クローキング (COM)
クローキングは、偽装中にクライアントがサーバーに対してプロジェクトする ID を決定する COM セキュリティ機能です。 クローキングが設定されると、中間サーバーは独自の ID をマスクし、クライアントの代わりに呼び出すサーバーにクライアントの ID を提示します。 基本的には;サーバーによって表示されるクライアント ID は、プロキシに関連付けられている ID です。 プロキシの ID はいくつかの要因によって決まります。そのうちの 1 つは、設定されているクローキングの種類 (存在する場合) です。 クローキングは、Schannel セキュリティ プロバイダーではサポートされていません。
次のトピックでは、AUTO モードの詳細について説明します。
クローキングの種類
クローシングには、静的クローキングと動的クローキングの 2 種類があります。
- 静的クローリング (EOAC_STATIC_CLOAKING) では、サーバーは、クライアントからサーバーへの最初の呼び出しからのスレッド トークンを確認します。 最初の呼び出しで、CoSetProxyBlanket の呼び出し中にプロキシ ID が以前に設定されていた場合、そのプロキシ ID が使用されます。 ただし、プロキシ ID が以前に設定されていない場合は、スレッド トークンが使用されます。 スレッド トークンが存在しない場合は、プロセス トークンが使用されます。 今後のすべての呼び出しでは、最初の呼び出しで設定された ID が使用されます。
- 動的クローキング (EOAC_DYNAMIC_CLOAKING) では、各呼び出しで現在のスレッド トークン (スレッド トークンがある場合) を使用して、クライアントの ID を判断します。 スレッド トークンがない場合は、プロセス トークンが使用されます。 つまり、偽装中にクライアントの代わりに呼び出されたサーバーは、呼び出しを開始した COM クライアントの ID を確認します。これは通常、望ましい動作です。 (もちろん、偽装を成功させるには、適切な偽装レベルを設定して偽装する権限をクライアントがサーバーに与えている必要があります。詳細については、「偽装レベル」を参照してください)。この種のクローキングは高価です。
クローキングがクライアント ID に与える影響
暗号化された呼び出しが行われ、サーバーがクライアントにその ID を要求すると、通常はプロキシに関連付けられた ID が取得されます。 (認証サービスが実際の ID からの変換を実行する場合がありますが、一般にプロキシ ID はサーバーが参照する ID です)。プロキシは、設定されているクローキングの種類やその他の要因に依存する ID をサーバーに提示します。
要約すると、クライアントの ID は、クローキング フラグ セット、プロセス トークン、スレッド トークンの有無、およびプロキシ ID が以前に設定されているかどうかの関数です。 次の表は、これらの要因が異なる場合に生成されるプロキシ ID (クライアント ID) を示しています。
クローキング フラグ | スレッド トークンのプレゼンス | 以前に設定されたプロキシ ID | プロキシ ID (クライアント ID) |
---|---|---|---|
クローキングが設定されていません |
Don't care |
Don't care |
プロセス トークンまたは認証 ID |
EOAC_STATIC_CLOAKING |
提示 |
いいえ |
スレッド トークン |
EOAC_STATIC_CLOAKING |
提示 |
はい |
現在のプロキシ ID |
EOAC_STATIC_CLOAKING |
なし |
いいえ |
プロセス トークン |
EOAC_STATIC_CLOAKING |
なし |
はい |
現在のプロキシ ID |
EOAC_DYNAMIC_CLOAKING |
提示 |
Don't care |
スレッド トークン |
EOAC_DYNAMIC_CLOAKING |
なし |
Don't care |
プロセス トークン |
次のフローチャートは、さまざまな状況でプロキシ ID がどのように決定されるかを示しています。
クローキングの設定
クローキングは、プロセス全体のクローキングを設定する CoInitializeSecurity の呼び出しで機能フラグとして設定されます。 その後、クライアントが IClientSecurity::SetBlanket (または CoSetProxyBlanket) の呼び出しによって変更されるまで、クローキング機能が設定されます。これにより、プロキシのクローリングが設定されます。
既定では、クローキングは設定されていません。 これを設定するには、CoInitializeSecurity または SetBlanket の pCapabilities パラメーターにEOAC_STATIC_CLOAKINGまたはEOAC_DYNAMIC_CLOAKINGを渡します。
CoInitializeSecurity を使用して静的クローキングを有効にすると、プロキシで初めて呼び出しを行うときに、各プロキシがトークン (スレッドまたはプロセス) を取得します。 SetBlanket を使用して静的クローキングが有効になっている場合、プロキシはその時点でスレッド上のトークンを取得します。 SetBlanket が呼び出されたときにスレッド トークンが使用できない場合、プロセス トークンはプロキシの ID に使用されます。 基本的に、 SetBlanket はプロキシの ID を修正します。
動的クローキングでは、動的クローキングが CoInitializeSecurity を使用するか SetBlanket を使用して設定されているかに関係なく、プロキシの ID が同じ方法で決定されます。 現在のスレッド トークンが存在する場合は使用されます。それ以外の場合は、プロセス トークンが使用されます。
CoInitializeSecurity の呼び出しによってプロセス全体にクローキングが設定されていて、プロセス トークンを使用して呼び出しを行う場合は、呼び出しの実行中に偽装しないでください。
クローキングと偽装レベル
前述メンションように、クローキング機能によって、偽装中にサーバーに表示される ID が決まります。 クローキングは、サーバーがクライアントの代わりに呼び出している別のサーバーに独自の ID 以外の ID を投影する方法を提供します。 偽装レベルは、クライアントがサーバーに与える権限の量を示します。
クローキングなしの偽装は機能しますが、場合によっては、最終的なサーバーが最初の呼び出し元の ID を知る必要があるため、最適な選択ではない可能性があります。 承認されたクライアントのみがリモート コンピューターにアクセスできるようにすることが困難なため、クローキングを使用しないと実現できません。 偽装がクロークなしで使用される場合、ダウンストリーム サーバーに提示される ID は、即時呼び出しプロセスの ID です。
しかし、クローキングは偽装なしでは役に立ちません。 クローキングは、クライアントが偽装または委任の偽装レベルを設定している場合にのみ意味があります。 (偽装レベルが低い場合、サーバーはクロークされた呼び出しを行うことができません)。クローキングが成功するかどうかは、クロスしたコンピューター境界の数と偽装レベルによって異なります。これは、サーバーがクライアントに代わって動作する必要がある権限の量を示します。
場合によっては、クライアントが偽装レベルをRPC_C_IMP_LEVEL_IMPERSONATEに設定するときに、サーバーがクローキングを設定するのが理にかなっています。 ただし、特定の制限が有効です。 元のクライアントが偽装レベルをRPC_C_IMP_LEVEL_IMPERSONATEに設定した場合、中間サーバー (同じコンピューター上のクライアントとして機能) は、1 つのコンピューター境界を越えてのみクロークできます。 プロセスがこのレベルでクライアントを偽装している場合、偽装トークンは 1 つコンピューターの境界のみを超えて渡すことができます。 コンピューターの境界を越えた後は、ローカル リソースにのみアクセスできます。 サーバーに提示される ID は、設定されているクローキングの種類によって異なります。 クローキングが設定されていない場合、サーバーに提示される ID は、即時呼び出しを行うプロセスの ID になります。
複数のコンピューター境界を越えてクロークするには、適切なクローキング機能フラグと委任レベルの偽装の両方を指定する必要があります。 この種類の偽装では、クライアントのローカル資格情報とネットワーク資格情報の両方がサーバーに付与されるため、偽装トークンは任意の数のコンピューター境界を超えることができます。 ここでも、サーバーに提示される ID は、設定されているクローキングの種類によって異なります。 委任レベルの偽装でクローキングが設定されていない場合、サーバーに提示される ID は呼び出しを行うプロセスの ID です。
たとえば、プロセス A が B を呼び出し、B 呼び出し C. B がクローキングを設定し、A が偽装レベルを偽装に設定したとします。 A、B、C が同じコンピューター上にある場合、偽装トークンを A から B に渡してから C に渡すと機能します。 ただし、A と C が同じコンピューター上にあり、B がそうでない場合、トークンを A と B の間で渡すことはできますが、B から C には渡しません。B から C への呼び出しは失敗します。これは、クローキング中に B が C を呼び出すことができないためです。 ただし、A が偽装レベルを委任するように設定した場合、トークンは B から C に渡され、呼び出しが成功する可能性があります。
クローキングのシナリオ
次の図では、プロセス A は B を呼び出し、C を呼び出し、クローキングが設定されていない場合は D を呼び出します。 その結果、各中間プロセスは、それを呼び出したプロセスの ID を確認します。
静的クローリングでは、サーバーは、クライアントからサーバーへの最初の呼び出し中に設定されたプロキシ ID を確認します。 次の図は、B から C への呼び出し中に設定されるプロキシ ID の例を示しています。後続の呼び出しで、B と C によって静的クローキングが設定されている場合、プロセス D は B の ID を確認します。
動的クローキングでは、偽装中の呼び出し元の ID は、現在のスレッド トークン (存在する場合) に基づいています。 次の図は、B から C への以前の呼び出しにもかかわらず、B と C が動的クローキングを設定し、D が A の ID を確認する状況を示しています。