curl-library
Re: [PATCH] SF bug #1302: HTTP Auth Negotiate sends Kerberos token instead of SPNEGO token
Date: Tue, 15 Jul 2014 14:26:47 +0100
On Tue, 2014-07-15 at 14:53 +0200, Michael Osipov wrote:
> While you are right about "add half of this back again", it not just
> like add that enum and you are done. I you must add the define for the
> CURLAUTH_, add CURL_VERSION_, register both at the appropriate spots,
> add the command line options, etc. That might result in an additional
> series of commits. That's why I have abstained from.
I didn't mean going that far. I meant just this much...
This is tested on Windows and Linux as far as I can — I don't have a
server which offers 'WWW-Authenticate: Kerberos' but I've tested the
non-SPNEGO path in both cases and it works correctly, using *only*
Kerberos and thus failing to authenticate to hosts where NTLM fallback
is required.
From 5109cf90206eb26c69d48d205a4689fbd404e9c2 Mon Sep 17 00:00:00 2001
From: David Woodhouse <David.Woodhouse_at_intel.com>
Date: Tue, 15 Jul 2014 14:23:12 +0100
Subject: [PATCH] Support WWW-Authenticate: Kerberos in place of defunct
GSS-Negotiate
Based on a patch from Michael Osipov <1983-01-06_at_gmx.net> which just removed
GSS-Negotiate.
---
lib/http.c | 2 +-
lib/http_negotiate.c | 34 ++++++++++------------------------
lib/http_negotiate_sspi.c | 39 ++++++++++++---------------------------
lib/urldata.h | 2 +-
4 files changed, 24 insertions(+), 53 deletions(-)
diff --git a/lib/http.c b/lib/http.c
index 4931dd8..56c0616 100644
--- a/lib/http.c
+++ b/lib/http.c
@@ -772,7 +772,7 @@ CURLcode Curl_http_input_auth(struct connectdata *conn, bool proxy,
while(*auth) {
#ifdef USE_HTTP_NEGOTIATE
- if(checkprefix("GSS-Negotiate", auth) ||
+ if(checkprefix("Kerberos", auth) ||
checkprefix("Negotiate", auth)) {
int neg;
*availp |= CURLAUTH_GSSNEGOTIATE;
diff --git a/lib/http_negotiate.c b/lib/http_negotiate.c
index bbad0b4..d4ae741 100644
--- a/lib/http_negotiate.c
+++ b/lib/http_negotiate.c
@@ -53,26 +53,12 @@ get_gss_name(struct connectdata *conn, bool proxy, gss_name_t *server)
OM_uint32 major_status, minor_status;
gss_buffer_desc token = GSS_C_EMPTY_BUFFER;
char name[2048];
- const char* service;
- /* GSSAPI implementation by Globus (known as GSI) requires the name to be
- of form "<service>/<fqdn>" instead of <service>@<fqdn> (ie. slash instead
- of at-sign). Also GSI servers are often identified as 'host' not 'khttp'.
- Change following lines if you want to use GSI */
-
- /* IIS uses the <service>@<fqdn> form but uses 'http' as the service name */
-
- if(neg_ctx->gss)
- service = "KHTTP";
- else
- service = "HTTP";
-
- token.length = strlen(service) + 1 + strlen(proxy ? conn->proxy.name :
- conn->host.name) + 1;
+ token.length = 5 + strlen(proxy ? conn->proxy.name : conn->host.name) + 1;
if(token.length + 1 > sizeof(name))
return EMSGSIZE;
- snprintf(name, sizeof(name), "%s@%s", service, proxy ? conn->proxy.name :
+ snprintf(name, sizeof(name), "HTTP@%s", proxy ? conn->proxy.name :
conn->host.name);
token.value = (void *) name;
@@ -128,29 +114,29 @@ int Curl_input_negotiate(struct connectdata *conn, bool proxy,
int ret;
size_t len;
size_t rawlen = 0;
- bool gss;
+ bool spnego;
const char* protocol;
CURLcode error;
- if(checkprefix("GSS-Negotiate", header)) {
- protocol = "GSS-Negotiate";
- gss = TRUE;
+ if(checkprefix("Kerberos", header)) {
+ protocol = "Kerberos";
+ spnego = FALSE;
}
else if(checkprefix("Negotiate", header)) {
protocol = "Negotiate";
- gss = FALSE;
+ spnego = TRUE;
}
else
return -1;
if(neg_ctx->context) {
- if(neg_ctx->gss != gss) {
+ if(neg_ctx->spnego != spnego) {
return -1;
}
}
else {
neg_ctx->protocol = protocol;
- neg_ctx->gss = gss;
+ neg_ctx->spnego = spnego;
}
if(neg_ctx->context && neg_ctx->status == GSS_S_COMPLETE) {
@@ -184,7 +170,7 @@ int Curl_input_negotiate(struct connectdata *conn, bool proxy,
&minor_status,
&neg_ctx->context,
neg_ctx->server_name,
- TRUE,
+ spnego,
GSS_C_NO_CHANNEL_BINDINGS,
&input_token,
&output_token,
diff --git a/lib/http_negotiate_sspi.c b/lib/http_negotiate_sspi.c
index 236766b..8bccaea 100644
--- a/lib/http_negotiate_sspi.c
+++ b/lib/http_negotiate_sspi.c
@@ -52,27 +52,12 @@ get_gss_name(struct connectdata *conn, bool proxy,
/* proxy auth requested but no given proxy name, error out! */
return -1;
- /* GSSAPI implementation by Globus (known as GSI) requires the name to be
- of form "<service>/<fqdn>" instead of <service>@<fqdn> (ie. slash instead
- of at-sign). Also GSI servers are often identified as 'host' not 'khttp'.
- Change following lines if you want to use GSI */
-
- /* IIS uses the <service>@<fqdn> form but uses 'http' as the service name,
- and SSPI then generates an NTLM token. When using <service>/<fqdn> a
- Kerberos token is generated. */
-
- if(neg_ctx->gss)
- service = "KHTTP";
- else
- service = "HTTP";
-
- length = strlen(service) + 1 + strlen(proxy ? conn->proxy.name :
- conn->host.name) + 1;
+ length = 5 + strlen(proxy ? conn->proxy.name : conn->host.name) + 1;
if(length + 1 > sizeof(neg_ctx->server_name))
return EMSGSIZE;
- snprintf(neg_ctx->server_name, sizeof(neg_ctx->server_name), "%s/%s",
- service, proxy ? conn->proxy.name : conn->host.name);
+ snprintf(neg_ctx->server_name, sizeof(neg_ctx->server_name), "HTTP/%s",
+ proxy ? conn->proxy.name : conn->host.name);
return 0;
}
@@ -94,29 +79,29 @@ int Curl_input_negotiate(struct connectdata *conn, bool proxy,
TCHAR *sname;
int ret;
size_t len = 0, input_token_len = 0;
- bool gss = FALSE;
+ bool spnego = FALSE;
const char* protocol;
CURLcode error;
- if(checkprefix("GSS-Negotiate", header)) {
- protocol = "GSS-Negotiate";
- gss = TRUE;
+ if(checkprefix("Kerberos", header)) {
+ protocol = "Kerberos";
+ spnego = FALSE;
}
else if(checkprefix("Negotiate", header)) {
protocol = "Negotiate";
- gss = FALSE;
+ spnego = TRUE;
}
else
return -1;
if(neg_ctx->context) {
- if(neg_ctx->gss != gss) {
+ if(neg_ctx->spnego != spnego) {
return -1;
}
}
else {
neg_ctx->protocol = protocol;
- neg_ctx->gss = gss;
+ neg_ctx->spnego = spnego;
}
if(neg_ctx->context && neg_ctx->status == SEC_E_OK) {
@@ -135,7 +120,7 @@ int Curl_input_negotiate(struct connectdata *conn, bool proxy,
if(!neg_ctx->output_token) {
PSecPkgInfo SecurityPackage;
- ret = s_pSecFn->QuerySecurityPackageInfo((TCHAR *) TEXT("Negotiate"),
+ ret = s_pSecFn->QuerySecurityPackageInfo((TCHAR *) TEXT(protocol),
&SecurityPackage);
if(ret != SEC_E_OK)
return -1;
@@ -165,7 +150,7 @@ int Curl_input_negotiate(struct connectdata *conn, bool proxy,
neg_ctx->status =
s_pSecFn->AcquireCredentialsHandle(NULL,
- (TCHAR *) TEXT("Negotiate"),
+ (TCHAR *) TEXT(protocol),
SECPKG_CRED_OUTBOUND, NULL, NULL,
NULL, NULL, neg_ctx->credentials,
&lifetime);
diff --git a/lib/urldata.h b/lib/urldata.h
index ebdad80..827cb9d 100644
--- a/lib/urldata.h
+++ b/lib/urldata.h
@@ -449,7 +449,7 @@ struct negotiatedata {
/* when doing Negotiate we first need to receive an auth token and then we
need to send our header */
enum { GSS_AUTHNONE, GSS_AUTHRECV, GSS_AUTHSENT } state;
- bool gss; /* Whether we're processing GSS-Negotiate or Negotiate */
+ bool spnego; /* Whether we're processing Kerberos or Negotiate */
const char* protocol; /* "GSS-Negotiate" or "Negotiate" */
#ifdef HAVE_GSSAPI
OM_uint32 status;
--
1.9.3
--
dwmw2
-------------------------------------------------------------------
List admin: http://cool.haxx.se/list/listinfo/curl-library
Etiquette: http://curl.haxx.se/mail/etiquette.html
- application/x-pkcs7-signature attachment: smime.p7s