当前位置: 首页 > 图文教程 > 网络安全 > 安全基础 > CLR 中代码访问安全检测实现原理(2)

安全基础
企业局域网的安全有效管理
QQ聊天时躲避黑客攻击的安全技巧
防止域名劫持的技巧
对于TOR是否能够实现真正安全传输的技术分析
教你找出并清除系统中木马的藏身之所
预防路由器蠕虫攻击
提高Windows系统安全性从设置启动项做起
赛门铁克称只有34%的PC用户会定期进行备份
如何解决网络不能正常传输问题?
摆脱Ghost一键恢复到整个硬盘的困扰
信息安全的关键:密码安全
加强路由器安全的轻松方法
怎样删除自己看过电影的踪迹?
江民6月6日病毒播报:魔兽用户在传播病毒
江民6月9日病毒播报:“杀人魔”木马
WindowsXP系统无线网络的安全
服务器虚拟机的安全管理注意事项
无线网络加密攻略
安全配置交换机端口提高网络安全性
和黑客的ASP漏洞入侵说byebye

安全基础 中的 CLR 中代码访问安全检测实现原理(2)


出处:互联网   整理: 软晨网(RuanChen.com)   发布: 2009-10-28   浏览: 77 ::
收藏到网摘: n/a

  虽然权限种类众多,但各种子类只负责定义自身权限的特性以及如何对自身权限验证,而所有的调用链遍历和验证工作,都是由 CodeAccessPermission.Demand() 方法完成的:

以下内容为程序代码:

public void CodeAccessPermission.Demand()
{
  CodeAccessSecurityEngine engine = SecurityManager.GetCodeAccessSecurityEngine();

  if ((engine != null) && !this.IsSubsetOf(null))
  {
    StackCrawlMark mark = StackCrawlMark.LookForMyCallersCaller;
    engine.Check(this, ref mark);
  }
}

  可以看到 CodeAccessPermission.Demand 方法,实际上是将验证操作转发给安全管理器 SecurityManager 的代码访问安全引擎 CodeAccessSecurityEngine 类型的 Check 方法完成的。

以下内容为程序代码:

internal class CodeAccessSecurityEngine
{
 internal virtual void Check(CodeAccessPermission cap, ref StackCrawlMark stackMark)
 {
  if (!PreCheck(cap, null, 1, ref stackMark, PermissionType.DefaultFlag))
  {
   Check(PermissionToken.GetToken(cap), cap, ref stackMark, -1, ((cap is IUnrestrictedPermission) ? 1 : 0));
  }
 }

 internal virtual void Check(CodeAccessPermission cap, ref StackCrawlMark stackMark, PermissionType permType)
 {
  int num1 = 0;
  if (CodeAccessSecurityEngine.GetResult(permType, out num1))
  {
   return;
  }
  if (this.PreCheck(cap, null, 1, ref stackMark, permType))
  {
   CodeAccessSecurityEngine.SetResult(permType, num1);
   return;
  }
  this.Check(PermissionToken.GetToken(cap), cap, ref stackMark, -1, ((cap is IUnrestrictedPermission) ? 1 : 0));
 }

 [MethodImpl(MethodImplOptions.InternalCall)]
 private void Check(PermissionToken permToken, CodeAccessPermission demand, ref StackCrawlMark stackMark, int checkFrames, int unrestrictedOverride);
}


  CodeAccessSecurityEngine 内部类的 Check 方法,将最终调用通过 Unmanaged 代码实现的内部方法进行安全检测。rotor 中的 COMCodeAccessSecurityEngine 类型 (ComCodeAccessSecurityEngine.cpp) 实现了这个检测逻辑。
  COMCodeAccessSecurityEngine::Check 函数 (ComCodeAccessSecurityEngine.cpp:683) 通过调用 COMCodeAccessSecurityEngine::CheckInternal 函数 (ComCodeAccessSecurityEngine.cpp:697) 填充一个堆栈遍历请求结构 CasCheckWalkData 的内容,最终将请求转发给 StandardCodeAccessCheck 函数 (ComCodeAccessSecurityEngine.cpp:563) 完成检测。此结构的指针将作为堆栈遍历回调函数的参数传递给回调函数进行实际权限验证,而 StandardCodeAccessCheck 只是负责调用全局堆栈遍历支持 StackWalkFunctions 函数(StackWalk.cpp:512),以 CodeAccessCheckStackWalkCB 函数 (ComCodeAccessSecurityEngine.cpp:449) 为回调函数,以 CheckInternal 函数填充的 CasCheckWalkData 结构为参数,通过现成的堆栈遍历支持 Thread::StackWalkFrames 完成堆栈遍历。

  通过堆栈遍历实现代码访问安全检测调用流程如下:

以下为引用:

CodeAccessSecurityEngine::Check 内部调用定义,由下面的函数实现
 COMCodeAccessSecurityEngine::Check 转发检测请求 (ComCodeAccessSecurityEngine.cpp:683)
  COMCodeAccessSecurityEngine::CheckInternal 填充 CasCheckWalkData 结构 (ComCodeAccessSecurityEngine.cpp:697)
   StandardCodeAccessCheck 执行堆栈遍历
    Thread::StackWalkFrames 遍历当前线程堆栈
     CodeAccessCheckStackWalkCB 检测当前组件权限 (ComCodeAccessSecurityEngine.cpp:449)


  因此现在 CAS 检测的问题被分为两个部分:如何遍历调用堆栈;如何检测某个组件是否拥有权限。