Chinaunix首页 | 论坛 | 博客
  • 博客访问: 1275553
  • 博文数量: 554
  • 博客积分: 10425
  • 博客等级: 上将
  • 技术积分: 7555
  • 用 户 组: 普通用户
  • 注册时间: 2006-11-09 09:49
文章分类

全部博文(554)

文章存档

2012年(1)

2011年(1)

2009年(8)

2008年(544)

分类:

2008-04-14 10:11:30


简单验证安全层(Simple Authentication Security Layer, SASL) 介绍
第7 章• 编写使用SASL的应用程序155
SASL_CB_GETPATH 获取以冒号分隔的SASL 插件搜索路径列表。缺省路径取决于以
下体系结构:
 32 位SPARC 体系结构: /usr/lib/sasl
 32 位x86 体系结构: /usr/lib/sasl
 64 位SPARC 体系结构: /usr/lib/sasl/sparcv9
 x64 体系结构: /usr/lib/sasl/amd64
SASL_CB_GETCONF 获取SASL 服务器的配置目录的路径。缺省设置为/etc/sasl。
SASL_CB_LANGUAGE 为客户机和服务器错误消息和客户机提示指定以逗号分隔的RFC
1766 语言代码列表(按优先级顺序)。缺省设置为i-default。
SASL_CB_VERIFYFILE 验证配置文件和插件文件。
SASL 提供以下仅限客户机使用的回调:
SASL_CB_USER 获取客户机用户名。用户名与授权ID 相同。LOGNAME
环境变量为缺省设置。
SASL_CB_AUTHNAME 获取客户机验证名称。
SASL_CB_PASS 获取基于客户机口令短语的机密。
SASL_CB_ECHOPROMPT 获取给定质询提示的结果。可以回显来自客户机的输入。
SASL_CB_NOECHOPROMPT 获取给定质询提示的结果。不应回显来自客户机的输入。
SASL_CB_GETREALM 设置用于验证的领域。
SASL 提供以下仅限服务器使用的回调:
SASL_CB_PROXY_POLICY 检查是否授权经过验证的用户代表指定用户
执行操作。如果未注册此回调,则经过验证
的用户与要授权的用户必须是同一用户。如
果这些ID 不同,则验证将失败。请使用服务
器应用程序来维护非标准授权策略。
SASL_CB_SERVER_USERDB_CHECKPASS 针对调用方提供的用户数据库验证纯文本口
令。
SASL_CB_SERVER_USERDB_SETPASS 在用户数据库中存储纯文本口令
SASL_CB_CANON_USER 调用应用程序提供的用户标准化函数。
首次初始化SASL 库时,服务器和客户机会声明所有必要的全局回调。执行SASL 会话之前
或期间可以使用全局回调。初始化之前,回调将执行诸如装入插件、记录数据和读取配置
文件之类的任务。SASL 会话开始时,可以声明其他回调。这类回调可以覆盖全局回调(如
果必要)。
简单验证安全层(Simple Authentication Security Layer, SASL) 介绍
156 Solaris 开发者安全性指南• 2006 年11 月
SASL 连接上下文
libsasl 使用SASL 连接上下文维护SASL 客户机和SASL 服务器的每个SASL 会话的状态。每
个上下文一次只能用于一个验证和安全会话。维护的状态包括以下信息:
 连接信息,如服务、命名和地址信息以及协议标志
 特定于连接的回调
 用于协商SASL SSF 的安全属性
 验证状态以及安全层信息
SASL 周期中的步骤
下图显示了SASL 生命周期中的步骤。客户机操作显示在图的左侧,服务器操作显示在右
侧。中间的箭头显示客户机与服务器之间通过外部连接执行的交互操作。
简单验证安全层(Simple Authentication Security Layer, SASL) 介绍
第7 章• 编写使用SASL的应用程序157
图7–2 SASL生命周期
以下各节说明了生命周期中的步骤。
libsasl 初始化
客户机调用sasl_client_init() 来初始化libsasl 以供客户机使用;而服务器调用
sasl_server_init() 来初始化libsasl 以供服务器使用。
运行sasl_client_init() 时,将装入SASL 客户机、该客户机的机制以及该客户机的标准化
插件。同样,调用sasl_server_init() 时,将装入SASL 服务器、该服务器的机制、该服务
器的标准化插件以及该服务器的auxprop 插件。调用sasl_client_init() 后,可以使用
sasl_client_add_plugin() 和sasl_canonuser_add_plugin() 来添加其他客户机插件。在服
务器端,调用sasl_server_init() 后,可以通过sasl_server_add_plugin()、
简单验证安全层(Simple Authentication Security Layer, SASL) 介绍
158 Solaris 开发者安全性指南• 2006 年11 月
sasl_canonuser_add_plugin() 和sasl_auxprop_add_plugin() 来添加其他的服务器插件。依
据体系结构,我们在Solaris 软件的以下目录中提供了SASL 机制:
 32 位SPARC 体系结构: /usr/lib/sasl
 32 位x86 体系结构: /usr/lib/sasl
 64 位SPARC 体系结构: /usr/lib/sasl/sparcv9
 x64 体系结构: /usr/lib/sasl/amd64
