NeoMutt  2022-04-29-323-g5fcc6c
Teaching an old dog new tricks
DOXYGEN
auth.c
Go to the documentation of this file.
1
30#include "config.h"
31#include <stdbool.h>
32#include <stdio.h>
33#include <string.h>
34#include "private.h"
35#include "mutt/lib.h"
36#include "address/lib.h"
37#include "config/lib.h"
38#include "core/lib.h"
39#include "conn/lib.h"
40#include "adata.h"
41#ifdef USE_SASL_CYRUS
42#include <sasl/sasl.h>
43#include <sasl/saslutil.h>
44#endif
45#ifdef USE_SASL_GNU
46#include <gsasl.h>
47#endif
48
49#ifdef USE_SASL_GNU
53static enum PopAuthRes pop_auth_gsasl(struct PopAccountData *adata, const char *method)
54{
55 Gsasl_session *gsasl_session = NULL;
56 struct Buffer *output_buf = NULL;
57 struct Buffer *input_buf = NULL;
58 int rc = POP_A_FAILURE;
59 int gsasl_rc = GSASL_OK;
60
61 const char *chosen_mech = mutt_gsasl_get_mech(method,
63 if (!chosen_mech)
64 {
65 mutt_debug(LL_DEBUG2, "returned no usable mech\n");
66 return POP_A_UNAVAIL;
67 }
68
69 mutt_debug(LL_DEBUG2, "using mech %s\n", chosen_mech);
70
71 if (mutt_gsasl_client_new(adata->conn, chosen_mech, &gsasl_session) < 0)
72 {
73 mutt_debug(LL_DEBUG1, "Error allocating GSASL connection.\n");
74 return POP_A_UNAVAIL;
75 }
76
77 mutt_message(_("Authenticating (%s)..."), chosen_mech);
78
79 output_buf = mutt_buffer_pool_get();
80 input_buf = mutt_buffer_pool_get();
81 mutt_buffer_printf(output_buf, "AUTH %s\r\n", chosen_mech);
82
83 do
84 {
85 if (mutt_socket_send(adata->conn, mutt_buffer_string(output_buf)) < 0)
86 {
87 adata->status = POP_DISCONNECTED;
88 rc = POP_A_SOCKET;
89 goto fail;
90 }
91
92 if (mutt_socket_buffer_readln(input_buf, adata->conn) < 0)
93 {
94 adata->status = POP_DISCONNECTED;
95 rc = POP_A_SOCKET;
96 goto fail;
97 }
98
99 if (!mutt_strn_equal(mutt_buffer_string(input_buf), "+ ", 2))
100 break;
101
102 const char *pop_auth_data = mutt_buffer_string(input_buf) + 2;
103 char *gsasl_step_output = NULL;
104 gsasl_rc = gsasl_step64(gsasl_session, pop_auth_data, &gsasl_step_output);
105 if ((gsasl_rc == GSASL_NEEDS_MORE) || (gsasl_rc == GSASL_OK))
106 {
107 mutt_buffer_strcpy(output_buf, gsasl_step_output);
108 mutt_buffer_addstr(output_buf, "\r\n");
109 gsasl_free(gsasl_step_output);
110 }
111 else
112 {
113 mutt_debug(LL_DEBUG1, "gsasl_step64() failed (%d): %s\n", gsasl_rc,
114 gsasl_strerror(gsasl_rc));
115 }
116 } while ((gsasl_rc == GSASL_NEEDS_MORE) || (gsasl_rc == GSASL_OK));
117
118 if (mutt_strn_equal(mutt_buffer_string(input_buf), "+ ", 2))
119 {
120 mutt_socket_send(adata->conn, "*\r\n");
121 goto fail;
122 }
123
124 if (mutt_strn_equal(mutt_buffer_string(input_buf), "+OK", 3) && (gsasl_rc == GSASL_OK))
125 rc = POP_A_SUCCESS;
126
127fail:
128 mutt_buffer_pool_release(&input_buf);
129 mutt_buffer_pool_release(&output_buf);
130 mutt_gsasl_client_finish(&gsasl_session);
131
132 if (rc == POP_A_FAILURE)
133 {
134 mutt_debug(LL_DEBUG2, "%s failed\n", chosen_mech);
135 mutt_error(_("SASL authentication failed"));
136 }
137
138 return rc;
139}
140#endif
141
142#ifdef USE_SASL_CYRUS
146static enum PopAuthRes pop_auth_sasl(struct PopAccountData *adata, const char *method)
147{
148 sasl_conn_t *saslconn = NULL;
149 sasl_interact_t *interaction = NULL;
150 int rc;
151 char inbuf[1024] = { 0 };
152 const char *mech = NULL;
153 const char *pc = NULL;
154 unsigned int len = 0, olen = 0;
155
156 if (mutt_account_getpass(&adata->conn->account) || !adata->conn->account.pass[0])
157 return POP_A_FAILURE;
158
159 if (mutt_sasl_client_new(adata->conn, &saslconn) < 0)
160 {
161 mutt_debug(LL_DEBUG1, "Error allocating SASL connection\n");
162 return POP_A_FAILURE;
163 }
164
165 if (!method)
166 method = adata->auth_list.data;
167
168 while (true)
169 {
170 rc = sasl_client_start(saslconn, method, &interaction, &pc, &olen, &mech);
171 if (rc != SASL_INTERACT)
172 break;
173 mutt_sasl_interact(interaction);
174 }
175
176 if ((rc != SASL_OK) && (rc != SASL_CONTINUE))
177 {
178 mutt_debug(LL_DEBUG1, "Failure starting authentication exchange. No shared mechanisms?\n");
179
180 /* SASL doesn't support suggested mechanisms, so fall back */
181 sasl_dispose(&saslconn);
182 return POP_A_UNAVAIL;
183 }
184
185 /* About client_start: If sasl_client_start() returns data via pc/olen,
186 * the client is expected to send this first (after the AUTH string is sent).
187 * sasl_client_start() may in fact return SASL_OK in this case. */
188 unsigned int client_start = olen;
189
190 // L10N: (%s) is the method name, e.g. Anonymous, CRAM-MD5, GSSAPI, SASL
191 mutt_message(_("Authenticating (%s)..."), "SASL");
192
193 size_t bufsize = MAX((olen * 2), 1024);
194 char *buf = mutt_mem_malloc(bufsize);
195
196 snprintf(buf, bufsize, "AUTH %s", mech);
197 olen = strlen(buf);
198
199 /* looping protocol */
200 while (true)
201 {
202 mutt_str_copy(buf + olen, "\r\n", bufsize - olen);
203 mutt_socket_send(adata->conn, buf);
204 if (mutt_socket_readln_d(inbuf, sizeof(inbuf), adata->conn, MUTT_SOCK_LOG_FULL) < 0)
205 {
206 sasl_dispose(&saslconn);
207 adata->status = POP_DISCONNECTED;
208 FREE(&buf);
209 return POP_A_SOCKET;
210 }
211
212 /* Note we don't exit if rc==SASL_OK when client_start is true.
213 * This is because the first loop has only sent the AUTH string, we
214 * need to loop at least once more to send the pc/olen returned
215 * by sasl_client_start(). */
216 if (!client_start && (rc != SASL_CONTINUE))
217 break;
218
219 if (mutt_str_startswith(inbuf, "+ ") &&
220 (sasl_decode64(inbuf + 2, strlen(inbuf + 2), buf, bufsize - 1, &len) != SASL_OK))
221 {
222 mutt_debug(LL_DEBUG1, "error base64-decoding server response\n");
223 goto bail;
224 }
225
226 if (!client_start)
227 {
228 while (true)
229 {
230 rc = sasl_client_step(saslconn, buf, len, &interaction, &pc, &olen);
231 if (rc != SASL_INTERACT)
232 break;
233 mutt_sasl_interact(interaction);
234 }
235 }
236 else
237 {
238 olen = client_start;
239 client_start = 0;
240 }
241
242 /* Even if sasl_client_step() returns SASL_OK, we should send at
243 * least one more line to the server. */
244 if ((rc != SASL_CONTINUE) && (rc != SASL_OK))
245 break;
246
247 /* send out response, or line break if none needed */
248 if (pc)
249 {
250 if ((olen * 2) > bufsize)
251 {
252 bufsize = olen * 2;
253 mutt_mem_realloc(&buf, bufsize);
254 }
255 if (sasl_encode64(pc, olen, buf, bufsize, &olen) != SASL_OK)
256 {
257 mutt_debug(LL_DEBUG1, "error base64-encoding client response\n");
258 goto bail;
259 }
260 }
261 }
262
263 if (rc != SASL_OK)
264 goto bail;
265
266 if (mutt_str_startswith(inbuf, "+OK"))
267 {
268 mutt_sasl_setup_conn(adata->conn, saslconn);
269 FREE(&buf);
270 return POP_A_SUCCESS;
271 }
272
273bail:
274 sasl_dispose(&saslconn);
275
276 /* terminate SASL session if the last response is not +OK nor -ERR */
277 if (mutt_str_startswith(inbuf, "+ "))
278 {
279 snprintf(buf, bufsize, "*\r\n");
280 if (pop_query(adata, buf, bufsize) == -1)
281 {
282 FREE(&buf);
283 return POP_A_SOCKET;
284 }
285 }
286
287 FREE(&buf);
288 // L10N: %s is the method name, e.g. Anonymous, CRAM-MD5, GSSAPI, SASL
289 mutt_error(_("%s authentication failed"), "SASL");
290
291 return POP_A_FAILURE;
292}
293#endif
294
300void pop_apop_timestamp(struct PopAccountData *adata, char *buf)
301{
302 char *p1 = NULL, *p2 = NULL;
303
304 FREE(&adata->timestamp);
305
306 if ((p1 = strchr(buf, '<')) && (p2 = strchr(p1, '>')))
307 {
308 p2[1] = '\0';
309 adata->timestamp = mutt_str_dup(p1);
310 }
311}
312
316static enum PopAuthRes pop_auth_apop(struct PopAccountData *adata, const char *method)
317{
318 struct Md5Ctx md5ctx;
319 unsigned char digest[16];
320 char hash[33] = { 0 };
321 char buf[1024] = { 0 };
322
323 if (mutt_account_getpass(&adata->conn->account) || !adata->conn->account.pass[0])
324 return POP_A_FAILURE;
325
326 if (!adata->timestamp)
327 return POP_A_UNAVAIL;
328
329 if (!mutt_addr_valid_msgid(adata->timestamp))
330 {
331 mutt_error(_("POP timestamp is invalid"));
332 return POP_A_UNAVAIL;
333 }
334
335 // L10N: (%s) is the method name, e.g. Anonymous, CRAM-MD5, GSSAPI, SASL
336 mutt_message(_("Authenticating (%s)..."), "APOP");
337
338 /* Compute the authentication hash to send to the server */
339 mutt_md5_init_ctx(&md5ctx);
340 mutt_md5_process(adata->timestamp, &md5ctx);
341 mutt_md5_process(adata->conn->account.pass, &md5ctx);
342 mutt_md5_finish_ctx(&md5ctx, digest);
343 mutt_md5_toascii(digest, hash);
344
345 /* Send APOP command to server */
346 snprintf(buf, sizeof(buf), "APOP %s %s\r\n", adata->conn->account.user, hash);
347
348 switch (pop_query(adata, buf, sizeof(buf)))
349 {
350 case 0:
351 return POP_A_SUCCESS;
352 case -1:
353 return POP_A_SOCKET;
354 }
355
356 // L10N: %s is the method name, e.g. Anonymous, CRAM-MD5, GSSAPI, SASL
357 mutt_error(_("%s authentication failed"), "APOP");
358
359 return POP_A_FAILURE;
360}
361
365static enum PopAuthRes pop_auth_user(struct PopAccountData *adata, const char *method)
366{
367 if (!adata->cmd_user)
368 return POP_A_UNAVAIL;
369
370 if (mutt_account_getpass(&adata->conn->account) || !adata->conn->account.pass[0])
371 return POP_A_FAILURE;
372
373 mutt_message(_("Logging in..."));
374
375 char buf[1024] = { 0 };
376 snprintf(buf, sizeof(buf), "USER %s\r\n", adata->conn->account.user);
377 int rc = pop_query(adata, buf, sizeof(buf));
378
379 if (adata->cmd_user == 2)
380 {
381 if (rc == 0)
382 {
383 adata->cmd_user = 1;
384
385 mutt_debug(LL_DEBUG1, "set USER capability\n");
386 }
387
388 if (rc == -2)
389 {
390 adata->cmd_user = 0;
391
392 mutt_debug(LL_DEBUG1, "unset USER capability\n");
393 snprintf(adata->err_msg, sizeof(adata->err_msg), "%s",
394 _("Command USER is not supported by server"));
395 }
396 }
397
398 if (rc == 0)
399 {
400 snprintf(buf, sizeof(buf), "PASS %s\r\n", adata->conn->account.pass);
401 const short c_debug_level = cs_subset_number(NeoMutt->sub, "debug_level");
402 rc = pop_query_d(adata, buf, sizeof(buf),
403 /* don't print the password unless we're at the ungodly debugging level */
404 (c_debug_level < MUTT_SOCK_LOG_FULL) ? "PASS *\r\n" : NULL);
405 }
406
407 switch (rc)
408 {
409 case 0:
410 return POP_A_SUCCESS;
411 case -1:
412 return POP_A_SOCKET;
413 }
414
415 mutt_error("%s %s", _("Login failed"), adata->err_msg);
416
417 return POP_A_FAILURE;
418}
419
423static enum PopAuthRes pop_auth_oauth(struct PopAccountData *adata, const char *method)
424{
425 /* If they did not explicitly request or configure oauth then fail quietly */
426 const char *const c_pop_oauth_refresh_command = cs_subset_string(NeoMutt->sub, "pop_oauth_refresh_command");
427 if (!method && !c_pop_oauth_refresh_command)
428 return POP_A_UNAVAIL;
429
430 // L10N: (%s) is the method name, e.g. Anonymous, CRAM-MD5, GSSAPI, SASL
431 mutt_message(_("Authenticating (%s)..."), "OAUTHBEARER");
432
433 char *oauthbearer = mutt_account_getoauthbearer(&adata->conn->account, false);
434 if (!oauthbearer)
435 return POP_A_FAILURE;
436
437 size_t auth_cmd_len = strlen(oauthbearer) + 30;
438 char *auth_cmd = mutt_mem_malloc(auth_cmd_len);
439 snprintf(auth_cmd, auth_cmd_len, "AUTH OAUTHBEARER %s\r\n", oauthbearer);
440 FREE(&oauthbearer);
441
442 int rc = pop_query_d(adata, auth_cmd, strlen(auth_cmd),
443#ifdef DEBUG
444 /* don't print the bearer token unless we're at the ungodly debugging level */
445 (cs_subset_number(NeoMutt->sub, "debug_level") < MUTT_SOCK_LOG_FULL) ?
446 "AUTH OAUTHBEARER *\r\n" :
447#endif
448 NULL);
449 FREE(&auth_cmd);
450
451 switch (rc)
452 {
453 case 0:
454 return POP_A_SUCCESS;
455 case -1:
456 return POP_A_SOCKET;
457 }
458
459 /* The error response was a SASL continuation, so "continue" it.
460 * See RFC7628 3.2.3 */
461 mutt_socket_send(adata->conn, "\001");
462
463 char *err = adata->err_msg;
464 char decoded_err[1024] = { 0 };
465 int len = mutt_b64_decode(adata->err_msg, decoded_err, sizeof(decoded_err) - 1);
466 if (len >= 0)
467 {
468 decoded_err[len] = '\0';
469 err = decoded_err;
470 }
471 mutt_error("%s %s", _("Authentication failed"), err);
472
473 return POP_A_FAILURE;
474}
475
479static const struct PopAuth PopAuthenticators[] = {
480 // clang-format off
481 { pop_auth_oauth, "oauthbearer" },
482#ifdef USE_SASL_CYRUS
483 { pop_auth_sasl, NULL },
484#endif
485#ifdef USE_SASL_GNU
486 { pop_auth_gsasl, NULL },
487#endif
488 { pop_auth_apop, "apop" },
489 { pop_auth_user, "user" },
490 { NULL, NULL },
491 // clang-format on
492};
493
502bool pop_auth_is_valid(const char *authenticator)
503{
504 for (size_t i = 0; i < mutt_array_size(PopAuthenticators); i++)
505 {
506 const struct PopAuth *auth = &PopAuthenticators[i];
507 if (auth->method && mutt_istr_equal(auth->method, authenticator))
508 return true;
509 }
510
511 return false;
512}
513
524{
525 struct ConnAccount *cac = &adata->conn->account;
526 const struct PopAuth *authenticator = NULL;
527 int attempts = 0;
528 int rc = POP_A_UNAVAIL;
529
530 if ((mutt_account_getuser(cac) < 0) || (cac->user[0] == '\0'))
531 {
532 return -3;
533 }
534
535 const struct Slist *c_pop_authenticators = cs_subset_slist(NeoMutt->sub, "pop_authenticators");
536 const bool c_pop_auth_try_all = cs_subset_bool(NeoMutt->sub, "pop_auth_try_all");
537 if (c_pop_authenticators && (c_pop_authenticators->count > 0))
538 {
539 /* Try user-specified list of authentication methods */
540 struct ListNode *np = NULL;
541 STAILQ_FOREACH(np, &c_pop_authenticators->head, entries)
542 {
543 mutt_debug(LL_DEBUG2, "Trying method %s\n", np->data);
544 authenticator = PopAuthenticators;
545
546 while (authenticator->authenticate)
547 {
548 if (!authenticator->method || mutt_istr_equal(authenticator->method, np->data))
549 {
550 rc = authenticator->authenticate(adata, np->data);
551 if (rc == POP_A_SOCKET)
552 {
553 switch (pop_connect(adata))
554 {
555 case 0:
556 {
557 rc = authenticator->authenticate(adata, np->data);
558 break;
559 }
560 case -2:
561 rc = POP_A_FAILURE;
562 }
563 }
564
565 if (rc != POP_A_UNAVAIL)
566 attempts++;
567 if ((rc == POP_A_SUCCESS) || (rc == POP_A_SOCKET) ||
568 ((rc == POP_A_FAILURE) && !c_pop_auth_try_all))
569 {
570 break;
571 }
572 }
573 authenticator++;
574 }
575 }
576 }
577 else
578 {
579 /* Fall back to default: any authenticator */
580 mutt_debug(LL_DEBUG2, "Using any available method\n");
581 authenticator = PopAuthenticators;
582
583 while (authenticator->authenticate)
584 {
585 rc = authenticator->authenticate(adata, NULL);
586 if (rc == POP_A_SOCKET)
587 {
588 switch (pop_connect(adata))
589 {
590 case 0:
591 {
592 rc = authenticator->authenticate(adata, NULL);
593 break;
594 }
595 case -2:
596 rc = POP_A_FAILURE;
597 }
598 }
599
600 if (rc != POP_A_UNAVAIL)
601 attempts++;
602 if ((rc == POP_A_SUCCESS) || (rc == POP_A_SOCKET) ||
603 ((rc == POP_A_FAILURE) && !c_pop_auth_try_all))
604 {
605 break;
606 }
607
608 authenticator++;
609 }
610 }
611
612 switch (rc)
613 {
614 case POP_A_SUCCESS:
615 return 0;
616 case POP_A_SOCKET:
617 return -1;
618 case POP_A_UNAVAIL:
619 if (attempts == 0)
620 mutt_error(_("No authenticators available"));
621 }
622
623 return -2;
624}
bool mutt_addr_valid_msgid(const char *msgid)
Is this a valid Message ID?
Definition: address.c:764
Email Address Handling.
int mutt_b64_decode(const char *in, char *out, size_t olen)
Convert null-terminated base64 string to raw bytes.
Definition: base64.c:136
size_t mutt_buffer_strcpy(struct Buffer *buf, const char *s)
Copy a string into a Buffer.
Definition: buffer.c:327
size_t mutt_buffer_addstr(struct Buffer *buf, const char *s)
Add a string to a Buffer.
Definition: buffer.c:233
int mutt_buffer_printf(struct Buffer *buf, const char *fmt,...)
Format a string overwriting a Buffer.
Definition: buffer.c:168
static const char * mutt_buffer_string(const struct Buffer *buf)
Convert a buffer to a const char * "string".
Definition: buffer.h:77
const char * cs_subset_string(const struct ConfigSubset *sub, const char *name)
Get a string config item by name.
Definition: helpers.c:317
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
short cs_subset_number(const struct ConfigSubset *sub, const char *name)
Get a number config item by name.
Definition: helpers.c:169
bool cs_subset_bool(const struct ConfigSubset *sub, const char *name)
Get a boolean config item by name.
Definition: helpers.c:73
Convenience wrapper for the config headers.
Connection Library.
int mutt_account_getpass(struct ConnAccount *cac)
Fetch password into ConnAccount, if necessary.
Definition: connaccount.c:130
int mutt_account_getuser(struct ConnAccount *cac)
Retrieve username into ConnAccount, if necessary.
Definition: connaccount.c:50
char * mutt_account_getoauthbearer(struct ConnAccount *cac, bool xoauth2)
Get an OAUTHBEARER/XOAUTH2 token.
Definition: connaccount.c:195
Convenience wrapper for the core headers.
#define mutt_error(...)
Definition: logging.h:87
#define mutt_message(...)
Definition: logging.h:86
#define mutt_debug(LEVEL,...)
Definition: logging.h:84
const char * mutt_gsasl_get_mech(const char *requested_mech, const char *server_mechlist)
Pick a connection mechanism.
Definition: gsasl.c:162
int mutt_gsasl_client_new(struct Connection *conn, const char *mech, Gsasl_session **sctx)
Create a new GNU SASL client.
Definition: gsasl.c:197
void mutt_gsasl_client_finish(Gsasl_session **sctx)
Free a GNU SASL client.
Definition: gsasl.c:218
@ LL_DEBUG2
Log at debug level 2.
Definition: logging.h:41
@ LL_DEBUG1
Log at debug level 1.
Definition: logging.h:40
void mutt_md5_process(const char *str, struct Md5Ctx *md5ctx)
Process a NULL-terminated string.
Definition: md5.c:356
void mutt_md5_init_ctx(struct Md5Ctx *md5ctx)
Initialise the MD5 computation.
Definition: md5.c:262
void * mutt_md5_finish_ctx(struct Md5Ctx *md5ctx, void *resbuf)
Process the remaining bytes in the buffer.
Definition: md5.c:286
void mutt_md5_toascii(const void *digest, char *resbuf)
Convert a binary MD5 digest into ASCII Hexadecimal.
Definition: md5.c:457
void * mutt_mem_malloc(size_t size)
Allocate memory on the heap.
Definition: memory.c:90
void mutt_mem_realloc(void *ptr, size_t size)
Resize a block of memory on the heap.
Definition: memory.c:114
#define FREE(x)
Definition: memory.h:43
#define MAX(a, b)
Definition: memory.h:30
#define mutt_array_size(x)
Definition: memory.h:36
Convenience wrapper for the library headers.
#define _(a)
Definition: message.h:28
bool mutt_istr_equal(const char *a, const char *b)
Compare two strings, ignoring case.
Definition: string.c:819
char * mutt_str_dup(const char *str)
Copy a string, safely.
Definition: string.c:250
bool mutt_strn_equal(const char *a, const char *b, size_t num)
Check for equality of two strings (to a maximum), safely.
Definition: string.c:496
size_t mutt_str_startswith(const char *str, const char *prefix)
Check whether a string starts with a prefix.
Definition: string.c:227
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:652
void mutt_buffer_pool_release(struct Buffer **pbuf)
Free a Buffer from the pool.
Definition: pool.c:112
struct Buffer * mutt_buffer_pool_get(void)
Get a Buffer from the pool.
Definition: pool.c:101
Pop-specific Account data.
static enum PopAuthRes pop_auth_user(struct PopAccountData *adata, const char *method)
USER authenticator - Implements PopAuth::authenticate()
Definition: auth.c:365
bool pop_auth_is_valid(const char *authenticator)
Check if string is a valid pop authentication method.
Definition: auth.c:502
static const struct PopAuth PopAuthenticators[]
Accepted authentication methods.
Definition: auth.c:479
static enum PopAuthRes pop_auth_apop(struct PopAccountData *adata, const char *method)
APOP authenticator - Implements PopAuth::authenticate()
Definition: auth.c:316
void pop_apop_timestamp(struct PopAccountData *adata, char *buf)
Get the server timestamp for APOP authentication.
Definition: auth.c:300
static enum PopAuthRes pop_auth_oauth(struct PopAccountData *adata, const char *method)
Authenticate a POP connection using OAUTHBEARER - Implements PopAuth::authenticate()
Definition: auth.c:423
int pop_authenticate(struct PopAccountData *adata)
Authenticate with a POP server.
Definition: auth.c:523
int pop_connect(struct PopAccountData *adata)
Open connection.
Definition: lib.c:273
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:457
PopAuthRes
POP authentication responses.
Definition: private.h:58
@ POP_A_UNAVAIL
No valid authentication method.
Definition: private.h:62
@ POP_A_SUCCESS
Authenticated successfully.
Definition: private.h:59
@ POP_A_FAILURE
Authentication failed.
Definition: private.h:61
@ POP_A_SOCKET
Connection lost.
Definition: private.h:60
#define pop_query(adata, buf, buflen)
Definition: private.h:109
@ POP_DISCONNECTED
Disconnected from server.
Definition: private.h:51
#define STAILQ_FOREACH(var, head, field)
Definition: queue.h:352
int mutt_sasl_interact(sasl_interact_t *interaction)
Perform an SASL interaction with the user.
Definition: sasl.c:694
int mutt_sasl_client_new(struct Connection *conn, sasl_conn_t **saslconn)
Wrapper for sasl_client_new()
Definition: sasl.c:599
void mutt_sasl_setup_conn(struct Connection *conn, sasl_conn_t *saslconn)
Set up an SASL connection.
Definition: sasl.c:731
GUI display the mailboxes in a side panel.
int mutt_socket_readln_d(char *buf, size_t buflen, struct Connection *conn, int dbg)
Read a line from a socket.
Definition: socket.c:250
#define MUTT_SOCK_LOG_FULL
Definition: socket.h:56
#define mutt_socket_send(conn, buf)
Definition: socket.h:59
#define mutt_socket_buffer_readln(buf, conn)
Definition: socket.h:63
String manipulation buffer.
Definition: buffer.h:34
char * data
Pointer to data.
Definition: buffer.h:35
Login details for a remote server.
Definition: connaccount.h:53
char user[128]
Username.
Definition: connaccount.h:56
char pass[256]
Password.
Definition: connaccount.h:57
struct ConnAccount account
Account details: username, password, etc.
Definition: connection.h:50
A List node for strings.
Definition: list.h:35
char * data
String.
Definition: list.h:36
Cursor for the MD5 hashing.
Definition: md5.h:37
Container for Accounts, Notifications.
Definition: neomutt.h:37
struct ConfigSubset * sub
Inherited config items.
Definition: neomutt.h:39
POP-specific Account data -.
Definition: adata.h:37
char err_msg[POP_CMD_RESPONSE]
Definition: adata.h:56
unsigned int status
Definition: adata.h:39
struct Connection * conn
Connection to POP server.
Definition: adata.h:38
char * timestamp
Definition: adata.h:54
unsigned int cmd_user
optional command USER
Definition: adata.h:44
struct Buffer auth_list
list of auth mechanisms
Definition: adata.h:53
POP authentication multiplexor.
Definition: private.h:78
const char * method
Name of authentication method supported, NULL means variable.
Definition: private.h:87
enum PopAuthRes(* authenticate)(struct PopAccountData *adata, const char *method)
Authenticate a POP connection.
Definition: private.h:85
String list.
Definition: slist.h:47
struct ListHead head
List containing values.
Definition: slist.h:48
size_t count
Number of values in list.
Definition: slist.h:49