ESAPI-C 1.0
The OWASP Enterprise Security API for C
|
00001 00008 #include <string.h> 00009 00010 #include "executor.h" 00011 #include "log.h" 00012 00013 #define EXTRA_COMMANDS 7 // for "cd" and " && " in building command 00014 00017 int is_canonical(char *path) { 00018 int result; 00019 00020 char *canonical_path = realpath(path, NULL); 00021 /* char *canonical_path = canonicalize_file_name(path, NULL); */ 00022 if (canonical_path == NULL) { 00023 result = -1; 00024 } else { 00025 result = strcmp(path, canonical_path); 00026 free(canonical_path); 00027 } 00028 00029 return result; 00030 } 00031 00036 int is_allowed(char *path) { 00037 /* FIXME: Check against an allowed list in the ESAPI configuration */ 00038 return 1; 00039 } 00040 00050 char *esapi_execute(char *executable, char **params, int paramcount, 00051 char *workdir, codec *c, bool logParams) { 00052 FILE *fpipe = 0; 00053 int commandlen = 0; // for command line length 00054 char *output = 0; 00055 00056 if (is_canonical(executable) == 0) { 00057 (void) fprintf(stderr, "Executable not a canonical path"); 00058 return 0; 00059 } 00060 00061 if (is_allowed(executable) == 0) { 00062 (void) fprintf(stderr, "Executable not an allowed path"); 00063 return 0; 00064 } 00065 00066 if (executable) { 00067 commandlen = strlen(executable); 00068 } 00069 00070 if (workdir) { 00071 commandlen += strlen(workdir) + EXTRA_COMMANDS; 00072 } 00073 00074 // escape any special characters in the parameters 00075 // FIXME: Need to construct a local char ** for the encoded params 00076 00077 int i; 00078 int paramslen = 0; 00079 for (i = 0; i < paramcount; i++) { 00080 // char *param = params[i]; 00081 // params[i] = encodeForOS(c, param); 00082 paramslen += (strlen(params[i]) + 1); 00083 } 00084 commandlen += paramslen; 00085 00086 // working directory must exist 00087 // set the command into the list and create command array 00088 00089 char command[commandlen + 1]; 00090 00091 if (workdir) { 00092 if ((sprintf(command, "%s %s %s", "cd ", workdir, " && ")) 00093 >= commandlen) { 00094 (void) fprintf(stderr, "command line build error\n"); 00095 return 0; 00096 } 00097 } 00098 00099 strcat(command, executable); 00100 00101 for (i = 0; i < paramcount; i++) { 00102 char *param = params[i]; 00103 strcat(command, " "); 00104 strcat(command, param); 00105 } 00106 00107 if (logParams) { 00108 esapi_log_warn(NULL, EVENT_SUCCESS, 00109 "Initiating executable: %s %s in %s", executable, params, 00110 workdir); 00111 } else { 00112 esapi_log_warn( 00113 NULL, 00114 EVENT_SUCCESS, 00115 "Initiating executable: %s [sensitive parameters obscured] in %s", 00116 executable, workdir); 00117 } 00118 00119 /* FIXME: I think we need to use exec */ 00120 if ((fpipe = (FILE *) popen(command, "r")) == 0) { 00121 fprintf(stderr, "Problems with pipe\n"); 00122 return 0; 00123 } 00124 00125 char line[1024] = { 0 }; 00126 00127 if ((output = (char *) malloc(2048)) == 0) { 00128 (void) fprintf(stderr, "malloc failure in %s\n", __func__); 00129 exit(EXIT_FAILURE); 00130 } 00131 00132 memset((char *)output, 0, sizeof(output)); 00133 00134 while (fgets(line, sizeof(line), fpipe)) { 00135 strcat(output, line); 00136 } 00137 00138 pclose(fpipe); 00139 00140 return output; 00141 }