sign_server() はプログラムの中心部分です。server_establish_context() を呼び出してコンテキストを受け入れ、データを受信、ラップ解除、および検証し、そしてクライアントに返送する MIC を生成します。最後に、コンテキストを削除します。
/* * 関数: sign_server * * 目的: 「署名」サービスを実行する * * 引数: * * s (r) 接続が受け入れられた TCP ソケット * service_name (r) コンテキストを確立する GSS-API サービスの ASCII 名 * * 戻り値: エラーが発生した場合は -1 * * 効果: * * sign_server はコンテキストを確立し、単一の署名要求を実行する * * 署名要求は単一の GSS-AP ラップ済みトークンである。まず、 * このトークンがラップ解除される。次に、署名ブロックが * gss_get_mic で生成され、送信側に戻される。コンテキストが * 破棄され、接続が閉じられる。 * * エラーが発生した場合、-1 が戻される。 */ 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; /* クライアントとのコンテキストを確立する */ 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; /* ラップ済みメッセージトークンを受信する */ if (recv_token(s, &xmit_buf) < 0) return(-1); if (verbose && log) { fprintf(log, "Wrapped 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("unwrapping 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]) && isprint(cp[1])) fprintf(log, "\"%s\"\n", cp); else { printf("\n"); print_token(&msg_buf); } /* メッセージの署名ブロックを生成する */ 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); /* 署名ブロックをクライアントに送信する */ if (send_token(s, &xmit_buf) < 0) return(-1); (void) gss_release_buffer(&min_stat, &xmit_buf); /* コンテキストを削除する */ 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); } |