面向开发者的 Oracle® Solaris 11 安全性指南

退出打印视图

更新时间: 2014 年 7 月
 
 

SASL 周期中的步骤

下图显示了 SASL 生命周期中的步骤。客户机操作显示在图的左侧,服务器操作显示在右侧。中间的箭头显示客户机与服务器之间通过外部连接执行的交互操作。

图 7-2  SASL 生命周期

image:图中显示了 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()sasl_canonuser_add_plugin()sasl_auxprop_add_plugin() 来添加其他服务器插件。

    依据体系结构,我们在 Oracle 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 机制。

为使 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 会话的初始化过程。在此图和后续的图中,为了简单起见,省略了通过协议进行传输后的数据检查。

图 7-3  SASL 会话初始化

image:图中显示了在 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 上下文。

下图说明了此部分的验证过程。

图 7-4  SASL 验证:发送客户机数据

image:图中显示了客户机向服务器发送验证数据时客户机和服务器执行的步骤。

如果服务器对 sasl_server_start() 的调用返回 SASL_CONTINUE,则服务器将继续与客户机进行通信,以获取所有必要的验证信息。后续步骤的数目取决于机制。如果需要,客户机可以调用 sasl_client_step() 来处理来自服务器的验证数据并生成回复。同样,服务器可以调用 sasl_server_step() 来处理来自客户机的验证并相应地生成回复。此交换将持续进行下去,直到验证完成或出现错误为止。如果返回 SASL_OK,则指示对客户机或服务器的验证已成功完成。SASL 机制可能仍然具有要发送给另一端的其他数据,因此另一端可以完成验证。在两端都完成验证后,服务器和客户机便可查询彼此的属性。

下图显示了服务器与客户机之间为传输其他验证数据所执行的交互。

图 7-5  SASL 验证:处理服务器数据

image:图中显示了服务器向客户机返回数据时客户机和服务器执行的步骤。

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 连接的上下文资源。请参见libsasl Cleanup

释放 SASL 会话时,将通知关联的机制所有状态均可释放。只有在不会重复使用 SASL 会话时,才应释放该会话。否则,其他会话可以重复使用 SASL 状态。客户机和服务器都使用 sasl_dispose() 释放 SASL 连接上下文。

libsasl 清除

此步骤可释放 SASL 库和插件中的所有资源。客户机和服务器可以调用 sasl_done() 来释放 libsasl() 资源并卸载所有的 SASL 插件。sasl_done() 不会释放 SASL 连接上下文。请注意,如果应用程序同时为 SASL 客户机和 SASL 服务器,则 sasl_done() 将同时释放 SASL 客户机和 SASL 服务器资源。您不能仅释放客户机或服务器的资源。


Caution

注意  - 库不应调用 sasl_done()。应用程序在调用 sasl_done() 时务必要谨慎,避免与可能使用 libsasl 的任何库发生干扰。