检查 inetd 之后,gss-server 程序会调用 sign_server(),该函数用于执行程序的主要工作。sign_server() 首先通过调用 server_establish_context() 来建立上下文。
sign_server() 可执行以下任务:
接受上下文
展开数据
对数据进行签名
返回数据
这些任务将在以下各节中进行介绍。以下源代码说明了 sign_server() 函数。
int sign_server(s, server_creds) int s; gss_cred_id_t server_creds; { gss_buffer_desc client_name, xmit_buf, msg_buf; gss_ctx_id_t context; OM_uint32 maj_stat, min_stat; int i, conf_state, ret_flags; char *cp; /* Establish a context with the client */ if (server_establish_context(s, server_creds, &context, &client_name, &ret_flags) < 0) return(-1); printf("Accepted connection: \"%.*s\"\n", (int) client_name.length, (char *) client_name.value); (void) gss_release_buffer(&min_stat, &client_name); for (i=0; i < 3; i++) if (test_import_export_context(&context)) return -1; /* Receive the sealed message token */ if (recv_token(s, &xmit_buf) < 0) return(-1); if (verbose && log) { fprintf(log, "Sealed message token:\n"); print_token(&xmit_buf); } maj_stat = gss_unwrap(&min_stat, context, &xmit_buf, &msg_buf, &conf_state, (gss_qop_t *) NULL); if (maj_stat != GSS_S_COMPLETE) { display_status("unsealing message", maj_stat, min_stat); return(-1); } else if (! conf_state) { fprintf(stderr, "Warning! Message not encrypted.\n"); } (void) gss_release_buffer(&min_stat, &xmit_buf); fprintf(log, "Received message: "); cp = msg_buf.value; if ((isprint(cp[0]) || isspace(cp[0])) && (isprint(cp[1]) || isspace(cp[1]))) { fprintf(log, "\"%.*s\"\n", msg_buf.length, msg_buf.value); } else { printf("\n"); print_token(&msg_buf); } /* Produce a signature block for the message */ maj_stat = gss_get_mic(&min_stat, context, GSS_C_QOP_DEFAULT, &msg_buf, &xmit_buf); if (maj_stat != GSS_S_COMPLETE) { display_status("signing message", maj_stat, min_stat); return(-1); } (void) gss_release_buffer(&min_stat, &msg_buf); /* Send the signature block to the client */ if (send_token(s, &xmit_buf) < 0) return(-1); (void) gss_release_buffer(&min_stat, &xmit_buf); /* Delete context */ maj_stat = gss_delete_sec_context(&min_stat, &context, NULL); if (maj_stat != GSS_S_COMPLETE) { display_status("deleting context", maj_stat, min_stat); return(-1); } fflush(log); return(0); }