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

📄 authreg.c

📁 这是一个完全开放的
💻 C
📖 第 1 页 / 共 2 页
字号:
    }    /* plaintext auth (check) */    if(!authd && c2s->ar_mechanisms & AR_MECH_TRAD_PLAIN && c2s->ar->check_password != NULL)    {        elem = nad_find_elem(nad, 1, ns, "password", 1);        if(elem >= 0)        {            snprintf(str, 1024, "%.*s", NAD_CDATA_L(nad, elem), NAD_CDATA(nad, elem));            if((c2s->ar->check_password)(c2s->ar, username, sess->realm, str) == 0)            {                log_debug(ZONE, "plaintext auth (check) succeded");                authd = 1;            }        }    }    /* now, are they authenticated? */    if(authd)    {        log_write(c2s->log, LOG_NOTICE, "[%d] auth succeeded: username=%s, resource=%s", sess->s->tag, username, resource);        /* our local id */        sprintf(sess->c2s_id, "%d", sess->s->tag);        /* the full user jid for this session */        sess->jid = jid_new(c2s->pc, sess->s->req_to, 0);        strcpy(sess->jid->node, username);        strcpy(sess->jid->resource, resource);        jid_prep(sess->jid);        log_write(sess->c2s->log, LOG_NOTICE, "[%d] requesting session: jid=%s", sess->s->tag, jid_full(sess->jid));        /* build a result packet, we'll send this back to the client after we have a session for them */        sess->result = nad_new(sess->s->nad_cache);        ns = nad_add_namespace(sess->result, uri_CLIENT, NULL);        nad_append_elem(sess->result, ns, "iq", 0);        nad_set_attr(sess->result, 0, -1, "type", "result", 6);        attr = nad_find_attr(nad, 0, -1, "id", NULL);        if(attr >= 0)            nad_set_attr(sess->result, 0, -1, "id", NAD_AVAL(nad, attr), NAD_AVAL_L(nad, attr));        /* start a session with the sm */        sm_start(sess);        /* finished with the nad */        nad_free(nad);        return;    }    log_write(c2s->log, LOG_NOTICE, "[%d] auth failed: username=%s, resource=%s", sess->s->tag, username, resource);    /* auth failed, so error */    sx_nad_write(sess->s, stanza_tofrom(stanza_error(nad, 0, stanza_err_OLD_UNAUTH), 0));    return;}/** register get handler */static void _authreg_register_get(c2s_t c2s, sess_t sess, nad_t nad) {    int attr, ns;    char id[128];    /* registrations can happen if reg is enabled and we can create users and set passwords */    if(sess->active || !(c2s->ar->set_password != NULL && c2s->ar->create_user != NULL && c2s->ar_register_enable)) {        sx_nad_write(sess->s, stanza_tofrom(stanza_error(nad, 0, stanza_err_NOT_ALLOWED), 0));        return;    }    /* extract the id */    attr = nad_find_attr(nad, 0, -1, "id", NULL);    if(attr >= 0)        snprintf(id, 128, "%.*s", NAD_AVAL_L(nad, attr), NAD_AVAL(nad, attr));    nad_free(nad);    /* build a result packet */    nad = nad_new(sess->s->nad_cache);    ns = nad_add_namespace(nad, uri_CLIENT, NULL);    nad_append_elem(nad, ns, "iq", 0);    nad_append_attr(nad, -1, "type", "result");    if(attr >= 0)        nad_append_attr(nad, -1, "id", id);    ns = nad_add_namespace(nad, "jabber:iq:register", NULL);    nad_append_elem(nad, ns, "query", 1);        nad_append_elem(nad, ns, "username", 2);    nad_append_elem(nad, ns, "password", 2);    nad_append_elem(nad, ns, "instructions", 2);    nad_append_cdata(nad, c2s->ar_register_instructions, strlen(c2s->ar_register_instructions), 3);    /* give it back to the client */    sx_nad_write(sess->s, nad);}/** register set handler */static void _authreg_register_set(c2s_t c2s, sess_t sess, nad_t nad){    int ns = 0, elem, attr, sequence = 500, i;    char username[1024], password[1024], hash[41], token[11], str[51];    /* if we're not configured for registration (or pw changes), or we can't set passwords, fail outright */    if(!(c2s->ar_register_enable || c2s->ar_register_password) || c2s->ar->set_password == NULL) {        sx_nad_write(sess->s, stanza_tofrom(stanza_error(nad, 0, stanza_err_NOT_ALLOWED), 0));        return;    }    ns = nad_find_scoped_namespace(nad, "jabber:iq:register", NULL);    /* removals */    if(sess->active && nad_find_elem(nad, 1, ns, "remove", 1) >= 0) {        /* only if full reg is enabled */        if(!c2s->ar_register_enable) {            sx_nad_write(sess->s, stanza_tofrom(stanza_error(nad, 0, stanza_err_NOT_ALLOWED), 0));            return;        }        log_debug(ZONE, "user remove requested");        /* make sure we can delete them */        if(c2s->ar->delete_user == NULL) {            sx_nad_write(sess->s, stanza_tofrom(stanza_error(nad, 0, stanza_err_NOT_ALLOWED), 0));            return;        }        /* otherwise, delete them */        if((c2s->ar->delete_user)(c2s->ar, sess->jid->node, sess->realm) != 0) {            log_debug(ZONE, "user delete failed");            sx_nad_write(sess->s, stanza_tofrom(stanza_error(nad, 0, stanza_err_INTERNAL_SERVER_ERROR), 0));            return;        }        log_write(c2s->log, LOG_NOTICE, "[%d] deleted user: user=%s; realm=%s", sess->s->tag, sess->jid->node, sess->realm);        log_write(c2s->log, LOG_NOTICE, "[%d] registration remove succeeded, requesting user deletion: jid=%s", sess->s->tag, jid_user(sess->jid));        /* make a result nad */        sess->result = nad_new(sess->s->nad_cache);        ns = nad_add_namespace(sess->result, uri_CLIENT, NULL);        nad_append_elem(sess->result, ns, "iq", 0);        nad_set_attr(sess->result, 0, -1, "type", "result", 6);        /* extract the id */        attr = nad_find_attr(nad, 0, -1, "id", NULL);        if(attr >= 0)            nad_set_attr(sess->result, 0, -1, "id", NAD_AVAL(nad, attr), NAD_AVAL_L(nad, attr));        nad_free(nad);        sx_nad_write(sess->s, sess->result);        sess->result = NULL;        /* get the sm to delete them (it will force their sessions to end) */        sm_delete(sess);        return;    }    /* username is required */    elem = nad_find_elem(nad, 1, ns, "username", 1);    if(elem < 0)    {        log_debug(ZONE, "register set with no username, bouncing it");        sx_nad_write(sess->s, stanza_tofrom(stanza_error(nad, 0, stanza_err_BAD_REQUEST), 0));        return;    }    snprintf(username, 1024, "%.*s", NAD_CDATA_L(nad, elem), NAD_CDATA(nad, elem));#ifdef HAVE_IDN    if(stringprep_xmpp_nodeprep(username, 1024) != 0) {        log_debug(ZONE, "register set username failed nodeprep, bouncing it");        sx_nad_write(sess->s, stanza_tofrom(stanza_error(nad, 0, stanza_err_JID_MALFORMED), 0));        return;    }#endif    elem = nad_find_elem(nad, 1, ns, "password", 1);    if(elem < 0)    {        log_debug(ZONE, "register set with no password, bouncing it");        sx_nad_write(sess->s, stanza_tofrom(stanza_error(nad, 0, stanza_err_BAD_REQUEST), 0));        return;    }    /* if they're already auth'd, its a password change */    if(sess->active)    {        /* confirm that the username matches their auth id */        if(strcmp(username, sess->jid->node) != 0)        {            log_debug(ZONE, "%s is trying to change password for %s, bouncing it", jid_full(sess->jid), username);            sx_nad_write(sess->s, stanza_tofrom(stanza_error(nad, 0, stanza_err_OLD_UNAUTH), 0));            return;        }    }    /* can't go on if we're not doing full reg */    else if(!c2s->ar_register_enable) {        sx_nad_write(sess->s, stanza_tofrom(stanza_error(nad, 0, stanza_err_NOT_ALLOWED), 0));        return;    }    /* if they exist, bounce */    else if((c2s->ar->user_exists)(c2s->ar, username, sess->realm))    {        log_debug(ZONE, "attempt to register %s, but they already exist", username);        sx_nad_write(sess->s, stanza_tofrom(stanza_error(nad, 0, stanza_err_CONFLICT), 0));        return;    }    /* make sure we can create them */    else if(c2s->ar->create_user == NULL)    {        sx_nad_write(sess->s, stanza_tofrom(stanza_error(nad, 0, stanza_err_NOT_ALLOWED), 0));        return;    }    /* otherwise, create them */    else if((c2s->ar->create_user)(c2s->ar, username, sess->realm) != 0)    {        log_debug(ZONE, "user create failed");        sx_nad_write(sess->s, stanza_tofrom(stanza_error(nad, 0, stanza_err_INTERNAL_SERVER_ERROR), 0));        return;    }    else        log_write(c2s->log, LOG_NOTICE, "[%d] created user: user=%s; realm=%s", sess->s->tag, username, sess->realm);    /* extract the password */    snprintf(password, 257, "%.*s", NAD_CDATA_L(nad, elem), NAD_CDATA(nad, elem));    /* change it */    if((c2s->ar->set_password)(c2s->ar, username, sess->realm, password) != 0)    {        log_debug(ZONE, "password store failed");        sx_nad_write(sess->s, stanza_tofrom(stanza_error(nad, 0, stanza_err_INTERNAL_SERVER_ERROR), 0));        return;    }    /* store zerok data if we can */    if(c2s->ar_mechanisms & AR_MECH_TRAD_ZEROK && c2s->ar->set_zerok != NULL)    {        snprintf(token, 11, "%X", (unsigned int) time(NULL));        shahash_r(password, hash);        snprintf(str, 51, "%s%s", hash, token);        shahash_r(str, hash);        for(i = 0; i < sequence; i++)            shahash_r(hash, hash);        hash[40] = '\0';            if((c2s->ar->set_zerok)(c2s->ar, username, sess->realm, hash, token, sequence) != 0)        {            log_debug(ZONE, "zerok store failed");            sx_nad_write(sess->s, stanza_tofrom(stanza_error(nad, 0, stanza_err_INTERNAL_SERVER_ERROR), 0));            return;        }    }    log_debug(ZONE, "updated auth creds for %s", username);    /* make a result nad */    sess->result = nad_new(sess->s->nad_cache);    ns = nad_add_namespace(sess->result, uri_CLIENT, NULL);    nad_append_elem(sess->result, ns, "iq", 0);    nad_set_attr(sess->result, 0, -1, "type", "result", 6);    /* extract the id */    attr = nad_find_attr(nad, 0, -1, "id", NULL);    if(attr >= 0)        nad_set_attr(sess->result, 0, -1, "id", NAD_AVAL(nad, attr), NAD_AVAL_L(nad, attr));    /* if they're active, then this was just a password change, and we're done */    if(sess->active) {        log_write(c2s->log, LOG_NOTICE, "[%d] password changed: jid=%s", sess->s->tag, jid_user(sess->jid));        sx_nad_write(sess->s, sess->result);        sess->result = NULL;        return;    }    /* our local id */    sprintf(sess->c2s_id, "%d", sess->s->tag);    /* the user jid for this transaction */    sess->jid = jid_new(c2s->pc, sess->s->req_to, 0);    strcpy(sess->jid->node, username);    jid_prep(sess->jid);    log_write(c2s->log, LOG_NOTICE, "[%d] registration succeeded, requesting user creation: jid=%s", sess->s->tag, jid_user(sess->jid));    /* get the sm to create them */    sm_create(sess);    nad_free(nad);    return;}/** * processor for iq:auth and iq:register packets * return 0 if handled, 1 if not handled */int authreg_process(c2s_t c2s, sess_t sess, nad_t nad) {    int ns, query, type, authreg = -1, getset = -1;    /* need iq */    if(NAD_ENAME_L(nad, 0) != 2 || strncmp("iq", NAD_ENAME(nad, 0), 2) != 0)        return 1;    /* only want auth or register packets */    if((ns = nad_find_scoped_namespace(nad, "jabber:iq:auth", NULL)) >= 0 && (query = nad_find_elem(nad, 0, ns, "query", 1)) >= 0)        authreg = 0;    else if((ns = nad_find_scoped_namespace(nad, "jabber:iq:register", NULL)) >= 0 && (query = nad_find_elem(nad, 0, ns, "query", 1)) >= 0)        authreg = 1;    else        return 1;    /* if its to someone else, pass it */    if(nad_find_attr(nad, 0, -1, "to", NULL) >= 0 && nad_find_attr(nad, 0, -1, "to", sess->s->req_to) < 0)        return 1;    /* need a type */    if((type = nad_find_attr(nad, 0, -1, "type", NULL)) < 0 || NAD_AVAL_L(nad, type) != 3)    {        sx_nad_write(sess->s, stanza_tofrom(stanza_error(nad, 0, stanza_err_BAD_REQUEST), 0));        return 0;    }    /* get or set? */    if(strncmp("get", NAD_AVAL(nad, type), NAD_AVAL_L(nad, type)) == 0)        getset = 0;    else if(strncmp("set", NAD_AVAL(nad, type), NAD_AVAL_L(nad, type)) == 0)        getset = 1;    else    {        sx_nad_write(sess->s, stanza_tofrom(stanza_error(nad, 0, stanza_err_BAD_REQUEST), 0));        return 0;    }    /* hand to the correct handler */    if(authreg == 0) {        /* can't do iq:auth after sasl auth */        if(sess->sasl_authd) {            sx_nad_write(sess->s, stanza_tofrom(stanza_error(nad, 0, stanza_err_NOT_ALLOWED), 0));            return 0;        }        if(getset == 0) {            log_debug(ZONE, "auth get");            _authreg_auth_get(c2s, sess, nad);        } else if(getset == 1) {            log_debug(ZONE, "auth set");            _authreg_auth_set(c2s, sess, nad);        }    }    if(authreg == 1) {        if(getset == 0) {            log_debug(ZONE, "register get");            _authreg_register_get(c2s, sess, nad);        } else if(getset == 1) {            log_debug(ZONE, "register set");            _authreg_register_set(c2s, sess, nad);        }    }    /* handled */    return 0;}

⌨️ 快捷键说明

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