aboutsummaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
authorStefan Bühler <buehler@teamviewer.com>2014-11-24 09:18:55 +0100
committerDaniel Stenberg <daniel@haxx.se>2014-12-04 14:41:48 -0800
commit5dc68dd6092a789bb5e0a67a1c1356ba87fdcbc6 (patch)
tree3404fcc942395ce32ab665439a65e75e8b8d5134 /lib
parent557ca620e4f3a981043a8bbde3846e0dc9bb9388 (diff)
HTTP: don't abort connections with pending Negotiate authentication
... similarly to how NTLM works as Negotiate is in fact often NTLM with another name.
Diffstat (limited to 'lib')
-rw-r--r--lib/http.c112
1 files changed, 82 insertions, 30 deletions
diff --git a/lib/http.c b/lib/http.c
index 79d0592bb..d32a01271 100644
--- a/lib/http.c
+++ b/lib/http.c
@@ -347,6 +347,82 @@ static bool pickoneauth(struct auth *pick)
return picked;
}
+/* whether to complete request (for authentication) in current connection */
+static bool complete_request(struct connectdata *conn,
+ curl_off_t remaining_bytes)
+{
+#if defined(USE_NTLM) || defined(USE_SPNEGO)
+ struct SessionHandle *data = conn->data;
+ bool have_ntlm_or_negotiate = FALSE;
+ bool auth_started = FALSE;
+
+ /* don't reset connection when we're in NTLM or Negotiate authentication;
+ * those authenticate the connection - creating a new connection breaks the
+ * authentication.
+ */
+
+#if defined(USE_NTLM)
+ /* proxy NTLM authentication */
+ if((data->state.authproxy.picked == CURLAUTH_NTLM) ||
+ (data->state.authproxy.picked == CURLAUTH_NTLM_WB)) {
+ have_ntlm_or_negotiate = TRUE;
+ auth_started = auth_started
+ || (conn->proxyntlm.state != NTLMSTATE_NONE);
+ }
+
+ /* normal NTLM authentication */
+ if((data->state.authhost.picked == CURLAUTH_NTLM) ||
+ (data->state.authhost.picked == CURLAUTH_NTLM_WB)) {
+ have_ntlm_or_negotiate = TRUE;
+ auth_started = auth_started
+ || (conn->ntlm.state != NTLMSTATE_NONE);
+ }
+#endif
+
+#if defined(USE_SPNEGO)
+ /* proxy Negotiate authentication */
+ if(data->state.authproxy.picked == CURLAUTH_NEGOTIATE) {
+ have_ntlm_or_negotiate = TRUE;
+ auth_started = auth_started
+ || (data->state.proxyneg.state != GSS_AUTHNONE);
+ }
+
+ /* normal Negotiate authentication */
+ if(data->state.authhost.picked == CURLAUTH_NEGOTIATE) {
+ have_ntlm_or_negotiate = TRUE;
+ auth_started = auth_started
+ || (data->state.negotiate.state != GSS_AUTHNONE);
+ }
+#endif
+
+ if(have_ntlm_or_negotiate) {
+ if(remaining_bytes < 2000 || auth_started) {
+ /* NTLM/Negotiation has started *OR* there is just a little (<2K)
+ * data left to send, keep on sending.
+ */
+
+ /* rewind data when completely done sending! */
+ if(!conn->bits.authneg) {
+ conn->bits.rewindaftersend = TRUE;
+ infof(data, "Rewind stream after send\n");
+ }
+
+ return TRUE;
+ }
+
+ infof(data, "NTLM/Negotiate send, close instead of sending %"
+ CURL_FORMAT_CURL_OFF_T " bytes\n",
+ remaining_bytes);
+ }
+#else
+ /* unused parameters: */
+ (void)conn;
+ (void)remaining_bytes;
+#endif
+
+ return FALSE;
+}
+
/*
* Curl_http_perhapsrewind()
*
@@ -420,36 +496,12 @@ static CURLcode http_perhapsrewind(struct connectdata *conn)
conn->bits.rewindaftersend = FALSE; /* default */
if((expectsend == -1) || (expectsend > bytessent)) {
-#if defined(USE_NTLM)
- /* There is still data left to send */
- if((data->state.authproxy.picked == CURLAUTH_NTLM) ||
- (data->state.authhost.picked == CURLAUTH_NTLM) ||
- (data->state.authproxy.picked == CURLAUTH_NTLM_WB) ||
- (data->state.authhost.picked == CURLAUTH_NTLM_WB)) {
- if(((expectsend - bytessent) < 2000) ||
- (conn->ntlm.state != NTLMSTATE_NONE) ||
- (conn->proxyntlm.state != NTLMSTATE_NONE)) {
- /* The NTLM-negotiation has started *OR* there is just a little (<2K)
- data left to send, keep on sending. */
-
- /* rewind data when completely done sending! */
- if(!conn->bits.authneg) {
- conn->bits.rewindaftersend = TRUE;
- infof(data, "Rewind stream after send\n");
- }
-
- return CURLE_OK;
- }
+ if(conn->bits.close)
+ /* this is already marked to get closed */
+ return CURLE_OK;
- if(conn->bits.close)
- /* this is already marked to get closed */
- return CURLE_OK;
-
- infof(data, "NTLM send, close instead of sending %"
- CURL_FORMAT_CURL_OFF_T " bytes\n",
- (curl_off_t)(expectsend - bytessent));
- }
-#endif
+ if(complete_request(conn, (curl_off_t)(expectsend - bytessent)))
+ return CURLE_OK;
/* This is not NTLM or many bytes left to send: close */
connclose(conn, "Mid-auth HTTP and much data left to send");
@@ -460,7 +512,7 @@ static CURLcode http_perhapsrewind(struct connectdata *conn)
}
if(bytessent)
- /* we rewind now at once since if we already sent something */
+ /* we rewind now at once since we already sent something */
return Curl_readrewind(conn);
return CURLE_OK;