diff options
author | Shawn Pearce <spearce@spearce.org> | 2013-01-31 13:02:07 -0800 |
---|---|---|
committer | Junio C Hamano <gitster@pobox.com> | 2013-02-04 10:22:36 -0800 |
commit | 4656bf47fca857df51b5d6f4b7b052192b3b2317 (patch) | |
tree | 91e4d6cf951f2964de99d454ec89e426753ac453 /remote-curl.c | |
parent | e1b6ff44d61bcdd91280c3f7c3c5ace32d4b7c52 (diff) | |
download | git-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.c | 17 |
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; |