可以使用SASL_CB_GETPATH回调覆盖缺省位置。
此时,可以设置所有必需的全局回调。SASL 客户机和服务器可能包括以下回调:
 SASL_CB_GETOPT
 SASL_CB_LOG
 SASL_CB_GETPATH
 SASL_CB_VERIFYFILE
此外,SASL 服务器还可能包括SASL_CB_GETCONF 回调。
SASL 会话初始化
服务器和客户机通过协议建立连接。要使用SASL 执行验证,服务器和客户机可以分别使用
sasl_server_new() 和sasl_client_new() 来创建SASL 连接上下文。SASL 客户机和服务器可
以使用sasl_setprop() 来设置对机制强制执行安全限制的属性。此方法使SASL 消费方应用
程序可以决定指定SASL 连接上下文的最小SSF、最大SSF 和安全属性。
#define SASL_SEC_NOPLAINTEXT 0x0001
#define SASL_SEC_NOACTIVE 0x0002
#define SASL_SEC_NODICTIONARY 0x0004
#define SASL_SEC_FORWARD_SECRECY 0x0008
#define SASL_SEC_NOANONYMOUS 0x0010
#define SASL_SEC_PASS_CREDENTIALS 0x0020
#define SASL_SEC_MUTUAL_AUTH 0x0040
注– 验证和安全层可由客户机/服务器协议提供,也可由libsasl 外部的某些其他机制提供。
在这类情况下,可以使用sasl_setprop() 来设置外部验证ID 或外部SSF。例如,请考虑协
议对服务器结合使用SSL 和客户机验证的情况。在这种情况下,外部验证标识可以为客户
机的主题名称。外部SSF 可以为密钥大小。
对于服务器,libsasl 可以依据安全属性和外部SSF 来确定可用的SASL 机制。客户机可以
通过协议从SASL 服务器获取可用的SASL 机制。
简单验证安全层(Simple Authentication Security Layer, SASL) 介绍
第7 章• 编写使用SASL的应用程序159
为使SASL 服务器可以创建SASL 连接上下文,服务器应该调用sasl_server_new()。可以重
复使用不再使用的现有SASL 连接上下文。但是,可能需要重置以下参数:
#define SASL_DEFUSERREALM 3 /* default realm passed to server_new or set with setprop */
#define SASL_IPLOCALPORT 8 /* iplocalport string passed to server_new */
#define SASL_IPREMOTEPORT 9 /* ipremoteport string passed to server_new */
#define SASL_SERVICE 12 /* service passed to sasl_*_new */
#define SASL_SERVERFQDN 13 /* serverFQDN passed to sasl_*_new */
可以修改sasl_client_new() 和sasl_server_new() 的任何参数,但回调和协议标志除外。
服务器和客户机还可以使用sasl_setprop() 来指定以下属性,从而建立安全策略并设置连
接特定参数:
#define SASL_SSF_EXTERNAL 100 /* external SSF active (sasl_ssf_t *) */
#define SASL_SEC_PROPS 101 /* sasl_security_properties_t */
#define SASL_AUTH_EXTERNAL 102 /* external authentication ID (const char *)
*/
 SASL_SSF_EXTERNAL-用于设置强度因子,即密钥中的位数
 SASL_SEC_PROPS-用于定义安全策略
 SASL_AUTH_EXTERNAL-外部验证ID
