NeoMutt  2024-03-23-23-gec7045
Teaching an old dog new tricks
DOXYGEN
Loading...
Searching...
No Matches
auth_oauth.c
Go to the documentation of this file.
1
32#include "config.h"
33#include <stdbool.h>
34#include <stdio.h>
35#include "private.h"
36#include "mutt/lib.h"
37#include "config/lib.h"
38#include "core/lib.h"
39#include "conn/lib.h"
40#include "auth.h"
41#include "adata.h"
42#include "mutt_logging.h"
43
52 const char *method, bool xoauth2)
53{
54 char *ibuf = NULL;
55 char *oauthbearer = NULL;
56 const char *authtype = xoauth2 ? "XOAUTH2" : "OAUTHBEARER";
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 = cs_subset_string(NeoMutt->sub, "imap_oauth_refresh_command");
69 if (!method && !c_imap_oauth_refresh_command)
70 return IMAP_AUTH_UNAVAIL;
71
72 // L10N: (%s) is the method name, e.g. Anonymous, CRAM-MD5, GSSAPI, SASL
73 mutt_message(_("Authenticating (%s)..."), authtype);
74
75 /* We get the access token from the imap_oauth_refresh_command */
76 oauthbearer = mutt_account_getoauthbearer(&adata->conn->account, xoauth2);
77 if (!oauthbearer)
78 return IMAP_AUTH_FAILURE;
79
80 mutt_str_asprintf(&ibuf, "AUTHENTICATE %s %s", authtype, oauthbearer);
81
82 /* This doesn't really contain a password, but the token is good for
83 * an hour, so suppress it anyways. */
84 rc = imap_exec(adata, ibuf, IMAP_CMD_PASS);
85
86 FREE(&oauthbearer);
87 FREE(&ibuf);
88
89 if (rc != IMAP_EXEC_SUCCESS)
90 {
91 /* The error response was in SASL continuation, so continue the SASL
92 * to cause a failure and exit SASL input. See RFC7628 3.2.3 */
93 mutt_socket_send(adata->conn, "\001");
94 rc = imap_exec(adata, ibuf, IMAP_CMD_NO_FLAGS);
95 }
96
97 if (rc == IMAP_EXEC_SUCCESS)
98 {
100 return IMAP_AUTH_SUCCESS;
101 }
102
103 // L10N: %s is the method name, e.g. Anonymous, CRAM-MD5, GSSAPI, SASL
104 mutt_error(_("%s authentication failed"), authtype);
105 return IMAP_AUTH_FAILURE;
106}
107
111enum ImapAuthRes imap_auth_oauth(struct ImapAccountData *adata, const char *method)
112{
113 return imap_auth_oauth_xoauth2(adata, method, false);
114}
115
119enum ImapAuthRes imap_auth_xoauth2(struct ImapAccountData *adata, const char *method)
120{
121 return imap_auth_oauth_xoauth2(adata, method, true);
122}
IMAP authenticator multiplexor.
ImapAuthRes
Results of IMAP Authentication.
Definition: auth.h:39
@ IMAP_AUTH_FAILURE
Authentication failed.
Definition: auth.h:41
@ IMAP_AUTH_SUCCESS
Authentication successful.
Definition: auth.h:40
@ IMAP_AUTH_UNAVAIL
Authentication method not permitted.
Definition: auth.h:42
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:51
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:196
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:119
enum ImapAuthRes imap_auth_oauth(struct ImapAccountData *adata, const char *method)
Authenticate an IMAP connection using OAUTHBEARER - Implements ImapAuth::authenticate() -.
Definition: auth_oauth.c:111
#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:1307
#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:852
void mutt_clear_error(void)
Clear the message line (bottom line of screen)
Definition: mutt_logging.c:74
NeoMutt Logging.
Pop-specific Account data.
GUI display the mailboxes in a side panel.
#define mutt_socket_send(conn, buf)
Definition: socket.h:57
unsigned int ssf
Security strength factor, in bits (see notes)
Definition: connection.h:50
struct ConnAccount account
Account details: username, password, etc.
Definition: connection.h:49
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