NeoMutt  2023-05-17-16-g61469c
Teaching an old dog new tricks
DOXYGEN
sasl.h File Reference

SASL authentication support. More...

#include <sasl/sasl.h>
#include <stdbool.h>
+ Include dependency graph for sasl.h:
+ This graph shows which files directly or indirectly include this file:

Go to the source code of this file.

Functions

bool sasl_auth_validator (const char *authenticator)
 Validate an auth method against Cyrus SASL methods. More...
 
int mutt_sasl_client_new (struct Connection *conn, sasl_conn_t **saslconn)
 Wrapper for sasl_client_new() More...
 
void mutt_sasl_done (void)
 Invoke when processing is complete. More...
 
int mutt_sasl_interact (sasl_interact_t *interaction)
 Perform an SASL interaction with the user. More...
 
void mutt_sasl_setup_conn (struct Connection *conn, sasl_conn_t *saslconn)
 Set up an SASL connection. More...
 

Detailed Description

SASL authentication support.

Authors
  • Brendan Cully

This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.

You should have received a copy of the GNU General Public License along with this program. If not, see http://www.gnu.org/licenses/.

Definition in file sasl.h.

Function Documentation

◆ sasl_auth_validator()

bool sasl_auth_validator ( const char *  authenticator)

Validate an auth method against Cyrus SASL methods.

Parameters
authenticatorName of the authenticator to validate
Return values
trueArgument matches an accepted auth method

Definition at line 133 of file sasl.c.

