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

📄 authreg.c

📁 这是一个完全开放的
💻 C
📖 第 1 页 / 共 2 页
字号:
/* * jabberd - Jabber Open Source Server * Copyright (c) 2002 Jeremie Miller, Thomas Muldowney, *                    Ryan Eatmon, 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 */#include "c2s.h"#ifdef HAVE_IDN#include <stringprep.h>#endif/* authreg module manager *//* if you add a module, you'll need to update these arrays */#ifdef STORAGE_MYSQLextern int ar_mysql_init(authreg_t);#endif#ifdef STORAGE_PGSQLextern int ar_pgsql_init(authreg_t);#endif#ifdef STORAGE_DBextern int ar_db_init(authreg_t);#endif#ifdef STORAGE_LDAPextern int ar_ldap_init(authreg_t);#endif#ifdef STORAGE_PAMextern int ar_pam_init(authreg_t);#endif#ifdef STORAGE_PIPEextern int ar_pipe_init(authreg_t);#endif#ifdef STORAGE_ANONextern int ar_anon_init(authreg_t);#endifchar *module_names[] = {#ifdef STORAGE_MYSQL    "mysql",#endif#ifdef STORAGE_PGSQL    "pgsql",#endif#ifdef STORAGE_DB    "db",#endif#ifdef STORAGE_LDAP    "ldap",#endif#ifdef STORAGE_PAM    "pam",#endif#ifdef STORAGE_PIPE    "pipe",#endif#ifdef STORAGE_ANON    "anon",#endif    NULL};ar_module_init_fn module_inits[] = {#ifdef STORAGE_MYSQL    ar_mysql_init,#endif#ifdef STORAGE_PGSQL    ar_pgsql_init,#endif#ifdef STORAGE_DB    ar_db_init,#endif#ifdef STORAGE_LDAP    ar_ldap_init,#endif#ifdef STORAGE_PAM    ar_pam_init,#endif#ifdef STORAGE_PIPE    ar_pipe_init,#endif#ifdef STORAGE_ANON    ar_anon_init,#endif    NULL};typedef struct _authreg_error_st {    char        *class;    char        *name;    char        *code;    char        *uri;} *authreg_error_t;/** get a handle for the named module */authreg_t authreg_init(c2s_t c2s, char *name) {    int n;    ar_module_init_fn init = NULL;    authreg_t ar;    /* hunt it down */    n = 0;    while(module_names[n] != NULL)    {        if(strcmp(module_names[n], name) == 0)        {            init = module_inits[n];            break;        }        n++;    }    if(init == NULL)    {        log_write(c2s->log, LOG_ERR, "no such auth module '%s'", name);        return NULL;    }    /* make a new one */    ar = (authreg_t) malloc(sizeof(struct authreg_st));    memset(ar, 0, sizeof(struct authreg_st));    ar->c2s = c2s;    /* call the initialiser */    if((init)(ar) != 0)    {        log_write(c2s->log, LOG_ERR, "failed to initialise auth module '%s'", name);        authreg_free(ar);        return NULL;    }    /* we need user_exists(), at the very least */    if(ar->user_exists == NULL)    {        log_write(c2s->log, LOG_ERR, "auth module '%s' has no check for user existence", name);        authreg_free(ar);        return NULL;    }        /* its good */    log_write(c2s->log, LOG_NOTICE, "initialised auth module '%s'", name);    return ar;}/** shutdown the authreg system */void authreg_free(authreg_t ar) {    if(ar->free != NULL) (ar->free)(ar);    free(ar);}/** auth get handler */static void _authreg_auth_get(c2s_t c2s, sess_t sess, nad_t nad) {    int ns, elem, ssequence, attr;    char username[1024], shash[41], stoken[11], seqs[10], id[128];    /* can't auth if they're active */    if(sess->active) {        sx_nad_write(sess->s, stanza_tofrom(stanza_error(nad, 0, stanza_err_NOT_ALLOWED), 0));        return;    }    /* sort out the username */    ns = nad_find_scoped_namespace(nad, "jabber:iq:auth", NULL);    elem = nad_find_elem(nad, 1, ns, "username", 1);    if(elem < 0)    {        log_debug(ZONE, "auth get 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, "auth get username failed nodeprep, bouncing it");        sx_nad_write(sess->s, stanza_tofrom(stanza_error(nad, 0, stanza_err_JID_MALFORMED), 0));        return;    }#endif    /* no point going on if we have no mechanisms */    if(!(c2s->ar_mechanisms & (AR_MECH_TRAD_PLAIN | AR_MECH_TRAD_DIGEST | AR_MECH_TRAD_ZEROK))) {        sx_nad_write(sess->s, stanza_tofrom(stanza_error(nad, 0, stanza_err_FORBIDDEN), 0));        return;    }        /* do we have the user? */    if((c2s->ar->user_exists)(c2s->ar, username, sess->realm) == 0) {        sx_nad_write(sess->s, stanza_tofrom(stanza_error(nad, 0, stanza_err_OLD_UNAUTH), 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:auth", NULL);    nad_append_elem(nad, ns, "query", 1);        nad_append_elem(nad, ns, "username", 2);    nad_append_cdata(nad, username, strlen(username), 3);    nad_append_elem(nad, ns, "resource", 2);    /* fill out the packet with available auth mechanisms */    if(c2s->ar_mechanisms & AR_MECH_TRAD_PLAIN && (c2s->ar->get_password != NULL || c2s->ar->check_password != NULL))        nad_append_elem(nad, ns, "password", 2);    if(c2s->ar_mechanisms & AR_MECH_TRAD_DIGEST && c2s->ar->get_password != NULL)        nad_append_elem(nad, ns, "digest", 2);    /* don't offer zerok if the sequence is zero */    if(c2s->ar_mechanisms & AR_MECH_TRAD_ZEROK && c2s->ar->get_zerok != NULL && c2s->ar->set_zerok != NULL && (c2s->ar->get_zerok)(c2s->ar, username, sess->realm, shash, stoken, &ssequence) == 0 && ssequence > 0)    {        snprintf(seqs, 10, "%d", ssequence - 1);        nad_append_elem(nad, ns, "sequence", 2);        nad_append_cdata(nad, seqs, strlen(seqs), 3);        nad_append_elem(nad, ns, "token", 2);        nad_append_cdata(nad, stoken, strlen(stoken), 3);    }    /* give it back to the client */    sx_nad_write(sess->s, nad);    return;}/** auth set handler */static void _authreg_auth_set(c2s_t c2s, sess_t sess, nad_t nad) {    int ns, elem, attr, authd = 0, ssequence;    char username[1024], resource[1024], str[1024], shash[41], stoken[11], hash[280];    /* can't auth if they're active */    if(sess->active) {        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:auth", NULL);    /* sort out the username */    elem = nad_find_elem(nad, 1, ns, "username", 1);    if(elem < 0)    {        log_debug(ZONE, "auth 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, "auth set username failed nodeprep, bouncing it");        sx_nad_write(sess->s, stanza_tofrom(stanza_error(nad, 0, stanza_err_JID_MALFORMED), 0));        return;    }#endif    /* make sure we have the resource */    elem = nad_find_elem(nad, 1, ns, "resource", 1);    if(elem < 0)    {        log_debug(ZONE, "auth set with no resource, bouncing it");        sx_nad_write(sess->s, stanza_tofrom(stanza_error(nad, 0, stanza_err_BAD_REQUEST), 0));        return;    }    snprintf(resource, 1024, "%.*s", NAD_CDATA_L(nad, elem), NAD_CDATA(nad, elem));#ifdef HAVE_IDN    if(stringprep_xmpp_resourceprep(resource, 1024) != 0) {        log_debug(ZONE, "auth set resource failed resourceprep, bouncing it");        sx_nad_write(sess->s, stanza_tofrom(stanza_error(nad, 0, stanza_err_JID_MALFORMED), 0));        return;    }#endif    /* no point going on if we have no mechanisms */    if(!(c2s->ar_mechanisms & (AR_MECH_TRAD_PLAIN | AR_MECH_TRAD_DIGEST | AR_MECH_TRAD_ZEROK))) {        sx_nad_write(sess->s, stanza_tofrom(stanza_error(nad, 0, stanza_err_FORBIDDEN), 0));        return;    }        /* do we have the user? */    if((c2s->ar->user_exists)(c2s->ar, username, sess->realm) == 0) {        sx_nad_write(sess->s, stanza_tofrom(stanza_error(nad, 0, stanza_err_OLD_UNAUTH), 0));        return;    }        /* zerok auth */    if(!authd && c2s->ar_mechanisms & AR_MECH_TRAD_ZEROK && c2s->ar->get_zerok != NULL && c2s->ar->set_zerok != NULL && (c2s->ar->get_zerok)(c2s->ar, username, sess->realm, shash, stoken, &ssequence) == 0)    {        elem = nad_find_elem(nad, 1, ns, "hash", 1);        if(elem >= 0)        {            snprintf(hash, 41, "%.*s", NAD_CDATA_L(nad, elem), NAD_CDATA(nad, elem));            shahash_r(hash, hash);            if(strcmp(hash, shash) == 0)            {                /* update the auth creds */                ssequence--;                /* don't auth them if we can't update their auth creds */                snprintf(str, 41, "%.*s", NAD_CDATA_L(nad, elem), NAD_CDATA(nad, elem));                if((c2s->ar->set_zerok)(c2s->ar, username, sess->realm, str, stoken, ssequence) == 0)                {                    authd = 1;                    log_debug(ZONE, "zerok auth succeeded");                }                else                    log_debug(ZONE, "couldn't update auth creds, not allowing zerok auth");            }        }    }    /* digest auth */    if(!authd && c2s->ar_mechanisms & AR_MECH_TRAD_DIGEST && c2s->ar->get_password != NULL)    {        elem = nad_find_elem(nad, 1, ns, "digest", 1);        if(elem >= 0)        {            if((c2s->ar->get_password)(c2s->ar, username, sess->realm, str) == 0)            {                snprintf(hash, 280, "%s%s", sess->s->id, str);                shahash_r(hash, hash);                if(strlen(hash) == NAD_CDATA_L(nad, elem) && strncmp(hash, NAD_CDATA(nad, elem), NAD_CDATA_L(nad, elem)) == 0)                {                    log_debug(ZONE, "digest auth succeeded");                    authd = 1;                }            }        }    }    /* plaintext auth (compare) */    if(!authd && c2s->ar_mechanisms & AR_MECH_TRAD_PLAIN && c2s->ar->get_password != NULL)    {        elem = nad_find_elem(nad, 1, ns, "password", 1);        if(elem >= 0)        {            if((c2s->ar->get_password)(c2s->ar, username, sess->realm, str) == 0 && strlen(str) == NAD_CDATA_L(nad, elem) && strncmp(str, NAD_CDATA(nad, elem), NAD_CDATA_L(nad, elem)) == 0)            {                log_debug(ZONE, "plaintext auth (compare) succeeded");                authd = 1;            }        }

⌨️ 快捷键说明

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