]> granicus.if.org Git - curl/commitdiff
Daniel Kouril's patch that adds HTTP negotiation support to libcurl was
authorDaniel Stenberg <daniel@haxx.se>
Tue, 10 Jun 2003 12:22:19 +0000 (12:22 +0000)
committerDaniel Stenberg <daniel@haxx.se>
Tue, 10 Jun 2003 12:22:19 +0000 (12:22 +0000)
added.

14 files changed:
CHANGES
configure.ac
docs/curl.1
docs/libcurl/curl_easy_setopt.3
include/curl/curl.h
lib/Makefile.am
lib/http.c
lib/http_negotiate.c [new file with mode: 0644]
lib/http_negotiate.h [new file with mode: 0644]
lib/transfer.c
lib/url.c
lib/urldata.h
src/main.c
src/version.h

diff --git a/CHANGES b/CHANGES
index ac8050bc7e491b9c300603b036bec52a4c2c7834..0125671583f09b66cbfb02cf3324dcdc984c827b 100644 (file)
--- a/CHANGES
+++ b/CHANGES
@@ -7,6 +7,11 @@
                                   Changelog
 
 Daniel (10 June)
+- Daniel Kouril added HTTP Negotiate authentication support, as defined in the
+  IETF draft draft-brezak-spnego-http-04.txt. In use already by various
+  Microsoft web applications. CURLOPT_HTTPNEGOTIATE and --negotiate are the
+  new family members.
+
 - A missing ending bracket (']') while doing URL globbing could lead to a
   segfault. While fixing this, I also introduced better error reporting in the
   globbing code. (All this is application code outside libcurl.)
index c2245a2435b9e8397226b95cf7d84dd245c0565c..2707aa2e44abab5764a0b42794811f80c29a63b9 100644 (file)
@@ -454,6 +454,63 @@ else
   AC_MSG_RESULT(no)
 fi
 
+dnl **********************************************************************
+dnl Check for GSS-API libraries
+dnl **********************************************************************
+
+AC_ARG_WITH(gssapi-includes,
+  AC_HELP_STRING([--with-gssapi-includes=DIR],
+                 [Specify location of GSSAPI header]),
+  [ GSSAPI_INCS="-I$withval" 
+    want_gss="yes" ]
+)
+
+AC_ARG_WITH(gssapi-libs,
+  AC_HELP_STRING([--with-gssapi-libs=DIR],
+                [Specify location of GSSAPI libs]),
+  [ GSSAPI_LIBS="-L$withval -lgssapi"
+    want_gss="yes" ]
+)
+
+AC_ARG_WITH(gssapi,
+  AC_HELP_STRING([--with-gssapi=DIR],
+                 [Where to look for GSSAPI]),
+  [ GSSAPI_ROOT="$withval"
+    want_gss="yes" ]
+)
+
+AC_MSG_CHECKING([if GSSAPI support is requested])
+if test x"$want_gss" = xyes; then
+  if test -z "$GSSAPI_INCS"; then
+     if test -f "$GSSAPI_ROOT/bin/krb5-config"; then
+        gss_cppflags=`$GSSAPI_ROOT/bin/krb5-config --cflags gssapi`
+       CPPFLAGS="$CPPFLAGS $gss_cppflags"
+     else
+        CPPFLAGS="$GSSAPI_ROOT/include"
+     fi
+  else
+     CPPFLAGS="$CPPFLAGS $GSSAPI_INCS"
+  fi
+  
+  if test -z "$GSSAPI_LIB_DIR"; then
+     if test -f "$GSSAPI_ROOT/bin/krb5-config"; then
+        gss_ldflags=`$GSSAPI_ROOT/bin/krb5-config --libs gssapi`
+       LDFLAGS="$LDFLAGS $gss_ldflags"
+     else
+        LDFLAGS="$LDFLAGS $GSSAPI_ROOT/lib -lgssapi"
+     fi
+  else
+     LDFLAGS="$LDFLAGS $GSSAPI_LIB_DIR"
+  fi
+
+  AC_MSG_RESULT(yes)
+  AC_DEFINE(GSSAPI, 1, [if you have the gssapi libraries])
+  
+else
+  AC_MSG_RESULT(no)
+fi
+  
+
 dnl Detect the pkg-config tool, as it may have extra info about the
 dnl openssl installation we can use. I *believe* this is what we are
 dnl expected to do on really recent Redhat Linux hosts.
