]> jfr.im git - irc/quakenet/newserv.git/blobdiff - chanserv/authcmds/login.c
Various changes to support authname being stored inside the authext.
[irc/quakenet/newserv.git] / chanserv / authcmds / login.c
index dd837eebc6f77377980d89797e0323e6c839f0f7..9599de10732400e62cd812a8912b2938cb69486b 100644 (file)
@@ -2,11 +2,19 @@
  *
  *
  * CMDNAME: login
- * CMDLEVEL: QCMD_SECURE | QCMD_NOTAUTHED
+ * CMDLEVEL: QCMD_SECURE | QCMD_NOTAUTHED | QCMD_ALIAS
  * CMDARGS: 2
  * CMDDESC: Authenticates you on the bot.
  * CMDFUNC: csa_doauth
  * CMDPROTO: int csa_doauth(void *source, int cargc, char **cargv);
+ * CMDHELP: Usage: LOGIN <username> <password>
+ * CMDHELP: Authenticates you on the bot, where:
+ * CMDHELP: username - your username
+ * CMDHELP: password - your password
+ * CMDHELP: If you do not have a username and password, see HELLO.
+ * CMDHELP: Note: due to the sensitive nature of this command, you must send the message
+ * CMDHELP: to Q@CServe.quakenet.org when using it.
+ * CMDHELP: Note: the preferred way to authenticate is to use the /AUTH command.
  */
 
 #include "../chanserv.h"
 #include <stdio.h>
 #include <string.h>
 
