api-channels.texi 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347
  1. @c -*-texinfo-*-
  2. @c This file is part of Guile-SSH Reference Manual.
  3. @c Copyright (C) 2014 Artyom V. Poptsov
  4. @c See the file guile-ssh.texi for copying conditions.
  5. @node Channels
  6. @section Channels
  7. @menu
  8. * Channel Management::
  9. * Port Forwarding::
  10. @end menu
  11. @node Channel Management
  12. @subsection Channel Management
  13. @cindex data transferring
  14. @tindex channel
  15. The @code{(ssh channel)} module provides facilities to create
  16. Guile-SSH channels and manipulating of them.
  17. Channels are implemented as GNU Guile ports. Therefore they can be
  18. used with regular I/O procedures such as @code{display}, @code{write},
  19. @code{read-line} and friends (@pxref{Input and Output,,, guile, The
  20. GNU Guile Reference Manual}). This section describes operations that
  21. are specific for the channels.
  22. @deffn {Scheme Procedure} channel? x
  23. Return @code{#t} if @var{x} is a Guile-SSH channel, @code{#f}
  24. otherwise.
  25. @end deffn
  26. @deffn {Scheme Procedure} make-channel session [mode]
  27. Allocate a new Guile-SSH channel for the @var{session} (@pxref{Sessions}).
  28. @var{flags} are determine what kind of a channel should be created. Possible
  29. modes are: @code{OPEN_READ}, @code{OPEN_WRITE}, @code{OPEN_BOTH}. They allow
  30. to create either an input channel, output channel or input/output channel
  31. respectively.
  32. @end deffn
  33. @deffn {Scheme Procedure} channel-open-session channel
  34. Open a session channel. This procedure actually turn the
  35. @var{channel} into an open port available for I/O operations. Throw
  36. @code{guile-ssh-error} on error. Return value is undefined.
  37. @end deffn
  38. @deffn {Scheme Procedure} channel-request-exec channel command
  39. @cindex non-interactive SSH session
  40. @cindex command execution
  41. Run a shell @var{command} without an interactive shell. The @var{channel}
  42. must be open. Throw @code{guile-ssh-error} on error. Return value is
  43. undefined.
  44. This procedure is a low-level one and you should use remote pipes instead (@pxref{Remote Pipes}).
  45. @strong{Note} that the procedure only can be used to execute a single command
  46. on the remote host, so you should close the channel after
  47. @code{channel-request-exec}. If you want to execute another command then you
  48. must open a new channel and use it.
  49. Example:
  50. @lisp
  51. (let ((channel (make-channel session)))
  52. (channel-open-session channel)
  53. (channel-request-exec channel "uname")
  54. (read-line channel))
  55. @result{} "Linux"
  56. @end lisp
  57. @end deffn
  58. @deffn {Scheme Procedure} channel-request-pty channel
  59. Request a @acronym{PTY} (pseudo terminal). Throw @code{guile-ssh-error} on
  60. error. The @var{channel} must be open. Return value is undefined.
  61. @end deffn
  62. @deffn {Scheme Procedure} channel-request-shell channel
  63. Request a shell. The @var{channel} must be open. Throw
  64. @code{guile-ssh-error} on error. Return value is undefined.
  65. @end deffn
  66. @deffn {Scheme Procedure} channel-request-env channel variable value
  67. @cindex setting of environment variables
  68. Set an environment @var{variable} to @var{value}. Throw
  69. @code{guile-ssh-error} on error. The @var{channel} must be open. Return
  70. value is undefined.
  71. @end deffn
  72. @deffn {Scheme Procedure} channel-request-send-exit-status channel exit-status
  73. Send an @var{exit-status} to the remote process (as described in RFC 4254,
  74. section 6.10). Only SSH-v2 is supported. Return value is undefined.
  75. The @var{channel} needs to be closed with after this message.
  76. @end deffn
  77. @deffn {Scheme Procedure} channel-set-pty-size! channel columns rows
  78. Change size of the @acronym{PTY} to @var{columns} and @var{rows}. The
  79. @var{channel} must be open. Return value is undefined.
  80. @end deffn
  81. @deffn {Scheme Procedure} channel-set-stream! channel stream
  82. Set default @var{stream} for @var{channel}. @var{stream} must be one of the
  83. following symbols: @code{stdout} (default), @code{stderr}. The @var{channel}
  84. must be open. Throw @code{guile-ssh-error} on error. Return value is
  85. undefined.
  86. Example:
  87. @lisp
  88. (channel-set-stream! channel 'stderr)
  89. @end lisp
  90. @end deffn
  91. @deffn {Scheme Procedure} channel-get-stream channel
  92. Get current stream name from @var{channel}. The @var{channel} must be open.
  93. Throw @code{guile-ssh-error} on error. Return one of the following symbols:
  94. @code{stdout}, @code{stderr}.
  95. Example:
  96. @lisp
  97. (channel-get-stream channel)
  98. @result{} 'stderr
  99. @end lisp
  100. @end deffn
  101. @deffn {Scheme Procedure} channel-get-session channel
  102. Get the session to which belongs the @var{channel}. Throw
  103. @code{guile-ssh-error} on an error. Return the session.
  104. @end deffn
  105. @deffn {Scheme Procedure} channel-send-eof channel
  106. Send an end of file (EOF) on the @var{channel}. This action doesn't close the
  107. @var{channel}; you may still read from it but not write. Throw
  108. @code{guile-ssh-error} on an error. Return value is undefined.
  109. Example:
  110. @lisp
  111. (use-modules (ice-9 rdelim)
  112. ;; Guile-SSH modules.
  113. (ssh auth)
  114. (ssh popen)
  115. (ssh session)
  116. (ssh channel))
  117. ;; Make a session
  118. (define s (make-session #:host "example.org"))
  119. ;; Connect to the server
  120. (connect! s)
  121. ;; Authenticate
  122. (userauth-agent! s)
  123. ;; Open a remote pipe to 'wc' command running on
  124. ;; the server.
  125. (let ((p (open-remote-pipe s "wc" OPEN_BOTH)))
  126. ;; Send data to 'wc' command using the remote pipe.
  127. (display "Hello Scheme World!" p)
  128. ;; 'wc' reads data until EOF and writes its result
  129. ;; afterwards.
  130. (channel-send-eof p)
  131. ;; Read the 'wc' output.
  132. (read-line p))
  133. @result{} " 0 3 19"
  134. @end lisp
  135. @end deffn
  136. @deffn {Scheme Procedure} channel-eof? channel
  137. Return @code{#t} if remote has sent @acronym{EOF}, @code{#f} otherwise. Throw
  138. @code{guile-ssh-error} if the channel has been closed and freed.
  139. @end deffn
  140. @deffn {Scheme Procedure} channel-get-exit-status channel
  141. Get the exit status of the @var{channel} (error code from the executed
  142. instruction). The @var{channel} must be open. Return the exist status, or
  143. @code{#f} if no exit status has been returned (yet). Throw
  144. @code{guile-ssh-error} on error.
  145. @end deffn
  146. @node Port Forwarding
  147. @subsection Port Forwarding
  148. @cindex Port forwarding
  149. Low-level API from @code{(ssh channel)} module to manage SSH port
  150. forwarding. These procedures @strong{do not} bind the ports and do not
  151. automatically forward the content of a socket to the channel. You should
  152. either implement binding and data forwarding in your application or use the
  153. tunnel API (@pxref{Tunnels, Guile-SSH tunnel API})
  154. @deffn {Scheme Procedure} channel-open-forward channel [#:source-host=''localhost''] #:local-port #:remote-host [#:remote-port=local-port]
  155. Open a (local) TCP/IP forwarding @var{channel}. Connect to a
  156. @var{remote-host} and @var{remote-port}, and use @var{source-host} and
  157. @var{local-port} as origination of connections.
  158. The procedure returns one of the following symbols:
  159. @table @samp
  160. @item ok
  161. Success.
  162. @item again
  163. We are in the nonblocking mode and the call to be done again.
  164. @item error
  165. An error occured.
  166. @end table
  167. The local port forwarding works as follows:
  168. @example
  169. local-host remote-host
  170. ,..............., ,.................
  171. : : : :
  172. : [a browser] : : [a web server] :
  173. : | : : A :
  174. : | : : | :
  175. : port 8080 : : port 80 :
  176. : | : : | :
  177. : V : : | :
  178. : [SSH client]===========>[SSH server] :
  179. : : : :
  180. '...............' '................'
  181. @end example
  182. Where port 8080 is an arbitrary @var{local-port} and port 80 is a
  183. @var{remote-port}.
  184. Also in our case, ``SSH client'' is an application that uses Guile-SSH and
  185. calls @code{channel-open-forward}.
  186. Example:
  187. @lisp
  188. (channel-open-forward channel
  189. #:local-port 8080
  190. #:remote-host "www.example.org"
  191. #:remote-port 80)
  192. @end lisp
  193. @end deffn
  194. @deffn {Scheme Procedure} channel-listen-forward session [#:address=#f] [#:port=0]
  195. Start a TCP/IP reverse (remote) port forwarding. Send the ``tcpip-forward''
  196. global request using @var{session} to ask the server to begin listening for
  197. inbound connections on the specified @var{address} and @var{port}.
  198. If @var{address} is not specified (or set to @code{#f}) then the server binds
  199. all addresses on all protocol families supported by the server. When 0 is
  200. passed as a @var{port} then server allocates the next unprivileged port.
  201. The procedure returns two values: the first value is the result of the
  202. operation, and the second value is the bound port number; if @var{port} was
  203. set to 0 then the procedure returns the chosen port number.
  204. The result of the operation can be one of the following symbols:
  205. @table @samp
  206. @item ok
  207. Success.
  208. @item again
  209. We are in the nonblocking mode and the call to be done again.
  210. @item error
  211. An error occured.
  212. @end table
  213. Reverse port forwarding looks as follows:
  214. @example
  215. local-host remote-host
  216. ,................, ,.................
  217. : : : :
  218. : [a web server] : : [a browser] :
  219. : A : : | :
  220. : | : : | :
  221. : port 80 : : port 8080 :
  222. : | : : | :
  223. : | : : V :
  224. : [SSH client]<===========[SSH server] :
  225. : : : :
  226. '................' '................'
  227. @end example
  228. @end deffn
  229. @deffn {Scheme Procedure} channel-accept-forward session [timeout=0]
  230. Accept an incoming TCP/IP forwarding channel and get information about
  231. incoming connection. Return two values: the first value is the incoming
  232. channel, and the second value is a port number on which the connection was
  233. issued.
  234. @end deffn
  235. @deffn {Scheme Procedure} channel-cancel-forward session address port
  236. Send ``cancel-tcpip-forward'' global request to @var{session} to ask the
  237. server to cancel a ``tcpip-forward'' request on the bound @var{address} and
  238. @var{port}.
  239. The result of the operation can be one of the following symbols:
  240. @table @samp
  241. @item ok
  242. Success.
  243. @item again
  244. We are in the nonblocking mode and the call to be done again.
  245. @item error
  246. An error occured.
  247. @end table
  248. Here's an example Guile program that uses @code{channel-cancel-forward} to
  249. cancel reverse port forwarding on a server:
  250. @lisp
  251. #!/usr/bin/guile \
  252. -e main
  253. !#
  254. (use-modules (ssh session)
  255. (ssh auth)
  256. (ssh channel))
  257. (define (main args)
  258. (let ((session (make-session #:user "alice"
  259. #:host "127.0.0.1"
  260. #:port 22
  261. #:log-verbosity 'rare)))
  262. (connect! session)
  263. (userauth-agent! session)
  264. ;; Send "tcpip-forward" request to an SSH server
  265. (channel-listen-forward session #:address "localhost" #:port 12345)
  266. ;; Accept incoming reverse port forwarding requests with
  267. ;; 'channel-accept-forward' in some kind of loop...
  268. ;; Cancel the issued "tcpip-forward" request with
  269. ;; "cancel-tcpip-forward" request
  270. (channel-cancel-forward session "localhost" 12345)))
  271. @end lisp
  272. @end deffn
  273. @c Local Variables:
  274. @c TeX-master: "guile-ssh.texi"
  275. @c End: