rugged 0.27.9 → 0.27.10
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/lib/rugged/version.rb +1 -1
- data/vendor/libgit2/AUTHORS +1 -0
- data/vendor/libgit2/CMakeLists.txt +98 -54
- data/vendor/libgit2/COPYING +28 -0
- data/vendor/libgit2/cmake/Modules/AddCFlagIfSupported.cmake +15 -1
- data/vendor/libgit2/cmake/Modules/EnableWarnings.cmake +9 -8
- data/vendor/libgit2/cmake/Modules/FindCoreFoundation.cmake +2 -2
- data/vendor/libgit2/cmake/Modules/FindGSSAPI.cmake +1 -1
- data/vendor/libgit2/cmake/Modules/FindGSSFramework.cmake +28 -0
- data/vendor/libgit2/cmake/Modules/FindPCRE.cmake +38 -0
- data/vendor/libgit2/cmake/Modules/FindPCRE2.cmake +37 -0
- data/vendor/libgit2/cmake/Modules/FindSecurity.cmake +2 -2
- data/vendor/libgit2/cmake/Modules/FindStatNsec.cmake +6 -0
- data/vendor/libgit2/cmake/Modules/FindmbedTLS.cmake +93 -0
- data/vendor/libgit2/cmake/Modules/PkgBuildConfig.cmake +110 -0
- data/vendor/libgit2/cmake/Modules/SelectGSSAPI.cmake +53 -0
- data/vendor/libgit2/cmake/Modules/SelectHTTPSBackend.cmake +124 -0
- data/vendor/libgit2/cmake/Modules/SelectHashes.cmake +66 -0
- data/vendor/libgit2/deps/http-parser/CMakeLists.txt +2 -0
- data/vendor/libgit2/deps/http-parser/{LICENSE-MIT → COPYING} +0 -0
- data/vendor/libgit2/deps/http-parser/http_parser.c +11 -6
- data/vendor/libgit2/deps/ntlmclient/CMakeLists.txt +21 -0
- data/vendor/libgit2/deps/ntlmclient/compat.h +33 -0
- data/vendor/libgit2/deps/ntlmclient/crypt.h +64 -0
- data/vendor/libgit2/deps/ntlmclient/crypt_commoncrypto.c +120 -0
- data/vendor/libgit2/deps/ntlmclient/crypt_commoncrypto.h +18 -0
- data/vendor/libgit2/deps/ntlmclient/crypt_mbedtls.c +145 -0
- data/vendor/libgit2/deps/ntlmclient/crypt_mbedtls.h +18 -0
- data/vendor/libgit2/deps/ntlmclient/crypt_openssl.c +130 -0
- data/vendor/libgit2/deps/ntlmclient/crypt_openssl.h +21 -0
- data/vendor/libgit2/deps/ntlmclient/ntlm.c +1420 -0
- data/vendor/libgit2/deps/ntlmclient/ntlm.h +174 -0
- data/vendor/libgit2/deps/ntlmclient/ntlmclient.h +320 -0
- data/vendor/libgit2/deps/ntlmclient/unicode.h +36 -0
- data/vendor/libgit2/deps/ntlmclient/unicode_builtin.c +445 -0
- data/vendor/libgit2/deps/ntlmclient/unicode_iconv.c +201 -0
- data/vendor/libgit2/deps/ntlmclient/utf8.h +1257 -0
- data/vendor/libgit2/deps/ntlmclient/util.c +21 -0
- data/vendor/libgit2/deps/ntlmclient/util.h +14 -0
- data/vendor/libgit2/deps/pcre/CMakeLists.txt +140 -0
- data/vendor/libgit2/deps/pcre/COPYING +5 -0
- data/vendor/libgit2/deps/pcre/cmake/COPYING-CMAKE-SCRIPTS +22 -0
- data/vendor/libgit2/deps/pcre/cmake/FindEditline.cmake +17 -0
- data/vendor/libgit2/deps/pcre/cmake/FindPackageHandleStandardArgs.cmake +58 -0
- data/vendor/libgit2/deps/pcre/cmake/FindReadline.cmake +29 -0
- data/vendor/libgit2/deps/pcre/config.h.in +57 -0
- data/vendor/libgit2/deps/pcre/pcre.h +641 -0
- data/vendor/libgit2/deps/pcre/pcre_byte_order.c +319 -0
- data/vendor/libgit2/deps/pcre/pcre_chartables.c +198 -0
- data/vendor/libgit2/deps/pcre/pcre_compile.c +9800 -0
- data/vendor/libgit2/deps/pcre/pcre_config.c +190 -0
- data/vendor/libgit2/deps/pcre/pcre_dfa_exec.c +3676 -0
- data/vendor/libgit2/deps/pcre/pcre_exec.c +7173 -0
- data/vendor/libgit2/deps/pcre/pcre_fullinfo.c +245 -0
- data/vendor/libgit2/deps/pcre/pcre_get.c +669 -0
- data/vendor/libgit2/deps/pcre/pcre_globals.c +86 -0
- data/vendor/libgit2/deps/pcre/pcre_internal.h +2787 -0
- data/vendor/libgit2/deps/pcre/pcre_jit_compile.c +11913 -0
- data/vendor/libgit2/deps/pcre/pcre_maketables.c +156 -0
- data/vendor/libgit2/deps/pcre/pcre_newline.c +210 -0
- data/vendor/libgit2/deps/pcre/pcre_ord2utf8.c +94 -0
- data/vendor/libgit2/deps/pcre/pcre_printint.c +834 -0
- data/vendor/libgit2/deps/pcre/pcre_refcount.c +92 -0
- data/vendor/libgit2/deps/pcre/pcre_string_utils.c +211 -0
- data/vendor/libgit2/deps/pcre/pcre_study.c +1686 -0
- data/vendor/libgit2/deps/pcre/pcre_tables.c +727 -0
- data/vendor/libgit2/deps/pcre/pcre_ucd.c +3644 -0
- data/vendor/libgit2/deps/pcre/pcre_valid_utf8.c +301 -0
- data/vendor/libgit2/deps/pcre/pcre_version.c +98 -0
- data/vendor/libgit2/deps/pcre/pcre_xclass.c +268 -0
- data/vendor/libgit2/deps/pcre/pcreposix.c +421 -0
- data/vendor/libgit2/deps/pcre/pcreposix.h +117 -0
- data/vendor/libgit2/deps/pcre/ucp.h +224 -0
- data/vendor/libgit2/deps/winhttp/COPYING.GPL +993 -0
- data/vendor/libgit2/deps/winhttp/COPYING.LGPL +502 -0
- data/vendor/libgit2/deps/zlib/CMakeLists.txt +1 -0
- data/vendor/libgit2/deps/zlib/COPYING +27 -0
- data/vendor/libgit2/deps/zlib/adler32.c +0 -7
- data/vendor/libgit2/deps/zlib/crc32.c +0 -7
- data/vendor/libgit2/include/git2.h +5 -0
- data/vendor/libgit2/include/git2/annotated_commit.h +9 -0
- data/vendor/libgit2/include/git2/apply.h +149 -0
- data/vendor/libgit2/include/git2/attr.h +38 -20
- data/vendor/libgit2/include/git2/blame.h +42 -25
- data/vendor/libgit2/include/git2/blob.h +45 -13
- data/vendor/libgit2/include/git2/branch.h +1 -1
- data/vendor/libgit2/include/git2/buffer.h +22 -16
- data/vendor/libgit2/include/git2/cert.h +135 -0
- data/vendor/libgit2/include/git2/checkout.h +65 -32
- data/vendor/libgit2/include/git2/cherrypick.h +9 -7
- data/vendor/libgit2/include/git2/clone.h +12 -10
- data/vendor/libgit2/include/git2/commit.h +53 -3
- data/vendor/libgit2/include/git2/common.h +60 -8
- data/vendor/libgit2/include/git2/config.h +30 -19
- data/vendor/libgit2/include/git2/cred.h +308 -0
- data/vendor/libgit2/include/git2/deprecated.h +493 -0
- data/vendor/libgit2/include/git2/describe.h +32 -9
- data/vendor/libgit2/include/git2/diff.h +208 -156
- data/vendor/libgit2/include/git2/errors.h +54 -46
- data/vendor/libgit2/include/git2/filter.h +8 -0
- data/vendor/libgit2/include/git2/ignore.h +2 -2
- data/vendor/libgit2/include/git2/index.h +74 -52
- data/vendor/libgit2/include/git2/indexer.h +76 -6
- data/vendor/libgit2/include/git2/mailmap.h +115 -0
- data/vendor/libgit2/include/git2/merge.h +35 -18
- data/vendor/libgit2/include/git2/net.h +0 -5
- data/vendor/libgit2/include/git2/notes.h +1 -1
- data/vendor/libgit2/include/git2/object.h +17 -29
- data/vendor/libgit2/include/git2/odb.h +12 -11
- data/vendor/libgit2/include/git2/odb_backend.h +10 -9
- data/vendor/libgit2/include/git2/oid.h +2 -2
- data/vendor/libgit2/include/git2/pack.h +14 -3
- data/vendor/libgit2/include/git2/proxy.h +14 -8
- data/vendor/libgit2/include/git2/rebase.h +53 -6
- data/vendor/libgit2/include/git2/refs.h +33 -15
- data/vendor/libgit2/include/git2/refspec.h +17 -0
- data/vendor/libgit2/include/git2/remote.h +123 -24
- data/vendor/libgit2/include/git2/repository.h +76 -39
- data/vendor/libgit2/include/git2/revert.h +6 -4
- data/vendor/libgit2/include/git2/revwalk.h +7 -7
- data/vendor/libgit2/include/git2/signature.h +2 -2
- data/vendor/libgit2/include/git2/stash.h +15 -12
- data/vendor/libgit2/include/git2/status.h +33 -20
- data/vendor/libgit2/include/git2/submodule.h +30 -12
- data/vendor/libgit2/include/git2/sys/alloc.h +101 -0
- data/vendor/libgit2/include/git2/sys/commit.h +1 -1
- data/vendor/libgit2/include/git2/sys/config.h +13 -13
- data/vendor/libgit2/include/git2/sys/cred.h +90 -0
- data/vendor/libgit2/include/git2/sys/filter.h +6 -6
- data/vendor/libgit2/include/git2/sys/index.h +3 -0
- data/vendor/libgit2/include/git2/sys/mempack.h +35 -35
- data/vendor/libgit2/include/git2/sys/merge.h +9 -4
- data/vendor/libgit2/include/git2/sys/odb_backend.h +66 -22
- data/vendor/libgit2/include/git2/sys/path.h +64 -0
- data/vendor/libgit2/include/git2/sys/refdb_backend.h +76 -40
- data/vendor/libgit2/include/git2/sys/repository.h +5 -1
- data/vendor/libgit2/include/git2/sys/stream.h +92 -12
- data/vendor/libgit2/include/git2/sys/transport.h +129 -83
- data/vendor/libgit2/include/git2/tag.h +13 -4
- data/vendor/libgit2/include/git2/trace.h +2 -2
- data/vendor/libgit2/include/git2/transaction.h +1 -0
- data/vendor/libgit2/include/git2/transport.h +11 -311
- data/vendor/libgit2/include/git2/tree.h +4 -4
- data/vendor/libgit2/include/git2/types.h +33 -111
- data/vendor/libgit2/include/git2/version.h +4 -4
- data/vendor/libgit2/include/git2/worktree.h +48 -13
- data/vendor/libgit2/src/CMakeLists.txt +96 -164
- data/vendor/libgit2/src/alloc.c +43 -0
- data/vendor/libgit2/src/alloc.h +40 -0
- data/vendor/libgit2/src/allocators/stdalloc.c +119 -0
- data/vendor/libgit2/src/{streams/curl.h → allocators/stdalloc.h} +5 -5
- data/vendor/libgit2/src/allocators/win32_crtdbg.c +118 -0
- data/vendor/libgit2/src/{transports/cred.h → allocators/win32_crtdbg.h} +5 -4
- data/vendor/libgit2/src/annotated_commit.c +15 -8
- data/vendor/libgit2/src/apply.c +537 -31
- data/vendor/libgit2/src/apply.h +3 -1
- data/vendor/libgit2/src/array.h +2 -2
- data/vendor/libgit2/src/attr.c +81 -75
- data/vendor/libgit2/src/attr_file.c +207 -121
- data/vendor/libgit2/src/attr_file.h +9 -9
- data/vendor/libgit2/src/attrcache.c +51 -53
- data/vendor/libgit2/src/attrcache.h +2 -1
- data/vendor/libgit2/src/blame.c +47 -20
- data/vendor/libgit2/src/blame.h +2 -1
- data/vendor/libgit2/src/blame_git.c +37 -20
- data/vendor/libgit2/src/blob.c +128 -42
- data/vendor/libgit2/src/blob.h +19 -2
- data/vendor/libgit2/src/branch.c +67 -43
- data/vendor/libgit2/src/buf_text.c +7 -6
- data/vendor/libgit2/src/buffer.c +69 -57
- data/vendor/libgit2/src/buffer.h +1 -1
- data/vendor/libgit2/src/cache.c +38 -45
- data/vendor/libgit2/src/cache.h +3 -3
- data/vendor/libgit2/src/cc-compat.h +20 -3
- data/vendor/libgit2/src/checkout.c +109 -90
- data/vendor/libgit2/src/cherrypick.c +15 -9
- data/vendor/libgit2/src/clone.c +49 -27
- data/vendor/libgit2/src/clone.h +4 -0
- data/vendor/libgit2/src/commit.c +117 -49
- data/vendor/libgit2/src/commit.h +7 -0
- data/vendor/libgit2/src/commit_list.c +30 -78
- data/vendor/libgit2/src/commit_list.h +2 -2
- data/vendor/libgit2/src/common.h +27 -91
- data/vendor/libgit2/src/config.c +194 -176
- data/vendor/libgit2/src/config.h +8 -20
- data/vendor/libgit2/src/config_backend.h +96 -0
- data/vendor/libgit2/src/config_cache.c +41 -35
- data/vendor/libgit2/src/config_entries.c +229 -0
- data/vendor/libgit2/src/config_entries.h +24 -0
- data/vendor/libgit2/src/config_file.c +439 -753
- data/vendor/libgit2/src/config_mem.c +220 -0
- data/vendor/libgit2/src/config_parse.c +114 -63
- data/vendor/libgit2/src/config_parse.h +17 -16
- data/vendor/libgit2/src/config_snapshot.c +206 -0
- data/vendor/libgit2/src/crlf.c +219 -190
- data/vendor/libgit2/src/delta.c +25 -18
- data/vendor/libgit2/src/describe.c +42 -41
- data/vendor/libgit2/src/diff.c +53 -68
- data/vendor/libgit2/src/diff.h +2 -1
- data/vendor/libgit2/src/diff_driver.c +47 -49
- data/vendor/libgit2/src/diff_file.c +19 -17
- data/vendor/libgit2/src/diff_file.h +1 -1
- data/vendor/libgit2/src/diff_generate.c +162 -106
- data/vendor/libgit2/src/diff_generate.h +3 -3
- data/vendor/libgit2/src/diff_parse.c +4 -4
- data/vendor/libgit2/src/diff_print.c +42 -30
- data/vendor/libgit2/src/diff_stats.c +22 -7
- data/vendor/libgit2/src/diff_tform.c +16 -16
- data/vendor/libgit2/src/diff_xdiff.c +15 -3
- data/vendor/libgit2/src/errors.c +51 -39
- data/vendor/libgit2/src/errors.h +81 -0
- data/vendor/libgit2/src/features.h.in +11 -3
- data/vendor/libgit2/src/fetch.c +10 -5
- data/vendor/libgit2/src/fetchhead.c +17 -17
- data/vendor/libgit2/src/filebuf.c +32 -36
- data/vendor/libgit2/src/filebuf.h +2 -2
- data/vendor/libgit2/src/filter.c +46 -38
- data/vendor/libgit2/src/filter.h +0 -10
- data/vendor/libgit2/src/{fileops.c → futils.c} +80 -73
- data/vendor/libgit2/src/{fileops.h → futils.h} +6 -6
- data/vendor/libgit2/src/global.c +48 -63
- data/vendor/libgit2/src/global.h +0 -2
- data/vendor/libgit2/src/hash.c +61 -0
- data/vendor/libgit2/src/hash.h +20 -19
- data/vendor/libgit2/src/hash/sha1.h +38 -0
- data/vendor/libgit2/src/hash/sha1/collisiondetect.c +48 -0
- data/vendor/libgit2/src/hash/sha1/collisiondetect.h +19 -0
- data/vendor/libgit2/src/hash/{hash_common_crypto.h → sha1/common_crypto.c} +17 -17
- data/vendor/libgit2/src/hash/sha1/common_crypto.h +19 -0
- data/vendor/libgit2/src/hash/{hash_generic.c → sha1/generic.c} +22 -10
- data/vendor/libgit2/src/hash/{hash_generic.h → sha1/generic.h} +4 -10
- data/vendor/libgit2/src/hash/sha1/mbedtls.c +46 -0
- data/vendor/libgit2/src/hash/sha1/mbedtls.h +19 -0
- data/vendor/libgit2/src/hash/sha1/openssl.c +59 -0
- data/vendor/libgit2/src/hash/sha1/openssl.h +19 -0
- data/vendor/libgit2/src/hash/{sha1dc → sha1/sha1dc}/sha1.c +14 -3
- data/vendor/libgit2/src/hash/{sha1dc → sha1/sha1dc}/sha1.h +0 -0
- data/vendor/libgit2/src/hash/{sha1dc → sha1/sha1dc}/ubc_check.c +0 -0
- data/vendor/libgit2/src/hash/{sha1dc → sha1/sha1dc}/ubc_check.h +0 -0
- data/vendor/libgit2/src/hash/{hash_win32.c → sha1/win32.c} +47 -37
- data/vendor/libgit2/src/hash/{hash_win32.h → sha1/win32.h} +6 -19
- data/vendor/libgit2/src/hashsig.c +5 -5
- data/vendor/libgit2/src/idxmap.c +107 -61
- data/vendor/libgit2/src/idxmap.h +153 -31
- data/vendor/libgit2/src/ignore.c +43 -47
- data/vendor/libgit2/src/index.c +337 -232
- data/vendor/libgit2/src/index.h +17 -1
- data/vendor/libgit2/src/indexer.c +346 -175
- data/vendor/libgit2/src/integer.h +71 -26
- data/vendor/libgit2/src/iterator.c +142 -70
- data/vendor/libgit2/src/iterator.h +15 -0
- data/vendor/libgit2/src/khash.h +3 -1
- data/vendor/libgit2/src/mailmap.c +485 -0
- data/vendor/libgit2/src/mailmap.h +35 -0
- data/vendor/libgit2/src/map.h +1 -1
- data/vendor/libgit2/src/merge.c +144 -100
- data/vendor/libgit2/src/merge_driver.c +11 -11
- data/vendor/libgit2/src/merge_file.c +2 -2
- data/vendor/libgit2/src/mwindow.c +24 -29
- data/vendor/libgit2/src/mwindow.h +4 -4
- data/vendor/libgit2/src/net.c +184 -0
- data/vendor/libgit2/src/net.h +36 -0
- data/vendor/libgit2/src/netops.c +55 -156
- data/vendor/libgit2/src/netops.h +3 -23
- data/vendor/libgit2/src/notes.c +16 -11
- data/vendor/libgit2/src/object.c +120 -69
- data/vendor/libgit2/src/object.h +22 -9
- data/vendor/libgit2/src/object_api.c +8 -8
- data/vendor/libgit2/src/odb.c +116 -93
- data/vendor/libgit2/src/odb.h +8 -7
- data/vendor/libgit2/src/odb_loose.c +62 -55
- data/vendor/libgit2/src/odb_mempack.c +21 -34
- data/vendor/libgit2/src/odb_pack.c +18 -14
- data/vendor/libgit2/src/offmap.c +53 -35
- data/vendor/libgit2/src/offmap.h +108 -21
- data/vendor/libgit2/src/oid.c +12 -7
- data/vendor/libgit2/src/oidmap.c +49 -47
- data/vendor/libgit2/src/oidmap.h +101 -24
- data/vendor/libgit2/src/pack-objects.c +88 -87
- data/vendor/libgit2/src/pack-objects.h +2 -8
- data/vendor/libgit2/src/pack.c +99 -101
- data/vendor/libgit2/src/pack.h +17 -19
- data/vendor/libgit2/src/parse.c +10 -0
- data/vendor/libgit2/src/parse.h +3 -3
- data/vendor/libgit2/src/patch.c +4 -4
- data/vendor/libgit2/src/patch_generate.c +20 -20
- data/vendor/libgit2/src/patch_parse.c +151 -63
- data/vendor/libgit2/src/path.c +169 -125
- data/vendor/libgit2/src/path.h +3 -71
- data/vendor/libgit2/src/pathspec.c +19 -19
- data/vendor/libgit2/src/pool.c +26 -22
- data/vendor/libgit2/src/pool.h +7 -7
- data/vendor/libgit2/src/posix.c +10 -10
- data/vendor/libgit2/src/posix.h +12 -1
- data/vendor/libgit2/src/proxy.c +8 -3
- data/vendor/libgit2/src/push.c +37 -31
- data/vendor/libgit2/src/push.h +2 -1
- data/vendor/libgit2/src/reader.c +265 -0
- data/vendor/libgit2/src/reader.h +107 -0
- data/vendor/libgit2/src/rebase.c +115 -59
- data/vendor/libgit2/src/refdb.c +15 -3
- data/vendor/libgit2/src/refdb_fs.c +381 -254
- data/vendor/libgit2/src/reflog.c +13 -15
- data/vendor/libgit2/src/refs.c +118 -88
- data/vendor/libgit2/src/refs.h +5 -3
- data/vendor/libgit2/src/refspec.c +56 -37
- data/vendor/libgit2/src/refspec.h +1 -1
- data/vendor/libgit2/src/regexp.c +221 -0
- data/vendor/libgit2/src/regexp.h +97 -0
- data/vendor/libgit2/src/remote.c +266 -215
- data/vendor/libgit2/src/remote.h +11 -2
- data/vendor/libgit2/src/repository.c +280 -225
- data/vendor/libgit2/src/repository.h +52 -40
- data/vendor/libgit2/src/reset.c +8 -8
- data/vendor/libgit2/src/revert.c +14 -9
- data/vendor/libgit2/src/revparse.c +47 -48
- data/vendor/libgit2/src/revwalk.c +120 -57
- data/vendor/libgit2/src/revwalk.h +22 -1
- data/vendor/libgit2/src/settings.c +47 -10
- data/vendor/libgit2/src/signature.c +11 -11
- data/vendor/libgit2/src/sortedcache.c +22 -36
- data/vendor/libgit2/src/sortedcache.h +1 -1
- data/vendor/libgit2/src/stash.c +125 -99
- data/vendor/libgit2/src/status.c +28 -22
- data/vendor/libgit2/src/stream.h +17 -2
- data/vendor/libgit2/src/streams/mbedtls.c +483 -0
- data/vendor/libgit2/src/streams/mbedtls.h +23 -0
- data/vendor/libgit2/src/streams/openssl.c +224 -114
- data/vendor/libgit2/src/streams/openssl.h +4 -108
- data/vendor/libgit2/src/streams/registry.c +118 -0
- data/vendor/libgit2/src/streams/registry.h +19 -0
- data/vendor/libgit2/src/streams/socket.c +55 -30
- data/vendor/libgit2/src/streams/stransport.c +57 -32
- data/vendor/libgit2/src/streams/stransport.h +5 -0
- data/vendor/libgit2/src/streams/tls.c +50 -19
- data/vendor/libgit2/src/streams/tls.h +12 -4
- data/vendor/libgit2/src/strmap.c +47 -74
- data/vendor/libgit2/src/strmap.h +108 -33
- data/vendor/libgit2/src/submodule.c +272 -216
- data/vendor/libgit2/src/submodule.h +1 -1
- data/vendor/libgit2/src/sysdir.c +29 -19
- data/vendor/libgit2/src/tag.c +41 -28
- data/vendor/libgit2/src/tag.h +2 -1
- data/vendor/libgit2/src/trace.c +2 -2
- data/vendor/libgit2/src/trace.h +3 -3
- data/vendor/libgit2/src/trailer.c +52 -38
- data/vendor/libgit2/src/transaction.c +30 -29
- data/vendor/libgit2/src/transport.c +5 -5
- data/vendor/libgit2/src/transports/auth.c +15 -11
- data/vendor/libgit2/src/transports/auth.h +10 -3
- data/vendor/libgit2/src/transports/auth_negotiate.c +33 -18
- data/vendor/libgit2/src/transports/auth_negotiate.h +2 -2
- data/vendor/libgit2/src/transports/auth_ntlm.c +223 -0
- data/vendor/libgit2/src/transports/auth_ntlm.h +35 -0
- data/vendor/libgit2/src/transports/cred.c +24 -24
- data/vendor/libgit2/src/transports/git.c +26 -31
- data/vendor/libgit2/src/transports/http.c +881 -348
- data/vendor/libgit2/src/transports/http.h +2 -0
- data/vendor/libgit2/src/transports/local.c +35 -35
- data/vendor/libgit2/src/transports/smart.c +70 -47
- data/vendor/libgit2/src/transports/smart.h +3 -4
- data/vendor/libgit2/src/transports/smart_pkt.c +43 -40
- data/vendor/libgit2/src/transports/smart_protocol.c +96 -116
- data/vendor/libgit2/src/transports/ssh.c +77 -66
- data/vendor/libgit2/src/transports/winhttp.c +318 -314
- data/vendor/libgit2/src/tree-cache.c +19 -12
- data/vendor/libgit2/src/tree.c +103 -142
- data/vendor/libgit2/src/tree.h +1 -12
- data/vendor/libgit2/src/unix/map.c +3 -3
- data/vendor/libgit2/src/unix/posix.h +1 -11
- data/vendor/libgit2/src/userdiff.h +3 -1
- data/vendor/libgit2/src/util.c +70 -56
- data/vendor/libgit2/src/util.h +28 -156
- data/vendor/libgit2/src/vector.c +4 -4
- data/vendor/libgit2/src/wildmatch.c +320 -0
- data/vendor/libgit2/src/wildmatch.h +23 -0
- data/vendor/libgit2/src/win32/dir.c +3 -3
- data/vendor/libgit2/src/win32/findfile.c +3 -3
- data/vendor/libgit2/src/win32/map.c +9 -11
- data/vendor/libgit2/src/win32/msvc-compat.h +6 -0
- data/vendor/libgit2/src/win32/path_w32.c +113 -9
- data/vendor/libgit2/src/win32/path_w32.h +18 -29
- data/vendor/libgit2/src/win32/posix.h +1 -4
- data/vendor/libgit2/src/win32/posix_w32.c +70 -45
- data/vendor/libgit2/src/win32/precompiled.h +0 -2
- data/vendor/libgit2/src/win32/thread.c +5 -10
- data/vendor/libgit2/src/win32/w32_buffer.c +9 -5
- data/vendor/libgit2/src/win32/w32_common.h +39 -0
- data/vendor/libgit2/src/win32/w32_crtdbg_stacktrace.c +3 -2
- data/vendor/libgit2/src/win32/w32_crtdbg_stacktrace.h +26 -75
- data/vendor/libgit2/src/win32/w32_stack.c +6 -11
- data/vendor/libgit2/src/win32/w32_stack.h +3 -3
- data/vendor/libgit2/src/win32/w32_util.c +27 -64
- data/vendor/libgit2/src/win32/w32_util.h +5 -49
- data/vendor/libgit2/src/worktree.c +95 -60
- data/vendor/libgit2/src/worktree.h +2 -0
- data/vendor/libgit2/src/xdiff/xdiffi.c +7 -5
- data/vendor/libgit2/src/xdiff/xhistogram.c +1 -1
- data/vendor/libgit2/src/xdiff/xmerge.c +27 -15
- data/vendor/libgit2/src/xdiff/xpatience.c +3 -0
- data/vendor/libgit2/src/zstream.c +4 -4
- metadata +122 -33
- data/vendor/libgit2/deps/regex/CMakeLists.txt +0 -2
- data/vendor/libgit2/deps/regex/config.h +0 -7
- data/vendor/libgit2/deps/regex/regcomp.c +0 -3857
- data/vendor/libgit2/deps/regex/regex.c +0 -92
- data/vendor/libgit2/deps/regex/regex.h +0 -582
- data/vendor/libgit2/deps/regex/regex_internal.c +0 -1744
- data/vendor/libgit2/deps/regex/regex_internal.h +0 -819
- data/vendor/libgit2/deps/regex/regexec.c +0 -4369
- data/vendor/libgit2/include/git2/inttypes.h +0 -309
- data/vendor/libgit2/include/git2/sys/time.h +0 -31
- data/vendor/libgit2/libgit2.pc.in +0 -13
- data/vendor/libgit2/src/config_file.h +0 -73
- data/vendor/libgit2/src/fnmatch.c +0 -248
- data/vendor/libgit2/src/fnmatch.h +0 -48
- data/vendor/libgit2/src/hash/hash_collisiondetect.h +0 -47
- data/vendor/libgit2/src/hash/hash_openssl.h +0 -59
- data/vendor/libgit2/src/streams/curl.c +0 -385
@@ -14,11 +14,14 @@
|
|
14
14
|
#include "global.h"
|
15
15
|
#include "git2.h"
|
16
16
|
#include "buffer.h"
|
17
|
+
#include "net.h"
|
17
18
|
#include "netops.h"
|
18
19
|
#include "smart.h"
|
19
|
-
#include "cred.h"
|
20
20
|
#include "streams/socket.h"
|
21
21
|
|
22
|
+
#include "git2/cred.h"
|
23
|
+
#include "git2/sys/cred.h"
|
24
|
+
|
22
25
|
#ifdef GIT_SSH
|
23
26
|
|
24
27
|
#define OWNING_SUBTRANSPORT(s) ((ssh_subtransport *)(s)->parent.subtransport)
|
@@ -54,7 +57,7 @@ static void ssh_error(LIBSSH2_SESSION *session, const char *errmsg)
|
|
54
57
|
char *ssherr;
|
55
58
|
libssh2_session_last_error(session, &ssherr, NULL, 0);
|
56
59
|
|
57
|
-
|
60
|
+
git_error_set(GIT_ERROR_SSH, "%s: %s", errmsg, ssherr);
|
58
61
|
}
|
59
62
|
|
60
63
|
/*
|
@@ -85,7 +88,7 @@ static int gen_proto(git_buf *request, const char *cmd, const char *url)
|
|
85
88
|
|
86
89
|
done:
|
87
90
|
if (!repo) {
|
88
|
-
|
91
|
+
git_error_set(GIT_ERROR_NET, "malformed git protocol URL");
|
89
92
|
return -1;
|
90
93
|
}
|
91
94
|
|
@@ -121,7 +124,7 @@ static int send_command(ssh_stream *s)
|
|
121
124
|
s->sent_command = 1;
|
122
125
|
|
123
126
|
cleanup:
|
124
|
-
|
127
|
+
git_buf_dispose(&request);
|
125
128
|
return error;
|
126
129
|
}
|
127
130
|
|
@@ -132,7 +135,7 @@ static int ssh_stream_read(
|
|
132
135
|
size_t *bytes_read)
|
133
136
|
{
|
134
137
|
int rc;
|
135
|
-
ssh_stream *s = (ssh_stream
|
138
|
+
ssh_stream *s = GIT_CONTAINER_OF(stream, ssh_stream, parent);
|
136
139
|
|
137
140
|
*bytes_read = 0;
|
138
141
|
|
@@ -151,7 +154,7 @@ static int ssh_stream_read(
|
|
151
154
|
*/
|
152
155
|
if (rc == 0) {
|
153
156
|
if ((rc = libssh2_channel_read_stderr(s->channel, buffer, buf_size)) > 0) {
|
154
|
-
|
157
|
+
git_error_set(GIT_ERROR_SSH, "%*s", rc, buffer);
|
155
158
|
return GIT_EEOF;
|
156
159
|
} else if (rc < LIBSSH2_ERROR_NONE) {
|
157
160
|
ssh_error(s->session, "SSH could not read stderr");
|
@@ -170,7 +173,7 @@ static int ssh_stream_write(
|
|
170
173
|
const char *buffer,
|
171
174
|
size_t len)
|
172
175
|
{
|
173
|
-
ssh_stream *s = (ssh_stream
|
176
|
+
ssh_stream *s = GIT_CONTAINER_OF(stream, ssh_stream, parent);
|
174
177
|
size_t off = 0;
|
175
178
|
ssize_t ret = 0;
|
176
179
|
|
@@ -196,7 +199,7 @@ static int ssh_stream_write(
|
|
196
199
|
|
197
200
|
static void ssh_stream_free(git_smart_subtransport_stream *stream)
|
198
201
|
{
|
199
|
-
ssh_stream *s = (ssh_stream
|
202
|
+
ssh_stream *s = GIT_CONTAINER_OF(stream, ssh_stream, parent);
|
200
203
|
ssh_subtransport *t;
|
201
204
|
|
202
205
|
if (!stream)
|
@@ -238,7 +241,7 @@ static int ssh_stream_alloc(
|
|
238
241
|
assert(stream);
|
239
242
|
|
240
243
|
s = git__calloc(sizeof(ssh_stream), 1);
|
241
|
-
|
244
|
+
GIT_ERROR_CHECK_ALLOC(s);
|
242
245
|
|
243
246
|
s->parent.subtransport = &t->parent;
|
244
247
|
s->parent.read = ssh_stream_read;
|
@@ -258,8 +261,7 @@ static int ssh_stream_alloc(
|
|
258
261
|
}
|
259
262
|
|
260
263
|
static int git_ssh_extract_url_parts(
|
261
|
-
|
262
|
-
char **username,
|
264
|
+
git_net_url *urldata,
|
263
265
|
const char *url)
|
264
266
|
{
|
265
267
|
char *colon, *at;
|
@@ -271,20 +273,20 @@ static int git_ssh_extract_url_parts(
|
|
271
273
|
at = strchr(url, '@');
|
272
274
|
if (at) {
|
273
275
|
start = at + 1;
|
274
|
-
|
275
|
-
|
276
|
+
urldata->username = git__substrdup(url, at - url);
|
277
|
+
GIT_ERROR_CHECK_ALLOC(urldata->username);
|
276
278
|
} else {
|
277
279
|
start = url;
|
278
|
-
|
280
|
+
urldata->username = NULL;
|
279
281
|
}
|
280
282
|
|
281
283
|
if (colon == NULL || (colon < start)) {
|
282
|
-
|
284
|
+
git_error_set(GIT_ERROR_NET, "malformed URL");
|
283
285
|
return -1;
|
284
286
|
}
|
285
287
|
|
286
|
-
|
287
|
-
|
288
|
+
urldata->host = git__substrdup(start, colon - start);
|
289
|
+
GIT_ERROR_CHECK_ALLOC(urldata->host);
|
288
290
|
|
289
291
|
return 0;
|
290
292
|
}
|
@@ -350,7 +352,7 @@ static int _git_ssh_authenticate_session(
|
|
350
352
|
int rc;
|
351
353
|
|
352
354
|
do {
|
353
|
-
|
355
|
+
git_error_clear();
|
354
356
|
switch (cred->credtype) {
|
355
357
|
case GIT_CREDTYPE_USERPASS_PLAINTEXT: {
|
356
358
|
git_cred_userpass_plaintext *c = (git_cred_userpass_plaintext *)cred;
|
@@ -428,7 +430,7 @@ static int _git_ssh_authenticate_session(
|
|
428
430
|
return GIT_EAUTH;
|
429
431
|
|
430
432
|
if (rc != LIBSSH2_ERROR_NONE) {
|
431
|
-
if (!
|
433
|
+
if (!git_error_last())
|
432
434
|
ssh_error(session, "Failed to authenticate SSH session");
|
433
435
|
return -1;
|
434
436
|
}
|
@@ -447,24 +449,24 @@ static int request_creds(git_cred **out, ssh_subtransport *t, const char *user,
|
|
447
449
|
error = t->owner->cred_acquire_cb(&cred, t->owner->url, user, auth_methods,
|
448
450
|
t->owner->cred_acquire_payload);
|
449
451
|
|
450
|
-
if (error == GIT_PASSTHROUGH)
|
452
|
+
if (error == GIT_PASSTHROUGH) {
|
451
453
|
no_callback = 1;
|
452
|
-
else if (error < 0)
|
454
|
+
} else if (error < 0) {
|
453
455
|
return error;
|
454
|
-
else if (!cred) {
|
455
|
-
|
456
|
+
} else if (!cred) {
|
457
|
+
git_error_set(GIT_ERROR_SSH, "callback failed to initialize SSH credentials");
|
456
458
|
return -1;
|
457
459
|
}
|
458
460
|
}
|
459
461
|
|
460
462
|
if (no_callback) {
|
461
|
-
|
463
|
+
git_error_set(GIT_ERROR_SSH, "authentication required but no callback set");
|
462
464
|
return -1;
|
463
465
|
}
|
464
466
|
|
465
467
|
if (!(cred->credtype & auth_methods)) {
|
466
468
|
cred->free(cred);
|
467
|
-
|
469
|
+
git_error_set(GIT_ERROR_SSH, "callback returned unsupported credentials type");
|
468
470
|
return -1;
|
469
471
|
}
|
470
472
|
|
@@ -479,13 +481,13 @@ static int _git_ssh_session_create(
|
|
479
481
|
{
|
480
482
|
int rc = 0;
|
481
483
|
LIBSSH2_SESSION* s;
|
482
|
-
git_socket_stream *socket = (git_socket_stream
|
484
|
+
git_socket_stream *socket = GIT_CONTAINER_OF(io, git_socket_stream, parent);
|
483
485
|
|
484
486
|
assert(session);
|
485
487
|
|
486
488
|
s = libssh2_session_init();
|
487
489
|
if (!s) {
|
488
|
-
|
490
|
+
git_error_set(GIT_ERROR_NET, "failed to initialize SSH session");
|
489
491
|
return -1;
|
490
492
|
}
|
491
493
|
|
@@ -506,14 +508,15 @@ static int _git_ssh_session_create(
|
|
506
508
|
return 0;
|
507
509
|
}
|
508
510
|
|
511
|
+
#define SSH_DEFAULT_PORT "22"
|
512
|
+
|
509
513
|
static int _git_ssh_setup_conn(
|
510
514
|
ssh_subtransport *t,
|
511
515
|
const char *url,
|
512
516
|
const char *cmd,
|
513
517
|
git_smart_subtransport_stream **stream)
|
514
518
|
{
|
515
|
-
|
516
|
-
const char *default_port="22";
|
519
|
+
git_net_url urldata = GIT_NET_URL_INIT;
|
517
520
|
int auth_methods, error = 0;
|
518
521
|
size_t i;
|
519
522
|
ssh_stream *s;
|
@@ -535,19 +538,22 @@ static int _git_ssh_setup_conn(
|
|
535
538
|
const char *p = ssh_prefixes[i];
|
536
539
|
|
537
540
|
if (!git__prefixcmp(url, p)) {
|
538
|
-
if ((error =
|
541
|
+
if ((error = git_net_url_parse(&urldata, url)) < 0)
|
539
542
|
goto done;
|
540
543
|
|
541
544
|
goto post_extract;
|
542
545
|
}
|
543
546
|
}
|
544
|
-
if ((error = git_ssh_extract_url_parts(&
|
547
|
+
if ((error = git_ssh_extract_url_parts(&urldata, url)) < 0)
|
545
548
|
goto done;
|
546
|
-
|
547
|
-
|
549
|
+
|
550
|
+
if (urldata.port == NULL)
|
551
|
+
urldata.port = git__strdup(SSH_DEFAULT_PORT);
|
552
|
+
|
553
|
+
GIT_ERROR_CHECK_ALLOC(urldata.port);
|
548
554
|
|
549
555
|
post_extract:
|
550
|
-
if ((error = git_socket_stream_new(&s->io, host, port)) < 0 ||
|
556
|
+
if ((error = git_socket_stream_new(&s->io, urldata.host, urldata.port)) < 0 ||
|
551
557
|
(error = git_stream_connect(s->io)) < 0)
|
552
558
|
goto done;
|
553
559
|
|
@@ -560,6 +566,14 @@ post_extract:
|
|
560
566
|
|
561
567
|
cert.parent.cert_type = GIT_CERT_HOSTKEY_LIBSSH2;
|
562
568
|
|
569
|
+
#ifdef LIBSSH2_HOSTKEY_HASH_SHA256
|
570
|
+
key = libssh2_hostkey_hash(session, LIBSSH2_HOSTKEY_HASH_SHA256);
|
571
|
+
if (key != NULL) {
|
572
|
+
cert.type |= GIT_CERT_SSH_SHA256;
|
573
|
+
memcpy(&cert.hash_sha256, key, 32);
|
574
|
+
}
|
575
|
+
#endif
|
576
|
+
|
563
577
|
key = libssh2_hostkey_hash(session, LIBSSH2_HOSTKEY_HASH_SHA1);
|
564
578
|
if (key != NULL) {
|
565
579
|
cert.type |= GIT_CERT_SSH_SHA1;
|
@@ -573,41 +587,42 @@ post_extract:
|
|
573
587
|
}
|
574
588
|
|
575
589
|
if (cert.type == 0) {
|
576
|
-
|
590
|
+
git_error_set(GIT_ERROR_SSH, "unable to get the host key");
|
577
591
|
error = -1;
|
578
592
|
goto done;
|
579
593
|
}
|
580
594
|
|
581
595
|
/* We don't currently trust any hostkeys */
|
582
|
-
|
596
|
+
git_error_clear();
|
583
597
|
|
584
598
|
cert_ptr = &cert;
|
585
599
|
|
586
|
-
error = t->owner->certificate_check_cb((git_cert *) cert_ptr, 0, host, t->owner->message_cb_payload);
|
587
|
-
|
588
|
-
|
589
|
-
|
600
|
+
error = t->owner->certificate_check_cb((git_cert *) cert_ptr, 0, urldata.host, t->owner->message_cb_payload);
|
601
|
+
|
602
|
+
if (error < 0 && error != GIT_PASSTHROUGH) {
|
603
|
+
if (!git_error_last())
|
604
|
+
git_error_set(GIT_ERROR_NET, "user cancelled hostkey check");
|
590
605
|
|
591
606
|
goto done;
|
592
607
|
}
|
593
608
|
}
|
594
609
|
|
595
610
|
/* we need the username to ask for auth methods */
|
596
|
-
if (!
|
611
|
+
if (!urldata.username) {
|
597
612
|
if ((error = request_creds(&cred, t, NULL, GIT_CREDTYPE_USERNAME)) < 0)
|
598
613
|
goto done;
|
599
614
|
|
600
|
-
|
615
|
+
urldata.username = git__strdup(((git_cred_username *) cred)->username);
|
601
616
|
cred->free(cred);
|
602
617
|
cred = NULL;
|
603
|
-
if (!
|
618
|
+
if (!urldata.username)
|
604
619
|
goto done;
|
605
|
-
} else if (
|
606
|
-
if ((error = git_cred_userpass_plaintext_new(&cred,
|
620
|
+
} else if (urldata.username && urldata.password) {
|
621
|
+
if ((error = git_cred_userpass_plaintext_new(&cred, urldata.username, urldata.password)) < 0)
|
607
622
|
goto done;
|
608
623
|
}
|
609
624
|
|
610
|
-
if ((error = list_auth_methods(&auth_methods, session,
|
625
|
+
if ((error = list_auth_methods(&auth_methods, session, urldata.username)) < 0)
|
611
626
|
goto done;
|
612
627
|
|
613
628
|
error = GIT_EAUTH;
|
@@ -621,11 +636,11 @@ post_extract:
|
|
621
636
|
cred = NULL;
|
622
637
|
}
|
623
638
|
|
624
|
-
if ((error = request_creds(&cred, t,
|
639
|
+
if ((error = request_creds(&cred, t, urldata.username, auth_methods)) < 0)
|
625
640
|
goto done;
|
626
641
|
|
627
|
-
if (strcmp(
|
628
|
-
|
642
|
+
if (strcmp(urldata.username, git_cred_get_username(cred))) {
|
643
|
+
git_error_set(GIT_ERROR_SSH, "username does not match previous request");
|
629
644
|
error = -1;
|
630
645
|
goto done;
|
631
646
|
}
|
@@ -661,11 +676,7 @@ done:
|
|
661
676
|
if (cred)
|
662
677
|
cred->free(cred);
|
663
678
|
|
664
|
-
|
665
|
-
git__free(port);
|
666
|
-
git__free(path);
|
667
|
-
git__free(user);
|
668
|
-
git__free(pass);
|
679
|
+
git_net_url_dispose(&urldata);
|
669
680
|
|
670
681
|
return error;
|
671
682
|
}
|
@@ -692,7 +703,7 @@ static int ssh_uploadpack(
|
|
692
703
|
return 0;
|
693
704
|
}
|
694
705
|
|
695
|
-
|
706
|
+
git_error_set(GIT_ERROR_NET, "must call UPLOADPACK_LS before UPLOADPACK");
|
696
707
|
return -1;
|
697
708
|
}
|
698
709
|
|
@@ -719,7 +730,7 @@ static int ssh_receivepack(
|
|
719
730
|
return 0;
|
720
731
|
}
|
721
732
|
|
722
|
-
|
733
|
+
git_error_set(GIT_ERROR_NET, "must call RECEIVEPACK_LS before RECEIVEPACK");
|
723
734
|
return -1;
|
724
735
|
}
|
725
736
|
|
@@ -729,7 +740,7 @@ static int _ssh_action(
|
|
729
740
|
const char *url,
|
730
741
|
git_smart_service_t action)
|
731
742
|
{
|
732
|
-
ssh_subtransport *t = (ssh_subtransport
|
743
|
+
ssh_subtransport *t = GIT_CONTAINER_OF(subtransport, ssh_subtransport, parent);
|
733
744
|
|
734
745
|
switch (action) {
|
735
746
|
case GIT_SERVICE_UPLOADPACK_LS:
|
@@ -751,7 +762,7 @@ static int _ssh_action(
|
|
751
762
|
|
752
763
|
static int _ssh_close(git_smart_subtransport *subtransport)
|
753
764
|
{
|
754
|
-
ssh_subtransport *t = (ssh_subtransport
|
765
|
+
ssh_subtransport *t = GIT_CONTAINER_OF(subtransport, ssh_subtransport, parent);
|
755
766
|
|
756
767
|
assert(!t->current_stream);
|
757
768
|
|
@@ -762,7 +773,7 @@ static int _ssh_close(git_smart_subtransport *subtransport)
|
|
762
773
|
|
763
774
|
static void _ssh_free(git_smart_subtransport *subtransport)
|
764
775
|
{
|
765
|
-
ssh_subtransport *t = (ssh_subtransport
|
776
|
+
ssh_subtransport *t = GIT_CONTAINER_OF(subtransport, ssh_subtransport, parent);
|
766
777
|
|
767
778
|
assert(!t->current_stream);
|
768
779
|
|
@@ -835,7 +846,7 @@ int git_smart_subtransport_ssh(
|
|
835
846
|
GIT_UNUSED(param);
|
836
847
|
|
837
848
|
t = git__calloc(sizeof(ssh_subtransport), 1);
|
838
|
-
|
849
|
+
GIT_ERROR_CHECK_ALLOC(t);
|
839
850
|
|
840
851
|
t->owner = (transport_smart *)owner;
|
841
852
|
t->parent.action = _ssh_action;
|
@@ -851,7 +862,7 @@ int git_smart_subtransport_ssh(
|
|
851
862
|
assert(out);
|
852
863
|
*out = NULL;
|
853
864
|
|
854
|
-
|
865
|
+
git_error_set(GIT_ERROR_INVALID, "cannot create SSH transport. Library was built without SSH support");
|
855
866
|
return -1;
|
856
867
|
#endif
|
857
868
|
}
|
@@ -871,7 +882,7 @@ int git_transport_ssh_with_paths(git_transport **out, git_remote *owner, void *p
|
|
871
882
|
};
|
872
883
|
|
873
884
|
if (paths->count != 2) {
|
874
|
-
|
885
|
+
git_error_set(GIT_ERROR_SSH, "invalid ssh paths, must be two strings");
|
875
886
|
return GIT_EINVALIDSPEC;
|
876
887
|
}
|
877
888
|
|
@@ -882,9 +893,9 @@ int git_transport_ssh_with_paths(git_transport **out, git_remote *owner, void *p
|
|
882
893
|
t = (ssh_subtransport *) smart->wrapped;
|
883
894
|
|
884
895
|
t->cmd_uploadpack = git__strdup(paths->strings[0]);
|
885
|
-
|
896
|
+
GIT_ERROR_CHECK_ALLOC(t->cmd_uploadpack);
|
886
897
|
t->cmd_receivepack = git__strdup(paths->strings[1]);
|
887
|
-
|
898
|
+
GIT_ERROR_CHECK_ALLOC(t->cmd_receivepack);
|
888
899
|
|
889
900
|
*out = transport;
|
890
901
|
return 0;
|
@@ -895,7 +906,7 @@ int git_transport_ssh_with_paths(git_transport **out, git_remote *owner, void *p
|
|
895
906
|
assert(out);
|
896
907
|
*out = NULL;
|
897
908
|
|
898
|
-
|
909
|
+
git_error_set(GIT_ERROR_INVALID, "cannot create SSH transport. Library was built without SSH support");
|
899
910
|
return -1;
|
900
911
|
#endif
|
901
912
|
}
|
@@ -911,7 +922,7 @@ int git_transport_ssh_global_init(void)
|
|
911
922
|
{
|
912
923
|
#ifdef GIT_SSH
|
913
924
|
if (libssh2_init(0) < 0) {
|
914
|
-
|
925
|
+
git_error_set(GIT_ERROR_SSH, "unable to initialize libssh2");
|
915
926
|
return -1;
|
916
927
|
}
|
917
928
|
|
@@ -19,6 +19,7 @@
|
|
19
19
|
#include "repository.h"
|
20
20
|
#include "global.h"
|
21
21
|
#include "http.h"
|
22
|
+
#include "git2/sys/cred.h"
|
22
23
|
|
23
24
|
#include <wincrypt.h>
|
24
25
|
#include <winhttp.h>
|
@@ -48,6 +49,14 @@
|
|
48
49
|
# define WINHTTP_FLAG_SECURE_PROTOCOL_TLS1_2 0x00000800
|
49
50
|
#endif
|
50
51
|
|
52
|
+
#ifndef HTTP_STATUS_PERMANENT_REDIRECT
|
53
|
+
# define HTTP_STATUS_PERMANENT_REDIRECT 308
|
54
|
+
#endif
|
55
|
+
|
56
|
+
#ifndef DWORD_MAX
|
57
|
+
# define DWORD_MAX 0xffffffff
|
58
|
+
#endif
|
59
|
+
|
51
60
|
static const char *prefix_https = "https://";
|
52
61
|
static const char *upload_pack_service = "upload-pack";
|
53
62
|
static const char *upload_pack_ls_service_url = "/info/refs?service=git-upload-pack";
|
@@ -101,23 +110,43 @@ typedef struct {
|
|
101
110
|
} winhttp_stream;
|
102
111
|
|
103
112
|
typedef struct {
|
104
|
-
|
105
|
-
transport_smart *owner;
|
106
|
-
gitno_connection_data connection_data;
|
107
|
-
gitno_connection_data proxy_connection_data;
|
113
|
+
git_net_url url;
|
108
114
|
git_cred *cred;
|
109
|
-
git_cred *url_cred;
|
110
|
-
git_cred *proxy_cred;
|
111
115
|
int auth_mechanisms;
|
116
|
+
bool url_cred_presented;
|
117
|
+
} winhttp_server;
|
118
|
+
|
119
|
+
typedef struct {
|
120
|
+
git_smart_subtransport parent;
|
121
|
+
transport_smart *owner;
|
122
|
+
|
123
|
+
winhttp_server server;
|
124
|
+
winhttp_server proxy;
|
125
|
+
|
112
126
|
HINTERNET session;
|
113
127
|
HINTERNET connection;
|
114
128
|
} winhttp_subtransport;
|
115
129
|
|
116
|
-
static int
|
130
|
+
static int apply_userpass_credentials(HINTERNET request, DWORD target, int mechanisms, git_cred *cred)
|
117
131
|
{
|
118
132
|
git_cred_userpass_plaintext *c = (git_cred_userpass_plaintext *)cred;
|
119
|
-
wchar_t *user, *pass;
|
133
|
+
wchar_t *user = NULL, *pass = NULL;
|
120
134
|
int user_len = 0, pass_len = 0, error = 0;
|
135
|
+
DWORD native_scheme;
|
136
|
+
|
137
|
+
if (mechanisms & GIT_WINHTTP_AUTH_NEGOTIATE) {
|
138
|
+
native_scheme = WINHTTP_AUTH_SCHEME_NEGOTIATE;
|
139
|
+
} else if (mechanisms & GIT_WINHTTP_AUTH_NTLM) {
|
140
|
+
native_scheme = WINHTTP_AUTH_SCHEME_NTLM;
|
141
|
+
} else if (mechanisms & GIT_WINHTTP_AUTH_DIGEST) {
|
142
|
+
native_scheme = WINHTTP_AUTH_SCHEME_DIGEST;
|
143
|
+
} else if (mechanisms & GIT_WINHTTP_AUTH_BASIC) {
|
144
|
+
native_scheme = WINHTTP_AUTH_SCHEME_BASIC;
|
145
|
+
} else {
|
146
|
+
git_error_set(GIT_ERROR_NET, "invalid authentication scheme");
|
147
|
+
error = -1;
|
148
|
+
goto done;
|
149
|
+
}
|
121
150
|
|
122
151
|
if ((error = user_len = git__utf8_to_16_alloc(&user, c->username)) < 0)
|
123
152
|
goto done;
|
@@ -125,8 +154,8 @@ static int _apply_userpass_credential(HINTERNET request, DWORD target, DWORD sch
|
|
125
154
|
if ((error = pass_len = git__utf8_to_16_alloc(&pass, c->password)) < 0)
|
126
155
|
goto done;
|
127
156
|
|
128
|
-
if (!WinHttpSetCredentials(request, target,
|
129
|
-
|
157
|
+
if (!WinHttpSetCredentials(request, target, native_scheme, user, pass, NULL)) {
|
158
|
+
git_error_set(GIT_ERROR_OS, "failed to set credentials");
|
130
159
|
error = -1;
|
131
160
|
}
|
132
161
|
|
@@ -143,90 +172,74 @@ done:
|
|
143
172
|
return error;
|
144
173
|
}
|
145
174
|
|
146
|
-
static int
|
175
|
+
static int apply_default_credentials(HINTERNET request, DWORD target, int mechanisms)
|
147
176
|
{
|
148
|
-
|
149
|
-
|
150
|
-
WINHTTP_AUTH_SCHEME_DIGEST, cred);
|
151
|
-
}
|
152
|
-
|
153
|
-
return _apply_userpass_credential(request, WINHTTP_AUTH_TARGET_PROXY,
|
154
|
-
WINHTTP_AUTH_SCHEME_BASIC, cred);
|
155
|
-
}
|
156
|
-
|
157
|
-
static int apply_userpass_credential(HINTERNET request, int mechanisms, git_cred *cred)
|
158
|
-
{
|
159
|
-
DWORD native_scheme;
|
177
|
+
DWORD autologon_level = WINHTTP_AUTOLOGON_SECURITY_LEVEL_LOW;
|
178
|
+
DWORD native_scheme = 0;
|
160
179
|
|
161
|
-
if ((mechanisms &
|
162
|
-
|
180
|
+
if ((mechanisms & GIT_WINHTTP_AUTH_NEGOTIATE) != 0) {
|
181
|
+
native_scheme = WINHTTP_AUTH_SCHEME_NEGOTIATE;
|
182
|
+
} else if ((mechanisms & GIT_WINHTTP_AUTH_NTLM) != 0) {
|
163
183
|
native_scheme = WINHTTP_AUTH_SCHEME_NTLM;
|
164
|
-
} else if (mechanisms & GIT_WINHTTP_AUTH_BASIC) {
|
165
|
-
native_scheme = WINHTTP_AUTH_SCHEME_BASIC;
|
166
184
|
} else {
|
167
|
-
|
185
|
+
git_error_set(GIT_ERROR_NET, "invalid authentication scheme");
|
168
186
|
return -1;
|
169
187
|
}
|
170
188
|
|
171
|
-
|
172
|
-
|
173
|
-
|
174
|
-
|
175
|
-
|
176
|
-
|
177
|
-
/* Either the caller explicitly requested that default credentials be passed,
|
178
|
-
* or our fallback credential callback was invoked and checked that the target
|
179
|
-
* URI was in the appropriate Internet Explorer security zone. By setting this
|
180
|
-
* flag, we guarantee that the credentials are delivered by WinHTTP. The default
|
181
|
-
* is "medium" which applies to the intranet and sounds like it would correspond
|
182
|
-
* to Internet Explorer security zones, but in fact does not. */
|
183
|
-
DWORD data = WINHTTP_AUTOLOGON_SECURITY_LEVEL_LOW;
|
184
|
-
DWORD native_scheme = 0;
|
185
|
-
|
186
|
-
if ((mechanisms & GIT_WINHTTP_AUTH_NTLM) != 0)
|
187
|
-
native_scheme |= WINHTTP_AUTH_SCHEME_NTLM;
|
188
|
-
|
189
|
-
if ((mechanisms & GIT_WINHTTP_AUTH_NEGOTIATE) != 0)
|
190
|
-
native_scheme |= WINHTTP_AUTH_SCHEME_NEGOTIATE;
|
191
|
-
|
192
|
-
if (!native_scheme) {
|
193
|
-
giterr_set(GITERR_NET, "invalid authentication scheme");
|
189
|
+
/*
|
190
|
+
* Autologon policy must be "low" to use default creds.
|
191
|
+
* This is safe as the user has explicitly requested it.
|
192
|
+
*/
|
193
|
+
if (!WinHttpSetOption(request, WINHTTP_OPTION_AUTOLOGON_POLICY, &autologon_level, sizeof(DWORD))) {
|
194
|
+
git_error_set(GIT_ERROR_OS, "could not configure logon policy");
|
194
195
|
return -1;
|
195
196
|
}
|
196
197
|
|
197
|
-
if (!
|
198
|
-
|
199
|
-
|
200
|
-
if (!WinHttpSetCredentials(request, WINHTTP_AUTH_TARGET_SERVER, native_scheme, NULL, NULL, NULL))
|
198
|
+
if (!WinHttpSetCredentials(request, target, native_scheme, NULL, NULL, NULL)) {
|
199
|
+
git_error_set(GIT_ERROR_OS, "could not configure credentials");
|
201
200
|
return -1;
|
201
|
+
}
|
202
202
|
|
203
203
|
return 0;
|
204
204
|
}
|
205
205
|
|
206
|
-
static int
|
206
|
+
static int acquire_url_cred(
|
207
207
|
git_cred **cred,
|
208
|
-
const char *url,
|
209
|
-
const char *username_from_url,
|
210
208
|
unsigned int allowed_types,
|
211
|
-
|
209
|
+
const char *username,
|
210
|
+
const char *password)
|
212
211
|
{
|
213
|
-
|
212
|
+
if (allowed_types & GIT_CREDTYPE_USERPASS_PLAINTEXT)
|
213
|
+
return git_cred_userpass_plaintext_new(cred, username, password);
|
214
|
+
|
215
|
+
if ((allowed_types & GIT_CREDTYPE_DEFAULT) && *username == '\0' && *password == '\0')
|
216
|
+
return git_cred_default_new(cred);
|
214
217
|
|
215
|
-
|
216
|
-
|
218
|
+
return 1;
|
219
|
+
}
|
220
|
+
|
221
|
+
static int acquire_fallback_cred(
|
222
|
+
git_cred **cred,
|
223
|
+
const char *url,
|
224
|
+
unsigned int allowed_types)
|
225
|
+
{
|
226
|
+
int error = 1;
|
217
227
|
|
218
228
|
/* If the target URI supports integrated Windows authentication
|
219
229
|
* as an authentication mechanism */
|
220
230
|
if (GIT_CREDTYPE_DEFAULT & allowed_types) {
|
221
231
|
wchar_t *wide_url;
|
232
|
+
HRESULT hCoInitResult;
|
222
233
|
|
223
234
|
/* Convert URL to wide characters */
|
224
235
|
if (git__utf8_to_16_alloc(&wide_url, url) < 0) {
|
225
|
-
|
236
|
+
git_error_set(GIT_ERROR_OS, "failed to convert string to wide form");
|
226
237
|
return -1;
|
227
238
|
}
|
228
239
|
|
229
|
-
|
240
|
+
hCoInitResult = CoInitializeEx(NULL, COINIT_MULTITHREADED);
|
241
|
+
|
242
|
+
if (SUCCEEDED(hCoInitResult) || hCoInitResult == RPC_E_CHANGED_MODE) {
|
230
243
|
IInternetSecurityManager* pISM;
|
231
244
|
|
232
245
|
/* And if the target URI is in the My Computer, Intranet, or Trusted zones */
|
@@ -250,7 +263,9 @@ static int fallback_cred_acquire_cb(
|
|
250
263
|
pISM->lpVtbl->Release(pISM);
|
251
264
|
}
|
252
265
|
|
253
|
-
|
266
|
+
/* Only unitialize if the call to CoInitializeEx was successful. */
|
267
|
+
if (SUCCEEDED(hCoInitResult))
|
268
|
+
CoUninitialize();
|
254
269
|
}
|
255
270
|
|
256
271
|
git__free(wide_url);
|
@@ -269,29 +284,32 @@ static int certificate_check(winhttp_stream *s, int valid)
|
|
269
284
|
|
270
285
|
/* If there is no override, we should fail if WinHTTP doesn't think it's fine */
|
271
286
|
if (t->owner->certificate_check_cb == NULL && !valid) {
|
272
|
-
if (!
|
273
|
-
|
287
|
+
if (!git_error_last())
|
288
|
+
git_error_set(GIT_ERROR_NET, "unknown certificate check failure");
|
274
289
|
|
275
290
|
return GIT_ECERTIFICATE;
|
276
291
|
}
|
277
292
|
|
278
|
-
if (t->owner->certificate_check_cb == NULL ||
|
293
|
+
if (t->owner->certificate_check_cb == NULL || git__strcmp(t->server.url.scheme, "https") != 0)
|
279
294
|
return 0;
|
280
295
|
|
281
296
|
if (!WinHttpQueryOption(s->request, WINHTTP_OPTION_SERVER_CERT_CONTEXT, &cert_ctx, &cert_ctx_size)) {
|
282
|
-
|
297
|
+
git_error_set(GIT_ERROR_OS, "failed to get server certificate");
|
283
298
|
return -1;
|
284
299
|
}
|
285
300
|
|
286
|
-
|
301
|
+
git_error_clear();
|
287
302
|
cert.parent.cert_type = GIT_CERT_X509;
|
288
303
|
cert.data = cert_ctx->pbCertEncoded;
|
289
304
|
cert.len = cert_ctx->cbCertEncoded;
|
290
|
-
error = t->owner->certificate_check_cb((git_cert *) &cert, valid, t->
|
305
|
+
error = t->owner->certificate_check_cb((git_cert *) &cert, valid, t->server.url.host, t->owner->message_cb_payload);
|
291
306
|
CertFreeCertificateContext(cert_ctx);
|
292
307
|
|
293
|
-
if (error
|
294
|
-
|
308
|
+
if (error == GIT_PASSTHROUGH)
|
309
|
+
error = valid ? 0 : GIT_ECERTIFICATE;
|
310
|
+
|
311
|
+
if (error < 0 && !git_error_last())
|
312
|
+
git_error_set(GIT_ERROR_NET, "user cancelled certificate check");
|
295
313
|
|
296
314
|
return error;
|
297
315
|
}
|
@@ -321,37 +339,26 @@ static void winhttp_stream_close(winhttp_stream *s)
|
|
321
339
|
s->sent_request = 0;
|
322
340
|
}
|
323
341
|
|
324
|
-
|
325
|
-
|
326
|
-
*
|
327
|
-
|
328
|
-
|
329
|
-
|
330
|
-
const wchar_t *url, int url_len)
|
342
|
+
static int apply_credentials(
|
343
|
+
HINTERNET request,
|
344
|
+
git_net_url *url,
|
345
|
+
int target,
|
346
|
+
git_cred *creds,
|
347
|
+
int mechanisms)
|
331
348
|
{
|
332
|
-
|
349
|
+
int error = 0;
|
333
350
|
|
334
|
-
|
335
|
-
/* These tell WinHttpCrackUrl that we're interested in the fields */
|
336
|
-
components.dwUserNameLength = 1;
|
337
|
-
components.dwPasswordLength = 1;
|
351
|
+
GIT_UNUSED(url);
|
338
352
|
|
339
|
-
|
340
|
-
|
341
|
-
|
342
|
-
|
353
|
+
/* If we have creds, just apply them */
|
354
|
+
if (creds && creds->credtype == GIT_CREDTYPE_USERPASS_PLAINTEXT)
|
355
|
+
error = apply_userpass_credentials(request, target, mechanisms, creds);
|
356
|
+
else if (creds && creds->credtype == GIT_CREDTYPE_DEFAULT)
|
357
|
+
error = apply_default_credentials(request, target, mechanisms);
|
343
358
|
|
344
|
-
|
345
|
-
*user_len = components.dwUserNameLength;
|
346
|
-
*pass = components.lpszPassword;
|
347
|
-
*pass_len = components.dwPasswordLength;
|
348
|
-
|
349
|
-
return 0;
|
359
|
+
return error;
|
350
360
|
}
|
351
361
|
|
352
|
-
#define SCHEME_HTTP "http://"
|
353
|
-
#define SCHEME_HTTPS "https://"
|
354
|
-
|
355
362
|
static int winhttp_stream_connect(winhttp_stream *s)
|
356
363
|
{
|
357
364
|
winhttp_subtransport *t = OWNING_SUBTRANSPORT(s);
|
@@ -364,18 +371,20 @@ static int winhttp_stream_connect(winhttp_stream *s)
|
|
364
371
|
unsigned long disable_redirects = WINHTTP_DISABLE_REDIRECTS;
|
365
372
|
int default_timeout = TIMEOUT_INFINITE;
|
366
373
|
int default_connect_timeout = DEFAULT_CONNECT_TIMEOUT;
|
374
|
+
DWORD autologon_policy = WINHTTP_AUTOLOGON_SECURITY_LEVEL_HIGH;
|
375
|
+
|
367
376
|
size_t i;
|
368
377
|
const git_proxy_options *proxy_opts;
|
369
378
|
|
370
379
|
/* Prepare URL */
|
371
|
-
git_buf_printf(&buf, "%s%s", t->
|
380
|
+
git_buf_printf(&buf, "%s%s", t->server.url.path, s->service_url);
|
372
381
|
|
373
382
|
if (git_buf_oom(&buf))
|
374
383
|
return -1;
|
375
384
|
|
376
385
|
/* Convert URL to wide characters */
|
377
386
|
if (git__utf8_to_16_alloc(&s->request_uri, git_buf_cstr(&buf)) < 0) {
|
378
|
-
|
387
|
+
git_error_set(GIT_ERROR_OS, "failed to convert string to wide form");
|
379
388
|
goto on_error;
|
380
389
|
}
|
381
390
|
|
@@ -387,27 +396,31 @@ static int winhttp_stream_connect(winhttp_stream *s)
|
|
387
396
|
NULL,
|
388
397
|
WINHTTP_NO_REFERER,
|
389
398
|
types,
|
390
|
-
t->
|
399
|
+
git__strcmp(t->server.url.scheme, "https") == 0 ? WINHTTP_FLAG_SECURE : 0);
|
391
400
|
|
392
401
|
if (!s->request) {
|
393
|
-
|
402
|
+
git_error_set(GIT_ERROR_OS, "failed to open request");
|
394
403
|
goto on_error;
|
395
404
|
}
|
396
405
|
|
406
|
+
/* Never attempt default credentials; we'll provide them explicitly. */
|
407
|
+
if (!WinHttpSetOption(s->request, WINHTTP_OPTION_AUTOLOGON_POLICY, &autologon_policy, sizeof(DWORD)))
|
408
|
+
return -1;
|
409
|
+
|
397
410
|
if (!WinHttpSetTimeouts(s->request, default_timeout, default_connect_timeout, default_timeout, default_timeout)) {
|
398
|
-
|
411
|
+
git_error_set(GIT_ERROR_OS, "failed to set timeouts for WinHTTP");
|
399
412
|
goto on_error;
|
400
413
|
}
|
401
414
|
|
402
415
|
proxy_opts = &t->owner->proxy;
|
403
416
|
if (proxy_opts->type == GIT_PROXY_AUTO) {
|
404
417
|
/* Set proxy if necessary */
|
405
|
-
if (git_remote__get_http_proxy(t->owner->owner,
|
418
|
+
if (git_remote__get_http_proxy(t->owner->owner, (strcmp(t->server.url.scheme, "https") == 0), &proxy_url) < 0)
|
406
419
|
goto on_error;
|
407
420
|
}
|
408
421
|
else if (proxy_opts->type == GIT_PROXY_SPECIFIED) {
|
409
422
|
proxy_url = git__strdup(proxy_opts->url);
|
410
|
-
|
423
|
+
GIT_ERROR_CHECK_ALLOC(proxy_url);
|
411
424
|
}
|
412
425
|
|
413
426
|
if (proxy_url) {
|
@@ -415,38 +428,24 @@ static int winhttp_stream_connect(winhttp_stream *s)
|
|
415
428
|
WINHTTP_PROXY_INFO proxy_info;
|
416
429
|
wchar_t *proxy_wide;
|
417
430
|
|
418
|
-
|
419
|
-
t->proxy_connection_data.use_ssl = false;
|
420
|
-
} else if (!git__prefixcmp(proxy_url, SCHEME_HTTPS)) {
|
421
|
-
t->proxy_connection_data.use_ssl = true;
|
422
|
-
} else {
|
423
|
-
giterr_set(GITERR_NET, "invalid URL: '%s'", proxy_url);
|
424
|
-
return -1;
|
425
|
-
}
|
426
|
-
|
427
|
-
gitno_connection_data_free_ptrs(&t->proxy_connection_data);
|
431
|
+
git_net_url_dispose(&t->proxy.url);
|
428
432
|
|
429
|
-
if ((error =
|
430
|
-
&t->proxy_connection_data.user, &t->proxy_connection_data.pass, proxy_url, NULL)) < 0)
|
433
|
+
if ((error = git_net_url_parse(&t->proxy.url, proxy_url)) < 0)
|
431
434
|
goto on_error;
|
432
435
|
|
433
|
-
if (t->
|
434
|
-
|
435
|
-
|
436
|
-
|
437
|
-
|
438
|
-
if ((error = git_cred_userpass_plaintext_new(&t->proxy_cred, t->proxy_connection_data.user, t->proxy_connection_data.pass)) < 0)
|
439
|
-
goto on_error;
|
436
|
+
if (strcmp(t->proxy.url.scheme, "http") != 0 && strcmp(t->proxy.url.scheme, "https") != 0) {
|
437
|
+
git_error_set(GIT_ERROR_NET, "invalid URL: '%s'", proxy_url);
|
438
|
+
error = -1;
|
439
|
+
goto on_error;
|
440
440
|
}
|
441
441
|
|
442
|
-
|
443
|
-
|
444
|
-
else
|
445
|
-
git_buf_PUTS(&processed_url, SCHEME_HTTP);
|
442
|
+
git_buf_puts(&processed_url, t->proxy.url.scheme);
|
443
|
+
git_buf_PUTS(&processed_url, "://");
|
446
444
|
|
447
|
-
git_buf_puts(&processed_url, t->
|
448
|
-
|
449
|
-
|
445
|
+
git_buf_puts(&processed_url, t->proxy.url.host);
|
446
|
+
|
447
|
+
if (!git_net_url_is_default_port(&t->proxy.url))
|
448
|
+
git_buf_printf(&processed_url, ":%s", t->proxy.url.port);
|
450
449
|
|
451
450
|
if (git_buf_oom(&processed_url)) {
|
452
451
|
error = -1;
|
@@ -455,7 +454,7 @@ static int winhttp_stream_connect(winhttp_stream *s)
|
|
455
454
|
|
456
455
|
/* Convert URL to wide characters */
|
457
456
|
error = git__utf8_to_16_alloc(&proxy_wide, processed_url.ptr);
|
458
|
-
|
457
|
+
git_buf_dispose(&processed_url);
|
459
458
|
if (error < 0)
|
460
459
|
goto on_error;
|
461
460
|
|
@@ -467,20 +466,15 @@ static int winhttp_stream_connect(winhttp_stream *s)
|
|
467
466
|
WINHTTP_OPTION_PROXY,
|
468
467
|
&proxy_info,
|
469
468
|
sizeof(WINHTTP_PROXY_INFO))) {
|
470
|
-
|
469
|
+
git_error_set(GIT_ERROR_OS, "failed to set proxy");
|
471
470
|
git__free(proxy_wide);
|
472
471
|
goto on_error;
|
473
472
|
}
|
474
473
|
|
475
474
|
git__free(proxy_wide);
|
476
475
|
|
477
|
-
if (t->
|
478
|
-
|
479
|
-
if ((error = apply_userpass_credential_proxy(s->request, t->proxy_cred, t->auth_mechanisms)) < 0)
|
480
|
-
goto on_error;
|
481
|
-
}
|
482
|
-
}
|
483
|
-
|
476
|
+
if ((error = apply_credentials(s->request, &t->proxy.url, WINHTTP_AUTH_TARGET_PROXY, t->proxy.cred, t->proxy.auth_mechanisms)) < 0)
|
477
|
+
goto on_error;
|
484
478
|
}
|
485
479
|
|
486
480
|
/* Disable WinHTTP redirects so we can handle them manually. Why, you ask?
|
@@ -490,7 +484,8 @@ static int winhttp_stream_connect(winhttp_stream *s)
|
|
490
484
|
WINHTTP_OPTION_DISABLE_FEATURE,
|
491
485
|
&disable_redirects,
|
492
486
|
sizeof(disable_redirects))) {
|
493
|
-
|
487
|
+
git_error_set(GIT_ERROR_OS, "failed to disable redirects");
|
488
|
+
error = -1;
|
494
489
|
goto on_error;
|
495
490
|
}
|
496
491
|
|
@@ -504,7 +499,7 @@ static int winhttp_stream_connect(winhttp_stream *s)
|
|
504
499
|
|
505
500
|
/* Send Pragma: no-cache header */
|
506
501
|
if (!WinHttpAddRequestHeaders(s->request, pragma_nocache, (ULONG) -1L, WINHTTP_ADDREQ_FLAG_ADD)) {
|
507
|
-
|
502
|
+
git_error_set(GIT_ERROR_OS, "failed to add a header to the request");
|
508
503
|
goto on_error;
|
509
504
|
}
|
510
505
|
|
@@ -517,13 +512,13 @@ static int winhttp_stream_connect(winhttp_stream *s)
|
|
517
512
|
goto on_error;
|
518
513
|
|
519
514
|
if (git__utf8_to_16(ct, MAX_CONTENT_TYPE_LEN, git_buf_cstr(&buf)) < 0) {
|
520
|
-
|
515
|
+
git_error_set(GIT_ERROR_OS, "failed to convert content-type to wide characters");
|
521
516
|
goto on_error;
|
522
517
|
}
|
523
518
|
|
524
519
|
if (!WinHttpAddRequestHeaders(s->request, ct, (ULONG)-1L,
|
525
520
|
WINHTTP_ADDREQ_FLAG_ADD | WINHTTP_ADDREQ_FLAG_REPLACE)) {
|
526
|
-
|
521
|
+
git_error_set(GIT_ERROR_OS, "failed to add a header to the request");
|
527
522
|
goto on_error;
|
528
523
|
}
|
529
524
|
|
@@ -534,13 +529,13 @@ static int winhttp_stream_connect(winhttp_stream *s)
|
|
534
529
|
goto on_error;
|
535
530
|
|
536
531
|
if (git__utf8_to_16(ct, MAX_CONTENT_TYPE_LEN, git_buf_cstr(&buf)) < 0) {
|
537
|
-
|
532
|
+
git_error_set(GIT_ERROR_OS, "failed to convert accept header to wide characters");
|
538
533
|
goto on_error;
|
539
534
|
}
|
540
535
|
|
541
536
|
if (!WinHttpAddRequestHeaders(s->request, ct, (ULONG)-1L,
|
542
537
|
WINHTTP_ADDREQ_FLAG_ADD | WINHTTP_ADDREQ_FLAG_REPLACE)) {
|
543
|
-
|
538
|
+
git_error_set(GIT_ERROR_OS, "failed to add a header to the request");
|
544
539
|
goto on_error;
|
545
540
|
}
|
546
541
|
}
|
@@ -550,45 +545,28 @@ static int winhttp_stream_connect(winhttp_stream *s)
|
|
550
545
|
git_buf_clear(&buf);
|
551
546
|
git_buf_puts(&buf, t->owner->custom_headers.strings[i]);
|
552
547
|
if (git__utf8_to_16(ct, MAX_CONTENT_TYPE_LEN, git_buf_cstr(&buf)) < 0) {
|
553
|
-
|
548
|
+
git_error_set(GIT_ERROR_OS, "failed to convert custom header to wide characters");
|
554
549
|
goto on_error;
|
555
550
|
}
|
556
551
|
|
557
552
|
if (!WinHttpAddRequestHeaders(s->request, ct, (ULONG)-1L,
|
558
553
|
WINHTTP_ADDREQ_FLAG_ADD | WINHTTP_ADDREQ_FLAG_REPLACE)) {
|
559
|
-
|
554
|
+
git_error_set(GIT_ERROR_OS, "failed to add a header to the request");
|
560
555
|
goto on_error;
|
561
556
|
}
|
562
557
|
}
|
563
558
|
}
|
564
559
|
|
565
560
|
/* If requested, disable certificate validation */
|
566
|
-
if (t->
|
561
|
+
if (strcmp(t->server.url.scheme, "https") == 0) {
|
567
562
|
int flags;
|
568
563
|
|
569
564
|
if (t->owner->parent.read_flags(&t->owner->parent, &flags) < 0)
|
570
565
|
goto on_error;
|
571
566
|
}
|
572
567
|
|
573
|
-
|
574
|
-
if (t->cred &&
|
575
|
-
t->cred->credtype == GIT_CREDTYPE_USERPASS_PLAINTEXT &&
|
576
|
-
apply_userpass_credential(s->request, t->auth_mechanisms, t->cred) < 0)
|
568
|
+
if ((error = apply_credentials(s->request, &t->server.url, WINHTTP_AUTH_TARGET_SERVER, t->server.cred, t->server.auth_mechanisms)) < 0)
|
577
569
|
goto on_error;
|
578
|
-
else if (t->cred &&
|
579
|
-
t->cred->credtype == GIT_CREDTYPE_DEFAULT &&
|
580
|
-
apply_default_credentials(s->request, t->auth_mechanisms) < 0)
|
581
|
-
goto on_error;
|
582
|
-
|
583
|
-
/* If no other credentials have been applied and the URL has username and
|
584
|
-
* password, use those */
|
585
|
-
if (!t->cred && t->connection_data.user && t->connection_data.pass) {
|
586
|
-
if (!t->url_cred &&
|
587
|
-
git_cred_userpass_plaintext_new(&t->url_cred, t->connection_data.user, t->connection_data.pass) < 0)
|
588
|
-
goto on_error;
|
589
|
-
if (apply_userpass_credential(s->request, GIT_WINHTTP_AUTH_BASIC, t->url_cred) < 0)
|
590
|
-
goto on_error;
|
591
|
-
}
|
592
570
|
|
593
571
|
/* We've done everything up to calling WinHttpSendRequest. */
|
594
572
|
|
@@ -599,14 +577,14 @@ on_error:
|
|
599
577
|
winhttp_stream_close(s);
|
600
578
|
|
601
579
|
git__free(proxy_url);
|
602
|
-
|
580
|
+
git_buf_dispose(&buf);
|
603
581
|
return error;
|
604
582
|
}
|
605
583
|
|
606
584
|
static int parse_unauthorized_response(
|
607
|
-
HINTERNET request,
|
608
585
|
int *allowed_types,
|
609
|
-
int *allowed_mechanisms
|
586
|
+
int *allowed_mechanisms,
|
587
|
+
HINTERNET request)
|
610
588
|
{
|
611
589
|
DWORD supported, first, target;
|
612
590
|
|
@@ -617,7 +595,7 @@ static int parse_unauthorized_response(
|
|
617
595
|
* We can assume this was already done, since we know we are unauthorized.
|
618
596
|
*/
|
619
597
|
if (!WinHttpQueryAuthSchemes(request, &supported, &first, &target)) {
|
620
|
-
|
598
|
+
git_error_set(GIT_ERROR_OS, "failed to parse supported auth schemes");
|
621
599
|
return -1;
|
622
600
|
}
|
623
601
|
|
@@ -651,7 +629,7 @@ static int write_chunk(HINTERNET request, const char *buffer, size_t len)
|
|
651
629
|
git_buf buf = GIT_BUF_INIT;
|
652
630
|
|
653
631
|
/* Chunk header */
|
654
|
-
git_buf_printf(&buf, "%
|
632
|
+
git_buf_printf(&buf, "%"PRIXZ"\r\n", len);
|
655
633
|
|
656
634
|
if (git_buf_oom(&buf))
|
657
635
|
return -1;
|
@@ -659,18 +637,18 @@ static int write_chunk(HINTERNET request, const char *buffer, size_t len)
|
|
659
637
|
if (!WinHttpWriteData(request,
|
660
638
|
git_buf_cstr(&buf), (DWORD)git_buf_len(&buf),
|
661
639
|
&bytes_written)) {
|
662
|
-
|
663
|
-
|
640
|
+
git_buf_dispose(&buf);
|
641
|
+
git_error_set(GIT_ERROR_OS, "failed to write chunk header");
|
664
642
|
return -1;
|
665
643
|
}
|
666
644
|
|
667
|
-
|
645
|
+
git_buf_dispose(&buf);
|
668
646
|
|
669
647
|
/* Chunk body */
|
670
648
|
if (!WinHttpWriteData(request,
|
671
649
|
buffer, (DWORD)len,
|
672
650
|
&bytes_written)) {
|
673
|
-
|
651
|
+
git_error_set(GIT_ERROR_OS, "failed to write chunk");
|
674
652
|
return -1;
|
675
653
|
}
|
676
654
|
|
@@ -678,7 +656,7 @@ static int write_chunk(HINTERNET request, const char *buffer, size_t len)
|
|
678
656
|
if (!WinHttpWriteData(request,
|
679
657
|
"\r\n", 2,
|
680
658
|
&bytes_written)) {
|
681
|
-
|
659
|
+
git_error_set(GIT_ERROR_OS, "failed to write chunk footer");
|
682
660
|
return -1;
|
683
661
|
}
|
684
662
|
|
@@ -691,7 +669,7 @@ static int winhttp_close_connection(winhttp_subtransport *t)
|
|
691
669
|
|
692
670
|
if (t->connection) {
|
693
671
|
if (!WinHttpCloseHandle(t->connection)) {
|
694
|
-
|
672
|
+
git_error_set(GIT_ERROR_OS, "unable to close connection");
|
695
673
|
ret = -1;
|
696
674
|
}
|
697
675
|
|
@@ -700,7 +678,7 @@ static int winhttp_close_connection(winhttp_subtransport *t)
|
|
700
678
|
|
701
679
|
if (t->session) {
|
702
680
|
if (!WinHttpCloseHandle(t->session)) {
|
703
|
-
|
681
|
+
git_error_set(GIT_ERROR_OS, "unable to close session");
|
704
682
|
ret = -1;
|
705
683
|
}
|
706
684
|
|
@@ -719,27 +697,31 @@ static void CALLBACK winhttp_status(
|
|
719
697
|
{
|
720
698
|
DWORD status;
|
721
699
|
|
700
|
+
GIT_UNUSED(connection);
|
701
|
+
GIT_UNUSED(ctx);
|
702
|
+
GIT_UNUSED(info_len);
|
703
|
+
|
722
704
|
if (code != WINHTTP_CALLBACK_STATUS_SECURE_FAILURE)
|
723
705
|
return;
|
724
706
|
|
725
707
|
status = *((DWORD *)info);
|
726
708
|
|
727
709
|
if ((status & WINHTTP_CALLBACK_STATUS_FLAG_CERT_CN_INVALID))
|
728
|
-
|
710
|
+
git_error_set(GIT_ERROR_NET, "SSL certificate issued for different common name");
|
729
711
|
else if ((status & WINHTTP_CALLBACK_STATUS_FLAG_CERT_DATE_INVALID))
|
730
|
-
|
712
|
+
git_error_set(GIT_ERROR_NET, "SSL certificate has expired");
|
731
713
|
else if ((status & WINHTTP_CALLBACK_STATUS_FLAG_INVALID_CA))
|
732
|
-
|
714
|
+
git_error_set(GIT_ERROR_NET, "SSL certificate signed by unknown CA");
|
733
715
|
else if ((status & WINHTTP_CALLBACK_STATUS_FLAG_INVALID_CERT))
|
734
|
-
|
716
|
+
git_error_set(GIT_ERROR_NET, "SSL certificate is invalid");
|
735
717
|
else if ((status & WINHTTP_CALLBACK_STATUS_FLAG_CERT_REV_FAILED))
|
736
|
-
|
718
|
+
git_error_set(GIT_ERROR_NET, "certificate revocation check failed");
|
737
719
|
else if ((status & WINHTTP_CALLBACK_STATUS_FLAG_CERT_REVOKED))
|
738
|
-
|
720
|
+
git_error_set(GIT_ERROR_NET, "SSL certificate was revoked");
|
739
721
|
else if ((status & WINHTTP_CALLBACK_STATUS_FLAG_SECURITY_CHANNEL_ERROR))
|
740
|
-
|
722
|
+
git_error_set(GIT_ERROR_NET, "security libraries could not be loaded");
|
741
723
|
else
|
742
|
-
|
724
|
+
git_error_set(GIT_ERROR_NET, "unknown security error %lu", status);
|
743
725
|
}
|
744
726
|
|
745
727
|
static int winhttp_connect(
|
@@ -761,13 +743,13 @@ static int winhttp_connect(
|
|
761
743
|
t->connection = NULL;
|
762
744
|
|
763
745
|
/* Prepare port */
|
764
|
-
if (git__strntol32(&port, t->
|
765
|
-
strlen(t->
|
746
|
+
if (git__strntol32(&port, t->server.url.port,
|
747
|
+
strlen(t->server.url.port), NULL, 10) < 0)
|
766
748
|
return -1;
|
767
749
|
|
768
750
|
/* Prepare host */
|
769
|
-
if (git__utf8_to_16_alloc(&wide_host, t->
|
770
|
-
|
751
|
+
if (git__utf8_to_16_alloc(&wide_host, t->server.url.host) < 0) {
|
752
|
+
git_error_set(GIT_ERROR_OS, "unable to convert host to wide characters");
|
771
753
|
return -1;
|
772
754
|
}
|
773
755
|
|
@@ -778,13 +760,13 @@ static int winhttp_connect(
|
|
778
760
|
}
|
779
761
|
|
780
762
|
if (git__utf8_to_16_alloc(&wide_ua, git_buf_cstr(&ua)) < 0) {
|
781
|
-
|
763
|
+
git_error_set(GIT_ERROR_OS, "unable to convert host to wide characters");
|
782
764
|
git__free(wide_host);
|
783
|
-
|
765
|
+
git_buf_dispose(&ua);
|
784
766
|
return -1;
|
785
767
|
}
|
786
768
|
|
787
|
-
|
769
|
+
git_buf_dispose(&ua);
|
788
770
|
|
789
771
|
/* Establish session */
|
790
772
|
t->session = WinHttpOpen(
|
@@ -795,7 +777,7 @@ static int winhttp_connect(
|
|
795
777
|
0);
|
796
778
|
|
797
779
|
if (!t->session) {
|
798
|
-
|
780
|
+
git_error_set(GIT_ERROR_OS, "failed to init WinHTTP");
|
799
781
|
goto on_error;
|
800
782
|
}
|
801
783
|
|
@@ -810,7 +792,7 @@ static int winhttp_connect(
|
|
810
792
|
sizeof(protocols));
|
811
793
|
|
812
794
|
if (!WinHttpSetTimeouts(t->session, default_timeout, default_connect_timeout, default_timeout, default_timeout)) {
|
813
|
-
|
795
|
+
git_error_set(GIT_ERROR_OS, "failed to set timeouts for WinHTTP");
|
814
796
|
goto on_error;
|
815
797
|
}
|
816
798
|
|
@@ -823,12 +805,12 @@ static int winhttp_connect(
|
|
823
805
|
0);
|
824
806
|
|
825
807
|
if (!t->connection) {
|
826
|
-
|
808
|
+
git_error_set(GIT_ERROR_OS, "failed to connect to host");
|
827
809
|
goto on_error;
|
828
810
|
}
|
829
811
|
|
830
812
|
if (WinHttpSetStatusCallback(t->connection, winhttp_status, WINHTTP_CALLBACK_FLAG_SECURE_FAILURE, 0) == WINHTTP_INVALID_STATUS_CALLBACK) {
|
831
|
-
|
813
|
+
git_error_set(GIT_ERROR_OS, "failed to set status callback");
|
832
814
|
goto on_error;
|
833
815
|
}
|
834
816
|
|
@@ -849,6 +831,11 @@ static int do_send_request(winhttp_stream *s, size_t len, int ignore_length)
|
|
849
831
|
int attempts;
|
850
832
|
bool success;
|
851
833
|
|
834
|
+
if (len > DWORD_MAX) {
|
835
|
+
SetLastError(ERROR_NOT_ENOUGH_MEMORY);
|
836
|
+
return -1;
|
837
|
+
}
|
838
|
+
|
852
839
|
for (attempts = 0; attempts < 5; attempts++) {
|
853
840
|
if (ignore_length) {
|
854
841
|
success = WinHttpSendRequest(s->request,
|
@@ -859,10 +846,10 @@ static int do_send_request(winhttp_stream *s, size_t len, int ignore_length)
|
|
859
846
|
success = WinHttpSendRequest(s->request,
|
860
847
|
WINHTTP_NO_ADDITIONAL_HEADERS, 0,
|
861
848
|
WINHTTP_NO_REQUEST_DATA, 0,
|
862
|
-
len, 0);
|
849
|
+
(DWORD)len, 0);
|
863
850
|
}
|
864
851
|
|
865
|
-
if (success || GetLastError() != SEC_E_BUFFER_TOO_SMALL)
|
852
|
+
if (success || GetLastError() != (DWORD)SEC_E_BUFFER_TOO_SMALL)
|
866
853
|
break;
|
867
854
|
}
|
868
855
|
|
@@ -874,10 +861,10 @@ static int send_request(winhttp_stream *s, size_t len, int ignore_length)
|
|
874
861
|
int request_failed = 0, cert_valid = 1, error = 0;
|
875
862
|
DWORD ignore_flags;
|
876
863
|
|
877
|
-
|
864
|
+
git_error_clear();
|
878
865
|
if ((error = do_send_request(s, len, ignore_length)) < 0) {
|
879
866
|
if (GetLastError() != ERROR_WINHTTP_SECURE_FAILURE) {
|
880
|
-
|
867
|
+
git_error_set(GIT_ERROR_OS, "failed to send request");
|
881
868
|
return -1;
|
882
869
|
}
|
883
870
|
|
@@ -885,10 +872,10 @@ static int send_request(winhttp_stream *s, size_t len, int ignore_length)
|
|
885
872
|
cert_valid = 0;
|
886
873
|
}
|
887
874
|
|
888
|
-
|
875
|
+
git_error_clear();
|
889
876
|
if ((error = certificate_check(s, cert_valid)) < 0) {
|
890
|
-
if (!
|
891
|
-
|
877
|
+
if (!git_error_last())
|
878
|
+
git_error_set(GIT_ERROR_OS, "user cancelled certificate check");
|
892
879
|
|
893
880
|
return error;
|
894
881
|
}
|
@@ -900,16 +887,69 @@ static int send_request(winhttp_stream *s, size_t len, int ignore_length)
|
|
900
887
|
ignore_flags = no_check_cert_flags;
|
901
888
|
|
902
889
|
if (!WinHttpSetOption(s->request, WINHTTP_OPTION_SECURITY_FLAGS, &ignore_flags, sizeof(ignore_flags))) {
|
903
|
-
|
890
|
+
git_error_set(GIT_ERROR_OS, "failed to set security options");
|
904
891
|
return -1;
|
905
892
|
}
|
906
893
|
|
907
894
|
if ((error = do_send_request(s, len, ignore_length)) < 0)
|
908
|
-
|
895
|
+
git_error_set(GIT_ERROR_OS, "failed to send request with unchecked certificate");
|
909
896
|
|
910
897
|
return error;
|
911
898
|
}
|
912
899
|
|
900
|
+
static int acquire_credentials(
|
901
|
+
HINTERNET request,
|
902
|
+
winhttp_server *server,
|
903
|
+
const char *url_str,
|
904
|
+
git_cred_acquire_cb cred_cb,
|
905
|
+
void *cred_cb_payload)
|
906
|
+
{
|
907
|
+
int allowed_types;
|
908
|
+
int error = 1;
|
909
|
+
|
910
|
+
if (parse_unauthorized_response(&allowed_types, &server->auth_mechanisms, request) < 0)
|
911
|
+
return -1;
|
912
|
+
|
913
|
+
if (allowed_types) {
|
914
|
+
git_cred_free(server->cred);
|
915
|
+
server->cred = NULL;
|
916
|
+
|
917
|
+
/* Start with URL-specified credentials, if there were any. */
|
918
|
+
if (!server->url_cred_presented && server->url.username && server->url.password) {
|
919
|
+
error = acquire_url_cred(&server->cred, allowed_types, server->url.username, server->url.password);
|
920
|
+
server->url_cred_presented = 1;
|
921
|
+
|
922
|
+
if (error < 0)
|
923
|
+
return error;
|
924
|
+
}
|
925
|
+
|
926
|
+
/* Next use the user-defined callback, if there is one. */
|
927
|
+
if (error > 0 && cred_cb) {
|
928
|
+
error = cred_cb(&server->cred, url_str, server->url.username, allowed_types, cred_cb_payload);
|
929
|
+
|
930
|
+
/* Treat GIT_PASSTHROUGH as though git_cred_acquire_cb isn't set */
|
931
|
+
if (error == GIT_PASSTHROUGH)
|
932
|
+
error = 1;
|
933
|
+
else if (error < 0)
|
934
|
+
return error;
|
935
|
+
}
|
936
|
+
|
937
|
+
/* Finally, invoke the fallback default credential lookup. */
|
938
|
+
if (error > 0) {
|
939
|
+
error = acquire_fallback_cred(&server->cred, url_str, allowed_types);
|
940
|
+
|
941
|
+
if (error < 0)
|
942
|
+
return error;
|
943
|
+
}
|
944
|
+
}
|
945
|
+
|
946
|
+
/*
|
947
|
+
* No error occurred but we could not find appropriate credentials.
|
948
|
+
* This behaves like a pass-through.
|
949
|
+
*/
|
950
|
+
return error;
|
951
|
+
}
|
952
|
+
|
913
953
|
static int winhttp_stream_read(
|
914
954
|
git_smart_subtransport_stream *stream,
|
915
955
|
char *buffer,
|
@@ -924,8 +964,8 @@ static int winhttp_stream_read(
|
|
924
964
|
|
925
965
|
replay:
|
926
966
|
/* Enforce a reasonable cap on the number of replays */
|
927
|
-
if (++
|
928
|
-
|
967
|
+
if (replay_count++ >= GIT_HTTP_REPLAY_MAX) {
|
968
|
+
git_error_set(GIT_ERROR_NET, "too many redirects or authentication replays");
|
929
969
|
return -1;
|
930
970
|
}
|
931
971
|
|
@@ -960,7 +1000,7 @@ replay:
|
|
960
1000
|
if (!WinHttpWriteData(s->request,
|
961
1001
|
"0\r\n\r\n", 5,
|
962
1002
|
&bytes_written)) {
|
963
|
-
|
1003
|
+
git_error_set(GIT_ERROR_OS, "failed to write final chunk");
|
964
1004
|
return -1;
|
965
1005
|
}
|
966
1006
|
}
|
@@ -971,11 +1011,12 @@ replay:
|
|
971
1011
|
if (INVALID_SET_FILE_POINTER == SetFilePointer(s->post_body,
|
972
1012
|
0, 0, FILE_BEGIN) &&
|
973
1013
|
NO_ERROR != GetLastError()) {
|
974
|
-
|
1014
|
+
git_error_set(GIT_ERROR_OS, "failed to reset file pointer");
|
975
1015
|
return -1;
|
976
1016
|
}
|
977
1017
|
|
978
1018
|
buffer = git__malloc(CACHED_POST_BODY_BUF_SIZE);
|
1019
|
+
GIT_ERROR_CHECK_ALLOC(buffer);
|
979
1020
|
|
980
1021
|
while (len > 0) {
|
981
1022
|
DWORD bytes_written;
|
@@ -985,14 +1026,14 @@ replay:
|
|
985
1026
|
&bytes_read, NULL) ||
|
986
1027
|
!bytes_read) {
|
987
1028
|
git__free(buffer);
|
988
|
-
|
1029
|
+
git_error_set(GIT_ERROR_OS, "failed to read from temp file");
|
989
1030
|
return -1;
|
990
1031
|
}
|
991
1032
|
|
992
1033
|
if (!WinHttpWriteData(s->request, buffer,
|
993
1034
|
bytes_read, &bytes_written)) {
|
994
1035
|
git__free(buffer);
|
995
|
-
|
1036
|
+
git_error_set(GIT_ERROR_OS, "failed to write data");
|
996
1037
|
return -1;
|
997
1038
|
}
|
998
1039
|
|
@@ -1008,7 +1049,7 @@ replay:
|
|
1008
1049
|
}
|
1009
1050
|
|
1010
1051
|
if (!WinHttpReceiveResponse(s->request, 0)) {
|
1011
|
-
|
1052
|
+
git_error_set(GIT_ERROR_OS, "failed to receive response");
|
1012
1053
|
return -1;
|
1013
1054
|
}
|
1014
1055
|
|
@@ -1020,7 +1061,7 @@ replay:
|
|
1020
1061
|
WINHTTP_HEADER_NAME_BY_INDEX,
|
1021
1062
|
&status_code, &status_code_length,
|
1022
1063
|
WINHTTP_NO_HEADER_INDEX)) {
|
1023
|
-
|
1064
|
+
git_error_set(GIT_ERROR_OS, "failed to retrieve status code");
|
1024
1065
|
return -1;
|
1025
1066
|
}
|
1026
1067
|
|
@@ -1034,7 +1075,8 @@ replay:
|
|
1034
1075
|
HTTP_STATUS_REDIRECT == status_code ||
|
1035
1076
|
(HTTP_STATUS_REDIRECT_METHOD == status_code &&
|
1036
1077
|
get_verb == s->verb) ||
|
1037
|
-
HTTP_STATUS_REDIRECT_KEEP_VERB == status_code
|
1078
|
+
HTTP_STATUS_REDIRECT_KEEP_VERB == status_code ||
|
1079
|
+
HTTP_STATUS_PERMANENT_REDIRECT == status_code)) {
|
1038
1080
|
|
1039
1081
|
/* Check for Windows 7. This workaround is only necessary on
|
1040
1082
|
* Windows Vista and earlier. Windows 7 is version 6.1. */
|
@@ -1050,12 +1092,12 @@ replay:
|
|
1050
1092
|
&location_length,
|
1051
1093
|
WINHTTP_NO_HEADER_INDEX) ||
|
1052
1094
|
GetLastError() != ERROR_INSUFFICIENT_BUFFER) {
|
1053
|
-
|
1095
|
+
git_error_set(GIT_ERROR_OS, "failed to read Location header");
|
1054
1096
|
return -1;
|
1055
1097
|
}
|
1056
1098
|
|
1057
1099
|
location = git__malloc(location_length);
|
1058
|
-
|
1100
|
+
GIT_ERROR_CHECK_ALLOC(location);
|
1059
1101
|
|
1060
1102
|
if (!WinHttpQueryHeaders(s->request,
|
1061
1103
|
WINHTTP_QUERY_LOCATION,
|
@@ -1063,14 +1105,14 @@ replay:
|
|
1063
1105
|
location,
|
1064
1106
|
&location_length,
|
1065
1107
|
WINHTTP_NO_HEADER_INDEX)) {
|
1066
|
-
|
1108
|
+
git_error_set(GIT_ERROR_OS, "failed to read Location header");
|
1067
1109
|
git__free(location);
|
1068
1110
|
return -1;
|
1069
1111
|
}
|
1070
1112
|
|
1071
1113
|
/* Convert the Location header to UTF-8 */
|
1072
1114
|
if (git__utf16_to_8_alloc(&location8, location) < 0) {
|
1073
|
-
|
1115
|
+
git_error_set(GIT_ERROR_OS, "failed to convert Location header to UTF-8");
|
1074
1116
|
git__free(location);
|
1075
1117
|
return -1;
|
1076
1118
|
}
|
@@ -1082,7 +1124,7 @@ replay:
|
|
1082
1124
|
|
1083
1125
|
if (!git__prefixcmp_icase(location8, prefix_https)) {
|
1084
1126
|
/* Upgrade to secure connection; disconnect and start over */
|
1085
|
-
if (
|
1127
|
+
if (gitno_connection_data_handle_redirect(&t->server.url, location8, s->service_url) < 0) {
|
1086
1128
|
git__free(location8);
|
1087
1129
|
return -1;
|
1088
1130
|
}
|
@@ -1097,72 +1139,39 @@ replay:
|
|
1097
1139
|
goto replay;
|
1098
1140
|
}
|
1099
1141
|
|
1100
|
-
/* Handle proxy authentication failures */
|
1101
|
-
if (status_code == HTTP_STATUS_PROXY_AUTH_REQ) {
|
1102
|
-
int allowed_types;
|
1103
|
-
|
1104
|
-
if (parse_unauthorized_response(s->request, &allowed_types, &t->auth_mechanisms) < 0)
|
1105
|
-
return -1;
|
1106
|
-
|
1107
|
-
/* TODO: extract the username from the url, no payload? */
|
1108
|
-
if (t->owner->proxy.credentials) {
|
1109
|
-
int cred_error = 1;
|
1110
|
-
cred_error = t->owner->proxy.credentials(&t->proxy_cred, t->owner->proxy.url, NULL, allowed_types, t->owner->proxy.payload);
|
1111
|
-
|
1112
|
-
if (cred_error < 0)
|
1113
|
-
return cred_error;
|
1114
|
-
}
|
1115
|
-
|
1116
|
-
winhttp_stream_close(s);
|
1117
|
-
goto replay;
|
1118
|
-
}
|
1119
|
-
|
1120
1142
|
/* Handle authentication failures */
|
1121
|
-
if (
|
1122
|
-
int
|
1123
|
-
|
1124
|
-
|
1125
|
-
|
1126
|
-
|
1127
|
-
|
1128
|
-
|
1129
|
-
|
1130
|
-
|
1131
|
-
t->cred
|
1132
|
-
|
1133
|
-
|
1134
|
-
|
1135
|
-
|
1136
|
-
|
1137
|
-
|
1138
|
-
|
1139
|
-
|
1140
|
-
|
1141
|
-
|
1142
|
-
|
1143
|
-
|
1144
|
-
|
1145
|
-
|
1146
|
-
|
1147
|
-
|
1148
|
-
|
1149
|
-
if (cred_error < 0)
|
1150
|
-
return cred_error;
|
1151
|
-
}
|
1152
|
-
|
1153
|
-
if (!cred_error) {
|
1154
|
-
assert(t->cred);
|
1155
|
-
|
1156
|
-
winhttp_stream_close(s);
|
1157
|
-
|
1158
|
-
/* Successfully acquired a credential */
|
1159
|
-
goto replay;
|
1160
|
-
}
|
1143
|
+
if (status_code == HTTP_STATUS_DENIED) {
|
1144
|
+
int error = acquire_credentials(s->request,
|
1145
|
+
&t->server,
|
1146
|
+
t->owner->url,
|
1147
|
+
t->owner->cred_acquire_cb,
|
1148
|
+
t->owner->cred_acquire_payload);
|
1149
|
+
|
1150
|
+
if (error < 0) {
|
1151
|
+
return error;
|
1152
|
+
} else if (!error) {
|
1153
|
+
assert(t->server.cred);
|
1154
|
+
winhttp_stream_close(s);
|
1155
|
+
goto replay;
|
1156
|
+
}
|
1157
|
+
} else if (status_code == HTTP_STATUS_PROXY_AUTH_REQ) {
|
1158
|
+
int error = acquire_credentials(s->request,
|
1159
|
+
&t->proxy,
|
1160
|
+
t->owner->proxy.url,
|
1161
|
+
t->owner->proxy.credentials,
|
1162
|
+
t->owner->proxy.payload);
|
1163
|
+
|
1164
|
+
if (error < 0) {
|
1165
|
+
return error;
|
1166
|
+
} else if (!error) {
|
1167
|
+
assert(t->proxy.cred);
|
1168
|
+
winhttp_stream_close(s);
|
1169
|
+
goto replay;
|
1161
1170
|
}
|
1162
1171
|
}
|
1163
1172
|
|
1164
1173
|
if (HTTP_STATUS_OK != status_code) {
|
1165
|
-
|
1174
|
+
git_error_set(GIT_ERROR_NET, "request failed with status code: %lu", status_code);
|
1166
1175
|
return -1;
|
1167
1176
|
}
|
1168
1177
|
|
@@ -1173,7 +1182,7 @@ replay:
|
|
1173
1182
|
p_snprintf(expected_content_type_8, MAX_CONTENT_TYPE_LEN, "application/x-git-%s-advertisement", s->service);
|
1174
1183
|
|
1175
1184
|
if (git__utf8_to_16(expected_content_type, MAX_CONTENT_TYPE_LEN, expected_content_type_8) < 0) {
|
1176
|
-
|
1185
|
+
git_error_set(GIT_ERROR_OS, "failed to convert expected content-type to wide characters");
|
1177
1186
|
return -1;
|
1178
1187
|
}
|
1179
1188
|
|
@@ -1184,12 +1193,12 @@ replay:
|
|
1184
1193
|
WINHTTP_HEADER_NAME_BY_INDEX,
|
1185
1194
|
&content_type, &content_type_length,
|
1186
1195
|
WINHTTP_NO_HEADER_INDEX)) {
|
1187
|
-
|
1196
|
+
git_error_set(GIT_ERROR_OS, "failed to retrieve response content-type");
|
1188
1197
|
return -1;
|
1189
1198
|
}
|
1190
1199
|
|
1191
1200
|
if (wcscmp(expected_content_type, content_type)) {
|
1192
|
-
|
1201
|
+
git_error_set(GIT_ERROR_NET, "received unexpected content-type");
|
1193
1202
|
return -1;
|
1194
1203
|
}
|
1195
1204
|
|
@@ -1201,7 +1210,7 @@ replay:
|
|
1201
1210
|
(DWORD)buf_size,
|
1202
1211
|
&dw_bytes_read))
|
1203
1212
|
{
|
1204
|
-
|
1213
|
+
git_error_set(GIT_ERROR_OS, "failed to read data");
|
1205
1214
|
return -1;
|
1206
1215
|
}
|
1207
1216
|
|
@@ -1224,7 +1233,7 @@ static int winhttp_stream_write_single(
|
|
1224
1233
|
|
1225
1234
|
/* This implementation of write permits only a single call. */
|
1226
1235
|
if (s->sent_request) {
|
1227
|
-
|
1236
|
+
git_error_set(GIT_ERROR_NET, "subtransport configured for only one write");
|
1228
1237
|
return -1;
|
1229
1238
|
}
|
1230
1239
|
|
@@ -1237,7 +1246,7 @@ static int winhttp_stream_write_single(
|
|
1237
1246
|
(LPCVOID)buffer,
|
1238
1247
|
(DWORD)len,
|
1239
1248
|
&bytes_written)) {
|
1240
|
-
|
1249
|
+
git_error_set(GIT_ERROR_OS, "failed to write data");
|
1241
1250
|
return -1;
|
1242
1251
|
}
|
1243
1252
|
|
@@ -1255,12 +1264,12 @@ static int put_uuid_string(LPWSTR buffer, size_t buffer_len_cch)
|
|
1255
1264
|
if (RPC_S_OK != status &&
|
1256
1265
|
RPC_S_UUID_LOCAL_ONLY != status &&
|
1257
1266
|
RPC_S_UUID_NO_ADDRESS != status) {
|
1258
|
-
|
1267
|
+
git_error_set(GIT_ERROR_NET, "unable to generate name for temp file");
|
1259
1268
|
return -1;
|
1260
1269
|
}
|
1261
1270
|
|
1262
1271
|
if (buffer_len_cch < UUID_LENGTH_CCH + 1) {
|
1263
|
-
|
1272
|
+
git_error_set(GIT_ERROR_NET, "buffer too small for name of temp file");
|
1264
1273
|
return -1;
|
1265
1274
|
}
|
1266
1275
|
|
@@ -1275,7 +1284,7 @@ static int put_uuid_string(LPWSTR buffer, size_t buffer_len_cch)
|
|
1275
1284
|
uuid.Data4[4], uuid.Data4[5], uuid.Data4[6], uuid.Data4[7]);
|
1276
1285
|
|
1277
1286
|
if (result < UUID_LENGTH_CCH) {
|
1278
|
-
|
1287
|
+
git_error_set(GIT_ERROR_OS, "unable to generate name for temp file");
|
1279
1288
|
return -1;
|
1280
1289
|
}
|
1281
1290
|
|
@@ -1287,7 +1296,7 @@ static int get_temp_file(LPWSTR buffer, DWORD buffer_len_cch)
|
|
1287
1296
|
size_t len;
|
1288
1297
|
|
1289
1298
|
if (!GetTempPathW(buffer_len_cch, buffer)) {
|
1290
|
-
|
1299
|
+
git_error_set(GIT_ERROR_OS, "failed to get temp path");
|
1291
1300
|
return -1;
|
1292
1301
|
}
|
1293
1302
|
|
@@ -1330,13 +1339,13 @@ static int winhttp_stream_write_buffered(
|
|
1330
1339
|
|
1331
1340
|
if (INVALID_HANDLE_VALUE == s->post_body) {
|
1332
1341
|
s->post_body = NULL;
|
1333
|
-
|
1342
|
+
git_error_set(GIT_ERROR_OS, "failed to create temporary file");
|
1334
1343
|
return -1;
|
1335
1344
|
}
|
1336
1345
|
}
|
1337
1346
|
|
1338
1347
|
if (!WriteFile(s->post_body, buffer, (DWORD)len, &bytes_written, NULL)) {
|
1339
|
-
|
1348
|
+
git_error_set(GIT_ERROR_OS, "failed to write to temporary file");
|
1340
1349
|
return -1;
|
1341
1350
|
}
|
1342
1351
|
|
@@ -1363,7 +1372,7 @@ static int winhttp_stream_write_chunked(
|
|
1363
1372
|
if (!WinHttpAddRequestHeaders(s->request,
|
1364
1373
|
transfer_encoding, (ULONG) -1L,
|
1365
1374
|
WINHTTP_ADDREQ_FLAG_ADD)) {
|
1366
|
-
|
1375
|
+
git_error_set(GIT_ERROR_OS, "failed to add a header to the request");
|
1367
1376
|
return -1;
|
1368
1377
|
}
|
1369
1378
|
|
@@ -1390,8 +1399,10 @@ static int winhttp_stream_write_chunked(
|
|
1390
1399
|
/* Append as much to the buffer as we can */
|
1391
1400
|
int count = (int)min(CACHED_POST_BODY_BUF_SIZE - s->chunk_buffer_len, len);
|
1392
1401
|
|
1393
|
-
if (!s->chunk_buffer)
|
1402
|
+
if (!s->chunk_buffer) {
|
1394
1403
|
s->chunk_buffer = git__malloc(CACHED_POST_BODY_BUF_SIZE);
|
1404
|
+
GIT_ERROR_CHECK_ALLOC(s->chunk_buffer);
|
1405
|
+
}
|
1395
1406
|
|
1396
1407
|
memcpy(s->chunk_buffer + s->chunk_buffer_len, buffer, count);
|
1397
1408
|
s->chunk_buffer_len += count;
|
@@ -1432,7 +1443,7 @@ static int winhttp_stream_alloc(winhttp_subtransport *t, winhttp_stream **stream
|
|
1432
1443
|
return -1;
|
1433
1444
|
|
1434
1445
|
s = git__calloc(1, sizeof(winhttp_stream));
|
1435
|
-
|
1446
|
+
GIT_ERROR_CHECK_ALLOC(s);
|
1436
1447
|
|
1437
1448
|
s->parent.subtransport = &t->parent;
|
1438
1449
|
s->parent.read = winhttp_stream_read;
|
@@ -1516,7 +1527,7 @@ static int winhttp_action(
|
|
1516
1527
|
int ret = -1;
|
1517
1528
|
|
1518
1529
|
if (!t->connection)
|
1519
|
-
if ((ret =
|
1530
|
+
if ((ret = git_net_url_parse(&t->server.url, url)) < 0 ||
|
1520
1531
|
(ret = winhttp_connect(t)) < 0)
|
1521
1532
|
return ret;
|
1522
1533
|
|
@@ -1558,24 +1569,17 @@ static int winhttp_close(git_smart_subtransport *subtransport)
|
|
1558
1569
|
{
|
1559
1570
|
winhttp_subtransport *t = (winhttp_subtransport *)subtransport;
|
1560
1571
|
|
1561
|
-
|
1562
|
-
|
1563
|
-
gitno_connection_data_free_ptrs(&t->proxy_connection_data);
|
1564
|
-
memset(&t->proxy_connection_data, 0x0, sizeof(gitno_connection_data));
|
1565
|
-
|
1566
|
-
if (t->cred) {
|
1567
|
-
t->cred->free(t->cred);
|
1568
|
-
t->cred = NULL;
|
1569
|
-
}
|
1572
|
+
git_net_url_dispose(&t->server.url);
|
1573
|
+
git_net_url_dispose(&t->proxy.url);
|
1570
1574
|
|
1571
|
-
if (t->
|
1572
|
-
t->
|
1573
|
-
t->
|
1575
|
+
if (t->server.cred) {
|
1576
|
+
t->server.cred->free(t->server.cred);
|
1577
|
+
t->server.cred = NULL;
|
1574
1578
|
}
|
1575
1579
|
|
1576
|
-
if (t->
|
1577
|
-
t->
|
1578
|
-
t->
|
1580
|
+
if (t->proxy.cred) {
|
1581
|
+
t->proxy.cred->free(t->proxy.cred);
|
1582
|
+
t->proxy.cred = NULL;
|
1579
1583
|
}
|
1580
1584
|
|
1581
1585
|
return winhttp_close_connection(t);
|
@@ -1600,7 +1604,7 @@ int git_smart_subtransport_http(git_smart_subtransport **out, git_transport *own
|
|
1600
1604
|
return -1;
|
1601
1605
|
|
1602
1606
|
t = git__calloc(1, sizeof(winhttp_subtransport));
|
1603
|
-
|
1607
|
+
GIT_ERROR_CHECK_ALLOC(t);
|
1604
1608
|
|
1605
1609
|
t->owner = (transport_smart *)owner;
|
1606
1610
|
t->parent.action = winhttp_action;
|