rugged 1.6.3 → 1.9.0

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