GSS-API のプログラミング

コンテキストの起動 (クライアント)

アプリケーションとリモートピア間でのセキュリティコンテキストの起動は、gss_init_sec_context() 関数で行います。成功した場合、gss_init_sec_context() 関数は確立中のコンテキストのコンテキストハンドルと、受け入れ側に送信するコンテキストレベルトークンを戻します。しかし、gss_init_sec_context() を呼び出す前に、クライアントは次のことを行う必要があります。

  1. 必要であれば、gss_acquire_cred() で資格を獲得します。しかし、通常、クライアントはログイン時に資格を受け取っているため、その場合、この手順は飛ばすことができます。

  2. gss_import_name() で、サーバー名を GSS-API 内部形式にインポートします。名前と gss_import_name() についての詳細は、名前を参照してください。

gss_init_sec_context() を呼び出すとき、通常、クライアントは次の引数値を渡します。

アプリケーションは必ずしもこのようなデフォルト値を使用する必要はありません。さらに、クライアントは req_flags 引数を使用して、他のセキュリティパラメータに対する要件を指定することもあります。gss_init_sec_context() 引数についての詳細は、以降の節で説明します。

コンテキストを確立するために、コンテキスト受け入れ側はいくつかの「ハンドシェーク」を要求できます。つまり、コンテキストが完全に確立されたと考えられるまでに、複数のコンテキスト情報を送信するように起動側に要求できます。したがって、移植性のため、コンテキストの起動は常に、コンテキストが完全に確立されたかどうかを検査するループの一部として行われる必要があります。

コンテキストが完全に確立されていない場合、gss_init_sec_context() はメジャー状態コードとして GSS_C_CONTINUE_NEEDED を戻します。したがって、ループは gss_init_sec_context() の戻り値を使用して、起動ループを継続するかどうかをテストする必要があります。

クライアントはコンテキスト情報をサーバーに、gss_init_sec_context() から戻された出力トークンの形式で渡します。その後、クライアントはこの情報をサーバーから入力トークンとして受け取ります。すると、後続の gss_init_sec_context() の呼び出しに引数として渡すことができます。受け取った入力トークンの長さが 0 の場合、サーバーはこれ以上出力トークンを要求していないことが分かります。

したがって、gss_init_sec_context() の戻り状態を検査することに加えて、ループは入力トークンの長さを検査して、さらにトークンをサーバーに送信するのかどうかを判断する必要があります。ループが始まる前には、入力トークンを GSS_C_NO_BUFFER に設定するか、構造体の長さフィールドを 0 に設定することによって、入力トークンの長さを 0 に初期化する必要があります。

次に、このようなループの例を示します。かなり一般化されています。


context = GSS_C_NO_CONTEXT を入れる
input token = GSS_C_NO_BUFFER を入れる

do {

     gss_init_sec_context(credential, context, name, input_token, 
          output_token, other args...)

     if (受け入れ側に送信する output_token がある時)

          受け入れ側に output_token を送信
          output_token を解放する

     if (context が完全でない時)

          受け入れ側から input_token を受け取る

     if (GSS-API エラーがある時)
          context を削除する

} while (context が完全になるまで)

当然、実際のループはより複雑になります。たとえば、より多くのエラー検査が必要になるなどです。このようなコンテキスト起動ループの実際の例については、コンテキストの確立(プログラムリストは client_establish_context()) を参照してください。さらに、gss_init_sec_context(3GSS) のマニュアルページにも、上記例ほど一般化されていない例があります。

繰り返しますが、GSS-API 自身はトークンを送受信しません。トークンの送受信はアプリケーションが処理する必要があります。トークン転送関数の例については、send_token()recv_token()を参照してください。

次に、gss_init_sec_context() の形式を示します。詳細は、gss_init_sec_context(3GSS) のマニュアルページを参照してください。


例 1–6 gss_init_sec_context()


     OM_uint32 gss_init_sec_context (
       OM_uint32                    *minor_status,
       const gss_cred_id_t          initiator_cred_handle,
       gss_ctx_id_t                 *context_handle,
       const gss_name_t             target_name,
       const gss_OID                mech_type,
       OM_uint32                    req_flags,
       OM_uint32                    time_req,
       const gss_channel_bindings_t input_chan_bindings,
       const gss_buffer_t           input_token
       gss_OID                      *actual_mech_type,
       gss_buffer_t                 output_token,
       OM_uint32                    *ret_flags,
       OM_uint32                    *time_rec )

minor_status

実際の機構から戻される状態コード。

initiator_cred_handle

アプリケーションの資格ハンドル。デフォルトの資格を使用することを示すには、GSS_C_NO_CREDENTIAL に初期化する必要があります。

context_handle

戻すべきコンテキストハンドル。ループが始まる前には、GSS_C_NO_CONTEXT に設定する必要があります。

target_name

接続先のプリンシパルの名前。たとえば、「nfs@machinename」などです。

mech_type

使用されるセキュリティ機構。GSS-API が提供するデフォルトを取得するには、GSS_C_NO_OID に設定します。

req_flags

このコンテキストで要求される追加のサービスまたはパラメータを示すフラグ。req_flags フラグは次のようにビット論理和をとって、希望のビットマスク値を作成する必要があります。


GSS_C_MUTUAL_FLAG | GSS_C_DELEG_FLAG

GSS_C_DELEG_FLAG

起動側の資格を委託できるように要求します。委託を参照してください。

GSS_C_MUTUAL_FLAG

相互認証を要求します。相互認証を参照してください。

GSS_C_REPLAY_FLAG

繰り返しメッセージを検出するように要求します。誤順序の検出とリプレイの検出を参照してください。

