ESAPI-C 1.0
The OWASP Enterprise Security API for C

sec_context.c

Go to the documentation of this file.
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 
 All Data Structures Files Functions Variables Typedefs Defines