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

全部博文(554)

文章存档

2012年(1)

2011年(1)

2009年(8)

2008年(544)

分类:

2008-04-14 09:58:14


GSSAPI 客户机示例: main() 函数
第5 章• GSS-API 客户机示例105
示例5–1 gss-client 示例:main() (续)
port = atoi(*argv);
} else if (strcmp(*argv, "-mech") == 0) {
argc--; argv++;
if (!argc) usage();
mechanism = *argv;
} else if (strcmp(*argv, "-d") == 0) {
deleg_flag = GSS_C_DELEG_FLAG;
} else if (strcmp(*argv, "-f") == 0) {
use_file = 1;
} else
break;
argc--; argv++;
}
if (argc != 3)
usage();
if (argc > 1) {
strcpy(hostname, argv[0]);
} else if (gethostname(hostname, sizeof(hostname)) == -1) {
perror("gethostname");
exit(1);
}
GSSAPI 客户机示例: main() 函数
106 Solaris 开发者安全性指南• 2006 年11 月
示例5–1 gss-client 示例:main() (续)
if (argc > 2) {
strcpy(service_name, argv[1]);
strcat(service_name, "@");
strcat(service_name, hostname);
}
msg = argv[2];
/* Create GSSAPI object ID. */
if (mechanism)
parse_oid(mechanism, &g_mechOid);
/* Call server to create context and send data. */
if (call_server(hostname, port, g_mechOid, service_name,
deleg_flag, msg, use_file) < 0)
exit(1);
/* Release storage space for OID, if still allocated */
if (g_mechOid != GSS_C_NULL_OID)
(void) gss_release_oid(&min_stat, &gmechOid);
GSSAPI 客户机示例: main() 函数
第5 章• GSS-API 客户机示例107
示例5–1 gss-client 示例:main() (续)
return 0;
}
打开与服务器的连接
call_server() 函数使用以下代码与服务器建立连接:
if ((s = connect_to_server(host, port)) < 0)
return -1;
s 是一个最初通过调用socket() 返回的int 类型的文件描述符。
connect_to_server() 是GSS-API 外部的一个简单函数,它使用套接字来创建连接。
connect_to_server() 的源代码如以下示例所示。
注– 此示例的源代码也可以通过Sun 下载中心获取。请访问

示例5–2 connect_to_server() 函数
int connect_to_server(host, port)
char *host;
u_short port;
{
struct sockaddr_in saddr;
struct hostent *hp;
int s;
if ((hp = gethostbyname(host)) == NULL) {
fprintf(stderr, "Unknown host:%s\n", host);
return -1;
打开与服务器的连接
108 Solaris 开发者安全性指南• 2006 年11 月
示例5–2 connect_to_server() 函数(续)
}
saddr.sin_family = hp->h_addrtype;
memcpy((char *)&saddr.sin_addr, hp->h_addr, sizeof(saddr.sin_addr));
saddr.sin_port = htons(port);
if ((s = socket(AF_INET, SOCK_STREAM, 0)) < 0) {
perror("creating socket");
return -1;
}
if (connect(s, (struct sockaddr *)&saddr, sizeof(saddr)) < 0) {
perror("connecting to server");
(void) close(s);
return -1;
}
return s;
}
建立与服务器的安全上下文
建立连接之后,call_server() 会使用client_establish_context() 函数来创建安全上下
文,如下所示:
if (client_establish_context(s, service-name, deleg-flag, oid, &context,
&ret-flags) < 0) {
建立与服务器的安全上下文
第5 章• GSS-API 客户机示例109
(void) close(s);
return -1;
}
 s 是一个文件描述符,表示通过connect_to_server() 建立的连接。
 service-name 是所请求的网络服务。
 deleg-flag 用于指定服务器是否可以充当客户机的代理。
 oid 表示机制。
 context 是要创建的上下文。
 ret-flags 是一个int,用于指定GSS-API 函数gss_init_sec_context() 所返回的任何标
志。
client_establish_context() 执行以下任务:
 将服务名称转换为GSSAPI 内部格式
 在客户机和服务器之间循环执行令牌交换,直到建立完整的安全上下文为止
