Home | Info | Community | Development | myReactOS | Contact Us
ReactOS Development > Doxygensecurity.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
1.7.6.1
|