Ignore:
Timestamp:
01/09/11 03:59:19 (10 years ago)
Author:
Admin
Message:

Introducing cs_malloc/cs_realloc functions so that it's easier to log and handle errors. It's usage is demonstrated in oscam-http and oscam-http-helpers. Furthermore, some huge cleanups were done through the webinterface (the helpers module should be fine regarding threading issues now) and the oscam-log is now a bit safer by replacing the sprintfs through snprintfs (not only regarding BufferOverflows, but also Null strings dont lead to a crashing OSCam - at least on my debian).

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/oscam-http-helpers.c

    r4331 r4382  
    1717    if(result == NULL){
    1818        if((*vars).varsalloc <= (*vars).varscnt){
     19            if(!cs_realloc(&(*vars).names, (*vars).varsalloc * 2 * sizeof(char**), -1)) return value;
     20            if(!cs_realloc(&(*vars).values, (*vars).varsalloc * 2 * sizeof(char**), -1)) return value;
    1921            (*vars).varsalloc = (*vars).varscnt * 2;
    20             (*vars).names = (char**) realloc ((*vars).names, (*vars).varsalloc * sizeof(char**));
    21             (*vars).values = (char**) realloc ((*vars).values, (*vars).varsalloc * sizeof(char**));
    22         }
    23         tmp = (char *) malloc((strlen(name) + 1) * sizeof(char));
     22        }
     23        if(!cs_malloc(&tmp,(strlen(name) + 1) * sizeof(char), -1)) return value;
    2424        strcpy(tmp, name);
    2525        (*vars).names[(*vars).varscnt] = tmp;
    26         tmp = (char *) malloc((strlen(value) + 1) * sizeof(char));
     26        if(!cs_malloc(&tmp,(strlen(value) + 1) * sizeof(char), -1)){
     27            free((*vars).names[(*vars).varscnt]);
     28            return value;
     29        }
    2730        strcpy(tmp, value);
    2831        (*vars).values[(*vars).varscnt] = tmp;
     
    3235        if(append == 1){
    3336            int oldlen = strlen((*vars).values[i]);
    34             tmp = (char*) malloc ((oldlen + newlen + 1) * sizeof(char));
     37            if(!cs_malloc(&tmp, (oldlen + newlen + 1) * sizeof(char), -1)) return value;
    3538            memcpy(tmp, (*vars).values[i], oldlen);
    3639            strcpy(tmp + oldlen, value);
    3740        } else {
    38             tmp = (char*) malloc ((newlen + 1) * sizeof(char));
     41            if(!cs_malloc(&tmp, (newlen + 1) * sizeof(char), -1)) return value;
    3942            strcpy(tmp, value);
    4043        }
     
    4952  it after having added the array here! */
    5053char *tpl_addTmp(struct templatevars *vars, char *value){
    51     if((*vars).tmpalloc <= (*vars).tmpcnt){
     54    if((*vars).tmpalloc <= (*vars).tmpcnt){     
     55        if(!cs_realloc (&(*vars).tmp, (*vars).tmpalloc * 2 * sizeof(char**), -1)) return value;
    5256        (*vars).tmpalloc = (*vars).tmpcnt * 2;
    53         (*vars).tmp = (char**) realloc ((*vars).tmp, (*vars).tmpalloc * sizeof(char**));
    5457    }
    5558    (*vars).tmp[(*vars).tmpcnt] = value;
    56     (*vars).tmpcnt = (*vars).tmpcnt + 1;
     59    (*vars).tmpcnt++;
    5760    return value;
    5861}
     
    7073    va_end(argptr);
    7174   
    72     char *result = (char *) malloc((needed + 1) * sizeof(char));
     75    char *result;
     76    if(!cs_malloc(&result, (needed + 1) * sizeof(char), -1)) return "";
    7377    va_start(argptr,fmtstring);
    7478    vsnprintf(result, needed + 1, fmtstring, argptr);
     
    98102}
    99103
    100 /* Initializes all variables vor a templatevar-structure and returns a pointer to it. Make
     104/* Initializes all variables for a templatevar-structure and returns a pointer to it. Make
    101105   sure to call tpl_clear() when you are finished or you'll run into a memory leak! */
    102106struct templatevars *tpl_create(){
    103     struct templatevars *vars = (struct templatevars *) malloc(sizeof(struct templatevars));
    104     (*vars).varsalloc = 16;
     107    struct templatevars *vars;
     108    if(!cs_malloc(&vars, sizeof(struct templatevars), -1)) return NULL;
     109    (*vars).varsalloc = 64;
    105110    (*vars).varscnt = 0;
    106     (*vars).tmpalloc = 16;
     111    (*vars).tmpalloc = 64;
    107112    (*vars).tmpcnt = 0;
    108     (*vars).names = (char**) malloc ((*vars).varsalloc * sizeof(char**));
    109     (*vars).values = (char**) malloc ((*vars).varsalloc * sizeof(char**));
    110     (*vars).tmp = (char**) malloc ((*vars).tmpalloc * sizeof(char**));
     113    if(!cs_malloc(&(*vars).names, (*vars).varsalloc * sizeof(char**), -1)){
     114        free(vars);
     115        return NULL;
     116    }
     117    if(!cs_malloc(&(*vars).values, (*vars).varsalloc * sizeof(char**), -1)){
     118        free((*vars).names);
     119        free(vars);
     120        return NULL;
     121    };
     122    if(!cs_malloc(&(*vars).tmp, (*vars).tmpalloc * sizeof(char**), -1)){
     123        free((*vars).names);
     124        free((*vars).values);
     125        free(vars);
     126        return NULL;
     127    };
    111128    return vars;
    112129}
     
    144161
    145162/* Returns an unparsed template either from disk or from internal templates.
    146    Note: You must free() the result after using it!*/
     163   Note: You must free() the result after using it and you may get NULL if an error occured!*/
    147164char *tpl_getUnparsedTpl(const char* name){
    148165  int i;
     
    161178            char buffer[1024];
    162179            int read, allocated = 1025, size = 0;
    163             result = (char *) malloc(allocated * sizeof(char));
     180            if(!cs_malloc(&result, allocated * sizeof(char), -1)) return NULL;
    164181            if((fp = fopen(path,"r"))!=NULL){
    165182            while((read = fread(&buffer,sizeof(char),1024,fp)) > 0){
    166183                if(allocated < size + read + 1) {
    167184                    allocated += size + 1024;
    168                     result = (char *) realloc(result, allocated * sizeof(char));
     185                    if(!cs_realloc(&result, allocated * sizeof(char), -1)) return NULL;
    169186                }
    170187                memcpy(result + size, buffer, read);
     
    179196    if(i >= 0 && i < tplmapcnt){
    180197        int len = (strlen(tplmap[i])) + 1;
    181         result = (char *) malloc(len * sizeof(char));
     198        if(!cs_malloc(&result, len * sizeof(char), -1)) return NULL;
    182199        memcpy(result, tplmap[i], len);
    183200    } else {
    184         result = (char *) malloc(1 * sizeof(char));
     201        if(!cs_malloc(&result, 1 * sizeof(char), -1)) return NULL;
    185202        result[0] = '\0';
    186203  }
     
    189206
    190207/* Returns the specified template with all variables/other templates replaced or an
    191    empty string if the template doesn't exist*/
     208   empty string if the template doesn't exist. Do not free the result yourself, it
     209   will get automatically cleaned up! */
    192210char *tpl_getTpl(struct templatevars *vars, const char* name){
    193211    char *tplorg = tpl_getUnparsedTpl(name);
     212    if(!tplorg) return "";
    194213    char *tplend = tplorg + strlen(tplorg);
    195214    char *pch, *pch2, *tpl=tplorg;
     
    198217    int tmp,respos = 0;
    199218    int allocated = 2 * strlen(tpl) + 1;
    200     char *result = (char *) malloc(allocated * sizeof(char));
     219    char *result;
     220    if(!cs_malloc(&result, allocated * sizeof(char), -1)) return "";
    201221
    202222    while(tpl < tplend){
     
    216236                if(tmp + respos + 2 >= allocated){
    217237                    allocated = tmp + respos + 256;
    218                     result = (char *) realloc(result, allocated * sizeof(char));
     238                    if(!cs_realloc(&result, allocated * sizeof(char), -1)) return "";
    219239                }
    220240                memcpy(result + respos, pch2, tmp);
     
    225245            if(respos + 2 >= allocated){
    226246                allocated = respos + 256;
    227                 result = (char *) realloc(result, allocated * sizeof(char));
     247                if(!cs_realloc(&result, allocated * sizeof(char), -1)) return "";
    228248            }
    229249            result[respos] = tpl[0];
     
    243263  int tplmapcnt = sizeof(tplmap)/sizeof(char *);
    244264  int i, cnt = 0;
    245   char tmp[200];
     265  char tmp[256];
    246266  FILE *fp;
    247267  for(i = 0; i < tplcnt && i < tplmapcnt; ++i){
    248     if(strlen(tpl_getTplPath(tpl[i], path, tmp, 200)) > 0 && (fp = fopen(tmp,"w")) != NULL){
     268    if(strlen(tpl_getTplPath(tpl[i], path, tmp, 256)) > 0 && (fp = fopen(tmp,"w")) != NULL){
    249269            fwrite(tplmap[i], sizeof(char), strlen(tplmap[i]), fp);
    250270            fclose (fp);
     
    255275}
    256276
    257 /* Parses a value in an authentication string by removing all quotes/whitespace. Note that the original array is modified*/
     277/* Parses a value in an authentication string by removing all quotes/whitespace. Note that the original array is modified. */
    258278char *parse_auth_value(char *value){
    259279    char *pch = value;
     
    270290}
    271291
    272 /* Calculates the currently valid nonce value and copies it to result*/
    273 void calculate_nonce(char *result, int resultlen){
     292/* Calculates the currently valid nonce value and copies it to result. Please note that result needs to be at least (MD5_DIGEST_LENGTH * 2) + 1 large. */
     293void calculate_nonce(char *result){
    274294  char noncetmp[128];
     295  unsigned char md5tmp[MD5_DIGEST_LENGTH];
    275296  sprintf(noncetmp, "%d:%s", (int)time(NULL)/AUTHNONCEVALIDSECS, noncekey);
    276   char *expectednonce = char_to_hex(MD5((unsigned char*)noncetmp, strlen(noncetmp), NULL), MD5_DIGEST_LENGTH, hex2ascii);
    277   cs_strncpy(result, expectednonce, resultlen);
    278     free(expectednonce);
    279 }
    280 
    281 /* Checks if authentication is correct. Returns -1 if not correct, 1 if correct and 2 if nonce isn't valid anymore */
     297  char_to_hex(MD5((unsigned char*)noncetmp, strlen(noncetmp), md5tmp), MD5_DIGEST_LENGTH, (unsigned char*)result, hex2ascii);
     298}
     299
     300/* Checks if authentication is correct. Returns -1 if not correct, 1 if correct and 2 if nonce isn't valid anymore.
     301   Note that authstring will be modified. */
    282302int check_auth(char *authstring, char *method, char *path, char *expectednonce){
    283303    int authok = 0, uriok = 0;
     
    322342    if(uriok == 1 && strcmp(username, cfg->http_user) == 0){
    323343        char A1tmp[3 + strlen(username) + strlen(AUTHREALM) + strlen(expectedPassword)];
     344        char A1[(MD5_DIGEST_LENGTH * 2) + 1], A2[(MD5_DIGEST_LENGTH * 2) + 1], A3[(MD5_DIGEST_LENGTH * 2) + 1];
     345        unsigned char md5tmp[MD5_DIGEST_LENGTH];
    324346        sprintf(A1tmp, "%s:%s:%s", username, AUTHREALM, expectedPassword);
    325         char *A1 = char_to_hex(MD5((unsigned char*)A1tmp, strlen(A1tmp), NULL), MD5_DIGEST_LENGTH, hex2ascii);
     347        char_to_hex(MD5((unsigned char*)A1tmp, strlen(A1tmp), md5tmp), MD5_DIGEST_LENGTH, (unsigned char*)A1, hex2ascii);
    326348       
    327349        char A2tmp[2 + strlen(method) + strlen(uri)];
    328350        sprintf(A2tmp, "%s:%s", method, uri);       
    329         char *A2 = char_to_hex(MD5((unsigned char*)A2tmp, strlen(A2tmp), NULL), MD5_DIGEST_LENGTH, hex2ascii);
     351        char_to_hex(MD5((unsigned char*)A2tmp, strlen(A2tmp), md5tmp), MD5_DIGEST_LENGTH, (unsigned char*)A2, hex2ascii);
    330352       
    331353        char A3tmp[10 + strlen(A1) + strlen(A2) + strlen(authnonce) + strlen(authnc) + strlen(authcnonce)];
    332354        sprintf(A3tmp, "%s:%s:%s:%s:auth:%s", A1, authnonce, authnc, authcnonce, A2);
    333         char *A3 = char_to_hex(MD5((unsigned char*)A3tmp, strlen(A3tmp), NULL), MD5_DIGEST_LENGTH, hex2ascii);
     355        char_to_hex(MD5((unsigned char*)A3tmp, strlen(A3tmp), md5tmp), MD5_DIGEST_LENGTH, (unsigned char*)A3, hex2ascii);
    334356       
    335357        if(strcmp(A3, authresponse) == 0) {
     
    337359            else authok = 2;
    338360        }
    339         free(A1);
    340         free(A2);
    341         free(A3);
    342361    }
    343362    return authok;
     
    371390
    372391  time_t now;
    373   char timebuf[128];
    374   char buf[1024];
    375 
    376   sprintf(buf, "%s %d %s\r\n", PROTOCOL, status, title);
    377   sprintf(buf+strlen(buf), "Server: %s\r\n", SERVER);
     392  char timebuf[32];
     393  char buf[sizeof(PROTOCOL) + sizeof(SERVER) + strlen(title) + (extra == NULL?0:strlen(extra)+2) + (mime == NULL?0:strlen(mime)+2) + 256];
     394    char *pos = buf;
     395   
     396  pos += sprintf(pos, "%s %d %s\r\n", PROTOCOL, status, title);
     397  pos += sprintf(pos, "Server: %s\r\n", SERVER);
    378398
    379399  now = time(NULL);
    380400  strftime(timebuf, sizeof(timebuf), RFC1123FMT, gmtime(&now));
    381   sprintf(buf+strlen(buf), "Date: %s\r\n", timebuf);
     401  pos += sprintf(pos, "Date: %s\r\n", timebuf);
    382402
    383403    if (extra)
    384         sprintf(buf+strlen(buf), "%s\r\n", extra);
     404        pos += sprintf(pos, "%s\r\n", extra);
    385405
    386406    if (mime)
    387         sprintf(buf+strlen(buf), "Content-Type: %s\r\n", mime);
    388 
    389     strftime(timebuf, sizeof(timebuf), RFC1123FMT, gmtime(&now));
    390     sprintf(buf+strlen(buf), "Cache-Control: no-store, no-cache, must-revalidate\r\n");
    391     sprintf(buf+strlen(buf), "Expires: Sat, 26 Jul 1997 05:00:00 GMT\r\n");
    392     sprintf(buf+strlen(buf), "Last-Modified: %s\r\n", timebuf);
    393     sprintf(buf+strlen(buf), "Connection: close\r\n");
    394     sprintf(buf+strlen(buf), "\r\n");
     407        pos += sprintf(pos, "Content-Type: %s\r\n", mime);
     408
     409    pos += sprintf(pos, "Cache-Control: no-store, no-cache, must-revalidate\r\n");
     410    pos += sprintf(pos, "Expires: Sat, 26 Jul 1997 05:00:00 GMT\r\n");
     411    pos += sprintf(pos, "Last-Modified: %s\r\n", timebuf);
     412    pos += sprintf(pos, "Connection: close\r\n");
     413    pos += sprintf(pos, "\r\n");
    395414    webif_write(buf, f);
    396415}
    397416
    398417
     418
    399419/*
    400  * function for sending files. 1 = CSS, 2 = JS
     420 * function for sending files.
    401421 */
    402 void send_file(FILE *f, int fileno){
    403 
    404     char *filename;
    405 
    406     if (fileno == 1)
     422void send_file(FILE *f, char *filename){
     423    int fileno = 0;
     424
     425    if (!strcmp(filename, "CSS")){
    407426        filename = cfg->http_css;
    408     else if (fileno == 2)
     427        fileno = 1;
     428    } else if (!strcmp(filename, "JS")){
    409429        filename = cfg->http_jscript;
    410     else
    411         return;
     430        fileno = 2;
     431    }
    412432
    413433    if(strlen(filename) > 0 && file_exists(filename) == 1){
     
    428448        else if (fileno == 2)
    429449            webif_write(JSCRIPT, f);
    430        
    431450    }
    432451}
     
    442461}
    443462
     463void send_error500(FILE *f){
     464    send_error(f, 500, "Internal Server Error", NULL, "An internal error has occured.");
     465}
     466
    444467char *getParam(struct uriparams *params, char *name){
    445468    int i;
     
    462485char *xml_encode(struct templatevars *vars, char *chartoencode) {
    463486    int i, pos = 0, len = strlen(chartoencode);
     487    char *result;
    464488    /* In worst case, every character could get converted to 6 chars (we only support ASCII, for Unicode it would be 7)*/
    465489    char encoded[len * 6 + 1], buffer[7];
     
    486510    }
    487511    /* Allocate the needed memory size and store it in the templatevars */
    488     char *result = (char *)malloc(pos + 1);
     512    if(!cs_malloc(&result, pos + 1, -1)) return "";
    489513    memcpy(result, encoded, pos);
    490514    result[pos] = '\0';
Note: See TracChangeset for help on using the changeset viewer.