index b4ec7f6d90ce6903823950e665b3e8507e84065d..5e687528b316b0f44989ae323fe4c304aad6ef1f 100644 (file)
@@ -184,6 +184,14 @@ method than the default Basic method, and prevents the password from being
 sent over the wire in clear text. Use this in combination with the normal
 -u/--user option to set user name and password.  (Option added in curl 7.10.6)
 
+If this option is used several times,  each occurrence will toggle this on/off.
+.IP "--negotiate"
+(HTTP) Enables Negotiate authentication. The Negotiate method was designed by
+Microsoft and is used in their web aplications. It is primarily 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 this option is used several times,  each occurrence will toggle this on/off.
 .IP "--disable-epsv"
 (FTP) Tell curl to disable the use of the EPSV command when doing passive FTP
index 4eeaac79d15aeb650601869190ceab7e77190aee..ea66ace5bc4586786a789bedf3993656dd09cbb3 100644 (file)
@@ -272,7 +272,7 @@ The main point of this would be that the write callback gets called more often
 and with smaller chunks. This is just treated as a request, not an order. You
 cannot be guaranteed to actually get the given size. (Added in 7.10)
 .PP
-.SH NAMES and PASSWORDS OPTIONS
+.SH NAMES and PASSWORDS OPTIONS (Authentication)
 .TP 0.4i
 .B CURLOPT_NETRC
 This parameter controls the preference of libcurl between using user names and
@@ -322,15 +322,31 @@ prompt function.
 
 When using HTTP and CURLOPT_FOLLOWLOCATION, libcurl might perform several
 requests to possibly different hosts. libcurl will only send this user and
-password information to hosts using the initial host name, so if libcurl
-follows locations to other hosts it will not send the user and password to
-those. This is enforced to prevent accidental information leakage.
+password information to hosts using the initial host name (unless
+CURLOPT_UNRESTRICTED_AUTH is set), so if libcurl follows locations to other
+hosts it will not send the user and password to those. This is enforced to
+prevent accidental information leakage.
 .TP
 .B CURLOPT_PROXYUSERPWD
 Pass a char * as parameter, which should be [user name]:[password] to use for
 the connection to the HTTP proxy. If the password is left out, you will be
 prompted for it. \fICURLOPT_PASSWDFUNCTION\fP can be used to set your own
 prompt function.
+.TP
+.B CURLOPT_HTTPDIGEST
+Pass a long set to a non-zero value to enable HTTP Digest authentication.
+Digest authentication is defined in RFC2617 and is a somewhat more secure way
+to do user+password checking over public networks than the regular
+old-fashioned Basic authentication. By default, libcurl uses Basic. Set name
+and password with the CURLOPT_USERPWD option. (Added in 7.10.6)
+.TP
+.B CURLOPT_HTTPNEGOTIATE
+Pass a long set to a non-zero value to enable HTTP Negotiate authentication.
+The Negotiate method was designed by Microsoft and is used in their web
+aplications. It is primarily 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.  Set name and
+password with the CURLOPT_USERPWD option. (Added in 7.10.6)
 .PP
 .SH HTTP OPTIONS
 .TP 0.4i
index a81afba2c9e3bbb620303a99814f0c213ded0ed7..46e09f4291a9b2470f2301aa92e44f8ede2162ee 100644 (file)
@@ -629,6 +629,10 @@ typedef enum {
      You should use this in combination with CURLOPT_USERPWD. */
   CINIT(HTTPDIGEST, LONG, 107),
 
+  /* Set this to a non-zero value to enable HTTP Negotiate Authentication.
+     You should use this in combination with CURLOPT_USERPWD. */
+  CINIT(HTTPNEGOTIATE, LONG, 108),
+
   CURLOPT_LASTENTRY /* the last unused */
 } CURLoption;
 
