rugged 1.7.2 → 1.9.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (361) hide show
  1. checksums.yaml +4 -4
  2. data/lib/rugged/version.rb +1 -1
  3. data/vendor/libgit2/AUTHORS +1 -0
  4. data/vendor/libgit2/CMakeLists.txt +23 -10
  5. data/vendor/libgit2/COPYING +195 -1
  6. data/vendor/libgit2/cmake/{FindIconv.cmake → FindIntlIconv.cmake} +6 -0
  7. data/vendor/libgit2/cmake/FindLLHTTP.cmake +39 -0
  8. data/vendor/libgit2/cmake/SelectGSSAPI.cmake +1 -1
  9. data/vendor/libgit2/cmake/SelectHTTPParser.cmake +23 -8
  10. data/vendor/libgit2/cmake/SelectHTTPSBackend.cmake +17 -8
  11. data/vendor/libgit2/cmake/SelectHashes.cmake +28 -11
  12. data/vendor/libgit2/cmake/SelectRegex.cmake +6 -1
  13. data/vendor/libgit2/cmake/SelectSSH.cmake +22 -17
  14. data/vendor/libgit2/cmake/SelectZlib.cmake +4 -0
  15. data/vendor/libgit2/deps/llhttp/CMakeLists.txt +8 -0
  16. data/vendor/libgit2/deps/llhttp/LICENSE-MIT +22 -0
  17. data/vendor/libgit2/deps/llhttp/api.c +510 -0
  18. data/vendor/libgit2/deps/llhttp/http.c +170 -0
  19. data/vendor/libgit2/deps/llhttp/llhttp.c +10168 -0
  20. data/vendor/libgit2/deps/llhttp/llhttp.h +897 -0
  21. data/vendor/libgit2/deps/ntlmclient/CMakeLists.txt +1 -1
  22. data/vendor/libgit2/deps/ntlmclient/crypt_builtin_md4.c +311 -0
  23. data/vendor/libgit2/deps/ntlmclient/crypt_commoncrypto.c +2 -1
  24. data/vendor/libgit2/deps/ntlmclient/crypt_mbedtls.c +0 -20
  25. data/vendor/libgit2/deps/ntlmclient/crypt_openssl.c +4 -4
  26. data/vendor/libgit2/deps/ntlmclient/ntlm.c +21 -21
  27. data/vendor/libgit2/deps/ntlmclient/unicode_builtin.c +5 -4
  28. data/vendor/libgit2/deps/ntlmclient/unicode_iconv.c +2 -1
  29. data/vendor/libgit2/deps/ntlmclient/utf8.h +1176 -721
  30. data/vendor/libgit2/deps/ntlmclient/util.h +11 -0
  31. data/vendor/libgit2/deps/pcre/CMakeLists.txt +1 -0
  32. data/vendor/libgit2/deps/xdiff/xmerge.c +2 -2
  33. data/vendor/libgit2/deps/zlib/CMakeLists.txt +6 -1
  34. data/vendor/libgit2/deps/zlib/LICENSE +22 -0
  35. data/vendor/libgit2/deps/zlib/adler32.c +5 -27
  36. data/vendor/libgit2/deps/zlib/crc32.c +94 -167
  37. data/vendor/libgit2/deps/zlib/deflate.c +358 -435
  38. data/vendor/libgit2/deps/zlib/deflate.h +41 -10
  39. data/vendor/libgit2/deps/zlib/gzguts.h +13 -18
  40. data/vendor/libgit2/deps/zlib/infback.c +17 -30
  41. data/vendor/libgit2/deps/zlib/inffast.c +1 -4
  42. data/vendor/libgit2/deps/zlib/inffast.h +1 -1
  43. data/vendor/libgit2/deps/zlib/inflate.c +36 -102
  44. data/vendor/libgit2/deps/zlib/inftrees.c +6 -11
  45. data/vendor/libgit2/deps/zlib/inftrees.h +6 -6
  46. data/vendor/libgit2/deps/zlib/trees.c +287 -352
  47. data/vendor/libgit2/deps/zlib/zconf.h +23 -14
  48. data/vendor/libgit2/deps/zlib/zlib.h +202 -202
  49. data/vendor/libgit2/deps/zlib/zutil.c +18 -44
  50. data/vendor/libgit2/deps/zlib/zutil.h +13 -33
  51. data/vendor/libgit2/include/git2/annotated_commit.h +12 -5
  52. data/vendor/libgit2/include/git2/apply.h +27 -6
  53. data/vendor/libgit2/include/git2/attr.h +17 -4
  54. data/vendor/libgit2/include/git2/blame.h +133 -28
  55. data/vendor/libgit2/include/git2/blob.h +71 -28
  56. data/vendor/libgit2/include/git2/branch.h +22 -15
  57. data/vendor/libgit2/include/git2/buffer.h +6 -4
  58. data/vendor/libgit2/include/git2/cert.h +2 -1
  59. data/vendor/libgit2/include/git2/checkout.h +83 -32
  60. data/vendor/libgit2/include/git2/cherrypick.h +10 -3
  61. data/vendor/libgit2/include/git2/clone.h +25 -9
  62. data/vendor/libgit2/include/git2/commit.h +132 -3
  63. data/vendor/libgit2/include/git2/common.h +120 -63
  64. data/vendor/libgit2/include/git2/config.h +93 -23
  65. data/vendor/libgit2/include/git2/credential.h +30 -2
  66. data/vendor/libgit2/include/git2/credential_helpers.h +1 -0
  67. data/vendor/libgit2/include/git2/deprecated.h +133 -3
  68. data/vendor/libgit2/include/git2/describe.h +13 -1
  69. data/vendor/libgit2/include/git2/diff.h +38 -8
  70. data/vendor/libgit2/include/git2/email.h +9 -29
  71. data/vendor/libgit2/include/git2/errors.h +46 -73
  72. data/vendor/libgit2/include/git2/filter.h +14 -7
  73. data/vendor/libgit2/include/git2/global.h +8 -1
  74. data/vendor/libgit2/include/git2/graph.h +3 -2
  75. data/vendor/libgit2/include/git2/ignore.h +10 -0
  76. data/vendor/libgit2/include/git2/index.h +99 -14
  77. data/vendor/libgit2/include/git2/indexer.h +21 -4
  78. data/vendor/libgit2/include/git2/mailmap.h +7 -1
  79. data/vendor/libgit2/include/git2/merge.h +46 -1
  80. data/vendor/libgit2/include/git2/message.h +2 -2
  81. data/vendor/libgit2/include/git2/net.h +3 -1
  82. data/vendor/libgit2/include/git2/notes.h +9 -6
  83. data/vendor/libgit2/include/git2/object.h +9 -8
  84. data/vendor/libgit2/include/git2/odb.h +91 -49
  85. data/vendor/libgit2/include/git2/odb_backend.h +80 -52
  86. data/vendor/libgit2/include/git2/oid.h +23 -24
  87. data/vendor/libgit2/include/git2/oidarray.h +7 -1
  88. data/vendor/libgit2/include/git2/pack.h +13 -1
  89. data/vendor/libgit2/include/git2/patch.h +2 -3
  90. data/vendor/libgit2/include/git2/pathspec.h +9 -0
  91. data/vendor/libgit2/include/git2/proxy.h +10 -0
  92. data/vendor/libgit2/include/git2/rebase.h +9 -6
  93. data/vendor/libgit2/include/git2/refdb.h +2 -2
  94. data/vendor/libgit2/include/git2/reflog.h +3 -2
  95. data/vendor/libgit2/include/git2/refs.h +9 -6
  96. data/vendor/libgit2/include/git2/refspec.h +14 -4
  97. data/vendor/libgit2/include/git2/remote.h +94 -18
  98. data/vendor/libgit2/include/git2/repository.h +57 -21
  99. data/vendor/libgit2/include/git2/reset.h +16 -3
  100. data/vendor/libgit2/include/git2/revert.h +9 -4
  101. data/vendor/libgit2/include/git2/revparse.h +3 -3
  102. data/vendor/libgit2/include/git2/revwalk.h +3 -2
  103. data/vendor/libgit2/include/git2/signature.h +46 -1
  104. data/vendor/libgit2/include/git2/stash.h +17 -3
  105. data/vendor/libgit2/include/git2/status.h +10 -6
  106. data/vendor/libgit2/include/git2/stdint.h +87 -85
  107. data/vendor/libgit2/include/git2/strarray.h +2 -3
  108. data/vendor/libgit2/include/git2/submodule.h +20 -9
  109. data/vendor/libgit2/include/git2/sys/alloc.h +12 -0
  110. data/vendor/libgit2/include/git2/sys/commit.h +77 -3
  111. data/vendor/libgit2/include/git2/sys/commit_graph.h +103 -62
  112. data/vendor/libgit2/include/git2/sys/config.h +80 -4
  113. data/vendor/libgit2/include/git2/sys/credential.h +4 -3
  114. data/vendor/libgit2/include/git2/sys/diff.h +21 -1
  115. data/vendor/libgit2/include/git2/sys/email.h +7 -0
  116. data/vendor/libgit2/include/git2/sys/errors.h +76 -0
  117. data/vendor/libgit2/include/git2/sys/filter.h +66 -3
  118. data/vendor/libgit2/include/git2/sys/hashsig.h +11 -0
  119. data/vendor/libgit2/include/git2/sys/index.h +3 -2
  120. data/vendor/libgit2/include/git2/sys/mempack.h +32 -2
  121. data/vendor/libgit2/include/git2/sys/merge.h +55 -7
  122. data/vendor/libgit2/include/git2/sys/midx.h +43 -4
  123. data/vendor/libgit2/include/git2/sys/odb_backend.h +7 -3
  124. data/vendor/libgit2/include/git2/sys/openssl.h +8 -1
  125. data/vendor/libgit2/include/git2/sys/path.h +12 -1
  126. data/vendor/libgit2/include/git2/sys/refdb_backend.h +40 -36
  127. data/vendor/libgit2/include/git2/sys/refs.h +3 -2
  128. data/vendor/libgit2/include/git2/sys/remote.h +8 -1
  129. data/vendor/libgit2/include/git2/sys/repository.h +63 -3
  130. data/vendor/libgit2/include/git2/sys/stream.h +11 -2
  131. data/vendor/libgit2/include/git2/sys/transport.h +24 -3
  132. data/vendor/libgit2/include/git2/tag.h +3 -1
  133. data/vendor/libgit2/include/git2/trace.h +9 -3
  134. data/vendor/libgit2/include/git2/transaction.h +3 -2
  135. data/vendor/libgit2/include/git2/transport.h +11 -3
  136. data/vendor/libgit2/include/git2/tree.h +16 -5
  137. data/vendor/libgit2/include/git2/types.h +19 -3
  138. data/vendor/libgit2/include/git2/version.h +44 -8
  139. data/vendor/libgit2/include/git2/worktree.h +16 -6
  140. data/vendor/libgit2/src/CMakeLists.txt +6 -4
  141. data/vendor/libgit2/src/cli/CMakeLists.txt +2 -2
  142. data/vendor/libgit2/src/cli/cmd.c +1 -1
  143. data/vendor/libgit2/src/cli/cmd.h +4 -0
  144. data/vendor/libgit2/src/cli/cmd_blame.c +287 -0
  145. data/vendor/libgit2/src/cli/cmd_cat_file.c +6 -8
  146. data/vendor/libgit2/src/cli/cmd_clone.c +5 -7
  147. data/vendor/libgit2/src/cli/cmd_config.c +241 -0
  148. data/vendor/libgit2/src/cli/cmd_hash_object.c +6 -8
  149. data/vendor/libgit2/src/cli/cmd_help.c +6 -7
  150. data/vendor/libgit2/src/cli/cmd_index_pack.c +114 -0
  151. data/vendor/libgit2/src/cli/cmd_init.c +102 -0
  152. data/vendor/libgit2/src/cli/common.c +168 -0
  153. data/vendor/libgit2/src/cli/common.h +63 -0
  154. data/vendor/libgit2/src/cli/error.h +1 -1
  155. data/vendor/libgit2/src/cli/main.c +52 -24
  156. data/vendor/libgit2/src/cli/opt.c +29 -3
  157. data/vendor/libgit2/src/cli/opt.h +21 -3
  158. data/vendor/libgit2/src/cli/opt_usage.c +102 -33
  159. data/vendor/libgit2/src/cli/opt_usage.h +6 -1
  160. data/vendor/libgit2/src/cli/progress.c +51 -2
  161. data/vendor/libgit2/src/cli/progress.h +12 -0
  162. data/vendor/libgit2/src/cli/unix/sighandler.c +2 -1
  163. data/vendor/libgit2/src/cli/win32/precompiled.h +1 -1
  164. data/vendor/libgit2/src/cli/win32/sighandler.c +1 -1
  165. data/vendor/libgit2/src/libgit2/CMakeLists.txt +26 -8
  166. data/vendor/libgit2/src/libgit2/apply.c +10 -13
  167. data/vendor/libgit2/src/libgit2/attr.c +30 -13
  168. data/vendor/libgit2/src/libgit2/attr_file.c +7 -2
  169. data/vendor/libgit2/src/libgit2/attr_file.h +2 -0
  170. data/vendor/libgit2/src/libgit2/attrcache.c +69 -33
  171. data/vendor/libgit2/src/libgit2/attrcache.h +5 -9
  172. data/vendor/libgit2/src/libgit2/blame.c +130 -44
  173. data/vendor/libgit2/src/libgit2/blame.h +1 -0
  174. data/vendor/libgit2/src/libgit2/cache.c +22 -17
  175. data/vendor/libgit2/src/libgit2/cache.h +7 -9
  176. data/vendor/libgit2/src/libgit2/checkout.c +34 -24
  177. data/vendor/libgit2/src/libgit2/checkout.h +0 -2
  178. data/vendor/libgit2/src/libgit2/cherrypick.c +1 -2
  179. data/vendor/libgit2/src/libgit2/clone.c +186 -166
  180. data/vendor/libgit2/src/libgit2/clone.h +4 -1
  181. data/vendor/libgit2/src/libgit2/commit.c +92 -0
  182. data/vendor/libgit2/src/libgit2/commit_graph.c +67 -56
  183. data/vendor/libgit2/src/libgit2/commit_graph.h +1 -2
  184. data/vendor/libgit2/src/libgit2/config.c +389 -298
  185. data/vendor/libgit2/src/libgit2/config.cmake.in +3 -0
  186. data/vendor/libgit2/src/libgit2/config.h +9 -4
  187. data/vendor/libgit2/src/libgit2/config_backend.h +8 -10
  188. data/vendor/libgit2/src/libgit2/config_cache.c +4 -5
  189. data/vendor/libgit2/src/libgit2/config_file.c +99 -88
  190. data/vendor/libgit2/src/libgit2/config_list.c +285 -0
  191. data/vendor/libgit2/src/libgit2/config_list.h +32 -0
  192. data/vendor/libgit2/src/libgit2/config_mem.c +194 -40
  193. data/vendor/libgit2/src/libgit2/config_parse.c +10 -9
  194. data/vendor/libgit2/src/libgit2/config_snapshot.c +24 -31
  195. data/vendor/libgit2/src/libgit2/describe.c +24 -24
  196. data/vendor/libgit2/src/libgit2/diff.c +1 -1
  197. data/vendor/libgit2/src/libgit2/diff_driver.c +12 -19
  198. data/vendor/libgit2/src/libgit2/diff_driver.h +2 -2
  199. data/vendor/libgit2/src/libgit2/diff_generate.c +3 -3
  200. data/vendor/libgit2/src/libgit2/diff_parse.c +2 -2
  201. data/vendor/libgit2/src/libgit2/diff_print.c +65 -9
  202. data/vendor/libgit2/src/libgit2/diff_tform.c +36 -8
  203. data/vendor/libgit2/src/libgit2/email.c +1 -0
  204. data/vendor/libgit2/src/libgit2/fetch.c +5 -3
  205. data/vendor/libgit2/src/libgit2/filter.c +5 -5
  206. data/vendor/libgit2/src/libgit2/git2.rc +3 -3
  207. data/vendor/libgit2/src/libgit2/grafts.c +18 -20
  208. data/vendor/libgit2/src/libgit2/grafts.h +0 -1
  209. data/vendor/libgit2/src/libgit2/graph.c +1 -1
  210. data/vendor/libgit2/src/libgit2/hashmap_oid.h +30 -0
  211. data/vendor/libgit2/src/libgit2/ignore.c +9 -5
  212. data/vendor/libgit2/src/libgit2/index.c +68 -90
  213. data/vendor/libgit2/src/libgit2/index.h +2 -2
  214. data/vendor/libgit2/src/libgit2/index_map.c +95 -0
  215. data/vendor/libgit2/src/libgit2/index_map.h +28 -0
  216. data/vendor/libgit2/src/libgit2/indexer.c +34 -38
  217. data/vendor/libgit2/src/libgit2/iterator.c +14 -8
  218. data/vendor/libgit2/src/libgit2/libgit2.c +153 -368
  219. data/vendor/libgit2/src/libgit2/mailmap.c +1 -1
  220. data/vendor/libgit2/src/libgit2/merge.c +42 -37
  221. data/vendor/libgit2/src/libgit2/merge_driver.c +2 -2
  222. data/vendor/libgit2/src/libgit2/midx.c +28 -15
  223. data/vendor/libgit2/src/libgit2/mwindow.c +38 -45
  224. data/vendor/libgit2/src/libgit2/mwindow.h +4 -0
  225. data/vendor/libgit2/src/libgit2/object.c +6 -5
  226. data/vendor/libgit2/src/libgit2/odb.c +5 -4
  227. data/vendor/libgit2/src/libgit2/odb_mempack.c +49 -17
  228. data/vendor/libgit2/src/libgit2/odb_pack.c +13 -5
  229. data/vendor/libgit2/src/libgit2/oid.c +32 -5
  230. data/vendor/libgit2/src/libgit2/oid.h +11 -0
  231. data/vendor/libgit2/src/libgit2/pack-objects.c +58 -31
  232. data/vendor/libgit2/src/libgit2/pack-objects.h +12 -4
  233. data/vendor/libgit2/src/libgit2/pack.c +30 -24
  234. data/vendor/libgit2/src/libgit2/pack.h +15 -10
  235. data/vendor/libgit2/src/libgit2/patch_parse.c +2 -2
  236. data/vendor/libgit2/src/libgit2/path.c +1 -1
  237. data/vendor/libgit2/src/libgit2/pathspec.c +1 -1
  238. data/vendor/libgit2/src/libgit2/push.c +79 -28
  239. data/vendor/libgit2/src/libgit2/push.h +1 -0
  240. data/vendor/libgit2/src/libgit2/refdb_fs.c +128 -61
  241. data/vendor/libgit2/src/libgit2/reflog.c +1 -2
  242. data/vendor/libgit2/src/libgit2/reflog.h +2 -0
  243. data/vendor/libgit2/src/libgit2/refs.c +26 -7
  244. data/vendor/libgit2/src/libgit2/refs.h +6 -1
  245. data/vendor/libgit2/src/libgit2/refspec.c +28 -1
  246. data/vendor/libgit2/src/libgit2/refspec.h +8 -0
  247. data/vendor/libgit2/src/libgit2/remote.c +121 -61
  248. data/vendor/libgit2/src/libgit2/repository.c +231 -51
  249. data/vendor/libgit2/src/libgit2/repository.h +10 -6
  250. data/vendor/libgit2/src/libgit2/revert.c +1 -2
  251. data/vendor/libgit2/src/libgit2/revparse.c +2 -2
  252. data/vendor/libgit2/src/libgit2/revwalk.c +13 -10
  253. data/vendor/libgit2/src/libgit2/revwalk.h +3 -3
  254. data/vendor/libgit2/src/libgit2/settings.c +468 -0
  255. data/vendor/libgit2/src/libgit2/settings.h +6 -2
  256. data/vendor/libgit2/src/libgit2/signature.c +132 -15
  257. data/vendor/libgit2/src/libgit2/signature.h +0 -1
  258. data/vendor/libgit2/src/libgit2/status.c +1 -1
  259. data/vendor/libgit2/src/libgit2/streams/mbedtls.c +54 -60
  260. data/vendor/libgit2/src/libgit2/streams/openssl.c +32 -7
  261. data/vendor/libgit2/src/libgit2/streams/openssl.h +2 -0
  262. data/vendor/libgit2/src/libgit2/streams/openssl_dynamic.c +4 -0
  263. data/vendor/libgit2/src/libgit2/streams/openssl_dynamic.h +3 -0
  264. data/vendor/libgit2/src/libgit2/streams/stransport.c +39 -7
  265. data/vendor/libgit2/src/libgit2/submodule.c +106 -63
  266. data/vendor/libgit2/src/libgit2/submodule.h +6 -7
  267. data/vendor/libgit2/src/libgit2/tag.c +1 -1
  268. data/vendor/libgit2/src/libgit2/trailer.c +6 -6
  269. data/vendor/libgit2/src/libgit2/transaction.c +26 -20
  270. data/vendor/libgit2/src/libgit2/transaction.h +4 -1
  271. data/vendor/libgit2/src/libgit2/transport.c +4 -1
  272. data/vendor/libgit2/src/libgit2/transports/credential.c +1 -1
  273. data/vendor/libgit2/src/libgit2/transports/http.c +1 -2
  274. data/vendor/libgit2/src/libgit2/transports/http.h +0 -10
  275. data/vendor/libgit2/src/libgit2/transports/httpclient.c +112 -72
  276. data/vendor/libgit2/src/libgit2/transports/httpparser.c +128 -0
  277. data/vendor/libgit2/src/libgit2/transports/httpparser.h +99 -0
  278. data/vendor/libgit2/src/libgit2/transports/local.c +8 -7
  279. data/vendor/libgit2/src/libgit2/transports/smart.c +20 -8
  280. data/vendor/libgit2/src/libgit2/transports/smart.h +4 -2
  281. data/vendor/libgit2/src/libgit2/transports/smart_pkt.c +2 -2
  282. data/vendor/libgit2/src/libgit2/transports/smart_protocol.c +55 -10
  283. data/vendor/libgit2/src/libgit2/transports/ssh.c +41 -1103
  284. data/vendor/libgit2/src/libgit2/transports/ssh_exec.c +347 -0
  285. data/vendor/libgit2/src/libgit2/transports/ssh_exec.h +26 -0
  286. data/vendor/libgit2/src/libgit2/transports/ssh_libssh2.c +1126 -0
  287. data/vendor/libgit2/src/libgit2/transports/ssh_libssh2.h +28 -0
  288. data/vendor/libgit2/src/libgit2/transports/winhttp.c +35 -7
  289. data/vendor/libgit2/src/libgit2/tree.c +34 -26
  290. data/vendor/libgit2/src/libgit2/tree.h +3 -2
  291. data/vendor/libgit2/src/libgit2/worktree.c +14 -17
  292. data/vendor/libgit2/src/util/CMakeLists.txt +4 -6
  293. data/vendor/libgit2/src/util/alloc.c +4 -1
  294. data/vendor/libgit2/src/util/allocators/debugalloc.c +73 -0
  295. data/vendor/libgit2/src/{cli/cli.h → util/allocators/debugalloc.h} +6 -9
  296. data/vendor/libgit2/src/util/allocators/stdalloc.c +0 -10
  297. data/vendor/libgit2/src/util/array.h +18 -17
  298. data/vendor/libgit2/src/util/cc-compat.h +2 -0
  299. data/vendor/libgit2/src/util/ctype_compat.h +70 -0
  300. data/vendor/libgit2/src/util/date.c +22 -14
  301. data/vendor/libgit2/src/util/date.h +12 -0
  302. data/vendor/libgit2/src/util/errors.c +401 -0
  303. data/vendor/libgit2/src/{libgit2 → util}/errors.h +21 -17
  304. data/vendor/libgit2/src/util/fs_path.c +15 -4
  305. data/vendor/libgit2/src/util/fs_path.h +23 -0
  306. data/vendor/libgit2/src/util/futils.c +6 -5
  307. data/vendor/libgit2/src/util/futils.h +13 -4
  308. data/vendor/libgit2/src/util/git2_features.h.in +12 -1
  309. data/vendor/libgit2/src/util/git2_util.h +6 -0
  310. data/vendor/libgit2/src/util/hash/openssl.c +152 -0
  311. data/vendor/libgit2/src/util/hash/openssl.h +17 -1
  312. data/vendor/libgit2/src/util/hash/sha.h +4 -1
  313. data/vendor/libgit2/src/util/hashmap.h +424 -0
  314. data/vendor/libgit2/src/util/hashmap_str.h +43 -0
  315. data/vendor/libgit2/src/util/integer.h +3 -1
  316. data/vendor/libgit2/src/util/net.c +13 -7
  317. data/vendor/libgit2/src/util/net.h +2 -0
  318. data/vendor/libgit2/src/util/pool.c +1 -1
  319. data/vendor/libgit2/src/util/pool.h +5 -0
  320. data/vendor/libgit2/src/util/pqueue.h +1 -1
  321. data/vendor/libgit2/src/util/process.h +222 -0
  322. data/vendor/libgit2/src/util/rand.c +1 -7
  323. data/vendor/libgit2/src/util/regexp.c +1 -1
  324. data/vendor/libgit2/src/util/sortedcache.c +14 -13
  325. data/vendor/libgit2/src/util/sortedcache.h +3 -3
  326. data/vendor/libgit2/src/util/str.c +2 -2
  327. data/vendor/libgit2/src/util/strlist.c +108 -0
  328. data/vendor/libgit2/src/util/strlist.h +36 -0
  329. data/vendor/libgit2/src/util/unix/posix.h +0 -2
  330. data/vendor/libgit2/src/util/unix/process.c +629 -0
  331. data/vendor/libgit2/src/util/unix/realpath.c +23 -5
  332. data/vendor/libgit2/src/util/util.c +2 -2
  333. data/vendor/libgit2/src/util/util.h +4 -38
  334. data/vendor/libgit2/src/util/vector.c +3 -3
  335. data/vendor/libgit2/src/util/vector.h +2 -2
  336. data/vendor/libgit2/src/util/win32/posix_w32.c +29 -6
  337. data/vendor/libgit2/src/util/win32/process.c +506 -0
  338. metadata +45 -28
  339. data/vendor/libgit2/deps/http-parser/CMakeLists.txt +0 -6
  340. data/vendor/libgit2/deps/http-parser/COPYING +0 -23
  341. data/vendor/libgit2/deps/http-parser/http_parser.c +0 -2182
  342. data/vendor/libgit2/deps/http-parser/http_parser.h +0 -305
  343. data/vendor/libgit2/deps/zlib/COPYING +0 -27
  344. data/vendor/libgit2/include/git2/sys/reflog.h +0 -21
  345. data/vendor/libgit2/src/libgit2/config_entries.c +0 -237
  346. data/vendor/libgit2/src/libgit2/config_entries.h +0 -24
  347. data/vendor/libgit2/src/libgit2/errors.c +0 -293
  348. data/vendor/libgit2/src/libgit2/idxmap.c +0 -157
  349. data/vendor/libgit2/src/libgit2/idxmap.h +0 -177
  350. data/vendor/libgit2/src/libgit2/libgit2.h +0 -15
  351. data/vendor/libgit2/src/libgit2/offmap.c +0 -101
  352. data/vendor/libgit2/src/libgit2/offmap.h +0 -133
  353. data/vendor/libgit2/src/libgit2/oidmap.c +0 -107
  354. data/vendor/libgit2/src/libgit2/oidmap.h +0 -128
  355. data/vendor/libgit2/src/libgit2/threadstate.c +0 -97
  356. data/vendor/libgit2/src/libgit2/threadstate.h +0 -22
  357. data/vendor/libgit2/src/libgit2/transports/ssh.h +0 -14
  358. data/vendor/libgit2/src/util/khash.h +0 -615
  359. data/vendor/libgit2/src/util/strmap.c +0 -100
  360. data/vendor/libgit2/src/util/strmap.h +0 -131
  361. /data/vendor/libgit2/cmake/{FindHTTPParser.cmake → FindHTTP_Parser.cmake} +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