summaryrefslogtreecommitdiff
path: root/external/neon/neon.patch
blob: 23aef0d0fe85122433409b0f241e1817a403eef4 (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
--- 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_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_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 around 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_openssl.c
+++ src/ne_openssl.c
@@ -43,6 +43,13 @@
 #endif
 #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 +805,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
 }