ReactOS Fundraising Campaign 2012
 
€ 4,410 / € 30,000

Information | Donate

Home | Info | Community | Development | myReactOS | Contact Us

  1. Home
  2. Community
  3. Development
  4. myReactOS
  5. Fundraiser 2012

  1. Main Page
  2. Alphabetical List
  3. Data Structures
  4. Directories
  5. File List
  6. Data Fields
  7. Globals
  8. Related Pages

ReactOS Development > Doxygen

security.c
Go to the documentation of this file.
00001 /*
00002  * security.c: Implementation of the XSLT security framework
00003  *
00004  * See Copyright for the status of this software.
00005  *
00006  * daniel@veillard.com
00007  */
00008 
00009 #define IN_LIBXSLT
00010 #include "libxslt.h"
00011 
00012 #include <string.h>
00013 
00014 #ifdef HAVE_SYS_TYPES_H
00015 #include <sys/types.h>
00016 #endif
00017 #ifdef HAVE_SYS_STAT_H
00018 #include <sys/stat.h>
00019 #endif
00020 
00021 #ifdef HAVE_MATH_H
00022 #include <math.h>
00023 #endif
00024 #ifdef HAVE_FLOAT_H
00025 #include <float.h>
00026 #endif
00027 #ifdef HAVE_IEEEFP_H
00028 #include <ieeefp.h>
00029 #endif
00030 #ifdef HAVE_NAN_H
00031 #include <nan.h>
00032 #endif
00033 #ifdef HAVE_CTYPE_H
00034 #include <ctype.h>
00035 #endif
00036 
00037 #if defined(WIN32) && !defined(__CYGWIN__)
00038 #include <windows.h>
00039 #ifndef INVALID_FILE_ATTRIBUTES
00040 #define INVALID_FILE_ATTRIBUTES ((DWORD)-1)
00041 #endif
00042 #endif
00043 
00044 #ifndef HAVE_STAT
00045 #  ifdef HAVE__STAT
00046      /* MS C library seems to define stat and _stat. The definition
00047       *         is identical. Still, mapping them to each other causes a warning. */
00048 #    ifndef _MSC_VER
00049 #      define stat(x,y) _stat(x,y)
00050 #    endif
00051 #    define HAVE_STAT
00052 #  endif
00053 #endif
00054 
00055 #include <libxml/xmlmemory.h>
00056 #include <libxml/tree.h>
00057 #include <libxml/uri.h>
00058 #include "xslt.h"
00059 #include "xsltInternals.h"
00060 #include "xsltutils.h"
00061 #include "extensions.h"
00062 #include "security.h"
00063 
00064 
00065 struct _xsltSecurityPrefs {
00066     xsltSecurityCheck readFile;
00067     xsltSecurityCheck createFile;
00068     xsltSecurityCheck createDir;
00069     xsltSecurityCheck readNet;
00070     xsltSecurityCheck writeNet;
00071 };
00072 
00073 static xsltSecurityPrefsPtr xsltDefaultSecurityPrefs = NULL;
00074 
00075 /************************************************************************
00076  *                                  *
00077  *          Module interfaces               *
00078  *                                  *
00079  ************************************************************************/
00080 
00088 xsltSecurityPrefsPtr
00089 xsltNewSecurityPrefs(void) {
00090     xsltSecurityPrefsPtr ret;
00091 
00092     xsltInitGlobals();
00093 
00094     ret = (xsltSecurityPrefsPtr) xmlMalloc(sizeof(xsltSecurityPrefs));
00095     if (ret == NULL) {
00096     xsltTransformError(NULL, NULL, NULL,
00097         "xsltNewSecurityPrefs : malloc failed\n");
00098     return(NULL);
00099     }
00100     memset(ret, 0, sizeof(xsltSecurityPrefs));
00101     return(ret);
00102 }
00103 
00110 void
00111 xsltFreeSecurityPrefs(xsltSecurityPrefsPtr sec) {
00112     if (sec == NULL)
00113     return;
00114     xmlFree(sec);
00115 }
00116 
00127 int
00128 xsltSetSecurityPrefs(xsltSecurityPrefsPtr sec, xsltSecurityOption option,
00129                      xsltSecurityCheck func) {
00130     xsltInitGlobals();
00131     if (sec == NULL)
00132     return(-1);
00133     switch (option) {
00134         case XSLT_SECPREF_READ_FILE:
00135             sec->readFile = func; return(0);
00136         case XSLT_SECPREF_WRITE_FILE:
00137             sec->createFile = func; return(0);
00138         case XSLT_SECPREF_CREATE_DIRECTORY:
00139             sec->createDir = func; return(0);
00140         case XSLT_SECPREF_READ_NETWORK:
00141             sec->readNet = func; return(0);
00142         case XSLT_SECPREF_WRITE_NETWORK:
00143             sec->writeNet = func; return(0);
00144     }
00145     return(-1);
00146 }
00147 
00157 xsltSecurityCheck
00158 xsltGetSecurityPrefs(xsltSecurityPrefsPtr sec, xsltSecurityOption option) {
00159     if (sec == NULL)
00160     return(NULL);
00161     switch (option) {
00162         case XSLT_SECPREF_READ_FILE:
00163             return(sec->readFile);
00164         case XSLT_SECPREF_WRITE_FILE:
00165             return(sec->createFile);
00166         case XSLT_SECPREF_CREATE_DIRECTORY:
00167             return(sec->createDir);
00168         case XSLT_SECPREF_READ_NETWORK:
00169             return(sec->readNet);
00170         case XSLT_SECPREF_WRITE_NETWORK:
00171             return(sec->writeNet);
00172     }
00173     return(NULL);
00174 }
00175 
00182 void
00183 xsltSetDefaultSecurityPrefs(xsltSecurityPrefsPtr sec) {
00184     
00185     xsltDefaultSecurityPrefs = sec;
00186 }
00187 
00195 xsltSecurityPrefsPtr
00196 xsltGetDefaultSecurityPrefs(void) {
00197     return(xsltDefaultSecurityPrefs);
00198 }
00199 
00209 int                    
00210 xsltSetCtxtSecurityPrefs(xsltSecurityPrefsPtr sec,
00211                      xsltTransformContextPtr ctxt) {
00212     if (ctxt == NULL)
00213     return(-1);
00214     ctxt->sec = (void *) sec;
00215     return(0);
00216 }
00217 
00218 
00229 int
00230 xsltSecurityAllow(xsltSecurityPrefsPtr sec ATTRIBUTE_UNUSED,
00231               xsltTransformContextPtr ctxt ATTRIBUTE_UNUSED,
00232           const char *value ATTRIBUTE_UNUSED) {
00233     return(1);
00234 }
00235 
00246 int
00247 xsltSecurityForbid(xsltSecurityPrefsPtr sec ATTRIBUTE_UNUSED,
00248               xsltTransformContextPtr ctxt ATTRIBUTE_UNUSED,
00249           const char *value ATTRIBUTE_UNUSED) {
00250     return(0);
00251 }
00252 
00253 /************************************************************************
00254  *                                  *
00255  *          Internal interfaces             *
00256  *                                  *
00257  ************************************************************************/
00258 
00277 static int
00278 xsltCheckFilename (const char *path)
00279 {
00280 #ifdef HAVE_STAT
00281     struct stat stat_buffer;
00282 #if defined(WIN32) && !defined(__CYGWIN__)
00283     DWORD dwAttrs;
00284 
00285     dwAttrs = GetFileAttributes(path); 
00286     if (dwAttrs != INVALID_FILE_ATTRIBUTES) {
00287         if (dwAttrs & FILE_ATTRIBUTE_DIRECTORY) {
00288             return 2;
00289         }
00290     }
00291 #endif
00292 
00293     if (stat(path, &stat_buffer) == -1)
00294         return 0;
00295 
00296 #ifdef S_ISDIR
00297     if (S_ISDIR(stat_buffer.st_mode)) {
00298         return 2;
00299     }
00300 #endif
00301 #endif
00302     return 1;
00303 }
00304 
00305 static int
00306 xsltCheckWritePath(xsltSecurityPrefsPtr sec,
00307            xsltTransformContextPtr ctxt,
00308            const char *path)
00309 {
00310     int ret;
00311     xsltSecurityCheck check;
00312     char *directory;
00313 
00314     check = xsltGetSecurityPrefs(sec, XSLT_SECPREF_WRITE_FILE);
00315     if (check != NULL) {
00316     ret = check(sec, ctxt, path);
00317     if (ret == 0) {
00318         xsltTransformError(ctxt, NULL, NULL,
00319                    "File write for %s refused\n", path);
00320         return(0);
00321     }
00322     }
00323 
00324     directory = xmlParserGetDirectory (path);
00325 
00326     if (directory != NULL) {
00327     ret = xsltCheckFilename(directory);
00328     if (ret == 0) {
00329         /*
00330          * The directory doesn't exist check for creation
00331          */
00332         check = xsltGetSecurityPrefs(sec,
00333                      XSLT_SECPREF_CREATE_DIRECTORY);
00334         if (check != NULL) {
00335         ret = check(sec, ctxt, directory);
00336         if (ret == 0) {
00337             xsltTransformError(ctxt, NULL, NULL,
00338                        "Directory creation for %s refused\n",
00339                        path);
00340             xmlFree(directory);
00341             return(0);
00342         }
00343         }
00344         ret = xsltCheckWritePath(sec, ctxt, directory);
00345         if (ret == 1)
00346         ret = mkdir(directory, 0755);
00347     }
00348     xmlFree(directory);
00349     if (ret < 0)
00350         return(ret);
00351     }
00352 
00353     return(1);
00354 }
00355 
00367 int
00368 xsltCheckWrite(xsltSecurityPrefsPtr sec,
00369            xsltTransformContextPtr ctxt, const xmlChar *URL) {
00370     int ret;
00371     xmlURIPtr uri;
00372     xsltSecurityCheck check;
00373 
00374     uri = xmlParseURI((const char *)URL);
00375     if (uri == NULL) {
00376         uri = xmlCreateURI();
00377     if (uri == NULL) {
00378         xsltTransformError(ctxt, NULL, NULL,
00379          "xsltCheckWrite: out of memory for %s\n", URL);
00380         return(-1);
00381     }
00382     uri->path = (char *)xmlStrdup(URL);
00383     }
00384     if ((uri->scheme == NULL) ||
00385     (xmlStrEqual(BAD_CAST uri->scheme, BAD_CAST "file"))) {
00386 
00387 #if defined(WIN32) && !defined(__CYGWIN__)
00388     if ((uri->path)&&(uri->path[0]=='/')&&
00389         (uri->path[1]!='\0')&&(uri->path[2]==':'))
00390     ret = xsltCheckWritePath(sec, ctxt, uri->path+1);
00391     else
00392 #endif
00393 
00394     /*
00395      * Check if we are allowed to write this file
00396      */
00397     ret = xsltCheckWritePath(sec, ctxt, uri->path);
00398     if (ret <= 0) {
00399         xmlFreeURI(uri);
00400         return(ret);
00401     }
00402     } else {
00403     /*
00404      * Check if we are allowed to write this network resource
00405      */
00406     check = xsltGetSecurityPrefs(sec, XSLT_SECPREF_WRITE_NETWORK);
00407     if (check != NULL) {
00408         ret = check(sec, ctxt, (const char *)URL);
00409         if (ret == 0) {
00410         xsltTransformError(ctxt, NULL, NULL,
00411                  "File write for %s refused\n", URL);
00412         xmlFreeURI(uri);
00413         return(0);
00414         }
00415     }
00416     }
00417     xmlFreeURI(uri);
00418     return(1);
00419 }
00420 
00421 
00432 int
00433 xsltCheckRead(xsltSecurityPrefsPtr sec,
00434           xsltTransformContextPtr ctxt, const xmlChar *URL) {
00435     int ret;
00436     xmlURIPtr uri;
00437     xsltSecurityCheck check;
00438 
00439     uri = xmlParseURI((const char *)URL);
00440     if (uri == NULL) {
00441     xsltTransformError(ctxt, NULL, NULL,
00442      "xsltCheckRead: URL parsing failed for %s\n",
00443              URL);
00444     return(-1);
00445     }
00446     if ((uri->scheme == NULL) ||
00447     (xmlStrEqual(BAD_CAST uri->scheme, BAD_CAST "file"))) {
00448 
00449     /*
00450      * Check if we are allowed to read this file
00451      */
00452     check = xsltGetSecurityPrefs(sec, XSLT_SECPREF_READ_FILE);
00453     if (check != NULL) {
00454         ret = check(sec, ctxt, uri->path);
00455         if (ret == 0) {
00456         xsltTransformError(ctxt, NULL, NULL,
00457                  "Local file read for %s refused\n", URL);
00458         xmlFreeURI(uri);
00459         return(0);
00460         }
00461     }
00462     } else {
00463     /*
00464      * Check if we are allowed to write this network resource
00465      */
00466     check = xsltGetSecurityPrefs(sec, XSLT_SECPREF_READ_NETWORK);
00467     if (check != NULL) {
00468         ret = check(sec, ctxt, (const char *)URL);
00469         if (ret == 0) {
00470         xsltTransformError(ctxt, NULL, NULL,
00471                  "Network file read for %s refused\n", URL);
00472         xmlFreeURI(uri);
00473         return(0);
00474         }
00475     }
00476     }
00477     xmlFreeURI(uri);
00478     return(1);
00479 }
00480 

Generated on Sun May 27 2012 04:17:42 for ReactOS by doxygen 1.7.6.1

ReactOS is a registered trademark or a trademark of ReactOS Foundation in the United States and other countries.