diff options
author | Brandon Long <blong@fiction.net> | 2018-06-26 15:42:08 -0700 |
---|---|---|
committer | Kevin McCarthy <kevin@8t8.us> | 2018-07-16 19:21:45 -0700 |
commit | 98cc42365ac97b0dfeafadf5561043e06744fcf6 (patch) | |
tree | 9c82c0088a9cfe90ae6c578811eef6fbd7954fe2 /account.c | |
parent | 363c3a95a8c5ed55a4ab8618363aa848453f3d19 (diff) |
Improve OAUTHBEARER support.
Move token refresh commands to their own config variables. Consolidate
code for refreshing tokens and generating the SASL OAUTHBEARER
argument in account.c. Add support for OAUTHBEARER to pop.
Fix pop_auth_oauth() mutt_from_base64() call from 1.10.1 release.
Diffstat (limited to 'account.c')
-rw-r--r-- | account.c | 80 |
1 files changed, 80 insertions, 0 deletions
@@ -238,3 +238,83 @@ void mutt_account_unsetpass (ACCOUNT* account) { 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. + */ +char* mutt_account_getoauthbearer (ACCOUNT* account) +{ + FILE *fp; + char *cmd = NULL; + char *token = NULL; + size_t token_size = 0; + char *oauthbearer = NULL; + size_t oalen; + char *encoded_token = NULL; + size_t encoded_len; + pid_t pid; + + /* The oauthbearer token includes the login */ + if (mutt_account_getlogin (account)) + return NULL; + +#ifdef USE_IMAP + if ((account->type == MUTT_ACCT_TYPE_IMAP) && ImapOauthRefreshCmd) + cmd = ImapOauthRefreshCmd; +#endif +#ifdef USE_POP + else if ((account->type == MUTT_ACCT_TYPE_POP) && PopOauthRefreshCmd) + cmd = PopOauthRefreshCmd; +#endif +#ifdef USE_SMTP + else if ((account->type == MUTT_ACCT_TYPE_SMTP) && SmtpOauthRefreshCmd) + cmd = SmtpOauthRefreshCmd; +#endif + + if (cmd == NULL) + { + mutt_error (_("mutt_account_getoauthbearer: No OAUTH refresh command defined")); + return NULL; + } + + if ((pid = mutt_create_filter (cmd, NULL, &fp, NULL)) < 0) + { + mutt_perror _("mutt_account_getoauthbearer: Unable to run refresh command"); + return NULL; + } + + /* read line */ + token = mutt_read_line (NULL, &token_size, fp, NULL, 0); + safe_fclose (&fp); + mutt_wait_filter (pid); + + if (token == NULL || *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. + */ + oalen = strlen (account->login) + strlen (account->host) + strlen (token) + 50; + oauthbearer = safe_malloc (oalen); + + snprintf (oauthbearer, oalen, + "n,a=%s,\001host=%s\001port=%d\001auth=Bearer %s\001\001", + account->login, account->host, account->port, token); + + FREE (&token); + + encoded_len = strlen (oauthbearer) * 4 / 3 + 10; + encoded_token = safe_malloc (encoded_len); + mutt_to_base64 ((unsigned char*) encoded_token, + (unsigned char*) oauthbearer, strlen (oauthbearer), + encoded_len); + FREE (&oauthbearer); + return encoded_token; +} |