From: Pierre Habouzit Date: Sat, 26 May 2007 11:24:09 +0000 (+0200) Subject: ESMTP is utterly broken, and pulls OpenSSL. X-Git-Url: http://git.madism.org/?p=apps%2Fmadmutt.git;a=commitdiff_plain;h=4f8cd7c03aba20081ae3403ee194ce7e54f224fd;hp=e87df0bb071ba21d6e3d6a47cb797c135605eba5 ESMTP is utterly broken, and pulls OpenSSL. Broken in the sense that it cannot use mutt certificate cache e.g. or segfaults in the lib whereas I give correct parameters. I'm sure it's less than a thousands of line to write with gnutls and sasl. Signed-off-by: Pierre Habouzit --- diff --git a/CMakeLists.txt b/CMakeLists.txt index 0067433..2fa11d5 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -34,7 +34,6 @@ SET(MAILPATH CACHE STRING "Where new mail is spooled") OPTION(WITH_GPGME "Use GPGME [default: on]" ON) OPTION(WITH_NNTP "Build NNTP support [default: off]") OPTION(WITH_IDN "Use GNU libidn for domain names [default: off]") -OPTION(WITH_LIBESMTP "Use libESMTP [default: off]") OPTION(WITH_SLANG "Use S-Lang instead of ncurses [default:off]") OPTION(USE_FLOCK "Use flock to lock files [default: off]") @@ -241,11 +240,6 @@ IF(USE_HCACHE) ENDIF(NOT USE_HCACHE) ENDIF(USE_HCACHE) -IF(WITH_LIBESMTP) - SET(USE_LIBESMTP 1) - SET(MUTTLIBS "${MUTTLIBS} -lesmtp") -ENDIF(WITH_LIBESMTP) - IF(WITH_NNTP AND NOT USE_NNTP) SET(USE_NNTP 1) MESSAGE(STATUS "building NNTP support") diff --git a/config.h.cmake b/config.h.cmake index e9af40c..43d5853 100644 --- a/config.h.cmake +++ b/config.h.cmake @@ -77,6 +77,5 @@ #cmakedefine USE_FCNTL 1 #cmakedefine USE_FLOCK 1 #cmakedefine USE_HCACHE 1 -#cmakedefine USE_LIBESMTP 1 #cmakedefine USE_NNTP 1 #cmakedefine USE_SLANG_CURSES 1 diff --git a/configure b/configure index 5f3142e..52b7eb6 100755 --- a/configure +++ b/configure @@ -22,7 +22,7 @@ mkdir -p $builddir ln -s $builddir build if test $# -eq 0; then - cd $builddir && cmake -DWITH_NNTP=1 -DWITH_IDN=1 -DUSE_HCACHE=1 -DWITH_LIBESMTP=1 --with-prefix=/usr .. + cd $builddir && cmake -DWITH_NNTP=1 -DWITH_IDN=1 -DUSE_HCACHE=1 --with-prefix=/usr .. else cd $builddir && cmake "$@" .. fi diff --git a/globals.h b/globals.h index f2710a9..2b26cc1 100644 --- a/globals.h +++ b/globals.h @@ -102,13 +102,6 @@ WHERE char *SidebarBoundary; WHERE char *SignOffString; WHERE char *SimpleSearch; -#if defined(USE_LIBESMTP) -WHERE char *SmtpAuthUser; -WHERE char *SmtpAuthPass; -WHERE char *SmtpHost; -WHERE unsigned short SmtpPort; -WHERE char *SmtpUseTLS; -#endif WHERE char *Spoolfile; WHERE char *StChars; diff --git a/init.h b/init.h index 89dcb12..456f55b 100644 --- a/init.h +++ b/init.h @@ -66,21 +66,6 @@ struct option_t { /* build complete documentation */ -#ifdef _MAKEDOC -# ifndef USE_LIBESMTP -# define USE_LIBESMTP -# endif -# ifndef USE_NNTP -# define USE_NNTP -# endif -# ifndef USE_HCACHE -# define USE_HCACHE -# endif -# ifndef HAVE_LIBIDN -# define HAVE_LIBIDN -# endif -#endif - struct option_t MuttVars[] = { /*++*/ {"abort_noattach", DT_QUAD, R_NONE, OPT_ATTACH, "no" }, @@ -1531,64 +1516,6 @@ struct option_t MuttVars[] = { ** keyid (the hash-value that OpenSSL generates) to work properly ** (S/MIME only) */ -#if defined(USE_LIBESMTP) - {"smtp_user", DT_STR, R_NONE, UL &SmtpAuthUser, "" }, - /* - ** .pp - ** Availability: SMTP - ** - ** .pp - ** Defines the username to use with SMTP AUTH. Setting this variable will - ** cause Madmutt to attempt to use SMTP AUTH when sending. - */ - {"smtp_pass", DT_STR, R_NONE, UL &SmtpAuthPass, "" }, - /* - ** .pp - ** Availability: SMTP - ** - ** .pp - ** Defines the password to use with SMTP AUTH. If ``$$smtp_user'' - ** is set, but this variable is not, you will be prompted for a password - ** when sending. - ** .pp - ** \fBNote:\fP Storing passwords in a configuration file - ** presents a security risk since the superuser of your machine may read it - ** regardless of the file's permissions. - */ - {"smtp_host", DT_STR, R_NONE, UL &SmtpHost, "" }, - /* - ** .pp - ** Availability: SMTP - ** - ** .pp - ** Defines the SMTP host which will be used to deliver mail, as opposed - ** to invoking the sendmail binary. Setting this variable overrides the - ** value of ``$$sendmail'', and any associated variables. - */ - {"smtp_port", DT_NUM, R_NONE, UL &SmtpPort, "25" }, - /* - ** .pp - ** Availability: SMTP - ** - ** .pp - ** Defines the port that the SMTP host is listening on for mail delivery. - ** Must be specified as a number. - ** .pp - ** Defaults to 25, the standard SMTP port, but RFC 2476-compliant SMTP - ** servers will probably desire 587, the mail submission port. - */ - {"smtp_use_tls", DT_STR, R_NONE, UL &SmtpUseTLS, "" }, - /* - ** .pp - ** Availability: SMTP - ** - ** .pp - ** Defines wether to use STARTTLS. If this option is set to ``\fIrequired\fP'' - ** and the server does not support STARTTLS or there is an error in the - ** TLS Handshake, the connection will fail. Setting this to ``\fIenabled\fP'' - ** will try to start TLS and continue without TLS in case of an error. - */ -#endif {"pipe_split", DT_BOOL, R_NONE, OPTPIPESPLIT, "no" }, /* ** .pp diff --git a/lib-lua/madmutt.cpkg b/lib-lua/madmutt.cpkg index 5c2ebe7..7752312 100644 --- a/lib-lua/madmutt.cpkg +++ b/lib-lua/madmutt.cpkg @@ -287,7 +287,7 @@ static char *madmutt_init_hostname(void) /* ** .pp ** \fBNote:\fP you should not enable this unless you are using Sendmail - ** 8.8.x or greater or in connection with the SMTP support via libESMTP. + ** 8.8.x or greater. ** .pp ** This variable sets the request for when notification is returned. The ** string consists of a comma separated list (no spaces!) of one or more @@ -304,7 +304,7 @@ static char *madmutt_init_hostname(void) /* ** .pp ** \fBNote:\fP you should not enable this unless you are using Sendmail - ** 8.8.x or greater or in connection with the SMTP support via libESMTP. + ** 8.8.x or greater. ** .pp ** This variable controls how much of your message is returned in DSN ** messages. It may be set to either \fIhdrs\fP to return just the @@ -336,12 +336,11 @@ static char *madmutt_init_hostname(void) ** .pp ** \fBWarning:\fP do not set this variable unless you are using a version ** of sendmail which supports the \fT-B8BITMIME\fP flag (such as sendmail - ** 8.8.x) or in connection with the SMTP support via libESMTP. + ** 8.8.x). ** Otherwise you may not be able to send mail. ** .pp ** When \fIset\fP, Madmutt will either invoke ``$$sendmail'' with the \fT-B8BITMIME\fP - ** flag when sending 8-bit messages to enable ESMTP negotiation or tell - ** libESMTP to do so. + ** flag when sending 8-bit messages to enable ESMTP negotiation. */ bool use_8bitmime = 0; @@ -352,9 +351,8 @@ static char *madmutt_init_hostname(void) ** derive it from the "From:" header. ** ** .pp - ** \fBNote:\fP This information is passed - ** to sendmail command using the "-f" command line switch and - ** passed to the SMTP server for libESMTP (if support is compiled in). + ** \fBNote:\fP This information is passed to sendmail command using the + ** "-f" command line switch. */ bool use_envelope_from = 0; diff --git a/main.c b/main.c index 90d5e1a..801966b 100644 --- a/main.c +++ b/main.c @@ -49,10 +49,6 @@ extern int optind; #include #endif -#ifdef USE_LIBESMTP -#include -#endif - #ifdef USE_HCACHE #if defined(HAVE_QDBM) #include @@ -130,9 +126,6 @@ options:\n\ static void show_version (void) { struct utsname uts; -#ifdef USE_LIBESMTP - char buf[STRING]; -#endif puts (mutt_make_version()); puts (_(Notice)); @@ -165,11 +158,6 @@ static void show_version (void) stringprep_check_version (NULL), STRINGPREP_VERSION); #endif -#ifdef USE_LIBESMTP - smtp_version (buf, sizeof (buf), 0); - printf (" libESMTP %s\n", buf); -#endif - #ifdef USE_HCACHE #if defined(HAVE_QDBM) printf (" qdbm %s\n", dpversion); @@ -210,11 +198,6 @@ static void show_version (void) #else "-USE_NNTP " #endif -#ifdef USE_LIBESMTP - "+USE_LIBESMTP " -#else - "-USE_LIBESMTP " -#endif #ifdef HAVE_LIBIDN "+HAVE_LIBIDN " #else diff --git a/protos.h b/protos.h index 31ae4ed..e2915aa 100644 --- a/protos.h +++ b/protos.h @@ -145,11 +145,6 @@ int mutt_save_confirm (const char *, struct stat *); void ci_bounce_message (HEADER *, int *); int ci_send_message (int, HEADER *, char *, CONTEXT *, HEADER *); -#ifdef USE_LIBESMTP -int send_smtp_check_usetls (const char* option, unsigned long p, - char* errbuf, ssize_t errlen); -#endif - /* flags for mutt_extract_token() */ #define M_TOKEN_EQUAL (1 << 0) /* treat '=' as a special */ #define M_TOKEN_CONDENSE (1 << 1) /* ^(char) to control chars (macros) */ diff --git a/sendlib.c b/sendlib.c index 0f33616..0889c89 100644 --- a/sendlib.c +++ b/sendlib.c @@ -11,15 +11,6 @@ #include -#ifdef USE_LIBESMTP -#ifdef HAVE_GNUTLS_OPENSSL_H -#define SSL_SESSION_ASN1_VERSION -#include -#endif -#include -#include -#endif - #include #include #include @@ -47,373 +38,6 @@ #define EX_OK 0 #endif -#ifdef USE_LIBESMTP -static char authpass[STRING] = ""; - -#define FAIL() \ - do { \ - ret = -1; \ - goto Done; \ - } while (0) -#define MSGFAIL(msg) \ - do { \ - mutt_error("%s", msg); \ - FAIL(); \ - } while (0) -#define LIBCFAIL(msg) \ - do { \ - mutt_error("%s: %s", msg, strerror(errno)); \ - FAIL(); \ - } while (0) -#define SMTPFAIL(msg) \ - do { \ - _send_smtp_perror(msg); \ - FAIL(); \ - } while (0) -#define extna(msg) { mutt_error (_("SMTP Extension '%s' not supported by MTA."), \ - msg); sleep (1); } - -/* - * _send_smtp_ensure_init - * Make sure the libESMTP support in mutt is initialized at some time. - */ -static void _send_smtp_ensure_init () -{ - static int libesmtp_init = 0; - - if (!libesmtp_init) { - if (SmtpAuthUser) - auth_client_init (); - libesmtp_init = 1; - } -} - -/* - * _send_smtp_perror - * Prints 'msg', a colon, and then a string representation of the - * libesmtp errno as a mutt error. - */ -static void _send_smtp_perror (const char *msg) -{ - char buf[512]; - - mutt_error ("%s: %s", msg, - smtp_strerror (smtp_errno (), buf, sizeof (buf))); -} - -/* - * _send_smtp_add_recipients - * Adds every address in 'addr' as a recipient to the smtp message - * 'message'. Note that this does not mean that they will necessarily - * show up in the mail headers (e.g., when bcc'ing). Returns 0 upon - * success, -1 upon failure (and prints an error message). - * - * Very similar to sendlib.c::add_args - */ -static int -_send_smtp_add_recipients (smtp_message_t message, address_t * addr) -{ - int ret = 0; - - for (; addr; addr = addr->next) { - /* weed out group mailboxes, since those are for display only */ - if (addr->mailbox && !addr->group) { - if (!smtp_add_recipient (message, addr->mailbox)) - SMTPFAIL ("smtp_add_recipient"); - } - } - -Done: - return ret; -} - -static int -_send_smtp_auth_interact (auth_client_request_t request, - char **result, int fields, - void *arg __attribute__ ((unused))) -{ - int i; - - for (i = 0; i < fields; i++) { - if (request[i].flags & AUTH_USER) { - result[i] = SmtpAuthUser; - } else if (request[i].flags & AUTH_PASS) { - if (SmtpAuthPass) { - result[i] = SmtpAuthPass; - } else { - if (authpass[0] == '\0') { - char prompt[STRING]; - - snprintf(prompt, sizeof(prompt), "%s%s: ", request[i].prompt, - request[i].flags & AUTH_CLEARTEXT ? " (not encrypted)" : - ""); - mutt_get_field_unbuffered(prompt, authpass, sizeof(authpass), - M_PASS); - } - result[i] = authpass; - } - } - } - - return 1; -} - -#define BUFLEN 8192 - -static const char * -_send_smtp_messagefp_cb(void **buf, int *len, void *arg) -{ - int octets; - - if (*buf == NULL) - *buf = xmalloc(BUFLEN); - - if (len == NULL) { - rewind ((FILE *) arg); - return NULL; - } - - if (fgets (*buf, BUFLEN - 2, (FILE *) arg) == NULL) { - octets = 0; - } - else { - char *p = strchr (*buf, '\0'); - - if (p[-1] == '\n' && p[-2] != '\r') { - m_strcpy(p - 1, (char *) *buf + BUFLEN - p + 1, "\r\n"); - p++; - } - octets = p - (char *) *buf; - } - - *len = octets; - return *buf; -} - -static void event_cb (smtp_session_t session __attribute__ ((unused)), - 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*); - mutt_error (_("Error verifying certificate. Error Code: %lu"), vfy_result); - sleep(2); - *ok = 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 (m_strisempty(MTransport.dsn_notify) || !message || m_strisempty(from) || - strstr (MTransport.dsn_notify, "never") != NULL) - return; - - if (strstr (MTransport.dsn_notify, "failure") != NULL) - flags |= Notify_FAILURE; - if (strstr (MTransport.dsn_notify, "delay") != NULL) - flags |= Notify_DELAY; - if (strstr (MTransport.dsn_notify, "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 (m_strisempty(MTransport.dsn_return) || !message) - return; - if (ascii_strncasecmp (MTransport.dsn_return, "hdrs", 4) == 0) - smtp_dsn_set_ret (message, Ret_HDRS); - else if (ascii_strncasecmp (MTransport.dsn_return, "full", 4) == 0) - smtp_dsn_set_ret (message, Ret_FULL); -} - -int send_smtp_check_usetls (const char* option, unsigned long p, - char* errbuf, ssize_t errlen) { - char* val = (char*) p; - if (m_strisempty(val)) - return (1); - if (m_strncmp(val, "enabled", 7) != 0 && - m_strncmp(val, "required", 8) != 0) { - if (errbuf) - snprintf (errbuf, errlen, _("'%s' is invalid for %s"), val, option); - return (0); - } - return (1); -} - -/* - * send_smtp_invoke - * Sends a mail message to the provided recipients using libesmtp. - * Returns 0 upon success, -1 upon failure (and prints an error - * message). - */ -static int -send_smtp_invoke(address_t *from, address_t *to, address_t *cc, - address_t *bcc, const char *msg, int eightbit) -{ - int ret = 0; - smtp_session_t session; - smtp_message_t message; - char *hostportstr = NULL; - size_t hostportlen; - FILE *fp = NULL; - auth_context_t authctx = NULL; - const smtp_status_t *status; - char* envfrom = from->mailbox; - - _send_smtp_ensure_init (); - - if ((session = smtp_create_session ()) == NULL) - SMTPFAIL ("smtp_create_session"); - -#ifdef HAVE_GNUTLS_OPENSSL_H - if (!ascii_strncasecmp("enabled", SmtpUseTLS, 7)) { - smtp_starttls_enable(session, Starttls_ENABLED); - } else if (!ascii_strncasecmp("required", SmtpUseTLS, 8)) { - 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 = m_strlen(SmtpHost) + 7; - hostportstr = p_new(char, hostportlen); - snprintf (hostportstr, hostportlen, "%s:%d", SmtpHost, SmtpPort); - if (!smtp_set_server (session, hostportstr)) - SMTPFAIL ("smtp_set_server"); - - if (SmtpAuthUser) { - if ((authctx = auth_create_context ()) == NULL) - MSGFAIL ("auth_create_context failed"); - auth_set_mechanism_flags (authctx, AUTH_PLUGIN_PLAIN, 0); - auth_set_interact_cb (authctx, _send_smtp_auth_interact, NULL); - - if (!smtp_auth_set_context (session, authctx)) - SMTPFAIL ("smtp_auth_set_context"); - } - -#ifdef 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 (MTransport.use_envelope_from && MTransport.envelope_from_address) - envfrom = MTransport.envelope_from_address->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 && MTransport.use_8bitmime) - smtp_8bitmime_set_body (message, E8bitmime_8BITMIME); - - if ((fp = fopen (msg, "r")) == NULL) - LIBCFAIL ("fopen"); - if (!smtp_set_messagecb (message, _send_smtp_messagefp_cb, fp)) - SMTPFAIL ("smtp_set_messagecb"); - if (_send_smtp_add_recipients (message, to)) - FAIL (); - if (_send_smtp_add_recipients (message, cc)) - FAIL (); - if (_send_smtp_add_recipients (message, bcc)) - FAIL (); - if (!smtp_start_session (session)) - SMTPFAIL ("smtp_start_session"); - - status = smtp_message_transfer_status (message); - if (status->code < 200 || status->code > 299) { - char buf[256]; - - snprintf (buf, sizeof (buf), "SMTP error while sending: %d %s", - status->code, status->text); - MSGFAIL (buf); - } - -Done: - m_fclose(&fp); - if (hostportstr != NULL) - p_delete(&hostportstr); - if (session != NULL) - smtp_destroy_session (session); - if (authctx != NULL) - auth_destroy_context (authctx); - - /* Forget user-entered SMTP AUTH password if send fails */ - if (ret != 0) - authpass[0] = '\0'; - - return ret; -} -#endif - static void transform_to_7bit (BODY * a, FILE * fpin); static void encode_quoted (fgetconv_t * fc, FILE * fout, int istext) @@ -2183,11 +1807,9 @@ add_option(const char **args, ssize_t *argslen, ssize_t *argsmax, const char *s) return (args); } -static int mutt_invoke_sendmail (address_t * from, /* the sender */ - address_t * to, address_t * cc, address_t * bcc, /* recips */ - const char *msg, /* file containing message */ - int eightbit) -{ /* message contains 8bit chars */ +int mutt_invoke_mta(address_t *from, address_t *to, address_t *cc, + address_t *bcc, const char *msg, int eightbit) +{ char cmd[LONG_STRING]; char *ps = NULL, *path = NULL, *childout = NULL; const char **args = NULL; @@ -2293,22 +1915,6 @@ static int mutt_invoke_sendmail (address_t * from, /* the sender */ return (i); } -int mutt_invoke_mta (address_t * from, /* the sender */ - address_t * to, address_t * cc, address_t * bcc, /* recips */ - const char *msg, /* file containing message */ - int eightbit) -{ /* message contains 8bit chars */ -#ifdef USE_LIBESMTP -#ifdef USE_NNTP - if (!option (OPTNEWSSEND)) -#endif - if (SmtpHost) - return send_smtp_invoke (from, to, cc, bcc, msg, eightbit); -#endif - - return mutt_invoke_sendmail (from, to, cc, bcc, msg, eightbit); -} - /* For postponing (!final) do the necessary encodings only */ void mutt_prepare_envelope (ENVELOPE * env, int final) {