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