NeoMutt  2025-12-11-911-gd8d604
Teaching an old dog new tricks
DOXYGEN
Loading...
Searching...
No Matches
sasl.c
Go to the documentation of this file.
1
24
41
42#include "config.h"
43#include <errno.h>
44#include <netdb.h>
45#include <sasl/sasl.h>
46#include <stdbool.h>
47#include <stdint.h>
48#include <stdio.h>
49#include <string.h>
50#include <sys/socket.h>
51#include <sys/types.h>
52#include "mutt/lib.h"
53#include "core/lib.h"
54#include "sasl.h"
55#include "editor/lib.h"
56#include "history/lib.h"
57#include "connaccount.h"
58#include "connection.h"
59#include "globals.h"
60#include "module_data.h"
61
66{
67 sasl_conn_t *saslconn;
68 const sasl_ssf_t *ssf;
69 const unsigned int *pbufsize;
70
71 /* read buffer */
72 const char *buf;
73 unsigned int blen;
74 unsigned int bpos;
75
76 void *sockdata;
77
81 int (*open)(struct Connection *conn);
82
86 int (*read)(struct Connection *conn, char *buf, size_t count);
87
91 int (*write)(struct Connection *conn, const char *buf, size_t count);
92
96 int (*poll)(struct Connection *conn, time_t wait_secs);
97
101 int (*close)(struct Connection *conn);
102};
103
107static const char *const SaslAuthenticators[] = {
108 "ANONYMOUS", "CRAM-MD5", "DIGEST-MD5", "EXTERNAL",
109 "GS2-IAKERB", "GS2-KRB5", "GSS-SPNEGO", "GSSAPI",
110 "LOGIN", "NTLM", "OTP-MD4", "OTP-MD5",
111 "OTP-SHA1", "PASSDSS-3DES-1", "PLAIN", "SCRAM-SHA-1",
112 "SCRAM-SHA-224", "SCRAM-SHA-256", "SCRAM-SHA-384", "SCRAM-SHA-512",
113 "SRP",
114};
115
117#define MUTT_SASL_MAXBUF 65536
118
120#define IP_PORT_BUFLEN (NI_MAXHOST + NI_MAXSERV)
121
123// MuttSaslCallbacks moved to ConnModuleData
124
126// SecretPtr moved to ConnModuleData
127
133bool sasl_auth_validator(const char *authenticator)
134{
135 for (size_t i = 0; i < countof(SaslAuthenticators); i++)
136 {
137 const char *auth = SaslAuthenticators[i];
138 if (mutt_istr_equal(auth, authenticator))
139 return true;
140 }
141
142 return false;
143}
144
150static int getnameinfo_err(int rc)
151{
152 int err;
153 mutt_debug(LL_DEBUG1, "getnameinfo: ");
154 switch (rc)
155 {
156 case EAI_AGAIN:
157 mutt_debug(LL_DEBUG1, "The name could not be resolved at this time. Future attempts may succeed\n");
158 err = SASL_TRYAGAIN;
159 break;
160 case EAI_BADFLAGS:
161 mutt_debug(LL_DEBUG1, "The flags had an invalid value\n");
162 err = SASL_BADPARAM;
163 break;
164 case EAI_FAIL:
165 mutt_debug(LL_DEBUG1, "A non-recoverable error occurred\n");
166 err = SASL_FAIL;
167 break;
168 case EAI_FAMILY:
169 mutt_debug(LL_DEBUG1, "The address family was not recognized or the address length was invalid for the specified family\n");
170 err = SASL_BADPROT;
171 break;
172 case EAI_MEMORY:
173 mutt_debug(LL_DEBUG1, "There was a memory allocation failure\n");
174 err = SASL_NOMEM;
175 break;
176 case EAI_NONAME:
177 mutt_debug(LL_DEBUG1, "The name does not resolve for the supplied parameters. "
178 "NI_NAMEREQD is set and the host's name can't be located, or both nodename and servname were null.\n");
179 err = SASL_FAIL; /* no real equivalent */
180 break;
181 case EAI_SYSTEM:
182 mutt_debug(LL_DEBUG1, "A system error occurred. The error code can be found in errno(%d,%s))\n",
183 errno, strerror(errno));
184 err = SASL_FAIL; /* no real equivalent */
185 break;
186 default:
187 mutt_debug(LL_DEBUG1, "Unknown error %d\n", rc);
188 err = SASL_FAIL; /* no real equivalent */
189 break;
190 }
191 return err;
192}
193
204static int iptostring(const struct sockaddr *addr, socklen_t addrlen, char *out,
205 unsigned int outlen)
206{
207 char hbuf[NI_MAXHOST], pbuf[NI_MAXSERV];
208 int rc;
209
210 if (!addr || !out)
211 return SASL_BADPARAM;
212
213 rc = getnameinfo(addr, addrlen, hbuf, sizeof(hbuf), pbuf, sizeof(pbuf),
214 NI_NUMERICHOST |
215#ifdef NI_WITHSCOPEID
216 NI_WITHSCOPEID |
217#endif
218 NI_NUMERICSERV);
219 if (rc != 0)
220 return getnameinfo_err(rc);
221
222 if (outlen < strlen(hbuf) + strlen(pbuf) + 2)
223 return SASL_BUFOVER;
224
225 snprintf(out, outlen, "%s;%s", hbuf, pbuf);
226
227 return SASL_OK;
228}
229
237static int mutt_sasl_cb_log(void *context, int priority, const char *message)
238{
239 if (priority == SASL_LOG_NONE)
240 return SASL_OK;
241
242 int mutt_priority = 0;
243 switch (priority)
244 {
245 case SASL_LOG_TRACE:
246 case SASL_LOG_PASS:
247 mutt_priority = 5;
248 break;
249 case SASL_LOG_DEBUG:
250 case SASL_LOG_NOTE:
251 mutt_priority = 3;
252 break;
253 case SASL_LOG_FAIL:
254 case SASL_LOG_WARN:
255 mutt_priority = 2;
256 break;
257 case SASL_LOG_ERR:
258 mutt_priority = 1;
259 break;
260 default:
261 mutt_debug(LL_DEBUG1, "SASL unknown log priority: %s\n", message);
262 return SASL_OK;
263 }
264 mutt_debug(mutt_priority, "SASL: %s\n", message);
265 return SASL_OK;
266}
267
275{
276 static bool sasl_init = false;
277
278 static sasl_callback_t callbacks[2];
279 int rc;
280
281 if (sasl_init)
282 return SASL_OK;
283
284 /* set up default logging callback */
285 callbacks[0].id = SASL_CB_LOG;
286 callbacks[0].proc = (int (*)(void))(intptr_t) mutt_sasl_cb_log;
287 callbacks[0].context = NULL;
288
289 callbacks[1].id = SASL_CB_LIST_END;
290 callbacks[1].proc = NULL;
291 callbacks[1].context = NULL;
292
293 rc = sasl_client_init(callbacks);
294
295 if (rc != SASL_OK)
296 {
297 mutt_debug(LL_DEBUG1, "libsasl initialisation failed\n");
298 return SASL_FAIL;
299 }
300
301 sasl_init = true;
302
303 return SASL_OK;
304}
305
314static int mutt_sasl_cb_authname(void *context, int id, const char **result, unsigned int *len)
315{
316 if (!result)
317 return SASL_FAIL;
318
319 struct ConnAccount *cac = context;
320
321 *result = NULL;
322 if (len)
323 *len = 0;
324
325 if (!cac)
326 return SASL_BADPARAM;
327
328 mutt_debug(LL_DEBUG2, "getting %s for %s:%u\n",
329 (id == SASL_CB_AUTHNAME) ? "authname" : "user", cac->host, cac->port);
330
331 if (id == SASL_CB_AUTHNAME)
332 {
333 if (mutt_account_getlogin(cac) < 0)
334 return SASL_FAIL;
335 *result = cac->login;
336 }
337 else
338 {
339 if (mutt_account_getuser(cac) < 0)
340 return SASL_FAIL;
341 *result = cac->user;
342 }
343
344 if (len)
345 *len = strlen(*result);
346
347 return SASL_OK;
348}
349
358static int mutt_sasl_cb_pass(sasl_conn_t *conn, void *context, int id, sasl_secret_t **psecret)
359{
360 struct ConnAccount *cac = context;
361 int len;
362
363 if (!cac || !psecret)
364 return SASL_BADPARAM;
365
366 mutt_debug(LL_DEBUG2, "getting password for %s@%s:%u\n", cac->login, cac->host, cac->port);
367
368 if (mutt_account_getpass(cac) < 0)
369 return SASL_FAIL;
370
372 len = strlen(cac->pass);
373
374 sasl_secret_t *secret = mod_data->secret_ptr;
375 mutt_mem_realloc(&secret, sizeof(sasl_secret_t) + len);
376 memcpy((char *) secret->data, cac->pass, (size_t) len);
377 secret->len = len;
378 mod_data->secret_ptr = secret;
379 *psecret = secret;
380
381 return SASL_OK;
382}
383
389static sasl_callback_t *mutt_sasl_get_callbacks(struct ConnAccount *cac)
390{
392 if (!mod_data->mutt_sasl_callbacks)
393 mod_data->mutt_sasl_callbacks = mutt_mem_calloc(5, sizeof(sasl_callback_t));
394
395 sasl_callback_t *callback = mod_data->mutt_sasl_callbacks;
396
397 callback->id = SASL_CB_USER;
398 callback->proc = (int (*)(void))(intptr_t) mutt_sasl_cb_authname;
399 callback->context = cac;
400 callback++;
401
402 callback->id = SASL_CB_AUTHNAME;
403 callback->proc = (int (*)(void))(intptr_t) mutt_sasl_cb_authname;
404 callback->context = cac;
405 callback++;
406
407 callback->id = SASL_CB_PASS;
408 callback->proc = (int (*)(void))(intptr_t) mutt_sasl_cb_pass;
409 callback->context = cac;
410 callback++;
411
412 callback->id = SASL_CB_GETREALM;
413 callback->proc = NULL;
414 callback->context = NULL;
415 callback++;
416
417 callback->id = SASL_CB_LIST_END;
418 callback->proc = NULL;
419 callback->context = NULL;
420
421 return mod_data->mutt_sasl_callbacks;
422}
423
431static int mutt_sasl_conn_open(struct Connection *conn)
432{
433 struct SaslSockData *sasldata = conn->sockdata;
434 conn->sockdata = sasldata->sockdata;
435 int rc = sasldata->open(conn);
436 conn->sockdata = sasldata;
437
438 return rc;
439}
440
447static int mutt_sasl_conn_close(struct Connection *conn)
448{
449 struct SaslSockData *sasldata = conn->sockdata;
450
451 /* restore connection's underlying methods */
452 conn->sockdata = sasldata->sockdata;
453 conn->open = sasldata->open;
454 conn->read = sasldata->read;
455 conn->write = sasldata->write;
456 conn->poll = sasldata->poll;
457 conn->close = sasldata->close;
458
459 /* release sasl resources */
460 sasl_dispose(&sasldata->saslconn);
461 FREE(&sasldata);
462
463 /* call underlying close */
464 int rc = conn->close(conn);
465
466 return rc;
467}
468
472static int mutt_sasl_conn_read(struct Connection *conn, char *buf, size_t count)
473{
474 int rc;
475 unsigned int olen;
476
477 struct SaslSockData *sasldata = conn->sockdata;
478
479 /* if we still have data in our read buffer, copy it into buf */
480 if (sasldata->blen > sasldata->bpos)
481 {
482 olen = ((sasldata->blen - sasldata->bpos) > count) ?
483 count :
484 sasldata->blen - sasldata->bpos;
485
486 memcpy(buf, sasldata->buf + sasldata->bpos, olen);
487 sasldata->bpos += olen;
488
489 return olen;
490 }
491
492 conn->sockdata = sasldata->sockdata;
493
494 sasldata->bpos = 0;
495 sasldata->blen = 0;
496
497 /* and decode the result, if necessary */
498 if (*sasldata->ssf != 0)
499 {
500 do
501 {
502 /* call the underlying read function to fill the buffer */
503 rc = sasldata->read(conn, buf, count);
504 if (rc <= 0)
505 goto out;
506
507 rc = sasl_decode(sasldata->saslconn, buf, rc, &sasldata->buf, &sasldata->blen);
508 if (rc != SASL_OK)
509 {
510 mutt_debug(LL_DEBUG1, "SASL decode failed: %s\n", sasl_errstring(rc, NULL, NULL));
511 goto out;
512 }
513 } while (sasldata->blen == 0);
514
515 olen = ((sasldata->blen - sasldata->bpos) > count) ?
516 count :
517 sasldata->blen - sasldata->bpos;
518
519 memcpy(buf, sasldata->buf, olen);
520 sasldata->bpos += olen;
521
522 rc = olen;
523 }
524 else
525 {
526 rc = sasldata->read(conn, buf, count);
527 }
528
529out:
530 conn->sockdata = sasldata;
531
532 return rc;
533}
534
538static int mutt_sasl_conn_write(struct Connection *conn, const char *buf, size_t count)
539{
540 int rc;
541 const char *pbuf = NULL;
542 unsigned int olen, plen;
543
544 struct SaslSockData *sasldata = conn->sockdata;
545 conn->sockdata = sasldata->sockdata;
546
547 /* encode data, if necessary */
548 if (*sasldata->ssf != 0)
549 {
550 /* handle data larger than MAXOUTBUF */
551 do
552 {
553 olen = (count > *sasldata->pbufsize) ? *sasldata->pbufsize : count;
554
555 rc = sasl_encode(sasldata->saslconn, buf, olen, &pbuf, &plen);
556 if (rc != SASL_OK)
557 {
558 mutt_debug(LL_DEBUG1, "SASL encoding failed: %s\n", sasl_errstring(rc, NULL, NULL));
559 goto fail;
560 }
561
562 rc = sasldata->write(conn, pbuf, plen);
563 if (rc != plen)
564 goto fail;
565
566 count -= olen;
567 buf += olen;
568 } while (count > *sasldata->pbufsize);
569 }
570 else
571 {
572 /* just write using the underlying socket function */
573 rc = sasldata->write(conn, buf, count);
574 }
575
576 conn->sockdata = sasldata;
577
578 return rc;
579
580fail:
581 conn->sockdata = sasldata;
582 return -1;
583}
584
588static int mutt_sasl_conn_poll(struct Connection *conn, time_t wait_secs)
589{
590 struct SaslSockData *sasldata = conn->sockdata;
591 int rc;
592
593 conn->sockdata = sasldata->sockdata;
594 rc = sasldata->poll(conn, wait_secs);
595 conn->sockdata = sasldata;
596
597 return rc;
598}
599
610int mutt_sasl_client_new(struct Connection *conn, sasl_conn_t **saslconn)
611{
612 if (mutt_sasl_start() != SASL_OK)
613 return -1;
614
615 if (!conn->account.service)
616 {
617 mutt_error(_("Unknown SASL profile"));
618 return -1;
619 }
620
621 socklen_t size;
622
623 struct sockaddr_storage local = { 0 };
624 char iplocalport[IP_PORT_BUFLEN] = { 0 };
625 char *plp = NULL;
626 size = sizeof(local);
627 if (getsockname(conn->fd, (struct sockaddr *) &local, &size) == 0)
628 {
629 if (iptostring((struct sockaddr *) &local, size, iplocalport, IP_PORT_BUFLEN) == SASL_OK)
630 plp = iplocalport;
631 else
632 mutt_debug(LL_DEBUG2, "SASL failed to parse local IP address\n");
633 }
634 else
635 {
636 mutt_debug(LL_DEBUG2, "SASL failed to get local IP address\n");
637 }
638
639 struct sockaddr_storage remote = { 0 };
640 char ipremoteport[IP_PORT_BUFLEN] = { 0 };
641 char *prp = NULL;
642 size = sizeof(remote);
643 if (getpeername(conn->fd, (struct sockaddr *) &remote, &size) == 0)
644 {
645 if (iptostring((struct sockaddr *) &remote, size, ipremoteport, IP_PORT_BUFLEN) == SASL_OK)
646 prp = ipremoteport;
647 else
648 mutt_debug(LL_DEBUG2, "SASL failed to parse remote IP address\n");
649 }
650 else
651 {
652 mutt_debug(LL_DEBUG2, "SASL failed to get remote IP address\n");
653 }
654
655 mutt_debug(LL_DEBUG2, "SASL local ip: %s, remote ip:%s\n", NONULL(plp), NONULL(prp));
656
657 int rc = sasl_client_new(conn->account.service, conn->account.host, plp, prp,
658 mutt_sasl_get_callbacks(&conn->account), 0, saslconn);
659 if (rc != SASL_OK)
660 {
661 mutt_error(_("Error allocating SASL connection"));
662 return -1;
663 }
664
665 /* Work around a casting bug in the SASL krb4 module */
666 sasl_security_properties_t secprops = { 0 };
667 secprops.max_ssf = 0x7fff;
668 secprops.maxbufsize = MUTT_SASL_MAXBUF;
669 if (sasl_setprop(*saslconn, SASL_SEC_PROPS, &secprops) != SASL_OK)
670 {
671 mutt_error(_("Error setting SASL security properties"));
672 sasl_dispose(saslconn);
673 return -1;
674 }
675
676 if (conn->ssf != 0)
677 {
678 /* I'm not sure this actually has an effect, at least with SASLv2 */
679 mutt_debug(LL_DEBUG2, "External SSF: %d\n", conn->ssf);
680 if (sasl_setprop(*saslconn, SASL_SSF_EXTERNAL, &conn->ssf) != SASL_OK)
681 {
682 mutt_error(_("Error setting SASL external security strength"));
683 sasl_dispose(saslconn);
684 return -1;
685 }
686 }
687 if (conn->account.user[0])
688 {
689 mutt_debug(LL_DEBUG2, "External authentication name: %s\n", conn->account.user);
690 if (sasl_setprop(*saslconn, SASL_AUTH_EXTERNAL, conn->account.user) != SASL_OK)
691 {
692 mutt_error(_("Error setting SASL external user name"));
693 sasl_dispose(saslconn);
694 return -1;
695 }
696 }
697
698 return 0;
699}
700
708int mutt_sasl_interact(sasl_interact_t *interaction)
709{
710 int rc = SASL_OK;
711 char prompt[128] = { 0 };
712 struct Buffer *resp = buf_pool_get();
713
714 while (interaction->id != SASL_CB_LIST_END)
715 {
716 mutt_debug(LL_DEBUG2, "filling in SASL interaction %ld\n", interaction->id);
717
718 snprintf(prompt, sizeof(prompt), "%s: ", interaction->prompt);
719 buf_reset(resp);
720
721 if (!OptGui || (mw_get_field(prompt, resp, MUTT_COMP_NONE, HC_OTHER, NULL, NULL) != 0))
722 {
723 rc = SASL_FAIL;
724 break;
725 }
726
727 interaction->len = buf_len(resp) + 1;
728 interaction->result = buf_strdup(resp);
729 interaction++;
730 }
731
732 buf_pool_release(&resp);
733 return rc;
734}
735
744void mutt_sasl_setup_conn(struct Connection *conn, sasl_conn_t *saslconn)
745{
746 struct SaslSockData *sasldata = MUTT_MEM_MALLOC(1, struct SaslSockData);
747 /* work around sasl_getprop aliasing issues */
748 const void *tmp = NULL;
749
750 sasldata->saslconn = saslconn;
751 /* get ssf so we know whether we have to (en|de)code read/write */
752 sasl_getprop(saslconn, SASL_SSF, &tmp);
753 sasldata->ssf = tmp;
754 mutt_debug(LL_DEBUG3, "SASL protection strength: %u\n", *sasldata->ssf);
755 /* Add SASL SSF to transport SSF */
756 conn->ssf += *sasldata->ssf;
757 sasl_getprop(saslconn, SASL_MAXOUTBUF, &tmp);
758 sasldata->pbufsize = tmp;
759 mutt_debug(LL_DEBUG3, "SASL protection buffer size: %u\n", *sasldata->pbufsize);
760
761 /* clear input buffer */
762 sasldata->buf = NULL;
763 sasldata->bpos = 0;
764 sasldata->blen = 0;
765
766 /* preserve old functions */
767 sasldata->sockdata = conn->sockdata;
768 sasldata->open = conn->open;
769 sasldata->read = conn->read;
770 sasldata->write = conn->write;
771 sasldata->poll = conn->poll;
772 sasldata->close = conn->close;
773
774 /* and set up new functions */
775 conn->sockdata = sasldata;
781}
782
790{
791 /* As we never use the server-side, the silently ignore the return value */
792 sasl_client_done();
793}
size_t buf_len(const struct Buffer *buf)
Calculate the length of a Buffer.
Definition buffer.c:491
void buf_reset(struct Buffer *buf)
Reset an existing Buffer.
Definition buffer.c:76
char * buf_strdup(const struct Buffer *buf)
Copy a Buffer's string.
Definition buffer.c:571
Conn private Module data.
int mutt_account_getpass(struct ConnAccount *cac)
Fetch password into ConnAccount, if necessary.
int mutt_account_getuser(struct ConnAccount *cac)
Retrieve username into ConnAccount, if necessary.
Definition connaccount.c:51
int mutt_account_getlogin(struct ConnAccount *cac)
Retrieve login info into ConnAccount, if necessary.
Connection Credentials.
An open network connection (socket)
Convenience wrapper for the core headers.
Edit a string.
@ MUTT_COMP_NONE
No flags are set.
Definition wdata.h:46
bool OptGui
(pseudo) when the gui (and curses) are started
Definition globals.c:48
Global variables.
static int mutt_sasl_conn_close(struct Connection *conn)
Close SASL connection - Implements Connection::close() -.
Definition sasl.c:447
int(* close)(struct Connection *conn)
Close a socket Connection - Implements Connection::close() -.
Definition sasl.c:101
int(* open)(struct Connection *conn)
Open a socket Connection - Implements Connection::open() -.
Definition sasl.c:81
static int mutt_sasl_conn_open(struct Connection *conn)
Empty wrapper for underlying open function - Implements Connection::open() -.
Definition sasl.c:431
int(* poll)(struct Connection *conn, time_t wait_secs)
Check if any data is waiting on a socket - Implements Connection::poll() -.
Definition sasl.c:96
static int mutt_sasl_conn_poll(struct Connection *conn, time_t wait_secs)
Check if any data is waiting on a socket - Implements Connection::poll() -.
Definition sasl.c:588
static int mutt_sasl_conn_read(struct Connection *conn, char *buf, size_t count)
Read data from an SASL connection - Implements Connection::read() -.
Definition sasl.c:472
int(* read)(struct Connection *conn, char *buf, size_t count)
Read from a socket Connection - Implements Connection::read() -.
Definition sasl.c:86
static int mutt_sasl_conn_write(struct Connection *conn, const char *buf, size_t count)
Write to an SASL connection - Implements Connection::write() -.
Definition sasl.c:538
int(* write)(struct Connection *conn, const char *buf, size_t count)
Write to a socket Connection - Implements Connection::write() -.
Definition sasl.c:91
int mw_get_field(const char *prompt, struct Buffer *buf, CompletionFlags complete, enum HistoryClass hclass, const struct CompleteOps *comp_api, void *cdata)
Ask the user for a string -.
Definition window.c:502
#define mutt_error(...)
Definition logging2.h:94
#define mutt_debug(LEVEL,...)
Definition logging2.h:91
Read/write command history from/to a file.
@ HC_OTHER
Miscellaneous strings.
Definition lib.h:61
@ LL_DEBUG3
Log at debug level 3.
Definition logging2.h:47
@ LL_DEBUG2
Log at debug level 2.
Definition logging2.h:46
@ LL_DEBUG1
Log at debug level 1.
Definition logging2.h:45
void * mutt_mem_calloc(size_t nmemb, size_t size)
Allocate zeroed memory on the heap.
Definition memory.c:76
void mutt_mem_realloc(void *pptr, size_t size)
Resize a block of memory on the heap.
Definition memory.c:146
#define countof(x)
Definition memory.h:49
#define FREE(x)
Free memory and set the pointer to NULL.
Definition memory.h:68
#define MUTT_MEM_MALLOC(n, type)
Definition memory.h:53
@ MODULE_ID_CONN
ModuleConn, Network connections
Definition module_api.h:60
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:677
void * neomutt_get_module_data(struct NeoMutt *n, enum ModuleId id)
Get the private data for a Module.
Definition neomutt.c:663
struct Buffer * buf_pool_get(void)
Get a Buffer from the pool.
Definition pool.c:91
void buf_pool_release(struct Buffer **ptr)
Return a Buffer to the pool.
Definition pool.c:111
static int mutt_sasl_cb_pass(sasl_conn_t *conn, void *context, int id, sasl_secret_t **psecret)
SASL callback function to get password.
Definition sasl.c:358
#define MUTT_SASL_MAXBUF
Maximum size for SASL protection buffer.
Definition sasl.c:117
static int mutt_sasl_cb_authname(void *context, int id, const char **result, unsigned int *len)
Callback to retrieve authname or user from ConnAccount.
Definition sasl.c:314
void mutt_sasl_cleanup(void)
Invoke when processing is complete.
Definition sasl.c:789
#define IP_PORT_BUFLEN
Buffer size for "host;port" string (NI_MAXHOST + NI_MAXSERV)
Definition sasl.c:120
int mutt_sasl_start(void)
Initialise SASL library.
Definition sasl.c:274
static int getnameinfo_err(int rc)
Convert a getaddrinfo() error code into an SASL error code.
Definition sasl.c:150
int mutt_sasl_interact(sasl_interact_t *interaction)
Perform an SASL interaction with the user.
Definition sasl.c:708
static int mutt_sasl_cb_log(void *context, int priority, const char *message)
Callback to log SASL messages.
Definition sasl.c:237
static sasl_callback_t * mutt_sasl_get_callbacks(struct ConnAccount *cac)
Get the SASL callback functions.
Definition sasl.c:389
static const char *const SaslAuthenticators[]
Authentication methods supported by Cyrus SASL.
Definition sasl.c:107
static int iptostring(const struct sockaddr *addr, socklen_t addrlen, char *out, unsigned int outlen)
Convert IP Address to string.
Definition sasl.c:204
bool sasl_auth_validator(const char *authenticator)
SASL callback functions, e.g. mutt_sasl_cb_authname(), mutt_sasl_cb_pass()
Definition sasl.c:133
int mutt_sasl_client_new(struct Connection *conn, sasl_conn_t **saslconn)
Wrapper for sasl_client_new()
Definition sasl.c:610
void mutt_sasl_setup_conn(struct Connection *conn, sasl_conn_t *saslconn)
Set up an SASL connection.
Definition sasl.c:744
SASL authentication support.
#define NONULL(x)
Definition string2.h:44
String manipulation buffer.
Definition buffer.h:36
Login details for a remote server.
Definition connaccount.h:59
char login[128]
Login name.
Definition connaccount.h:61
char user[128]
Username.
Definition connaccount.h:62
char pass[256]
Password.
Definition connaccount.h:63
const char * service
Name of the service, e.g. "imap".
Definition connaccount.h:67
char host[128]
Server to login to.
Definition connaccount.h:60
unsigned short port
Port to connect to.
Definition connaccount.h:64
Conn private Module data.
Definition module_data.h:38
void * sockdata
Backend-specific socket data.
Definition connection.h:55
int(* poll)(struct Connection *conn, time_t wait_secs)
Definition connection.h:105
int(* write)(struct Connection *conn, const char *buf, size_t count)
Definition connection.h:92
unsigned int ssf
Security strength factor, in bits (see notes)
Definition connection.h:50
int(* close)(struct Connection *conn)
Definition connection.h:116
struct ConnAccount account
Account details: username, password, etc.
Definition connection.h:49
int(* open)(struct Connection *conn)
Definition connection.h:66
int fd
Socket file descriptor.
Definition connection.h:53
int(* read)(struct Connection *conn, char *buf, size_t count)
Definition connection.h:79
Container for Accounts, Notifications.
Definition neomutt.h:41
SASL authentication API -.
Definition sasl.c:66
void * sockdata
Underlying socket data.
Definition sasl.c:76
unsigned int blen
Size of the read buffer.
Definition sasl.c:73
unsigned int bpos
Current read position.
Definition sasl.c:74
const sasl_ssf_t * ssf
Security strength factor, in bits.
Definition sasl.c:68
const unsigned int * pbufsize
Buffer size.
Definition sasl.c:69
const char * buf
Buffer for data read from the connection.
Definition sasl.c:72
sasl_conn_t * saslconn
Raw SASL connection.
Definition sasl.c:67