/*********************************************************
- * Copyright (C) 2003-2018 VMware, Inc. All rights reserved.
+ * Copyright (C) 2003-2019 VMware, Inc. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as published
gboolean ToolsDaemonTcloReceiveVixCommand(RpcInData *data);
-static HgfsServerMgrData gFoundryHgfsBkdrConn;
-gboolean ToolsDaemonHgfsImpersonated(RpcInData *data);
-
#if defined(__linux__) || defined(_WIN32)
gboolean ToolsDaemonTcloSyncDriverFreeze(RpcInData *data);
}
#endif
- /* Register a straight through connection with the Hgfs server. */
- HgfsServerManager_DataInit(&gFoundryHgfsBkdrConn,
- VIX_BACKDOORCOMMAND_SEND_HGFS_PACKET,
- NULL, // rpc - no rpc registered
- NULL); // rpc callback
- HgfsServerManager_Register(&gFoundryHgfsBkdrConn);
-
}
void
FoundryToolsDaemon_Uninitialize(ToolsAppCtx *ctx)
{
- HgfsServerManager_Unregister(&gFoundryHgfsBkdrConn);
VixTools_Uninitialize();
}
} // ToolsDaemonTcloMountHGFS
-/*
- *-----------------------------------------------------------------------------
- *
- * ToolsDaemonHgfsImpersonated --
- *
- * Tclo cmd handler for hgfs requests.
- *
- * Here we receive guest user credentials and an HGFS packet to
- * be processed by the HGFS server under the context of
- * the guest user credentials.
- *
- * We pre-allocate a HGFS reply packet buffer and leave some space at
- * the beginning of the buffer for foundry error codes.
- * The format of the foundry error codes is a 64 bit number (as text),
- * followed by a 32 bit number (as text), followed by a hash,
- * all delimited by space (' '). The hash is needed
- * to make it easier for text parsers to know where the
- * HGFS reply packet begins, since it can start with a space.
- *
- * We do this funky "allocate an HGFS packet with extra
- * room for foundry error codes" to avoid copying buffers
- * around. The HGFS packet buffer is roughly 62k for large V3 Hgfs request
- * or 6k for other request , so it would be bad to copy that for every packet.
- *
- * It is guaranteed that we will not be called twice
- * at the same time, so it is safe for resultPacket to be static.
- * The TCLO processing loop (RpcInLoop()) is synchronous.
- *
- *
- * Results:
- * TRUE on TCLO success (*result contains the hgfs reply)
- * FALSE on TCLO error (not supposed to happen)
- *
- * Side effects:
- * None
- *
- *-----------------------------------------------------------------------------
- */
-
-gboolean
-ToolsDaemonHgfsImpersonated(RpcInData *data) // IN
-{
- VixError err;
- size_t hgfsPacketSize = 0;
- size_t hgfsReplySize = 0;
- const char *origArgs = data->args;
- Bool impersonatingVMWareUser = FALSE;
- char *credentialTypeStr = NULL;
- char *obfuscatedNamePassword = NULL;
- void *userToken = NULL;
- int actualUsed;
-#define STRLEN_OF_MAX_64_BIT_NUMBER_AS_STRING 20
-#define OTHER_TEXT_SIZE 4 /* strlen(space zero space quote) */
- static char resultPacket[STRLEN_OF_MAX_64_BIT_NUMBER_AS_STRING
- + OTHER_TEXT_SIZE
- + HGFS_LARGE_PACKET_MAX];
- char *hgfsReplyPacket = resultPacket
- + STRLEN_OF_MAX_64_BIT_NUMBER_AS_STRING
- + OTHER_TEXT_SIZE;
-
-
- err = VIX_OK;
-
- /*
- * We assume VixError is 64 bits. If it changes, we need
- * to adjust STRLEN_OF_MAX_64_BIT_NUMBER_AS_STRING.
- *
- * There isn't much point trying to return gracefully
- * if sizeof(VixError) is larger than we expected: we didn't
- * allocate enough space to actually represent the error!
- * So we're stuck. Panic at this point.
- */
- ASSERT_ON_COMPILE(sizeof (uint64) == sizeof err);
-
- /*
- * Get the authentication information.
- */
- credentialTypeStr = ToolsDaemonTcloGetQuotedString(data->args, &data->args);
- obfuscatedNamePassword = ToolsDaemonTcloGetQuotedString(data->args, &data->args);
-
- /*
- * Make sure we are passed the correct arguments.
- */
- if ((NULL == credentialTypeStr) || (NULL == obfuscatedNamePassword)) {
- err = VIX_E_INVALID_ARG;
- goto abort;
- }
-
- /*
- * Skip over our token that is right before the HGFS packet.
- * This makes ToolsDaemonTcloGetQuotedString parsing predictable,
- * since it will try to eat trailing spaces after a quoted string,
- * and the HGFS packet might begin with a space.
- */
- if (((data->args - origArgs) >= data->argsSize) || ('#' != *(data->args))) {
- /*
- * Buffer too small or we got an unexpected token.
- */
- err = VIX_E_FAIL;
- goto abort;
- }
- data->args++;
-
- /*
- * At this point args points to the HGFS packet.
- * If we're pointing beyond the end of the buffer, we'll
- * get a negative HGFS packet length and abort.
- */
- hgfsPacketSize = data->argsSize - (data->args - origArgs);
- if (hgfsPacketSize <= 0) {
- err = VIX_E_FAIL;
- goto abort;
- }
-
- if (thisProcessRunsAsRoot) {
- impersonatingVMWareUser = VixToolsImpersonateUserImpl(credentialTypeStr,
- VIX_USER_CREDENTIAL_NONE,
- obfuscatedNamePassword,
- &userToken);
- if (!impersonatingVMWareUser) {
- err = VIX_E_GUEST_USER_PERMISSIONS;
- goto abort;
- }
- }
-
- /*
- * Impersonation was okay, so let's give our packet to
- * the HGFS server and forward the reply packet back.
- */
- hgfsReplySize = sizeof resultPacket - (hgfsReplyPacket - resultPacket);
- HgfsServerManager_ProcessPacket(&gFoundryHgfsBkdrConn, // hgfs server connection
- data->args, // packet in buf
- hgfsPacketSize, // packet in size
- hgfsReplyPacket, // packet out buf
- &hgfsReplySize); // reply buf/data size
-
-abort:
- if (impersonatingVMWareUser) {
- VixToolsUnimpersonateUser(userToken);
- }
- VixToolsLogoutUser(userToken);
-
- /*
- * These were allocated by ToolsDaemonTcloGetQuotedString.
- */
- free(credentialTypeStr);
- free(obfuscatedNamePassword);
-
- data->result = resultPacket;
- data->resultLen = STRLEN_OF_MAX_64_BIT_NUMBER_AS_STRING
- + OTHER_TEXT_SIZE
- + hgfsReplySize;
-
- /*
- * Render the foundry error codes into the buffer.
- */
- actualUsed = Str_Snprintf(resultPacket,
- STRLEN_OF_MAX_64_BIT_NUMBER_AS_STRING
- + OTHER_TEXT_SIZE,
- "%"FMT64"d 0 ",
- err);
-
- if (actualUsed < 0) {
- /*
- * We computed our string length wrong! This should never happen.
- * But if it does, let's try to recover gracefully. The "1" in
- * the string below is VIX_E_FAIL. We don't try to use %d since
- * we couldn't even do that right the first time around.
- * That hash is needed for the parser on the other
- * end to stop before the HGFS packet, since the HGFS packet
- * can contain a space (and the parser can eat trailing spaces).
- */
- ASSERT(0);
- actualUsed = Str_Snprintf(resultPacket,
- STRLEN_OF_MAX_64_BIT_NUMBER_AS_STRING,
- "1 0 #");
- data->resultLen = actualUsed;
- } else {
- /*
- * We computed the string length correctly. Great!
- *
- * We allocated enough space to cover a large 64 bit number
- * for VixError. Chances are we didn't use all that space.
- * Instead, pad it with whitespace so the text parser can skip
- * over it.
- */
- memset(resultPacket + actualUsed,
- ' ',
- STRLEN_OF_MAX_64_BIT_NUMBER_AS_STRING
- + OTHER_TEXT_SIZE
- - actualUsed);
- /*
- * Put a hash right before the HGFS packet.
- * So the buffer will look something like this:
- * "0 0 #" followed by the HGFS packet.
- */
- resultPacket[STRLEN_OF_MAX_64_BIT_NUMBER_AS_STRING
- + OTHER_TEXT_SIZE - 1] = '#';
- }
-
- g_message("%s\n", __FUNCTION__);
- return TRUE;
-} // ToolsDaemonHgfsImpersonated
-
#undef STRLEN_OF_MAX_64_BIT_NUMBER_AS_STRING
#undef OTHER_TEXT_SIZE