summaryrefslogtreecommitdiff
path: root/remote-curl.c
diff options
context:
space:
mode:
authorShawn Pearce <spearce@spearce.org>2013-01-31 13:02:07 -0800
committerJunio C Hamano <gitster@pobox.com>2013-02-04 10:22:36 -0800
commit4656bf47fca857df51b5d6f4b7b052192b3b2317 (patch)
tree91e4d6cf951f2964de99d454ec89e426753ac453 /remote-curl.c
parente1b6ff44d61bcdd91280c3f7c3c5ace32d4b7c52 (diff)
downloadgit-4656bf47fca857df51b5d6f4b7b052192b3b2317.tar.gz
Verify Content-Type from smart HTTP servers
Before parsing a suspected smart-HTTP response verify the returned Content-Type matches the standard. This protects a client from attempting to process a payload that smells like a smart-HTTP server response. JGit has been doing this check on all responses since the dawn of time. I mistakenly failed to include it in git-core when smart HTTP was introduced. At the time I didn't know how to get the Content-Type from libcurl. I punted, meant to circle back and fix this, and just plain forgot about it. Signed-off-by: Shawn Pearce <spearce@spearce.org> Signed-off-by: Junio C Hamano <gitster@pobox.com>
Diffstat (limited to 'remote-curl.c')
-rw-r--r--remote-curl.c17
1 files changed, 12 insertions, 5 deletions
diff --git a/remote-curl.c b/remote-curl.c
index 9a8b123507..933c69ac26 100644
--- a/remote-curl.c
+++ b/remote-curl.c
@@ -92,6 +92,8 @@ static void free_discovery(struct discovery *d)
static struct discovery* discover_refs(const char *service)
{
+ struct strbuf exp = STRBUF_INIT;
+ struct strbuf type = STRBUF_INIT;
struct strbuf buffer = STRBUF_INIT;
struct discovery *last = last_discovery;
char *refs_url;
@@ -113,7 +115,7 @@ static struct discovery* discover_refs(const char *service)
}
refs_url = strbuf_detach(&buffer, NULL);
- http_ret = http_get_strbuf(refs_url, &buffer, HTTP_NO_CACHE);
+ http_ret = http_get_strbuf(refs_url, &type, &buffer, HTTP_NO_CACHE);
switch (http_ret) {
case HTTP_OK:
break;
@@ -132,17 +134,20 @@ static struct discovery* discover_refs(const char *service)
last->buf_alloc = strbuf_detach(&buffer, &last->len);
last->buf = last->buf_alloc;
- if (maybe_smart && 5 <= last->len && last->buf[4] == '#') {
- /* smart HTTP response; validate that the service
+ strbuf_addf(&exp, "application/x-%s-advertisement", service);
+ if (maybe_smart &&
+ (5 <= last->len && last->buf[4] == '#') &&
+ !strbuf_cmp(&exp, &type)) {
+ /*
+ * smart HTTP response; validate that the service
* pkt-line matches our request.
*/
- struct strbuf exp = STRBUF_INIT;
-
if (packet_get_line(&buffer, &last->buf, &last->len) <= 0)
die("%s has invalid packet header", refs_url);
if (buffer.len && buffer.buf[buffer.len - 1] == '\n')
strbuf_setlen(&buffer, buffer.len - 1);
+ strbuf_reset(&exp);
strbuf_addf(&exp, "# service=%s", service);
if (strbuf_cmp(&exp, &buffer))
die("invalid server response; got '%s'", buffer.buf);
@@ -160,6 +165,8 @@ static struct discovery* discover_refs(const char *service)
}
free(refs_url);
+ strbuf_release(&exp);
+ strbuf_release(&type);
strbuf_release(&buffer);
last_discovery = last;
return last;