Merge pull request #614 from orgads/curl-digest
curl: Fix digest authentication
This commit is contained in:
@@ -0,0 +1,211 @@
|
||||
From 59f3f92ba6150e9a5a57f71b6e781802148916d0 Mon Sep 17 00:00:00 2001
|
||||
From: Grant Pannell <grant@pannell.net.au>
|
||||
Date: Sun, 26 Apr 2015 16:12:23 +0200
|
||||
Subject: [PATCH] sasl_sspi: Populate domain from the realm in the challenge
|
||||
|
||||
Without this, SSPI based digest auth was broken.
|
||||
|
||||
Bug: https://github.com/bagder/curl/pull/141.patch
|
||||
---
|
||||
lib/curl_sasl.c | 14 +++++-----
|
||||
lib/curl_sasl.h | 9 +++++++
|
||||
lib/curl_sasl_sspi.c | 74 ++++++++++++++++++++++++++++++++++++++++++++++++++++
|
||||
lib/curl_sspi.h | 4 +++
|
||||
4 files changed, 95 insertions(+), 6 deletions(-)
|
||||
|
||||
diff --git a/lib/curl_sasl.c b/lib/curl_sasl.c
|
||||
index d9f63ab..68646bc 100644
|
||||
--- a/lib/curl_sasl.c
|
||||
+++ b/lib/curl_sasl.c
|
||||
@@ -76,9 +76,6 @@ const struct {
|
||||
#define DIGEST_QOP_VALUE_STRING_AUTH_INT "auth-int"
|
||||
#define DIGEST_QOP_VALUE_STRING_AUTH_CONF "auth-conf"
|
||||
|
||||
-#define DIGEST_MAX_VALUE_LENGTH 256
|
||||
-#define DIGEST_MAX_CONTENT_LENGTH 1024
|
||||
-
|
||||
/* The CURL_OUTPUT_DIGEST_CONV macro below is for non-ASCII machines.
|
||||
It converts digest text to ASCII so the MD5 will be correct for
|
||||
what ultimately goes over the network.
|
||||
@@ -90,13 +87,16 @@ const struct {
|
||||
return result; \
|
||||
}
|
||||
|
||||
+#endif
|
||||
+
|
||||
+#if !defined(CURL_DISABLE_CRYPTO_AUTH)
|
||||
/*
|
||||
* Returns 0 on success and then the buffers are filled in fine.
|
||||
*
|
||||
* Non-zero means failure to parse.
|
||||
*/
|
||||
-static int sasl_digest_get_pair(const char *str, char *value, char *content,
|
||||
- const char **endptr)
|
||||
+int Curl_sasl_digest_get_pair(const char *str, char *value, char *content,
|
||||
+ const char **endptr)
|
||||
{
|
||||
int c;
|
||||
bool starts_with_quote = FALSE;
|
||||
@@ -157,7 +157,9 @@ static int sasl_digest_get_pair(const char *str, char *value, char *content,
|
||||
|
||||
return 0; /* all is fine! */
|
||||
}
|
||||
+#endif
|
||||
|
||||
+#if !defined(CURL_DISABLE_CRYPTO_AUTH) && !defined(USE_WINDOWS_SSPI)
|
||||
/* Convert md5 chunk to RFC2617 (section 3.1.3) -suitable ascii string*/
|
||||
static void sasl_digest_md5_to_ascii(unsigned char *source, /* 16 bytes */
|
||||
unsigned char *dest) /* 33 bytes */
|
||||
@@ -776,7 +778,7 @@ CURLcode Curl_sasl_decode_digest_http_message(const char *chlg,
|
||||
chlg++;
|
||||
|
||||
/* Extract a value=content pair */
|
||||
- if(!sasl_digest_get_pair(chlg, value, content, &chlg)) {
|
||||
+ if(!Curl_sasl_digest_get_pair(chlg, value, content, &chlg)) {
|
||||
if(Curl_raw_equal(value, "nonce")) {
|
||||
digest->nonce = strdup(content);
|
||||
if(!digest->nonce)
|
||||
diff --git a/lib/curl_sasl.h b/lib/curl_sasl.h
|
||||
index 0dc7377..117d60e 100644
|
||||
--- a/lib/curl_sasl.h
|
||||
+++ b/lib/curl_sasl.h
|
||||
@@ -65,6 +65,11 @@ struct kerberos5data;
|
||||
#define SASL_MECH_STRING_NTLM "NTLM"
|
||||
#define SASL_MECH_STRING_XOAUTH2 "XOAUTH2"
|
||||
|
||||
+#if !defined(CURL_DISABLE_CRYPTO_AUTH)
|
||||
+#define DIGEST_MAX_VALUE_LENGTH 256
|
||||
+#define DIGEST_MAX_CONTENT_LENGTH 1024
|
||||
+#endif
|
||||
+
|
||||
enum {
|
||||
CURLDIGESTALGO_MD5,
|
||||
CURLDIGESTALGO_MD5SESS
|
||||
@@ -136,6 +141,10 @@ char *Curl_sasl_build_spn(const char *service, const char *instance);
|
||||
TCHAR *Curl_sasl_build_spn(const char *service, const char *instance);
|
||||
#endif
|
||||
|
||||
+/* This is used to extract the realm from a challenge message */
|
||||
+int Curl_sasl_digest_get_pair(const char *str, char *value, char *content,
|
||||
+ const char **endptr);
|
||||
+
|
||||
#if defined(HAVE_GSSAPI)
|
||||
char *Curl_sasl_build_gssapi_spn(const char *service, const char *host);
|
||||
#endif
|
||||
diff --git a/lib/curl_sasl_sspi.c b/lib/curl_sasl_sspi.c
|
||||
index 0a332e6..b149530 100644
|
||||
--- a/lib/curl_sasl_sspi.c
|
||||
+++ b/lib/curl_sasl_sspi.c
|
||||
@@ -40,6 +40,7 @@
|
||||
#include "sendf.h"
|
||||
#include "strdup.h"
|
||||
#include "curl_printf.h"
|
||||
+#include "rawstr.h"
|
||||
|
||||
/* The last #include files should be: */
|
||||
#include "curl_memory.h"
|
||||
@@ -274,6 +275,74 @@ CURLcode Curl_sasl_create_digest_md5_message(struct SessionHandle *data,
|
||||
}
|
||||
|
||||
/*
|
||||
+* Curl_override_sspi_http_realm()
|
||||
+*
|
||||
+* This is used to populate the domain in a SSPI identity structure
|
||||
+* The realm is extracted from the challenge message and used as the
|
||||
+* domain if it is not already explicitly set.
|
||||
+*
|
||||
+* Parameters:
|
||||
+*
|
||||
+* chlg [in] - The challenge message.
|
||||
+* identity [in/out] - The identity structure.
|
||||
+*
|
||||
+* Returns CURLE_OK on success.
|
||||
+*/
|
||||
+CURLcode Curl_override_sspi_http_realm(const char *chlg,
|
||||
+ SEC_WINNT_AUTH_IDENTITY *identity)
|
||||
+{
|
||||
+ xcharp_u domain, dup_domain;
|
||||
+
|
||||
+ /* If domain is blank or unset, check challenge message for realm */
|
||||
+ if(!identity->Domain || !identity->DomainLength) {
|
||||
+ for(;;) {
|
||||
+ char value[DIGEST_MAX_VALUE_LENGTH];
|
||||
+ char content[DIGEST_MAX_CONTENT_LENGTH];
|
||||
+
|
||||
+ /* Pass all additional spaces here */
|
||||
+ while(*chlg && ISSPACE(*chlg))
|
||||
+ chlg++;
|
||||
+
|
||||
+ /* Extract a value=content pair */
|
||||
+ if(!Curl_sasl_digest_get_pair(chlg, value, content, &chlg)) {
|
||||
+ if(Curl_raw_equal(value, "realm")) {
|
||||
+
|
||||
+ /* Setup identity's domain and length */
|
||||
+ domain.tchar_ptr = Curl_convert_UTF8_to_tchar((char *)content);
|
||||
+ if(!domain.tchar_ptr)
|
||||
+ return CURLE_OUT_OF_MEMORY;
|
||||
+ dup_domain.tchar_ptr = _tcsdup(domain.tchar_ptr);
|
||||
+ if(!dup_domain.tchar_ptr) {
|
||||
+ Curl_unicodefree(domain.tchar_ptr);
|
||||
+ return CURLE_OUT_OF_MEMORY;
|
||||
+ }
|
||||
+ identity->Domain = dup_domain.tbyte_ptr;
|
||||
+ identity->DomainLength = curlx_uztoul(_tcslen(dup_domain.tchar_ptr));
|
||||
+ dup_domain.tchar_ptr = NULL;
|
||||
+
|
||||
+ Curl_unicodefree(domain.tchar_ptr);
|
||||
+ }
|
||||
+ else {
|
||||
+ /* unknown specifier, ignore it! */
|
||||
+ }
|
||||
+ }
|
||||
+ else
|
||||
+ break; /* we're done here */
|
||||
+
|
||||
+ /* Pass all additional spaces here */
|
||||
+ while(*chlg && ISSPACE(*chlg))
|
||||
+ chlg++;
|
||||
+
|
||||
+ /* Allow the list to be comma-separated */
|
||||
+ if(',' == *chlg)
|
||||
+ chlg++;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ return CURLE_OK;
|
||||
+}
|
||||
+
|
||||
+/*
|
||||
* Curl_sasl_decode_digest_http_message()
|
||||
*
|
||||
* This is used to decode a HTTP DIGEST challenge message into the seperate
|
||||
@@ -374,6 +443,11 @@ CURLcode Curl_sasl_create_digest_http_message(struct SessionHandle *data,
|
||||
if(Curl_create_sspi_identity(userp, passwdp, &identity))
|
||||
return CURLE_OUT_OF_MEMORY;
|
||||
|
||||
+ /* Populate our identity domain */
|
||||
+ if(Curl_override_sspi_http_realm((const char*)digest->input_token,
|
||||
+ &identity))
|
||||
+ return CURLE_OUT_OF_MEMORY;
|
||||
+
|
||||
/* Allow proper cleanup of the identity structure */
|
||||
p_identity = &identity;
|
||||
}
|
||||
diff --git a/lib/curl_sspi.h b/lib/curl_sspi.h
|
||||
index 7fa308c..8655715 100644
|
||||
--- a/lib/curl_sspi.h
|
||||
+++ b/lib/curl_sspi.h
|
||||
@@ -43,6 +43,10 @@
|
||||
CURLcode Curl_sspi_global_init(void);
|
||||
void Curl_sspi_global_cleanup(void);
|
||||
|
||||
+/* This is used to populate the domain in a SSPI identity structure */
|
||||
+CURLcode Curl_override_sspi_http_realm(const char *chlg,
|
||||
+ SEC_WINNT_AUTH_IDENTITY *identity);
|
||||
+
|
||||
/* This is used to generate an SSPI identity structure */
|
||||
CURLcode Curl_create_sspi_identity(const char *userp, const char *passwdp,
|
||||
SEC_WINNT_AUTH_IDENTITY *identity);
|
||||
--
|
||||
2.3.7.windows.1
|
||||
|
||||
@@ -6,7 +6,7 @@ _variant=-openssl
|
||||
_realname=curl
|
||||
pkgname="${MINGW_PACKAGE_PREFIX}-${_realname}"
|
||||
pkgver=7.42.1
|
||||
pkgrel=2
|
||||
pkgrel=3
|
||||
pkgdesc="An URL retrival utility and library. (mingw-w64)"
|
||||
arch=('any')
|
||||
url="http://curl.haxx.se"
|
||||
@@ -29,12 +29,14 @@ options=('staticlibs')
|
||||
source=("$url/download/${_realname}-$pkgver.tar.bz2"{,.asc}
|
||||
"0001-curl-relocation.patch"
|
||||
"0002-curl-mingw-enable-static.patch"
|
||||
"0003-curl-mingw-text-mode-for-netrc.patch")
|
||||
"0003-curl-mingw-text-mode-for-netrc.patch"
|
||||
"0004-sasl_sspi-Populate-domain-from-the-realm-in-the-chal.patch")
|
||||
md5sums=('296945012ce647b94083ed427c1877a8'
|
||||
'SKIP'
|
||||
'58520051c4ed77781d233c3fa40a5435'
|
||||
'eac9e212e619490966ae47004bec547b'
|
||||
'c35c31a1c8ed28c75be93e5bf95c8c9e')
|
||||
'c35c31a1c8ed28c75be93e5bf95c8c9e'
|
||||
'8d16dedc48b53f9406ab103a74889681')
|
||||
validpgpkeys=('914C533DF9B2ADA2204F586D78E11C6B279D5C91') # Daniel Stenberg
|
||||
|
||||
prepare() {
|
||||
@@ -43,6 +45,7 @@ prepare() {
|
||||
patch -p1 -i "${srcdir}/0001-curl-relocation.patch"
|
||||
patch -p1 -i "${srcdir}/0002-curl-mingw-enable-static.patch"
|
||||
patch -p1 -i "${srcdir}/0003-curl-mingw-text-mode-for-netrc.patch"
|
||||
patch -p1 -i "${srcdir}/0004-sasl_sspi-Populate-domain-from-the-realm-in-the-chal.patch"
|
||||
autoreconf -vfi
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user