summaryrefslogtreecommitdiff
path: root/www/firefox-esr/files/patch-ff-479880
blob: 761b90bbd3454a514face288c795f670531f761e (plain) (blame)
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
? 1.8.patch
Index: nsHttpChannel.cpp
===================================================================
RCS file: /cvsroot/mozilla/netwerk/protocol/http/src/nsHttpChannel.cpp,v
retrieving revision 1.256.2.22
diff -U 8 -p -p -r1.256.2.22 nsHttpChannel.cpp
--- netwerk/protocol/http/src/nsHttpChannel.cpp	20 Jul 2006 22:59:31 -0000	1.256.2.22
+++ netwerk/protocol/http/src/nsHttpChannel.cpp	28 May 2009 20:20:06 -0000
@@ -755,24 +755,92 @@ nsHttpChannel::CallOnStartRequest()
 
     // install stream converter if required
     ApplyContentConversions();
 
     return rv;
 }
 
 nsresult
+nsHttpChannel::ProcessFailedSSLConnect(PRUint32 httpStatus)
+{
+    // Failure to set up SSL proxy tunnel means one of the following:
+    // 1) Proxy wants authorization, or forbids.
+    // 2) DNS at proxy couldn't resolve target URL.
+    // 3) Proxy connection to target failed or timed out.
+    // 4) Eve noticed our proxy CONNECT, and is replying with malicious HTML.
+    // 
+    // Our current architecture will parse response content with the
+    // permission of the target URL!  Given #4, we must avoid rendering the
+    // body of the reply, and instead give the user a (hopefully helpful) 
+    // boilerplate error page, based on just the HTTP status of the reply.
+
+    NS_ABORT_IF_FALSE(mConnectionInfo->UsingSSL(),
+                      "SSL connect failed but not using SSL?");
+    nsresult rv;
+    switch (httpStatus) 
+    {
+    case 403: // HTTP/1.1: "Forbidden"
+    case 407: // ProcessAuthentication() failed
+    case 501: // HTTP/1.1: "Not Implemented"
+        // user sees boilerplate Mozilla "Proxy Refused Connection" page.
+        rv = NS_ERROR_PROXY_CONNECTION_REFUSED; 
+        break;
+    // Squid sends 404 if DNS fails (regular 404 from target is tunneled)
+    case 404: // HTTP/1.1: "Not Found"
+    // RFC 2616: "some deployed proxies are known to return 400 or 500 when
+    // DNS lookups time out."  (Squid uses 500 if it runs out of sockets: so
+    // we have a conflict here).
+    case 400: // HTTP/1.1 "Bad Request"
+    case 500: // HTTP/1.1: "Internal Server Error"
+        /* User sees: "Address Not Found: Firefox can't find the server at
+         * www.foo.com."
+         */
+        rv = NS_ERROR_UNKNOWN_HOST; 
+        break;
+    case 502: // HTTP/1.1: "Bad Gateway" (invalid resp from target server)
+    // Squid returns 503 if target request fails for anything but DNS.
+    case 503: // HTTP/1.1: "Service Unavailable"
+        /* User sees: "Failed to Connect:
+         *  Firefox can't establish a connection to the server at
+         *  www.foo.com.  Though the site seems valid, the browser
+         *  was unable to establish a connection."
+         */
+        rv = NS_ERROR_CONNECTION_REFUSED;
+        break;
+    // RFC 2616 uses 504 for both DNS and target timeout, so not clear what to
+    // do here: picking target timeout, as DNS covered by 400/404/500
+    case 504: // HTTP/1.1: "Gateway Timeout" 
+        // user sees: "Network Timeout: The server at www.foo.com
+        //              is taking too long to respond."
+        rv = NS_ERROR_NET_TIMEOUT;
+        break;
+    // Confused proxy server or malicious response
+    default:
+        rv = NS_ERROR_PROXY_CONNECTION_REFUSED; 
+        break;
+    }
+    LOG(("Cancelling failed SSL proxy connection [this=%x httpStatus=%u]\n",
+         this, httpStatus)); 
+    Cancel(rv);
+    return rv;
+}
+
+nsresult
 nsHttpChannel::ProcessResponse()
 {
     nsresult rv;
     PRUint32 httpStatus = mResponseHead->Status();
 
     LOG(("nsHttpChannel::ProcessResponse [this=%x httpStatus=%u]\n",
         this, httpStatus));
 
+    if (mTransaction->SSLConnectFailed() && httpStatus != 407)
+        return ProcessFailedSSLConnect(httpStatus);
+
     // notify "http-on-examine-response" observers
     gHttpHandler->OnExamineResponse(this);
 
     // set cookies, if any exist; done after OnExamineResponse to allow those
     // observers to modify the cookie response headers
     SetCookie(mResponseHead->PeekHeader(nsHttp::Set_Cookie));
 
     // handle unused username and password in url (see bug 232567)
@@ -837,16 +905,18 @@ nsHttpChannel::ProcessResponse()
             rv = ProcessNormal();
         }
         break;
     case 401:
     case 407:
         rv = ProcessAuthentication(httpStatus);
         if (NS_FAILED(rv)) {
             LOG(("ProcessAuthentication failed [rv=%x]\n", rv));
+            if (mTransaction->SSLConnectFailed())
+                return ProcessFailedSSLConnect(httpStatus);
             CheckForSuperfluousAuth();
             rv = ProcessNormal();
         }
         break;
     case 412: // Precondition failed
     case 416: // Invalid range
         if (mResuming) {
             Cancel(NS_ERROR_ENTITY_CHANGED);
Index: nsHttpChannel.h
===================================================================
RCS file: /cvsroot/mozilla/netwerk/protocol/http/src/nsHttpChannel.h,v
retrieving revision 1.70.4.5
diff -U 8 -p -p -r1.70.4.5 nsHttpChannel.h
--- netwerk/protocol/http/src/nsHttpChannel.h	27 Jun 2006 20:27:29 -0000	1.70.4.5
+++ netwerk/protocol/http/src/nsHttpChannel.h	28 May 2009 20:20:06 -0000
@@ -155,16 +155,17 @@ private:
     nsresult SetupTransaction();
     void     AddCookiesToRequest();
     void     ApplyContentConversions();
     nsresult CallOnStartRequest();
     nsresult ProcessResponse();
     nsresult ProcessNormal();
     nsresult ProcessNotModified();
     nsresult ProcessRedirection(PRUint32 httpStatus);
+    nsresult ProcessFailedSSLConnect(PRUint32 httpStatus);
     nsresult ProcessAuthentication(PRUint32 httpStatus);
     PRBool   ResponseWouldVary();
 
     // redirection specific methods
     void     HandleAsyncRedirect();
     void     HandleAsyncNotModified();
     nsresult PromptTempRedirect();
     nsresult SetupReplacementChannel(nsIURI *, nsIChannel *, PRBool preserveMethod);