1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142
|
--- ../old/evolution-data-server-1.6.3/camel/camel-sasl-ntlm.c 2006-05-03 13:59:26.000000000 +0000
+++ evolution-data-server-1.6.3/camel/camel-sasl-ntlm.c 2009-05-30 05:09:06.000000000 +0000
@@ -72,9 +72,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"
@@ -91,22 +90,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, 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, hash);
@@ -114,7 +151,11 @@
ntlm_nt_hash (sasl->service->url->passwd, 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,
@@ -123,8 +164,7 @@
NTLM_RESPONSE_FLAGS, sizeof (NTLM_RESPONSE_FLAGS) - 1);
ntlm_set_string (ret, NTLM_RESPONSE_DOMAIN_OFFSET,
- token->data + NTLM_CHALLENGE_DOMAIN_OFFSET,
- atoi (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));
@@ -136,6 +176,18 @@
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;
}
@@ -199,17 +251,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, data, len);
-}
-
-
#define KEYBITS(k,s) \
(((k[(s)/8] << ((s)%8)) & 0xFF) | (k[(s)/8+1] >> (8-(s)%8)))
|