NeoMutt  2023-03-22
Teaching an old dog new tricks
DOXYGEN
gsasl.c File Reference

GNU SASL authentication support. More...

#include "config.h"
#include <gsasl.h>
#include <stdbool.h>
#include "mutt/lib.h"
#include "connaccount.h"
#include "connection.h"
#include "gsasl2.h"
#include "mutt_account.h"
+ Include dependency graph for gsasl.c:

Go to the source code of this file.

Functions

static int mutt_gsasl_callback (Gsasl *ctx, Gsasl_session *sctx, Gsasl_property prop)
 Callback to retrieve authname or user from ConnAccount. More...
 
static bool mutt_gsasl_init (void)
 Initialise GNU SASL library. More...
 
void mutt_gsasl_done (void)
 Shutdown GNU SASL library. More...
 
const char * mutt_gsasl_get_mech (const char *requested_mech, const char *server_mechlist)
 Pick a connection mechanism. More...
 
int mutt_gsasl_client_new (struct Connection *conn, const char *mech, Gsasl_session **sctx)
 Create a new GNU SASL client. More...
 
void mutt_gsasl_client_finish (Gsasl_session **sctx)
 Free a GNU SASL client. More...
 

Variables

static Gsasl * mutt_gsasl_ctx = NULL
 

Detailed Description

GNU SASL authentication support.

Authors
  • Richard Russon

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 gsasl.c.

Function Documentation

◆ mutt_gsasl_callback()

static int mutt_gsasl_callback ( Gsasl *  ctx,
Gsasl_session *  sctx,
Gsasl_property  prop 
)
static

Callback to retrieve authname or user from ConnAccount.

Parameters
ctxGNU SASL context
sctxGNU SASL session
propProperty to get, e.g. GSASL_PASSWORD
Return values
numGNU SASL error code, e.g. GSASL_OK

Definition at line 47 of file gsasl.c.

48{
49 int rc = GSASL_NO_CALLBACK;
50
51 struct Connection *conn = gsasl_session_hook_get(sctx);
52 if (!conn)
53 {
54 mutt_debug(LL_DEBUG1, "missing session hook data!\n");
55 return rc;
56 }
57
58 switch (prop)
59 {
60 case GSASL_PASSWORD:
61 if (mutt_account_getpass(&conn->account))
62 return rc;
63 gsasl_property_set(sctx, GSASL_PASSWORD, conn->account.pass);
64 rc = GSASL_OK;
65 break;
66
67 case GSASL_AUTHID:
68 /* whom the provided password belongs to: login */
70 return rc;
71 gsasl_property_set(sctx, GSASL_AUTHID, conn->account.login);
72 rc = GSASL_OK;
73 break;
74
75 case GSASL_AUTHZID:
76 /* name of the user whose mail/resources you intend to access: user */
77 if (mutt_account_getuser(&conn->account))
78 return rc;
79 gsasl_property_set(sctx, GSASL_AUTHZID, conn->account.user);
80 rc = GSASL_OK;
81 break;
82
83 case GSASL_ANONYMOUS_TOKEN:
84 gsasl_property_set(sctx, GSASL_ANONYMOUS_TOKEN, "dummy");
85 rc = GSASL_OK;
86 break;
87
88 case GSASL_SERVICE:
89 {
90 const char *service = NULL;
91 switch (conn->account.type)
92 {
94 service = "imap";
95 break;
97 service = "pop";
98 break;
100 service = "smtp";
101 break;
102 default:
103 return rc;
104 }
105 gsasl_property_set(sctx, GSASL_SERVICE, service);
106 rc = GSASL_OK;
107 break;
108 }
109
110 case GSASL_HOSTNAME:
111 gsasl_property_set(sctx, GSASL_HOSTNAME, conn->account.host);
112 rc = GSASL_OK;
113 break;
114
115 default:
116 break;
117 }
118
119 return rc;
120}
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:49
int mutt_account_getlogin(struct ConnAccount *cac)
Retrieve login info into ConnAccount, if necessary.
Definition: connaccount.c:99
#define mutt_debug(LEVEL,...)
Definition: logging.h:84
@ LL_DEBUG1
Log at debug level 1.
Definition: logging.h:40
@ MUTT_ACCT_TYPE_SMTP
Smtp Account.
Definition: mutt_account.h:39
@ MUTT_ACCT_TYPE_POP
Pop Account.
Definition: mutt_account.h:38
@ MUTT_ACCT_TYPE_IMAP
Imap Account.
Definition: mutt_account.h:37
char login[128]
Login name.
Definition: connaccount.h:55
char user[128]
Username.
Definition: connaccount.h:56
char pass[256]
Password.
Definition: connaccount.h:57
char host[128]
Server to login to.
Definition: connaccount.h:54
unsigned char type
Connection type, e.g. MUTT_ACCT_TYPE_IMAP.
Definition: connaccount.h:59
struct ConnAccount account
Account details: username, password, etc.
Definition: connection.h:50
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ mutt_gsasl_init()