index b17bac1987739b823b2a237c9ba330beacc688d2..64cfaa74fbb02154fbe79e49e14cdec09d918f84 100644 (file)
@@ -68,7 +68,7 @@ strequal.h easy.c security.h security.c krb4.c krb4.h memdebug.c      \
 memdebug.h inet_ntoa_r.h http_chunks.c http_chunks.h strtok.c strtok.h \
 connect.c connect.h llist.c llist.h hash.c hash.h multi.c              \
 content_encoding.c content_encoding.h share.c share.h http_digest.c \
-md5.c md5.h http_digest.h
+md5.c md5.h http_digest.h http_negotiate.c http_negotiate.h
 
 noinst_HEADERS = setup.h transfer.h
 
index 16a87d937bdd11c722a06e1c33e701146320459e..e5d2b49d377391f771bd4060a9e5ac4f3f6cea59 100644 (file)
@@ -688,6 +688,14 @@ CURLcode Curl_http(struct connectdata *conn)
     conn->allocptr.uagent=NULL;
   }
 
+#ifdef GSSAPI
+  if (data->state.negotiate.context && 
+      !GSS_ERROR(data->state.negotiate.status)) {
+     result = Curl_output_negotiate(conn);
+     if (result)
+       return result;
+  } else
+#endif
   if(data->state.digest.nonce) {
     result = Curl_output_digest(conn,
                                 (unsigned char *)request,
diff --git a/lib/http_negotiate.c b/lib/http_negotiate.c
new file mode 100644 (file)
index 0000000..9a2d46a
--- /dev/null
@@ -0,0 +1,217 @@
+/***************************************************************************
+ *                                  _   _ ____  _     
+ *  Project                     ___| | | |  _ \| |    
+ *                             / __| | | | |_) | |    
+ *                            | (__| |_| |  _ <| |___ 
+ *                             \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2003, 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
+ * are also available at http://curl.haxx.se/docs/copyright.html.
+ * 
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ * $Id$
+ ***************************************************************************/
+#include "setup.h"
+
+#ifdef GSSAPI
+
+#ifndef CURL_DISABLE_HTTP
+/* -- WIN32 approved -- */
+#include <stdio.h>
+#include <string.h>
+#include <stdarg.h>
+#include <stdlib.h>
+#include <ctype.h>
+
+#include "urldata.h"
+#include "sendf.h"
+#include "strequal.h"
+
+#include "http_negotiate.h"
+
+#define _MPRINTF_REPLACE /* use our functions only */
+#include <curl/mprintf.h>
+
+/* The last #include file should be: */
+#ifdef MALLOCDEBUG
+#include "memdebug.h"
+#endif
+
+static int
+get_gss_name(struct connectdata *conn, gss_name_t *server)
+{
+  OM_uint32 major_status, minor_status;
+  gss_buffer_desc token = GSS_C_EMPTY_BUFFER;
+  char name[2048];
+
+#ifdef KRB5
+  token.length = strlen("khttp@") + strlen(conn->hostname) + 1;
+#els
+  token.length = strlen("host/") + strlen(conn->hostname) + 1;
+#endif
+  if (token.length + 1 > sizeof(name))
+    return EMSGSIZE;
+#ifdef KRB5
+  sprintf(name, "khttp@%s", conn->hostname);
+#else
+  sprintf(name, "host/%s", conn->hostname);
+#endif
+  token.value = (void *) name;
+  major_status = gss_import_name(&minor_status,
+                                 &token,
+                                 GSS_C_NT_HOSTBASED_SERVICE,
+                                 server);
+  return GSS_ERROR(major_status) ? -1 : 0;
+}
+
+static void
+log_gss_error(struct connectdata *conn, OM_uint32 error_status, char *prefix)
+{
+  OM_uint32 maj_stat, min_stat;
+  OM_uint32 msg_ctx = 0;
+  gss_buffer_desc status_string;
+  char buf[1024];
+  size_t len;
+
+  snprintf(buf, sizeof(buf), "%s", prefix);
+  len = strlen(buf);
+  do {
+    maj_stat = gss_display_status (&min_stat,
+                                   error_status,
+                                   GSS_C_MECH_CODE,
+                                   GSS_C_NO_OID,
+                                   &msg_ctx,
+                                   &status_string);
+    if (sizeof(buf) > len + status_string.length + 1) {
+      sprintf(buf + len, ": %s", (char*) status_string.value);
+      len += status_string.length;
+    }
+    gss_release_buffer(&min_stat, &status_string);
+  } while (!GSS_ERROR(maj_stat) && msg_ctx != 0);
+
+  infof(conn->data, buf);
+}
+
+CURLcode Curl_input_negotiate(struct connectdata *conn, char *header)
+{ 
+  struct negotiatedata *neg_ctx = &conn->data->state.negotiate;
+  OM_uint32 major_status, minor_status, minor_status2;
+  gss_buffer_desc input_token = GSS_C_EMPTY_BUFFER;
+  gss_buffer_desc output_token = GSS_C_EMPTY_BUFFER;
+  int ret;
+  size_t len;
+
+  while(*header && isspace((int)*header))
+    header++;
+  if(!checkprefix("GSS-Negotiate", header))
+    return -1;
+
+  if (neg_ctx->context && neg_ctx->status == GSS_S_COMPLETE) {
+    /* We finished succesfully our part of authentication, but server
+     * rejected it (since we're again here). Exit with an error since we
+     * can't invent anything better */
+    Curl_cleanup_negotiate(conn->data);
+    return -1;
+  }
+
+  if (neg_ctx->server_name == NULL &&
+      (ret = get_gss_name(conn, &neg_ctx->server_name)))
+    return ret;
+
+  header += strlen("GSS-Negotiate");
+  while(*header && isspace((int)*header))
+    header++;
+
+  len = strlen(header);
+  if (len > 0) {
+    input_token.length = (len+3)/4 * 3;
+    input_token.value = malloc(input_token.length);
+    if (input_token.value == NULL)
+      return ENOMEM;
+    input_token.length = Curl_base64_decode(header, input_token.value);
+    if (input_token.length < 0)
+      return -1;
+  }
+
+  major_status = gss_init_sec_context(&minor_status,
+                                      GSS_C_NO_CREDENTIAL,
+                                      &neg_ctx->context,
+                                      neg_ctx->server_name,
+                                      GSS_C_NO_OID,
+                                      GSS_C_DELEG_FLAG,
+                                      0,
+                                      GSS_C_NO_CHANNEL_BINDINGS,
+                                      &input_token,
+                                      NULL,
+                                      &output_token,
+                                      NULL,
+                                      NULL);
+  if (input_token.length > 0)
+    gss_release_buffer(&minor_status2, &input_token);
+  neg_ctx->status = major_status;
+  if (GSS_ERROR(major_status)) {
+    /* Curl_cleanup_negotiate(conn->data) ??? */
+    log_gss_error(conn, minor_status, "gss_init_sec_context() failed: ");
+    return -1;
+  }
+
+  if (output_token.length == 0) {
+    return -1;
+  }
+
+  neg_ctx->output_token = output_token;
+  /* conn->bits.close = FALSE; */
+
+  return 0;
+}
+   
+
+CURLcode Curl_output_negotiate(struct connectdata *conn)
+{ 
+  struct negotiatedata *neg_ctx = &conn->data->state.negotiate;
+  OM_uint32 minor_status;
+  char *encoded = NULL;
+  size_t len;
+  
+  len = Curl_base64_encode(neg_ctx->output_token.value,
+                           neg_ctx->output_token.length,
+                           &encoded);
+  if (len < 0)
+    return -1;
+
+  conn->allocptr.userpwd =
+    aprintf("Authorization: GSS-Negotiate %s\r\n", encoded);
+  free(encoded);
+  gss_release_buffer(&minor_status, &neg_ctx->output_token);
+  return (conn->allocptr.userpwd == NULL) ? ENOMEM : 0;
+}
+
+void Curl_cleanup_negotiate(struct SessionHandle *data)
+{ 
+  OM_uint32 minor_status;
+  struct negotiatedata *neg_ctx = &data->state.negotiate;
+
+  if (neg_ctx->context != GSS_C_NO_CONTEXT)
+    gss_delete_sec_context(&minor_status, &neg_ctx->context, GSS_C_NO_BUFFER);
+
+  if (neg_ctx->output_token.length != 0)
+    gss_release_buffer(&minor_status, &neg_ctx->output_token);
+
+  if (neg_ctx->server_name != GSS_C_NO_NAME)
+    gss_release_name(&minor_status, &neg_ctx->server_name);
+  
+  memset(neg_ctx, 0, sizeof(*neg_ctx));
+}
+
+
+#endif
+#endif
diff --git a/lib/http_negotiate.h b/lib/http_negotiate.h
new file mode 100644 (file)
index 0000000..09141bd
--- /dev/null
@@ -0,0 +1,39 @@
+#ifndef __HTTP_NEGOTIATE_H
+#define __HTTP_NEGOTIATE_H
+
+/***************************************************************************
+ *                                  _   _ ____  _     
+ *  Project                     ___| | | |  _ \| |    
+ *                             / __| | | | |_) | |    
+ *                            | (__| |_| |  _ <| |___ 
+ *                             \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2003, 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
+ * are also available at http://curl.haxx.se/docs/copyright.html.
+ * 
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ * $Id$
+ ***************************************************************************/
+
+#ifdef GSSAPI
+
+/* this is for Negotiate header input */
+CURLcode Curl_input_negotiate(struct connectdata *conn, char *header);
+
+/* this is for creating Negotiate header output */
+CURLcode Curl_output_negotiate(struct connectdata *conn);
+
+void Curl_cleanup_negotiate(struct SessionHandle *data);
+
+#endif
+
+#endif
index 6571e16369ede0a09e492dfb3bdfc49a52c4b35f..2eda08889219472b7e7b55588e603b2d371b2fca 100644 (file)
@@ -96,6 +96,9 @@
 #include "getinfo.h"
 #include "ssluse.h"
 #include "http_digest.h"
+#ifdef GSSAPI
+#include "http_negotiate.h"
+#endif
 
 #define _MPRINTF_REPLACE /* use our functions only */
 #include <curl/mprintf.h>
@@ -719,6 +722,20 @@ CURLcode Curl_readwrite(struct connectdata *conn,
               if(data->set.get_filetime)
                 data->info.filetime = k->timeofdoc;
             }
+#ifdef GSSAPI
+           else if (Curl_compareheader(k->p, "WWW-Authenticate:",
+                                        "GSS-Negotiate") &&
+                    (401 == k->httpcode) &&
+                    data->set.httpnegotiate) {
+             int neg;
+
+             neg = Curl_input_negotiate(conn,
+                                        k->p+strlen("WWW-Authenticate:"));
+             if (neg == 0)
+                /* simulate redirection to make curl send the request again */
+                conn->newurl = strdup(data->change.url);
+           }
+#endif
             else if(checkprefix("WWW-Authenticate:", k->p) &&
                     (401 == k->httpcode) &&
                     data->set.httpdigest /* Digest authentication is 
index ee13f08a67343e117b33ca038fc5c8921ed0e41b..0ac487e9110c7eaa147c07707672fbefd5dafd31 100644 (file)
--- a/lib/url.c
+++ b/lib/url.c
 #include "share.h"
 #include "content_encoding.h"
 #include "http_digest.h"
+#ifdef GSSAPI
+#include "http_negotiate.h"
+#endif
 
 /* And now for the protocols */
 #include "ftp.h"
@@ -847,6 +850,12 @@ CURLcode Curl_setopt(struct SessionHandle *data, CURLoption option, ...)
      */
     data->set.httpdigest = va_arg(param, long);
     break;
+#ifdef GSSAPI
+  case CURLOPT_HTTPNEGOTIATE:
+    /* Enable HTTP Negotaiate authentication */
+    data->set.httpnegotiate = va_arg(param, long);
+    break;
+#endif
   case CURLOPT_USERPWD:
     /*
      * user:password to use in the operation
index 58f70067738cc67ea6ac19dad9e52982c4eb0699..4dbd4092a8d19494c1de4f2172500b3b870e5016 100644 (file)
 #include <zlib.h>              /* for content-encoding 08/28/02 jhrg */
 #endif
 
+#ifdef GSSAPI
+#include <gssapi.h>
+#endif
+
 /* Download buffer size, keep it fairly big for speed reasons */
 #define BUFSIZE CURL_MAX_WRITE_SIZE
 
@@ -160,6 +164,15 @@ struct digestdata {
   int algo;
 };
 
+#ifdef GSSAPI
+struct negotiatedata {
+  OM_uint32 status;
+  gss_ctx_id_t context;
+  gss_name_t server_name;
+  gss_buffer_desc output_token;
+};
+#endif
+
 /****************************************************************************
  * HTTP unique setup
  ***************************************************************************/
@@ -627,6 +640,10 @@ struct UrlState {
                       is always set TRUE when curl_easy_perform() is called. */
 
   struct digestdata digest;
+
+#ifdef GSSAPI
+  struct negotiatedata negotiate;
+#endif
 };
 
 
@@ -672,6 +689,9 @@ struct UserDefined {
   long use_port;     /* which port to use (when not using default) */
   char *userpwd;     /* <user:password>, if used */
   bool httpdigest;   /* if HTTP Digest is enabled */
+#ifdef GSSAPI
+  bool httpnegotiate; /* if HTTP Negotiate authentication is enabled */
+#endif
   char *set_range;   /* range, if used. See README for detailed specification
                         on this syntax. */
   long followlocation; /* as in HTTP Location: */
index 3a52401e02ba184e48c9b4e8254155e61489180d..0e740f3ed22f831a2c565189879649e74275a782 100644 (file)
@@ -359,6 +359,9 @@ static void help(void)
        " -d/--data <data>   HTTP POST data (H)\n"
        "    --data-ascii <data>   HTTP POST ASCII data (H)\n"
        "    --data-binary <data>  HTTP POST binary data (H)\n"
+#ifdef GSSAPI
+       "    --negotiate     Enable HTTP Negotiate Authentication\n"
+#endif
        "    --digest        Enable HTTP Digest Authentication");
   puts("    --disable-eprt  Prevents curl from using EPRT or LPRT (F)\n"
        "    --disable-epsv  Prevents curl from using EPSV (F)\n"
@@ -461,6 +464,9 @@ struct Configurable {
   bool cookiesession; /* new session? */
   bool encoding;    /* Accept-Encoding please */
   bool digest;      /* Digest Authentication */
+#ifdef GSSAPI
+  bool negotiate;   /* Negotiate Authentication */
+#endif
   bool use_resume;
   bool resume_from_current;
   bool disable_epsv;
@@ -1053,6 +1059,9 @@ static ParameterError getparameter(char *flag, /* f or -long-flag */
     {"5i", "limit-rate", TRUE},
     {"5j", "compressed",  FALSE}, /* might take an arg someday */
     {"5k", "digest",     FALSE},
+#ifdef GSSAPI
+    {"5l",  "negotiate", FALSE},
+#endif
     {"0", "http1.0",     FALSE},
     {"1", "tlsv1",       FALSE},
     {"2", "sslv2",       FALSE},
@@ -1281,6 +1290,12 @@ static ParameterError getparameter(char *flag, /* f or -long-flag */
        config->digest ^= TRUE;
        break;
 
+#ifdef GSSAPI
+      case 'l': /* --negotiate */
+       config->negotiate ^= TRUE;
+       break;
+#endif
+
       default: /* the URL! */
         {
           struct getout *url;
@@ -2976,6 +2991,10 @@ operate(struct Configurable *config, int argc, char *argv[])
 
       /* new in libcurl 7.10.6 */
       curl_easy_setopt(curl, CURLOPT_HTTPDIGEST, config->digest);
+
+#ifdef GSSAPI
+      curl_easy_setopt(curl, CURLOPT_HTTPNEGOTIATE, config->negotiate);
+#endif
       
       /* new in curl 7.9.7 */
       if(config->trace_dump) {
index 897334a59a1f50f9bd160ad4adfce90993d0f4e3..be9b11869e9356d7d9e55d7aba1d601390776ff1 100644 (file)
@@ -1,3 +1,3 @@
 #define CURL_NAME "curl"
-#define CURL_VERSION "7.10.5"
+#define CURL_VERSION "7.10.6-pre1"
 #define CURL_ID CURL_NAME " " CURL_VERSION " (" OS ") "