カスタム Credential Provider で自動ログオンを行う方法

PlatformSDK( Windows SDK) サポートの mitsuruwです。

今年の夏もいよいよクライマックスにさしかかりましたが、皆様いかがお過ごしでしょうか。
我が家は今年一度もクーラーをつけていません。去年も一年通して 3 回しかつけなかったのですが、
案外扇風機でもなんとかなるものです。しかし、クーラーを使用していないため、この季節、アイロンだけは本当に大変です。
なんと驚くべきことに我が家では洗濯とアイロンは私の仕事なのです!
洗濯機は全自動なんだからアイロンも全自動があれば良いのに、といつも思います。
 
さて、アイロンは自動でかけてもらえませんが、Windows のログオンに使用される Credential Provider
では自動でログオンさせる仕組みが用意されています。今回はカスタムの Credential Provider を使用して
自動でログオンを行う方法をご紹介したいと思います。

Credential Provider による自動ログオン

すでにログオン アカウントとパスワードが事前に判明しているとき、カスタム Credential Provider
を使用して自動でログオンを行いたい場合があります。これを実現するためのインターフェースとして、
Credential Provider には以下の 2 つが用意されています。
 
 1) GetCredentialCount() メソッドを使用した自動ログオン
  Title : ICredentialProvider::GetCredentialCount Method (Windows)
  URL   : <https://msdn.microsoft.com/en-us/library/bb776039.aspx>
 
 2) SetSelected() メソッドを使用した自動ログオン
  Title : ICredentialProviderCredential::SetSelected Method (Windows)
  URL   : <https://msdn.microsoft.com/en-us/library/bb776034.aspx>
 
それぞれのインターフェースについて、もう少し詳しく見てみましょう。
 
1) GetCredentialCount() メソッドを使用した自動ログオン
Credntial Provider は、その中に複数の資格情報タイルを持つことが可能です。
例えば、前回ご紹介した SampleCredentialProvider も "Administrator" 用と "Guest" 用の
2 つの資格情報タイルをもっています。
 
GetCredentialCount() は Crednetial Provider のロード元である logonUI.exe が、
対象となる Credential Provider に対して、いくつの資格情報タイルを持っているのかの情報を
取得するために呼び出すメソッドです。そのため、GetCredentialCount() が呼び出された
Credential Provider は、pdwCount 引数に自身がもっている資格情報タイルの数を設定して
返さなければなりません。

また、pdwDefault 引数には、それらの資格情報タイルのうち、何番目のタイルを既定のタイルとするのか、
その Index を設定します。もし特に既定のタイルを設定しない場合には、pdwDefault 引数に
CREDENTIAL_PROVIDER_NO_DEFAULT を設定しておきます。
最後に残された pbAutoLogonWithDefault 引数ですが、この pbAutoLogonWithDefault 引数を TRUE に
設定して返すと、logonUI.exe 側に対して、"pdwDefault 引数に設定した(既定の) タイルを使用して
自動でログオンしてください" という意味になります。
これがひとつ目の自動ログオン設定のタイミングです。
 
-----
HRESULT CSampleProvider::GetCredentialCount(
    DWORD* pdwCount,
    DWORD* pdwDefault,
    BOOL* pbAutoLogonWithDefault
    )
{
    // GetCredentialCount() の実装例
      :
    *pdwCount = 2; // この CP は 2 つの資格情報タイルをもっています。
    *pdwDefault = 0; // 既定のタイルは 1 番目 (Index=0) のタイルです。
    *pbAutoLogonWithDefault = TRUE; // 既定のタイルを使用した自動ログオンを要求します。
        :
    return S_OK;
}
-----

2) SetSelected() メソッドを使用した自動ログオン
もうひとつの自動ログオン設定のタイミングは SetSelected() メソッドです。
SetSelected() は CredentialProvider が列挙された後、対象の資格情報タイルが選択された
タイミングで logonUI.exe から呼び出されます。この時、pbAutoLogon 引数に TRUE を設定すると、
"この資格情報タイルを使用して自動でログオンしてください" という意味になります。
-----
HRESULT CSampleCredential::SetSelected(BOOL* pbAutoLogon) 
{
    // SetSelected() の実装例
      :
    *pbAutoLogon = TRUE; // この資格情報タイルを使用した自動ログオンを要求します。
      :
    return S_OK;
}
------
 
上述した 2 つのメソッドの引数を設定することにより、logonUI.exe に対して自動ログオンを要求する
ことができます。例えば、別途動作している Windows サービス プロセスからログオン アカウントと
パスワードの情報を取得し、自動ログオンすることにより、ユーザーに資格情報を入力させずにログオンを
行うことも可能になります。また、この自動ログオンの仕組みを応用することによって、特定の USB  を
挿入したタイミングでログオンを行う、といったことも実現可能です。
 
しかし、自動ログオンのシナリオにはひとつ考慮しなければいけない大事なポイントがあります。
それは、もし自分以外の Credential Provider が登録されていて、その Credential Provider も同様に
自動ログオンを要求してきた場合です。
実は複数の Credential Provider が自動ログオンを要求してきた場合、logonUI.exe がどちらを優先
するかは不定です。そのため、自分の Credential Provider での自動ログオンを確実にするためには、
他の Credential Provider をフィルタして表示しないようにする必要があります。
 
次回はこの Credential Provider Filter (CP Filter) について少しご説明したいと思います。