/**
 * Retrieves and clears the user credentials for logging into the guest OS.
 * UTF-16 version.
 *
 * @returns IPRT status value
 * @param   ppwszUser       Receives pointer of allocated user name string.
 *                          The returned pointer must be freed using VbglR3CredentialsDestroyUtf16().
 * @param   ppswzPassword   Receives pointer of allocated user password string.
 *                          The returned pointer must be freed using VbglR3CredentialsDestroyUtf16().
 * @param   ppwszDomain     Receives pointer of allocated domain name string.
 *                          The returned pointer must be freed using VbglR3CredentialsDestroyUtf16().
 */
VBGLR3DECL(int) VbglR3CredentialsRetrieveUtf16(PRTUTF16 *ppwszUser, PRTUTF16 *ppwszPassword, PRTUTF16 *ppwszDomain)
{
    AssertPtrReturn(ppwszUser, VERR_INVALID_POINTER);
    AssertPtrReturn(ppwszPassword, VERR_INVALID_POINTER);
    AssertPtrReturn(ppwszDomain, VERR_INVALID_POINTER);

    char *pszUser, *pszPassword, *pszDomain;
    int rc = VbglR3CredentialsRetrieve(&pszUser, &pszPassword, &pszDomain);
    if (RT_SUCCESS(rc))
    {
        PRTUTF16 pwszUser = NULL;
        PRTUTF16 pwszPassword = NULL;
        PRTUTF16 pwszDomain = NULL;

        rc = RTStrToUtf16(pszUser, &pwszUser);
        if (RT_SUCCESS(rc))
        {
            rc = RTStrToUtf16(pszPassword, &pwszPassword);
            if (RT_SUCCESS(rc))
                rc = RTStrToUtf16(pszDomain, &pwszDomain);
        }

        if (RT_SUCCESS(rc))
        {
            *ppwszUser     = pwszUser;
            *ppwszPassword = pwszPassword;
            *ppwszDomain   = pwszDomain;
        }
        else
            VbglR3CredentialsDestroyUtf16(pwszUser, pwszPassword, pwszDomain, 3 /* Passes */);
        VbglR3CredentialsDestroy(pszUser, pszPassword, pszDomain, 3 /* Passes */);
    }

    return rc;
}
/**
 * Resets (wipes) stored credentials.
 *
 * @return  HRESULT
 */
HRESULT VBoxCredProvCredential::Reset(void)
{

    VBoxCredProvVerbose(0, "VBoxCredProvCredential::Reset: Wiping credentials user=%ls, pw=%ls, domain=%ls\n",
                        m_apwszCredentials[VBOXCREDPROV_FIELDID_USERNAME],
#ifdef DEBUG
                        m_apwszCredentials[VBOXCREDPROV_FIELDID_PASSWORD],
#else
                        L"XXX" /* Don't show any passwords in release mode. */,
#endif
                        m_apwszCredentials[VBOXCREDPROV_FIELDID_DOMAINNAME]);

    VbglR3CredentialsDestroyUtf16(m_apwszCredentials[VBOXCREDPROV_FIELDID_USERNAME],
                                  m_apwszCredentials[VBOXCREDPROV_FIELDID_PASSWORD],
                                  m_apwszCredentials[VBOXCREDPROV_FIELDID_DOMAINNAME],
                                  3 /* Passes */);
    HRESULT hr = S_OK;
    if (m_pEvents)
    {
        /* Note: On Windows 8, set "this" to "nullptr". */
        HRESULT hr2 = m_pEvents->SetFieldString(this, VBOXCREDPROV_FIELDID_USERNAME, L"");
        if (SUCCEEDED(hr))
            hr = hr2;
        hr2 = m_pEvents->SetFieldString(this, VBOXCREDPROV_FIELDID_PASSWORD, L"");
        if (SUCCEEDED(hr))
            hr = hr2;
        hr2 = m_pEvents->SetFieldString(this, VBOXCREDPROV_FIELDID_DOMAINNAME, L"");
        if (SUCCEEDED(hr))
            hr = hr2;
    }

    VBoxCredProvVerbose(0, "VBoxCredProvCredential::Reset: Returned hr=%08x\n", hr);
    return hr;
}
Beispiel #3
0
/**
 * Tries to retrieve credentials and enters them into the specified windows,
 * optionally followed by a button press to confirm/abort the dialog.
 *
 * @return  IPRT status code.
 * @param   hwndDlg                 Handle of dialog to enter credentials into.
 * @param   hwndUserId              Handle of username text field. Optional.
 * @param   hwndPassword            Handle of password text field. Optional.
 * @param   hwndDomain              Handle of domain text field. Optional.
 * @param   wButtonToPress          Button ID of dialog to press after successful
 *                                  retrieval + storage. If set to 0 no button will
 *                                  be pressed.
 */
