return csa_completeauth(sender, rup, authtype);
}
+int csa_doauth(void *source, int cargc, char **cargv) {
+ return csa_auth(source, cargc, cargv, NULL);
+}
+
int csa_completeauth(nick *sender, reguser *rup, char *authtype) {
- int toomanyauths=0;
- time_t now, oldlastauth;
- char userhost[USERLEN+HOSTLEN+2];
- nick *onp;
void *args[2];
- authname *anp;
-
- /* This should never fail but do something other than crashing if it does. */
- if (!(anp=findauthname(rup->ID))) {
- chanservstdmessage(sender, QM_AUTHFAIL);
- return CMD_ERROR;
- }
-
- /* Check for too many auths. Don't return immediately, since we will still warn
- * other users on the acct in this case. */
- if (!UHasStaffPriv(rup) && !UIsNoAuthLimit(rup)) {
- if (anp->usercount >= MAXAUTHCOUNT) {
- chanservstdmessage(sender, QM_TOOMANYAUTHS);
- toomanyauths=1;
- }
- }
-
- for (onp=anp->nicks;onp;onp=onp->nextbyauthname) {
- if (toomanyauths) {
- chanservstdmessage(onp, QM_OTHERUSERAUTHEDLIMIT, sender->nick, sender->ident, sender->host->name->content, MAXAUTHCOUNT);
- } else {
- chanservstdmessage(onp, QM_OTHERUSERAUTHED, sender->nick, sender->ident, sender->host->name->content);
- }
- }
-
- if (toomanyauths)
- return CMD_ERROR;
+ time_t oldlastauth;
- now=time(NULL);
-
- if (UHasSuspension(rup) && rup->suspendexp && (now >= rup->suspendexp)) {
- /* suspension has expired, remove it */
- rup->flags&=(~(QUFLAG_SUSPENDED|QUFLAG_GLINE|QUFLAG_DELAYEDGLINE));
- rup->suspendby=0;
- rup->suspendexp=0;
- freesstring(rup->suspendreason);
- rup->suspendreason=0;
- csdb_updateuser(rup);
- }
-
- if (UIsSuspended(rup)) {
- /* plain suspend */
- chanservstdmessage(sender, QM_AUTHSUSPENDED);
- if(rup->suspendreason)
- chanservstdmessage(sender, QM_REASON, rup->suspendreason->content);
- if (rup->suspendexp)
- chanservstdmessage(sender, QM_EXPIRES, rup->suspendexp);
- return CMD_ERROR;
- }
- if (UIsInactive(rup)) {
- chanservstdmessage(sender, QM_INACTIVEACCOUNT);
- return CMD_ERROR;
- }
-
- /* Guarantee a unique auth timestamp for each account */
oldlastauth=rup->lastauth;
-
- if (rup->lastauth < now)
- rup->lastauth=now;
- else
- rup->lastauth++;
-
- sprintf(userhost,"%s@%s",sender->ident,sender->host->name->content);
- if (rup->lastuserhost)
- freesstring(rup->lastuserhost);
- rup->lastuserhost=getsstring(userhost,USERLEN+HOSTLEN+1);
-
- csdb_updateuser(rup);
- cs_log(sender,"%s OK username %s", authtype,rup->username);
+ if(!csa_completeauth2(rup, sender->nick, sender->ident, sender->host->name->content, authtype, chanservstdmessage, sender))
+ return CMD_ERROR;
localusersetaccount(sender, rup->username, rup->ID, cs_accountflagmap(rup), rup->lastauth);
args[0]=sender;
args[1]=(void *)oldlastauth;
+ /* note: not triggered for REMOTEAUTH */
triggerhook(HOOK_CHANSERV_AUTH, args);
return CMD_OK;
}
-
-int csa_doauth(void *source, int cargc, char **cargv) {
- return csa_auth(source, cargc, cargv, NULL);
-}
return rup;
}
+
+int csa_completeauth2(reguser *rup, char *nickname, char *ident, char *hostname, char *authtype, void (*reply)(nick *, int, ...), nick *reply_to) {
+ int toomanyauths=0;
+ time_t now;
+ char userhost[USERLEN+HOSTLEN+2];
+ nick *onp;
+ authname *anp;
+
+ /* This should never fail but do something other than crashing if it does. */
+ if (!(anp=findauthname(rup->ID))) {
+ reply(reply_to, QM_AUTHFAIL);
+ return 0;
+ }
+
+ /* Check for too many auths. Don't return immediately, since we will still warn
+ * other users on the acct in this case. */
+ if (!UHasStaffPriv(rup) && !UIsNoAuthLimit(rup)) {
+ if (anp->usercount >= MAXAUTHCOUNT) {
+ reply(reply_to, QM_TOOMANYAUTHS);
+ toomanyauths=1;
+ }
+ }
+
+ for (onp=anp->nicks;onp;onp=onp->nextbyauthname) {
+ if (toomanyauths) {
+ chanservstdmessage(onp, QM_OTHERUSERAUTHEDLIMIT, nickname, ident, hostname, MAXAUTHCOUNT);
+ } else {
+ chanservstdmessage(onp, QM_OTHERUSERAUTHED, nickname, ident, hostname);
+ }
+ }
+
+ if (toomanyauths)
+ return 0;
+
+ now=time(NULL);
+
+ if (UHasSuspension(rup) && rup->suspendexp && (now >= rup->suspendexp)) {
+ /* suspension has expired, remove it */
+ rup->flags&=(~(QUFLAG_SUSPENDED|QUFLAG_GLINE|QUFLAG_DELAYEDGLINE));
+ rup->suspendby=0;
+ rup->suspendexp=0;
+ freesstring(rup->suspendreason);
+ rup->suspendreason=0;
+ csdb_updateuser(rup);
+ }
+
+ if (UIsSuspended(rup)) {
+ /* plain suspend */
+ reply(reply_to, QM_AUTHSUSPENDED);
+ if(rup->suspendreason)
+ reply(reply_to, QM_REASON, rup->suspendreason->content);
+ if (rup->suspendexp)
+ reply(reply_to, QM_EXPIRES, rup->suspendexp);
+ return 0;
+ }
+ if (UIsInactive(rup)) {
+ reply(reply_to, QM_INACTIVEACCOUNT);
+ return 0;
+ }
+
+ /* Guarantee a unique auth timestamp for each account */
+ if (rup->lastauth < now)
+ rup->lastauth=now;
+ else
+ rup->lastauth++;
+
+ sprintf(userhost,"%s@%s",ident,hostname);
+ if (rup->lastuserhost)
+ freesstring(rup->lastuserhost);
+ rup->lastuserhost=getsstring(userhost,USERLEN+HOSTLEN+1);
+
+ csdb_updateuser(rup);
+
+ cs_log(NULL,"%s!%s@%s [noauth] %s OK username %s",nickname,ident,hostname,authtype,rup->username);
+
+ return 1;
+}
int csa_checkeboy_r(char *eboy);
int csa_checkpasswordquality(char *password);
reguser *csa_createaccount(char *username, char *password, char *email);
+int csa_completeauth2(reguser *rup, char *nickname, char *ident, char *hostname, char *authtype, void (*reply)(nick *, int, ...), nick *reply_to);
void chanservcommandinit();
void chanservcommandclose();
void chanservstdmessage(nick *np, int messageid, ... );
+void chanservstdvmessage(nick *np, reguser *rup, int messageid, int max_line_len, void (*callback)(nick *, char *), va_list va);
void chanservaddcommand(char *command, int flags, int maxparams, CommandHandler handler, char *description, const char *help);
void chanservremovecommand(char *command, CommandHandler handler);
void chanservaddctcpcommand(char *command, CommandHandler hander);
int csa_doresendemail(void *source, int cargc, char **cargv);
int csa_doactivateuser(void *source, int cargc, char **cargv);
int csa_doaddchan(void *source, int argc, char **argv);
+int csa_doremoteauth(void *source, int argc, char **argv);
+
static int decrypt_password(unsigned char *secret, int keybits, char *buf, int bufsize, char *encrypted);
static int hex_to_int(char *input, unsigned char *buf, int buflen);
registercontrolhelpcmd("resendemail", NO_RELAY, 1, csa_doresendemail, "Usage: resendemail <userid>");
registercontrolhelpcmd("activateuser", NO_RELAY, 1, csa_doactivateuser, "Usage: activateuser <userid>");
registercontrolhelpcmd("addchan", NO_RELAY, 3, csa_doaddchan, "Usage: addchan <channel> <userid> <channel type>");
+ registercontrolhelpcmd("remoteauth", NO_RELAY, 6, csa_doremoteauth, "Usage: remoteauth <username> <digest> <junk> <nick> <ident> <host>");
s=getcopyconfigitem("chanserv","createaccountsecret","",128);
if(!s || !s->content || !s->content[0]) {
return CMD_OK;
}
+static void controlremotereply(nick *target, char *message) {
+ controlreply(target, "CHECKHASHPASS FAIL text %s", message);
+}
+
+static void remote_reply(nick *sender, int message_id, ...) {
+ va_list va;
+ va_start(va, message_id);
+ chanservstdvmessage(sender, NULL, message_id, -1 * (int)(strlen("CHECKHASHPASS FAIL text ")), controlremotereply, va);
+ va_end(va);
+}
+
+int csa_doremoteauth(void *source, int cargc, char **cargv) {
+ nick *sender=(nick *)source;
+ reguser *rup;
+
+ if(cargc<6) {
+ controlreply(sender, "REMOTEAUTH FAIL args");
+ controlreply(sender, "REMOTEAUTH END");
+ return CMD_ERROR;
+ }
+
+ char *account = cargv[0];
+ char *digest = cargv[1];
+ char *junk = cargv[2];
+ char *nick = cargv[3];
+ char *ident = cargv[4];
+ char *hostname = cargv[5];
+
+ if (!(rup=findreguserbynick(account))) {
+ controlreply(sender, "REMOTEAUTH FAIL user");
+ controlreply(sender, "REMOTEAUTH END");
+ return CMD_ERROR;
+ }
+
+ if(!checkhashpass(rup, junk, digest)) {
+ controlreply(sender, "REMOTEAUTH FAIL digest");
+ controlreply(sender, "REMOTEAUTH END");
+ return CMD_ERROR;
+ }
+
+ if (!csa_completeauth2(rup, nick, ident, hostname, "REMOTEAUTH", remote_reply, sender)) {
+ controlreply(sender, "REMOTEAUTH END");
+ return CMD_ERROR;
+ }
+
+ /* username:ts:authid */
+ controlreply(sender, "REMOTEAUTH OK %s %ld %ld", rup->username, rup->lastauth ? rup->lastauth : getnettime(), rup->ID);
+
+ /* note: NO HOOK_CHANSERV_AUTH */
+
+ return CMD_OK;
+}
+
static char *email_to_error(char *email) {
maildomain *mdp, *smdp;
char *local;
}
}
-void chanservstdmessage(nick *np, int messageid, ... ) {
+static void __chanservstdvmessage(nick *np, reguser *rup, int messageid, int max_line_len, void (*callback)(nick *, char *), ...) {
+ va_list va;
+ va_start(va, callback);
+ chanservstdvmessage(np, rup, messageid, max_line_len, callback, va);
+ va_end(va);
+}
+
+void chanservstdvmessage(nick *np, reguser *rup, int messageid, int max_line_len, void (*callback)(nick *, char *), va_list va) {
char buf[5010];
char buf2[512];
- int notice;
- reguser *rup;
int language;
- va_list va, va2;
+ va_list va2;
char *message, *messageargs;
char *bp2,*bp;
int len;
- if (getreguserfromnick(np) == NULL) {
- notice=1;
+ if(max_line_len <= 0)
+ max_line_len = 490 + max_line_len;
+
+ if (rup == NULL) {
language=0;
} else {
- rup=getreguserfromnick(np);
- if(UIsNotice(rup)) {
- notice=1;
- } else {
- notice=0;
- }
language=rup->languageid;
}
messageargs=defaultmessages[messageid*2+1];
- va_start(va,messageid);
va_copy(va2, va);
q9vsnprintf(buf,5000,message,messageargs,va);
- va_end(va);
len=0;
bp2=buf2;
for (bp=buf; ;bp++) {
/* We send something if we hit a \n, fill the buffer or run out of source */
- if (*bp=='\n' || len>490 || !*bp) {
+ if (*bp=='\n' || len>max_line_len || !*bp) {
if (*bp && *bp!='\n') {
bp--;
}
*bp2='\0';
- if (chanservnick && *buf2) {
- if (notice) {
- sendnoticetouser(chanservnick,np,"%s",buf2);
- } else {
- sendmessagetouser(chanservnick,np,"%s",buf2);
- }
- }
+ if (chanservnick && *buf2)
+ callback(np, buf2);
/* If we ran out of buffer, get out here */
if (!*bp)
if (messageid==QM_NOTENOUGHPARAMS) {
char *command=va_arg(va2, char *);
cs_sendhelp(np, command, 1);
- chanservstdmessage(np, QM_TYPEHELPFORHELP, command);
+ __chanservstdvmessage(np, rup, QM_TYPEHELPFORHELP, max_line_len, callback, command);
}
va_end(va2);
}
+static void message_callback(nick *np, char *buf) {
+ sendmessagetouser(chanservnick,np,"%s",buf);
+}
+
+static void notice_callback(nick *np, char *buf) {
+ sendnoticetouser(chanservnick,np,"%s",buf);
+}
+
+void chanservstdmessage(nick *np, int messageid, ...) {
+ reguser *rup;
+ va_list va;
+ int notice;
+
+ rup = getreguserfromnick(np);
+ notice = rup == NULL ? 1 : UIsNotice(rup);
+
+ va_start(va, messageid);
+ chanservstdvmessage(np, rup, messageid, 0, notice ? notice_callback : message_callback, va);
+ va_end(va);
+}
+
void chanservsendmessage_real(nick *np, int oneline, char *message, ... ) {
char buf[5010]; /* Very large buffer.. */
char buf2[512], *bp, *bp2;
/* 501 spare for now */
#define HOOK_CHANSERV_RUNNING 502 /* No arg */
-#define HOOK_CHANSERV_AUTH 503 /* Argument is void*[2] (nick *, lastauth) */
+#define HOOK_CHANSERV_AUTH 503 /* Argument is void*[2] (nick *, lastauth) */ /* note: not triggered for REMOTEAUTH */
#define HOOK_CHANSERV_PWCHANGE 504 /* Argument is nick * */
#define HOOK_CHANSERV_CHANLEVMOD 505 /* Argument is void*[3] (nick *, regchanuser *, oldflags) */
#define HOOK_CHANSERV_CHANLEVDUMP 506 /* Argument is nick * */