summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEdward Thomson <ethomson@edwardthomson.com>2018-10-22 11:29:01 +0100
committerEdward Thomson <ethomson@edwardthomson.com>2018-11-28 15:30:17 +0000
commit6af8572c7f282f458c6c63b005a85c46a14569db (patch)
treead2404339b72b981e0f5ba98d14bd7bc8c668d8b
parent2265481261c63a562e4d07f624f7888a5ee0c50c (diff)
downloadlibgit2-6af8572c7f282f458c6c63b005a85c46a14569db.tar.gz
http transport: cap number of authentication replays
Put a limit on the number of authentication replays in the HTTP transport. Standardize on 7 replays for authentication or redirects, which matches the behavior of the WinHTTP transport.
-rw-r--r--src/transports/http.c15
-rw-r--r--src/transports/http.h2
-rw-r--r--src/transports/winhttp.c2
3 files changed, 10 insertions, 9 deletions
diff --git a/src/transports/http.c b/src/transports/http.c
index 29924a0c2..5c060f4aa 100644
--- a/src/transports/http.c
+++ b/src/transports/http.c
@@ -66,7 +66,7 @@ typedef struct {
unsigned sent_request : 1,
received_response : 1,
chunked : 1,
- redirect_count : 3;
+ replay_count : 3;
} http_stream;
typedef struct {
@@ -424,6 +424,12 @@ static int on_headers_complete(http_parser *parser)
git_buf buf = GIT_BUF_INIT;
int allowed_proxy_auth_types = 0, allowed_www_auth_types = 0;
+ /* Enforce a reasonable cap on the number of replays */
+ if (s->replay_count++ >= GIT_HTTP_REPLAY_MAX) {
+ giterr_set(GITERR_NET, "too many redirects or authentication replays");
+ return t->parse_error = PARSE_ERROR_GENERIC;
+ }
+
/* Both parse_header_name and parse_header_value are populated
* and ready for consumption. */
if (VALUE == t->last_cb)
@@ -472,11 +478,6 @@ static int on_headers_complete(http_parser *parser)
parser->status_code == 308) &&
t->location) {
- if (s->redirect_count >= 7) {
- giterr_set(GITERR_NET, "too many redirects");
- return t->parse_error = PARSE_ERROR_GENERIC;
- }
-
if (gitno_connection_data_from_url(&t->gitserver_data, t->location, s->service_url) < 0)
return t->parse_error = PARSE_ERROR_GENERIC;
@@ -489,8 +490,6 @@ static int on_headers_complete(http_parser *parser)
t->location = NULL;
t->connected = 0;
- s->redirect_count++;
-
t->parse_error = PARSE_ERROR_REPLAY;
return 0;
}
diff --git a/src/transports/http.h b/src/transports/http.h
index 6c4ecc9a4..b09475755 100644
--- a/src/transports/http.h
+++ b/src/transports/http.h
@@ -10,6 +10,8 @@
#include "buffer.h"
+#define GIT_HTTP_REPLAY_MAX 7
+
GIT_INLINE(int) git_http__user_agent(git_buf *buf)
{
const char *ua = git_libgit2__user_agent();
diff --git a/src/transports/winhttp.c b/src/transports/winhttp.c
index 5e7bde73c..30e2ecb73 100644
--- a/src/transports/winhttp.c
+++ b/src/transports/winhttp.c
@@ -932,7 +932,7 @@ static int winhttp_stream_read(
replay:
/* Enforce a reasonable cap on the number of replays */
- if (++replay_count >= 7) {
+ if (replay_count++ >= GIT_HTTP_REPLAY_MAX) {
giterr_set(GITERR_NET, "too many redirects or authentication replays");
return -1;
}