NeoMutt  2021-02-05-666-ge300cd
Teaching an old dog new tricks
DOXYGEN
auth.c File Reference

POP authentication. More...

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

Go to the source code of this file.

Functions

static enum PopAuthRes pop_auth_sasl (struct PopAccountData *adata, const char *method)
 POP SASL authenticator - Implements PopAuth::authenticate() More...
 
void pop_apop_timestamp (struct PopAccountData *adata, char *buf)
 Get the server timestamp for APOP authentication. More...
 
static enum PopAuthRes pop_auth_apop (struct PopAccountData *adata, const char *method)
 APOP authenticator - Implements PopAuth::authenticate() More...
 
static enum PopAuthRes pop_auth_user (struct PopAccountData *adata, const char *method)
 USER authenticator - Implements PopAuth::authenticate() More...
 
static enum PopAuthRes pop_auth_oauth (struct PopAccountData *adata, const char *method)
 Authenticate a POP connection using OAUTHBEARER - Implements PopAuth::authenticate() More...
 
bool pop_auth_is_valid (const char *authenticator)
 Check if string is a valid pop authentication method. More...
 
int pop_authenticate (struct PopAccountData *adata)
 Authenticate with a POP server. More...
 

Variables

static const struct PopAuth pop_authenticators []
 Accepted authentication methods. More...
 

Detailed Description

POP authentication.

Authors
  • Vsevolod Volkov
  • Richard Russon

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

Function Documentation

◆ pop_auth_sasl()

static enum PopAuthRes pop_auth_sasl ( struct PopAccountData adata,
const char *  method 
)
static

POP SASL authenticator - Implements PopAuth::authenticate()

Definition at line 51 of file auth.c.