static bool mutt_gsasl_init ( void  )
static

Initialise GNU SASL library.

Return values
trueSuccess

Definition at line 126 of file gsasl.c.

127{
128 if (mutt_gsasl_ctx)
129 return true;
130
131 int rc = gsasl_init(&mutt_gsasl_ctx);
132 if (rc != GSASL_OK)
133 {
134 mutt_gsasl_ctx = NULL;
135 mutt_debug(LL_DEBUG1, "libgsasl initialisation failed (%d): %s.\n", rc,
136 gsasl_strerror(rc));
137 return false;
138 }
139
140 gsasl_callback_set(mutt_gsasl_ctx, mutt_gsasl_callback);
141 return true;
142}
static int mutt_gsasl_callback(Gsasl *ctx, Gsasl_session *sctx, Gsasl_property prop)
Callback to retrieve authname or user from ConnAccount.
Definition: gsasl.c:47
static Gsasl * mutt_gsasl_ctx
Definition: gsasl.c:38
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ mutt_gsasl_done()

void mutt_gsasl_done ( void  )

Shutdown GNU SASL library.

Definition at line 147 of file gsasl.c.

148{
149 if (!mutt_gsasl_ctx)
150 return;
151
152 gsasl_done(mutt_gsasl_ctx);
153 mutt_gsasl_ctx = NULL;
154}
+ Here is the caller graph for this function:

◆ mutt_gsasl_get_mech()

const char * mutt_gsasl_get_mech ( const char *  requested_mech,
const char *  server_mechlist 
)

Pick a connection mechanism.

Parameters
requested_mechRequested mechanism
server_mechlistServer's list of mechanisms
Return values
ptrSelected mechanism string

Definition at line 162 of file gsasl.c.

163{
164 if (!mutt_gsasl_init())
165 return NULL;
166
167 /* libgsasl does not do case-independent string comparisons,
168 * and stores its methods internally in uppercase. */
169 char *uc_server_mechlist = mutt_str_dup(server_mechlist);
170 if (uc_server_mechlist)
171 mutt_str_upper(uc_server_mechlist);
172
173 char *uc_requested_mech = mutt_str_dup(requested_mech);
174 if (uc_requested_mech)
175 mutt_str_upper(uc_requested_mech);
176
177 const char *sel_mech = NULL;
178 if (uc_requested_mech)
179 sel_mech = gsasl_client_suggest_mechanism(mutt_gsasl_ctx, uc_requested_mech);
180 else
181 sel_mech = gsasl_client_suggest_mechanism(mutt_gsasl_ctx, uc_server_mechlist);
182
183 FREE(&uc_requested_mech);
184 FREE(&uc_server_mechlist);
185
186 return sel_mech;
187}
static bool mutt_gsasl_init(void)
Initialise GNU SASL library.
Definition: gsasl.c:126
#define FREE(x)
Definition: memory.h:43
char * mutt_str_dup(const char *str)
Copy a string, safely.
Definition: string.c:250
char * mutt_str_upper(char *str)
Convert all characters in the string to uppercase.
Definition: string.c:407
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ mutt_gsasl_client_new()

int mutt_gsasl_client_new ( struct Connection conn,
const char *  mech,
Gsasl_session **  sctx 
)

Create a new GNU SASL client.

Parameters
connConnection to a server
mechMechanisms to use
sctxGNU SASL Session
Return values
0Success
-1Error

Definition at line 197 of file gsasl.c.

198{
199 if (!mutt_gsasl_init())
200 return -1;
201
202 int rc = gsasl_client_start(mutt_gsasl_ctx, mech, sctx);
203 if (rc != GSASL_OK)
204 {
205 *sctx = NULL;
206 mutt_debug(LL_DEBUG1, "gsasl_client_start failed (%d): %s.\n", rc, gsasl_strerror(rc));
207 return -1;
208 }
209
210 gsasl_session_hook_set(*sctx, conn);
211 return 0;
212}
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ mutt_gsasl_client_finish()

void mutt_gsasl_client_finish ( Gsasl_session **  sctx)

Free a GNU SASL client.

Parameters
sctxGNU SASL Session

Definition at line 218 of file gsasl.c.

219{
220 gsasl_finish(*sctx);
221 *sctx = NULL;
222}
+ Here is the caller graph for this function:

Variable Documentation

◆ mutt_gsasl_ctx

Gsasl* mutt_gsasl_ctx = NULL
static

Definition at line 38 of file gsasl.c.