将服务名称转换为GSS-API 格式
client_establish_context() 执行的首个任务是使用gss_import_name() 将服务名称字符串
转换为GSS-API 内部格式。
示例5–3client_establish_context()-转换服务名称
/*
* Import the name into target_name. Use send_tok to save
* local variable space.
*/
send_tok.value = service_name;
send_tok.length = strlen(service_name) + 1;
maj_stat = gss_import_name(&min_stat, &send_tok,
(gss_OID) GSS_C_NT_HOSTBASED_SERVICE, &target_name);
if (maj_stat != GSS_S_COMPLETE) {
建立与服务器的安全上下文
110 Solaris 开发者安全性指南• 2006 年11 月
示例5–3 client_establish_context()-转换服务名称(续)
display_status("parsing name", maj_stat, min_stat);
return -1;
}
gss_import_name() 提取存储在不透明GSS_API 缓冲区send_tok 中的服务名称,然后将服务
名称字符串转换为GSS_API 内部名称target_name。send_tok 用于节省空间,而不是用于
声明新的gss_buffer_desc。第三个参数类型为gss_OID,用于指明send_tok 名称的格式。
此示例使用GSS_C_NT_HOSTBASED_SERVICE,这表示服务采用 格式。有关此参数
的其他可能值,请参见第305 页中的“名称类型”。
为GSS-API 建立安全上下文
将服务转换为GSS-API 内部格式之后即可建立上下文。为了尽可能提高可移植性,应当始
终循环建立上下文。
进入循环之前,client_establish_context() 会初始化上下文和token_ptr 参数。使用
token_ptr 时需要进行选择。token_ptr 可以指向send_tok(发送到服务器的令牌)或recv_tok
(服务器发回的令牌)。
在循环内部,需要检查两项:
 gss_init_sec_context() 返回的状态
返回状态可捕捉任何可能要求循环异常中止的错误。当且仅当服务器还要发送另一个令
牌时,gss_init_sec_context() 才会返回GSS_S_CONTINUE_NEEDED。
 gss_init_sec_context() 所生成的要发送到服务器的令牌的大小
如果令牌大小为零,则表示不再有可以发送到服务器的信息并且可以退出循环。令牌大
小可根据token_ptr 来确定。
以下伪代码对该循环进行了说明:
do
gss_init_sec_context()
if no context was created
exit with error;
if the status is neither "complete" nor "in process"
建立与服务器的安全上下文
第5 章• GSS-API 客户机示例111
release the service namespace and exit with error;
if there is a token to send to the server, that is, the size is nonzero
send the token;
if sending the token fails,
release the token and service namespaces. Exit with error;
release the namespace for the token that was just sent;
if the context is not completely set up
receive a token from the server;
while the context is not complete
该循环从调用gss_init_sec_context() 开始,该函数使用以下参数:
 要由基础机制设置的状态码。
 凭证句柄。此示例使用GSS_C_NO_CREDENTIAL 充当缺省主体。
 gss-context,表示要创建的上下文句柄。
 服务的target-name,作为GSS_API 内部名称。
 oid,机制的ID。
 请求标志。在本示例中,客户机请求执行以下操作:服务器对自身进行验证,打开消息
重复功能,服务器根据请求充当代理。
 对于上下文无时间限制。
 没有请求使用通道绑定。
 token_ptr,指向从服务器收到的令牌。
 服务器实际使用的机制。机制在此处设置为NULL,这是因为应用程序不会使用该值。
 &send_tok,即gss_init_sec_context() 所创建的要发送到服务器的令牌。
 返回标志。设置为NULL,这是因为在此示例中忽略了这些标志。
注– 客户机在启动上下文之前无需获取凭证。在客户端,凭证管理通过GSS-API 以透明方式
处理。即,GSS-API 知道如何获取此机制为该主体创建的凭证。因此,应用程序可以向
gss_init_sec_context() 传递缺省凭证。但是在服务器端,服务器应用程序在接受上下文之
前必须明确获取服务的凭证。请参见第132 页中的“获取凭证”。
检查了上下文或其一部分是否存在,以及gss_init_sec_context() 是否返回有效状态之
后,connect_to_server() 会检查gss_init_sec_context() 是否提供了要发送到服务器的令
牌。如果不存在任何令牌,则表明服务器已经指示不需要其他任何令牌。如果提供了令
建立与服务器的安全上下文
112 Solaris 开发者安全性指南• 2006 年11 月
牌,则必须将该令牌发送到服务器。如果发送该令牌失败,则无法确定该令牌和服务的名
称空间,并且connect_to_server() 将退出。以下算法通过查看令牌的长度来检查令牌是否
存在:
if (send_tok_length != 0) {
if (send_token(s, &send_tok) < 0) {
(void) gss_release_buffer(&min_stat, &send_tok);
(void) gss_release_name(&min_stat, &target_name);
return -1;
}
}
send_token() 不是GSS-API 函数,需要由用户进行编写。send_token() 函数可将令牌写入
到文件描述符中。send_token() 在成功时返回0,在失败时返回–1。GSS-API 本身不收发令
牌。调用应用程序负责收发GSS-API 已创建的任何令牌。
下面提供了用于建立上下文循环的源代码。
注– 此示例的源代码也可以通过Sun 下载中心获取。请访问

