GSS-API のプログラミング

sign_server()

sign_server() はプログラムの中心部分です。server_establish_context() を呼び出してコンテキストを受け入れ、データを受信、ラップ解除、および検証し、そしてクライアントに返送する MIC を生成します。最後に、コンテキストを削除します。


例 A–12 sign_server()


/*
 * 関数: 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);
}