Gentoo Websites Logo
Go to: Gentoo Home Documentation Forums Lists Bugs Planet Store Wiki Get Gentoo!
View | Details | Raw Unified | Return to bug 261203
Collapse All | Expand All

(-)camel/camel-sasl-ntlm.c (-24 / +65 lines)
Lines 74-82 camel_sasl_ntlm_get_type (void) Link Here
74
74
75
#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"
75
#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"
76
76
77
#define NTLM_CHALLENGE_NONCE_OFFSET      24
77
#define NTLM_CHALLENGE_DOMAIN_OFFSET		12
78
#define NTLM_CHALLENGE_DOMAIN_OFFSET     48
78
#define NTLM_CHALLENGE_NONCE_OFFSET		24
79
#define NTLM_CHALLENGE_DOMAIN_LEN_OFFSET 44
80
79
81
#define NTLM_RESPONSE_HEADER         "NTLMSSP\x00\x03\x00\x00\x00"
80
#define NTLM_RESPONSE_HEADER         "NTLMSSP\x00\x03\x00\x00\x00"
82
#define NTLM_RESPONSE_FLAGS          "\x82\x01"
81
#define NTLM_RESPONSE_FLAGS          "\x82\x01"
Lines 93-114 static void ntlm_calc_response (const Link Here
93
				  guchar results[24]);
92
				  guchar results[24]);
94
static void ntlm_lanmanager_hash (const char *password, char hash[21]);
93
static void ntlm_lanmanager_hash (const char *password, char hash[21]);
95
static void ntlm_nt_hash         (const char *password, char hash[21]);
94
static void ntlm_nt_hash         (const char *password, char hash[21]);
96
static void ntlm_set_string      (GByteArray *ba, int offset,
95
97
				  const char *data, int len);
