NeoMutt  2024-12-12-14-g7b49f7
Teaching an old dog new tricks
DOXYGEN
Loading...
Searching...
No Matches
auth_gsasl.c
Go to the documentation of this file.
1
29#include "config.h"
30#include <gsasl.h>
31#include <stddef.h>
32#include "private.h"
33#include "mutt/lib.h"
34#include "conn/lib.h"
35#include "adata.h"
36#include "auth.h"
37
41enum ImapAuthRes imap_auth_gsasl(struct ImapAccountData *adata, const char *method)
42{
43 Gsasl_session *gsasl_session = NULL;
44 struct Buffer *output_buf = NULL;
45 char *imap_step_output = NULL;
46 int rc = IMAP_AUTH_FAILURE;
47 int gsasl_rc = GSASL_OK;
48 int imap_step_rc = IMAP_RES_CONTINUE;
49
50 const char *chosen_mech = mutt_gsasl_get_mech(method, adata->capstr);
51 if (!chosen_mech)
52 {
53 mutt_debug(LL_DEBUG2, "mutt_gsasl_get_mech() returned no usable mech\n");
54 return IMAP_AUTH_UNAVAIL;
55 }
56
57 mutt_debug(LL_DEBUG2, "using mech %s\n", chosen_mech);
58
59 if (mutt_gsasl_client_new(adata->conn, chosen_mech, &gsasl_session) < 0)
60 {
61 mutt_debug(LL_DEBUG1, "Error allocating GSASL connection\n");
62 return IMAP_AUTH_UNAVAIL;
63 }
64
65 mutt_message(_("Authenticating (%s)..."), chosen_mech);
66
67 output_buf = buf_pool_get();
68 buf_printf(output_buf, "AUTHENTICATE %s", chosen_mech);
69 if (adata->capabilities & IMAP_CAP_SASL_IR)
70 {
71 char *gsasl_step_output = NULL;
72 gsasl_rc = gsasl_step64(gsasl_session, "", &gsasl_step_output);
73 if ((gsasl_rc != GSASL_NEEDS_MORE) && (gsasl_rc != GSASL_OK))
74 {
75 mutt_debug(LL_DEBUG1, "gsasl_step64() failed (%d): %s\n", gsasl_rc,
76 gsasl_strerror(gsasl_rc));
78 goto bail;
79 }
80
81 buf_addch(output_buf, ' ');
82 buf_addstr(output_buf, gsasl_step_output);
83 gsasl_free(gsasl_step_output);
84 }
85 imap_cmd_start(adata, buf_string(output_buf));
86
87 do
88 {
89 do
90 {
91 imap_step_rc = imap_cmd_step(adata);
92 } while (imap_step_rc == IMAP_RES_CONTINUE);
93
94 if ((imap_step_rc == IMAP_RES_BAD) || (imap_step_rc == IMAP_RES_NO))
95 goto bail;
96
97 if (imap_step_rc != IMAP_RES_RESPOND)
98 break;
99
100 imap_step_output = imap_next_word(adata->buf);
101
102 char *gsasl_step_output = NULL;
103 gsasl_rc = gsasl_step64(gsasl_session, imap_step_output, &gsasl_step_output);
104 if ((gsasl_rc == GSASL_NEEDS_MORE) || (gsasl_rc == GSASL_OK))
105 {
106 buf_strcpy(output_buf, gsasl_step_output);
107 gsasl_free(gsasl_step_output);
108 }
109 else
110 {
111 // sasl error occurred, send an abort string
112 mutt_debug(LL_DEBUG1, "gsasl_step64() failed (%d): %s\n", gsasl_rc,
113 gsasl_strerror(gsasl_rc));
114 buf_strcpy(output_buf, "*");
115 }
116
117 buf_addstr(output_buf, "\r\n");
118 mutt_socket_send(adata->conn, buf_string(output_buf));
119 } while ((gsasl_rc == GSASL_NEEDS_MORE) || (gsasl_rc == GSASL_OK));
120
121 if (imap_step_rc != IMAP_RES_OK)
122 {
123 do
124 imap_step_rc = imap_cmd_step(adata);
125 while (imap_step_rc == IMAP_RES_CONTINUE);
126 }
127
128 if (imap_step_rc == IMAP_RES_RESPOND)
129 {
130 mutt_socket_send(adata->conn, "*\r\n");
131 goto bail;
132 }
133
134 if ((gsasl_rc != GSASL_OK) || (imap_step_rc != IMAP_RES_OK))
135 goto bail;
136
137 if (imap_code(adata->buf))
139
140bail:
141 buf_pool_release(&output_buf);
142 mutt_gsasl_client_finish(&gsasl_session);
143
144 if (rc == IMAP_AUTH_FAILURE)
145 {
146 mutt_debug(LL_DEBUG2, "%s failed\n", chosen_mech);
147 mutt_error(_("SASL authentication failed"));
148 }
149
150 return rc;
151}
IMAP authenticator multiplexor.
ImapAuthRes
Results of IMAP Authentication.
Definition: auth.h:39
@ IMAP_AUTH_FAILURE
Authentication failed.
Definition: auth.h:41
@ IMAP_AUTH_SUCCESS
Authentication successful.
Definition: auth.h:40
@ IMAP_AUTH_UNAVAIL
Authentication method not permitted.
Definition: auth.h:42
int buf_printf(struct Buffer *buf, const char *fmt,...)
Format a string overwriting a Buffer.
Definition: buffer.c:161
size_t buf_addch(struct Buffer *buf, char c)
Add a single character to a Buffer.
Definition: buffer.c:241
size_t buf_addstr(struct Buffer *buf, const char *s)
Add a string to a Buffer.
Definition: buffer.c:226
size_t buf_strcpy(struct Buffer *buf, const char *s)
Copy a string into a Buffer.
Definition: buffer.c:395
static const char * buf_string(const struct Buffer *buf)
Convert a buffer to a const char * "string".
Definition: buffer.h:96
Connection Library.
enum ImapAuthRes imap_auth_gsasl(struct ImapAccountData *adata, const char *method)
GNU SASL authenticator - Implements ImapAuth::authenticate() -.
Definition: auth_gsasl.c:41
#define mutt_error(...)
Definition: logging2.h:92
#define mutt_message(...)
Definition: logging2.h:91
#define mutt_debug(LEVEL,...)
Definition: logging2.h:89
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_client_finish(Gsasl_session **sctx)
Free a GNU SASL client.
Definition: gsasl.c:220
int imap_cmd_start(struct ImapAccountData *adata, const char *cmdstr)
Given an IMAP command, send it to the server.
Definition: command.c:1114
int imap_cmd_step(struct ImapAccountData *adata)
Reads server responses from an IMAP command.
Definition: command.c:1128
bool imap_code(const char *s)
Was the command successful.
Definition: command.c:1255
#define IMAP_RES_RESPOND
+
Definition: private.h:57
#define IMAP_RES_OK
<tag> OK ...
Definition: private.h:55
#define IMAP_RES_NO
<tag> NO ...
Definition: private.h:53
#define IMAP_CAP_SASL_IR
SASL initial response draft.
Definition: private.h:134
#define IMAP_RES_CONTINUE
* ...
Definition: private.h:56
char * imap_next_word(char *s)
Find where the next IMAP word begins.
Definition: util.c:824
#define IMAP_RES_BAD
<tag> BAD ...
Definition: private.h:54
@ LL_DEBUG2
Log at debug level 2.
Definition: logging2.h:44
@ LL_DEBUG1
Log at debug level 1.
Definition: logging2.h:43
Convenience wrapper for the library headers.
#define _(a)
Definition: message.h:28
struct Buffer * buf_pool_get(void)
Get a Buffer from the pool.
Definition: pool.c:82
void buf_pool_release(struct Buffer **ptr)
Return a Buffer to the pool.
Definition: pool.c:96
Pop-specific Account data.
GUI display the mailboxes in a side panel.
#define mutt_socket_send(conn, buf)
Definition: socket.h:57
String manipulation buffer.
Definition: buffer.h:36
IMAP-specific Account data -.
Definition: adata.h:40
ImapCapFlags capabilities
Capability flags.
Definition: adata.h:55
char * capstr
Capability string from the server.
Definition: adata.h:54
char * buf
Definition: adata.h:59
struct Connection * conn
Connection to IMAP server.
Definition: adata.h:41