NeoMutt  2025-12-11-980-ge38c27
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];
208 char pbuf[NI_MAXSERV];
209 int rc;
210
211 if (!addr || !out)
212 return SASL_BADPARAM;
213
214 rc = getnameinfo(addr, addrlen, hbuf, sizeof(hbuf), pbuf, sizeof(pbuf),
215 NI_NUMERICHOST |
216#ifdef NI_WITHSCOPEID
217 NI_WITHSCOPEID |
218#endif
219 NI_NUMERICSERV);
220 if (rc != 0)
221 return getnameinfo_err(rc);
222
223 if (outlen < strlen(hbuf) + strlen(pbuf) + 2)
224 return SASL_BUFOVER;
225
226 snprintf(out, outlen, "%s;%s", hbuf, pbuf);
227
228 return SASL_OK;
229}
230
238static int mutt_sasl_cb_log(void *context, int priority, const char *message)
239{
240 if (priority == SASL_LOG_NONE)
241 return SASL_OK;
242
243 int mutt_priority = 0;
244 switch (priority)
245 {
246 case SASL_LOG_TRACE:
247 case SASL_LOG_PASS:
248 mutt_priority = 5;
249 break;
250 case SASL_LOG_DEBUG:
251 case SASL_LOG_NOTE:
252 mutt_priority = 3;
253 break;
254 case SASL_LOG_FAIL:
255 case SASL_LOG_WARN:
256 mutt_priority = 2;
257 break;
258 case SASL_LOG_ERR:
259 mutt_priority = 1;
260 break;
261 default:
262 mutt_debug(LL_DEBUG1, "SASL unknown log priority: %s\n", message);
263 return SASL_OK;
264 }
265 mutt_debug(mutt_priority, "SASL: %s\n", message);
266 return SASL_OK;
267}
268
276{
277 static bool sasl_init = false;
278
279 static sasl_callback_t callbacks[2];
280 int rc;
281
282 if (sasl_init)
283 return SASL_OK;
284
285 /* set up default logging callback */
286 callbacks[0].id = SASL_CB_LOG;
287 callbacks[0].proc = (int (*)(void))(intptr_t) mutt_sasl_cb_log;
288 callbacks[0].context = NULL;
289
290 callbacks[1].id = SASL_CB_LIST_END;
291 callbacks[1].proc = NULL;
292 callbacks[1].context = NULL;
293
294 rc = sasl_client_init(callbacks);
295
296 if (rc != SASL_OK)
297 {
298 mutt_debug(LL_DEBUG1, "libsasl initialisation failed\n");
299 return SASL_FAIL;
300 }
301
302 sasl_init = true;
303
304 return SASL_OK;
305}
306
315static int mutt_sasl_cb_authname(void *context, int id, const char **result, unsigned int *len)
316{
317 if (!result)
318 return SASL_FAIL;
319
320 struct ConnAccount *cac = context;
321
322 *result = NULL;
323 if (len)
324 *len = 0;
325
326 if (!cac)
327 return SASL_BADPARAM;
328
329 mutt_debug(LL_DEBUG2, "getting %s for %s:%u\n",
330 (id == SASL_CB_AUTHNAME) ? "authname" : "user", cac->host, cac->port);
331
332 if (id == SASL_CB_AUTHNAME)
333 {
334 if (mutt_account_getlogin(cac) < 0)
335 return SASL_FAIL;
336 *result = cac->login;
337 }
338 else
339 {
340 if (mutt_account_getuser(cac) < 0)
341 return SASL_FAIL;
342 *result = cac->user;
343 }
344
345 if (len)
346 *len = strlen(*result);
347
348 return SASL_OK;
349}
350
359static int mutt_sasl_cb_pass(sasl_conn_t *conn, void *context, int id, sasl_secret_t **psecret)
360{
361 struct ConnAccount *cac = context;
362 int len;
363
364 if (!cac || !psecret)
365 return SASL_BADPARAM;
366
367 mutt_debug(LL_DEBUG2, "getting password for %s@%s:%u\n", cac->login, cac->host, cac->port);
368
369 if (mutt_account_getpass(cac) < 0)
370 return SASL_FAIL;
371
373 len = strlen(cac->pass);
374
375 sasl_secret_t *secret = mod_data->secret_ptr;
376 mutt_mem_realloc(&secret, sizeof(sasl_secret_t) + len);
377 memcpy((char *) secret->data, cac->pass, (size_t) len);
378 secret->len = len;
379 mod_data->secret_ptr = secret;
380 *psecret = secret;
381
382 return SASL_OK;
383}
384
390static sasl_callback_t *mutt_sasl_get_callbacks(struct ConnAccount *cac)
391{
393 if (!mod_data->mutt_sasl_callbacks)
394 mod_data->mutt_sasl_callbacks = mutt_mem_calloc(5, sizeof(sasl_callback_t));
395
396 sasl_callback_t *callback = mod_data->mutt_sasl_callbacks;
397
398 callback->id = SASL_CB_USER;
399 callback->proc = (int (*)(void))(intptr_t) mutt_sasl_cb_authname;
400 callback->context = cac;
401 callback++;
402
403 callback->id = SASL_CB_AUTHNAME;
404 callback->proc = (int (*)(void))(intptr_t) mutt_sasl_cb_authname;
405 callback->context = cac;
406 callback++;
407
408 callback->id = SASL_CB_PASS;
409 callback->proc = (int (*)(void))(intptr_t) mutt_sasl_cb_pass;
410 callback->context = cac;
411 callback++;
412
413 callback->id = SASL_CB_GETREALM;
414 callback->proc = NULL;
415 callback->context = NULL;
416 callback++;
417
418 callback->id = SASL_CB_LIST_END;
419 callback->proc = NULL;
420 callback->context = NULL;
421
422 return mod_data->mutt_sasl_callbacks;
423}
424
432static int mutt_sasl_conn_open(struct Connection *conn)
433{
434 struct SaslSockData *sasldata = conn->sockdata;
435 conn->sockdata = sasldata->sockdata;
436 int rc = sasldata->open(conn);
437 conn->sockdata = sasldata;
438
439 return rc;
440}
441
448static int mutt_sasl_conn_close(struct Connection *conn)
449{
450 struct SaslSockData *sasldata = conn->sockdata;
451
452 /* restore connection's underlying methods */
453 conn->sockdata = sasldata->sockdata;
454 conn->open = sasldata->open;
455 conn->read = sasldata->read;
456 conn->write = sasldata->write;
457 conn->poll = sasldata->poll;
458 conn->close = sasldata->close;
459
460 /* release sasl resources */
461 sasl_dispose(&sasldata->saslconn);
462 FREE(&sasldata);
463
464 /* call underlying close */
465 int rc = conn->close(conn);
466
467 return rc;
468}
469
473static int mutt_sasl_conn_read(struct Connection *conn, char *buf, size_t count)
474{
475 int rc;
476 unsigned int olen;
477
478 struct SaslSockData *sasldata = conn->sockdata;
479
480 /* if we still have data in our read buffer, copy it into buf */
481 if (sasldata->blen > sasldata->bpos)
482 {
483 olen = ((sasldata->blen - sasldata->bpos) > count) ?
484 count :
485 sasldata->blen - sasldata->bpos;
486
487 memcpy(buf, sasldata->buf + sasldata->bpos, olen);
488 sasldata->bpos += olen;
489
490 return olen;
491 }
492
493 conn->sockdata = sasldata->sockdata;
494
495 sasldata->bpos = 0;
496 sasldata->blen = 0;
497
498 /* and decode the result, if necessary */
499 if (*sasldata->ssf != 0)
500 {
501 do
502 {
503 /* call the underlying read function to fill the buffer */
504 rc = sasldata->read(conn, buf, count);
505 if (rc <= 0)
506 goto out;
507
508 rc = sasl_decode(sasldata->saslconn, buf, rc, &sasldata->buf, &sasldata->blen);
509 if (rc != SASL_OK)
510 {
511 mutt_debug(LL_DEBUG1, "SASL decode failed: %s\n", sasl_errstring(rc, NULL, NULL));
512 goto out;
513 }
514 } while (sasldata->blen == 0);
515
516 olen = ((sasldata->blen - sasldata->bpos) > count) ?
517 count :
518 sasldata->blen - sasldata->bpos;
519
520 memcpy(buf, sasldata->buf, olen);
521 sasldata->bpos += olen;
522
523 rc = olen;
524 }
525 else
526 {
527 rc = sasldata->read(conn, buf, count);
528 }
529
530out:
531 conn->sockdata = sasldata;
532
533 return rc;
534}
535
539static int mutt_sasl_conn_write(struct Connection *conn, const char *buf, size_t count)
540{
541 int rc;
542 const char *pbuf = NULL;
543 unsigned int olen;
544 unsigned int plen;
545
546 struct SaslSockData *sasldata = conn->sockdata;
547 conn->sockdata = sasldata->sockdata;
548
549 /* encode data, if necessary */
550 if (*sasldata->ssf != 0)
551 {
552 /* handle data larger than MAXOUTBUF */
553 do
554 {
555 olen = (count > *sasldata->pbufsize) ? *sasldata->pbufsize : count;
556
557 rc = sasl_encode(sasldata->saslconn, buf, olen, &pbuf, &plen);
558 if (rc != SASL_OK)
559 {
560 mutt_debug(LL_DEBUG1, "SASL encoding failed: %s\n", sasl_errstring(rc, NULL, NULL));
561 goto fail;
562 }
563
564 rc = sasldata->write(conn, pbuf, plen);
565 if (rc != plen)
566 goto fail;
567
568 count -= olen;
569 buf += olen;
570 } while (count > *sasldata->pbufsize);
571 }
572 else
573 {
574 /* just write using the underlying socket function */
575 rc = sasldata->write(conn, buf, count);
576 }
577
578 conn->sockdata = sasldata;
579
580 return rc;
581
582fail:
583 conn->sockdata = sasldata;
584 return -1;
585}
586
590static int mutt_sasl_conn_poll(struct Connection *conn, time_t wait_secs)
591{
592 struct SaslSockData *sasldata = conn->sockdata;
593 int rc;
594
595 conn->sockdata = sasldata->sockdata;
596 rc = sasldata->poll(conn, wait_secs);
597 conn->sockdata = sasldata;
598
599 return rc;
600}
601
612int mutt_sasl_client_new(struct Connection *conn, sasl_conn_t **saslconn)
613{
614 if (mutt_sasl_start() != SASL_OK)
615 return -1;
616
617 if (!conn->account.service)
618 {
619 mutt_error(_("Unknown SASL profile"));
620 return -1;
621 }
622
623 socklen_t size;
624
625 struct sockaddr_storage local = { 0 };
626 char iplocalport[IP_PORT_BUFLEN] = { 0 };
627 char *plp = NULL;
628 size = sizeof(local);
629 if (getsockname(conn->fd, (struct sockaddr *) &local, &size) == 0)
630 {
631 if (iptostring((struct sockaddr *) &local, size, iplocalport, IP_PORT_BUFLEN) == SASL_OK)
632 plp = iplocalport;
633 else
634 mutt_debug(LL_DEBUG2, "SASL failed to parse local IP address\n");
635 }
636 else
637 {
638 mutt_debug(LL_DEBUG2, "SASL failed to get local IP address\n");
639 }
640
641 struct sockaddr_storage remote = { 0 };
642 char ipremoteport[IP_PORT_BUFLEN] = { 0 };
643 char *prp = NULL;
644 size = sizeof(remote);
645 if (getpeername(conn->fd, (struct sockaddr *) &remote, &size) == 0)
646 {
647 if (iptostring((struct sockaddr *) &remote, size, ipremoteport, IP_PORT_BUFLEN) == SASL_OK)
648 prp = ipremoteport;
649 else
650 mutt_debug(LL_DEBUG2, "SASL failed to parse remote IP address\n");
651 }
652 else
653 {
654 mutt_debug(LL_DEBUG2, "SASL failed to get remote IP address\n");
655 }
656
657 mutt_debug(LL_DEBUG2, "SASL local ip: %s, remote ip:%s\n", NONULL(plp), NONULL(prp));
658
659 int rc = sasl_client_new(conn->account.service, conn->account.host, plp, prp,
660 mutt_sasl_get_callbacks(&conn->account), 0, saslconn);
661 if (rc != SASL_OK)
662 {
663 mutt_error(_("Error allocating SASL connection"));
664 return -1;
665 }
666
667 /* Work around a casting bug in the SASL krb4 module */
668 sasl_security_properties_t secprops = { 0 };
669 secprops.max_ssf = 0x7fff;
670 secprops.maxbufsize = MUTT_SASL_MAXBUF;
671 if (sasl_setprop(*saslconn, SASL_SEC_PROPS, &secprops) != SASL_OK)
672 {
673 mutt_error(_("Error setting SASL security properties"));
674 sasl_dispose(saslconn);
675 return -1;
676 }
677
678 if (conn->ssf != 0)
679 {
680 /* I'm not sure this actually has an effect, at least with SASLv2 */
681 mutt_debug(LL_DEBUG2, "External SSF: %d\n", conn->ssf);
682 if (sasl_setprop(*saslconn, SASL_SSF_EXTERNAL, &conn->ssf) != SASL_OK)
683 {
684 mutt_error(_("Error setting SASL external security strength"));
685 sasl_dispose(saslconn);
686 return -1;
687 }
688 }
689 if (conn->account.user[0])
690 {
691 mutt_debug(LL_DEBUG2, "External authentication name: %s\n", conn->account.user);
692 if (sasl_setprop(*saslconn, SASL_AUTH_EXTERNAL, conn->account.user) != SASL_OK)
693 {
694 mutt_error(_("Error setting SASL external user name"));
695 sasl_dispose(saslconn);
696 return -1;
697 }
698 }
699
700 return 0;
701}
702
710int mutt_sasl_interact(sasl_interact_t *interaction)
711{
712 int rc = SASL_OK;
713 char prompt[128] = { 0 };
714 struct Buffer *resp = buf_pool_get();
715
716 while (interaction->id != SASL_CB_LIST_END)
717 {
718 mutt_debug(LL_DEBUG2, "filling in SASL interaction %ld\n", interaction->id);
719
720 snprintf(prompt, sizeof(prompt), "%s: ", interaction->prompt);
721 buf_reset(resp);
722
723 if (!OptGui || (mw_get_field(prompt, resp, MUTT_COMP_NONE, HC_OTHER, NULL, NULL) != 0))
724 {
725 rc = SASL_FAIL;
726 break;
727 }
728
729 interaction->len = buf_len(resp) + 1;
730 interaction->result = buf_strdup(resp);
731 interaction++;
732 }
733
734 buf_pool_release(&resp);
735 return rc;
736}
737
746void mutt_sasl_setup_conn(struct Connection *conn, sasl_conn_t *saslconn)
747{
748 struct SaslSockData *sasldata = MUTT_MEM_MALLOC(1, struct SaslSockData);
749 /* work around sasl_getprop aliasing issues */
750 const void *tmp = NULL;
751
752 sasldata->saslconn = saslconn;
753 /* get ssf so we know whether we have to (en|de)code read/write */
754 sasl_getprop(saslconn, SASL_SSF, &tmp);
755 sasldata->ssf = tmp;
756 mutt_debug(LL_DEBUG3, "SASL protection strength: %u\n", *sasldata->ssf);
757 /* Add SASL SSF to transport SSF */
758 conn->ssf += *sasldata->ssf;
759 sasl_getprop(saslconn, SASL_MAXOUTBUF, &tmp);
760 sasldata->pbufsize = tmp;
761 mutt_debug(LL_DEBUG3, "SASL protection buffer size: %u\n", *sasldata->pbufsize);
762
763 /* clear input buffer */
764 sasldata->buf = NULL;
765 sasldata->bpos = 0;
766 sasldata->blen = 0;
767
768 /* preserve old functions */
769 sasldata->sockdata = conn->sockdata;
770 sasldata->open = conn->open;
771 sasldata->read = conn->read;
772 sasldata->write = conn->write;
773 sasldata->poll = conn->poll;
774 sasldata->close = conn->close;
775
776 /* and set up new functions */
777 conn->sockdata = sasldata;
783}
784
792{
793 /* As we never use the server-side, the silently ignore the return value */
794 sasl_client_done();
795}
size_t buf_len(const struct Buffer *buf)
Calculate the length of a Buffer.
Definition buffer.c:497
void buf_reset(struct Buffer *buf)
Reset an existing Buffer.
Definition buffer.c:89
char * buf_strdup(const struct Buffer *buf)
Copy a Buffer's string.
Definition buffer.c:577
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:448
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:432
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:590
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:473
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:539
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:79
void mutt_mem_realloc(void *pptr, size_t size)
Resize a block of memory on the heap.
Definition memory.c:149
#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:678
void * neomutt_get_module_data(struct NeoMutt *n, enum ModuleId id)
Get the private data for a Module.
Definition neomutt.c:666
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:359
#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:315
void mutt_sasl_cleanup(void)
Invoke when processing is complete.
Definition sasl.c:791
#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:275
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:710
static int mutt_sasl_cb_log(void *context, int priority, const char *message)
Callback to log SASL messages.
Definition sasl.c:238
static sasl_callback_t * mutt_sasl_get_callbacks(struct ConnAccount *cac)
Get the SASL callback functions.
Definition sasl.c:390
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:612
void mutt_sasl_setup_conn(struct Connection *conn, sasl_conn_t *saslconn)
Set up an SASL connection.
Definition sasl.c:746
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