Merge branch 'ps/http-gssapi-cred-delegation'
authorJunio C Hamano <gitster@pobox.com>
Thu, 6 Oct 2016 21:53:11 +0000 (14:53 -0700)
committerJunio C Hamano <gitster@pobox.com>
Thu, 6 Oct 2016 21:53:11 +0000 (14:53 -0700)
In recent versions of cURL, GSSAPI credential delegation is
disabled by default due to CVE-2011-2192; introduce a configuration
to selectively allow enabling this.

* ps/http-gssapi-cred-delegation:
http: control GSSAPI credential delegation

1  2 
Documentation/config.txt
http.c
diff --combined Documentation/config.txt
index e78293b6dbe31cd254cd64c94a045cfe9a2877a9,c588168d39658816a185e43cb19711df93ed1ec9..a17947462a931d70700461c8a1a7a32b20bd3676
@@@ -953,8 -953,7 +953,8 @@@ color.branch:
        A boolean to enable/disable color in the output of
        linkgit:git-branch[1]. May be set to `always`,
        `false` (or `never`) or `auto` (or `true`), in which case colors are used
 -      only when the output is to a terminal. Defaults to false.
 +      only when the output is to a terminal. If unset, then the
 +      value of `color.ui` is used (`auto` by default).
  
  color.branch.<slot>::
        Use customized color for branch coloration. `<slot>` is one of
@@@ -969,8 -968,7 +969,8 @@@ color.diff:
        linkgit:git-log[1], and linkgit:git-show[1] will use color
        for all patches.  If it is set to `true` or `auto`, those
        commands will only use color when output is to the terminal.
 -      Defaults to false.
 +      If unset, then the value of `color.ui` is used (`auto` by
 +      default).
  +
  This does not affect linkgit:git-format-patch[1] or the
  'git-diff-{asterisk}' plumbing commands.  Can be overridden on the
@@@ -993,8 -991,7 +993,8 @@@ color.decorate.<slot>:
  color.grep::
        When set to `always`, always highlight matches.  When `false` (or
        `never`), never.  When set to `true` or `auto`, use color only
 -      when the output is written to the terminal.  Defaults to `false`.
 +      when the output is written to the terminal.  If unset, then the
 +      value of `color.ui` is used (`auto` by default).
  
  color.grep.<slot>::
        Use customized color for grep colorization.  `<slot>` specifies which
@@@ -1027,8 -1024,7 +1027,8 @@@ color.interactive:
        and displays (such as those used by "git-add --interactive" and
        "git-clean --interactive"). When false (or `never`), never.
        When set to `true` or `auto`, use colors only when the output is
 -      to the terminal. Defaults to false.
 +      to the terminal. If unset, then the value of `color.ui` is
 +      used (`auto` by default).
  
  color.interactive.<slot>::
        Use customized color for 'git add --interactive' and 'git clean
@@@ -1044,15 -1040,13 +1044,15 @@@ color.showBranch:
        A boolean to enable/disable color in the output of
        linkgit:git-show-branch[1]. May be set to `always`,
        `false` (or `never`) or `auto` (or `true`), in which case colors are used
 -      only when the output is to a terminal. Defaults to false.
 +      only when the output is to a terminal. If unset, then the
 +      value of `color.ui` is used (`auto` by default).
  
  color.status::
        A boolean to enable/disable color in the output of
        linkgit:git-status[1]. May be set to `always`,
        `false` (or `never`) or `auto` (or `true`), in which case colors are used
 -      only when the output is to a terminal. Defaults to false.
 +      only when the output is to a terminal. If unset, then the
 +      value of `color.ui` is used (`auto` by default).
  
  color.status.<slot>::
        Use customized color for status colorization. `<slot>` is
@@@ -1372,7 -1366,7 +1372,7 @@@ fsck.skipList:
  gc.aggressiveDepth::
        The depth parameter used in the delta compression
        algorithm used by 'git gc --aggressive'.  This defaults
 -      to 250.
 +      to 50.
  
  gc.aggressiveWindow::
        The window size parameter used in the delta compression