96
typedef struct {
97
	guint16 length;
98
	guint16 allocated;
99
	guint32 offset;
100
} SecurityBuffer;
101
102
static GString *
103
ntlm_get_string (GByteArray *ba, int offset)
104
{
105
	SecurityBuffer *secbuf;
106
	GString *string;
107
	gchar *buf_string;
108
	guint16 buf_length;
109
	guint32 buf_offset;
110
111
	secbuf = (SecurityBuffer *) &ba->data[offset];
112
	buf_length = GUINT16_FROM_LE (secbuf->length);
113
	buf_offset = GUINT32_FROM_LE (secbuf->offset);
114
115
	if (ba->len < buf_offset + buf_length)
116
		return NULL;
117
118
	string = g_string_sized_new (buf_length);
119
	buf_string = (gchar *) &ba->data[buf_offset];
120
	g_string_append_len (string, buf_string, buf_length);
121
122
	return string;
123
}
124
125
static void
126
ntlm_set_string (GByteArray *ba, int offset, const char *data, int len)
127
{
128
	SecurityBuffer *secbuf;
129
130
	secbuf = (SecurityBuffer *) &ba->data[offset];
131
	secbuf->length = GUINT16_TO_LE (len);
132
	secbuf->offset = GUINT32_TO_LE (ba->len);
133
	secbuf->allocated = secbuf->length;
134
135
	g_byte_array_append (ba, (guint8 *) data, len);
136
}
98
137
99
static GByteArray *
138
static GByteArray *
100
ntlm_challenge (CamelSasl *sasl, GByteArray *token, CamelException *ex)
139
ntlm_challenge (CamelSasl *sasl, GByteArray *token, CamelException *ex)
101
{
140
{
102
	GByteArray *ret;
141
	GByteArray *ret;
103
	guchar nonce[8], hash[21], lm_resp[24], nt_resp[24];
142
	guchar nonce[8], hash[21], lm_resp[24], nt_resp[24];
143
	GString *domain;
104
144
105
	ret = g_byte_array_new ();
145
	ret = g_byte_array_new ();
106
146
107
	if (!token || !token->len) {
147
	if (!token || token->len < NTLM_CHALLENGE_NONCE_OFFSET + 8)
108
		g_byte_array_append (ret, (guint8 *) NTLM_REQUEST,
148
		goto fail;
109
				     sizeof (NTLM_REQUEST) - 1);
110
		return ret;
111
	}
112
149
113
	memcpy (nonce, token->data + NTLM_CHALLENGE_NONCE_OFFSET, 8);
150
	memcpy (nonce, token->data + NTLM_CHALLENGE_NONCE_OFFSET, 8);
114
	ntlm_lanmanager_hash (sasl->service->url->passwd, (char *) hash);
151
	ntlm_lanmanager_hash (sasl->service->url->passwd, (char *) hash);
Lines 116-122 ntlm_challenge (CamelSasl *sasl, GByteAr Link Here
116
	ntlm_nt_hash (sasl->service->url->passwd, (char *) hash);
153
	ntlm_nt_hash (sasl->service->url->passwd, (char *) hash);
117
	ntlm_calc_response (hash, nonce, nt_resp);
154
	ntlm_calc_response (hash, nonce, nt_resp);
118
155
119
	ret = g_byte_array_new ();
156
	domain = ntlm_get_string (token, NTLM_CHALLENGE_DOMAIN_OFFSET);
157
	if (domain == NULL)
158
		goto fail;
159
160
	/* Don't jump to 'fail' label after this point. */
120
	g_byte_array_set_size (ret, NTLM_RESPONSE_BASE_SIZE);
161
	g_byte_array_set_size (ret, NTLM_RESPONSE_BASE_SIZE);
121
	memset (ret->data, 0, NTLM_RESPONSE_BASE_SIZE);
162
	memset (ret->data, 0, NTLM_RESPONSE_BASE_SIZE);
122
	memcpy (ret->data, NTLM_RESPONSE_HEADER,
163
	memcpy (ret->data, NTLM_RESPONSE_HEADER,
Lines 125-132 ntlm_challenge (CamelSasl *sasl, GByteAr Link Here
125
		NTLM_RESPONSE_FLAGS, sizeof (NTLM_RESPONSE_FLAGS) - 1);
166
		NTLM_RESPONSE_FLAGS, sizeof (NTLM_RESPONSE_FLAGS) - 1);
126
167
127
	ntlm_set_string (ret, NTLM_RESPONSE_DOMAIN_OFFSET,
168
	ntlm_set_string (ret, NTLM_RESPONSE_DOMAIN_OFFSET,
128
			 (const char *) token->data + NTLM_CHALLENGE_DOMAIN_OFFSET,
169
			 domain->str, domain->len);
129
			 atoi ((char *) token->data + NTLM_CHALLENGE_DOMAIN_LEN_OFFSET));
130
	ntlm_set_string (ret, NTLM_RESPONSE_USER_OFFSET,
170
	ntlm_set_string (ret, NTLM_RESPONSE_USER_OFFSET,
131
			 sasl->service->url->user,
171
			 sasl->service->url->user,
132
			 strlen (sasl->service->url->user));
172
			 strlen (sasl->service->url->user));
Lines 138-143 ntlm_challenge (CamelSasl *sasl, GByteAr Link Here
138
			 (const char *) nt_resp, sizeof (nt_resp));
178
			 (const char *) nt_resp, sizeof (nt_resp));
139
179
140
	sasl->authenticated = TRUE;
180
	sasl->authenticated = TRUE;
181
182
	g_string_free (domain, TRUE);
183
184
	goto exit;
185
186
fail:
187
	/* If the challenge is malformed, restart authentication.
188
	 * XXX A malicious server could make this loop indefinitely. */
189
	g_byte_array_append (ret, (guint8 *) NTLM_REQUEST,
190
			     sizeof (NTLM_REQUEST) - 1);
191
192
exit:
141
	return ret;
193
	return ret;
142
}
194
}
143
195
Lines 201-217 ntlm_nt_hash (const char *password, char Link Here
201
	g_free (buf);
253
	g_free (buf);
202
}
254
}
203
255
204
static void
205
ntlm_set_string (GByteArray *ba, int offset, const char *data, int len)
206
{
207
	ba->data[offset    ] = ba->data[offset + 2] =  len       & 0xFF;
208
	ba->data[offset + 1] = ba->data[offset + 3] = (len >> 8) & 0xFF;
209
	ba->data[offset + 4] =  ba->len       & 0xFF;
210
	ba->data[offset + 5] = (ba->len >> 8) & 0xFF;
211
	g_byte_array_append (ba, (guint8 *) data, len);
212
}
213
214
215
#define KEYBITS(k,s) \
256
#define KEYBITS(k,s) \
216
        (((k[(s)/8] << ((s)%8)) & 0xFF) | (k[(s)/8+1] >> (8-(s)%8)))
257
        (((k[(s)/8] << ((s)%8)) & 0xFF) | (k[(s)/8+1] >> (8-(s)%8)))
217
258

Return to bug 261203