]> jfr.im git - irc/quakenet/newserv.git/commitdiff
CHANSERV: add REMOTEAUTH command 58/head
authorChris Porter <redacted>
Mon, 10 Jul 2017 21:42:15 +0000 (22:42 +0100)
committerChris Porter <redacted>
Mon, 10 Jul 2017 22:29:42 +0000 (23:29 +0100)
chanserv/authcmds/auth.c
chanserv/authlib.c
chanserv/authlib.h
chanserv/chanserv.h
chanserv/chanserv_relay.c
chanserv/chanservuser.c
core/hooks.h

index ab9ce2271ab963cf1d4b0df7c62cc4ab08366877..3adc7f35cf6aba39a219ce1f79b8170562f6456e 100644 (file)
@@ -80,82 +80,18 @@ int csa_auth(void *source, int cargc, char **cargv, CRAlgorithm alg) {
   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);
 
@@ -163,11 +99,8 @@ int csa_completeauth(nick *sender, reguser *rup, char *authtype) {
 
   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);
-}
index 6ff0d386c4894a57e4c512c144ab2d50ab2eb9e8..def32b61f755cbcad33adb47e08583674fc7ff20 100644 (file)
@@ -197,3 +197,80 @@ reguser *csa_createaccount(char *username, char *password, char *email) {
 
   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;
+}
index 246d6d79d6bad834485671090e62a181c25dc3c5..a6868f1373b2de481f0a75145be05d6a87d5c1e9 100644 (file)
@@ -13,3 +13,4 @@ int csa_checkaccountname_r(char *accountname);
 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);
index bd5c613cd5a08684c74ad8250bef81894e59f594..6b94adb18f5a8f66be07259dca7246a3ccc2bbb0 100644 (file)
@@ -851,6 +851,7 @@ void chanservwallmessage(char *message, ... ) __attribute__ ((format (printf, 1,
 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);
index 6180612ec0514f10962d467547cc1da434bc9a90..d7464431951136e461d837813f9f5409ea92e505 100644 (file)
@@ -23,6 +23,8 @@ int csa_dosetemail(void *source, int cargc, char **cargv);
 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);
 
@@ -71,6 +73,7 @@ void relayfinishinit(int hooknum, void *arg) {
   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]) {
@@ -135,6 +138,59 @@ int csa_docheckhashpass(void *source, int cargc, char **cargv) {
   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;
index 0428050082ac734a2cb7debc510c15c8ed498114..b606f3633cf1354de45b5be588b20a3684a9c410 100644 (file)
@@ -355,27 +355,28 @@ void chanservjoinchan(channel *cp) {
   }
 }
 
-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;
   }
 
@@ -389,29 +390,22 @@ void chanservstdmessage(nick *np, int messageid, ... ) {
 
   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)
@@ -429,12 +423,33 @@ void chanservstdmessage(nick *np, int messageid, ... ) {
   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;
index c728c2e5cbeb0446e8375e5629210ad4645fe4f9..363589652e30212812c4df663bb530b83ac7d466 100644 (file)
@@ -69,7 +69,7 @@
 /* 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 * */