⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 mech_digest_md5.c

📁 这是一个完全开放的
💻 C
📖 第 1 页 / 共 2 页
字号:
/* * scod - a minimal sasl implementation for jabberd2 * Copyright (c) 2003 Robert Norris * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA02111-1307USA *//* DIGEST-MD5 mechanism */#include "scod.h"#include <ctype.h>#define HT  (9)#define CR  (13)#define LF  (10)#define SP  (32)#define DEL (127)static char *_opt_quote(char *in) {    int nesc;    char *r, *out, *w;    r = in;    nesc = 0;    while(*r != '\0') {        if(*r == '"' || *r == '\\')            nesc++;        r++;    }    out = (char *) malloc(sizeof(char) * (strlen(in) + nesc + 3));    r = in;    w = out;    *w = '"';    w++;    while(*r != '\0') {        if(*r == '"' || *r == '\\') {            *w = '\\';            w++;        }        *w = *r;        w++;        r++;    }    *w = '"';    w++;    *w = '\0';    log_debug(ZONE, "escaped '%s' into '%s'", in, out);    return out;}/** the list parser is based on code from cyrus-sasl. I love open source ;) */static char *_opt_skip_lws(char *c) {    if(c == NULL)        return NULL;    while(*c == ' ' || *c == HT || *c == CR || *c == LF) {        if(*c == '\0')            break;        c++;    }          return c;}static char *_opt_skip_token(char *c, int ci) {    if(c == NULL)        return NULL;        while(*c > SP) {        if(*c == DEL || *c == '(' || *c == ')' || *c == '<' || *c == '>' ||           *c == '@' || *c == ',' || *c == ';' || *c == ':' || *c == '\\' ||           *c == '\'' || *c == '/' || *c == '[' || *c == ']' || *c == '?' ||           *c == '=' || *c == '{' || *c == '}') {            if(ci) {                if(!isupper((unsigned char) *c))                break;            } else                break;        }        c++;    }      return c;}static char *_opt_unquote(char *in) {    char *out, *end;    int esc = 0;    /* if its not quoted, there's nothing to do */    if(*in != '"')        return _opt_skip_token(in, 0);        in++;    out = in;        for(end = in; *end != '\0'; end++, out++) {        if(esc) {            *out = *end;            esc = 0;        }        else if(*end == '\\') {            esc = 1;            out--;        }        else if(*end == '"')            break;        else            *out = *end;          }        if(*end != '"')        return NULL;        while(out <= end) {        *out = '\0';        out++;    }    end++;        return end;  } static void _opt_get_pair(char **in, char **key, char **val) {    char *end, *cur = *in;    *key = NULL;    *val = NULL;        if(*cur == '\0')        return;        cur = _opt_skip_lws(cur);        *key = cur;        cur = _opt_skip_token(cur, 1);        if(*cur != '=' && *cur != '\0') {        *cur = '\0';        cur++;    }        cur = _opt_skip_lws(cur);        if(*cur != '=') {        *key = NULL;        return;    }        *cur = '\0';    cur++;        cur = _opt_skip_lws(cur);          *val = (*cur == '"') ? cur + 1 : cur;        end = _opt_unquote(cur);    if(end == NULL) {        *key = NULL;        return;    }        if(*end != ',' && *end != '\0') {        *end = '\0';        end++;    }        end = _opt_skip_lws(end);        if(*end == ',') {        *end = '\0';        end++;    }    else if(*end != '\0') {         *key = NULL;        return;    }        *in = end;}static xht _digest_md5_parse_options(const char *buf, int buflen) {    xht hash, sub;    char *nbuf, *in, *key, *val;    nbuf = (char *) malloc(sizeof(char) * (buflen + 1));    strncpy(nbuf, buf, buflen);    nbuf[buflen] = '\0';    hash = xhash_new(101);    in = nbuf;    while(1) {        _opt_get_pair(&in, &key, &val);        if(key == NULL)            break;        sub = xhash_get(hash, key);        if(sub == NULL) {            sub = xhash_new(11);            xhash_put(hash, pstrdup(xhash_pool(hash), key), sub);            pool_cleanup(xhash_pool(hash), (void (*)(void *)) xhash_free, sub);        }        xhash_put(sub, pstrdup(xhash_pool(hash), val), (void *) 1);        log_debug(ZONE, "got key '%s' val '%s'", key, val);    }    free(nbuf);    return hash;}static char *_digest_md5_gen_nonce(void) {    int i, r;    char nonce[65], hnonce[41];    for(i = 0; i < 64; i++) {        r = (int) (36.0 * rand() / RAND_MAX);        nonce[i] = (r >= 0 && r <= 9) ? (r + 48) : (r + 87);    }    nonce[64] = '\0';    shahash_r(nonce, hnonce);    log_debug(ZONE, "generated nonce: %s", hnonce);    return strdup(hnonce);}typedef struct _digest_md5_st {    pool        p;    char        *nonce;    char        *cnonce;    char        *nc;    int         step;} *digest_md5_t;static int _digest_md5_client_start(scod_mech_t mech, scod_t sd, char **resp, int *resplen) {    log_debug(ZONE, "DIGEST-MD5 client start");    return sd_CONTINUE;}static int _digest_md5_client_step(scod_mech_t mech, scod_t sd, const char *chal, int challen, char **resp, int *resplen) {    xht attrs, sub;    char *key, *realm, *nonce, *qop, *charset, *algorithm, *cnonce, *c;    md5_state_t md5;    md5_byte_t hash[16];    char ha1[33], ha2[33], hrsp[33];    pool p;    spool s;    log_debug(ZONE, "DIGEST-MD5 client step; challenge: %.*s", challen, chal);    if(sd->mech_data != NULL) {        /* !!! check rspauth */        sd->mech_data = NULL;        return sd_SUCCESS;    }    realm = nonce = qop = charset = algorithm = NULL;    attrs = _digest_md5_parse_options(chal, challen);    if(xhash_iter_first(attrs))        do {            xhash_iter_get(attrs, (const char **) &key, (void **) &sub);            log_debug(ZONE, "extracting '%s'", key);            if(xhash_iter_first(sub)) {                if(strcmp(key, "realm") == 0)                    (mech->ctx->cb)(sd, sd_cb_DIGEST_MD5_CHOOSE_REALM, (void *) sub, (void **) &realm, mech->ctx->cbarg);                else if(strcmp(key, "nonce") == 0)                    xhash_iter_get(sub, (const char **) &nonce, NULL);                else if(strcmp(key, "qop") == 0)                    xhash_iter_get(sub, (const char **) &qop, NULL);                else if(strcmp(key, "charset") == 0)                    xhash_iter_get(sub, (const char **) &charset, NULL);                else if(strcmp(key, "algorithm") == 0)                    xhash_iter_get(sub, (const char **) &algorithm, NULL);            }        } while(xhash_iter_next(attrs));    if(nonce == NULL || qop == NULL || charset == NULL || algorithm == NULL) {        log_debug(ZONE, "missing attribute");        xhash_free(attrs);        return sd_auth_MALFORMED_DATA;    }    cnonce = _digest_md5_gen_nonce();    md5_init(&md5);    md5_append(&md5, sd->authnid, strlen(sd->authnid));    md5_append(&md5, ":", 1);    if(realm != NULL) md5_append(&md5, realm, strlen(realm));    md5_append(&md5, ":", 1);    md5_append(&md5, sd->pass, strlen(sd->pass));    md5_finish(&md5, hash);    md5_init(&md5);    md5_append(&md5, hash, 16);    md5_append(&md5, ":", 1);    md5_append(&md5, nonce, strlen(nonce));    md5_append(&md5, ":", 1);    md5_append(&md5, cnonce, 40);    if(sd->authzid != NULL) {        md5_append(&md5, ":", 1);        md5_append(&md5, sd->authzid, strlen(sd->authzid));    }    md5_finish(&md5, hash);                         /* A1 */    hex_from_raw(hash, 16, ha1);    log_debug(ZONE, "HEX(H(A1)) = %s", ha1);

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -