[evolution-data-server] Support NTLMv2 in camel-sasl-ntlm.c
- From: David Woodhouse <dwmw2 src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [evolution-data-server] Support NTLMv2 in camel-sasl-ntlm.c
- Date: Fri, 1 Apr 2011 19:34:37 +0000 (UTC)
commit e31811597c0afc8fbf932b40617ee6b8c022ea9e
Author: David Woodhouse <David Woodhouse intel com>
Date: Tue Mar 22 10:11:09 2011 +0000
Support NTLMv2 in camel-sasl-ntlm.c
This still isn't good enough; we need to support calling out to
/usr/bin/ntlm_auth to handle the challenge/response *for* us, for
single-sign-on so that we don't need to know the password for ourselves.
camel/camel-sasl-ntlm.c | 52 +++++++++++++++++++++++++++++++++++++++++-----
1 files changed, 46 insertions(+), 6 deletions(-)
---
diff --git a/camel/camel-sasl-ntlm.c b/camel/camel-sasl-ntlm.c
index e180725..540b1c0 100644
--- a/camel/camel-sasl-ntlm.c
+++ b/camel/camel-sasl-ntlm.c
@@ -45,9 +45,10 @@ CamelServiceAuthType camel_sasl_ntlm_authtype = {
G_DEFINE_TYPE (CamelSaslNTLM, camel_sasl_ntlm, CAMEL_TYPE_SASL)
-#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_REQUEST "NTLMSSP\x00\x01\x00\x00\x00\x06\x82\x08\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_DOMAIN_OFFSET 12
+#define NTLM_CHALLENGE_FLAGS_OFFSET 20
#define NTLM_CHALLENGE_NONCE_OFFSET 24
#define NTLM_RESPONSE_HEADER "NTLMSSP\x00\x03\x00\x00\x00"
@@ -672,12 +673,48 @@ sasl_ntlm_challenge_sync (CamelSasl *sasl,
if (!token || token->len < NTLM_CHALLENGE_NONCE_OFFSET + 8)
goto fail;
- memcpy (nonce, token->data + NTLM_CHALLENGE_NONCE_OFFSET, 8);
- ntlm_lanmanager_hash (service->url->passwd, (gchar *) hash);
- ntlm_calc_response (hash, nonce, lm_resp);
- ntlm_nt_hash (service->url->passwd, (gchar *) hash);
- ntlm_calc_response (hash, nonce, nt_resp);
+ /* 0x00080000: Negotiate NTLM2 Key */
+ if (token->data[NTLM_CHALLENGE_FLAGS_OFFSET + 2] & 8) {
+ /* NTLM2 session response */
+ struct {
+ guint32 srv[2];
+ guint32 clnt[2];
+ } sess_nonce;
+ GChecksum *md5;
+ guint8 digest[16];
+ gsize digest_len = sizeof(digest);
+
+ sess_nonce.clnt[0] = g_random_int();
+ sess_nonce.clnt[1] = g_random_int();
+
+ /* LM response is 8-byte client nonce, NUL-padded to 24 */
+ memcpy(lm_resp, sess_nonce.clnt, 8);
+ memset(lm_resp + 8, 0, 16);
+
+ /* Session nonce is client nonce + server nonce */
+ memcpy (sess_nonce.srv,
+ token->data + NTLM_CHALLENGE_NONCE_OFFSET, 8);
+
+ /* Take MD5 of session nonce */
+ md5 = g_checksum_new (G_CHECKSUM_MD5);
+ g_checksum_update (md5, (void *)&sess_nonce, 16);
+ g_checksum_get_digest (md5, (void *)&digest, &digest_len);
+ g_checksum_get_digest (md5, digest, &digest_len);
+
+ g_checksum_free (md5);
+ ntlm_nt_hash (service->url->passwd, (gchar *) hash);
+
+ ntlm_calc_response (hash, digest, nt_resp);
+ } else {
+ /* NTLM1 */
+ memcpy (nonce, token->data + NTLM_CHALLENGE_NONCE_OFFSET, 8);
+ ntlm_lanmanager_hash (service->url->passwd, (gchar *) hash);
+ ntlm_calc_response (hash, nonce, lm_resp);
+ ntlm_nt_hash (service->url->passwd, (gchar *) hash);
+ ntlm_calc_response (hash, nonce, nt_resp);
+ }
+ /* FIXME: The server domain doesn't always match the user's domain */
domain = ntlm_get_string (token, NTLM_CHALLENGE_DOMAIN_OFFSET);
if (domain == NULL)
goto fail;
@@ -689,6 +726,9 @@ sasl_ntlm_challenge_sync (CamelSasl *sasl,
sizeof (NTLM_RESPONSE_HEADER) - 1);
memcpy (ret->data + NTLM_RESPONSE_FLAGS_OFFSET,
NTLM_RESPONSE_FLAGS, sizeof (NTLM_RESPONSE_FLAGS) - 1);
+ /* Mask in the NTLM2SESSION flag */
+ ret->data[NTLM_RESPONSE_FLAGS_OFFSET + 2] |=
+ token->data[NTLM_CHALLENGE_FLAGS_OFFSET + 2] & 8;
ntlm_set_string (ret, NTLM_RESPONSE_DOMAIN_OFFSET,
domain->str, domain->len);
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]