52 {
53  sasl_conn_t *saslconn = NULL;
54  sasl_interact_t *interaction = NULL;
55  int rc;
56  char inbuf[1024];
57  const char *mech = NULL;
58  const char *pc = NULL;
59  unsigned int len = 0, olen = 0;
60 
61  if (mutt_account_getpass(&adata->conn->account) || !adata->conn->account.pass[0])
62  return POP_A_FAILURE;
63 
64  if (mutt_sasl_client_new(adata->conn, &saslconn) < 0)
65  {
66  mutt_debug(LL_DEBUG1, "Error allocating SASL connection\n");
67  return POP_A_FAILURE;
68  }
69 
70  if (!method)
71  method = adata->auth_list.data;
72 
73  while (true)
74  {
75  rc = sasl_client_start(saslconn, method, &interaction, &pc, &olen, &mech);
76  if (rc != SASL_INTERACT)
77  break;
78  mutt_sasl_interact(interaction);
79  }
80 
81  if ((rc != SASL_OK) && (rc != SASL_CONTINUE))
82  {
83  mutt_debug(
84  LL_DEBUG1,
85  "Failure starting authentication exchange. No shared mechanisms?\n");
86 
87  /* SASL doesn't support suggested mechanisms, so fall back */
88  sasl_dispose(&saslconn);
89  return POP_A_UNAVAIL;
90  }
91 
92  /* About client_start: If sasl_client_start() returns data via pc/olen,
93  * the client is expected to send this first (after the AUTH string is sent).
94  * sasl_client_start() may in fact return SASL_OK in this case. */
95  unsigned int client_start = olen;
96 
97  // L10N: (%s) is the method name, e.g. Anonymous, CRAM-MD5, GSSAPI, SASL
98  mutt_message(_("Authenticating (%s)..."), "SASL");
99 
100  size_t bufsize = MAX((olen * 2), 1024);
101  char *buf = mutt_mem_malloc(bufsize);
102 
103  snprintf(buf, bufsize, "AUTH %s", mech);
104  olen = strlen(buf);
105 
106  /* looping protocol */
107  while (true)
108  {
109  mutt_str_copy(buf + olen, "\r\n", bufsize - olen);
110  mutt_socket_send(adata->conn, buf);
111  if (mutt_socket_readln_d(inbuf, sizeof(inbuf), adata->conn, MUTT_SOCK_LOG_FULL) < 0)
112  {
113  sasl_dispose(&saslconn);
114  adata->status = POP_DISCONNECTED;
115  FREE(&buf);
116  return POP_A_SOCKET;
117  }
118 
119  /* Note we don't exit if rc==SASL_OK when client_start is true.
120  * This is because the first loop has only sent the AUTH string, we
121  * need to loop at least once more to send the pc/olen returned
122  * by sasl_client_start(). */
123  if (!client_start && (rc != SASL_CONTINUE))
124  break;
125 
126  if (mutt_str_startswith(inbuf, "+ ") &&
127  (sasl_decode64(inbuf + 2, strlen(inbuf + 2), buf, bufsize - 1, &len) != SASL_OK))
128  {
129  mutt_debug(LL_DEBUG1, "error base64-decoding server response\n");
130  goto bail;
131  }
132 
133  if (!client_start)
134  {
135  while (true)
136  {
137  rc = sasl_client_step(saslconn, buf, len, &interaction, &pc, &olen);
138  if (rc != SASL_INTERACT)
139  break;
140  mutt_sasl_interact(interaction);
141  }
142  }
143  else
144  {
145  olen = client_start;
146  client_start = 0;
147  }
148 
149  /* Even if sasl_client_step() returns SASL_OK, we should send at
150  * least one more line to the server. */
151  if ((rc != SASL_CONTINUE) && (rc != SASL_OK))
152  break;
153 
154  /* send out response, or line break if none needed */
155  if (pc)
156  {
157  if ((olen * 2) > bufsize)
158  {
159  bufsize = olen * 2;
160  mutt_mem_realloc(&buf, bufsize);
161  }
162  if (sasl_encode64(pc, olen, buf, bufsize, &olen) != SASL_OK)
163  {
164  mutt_debug(LL_DEBUG1, "error base64-encoding client response\n");
165  goto bail;
166  }
167  }
168  }
169 
170  if (rc != SASL_OK)
171  goto bail;
172 
173  if (mutt_str_startswith(inbuf, "+OK"))
174  {
175  mutt_sasl_setup_conn(adata->conn, saslconn);
176  FREE(&buf);
177  return POP_A_SUCCESS;
178  }
179 
180 bail:
181  sasl_dispose(&saslconn);
182 
183  /* terminate SASL session if the last response is not +OK nor -ERR */
184  if (mutt_str_startswith(inbuf, "+ "))
185  {
186  snprintf(buf, bufsize, "*\r\n");
187  if (pop_query(adata, buf, bufsize) == -1)
188  {
189  FREE(&buf);
190  return POP_A_SOCKET;
191  }
192  }
193 
194  FREE(&buf);
195  // L10N: %s is the method name, e.g. Anonymous, CRAM-MD5, GSSAPI, SASL
196  mutt_error(_("%s authentication failed"), "SASL");
197 
198  return POP_A_FAILURE;
199 }
#define pop_query(adata, buf, buflen)
Definition: private.h:106
const char * method
Name of authentication method supported, NULL means variable.
Definition: auth.c:52
struct ConnAccount account
Account details: username, password, etc.
Definition: connection.h:40
#define mutt_socket_send(conn, buf)
Definition: mutt_socket.h:37
#define mutt_error(...)
Definition: logging.h:88
Connection lost.
Definition: private.h:60
#define _(a)
Definition: message.h:28
struct Connection * conn
Definition: adata.h:38
int mutt_sasl_client_new(struct Connection *conn, sasl_conn_t **saslconn)
Wrapper for sasl_client_new()
Definition: sasl.c:603
Authenticated successfully.
Definition: private.h:59
void mutt_sasl_setup_conn(struct Connection *conn, sasl_conn_t *saslconn)
Set up an SASL connection.
Definition: sasl.c:734
Disconnected from server.
Definition: private.h:51
#define MUTT_SOCK_LOG_FULL
Definition: mutt_socket.h:31
struct Buffer auth_list
list of auth mechanisms
Definition: adata.h:53
#define MAX(a, b)
Definition: memory.h:30
Authentication failed.
Definition: private.h:61
char pass[256]
Password.
Definition: connaccount.h:56
void mutt_mem_realloc(void *ptr, size_t size)
Resize a block of memory on the heap.
Definition: memory.c:114
size_t mutt_str_startswith(const char *str, const char *prefix)
Check whether a string starts with a prefix.
Definition: string.c:160
void * mutt_mem_malloc(size_t size)
Allocate memory on the heap.
Definition: memory.c:90
char * data
Pointer to data.
Definition: buffer.h:35
#define mutt_debug(LEVEL,...)
Definition: logging.h:85
unsigned int status
Definition: adata.h:39
Log at debug level 1.
Definition: logging.h:40
size_t mutt_str_copy(char *dest, const char *src, size_t dsize)
Copy a string into a buffer (guaranteeing NUL-termination)
Definition: string.c:749
#define mutt_message(...)
Definition: logging.h:87
#define FREE(x)
Definition: memory.h:40
int mutt_socket_readln_d(char *buf, size_t buflen, struct Connection *conn, int dbg)
Read a line from a socket.
Definition: socket.c:246
No valid authentication method.
Definition: private.h:62
int mutt_account_getpass(struct ConnAccount *cac)
Fetch password into ConnAccount, if necessary.
Definition: connaccount.c:110
int mutt_sasl_interact(sasl_interact_t *interaction)
Perform an SASL interaction with the user.
Definition: sasl.c:698
+ Here is the call graph for this function:

