evolution-data-server r10161 - trunk/camel
- From: mbarnes svn gnome org
- To: svn-commits-list gnome org
- Subject: evolution-data-server r10161 - trunk/camel
- Date: Thu, 12 Mar 2009 18:00:07 +0000 (UTC)
Author: mbarnes
Date: Thu Mar 12 18:00:06 2009
New Revision: 10161
URL: http://svn.gnome.org/viewvc/evolution-data-server?rev=10161&view=rev
Log:
2009-03-12 Matthew Barnes <mbarnes redhat com>
* camel/camel-sasl-ntlm.c (ntlm_challenge):
CVE-2009-0852: Add stricter checking of NTLM authentication
challenges, and extract the domain length value properly.
Modified:
trunk/camel/ChangeLog
trunk/camel/camel-sasl-ntlm.c
Modified: trunk/camel/camel-sasl-ntlm.c
==============================================================================
--- trunk/camel/camel-sasl-ntlm.c (original)
+++ trunk/camel/camel-sasl-ntlm.c Thu Mar 12 18:00:06 2009
@@ -74,9 +74,8 @@
#define NTLM_REQUEST "NTLMSSP\x00\x01\x00\x00\x00\x06\x82\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x30\x00\x00\x00\x00\x00\x00\x00\x30\x00\x00\x00"
-#define NTLM_CHALLENGE_NONCE_OFFSET 24
-#define NTLM_CHALLENGE_DOMAIN_OFFSET 48
-#define NTLM_CHALLENGE_DOMAIN_LEN_OFFSET 44
+#define NTLM_CHALLENGE_DOMAIN_OFFSET 12
+#define NTLM_CHALLENGE_NONCE_OFFSET 24
#define NTLM_RESPONSE_HEADER "NTLMSSP\x00\x03\x00\x00\x00"
#define NTLM_RESPONSE_FLAGS "\x82\x01"
@@ -93,22 +92,60 @@
guchar results[24]);
static void ntlm_lanmanager_hash (const char *password, char hash[21]);
static void ntlm_nt_hash (const char *password, char hash[21]);
-static void ntlm_set_string (GByteArray *ba, int offset,
- const char *data, int len);
+
+typedef struct {
+ guint16 length;
+ guint16 allocated;
+ guint32 offset;
+} SecurityBuffer;
+
+static GString *
+ntlm_get_string (GByteArray *ba, int offset)
+{
+ SecurityBuffer *secbuf;
+ GString *string;
+ gchar *buf_string;
+ guint16 buf_length;
+ guint32 buf_offset;
+
+ secbuf = (SecurityBuffer *) &ba->data[offset];
+ buf_length = GUINT16_FROM_LE (secbuf->length);
+ buf_offset = GUINT32_FROM_LE (secbuf->offset);
+
+ if (ba->len < buf_offset + buf_length)
+ return NULL;
+
+ string = g_string_sized_new (buf_length);
+ buf_string = (gchar *) &ba->data[buf_offset];
+ g_string_append_len (string, buf_string, buf_length);
+
+ return string;
+}
+
+static void
+ntlm_set_string (GByteArray *ba, int offset, const char *data, int len)
+{
+ SecurityBuffer *secbuf;
+
+ secbuf = (SecurityBuffer *) &ba->data[offset];
+ secbuf->length = GUINT16_TO_LE (len);
+ secbuf->offset = GUINT32_TO_LE (ba->len);
+ secbuf->allocated = secbuf->length;
+
+ g_byte_array_append (ba, (guint8 *) data, len);
+}
static GByteArray *
ntlm_challenge (CamelSasl *sasl, GByteArray *token, CamelException *ex)
{
GByteArray *ret;
guchar nonce[8], hash[21], lm_resp[24], nt_resp[24];
+ GString *domain;
ret = g_byte_array_new ();
- if (!token || !token->len) {
- g_byte_array_append (ret, (guint8 *) NTLM_REQUEST,
- sizeof (NTLM_REQUEST) - 1);
- return ret;
- }
+ if (!token || token->len < NTLM_CHALLENGE_NONCE_OFFSET + 8)
+ goto fail;
memcpy (nonce, token->data + NTLM_CHALLENGE_NONCE_OFFSET, 8);
ntlm_lanmanager_hash (sasl->service->url->passwd, (char *) hash);
@@ -116,7 +153,11 @@
ntlm_nt_hash (sasl->service->url->passwd, (char *) hash);
ntlm_calc_response (hash, nonce, nt_resp);
- ret = g_byte_array_new ();
+ domain = ntlm_get_string (token, NTLM_CHALLENGE_DOMAIN_OFFSET);
+ if (domain == NULL)
+ goto fail;
+
+ /* Don't jump to 'fail' label after this point. */
g_byte_array_set_size (ret, NTLM_RESPONSE_BASE_SIZE);
memset (ret->data, 0, NTLM_RESPONSE_BASE_SIZE);
memcpy (ret->data, NTLM_RESPONSE_HEADER,
@@ -125,8 +166,7 @@
NTLM_RESPONSE_FLAGS, sizeof (NTLM_RESPONSE_FLAGS) - 1);
ntlm_set_string (ret, NTLM_RESPONSE_DOMAIN_OFFSET,
- (const char *) token->data + NTLM_CHALLENGE_DOMAIN_OFFSET,
- atoi ((char *) token->data + NTLM_CHALLENGE_DOMAIN_LEN_OFFSET));
+ domain->str, domain->len);
ntlm_set_string (ret, NTLM_RESPONSE_USER_OFFSET,
sasl->service->url->user,
strlen (sasl->service->url->user));
@@ -138,6 +178,18 @@
(const char *) nt_resp, sizeof (nt_resp));
sasl->authenticated = TRUE;
+
+ g_string_free (domain, TRUE);
+
+ goto exit;
+
+fail:
+ /* If the challenge is malformed, restart authentication.
+ * XXX A malicious server could make this loop indefinitely. */
+ g_byte_array_append (ret, (guint8 *) NTLM_REQUEST,
+ sizeof (NTLM_REQUEST) - 1);
+
+exit:
return ret;
}
@@ -201,17 +253,6 @@
g_free (buf);
}
-static void
-ntlm_set_string (GByteArray *ba, int offset, const char *data, int len)
-{
- ba->data[offset ] = ba->data[offset + 2] = len & 0xFF;
- ba->data[offset + 1] = ba->data[offset + 3] = (len >> 8) & 0xFF;
- ba->data[offset + 4] = ba->len & 0xFF;
- ba->data[offset + 5] = (ba->len >> 8) & 0xFF;
- g_byte_array_append (ba, (guint8 *) data, len);
-}
-
-
#define KEYBITS(k,s) \
(((k[(s)/8] << ((s)%8)) & 0xFF) | (k[(s)/8+1] >> (8-(s)%8)))
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]