From 9db36827fb5eade403143b36566914ee9dc37d7b Mon Sep 17 00:00:00 2001
From: Steve Holme <steve_holme@hotmail.com>
Date: Thu, 20 Feb 2014 23:51:36 +0000
Subject: [PATCH] url: Fixed connection re-use when using different log-in
 credentials

In addition to FTP, other connection based protocols such as IMAP, POP3,
SMTP, SCP, SFTP and LDAP require a new connection when different log-in
credentials are specified. Fixed the detection logic to include these
other protocols.

Bug: http://curl.haxx.se/docs/adv_20140326A.html

---
There's an issue with test 519 - it hangs.
In short: because the test server (sws) runs in a single thread and doesn't fork.

The test 519 connects to the server over HTTP with a username/password and
later tries it with anotheruser/anotherpassword.

The server runs a simple accept() loop where it serves the clients using
recv()/send().

Before the security patch, the two GET requests the test makes were
issued from a single connection.
Thus the server served the first request and later the other in a single
run of the accept() loop.

After the patch, the two request now come in two separate connections.
So the server accept()s the first connection and then waits in recv(),
because the connection is still open.
The code never gets to another accept() so the second connection isn't
served at all.

---
 lib/http.c    | 2 +-
 lib/url.c     | 7 ++++---
 lib/urldata.h | 2 ++
 3 files changed, 7 insertions(+), 4 deletions(-)

Index: curl-7.19.7/lib/http.c
===================================================================
--- curl-7.19.7.orig/lib/http.c	2014-03-17 12:35:47.021495957 +0100
+++ curl-7.19.7/lib/http.c	2014-03-17 12:40:51.478753181 +0100
@@ -162,7 +162,7 @@ const struct Curl_handler Curl_handler_h
   ZERO_NULL,                            /* perform_getsock */
   ZERO_NULL,                            /* disconnect */
   PORT_HTTPS,                           /* defport */
-  PROT_HTTP | PROT_HTTPS | PROT_SSL     /* protocol */
+  PROT_HTTP | PROT_HTTPS | PROT_SSL | PROTOPT_CREDSPERREQUEST    /* protocol */
 };
 #endif
 
Index: curl-7.19.7/lib/url.c
===================================================================
--- curl-7.19.7.orig/lib/url.c	2014-03-17 12:35:47.023495979 +0100
+++ curl-7.19.7/lib/url.c	2014-03-17 12:43:24.543389047 +0100
@@ -2740,11 +2740,11 @@ ConnectionExists(struct SessionHandle *d
             continue;
           }
         }
-        if((needle->protocol & PROT_FTP) ||
+      if((!(needle->protocol & PROTOPT_CREDSPERREQUEST)) ||
            ((needle->protocol & PROT_HTTP) &&
             (data->state.authhost.want & CURLAUTH_NTLM))) {
-          /* This is FTP or HTTP+NTLM, verify that we're using the same name
-             and password as well */
+        /* This protocol requires credentials per connection or is HTTP+NTLM,
+           so verify that we're using the same name and password as well */
           if(!strequal(needle->user, check->user) ||
              !strequal(needle->passwd, check->passwd)) {
             /* one of them was different */
Index: curl-7.19.7/lib/urldata.h
===================================================================
--- curl-7.19.7.orig/lib/urldata.h	2014-03-17 12:35:47.023495979 +0100
+++ curl-7.19.7/lib/urldata.h	2014-03-17 12:45:58.271030918 +0100
@@ -931,6 +931,8 @@ struct connectdata {
 
 #define PROT_SSL     (1<<22) /* protocol requires SSL */
 #define PROT_MISSING (1<<23)
+#define PROTOPT_CREDSPERREQUEST (1<<24) /* requires login creditials per request
+                                          as opposed to per connection */
 
 #define PROT_CLOSEACTION PROT_FTP /* these ones need action before socket
                                      close */
Index: curl-7.19.7/tests/data/DISABLED
===================================================================
--- curl-7.19.7.orig/tests/data/DISABLED	2009-09-26 22:51:51.000000000 +0200
+++ curl-7.19.7/tests/data/DISABLED	2014-04-09 17:30:28.875339562 +0200
@@ -3,6 +3,7 @@
 # test cases are run by runtests.pl. Just add the plain test case numbers, one
 # per line.
 # Lines starting with '#' letters are treated as comments.
+519
 563
 564
 
