GSS-API のプログラミング

コンテキストの受け入れ

コンテキストの確立では、クライアントとサーバー間で一連のトークンが交換されます。したがって、プログラムの移植性を保持するために、コンテキストの受け入れとコンテキストの起動はループで行われる必要があります。実際、コンテキストを受け入れるためのループとコンテキストを確立するためのループは (まったく逆ですが) 非常によく似ています。コンテキストの確立と比較してください。

  1. サーバーが最初に行うことは、クライアントがコンテキスト起動プロセスの一部として送信したトークンを探すことです。GSS-API 自身はトークンを送受信しないことを思い出してください。したがって、この作業を行うには、プログラムは独自のルーチンを持つ必要があります。サーバーがトークンの受信用に使用するルーチンを、この例では recv_token() としています。詳細は、recv_token()を参照してください。


         do {
              if (recv_token(s, &recv_tok) < 0)
                   return -1;
  2. 次に、プログラムは GSS-API 関数 gss_accept_sec_context() を呼び出します。


      maj_stat = gss_accept_sec_context(&min_stat,
                                       context,
                                       server_creds,
                                       &recv_tok,
                                       GSS_C_NO_CHANNEL_BINDINGS,
                                       &client,
                                       &doid,
                                       &send_tok,
                                       ret_flags,
                                       NULL,    /* time_rec を無視する */
                                       NULL);   /* del_cred_handle を無視する */
    次に、各引数について説明します。
    • min_stat は実際の機構から戻されるエラー状態です。

    • context は確立されているコンテキストです。

    • server_creds は提供されているサーバーの資格です (資格の獲得を参照)。

    • recv_tokrecv_token() でクライアントから受信したトークンです。

    • GSS_C_NO_CHANNEL_BINDINGS はチャネルバインディングを使用しないことを示すフラグです (チャネルバインディングを参照)。

    • client はクライアント名 (ASCII 文字) です。

    • oid は機構です (OID 形式)。

    • send_tok はクライアントに送信するトークンです。

    • ret_flags は、コンテキストがサポートするオプション (メッセージ順序検出など) を示すさまざまなフラグです。

    • NULL は、コンテキストが有効である期間の長さにも、サーバーがクライアントのプロキシとして動作できるかどうかにも、プログラムが関与していないことを示します。

    gss_accept_sec_context()maj_statGSS_S_CONTINUE_NEEDED を設定している限り、受け入れループは継続します (エラーの場合を除く)。maj_stat の値が GSS_S_CONTINUE_NEEDED でも GSS_S_COMPLETE でもない場合、問題が発生し、ループが終了したことを示します。

  3. クライアントに返送するトークンが存在する場合、gss_accept_sec_context()send_tok の長さ (正の数) を戻します。次に行うことは、送信するトークンがあるかどうかを調べて、もしあれば、そのトークンを送信することです。


         if (send_tok.length != 0) {
              . . .
              if (send_token(s, &send_tok) < 0) {
                   fprintf(log, "failure sending token\n");
                   return -1;
              }
    
              (void) gss_release_buffer(&min_stat, &send_tok);
              }