-/*
+/**
+ * @file
+ * IMAP OAUTH authentication method
+ *
+ * @authors
* Copyright (C) 1999-2001,2005 Brendan Cully <brendan@kublai.com>
* Copyright (C) 2018 Brandon Long <blong@fiction.net>
- *
- * 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.
+ *
+ * @copyright
+ * 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, see <http://www.gnu.org/licenses/>.
*/
-/* IMAP login/authentication code */
+/**
+ * @page imap_auth_oauth IMAP OAUTH authentication method
+ *
+ * IMAP OAUTH authentication method
+ */
#include "config.h"
#include "imap_private.h"
#include "mutt_socket.h"
#include "muttlib.h"
-/* imap_auth_oauth: AUTH=OAUTHBEARER support. See RFC 7628 */
+/**
+ * imap_auth_oauth - Authenticate an IMAP connection using OAUTHBEARER
+ * @param idata Server data
+ * @param method Name of this authentication method (UNUSED)
+ * @retval num Result, e.g. #IMAP_AUTH_SUCCESS
+ */
enum ImapAuthRes imap_auth_oauth(struct ImapData *idata, const char *method)
{
char *ibuf = NULL;
/* For now, we only support SASL_IR also and over TLS */
if (!mutt_bit_isset(idata->capabilities, AUTH_OAUTHBEARER) ||
!mutt_bit_isset(idata->capabilities, SASL_IR) || !idata->conn->ssf)
+ {
return IMAP_AUTH_UNAVAIL;
+ }
mutt_message(_("Authenticating (OAUTHBEARER)..."));
/* We get the access token from the imap_oauth_refresh_command */
oauthbearer = mutt_account_getoauthbearer(&idata->conn->account);
- if (oauthbearer == NULL)
+ if (!oauthbearer)
return IMAP_AUTH_FAILURE;
ilen = mutt_str_strlen(oauthbearer) + 30;
}
mutt_error(_("OAUTHBEARER authentication failed."));
- mutt_sleep(2);
return IMAP_AUTH_FAILURE;
}
/* These Config Variables are only used in mutt_account.c */
char *ImapLogin; ///< Config: (imap) Login name for the IMAP server (defaults to ImapUser)
-char *ImapOauthRefreshCmd;
+char *ImapOauthRefreshCmd; ///< Config: (imap) External command to generate OAUTH refresh token
char *ImapPass; ///< Config: (imap) Password for the IMAP server
char *NntpPass; ///< Config: (nntp) Password for the news server
char *NntpUser; ///< Config: (nntp) Username for the news server
+char *PopOauthRefreshCmd; ///< Config: (pop) External command to generate OAUTH refresh token
char *PopPass; ///< Config: (pop) Password of the POP server
char *PopUser; ///< Config: (pop) Username of the POP server
+char *SmtpOauthRefreshCmd; ///< Config: (smtp) External command to generate OAUTH refresh token
char *SmtpPass; ///< Config: (smtp) Password for the SMTP server
-char *SmtpOauthRefreshCmd;
/**
* mutt_account_match - Compare account info (host/port/user)
account->flags &= ~MUTT_ACCT_PASS;
}
-/* mutt_account_getoauthbearer: call external command to generate the
- * oauth refresh token for this ACCOUNT, then create and encode the
- * OAUTHBEARER token based on RFC 7628. Returns NULL on failure.
- * Resulting token is dynamically allocated and should be FREE'd by the
- * caller.
+/**
+ * mutt_account_getoauthbearer - Get an OAUTHBEARER token
+ * @param account Account to use
+ * @retval ptr OAuth token
+ * @retval NULL Error
+ *
+ * Run an external command to generate the oauth refresh token for an account,
+ * then create and encode the OAUTHBEARER token based on RFC7628.
+ *
+ * @note Caller should free the token
*/
char *mutt_account_getoauthbearer(struct Account *account)
{
cmd = SmtpOauthRefreshCmd;
#endif
- if (cmd == NULL)
+ if (!cmd)
{
mutt_error(
_("mutt_account_getoauthbearer: No OAUTH refresh command defined"));
return NULL;
}
- if ((pid = mutt_create_filter(cmd, NULL, &fp, NULL)) < 0)
+ pid = mutt_create_filter(cmd, NULL, &fp, NULL);
+ if (pid < 0)
{
mutt_perror(
_("mutt_account_getoauthbearer: Unable to run refresh command"));
return NULL;
}
- /* read line */
token = mutt_file_read_line(NULL, &token_size, fp, NULL, 0);
mutt_file_fclose(&fp);
mutt_wait_filter(pid);
- if (token == NULL || *token == '\0')
+ if (!token || *token == '\0')
{
mutt_error(_("mutt_account_getoauthbearer: Command returned empty string"));
FREE(&token);
return NULL;
}
- /* Determine the length of the keyed message digest, add 50 for
- * overhead.
- */
+ /* Determine the length of the keyed message digest, add 50 for overhead. */
oalen = strlen(account->login) + strlen(account->host) + strlen(token) + 50;
oauthbearer = mutt_mem_malloc(oalen);
extern char *ImapPass;
extern char *NntpPass;
extern char *NntpUser;
+extern char *PopOauthRefreshCmd;
extern char *PopPass;
extern char *PopUser;
-extern char *SmtpPass;
extern char *SmtpOauthRefreshCmd;
+extern char *SmtpPass;
/**
* enum AccountType - account types
short PopCheckinterval; ///< Config: (pop) Interval between checks for new mail
unsigned char PopDelete; ///< Config: (pop) After downloading POP messages, delete them on the server
char *PopHost; ///< Config: (pop) Url of the POP server
-char *PopOauthRefreshCmd;
bool PopLast; ///< Config: (pop) Use the 'LAST' command to fetch new mail
#ifdef USE_HCACHE
extern short PopCheckinterval;
extern unsigned char PopDelete;
extern char * PopHost;
-extern char *PopOauthRefreshCmd;
extern bool PopLast;
/* These Config Variables are only used in pop/pop_auth.c */
return POP_A_FAILURE;
}
-/* OAUTHBEARER authenticator */
+/**
+ * pop_auth_oauth - Authenticate a POP connection using OAUTHBEARER
+ * @param pop_data POP Server data
+ * @param method Name of this authentication method (UNUSED)
+ * @retval num Result, e.g. #POP_A_SUCCESS
+ */
static enum PopAuthRes pop_auth_oauth(struct PopData *pop_data, const char *method)
{
char *oauthbearer = NULL;
mutt_message(_("Authenticating (OAUTHBEARER)..."));
oauthbearer = mutt_account_getoauthbearer(&pop_data->conn->account);
- if (oauthbearer == NULL)
+ if (!oauthbearer)
return POP_A_FAILURE;
auth_cmd_len = strlen(oauthbearer) + 30;
ret = pop_query_d(pop_data, auth_cmd, strlen(auth_cmd),
#ifdef DEBUG
/* don't print the bearer token unless we're at the ungodly debugging level */
- DebugLevel < MUTT_SOCK_LOG_FULL ? "AUTH OAUTHBEARER *\r\n" :
+ (DebugLevel < MUTT_SOCK_LOG_FULL) ? "AUTH OAUTHBEARER *\r\n" :
#endif
NULL);
FREE(&auth_cmd);
}
/* The error response was a SASL continuation, so "continue" it.
- * See RFC 7628 3.2.3
- */
+ * See RFC7628 3.2.3 */
mutt_socket_send(pop_data->conn, "\001");
err = pop_data->err_msg;
}
#endif
-/* smtp_auth_oauth: AUTH=OAUTHBEARER support. See RFC 7628 */
+/**
+ * smtp_auth_oauth - Authenticate an SMTP connection using OAUTHBEARER
+ * @param conn Connection info
+ * @retval num Result, e.g. #SMTP_AUTH_SUCCESS
+ */
static int smtp_auth_oauth(struct Connection *conn)
{
- char *ibuf = NULL;
- char *oauthbearer = NULL;
- int ilen;
- int rc;
-
mutt_message(_("Authenticating (OAUTHBEARER)..."));
/* We get the access token from the smtp_oauth_refresh_command */
- oauthbearer = mutt_account_getoauthbearer(&conn->account);
- if (oauthbearer == NULL)
+ char *oauthbearer = mutt_account_getoauthbearer(&conn->account);
+ if (!oauthbearer)
return SMTP_AUTH_FAIL;
- ilen = strlen(oauthbearer) + 30;
- ibuf = mutt_mem_malloc(ilen);
+ size_t ilen = strlen(oauthbearer) + 30;
+ char *ibuf = mutt_mem_malloc(ilen);
snprintf(ibuf, ilen, "AUTH OAUTHBEARER %s\r\n", oauthbearer);
- rc = mutt_socket_send(conn, ibuf);
+ int rc = mutt_socket_send(conn, ibuf);
FREE(&oauthbearer);
FREE(&ibuf);
mutt_debug(2, "Trying method %s\n", method);
- if (!strcmp(method, "oauthbearer"))
+ if (strcmp(method, "oauthbearer") == 0)
{
r = smtp_auth_oauth(conn);
}