NeoMutt  2024-12-12-14-g7b49f7
Teaching an old dog new tricks
DOXYGEN
Loading...
Searching...
No Matches
gsasl.c
Go to the documentation of this file.
1
29#include "config.h"
30#include <gsasl.h>
31#include <stdbool.h>
32#include <stddef.h>
33#include "mutt/lib.h"
34#include "connaccount.h"
35#include "connection.h"
36#include "gsasl2.h"
37#include "mutt_account.h"
38
40static Gsasl *MuttGsaslCtx = NULL;
41
49static int mutt_gsasl_callback(Gsasl *ctx, Gsasl_session *sctx, Gsasl_property prop)
50{
51 int rc = GSASL_NO_CALLBACK;
52
53 struct Connection *conn = gsasl_session_hook_get(sctx);
54 if (!conn)
55 {
56 mutt_debug(LL_DEBUG1, "missing session hook data!\n");
57 return rc;
58 }
59
60 switch (prop)
61 {
62 case GSASL_PASSWORD:
63 if (mutt_account_getpass(&conn->account))
64 return rc;
65 gsasl_property_set(sctx, GSASL_PASSWORD, conn->account.pass);
66 rc = GSASL_OK;
67 break;
68
69 case GSASL_AUTHID:
70 /* whom the provided password belongs to: login */
72 return rc;
73 gsasl_property_set(sctx, GSASL_AUTHID, conn->account.login);
74 rc = GSASL_OK;
75 break;
76
77 case GSASL_AUTHZID:
78 /* name of the user whose mail/resources you intend to access: user */
79 if (mutt_account_getuser(&conn->account))
80 return rc;
81 gsasl_property_set(sctx, GSASL_AUTHZID, conn->account.user);
82 rc = GSASL_OK;
83 break;
84
85 case GSASL_ANONYMOUS_TOKEN:
86 gsasl_property_set(sctx, GSASL_ANONYMOUS_TOKEN, "dummy");
87 rc = GSASL_OK;
88 break;
89
90 case GSASL_SERVICE:
91 {
92 const char *service = NULL;
93 switch (conn->account.type)
94 {
96 service = "imap";
97 break;
99 service = "pop";
100 break;
102 service = "smtp";
103 break;
104 default:
105 return rc;
106 }
107 gsasl_property_set(sctx, GSASL_SERVICE, service);
108 rc = GSASL_OK;
109 break;
110 }
111
112 case GSASL_HOSTNAME:
113 gsasl_property_set(sctx, GSASL_HOSTNAME, conn->account.host);
114 rc = GSASL_OK;
115 break;
116
117 default:
118 break;
119 }
120
121 return rc;
122}
123
128static bool mutt_gsasl_init(void)
129{
130 if (MuttGsaslCtx)
131 return true;
132
133 int rc = gsasl_init(&MuttGsaslCtx);
134 if (rc != GSASL_OK)
135 {
136 MuttGsaslCtx = NULL;
137 mutt_debug(LL_DEBUG1, "libgsasl initialisation failed (%d): %s\n", rc,
138 gsasl_strerror(rc));
139 return false;
140 }
141
142 gsasl_callback_set(MuttGsaslCtx, mutt_gsasl_callback);
143 return true;
144}
145
150{
151 if (!MuttGsaslCtx)
152 return;
153
154 gsasl_done(MuttGsaslCtx);
155 MuttGsaslCtx = NULL;
156}
157
164const char *mutt_gsasl_get_mech(const char *requested_mech, const char *server_mechlist)
165{
166 if (!mutt_gsasl_init())
167 return NULL;
168
169 /* libgsasl does not do case-independent string comparisons,
170 * and stores its methods internally in uppercase. */
171 char *uc_server_mechlist = mutt_str_dup(server_mechlist);
172 if (uc_server_mechlist)
173 mutt_str_upper(uc_server_mechlist);
174
175 char *uc_requested_mech = mutt_str_dup(requested_mech);
176 if (uc_requested_mech)
177 mutt_str_upper(uc_requested_mech);
178
179 const char *sel_mech = NULL;
180 if (uc_requested_mech)
181 sel_mech = gsasl_client_suggest_mechanism(MuttGsaslCtx, uc_requested_mech);
182 else
183 sel_mech = gsasl_client_suggest_mechanism(MuttGsaslCtx, uc_server_mechlist);
184
185 FREE(&uc_requested_mech);
186 FREE(&uc_server_mechlist);
187
188 return sel_mech;
189}
190
199int mutt_gsasl_client_new(struct Connection *conn, const char *mech, Gsasl_session **sctx)
200{
201 if (!mutt_gsasl_init())
202 return -1;
203
204 int rc = gsasl_client_start(MuttGsaslCtx, mech, sctx);
205 if (rc != GSASL_OK)
206 {
207 *sctx = NULL;
208 mutt_debug(LL_DEBUG1, "gsasl_client_start failed (%d): %s\n", rc, gsasl_strerror(rc));
209 return -1;
210 }
211
212 gsasl_session_hook_set(*sctx, conn);
213 return 0;
214}
215
220void mutt_gsasl_client_finish(Gsasl_session **sctx)
221{
222 gsasl_finish(*sctx);
223 *sctx = NULL;
224}
int mutt_account_getpass(struct ConnAccount *cac)
Fetch password into ConnAccount, if necessary.
Definition: connaccount.c:130
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.
Definition: connaccount.c:100
Connection Credentials.
An open network connection (socket)
#define mutt_debug(LEVEL,...)
Definition: logging2.h:89
GNU SASL authentication support.
static int mutt_gsasl_callback(Gsasl *ctx, Gsasl_session *sctx, Gsasl_property prop)
Callback to retrieve authname or user from ConnAccount.
Definition: gsasl.c:49
static Gsasl * MuttGsaslCtx
Global GNU SASL handle.
Definition: gsasl.c:40
const char * mutt_gsasl_get_mech(const char *requested_mech, const char *server_mechlist)
Pick a connection mechanism.
Definition: gsasl.c:164
int mutt_gsasl_client_new(struct Connection *conn, const char *mech, Gsasl_session **sctx)
Create a new GNU SASL client.
Definition: gsasl.c:199
void mutt_gsasl_cleanup(void)
Shutdown GNU SASL library.
Definition: gsasl.c:149
void mutt_gsasl_client_finish(Gsasl_session **sctx)
Free a GNU SASL client.
Definition: gsasl.c:220
static bool mutt_gsasl_init(void)
Initialise GNU SASL library.
Definition: gsasl.c:128
@ LL_DEBUG1
Log at debug level 1.
Definition: logging2.h:43
#define FREE(x)
Definition: memory.h:55
Convenience wrapper for the library headers.
char * mutt_str_dup(const char *str)
Copy a string, safely.
Definition: string.c:253
char * mutt_str_upper(char *str)
Convert all characters in the string to uppercase.
Definition: string.c:336
ConnAccount object used by POP and IMAP.
@ MUTT_ACCT_TYPE_SMTP
Smtp Account.
Definition: mutt_account.h:38
@ MUTT_ACCT_TYPE_POP
Pop Account.
Definition: mutt_account.h:37
@ MUTT_ACCT_TYPE_IMAP
Imap Account.
Definition: mutt_account.h:36
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:49