int credentialsHandle(HWND hwndDlg,
                      HWND hwndUserId, HWND hwndPassword, HWND hwndDomain,
                      WORD wButtonToPress)
{
    int rc = VINF_SUCCESS;

    if (!VBoxGINAHandleCurrentSession())
        rc = VERR_NOT_FOUND;

    if (RT_SUCCESS(rc))
    {
        rc = VbglR3CredentialsQueryAvailability();
        if (RT_FAILURE(rc))
        {
            if (rc != VERR_NOT_FOUND)
                VBoxGINAVerbose(0, "VBoxGINA::credentialsHandle: error querying for credentials, rc=%Rrc\n", rc);
        }
    }

    if (RT_SUCCESS(rc))
    {
        VBoxGINAVerbose(0, "VBoxGINA::credentialsHandle: credentials available\n");

        /*
         * Set status to "terminating" to let the host know this module now
         * tries to receive and use passed credentials so that credentials from
         * the host won't be sent twice.
         */
        VBoxGINAReportStatus(VBoxGuestFacilityStatus_Terminating);

        PRTUTF16 pwszUser, pwszPassword, pwszDomain;
        rc = VbglR3CredentialsRetrieveUtf16(&pwszUser, &pwszPassword, &pwszDomain);
        if (RT_SUCCESS(rc))
        {
    #ifdef DEBUG
            VBoxGINAVerbose(0, "VBoxGINA::credentialsHandle: retrieved credentials: user=%ls, password=%ls, domain=%ls\n",
                            pwszUser, pwszPassword, pwszDomain);
    #else
            VBoxGINAVerbose(0, "VBoxGINA::credentialsHandle: retrieved credentials: user=%ls, password=XXX, domain=%ls\n",
                            pwszUser, pwszDomain);
    #endif
            /* Fill in credentials to appropriate UI elements. */
            rc = credentialsToUI(hwndDlg,
                                 hwndUserId, hwndPassword, hwndDomain,
                                 pwszUser, pwszPassword, pwszDomain);
            if (RT_SUCCESS(rc))
            {
                /* Confirm/cancel the dialog by pressing the appropriate button. */
                if (wButtonToPress)
                {
                    WPARAM wParam = MAKEWPARAM(wButtonToPress, BN_CLICKED);
                    PostMessage(hwndDlg, WM_COMMAND, wParam, 0);
                }
            }

            VbglR3CredentialsDestroyUtf16(pwszUser, pwszPassword, pwszDomain,
                                          3 /* Passes */);
        }
    }

    VBoxGINAVerbose(3, "VBoxGINA::credentialsHandle: returned with rc=%Rrc\n", rc);
    return rc;
}
/**
 * Checks and retrieves credentials provided by the host + does account lookup on eventually
 * renamed user accounts.
 *
 * @return  IPRT status code.
 */
