InitializeSecurityContext (Negotiate) 関数
InitializeSecurityContext (Negotiate) 関数は、資格情報ハンドルからクライアント側の送信セキュリティ コンテキストを開始します。 関数は、クライアント アプリケーションとリモート ピアの間に セキュリティ コンテキスト を構築するために使用されます。 InitializeSecurityContext (Negotiate) は、クライアントがリモート ピアに渡す必要があるトークンを返します。このトークンは、ピアが AcceptSecurityContext (Negotiate) 呼び出しを通じてローカル セキュリティ実装に送信します。 生成されるトークンは、すべての呼び出し元によって不透明と見なされる必要があります。
通常、 InitializeSecurityContext (Negotiate) 関数は、十分な セキュリティ コンテキスト が確立されるまでループ内で呼び出されます。
構文
SECURITY_STATUS SEC_Entry InitializeSecurityContext(
_In_opt_ PCredHandle phCredential,
_In_opt_ PCtxtHandle phContext,
_In_opt_ SEC_CHAR *pszTargetName,
_In_ ULONG fContextReq,
_In_ ULONG Reserved1,
_In_ ULONG TargetDataRep,
_In_opt_ PSecBufferDesc pInput,
_In_ ULONG Reserved2,
_Inout_opt_ PCtxtHandle phNewContext,
_Inout_opt_ PSecBufferDesc pOutput,
_Out_ PULONG pfContextAttr,
_Out_opt_ PTimeStamp ptsExpiry
);
パラメーター
phCredential[in, optional]
AcquireCredentialsHandle (Negotiate) によって返される資格情報へのハンドル。 このハンドルは、 セキュリティ コンテキストを構築するために使用されます。 InitializeSecurityContext (Negotiate) 関数には、少なくとも OUTBOUND 資格情報が必要です。
phContext[in, optional]
CtxtHandle 構造体へのポインター。
InitializeSecurityContext (Negotiate) の最初の呼び出しでは、このポインターは ですNULL
。 2 番目の呼び出しでは、このパラメーターは、最初の呼び出しによって phNewContext パラメーターで返される部分的に形成されたコンテキストへのハンドルへのポインターです。
警告
InitializeSecurityContext (Negotiate) の同時呼び出しでは、同じコンテキスト ハンドルを使用しないでください。 セキュリティ サービス プロバイダーの API 実装はスレッド セーフではありません。
pszTargetName[in, optional]
サービス プリンシパル名 (SPN) または移行先サーバーの セキュリティ コンテキスト を示す null で終わる文字列へのポインター。
アプリケーションは、再生攻撃を軽減するために有効な SPN を提供する必要があります。
fContextReq[in]
コンテキストの要求を示すビット フラグ。 すべてのパッケージですべての要件をサポートできるわけではありません。 このパラメーターに使用されるフラグの前には、ISC_REQ_DELEGATEなどのISC_REQ_が付きます。 このパラメーターには、次の属性フラグの 1 つ以上を指定できます。
値 | 意味 |
---|---|
ISC_REQ_ALLOCATE_MEMORY | セキュリティ パッケージは、出力バッファーを割り当てます。 出力バッファーの使用が完了したら、 FreeContextBuffer 関数を呼び出して解放します。 |
ISC_REQ_CONFIDENTIALITY | EncryptMessage 関数を使用してメッセージを暗号化します。 |
ISC_REQ_CONNECTION | セキュリティ コンテキストでは、書式設定メッセージは処理されません。 この値は既定値です。 |
ISC_REQ_DELEGATE | サーバーは、コンテキストを使用して、クライアントとして他のサーバーに対する認証を行うことができます。 このフラグを機能させるには 、ISC_REQ_MUTUAL_AUTH フラグを設定する必要があります。 Kerberos に対して有効です。 制約付き委任の場合は、このフラグを無視します。 |
ISC_REQ_EXTENDED_ERROR | エラーが発生すると、リモート パーティに通知されます。 |
ISC_REQ_INTEGRITY | EncryptMessage 関数と MakeSignature 関数を使用して、メッセージに署名し、署名を確認します。 |
ISC_REQ_MUTUAL_AUTH | サービスの相互認証ポリシーが満たされます。 注意: これは、必ずしも相互認証が実行されるという意味ではなく、サービスの認証ポリシーが満たされていることを意味します。 相互認証を確実に実行するには、 QueryContextAttributes (Negotiate) 関数を 呼び出します。 |
ISC_REQ_NO_INTEGRITY | このフラグが設定されている場合、 ISC_REQ_INTEGRITY フラグは無視されます。 |
ISC_REQ_REPLAY_DETECT | EncryptMessage 関数または MakeSignature 関数を使用してエンコードされた再生されたメッセージを検出します。 |
ISC_REQ_SEQUENCE_DETECT | 受信したメッセージを順番に検出します。 |
ISC_REQ_STREAM | ストリーム指向接続をサポートします。 |
要求された属性は、クライアントでサポートされていない可能性があります。 詳細については、 pfContextAttr パラメーターを参照してください。
さまざまな属性の詳細については、「 コンテキスト要件」を参照してください。
予約済み 1[in]
このパラメーターは予約済みであり、0 に設定する必要があります。
TargetDataRep[in]
ターゲットのデータ表現 (バイト順序など)。 このパラメーターには、SECURITY_NATIVE_DREPまたはSECURITY_NETWORK_DREPを指定できます。
pInput[in, optional]
パッケージへの入力として指定されたバッファーへのポインターを含む SecBufferDesc 構造体へのポインター。 クライアント コンテキストがサーバーによって開始されていない限り、このパラメーターの値は NULL
関数の最初の呼び出しで指定する必要があります。 以降の関数の呼び出し、またはクライアント コンテキストがサーバーによって開始されたとき、このパラメーターの値は、リモート コンピューターによって返されるトークンを保持するのに十分なメモリが割り当てられたバッファーへのポインターです。
予約済み 2[in]
このパラメーターは予約済みであり、0 に設定する必要があります。
phNewContext[in, out, optional]
CtxtHandle 構造体へのポインター。
InitializeSecurityContext (Negotiate) の最初の呼び出しで、このポインターは新しいコンテキスト ハンドルを受け取ります。 2 番目の呼び出しでは、 phNewContext は phContext パラメーターで指定されたハンドルと同じにすることができます。
phNewContext を にしないでください NULL
。
pOutput[in, out, optional]
出力データを受信する SecBuffer 構造体へのポインターを含む SecBufferDesc 構造体へのポインター。 入力にSEC_READWRITEとしてバッファーが入力された場合は、出力時にそのバッファーが存在します。 システムは、(ISC_REQ_ALLOCATE_MEMORYを介して) 要求された場合にセキュリティ トークンのバッファーを割り当て、セキュリティ トークンのバッファー記述子にアドレスを入力します。
pfContextAttr[out]
確立されたコンテキストの 属性 を示すビット フラグのセットを受け取る変数へのポインター。 さまざまな属性の説明については、「 コンテキスト要件」を参照してください。
このパラメーターに使用されるフラグには、ISC_RET_DELEGATEなどのISC_RETが付きます。 有効な値の一覧については、 fContextReq パラメーターを参照してください。
最後の関数呼び出しが正常に返されるまで、セキュリティ関連の属性をチェックしないでください。 セキュリティに関連しない属性フラグ (ASC_RET_ALLOCATED_MEMORY フラグなど) は、最終的な戻り値の前に確認できます。
注意
特定のコンテキスト属性は、リモート ピアとのネゴシエーション中に変更される可能性があります。
ptsExpiry[out, optional]
コンテキストの有効期限を受け取る TimeStamp 構造体へのポインター。
セキュリティ パッケージでは、常にローカル時刻にこの値を返すようにすることをお勧めします。 このパラメーターは省略可能であり、 NULL
有効期間の短いクライアントに渡す必要があります。
戻り値
関数が成功した場合、関数は次のいずれかの成功コードを返します。
リターン コード | 説明 |
---|---|
SEC_E_OK | セキュリティ コンテキストが正常に初期化されました。 別の InitializeSecurityContext (Negotiate) 呼び出しは必要ありません。 関数が出力トークンを返す場合、つまり pOutput のSECBUFFER_TOKENの長さが 0 以外の場合は、そのトークンをサーバーに送信する必要があります。 |
SEC_I_COMPLETE_AND_CONTINUE | クライアントは CompleteAuthToken を 呼び出し、出力をサーバーに渡す必要があります。 その後、クライアントは返されたトークンを待機し、別の呼び出しで InitializeSecurityContext (Negotiate) に渡します。 |
SEC_I_COMPLETE_NEEDED | クライアントはメッセージの作成を完了し、 CompleteAuthToken 関数を呼び出す必要があります。 |
SEC_I_CONTINUE_NEEDED | クライアントは出力トークンをサーバーに送信し、戻りトークンを待機する必要があります。 返されたトークンは、 InitializeSecurityContext (Negotiate) の別の呼び出しで渡されます。 出力トークンは空にすることができます。 |
関数が失敗した場合、関数は次のいずれかのエラー コードを返します。
リターン コード | 説明 |
---|---|
SEC_E_INSUFFICIENT_MEMORY | 要求されたアクションを完了するのに十分なメモリがありません。 |
SEC_E_INTERNAL_ERROR | SSPI エラー コードにマップされないエラーが発生しました。 |
SEC_E_INVALID_HANDLE | 関数に渡されたハンドルが無効です。 |
SEC_E_INVALID_TOKEN | このエラーは、転送中に破損したトークン、サイズが正しくないトークン、間違った制約付き 委任に渡されたトークンなど、入力トークンの形式が正しくないことが原因です。 クライアントとサーバーが適切な 制約付き委任をネゴシエートしなかった場合、間違ったパッケージにトークンを渡すと発生する可能性があります。 |
SEC_E_LOGON_DENIED | ログオンに失敗しました。 |
SEC_E_NO_AUTHENTICATING_AUTHORITY | 認証のために機関に連絡できませんでした。 認証パーティのドメイン名が間違っているか、ドメインに到達できないか、信頼関係エラーが発生している可能性があります。 |
SEC_E_NO_CREDENTIALS | 制約付き委任では、資格情報を使用できません。 |
SEC_E_TARGET_UNKNOWN | ターゲットが認識されませんでした。 |
SEC_E_UNSUPPORTED_FUNCTION | fContextReq パラメーターで無効なコンテキスト属性フラグ (ISC_REQ_DELEGATEまたはISC_REQ_PROMPT_FOR_CREDS) が指定されました。 |
SEC_E_WRONG_PRINCIPAL | 認証要求を受け取ったプリンシパルは、 pszTargetName パラメーターに渡されたものと同じではありません。 これは、相互認証の失敗を示します。 |
解説
呼び出し元は、最終的なコンテキスト属性で十分かどうかを判断する責任があります。 たとえば、機密性が要求されたが確立できなかった場合、一部のアプリケーションは接続を直ちにシャットダウンすることを選択できます。
セキュリティ コンテキストの属性が十分でない場合、クライアントは DeleteSecurityContext 関数を呼び出して、部分的に作成されたコンテキストを解放する必要があります。
InitializeSecurityContext (Negotiate) 関数は、クライアントが送信コンテキストを初期化するために使用します。
2 足の セキュリティ コンテキストの場合、呼び出しシーケンスは次のようになります。
- クライアントは 、phContext を に設定して 関数を
NULL
呼び出し、バッファー記述子に入力メッセージを入力します。 - セキュリティ パッケージは、パラメーターを調べて不透明なトークンを構築し、バッファー配列の TOKEN 要素に配置します。 fContextReq パラメーターに ISC_REQ_ALLOCATE_MEMORY フラグが含まれている場合、セキュリティ パッケージはメモリを割り当て、TOKEN 要素内のポインターを返します。
- クライアントは 、pOutput バッファーで返されたトークンをターゲット サーバーに送信します。 その後、サーバーは AcceptSecurityContext (Negotiate) 関数の呼び出しでトークンを入力引数として渡します。
- AcceptSecurityContext (Negotiate) はトークンを返すことができます。このトークンは、最初の呼び出しがSEC_I_CONTINUE_NEEDED返された場合に、 InitializeSecurityContext (Negotiate) の 2 回目の呼び出しのためにサーバーがクライアントに送信します。
相互認証などの複数の脚の セキュリティ コンテキストの場合、呼び出しシーケンスは次のようになります。
- クライアントは前述のように 関数を呼び出しますが、パッケージはSEC_I_CONTINUE_NEEDED成功コードを返します。
- クライアントは出力トークンをサーバーに送信し、サーバーの応答を待機します。
- サーバーの応答を受信すると、クライアントは InitializeSecurityContext (Negotiate) を再度呼び出し、 phContext は最後の呼び出しから返されたハンドルに設定されます。 サーバーから受信したトークンは pInput パラメーターで指定されます。
- InitializeSecurityContext (Negotiate) の同時呼び出しでは、phContext 値を使用しないでください。 セキュリティ プロバイダーの実装はスレッド セーフではありません。
サーバーが正常に応答した場合、 セキュリティ パッケージ はSEC_E_OKを返し、セキュリティで保護されたセッションが確立されます。
関数からいずれかのエラー応答が返された場合、サーバーの応答は受け入れられません。セッションは確立されません。
関数がSEC_I_CONTINUE_NEEDED、SEC_I_COMPLETE_NEEDED、またはSEC_I_COMPLETE_AND_CONTINUEを返す場合は、手順 2 と 3 が繰り返されます。
セキュリティ コンテキストを初期化するには、基になる認証メカニズムと fContextReq パラメーターで指定された選択肢に応じて、この関数の複数の呼び出しが必要になる場合があります。
fContextReq パラメーターと pfContextAttributes パラメーターは、さまざまなコンテキスト属性を表すビットマスクです。 さまざまな属性の説明については、「 コンテキスト要件」を参照してください。 pfContextAttributes パラメーターは、正常に戻った場合は有効ですが、最終的に正常に返された場合にのみ、コンテキストのセキュリティの側面に関連するフラグを調べる必要があります。 中間の戻り値は、たとえば、ISC_RET_ALLOCATED_MEMORY フラグを設定できます。
ISC_REQ_USE_SUPPLIED_CREDS フラグが設定されている場合、 セキュリティ パッケージ は pInput 入力バッファーでSECBUFFER_PKG_PARAMSバッファーの種類を検索する必要があります。 これは一般的なソリューションではありませんが、必要に応じて セキュリティ パッケージ とアプリケーションの強力なペアリングを可能にします。
ISC_REQ_ALLOCATE_MEMORYが指定されている場合、呼び出し元は FreeContextBuffer 関数を呼び出してメモリを解放する必要があります。
たとえば、入力トークンが LAN マネージャーからの課題である可能性があります。 この場合、出力トークンは、チャレンジに対する NTLM で暗号化された応答になります。
クライアントが実行するアクションは、この関数からのリターン コードによって異なります。 戻りコードがSEC_E_OK場合、2 回目の InitializeSecurityContext (Negotiate) 呼び出しはなく、サーバーからの応答は必要ありません。 戻りコードがSEC_I_CONTINUE_NEEDED場合、クライアントはサーバーからの応答でトークンを受け取り、 InitializeSecurityContext (Negotiate) の 2 回目の呼び出しで渡します。 SEC_I_COMPLETE_NEEDED戻りコードは、クライアントがメッセージの作成を完了し、 CompleteAuthToken 関数を呼び出す必要があることを示します。 SEC_I_COMPLETE_AND_CONTINUE コードには、これらのアクションの両方が組み込まれています。
InitializeSecurityContext (Negotiate) が最初の (または唯一の) 呼び出しで成功を返す場合、呼び出し元は最終的に、呼び出しが認証交換の後の区間で失敗した場合でも、返されたハンドルで DeleteSecurityContext 関数を呼び出す必要があります。
クライアントは、正常に完了した後に InitializeSecurityContext (Negotiate) を再度呼び出す場合があります。 これは、再認証が必要であることを セキュリティ パッケージ に示します。
カーネル モードの呼び出し元には、次の違いがあります。ターゲット名は、VirtualAlloc を使用して仮想メモリに割り当てる必要がある Unicode 文字列です。プールから割り当ててはいけません。 pInput および pOutput で渡され、提供されるバッファーは、プール内ではなく仮想メモリ内に存在する必要があります。
要件
要件 | 値 |
---|---|
サポートされている最小のクライアント | Windows XP [デスクトップ アプリのみ] |
サポートされている最小のサーバー | Windows Server 2003 [デスクトップ アプリのみ] |
Header | Sspi.h (Security.h を含む) |
ライブラリ | Secur32.lib |
[DLL] | Secur32.dll |
こちらもご覧ください
AcceptSecurityContext (ネゴシエート)