more places to fix the new linebreak behaviour of the base64 encoder.
[citadel.git] / citadel / modules / smtp / serv_smtp.c
index 681e0c740bf1076a89e25c61563d87393b51110b..a93bb438e384231052681d5ac4346aba074e8feb 100644 (file)
@@ -394,13 +394,17 @@ void smtp_help(long offset, long Flags) {
 void smtp_get_user(long offset)
 {
        char buf[SIZ];
-       char username[SIZ];
        citsmtp *sSMTP = SMTP;
 
-       CtdlDecodeBase64(username, ChrPtr(sSMTP->Cmd) + offset, SIZ);
+       StrBufDecodeBase64(sSMTP->Cmd);
+
        /* syslog(LOG_DEBUG, "Trying <%s>\n", username); */
-       if (CtdlLoginExistingUser(NULL, username) == login_ok) {
-               CtdlEncodeBase64(buf, "Password:", 9, 0);
+       if (CtdlLoginExistingUser(NULL, ChrPtr(sSMTP->Cmd)) == login_ok) {
+               size_t len = CtdlEncodeBase64(buf, "Password:", 9, 0);
+
+               if (buf[len - 1] == '\n') {
+                       buf[len - 1] = '\0';
+               }
                cprintf("334 %s\r\n", buf);
                sSMTP->command_state = smtp_password;
        }
@@ -418,12 +422,11 @@ void smtp_get_pass(long offset, long Flags)
 {
        citsmtp *sSMTP = SMTP;
        char password[SIZ];
-       long len;
 
-       memset(password, 0, sizeof(password));  
-       len = CtdlDecodeBase64(password, ChrPtr(sSMTP->Cmd), SIZ);
+       memset(password, 0, sizeof(password));
+       StrBufDecodeBase64(sSMTP->Cmd);
        /* syslog(LOG_DEBUG, "Trying <%s>\n", password); */
-       if (CtdlTryPassword(password, len) == pass_ok) {
+       if (CtdlTryPassword(SKEY(sSMTP->Cmd)) == pass_ok) {
                smtp_auth_greeting(offset, Flags);
        }
        else {
@@ -439,19 +442,44 @@ void smtp_get_pass(long offset, long Flags)
 void smtp_try_plain(long offset, long Flags)
 {
        citsmtp *sSMTP = SMTP;
-       char decoded_authstring[1024];
-       char ident[256];
-       char user[256];
-       char pass[256];
+       const char*decoded_authstring;
+       char ident[256] = "";
+       char user[256] = "";
+       char pass[256] = "";
        int result;
-       long len;
 
-       CtdlDecodeBase64(decoded_authstring, ChrPtr(sSMTP->Cmd), StrLength(sSMTP->Cmd));
-       safestrncpy(ident, decoded_authstring, sizeof ident);
-       safestrncpy(user, &decoded_authstring[strlen(ident) + 1], sizeof user);
-       len = safestrncpy(pass, &decoded_authstring[strlen(ident) + strlen(user) + 2], sizeof pass);
-       if (len == -1)
-               len = sizeof(pass) - 1;
+       long decoded_len;
+       long len = 0;
+       long plen = 0;
+
+       memset(pass, 0, sizeof(pass));
+       decoded_len = StrBufDecodeBase64(sSMTP->Cmd);
+
+       if (decoded_len > 0)
+       {
+               decoded_authstring = ChrPtr(sSMTP->Cmd);
+
+               len = safestrncpy(ident, decoded_authstring, sizeof ident);
+
+               decoded_len -= len - 1;
+               decoded_authstring += len + 1;
+
+               if (decoded_len > 0)
+               {
+                       len = safestrncpy(user, decoded_authstring, sizeof user);
+
+                       decoded_authstring += len + 1;
+                       decoded_len -= len - 1;
+               }
+
+               if (decoded_len > 0)
+               {
+                       plen = safestrncpy(pass, decoded_authstring, sizeof pass);
+
+                       if (plen < 0)
+                               plen = sizeof(pass) - 1;
+               }
+       }
 
        sSMTP->command_state = smtp_command;
 
@@ -463,7 +491,7 @@ void smtp_try_plain(long offset, long Flags)
        }
 
        if (result == login_ok) {
-               if (CtdlTryPassword(pass, len) == pass_ok) {
+               if (CtdlTryPassword(pass, plen) == pass_ok) {
                        smtp_webcit_preferences_hack();
                        smtp_auth_greeting(offset, Flags);
                        return;
@@ -495,7 +523,10 @@ void smtp_auth(long offset, long Flags)
                        smtp_get_user(6);
                }
                else {
-                       CtdlEncodeBase64(username_prompt, "Username:", 9, 0);
+                       size_t len = CtdlEncodeBase64(username_prompt, "Username:", 9, 0);
+                       if (username_prompt[len - 1] == '\n') {
+                               username_prompt[len - 1] = '\0';
+                       }
                        cprintf("334 %s\r\n", username_prompt);
                        sSMTP->command_state = smtp_user;
                }
@@ -622,7 +653,7 @@ void smtp_mail(long offset, long flags) {
         * address so we don't have to contend with the empty string causing
         * other code to fail when it's expecting something there.
         */
-       if (StrLength(sSMTP->from)) {
+       if (StrLength(sSMTP->from) == 0) {
                StrBufPlain(sSMTP->from, HKEY("someone@example.com"));
        }
 
@@ -668,7 +699,7 @@ void smtp_rcpt(long offset, long flags)
 {
        struct CitContext *CCC = CC;
        char message_to_spammer[SIZ];
-       struct recptypes *valid = NULL;
+       recptypes *valid = NULL;
        citsmtp *sSMTP = SMTP;
 
        if (StrLength(sSMTP->from) == 0) {
@@ -767,7 +798,7 @@ void smtp_data(long offset, long flags)
        struct CtdlMessage *msg = NULL;
        long msgnum = (-1L);
        char nowstamp[SIZ];
-       struct recptypes *valid;
+       recptypes *valid;
        int scan_errors;
        int i;
        citsmtp *sSMTP = SMTP;
@@ -859,8 +890,8 @@ void smtp_data(long offset, long flags)
                        return;
                }
 
-               CM_SetField(msg, eNodeName, config.c_nodename, strlen(config.c_nodename));
-               CM_SetField(msg, eHumanNode, config.c_humannode, strlen(config.c_humannode));
+               CM_SetField(msg, eNodeName, CFG_KEY(c_nodename));
+               CM_SetField(msg, eHumanNode, CFG_KEY(c_humannode));
                CM_SetField(msg, eOriginalRoom, HKEY(MAILROOM));
                if (sSMTP->preferred_sender_name != NULL)
                        CM_SetField(msg, eAuthor, SKEY(sSMTP->preferred_sender_name));
@@ -896,7 +927,7 @@ void smtp_data(long offset, long flags)
                scan_errors = 0;
        }
        else {
-               scan_errors = PerformMessageHooks(msg, EVT_SMTPSCAN);
+               scan_errors = PerformMessageHooks(msg, valid, EVT_SMTPSCAN);
        }
 
        if (scan_errors > 0) {  /* We don't want this message! */
@@ -975,6 +1006,7 @@ void smtp_starttls(long offset, long flags)
  */
 void smtp_command_loop(void)
 {
+       static const ConstStr AuthPlainStr = {HKEY("AUTH PLAIN")};
        struct CitContext *CCC = CC;
        citsmtp *sSMTP = SMTP;
        const char *pch, *pchs;
@@ -995,15 +1027,21 @@ void smtp_command_loop(void)
        syslog(LOG_DEBUG, "SMTP server: %s\n", ChrPtr(sSMTP->Cmd));
 
        if (sSMTP->command_state == smtp_user) {
-               smtp_get_user(0);
+               if (!strncmp(ChrPtr(sSMTP->Cmd), AuthPlainStr.Key, AuthPlainStr.len))
+                       smtp_try_plain(0, 0);
+               else
+                       smtp_get_user(0);
+               return;
        }
 
        else if (sSMTP->command_state == smtp_password) {
                smtp_get_pass(0, 0);
+               return;
        }
 
        else if (sSMTP->command_state == smtp_plain) {
                smtp_try_plain(0, 0);
+               return;
        }
 
        pchs = pch = ChrPtr(sSMTP->Cmd);