- Timestamp:
- Aug 9, 2012 2:36:02 PM (12 years ago)
- Location:
- trunk
- Files:
-
- 5 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/include/iprt/dir.h
r42708 r42712 98 98 */ 99 99 RTDECL(int) RTDirCreateTemp(char *pszTemplate, RTFMODE fMode); 100 101 /** 102 * Secure version of @a RTDirCreateTemp with a fixed mode of 0700. 103 * 104 * This function behaves in the same way as @a RTDirCreateTemp with two 105 * additional points. Firstly the mode is fixed to 0700. Secondly it will 106 * fail if it is not possible to perform the operation securely. Possible 107 * reasons include that the directory could be removed by another unprivileged 108 * user before it is used (e.g. if is created in a non-sticky /tmp directory) 109 * or that the path contains symbolic links which another unprivileged user 110 * could manipulate; however the exact criteria will be specified on a 111 * platform-by-platform basis as platform support is added. 112 * @see RTPathIsSecure for the current list of criteria. 113 * @returns iprt status code. 114 * @returns VERR_NOT_SUPPORTED if the interface can not be supported on the 115 * current platform at this time. 116 * @returns VERR_INSECURE if the directory could not be created securely. 117 * @param pszTemplate The directory name template on input. The 118 * actual directory name on success. Empty string 119 * on failure. 120 */ 121 RTDECL(int) RTDirCreateTempSecure(char *pszTemplate); 100 122 101 123 /** -
trunk/include/iprt/file.h
r39641 r42712 587 587 588 588 589 /** 590 * Creates a new file with a unique name using the given template. 591 * 592 * One or more trailing X'es in the template will be replaced by random alpha 593 * numeric characters until a RTFileOpen with RTFILE_O_CREATE succeeds or we 594 * run out of patience. 595 * For instance: 596 * "/tmp/myprog-XXXXXX" 597 * 598 * As an alternative to trailing X'es, it is possible to put 3 or more X'es 599 * somewhere inside the file name. In the following string only the last 600 * bunch of X'es will be modified: 601 * "/tmp/myprog-XXX-XXX.tmp" 602 * 603 * @returns iprt status code. 604 * @param pszTemplate The file name template on input. The actual file 605 * name on success. Empty string on failure. 606 * @param fMode The mode to create the file with. Use 0600 unless 607 * you have reason not to. 608 */ 609 RTDECL(int) RTFileCreateTemp(char *pszTemplate, RTFMODE fMode); 610 611 /** 612 * Secure version of @a RTFileCreateTemp with a fixed mode of 0600. 613 * 614 * This function behaves in the same way as @a RTFileCreateTemp with two 615 * additional points. Firstly the mode is fixed to 0600. Secondly it will 616 * fail if it is not possible to perform the operation securely. Possible 617 * reasons include that the file could be removed by another unprivileged 618 * user before it is used (e.g. if is created in a non-sticky /tmp directory) 619 * or that the path contains symbolic links which another unprivileged user 620 * could manipulate; however the exact criteria will be specified on a 621 * platform-by-platform basis as platform support is added. 622 * @see RTPathIsSecure for the current list of criteria. 623 * @returns iprt status code. 624 * @returns VERR_NOT_SUPPORTED if the interface can not be supported on the 625 * current platform at this time. 626 * @returns VERR_INSECURE if the file could not be created securely. 627 * @param pszTemplate The file name template on input. The actual 628 * file name on success. Empty string on failure. 629 */ 630 RTDECL(int) RTFileCreateTempSecure(char *pszTemplate); 631 632 589 633 /** @page pg_rt_filelock RT File locking API description 590 634 * -
trunk/include/iprt/mangling.h
r42067 r42712 390 390 # define RTDirCreateFullPath RT_MANGLER(RTDirCreateFullPath) 391 391 # define RTDirCreateTemp RT_MANGLER(RTDirCreateTemp) 392 # define RTDirCreateTempSecure RT_MANGLER(RTDirCreateTempSecure) 392 393 # define RTDirCreateUniqueNumbered RT_MANGLER(RTDirCreateUniqueNumbered) 393 394 # define RTDirExists RT_MANGLER(RTDirExists) … … 478 479 # define RTFileCopyByHandlesEx RT_MANGLER(RTFileCopyByHandlesEx) 479 480 # define RTFileCopyEx RT_MANGLER(RTFileCopyEx) 481 # define RTFileCreateTemp RT_MANGLER(RTFileCreateTemp) 482 # define RTFileCreateTempSecure RT_MANGLER(RTFileCreateTempSecure) 480 483 # define RTFileDelete RT_MANGLER(RTFileDelete) 481 484 # define RTFileExists RT_MANGLER(RTFileExists) -
trunk/src/VBox/Runtime/generic/createtemp-generic.cpp
r42709 r42712 1 1 /* $Id$ */ 2 2 /** @file 3 * IPRT - RTDirCreateTemp, generic implementation.3 * IPRT - temporary file and directory creation, generic implementation. 4 4 */ 5 5 6 6 /* 7 * Copyright (C) 2009 Oracle Corporation7 * Copyright (C) 2009-2012 Oracle Corporation 8 8 * 9 9 * This file is part of VirtualBox Open Source Edition (OSE), as … … 34 34 #include <iprt/assert.h> 35 35 #include <iprt/err.h> 36 #include <iprt/file.h> 36 37 #include <iprt/path.h> 37 38 #include <iprt/rand.h> … … 108 109 RTDECL(int) RTDirCreateTemp(char *pszTemplate, RTFMODE fMode) 109 110 { 110 char *pszX = NULL; /* Initialise to make gcc happy. */111 char *pszX = NULL; 111 112 unsigned cXes = 0; 112 113 int rc = rtCreateTempValidateTemplate(pszTemplate, &pszX, &cXes); … … 139 140 RT_EXPORT_SYMBOL(RTDirCreateTemp); 140 141 142 143 /** @todo Test case for this once it is implemented. */ 144 RTDECL(int) RTDirCreateTempSecure(char *pszTemplate) 145 { 146 size_t cchDir; 147 char chOld; 148 int rc; 149 /* bool fSafe; */ 150 151 /* Temporarily convert pszTemplate to a path. */ 152 RTPathParse(pszTemplate, &cchDir, NULL, NULL); 153 chOld = pszTemplate[cchDir]; 154 pszTemplate[cchDir] = '\0'; 155 /** @todo Implement this. */ 156 rc = /* RTPathIsSecure(pszTemplate, &fSafe) */ VERR_NOT_SUPPORTED; 157 pszTemplate[cchDir] = chOld; 158 if (RT_SUCCESS(rc) /* && fSafe */) 159 return RTDirCreateTemp(pszTemplate, 0700); 160 else 161 { 162 *pszTemplate = '\0'; 163 /** @todo Replace VERR_PERMISSION_DENIED. VERR_INSECURE? */ 164 return RT_FAILURE(rc) ? rc : VERR_PERMISSION_DENIED; 165 } 166 } 167 RT_EXPORT_SYMBOL(RTDirCreateTempSecure); 168 169 170 RTDECL(int) RTFileCreateTemp(char *pszTemplate, RTFMODE fMode) 171 { 172 char *pszX = NULL; 173 unsigned cXes = 0; 174 RTFILE hFile; 175 int rc = rtCreateTempValidateTemplate(pszTemplate, &pszX, &cXes); 176 if (RT_FAILURE(rc)) 177 { 178 *pszTemplate = '\0'; 179 return rc; 180 } 181 /* 182 * Try ten thousand times. 183 */ 184 int i = 10000; 185 while (i-- > 0) 186 { 187 uint64_t fOpen = RTFILE_O_WRITE | RTFILE_O_DENY_ALL 188 | RTFILE_O_CREATE | RTFILE_O_NOT_CONTENT_INDEXED 189 | fMode << RTFILE_O_CREATE_MODE_SHIFT; 190 rtCreateTempFillTemplate(pszX, cXes); 191 rc = RTFileOpen(&hFile, pszTemplate, fOpen); 192 if (RT_SUCCESS(rc)) 193 { 194 RTFileClose(hFile); 195 return rc; 196 } 197 /** @todo Anything else to consider? */ 198 if (rc != VERR_ALREADY_EXISTS) 199 { 200 *pszTemplate = '\0'; 201 return rc; 202 } 203 } 204 205 /* we've given up. */ 206 *pszTemplate = '\0'; 207 return VERR_ALREADY_EXISTS; 208 } 209 RT_EXPORT_SYMBOL(RTFileCreateTemp); 210 211 212 /** @todo Test case for this once it is implemented. */ 213 RTDECL(int) RTFileCreateTempSecure(char *pszTemplate) 214 { 215 size_t cchDir; 216 char chOld; 217 int rc; 218 /* bool fSafe; */ 219 220 /* Temporarily convert pszTemplate to a path. */ 221 RTPathParse(pszTemplate, &cchDir, NULL, NULL); 222 chOld = pszTemplate[cchDir]; 223 pszTemplate[cchDir] = '\0'; 224 /** @todo Implement this. */ 225 rc = /* RTPathIsSecure(pszTemplate, &fSafe) */ VERR_NOT_SUPPORTED; 226 pszTemplate[cchDir] = chOld; 227 if (RT_SUCCESS(rc) /* && fSafe */) 228 return RTFileCreateTemp(pszTemplate, 0600); 229 else 230 { 231 *pszTemplate = '\0'; 232 /** @todo Replace VERR_PERMISSION_DENIED. VERR_INSECURE? */ 233 return RT_FAILURE(rc) ? rc : VERR_PERMISSION_DENIED; 234 } 235 } 236 RT_EXPORT_SYMBOL(RTFileCreateTempSecure); -
trunk/src/VBox/Runtime/testcase/tstRTTemp.cpp
r42708 r42712 48 48 49 49 50 static void tst DirCreateTemp(const char *pszSubTest, const char *pszTemplate, unsigned cTimes, bool fSkipXCheck)50 static void tstObjectCreateTemp(const char *pszSubTest, const char *pszTemplate, bool fFile, RTFMODE fMode, unsigned cTimes, bool fSkipXCheck) 51 51 { 52 52 RTTestISub(pszSubTest); 53 const char *pcszAPI = fFile ? "RTFileCreateTemp" : "RTDirCreateTemp"; 53 54 54 55 /* Allocate the result array. */ … … 62 63 int rc; 63 64 char szName[RTPATH_MAX]; 65 RTFMODE fModeFinal; 64 66 RTTESTI_CHECK_RC(rc = RTPathAppend(strcpy(szName, g_szTempPath), sizeof(szName), pszTemplate), VINF_SUCCESS); 65 67 if (RT_FAILURE(rc)) … … 70 72 break; 71 73 72 rc = RTDirCreateTemp(papszNames[i], 0700); 74 rc = fFile 75 ? RTFileCreateTemp(papszNames[i], fMode) 76 : RTDirCreateTemp(papszNames[i], fMode); 73 77 if (rc != VINF_SUCCESS) 74 78 { 75 RTTestIFailed(" RTDirCreateTemp(%s) call #%u -> %Rrc\n", szName, i, rc);79 RTTestIFailed("%s(%s, %#o) call #%u -> %Rrc\n", pcszAPI, szName, (int)fMode, i, rc); 76 80 RTStrFree(papszNames[i]); 77 81 papszNames[i] = NULL; 78 82 break; 79 83 } 80 RTTestIPrintf(RTTESTLVL_DEBUG, "%s\n", papszNames[i]); 81 RTTESTI_CHECK_MSG(strlen(szName) == strlen(papszNames[i]), ("szName %s\nReturned %s\n", szName, papszNames[i])); 84 RTTESTI_CHECK_RC_OK(rc = RTPathGetMode(papszNames[i], &fModeFinal)); 85 if (RT_SUCCESS(rc)) 86 { 87 fModeFinal &= (RTFS_UNIX_IRWXU | RTFS_UNIX_IRWXO); 88 RTTESTI_CHECK_MSG((fModeFinal & ~fMode) == 0, 89 ("%s: szName %s\nfModeFinal ~= %#o, expected %#o\n", 90 pcszAPI, szName, fModeFinal, (int)fMode)); 91 } 92 RTTestIPrintf(RTTESTLVL_DEBUG, "%s: %s\n", pcszAPI, papszNames[i]); 93 RTTESTI_CHECK_MSG(strlen(szName) == strlen(papszNames[i]), ("%s: szName %s\nReturned %s\n", pcszAPI, szName, papszNames[i])); 82 94 if (!fSkipXCheck) 83 RTTESTI_CHECK_MSG(strchr(RTPathFilename(papszNames[i]), 'X') == NULL, (" szName %s\nReturned %s\n", szName, papszNames[i]));95 RTTESTI_CHECK_MSG(strchr(RTPathFilename(papszNames[i]), 'X') == NULL, ("%s: szName %s\nReturned %s\n", pcszAPI, szName, papszNames[i])); 84 96 } 85 97 … … 87 99 while (i-- > 0) 88 100 { 89 RTTESTI_CHECK_RC(RTDirRemove(papszNames[i]), VINF_SUCCESS); 101 if (fFile) 102 RTTESTI_CHECK_RC(RTFileDelete(papszNames[i]), VINF_SUCCESS); 103 else 104 RTTESTI_CHECK_RC(RTDirRemove(papszNames[i]), VINF_SUCCESS); 90 105 RTStrFree(papszNames[i]); 91 106 } 92 107 RTMemTmpFree(papszNames); 108 } 109 110 111 static void tstFileCreateTemp(const char *pszSubTest, const char *pszTemplate, RTFMODE fMode, unsigned cTimes, bool fSkipXCheck) 112 { 113 tstObjectCreateTemp(pszSubTest, pszTemplate, true /* fFile */, fMode, 114 cTimes, fSkipXCheck); 115 } 116 117 118 static void tstDirCreateTemp(const char *pszSubTest, const char *pszTemplate, RTFMODE fMode, unsigned cTimes, bool fSkipXCheck) 119 { 120 tstObjectCreateTemp(pszSubTest, pszTemplate, false /* fFile */, fMode, 121 cTimes, fSkipXCheck); 122 } 123 124 125 static void tstBothCreateTemp(const char *pszSubTest, const char *pszTemplate, RTFMODE fMode, unsigned cTimes, bool fSkipXCheck) 126 { 127 char pszSubTestLong[128]; 128 129 RTStrPrintf(pszSubTestLong, sizeof(pszSubTestLong), "RTFileCreateTemp %s", 130 pszSubTest); 131 tstFileCreateTemp(pszSubTestLong, pszTemplate, fMode, cTimes, 132 fSkipXCheck); 133 RTStrPrintf(pszSubTestLong, sizeof(pszSubTestLong), "RTDirCreateTemp %s", 134 pszSubTest); 135 tstDirCreateTemp(pszSubTestLong, pszTemplate, fMode, cTimes, fSkipXCheck); 93 136 } 94 137 … … 110 153 111 154 /* 112 * Create N temporary directories using RTDirCreateTemp.155 * Create N temporary files and directories using RT(File|Dir)CreateTemp. 113 156 */ 114 tst DirCreateTemp("RTDirCreateTemp #1 (standard)", "rtRTTemp-XXXXXX",128, false /*fSkipXCheck*/);115 tst DirCreateTemp("RTDirCreateTemp #2 (long)", "rtRTTemp-XXXXXXXXXXXXXXXXX",128, false /*fSkipXCheck*/);116 tst DirCreateTemp("RTDirCreateTemp #3 (short)", "rtRTTemp-XX",128, false /*fSkipXCheck*/);117 tst DirCreateTemp("RTDirCreateTemp #4 (very short)", "rtRTTemp-X",26+10, false /*fSkipXCheck*/);118 tst DirCreateTemp("RTDirCreateTemp #5 (in-name)", "rtRTTemp-XXXt",2, false /*fSkipXCheck*/);119 tst DirCreateTemp("RTDirCreateTemp #6 (in-name)", "XXX-rtRTTemp",2, false /*fSkipXCheck*/);120 tst DirCreateTemp("RTDirCreateTemp #7 (in-name)", "rtRTTemp-XXXXXXXXX.tmp",128, false /*fSkipXCheck*/);121 tst DirCreateTemp("RTDirCreateTemp #8 (in-name)", "rtRTTemp-XXXXXXX-X.tmp",128, true /*fSkipXCheck*/);122 tst DirCreateTemp("RTDirCreateTemp #9 (in-name)", "rtRTTemp-XXXXXX-XX.tmp",128, true /*fSkipXCheck*/);157 tstBothCreateTemp("#1 (standard)", "rtRTTemp-XXXXXX", 0700, 128, false /*fSkipXCheck*/); 158 tstBothCreateTemp("#2 (long)", "rtRTTemp-XXXXXXXXXXXXXXXXX", 0700, 128, false /*fSkipXCheck*/); 159 tstBothCreateTemp("#3 (short)", "rtRTTemp-XX", 0777, 128, false /*fSkipXCheck*/); 160 tstBothCreateTemp("#4 (very short)", "rtRTTemp-X", 0100, 26+10, false /*fSkipXCheck*/); 161 tstBothCreateTemp("#5 (in-name)", "rtRTTemp-XXXt", 0301, 2, false /*fSkipXCheck*/); 162 tstBothCreateTemp("#6 (in-name)", "XXX-rtRTTemp", 0355, 2, false /*fSkipXCheck*/); 163 tstBothCreateTemp("#7 (in-name)", "rtRTTemp-XXXXXXXXX.tmp", 0755, 128, false /*fSkipXCheck*/); 164 tstBothCreateTemp("#8 (in-name)", "rtRTTemp-XXXXXXX-X.tmp", 0700, 128, true /*fSkipXCheck*/); 165 tstBothCreateTemp("#9 (in-name)", "rtRTTemp-XXXXXX-XX.tmp", 0700, 128, true /*fSkipXCheck*/); 123 166 124 167 /*
Note:
See TracChangeset
for help on using the changeset viewer.