/** * 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; }
/** * 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; }