NeoMutt  2021-10-29-43-g6b8931
Teaching an old dog new tricks
DOXYGEN
auth_oauth.c File Reference

IMAP OAUTH authentication method. More...

#include "config.h"
#include <stdbool.h>
#include <stdio.h>
#include "private.h"
#include "mutt/lib.h"
#include "config/lib.h"
#include "core/lib.h"
#include "conn/lib.h"
#include "auth.h"
#include "adata.h"
#include "mutt_logging.h"
#include "mutt_socket.h"
+ Include dependency graph for auth_oauth.c:

Go to the source code of this file.

Functions

enum ImapAuthRes imap_auth_oauth_xoauth2 (struct ImapAccountData *adata, const char *method, bool xoauth2)
 Authenticate an IMAP connection using OAUTHBEARER or XOAUTH2. More...
 
enum ImapAuthRes imap_auth_oauth (struct ImapAccountData *adata, const char *method)
 Authenticate an IMAP connection using OAUTHBEARER - Implements ImapAuth::authenticate() More...
 
enum ImapAuthRes imap_auth_xoauth2 (struct ImapAccountData *adata, const char *method)
 Authenticate an IMAP connection using XOAUTH2 - Implements ImapAuth::authenticate() More...
 

Detailed Description

IMAP OAUTH authentication method.

Authors
  • Brendan Cully
  • Brandon Long

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/.

Definition in file auth_oauth.c.

Function Documentation

◆ imap_auth_oauth_xoauth2()

enum ImapAuthRes imap_auth_oauth_xoauth2 ( struct ImapAccountData adata,
const char *  method,
bool  xoauth2 
)

Authenticate an IMAP connection using OAUTHBEARER or XOAUTH2.

Parameters
adataImap Account data
methodUse this named method, or any available method if NULL
xoauth2Use xoauth2 token (if true) or oauthbearer token (if false)
Return values
numImapAuth::ImapAuthRes Result, e.g. IMAP_AUTH_SUCCESS

Definition at line 1 of file auth_oauth.c.