示例5–4用于建立上下文的循环
/*
* Perform the context establishment loop.
*
* On each pass through the loop, token_ptr points to the token
* to send to the server (or GSS_C_NO_BUFFER on the first pass).
* Every generated token is stored in send_tok which is then
* transmitted to the server; every received token is stored in
* recv_tok, which token_ptr is then set to, to be processed by
* the next call to gss_init_sec_context.
建立与服务器的安全上下文
第5 章• GSS-API 客户机示例113
示例5–4 用于建立上下文的循环(续)
*
* GSS-API guarantees that send_tok’s length will be non-zero
* if and only if the server is expecting another token from us,
* and that gss_init_sec_context returns GSS_S_CONTINUE_NEEDED if
* and only if the server has another token to send us.
*/
token_ptr = GSS_C_NO_BUFFER;
*gss_context = GSS_C_NO_CONTEXT;
1234567890123456789012345678901234567890123456789012345678901234567890123456
do {
maj_stat =
gss_init_sec_context(&min_stat, GSS_C_NO_CREDENTIAL,
gss_context, target_name, oid,
GSS_C_MUTUAL_FLAG | GSS_C_REPLAY_FLAG | deleg_flag,
0, NULL, /* no channel bindings */
token_ptr, NULL, /* ignore mech type */
&send_tok, ret_flags, NULL); /* ignore time_rec */
if (gss_context == NULL){
printf("Cannot create context\n");
return GSS_S_NO_CONTEXT;
}
建立与服务器的安全上下文
114 Solaris 开发者安全性指南• 2006 年11 月
示例5–4 用于建立上下文的循环(续)
if (token_ptr != GSS_C_NO_BUFFER)
(void) gss_release_buffer(&min_stat, &recv_tok);
if (maj_stat!=GSS_S_COMPLETE && maj_stat!=GSS_S_CONTINUE_NEEDED) {
display_status("initializing context", maj_stat, min_stat);
(void) gss_release_name(&min_stat, &target_name);
return -1;
}
if (send_tok.length != 0){
fprintf(stdout, "Sending init_sec_context token (size=%ld)...",
send_tok.length);
if (send_token(s, &send_tok) < 0) {
(void) gss_release_buffer(&min_stat, &send_tok);
(void) gss_release_name(&min_stat, &target_name);
return -1;
}
}
(void) gss_release_buffer(&min_stat, &send_tok);
if (maj_stat == GSS_S_CONTINUE_NEEDED) {
fprintf(stdout, "continue needed...");
if (recv_token(s, &recv_tok) < 0) {
(void) gss_release_name(&min_stat, &target_name);
建立与服务器的安全上下文
第5 章• GSS-API 客户机示例115
示例5–4 用于建立上下文的循环(续)
return -1;
}
token_ptr = &recv_tok;
}
printf("\n");
} while (maj_stat == GSS_S_CONTINUE_NEEDED);
有关send_token() 和recv_token() 工作方式的更多信息,请参见第283 页中的“各种
GSS-API 样例函数”。
客户端上的各种GSSAPI 上下文操作
作为样例程序,gss-client 所执行的一些功能用于说明。以下源代码不是执行基本任务所
必需的,之所以提供它是为了说明以下其他操作:
 保存和恢复上下文
 显示上下文标志
 获取上下文状态
这些操作的源代码如以下示例所示。
注– 此示例的源代码也可以通过Sun 下载中心获取。请访问

