diff options
| -rw-r--r-- | CHANGES | 5 | ||||
| -rw-r--r-- | RELEASE-NOTES | 5 | ||||
| -rw-r--r-- | docs/curl.1 | 11 | ||||
| -rw-r--r-- | lib/http.c | 16 | ||||
| -rw-r--r-- | lib/http_negotiate.c | 14 | ||||
| -rw-r--r-- | lib/http_negotiate.h | 4 | ||||
| -rw-r--r-- | src/main.c | 11 | 
7 files changed, 54 insertions, 12 deletions
| @@ -6,6 +6,11 @@                                    Changelog +Daniel S (21 September 2007) +- Mark Davies fixed Negotiate authentication over proxy, and also introduced +  the --proxy-negotiate command line option to allow a user to explicitly +  select it. +  Daniel S (19 September 2007)  - Rob Crittenden provided an NSS update with the following highlights: diff --git a/RELEASE-NOTES b/RELEASE-NOTES index c54f0162d..dcd863554 100644 --- a/RELEASE-NOTES +++ b/RELEASE-NOTES @@ -13,6 +13,7 @@ This release includes the following changes:   o automatically append ";type=<a|i>" when using HTTP proxies for FTP urls   o improved NSS support + o added --proxy-negotiate  This release includes the following bugfixes: @@ -20,6 +21,7 @@ This release includes the following bugfixes:   o ldapv3 support on Windows   o ldap builds with the MSVC makefiles   o no HOME and no key given caused SSH auth failure + o Negotiate authentication over proxy  This release includes the following known bugs: @@ -36,6 +38,7 @@ New curl mirrors:  This release would not have looked like this without help, code, reports and  advice from friends like these: - Dan Fandrich, Michal Marek, Günter Knauf, Rob Crittenden, Immanuel Gregoire + Dan Fandrich, Michal Marek, Günter Knauf, Rob Crittenden, Immanuel Gregoire, + Mark Davies          Thanks! (and sorry if I forgot to mention someone) diff --git a/docs/curl.1 b/docs/curl.1 index 2b1736998..fc2cc13e3 100644 --- a/docs/curl.1 +++ b/docs/curl.1 @@ -774,6 +774,9 @@ meant as a support for Kerberos5 authentication but may be also used along  with another authentication methods. For more information see IETF draft  draft-brezak-spnego-http-04.txt. +If you want to enable Negotiate for your proxy authentication, then use +\fI--proxy-negotiate\fP. +  This option requires that the library was built with GSSAPI support. This is  not very common. Use \fI-V/--version\fP to see if your version supports  GSS-Negotiate. @@ -863,6 +866,14 @@ Tells curl to use HTTP Digest authentication when communicating with the given  proxy. Use \fI--digest\fP for enabling HTTP Digest with a remote host.  If this option is used twice, the second will again disable proxy HTTP Digest. +.IP "--proxy-negotiate" +Tells curl to use HTTP Negotiate authentication when communicating +with the given proxy. Use \fI--negotiate\fP for enabling HTTP Negotiate +with a remote host. + +If this option is used twice, the second will again disable proxy HTTP +Negotiate. +  .IP "--proxy-ntlm"  Tells curl to use HTTP NTLM authentication when communicating with the given  proxy. Use \fI--ntlm\fP for enabling NTLM with a remote host. diff --git a/lib/http.c b/lib/http.c index 090aad3d2..67b2d3f55 100644 --- a/lib/http.c +++ b/lib/http.c @@ -424,6 +424,18 @@ Curl_http_output_auth(struct connectdata *conn,    /* Send proxy authentication header if needed */    if (conn->bits.httpproxy &&        (conn->bits.tunnel_proxy == proxytunnel)) { +#ifdef HAVE_GSSAPI +    if((authproxy->picked == CURLAUTH_GSSNEGOTIATE) && +       data->state.negotiate.context && +       !GSS_ERROR(data->state.negotiate.status)) { +      auth="GSS-Negotiate"; +      result = Curl_output_negotiate(conn, TRUE); +      if (result) +        return result; +      authproxy->done = TRUE; +    }  +    else +#endif  #ifdef USE_NTLM      if(authproxy->picked == CURLAUTH_NTLM) {        auth="NTLM"; @@ -486,7 +498,7 @@ Curl_http_output_auth(struct connectdata *conn,           data->state.negotiate.context &&           !GSS_ERROR(data->state.negotiate.status)) {          auth="GSS-Negotiate"; -        result = Curl_output_negotiate(conn); +        result = Curl_output_negotiate(conn, FALSE);          if (result)            return result;          authhost->done = TRUE; @@ -593,7 +605,7 @@ CURLcode Curl_http_input_auth(struct connectdata *conn,      authp->avail |= CURLAUTH_GSSNEGOTIATE;      if(authp->picked == CURLAUTH_GSSNEGOTIATE) {        /* if exactly this is wanted, go */ -      int neg = Curl_input_negotiate(conn, start); +      int neg = Curl_input_negotiate(conn, (bool)(httpcode == 407), start);        if (neg == 0) {          data->reqdata.newurl = strdup(data->change.url);          data->state.authproblem = (data->reqdata.newurl == NULL); diff --git a/lib/http_negotiate.c b/lib/http_negotiate.c index f504c12d8..f5cc6cc6c 100644 --- a/lib/http_negotiate.c +++ b/lib/http_negotiate.c @@ -49,7 +49,7 @@  #include "memdebug.h"  static int -get_gss_name(struct connectdata *conn, gss_name_t *server) +get_gss_name(struct connectdata *conn, bool proxy, gss_name_t *server)  {    struct negotiatedata *neg_ctx = &conn->data->state.negotiate;    OM_uint32 major_status, minor_status; @@ -69,11 +69,11 @@ get_gss_name(struct connectdata *conn, gss_name_t *server)    else      service = "HTTP"; -  token.length = strlen(service) + 1 + strlen(conn->host.name) + 1; +  token.length = strlen(service) + 1 + strlen(proxy ? conn->proxy.name : conn->host.name) + 1;    if (token.length + 1 > sizeof(name))      return EMSGSIZE; -  snprintf(name, sizeof(name), "%s@%s", service, conn->host.name); +  snprintf(name, sizeof(name), "%s@%s", service, proxy ? conn->proxy.name : conn->host.name);    token.value = (void *) name;    major_status = gss_import_name(&minor_status, @@ -113,7 +113,7 @@ log_gss_error(struct connectdata *conn, OM_uint32 error_status, char *prefix)    infof(conn->data, "%s", buf);  } -int Curl_input_negotiate(struct connectdata *conn, const char *header) +int Curl_input_negotiate(struct connectdata *conn, bool proxy, const char *header)  {    struct negotiatedata *neg_ctx = &conn->data->state.negotiate;    OM_uint32 major_status, minor_status, minor_status2; @@ -156,7 +156,7 @@ int Curl_input_negotiate(struct connectdata *conn, const char *header)    }    if (neg_ctx->server_name == NULL && -      (ret = get_gss_name(conn, &neg_ctx->server_name))) +      (ret = get_gss_name(conn, proxy, &neg_ctx->server_name)))      return ret;    header += strlen(neg_ctx->protocol); @@ -245,7 +245,7 @@ int Curl_input_negotiate(struct connectdata *conn, const char *header)  } -CURLcode Curl_output_negotiate(struct connectdata *conn) +CURLcode Curl_output_negotiate(struct connectdata *conn, bool proxy)  {    struct negotiatedata *neg_ctx = &conn->data->state.negotiate;    OM_uint32 minor_status; @@ -299,7 +299,7 @@ CURLcode Curl_output_negotiate(struct connectdata *conn)      return CURLE_OUT_OF_MEMORY;    conn->allocptr.userpwd = -    aprintf("Authorization: %s %s\r\n", neg_ctx->protocol, encoded); +    aprintf("%sAuthorization: %s %s\r\n", proxy ? "Proxy-" : "", neg_ctx->protocol, encoded);    free(encoded);    gss_release_buffer(&minor_status, &neg_ctx->output_token);    return (conn->allocptr.userpwd == NULL) ? CURLE_OUT_OF_MEMORY : CURLE_OK; diff --git a/lib/http_negotiate.h b/lib/http_negotiate.h index e0507013f..669fee586 100644 --- a/lib/http_negotiate.h +++ b/lib/http_negotiate.h @@ -27,10 +27,10 @@  #ifdef HAVE_GSSAPI  /* this is for Negotiate header input */ -int Curl_input_negotiate(struct connectdata *conn, const char *header); +int Curl_input_negotiate(struct connectdata *conn, bool proxy, const char *header);  /* this is for creating Negotiate header output */ -CURLcode Curl_output_negotiate(struct connectdata *conn); +CURLcode Curl_output_negotiate(struct connectdata *conn, bool proxy);  void Curl_cleanup_negotiate(struct SessionHandle *data); diff --git a/src/main.c b/src/main.c index 3eca434e0..1fffb9695 100644 --- a/src/main.c +++ b/src/main.c @@ -426,6 +426,7 @@ struct Configurable {    bool create_dirs;    bool ftp_create_dirs;    bool ftp_skip_ip; +  bool proxynegotiate;    bool proxyntlm;    bool proxydigest;    bool proxybasic; @@ -690,6 +691,7 @@ static void help(void)      "    --proxy-anyauth Pick \"any\" proxy authentication method (H)",      "    --proxy-basic   Use Basic authentication on the proxy (H)",      "    --proxy-digest  Use Digest authentication on the proxy (H)", +    "    --proxy-negotiate Use Negotiate authentication on the proxy (H)",      "    --proxy-ntlm    Use NTLM authentication on the proxy (H)",      " -P/--ftp-port <address> Use PORT with address instead of PASV (F)",      " -q                 If used as the first parameter disables .curlrc", @@ -1492,6 +1494,7 @@ static ParameterError getparameter(char *flag, /* f or -long-flag */      {"$g", "retry",      TRUE},      {"$h", "retry-delay", TRUE},      {"$i", "retry-max-time", TRUE}, +    {"$k", "proxy-negotiate",   FALSE},      {"$m", "ftp-account", TRUE},      {"$n", "proxy-anyauth", FALSE},      {"$o", "trace-time", FALSE}, @@ -1892,6 +1895,12 @@ static ParameterError getparameter(char *flag, /* f or -long-flag */            return PARAM_BAD_NUMERIC;          break; +      case 'k': /* --proxy-negotiate */ +        if(curlinfo->features & CURL_VERSION_GSSNEGOTIATE) +          config->proxynegotiate ^= TRUE; +        else +          return PARAM_LIBCURL_DOESNT_SUPPORT; +        break;        case 'm': /* --ftp-account */          GetStr(&config->ftp_account, nextarg);          break; @@ -4302,6 +4311,8 @@ operate(struct Configurable *config, int argc, argv_item_t argv[])                           config->ftp_create_dirs);          if(config->proxyanyauth)            my_setopt(curl, CURLOPT_PROXYAUTH, CURLAUTH_ANY); +        else if(config->proxynegotiate) +          my_setopt(curl, CURLOPT_PROXYAUTH, CURLAUTH_GSSNEGOTIATE);          else if(config->proxyntlm)            my_setopt(curl, CURLOPT_PROXYAUTH, CURLAUTH_NTLM);          else if(config->proxydigest) | 