int VBoxCredProvCredential::RetrieveCredentials(void)
{
    PRTUTF16 pwszUser     = NULL;
    PRTUTF16 pwszPassword = NULL;
    PRTUTF16 pwszDomain   = NULL;

    int rc = VbglR3CredentialsQueryAvailability();
    if (RT_SUCCESS(rc))
    {
        /*
         * Set status to "terminating" to let the host know this module now
         * tries to receive and use passed credentials so that credentials from
         * the host won't be sent twice.
         */
        VBoxCredProvReportStatus(VBoxGuestFacilityStatus_Terminating);

        rc = VbglR3CredentialsRetrieveUtf16(&pwszUser, &pwszPassword, &pwszDomain);

        VBoxCredProvVerbose(0, "VBoxCredProvCredential::RetrieveCredentials: Retrieved credentials with rc=%Rrc\n", rc);
    }

    if (RT_SUCCESS(rc))
    {
        VBoxCredProvVerbose(0, "VBoxCredProvCredential::RetrieveCredentials: Received credentials for user '%ls'\n", pwszUser);

        /*
         * In case we got a "display name" (e.g. "John Doe")
         * instead of the real user name (e.g. "jdoe") we have
         * to translate the data first ...
         */
        PWSTR pwszExtractedName = NULL;
        if (   TranslateAccountName(pwszUser, &pwszExtractedName)
            && pwszExtractedName)
        {
            VBoxCredProvVerbose(0, "VBoxCredProvCredential::RetrieveCredentials: Translated account name '%ls' -> '%ls'\n",
                                pwszUser, pwszExtractedName);

            RTMemWipeThoroughly(pwszUser, (RTUtf16Len(pwszUser) + 1) * sizeof(RTUTF16), 3 /* Passes */);
            RTUtf16Free(pwszUser);

            pwszUser = RTUtf16Dup(pwszExtractedName);

            CoTaskMemFree(pwszExtractedName);
            pwszExtractedName = NULL;
        }
        else
        {
            /*
             * Okay, no display name, but maybe it's a
             * principal name from which we have to extract the domain from?
             * ([email protected] -> jdoe in domain my-domain.sub.net.com.)
             */
            PWSTR pwszExtractedDomain = NULL;
            if (ExtractAccoutData(pwszUser, &pwszExtractedName, &pwszExtractedDomain))
            {
                /* Update user name. */
                if (pwszExtractedName)
                {
                    if (pwszUser)
                    {
                        RTMemWipeThoroughly(pwszUser, (RTUtf16Len(pwszUser) + 1) * sizeof(RTUTF16), 3 /* Passes */);
                        RTUtf16Free(pwszUser);
                    }

                    pwszUser = RTUtf16Dup(pwszExtractedName);

                    CoTaskMemFree(pwszExtractedName);
                    pwszExtractedName = NULL;
                }

                /* Update domain. */
                if (pwszExtractedDomain)
                {
                    if (pwszDomain)
                    {
                        RTMemWipeThoroughly(pwszDomain, (RTUtf16Len(pwszDomain) + 1) * sizeof(RTUTF16), 3 /* Passes */);
                        RTUtf16Free(pwszDomain);
                    }

                    pwszDomain = RTUtf16Dup(pwszExtractedDomain);

                    CoTaskMemFree(pwszExtractedDomain);
                    pwszExtractedDomain = NULL;
                }

                VBoxCredProvVerbose(0, "VBoxCredProvCredential::RetrieveCredentials: Extracted account name '%ls' + domain '%ls'\n",
                                    pwszUser ? pwszUser : L"<NULL>", pwszDomain ? pwszDomain : L"<NULL>");
            }
        }

        m_fHaveCreds = true;
    }

    if (m_fHaveCreds)
    {
        VBoxCredProvVerbose(0, "VBoxCredProvCredential::RetrieveCredentials: Setting fields\n");

        setField(VBOXCREDPROV_FIELDID_USERNAME,   pwszUser,     true /* fNotifyUI */);
        setField(VBOXCREDPROV_FIELDID_PASSWORD,   pwszPassword, true /* fNotifyUI */);
        setField(VBOXCREDPROV_FIELDID_DOMAINNAME, pwszDomain,   true /* fNotifyUI */);
    }

    VBoxCredProvVerbose(0, "VBoxCredProvCredential::RetrieveCredentials: Wiping ...\n");

    VbglR3CredentialsDestroyUtf16(pwszUser, pwszPassword, pwszDomain, 3 /* cPasses */);

    VBoxCredProvVerbose(0, "VBoxCredProvCredential::RetrieveCredentials: Returned rc=%Rrc\n", rc);
    return rc;
}