示例5–5 gss-client:call_server() 建立上下文
/* Save and then restore the context */
maj_stat = gss_export_sec_context(&min_stat,
&context,
&context_token);
if (maj_stat != GSS_S_COMPLETE) {
display_status("exporting context", maj_stat, min_stat);
客户端上的各种GSSAPI 上下文操作
116 Solaris 开发者安全性指南• 2006 年11 月
示例5–5 gss-client:call_server() 建立上下文(续)
return -1;
}
maj_stat = gss_import_sec_context(&min_stat,
&context_token,
&context);
if (maj_stat != GSS_S_COMPLETE) {
display_status("importing context", maj_stat, min_stat);
return -1;
}
(void) gss_release_buffer(&min_stat, &context_token);
/* display the flags */
display_ctx_flags(ret_flags);
/* Get context information */
maj_stat = gss_inquire_context(&min_stat, context,
&src_name, &targ_name, &lifetime,
&mechanism, &context_flags,
&is_local,
&is_open);
if (maj_stat != GSS_S_COMPLETE) {
display_status("inquiring context", maj_stat, min_stat);
return -1;
客户端上的各种GSSAPI 上下文操作
第5 章• GSS-API 客户机示例117
示例5–5 gss-client:call_server() 建立上下文(续)
}
if (maj_stat == GSS_S_CONTEXT_EXPIRED) {
printf(" context expired\n");
display_status("Context is expired", maj_stat, min_stat);
return -1;
}
包装和发送消息
gss-client 应用程序必须首先包装(即加密)数据,然后才能将其发送。应用程序通过执
行以下步骤来包装消息:
 确定包装大小限制,此过程可确保协议提供经过包装的消息。
 获取源和目标的名称。将名称从对象标识符转换为字符串。
 获取机制名称的列表。将名称从对象标识符转换为字符串。
 将消息插入到缓冲区中并对其进行包装。
 将消息发送到服务器。
以下源代码可用于包装消息。
注– 此示例的源代码也可以通过Sun 下载中心获取。请访问

