rugged 1.7.2 → 1.9.6

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (477) hide show
  1. checksums.yaml +4 -4
  2. data/ext/rugged/extconf.rb +4 -4
  3. data/ext/rugged/rugged.c +12 -1
  4. data/ext/rugged/rugged_blame.c +22 -6
  5. data/ext/rugged/rugged_blob.c +24 -9
  6. data/ext/rugged/rugged_branch.c +10 -7
  7. data/ext/rugged/rugged_branch_collection.c +8 -6
  8. data/ext/rugged/rugged_commit.c +7 -6
  9. data/ext/rugged/rugged_config.c +20 -11
  10. data/ext/rugged/rugged_diff.c +26 -12
  11. data/ext/rugged/rugged_diff_hunk.c +2 -1
  12. data/ext/rugged/rugged_index.c +39 -29
  13. data/ext/rugged/rugged_note.c +7 -6
  14. data/ext/rugged/rugged_object.c +3 -2
  15. data/ext/rugged/rugged_patch.c +23 -9
  16. data/ext/rugged/rugged_rebase.c +22 -10
  17. data/ext/rugged/rugged_reference.c +22 -13
  18. data/ext/rugged/rugged_reference_collection.c +9 -7
  19. data/ext/rugged/rugged_remote.c +23 -12
  20. data/ext/rugged/rugged_remote_collection.c +11 -9
  21. data/ext/rugged/rugged_repo.c +60 -45
  22. data/ext/rugged/rugged_revwalk.c +22 -12
  23. data/ext/rugged/rugged_submodule.c +23 -20
  24. data/ext/rugged/rugged_submodule_collection.c +20 -9
  25. data/ext/rugged/rugged_tag.c +6 -4
  26. data/ext/rugged/rugged_tag_collection.c +7 -5
  27. data/ext/rugged/rugged_tree.c +27 -15
  28. data/lib/rugged/version.rb +1 -1
  29. data/vendor/libgit2/AUTHORS +3 -0
  30. data/vendor/libgit2/CMakeLists.txt +23 -10
  31. data/vendor/libgit2/COPYING +278 -12
  32. data/vendor/libgit2/cmake/DefaultCFlags.cmake +8 -3
  33. data/vendor/libgit2/cmake/{FindIconv.cmake → FindIntlIconv.cmake} +6 -0
  34. data/vendor/libgit2/cmake/FindLLHTTP.cmake +39 -0
  35. data/vendor/libgit2/cmake/SelectGSSAPI.cmake +1 -1
  36. data/vendor/libgit2/cmake/SelectHTTPParser.cmake +23 -8
  37. data/vendor/libgit2/cmake/SelectHTTPSBackend.cmake +17 -8
  38. data/vendor/libgit2/cmake/SelectHashes.cmake +28 -11
  39. data/vendor/libgit2/cmake/SelectRegex.cmake +14 -4
  40. data/vendor/libgit2/cmake/SelectSSH.cmake +30 -19
  41. data/vendor/libgit2/cmake/SelectZlib.cmake +4 -0
  42. data/vendor/libgit2/deps/llhttp/CMakeLists.txt +8 -0
  43. data/vendor/libgit2/deps/llhttp/LICENSE-MIT +22 -0
  44. data/vendor/libgit2/deps/llhttp/api.c +510 -0
  45. data/vendor/libgit2/deps/llhttp/http.c +170 -0
  46. data/vendor/libgit2/deps/llhttp/llhttp.c +10168 -0
  47. data/vendor/libgit2/deps/llhttp/llhttp.h +897 -0
  48. data/vendor/libgit2/deps/ntlmclient/CMakeLists.txt +1 -1
  49. data/vendor/libgit2/deps/ntlmclient/crypt_builtin_md4.c +311 -0
  50. data/vendor/libgit2/deps/ntlmclient/crypt_commoncrypto.c +2 -1
  51. data/vendor/libgit2/deps/ntlmclient/crypt_mbedtls.c +0 -20
  52. data/vendor/libgit2/deps/ntlmclient/crypt_openssl.c +4 -4
  53. data/vendor/libgit2/deps/ntlmclient/ntlm.c +21 -21
  54. data/vendor/libgit2/deps/ntlmclient/unicode_builtin.c +5 -4
  55. data/vendor/libgit2/deps/ntlmclient/unicode_iconv.c +2 -1
  56. data/vendor/libgit2/deps/ntlmclient/utf8.h +1176 -721
  57. data/vendor/libgit2/deps/ntlmclient/util.h +11 -0
  58. data/vendor/libgit2/deps/pcre2/CMakeLists.txt +110 -0
  59. data/vendor/libgit2/deps/pcre2/LICENCE.md +104 -0
  60. data/vendor/libgit2/deps/pcre2/config.h.in +54 -0
  61. data/vendor/libgit2/deps/pcre2/pcre2.h +1079 -0
  62. data/vendor/libgit2/deps/pcre2/pcre2_auto_possess.c +1416 -0
  63. data/vendor/libgit2/deps/{pcre/pcre_chartables.c → pcre2/pcre2_chartables.c} +41 -47
  64. data/vendor/libgit2/deps/{pcre/pcre_ord2utf8.c → pcre2/pcre2_chkdint.c} +36 -36
  65. data/vendor/libgit2/deps/pcre2/pcre2_compile.c +11345 -0
  66. data/vendor/libgit2/deps/pcre2/pcre2_compile.h +356 -0
  67. data/vendor/libgit2/deps/pcre2/pcre2_compile_cgroup.c +632 -0
  68. data/vendor/libgit2/deps/pcre2/pcre2_compile_class.c +2777 -0
  69. data/vendor/libgit2/deps/pcre2/pcre2_config.c +250 -0
  70. data/vendor/libgit2/deps/pcre2/pcre2_context.c +557 -0
  71. data/vendor/libgit2/deps/pcre2/pcre2_convert.c +1263 -0
  72. data/vendor/libgit2/deps/{pcre/pcre_dfa_exec.c → pcre2/pcre2_dfa_match.c} +1402 -943
  73. data/vendor/libgit2/deps/pcre2/pcre2_error.c +384 -0
  74. data/vendor/libgit2/deps/pcre2/pcre2_extuni.c +159 -0
  75. data/vendor/libgit2/deps/pcre2/pcre2_find_bracket.c +217 -0
  76. data/vendor/libgit2/deps/pcre2/pcre2_fuzzsupport.c +844 -0
  77. data/vendor/libgit2/deps/pcre2/pcre2_internal.h +2353 -0
  78. data/vendor/libgit2/deps/pcre2/pcre2_intmodedep.h +1044 -0
  79. data/vendor/libgit2/deps/pcre2/pcre2_maketables.c +177 -0
  80. data/vendor/libgit2/deps/pcre2/pcre2_match.c +8244 -0
  81. data/vendor/libgit2/deps/pcre2/pcre2_match_data.c +184 -0
  82. data/vendor/libgit2/deps/pcre2/pcre2_match_next.c +171 -0
  83. data/vendor/libgit2/deps/{pcre/pcre_newline.c → pcre2/pcre2_newline.c} +92 -63
  84. data/vendor/libgit2/deps/{pcre/pcre_refcount.c → pcre2/pcre2_ord2utf.c} +64 -38
  85. data/vendor/libgit2/deps/pcre2/pcre2_pattern_info.c +430 -0
  86. data/vendor/libgit2/deps/pcre2/pcre2_printint_inc.h +1098 -0
  87. data/vendor/libgit2/deps/pcre2/pcre2_script_run.c +344 -0
  88. data/vendor/libgit2/deps/pcre2/pcre2_serialize.c +284 -0
  89. data/vendor/libgit2/deps/pcre2/pcre2_string_utils.c +199 -0
  90. data/vendor/libgit2/deps/pcre2/pcre2_study.c +2087 -0
  91. data/vendor/libgit2/deps/pcre2/pcre2_substitute.c +1761 -0
  92. data/vendor/libgit2/deps/pcre2/pcre2_substring.c +553 -0
  93. data/vendor/libgit2/deps/pcre2/pcre2_tables.c +310 -0
  94. data/vendor/libgit2/deps/pcre2/pcre2_ucd.c +5805 -0
  95. data/vendor/libgit2/deps/pcre2/pcre2_ucp.h +408 -0
  96. data/vendor/libgit2/deps/pcre2/pcre2_ucptables_inc.h +1596 -0
  97. data/vendor/libgit2/deps/pcre2/pcre2_util.h +179 -0
  98. data/vendor/libgit2/deps/pcre2/pcre2_valid_utf.c +397 -0
  99. data/vendor/libgit2/deps/pcre2/pcre2_xclass.c +547 -0
  100. data/vendor/libgit2/deps/xdiff/CMakeLists.txt +1 -1
  101. data/vendor/libgit2/deps/xdiff/xmerge.c +16 -12
  102. data/vendor/libgit2/deps/zlib/CMakeLists.txt +6 -1
  103. data/vendor/libgit2/deps/zlib/LICENSE +22 -0
  104. data/vendor/libgit2/deps/zlib/adler32.c +5 -27
  105. data/vendor/libgit2/deps/zlib/crc32.c +94 -167
  106. data/vendor/libgit2/deps/zlib/deflate.c +358 -435
  107. data/vendor/libgit2/deps/zlib/deflate.h +41 -10
  108. data/vendor/libgit2/deps/zlib/gzguts.h +13 -18
  109. data/vendor/libgit2/deps/zlib/infback.c +17 -30
  110. data/vendor/libgit2/deps/zlib/inffast.c +1 -4
  111. data/vendor/libgit2/deps/zlib/inffast.h +1 -1
  112. data/vendor/libgit2/deps/zlib/inflate.c +36 -102
  113. data/vendor/libgit2/deps/zlib/inftrees.c +6 -11
  114. data/vendor/libgit2/deps/zlib/inftrees.h +6 -6
  115. data/vendor/libgit2/deps/zlib/trees.c +287 -352
  116. data/vendor/libgit2/deps/zlib/zconf.h +23 -14
  117. data/vendor/libgit2/deps/zlib/zlib.h +202 -202
  118. data/vendor/libgit2/deps/zlib/zutil.c +18 -44
  119. data/vendor/libgit2/deps/zlib/zutil.h +13 -33
  120. data/vendor/libgit2/include/git2/annotated_commit.h +12 -5
  121. data/vendor/libgit2/include/git2/apply.h +27 -6
  122. data/vendor/libgit2/include/git2/attr.h +17 -4
  123. data/vendor/libgit2/include/git2/blame.h +133 -28
  124. data/vendor/libgit2/include/git2/blob.h +71 -28
  125. data/vendor/libgit2/include/git2/branch.h +22 -15
  126. data/vendor/libgit2/include/git2/buffer.h +6 -4
  127. data/vendor/libgit2/include/git2/cert.h +2 -1
  128. data/vendor/libgit2/include/git2/checkout.h +83 -32
  129. data/vendor/libgit2/include/git2/cherrypick.h +10 -3
  130. data/vendor/libgit2/include/git2/clone.h +25 -9
  131. data/vendor/libgit2/include/git2/commit.h +132 -3
  132. data/vendor/libgit2/include/git2/common.h +132 -63
  133. data/vendor/libgit2/include/git2/config.h +93 -23
  134. data/vendor/libgit2/include/git2/credential.h +30 -2
  135. data/vendor/libgit2/include/git2/credential_helpers.h +1 -0
  136. data/vendor/libgit2/include/git2/deprecated.h +134 -4
  137. data/vendor/libgit2/include/git2/describe.h +13 -1
  138. data/vendor/libgit2/include/git2/diff.h +38 -8
  139. data/vendor/libgit2/include/git2/email.h +9 -29
  140. data/vendor/libgit2/include/git2/errors.h +46 -73
  141. data/vendor/libgit2/include/git2/filter.h +14 -7
  142. data/vendor/libgit2/include/git2/global.h +8 -1
  143. data/vendor/libgit2/include/git2/graph.h +3 -2
  144. data/vendor/libgit2/include/git2/ignore.h +10 -0
  145. data/vendor/libgit2/include/git2/index.h +100 -15
  146. data/vendor/libgit2/include/git2/indexer.h +21 -4
  147. data/vendor/libgit2/include/git2/mailmap.h +7 -1
  148. data/vendor/libgit2/include/git2/merge.h +50 -3
  149. data/vendor/libgit2/include/git2/message.h +2 -2
  150. data/vendor/libgit2/include/git2/net.h +3 -1
  151. data/vendor/libgit2/include/git2/notes.h +9 -6
  152. data/vendor/libgit2/include/git2/object.h +9 -8
  153. data/vendor/libgit2/include/git2/odb.h +91 -49
  154. data/vendor/libgit2/include/git2/odb_backend.h +80 -52
  155. data/vendor/libgit2/include/git2/oid.h +23 -25
  156. data/vendor/libgit2/include/git2/oidarray.h +7 -1
  157. data/vendor/libgit2/include/git2/pack.h +13 -1
  158. data/vendor/libgit2/include/git2/patch.h +2 -3
  159. data/vendor/libgit2/include/git2/pathspec.h +9 -0
  160. data/vendor/libgit2/include/git2/proxy.h +12 -3
  161. data/vendor/libgit2/include/git2/rebase.h +9 -6
  162. data/vendor/libgit2/include/git2/refdb.h +2 -2
  163. data/vendor/libgit2/include/git2/reflog.h +3 -2
  164. data/vendor/libgit2/include/git2/refs.h +9 -6
  165. data/vendor/libgit2/include/git2/refspec.h +14 -4
  166. data/vendor/libgit2/include/git2/remote.h +113 -25
  167. data/vendor/libgit2/include/git2/repository.h +57 -21
  168. data/vendor/libgit2/include/git2/reset.h +16 -3
  169. data/vendor/libgit2/include/git2/revert.h +9 -4
  170. data/vendor/libgit2/include/git2/revparse.h +3 -3
  171. data/vendor/libgit2/include/git2/revwalk.h +3 -2
  172. data/vendor/libgit2/include/git2/signature.h +46 -1
  173. data/vendor/libgit2/include/git2/stash.h +17 -3
  174. data/vendor/libgit2/include/git2/status.h +10 -6
  175. data/vendor/libgit2/include/git2/stdint.h +87 -85
  176. data/vendor/libgit2/include/git2/strarray.h +2 -3
  177. data/vendor/libgit2/include/git2/submodule.h +20 -9
  178. data/vendor/libgit2/include/git2/sys/alloc.h +12 -0
  179. data/vendor/libgit2/include/git2/sys/commit.h +77 -3
  180. data/vendor/libgit2/include/git2/sys/commit_graph.h +103 -62
  181. data/vendor/libgit2/include/git2/sys/config.h +80 -4
  182. data/vendor/libgit2/include/git2/sys/credential.h +4 -3
  183. data/vendor/libgit2/include/git2/sys/diff.h +21 -1
  184. data/vendor/libgit2/include/git2/sys/email.h +7 -0
  185. data/vendor/libgit2/include/git2/sys/errors.h +76 -0
  186. data/vendor/libgit2/include/git2/sys/filter.h +66 -3
  187. data/vendor/libgit2/include/git2/sys/hashsig.h +11 -0
  188. data/vendor/libgit2/include/git2/sys/index.h +3 -2
  189. data/vendor/libgit2/include/git2/sys/mempack.h +32 -2
  190. data/vendor/libgit2/include/git2/sys/merge.h +55 -7
  191. data/vendor/libgit2/include/git2/sys/midx.h +43 -4
  192. data/vendor/libgit2/include/git2/sys/odb_backend.h +7 -3
  193. data/vendor/libgit2/include/git2/sys/openssl.h +8 -1
  194. data/vendor/libgit2/include/git2/sys/path.h +12 -1
  195. data/vendor/libgit2/include/git2/sys/refdb_backend.h +40 -36
  196. data/vendor/libgit2/include/git2/sys/refs.h +3 -2
  197. data/vendor/libgit2/include/git2/sys/remote.h +8 -1
  198. data/vendor/libgit2/include/git2/sys/repository.h +63 -3
  199. data/vendor/libgit2/include/git2/sys/stream.h +11 -2
  200. data/vendor/libgit2/include/git2/sys/transport.h +25 -4
  201. data/vendor/libgit2/include/git2/tag.h +3 -1
  202. data/vendor/libgit2/include/git2/trace.h +9 -3
  203. data/vendor/libgit2/include/git2/transaction.h +3 -2
  204. data/vendor/libgit2/include/git2/transport.h +11 -3
  205. data/vendor/libgit2/include/git2/tree.h +16 -5
  206. data/vendor/libgit2/include/git2/types.h +19 -3
  207. data/vendor/libgit2/include/git2/version.h +46 -8
  208. data/vendor/libgit2/include/git2/worktree.h +16 -6
  209. data/vendor/libgit2/src/CMakeLists.txt +6 -4
  210. data/vendor/libgit2/src/cli/CMakeLists.txt +3 -4
  211. data/vendor/libgit2/src/cli/cmd.c +1 -1
  212. data/vendor/libgit2/src/cli/cmd.h +4 -0
  213. data/vendor/libgit2/src/cli/cmd_blame.c +287 -0
  214. data/vendor/libgit2/src/cli/cmd_cat_file.c +6 -8
  215. data/vendor/libgit2/src/cli/cmd_clone.c +5 -7
  216. data/vendor/libgit2/src/cli/cmd_config.c +241 -0
  217. data/vendor/libgit2/src/cli/cmd_hash_object.c +6 -8
  218. data/vendor/libgit2/src/cli/cmd_help.c +6 -7
  219. data/vendor/libgit2/src/cli/cmd_index_pack.c +114 -0
  220. data/vendor/libgit2/src/cli/cmd_init.c +102 -0
  221. data/vendor/libgit2/src/cli/common.c +168 -0
  222. data/vendor/libgit2/src/cli/common.h +63 -0
  223. data/vendor/libgit2/src/cli/error.h +1 -1
  224. data/vendor/libgit2/src/cli/main.c +52 -24
  225. data/vendor/libgit2/src/cli/opt.c +31 -5
  226. data/vendor/libgit2/src/cli/opt.h +21 -3
  227. data/vendor/libgit2/src/cli/opt_usage.c +102 -33
  228. data/vendor/libgit2/src/cli/opt_usage.h +6 -1
  229. data/vendor/libgit2/src/cli/progress.c +51 -2
  230. data/vendor/libgit2/src/cli/progress.h +12 -0
  231. data/vendor/libgit2/src/cli/unix/sighandler.c +2 -1
  232. data/vendor/libgit2/src/cli/win32/precompiled.h +1 -1
  233. data/vendor/libgit2/src/cli/win32/sighandler.c +1 -1
  234. data/vendor/libgit2/src/libgit2/CMakeLists.txt +55 -21
  235. data/vendor/libgit2/src/libgit2/apply.c +10 -13
  236. data/vendor/libgit2/src/libgit2/attr.c +30 -13
  237. data/vendor/libgit2/src/libgit2/attr_file.c +17 -5
  238. data/vendor/libgit2/src/libgit2/attr_file.h +2 -0
  239. data/vendor/libgit2/src/libgit2/attrcache.c +69 -33
  240. data/vendor/libgit2/src/libgit2/attrcache.h +5 -9
  241. data/vendor/libgit2/src/libgit2/blame.c +135 -43
  242. data/vendor/libgit2/src/libgit2/blame.h +1 -0
  243. data/vendor/libgit2/src/libgit2/cache.c +22 -17
  244. data/vendor/libgit2/src/libgit2/cache.h +7 -9
  245. data/vendor/libgit2/src/libgit2/checkout.c +34 -24
  246. data/vendor/libgit2/src/libgit2/checkout.h +0 -2
  247. data/vendor/libgit2/src/libgit2/cherrypick.c +1 -2
  248. data/vendor/libgit2/src/libgit2/clone.c +192 -166
  249. data/vendor/libgit2/src/libgit2/clone.h +4 -1
  250. data/vendor/libgit2/src/libgit2/commit.c +93 -1
  251. data/vendor/libgit2/src/libgit2/commit_graph.c +68 -58
  252. data/vendor/libgit2/src/libgit2/commit_graph.h +1 -2
  253. data/vendor/libgit2/src/libgit2/config.c +390 -299
  254. data/vendor/libgit2/src/libgit2/config.cmake.in +3 -0
  255. data/vendor/libgit2/src/libgit2/config.h +9 -4
  256. data/vendor/libgit2/src/libgit2/config_backend.h +8 -10
  257. data/vendor/libgit2/src/libgit2/config_cache.c +4 -5
  258. data/vendor/libgit2/src/libgit2/config_file.c +101 -89
  259. data/vendor/libgit2/src/libgit2/config_list.c +285 -0
  260. data/vendor/libgit2/src/libgit2/config_list.h +32 -0
  261. data/vendor/libgit2/src/libgit2/config_mem.c +195 -40
  262. data/vendor/libgit2/src/libgit2/config_parse.c +12 -10
  263. data/vendor/libgit2/src/libgit2/config_snapshot.c +24 -31
  264. data/vendor/libgit2/src/libgit2/delta.c +13 -1
  265. data/vendor/libgit2/src/libgit2/describe.c +24 -24
  266. data/vendor/libgit2/src/libgit2/diff.c +1 -1
  267. data/vendor/libgit2/src/libgit2/diff_driver.c +13 -20
  268. data/vendor/libgit2/src/libgit2/diff_driver.h +2 -2
  269. data/vendor/libgit2/src/libgit2/diff_generate.c +3 -3
  270. data/vendor/libgit2/src/libgit2/diff_parse.c +2 -2
  271. data/vendor/libgit2/src/libgit2/diff_print.c +65 -9
  272. data/vendor/libgit2/src/libgit2/diff_stats.c +19 -12
  273. data/vendor/libgit2/src/libgit2/diff_tform.c +36 -8
  274. data/vendor/libgit2/src/libgit2/email.c +1 -0
  275. data/vendor/libgit2/src/libgit2/fetch.c +5 -3
  276. data/vendor/libgit2/src/libgit2/fetchhead.c +1 -1
  277. data/vendor/libgit2/src/libgit2/filter.c +5 -5
  278. data/vendor/libgit2/src/libgit2/git2.rc +3 -3
  279. data/vendor/libgit2/src/libgit2/grafts.c +18 -20
  280. data/vendor/libgit2/src/libgit2/grafts.h +0 -1
  281. data/vendor/libgit2/src/libgit2/graph.c +1 -1
  282. data/vendor/libgit2/src/libgit2/hashmap_oid.h +30 -0
  283. data/vendor/libgit2/src/libgit2/ignore.c +9 -5
  284. data/vendor/libgit2/src/libgit2/index.c +76 -98
  285. data/vendor/libgit2/src/libgit2/index.h +5 -2
  286. data/vendor/libgit2/src/libgit2/index_map.c +95 -0
  287. data/vendor/libgit2/src/libgit2/index_map.h +28 -0
  288. data/vendor/libgit2/src/libgit2/indexer.c +38 -41
  289. data/vendor/libgit2/src/libgit2/iterator.c +14 -8
  290. data/vendor/libgit2/src/libgit2/libgit2.c +153 -368
  291. data/vendor/libgit2/src/libgit2/mailmap.c +1 -1
  292. data/vendor/libgit2/src/libgit2/merge.c +43 -38
  293. data/vendor/libgit2/src/libgit2/merge.h +4 -0
  294. data/vendor/libgit2/src/libgit2/merge_driver.c +2 -2
  295. data/vendor/libgit2/src/libgit2/merge_file.c +43 -30
  296. data/vendor/libgit2/src/libgit2/message.c +1 -1
  297. data/vendor/libgit2/src/libgit2/midx.c +30 -18
  298. data/vendor/libgit2/src/libgit2/mwindow.c +38 -45
  299. data/vendor/libgit2/src/libgit2/mwindow.h +4 -0
  300. data/vendor/libgit2/src/libgit2/object.c +6 -5
  301. data/vendor/libgit2/src/libgit2/odb.c +7 -10
  302. data/vendor/libgit2/src/libgit2/odb_loose.c +24 -14
  303. data/vendor/libgit2/src/libgit2/odb_mempack.c +49 -17
  304. data/vendor/libgit2/src/libgit2/odb_pack.c +13 -5
  305. data/vendor/libgit2/src/libgit2/oid.c +36 -10
  306. data/vendor/libgit2/src/libgit2/oid.h +11 -0
  307. data/vendor/libgit2/src/libgit2/pack-objects.c +59 -34
  308. data/vendor/libgit2/src/libgit2/pack-objects.h +12 -4
  309. data/vendor/libgit2/src/libgit2/pack.c +33 -24
  310. data/vendor/libgit2/src/libgit2/pack.h +15 -10
  311. data/vendor/libgit2/src/libgit2/patch_parse.c +2 -2
  312. data/vendor/libgit2/src/libgit2/path.c +1 -1
  313. data/vendor/libgit2/src/libgit2/pathspec.c +1 -1
  314. data/vendor/libgit2/src/libgit2/push.c +79 -28
  315. data/vendor/libgit2/src/libgit2/push.h +1 -0
  316. data/vendor/libgit2/src/libgit2/refdb_fs.c +128 -61
  317. data/vendor/libgit2/src/libgit2/reflog.c +1 -2
  318. data/vendor/libgit2/src/libgit2/reflog.h +2 -0
  319. data/vendor/libgit2/src/libgit2/refs.c +41 -13
  320. data/vendor/libgit2/src/libgit2/refs.h +6 -1
  321. data/vendor/libgit2/src/libgit2/refspec.c +28 -1
  322. data/vendor/libgit2/src/libgit2/refspec.h +8 -0
  323. data/vendor/libgit2/src/libgit2/remote.c +125 -62
  324. data/vendor/libgit2/src/libgit2/remote.h +0 -1
  325. data/vendor/libgit2/src/libgit2/repository.c +235 -54
  326. data/vendor/libgit2/src/libgit2/repository.h +10 -6
  327. data/vendor/libgit2/src/libgit2/revert.c +1 -2
  328. data/vendor/libgit2/src/libgit2/revparse.c +2 -2
  329. data/vendor/libgit2/src/libgit2/revwalk.c +13 -10
  330. data/vendor/libgit2/src/libgit2/revwalk.h +3 -3
  331. data/vendor/libgit2/src/libgit2/settings.c +477 -0
  332. data/vendor/libgit2/src/libgit2/settings.h +6 -2
  333. data/vendor/libgit2/src/libgit2/signature.c +132 -15
  334. data/vendor/libgit2/src/libgit2/signature.h +0 -1
  335. data/vendor/libgit2/src/libgit2/status.c +1 -1
  336. data/vendor/libgit2/src/libgit2/streams/mbedtls.c +54 -60
  337. data/vendor/libgit2/src/libgit2/streams/openssl.c +36 -8
  338. data/vendor/libgit2/src/libgit2/streams/openssl.h +2 -0
  339. data/vendor/libgit2/src/libgit2/streams/openssl_dynamic.c +4 -0
  340. data/vendor/libgit2/src/libgit2/streams/openssl_dynamic.h +3 -0
  341. data/vendor/libgit2/src/libgit2/streams/socket.c +30 -0
  342. data/vendor/libgit2/src/libgit2/streams/stransport.c +39 -7
  343. data/vendor/libgit2/src/libgit2/submodule.c +195 -80
  344. data/vendor/libgit2/src/libgit2/submodule.h +6 -7
  345. data/vendor/libgit2/src/libgit2/tag.c +4 -2
  346. data/vendor/libgit2/src/libgit2/trailer.c +6 -6
  347. data/vendor/libgit2/src/libgit2/transaction.c +26 -20
  348. data/vendor/libgit2/src/libgit2/transaction.h +4 -1
  349. data/vendor/libgit2/src/libgit2/transport.c +4 -1
  350. data/vendor/libgit2/src/libgit2/transports/auth_sspi.c +2 -0
  351. data/vendor/libgit2/src/libgit2/transports/credential.c +2 -2
  352. data/vendor/libgit2/src/libgit2/transports/git.c +1 -1
  353. data/vendor/libgit2/src/libgit2/transports/http.c +5 -6
  354. data/vendor/libgit2/src/libgit2/transports/http.h +0 -10
  355. data/vendor/libgit2/src/libgit2/transports/httpclient.c +124 -81
  356. data/vendor/libgit2/src/libgit2/transports/httpparser.c +128 -0
  357. data/vendor/libgit2/src/libgit2/transports/httpparser.h +99 -0
  358. data/vendor/libgit2/src/libgit2/transports/local.c +16 -8
  359. data/vendor/libgit2/src/libgit2/transports/smart.c +25 -13
  360. data/vendor/libgit2/src/libgit2/transports/smart.h +4 -2
  361. data/vendor/libgit2/src/libgit2/transports/smart_pkt.c +7 -6
  362. data/vendor/libgit2/src/libgit2/transports/smart_protocol.c +55 -10
  363. data/vendor/libgit2/src/libgit2/transports/ssh.c +41 -1103
  364. data/vendor/libgit2/src/libgit2/transports/ssh_exec.c +386 -0
  365. data/vendor/libgit2/src/libgit2/transports/ssh_exec.h +26 -0
  366. data/vendor/libgit2/src/libgit2/transports/ssh_libssh2.c +1132 -0
  367. data/vendor/libgit2/src/libgit2/transports/ssh_libssh2.h +28 -0
  368. data/vendor/libgit2/src/libgit2/transports/winhttp.c +35 -7
  369. data/vendor/libgit2/src/libgit2/tree.c +34 -26
  370. data/vendor/libgit2/src/libgit2/tree.h +3 -2
  371. data/vendor/libgit2/src/libgit2/worktree.c +14 -17
  372. data/vendor/libgit2/src/util/CMakeLists.txt +7 -10
  373. data/vendor/libgit2/src/util/alloc.c +4 -1
  374. data/vendor/libgit2/src/util/allocators/debugalloc.c +73 -0
  375. data/vendor/libgit2/src/{cli/cli.h → util/allocators/debugalloc.h} +6 -9
  376. data/vendor/libgit2/src/util/allocators/stdalloc.c +0 -10
  377. data/vendor/libgit2/src/util/array.h +18 -17
  378. data/vendor/libgit2/src/util/cc-compat.h +2 -0
  379. data/vendor/libgit2/src/util/ctype_compat.h +70 -0
  380. data/vendor/libgit2/src/util/date.c +22 -14
  381. data/vendor/libgit2/src/util/date.h +12 -0
  382. data/vendor/libgit2/src/util/errors.c +401 -0
  383. data/vendor/libgit2/src/{libgit2 → util}/errors.h +21 -17
  384. data/vendor/libgit2/src/util/fs_path.c +81 -10
  385. data/vendor/libgit2/src/util/fs_path.h +39 -10
  386. data/vendor/libgit2/src/util/futils.c +6 -5
  387. data/vendor/libgit2/src/util/futils.h +24 -7
  388. data/vendor/libgit2/src/util/git2_features.h.in +12 -1
  389. data/vendor/libgit2/src/util/git2_util.h +6 -0
  390. data/vendor/libgit2/src/util/hash/builtin.c +14 -4
  391. data/vendor/libgit2/src/util/hash/openssl.c +148 -0
  392. data/vendor/libgit2/src/util/hash/openssl.h +17 -1
  393. data/vendor/libgit2/src/util/hash/rfc6234/sha224-256.c +8 -6
  394. data/vendor/libgit2/src/util/hash/sha.h +4 -1
  395. data/vendor/libgit2/src/util/hashmap.h +425 -0
  396. data/vendor/libgit2/src/util/hashmap_str.h +43 -0
  397. data/vendor/libgit2/src/util/integer.h +3 -1
  398. data/vendor/libgit2/src/util/net.c +17 -11
  399. data/vendor/libgit2/src/util/net.h +2 -0
  400. data/vendor/libgit2/src/util/pool.c +1 -1
  401. data/vendor/libgit2/src/util/pool.h +5 -0
  402. data/vendor/libgit2/src/util/pqueue.h +1 -1
  403. data/vendor/libgit2/src/util/process.h +223 -0
  404. data/vendor/libgit2/src/util/rand.c +1 -7
  405. data/vendor/libgit2/src/util/regexp.c +28 -13
  406. data/vendor/libgit2/src/util/regexp.h +7 -2
  407. data/vendor/libgit2/src/util/runtime.c +2 -2
  408. data/vendor/libgit2/src/util/sortedcache.c +14 -13
  409. data/vendor/libgit2/src/util/sortedcache.h +3 -3
  410. data/vendor/libgit2/src/util/str.c +20 -8
  411. data/vendor/libgit2/src/util/str.h +5 -3
  412. data/vendor/libgit2/src/util/strlist.c +108 -0
  413. data/vendor/libgit2/src/util/strlist.h +36 -0
  414. data/vendor/libgit2/src/util/unix/posix.h +0 -2
  415. data/vendor/libgit2/src/util/unix/process.c +706 -0
  416. data/vendor/libgit2/src/util/unix/realpath.c +23 -5
  417. data/vendor/libgit2/src/util/util.c +18 -5
  418. data/vendor/libgit2/src/util/util.h +5 -38
  419. data/vendor/libgit2/src/util/vector.c +3 -3
  420. data/vendor/libgit2/src/util/vector.h +2 -2
  421. data/vendor/libgit2/src/util/win32/path_w32.c +81 -5
  422. data/vendor/libgit2/src/util/win32/posix_w32.c +29 -6
  423. data/vendor/libgit2/src/util/win32/process.c +522 -0
  424. metadata +102 -67
  425. data/vendor/libgit2/deps/http-parser/CMakeLists.txt +0 -6
  426. data/vendor/libgit2/deps/http-parser/COPYING +0 -23
  427. data/vendor/libgit2/deps/http-parser/http_parser.c +0 -2182
  428. data/vendor/libgit2/deps/http-parser/http_parser.h +0 -305
  429. data/vendor/libgit2/deps/pcre/CMakeLists.txt +0 -140
  430. data/vendor/libgit2/deps/pcre/COPYING +0 -5
  431. data/vendor/libgit2/deps/pcre/LICENCE +0 -93
  432. data/vendor/libgit2/deps/pcre/cmake/COPYING-CMAKE-SCRIPTS +0 -22
  433. data/vendor/libgit2/deps/pcre/cmake/FindEditline.cmake +0 -17
  434. data/vendor/libgit2/deps/pcre/cmake/FindPackageHandleStandardArgs.cmake +0 -58
  435. data/vendor/libgit2/deps/pcre/cmake/FindReadline.cmake +0 -29
  436. data/vendor/libgit2/deps/pcre/config.h.in +0 -57
  437. data/vendor/libgit2/deps/pcre/pcre.h +0 -641
  438. data/vendor/libgit2/deps/pcre/pcre_byte_order.c +0 -319
  439. data/vendor/libgit2/deps/pcre/pcre_compile.c +0 -9815
  440. data/vendor/libgit2/deps/pcre/pcre_config.c +0 -190
  441. data/vendor/libgit2/deps/pcre/pcre_exec.c +0 -7173
  442. data/vendor/libgit2/deps/pcre/pcre_fullinfo.c +0 -245
  443. data/vendor/libgit2/deps/pcre/pcre_get.c +0 -669
  444. data/vendor/libgit2/deps/pcre/pcre_globals.c +0 -86
  445. data/vendor/libgit2/deps/pcre/pcre_internal.h +0 -2787
  446. data/vendor/libgit2/deps/pcre/pcre_jit_compile.c +0 -11913
  447. data/vendor/libgit2/deps/pcre/pcre_maketables.c +0 -156
  448. data/vendor/libgit2/deps/pcre/pcre_printint.c +0 -834
  449. data/vendor/libgit2/deps/pcre/pcre_string_utils.c +0 -211
  450. data/vendor/libgit2/deps/pcre/pcre_study.c +0 -1686
  451. data/vendor/libgit2/deps/pcre/pcre_tables.c +0 -727
  452. data/vendor/libgit2/deps/pcre/pcre_ucd.c +0 -3644
  453. data/vendor/libgit2/deps/pcre/pcre_valid_utf8.c +0 -301
  454. data/vendor/libgit2/deps/pcre/pcre_version.c +0 -98
  455. data/vendor/libgit2/deps/pcre/pcre_xclass.c +0 -268
  456. data/vendor/libgit2/deps/pcre/pcreposix.c +0 -420
  457. data/vendor/libgit2/deps/pcre/pcreposix.h +0 -117
  458. data/vendor/libgit2/deps/pcre/ucp.h +0 -224
  459. data/vendor/libgit2/deps/zlib/COPYING +0 -27
  460. data/vendor/libgit2/include/git2/sys/reflog.h +0 -21
  461. data/vendor/libgit2/src/libgit2/config_entries.c +0 -237
  462. data/vendor/libgit2/src/libgit2/config_entries.h +0 -24
  463. data/vendor/libgit2/src/libgit2/errors.c +0 -293
  464. data/vendor/libgit2/src/libgit2/idxmap.c +0 -157
  465. data/vendor/libgit2/src/libgit2/idxmap.h +0 -177
  466. data/vendor/libgit2/src/libgit2/libgit2.h +0 -15
  467. data/vendor/libgit2/src/libgit2/offmap.c +0 -101
  468. data/vendor/libgit2/src/libgit2/offmap.h +0 -133
  469. data/vendor/libgit2/src/libgit2/oidmap.c +0 -107
  470. data/vendor/libgit2/src/libgit2/oidmap.h +0 -128
  471. data/vendor/libgit2/src/libgit2/threadstate.c +0 -97
  472. data/vendor/libgit2/src/libgit2/threadstate.h +0 -22
  473. data/vendor/libgit2/src/libgit2/transports/ssh.h +0 -14
  474. data/vendor/libgit2/src/util/khash.h +0 -615
  475. data/vendor/libgit2/src/util/strmap.c +0 -100
  476. data/vendor/libgit2/src/util/strmap.h +0 -131
  477. /data/vendor/libgit2/cmake/{FindHTTPParser.cmake → FindHTTP_Parser.cmake} +0 -0
