Discussion:
Any credential provider gurus out there?
(too old to reply)
Dana Epp [Security MVP]
2008-05-27 22:39:51 UTC
Permalink
Hey guys,

I need some help. Hoping someone in the community has some experience with
writing Credential Providers in Vista or Windows Server 2008.

I have went through all the samples, and the very LITTLE documentation on
the topic in MSDN, and still not clear on a few things. I am hoping someone
could give me some pointers.

I am wrapping the password credential provider and adding an extra password
field. I have it set up so I can do my own password validation logic and
work with the extra field in GetSerialization() just fine. If I find that
the second password is invalid, I want to return a failure, and go to the
blank screen where it can say something like "Bad secondary password". I
would EXPECT this is done in ReportResult(). However, just what are you
supposed to do in GetSerialization() to fire off directly to ReportResult()
so I can output the error string I want? I thought I could do something
like:

*pcpsiOptionalStatusIcon = CPSI_ERROR;
*pcpgsr = CPGSR_RETURN_CREDENTIAL_FINISHED;
hr = ERROR_NOT_AUTHENTICATED;

Problem is it doesn't enter into ReportResult(). I don't want it to actually
call into the LSA* functions underneith. By not passing it down to the
wrapped CP, I assumed I could do the control I wanted.

Any ideas how to do that? Basically if during GetSerialization() I find a
failure, I want to show the results screen and put my error message up. I
don't seem to see any documentation on that. None of the samples cover this
scenario that I can see.

Any pointers to documentation or examples on how to do this would be greatly
appreciated.

Regards,
Dana
Kashif Mushtaq
2008-06-03 19:37:01 UTC
Permalink
GetSerialization is actual place where you will validate your data before
letting the control go back to windows.

if your authentication fails, you can use set control text functions to
display error message on the tile (small and large text fields etc)

Thats how I used it and I did all my validations in GetSerialization
functions (Implemented One Time Password Validation)
Post by Dana Epp [Security MVP]
Hey guys,
I need some help. Hoping someone in the community has some experience with
writing Credential Providers in Vista or Windows Server 2008.
I have went through all the samples, and the very LITTLE documentation on
the topic in MSDN, and still not clear on a few things. I am hoping someone
could give me some pointers.
I am wrapping the password credential provider and adding an extra password
field. I have it set up so I can do my own password validation logic and
work with the extra field in GetSerialization() just fine. If I find that
the second password is invalid, I want to return a failure, and go to the
blank screen where it can say something like "Bad secondary password". I
would EXPECT this is done in ReportResult(). However, just what are you
supposed to do in GetSerialization() to fire off directly to ReportResult()
so I can output the error string I want? I thought I could do something
*pcpsiOptionalStatusIcon = CPSI_ERROR;
*pcpgsr = CPGSR_RETURN_CREDENTIAL_FINISHED;
hr = ERROR_NOT_AUTHENTICATED;
Problem is it doesn't enter into ReportResult(). I don't want it to actually
call into the LSA* functions underneith. By not passing it down to the
wrapped CP, I assumed I could do the control I wanted.
Any ideas how to do that? Basically if during GetSerialization() I find a
failure, I want to show the results screen and put my error message up. I
don't seem to see any documentation on that. None of the samples cover this
scenario that I can see.
Any pointers to documentation or examples on how to do this would be greatly
appreciated.
Regards,
Dana
Kashif Mushtaq
2008-06-03 19:46:01 UTC
Permalink
you can also use custom dialog or message box