◆ pop_apop_timestamp()

void pop_apop_timestamp ( struct PopAccountData adata,
char *  buf 
)

Get the server timestamp for APOP authentication.

Parameters
adataPOP Account data
bufTimestamp string

Definition at line 207 of file auth.c.

208 {
209  char *p1 = NULL, *p2 = NULL;
210 
211  FREE(&adata->timestamp);
212 
213  if ((p1 = strchr(buf, '<')) && (p2 = strchr(p1, '>')))
214  {
215  p2[1] = '\0';
216  adata->timestamp = mutt_str_dup(p1);
217  }
218 }
char * mutt_str_dup(const char *str)
Copy a string, safely.
Definition: string.c:370
char * timestamp
Definition: adata.h:54
#define FREE(x)
Definition: memory.h:40
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ pop_auth_apop()

static enum PopAuthRes pop_auth_apop ( struct PopAccountData adata,
const char *  method 
)
static

APOP authenticator - Implements PopAuth::authenticate()

Definition at line 223 of file auth.c.

224 {
225  struct Md5Ctx md5ctx;
226  unsigned char digest[16];
227  char hash[33];
228  char buf[1024];
229 
230  if (mutt_account_getpass(&adata->conn->account) || !adata->conn->account.pass[0])
231  return POP_A_FAILURE;
232 
233  if (!adata->timestamp)
234  return POP_A_UNAVAIL;
235 
236  if (!mutt_addr_valid_msgid(adata->timestamp))
237  {
238  mutt_error(_("POP timestamp is invalid"));
239  return POP_A_UNAVAIL;
240  }
241 
242  // L10N: (%s) is the method name, e.g. Anonymous, CRAM-MD5, GSSAPI, SASL
243  mutt_message(_("Authenticating (%s)..."), "APOP");
244 
245  /* Compute the authentication hash to send to the server */
246  mutt_md5_init_ctx(&md5ctx);
247  mutt_md5_process(adata->timestamp, &md5ctx);
248  mutt_md5_process(adata->conn->account.pass, &md5ctx);
249  mutt_md5_finish_ctx(&md5ctx, digest);
250  mutt_md5_toascii(digest, hash);
251 
252  /* Send APOP command to server */
253  snprintf(buf, sizeof(buf), "APOP %s %s\r\n", adata->conn->account.user, hash);
254 
255  switch (pop_query(adata, buf, sizeof(buf)))
256  {
257  case 0:
258  return POP_A_SUCCESS;
259  case -1:
260  return POP_A_SOCKET;
261  }
262 
263  // L10N: %s is the method name, e.g. Anonymous, CRAM-MD5, GSSAPI, SASL
264  mutt_error(_("%s authentication failed"), "APOP");
265 
266  return POP_A_FAILURE;
267 }
#define pop_query(adata, buf, buflen)
Definition: private.h:106
Cursor for the MD5 hashing.
Definition: md5.h:36
struct ConnAccount account
Account details: username, password, etc.
Definition: connection.h:40
#define mutt_error(...)
Definition: logging.h:88
void mutt_md5_process(const char *str, struct Md5Ctx *md5ctx)
Process a NULL-terminated string.
Definition: md5.c:355
char user[128]
Username.
Definition: connaccount.h:55
Connection lost.
Definition: private.h:60
#define _(a)
Definition: message.h:28
struct Connection * conn
Definition: adata.h:38
void mutt_md5_init_ctx(struct Md5Ctx *md5ctx)
Initialise the MD5 computation.
Definition: md5.c:262
Authenticated successfully.
Definition: private.h:59
Authentication failed.
Definition: private.h:61
void mutt_md5_toascii(const void *digest, char *resbuf)
Convert a binary MD5 digest into ASCII Hexadecimal.
Definition: md5.c:457
void * mutt_md5_finish_ctx(struct Md5Ctx *md5ctx, void *resbuf)
Process the remaining bytes in the buffer.
Definition: md5.c:286
char pass[256]
Password.
Definition: connaccount.h:56
char * timestamp
Definition: adata.h:54
bool mutt_addr_valid_msgid(const char *msgid)
Is this a valid Message ID?
Definition: address.c:764
#define mutt_message(...)
Definition: logging.h:87
No valid authentication method.
Definition: private.h:62
int mutt_account_getpass(struct ConnAccount *cac)
Fetch password into ConnAccount, if necessary.
Definition: connaccount.c:110
+ Here is the call graph for this function:

◆ pop_auth_user()

static enum PopAuthRes pop_auth_user ( struct PopAccountData adata,
const char *  method 
)
static

USER authenticator - Implements PopAuth::authenticate()

Definition at line 272 of file auth.c.

273 {
274  if (!adata->cmd_user)
275  return POP_A_UNAVAIL;
276 
277  if (mutt_account_getpass(&adata->conn->account) || !adata->conn->account.pass[0])
278  return POP_A_FAILURE;
279 
280  mutt_message(_("Logging in..."));
281 
282  char buf[1024];
283  snprintf(buf, sizeof(buf), "USER %s\r\n", adata->conn->account.user);
284  int ret = pop_query(adata, buf, sizeof(buf));
285 
286  if (adata->cmd_user == 2)
287  {
288  if (ret == 0)
289  {
290  adata->cmd_user = 1;
291 
292  mutt_debug(LL_DEBUG1, "set USER capability\n");
293  }
294 
295  if (ret == -2)
296  {
297  adata->cmd_user = 0;
298 
299  mutt_debug(LL_DEBUG1, "unset USER capability\n");
300  snprintf(adata->err_msg, sizeof(adata->err_msg), "%s",
301  _("Command USER is not supported by server"));
302  }
303  }
304 
305  if (ret == 0)
306  {
307  snprintf(buf, sizeof(buf), "PASS %s\r\n", adata->conn->account.pass);
308  const short c_debug_level = cs_subset_number(NeoMutt->sub, "debug_level");
309  ret = pop_query_d(adata, buf, sizeof(buf),
310  /* don't print the password unless we're at the ungodly debugging level */
311  (c_debug_level < MUTT_SOCK_LOG_FULL) ? "PASS *\r\n" : NULL);
312  }
313 
314  switch (ret)
315  {
316  case 0:
317  return POP_A_SUCCESS;
318  case -1:
319  return POP_A_SOCKET;
320  }
321 
322  mutt_error("%s %s", _("Login failed"), adata->err_msg);
323 
324  return POP_A_FAILURE;
325 }
#define pop_query(adata, buf, buflen)
Definition: private.h:106
char err_msg[POP_CMD_RESPONSE]
Definition: adata.h:56
struct ConnAccount account
Account details: username, password, etc.
Definition: connection.h:40
#define mutt_error(...)
Definition: logging.h:88
char user[128]
Username.
Definition: connaccount.h:55
Connection lost.
Definition: private.h:60
#define _(a)
Definition: message.h:28
struct Connection * conn
Definition: adata.h:38
Authenticated successfully.
Definition: private.h:59
short cs_subset_number(const struct ConfigSubset *sub, const char *name)
Get a number config item by name.
Definition: helpers.c:169
#define MUTT_SOCK_LOG_FULL
Definition: mutt_socket.h:31
Container for Accounts, Notifications.
Definition: neomutt.h:36
unsigned int cmd_user
optional command USER
Definition: adata.h:44
Authentication failed.
Definition: private.h:61
char pass[256]
Password.
Definition: connaccount.h:56
#define mutt_debug(LEVEL,...)
Definition: logging.h:85
Log at debug level 1.
Definition: logging.h:40
#define mutt_message(...)
Definition: logging.h:87
struct ConfigSubset * sub
Inherited config items.
Definition: neomutt.h:39
int pop_query_d(struct PopAccountData *adata, char *buf, size_t buflen, char *msg)
Send data from buffer and receive answer to the same buffer.
Definition: lib.c:461
No valid authentication method.
Definition: private.h:62
int mutt_account_getpass(struct ConnAccount *cac)
Fetch password into ConnAccount, if necessary.
Definition: connaccount.c:110
+ Here is the call graph for this function:

