Markus Moeller's SPNEGO patch applied, with my edits, additions and minor

cleanups.
This commit is contained in:
Daniel Stenberg 2003-09-19 12:56:22 +00:00
parent bbc01c36d2
commit 09ccfcdcd4
10 changed files with 150 additions and 16 deletions

View File

@ -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.

View 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)

View 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.

View 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()

View 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;

View File

@ -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;

View 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);

View File

@ -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)

View File

@ -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

View 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 */