#include "c2s.h"
#ifdef HAVE_IDN
#include <stringprep.h>
#endif
#ifdef STORAGE_MYSQL
extern int ar_mysql_init(authreg_t);
#endif
#ifdef STORAGE_PGSQL
extern int ar_pgsql_init(authreg_t);
#endif
#ifdef STORAGE_DB
extern int ar_db_init(authreg_t);
#endif
#ifdef STORAGE_LDAP
extern int ar_ldap_init(authreg_t);
#endif
#ifdef STORAGE_PAM
extern int ar_pam_init(authreg_t);
#endif
#ifdef STORAGE_PIPE
extern int ar_pipe_init(authreg_t);
#endif
#ifdef STORAGE_ANON
extern int ar_anon_init(authreg_t);
#endif
#ifdef STORAGE_SQLITE
extern int ar_sqlite_init(authreg_t);
#endif
char *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
#ifdef STORAGE_SQLITE
"sqlite",
#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
#ifdef STORAGE_SQLITE
ar_sqlite_init,
#endif
NULL
};
typedef struct _authreg_error_st {
char *class;
char *name;
char *code;
char *uri;
} *authreg_error_t;
authreg_t authreg_init(c2s_t c2s, char *name) {
int n;
ar_module_init_fn init = NULL;
authreg_t ar;
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;
}
ar = (authreg_t) malloc(sizeof(struct authreg_st));
memset(ar, 0, sizeof(struct authreg_st));
ar->c2s = c2s;
if((init)(ar) != 0)
{
log_write(c2s->log, LOG_ERR, "failed to initialise auth module '%s'", name);
authreg_free(ar);
return NULL;
}
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;
}
log_write(c2s->log, LOG_NOTICE, "initialised auth module '%s'", name);
return ar;
}
void authreg_free(authreg_t ar) {
if(ar->free != NULL) (ar->free)(ar);
free(ar);
}
static void _authreg_auth_get(c2s_t c2s, sess_t sess, nad_t nad) {
int ns, elem, ssequence, attr, err;
char username[1024], shash[41], stoken[11], seqs[10], id[128];
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);
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
if(!(c2s->ar_mechanisms & (AR_MECH_TRAD_PLAIN | AR_MECH_TRAD_DIGEST | AR_MECH_TRAD_ZEROK | AR_MECH_TRAD_CRAMMD5))) {
sx_nad_write(sess->s, stanza_tofrom(stanza_error(nad, 0, stanza_err_FORBIDDEN), 0));
return;
}
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;
}
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);
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);
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);
if(c2s->ar_mechanisms & AR_MECH_TRAD_CRAMMD5 && c2s->ar->create_challenge != NULL) {
err = (c2s->ar->create_challenge)(c2s->ar, (char *) username, (char *) sess->auth_challenge, sizeof(sess->auth_challenge));
if (0 == err) {
sx_nad_write(sess->s, stanza_tofrom(stanza_error(nad, 0, stanza_err_INTERNAL_SERVER_ERROR), 0));
return;
}
else if (1 == err) {
nad_append_elem(nad, ns, "crammd5", 2);
nad_append_attr(nad, -1, "challenge", sess->auth_challenge);
}
else ;
}
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);
}
sx_nad_write(sess->s, nad);
return;
}
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];
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);
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
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
if(!(c2s->ar_mechanisms & (AR_MECH_TRAD_PLAIN | AR_MECH_TRAD_DIGEST | AR_MECH_TRAD_ZEROK | AR_MECH_TRAD_CRAMMD5))) {
sx_nad_write(sess->s, stanza_tofrom(stanza_error(nad, 0, stanza_err_FORBIDDEN), 0));
return;
}
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;
}
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)
{
ssequence--;
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");
}
}
}
if(!authd && c2s->ar_mechanisms & AR_MECH_TRAD_CRAMMD5 && c2s->ar->check_response != NULL)
{
elem = nad_find_elem(nad, 1, ns, "crammd5", 1);
if(elem >= 0)
{
snprintf(str, 1024, "%.*s", NAD_CDATA_L(nad, elem), NAD_CDATA(nad, elem));
if((c2s->ar->check_response)(c2s->ar, username, sess->realm, sess->auth_challenge, str) == 0)
{
log_debug(ZONE, "crammd5 auth (check) succeded");
authd = 1;
}
}
}
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;
}
}
}
}
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;
}
}
}
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;
}
}
}
if(authd)
{
log_write(c2s->log, LOG_NOTICE, "[%d] auth succeeded: username=%s, resource=%s", sess->s->tag, username, resource);
sprintf(sess->c2s_id, "%d", sess->s->tag);
sess->jid = jid_new(c2s->pc, sess->s->req_to, -1);
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));
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));
sm_start(sess);
nad_free(nad);
return;
}
log_write(c2s->log, LOG_NOTICE, "[%d] auth failed: username=%s, resource=%s", sess->s->tag, username, resource);
sx_nad_write(sess->s, stanza_tofrom(stanza_error(nad, 0, stanza_err_OLD_UNAUTH), 0));
return;
}
static void _authreg_register_get(c2s_t c2s, sess_t sess, nad_t nad) {
int attr, ns;
char id[128];
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;
}
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);
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);
sx_nad_write(sess->s, nad);
}
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(!(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);
if(sess->active && nad_find_elem(nad, 1, ns, "remove", 1) >= 0) {
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");
if(c2s->ar->delete_user == NULL) {
sx_nad_write(sess->s, stanza_tofrom(stanza_error(nad, 0, stanza_err_NOT_ALLOWED), 0));
return;
}
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));
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));
nad_free(nad);
sx_nad_write(sess->s, sess->result);
sess->result = NULL;
sm_delete(sess);
return;
}
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(sess->active)
{
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;
}
}
else if(!c2s->ar_register_enable) {
sx_nad_write(sess->s, stanza_tofrom(stanza_error(nad, 0, stanza_err_NOT_ALLOWED), 0));
return;
}
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;
}
else if(c2s->ar->create_user == NULL)
{
sx_nad_write(sess->s, stanza_tofrom(stanza_error(nad, 0, stanza_err_NOT_ALLOWED), 0));
return;
}
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);
snprintf(password, 257, "%.*s", NAD_CDATA_L(nad, elem), NAD_CDATA(nad, elem));
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;
}
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);
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));
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;
}
sprintf(sess->c2s_id, "%d", sess->s->tag);
sess->jid = jid_new(c2s->pc, sess->s->req_to, -1);
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));
sm_create(sess);
nad_free(nad);
return;
}
int authreg_process(c2s_t c2s, sess_t sess, nad_t nad) {
int ns, query, type, authreg = -1, getset = -1;
if(NAD_ENAME_L(nad, 0) != 2 || strncmp("iq", NAD_ENAME(nad, 0), 2) != 0)
return 1;
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(nad_find_attr(nad, 0, -1, "to", NULL) >= 0 && nad_find_attr(nad, 0, -1, "to", sess->s->req_to) < 0)
return 1;
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;
}
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;
}
if(authreg == 0) {
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);
}
}
return 0;
}