134{
135 for (size_t i = 0; i < mutt_array_size(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}
#define mutt_array_size(x)
Definition: memory.h:36
bool mutt_istr_equal(const char *a, const char *b)
Compare two strings, ignoring case.
Definition: string.c:810
static const char *const SaslAuthenticators[]
Authenticaion methods supported by Cyrus SASL.
Definition: sasl.c:103
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ mutt_sasl_client_new()

int mutt_sasl_client_new ( struct Connection conn,
sasl_conn_t **  saslconn 
)

Wrapper for sasl_client_new()

Parameters
[in]connConnection to a server
[out]saslconnSASL connection
Return values
0Success
-1Error

which also sets various security properties. If this turns out to be fine for POP too we can probably stop exporting mutt_sasl_get_callbacks().

Definition at line 603 of file sasl.c.

604{
605 sasl_security_properties_t secprops;
606 struct sockaddr_storage local, remote;
607 socklen_t size;
608 char iplocalport[IP_PORT_BUFLEN], ipremoteport[IP_PORT_BUFLEN];
609 char *plp = NULL;
610 char *prp = NULL;
611 int rc;
612
613 if (mutt_sasl_start() != SASL_OK)
614 return -1;
615
616 if (!conn->account.service)
617 {
618 mutt_error(_("Unknown SASL profile"));
619 return -1;
620 }
621
622 size = sizeof(local);
623 if (getsockname(conn->fd, (struct sockaddr *) &local, &size) == 0)
624 {
625 if (iptostring((struct sockaddr *) &local, size, iplocalport, IP_PORT_BUFLEN) == SASL_OK)
626 plp = iplocalport;
627 else
628 mutt_debug(LL_DEBUG2, "SASL failed to parse local IP address\n");
629 }
630 else
631 {
632 mutt_debug(LL_DEBUG2, "SASL failed to get local IP address\n");
633 }
634
635 size = sizeof(remote);
636 if (getpeername(conn->fd, (struct sockaddr *) &remote, &size) == 0)
637 {
638 if (iptostring((struct sockaddr *) &remote, size, ipremoteport, IP_PORT_BUFLEN) == SASL_OK)
639 prp = ipremoteport;
640 else
641 mutt_debug(LL_DEBUG2, "SASL failed to parse remote IP address\n");
642 }
643 else
644 {
645 mutt_debug(LL_DEBUG2, "SASL failed to get remote IP address\n");
646 }
647
648 mutt_debug(LL_DEBUG2, "SASL local ip: %s, remote ip:%s\n", NONULL(plp), NONULL(prp));
649
650 rc = sasl_client_new(conn->account.service, conn->account.host, plp, prp,
651 mutt_sasl_get_callbacks(&conn->account), 0, saslconn);
652
653 if (rc != SASL_OK)
654 {
655 mutt_error(_("Error allocating SASL connection"));
656 return -1;
657 }
658
659 memset(&secprops, 0, sizeof(secprops));
660 /* Work around a casting bug in the SASL krb4 module */
661 secprops.max_ssf = 0x7fff;
662 secprops.maxbufsize = MUTT_SASL_MAXBUF;
663 if (sasl_setprop(*saslconn, SASL_SEC_PROPS, &secprops) != SASL_OK)
664 {
665 mutt_error(_("Error setting SASL security properties"));
666 sasl_dispose(saslconn);
667 return -1;
668 }
669
670 if (conn->ssf != 0)
671 {
672 /* I'm not sure this actually has an effect, at least with SASLv2 */
673 mutt_debug(LL_DEBUG2, "External SSF: %d\n", conn->ssf);
674 if (sasl_setprop(*saslconn, SASL_SSF_EXTERNAL, &conn->ssf) != SASL_OK)
675 {
676 mutt_error(_("Error setting SASL external security strength"));
677 sasl_dispose(saslconn);
678 return -1;
679 }
680 }
681 if (conn->account.user[0])
682 {
683 mutt_debug(LL_DEBUG2, "External authentication name: %s\n", conn->account.user);
684 if (sasl_setprop(*saslconn, SASL_AUTH_EXTERNAL, conn->account.user) != SASL_OK)
685 {
686 mutt_error(_("Error setting SASL external user name"));
687 sasl_dispose(saslconn);
688 return -1;
689 }
690 }
691
692 return 0;
693}
#define mutt_error(...)
Definition: logging2.h:87
#define mutt_debug(LEVEL,...)
Definition: logging2.h:84
@ LL_DEBUG2
Log at debug level 2.
Definition: logging2.h:41
#define _(a)
Definition: message.h:28
#define MUTT_SASL_MAXBUF
Definition: sasl.c:115
#define IP_PORT_BUFLEN
Definition: sasl.c:120
static int mutt_sasl_start(void)
Initialise SASL library.
Definition: sasl.c:274
static sasl_callback_t * mutt_sasl_get_callbacks(struct ConnAccount *cac)
Get the SASL callback functions.
Definition: sasl.c:386
static int iptostring(const struct sockaddr *addr, socklen_t addrlen, char *out, unsigned int outlen)
Convert IP Address to string.
Definition: sasl.c:204
#define NONULL(x)
Definition: string2.h:37
char user[128]
Username.
Definition: connaccount.h:56
const char * service
Name of the service, e.g. "imap".
Definition: connaccount.h:61
char host[128]
Server to login to.
Definition: connaccount.h:54
unsigned int ssf
Security strength factor, in bits (see notes)
Definition: connection.h:51
struct ConnAccount account
Account details: username, password, etc.
Definition: connection.h:50
int fd
Socket file descriptor.
Definition: connection.h:54
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ mutt_sasl_done()

void mutt_sasl_done ( void  )

Invoke when processing is complete.

This is a cleanup function, used to free all memory used by the library. Invoke when processing is complete.

Definition at line 784 of file sasl.c.

785{
786 /* As we never use the server-side, the silently ignore the return value */
787 sasl_client_done();
788}
+ Here is the caller graph for this function:

◆ mutt_sasl_interact()

int mutt_sasl_interact ( sasl_interact_t *  interaction)

Perform an SASL interaction with the user.

Parameters
interactionDetails of interaction
Return values
numSASL error code: SASL_OK or SASL_FAIL

An example interaction might be asking the user for a password.

Definition at line 702 of file sasl.c.

703{
704 int rc = SASL_OK;
705 char prompt[128] = { 0 };
706 struct Buffer *resp = buf_pool_get();
707
708 while (interaction->id != SASL_CB_LIST_END)
709 {
710 mutt_debug(LL_DEBUG2, "filling in SASL interaction %ld\n", interaction->id);
711
712 snprintf(prompt, sizeof(prompt), "%s: ", interaction->prompt);
713 buf_reset(resp);
714
715 if (OptNoCurses ||
716 (buf_get_field(prompt, resp, MUTT_COMP_NO_FLAGS, false, NULL, NULL, NULL) != 0))
717 {
718 rc = SASL_FAIL;
719 break;
720 }
721
722 interaction->len = buf_len(resp) + 1;
723 interaction->result = buf_strdup(resp);
724 interaction++;
725 }
726
727 buf_pool_release(&resp);
728 return rc;
729}
size_t buf_len(const struct Buffer *buf)
Calculate the length of a Buffer.
Definition: buffer.c:414
void buf_reset(struct Buffer *buf)
Reset an existing Buffer.
Definition: buffer.c:86
char * buf_strdup(const struct Buffer *buf)
Copy a Buffer's string.
Definition: buffer.c:490
int buf_get_field(const char *field, struct Buffer *buf, CompletionFlags complete, bool multiple, struct Mailbox *m, char ***files, int *numfiles)
Ask the user for a string.
Definition: window.c:180
bool OptNoCurses
(pseudo) when sending in batch mode
Definition: globals.c:82
#define MUTT_COMP_NO_FLAGS
No flags are set.
Definition: mutt.h:55
struct Buffer * buf_pool_get(void)
Get a Buffer from the pool.
Definition: pool.c:106
void buf_pool_release(struct Buffer **ptr)
Return a Buffer to the pool.
Definition: pool.c:119
String manipulation buffer.
Definition: buffer.h:34
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ mutt_sasl_setup_conn()

void mutt_sasl_setup_conn ( struct Connection conn,
sasl_conn_t *  saslconn 
)

Set up an SASL connection.

Parameters
connConnection to a server
saslconnSASL connection

Replace connection methods, sockdata with SASL wrappers, for protection layers. Also get ssf, as a fastpath for the read/write methods.

Definition at line 739 of file sasl.c.

740{
741 struct SaslSockData *sasldata = mutt_mem_malloc(sizeof(struct SaslSockData));
742 /* work around sasl_getprop aliasing issues */
743 const void *tmp = NULL;
744
745 sasldata->saslconn = saslconn;
746 /* get ssf so we know whether we have to (en|de)code read/write */
747 sasl_getprop(saslconn, SASL_SSF, &tmp);
748 sasldata->ssf = tmp;
749 mutt_debug(LL_DEBUG3, "SASL protection strength: %u\n", *sasldata->ssf);
750 /* Add SASL SSF to transport SSF */
751 conn->ssf += *sasldata->ssf;
752 sasl_getprop(saslconn, SASL_MAXOUTBUF, &tmp);
753 sasldata->pbufsize = tmp;
754 mutt_debug(LL_DEBUG3, "SASL protection buffer size: %u\n", *sasldata->pbufsize);
755
756 /* clear input buffer */
757 sasldata->buf = NULL;
758 sasldata->bpos = 0;
759 sasldata->blen = 0;
760
761 /* preserve old functions */
762 sasldata->sockdata = conn->sockdata;
763 sasldata->open = conn->open;
764 sasldata->read = conn->read;
765 sasldata->write = conn->write;
766 sasldata->poll = conn->poll;
767 sasldata->close = conn->close;
768
769 /* and set up new functions */
770 conn->sockdata = sasldata;
776}
static int mutt_sasl_conn_close(struct Connection *conn)
Close SASL connection - Implements Connection::close() -.
Definition: sasl.c:440
int(* close)(struct Connection *conn)
Close a socket Connection - Implements Connection::close() -.
Definition: sasl.c:97
int(* open)(struct Connection *conn)
Open a socket Connection - Implements Connection::open() -.
Definition: sasl.c:77
static int mutt_sasl_conn_open(struct Connection *conn)
Empty wrapper for underlying open function - Implements Connection::open() -.
Definition: sasl.c:424
int(* poll)(struct Connection *conn, time_t wait_secs)
Check whether a socket read would block - Implements Connection::poll() -.
Definition: sasl.c:92
static int mutt_sasl_conn_poll(struct Connection *conn, time_t wait_secs)
Check an SASL connection for data - Implements Connection::poll() -.
Definition: sasl.c:581
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:465
int(* read)(struct Connection *conn, char *buf, size_t count)
Read from a socket Connection - Implements Connection::read() -.
Definition: sasl.c:82
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:531
int(* write)(struct Connection *conn, const char *buf, size_t count)
Write to a socket Connection - Implements Connection::write() -.
Definition: sasl.c:87
@ LL_DEBUG3
Log at debug level 3.
Definition: logging2.h:42
void * mutt_mem_malloc(size_t size)
Allocate memory on the heap.
Definition: memory.c:90
void * sockdata
Backend-specific socket data.
Definition: connection.h:56
int(* poll)(struct Connection *conn, time_t wait_secs)
Definition: connection.h:106
int(* write)(struct Connection *conn, const char *buf, size_t count)
Definition: connection.h:93
int(* close)(struct Connection *conn)
Definition: connection.h:117
int(* open)(struct Connection *conn)
Definition: connection.h:67
int(* read)(struct Connection *conn, char *buf, size_t count)
Definition: connection.h:80
SASL authentication API -.
Definition: sasl.c:62
void * sockdata
Underlying socket data.
Definition: sasl.c:72
unsigned int blen
Size of the read buffer.
Definition: sasl.c:69
unsigned int bpos
Current read position.
Definition: sasl.c:70
const sasl_ssf_t * ssf
Definition: sasl.c:64
const unsigned int * pbufsize
Definition: sasl.c:65
const char * buf
Buffer for data read from the connection.
Definition: sasl.c:68
sasl_conn_t * saslconn
Definition: sasl.c:63
+ Here is the call graph for this function:
+ Here is the caller graph for this function: