Changeset 33806 in vbox
- Timestamp:
- Nov 5, 2010 5:20:15 PM (14 years ago)
- Location:
- trunk
- Files:
-
- 30 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/Config.kmk
r33677 r33806 3008 3008 3009 3009 # 3010 # Template for building set-uid-to-root helper programs. 3011 # These shall have not extra runpaths, esp. not origin ones. 3012 # 3013 TEMPLATE_VBoxR3SetUidToRoot = Set-uid-to-root helper program. 3014 TEMPLATE_VBoxR3SetUidToRoot_EXTENDS = VBOXR3HARDENEDEXE 3015 TEMPLATE_VBoxR3SetUidToRoot_LIBS = $(NO_SUCH_VARIABLE) 3016 3017 3018 # 3010 3019 # Template for building R3 shared objects / DLLs with the 10.5 Mac OS X SDK. 3011 3020 # Identical to VBOXR3EXE, except for the DYLIB, the classic_linker and SDK bits. -
trunk/include/VBox/err.h
r33739 r33806 1390 1390 /** The file or directory is world writable (hardening). */ 1391 1391 #define VERR_SUPLIB_WORLD_WRITABLE (-3767) 1392 /** The argv[0] of an internal application does not match the executable image 1393 * path (hardening). */ 1394 #define VERR_SUPLIB_INVALID_ARGV0_INTERNAL (-3768) 1395 /** The internal application does not reside in the correct place (hardening). */ 1396 #define VERR_SUPLIB_INVALID_INTERNAL_APP_DIR (-3769) 1392 1397 /** @} */ 1393 1398 -
trunk/include/VBox/sup.h
r33739 r33806 971 971 * @param phFile Where to store the handle to the opened file. This is optional, pass NULL 972 972 * if the file should not be opened. 973 * @deprecated Write a new one. 973 974 */ 974 975 SUPR3DECL(int) SUPR3HardenedVerifyFile(const char *pszFilename, const char *pszWhat, PRTFILE phFile); 976 977 /** 978 * Verifies the integrity of a the current process, including the image 979 * location and that the invocation was absolute. 980 * 981 * This must currently be called after initializing the runtime. The intended 982 * audience is set-uid-to-root applications, root services and similar. 983 * 984 * @returns VBox status code. On failure 985 * message. 986 * @param pszArgv0 The first argument to main(). 987 * @param fInternal Set this to @c true if this is an internal 988 * VirtualBox application. Otherwise pass @c false. 989 * @param pszErr Where to return error message on failure. 990 * @param cbErr The size of the error buffer. 991 */ 992 SUPR3DECL(int) SUPR3HardenedVerifySelf(const char *pszArgv0, bool fInternal, char *pszErr, size_t cbErr); 975 993 976 994 /** -
trunk/include/iprt/process.h
r33044 r33806 282 282 283 283 /** 284 * Gets the executable image name (full path) of the current process. 285 * 286 * @returns pszExecName on success. NULL on buffer overflow or other errors. 287 * 288 * @param pszExecName Where to store the name. 289 * @param cchExecName The size of the buffer. 290 */ 291 RTR3DECL(char *) RTProcGetExecutableName(char *pszExecName, size_t cchExecName); 284 * Gets the short process name. 285 * 286 * @returns Pointer to read-only name string. 287 */ 288 RTR3DECL(const char *) RTProcShortName(void); 289 290 /** 291 * Gets the path to the executable image of the current process. 292 * 293 * @returns pszExecPath on success. NULL on buffer overflow or other errors. 294 * 295 * @param pszExecPath Where to store the path. 296 * @param cbExecPath The size of the buffer. 297 */ 298 RTR3DECL(char *) RTProcGetExecutablePath(char *pszExecPath, size_t cbExecPath); 292 299 293 300 /** -
trunk/src/VBox/Additions/common/VBoxService/VBoxServiceControlExec.cpp
r33762 r33806 1049 1049 /* Search the path of our executable. */ 1050 1050 char szVBoxService[RTPATH_MAX]; 1051 if (RTProcGetExecutable Name(szVBoxService, sizeof(szVBoxService)))1051 if (RTProcGetExecutablePath(szVBoxService, sizeof(szVBoxService))) 1052 1052 { 1053 1053 char *pszExecResolved = NULL; -
trunk/src/VBox/Additions/common/VBoxService/VBoxServicePageSharing.cpp
r32772 r33806 690 690 { 691 691 char szExeName[256]; 692 char *pszExeName = RTProcGetExecutable Name(szExeName, sizeof(szExeName));692 char *pszExeName = RTProcGetExecutablePath(szExeName, sizeof(szExeName)); 693 693 if (pszExeName) 694 694 { -
trunk/src/VBox/HostDrivers/Support/SUPLib.cpp
r33740 r33806 1438 1438 1439 1439 1440 SUPR3DECL(int) SUPR3HardenedVerifySelf(const char *pszArgv0, bool fInternal, char *pszErr, size_t cbErr) 1441 { 1442 /* 1443 * Quick input validation. 1444 */ 1445 AssertPtr(pszArgv0); 1446 AssertPtr(pszErr); 1447 Assert(cbErr > 32); 1448 1449 /* 1450 * Get the executable image path as we need it for all the tests here. 1451 */ 1452 char szExecPath[RTPATH_MAX]; 1453 if (!RTProcGetExecutablePath(szExecPath, sizeof(szExecPath))) 1454 { 1455 RTStrPrintf(pszErr, cbErr, "RTProcGetExecutablePath failed"); 1456 return VERR_INTERNAL_ERROR_2; 1457 } 1458 1459 int rc; 1460 if (fInternal) 1461 { 1462 /* 1463 * Internal applications must be launched directly without any PATH 1464 * searching involved. 1465 */ 1466 if (RTPathCompare(pszArgv0, szExecPath) != 0) 1467 { 1468 RTStrPrintf(pszErr, cbErr, "argv[0] does not match the executable image path: '%s' != '%s'", pszArgv0, szExecPath); 1469 return VERR_SUPLIB_INVALID_ARGV0_INTERNAL; 1470 } 1471 1472 /* 1473 * Internal applications must reside in or under the 1474 * RTPathAppPrivateArch directory. 1475 */ 1476 char szAppPrivateArch[RTPATH_MAX]; 1477 rc = RTPathAppPrivateArch(szAppPrivateArch, sizeof(szAppPrivateArch)); 1478 if (RT_FAILURE(rc)) 1479 { 1480 RTStrPrintf(pszErr, cbErr, "RTPathAppPrivateArch failed with rc=%Rrc", rc); 1481 return VERR_SUPLIB_INVALID_ARGV0_INTERNAL; 1482 } 1483 size_t cchAppPrivateArch = strlen(szAppPrivateArch); 1484 if ( cchAppPrivateArch >= strlen(szExecPath) 1485 || !RTPATH_IS_SLASH(szExecPath[cchAppPrivateArch])) 1486 { 1487 RTStrPrintf(pszErr, cbErr, "Internal executable does reside under RTPathAppPrivateArch"); 1488 return VERR_SUPLIB_INVALID_INTERNAL_APP_DIR; 1489 } 1490 szExecPath[cchAppPrivateArch] = '\0'; 1491 if (RTPathCompare(szExecPath, szAppPrivateArch) != 0) 1492 { 1493 RTStrPrintf(pszErr, cbErr, "Internal executable does reside under RTPathAppPrivateArch"); 1494 return VERR_SUPLIB_INVALID_INTERNAL_APP_DIR; 1495 } 1496 szExecPath[cchAppPrivateArch] = RTPATH_SLASH; 1497 } 1498 1499 #ifdef VBOX_WITH_HARDENING 1500 /* 1501 * Verify that the image file and parent directories are sane. 1502 */ 1503 rc = supR3HardenedVerifyFile(szPath, NULL, pszErr, cbErr); 1504 if (RT_FAILURE(rc)) 1505 return rc; 1506 #endif 1507 1508 return VINF_SUCCESS; 1509 } 1510 1511 1440 1512 SUPR3DECL(int) SUPR3HardenedVerifyDir(const char *pszDirPath, bool fRecursive, bool fCheckFiles, char *pszErr, size_t cbErr) 1441 1513 { -
trunk/src/VBox/HostServices/GuestControl/testcase/tstGuestControlSvc.cpp
r31847 r33806 1127 1127 1128 1128 /* Save image name for later use. */ 1129 if (!RTProcGetExecutable Name(g_szImageName, sizeof(g_szImageName)))1130 return RTMsgErrorExit(RTEXITCODE_FAILURE, "RTProcGetExecutable Namefailed\n");1129 if (!RTProcGetExecutablePath(g_szImageName, sizeof(g_szImageName))) 1130 return RTMsgErrorExit(RTEXITCODE_FAILURE, "RTProcGetExecutablePath failed\n"); 1131 1131 1132 1132 VBOXHGCMSVCFNTABLE svcTable; -
trunk/src/VBox/HostServices/SharedOpenGL/render/renderspu_cocoa.c
r33540 r33806 68 68 /* VirtualBox is the only frontend which support 3D right now. */ 69 69 char pszName[256]; 70 if (RTProcGetExecutable Name(pszName, sizeof(pszName)))70 if (RTProcGetExecutablePath(pszName, sizeof(pszName))) 71 71 /* Check for VirtualBox and VirtualBoxVM */ 72 72 if (RTStrNICmp(RTPathFilename(pszName), "VirtualBox", 10) != 0) -
trunk/src/VBox/Main/ConsoleImpl.cpp
r33784 r33806 5066 5066 /* the package type is interesting for Linux distributions */ 5067 5067 char szExecName[RTPATH_MAX]; 5068 char *pszExecName = RTProcGetExecutable Name(szExecName, sizeof(szExecName));5068 char *pszExecName = RTProcGetExecutablePath(szExecName, sizeof(szExecName)); 5069 5069 RTLogRelLogger(loggerRelease, 0, ~0U, 5070 5070 "Executable: %s\n" -
trunk/src/VBox/Main/DHCPServerRunner.cpp
r31539 r33806 83 83 /* get the path to the executable */ 84 84 char exePathBuf[RTPATH_MAX]; 85 const char *exePath = RTProcGetExecutable Name(exePathBuf, RTPATH_MAX);85 const char *exePath = RTProcGetExecutablePath(exePathBuf, RTPATH_MAX); 86 86 char *substrSl = strrchr(exePathBuf, '/'); 87 87 char *substrBs = strrchr(exePathBuf, '\\'); -
trunk/src/VBox/Main/ExtPackManagerImpl.cpp
r33765 r33806 445 445 if (RT_FAILURE(vrc)) 446 446 { 447 m->strWhyUnusable.printf(tr("%s "), szErr);447 m->strWhyUnusable.printf(tr("%s (rc=%Rrc)"), szErr, vrc); 448 448 return; 449 449 } … … 842 842 int rc = RTPathAppPrivateArch(szBaseDir, sizeof(szBaseDir)); 843 843 AssertLogRelRCReturn(rc, E_FAIL); 844 rc = RTPathAppend(szBaseDir, sizeof(szBaseDir), "ExtensionPacks");844 rc = RTPathAppend(szBaseDir, sizeof(szBaseDir), VBOX_EXTPACK_INSTALL_DIR); 845 845 AssertLogRelRCReturn(rc, E_FAIL); 846 846 847 847 char szCertificatDir[RTPATH_MAX]; 848 rc = RTPathAppPrivate Arch(szCertificatDir, sizeof(szCertificatDir));848 rc = RTPathAppPrivateNoArch(szCertificatDir, sizeof(szCertificatDir)); 849 849 AssertLogRelRCReturn(rc, E_FAIL); 850 rc = RTPathAppend(szBaseDir, sizeof(szCertificatDir), "Certificates");850 rc = RTPathAppend(szBaseDir, sizeof(szCertificatDir), VBOX_EXTPACK_CERT_DIR); 851 851 AssertLogRelRCReturn(rc, E_FAIL); 852 852 … … 882 882 if ( RTFS_IS_DIRECTORY(Entry.Info.Attr.fMode) 883 883 && strcmp(Entry.szName, ".") != 0 884 && strcmp(Entry.szName, "..") != 0 ) 884 && strcmp(Entry.szName, "..") != 0 885 && VBoxExtPackIsValidName(Entry.szName) ) 885 886 { 886 887 /* … … 1003 1004 /* 1004 1005 * Derive the name of the extension pack from the file 1005 * name. 1006 * 1007 * RESTRICTION: The name can only contain english alphabet 1008 * charactes, decimal digits and space. 1009 * Impose a max length of 64 chars. 1006 * name. Certain restrictions are here placed on the 1007 * tarball name. 1010 1008 */ 1011 char *pszName = RTStrDup(RTPathFilename(strTarball.c_str()));1012 if (p szName)1009 iprt::MiniString *pStrName = VBoxExtPackExtractNameFromTarballPath(strTarball.c_str()); 1010 if (pStrName) 1013 1011 { 1014 char *pszEnd = pszName; 1015 while (RT_C_IS_ALNUM(*pszEnd) || *pszEnd == ' ') 1016 pszEnd++; 1017 if ( pszEnd == pszName 1018 || pszEnd - pszName <= 64) 1012 /* 1013 * Refresh the data we have on the extension pack as it 1014 * may be made stale by direct meddling or some other user. 1015 */ 1016 ExtPack *pExtPack; 1017 hrc = refreshExtPack(pStrName->c_str(), false /*a_fUnsuableIsError*/, &pExtPack); 1018 if (SUCCEEDED(hrc) && !pExtPack) 1019 1019 { 1020 *pszEnd = '\0';1021 1022 1020 /* 1023 * R efresh the data we have on the extension pack1024 * as it may be made stale by direct meddling or1025 * some other user.1021 * Run the set-uid-to-root binary that performs the actual 1022 * installation. Then create an object for the packet (we 1023 * do this even on failure, to be on the safe side). 1026 1024 */ 1027 ExtPack *pExtPack; 1028 hrc = refreshExtPack(pszName, false /*a_fUnsuableIsError*/, &pExtPack); 1029 if (SUCCEEDED(hrc) && !pExtPack) 1025 char szTarballFd[64]; 1026 RTStrPrintf(szTarballFd, sizeof(szTarballFd), "0x%RX64", 1027 (uint64_t)RTFileToNative(hFile)); 1028 1029 hrc = runSetUidToRootHelper("install", 1030 "--base-dir", m->strBaseDir.c_str(), 1031 "--certificate-dir", m->strCertificatDirPath.c_str(), 1032 "--name", pStrName->c_str(), 1033 "--tarball", strTarball.c_str(), 1034 "--tarball-fd", &szTarballFd[0], 1035 NULL); 1036 if (SUCCEEDED(hrc)) 1030 1037 { 1031 /* 1032 * Run the set-uid-to-root binary that performs the actual 1033 * installation. Then create an object for the packet (we 1034 * do this even on failure, to be on the safe side). 1035 */ 1036 char szTarballFd[64]; 1037 RTStrPrintf(szTarballFd, sizeof(szTarballFd), "0x%RX64", 1038 (uint64_t)RTFileToNative(hFile)); 1039 1040 hrc = runSetUidToRootHelper("install", 1041 "--base-dir", m->strBaseDir.c_str(), 1042 "--name", pszName, 1043 "--certificate-dir", m->strCertificatDirPath.c_str(), 1044 "--tarball", strTarball.c_str(), 1045 "--tarball-fd", &szTarballFd[0], 1046 NULL); 1038 hrc = refreshExtPack(pStrName->c_str(), true /*a_fUnsuableIsError*/, &pExtPack); 1047 1039 if (SUCCEEDED(hrc)) 1048 1040 { 1049 hrc = refreshExtPack(pszName, true /*a_fUnsuableIsError*/, &pExtPack); 1050 if (SUCCEEDED(hrc)) 1051 { 1052 LogRel(("ExtPackManager: Successfully installed extension pack '%s'.\n", pszName)); 1053 pExtPack->callInstalledHook(); 1054 } 1055 } 1056 else 1057 { 1058 ErrorInfoKeeper Eik; 1059 refreshExtPack(pszName, false /*a_fUnsuableIsError*/, NULL); 1041 LogRel(("ExtPackManager: Successfully installed extension pack '%s'.\n", pStrName->c_str())); 1042 pExtPack->callInstalledHook(); 1060 1043 } 1061 1044 } 1062 else if (SUCCEEDED(hrc))1063 hrc = setError(E_FAIL,1064 tr("Extension pack '%s' is already installed."1065 " In case of a reinstallation, please uninstall it first"),1066 pszName);1045 else 1046 { 1047 ErrorInfoKeeper Eik; 1048 refreshExtPack(pStrName->c_str(), false /*a_fUnsuableIsError*/, NULL); 1049 } 1067 1050 } 1068 else 1069 hrc = setError(E_FAIL, tr("Malformed '%s' file name"), strTarball.c_str()); 1051 else if (SUCCEEDED(hrc)) 1052 hrc = setError(E_FAIL, 1053 tr("Extension pack '%s' is already installed." 1054 " In case of a reinstallation, please uninstall it first"), 1055 pStrName->c_str()); 1056 delete pStrName; 1070 1057 } 1071 1058 else 1072 hrc = E_OUTOFMEMORY;1059 hrc = setError(E_FAIL, tr("Malformed '%s' file name"), strTarball.c_str()); 1073 1060 } 1074 1061 else if (RT_SUCCESS(vrc)) -
trunk/src/VBox/Main/ExtPackUtil.cpp
r33656 r33806 15 15 * Header Files * 16 16 *******************************************************************************/ 17 #include " ExtPackUtil.h"17 #include "include/ExtPackUtil.h" 18 18 19 19 #include <iprt/ctype.h> … … 150 150 151 151 /** 152 * Extract the extension pack name from the tarball path. 153 * 154 * @returns String containing the name on success, the caller must delete it. 155 * NULL if no valid name was found or if we ran out of memory. 156 * @param pszTarball The path to the tarball. 157 */ 158 iprt::MiniString *VBoxExtPackExtractNameFromTarballPath(const char *pszTarball) 159 { 160 /* 161 * Skip ahead to the filename part and count the number of characters 162 * that matches the criteria for a extension pack name. 163 */ 164 const char *pszSrc = RTPathFilename(pszTarball); 165 if (!pszSrc) 166 return NULL; 167 168 size_t off = 0; 169 while (RT_C_IS_ALNUM(pszSrc[off]) || pszSrc[off] == ' ') 170 off++; 171 172 /* 173 * Check min and max name limits. 174 */ 175 if ( off > VBOX_EXTPACK_NAME_MIN_LEN 176 || off < VBOX_EXTPACK_NAME_MIN_LEN) 177 return NULL; 178 179 /* 180 * Make a duplicate of the name and return it. 181 */ 182 iprt::MiniString *pStrRet = new iprt::MiniString(off, pszSrc); 183 Assert(VBoxExtPackIsValidName(pStrRet->c_str())); 184 return pStrRet; 185 } 186 187 188 /** 152 189 * Validates the extension pack name. 153 190 * 154 191 * @returns true if valid, false if not. 155 192 * @param pszName The name to validate. 193 * @sa VBoxExtPackExtractNameFromTarballPath 156 194 */ 157 195 bool VBoxExtPackIsValidName(const char *pszName) 158 196 { 159 /* This must match the code in the extension manager. */ 160 if (!pszName || *pszName == '\0') 161 return false; 162 while (RT_C_IS_ALNUM(*pszName) || *pszName == ' ') 163 pszName++; 164 return *pszName == '\0'; 197 if (!pszName) 198 return false; 199 200 /* 201 * Check the characters making up the name, only english alphabet 202 * characters, decimal digits and spaces are allowed. 203 */ 204 size_t off = 0; 205 while (pszName[off]) 206 { 207 if (!RT_C_IS_ALNUM(pszName[off]) && !pszName[off] == ' ') 208 return false; 209 off++; 210 } 211 212 /* 213 * Check min and max name limits. 214 */ 215 if ( off > VBOX_EXTPACK_NAME_MIN_LEN 216 || off < VBOX_EXTPACK_NAME_MIN_LEN) 217 return false; 218 219 return true; 165 220 } 166 221 -
trunk/src/VBox/Main/Makefile.kmk
r33784 r33806 730 730 ifeq ($(LOGNAME),bird) # def VBOX_WITH_EXTPACK 731 731 PROGRAMS += VBoxExtPackHelperApp 732 VBoxExtPackHelperApp_TEMPLATE = VBoxR3Static 733 VBoxExtPackHelperApp_SOURCES = VBoxExtPackHelperApp.cpp 734 VBoxExtPackHelperApp_DEFS = IN_RT_R3 732 VBoxExtPackHelperApp_TEMPLATE = VBoxR3SetUidToRoot 733 VBoxExtPackHelperApp_SOURCES = \ 734 VBoxExtPackHelperApp.cpp \ 735 ExtPackUtil.cpp 735 736 VBoxExtPackHelperApp_LIBS = \ 736 $(VBOX_LIB_RUNTIME_STATIC) 737 $(LIB_RUNTIME) 738 737 739 endif # VBOX_WITH_EXTPACK 738 740 -
trunk/src/VBox/Main/VBoxExtPackHelperApp.cpp
r33784 r33806 19 19 #include <iprt/buildconfig.h> 20 20 //#include <iprt/ctype.h> 21 //#include <iprt/dir.h>21 #include <iprt/dir.h> 22 22 //#include <iprt/env.h> 23 //#include <iprt/file.h> 23 #include <iprt/file.h> 24 #include <iprt/fs.h> 24 25 #include <iprt/getopt.h> 25 26 #include <iprt/initterm.h> 26 27 #include <iprt/message.h> 27 //#include <iprt/param.h>28 #include <iprt/param.h> 28 29 #include <iprt/path.h> 29 30 //#include <iprt/pipe.h> 31 #include <iprt/process.h> 30 32 #include <iprt/string.h> 31 33 #include <iprt/stream.h> … … 33 35 #include <VBox/log.h> 34 36 #include <VBox/err.h> 37 #include <VBox/sup.h> 35 38 #include <VBox/version.h> 36 39 … … 40 43 { 41 44 return true; 45 } 46 47 48 /** 49 * Handle the special standard options when these are specified after the 50 * command. 51 * 52 * @param ch The option character. 53 */ 54 static RTEXITCODE DoStandardOption(int ch) 55 { 56 switch (ch) 57 { 58 case 'h': 59 { 60 RTMsgInfo(VBOX_PRODUCT " Extension Pack Helper App\n" 61 "(C) " VBOX_C_YEAR " " VBOX_VENDOR "\n" 62 "All rights reserved.\n" 63 "\n" 64 "This NOT intended for general use, please use VBoxManage instead\n" 65 "or call the IExtPackManager API directly.\n" 66 "\n" 67 "Usage: %s <command> [options]\n" 68 "Commands:\n" 69 " install --base-dir <dir> --certificate-dir <dir> --name <name> \\\n" 70 " --tarball <tarball> --tarball-fd <fd>\n" 71 " uninstall --base-dir <dir> --name <name>\n" 72 , RTProcShortName()); 73 return RTEXITCODE_SUCCESS; 74 } 75 76 case 'V': 77 RTPrintf("%sr%d\n", VBOX_VERSION_STRING, RTBldCfgRevision()); 78 return RTEXITCODE_SUCCESS; 79 80 default: 81 AssertFailedReturn(RTEXITCODE_FAILURE); 82 } 83 } 84 85 86 /** 87 * Checks if the cerficiate directory is valid. 88 * 89 * @returns true if it is valid, false if it isn't. 90 * @param pszCertDir The certificate directory to validate. 91 */ 92 static bool IsValidCertificateDir(const char *pszCertDir) 93 { 94 /* 95 * Just be darn strict for now. 96 */ 97 char szCorrect[RTPATH_MAX]; 98 int rc = RTPathAppPrivateNoArch(szCorrect, sizeof(szCorrect)); 99 if (RT_FAILURE(rc)) 100 return false; 101 rc = RTPathAppend(szCorrect, sizeof(szCorrect), VBOX_EXTPACK_CERT_DIR); 102 if (RT_FAILURE(rc)) 103 return false; 104 105 return RTPathCompare(szCorrect, pszCertDir) == 0; 106 } 107 108 109 /** 110 * Checks if the base directory is valid. 111 * 112 * @returns true if it is valid, false if it isn't. 113 * @param pszBaesDir The base directory to validate. 114 */ 115 static bool IsValidBaseDir(const char *pszBaseDir) 116 { 117 /* 118 * Just be darn strict for now. 119 */ 120 char szCorrect[RTPATH_MAX]; 121 int rc = RTPathAppPrivateArch(szCorrect, sizeof(szCorrect)); 122 if (RT_FAILURE(rc)) 123 return false; 124 rc = RTPathAppend(szCorrect, sizeof(szCorrect), VBOX_EXTPACK_INSTALL_DIR); 125 if (RT_FAILURE(rc)) 126 return false; 127 128 return RTPathCompare(szCorrect, pszBaseDir) == 0; 129 } 130 131 /** 132 * Cleans up a temporary extension pack directory. 133 * 134 * This is used by 'uninstall', 'cleanup' and in the failure path of 'install'. 135 * 136 * @returns The program exit code. 137 * @param pszDir The directory to clean up. The caller is 138 * responsible for making sure this is valid. 139 * @param fTemporary Whether this is a temporary install directory or 140 * not. 141 */ 142 static RTEXITCODE RemoveExtPackDir(const char *pszDir, bool fTemporary) 143 { 144 /** @todo May have to undo 555 modes here later. */ 145 int rc = RTDirRemoveRecursive(pszDir, RTDIRRMREC_F_CONTENT_AND_DIR); 146 if (RT_FAILURE(rc)) 147 return RTMsgErrorExit(RTEXITCODE_FAILURE, 148 "Failed to delete the %sextension pack directory: %Rrc ('%s')", 149 fTemporary ? "temporary " : "", rc, pszDir); 150 return RTEXITCODE_SUCCESS; 151 } 152 153 154 /** 155 * Sets the permissions of the temporary extension pack directory just before 156 * renaming it. 157 * 158 * By default the temporary directory is only accessible by root, this function 159 * will make it world readable and browseable. 160 * 161 * @returns The program exit code. 162 * @param pszDir The temporary extension pack directory. 163 */ 164 static RTEXITCODE SetExtPackPermissions(const char *pszDir) 165 { 166 #if !defined(RT_OS_WINDOWS) 167 int rc = RTPathSetMode(pszDir, 0755); 168 if (RT_FAILURE(rc)) 169 return RTMsgErrorExit(RTEXITCODE_FAILURE, "Failed to set directory permissions: %Rrc ('%s')", rc, pszDir); 170 #else 171 /** @todo */ 172 #endif 173 174 return RTEXITCODE_SUCCESS; 175 } 176 177 /** 178 * Validates the extension pack. 179 * 180 * Operations performed: 181 * - Manifest seal check. 182 * - Manifest check. 183 * - Recursive hardening check. 184 * - XML validity check. 185 * - Name check (against XML). 186 * 187 * @returns The program exit code. 188 * @param pszDir The directory where the extension pack has been 189 * unpacked. 190 * @param pszName The expected extension pack name. 191 * @param pszTarball The name of the tarball in case we have to 192 * complain about something. 193 */ 194 static RTEXITCODE ValidateExtPack(const char *pszDir, const char *pszTarball, const char *pszName) 195 { 196 /** @todo */ 197 return RTEXITCODE_SUCCESS; 198 } 199 200 201 /** 202 * Unpacks the extension pack into the specified directory. 203 * 204 * This will apply ownership and permission changes to all the content, the 205 * exception is @a pszDirDst which will be handled by SetExtPackPermissions. 206 * 207 * @returns The program exit code. 208 * @param hTarballFile The tarball to unpack. 209 * @param pszDirDst Where to unpack it. 210 * @param pszTarball The name of the tarball in case we have to 211 * complain about something. 212 */ 213 static RTEXITCODE UnpackExtPack(RTFILE hTarballFile, const char *pszDirDst, const char *pszTarball) 214 { 215 /** @todo */ 216 return RTEXITCODE_SUCCESS; 217 } 218 219 220 /** 221 * The 2nd part of the installation process. 222 * 223 * @returns The program exit code. 224 * @param pszBaseDir The base directory. 225 * @param pszCertDir The certificat directory. 226 * @param pszTarball The tarball name. 227 * @param hTarballFile The handle to open the @a pszTarball file. 228 * @param hTarballFileOpt The tarball file handle (optional). 229 * @param pszName The extension pack name. 230 */ 231 static RTEXITCODE DoInstall2(const char *pszBaseDir, const char *pszCertDir, const char *pszTarball, 232 RTFILE hTarballFile, RTFILE hTarballFileOpt, const char *pszName) 233 { 234 /* 235 * Do some basic validation of the tarball file. 236 */ 237 RTFSOBJINFO ObjInfo; 238 int rc = RTFileQueryInfo(hTarballFile, &ObjInfo, RTFSOBJATTRADD_UNIX); 239 if (RT_FAILURE(rc)) 240 return RTMsgErrorExit(RTEXITCODE_FAILURE, "RTFileQueryInfo failed with %Rrc on '%s'", rc, pszTarball); 241 if (!RTFS_IS_FILE(ObjInfo.Attr.fMode)) 242 return RTMsgErrorExit(RTEXITCODE_FAILURE, "Not a regular file: %s", pszTarball); 243 244 if (hTarballFileOpt != NIL_RTFILE) 245 { 246 RTFSOBJINFO ObjInfo2; 247 rc = RTFileQueryInfo(hTarballFileOpt, &ObjInfo2, RTFSOBJATTRADD_UNIX); 248 if (RT_FAILURE(rc)) 249 return RTMsgErrorExit(RTEXITCODE_FAILURE, "RTFileQueryInfo failed with %Rrc on --tarball-fd", rc); 250 if ( ObjInfo.Attr.u.Unix.INodeIdDevice != ObjInfo2.Attr.u.Unix.INodeIdDevice 251 || ObjInfo.Attr.u.Unix.INodeId != ObjInfo2.Attr.u.Unix.INodeId) 252 return RTMsgErrorExit(RTEXITCODE_FAILURE, "--tarball and --tarball-fd does not match"); 253 } 254 255 /* 256 * Construct the paths to the two directories we'll be using. 257 */ 258 char szFinalPath[RTPATH_MAX]; 259 rc = RTPathJoin(szFinalPath, sizeof(szFinalPath), pszBaseDir, pszName); 260 if (RT_FAILURE(rc)) 261 return RTMsgErrorExit(RTEXITCODE_FAILURE, 262 "Failed to construct the path to the final extension pack directory: %Rrc", rc); 263 264 char szTmpPath[RTPATH_MAX]; 265 rc = RTPathJoin(szTmpPath, sizeof(szTmpPath) - 64, pszBaseDir, pszName); 266 if (RT_SUCCESS(rc)) 267 { 268 size_t cchTmpPath = strlen(szTmpPath); 269 RTStrPrintf(&szTmpPath[cchTmpPath], sizeof(szTmpPath) - cchTmpPath, "-_-inst-%u", (uint32_t)RTProcSelf()); 270 } 271 if (RT_FAILURE(rc)) 272 return RTMsgErrorExit(RTEXITCODE_FAILURE, 273 "Failed to construct the path to the temporary extension pack directory: %Rrc", rc); 274 275 /* 276 * Check that they don't exist at this point in time. 277 */ 278 rc = RTPathQueryInfoEx(szFinalPath, &ObjInfo, RTFSOBJATTRADD_NOTHING, RTPATH_F_ON_LINK); 279 if (RT_SUCCESS(rc) && RTFS_IS_DIRECTORY(ObjInfo.Attr.fMode)) 280 return RTMsgErrorExit(RTEXITCODE_FAILURE, "The extension pack is already installed. You must uninstall the old one first."); 281 if (RT_SUCCESS(rc)) 282 return RTMsgErrorExit(RTEXITCODE_FAILURE, 283 "Found non-directory file system object where the extension pack would be installed ('%s')", 284 szFinalPath); 285 if (rc != VERR_FILE_NOT_FOUND && rc != VERR_PATH_NOT_FOUND) 286 return RTMsgErrorExit(RTEXITCODE_FAILURE, "Unexpected RTPathQueryInfoEx status code %Rrc for '%s'", rc, szFinalPath); 287 288 rc = RTPathQueryInfoEx(szTmpPath, &ObjInfo, RTFSOBJATTRADD_NOTHING, RTPATH_F_ON_LINK); 289 if (rc != VERR_FILE_NOT_FOUND && rc != VERR_PATH_NOT_FOUND) 290 return RTMsgErrorExit(RTEXITCODE_FAILURE, "Unexpected RTPathQueryInfoEx status code %Rrc for '%s'", rc, szFinalPath); 291 292 /* 293 * Create the temporary directory and prepare the extension pack within it. 294 * If all checks out correctly, rename it to the final directory. 295 */ 296 rc = RTDirCreate(szTmpPath, 0700); 297 if (RT_FAILURE(rc)) 298 return RTMsgErrorExit(RTEXITCODE_FAILURE, "Failed to create temporary directory: %Rrc ('%s')", rc, szTmpPath); 299 300 RTEXITCODE rcExit = UnpackExtPack(hTarballFile, szTmpPath, pszTarball); 301 if (rcExit == RTEXITCODE_SUCCESS) 302 rcExit = ValidateExtPack(szTmpPath, pszTarball, pszName); 303 if (rcExit == RTEXITCODE_SUCCESS) 304 rcExit = SetExtPackPermissions(szTmpPath); 305 if (rcExit == RTEXITCODE_SUCCESS) 306 { 307 rc = RTDirRename(szTmpPath, szFinalPath, RTPATHRENAME_FLAGS_NO_REPLACE); 308 if (RT_SUCCESS(rc)) 309 RTMsgInfo("Successfully installed '%s' (%s)", pszName, pszTarball); 310 else 311 rcExit = RTMsgErrorExit(RTEXITCODE_FAILURE, 312 "Failed to rename the temporary directory to the final one: %Rrc ('%s' -> '%s')", 313 rc, szTmpPath, szFinalPath); 314 } 315 316 /* 317 * Clean up the temporary directory on failure. 318 */ 319 if (rcExit != RTEXITCODE_SUCCESS) 320 RemoveExtPackDir(szTmpPath, true /*fTemporary*/); 321 322 return rcExit; 42 323 } 43 324 … … 52 333 static RTEXITCODE DoInstall(int argc, char **argv) 53 334 { 54 return RTEXITCODE_FAILURE; 55 } 335 /* 336 * Parse the parameters. 337 * 338 * Note! The --base-dir and --cert-dir are only for checking that the 339 * caller and this help applications have the same idea of where 340 * things are. Likewise, the --name is for verifying assumptions 341 * the caller made about the name. The optional --tarball-fd option 342 * is just for easing the paranoia on the user side. 343 */ 344 static const RTGETOPTDEF s_aOptions[] = 345 { 346 { "--base-dir", 'b', RTGETOPT_REQ_STRING }, 347 { "--cert-dir", 'c', RTGETOPT_REQ_STRING }, 348 { "--name", 'n', RTGETOPT_REQ_STRING }, 349 { "--tarball", 't', RTGETOPT_REQ_STRING }, 350 { "--tarball-fd", 'f', RTGETOPT_REQ_UINT64 } 351 }; 352 RTGETOPTSTATE GetState; 353 int rc = RTGetOptInit(&GetState, argc, argv, s_aOptions, RT_ELEMENTS(s_aOptions), 1, 0 /*fFlags*/); 354 if (RT_FAILURE(rc)) 355 return RTMsgErrorExit(RTEXITCODE_FAILURE, "RTGetOptInit failed: %Rrc\n", rc); 356 357 const char *pszBaseDir = NULL; 358 const char *pszCertDir = NULL; 359 const char *pszName = NULL; 360 const char *pszTarball = NULL; 361 RTFILE hTarballFileOpt = NIL_RTFILE; 362 RTGETOPTUNION ValueUnion; 363 int ch; 364 while ((ch = RTGetOpt(&GetState, &ValueUnion))) 365 { 366 switch (ch) 367 { 368 case 'b': 369 if (pszBaseDir) 370 return RTMsgErrorExit(RTEXITCODE_SYNTAX, "Too many --base-dir options"); 371 pszBaseDir = ValueUnion.psz; 372 if (!IsValidBaseDir(pszBaseDir)) 373 return RTMsgErrorExit(RTEXITCODE_FAILURE, "Invalid base directory: '%s'", pszBaseDir); 374 break; 375 376 case 'c': 377 if (pszCertDir) 378 return RTMsgErrorExit(RTEXITCODE_SYNTAX, "Too many --cert-dir options"); 379 pszCertDir = ValueUnion.psz; 380 if (!IsValidCertificateDir(pszCertDir)) 381 return RTMsgErrorExit(RTEXITCODE_FAILURE, "Invalid certificate directory: '%s'", pszCertDir); 382 break; 383 384 case 'n': 385 if (pszName) 386 return RTMsgErrorExit(RTEXITCODE_SYNTAX, "Too many --name options"); 387 pszName = ValueUnion.psz; 388 if (!VBoxExtPackIsValidName(pszName)) 389 return RTMsgErrorExit(RTEXITCODE_FAILURE, "Invalid extension pack name: '%s'", pszName); 390 break; 391 392 case 't': 393 if (pszTarball) 394 return RTMsgErrorExit(RTEXITCODE_SYNTAX, "Too many --tarball options"); 395 pszTarball = ValueUnion.psz; 396 break; 397 398 case 'd': 399 { 400 if (hTarballFileOpt != NIL_RTFILE) 401 return RTMsgErrorExit(RTEXITCODE_SYNTAX, "Too many --tarball-fd options"); 402 RTHCUINTPTR hNative = (RTHCUINTPTR)ValueUnion.u64; 403 if (hNative != ValueUnion.u64) 404 return RTMsgErrorExit(RTEXITCODE_SYNTAX, "The --tarball-fd value is out of range: %#RX64", ValueUnion.u64); 405 rc = RTFileFromNative(&hTarballFileOpt, hNative); 406 if (RT_FAILURE(rc)) 407 return RTMsgErrorExit(RTEXITCODE_SYNTAX, "RTFileFromNative failed on --target-fd value: %Rrc", rc); 408 break; 409 } 410 411 case 'h': 412 case 'V': 413 return DoStandardOption(ch); 414 415 default: 416 return RTGetOptPrintError(ch, &ValueUnion); 417 } 418 break; 419 } 420 if (!pszName) 421 return RTMsgErrorExit(RTEXITCODE_SYNTAX, "Missing --name option"); 422 if (!pszBaseDir) 423 return RTMsgErrorExit(RTEXITCODE_SYNTAX, "Missing --base-dir option"); 424 if (!pszCertDir) 425 return RTMsgErrorExit(RTEXITCODE_SYNTAX, "Missing --cert-dir option"); 426 if (!pszTarball) 427 return RTMsgErrorExit(RTEXITCODE_SYNTAX, "Missing --tarball option"); 428 429 /* 430 * Ok, down to business. 431 */ 432 RTFILE hTarballFile; 433 rc = RTFileOpen(&hTarballFile, pszTarball, RTFILE_O_READ | RTFILE_O_OPEN | RTFILE_O_DENY_WRITE); 434 if (RT_FAILURE(rc)) 435 return RTMsgErrorExit(RTEXITCODE_FAILURE, "Failed to open the extension pack tarball: %Rrc ('%s')", rc, pszTarball); 436 437 RTEXITCODE rcExit = DoInstall2(pszBaseDir, pszCertDir, pszTarball, hTarballFile, hTarballFileOpt, pszName); 438 RTFileClose(hTarballFile); 439 return rcExit; 440 } 441 56 442 57 443 /** … … 64 450 static RTEXITCODE DoUninstall(int argc, char **argv) 65 451 { 66 return RTEXITCODE_FAILURE; 67 } 68 69 70 int main(int argc, char **argv) 71 { 72 int rc = RTR3Init(); 73 if (RT_FAILURE(rc)) 74 return RTMsgInitFailure(rc); 75 76 RTEXITCODE rcExit = RTEXITCODE_FAILURE; 77 if (argc > 1) 78 { 79 /* 80 * Command string switch. 81 */ 82 if (!strcmp(argv[1], "install")) 83 rcExit = DoInstall(argc, argv); 84 else if (!strcmp(argv[1], "uninstall")) 85 rcExit = DoUninstall(argc, argv); 86 else 452 /* 453 * Parse the parameters. 454 * 455 * Note! The --base-dir is only for checking that the caller and this help 456 * applications have the same idea of where things are. 457 */ 458 static const RTGETOPTDEF s_aOptions[] = 459 { 460 { "--base-dir", 'b', RTGETOPT_REQ_STRING }, 461 { "--name", 'n', RTGETOPT_REQ_STRING } 462 }; 463 RTGETOPTSTATE GetState; 464 int rc = RTGetOptInit(&GetState, argc, argv, s_aOptions, RT_ELEMENTS(s_aOptions), 1, 0 /*fFlags*/); 465 if (RT_FAILURE(rc)) 466 return RTMsgErrorExit(RTEXITCODE_FAILURE, "RTGetOptInit failed: %Rrc\n", rc); 467 468 const char *pszBaseDir = NULL; 469 const char *pszName = NULL; 470 RTGETOPTUNION ValueUnion; 471 int ch; 472 while ((ch = RTGetOpt(&GetState, &ValueUnion))) 473 { 474 switch (ch) 87 475 { 88 /* 89 * Didn't match a command, check for standard options. 90 */ 91 RTGETOPTSTATE State; 92 rc = RTGetOptInit(&State, argc, argv, NULL, 0, 1, 0 /*fFlags*/); 476 case 'b': 477 if (pszBaseDir) 478 return RTMsgErrorExit(RTEXITCODE_SYNTAX, "Too many --base-dir options"); 479 pszBaseDir = ValueUnion.psz; 480 if (!IsValidBaseDir(pszBaseDir)) 481 return RTMsgErrorExit(RTEXITCODE_FAILURE, "Invalid base directory: '%s'", pszBaseDir); 482 break; 483 484 case 'n': 485 if (pszName) 486 return RTMsgErrorExit(RTEXITCODE_SYNTAX, "Too many --name options"); 487 pszName = ValueUnion.psz; 488 if (!VBoxExtPackIsValidName(pszName)) 489 return RTMsgErrorExit(RTEXITCODE_FAILURE, "Invalid extension pack name: '%s'", pszName); 490 break; 491 492 case 'h': 493 case 'V': 494 return DoStandardOption(ch); 495 496 default: 497 return RTGetOptPrintError(ch, &ValueUnion); 498 } 499 break; 500 } 501 if (!pszName) 502 return RTMsgErrorExit(RTEXITCODE_SYNTAX, "Missing --name option"); 503 if (!pszBaseDir) 504 return RTMsgErrorExit(RTEXITCODE_SYNTAX, "Missing --base-dir option"); 505 506 /* 507 * Ok, down to business. 508 */ 509 /* Check that it exists. */ 510 char szExtPackDir[RTPATH_MAX]; 511 rc = RTPathJoin(szExtPackDir, sizeof(szExtPackDir), pszBaseDir, pszName); 512 if (RT_FAILURE(rc)) 513 return RTMsgErrorExit(RTEXITCODE_FAILURE, "Failed to construct extension pack path: %Rrc", rc); 514 515 if (!RTDirExists(szExtPackDir)) 516 { 517 RTMsgInfo("Extension pack not installed. Nothing to do."); 518 return RTEXITCODE_SUCCESS; 519 } 520 521 /* Rename the extension pack directory before deleting it to prevent new 522 VM processes from picking it up. */ 523 char szExtPackUnInstDir[RTPATH_MAX]; 524 rc = RTPathJoin(szExtPackUnInstDir, sizeof(szExtPackUnInstDir), pszBaseDir, pszName); 525 if (RT_SUCCESS(rc)) 526 rc = RTStrCat(szExtPackUnInstDir, sizeof(szExtPackUnInstDir), "-_-uninst"); 527 if (RT_FAILURE(rc)) 528 return RTMsgErrorExit(RTEXITCODE_FAILURE, "Failed to construct temporary extension pack path: %Rrc", rc); 529 530 rc = RTDirRename(szExtPackDir, szExtPackUnInstDir, RTPATHRENAME_FLAGS_NO_REPLACE); 531 if (RT_FAILURE(rc)) 532 return RTMsgErrorExit(RTEXITCODE_FAILURE, "Failed to rename the extension pack directory: %Rrc", rc); 533 534 /* Recursively delete the directory content. */ 535 RTEXITCODE rcExit = RemoveExtPackDir(szExtPackUnInstDir, false /*fTemporary*/); 536 if (rcExit == RTEXITCODE_SUCCESS) 537 RTMsgInfo("Successfully removed extension pack '%s'\n", pszName); 538 539 return rcExit; 540 } 541 542 /** 543 * Implements the 'cleanup' command. 544 * 545 * @returns The program exit code. 546 * @param argc The number of program arguments. 547 * @param argv The program arguments. 548 */ 549 static RTEXITCODE DoCleanup(int argc, char **argv) 550 { 551 /* 552 * Parse the parameters. 553 * 554 * Note! The --base-dir is only for checking that the caller and this help 555 * applications have the same idea of where things are. 556 */ 557 static const RTGETOPTDEF s_aOptions[] = 558 { 559 { "--base-dir", 'b', RTGETOPT_REQ_STRING }, 560 }; 561 RTGETOPTSTATE GetState; 562 int rc = RTGetOptInit(&GetState, argc, argv, s_aOptions, RT_ELEMENTS(s_aOptions), 1, 0 /*fFlags*/); 563 if (RT_FAILURE(rc)) 564 return RTMsgErrorExit(RTEXITCODE_FAILURE, "RTGetOptInit failed: %Rrc\n", rc); 565 566 const char *pszBaseDir = NULL; 567 RTGETOPTUNION ValueUnion; 568 int ch; 569 while ((ch = RTGetOpt(&GetState, &ValueUnion))) 570 { 571 switch (ch) 572 { 573 case 'b': 574 if (pszBaseDir) 575 return RTMsgErrorExit(RTEXITCODE_SYNTAX, "Too many --base-dir options"); 576 pszBaseDir = ValueUnion.psz; 577 if (!IsValidBaseDir(pszBaseDir)) 578 return RTMsgErrorExit(RTEXITCODE_FAILURE, "Invalid base directory: '%s'", pszBaseDir); 579 break; 580 581 case 'h': 582 case 'V': 583 return DoStandardOption(ch); 584 585 default: 586 return RTGetOptPrintError(ch, &ValueUnion); 587 } 588 break; 589 } 590 if (!pszBaseDir) 591 return RTMsgErrorExit(RTEXITCODE_SYNTAX, "Missing --base-dir option"); 592 593 /* 594 * Ok, down to business. 595 */ 596 PRTDIR pDir; 597 rc = RTDirOpen(&pDir, pszBaseDir); 598 if (RT_FAILURE(rc)) 599 return RTMsgErrorExit(RTEXITCODE_FAILURE, "Failed open the base directory: %Rrc ('%s')", rc, pszBaseDir); 600 601 uint32_t cCleaned = 0; 602 RTEXITCODE rcExit = RTEXITCODE_SUCCESS; 603 for (;;) 604 { 605 RTDIRENTRYEX Entry; 606 rc = RTDirReadEx(pDir, &Entry, NULL /*pcbDirEntry*/, RTFSOBJATTRADD_NOTHING, RTPATH_F_ON_LINK); 607 if (RT_FAILURE(rc)) 608 { 609 if (rc != VERR_NO_MORE_FILES) 610 rcExit = RTMsgErrorExit(RTEXITCODE_FAILURE, "RTDirReadEx returns %Rrc", rc); 611 break; 612 } 613 if ( RTFS_IS_DIRECTORY(Entry.Info.Attr.fMode) 614 && strcmp(Entry.szName, ".") != 0 615 && strcmp(Entry.szName, "..") != 0 616 && !VBoxExtPackIsValidName(Entry.szName) ) 617 { 618 char szPath[RTPATH_MAX]; 619 rc = RTPathJoin(szPath, sizeof(szPath), pszBaseDir, Entry.szName); 93 620 if (RT_SUCCESS(rc)) 94 621 { 95 for (;;) 96 { 97 RTGETOPTUNION ValueUnion; 98 int ch = RTGetOpt(&State, &ValueUnion); 99 switch (ch) 100 { 101 case 'h': 102 RTMsgInfo(VBOX_PRODUCT " Extension Pack Helper App\n" 103 "(C) " VBOX_C_YEAR " " VBOX_VENDOR "\n" 104 "All rights reserved.\n" 105 "\n" 106 "This NOT intended for general use, please use VBoxManage instead\n" 107 "or call the IExtPackManager API directly.\n" 108 "\n" 109 "Usage: %s <command> [options]\n" 110 "Commands:\n" 111 " install --base-dir <dir> --name <name> --tarball <tarball> --tarball-fd <fd>\n" 112 " uninstall --base-dir <dir> --name <name>\n" 113 , RTPathFilename(argv[0])); 114 rcExit = RTEXITCODE_SUCCESS; 115 break; 116 117 case 'V': 118 RTPrintf("%sr%d\n", VBOX_VERSION_STRING, RTBldCfgRevision()); 119 rcExit = RTEXITCODE_SUCCESS; 120 break; 121 122 default: 123 rcExit = RTGetOptPrintError(ch, &ValueUnion); 124 break; 125 } 126 } 622 RTEXITCODE rcExit2 = RemoveExtPackDir(szPath, true /*fTemporary*/); 623 if (rcExit2 == RTEXITCODE_SUCCESS) 624 RTMsgInfo("Successfully removed '%s'.", Entry.szName); 625 else if (rcExit == RTEXITCODE_SUCCESS) 626 rcExit = rcExit2; 127 627 } 128 628 else 129 RTMsgError("RTGetOptInit failed: %Rrc\n", rc); 629 rcExit = RTMsgErrorExit(RTEXITCODE_FAILURE, "RTPathJoin failed with %Rrc for '%s'", rc, Entry.szName); 630 cCleaned++; 130 631 } 131 632 } 132 else 133 RTMsgError("No command was specified\n"); 633 RTDirClose(pDir); 634 if (!cCleaned) 635 RTMsgInfo("Nothing to clean."); 134 636 return rcExit; 135 637 } 136 638 639 640 641 int main(int argc, char **argv) 642 { 643 /* 644 * Initialize IPRT and check that we're correctly installed. 645 */ 646 int rc = RTR3Init(); 647 if (RT_FAILURE(rc)) 648 return RTMsgInitFailure(rc); 649 650 char szErr[2048]; 651 rc = SUPR3HardenedVerifySelf(argv[0], true /*fInternal*/, szErr, sizeof(szErr)); 652 if (RT_FAILURE(rc)) 653 return RTMsgErrorExit(RTEXITCODE_FAILURE, "%s", szErr); 654 655 /* 656 * Parse the top level arguments until we find a command. 657 */ 658 static const RTGETOPTDEF s_aOptions[] = 659 { 660 #define CMD_INSTALL 1000 661 { "install", CMD_INSTALL, RTGETOPT_REQ_NOTHING }, 662 #define CMD_UNINSTALL 1001 663 { "uninstall", CMD_UNINSTALL, RTGETOPT_REQ_NOTHING }, 664 #define CMD_CLEANUP 1002 665 { "cleanup", CMD_CLEANUP, RTGETOPT_REQ_NOTHING }, 666 }; 667 RTGETOPTSTATE GetState; 668 rc = RTGetOptInit(&GetState, argc, argv, s_aOptions, RT_ELEMENTS(s_aOptions), 1, 0 /*fFlags*/); 669 if (RT_FAILURE(rc)) 670 return RTMsgErrorExit(RTEXITCODE_FAILURE, "RTGetOptInit failed: %Rrc\n", rc); 671 for (;;) 672 { 673 RTGETOPTUNION ValueUnion; 674 int ch = RTGetOpt(&GetState, &ValueUnion); 675 switch (ch) 676 { 677 case 0: 678 return RTMsgErrorExit(RTEXITCODE_SYNTAX, "No command specified"); 679 680 case CMD_INSTALL: 681 return DoInstall(argc, argv); 682 683 case CMD_UNINSTALL: 684 return DoUninstall(argc, argv); 685 686 case CMD_CLEANUP: 687 return DoCleanup(argc, argv); 688 689 case 'h': 690 case 'V': 691 return DoStandardOption(ch); 692 693 default: 694 return RTGetOptPrintError(ch, &ValueUnion); 695 } 696 /* not currently reached */ 697 } 698 /* not reached */ 699 } 700 -
trunk/src/VBox/Main/VirtualBoxImpl.cpp
r33784 r33806 2062 2062 /* get the path to the executable */ 2063 2063 char exePathBuf[RTPATH_MAX]; 2064 char *exePath = RTProcGetExecutable Name(exePathBuf, RTPATH_MAX);2064 char *exePath = RTProcGetExecutablePath(exePathBuf, RTPATH_MAX); 2065 2065 if (!exePath) 2066 2066 { -
trunk/src/VBox/Main/generic/OpenGLTestApp.cpp
r28800 r33806 166 166 /* the package type is interesting for Linux distributions */ 167 167 char szExecName[RTPATH_MAX]; 168 char *pszExecName = RTProcGetExecutable Name(szExecName, sizeof(szExecName));168 char *pszExecName = RTProcGetExecutablePath(szExecName, sizeof(szExecName)); 169 169 RTLogRelLogger(loggerRelease, 0, ~0U, 170 170 "Executable: %s\n" -
trunk/src/VBox/Main/include/ExtPackUtil.h
r33693 r33806 24 24 * The suffix of a extension pack tarball. */ 25 25 #define VBOX_EXTPACK_SUFFIX ".vbox-extpack" 26 27 /** The minimum length (strlen) of a extension pack name. */ 28 #define VBOX_EXTPACK_NAME_MIN_LEN 6 29 /** The max length (strlen) of a extension pack name. */ 30 #define VBOX_EXTPACK_NAME_MAX_LEN 64 31 32 /** The architecture-dependent application data subdirectory where the 33 * extension packs are installed. Relative to RTPathAppPrivateArch. */ 34 #define VBOX_EXTPACK_INSTALL_DIR "ExtensionPacks" 35 /** The architecture-independent application data subdirectory where the 36 * certificates are installed. Relative to RTPathAppPrivateNoArch. */ 37 #define VBOX_EXTPACK_CERT_DIR "Certificates" 26 38 27 39 … … 52 64 53 65 iprt::MiniString *VBoxExtPackLoadDesc(const char *a_pszDir, PVBOXEXTPACKDESC a_pExtPackDesc, PRTFSOBJINFO a_pObjInfo); 66 iprt::MiniString *VBoxExtPackExtractNameFromTarballPath(const char *pszTarball); 54 67 bool VBoxExtPackIsValidName(const char *pszName); 55 68 bool VBoxExtPackIsValidVersionString(const char *pszName); -
trunk/src/VBox/Runtime/VBox/RTAssertShouldPanic-vbox.cpp
r28800 r33806 116 116 { 117 117 char *pszExecName = &szCmd[cch]; 118 if (!RTProcGetExecutable Name(pszExecName, sizeof(szCmd) - cch))118 if (!RTProcGetExecutablePath(pszExecName, sizeof(szCmd) - cch)) 119 119 *pszExecName = '\0'; 120 120 } -
trunk/src/VBox/Runtime/VBox/log-vbox.cpp
r33664 r33806 297 297 # ifndef IN_GUEST 298 298 char szExecName[RTPATH_MAX]; 299 if (!RTProcGetExecutable Name(szExecName, sizeof(szExecName)))299 if (!RTProcGetExecutablePath(szExecName, sizeof(szExecName))) 300 300 strcpy(szExecName, "VBox"); 301 301 RTTIMESPEC TimeSpec; -
trunk/src/VBox/Runtime/generic/RTProcDaemonize-generic.cpp
r28800 r33806 49 49 */ 50 50 char szExecPath[RTPATH_MAX]; 51 AssertReturn(RTProcGetExecutable Name(szExecPath, sizeof(szExecPath)) == szExecPath, VERR_WRONG_ORDER);51 AssertReturn(RTProcGetExecutablePath(szExecPath, sizeof(szExecPath)) == szExecPath, VERR_WRONG_ORDER); 52 52 53 53 /* -
trunk/src/VBox/Runtime/r3/init.cpp
r33595 r33806 80 80 81 81 /** The process path. 82 * This is used by RTPathExecDir and RTProcGetExecutable Nameand set by rtProcInitName. */82 * This is used by RTPathExecDir and RTProcGetExecutablePath and set by rtProcInitName. */ 83 83 char g_szrtProcExePath[RTPATH_MAX]; 84 84 /** The length of g_szrtProcExePath. */ -
trunk/src/VBox/Runtime/r3/process.cpp
r33454 r33806 92 92 93 93 94 RTR3DECL(char *) RTProcGetExecutable Name(char *pszExecName, size_t cchExecName)94 RTR3DECL(char *) RTProcGetExecutablePath(char *pszExecPath, size_t cbExecPath) 95 95 { 96 96 if (RT_UNLIKELY(g_szrtProcExePath[0] == '\0')) … … 101 101 */ 102 102 size_t cch = g_cchrtProcExePath; 103 if (cch < c chExecName)103 if (cch < cbExecPath) 104 104 { 105 memcpy(pszExec Name, g_szrtProcExePath, cch);106 pszExec Name[cch] = '\0';107 return pszExec Name;105 memcpy(pszExecPath, g_szrtProcExePath, cch); 106 pszExecPath[cch] = '\0'; 107 return pszExecPath; 108 108 } 109 109 110 AssertMsgFailed(("Buffer too small (%zu <= %zu)\n", c chExecName, cch));110 AssertMsgFailed(("Buffer too small (%zu <= %zu)\n", cbExecPath, cch)); 111 111 return NULL; 112 112 } 113 113 114 115 RTR3DECL(const char *) RTProcShortName(void) 116 { 117 return &g_szrtProcExePath[g_offrtProcName]; 118 } 119 -
trunk/src/VBox/Runtime/r3/solaris/coredumper-solaris.cpp
r33540 r33806 1956 1956 pVBoxProc->CoreContent = CC_CONTENT_DEFAULT; 1957 1957 1958 RTProcGetExecutable Name(pVBoxProc->szExecPath, sizeof(pVBoxProc->szExecPath)); /* this gets full path not just name */1958 RTProcGetExecutablePath(pVBoxProc->szExecPath, sizeof(pVBoxProc->szExecPath)); /* this gets full path not just name */ 1959 1959 pVBoxProc->pszExecName = RTPathFilename(pVBoxProc->szExecPath); 1960 1960 -
trunk/src/VBox/Runtime/testcase/tstRTDigest.cpp
r32568 r33806 48 48 { 49 49 char szName[RTPATH_MAX]; 50 if (!RTProcGetExecutable Name(szName, sizeof(szName)))50 if (!RTProcGetExecutablePath(szName, sizeof(szName))) 51 51 strcpy(szName, "tstRTDigest"); 52 52 -
trunk/src/VBox/Runtime/testcase/tstRTPath.cpp
r33450 r33806 53 53 54 54 /* 55 * RTPathExecDir, RTPathUserHome and RTProcGetExecutable Name.55 * RTPathExecDir, RTPathUserHome and RTProcGetExecutablePath. 56 56 */ 57 57 RTTestSub(hTest, "RTPathExecDir"); … … 60 60 RTTestIPrintf(RTTESTLVL_INFO, "ExecDir={%s}\n", szPath); 61 61 62 RTTestSub(hTest, "RTProcGetExecutable Name");63 if (RTProcGetExecutable Name(szPath, sizeof(szPath)) == szPath)62 RTTestSub(hTest, "RTProcGetExecutablePath"); 63 if (RTProcGetExecutablePath(szPath, sizeof(szPath)) == szPath) 64 64 RTTestIPrintf(RTTESTLVL_INFO, "ExecutableName={%s}\n", szPath); 65 65 else 66 RTTestIFailed("RTProcGetExecutable Name-> NULL");66 RTTestIFailed("RTProcGetExecutablePath -> NULL"); 67 67 68 68 RTTestSub(hTest, "RTPathUserHome"); -
trunk/src/VBox/Runtime/testcase/tstRTPipe.cpp
r28800 r33806 94 94 95 95 char szPathSelf[RTPATH_MAX]; 96 RTTESTI_CHECK_RETV(RTProcGetExecutable Name(szPathSelf, sizeof(szPathSelf)) == szPathSelf);96 RTTESTI_CHECK_RETV(RTProcGetExecutablePath(szPathSelf, sizeof(szPathSelf)) == szPathSelf); 97 97 98 98 RTPIPE hPipeR; … … 157 157 158 158 char szPathSelf[RTPATH_MAX]; 159 RTTESTI_CHECK_RETV(RTProcGetExecutable Name(szPathSelf, sizeof(szPathSelf)) == szPathSelf);159 RTTESTI_CHECK_RETV(RTProcGetExecutablePath(szPathSelf, sizeof(szPathSelf)) == szPathSelf); 160 160 161 161 RTPIPE hPipeR; -
trunk/src/VBox/Runtime/testcase/tstRTProcCreateEx.cpp
r30093 r33806 436 436 RTTestBanner(hTest); 437 437 438 if (!RTProcGetExecutable Name(g_szExecName, sizeof(g_szExecName)))438 if (!RTProcGetExecutablePath(g_szExecName, sizeof(g_szExecName))) 439 439 RTStrCopy(g_szExecName, sizeof(g_szExecName), argv[0]); 440 440 -
trunk/src/VBox/Runtime/testcase/tstRTProcIsRunningByName.cpp
r28800 r33806 72 72 * Test 3: Check for our own process, filename only. 73 73 */ 74 if (RTProcGetExecutable Name(szExecPath, RTPATH_MAX))74 if (RTProcGetExecutablePath(szExecPath, RTPATH_MAX)) 75 75 { 76 76 /* Strip any path components */ … … 105 105 else 106 106 { 107 RTPrintf("tstRTProcIsRunningByName: FAILURE - RTProcGetExecutable Namefailed!\n");107 RTPrintf("tstRTProcIsRunningByName: FAILURE - RTProcGetExecutablePath failed!\n"); 108 108 cErrors++; 109 109 } -
trunk/src/VBox/Runtime/testcase/tstRTSymlink.cpp
r33426 r33806 129 129 130 130 char szExecFile[RTPATH_MAX]; 131 RTTESTI_CHECK_RETV(RTProcGetExecutable Name(szExecFile, sizeof(szExecFile)) != NULL);131 RTTESTI_CHECK_RETV(RTProcGetExecutablePath(szExecFile, sizeof(szExecFile)) != NULL); 132 132 size_t cchExecFile = strlen(szExecFile); 133 133 RTTESTI_CHECK(RTFileExists(szExecFile));
Note:
See TracChangeset
for help on using the changeset viewer.