aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--CHANGES7
-rw-r--r--configure.ac32
-rw-r--r--docs/libcurl/curl_version_info.36
-rw-r--r--include/curl/curl.h1
-rw-r--r--lib/http.c4
-rw-r--r--lib/http_negotiate.c92
-rw-r--r--lib/http_negotiate.h2
-rw-r--r--lib/url.c4
-rw-r--r--lib/urldata.h11
-rw-r--r--lib/version.c7
10 files changed, 150 insertions, 16 deletions
diff --git a/CHANGES b/CHANGES
index c89dc7b6f..f35d2a1f4 100644
--- 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.
diff --git a/configure.ac b/configure.ac
index 09576a5e7..7f0423011 100644
--- a/configure.ac
+++ b/configure.ac
@@ -458,6 +458,31 @@ else
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)
diff --git a/docs/libcurl/curl_version_info.3 b/docs/libcurl/curl_version_info.3
index 15bcb7b42..ed1327b21 100644
--- a/docs/libcurl/curl_version_info.3
+++ b/docs/libcurl/curl_version_info.3
@@ -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.
diff --git a/include/curl/curl.h b/include/curl/curl.h
index 117fb6720..f78d8a84d 100644
--- a/include/curl/curl.h
+++ b/include/curl/curl.h
@@ -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()
diff --git a/lib/http.c b/lib/http.c
index 8cb97dd1d..5195122a8 100644
--- a/lib/http.c
+++ b/lib/http.c
@@ -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;
diff --git a/lib/http_negotiate.c b/lib/http_negotiate.c
index 5012b0764..fcbb3eadb 100644
--- a/lib/http_negotiate.c
+++ b/lib/http_negotiate.c
@@ -22,7 +22,10 @@
***************************************************************************/
#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;
diff --git a/lib/http_negotiate.h b/lib/http_negotiate.h
index 36a346c56..f58f45560 100644
--- a/lib/http_negotiate.h
+++ b/lib/http_negotiate.h
@@ -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);
diff --git a/lib/url.c b/lib/url.c
index a1f474d4d..12abbb2c5 100644
--- 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)
diff --git a/lib/urldata.h b/lib/urldata.h
index 6d89bf736..16c413d61 100644
--- a/lib/urldata.h
+++ b/lib/urldata.h
@@ -86,9 +86,14 @@
#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
diff --git a/lib/version.c b/lib/version.c
index 651f895e1..3e8c88513 100644
--- a/lib/version.c
+++ b/lib/version.c
@@ -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
@@ -186,6 +186,9 @@ static curl_version_info_data version_info = {
#ifdef USE_ARES
| CURL_VERSION_ASYNCHDNS
#endif
+#ifdef HAVE_SPNEGO
+ | CURL_VERSION_SPNEGO
+#endif
,
NULL, /* ssl_version */
0, /* ssl_version_num */