-int csa_doauth(void *source, int cargc, char **cargv) {
+int csa_auth(void *source, int cargc, char **cargv, CRAlgorithm alg) {
   reguser *rup;
-  activeuser* aup;
-  nick *sender=source;
-  nicklist *nl = NULL;
+  activeuser *aup;
+  nick *sender=source, *onp;
   char userhost[USERLEN+HOSTLEN+2];
-  int ucount=0;
+  int challenge=0;
+  char *authtype = "AUTH";
+  authname *anp;
+  int toomanyauths=0;
+  time_t now;
 
-  if (cargc<2) {
+  if (alg) {
+    challenge=1;
+    authtype = "CHALLENGEAUTH";
+  } else if (cargc<2) {
     chanservstdmessage(sender, QM_NOTENOUGHPARAMS, "auth");
     return CMD_ERROR;
   }
@@ -34,26 +48,66 @@ int csa_doauth(void *source, int cargc, char **cargv) {
   aup->authattempts++;
   if (aup->authattempts > MAXAUTHATTEMPT) {
     if ((aup->authattempts % 100) == 0)
-      chanservwallmessage("Warning: User %s!%s@%s attempted to auth %d times. Last attempt: AUTH %s %s", 
-        nl->np->nick, nl->np->ident, nl->np->host->name->content, cargv[0], cargv[1]);
+      chanservwallmessage("Warning: User %s!%s@%s attempted to auth %d times. Last attempt: %s %s %s",
+        sender->nick, sender->ident, sender->host->name->content, aup->authattempts, authtype, cargv[0], cargv[1]);
     chanservstdmessage(sender, QM_AUTHFAIL);
-    cs_log(sender,"AUTH FAIL too many auth attempts (last attempt: AUTH %s %s)",cargv[0], cargv[1]); 
+    cs_log(sender,"%s FAIL too many auth attempts (last attempt: %s %s %s)", authtype, authtype, cargv[0], cargv[1]); 
     return CMD_ERROR;
   }
 
   if (!(rup=findreguserbynick(cargv[0]))) {
     chanservstdmessage(sender, QM_AUTHFAIL);
-    cs_log(sender,"AUTH FAIL bad username %s",cargv[0]); 
+    cs_log(sender,"%s FAIL bad username %s",authtype,cargv[0]); 
     return CMD_ERROR;
   }
 
-  if (!checkpassword(rup, cargv[1])) {
+  if (!challenge) {
+    if (!checkpassword(rup, cargv[1])) {
+      chanservstdmessage(sender, QM_AUTHFAIL);
+      cs_log(sender,"%s FAIL username %s bad password %s",authtype,rup->username,cargv[1]);
+      return CMD_ERROR;
+    }
+  } else {
+    if (!checkresponse(rup, aup->entropy, cargv[1], alg)) {
+      chanservstdmessage(sender, QM_AUTHFAIL);
+      cs_log(sender,"%s FAIL username %s bad response",authtype,rup->username);
+      return CMD_ERROR;
+    }
+  }
+
+  /* This should never fail but do something other than crashing if it does. */
+  if (!(anp=findauthname(rup->ID))) {
     chanservstdmessage(sender, QM_AUTHFAIL);
-    cs_log(sender,"AUTH FAIL username %s bad password %s",rup->username,cargv[1]);
     return CMD_ERROR;
   }
 
-  rup->lastauth=time(NULL);
+  /* Check for too many auths.  Don't return immediately, since we will still warn
+   * other users on the acct in this case. */
+  if (!UHasHelperPriv(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;
+
+  /* Guarantee a unique auth timestamp for each account */
+  now=time(NULL);
+  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);
@@ -68,48 +122,28 @@ int csa_doauth(void *source, int cargc, char **cargv) {
     rup->suspendreason=0;
   }
   
-  if (UIsNeedAuth(rup))
-    rup->flags&=~(QUFLAG_NEEDAUTH);
   csdb_updateuser(rup);
   
-  if (UIsDelayedGline(rup)) {
-    /* delayed-gline - schedule the user's squelching */
-    deleteschedule(NULL, &chanservdgline, (void*)rup); /* icky, but necessary unless we stick more stuff in reguser structure */
-    scheduleoneshot(time(NULL)+rand()%900, &chanservdgline, (void*)rup);
-  }
-  else if (UIsGline(rup)) {
-    /* instant-gline - lets be lazy and set a schedule expiring now :) */
-    deleteschedule(NULL, &chanservdgline, (void*)rup); /* icky, but necessary unless we stick more stuff in reguser structure */
-    scheduleoneshot(time(NULL), &chanservdgline, (void*)rup);
-  }
-  else if (UIsSuspended(rup)) {
+  if (UIsSuspended(rup)) {
     /* plain suspend */
     chanservstdmessage(sender, QM_AUTHSUSPENDED);
-    chanservstdmessage(sender, QM_REASON, rup->suspendreason->content);
-    if (rup->suspendexp) {
-      struct tm* tmp;
-      char buf[200];
-      
-      tmp=gmtime(&(rup->suspendexp));
-      strftime(buf, 15, "%d/%m/%y %H:%M", tmp);
-      chanservstdmessage(sender, QM_EXPIRES, buf);
-    }
+    if(rup->suspendreason)
+      chanservstdmessage(sender, QM_REASON, rup->suspendreason->content);
+    if (rup->suspendexp)
+      chanservstdmessage(sender, QM_EXPIRES, rup->suspendexp);
     return CMD_ERROR;
   }
   
-  if (!UHasHelperPriv(rup) && !UIsNoAuthLimit(rup)) {
-    for (nl=rup->nicks; nl; nl=nl->next)
-      ucount++;
-    
-    if (ucount >= MAXAUTHCOUNT) {
-      chanservstdmessage(sender, QM_TOOMANYAUTHS);
-      return CMD_ERROR;
-    }
-  }
   
   chanservstdmessage(sender, QM_AUTHOK, rup->username);
-  cs_log(sender,"AUTH OK username %s", rup->username);
-  localusersetaccount(sender, rup->username);
+
+  cs_log(sender,"%s OK username %s", authtype,rup->username);
+
+  localusersetaccount(sender, rup->username, rup->ID, cs_accountflagmap(rup), rup->lastauth);
 
   return CMD_OK;
 }
+
+int csa_doauth(void *source, int cargc, char **cargv) {
+  return csa_auth(source, cargc, cargv, NULL);
+}