]> git.ipfire.org Git - thirdparty/git.git/blobdiff - http.c
Merge branch 'bw/protocol-v2'
[thirdparty/git.git] / http.c
diff --git a/http.c b/http.c
index 531c59d21e3e99f3b6c14b0bd0967285393b4359..fed13b2169a49aa602fc2ff21d45e368e1734d79 100644 (file)
--- a/http.c
+++ b/http.c
 #include "transport.h"
 #include "packfile.h"
 #include "protocol.h"
+#include "string-list.h"
+#include "object-store.h"
 
 static struct trace_key trace_curl = TRACE_KEY_INIT(CURL);
+static int trace_curl_data = 1;
+static struct string_list cookies_to_redact = STRING_LIST_INIT_DUP;
 #if LIBCURL_VERSION_NUM >= 0x070a08
 long int git_curl_ipresolve = CURL_IPRESOLVE_WHATEVER;
 #else
@@ -59,6 +63,9 @@ static struct {
        { "tlsv1.1", CURL_SSLVERSION_TLSv1_1 },
        { "tlsv1.2", CURL_SSLVERSION_TLSv1_2 },
 #endif
+#if LIBCURL_VERSION_NUM >= 0x073400
+       { "tlsv1.3", CURL_SSLVERSION_TLSv1_3 },
+#endif
 };
 #if LIBCURL_VERSION_NUM >= 0x070903
 static const char *ssl_key;
@@ -66,6 +73,9 @@ static const char *ssl_key;
 #if LIBCURL_VERSION_NUM >= 0x070908
 static const char *ssl_capath;
 #endif
+#if LIBCURL_VERSION_NUM >= 0x071304
+static const char *curl_no_proxy;
+#endif
 #if LIBCURL_VERSION_NUM >= 0x072c00
 static const char *ssl_pinnedkey;
 #endif
@@ -74,7 +84,6 @@ static long curl_low_speed_limit = -1;
 static long curl_low_speed_time = -1;
 static int curl_ftp_no_epsv;
 static const char *curl_http_proxy;
-static const char *curl_no_proxy;
 static const char *http_proxy_authmethod;
 static struct {
        const char *name;
@@ -575,6 +584,54 @@ static void redact_sensitive_header(struct strbuf *header)
                /* Everything else is opaque and possibly sensitive */
                strbuf_setlen(header,  sensitive_header - header->buf);
                strbuf_addstr(header, " <redacted>");
+       } else if (cookies_to_redact.nr &&
+                  skip_prefix(header->buf, "Cookie:", &sensitive_header)) {
+               struct strbuf redacted_header = STRBUF_INIT;
+               char *cookie;
+
+               while (isspace(*sensitive_header))
+                       sensitive_header++;
+
+               /*
+                * The contents of header starting from sensitive_header will
+                * subsequently be overridden, so it is fine to mutate this
+                * string (hence the assignment to "char *").
+                */
+               cookie = (char *) sensitive_header;
+
+               while (cookie) {
+                       char *equals;
+                       char *semicolon = strstr(cookie, "; ");
+                       if (semicolon)
+                               *semicolon = 0;
+                       equals = strchrnul(cookie, '=');
+                       if (!equals) {
+                               /* invalid cookie, just append and continue */
+                               strbuf_addstr(&redacted_header, cookie);
+                               continue;
+                       }
+                       *equals = 0; /* temporarily set to NUL for lookup */
+                       if (string_list_lookup(&cookies_to_redact, cookie)) {
+                               strbuf_addstr(&redacted_header, cookie);
+                               strbuf_addstr(&redacted_header, "=<redacted>");
+                       } else {
+                               *equals = '=';
+                               strbuf_addstr(&redacted_header, cookie);
+                       }
+                       if (semicolon) {
+                               /*
+                                * There are more cookies. (Or, for some
+                                * reason, the input string ends in "; ".)
+                                */
+                               strbuf_addstr(&redacted_header, "; ");
+                               cookie = semicolon + strlen("; ");
+                       } else {
+                               cookie = NULL;
+                       }
+               }
+
+               strbuf_setlen(header, sensitive_header - header->buf);
+               strbuf_addbuf(header, &redacted_header);
        }
 }
 
