VirtualBox

Changeset 42712 in vbox for trunk


Ignore:
Timestamp:
Aug 9, 2012 2:36:02 PM (12 years ago)
Author:
vboxsync
Message:

Runtime: add RTFileCreateTemp, RTFileCreateTempSecure and RTDirCreateTempSecure (the last two are not yet implemented).

Location:
trunk
Files:
5 edited

Legend:

Unmodified
Added
Removed
  • trunk/include/iprt/dir.h

    r42708 r42712  
    9898 */
    9999RTDECL(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 */
     121RTDECL(int) RTDirCreateTempSecure(char *pszTemplate);
    100122
    101123/**
  • trunk/include/iprt/file.h

    r39641 r42712  
    587587
    588588
     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 */
     609RTDECL(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 */
     630RTDECL(int) RTFileCreateTempSecure(char *pszTemplate);
     631
     632
    589633/** @page   pg_rt_filelock      RT File locking API description
    590634 *
  • trunk/include/iprt/mangling.h

    r42067 r42712  
    390390# define RTDirCreateFullPath                            RT_MANGLER(RTDirCreateFullPath)
    391391# define RTDirCreateTemp                                RT_MANGLER(RTDirCreateTemp)
     392# define RTDirCreateTempSecure                          RT_MANGLER(RTDirCreateTempSecure)
    392393# define RTDirCreateUniqueNumbered                      RT_MANGLER(RTDirCreateUniqueNumbered)
    393394# define RTDirExists                                    RT_MANGLER(RTDirExists)
     
    478479# define RTFileCopyByHandlesEx                          RT_MANGLER(RTFileCopyByHandlesEx)
    479480# define RTFileCopyEx                                   RT_MANGLER(RTFileCopyEx)
     481# define RTFileCreateTemp                               RT_MANGLER(RTFileCreateTemp)
     482# define RTFileCreateTempSecure                         RT_MANGLER(RTFileCreateTempSecure)
    480483# define RTFileDelete                                   RT_MANGLER(RTFileDelete)
    481484# define RTFileExists                                   RT_MANGLER(RTFileExists)
  • trunk/src/VBox/Runtime/generic/createtemp-generic.cpp

    r42709 r42712  
    11/* $Id$ */
    22/** @file
    3  * IPRT - RTDirCreateTemp, generic implementation.
     3 * IPRT - temporary file and directory creation, generic implementation.
    44 */
    55
    66/*
    7  * Copyright (C) 2009 Oracle Corporation
     7 * Copyright (C) 2009-2012 Oracle Corporation
    88 *
    99 * This file is part of VirtualBox Open Source Edition (OSE), as
     
    3434#include <iprt/assert.h>
    3535#include <iprt/err.h>
     36#include <iprt/file.h>
    3637#include <iprt/path.h>
    3738#include <iprt/rand.h>
     
    108109RTDECL(int) RTDirCreateTemp(char *pszTemplate, RTFMODE fMode)
    109110{
    110     char       *pszX = NULL;  /* Initialise to make gcc happy. */
     111    char       *pszX = NULL;
    111112    unsigned    cXes = 0;
    112113    int rc = rtCreateTempValidateTemplate(pszTemplate, &pszX, &cXes);
     
    139140RT_EXPORT_SYMBOL(RTDirCreateTemp);
    140141
     142
     143/** @todo Test case for this once it is implemented. */
     144RTDECL(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}
     167RT_EXPORT_SYMBOL(RTDirCreateTempSecure);
     168
     169
     170RTDECL(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}
     209RT_EXPORT_SYMBOL(RTFileCreateTemp);
     210
     211
     212/** @todo Test case for this once it is implemented. */
     213RTDECL(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}
     236RT_EXPORT_SYMBOL(RTFileCreateTempSecure);
  • trunk/src/VBox/Runtime/testcase/tstRTTemp.cpp

    r42708 r42712  
    4848
    4949
    50 static void tstDirCreateTemp(const char *pszSubTest, const char *pszTemplate, unsigned cTimes, bool fSkipXCheck)
     50static void tstObjectCreateTemp(const char *pszSubTest, const char *pszTemplate, bool fFile, RTFMODE fMode, unsigned cTimes, bool fSkipXCheck)
    5151{
    5252    RTTestISub(pszSubTest);
     53    const char *pcszAPI = fFile ? "RTFileCreateTemp" : "RTDirCreateTemp";
    5354
    5455    /* Allocate the result array. */
     
    6263        int rc;
    6364        char szName[RTPATH_MAX];
     65        RTFMODE fModeFinal;
    6466        RTTESTI_CHECK_RC(rc = RTPathAppend(strcpy(szName, g_szTempPath), sizeof(szName), pszTemplate), VINF_SUCCESS);
    6567        if (RT_FAILURE(rc))
     
    7072            break;
    7173
    72         rc = RTDirCreateTemp(papszNames[i], 0700);
     74        rc =   fFile
     75             ? RTFileCreateTemp(papszNames[i], fMode)
     76             : RTDirCreateTemp(papszNames[i], fMode);
    7377        if (rc != VINF_SUCCESS)
    7478        {
    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);
    7680            RTStrFree(papszNames[i]);
    7781            papszNames[i] = NULL;
    7882            break;
    7983        }
    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]));
    8294        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]));
    8496    }
    8597
     
    8799    while (i-- > 0)
    88100    {
    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);
    90105        RTStrFree(papszNames[i]);
    91106    }
    92107    RTMemTmpFree(papszNames);
     108}
     109
     110
     111static 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
     118static 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
     125static 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);
    93136}
    94137
     
    110153
    111154    /*
    112      * Create N temporary directories using RTDirCreateTemp.
     155     * Create N temporary files and directories using RT(File|Dir)CreateTemp.
    113156     */
    114     tstDirCreateTemp("RTDirCreateTemp #1 (standard)",   "rtRTTemp-XXXXXX",              128, false /*fSkipXCheck*/);
    115     tstDirCreateTemp("RTDirCreateTemp #2 (long)",       "rtRTTemp-XXXXXXXXXXXXXXXXX",  128, false /*fSkipXCheck*/);
    116     tstDirCreateTemp("RTDirCreateTemp #3 (short)",      "rtRTTemp-XX",                  128, false /*fSkipXCheck*/);
    117     tstDirCreateTemp("RTDirCreateTemp #4 (very short)", "rtRTTemp-X",                26+10, false /*fSkipXCheck*/);
    118     tstDirCreateTemp("RTDirCreateTemp #5 (in-name)",    "rtRTTemp-XXXt",                  2, false /*fSkipXCheck*/);
    119     tstDirCreateTemp("RTDirCreateTemp #6 (in-name)",    "XXX-rtRTTemp",                  2, false /*fSkipXCheck*/);
    120     tstDirCreateTemp("RTDirCreateTemp #7 (in-name)",    "rtRTTemp-XXXXXXXXX.tmp",      128, false /*fSkipXCheck*/);
    121     tstDirCreateTemp("RTDirCreateTemp #8 (in-name)",    "rtRTTemp-XXXXXXX-X.tmp",      128, true /*fSkipXCheck*/);
    122     tstDirCreateTemp("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*/);
    123166
    124167    /*
Note: See TracChangeset for help on using the changeset viewer.

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette