Solaris 开发者安全性指南

获取凭证

凭证由基础机制创建,而不是由客户机应用程序、服务器应用程序或 GSS-API 创建。客户机程序通常具有在登录时获取的凭证。服务器需要始终明确获取凭证。

gss-server 程序包含 server_acquire_creds() 函数,该函数用于获取要提供的服务的凭证。server_acquire_creds() 将该服务的名称和要使用的安全机制用作输入,然后返回该服务的凭证。

server_acquire_creds() 使用 GSS-API 函数 gss_acquire_cred() 来获取服务器所提供的服务的凭证。server_acquire_creds() 访问 gss_acquire_cred() 之前必须执行以下两个任务:

  1. 检查机制列表并将该列表缩减成单个机制以获取凭证。

    如果多个机制可以共享单个凭证,gss_acquire_cred() 函数将返回所有这些机制的凭证。因此,gss_acquire_cred() 会将一组机制用作输入。(请参见在 GSS-API 中使用凭证。)但是,在大多数情况(包括此情况)下,单个凭证可能并不适用于多个机制。gss-server 程序中会在命令行上指定单个机制或使用缺省机制。因此,第一个任务是确保传递给 gss_acquire_cred() 的那组机制中包含单个机制(缺省机制或其他机制),如下所示:

    if (mechOid != GSS_C_NULL_OID) {
    
         desiredMechs = &mechOidSet;
    
         mechOidSet.count = 1;
    
         mechOidSet.elements = mechOid;
    
    } else
    
         desiredMechs = GSS_C_NULL_OID_SET;

    GSS_C_NULL_OID_SET 表示应当使用缺省机制。

  2. 将服务名称转换为 GSS-API 格式。

    由于 gss_acquire_cred() 会接受 gss_name_t 结构形式的服务名称作为参数,因此必须将服务名称转换为这种格式。可使用 gss_import_name() 函数执行此转换。与所有 GSS-API 函数一样,此函数要求参数采用 GSS-API 类型,因此必须首先将服务名称复制到 GSS-API 缓冲区,如下所示:

         name_buf.value = service_name;
    
         name_buf.length = strlen(name_buf.value) + 1;
    
         maj_stat = gss_import_name(&min_stat, &name_buf,
    
                    (gss_OID) GSS_C_NT_HOSTBASED_SERVICE, &server_name);
    
         if (maj_stat != GSS_S_COMPLETE) {
    
              display_status("importing name", maj_stat, min_stat);
    
              if (mechOid != GSS_C_NO_OID)
    
                    gss_release_oid(&min_stat, &mechOid);
    
              return -1;
    
         }

    另请注意非标准函数 gss_release_oid() 的用法。

    输入是 name_buf 中字符串形式的服务名称。输出是一个指向 gss_name_t 结构 server_name 的指针。第三个参数 GSS_C_NT_HOSTBASED_SERVICEname_buf 中字符串的名称类型。在这种情况下,名称类型表示应当将字符串解释为 service@host 格式的服务。

执行这些任务之后,服务器程序可以调用 gss_acquire_cred()

maj_stat = gss_acquire_cred(&min_stat, server_name, 0,

                                 desiredMechs, GSS_C_ACCEPT,

                                 server_creds, NULL, NULL);

以下源代码说明了 server_acquire_creds() 函数。


注 –

此示例的源代码也可以通过 Sun 下载中心获取。请访问 http://www.sun.com/download/products.xml?id=41912db5



示例 6–2 server_acquire_creds() 函数的样例代码

/*

 * Function: server_acquire_creds

 *

 * Purpose: imports a service name and acquires credentials for it

 *

 * Arguments:

 *

 *      service_name    (r) the ASCII service name

        mechType        (r) the mechanism type to use

 *      server_creds    (w) the GSS-API service credentials

 *

 * Returns: 0 on success, -1 on failure

 *

 * Effects:

 *

 * The service name is imported with gss_import_name, and service

 * credentials are acquired with gss_acquire_cred.  If either operation

 * fails, an error message is displayed and -1 is returned; otherwise,

 * 0 is returned.

 */

int server_acquire_creds(service_name, mechOid, server_creds)

     char *service_name;

     gss_OID mechOid;

     gss_cred_id_t *server_creds;

{

     gss_buffer_desc name_buf;

     gss_name_t server_name;

     OM_uint32 maj_stat, min_stat;

     gss_OID_set_desc mechOidSet;

     gss_OID_set desiredMechs = GSS_C_NULL_OID_SET;



     if (mechOid != GSS_C_NULL_OID) {

                desiredMechs = &mechOidSet;

                mechOidSet.count = 1;

                mechOidSet.elements = mechOid;

     } else

                desiredMechs = GSS_C_NULL_OID_SET;



     name_buf.value = service_name;

     name_buf.length = strlen(name_buf.value) + 1;

     maj_stat = gss_import_name(&min_stat, &name_buf,

                (gss_OID) GSS_C_NT_HOSTBASED_SERVICE, &server_name);

     if (maj_stat != GSS_S_COMPLETE) {

          display_status("importing name", maj_stat, min_stat);

          if (mechOid != GSS_C_NO_OID)

                gss_release_oid(&min_stat, &mechOid);

          return -1;

     }



     maj_stat = gss_acquire_cred(&min_stat, server_name, 0,

                                 desiredMechs, GSS_C_ACCEPT,

                                 server_creds, NULL, NULL);



     if (maj_stat != GSS_S_COMPLETE) {

          display_status("acquiring credentials", maj_stat, min_stat);

          return -1;

     }



     (void) gss_release_name(&min_stat, &server_name);



     return 0;

}