◆ pop_auth_oauth()

static enum PopAuthRes pop_auth_oauth ( struct PopAccountData adata,
const char *  method 
)
static

Authenticate a POP connection using OAUTHBEARER - Implements PopAuth::authenticate()

Definition at line 330 of file auth.c.

331 {
332  /* If they did not explicitly request or configure oauth then fail quietly */
333  const char *const c_pop_oauth_refresh_command =
334  cs_subset_string(NeoMutt->sub, "pop_oauth_refresh_command");
335  if (!method && !c_pop_oauth_refresh_command)
336  return POP_A_UNAVAIL;
337 
338  // L10N: (%s) is the method name, e.g. Anonymous, CRAM-MD5, GSSAPI, SASL
339  mutt_message(_("Authenticating (%s)..."), "OAUTHBEARER");
340 
341  char *oauthbearer = mutt_account_getoauthbearer(&adata->conn->account);
342  if (!oauthbearer)
343  return POP_A_FAILURE;
344 
345  size_t auth_cmd_len = strlen(oauthbearer) + 30;
346  char *auth_cmd = mutt_mem_malloc(auth_cmd_len);
347  snprintf(auth_cmd, auth_cmd_len, "AUTH OAUTHBEARER %s\r\n", oauthbearer);
348  FREE(&oauthbearer);
349 
350  int ret = pop_query_d(adata, auth_cmd, strlen(auth_cmd),
351 #ifdef DEBUG
352  /* don't print the bearer token unless we're at the ungodly debugging level */
353  (cs_subset_number(NeoMutt->sub, "debug_level") < MUTT_SOCK_LOG_FULL) ?
354  "AUTH OAUTHBEARER *\r\n" :
355 #endif
356  NULL);
357  FREE(&auth_cmd);
358 
359  switch (ret)
360  {
361  case 0:
362  return POP_A_SUCCESS;
363  case -1:
364  return POP_A_SOCKET;
365  }
366 
367  /* The error response was a SASL continuation, so "continue" it.
368  * See RFC7628 3.2.3 */
369  mutt_socket_send(adata->conn, "\001");
370 
371  char *err = adata->err_msg;
372  char decoded_err[1024];
373  int len = mutt_b64_decode(adata->err_msg, decoded_err, sizeof(decoded_err) - 1);
374  if (len >= 0)
375  {
376  decoded_err[len] = '\0';
377  err = decoded_err;
378  }
379  mutt_error("%s %s", _("Authentication failed"), err);
380 
381  return POP_A_FAILURE;
382 }
char err_msg[POP_CMD_RESPONSE]
Definition: adata.h:56
struct ConnAccount account
Account details: username, password, etc.
Definition: connection.h:40
#define mutt_socket_send(conn, buf)
Definition: mutt_socket.h:37
#define mutt_error(...)
Definition: logging.h:88
Connection lost.
Definition: private.h:60
#define _(a)
Definition: message.h:28
struct Connection * conn
Definition: adata.h:38
Authenticated successfully.
Definition: private.h:59
short cs_subset_number(const struct ConfigSubset *sub, const char *name)
Get a number config item by name.
Definition: helpers.c:169
#define MUTT_SOCK_LOG_FULL
Definition: mutt_socket.h:31
Container for Accounts, Notifications.
Definition: neomutt.h:36
Authentication failed.
Definition: private.h:61
void * mutt_mem_malloc(size_t size)
Allocate memory on the heap.
Definition: memory.c:90
const char * cs_subset_string(const struct ConfigSubset *sub, const char *name)
Get a string config item by name.
Definition: helpers.c:317
#define mutt_message(...)
Definition: logging.h:87
#define FREE(x)
Definition: memory.h:40
struct ConfigSubset * sub
Inherited config items.
Definition: neomutt.h:39
int pop_query_d(struct PopAccountData *adata, char *buf, size_t buflen, char *msg)
Send data from buffer and receive answer to the same buffer.
Definition: lib.c:461
No valid authentication method.
Definition: private.h:62
char * mutt_account_getoauthbearer(struct ConnAccount *cac)
Get an OAUTHBEARER token.
Definition: connaccount.c:157
int mutt_b64_decode(const char *in, char *out, size_t olen)
Convert null-terminated base64 string to raw bytes.
Definition: base64.c:136
+ Here is the call graph for this function:

