#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <errno.h>
#include <string.h>
#include <ctype.h>
#include <avl.h>
#include "f00f.h"
#define COOKIESIZE 32
static void auth_intern(presence_t p, char *arg) {
nick_t *v;
char *user;
char *password;
char *vinnie;
PGresult *res = NULL;
pg_trans_t *pg = NULL;
presence_t vp = {0};
if(!arg) {
if(!p.nick->user || p.nick->cred < AUTH_CERTAIN)
say(p, _("Je bent niet geauthenticeerd, %s."), p.nick->name);
else
say(p, _("Je bent geauthenticeerd, %s."), p.nick->user->name);
return;
}
if(unc_readtowritelock(&p)) {
password = match(arg);
if(!password) {
user = p.nick->name;
password = arg;
} else {
user = arg;
}
pg = pg_begin();
if(!pg)
goto end;
res = pg_query(pg, "SELECT checkpassword('%?', '%?')",
user, password);
if(!res || !PQntuples(res))
goto rollback;
if(!strcmp(PQgetvalue(res, 0, 0), "t")) {
setuser(p.nick, newuser(user));
p.nick->cred = AUTH_CERTAIN;
say(p, _("Je hebt je met succes geauthenticeerd, %s."),
p.nick->user->name);
if(!p.nick->vinnie && (v = getnick("Vinnie")) && v->user && v->cred >= AUTH_CERTAIN && !strcasecmp(v->user->name, "Vinnie")) {
res = pg_query(pg, "SELECT username FROM auth_vinnie WHERE luser = (SELECT luser FROM users WHERE name = '%l?')",
p.nick->user->name);
vinnie = pg_getstr(res, 0, 0);
if(vinnie) {
vp.nick = v;
say(vp, "userauth %s %s", user, vinnie);
p.nick->vinnie = xstrdup(vinnie);
}
}
} else {
say(p, _("Authenticatie mislukt."));
}
pg_commit(pg);
goto end;
rollback:
pg_rollback(pg);
}
end:
unc_writetoreadlock(NULL);
}
static void auth_vinnie(char *arg) {
nick_t *k;
user_t *u;
char *user;
authstage_t c;
PGresult *res = NULL;
pg_trans_t *pg = NULL;
int argc;
char **argv;
nettesplitargs(arg, &argc, &argv);
pregister(argv);
if(argc != 3)
return;
if(unc_readtowritelock(NULL)) {
k = getnick(argv[0]);
if(!k) {
eprintf("Vinnie authenticeert iemand die we niet kennen: %s\n", argv[0]);
goto end;
}
xreplace(&k->vinnie, argv[1]);
pg = pg_begin();
if(!pg)
goto end;
res = pg_query(pg, "SELECT getvinnie('%?')", argv[1]);
if(!res || !PQntuples(res))
goto rollback;
user = PQgetvalue(res, 0, 0);
if(!user || !*user)
goto rollback;
u = newuser(PQgetvalue(res, 0, 0));
if(!u)
goto rollback;
if(strcasecmp(argv[2], "CERTAIN"))
c = AUTH_UNKNOWN;
else
c = AUTH_CERTAIN;
if(c > k->cred) {
setuser(k, u);
k->cred = k->vinniecred = c;
}
pg_commit(pg);
goto end;
rollback:
pg_rollback(pg);
}
end:
unc_writetoreadlock(NULL);
}
static void f00f_AUTHENTICATE(presence_t p, char *arg) {
if(p.chan) {
lart(p);
return;
}
if(isuser(p, "Vinnie"))
auth_vinnie(arg);
else
auth_intern(p, arg);
}
static void f00f_DEAUTHENTICATE(presence_t p, char *arg) {
if(unc_readtowritelock(&p)) {
if(p.nick->cred <= 0) {
say(p, _("Je bent niet geauthenticeerd."));
} else {
p.nick->cred = AUTH_UNKNOWN;
xreplace(&p.nick->vinnie, NULL);
say(p, _("Je hebt je succesvol gedeauthenticeerd."));
}
}
unc_writetoreadlock(NULL);
}
static void auth_cookie(presence_t p, char *arg) {
char *user;
PGresult *res = NULL;
pg_trans_t *pg = NULL;
if(unc_readtowritelock(&p)) {
pg = pg_begin();
if(!pg)
goto end;
res = pg_query(pg, "SELECT usecookie('%?')", arg);
if(!res || !PQntuples(res))
goto rollback;
user = PQgetvalue(res, 0, 0);
if(!user || !*user)
goto rollback;
setuser(p.nick, newuser(user));
p.nick->cred = AUTH_CERTAIN;
say(p, _("Je bent nu geauthenticeerd als user \xe2\x80\x98%s\xe2\x80\x99."), user);
pg_commit(pg);
goto end;
rollback:
say(p, _("Authenticatie mislukt."));
pg_rollback(pg);
}
end:
unc_writetoreadlock(NULL);
}
static char *makecookie(void) {
char *cookie;
int i;
cookie = palloc_unaligned(COOKIESIZE + 1);
for(i = 0; i < COOKIESIZE; i++)
i[cookie] = mt_genrand32_bounded(0, 36)["0123456789abcdefghijklmnnopqrstuvwxyz"];
cookie[i] = '\0';
return cookie;
}
static void auth_getcookie(presence_t p) {
char *cookie;
PGresult *res = NULL;
pg_trans_t *pg = NULL;
if(unc_readtowritelock(&p)) {
if(p.nick->cred < 5) {
say(p, _("Je moet je eerst authenticeren."));
goto end;
}
pg = pg_begin();
if(!pg)
goto end;
cookie = makecookie();
res = pg_query(pg, "SELECT addcookie('%?', '%?')", p.nick->user->name, cookie);
if(!res || !PQntuples(res))
goto rollback;
say(p, _("Koekje: %s"), cookie);
pg_commit(pg);
goto end;
rollback:
pg_rollback(pg);
}
end:
unc_writetoreadlock(NULL);
}
static void auth_COOKIE(presence_t p, char *arg) {
if(!arg)
auth_getcookie(p);
else
auth_cookie(p, arg);
}
static void f00f_USER(presence_t p, char *arg) {
user_t *u;
nick_t *k;
avl_node_t *n;
splitbuf_t *q;
if(!checkperms(p, "users"))
return;
q = qnew();
if(!arg) {
qprintf(q, _("\002users\002:"));
for(n = users.head; n; n = n->next) {
qprintf(q, " %s", subuser(n)->name);
}
} else {
u = getuser(arg);
if(!u) {
qprintf(q, _("\002%s\002? Niet gevonden. Sowwy."), arg);
} else {
qprintf(q, "[\002%s\002]", u->name);
for(n = u->nicks.head; n; n = n->next) {
k = n->item;
qprintf(q, " %s(%d)", k->name, k->cred);
if(k->vinnie) {
if(!stricmp(u->name, k->vinnie))
qputc(q, '*');
else
qprintf(q, "[%s]", k->vinnie);
}
}
}
}
sayq(p, q);
qfree(q);
}
static void f00f_NICK(presence_t p, char *arg) {
nick_t *k;
chan_t *c;
avl_node_t *n;
splitbuf_t *q;
if(!checkperms(p, "nicks"))
return;
q = qnew();
if(!arg) {
qprintf(q, _("\002nicks\002:"));
for(n = nicks.head; n; n = n->next) {
k = subnick(n);
qprintf(q, " %s", k->name);
if(k->user) {
qprintf(q, "(");
if(stricmp(k->name, k->user->name))
qprintf(q, "%s:", k->user->name);
qprintf(q, "%d)", k->cred);
}
if(k->vinnie) {
if(k->user && !stricmp(k->user->name, k->vinnie))
qputc(q, '*');
else
qprintf(q, "[%s]", k->vinnie);
}
}
} else {
k = getnick(arg);
if(!k) {
qprintf(q, _("\002%s\002? Niet gevonden. Sowwy."), arg);
} else {
qprintf(q, "[\002%s\002]", k->name);
if(k->user)
qprintf(q, " %s(%d)", k->user->name, k->cred);
if(k->vinnie) {
if(k->user && !stricmp(k->user->name, k->vinnie))
qputc(q, '*');
else
qprintf(q, "[%s]", k->vinnie);
}
for(n = k->chans.head; n; n = n->next) {
c = n->item;
qprintf(q, " %s", c->name);
}
}
}
sayq(p, q);
qfree(q);
}
static void f00f_CHAN(presence_t p, char *arg) {
chan_t *c;
nick_t *u;
avl_node_t *n;
splitbuf_t *q;
if(!checkperms(p, "chans"))
return;
q = qnew();
if(!arg) {
qprintf(q, _("\002channels\002:"));
for(n = chans.head; n; n = n->next) {
c = subchan(n);
qprintf(q, " %s(%d)", c->name, (int)avl_count(&c->nicks));
}
} else {
c = getchan(arg);
if(!c) {
qprintf(q, _("\002%s\002? Niet gevonden. Sowwy."), arg);
} else {
qprintf(q, "[\002%s\002]", c->name);
for(n = c->nicks.head; n; n = n->next) {
u = n->item;
qprintf(q, " %s", u->name);
}
}
}
sayq(p, q);
qfree(q);
}
static void f00f_PASSWORD(presence_t p, char *arg) {
PGresult *res = NULL;
pg_trans_t *pg = NULL;
if(!arg)
return;
if(p.chan) {
lart(p);
return;
}
if(unc_readtowritelock(&p)) {
if(!p.nick->user) {
say(p, _("Ik ken je niet. Misschien moet je je even authenticeren?"));
goto end;
}
if(p.nick->cred < AUTH_CERTAIN) {
say(p, _("Je moet je eerst authenticeren."));
goto end;
}
pg = pg_begin();
if(!pg)
goto end;
res = pg_query(pg, "SELECT setpassword('%?', '%?')",
p.nick->user->name, arg);
if(!res || !PQntuples(res))
goto rollback;
if(!strcmp(PQgetvalue(res, 0, 0), "t"))
say(p, _("Password gewijzigd."));
else
say(p, _("Password wijziging mislukt."));
pg_commit(pg);
goto end;
rollback:
pg_rollback(pg);
} else {
say(p, _("Woeps, mislukt, probeer het zo nog eens!"));
}
end:
unc_writetoreadlock(NULL);
}
static void f00f_VINNIE(presence_t p, char *arg) {
PGresult *res = NULL;
pg_trans_t *pg = NULL;
if(unc_readtowritelock(&p)) {
if(!p.nick->user) {
say(p, _("Ik ken je niet. Misschien moet je je even authenticeren?"));
goto end;
}
if(p.nick->cred < AUTH_CERTAIN) {
say(p, _("Je moet je eerst authenticeren."));
goto end;
}
if(!p.nick->vinnie) {
say(p, _("Je moet je ook even bij Vinnie authenticeren."));
goto end;
}
pg = pg_begin();
if(!pg)
goto end;
res = pg_query(pg, "SELECT setvinnie('%?', '%?')",
p.nick->user->name, p.nick->vinnie);
if(!res || !PQntuples(res))
goto rollback;
if(!strcmp(PQgetvalue(res, 0, 0), "t"))
say(p, _("Je bent nu geassocieerd met user \xe2\x80\x98%s\xe2\x80\x99 in Vinnie's database."), p.nick->vinnie);
else
say(p, _("Associatie mislukt."));
pg_commit(pg);
goto end;
rollback:
pg_rollback(pg);
} else {
say(p, _("Woeps, mislukt, probeer het zo nog eens!"));
}
end:
unc_writetoreadlock(NULL);
}
static void f00f_DEVINNIE(presence_t p, char *arg) {
PGresult *res = NULL;
pg_trans_t *pg = NULL;
if(unc_readtowritelock(&p)) {
if(!p.nick || !p.nick->user) {
say(p, _("Ik ken je niet. Misschien moet je je even authenticeren?"));
goto end;
}
if(p.nick->cred < AUTH_CERTAIN) {
say(p, _("Je moet je eerst authenticeren."));
goto end;
}
pg = pg_begin();
if(!pg)
goto end;
res = pg_query(pg, "SELECT unsetvinnie('%?')",
p.nick->user->name);
if(!res || !PQntuples(res))
goto rollback;
if(!strcmp(PQgetvalue(res, 0, 0), "t"))
say(p, _("Je bent gedissocieerd met Vinnie's database."));
else
say(p, _("Dissociatie mislukt."));
pg_commit(pg);
goto end;
rollback:
pg_rollback(pg);
}
end:
unc_writetoreadlock(NULL);
}
static void f00f_ADDUSER(presence_t p, char *arg) {
user_t *u;
nick_t *k;
char *user;
PGresult *res = NULL;
pg_trans_t *pg = NULL;
presence_t np = {0};
if(!arg)
return;
if(unc_readtowritelock(&p)) {
if(!checkperms(p, "adduser"))
goto end;
user = match(arg) ?: arg;
k = getnick(arg);
u = dbuser(user);
np.nick = k;
if(!k) {
say(p, _("Die nick bestaat niet!"));
goto end;
}
if(u) {
setuser(k, u);
k->cred = AUTH_CERTAIN;
say(p, _("%s is nu geauthenticeerd als user \xe2\x80\x98%s\xe2\x80\x99."), k->name, u->name);
say(np, _("Je bent nu geauthenticeerd als user \xe2\x80\x98%s\xe2\x80\x99."), u->name);
goto end;
}
pg = pg_begin();
if(!pg)
goto end;
res = pg_query(pg, "SELECT adduser('%?')", user);
if(!res || !PQntuples(res))
goto rollback;
if(!strcmp(PQgetvalue(res, 0, 0), "t")) {
setuser(k, u = newuser(user));
k->cred = AUTH_CERTAIN;
say(p, _("%s toegevoegd als user %s."), k->name, u->name);
say(np, _("Je bent toegevoegd als user \xe2\x80\x98%s\xe2\x80\x99."), u->name);
say(np, _("Gebruik !password om een password in te stellen."));
} else {
say(p, _("Toevoegen user mislukt."));
}
pg_commit(pg);
goto end;
rollback:
pg_rollback(pg);
}
end:
unc_writetoreadlock(NULL);
}
static void f00f_KOEKJE(presence_t p, char *arg) {
if(p.chan)
appreciate(p, arg, "koekje");
else
auth_COOKIE(p, arg);
}
static tab_entry_t command_tab_entries[] = {
{"AUTH", f00f_AUTHENTICATE},
{"AUTHENTICATE", f00f_AUTHENTICATE},
{"COOKIE", f00f_KOEKJE},
{"DEAUTH", f00f_DEAUTHENTICATE},
{"DEAUTHENTICATE", f00f_DEAUTHENTICATE},
{"GEBRUIKER", f00f_USER},
{"GEBRUIKERS", f00f_USER},
{"USER", f00f_USER},
{"USERS", f00f_USER},
{"BIJNAAM", f00f_NICK},
{"BIJNAMEN", f00f_NICK},
{"NICK", f00f_NICK},
{"NICKS", f00f_NICK},
{"CHAN", f00f_CHAN},
{"CHANS", f00f_CHAN},
{"KANAAL", f00f_CHAN},
{"KANALEN", f00f_CHAN},
{"KOEKJE", f00f_KOEKJE},
{"PASS", f00f_PASSWORD},
{"PASSWORD", f00f_PASSWORD},
{"PASWOORD", f00f_PASSWORD},
{"WACHTWOORD", f00f_PASSWORD},
{"VINNIE", f00f_VINNIE},
{"DEVINNIE", f00f_DEVINNIE},
{"ONTVINNIE", f00f_DEVINNIE},
{"ADDUSER", f00f_ADDUSER},
{"PAT", f00f_KOEKJE},
{"BRAAF", f00f_KOEKJE},
};
TAB_REGISTER(command);