* Copyright notice from original mutt:
* [none]
*
+ * Parts were written/modified by:
+ * Christian Gall <cg@cgall.de>
+ * Rocco Rutte <pdmef@cs.tu-berlin.de>
+ *
* This file is part of mutt-ng, see http://www.muttng.org/.
* It's licensed under the GNU General Public License,
* please see the file GPL in the top level source directory.
#endif
#include "mutt.h"
+#include "ascii.h"
+#include "enter.h"
#include "lib/mem.h"
#include "lib/intl.h"
#include "lib/str.h"
+#if defined (USE_SSL) || (defined (USE_GNUTLS) && defined (HAVE_GNUTLS_OPENSSL_H))
+#include <openssl/ssl.h>
+#endif
+
#include <errno.h>
+
#include <auth-client.h>
#include <libesmtp.h>
_mutt_libesmtp_perror(msg); \
FAIL(); \
} while (0)
+#define extna(msg) { mutt_error (_("SMTP Extension '%s' not supported by MTA."), \
+ msg); sleep (1); }
/*
* _mutt_libesmtp_ensure_init
snprintf (prompt, sizeof (prompt), "%s%s: ", request[i].prompt,
(request[i].
flags & AUTH_CLEARTEXT) ? " (not encrypted)" : "");
- mutt_get_password (prompt, authpass, sizeof (authpass));
+ mutt_get_field_unbuffered (prompt, authpass, sizeof (authpass),
+ M_PASS);
}
result[i] = authpass;
}
return *buf;
}
+static int handle_invalid_peer_certificate (long vfy_result) {
+#if defined (USE_SSL) || (defined (USE_GNUTLS) && defined (HAVE_GNUTLS_OPENSSL_H))
+ mutt_error (_("Error verifying certificate: %s"),
+ NONULL (X509_verify_cert_error_string (vfy_result)));
+#else
+ mutt_error (_("Error verifying certificate. Error Code: %lu"), vfy_result);
+#endif
+ sleep(2);
+ return 1; /* Accept the problem */
+}
+
+static void event_cb (smtp_session_t session, int event_no, void *arg,...)
+{
+ va_list alist;
+ int *ok;
+
+ va_start(alist, arg);
+ switch(event_no) {
+ case SMTP_EV_CONNECT:
+ case SMTP_EV_MAILSTATUS:
+ case SMTP_EV_RCPTSTATUS:
+ case SMTP_EV_MESSAGEDATA:
+ case SMTP_EV_MESSAGESENT:
+ case SMTP_EV_DISCONNECT: break;
+ case SMTP_EV_WEAK_CIPHER: {
+ int bits;
+ bits = va_arg(alist, long); ok = va_arg(alist, int*);
+ mutt_message (_("SMTP_EV_WEAK_CIPHER, bits=%d - accepted."), bits);
+ sleep(1);
+ *ok = 1; break;
+ }
+ case SMTP_EV_STARTTLS_OK:
+ mutt_message (_("Using TLS"));
+ sleep(1);
+ break;
+ case SMTP_EV_INVALID_PEER_CERTIFICATE: {
+ long vfy_result;
+ vfy_result = va_arg(alist, long); ok = va_arg(alist, int*);
+ *ok = handle_invalid_peer_certificate(vfy_result);
+ sleep(1);
+ break;
+ }
+ case SMTP_EV_NO_PEER_CERTIFICATE: {
+ ok = va_arg(alist, int*);
+ mutt_message (_("SMTP_EV_NO_PEER_CERTIFICATE - accepted."));
+ sleep(1);
+ *ok = 1; break;
+ }
+ case SMTP_EV_WRONG_PEER_CERTIFICATE: {
+ ok = va_arg(alist, int*);
+ mutt_message (_("SMTP_EV_WRONG_PEER_CERTIFICATE - accepted."));
+ sleep(1);
+ *ok = 1; break;
+ }
+ case SMTP_EV_NO_CLIENT_CERTIFICATE: {
+ ok = va_arg(alist, int*);
+ mutt_message (_("SMTP_EV_NO_CLIENT_CERTIFICATE - accepted."));
+ sleep(1);
+ *ok = 1; break;
+ }
+ case SMTP_EV_EXTNA_DSN:
+ extna ("DSN");
+ break;
+ case SMTP_EV_EXTNA_STARTTLS:
+ extna ("StartTLS");
+ break;
+ case SMTP_EV_EXTNA_8BITMIME:
+ extna ("8BITMIME");
+ break;
+ default:
+ mutt_message(_("Got unhandled event ID = %d - ignored."), event_no);
+ sleep(1);
+ }
+ va_end(alist);
+}
+
+static void do_dsn_notify (smtp_message_t message, const char* from) {
+ int flags = Notify_NOTSET;
+ smtp_recipient_t self = NULL;
+
+ if (!DsnNotify || !*DsnNotify || !message || !from || !*from ||
+ strstr (DsnNotify, "never") != NULL)
+ return;
+
+ if (strstr (DsnNotify, "failure") != NULL)
+ flags |= Notify_FAILURE;
+ if (strstr (DsnNotify, "delay") != NULL)
+ flags |= Notify_DELAY;
+ if (strstr (DsnNotify, "success") != NULL)
+ flags |= Notify_SUCCESS;
+
+ if (flags != Notify_NOTSET) {
+ if (!(self = smtp_add_recipient (message, from)))
+ return;
+ smtp_dsn_set_notify (self, flags);
+ }
+}
+
+static void do_dsn_ret (smtp_message_t message) {
+ if (!DsnReturn || !*DsnReturn || !message)
+ return;
+ if (ascii_strncasecmp (DsnReturn, "hdrs", 4) == 0)
+ smtp_dsn_set_ret (message, Ret_HDRS);
+ else if (ascii_strncasecmp (DsnReturn, "full", 4) == 0)
+ smtp_dsn_set_ret (message, Ret_FULL);
+}
+
+#if defined (USE_LIBESMTP) && (defined (USE_SSL) || defined (USE_GNUTLS))
+int mutt_libesmtp_check_usetls (const char* option, unsigned long p,
+ char* errbuf, size_t errlen) {
+ char* val = (char*) p;
+ if (!val || !*val)
+ return (1);
+ if (str_ncmp (val, "enabled", 7) != 0 &&
+ str_ncmp (val, "required", 8) != 0) {
+ if (errbuf)
+ snprintf (errbuf, errlen, _("'%s' is invalid for %s"), val, option);
+ return (0);
+ }
+ return (1);
+}
+#endif
+
/*
- * mutt_invoke_libesmtp
+ * mutt_libesmtp_invoke
* Sends a mail message to the provided recipients using libesmtp.
* Returns 0 upon success, -1 upon failure (and prints an error
* message).
*/
-int mutt_invoke_libesmtp (ADDRESS * from, /* the sender */
+int mutt_libesmtp_invoke (ADDRESS * from, /* the sender */
ADDRESS * to, ADDRESS * cc, ADDRESS * bcc, /* recips */
const char *msg, /* file containing message */
int eightbit)
FILE *fp = NULL;
auth_context_t authctx = NULL;
const smtp_status_t *status;
+ char* envfrom = from->mailbox;
_mutt_libesmtp_ensure_init ();
if ((session = smtp_create_session ()) == NULL)
SMTPFAIL ("smtp_create_session");
+#if defined (USE_SSL) || (defined (USE_GNUTLS) && defined (HAVE_GNUTLS_OPENSSL_H))
+ if (SmtpUseTLS != NULL && ascii_strncasecmp("enabled", SmtpUseTLS, 7) == 0) {
+ smtp_starttls_enable(session, Starttls_ENABLED);
+ } else if (SmtpUseTLS != NULL && ascii_strncasecmp("required", SmtpUseTLS, 8) == 0) {
+ smtp_starttls_enable(session, Starttls_REQUIRED);
+ }
+#endif
+
/* Create hostname:port string and tell libesmtp */
/* len = SmtpHost len + colon + max port (65536 => 5 chars) + terminator */
hostportlen = str_len (SmtpHost) + 7;
SMTPFAIL ("smtp_auth_set_context");
}
+#if defined (USE_SSL) || (defined (USE_GNUTLS) && defined (HAVE_GNUTLS_OPENSSL_H))
+ smtp_starttls_set_ctx (session, NULL);
+#endif
+ smtp_set_eventcb (session, event_cb, NULL);
+
if ((message = smtp_add_message (session)) == NULL)
SMTPFAIL ("smtp_add_message");
+
/* Initialize envelope sender */
- if (!smtp_set_reverse_path (message, from->mailbox))
+ if (option (OPTENVFROM) && EnvFrom)
+ envfrom = EnvFrom->mailbox;
+ if (!smtp_set_reverse_path (message, envfrom))
SMTPFAIL ("smtp_set_reverse_path");
+ /* set up DSN for message */
+ do_dsn_notify (message, envfrom);
+ do_dsn_ret (message);
+
+ /* set up 8bitmime flag */
+ if (eightbit && option (OPTUSE8BITMIME))
+ smtp_8bitmime_set_body (message, E8bitmime_8BITMIME);
+
if ((fp = fopen (msg, "r")) == NULL)
LIBCFAIL ("fopen");
if (!smtp_set_messagecb (message, _mutt_libesmtp_messagefp_cb, fp))
if (fp != NULL)
fclose (fp);
if (hostportstr != NULL)
- free (hostportstr);
+ mem_free (&hostportstr);
if (session != NULL)
smtp_destroy_session (session);
if (authctx != NULL)