]> granicus.if.org Git - mutt/commitdiff
Change auth_gss to to use buffers and the buffer pool.
authorKevin McCarthy <kevin@8t8.us>
Wed, 13 Feb 2019 00:41:07 +0000 (16:41 -0800)
committerKevin McCarthy <kevin@8t8.us>
Wed, 13 Feb 2019 03:01:16 +0000 (19:01 -0800)
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

index 772411a4ac1136f62ebf3ea25cadd03b95ac3149..6605b3daab4669d1e2f156b74f819437ad2420d7 100644 (file)
@@ -44,8 +44,6 @@
 #  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
@@ -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;
 }