◆ pop_auth_is_valid()

bool pop_auth_is_valid ( const char *  authenticator)

Check if string is a valid pop authentication method.

Parameters
authenticatorAuthenticator string to check
Return values
trueArgument is a valid auth method

Validate whether an input string is an accepted pop authentication method as defined by pop_authenticators.

Definition at line 407 of file auth.c.

408 {
409  for (size_t i = 0; i < mutt_array_size(pop_authenticators); i++)
410  {
411  const struct PopAuth *auth = &pop_authenticators[i];
412  if (auth->method && mutt_istr_equal(auth->method, authenticator))
413  return true;
414  }
415 
416  return false;
417 }
static const struct PopAuth pop_authenticators[]
Accepted authentication methods.
Definition: auth.c:387
#define mutt_array_size(x)
Definition: memory.h:33
POP authentication multiplexor.
Definition: private.h:77
const char * method
Name of authentication method supported, NULL means variable.
Definition: private.h:87
bool mutt_istr_equal(const char *a, const char *b)
Compare two strings, ignoring case.
Definition: string.c:916
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ pop_authenticate()

int pop_authenticate ( struct PopAccountData adata)

Authenticate with a POP server.

Parameters
adataPOP Account data
Return values
numResult, e.g. POP_A_SUCCESS
0Successful
-1Connection lost
-2Login failed
-3Authentication cancelled

Definition at line 428 of file auth.c.

