2016-03-14 76 views
0

我試圖從一個工作站(本地)上的智能卡讀取憑證,然後將其發送到不同的工作站(遠程)並使用它從憑證提供程序登錄到該工作站。Windows憑據提供程序遠程登錄

我一直在尋找,並研究了幾個星期,但還沒有找到任何人顯示或告訴如何做到這一點。

我發現在https://www.idrix.fr/Root/Samples/LsaSmartCardLogon2.cpp,這是一個智能卡憑證提供程序的工作代碼的一個很好的工作的幾個引用,但不幸的是要求憑證提供者可以直接訪問智能卡上的憑據。

我正在使用的實際代碼似乎有點太長,以包括在帖子中,所以我想我嘗試使用sudo代碼問這個問題。 在本地工作站:

MySendCredentialsFromSmartCard(){ 
    CryptAcquireContext(hProv, containerName, cardName, PROV_RSA_FULL, CRYPT_SILENT) 
    CryptGetUserKey(*hProv, AT_KEYEXCHANGE, &hCryptKey); 
    CryptGetKeyParam(hCryptKey, KP_CERTIFICATE, encodedCert, &size, 0); 
    MySendCertToRemote(encodedCert,size); 
} 

在遠程工作站中的自定義憑據提供運行:

HRESULT CSampleCredential::GetSerialization( 
    _Out_ CREDENTIAL_PROVIDER_GET_SERIALIZATION_RESPONSE *pcpgsr, 
    _Out_ CREDENTIAL_PROVIDER_CREDENTIAL_SERIALIZATION *pcpcs, 
    _Outptr_result_maybenull_ PWSTR *ppwszOptionalStatusText, 
    _Out_ CREDENTIAL_PROVIDER_STATUS_ICON *pcpsiOptionalStatusIcon){ 

    MyReadCertFromRemote(&cert,&size); 
    CryptAcquireContext(&hCryptProv, NULL, NULL, PROV_RSA_FULL, 0); 
    CryptCreateHash(hCryptProv, CALG_SHA1, NULL, 0, &hHash); 
    CryptHashData(hHash, (BYTE *)cert, (DWORD)size, 0); 

    CERT_CREDENTIAL_INFO certInfo; 

    CryptGetHashParam(hHash, HP_HASHVAL, certInfo.rgbHashOfCert, &dwHashLen, 0); 
    CredMarshalCredential(CertCredential, &certInfo, marshalledCred); 
/****************************for debug only*****************************/ 
    LogonUser((*marshalledCred, NULL, NULL, LOGON32_LOGON_NEW_CREDENTIALS, LOGON32_PROVIDER_WINNT50, &userHandle); 
//this reuturns 1 (success) 
/**************************************************************************/ 
    KERB_INTERACTIVE_UNLOCK_LOGON kiul; 
    CREDENTIAL_PROVIDER_USAGE_SCENARIO cpus 
    KerbInteractiveUnlockLogonInit(L"", (PWSTR)marshaledCred, L"", cpus, &kiul);//(note:I've tried this with the third param set to the card's pin) 
    KerbInteractiveUnlockLogonPack(kiul, &pcpcs->rgbSerialization, &pcpcs->cbSerialization); 
    RetrieveNegotiateAuthPackage(&ulAuthPackage); 
    pcpcs->ulAuthenticationPackage = ulAuthPackage; 
    pcpcs->clsidCredentialProvider = CLSID_OfProvider; 
    *pcpgsr = CPGSR_RETURN_CREDENTIAL_FINISHED; 
} 

LogonUI.exe顯示「指定的登錄會話不存在,它可能已被終止。」這個接口與Windows錯誤代碼1312相對應。似乎大多數開發人員在使用此錯誤代碼時都遇到了使用SSL證書配置IIS的問題。我發現沒有提及與憑證提供者有關的這個錯誤。 各種線程似乎表明LogonUser是一個圍繞LSALogonUser的包裝器,ICredentialProviderCredential :: GetSerialization的返回值將傳遞給LSALogonUser。事實上,我打電話給LogonUser的編組憑證成功似乎表明,我在正確的軌道上,但我一直無法驗證,也沒有找出我失蹤的東西。 我想盡量避免需要將憑據存儲在遠程工作站上的解決方案,因爲它通常是域管理員憑據。 任何想法任何人?任何建議如何進行?

感謝

回答

0

我想你可以使用一個通信機制做到這一點,你從一個工作站發送數據到另一個和你SetSerialization(串行數據的遠程一個),而不是GetSerialization()的,準備所有字段並處理登錄。

從我對您的理解來看,Provider類(由ICredentialProvider繼承的類)必須以某種方式等待這些憑據並將它們傳遞給SetSerialization