//user logging to local workstation
if(wcsicmp(bstrDomain.m_str, bstrComputerName.m_str)!=0)
{

CComBSTR bValidateWS = Validate_Workstation(bstrDomain, bstrComputerName);
if(bValidateWS==L"0")
{
//not in domain
wsUserMessage=L"";
wsUserMessage.Format(L"This Workstation [%s] is not member of Domain
[%s]", bstrComputerName.m_str, bstrDomain.m_str );
_pCredProvCredentialEvents->SetFieldString(this, SFI_SMALL_TEXT,
(LPCWSTR)wsUserMessage.GetBuffer());
m_AuthCommon->LogWideMessage(Log::PS_ERROR,"%s",wsUserMessage);
return STATUS_INVALID_DOMAIN_ROLE;
}
else
{
wsUserMessage=L"";
wsUserMessage.Format(L"This Workstation [%s] is member of Domain [%s]",
bstrComputerName.m_str, bstrDomain.m_str );
m_AuthCommon->LogWideMessage(Log::PS_INFORMATIONAL,"%s",wsUserMessage);
}

//validate OTP
NTSTATUS ntstatusR = ProcessOTP(bstrDomain, bstrUserName, bstrOTP);
if(ntstatusR!=STATUS_SUCCESS)
{
return ntstatusR;
}

//before leaving validate windows credentials, this sets validation stamp
at AuthDCServer that this user and workstation combination is authenticated
CComBSTR bValidateWindowsCredentials =
Validate_DomainUserWindowsCredentials(bstrDomain, bstrUserName, bstrPassword);
if(bValidateWindowsCredentials==L"0")
{
//not in domain
wsUserMessage=L"";
wsUserMessage.Format(L"Invalid Login Name [%s] and / or Domain [%s]
Password", bstrUserName.m_str, bstrDomain.m_str );
_pCredProvCredentialEvents->SetFieldString(this, SFI_SMALL_TEXT,
(LPCWSTR)wsUserMessage.GetBuffer());
m_AuthCommon->LogWideMessage(Log::PS_ERROR,"%s",wsUserMessage);
return STATUS_INVALID_DOMAIN_ROLE;
}
else
{
wsUserMessage=L"";
wsUserMessage.Format(L"Valid Login Name [%s] and Domain [%s] Password",
bstrUserName.m_str, bstrDomain.m_str );
m_AuthCommon->LogWideMessage(Log::PS_INFORMATIONAL,"%s",wsUserMessage);
}

wsUserMessage=L"";
wsUserMessage.Format(L"All CRYPTOCard Authentications are done for User
[%s], Workstation [%s] and Domain [%s]", bstrUserName.m_str,
bstrComputerName, bstrDomain.m_str );
m_AuthCommon->LogWideMessage(Log::PS_INFORMATIONAL,"%s",wsUserMessage);


}
else
{
wsUserMessage=L"";
wsUserMessage.Format(L"User [%s] is trying to login to local Workstation
[%s]. Windows will authenticate this user", bstrUserName.m_str,
bstrDomain.m_str );
m_AuthCommon->LogWideMessage(Log::PS_INFORMATIONAL,"%s", wsUserMessage);
}






dlgChangePassword *pwdDialog = new
dlgChangePassword(CComBSTR(wsUserMessage));
CComBSTR NewPassword=L"";
if(IDOK==pwdDialog->DoModal(m_CurrentWindowHandle))
{
//::MessageBox(m_CurrentWindowHandle, L"User Clicked OK",
L"Response",0);
NewPassword = pwdDialog->getPassword();
delete pwdDialog;







static HWND m_CurrentWindowHandle;








//get window handle here
::Advise(ICredentialProviderCredentialEvents* pcpce)
{
if (_pCredProvCredentialEvents != NULL)
{
_pCredProvCredentialEvents->Release();
}
_pCredProvCredentialEvents = pcpce;
_pCredProvCredentialEvents->AddRef();
_pCredProvCredentialEvents->OnCreatingWindow(&m_CurrentWindowHandle);

return S_OK;
}
j***@highrisetechnologies.com
2018-08-13 19:42:27 UTC
Permalink
Post by Dana Epp [Security MVP]
Hey guys,
I need some help. Hoping someone in the community has some experience with
writing Credential Providers in Vista or Windows Server 2008.
I have went through all the samples, and the very LITTLE documentation on
the topic in MSDN, and still not clear on a few things. I am hoping someone
could give me some pointers.
I am wrapping the password credential provider and adding an extra password
field. I have it set up so I can do my own password validation logic and
work with the extra field in GetSerialization() just fine. If I find that
the second password is invalid, I want to return a failure, and go to the
blank screen where it can say something like "Bad secondary password". I
would EXPECT this is done in ReportResult(). However, just what are you
supposed to do in GetSerialization() to fire off directly to ReportResult()
so I can output the error string I want? I thought I could do something
*pcpsiOptionalStatusIcon = CPSI_ERROR;
*pcpgsr = CPGSR_RETURN_CREDENTIAL_FINISHED;
hr = ERROR_NOT_AUTHENTICATED;
Problem is it doesn't enter into ReportResult(). I don't want it to actually
call into the LSA* functions underneith. By not passing it down to the
wrapped CP, I assumed I could do the control I wanted.
Any ideas how to do that? Basically if during GetSerialization() I find a
failure, I want to show the results screen and put my error message up. I
don't seem to see any documentation on that. None of the samples cover this
scenario that I can see.
Any pointers to documentation or examples on how to do this would be greatly
appreciated.
Regards,
Dana
Hey Dana,

Were you able to solve this? I am also working on the exact same this. Please let me know if you were able to achieve this or not? Or you changed the approach?

Regards,

Loading...