示例5–6 gss-client 示例:call_server()-包装消息
/* Test gss_wrap_size_limit */
maj_stat = gss_wrap_size_limit(&min_stat, context, conf_req_flag,
GSS_C_QOP_DEFAULT, req_output_size, &max_input_size);
if (maj_stat != GSS_S_COMPLETE) {
display_status("wrap_size_limit call", maj_stat, min_stat);
} else
包装和发送消息
118 Solaris 开发者安全性指南• 2006 年11 月
示例5–6 gss-client 示例:call_server()-包装消息(续)
fprintf (stderr, "gss_wrap_size_limit returned "
"max input size = %d \n"
"for req_output_size = %d with Integrity only\n",
max_input_size , req_output_size , conf_req_flag);
conf_req_flag = 1;
maj_stat = gss_wrap_size_limit(&min_stat, context, conf_req_flag,
GSS_C_QOP_DEFAULT, req_output_size, &max_input_size);
if (maj_stat != GSS_S_COMPLETE) {
display_status("wrap_size_limit call", maj_stat, min_stat);
} else
fprintf (stderr, "gss_wrap_size_limit returned "
" max input size = %d \n" "for req_output_size = %d with "
"Integrity & Privacy \n", max_input_size , req_output_size );
maj_stat = gss_display_name(&min_stat, src_name, &sname, &name_type);
if (maj_stat != GSS_S_COMPLETE) {
display_status("displaying source name", maj_stat, min_stat);
return -1;
}
maj_stat = gss_display_name(&min_stat, targ_name, &tname,
(gss_OID *) NULL);
包装和发送消息
第5 章• GSS-API 客户机示例119
示例5–6 gss-client 示例:call_server()-包装消息(续)
if (maj_stat != GSS_S_COMPLETE) {
display_status("displaying target name", maj_stat, min_stat);
return -1;
}
fprintf(stderr, "\"%.*s\" to \"%.*s\", lifetime %u, flags %x, %s, %s\n",
(int) sname.length, (char *) sname.value, (int) tname.length,
(char *) tname.value, lifetime, context_flags,
(is_local) ? "locally initiated" :"remotely initiated",
(is_open) ? "open" :"closed");
(void) gss_release_name(&min_stat, &src_name);
(void) gss_release_name(&min_stat, &targ_name);
(void) gss_release_buffer(&min_stat, &sname);
(void) gss_release_buffer(&min_stat, &tname);
maj_stat = gss_oid_to_str(&min_stat, name_type, &oid_name);
if (maj_stat != GSS_S_COMPLETE) {
display_status("converting oid->string", maj_stat, min_stat);
return -1;
}
fprintf(stderr, "Name type of source name is %.*s.\n", (int) oid_name.length,
(char *) oid_name.value);
(void) gss_release_buffer(&min_stat, &oid_name);
包装和发送消息
120 Solaris 开发者安全性指南• 2006 年11 月
示例5–6 gss-client 示例:call_server()-包装消息(续)
/* Now get the names supported by the mechanism */
maj_stat = gss_inquire_names_for_mech(&min_stat, mechanism, &mech_names);
if (maj_stat != GSS_S_COMPLETE) {
display_status("inquiring mech names", maj_stat, min_stat);
return -1;
}
maj_stat = gss_oid_to_str(&min_stat, mechanism, &oid_name);
if (maj_stat != GSS_S_COMPLETE) {
display_status("converting oid->string", maj_stat, min_stat);
return -1;
}
mechStr = (char *)__gss_oid_to_mech(mechanism);
fprintf(stderr, "Mechanism %.*s (%s) supports %d names\n", (int) oid_name.length,
(char *) oid_name.value, (mechStr == NULL ? "NULL" :mechStr),
mech_names->count);
(void) gss_release_buffer(&min_stat, &oid_name);
for (i=0; i < mech_names->count; i++) {
maj_stat = gss_oid_to_str(&min_stat, &mech_names->elements[i], &oid_name);
if (maj_stat != GSS_S_COMPLETE) {
display_status("converting oid->string", maj_stat, min_stat);
包装和发送消息
第5 章• GSS-API 客户机示例121
示例5–6 gss-client 示例:call_server()-包装消息(续)
return -1;
}
fprintf(stderr, " %d:%.*s\n", i, (int) oid_name.length, (
char *) oid_name.value);
(void) gss_release_buffer(&min_stat, &oid_name);
}
(void) gss_release_oid_set(&min_stat, &mech_names);
if (use_file) {
read_file(msg, &in_buf);
} else {
/* Wrap the message */
in_buf.value = msg;
in_buf.length = strlen(msg) + 1;
}
if (ret_flag & GSS_C_CONF_FLAG) {
state = 1;
else
state = 0;
}
maj_stat = gss_wrap(&min_stat, context, 1, GSS_C_QOP_DEFAULT, &in_buf,
包装和发送消息
122 Solaris 开发者安全性指南• 2006 年11 月
示例5–6 gss-client 示例:call_server()-包装消息(续)
&state, &out_buf);
if (maj_stat != GSS_S_COMPLETE) {
display_status("wrapping message", maj_stat, min_stat);
(void) close(s);
(void) gss_delete_sec_context(&min_stat, &context, GSS_C_NO_BUFFER);
return -1;
} else if (! state) {
fprintf(stderr, "Warning! Message not encrypted.\n");
}
/* Send to server */
if (send_token(s, &out_buf) < 0) {
(void) close(s);
(void) gss_delete_sec_context(&min_stat, &context, GSS_C_NO_BUFFER);
return -1;
}
(void) gss_release_buffer(&min_stat, &out_buf);
读取和检验GSS-API 客户机中的签名块
现在,gss-client 程序可以测试已发送消息的有效性。服务器会针对已发送的消息返回
MIC。可以通过recv_token() 检索此消息。
然后,使用gss_verify_mic() 函数检验消息的签名(即MIC)。gss_verify_mic() 用于将
收到的MIC 与未包装的原始消息进行比较。收到的MIC 来自服务器的令牌,该令牌存储在
out_buf 中。来自未包装版本的消息的MIC 存放在in_buf 中。如果这两个MIC 匹配,系统便
会检验此消息。客户机随后会为所收到的令牌释放缓冲区out_buf。
以下源代码说明了读取和检验签名块的过程。
读取和检验GSS-API 客户机中的签名块
第5 章• GSS-API 客户机示例123
注– 此示例的源代码也可以通过Sun 下载中心获取。请访问

示例5–7 gss-client 示例-读取和检验签名块
/* Read signature block into out_buf */
if (recv_token(s, &out_buf) < 0) {
(void) close(s);
(void) gss_delete_sec_context(&min_stat, &context, GSS_C_NO_BUFFER);
return -1;
}
/* Verify signature block */
maj_stat = gss_(&min_stat, context, &in_buf,
&out_buf, &qop_state);
if (maj_stat != GSS_S_COMPLETE) {
display_status("verifying signature", maj_stat, min_stat);
(void) close(s);
(void) gss_delete_sec_context(&min_stat, &context, GSS_C_NO_BUFFER);
return -1;
}
(void) gss_release_buffer(&min_stat, &out_buf);
if (use_file)
free(in_buf.value);
读取和检验GSS-API 客户机中的签名块
124 Solaris 开发者安全性指南• 2006 年11 月
示例5–7 gss-client 示例-读取和检验签名块(续)
printf("Signature verified.\n");
删除安全上下文
call_server() 函数通过删除上下文并返回到main() 函数来结束操作。
注– 此示例的源代码也可以通过Sun 下载中心获取。请访问