服务器可以调用sasl_listmech() 来获取满足安全策略的可用SASL 机制的列表。一般情况
下,客户机可以采用与协议相关的方式从服务器获取可用机制的列表。
下图说明了SASL 会话的初始化过程。在此图和后续的图中,为了简单起见,省略了通过协
议进行传输后的数据检查。
简单验证安全层(Simple Authentication Security Layer, SASL) 介绍
160 Solaris 开发者安全性指南• 2006 年11 月
图7–3 SASL会话初始化
SASL 验证
验证根据使用的安全机制采用不同数量的客户机和服务器步骤。SASL 客户机将调用
sasl_client_start() 和要使用的安全机制列表。此列表通常来自服务器。libsasl 将依据
可用机制和客户机的安全策略选择要用于此SASL 会话的最佳机制。客户机的安全策略控制
允许的机制。选定的机制由sasl_client_start() 返回。有时,客户机的安全机制需要其他
验证信息。对于已注册的回调,libsasl 将调用指定的回调,除非回调函数为NULL。如果
回调函数为NULL,则libsasl 将返回SASL_INTERACT 和对所需信息的请求。如果返回
SASL_INTERACT,则应使用请求的信息调用sasl_client_start()。
如果sasl_client_start() 返回SASL_CONTINUE 或SASL_OK,则客户机应向服务器发送
包含生成的所有验证数据的选定机制。如果返回任何其他值,则表示出现了错误。例如,
任何机制可能都不可用。
服务器将接收客户机选定的机制,以及所有的验证数据。随后,服务器将调用
sasl_server_start() 来初始化此会话的机制数据。sasl_server_start() 还将处理所有的验
证数据。如果sasl_server_start() 返回SASL_CONTINUE 或SASL_OK,则服务器将发送
验证数据。如果sasl_server_start() 返回任何其他值,则表示出现了错误,如不可接受的
机制或验证失败。必须中止验证。应该释放或重复使用SASL 上下文。
简单验证安全层(Simple Authentication Security Layer, SASL) 介绍
第7 章• 编写使用SASL的应用程序161
下图说明了此部分的验证过程。
图7–4 SASL验证:发送客户机数据
如果服务器对sasl_server_start() 的调用返回SASL_CONTINUE,则服务器将继续与客户
机进行通信,以获取所有必要的验证信息。后续步骤的数目取决于机制。如果需要,客户
机可以调用sasl_client_step() 来处理来自服务器的验证数据并生成回复。同样,服务器
可以调用sasl_server_step() 来处理来自客户机的验证并相应地生成回复。此交换将持续
进行下去,直到验证完成或出现错误为止。如果返回SASL_OK,则指示对客户机或服务器
的验证已成功完成。SASL 机制可能仍然具有要发送给另一端的其他数据,因此另一端可以
完成验证。在两端都完成验证后,服务器和客户机便可查询彼此的属性。
简单验证安全层(Simple Authentication Security Layer, SASL) 介绍
162 Solaris 开发者安全性指南• 2006 年11 月
下图显示了服务器与客户机之间为传输其他验证数据所执行的交互。
简单验证安全层(Simple Authentication Security Layer, SASL) 介绍
第7 章• 编写使用SASL的应用程序163
图7–5 SASL验证:处理服务器数据
简单验证安全层(Simple Authentication Security Layer, SASL) 介绍
164 Solaris 开发者安全性指南• 2006 年11 月
SASL 保密性和完整性
要检查安全层,请使用sasl_getprop(3SASL) 函数来查看安全强度因子(security strength
factor, SSF) 的值是否大于0。如果已协商安全层,则成功验证后客户机和服务器必须使用生
成的SSF。在客户机与服务器之间交换数据的方式与验证的方式相同。通过协议向客户机或
服务器发送数据之前,将sasl_encode() 应用于数据。在接收端,使用sasl_decode() 对数
据进行解码。如果未协商安全层,则无需SASL 连接上下文。随后,即可处理或重复使用该
上下文。
释放SASL 会话
只有在不会重复使用会话时,才应释放SASL 连接上下文。sasl_dispose() 将释放SASL 连
接上下文以及所有关联的资源和机制。调用sasl_done() 之前,必须处理SASL 连接上下
文。sasl_done() 不负责释放SASL 连接的上下文资源。请参见第165 页中的“libsasl 清除
”。
释放SASL 会话时,将通知关联的机制所有状态均可释放。只有在不会重复使用SASL 会话
时,才应释放该会话。否则,其他会话可以重复使用SASL 状态。客户机和服务器都使用
sasl_dispose() 释放SASL 连接上下文。
libsasl 清除
此步骤可释放SASL 库和插件中的所有资源。客户机和服务器可以调用sasl_done() 来释放
libsasl() 资源并卸载所有的SASL 插件。sasl_done() 不会释放SASL 连接上下文。请注
意,如果应用程序同时为SASL 客户机和SASL 服务器,则sasl_done() 将同时释放SASL 客
户机和SASL 服务器资源。您不能仅释放客户机或服务器的资源。
注意– 库不应调用sasl_done()。应用程序在调用sasl_done() 时务必要谨慎,避免与所有可
能使用libsasl 的库发生干扰。
SASL 示例
本节说明客户机应用程序与服务器应用程序之间的典型SASL 会话。该示例包含以下步骤:
1. 客户机应用程序可以初始化libsasl 并设置以下全局回调:
 SASL_CB_GETREALM
 SASL_CB_USER
 SASL_CB_AUTHNAME
 SASL_CB_PASS
 SASL_CB_GETPATH
 SASL_CB_LIST_END
2. 服务器应用程序可以初始化libsasl 并设置以下全局回调:
 SASL_CB_LOG
SASL示例
第7 章• 编写使用SASL的应用程序165
 SASL_CB_LIST_END
