Sean CaronUpdate stylea9363d38 years agoHistory
144 lines · 3.9 KB · C
RawDownload
/* bijou HTTP server for plan 9 by sean caron (scaron@umich.edu) */ #include "main.h" /* return codes:  *  * 0 = success  * 1 = http 500 internal server error  * 2 = http 401 authorization required*/ int check_authorization(char *path, char *rpath, struct configuration cfg, struct request req, struct htpasswd *htpass) {    Dir *td;	    char *u, *p, *temp;    int q, j, r;    uchar digest[SHA1dlen];    DigestState *s;    char up[41];     temp = malloc(sizeof(char)*(strlen(path)+1));     if (temp == 0) {        exits("MALLOC");    }     strcpy(temp, path);     if (temp[strlen(temp)-1] != '/') {        for (j = strlen(temp); j > 0; j--) {            if (temp[j] == '/') {                temp[j+1] = '\0';                break;            }        }    }     temp = realloc(temp, sizeof(char)*(strlen(temp)+strlen(cfg.htpassfile)+2));     if (temp == 0) {        exits("REALLOC");    }     strcat(temp, cfg.htpassfile);     while (1) {        // try the path on hand        td = dirstat(temp);         // didnt find htpasswd file, chop the path and keep looking        if (td == nil) {            for (j = strlen(temp); j >= 0; j--) {                if (temp[j] == '/') {                    temp[j] = '\0';                    break;                }            }             // if chopping off the lash slash leaves us with rpath then break out of the loop            if (strcmp(temp, rpath) == 0) {                break;            }             for (j = strlen(temp); j >= 0; j--) {                if (temp[j] == '/') {                    temp[j+1] = '\0';                    break;                }            }             strcat(temp, cfg.htpassfile);        }         // found a htpasswd file, break out of this htpasswd locator loop        else {            break;        }    }     // at this point, we have in temp either equal to rpath, or a path to a htpasswd file if one exists.     // so basically, check to see: if temp is not rpath (contains a path to a htpasswd file)    if (strcmp(temp, rpath) != 0) {        // then read in the htpasswd file        r = read_htpasswd_file(temp, htpass);         // if the function returned with an error code, give the client a HTTP 500 internal server error        if (r != 0) {            free(temp);            return 1;        }         // if we were ok, then:        // split req.authorization into username and password (it should already be decoded)        // username and password are colon delimited         r = 0;         // maybe we should make a copy of req.authorization before strtok'ing it...        u = strtok(req.authorization, ":");         // this sort of error handling is really crude; this should get refactored later.        if (u == 0) {            free(temp);            return 2;        }         p = strtok(0, ":");         if (p == 0) {            free(temp);            return 2;        }         // compare user name and password with entries read in from htpasswd file         r = 0;         for (q = 0; q < htpass->n_users; q++) {            if (strcmp( u, *(htpass->user+q)) == 0) {                s = sha1( (uchar *)p, strlen(p), digest, nil);                 sprintf(up, "%02.x%02.x%02.x%02.x%02.x%02.x%02.x%02.x%02.x%02.x%02.x%02.x%02.x%02.x%02.x%02.x%02.x%02.x%02.x%02.x", digest[0], digest[1], digest[2], digest[3], digest[4], digest[5], digest[6], digest[7], digest[8], digest[9], digest[10], digest[11], digest[12], digest[13], digest[14], digest[15], digest[16], digest[17], digest[18], digest[19] );                 if (strcmp(up, *(htpass->pass+q)) == 0) {                    r = 1;                    break;                }            }        }         // if there is no match, give http 401 authorization required error        if (r != 1) {            free(temp);            return 2;        }         // otherwise, success; just pass through, we will return 0 and serve up the page    }     free(temp);     return 0;}