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