]> code.citadel.org Git - citadel.git/blobdiff - citadel/modules/imap/serv_imap.c
* if we fail to log in because of user/passvoid wrong, reply with NO instead of BAD
[citadel.git] / citadel / modules / imap / serv_imap.c
index ac91a75821dfb9d3a9d6cfa48f007b9e2d3155b6..27c0da4ccbb424f7082b728972d2310d344d7400 100644 (file)
@@ -56,7 +56,6 @@
 #include "support.h"
 #include "config.h"
 #include "user_ops.h"
-#include "policy.h"
 #include "database.h"
 #include "msgbase.h"
 #include "internet_addressing.h"
@@ -413,9 +412,8 @@ void imap_cleanup_function(void)
        imap_free_msgids();
        imap_free_transmitted_message();
 
-       if (IMAP->cached_rfc822_data != NULL) {
-               free(IMAP->cached_rfc822_data);
-               IMAP->cached_rfc822_data = NULL;
+       if (IMAP->cached_rfc822 != NULL) {
+               FreeStrBuf(&IMAP->cached_rfc822);
                IMAP->cached_rfc822_msgnum = (-1);
                IMAP->cached_rfc822_withbody = 0;
        }
@@ -505,7 +503,6 @@ void imap_greeting(void)
        CC->session_specific_data = malloc(sizeof(citimap));
        memset(IMAP, 0, sizeof(citimap));
        IMAP->authstate = imap_as_normal;
-       IMAP->cached_rfc822_data = NULL;
        IMAP->cached_rfc822_msgnum = (-1);
        IMAP->cached_rfc822_withbody = 0;
 
@@ -553,12 +550,17 @@ void imap_login(int num_parms, ConstStr *Params)
                }
        case 4:
                if (CtdlLoginExistingUser(NULL, Params[2].Key) == login_ok) {
-                       if (CtdlTryPassword(Params[3].Key) == pass_ok) {
+                       if (CtdlTryPassword(Params[3].Key, Params[3].len) == pass_ok) {
                                cprintf("%s OK [", Params[0].Key);
                                imap_output_capability_string();
                                cprintf("] Hello, %s\r\n", CC->user.fullname);
                                return;
                        }
+                       else
+                       {
+                               cprintf("%s NO AUTHENTICATE %s failed\r\n",
+                                       Params[0].Key, Params[3].Key);
+                       }
                }
 
                cprintf("%s BAD Login incorrect\r\n", Params[0].Key);
@@ -575,7 +577,7 @@ void imap_login(int num_parms, ConstStr *Params)
  */
 void imap_authenticate(int num_parms, ConstStr *Params)
 {
-       char buf[SIZ];
+       char UsrBuf[SIZ];
 
        if (num_parms != 3) {
                cprintf("%s BAD incorrect number of parameters\r\n",
@@ -589,16 +591,16 @@ void imap_authenticate(int num_parms, ConstStr *Params)
        }
 
        if (!strcasecmp(Params[2].Key, "LOGIN")) {
-               CtdlEncodeBase64(buf, "Username:", 9, 0);
-               cprintf("+ %s\r\n", buf);
+               CtdlEncodeBase64(UsrBuf, "Username:", 9, 0);
+               cprintf("+ %s\r\n", UsrBuf);
                IMAP->authstate = imap_as_expecting_username;
                strcpy(IMAP->authseq, Params[0].Key);
                return;
        }
 
        if (!strcasecmp(Params[2].Key, "PLAIN")) {
-               // CtdlEncodeBase64(buf, "Username:", 9, 0);
-               // cprintf("+ %s\r\n", buf);
+               // CtdlEncodeBase64(UsrBuf, "Username:", 9, 0);
+               // cprintf("+ %s\r\n", UsrBuf);
                cprintf("+ \r\n");
                IMAP->authstate = imap_as_expecting_plainauth;
                strcpy(IMAP->authseq, Params[0].Key);
@@ -619,6 +621,7 @@ void imap_auth_plain(void)
        char user[256];
        char pass[256];
        int result;
+       long len;
 
        memset(pass, 0, sizeof(pass));
        StrBufDecodeBase64(IMAP->Cmd.CmdBuf);
@@ -626,7 +629,9 @@ void imap_auth_plain(void)
        decoded_authstring = ChrPtr(IMAP->Cmd.CmdBuf);
        safestrncpy(ident, decoded_authstring, sizeof ident);
        safestrncpy(user, &decoded_authstring[strlen(ident) + 1], sizeof user);
-       safestrncpy(pass, &decoded_authstring[strlen(ident) + strlen(user) + 2], sizeof pass);
+       len = safestrncpy(pass, &decoded_authstring[strlen(ident) + strlen(user) + 2], sizeof pass);
+       if (len < 0)
+               len = sizeof(pass) - 1;
 
        IMAP->authstate = imap_as_normal;
 
@@ -638,7 +643,7 @@ void imap_auth_plain(void)
        }
 
        if (result == login_ok) {
-               if (CtdlTryPassword(pass) == pass_ok) {
+               if (CtdlTryPassword(pass, len) == pass_ok) {
                        cprintf("%s OK authentication succeeded\r\n", IMAP->authseq);
                        return;
                }
@@ -649,20 +654,20 @@ void imap_auth_plain(void)
 
 void imap_auth_login_user(long state)
 {
-       char buf[SIZ];
+       char PWBuf[SIZ];
        citimap *Imap = IMAP;
 
        switch (state){
        case imap_as_expecting_username:
                StrBufDecodeBase64(Imap->Cmd.CmdBuf);
                CtdlLoginExistingUser(NULL, ChrPtr(Imap->Cmd.CmdBuf));
-               CtdlEncodeBase64(buf, "Password:", 9, 0);
-               cprintf("+ %s\r\n", buf);
+               CtdlEncodeBase64(PWBuf, "Password:", 9, 0);
+               cprintf("+ %s\r\n", PWBuf);
                
                Imap->authstate = imap_as_expecting_password;
                return;
        case imap_as_expecting_multilineusername:
-               extract_token(buf, ChrPtr(Imap->Cmd.CmdBuf), 1, ' ', sizeof(buf));
+               extract_token(PWBuf, ChrPtr(Imap->Cmd.CmdBuf), 1, ' ', sizeof(PWBuf));
                CtdlLoginExistingUser(NULL, ChrPtr(Imap->Cmd.CmdBuf));
                cprintf("+ go ahead\r\n");
                IMAP->authstate = imap_as_expecting_multilinepassword;
@@ -675,19 +680,24 @@ void imap_auth_login_pass(long state)
 {
        citimap *Imap = IMAP;
        const char *pass = NULL;
-       char buf[SIZ];
+       long len = 0;
 
        switch (state) {
        default:
        case imap_as_expecting_password:
                StrBufDecodeBase64(Imap->Cmd.CmdBuf);
-               pass = buf;
+               pass = ChrPtr(Imap->Cmd.CmdBuf);
+               len = StrLength(Imap->Cmd.CmdBuf);
                break;
        case imap_as_expecting_multilinepassword:
                pass = ChrPtr(Imap->Cmd.CmdBuf);
+               len = StrLength(Imap->Cmd.CmdBuf);
                break;
        }
-       if (CtdlTryPassword(pass) == pass_ok) {
+       if (len > USERNAME_SIZE)
+               StrBufCutAt(Imap->Cmd.CmdBuf, USERNAME_SIZE, NULL);
+
+       if (CtdlTryPassword(pass, len) == pass_ok) {
                cprintf("%s OK authentication succeeded\r\n", IMAP->authseq);
        } else {
                cprintf("%s NO authentication failed\r\n", IMAP->authseq);
@@ -706,9 +716,9 @@ void imap_starttls(int num_parms, ConstStr *Params)
        char nosup_response[SIZ];
        char error_response[SIZ];
 
-       sprintf(ok_response,    "%s OK begin TLS negotiation now\r\n",  Params[0].Key);
-       sprintf(nosup_response, "%s NO TLS not supported here\r\n",     Params[0].Key);
-       sprintf(error_response, "%s BAD Internal error\r\n",            Params[0].Key);
+       snprintf(ok_response, SIZ,      "%s OK begin TLS negotiation now\r\n",  Params[0].Key);
+       snprintf(nosup_response, SIZ,   "%s NO TLS not supported here\r\n",     Params[0].Key);
+       snprintf(error_response, SIZ,   "%s BAD Internal error\r\n",            Params[0].Key);
        CtdlModuleStartCryptoMsgs(ok_response, nosup_response, error_response);
 }
 
@@ -718,7 +728,7 @@ void imap_starttls(int num_parms, ConstStr *Params)
  */
 void imap_select(int num_parms, ConstStr *Params)
 {
-       char towhere[SIZ];
+       char towhere[ROOMNAMELEN];
        char augmented_roomname[ROOMNAMELEN];
        int c = 0;
        int ok = 0;
@@ -747,7 +757,7 @@ void imap_select(int num_parms, ConstStr *Params)
                CtdlMailboxName(augmented_roomname, sizeof augmented_roomname, &CC->user, towhere);
                c = CtdlGetRoom(&QRscratch, augmented_roomname);
                if (c == 0) {
-                       strcpy(towhere, augmented_roomname);
+                       safestrncpy(towhere, augmented_roomname, sizeof(towhere));
                }
        }
 
@@ -889,7 +899,7 @@ void imap_namespace(int num_parms, ConstStr *Params)
        int i;
        struct floor *fl;
        int floors = 0;
-       char buf[SIZ];
+       char Namespace[SIZ];
 
        cprintf("* NAMESPACE ");
 
@@ -906,8 +916,8 @@ void imap_namespace(int num_parms, ConstStr *Params)
                if (fl->f_flags & F_INUSE) {
                        if (floors > 0) cprintf(" ");
                        cprintf("(");
-                       sprintf(buf, "%s/", fl->f_name);
-                       plain_imap_strout(buf);
+                       snprintf(Namespace, sizeof(Namespace), "%s/", fl->f_name);
+                       plain_imap_strout(Namespace);
                        cprintf(" \"/\")");
                        ++floors;
                }
@@ -1025,7 +1035,7 @@ int imap_grabroom(char *returned_roomname, const char *foldername, int zapped_ok
                            &CC->user, roomname);
                c = CtdlGetRoom(&QRscratch, augmented_roomname);
                if (c == 0)
-                       strcpy(roomname, augmented_roomname);
+                       safestrncpy(roomname, augmented_roomname, sizeof(roomname));
        }
 
        /* If the room exists, check security/access */
@@ -1047,7 +1057,7 @@ int imap_grabroom(char *returned_roomname, const char *foldername, int zapped_ok
                strcpy(returned_roomname, "");
                return (2);
        } else {
-               strcpy(returned_roomname, QRscratch.QRname);
+               safestrncpy(returned_roomname, QRscratch.QRname, ROOMNAMELEN);
                return (0);
        }
 }
@@ -1061,7 +1071,7 @@ void imap_status(int num_parms, ConstStr *Params)
 {
        int ret;
        char roomname[ROOMNAMELEN];
-       char buf[SIZ];
+       char imaproomname[SIZ];
        char savedroom[ROOMNAMELEN];
        int msgs, new;
 
@@ -1089,9 +1099,9 @@ void imap_status(int num_parms, ConstStr *Params)
         * names and simply spew all possible data items.  It's far easier to
         * code and probably saves us some processing time too.
         */
-       imap_mailboxname(buf, sizeof buf, &CC->room);
+       imap_mailboxname(imaproomname, sizeof imaproomname, &CC->room);
        cprintf("* STATUS ");
-       plain_imap_strout(buf);
+       plain_imap_strout(imaproomname);
        cprintf(" (MESSAGES %d ", msgs);
        cprintf("RECENT %d ", new);     /* Initially, new==recent */
        cprintf("UIDNEXT %ld ", CitControl.MMhighest + 1);
@@ -1304,7 +1314,7 @@ void imap_rename(int num_parms, ConstStr *Params)
        struct irl *irl = NULL; /* the list */
        struct irl *irlp = NULL;        /* scratch pointer */
        struct irlparms irlparms;
-       char buf[1024];
+       char aidemsg[1024];
 
        if (strchr(Params[3].Key, '\\') != NULL) {
                cprintf("%s NO Invalid character in folder name\r\n",
@@ -1376,12 +1386,12 @@ void imap_rename(int num_parms, ConstStr *Params)
                }
        }
 
-       snprintf(buf, sizeof buf, "IMAP folder \"%s\" renamed to \"%s\" by %s\n",
+       snprintf(aidemsg, sizeof aidemsg, "IMAP folder \"%s\" renamed to \"%s\" by %s\n",
                Params[2].Key,
                Params[3].Key,
                CC->curr_user
        );
-       CtdlAideMessage(buf, "IMAP folder rename");
+       CtdlAideMessage(aidemsg, "IMAP folder rename");
 
        cprintf("%s OK RENAME completed\r\n", Params[0].Key);
 }
@@ -1421,7 +1431,7 @@ void imap_command_loop(void)
                CtdlLogPrintf(CTDL_INFO, "IMAP: <plain_auth>\n");
        }
        else if ((Imap->authstate == imap_as_expecting_multilineusername) || 
-                bmstrcasestr(ChrPtr(Imap->Cmd.CmdBuf), " LOGIN ")) {
+                cbmstrcasestr(ChrPtr(Imap->Cmd.CmdBuf), " LOGIN ")) {
                CtdlLogPrintf(CTDL_INFO, "IMAP: LOGIN...\n");
        }
        else {