locked
SmartCardCredentialsProvider.dll UI doesn't accept user input RRS feed

  • Question

  • My company is programming for the SmartCard security setup in Windows. However, we hit a snag when we updated to Fall Creators, which a developer was able to mitigate by not passing a parent window to the CredUIPromptForWindowsCredentialsW() function (desktop/root/NULL). If we pass a parent window, it results in the Smart Card Login dialog to not be accessible, as in the window pops up, but when you click on it, the Window's Default Beep is heard and you cannot type anything. I've looked using Spy++ and it states that there is no child window that is interfering, but there are messages getting to the window that Spy++ can see (WM_SETCURSORWM_MOUSEMOVEWM_LBUTTONDOWNWM_LBUTTONUP and a bunch of registered SHELLHOOK with various parameters).

    The application is written using the MFC MBCS framework if that makes a difference.

    Things that I've tried are:

    1. Showing the parent window (currently hidden). This sometimes works when I use ::ShowWindow(m_Parent, SW_SHOW); but never works when I use ::SetWindowPos(m_Parent, NULL, 0, 0, 0, 0, SWP_SHOWWINDOW | SWP_NOMOVE | SWP_NOSIZE | SWP_NOZORDER);
    2. I've attempted to detour the message and thread creation functions in an attempt to log what's going on, but I don't seem to get any information.

    I'm really scratching my head on this. Why would the Smart Card Login window not get the focus? What could be interfering with this? We need to stop using this workaround and actually get the Smart Card Login to have a parent window.


    I don't mind someone marking a post as "Proposed as answer", but DO NOT mark it as "Answered". If I am the OP, I will decide if a post actually answers my post or not. Thank you.

    Tuesday, April 17, 2018 4:12 PM