示例5–8 gss-client 示例:call_server()-删除上下文
/* Delete context */
maj_stat = gss_delete_sec_context(&min_stat, &context, &out_buf);
if (maj_stat != GSS_S_COMPLETE) {
display_status("deleting context", maj_stat, min_stat);
(void) close(s);
(void) gss_delete_sec_context(&min_stat, &context, GSS_C_NO_BUFFER);
return -1;
}
(void) gss_release_buffer(&min_stat, &out_buf);
(void) close(s);
return 0;
删除安全上下文
第5 章• GSS-API 客户机示例125
126
GSS-API 服务器示例
本章将对gss-server 样例程序的源代码进行详细介绍,其中包含以下主题:
 第127 页中的“GSSAPI 服务器示例概述”
 第128 页中的“GSSAPI 服务器示例:main() 函数”
 第132 页中的“获取凭证”
 第137 页中的“检查inetd”
 第137 页中的“从客户机接收数据”
 第152 页中的“在GSSAPI 服务器示例中清除”
GSSAPI 服务器示例概述
样例服务器端程序gss-server 可以与上一章中介绍的gss-client 结合使用。gss-server 的
基本用途是从gssapi-client 接收和返回经过包装的消息并对其进行签名。
以下几节将提供有关gss-server 工作方式的逐步说明。由于gss-server 是一个用于说明
GSSAPI 功能的样例程序,因此仅详细讨论该程序的相关部分。这两个应用程序的完整源代
码可在附录中找到,也可以从以下网址下载:
http://developers.sun.com/prodtech/solaris/downloads/index.html
GSSAPI 服务器示例结构
gss-structure 应用程序执行以下步骤:
1. 解析命令行。
2. 如果指定了机制,请将该机制的名称转换为内部格式。
3. 获取调用方的凭证。
4. 查看用户是否指定了要使用inetd 守护进程进行连接。
5. 与客户机建立连接。
6. 从客户机接收数据。
7. 对数据进行签名并返回数据。
6第6 章
127
8. 释放名称空间并退出。
运行GSSAPI 服务器示例
gss-server 在命令行中采用以下形式:
gss-server [-port port] [-verbose] [-inetd] [-once] [-logfile file] \
[-mech mechanism] service-name
 port 是要侦听的端口号。如果未指定任何端口,则程序使用端口4444 作为缺省端口。
 -verbose 会导致在运行gss-server 时显示消息。
 -inetd 表示程序应当使用inetd 守护进程来侦听端口。-inetd 使用stdin 和stdout 连接
到客户机。
 -once 表示仅建立单实例连接。
 mechanism 是要使用的安全机制的名称,如Kerberos v5。如果未指定任何机制,GSS-API
将使用缺省机制。
 service-name 是客户机所请求的网络服务的名称,如telnet、ftp 或登录服务。
典型的命令行可能如以下示例所示:
% gss-server -port 8080 -once -mech kerberos_v5 erebos.eng nfs "hello"
GSSAPI 服务器示例:main() 函数
gss-server main() 函数可执行以下任务:
 解析命令行参数并为变量指定参数
 获取与机制对应的服务的凭证
 调用sign_server() 函数,该函数会执行涉及到对消息进行签名和返回消息等工作
 释放已经获取的凭证
 释放机制的OID 名称空间
 在连接仍处于打开状态时关闭连接
注– 此示例的源代码也可以通过Sun 下载中心获取。请访问

示例6–1 gss-server 示例:main()
int
main(argc, argv)
GSSAPI 服务器示例:main() 函数
128 Solaris 开发者安全性指南• 2006 年11 月
示例6–1 gss-server 示例:main() (续)
int argc;
char **argv;
{
char *service_name;
gss_cred_id_t server_creds;
OM_uint32 min_stat;
u_short port = 4444;
int s;
int once = 0;
int do_inetd = 0;
log = stdout;
display_file = stdout;
/* Parse command-line arguments. */
argc--; argv++;
while (argc) {
if (strcmp(*argv, "-port") == 0) {
argc--; argv++;
if (!argc) usage();
port = atoi(*argv);
} else if (strcmp(*argv, "-verbose") == 0) {
verbose = 1;
 
以上文章转自于 : http://developers.sun.com.cn/
阅读(896) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~