changeset 2808:48250919bbc4 HEAD

support OEM encoding in NTLM messages. Patch by Andrey Panin.
author Timo Sirainen <tss@iki.fi>
date Fri, 22 Oct 2004 16:34:06 +0300
parents ad3fcccca2bb
children 0b1bef51f207
files src/auth/mech-ntlm.c src/lib-ntlm/ntlm-message.c src/lib-ntlm/ntlm.h
diffstat 3 files changed, 40 insertions(+), 24 deletions(-) [+]
line wrap: on
line diff
--- a/src/auth/mech-ntlm.c	Fri Oct 22 03:48:44 2004 +0300
+++ b/src/auth/mech-ntlm.c	Fri Oct 22 16:34:06 2004 +0300
@@ -26,6 +26,7 @@
 
 	/* requested: */
 	int ntlm2_negotiated;
+	int unicode_negotiated;
 	const unsigned char *challenge;
 
 	/* received: */
@@ -141,6 +142,7 @@
 			(struct ntlmssp_request *)data;
 		const struct ntlmssp_challenge *message;
 		size_t message_size;
+		uint32_t flags;
 
 		if (!ntlmssp_check_request(ntlm_request, data_size, &error)) {
 			if (verbose) {
@@ -154,8 +156,9 @@
 
 		message = ntlmssp_create_challenge(request->pool, ntlm_request,
 						   &message_size);
-		request->ntlm2_negotiated =
-			read_le32(&message->flags) & NTLMSSP_NEGOTIATE_NTLM2;
+		flags = read_le32(&message->flags);
+		request->ntlm2_negotiated = flags & NTLMSSP_NEGOTIATE_NTLM2;
+		request->unicode_negotiated = flags & NTLMSSP_NEGOTIATE_UNICODE;
 		request->challenge = message->challenge;
 
 		auth_request->callback(auth_request,
@@ -180,7 +183,8 @@
 		memcpy(request->response, response, data_size);
 
 		username = p_strdup(auth_request->pool,
-				    ntlmssp_t_str(request->response, user));
+				    ntlmssp_t_str(request->response, user, 
+				    request->unicode_negotiated));
 
 		if (!mech_fix_username(username, &error)) {
 			if (verbose) {
--- a/src/lib-ntlm/ntlm-message.c	Fri Oct 22 03:48:44 2004 +0300
+++ b/src/lib-ntlm/ntlm-message.c	Fri Oct 22 16:34:06 2004 +0300
@@ -21,42 +21,52 @@
 #include <stdarg.h>
 #include <ctype.h>
 
-const char * __ntlmssp_t_str(const void *message, struct ntlmssp_buffer *buffer)
+const char * __ntlmssp_t_str(const void *message, struct ntlmssp_buffer *buffer,
+			     int unicode)
 {
-	unsigned int len = read_le16(&buffer->length) / sizeof(ucs2le_t);
-	string_t *str = t_str_new(len / 2);
+	unsigned int len = read_le16(&buffer->length);
 	const char *p = ((char *) message) + read_le32(&buffer->offset);
+	string_t *str;
+
+	if (unicode)
+		len /= sizeof(ucs2le_t);
+
+	str = t_str_new(len);
 
 	while (len-- > 0) {
 		str_append_c(str, *p & 0x7f);
-		p += sizeof(ucs2le_t);
+		p += unicode ? sizeof(ucs2le_t) : 1;
 	}
 
 	return str_c(str);
 }
 
-static unsigned int append_string(buffer_t *buf, const char *str, int ucase)
+static unsigned int append_string(buffer_t *buf, const char *str, 
+				  int ucase, int unicode)
 {
 	unsigned int length = 0;
 
 	for ( ; *str; str++) {
 		buffer_append_c(buf, ucase ? toupper(*str) : *str);
-		buffer_append_c(buf, 0);
-		length += sizeof(ucs2le_t);
+		if (unicode) {
+			buffer_append_c(buf, 0);
+			length++; 
+		}
+		length++;
 	}
 
 	return length;
 }
 
 static void ntlmssp_append_string(buffer_t *buf, size_t buffer_offset,
-				  const char *str)
+				  const char *str, int unicode)
 {
 	struct ntlmssp_buffer buffer;
 	unsigned int length;
 
 	write_le32(&buffer.offset, buffer_get_used_size(buf));
 
-	length = append_string(buf, str, 0);
+	length = append_string(buf, str, FALSE, unicode);
 
 	write_le16(&buffer.length, length);
 	write_le16(&buffer.space, length);
@@ -95,7 +105,8 @@
 				write_le16(&info.length,
 					   strlen(data) * sizeof(ucs2le_t));
 				buffer_append(buf, &info, sizeof(info));
-				length = append_string(buf, data, 0);
+				length = append_string(buf, data, FALSE, TRUE) +
+					 sizeof(info);
 				break;
 			default:
 				i_panic("Invalid NTLM target info block type "
@@ -115,10 +126,14 @@
 
 static inline uint32_t ntlmssp_flags(uint32_t client_flags)
 {
-	uint32_t flags = NTLMSSP_NEGOTIATE_UNICODE |
-			 NTLMSSP_NEGOTIATE_NTLM |
+	uint32_t flags = NTLMSSP_NEGOTIATE_NTLM |
 			 NTLMSSP_NEGOTIATE_TARGET_INFO;
 
+	if (client_flags & NTLMSSP_NEGOTIATE_UNICODE)
+		flags |= NTLMSSP_NEGOTIATE_UNICODE;
+	else
+		flags |= NTLMSSP_NEGOTIATE_OEM;
+
 	if (client_flags & NTLMSSP_NEGOTIATE_NTLM2)
 		flags |= NTLMSSP_NEGOTIATE_NTLM2;
 
@@ -134,6 +149,7 @@
 {
 	buffer_t *buf;
 	uint32_t flags = ntlmssp_flags(read_le32(&request->flags));
+	int unicode = flags & NTLMSSP_NEGOTIATE_UNICODE;
 	struct ntlmssp_challenge c;
 
 	buf = buffer_create_dynamic(pool, sizeof(struct ntlmssp_challenge));
@@ -149,7 +165,7 @@
 	if (flags & NTLMSSP_TARGET_TYPE_SERVER)
 		ntlmssp_append_string(buf,
 			offsetof(struct ntlmssp_challenge, target_name),
-			my_hostname);
+			my_hostname, unicode);
 
 	ntlmssp_append_target_info(buf, offsetof(struct ntlmssp_challenge,
 						 target_info),
@@ -200,11 +216,6 @@
 
 	flags = read_le32(&request->flags);
 
-	if ((flags & NTLMSSP_NEGOTIATE_UNICODE) == 0) {
-		*error = "client doesn't advertise Unicode support";
-		return 0;
-	}
-
 	if ((flags & NTLMSSP_NEGOTIATE_NTLM) == 0) {
 		*error = "client doesn't advertise NTLM support";
 		return 0;
--- a/src/lib-ntlm/ntlm.h	Fri Oct 22 03:48:44 2004 +0300
+++ b/src/lib-ntlm/ntlm.h	Fri Oct 22 16:34:06 2004 +0300
@@ -26,10 +26,11 @@
 	return read_le16(&buffer->length);
 }
 
-#define ntlmssp_t_str(message, buffer) \
-	__ntlmssp_t_str((message), &message->buffer)
+#define ntlmssp_t_str(message, buffer, unicode) \
+	__ntlmssp_t_str((message), &(message)->buffer, (unicode))
 
 const char * __ntlmssp_t_str(const void *message,
-			     struct ntlmssp_buffer *buffer);
+			     struct ntlmssp_buffer *buffer,
+			     int unicode);
 
 #endif