3. 客户机将创建SASL 连接上下文,设置安全属性并从服务器请求可用机制的列表。
4. 服务器将创建SASL 连接上下文,设置安全属性,获取适当SASL 机制的列表并向客户机
发送该列表。
5. 客户机将接收可用机制的列表,选择一种机制,并向服务器发送所选择的机制以及所有
验证数据。
6. 随后,客户机和服务器将交换SASL 数据,直到验证和安全层协商完成为止。
7. 验证完成后,客户机和服务器将确定是否已协商安全层。客户机将对测试消息进行编
码。然后,会将该消息发送给服务器。服务器也会确定经过验证的用户的用户名和该用
户的领域。
8. 服务器将接收、解码和列显编码的消息。
9. 客户机将调用sasl_dispose() 以释放客户机的SASL 连接上下文。随后,客户机将调用
sasl_done() 以释放libsasl 资源。
10. 服务器将调用sasl_dispose() 以释放客户机连接上下文。
以下是客户机与服务器之间的对话。执行调用时,会显示对libsasl 的每个调用。每次数据
传输都由发送者和接收者指明。数据采用编码的形式显示,并在前面加上表示来源的字符
: C: 表示来自于客户机,S: 表示来自于服务器。附录D中同时提供了两种应用程序的源代
码。
客户机
% doc-sample-client
*** Calling sasl_client_init() to initialize libsasl for client use ***
*** Calling sasl_client_new() to create client SASL connection context ***
*** Calling sasl_setprop() to set sasl context security properties ***
Waiting for mechanism list from server...
服务器
% doc-sample-server digest-md5
*** Calling sasl_server_init() to initialize libsasl for server use ***
*** Calling sasl_server_new() to create server SASL connection context ***
*** Calling sasl_setprop() to set sasl context security properties ***
Forcing use of mechanism digest-md5
Sending list of 1 mechanism(s)
SASL示例
166 Solaris 开发者安全性指南• 2006 年11 月
S:ZGlnZXN0LW1kNQ==
客户机
S:ZGlnZXN0LW1kNQ==
received 10 byte message
got ’digest-md5’
Choosing best mechanism from:digest-md5
*** Calling sasl_client_start() ***
Using mechanism DIGEST-MD5
Sending initial response...
C:RElHRVNULU1ENQ==
Waiting for server reply...
服务器
C:RElHRVNULU1ENQ==
got ’DIGEST-MD5’
*** Calling sasl_server_start() ***
Sending response...
S:bm9uY2U9IklicGxhRHJZNE4Z1gyVm5lQzl5MTZOYWxUOVcvanUrcmp5YmRqaHM\
sbT0iam0xMTQxNDIiLHFvcD0iYXV0aCxhdXRoLWludCxhdXRoLWNvbmYiLGNpcGhlcj0ic\
QwLHJjNC01NixyYzQiLG1heGJ1Zj0yMDQ4LGNoYXJzZXQ9dXRmLTgsYWxnb3JpdGhtPW1k\
XNz
Waiting for client reply...
客户机
S:bm9uY2U9IklicGxhRHJZNE4Z1gyVm5lQzl5MTZOYWxUOVcvanUrcmp5YmRqaHM\
sbT0iam0xMTQxNDIiLHFvcD0iYXV0aCxhdXRoLWludCxhdXRoLWNvbmYiLGNpcGhlcj0ic\
SASL示例
第7 章• 编写使用SASL的应用程序167
QwLHJjNC01NixyYzQiLG1heGJ1Zj0yMDQ4LGNoYXJzZXQ9dXRmLTgsYWxnb3JpdGhtPW1k\
XNz
received 171 byte message
got ’nonce="IbplaDrY4N4szhgX2VneC9y16NalT9W/ju+rjybdjhs=",\
realm="jm114142",qop="auth,auth-int,auth-conf",cipher="rc4-40,rc4-56,\
rc4",maxbuf=2048,charset=utf-8,algorithm=md5-sess’
*** Calling sasl_client_step() ***
Please enter your authorization name :zzzz
Please enter your authentication name :zzzz
Please enter your password :zz
*** Calling sasl_client_step() ***
Sending response...
C:dXNlcm5hbWU9Inp6enoiLHJlYWxtPSJqbTExNDE0MiIsbm9uY2U9IklicGxhRHJZNE4\
yVm5lQzl5MTZOYWxUOVcvanUrcmp5YmRqaHM9Iixjbm9uY2U9InlqZ2hMVmhjRFJMa0Fob\
tDS0p2WVUxMUM4V1NycjJVWm5IR2Vkclk9IixuYz0wMDAwMDAwMSxxb3A9YXV0aC1jb25m\
Ghlcj0icmM0IixtYXhidWY9MjA0OCxkaWdlc3QtdXJpPSJyY21kLyIscmVzcG9uc2U9OTY\
ODI1MmRmNzY4YTJjYzkxYjJjZDMyYTk0ZWM=
Waiting for server reply...
服务器
C:dXNlcm5hbWU9Inp6enoiLHJlYWxtPSJqbTExNDE0MiIsbm9uY2U9IklicGxhRHJZNE4\
yVm5lQzl5MTZOYWxUOVcvanUrcmp5YmRqaHM9Iixjbm9uY2U9InlqZ2hMVmhjRFJMa0Fob\
tDS0p2WVUxMUM4V1NycjJVWm5IR2Vkclk9IixuYz0wMDAwMDAwMSxxb3A9YXV0aC1jb25m\
Ghlcj0icmM0IixtYXhidWY9MjA0OCxkaWdlc3QtdXJpPSJyY21kLyIscmVzcG9uc2U9OTY\
ODI1MmRmNzY4YTJjYzkxYjJjZDMyYTk0ZWM=
SASL示例
168 Solaris 开发者安全性指南• 2006 年11 月
got ’username="zzzz",realm="jm114142",\
nonce="IbplaDrY4N4szhgX2VneC9y16NalT9W/ju+rjybdjhs=",\
cnonce="yjghLVhcDRLkAhoirwKCKJvYU11C8WSrr2UZnHGedrY=", \
nc=00000001,qop=auth-conf,cipher="rc4",maxbuf=2048,digest-uri="rcmd/",\
response=966e978252df768a2cc91b2cd32a94ec’
*** Calling sasl_server_step() ***
Sending response...
S:cnNwYXV0aD0yYjEzMzRjYzU4NTE4MTEwOWM3OTdhMjUwYjkwMzk3OQ==
Waiting for client reply...
客户机
S:cnNwYXV0aD0yYjEzMzRjYzU4NTE4MTEwOWM3OTdhMjUwYjkwMzk3OQ==
received 40 byte message
got ’rspauth=2b1334cc585181109c797a250b903979’
*** Calling sasl_client_step() ***
C:
Negotiation complete
*** Calling sasl_getprop() ***
Username:zzzz
SSF:128
Waiting for encoded message...
服务器
Waiting for client reply...
C:got ’’ *** Calling sasl_server_step() ***
Negotiation complete
SASL示例
第7 章• 编写使用SASL的应用程序169
*** Calling sasl_getprop() to get username, realm, ssf ***
Username:zzzz
Realm:22c38
SSF:128
*** Calling sasl_encode() *** sending encrypted message ’srv message 1’
S:AAAAHvArjnAvDFuMBqAAxkqdumzJB6VD1oajiwABAAAAAA==
客户机
S:AAAAHvArjnAvDFuMBqAAxkqdumzJB6VD1oajiwABAAAAAA==
received 34 byte message
got ’’
*** Calling sasl_decode() ***
received decoded message ’srv message 1’
*** Calling sasl_encode() ***
sending encrypted message ’client message 1’
C:AAAAIRdkTEMYOn9X4NXkxPc3OTFvAZUnLbZANqzn6gABAAAAAA==
*** Calling sasl_dispose() to release client SASL connection context ***
*** Calling sasl_done() to release libsasl resources ***
服务器
Waiting for encrypted message...
C:AAAAIRdkTEMYOn9X4NXkxPc3OTFvAZUnLbZANqzn6gABAAAAAA==
got ’’
*** Calling sasl_decode() ***
received decoded message ’client message 1’
*** Calling sasl_dispose() to release client SASL connection context ***
SASL示例
170 Solaris 开发者安全性指南• 2006 年11 月
服务提供者的SASL
本节介绍如何创建用于为SASL 应用程序提供机制和其他服务的插件。
注– 由于导出规程,对于非Solaris 客户机/服务器机制插件,Solaris SASLSPI 不支持安全层。
因此,非Solaris 客户机/服务器机制插件不能提供完整性和保密性服务。Solaris 客户机/服务
器机制插件没有此限制。
SASL 插件概述
SASL 服务提供者接口(service provider interface, SPI) 可实现插件与libsasl 库之间的通信。
SASL 插件通常作为共享库来实现。单个共享库可以具有一个或多个不同类型的SASL 插
件。位于共享库中的插件是由libsasl 通过dlopen(3C) 函数动态打开的。
还可以将插件静态绑定至调用libsasl 的应用程序。使用sasl_client_add_plugin() 函数或
sasl_server_add_plugin() 函数装入这些种类的插件,具体视应用程序是客户机还是服务器
而定。
Solaris 操作系统中的SASL 插件具有以下要求:
 共享库中的插件必须位于有效的可执行对象文件(文件扩展名最好是.so)中。
 插件必须位于可验证的位置中。SASL_CB_VERIFYFILE 回调用于验证插件。
 插件必须包含正确的入口点。
 SASL 客户机的插件版本必须与SASL 服务器的对应插件版本匹配。
 插件需要能够成功初始化。
 二进制类型的插件必须与libsasl 的二进制类型匹配。
