summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDan Winship <danw@src.gnome.org>2002-05-23 14:50:18 +0000
committerDan Winship <danw@src.gnome.org>2002-05-23 14:50:18 +0000
commit14b5528d180e2f76d9185a14d045b15c13430661 (patch)
treea8c763d015ee2be12b4257a357529894bfcdf317
parent60049c383a4ce35a426294a8665b6b00edb648f6 (diff)
downloadlibsoup-14b5528d180e2f76d9185a14d045b15c13430661.tar.gz
install soup-ntlm.h
* src/libsoup/Makefile.am (libsoupinclude_HEADERS): install soup-ntlm.h * src/libsoup/soup-ntlm.c (soup_ntlm_parse_challenge): Separated out of soup_ntlm_response. Takes the challenge and returns the nonce and default domain from it. (The application can use this from a 401 handler to find the domain name when using NTLM auth.) (soup_ntlm_response): Remove the challenge-parsing code from here. Just take the nonce instead. * src/libsoup/soup-auth.c (ntlm_init): Update for soup-ntlm changes. Don't parse the authmech twice since there's no reason to.
-rw-r--r--ChangeLog16
-rw-r--r--libsoup/Makefile.am2
-rw-r--r--libsoup/soup-auth.c46
-rw-r--r--libsoup/soup-ntlm.c98
-rw-r--r--libsoup/soup-ntlm.h25
5 files changed, 115 insertions, 72 deletions
diff --git a/ChangeLog b/ChangeLog
index 94001930..0b64b07c 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,19 @@
+2002-05-23 Dan Winship <danw@ximian.com>
+
+ * src/libsoup/Makefile.am (libsoupinclude_HEADERS): install
+ soup-ntlm.h
+
+ * src/libsoup/soup-ntlm.c (soup_ntlm_parse_challenge): Separated
+ out of soup_ntlm_response. Takes the challenge and returns the
+ nonce and default domain from it. (The application can use this
+ from a 401 handler to find the domain name when using NTLM auth.)
+ (soup_ntlm_response): Remove the challenge-parsing code from here.
+ Just take the nonce instead.
+
+ * src/libsoup/soup-auth.c (ntlm_init): Update for soup-ntlm
+ changes. Don't parse the authmech twice since there's no reason
+ to.
+
2002-05-06 Joe Shaw <joe@ximian.com>
* src/libsoup/soup-headers.c (soup_headers_parse_request):
diff --git a/libsoup/Makefile.am b/libsoup/Makefile.am
index e47c5752..5381c1d6 100644
--- a/libsoup/Makefile.am
+++ b/libsoup/Makefile.am
@@ -26,6 +26,7 @@ libsoupinclude_HEADERS = \
soup-message.h \
soup-method.h \
soup-misc.h \
+ soup-ntlm.h \
soup-parser.h \
soup-serializer.h \
soup-server-auth.h \
@@ -59,7 +60,6 @@ libsoup_la_SOURCES = \
soup-misc.c \
soup-nss.h \
soup-nss.c \
- soup-ntlm.h \
soup-ntlm.c \
soup-parser.c \
soup-private.h \
diff --git a/libsoup/soup-auth.c b/libsoup/soup-auth.c
index 1ffc8b83..baef0060 100644
--- a/libsoup/soup-auth.c
+++ b/libsoup/soup-auth.c
@@ -530,42 +530,38 @@ ntlm_parse (SoupAuth *sa, const char *header)
g_strstrip (auth->header);
}
-/*
- * FIXME: Because NTLM is a two step process, we parse the host and domain out
- * of the context's uri twice. This is because there is no way to reparse
- * a new header with an existing SoupAuth, so a new one is created for
- * each negotiation step.
- */
static void
ntlm_init (SoupAuth *sa, const SoupUri *uri)
{
SoupAuthNTLM *auth = (SoupAuthNTLM *) sa;
- gchar *host, *domain;
-
- host = ntlm_get_authmech_token (uri, "host=");
- domain = ntlm_get_authmech_token (uri, "domain=");
if (strlen (auth->header) < sizeof ("NTLM"))
auth->response = soup_ntlm_request ();
else {
- gchar lm_hash [21], nt_hash [21];
-
- soup_ntlm_lanmanager_hash (uri->passwd, lm_hash);
- soup_ntlm_nt_hash (uri->passwd, nt_hash);
-
- auth->response =
- soup_ntlm_response (auth->header,
- uri->user,
- (gchar *) &lm_hash,
- (gchar *) &nt_hash,
- host,
- domain);
+ gchar *host, *domain, *nonce;
+
+ host = ntlm_get_authmech_token (uri, "host=");
+ domain = ntlm_get_authmech_token (uri, "domain=");
+
+ if (!soup_ntlm_parse_challenge (auth->header,
+ &nonce,
+ domain ? NULL : &domain))
+ auth->response = NULL;
+ else {
+ auth->response =
+ soup_ntlm_response (nonce,
+ uri->user,
+ uri->passwd,
+ host,
+ domain);
+ g_free (nonce);
+ }
+
+ g_free (host);
+ g_free (domain);
auth->completed = TRUE;
}
- g_free (host);
- g_free (domain);
-
g_free (auth->header);
auth->header = NULL;
}
diff --git a/libsoup/soup-ntlm.c b/libsoup/soup-ntlm.c
index 64f809fe..9d367082 100644
--- a/libsoup/soup-ntlm.c
+++ b/libsoup/soup-ntlm.c
@@ -44,7 +44,7 @@ static void calc_response (const guchar *key,
"\x00\x00\x00\x00\x00"
void
-soup_ntlm_lanmanager_hash (const char *password, char hash[21])
+soup_ntlm_lanmanager_hash (const char *password, guchar hash[21])
{
guchar lm_password [15];
DES_KS ks;
@@ -66,7 +66,7 @@ soup_ntlm_lanmanager_hash (const char *password, char hash[21])
}
void
-soup_ntlm_nt_hash (const char *password, char hash[21])
+soup_ntlm_nt_hash (const char *password, guchar hash[21])
{
unsigned char *buf, *p;
@@ -90,10 +90,9 @@ typedef struct {
guchar zero_pad[2];
} NTLMString;
-#define NTLM_CHALLENGE_NONCE_OFFSET 24
-#define NTLM_CHALLENGE_NONCE_LENGTH 8
-#define NTLM_CHALLENGE_DOMAIN_OFFSET 48
-#define NTLM_CHALLENGE_DOMAIN_LEN_OFFSET 44
+#define NTLM_CHALLENGE_NONCE_OFFSET 24
+#define NTLM_CHALLENGE_NONCE_LENGTH 8
+#define NTLM_CHALLENGE_DOMAIN_STRING_OFFSET 12
#define NTLM_RESPONSE_HEADER "NTLMSSP\x00\x03\x00\x00\x00"
#define NTLM_RESPONSE_FLAGS "\x82\x01"
@@ -116,8 +115,10 @@ typedef struct {
#if G_BYTE_ORDER == G_BIG_ENDIAN
#define LE16(x) (((x & 0xFF) << 8) | ((x >> 8) & 0xFF))
+#define UNLE16(x) LE16(x)
#else
#define LE16(x) x
+#define UNLE16(x) x
#endif
static void
@@ -134,39 +135,73 @@ soup_ntlm_request (void)
return g_strdup ("NTLM TlRMTVNTUAABAAAABoIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAMAAAAAAAAAAwAAAA");
}
-char *
-soup_ntlm_response (const char *challenge,
- const char *user,
- const char *lm_hash,
- const char *nt_hash,
- const char *host,
- const char *domain)
+gboolean
+soup_ntlm_parse_challenge (const char *challenge,
+ char **nonce,
+ char **default_domain)
{
- int hlen, dlen, ulen, offset, decodelen;
- guchar lm_resp[24], nt_resp[24], *nonce;
- NTLMResponse resp;
+ int clen, decodelen;
+ NTLMString domain;
char *chall;
- unsigned char *out, *p;
int state, save;
if (strncmp (challenge, "NTLM ", 5) != 0)
- return NULL;
+ return FALSE;
decodelen = strlen (challenge) - 5;
chall = g_malloc (decodelen);
state = save = 0;
- soup_base64_decode_step ((guchar *) challenge + 5,
- decodelen,
- chall,
- &state,
- &save);
+ clen = soup_base64_decode_step ((guchar *) challenge + 5,
+ decodelen,
+ chall,
+ &state,
+ &save);
+
+ if (clen < NTLM_CHALLENGE_DOMAIN_STRING_OFFSET ||
+ clen < NTLM_CHALLENGE_NONCE_OFFSET + NTLM_CHALLENGE_NONCE_LENGTH) {
+ g_free (chall);
+ return FALSE;
+ }
+
+ if (default_domain) {
+ memcpy (&domain, chall + NTLM_CHALLENGE_DOMAIN_STRING_OFFSET, sizeof (domain));
+ domain.length = UNLE16 (domain.length);
+ domain.offset = UNLE16 (domain.offset);
+
+ if (clen < domain.length + domain.offset) {
+ g_free (chall);
+ return FALSE;
+ }
+
+ *default_domain = g_strndup (chall + domain.offset, domain.length);
+ }
- nonce = chall + NTLM_CHALLENGE_NONCE_OFFSET;
- nonce [NTLM_CHALLENGE_NONCE_LENGTH] = '\0';
+ if (nonce) {
+ *nonce = g_strndup (chall + NTLM_CHALLENGE_NONCE_OFFSET,
+ NTLM_CHALLENGE_NONCE_LENGTH);
+ }
- calc_response (lm_hash, nonce, lm_resp);
- calc_response (nt_hash, nonce, nt_resp);
+ return TRUE;
+}
+
+char *
+soup_ntlm_response (const char *nonce,
+ const char *user,
+ const char *password,
+ const char *host,
+ const char *domain)
+{
+ int hlen, dlen, ulen, offset;
+ guchar hash[21], lm_resp[24], nt_resp[24];
+ NTLMResponse resp;
+ unsigned char *out, *p;
+ int state, save;
+
+ soup_ntlm_lanmanager_hash (password, hash);
+ calc_response (hash, nonce, lm_resp);
+ soup_ntlm_nt_hash (password, hash);
+ calc_response (hash, nonce, nt_resp);
memset (&resp, 0, sizeof (resp));
memcpy (resp.header, NTLM_RESPONSE_HEADER, sizeof (resp.header));
@@ -174,13 +209,7 @@ soup_ntlm_response (const char *challenge,
offset = sizeof (resp);
- if (domain)
- dlen = strlen (domain);
- else {
- /* Grab the default domain from the challenge */
- domain = chall + NTLM_CHALLENGE_DOMAIN_OFFSET;
- dlen = atoi (chall + NTLM_CHALLENGE_DOMAIN_LEN_OFFSET);
- }
+ dlen = strlen (domain);
ntlm_set_string (&resp.domain, &offset, dlen);
ulen = strlen (user);
ntlm_set_string (&resp.user, &offset, ulen);
@@ -235,7 +264,6 @@ soup_ntlm_response (const char *challenge,
&state,
&save);
*p = '\0';
- g_free (chall);
return out;
}
diff --git a/libsoup/soup-ntlm.h b/libsoup/soup-ntlm.h
index 3149805a..5b35f429 100644
--- a/libsoup/soup-ntlm.h
+++ b/libsoup/soup-ntlm.h
@@ -13,19 +13,22 @@
#include <glib.h>
-void soup_ntlm_lanmanager_hash (const char *password,
- char hash[21]);
+void soup_ntlm_lanmanager_hash (const char *password,
+ guchar hash[21]);
-void soup_ntlm_nt_hash (const char *password,
- char hash[21]);
+void soup_ntlm_nt_hash (const char *password,
+ guchar hash[21]);
-char *soup_ntlm_request (void);
+char *soup_ntlm_request (void);
-char *soup_ntlm_response (const char *challenge,
- const char *user,
- const char *lm_hash,
- const char *nt_hash,
- const char *host,
- const char *domain);
+gboolean soup_ntlm_parse_challenge (const char *challenge,
+ char **nonce,
+ char **default_domain);
+
+char *soup_ntlm_response (const char *nonce,
+ const char *user,
+ const char *password,
+ const char *host,
+ const char *domain);
#endif /* NTLM_H */