X-Git-Url: http://git.madism.org/?p=apps%2Fmadmutt.git;a=blobdiff_plain;f=sendlib.c;h=33129ed19d0519a36342598a12467427783da55b;hp=8891280168f55ca88348e2cb1ca32860118d4921;hb=dc726add2e8fe52be1f6859ea7cbe4651498eeb8;hpb=5ef16452ce43a12e467e7004a6a240aefb87a774 diff --git a/sendlib.c b/sendlib.c index 8891280..33129ed 100644 --- a/sendlib.c +++ b/sendlib.c @@ -11,17 +11,11 @@ #include -#ifdef USE_LIBESMTP -#include -#include -#endif - #include #include #include #include -#include -#include +#include #include #include "mutt.h" @@ -33,393 +27,12 @@ #include "charset.h" #include "mutt_idna.h" -#ifdef USE_NNTP -#include -#endif - #ifdef HAVE_SYSEXITS_H #include #else /* Make sure EX_OK is defined */ #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 int handle_invalid_peer_certificate (long vfy_result) { -#if 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 __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*); - *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 (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) -{ /* message contains 8bit chars */ - int ret = 0; /* return value, default = success */ - 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 (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 = 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) @@ -1630,17 +1243,13 @@ BODY *mutt_remove_multipart (BODY * b) char *mutt_make_date (char *s, ssize_t len) { - time_t t = time (NULL); - struct tm *l = localtime (&t); - time_t tz = mutt_local_tz (t); + time_t t = time(NULL); + const char *loc; - tz /= 60; - - snprintf (s, len, "Date: %s, %d %s %d %02d:%02d:%02d %+03d%02d\n", - Weekdays[l->tm_wday], l->tm_mday, Months[l->tm_mon], - l->tm_year + 1900, l->tm_hour, l->tm_min, l->tm_sec, - (int) tz / 60, (int) abs (tz) % 60); - return (s); + loc = setlocale(LC_TIME, "C"); + strftime(s, len, "Date: %a, %d %b %Y %T %z\n", localtime(&t)); + setlocale(LC_TIME, loc); + return s; } /* wrapper around mutt_write_address() so we can handle very large @@ -1724,30 +1333,22 @@ static int edit_header(int mode, const char *s) * mode == 1 => "lite" mode (used for edit_hdrs) * mode == 0 => normal mode. write full header + MIME headers * mode == -1 => write just the envelope info (used for postponing messages) - * - * privacy != 0 => will omit any headers which may identify the user. - * Output generated is suitable for being sent through - * anonymous remailer chains. - * */ int mutt_write_rfc822_header (FILE * fp, ENVELOPE * env, BODY * attach, - int mode, int privacy) + int mode) { char buffer[LONG_STRING]; char *p; string_list_t *tmp = env->userhdrs; int has_agent = 0; /* user defined user-agent header field exists */ -#ifdef USE_NNTP - if (!option (OPTNEWSSEND)) -#endif - if (mode == 0 && !privacy) - fputs (mutt_make_date (buffer, sizeof (buffer)), fp); + if (mode == 0) + fputs (mutt_make_date (buffer, sizeof (buffer)), fp); /* OPTUSEFROM is not consulted here so that we can still write a From: * field if the user sets it with the `my_hdr' command */ - if (env->from && !privacy) { + if (env->from) { buffer[0] = 0; rfc822_addrcat(buffer, sizeof(buffer), env->from, 0); fprintf (fp, "From: %s\n", buffer); @@ -1758,22 +1359,16 @@ int mutt_write_rfc822_header (FILE * fp, ENVELOPE * env, BODY * attach, mutt_write_address_list (env->to, fp, 4, 0); } else if (mode > 0) -#ifdef USE_NNTP - if (!option (OPTNEWSSEND)) -#endif - if (edit_header(mode, "To:")) - fputs ("To:\n", fp); + if (edit_header(mode, "To:")) + fputs ("To:\n", fp); if (env->cc) { fputs ("Cc: ", fp); mutt_write_address_list (env->cc, fp, 4, 0); } else if (mode > 0) -#ifdef USE_NNTP - if (!option (OPTNEWSSEND)) -#endif - if (edit_header(mode, "Cc:")) - fputs ("Cc:\n", fp); + if (edit_header(mode, "Cc:")) + fputs ("Cc:\n", fp); if (env->bcc) { if (mode != 0 || option (OPTWRITEBCC)) { @@ -1782,23 +1377,8 @@ int mutt_write_rfc822_header (FILE * fp, ENVELOPE * env, BODY * attach, } } else if (mode > 0) -#ifdef USE_NNTP - if (!option (OPTNEWSSEND)) -#endif - if (edit_header(mode, "Bcc:")) - fputs ("Bcc:\n", fp); - -#ifdef USE_NNTP - if (env->newsgroups) - fprintf (fp, "Newsgroups: %s\n", env->newsgroups); - else if (mode == 1 && option (OPTNEWSSEND) && edit_header(mode, "Newsgroups:")) - fputs ("Newsgroups:\n", fp); - - if (env->followup_to) - fprintf (fp, "Followup-To: %s\n", env->followup_to); - else if (mode == 1 && option (OPTNEWSSEND) && edit_header(mode, "Followup-To:")) - fputs ("Followup-To:\n", fp); -#endif + if (edit_header(mode, "Bcc:")) + fputs ("Bcc:\n", fp); if (env->subject) fprintf (fp, "Subject: %s\n", env->subject); @@ -1806,7 +1386,7 @@ int mutt_write_rfc822_header (FILE * fp, ENVELOPE * env, BODY * attach, fputs ("Subject:\n", fp); /* save message id if the user has set it */ - if (env->message_id && !privacy) + if (env->message_id) fprintf (fp, "Message-ID: %s\n", env->message_id); if (env->reply_to) { @@ -1816,14 +1396,10 @@ int mutt_write_rfc822_header (FILE * fp, ENVELOPE * env, BODY * attach, else if (mode > 0 && edit_header(mode, "Reply-To:")) fputs ("Reply-To:\n", fp); - if (env->mail_followup_to) -#ifdef USE_NNTP - if (!option (OPTNEWSSEND)) -#endif - { - fputs ("Mail-Followup-To: ", fp); - mutt_write_address_list (env->mail_followup_to, fp, 18, 0); - } + if (env->mail_followup_to) { + fputs ("Mail-Followup-To: ", fp); + mutt_write_address_list (env->mail_followup_to, fp, 18, 0); + } if (mode <= 0) { if (env->references) { @@ -1853,8 +1429,6 @@ int mutt_write_rfc822_header (FILE * fp, ENVELOPE * env, BODY * attach, /* check to see if the user has overridden the user-agent field */ if (!ascii_strncasecmp ("user-agent", tmp->data, 10)) { has_agent = 1; - if (privacy) - continue; } fputs (tmp->data, fp); @@ -1862,7 +1436,7 @@ int mutt_write_rfc822_header (FILE * fp, ENVELOPE * env, BODY * attach, } } - if (mode == 0 && !privacy && option (OPTXMAILER) && !has_agent) { + if (mode == 0 && option (OPTXMAILER) && !has_agent) { if (mod_core.operating_system) { fprintf(fp, "User-Agent: %s (%s)\n", mutt_make_version(), mod_core.operating_system); @@ -2189,30 +1763,16 @@ 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; ssize_t argslen = 0, argsmax = 0; int i; -#ifdef USE_NNTP - if (option (OPTNEWSSEND)) { - m_strformat(cmd, sizeof(cmd), 0, Inews, nntp_format_str, 0, 0); - if (m_strisempty(cmd)) { - i = nntp_post (msg); - unlink (msg); - return i; - } - } else -#endif - { - m_strcpy(cmd, sizeof(cmd), MTransport.sendmail); - } + m_strcpy(cmd, sizeof(cmd), MTransport.sendmail); ps = cmd; i = 0; @@ -2235,36 +1795,30 @@ static int mutt_invoke_sendmail (address_t * from, /* the sender */ i++; } -#ifdef USE_NNTP - if (!option (OPTNEWSSEND)) { -#endif - if (eightbit && MTransport.use_8bitmime) - args = add_option(args, &argslen, &argsmax, "-B8BITMIME"); - - if (MTransport.use_envelope_from) { - address_t *f = MTransport.envelope_from_address; - if (!f && from && !from->next) - f = from; - if (f) { - args = add_option (args, &argslen, &argsmax, "-f"); - args = add_args (args, &argslen, &argsmax, f); - } - } - if (MTransport.dsn_notify) { - args = add_option (args, &argslen, &argsmax, "-N"); - args = add_option (args, &argslen, &argsmax, MTransport.dsn_notify); - } - if (MTransport.dsn_return) { - args = add_option (args, &argslen, &argsmax, "-R"); - args = add_option (args, &argslen, &argsmax, MTransport.dsn_return); + if (eightbit && MTransport.use_8bitmime) + args = add_option(args, &argslen, &argsmax, "-B8BITMIME"); + + if (MTransport.use_envelope_from) { + address_t *f = MTransport.envelope_from_address; + if (!f && from && !from->next) + f = from; + if (f) { + args = add_option (args, &argslen, &argsmax, "-f"); + args = add_args (args, &argslen, &argsmax, f); } - args = add_option (args, &argslen, &argsmax, "--"); - args = add_args (args, &argslen, &argsmax, to); - args = add_args (args, &argslen, &argsmax, cc); - args = add_args (args, &argslen, &argsmax, bcc); -#ifdef USE_NNTP } -#endif + if (MTransport.dsn_notify) { + args = add_option (args, &argslen, &argsmax, "-N"); + args = add_option (args, &argslen, &argsmax, MTransport.dsn_notify); + } + if (MTransport.dsn_return) { + args = add_option (args, &argslen, &argsmax, "-R"); + args = add_option (args, &argslen, &argsmax, MTransport.dsn_return); + } + args = add_option (args, &argslen, &argsmax, "--"); + args = add_args (args, &argslen, &argsmax, to); + args = add_args (args, &argslen, &argsmax, cc); + args = add_args (args, &argslen, &argsmax, bcc); if (argslen >= argsmax) p_realloc(&args, ++argsmax); @@ -2299,22 +1853,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) { @@ -2439,15 +1977,8 @@ int mutt_bounce_message (FILE * fp, HEADER * h, address_t * to) return -1; } rfc822_addrcat(resent_from, sizeof(resent_from), from, 0); - -#ifdef USE_NNTP - unset_option (OPTNEWSSEND); -#endif - ret = _mutt_bounce_message (fp, h, to, resent_from, from); - address_list_wipe(&from); - return ret; } @@ -2499,7 +2030,7 @@ int mutt_write_fcc (const char *path, HEADER * hdr, const char *msgid, /* post == 1 => postpone message. Set mode = -1 in mutt_write_rfc822_header() * post == 0 => Normal mode. Set mode = 0 in mutt_write_rfc822_header() * */ - mutt_write_rfc822_header(msg->fp, hdr->env, hdr->content, -post, 0); + mutt_write_rfc822_header(msg->fp, hdr->env, hdr->content, -post); /* (postponment) if this was a reply of some sort, contians the * Message-ID: of message replied to. Save it using a special X-Mutt- @@ -2550,19 +2081,6 @@ int mutt_write_fcc (const char *path, HEADER * hdr, const char *msgid, fputc ('\n', msg->fp); } - /* (postponement) if the mail is to be sent through a mixmaster - * chain, save that information - */ - if (post && hdr->chain && hdr->chain) { - string_list_t *p; - - fputs ("X-Mutt-Mix:", msg->fp); - for (p = hdr->chain; p; p = p->next) - fprintf (msg->fp, " %s", (char *) p->data); - - fputc ('\n', msg->fp); - } - if (tempfp) { char sasha[LONG_STRING]; int lines = 0;