1. 26 9月, 2015 1 次提交
  2. 24 9月, 2015 1 次提交
    • J
      transport: add a protocol-whitelist environment variable · a5adaced
      Jeff King 提交于
      If we are cloning an untrusted remote repository into a
      sandbox, we may also want to fetch remote submodules in
      order to get the complete view as intended by the other
      side. However, that opens us up to attacks where a malicious
      user gets us to clone something they would not otherwise
      have access to (this is not necessarily a problem by itself,
      but we may then act on the cloned contents in a way that
      exposes them to the attacker).
      
      Ideally such a setup would sandbox git entirely away from
      high-value items, but this is not always practical or easy
      to set up (e.g., OS network controls may block multiple
      protocols, and we would want to enable some but not others).
      
      We can help this case by providing a way to restrict
      particular protocols. We use a whitelist in the environment.
      This is more annoying to set up than a blacklist, but
      defaults to safety if the set of protocols git supports
      grows). If no whitelist is specified, we continue to default
      to allowing all protocols (this is an "unsafe" default, but
      since the minority of users will want this sandboxing
      effect, it is the only sensible one).
      
      A note on the tests: ideally these would all be in a single
      test file, but the git-daemon and httpd test infrastructure
      is an all-or-nothing proposition rather than a test-by-test
      prerequisite. By putting them all together, we would be
      unable to test the file-local code on machines without
      apache.
      Signed-off-by: NJeff King <peff@peff.net>
      Signed-off-by: NJunio C Hamano <gitster@pobox.com>
      a5adaced
  3. 08 1月, 2015 1 次提交
  4. 16 9月, 2014 1 次提交
    • J
      push: the beginning of "git push --signed" · a85b377d
      Junio C Hamano 提交于
      While signed tags and commits assert that the objects thusly signed
      came from you, who signed these objects, there is not a good way to
      assert that you wanted to have a particular object at the tip of a
      particular branch.  My signing v2.0.1 tag only means I want to call
      the version v2.0.1, and it does not mean I want to push it out to my
      'master' branch---it is likely that I only want it in 'maint', so
      the signature on the object alone is insufficient.
      
      The only assurance to you that 'maint' points at what I wanted to
      place there comes from your trust on the hosting site and my
      authentication with it, which cannot easily audited later.
      
      Introduce a mechanism that allows you to sign a "push certificate"
      (for the lack of better name) every time you push, asserting that
      what object you are pushing to update which ref that used to point
      at what other object.  Think of it as a cryptographic protection for
      ref updates, similar to signed tags/commits but working on an
      orthogonal axis.
      
      The basic flow based on this mechanism goes like this:
      
       1. You push out your work with "git push --signed".
      
       2. The sending side learns where the remote refs are as usual,
          together with what protocol extension the receiving end
          supports.  If the receiving end does not advertise the protocol
          extension "push-cert", an attempt to "git push --signed" fails.
      
          Otherwise, a text file, that looks like the following, is
          prepared in core:
      
      	certificate version 0.1
      	pusher Junio C Hamano <gitster@pobox.com> 1315427886 -0700
      
      	7339ca65... 21580ecb... refs/heads/master
      	3793ac56... 12850bec... refs/heads/next
      
          The file begins with a few header lines, which may grow as we
          gain more experience.  The 'pusher' header records the name of
          the signer (the value of user.signingkey configuration variable,
          falling back to GIT_COMMITTER_{NAME|EMAIL}) and the time of the
          certificate generation.  After the header, a blank line follows,
          followed by a copy of the protocol message lines.
      
          Each line shows the old and the new object name at the tip of
          the ref this push tries to update, in the way identical to how
          the underlying "git push" protocol exchange tells the ref
          updates to the receiving end (by recording the "old" object
          name, the push certificate also protects against replaying).  It
          is expected that new command packet types other than the
          old-new-refname kind will be included in push certificate in the
          same way as would appear in the plain vanilla command packets in
          unsigned pushes.
      
          The user then is asked to sign this push certificate using GPG,
          formatted in a way similar to how signed tag objects are signed,
          and the result is sent to the other side (i.e. receive-pack).
      
          In the protocol exchange, this step comes immediately before the
          sender tells what the result of the push should be, which in
          turn comes before it sends the pack data.
      
       3. When the receiving end sees a push certificate, the certificate
          is written out as a blob.  The pre-receive hook can learn about
          the certificate by checking GIT_PUSH_CERT environment variable,
          which, if present, tells the object name of this blob, and make
          the decision to allow or reject this push.  Additionally, the
          post-receive hook can also look at the certificate, which may be
          a good place to log all the received certificates for later
          audits.
      
      Because a push certificate carry the same information as the usual
      command packets in the protocol exchange, we can omit the latter
      when a push certificate is in use and reduce the protocol overhead.
      This however is not included in this patch to make it easier to
      review (in other words, the series at this step should never be
      released without the remainder of the series, as it implements an
      interim protocol that will be incompatible with the final one).
      As such, the documentation update for the protocol is left out of
      this step.
      Signed-off-by: NJunio C Hamano <gitster@pobox.com>
      a85b377d
  5. 11 12月, 2013 3 次提交
  6. 08 8月, 2013 1 次提交
    • J
      fetch: work around "transport-take-over" hack · b26ed430
      Junio C Hamano 提交于
      A Git-aware "connect" transport allows the "transport_take_over" to
      redirect generic transport requests like fetch(), push_refs() and
      get_refs_list() to the native Git transport handling methods.  The
      take-over process replaces transport->data with a fake data that
      these method implementations understand.
      
      While this hack works OK for a single request, it breaks when the
      transport needs to make more than one requests.  transport->data
      that used to hold necessary information for the specific helper to
      work correctly is destroyed during the take-over process.
      
      One codepath that this matters is "git fetch" in auto-follow mode;
      when it does not get all the tags that ought to point at the history
      it got (which can be determined by looking at the peeled tags in the
      initial advertisement) from the primary transfer, it internally
      makes a second request to complete the fetch.  Because "take-over"
      hack has already destroyed the data necessary to talk to the
      transport helper by the time this happens, the second request cannot
      make a request to the helper to make another connection to fetch
      these additional tags.
      
      Mark such a transport as "cannot_reuse", and use a separate
      transport to perform the backfill fetch in order to work around
      this breakage.
      
      Note that this problem does not manifest itself when running t5802,
      because our upload-pack gives you all the necessary auto-followed
      tags during the primary transfer.  You would need to step through
      "git fetch" in a debugger, stop immediately after the primary
      transfer finishes and writes these auto-followed tags, remove the
      tag references and repack/prune the repository to convince the
      "find-non-local-tags" procedure that the primary transfer failed to
      give us all the necessary tags, and then let it continue, in order
      to trigger the bug in the secondary transfer this patch fixes.
      Signed-off-by: NJunio C Hamano <gitster@pobox.com>
      b26ed430
  7. 23 7月, 2013 1 次提交
    • J
      push --force-with-lease: implement logic to populate old_sha1_expect[] · 91048a95
      Junio C Hamano 提交于
      This plugs the push_cas_option data collected by the command line
      option parser to the transport system with a new function
      apply_push_cas(), which is called after match_push_refs() has
      already been called.
      
      At this point, we know which remote we are talking to, and what
      remote refs we are going to update, so we can fill in the details
      that may have been missing from the command line, such as
      
       (1) what abbreviated refname the user gave us matches the actual
           refname at the remote; and
      
       (2) which remote-tracking branch in our local repository to read
           the value of the object to expect at the remote.
      
      to populate the old_sha1_expect[] field of each of the remote ref.
      As stated in the documentation, the use of remote-tracking branch
      as the default is a tentative one, and we may come up with a better
      logic as we gain experience.
      
      Still nobody uses this information, which is the topic of the next
      patch.
      Signed-off-by: NJunio C Hamano <gitster@pobox.com>
      91048a95
  8. 09 7月, 2013 1 次提交
    • J
      cache.h: move remote/connect API out of it · 47a59185
      Junio C Hamano 提交于
      The definition of "struct ref" in "cache.h", a header file so
      central to the system, always confused me.  This structure is not
      about the local ref used by sha1-name API to name local objects.
      
      It is what refspecs are expanded into, after finding out what refs
      the other side has, to define what refs are updated after object
      transfer succeeds to what values.  It belongs to "remote.h" together
      with "struct refspec".
      
      While we are at it, also move the types and functions related to the
      Git transport connection to a new header file connect.h
      Signed-off-by: NJunio C Hamano <gitster@pobox.com>
      47a59185
  9. 19 6月, 2013 1 次提交
  10. 28 5月, 2013 1 次提交
    • N
      clone: open a shortcut for connectivity check · c6807a40
      Nguyễn Thái Ngọc Duy 提交于
      In order to make sure the cloned repository is good, we run "rev-list
      --objects --not --all $new_refs" on the repository. This is expensive
      on large repositories. This patch attempts to mitigate the impact in
      this special case.
      
      In the "good" clone case, we only have one pack. If all of the
      following are met, we can be sure that all objects reachable from the
      new refs exist, which is the intention of running "rev-list ...":
      
       - all refs point to an object in the pack
       - there are no dangling pointers in any object in the pack
       - no objects in the pack point to objects outside the pack
      
      The second and third checks can be done with the help of index-pack as
      a slight variation of --strict check (which introduces a new condition
      for the shortcut: pack transfer must be used and the number of objects
      large enough to call index-pack). The first is checked in
      check_everything_connected after we get an "ok" from index-pack.
      
      "index-pack + new checks" is still faster than the current "index-pack
      + rev-list", which is the whole point of this patch. If any of the
      conditions fail, we fall back to the good old but expensive "rev-list
      ..". In that case it's even more expensive because we have to pay for
      the new checks in index-pack. But that should only happen when the
      other side is either buggy or malicious.
      
      Cloning linux-2.6 over file://
      
              before         after
      real    3m25.693s      2m53.050s
      user    5m2.037s       4m42.396s
      sys     0m13.750s      0m16.574s
      
      A more realistic test with ssh:// over wireless
      
              before         after
      real    11m26.629s     10m4.213s
      user    5m43.196s      5m19.444s
      sys     0m35.812s      0m37.630s
      
      This shortcut is not applied to shallow clones, partly because shallow
      clones should have no more objects than a usual fetch and the cost of
      rev-list is acceptable, partly to avoid dealing with corner cases when
      grafting is involved.
      
      This shortcut does not apply to unpack-objects code path either
      because the number of objects must be small in order to trigger that
      code path.
      Signed-off-by: NNguyễn Thái Ngọc Duy <pclouds@gmail.com>
      Signed-off-by: NJunio C Hamano <gitster@pobox.com>
      c6807a40
  11. 13 4月, 2013 1 次提交
  12. 06 3月, 2013 1 次提交
    • J
      push: --follow-tags · c2aba155
      Junio C Hamano 提交于
      The new option "--follow-tags" tells "git push" to push annotated
      tags that are missing from the other side and that can be reached by
      the history that is otherwise pushed out.
      
      For example, if you are using the "simple", "current", or "upstream"
      push, you would ordinarily push the history leading to the commit at
      your current HEAD and nothing else.  With this option, you would
      also push all annotated tags that can be reached from that commit to
      the other side.
      Signed-off-by: NJunio C Hamano <gitster@pobox.com>
      c2aba155
  13. 25 1月, 2013 1 次提交
    • J
      push: introduce REJECT_FETCH_FIRST and REJECT_NEEDS_FORCE · 75e5c0dc
      Junio C Hamano 提交于
      When we push to update an existing ref, if:
      
       * the object at the tip of the remote is not a commit; or
       * the object we are pushing is not a commit,
      
      it won't be correct to suggest to fetch, integrate and push again,
      as the old and new objects will not "merge".  We should explain that
      the push must be forced when there is a non-committish object is
      involved in such a case.
      
      If we do not have the current object at the tip of the remote, we do
      not even know that object, when fetched, is something that can be
      merged.  In such a case, suggesting to pull first just like
      non-fast-forward case may not be technically correct, but in
      practice, most such failures are seen when you try to push your work
      to a branch without knowing that somebody else already pushed to
      update the same branch since you forked, so "pull first" would work
      as a suggestion most of the time.  And if the object at the tip is
      not a commit, "pull first" will fail, without making any permanent
      damage.  As a side effect, it also makes the error message the user
      will get during the next "push" attempt easier to understand, now
      the user is aware that a non-commit object is involved.
      
      In these cases, the current code already rejects such a push on the
      client end, but we used the same error and advice messages as the
      ones used when rejecting a non-fast-forward push, i.e. pull from
      there and integrate before pushing again.
      
      Introduce new rejection reasons and reword the messages
      appropriately.
      
      [jc: with help by Peff on message details]
      Signed-off-by: NJunio C Hamano <gitster@pobox.com>
      75e5c0dc
  14. 19 1月, 2013 1 次提交
    • A
      push: Add support for pre-push hooks · ec55559f
      Aaron Schrab 提交于
      Add support for a pre-push hook which can be used to determine if the
      set of refs to be pushed is suitable for the target repository.  The
      hook is run with two arguments specifying the name and location of the
      destination repository.
      
      Information about what is to be pushed is provided by sending lines of
      the following form to the hook's standard input:
      
        <local ref> SP <local sha1> SP <remote ref> SP <remote sha1> LF
      
      If the hook exits with a non-zero status, the push will be aborted.
      
      This will allow the script to determine if the push is acceptable based
      on the target repository and branch(es), the commits which are to be
      pushed, and even the source branches in some cases.
      Signed-off-by: NAaron Schrab <aaron@schrab.com>
      Signed-off-by: NJunio C Hamano <gitster@pobox.com>
      ec55559f
  15. 02 12月, 2012 2 次提交
  16. 29 10月, 2012 1 次提交
  17. 15 9月, 2012 1 次提交
  18. 31 3月, 2012 1 次提交
  19. 27 3月, 2012 1 次提交
    • J
      clean up struct ref's nonfastforward field · e339aa92
      Jeff King 提交于
      Each ref structure contains a "nonfastforward" field which
      is set during push to show whether the ref rewound history.
      Originally this was a single bit, but it was changed in
      f25950f3 (push: Provide situational hints for non-fast-forward
      errors) to an enum differentiating a non-ff of the current
      branch versus another branch.
      
      However, we never actually set the member according to the
      enum values, nor did we ever read it expecting anything but
      a boolean value. But we did use the side effect of declaring
      the enum constants to store those values in a totally
      different integer variable. The code as-is isn't buggy, but
      the enum declaration inside "struct ref" is somewhat
      misleading.
      
      Let's convert nonfastforward back into a single bit, and
      then define the NON_FF_* constants closer to where they
      would be used (they are returned via the "int *nonfastforward"
      parameter to transport_push, so we can define them there).
      Signed-off-by: NJeff King <peff@peff.net>
      Signed-off-by: NJunio C Hamano <gitster@pobox.com>
      e339aa92
  20. 23 2月, 2012 1 次提交
    • F
      push: add '--prune' option · 6ddba5e2
      Felipe Contreras 提交于
      When pushing groups of refs to a remote, there is no simple way to remove
      old refs that still exist at the remote that is no longer updated from us.
      This will allow us to remove such refs from the remote.
      
      With this change, running this command
      
       $ git push --prune remote refs/heads/*:refs/remotes/laptop/*
      
      removes refs/remotes/laptop/foo from the remote if we do not have branch
      "foo" locally anymore.
      Signed-off-by: NFelipe Contreras <felipe.contreras@gmail.com>
      Signed-off-by: NJunio C Hamano <gitster@pobox.com>
      6ddba5e2
  21. 21 8月, 2011 1 次提交
  22. 20 5月, 2011 1 次提交
    • J
      refactor refs_from_alternate_cb to allow passing extra data · 114a6a88
      Jeff King 提交于
      The foreach_alt_odb function triggers a callback for each
      alternate object db we have, with room for a single void
      pointer as data. Currently, we always call refs_from_alternate_cb
      as the callback function, and then pass another callback (to
      receive each ref individually) as the void pointer.
      
      This has two problems:
      
        1. C technically forbids stuffing a function pointer into
           a "void *". In practice, this probably doesn't matter
           on any architectures git runs on, but it never hurts to
           follow the letter of the law.
      
        2. There is no room for an extra data pointer. Indeed, the
           alternate_ref_fn that refs_from_alternate_cb calls
           takes a void* for data, but we always pass it NULL.
      
      Instead, let's properly stuff our function pointer into a
      data struct, which also leaves room for an extra
      caller-supplied data pointer. And to keep things simple for
      existing callers, let's make a for_each_alternate_ref
      function that takes care of creating the extra struct.
      Signed-off-by: NJeff King <peff@peff.net>
      Signed-off-by: NJunio C Hamano <gitster@pobox.com>
      114a6a88
  23. 18 3月, 2011 1 次提交
    • J
      refs_from_alternate: helper to use refs from alternates · 36cfda15
      Junio C Hamano 提交于
      The receiving end of "git push" advertises the objects that the repository
      itself does not use, but are at the tips of refs in other repositories
      whose object databases are used as alternates for it. This helps it avoid
      having to receive (and the pusher having to send) objects that are already
      available to the receiving repository via the alternates mechanism.
      
      Tweak the helper function that implements this feature, and move it to
      transport.[ch] for future reuse by other programs.
      
      The additional test demonstrates how this optimization is helping "git push",
      and "git fetch" is ignorant about it.
      Signed-off-by: NJunio C Hamano <gitster@pobox.com>
      Acked-by: NShawn O. Pearce <spearce@spearce.org>
      36cfda15
  24. 14 10月, 2010 1 次提交
  25. 25 2月, 2010 4 次提交
  26. 18 2月, 2010 1 次提交
  27. 17 2月, 2010 1 次提交
    • T
      transport: add got_remote_refs flag · b0d66e15
      Tay Ray Chuan 提交于
      transport_get_remote_refs() in tranport.c checks transport->remote_refs
      to determine whether transport->get_refs_list() should be invoked.  The
      logic is "if it is NULL, we haven't run ls-remote to find out yet".
      
      However, transport->remote_refs could still be NULL while cloning from
      an empty repository.  This causes get_refs_list() to be run unnecessarily.
      
      Introduce a flag, transport->got_remote_refs, to more explicitly record
      if we have run transport->get_refs_list() already.
      Signed-off-by: NTay Ray Chuan <rctay89@gmail.com>
      Acked-by: NJeff King <peff@peff.net>
      Signed-off-by: NJunio C Hamano <gitster@pobox.com>
      b0d66e15
  28. 17 1月, 2010 1 次提交
  29. 29 12月, 2009 1 次提交
  30. 28 12月, 2009 1 次提交
  31. 10 12月, 2009 2 次提交
  32. 18 11月, 2009 1 次提交
  33. 31 10月, 2009 1 次提交