1
0
mirror of https://github.com/moparisthebest/curl synced 2024-12-21 23:58:49 -05:00

- Christian Krause filed bug #2221237

(http://curl.haxx.se/bug/view.cgi?id=2221237) that identified an infinite
  loop during GSS authentication given some specific conditions. With his
  patience and great feedback I managed to narrow down the problem and
  eventually fix it although I can't test any of this myself!
This commit is contained in:
Daniel Stenberg 2008-12-08 13:52:20 +00:00
parent dff4ce92ad
commit 42365aa7ef
4 changed files with 44 additions and 17 deletions

View File

@ -6,6 +6,13 @@
Changelog Changelog
Daniel Stenberg (8 Dec 2008)
- Christian Krause filed bug #2221237
(http://curl.haxx.se/bug/view.cgi?id=2221237) that identified an infinite
loop during GSS authentication given some specific conditions. With his
patience and great feedback I managed to narrow down the problem and
eventually fix it although I can't test any of this myself!
Daniel Fandrich (3 Dec 2008) Daniel Fandrich (3 Dec 2008)
- Fixed the getifaddrs version of Curl_if2ip to work on systems without IPv6 - Fixed the getifaddrs version of Curl_if2ip to work on systems without IPv6
support (e.g. Minix) support (e.g. Minix)

View File

@ -24,6 +24,7 @@ This release includes the following bugfixes:
o fix SCP/SFTP busyloop by using a new libssh2 0.19 function o fix SCP/SFTP busyloop by using a new libssh2 0.19 function
o bad fclose() after a fatal error in cookie code o bad fclose() after a fatal error in cookie code
o curl_multi_remove_handle() when the handle was in use in a HTTP pipeline o curl_multi_remove_handle() when the handle was in use in a HTTP pipeline
o GSS authentication infinite loop problem
This release includes the following known bugs: This release includes the following known bugs:

View File

@ -507,8 +507,8 @@ CURLcode Curl_http_auth_act(struct connectdata *conn)
static CURLcode static CURLcode
output_auth_headers(struct connectdata *conn, output_auth_headers(struct connectdata *conn,
struct auth *authstatus, struct auth *authstatus,
const char *request, const char *request,
const char *path, const char *path,
bool proxy) bool proxy)
{ {
struct SessionHandle *data = conn->data; struct SessionHandle *data = conn->data;
@ -529,6 +529,7 @@ output_auth_headers(struct connectdata *conn,
if(result) if(result)
return result; return result;
authstatus->done = TRUE; authstatus->done = TRUE;
data->state.negotiate.state = GSS_AUTHSENT;
} }
else else
#endif #endif
@ -545,9 +546,9 @@ output_auth_headers(struct connectdata *conn,
if(authstatus->picked == CURLAUTH_DIGEST) { if(authstatus->picked == CURLAUTH_DIGEST) {
auth="Digest"; auth="Digest";
result = Curl_output_digest(conn, result = Curl_output_digest(conn,
proxy, proxy,
(const unsigned char *)request, (const unsigned char *)request,
(const unsigned char *)path); (const unsigned char *)path);
if(result) if(result)
return result; return result;
} }
@ -562,7 +563,7 @@ output_auth_headers(struct connectdata *conn,
auth="Basic"; auth="Basic";
result = http_output_basic(conn, proxy); result = http_output_basic(conn, proxy);
if(result) if(result)
return result; return result;
} }
/* NOTE: this function should set 'done' TRUE, as the other auth /* NOTE: this function should set 'done' TRUE, as the other auth
functions work that way */ functions work that way */
@ -571,9 +572,9 @@ output_auth_headers(struct connectdata *conn,
if(auth) { if(auth) {
infof(data, "%s auth using %s with user '%s'\n", infof(data, "%s auth using %s with user '%s'\n",
proxy?"Proxy":"Server", auth, proxy?"Proxy":"Server", auth,
proxy?(conn->proxyuser?conn->proxyuser:""): proxy?(conn->proxyuser?conn->proxyuser:""):
(conn->user?conn->user:"")); (conn->user?conn->user:""));
authstatus->multi = (bool)(!authstatus->done); authstatus->multi = (bool)(!authstatus->done);
} }
else else
@ -707,24 +708,39 @@ CURLcode Curl_http_input_auth(struct connectdata *conn,
* If the provided authentication is wanted as one out of several accepted * If the provided authentication is wanted as one out of several accepted
* types (using &), we OR this authentication type to the authavail * types (using &), we OR this authentication type to the authavail
* variable. * variable.
*
* Note:
*
* ->picked is first set to the 'want' value (one or more bits) before the
* request is sent, and then it is again set _after_ all response 401/407
* headers have been received but then only to a single preferred method
* (bit).
*
*/ */
#ifdef HAVE_GSSAPI #ifdef HAVE_GSSAPI
if(checkprefix("GSS-Negotiate", start) || if(checkprefix("GSS-Negotiate", start) ||
checkprefix("Negotiate", start)) { checkprefix("Negotiate", start)) {
int neg;
*availp |= CURLAUTH_GSSNEGOTIATE; *availp |= CURLAUTH_GSSNEGOTIATE;
authp->avail |= CURLAUTH_GSSNEGOTIATE; authp->avail |= CURLAUTH_GSSNEGOTIATE;
if(authp->picked == CURLAUTH_GSSNEGOTIATE) {
/* if exactly this is wanted, go */ if(data->state.negotiate.state == GSS_AUTHSENT) {
int neg = Curl_input_negotiate(conn, (bool)(httpcode == 407), start); /* if we sent GSS authentication in the outgoing request and we get this
back, we're in trouble */
infof(data, "Authentication problem. Ignoring this.\n");
data->state.authproblem = TRUE;
}
else {
neg = Curl_input_negotiate(conn, (bool)(httpcode == 407), start);
if(neg == 0) { if(neg == 0) {
DEBUGASSERT(!data->req.newurl); DEBUGASSERT(!data->req.newurl);
data->req.newurl = strdup(data->change.url); data->req.newurl = strdup(data->change.url);
data->state.authproblem = (data->req.newurl == NULL); if(!data->req.newurl)
} return CURLE_OUT_OF_MEMORY;
else { data->state.authproblem = FALSE;
infof(data, "Authentication problem. Ignoring this.\n"); /* we received GSS auth info and we dealt with it fine */
data->state.authproblem = TRUE; data->state.negotiate.state = GSS_AUTHRECV;
} }
} }
} }

View File

@ -299,6 +299,9 @@ struct ntlmdata {
#ifdef HAVE_GSSAPI #ifdef HAVE_GSSAPI
struct negotiatedata { 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 gss; /* Whether we're processing GSS-Negotiate or Negotiate */
const char* protocol; /* "GSS-Negotiate" or "Negotiate" */ const char* protocol; /* "GSS-Negotiate" or "Negotiate" */
OM_uint32 status; OM_uint32 status;