52 {
53  char *ibuf = NULL;
54  char *oauthbearer = NULL;
55  const char *authtype = xoauth2 ? "XOAUTH2" : "OAUTHBEARER";
56  int ilen;
57  int rc;
58 
59  /* For now, we only support SASL_IR also and over TLS */
60  if ((xoauth2 && !(adata->capabilities & IMAP_CAP_AUTH_XOAUTH2)) ||
61  (!xoauth2 && !(adata->capabilities & IMAP_CAP_AUTH_OAUTHBEARER)) ||
62  !(adata->capabilities & IMAP_CAP_SASL_IR) || (adata->conn->ssf == 0))
63  {
64  return IMAP_AUTH_UNAVAIL;
65  }
66 
67  /* If they did not explicitly request or configure oauth then fail quietly */
68  const char *const c_imap_oauth_refresh_command =
69  cs_subset_string(NeoMutt->sub, "imap_oauth_refresh_command");
70  if (!method && !c_imap_oauth_refresh_command)
71  return IMAP_AUTH_UNAVAIL;
72 
73  // L10N: (%s) is the method name, e.g. Anonymous, CRAM-MD5, GSSAPI, SASL
74  mutt_message(_("Authenticating (%s)..."), authtype);
75 
76  /* We get the access token from the imap_oauth_refresh_command */
77  oauthbearer = mutt_account_getoauthbearer(&adata->conn->account, xoauth2);
78  if (!oauthbearer)
79  return IMAP_AUTH_FAILURE;
80 
81  ilen = mutt_str_len(oauthbearer) + 30;
82  ibuf = mutt_mem_malloc(ilen);
83  snprintf(ibuf, ilen, "AUTHENTICATE %s %s", authtype, oauthbearer);
84 
85  /* This doesn't really contain a password, but the token is good for
86  * an hour, so suppress it anyways. */
87  rc = imap_exec(adata, ibuf, IMAP_CMD_PASS);
88 
89  FREE(&oauthbearer);
90  FREE(&ibuf);
91 
92  if (rc != IMAP_EXEC_SUCCESS)
93  {
94  /* The error response was in SASL continuation, so continue the SASL
95  * to cause a failure and exit SASL input. See RFC7628 3.2.3 */
96  mutt_socket_send(adata->conn, "\001");
97  rc = imap_exec(adata, ibuf, IMAP_CMD_NO_FLAGS);
98  }
99 
100  if (rc == IMAP_EXEC_SUCCESS)
101  {
103  return IMAP_AUTH_SUCCESS;
104  }
105 
106  // L10N: %s is the method name, e.g. Anonymous, CRAM-MD5, GSSAPI, SASL
107  mutt_error(_("%s authentication failed"), authtype);
108  return IMAP_AUTH_FAILURE;
109 }
@ IMAP_AUTH_FAILURE
Authentication failed.
Definition: auth.h:40
@ IMAP_AUTH_SUCCESS
Authentication successful.
Definition: auth.h:39
@ IMAP_AUTH_UNAVAIL
Authentication method not permitted.
Definition: auth.h:41
char * mutt_account_getoauthbearer(struct ConnAccount *cac, bool xoauth2)
Get an OAUTHBEARER/XOAUTH2 token.
Definition: connaccount.c:159
#define mutt_error(...)
Definition: logging.h:87
#define mutt_message(...)
Definition: logging.h:86
const char * cs_subset_string(const struct ConfigSubset *sub, const char *name)
Get a string config item by name.
Definition: helpers.c:317
int imap_exec(struct ImapAccountData *adata, const char *cmdstr, ImapCmdFlags flags)
Execute a command and wait for the response from the server.
Definition: command.c:1255
#define IMAP_CMD_NO_FLAGS
No flags are set.
Definition: private.h:73
#define IMAP_CMD_PASS
Command contains a password. Suppress logging.
Definition: private.h:74
@ IMAP_EXEC_SUCCESS
Imap command executed or queued successfully.
Definition: private.h:84
#define IMAP_CAP_SASL_IR
SASL initial response draft.
Definition: private.h:136
#define IMAP_CAP_AUTH_XOAUTH2
AUTH=XOAUTH2, deprecated but used by OWA.
Definition: private.h:132
#define IMAP_CAP_AUTH_OAUTHBEARER
RFC7628: AUTH=OAUTHBEARER.
Definition: private.h:131
void * mutt_mem_malloc(size_t size)
Allocate memory on the heap.
Definition: memory.c:90
#define FREE(x)
Definition: memory.h:40
#define _(a)
Definition: message.h:28
size_t mutt_str_len(const char *a)
Calculate the length of a string, safely.
Definition: string.c:475
void mutt_clear_error(void)
Clear the message line (bottom line of screen)
Definition: mutt_logging.c:113
#define mutt_socket_send(conn, buf)
Definition: mutt_socket.h:37
unsigned int ssf
Security strength factor, in bits (see notes)
Definition: connection.h:51
struct ConnAccount account
Account details: username, password, etc.
Definition: connection.h:50
ImapCapFlags capabilities
Capability flags.
Definition: adata.h:55
struct Connection * conn
Connection to IMAP server.
Definition: adata.h:41
Container for Accounts, Notifications.
Definition: neomutt.h:37
struct ConfigSubset * sub
Inherited config items.
Definition: neomutt.h:39

◆ imap_auth_oauth()

enum ImapAuthRes imap_auth_oauth ( struct ImapAccountData adata,
const char *  method 
)

Authenticate an IMAP connection using OAUTHBEARER - Implements ImapAuth::authenticate()

Definition at line 1 of file auth_oauth.c.

115 {
116  return imap_auth_oauth_xoauth2(adata, method, false);
117 }
enum ImapAuthRes imap_auth_oauth_xoauth2(struct ImapAccountData *adata, const char *method, bool xoauth2)
Authenticate an IMAP connection using OAUTHBEARER or XOAUTH2.
Definition: auth_oauth.c:50
+ Here is the call graph for this function:

◆ imap_auth_xoauth2()

enum ImapAuthRes imap_auth_xoauth2 ( struct ImapAccountData adata,
const char *  method 
)

Authenticate an IMAP connection using XOAUTH2 - Implements ImapAuth::authenticate()

Definition at line 1 of file auth_oauth.c.

123 {
124  return imap_auth_oauth_xoauth2(adata, method, true);
125 }