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

安全基础
入侵常用TCP端口作用及其操作建议之二十九
玩转XP系统中的一些另类卸载
移动硬盘常见问题的解决(1)
移动硬盘常见问题的解决(2)
使用RSS能做的十六件事
Win XP系统19例常见问题(1)
Win XP系统19例常见问题(2)
Win XP系统19例常见问题(3)
Win XP系统19例常见问题(4)
企业安全管理从IP地址开始
计算机取证常识
深入剖析EFS
WinXP另类垃圾的清理(1)
WinXP另类垃圾的清理(2)
WinXP另类垃圾的清理(3)
WinXP另类垃圾的清理(4)
给Windows XP标题栏瘦瘦身
体验Windows XP的网络视频会议(1)
体验Windows XP的网络视频会议(2)
交换网络中的嗅探和ARP欺骗

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


出处:互联网   整理: 软晨网(RuanChen.com)   发布: 2009-10-28   浏览: 68 ::
收藏到网摘: 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 检测的问题被分为两个部分:如何遍历调用堆栈;如何检测某个组件是否拥有权限。