SASL 插件分为四种类别:
 客户机机制插件
 服务器机制插件
 标准化插件
 Auxprop 插件
sasl_client_init() 函数导致SASL 客户机装入所有可用的客户机插件。
sasl_server_init() 函数导致SASL 服务器装入服务器插件、标准化插件和auxprop 插件。
调用sasl_done() 时将卸载所有插件。
为查找插件,libsasl 使用SASL_CB_GETPATH回调函数或缺省路径。SASL_CB_GETPATH
返回以冒号分隔的目录列表,以供在其中查找插件。如果SASL 消费方指定了
SASL_CB_GETPATH回调,则libsasl 将使用返回的搜索路径。否则,SASL 消费方可以使
用与二进制类型对应的缺省路径:
 32 位SPARC 体系结构: /usr/lib/sasl
 32 位x86 体系结构: /usr/lib/sasl
服务提供者的SASL
第7 章• 编写使用SASL的应用程序171
 64 位SPARC 体系结构: /usr/lib/sasl/sparcv9
 x64 体系结构: /usr/lib/sasl/amd64
在装入过程中,libsasl 将调用最新支持的插件版本。插件将返回该版本以及描述该插件的
结构。如果该版本合格,则libsasl 即可装入该插件。当前版本号SASL_UTILS_VERSION
为4。
初始化插件后,插件与libsasl 之间的后续通信通过必须建立的结构执行。插件使用
sasl_utils_t 结构来调用libsasl。libsasl 使用以下结构中的入口点与插件进行通信:
 sasl_out_params_t
 sasl_client_params_t
 sasl_server_params_t
 sasl_client_plug_t
 sasl_server_plug_t
 sasl_canonuser_plug_t
 sasl_auxprop_plug_t
