9c0076729ec8138e89ce8a6af9a772b68f1f8dc7vboxsync/** @file
9c0076729ec8138e89ce8a6af9a772b68f1f8dc7vboxsync *
45c94fd5bc3ee64a3577f858c7eca5a566601c6fvboxsync * VirtualBox External Authentication Library:
9c0076729ec8138e89ce8a6af9a772b68f1f8dc7vboxsync * Simple Authentication.
9c0076729ec8138e89ce8a6af9a772b68f1f8dc7vboxsync */
9c0076729ec8138e89ce8a6af9a772b68f1f8dc7vboxsync
9c0076729ec8138e89ce8a6af9a772b68f1f8dc7vboxsync/*
45c94fd5bc3ee64a3577f858c7eca5a566601c6fvboxsync * Copyright (C) 2006-2011 Oracle Corporation
9c0076729ec8138e89ce8a6af9a772b68f1f8dc7vboxsync *
9c0076729ec8138e89ce8a6af9a772b68f1f8dc7vboxsync * This file is part of VirtualBox Open Source Edition (OSE), as
9c0076729ec8138e89ce8a6af9a772b68f1f8dc7vboxsync * available from http://www.virtualbox.org. This file is free software;
9c0076729ec8138e89ce8a6af9a772b68f1f8dc7vboxsync * you can redistribute it and/or modify it under the terms of the GNU
9c0076729ec8138e89ce8a6af9a772b68f1f8dc7vboxsync * General Public License (GPL) as published by the Free Software
9c0076729ec8138e89ce8a6af9a772b68f1f8dc7vboxsync * Foundation, in version 2 as it comes in the "COPYING" file of the
9c0076729ec8138e89ce8a6af9a772b68f1f8dc7vboxsync * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
9c0076729ec8138e89ce8a6af9a772b68f1f8dc7vboxsync * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
9c0076729ec8138e89ce8a6af9a772b68f1f8dc7vboxsync */
9c0076729ec8138e89ce8a6af9a772b68f1f8dc7vboxsync
9c0076729ec8138e89ce8a6af9a772b68f1f8dc7vboxsync#include <stdlib.h>
9c0076729ec8138e89ce8a6af9a772b68f1f8dc7vboxsync#include <stdio.h>
9c0076729ec8138e89ce8a6af9a772b68f1f8dc7vboxsync#include <string.h>
9c0076729ec8138e89ce8a6af9a772b68f1f8dc7vboxsync
9c0076729ec8138e89ce8a6af9a772b68f1f8dc7vboxsync#include <iprt/cdefs.h>
9c0076729ec8138e89ce8a6af9a772b68f1f8dc7vboxsync#include <iprt/uuid.h>
6754e49069315bd28137abb0f9241e3aeb99a97evboxsync#include <iprt/sha.h>
9c0076729ec8138e89ce8a6af9a772b68f1f8dc7vboxsync
b8908d384db2324f04a2f68a13e67ea32ebf609avboxsync#include <VBox/VBoxAuth.h>
9c0076729ec8138e89ce8a6af9a772b68f1f8dc7vboxsync
9c0076729ec8138e89ce8a6af9a772b68f1f8dc7vboxsync#include <VBox/com/com.h>
9c0076729ec8138e89ce8a6af9a772b68f1f8dc7vboxsync#include <VBox/com/string.h>
9c0076729ec8138e89ce8a6af9a772b68f1f8dc7vboxsync#include <VBox/com/Guid.h>
9c0076729ec8138e89ce8a6af9a772b68f1f8dc7vboxsync#include <VBox/com/VirtualBox.h>
9c0076729ec8138e89ce8a6af9a772b68f1f8dc7vboxsync
9c0076729ec8138e89ce8a6af9a772b68f1f8dc7vboxsyncusing namespace com;
9c0076729ec8138e89ce8a6af9a772b68f1f8dc7vboxsync
9c0076729ec8138e89ce8a6af9a772b68f1f8dc7vboxsync/* If defined, debug messages will be written to the specified file. */
b8908d384db2324f04a2f68a13e67ea32ebf609avboxsync//#define AUTH_DEBUG_FILE_NAME "/tmp/VBoxAuth.log"
9c0076729ec8138e89ce8a6af9a772b68f1f8dc7vboxsync
9c0076729ec8138e89ce8a6af9a772b68f1f8dc7vboxsync
9c0076729ec8138e89ce8a6af9a772b68f1f8dc7vboxsyncstatic void dprintf(const char *fmt, ...)
9c0076729ec8138e89ce8a6af9a772b68f1f8dc7vboxsync{
b8908d384db2324f04a2f68a13e67ea32ebf609avboxsync#ifdef AUTH_DEBUG_FILE_NAME
9c0076729ec8138e89ce8a6af9a772b68f1f8dc7vboxsync va_list va;
9c0076729ec8138e89ce8a6af9a772b68f1f8dc7vboxsync
9c0076729ec8138e89ce8a6af9a772b68f1f8dc7vboxsync va_start(va, fmt);
9c0076729ec8138e89ce8a6af9a772b68f1f8dc7vboxsync
9c0076729ec8138e89ce8a6af9a772b68f1f8dc7vboxsync char buffer[1024];
9c0076729ec8138e89ce8a6af9a772b68f1f8dc7vboxsync
9c0076729ec8138e89ce8a6af9a772b68f1f8dc7vboxsync vsnprintf(buffer, sizeof(buffer), fmt, va);
9c0076729ec8138e89ce8a6af9a772b68f1f8dc7vboxsync
b8908d384db2324f04a2f68a13e67ea32ebf609avboxsync FILE *f = fopen(AUTH_DEBUG_FILE_NAME, "ab");
8b98c71a5a01d215eafbc3605cb7a66cc91ea774vboxsync if (f)
8b98c71a5a01d215eafbc3605cb7a66cc91ea774vboxsync {
8b98c71a5a01d215eafbc3605cb7a66cc91ea774vboxsync fprintf(f, "%s", buffer);
8b98c71a5a01d215eafbc3605cb7a66cc91ea774vboxsync fclose(f);
8b98c71a5a01d215eafbc3605cb7a66cc91ea774vboxsync }
9c0076729ec8138e89ce8a6af9a772b68f1f8dc7vboxsync
9c0076729ec8138e89ce8a6af9a772b68f1f8dc7vboxsync va_end (va);
9c0076729ec8138e89ce8a6af9a772b68f1f8dc7vboxsync#endif
9c0076729ec8138e89ce8a6af9a772b68f1f8dc7vboxsync}
9c0076729ec8138e89ce8a6af9a772b68f1f8dc7vboxsync
9c0076729ec8138e89ce8a6af9a772b68f1f8dc7vboxsyncRT_C_DECLS_BEGIN
8b98c71a5a01d215eafbc3605cb7a66cc91ea774vboxsyncDECLEXPORT(AuthResult) AUTHCALL AuthEntry(const char *szCaller,
8b98c71a5a01d215eafbc3605cb7a66cc91ea774vboxsync PAUTHUUID pUuid,
8b98c71a5a01d215eafbc3605cb7a66cc91ea774vboxsync AuthGuestJudgement guestJudgement,
8b98c71a5a01d215eafbc3605cb7a66cc91ea774vboxsync const char *szUser,
8b98c71a5a01d215eafbc3605cb7a66cc91ea774vboxsync const char *szPassword,
8b98c71a5a01d215eafbc3605cb7a66cc91ea774vboxsync const char *szDomain,
8b98c71a5a01d215eafbc3605cb7a66cc91ea774vboxsync int fLogon,
8b98c71a5a01d215eafbc3605cb7a66cc91ea774vboxsync unsigned clientId)
9c0076729ec8138e89ce8a6af9a772b68f1f8dc7vboxsync{
9c0076729ec8138e89ce8a6af9a772b68f1f8dc7vboxsync /* default is failed */
8b98c71a5a01d215eafbc3605cb7a66cc91ea774vboxsync AuthResult result = AuthResultAccessDenied;
9c0076729ec8138e89ce8a6af9a772b68f1f8dc7vboxsync
9c0076729ec8138e89ce8a6af9a772b68f1f8dc7vboxsync /* only interested in logon */
9c0076729ec8138e89ce8a6af9a772b68f1f8dc7vboxsync if (!fLogon)
9c0076729ec8138e89ce8a6af9a772b68f1f8dc7vboxsync /* return value ignored */
9c0076729ec8138e89ce8a6af9a772b68f1f8dc7vboxsync return result;
9c0076729ec8138e89ce8a6af9a772b68f1f8dc7vboxsync
9c0076729ec8138e89ce8a6af9a772b68f1f8dc7vboxsync char uuid[RTUUID_STR_LENGTH] = {0};
9c0076729ec8138e89ce8a6af9a772b68f1f8dc7vboxsync if (pUuid)
9c0076729ec8138e89ce8a6af9a772b68f1f8dc7vboxsync RTUuidToStr((PCRTUUID)pUuid, (char*)uuid, RTUUID_STR_LENGTH);
9c0076729ec8138e89ce8a6af9a772b68f1f8dc7vboxsync
9c0076729ec8138e89ce8a6af9a772b68f1f8dc7vboxsync /* the user might contain a domain name, split it */
9c0076729ec8138e89ce8a6af9a772b68f1f8dc7vboxsync char *user = strchr((char*)szUser, '\\');
9c0076729ec8138e89ce8a6af9a772b68f1f8dc7vboxsync if (user)
9c0076729ec8138e89ce8a6af9a772b68f1f8dc7vboxsync user++;
9c0076729ec8138e89ce8a6af9a772b68f1f8dc7vboxsync else
9c0076729ec8138e89ce8a6af9a772b68f1f8dc7vboxsync user = (char*)szUser;
9c0076729ec8138e89ce8a6af9a772b68f1f8dc7vboxsync
6754e49069315bd28137abb0f9241e3aeb99a97evboxsync dprintf("VBoxAuth: uuid: %s, user: %s, szPassword: %s\n", uuid, user, szPassword);
9c0076729ec8138e89ce8a6af9a772b68f1f8dc7vboxsync
9c0076729ec8138e89ce8a6af9a772b68f1f8dc7vboxsync ComPtr<IVirtualBox> virtualBox;
9c0076729ec8138e89ce8a6af9a772b68f1f8dc7vboxsync HRESULT rc;
9c0076729ec8138e89ce8a6af9a772b68f1f8dc7vboxsync
9c0076729ec8138e89ce8a6af9a772b68f1f8dc7vboxsync rc = virtualBox.createLocalObject(CLSID_VirtualBox);
9c0076729ec8138e89ce8a6af9a772b68f1f8dc7vboxsync if (SUCCEEDED(rc))
9c0076729ec8138e89ce8a6af9a772b68f1f8dc7vboxsync {
6754e49069315bd28137abb0f9241e3aeb99a97evboxsync Bstr key = BstrFmt("VBoxAuthSimple/users/%s", user);
9c0076729ec8138e89ce8a6af9a772b68f1f8dc7vboxsync Bstr password;
9c0076729ec8138e89ce8a6af9a772b68f1f8dc7vboxsync
9c0076729ec8138e89ce8a6af9a772b68f1f8dc7vboxsync /* lookup in VM's extra data? */
9c0076729ec8138e89ce8a6af9a772b68f1f8dc7vboxsync if (pUuid)
9c0076729ec8138e89ce8a6af9a772b68f1f8dc7vboxsync {
9c0076729ec8138e89ce8a6af9a772b68f1f8dc7vboxsync ComPtr<IMachine> machine;
508452243fd3328f7b9e0405d39fb9dc004e31b8vboxsync virtualBox->FindMachine(Bstr(uuid).raw(), machine.asOutParam());
9c0076729ec8138e89ce8a6af9a772b68f1f8dc7vboxsync if (machine)
9c0076729ec8138e89ce8a6af9a772b68f1f8dc7vboxsync machine->GetExtraData(key.raw(), password.asOutParam());
9c0076729ec8138e89ce8a6af9a772b68f1f8dc7vboxsync } else
9c0076729ec8138e89ce8a6af9a772b68f1f8dc7vboxsync /* lookup global extra data */
9c0076729ec8138e89ce8a6af9a772b68f1f8dc7vboxsync virtualBox->GetExtraData(key.raw(), password.asOutParam());
9c0076729ec8138e89ce8a6af9a772b68f1f8dc7vboxsync
6754e49069315bd28137abb0f9241e3aeb99a97evboxsync if (!password.isEmpty())
9c0076729ec8138e89ce8a6af9a772b68f1f8dc7vboxsync {
6754e49069315bd28137abb0f9241e3aeb99a97evboxsync /* calculate hash */
6754e49069315bd28137abb0f9241e3aeb99a97evboxsync uint8_t abDigest[RTSHA256_HASH_SIZE];
6754e49069315bd28137abb0f9241e3aeb99a97evboxsync RTSha256(szPassword, strlen(szPassword), abDigest);
c8befbec2916e0bba4d254c81d87e5b0e78013bavboxsync char pszDigest[RTSHA256_DIGEST_LEN + 1];
6754e49069315bd28137abb0f9241e3aeb99a97evboxsync RTSha256ToString(abDigest, pszDigest, sizeof(pszDigest));
508452243fd3328f7b9e0405d39fb9dc004e31b8vboxsync
6754e49069315bd28137abb0f9241e3aeb99a97evboxsync if (password == pszDigest)
8b98c71a5a01d215eafbc3605cb7a66cc91ea774vboxsync result = AuthResultAccessGranted;
9c0076729ec8138e89ce8a6af9a772b68f1f8dc7vboxsync }
9c0076729ec8138e89ce8a6af9a772b68f1f8dc7vboxsync }
9c0076729ec8138e89ce8a6af9a772b68f1f8dc7vboxsync
9c0076729ec8138e89ce8a6af9a772b68f1f8dc7vboxsync return result;
9c0076729ec8138e89ce8a6af9a772b68f1f8dc7vboxsync}
9c0076729ec8138e89ce8a6af9a772b68f1f8dc7vboxsyncRT_C_DECLS_END
9c0076729ec8138e89ce8a6af9a772b68f1f8dc7vboxsync
9c0076729ec8138e89ce8a6af9a772b68f1f8dc7vboxsync/* Verify the function prototype. */
8b98c71a5a01d215eafbc3605cb7a66cc91ea774vboxsyncstatic PAUTHENTRY3 gpfnAuthEntry = AuthEntry;