]> git.llucax.com Git - software/mutt-debian.git/blobdiff - smtp.c
staging the nntp patch which is not applying cleanly at the moment
[software/mutt-debian.git] / smtp.c
diff --git a/smtp.c b/smtp.c
index a49d25cb9f2d728031ec9aa504b8fd75f1e0d391..9d096a392d2e1542a3f96f713b66fbcb34776870 100644 (file)
--- a/smtp.c
+++ b/smtp.c
@@ -47,6 +47,7 @@
 
 #define smtp_err_read -2
 #define smtp_err_write -3
+#define smtp_err_code -4
 
 #define SMTP_PORT 25
 #define SMTPS_PORT 465
@@ -76,6 +77,21 @@ static int Esmtp = 0;
 static char* AuthMechs = NULL;
 static unsigned char Capabilities[(CAPMAX + 7)/ 8];
 
+static int smtp_code (char *buf, size_t len, int *n)
+{
+  char code[4];
+
+  if (len < 4)
+    return -1;
+  code[0] = buf[0];
+  code[1] = buf[1];
+  code[2] = buf[2];
+  code[3] = 0;
+  if (mutt_atoi (code, n) < 0)
+    return -1;
+  return 0;
+}
+
 /* Reads a command response from the SMTP server.
  * Returns:
  * 0   on success (2xx code) or continue (354 code)
@@ -107,7 +123,9 @@ smtp_get_resp (CONNECTION * conn)
     else if (!ascii_strncasecmp ("STARTTLS", buf + 4, 8))
       mutt_bit_set (Capabilities, STARTTLS);
 
-    n = atoi (buf);
+    if (smtp_code (buf, n, &n) < 0)
+      return smtp_err_code;
+
   } while (buf[3] == '-');
 
   if (smtp_success (n) || n == smtp_continue)
@@ -125,6 +143,12 @@ smtp_rcpt_to (CONNECTION * conn, const ADDRESS * a)
 
   while (a)
   {
+    /* weed out group mailboxes, since those are for display only */
+    if (!a->mailbox || a->group)
+    {
+      a = a->next;
+      continue;
+    }
     if (mutt_bit_isset (Capabilities, DSN) && DsnNotify)
       snprintf (buf, sizeof (buf), "RCPT TO:<%s> NOTIFY=%s\r\n",
                 a->mailbox, DsnNotify);
@@ -147,7 +171,7 @@ smtp_data (CONNECTION * conn, const char *msgfile)
   FILE *fp = 0;
   progress_t progress;
   struct stat st;
-  int r;
+  int r, term = 0;
   size_t buflen;
 
   fp = fopen (msgfile, "r");
@@ -164,18 +188,19 @@ smtp_data (CONNECTION * conn, const char *msgfile)
   snprintf (buf, sizeof (buf), "DATA\r\n");
   if (mutt_socket_write (conn, buf) == -1)
   {
-    fclose (fp);
+    safe_fclose (&fp);
     return smtp_err_write;
   }
   if ((r = smtp_get_resp (conn)))
   {
-    fclose (fp);
+    safe_fclose (&fp);
     return r;
   }
 
   while (fgets (buf, sizeof (buf) - 1, fp))
   {
     buflen = mutt_strlen (buf);
+    term = buf[buflen-1] == '\n';
     if (buflen && buf[buflen-1] == '\n'
        && (buflen == 1 || buf[buflen - 2] != '\r'))
       snprintf (buf + buflen - 1, sizeof (buf) - buflen + 1, "\r\n");
@@ -183,19 +208,24 @@ smtp_data (CONNECTION * conn, const char *msgfile)
     {
       if (mutt_socket_write_d (conn, ".", -1, M_SOCK_LOG_FULL) == -1)
       {
-        fclose (fp);
+        safe_fclose (&fp);
         return smtp_err_write;
       }
     }
     if (mutt_socket_write_d (conn, buf, -1, M_SOCK_LOG_FULL) == -1)
     {
-      fclose (fp);
+      safe_fclose (&fp);
       return smtp_err_write;
     }
-
     mutt_progress_update (&progress, ftell (fp), -1);
   }
-  fclose (fp);
+  if (!term && buflen &&
+      mutt_socket_write_d (conn, "\r\n", -1, M_SOCK_LOG_FULL) == -1)
+  {
+    safe_fclose (&fp);
+    return smtp_err_write;
+  }
+  safe_fclose (&fp);
 
   /* terminate the message body */
   if (mutt_socket_write (conn, ".\r\n") == -1)
@@ -284,6 +314,8 @@ mutt_smtp_send (const ADDRESS* from, const ADDRESS* to, const ADDRESS* cc,
     mutt_error (_("SMTP session failed: read error"));
   else if (ret == smtp_err_write)
     mutt_error (_("SMTP session failed: write error"));
+  else if (ret == smtp_err_code)
+    mutt_error (_("Invalid server response"));
 
   return ret;
 }
@@ -422,6 +454,12 @@ static int smtp_open (CONNECTION* conn)
     }
 
 #ifdef USE_SASL
+    if (!(conn->account.flags & M_ACCT_PASS) && option (OPTNOCURSES))
+    {
+      mutt_error (_("Interactive SMTP authentication not supported"));
+      mutt_sleep (1);
+      return -1;
+    }
     return smtp_auth (conn);
 #else
     mutt_error (_("SMTP authentication requires SASL"));
@@ -534,9 +572,10 @@ static int smtp_auth_sasl (CONNECTION* conn, const char* mechlist)
   do {
     if (mutt_socket_write (conn, buf) < 0)
       goto fail;
-    if (mutt_socket_readln (buf, sizeof (buf), conn) < 0)
+    if ((rc = mutt_socket_readln (buf, sizeof (buf), conn)) < 0)
+      goto fail;
+    if (smtp_code (buf, rc, &rc) < 0)
       goto fail;
-    rc = atoi(buf);
 
     if (rc != smtp_ready)
       break;