可以在SASL 头文件中找到这些结构的源代码。这些结构将在下一节中进行介绍。
SASL 插件的重要结构
libsasl 与插件之间的通信是通过以下结构完成的:
 sasl_utils_t-sasl_utils_t 结构包含大量实用程序函数以及三种上下文:
此结构包含大量可为插件编写人员提供者便的实用程序函数。许多函数是指向libsasl
中的公共接口的指针。插件不需要直接调用libsasl,除非出于某种原因,插件需要是
SASL 消费方。
libsasl 将为sasl_utils_t 创建三种上下文。
 sasl_conn_t *conn
 sasl_rand_t *rpool
 void *getopt_context
在某些情况(如装入插件)下,sasl_utils_t 中的conn 变量实际上与连接没有关联。在
另外一些情况下,conn 是SASL 消费方的SASL 连接上下文。rpool 变量用于随机数生成
函数。getopt_context 是应该与getopt() 函数结合使用的上下文。
sasl_getopt_t(3SASL)、sasl_log_t(3SASL) 和sasl_getcallback_t (3SASL)
 sasl_out_params_t-libsasl 用于创建sasl_out_params_t 结构并将该结构传递给客户机
或服务器中的mech_step()。此结构可以将以下信息传达给libsasl: 验证状态、
authid、authzid、maxbuf、协商的ssf 以及数据编码和解码信息
 sasl_client_params_t-libsasl 使用sasl_client_params_t 结构将客户机状态传递给
SASL 客户机机制。客户机机制的mech_new()、mech_step() 和mech_idle() 入口点用于
发送此状态数据。canon_user_client() 入口点还需要同时传递客户机状态。
服务提供者的SASL
172 Solaris 开发者安全性指南• 2006 年11 月
 sasl_server_params_t-sasl_server_params_t 结构在服务器端执行和
sasl_client_params_t 类似的功能。
客户机插件
客户机插件用于管理SASL 协商的客户端。客户机插件通常随对应的服务器插件一同打包。
客户机插件包含一种或多种客户端SASL 机制。每种SASL 客户机机制都支持验证、完整性
和保密性(后两者是可选的)。每种机制都提供有关该机制的功能的信息:
 最大SSF
 最大安全标志
 插件功能
 用于使用插件的回调和提示ID
客户机插件必须导出sasl_client_plug_init()。libsasl 将调用sasl_client_plug_init()
来初始化客户机的插件。插件将返回sasl_client_plug_t 结构。sasl_client_plug_t 将为
libsasl 提供以下用于调用机制的入口点:
 mech_new()-客户机通过调用sasl_client_start()(使用mech_new())来启动连接。
mech_new() 将执行特定于机制的初始化。如有必要,将分配连接上下文。
 mech_step()-mech_step() 可通过sasl_client_start() 和sasl_client_step() 来进行调
用。调用mech_new() 后,mech_step() 将对客户端执行验证。如果验证成功,
mech_step() 将返回SASL_OK。如果需要更多数据,则将返回SASL_CONTINUE。如果
验证失败,则将返回SASL 错误代码。如果出现错误,则将调用seterror()。如果验证
成功,则mech_step() 必须返回包含相关安全层信息和回调的sasl_out_params_t 结构。
canon_user() 函数是此结构的一部分。客户机收到验证和授权ID 时,必须调用
canon_user()。
 mech_dispose()-mech_dispose() 是在安全关闭上下文时进行调用的。mech_dispose()
