diff options
author | Dan Winship <danw@src.gnome.org> | 2002-05-23 14:50:18 +0000 |
---|---|---|
committer | Dan Winship <danw@src.gnome.org> | 2002-05-23 14:50:18 +0000 |
commit | 14b5528d180e2f76d9185a14d045b15c13430661 (patch) | |
tree | a8c763d015ee2be12b4257a357529894bfcdf317 | |
parent | 60049c383a4ce35a426294a8665b6b00edb648f6 (diff) | |
download | libsoup-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-- | ChangeLog | 16 | ||||
-rw-r--r-- | libsoup/Makefile.am | 2 | ||||
-rw-r--r-- | libsoup/soup-auth.c | 46 | ||||
-rw-r--r-- | libsoup/soup-ntlm.c | 98 | ||||
-rw-r--r-- | libsoup/soup-ntlm.h | 25 |
5 files changed, 115 insertions, 72 deletions
@@ -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 */ |