mirror of
https://github.com/moparisthebest/curl
synced 2025-02-28 09:21:50 -05:00
Negotiate: fix for HTTP POST with Negotiate
* Adjusted unit tests 2056, 2057 * do not generally close connections with CURLAUTH_NEGOTIATE after every request * moved negotiatedata from UrlState to connectdata * Added stream rewind logic for CURLAUTH_NEGOTIATE * introduced negotiatedata::GSS_AUTHDONE and negotiatedata::GSS_AUTHSUCC * Consider authproblem state for CURLAUTH_NEGOTIATE * Consider reuse_forbid for CURLAUTH_NEGOTIATE * moved and adjusted negotiate authentication state handling from output_auth_headers into Curl_output_negotiate * Curl_output_negotiate: ensure auth done is always set * Curl_output_negotiate: Set auth done also if result code is GSS_S_CONTINUE_NEEDED/SEC_I_CONTINUE_NEEDED as this result code may also indicate the last challenge request (only works with disabled Expect: 100-continue and CURLOPT_KEEP_SENDING_ON_ERROR -> 1) * Consider "Persistent-Auth" header, detect if not present; Reset/Cleanup negotiate after authentication if no persistent authentication * apply changes introduced with #2546 for negotiate rewind logic Fixes #1261 Closes #1975
This commit is contained in:
parent
dd8a19f8a0
commit
6c60355323
116
lib/http.c
116
lib/http.c
@ -481,8 +481,36 @@ static CURLcode http_perhapsrewind(struct connectdata *conn)
|
||||
(curl_off_t)(expectsend - bytessent));
|
||||
}
|
||||
#endif
|
||||
#if defined(USE_SPNEGO)
|
||||
/* There is still data left to send */
|
||||
if((data->state.authproxy.picked == CURLAUTH_NEGOTIATE) ||
|
||||
(data->state.authhost.picked == CURLAUTH_NEGOTIATE)) {
|
||||
if(((expectsend - bytessent) < 2000) ||
|
||||
(conn->negotiate.state != GSS_AUTHNONE) ||
|
||||
(conn->proxyneg.state != GSS_AUTHNONE)) {
|
||||
/* The NEGOTIATE-negotiation has started *OR*
|
||||
there is just a little (<2K) data left to send, keep on sending. */
|
||||
|
||||
/* This is not NTLM or many bytes left to send: close */
|
||||
/* rewind data when completely done sending! */
|
||||
if(!conn->bits.authneg && (conn->writesockfd != CURL_SOCKET_BAD)) {
|
||||
conn->bits.rewindaftersend = TRUE;
|
||||
infof(data, "Rewind stream after send\n");
|
||||
}
|
||||
|
||||
return CURLE_OK;
|
||||
}
|
||||
|
||||
if(conn->bits.close)
|
||||
/* this is already marked to get closed */
|
||||
return CURLE_OK;
|
||||
|
||||
infof(data, "NEGOTIATE send, close instead of sending %"
|
||||
CURL_FORMAT_CURL_OFF_T " bytes\n",
|
||||
(curl_off_t)(expectsend - bytessent));
|
||||
}
|
||||
#endif
|
||||
|
||||
/* This is not NEGOTIATE/NTLM or many bytes left to send: close */
|
||||
streamclose(conn, "Mid-auth HTTP and much data left to send");
|
||||
data->req.size = 0; /* don't download any more than 0 bytes */
|
||||
|
||||
@ -600,10 +628,6 @@ output_auth_headers(struct connectdata *conn,
|
||||
#if !defined(CURL_DISABLE_VERBOSE_STRINGS) || defined(USE_SPNEGO)
|
||||
struct Curl_easy *data = conn->data;
|
||||
#endif
|
||||
#ifdef USE_SPNEGO
|
||||
struct negotiatedata *negdata = proxy ?
|
||||
&data->state.proxyneg : &data->state.negotiate;
|
||||
#endif
|
||||
|
||||
#ifdef CURL_DISABLE_CRYPTO_AUTH
|
||||
(void)request;
|
||||
@ -611,15 +635,11 @@ output_auth_headers(struct connectdata *conn,
|
||||
#endif
|
||||
|
||||
#ifdef USE_SPNEGO
|
||||
negdata->state = GSS_AUTHNONE;
|
||||
if((authstatus->picked == CURLAUTH_NEGOTIATE) &&
|
||||
negdata->context && !GSS_ERROR(negdata->status)) {
|
||||
if((authstatus->picked == CURLAUTH_NEGOTIATE)) {
|
||||
auth = "Negotiate";
|
||||
result = Curl_output_negotiate(conn, proxy);
|
||||
if(result)
|
||||
return result;
|
||||
authstatus->done = TRUE;
|
||||
negdata->state = GSS_AUTHSENT;
|
||||
}
|
||||
else
|
||||
#endif
|
||||
@ -796,7 +816,7 @@ CURLcode Curl_http_input_auth(struct connectdata *conn, bool proxy,
|
||||
|
||||
#ifdef USE_SPNEGO
|
||||
struct negotiatedata *negdata = proxy?
|
||||
&data->state.proxyneg:&data->state.negotiate;
|
||||
&conn->proxyneg:&conn->negotiate;
|
||||
#endif
|
||||
unsigned long *availp;
|
||||
struct auth *authp;
|
||||
@ -835,21 +855,18 @@ CURLcode Curl_http_input_auth(struct connectdata *conn, bool proxy,
|
||||
authp->avail |= CURLAUTH_NEGOTIATE;
|
||||
|
||||
if(authp->picked == CURLAUTH_NEGOTIATE) {
|
||||
if(negdata->state == GSS_AUTHSENT ||
|
||||
negdata->state == GSS_AUTHNONE) {
|
||||
CURLcode result = Curl_input_negotiate(conn, proxy, auth);
|
||||
if(!result) {
|
||||
DEBUGASSERT(!data->req.newurl);
|
||||
data->req.newurl = strdup(data->change.url);
|
||||
if(!data->req.newurl)
|
||||
return CURLE_OUT_OF_MEMORY;
|
||||
data->state.authproblem = FALSE;
|
||||
/* we received a GSS auth token and we dealt with it fine */
|
||||
negdata->state = GSS_AUTHRECV;
|
||||
}
|
||||
else
|
||||
data->state.authproblem = TRUE;
|
||||
CURLcode result = Curl_input_negotiate(conn, proxy, auth);
|
||||
if(!result) {
|
||||
DEBUGASSERT(!data->req.newurl);
|
||||
data->req.newurl = strdup(data->change.url);
|
||||
if(!data->req.newurl)
|
||||
return CURLE_OUT_OF_MEMORY;
|
||||
data->state.authproblem = FALSE;
|
||||
/* we received a GSS auth token and we dealt with it fine */
|
||||
negdata->state = GSS_AUTHRECV;
|
||||
}
|
||||
else
|
||||
data->state.authproblem = TRUE;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1555,20 +1572,6 @@ CURLcode Curl_http_done(struct connectdata *conn,
|
||||
|
||||
Curl_unencode_cleanup(conn);
|
||||
|
||||
#ifdef USE_SPNEGO
|
||||
if(data->state.proxyneg.state == GSS_AUTHSENT ||
|
||||
data->state.negotiate.state == GSS_AUTHSENT) {
|
||||
/* add forbid re-use if http-code != 401/407 as a WA only needed for
|
||||
* 401/407 that signal auth failure (empty) otherwise state will be RECV
|
||||
* with current code.
|
||||
* Do not close CONNECT_ONLY connections. */
|
||||
if((data->req.httpcode != 401) && (data->req.httpcode != 407) &&
|
||||
!data->set.connect_only)
|
||||
streamclose(conn, "Negotiate transfer completed");
|
||||
Curl_cleanup_negotiate(data);
|
||||
}
|
||||
#endif
|
||||
|
||||
/* set the proper values (possibly modified on POST) */
|
||||
conn->seek_func = data->set.seek_func; /* restore */
|
||||
conn->seek_client = data->set.seek_client; /* restore */
|
||||
@ -3376,7 +3379,24 @@ CURLcode Curl_http_readwrite_headers(struct Curl_easy *data,
|
||||
data->state.authproblem = TRUE;
|
||||
}
|
||||
#endif
|
||||
|
||||
#if defined(USE_SPNEGO)
|
||||
if(conn->bits.close &&
|
||||
(((data->req.httpcode == 401) &&
|
||||
(conn->negotiate.state == GSS_AUTHRECV)) ||
|
||||
((data->req.httpcode == 407) &&
|
||||
(conn->proxyneg.state == GSS_AUTHRECV)))) {
|
||||
infof(data, "Connection closure while negotiating auth (HTTP 1.0?)\n");
|
||||
data->state.authproblem = TRUE;
|
||||
}
|
||||
if((conn->negotiate.state == GSS_AUTHDONE) &&
|
||||
(data->req.httpcode != 401)) {
|
||||
conn->negotiate.state = GSS_AUTHSUCC;
|
||||
}
|
||||
if((conn->proxyneg.state == GSS_AUTHDONE) &&
|
||||
(data->req.httpcode != 407)) {
|
||||
conn->proxyneg.state = GSS_AUTHSUCC;
|
||||
}
|
||||
#endif
|
||||
/*
|
||||
* When all the headers have been parsed, see if we should give
|
||||
* up and return an error.
|
||||
@ -3953,6 +3973,22 @@ CURLcode Curl_http_readwrite_headers(struct Curl_easy *data,
|
||||
if(result)
|
||||
return result;
|
||||
}
|
||||
#ifdef USE_SPNEGO
|
||||
else if(checkprefix("Persistent-Auth", k->p)) {
|
||||
struct negotiatedata *negdata = &conn->negotiate;
|
||||
struct auth *authp = &data->state.authhost;
|
||||
if(authp->picked == CURLAUTH_NEGOTIATE) {
|
||||
char *persistentauth = Curl_copy_header_value(k->p);
|
||||
if(!persistentauth)
|
||||
return CURLE_OUT_OF_MEMORY;
|
||||
negdata->noauthpersist = checkprefix("false", persistentauth);
|
||||
negdata->havenoauthpersist = TRUE;
|
||||
infof(data, "Negotiate: noauthpersist -> %d, header part: %s",
|
||||
negdata->noauthpersist, persistentauth);
|
||||
free(persistentauth);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
else if((k->httpcode >= 300 && k->httpcode < 400) &&
|
||||
checkprefix("Location:", k->p) &&
|
||||
!data->req.location) {
|
||||
|
@ -56,7 +56,7 @@ CURLcode Curl_input_negotiate(struct connectdata *conn, bool proxy,
|
||||
service = data->set.str[STRING_PROXY_SERVICE_NAME] ?
|
||||
data->set.str[STRING_PROXY_SERVICE_NAME] : "HTTP";
|
||||
host = conn->http_proxy.host.name;
|
||||
neg_ctx = &data->state.proxyneg;
|
||||
neg_ctx = &conn->proxyneg;
|
||||
}
|
||||
else {
|
||||
userp = conn->user;
|
||||
@ -64,7 +64,7 @@ CURLcode Curl_input_negotiate(struct connectdata *conn, bool proxy,
|
||||
service = data->set.str[STRING_SERVICE_NAME] ?
|
||||
data->set.str[STRING_SERVICE_NAME] : "HTTP";
|
||||
host = conn->host.name;
|
||||
neg_ctx = &data->state.negotiate;
|
||||
neg_ctx = &conn->negotiate;
|
||||
}
|
||||
|
||||
/* Not set means empty */
|
||||
@ -80,11 +80,16 @@ CURLcode Curl_input_negotiate(struct connectdata *conn, bool proxy,
|
||||
header++;
|
||||
|
||||
len = strlen(header);
|
||||
neg_ctx->havenegdata = len != 0;
|
||||
if(!len) {
|
||||
/* Is this the first call in a new negotiation? */
|
||||
if(neg_ctx->context) {
|
||||
/* The server rejected our authentication and hasn't suppled any more
|
||||
if(neg_ctx->state == GSS_AUTHSUCC) {
|
||||
infof(conn->data, "Negotiate auth restarted\n");
|
||||
Curl_cleanup_negotiate(conn);
|
||||
}
|
||||
else if(neg_ctx->state != GSS_AUTHNONE) {
|
||||
/* The server rejected our authentication and hasn't supplied any more
|
||||
negotiation mechanisms */
|
||||
Curl_cleanup_negotiate(conn);
|
||||
return CURLE_LOGIN_DENIED;
|
||||
}
|
||||
}
|
||||
@ -106,38 +111,96 @@ CURLcode Curl_input_negotiate(struct connectdata *conn, bool proxy,
|
||||
|
||||
CURLcode Curl_output_negotiate(struct connectdata *conn, bool proxy)
|
||||
{
|
||||
struct negotiatedata *neg_ctx = proxy ? &conn->data->state.proxyneg :
|
||||
&conn->data->state.negotiate;
|
||||
struct negotiatedata *neg_ctx = proxy ? &conn->proxyneg :
|
||||
&conn->negotiate;
|
||||
struct auth *authp = proxy ? &conn->data->state.authproxy :
|
||||
&conn->data->state.authhost;
|
||||
char *base64 = NULL;
|
||||
size_t len = 0;
|
||||
char *userp;
|
||||
CURLcode result;
|
||||
|
||||
result = Curl_auth_create_spnego_message(conn->data, neg_ctx, &base64, &len);
|
||||
if(result)
|
||||
return result;
|
||||
authp->done = FALSE;
|
||||
|
||||
userp = aprintf("%sAuthorization: Negotiate %s\r\n", proxy ? "Proxy-" : "",
|
||||
base64);
|
||||
|
||||
if(proxy) {
|
||||
Curl_safefree(conn->allocptr.proxyuserpwd);
|
||||
conn->allocptr.proxyuserpwd = userp;
|
||||
if(neg_ctx->state == GSS_AUTHRECV) {
|
||||
if(neg_ctx->havenegdata) {
|
||||
neg_ctx->havemultiplerequests = TRUE;
|
||||
}
|
||||
}
|
||||
else {
|
||||
Curl_safefree(conn->allocptr.userpwd);
|
||||
conn->allocptr.userpwd = userp;
|
||||
else if(neg_ctx->state == GSS_AUTHSUCC) {
|
||||
if(!neg_ctx->havenoauthpersist) {
|
||||
neg_ctx->noauthpersist = !neg_ctx->havemultiplerequests;
|
||||
}
|
||||
}
|
||||
|
||||
free(base64);
|
||||
if(neg_ctx->noauthpersist ||
|
||||
(neg_ctx->state != GSS_AUTHDONE && neg_ctx->state != GSS_AUTHSUCC)) {
|
||||
|
||||
return (userp == NULL) ? CURLE_OUT_OF_MEMORY : CURLE_OK;
|
||||
if(neg_ctx->noauthpersist && neg_ctx->state == GSS_AUTHSUCC) {
|
||||
infof(conn->data, "Curl_output_negotiate, "
|
||||
"no persistent authentication: cleanup existing context");
|
||||
Curl_auth_spnego_cleanup(neg_ctx);
|
||||
}
|
||||
if(!neg_ctx->context) {
|
||||
result = Curl_input_negotiate(conn, proxy, "Negotiate");
|
||||
if(result)
|
||||
return result;
|
||||
}
|
||||
|
||||
result = Curl_auth_create_spnego_message(conn->data,
|
||||
neg_ctx, &base64, &len);
|
||||
if(result)
|
||||
return result;
|
||||
|
||||
userp = aprintf("%sAuthorization: Negotiate %s\r\n", proxy ? "Proxy-" : "",
|
||||
base64);
|
||||
|
||||
if(proxy) {
|
||||
Curl_safefree(conn->allocptr.proxyuserpwd);
|
||||
conn->allocptr.proxyuserpwd = userp;
|
||||
}
|
||||
else {
|
||||
Curl_safefree(conn->allocptr.userpwd);
|
||||
conn->allocptr.userpwd = userp;
|
||||
}
|
||||
|
||||
free(base64);
|
||||
|
||||
if(userp == NULL) {
|
||||
return CURLE_OUT_OF_MEMORY;
|
||||
}
|
||||
|
||||
neg_ctx->state = GSS_AUTHSENT;
|
||||
#ifdef HAVE_GSSAPI
|
||||
if(neg_ctx->status == GSS_S_COMPLETE ||
|
||||
neg_ctx->status == GSS_S_CONTINUE_NEEDED) {
|
||||
neg_ctx->state = GSS_AUTHDONE;
|
||||
}
|
||||
#else
|
||||
#ifdef USE_WINDOWS_SSPI
|
||||
if(neg_ctx->status == SEC_E_OK ||
|
||||
neg_ctx->status == SEC_I_CONTINUE_NEEDED) {
|
||||
neg_ctx->state = GSS_AUTHDONE;
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
}
|
||||
|
||||
if(neg_ctx->state == GSS_AUTHDONE || neg_ctx->state == GSS_AUTHSUCC) {
|
||||
/* connection is already authenticated,
|
||||
* don't send a header in future requests */
|
||||
authp->done = TRUE;
|
||||
}
|
||||
|
||||
neg_ctx->havenegdata = FALSE;
|
||||
|
||||
return CURLE_OK;
|
||||
}
|
||||
|
||||
void Curl_cleanup_negotiate(struct Curl_easy *data)
|
||||
void Curl_cleanup_negotiate(struct connectdata *conn)
|
||||
{
|
||||
Curl_auth_spnego_cleanup(&data->state.negotiate);
|
||||
Curl_auth_spnego_cleanup(&data->state.proxyneg);
|
||||
Curl_auth_spnego_cleanup(&conn->negotiate);
|
||||
Curl_auth_spnego_cleanup(&conn->proxyneg);
|
||||
}
|
||||
|
||||
#endif /* !CURL_DISABLE_HTTP && USE_SPNEGO */
|
||||
|
@ -7,7 +7,7 @@
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 1998 - 2015, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
* Copyright (C) 1998 - 2019, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
*
|
||||
* This software is licensed as described in the file COPYING, which
|
||||
* you should have received as part of this distribution. The terms
|
||||
@ -31,7 +31,7 @@ CURLcode Curl_input_negotiate(struct connectdata *conn, bool proxy,
|
||||
/* this is for creating Negotiate header output */
|
||||
CURLcode Curl_output_negotiate(struct connectdata *conn, bool proxy);
|
||||
|
||||
void Curl_cleanup_negotiate(struct Curl_easy *data);
|
||||
void Curl_cleanup_negotiate(struct connectdata *conn);
|
||||
|
||||
#endif /* USE_SPNEGO */
|
||||
|
||||
|
@ -600,7 +600,7 @@ static CURLcode multi_done(struct Curl_easy *data,
|
||||
|
||||
/* if data->set.reuse_forbid is TRUE, it means the libcurl client has
|
||||
forced us to close this connection. This is ignored for requests taking
|
||||
place in a NTLM authentication handshake
|
||||
place in a NTLM/NEGOTIATE authentication handshake
|
||||
|
||||
if conn->bits.close is TRUE, it means that the connection should be
|
||||
closed in spite of all our efforts to be nice, due to protocol
|
||||
@ -617,6 +617,10 @@ static CURLcode multi_done(struct Curl_easy *data,
|
||||
#if defined(USE_NTLM)
|
||||
&& !(conn->ntlm.state == NTLMSTATE_TYPE2 ||
|
||||
conn->proxyntlm.state == NTLMSTATE_TYPE2)
|
||||
#endif
|
||||
#if defined(USE_SPNEGO)
|
||||
&& !(conn->negotiate.state == GSS_AUTHRECV ||
|
||||
conn->proxyneg.state == GSS_AUTHRECV)
|
||||
#endif
|
||||
) || conn->bits.close
|
||||
|| (premature && !(conn->handler->flags & PROTOPT_STREAM))) {
|
||||
|
@ -806,6 +806,10 @@ CURLcode Curl_disconnect(struct Curl_easy *data,
|
||||
/* Cleanup NTLM connection-related data */
|
||||
Curl_http_ntlm_cleanup(conn);
|
||||
#endif
|
||||
#if !defined(CURL_DISABLE_HTTP) && defined(USE_SPNEGO)
|
||||
/* Cleanup NEGOTIATE connection-related data */
|
||||
Curl_cleanup_negotiate(conn);
|
||||
#endif
|
||||
|
||||
/* the protocol specific disconnect handler and conn_shutdown need a transfer
|
||||
for the connection! */
|
||||
|
@ -358,7 +358,9 @@ struct ntlmdata {
|
||||
struct negotiatedata {
|
||||
/* When doing Negotiate (SPNEGO) auth, we first need to send a token
|
||||
and then validate the received one. */
|
||||
enum { GSS_AUTHNONE, GSS_AUTHRECV, GSS_AUTHSENT } state;
|
||||
enum {
|
||||
GSS_AUTHNONE, GSS_AUTHRECV, GSS_AUTHSENT, GSS_AUTHDONE, GSS_AUTHSUCC
|
||||
} state;
|
||||
#ifdef HAVE_GSSAPI
|
||||
OM_uint32 status;
|
||||
gss_ctx_id_t context;
|
||||
@ -380,6 +382,10 @@ struct negotiatedata {
|
||||
size_t output_token_length;
|
||||
#endif
|
||||
#endif
|
||||
bool noauthpersist;
|
||||
bool havenoauthpersist;
|
||||
bool havenegdata;
|
||||
bool havemultiplerequests;
|
||||
};
|
||||
#endif
|
||||
|
||||
@ -977,6 +983,11 @@ struct connectdata {
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifdef USE_SPNEGO
|
||||
struct negotiatedata negotiate; /* state data for host Negotiate auth */
|
||||
struct negotiatedata proxyneg; /* state data for proxy Negotiate auth */
|
||||
#endif
|
||||
|
||||
/* data used for the asynch name resolve callback */
|
||||
struct Curl_async async;
|
||||
|
||||
@ -1274,11 +1285,6 @@ struct UrlState {
|
||||
struct digestdata digest; /* state data for host Digest auth */
|
||||
struct digestdata proxydigest; /* state data for proxy Digest auth */
|
||||
|
||||
#ifdef USE_SPNEGO
|
||||
struct negotiatedata negotiate; /* state data for host Negotiate auth */
|
||||
struct negotiatedata proxyneg; /* state data for proxy Negotiate auth */
|
||||
#endif
|
||||
|
||||
struct auth authhost; /* auth details for host */
|
||||
struct auth authproxy; /* auth details for proxy */
|
||||
|
||||
|
@ -5,7 +5,7 @@
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 1998 - 2016, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
* Copyright (C) 1998 - 2019, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
*
|
||||
* This software is licensed as described in the file COPYING, which
|
||||
* you should have received as part of this distribution. The terms
|
||||
@ -273,6 +273,11 @@ void Curl_auth_spnego_cleanup(struct negotiatedata *nego)
|
||||
|
||||
/* Reset any variables */
|
||||
nego->status = 0;
|
||||
nego->state = GSS_AUTHNONE;
|
||||
nego->noauthpersist = FALSE;
|
||||
nego->havenoauthpersist = FALSE;
|
||||
nego->havenegdata = FALSE;
|
||||
nego->havemultiplerequests = FALSE;
|
||||
}
|
||||
|
||||
#endif /* HAVE_GSSAPI && USE_SPNEGO */
|
||||
|
@ -343,6 +343,11 @@ void Curl_auth_spnego_cleanup(struct negotiatedata *nego)
|
||||
/* Reset any variables */
|
||||
nego->status = 0;
|
||||
nego->token_max = 0;
|
||||
nego->state = GSS_AUTHNONE;
|
||||
nego->noauthpersist = FALSE;
|
||||
nego->havenoauthpersist = FALSE;
|
||||
nego->havenegdata = FALSE;
|
||||
nego->havemultiplerequests = FALSE;
|
||||
}
|
||||
|
||||
#endif /* USE_WINDOWS_SSPI && USE_SPNEGO */
|
||||
|
@ -8,17 +8,7 @@ HTTP Negotiate auth (stub krb5)
|
||||
</info>
|
||||
# Server-side
|
||||
<reply>
|
||||
<!-- First request, expect 401 Negotiate -->
|
||||
<data>
|
||||
HTTP/1.1 401 Authorization Required
|
||||
Server: Microsoft-IIS/7.0
|
||||
Content-Type: text/html; charset=iso-8859-1
|
||||
WWW-Authenticate: Negotiate
|
||||
Content-Length: 13
|
||||
|
||||
Not yet sir!
|
||||
</data>
|
||||
<!-- Second request, expect success in one shot -->
|
||||
<!-- First request, expect success in one shot -->
|
||||
<data1>
|
||||
HTTP/1.1 200 Things are fine in server land
|
||||
Server: Microsoft-IIS/7.0
|
||||
@ -29,12 +19,6 @@ Content-Length: 15
|
||||
Nice auth sir!
|
||||
</data1>
|
||||
<datacheck>
|
||||
HTTP/1.1 401 Authorization Required
|
||||
Server: Microsoft-IIS/7.0
|
||||
Content-Type: text/html; charset=iso-8859-1
|
||||
WWW-Authenticate: Negotiate
|
||||
Content-Length: 13
|
||||
|
||||
HTTP/1.1 200 Things are fine in server land
|
||||
Server: Microsoft-IIS/7.0
|
||||
Content-Type: text/html; charset=iso-8859-1
|
||||
@ -73,10 +57,6 @@ CURL_STUB_GSS_CREDS="KRB5_Alice"
|
||||
^User-Agent:.*
|
||||
</strip>
|
||||
<protocol>
|
||||
GET /2056 HTTP/1.1
|
||||
Host: %HOSTIP:%HTTPPORT
|
||||
Accept: */*
|
||||
|
||||
GET /2056 HTTP/1.1
|
||||
Host: %HOSTIP:%HTTPPORT
|
||||
Authorization: Negotiate IktSQjVfQWxpY2UiOkhUVFBAMTI3LjAuMC4xOjE6QUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQQ==
|
||||
|
@ -8,17 +8,7 @@ HTTP Negotiate auth (stub ntlm)
|
||||
</info>
|
||||
# Server-side
|
||||
<reply>
|
||||
<!-- First request, expect 401 Negotiate -->
|
||||
<data>
|
||||
HTTP/1.1 401 Authorization Required
|
||||
Server: Microsoft-IIS/7.0
|
||||
Content-Type: text/html; charset=iso-8859-1
|
||||
WWW-Authenticate: Negotiate
|
||||
Content-Length: 13
|
||||
|
||||
Not yet sir!
|
||||
</data>
|
||||
<!-- Second request, expect 401 (ntlm challenge) -->
|
||||
<!-- First request, expect 401 (ntlm challenge) -->
|
||||
<data1>
|
||||
HTTP/1.1 401 Authorization Required
|
||||
Server: Microsoft-IIS/7.0
|
||||
@ -28,7 +18,7 @@ Content-Length: 19
|
||||
|
||||
Still not yet sir!
|
||||
</data1>
|
||||
<!-- Third request, expect success -->
|
||||
<!-- Second request, expect success -->
|
||||
<data2>
|
||||
HTTP/1.1 200 Things are fine in server land
|
||||
Server: Microsoft-IIS/7.0
|
||||
@ -39,12 +29,6 @@ Content-Length: 15
|
||||
Nice auth sir!
|
||||
</data2>
|
||||
<datacheck>
|
||||
HTTP/1.1 401 Authorization Required
|
||||
Server: Microsoft-IIS/7.0
|
||||
Content-Type: text/html; charset=iso-8859-1
|
||||
WWW-Authenticate: Negotiate
|
||||
Content-Length: 13
|
||||
|
||||
HTTP/1.1 401 Authorization Required
|
||||
Server: Microsoft-IIS/7.0
|
||||
Content-Type: text/html; charset=iso-8859-1
|
||||
@ -89,10 +73,6 @@ CURL_STUB_GSS_CREDS="NTLM_Alice"
|
||||
^User-Agent:.*
|
||||
</strip>
|
||||
<protocol>
|
||||
GET /2057 HTTP/1.1
|
||||
Host: %HOSTIP:%HTTPPORT
|
||||
Accept: */*
|
||||
|
||||
GET /2057 HTTP/1.1
|
||||
Host: %HOSTIP:%HTTPPORT
|
||||
Authorization: Negotiate Ik5UTE1fQWxpY2UiOkhUVFBAMTI3LjAuMC4xOjI6QUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQQ==
|
||||
|
Loading…
x
Reference in New Issue
Block a user