curl-library
Re: Windows SSPI patch?
Date: Thu, 03 Mar 2005 08:10:26 -0500
Daniel Stenberg wrote:
> On Thu, 3 Mar 2005, Christopher R. Palmer wrote:
>
>> I modified curl to use the SSPI interface rather than the curl+SSL
>> implementation of NTLM.
>
> In my ears, this sounds like something more Windows users will appreciate.
>
> I'm interested in such a patch.
Great! I wasn't sure if you'd be interested because it's a little painful
to have very different pieces of code on different systems...
I've attached the patch to this email. As I said, if you want to
incorporate it, I'm willing to do some work fixing up things you don't like
about it.
Cheers,
Chris.
-- Christopher R. Palmer palmer_at_vivisimo.com Chief Technology Officer www.vivisimo.com Vivisimo, Inc.
diff -r --unified orig/curl-7.13.0/Makefile curl-7.13.0/Makefile
--- orig/curl-7.13.0/Makefile 2005-02-01 02:55:33.000000000 -0500
+++ curl-7.13.0/Makefile 2005-02-14 09:53:42.968750000 -0500
@@ -114,6 +114,18 @@
cd ..\src
nmake /f Makefile.vc6
+vc-debug:
+ cd lib
+ nmake /f Makefile.vc6 cfg=debug
+ cd ..\src
+ nmake /f Makefile.vc6 cfg=debug
+
+vc-debug-ssl-zlib:
+ cd lib
+ nmake /f Makefile.vc6 cfg=debug-ssl-zlib
+ cd ..\src
+ nmake /f Makefile.vc6 debug
+
vc-zlib:
cd lib
nmake /f Makefile.vc6 cfg=release-zlib
Only in curl-7.13.0/: Makefile.orig
diff -r --unified orig/curl-7.13.0/lib/Makefile.vc6 curl-7.13.0/lib/Makefile.vc6
--- orig/curl-7.13.0/lib/Makefile.vc6 2005-01-19 04:46:47.000000000 -0500
+++ curl-7.13.0/lib/Makefile.vc6 2005-02-14 09:53:43.000000000 -0500
@@ -49,11 +49,11 @@
#############################################################
## Nothing more to do below this line!
-CCNODBG = cl.exe /MD /O2 /DNDEBUG
-CCDEBUG = cl.exe /MDd /Od /Gm /Zi /D_DEBUG /GZ
+CCNODBG = cl.exe /MD /O2 /DNDEBUG /DUSE_WINDOWS_SSPI=1
+CCDEBUG = cl.exe /MDd /Od /Gm /Zi /D_DEBUG /GZ /DUSE_WINDOWS_SSPI=1
CFLAGSSSL = /DUSE_SSLEAY /I "$(OPENSSL_PATH)/inc32" /I "$(OPENSSL_PATH)/inc32/openssl"
CFLAGSZLIB = /DHAVE_ZLIB_H /DHAVE_ZLIB /DHAVE_LIBZ /I "$(ZLIB_PATH)"
-CFLAGS = /I. /I../include /nologo /W3 /GX /DWIN32 /YX /FD /c /DBUILDING_LIBCURL
+CFLAGS = /I../include /nologo /W3 /GX /DWIN32 /YX /FD /c /DBUILDING_LIBCURL
LNKDLL = link.exe /DLL
LNKLIB = link.exe /lib
LFLAGS = /nologo
Only in curl-7.13.0/lib: debug
diff -r --unified orig/curl-7.13.0/lib/http.c curl-7.13.0/lib/http.c
--- orig/curl-7.13.0/lib/http.c 2005-01-21 04:32:33.000000000 -0500
+++ curl-7.13.0/lib/http.c 2005-02-14 10:25:54.500000000 -0500
@@ -401,7 +401,7 @@
/* Send proxy authentication header if needed */
if (conn->bits.httpproxy &&
(conn->bits.tunnel_proxy == proxytunnel)) {
-#ifdef USE_SSLEAY
+#if defined(USE_SSLEAY) || (defined(WIN32) && defined(USE_WINDOWS_SSPI))
if(authproxy->want == CURLAUTH_NTLM) {
auth=(char *)"NTLM";
result = Curl_output_ntlm(conn, TRUE);
@@ -462,7 +462,7 @@
}
else
#endif
-#ifdef USE_SSLEAY
+#if defined(USE_SSLEAY) || (defined(WIN32) && defined(USE_WINDOWS_SSPI))
if(authhost->picked == CURLAUTH_NTLM) {
auth=(char *)"NTLM";
result = Curl_output_ntlm(conn, FALSE);
@@ -575,7 +575,7 @@
}
else
#endif
-#ifdef USE_SSLEAY
+#if defined(USE_SSLEAY) || (defined(WIN32) && defined(USE_WINDOWS_SSPI))
/* NTLM support requires the SSL crypto libs */
if(checkprefix("NTLM", start)) {
*availp |= CURLAUTH_NTLM;
diff -r --unified orig/curl-7.13.0/lib/http_ntlm.c curl-7.13.0/lib/http_ntlm.c
--- orig/curl-7.13.0/lib/http_ntlm.c 2004-12-07 18:09:41.000000000 -0500
+++ curl-7.13.0/lib/http_ntlm.c 2005-02-14 09:57:49.140625000 -0500
@@ -30,7 +30,7 @@
*/
#ifndef CURL_DISABLE_HTTP
-#ifdef USE_SSLEAY
+#if defined(USE_SSLEAY) || (defined(WIN32) && defined(USE_WINDOWS_SSPI))
/* We need OpenSSL for the crypto lib to provide us with MD4 and DES */
/* -- WIN32 approved -- */
@@ -51,6 +51,8 @@
#define _MPRINTF_REPLACE /* use our functions only */
#include <curl/mprintf.h>
+#ifndef USE_WINDOWS_SSPI
+
#include <openssl/des.h>
#include <openssl/md4.h>
#include <openssl/ssl.h>
@@ -71,6 +73,12 @@
#define DESKEY(x) &x
#endif
+#else
+
+#include <rpc.h>
+
+#endif
+
/* The last #include file should be: */
#include "memdebug.h"
@@ -128,9 +136,15 @@
ntlm->state = NTLMSTATE_TYPE2; /* we got a type-2 */
+#if USE_WINDOWS_SSPI
+ ntlm->type_2 = malloc(size+1);
+ ntlm->n_type_2 = size;
+ memcpy(ntlm->type_2, buffer, size);
+#else
if(size >= 48)
- /* the nonce of interest is index [24 .. 31], 8 bytes */
- memcpy(ntlm->nonce, &buffer[24], 8);
+ /* the nonce of interest is index [24 .. 31], 8 bytes */
+ memcpy(ntlm->nonce, &buffer[24], 8);
+#endif
/* at index decimal 20, there's a 32bit NTLM flag field */
@@ -145,6 +159,8 @@
return CURLNTLM_FINE;
}
+#ifndef USE_WINDOWS_SSPI
+
/*
* Turns a 56 bit key into the 64 bit, odd parity key and sets the key. The
* key schedule ks is also set.
@@ -271,6 +287,32 @@
free(pw);
}
+#endif
+
+#if USE_WINDOWS_SSPI
+
+static void
+ntlm_sspi_cleanup(struct ntlmdata *ntlm)
+{
+ if (ntlm->type_2) {
+ free(ntlm->type_2);
+ ntlm->type_2 = NULL;
+ }
+ if (ntlm->has_handles) {
+ DeleteSecurityContext(&ntlm->c_handle);
+ FreeCredentialsHandle(&ntlm->handle);
+ ntlm->has_handles = 0;
+ }
+ if (ntlm->p_identity) {
+ free(ntlm->identity.User);
+ free(ntlm->identity.Password);
+ free(ntlm->identity.Domain);
+ ntlm->p_identity = NULL;
+ }
+}
+
+#endif
+
#define SHORTPAIR(x) ((x) & 0xff), ((x) >> 8)
#define LONGQUARTET(x) ((x) & 0xff), (((x) >> 8)&0xff), \
(((x) >>16)&0xff), ((x)>>24)
@@ -345,6 +387,83 @@
*/
+#if USE_WINDOWS_SSPI
+ {
+ SecBuffer buf;
+ SecBufferDesc desc;
+ SECURITY_STATUS status;
+ ULONG attrs;
+ const char *user;
+ int domlen;
+
+ ntlm_sspi_cleanup(ntlm);
+
+ user = strchr(userp, '\\');
+ if (!user) user = strchr(userp, '/');
+
+ if (user) {
+ domain = userp;
+ domlen = user - userp;
+ user++;
+ } else {
+ user = userp;
+ domain = "";
+ domlen = 0;
+ }
+
+ if (user && *user) {
+ ntlm->identity.User = strdup(user);
+ ntlm->identity.UserLength = strlen(user);
+ ntlm->identity.Password = strdup(passwdp);
+ ntlm->identity.PasswordLength = strlen(passwdp);
+ ntlm->identity.Domain = malloc(domlen+1);
+ strncpy(ntlm->identity.Domain, domain, domlen);
+ ntlm->identity.Domain[domlen] = '\0';
+ ntlm->identity.DomainLength = domlen;
+ ntlm->identity.Flags = SEC_WINNT_AUTH_IDENTITY_ANSI;
+ ntlm->p_identity = &ntlm->identity;
+ } else {
+ ntlm->p_identity = NULL;
+ }
+
+ /* todo use the secdata or whatever buffer to hold username/passoword */
+ if (AcquireCredentialsHandle(
+ NULL, "NTLM", SECPKG_CRED_OUTBOUND, NULL, ntlm->p_identity,
+ NULL, NULL, &ntlm->handle, NULL
+ ) != SEC_E_OK)
+ {
+ return CURLE_OUT_OF_MEMORY;
+ }
+
+ desc.ulVersion = SECBUFFER_VERSION;
+ desc.cBuffers = 1;
+ desc.pBuffers = &buf;
+ buf.cbBuffer = sizeof(ntlmbuf);
+ buf.BufferType = SECBUFFER_TOKEN;
+ buf.pvBuffer = ntlmbuf;
+
+ status = InitializeSecurityContext(
+ &ntlm->handle, NULL, (char *) host,
+ ISC_REQ_CONFIDENTIALITY | ISC_REQ_REPLAY_DETECT |
+ ISC_REQ_CONNECTION,
+ 0, SECURITY_NETWORK_DREP, NULL, 0,
+ &ntlm->c_handle, &desc, &attrs, NULL
+ );
+
+ if (status == SEC_I_COMPLETE_AND_CONTINUE ||
+ status == SEC_I_CONTINUE_NEEDED)
+ {
+ CompleteAuthToken(&ntlm->c_handle, &desc);
+ } else if (status != SEC_E_OK) {
+ /* free handle */
+ FreeCredentialsHandle(&ntlm->handle);
+ return CURLE_OUT_OF_MEMORY;
+ }
+
+ ntlm->has_handles = 1;
+ size = buf.cbBuffer;
+ }
+#else
snprintf((char *)ntlmbuf, sizeof(ntlmbuf), "NTLMSSP%c"
"\x01%c%c%c" /* 32-bit type = 1 */
"%c%c%c%c" /* 32-bit NTLM flag field */
@@ -378,6 +497,7 @@
/* initial packet length */
size = 32 + hostlen + domlen;
+#endif
/* now keeper of the base64 encoded package size */
size = Curl_base64_encode((char *)ntlmbuf, size, &base64);
@@ -413,6 +533,41 @@
*/
{
+#if USE_WINDOWS_SSPI
+ SecBuffer type_2, type_3;
+ SecBufferDesc type_2_desc, type_3_desc;
+ SECURITY_STATUS status;
+ ULONG attrs;
+
+ type_2_desc.ulVersion = type_3_desc.ulVersion = SECBUFFER_VERSION;
+ type_2_desc.cBuffers = type_3_desc.cBuffers = 1;
+ type_2_desc.pBuffers = &type_2;
+ type_3_desc.pBuffers = &type_3;
+
+ type_2.BufferType = SECBUFFER_TOKEN;
+ type_2.pvBuffer = ntlm->type_2;
+ type_2.cbBuffer = ntlm->n_type_2;
+ type_3.BufferType = SECBUFFER_TOKEN;
+ type_3.pvBuffer = ntlmbuf;
+ type_3.cbBuffer = sizeof(ntlmbuf);
+
+ status = InitializeSecurityContext(
+ &ntlm->handle, &ntlm->c_handle, (char *) host,
+ ISC_REQ_CONFIDENTIALITY | ISC_REQ_REPLAY_DETECT |
+ ISC_REQ_CONNECTION,
+ 0, SECURITY_NETWORK_DREP, &type_2_desc, 0,
+ &ntlm->c_handle, &type_3_desc, &attrs, NULL
+ );
+
+ if (status != SEC_E_OK) {
+ return CURLE_OUT_OF_MEMORY;
+ }
+
+ size = type_3.cbBuffer;
+
+ ntlm_sspi_cleanup(ntlm);
+
+#else
int lmrespoff;
int ntrespoff;
int useroff;
@@ -552,6 +707,8 @@
ntlmbuf[56] = (unsigned char)(size & 0xff);
ntlmbuf[57] = (unsigned char)(size >> 8);
+#endif
+
/* convert the binary blob into base64 */
size = Curl_base64_encode((char *)ntlmbuf, size, &base64);
@@ -583,5 +740,16 @@
return CURLE_OK;
}
+
+
+void
+Curl_ntlm_cleanup(struct connectdata *conn)
+{
+#if USE_WINDOWS_SSPI
+ ntlm_sspi_cleanup(&conn->ntlm);
+ ntlm_sspi_cleanup(&conn->proxyntlm);
+#endif
+}
+
#endif /* USE_SSLEAY */
#endif /* !CURL_DISABLE_HTTP */
diff -r --unified orig/curl-7.13.0/lib/http_ntlm.h curl-7.13.0/lib/http_ntlm.h
--- orig/curl-7.13.0/lib/http_ntlm.h 2004-03-30 01:39:24.000000000 -0500
+++ curl-7.13.0/lib/http_ntlm.h 2005-02-14 09:53:43.062500000 -0500
@@ -38,7 +38,7 @@
/* this is for creating ntlm header output */
CURLcode Curl_output_ntlm(struct connectdata *conn, bool proxy);
-void Curl_ntlm_cleanup(struct SessionHandle *data);
+void Curl_ntlm_cleanup(struct connectdata *conn);
/* Flag bits definitions based on http://davenport.sourceforge.net/ntlm.html */
Only in curl-7.13.0/lib: libcurl.lib
Only in curl-7.13.0/lib: release-ssl-zlib
diff -r --unified orig/curl-7.13.0/lib/url.c curl-7.13.0/lib/url.c
--- orig/curl-7.13.0/lib/url.c 2005-01-30 07:42:15.000000000 -0500
+++ curl-7.13.0/lib/url.c 2005-02-14 17:45:18.125000000 -0500
@@ -130,7 +130,7 @@
#include "url.h"
#include "connect.h"
#include "inet_ntop.h"
-#include <ca-bundle.h>
+#include "ca-bundle.h"
#if defined(HAVE_INET_NTOA_R) && !defined(HAVE_INET_NTOA_R_DECL)
#include "inet_ntoa_r.h"
@@ -832,7 +832,7 @@
{
long auth = va_arg(param, long);
/* switch off bits we can't support */
-#ifndef USE_SSLEAY
+#if ! defined(USE_SSLEAY) && !(defined(WIN32) && defined(USE_WINDOWS_SSPI))
auth &= ~CURLAUTH_NTLM; /* no NTLM without SSL */
#endif
#ifndef HAVE_GSSAPI
@@ -1449,6 +1449,10 @@
data->state.authhost.want;
data->state.authproblem = FALSE;
+
+#if defined(USE_SSLEAY) || (defined(WIN32) && defined(USE_WINDOWS_SSPI))
+ Curl_ntlm_cleanup(conn);
+#endif
}
if(conn->curl_disconnect)
diff -r --unified orig/curl-7.13.0/lib/urldata.h curl-7.13.0/lib/urldata.h
--- orig/curl-7.13.0/lib/urldata.h 2005-01-29 08:08:59.000000000 -0500
+++ curl-7.13.0/lib/urldata.h 2005-02-14 09:53:43.078125000 -0500
@@ -188,10 +188,27 @@
NTLMSTATE_LAST
} curlntlm;
+#if USE_WINDOWS_SSPI
+#define SECURITY_WIN32 1
+#include <Security.h>
+#include <rpc.h>
+#endif
+
/* Struct used for NTLM challenge-response authentication */
struct ntlmdata {
curlntlm state;
+#if USE_WINDOWS_SSPI
+ CredHandle handle;
+ CtxtHandle c_handle;
+ SEC_WINNT_AUTH_IDENTITY identity;
+ SEC_WINNT_AUTH_IDENTITY *p_identity;
+ int has_handles;
+
+ void *type_2;
+ int n_type_2;
+#else
unsigned char nonce[8];
+#endif
};
#ifdef HAVE_GSSAPI
Only in curl-7.13.0/lib: vc60.idb
Only in curl-7.13.0/lib: vc60.pch
diff -r --unified orig/curl-7.13.0/lib/version.c curl-7.13.0/lib/version.c
--- orig/curl-7.13.0/lib/version.c 2004-12-20 13:23:43.000000000 -0500
+++ curl-7.13.0/lib/version.c 2005-02-14 10:00:24.687500000 -0500
@@ -194,6 +194,8 @@
#endif
#ifdef USE_SSLEAY
| CURL_VERSION_SSL
+#endif
+#if defined(USE_SSLEAY) || (defined(WIN32) && defined(USE_WINDOWS_SSPI))
| CURL_VERSION_NTLM /* since this requires OpenSSL */
#endif
#ifdef HAVE_LIBZ
Only in curl-7.13.0/: libz.lib
diff -r --unified orig/curl-7.13.0/src/Makefile.vc6 curl-7.13.0/src/Makefile.vc6
--- orig/curl-7.13.0/src/Makefile.vc6 2005-01-19 04:46:47.000000000 -0500
+++ curl-7.13.0/src/Makefile.vc6 2005-02-14 10:09:34.484375000 -0500
@@ -37,7 +37,7 @@
## Release
CCR = cl.exe /MD /O2 /DNDEBUG
-LINKR = link.exe /incremental:no /libpath:"../lib"
+LINKR = link.exe /incremental:no /libpath:"../lib" /nodefaultlib:libc
RCR = rc.exe /dCURLDEBUG=0
## Debug
@@ -177,6 +177,13 @@
LFLAGS = $(LFLAGS) $(SSL_IMP_LFLAGS) $(ZLIB_LFLAGS)
!ENDIF
+#################################################
+# debug
+
+!IF "$(CFG)" == "debug"
+LINKLIBS = libcurld.lib
+!ENDIF
+
LINKLIBS = $(LINKLIBS) wsock32.lib winmm.lib
LINKLIBS_DEBUG = $(LINKLIBS_DEBUG) wsock32.lib winmm.lib
@@ -184,10 +191,10 @@
all : release
release: $(RELEASE_OBJS)
- $(LINKR) $(LFLAGS) $(LINKLIBS) $(RELEASE_OBJS)
+ $(LINKR) $(LFLAGS) $(LINKLIBS) $(RELEASE_OBJS) "C:\Program Files\Microsoft SDK\lib\secur32.lib"
debug: $(DEBUG_OBJS)
- $(LINKD) $(LFLAGS) $(LINKLIBS_DEBUG) $(DEBUG_OBJS)
+ $(LINKD) $(LFLAGS) $(LINKLIBS_DEBUG) $(DEBUG_OBJS) "C:\Program Files\Microsoft SDK\lib\secur32.lib"
## Release
hugehelpr.obj: hugehelp.c
Only in curl-7.13.0/src: Makefile.vc6.orig
Only in curl-7.13.0/src: curl.exe
Only in curl-7.13.0/src: curl.exp
Only in curl-7.13.0/src: curl.lib
Only in curl-7.13.0/src: curl.opt
Only in curl-7.13.0/src: curlr.res
Only in curl-7.13.0/src: getpassr.obj
Only in curl-7.13.0/src: homedirr.obj
Only in curl-7.13.0/src: hugehelpd.exe
Only in curl-7.13.0/src: hugehelpd.exp
Only in curl-7.13.0/src: hugehelpd.lib
Only in curl-7.13.0/src: hugehelpr.obj
Only in curl-7.13.0/src: mainr.obj
Only in curl-7.13.0/src: strtoofftr.obj
Only in curl-7.13.0/src: timevalr.obj
Only in curl-7.13.0/src: urlglobr.obj
Only in curl-7.13.0/src: vc60.idb
Only in curl-7.13.0/src: vc60.pch
Only in curl-7.13.0/src: writeoutr.obj
Only in curl-7.13.0/: zconf.h
Only in curl-7.13.0/: zlib.h
Only in curl-7.13.0/: zlib.lib
Received on 2005-03-03