@@@ -1736,6 -1730,20 +1736,20 @@@ http.emptyAuth:
        a username in the URL, as libcurl normally requires a username for
        authentication.
  
+ http.delegation::
+       Control GSSAPI credential delegation. The delegation is disabled
+       by default in libcurl since version 7.21.7. Set parameter to tell
+       the server what it is allowed to delegate when it comes to user
+       credentials. Used with GSS/kerberos. Possible values are:
+ +
+ --
+ * `none` - Don't allow any delegation.
+ * `policy` - Delegates if and only if the OK-AS-DELEGATE flag is set in the
+   Kerberos service ticket, which is a matter of realm policy.
+ * `always` - Unconditionally allow the server to delegate.
+ --
  http.extraHeader::
        Pass an additional HTTP header when communicating with a server.  If
        more than one such entry exists, all of them are added as extra
@@@ -2523,12 -2531,6 +2537,12 @@@ receive.unpackLimit:
        especially on slow filesystems.  If not set, the value of
        `transfer.unpackLimit` is used instead.
  
 +receive.maxInputSize::
 +      If the size of the incoming pack stream is larger than this
 +      limit, then git-receive-pack will error out, instead of
 +      accepting the pack file. If not set or set to 0, then the size
 +      is unlimited.
 +
  receive.denyDeletes::
        If set to true, git-receive-pack will deny a ref update that deletes
        the ref. Use this to prevent such a ref deletion via a push.
@@@ -2859,18 -2861,6 +2873,18 @@@ submodule.fetchJobs:
        in parallel. A value of 0 will give some reasonable default.
        If unset, it defaults to 1.
  
 +submodule.alternateLocation::
 +      Specifies how the submodules obtain alternates when submodules are
 +      cloned. Possible values are `no`, `superproject`.
 +      By default `no` is assumed, which doesn't add references. When the
 +      value is set to `superproject` the submodule to be cloned computes
 +      its alternates location relative to the superprojects alternate.
 +
 +submodule.alternateErrorStrategy
 +      Specifies how to treat errors with the alternates for a submodule
 +      as computed via `submodule.alternateLocation`. Possible values are
 +      `ignore`, `info`, `die`. Default is `die`.
 +
  tag.forceSignAnnotated::
        A boolean to specify whether annotated tags created should be GPG signed.
        If `--annotate` is specified on the command line, it takes
diff --combined http.c
index 82ed54269059c38e1698b7ffc1af0d1000e5bfec,624f0ce65d212e5ae05e42492b23afef80ccaf69..0c65639881c6572c6fb9c6038580f9d915daef05
--- 1/http.c
--- 2/http.c
+++ b/http.c
@@@ -90,6 -90,18 +90,18 @@@ static struct 
         * here, too
         */
  };
+ #if LIBCURL_VERSION_NUM >= 0x071600
+ static const char *curl_deleg;
+ static struct {
+       const char *name;
+       long curl_deleg_param;
+ } curl_deleg_levels[] = {
+       { "none", CURLGSSAPI_DELEGATION_NONE },
+       { "policy", CURLGSSAPI_DELEGATION_POLICY_FLAG },
+       { "always", CURLGSSAPI_DELEGATION_FLAG },
+ };
+ #endif
  static struct credential proxy_auth = CREDENTIAL_INIT;
  static const char *curl_proxyuserpwd;
  static const char *curl_cookie_file;
