]> granicus.if.org Git - curl/commitdiff
Markus Moeller's SPNEGO patch applied, with my edits, additions and minor
authorDaniel Stenberg <daniel@haxx.se>
Fri, 19 Sep 2003 12:56:22 +0000 (12:56 +0000)
committerDaniel Stenberg <daniel@haxx.se>
Fri, 19 Sep 2003 12:56:22 +0000 (12:56 +0000)
cleanups.

CHANGES
configure.ac
docs/libcurl/curl_version_info.3
include/curl/curl.h
lib/http.c
lib/http_negotiate.c
lib/http_negotiate.h
lib/url.c
lib/urldata.h
lib/version.c

diff --git a/CHANGES b/CHANGES
index c89dc7b6ffeb5d54eb6c78ad66be55770e22fed0..f35d2a1f4c53482e5be6c7beeb9d7f50de89ae57 100644 (file)
--- a/CHANGES
+++ b/CHANGES
@@ -6,6 +6,13 @@
 
                                   Changelog
 
+
+Daniel (19 September)
+- Applied Markus Moeller's patch that introduces SPNEGO support if libcurl
+  is built with the FBopenssl libraries. curl_version_info() now returns
+  info on SPNEGO availability. The patch also made the GSSAPI stuff work fine
+  with the MIT GSS-library (the Heimdal one still works too).
+
 Daniel (16 September)
 - Doing PUT with --digest failed, as reported in bug report #805853.
 
index 09576a5e7a44407a2f76c151bbf9014d2d291f2c..7f04230115c4f59b9cb2a34bcbab089cbd17b831 100644 (file)
@@ -457,6 +457,31 @@ else
   AC_MSG_RESULT(no)
 fi
 
+dnl **********************************************************************
+dnl Check for FBopenssl(SPNEGO) libraries
+dnl **********************************************************************
+
+AC_ARG_WITH(spnego,
+  AC_HELP_STRING([--with-spnego=DIR],
+                 [Specify location of SPNEGO library fbopenssl]),
+  [ SPNEGO_ROOT="$withval"
+    want_spnego="yes" ]
+)
+AC_MSG_CHECKING([if SPNEGO support is requested])
+if test x"$want_spnego" = xyes; then
+  if test -z "$SPNEGO_LIB_DIR"; then
+     LDFLAGS="$LDFLAGS -L$SPNEGO_ROOT $(wl)-R$SPNEGO_ROOT -lfbopenssl"
+  else
+     LDFLAGS="$LDFLAGS $SPNEGO_LIB_DIR"
+  fi
+  AC_DEFINE(HAVE_SPNEGO, 1, [Define this if you have the SPNEGO library fbopenssl])
+  AC_MSG_RESULT(yes)
+else
+  AC_MSG_RESULT(no)
+fi
+
 dnl **********************************************************************
 dnl Check for GSS-API libraries
 dnl **********************************************************************
@@ -507,7 +532,12 @@ if test x"$want_gss" = xyes; then
   fi
 
   AC_MSG_RESULT(yes)
-  AC_DEFINE(GSSAPI, 1, [if you have the gssapi libraries])
+  AC_DEFINE(HAVE_GSSAPI, 1, [if you have the gssapi libraries])
+  if test -f "$GSSAPI_INCS/gssapi.h"; then
+      AC_DEFINE(HAVE_GSSHEIMDAL, 1, [if you have the Heimdal gssapi libraries])
+  else
+      AC_DEFINE(HAVE_GSSMIT, 1, [if you have the MIT gssapi libraries])
+  fi
   
 else
   AC_MSG_RESULT(no)
index 15bcb7b42591b3d01d1470d281a5cc515aafd66a..ed1327b21c149a532d6a5f3f32321fdeb2b8849c 100644 (file)
@@ -2,7 +2,7 @@
 .\" nroff -man [file]
 .\" $Id$
 .\"
-.TH curl_version_info 3 "12 Aug 2003" "libcurl 7.10.7" "libcurl Manual"
+.TH curl_version_info 3 "19 Sep 2003" "libcurl 7.10.8" "libcurl Manual"
 .SH NAME
 curl_version_info - returns run-time libcurl version info
 .SH SYNOPSIS
@@ -84,6 +84,10 @@ interest for libcurl hackers. (added in 7.10.6)
 libcurl was built with support for asynchronous name lookups, which allows
 more exact timeouts (even on Windows) and less blocking when using the multi
 interface. (added in 7.10.7)
+.TP
+.B CURL_VERSION_SPNEGO
+libcurl was built with support for SPNEGO authentication (Simple and Protected
+GSS-API Negotiation Mechanism, defined in RFC 2478.) (added in 7.10.8)
 .PP
 \fIssl_version\fP is an ascii string for the OpenSSL version used. If libcurl
 has no SSL support, this is NULL.
index 117fb6720ab9cffddac5a3dbd529823844c1ed00..f78d8a84d73b4c634fcc445d13db534cf30fb8c6 100644 (file)
@@ -1134,6 +1134,7 @@ typedef struct {
 #define CURL_VERSION_GSSNEGOTIATE (1<<5)
 #define CURL_VERSION_DEBUG     (1<<6) /* built with debug capabilities */
 #define CURL_VERSION_ASYNCHDNS (1<<7)
+#define CURL_VERSION_SPNEGO    (1<<8)
 
 /*
  * NAME curl_version_info()
index 8cb97dd1d3d2b58fc279214a23a39b7861e3da19..5195122a8c9dff23d2fc97f764c882a31d4d6628 100644 (file)
@@ -238,7 +238,7 @@ CURLcode http_auth_headers(struct connectdata *conn,
     }
     /* Send web authentication header if needed */
     if (data->state.authstage == 401) {
-#ifdef GSSAPI
+#ifdef HAVE_GSSAPI
       if((data->state.authwant == CURLAUTH_GSSNEGOTIATE) &&
          data->state.negotiate.context && 
          !GSS_ERROR(data->state.negotiate.status)) {
@@ -324,7 +324,7 @@ CURLcode Curl_http_auth(struct connectdata *conn,
   while(*start && isspace((int)*start))
     start++;
 
-#ifdef GSSAPI
+#ifdef HAVE_GSSAPI
   if (checkprefix("GSS-Negotiate", start) ||
       checkprefix("Negotiate", start)) {
     *availp |= CURLAUTH_GSSNEGOTIATE;
index 5012b0764fb2249a6aaff304c7f10802de2f4d7b..fcbb3eadbdf8e961f1af176425d3a61a78ab7f6f 100644 (file)
  ***************************************************************************/
 #include "setup.h"
 
-#ifdef GSSAPI
+#ifdef HAVE_GSSAPI
+#ifdef HAVE_GSSMIT
+#define GSS_C_NT_HOSTBASED_SERVICE gss_nt_service_name
+#endif
 
 #ifndef CURL_DISABLE_HTTP
 /* -- WIN32 approved -- */
@@ -171,6 +174,46 @@ int Curl_input_negotiate(struct connectdata *conn, char *header)
     if (rawlen < 0)
       return -1;
     input_token.length = rawlen;
+
+#ifdef SPNEGO /* Handle SPNEGO */
+    if (checkprefix("Negotiate", header)) {
+        ASN1_OBJECT *   object            = NULL;
+        int             rc                = 1;
+        unsigned char * spnegoToken       = NULL;
+        size_t          spnegoTokenLength = 0;
+        unsigned char * mechToken         = NULL;
+        size_t          mechTokenLength   = 0;
+
+        spnegoToken = malloc(input_token.length);
+        if (input_token.value == NULL)
+          return ENOMEM;
+        spnegoTokenLength = input_token.length;
+
+        object = OBJ_txt2obj ("1.2.840.113554.1.2.2", 1);
+        if (!parseSpnegoTargetToken(spnegoToken,
+                                    spnegoTokenLength,
+                                    NULL,
+                                    NULL,
+                                    &mechToken,
+                                    &mechTokenLength,
+                                    NULL,
+                                    NULL)) {
+          free(spnegoToken);
+          spnegoToken = NULL;
+          infof(conn->data, "Parse SPNEGO Target Token failed\n");
+        }
+        else {
+          free(input_token.value);
+          input_token.value = NULL;
+          input_token.value = malloc(mechTokenLength);
+          memcpy(input_token.value, mechToken,mechTokenLength);
+          input_token.length = mechTokenLength;
+          free(mechToken);
+          mechToken = NULL;
+          infof(conn->data, "Parse SPNEGO Target Token succeded\n");
+        }
+    }
+#endif
   }
 
   major_status = gss_init_sec_context(&minor_status,
@@ -212,9 +255,50 @@ CURLcode Curl_output_negotiate(struct connectdata *conn)
   struct negotiatedata *neg_ctx = &conn->data->state.negotiate;
   OM_uint32 minor_status;
   char *encoded = NULL;
-  int len = Curl_base64_encode(neg_ctx->output_token.value,
-                               neg_ctx->output_token.length,
-                               &encoded);
+  int len;
+
+#ifdef SPNEGO /* Handle SPNEGO */
+  if (checkprefix("Negotiate",neg_ctx->protocol)) {
+    ASN1_OBJECT *   object            = NULL;
+    int             rc                = 1;
+    unsigned char * spnegoToken       = NULL;
+    size_t          spnegoTokenLength = 0;
+    unsigned char * responseToken       = NULL;
+    size_t          responseTokenLength = 0;
+    
+    responseToken = malloc(neg_ctx->output_token.length);
+    if ( responseToken == NULL)
+      return CURLE_OUT_OF_MEMORY;
+    memcpy(responseToken, neg_ctx->output_token.value,
+           neg_ctx->output_token.length);
+    responseTokenLength = neg_ctx->output_token.length;
+
+    object=OBJ_txt2obj ("1.2.840.113554.1.2.2", 1);
+    if (!makeSpnegoInitialToken (object,
+                                 responseToken,
+                                 responseTokenLength,
+                                 &spnegoToken,
+                                 &spnegoTokenLength)) {
+      free(responseToken);
+      responseToken = NULL;
+      infof(conn->data, "Make SPNEGO Initial Token failed\n");
+    }
+    else {
+      free(neg_ctx->output_token.value);
+      responseToken = NULL;
+      neg_ctx->output_token.value = malloc(spnegoTokenLength);
+      memcpy(neg_ctx->output_token.value, spnegoToken,spnegoTokenLength);
+      neg_ctx->output_token.length = spnegoTokenLength;
+      free(spnegoToken);
+      spnegoToken = NULL;
+      infof(conn->data, "Make SPNEGO Initial Token succeded\n");
+    }
+  }
+#endif
+  len = Curl_base64_encode(neg_ctx->output_token.value,
+                           neg_ctx->output_token.length,
+                           &encoded);
+
   if (len < 0)
     return CURLE_OUT_OF_MEMORY;
 
index 36a346c56511a08d28e1bf919498cc9b50e0b3ff..f58f455604106b809ab682c9066feac0a37d63df 100644 (file)
@@ -24,7 +24,7 @@
  * $Id$
  ***************************************************************************/
 
-#ifdef GSSAPI
+#ifdef HAVE_GSSAPI
 
 /* this is for Negotiate header input */
 int Curl_input_negotiate(struct connectdata *conn, char *header);
index a1f474d4d6cf894168d9b83e7de8f3b34fb01a16..12abbb2c54132f3f8ead2c1fbc830d9397560973 100644 (file)
--- a/lib/url.c
+++ b/lib/url.c
@@ -879,7 +879,7 @@ CURLcode Curl_setopt(struct SessionHandle *data, CURLoption option, ...)
 #ifndef USE_SSLEAY
     auth &= ~CURLAUTH_NTLM; /* no NTLM without SSL */
 #endif
-#ifndef GSSAPI
+#ifndef HAVE_GSSAPI
     auth &= ~CURLAUTH_GSSNEGOTIATE; /* no GSS-Negotiate without GSSAPI */
 #endif
     if(!auth)
@@ -899,7 +899,7 @@ CURLcode Curl_setopt(struct SessionHandle *data, CURLoption option, ...)
 #ifndef USE_SSLEAY
     auth &= ~CURLAUTH_NTLM; /* no NTLM without SSL */
 #endif
-#ifndef GSSAPI
+#ifndef HAVE_GSSAPI
     auth &= ~CURLAUTH_GSSNEGOTIATE; /* no GSS-Negotiate without GSSAPI */
 #endif
     if(!auth)
index 6d89bf736f05963af2c37f4b97a701c4f34147d2..16c413d610f0f69971ef71c4a40949c77f1693ea 100644 (file)
 #include <zlib.h>              /* for content-encoding */
 #endif
 
-#ifdef GSSAPI
+#ifdef HAVE_GSSAPI
+#ifdef HAVE_GSSMIT
+#include <gssapi/gssapi.h>
+#include <gssapi/gssapi_generic.h>
+#else
 #include <gssapi.h>
 #endif
+#endif
 
 #ifdef USE_ARES
 #include <ares.h>
@@ -184,7 +189,7 @@ struct ntlmdata {
   unsigned char nonce[8];
 };
 
-#ifdef GSSAPI
+#ifdef HAVE_GSSAPI
 struct negotiatedata {
   bool gss; /* Whether we're processing GSS-Negotiate or Negotiate */
   const char* protocol; /* "GSS-Negotiate" or "Negotiate" */
@@ -688,7 +693,7 @@ struct UrlState {
 
   struct digestdata digest;
 
-#ifdef GSSAPI
+#ifdef HAVE_GSSAPI
   struct negotiatedata negotiate;
 #endif
 
index 651f895e110b4c94b45a3918a067aadd1cc08c51..3e8c88513f2e5a7945efcae8030fdbeac845f4f6 100644 (file)
@@ -114,7 +114,7 @@ char *curl_version(void)
   sprintf(ptr, " zlib/%s", zlibVersion());
   ptr += strlen(ptr);
 #endif
-#ifdef GSSAPI
+#ifdef HAVE_GSSAPI
   sprintf(ptr, " GSS");
   ptr += strlen(ptr);
 #endif
@@ -177,7 +177,7 @@ static curl_version_info_data version_info = {
 #ifdef HAVE_LIBZ
   | CURL_VERSION_LIBZ
 #endif
-#ifdef GSSAPI
+#ifdef HAVE_GSSAPI
   | CURL_VERSION_GSSNEGOTIATE
 #endif
 #ifdef CURLDEBUG
@@ -185,6 +185,9 @@ static curl_version_info_data version_info = {
 #endif
 #ifdef USE_ARES
   | CURL_VERSION_ASYNCHDNS
+#endif
+#ifdef HAVE_SPNEGO
+  | CURL_VERSION_SPNEGO
 #endif
   ,
   NULL, /* ssl_version */