ICredentialProvider

Did anybody make a successful user logon using the new ICredentialProvider interface

My credentials are displayed, but I can't make them to logon. And what worse - after 20 or 30 seconds, the winlogon crashes completely with no recovery possible excepting hardware reset.

I thought I basically did something wrong and decided to wait for more detailed documentation or some sample code. But MS doesn't seem to put too much effort on improving their SDK documentation and I also found that at least one other programmer has the same problem:

http://msdn.microsoft.com/newsgroups/default.aspx query=vista&dg=microsoft.public.platformsdk.security&cat=en-us-msdn-windev-winsdk&lang=en&cr=US&pt=&catlist=BC660915-5862-4C50-90C5-906EA14F77C0%2CAB6C31EE-77E8-4E0E-8068-CB7C8258B8CA%2C774F24A2-F71F-425F-AC2B-DC48AB0DA5C9&dglist=&ptlist=&exp=&sloc=en-us

The last function called is ICreedentialProviderCredential::GetStringValue() which retrieves my credential data.

Please show off if you did better, at least I will get some motivation :-)



Answer this question

ICredentialProvider

  • newbie730

    Well, I ran OLE/COM Object viewer and I can confirm your results - ICredentialProvider is not registered, only ICredentialProviderEvents.

    I didn't try to make such a tool like you did, I can't invoke my provider myself, it is only called from the LogonUI. I also needed something like your tool for a comfortable development, so I am using VMware and it works great.

    Maybe the LogonUI does some kind of temporary registration on ICredentialProvider, I don't know, I am no COM guru :-)

    Vista logon and unlock scenario goes like this:

    SetUsageScenario()

    Advise()

    GetCredentialsCount() // n

    n times GetCredentialAt()

    GetFieldDescriptorCount() // m

    m times GetFieldDescriptorAt()

    When you submit a credential, two most important methods called are GetSerialization() and ReportResult().

    Things get of course more complicated when using callback interfaces to reenumerate credentials, change fields, make autologon etc.


  • Zsolt Soczo

    Sorry, I have no idea what else you could do. I can only say again, there are two needed steps:

    1) register the dll, so that you have the CLSID entry of object implementing ICredentialProvider under HKEY_CLASSES_ROOT\CLSID.

    2) add a key under Credential Providers, for example this is how it looks like on my machine:

    HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Authentication\Credential Providers\{38CBEEAA-67B8-41A1-9A79-D08515333CF2}


  • pattinyl

    So I finally made it - at least partially. The crashes were caused by improper COM parameter passing. Clearly my fault as I expected :-) For anybody who did the same mistake - when passing dynamically allocated memory within COM (for example allocating and filling LPWSTR* output parameter), the memory has to be allocated using CoTaskMemAlloc() function. It is said to be one of the fundamental COM knowledge, unfortunatelly I didn't know :-)

    Now I am fighting to implement GetSerialization() method. Again, most probably lacking some fundamental knowledge, I am trying to fill various Kerberos serialization structures and pass them to WinlogonUI, but I get nothing else than "Parameter is incorrect" in response.


  • Dan Bunea MSDN

    In this case, the second parameter has IMHO no use yet - as far as I know it is always set to zero. But there were more significant changes in the interface, so I would strongly recommend to use the latest header.
  • Jan Kučera

    Hi,

    You must be one of only a very few people to get this working! I've come back to this and I'm getting a similar problem.

    I've written a COM object that impliments ICredentialProvider. I'm fairly sure it is working because I can do this:

    IUnknown *pUnknown=NULL;

    hr=CoCreateInstance(CLSID_CSimpleCred, NULL, CLSCTX_INPROC_SERVER, IID_IUnknown, (void**)&pUnknown);

    ICredentialProvider *pProv=NULL;

    hr=pUnknown->QueryInterface(IID_ICredentialProvider, (void**)&pProv);

    hr=pProv->SetUsageScenario(CPUS_LOGON);

    I've followed your instructions for registering the .dll in the registry, and that seems to work because the dll is definitely loaded into memory by LogonUI.exe and the object class constructor is called. However, none of the ICredentialProvider methods are ever called. I must be missing something obvious.

    I've only implimented ICredentialProvider as a test - nothing else. Do you know of anything else that needs to be done

    Many Thanks.


  • 朵朵

    Hi,

    it doesn't matter whether the computer is in domain or not, ICredentialProvider methods are called by LogonUI anyway.

    You will definitely need to write and registered a dll. In that dll you should implement at least ICredentialProvider and ICredentialProviderCredential interfaces. I recommend you to use attributed COM, which makes all the tricky registrations quite easy.

    In addition, you have to create some special registry keys to let the LogonUI know about your provider - see: http://msdn.microsoft.com/newsgroups/default.aspx dg=microsoft.public.platformsdk.security&tid=5ee1c87a-d056-4c18-a962-db0b2ee355a0&cat=en-us-msdn-windev-winsdk&lang=en&cr=US&sloc=en-us&m=1&p=1


  • NonGT

    Yes. It is called when the Vista machine is not in a domain.
  • Dag Sanna

    Thanks a lot for that. It's really helpful.

    Does your code get called when the Vista machine is not in a domain



  • Gangadhart

    Thank you for that reply. I have written and registered my dll which implements ICredentialProvider [C++ non-attributed] and have written a small test harness for it. When I run the test harness the dll gets called and within it does a QueryInterface from the coclass to ICredentialProvider. It is this QueryInterface that is failing "Interface not registered" because ICredentialProvider is not registered. I am using the same build [5270] as you so it is a mystery to me.

    I am also interested in any notes about the sequence of calls that Vista executes under different scenarios.

    Thanks in advance

    Philip



  • De los Palotes Juan

    Thanks to the other thread, I see the new header file states that SetUsageScenario takes two parameters. I wonder if using the old header file has anything to do with my problems !
  • Ariston Collander

    I'm glad to hear you got it going; I'm having difficulties. Build 5270 but ICredentialProvider is not in the registry as an interface only ICredentialPRoviderEvents and so the QueryInterface to convert to ICredentialProvider fails with interface not registered.

    Have you, or anyone got any ideas Is there a dll which I could register for ICredentialProvider

    Also, do the methods get called when it's not in a domain and using the XP -Home like logon

    Any help is much appreciated.

    Philip



  • widdowsj

    Thanks for your help on this. I've now got some test code working based on the ICredentialProvider interface in the new header. Strictly speaking, of course, this is a different interface to the earlier version which is described in the latest SDK.

    Anyone trying this for themselves should note that the documentation for ICredentialProvider and ICredentialProviderCredential interfaces is out of date in the January 2006 CTP SDK. Implimenting the documented interfaces won't work on build 5270.


  • belikekhushi

    Can you tell me any issues you encountered getting your gui to work [if you have one]

    My ICP gets called but there's no gui and I hove no bitmap yet.

    Philip



  • BlueBSH

    So I finally made it! Many thanks to MS credential provider team who helped me a lot.

    Use Negotiate authentication package (LsaLookupAuthenticationPackage on NEGOSSP_NAME_A).

    See http://msdn.microsoft.com/msdnmag/issues/05/06/SecurityBriefs/ , “Calling LsaLogonUser”, for a hint how to properly deal with KERB_INTERACTIVE_UNLOCK_LOGON structure. Then the only difference is that the Buffer member of each unicode string is not a pointer to the shared buffer, but an offset. Because the buffer is allocated right after the structure, the offset for a domain is sizeof(KERB_INTERACTIVE_UNLOCK_LOGON), for username it must be increased with the length of domain string and the password follows after the domain. All the strings are wide strings without a terminanting \0 character.

    Note that this may (and probably will) change in the future, I am currently working with build 5270.


  • ICredentialProvider