@@ -0,0 +1,1132 @@
1
+ /*
2
+ * Copyright (C) the libgit2 contributors. All rights reserved.
3
+ *
4
+ * This file is part of libgit2, distributed under the GNU GPL v2 with
5
+ * a Linking Exception. For full terms see the included COPYING file.
6
+ */
7
+
8
+ #include "ssh_libssh2.h"
9
+
10
+ #ifdef GIT_SSH_LIBSSH2
11
+
12
+ #include <libssh2.h>
13
+
14
+ #include "runtime.h"
15
+ #include "net.h"
16
+ #include "smart.h"
17
+ #include "process.h"
18
+ #include "streams/socket.h"
19
+ #include "sysdir.h"
20
+
21
+ #include "git2/credential.h"
22
+ #include "git2/sys/credential.h"
23
+
24
+ #define OWNING_SUBTRANSPORT(s) ((ssh_subtransport *)(s)->parent.subtransport)
25
+
26
+ extern int git_socket_stream__timeout;
27
+
28
+ static const char cmd_uploadpack[] = "git-upload-pack";
29
+ static const char cmd_receivepack[] = "git-receive-pack";
30
+
31
+ typedef struct {
32
+ git_smart_subtransport_stream parent;
33
+ git_stream *io;
34
+ LIBSSH2_SESSION *session;
35
+ LIBSSH2_CHANNEL *channel;
36
+ const char *cmd;
37
+ git_net_url url;
38
+ unsigned sent_command : 1;
39
+ } ssh_stream;
40
+
41
+ typedef struct {
42
+ git_smart_subtransport parent;
43
+ transport_smart *owner;
44
+ ssh_stream *current_stream;
45
+ git_credential *cred;
46
+ char *cmd_uploadpack;
47
+ char *cmd_receivepack;
48
+ } ssh_subtransport;
49
+
50
+ static int list_auth_methods(int *out, LIBSSH2_SESSION *session, const char *username);
51
+
52
+ static void ssh_error(LIBSSH2_SESSION *session, const char *errmsg)
53
+ {
54
+ char *ssherr;
55
+ libssh2_session_last_error(session, &ssherr, NULL, 0);
56
+
57
+ git_error_set(GIT_ERROR_SSH, "%s: %s", errmsg, ssherr);
58
+ }
59
+
60
+ /*
61
+ * Create a git protocol request.
62
+ *
63
+ * For example: git-upload-pack '/libgit2/libgit2'
64
+ */
65
+ static int gen_proto(git_str *request, const char *cmd, git_net_url *url)
66
+ {
67
+ const char *repo;
68
+
69
+ repo = url->path;
70
+
71
+ if (repo && repo[0] == '/' && repo[1] == '~')
72
+ repo++;
73
+
74
+ if (!repo || !repo[0]) {
75
+ git_error_set(GIT_ERROR_NET, "malformed git protocol URL");
76
+ return -1;
77
+ }
78
+
79
+ git_str_puts(request, cmd);
80
+ git_str_puts(request, " '");
81
+ git_str_puts(request, repo);
82
+ git_str_puts(request, "'");
83
+
84
+ if (git_str_oom(request))
85
+ return -1;
86
+
87
+ return 0;
88
+ }
89
+
90
+ static int send_command(ssh_stream *s)
91
+ {
92
+ int error;
93
+ git_str request = GIT_STR_INIT;
94
+
95
+ error = gen_proto(&request, s->cmd, &s->url);
96
+ if (error < 0)
97
+ goto cleanup;
98
+
99
+ error = libssh2_channel_exec(s->channel, request.ptr);
100
+ if (error < LIBSSH2_ERROR_NONE) {
101
+ ssh_error(s->session, "SSH could not execute request");
102
+ goto cleanup;
103
+ }
104
+
105
+ s->sent_command = 1;
106
+
107
+ cleanup:
108
+ git_str_dispose(&request);
109
+ return error;
110
+ }
111
+
112
+ static int ssh_stream_read(
113
+ git_smart_subtransport_stream *stream,
114
+ char *buffer,
115
+ size_t buf_size,
116
+ size_t *bytes_read)
117
+ {
118
+ ssh_stream *s = GIT_CONTAINER_OF(stream, ssh_stream, parent);
119
+ ssize_t rc;
120
+
121
+ *bytes_read = 0;
122
+
123
+ if (!s->sent_command && send_command(s) < 0)
124
+ return -1;
125
+
126
+ if ((rc = libssh2_channel_read(s->channel, buffer, buf_size)) < LIBSSH2_ERROR_NONE) {
127
+ ssh_error(s->session, "SSH could not read data");
128
+ return -1;
129
+ }
130
+
131
+ /*
132
+ * If we can't get anything out of stdout, it's typically a
133
+ * not-found error, so read from stderr and signal EOF on
134
+ * stderr.
135
+ */
136
+ if (rc == 0) {
137
+ if ((rc = libssh2_channel_read_stderr(s->channel, buffer, buf_size)) > 0) {
138
+ git_error_set(GIT_ERROR_SSH, "%*s", (int)rc, buffer);
139
+ return GIT_EEOF;
140
+ } else if (rc < LIBSSH2_ERROR_NONE) {
141
+ ssh_error(s->session, "SSH could not read stderr");
142
+ return -1;
143
+ }
144
+ }
145
+
146
+ *bytes_read = rc;
147
+
148
+ return 0;
149
+ }
150
+
151
+ static int ssh_stream_write(
152
+ git_smart_subtransport_stream *stream,
153
+ const char *buffer,
154
+ size_t len)
155
+ {
156
+ ssh_stream *s = GIT_CONTAINER_OF(stream, ssh_stream, parent);
157
+ size_t off = 0;
158
+ ssize_t ret = 0;
159
+
160
+ if (!s->sent_command && send_command(s) < 0)
161
+ return -1;
162
+
163
+ do {
164
+ ret = libssh2_channel_write(s->channel, buffer + off, len - off);
165
+ if (ret < 0)
166
+ break;
167
+
168
+ off += ret;
169
+
170
+ } while (off < len);
171
+
172
+ if (ret < 0) {
173
+ ssh_error(s->session, "SSH could not write data");
174
+ return -1;
175
+ }
176
+
177
+ return 0;
178
+ }
179
+
180
+ static void ssh_stream_free(git_smart_subtransport_stream *stream)
181
+ {
182
+ ssh_stream *s = GIT_CONTAINER_OF(stream, ssh_stream, parent);
183
+ ssh_subtransport *t;
184
+
185
+ if (!stream)
186
+ return;
187
+
188
+ t = OWNING_SUBTRANSPORT(s);
189
+ t->current_stream = NULL;
190
+
191
+ if (s->channel) {
192
+ libssh2_channel_close(s->channel);
193
+ libssh2_channel_free(s->channel);
194
+ s->channel = NULL;
195
+ }
196
+
197
+ if (s->session) {
198
+ libssh2_session_disconnect(s->session, "closing transport");
199
+ libssh2_session_free(s->session);
200
+ s->session = NULL;
201
+ }
202
+
203
+ if (s->io) {
204
+ git_stream_close(s->io);
205
+ git_stream_free(s->io);
206
+ s->io = NULL;
207
+ }
208
+
209
+ git_net_url_dispose(&s->url);
210
+ git__free(s);
211
+ }
212
+
213
+ static int ssh_stream_alloc(
214
+ ssh_subtransport *t,
215
+ const char *cmd,
216
+ git_smart_subtransport_stream **stream)
217
+ {
218
+ ssh_stream *s;
219
+
220
+ GIT_ASSERT_ARG(stream);
221
+
222
+ s = git__calloc(sizeof(ssh_stream), 1);
223
+ GIT_ERROR_CHECK_ALLOC(s);
224
+
225
+ s->parent.subtransport = &t->parent;
226
+ s->parent.read = ssh_stream_read;
227
+ s->parent.write = ssh_stream_write;
228
+ s->parent.free = ssh_stream_free;
229
+
230
+ s->cmd = cmd;
231
+
232
+ *stream = &s->parent;
233
+ return 0;
234
+ }
235
+
236
+ static int ssh_agent_auth(LIBSSH2_SESSION *session, git_credential_ssh_key *c) {
237
+ int rc = LIBSSH2_ERROR_NONE;
238
+
239
+ struct libssh2_agent_publickey *curr, *prev = NULL;
240
+
241
+ LIBSSH2_AGENT *agent = libssh2_agent_init(session);
242
+
243
+ if (agent == NULL)
244
+ return -1;
245
+
246
+ rc = libssh2_agent_connect(agent);
247
+
248
+ if (rc != LIBSSH2_ERROR_NONE) {
249
+ rc = LIBSSH2_ERROR_AUTHENTICATION_FAILED;
250
+ goto shutdown;
251
+ }
252
+
253
+ rc = libssh2_agent_list_identities(agent);
254
+
255
+ if (rc != LIBSSH2_ERROR_NONE)
256
+ goto shutdown;
257
+
258
+ while (1) {
259
+ rc = libssh2_agent_get_identity(agent, &curr, prev);
260
+
261
+ if (rc < 0)
262
+ goto shutdown;
263
+
264
+ /* rc is set to 1 whenever the ssh agent ran out of keys to check.
265
+ * Set the error code to authentication failure rather than erroring
266
+ * out with an untranslatable error code.
267
+ */
268
+ if (rc == 1) {
269
+ rc = LIBSSH2_ERROR_AUTHENTICATION_FAILED;
270
+ goto shutdown;
271
+ }
272
+
273
+ rc = libssh2_agent_userauth(agent, c->username, curr);
274
+
275
+ if (rc == 0)
276
+ break;
277
+
278
+ prev = curr;
279
+ }
280
+
281
+ shutdown:
282
+
283
+ if (rc != LIBSSH2_ERROR_NONE)
284
+ ssh_error(session, "error authenticating");
285
+
286
+ libssh2_agent_disconnect(agent);
287
+ libssh2_agent_free(agent);
288
+
289
+ return rc;
290
+ }
291
+
292
+ static int _git_ssh_authenticate_session(
293
+ LIBSSH2_SESSION *session,
294
+ git_credential *cred)
295
+ {
296
+ int rc;
297
+
298
+ do {
299
+ git_error_clear();
300
+ switch (cred->credtype) {
301
+ case GIT_CREDENTIAL_USERPASS_PLAINTEXT: {
302
+ git_credential_userpass_plaintext *c = (git_credential_userpass_plaintext *)cred;
303
+ rc = libssh2_userauth_password(session, c->username, c->password);
304
+ break;
305
+ }
306
+ case GIT_CREDENTIAL_SSH_KEY: {
307
+ git_credential_ssh_key *c = (git_credential_ssh_key *)cred;
308
+
309
+ if (c->privatekey)
310
+ rc = libssh2_userauth_publickey_fromfile(
311
+ session, c->username, c->publickey,
312
+ c->privatekey, c->passphrase);
313
+ else
314
+ rc = ssh_agent_auth(session, c);
315
+
316
+ break;
317
+ }
318
+ case GIT_CREDENTIAL_SSH_CUSTOM: {
319
+ git_credential_ssh_custom *c = (git_credential_ssh_custom *)cred;
320
+
321
+ rc = libssh2_userauth_publickey(
322
+ session, c->username, (const unsigned char *)c->publickey,
323
+ c->publickey_len, c->sign_callback, &c->payload);
324
+ break;
325
+ }
326
+ case GIT_CREDENTIAL_SSH_INTERACTIVE: {
327
+ void **abstract = libssh2_session_abstract(session);
328
+ git_credential_ssh_interactive *c = (git_credential_ssh_interactive *)cred;
329
+
330
+ /* ideally, we should be able to set this by calling
331
+ * libssh2_session_init_ex() instead of libssh2_session_init().
332
+ * libssh2's API is inconsistent here i.e. libssh2_userauth_publickey()
333
+ * allows you to pass the `abstract` as part of the call, whereas
334
+ * libssh2_userauth_keyboard_interactive() does not!
335
+ *
336
+ * The only way to set the `abstract` pointer is by calling
337
+ * libssh2_session_abstract(), which will replace the existing
338
+ * pointer as is done below. This is safe for now (at time of writing),
339
+ * but may not be valid in future.
340
+ */
341
+ *abstract = c->payload;
342
+
343
+ rc = libssh2_userauth_keyboard_interactive(
344
+ session, c->username, c->prompt_callback);
345
+ break;
346
+ }
347
+ #ifdef GIT_SSH_LIBSSH2_MEMORY_CREDENTIALS
348
+ case GIT_CREDENTIAL_SSH_MEMORY: {
349
+ git_credential_ssh_key *c = (git_credential_ssh_key *)cred;
350
+
351
+ GIT_ASSERT(c->username);
352
+ GIT_ASSERT(c->privatekey);
353
+
354
+ rc = libssh2_userauth_publickey_frommemory(
355
+ session,
356
+ c->username,
357
+ strlen(c->username),
358
+ c->publickey,
359
+ c->publickey ? strlen(c->publickey) : 0,
360
+ c->privatekey,
361
+ strlen(c->privatekey),
362
+ c->passphrase);
363
+ break;
364
+ }
365
+ #endif
366
+ default:
367
+ rc = LIBSSH2_ERROR_AUTHENTICATION_FAILED;
368
+ }
369
+ } while (LIBSSH2_ERROR_EAGAIN == rc);
370
+
371
+ if (rc == LIBSSH2_ERROR_PASSWORD_EXPIRED ||
372
+ rc == LIBSSH2_ERROR_AUTHENTICATION_FAILED ||
373
+ rc == LIBSSH2_ERROR_PUBLICKEY_UNVERIFIED)
374
+ return GIT_EAUTH;
375
+
376
+ if (rc != LIBSSH2_ERROR_NONE) {
377
+ if (git_error_last()->klass == GIT_ERROR_NONE)
378
+ ssh_error(session, "failed to authenticate SSH session");
379
+ return -1;
380
+ }
381
+
382
+ return 0;
383
+ }
384
+
385
+ static int request_creds(git_credential **out, ssh_subtransport *t, const char *user, int auth_methods)
386
+ {
387
+ int error, no_callback = 0;
388
+ git_credential *cred = NULL;
389
+
390
+ if (!t->owner->connect_opts.callbacks.credentials) {
391
+ no_callback = 1;
392
+ } else {
393
+ error = t->owner->connect_opts.callbacks.credentials(
394
+ &cred,
395
+ t->owner->url,
396
+ user,
397
+ auth_methods,
398
+ t->owner->connect_opts.callbacks.payload);
399
+
400
+ if (error == GIT_PASSTHROUGH) {
401
+ no_callback = 1;
402
+ } else if (error < 0) {
403
+ return error;
404
+ } else if (!cred) {
405
+ git_error_set(GIT_ERROR_SSH, "callback failed to initialize SSH credentials");
406
+ return -1;
407
+ }
408
+ }
409
+
410
+ if (no_callback) {
411
+ git_error_set(GIT_ERROR_SSH, "authentication required but no callback set");
412
+ return GIT_EAUTH;
413
+ }
414
+
415
+ if (!(cred->credtype & auth_methods)) {
416
+ cred->free(cred);
417
+ git_error_set(GIT_ERROR_SSH, "authentication callback returned unsupported credentials type");
418
+ return GIT_EAUTH;
419
+ }
420
+
421
+ *out = cred;
422
+
423
+ return 0;
424
+ }
425
+
426
+ #define SSH_DIR ".ssh"
427
+ #define KNOWN_HOSTS_FILE "known_hosts"
428
+
429
+ /*
430
+ * Load the known_hosts file.
431
+ *
432
+ * Returns success but leaves the output NULL if we couldn't find the file.
433
+ */
434
+ static int load_known_hosts(LIBSSH2_KNOWNHOSTS **hosts, LIBSSH2_SESSION *session)
435
+ {
436
+ git_str path = GIT_STR_INIT, sshdir = GIT_STR_INIT;
437
+ LIBSSH2_KNOWNHOSTS *known_hosts = NULL;
438
+ int error;
439
+
440
+ GIT_ASSERT_ARG(hosts);
441
+
442
+ if ((known_hosts = libssh2_knownhost_init(session)) == NULL) {
443
+ ssh_error(session, "error initializing known hosts");
444
+ error = -1;
445
+ goto out;
446
+ }
447
+
448
+ if ((error = git_sysdir_expand_homedir_file(&sshdir, SSH_DIR)) < 0) {
449
+ if (error == GIT_ENOTFOUND)
450
+ error = 0;
451
+
452
+ goto out;
453
+ }
454
+
455
+ if ((error = git_str_joinpath(&path, git_str_cstr(&sshdir), KNOWN_HOSTS_FILE)) < 0)
456
+ goto out;
457
+
458
+ /*
459
+ * Try to read the file and consider not finding it as not trusting the
460
+ * host rather than an error.
461
+ */
462
+ error = libssh2_knownhost_readfile(known_hosts, git_str_cstr(&path), LIBSSH2_KNOWNHOST_FILE_OPENSSH);
463
+ if (error == LIBSSH2_ERROR_FILE)
464
+ error = 0;
465
+ if (error < 0)
466
+ ssh_error(session, "error reading known_hosts");
467
+
468
+ out:
469
+ *hosts = known_hosts;
470
+
471
+ git_str_dispose(&sshdir);
472
+ git_str_dispose(&path);
473
+
474
+ return error;
475
+ }
476
+
477
+ static void add_hostkey_pref_if_avail(
478
+ LIBSSH2_KNOWNHOSTS *known_hosts,
479
+ const char *hostname,
480
+ int port,
481
+ git_str *prefs,
482
+ int type,
483
+ const char *type_name)
484
+ {
485
+ struct libssh2_knownhost *host = NULL;
486
+ const char key = '\0';
487
+ int mask = LIBSSH2_KNOWNHOST_TYPE_PLAIN | LIBSSH2_KNOWNHOST_KEYENC_RAW | type;
488
+ int error;
489
+
490
+ error = libssh2_knownhost_checkp(known_hosts, hostname, port, &key, 1, mask, &host);
491
+ if (error == LIBSSH2_KNOWNHOST_CHECK_MISMATCH) {
492
+ if (git_str_len(prefs) > 0) {
493
+ git_str_putc(prefs, ',');
494
+ }
495
+ git_str_puts(prefs, type_name);
496
+ }
497
+ }
498
+
499
+ /*
500
+ * We figure out what kind of key we want to ask the remote for by trying to
501
+ * look it up with a nonsense key and using that mismatch to figure out what key
502
+ * we do have stored for the host.
503
+ *
504
+ * Populates prefs with the string to pass to libssh2_session_method_pref.
505
+ */
506
+ static void find_hostkey_preference(
507
+ LIBSSH2_KNOWNHOSTS *known_hosts,
508
+ const char *hostname,
509
+ int port,
510
+ git_str *prefs)
511
+ {
512
+ /*
513
+ * The order here is important as it indicates the priority of what will
514
+ * be preferred.
515
+ */
516
+ #ifdef LIBSSH2_KNOWNHOST_KEY_ED25519
517
+ add_hostkey_pref_if_avail(known_hosts, hostname, port, prefs, LIBSSH2_KNOWNHOST_KEY_ED25519, "ssh-ed25519");
518
+ #endif
519
+ #ifdef LIBSSH2_KNOWNHOST_KEY_ECDSA_256
520
+ add_hostkey_pref_if_avail(known_hosts, hostname, port, prefs, LIBSSH2_KNOWNHOST_KEY_ECDSA_256, "ecdsa-sha2-nistp256");
521
+ add_hostkey_pref_if_avail(known_hosts, hostname, port, prefs, LIBSSH2_KNOWNHOST_KEY_ECDSA_384, "ecdsa-sha2-nistp384");
522
+ add_hostkey_pref_if_avail(known_hosts, hostname, port, prefs, LIBSSH2_KNOWNHOST_KEY_ECDSA_521, "ecdsa-sha2-nistp521");
523
+ #endif
524
+ add_hostkey_pref_if_avail(known_hosts, hostname, port, prefs, LIBSSH2_KNOWNHOST_KEY_SSHRSA, "rsa-sha2-512");
525
+ add_hostkey_pref_if_avail(known_hosts, hostname, port, prefs, LIBSSH2_KNOWNHOST_KEY_SSHRSA, "rsa-sha2-256");
526
+ add_hostkey_pref_if_avail(known_hosts, hostname, port, prefs, LIBSSH2_KNOWNHOST_KEY_SSHRSA, "ssh-rsa");
527
+ }
528
+
529
+ static int _git_ssh_session_create(
530
+ LIBSSH2_SESSION **session,
531
+ LIBSSH2_KNOWNHOSTS **hosts,
532
+ const char *hostname,
533
+ int port,
534
+ git_stream *io)
535
+ {
536
+ git_socket_stream *socket = GIT_CONTAINER_OF(io, git_socket_stream, parent);
537
+ LIBSSH2_SESSION *s;
538
+ LIBSSH2_KNOWNHOSTS *known_hosts;
539
+ git_str prefs = GIT_STR_INIT;
540
+ int rc = 0;
541
+
542
+ GIT_ASSERT_ARG(session);
543
+ GIT_ASSERT_ARG(hosts);
544
+
545
+ s = libssh2_session_init();
546
+ if (!s) {
547
+ git_error_set(GIT_ERROR_NET, "failed to initialize SSH session");
548
+ return -1;
549
+ }
550
+
551
+ if (git_socket_stream__timeout > 0) {
552
+ libssh2_session_set_timeout(s, git_socket_stream__timeout);
553
+ }
554
+
555
+ if ((rc = load_known_hosts(&known_hosts, s)) < 0) {
556
+ ssh_error(s, "error loading known_hosts");
557
+ libssh2_session_free(s);
558
+ return -1;
559
+ }
560
+
561
+ find_hostkey_preference(known_hosts, hostname, port, &prefs);
562
+ if (git_str_len(&prefs) > 0) {
563
+ do {
564
+ rc = libssh2_session_method_pref(s, LIBSSH2_METHOD_HOSTKEY, git_str_cstr(&prefs));
565
+ } while (LIBSSH2_ERROR_EAGAIN == rc);
566
+ if (rc != LIBSSH2_ERROR_NONE) {
567
+ ssh_error(s, "failed to set hostkey preference");
568
+ goto on_error;
569
+ }
570
+ }
571
+ git_str_dispose(&prefs);
572
+
573
+ do {
574
+ rc = libssh2_session_handshake(s, socket->s);
575
+ } while (LIBSSH2_ERROR_EAGAIN == rc);
576
+
577
+ if (rc != LIBSSH2_ERROR_NONE) {
578
+ ssh_error(s, "failed to start SSH session");
579
+ goto on_error;
580
+ }
581
+
582
+ libssh2_session_set_blocking(s, 1);
583
+
584
+ *session = s;
585
+ *hosts = known_hosts;
586
+
587
+ return 0;
588
+
589
+ on_error:
590
+ libssh2_knownhost_free(known_hosts);
591
+ libssh2_session_free(s);
592
+ return -1;
593
+ }
594
+
595
+
596
+ /*
597
+ * Returns the typemask argument to pass to libssh2_knownhost_check{,p} based on
598
+ * the type of key that libssh2_session_hostkey returns.
599
+ */
600
+ static int fingerprint_type_mask(int keytype)
601
+ {
602
+ int mask = LIBSSH2_KNOWNHOST_TYPE_PLAIN | LIBSSH2_KNOWNHOST_KEYENC_RAW;
603
+ return mask;
604
+
605
+ switch (keytype) {
606
+ case LIBSSH2_HOSTKEY_TYPE_RSA:
607
+ mask |= LIBSSH2_KNOWNHOST_KEY_SSHRSA;
608
+ break;
609
+ case LIBSSH2_HOSTKEY_TYPE_DSS:
610
+ mask |= LIBSSH2_KNOWNHOST_KEY_SSHDSS;
611
+ break;
612
+ #ifdef LIBSSH2_HOSTKEY_TYPE_ECDSA_256
613
+ case LIBSSH2_HOSTKEY_TYPE_ECDSA_256:
614
+ mask |= LIBSSH2_KNOWNHOST_KEY_ECDSA_256;
615
+ break;
616
+ case LIBSSH2_HOSTKEY_TYPE_ECDSA_384:
617
+ mask |= LIBSSH2_KNOWNHOST_KEY_ECDSA_384;
618
+ break;
619
+ case LIBSSH2_HOSTKEY_TYPE_ECDSA_521:
620
+ mask |= LIBSSH2_KNOWNHOST_KEY_ECDSA_521;
621
+ break;
622
+ #endif
623
+ #ifdef LIBSSH2_HOSTKEY_TYPE_ED25519
624
+ case LIBSSH2_HOSTKEY_TYPE_ED25519:
625
+ mask |= LIBSSH2_KNOWNHOST_KEY_ED25519;
626
+ break;
627
+ #endif
628
+ }
629
+
630
+ return mask;
631
+ }
632
+
633
+ /*
634
+ * Check the host against the user's known_hosts file.
635
+ *
636
+ * Returns 1/0 for valid/''not-valid or <0 for an error
637
+ */
638
+ static int check_against_known_hosts(
639
+ LIBSSH2_SESSION *session,
640
+ LIBSSH2_KNOWNHOSTS *known_hosts,
641
+ const char *hostname,
642
+ int port,
643
+ const char *key,
644
+ size_t key_len,
645
+ int key_type)
646
+ {
647
+ int check, typemask, ret = 0;
648
+ struct libssh2_knownhost *host = NULL;
649
+
650
+ if (known_hosts == NULL)
651
+ return 0;
652
+
653
+ typemask = fingerprint_type_mask(key_type);
654
+ check = libssh2_knownhost_checkp(known_hosts, hostname, port, key, key_len, typemask, &host);
655
+ if (check == LIBSSH2_KNOWNHOST_CHECK_FAILURE) {
656
+ ssh_error(session, "error checking for known host");
657
+ return -1;
658
+ }
659
+
660
+ ret = check == LIBSSH2_KNOWNHOST_CHECK_MATCH ? 1 : 0;
661
+
662
+ return ret;
663
+ }
664
+
665
+ /*
666
+ * Perform the check for the session's certificate against known hosts if
667
+ * possible and then ask the user if they have a callback.
668
+ *
669
+ * Returns 1/0 for valid/not-valid or <0 for an error
670
+ */
671
+ static int check_certificate(
672
+ LIBSSH2_SESSION *session,
673
+ LIBSSH2_KNOWNHOSTS *known_hosts,
674
+ git_transport_certificate_check_cb check_cb,
675
+ void *check_cb_payload,
676
+ const char *host,
677
+ int port)
678
+ {
679
+ git_cert_hostkey cert = {{ 0 }};
680
+ const char *key;
681
+ size_t cert_len;
682
+ int cert_type, cert_valid = 0, error = GIT_ECERTIFICATE;
683
+
684
+ if ((key = libssh2_session_hostkey(session, &cert_len, &cert_type)) == NULL) {
685
+ ssh_error(session, "failed to retrieve hostkey");
686
+ return -1;
687
+ }
688
+
689
+ if ((cert_valid = check_against_known_hosts(session, known_hosts, host, port, key, cert_len, cert_type)) < 0)
690
+ return -1;
691
+
692
+ cert.parent.cert_type = GIT_CERT_HOSTKEY_LIBSSH2;
693
+ if (key != NULL) {
694
+ cert.type |= GIT_CERT_SSH_RAW;
695
+ cert.hostkey = key;
696
+ cert.hostkey_len = cert_len;
697
+ switch (cert_type) {
698
+ case LIBSSH2_HOSTKEY_TYPE_RSA:
699
+ cert.raw_type = GIT_CERT_SSH_RAW_TYPE_RSA;
700
+ break;
701
+ case LIBSSH2_HOSTKEY_TYPE_DSS:
702
+ cert.raw_type = GIT_CERT_SSH_RAW_TYPE_DSS;
703
+ break;
704
+
705
+ #ifdef LIBSSH2_HOSTKEY_TYPE_ECDSA_256
706
+ case LIBSSH2_HOSTKEY_TYPE_ECDSA_256:
707
+ cert.raw_type = GIT_CERT_SSH_RAW_TYPE_KEY_ECDSA_256;
708
+ break;
709
+ case LIBSSH2_HOSTKEY_TYPE_ECDSA_384:
710
+ cert.raw_type = GIT_CERT_SSH_RAW_TYPE_KEY_ECDSA_384;
711
+ break;
712
+ case LIBSSH2_KNOWNHOST_KEY_ECDSA_521:
713
+ cert.raw_type = GIT_CERT_SSH_RAW_TYPE_KEY_ECDSA_521;
714
+ break;
715
+ #endif
716
+
717
+ #ifdef LIBSSH2_HOSTKEY_TYPE_ED25519
718
+ case LIBSSH2_HOSTKEY_TYPE_ED25519:
719
+ cert.raw_type = GIT_CERT_SSH_RAW_TYPE_KEY_ED25519;
720
+ break;
721
+ #endif
722
+ default:
723
+ cert.raw_type = GIT_CERT_SSH_RAW_TYPE_UNKNOWN;
724
+ }
725
+ }
726
+
727
+ #ifdef LIBSSH2_HOSTKEY_HASH_SHA256
728
+ key = libssh2_hostkey_hash(session, LIBSSH2_HOSTKEY_HASH_SHA256);
729
+ if (key != NULL) {
730
+ cert.type |= GIT_CERT_SSH_SHA256;
731
+ memcpy(&cert.hash_sha256, key, 32);
732
+ }
733
+ #endif
734
+
735
+ key = libssh2_hostkey_hash(session, LIBSSH2_HOSTKEY_HASH_SHA1);
736
+ if (key != NULL) {
737
+ cert.type |= GIT_CERT_SSH_SHA1;
738
+ memcpy(&cert.hash_sha1, key, 20);
739
+ }
740
+
741
+ key = libssh2_hostkey_hash(session, LIBSSH2_HOSTKEY_HASH_MD5);
742
+ if (key != NULL) {
743
+ cert.type |= GIT_CERT_SSH_MD5;
744
+ memcpy(&cert.hash_md5, key, 16);
745
+ }
746
+
747
+ if (cert.type == 0) {
748
+ git_error_set(GIT_ERROR_SSH, "unable to get the host key");
749
+ return -1;
750
+ }
751
+
752
+ if (check_cb != NULL) {
753
+ git_cert_hostkey *cert_ptr = &cert;
754
+
755
+ error = check_cb((git_cert *)cert_ptr, cert_valid, host,
756
+ check_cb_payload);
757
+
758
+ if (error == 0)
759
+ cert_valid = 1;
760
+ else if (error != GIT_PASSTHROUGH)
761
+ cert_valid = 0;
762
+ }
763
+
764
+ if (!cert_valid) {
765
+ git_error_set(GIT_ERROR_SSH, "invalid or unknown remote ssh hostkey");
766
+ return (error == GIT_PASSTHROUGH) ? GIT_ECERTIFICATE : error;
767
+ }
768
+
769
+ return 0;
770
+ }
771
+
772
+ #define SSH_DEFAULT_PORT "22"
773
+
774
+ static int _git_ssh_setup_conn(
775
+ ssh_subtransport *t,
776
+ const char *url,
777
+ const char *cmd,
778
+ git_smart_subtransport_stream **stream)
779
+ {
780
+ int auth_methods, error = 0, port;
781
+ ssh_stream *s;
782
+ git_credential *cred = NULL;
783
+ LIBSSH2_SESSION *session=NULL;
784
+ LIBSSH2_CHANNEL *channel=NULL;
785
+ LIBSSH2_KNOWNHOSTS *known_hosts = NULL;
786
+
787
+ t->current_stream = NULL;
788
+
789
+ *stream = NULL;
790
+ if (ssh_stream_alloc(t, cmd, stream) < 0)
791
+ return -1;
792
+
793
+ s = (ssh_stream *)*stream;
794
+ s->session = NULL;
795
+ s->channel = NULL;
796
+
797
+ if (git_net_str_is_url(url))
798
+ error = git_net_url_parse(&s->url, url);
799
+ else
800
+ error = git_net_url_parse_scp(&s->url, url);
801
+
802
+ if (error < 0)
803
+ goto done;
804
+
805
+ /* Safety check: like git, we forbid paths that look like an option as
806
+ * that could lead to injection on the remote side */
807
+ if (git_process__is_cmdline_option(s->url.path)) {
808
+ git_error_set(GIT_ERROR_NET, "cannot ssh: path '%s' is ambiguous with command-line option", s->url.path);
809
+ error = -1;
810
+ goto done;
811
+ }
812
+
813
+
814
+ if ((error = git_socket_stream_new(&s->io, s->url.host, s->url.port)) < 0 ||
815
+ (error = git_stream_connect(s->io)) < 0)
816
+ goto done;
817
+
818
+ /*
819
+ * Try to parse the port as a number, if we can't then fall back to
820
+ * default. It would be nice if we could get the port that was resolved
821
+ * as part of the stream connection, but that's not something that's
822
+ * exposed.
823
+ */
824
+ if (git__strntol32(&port, s->url.port, strlen(s->url.port), NULL, 10) < 0)
825
+ port = -1;
826
+
827
+ if ((error = _git_ssh_session_create(&session, &known_hosts, s->url.host, port, s->io)) < 0)
828
+ goto done;
829
+
830
+ if ((error = check_certificate(session, known_hosts, t->owner->connect_opts.callbacks.certificate_check, t->owner->connect_opts.callbacks.payload, s->url.host, port)) < 0)
831
+ goto done;
832
+
833
+ /* we need the username to ask for auth methods */
834
+ if (!s->url.username) {
835
+ if ((error = request_creds(&cred, t, NULL, GIT_CREDENTIAL_USERNAME)) < 0)
836
+ goto done;
837
+
838
+ s->url.username = git__strdup(((git_credential_username *) cred)->username);
839
+ cred->free(cred);
840
+ cred = NULL;
841
+ if (!s->url.username)
842
+ goto done;
843
+ } else if (s->url.username && s->url.password) {
844
+ if ((error = git_credential_userpass_plaintext_new(&cred, s->url.username, s->url.password)) < 0)
845
+ goto done;
846
+ }
847
+
848
+ if ((error = list_auth_methods(&auth_methods, session, s->url.username)) < 0)
849
+ goto done;
850
+
851
+ error = GIT_EAUTH;
852
+ /* if we already have something to try */
853
+ if (cred && auth_methods & cred->credtype)
854
+ error = _git_ssh_authenticate_session(session, cred);
855
+
856
+ while (error == GIT_EAUTH) {
857
+ if (cred) {
858
+ cred->free(cred);
859
+ cred = NULL;
860
+ }
861
+
862
+ if ((error = request_creds(&cred, t, s->url.username, auth_methods)) < 0)
863
+ goto done;
864
+
865
+ if (strcmp(s->url.username, git_credential_get_username(cred))) {
866
+ git_error_set(GIT_ERROR_SSH, "username does not match previous request");
867
+ error = -1;
868
+ goto done;
869
+ }
870
+
871
+ error = _git_ssh_authenticate_session(session, cred);
872
+
873
+ if (error == GIT_EAUTH) {
874
+ /* refresh auth methods */
875
+ if ((error = list_auth_methods(&auth_methods, session, s->url.username)) < 0)
876
+ goto done;
877
+ else
878
+ error = GIT_EAUTH;
879
+ }
880
+ }
881
+
882
+ if (error < 0)
883
+ goto done;
884
+
885
+ channel = libssh2_channel_open_session(session);
886
+ if (!channel) {
887
+ error = -1;
888
+ ssh_error(session, "Failed to open SSH channel");
889
+ goto done;
890
+ }
891
+
892
+ libssh2_channel_set_blocking(channel, 1);
893
+
894
+ s->session = session;
895
+ s->channel = channel;
896
+
897
+ t->current_stream = s;
898
+
899
+ done:
900
+ if (known_hosts)
901
+ libssh2_knownhost_free(known_hosts);
902
+
903
+ if (error < 0) {
904
+ ssh_stream_free(*stream);
905
+
906
+ if (session)
907
+ libssh2_session_free(session);
908
+ }
909
+
910
+ if (cred)
911
+ cred->free(cred);
912
+
913
+ return error;
914
+ }
915
+
916
+ static int ssh_uploadpack_ls(
917
+ ssh_subtransport *t,
918
+ const char *url,
919
+ git_smart_subtransport_stream **stream)
920
+ {
921
+ const char *cmd = t->cmd_uploadpack ? t->cmd_uploadpack : cmd_uploadpack;
922
+
923
+ return _git_ssh_setup_conn(t, url, cmd, stream);
924
+ }
925
+
926
+ static int ssh_uploadpack(
927
+ ssh_subtransport *t,
928
+ const char *url,
929
+ git_smart_subtransport_stream **stream)
930
+ {
931
+ GIT_UNUSED(url);
932
+
933
+ if (t->current_stream) {
934
+ *stream = &t->current_stream->parent;
935
+ return 0;
936
+ }
937
+
938
+ git_error_set(GIT_ERROR_NET, "must call UPLOADPACK_LS before UPLOADPACK");
939
+ return -1;
940
+ }
941
+
942
+ static int ssh_receivepack_ls(
943
+ ssh_subtransport *t,
944
+ const char *url,
945
+ git_smart_subtransport_stream **stream)
946
+ {
947
+ const char *cmd = t->cmd_receivepack ? t->cmd_receivepack : cmd_receivepack;
948
+
949
+
950
+ return _git_ssh_setup_conn(t, url, cmd, stream);
951
+ }
952
+
953
+ static int ssh_receivepack(
954
+ ssh_subtransport *t,
955
+ const char *url,
956
+ git_smart_subtransport_stream **stream)
957
+ {
958
+ GIT_UNUSED(url);
959
+
960
+ if (t->current_stream) {
961
+ *stream = &t->current_stream->parent;
962
+ return 0;
963
+ }
964
+
965
+ git_error_set(GIT_ERROR_NET, "must call RECEIVEPACK_LS before RECEIVEPACK");
966
+ return -1;
967
+ }
968
+
969
+ static int _ssh_action(
970
+ git_smart_subtransport_stream **stream,
971
+ git_smart_subtransport *subtransport,
972
+ const char *url,
973
+ git_smart_service_t action)
974
+ {
975
+ ssh_subtransport *t = GIT_CONTAINER_OF(subtransport, ssh_subtransport, parent);
976
+
977
+ switch (action) {
978
+ case GIT_SERVICE_UPLOADPACK_LS:
979
+ return ssh_uploadpack_ls(t, url, stream);
980
+
981
+ case GIT_SERVICE_UPLOADPACK:
982
+ return ssh_uploadpack(t, url, stream);
983
+
984
+ case GIT_SERVICE_RECEIVEPACK_LS:
985
+ return ssh_receivepack_ls(t, url, stream);
986
+
987
+ case GIT_SERVICE_RECEIVEPACK:
988
+ return ssh_receivepack(t, url, stream);
989
+ }
990
+
991
+ *stream = NULL;
992
+ return -1;
993
+ }
994
+
995
+ static int _ssh_close(git_smart_subtransport *subtransport)
996
+ {
997
+ ssh_subtransport *t = GIT_CONTAINER_OF(subtransport, ssh_subtransport, parent);
998
+
999
+ GIT_ASSERT(!t->current_stream);
1000
+
1001
+ GIT_UNUSED(t);
1002
+
1003
+ return 0;
1004
+ }
1005
+
1006
+ static void _ssh_free(git_smart_subtransport *subtransport)
1007
+ {
1008
+ ssh_subtransport *t = GIT_CONTAINER_OF(subtransport, ssh_subtransport, parent);
1009
+
1010
+ git__free(t->cmd_uploadpack);
1011
+ git__free(t->cmd_receivepack);
1012
+ git__free(t);
1013
+ }
1014
+
1015
+ #define SSH_AUTH_PUBLICKEY "publickey"
1016
+ #define SSH_AUTH_PASSWORD "password"
1017
+ #define SSH_AUTH_KEYBOARD_INTERACTIVE "keyboard-interactive"
1018
+
1019
+ static int list_auth_methods(int *out, LIBSSH2_SESSION *session, const char *username)
1020
+ {
1021
+ const char *list, *ptr;
1022
+
1023
+ *out = 0;
1024
+
1025
+ list = libssh2_userauth_list(session, username,
1026
+ (unsigned int)strlen(username));
1027
+
1028
+ /* either error, or the remote accepts NONE auth, which is bizarre, let's punt */
1029
+ if (list == NULL && !libssh2_userauth_authenticated(session)) {
1030
+ ssh_error(session, "remote rejected authentication");
1031
+ return GIT_EAUTH;
1032
+ }
1033
+
1034
+ ptr = list;
1035
+ while (ptr) {
1036
+ if (*ptr == ',')
1037
+ ptr++;
1038
+
1039
+ if (!git__prefixcmp(ptr, SSH_AUTH_PUBLICKEY)) {
1040
+ *out |= GIT_CREDENTIAL_SSH_KEY;
1041
+ *out |= GIT_CREDENTIAL_SSH_CUSTOM;
1042
+ #ifdef GIT_SSH_LIBSSH2_MEMORY_CREDENTIALS
1043
+ *out |= GIT_CREDENTIAL_SSH_MEMORY;
1044
+ #endif
1045
+ ptr += strlen(SSH_AUTH_PUBLICKEY);
1046
+ continue;
1047
+ }
1048
+
1049
+ if (!git__prefixcmp(ptr, SSH_AUTH_PASSWORD)) {
1050
+ *out |= GIT_CREDENTIAL_USERPASS_PLAINTEXT;
1051
+ ptr += strlen(SSH_AUTH_PASSWORD);
1052
+ continue;
1053
+ }
1054
+
1055
+ if (!git__prefixcmp(ptr, SSH_AUTH_KEYBOARD_INTERACTIVE)) {
1056
+ *out |= GIT_CREDENTIAL_SSH_INTERACTIVE;
1057
+ ptr += strlen(SSH_AUTH_KEYBOARD_INTERACTIVE);
1058
+ continue;
1059
+ }
1060
+
1061
+ /* Skip it if we don't know it */
1062
+ ptr = strchr(ptr, ',');
1063
+ }
1064
+
1065
+ return 0;
1066
+ }
1067
+
1068
+ int git_smart_subtransport_ssh_libssh2(
1069
+ git_smart_subtransport **out,
1070
+ git_transport *owner,
1071
+ void *param)
1072
+ {
1073
+ ssh_subtransport *t;
1074
+
1075
+ GIT_ASSERT_ARG(out);
1076
+
1077
+ GIT_UNUSED(param);
1078
+
1079
+ t = git__calloc(sizeof(ssh_subtransport), 1);
1080
+ GIT_ERROR_CHECK_ALLOC(t);
1081
+
1082
+ t->owner = (transport_smart *)owner;
1083
+ t->parent.action = _ssh_action;
1084
+ t->parent.close = _ssh_close;
1085
+ t->parent.free = _ssh_free;
1086
+
1087
+ *out = (git_smart_subtransport *) t;
1088
+ return 0;
1089
+ }
1090
+
1091
+ int git_smart_subtransport_ssh_libssh2_set_paths(
1092
+ git_smart_subtransport *subtransport,
1093
+ const char *cmd_uploadpack,
1094
+ const char *cmd_receivepack)
1095
+ {
1096
+ ssh_subtransport *t = (ssh_subtransport *)subtransport;
1097
+
1098
+ git__free(t->cmd_uploadpack);
1099
+ git__free(t->cmd_receivepack);
1100
+
1101
+ t->cmd_uploadpack = git__strdup(cmd_uploadpack);
1102
+ GIT_ERROR_CHECK_ALLOC(t->cmd_uploadpack);
1103
+
1104
+ t->cmd_receivepack = git__strdup(cmd_receivepack);
1105
+ GIT_ERROR_CHECK_ALLOC(t->cmd_receivepack);
1106
+
1107
+ return 0;
1108
+ }
1109
+
1110
+ static void shutdown_libssh2(void)
1111
+ {
1112
+ libssh2_exit();
1113
+ }
1114
+
1115
+ int git_transport_ssh_libssh2_global_init(void)
1116
+ {
1117
+ if (libssh2_init(0) < 0) {
1118
+ git_error_set(GIT_ERROR_SSH, "unable to initialize libssh2");
1119
+ return -1;
1120
+ }
1121
+
1122
+ return git_runtime_shutdown_register(shutdown_libssh2);
1123
+ }
1124
+
1125
+ #else /* GIT_SSH */
1126
+
1127
+ int git_transport_ssh_libssh2_global_init(void)
1128
+ {
1129
+ return 0;
1130
+ }
1131
+
1132
+ #endif