edit.c enter.c flags.c init.c filter.c from.c \
getdomain.c group.c \
handler.c hash.c hdrline.c headers.c help.c hook.c keymap.c \
- main.c mbox.c menu.c mh.c mx.c pager.c parse.c pattern.c \
+ main.c mbox.c menu.c mh.c mutt_sasl_plain.c mx.c pager.c parse.c pattern.c \
postpone.c query.c recvattach.c recvcmd.c \
rfc822.c rfc1524.c rfc2047.c rfc2231.c rfc3676.c \
score.c send.c sendlib.c signal.c sort.c \
attach.h buffy.h charset.h compress.h copy.h crypthash.h dotlock.h functions.h gen_defs \
globals.h hash.h history.h init.h keymap.h mutt_crypt.h \
mailbox.h mapping.h md5.h mime.h mutt.h mutt_curses.h mutt_menu.h \
- mutt_regex.h mutt_sasl.h mutt_socket.h mutt_ssl.h mutt_tunnel.h \
- mx.h pager.h pgp.h pop.h protos.h rfc1524.h rfc2047.h \
+ mutt_regex.h mutt_sasl.h mutt_sasl_plain.h mutt_socket.h mutt_ssl.h \
+ mutt_tunnel.h mx.h pager.h pgp.h pop.h protos.h rfc1524.h rfc2047.h \
rfc2231.h rfc822.h rfc3676.h sha1.h sort.h mime.types \
nntp.h ChangeLog.nntp \
_regex.h OPS.MIX README.SECURITY remailer.c remailer.h browser.h \
noinst_LIBRARIES = libimap.a
noinst_HEADERS = auth.h imap_private.h message.h
-libimap_a_SOURCES = auth.c auth_login.c browse.c command.c imap.c imap.h \
- message.c utf7.c util.c $(AUTHENTICATORS) $(GSSSOURCES)
+libimap_a_SOURCES = auth.c auth_plain.c auth_login.c browse.c command.c \
+ imap.c imap.h message.c utf7.c util.c $(AUTHENTICATORS) $(GSSSOURCES)
#include "auth.h"
static const imap_auth_t imap_authenticators[] = {
+ { imap_auth_plain, "plain" },
#ifdef USE_SASL
{ imap_auth_sasl, NULL },
#else
} imap_auth_t;
/* external authenticator prototypes */
+imap_auth_res_t imap_auth_plain (IMAP_DATA *idata, const char *method);
#ifndef USE_SASL
imap_auth_res_t imap_auth_anon (IMAP_DATA* idata, const char* method);
imap_auth_res_t imap_auth_cram_md5 (IMAP_DATA* idata, const char* method);
--- /dev/null
+/*
+ * Copyright (C) 1999-2001,2005,2009 Brendan Cully <brendan@kublai.com>
+ * Copyright (C) 2016 Pietro Cerutti <gahr@gahr.ch>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+/* SASL PLAIN support */
+
+#if HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include "mutt.h"
+#include "imap_private.h"
+#include "mutt_sasl_plain.h"
+#include "auth.h"
+
+/* imap_auth_plain: SASL PLAIN support */
+imap_auth_res_t imap_auth_plain(IMAP_DATA *idata, const char *method)
+{
+ char buf[STRING];
+
+ if (mutt_account_getuser(&idata->conn->account))
+ return IMAP_AUTH_FAILURE;
+ if (mutt_account_getpass(&idata->conn->account))
+ return IMAP_AUTH_FAILURE;
+
+ mutt_message _("Logging in...");
+
+ mutt_sasl_plain_msg(buf, STRING, "AUTHENTICATE PLAIN",
+ idata->conn->account.user, idata->conn->account.user,
+ idata->conn->account.pass);
+
+ if (!imap_exec(idata, buf, IMAP_CMD_FAIL_OK | IMAP_CMD_PASS))
+ {
+ mutt_clear_error(); /* clear "Logging in...". fixes #3524 */
+ return IMAP_AUTH_SUCCESS;
+ }
+
+ mutt_error _("Login failed.");
+ mutt_sleep(2);
+ return IMAP_AUTH_FAILURE;
+}
+
** (S/MIME only)
*/
#ifdef USE_SMTP
-# ifdef USE_SASL
{ "smtp_authenticators", DT_STR, R_NONE, UL &SmtpAuthenticators, UL 0 },
/*
** .pp
** This is a colon-delimited list of authentication methods mutt may
** attempt to use to log in to an SMTP server, in the order mutt should
- ** try them. Authentication methods are any SASL mechanism, e.g.
+ ** try them. Authentication methods are any SASL mechanism, e.g. ``plain'',
** ``digest-md5'', ``gssapi'' or ``cram-md5''.
** This option is case-insensitive. If it is ``unset''
** (the default) mutt will try all available methods, in order from
- ** most-secure to least-secure.
+ ** most-secure to least-secure. Support for the ``plain'' mechanism is
+ ** bundled; other mechanisms are provided by an external SASL library (look
+ ** for +USE_SASL in the output of mutt -v).
** .pp
** Example:
** .ts
** set smtp_authenticators="digest-md5:cram-md5"
** .te
*/
-# endif /* USE_SASL */
{ "smtp_pass", DT_STR, R_NONE|F_SENSITIVE, UL &SmtpPass, UL 0 },
/*
** .pp
--- /dev/null
+/*
+ * Copyright (C) 2016 Pietro Cerutti <gahr@gahr.ch>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include "mutt.h"
+#include "mutt_sasl_plain.h"
+
+size_t mutt_sasl_plain_msg(char *buf, size_t buflen, const char *cmd,
+ const char *authz, const char *user,
+ const char *pass)
+{
+ /* authz, user, and pass can each be up to 255 bytes, making up for a 765
+ * bytes string. Add the two NULL bytes in between plus one at the end and we
+ * get 768. */
+ char tmp[768];
+ size_t len;
+ size_t tmplen;
+
+ if (!user || !*user || !pass || !*pass)
+ return 0;
+
+ tmplen = snprintf(tmp, sizeof(tmp), "%s%c%s%c%s", NONULL(authz), '\0', user,
+ '\0', pass);
+
+ len = snprintf(buf, buflen, "%s ", cmd);
+ len += mutt_to_base64(buf + len, tmp, tmplen, buflen - len);
+ return len;
+}
--- /dev/null
+/*
+ * Copyright (C) 2016 Pietro Cerutti <gahr@gahr.ch>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+#ifndef _MUTT_SASL_PLAIN_H_
+#define _MUTT_SASL_PLAIN_H_
+
+#include <stdlib.h> /* for size_t */
+
+/**
+ * mutt_sasl_plain_msg - construct a base64 encoded SASL PLAIN message
+ * @param buf Destination buffer.
+ * @param buflen Available space in the destination buffer.
+ * @param cmd Protocol-specific string the prepend to the PLAIN message.
+ * @param authz Authorization identity.
+ * @param user Authentication identity (username).
+ * @param pass Password.
+ *
+ * @return The number of bytes written to buf.
+ *
+ * This function can be used to build a protocol-specific SASL Response message
+ * using the PLAIN mechanism. The protocol specific command is given in the cmd
+ * parameter. The function appends a space, encodes the string derived from
+ * authz\0user\0pass using base64 encoding, and stores the result in buf.
+ *
+ * Example usages for IMAP and SMTP, respectively:
+ *
+ * mutt_sasl_plain_msg(buf, sizeof(buf), "AUTHENTICATE PLAIN", user, user, pass);
+ * mutt_sasl_plain_msg(buf, sizeof(buf), "AUTH PLAIN", NULL, user, pass);
+ */
+size_t mutt_sasl_plain_msg(char *buf, size_t buflen, const char *cmd,
+ const char *authz, const char *user,
+ const char *pass);
+
+#endif /* _MUTT_SASL_PLAIN_H_ */
#include <sasl/sasl.h>
#include <sasl/saslutil.h>
+#else
+#include "mutt_sasl_plain.h"
#endif
#include <netdb.h>
#ifdef USE_SASL
static int smtp_auth (CONNECTION* conn);
static int smtp_auth_sasl (CONNECTION* conn, const char* mechanisms);
+#else
+static int smtp_auth_plain (CONNECTION* conn);
#endif
static int smtp_fill_account (ACCOUNT* account);
#ifdef USE_SASL
return smtp_auth (conn);
#else
- mutt_error (_("SMTP authentication requires SASL"));
- mutt_sleep (1);
- return -1;
+ return smtp_auth_plain (conn);
#endif /* USE_SASL */
}
FREE (&buf);
return SMTP_AUTH_FAIL;
}
+#else /* USE_SASL */
+
+static int smtp_auth_plain(CONNECTION* conn)
+{
+ char buf[LONG_STRING];
+ size_t len;
+ const char *method;
+ const char *delim;
+ const char *error = _("SASL authentication failed");
+
+ if (!SmtpAuthenticators || !*SmtpAuthenticators)
+ {
+ goto error;
+ }
+
+ /* Check if any elements in SmtpAuthenticators is "plain" */
+ for (method = delim = SmtpAuthenticators;
+ *delim && (delim = mutt_strchrnul(method, ':'));
+ method = delim + 1)
+ {
+ if (ascii_strncasecmp(method, "plain", 5) == 0)
+ {
+ /* Get username and password. Bail out of any cannot be retrieved. */
+ if (mutt_account_getuser(&conn->account) ||
+ mutt_account_getpass(&conn->account))
+ {
+ goto error;
+ }
+
+ /* Build the initial client response. */
+ len = mutt_sasl_plain_msg(buf, sizeof(buf), "AUTH PLAIN",
+ conn->account.user, conn->account.user, conn->account.pass);
+
+ /* Terminate as per SMTP protocol. Bail out if there's no room left. */
+ if (snprintf(buf + len, sizeof(buf) - len, "\r\n") != 2)
+ {
+ goto error;
+ }
+
+ /* Send request, receive response (with a check for OK code). */
+ if ((mutt_socket_write(conn, buf) < 0) || smtp_get_resp(conn))
+ {
+ goto error;
+ }
+
+ /* If we got here, auth was successful. */
+ return 0;
+ }
+ }
+
+ error = _("No authenticators available");
+
+error:
+ mutt_error(error);
+ mutt_sleep(1);
+ return -1;
+}
#endif /* USE_SASL */