From 3dd3eee40fe1f4e3a2e7ae6e10826462ef32c4a6 Mon Sep 17 00:00:00 2001 From: Kevin McCarthy Date: Tue, 12 Feb 2019 16:41:07 -0800 Subject: [PATCH] Change auth_gss to to use buffers and the buffer pool. Ticket #100 revealed that even a bufsize of 8192 isn't guaranteed to be big enough. Convert those large buffers to use the buffer pool instead. --- imap/auth_gss.c | 72 +++++++++++++++++++++++++++---------------------- 1 file changed, 40 insertions(+), 32 deletions(-) diff --git a/imap/auth_gss.c b/imap/auth_gss.c index 772411a4..6605b3da 100644 --- a/imap/auth_gss.c +++ b/imap/auth_gss.c @@ -44,8 +44,6 @@ # include #endif -#define GSS_BUFSIZE 8192 - #define GSS_AUTH_P_NONE 1 #define GSS_AUTH_P_INTEGRITY 2 #define GSS_AUTH_P_PRIVACY 4 @@ -109,9 +107,9 @@ imap_auth_res_t imap_auth_gss (IMAP_DATA* idata, const char* method) gss_qop_t quality; int cflags; OM_uint32 maj_stat, min_stat; - char buf1[GSS_BUFSIZE], buf2[GSS_BUFSIZE]; + BUFFER *buf1 = NULL, *buf2 = NULL; unsigned long buf_size; - int rc; + int rc, retval = IMAP_AUTH_FAILURE; if (!mutt_bit_isset (idata->capabilities, AGSSAPI)) return IMAP_AUTH_UNAVAIL; @@ -119,16 +117,20 @@ imap_auth_res_t imap_auth_gss (IMAP_DATA* idata, const char* method) if (mutt_account_getuser (&idata->conn->account)) return IMAP_AUTH_FAILURE; + buf1 = mutt_buffer_pool_get (); + buf2 = mutt_buffer_pool_get (); + /* get an IMAP service ticket for the server */ - snprintf (buf1, sizeof (buf1), "imap@%s", idata->conn->account.host); - request_buf.value = buf1; - request_buf.length = strlen (buf1); + mutt_buffer_printf (buf1, "imap@%s", idata->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) { dprint (2, (debugfile, "Couldn't get service name for [%s]\n", buf1)); - return IMAP_AUTH_UNAVAIL; + retval = IMAP_AUTH_UNAVAIL; + goto cleanup; } #ifdef DEBUG else if (debuglevel >= 2) @@ -155,7 +157,8 @@ imap_auth_res_t imap_auth_gss (IMAP_DATA* idata, const char* method) dprint (1, (debugfile, "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 */ @@ -177,11 +180,10 @@ imap_auth_res_t imap_auth_gss (IMAP_DATA* idata, const char* method) /* now start the security context initialisation loop... */ dprint (2, (debugfile, "Sending credentials\n")); - mutt_to_base64 ((unsigned char*) buf1, send_token.value, send_token.length, - sizeof (buf1) - 2); + mutt_buffer_to_base64 (buf1, send_token.value, send_token.length); gss_release_buffer (&min_stat, &send_token); - safe_strcat (buf1, sizeof (buf1), "\r\n"); - mutt_socket_write (idata->conn, buf1); + mutt_buffer_addstr (buf1, "\r\n"); + mutt_socket_write (idata->conn, mutt_b2s (buf1)); while (maj_stat == GSS_S_CONTINUE_NEEDED) { @@ -197,8 +199,8 @@ imap_auth_res_t imap_auth_gss (IMAP_DATA* idata, const char* method) goto bail; } - request_buf.length = mutt_from_base64 (buf2, idata->buf + 2, sizeof(buf2)); - request_buf.value = buf2; + request_buf.length = mutt_buffer_from_base64 (buf2, idata->buf + 2); + request_buf.value = buf2->data; sec_token = &request_buf; /* Write client data */ @@ -214,11 +216,10 @@ imap_auth_res_t imap_auth_gss (IMAP_DATA* idata, const char* method) goto err_abort_cmd; } - mutt_to_base64 ((unsigned char*) buf1, send_token.value, - send_token.length, sizeof (buf1) - 2); + mutt_buffer_to_base64 (buf1, send_token.value, send_token.length); gss_release_buffer (&min_stat, &send_token); - safe_strcat (buf1, sizeof (buf1), "\r\n"); - mutt_socket_write (idata->conn, buf1); + mutt_buffer_addstr (buf1, "\r\n"); + mutt_socket_write (idata->conn, mutt_b2s (buf1)); } gss_release_name (&min_stat, &target_name); @@ -233,8 +234,8 @@ imap_auth_res_t imap_auth_gss (IMAP_DATA* idata, const char* method) dprint (1, (debugfile, "Error receiving server response.\n")); goto bail; } - request_buf.length = mutt_from_base64 (buf2, idata->buf + 2, sizeof(buf2)); - request_buf.value = buf2; + request_buf.length = mutt_buffer_from_base64 (buf2, idata->buf + 2); + request_buf.value = buf2->data; maj_stat = gss_unwrap (&min_stat, context, &request_buf, &send_token, &cflags, &quality); @@ -270,12 +271,13 @@ imap_auth_res_t imap_auth_gss (IMAP_DATA* idata, const char* method) /* 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_clear (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, idata->conn->account.user, sizeof (buf1) - 4); - request_buf.value = buf1; - request_buf.length = 4 + strlen (idata->conn->account.user); + mutt_buffer_addstr (buf1, idata->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) @@ -284,12 +286,11 @@ imap_auth_res_t imap_auth_gss (IMAP_DATA* idata, const char* method) goto err_abort_cmd; } - mutt_to_base64 ((unsigned char*) buf1, send_token.value, send_token.length, - sizeof (buf1) - 2); + mutt_buffer_to_base64 (buf1, send_token.value, send_token.length); dprint (2, (debugfile, "Requesting authorisation as %s\n", idata->conn->account.user)); - safe_strcat (buf1, sizeof (buf1), "\r\n"); - mutt_socket_write (idata->conn, buf1); + mutt_buffer_addstr (buf1, "\r\n"); + mutt_socket_write (idata->conn, mutt_b2s (buf1)); /* Joy of victory or agony of defeat? */ do @@ -314,7 +315,8 @@ imap_auth_res_t imap_auth_gss (IMAP_DATA* idata, const char* method) * 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; @@ -328,5 +330,11 @@ err_abort_cmd: bail: mutt_error _("GSSAPI authentication failed."); mutt_sleep (2); - return IMAP_AUTH_FAILURE; + retval = IMAP_AUTH_FAILURE; + +cleanup: + mutt_buffer_pool_release (&buf1); + mutt_buffer_pool_release (&buf2); + + return retval; } -- 2.40.0