NeoMutt  2023-11-03-107-g582dc1
Teaching an old dog new tricks
DOXYGEN
Loading...
Searching...
No Matches
auth_oauth.c
Go to the documentation of this file.
1
30#include "config.h"
31#include <stdbool.h>
32#include <stdio.h>
33#include "private.h"
34#include "mutt/lib.h"
35#include "config/lib.h"
36#include "core/lib.h"
37#include "conn/lib.h"
38#include "auth.h"
39#include "adata.h"
40#include "mutt_logging.h"
41
50 const char *method, bool xoauth2)
51{
52 char *ibuf = NULL;
53 char *oauthbearer = NULL;
54 const char *authtype = xoauth2 ? "XOAUTH2" : "OAUTHBEARER";
55 int rc;
56
57 /* For now, we only support SASL_IR also and over TLS */
58 if ((xoauth2 && !(adata->capabilities & IMAP_CAP_AUTH_XOAUTH2)) ||
59 (!xoauth2 && !(adata->capabilities & IMAP_CAP_AUTH_OAUTHBEARER)) ||
60 !(adata->capabilities & IMAP_CAP_SASL_IR) || (adata->conn->ssf == 0))
61 {
62 return IMAP_AUTH_UNAVAIL;
63 }
64
65 /* If they did not explicitly request or configure oauth then fail quietly */
66 const char *const c_imap_oauth_refresh_command = cs_subset_string(NeoMutt->sub, "imap_oauth_refresh_command");
67 if (!method && !c_imap_oauth_refresh_command)
68 return IMAP_AUTH_UNAVAIL;
69
70 // L10N: (%s) is the method name, e.g. Anonymous, CRAM-MD5, GSSAPI, SASL
71 mutt_message(_("Authenticating (%s)..."), authtype);
72
73 /* We get the access token from the imap_oauth_refresh_command */
74 oauthbearer = mutt_account_getoauthbearer(&adata->conn->account, xoauth2);
75 if (!oauthbearer)
76 return IMAP_AUTH_FAILURE;
77
78 mutt_str_asprintf(&ibuf, "AUTHENTICATE %s %s", authtype, oauthbearer);
79
80 /* This doesn't really contain a password, but the token is good for
81 * an hour, so suppress it anyways. */
82 rc = imap_exec(adata, ibuf, IMAP_CMD_PASS);
83
84 FREE(&oauthbearer);
85 FREE(&ibuf);
86
87 if (rc != IMAP_EXEC_SUCCESS)
88 {
89 /* The error response was in SASL continuation, so continue the SASL
90 * to cause a failure and exit SASL input. See RFC7628 3.2.3 */
91 mutt_socket_send(adata->conn, "\001");
92 rc = imap_exec(adata, ibuf, IMAP_CMD_NO_FLAGS);
93 }
94
95 if (rc == IMAP_EXEC_SUCCESS)
96 {
98 return IMAP_AUTH_SUCCESS;
99 }
100
101 // L10N: %s is the method name, e.g. Anonymous, CRAM-MD5, GSSAPI, SASL
102 mutt_error(_("%s authentication failed"), authtype);
103 return IMAP_AUTH_FAILURE;
104}
105
109enum ImapAuthRes imap_auth_oauth(struct ImapAccountData *adata, const char *method)
110{
111 return imap_auth_oauth_xoauth2(adata, method, false);
112}
113
117enum ImapAuthRes imap_auth_xoauth2(struct ImapAccountData *adata, const char *method)
118{
119 return imap_auth_oauth_xoauth2(adata, method, true);
120}
IMAP authenticator multiplexor.
ImapAuthRes
Results of IMAP Authentication.
Definition: auth.h:38
@ 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
static 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:49
const char * cs_subset_string(const struct ConfigSubset *sub, const char *name)
Get a string config item by name.
Definition: helpers.c:292
Convenience wrapper for the config headers.
Connection Library.
char * mutt_account_getoauthbearer(struct ConnAccount *cac, bool xoauth2)
Get an OAUTHBEARER/XOAUTH2 token.
Definition: connaccount.c:194
Convenience wrapper for the core headers.
enum ImapAuthRes imap_auth_xoauth2(struct ImapAccountData *adata, const char *method)
Authenticate an IMAP connection using XOAUTH2 - Implements ImapAuth::authenticate() -.
Definition: auth_oauth.c:117
enum ImapAuthRes imap_auth_oauth(struct ImapAccountData *adata, const char *method)
Authenticate an IMAP connection using OAUTHBEARER - Implements ImapAuth::authenticate() -.
Definition: auth_oauth.c:109
#define mutt_error(...)
Definition: logging2.h:92
#define mutt_message(...)
Definition: logging2.h:91
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:1302
#define IMAP_CMD_NO_FLAGS
No flags are set.
Definition: private.h:71
#define IMAP_CMD_PASS
Command contains a password. Suppress logging.
Definition: private.h:72
@ IMAP_EXEC_SUCCESS
Imap command executed or queued successfully.
Definition: private.h:82
#define IMAP_CAP_SASL_IR
SASL initial response draft.
Definition: private.h:134
#define IMAP_CAP_AUTH_XOAUTH2
AUTH=XOAUTH2, deprecated but used by OWA.
Definition: private.h:130
#define IMAP_CAP_AUTH_OAUTHBEARER
RFC7628: AUTH=OAUTHBEARER.
Definition: private.h:129
#define FREE(x)
Definition: memory.h:45
Convenience wrapper for the library headers.
#define _(a)
Definition: message.h:28
int mutt_str_asprintf(char **strp, const char *fmt,...)
Definition: string.c:966
void mutt_clear_error(void)
Clear the message line (bottom line of screen)
Definition: mutt_logging.c:73
NeoMutt Logging.
Pop-specific Account data.
GUI display the mailboxes in a side panel.
#define mutt_socket_send(conn, buf)
Definition: socket.h:59
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
IMAP-specific Account data -.
Definition: adata.h:40
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:41
struct ConfigSubset * sub
Inherited config items.
Definition: neomutt.h:45