summaryrefslogtreecommitdiff
path: root/neon/neon.patch
blob: 95d6b55024b3029dd131d55d19e387eb6e5319bd (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
--- src/ne_auth.c	2010-10-14 17:00:53.000000000 +0200
+++ src/ne_auth.c	2011-02-03 10:31:22.000000000 +0100
@@ -367,7 +367,7 @@
 static int get_credentials(auth_session *sess, ne_buffer **errmsg, int attempt,
                            struct auth_challenge *chall, char *pwbuf) 
 {
-    if (chall->handler->creds(chall->handler->userdata, sess->realm, 
+    if (chall->handler->creds(chall->handler->userdata, chall->protocol->name, sess->realm, 
                               chall->handler->attempt++, sess->username, pwbuf) == 0) {
         return 0;
     } else {
@@ -385,15 +385,19 @@
 {
     char *tmp, password[NE_ABUFSIZ];
 
+#if 0 /* Workaround - IIS sends challenge without realm. */
+
     /* Verify challenge... must have a realm */
     if (parms->realm == NULL) {
         challenge_error(errmsg, _("missing realm in Basic challenge"));
 	return -1;
     }
+#endif
 
     clean_session(sess);
     
-    sess->realm = ne_strdup(parms->realm);
+    if (parms->realm != NULL)
+        sess->realm = ne_strdup(parms->realm);
 
     if (get_credentials(sess, errmsg, attempt, parms, password)) {
 	/* Failed to get credentials */
@@ -610,10 +614,12 @@
         return NULL;
 }
 
-static int continue_sspi(auth_session *sess, int ntlm, const char *hdr)
+static int continue_sspi(auth_session *sess, int ntlm, const char *hdr,
+                         int attempt, struct auth_challenge *parms, ne_buffer **errmsg)
 {
     int status;
     char *response = NULL;
+    char password[NE_ABUFSIZ];
     
     NE_DEBUG(NE_DBG_HTTPAUTH, "auth: SSPI challenge.\n");
     
@@ -630,8 +636,17 @@
             return status;
         }
     }
-    
-    status = ne_sspi_authenticate(sess->sspi_context, hdr, &response);
+   
+    /* Authentification needs more than one http request.
+     * As long as authentification in progress use the existing credentials.
+     * Otherwise get new credentials.*/
+    if (!hdr)
+        if (get_credentials(sess, errmsg, attempt, parms, password)) {
+            /* Failed to get credentials */
+            return -1;
+        } 
+
+    status = ne_sspi_authenticate(sess->sspi_context, hdr, &response, sess->username, password);
     if (status) {
         return status;
     }
@@ -651,7 +666,7 @@
 {
     int ntlm = ne_strcasecmp(parms->protocol->name, "NTLM") == 0;
 
-    return continue_sspi(sess, ntlm, parms->opaque);
+    return continue_sspi(sess, ntlm, parms->opaque, attempt, parms, errmsg);
 }
 
 static int verify_sspi(struct auth_request *req, auth_session *sess,
@@ -674,7 +689,7 @@
         return NE_OK;
     }
 
-    return continue_sspi(sess, ntlm, ptr);
+    return continue_sspi(sess, ntlm, ptr, 0, NULL, NULL);
 }
 
 #endif
--- src/ne_auth.h	2009-09-01 22:13:12.000000000 +0200
+++ src/ne_auth.h	2011-02-03 10:26:20.000000000 +0100
@@ -47,8 +47,8 @@
  * Hint: if you just wish to attempt authentication just once (even if
  * the user gets the username/password wrong), have the callback
  * function use 'attempt' value as the function return value. */
-typedef int (*ne_auth_creds)(void *userdata, const char *realm, int attempt,
-			     char *username, char *password);
+typedef int (*ne_auth_creds)(void *userdata, const char * auth_protocol,
+                 const char *realm, int attempt, char *username, char *password);
 
 /* Set callbacks to provide credentials for server and proxy
  * authentication, using the default set of authentication protocols.
--- src/ne_defs.h	2010-01-11 23:57:34.000000000 +0100
+++ src/ne_defs.h	2011-02-03 10:26:20.000000000 +0100
@@ -41,7 +41,7 @@
 #endif
 
 /* define ssize_t for Win32 */
-#if defined(WIN32) && !defined(ssize_t)
+#if defined(WIN32) && !defined(ssize_t) && !defined(__MINGW32__)
 #define ssize_t int
 #endif
 
--- src/ne_locks.c	2007-02-05 11:09:27.000000000 +0100
+++ src/ne_locks.c	2011-02-03 10:26:21.000000000 +0100
@@ -579,6 +579,23 @@
         const char *token = ne_get_response_header(ctx->req, "Lock-Token");
         /* at the root element; retrieve the Lock-Token header,
          * and bail if it wasn't given. */
+#ifdef IIS_LOCK_BUG_WORKAROUND
+        /* MS IIS violates RFC 2518/4918. It does not send a Lock-Token response
+           header upon successful creation of a new lock. As a workaround, we
+           will try to pick the lock token from the response body (although
+           this is not 100% safe in case of multiple activelocks). */
+        if (token == NULL)
+	  NE_DEBUG(NE_DBG_LOCKS,
+		   "Ignoring missing LOCK response Lock-Token header\n");
+
+        if (token != NULL) {
+	  if (token[0] == '<') token++;
+	  ctx->token = ne_strdup(token);
+	  ne_shave(ctx->token, ">");
+	  NE_DEBUG(NE_DBG_LOCKS, "lk_startelm: Finding token %s\n",
+		   ctx->token);
+        }
+#else
         if (token == NULL) {
             ne_xml_set_error(ctx->parser, 
                              _("LOCK response missing Lock-Token header"));
@@ -590,12 +607,28 @@
         ne_shave(ctx->token, ">");
         NE_DEBUG(NE_DBG_LOCKS, "lk_startelm: Finding token %s\n",
                  ctx->token);
+#endif
     }
 
     /* TODO: only accept 'prop' as root for LOCK response */
     if (!can_accept(parent, id))
         return NE_XML_DECLINE;
 
+#ifdef IIS_LOCK_BUG_WORKAROUND
+    if (id == ELM_activelock && ctx->found) {
+      /* Found another activelock... */
+      const char *token = ne_get_response_header(ctx->req, "Lock-Token");
+      if (token == NULL) {
+	/* Response contains more than one activelock and no Lock-Token
+	 * response header. We are doomed. No safe workaround for IIS
+	 * lock bug possible. */
+	ne_xml_set_error(ctx->parser,
+			 _("LOCK response missing Lock-Token header and more than one activelock"));
+	return NE_XML_ABORT;
+      }
+    }
+#endif
+
     if (id == ELM_activelock && !ctx->found) {
 	/* a new activelock */
 	ne_lock_free(&ctx->active);
@@ -621,7 +654,12 @@
 	return -1;
 
     if (state == ELM_activelock) {
+#ifdef IIS_LOCK_BUG_WORKAROUND
+      if (ctx->active.token) {
+        ctx->token = ne_strdup(ctx->active.token);
+#else
 	if (ctx->active.token && strcmp(ctx->active.token, ctx->token) == 0) {
+#endif
 	    ctx->found = 1;
 	}
     }
--- src/ne_locks.h	2006-01-02 12:43:19.000000000 +0100
+++ src/ne_locks.h	2011-02-03 10:26:21.000000000 +0100
@@ -22,6 +22,10 @@
 #ifndef NE_LOCKS_H
 #define NE_LOCKS_H
 
+# if defined __GNUC__
+# pragma GCC system_header
+# endif
+
 #include "ne_request.h" /* for ne_session + ne_request */
 #include "ne_uri.h" /* for ne_uri */
 
--- src/ne_sspi.c	2007-08-10 17:26:08.000000000 +0200
+++ src/ne_sspi.c	2011-02-03 10:26:21.000000000 +0100
@@ -206,6 +206,45 @@
 }
 
 /*
+ * Simplification wrapper arround AcquireCredentialsHandle as most of
+ * the parameters do not change.
+ */
+static int acquireCredentialsHandleForUsername(CredHandle * credentials, char *package, const char *username, const char *password)
+{
+    SECURITY_STATUS status;
+    TimeStamp timestamp;
+
+	const char *domain = "";
+
+	int rc, rcISC;
+	SecPkgInfo *secPackInfo;
+	SEC_WINNT_AUTH_IDENTITY *nameAndPwd = NULL;
+	int bytesReceived = 0, bytesSent = 0;
+
+	nameAndPwd = (SEC_WINNT_AUTH_IDENTITY *) malloc( sizeof(SEC_WINNT_AUTH_IDENTITY) );
+	memset( nameAndPwd, '\0', sizeof (*nameAndPwd) );
+	nameAndPwd->Domain = (unsigned char *) _strdup( domain? domain: "" );
+	nameAndPwd->DomainLength = domain? strlen( domain ): 0;
+	nameAndPwd->User = (unsigned char *) _strdup( username? username: "" );
+	nameAndPwd->UserLength = username? strlen( username ): 0;
+	nameAndPwd->Password = (unsigned char *) _strdup( password? password: "" );
+	nameAndPwd->PasswordLength = password? strlen( password ): 0;
+	nameAndPwd->Flags = SEC_WINNT_AUTH_IDENTITY_ANSI;
+
+	status = pSFT->AcquireCredentialsHandle( NULL, package, SECPKG_CRED_OUTBOUND,
+		NULL, nameAndPwd, NULL, NULL, credentials, &timestamp );
+
+    if (status != SEC_E_OK) {
+        NE_DEBUG(NE_DBG_HTTPAUTH,
+                 "sspi: AcquireCredentialsHandle [fail] [%x].\n", status);
+        return -1;
+    }
+
+    return 0;
+}
+
+
+/*
  * Wrapper arround initializeSecurityContext.  Supplies several
  * default parameters as well as logging in case of errors.
  */
@@ -483,7 +522,7 @@
  * Processes received authentication tokens as well as supplies the
  * response token.
  */
-int ne_sspi_authenticate(void *context, const char *base64Token, char **responseToken)
+int ne_sspi_authenticate(void *context, const char *base64Token, char **responseToken, const char* username, const char* password)
 {
     SecBufferDesc outBufferDesc;
     SecBuffer outBuffer;
@@ -561,13 +600,22 @@
         /* Reset any existing context since we are starting over */
         resetContext(sspiContext);
 
-        if (acquireCredentialsHandle
-            (&sspiContext->credentials, sspiContext->mechanism) != SEC_E_OK) {
-                freeBuffer(&outBufferDesc);
-                NE_DEBUG(NE_DBG_HTTPAUTH,
-                    "sspi: acquireCredentialsHandle failed.\n");
-                return -1;
-        }
+	if (strlen(username) != 0) {
+	  if (acquireCredentialsHandleForUsername
+	        (&sspiContext->credentials, sspiContext->mechanism, username, password) != SEC_E_OK) {
+	    freeBuffer(&outBufferDesc);
+	    NE_DEBUG(NE_DBG_HTTPAUTH, "sspi: acquireCredentialsHandleForUsername failed.\n");
+	    return -1;
+	  }
+	} else {
+	  if (acquireCredentialsHandle
+	      (&sspiContext->credentials, sspiContext->mechanism) != SEC_E_OK) {
+	    freeBuffer(&outBufferDesc);
+	    NE_DEBUG(NE_DBG_HTTPAUTH, "sspi: acquireCredentialsHandle failed.\n");
+	    return -1;
+	  }
+	}
+
 
         securityStatus =
             initializeSecurityContext(&sspiContext->credentials, NULL,
--- src/ne_sspi.h	2006-02-12 13:05:14.000000000 +0100
+++ src/ne_sspi.h	2011-02-03 10:26:21.000000000 +0100
@@ -41,7 +41,7 @@
 int ne_sspi_clear_context(void *context);
 
 int ne_sspi_authenticate(void *context, const char *base64Token,
-                         char **responseToken);
+                         char **responseToken, const char* username, const char* password);
 
 #endif /* HAVE_SSPI */
 
--- src/ne_uri.c	2007-12-05 12:04:47.000000000 +0100
+++ src/ne_uri.c	2011-02-03 10:26:21.000000000 +0100
@@ -42,7 +42,7 @@
 #include "ne_alloc.h"
 #include "ne_uri.h"
 
-/* URI ABNF from RFC 3986: */
+/* URI ABNF from RFC 3986: (TKR: SharePoint is contradictory to this RFC. So I fix it here. )*/
 
 #define PS (0x0001) /* "+" */
 #define PC (0x0002) /* "%" */
@@ -67,6 +67,9 @@
 
 #define OT (0x4000) /* others */
 
+/* TKR new symbol */
+#define WS (0x8000) /* Whitespaces ( Space, Tab ) */
+
 #define URI_ALPHA (AL)
 #define URI_DIGIT (DG)
 
@@ -83,20 +86,21 @@
 /* pchar = unreserved / pct-encoded / sub-delims / ":" / "@" */
 #define URI_PCHAR (URI_UNRESERVED | PC | URI_SUBDELIM | CL | AT)
 /* invented: segchar = pchar / "/" */
-#define URI_SEGCHAR (URI_PCHAR | FS)
+/* (TKR) WS added */
+#define URI_SEGCHAR (URI_PCHAR | FS | WS)
 /* query = *( pchar / "/" / "?" ) */
 #define URI_QUERY (URI_PCHAR | FS | QU)
 /* fragment == query */
 #define URI_FRAGMENT URI_QUERY
 
 /* any characters which should be path-escaped: */
-#define URI_ESCAPE ((URI_GENDELIM & ~(FS)) | URI_SUBDELIM | OT | PC)
+#define URI_ESCAPE ((URI_GENDELIM & ~(FS)) | URI_SUBDELIM | OT | WS | PC)
 
 static const unsigned int uri_chars[256] = {
 /* 0xXX    x0      x2      x4      x6      x8      xA      xC      xE     */
-/*   0x */ OT, OT, OT, OT, OT, OT, OT, OT, OT, OT, OT, OT, OT, OT, OT, OT,
+/*   0x */ OT, OT, OT, OT, OT, OT, OT, OT, OT, WS, OT, OT, OT, OT, OT, OT,
 /*   1x */ OT, OT, OT, OT, OT, OT, OT, OT, OT, OT, OT, OT, OT, OT, OT, OT,
-/*   2x */ OT, SD, OT, GD, SD, PC, SD, SD, SD, SD, SD, PS, SD, DS, DT, FS,
+/*   2x */ WS, SD, OT, GD, SD, PC, SD, SD, SD, SD, SD, PS, SD, DS, DT, FS,
 /*   3x */ DG, DG, DG, DG, DG, DG, DG, DG, DG, DG, CL, SD, OT, SD, OT, QU,
 /*   4x */ AT, AL, AL, AL, AL, AL, AL, AL, AL, AL, AL, AL, AL, AL, AL, AL,
 /*   5x */ AL, AL, AL, AL, AL, AL, AL, AL, AL, AL, AL, GD, OT, GD, OT, US,
--- src/ne_utils.c	2006-03-07 10:36:43.000000000 +0100
+++ src/ne_utils.c	2011-02-03 10:26:21.000000000 +0100
@@ -118,6 +118,9 @@
 #ifdef HAVE_GNUTLS
     ", GNU TLS " LIBGNUTLS_VERSION
 #endif /* HAVE_GNUTLS */
+#ifdef HAVE_SSPI
+    ", SSPI"
+#endif /* HAVE_SSPI */
    "."
 ;
 
@@ -137,7 +140,7 @@
     switch (feature) {
 #if defined(NE_HAVE_SSL) || defined(NE_HAVE_ZLIB) || defined(NE_HAVE_IPV6) \
     || defined(NE_HAVE_SOCKS) || defined(NE_HAVE_LFS) \
-    || defined(NE_HAVE_TS_SSL) || defined(NE_HAVE_I18N)
+    || defined(NE_HAVE_TS_SSL) || defined(NE_HAVE_I18N) || defined(HAVE_SSPI)
 #ifdef NE_HAVE_SSL
     case NE_FEATURE_SSL:
 #endif
@@ -159,6 +162,9 @@
 #ifdef NE_HAVE_I18N
     case NE_FEATURE_I18N:
 #endif
+#ifdef HAVE_SSPI
+    case NE_FEATURE_SSPI:
+#endif
         return 1;
 #endif /* NE_HAVE_* */
     default:
--- src/ne_utils.h	2007-07-16 08:54:57.000000000 +0200
+++ src/ne_utils.h	2011-02-03 10:26:21.000000000 +0100
@@ -54,6 +54,7 @@
 #define NE_FEATURE_SOCKS (5) /* SOCKSv5 support */
 #define NE_FEATURE_TS_SSL (6) /* Thread-safe SSL/TLS support */
 #define NE_FEATURE_I18N (7) /* i18n error message support */
+#define NE_FEATURE_SSPI (8) /* NTLM/Negotiate authentication protocol via SSPI */
 
 /* Returns non-zero if library is built with support for the given
  * NE_FEATURE_* feature code 'code'. */
--- src/ne_openssl.c
+++ src/ne_openssl.c
@@ -41,6 +41,13 @@
 #include <pthread.h>
 #endif
 
+#ifdef WIN32
+#define X509_NAME WIN32_X509_NAME
+#include <windows.h>
+#include <wincrypt.h>
+#undef X509_NAME
+#endif
+
 #include "ne_ssl.h"
 #include "ne_string.h"
 #include "ne_session.h"
@@ -798,6 +798,31 @@
     X509_STORE_load_locations(store, NE_SSL_CA_BUNDLE, NULL);
 #else
     X509_STORE_set_default_paths(store);
+#ifdef WIN32
+    {
+	HCERTSTORE hStore;
+	PCCERT_CONTEXT pContext = NULL;
+	X509 *x509;
+
+	hStore = CertOpenSystemStore(0, "ROOT");
+	if (hStore)
+	{
+	    while (pContext = CertEnumCertificatesInStore(hStore, pContext))
+	    {
+		x509 = d2i_X509(NULL, &pContext->pbCertEncoded, pContext->cbCertEncoded);
+		if (x509)
+		{
+		    X509_STORE_add_cert(store, x509);
+		    X509_free(x509);
+		}
+	    }
+	}
+
+	CertFreeCertificateContext(pContext);
+	CertCloseStore(hStore, 0);
+    }
+#endif
+
 #endif
 }