由sasl_dispose() 进行调用。
 mech_free()-mech_free() 是在libsasl 关闭时进行调用的。插件的所有其余全局状态
都是通过mech_free() 释放的。
服务器插件
服务器插件用于管理SASL 协商的服务器端。服务器插件通常随对应的客户机插件一同打
包。服务器插件包含一种或多种服务器端SASL 机制。每种SASL 服务器机制都支持验证、
完整性和保密性(后两者是可选的)。每种机制都提供有关该机制的功能的信息:
 最大SSF
 最大安全标志
 插件功能
 用于使用插件的回调和提示ID
服务器插件必须导出sasl_server_plug_init()。libsasl 将调用sasl_server_plug_init()
来初始化服务器的插件。插件将返回sasl_server_plug_t 结构。sasl_server_plug_t 将为
libsasl 提供以下用于调用机制的入口点:
服务提供者的SASL
第7 章• 编写使用SASL的应用程序173
 mech_new()-服务器通过调用sasl_server_start()(使用mech_new())来启动连接。
mech_new() 将执行特定于机制的初始化。如有必要,mech_new() 将分配连接上下文。
 mech_step()-mech_step() 可通过sasl_server_start() 和sasl_server_step() 来进行调
用。调用mech_new() 后,mech_step() 将对服务器端执行验证。如果验证成功,
mech_step() 将返回SASL_OK。如果需要更多数据,则将返回SASL_CONTINUE。如果
验证失败,则将返回SASL 错误代码。如果出现错误,则将调用seterror()。如果验证
成功,则mech_step() 必须返回包含相关安全层信息和回调的sasl_out_params_t 结构。
canon_user() 函数是此结构的一部分。服务器收到验证和授权ID 时,必须调用
canon_user()。调用canon_user() 函数将导致propctx 被填充。标准化验证之前,应执
行所有必需的辅助属性请求。标准化验证后,应执行授权ID 查找。
返回SASL_OK 之前,mech_step() 函数必须填充所有相关的sasl_out_params_t 字段。
这些字段可以执行以下函数:
 doneflag-指示完整的交换
 maxoutbuf-指示安全层的最大输出大小
 mech_ssf-为安全层提供SSF
 encode()-由sasl_encode()、sasl_encodev() 和sasl_decode() 进行调用
 decode()-由sasl_encode()、sasl_encodev() 和sasl_decode() 进行调用
 encode_context()-由sasl_encode()、sasl_encodev() 和sasl_decode() 进行调用
 decode_context()-由sasl_encode()、sasl_encodev() 和sasl_decode() 进行调用
 mech_dispose()-mech_dispose() 是在安全关闭上下文时进行调用的。mech_dispose()
由sasl_dispose() 进行调用。
 mech_free()-mech_free() 是在libsasl 关闭时进行调用的。插件的所有其余全局状态
都是通过mech_free() 释放的。
 setpass() 可以设置用户口令。setpass() 使机制可以具有内部口令。
 mech_avail() 由sasl_listmech() 进行调用,目的是检查机制是否可用于给定用户。
mech_avail() 可以创建新的上下文,进而避免对mech_new() 的调用。只要性能不受影
响,就应使用此方法创建上下文。
用户标准化插件
标准化插件为客户端和服务器端的验证和授权名称的备用标准化提供支持。
sasl_canonuser_plug_init() 用于装入标准化插件。标准化插件具有以下要求:
 必须将标准化的名称复制到输出缓冲区。
 可以将同一输入缓冲区用作输出缓冲区。
 当仅存在一个验证ID 或授权ID 时,标准化插件必须发挥作用。
用户标准化插件必须导出sasl_canonuser_init() 函数。sasl_canonuser_init() 函数必须返
回sasl_canonuser_plug_t 以建立必要的入口点。用户标准化插件必须至少实现
sasl_canonuser_plug_t 结构的一个canon_user_client() 成员或canon_user_server() 成
员。
服务提供者的SASL
174 Solaris 开发者安全性指南• 2006 年11 月
辅助属性(auxprop) 插件
Auxprop 插件为查找SASL 服务器的authid 和authzid 的辅助属提供支持。例如,应用程序
可能需要查找内部验证的用户口令。sasl_auxprop_plug_init() 函数用于初始化auxprop 插
件并返回sasl_auxpropr_plug_t 结构。
要成功实现auxprop 插件,必须实现sasl_auxprop_plug_t 结构的auxprop_lookup 成员。标
准化用户名后,应使用标准化的用户名来调用auxprop_lookup() 函数。随后,插件即可执
行请求的辅助属性所需的所有查询。
注– Sun Microsystems, Inc. 当前不支持auxprop 插件。
SASL 插件开发指南
本节提供一些用于开发SASL 插件的其他建议。
SASL 插件中的错误报告
适当的错误报告可以帮助跟踪验证问题和其他调试问题。建议插件开发者使用
sasl_utils_t 结构中的sasl_seterror() 回调为给定连接提供详细的错误信息。
SASL 插件中的内存分配
在SASL 中分配内存的一般规则是在不再需要已分配的任何内存时将其释放。遵循此规则可
以提高性能和可移植性,而且可以避免内存泄漏。
设置SASL 协商顺序
插件机制可以设置客户机和服务器通过以下标志执行SASL 会话的顺序:
 SASL_FEAT_WANT_CLIENT_FIRST-客户端将开始交换。
 SASL_FEAT_WANT_SERVER_LAST-服务器将最终数据发送到客户机。