@@@ -201,13 -213,6 +213,13 @@@ static void finish_active_slot(struct a
                slot->callback_func(slot->callback_data);
  }
  
 +static void xmulti_remove_handle(struct active_request_slot *slot)
 +{
 +#ifdef USE_CURL_MULTI
 +      curl_multi_remove_handle(curlm, slot->curl);
 +#endif
 +}
 +
  #ifdef USE_CURL_MULTI
  static void process_curl_messages(void)
  {
                               slot->curl != curl_message->easy_handle)
                                slot = slot->next;
                        if (slot != NULL) {
 -                              curl_multi_remove_handle(curlm, slot->curl);
 +                              xmulti_remove_handle(slot);
                                slot->curl_result = curl_result;
                                finish_active_slot(slot);
                        } else {
@@@ -323,6 -328,15 +335,15 @@@ static int http_options(const char *var
                return 0;
        }
  
+       if (!strcmp("http.delegation", var)) {
+ #if LIBCURL_VERSION_NUM >= 0x071600
+               return git_config_string(&curl_deleg, var, value);
+ #else
+               warning(_("Delegation control is not supported with cURL < 7.22.0"));
+               return 0;
+ #endif
+       }
        if (!strcmp("http.pinnedpubkey", var)) {
  #if LIBCURL_VERSION_NUM >= 0x072c00
                return git_config_pathname(&ssl_pinnedkey, var, value);
@@@ -629,6 -643,22 +650,22 @@@ static CURL *get_curl_handle(void
        curl_easy_setopt(result, CURLOPT_HTTPAUTH, CURLAUTH_ANY);
  #endif
  
+ #if LIBCURL_VERSION_NUM >= 0x071600
+       if (curl_deleg) {
+               int i;
+               for (i = 0; i < ARRAY_SIZE(curl_deleg_levels); i++) {
+                       if (!strcmp(curl_deleg, curl_deleg_levels[i].name)) {
+                               curl_easy_setopt(result, CURLOPT_GSSAPI_DELEGATION,
+                                               curl_deleg_levels[i].curl_deleg_param);
+                               break;
+                       }
+               }
+               if (i == ARRAY_SIZE(curl_deleg_levels))
+                       warning("Unknown delegation method '%s': using default",
+                               curl_deleg);
+       }
+ #endif
        if (http_proactive_auth)
                init_curl_http_auth(result);
  
         * precedence here, as in CURL.
         */
        if (!curl_http_proxy) {
 -              if (!strcmp(http_auth.protocol, "https")) {
 +              if (http_auth.protocol && !strcmp(http_auth.protocol, "https")) {
                        var_override(&curl_http_proxy, getenv("HTTPS_PROXY"));
                        var_override(&curl_http_proxy, getenv("https_proxy"));
                } else {
@@@ -888,7 -918,9 +925,7 @@@ void http_cleanup(void
        while (slot != NULL) {
                struct active_request_slot *next = slot->next;
                if (slot->curl != NULL) {
 -#ifdef USE_CURL_MULTI
 -                      curl_multi_remove_handle(curlm, slot->curl);
 -#endif
 +                      xmulti_remove_handle(slot);
                        curl_easy_cleanup(slot->curl);
                }
                free(slot);
@@@ -1027,8 -1059,6 +1064,8 @@@ int start_active_slot(struct active_req
  
        if (curlm_result != CURLM_OK &&
            curlm_result != CURLM_CALL_MULTI_PERFORM) {
 +              warning("curl_multi_add_handle failed: %s",
 +                      curl_multi_strerror(curlm_result));
                active_requests--;
                slot->in_use = 0;
                return 0;
@@@ -1168,13 -1198,13 +1205,13 @@@ void run_active_slot(struct active_requ
  static void release_active_slot(struct active_request_slot *slot)
  {
        closedown_active_slot(slot);
 -      if (slot->curl && curl_session_count > min_curl_sessions) {
 -#ifdef USE_CURL_MULTI
 -              curl_multi_remove_handle(curlm, slot->curl);
 -#endif
 -              curl_easy_cleanup(slot->curl);
 -              slot->curl = NULL;
 -              curl_session_count--;
 +      if (slot->curl) {
 +              xmulti_remove_handle(slot);
 +              if (curl_session_count > min_curl_sessions) {
 +                      curl_easy_cleanup(slot->curl);
 +                      slot->curl = NULL;
 +                      curl_session_count--;
 +              }
        }
  #ifdef USE_CURL_MULTI
        fill_active_slots();