对于《windows核心编程》中的只言片语无法驱散心中的疑惑。就让MSDN中的解释给我们一盏明灯吧。如果要很详细的介绍,还是到MSDN仔细的看吧,我只是大体用容易理解的语言描述一下。
windows的安全访问控制(ACM,access control mode)是由两部分组成的。一个是访问令牌(access tokens),另一个是安全描述符(security identifiers)。
访问令牌是欲进行访问的进程使用的表明自己身份和特权的信息数据。
安全描述符是欲被访问的安全对象的相关安全信息。如什么样的用户的什么访问请求可以被允许,什么样的用户或者组的什么访问要被拒绝。
- Security Identifiers(SID)
经常听到SID,那么什么是SID呢,MSDN中说,SID是用来标识信任方的唯一的数值,其长度可变。而信任方就是用户,组,会话。所以基本上可以把SID理解为是一个用户名,一个组名,会话名。只是他们是经过安全认证,且不会重复,也就是安全可靠的。如果我们提到张三这个用户的SID,那么我们就可以理解为“张三(真)“。
- Security Descriptors(安全描述符)
MSDN说安全描述符包含了描述一个安全对象的安全信息。其实这句话说的很对,只是是大概上的。让我们具体看看安全描述符到底描述了哪些东西?
安全描述符包括:
1.与安全描述符关联的安全对象的拥有者的SID和此拥有者所在主群的SID
2.一个DACL(discretionary access control list)
3.一个SACL(system access control list)
4.和安全描述符意思相符的控制位集合
第一点不用说了,第二,三点看下面的ACL有详细解释,DACL和SACL分别是ACL的一种类型。第四点暂且不详。
- ACL(访问控制列表,access control list)
一提到像访问控制列表这样的东西,就会比较畏惧。其实一开始自己也很畏惧。因为以前一直对那些计算机理论术语很没感情。不过理解之后还是挺不错的。
ACL包括两种类型的访问控制列表,但不管是哪种列表它们的基本格式是一样的,那就是列表,列表入口(也叫访问控制入口,ACE,access control entry)。这两种安全控制列表分别是:
1.DACL(自由访问控制列表)
就像它的名字一样,DACL就是一个表明其它所有人的自由的(相应的)访问控制列表。这是什么意思呢?让我们具体看看DACL里面是什么东西吧。看下图你就比较明白了。
相信看了这个图能明白一大半。一个DACL是一个列表,每个列表入口(ACE)都是一个对某个SID的访问控制说明,描述这个SID是被拒绝还是被允许,如果允许的话,对这个SID给予什么权限。当然这个图很形象,但实际中ACE里面不是一个一个的字符串,这个ACE是怎么样的呢?
ACE其实由四部分组成,只是上面的图画的太好了。
这四部分分别是:
1.可能访问本ACE某个用户SID(对应Andrew)
2.该用户的访问权限的掩码(Read,write,execute)
3.ACE的类型,总共有三种。Access-denied ACE,Access-allowed ACE,System-audit ACE。前两种是DACL类型,最后一种是SACL类型。
4.这个ACE是否可以被其他安全对象继承。
那么DACL是如何工作的?
就想上图显示的一样,线程访问安全对象,要出示自己的令牌(说的很人性化似地,其实是有操作系统查看线程access tokens数据结构),将access tokens的用户SID,所属组群SID以及相应的权限与DACL里面的每个ACE相应的数据项进行比较,直到比较到一个ACE明确允许这个线程的所需操作,或者明确拒绝这个线程的访问要求,再或者没有找到上面任何一种情况比较结束了,那么就默认的拒绝。这个链表的比较是顺序的,从头到尾。如果链表的顺序变了,或许原来访问请求的结果就样了。
例如将上图中ACE3和ACE1的顺序调换过来,Thread A的请求就会被允许。所以顺序很重要。所以如果要构建一个安全描述符的DACL的话,用API添加ACE的时候,程序员要谨慎处理。注意API函数添加ACE始终实在链表末尾添加的。
ACE继承没有完全研究,暂且搁浅!
2.SACL(系统访问控制列表)
SACL是什么呢?其实就是一个审计中心,这个列表里面列举着那些类型的访问请求需要被系统记录。一旦有用户访问一个安全对象,其请求的访问权限和SACL中的一个ACE符合,那么系统会记录这个用户的请求是被拒绝了还是被允许了。MSDN提及说,将来可能会实现安全对象会对未经授权的用户访问发出警告信息。
- Access Tokens(访问令牌)
我们可以这样理解访问令牌,不过还是先把完整概念介绍一下。
访问令牌是包含12项,分别是:
- 当前用户的安全ID(稍后介绍),
- 当前用户所属组的安全ID。
- 当权会话安全ID。
- 用户所有的特权列表(包括用户本身,和其所属组)。
- 令牌拥有者安全ID。
- 用户所属主组群安全ID。
- 默认的自由访问控制列表(稍后介绍)。
- 源访问令牌
- 表明此令牌是源令牌还是模拟令牌
- 可选的链表,表明此令牌限制哪些SID
- 当前模拟令牌的级别
- 其他数据资料
看到这么多数据项,你该知道安全措施需要付出多大的代价了吧。
访问令牌描述了一个进程或线程的相关的安全信息。这些信息表明与这个进程或者线程关联的用户的标识符和特权。当用户登陆系统是,将用户密码和系统内数据库内的响应密码对比,如果验证通过,系统给用户产生一个访问令牌。以后这用户打开的所有线程都是继承与这个令牌。拿着这个令牌去访问安全对象。(Windows vista之后已经不一样了,如果是管理员登陆的话,管理员得到的访问令牌,和管理员启动的进行所拥有的令牌不一样,进程的令牌是被筛选的,或者说是降低权限的,进程要获得管理员的访问令牌(或者会所权限),就必须发出申请,系统显示一个对话框,是否允许这个程序以这种方式启动。)
每个进程至少有一个访问令牌,那就是主访问令牌,为什么是主呢?因为有些进程可能模拟另一个用户,并会或者另一个用户的令牌,而那个令牌就是模拟令牌。而系统在将进程的访问和安全对象进行审核是,使用的是主访问令牌。具体的暂且未知。
这样基本上初步了解了一下,windows 的ACM了。