如果未设置任何标志,则机制插件将在内部设置顺序。在这种情况下,机制必须同时检查
客户机和服务器中需要发送的数据。请注意,只有在协议允许初始响应时,才有可能出现
客户机首先发送的情况。
服务器最后发送的情况要求在步骤函数返回SASL_OK 时插件可设置*serverout。永远不让
服务器最后发送的那些机制必须将*serverout 设置为NULL。始终让服务器最后发送的那
些机制需要将*serverout 指向成功数据。
服务提供者的SASL
第7 章• 编写使用SASL的应用程序175
176
Solaris 加密框架介绍
Solaris 加密框架是一种体系结构,可使Solaris 操作系统中的应用程序使用或提供加密服
务。所有与框架的交互都基于RSASecurity Inc. 的PKCS#11 加密令牌接口(Cryptographic
Token Interface, Cryptoki)。PKCS#11 是RSALaboratories(RSASecurity Inc. 的研究机构)开发
的一种产品。本章介绍Solaris 加密框架的以下主题:
 第178 页中的“加密框架概述”
 第180 页中的“加密框架的组件”
 第181 页中的“加密开发者需要了解的内容”
 第383 页中的“向提供者中添加签名”
 第182 页中的“避免在用户级提供者中出现数据清除冲突”
Solaris 加密术语
获取加密服务的应用程序、库或内核模块称作消费方,通过加密框架向消费方提供加密服
务的应用程序称作提供者,或称作插件。用来实现加密操作的软件称作机制。机制不只是
算法,还包括算法的应用方式。例如,应用于验证机制的DES(数据加密标准)算法被视
为一个单独的机制,应用于逐块加密的DES 则是另一个机制。
令牌是可以执行加密的设备的抽象术语。此外,令牌可以存储要用在加密操作中的信息。
一个令牌可以支持一个或多个机制。令牌可以代表硬件,例如加速器板中的部件。仅代表
软件的令牌称作软令牌。令牌可以插入到插槽中,插槽也是一种物理比喻。插槽是使用加
密服务的应用程序的连接点。
除了提供者的特定插槽以外,Solaris 实现还提供一个名为元插槽的特殊插槽。元插槽是
Solaris 加密框架库(libpkcs11.so) 的一个组件。元插槽充当一个虚拟插槽,它具有框架中安
装的所有令牌和插槽的组合功能。实际上,元插槽使应用程序通过单个插槽与任何可用的
加密服务透明地连接。当应用程序请求加密服务时,元插槽将指向最适合的插槽,这简化
了插槽的选择过程。在某些情况下可能需要一个不同的插槽,此时,应用程序必须显式地
执行单独的搜索。元插槽由系统自动启用,而且只能由系统管理员通过显式的操作来禁
用。
8第8 章
177
会话是令牌与使用加密服务的应用程序之间的连接。PKCS #11 标准使用两种对象:令牌对
象和会话对象。会话对象是暂时的对象,即它只在会话期间存在。在会话结束之后仍存在
的对象称作令牌对象。
令牌对象的缺省位置是$HOME/.sunw/pkcs11_softtoken。或者,可以将令牌对象存储到
$SOFTTOKEN_DIR/pkcs11_softtoken 中。专用令牌对象由个人识别码(personal identification
numbe, PIN) 保护。要创建或更改令牌对象,需要对用户进行验证,除非用户访问的是专用
令牌对象。
加密框架概述
加密框架是Solaris OS 的一部分,它提供Sun Microsystems, Inc. 和各个第三方供应商的加密
服务。加密框架提供以下各种服务:
 消息加密和消息摘要
 消息验证代码(Message authentication code, MAC)
 数字签名
 用来访问加密服务的应用程序编程接口(Application programming interface, API)
 用来提供加密服务的服务提供者接口(Service provider interface, SPI)
 用来管理加密资源的管理命令
下图提供了加密框架的概述。该图中的浅灰色阴影表示加密框架的用户级部分,深灰色阴
影表示加密框架的内核级部分,带有斜条纹的背景表示专用软件部分。
加密框架概述
178 Solaris 开发者安全性指南• 2006 年11 月
图8–1 Solaris 加密框架概述
 
 
以上文章转自于 : http://developers.sun.com.cn/
 
 
阅读(1091) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~