429 {
430  struct ConnAccount *cac = &adata->conn->account;
431  const struct PopAuth *authenticator = NULL;
432  int attempts = 0;
433  int ret = POP_A_UNAVAIL;
434 
435  if ((mutt_account_getuser(cac) < 0) || (cac->user[0] == '\0'))
436  {
437  return -3;
438  }
439 
440  const struct Slist *c_pop_authenticators =
441  cs_subset_slist(NeoMutt->sub, "pop_authenticators");
442  const bool c_pop_auth_try_all =
443  cs_subset_bool(NeoMutt->sub, "pop_auth_try_all");
444  if (c_pop_authenticators && (c_pop_authenticators->count > 0))
445  {
446  /* Try user-specified list of authentication methods */
447  struct ListNode *np = NULL;
448  STAILQ_FOREACH(np, &c_pop_authenticators->head, entries)
449  {
450  mutt_debug(LL_DEBUG2, "Trying method %s\n", np->data);
451  authenticator = pop_authenticators;
452 
453  while (authenticator->authenticate)
454  {
455  if (!authenticator->method || mutt_istr_equal(authenticator->method, np->data))
456  {
457  ret = authenticator->authenticate(adata, np->data);
458  if (ret == POP_A_SOCKET)
459  {
460  switch (pop_connect(adata))
461  {
462  case 0:
463  {
464  ret = authenticator->authenticate(adata, np->data);
465  break;
466  }
467  case -2:
468  ret = POP_A_FAILURE;
469  }
470  }
471 
472  if (ret != POP_A_UNAVAIL)
473  attempts++;
474  if ((ret == POP_A_SUCCESS) || (ret == POP_A_SOCKET) ||
475  ((ret == POP_A_FAILURE) && !c_pop_auth_try_all))
476  {
477  break;
478  }
479  }
480  authenticator++;
481  }
482  }
483  }
484  else
485  {
486  /* Fall back to default: any authenticator */
487  mutt_debug(LL_DEBUG2, "Using any available method\n");
488  authenticator = pop_authenticators;
489 
490  while (authenticator->authenticate)
491  {
492  ret = authenticator->authenticate(adata, NULL);
493  if (ret == POP_A_SOCKET)
494  {
495  switch (pop_connect(adata))
496  {
497  case 0:
498  {
499  ret = authenticator->authenticate(adata, NULL);
500  break;
501  }
502  case -2:
503  ret = POP_A_FAILURE;
504  }
505  }
506 
507  if (ret != POP_A_UNAVAIL)
508  attempts++;
509  if ((ret == POP_A_SUCCESS) || (ret == POP_A_SOCKET) ||
510  ((ret == POP_A_FAILURE) && !c_pop_auth_try_all))
511  {
512  break;
513  }
514 
515  authenticator++;
516  }
517  }
518 
519  switch (ret)
520  {
521  case POP_A_SUCCESS:
522  return 0;
523  case POP_A_SOCKET:
524  return -1;
525  case POP_A_UNAVAIL:
526  if (attempts == 0)
527  mutt_error(_("No authenticators available"));
528  }
529 
530  return -2;
531 }
int mutt_account_getuser(struct ConnAccount *cac)
Retrieve username into ConnAccount, if necessary.
Definition: connaccount.c:47
bool cs_subset_bool(const struct ConfigSubset *sub, const char *name)
Get a boolean config item by name.
Definition: helpers.c:73
enum PopAuthRes(* authenticate)(struct PopAccountData *adata, const char *method)
Authenticate a POP connection.
Definition: private.h:85
struct ConnAccount account
Account details: username, password, etc.
Definition: connection.h:40
#define mutt_error(...)
Definition: logging.h:88
int pop_connect(struct PopAccountData *adata)
Open connection.
Definition: lib.c:275
static const struct PopAuth pop_authenticators[]
Accepted authentication methods.
Definition: auth.c:387
char user[128]
Username.
Definition: connaccount.h:55
Connection lost.
Definition: private.h:60
#define _(a)
Definition: message.h:28
struct Connection * conn
Definition: adata.h:38
Authenticated successfully.
Definition: private.h:59
String list.
Definition: slist.h:46
Container for Accounts, Notifications.
Definition: neomutt.h:36
Authentication failed.
Definition: private.h:61
Log at debug level 2.
Definition: logging.h:41
struct ListHead head
Definition: slist.h:48
POP authentication multiplexor.
Definition: private.h:77
const char * method
Name of authentication method supported, NULL means variable.
Definition: private.h:87
bool mutt_istr_equal(const char *a, const char *b)
Compare two strings, ignoring case.
Definition: string.c:916
size_t count
Definition: slist.h:49
#define STAILQ_FOREACH(var, head, field)
Definition: queue.h:352
#define mutt_debug(LEVEL,...)
Definition: logging.h:85
Login details for a remote server.
Definition: connaccount.h:51
const struct Slist * cs_subset_slist(const struct ConfigSubset *sub, const char *name)
Get a string-list config item by name.
Definition: helpers.c:268
char * data
String.
Definition: list.h:36
struct ConfigSubset * sub
Inherited config items.
Definition: neomutt.h:39
A List node for strings.
Definition: list.h:34
No valid authentication method.
Definition: private.h:62
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

Variable Documentation

◆ pop_authenticators

const struct PopAuth pop_authenticators[]
static
Initial value:
= {
{ pop_auth_oauth, "oauthbearer" },
{ pop_auth_sasl, NULL },
{ pop_auth_apop, "apop" },
{ pop_auth_user, "user" },
{ NULL, NULL },
}
static enum PopAuthRes pop_auth_sasl(struct PopAccountData *adata, const char *method)
POP SASL authenticator - Implements PopAuth::authenticate()
Definition: auth.c:51
static enum PopAuthRes pop_auth_apop(struct PopAccountData *adata, const char *method)
APOP authenticator - Implements PopAuth::authenticate()
Definition: auth.c:223
static enum PopAuthRes pop_auth_user(struct PopAccountData *adata, const char *method)
USER authenticator - Implements PopAuth::authenticate()
Definition: auth.c:272
static enum PopAuthRes pop_auth_oauth(struct PopAccountData *adata, const char *method)
Authenticate a POP connection using OAUTHBEARER - Implements PopAuth::authenticate() ...
Definition: auth.c:330

Accepted authentication methods.

Definition at line 387 of file auth.c.