GSS_C_SEQUENCE_FLAG

誤順序メッセージを検出するように要求します。誤順序の検出とリプレイの検出を参照してください。

GSS_C_CONF_FLAG

転送されるメッセージに機密性サービスを適用するように、つまり、メッセージを暗号化するように要求します。機密性が許可されない場合、データ起点認証と (GSS_C_INTEG_FLAG が偽でなければ) 整合性サービスだけを適用できます。

GSS_C_INTEG_FLAG

メッセージに整合性サービスを適用するように、つまり、メッセージに MIC を付けて有効性を保証するように要求します。

GSS_C_ANON_FLAG

起動側が匿名のままであるように要求します。匿名認証を参照してください。

time_req

コンテキストが有効であるべき時間 (秒)。デフォルトを要求するには、0 に設定します。

input_chan_bindings

セキュリティコンテキストに接続された特定のピアツーピアのチャネル識別情報。チャネルバインディングについての詳細は、チャネルバインディングを参照してください。チャネルバインディングを使用しない場合は、GSS_C_NO_CHANNEL_BINDINGS に設定します。

input_token

コンテキスト受け入れ側から受信したトークン (もしあれば)。関数が呼び出される前に、GSS_C_NO_BUFFER に初期化する (あるいは、長さフィールドを 0 に設定する) 必要があります。

actual_mech_type

コンテキストで実際に使用される機構。どの機構が使用されるかを知る必要がない場合は、NULL に設定します。

output_token

受け入れ側に送信すべきトークン。

ret_flags

このコンテキストで要求された、追加のサービスまたはパラメータを示すフラグ。ret_flags フラグは次のようにビット論理積をとって、戻されたビットマスク値をテストする必要があります。


if (ret_flags & GSS_C_CONF_FLAG)
     confidentiality = TRUE;

GSS_C_DELEG_FLAG

真の場合、起動側の資格が委託できることを示します。委託を参照してください。

GSS_C_MUTUAL_FLAG

真の場合、相互認証が使用できることを示します。相互認証を参照してください。

GSS_C_REPLAY_FLAG

真の場合、繰り返しメッセージの検出が有効であることを示します。誤順序の検出とリプレイの検出を参照してください。

GSS_C_SEQUENCE_FLAG

真の場合、誤順序メッセージの検出が有効であることを示します。誤順序の検出とリプレイの検出を参照してください。

GSS_C_CONF_FLAG

真の場合、転送されるメッセージに機密性サービスを適用できます。つまり、メッセージを暗号化できます。機密性が許可されない場合、データ起点認証と (GSS_C_INTEG_FLAG が偽でなければ) 整合性サービスだけを適用できます。

GSS_C_INTEG_FLAG

真の場合、メッセージに整合性サービスを適用できます。つまり、メッセージに MIC (Message Integrity Code) を付けて有効性を保証できます。

GSS_C_ANON_FLAG

真の場合、コンテキスト起動側が匿名のままであることを示します。匿名認証を参照してください。

GSS_C_PROT_READY_FLAG

コンテキストの確立に時間がかかり、完了するまで、クライアントが待機する場合もあります。コンテキストが完全に確立されていない場合でも、gss_init_sec_context() は、コンテキストが完全に確立された後にどの保護サービスが使用できるかを (もしあれば) 示すことができます。したがって、アプリケーションはデータをバッファに格納しておいて、コンテキストが完全に確立された後で、バッファに格納しておいたデータを送信できます。

ret_flagsGSS_C_PROT_READY_FLAG を示す場合、コンテキストが完全に確立されていない場合でも (つまり、gss_init_sec_context()GSS_S_CONTINUE_NEEDED を戻す場合でも)、GSS_C_CONF_FLAGGSS_C_INTEG_FLAG が示す保護サービスを使用できます。すると、アプリケーションは希望の保護サービスに適切なラップ関数 (gss_wrap() または gss_get_mic()) を呼び出し、さらに、コンテキストが完全に確立されたときに転送する出力をバッファに格納できます。

GSS_C_PROT_READY_FLAG が偽の場合、アプリケーションはデータ保護を仮定できず、コンテキストの確立が完了するまで (つまり、gss_init_sec_context()GSS_S_COMPLETE を戻すまで) 待機する必要があります。


注 –

GSS-API の以前のバージョンは GSS_C_PROT_READY_FLAG 引数をサポートしていません。したがって、移植性を最大限にしたい開発者は、コンテキストの確立が完了した後で GSS_C_CONF_FLAGGSS_C_INTEG_FLAG フラグを調べて、どのメッセージ毎サービスを使用できるかを判断する必要があります。


GSS_C_TRANS_FLAG

このコンテキストがエクスポートできるかどうかを示します。コンテキストのインポートとエクスポートについての詳細は、コンテキストのエクスポートとインポートを参照してください。

time_rec

資格が有効である時間 (秒)。時間が重要でない場合は、NULL に設定します。

一般に、コンテキストが完全に確立されていない時に戻されるパラメータ値は、コンテキストが完了する時に入力されるはずの値です。詳細は、gss_init_sec_context() のマニュアルページを参照してください。

正常に終了した場合、gss_init_sec_context()GSS_S_COMPLETE を戻します。コンテキスト確立トークンがピアとなるアプリケーションから要求された場合、gss_init_sec_context()GSS_S_CONTINUE_NEEDED を戻します。エラーが発生した場合、gss_init_sec_context() はエラーコードを戻します。エラーコードについては、gss_init_sec_context(3GSS) のマニュアルページを参照してください。

コンテキストの起動が失敗した場合、クライアントはサーバーから切断する必要があります。