libssh2.bmx 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557
  1. ' Copyright (c) 2009-2022 Bruce A Henderson
  2. ' All rights reserved.
  3. '
  4. ' Redistribution and use in source and binary forms, with or without
  5. ' modification, are permitted provided that the following conditions are met:
  6. ' * Redistributions of source code must retain the above copyright
  7. ' notice, this list of conditions and the following disclaimer.
  8. ' * Redistributions in binary form must reproduce the above copyright
  9. ' notice, this list of conditions and the following disclaimer in the
  10. ' documentation and/or other materials provided with the distribution.
  11. ' * Neither the auther nor the names of its contributors may be used to
  12. ' endorse or promote products derived from this software without specific
  13. ' prior written permission.
  14. '
  15. ' THIS SOFTWARE IS PROVIDED BY Bruce A Henderson ``AS IS'' AND ANY
  16. ' EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
  17. ' WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  18. ' DISCLAIMED. IN NO EVENT SHALL Bruce A Henderson BE LIABLE FOR ANY
  19. ' DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
  20. ' (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  21. ' LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
  22. ' ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  23. ' (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  24. ' SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  25. '
  26. SuperStrict
  27. Rem
  28. bbdoc: Libssh2
  29. End Rem
  30. Module Net.libssh2
  31. ModuleInfo "Version: 1.04"
  32. ModuleInfo "License: BSD"
  33. ModuleInfo "Copyright: Wrapper - 2009-2022 Bruce A Henderson"
  34. ModuleInfo "History: 1.04"
  35. ModuleInfo "History: Linux build fixes."
  36. ModuleInfo "History: 1.03"
  37. ModuleInfo "History: Update to libssh2 1.10.0"
  38. ModuleInfo "History: Patched to support mbedtls 3.x"
  39. ModuleInfo "History: 1.02"
  40. ModuleInfo "History: Added SFTP support."
  41. ModuleInfo "History: Use mbedtls instead of OpenSSL."
  42. ModuleInfo "History: 1.01"
  43. ModuleInfo "History: Update to libssh2 1.8.0"
  44. ModuleInfo "History: 1.00"
  45. ModuleInfo "History: Initial Release."
  46. ModuleInfo "CC_OPTS: -DLIBSSH2_MBEDTLS"
  47. Import BRL.Socket
  48. Import "common.bmx"
  49. '
  50. ' Notes :
  51. ' libssh2 updated to support mbedtls 3.x (see patches/)
  52. '
  53. Rem
  54. bbdoc: An SSH session object.
  55. End Rem
  56. Type TSSHSession
  57. Field sessionPtr:Byte Ptr
  58. Field interactiveCallback(name:String, instruction:String, prompts:TSSHKeyboardPrompt[], responses:TSSHKeyboardResponse[])
  59. Method New()
  60. sessionPtr = bmx_libssh2_session_create(Self)
  61. End Method
  62. Rem
  63. bbdoc: Indicates whether or not the named session has been successfully authenticated.
  64. returns: True if authenticated and False if not.
  65. End Rem
  66. Method Authenticated:Int()
  67. Return bmx_libssh2_userauth_authenticated(sessionPtr)
  68. End Method
  69. Rem
  70. bbdoc: Tunnels a TCP/IP connection through the SSH transport via the remote host to a third party.
  71. returns: A newly allocated LIBSSH2_CHANNEL instance, or NULL on errors.
  72. about: Communication from the client to the SSH server remains encrypted, communication from the server to the 3rd party host
  73. travels in cleartext.
  74. End Rem
  75. Method DirectTCPIP:TSSHChannel(host:String, port:Int, shost:String = Null, sport:Int = 0)
  76. Return TSSHChannel._create(bmx_libssh2_channel_directtcpip(sessionPtr, host, port, shost, sport))
  77. End Method
  78. Rem
  79. bbdoc: Begins transport layer protocol negotiation with the connected host.
  80. returns: 0 on success, negative on failure.
  81. End Rem
  82. Method Startup:Int(socket:TSocket)
  83. Return bmx_libssh2_session_handshake(sessionPtr, socket._socket)
  84. End Method
  85. Rem
  86. bbdoc: Returns the computed digest of the remote system's hostkey.
  87. returns: Computed hostkey hash value, or NULL if the session has not yet been started up. (The hash consists of raw binary bytes, not hex digits, so is not directly printable.)
  88. about: The length of the returned string is hashType specific (e.g. 16 bytes for MD5, 20 bytes for SHA1).
  89. End Rem
  90. Method HostkeyHash:String(hashType:Int)
  91. ' TODO
  92. End Method
  93. Rem
  94. bbdoc: Sends a disconnect message to the remote host associated with session, along with a verbose description.
  95. returns: 0 on success or negative on failure.
  96. End Rem
  97. Method Disconnect:Int(description:String)
  98. Return bmx_libssh2_session_disconnect(sessionPtr, description)
  99. End Method
  100. Rem
  101. bbdoc: Allocates a new channel for exchanging data with the server.
  102. End Rem
  103. Method OpenChannel:TSSHChannel()
  104. Return TSSHChannel._create(bmx_libssh2_channel_open(sessionPtr))
  105. End Method
  106. Rem
  107. bbdoc: Attempts basic password authentication.
  108. returns: 0 on success or negative on failure. It returns LIBSSH2_ERROR_EAGAIN when it would otherwise block. While LIBSSH2_ERROR_EAGAIN is a negative number, it isn't really a failure per se.
  109. about: Note that many SSH servers which appear to support ordinary password authentication actually have it disabled and use
  110. Keyboard Interactive authentication (routed via PAM or another authentication backed) instead.
  111. End Rem
  112. Method UserAuthPassword:Int(username:String, password:String)
  113. Return bmx_libssh2_userauth_password(sessionPtr, username, password)
  114. End Method
  115. Rem
  116. bbdoc:
  117. End Rem
  118. Method UserAuthKeyboardInteractive:Int(username:String, callback(name:String, instruction:String, ..
  119. prompts:TSSHKeyboardPrompt[], responses:TSSHKeyboardResponse[]))
  120. interactiveCallback = callback
  121. Return bmx_libssh2_userauth_keyboard_interactive(sessionPtr, username)
  122. End Method
  123. Function _kbdCallback(session:TSSHSession, name:String, instruction:String, ..
  124. prompts:TSSHKeyboardPrompt[], responses:TSSHKeyboardResponse[]) { nomangle }
  125. session.interactiveCallback(name, instruction, prompts, responses)
  126. End Function
  127. Function _newPrompts:TSSHKeyboardPrompt[](size:Int) { nomangle }
  128. Return New TSSHKeyboardPrompt[size]
  129. End Function
  130. Function _setPrompt(prompts:TSSHKeyboardPrompt[], index:Int, promptPtr:Byte Ptr) { nomangle }
  131. prompts[index] = TSSHKeyboardPrompt._create(promptPtr)
  132. End Function
  133. Function _newResponses:TSSHKeyboardResponse[](size:Int) { nomangle }
  134. Return New TSSHKeyboardResponse[size]
  135. End Function
  136. Function _setResponse(responses:TSSHKeyboardResponse[], index:Int, responsePtr:Byte Ptr) { nomangle }
  137. responses[index] = TSSHKeyboardResponse._create(responsePtr)
  138. End Function
  139. Rem
  140. bbdoc: Opens SFTP channel for the given SSH session.
  141. End Rem
  142. Method SftpInit:TSSHSftp()
  143. Return TSSHSftp._create(bmx_libssh2_sftp_init(sessionPtr))
  144. End Method
  145. Rem
  146. bbdoc: Frees resources associated with the session instance.
  147. about: Typically called after Disconnect().
  148. End Rem
  149. Method Free()
  150. If sessionPtr Then
  151. bmx_libssh2_session_free(sessionPtr)
  152. sessionPtr = Null
  153. End If
  154. End Method
  155. Method Delete()
  156. Free()
  157. End Method
  158. End Type
  159. Rem
  160. bbdoc:
  161. End Rem
  162. Type TSSHChannel
  163. Field channelPtr:Byte Ptr
  164. Function _create:TSSHChannel(channelPtr:Byte Ptr)
  165. If channelPtr Then
  166. Local this:TSSHChannel = New TSSHChannel
  167. this.channelPtr = channelPtr
  168. Return this
  169. End If
  170. End Function
  171. Rem
  172. bbdoc: Sets an environment variable in the remote channel's process space.
  173. about: Note that this does not make sense for all channel types and may be ignored by the server despite returning success.
  174. End Rem
  175. Method SetEnv:Int(name:String, value:String)
  176. Return bmx_libssh2_channel_setenv(channelPtr, name, value)
  177. End Method
  178. Rem
  179. bbdoc: Requests a PTY on an established channel.
  180. about: Note that this does not make sense for all channel types and may be ignored by the server despite returning success.
  181. End Rem
  182. Method RequestPty:Int(term:String)
  183. Return bmx_libssh2_channel_requestpty(channelPtr, term)
  184. End Method
  185. Rem
  186. bbdoc: Initiates a shell request.
  187. End Rem
  188. Method shell:Int()
  189. Return bmx_libssh2_channel_shell(channelPtr)
  190. End Method
  191. Rem
  192. bbdoc: Checks if the remote host has sent an EOF status for the selected stream.
  193. End Rem
  194. Method Eof:Int()
  195. Return bmx_libssh2_channel_eof(channelPtr)
  196. End Method
  197. Rem
  198. bbdoc: Initiates an exec request.
  199. End Rem
  200. Method Exec:Int(message:String)
  201. Return bmx_libssh2_channel_exec(channelPtr, message)
  202. End Method
  203. Rem
  204. bbdoc: Returns the exit code raised by the process running on the remote host at the other end of the named channel.
  205. returns: 0 on failure, otherwise the Exit Status reported by remote host.
  206. about: Note that the exit status may not be available if the remote end has not yet set its status to closed.
  207. End Rem
  208. Method GetExitStatus:Int()
  209. Return bmx_libssh2_channel_getexitstatus(channelPtr)
  210. End Method
  211. Rem
  212. bbdoc: Initiates a subsystem request.
  213. End Rem
  214. Method Subsystem:Int(message:String)
  215. Return bmx_libssh2_channel_subsystem(channelPtr, message)
  216. End Method
  217. Rem
  218. bbdoc: Checks to see if data is available in the channel's read buffer.
  219. returns: True when data is available and False otherwise.
  220. about: No attempt is made with this method to see if packets are available to be processed.
  221. End Rem
  222. Method PollRead:Int(extended:Int)
  223. Return bmx_libssh2_channel_pollread(channelPtr, extended)
  224. End Method
  225. Rem
  226. bbdoc: Initiates a request on the channel.
  227. about: The SSH2 protocol currently defines shell, exec, and subsystem as standard process services.
  228. End Rem
  229. Method ProcessStartup:String(request:String, message:String)
  230. Return bmx_libssh2_channel_processstartup(channelPtr, request, message)
  231. End Method
  232. Rem
  233. bbdoc: Attempts to read data from an active channel stream.
  234. returns: Actual number of bytes read or negative on failure. It returns LIBSSH2_ERROR_EAGAIN when it would otherwise block. While LIBSSH2_ERROR_EAGAIN is a negative number, it isn't really a failure per se.
  235. End Rem
  236. Method Read:Int(buffer:Byte Ptr, size:Int)
  237. Return bmx_libssh2_channel_read(channelPtr, buffer, size)
  238. End Method
  239. Rem
  240. bbdoc: Attempts to read data from the stderr substream.
  241. returns: Actual number of bytes read or negative on failure. It returns LIBSSH2_ERROR_EAGAIN when it would otherwise block. While LIBSSH2_ERROR_EAGAIN is a negative number, it isn't really a failure per se.
  242. End Rem
  243. Method ReadStderr:Int(buffer:Byte Ptr, size:Int)
  244. Return bmx_libssh2_channel_read_stderr(channelPtr, buffer, size)
  245. End Method
  246. Rem
  247. bbdoc: Tells the remote host that no further data will be sent on the specified channel.
  248. returns: 0 on success or negative on failure. It returns LIBSSH2_ERROR_EAGAIN when it would otherwise block. While LIBSSH2_ERROR_EAGAIN is a negative number, it isn't really a failure per se.
  249. about: Processes typically interpret this as a closed stdin descriptor.
  250. End Rem
  251. Method SendEof:Int()
  252. Return bmx_libssh2_channel_sendeof(channelPtr)
  253. End Method
  254. Rem
  255. bbdoc: Sets or clears blocking mode on channel.
  256. about: Currently this is just a short cut call to TSSHSession::SetBlocking() and therefore will affect the session and all channels.
  257. End Rem
  258. Method SetBlocking(blocking:Int)
  259. bmx_libssh2_channel_set_blocking(channelPtr, blocking)
  260. End Method
  261. Rem
  262. bbdoc: Enters a temporary blocking state until the remote host closes the named channel.
  263. returns: 0 on success or negative on failure. It returns LIBSSH2_ERROR_EAGAIN when it would otherwise block. While LIBSSH2_ERROR_EAGAIN is a negative number, it isn't really a failure per se.
  264. about: Typically sent after TSSHChannel.Close() in order to examine the exit status.
  265. End Rem
  266. Method WaitClosed:Int()
  267. Return bmx_libssh2_channel_waitclosed(channelPtr)
  268. End Method
  269. Rem
  270. bbdoc: Waits for the remote end to acknowledge an EOF request.
  271. returns: 0 on success or negative on failure. It returns LIBSSH2_ERROR_EAGAIN when it would otherwise block. While LIBSSH2_ERROR_EAGAIN is a negative number, it isn't really a failure per se.
  272. End Rem
  273. Method WaitEof:Int()
  274. Return bmx_libssh2_channel_waiteof(channelPtr)
  275. End Method
  276. Rem
  277. bbdoc: Writes data to a channel stream.
  278. returns: Actual number of bytes written or negative on failure. LIBSSH2_ERROR_EAGAIN when it would otherwise block. While LIBSSH2_ERROR_EAGAIN is a negative number, it isn't really a failure per se.
  279. End Rem
  280. Method Write:Int(buffer:Byte Ptr, size:Int)
  281. Return bmx_libssh2_channel_write(channelPtr, buffer, size)
  282. End Method
  283. Rem
  284. bbdoc: Writes data to the stderr substream.
  285. returns: Actual number of bytes written or negative on failure. LIBSSH2_ERROR_EAGAIN when it would otherwise block. While LIBSSH2_ERROR_EAGAIN is a negative number, it isn't really a failure per se.
  286. End Rem
  287. Method WriteStderr:Int(buffer:Byte Ptr, size:Int)
  288. Return bmx_libssh2_channel_write_stderr(channelPtr, buffer, size)
  289. End Method
  290. Rem
  291. bbdoc:
  292. End Rem
  293. Method Free()
  294. If channelPtr Then
  295. bmx_libssh2_channel_free(channelPtr)
  296. channelPtr = Null
  297. End If
  298. End Method
  299. Method Delete()
  300. Free()
  301. End Method
  302. End Type
  303. Rem
  304. bbdoc:
  305. End Rem
  306. Type TSSHKeyboardResponse
  307. Field responsePtr:Byte Ptr
  308. Function _create:TSSHKeyboardResponse(responsePtr:Byte Ptr)
  309. If responsePtr Then
  310. Local this:TSSHKeyboardResponse = New TSSHKeyboardResponse
  311. this.responsePtr = responsePtr
  312. Return this
  313. End If
  314. End Function
  315. Rem
  316. bbdoc:
  317. End Rem
  318. Method SetText(text:String)
  319. bmx_libssh2_kbdint_response_settext(responsePtr, text)
  320. End Method
  321. End Type
  322. Rem
  323. bbdoc:
  324. End Rem
  325. Type TSSHKeyboardPrompt
  326. Field promptPtr:Byte Ptr
  327. Function _create:TSSHKeyboardPrompt(promptPtr:Byte Ptr)
  328. If promptPtr Then
  329. Local this:TSSHKeyboardPrompt = New TSSHKeyboardPrompt
  330. this.promptPtr = promptPtr
  331. Return this
  332. End If
  333. End Function
  334. Rem
  335. bbdoc:
  336. End Rem
  337. Method GetText:String()
  338. Return bmx_libssh2_kbdint_prompt_gettext(promptPtr)
  339. End Method
  340. Rem
  341. bbdoc:
  342. End Rem
  343. Method Echo:Int()
  344. Return bmx_libssh2_kbdint_prompt_echo(promptPtr)
  345. End Method
  346. End Type
  347. Rem
  348. bbdoc: An SFTP channel.
  349. End Rem
  350. Type TSSHSftp
  351. Field sftpPtr:Byte Ptr
  352. Function _create:TSSHSftp(sftpPtr:Byte Ptr)
  353. If sftpPtr Then
  354. Local this:TSSHSftp = New TSSHSftp
  355. this.sftpPtr = sftpPtr
  356. Return this
  357. End If
  358. End Function
  359. Rem
  360. bbdoc:
  361. End Rem
  362. Method Mkdir:Int(path:String, mode:Int)
  363. Return bmx_libssh2_sftp_mkdir(sftpPtr, path, mode)
  364. End Method
  365. Rem
  366. bbdoc:
  367. End Rem
  368. Method Rmdir:Int(path:String)
  369. Return bmx_libssh2_sftp_rmdir(sftpPtr, path)
  370. End Method
  371. Rem
  372. bbdoc: Renames a filesystem object on the remote filesystem.
  373. returns: 0 on success or negative on failure. It returns @LIBSSH2_ERROR_EAGAIN when it would otherwise block. While @LIBSSH2_ERROR_EAGAIN is a negative number, it isn't really a failure per se.
  374. about: The semantics of this command typically include the ability to move a filesystem object between folders
  375. and/or filesystem mounts. If the LIBSSH2_SFTP_RENAME_OVERWRITE flag is not set and the destfile entry already
  376. exists, the operation will fail. Use of the other two flags indicate a preference (but not a requirement) for
  377. the remote end to perform an atomic rename operation and/or using native system calls when possible.
  378. End Rem
  379. Method Rename:Int(source:String, dest:String, flags:Int)
  380. Return bmx_libssh2_sftp_rename(sftpPtr, source, dest, flags)
  381. End Method
  382. Rem
  383. bbdoc:
  384. End Rem
  385. Method GetChannel:TSSHChannel()
  386. Return TSSHChannel._create(bmx_libssh2_sftp_get_channel(sftpPtr))
  387. End Method
  388. Rem
  389. bbdoc:
  390. End Rem
  391. Method LastError:Int()
  392. Return bmx_libssh2_sftp_last_error(sftpPtr)
  393. End Method
  394. Rem
  395. bbdoc:
  396. End Rem
  397. Method OpenFile:TSSHSftpHandle(filename:String, flags:Int, mode:Int)
  398. Return TSSHSftpHandle._create(bmx_libssh2_sftp_open(sftpPtr, filename, flags, mode, LIBSSH2_SFTP_OPENFILE))
  399. End Method
  400. Rem
  401. bbdoc:
  402. End Rem
  403. Method OpenDir:TSSHSftpHandle(dirname:String, flags:Int, mode:Int)
  404. Return TSSHSftpHandle._create(bmx_libssh2_sftp_open(sftpPtr, dirname, flags, mode, LIBSSH2_SFTP_OPENDIR))
  405. End Method
  406. Rem
  407. bbdoc:
  408. End Rem
  409. Method Shutdown:Int()
  410. If sftpPtr Then
  411. Local res:Int = bmx_libssh2_sftp_shutdown(sftpPtr)
  412. sftpPtr = Null
  413. Return res
  414. End If
  415. End Method
  416. Method Delete()
  417. Shutdown()
  418. End Method
  419. End Type
  420. Rem
  421. bbdoc: A filehandle for the remote file.
  422. End Rem
  423. Type TSSHSftpHandle
  424. Field handlePtr:Byte Ptr
  425. Function _create:TSSHSftpHandle(handlePtr:Byte Ptr)
  426. If handlePtr Then
  427. Local this:TSSHSftpHandle = New TSSHSftpHandle
  428. this.handlePtr = handlePtr
  429. Return this
  430. End If
  431. End Function
  432. Rem
  433. bbdoc:
  434. End Rem
  435. Method Read:Size_T(buf:Byte Ptr, length:Size_T)
  436. Return bmx_libssh2_sftp_read(handlePtr, buf, length)
  437. End Method
  438. Rem
  439. bbdoc:
  440. End Rem
  441. Method Write:Size_T(buf:Byte Ptr, count:Size_T)
  442. Return bmx_libssh2_sftp_write(handlePtr, buf, count)
  443. End Method
  444. Rem
  445. bbdoc:
  446. End Rem
  447. Method Tell:Size_T()
  448. Return bmx_libssh2_sftp_tell(handlePtr)
  449. End Method
  450. Rem
  451. bbdoc:
  452. End Rem
  453. Method Fsync:Int()
  454. Return bmx_libssh2_sftp_fsync(handlePtr)
  455. End Method
  456. Rem
  457. bbdoc:
  458. End Rem
  459. Method Seek(offset:Long)
  460. bmx_libssh2_sftp_seek64(handlePtr, offset)
  461. End Method
  462. Rem
  463. bbdoc:
  464. End Rem
  465. Method Close:Int()
  466. Return bmx_libssh2_sftp_close_handle(handlePtr)
  467. End Method
  468. End Type