All replies

  • Some stuff I found in the Debug Output window are:

    Exception thrown at 0x763008F2 in app.exe: Microsoft C++ exception: errorlib::specific_error_exception<hresult_error::tag> at memory location 0x3B74F824.
    Exception thrown at 0x763008F2 in app.exe: Microsoft C++ exception: errorlib::specific_error_exception<hresult_error::tag> at memory location 0x3B74F824.
    
    Exception thrown at 0x763008F2 in app.exe: Microsoft C++ exception: errorlib::specific_error_exception<hresult_error::tag> at memory location 0x3B74F8E4.
    Exception thrown at 0x763008F2 in app.exe: Microsoft C++ exception: errorlib::specific_error_exception<hresult_error::tag> at memory location 0x3B74F8C8.
    
    onecoreuap\ds\security\fido\credprov\dll\fidoscenariocredui.cpp(44)\fidocredprov.dll!3C8CD0D9: (caller: 3C8CB529) ReturnHr(1) tid(5488) 80070057 The parameter is incorrect.
        Msg:[InvalidFlags 32] 
    onecoreuap\ds\security\fido\credprov\dll\fidoprovider.cpp(62)\fidocredprov.dll!3C8CB540: (caller: 27886879) ReturnHr(2) tid(5488) 80070057 The parameter is incorrect.
    
    onecore\ds\security\biometrics\credprov\provider_v2\bioprovider.cpp(99)\BioCredProv.dll!3CDC9620: (caller: 27886879) ReturnHr(1) tid(5488) 80098003     CallContext:[\SetUsageScenario] 
    onecore\ds\security\biometrics\credprov\provider_v2\bioprovider.cpp(206)\BioCredProv.dll!3CDC9117: (caller: 27886ECF) ReturnHr(2) tid(5488) 80004001 Not implemented
        CallContext:[\UnAdvise] 
    
    onecoreuap\shell\auth\credprov2fahelper\dll\credprov2fahelper.cpp(80)\CredProv2faHelper.dll!2B0F63E5: (caller: 278870A4) ReturnHr(1) tid(5488) 800704EC This program is blocked by group policy. For more information, contact your system administrator.
        Msg:[Device unlock policy not configured] 
    onecore\ds\security\ngc\utils\common\lib\sidutils.cpp(786)\ngccredprov.dll!3CE59F69: (caller: 3CE58CA0) ReturnHr(1) tid(5488) 80070057 The parameter is incorrect.
    Exception thrown at 0x763008F2 (KernelBase.dll) in app.exe: 0x0000071A: The remote procedure call was canceled, or if a call time-out was specified, the call timed out.
    Exception thrown at 0x763008F2 (KernelBase.dll) in app.exe: 0x0000071A: The remote procedure call was canceled, or if a call time-out was specified, the call timed out.
    
    Exception thrown at 0x763008F2 (KernelBase.dll) in app.exe: 0x0000071A: The remote procedure call was canceled, or if a call time-out was specified, the call timed out.
    Exception thrown at 0x763008F2 in app.exe: Microsoft C++ exception: unsigned long at memory location 0x3B74F194.

    Though these appear when the parent is the root (desktop) or our window, so I'm not sure if they mean anything.


    I don't mind someone marking a post as "Proposed as answer", but DO NOT mark it as "Answered". If I am the OP, I will decide if a post actually answers my post or not. Thank you.

    Tuesday, April 17, 2018 4:15 PM
  • Here is the code (more or less) that is used to bring up the Smart Card dialog:

    CREDUI_INFOW credUIInfo;
    memset(&credUIInfo, 0, sizeof(credUIInfo));
    credUIInfo.cbSize = sizeof(credUIInfo);
    credUIInfo.hwndParent = m_Parent;
    credUIInfo.pszCaptionText = L"Smart Card Login";
    ULONG ulAuthPackageID = 0;
    
    HANDLE hLSA = NULL;
    DWORD dwErr = LsaNtStatusToWinError(LsaConnectUntrusted(&hLSA));
    if (dwErr == ERROR_SUCCESS) {
        LSA_STRING lsaszAuthPackageName;
        SizeTToUShort(strlen("Negotiate"), &lsaszAuthPackageName.Length);
        lsaszAuthPackageName.MaximumLength = lsaszAuthPackageName.Length + sizeof(CHAR);
        lsaszAuthPackageName.Buffer = (PCHAR)"Negotiate";
    
        dwErr = LsaNtStatusToWinError(LsaLookupAuthenticationPackage(hLSA, &lsaszAuthPackageName, &ulAuthPackageID));
    }
    
    // Disconnect from the LSA server:
    if (hLSA) {LsaDeregisterLogonProcess(hLSA);}
    
    KERB_CERTIFICATE_LOGON credFilter;
    memset(&credFilter, 0, sizeof(credFilter));
    credFilter.MessageType = KerbCertificateLogon; // (indicates an interactive smart card certificate login)
    
    LPVOID pCredBuffer = NULL;
    DWORD dwCredLen = 0;
    
    dwErr = CredUIPromptForWindowsCredentialsW(&credUIInfo, dwErr, &ulAuthPackageID, &credFilter, sizeof(credFilter), &pCredBuffer, &dwCredLen, NULL, CREDUIWIN_IN_CRED_ONLY);

    It appears that the dialog is disabled according to Spy++. Writing a quick little app that, given any window handle, will enable the window associated with that handle by calling EnableWindow() will actually enable the window. Why would this be the case? Why would the window be disabled?



    I don't mind someone marking a post as "Proposed as answer", but DO NOT mark it as "Answered". If I am the OP, I will decide if a post actually answers my post or not. Thank you.



    • Edited by A D R I A N Tuesday, April 17, 2018 4:16 PM
    Tuesday, April 17, 2018 4:15 PM
  • A workaround to this problem, which I think is better then not setting the parent, is to poll for the security dialog and once it is visible and it is still not enabled, then enable it.

    constexpr UINT_PTR enable_window_id = 0;
    ::SetTimer(m_Parent, enable_window_id, 100, [](HWND hwnd, UINT /*msg*/, UINT_PTR id, DWORD /*dwTime*/)
    {
        if (HWND hChild = ::FindWindow(_T("Credential Dialog Xaml Host"), nullptr))
        {
            if (::IsWindowVisible(hChild) && !::IsWindowEnabled(hChild))
            {
                ::EnableWindow(hChild, TRUE);
                ::KillTimer(hwnd, id);
            }
        }
    });
    
    //...
    // CredUIPromptForWindowsCredentials(...) call
    //...
    
    // If MS ever fixes this problem, will need to kill this timer manually
    ::KillTimer(m_Parent, enable_window_id);

    I personally think this is really kludgy, but who knows when MS will fix it.

    I have also posted this question to SO here, which is pretty much a copy of what I stated in this thread.


    I don't mind someone marking a post as "Proposed as answer", but DO NOT mark it as "Answered". If I am the OP, I will decide if a post actually answers my post or not. Thank you.


    • Edited by A D R I A N Tuesday, April 17, 2018 4:22 PM
    Tuesday, April 17, 2018 4:21 PM
  • So, does anyone have any info on this issue?

    I don't mind someone marking a post as "Proposed as answer", but DO NOT mark it as "Answered". If I am the OP, I will decide if a post actually answers my post or not. Thank you.

    Thursday, April 19, 2018 4:09 PM