@@ -645,24 +702,32 @@ static int curl_trace(CURL *handle, curl_infotype type, char *data, size_t size,
                curl_dump_header(text, (unsigned char *)data, size, DO_FILTER);
                break;
        case CURLINFO_DATA_OUT:
-               text = "=> Send data";
-               curl_dump_data(text, (unsigned char *)data, size);
+               if (trace_curl_data) {
+                       text = "=> Send data";
+                       curl_dump_data(text, (unsigned char *)data, size);
+               }
                break;
        case CURLINFO_SSL_DATA_OUT:
-               text = "=> Send SSL data";
-               curl_dump_data(text, (unsigned char *)data, size);
+               if (trace_curl_data) {
+                       text = "=> Send SSL data";
+                       curl_dump_data(text, (unsigned char *)data, size);
+               }
                break;
        case CURLINFO_HEADER_IN:
                text = "<= Recv header";
                curl_dump_header(text, (unsigned char *)data, size, NO_FILTER);
                break;
        case CURLINFO_DATA_IN:
-               text = "<= Recv data";
-               curl_dump_data(text, (unsigned char *)data, size);
+               if (trace_curl_data) {
+                       text = "<= Recv data";
+                       curl_dump_data(text, (unsigned char *)data, size);
+               }
                break;
        case CURLINFO_SSL_DATA_IN:
-               text = "<= Recv SSL data";
-               curl_dump_data(text, (unsigned char *)data, size);
+               if (trace_curl_data) {
+                       text = "<= Recv SSL data";
+                       curl_dump_data(text, (unsigned char *)data, size);
+               }
                break;
 
        default:                /* we ignore unknown types by default */
@@ -807,6 +872,13 @@ static CURL *get_curl_handle(void)
        if (getenv("GIT_CURL_VERBOSE"))
                curl_easy_setopt(result, CURLOPT_VERBOSE, 1L);
        setup_curl_trace(result);
+       if (getenv("GIT_TRACE_CURL_NO_DATA"))
+               trace_curl_data = 0;
+       if (getenv("GIT_REDACT_COOKIES")) {
+               string_list_split(&cookies_to_redact,
+                                 getenv("GIT_REDACT_COOKIES"), ',', -1);
+               string_list_sort(&cookies_to_redact);
+       }
 
        curl_easy_setopt(result, CURLOPT_USERAGENT,
                user_agent ? user_agent : git_user_agent());
@@ -1177,14 +1249,14 @@ static struct fill_chain *fill_cfg;
 
 void add_fill_function(void *data, int (*fill)(void *))
 {
-       struct fill_chain *new = xmalloc(sizeof(*new));
+       struct fill_chain *new_fill = xmalloc(sizeof(*new_fill));
        struct fill_chain **linkp = &fill_cfg;
-       new->data = data;
-       new->fill = fill;
-       new->next = NULL;
+       new_fill->data = data;
+       new_fill->fill = fill;
+       new_fill->next = NULL;
        while (*linkp)
                linkp = &(*linkp)->next;
-       *linkp = new;
+       *linkp = new_fill;
 }
 
 void fill_active_slots(void)
@@ -2021,7 +2093,6 @@ int finish_http_pack_request(struct http_pack_request *preq)
        char *tmp_idx;
        size_t len;
        struct child_process ip = CHILD_PROCESS_INIT;
-       const char *ip_argv[8];
 
        close_pack_index(p);
 
@@ -2037,13 +2108,9 @@ int finish_http_pack_request(struct http_pack_request *preq)
                die("BUG: pack tmpfile does not end in .pack.temp?");
        tmp_idx = xstrfmt("%.*s.idx.temp", (int)len, preq->tmpfile);
 
-       ip_argv[0] = "index-pack";
-       ip_argv[1] = "-o";
-       ip_argv[2] = tmp_idx;
-       ip_argv[3] = preq->tmpfile;
-       ip_argv[4] = NULL;
-
-       ip.argv = ip_argv;
+       argv_array_push(&ip.args, "index-pack");
+       argv_array_pushl(&ip.args, "-o", tmp_idx, NULL);
+       argv_array_push(&ip.args, preq->tmpfile);
        ip.git_cmd = 1;
        ip.no_stdin = 1;
        ip.no_stdout = 1;
@@ -2063,7 +2130,7 @@ int finish_http_pack_request(struct http_pack_request *preq)
                return -1;
        }
 
-       install_packed_git(p);
+       install_packed_git(the_repository, p);
        free(tmp_idx);
        return 0;
 }
@@ -2164,7 +2231,7 @@ struct http_object_request *new_http_object_request(const char *base_url,
        unsigned char *sha1)
 {
        char *hex = sha1_to_hex(sha1);
-       const char *filename;
+       struct strbuf filename = STRBUF_INIT;
        char prevfile[PATH_MAX];
        int prevlocal;
        char prev_buf[PREV_BUF_SIZE];
@@ -2176,14 +2243,15 @@ struct http_object_request *new_http_object_request(const char *base_url,
        hashcpy(freq->sha1, sha1);
        freq->localfile = -1;
 
-       filename = sha1_file_name(sha1);
+       sha1_file_name(the_repository, &filename, sha1);
        snprintf(freq->tmpfile, sizeof(freq->tmpfile),
-                "%s.temp", filename);
+                "%s.temp", filename.buf);
 
-       snprintf(prevfile, sizeof(prevfile), "%s.prev", filename);
+       snprintf(prevfile, sizeof(prevfile), "%s.prev", filename.buf);
        unlink_or_warn(prevfile);
        rename(freq->tmpfile, prevfile);
        unlink_or_warn(freq->tmpfile);
+       strbuf_release(&filename);
 
        if (freq->localfile != -1)
                error("fd leakage in start: %d", freq->localfile);
@@ -2298,6 +2366,7 @@ void process_http_object_request(struct http_object_request *freq)
 int finish_http_object_request(struct http_object_request *freq)
 {
        struct stat st;
+       struct strbuf filename = STRBUF_INIT;
 
        close(freq->localfile);
        freq->localfile = -1;
@@ -2323,8 +2392,9 @@ int finish_http_object_request(struct http_object_request *freq)
                unlink_or_warn(freq->tmpfile);
                return -1;
        }
-       freq->rename =
-               finalize_object_file(freq->tmpfile, sha1_file_name(freq->sha1));
+       sha1_file_name(the_repository, &filename, freq->sha1);
+       freq->rename = finalize_object_file(freq->tmpfile, filename.buf);
+       strbuf_release(&filename);
 
        return freq->rename;
 }