f5663ddc90362ab5cfe32e277fa34f2b057e8cfdvboxsync/* $Id$ */
bd44be5c996657f50cadcb987ee2879f4114d249vboxsync/** @file
bd44be5c996657f50cadcb987ee2879f4114d249vboxsync * VBoxGuestR3Lib - Ring-3 Support Library for VirtualBox guest additions, user credentials.
bd44be5c996657f50cadcb987ee2879f4114d249vboxsync */
bd44be5c996657f50cadcb987ee2879f4114d249vboxsync
bd44be5c996657f50cadcb987ee2879f4114d249vboxsync/*
c7814cf6e1240a519cbec0441e033d0e2470ed00vboxsync * Copyright (C) 2009-2012 Oracle Corporation
bd44be5c996657f50cadcb987ee2879f4114d249vboxsync *
bd44be5c996657f50cadcb987ee2879f4114d249vboxsync * This file is part of VirtualBox Open Source Edition (OSE), as
bd44be5c996657f50cadcb987ee2879f4114d249vboxsync * available from http://www.virtualbox.org. This file is free software;
bd44be5c996657f50cadcb987ee2879f4114d249vboxsync * you can redistribute it and/or modify it under the terms of the GNU
bd44be5c996657f50cadcb987ee2879f4114d249vboxsync * General Public License (GPL) as published by the Free Software
bd44be5c996657f50cadcb987ee2879f4114d249vboxsync * Foundation, in version 2 as it comes in the "COPYING" file of the
bd44be5c996657f50cadcb987ee2879f4114d249vboxsync * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
bd44be5c996657f50cadcb987ee2879f4114d249vboxsync * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
bd44be5c996657f50cadcb987ee2879f4114d249vboxsync *
aba0e602e244ae7c4f11b50fc6d2440f5a762038vboxsync * The contents of this file may alternatively be used under the terms
aba0e602e244ae7c4f11b50fc6d2440f5a762038vboxsync * of the Common Development and Distribution License Version 1.0
aba0e602e244ae7c4f11b50fc6d2440f5a762038vboxsync * (CDDL) only, as it comes in the "COPYING.CDDL" file of the
aba0e602e244ae7c4f11b50fc6d2440f5a762038vboxsync * VirtualBox OSE distribution, in which case the provisions of the
aba0e602e244ae7c4f11b50fc6d2440f5a762038vboxsync * CDDL are applicable instead of those of the GPL.
aba0e602e244ae7c4f11b50fc6d2440f5a762038vboxsync *
aba0e602e244ae7c4f11b50fc6d2440f5a762038vboxsync * You may elect to license modified versions of this file under the
aba0e602e244ae7c4f11b50fc6d2440f5a762038vboxsync * terms and conditions of either the GPL or the CDDL or both.
bd44be5c996657f50cadcb987ee2879f4114d249vboxsync */
bd44be5c996657f50cadcb987ee2879f4114d249vboxsync
bd44be5c996657f50cadcb987ee2879f4114d249vboxsync
bd44be5c996657f50cadcb987ee2879f4114d249vboxsync/*******************************************************************************
bd44be5c996657f50cadcb987ee2879f4114d249vboxsync* Header Files *
bd44be5c996657f50cadcb987ee2879f4114d249vboxsync*******************************************************************************/
20627226661ed2e925ff34f706827529ec880624vboxsync#include <iprt/asm.h>
38a1025c152d8cfd52dda13ecccb8f601d5e84ebvboxsync#include <iprt/mem.h>
20627226661ed2e925ff34f706827529ec880624vboxsync#include <iprt/rand.h>
38a1025c152d8cfd52dda13ecccb8f601d5e84ebvboxsync#include <iprt/string.h>
bd44be5c996657f50cadcb987ee2879f4114d249vboxsync#include <VBox/log.h>
bd44be5c996657f50cadcb987ee2879f4114d249vboxsync
bd44be5c996657f50cadcb987ee2879f4114d249vboxsync#include "VBGLR3Internal.h"
bd44be5c996657f50cadcb987ee2879f4114d249vboxsync
bd44be5c996657f50cadcb987ee2879f4114d249vboxsync
bd44be5c996657f50cadcb987ee2879f4114d249vboxsync/**
bd44be5c996657f50cadcb987ee2879f4114d249vboxsync * Checks whether user credentials are available to the guest or not.
bd44be5c996657f50cadcb987ee2879f4114d249vboxsync *
b11724409affb86e618d406fae3791ec2c61d184vboxsync * @returns IPRT status value; VINF_SUCCESS if credentials are available,
ad27e1d5e48ca41245120c331cc88b50464813cevboxsync * VERR_NOT_FOUND if not. Otherwise an error is occurred.
bd44be5c996657f50cadcb987ee2879f4114d249vboxsync */
cb99e79882dc7075944aa81c071752785c76be6bvboxsyncVBGLR3DECL(int) VbglR3CredentialsQueryAvailability(void)
bd44be5c996657f50cadcb987ee2879f4114d249vboxsync{
f5663ddc90362ab5cfe32e277fa34f2b057e8cfdvboxsync VMMDevCredentials Req;
f5663ddc90362ab5cfe32e277fa34f2b057e8cfdvboxsync RT_ZERO(Req);
f5663ddc90362ab5cfe32e277fa34f2b057e8cfdvboxsync vmmdevInitRequest((VMMDevRequestHeader*)&Req, VMMDevReq_QueryCredentials);
f5663ddc90362ab5cfe32e277fa34f2b057e8cfdvboxsync Req.u32Flags |= VMMDEV_CREDENTIALS_QUERYPRESENCE;
bd44be5c996657f50cadcb987ee2879f4114d249vboxsync
f5663ddc90362ab5cfe32e277fa34f2b057e8cfdvboxsync int rc = vbglR3GRPerform(&Req.header);
b11724409affb86e618d406fae3791ec2c61d184vboxsync if (RT_SUCCESS(rc))
b11724409affb86e618d406fae3791ec2c61d184vboxsync {
b11724409affb86e618d406fae3791ec2c61d184vboxsync if ((Req.u32Flags & VMMDEV_CREDENTIALS_PRESENT) == 0)
b11724409affb86e618d406fae3791ec2c61d184vboxsync rc = VERR_NOT_FOUND;
b11724409affb86e618d406fae3791ec2c61d184vboxsync }
b11724409affb86e618d406fae3791ec2c61d184vboxsync return rc;
bd44be5c996657f50cadcb987ee2879f4114d249vboxsync}
bd44be5c996657f50cadcb987ee2879f4114d249vboxsync
bd44be5c996657f50cadcb987ee2879f4114d249vboxsync
bd44be5c996657f50cadcb987ee2879f4114d249vboxsync/**
f5663ddc90362ab5cfe32e277fa34f2b057e8cfdvboxsync * Retrieves and clears the user credentials for logging into the guest OS.
bd44be5c996657f50cadcb987ee2879f4114d249vboxsync *
bd44be5c996657f50cadcb987ee2879f4114d249vboxsync * @returns IPRT status value
f5663ddc90362ab5cfe32e277fa34f2b057e8cfdvboxsync * @param ppszUser Receives pointer of allocated user name string.
940534f83612182a14887c7ccac92bfc43cbebd2vboxsync * The returned pointer must be freed using VbglR3CredentialsDestroy().
f5663ddc90362ab5cfe32e277fa34f2b057e8cfdvboxsync * @param ppszPassword Receives pointer of allocated user password string.
940534f83612182a14887c7ccac92bfc43cbebd2vboxsync * The returned pointer must be freed using VbglR3CredentialsDestroy().
f5663ddc90362ab5cfe32e277fa34f2b057e8cfdvboxsync * @param ppszDomain Receives pointer of allocated domain name string.
940534f83612182a14887c7ccac92bfc43cbebd2vboxsync * The returned pointer must be freed using VbglR3CredentialsDestroy().
bd44be5c996657f50cadcb987ee2879f4114d249vboxsync */
bd44be5c996657f50cadcb987ee2879f4114d249vboxsyncVBGLR3DECL(int) VbglR3CredentialsRetrieve(char **ppszUser, char **ppszPassword, char **ppszDomain)
bd44be5c996657f50cadcb987ee2879f4114d249vboxsync{
9ffc69ee5b1d727cdebfd2b3daa9161a690b9677vboxsync AssertPtrReturn(ppszUser, VERR_INVALID_POINTER);
9ffc69ee5b1d727cdebfd2b3daa9161a690b9677vboxsync AssertPtrReturn(ppszPassword, VERR_INVALID_POINTER);
9ffc69ee5b1d727cdebfd2b3daa9161a690b9677vboxsync AssertPtrReturn(ppszDomain, VERR_INVALID_POINTER);
9ffc69ee5b1d727cdebfd2b3daa9161a690b9677vboxsync
f5663ddc90362ab5cfe32e277fa34f2b057e8cfdvboxsync VMMDevCredentials Req;
f5663ddc90362ab5cfe32e277fa34f2b057e8cfdvboxsync RT_ZERO(Req);
f5663ddc90362ab5cfe32e277fa34f2b057e8cfdvboxsync vmmdevInitRequest((VMMDevRequestHeader*)&Req, VMMDevReq_QueryCredentials);
f5663ddc90362ab5cfe32e277fa34f2b057e8cfdvboxsync Req.u32Flags |= VMMDEV_CREDENTIALS_READ | VMMDEV_CREDENTIALS_CLEAR;
bd44be5c996657f50cadcb987ee2879f4114d249vboxsync
f5663ddc90362ab5cfe32e277fa34f2b057e8cfdvboxsync int rc = vbglR3GRPerform(&Req.header);
bd44be5c996657f50cadcb987ee2879f4114d249vboxsync if (RT_SUCCESS(rc))
bd44be5c996657f50cadcb987ee2879f4114d249vboxsync {
f5663ddc90362ab5cfe32e277fa34f2b057e8cfdvboxsync rc = RTStrDupEx(ppszUser, Req.szUserName);
f5663ddc90362ab5cfe32e277fa34f2b057e8cfdvboxsync if (RT_SUCCESS(rc))
f5663ddc90362ab5cfe32e277fa34f2b057e8cfdvboxsync {
f5663ddc90362ab5cfe32e277fa34f2b057e8cfdvboxsync rc = RTStrDupEx(ppszPassword, Req.szPassword);
f5663ddc90362ab5cfe32e277fa34f2b057e8cfdvboxsync if (RT_SUCCESS(rc))
f5663ddc90362ab5cfe32e277fa34f2b057e8cfdvboxsync {
f5663ddc90362ab5cfe32e277fa34f2b057e8cfdvboxsync rc = RTStrDupEx(ppszDomain, Req.szDomain);
f5663ddc90362ab5cfe32e277fa34f2b057e8cfdvboxsync if (RT_SUCCESS(rc))
f5663ddc90362ab5cfe32e277fa34f2b057e8cfdvboxsync return VINF_SUCCESS;
f5663ddc90362ab5cfe32e277fa34f2b057e8cfdvboxsync
f5663ddc90362ab5cfe32e277fa34f2b057e8cfdvboxsync RTStrFree(*ppszPassword);
f5663ddc90362ab5cfe32e277fa34f2b057e8cfdvboxsync }
f5663ddc90362ab5cfe32e277fa34f2b057e8cfdvboxsync RTStrFree(*ppszUser);
f5663ddc90362ab5cfe32e277fa34f2b057e8cfdvboxsync }
bd44be5c996657f50cadcb987ee2879f4114d249vboxsync }
bd44be5c996657f50cadcb987ee2879f4114d249vboxsync return rc;
bd44be5c996657f50cadcb987ee2879f4114d249vboxsync}
bd44be5c996657f50cadcb987ee2879f4114d249vboxsync
940534f83612182a14887c7ccac92bfc43cbebd2vboxsync
9ffc69ee5b1d727cdebfd2b3daa9161a690b9677vboxsync/**
9ffc69ee5b1d727cdebfd2b3daa9161a690b9677vboxsync * Retrieves and clears the user credentials for logging into the guest OS.
9ffc69ee5b1d727cdebfd2b3daa9161a690b9677vboxsync * UTF-16 version.
9ffc69ee5b1d727cdebfd2b3daa9161a690b9677vboxsync *
9ffc69ee5b1d727cdebfd2b3daa9161a690b9677vboxsync * @returns IPRT status value
9ffc69ee5b1d727cdebfd2b3daa9161a690b9677vboxsync * @param ppwszUser Receives pointer of allocated user name string.
9ffc69ee5b1d727cdebfd2b3daa9161a690b9677vboxsync * The returned pointer must be freed using VbglR3CredentialsDestroyUtf16().
9ffc69ee5b1d727cdebfd2b3daa9161a690b9677vboxsync * @param ppswzPassword Receives pointer of allocated user password string.
9ffc69ee5b1d727cdebfd2b3daa9161a690b9677vboxsync * The returned pointer must be freed using VbglR3CredentialsDestroyUtf16().
9ffc69ee5b1d727cdebfd2b3daa9161a690b9677vboxsync * @param ppwszDomain Receives pointer of allocated domain name string.
9ffc69ee5b1d727cdebfd2b3daa9161a690b9677vboxsync * The returned pointer must be freed using VbglR3CredentialsDestroyUtf16().
9ffc69ee5b1d727cdebfd2b3daa9161a690b9677vboxsync */
9ffc69ee5b1d727cdebfd2b3daa9161a690b9677vboxsyncVBGLR3DECL(int) VbglR3CredentialsRetrieveUtf16(PRTUTF16 *ppwszUser, PRTUTF16 *ppwszPassword, PRTUTF16 *ppwszDomain)
9ffc69ee5b1d727cdebfd2b3daa9161a690b9677vboxsync{
9ffc69ee5b1d727cdebfd2b3daa9161a690b9677vboxsync AssertPtrReturn(ppwszUser, VERR_INVALID_POINTER);
9ffc69ee5b1d727cdebfd2b3daa9161a690b9677vboxsync AssertPtrReturn(ppwszPassword, VERR_INVALID_POINTER);
9ffc69ee5b1d727cdebfd2b3daa9161a690b9677vboxsync AssertPtrReturn(ppwszDomain, VERR_INVALID_POINTER);
9ffc69ee5b1d727cdebfd2b3daa9161a690b9677vboxsync
9ffc69ee5b1d727cdebfd2b3daa9161a690b9677vboxsync char *pszUser, *pszPassword, *pszDomain;
9ffc69ee5b1d727cdebfd2b3daa9161a690b9677vboxsync int rc = VbglR3CredentialsRetrieve(&pszUser, &pszPassword, &pszDomain);
9ffc69ee5b1d727cdebfd2b3daa9161a690b9677vboxsync if (RT_SUCCESS(rc))
9ffc69ee5b1d727cdebfd2b3daa9161a690b9677vboxsync {
9ffc69ee5b1d727cdebfd2b3daa9161a690b9677vboxsync PRTUTF16 pwszUser = NULL;
9ffc69ee5b1d727cdebfd2b3daa9161a690b9677vboxsync PRTUTF16 pwszPassword = NULL;
9ffc69ee5b1d727cdebfd2b3daa9161a690b9677vboxsync PRTUTF16 pwszDomain = NULL;
9ffc69ee5b1d727cdebfd2b3daa9161a690b9677vboxsync
9ffc69ee5b1d727cdebfd2b3daa9161a690b9677vboxsync rc = RTStrToUtf16(pszUser, &pwszUser);
9ffc69ee5b1d727cdebfd2b3daa9161a690b9677vboxsync if (RT_SUCCESS(rc))
9ffc69ee5b1d727cdebfd2b3daa9161a690b9677vboxsync {
9ffc69ee5b1d727cdebfd2b3daa9161a690b9677vboxsync rc = RTStrToUtf16(pszPassword, &pwszPassword);
9ffc69ee5b1d727cdebfd2b3daa9161a690b9677vboxsync if (RT_SUCCESS(rc))
9ffc69ee5b1d727cdebfd2b3daa9161a690b9677vboxsync rc = RTStrToUtf16(pszDomain, &pwszDomain);
9ffc69ee5b1d727cdebfd2b3daa9161a690b9677vboxsync }
9ffc69ee5b1d727cdebfd2b3daa9161a690b9677vboxsync
9ffc69ee5b1d727cdebfd2b3daa9161a690b9677vboxsync if (RT_SUCCESS(rc))
9ffc69ee5b1d727cdebfd2b3daa9161a690b9677vboxsync {
9ffc69ee5b1d727cdebfd2b3daa9161a690b9677vboxsync *ppwszUser = pwszUser;
9ffc69ee5b1d727cdebfd2b3daa9161a690b9677vboxsync *ppwszPassword = pwszPassword;
9ffc69ee5b1d727cdebfd2b3daa9161a690b9677vboxsync *ppwszDomain = pwszDomain;
9ffc69ee5b1d727cdebfd2b3daa9161a690b9677vboxsync }
9ffc69ee5b1d727cdebfd2b3daa9161a690b9677vboxsync else
fb51a02921f8a53cad10e6dd1e25883403a93370vboxsync VbglR3CredentialsDestroyUtf16(pwszUser, pwszPassword, pwszDomain, 3 /* Passes */);
fb51a02921f8a53cad10e6dd1e25883403a93370vboxsync VbglR3CredentialsDestroy(pszUser, pszPassword, pszDomain, 3 /* Passes */);
9ffc69ee5b1d727cdebfd2b3daa9161a690b9677vboxsync }
9ffc69ee5b1d727cdebfd2b3daa9161a690b9677vboxsync
9ffc69ee5b1d727cdebfd2b3daa9161a690b9677vboxsync return rc;
9ffc69ee5b1d727cdebfd2b3daa9161a690b9677vboxsync}
9ffc69ee5b1d727cdebfd2b3daa9161a690b9677vboxsync
fb51a02921f8a53cad10e6dd1e25883403a93370vboxsync
940534f83612182a14887c7ccac92bfc43cbebd2vboxsync/**
20627226661ed2e925ff34f706827529ec880624vboxsync * Clears and frees the three strings.
940534f83612182a14887c7ccac92bfc43cbebd2vboxsync *
4fd422211bfa08d134940933274daafa9f2a3ef7vboxsync * @param pszUser Receives pointer of the user name string to destroy.
940534f83612182a14887c7ccac92bfc43cbebd2vboxsync * Optional.
4fd422211bfa08d134940933274daafa9f2a3ef7vboxsync * @param pszPassword Receives pointer of the password string to destroy.
940534f83612182a14887c7ccac92bfc43cbebd2vboxsync * Optional.
940534f83612182a14887c7ccac92bfc43cbebd2vboxsync * @param pszDomain Receives pointer of allocated domain name string.
940534f83612182a14887c7ccac92bfc43cbebd2vboxsync * Optional.
20627226661ed2e925ff34f706827529ec880624vboxsync * @param cPasses Number of wipe passes. The more the better + slower.
940534f83612182a14887c7ccac92bfc43cbebd2vboxsync */
20627226661ed2e925ff34f706827529ec880624vboxsyncVBGLR3DECL(void) VbglR3CredentialsDestroy(char *pszUser, char *pszPassword, char *pszDomain, uint32_t cPasses)
940534f83612182a14887c7ccac92bfc43cbebd2vboxsync{
38a1025c152d8cfd52dda13ecccb8f601d5e84ebvboxsync /* wipe first */
38a1025c152d8cfd52dda13ecccb8f601d5e84ebvboxsync if (pszUser)
38a1025c152d8cfd52dda13ecccb8f601d5e84ebvboxsync RTMemWipeThoroughly(pszUser, strlen(pszUser) + 1, cPasses);
38a1025c152d8cfd52dda13ecccb8f601d5e84ebvboxsync if (pszPassword)
38a1025c152d8cfd52dda13ecccb8f601d5e84ebvboxsync RTMemWipeThoroughly(pszPassword, strlen(pszPassword) + 1, cPasses);
38a1025c152d8cfd52dda13ecccb8f601d5e84ebvboxsync if (pszDomain)
38a1025c152d8cfd52dda13ecccb8f601d5e84ebvboxsync RTMemWipeThoroughly(pszDomain, strlen(pszDomain) + 1, cPasses);
38a1025c152d8cfd52dda13ecccb8f601d5e84ebvboxsync
38a1025c152d8cfd52dda13ecccb8f601d5e84ebvboxsync /* then free. */
20627226661ed2e925ff34f706827529ec880624vboxsync RTStrFree(pszUser);
20627226661ed2e925ff34f706827529ec880624vboxsync RTStrFree(pszPassword);
20627226661ed2e925ff34f706827529ec880624vboxsync RTStrFree(pszDomain);
940534f83612182a14887c7ccac92bfc43cbebd2vboxsync}
20627226661ed2e925ff34f706827529ec880624vboxsync
fb51a02921f8a53cad10e6dd1e25883403a93370vboxsync
9ffc69ee5b1d727cdebfd2b3daa9161a690b9677vboxsync/**
9ffc69ee5b1d727cdebfd2b3daa9161a690b9677vboxsync * Clears and frees the three strings. UTF-16 version.
9ffc69ee5b1d727cdebfd2b3daa9161a690b9677vboxsync *
9ffc69ee5b1d727cdebfd2b3daa9161a690b9677vboxsync * @param pwszUser Receives pointer of the user name string to destroy.
9ffc69ee5b1d727cdebfd2b3daa9161a690b9677vboxsync * Optional.
9ffc69ee5b1d727cdebfd2b3daa9161a690b9677vboxsync * @param pwszPassword Receives pointer of the password string to destroy.
9ffc69ee5b1d727cdebfd2b3daa9161a690b9677vboxsync * Optional.
9ffc69ee5b1d727cdebfd2b3daa9161a690b9677vboxsync * @param pwszDomain Receives pointer of allocated domain name string.
9ffc69ee5b1d727cdebfd2b3daa9161a690b9677vboxsync * Optional.
9ffc69ee5b1d727cdebfd2b3daa9161a690b9677vboxsync * @param cPasses Number of wipe passes. The more the better + slower.
9ffc69ee5b1d727cdebfd2b3daa9161a690b9677vboxsync */
9ffc69ee5b1d727cdebfd2b3daa9161a690b9677vboxsyncVBGLR3DECL(void) VbglR3CredentialsDestroyUtf16(PRTUTF16 pwszUser, PRTUTF16 pwszPassword, PRTUTF16 pwszDomain,
9ffc69ee5b1d727cdebfd2b3daa9161a690b9677vboxsync uint32_t cPasses)
9ffc69ee5b1d727cdebfd2b3daa9161a690b9677vboxsync{
9ffc69ee5b1d727cdebfd2b3daa9161a690b9677vboxsync /* wipe first */
9ffc69ee5b1d727cdebfd2b3daa9161a690b9677vboxsync if (pwszUser)
fb51a02921f8a53cad10e6dd1e25883403a93370vboxsync RTMemWipeThoroughly(pwszUser, (RTUtf16Len(pwszUser) + 1) * sizeof(RTUTF16), cPasses);
9ffc69ee5b1d727cdebfd2b3daa9161a690b9677vboxsync if (pwszPassword)
fb51a02921f8a53cad10e6dd1e25883403a93370vboxsync RTMemWipeThoroughly(pwszPassword, (RTUtf16Len(pwszPassword) + 1) * sizeof(RTUTF16), cPasses);
9ffc69ee5b1d727cdebfd2b3daa9161a690b9677vboxsync if (pwszDomain)
fb51a02921f8a53cad10e6dd1e25883403a93370vboxsync RTMemWipeThoroughly(pwszDomain, (RTUtf16Len(pwszDomain) + 1) * sizeof(RTUTF16), cPasses);
9ffc69ee5b1d727cdebfd2b3daa9161a690b9677vboxsync
9ffc69ee5b1d727cdebfd2b3daa9161a690b9677vboxsync /* then free. */
9ffc69ee5b1d727cdebfd2b3daa9161a690b9677vboxsync RTUtf16Free(pwszUser);
9ffc69ee5b1d727cdebfd2b3daa9161a690b9677vboxsync RTUtf16Free(pwszPassword);
9ffc69ee5b1d727cdebfd2b3daa9161a690b9677vboxsync RTUtf16Free(pwszDomain);
9ffc69ee5b1d727cdebfd2b3daa9161a690b9677vboxsync}
9ffc69ee5b1d727cdebfd2b3daa9161a690b9677vboxsync