]> code.citadel.org Git - citadel.git/blobdiff - citadel/modules/imap/serv_imap.c
Don't output a space between imap namespaces
[citadel.git] / citadel / modules / imap / serv_imap.c
index 533ac82117a16baf66ba78b8c7f65d72effbaa37..cd0de575d0f6fd4e96aeebf5905695a26aea8228 100644 (file)
@@ -1,6 +1,4 @@
 /*
- * $Id$ 
- *
  * IMAP server for the Citadel system
  * Copyright (C) 2000-2009 by Art Cancro and others.
  * This code is released under the terms of the GNU General Public License.
@@ -56,7 +54,6 @@
 #include "support.h"
 #include "config.h"
 #include "user_ops.h"
-#include "policy.h"
 #include "database.h"
 #include "msgbase.h"
 #include "internet_addressing.h"
@@ -129,7 +126,7 @@ void imap_free_transmitted_message(void)
  */
 void imap_set_seen_flags(int first_msg)
 {
-       struct visit vbuf;
+       visit vbuf;
        int i;
        int num_sets;
        int s;
@@ -413,9 +410,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;
        }
@@ -426,7 +422,8 @@ void imap_cleanup_function(void)
                IMAP->cached_body_len = 0;
                IMAP->cached_bodymsgnum = (-1);
        }
-
+       FreeStrBuf(&IMAP->Cmd.CmdBuf);
+       if (IMAP->Cmd.Params != NULL) free(IMAP->Cmd.Params);
        free(IMAP);
        CtdlLogPrintf(CTDL_DEBUG, "Finished IMAP cleanup hook\n");
 }
@@ -504,7 +501,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;
 
@@ -552,12 +548,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);
@@ -574,7 +575,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",
@@ -588,16 +589,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);
@@ -618,6 +619,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);
@@ -625,7 +627,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;
 
@@ -637,7 +641,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;
                }
@@ -648,20 +652,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;
@@ -674,19 +678,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);
@@ -705,9 +714,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);
 }
 
@@ -717,7 +726,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;
@@ -746,7 +755,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));
                }
        }
 
@@ -888,7 +897,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 ");
 
@@ -903,10 +912,10 @@ void imap_namespace(int num_parms, ConstStr *Params)
        for (i = 0; i < MAXFLOORS; ++i) {
                fl = CtdlGetCachedFloor(i);
                if (fl->f_flags & F_INUSE) {
-                       if (floors > 0) cprintf(" ");
+                       /* if (floors > 0) cprintf(" "); samjam says this confuses javamail */
                        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;
                }
@@ -1024,7 +1033,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 */
@@ -1046,7 +1055,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);
        }
 }
@@ -1060,7 +1069,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;
 
@@ -1088,9 +1097,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);
@@ -1303,7 +1312,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",
@@ -1375,12 +1384,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);
 }
@@ -1420,7 +1429,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 {
@@ -1738,5 +1747,5 @@ CTDL_MODULE_INIT(imap)
        }
        
        /* return our Subversion id for the Log */
-       return "$Id$";
+       return "imap";
 }