#include <gssapi/gssapi_generic.h>
#endif
-#define GSS_BUFSIZE 8192
-
#define GSS_AUTH_P_NONE 1
#define GSS_AUTH_P_INTEGRITY 2
#define GSS_AUTH_P_PRIVACY 4
gss_qop_t quality;
int cflags;
OM_uint32 maj_stat, min_stat;
- char buf1[GSS_BUFSIZE], buf2[GSS_BUFSIZE];
unsigned long buf_size;
- int rc;
+ int rc, retval = IMAP_AUTH_FAILURE;
if (!(adata->capabilities & IMAP_CAP_AGSSAPI))
return IMAP_AUTH_UNAVAIL;
if (mutt_account_getuser(&adata->conn->account) < 0)
return IMAP_AUTH_FAILURE;
+ struct Buffer *buf1 = mutt_buffer_pool_get();
+ struct Buffer *buf2 = mutt_buffer_pool_get();
+
/* get an IMAP service ticket for the server */
- snprintf(buf1, sizeof(buf1), "imap@%s", adata->conn->account.host);
- request_buf.value = buf1;
- request_buf.length = strlen(buf1);
+ mutt_buffer_printf(buf1, "imap@%s", adata->conn->account.host);
+ request_buf.value = buf1->data;
+ request_buf.length = mutt_buffer_len(buf1);
+
maj_stat = gss_import_name(&min_stat, &request_buf, gss_nt_service_name, &target_name);
if (maj_stat != GSS_S_COMPLETE)
{
mutt_debug(2, "Couldn't get service name for [%s]\n", buf1);
- return IMAP_AUTH_UNAVAIL;
+ retval = IMAP_AUTH_UNAVAIL;
+ goto cleanup;
}
else if (DebugLevel >= 2)
{
mutt_debug(1, "Error acquiring credentials - no TGT?\n");
gss_release_name(&min_stat, &target_name);
- return IMAP_AUTH_UNAVAIL;
+ retval = IMAP_AUTH_UNAVAIL;
+ goto cleanup;
}
/* now begin login */
/* now start the security context initialisation loop... */
mutt_debug(2, "Sending credentials\n");
- mutt_b64_encode(send_token.value, send_token.length, buf1, sizeof(buf1) - 2);
+ mutt_b64_buffer_encode(buf1, send_token.value, send_token.length);
gss_release_buffer(&min_stat, &send_token);
- mutt_str_strcat(buf1, sizeof(buf1), "\r\n");
- mutt_socket_send(adata->conn, buf1);
+ mutt_buffer_addstr(buf1, "\r\n");
+ mutt_socket_send(adata->conn, mutt_b2s(buf1));
while (maj_stat == GSS_S_CONTINUE_NEEDED)
{
goto bail;
}
- request_buf.length = mutt_b64_decode(adata->buf + 2, buf2, sizeof(buf2));
- request_buf.value = buf2;
+ request_buf.length = mutt_b64_buffer_decode(buf2, adata->buf + 2);
+ request_buf.value = buf2->data;
sec_token = &request_buf;
/* Write client data */
goto err_abort_cmd;
}
- mutt_b64_encode(send_token.value, send_token.length, buf1, sizeof(buf1) - 2);
+ mutt_b64_buffer_encode(buf1, send_token.value, send_token.length);
gss_release_buffer(&min_stat, &send_token);
- mutt_str_strcat(buf1, sizeof(buf1), "\r\n");
- mutt_socket_send(adata->conn, buf1);
+ mutt_buffer_addstr(buf1, "\r\n");
+ mutt_socket_send(adata->conn, mutt_b2s(buf1));
}
gss_release_name(&min_stat, &target_name);
mutt_debug(1, "#2 Error receiving server response.\n");
goto bail;
}
- request_buf.length = mutt_b64_decode(adata->buf + 2, buf2, sizeof(buf2));
- request_buf.value = buf2;
+ request_buf.length = mutt_b64_buffer_decode(buf2, adata->buf + 2);
+ request_buf.value = buf2->data;
maj_stat = gss_unwrap(&min_stat, context, &request_buf, &send_token, &cflags, &quality);
if (maj_stat != GSS_S_COMPLETE)
/* agree to terms (hack!) */
buf_size = htonl(buf_size); /* not relevant without integrity/privacy */
- memcpy(buf1, &buf_size, 4);
- buf1[0] = GSS_AUTH_P_NONE;
+ mutt_buffer_reset(buf1);
+ mutt_buffer_addch(buf1, GSS_AUTH_P_NONE);
+ mutt_buffer_addstr_n(buf1, ((char *) &buf_size) + 1, 3);
/* server decides if principal can log in as user */
- strncpy(buf1 + 4, adata->conn->account.user, sizeof(buf1) - 4);
- request_buf.value = buf1;
- request_buf.length = 4 + strlen(adata->conn->account.user);
+ mutt_buffer_addstr(buf1, adata->conn->account.user);
+ request_buf.value = buf1->data;
+ request_buf.length = mutt_buffer_len(buf1);
maj_stat = gss_wrap(&min_stat, context, 0, GSS_C_QOP_DEFAULT, &request_buf,
&cflags, &send_token);
if (maj_stat != GSS_S_COMPLETE)
goto err_abort_cmd;
}
- mutt_b64_encode(send_token.value, send_token.length, buf1, sizeof(buf1) - 2);
+ mutt_b64_buffer_encode(buf1, send_token.value, send_token.length);
mutt_debug(2, "Requesting authorisation as %s\n", adata->conn->account.user);
- mutt_str_strcat(buf1, sizeof(buf1), "\r\n");
- mutt_socket_send(adata->conn, buf1);
+ mutt_buffer_addstr(buf1, "\r\n");
+ mutt_socket_send(adata->conn, mutt_b2s(buf1));
/* Joy of victory or agony of defeat? */
do
* enough to flush its own credentials */
gss_release_buffer(&min_stat, &send_token);
- return IMAP_AUTH_SUCCESS;
+ retval = IMAP_AUTH_SUCCESS;
+ goto cleanup;
}
else
goto bail;
bail:
mutt_error(_("GSSAPI authentication failed"));
- return IMAP_AUTH_FAILURE;
+ retval = IMAP_AUTH_FAILURE;
+
+cleanup:
+ mutt_buffer_pool_release(&buf1);
+ mutt_buffer_pool_release(&buf2);
+
+ return retval;
}