ICカードを使ってパソコンにログオンするアプリを作成しています。
マイクロソフトのサンプルアプリをベースにICカードを読み取るロジックの実装まで行うことができましたが、
ログオンを行う部分の実装で躓いています。
カードを検知し内容を読み取った後、カードに紐づくユーザIDでログオンを行いたいのですが、
以下のロジック(MyLogonUser())で返り値正常となるもののログオン画面からデスクトップ画面に遷移できない状況です。
※カードとユーザIDは事前に紐づけ情報をパソコンに保存しています
いろいろググってはいるものの、CredentialProvider自体の情報が乏しく、
サンプルアプリ自体の理解度も進んでいない状態です。
勉強になりそうなサイトがございましたら、教えていただきたく思います。
■質問事項
・「LsaLogonUser」ではログオン(デスクトップ画面に遷移)することができないのでしょうか?
・「LsaLogonUser」を実行した後、ログオンするための別の処理が必要なのでしょうか?
■開発環境
・Windows8.1Pro 64Bit
・Visual Studio 2017 C++
・「test」というユーザが1つ存在している状態
■実装ロジック
ログオン部分の実装になります。その他のロジックはどこを提示して良いかの判断がつきませんでした。
ご指摘いただきましたら、その都度掲載するようにいたします。
○クラス
・CCredentialProvider
GetCredentialCount()でCCredentialProviderCredentialを呼び出ししています
・CCredentialProviderCredential
カードの受付開始/停止(SmartCard)及び読み取った内容の表示を行っています
・SmartCard
カード検知、内容の読み出しとログオン処理を行っています
○ログオン部分
#カード内容の読取後に実行している処理
#※ユーザID/パスワードは固定にしています
NTSTATUS st;
HANDLE lsa;
HANDLE hToken;
LSA_STRING lsaString;
ULONG uPackageId;
st = LsaConnectUntrusted(&lsa);
if (st != 0)
{
DebugPrint(L"LsaConnectUntrusted failed");
}
else
{
DebugPrint(L"LsaConnectUntrusted ok");
InitString(&lsaString, MSV1_0_PACKAGE_NAME);
st = LsaLookupAuthenticationPackage(lsa, &lsaString, &uPackageId);
if (st != 0)
{
DebugPrint(L"LsaLookupAuthenticationPackage failed");
LsaDeregisterLogonProcess(lsa);
}
else
{
DebugPrint(L"LsaLookupAuthenticationPackage ok");
if (!MyLogonUser(lsa, uPackageId, L"test", L"12345678", L"", &hToken)) {
DebugPrint(L"MyLogonUser failed ");
LsaDeregisterLogonProcess(lsa);
}
else {
DebugPrint(L"MyLogonUser ok");
CloseHandle(hToken);
LsaDeregisterLogonProcess(lsa);
}
}
}
extern "C" BOOL MyLogonUser(HANDLE hLsa, ULONG uPackageId, LPWSTR lpszUserName, LPWSTR lpszPassword, LPWSTR lpszDomainName, HANDLE *phToken)
{
LUID luid;
ULONG uBufferLength;
ULONG uProfileLength;
LPBYTE lp;
NTSTATUS ns;
NTSTATUS nsSub;
LSA_STRING lsaOriginal;
QUOTA_LIMITS limits;
TOKEN_SOURCE tokenSource;
MSV1_0_INTERACTIVE_LOGON msvLogon;
PMSV1_0_INTERACTIVE_LOGON pmsvLogon;
PMSV1_0_INTERACTIVE_PROFILE pmsvProfile;
InitString(&lsaOriginal, "origial");
uBufferLength = sizeof(MSV1_0_INTERACTIVE_LOGON);
uBufferLength += InitUnicodeString(&msvLogon.UserName, lpszUserName);
uBufferLength += InitUnicodeString(&msvLogon.Password, lpszPassword);
uBufferLength += InitUnicodeString(&msvLogon.LogonDomainName, lpszDomainName);
msvLogon.MessageType = MsV1_0InteractiveLogon;
lp = (LPBYTE)LocalAlloc(LPTR, uBufferLength);
CopyMemory(lp, (PVOID)&msvLogon, sizeof(MSV1_0_INTERACTIVE_LOGON));
pmsvLogon = (PMSV1_0_INTERACTIVE_LOGON)lp;
lp += sizeof(MSV1_0_INTERACTIVE_LOGON);
FormatBuffer(&lp, &pmsvLogon->UserName);
lp += pmsvLogon->UserName.Length;
FormatBuffer(&lp, &pmsvLogon->Password);
lp += pmsvLogon->Password.Length;
FormatBuffer(&lp, &pmsvLogon->LogonDomainName);
lstrcpyA(tokenSource.SourceName, "LsaLogonUser");
AllocateLocallyUniqueId(&tokenSource.SourceIdentifier);
ns = LsaLogonUser(hLsa, &lsaOriginal, Interactive, uPackageId,
(PVOID)pmsvLogon, uBufferLength, 0, &tokenSource, (PVOID *)&pmsvProfile,
&uProfileLength, &luid, phToken, &limits, &nsSub);
if (LsaNtStatusToWinError(ns) != ERROR_SUCCESS) {
LocalFree(pmsvLogon);
return FALSE;
}
LsaFreeReturnBuffer(pmsvProfile);
LocalFree(pmsvLogon);
return TRUE;
}
extern "C" ULONG InitString(PLSA_STRING plsaString, LPSTR lpszString)
{
if (lpszString == NULL) {
plsaString->Length = 0;
plsaString->MaximumLength = 0;
plsaString->Buffer = NULL;
}
else {
plsaString->Length = (USHORT)(lstrlenA(lpszString) * sizeof(CHAR));
plsaString->MaximumLength = plsaString->Length + sizeof(CHAR);
plsaString->Buffer = lpszString;
}
return plsaString->Length;
}
extern "C" ULONG InitUnicodeString(PLSA_UNICODE_STRING plsaString, LPWSTR lpszString)
{
if (lpszString == NULL) {
plsaString->Length = 0;
plsaString->MaximumLength = 0;
plsaString->Buffer = NULL;
}
else {
plsaString->Length = (USHORT)(lstrlen(lpszString) * sizeof(WCHAR));
plsaString->MaximumLength = plsaString->Length + sizeof(WCHAR);
plsaString->Buffer = lpszString;
}
return plsaString->Length;
}
extern "C" void FormatBuffer(LPBYTE *lp, PUNICODE_STRING pString)
{
if (pString->Buffer != NULL) {
CopyMemory(*lp, pString->Buffer, pString->Length);
pString->Buffer = (LPWSTR)*lp;
}
}