#include "jsm.h"
int mod_auth_0k_set(mapi m, jid id, char *hash, char *token, char *sequence)
{
xmlnode x;
if(id == NULL || hash == NULL || token == NULL || sequence == NULL) return 1;
log_debug(ZONE,"saving 0k data");
if(m->user == NULL)
{
if((x = xdb_get(m->si->xc, id, NS_AUTH)) != NULL)
{
xmlnode_free(x);
}else{
log_debug(ZONE,"NS_AUTH flag doesn't exist, creating");
x = xmlnode_new_tag_pool(m->packet->p,"password");
xmlnode_put_attrib(x,"xmlns",NS_AUTH);
if(xdb_set(m->si->xc, id, NS_AUTH, x))
return 1;
}
}
x = xmlnode_new_tag_pool(m->packet->p,"zerok");
xmlnode_put_attrib(x,"xmlns",NS_AUTH_0K);
xmlnode_insert_cdata(xmlnode_insert_tag(x,"hash"),hash,-1);
xmlnode_insert_cdata(xmlnode_insert_tag(x,"token"),token,-1);
xmlnode_insert_cdata(xmlnode_insert_tag(x,"sequence"),sequence,-1);
return xdb_set(m->si->xc, id, NS_AUTH_0K, x);
}
int mod_auth_0k_reset(mapi m, jid id, char *pass)
{
char token[10];
char seqs_default[] = "500";
int sequence, i;
char *seqs, hash[41];
if(pass == NULL) return 1;
log_debug(ZONE,"resetting 0k variables");
seqs = xmlnode_get_tag_data(js_config(m->si, "mod_auth_0k"),"sequences");
if(seqs == NULL)
seqs = seqs_default;
sequence = atoi(seqs);
sprintf(token,"%X",(int)time(NULL));
shahash_r(pass,hash);
shahash_r(spools(m->packet->p,hash,token,m->packet->p),hash);
for(i = 0; i < sequence; i++, shahash_r(hash,hash));
return mod_auth_0k_set(m, id, hash, token, seqs);
}
mreturn mod_auth_0k_go(mapi m, void *enable)
{
char *token, *hash, *seqs, *pass;
char *c_hash = NULL;
int sequence = 0, i;
xmlnode xdb;
if( jpacket_subtype(m->packet) == JPACKET__SET &&
(c_hash = xmlnode_get_tag_data(m->packet->iq,"hash")) == NULL &&
(pass = xmlnode_get_tag_data(m->packet->iq,"password")) == NULL)
return M_PASS;
log_debug(ZONE,"checking");
if((xdb = xdb_get(m->si->xc, m->user->id, NS_AUTH_0K)) == NULL)
{
if(mod_auth_0k_reset(m,m->user->id,m->user->pass))
return M_PASS;
xdb = xdb_get(m->si->xc, m->user->id, NS_AUTH_0K);
}
seqs = xmlnode_get_tag_data(xdb,"sequence");
if(seqs != NULL)
{
sequence = atoi(seqs);
if(sequence > 0)
sprintf(seqs,"%d",sequence - 1);
}
token = xmlnode_get_tag_data(xdb,"token");
hash = xmlnode_get_tag_data(xdb,"hash");
if(jpacket_subtype(m->packet) == JPACKET__GET)
{
if(hash != NULL && token != NULL && sequence > 0)
{
xmlnode_insert_cdata(xmlnode_insert_tag(m->packet->iq,"sequence"),seqs,-1);
xmlnode_insert_cdata(xmlnode_insert_tag(m->packet->iq,"token"),token,-1);
}
xmlnode_free(xdb);
return M_PASS;
}
if(c_hash == NULL && enable)
{
log_debug(ZONE,"generating our own 0k from the plaintext password to match the stored vars");
c_hash = pmalloc(m->packet->p,sizeof(char)*41);
shahash_r(pass,c_hash);
shahash_r(spools(m->packet->p,c_hash,token,m->packet->p),c_hash);
for(i = 1; i < sequence; i++, shahash_r(c_hash,c_hash));
}
log_debug("mod_auth_0k","got client hash %s for sequence %d and token %s",c_hash,sequence,token);
if(j_strcmp(shahash(c_hash), hash) != 0)
{
jutil_error(m->packet->x, TERROR_AUTH);
}else{
xmlnode_hide(xmlnode_get_tag(xdb,"sequence"));
xmlnode_insert_cdata(xmlnode_insert_tag(xdb,"sequence"),seqs,-1);
xmlnode_hide(xmlnode_get_tag(xdb,"hash"));
xmlnode_insert_cdata(xmlnode_insert_tag(xdb,"hash"),c_hash,-1);
xmlnode_put_attrib(xdb,"xmlns",NS_AUTH_0K);
if(xdb_set(m->si->xc, m->user->id, NS_AUTH_0K, xdb))
jutil_error(m->packet->x, TERROR_REQTIMEOUT);
else
jutil_iqresult(m->packet->x);
}
xmlnode_free(xdb);
return M_HANDLED;
}
mreturn mod_auth_0k_reg(mapi m, void *arg)
{
int disable = 1;
jid id;
if(js_config(m->si, "mod_auth_0k/enable_registration") != NULL)
disable = 0;
if(jpacket_subtype(m->packet) == JPACKET__GET)
{
if(!disable)
xmlnode_insert_tag(m->packet->iq,"hash");
return M_PASS;
}
if(m->user == NULL)
id = jid_user(m->packet->to);
else
id = m->user->id;
if(jpacket_subtype(m->packet) != JPACKET__SET) return M_PASS;
if(xmlnode_get_tag_data(m->packet->iq,"password") != NULL)
xdb_set(m->si->xc, id, NS_AUTH_0K, NULL);
if(!disable && xmlnode_get_tag_data(m->packet->iq,"hash") != NULL && mod_auth_0k_set(m,id,xmlnode_get_tag_data(m->packet->iq,"hash"),xmlnode_get_tag_data(m->packet->iq,"token"),xmlnode_get_tag_data(m->packet->iq,"sequence")))
{
jutil_error(m->packet->x,(terror){500,"Authentication Storage Failed"});
return M_HANDLED;
}
return M_PASS;
}
mreturn mod_auth_0k_server(mapi m, void *arg)
{
mreturn ret;
if(m->packet->type != JPACKET_IQ) return M_IGNORE;
if(m->user == NULL) return M_PASS;
if(!NSCHECK(m->packet->iq,NS_REGISTER)) return M_PASS;
ret = mod_auth_0k_reg(m,arg);
if(ret == M_HANDLED)
js_deliver(m->si, jpacket_reset(m->packet));
return ret;
}
void mod_auth_0k(jsmi si)
{
log_warn(NULL,"mod_auth_0k in jsm_apple.so is diabled");
#if 0
void *enable = 0;
log_debug(ZONE,"there goes the neighborhood");
if(js_config(si, "mod_auth_0k/enable_plaintext") != NULL)
enable = (void*)1;
js_mapi_register(si, e_AUTH, mod_auth_0k_go, enable);
js_mapi_register(si, e_SERVER, mod_auth_0k_server, NULL);
if (js_config(si,"register") != NULL) js_mapi_register(si, e_REGISTER, mod_auth_0k_reg, NULL);
#endif
}