ESAPI-C 1.0
The OWASP Enterprise Security API for C
|
00001 00008 #include <stdlib.h> 00009 #include <stdio.h> 00010 #include <gcrypt.h> 00011 #include <string.h> 00012 #include "base64.h" 00013 #include "esapi.h" 00014 #include "log.h" 00015 00016 #define LINE_LEN 1024 00017 #define PARSE_ERROR 0 00018 #define PARSE_SUCCESS 1 00019 00020 char *value_delimiters = ", "; 00021 00022 char **_parse_csv(char *value) { 00023 int count = 0, i; 00024 char **result = 0; 00025 char *tmp; 00026 char *copy; 00027 00028 if ((copy = strdup(value)) == 0) { 00029 (void) fprintf(stderr, "strdup failure in %s\n", __func__); 00030 exit(EXIT_FAILURE); 00031 } 00032 00033 tmp = strtok(copy, value_delimiters); 00034 while (tmp) { 00035 count++; 00036 tmp = strtok(NULL, value_delimiters); 00037 } 00038 00039 if (count) { 00040 if ((result = (char **) calloc(count, sizeof(char *))) == 0) { 00041 (void) fprintf(stderr, "calloc failure in %s\n", __func__); 00042 exit(EXIT_FAILURE); 00043 } 00044 00045 tmp = strtok(copy, value_delimiters); 00046 00047 char *token = value; 00048 for (i = 0; i < count; i++) { 00049 result[i] = token; 00050 token += strlen(token) + 1; 00051 token += strspn(token, value_delimiters); 00052 } 00053 } 00054 00055 return result; 00056 } 00057 00058 int _parse_csv_for_length(char *value) { 00059 int len = 0; 00060 char *tmp = 0; 00061 char *copy; 00062 00063 if ((copy = strdup(value)) == 0) { 00064 (void) fprintf(stderr, "strdup failure in %s\n", __func__); 00065 exit(EXIT_FAILURE); 00066 } 00067 00068 tmp = strtok(copy, value_delimiters); 00069 while ((tmp = strtok(NULL, value_delimiters))) { 00070 len++; 00071 } 00072 00073 return len; 00074 } 00075 00076 int _parse_boolean(char *value) { 00077 if (strcasecmp(value, "true") == 0) { 00078 return 1; 00079 } 00080 00081 return 0; 00082 } 00083 00084 int _parse_asymmetric_algo(const char *alg) { 00085 if (!strcmp(alg, "RSA")) { 00086 return GCRY_PK_RSA; 00087 } else if (!strcmp(alg, "DSA")) { 00088 return GCRY_PK_DSA; 00089 } else if (!strcmp(alg, "ELGAMAL")) { 00090 return GCRY_PK_ELG; 00091 } 00092 00093 return 0; 00094 } 00095 00096 int _parse_symmetric_algo(const char *alg) { 00097 if (!strcmp(alg, "3DES")) { 00098 return GCRY_CIPHER_3DES; 00099 } else if (!strcmp(alg, "AES128")) { 00100 return GCRY_CIPHER_AES128; 00101 } else if (!strcmp(alg, "AES192")) { 00102 return GCRY_CIPHER_AES192; 00103 } else if (!strcmp(alg, "AES256")) { 00104 return GCRY_CIPHER_AES256; 00105 } else if (!strcmp(alg, "TWOFISH256")) { 00106 return GCRY_CIPHER_TWOFISH; 00107 } else if (!strcmp(alg, "TWOFISH128")) { 00108 return GCRY_CIPHER_TWOFISH128; 00109 } 00110 00111 return 0; 00112 } 00113 00114 int _parse_symmetric_algo_mode(const char *value) { 00115 if (!strcmp(value, "ECB")) { 00116 return GCRY_CIPHER_MODE_ECB; 00117 } else if (!strcmp(value, "CBC")) { 00118 return GCRY_CIPHER_MODE_CBC; 00119 } else if (!strcmp(value, "CFB")) { 00120 return GCRY_CIPHER_MODE_CFB; 00121 } else if (!strcmp(value, "CTR")) { 00122 return GCRY_CIPHER_MODE_CTR; 00123 } else if (!strcmp(value, "OFB")) { 00124 return GCRY_CIPHER_MODE_OFB; 00125 } 00126 00127 return 0; 00128 } 00129 00130 int _parse_hash_algo(const char *alg) { 00131 if (!strcmp(alg, "SHA1")) { 00132 return GCRY_MD_SHA1; 00133 } else if (!strcmp(alg, "RIPEMD")) { 00134 return GCRY_MD_RMD160; 00135 } else if (!strcmp(alg, "MD5")) { 00136 return GCRY_MD_MD5; 00137 } else if (!strcmp(alg, "SHA224")) { 00138 return GCRY_MD_SHA224; 00139 } else if (!strcmp(alg, "SHA256")) { 00140 return GCRY_MD_SHA256; 00141 } else if (!strcmp(alg, "SHA384")) { 00142 return GCRY_MD_SHA384; 00143 } else if (!strcmp(alg, "SHA512")) { 00144 return GCRY_MD_SHA512; 00145 } 00146 return 0; 00147 } 00148 00149 int _parse_config_entry(char *l, char *n, char *v) { 00150 for (; *l != '=' && *l != '\n' && *l != '\r' && *l != '\0'; l++, n++) { 00151 *n = *l; 00152 } 00153 00154 *n = '\0'; 00155 00156 if (*l != '=') 00157 return PARSE_ERROR; 00158 else 00159 l++; // step over the '=' 00160 00161 for (; *l != '\n' && *l != '\r' && *l != '\0'; l++, v++) { 00162 *v = *l; 00163 } 00164 00165 *v = '\0'; 00166 00167 return PARSE_SUCCESS; 00168 } 00169 00170 /* 00171 * Load the context structure from a file. 00172 */ 00173 struct esapi_ctx *load_security_context(const char *infile) { 00174 FILE *fd; 00175 char line[LINE_LEN] = { '0' }; 00176 char name[LINE_LEN] = { '0' }; 00177 char value[LINE_LEN] = { '0' }; 00178 struct esapi_ctx *ctx = 0; 00179 size_t outlen = 0; 00180 00181 if ((ctx = (struct esapi_ctx *) malloc(sizeof(struct esapi_ctx))) == 0) { 00182 fprintf(stderr, "malloc error in %s\n", __func__); 00183 exit(EXIT_FAILURE); 00184 } 00185 00186 // step 1: open up config file 00187 if ((fd = fopen(infile, "r")) == 0) { 00188 esapi_log_error(NULL, SECURITY_FAILURE, 00189 "Cannot open ESAPI configuration file %s in %s\n", infile, __func__); 00190 return 0; 00191 } 00192 00193 // step 2: initialize default values for the context members 00194 ctx->print_properties = 0; 00195 ctx->master_key = ""; 00196 ctx->master_salt = ""; 00197 ctx->master_iv = ""; 00198 ctx->allowed_exts = NULL; 00199 ctx->allowed_exts_len = 0; 00200 ctx->max_file_size = 100000; 00201 ctx->sym_algo = GCRY_CIPHER_AES256; 00202 ctx->sym_algo_mode = GCRY_CIPHER_MODE_CBC; 00203 memset(ctx->sym_key,'\0', sizeof(ctx->sym_key)); 00204 ctx->hash_algo = GCRY_MD_SHA256; 00205 ctx->asym_algo = GCRY_PK_RSA; 00206 ctx->asym_pub_key = NULL; 00207 ctx->asym_priv_key = NULL; 00208 ctx->fips140 = 0; 00209 ctx->secure_mem = 0; 00210 ctx->allowed_login_attempts = 3; 00211 // ctx->quotas = NULL; 00212 // ctx->quota_len = 0; 00213 ctx->idle_timeout = 30; 00214 ctx->absolute_timeout = 240; 00215 00216 // step 3: loop through lines, assigning members when recognized 00217 while (fgets(line, sizeof(line), fd) != NULL) { 00218 // Check for comments and empty lines 00219 if (line[0] != '#' && line[0] != '\r' && line[0] != '\n') { 00220 if (_parse_config_entry(line, name, value) == PARSE_ERROR) { 00221 fprintf(stderr, "Invalid line in ESAPI config file: '%s'", line); 00222 } else { 00223 int recognized = 1; 00224 if (!strcmp(name, "ESAPI.PrintProperties")) { 00225 ctx->print_properties = _parse_boolean(value); 00226 } else if (!strcmp(name, "Encryptor.MasterKey")) { 00227 base64_decode_alloc(value, strlen(value), &ctx->master_key, 00228 &outlen); 00229 } else if (!strcmp(name, "Encryptor.MasterSalt")) { 00230 ctx->master_salt = strdup(value); 00231 } else if (!strcmp(name, "Executor.AllowedExts")) { 00232 ctx->allowed_exts = _parse_csv(value); 00233 ctx->allowed_exts_len = _parse_csv_for_length(value); 00234 } else if (!strcmp(name, "Logger.MaxFileSize")) { 00235 ctx->max_file_size = atoi(value); 00236 } else if (!strcmp(name, "Encryptor.SymAlgo")) { 00237 ctx->sym_algo = _parse_symmetric_algo(value); 00238 } else if (!strcmp(name, "Encryptor.SymAlgoMode")) { 00239 ctx->sym_algo_mode = _parse_symmetric_algo_mode(value); 00240 } else if (!strcmp(name, "Encryptor.HashAlgo")) { 00241 ctx->hash_algo = _parse_hash_algo(value); 00242 } else if (!strcmp(name, "Encryptor.AsymAlgo")) { 00243 ctx->asym_algo = _parse_asymmetric_algo(value); 00244 } else if (!strcmp(name, "Encryptor.AsymPubKey")) { 00245 base64_decode_alloc(value, strlen(value), 00246 &ctx->asym_pub_key, &outlen); 00247 } else if (!strcmp(name, "Encryptor.AsymPrivKey")) { 00248 base64_decode_alloc(value, strlen(value), 00249 &ctx->asym_priv_key, &outlen); 00250 } else if (!strcmp(name, "Encryptor.FIPS140")) { 00251 ctx->fips140 = _parse_boolean(value); 00252 } else if (!strcmp(name, "Encryptor.SecureMem")) { 00253 ctx->secure_mem = _parse_boolean(value); 00254 } else if (!strcmp(name, "Authenticator.AllowedLoginAttempts")) { 00255 ctx->allowed_login_attempts = atoi(value); 00256 } else if (!strcmp(name, "Authenticator.IdleTimeout")) { 00257 ctx->idle_timeout = atoi(value); 00258 } else if (!strcmp(name, "Authenticator.AbsoluteTimeout")) { 00259 ctx->absolute_timeout = atoi(value); 00260 } else { 00261 recognized = 0; 00262 esapi_log_warn(NULL, EVENT_FAILURE, "Ignoring unrecognized ESAPI property name: %s", name); 00263 } 00264 if (recognized && ctx->print_properties) { 00265 printf("Loading property: %s=%s\n", name, value); 00266 esapi_log_error(NULL, SECURITY_SUCCESS, "Loading property: %s=%s", name, value); 00267 } 00268 } 00269 } 00270 } 00271 00272 return ctx; 00273 } 00274