Compare commits

..

73 Commits

Author SHA1 Message Date
Daniel Stenberg
98b0afdab8 release 1.1 2009-04-02 08:49:29 +00:00
Daniel Stenberg
5a3da233ec Sofian Brabez removed duplicate calls to libssh2_session_set_blocking() 2009-03-31 12:20:36 +00:00
Daniel Stenberg
74f4b7817b Uh, it is important that we don't set the local state 'local.close' to TRUE
until _after_ we're done as otherwise we might not get called again properly
to clean the entire thing since the close state is checked in
libssh2_channel_free
2009-03-31 08:52:25 +00:00
Daniel Stenberg
9ba11a374c Removed the trace output that said "May block until packet of type..." since
it simply wasn't true for non-blocking operations.
2009-03-30 09:19:49 +00:00
Daniel Stenberg
117b95e6e3 made sure the SFTP code makes more use of internal non-blocking functions
instead of the external API entries
2009-03-29 22:09:29 +00:00
Daniel Stenberg
60ee30b6c9 Fixed the memory leak in in libssh2_userauth_hostbased_fromfile_ex() that
Jean-Louis Charton found. Additional minor indent and comment edits.
2009-03-28 21:31:53 +00:00
Daniel Stenberg
55744f8f34 indent changes and removed libssh2_ prefix from static function 2009-03-28 21:22:16 +00:00
Yang Tse
8f78a935ca include libssh2_priv.h instead of libssh2.h in order to get
LIBSSH2_API properly defined on LIBSSH2_WIN32 build targets
2009-03-28 12:50:34 +00:00
Daniel Stenberg
75d5830490 Additional non-blocking fixes. 2009-03-27 22:24:09 +00:00
Daniel Stenberg
103a6e9e0b Me and my long fingers couldn't resist "merging" these statements in a previous
commit but of course that broke functionality and this is a revert of that
change.
2009-03-27 21:52:49 +00:00
Daniel Stenberg
76dab196b1 Dump to stderr simply because the other tracing functions in misc.c already
use stderr and mixing output "channels" causes too much confusion for me!
2009-03-27 21:51:43 +00:00
Daniel Stenberg
4353711127 fixed sftp_shutdown() for the blockiness and fixed libssh2_channel_close()
to work properly non-blocking
2009-03-27 20:20:48 +00:00
Daniel Stenberg
ad8b49b208 Fixed the order of the check in the BLOCK_ADJUST() macro so that it also works
for libssh2_session_free()
2009-03-27 12:48:03 +00:00
Daniel Stenberg
1d2bd301d3 kill warnings 2009-03-27 09:52:19 +00:00
Daniel Stenberg
5936d9ce4e Fix the BLOCK_ADJUST_ERRNO() macro to behave properly in blocking mode. 2009-03-27 09:37:48 +00:00
Simon Josefsson
de0c4159bf Add AC_CONFIG_MACRO_DIR to avoid warnings with libtool v2.2.x. 2009-03-27 08:54:15 +00:00
Daniel Stenberg
f390c8e02d fix comments, moved to htonu64 function to sftp.c and made it static 2009-03-27 07:03:00 +00:00
Daniel Stenberg
9df891e412 More cleaning up converting libssh2_ to _libssh2_ for internal functions and
removing libssh2_ from static functions. Added mac.h.
2009-03-26 22:25:23 +00:00
Daniel Stenberg
fc28f33384 comp.c only as a single _libssh2_ function, no external one 2009-03-26 22:09:35 +00:00
Daniel Stenberg
eabe072496 * Renamed the functions in src/transport.c to be _libssh2_transport_ prefixed
and introduced a transport.h header.

* Fixed the blocking mode to only change behavior not the actual underlying
  socket mode so we now always work with non-blocking sockets. This also
  introduces a new rule of thumb in libssh2 code: we don't call the
  external function calls internally. We use the internal (non-blocking)
  ones!

* libssh2_channel_receive_window_adjust2 was added and
  libssh2_channel_receive_window_adjust is now deprecated

* Introduced "local" header files with prototypes etc for different parts
  instead of cramming everything into libssh2_priv.h. channel.h is the
  first.
2009-03-26 15:41:14 +00:00
Daniel Stenberg
239bdffb59 avoid some busy-looping 2009-03-25 22:52:32 +00:00
Daniel Stenberg
bab3a30220 one function to remove, one proto to correct 2009-03-23 13:54:16 +00:00
Daniel Stenberg
2e548c1ca0 Updated comments and removed "libssh2_" prefixes from static functions 2009-03-23 13:35:20 +00:00
Daniel Stenberg
1e1ba6219e added basic docs 2009-03-23 13:20:48 +00:00
Daniel Stenberg
27d74a7bd5 quite possibly one of the most pointless functions in the libssh2 API...a 2009-03-23 13:17:49 +00:00
Daniel Stenberg
3d97a87669 ENOTCONN obviously doesn't exist in win32 so don't try to map that 2009-03-23 13:08:17 +00:00
Daniel Stenberg
022cac8510 [no comment] 2009-03-23 12:53:50 +00:00
Daniel Stenberg
d187a0fdb6 EEK revert the part of the previous commit that was just my non-functional
attempts to make things work with blocking sockets.
2009-03-23 12:51:53 +00:00
Daniel Stenberg
1936d167d1 I cut out the poll_socket argument from the protos for_libssh2_packet_askv()
and _libssh2_packet_ask() since they are internal and nothing in the code base
uses that functionality == simplicity with no drawbacks!
2009-03-23 12:43:59 +00:00
Daniel Stenberg
26b65e06b1 pass in unsigned ints for u32 values and not longs 2009-03-19 12:54:58 +00:00
Daniel Stenberg
468272d648 - (Mar 19 2009) Daniel Stenberg: based on a patch by "E L" we now use errno
properly after recv() and send() calls (that internally are now known as
  _libssh2_recv() and _libssh2_send()) so that the API and more works fine on
  windows too!
2009-03-19 12:45:59 +00:00
Daniel Stenberg
563f627647 I'm upgrading myself! 2009-03-18 13:11:28 +00:00
Simon Josefsson
872a6e28dc Add StrictModes=no to work around cygwin problem.
Reported by Yang Tse <yangsita@gmail.com>.
2009-03-17 19:07:35 +00:00
Simon Josefsson
fa5509d9f2 Add UsePrivilegeSeparation=no for cygwin.
Reported by Yang Tse <yangsita@gmail.com>
2009-03-17 17:25:42 +00:00
Daniel Stenberg
53ad07633e re-indented for clarity 2009-03-17 14:58:24 +00:00
Daniel Stenberg
0b7f20566c re-indented _libssh2_channel_packet_data_len() somewhat to make the huge
condition somewhat easier on the eye
2009-03-17 14:44:38 +00:00
Daniel Stenberg
cc5e952fa0 A cleanup effort: libssh2_ prefixes only on external APIs. Use _libssh2_ prefix
for library-wide internal functions. Don't use any of those on static functions.
I also did some comments and whitespace changes.
2009-03-17 13:48:35 +00:00
Daniel Stenberg
f2fa02c575 bump packet default size to 32768 2009-03-17 12:09:53 +00:00
Daniel Stenberg
0dbc6ed8b6 Refer to the exact symbol name, which also is the exact file name of the man
page file.
2009-03-17 10:34:27 +00:00
Simon Josefsson
c7a1d30590 Use libtool -export-symbols-regex to reduce numer of exported symbols. 2009-03-17 10:19:54 +00:00
Daniel Stenberg
8096b459d4 cleanup round 2009-03-16 23:25:14 +00:00
Daniel Stenberg
7ef3406b57 Added (templates for) the 13 missing man pages 2009-03-16 15:00:45 +00:00
Daniel Stenberg
d870042496 two more renaming of man pages to the actual function name 2009-03-16 14:40:37 +00:00
Daniel Stenberg
27355c740f rename the man page to use the same name as the actual function 2009-03-16 14:28:37 +00:00
Daniel Stenberg
f8ad00e6ae mention the basic changes in my previous few commits 2009-03-16 08:23:54 +00:00
Daniel Stenberg
94090cf55c Patch from bug report #1960894 by "Heiner" applied, and edited by me. It makes
SCP recv and send deal with file names containing spaces (and other
shell-special letters) by quoting them before they are passed to the remote
server.
2009-03-15 23:28:25 +00:00
Daniel Stenberg
ce9d44a3ff fixed some wrong comments and did a minor code edit and some further
whitespace changes
2009-03-15 23:07:09 +00:00
Daniel Stenberg
a678dbac06 added three more public functions I found lacking man pages 2009-03-15 22:59:46 +00:00
Daniel Stenberg
0812744424 fix a compiler warning 2009-03-15 22:40:11 +00:00
Daniel Stenberg
f56b8ef605 simplified how the "scp" command line is created in the libssh2_scp_recv()
function
2009-03-15 22:38:47 +00:00
Daniel Stenberg
1a630c5c09 Simplified libssh2_channel_read_ex() and made it send window adjustments less
frequent, use a few less struct fields in the channel struct and improved
reading from the network with libssh2_packet_read(). I also modified the
windowing algorithm and now use a much larger window. This greatly enhances
SSH/SCP performance. I also increased the size of the buffer the transport
layer uses from 4k to 16K.
2009-03-15 22:29:23 +00:00
Daniel Stenberg
3793b6768d oops, use %06d for the microseconds! 2009-03-14 23:04:25 +00:00
Daniel Stenberg
269bd5e9a4 re-indented and other whitespace edits 2009-03-14 22:29:48 +00:00
Daniel Stenberg
d7566e5065 improved trace logs with time stamps 2009-03-14 22:29:28 +00:00
Daniel Stenberg
bdd005a5e5 fixed to work quite similar to the sftp_nonblock example so that it waits
for the socket correctly and measures the transfer speed fine
2009-03-14 09:40:57 +00:00
Daniel Stenberg
a52f5d3b7e Cleanups, that do seem to have boosted SFTP download performance up to 300% in
some tests:

  * cut off "_ex" from several internal function names

  * corrected some log outputs

  * simplified libssh2_channel_read_ex() and made it much faster in the process

  * cut out {{{ and }}} comments that were incorrect anyway

  * fixed sftp_packet_ask() to return the correct packet by using memcmp() and
    not strncmp()

  * fixed mkdir()'s wait for packet to use the correct request_id - it
    semi-worked previously because strncmp() in sftp_packet_ask() made it
    match far too easily.

  * took away the polling functionality from sftp_packet_ask() since it wasn't
    used
2009-03-13 22:15:27 +00:00
Daniel Stenberg
d89782d99f improved non-blocking behavior for some of the initing stuff before the actual
data transfer begins
2009-03-13 22:14:47 +00:00
Daniel Stenberg
2ba8db9168 wait for socket action accordingly, and do some measurements on the transfer
to make this better to use for speed tests
2009-03-13 12:35:13 +00:00
Daniel Stenberg
5f32304805 - (Mar 7 2009) Olivier Hervieu pointed out a flaw in the
libssh2_channel_x11_req_ex() function that made it produce a crappy random
  chunk of data. Peter Stuge improved the fix to not do out-of-boundary
  writes. I (Daniel Stenberg) replaced the snprintf() with a plain sprintf()
  since the size argument wasn't adding anything anyway.
2009-03-07 22:08:05 +00:00
Guenter Knauf
16941e1fcf some minor Makefile tweaks. 2009-03-06 07:25:37 +00:00
Daniel Stenberg
663da93b42 - Added libssh2_version() 2009-02-23 16:22:46 +00:00
Daniel Stenberg
1addcbbf53 - (Feb 20 2009) libssh2_channel_direct_tcpip_ex() bug #1902169 fixed, which
caused it to fail when called a second time.
2009-02-20 16:14:45 +00:00
Mikhail Gusarov
d722e09196 Fixed dash-as-minus warning in libssh2_base64_decode.3 manpage 2009-02-17 16:22:51 +00:00
Mikhail Gusarov
317740415a Fixed syntax error in libssh2_banner_set.3 manpage 2009-02-17 16:22:17 +00:00
Simon Josefsson
558de5e103 Bump ABI revision from 1.0.0 to 1.0.1 due to code changes. 2009-02-16 21:49:31 +00:00
Simon Josefsson
74aad1869d Fix typo. 2009-02-16 21:48:22 +00:00
Simon Josefsson
b9de72732b Add date for v1.0 release. 2009-02-16 21:46:40 +00:00
Daniel Stenberg
c672b837f8 - (Feb 12 2009) Romain Bondue extended Markus Moeller fix from Feb 8, based on
a previous (uncommitted) patch by Erik Brossler. It improves
  libssh2_channel_write_ex in blocking situations when the socket is set non-
  blocking.
2009-02-12 11:46:28 +00:00
Daniel Stenberg
c547e07caa Markus Moeller fixed a flaw in libssh2_channel_write_ex() that would occur
on EAGAIN situations.
2009-02-08 12:09:20 +00:00
Daniel Stenberg
6a78a6b358 I want to remove all those macros from the official API at next soname bump 2009-01-01 22:52:46 +00:00
Daniel Stenberg
369fcddb24 fixed compiler warnings, and stripped off "libssh2_" from static functions
as that makes shorter function names and then making the code look fine within
80 columns is easier!
2009-01-01 22:47:06 +00:00
Daniel Stenberg
97fbb77da5 made the three public headers use (mostly) lines shorter than 80 columns as
HACKING says - it makes them much more readable to my old tired eyes...
2009-01-01 22:27:08 +00:00
Daniel Stenberg
acc2c5dfb9 we're actually working on the 1.0.1 version now (or should it be 1.1?) 2008-12-28 21:01:36 +00:00
105 changed files with 5033 additions and 3001 deletions

View File

@@ -1,12 +1,11 @@
* Sara Golemon: Author / Project Manager
* Daniel Stenberg: Co-maintainer
* James Housleys: Nonblocking conversion
* Simon Josefsson: libgcrypt support
* Daniel Stenberg: Nonblocking fixes, Build Improvements, and Daily snapshot
artist
* Mikhail Gusarov: Keyboard Interactive Authentication
* Wez Furlong & Edink Kadribasic: Windows Port

96
NEWS
View File

@@ -1,5 +1,97 @@
Version 1.0 ( )
-------------------------------
Version 1.1 (April 2, 2009)
---------------------------
- (Mar 28 2009) Daniel Stenberg:
Jean-Louis Charton found a memory leak in
libssh2_userauth_hostbased_fromfile_ex()
- (Mar 25 2009) Daniel Stenberg:
* Renamed the functions in src/transport.c to be _libssh2_transport_ prefixed
and introduced a transport.h header.
* Fixed the blocking mode to only change behavior not the actual underlying
socket mode so we now always work with non-blocking sockets. This also
introduces a new rule of thumb in libssh2 code: we don't call the
external function calls internally. We use the internal (non-blocking)
ones!
* libssh2_channel_receive_window_adjust2 was added and
libssh2_channel_receive_window_adjust is now deprecated
* Introduced "local" header files with prototypes etc for different parts
instead of cramming everything into libssh2_priv.h. channel.h is the
first.
- (Mar 19 2009) Daniel Stenberg: based on a patch by "E L" we now use errno
properly after recv() and send() calls (that internally are now known as
_libssh2_recv() and _libssh2_send()) so that the API and more works fine on
windows too!
- (Mar 17 2009) Simon Josefsson:
Added a Libtool -export-symbols-regex flag to reduce the number of
exported symbols in shared libraries. Reported by Mikhail Gusarov.
- (Mar 16 2009) Daniel Stenberg:
I renamed a few man pages to match the exact name of the functions they
describe. I also added template versions for the 13 functions that
previously lacked man pages. While these don't contain any docs just yet, it
will now be easier to add the info as the foundation is there!
- (Mar 15 2009) Daniel Stenberg:
* libssh2_channel_read_ex() was simplified and enhanced. It now adjusts the
window less frequent and uses much larger window that now allows MUCH
faster transfers.
* SCP send/recv now allow file names with whitespaces etc, thanks to a patch
by Heiner Steven
- (Mar 13 2009) Daniel Stenberg: Cleanups, that do seem to have boosted SFTP
download performance up to 300% in some tests:
* cut off "_ex" from several internal function names
* corrected some log outputs
* simplified libssh2_channel_read_ex() and made it much faster in the process
* cut out {{{ and }}} comments that were incorrect anyway
* fixed sftp_packet_ask() to return the correct packet by using memcmp() and
not strncmp()
* fixed mkdir()'s wait for packet to use the correct request_id - it
semi-worked previously because strncmp() in sftp_packet_ask() made it
match far too easily.
* took away the polling functionality from sftp_packet_ask() since it wasn't
used
- (Mar 7 2009) Olivier Hervieu pointed out a flaw in the
libssh2_channel_x11_req_ex() function that made it produce a crappy random
chunk of data. Peter Stuge improved the fix to not do out-of-boundary
writes. I (Daniel Stenberg) replaced the snprintf() with a plain sprintf()
since the size argument wasn't adding anything anyway.
- (Feb 23 2009) Added libssh2_version()
- (Feb 20 2009) libssh2_channel_direct_tcpip_ex() bug #1902169 fixed, which
caused it to fail when called a second time.
- (Feb 12 2009) Romain Bondue extended Markus Moeller fix from Feb 8, based on
a previous (uncommitted) patch by Erik Brossler. It improves
libssh2_channel_write_ex in blocking situations when the socket is set non-
blocking.
- (Feb 8 2009) Markus Moeller fixed a flaw in libssh2_channel_write_ex() that
would occur on EAGAIN situations.
Version 1.0 (December 26 2008)
------------------------------
- (Dec 20 2008) Based on Alexander Lamaison's patch, there's now a new
function called libssh2_sftp_tell64() that returns the 64 bit file offset,

14
TODO
View File

@@ -13,8 +13,6 @@ Things TODO
libssh2_publickey_list_free
libssh2_publickey_remove_ex
libssh2_publickey_shutdown
libssh2_session_flag
libssh2_session_get_blocking
libssh2_userauth_hostbased_fromfile_ex
* Decrease the number of mallocs. Everywhere.
@@ -23,8 +21,18 @@ Things TODO
* Extend the test suite to actually test lots of aspects of libssh2
* libssh2_channel_receive_window_adjust() can return EAGAIN while documented
to return the window as an "unsigned long".
At next SONAME bump
===================
* remove libssh2_base64_decode() from the API/ABI
* stop using #defined macros as part of the official API. The macros should
either be turned into real functions or discarded from the API.
* remove the following functions from the API/ABI
libssh2_base64_decode()
libssh2_session_flag()
libssh2_channel_handle_extended_data()
libssh2_channel_receive_window_adjust()

View File

@@ -1,5 +1,6 @@
# AC_PREREQ(2.57)
AC_INIT(libssh2, [-], libssh2-devel@lists.sourceforge.net)
AC_CONFIG_MACRO_DIR([m4])
AC_CONFIG_SRCDIR([src])
AC_CONFIG_HEADER([src/libssh2_config.h])
AM_MAINTAINER_MODE

View File

@@ -1,4 +1,4 @@
# $Id: Makefile.am,v 1.31 2008/12/26 07:46:45 bagder Exp $
# $Id: Makefile.am,v 1.37 2009/03/26 15:41:15 bagder Exp $
EXTRA_DIST = template.3
@@ -18,12 +18,16 @@ dist_man_MANS = \
libssh2_channel_open_ex.3 \
libssh2_channel_process_startup.3 \
libssh2_channel_read_ex.3 \
libssh2_channel_receive_window_adjust.3 \
libssh2_channel_receive_window_adjust2.3 \
libssh2_channel_request_pty_ex.3 \
libssh2_channel_send_eof.3 \
libssh2_channel_set_blocking.3 \
libssh2_channel_setenv_ex.3 \
libssh2_channel_wait_eof.3 \
libssh2_channel_wait_closed.3 \
libssh2_channel_window_read_ex.3 \
libssh2_channel_window_write_ex.3 \
libssh2_channel_write_ex.3 \
libssh2_channel_x11_req_ex.3 \
libssh2_hostkey_hash.3 \
@@ -34,7 +38,7 @@ dist_man_MANS = \
libssh2_session_callback_set.3 \
libssh2_session_free.3 \
libssh2_session_disconnect_ex.3 \
libssh2_session_init.3 \
libssh2_session_init_ex.3 \
libssh2_session_last_errno.3 \
libssh2_session_last_error.3 \
libssh2_session_method_pref.3 \
@@ -50,7 +54,7 @@ dist_man_MANS = \
libssh2_sftp_open_ex.3 \
libssh2_sftp_mkdir_ex.3 \
libssh2_sftp_read.3 \
libssh2_sftp_readdir.3 \
libssh2_sftp_readdir_ex.3 \
libssh2_sftp_rename_ex.3 \
libssh2_sftp_rmdir_ex.3 \
libssh2_sftp_seek.3 \
@@ -65,6 +69,20 @@ dist_man_MANS = \
libssh2_userauth_keyboard_interactive_ex.3 \
libssh2_userauth_list.3 \
libssh2_userauth_password_ex.3 \
libssh2_userauth_publickey_fromfile.3 \
libssh2_userauth_publickey_fromfile_ex.3 \
libssh2_base64_decode.3 \
libssh2_trace.3
libssh2_trace.3 \
libssh2_version.3
libssh2_channel_request_pty_size_ex.3 \
libssh2_free_host_entry.3 \
libssh2_host_entry_match.3 \
libssh2_new_host_entry.3 \
libssh2_publickey_add_ex.3 \
libssh2_publickey_init.3 \
libssh2_publickey_list_fetch.3 \
libssh2_publickey_list_free.3 \
libssh2_publickey_remove_ex.3 \
libssh2_publickey_shutdown.3 \
libssh2_session_flag.3 \
libssh2_session_get_blocking.3 \
libssh2_userauth_hostbased_fromfile_ex.3

View File

@@ -1,4 +1,4 @@
.\" $Id: libssh2_banner_set.3,v 1.1 2007/06/13 17:03:38 jehousley Exp $
.\" $Id: libssh2_banner_set.3,v 1.3 2009/03/17 10:34:27 bagder Exp $
.\"
.TH libssh2_banner_set 3 "1 Jun 2007" "libssh2 0.15" "libssh2 manual"
.SH NAME
@@ -11,14 +11,14 @@ libssh2_banner_set(LIBSSH2_SESSION *session, const char *banner);
.SH DESCRIPTION
\fIsession\fP - Session instance as returned by
.BR libssh2_session_init(3)
.BR libssh2_session_init_ex(3)
\fIbanner\fP - A pointer to a user defined banner
Set the banner that will be sent to the remote host when the SSH session is
started with
.BR libssh2_session_startup(3)
. This is optional; a banner corresponding to the protocol and libssh2 version will be sent by default.
This is optional; a banner corresponding to the protocol and libssh2 version will be sent by default.
.SH RETURN VALUE
Return 0 on success or negative on failure. It returns

View File

@@ -1,4 +1,4 @@
.\" $Id: libssh2_base64_decode.3,v 1.2 2008/12/26 07:37:55 bagder Exp $
.\" $Id: libssh2_base64_decode.3,v 1.3 2009/02/17 16:22:51 dottedmag Exp $
.\"
.TH libssh2_base64_decode 3 "23 Dec 2008" "libssh2 1.0" "libssh2 manual"
.SH NAME
@@ -24,4 +24,4 @@ The memory that *dest points to is allocated by the malloc function libssh2
uses, but there's no way for an appliction to free this data in a safe and
reliable way!
.SH RETURN VALUE
0 if successful, -1 if any error occurred.
0 if successful, \-1 if any error occurred.

View File

@@ -1,4 +1,4 @@
.\" $Id: libssh2_channel_close.3,v 1.2 2007/11/29 09:57:22 bagder Exp $
.\" $Id: libssh2_channel_close.3,v 1.3 2009/03/16 23:25:14 bagder Exp $
.\"
.TH libssh2_channel_close 3 "1 Jun 2007" "libssh2 0.15" "libssh2 manual"
.SH NAME
@@ -28,4 +28,4 @@ LIBSSH2_ERROR_EAGAIN is a negative number, it isn't really a failure per se.
\fILIBSSH2_ERROR_SOCKET_SEND\fP - Unable to send data on socket.
.SH SEE ALSO
.BR libssh2_channel_open(3)
.BR libssh2_channel_open_ex(3)

View File

@@ -1,4 +1,4 @@
.\" $Id: libssh2_channel_direct_tcpip_ex.3,v 1.1 2007/06/13 17:22:15 jehousley Exp $
.\" $Id: libssh2_channel_direct_tcpip_ex.3,v 1.2 2009/03/17 10:34:27 bagder Exp $
.\"
.TH libssh2_channel_direct_tcpip_ex 3 "1 Jun 2007" "libssh2 0.15" "libssh2 manual"
.SH NAME
@@ -14,7 +14,7 @@ libssh2_channel_direct_tcpip(LIBSSH2_SESSION *session, const char *host, int por
.SH DESCRIPTION
/fIsession/fP - Session instance as returned by
.BR libssh2_session_init(3)
.BR libssh2_session_init_ex(3)
/fIhost/fP - Third party host to connect to using the SSH host as a proxy.
@@ -31,9 +31,7 @@ in cleartext.
.SH RETURN VALUE
Pointer to a newly allocated LIBSSH2_CHANNEL instance, or NULL on errors.
.SH ERRORS
\fILIBSSH2_ERROR_ALLOC\fP - An internal memory allocation call failed.
.SH SEE ALSO
.BR libssh2_session_init(3)
.BR libssh2_session_init_ex(3)

View File

@@ -1,4 +1,4 @@
.\" $Id: libssh2_channel_eof.3,v 1.1 2007/06/13 17:22:15 jehousley Exp $
.\" $Id: libssh2_channel_eof.3,v 1.2 2009/03/16 23:25:14 bagder Exp $
.\"
.TH libssh2_channel_eof 3 "1 Jun 2007" "libssh2 0.15" "libssh2 manual"
.SH NAME
@@ -8,11 +8,11 @@ libssh2_channel_eof - check a channel's EOF status
int
libssh2_channel_eof(LIBSSH2_CHANNEL *channel);
.SH DESCRIPTION
\fIchannel\fP - active channel stream to set closed status on.
Check if the remote host has sent an EOF status for the selected stream.
.SH RETURN VALUE
Returns 1 if the remote host has sent EOF, otherwise 0.
.SH SEE ALSO
.BR libssh2_channel_close(3)

View File

@@ -1,4 +1,4 @@
.\" $Id: libssh2_channel_forward_accept.3,v 1.5 2007/06/13 16:41:33 jehousley Exp $
.\" $Id: libssh2_channel_forward_accept.3,v 1.6 2009/03/16 23:25:14 bagder Exp $
.\"
.TH libssh2_channel_forward_accept 3 "1 Jun 2007" "libssh2 0.15" "libssh2 manual"
.SH NAME
@@ -11,11 +11,11 @@ libssh2_channel_forward_accept(LIBSSH2_LISTENER *listener);
.SH DESCRIPTION
\fIlistener\fP is a forwarding listener instance as returned by
\fBlibssh2_channel_forward_listen(3)\fP.
\fBlibssh2_channel_forward_listen_ex(3)\fP.
.SH RETURN VALUE
A newly allocated channel instance or NULL on failure.
.SH ERRORS
\fILIBSSH2_ERROR_EAGAIN\fP - Marked for non-blocking I/O but the call
would block.
.SH SEE ALSO
.BR libssh2_channel_forward_listen(3)
.BR libssh2_channel_forward_listen_ex(3)

View File

@@ -1,4 +1,4 @@
.\" $Id: libssh2_channel_forward_cancel.3,v 1.1 2007/06/13 19:53:09 jehousley Exp $
.\" $Id: libssh2_channel_forward_cancel.3,v 1.2 2009/03/16 23:25:14 bagder Exp $
.\"
.TH libssh2_channel_forward_cancel 3 "1 Jun 2007" "libssh2 0.15" "libssh2 manual"
.SH NAME
@@ -11,7 +11,7 @@ libssh2_channel_forward_cancel(LIBSSH2_LISTENER *listener);
.SH DESCRIPTION
/fIlistener/fP - Forwarding listener instance as returned by
.BR libssh2_channel_forward_listen(3)
.BR libssh2_channel_forward_listen_ex(3)
Instruct the remote host to stop listening for new connections on a previously requested host/port.
@@ -26,4 +26,4 @@ LIBSSH2_ERROR_EAGAIN is a negative number, it isn't really a failure per se.
\fILIBSSH2_ERROR_SOCKET_SEND\fP - Unable to send data on socket.
.SH SEE ALSO
.BR libssh2_channel_forward_listen(3)
.BR libssh2_channel_forward_listen_ex(3)

View File

@@ -1,4 +1,4 @@
.\" $Id: libssh2_channel_handle_extended_data.3,v 1.1 2007/06/13 20:09:15 jehousley Exp $
.\" $Id: libssh2_channel_handle_extended_data.3,v 1.2 2009/03/26 15:41:16 bagder Exp $
.\"
.TH libssh2_channel_handle_extended_data 3 "1 Jun 2007" "libssh2 0.15" "libssh2 manual"
.SH NAME
@@ -10,6 +10,9 @@ void
libssh2_channel_handle_extended_data(LIBSSH2_CHANNEL *channel, int ignore_mode);
.SH DESCRIPTION
This function is deprecated. Use the
\fIlibssh2_channel_handle_extended_data2(3)\fP function instead!
\fIchannel\fP - Active channel stream to change extended data handling on.
\fIignore_mode\fP - One of the three LIBSSH2_CHANNEL_EXTENDED_DATA_* Constants.
@@ -17,21 +20,18 @@ libssh2_channel_handle_extended_data(LIBSSH2_CHANNEL *channel, int ignore_mode);
\fBLIBSSH2_CHANNEL_EXTENDED_DATA_NORMAL\fP: Queue extended data for eventual
reading
.br
\fBLIBSSH2_CHANNEL_EXTENDED_DATA_MERGE\fP: Treat extended data and ordinary
data the same. Merge all substreams such that calls to
.BR libssh2_channel_read(3)
will pull from all substreams on a first-in/first-out basis.
\fBLIBSSH2_CHANNEL_EXTENDED_DATA_MERGE\fP: Treat extended data and ordinary
data the same. Merge all substreams such that calls to
\fIlibssh2_channel_read(3)\fP will pull from all substreams on a
first-in/first-out basis.
.br
\fBLIBSSH2_CHANNEL_EXTENDED_DATA_IGNORE\fP: Discard all extended data as it
arrives.
Change how a channel deals with extended data packets. By default all
extended data is queued until read by
.BR libssh2_channel_read_ex(3)
Change how a channel deals with extended data packets. By default all extended
data is queued until read by \fIlibssh2_channel_read_ex(3)\fP
.SH RETURN VALUE
None.
.SH SEE ALSO
.BR libssh2_channel_handle_extended_data2(3)
.BR libssh2_channel_read_ex(3)

View File

@@ -1,4 +1,4 @@
.\" $Id: libssh2_channel_open_ex.3,v 1.1 2007/06/13 20:54:25 jehousley Exp $
.\" $Id: libssh2_channel_open_ex.3,v 1.2 2009/03/17 10:34:27 bagder Exp $
.\"
.TH libssh2_channel_open_ex 3 "1 Jun 2007" "libssh2 0.15" "libssh2 manual"
.SH NAME
@@ -14,7 +14,7 @@ libssh2_channel_open_session(session);
.SH DESCRIPTION
\fIsession\fP - Session instance as returned by
.BR libssh2_session_init(3)
.BR libssh2_session_init_ex(3)
\fIchannel_type\fP - Channel type to open. Typically one of session,
direct-tcpip, or tcpip-forward. The SSH2 protocol allowed for additional

View File

@@ -1,4 +1,4 @@
.\" $Id: libssh2_channel_process_startup.3,v 1.1 2007/06/13 20:54:25 jehousley Exp $
.\" $Id: libssh2_channel_process_startup.3,v 1.2 2009/03/16 23:25:14 bagder Exp $
.\"
.TH libssh2_channel_process_startup 3 "1 Jun 2007" "libssh2 0.15" "libssh2 manual"
.SH NAME
@@ -31,19 +31,16 @@ defines shell, exec, and subsystem as standard process services.
\fImessage_len\fP - Length of message parameter.
Initiate a request on a session type channel such as returned by
.BR libssh2_channel_open_session(3)
.BR libssh2_channel_open_ex(3)
.SH RETURN VALUE
Return 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.
.SH ERRORS
\fILIBSSH2_ERROR_ALLOC\fP - An internal memory allocation call failed.
\fILIBSSH2_ERROR_SOCKET_SEND\fP - Unable to send data on socket.
\fILIBSSH2_ERROR_CHANNEL_REQUEST_DENIED\fP -
.SH SEE ALSO
.BR libssh2_channel_open_session(3)
.BR libssh2_channel_open_ex(3)

View File

@@ -0,0 +1,31 @@
.\" $Id: libssh2_channel_receive_window_adjust.3,v 1.3 2009/03/26 15:41:16 bagder Exp $
.\"
.TH libssh2_channel_receive_window_adjust 3 "15 Mar 2009" "libssh2 0.15" "libssh2 manual"
.SH NAME
libssh2_channel_receive_window_adjust - adjust the channel window
.SH SYNOPSIS
#include <libssh2.h>
unsigned long
libssh2_channel_receive_window_adjust(LIBSSH2_CHANNEL * channel,
unsigned long adjustment,
unsigned char force);
.SH DESCRIPTION
This function is deprecated in 1.1. Use
\fIlibssh2_channel_receive_window_adjust2(3)\fP!
Adjust the receive window for a channel by adjustment bytes. If the amount to
be adjusted is less than LIBSSH2_CHANNEL_MINADJUST and force is 0 the
adjustment amount will be queued for a later packet.
.SH RETURN VALUE
Returns the new size of the receive window (as understood by remote end). Note
that the window value sent over the wire is strictly 32bit, but this API is
made to return a 'long' which may not be 32 bit on all platforms.
.SH ERRORS
In 1.0 and earlier, this function returns LIBSSH2_ERROR_EAGAIN for
non-blocking channels where it would otherwise block. However, that is a
negative number and this function only returns an unsigned value and this then
leads to a very strange value being returned.
.SH SEE ALSO
.BR libssh2_channel_window_read_ex(3)

View File

@@ -0,0 +1,29 @@
.\" $Id: libssh2_channel_receive_window_adjust2.3,v 1.1 2009/03/26 15:41:16 bagder Exp $
.\"
.TH libssh2_channel_receive_window_adjust2 3 "26 Mar 2009" "libssh2 1.1" "libssh2 manual"
.SH NAME
libssh2_channel_receive_window_adjust2 - adjust the channel window
.SH SYNOPSIS
#include <libssh2.h>
int
libssh2_channel_receive_window_adjust2(LIBSSH2_CHANNEL * channel,
unsigned long adjustment,
unsigned char force,
unsigned int *window);
.SH DESCRIPTION
Adjust the receive window for a channel by adjustment bytes. If the amount to
be adjusted is less than LIBSSH2_CHANNEL_MINADJUST and force is 0 the
adjustment amount will be queued for a later packet.
This function stores the new size of the receive window (as understood by
remote end) in the variable 'window' points to.
.SH RETURN VALUE
Return 0 on success and a negative value on error. If used in non-blocking
mode it will return LIBSSH2_ERROR_EAGAIN when it would otherwise block.
.SH ERRORS
.SH AVAILABILITY
Added in libssh2 1.1 since the previous API has deficiencies.
.SH SEE ALSO
.BR libssh2_channel_window_read_ex(3)

View File

@@ -1,4 +1,4 @@
.\" $Id: libssh2_channel_request_pty_ex.3,v 1.1 2007/06/13 21:07:59 jehousley Exp $
.\" $Id: libssh2_channel_request_pty_ex.3,v 1.2 2009/03/16 23:25:14 bagder Exp $
.\"
.TH libssh2_channel_request_pty_ex 3 "1 Jun 2007" "libssh2 0.15" "libssh2 manual"
.SH NAME
@@ -14,7 +14,7 @@ libssh2_channel_request_pty(LIBSSH2_CHANNEL *channel, char *term);
.SH DESCRIPTION
\fIchannel\fP - Previously opened channel instance such as returned by
.BR libssh2_channel_open_session(3)
.BR libssh2_channel_open_ex(3)
\fIterm\fP - Terminal emulation (e.g. vt102, ansi, etc...)
@@ -35,18 +35,15 @@ libssh2_channel_request_pty(LIBSSH2_CHANNEL *channel, char *term);
Request a PTY on an established channel. Note that this does not make sense
for all channel types and may be ignored by the server despite returning
success.
.SH RETURN VALUE
Return 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.
.SH ERRORS
\fILIBSSH2_ERROR_ALLOC\fP - An internal memory allocation call failed.
\fILIBSSH2_ERROR_SOCKET_SEND\fP - Unable to send data on socket.
\fILIBSSH2_ERROR_CHANNEL_REQUEST_DENIED\fP -
.SH SEE ALSO
.BR libssh2_channel_open_session(3)
.BR libssh2_channel_open_ex(3)

View File

@@ -0,0 +1,14 @@
.\" $Id: libssh2_channel_request_pty_size_ex.3,v 1.1 2009/03/16 15:00:45 bagder Exp $
.\"
.TH libssh2_channel_request_pty_size_ex 3 "1 Jun 2007" "libssh2 0.15" "libssh2 manual"
.SH NAME
libssh2_channel_request_pty_size_ex - TODO
.SH SYNOPSIS
.SH DESCRIPTION
.SH RETURN VALUE
.SH ERRORS
.SH SEE ALSO

View File

@@ -1,4 +1,4 @@
.\" $Id: libssh2_channel_set_blocking.3,v 1.5 2007/06/14 17:23:13 jehousley Exp $
.\" $Id: libssh2_channel_set_blocking.3,v 1.6 2009/03/26 15:41:16 bagder Exp $
.\"
.TH libssh2_channel_set_blocking 3 "1 Jun 2007" "libssh2 0.15" "libssh2 manual"
.SH NAME
@@ -8,7 +8,6 @@ libssh2_channel_set_blocking - set or clear blocking mode on channel
void
libssh2_channel_set_blocking(LIBSSH2_CHANNEL *channel, int blocking);
.SH DESCRIPTION
\fIchannel\fP - channel stream to set or clean blocking status on.
@@ -18,10 +17,8 @@ make it non-blocking.
Currently this is just a short cut call to
.BR libssh2_session_set_blocking(3)
and therefore will affect the session and all channels.
.SH RETURN VALUE
None
.SH SEE ALSO
.BR libssh2_session_set_blocking(3)
.BR libssh2_channel_read_ex(3)

View File

@@ -1,4 +1,4 @@
.\" $Id: libssh2_channel_setenv_ex.3,v 1.1 2007/06/13 21:30:15 jehousley Exp $
.\" $Id: libssh2_channel_setenv_ex.3,v 1.2 2009/03/16 23:25:14 bagder Exp $
.\"
.TH libssh2_channel_setenv_ex 3 "1 Jun 2007" "libssh2 0.15" "libssh2 manual"
.SH NAME
@@ -14,7 +14,7 @@ libssh2_channel_setenv(LIBSSH2_CHANNEL *channel, char *varname, const char *valu
.SH DESCRIPTION
\fIchannel\fP - Previously opened channel instance such as returned by
.BR libssh2_channel_open_session(3)
.BR libssh2_channel_open_ex(3)
\fIvarname\fP - Name of environment variable to set on the remote
channel instance.
@@ -25,8 +25,9 @@ channel instance.
\fIvalue_len\fP - Length of value parameter.
Set an environment variable in the remote channel's process space. Note that this does not make sense for all channel types and may be ignored by the server despite returning success.
Set an environment variable in the remote channel's process space. Note that
this does not make sense for all channel types and may be ignored by the
server despite returning success.
.SH RETURN VALUE
Return 0 on success or negative on failure. It returns
LIBSSH2_ERROR_EAGAIN when it would otherwise block. While
@@ -38,6 +39,5 @@ LIBSSH2_ERROR_EAGAIN is a negative number, it isn't really a failure per se.
\fILIBSSH2_ERROR_SOCKET_SEND\fP - Unable to send data on socket.
\fILIBSSH2_ERROR_CHANNEL_REQUEST_DENIED\fP -
.SH SEE ALSO
.BR libssh2_channel_open_session(3)
.BR libssh2_channel_open_ex(3)

View File

@@ -0,0 +1,26 @@
.\" $Id: libssh2_channel_window_read_ex.3,v 1.2 2009/03/16 23:25:14 bagder Exp $
.\"
.TH libssh2_channel_window_read_ex 3 "1 Jun 2007" "libssh2 0.15" "libssh2 manual"
.SH NAME
libssh2_channel_window_read_ex - Check the status of the read window
.SH SYNOPSIS
#include <libssh2.h>
unsigned long
libssh2_channel_window_read_ex(LIBSSH2_CHANNEL *channel,
unsigned long *read_avail,
unsigned long *window_size_initial)
.SH DESCRIPTION
Check the status of the read window. Returns the number of bytes which the
remote end may send without overflowing the window limit read_avail (if
passed) will be populated with the number of bytes actually available to be
read window_size_initial (if passed) will be populated with the
window_size_initial as defined by the channel_open request
.SH RETURN VALUE
The number of bytes which the remote end may send without overflowing the
window limit
.SH ERRORS
.SH SEE ALSO
.BR libssh2_channel_receive_window_adjust(3),
.BR libssh2_channel_window_write_ex(3)

View File

@@ -0,0 +1,23 @@
.\" $Id: libssh2_channel_window_write_ex.3,v 1.2 2009/03/16 23:25:14 bagder Exp $
.\"
.TH libssh2_channel_window_write_ex 3 "1 Jun 2007" "libssh2 0.15" "libssh2 manual"
.SH NAME
libssh2_channel_window_write_ex - Check the status of the write window
.SH SYNOPSIS
#include <libssh2.h>
unsigned long
libssh2_channel_window_write_ex(LIBSSH2_CHANNEL *channel,
unsigned long *window_size_initial)
.SH DESCRIPTION
Check the status of the write window Returns the number of bytes which may be
safely writen on the channel without blocking. 'window_size_initial' (if
passed) will be populated with the size of the initial window as defined by
the channel_open request
.SH RETURN VALUE
Number of bytes which may be safely writen on the channel without blocking.
.SH ERRORS
.SH SEE ALSO
.BR libssh2_channel_window_read_ex(3),
.BR libssh2_channel_receive_window_adjust(3)

View File

@@ -1,4 +1,4 @@
.\" $Id: libssh2_channel_write_ex.3,v 1.5 2007/06/13 16:41:33 jehousley Exp $
.\" $Id: libssh2_channel_write_ex.3,v 1.6 2009/03/16 23:25:14 bagder Exp $
.\"
.TH libssh2_channel_write_ex 3 "1 Jun 2007" "libssh2 0.15" "libssh2 manual"
.SH NAME
@@ -41,7 +41,8 @@ LIBSSH2_ERROR_EAGAIN is a negative number, it isn't really a failure per se.
\fILIBSSH2_ERROR_CHANNEL_CLOSED\fP - The channel has been closed.
\fILIBSSH2_ERROR_CHANNEL_EOF_SENT\fP - The channel has been requested to be closed.
\fILIBSSH2_ERROR_CHANNEL_EOF_SENT\fP - The channel has been requested to be
closed.
.SH SEE ALSO
.BR libssh2_channel_open_session(3)
.BR libssh2_channel_read(3)
.BR libssh2_channel_open_ex(3)
.BR libssh2_channel_read_ex(3)

View File

@@ -1,4 +1,4 @@
.\" $Id: libssh2_channel_x11_req_ex.3,v 1.1 2007/06/13 21:30:15 jehousley Exp $
.\" $Id: libssh2_channel_x11_req_ex.3,v 1.2 2009/03/16 23:25:14 bagder Exp $
.\"
.TH libssh2_channel_x11_req_ex 3 "1 Jun 2007" "libssh2 0.15" "libssh2 manual"
.SH NAME
@@ -14,7 +14,7 @@ libssh2_channel_x11_req(LIBSSH2_CHANNEL *channel, int screen_number);
.SH DESCRIPTION
\fIchannel\fP - Previously opened channel instance such as returned by
.BR libssh2_channel_open_session(3)
.BR libssh2_channel_open_ex(3)
\fIsingle_connection\fP - non-zero to only forward a single connection.
@@ -26,8 +26,8 @@ libssh2_channel_x11_req(LIBSSH2_CHANNEL *channel, int screen_number);
Request an X11 forwarding on \fIchannel\fP. To use X11 forwarding,
.BR libssh2_session_callback_set(3)
must first be called to set \fBLIBSSH2_CALLBACK_X11/fP. This callback will
be invoked when the remote host accepts the X11 forwarding.
must first be called to set \fBLIBSSH2_CALLBACK_X11\fP. This callback will be
invoked when the remote host accepts the X11 forwarding.
.SH RETURN VALUE
Return 0 on success or negative on failure. It returns
@@ -42,5 +42,5 @@ LIBSSH2_ERROR_EAGAIN is a negative number, it isn't really a failure per se.
\fILIBSSH2_ERROR_CHANNEL_REQUEST_DENIED\fP -
.SH SEE ALSO
.BR libssh2_channel_open_session(3)
.BR libssh2_channel_open_ex(3)
.BR libssh2_session_callback_set(3)

View File

@@ -0,0 +1,14 @@
.\" $Id: libssh2_free_host_entry.3,v 1.1 2009/03/16 15:00:45 bagder Exp $
.\"
.TH libssh2_free_host_entry 3 "1 Jun 2007" "libssh2 0.15" "libssh2 manual"
.SH NAME
libssh2_free_host_entry - TODO
.SH SYNOPSIS
.SH DESCRIPTION
.SH RETURN VALUE
.SH ERRORS
.SH SEE ALSO

View File

@@ -0,0 +1,14 @@
.\" $Id: libssh2_host_entry_match.3,v 1.1 2009/03/16 15:00:45 bagder Exp $
.\"
.TH libssh2_host_entry_match 3 "1 Jun 2007" "libssh2 0.15" "libssh2 manual"
.SH NAME
libssh2_host_entry_match - TODO
.SH SYNOPSIS
.SH DESCRIPTION
.SH RETURN VALUE
.SH ERRORS
.SH SEE ALSO

View File

@@ -1,4 +1,4 @@
.\" $Id: libssh2_hostkey_hash.3,v 1.1 2007/06/14 14:56:32 jehousley Exp $
.\" $Id: libssh2_hostkey_hash.3,v 1.2 2009/03/17 10:34:27 bagder Exp $
.\"
.TH libssh2_hostkey_hash 3 "1 Jun 2007" "libssh2 0.15" "libssh2 manual"
.SH NAME
@@ -11,7 +11,7 @@ libssh2_hostkey_hash(LIBSSH2_SESSION *session, int hash_type);
.SH DESCRIPTION
\fIsession\fP - Session instance as returned by
.BR libssh2_session_init(3)
.BR libssh2_session_init_ex(3)
\fIhash_type\fP - One of: \fBLIBSSH2_HOSTKEY_HASH_MD5\fP or
\fBLIBSSH2_HOSTKEY_HASH_SHA1\fP.
@@ -19,11 +19,9 @@ libssh2_hostkey_hash(LIBSSH2_SESSION *session, int hash_type);
Returns the computed digest of the remote system's hostkey. The length of
the returned string is hash_type specific (e.g. 16 bytes for MD5,
20 bytes for SHA1).
.SH RETURN VALUE
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.)
.SH SEE ALSO
.BR libssh2_session_init(3)
.BR libssh2_session_init_ex(3)

View File

@@ -0,0 +1,14 @@
.\" $Id: libssh2_new_host_entry.3,v 1.1 2009/03/16 15:00:45 bagder Exp $
.\"
.TH libssh2_new_host_entry 3 "1 Jun 2007" "libssh2 0.15" "libssh2 manual"
.SH NAME
libssh2_new_host_entry - TODO
.SH SYNOPSIS
.SH DESCRIPTION
.SH RETURN VALUE
.SH ERRORS
.SH SEE ALSO

View File

@@ -0,0 +1,14 @@
.\" $Id: libssh2_publickey_add_ex.3,v 1.1 2009/03/16 15:00:45 bagder Exp $
.\"
.TH libssh2_publickey_add_ex 3 "1 Jun 2007" "libssh2 0.15" "libssh2 manual"
.SH NAME
libssh2_publickey_add_ex - TODO
.SH SYNOPSIS
.SH DESCRIPTION
.SH RETURN VALUE
.SH ERRORS
.SH SEE ALSO

View File

@@ -0,0 +1,14 @@
.\" $Id: libssh2_publickey_init.3,v 1.1 2009/03/16 15:00:45 bagder Exp $
.\"
.TH libssh2_publickey_init 3 "1 Jun 2007" "libssh2 0.15" "libssh2 manual"
.SH NAME
libssh2_publickey_init - TODO
.SH SYNOPSIS
.SH DESCRIPTION
.SH RETURN VALUE
.SH ERRORS
.SH SEE ALSO

View File

@@ -0,0 +1,14 @@
.\" $Id: libssh2_publickey_list_fetch.3,v 1.1 2009/03/16 15:00:45 bagder Exp $
.\"
.TH libssh2_publickey_list_fetch 3 "1 Jun 2007" "libssh2 0.15" "libssh2 manual"
.SH NAME
libssh2_publickey_list_fetch - TODO
.SH SYNOPSIS
.SH DESCRIPTION
.SH RETURN VALUE
.SH ERRORS
.SH SEE ALSO

View File

@@ -0,0 +1,14 @@
.\" $Id: libssh2_publickey_list_free.3,v 1.1 2009/03/16 15:00:45 bagder Exp $
.\"
.TH libssh2_publickey_list_free 3 "1 Jun 2007" "libssh2 0.15" "libssh2 manual"
.SH NAME
libssh2_publickey_list_free - TODO
.SH SYNOPSIS
.SH DESCRIPTION
.SH RETURN VALUE
.SH ERRORS
.SH SEE ALSO

View File

@@ -0,0 +1,14 @@
.\" $Id: libssh2_publickey_remove_ex.3,v 1.1 2009/03/16 15:00:45 bagder Exp $
.\"
.TH libssh2_publickey_list_remove_ex 3 "1 Jun 2007" "libssh2 0.15" "libssh2 manual"
.SH NAME
libssh2_publickey_list_remove_ex - TODO
.SH SYNOPSIS
.SH DESCRIPTION
.SH RETURN VALUE
.SH ERRORS
.SH SEE ALSO

View File

@@ -0,0 +1,14 @@
.\" $Id: libssh2_publickey_shutdown.3,v 1.1 2009/03/16 15:00:45 bagder Exp $
.\"
.TH libssh2_publickey_shutdown 3 "1 Jun 2007" "libssh2 0.15" "libssh2 manual"
.SH NAME
libssh2_publickey_shutdown - TODO
.SH SYNOPSIS
.SH DESCRIPTION
.SH RETURN VALUE
.SH ERRORS
.SH SEE ALSO

View File

@@ -1,4 +1,4 @@
.\" $Id: libssh2_scp_recv.3,v 1.1 2007/06/14 14:56:32 jehousley Exp $
.\" $Id: libssh2_scp_recv.3,v 1.3 2009/03/17 10:34:27 bagder Exp $
.\"
.TH libssh2_scp_recv 3 "1 Jun 2007" "libssh2 0.15" "libssh2 manual"
.SH NAME
@@ -11,30 +11,23 @@ libssh2_scp_recv(LIBSSH2_SESSION *session, const char *path, struct stat *sb);
.SH DESCRIPTION
\fIsession\fP - Session instance as returned by
.BR libssh2_session_init(3)
.BR libssh2_session_init_ex(3)
\fIpath\fP - Full path and filename of file to transfer
\fIsb\fP - Populated with remote file's size, mode, mtime, and atime
Request a file from the remote host via SCP. This
function acts as a wrapper calling
.BR libssh2_channel_open_session(3)
,
.BR libssh2_channel_exec(3)
, and negotiating rcp protocol handshakes.
Request a file from the remote host via SCP.
.SH RETURN VALUE
Pointer to a newly allocated LIBSSH2_CHANNEL instance, or NULL on errors.
.SH ERRORS
\fILIBSSH2_ERROR_ALLOC\fP - An internal memory allocation call failed.
\fILIBSSH2_ERROR_SCP_PROTOCOL\fP -
\fILIBSSH2_ERROR_EAGAIN\fP - Marked for non-blocking I/O but the call would block.
\fILIBSSH2_ERROR_EAGAIN\fP - Marked for non-blocking I/O but the call would
block.
.SH SEE ALSO
.BR libssh2_session_init(3)
.BR libssh2_channel_open_session(3)
.BR libssh2_channel_exec(3)
.BR libssh2_session_init_ex(3)
.BR libssh2_channel_open_ex(3)

View File

@@ -1,4 +1,4 @@
.\" $Id: libssh2_scp_send_ex.3,v 1.1 2007/06/14 14:56:32 jehousley Exp $
.\" $Id: libssh2_scp_send_ex.3,v 1.3 2009/03/17 10:34:27 bagder Exp $
.\"
.TH libssh2_scp_send_ex 3 "1 Jun 2007" "libssh2 0.15" "libssh2 manual"
.SH NAME
@@ -8,13 +8,9 @@ libssh2_scp_send_ex - Send a file via SCP
LIBSSH2_CHANNEL *
libssh2_scp_send_ex(LIBSSH2_SESSION *session, const char *path, int mode, size_t size, long mtime, long atime);
LIBSSH2_CHANNEL *
libssh2_scp_send_ex(LIBSSH2_SESSION *session, const char *path, int mode, size_t size);
.SH DESCRIPTION
\fIsession\fP - Session instance as returned by
.BR libssh2_session_init(3)
.BR libssh2_session_init_ex(3)
\fIpath\fP - Full path and filename of file to transfer
@@ -28,13 +24,7 @@ ahead of time precisely)
\fIatime\fP - atime to assign to file being created (Set this and
mtime to zero to instruct remote host to use current time).
Send a file to the remote host via SCP. This function
acts as a wrapper calling
.BR libssh2_channel_open_session(3)
,
.BR libssh2_channel_exec(3)
, and negotiating rcp protocol handshakes.
Send a file to the remote host via SCP.
.SH RETURN VALUE
Pointer to a newly allocated LIBSSH2_CHANNEL instance, or NULL on errors.
@@ -45,8 +35,8 @@ Pointer to a newly allocated LIBSSH2_CHANNEL instance, or NULL on errors.
\fILIBSSH2_ERROR_SCP_PROTOCOL\fP -
\fILIBSSH2_ERROR_EAGAIN\fP - Marked for non-blocking I/O but the call would block.
\fILIBSSH2_ERROR_EAGAIN\fP - Marked for non-blocking I/O but the call would
block.
.SH SEE ALSO
.BR libssh2_channel_open_session(3)
.BR libssh2_channel_exec(3)
.BR libssh2_channel_open_ex(3)

View File

@@ -1,4 +1,4 @@
.\" $Id: libssh2_session_block_directions.3,v 1.2 2008/12/22 12:51:27 bagder Exp $
.\" $Id: libssh2_session_block_directions.3,v 1.3 2009/03/17 10:34:27 bagder Exp $
.\"
.TH libssh2_session_block_directions 3 "1 Oct 2008" "libssh2 1.0" "libssh2 manual"
.SH NAME
@@ -9,7 +9,7 @@ libssh2_session_block_directions - get directions that socket should wait for be
int
libssh2_session_block_directions(LIBSSH2_SESSION *session);
.SH DESCRIPTION
\fIsession\fP - Session instance as returned by \fBlibssh2_session_init(3)\fP
\fIsession\fP - Session instance as returned by \fBlibssh2_session_init_ex(3)\fP
When any of libssh2 functions return \fBLIBSSH2_ERROR_EAGAIN\fP an application
should wait for the socket to have data available for reading or

View File

@@ -1,4 +1,4 @@
.\" $Id: libssh2_session_callback_set.3,v 1.1 2007/06/14 15:26:58 jehousley Exp $
.\" $Id: libssh2_session_callback_set.3,v 1.2 2009/03/17 10:34:27 bagder Exp $
.\"
.TH libssh2_session_callback_set 3 "1 Jun 2007" "libssh2 0.15" "libssh2 manual"
.SH NAME
@@ -11,7 +11,7 @@ libssh2_session_callback_set(LIBSSH2_SESSION *session, int cbtype, void *callbac
.SH DESCRIPTION
\fIsession\fP - Session instance as returned by
.BR libssh2_session_init(3)
.BR libssh2_session_init_ex(3)
\fIcbtype\fP - Callback type. One of the types listed in Callback Types.
@@ -27,4 +27,4 @@ Pointer to previous callback handler. Returns NULL if no
prior callback handler was set.
.SH SEE ALSO
.BR libssh2_session_init(3)
.BR libssh2_session_init_ex(3)

View File

@@ -1,4 +1,4 @@
.\" $Id: libssh2_session_disconnect_ex.3,v 1.4 2007/06/13 16:41:33 jehousley Exp $
.\" $Id: libssh2_session_disconnect_ex.3,v 1.5 2009/03/17 10:34:27 bagder Exp $
.\"
.TH libssh2_session_disconnect_ex 3 "1 Jun 2007" "libssh2 0.15" "libssh2 manual"
.SH NAME
@@ -14,7 +14,7 @@ libssh2_session_disconnect(LIBSSH2_SESSION *session, const char *description);
.SH DESCRIPTION
\fIsession\fP - Session instance as returned by
.BR libssh2_session_init(3)
.BR libssh2_session_init_ex(3)
\fIreason\fP - One of the Disconnect Reason constants.
@@ -37,4 +37,4 @@ Return 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.
.SH SEE ALSO
.BR libssh2_session_init(3)
.BR libssh2_session_init_ex(3)

View File

@@ -0,0 +1,15 @@
.\" $Id: libssh2_session_flag.3,v 1.2 2009/03/23 13:17:49 bagder Exp $
.\"
.TH libssh2_session_flag 3 "1 Jun 2007" "libssh2 0.15" "libssh2 manual"
.SH NAME
libssh2_session_flag - TODO
.SH SYNOPSIS
int
libssh2_session_flag(LIBSSH2_SESSION * session, int flag, int value);
.SH DESCRIPTION
This function has no purpose and no documented flags can be set nor read.
.SH RETURN VALUE
0
.SH ERRORS
Its mere existence is an error
.SH SEE ALSO

View File

@@ -1,4 +1,4 @@
.\" $Id: libssh2_session_free.3,v 1.4 2007/06/13 16:41:33 jehousley Exp $
.\" $Id: libssh2_session_free.3,v 1.5 2009/03/16 23:25:14 bagder Exp $
.\"
.TH libssh2_session_free 3 "1 Jun 2007" "libssh2 0.15" "libssh2 manual"
.SH NAME
@@ -10,12 +10,11 @@ int
libssh2_session_free(LIBSSH2_SESSION *session);
.SH DESCRIPTION
Frees resources associated with a session instance. Typically called after
.BR libssh2_session_disconnect(3)
.BR libssh2_session_disconnect_ex(3)
.SH RETURN VALUE
Return 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.
.SH SEE ALSO
.BR libssh2_session_init(3)
.BR libssh2_session_disconnect(3)
.BR libssh2_session_init_ex(3)
.BR libssh2_session_disconnect_ex(3)

View File

@@ -0,0 +1,14 @@
.\" $Id: libssh2_session_get_blocking.3,v 1.2 2009/03/23 13:20:48 bagder Exp $
.\"
.TH libssh2_session_get_blocking 3 "1 Jun 2007" "libssh2 0.15" "libssh2 manual"
.SH NAME
libssh2_session_get_blocking - TODO
.SH SYNOPSIS
int libssh2_session_get_blocking(LIBSSH2_SESSION *session);
.SH DESCRIPTION
Returns 0 if the state of the session has previously be set to non-blocking
and it returns 1 if the state was set to blocking.
.SH RETURN VALUE
See description.
.SH SEE ALSO
.BR libssh2_session_set_blocking(3)

View File

@@ -1,4 +1,4 @@
.\" $Id: libssh2_session_init.3,v 1.6 2007/06/13 16:41:33 jehousley Exp $
.\" $Id: libssh2_session_init_ex.3,v 1.1 2009/03/16 14:40:37 bagder Exp $
.\"
.TH libssh2_session_init_ex 3 "1 Jun 2007" "libssh2 0.15" "libssh2 manual"
.SH NAME

View File

@@ -1,4 +1,4 @@
.\" $Id: libssh2_session_last_errno.3,v 1.1 2007/06/13 23:02:08 jehousley Exp $
.\" $Id: libssh2_session_last_errno.3,v 1.2 2009/03/17 10:34:27 bagder Exp $
.\"
.TH libssh2_session_last_errno 3 "1 Jun 2007" "libssh2 0.15" "libssh2 manual"
.SH NAME
@@ -11,7 +11,7 @@ libssh2_session_last_errno(LIBSSH2_SESSION *session);
.SH DESCRIPTION
\fIsession\fP - Session instance as returned by
.BR libssh2_session_init(3)
.BR libssh2_session_init_ex(3)
Determine the most recent error condition.

View File

@@ -1,4 +1,4 @@
.\" $Id: libssh2_session_last_error.3,v 1.1 2007/06/13 23:02:08 jehousley Exp $
.\" $Id: libssh2_session_last_error.3,v 1.2 2009/03/17 10:34:27 bagder Exp $
.\"
.TH libssh2_session_last_error 3 "1 Jun 2007" "libssh2 0.15" "libssh2 manual"
.SH NAME
@@ -11,7 +11,7 @@ libssh2_session_last_error(LIBSSH2_SESSION *session, char **errmsg, int *errmsg_
.SH DESCRIPTION
\fIsession\fP - Session instance as returned by
.BR libssh2_session_init(3)
.BR libssh2_session_init_ex(3)
\fIerrmsg\fP - If not NULL, is populated by reference with the human
readable form of the most recent error message.

View File

@@ -1,4 +1,4 @@
.\" $Id: libssh2_session_method_pref.3,v 1.1 2007/06/14 15:26:58 jehousley Exp $
.\" $Id: libssh2_session_method_pref.3,v 1.2 2009/03/17 10:34:27 bagder Exp $
.\"
.TH libssh2_session_method_pref 3 "1 Jun 2007" "libssh2 0.15" "libssh2 manual"
.SH NAME
@@ -11,7 +11,7 @@ libssh2_session_method_pref(LIBSSH2_SESSION *session, int method_type, const cha
.SH DESCRIPTION
\fIsession\fP - Session instance as returned by
.BR libssh2_session_init(3)
.BR libssh2_session_init_ex(3)
\fImethod_type\fP - One of the Method Type constants.
@@ -38,5 +38,5 @@ LIBSSH2_ERROR_EAGAIN is a negative number, it isn't really a failure per se.
\fILIBSSH2_ERROR_METHOD_NOT_SUPPORTED\fP - The requested method is not supported.
.SH SEE ALSO
.BR libssh2_session_init(3)
.BR libssh2_session_init_ex(3)
.BR libssh2_session_startup(3)

View File

@@ -1,4 +1,4 @@
.\" $Id: libssh2_session_methods.3,v 1.1 2007/06/14 15:26:58 jehousley Exp $
.\" $Id: libssh2_session_methods.3,v 1.2 2009/03/17 10:34:27 bagder Exp $
.\"
.TH libssh2_session_methods 3 "1 Jun 2007" "libssh2 0.15" "libssh2 manual"
.SH NAME
@@ -11,7 +11,7 @@ libssh2_session_methods(LIBSSH2_SESSION *session, int method_type);
.SH DESCRIPTION
\fIsession\fP - Session instance as returned by
.BR libssh2_session_init(3)
.BR libssh2_session_init_ex(3)
\fImethod_type\fP - One of the Method Type constants.
@@ -26,4 +26,4 @@ Negotiated method or NULL if the session has not yet been started.
\fILIBSSH2_ERROR_METHOD_NONE\fP -
.SH SEE ALSO
.BR libssh2_session_init(3)
.BR libssh2_session_init_ex(3)

View File

@@ -1,4 +1,4 @@
.\" $Id: libssh2_session_set_blocking.3,v 1.2 2008/07/03 10:58:53 bagder Exp $
.\" $Id: libssh2_session_set_blocking.3,v 1.3 2009/03/16 23:25:14 bagder Exp $
.\"
.TH libssh2_session_set_blocking 3 "1 Jun 2007" "libssh2 0.15" "libssh2 manual"
.SH NAME
@@ -11,7 +11,7 @@ libssh2_session_set_blocking(LIBSSH2_SESSION *session, int blocking);
.SH DESCRIPTION
\fIsession\fP - session instance as returned by
.BR libssh2_session_init(3)
.BR libssh2_session_init_ex(3)
\fIblocking\fP - Set to a non-zero value to make the channel block, or zero to
make it non-blocking.
@@ -29,4 +29,4 @@ anything.
None
.SH SEE ALSO
.BR libssh2_session_init(3)
.BR libssh2_session_init_ex(3)

View File

@@ -1,4 +1,4 @@
.\" $Id: libssh2_session_startup.3,v 1.6 2007/06/13 16:41:33 jehousley Exp $
.\" $Id: libssh2_session_startup.3,v 1.7 2009/03/16 23:25:14 bagder Exp $
.\"
.TH libssh2_session_startup 3 "1 Jun 2007" "libssh2 0.15" "libssh2 manual"
.SH NAME
@@ -11,7 +11,7 @@ libssh2_session_startup(LIBSSH2_SESSION *session, int socket);
.SH DESCRIPTION
\fIsession\fP - Session instance as returned by
.BR libssh2_session_init(3)
.BR libssh2_session_init_ex(3)
\fIsocket\fP - Connected socket descriptor. Typically a TCP connection
though the protocol allows for any reliable transport and the library will
@@ -39,4 +39,4 @@ the socket.
.SH SEE ALSO
.BR libssh2_session_free(3)
.BR libssh2_session_init(3)
.BR libssh2_session_init_ex(3)

View File

@@ -1,4 +1,4 @@
.\" $Id: libssh2_sftp_close_handle.3,v 1.1 2007/06/14 15:45:03 jehousley Exp $
.\" $Id: libssh2_sftp_close_handle.3,v 1.3 2009/03/17 10:34:27 bagder Exp $
.\"
.TH libssh2_sftp_close_handle 3 "1 Jun 2007" "libssh2 0.15" "libssh2 manual"
.SH NAME
@@ -17,19 +17,17 @@ int
libssh2_sftp_closedir(LIBSSH2_SFTP_HANDLE *handle);
.SH DESCRIPTION
\fIhandle\fP - SFTP File Handle as returned by
.BR libssh2_sftp_open(3)
or
.BR libssh2_sftp_opendir(3)
\fIhandle\fP - SFTP File Handle as returned by \fBlibssh2_sftp_open_ex(3)\fP
or \fBlibssh2_sftp_opendir(3)\fP (which is a macro).
Close an active LIBSSH2_SFTP_HANDLE. Because files and directories
share the same underlying storage mechanism these methods may be used
interchangably. It is recommended that
.BR libssh2_sftp_close()
.BR libssh2_sftp_closedir()
be used for files and that
.BR libssh2_sftp_closedir()
be used for directories so that future changes in the library
may cause minimal disruption.
be used for directories so that future changes in the library may cause
minimal disruption. Both are macros for \fBlibssh2_sftp_close_handle\fP.
.SH RETURN VALUE
Return 0 on success or negative on failure. It returns
@@ -48,5 +46,4 @@ received on the socket, or an SFTP operation caused an errorcode to
be returned by the server.
.SH SEE ALSO
.BR libssh2_sftp_open(3)
.BR libssh2_sftp_opendir(3)
.BR libssh2_sftp_open_ex(3)

View File

@@ -1,4 +1,4 @@
.\" $Id: libssh2_sftp_fstat_ex.3,v 1.1 2007/06/14 15:45:03 jehousley Exp $
.\" $Id: libssh2_sftp_fstat_ex.3,v 1.2 2009/03/16 23:25:14 bagder Exp $
.\"
.TH libssh2_sftp_fstat_ex 3 "1 Jun 2007" "libssh2 0.15" "libssh2 manual"
.SH NAME
@@ -18,7 +18,7 @@ libssh2_sftp_fsetstat(LIBSSH2_SFTP_HANDLE *handle, LIBSSH2_SFTP_ATTRIBUTES *attr
.SH DESCRIPTION
\fIhandle\fP - SFTP File Handle as returned by
.BR libssh2_sftp_open(3)
.BR libssh2_sftp_open_ex(3)
\fIattrs\fP - Pointer to attribute structure to set file metadata
from or into depending on the value of setstat.
@@ -28,12 +28,10 @@ with the data found in attrs according to the values of attrs->flags
and other relevant member attributes.
Get or Set statbuf type data for a given LIBSSH2_SFTP_HANDLE instance.
.SH RETURN VALUE
Return 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.
.SH ERRORS
\fILIBSSH2_ERROR_ALLOC\fP - An internal memory allocation call failed.
@@ -44,6 +42,5 @@ LIBSSH2_ERROR_EAGAIN is a negative number, it isn't really a failure per se.
\fILIBSSH2_ERROR_SFTP_PROTOCOL\fP - An invalid SFTP protocol response was
received on the socket, or an SFTP operation caused an errorcode to
be returned by the server.
.SH SEE ALSO
.BR libssh2_sftp_open(3)
.BR libssh2_sftp_open_ex(3)

View File

@@ -1,4 +1,4 @@
.\" $Id: libssh2_sftp_init.3,v 1.7 2007/11/21 14:07:32 dottedmag Exp $
.\" $Id: libssh2_sftp_init.3,v 1.8 2009/03/16 23:25:14 bagder Exp $
.\"
.TH libssh2_sftp_init 3 "1 Jun 2007" "libssh2 0.15" "libssh2 manual"
.SH NAME
@@ -12,7 +12,7 @@ libssh2_sftp_init(LIBSSH2_SESSION *session);
.SH DESCRIPTION
\fIsession\fP - Session instance as returned by
.BR libssh2_session_init(3)
.BR libssh2_session_init_ex(3)
Open a channel and initialize the SFTP subsystem. Although the SFTP subsystem
operates over the same type of channel as those exported by the Channel API,
@@ -34,8 +34,8 @@ A pointer to the newly allocated SFTP instance or NULL on failure.
received on the socket, or an SFTP operation caused an errorcode to be
returned by the server.
\fILIBSSH2_ERROR_EAGAIN\fP - Marked for non-blocking I/O but the call would block.
\fILIBSSH2_ERROR_EAGAIN\fP - Marked for non-blocking I/O but the call would
block.
.SH SEE ALSO
.BR libssh2_sftp_shutdown(3)
.BR libssh2_sftp_open_ex(3)

View File

@@ -1,4 +1,4 @@
.\" $Id: libssh2_sftp_mkdir_ex.3,v 1.6 2007/06/13 16:41:33 jehousley Exp $
.\" $Id: libssh2_sftp_mkdir_ex.3,v 1.7 2009/03/16 23:25:14 bagder Exp $
.\"
.TH libssh2_sftp_mkdir_ex 3 "1 Jun 2007" "libssh2 0.15" "libssh2 manual"
.SH NAME
@@ -12,7 +12,6 @@ libssh2_sftp_mkdir_ex(LIBSSH2_SFTP *sftp, const char *path, unsigned int path_le
int
libssh2_sftp_mkdir(LIBSSH2_SFTP *sftp, const char *path, long mode);
.SH DESCRIPTION
\fIsftp\fP - SFTP instance as returned by
.BR libssh2_sftp_init(3)
@@ -25,12 +24,10 @@ directory's parents must all exist priot to making this call.
\fImode\fP - directory creation mode (e.g. 0755).
Create a directory on the remote file system.
.SH RETURN VALUE
Return 0 on success 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.
.SH ERRORS
\fILIBSSH2_ERROR_ALLOC\fP - An internal memory allocation call failed.
@@ -41,6 +38,5 @@ LIBSSH2_ERROR_EAGAIN is a negative number, it isn't really a failure per se.
\fILIBSSH2_ERROR_SFTP_PROTOCOL\fP - An invalid SFTP protocol response was
received on the socket, or an SFTP operation caused an errorcode to be
returned by the server.
.SH SEE ALSO
.BR libssh2_sftp_opendir(3)
.BR libssh2_sftp_open_ex(3)

View File

@@ -1,4 +1,4 @@
.\" $Id: libssh2_sftp_open_ex.3,v 1.9 2007/11/21 14:07:32 dottedmag Exp $
.\" $Id: libssh2_sftp_open_ex.3,v 1.10 2009/03/16 23:25:14 bagder Exp $
.\"
.TH libssh2_sftp_open_ex 3 "1 Jun 2007" "libssh2 0.15" "libssh2 manual"
.SH NAME
@@ -46,8 +46,8 @@ failure.
received on the socket, or an SFTP operation caused an errorcode to be
returned by the server.
\fILIBSSH2_ERROR_EAGAIN\fP - Marked for non-blocking I/O but the call would block.
\fILIBSSH2_ERROR_EAGAIN\fP - Marked for non-blocking I/O but the call would
block.
.SH SEE ALSO
.BR libssh_sftp_close(3)
.BR libssh2_sftp_close_handle(3)

View File

@@ -1,4 +1,4 @@
.\" $Id: libssh2_sftp_read.3,v 1.8 2007/06/13 16:41:33 jehousley Exp $
.\" $Id: libssh2_sftp_read.3,v 1.10 2009/03/17 10:34:27 bagder Exp $
.\"
.TH libssh2_sftp_read 3 "1 Jun 2007" "libssh2 0.15" "libssh2 manual"
.SH NAME
@@ -12,7 +12,7 @@ libssh2_sftp_read(LIBSSH2_SFTP_HANDLE *handle, char *buffer, size_t buffer_maxle
.SH DESCRIPTION
\fIhandle\fP is the SFTP File Handle as returned by
.BR libssh2_sftp_open(3)
.BR libssh2_sftp_open_ex(3)
\fIbuffer\fP is a pointer to a pre-allocated buffer of at least
@@ -23,10 +23,9 @@ after the POSIX
.BR read(2)
function and uses the same calling semantics.
.BR libssh2_sftp_read(3)
will attempt to read as much as possible however it may not fill all of
buffer if the file pointer reaches the end or
if further reads would cause the socket to block.
will attempt to read as much as possible however it may not fill all of buffer
if the file pointer reaches the end or if further reads would cause the socket
to block.
.SH RETURN VALUE
Number of bytes actually populated into buffer, or negative on failure.
It returns LIBSSH2_ERROR_EAGAIN when it would otherwise block. While
@@ -38,10 +37,9 @@ LIBSSH2_ERROR_EAGAIN is a negative number, it isn't really a failure per se.
\fILIBSSH2_ERROR_SOCKET_TIMEOUT\fP -
\fILIBSSH2_ERROR_SFTP_PROTOCOL\fP - An invalid SFTP protocol response was
received on the socket, or an SFTP operation caused an errorcode to be
\fILIBSSH2_ERROR_SFTP_PROTOCOL\fP - An invalid SFTP protocol response was
received on the socket, or an SFTP operation caused an errorcode to be
returned by the server.
.SH SEE ALSO
.BR libssh2_sftp_open(3)
.BR libssh2_sftp_readnb(3)
.BR libssh2_sftp_open_ex(3)
.BR libssh2_sftp_read(3)

View File

@@ -1,4 +1,4 @@
.\" $Id: libssh2_sftp_readdir.3,v 1.11 2007/07/04 10:44:40 jehousley Exp $
.\" $Id: libssh2_sftp_readdir_ex.3,v 1.2 2009/03/16 23:25:14 bagder Exp $
.\"
.TH libssh2_sftp_readdir_ex 3 "1 Jun 2007" "libssh2 0.15" "libssh2 manual"
.SH NAME
@@ -15,7 +15,7 @@ libssh2_sftp_readdir(LIBSSH2_SFTP_HANDLE *handle, char *buffer, size_t buffer_ma
.SH DESCRIPTION
\fIhandle\fP - is the SFTP File Handle as returned by
.BR libssh2_sftp_diropen(3)
.BR libssh2_sftp_open_ex(3)
\fIbuffer\fP - is a pointer to a pre-allocated buffer of at least
\fIbuffer_maxlen\fP bytes to read data into.
@@ -41,8 +41,8 @@ however, it uses a variable sized directory entry (filename) buffer and
returns statbuf type data in the same call.
.SH RETURN VALUE
Number of bytes actually populated into buffer, or negative on failure. It returns
LIBSSH2_ERROR_EAGAIN when it would otherwise block. While
Number of bytes actually populated into buffer, 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.
.SH ERRORS
\fILIBSSH2_ERROR_ALLOC\fP - An internal memory allocation call failed.
@@ -54,7 +54,6 @@ LIBSSH2_ERROR_EAGAIN is a negative number, it isn't really a failure per se.
\fILIBSSH2_ERROR_SFTP_PROTOCOL\fP - An invalid SFTP protocol response was
received on the socket, or an SFTP operation caused an errorcode to be
returned by the server.
.SH SEE ALSO
.BR libssh2_sftp_opendir(3)
.BR libssh2_sftp_closedir(3)
.BR libssh2_sftp_open_ex(3),
.BR libssh2_sftp_close_handle(3)

View File

@@ -1,4 +1,4 @@
.\" $Id: libssh2_sftp_seek.3,v 1.3 2008/12/22 13:18:36 bagder Exp $
.\" $Id: libssh2_sftp_seek.3,v 1.5 2009/03/17 10:34:27 bagder Exp $
.\"
.TH libssh2_sftp_seek 3 "22 Dec 2008" "libssh2 1.0" "libssh2 manual"
.SH NAME
@@ -15,7 +15,7 @@ libssh2_sftp_seek64(LIBSSH2_SFTP_HANDLE *handle, libssh2_uint64_t offset);
.SH DESCRIPTION
\fIhandle\fP - SFTP File Handle as returned by
.BR libssh2_sftp_open(3)
.BR libssh2_sftp_open_ex(3)
\fIoffset\fP - Number of bytes from the beginning of file to seek to.
@@ -27,4 +27,4 @@ convenience offset during read/write operations.
.SH AVAILABILITY
libssh2_sftp_seek64(3) was added in 1.0
.SH SEE ALSO
.BR libssh2_sftp_open(3)
.BR libssh2_sftp_open_ex(3)

View File

@@ -1,4 +1,4 @@
.\" $Id: libssh2_sftp_tell.3,v 1.2 2008/12/22 12:46:45 bagder Exp $
.\" $Id: libssh2_sftp_tell.3,v 1.3 2009/03/17 10:34:27 bagder Exp $
.\"
.TH libssh2_sftp_tell 3 "1 Jun 2007" "libssh2 0.15" "libssh2 manual"
.SH NAME
@@ -11,12 +11,12 @@ size_t
libssh2_sftp_tell(LIBSSH2_SFTP_HANDLE *handle);
.SH DESCRIPTION
\fIhandle\fP - SFTP File Handle as returned by \fBlibssh2_sftp_open(3)\fP.
\fIhandle\fP - SFTP File Handle as returned by \fBlibssh2_sftp_open_ex(3)\fP.
Returns the current offset of the file handle's internal pointer. Note that
this is now deprecated. Use the newer \fBlibssh2_sftp_tell64(3)\fP instead!
.SH RETURN VALUE
Current offset from beginning of file in bytes.
.SH SEE ALSO
.BR libssh2_sftp_open(3),
.BR libssh2_sftp_open_ex(3),
.BR libssh2_sftp_tell64(3)

View File

@@ -1,4 +1,4 @@
.\" $Id: libssh2_sftp_tell64.3,v 1.1 2008/12/22 12:46:45 bagder Exp $
.\" $Id: libssh2_sftp_tell64.3,v 1.2 2009/03/17 10:34:27 bagder Exp $
.\"
.TH libssh2_sftp_tell64 3 "22 Dec 2008" "libssh2 1.0" "libssh2 manual"
.SH NAME
@@ -11,7 +11,7 @@ libssh2_uint64_t
libssh2_sftp_tell64(LIBSSH2_SFTP_HANDLE *handle);
.SH DESCRIPTION
\fIhandle\fP - SFTP File Handle as returned by \fBlibssh2_sftp_open(3)\fP
\fIhandle\fP - SFTP File Handle as returned by \fBlibssh2_sftp_open_ex(3)\fP
Identify the current offset of the file handle's internal pointer.
.SH RETURN VALUE
@@ -19,5 +19,5 @@ Current offset from beginning of file in bytes.
.SH AVAILABILITY
Added in libssh2 1.0
.SH SEE ALSO
.BR libssh2_sftp_open(3),
.BR libssh2_sftp_open_ex(3),
.BR libssh2_sftp_tell(3)

View File

@@ -1,4 +1,4 @@
.\" $Id: libssh2_sftp_write.3,v 1.2 2008/12/23 12:34:17 bagder Exp $
.\" $Id: libssh2_sftp_write.3,v 1.3 2009/03/17 10:34:27 bagder Exp $
.\"
.TH libssh2_sftp_write 3 "1 Jun 2007" "libssh2 0.15" "libssh2 manual"
.SH NAME
@@ -12,7 +12,7 @@ libssh2_sftp_write(LIBSSH2_SFTP_HANDLE *handle, const char *buffer, size_t count
.SH DESCRIPTION
\fIhandle\fP - SFTP File Handle as returned by
.BR libssh2_sftp_open(3)
.BR libssh2_sftp_open_ex(3)
\fIbuffer\fP - Pre-initialized data buffer to write to the LIBSSH2_SFTP_HANDLE.
@@ -38,4 +38,4 @@ received on the socket, or an SFTP operation caused an errorcode to
be returned by the server.
.SH SEE ALSO
.BR libssh2_sftp_open(3)
.BR libssh2_sftp_open_ex(3)

View File

@@ -1,4 +1,4 @@
.\" $Id: libssh2_userauth_authenticated.3,v 1.1 2007/06/14 17:15:32 jehousley Exp $
.\" $Id: libssh2_userauth_authenticated.3,v 1.2 2009/03/17 10:34:27 bagder Exp $
.\"
.TH libssh2_userauth_authenticated 3 "1 Jun 2007" "libssh2 0.15" "libssh2 manual"
.SH NAME
@@ -11,7 +11,7 @@ libssh2_userauth_authenticated(LIBSSH2_SESSION *session);
.SH DESCRIPTION
\fIsession\fP - Session instance as returned by
.BR libssh2_session_init(3)
.BR libssh2_session_init_ex(3)
Indicates whether or not the named session has been successfully authenticated.
@@ -19,4 +19,4 @@ Indicates whether or not the named session has been successfully authenticated.
Returns 1 if authenticated and 0 if not.
.SH SEE ALSO
.BR libssh2_session_init(3)
.BR libssh2_session_init_ex(3)

View File

@@ -0,0 +1,14 @@
.\" $Id: libssh2_userauth_hostbased_fromfile_ex.3,v 1.1 2009/03/16 15:00:45 bagder Exp $
.\"
.TH libssh2_userauth_hostbased_fromfile_ex 3 "1 Jun 2007" "libssh2 0.15" "libssh2 manual"
.SH NAME
libssh2_userauth_hostbased_fromfile_ex - TODO
.SH SYNOPSIS
.SH DESCRIPTION
.SH RETURN VALUE
.SH ERRORS
.SH SEE ALSO

View File

@@ -1,4 +1,4 @@
.\" $Id: libssh2_userauth_keyboard_interactive_ex.3,v 1.1 2008/03/08 18:26:32 dottedmag Exp $
.\" $Id: libssh2_userauth_keyboard_interactive_ex.3,v 1.2 2009/03/17 10:34:27 bagder Exp $
.\"
.TH libssh2_userauth_keyboard_interactive_ex 3 "8 Mar 2008" "libssh2 0.19" "libssh2 manual"
.SH NAME
@@ -14,7 +14,7 @@ libssh2_userauth_keyboard_interactive(LIBSSH2_SESSION *session, const char *user
.SH DESCRIPTION
\fIsession\fP - Session instance as returned by
.BR libssh2_session_init(3)
.BR libssh2_session_init_ex(3)
\fIusername\fP - Name of user to attempt plain password authentication for.
@@ -40,4 +40,4 @@ LIBSSH2_ERROR_EAGAIN is a negative number, it isn't really a failure per se.
\fILIBSSH2_ERROR_SOCKET_SEND\fP - Unable to send data on socket.
.SH SEE ALSO
.BR libssh2_session_init(3)
.BR libssh2_session_init_ex(3)

View File

@@ -1,4 +1,4 @@
.\" $Id: libssh2_userauth_list.3,v 1.1 2007/06/14 17:15:32 jehousley Exp $
.\" $Id: libssh2_userauth_list.3,v 1.2 2009/03/17 10:34:27 bagder Exp $
.\"
.TH libssh2_userauth_list 3 "1 Jun 2007" "libssh2 0.15" "libssh2 manual"
.SH NAME
@@ -11,7 +11,7 @@ libssh2_userauth_list(LIBSSH2_SESSION *session, const char *username, unsigned i
.SH DESCRIPTION
\fIsession\fP - Session instance as returned by
.BR libssh2_session_init(3)
.BR libssh2_session_init_ex(3)
\fIusername\fP - Username which will be used while authenticating. Note
that most server implementations do not permit attempting authentication
@@ -40,4 +40,4 @@ internally managed by libssh2. On failure ruturns NULL.
\fILIBSSH2_ERROR_EAGAIN\fP - Marked for non-blocking I/O but the call
.SH SEE ALSO
.BR libssh2_session_init(3)
.BR libssh2_session_init_ex(3)

View File

@@ -1,4 +1,4 @@
.\" $Id: libssh2_userauth_password_ex.3,v 1.1 2007/06/14 17:15:32 jehousley Exp $
.\" $Id: libssh2_userauth_password_ex.3,v 1.2 2009/03/17 10:34:27 bagder Exp $
.\"
.TH libssh2_userauth_password_ex 3 "1 Jun 2007" "libssh2 0.15" "libssh2 manual"
.SH NAME
@@ -14,7 +14,7 @@ libssh2_userauth_password(LIBSSH2_SESSION *session, const char *username, const
.SH DESCRIPTION
\fIsession\fP - Session instance as returned by
.BR libssh2_session_init(3)
.BR libssh2_session_init_ex(3)
\fIusername\fP - Name of user to attempt plain password authentication for.
@@ -47,4 +47,4 @@ LIBSSH2_ERROR_EAGAIN is a negative number, it isn't really a failure per se.
\fILIBSSH2_ERROR_PASSWORD_EXPIRED\fP -
.SH SEE ALSO
.BR libssh2_session_init(3)
.BR libssh2_session_init_ex(3)

View File

@@ -1,4 +1,4 @@
.\" $Id: libssh2_userauth_publickey_fromfile.3,v 1.1 2007/06/14 17:15:32 jehousley Exp $
.\" $Id: libssh2_userauth_publickey_fromfile_ex.3,v 1.2 2009/03/17 10:34:27 bagder Exp $
.\"
.TH libssh2_userauth_publickey_fromfile 3 "1 Jun 2007" "libssh2 0.15" "libssh2 manual"
.SH NAME
@@ -14,7 +14,7 @@ libssh2_userauth_publickey_fromfile_ex(LIBSSH2_SESSION *session, const char *use
.SH DESCRIPTION
\fIsession\fP - Session instance as returned by
.BR libssh2_session_init(3)
.BR libssh2_session_init_ex(3)
\fIusername\fP - Remote user name to authenticate as.
@@ -48,4 +48,4 @@ combination was invalid, or the signature for the supplied public
key was invalid.
.SH SEE ALSO
.BR libssh2_session_init(3)
.BR libssh2_session_init_ex(3)

38
docs/libssh2_version.3 Normal file
View File

@@ -0,0 +1,38 @@
.\" $Id: libssh2_version.3,v 1.1 2009/02/23 16:22:46 bagder Exp $
.\"
.TH libssh2_version 3 "23 Feb 2009" "libssh2 1.1" "libssh2 manual"
.SH NAME
libssh2_version - return the libssh2 version number
.SH SYNOPSIS
#include <libssh2.h>
const char *
libssh2_version(int required_version);
.SH DESCRIPTION
If \fIrequired_version\fP is lower than or equal to the version number of the
libssh2 in use, the version number of libssh2 is returned as a pointer to a
zero terminated string.
The \fIrequired_version\fP should be the version number as constructed by the
LIBSSH2_VERSION_NUM define in the libssh2.h public header file, which is a 24
bit number in the 0xMMmmpp format. MM for major, mm for minor and pp for patch
number.
.SH RETURN VALUE
The version number of libssh2 is returned as a pointer to a zero terminated
string or NULL if the \fIrequired_version\fP isn't fulfilled.
.SH EXAMPLE
To make sure you run with the correct libssh2 version:
.nf
if (!libssh2_version(LIBSSH2_VERSION_NUM)) {
fprintf (stderr, \&"Runtime libssh2 version too old!\&");
exit(1);
}
.fi
Unconditionally get the version number:
printf(\&"libssh2 version: %s\&", libssh2_version(0) );
.SH AVAILABILITY
This function was added in libssh2 1.1, in previous versions there way no way
to extract this info in run-time.

View File

@@ -1,7 +1,12 @@
/*
* $Id: scp_nonblock.c,v 1.13 2008/11/10 16:48:41 bagder Exp $
* $Id: scp_nonblock.c,v 1.15 2009/03/25 22:52:32 bagder Exp $
*
* Sample showing how to do SCP transfers in a non-blocking manner.
*
* The sample code has default values for host name, user name, password
* and path to copy, but you can specify them on the command line like:
*
* "scp_nonblock 192.168.0.1 user password /tmp/secrets"
*/
#include "libssh2_config.h"
@@ -32,6 +37,43 @@
#include <stdio.h>
#include <ctype.h>
/* diff in ms */
static long tvdiff(struct timeval newer, struct timeval older)
{
return (newer.tv_sec-older.tv_sec)*1000+
(newer.tv_usec-older.tv_usec)/1000;
}
static int waitsocket(int socket_fd, LIBSSH2_SESSION *session)
{
struct timeval timeout;
int rc;
fd_set fd;
fd_set *writefd = NULL;
fd_set *readfd = NULL;
int dir;
timeout.tv_sec = 10;
timeout.tv_usec = 0;
FD_ZERO(&fd);
FD_SET(socket_fd, &fd);
/* now make sure we wait in the correct direction */
dir = libssh2_session_block_directions(session);
if(dir & LIBSSH2_SESSION_BLOCK_INBOUND)
readfd = &fd;
if(dir & LIBSSH2_SESSION_BLOCK_OUTBOUND)
writefd = &fd;
rc = select(socket_fd + 1, readfd, writefd, NULL, &timeout);
return rc;
}
int main(int argc, char *argv[])
{
unsigned long hostaddr;
@@ -44,7 +86,12 @@ int main(int argc, char *argv[])
const char *password="password";
const char *scppath="/tmp/TEST";
struct stat fileinfo;
struct timeval start;
struct timeval end;
int rc;
int total = 0;
long time_ms;
int spin = 0;
#if defined(HAVE_IOCTLSOCKET)
long flag = 1;
#endif
@@ -110,10 +157,13 @@ int main(int argc, char *argv[])
/* Since we have set non-blocking, tell libssh2 we are non-blocking */
libssh2_session_set_blocking(session, 0);
gettimeofday(&start, NULL);
/* ... start it up. This will trade welcome banners, exchange keys,
* and setup crypto, compression, and MAC layers
*/
while ((rc = libssh2_session_startup(session, sock)) == LIBSSH2_ERROR_EAGAIN);
while ((rc = libssh2_session_startup(session, sock)) ==
LIBSSH2_ERROR_EAGAIN);
if (rc) {
fprintf(stderr, "Failure establishing SSH session: %d\n", rc);
return -1;
@@ -133,44 +183,55 @@ int main(int argc, char *argv[])
if (auth_pw) {
/* We could authenticate via password */
while ((rc = libssh2_userauth_password(session, username, password)) == LIBSSH2_ERROR_EAGAIN);
if (rc) {
while ((rc = libssh2_userauth_password(session, username, password)) ==
LIBSSH2_ERROR_EAGAIN);
if (rc) {
fprintf(stderr, "Authentication by password failed.\n");
goto shutdown;
}
} else {
/* Or by public key */
while ((rc = libssh2_userauth_publickey_fromfile(session, username,
"/home/username/.ssh/id_rsa.pub",
"/home/username/.ssh/id_rsa",
password)) == LIBSSH2_ERROR_EAGAIN);
"/home/username/"
".ssh/id_rsa.pub",
"/home/username/"
".ssh/id_rsa",
password)) ==
LIBSSH2_ERROR_EAGAIN);
if (rc) {
fprintf(stderr, "\tAuthentication by public key failed\n");
goto shutdown;
}
}
#if 0
libssh2_trace(session, LIBSSH2_TRACE_CONN);
#endif
/* Request a file via SCP */
fprintf(stderr, "libssh2_scp_recv()!\n");
do {
channel = libssh2_scp_recv(session, scppath, &fileinfo);
if ((!channel) && (libssh2_session_last_errno(session) != LIBSSH2_ERROR_EAGAIN)) {
char *err_msg;
if (!channel) {
if(libssh2_session_last_errno(session) != LIBSSH2_ERROR_EAGAIN) {
char *err_msg;
libssh2_session_last_error(session, &err_msg, NULL, 0);
fprintf(stderr, "%s\n", err_msg);
goto shutdown;
libssh2_session_last_error(session, &err_msg, NULL, 0);
fprintf(stderr, "%s\n", err_msg);
goto shutdown;
}
else {
fprintf(stderr, "libssh2_scp_recv() spin\n");
waitsocket(sock, session);
}
}
} while (!channel);
fprintf(stderr, "libssh2_scp_recv() is done, now receive data!\n");
while(got < fileinfo.st_size) {
char mem[1000];
struct timeval timeout;
char mem[1024*24];
int rc;
fd_set fd;
do {
int amount=sizeof(mem);
@@ -184,37 +245,34 @@ int main(int argc, char *argv[])
if (rc > 0) {
write(1, mem, rc);
got += rc;
total += rc;
}
} while (rc > 0);
if (rc == LIBSSH2_ERROR_EAGAIN) {
if ((rc == LIBSSH2_ERROR_EAGAIN) && (got < fileinfo.st_size)) {
/* this is due to blocking that would occur otherwise
so we loop on this condition */
timeout.tv_sec = 10;
timeout.tv_usec = 0;
FD_ZERO(&fd);
FD_SET(sock, &fd);
rc = select(sock+1, &fd, &fd, NULL, &timeout);
if (rc <= 0) {
/* negative is error
0 is timeout */
fprintf(stderr, "SCP timed out: %d\n", rc);
}
spin++;
waitsocket(sock, session); /* now we wait */
continue;
}
break;
}
gettimeofday(&end, NULL);
time_ms = tvdiff(end, start);
printf("Got %d bytes in %ld ms = %.1f bytes/sec spin: %d\n", total,
time_ms, total/(time_ms/1000.0), spin );
libssh2_channel_free(channel);
channel = NULL;
shutdown:
libssh2_session_disconnect(session, "Normal Shutdown, Thank you for playing");
libssh2_session_disconnect(session,
"Normal Shutdown, Thank you for playing");
libssh2_session_free(session);
#ifdef WIN32

View File

@@ -1,5 +1,5 @@
/*
* $Id: sftp.c,v 1.15 2008/11/10 16:48:41 bagder Exp $
* $Id: sftp.c,v 1.16 2009/03/31 12:20:36 bagder Exp $
*
* Sample showing how to do SFTP transfers.
*
@@ -131,9 +131,6 @@ int main(int argc, char *argv[])
return -1;
}
/* Since we have not set non-blocking, tell libssh2 we are blocking */
libssh2_session_set_blocking(session, 1);
/* At this point we havn't yet authenticated. The first thing to do
* is check the hostkey's fingerprint against our known hosts Your app
* may have it hard coded, may go to a file, may present it to the
@@ -207,9 +204,6 @@ int main(int argc, char *argv[])
goto shutdown;
}
/* Since we have not set non-blocking, tell libssh2 we are blocking */
libssh2_session_set_blocking(session, 1);
fprintf(stderr, "libssh2_sftp_open()!\n");
/* Request a file via SFTP */
sftp_handle =

View File

@@ -1,12 +1,12 @@
/*
* $Id: sftp_nonblock.c,v 1.15 2008/11/10 16:48:41 bagder Exp $
* $Id: sftp_nonblock.c,v 1.17 2009/03/13 22:14:47 bagder Exp $
*
* Sample showing how to do SFTP non-blocking transfers.
*
* The sample code has default values for host name, user name, password
* and path to copy, but you can specify them on the command line like:
*
* "sftp 192.168.0.1 user password /tmp/secrets"
* "sftp_nonblock 192.168.0.1 user password /tmp/secrets"
*/
#include "libssh2_config.h"
@@ -38,6 +38,43 @@
#include <stdio.h>
#include <ctype.h>
/* diff in ms */
static long tvdiff(struct timeval newer, struct timeval older)
{
return (newer.tv_sec-older.tv_sec)*1000+
(newer.tv_usec-older.tv_usec)/1000;
}
static int waitsocket(int socket_fd, LIBSSH2_SESSION *session)
{
struct timeval timeout;
int rc;
fd_set fd;
fd_set *writefd = NULL;
fd_set *readfd = NULL;
int dir;
timeout.tv_sec = 10;
timeout.tv_usec = 0;
FD_ZERO(&fd);
FD_SET(socket_fd, &fd);
/* now make sure we wait in the correct direction */
dir = libssh2_session_block_directions(session);
if(dir & LIBSSH2_SESSION_BLOCK_INBOUND)
readfd = &fd;
if(dir & LIBSSH2_SESSION_BLOCK_OUTBOUND)
writefd = &fd;
rc = select(socket_fd + 1, readfd, writefd, NULL, &timeout);
return rc;
}
int main(int argc, char *argv[])
{
unsigned long hostaddr;
@@ -48,7 +85,12 @@ int main(int argc, char *argv[])
const char *username="username";
const char *password="password";
const char *sftppath="/tmp/TEST";
struct timeval start;
struct timeval end;
int rc;
int total = 0;
long time_ms;
int spin = 0;
#if defined(HAVE_IOCTLSOCKET)
long flag = 1;
#endif
@@ -116,10 +158,13 @@ int main(int argc, char *argv[])
/* Since we have set non-blocking, tell libssh2 we are non-blocking */
libssh2_session_set_blocking(session, 0);
gettimeofday(&start, NULL);
/* ... start it up. This will trade welcome banners, exchange keys,
* and setup crypto, compression, and MAC layers
*/
while ((rc = libssh2_session_startup(session, sock)) == LIBSSH2_ERROR_EAGAIN);
while ((rc = libssh2_session_startup(session, sock)) ==
LIBSSH2_ERROR_EAGAIN);
if (rc) {
fprintf(stderr, "Failure establishing SSH session: %d\n", rc);
return -1;
@@ -139,66 +184,97 @@ int main(int argc, char *argv[])
if (auth_pw) {
/* We could authenticate via password */
while ((rc = libssh2_userauth_password(session, username, password)) == LIBSSH2_ERROR_EAGAIN);
while ((rc = libssh2_userauth_password(session, username, password))
== LIBSSH2_ERROR_EAGAIN);
if (rc) {
fprintf(stderr, "Authentication by password failed.\n");
goto shutdown;
}
} else {
/* Or by public key */
while ((rc = libssh2_userauth_publickey_fromfile(session, username,
"/home/username/.ssh/id_rsa.pub",
"/home/username/.ssh/id_rsa",
password)) == LIBSSH2_ERROR_EAGAIN);
while ((rc =
libssh2_userauth_publickey_fromfile(session, username,
"/home/username/"
".ssh/id_rsa.pub",
"/home/username/"
".ssh/id_rsa",
password)) ==
LIBSSH2_ERROR_EAGAIN);
if (rc) {
fprintf(stderr, "\tAuthentication by public key failed\n");
goto shutdown;
}
}
#if 0
libssh2_trace(session, LIBSSH2_TRACE_CONN);
#endif
fprintf(stderr, "libssh2_sftp_init()!\n");
do {
sftp_session = libssh2_sftp_init(session);
if ((!sftp_session) && (libssh2_session_last_errno(session) != LIBSSH2_ERROR_EAGAIN)) {
fprintf(stderr, "Unable to init SFTP session\n");
goto shutdown;
if(!sftp_session) {
if(libssh2_session_last_errno(session) ==
LIBSSH2_ERROR_EAGAIN) {
fprintf(stderr, "non-blocking init\n");
waitsocket(sock, session); /* now we wait */
}
else {
fprintf(stderr, "Unable to init SFTP session\n");
goto shutdown;
}
}
} while (!sftp_session);
fprintf(stderr, "libssh2_sftp_open()!\n");
/* Request a file via SFTP */
do {
sftp_handle = libssh2_sftp_open(sftp_session, sftppath, LIBSSH2_FXF_READ, 0);
sftp_handle = libssh2_sftp_open(sftp_session, sftppath,
LIBSSH2_FXF_READ, 0);
if ((!sftp_handle) && (libssh2_session_last_errno(session) != LIBSSH2_ERROR_EAGAIN)) {
fprintf(stderr, "Unable to open file with SFTP\n");
goto shutdown;
if (!sftp_handle) {
if (libssh2_session_last_errno(session) != LIBSSH2_ERROR_EAGAIN) {
fprintf(stderr, "Unable to open file with SFTP\n");
goto shutdown;
}
else {
fprintf(stderr, "non-blocking open\n");
waitsocket(sock, session); /* now we wait */
}
}
} while (!sftp_handle);
fprintf(stderr, "libssh2_sftp_open() is done, now receive data!\n");
do {
char mem[1024];
char mem[1024*24];
/* loop until we fail */
fprintf(stderr, "libssh2_sftp_readnb()!\n");
while ((rc = libssh2_sftp_read(sftp_handle, mem, sizeof(mem))) == LIBSSH2_ERROR_EAGAIN) {
;
while ((rc = libssh2_sftp_read(sftp_handle, mem,
sizeof(mem))) == LIBSSH2_ERROR_EAGAIN) {
spin++;
waitsocket(sock, session); /* now we wait */
}
if (rc > 0) {
total += rc;
write(1, mem, rc);
} else {
break;
}
} while (1);
gettimeofday(&end, NULL);
time_ms = tvdiff(end, start);
printf("Got %d bytes in %ld ms = %.1f bytes/sec spin: %d\n", total,
time_ms, total/(time_ms/1000.0), spin );
libssh2_sftp_close(sftp_handle);
libssh2_sftp_shutdown(sftp_session);
shutdown:
while ((rc = libssh2_session_disconnect(session, "Normal Shutdown, Thank you for playing")) == LIBSSH2_ERROR_EAGAIN);
printf("libssh2_session_disconnect\n");
while ((rc = libssh2_session_disconnect(session,
"Normal Shutdown, Thank you")) ==
LIBSSH2_ERROR_EAGAIN);
libssh2_session_free(session);
#ifdef WIN32

View File

@@ -1,5 +1,5 @@
/*
* $Id: sftp_write.c,v 1.9 2008/11/10 16:48:41 bagder Exp $
* $Id: sftp_write.c,v 1.10 2009/03/31 12:20:36 bagder Exp $
*
* Sample showing how to do SFTP write transfers.
*
@@ -155,9 +155,6 @@ int main(int argc, char *argv[])
goto shutdown;
}
/* Since we have not set non-blocking, tell libssh2 we are blocking */
libssh2_session_set_blocking(session, 1);
fprintf(stderr, "libssh2_sftp_open()!\n");
/* Request a file via SFTP */
sftp_handle =

View File

@@ -1,5 +1,5 @@
/*
* $Id: sftp_write_nonblock.c,v 1.12 2008/11/10 16:48:41 bagder Exp $
* $Id: sftp_write_nonblock.c,v 1.13 2009/03/31 12:20:36 bagder Exp $
*
* Sample showing how to do SFTP non-blocking write transfers.
*
@@ -180,9 +180,6 @@ int main(int argc, char *argv[])
}
} while (!sftp_session);
/* Since we have set non-blocking, tell libssh2 we are non-blocking */
libssh2_session_set_blocking(session, 0);
fprintf(stderr, "libssh2_sftp_open()!\n");
/* Request a file via SFTP */
do {

View File

@@ -60,7 +60,8 @@ extern "C" {
# endif /* LIBSSH2_WIN32 */
#endif /* LIBSSH2_API */
#if defined(LIBSSH2_DARWIN) || (defined(LIBSSH2_WIN32) && !defined(_MSC_VER) && !defined(__MINGW32__))
#if defined(LIBSSH2_DARWIN) || (defined(LIBSSH2_WIN32) && \
!defined(_MSC_VER) && !defined(__MINGW32__))
# include <sys/uio.h>
#endif
@@ -84,14 +85,14 @@ typedef long long libssh2_int64_t;
/* We use underscore instead of dash when appending CVS in dev versions just
to make the BANNER define (used by src/session.c) be a valid SSH
banner. Release versions have no appended strings and may of coruse not
banner. Release versions have no appended strings and may of course not
have dashes either. */
#define LIBSSH2_VERSION "1.0.0_CVS"
#define LIBSSH2_VERSION "1.1_CVS"
/* The numeric version number is also available "in parts" by using these
defines: */
#define LIBSSH2_VERSION_MAJOR 1
#define LIBSSH2_VERSION_MINOR 0
#define LIBSSH2_VERSION_MINOR 1
#define LIBSSH2_VERSION_PATCH 0
/* This is the numeric version of the libssh2 version number, meant for easier
@@ -109,7 +110,7 @@ typedef long long libssh2_int64_t;
and it is always a greater number in a more recent release. It makes
comparisons with greater than and less than work.
*/
#define LIBSSH2_VERSION_NUM 0x010000
#define LIBSSH2_VERSION_NUM 0x010100
/*
* This is the date and time when the full source package was created. The
@@ -145,19 +146,23 @@ typedef long long libssh2_int64_t;
/* 0.25 * 120 == 30 seconds */
#define LIBSSH2_SOCKET_POLL_MAXLOOPS 120
/* Maximum size to allow a payload to compress to, plays it safe by falling short of spec limits */
/* Maximum size to allow a payload to compress to, plays it safe by falling
short of spec limits */
#define LIBSSH2_PACKET_MAXCOMP 32000
/* Maximum size to allow a payload to deccompress to, plays it safe by allowing more than spec requires */
/* Maximum size to allow a payload to deccompress to, plays it safe by
allowing more than spec requires */
#define LIBSSH2_PACKET_MAXDECOMP 40000
/* Maximum size for an inbound compressed payload, plays it safe by overshooting spec limits */
/* Maximum size for an inbound compressed payload, plays it safe by
overshooting spec limits */
#define LIBSSH2_PACKET_MAXPAYLOAD 40000
/* Malloc callbacks */
#define LIBSSH2_ALLOC_FUNC(name) void *name(size_t count, void **abstract)
#define LIBSSH2_REALLOC_FUNC(name) void *name(void *ptr, size_t count, void **abstract)
#define LIBSSH2_FREE_FUNC(name) void name(void *ptr, void **abstract)
#define LIBSSH2_ALLOC_FUNC(name) void *name(size_t count, void **abstract)
#define LIBSSH2_REALLOC_FUNC(name) void *name(void *ptr, size_t count, \
void **abstract)
#define LIBSSH2_FREE_FUNC(name) void name(void *ptr, void **abstract)
typedef struct _LIBSSH2_USERAUTH_KBDINT_PROMPT
{
@@ -173,17 +178,42 @@ typedef struct _LIBSSH2_USERAUTH_KBDINT_RESPONSE
} LIBSSH2_USERAUTH_KBDINT_RESPONSE;
/* 'keyboard-interactive' authentication callback */
#define LIBSSH2_USERAUTH_KBDINT_RESPONSE_FUNC(name_) void name_(const char* name, int name_len, const char* instruction, int instruction_len, int num_prompts, const LIBSSH2_USERAUTH_KBDINT_PROMPT* prompts, LIBSSH2_USERAUTH_KBDINT_RESPONSE* responses, void **abstract)
#define LIBSSH2_USERAUTH_KBDINT_RESPONSE_FUNC(name_) \
void name_(const char* name, int name_len, const char* instruction, \
int instruction_len, int num_prompts, \
const LIBSSH2_USERAUTH_KBDINT_PROMPT* prompts, \
LIBSSH2_USERAUTH_KBDINT_RESPONSE* responses, void **abstract)
/* Callbacks for special SSH packets */
#define LIBSSH2_IGNORE_FUNC(name) void name(LIBSSH2_SESSION *session, const char *message, int message_len, void **abstract)
#define LIBSSH2_DEBUG_FUNC(name) void name(LIBSSH2_SESSION *session, int always_display, const char *message, int message_len, const char *language, int language_len,void **abstract)
#define LIBSSH2_DISCONNECT_FUNC(name) void name(LIBSSH2_SESSION *session, int reason, const char *message, int message_len, const char *language, int language_len, void **abstract)
#define LIBSSH2_PASSWD_CHANGEREQ_FUNC(name) void name(LIBSSH2_SESSION *session, char **newpw, int *newpw_len, void **abstract)
#define LIBSSH2_MACERROR_FUNC(name) int name(LIBSSH2_SESSION *session, const char *packet, int packet_len, void **abstract)
#define LIBSSH2_X11_OPEN_FUNC(name) void name(LIBSSH2_SESSION *session, LIBSSH2_CHANNEL *channel, const char *shost, int sport, void **abstract)
#define LIBSSH2_IGNORE_FUNC(name) \
void name(LIBSSH2_SESSION *session, const char *message, int message_len, \
void **abstract)
#define LIBSSH2_CHANNEL_CLOSE_FUNC(name) void name(LIBSSH2_SESSION *session, void **session_abstract, LIBSSH2_CHANNEL *channel, void **channel_abstract)
#define LIBSSH2_DEBUG_FUNC(name) \
void name(LIBSSH2_SESSION *session, int always_display, const char *message, \
int message_len, const char *language, int language_len, \
void **abstract)
#define LIBSSH2_DISCONNECT_FUNC(name) \
void name(LIBSSH2_SESSION *session, int reason, const char *message, \
int message_len, const char *language, int language_len, \
void **abstract)
#define LIBSSH2_PASSWD_CHANGEREQ_FUNC(name) \
void name(LIBSSH2_SESSION *session, char **newpw, int *newpw_len, \
void **abstract)
#define LIBSSH2_MACERROR_FUNC(name) \
int name(LIBSSH2_SESSION *session, const char *packet, int packet_len, \
void **abstract)
#define LIBSSH2_X11_OPEN_FUNC(name) \
void name(LIBSSH2_SESSION *session, LIBSSH2_CHANNEL *channel, \
const char *shost, int sport, void **abstract)
#define LIBSSH2_CHANNEL_CLOSE_FUNC(name) \
void name(LIBSSH2_SESSION *session, void **session_abstract, \
LIBSSH2_CHANNEL *channel, void **channel_abstract)
/* libssh2_session_callback_set() constants */
#define LIBSSH2_CALLBACK_IGNORE 0
@@ -217,7 +247,8 @@ typedef struct _LIBSSH2_POLLFD {
union {
int socket; /* File descriptors -- examined with system select() call */
LIBSSH2_CHANNEL *channel; /* Examined by checking internal state */
LIBSSH2_LISTENER *listener; /* Read polls only -- are inbound connections waiting to be accepted? */
LIBSSH2_LISTENER *listener; /* Read polls only -- are inbound
connections waiting to be accepted? */
} fd;
unsigned long events; /* Requested Events */
@@ -229,20 +260,28 @@ typedef struct _LIBSSH2_POLLFD {
#define LIBSSH2_POLLFD_CHANNEL 2
#define LIBSSH2_POLLFD_LISTENER 3
/* Note: Win32 Doesn't actually have a poll() implementation, so some of these values are faked with select() data */
/* Note: Win32 Doesn't actually have a poll() implementation, so some of these
values are faked with select() data */
/* Poll FD events/revents -- Match sys/poll.h where possible */
#define LIBSSH2_POLLFD_POLLIN 0x0001 /* Data available to be read or connection available -- All */
#define LIBSSH2_POLLFD_POLLPRI 0x0002 /* Priority data available to be read -- Socket only */
#define LIBSSH2_POLLFD_POLLEXT 0x0002 /* Extended data available to be read -- Channel only */
#define LIBSSH2_POLLFD_POLLOUT 0x0004 /* Can may be written -- Socket/Channel */
#define LIBSSH2_POLLFD_POLLIN 0x0001 /* Data available to be read or
connection available --
All */
#define LIBSSH2_POLLFD_POLLPRI 0x0002 /* Priority data available to
be read -- Socket only */
#define LIBSSH2_POLLFD_POLLEXT 0x0002 /* Extended data available to
be read -- Channel only */
#define LIBSSH2_POLLFD_POLLOUT 0x0004 /* Can may be written --
Socket/Channel */
/* revents only */
#define LIBSSH2_POLLFD_POLLERR 0x0008 /* Error Condition -- Socket */
#define LIBSSH2_POLLFD_POLLHUP 0x0010 /* HangUp/EOF -- Socket */
#define LIBSSH2_POLLFD_SESSION_CLOSED 0x0010 /* Session Disconnect */
#define LIBSSH2_POLLFD_POLLNVAL 0x0020 /* Invalid request -- Socket Only */
#define LIBSSH2_POLLFD_POLLEX 0x0040 /* Exception Condition -- Socket/Win32 */
#define LIBSSH2_POLLFD_CHANNEL_CLOSED 0x0080 /* Channel Disconnect */
#define LIBSSH2_POLLFD_LISTENER_CLOSED 0x0080 /* Listener Disconnect */
#define LIBSSH2_POLLFD_POLLERR 0x0008 /* Error Condition -- Socket */
#define LIBSSH2_POLLFD_POLLHUP 0x0010 /* HangUp/EOF -- Socket */
#define LIBSSH2_POLLFD_SESSION_CLOSED 0x0010 /* Session Disconnect */
#define LIBSSH2_POLLFD_POLLNVAL 0x0020 /* Invalid request -- Socket
Only */
#define LIBSSH2_POLLFD_POLLEX 0x0040 /* Exception Condition --
Socket/Win32 */
#define LIBSSH2_POLLFD_CHANNEL_CLOSED 0x0080 /* Channel Disconnect */
#define LIBSSH2_POLLFD_LISTENER_CLOSED 0x0080 /* Listener Disconnect */
#define HAVE_LIBSSH2_SESSION_BLOCK_DIRECTION
/* Block Direction Types */
@@ -311,46 +350,97 @@ typedef struct _LIBSSH2_POLLFD {
#define LIBSSH2_ERROR_EAGAIN -37
/* Session API */
LIBSSH2_API LIBSSH2_SESSION *libssh2_session_init_ex(LIBSSH2_ALLOC_FUNC((*my_alloc)), LIBSSH2_FREE_FUNC((*my_free)), LIBSSH2_REALLOC_FUNC((*my_realloc)), void *abstract);
#define libssh2_session_init() libssh2_session_init_ex(NULL, NULL, NULL, NULL)
LIBSSH2_API LIBSSH2_SESSION *
libssh2_session_init_ex(LIBSSH2_ALLOC_FUNC((*my_alloc)),
LIBSSH2_FREE_FUNC((*my_free)),
LIBSSH2_REALLOC_FUNC((*my_realloc)), void *abstract);
#define libssh2_session_init() libssh2_session_init_ex(NULL, NULL, NULL, NULL)
LIBSSH2_API void **libssh2_session_abstract(LIBSSH2_SESSION *session);
LIBSSH2_API void *libssh2_session_callback_set(LIBSSH2_SESSION *session, int cbtype, void *callback);
LIBSSH2_API int libssh2_banner_set(LIBSSH2_SESSION *session, const char *banner);
LIBSSH2_API void *libssh2_session_callback_set(LIBSSH2_SESSION *session,
int cbtype, void *callback);
LIBSSH2_API int libssh2_banner_set(LIBSSH2_SESSION *session,
const char *banner);
LIBSSH2_API int libssh2_session_startup(LIBSSH2_SESSION *session, int sock);
LIBSSH2_API int libssh2_session_disconnect_ex(LIBSSH2_SESSION *session, int reason, const char *description, const char *lang);
#define libssh2_session_disconnect(session, description) libssh2_session_disconnect_ex((session), SSH_DISCONNECT_BY_APPLICATION, (description), "")
LIBSSH2_API int libssh2_session_disconnect_ex(LIBSSH2_SESSION *session,
int reason,
const char *description,
const char *lang);
#define libssh2_session_disconnect(session, description) \
libssh2_session_disconnect_ex((session), SSH_DISCONNECT_BY_APPLICATION, \
(description), "")
LIBSSH2_API int libssh2_session_free(LIBSSH2_SESSION *session);
LIBSSH2_API const char *libssh2_hostkey_hash(LIBSSH2_SESSION *session, int hash_type);
LIBSSH2_API const char *libssh2_hostkey_hash(LIBSSH2_SESSION *session,
int hash_type);
LIBSSH2_API int libssh2_session_method_pref(LIBSSH2_SESSION *session, int method_type, const char *prefs);
LIBSSH2_API const char *libssh2_session_methods(LIBSSH2_SESSION *session, int method_type);
LIBSSH2_API int libssh2_session_last_error(LIBSSH2_SESSION *session, char **errmsg, int *errmsg_len, int want_buf);
LIBSSH2_API int libssh2_session_method_pref(LIBSSH2_SESSION *session,
int method_type,
const char *prefs);
LIBSSH2_API const char *libssh2_session_methods(LIBSSH2_SESSION *session,
int method_type);
LIBSSH2_API int libssh2_session_last_error(LIBSSH2_SESSION *session,
char **errmsg,
int *errmsg_len, int want_buf);
LIBSSH2_API int libssh2_session_last_errno(LIBSSH2_SESSION *session);
LIBSSH2_API int libssh2_session_block_directions(LIBSSH2_SESSION *session);
LIBSSH2_API int libssh2_session_flag(LIBSSH2_SESSION *session, int flag, int value);
LIBSSH2_API int libssh2_session_flag(LIBSSH2_SESSION *session, int flag,
int value);
/* Userauth API */
LIBSSH2_API char *libssh2_userauth_list(LIBSSH2_SESSION *session, const char *username, unsigned int username_len);
LIBSSH2_API char *libssh2_userauth_list(LIBSSH2_SESSION *session,
const char *username,
unsigned int username_len);
LIBSSH2_API int libssh2_userauth_authenticated(LIBSSH2_SESSION *session);
LIBSSH2_API int libssh2_userauth_password_ex(LIBSSH2_SESSION *session, const char *username, unsigned int username_len, const char *password, unsigned int password_len, LIBSSH2_PASSWD_CHANGEREQ_FUNC((*passwd_change_cb)));
#define libssh2_userauth_password(session, username, password) libssh2_userauth_password_ex((session), (username), strlen(username), (password), strlen(password), NULL)
LIBSSH2_API int libssh2_userauth_publickey_fromfile_ex(LIBSSH2_SESSION *session, const char *username, unsigned int username_len,
const char *publickey, const char *privatekey,
const char *passphrase);
#define libssh2_userauth_publickey_fromfile(session, username, publickey, privatekey, passphrase) \
libssh2_userauth_publickey_fromfile_ex((session), (username), strlen(username), (publickey), (privatekey), (passphrase))
LIBSSH2_API int libssh2_userauth_hostbased_fromfile_ex(LIBSSH2_SESSION *session, const char *username, unsigned int username_len,
const char *publickey, const char *privatekey,
const char *passphrase,
const char *hostname, unsigned int hostname_len,
const char *local_username, unsigned int local_username_len);
#define libssh2_userauth_hostbased_fromfile(session, username, publickey, privatekey, passphrase, hostname) \
libssh2_userauth_hostbased_fromfile_ex((session), (username), strlen(username), (publickey), (privatekey), (passphrase), (hostname), strlen(hostname), (username), strlen(username))
LIBSSH2_API int libssh2_userauth_password_ex(LIBSSH2_SESSION *session,
const char *username,
unsigned int username_len,
const char *password,
unsigned int password_len,
LIBSSH2_PASSWD_CHANGEREQ_FUNC((*passwd_change_cb)));
#define libssh2_userauth_password(session, username, password) \
libssh2_userauth_password_ex((session), (username), strlen(username), \
(password), strlen(password), NULL)
LIBSSH2_API int
libssh2_userauth_publickey_fromfile_ex(LIBSSH2_SESSION *session,
const char *username,
unsigned int username_len,
const char *publickey,
const char *privatekey,
const char *passphrase);
#define libssh2_userauth_publickey_fromfile(session, username, publickey, \
privatekey, passphrase) \
libssh2_userauth_publickey_fromfile_ex((session), (username), \
strlen(username), (publickey), \
(privatekey), (passphrase))
LIBSSH2_API int
libssh2_userauth_hostbased_fromfile_ex(LIBSSH2_SESSION *session,
const char *username,
unsigned int username_len,
const char *publickey,
const char *privatekey,
const char *passphrase,
const char *hostname,
unsigned int hostname_len,
const char *local_username,
unsigned int local_username_len);
#define libssh2_userauth_hostbased_fromfile(session, username, publickey, \
privatekey, passphrase, hostname) \
libssh2_userauth_hostbased_fromfile_ex((session), (username), \
strlen(username), (publickey), \
(privatekey), (passphrase), \
(hostname), strlen(hostname), \
(username), strlen(username))
/*
* response_callback is provided with filled by library prompts array,
@@ -358,16 +448,23 @@ LIBSSH2_API int libssh2_userauth_hostbased_fromfile_ex(LIBSSH2_SESSION *session,
* array is already allocated. Responses data will be freed by libssh2
* after callback return, but before subsequent callback invokation.
*/
LIBSSH2_API int libssh2_userauth_keyboard_interactive_ex(LIBSSH2_SESSION* session, const char *username, unsigned int username_len,
LIBSSH2_USERAUTH_KBDINT_RESPONSE_FUNC((*response_callback)));
#define libssh2_userauth_keyboard_interactive(session, username, response_callback) \
libssh2_userauth_keyboard_interactive_ex((session), (username), strlen(username), (response_callback))
LIBSSH2_API int
libssh2_userauth_keyboard_interactive_ex(LIBSSH2_SESSION* session,
const char *username,
unsigned int username_len,
LIBSSH2_USERAUTH_KBDINT_RESPONSE_FUNC((*response_callback)));
LIBSSH2_API int libssh2_poll(LIBSSH2_POLLFD *fds, unsigned int nfds, long timeout);
#define libssh2_userauth_keyboard_interactive(session, username, \
response_callback) \
libssh2_userauth_keyboard_interactive_ex((session), (username), \
strlen(username), (response_callback))
LIBSSH2_API int libssh2_poll(LIBSSH2_POLLFD *fds, unsigned int nfds,
long timeout);
/* Channel API */
#define LIBSSH2_CHANNEL_WINDOW_DEFAULT 65536
#define LIBSSH2_CHANNEL_PACKET_DEFAULT 16384
#define LIBSSH2_CHANNEL_PACKET_DEFAULT 32768
#define LIBSSH2_CHANNEL_MINADJUST 1024
/* Extended Data Handling */
@@ -380,81 +477,168 @@ LIBSSH2_API int libssh2_poll(LIBSSH2_POLLFD *fds, unsigned int nfds, long timeou
/* Returned by any function that would block during a read/write opperation */
#define LIBSSH2CHANNEL_EAGAIN LIBSSH2_ERROR_EAGAIN
LIBSSH2_API LIBSSH2_CHANNEL *libssh2_channel_open_ex(LIBSSH2_SESSION *session, const char *channel_type, unsigned int channel_type_len, unsigned int window_size, unsigned int packet_size, const char *message, unsigned int message_len);
#define libssh2_channel_open_session(session) libssh2_channel_open_ex((session), "session", sizeof("session") - 1, LIBSSH2_CHANNEL_WINDOW_DEFAULT, LIBSSH2_CHANNEL_PACKET_DEFAULT, NULL, 0)
LIBSSH2_API LIBSSH2_CHANNEL *
libssh2_channel_open_ex(LIBSSH2_SESSION *session, const char *channel_type,
unsigned int channel_type_len,
unsigned int window_size, unsigned int packet_size,
const char *message, unsigned int message_len);
LIBSSH2_API LIBSSH2_CHANNEL *libssh2_channel_direct_tcpip_ex(LIBSSH2_SESSION *session, const char *host, int port, const char *shost, int sport);
#define libssh2_channel_direct_tcpip(session, host, port) libssh2_channel_direct_tcpip_ex((session), (host), (port), "127.0.0.1", 22)
#define libssh2_channel_open_session(session) \
libssh2_channel_open_ex((session), "session", sizeof("session") - 1, \
LIBSSH2_CHANNEL_WINDOW_DEFAULT, \
LIBSSH2_CHANNEL_PACKET_DEFAULT, NULL, 0)
LIBSSH2_API LIBSSH2_LISTENER *libssh2_channel_forward_listen_ex(LIBSSH2_SESSION *session, const char *host, int port, int *bound_port, int queue_maxsize);
#define libssh2_channel_forward_listen(session, port) libssh2_channel_forward_listen_ex((session), NULL, (port), NULL, 16)
LIBSSH2_API LIBSSH2_CHANNEL *
libssh2_channel_direct_tcpip_ex(LIBSSH2_SESSION *session, const char *host,
int port, const char *shost, int sport);
#define libssh2_channel_direct_tcpip(session, host, port) \
libssh2_channel_direct_tcpip_ex((session), (host), (port), "127.0.0.1", 22)
LIBSSH2_API LIBSSH2_LISTENER *
libssh2_channel_forward_listen_ex(LIBSSH2_SESSION *session, const char *host,
int port, int *bound_port, int queue_maxsize);
#define libssh2_channel_forward_listen(session, port) \
libssh2_channel_forward_listen_ex((session), NULL, (port), NULL, 16)
LIBSSH2_API int libssh2_channel_forward_cancel(LIBSSH2_LISTENER *listener);
LIBSSH2_API LIBSSH2_CHANNEL *libssh2_channel_forward_accept(LIBSSH2_LISTENER *listener);
LIBSSH2_API LIBSSH2_CHANNEL *
libssh2_channel_forward_accept(LIBSSH2_LISTENER *listener);
LIBSSH2_API int libssh2_channel_setenv_ex(LIBSSH2_CHANNEL *channel, const char *varname, unsigned int varname_len, const char *value, unsigned int value_len);
#define libssh2_channel_setenv(channel, varname, value) libssh2_channel_setenv_ex((channel), (varname), strlen(varname), (value), strlen(value))
LIBSSH2_API int libssh2_channel_setenv_ex(LIBSSH2_CHANNEL *channel,
const char *varname,
unsigned int varname_len,
const char *value,
unsigned int value_len);
LIBSSH2_API int libssh2_channel_request_pty_ex(LIBSSH2_CHANNEL *channel, const char *term, unsigned int term_len, const char *modes, unsigned int modes_len, int width, int height, int width_px, int height_px);
#define libssh2_channel_request_pty(channel, term) libssh2_channel_request_pty_ex((channel), (term), strlen(term), NULL, 0, LIBSSH2_TERM_WIDTH, LIBSSH2_TERM_HEIGHT, LIBSSH2_TERM_WIDTH_PX, LIBSSH2_TERM_HEIGHT_PX)
#define libssh2_channel_setenv(channel, varname, value) \
libssh2_channel_setenv_ex((channel), (varname), strlen(varname), (value), \
strlen(value))
LIBSSH2_API int libssh2_channel_request_pty_size_ex(LIBSSH2_CHANNEL * channel, int width, int height, int width_px, int height_px);
#define libssh2_channel_request_pty_size(channel, width, height) libssh2_channel_request_pty_size_ex( (channel), (width), (height), 0, 0)
LIBSSH2_API int libssh2_channel_request_pty_ex(LIBSSH2_CHANNEL *channel,
const char *term,
unsigned int term_len,
const char *modes,
unsigned int modes_len,
int width, int height,
int width_px, int height_px);
#define libssh2_channel_request_pty(channel, term) \
libssh2_channel_request_pty_ex((channel), (term), strlen(term), NULL, 0, \
LIBSSH2_TERM_WIDTH, LIBSSH2_TERM_HEIGHT, \
LIBSSH2_TERM_WIDTH_PX, LIBSSH2_TERM_HEIGHT_PX)
LIBSSH2_API int libssh2_channel_x11_req_ex(LIBSSH2_CHANNEL *channel, int single_connection, const char *auth_proto, const char *auth_cookie, int screen_number);
#define libssh2_channel_x11_req(channel, screen_number) libssh2_channel_x11_req_ex((channel), 0, NULL, NULL, (screen_number))
LIBSSH2_API int libssh2_channel_request_pty_size_ex(LIBSSH2_CHANNEL *channel,
int width, int height,
int width_px,
int height_px);
#define libssh2_channel_request_pty_size(channel, width, height) \
libssh2_channel_request_pty_size_ex( (channel), (width), (height), 0, 0)
LIBSSH2_API int libssh2_channel_process_startup(LIBSSH2_CHANNEL *channel, const char *request, unsigned int request_len, const char *message, unsigned int message_len);
#define libssh2_channel_shell(channel) libssh2_channel_process_startup((channel), "shell", sizeof("shell") - 1, NULL, 0)
#define libssh2_channel_exec(channel, command) libssh2_channel_process_startup((channel), "exec", sizeof("exec") - 1, (command), strlen(command))
#define libssh2_channel_subsystem(channel, subsystem) libssh2_channel_process_startup((channel), "subsystem", sizeof("subsystem") - 1, (subsystem), strlen(subsystem))
LIBSSH2_API int libssh2_channel_x11_req_ex(LIBSSH2_CHANNEL *channel,
int single_connection,
const char *auth_proto,
const char *auth_cookie,
int screen_number);
#define libssh2_channel_x11_req(channel, screen_number) \
libssh2_channel_x11_req_ex((channel), 0, NULL, NULL, (screen_number))
LIBSSH2_API ssize_t libssh2_channel_read_ex(LIBSSH2_CHANNEL *channel, int stream_id, char *buf, size_t buflen);
LIBSSH2_API int libssh2_channel_process_startup(LIBSSH2_CHANNEL *channel,
const char *request,
unsigned int request_len,
const char *message,
unsigned int message_len);
#define libssh2_channel_shell(channel) \
libssh2_channel_process_startup((channel), "shell", sizeof("shell") - 1, \
NULL, 0)
#define libssh2_channel_exec(channel, command) \
libssh2_channel_process_startup((channel), "exec", sizeof("exec") - 1, \
(command), strlen(command))
#define libssh2_channel_subsystem(channel, subsystem) \
libssh2_channel_process_startup((channel), "subsystem", \
sizeof("subsystem") - 1, (subsystem), \
strlen(subsystem))
LIBSSH2_API ssize_t libssh2_channel_read_ex(LIBSSH2_CHANNEL *channel,
int stream_id, char *buf,
size_t buflen);
#define libssh2_channel_read(channel, buf, buflen) \
libssh2_channel_read_ex((channel), 0, (buf), (buflen))
libssh2_channel_read_ex((channel), 0, (buf), (buflen))
#define libssh2_channel_read_stderr(channel, buf, buflen) \
libssh2_channel_read_ex((channel), SSH_EXTENDED_DATA_STDERR, (buf), (buflen))
libssh2_channel_read_ex((channel), SSH_EXTENDED_DATA_STDERR, (buf), (buflen))
LIBSSH2_API int libssh2_poll_channel_read(LIBSSH2_CHANNEL *channel, int extended);
LIBSSH2_API int libssh2_poll_channel_read(LIBSSH2_CHANNEL *channel,
int extended);
LIBSSH2_API unsigned long libssh2_channel_window_read_ex(LIBSSH2_CHANNEL *channel, unsigned long *read_avail, unsigned long *window_size_initial);
LIBSSH2_API unsigned long
libssh2_channel_window_read_ex(LIBSSH2_CHANNEL *channel,
unsigned long *read_avail,
unsigned long *window_size_initial);
#define libssh2_channel_window_read(channel) \
libssh2_channel_window_read_ex((channel), NULL, NULL)
libssh2_channel_window_read_ex((channel), NULL, NULL)
LIBSSH2_API unsigned long libssh2_channel_receive_window_adjust(LIBSSH2_CHANNEL *channel, unsigned long adjustment, unsigned char force);
/* libssh2_channel_receive_window_adjust is DEPRECATED, do not use! */
LIBSSH2_API unsigned long
libssh2_channel_receive_window_adjust(LIBSSH2_CHANNEL *channel,
unsigned long adjustment,
unsigned char force);
LIBSSH2_API ssize_t libssh2_channel_write_ex(LIBSSH2_CHANNEL *channel, int stream_id, const char *buf, size_t buflen);
LIBSSH2_API int
libssh2_channel_receive_window_adjust2(LIBSSH2_CHANNEL *channel,
unsigned long adjustment,
unsigned char force,
unsigned int *storewindow);
LIBSSH2_API ssize_t libssh2_channel_write_ex(LIBSSH2_CHANNEL *channel,
int stream_id, const char *buf,
size_t buflen);
#define libssh2_channel_write(channel, buf, buflen) \
libssh2_channel_write_ex((channel), 0, (buf), (buflen))
libssh2_channel_write_ex((channel), 0, (buf), (buflen))
#define libssh2_channel_write_stderr(channel, buf, buflen) \
libssh2_channel_write_ex((channel), SSH_EXTENDED_DATA_STDERR, (buf), (buflen))
libssh2_channel_write_ex((channel), SSH_EXTENDED_DATA_STDERR, (buf), (buflen))
LIBSSH2_API unsigned long libssh2_channel_window_write_ex(LIBSSH2_CHANNEL *channel, unsigned long *window_size_initial);
#define libssh2_channel_window_write(channel) libssh2_channel_window_write_ex((channel), NULL)
LIBSSH2_API unsigned long
libssh2_channel_window_write_ex(LIBSSH2_CHANNEL *channel,
unsigned long *window_size_initial);
#define libssh2_channel_window_write(channel) \
libssh2_channel_window_write_ex((channel), NULL)
LIBSSH2_API void libssh2_session_set_blocking(LIBSSH2_SESSION* session, int blocking);
LIBSSH2_API void libssh2_session_set_blocking(LIBSSH2_SESSION* session,
int blocking);
LIBSSH2_API int libssh2_session_get_blocking(LIBSSH2_SESSION* session);
LIBSSH2_API void libssh2_channel_set_blocking(LIBSSH2_CHANNEL *channel, int blocking);
LIBSSH2_API void libssh2_channel_set_blocking(LIBSSH2_CHANNEL *channel,
int blocking);
LIBSSH2_API void libssh2_channel_handle_extended_data(LIBSSH2_CHANNEL *channel, int ignore_mode);
LIBSSH2_API int libssh2_channel_handle_extended_data2(LIBSSH2_CHANNEL *channel, int ignore_mode);
/* libssh2_channel_ignore_extended_data() is defined below for BC with version 0.1
* Future uses should use libssh2_channel_handle_extended_data() directly
* if LIBSSH2_CHANNEL_EXTENDED_DATA_MERGE is passed, extended data will be read (FIFO) from the standard data channel
/* libssh2_channel_handle_extended_data is DEPRECATED, do not use! */
LIBSSH2_API void libssh2_channel_handle_extended_data(LIBSSH2_CHANNEL *channel,
int ignore_mode);
LIBSSH2_API int libssh2_channel_handle_extended_data2(LIBSSH2_CHANNEL *channel,
int ignore_mode);
/* libssh2_channel_ignore_extended_data() is defined below for BC with version
* 0.1
*
* Future uses should use libssh2_channel_handle_extended_data() directly if
* LIBSSH2_CHANNEL_EXTENDED_DATA_MERGE is passed, extended data will be read
* (FIFO) from the standard data channel
*/
/* DEPRECATED */
#define libssh2_channel_ignore_extended_data(channel, ignore) libssh2_channel_handle_extended_data((channel), (ignore) ? LIBSSH2_CHANNEL_EXTENDED_DATA_IGNORE : LIBSSH2_CHANNEL_EXTENDED_DATA_NORMAL )
#define libssh2_channel_ignore_extended_data(channel, ignore) \
libssh2_channel_handle_extended_data((channel), \
(ignore) ? \
LIBSSH2_CHANNEL_EXTENDED_DATA_IGNORE : \
LIBSSH2_CHANNEL_EXTENDED_DATA_NORMAL )
#define LIBSSH2_CHANNEL_FLUSH_EXTENDED_DATA -1
#define LIBSSH2_CHANNEL_FLUSH_ALL -2
LIBSSH2_API int libssh2_channel_flush_ex(LIBSSH2_CHANNEL *channel, int streamid);
#define libssh2_channel_flush(channel) libssh2_channel_flush_ex((channel), 0)
#define libssh2_channel_flush_stderr(channel) libssh2_channel_flush_ex((channel), SSH_EXTENDED_DATA_STDERR)
LIBSSH2_API int libssh2_channel_get_exit_status(LIBSSH2_CHANNEL* channel);
LIBSSH2_API int libssh2_channel_flush_ex(LIBSSH2_CHANNEL *channel,
int streamid);
#define libssh2_channel_flush(channel) libssh2_channel_flush_ex((channel), 0)
#define libssh2_channel_flush_stderr(channel) \
libssh2_channel_flush_ex((channel), SSH_EXTENDED_DATA_STDERR)
LIBSSH2_API int libssh2_channel_get_exit_status(LIBSSH2_CHANNEL* channel);
LIBSSH2_API int libssh2_channel_send_eof(LIBSSH2_CHANNEL *channel);
LIBSSH2_API int libssh2_channel_eof(LIBSSH2_CHANNEL *channel);
LIBSSH2_API int libssh2_channel_wait_eof(LIBSSH2_CHANNEL *channel);
@@ -462,11 +646,23 @@ LIBSSH2_API int libssh2_channel_close(LIBSSH2_CHANNEL *channel);
LIBSSH2_API int libssh2_channel_wait_closed(LIBSSH2_CHANNEL *channel);
LIBSSH2_API int libssh2_channel_free(LIBSSH2_CHANNEL *channel);
LIBSSH2_API LIBSSH2_CHANNEL *libssh2_scp_recv(LIBSSH2_SESSION *session, const char *path, struct stat *sb);
LIBSSH2_API LIBSSH2_CHANNEL *libssh2_scp_send_ex(LIBSSH2_SESSION *session, const char *path, int mode, size_t size, long mtime, long atime);
#define libssh2_scp_send(session, path, mode, size) libssh2_scp_send_ex((session), (path), (mode), (size), 0, 0)
LIBSSH2_API LIBSSH2_CHANNEL *libssh2_scp_recv(LIBSSH2_SESSION *session,
const char *path,
struct stat *sb);
LIBSSH2_API LIBSSH2_CHANNEL *libssh2_scp_send_ex(LIBSSH2_SESSION *session,
const char *path, int mode,
size_t size, long mtime,
long atime);
#define libssh2_scp_send(session, path, mode, size) \
libssh2_scp_send_ex((session), (path), (mode), (size), 0, 0)
LIBSSH2_API int libssh2_base64_decode(LIBSSH2_SESSION *session, char **dest,
unsigned int *dest_len,
const char *src, unsigned int src_len);
LIBSSH2_API
const char *libssh2_version(int req_version_num);
LIBSSH2_API int libssh2_base64_decode(LIBSSH2_SESSION *session, char **dest, unsigned int *dest_len, const char *src, unsigned int src_len);
/* NOTE NOTE NOTE
libssh2_trace() has no function in builds that aren't built with debug

View File

@@ -68,8 +68,10 @@ typedef struct _libssh2_publickey_list {
} libssh2_publickey_list;
/* Generally use the first macro here, but if both name and value are string literals, you can use _fast() to take advantage of preprocessing */
#define libssh2_publickey_attribute(name, value, mandatory) { (name), strlen(name), (value), strlen(value), (mandatory) },
#define libssh2_publickey_attribute_fast(name, value, mandatory) { (name), sizeof(name) - 1, (value), sizeof(value) - 1, (mandatory) },
#define libssh2_publickey_attribute(name, value, mandatory) \
{ (name), strlen(name), (value), strlen(value), (mandatory) },
#define libssh2_publickey_attribute_fast(name, value, mandatory) \
{ (name), sizeof(name) - 1, (value), sizeof(value) - 1, (mandatory) },
#ifdef __cplusplus
extern "C" {
@@ -78,19 +80,32 @@ extern "C" {
/* Publickey Subsystem */
LIBSSH2_API LIBSSH2_PUBLICKEY *libssh2_publickey_init(LIBSSH2_SESSION *session);
LIBSSH2_API int libssh2_publickey_add_ex(LIBSSH2_PUBLICKEY *pkey, const unsigned char *name, unsigned long name_len,
const unsigned char *blob, unsigned long blob_len, char overwrite,
unsigned long num_attrs, const libssh2_publickey_attribute attrs[]);
#define libssh2_publickey_add(pkey, name, blob, blob_len, overwrite, num_attrs, attrs) \
libssh2_publickey_add_ex((pkey), (name), strlen(name), (blob), (blob_len), (overwrite), (num_attrs), (attrs))
LIBSSH2_API int libssh2_publickey_add_ex(LIBSSH2_PUBLICKEY *pkey,
const unsigned char *name,
unsigned long name_len,
const unsigned char *blob,
unsigned long blob_len, char overwrite,
unsigned long num_attrs,
const libssh2_publickey_attribute attrs[]);
#define libssh2_publickey_add(pkey, name, blob, blob_len, overwrite, \
num_attrs, attrs) \
libssh2_publickey_add_ex((pkey), (name), strlen(name), (blob), (blob_len), \
(overwrite), (num_attrs), (attrs))
LIBSSH2_API int libssh2_publickey_remove_ex(LIBSSH2_PUBLICKEY *pkey, const unsigned char *name, unsigned long name_len,
const unsigned char *blob, unsigned long blob_len);
LIBSSH2_API int libssh2_publickey_remove_ex(LIBSSH2_PUBLICKEY *pkey,
const unsigned char *name,
unsigned long name_len,
const unsigned char *blob,
unsigned long blob_len);
#define libssh2_publickey_remove(pkey, name, blob, blob_len) \
libssh2_publickey_remove_ex((pkey), (name), strlen(name), (blob), (blob_len))
libssh2_publickey_remove_ex((pkey), (name), strlen(name), (blob), (blob_len))
LIBSSH2_API int libssh2_publickey_list_fetch(LIBSSH2_PUBLICKEY *pkey, unsigned long *num_keys, libssh2_publickey_list **pkey_list);
LIBSSH2_API void libssh2_publickey_list_free(LIBSSH2_PUBLICKEY *pkey, libssh2_publickey_list *pkey_list);
LIBSSH2_API int
libssh2_publickey_list_fetch(LIBSSH2_PUBLICKEY *pkey,
unsigned long *num_keys,
libssh2_publickey_list **pkey_list);
LIBSSH2_API void libssh2_publickey_list_free(LIBSSH2_PUBLICKEY *pkey,
libssh2_publickey_list *pkey_list);
LIBSSH2_API int libssh2_publickey_shutdown(LIBSSH2_PUBLICKEY *pkey);
@@ -98,4 +113,4 @@ LIBSSH2_API int libssh2_publickey_shutdown(LIBSSH2_PUBLICKEY *pkey);
} /* extern "C" */
#endif
#endif /* ndef: LIBSSH2_PUBLICKEY_H */
#endif /* ifndef: LIBSSH2_PUBLICKEY_H */

View File

@@ -85,8 +85,8 @@ typedef struct _LIBSSH2_SFTP_ATTRIBUTES LIBSSH2_SFTP_ATTRIBUTES;
#define LIBSSH2_SFTP_ATTR_EXTENDED 0x80000000
struct _LIBSSH2_SFTP_ATTRIBUTES {
/* If flags & ATTR_* bit is set, then the value in this struct will be meaningful
* Otherwise it should be ignored
/* If flags & ATTR_* bit is set, then the value in this struct will be
* meaningful Otherwise it should be ignored
*/
unsigned long flags;
@@ -108,8 +108,8 @@ struct _LIBSSH2_SFTP_ATTRIBUTES {
#define LIBSSH2_SFTP_TYPE_FIFO 9
/*
* Reproduce the POSIX file modes here for systems that are not
* POSIX compliant.
* Reproduce the POSIX file modes here for systems that are not POSIX
* compliant.
*
* These is used in "permissions" of "struct _LIBSSH2_SFTP_ATTRIBUTES"
*/
@@ -184,65 +184,114 @@ LIBSSH2_API int libssh2_sftp_shutdown(LIBSSH2_SFTP *sftp);
LIBSSH2_API unsigned long libssh2_sftp_last_error(LIBSSH2_SFTP *sftp);
/* File / Directory Ops */
LIBSSH2_API LIBSSH2_SFTP_HANDLE *libssh2_sftp_open_ex(LIBSSH2_SFTP *sftp, const char *filename, unsigned int filename_len,
unsigned long flags, long mode, int open_type);
LIBSSH2_API LIBSSH2_SFTP_HANDLE *libssh2_sftp_open_ex(LIBSSH2_SFTP *sftp,
const char *filename,
unsigned int filename_len,
unsigned long flags,
long mode, int open_type);
#define libssh2_sftp_open(sftp, filename, flags, mode) \
libssh2_sftp_open_ex((sftp), (filename), strlen(filename), (flags), (mode), LIBSSH2_SFTP_OPENFILE)
libssh2_sftp_open_ex((sftp), (filename), strlen(filename), (flags), \
(mode), LIBSSH2_SFTP_OPENFILE)
#define libssh2_sftp_opendir(sftp, path) \
libssh2_sftp_open_ex((sftp), (path), strlen(path), 0, 0, LIBSSH2_SFTP_OPENDIR)
libssh2_sftp_open_ex((sftp), (path), strlen(path), 0, 0, \
LIBSSH2_SFTP_OPENDIR)
LIBSSH2_API ssize_t libssh2_sftp_read(LIBSSH2_SFTP_HANDLE *handle, char *buffer, size_t buffer_maxlen);
LIBSSH2_API ssize_t libssh2_sftp_read(LIBSSH2_SFTP_HANDLE *handle,
char *buffer, size_t buffer_maxlen);
LIBSSH2_API int libssh2_sftp_readdir_ex(LIBSSH2_SFTP_HANDLE *handle, char *buffer, size_t buffer_maxlen,
char *longentry, size_t longentry_maxlen,
LIBSSH2_API int libssh2_sftp_readdir_ex(LIBSSH2_SFTP_HANDLE *handle, \
char *buffer, size_t buffer_maxlen,
char *longentry,
size_t longentry_maxlen,
LIBSSH2_SFTP_ATTRIBUTES *attrs);
#define libssh2_sftp_readdir(handle, buffer, buffer_maxlen, attrs) \
libssh2_sftp_readdir_ex((handle), (buffer), (buffer_maxlen), NULL, 0, (attrs))
#define libssh2_sftp_readdir(handle, buffer, buffer_maxlen, attrs) \
libssh2_sftp_readdir_ex((handle), (buffer), (buffer_maxlen), NULL, 0, \
(attrs))
LIBSSH2_API ssize_t libssh2_sftp_write(LIBSSH2_SFTP_HANDLE *handle, const char *buffer, size_t count);
LIBSSH2_API ssize_t libssh2_sftp_write(LIBSSH2_SFTP_HANDLE *handle,
const char *buffer, size_t count);
LIBSSH2_API int libssh2_sftp_close_handle(LIBSSH2_SFTP_HANDLE *handle);
#define libssh2_sftp_close(handle) libssh2_sftp_close_handle(handle)
#define libssh2_sftp_closedir(handle) libssh2_sftp_close_handle(handle)
#define libssh2_sftp_close(handle) libssh2_sftp_close_handle(handle)
#define libssh2_sftp_closedir(handle) libssh2_sftp_close_handle(handle)
LIBSSH2_API void libssh2_sftp_seek(LIBSSH2_SFTP_HANDLE *handle, size_t offset);
LIBSSH2_API void libssh2_sftp_seek64(LIBSSH2_SFTP_HANDLE *handle, libssh2_uint64_t offset);
#define libssh2_sftp_rewind(handle) libssh2_sftp_seek64((handle), 0)
LIBSSH2_API void libssh2_sftp_seek64(LIBSSH2_SFTP_HANDLE *handle,
libssh2_uint64_t offset);
#define libssh2_sftp_rewind(handle) libssh2_sftp_seek64((handle), 0)
LIBSSH2_API size_t libssh2_sftp_tell(LIBSSH2_SFTP_HANDLE *handle);
LIBSSH2_API libssh2_uint64_t libssh2_sftp_tell64(LIBSSH2_SFTP_HANDLE *handle);
LIBSSH2_API int libssh2_sftp_fstat_ex(LIBSSH2_SFTP_HANDLE *handle, LIBSSH2_SFTP_ATTRIBUTES *attrs, int setstat);
#define libssh2_sftp_fstat(handle, attrs) libssh2_sftp_fstat_ex((handle), (attrs), 0)
#define libssh2_sftp_fsetstat(handle, attrs) libssh2_sftp_fstat_ex((handle), (attrs), 1)
LIBSSH2_API int libssh2_sftp_fstat_ex(LIBSSH2_SFTP_HANDLE *handle,
LIBSSH2_SFTP_ATTRIBUTES *attrs,
int setstat);
#define libssh2_sftp_fstat(handle, attrs) \
libssh2_sftp_fstat_ex((handle), (attrs), 0)
#define libssh2_sftp_fsetstat(handle, attrs) \
libssh2_sftp_fstat_ex((handle), (attrs), 1)
/* Miscellaneous Ops */
LIBSSH2_API int libssh2_sftp_rename_ex(LIBSSH2_SFTP *sftp, const char *source_filename, unsigned int srouce_filename_len,
const char *dest_filename, unsigned int dest_filename_len,
long flags);
#define libssh2_sftp_rename(sftp, sourcefile, destfile) libssh2_sftp_rename_ex((sftp), (sourcefile), strlen(sourcefile), (destfile), strlen(destfile), \
LIBSSH2_SFTP_RENAME_OVERWRITE | LIBSSH2_SFTP_RENAME_ATOMIC | LIBSSH2_SFTP_RENAME_NATIVE)
LIBSSH2_API int libssh2_sftp_rename_ex(LIBSSH2_SFTP *sftp,
const char *source_filename,
unsigned int srouce_filename_len,
const char *dest_filename,
unsigned int dest_filename_len,
long flags);
#define libssh2_sftp_rename(sftp, sourcefile, destfile) \
libssh2_sftp_rename_ex((sftp), (sourcefile), strlen(sourcefile), \
(destfile), strlen(destfile), \
LIBSSH2_SFTP_RENAME_OVERWRITE | \
LIBSSH2_SFTP_RENAME_ATOMIC | \
LIBSSH2_SFTP_RENAME_NATIVE)
LIBSSH2_API int libssh2_sftp_unlink_ex(LIBSSH2_SFTP *sftp, const char *filename, unsigned int filename_len);
#define libssh2_sftp_unlink(sftp, filename) libssh2_sftp_unlink_ex((sftp), (filename), strlen(filename))
LIBSSH2_API int libssh2_sftp_unlink_ex(LIBSSH2_SFTP *sftp,
const char *filename,
unsigned int filename_len);
#define libssh2_sftp_unlink(sftp, filename) \
libssh2_sftp_unlink_ex((sftp), (filename), strlen(filename))
LIBSSH2_API int libssh2_sftp_mkdir_ex(LIBSSH2_SFTP *sftp, const char *path, unsigned int path_len, long mode);
#define libssh2_sftp_mkdir(sftp, path, mode) libssh2_sftp_mkdir_ex((sftp), (path), strlen(path), (mode))
LIBSSH2_API int libssh2_sftp_mkdir_ex(LIBSSH2_SFTP *sftp,
const char *path,
unsigned int path_len, long mode);
#define libssh2_sftp_mkdir(sftp, path, mode) \
libssh2_sftp_mkdir_ex((sftp), (path), strlen(path), (mode))
LIBSSH2_API int libssh2_sftp_rmdir_ex(LIBSSH2_SFTP *sftp, const char *path, unsigned int path_len);
#define libssh2_sftp_rmdir(sftp, path) libssh2_sftp_rmdir_ex((sftp), (path), strlen(path))
LIBSSH2_API int libssh2_sftp_rmdir_ex(LIBSSH2_SFTP *sftp,
const char *path,
unsigned int path_len);
#define libssh2_sftp_rmdir(sftp, path) \
libssh2_sftp_rmdir_ex((sftp), (path), strlen(path))
LIBSSH2_API int libssh2_sftp_stat_ex(LIBSSH2_SFTP *sftp, const char *path, unsigned int path_len, int stat_type, LIBSSH2_SFTP_ATTRIBUTES *attrs);
#define libssh2_sftp_stat(sftp, path, attrs) libssh2_sftp_stat_ex((sftp), (path), strlen(path), LIBSSH2_SFTP_STAT, (attrs))
#define libssh2_sftp_lstat(sftp, path, attrs) libssh2_sftp_stat_ex((sftp), (path), strlen(path), LIBSSH2_SFTP_LSTAT, (attrs))
#define libssh2_sftp_setstat(sftp, path, attrs) libssh2_sftp_stat_ex((sftp), (path), strlen(path), LIBSSH2_SFTP_SETSTAT, (attrs))
LIBSSH2_API int libssh2_sftp_stat_ex(LIBSSH2_SFTP *sftp,
const char *path,
unsigned int path_len,
int stat_type,
LIBSSH2_SFTP_ATTRIBUTES *attrs);
#define libssh2_sftp_stat(sftp, path, attrs) \
libssh2_sftp_stat_ex((sftp), (path), strlen(path), LIBSSH2_SFTP_STAT, \
(attrs))
#define libssh2_sftp_lstat(sftp, path, attrs) \
libssh2_sftp_stat_ex((sftp), (path), strlen(path), LIBSSH2_SFTP_LSTAT, \
(attrs))
#define libssh2_sftp_setstat(sftp, path, attrs) \
libssh2_sftp_stat_ex((sftp), (path), strlen(path), LIBSSH2_SFTP_SETSTAT, \
(attrs))
LIBSSH2_API int libssh2_sftp_symlink_ex(LIBSSH2_SFTP *sftp, const char *path, unsigned int path_len, char *target, unsigned int target_len, int link_type);
#define libssh2_sftp_symlink(sftp, orig, linkpath) libssh2_sftp_symlink_ex((sftp), (orig), strlen(orig), (linkpath), strlen(linkpath), LIBSSH2_SFTP_SYMLINK)
#define libssh2_sftp_readlink(sftp, path, target, maxlen) libssh2_sftp_symlink_ex((sftp), (path), strlen(path), (target), (maxlen), LIBSSH2_SFTP_READLINK)
#define libssh2_sftp_realpath(sftp, path, target, maxlen) libssh2_sftp_symlink_ex((sftp), (path), strlen(path), (target), (maxlen), LIBSSH2_SFTP_REALPATH)
LIBSSH2_API int libssh2_sftp_symlink_ex(LIBSSH2_SFTP *sftp,
const char *path,
unsigned int path_len,
char *target,
unsigned int target_len, int link_type);
#define libssh2_sftp_symlink(sftp, orig, linkpath) \
libssh2_sftp_symlink_ex((sftp), (orig), strlen(orig), (linkpath), \
strlen(linkpath), LIBSSH2_SFTP_SYMLINK)
#define libssh2_sftp_readlink(sftp, path, target, maxlen) \
libssh2_sftp_symlink_ex((sftp), (path), strlen(path), (target), (maxlen), \
LIBSSH2_SFTP_READLINK)
#define libssh2_sftp_realpath(sftp, path, target, maxlen) \
libssh2_sftp_symlink_ex((sftp), (path), strlen(path), (target), (maxlen), \
LIBSSH2_SFTP_REALPATH)
#ifdef __cplusplus
} /* extern "C" */

View File

@@ -5,7 +5,7 @@
##
## Comments to: Guenter Knauf <eflash@gmx.net>
##
## $Id: Makefile.netware,v 1.12 2007/07/22 00:47:21 gknauf Exp $
## $Id: Makefile.netware,v 1.13 2009/03/06 07:25:37 gknauf Exp $
#
#########################################################################
@@ -21,7 +21,7 @@ endif
# Edit the path below to point to the base of your OpenSSL package.
ifndef OPENSSL_PATH
OPENSSL_PATH = ../../openssl-0.9.8e
OPENSSL_PATH = ../../openssl-0.9.8j
endif
# Edit the path below to point to your Distribution folder.
@@ -39,7 +39,7 @@ DEVLARC = $(DEVLDIR).zip
# Edit the vars below to change NLM target settings.
TARGET = libssh2
VERSION = $(LIBSSH2_VERSION)
COPYR = Copyright (c) 2004-2007 Sara Golemon <sarag@libssh2.org>
COPYR = Copyright (c) 2004-2009 Sara Golemon <sarag@libssh2.org>
WWWURL = http://www.libssh2.org/
DESCR = libssh2 $(LIBSSH2_VERSION_STR) ($(LIBARCH)) - $(WWWURL)
MTSAFE = YES
@@ -522,6 +522,7 @@ endif
@echo $(DL) libssh2_scp_recv,$(DL) >> $@
@echo $(DL) libssh2_scp_send_ex,$(DL) >> $@
@echo $(DL) libssh2_session_abstract,$(DL) >> $@
@echo $(DL) libssh2_session_block_directions,$(DL) >> $@
@echo $(DL) libssh2_session_callback_set,$(DL) >> $@
@echo $(DL) libssh2_session_disconnect_ex,$(DL) >> $@
@echo $(DL) libssh2_session_free,$(DL) >> $@
@@ -543,6 +544,7 @@ endif
@echo $(DL) libssh2_sftp_rename_ex,$(DL) >> $@
@echo $(DL) libssh2_sftp_rmdir_ex,$(DL) >> $@
@echo $(DL) libssh2_sftp_seek,$(DL) >> $@
@echo $(DL) libssh2_sftp_seek64,$(DL) >> $@
@echo $(DL) libssh2_sftp_shutdown,$(DL) >> $@
@echo $(DL) libssh2_sftp_stat_ex,$(DL) >> $@
@echo $(DL) libssh2_sftp_symlink_ex,$(DL) >> $@

View File

@@ -5,7 +5,7 @@
##
## Comments to: Guenter Knauf <eflash@gmx.net>
##
## $Id: Makefile.netware,v 1.8 2007/08/08 16:32:42 gknauf Exp $
## $Id: Makefile.netware,v 1.9 2009/03/06 07:25:37 gknauf Exp $
#
#########################################################################
@@ -21,7 +21,7 @@ endif
# Edit the path below to point to the base of your OpenSSL package.
ifndef OPENSSL_PATH
OPENSSL_PATH = ../../../openssl-0.9.8e
OPENSSL_PATH = ../../../openssl-0.9.8j
endif
# Edit the var below to enable static linking of libssh2 and libz
@@ -31,7 +31,7 @@ LINK_STATIC = 1
SAMPLES = ../../example/simple
TARGETS := $(patsubst $(SAMPLES)/%.c,%.nlm,$(strip $(wildcard $(SAMPLES)/*.c)))
VERSION = $(LIBSSH2_VERSION)
COPYR = Copyright (c) 2004-2007, Sara Golemon <sarag@libssh2.org>
COPYR = Copyright (c) 2004-2009, Sara Golemon <sarag@libssh2.org>
WWWURL = http://www.libssh2.org/
DESCR = libssh2 $(notdir $(@:.def=)) $(LIBSSH2_VERSION_STR) ($(LIBARCH)) - $(WWWURL)
MTSAFE = YES

View File

@@ -1,9 +1,9 @@
# $Id: Makefile.am,v 1.13 2008/11/21 14:34:03 jas4711 Exp $
# $Id: Makefile.am,v 1.19 2009/03/26 22:25:23 bagder Exp $
AUTOMAKE_OPTIONS = foreign nostdinc
libssh2_la_SOURCES = channel.c comp.c crypt.c hostkey.c kex.c mac.c \
misc.c packet.c publickey.c scp.c session.c sftp.c userauth.c \
libssh2_priv.h openssl.h libgcrypt.h transport.c
libssh2_la_SOURCES = channel.c comp.c crypt.c hostkey.c kex.c mac.c misc.c \
packet.c publickey.c scp.c session.c sftp.c userauth.c libssh2_priv.h \
openssl.h libgcrypt.h transport.c version.c transport.h channel.h comp.h mac.h
if LIBGCRYPT
libssh2_la_SOURCES += libgcrypt.c pem.c
@@ -20,7 +20,7 @@ lib_LTLIBRARIES = libssh2.la
# tree
AM_CPPFLAGS = -I$(top_srcdir)/include -I$(top_builddir)/src
VERSION=-version-info 1:0:0
VERSION=-version-info 1:1:0
# This flag accepts an argument of the form current[:revision[:age]]. So,
# passing -version-info 3:12:1 sets current to 3, revision to 12, and age to
@@ -51,4 +51,5 @@ VERSION=-version-info 1:0:0
#
libssh2_la_LDFLAGS = $(VERSION) -no-undefined \
-export-symbols-regex '^libssh2_.*' \
$(LTLIBGCRYPT) $(LTLIBSSL) $(LTLIBZ)

File diff suppressed because it is too large Load Diff

108
src/channel.h Normal file
View File

@@ -0,0 +1,108 @@
#ifndef __LIBSSH2_CHANNEL_H
#define __LIBSSH2_CHANNEL_H
/* Copyright (c) 2008-2009 by Daniel Stenberg
*
* All rights reserved.
*
* Redistribution and use in source and binary forms,
* with or without modification, are permitted provided
* that the following conditions are met:
*
* Redistributions of source code must retain the above
* copyright notice, this list of conditions and the
* following disclaimer.
*
* Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following
* disclaimer in the documentation and/or other materials
* provided with the distribution.
*
* Neither the name of the copyright holder nor the names
* of any other contributors may be used to endorse or
* promote products derived from this software without
* specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
* CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
* USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
* OF SUCH DAMAGE.
*/
/*
* _libssh2_channel_receive_window_adjust
*
* Adjust the receive window for a channel by adjustment bytes. If the amount
* to be adjusted is less than LIBSSH2_CHANNEL_MINADJUST and force is 0 the
* adjustment amount will be queued for a later packet.
*
* Always non-blocking.
*/
int _libssh2_channel_receive_window_adjust(LIBSSH2_CHANNEL * channel,
unsigned long adjustment,
unsigned char force,
unsigned int *store);
/*
* _libssh2_channel_flush
*
* Flush data from one (or all) stream
* Returns number of bytes flushed, or negative on failure
*/
int _libssh2_channel_flush(LIBSSH2_CHANNEL *channel, int streamid);
/*
* _libssh2_channel_free
*
* Make sure a channel is closed, then remove the channel from the session
* and free its resource(s)
*
* Returns 0 on success, negative on failure
*/
int _libssh2_channel_free(LIBSSH2_CHANNEL *channel);
int
_libssh2_channel_extended_data(LIBSSH2_CHANNEL *channel, int ignore_mode);
/*
* _libssh2_channel_write
*
* Send data to a channel
*/
ssize_t
_libssh2_channel_write(LIBSSH2_CHANNEL *channel, int stream_id,
const char *buf, size_t buflen);
/*
* _libssh2_channel_open
*
* Establish a generic session channel
*/
LIBSSH2_CHANNEL *
_libssh2_channel_open(LIBSSH2_SESSION * session, const char *channel_type,
unsigned int channel_type_len,
unsigned int window_size, unsigned int packet_size,
const char *message, unsigned int message_len);
/*
* _libssh2_channel_process_startup
*
* Primitive for libssh2_channel_(shell|exec|subsystem)
*/
int
_libssh2_channel_process_startup(LIBSSH2_CHANNEL *channel,
const char *request, unsigned int request_len,
const char *message, unsigned int message_len);
#endif /* __LIBSSH2_CHANNEL_H */

View File

@@ -40,22 +40,26 @@
# include <zlib.h>
#endif
#include "comp.h"
/* ********
* none *
******** */
/* {{{ libssh2_comp_method_none_comp
/*
* comp_method_none_comp
*
* Minimalist compression: Absolutely none
*/
static int
libssh2_comp_method_none_comp(LIBSSH2_SESSION * session,
int compress,
unsigned char **dest,
unsigned long *dest_len,
unsigned long payload_limit,
int *free_dest,
const unsigned char *src,
unsigned long src_len, void **abstract)
comp_method_none_comp(LIBSSH2_SESSION * session,
int compress,
unsigned char **dest,
unsigned long *dest_len,
unsigned long payload_limit,
int *free_dest,
const unsigned char *src,
unsigned long src_len, void **abstract)
{
(void) session;
(void) compress;
@@ -69,12 +73,12 @@ libssh2_comp_method_none_comp(LIBSSH2_SESSION * session,
return 0;
}
/* }}} */
static const LIBSSH2_COMP_METHOD libssh2_comp_method_none = {
static const LIBSSH2_COMP_METHOD comp_method_none = {
"none",
NULL,
libssh2_comp_method_none_comp,
comp_method_none_comp,
NULL
};
@@ -83,13 +87,13 @@ static const LIBSSH2_COMP_METHOD libssh2_comp_method_none = {
* zlib *
******** */
/* {{{ Memory management wrappers
/* Memory management wrappers
* Yes, I realize we're doing a callback to a callback,
* Deal...
*/
static voidpf
libssh2_comp_method_zlib_alloc(voidpf opaque, uInt items, uInt size)
comp_method_zlib_alloc(voidpf opaque, uInt items, uInt size)
{
LIBSSH2_SESSION *session = (LIBSSH2_SESSION *) opaque;
@@ -97,21 +101,21 @@ libssh2_comp_method_zlib_alloc(voidpf opaque, uInt items, uInt size)
}
static void
libssh2_comp_method_zlib_free(voidpf opaque, voidpf address)
comp_method_zlib_free(voidpf opaque, voidpf address)
{
LIBSSH2_SESSION *session = (LIBSSH2_SESSION *) opaque;
LIBSSH2_FREE(session, address);
}
/* }}} */
/* {{{ libssh2_comp_method_zlib_init
/* libssh2_comp_method_zlib_init
* All your bandwidth are belong to us (so save some)
*/
static int
libssh2_comp_method_zlib_init(LIBSSH2_SESSION * session, int compress,
void **abstract)
comp_method_zlib_init(LIBSSH2_SESSION * session, int compress,
void **abstract)
{
z_stream *strm;
int status;
@@ -126,8 +130,8 @@ libssh2_comp_method_zlib_init(LIBSSH2_SESSION * session, int compress,
memset(strm, 0, sizeof(z_stream));
strm->opaque = (voidpf) session;
strm->zalloc = (alloc_func) libssh2_comp_method_zlib_alloc;
strm->zfree = (free_func) libssh2_comp_method_zlib_free;
strm->zalloc = (alloc_func) comp_method_zlib_alloc;
strm->zfree = (free_func) comp_method_zlib_free;
if (compress) {
/* deflate */
status = deflateInit(strm, Z_DEFAULT_COMPRESSION);
@@ -145,20 +149,20 @@ libssh2_comp_method_zlib_init(LIBSSH2_SESSION * session, int compress,
return 0;
}
/* }}} */
/* {{{ libssh2_comp_method_zlib_comp
/* libssh2_comp_method_zlib_comp
* zlib, a compression standard for all occasions
*/
static int
libssh2_comp_method_zlib_comp(LIBSSH2_SESSION * session,
int compress,
unsigned char **dest,
unsigned long *dest_len,
unsigned long payload_limit,
int *free_dest,
const unsigned char *src,
unsigned long src_len, void **abstract)
comp_method_zlib_comp(LIBSSH2_SESSION * session,
int compress,
unsigned char **dest,
unsigned long *dest_len,
unsigned long payload_limit,
int *free_dest,
const unsigned char *src,
unsigned long src_len, void **abstract)
{
z_stream *strm = *abstract;
/* A short-term alloc of a full data chunk is better than a series of
@@ -229,8 +233,9 @@ libssh2_comp_method_zlib_comp(LIBSSH2_SESSION * session,
compress ? (strm->avail_in + 4) : (2 * strm->avail_in);
} else
while (!strm->avail_out) {
/* Done with input, might be a byte or two in internal buffer during compress
* Or potentially many bytes if it's a decompress
/* Done with input, might be a byte or two in internal buffer
* during compress. Or potentially many bytes if it's a
* decompress
*/
int grow_size = compress ? 8 : 1024;
char *newout;
@@ -283,14 +288,13 @@ libssh2_comp_method_zlib_comp(LIBSSH2_SESSION * session,
return 0;
}
/* }}} */
/* {{{ libssh2_comp_method_zlib_dtor
/* libssh2_comp_method_zlib_dtor
* All done, no more compression for you
*/
static int
libssh2_comp_method_zlib_dtor(LIBSSH2_SESSION * session, int compress,
void **abstract)
comp_method_zlib_dtor(LIBSSH2_SESSION * session, int compress,
void **abstract)
{
z_stream *strm = *abstract;
@@ -311,13 +315,11 @@ libssh2_comp_method_zlib_dtor(LIBSSH2_SESSION * session, int compress,
return 0;
}
/* }}} */
static const LIBSSH2_COMP_METHOD libssh2_comp_method_zlib = {
static const LIBSSH2_COMP_METHOD comp_method_zlib = {
"zlib",
libssh2_comp_method_zlib_init,
libssh2_comp_method_zlib_comp,
libssh2_comp_method_zlib_dtor,
comp_method_zlib_init,
comp_method_zlib_comp,
comp_method_zlib_dtor,
};
#endif /* LIBSSH2_HAVE_ZLIB */
@@ -325,16 +327,16 @@ static const LIBSSH2_COMP_METHOD libssh2_comp_method_zlib = {
* Compression Methods *
*********************** */
static const LIBSSH2_COMP_METHOD *_libssh2_comp_methods[] = {
&libssh2_comp_method_none,
static const LIBSSH2_COMP_METHOD *comp_methods[] = {
&comp_method_none,
#ifdef LIBSSH2_HAVE_ZLIB
&libssh2_comp_method_zlib,
&comp_method_zlib,
#endif /* LIBSSH2_HAVE_ZLIB */
NULL
};
const LIBSSH2_COMP_METHOD **
libssh2_comp_methods(void)
_libssh2_comp_methods(void)
{
return _libssh2_comp_methods;
return comp_methods;
}

45
src/comp.h Normal file
View File

@@ -0,0 +1,45 @@
#ifndef __LIBSSH2_COMP_H
#define __LIBSSH2_COMP_H
/* Copyright (C) 2009 by Daniel Stenberg
*
* Redistribution and use in source and binary forms,
* with or without modification, are permitted provided
* that the following conditions are met:
*
* Redistributions of source code must retain the above
* copyright notice, this list of conditions and the
* following disclaimer.
*
* Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following
* disclaimer in the documentation and/or other materials
* provided with the distribution.
*
* Neither the name of the copyright holder nor the names
* of any other contributors may be used to endorse or
* promote products derived from this software without
* specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
* CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
* USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
* OF SUCH DAMAGE.
*
*/
#include "libssh2_priv.h"
const LIBSSH2_COMP_METHOD **_libssh2_comp_methods(void);
#endif /* __LIBSSH2_COMP_H */

View File

@@ -38,27 +38,26 @@
#include "libssh2_priv.h"
#ifdef LIBSSH2_CRYPT_NONE
/* {{{ libssh2_crypt_none_crypt
/* crypt_none_crypt
* Minimalist cipher: VERY secure *wink*
*/
static int
libssh2_crypt_none_crypt(LIBSSH2_SESSION * session, unsigned char *buf,
crypt_none_crypt(LIBSSH2_SESSION * session, unsigned char *buf,
void **abstract)
{
/* Do nothing to the data! */
return 0;
}
/* }}} */
static const LIBSSH2_CRYPT_METHOD libssh2_crypt_method_none = {
"none",
8, /* blocksize (SSH2 defines minimum blocksize as 8) */
0, /* iv_len */
0, /* secret_len */
0, /* flags */
8, /* blocksize (SSH2 defines minimum blocksize as 8) */
0, /* iv_len */
0, /* secret_len */
0, /* flags */
NULL,
libssh2_crypt_none_crypt,
crypt_none_crypt,
NULL
};
#endif /* LIBSSH2_CRYPT_NONE */
@@ -66,16 +65,16 @@ static const LIBSSH2_CRYPT_METHOD libssh2_crypt_method_none = {
struct crypt_ctx
{
int encrypt;
_libssh2_cipher_type(algo);
_libssh2_cipher_type(algo);
_libssh2_cipher_ctx h;
};
static int
_libssh2_init(LIBSSH2_SESSION * session,
const LIBSSH2_CRYPT_METHOD * method,
unsigned char *iv, int *free_iv,
unsigned char *secret, int *free_secret,
int encrypt, void **abstract)
crypt_init(LIBSSH2_SESSION * session,
const LIBSSH2_CRYPT_METHOD * method,
unsigned char *iv, int *free_iv,
unsigned char *secret, int *free_secret,
int encrypt, void **abstract)
{
struct crypt_ctx *ctx = LIBSSH2_ALLOC(session,
sizeof(struct crypt_ctx));
@@ -95,7 +94,7 @@ _libssh2_init(LIBSSH2_SESSION * session,
}
static int
_libssh2_encrypt(LIBSSH2_SESSION * session, unsigned char *block,
crypt_encrypt(LIBSSH2_SESSION * session, unsigned char *block,
void **abstract)
{
struct crypt_ctx *cctx = *(struct crypt_ctx **) abstract;
@@ -104,7 +103,7 @@ _libssh2_encrypt(LIBSSH2_SESSION * session, unsigned char *block,
}
static int
_libssh2_dtor(LIBSSH2_SESSION * session, void **abstract)
crypt_dtor(LIBSSH2_SESSION * session, void **abstract)
{
struct crypt_ctx **cctx = (struct crypt_ctx **) abstract;
if (cctx && *cctx) {
@@ -122,9 +121,9 @@ static const LIBSSH2_CRYPT_METHOD libssh2_crypt_method_aes128_cbc = {
16, /* initial value length */
16, /* secret length -- 16*8 == 128bit */
0, /* flags */
&_libssh2_init,
&_libssh2_encrypt,
&_libssh2_dtor,
&crypt_init,
&crypt_encrypt,
&crypt_dtor,
_libssh2_cipher_aes128
};
@@ -134,9 +133,9 @@ static const LIBSSH2_CRYPT_METHOD libssh2_crypt_method_aes192_cbc = {
16, /* initial value length */
24, /* secret length -- 24*8 == 192bit */
0, /* flags */
&_libssh2_init,
&_libssh2_encrypt,
&_libssh2_dtor,
&crypt_init,
&crypt_encrypt,
&crypt_dtor,
_libssh2_cipher_aes192
};
@@ -146,9 +145,9 @@ static const LIBSSH2_CRYPT_METHOD libssh2_crypt_method_aes256_cbc = {
16, /* initial value length */
32, /* secret length -- 32*8 == 256bit */
0, /* flags */
&_libssh2_init,
&_libssh2_encrypt,
&_libssh2_dtor,
&crypt_init,
&crypt_encrypt,
&crypt_dtor,
_libssh2_cipher_aes256
};
@@ -160,9 +159,9 @@ static const LIBSSH2_CRYPT_METHOD
16, /* initial value length */
32, /* secret length -- 32*8 == 256bit */
0, /* flags */
&_libssh2_init,
&_libssh2_encrypt,
&_libssh2_dtor,
&crypt_init,
&crypt_encrypt,
&crypt_dtor,
_libssh2_cipher_aes256
};
#endif /* LIBSSH2_AES */
@@ -174,9 +173,9 @@ static const LIBSSH2_CRYPT_METHOD libssh2_crypt_method_blowfish_cbc = {
8, /* initial value length */
16, /* secret length */
0, /* flags */
&_libssh2_init,
&_libssh2_encrypt,
&_libssh2_dtor,
&crypt_init,
&crypt_encrypt,
&crypt_dtor,
_libssh2_cipher_blowfish
};
#endif /* LIBSSH2_BLOWFISH */
@@ -188,9 +187,9 @@ static const LIBSSH2_CRYPT_METHOD libssh2_crypt_method_arcfour = {
8, /* initial value length */
16, /* secret length */
0, /* flags */
&_libssh2_init,
&_libssh2_encrypt,
&_libssh2_dtor,
&crypt_init,
&crypt_encrypt,
&crypt_dtor,
_libssh2_cipher_arcfour
};
#endif /* LIBSSH2_RC4 */
@@ -202,9 +201,9 @@ static const LIBSSH2_CRYPT_METHOD libssh2_crypt_method_cast128_cbc = {
8, /* initial value length */
16, /* secret length */
0, /* flags */
&_libssh2_init,
&_libssh2_encrypt,
&_libssh2_dtor,
&crypt_init,
&crypt_encrypt,
&crypt_dtor,
_libssh2_cipher_cast5
};
#endif /* LIBSSH2_CAST */
@@ -216,9 +215,9 @@ static const LIBSSH2_CRYPT_METHOD libssh2_crypt_method_3des_cbc = {
8, /* initial value length */
24, /* secret length */
0, /* flags */
&_libssh2_init,
&_libssh2_encrypt,
&_libssh2_dtor,
&crypt_init,
&crypt_encrypt,
&crypt_dtor,
_libssh2_cipher_3des
};
#endif

View File

@@ -47,17 +47,19 @@
* ssh-rsa *
*********** */
static int libssh2_hostkey_method_ssh_rsa_dtor(LIBSSH2_SESSION * session,
void **abstract);
static int hostkey_method_ssh_rsa_dtor(LIBSSH2_SESSION * session,
void **abstract);
/* {{{ libssh2_hostkey_method_ssh_rsa_init
/*
* hostkey_method_ssh_rsa_init
*
* Initialize the server hostkey working area with e/n pair
*/
static int
libssh2_hostkey_method_ssh_rsa_init(LIBSSH2_SESSION * session,
const unsigned char *hostkey_data,
unsigned long hostkey_data_len,
void **abstract)
hostkey_method_ssh_rsa_init(LIBSSH2_SESSION * session,
const unsigned char *hostkey_data,
unsigned long hostkey_data_len,
void **abstract)
{
libssh2_rsa_ctx *rsactx;
const unsigned char *s, *e, *n;
@@ -66,12 +68,12 @@ libssh2_hostkey_method_ssh_rsa_init(LIBSSH2_SESSION * session,
(void) hostkey_data_len;
if (*abstract) {
libssh2_hostkey_method_ssh_rsa_dtor(session, abstract);
hostkey_method_ssh_rsa_dtor(session, abstract);
*abstract = NULL;
}
s = hostkey_data;
len = libssh2_ntohu32(s);
len = _libssh2_ntohu32(s);
s += 4;
if (len != 7 || strncmp((char *) s, "ssh-rsa", 7) != 0) {
@@ -79,12 +81,12 @@ libssh2_hostkey_method_ssh_rsa_init(LIBSSH2_SESSION * session,
}
s += 7;
e_len = libssh2_ntohu32(s);
e_len = _libssh2_ntohu32(s);
s += 4;
e = s;
s += e_len;
n_len = libssh2_ntohu32(s);
n_len = _libssh2_ntohu32(s);
s += 4;
n = s;
s += n_len;
@@ -98,23 +100,23 @@ libssh2_hostkey_method_ssh_rsa_init(LIBSSH2_SESSION * session,
return 0;
}
/* }}} */
/* {{{ libssh2_hostkey_method_ssh_rsa_initPEM
/*
* hostkey_method_ssh_rsa_initPEM
*
* Load a Private Key from a PEM file
*/
static int
libssh2_hostkey_method_ssh_rsa_initPEM(LIBSSH2_SESSION * session,
const char *privkeyfile,
unsigned const char *passphrase,
void **abstract)
hostkey_method_ssh_rsa_initPEM(LIBSSH2_SESSION * session,
const char *privkeyfile,
unsigned const char *passphrase,
void **abstract)
{
libssh2_rsa_ctx *rsactx;
FILE *fp;
int ret;
if (*abstract) {
libssh2_hostkey_method_ssh_rsa_dtor(session, abstract);
hostkey_method_ssh_rsa_dtor(session, abstract);
*abstract = NULL;
}
@@ -134,17 +136,17 @@ libssh2_hostkey_method_ssh_rsa_initPEM(LIBSSH2_SESSION * session,
return 0;
}
/* }}} */
/* {{{ libssh2_hostkey_method_ssh_rsa_sign
/*
* hostkey_method_ssh_rsa_sign
*
* Verify signature created by remote
*/
static int
libssh2_hostkey_method_ssh_rsa_sig_verify(LIBSSH2_SESSION * session,
const unsigned char *sig,
unsigned long sig_len,
const unsigned char *m,
unsigned long m_len, void **abstract)
hostkey_method_ssh_rsa_sig_verify(LIBSSH2_SESSION * session,
const unsigned char *sig,
unsigned long sig_len,
const unsigned char *m,
unsigned long m_len, void **abstract)
{
libssh2_rsa_ctx *rsactx = (libssh2_rsa_ctx *) (*abstract);
(void) session;
@@ -155,18 +157,18 @@ libssh2_hostkey_method_ssh_rsa_sig_verify(LIBSSH2_SESSION * session,
return _libssh2_rsa_sha1_verify(rsactx, sig, sig_len, m, m_len);
}
/* }}} */
/* {{{ libssh2_hostkey_method_ssh_rsa_signv
/*
* hostkey_method_ssh_rsa_signv
*
* Construct a signature from an array of vectors
*/
static int
libssh2_hostkey_method_ssh_rsa_signv(LIBSSH2_SESSION * session,
unsigned char **signature,
unsigned long *signature_len,
unsigned long veccount,
const struct iovec datavec[],
void **abstract)
hostkey_method_ssh_rsa_signv(LIBSSH2_SESSION * session,
unsigned char **signature,
unsigned long *signature_len,
unsigned long veccount,
const struct iovec datavec[],
void **abstract)
{
libssh2_rsa_ctx *rsactx = (libssh2_rsa_ctx *) (*abstract);
int ret;
@@ -189,13 +191,13 @@ libssh2_hostkey_method_ssh_rsa_signv(LIBSSH2_SESSION * session,
return 0;
}
/* }}} */
/* {{{ libssh2_hostkey_method_ssh_rsa_dtor
/*
* hostkey_method_ssh_rsa_dtor
*
* Shutdown the hostkey
*/
static int
libssh2_hostkey_method_ssh_rsa_dtor(LIBSSH2_SESSION * session, void **abstract)
hostkey_method_ssh_rsa_dtor(LIBSSH2_SESSION * session, void **abstract)
{
libssh2_rsa_ctx *rsactx = (libssh2_rsa_ctx *) (*abstract);
(void) session;
@@ -207,17 +209,15 @@ libssh2_hostkey_method_ssh_rsa_dtor(LIBSSH2_SESSION * session, void **abstract)
return 0;
}
/* }}} */
static const LIBSSH2_HOSTKEY_METHOD libssh2_hostkey_method_ssh_rsa = {
static const LIBSSH2_HOSTKEY_METHOD hostkey_method_ssh_rsa = {
"ssh-rsa",
MD5_DIGEST_LENGTH,
libssh2_hostkey_method_ssh_rsa_init,
libssh2_hostkey_method_ssh_rsa_initPEM,
libssh2_hostkey_method_ssh_rsa_sig_verify,
libssh2_hostkey_method_ssh_rsa_signv,
hostkey_method_ssh_rsa_init,
hostkey_method_ssh_rsa_initPEM,
hostkey_method_ssh_rsa_sig_verify,
hostkey_method_ssh_rsa_signv,
NULL, /* encrypt */
libssh2_hostkey_method_ssh_rsa_dtor,
hostkey_method_ssh_rsa_dtor,
};
#endif /* LIBSSH2_RSA */
@@ -226,17 +226,19 @@ static const LIBSSH2_HOSTKEY_METHOD libssh2_hostkey_method_ssh_rsa = {
* ssh-dss *
*********** */
static int libssh2_hostkey_method_ssh_dss_dtor(LIBSSH2_SESSION * session,
void **abstract);
static int hostkey_method_ssh_dss_dtor(LIBSSH2_SESSION * session,
void **abstract);
/* {{{ libssh2_hostkey_method_ssh_dss_init
/*
* hostkey_method_ssh_dss_init
*
* Initialize the server hostkey working area with p/q/g/y set
*/
static int
libssh2_hostkey_method_ssh_dss_init(LIBSSH2_SESSION * session,
const unsigned char *hostkey_data,
unsigned long hostkey_data_len,
void **abstract)
hostkey_method_ssh_dss_init(LIBSSH2_SESSION * session,
const unsigned char *hostkey_data,
unsigned long hostkey_data_len,
void **abstract)
{
libssh2_dsa_ctx *dsactx;
const unsigned char *p, *q, *g, *y, *s;
@@ -244,31 +246,31 @@ libssh2_hostkey_method_ssh_dss_init(LIBSSH2_SESSION * session,
(void) hostkey_data_len;
if (*abstract) {
libssh2_hostkey_method_ssh_dss_dtor(session, abstract);
hostkey_method_ssh_dss_dtor(session, abstract);
*abstract = NULL;
}
s = hostkey_data;
len = libssh2_ntohu32(s);
len = _libssh2_ntohu32(s);
s += 4;
if (len != 7 || strncmp((char *) s, "ssh-dss", 7) != 0) {
return -1;
}
s += 7;
p_len = libssh2_ntohu32(s);
p_len = _libssh2_ntohu32(s);
s += 4;
p = s;
s += p_len;
q_len = libssh2_ntohu32(s);
q_len = _libssh2_ntohu32(s);
s += 4;
q = s;
s += q_len;
g_len = libssh2_ntohu32(s);
g_len = _libssh2_ntohu32(s);
s += 4;
g = s;
s += g_len;
y_len = libssh2_ntohu32(s);
y_len = _libssh2_ntohu32(s);
s += 4;
y = s;
s += y_len;
@@ -280,23 +282,23 @@ libssh2_hostkey_method_ssh_dss_init(LIBSSH2_SESSION * session,
return 0;
}
/* }}} */
/* {{{ libssh2_hostkey_method_ssh_dss_initPEM
/*
* hostkey_method_ssh_dss_initPEM
*
* Load a Private Key from a PEM file
*/
static int
libssh2_hostkey_method_ssh_dss_initPEM(LIBSSH2_SESSION * session,
const char *privkeyfile,
unsigned const char *passphrase,
void **abstract)
hostkey_method_ssh_dss_initPEM(LIBSSH2_SESSION * session,
const char *privkeyfile,
unsigned const char *passphrase,
void **abstract)
{
libssh2_dsa_ctx *dsactx;
FILE *fp;
int ret;
if (*abstract) {
libssh2_hostkey_method_ssh_dss_dtor(session, abstract);
hostkey_method_ssh_dss_dtor(session, abstract);
*abstract = NULL;
}
@@ -316,17 +318,17 @@ libssh2_hostkey_method_ssh_dss_initPEM(LIBSSH2_SESSION * session,
return 0;
}
/* }}} */
/* {{{ libssh2_hostkey_method_ssh_dss_sign
/*
* libssh2_hostkey_method_ssh_dss_sign
*
* Verify signature created by remote
*/
static int
libssh2_hostkey_method_ssh_dss_sig_verify(LIBSSH2_SESSION * session,
const unsigned char *sig,
unsigned long sig_len,
const unsigned char *m,
unsigned long m_len, void **abstract)
hostkey_method_ssh_dss_sig_verify(LIBSSH2_SESSION * session,
const unsigned char *sig,
unsigned long sig_len,
const unsigned char *m,
unsigned long m_len, void **abstract)
{
libssh2_dsa_ctx *dsactx = (libssh2_dsa_ctx *) (*abstract);
@@ -341,18 +343,18 @@ libssh2_hostkey_method_ssh_dss_sig_verify(LIBSSH2_SESSION * session,
return _libssh2_dsa_sha1_verify(dsactx, sig, m, m_len);
}
/* }}} */
/* {{{ libssh2_hostkey_method_ssh_dss_signv
/*
* hostkey_method_ssh_dss_signv
*
* Construct a signature from an array of vectors
*/
static int
libssh2_hostkey_method_ssh_dss_signv(LIBSSH2_SESSION * session,
unsigned char **signature,
unsigned long *signature_len,
unsigned long veccount,
const struct iovec datavec[],
void **abstract)
hostkey_method_ssh_dss_signv(LIBSSH2_SESSION * session,
unsigned char **signature,
unsigned long *signature_len,
unsigned long veccount,
const struct iovec datavec[],
void **abstract)
{
libssh2_dsa_ctx *dsactx = (libssh2_dsa_ctx *) (*abstract);
unsigned char hash[SHA_DIGEST_LENGTH];
@@ -381,13 +383,13 @@ libssh2_hostkey_method_ssh_dss_signv(LIBSSH2_SESSION * session,
return 0;
}
/* }}} */
/* {{{ libssh2_hostkey_method_ssh_dss_dtor
/*
* libssh2_hostkey_method_ssh_dss_dtor
*
* Shutdown the hostkey method
*/
static int
libssh2_hostkey_method_ssh_dss_dtor(LIBSSH2_SESSION * session, void **abstract)
hostkey_method_ssh_dss_dtor(LIBSSH2_SESSION * session, void **abstract)
{
libssh2_dsa_ctx *dsactx = (libssh2_dsa_ctx *) (*abstract);
(void) session;
@@ -399,26 +401,24 @@ libssh2_hostkey_method_ssh_dss_dtor(LIBSSH2_SESSION * session, void **abstract)
return 0;
}
/* }}} */
static const LIBSSH2_HOSTKEY_METHOD libssh2_hostkey_method_ssh_dss = {
static const LIBSSH2_HOSTKEY_METHOD hostkey_method_ssh_dss = {
"ssh-dss",
MD5_DIGEST_LENGTH,
libssh2_hostkey_method_ssh_dss_init,
libssh2_hostkey_method_ssh_dss_initPEM,
libssh2_hostkey_method_ssh_dss_sig_verify,
libssh2_hostkey_method_ssh_dss_signv,
hostkey_method_ssh_dss_init,
hostkey_method_ssh_dss_initPEM,
hostkey_method_ssh_dss_sig_verify,
hostkey_method_ssh_dss_signv,
NULL, /* encrypt */
libssh2_hostkey_method_ssh_dss_dtor,
hostkey_method_ssh_dss_dtor,
};
#endif /* LIBSSH2_DSA */
static const LIBSSH2_HOSTKEY_METHOD *_libssh2_hostkey_methods[] = {
static const LIBSSH2_HOSTKEY_METHOD *hostkey_methods[] = {
#if LIBSSH2_RSA
&libssh2_hostkey_method_ssh_rsa,
&hostkey_method_ssh_rsa,
#endif /* LIBSSH2_RSA */
#if LIBSSH2_DSA
&libssh2_hostkey_method_ssh_dss,
&hostkey_method_ssh_dss,
#endif /* LIBSSH2_DSA */
NULL
};
@@ -426,10 +426,12 @@ static const LIBSSH2_HOSTKEY_METHOD *_libssh2_hostkey_methods[] = {
const LIBSSH2_HOSTKEY_METHOD **
libssh2_hostkey_methods(void)
{
return _libssh2_hostkey_methods;
return hostkey_methods;
}
/* {{{ libssh2_hostkey_hash
/*
* libssh2_hostkey_hash
*
* Returns hash signature
* Returned buffer should NOT be freed
* Length of buffer is determined by hash type
@@ -451,5 +453,3 @@ libssh2_hostkey_hash(LIBSSH2_SESSION * session, int hash_type)
return NULL;
}
}
/* }}} */

529
src/kex.c

File diff suppressed because it is too large Load Diff

View File

@@ -1,4 +1,5 @@
/* Copyright (c) 2004-2008, Sara Golemon <sarag@libssh2.org>
* Copyright (c) 2009 by Daniel Stenberg
* All rights reserved.
*
* Redistribution and use in source and binary forms,
@@ -79,24 +80,31 @@
#include "libssh2_publickey.h"
#include "libssh2_sftp.h"
#ifndef FALSE
#define FALSE 0
#endif
#ifndef TRUE
#define TRUE 1
#endif
/* Provide iovec / writev on WIN32 platform. */
#ifdef WIN32
/* same as WSABUF */
struct iovec {
u_long iov_len;
char *iov_base;
u_long iov_len;
char *iov_base;
};
#define inline __inline
static inline int writev(int sock, struct iovec *iov, int nvecs)
{
DWORD ret;
if (WSASend(sock, (LPWSABUF)iov, nvecs, &ret, 0, NULL, NULL) == 0) {
return ret;
}
return -1;
DWORD ret;
if (WSASend(sock, (LPWSABUF)iov, nvecs, &ret, 0, NULL, NULL) == 0) {
return ret;
}
return -1;
}
#endif /* WIN32 */
@@ -133,13 +141,6 @@ static inline int writev(int sock, struct iovec *iov, int nvecs)
#define inline __inline
#endif
/* not really usleep, but safe for the way we use it in this lib */
static inline int usleep(int udelay)
{
Sleep(udelay / 1000);
return 0;
}
#endif
/* RFC4253 section 6.1 Maximum Packet Length says:
@@ -151,13 +152,20 @@ static inline int usleep(int udelay)
*/
#define MAX_SSH_PACKET_LEN 35000
#define LIBSSH2_ALLOC(session, count) session->alloc((count), &(session)->abstract)
#define LIBSSH2_REALLOC(session, ptr, count) ((ptr) ? session->realloc((ptr), (count), &(session)->abstract) : session->alloc((count), &(session)->abstract))
#define LIBSSH2_FREE(session, ptr) session->free((ptr), &(session)->abstract)
#define LIBSSH2_IGNORE(session, data, datalen) session->ssh_msg_ignore((session), (data), (datalen), &(session)->abstract)
#define LIBSSH2_DEBUG(session, always_display, message, message_len, language, language_len) \
session->ssh_msg_disconnect((session), (always_display), (message), (message_len), (language), (language_len), &(session)->abstract)
#define LIBSSH2_ALLOC(session, count) \
session->alloc((count), &(session)->abstract)
#define LIBSSH2_REALLOC(session, ptr, count) \
((ptr) ? session->realloc((ptr), (count), &(session)->abstract) : \
session->alloc((count), &(session)->abstract))
#define LIBSSH2_FREE(session, ptr) \
session->free((ptr), &(session)->abstract)
#define LIBSSH2_IGNORE(session, data, datalen) \
session->ssh_msg_ignore((session), (data), (datalen), &(session)->abstract)
#define LIBSSH2_DEBUG(session, always_display, message, message_len, \
language, language_len) \
session->ssh_msg_disconnect((session), (always_display), (message), \
(message_len), (language), (language_len), \
&(session)->abstract)
#define LIBSSH2_DISCONNECT(session, reason, message, message_len, language, language_len) \
session->ssh_msg_disconnect((session), (reason), (message), (message_len), (language), (language_len), &(session)->abstract)
@@ -387,11 +395,8 @@ struct _LIBSSH2_CHANNEL
libssh2_nonblocking_states read_state;
LIBSSH2_PACKET *read_packet;
LIBSSH2_PACKET *read_next;
int read_block;
int read_bytes_read;
uint32_t read_local_id;
int read_want;
int read_unlink_packet;
/* State variables used in libssh2_channel_write_ex() */
libssh2_nonblocking_states write_state;
@@ -466,7 +471,7 @@ typedef struct _libssh2_endpoint_data
char *lang_prefs;
} libssh2_endpoint_data;
#define PACKETBUFSIZE 4096
#define PACKETBUFSIZE (1024*16)
struct transportpacket
{
@@ -679,6 +684,9 @@ struct _LIBSSH2_SESSION
unsigned char *session_id;
unsigned long session_id_len;
/* this is set to TRUE if a blocking API behavior is requested */
int api_block_mode;
/* Server's public key */
const LIBSSH2_HOSTKEY_METHOD *hostkey;
void *server_hostkey_abstract;
@@ -699,7 +707,8 @@ struct _LIBSSH2_SESSION
/* (local as source of data -- packet_write ) */
libssh2_endpoint_data local;
/* Inbound Data buffer -- Sometimes the packet that comes in isn't the packet we're ready for */
/* Inbound Data buffer -- Sometimes the packet that comes in isn't the
packet we're ready for */
LIBSSH2_PACKET_BRIGADE packets;
/* Active connection channels */
@@ -710,9 +719,10 @@ struct _LIBSSH2_SESSION
/* Actual I/O socket */
int socket_fd;
int socket_block;
int socket_state;
int socket_block_directions;
int socket_prev_blockstate; /* stores the state of the socket blockiness
when libssh2_session_startup() is called */
/* Error tracking */
char *err_msg;
@@ -861,7 +871,8 @@ struct _LIBSSH2_SESSION
libssh2_nonblocking_states sftpInit_state;
LIBSSH2_SFTP *sftpInit_sftp;
LIBSSH2_CHANNEL *sftpInit_channel;
unsigned char sftpInit_buffer[9]; /* sftp_header(5){excludes request_id} + version_id(4) */
unsigned char sftpInit_buffer[9]; /* sftp_header(5){excludes request_id}
+ version_id(4) */
/* State variables used in libssh2_scp_recv() */
libssh2_nonblocking_states scpRecv_state;
@@ -1121,16 +1132,24 @@ _libssh2_debug(LIBSSH2_SESSION * session, int context, const char *format, ...)
#define SSH_MSG_CHANNEL_SUCCESS 99
#define SSH_MSG_CHANNEL_FAILURE 100
void libssh2_session_shutdown(LIBSSH2_SESSION * session);
void _libssh2_session_shutdown(LIBSSH2_SESSION * session);
unsigned long libssh2_ntohu32(const unsigned char *buf);
libssh2_uint64_t libssh2_ntohu64(const unsigned char *buf);
void libssh2_htonu32(unsigned char *buf, unsigned long val);
void libssh2_htonu64(unsigned char *buf, libssh2_uint64_t val);
unsigned int _libssh2_ntohu32(const unsigned char *buf);
libssh2_uint64_t _libssh2_ntohu64(const unsigned char *buf);
void _libssh2_htonu32(unsigned char *buf, unsigned int val);
#ifdef WIN32
ssize_t _libssh2_recv(int socket, void *buffer, size_t length, int flags);
ssize_t _libssh2_send(int socket, const void *buffer, size_t length, int flags);
#else
#define _libssh2_recv(a,b,c,d) recv(a,b,c,d)
#define _libssh2_send(a,b,c,d) send(a,b,c,d)
#endif
#define LIBSSH2_READ_TIMEOUT 60 /* generic timeout in seconds used when
waiting for more data to arrive */
int libssh2_waitsocket(LIBSSH2_SESSION * session, long seconds);
int _libssh2_wait_socket(LIBSSH2_SESSION *session);
/* CAUTION: some of these error codes are returned in the public API and is
@@ -1146,55 +1165,53 @@ int libssh2_waitsocket(LIBSSH2_SESSION * session, long seconds);
#define PACKET_FAIL -1
#define PACKET_NONE 0
libssh2pack_t libssh2_packet_read(LIBSSH2_SESSION * session);
libssh2pack_t _libssh2_packet_read(LIBSSH2_SESSION * session);
int libssh2_packet_ask_ex(LIBSSH2_SESSION * session, unsigned char packet_type,
unsigned char **data, unsigned long *data_len,
unsigned long match_ofs,
const unsigned char *match_buf,
unsigned long match_len, int poll_socket);
int _libssh2_packet_ask(LIBSSH2_SESSION * session, unsigned char packet_type,
unsigned char **data, unsigned long *data_len,
unsigned long match_ofs,
const unsigned char *match_buf,
unsigned long match_len);
int libssh2_packet_askv_ex(LIBSSH2_SESSION * session,
const unsigned char *packet_types,
unsigned char **data, unsigned long *data_len,
unsigned long match_ofs,
const unsigned char *match_buf,
unsigned long match_len, int poll_socket);
int libssh2_packet_require_ex(LIBSSH2_SESSION * session,
unsigned char packet_type, unsigned char **data,
unsigned long *data_len, unsigned long match_ofs,
const unsigned char *match_buf,
unsigned long match_len,
packet_require_state_t * state);
int libssh2_packet_requirev_ex(LIBSSH2_SESSION * session,
const unsigned char *packet_types,
unsigned char **data, unsigned long *data_len,
unsigned long match_ofs,
const unsigned char *match_buf,
unsigned long match_len,
packet_requirev_state_t * state);
int libssh2_packet_burn(LIBSSH2_SESSION * session,
libssh2_nonblocking_states * state);
int libssh2_packet_write(LIBSSH2_SESSION * session, unsigned char *data,
unsigned long data_len);
int libssh2_packet_add(LIBSSH2_SESSION * session, unsigned char *data,
size_t datalen, int macstate);
int _libssh2_packet_askv(LIBSSH2_SESSION * session,
const unsigned char *packet_types,
unsigned char **data, unsigned long *data_len,
unsigned long match_ofs,
const unsigned char *match_buf,
unsigned long match_len);
int _libssh2_packet_require(LIBSSH2_SESSION * session,
unsigned char packet_type, unsigned char **data,
unsigned long *data_len, unsigned long match_ofs,
const unsigned char *match_buf,
unsigned long match_len,
packet_require_state_t * state);
int _libssh2_packet_requirev(LIBSSH2_SESSION * session,
const unsigned char *packet_types,
unsigned char **data, unsigned long *data_len,
unsigned long match_ofs,
const unsigned char *match_buf,
unsigned long match_len,
packet_requirev_state_t * state);
int _libssh2_packet_burn(LIBSSH2_SESSION * session,
libssh2_nonblocking_states * state);
int _libssh2_packet_write(LIBSSH2_SESSION * session, unsigned char *data,
unsigned long data_len);
int _libssh2_packet_add(LIBSSH2_SESSION * session, unsigned char *data,
size_t datalen, int macstate);
int libssh2_kex_exchange(LIBSSH2_SESSION * session, int reexchange,
key_exchange_state_t * state);
unsigned long libssh2_channel_nextid(LIBSSH2_SESSION * session);
LIBSSH2_CHANNEL *libssh2_channel_locate(LIBSSH2_SESSION * session,
unsigned long channel_id);
unsigned long libssh2_channel_packet_data_len(LIBSSH2_CHANNEL * channel,
int stream_id);
unsigned long _libssh2_channel_nextid(LIBSSH2_SESSION * session);
LIBSSH2_CHANNEL *_libssh2_channel_locate(LIBSSH2_SESSION * session,
unsigned long channel_id);
unsigned long _libssh2_channel_packet_data_len(LIBSSH2_CHANNEL * channel,
int stream_id);
/* this is the lib-internal set blocking function */
int _libssh2_session_set_blocking(LIBSSH2_SESSION * session, int blocking);
/* Let crypt.c/hostkey.c/comp.c/mac.c expose their method structs */
/* Let crypt.c/hostkey.c expose their method structs */
const LIBSSH2_CRYPT_METHOD **libssh2_crypt_methods(void);
const LIBSSH2_HOSTKEY_METHOD **libssh2_hostkey_methods(void);
const LIBSSH2_COMP_METHOD **libssh2_comp_methods(void);
const LIBSSH2_MAC_METHOD **libssh2_mac_methods(void);
/* Language API doesn't exist yet. Just act like we've agreed on a language */
#define libssh2_kex_agree_lang(session, endpoint, str, str_len) 0
@@ -1208,4 +1225,49 @@ int _libssh2_pem_decode_sequence(unsigned char **data, unsigned int *datalen);
int _libssh2_pem_decode_integer(unsigned char **data, unsigned int *datalen,
unsigned char **i, unsigned int *ilen);
/* Conveniance-macros to allow code like this;
int rc = BLOCK_ADJUST(rc, session, session_startup(session, sock) );
int rc = BLOCK_ADJUST_ERRNO(ptr, session, session_startup(session, sock) );
The point of course being to make sure that while in non-blocking mode
these always return no matter what the return code is, but in blocking mode
it blocks if EAGAIN is the reason for the return from the underlying
function.
*/
#define BLOCK_ADJUST(rc,sess,x) \
do { \
rc = x; \
/* the order of the check below is important to properly deal with the
case when the 'sess' is freed */ \
if((rc != LIBSSH2_ERROR_EAGAIN) || !sess->api_block_mode) \
break; \
rc = _libssh2_wait_socket(sess); \
if(rc) \
break; \
} while(1)
/*
* For functions that returns a pointer, we need to check if the API is
* non-blocking and return immediately. If the pointer is non-NULL we return
* immediately. If the API is blocking and we get a NULL we check the errno
* and *only* if that is EAGAIN we loop and wait for socket action.
*/
#define BLOCK_ADJUST_ERRNO(ptr,sess,x) \
do { \
int rc; \
ptr = x; \
if(!sess->api_block_mode || \
(ptr != NULL) || \
(libssh2_session_last_errno(sess) != LIBSSH2_ERROR_EAGAIN) ) \
break; \
rc = _libssh2_wait_socket(sess); \
if(rc) \
break; \
} while(1)
#endif /* LIBSSH2_H */

197
src/mac.c
View File

@@ -36,39 +36,40 @@
*/
#include "libssh2_priv.h"
#include "mac.h"
#ifdef LIBSSH2_MAC_NONE
/* {{{ libssh2_mac_none_MAC
/* mac_none_MAC
* Minimalist MAC: No MAC
*/
static int
libssh2_mac_none_MAC(LIBSSH2_SESSION * session, unsigned char *buf,
unsigned long seqno, const unsigned char *packet,
unsigned long packet_len, const unsigned char *addtl,
unsigned long addtl_len, void **abstract)
mac_none_MAC(LIBSSH2_SESSION * session, unsigned char *buf,
unsigned long seqno, const unsigned char *packet,
unsigned long packet_len, const unsigned char *addtl,
unsigned long addtl_len, void **abstract)
{
return 0;
}
/* }}} */
static LIBSSH2_MAC_METHOD libssh2_mac_method_none = {
static LIBSSH2_MAC_METHOD mac_method_none = {
"none",
0,
0,
NULL,
libssh2_mac_none_MAC,
mac_none_MAC,
NULL
};
#endif /* LIBSSH2_MAC_NONE */
/* {{{ libssh2_mac_method_common_init
/* mac_method_common_init
* Initialize simple mac methods
*/
static int
libssh2_mac_method_common_init(LIBSSH2_SESSION * session, unsigned char *key,
int *free_key, void **abstract)
mac_method_common_init(LIBSSH2_SESSION * session, unsigned char *key,
int *free_key, void **abstract)
{
*abstract = key;
*free_key = 0;
@@ -77,13 +78,13 @@ libssh2_mac_method_common_init(LIBSSH2_SESSION * session, unsigned char *key,
return 0;
}
/* }}} */
/* {{{ libssh2_mac_method_common_dtor
/* mac_method_common_dtor
* Cleanup simple mac methods
*/
static int
libssh2_mac_method_common_dtor(LIBSSH2_SESSION * session, void **abstract)
mac_method_common_dtor(LIBSSH2_SESSION * session, void **abstract)
{
if (*abstract) {
LIBSSH2_FREE(session, *abstract);
@@ -93,24 +94,24 @@ libssh2_mac_method_common_dtor(LIBSSH2_SESSION * session, void **abstract)
return 0;
}
/* }}} */
/* {{{ libssh2_mac_method_hmac_sha1_hash
/* mac_method_hmac_sha1_hash
* Calculate hash using full sha1 value
*/
static int
libssh2_mac_method_hmac_sha1_hash(LIBSSH2_SESSION * session,
unsigned char *buf, unsigned long seqno,
const unsigned char *packet,
unsigned long packet_len,
const unsigned char *addtl,
unsigned long addtl_len, void **abstract)
mac_method_hmac_sha1_hash(LIBSSH2_SESSION * session,
unsigned char *buf, unsigned long seqno,
const unsigned char *packet,
unsigned long packet_len,
const unsigned char *addtl,
unsigned long addtl_len, void **abstract)
{
libssh2_hmac_ctx ctx;
unsigned char seqno_buf[4];
(void) session;
libssh2_htonu32(seqno_buf, seqno);
_libssh2_htonu32(seqno_buf, seqno);
libssh2_hmac_sha1_init(&ctx, *abstract, 20);
libssh2_hmac_update(ctx, seqno_buf, 4);
@@ -124,64 +125,64 @@ libssh2_mac_method_hmac_sha1_hash(LIBSSH2_SESSION * session,
return 0;
}
/* }}} */
static const LIBSSH2_MAC_METHOD libssh2_mac_method_hmac_sha1 = {
static const LIBSSH2_MAC_METHOD mac_method_hmac_sha1 = {
"hmac-sha1",
20,
20,
libssh2_mac_method_common_init,
libssh2_mac_method_hmac_sha1_hash,
libssh2_mac_method_common_dtor,
mac_method_common_init,
mac_method_hmac_sha1_hash,
mac_method_common_dtor,
};
/* {{{ libssh2_mac_method_hmac_sha1_96_hash
/* mac_method_hmac_sha1_96_hash
* Calculate hash using first 96 bits of sha1 value
*/
static int
libssh2_mac_method_hmac_sha1_96_hash(LIBSSH2_SESSION * session,
unsigned char *buf, unsigned long seqno,
const unsigned char *packet,
unsigned long packet_len,
const unsigned char *addtl,
unsigned long addtl_len, void **abstract)
mac_method_hmac_sha1_96_hash(LIBSSH2_SESSION * session,
unsigned char *buf, unsigned long seqno,
const unsigned char *packet,
unsigned long packet_len,
const unsigned char *addtl,
unsigned long addtl_len, void **abstract)
{
unsigned char temp[SHA_DIGEST_LENGTH];
libssh2_mac_method_hmac_sha1_hash(session, temp, seqno, packet, packet_len,
addtl, addtl_len, abstract);
mac_method_hmac_sha1_hash(session, temp, seqno, packet, packet_len,
addtl, addtl_len, abstract);
memcpy(buf, (char *) temp, 96 / 8);
return 0;
}
/* }}} */
static const LIBSSH2_MAC_METHOD libssh2_mac_method_hmac_sha1_96 = {
static const LIBSSH2_MAC_METHOD mac_method_hmac_sha1_96 = {
"hmac-sha1-96",
12,
20,
libssh2_mac_method_common_init,
libssh2_mac_method_hmac_sha1_96_hash,
libssh2_mac_method_common_dtor,
mac_method_common_init,
mac_method_hmac_sha1_96_hash,
mac_method_common_dtor,
};
/* {{{ libssh2_mac_method_hmac_md5_hash
/* mac_method_hmac_md5_hash
* Calculate hash using full md5 value
*/
static int
libssh2_mac_method_hmac_md5_hash(LIBSSH2_SESSION * session, unsigned char *buf,
unsigned long seqno,
const unsigned char *packet,
unsigned long packet_len,
const unsigned char *addtl,
unsigned long addtl_len, void **abstract)
mac_method_hmac_md5_hash(LIBSSH2_SESSION * session, unsigned char *buf,
unsigned long seqno,
const unsigned char *packet,
unsigned long packet_len,
const unsigned char *addtl,
unsigned long addtl_len, void **abstract)
{
libssh2_hmac_ctx ctx;
unsigned char seqno_buf[4];
(void) session;
libssh2_htonu32(seqno_buf, seqno);
_libssh2_htonu32(seqno_buf, seqno);
libssh2_hmac_md5_init(&ctx, *abstract, 16);
libssh2_hmac_update(ctx, seqno_buf, 4);
@@ -195,66 +196,64 @@ libssh2_mac_method_hmac_md5_hash(LIBSSH2_SESSION * session, unsigned char *buf,
return 0;
}
/* }}} */
static const LIBSSH2_MAC_METHOD libssh2_mac_method_hmac_md5 = {
static const LIBSSH2_MAC_METHOD mac_method_hmac_md5 = {
"hmac-md5",
16,
16,
libssh2_mac_method_common_init,
libssh2_mac_method_hmac_md5_hash,
libssh2_mac_method_common_dtor,
mac_method_common_init,
mac_method_hmac_md5_hash,
mac_method_common_dtor,
};
/* {{{ libssh2_mac_method_hmac_md5_96_hash
/* mac_method_hmac_md5_96_hash
* Calculate hash using first 96 bits of md5 value
*/
static int
libssh2_mac_method_hmac_md5_96_hash(LIBSSH2_SESSION * session,
unsigned char *buf, unsigned long seqno,
const unsigned char *packet,
unsigned long packet_len,
const unsigned char *addtl,
unsigned long addtl_len, void **abstract)
mac_method_hmac_md5_96_hash(LIBSSH2_SESSION * session,
unsigned char *buf, unsigned long seqno,
const unsigned char *packet,
unsigned long packet_len,
const unsigned char *addtl,
unsigned long addtl_len, void **abstract)
{
unsigned char temp[MD5_DIGEST_LENGTH];
libssh2_mac_method_hmac_md5_hash(session, temp, seqno, packet, packet_len,
addtl, addtl_len, abstract);
mac_method_hmac_md5_hash(session, temp, seqno, packet, packet_len,
addtl, addtl_len, abstract);
memcpy(buf, (char *) temp, 96 / 8);
return 0;
}
/* }}} */
static const LIBSSH2_MAC_METHOD libssh2_mac_method_hmac_md5_96 = {
static const LIBSSH2_MAC_METHOD mac_method_hmac_md5_96 = {
"hmac-md5-96",
12,
16,
libssh2_mac_method_common_init,
libssh2_mac_method_hmac_md5_96_hash,
libssh2_mac_method_common_dtor,
mac_method_common_init,
mac_method_hmac_md5_96_hash,
mac_method_common_dtor,
};
#if LIBSSH2_HMAC_RIPEMD
/* {{{ libssh2_mac_method_hmac_ripemd160_hash
/* mac_method_hmac_ripemd160_hash
* Calculate hash using ripemd160 value
*/
static int
libssh2_mac_method_hmac_ripemd160_hash(LIBSSH2_SESSION * session,
unsigned char *buf, unsigned long seqno,
const unsigned char *packet,
unsigned long packet_len,
const unsigned char *addtl,
unsigned long addtl_len,
void **abstract)
mac_method_hmac_ripemd160_hash(LIBSSH2_SESSION * session,
unsigned char *buf, unsigned long seqno,
const unsigned char *packet,
unsigned long packet_len,
const unsigned char *addtl,
unsigned long addtl_len,
void **abstract)
{
libssh2_hmac_ctx ctx;
unsigned char seqno_buf[4];
(void) session;
libssh2_htonu32(seqno_buf, seqno);
_libssh2_htonu32(seqno_buf, seqno);
libssh2_hmac_ripemd160_init(&ctx, *abstract, 20);
libssh2_hmac_update(ctx, seqno_buf, 4);
@@ -268,44 +267,44 @@ libssh2_mac_method_hmac_ripemd160_hash(LIBSSH2_SESSION * session,
return 0;
}
/* }}} */
static const LIBSSH2_MAC_METHOD libssh2_mac_method_hmac_ripemd160 = {
static const LIBSSH2_MAC_METHOD mac_method_hmac_ripemd160 = {
"hmac-ripemd160",
20,
20,
libssh2_mac_method_common_init,
libssh2_mac_method_hmac_ripemd160_hash,
libssh2_mac_method_common_dtor,
mac_method_common_init,
mac_method_hmac_ripemd160_hash,
mac_method_common_dtor,
};
static const LIBSSH2_MAC_METHOD libssh2_mac_method_hmac_ripemd160_openssh_com = {
static const LIBSSH2_MAC_METHOD mac_method_hmac_ripemd160_openssh_com = {
"hmac-ripemd160@openssh.com",
20,
20,
libssh2_mac_method_common_init,
libssh2_mac_method_hmac_ripemd160_hash,
libssh2_mac_method_common_dtor,
mac_method_common_init,
mac_method_hmac_ripemd160_hash,
mac_method_common_dtor,
};
#endif /* LIBSSH2_HMAC_RIPEMD */
static const LIBSSH2_MAC_METHOD *_libssh2_mac_methods[] = {
&libssh2_mac_method_hmac_sha1,
&libssh2_mac_method_hmac_sha1_96,
&libssh2_mac_method_hmac_md5,
&libssh2_mac_method_hmac_md5_96,
static const LIBSSH2_MAC_METHOD *mac_methods[] = {
&mac_method_hmac_sha1,
&mac_method_hmac_sha1_96,
&mac_method_hmac_md5,
&mac_method_hmac_md5_96,
#if LIBSSH2_HMAC_RIPEMD
&libssh2_mac_method_hmac_ripemd160,
&libssh2_mac_method_hmac_ripemd160_openssh_com,
&mac_method_hmac_ripemd160,
&mac_method_hmac_ripemd160_openssh_com,
#endif /* LIBSSH2_HMAC_RIPEMD */
#ifdef LIBSSH2_MAC_NONE
&libssh2_mac_method_none,
&mac_method_none,
#endif /* LIBSSH2_MAC_NONE */
NULL
};
const LIBSSH2_MAC_METHOD **
libssh2_mac_methods(void)
_libssh2_mac_methods(void)
{
return _libssh2_mac_methods;
return mac_methods;
}

45
src/mac.h Normal file
View File

@@ -0,0 +1,45 @@
#ifndef __LIBSSH2_MAC_H
#define __LIBSSH2_MAC_H
/* Copyright (C) 2009 by Daniel Stenberg
*
* Redistribution and use in source and binary forms,
* with or without modification, are permitted provided
* that the following conditions are met:
*
* Redistributions of source code must retain the above
* copyright notice, this list of conditions and the
* following disclaimer.
*
* Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following
* disclaimer in the documentation and/or other materials
* provided with the distribution.
*
* Neither the name of the copyright holder nor the names
* of any other contributors may be used to endorse or
* promote products derived from this software without
* specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
* CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
* USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
* OF SUCH DAMAGE.
*
*/
#include "libssh2_priv.h"
const LIBSSH2_MAC_METHOD **_libssh2_mac_methods(void);
#endif /* __LIBSSH2_MAC_H */

View File

@@ -1,4 +1,5 @@
/* Copyright (c) 2004-2007, Sara Golemon <sarag@libssh2.org>
* Copyright (c) 2009 by Daniel Stenberg
* All rights reserved.
*
* Redistribution and use in source and binary forms,
@@ -40,21 +41,84 @@
#include <unistd.h>
#endif
/* {{{ libssh2_ntohu32
#ifdef HAVE_SYS_TIME_H
#include <sys/time.h>
#endif
#include <errno.h>
#ifdef WIN32
static int wsa2errno(void)
{
switch (WSAGetLastError()) {
case WSAEWOULDBLOCK:
return EAGAIN;
case WSAENOTSOCK:
return EBADF;
case WSAEINTR:
return EINTR;
default:
/* It is most important to ensure errno does not stay at EAGAIN
* when a different error occurs so just set errno to a generic
* error */
return EIO;
}
}
#endif
#ifndef _libssh2_recv
/* _libssh2_recv
*
* Wrapper around standard recv to allow WIN32 systems
* to set errno
*/
unsigned long
libssh2_ntohu32(const unsigned char *buf)
ssize_t
_libssh2_recv(int socket, void *buffer, size_t length, int flags)
{
ssize_t rc = recv(socket, buffer, length, flags);
#ifdef WIN32
if (rc < 0 )
errno = wsa2errno();
#endif
return rc;
}
#endif /* _libssh2_recv */
#ifndef _libssh2_send
/* _libssh2_send
*
* Wrapper around standard send to allow WIN32 systems
* to set errno
*/
ssize_t
_libssh2_send(int socket, const void *buffer, size_t length, int flags)
{
ssize_t rc = send(socket, buffer, length, flags);
#ifdef WIN32
if (rc < 0 )
errno = wsa2errno();
#endif
return rc;
}
#endif /* _libssh2_recv */
/* libssh2_ntohu32
*/
unsigned int
_libssh2_ntohu32(const unsigned char *buf)
{
return (buf[0] << 24) | (buf[1] << 16) | (buf[2] << 8) | buf[3];
}
/* }}} */
/* {{{ libssh2_ntohu64
*
/* _libssh2_ntohu64
*/
libssh2_uint64_t
libssh2_ntohu64(const unsigned char *buf)
_libssh2_ntohu64(const unsigned char *buf)
{
unsigned long msl, lsl;
@@ -64,12 +128,10 @@ libssh2_ntohu64(const unsigned char *buf)
return ((libssh2_uint64_t)msl <<32) | lsl;
}
/* }}} */
/* {{{ libssh2_htonu32
/* _libssh2_htonu32
*/
void
libssh2_htonu32(unsigned char *buf, unsigned long value)
_libssh2_htonu32(unsigned char *buf, unsigned int value)
{
buf[0] = (value >> 24) & 0xFF;
buf[1] = (value >> 16) & 0xFF;
@@ -77,42 +139,20 @@ libssh2_htonu32(unsigned char *buf, unsigned long value)
buf[3] = value & 0xFF;
}
/* }}} */
/* {{{ libssh2_htonu64
*/
void
libssh2_htonu64(unsigned char *buf, libssh2_uint64_t value)
{
unsigned long msl = ((libssh2_uint64_t)value >> 32);
buf[0] = (msl >> 24) & 0xFF;
buf[1] = (msl >> 16) & 0xFF;
buf[2] = (msl >> 8) & 0xFF;
buf[3] = msl & 0xFF;
buf[4] = (value >> 24) & 0xFF;
buf[5] = (value >> 16) & 0xFF;
buf[6] = (value >> 8) & 0xFF;
buf[7] = value & 0xFF;
}
/* }}} */
/* Base64 Conversion */
/* {{{ */
static const char libssh2_base64_table[] =
{ 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M',
static const char base64_table[] =
{
'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M',
'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z',
'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm',
'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z',
'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '+', '/', '\0'
};
static const char libssh2_base64_pad = '=';
static const char base64_pad = '=';
static const short libssh2_base64_reverse_table[256] = {
static const short base64_reverse_table[256] = {
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 62, -1, -1, -1, 63,
@@ -131,10 +171,8 @@ static const short libssh2_base64_reverse_table[256] = {
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1
};
/* }}} */
/* {{{ libssh2_base64_decode
/* libssh2_base64_decode
*
* Decode a base64 chunk and store it into a newly alloc'd buffer
*/
LIBSSH2_API int
@@ -153,7 +191,7 @@ libssh2_base64_decode(LIBSSH2_SESSION * session, char **data,
}
for(s = (unsigned char *) src; ((char *) s) < (src + src_len); s++) {
if ((v = libssh2_base64_reverse_table[*s]) < 0)
if ((v = base64_reverse_table[*s]) < 0)
continue;
switch (i % 4) {
case 0:
@@ -174,7 +212,8 @@ libssh2_base64_decode(LIBSSH2_SESSION * session, char **data,
i++;
}
if ((i % 4) == 1) {
/* Invalid -- We have a byte which belongs exclusively to a partial octet */
/* Invalid -- We have a byte which belongs exclusively to a partial
octet */
LIBSSH2_FREE(session, *data);
return -1;
}
@@ -183,8 +222,6 @@ libssh2_base64_decode(LIBSSH2_SESSION * session, char **data,
return 0;
}
/* }}} */
#ifdef LIBSSH2DEBUG
LIBSSH2_API int
libssh2_trace(LIBSSH2_SESSION * session, int bitmask)
@@ -199,16 +236,18 @@ _libssh2_debug(LIBSSH2_SESSION * session, int context, const char *format, ...)
char buffer[1536];
int len;
va_list vargs;
struct timeval now;
static int firstsec;
static const char *const contexts[9] = {
"Unknown",
"Transport",
"Key Exchange",
"Key Ex",
"Userauth",
"Connection",
"scp",
"SFTP Subsystem",
"Conn",
"SCP",
"SFTP",
"Failure Event",
"Publickey Subsystem",
"Publickey",
};
if (context < 1 || context > 8) {
@@ -218,8 +257,14 @@ _libssh2_debug(LIBSSH2_SESSION * session, int context, const char *format, ...)
/* no such output asked for */
return;
}
gettimeofday(&now, NULL);
if(!firstsec) {
firstsec = now.tv_sec;
}
now.tv_sec -= firstsec;
len = snprintf(buffer, 1535, "[libssh2] %s: ", contexts[context]);
len = snprintf(buffer, sizeof(buffer), "[libssh2] %d.%06d %s: ",
(int)now.tv_sec, (int)now.tv_usec, contexts[context]);
va_start(vargs, format);
len += vsnprintf(buffer + len, 1535 - len, format, vargs);

View File

@@ -100,8 +100,7 @@
# define LIBSSH2_3DES 1
#endif
#define libssh2_random(buf, len) \
RAND_bytes ((buf), (len))
#define libssh2_random(buf, len) RAND_bytes ((buf), (len))
#define libssh2_sha1_ctx SHA_CTX
#define libssh2_sha1_init(ctx) SHA1_Init(ctx)

View File

@@ -1,4 +1,5 @@
/* Copyright (c) 2004-2007, Sara Golemon <sarag@libssh2.org>
* Copyright (c) 2009 by Daniel Stenberg
* All rights reserved.
*
* Redistribution and use in source and binary forms,
@@ -58,13 +59,17 @@
#include <sys/types.h>
/* {{{ libssh2_packet_queue_listener
#include "transport.h"
/*
* libssh2_packet_queue_listener
*
* Queue a connection request for a listener
*/
static inline int
libssh2_packet_queue_listener(LIBSSH2_SESSION * session, unsigned char *data,
unsigned long datalen,
packet_queue_listener_state_t * listen_state)
packet_queue_listener(LIBSSH2_SESSION * session, unsigned char *data,
unsigned long datalen,
packet_queue_listener_state_t * listen_state)
{
/*
* Look for a matching listener
@@ -80,26 +85,26 @@ libssh2_packet_queue_listener(LIBSSH2_SESSION * session, unsigned char *data,
(void) datalen;
if (listen_state->state == libssh2_NB_state_idle) {
listen_state->sender_channel = libssh2_ntohu32(s);
listen_state->sender_channel = _libssh2_ntohu32(s);
s += 4;
listen_state->initial_window_size = libssh2_ntohu32(s);
listen_state->initial_window_size = _libssh2_ntohu32(s);
s += 4;
listen_state->packet_size = libssh2_ntohu32(s);
listen_state->packet_size = _libssh2_ntohu32(s);
s += 4;
listen_state->host_len = libssh2_ntohu32(s);
listen_state->host_len = _libssh2_ntohu32(s);
s += 4;
listen_state->host = s;
s += listen_state->host_len;
listen_state->port = libssh2_ntohu32(s);
listen_state->port = _libssh2_ntohu32(s);
s += 4;
listen_state->shost_len = libssh2_ntohu32(s);
listen_state->shost_len = _libssh2_ntohu32(s);
s += 4;
listen_state->shost = s;
s += listen_state->shost_len;
listen_state->sport = libssh2_ntohu32(s);
listen_state->sport = _libssh2_ntohu32(s);
s += 4;
_libssh2_debug(session, LIBSSH2_DBG_CONN,
@@ -169,7 +174,7 @@ libssh2_packet_queue_listener(LIBSSH2_SESSION * session, unsigned char *data,
channel->remote.packet_size =
LIBSSH2_CHANNEL_PACKET_DEFAULT;
channel->local.id = libssh2_channel_nextid(session);
channel->local.id = _libssh2_channel_nextid(session);
channel->local.window_size_initial =
listen_state->initial_window_size;
channel->local.window_size =
@@ -186,21 +191,21 @@ libssh2_packet_queue_listener(LIBSSH2_SESSION * session, unsigned char *data,
p = listen_state->packet;
*(p++) = SSH_MSG_CHANNEL_OPEN_CONFIRMATION;
libssh2_htonu32(p, channel->remote.id);
_libssh2_htonu32(p, channel->remote.id);
p += 4;
libssh2_htonu32(p, channel->local.id);
_libssh2_htonu32(p, channel->local.id);
p += 4;
libssh2_htonu32(p, channel->remote.window_size_initial);
_libssh2_htonu32(p, channel->remote.window_size_initial);
p += 4;
libssh2_htonu32(p, channel->remote.packet_size);
_libssh2_htonu32(p, channel->remote.packet_size);
p += 4;
listen_state->state = libssh2_NB_state_created;
}
if (listen_state->state == libssh2_NB_state_created) {
rc = libssh2_packet_write(session, listen_state->packet,
17);
rc = _libssh2_transport_write(session, listen_state->packet,
17);
if (rc == PACKET_EAGAIN) {
return PACKET_EAGAIN;
} else if (rc) {
@@ -243,17 +248,18 @@ libssh2_packet_queue_listener(LIBSSH2_SESSION * session, unsigned char *data,
{
p = listen_state->packet;
*(p++) = SSH_MSG_CHANNEL_OPEN_FAILURE;
libssh2_htonu32(p, listen_state->sender_channel);
_libssh2_htonu32(p, listen_state->sender_channel);
p += 4;
libssh2_htonu32(p, failure_code);
_libssh2_htonu32(p, failure_code);
p += 4;
libssh2_htonu32(p, sizeof(FwdNotReq) - 1);
_libssh2_htonu32(p, sizeof(FwdNotReq) - 1);
p += 4;
memcpy(s, FwdNotReq, sizeof(FwdNotReq) - 1);
p += sizeof(FwdNotReq) - 1;
libssh2_htonu32(p, 0);
_libssh2_htonu32(p, 0);
rc = libssh2_packet_write(session, listen_state->packet, packet_len);
rc = _libssh2_transport_write(session, listen_state->packet,
packet_len);
if (rc == PACKET_EAGAIN) {
return PACKET_EAGAIN;
} else if (rc) {
@@ -267,15 +273,15 @@ libssh2_packet_queue_listener(LIBSSH2_SESSION * session, unsigned char *data,
}
}
/* }}} */
/* {{{ libssh2_packet_x11_open
/*
* packet_x11_open
*
* Accept a forwarded X11 connection
*/
static inline int
libssh2_packet_x11_open(LIBSSH2_SESSION * session, unsigned char *data,
unsigned long datalen,
packet_x11_open_state_t * x11open_state)
packet_x11_open(LIBSSH2_SESSION * session, unsigned char *data,
unsigned long datalen,
packet_x11_open_state_t * x11open_state)
{
int failure_code = 2; /* SSH_OPEN_CONNECT_FAILED */
unsigned char *s = data + (sizeof("x11") - 1) + 5;
@@ -288,17 +294,17 @@ libssh2_packet_x11_open(LIBSSH2_SESSION * session, unsigned char *data,
(void) datalen;
if (x11open_state->state == libssh2_NB_state_idle) {
x11open_state->sender_channel = libssh2_ntohu32(s);
x11open_state->sender_channel = _libssh2_ntohu32(s);
s += 4;
x11open_state->initial_window_size = libssh2_ntohu32(s);
x11open_state->initial_window_size = _libssh2_ntohu32(s);
s += 4;
x11open_state->packet_size = libssh2_ntohu32(s);
x11open_state->packet_size = _libssh2_ntohu32(s);
s += 4;
x11open_state->shost_len = libssh2_ntohu32(s);
x11open_state->shost_len = _libssh2_ntohu32(s);
s += 4;
x11open_state->shost = s;
s += x11open_state->shost_len;
x11open_state->sport = libssh2_ntohu32(s);
x11open_state->sport = _libssh2_ntohu32(s);
s += 4;
_libssh2_debug(session, LIBSSH2_DBG_CONN,
@@ -343,7 +349,7 @@ libssh2_packet_x11_open(LIBSSH2_SESSION * session, unsigned char *data,
channel->remote.window_size = LIBSSH2_CHANNEL_WINDOW_DEFAULT;
channel->remote.packet_size = LIBSSH2_CHANNEL_PACKET_DEFAULT;
channel->local.id = libssh2_channel_nextid(session);
channel->local.id = _libssh2_channel_nextid(session);
channel->local.window_size_initial =
x11open_state->initial_window_size;
channel->local.window_size = x11open_state->initial_window_size;
@@ -358,20 +364,20 @@ libssh2_packet_x11_open(LIBSSH2_SESSION * session, unsigned char *data,
channel->remote.packet_size);
p = x11open_state->packet;
*(p++) = SSH_MSG_CHANNEL_OPEN_CONFIRMATION;
libssh2_htonu32(p, channel->remote.id);
_libssh2_htonu32(p, channel->remote.id);
p += 4;
libssh2_htonu32(p, channel->local.id);
_libssh2_htonu32(p, channel->local.id);
p += 4;
libssh2_htonu32(p, channel->remote.window_size_initial);
_libssh2_htonu32(p, channel->remote.window_size_initial);
p += 4;
libssh2_htonu32(p, channel->remote.packet_size);
_libssh2_htonu32(p, channel->remote.packet_size);
p += 4;
x11open_state->state = libssh2_NB_state_created;
}
if (x11open_state->state == libssh2_NB_state_created) {
rc = libssh2_packet_write(session, x11open_state->packet, 17);
rc = _libssh2_transport_write(session, x11open_state->packet, 17);
if (rc == PACKET_EAGAIN) {
return PACKET_EAGAIN;
} else if (rc) {
@@ -409,17 +415,17 @@ libssh2_packet_x11_open(LIBSSH2_SESSION * session, unsigned char *data,
x11_exit:
p = x11open_state->packet;
*(p++) = SSH_MSG_CHANNEL_OPEN_FAILURE;
libssh2_htonu32(p, x11open_state->sender_channel);
_libssh2_htonu32(p, x11open_state->sender_channel);
p += 4;
libssh2_htonu32(p, failure_code);
_libssh2_htonu32(p, failure_code);
p += 4;
libssh2_htonu32(p, sizeof(X11FwdUnAvil) - 1);
_libssh2_htonu32(p, sizeof(X11FwdUnAvil) - 1);
p += 4;
memcpy(s, X11FwdUnAvil, sizeof(X11FwdUnAvil) - 1);
p += sizeof(X11FwdUnAvil) - 1;
libssh2_htonu32(p, 0);
_libssh2_htonu32(p, 0);
rc = libssh2_packet_write(session, x11open_state->packet, packet_len);
rc = _libssh2_transport_write(session, x11open_state->packet, packet_len);
if (rc == PACKET_EAGAIN) {
return PACKET_EAGAIN;
} else if (rc) {
@@ -432,14 +438,15 @@ libssh2_packet_x11_open(LIBSSH2_SESSION * session, unsigned char *data,
return 0;
}
/* }}} */
/* {{{ libssh2_packet_new
* Create a new packet and attach it to the brigade
/*
* _libssh2_packet_add
*
* Create a new packet and attach it to the brigade. Called from the transport
* layer when it as received a packet.
*/
int
libssh2_packet_add(LIBSSH2_SESSION * session, unsigned char *data,
size_t datalen, int macstate)
_libssh2_packet_add(LIBSSH2_SESSION * session, unsigned char *data,
size_t datalen, int macstate)
{
int rc;
@@ -518,11 +525,11 @@ libssh2_packet_add(LIBSSH2_SESSION * session, unsigned char *data,
char *message, *language;
int reason, message_len, language_len;
reason = libssh2_ntohu32(data + 1);
message_len = libssh2_ntohu32(data + 5);
reason = _libssh2_ntohu32(data + 1);
message_len = _libssh2_ntohu32(data + 5);
/* 9 = packet_type(1) + reason(4) + message_len(4) */
message = (char *) data + 9;
language_len = libssh2_ntohu32(data + 9 + message_len);
language_len = _libssh2_ntohu32(data + 9 + message_len);
/*
* This is where we hack on the data a little,
* Use the MSB of language_len to to a terminating NULL
@@ -573,10 +580,10 @@ libssh2_packet_add(LIBSSH2_SESSION * session, unsigned char *data,
char *message, *language;
int message_len, language_len;
message_len = libssh2_ntohu32(data + 2);
message_len = _libssh2_ntohu32(data + 2);
/* 6 = packet_type(1) + display(1) + message_len(4) */
message = (char *) data + 6;
language_len = libssh2_ntohu32(data + 6 + message_len);
language_len = _libssh2_ntohu32(data + 6 + message_len);
/*
* This is where we hack on the data a little,
* Use the MSB of language_len to to a terminating NULL
@@ -617,118 +624,116 @@ libssh2_packet_add(LIBSSH2_SESSION * session, unsigned char *data,
case SSH_MSG_CHANNEL_DATA:
/* packet_type(1) + channelno(4) + datalen(4) */
session->packAdd_data_head += 9;
{
session->packAdd_channel = libssh2_channel_locate(session,
libssh2_ntohu32
(data + 1));
if (!session->packAdd_channel) {
libssh2_error(session, LIBSSH2_ERROR_CHANNEL_UNKNOWN,
"Packet received for unknown channel, ignoring",
0);
LIBSSH2_FREE(session, data);
session->packAdd_state = libssh2_NB_state_idle;
return 0;
}
#ifdef LIBSSH2DEBUG
{
unsigned long stream_id = 0;
session->packAdd_channel =
_libssh2_channel_locate(session, _libssh2_ntohu32(data + 1));
if (data[0] == SSH_MSG_CHANNEL_EXTENDED_DATA) {
stream_id = libssh2_ntohu32(data + 5);
}
_libssh2_debug(session, LIBSSH2_DBG_CONN,
"%d bytes received for channel %lu/%lu stream #%lu",
(int) (datalen -
session->packAdd_data_head),
session->packAdd_channel->local.id,
session->packAdd_channel->remote.id,
stream_id);
}
#endif
if ((session->packAdd_channel->remote.
extended_data_ignore_mode ==
LIBSSH2_CHANNEL_EXTENDED_DATA_IGNORE)
&& (data[0] == SSH_MSG_CHANNEL_EXTENDED_DATA)) {
/* Pretend we didn't receive this */
LIBSSH2_FREE(session, data);
_libssh2_debug(session, LIBSSH2_DBG_CONN,
"Ignoring extended data and refunding %d bytes",
(int) (datalen - 13));
/* Adjust the window based on the block we just freed */
libssh2_packet_add_jump_point1:
session->packAdd_state = libssh2_NB_state_jump1;
rc = libssh2_channel_receive_window_adjust(session->
packAdd_channel,
datalen - 13,
0);
if (rc == PACKET_EAGAIN) {
session->socket_block_directions =
LIBSSH2_SESSION_BLOCK_OUTBOUND;
return PACKET_EAGAIN;
}
session->packAdd_state = libssh2_NB_state_idle;
return 0;
}
/*
* REMEMBER! remote means remote as source of data,
* NOT remote window!
*/
if (session->packAdd_channel->remote.packet_size <
(datalen - session->packAdd_data_head)) {
/*
* Spec says we MAY ignore bytes sent beyond
* packet_size
*/
libssh2_error(session,
LIBSSH2_ERROR_CHANNEL_PACKET_EXCEEDED,
"Packet contains more data than we offered to receive, truncating",
0);
datalen =
session->packAdd_channel->remote.packet_size +
session->packAdd_data_head;
}
if (session->packAdd_channel->remote.window_size <= 0) {
/*
* Spec says we MAY ignore bytes sent beyond
* window_size
*/
libssh2_error(session,
LIBSSH2_ERROR_CHANNEL_WINDOW_EXCEEDED,
"The current receive window is full, data ignored",
0);
LIBSSH2_FREE(session, data);
session->packAdd_state = libssh2_NB_state_idle;
return 0;
}
/* Reset EOF status */
session->packAdd_channel->remote.eof = 0;
if ((datalen - session->packAdd_data_head) >
session->packAdd_channel->remote.window_size) {
libssh2_error(session,
LIBSSH2_ERROR_CHANNEL_WINDOW_EXCEEDED,
"Remote sent more data than current window allows, truncating",
0);
datalen =
session->packAdd_channel->remote.window_size +
session->packAdd_data_head;
} else {
/* Now that we've received it, shrink our window */
session->packAdd_channel->remote.window_size -=
datalen - session->packAdd_data_head;
}
if (!session->packAdd_channel) {
libssh2_error(session, LIBSSH2_ERROR_CHANNEL_UNKNOWN,
"Packet received for unknown channel, ignoring",
0);
LIBSSH2_FREE(session, data);
session->packAdd_state = libssh2_NB_state_idle;
return 0;
}
#ifdef LIBSSH2DEBUG
{
unsigned long stream_id = 0;
if (data[0] == SSH_MSG_CHANNEL_EXTENDED_DATA) {
stream_id = _libssh2_ntohu32(data + 5);
}
_libssh2_debug(session, LIBSSH2_DBG_CONN,
"%d bytes packet_add() for %lu/%lu/%lu",
(int) (datalen - session->packAdd_data_head),
session->packAdd_channel->local.id,
session->packAdd_channel->remote.id,
stream_id);
}
#endif
if ((session->packAdd_channel->remote.extended_data_ignore_mode ==
LIBSSH2_CHANNEL_EXTENDED_DATA_IGNORE) &&
(data[0] == SSH_MSG_CHANNEL_EXTENDED_DATA)) {
/* Pretend we didn't receive this */
LIBSSH2_FREE(session, data);
_libssh2_debug(session, LIBSSH2_DBG_CONN,
"Ignoring extended data and refunding %d bytes",
(int) (datalen - 13));
/* Adjust the window based on the block we just freed */
libssh2_packet_add_jump_point1:
session->packAdd_state = libssh2_NB_state_jump1;
rc = libssh2_channel_receive_window_adjust(session->
packAdd_channel,
datalen - 13,
0);
if (rc == PACKET_EAGAIN) {
session->socket_block_directions =
LIBSSH2_SESSION_BLOCK_OUTBOUND;
return PACKET_EAGAIN;
}
session->packAdd_state = libssh2_NB_state_idle;
return 0;
}
/*
* REMEMBER! remote means remote as source of data,
* NOT remote window!
*/
if (session->packAdd_channel->remote.packet_size <
(datalen - session->packAdd_data_head)) {
/*
* Spec says we MAY ignore bytes sent beyond
* packet_size
*/
libssh2_error(session,
LIBSSH2_ERROR_CHANNEL_PACKET_EXCEEDED,
"Packet contains more data than we offered"
" to receive, truncating", 0);
datalen =
session->packAdd_channel->remote.packet_size +
session->packAdd_data_head;
}
if (session->packAdd_channel->remote.window_size <= 0) {
/*
* Spec says we MAY ignore bytes sent beyond
* window_size
*/
libssh2_error(session,
LIBSSH2_ERROR_CHANNEL_WINDOW_EXCEEDED,
"The current receive window is full,"
" data ignored",
0);
LIBSSH2_FREE(session, data);
session->packAdd_state = libssh2_NB_state_idle;
return 0;
}
/* Reset EOF status */
session->packAdd_channel->remote.eof = 0;
if ((datalen - session->packAdd_data_head) >
session->packAdd_channel->remote.window_size) {
libssh2_error(session,
LIBSSH2_ERROR_CHANNEL_WINDOW_EXCEEDED,
"Remote sent more data than current "
"window allows, truncating",
0);
datalen =
session->packAdd_channel->remote.window_size +
session->packAdd_data_head;
}
else {
/* Now that we've received it, shrink our window */
session->packAdd_channel->remote.window_size -=
datalen - session->packAdd_data_head;
}
break;
case SSH_MSG_CHANNEL_EOF:
{
session->packAdd_channel = libssh2_channel_locate(session,
libssh2_ntohu32
(data + 1));
session->packAdd_channel =
_libssh2_channel_locate(session, _libssh2_ntohu32(data + 1));
if (!session->packAdd_channel) {
/* We may have freed already, just quietly ignore this... */
@@ -752,18 +757,18 @@ libssh2_packet_add(LIBSSH2_SESSION * session, unsigned char *data,
case SSH_MSG_CHANNEL_REQUEST:
{
if (libssh2_ntohu32(data + 5) == sizeof("exit-status") - 1
if (_libssh2_ntohu32(data + 5) == sizeof("exit-status") - 1
&& !memcmp("exit-status", data + 9,
sizeof("exit-status") - 1)) {
/* we've got "exit-status" packet. Set the session value */
session->packAdd_channel =
libssh2_channel_locate(session,
libssh2_ntohu32(data + 1));
_libssh2_channel_locate(session,
_libssh2_ntohu32(data + 1));
if (session->packAdd_channel) {
session->packAdd_channel->exit_status =
libssh2_ntohu32(data + 9 + sizeof("exit-status"));
_libssh2_ntohu32(data + 9 + sizeof("exit-status"));
_libssh2_debug(session, LIBSSH2_DBG_CONN,
"Exit status %lu received for channel %lu/%lu",
session->packAdd_channel->exit_status,
@@ -780,9 +785,8 @@ libssh2_packet_add(LIBSSH2_SESSION * session, unsigned char *data,
case SSH_MSG_CHANNEL_CLOSE:
{
session->packAdd_channel = libssh2_channel_locate(session,
libssh2_ntohu32
(data + 1));
session->packAdd_channel =
_libssh2_channel_locate(session, _libssh2_ntohu32(data + 1));
if (!session->packAdd_channel) {
/* We may have freed already, just quietly ignore this... */
@@ -807,7 +811,7 @@ libssh2_packet_add(LIBSSH2_SESSION * session, unsigned char *data,
case SSH_MSG_CHANNEL_OPEN:
if ((datalen >= (sizeof("forwarded-tcpip") + 4)) &&
((sizeof("forwarded-tcpip") - 1) == libssh2_ntohu32(data + 1))
((sizeof("forwarded-tcpip") - 1) == _libssh2_ntohu32(data + 1))
&&
(memcmp
(data + 5, "forwarded-tcpip",
@@ -815,9 +819,8 @@ libssh2_packet_add(LIBSSH2_SESSION * session, unsigned char *data,
libssh2_packet_add_jump_point2:
session->packAdd_state = libssh2_NB_state_jump2;
rc = libssh2_packet_queue_listener(session, data, datalen,
&session->
packAdd_Qlstn_state);
rc = packet_queue_listener(session, data, datalen,
&session->packAdd_Qlstn_state);
if (rc == PACKET_EAGAIN) {
session->socket_block_directions =
LIBSSH2_SESSION_BLOCK_OUTBOUND;
@@ -829,13 +832,13 @@ libssh2_packet_add(LIBSSH2_SESSION * session, unsigned char *data,
return rc;
}
if ((datalen >= (sizeof("x11") + 4)) &&
((sizeof("x11") - 1) == libssh2_ntohu32(data + 1)) &&
((sizeof("x11") - 1) == _libssh2_ntohu32(data + 1)) &&
(memcmp(data + 5, "x11", sizeof("x11") - 1) == 0)) {
libssh2_packet_add_jump_point3:
session->packAdd_state = libssh2_NB_state_jump3;
rc = libssh2_packet_x11_open(session, data, datalen,
&session->packAdd_x11open_state);
rc = packet_x11_open(session, data, datalen,
&session->packAdd_x11open_state);
if (rc == PACKET_EAGAIN) {
session->socket_block_directions =
LIBSSH2_SESSION_BLOCK_OUTBOUND;
@@ -850,10 +853,10 @@ libssh2_packet_add(LIBSSH2_SESSION * session, unsigned char *data,
case SSH_MSG_CHANNEL_WINDOW_ADJUST:
{
unsigned long bytestoadd = libssh2_ntohu32(data + 5);
session->packAdd_channel = libssh2_channel_locate(session,
libssh2_ntohu32
(data + 1));
unsigned long bytestoadd = _libssh2_ntohu32(data + 5);
session->packAdd_channel =
_libssh2_channel_locate(session,
_libssh2_ntohu32(data + 1));
if (session->packAdd_channel && bytestoadd) {
session->packAdd_channel->local.window_size += bytestoadd;
@@ -922,11 +925,10 @@ libssh2_packet_add(LIBSSH2_SESSION * session, unsigned char *data,
}
/*
* The KEXINIT message has been added to the queue.
* The packAdd and readPack states need to be reset
* because libssh2_kex_exchange (eventually) calls upon
* libssh2_packet_read to read the rest of the key exchange
* conversation.
* The KEXINIT message has been added to the queue. The packAdd and
* readPack states need to be reset because libssh2_kex_exchange
* (eventually) calls upon _libssh2_transport_read to read the rest of
* the key exchange conversation.
*/
session->readPack_state = libssh2_NB_state_idle;
session->packet.total_num = 0;
@@ -939,7 +941,7 @@ libssh2_packet_add(LIBSSH2_SESSION * session, unsigned char *data,
* How about re-using the startup_key_state?
*/
memset(&session->startup_key_state, 0, sizeof(key_exchange_state_t));
/*
* If there was a key reexchange failure, let's just hope we didn't
* send NEWKEYS yet, otherwise remote will drop us like a rock
@@ -954,49 +956,33 @@ libssh2_packet_add(LIBSSH2_SESSION * session, unsigned char *data,
return 0;
}
/* }}} */
/* {{{ libssh2_packet_ask
/*
* _libssh2_packet_ask
*
* Scan the brigade for a matching packet type, optionally poll the socket for
* a packet first
*/
int
libssh2_packet_ask_ex(LIBSSH2_SESSION * session, unsigned char packet_type,
unsigned char **data, unsigned long *data_len,
unsigned long match_ofs, const unsigned char *match_buf,
unsigned long match_len, int poll_socket)
_libssh2_packet_ask(LIBSSH2_SESSION * session, unsigned char packet_type,
unsigned char **data, unsigned long *data_len,
unsigned long match_ofs, const unsigned char *match_buf,
unsigned long match_len)
{
LIBSSH2_PACKET *packet = session->packets.head;
if (poll_socket) {
/*
* XXX CHECK ***
* When "poll_socket" is "1" libhss2_packet_read() can return
* PACKET_EAGAIN. I am not sure what should happen, but internally
* there is only one location that might do so, libssh2_packet_askv_ex()
*/
libssh2pack_t rc = libssh2_packet_read(session);
if ((rc < 0) && !packet) {
return rc;
}
}
_libssh2_debug(session, LIBSSH2_DBG_TRANS,
"Looking for packet of type: %d", (int) packet_type);
while (packet) {
if (packet->data[0] == packet_type
&& (packet->data_len >= (match_ofs + match_len)) && (!match_buf
||
(memcmp
(packet->
data +
match_ofs,
match_buf,
match_len)
== 0))) {
&& (packet->data_len >= (match_ofs + match_len))
&& (!match_buf ||
(memcmp(packet->data + match_ofs, match_buf,
match_len) == 0))) {
*data = packet->data;
*data_len = packet->data_len;
/* unlink struct */
if (packet->prev) {
packet->prev->next = packet->next;
} else {
@@ -1018,32 +1004,26 @@ libssh2_packet_ask_ex(LIBSSH2_SESSION * session, unsigned char packet_type,
return -1;
}
/* }}} */
/* {{{ libssh2_packet_askv
/*
* libssh2_packet_askv
*
* Scan for any of a list of packet types in the brigade, optionally poll the
* socket for a packet first
*/
int
libssh2_packet_askv_ex(LIBSSH2_SESSION * session,
const unsigned char *packet_types,
unsigned char **data, unsigned long *data_len,
unsigned long match_ofs,
const unsigned char *match_buf,
unsigned long match_len, int poll_socket)
_libssh2_packet_askv(LIBSSH2_SESSION * session,
const unsigned char *packet_types,
unsigned char **data, unsigned long *data_len,
unsigned long match_ofs,
const unsigned char *match_buf,
unsigned long match_len)
{
int i, packet_types_len = strlen((char *) packet_types);
for(i = 0; i < packet_types_len; i++) {
/*
* XXX CHECK XXX
* When "poll_socket" is "1" libssh2_packet_ask_ex() could
* return PACKET_EAGAIN. Not sure the correct action, I
* think it is right as is.
*/
if (0 == libssh2_packet_ask_ex(session, packet_types[i], data,
data_len, match_ofs, match_buf,
match_len, i ? 0 : poll_socket)) {
if (0 == _libssh2_packet_ask(session, packet_types[i], data,
data_len, match_ofs,
match_buf, match_len)) {
return 0;
}
}
@@ -1051,71 +1031,40 @@ libssh2_packet_askv_ex(LIBSSH2_SESSION * session,
return -1;
}
/* }}} */
/* {{{ waitsocket
* Returns
* negative on error
* >0 on incoming data
* 0 on timeout
/*
* _libssh2_packet_require
*
* FIXME: convert to use poll on systems that have it.
*/
int
libssh2_waitsocket(LIBSSH2_SESSION * session, long seconds)
{
struct timeval timeout;
int rc;
fd_set fd;
timeout.tv_sec = seconds;
timeout.tv_usec = 0;
FD_ZERO(&fd);
FD_SET(session->socket_fd, &fd);
rc = select(session->socket_fd + 1, &fd, NULL, NULL, &timeout);
return rc;
}
/* {{{ libssh2_packet_require
* Loops libssh2_packet_read() until the packet requested is available
* Loops _libssh2_transport_read() until the packet requested is available
* SSH_DISCONNECT or a SOCKET_DISCONNECTED will cause a bailout
*
* Returns negative on error
* Returns 0 when it has taken care of the requested packet.
*/
int
libssh2_packet_require_ex(LIBSSH2_SESSION * session, unsigned char packet_type,
unsigned char **data, unsigned long *data_len,
unsigned long match_ofs,
const unsigned char *match_buf,
unsigned long match_len,
packet_require_state_t * state)
_libssh2_packet_require(LIBSSH2_SESSION * session, unsigned char packet_type,
unsigned char **data, unsigned long *data_len,
unsigned long match_ofs,
const unsigned char *match_buf,
unsigned long match_len,
packet_require_state_t *state)
{
if (state->start == 0) {
if (libssh2_packet_ask_ex
(session, packet_type, data, data_len, match_ofs, match_buf,
match_len, 0) == 0) {
if (_libssh2_packet_ask(session, packet_type, data, data_len,
match_ofs, match_buf,
match_len) == 0) {
/* A packet was available in the packet brigade */
return 0;
}
state->start = time(NULL);
_libssh2_debug(session, LIBSSH2_DBG_TRANS,
"May block until packet of type %d becomes available",
(int) packet_type);
}
while (session->socket_state == LIBSSH2_SOCKET_CONNECTED) {
libssh2pack_t ret = libssh2_packet_read(session);
libssh2pack_t ret = _libssh2_transport_read(session);
if (ret == PACKET_EAGAIN) {
return PACKET_EAGAIN;
} else if ((ret == 0) && (!session->socket_block)) {
/* If we are in non-blocking and there is no data, return that */
} else if (ret == 0) {
/* There is no data, return that. TODO: is this really correct? */
return PACKET_EAGAIN;
} else if (ret < 0) {
state->start = 0;
@@ -1123,16 +1072,15 @@ libssh2_packet_require_ex(LIBSSH2_SESSION * session, unsigned char packet_type,
return ret;
} else if (ret == packet_type) {
/* Be lazy, let packet_ask pull it out of the brigade */
ret =
libssh2_packet_ask_ex(session, packet_type, data, data_len,
match_ofs, match_buf, match_len, 0);
ret = _libssh2_packet_ask(session, packet_type, data, data_len,
match_ofs, match_buf, match_len);
state->start = 0;
return ret;
} else if (ret == 0) {
/* nothing available, wait until data arrives or we time out */
long left = LIBSSH2_READ_TIMEOUT - (time(NULL) - state->start);
if ((left <= 0) || (libssh2_waitsocket(session, left) <= 0)) {
if (left <= 0) {
state->start = 0;
return PACKET_TIMEOUT;
}
@@ -1143,16 +1091,16 @@ libssh2_packet_require_ex(LIBSSH2_SESSION * session, unsigned char packet_type,
return -1;
}
/* }}} */
/* {{{ libssh2_packet_burn
* Loops libssh2_packet_read() until any packet is available and promptly
* discards it
/*
* _libssh2_packet_burn
*
* Loops _libssh2_transport_read() until any packet is available and promptly
* discards it.
* Used during KEX exchange to discard badly guessed KEX_INIT packets
*/
int
libssh2_packet_burn(LIBSSH2_SESSION * session,
libssh2_nonblocking_states * state)
_libssh2_packet_burn(LIBSSH2_SESSION * session,
libssh2_nonblocking_states * state)
{
unsigned char *data;
unsigned long data_len;
@@ -1165,8 +1113,8 @@ libssh2_packet_burn(LIBSSH2_SESSION * session,
all_packets[i - 1] = i;
}
if (libssh2_packet_askv_ex
(session, all_packets, &data, &data_len, 0, NULL, 0, 0) == 0) {
if (_libssh2_packet_askv(session, all_packets, &data, &data_len, 0,
NULL, 0) == 0) {
i = data[0];
/* A packet was available in the packet brigade, burn it */
LIBSSH2_FREE(session, data);
@@ -1179,7 +1127,7 @@ libssh2_packet_burn(LIBSSH2_SESSION * session,
}
while (session->socket_state == LIBSSH2_SOCKET_CONNECTED) {
if ((ret = libssh2_packet_read(session)) == PACKET_EAGAIN) {
if ((ret = _libssh2_transport_read(session)) == PACKET_EAGAIN) {
return PACKET_EAGAIN;
} else if (ret < 0) {
*state = libssh2_NB_state_idle;
@@ -1191,8 +1139,7 @@ libssh2_packet_burn(LIBSSH2_SESSION * session,
/* Be lazy, let packet_ask pull it out of the brigade */
if (0 ==
libssh2_packet_ask_ex(session, ret, &data, &data_len, 0, NULL, 0,
0)) {
_libssh2_packet_ask(session, ret, &data, &data_len, 0, NULL, 0)) {
/* Smoke 'em if you got 'em */
LIBSSH2_FREE(session, data);
*state = libssh2_NB_state_idle;
@@ -1204,31 +1151,27 @@ libssh2_packet_burn(LIBSSH2_SESSION * session,
return -1;
}
/* }}} */
/*
* {{{ libssh2_packet_requirev
* _libssh2_packet_requirev
*
* Loops libssh2_packet_read() until one of a list of packet types requested is
* Loops _libssh2_transport_read() until one of a list of packet types requested is
* available
* SSH_DISCONNECT or a SOCKET_DISCONNECTED will cause a bailout
* packet_types is a null terminated list of packet_type numbers
*/
int
libssh2_packet_requirev_ex(LIBSSH2_SESSION * session,
const unsigned char *packet_types,
unsigned char **data, unsigned long *data_len,
unsigned long match_ofs,
const unsigned char *match_buf,
unsigned long match_len,
packet_requirev_state_t * state)
_libssh2_packet_requirev(LIBSSH2_SESSION * session,
const unsigned char *packet_types,
unsigned char **data, unsigned long *data_len,
unsigned long match_ofs,
const unsigned char *match_buf,
unsigned long match_len,
packet_requirev_state_t * state)
{
if (libssh2_packet_askv_ex
(session, packet_types, data, data_len, match_ofs, match_buf,
match_len, 0) == 0) {
/* One of the packets listed was available in the packet
brigade */
if (_libssh2_packet_askv(session, packet_types, data, data_len, match_ofs,
match_buf, match_len) == 0) {
/* One of the packets listed was available in the packet brigade */
state->start = 0;
return 0;
}
@@ -1238,7 +1181,7 @@ libssh2_packet_requirev_ex(LIBSSH2_SESSION * session,
}
while (session->socket_state != LIBSSH2_SOCKET_DISCONNECTED) {
int ret = libssh2_packet_read(session);
int ret = _libssh2_transport_read(session);
if ((ret < 0) && (ret != PACKET_EAGAIN)) {
state->start = 0;
return ret;
@@ -1246,19 +1189,20 @@ libssh2_packet_requirev_ex(LIBSSH2_SESSION * session,
if (ret <= 0) {
long left = LIBSSH2_READ_TIMEOUT - (time(NULL) - state->start);
if ((left <= 0) || (libssh2_waitsocket(session, left) <= 0)) {
if (left <= 0) {
state->start = 0;
return PACKET_TIMEOUT;
} else if (ret == PACKET_EAGAIN) {
}
else if (ret == PACKET_EAGAIN) {
return PACKET_EAGAIN;
}
}
if (strchr((char *) packet_types, ret)) {
/* Be lazy, let packet_ask pull it out of the brigade */
return libssh2_packet_askv_ex(session, packet_types, data,
data_len, match_ofs, match_buf,
match_len, 0);
return _libssh2_packet_askv(session, packet_types, data,
data_len, match_ofs, match_buf,
match_len);
}
}
@@ -1267,4 +1211,3 @@ libssh2_packet_requirev_ex(LIBSSH2_SESSION * session,
return -1;
}
/* }}} */

View File

@@ -52,13 +52,12 @@ typedef struct _LIBSSH2_PUBLICKEY_CODE_LIST
int name_len;
} LIBSSH2_PUBLICKEY_CODE_LIST;
static const LIBSSH2_PUBLICKEY_CODE_LIST libssh2_publickey_response_codes[] = {
{LIBSSH2_PUBLICKEY_RESPONSE_STATUS, "status", sizeof("status") - 1}
,
{LIBSSH2_PUBLICKEY_RESPONSE_VERSION, "version", sizeof("version") - 1}
,
{LIBSSH2_PUBLICKEY_RESPONSE_PUBLICKEY, "publickey", sizeof("publickey") - 1}
,
static const LIBSSH2_PUBLICKEY_CODE_LIST publickey_response_codes[] =
{
{LIBSSH2_PUBLICKEY_RESPONSE_STATUS, "status", sizeof("status") - 1},
{LIBSSH2_PUBLICKEY_RESPONSE_VERSION, "version", sizeof("version") - 1},
{LIBSSH2_PUBLICKEY_RESPONSE_PUBLICKEY, "publickey",
sizeof("publickey") - 1} ,
{0, NULL, 0}
};
@@ -75,46 +74,39 @@ static const LIBSSH2_PUBLICKEY_CODE_LIST libssh2_publickey_response_codes[] = {
#define LIBSSH2_PUBLICKEY_STATUS_CODE_MAX 8
static const LIBSSH2_PUBLICKEY_CODE_LIST libssh2_publickey_status_codes[] = {
{LIBSSH2_PUBLICKEY_SUCCESS, "success", sizeof("success") - 1}
,
static const LIBSSH2_PUBLICKEY_CODE_LIST publickey_status_codes[] = {
{LIBSSH2_PUBLICKEY_SUCCESS, "success", sizeof("success") - 1} ,
{LIBSSH2_PUBLICKEY_ACCESS_DENIED, "access denied",
sizeof("access denied") - 1}
,
sizeof("access denied") - 1},
{LIBSSH2_PUBLICKEY_STORAGE_EXCEEDED, "storage exceeded",
sizeof("storage exceeded") - 1}
,
sizeof("storage exceeded") - 1} ,
{LIBSSH2_PUBLICKEY_VERSION_NOT_SUPPORTED, "version not supported",
sizeof("version not supported") - 1}
,
sizeof("version not supported") - 1} ,
{LIBSSH2_PUBLICKEY_KEY_NOT_FOUND, "key not found",
sizeof("key not found") - 1}
,
sizeof("key not found") - 1},
{LIBSSH2_PUBLICKEY_KEY_NOT_SUPPORTED, "key not supported",
sizeof("key not supported") - 1}
,
sizeof("key not supported") - 1},
{LIBSSH2_PUBLICKEY_KEY_ALREADY_PRESENT, "key already present",
sizeof("key already present") - 1}
,
sizeof("key already present") - 1},
{LIBSSH2_PUBLICKEY_GENERAL_FAILURE, "general failure",
sizeof("general failure") - 1}
,
sizeof("general failure") - 1},
{LIBSSH2_PUBLICKEY_REQUEST_NOT_SUPPORTED, "request not supported",
sizeof("request not supported") - 1}
,
sizeof("request not supported") - 1},
{0, NULL, 0}
};
/* {{{ libssh2_publickey_status_error
/*
* publickey_status_error
*
* Format an error message from a status code
*/
#define LIBSSH2_PUBLICKEY_STATUS_TEXT_START "Publickey Subsystem Error: \""
#define LIBSSH2_PUBLICKEY_STATUS_TEXT_MID "\" Server Reports: \""
#define LIBSSH2_PUBLICKEY_STATUS_TEXT_END "\""
static void
libssh2_publickey_status_error(const LIBSSH2_PUBLICKEY * pkey,
LIBSSH2_SESSION * session, int status,
const unsigned char *message, int message_len)
publickey_status_error(const LIBSSH2_PUBLICKEY * pkey,
LIBSSH2_SESSION * session, int status,
const unsigned char *message, int message_len)
{
const char *status_text;
int status_text_len;
@@ -130,8 +122,8 @@ libssh2_publickey_status_error(const LIBSSH2_PUBLICKEY * pkey,
status_text = "unknown";
status_text_len = sizeof("unknown") - 1;
} else {
status_text = libssh2_publickey_status_codes[status].name;
status_text_len = libssh2_publickey_status_codes[status].name_len;
status_text = publickey_status_codes[status].name;
status_text_len = publickey_status_codes[status].name_len;
}
m_len =
@@ -161,14 +153,14 @@ libssh2_publickey_status_error(const LIBSSH2_PUBLICKEY * pkey,
libssh2_error(session, LIBSSH2_ERROR_PUBLICKEY_PROTOCOL, m, 1);
}
/* }}} */
/* {{{ libssh2_publickey_packet_receive
/*
* publickey_packet_receive
*
* Read a packet from the subsystem
*/
static int
libssh2_publickey_packet_receive(LIBSSH2_PUBLICKEY * pkey,
unsigned char **data, unsigned long *data_len)
publickey_packet_receive(LIBSSH2_PUBLICKEY * pkey,
unsigned char **data, unsigned long *data_len)
{
LIBSSH2_CHANNEL *channel = pkey->channel;
LIBSSH2_SESSION *session = channel->session;
@@ -185,7 +177,7 @@ libssh2_publickey_packet_receive(LIBSSH2_PUBLICKEY * pkey,
return -1;
}
pkey->receive_packet_len = libssh2_ntohu32(buffer);
pkey->receive_packet_len = _libssh2_ntohu32(buffer);
pkey->receive_packet =
LIBSSH2_ALLOC(session, pkey->receive_packet_len);
if (!pkey->receive_packet) {
@@ -221,25 +213,23 @@ libssh2_publickey_packet_receive(LIBSSH2_PUBLICKEY * pkey,
return 0;
}
/* }}} */
/* {{{ libssh2_publickey_response_id
/* publickey_response_id
*
* Translate a string response name to a numeric code
* Data will be incremented by 4 + response_len on success only
*/
static int
libssh2_publickey_response_id(unsigned char **pdata, int data_len)
publickey_response_id(unsigned char **pdata, int data_len)
{
unsigned long response_len;
unsigned char *data = *pdata;
const LIBSSH2_PUBLICKEY_CODE_LIST *codes =
libssh2_publickey_response_codes;
const LIBSSH2_PUBLICKEY_CODE_LIST *codes = publickey_response_codes;
if (data_len < 4) {
/* Malformed response */
return -1;
}
response_len = libssh2_ntohu32(data);
response_len = _libssh2_ntohu32(data);
data += 4;
data_len -= 4;
if (data_len < (int)response_len) {
@@ -259,13 +249,12 @@ libssh2_publickey_response_id(unsigned char **pdata, int data_len)
return -1;
}
/* }}} */
/* {{{ libssh2_publickey_response_success
/* libssh2_publickey_response_success
*
* Generic helper routine to wait for success response and nothing else
*/
static int
libssh2_publickey_response_success(LIBSSH2_PUBLICKEY * pkey)
publickey_response_success(LIBSSH2_PUBLICKEY * pkey)
{
LIBSSH2_SESSION *session = pkey->channel->session;
unsigned char *data, *s;
@@ -274,7 +263,7 @@ libssh2_publickey_response_success(LIBSSH2_PUBLICKEY * pkey)
int rc;
while (1) {
rc = libssh2_publickey_packet_receive(pkey, &data, &data_len);
rc = publickey_packet_receive(pkey, &data, &data_len);
if (rc == PACKET_EAGAIN) {
return PACKET_EAGAIN;
} else if (rc) {
@@ -285,7 +274,7 @@ libssh2_publickey_response_success(LIBSSH2_PUBLICKEY * pkey)
}
s = data;
if ((response = libssh2_publickey_response_id(&s, data_len)) < 0) {
if ((response = publickey_response_id(&s, data_len)) < 0) {
libssh2_error(session, LIBSSH2_ERROR_PUBLICKEY_PROTOCOL,
"Invalid publickey subsystem response code", 0);
LIBSSH2_FREE(session, data);
@@ -299,13 +288,13 @@ libssh2_publickey_response_success(LIBSSH2_PUBLICKEY * pkey)
unsigned long status, descr_len, lang_len;
unsigned char *descr, *lang;
status = libssh2_ntohu32(s);
status = _libssh2_ntohu32(s);
s += 4;
descr_len = libssh2_ntohu32(s);
descr_len = _libssh2_ntohu32(s);
s += 4;
descr = s;
s += descr_len;
lang_len = libssh2_ntohu32(s);
lang_len = _libssh2_ntohu32(s);
s += 4;
lang = s;
s += lang_len;
@@ -322,8 +311,8 @@ libssh2_publickey_response_success(LIBSSH2_PUBLICKEY * pkey)
return 0;
}
libssh2_publickey_status_error(pkey, session, status, descr,
descr_len);
publickey_status_error(pkey, session, status, descr,
descr_len);
LIBSSH2_FREE(session, data);
return -1;
}
@@ -340,14 +329,13 @@ libssh2_publickey_response_success(LIBSSH2_PUBLICKEY * pkey)
return -1;
}
/* }}} */
/* *****************
* Publickey API *
***************** */
/* {{{ libssh2_publickey_init
/*
* libssh2_publickey_init
*
* Startup the publickey subsystem
*/
LIBSSH2_API LIBSSH2_PUBLICKEY *
@@ -436,13 +424,13 @@ libssh2_publickey_init(LIBSSH2_SESSION * session)
session->pkeyInit_pkey->version = 0;
s = buffer;
libssh2_htonu32(s, 4 + (sizeof("version") - 1) + 4);
_libssh2_htonu32(s, 4 + (sizeof("version") - 1) + 4);
s += 4;
libssh2_htonu32(s, sizeof("version") - 1);
_libssh2_htonu32(s, sizeof("version") - 1);
s += 4;
memcpy(s, "version", sizeof("version") - 1);
s += sizeof("version") - 1;
libssh2_htonu32(s, LIBSSH2_PUBLICKEY_VERSION);
_libssh2_htonu32(s, LIBSSH2_PUBLICKEY_VERSION);
s += 4;
_libssh2_debug(session, LIBSSH2_DBG_PUBLICKEY,
@@ -470,9 +458,9 @@ libssh2_publickey_init(LIBSSH2_SESSION * session)
if (session->pkeyInit_state == libssh2_NB_state_sent3) {
while (1) {
rc = libssh2_publickey_packet_receive(session->pkeyInit_pkey,
&session->pkeyInit_data,
&session->pkeyInit_data_len);
rc = publickey_packet_receive(session->pkeyInit_pkey,
&session->pkeyInit_data,
&session->pkeyInit_data_len);
if (rc == PACKET_EAGAIN) {
libssh2_error(session, LIBSSH2_ERROR_EAGAIN,
"Would block waiting for response from publickey subsystem",
@@ -487,9 +475,7 @@ libssh2_publickey_init(LIBSSH2_SESSION * session)
s = session->pkeyInit_data;
if ((response =
libssh2_publickey_response_id(&s,
session->pkeyInit_data_len)) <
0) {
publickey_response_id(&s, session->pkeyInit_data_len)) < 0) {
libssh2_error(session, LIBSSH2_ERROR_PUBLICKEY_PROTOCOL,
"Invalid publickey subsystem response code", 0);
goto err_exit;
@@ -502,13 +488,13 @@ libssh2_publickey_init(LIBSSH2_SESSION * session)
unsigned long status, descr_len, lang_len;
unsigned char *descr, *lang;
status = libssh2_ntohu32(s);
status = _libssh2_ntohu32(s);
s += 4;
descr_len = libssh2_ntohu32(s);
descr_len = _libssh2_ntohu32(s);
s += 4;
descr = s;
s += descr_len;
lang_len = libssh2_ntohu32(s);
lang_len = _libssh2_ntohu32(s);
s += 4;
lang = s;
s += lang_len;
@@ -522,14 +508,14 @@ libssh2_publickey_init(LIBSSH2_SESSION * session)
goto err_exit;
}
libssh2_publickey_status_error(NULL, session, status,
descr, descr_len);
publickey_status_error(NULL, session, status,
descr, descr_len);
goto err_exit;
}
case LIBSSH2_PUBLICKEY_RESPONSE_VERSION:
/* What we want */
session->pkeyInit_pkey->version = libssh2_ntohu32(s);
session->pkeyInit_pkey->version = _libssh2_ntohu32(s);
if (session->pkeyInit_pkey->version >
LIBSSH2_PUBLICKEY_VERSION) {
_libssh2_debug(session, LIBSSH2_DBG_PUBLICKEY,
@@ -580,9 +566,9 @@ libssh2_publickey_init(LIBSSH2_SESSION * session)
return NULL;
}
/* }}} */
/* {{{ libssh2_publickey_add_ex
/*
* libssh2_publickey_add_ex
*
* Add a new public key entry
*/
LIBSSH2_API int
@@ -635,48 +621,48 @@ libssh2_publickey_add_ex(LIBSSH2_PUBLICKEY * pkey, const unsigned char *name,
}
pkey->add_s = pkey->add_packet;
libssh2_htonu32(pkey->add_s, packet_len - 4);
_libssh2_htonu32(pkey->add_s, packet_len - 4);
pkey->add_s += 4;
libssh2_htonu32(pkey->add_s, sizeof("add") - 1);
_libssh2_htonu32(pkey->add_s, sizeof("add") - 1);
pkey->add_s += 4;
memcpy(pkey->add_s, "add", sizeof("add") - 1);
pkey->add_s += sizeof("add") - 1;
if (pkey->version == 1) {
libssh2_htonu32(pkey->add_s, comment_len);
_libssh2_htonu32(pkey->add_s, comment_len);
pkey->add_s += 4;
if (comment) {
memcpy(pkey->add_s, comment, comment_len);
pkey->add_s += comment_len;
}
libssh2_htonu32(pkey->add_s, name_len);
_libssh2_htonu32(pkey->add_s, name_len);
pkey->add_s += 4;
memcpy(pkey->add_s, name, name_len);
pkey->add_s += name_len;
libssh2_htonu32(pkey->add_s, blob_len);
_libssh2_htonu32(pkey->add_s, blob_len);
pkey->add_s += 4;
memcpy(pkey->add_s, blob, blob_len);
pkey->add_s += blob_len;
} else {
/* Version == 2 */
libssh2_htonu32(pkey->add_s, name_len);
_libssh2_htonu32(pkey->add_s, name_len);
pkey->add_s += 4;
memcpy(pkey->add_s, name, name_len);
pkey->add_s += name_len;
libssh2_htonu32(pkey->add_s, blob_len);
_libssh2_htonu32(pkey->add_s, blob_len);
pkey->add_s += 4;
memcpy(pkey->add_s, blob, blob_len);
pkey->add_s += blob_len;
*(pkey->add_s++) = overwrite ? 0x01 : 0;
libssh2_htonu32(pkey->add_s, num_attrs);
_libssh2_htonu32(pkey->add_s, num_attrs);
pkey->add_s += 4;
for(i = 0; i < num_attrs; i++) {
libssh2_htonu32(pkey->add_s, attrs[i].name_len);
_libssh2_htonu32(pkey->add_s, attrs[i].name_len);
pkey->add_s += 4;
memcpy(pkey->add_s, attrs[i].name, attrs[i].name_len);
pkey->add_s += attrs[i].name_len;
libssh2_htonu32(pkey->add_s, attrs[i].value_len);
_libssh2_htonu32(pkey->add_s, attrs[i].value_len);
pkey->add_s += 4;
memcpy(pkey->add_s, attrs[i].value, attrs[i].value_len);
pkey->add_s += attrs[i].value_len;
@@ -709,7 +695,7 @@ libssh2_publickey_add_ex(LIBSSH2_PUBLICKEY * pkey, const unsigned char *name,
pkey->add_state = libssh2_NB_state_sent;
}
rc = libssh2_publickey_response_success(pkey);
rc = publickey_response_success(pkey);
if (rc == PACKET_EAGAIN) {
return PACKET_EAGAIN;
}
@@ -719,9 +705,7 @@ libssh2_publickey_add_ex(LIBSSH2_PUBLICKEY * pkey, const unsigned char *name,
return rc;
}
/* }}} */
/* {{{ libssh2_publickey_remove_ex
/* libssh2_publickey_remove_ex
* Remove an existing publickey so that authentication can no longer be performed using it
*/
LIBSSH2_API int
@@ -747,17 +731,17 @@ libssh2_publickey_remove_ex(LIBSSH2_PUBLICKEY * pkey,
}
pkey->remove_s = pkey->remove_packet;
libssh2_htonu32(pkey->remove_s, packet_len - 4);
_libssh2_htonu32(pkey->remove_s, packet_len - 4);
pkey->remove_s += 4;
libssh2_htonu32(pkey->remove_s, sizeof("remove") - 1);
_libssh2_htonu32(pkey->remove_s, sizeof("remove") - 1);
pkey->remove_s += 4;
memcpy(pkey->remove_s, "remove", sizeof("remove") - 1);
pkey->remove_s += sizeof("remove") - 1;
libssh2_htonu32(pkey->remove_s, name_len);
_libssh2_htonu32(pkey->remove_s, name_len);
pkey->remove_s += 4;
memcpy(pkey->remove_s, name, name_len);
pkey->remove_s += name_len;
libssh2_htonu32(pkey->remove_s, blob_len);
_libssh2_htonu32(pkey->remove_s, blob_len);
pkey->remove_s += 4;
memcpy(pkey->remove_s, blob, blob_len);
pkey->remove_s += blob_len;
@@ -788,7 +772,7 @@ libssh2_publickey_remove_ex(LIBSSH2_PUBLICKEY * pkey,
pkey->remove_state = libssh2_NB_state_sent;
}
rc = libssh2_publickey_response_success(pkey);
rc = publickey_response_success(pkey);
if (rc == PACKET_EAGAIN) {
return PACKET_EAGAIN;
}
@@ -798,9 +782,7 @@ libssh2_publickey_remove_ex(LIBSSH2_PUBLICKEY * pkey,
return rc;
}
/* }}} */
/* {{{ libssh2_publickey_list_fetch
/* libssh2_publickey_list_fetch
* Fetch a list of supported public key from a server
*/
LIBSSH2_API int
@@ -819,9 +801,9 @@ libssh2_publickey_list_fetch(LIBSSH2_PUBLICKEY * pkey, unsigned long *num_keys,
pkey->listFetch_data = NULL;
pkey->listFetch_s = pkey->listFetch_buffer;
libssh2_htonu32(pkey->listFetch_s, buffer_len - 4);
_libssh2_htonu32(pkey->listFetch_s, buffer_len - 4);
pkey->listFetch_s += 4;
libssh2_htonu32(pkey->listFetch_s, sizeof("list") - 1);
_libssh2_htonu32(pkey->listFetch_s, sizeof("list") - 1);
pkey->listFetch_s += 4;
memcpy(pkey->listFetch_s, "list", sizeof("list") - 1);
pkey->listFetch_s += sizeof("list") - 1;
@@ -850,8 +832,8 @@ libssh2_publickey_list_fetch(LIBSSH2_PUBLICKEY * pkey, unsigned long *num_keys,
}
while (1) {
rc = libssh2_publickey_packet_receive(pkey, &pkey->listFetch_data,
&pkey->listFetch_data_len);
rc = publickey_packet_receive(pkey, &pkey->listFetch_data,
&pkey->listFetch_data_len);
if (rc == PACKET_EAGAIN) {
return PACKET_EAGAIN;
} else if (rc) {
@@ -863,8 +845,8 @@ libssh2_publickey_list_fetch(LIBSSH2_PUBLICKEY * pkey, unsigned long *num_keys,
pkey->listFetch_s = pkey->listFetch_data;
if ((response =
libssh2_publickey_response_id(&pkey->listFetch_s,
pkey->listFetch_data_len)) < 0) {
publickey_response_id(&pkey->listFetch_s,
pkey->listFetch_data_len)) < 0) {
libssh2_error(session, LIBSSH2_ERROR_PUBLICKEY_PROTOCOL,
"Invalid publickey subsystem response code", 0);
goto err_exit;
@@ -877,13 +859,13 @@ libssh2_publickey_list_fetch(LIBSSH2_PUBLICKEY * pkey, unsigned long *num_keys,
unsigned long status, descr_len, lang_len;
unsigned char *descr, *lang;
status = libssh2_ntohu32(pkey->listFetch_s);
status = _libssh2_ntohu32(pkey->listFetch_s);
pkey->listFetch_s += 4;
descr_len = libssh2_ntohu32(pkey->listFetch_s);
descr_len = _libssh2_ntohu32(pkey->listFetch_s);
pkey->listFetch_s += 4;
descr = pkey->listFetch_s;
pkey->listFetch_s += descr_len;
lang_len = libssh2_ntohu32(pkey->listFetch_s);
lang_len = _libssh2_ntohu32(pkey->listFetch_s);
pkey->listFetch_s += 4;
lang = pkey->listFetch_s;
pkey->listFetch_s += lang_len;
@@ -904,8 +886,8 @@ libssh2_publickey_list_fetch(LIBSSH2_PUBLICKEY * pkey, unsigned long *num_keys,
return 0;
}
libssh2_publickey_status_error(pkey, session, status, descr,
descr_len);
publickey_status_error(pkey, session, status, descr,
descr_len);
goto err_exit;
}
case LIBSSH2_PUBLICKEY_RESPONSE_PUBLICKEY:
@@ -929,7 +911,7 @@ libssh2_publickey_list_fetch(LIBSSH2_PUBLICKEY * pkey, unsigned long *num_keys,
if (pkey->version == 1) {
unsigned long comment_len;
comment_len = libssh2_ntohu32(pkey->listFetch_s);
comment_len = _libssh2_ntohu32(pkey->listFetch_s);
pkey->listFetch_s += 4;
if (comment_len) {
list[keys].num_attrs = 1;
@@ -953,25 +935,25 @@ libssh2_publickey_list_fetch(LIBSSH2_PUBLICKEY * pkey, unsigned long *num_keys,
list[keys].num_attrs = 0;
list[keys].attrs = NULL;
}
list[keys].name_len = libssh2_ntohu32(pkey->listFetch_s);
list[keys].name_len = _libssh2_ntohu32(pkey->listFetch_s);
pkey->listFetch_s += 4;
list[keys].name = pkey->listFetch_s;
pkey->listFetch_s += list[keys].name_len;
list[keys].blob_len = libssh2_ntohu32(pkey->listFetch_s);
list[keys].blob_len = _libssh2_ntohu32(pkey->listFetch_s);
pkey->listFetch_s += 4;
list[keys].blob = pkey->listFetch_s;
pkey->listFetch_s += list[keys].blob_len;
} else {
/* Version == 2 */
list[keys].name_len = libssh2_ntohu32(pkey->listFetch_s);
list[keys].name_len = _libssh2_ntohu32(pkey->listFetch_s);
pkey->listFetch_s += 4;
list[keys].name = pkey->listFetch_s;
pkey->listFetch_s += list[keys].name_len;
list[keys].blob_len = libssh2_ntohu32(pkey->listFetch_s);
list[keys].blob_len = _libssh2_ntohu32(pkey->listFetch_s);
pkey->listFetch_s += 4;
list[keys].blob = pkey->listFetch_s;
pkey->listFetch_s += list[keys].blob_len;
list[keys].num_attrs = libssh2_ntohu32(pkey->listFetch_s);
list[keys].num_attrs = _libssh2_ntohu32(pkey->listFetch_s);
pkey->listFetch_s += 4;
if (list[keys].num_attrs) {
list[keys].attrs =
@@ -986,12 +968,12 @@ libssh2_publickey_list_fetch(LIBSSH2_PUBLICKEY * pkey, unsigned long *num_keys,
}
for(i = 0; i < list[keys].num_attrs; i++) {
list[keys].attrs[i].name_len =
libssh2_ntohu32(pkey->listFetch_s);
_libssh2_ntohu32(pkey->listFetch_s);
pkey->listFetch_s += 4;
list[keys].attrs[i].name = (char *) pkey->listFetch_s;
pkey->listFetch_s += list[keys].attrs[i].name_len;
list[keys].attrs[i].value_len =
libssh2_ntohu32(pkey->listFetch_s);
_libssh2_ntohu32(pkey->listFetch_s);
pkey->listFetch_s += 4;
list[keys].attrs[i].value = (char *) pkey->listFetch_s;
pkey->listFetch_s += list[keys].attrs[i].value_len;
@@ -1030,9 +1012,7 @@ libssh2_publickey_list_fetch(LIBSSH2_PUBLICKEY * pkey, unsigned long *num_keys,
return -1;
}
/* }}} */
/* {{{ libssh2_publickey_list_free
/* libssh2_publickey_list_free
* Free a previously fetched list of public keys
*/
LIBSSH2_API void
@@ -1053,9 +1033,7 @@ libssh2_publickey_list_free(LIBSSH2_PUBLICKEY * pkey,
LIBSSH2_FREE(session, pkey_list);
}
/* }}} */
/* {{{ libssh2_publickey_shutdown
/* libssh2_publickey_shutdown
* Shutdown the publickey subsystem
*/
LIBSSH2_API int
@@ -1090,5 +1068,3 @@ libssh2_publickey_shutdown(LIBSSH2_PUBLICKEY * pkey)
LIBSSH2_FREE(session, pkey);
return 0;
}
/* }}} */

388
src/scp.c
View File

@@ -39,17 +39,234 @@
#include <errno.h>
#include <stdlib.h>
/* {{{ libssh2_scp_recv
/* Max. length of a quoted string after libssh2_shell_quotearg() processing */
#define libssh2_shell_quotedsize(s) (3 * strlen(s) + 2)
/*
This function quotes a string in a way suitable to be used with a
shell, e.g. the file name
one two
becomes
'one two'
The resulting output string is crafted in a way that makes it usable
with the two most common shell types: Bourne Shell derived shells
(sh, ksh, ksh93, bash, zsh) and C-Shell derivates (csh, tcsh).
The following special cases are handled:
o If the string contains an apostrophy itself, the apostrophy
character is written in quotation marks, e.g. "'".
The shell cannot handle the syntax 'doesn\'t', so we close the
current argument word, add the apostrophe in quotation marks "",
and open a new argument word instead (_ indicate the input
string characters):
_____ _ _
'doesn' "'" 't'
Sequences of apostrophes are combined in one pair of quotation marks:
a'''b
becomes
_ ___ _
'a'"'''"'b'
o If the string contains an exclamation mark (!), the C-Shell
interprets it as an event number. Using \! (not within quotation
marks or single quotation marks) is a mechanism understood by
both Bourne Shell and C-Shell.
If a quotation was already started, the argument word is closed
first:
a!b
become
_ _ _
'a'\!'b'
The result buffer must be large enough for the expanded result. A
bad case regarding expansion is alternating characters and
apostrophes:
a'b'c'd' (length 8) gets converted to
'a'"'"'b'"'"'c'"'"'d'"'" (length 24)
This is the worst case.
Maximum length of the result:
1 + 6 * (length(input) + 1) / 2) + 1
=> 3 * length(input) + 2
Explanation:
o leading apostrophe
o one character / apostrophe pair (two characters) can get
represented as 6 characters: a' -> a'"'"'
o String terminator (+1)
A result buffer three times the size of the input buffer + 2
characters should be safe.
References:
o csh-compatible quotation (special handling for '!' etc.), see
http://www.grymoire.com/Unix/Csh.html#toc-uh-10
Return value:
Length of the resulting string (not counting the terminating '\0'),
or 0 in case of errors, e.g. result buffer too small
Note: this function could possible be used elsewhere within libssh2, but
until then it is kept static and in this source file.
*/
static unsigned
libssh2_shell_quotearg(const char *path, unsigned char *buf,
unsigned bufsize)
{
const char *src;
unsigned char *dst, *endp;
/*
* Processing States:
* UQSTRING: unquoted string: ... -- used for quoting exclamation
* marks. This is the initial state
* SQSTRING: single-qouted-string: '... -- any character may follow
* QSTRING: quoted string: "... -- only apostrophes may follow
*/
enum { UQSTRING, SQSTRING, QSTRING } state = UQSTRING;
endp = &buf[bufsize];
src = path;
dst = buf;
while (*src && dst < endp - 1) {
switch (*src) {
/*
* Special handling for apostrophe.
* An apostrophe is always written in quotation marks, e.g.
* ' -> "'".
*/
case '\'':
switch (state) {
case UQSTRING: /* Unquoted string */
if (dst+1 >= endp)
return 0;
*dst++ = '"';
break;
case QSTRING: /* Continue quoted string */
break;
case SQSTRING: /* Close single quoted string */
if (dst+2 >= endp)
return 0;
*dst++ = '\'';
*dst++ = '"';
break;
default:
break;
}
state = QSTRING;
break;
/*
* Special handling for exclamation marks. CSH interprets
* exclamation marks even when quoted with apostrophes. We convert
* it to the plain string \!, because both Bourne Shell and CSH
* interpret that as a verbatim exclamation mark.
*/
case '!':
switch (state) {
case UQSTRING:
if (dst+1 >= endp)
return 0;
*dst++ = '\\';
break;
case QSTRING:
if (dst+2 >= endp)
return 0;
*dst++ = '"'; /* Closing quotation mark */
*dst++ = '\\';
break;
case SQSTRING: /* Close single quoted string */
if (dst+2 >= endp)
return 0;
*dst++ = '\'';
*dst++ = '\\';
break;
default:
break;
}
state = UQSTRING;
break;
/*
* Ordinary character: prefer single-quoted string
*/
default:
switch (state) {
case UQSTRING:
if (dst+1 >= endp)
return 0;
*dst++ = '\'';
break;
case QSTRING:
if (dst+2 >= endp)
return 0;
*dst++ = '"'; /* Closing quotation mark */
*dst++ = '\'';
break;
case SQSTRING: /* Continue single quoted string */
break;
default:
break;
}
state = SQSTRING; /* Start single-quoted string */
break;
}
if (dst+1 >= endp)
return 0;
*dst++ = *src++;
}
switch (state) {
case UQSTRING:
break;
case QSTRING: /* Close quoted string */
if (dst+1 >= endp)
return 0;
*dst++ = '"';
break;
case SQSTRING: /* Close single quoted string */
if (dst+1 >= endp)
return 0;
*dst++ = '\'';
break;
default:
break;
}
if (dst+1 >= endp)
return 0;
*dst = '\0';
/* The result cannot be larger than 3 * strlen(path) + 2 */
/* assert((dst - buf) <= (3 * (src - path) + 2)); */
return dst - buf;
}
/*
* libssh2_scp_recv
*
* Open a channel and request a remote file via SCP
*
* NOTE: Will block in a busy loop on error. This has to be done,
* otherwise the blocking error code would erase the true
* cause of the error.
*/
LIBSSH2_API LIBSSH2_CHANNEL *
libssh2_scp_recv(LIBSSH2_SESSION * session, const char *path, struct stat * sb)
{
int path_len = strlen(path);
int cmd_len;
int rc;
if (session->scpRecv_state == libssh2_NB_state_idle) {
@@ -58,31 +275,28 @@ libssh2_scp_recv(LIBSSH2_SESSION * session, const char *path, struct stat * sb)
session->scpRecv_mtime = 0;
session->scpRecv_atime = 0;
session->scpRecv_command_len = path_len + sizeof("scp -f ");
if (sb) {
session->scpRecv_command_len++;
}
session->scpRecv_command_len =
libssh2_shell_quotedsize(path) + sizeof("scp -f ") + (sb?1:0);
session->scpRecv_command =
LIBSSH2_ALLOC(session, session->scpRecv_command_len);
if (!session->scpRecv_command) {
libssh2_error(session, LIBSSH2_ERROR_ALLOC,
"Unable to allocate a command buffer for SCP session",
0);
return NULL;
}
if (sb) {
memcpy(session->scpRecv_command, "scp -pf ",
sizeof("scp -pf ") - 1);
memcpy(session->scpRecv_command + sizeof("scp -pf ") - 1, path,
path_len);
} else {
memcpy(session->scpRecv_command, "scp -f ", sizeof("scp -f ") - 1);
memcpy(session->scpRecv_command + sizeof("scp -f ") - 1, path,
path_len);
}
session->scpRecv_command[session->scpRecv_command_len - 1] = '\0';
/* sprintf() is fine here since we allocated a large enough buffer */
sprintf((char *)session->scpRecv_command, "scp -%sf ", sb?"p":"");
cmd_len = strlen((char *)session->scpRecv_command);
(void) libssh2_shell_quotearg(path,
&session->scpRecv_command[cmd_len],
session->scpRecv_command_len - cmd_len);
_libssh2_debug(session, LIBSSH2_DBG_SCP,
"Opening channel for SCP receive");
@@ -92,28 +306,25 @@ libssh2_scp_recv(LIBSSH2_SESSION * session, const char *path, struct stat * sb)
if (session->scpRecv_state == libssh2_NB_state_created) {
/* Allocate a channel */
do {
session->scpRecv_channel =
libssh2_channel_open_ex(session, "session",
sizeof("session") - 1,
LIBSSH2_CHANNEL_WINDOW_DEFAULT,
LIBSSH2_CHANNEL_PACKET_DEFAULT, NULL,
0);
if (!session->scpRecv_channel) {
if (libssh2_session_last_errno(session) !=
LIBSSH2_ERROR_EAGAIN) {
LIBSSH2_FREE(session, session->scpRecv_command);
session->scpRecv_command = NULL;
session->scpRecv_state = libssh2_NB_state_idle;
return NULL;
} else if (libssh2_session_last_errno(session) ==
LIBSSH2_ERROR_EAGAIN) {
libssh2_error(session, LIBSSH2_ERROR_EAGAIN,
"Would block starting up channel", 0);
return NULL;
}
session->scpRecv_channel =
libssh2_channel_open_ex(session, "session",
sizeof("session") - 1,
LIBSSH2_CHANNEL_WINDOW_DEFAULT,
LIBSSH2_CHANNEL_PACKET_DEFAULT, NULL,
0);
if (!session->scpRecv_channel) {
if (libssh2_session_last_errno(session) !=
LIBSSH2_ERROR_EAGAIN) {
LIBSSH2_FREE(session, session->scpRecv_command);
session->scpRecv_command = NULL;
session->scpRecv_state = libssh2_NB_state_idle;
}
} while (!session->scpRecv_channel);
else {
libssh2_error(session, LIBSSH2_ERROR_EAGAIN,
"Would block starting up channel", 0);
}
return NULL;
}
session->scpRecv_state = libssh2_NB_state_sent;
}
@@ -162,9 +373,8 @@ libssh2_scp_recv(LIBSSH2_SESSION * session, const char *path, struct stat * sb)
if ((session->scpRecv_state == libssh2_NB_state_sent2)
|| (session->scpRecv_state == libssh2_NB_state_sent3)) {
while (sb
&& (session->scpRecv_response_len <
LIBSSH2_SCP_RESPONSE_BUFLEN)) {
while (sb && (session->scpRecv_response_len <
LIBSSH2_SCP_RESPONSE_BUFLEN)) {
unsigned char *s, *p;
if (session->scpRecv_state == libssh2_NB_state_sent2) {
@@ -194,8 +404,8 @@ libssh2_scp_recv(LIBSSH2_SESSION * session, const char *path, struct stat * sb)
0);
session->scpRecv_err_len =
libssh2_channel_packet_data_len(session->
scpRecv_channel, 0);
_libssh2_channel_packet_data_len(session->
scpRecv_channel, 0);
session->scpRecv_err_msg =
LIBSSH2_ALLOC(session, session->scpRecv_err_len + 1);
if (!session->scpRecv_err_msg) {
@@ -210,8 +420,9 @@ libssh2_scp_recv(LIBSSH2_SESSION * session, const char *path, struct stat * sb)
session->scpRecv_err_len);
if (rc <= 0) {
/*
* Since we have alread started reading this packet, it is
* already in the systems so it can't return PACKET_EAGAIN
* Since we have alread started reading this packet,
* it is already in the systems so it can't return
* PACKET_EAGAIN
*/
LIBSSH2_FREE(session, session->scpRecv_err_msg);
session->scpRecv_err_msg = NULL;
@@ -260,11 +471,13 @@ libssh2_scp_recv(LIBSSH2_SESSION * session, const char *path, struct stat * sb)
0);
goto scp_recv_error;
}
/* Way too short to be an SCP response, or not done yet, short circuit */
/* Way too short to be an SCP response, or not done yet,
short circuit */
continue;
}
/* We're guaranteed not to go under response_len == 0 by the logic above */
/* We're guaranteed not to go under response_len == 0 by the
logic above */
while ((session->
scpRecv_response[session->scpRecv_response_len - 1] ==
'\r')
@@ -357,7 +570,8 @@ libssh2_scp_recv(LIBSSH2_SESSION * session, const char *path, struct stat * sb)
"mtime = %ld, atime = %ld",
session->scpRecv_mtime, session->scpRecv_atime);
/* We *should* check that atime.usec is valid, but why let that stop use? */
/* We *should* check that atime.usec is valid, but why let
that stop use? */
break;
}
}
@@ -429,11 +643,13 @@ libssh2_scp_recv(LIBSSH2_SESSION * session, const char *path, struct stat * sb)
0);
goto scp_recv_error;
}
/* Way too short to be an SCP response, or not done yet, short circuit */
/* Way too short to be an SCP response, or not done yet,
short circuit */
continue;
}
/* We're guaranteed not to go under response_len == 0 by the logic above */
/* We're guaranteed not to go under response_len == 0 by the
logic above */
while ((session->
scpRecv_response[session->scpRecv_response_len - 1] ==
'\r')
@@ -516,7 +732,8 @@ libssh2_scp_recv(LIBSSH2_SESSION * session, const char *path, struct stat * sb)
"mode = 0%lo size = %ld", session->scpRecv_mode,
session->scpRecv_size);
/* We *should* check that basename is valid, but why let that stop us? */
/* We *should* check that basename is valid, but why let that
stop us? */
break;
}
}
@@ -543,29 +760,24 @@ libssh2_scp_recv(LIBSSH2_SESSION * session, const char *path, struct stat * sb)
return NULL;
}
/* }}} */
/* {{{ libssh2_scp_send_ex
/*
* libssh2_scp_send_ex
*
* Send a file using SCP
*
* NOTE: Will block in a busy loop on error. This has to be done,
* otherwise the blocking error code would erase the true
* cause of the error.
*/
LIBSSH2_API LIBSSH2_CHANNEL *
libssh2_scp_send_ex(LIBSSH2_SESSION * session, const char *path, int mode,
size_t size, long mtime, long atime)
{
int path_len = strlen(path);
int cmd_len;
unsigned const char *base;
int rc;
if (session->scpSend_state == libssh2_NB_state_idle) {
session->scpSend_command_len = path_len + sizeof("scp -t ");
if (mtime || atime) {
session->scpSend_command_len++;
}
session->scpSend_command_len =
libssh2_shell_quotedsize(path) + sizeof("scp -t ") +
((mtime || atime)?1:0);
session->scpSend_command =
LIBSSH2_ALLOC(session, session->scpSend_command_len);
@@ -576,16 +788,15 @@ libssh2_scp_send_ex(LIBSSH2_SESSION * session, const char *path, int mode,
return NULL;
}
if (mtime || atime) {
memcpy(session->scpSend_command, "scp -pt ",
sizeof("scp -pt ") - 1);
memcpy(session->scpSend_command + sizeof("scp -pt ") - 1, path,
path_len);
} else {
memcpy(session->scpSend_command, "scp -t ", sizeof("scp -t ") - 1);
memcpy(session->scpSend_command + sizeof("scp -t ") - 1, path,
path_len);
}
sprintf((char *)session->scpSend_command, "scp -%st ",
(mtime || atime)?"p":"");
cmd_len = strlen((char *)session->scpSend_command);
(void)libssh2_shell_quotearg(path,
&session->scpSend_command[cmd_len],
session->scpSend_command_len - cmd_len);
session->scpSend_command[session->scpSend_command_len - 1] = '\0';
_libssh2_debug(session, LIBSSH2_DBG_SCP,
@@ -602,17 +813,17 @@ libssh2_scp_send_ex(LIBSSH2_SESSION * session, const char *path, int mode,
LIBSSH2_CHANNEL_PACKET_DEFAULT, NULL, 0);
if (!session->scpSend_channel) {
if (libssh2_session_last_errno(session) != LIBSSH2_ERROR_EAGAIN) {
/* previous call set libssh2_session_last_error(), pass it through */
/* previous call set libssh2_session_last_error(), pass it
through */
LIBSSH2_FREE(session, session->scpSend_command);
session->scpSend_command = NULL;
session->scpSend_state = libssh2_NB_state_idle;
return NULL;
} else if (libssh2_session_last_errno(session) ==
LIBSSH2_ERROR_EAGAIN) {
}
else {
libssh2_error(session, LIBSSH2_ERROR_EAGAIN,
"Would block starting up channel", 0);
return NULL;
}
return NULL;
}
session->scpSend_state = libssh2_NB_state_sent;
@@ -628,8 +839,10 @@ libssh2_scp_send_ex(LIBSSH2_SESSION * session, const char *path, int mode,
libssh2_error(session, LIBSSH2_ERROR_EAGAIN,
"Would block requesting SCP startup", 0);
return NULL;
} else if (rc) {
/* previous call set libssh2_session_last_error(), pass it through */
}
else if (rc) {
/* previous call set libssh2_session_last_error(), pass it
through */
LIBSSH2_FREE(session, session->scpSend_command);
session->scpSend_command = NULL;
libssh2_error(session, LIBSSH2_ERROR_SCP_PROTOCOL,
@@ -679,7 +892,7 @@ libssh2_scp_send_ex(LIBSSH2_SESSION * session, const char *path, int mode,
libssh2_error(session, LIBSSH2_ERROR_EAGAIN,
"Would block sending time data for SCP file", 0);
return NULL;
} else if (rc != session->scpSend_response_len) {
} else if (rc != (int)session->scpSend_response_len) {
libssh2_error(session, LIBSSH2_ERROR_SOCKET_SEND,
"Unable to send time data for SCP file", 0);
goto scp_send_error;
@@ -738,7 +951,7 @@ libssh2_scp_send_ex(LIBSSH2_SESSION * session, const char *path, int mode,
libssh2_error(session, LIBSSH2_ERROR_EAGAIN,
"Would block send core file data for SCP file", 0);
return NULL;
} else if (rc != session->scpSend_response_len) {
} else if (rc != (int)session->scpSend_response_len) {
libssh2_error(session, LIBSSH2_ERROR_SOCKET_SEND,
"Unable to send core file data for SCP file", 0);
goto scp_send_error;
@@ -768,7 +981,7 @@ libssh2_scp_send_ex(LIBSSH2_SESSION * session, const char *path, int mode,
"Invalid ACK response from remote", 0);
session->scpSend_err_len =
libssh2_channel_packet_data_len(session->scpSend_channel, 0);
_libssh2_channel_packet_data_len(session->scpSend_channel, 0);
session->scpSend_err_msg =
LIBSSH2_ALLOC(session, session->scpSend_err_len + 1);
if (!session->scpSend_err_msg) {
@@ -808,4 +1021,3 @@ libssh2_scp_send_ex(LIBSSH2_SESSION * session, const char *path, int mode,
return NULL;
}
/* }}} */

View File

@@ -1,4 +1,5 @@
/* Copyright (c) 2004-2007, Sara Golemon <sarag@libssh2.org>
/* Copyright (c) 2004-2007 Sara Golemon <sarag@libssh2.org>
* Copyright (c) 2009 by Daniel Stenberg
* All rights reserved.
*
* Redistribution and use in source and binary forms,
@@ -50,7 +51,9 @@
#include <alloca.h>
#endif
/* {{{ libssh2_default_alloc
#include "transport.h"
/* libssh2_default_alloc
*/
static
LIBSSH2_ALLOC_FUNC(libssh2_default_alloc)
@@ -59,9 +62,7 @@ LIBSSH2_ALLOC_FUNC(libssh2_default_alloc)
return malloc(count);
}
/* }}} */
/* {{{ libssh2_default_free
/* libssh2_default_free
*/
static
LIBSSH2_FREE_FUNC(libssh2_default_free)
@@ -70,9 +71,7 @@ LIBSSH2_FREE_FUNC(libssh2_default_free)
free(ptr);
}
/* }}} */
/* {{{ libssh2_default_realloc
/* libssh2_default_realloc
*/
static
LIBSSH2_REALLOC_FUNC(libssh2_default_realloc)
@@ -81,15 +80,15 @@ LIBSSH2_REALLOC_FUNC(libssh2_default_realloc)
return realloc(ptr, count);
}
/* }}} */
/* {{{ libssh2_banner_receive
/*
* banner_receive
*
* Wait for a hello from the remote host
* Allocate a buffer and store the banner in session->remote.banner
* Returns: 0 on success, PACKET_EAGAIN if read would block, 1 on failure
*/
static int
libssh2_banner_receive(LIBSSH2_SESSION * session)
banner_receive(LIBSSH2_SESSION * session)
{
int ret;
int banner_len;
@@ -107,31 +106,10 @@ libssh2_banner_receive(LIBSSH2_SESSION * session)
|| (session->banner_TxRx_banner[banner_len - 1] != '\n'))) {
char c = '\0';
ret =
recv(session->socket_fd, &c, 1,
LIBSSH2_SOCKET_RECV_FLAGS(session));
ret = _libssh2_recv(session->socket_fd, &c, 1,
LIBSSH2_SOCKET_RECV_FLAGS(session));
if (ret < 0) {
#ifdef WIN32
switch (WSAGetLastError()) {
case WSAEWOULDBLOCK:
errno = EAGAIN;
break;
case WSAENOTSOCK:
errno = EBADF;
break;
case WSAENOTCONN:
case WSAECONNABORTED:
errno = WSAENOTCONN;
break;
case WSAEINTR:
errno = EINTR;
break;
}
#endif /* WIN32 */
if (errno == EAGAIN) {
session->socket_block_directions =
LIBSSH2_SESSION_BLOCK_INBOUND;
@@ -186,9 +164,9 @@ libssh2_banner_receive(LIBSSH2_SESSION * session)
return 0;
}
/* }}} */
/* {{{ libssh2_banner_send
/*
* banner_send
*
* Send the default banner, or the one set via libssh2_setopt_string
*
* Returns PACKET_EAGAIN if it would block - and if it does so, you should
@@ -197,7 +175,7 @@ libssh2_banner_receive(LIBSSH2_SESSION * session)
* (same data pointer and same data_len) until zero or failure is returned.
*/
static int
libssh2_banner_send(LIBSSH2_SESSION * session)
banner_send(LIBSSH2_SESSION * session)
{
char *banner = (char *) LIBSSH2_SSH_DEFAULT_BANNER_WITH_CRLF;
int banner_len = sizeof(LIBSSH2_SSH_DEFAULT_BANNER_WITH_CRLF) - 1;
@@ -229,10 +207,10 @@ libssh2_banner_send(LIBSSH2_SESSION * session)
session->banner_TxRx_state = libssh2_NB_state_created;
}
ret =
send(session->socket_fd, banner + session->banner_TxRx_total_send,
banner_len - session->banner_TxRx_total_send,
LIBSSH2_SOCKET_SEND_FLAGS(session));
ret = _libssh2_send(session->socket_fd,
banner + session->banner_TxRx_total_send,
banner_len - session->banner_TxRx_total_send,
LIBSSH2_SOCKET_SEND_FLAGS(session));
if (ret != (banner_len - session->banner_TxRx_total_send)) {
if ((ret > 0) || ((ret == -1) && (errno == EAGAIN))) {
@@ -254,16 +232,14 @@ libssh2_banner_send(LIBSSH2_SESSION * session)
return 0;
}
/* }}} */
/*
* _libssh2_nonblock() sets the given socket to either blocking or
* session_nonblock() sets the given socket to either blocking or
* non-blocking mode based on the 'nonblock' boolean argument. This function
* is copied from the libcurl sources with permission.
*/
static int
_libssh2_nonblock(int sockfd, /* operate on this */
int nonblock /* TRUE or FALSE */ )
session_nonblock(int sockfd, /* operate on this */
int nonblock /* TRUE or FALSE */ )
{
#undef SETBLOCK
#define SETBLOCK 0
@@ -327,11 +303,12 @@ _libssh2_nonblock(int sockfd, /* operate on this */
}
/*
* _libssh2_get_socket_nonblocking() gets the given blocking or non-blocking
* state of the socket.
* get_socket_nonblocking()
*
* gets the given blocking or non-blocking state of the socket.
*/
static int
_libssh2_get_socket_nonblocking(int sockfd)
get_socket_nonblocking(int sockfd)
{ /* operate on this */
#undef GETBLOCK
#define GETBLOCK 0
@@ -386,7 +363,7 @@ _libssh2_get_socket_nonblocking(int sockfd)
#endif
}
/* {{{ libssh2_banner_set
/* libssh2_banner_set
* Set the local banner
*/
LIBSSH2_API int
@@ -421,13 +398,14 @@ libssh2_banner_set(LIBSSH2_SESSION * session, const char *banner)
return 0;
}
/* }}} */
/* {{{ proto libssh2_session_init
* Allocate and initialize a libssh2 session structure
* Allows for malloc callbacks in case the calling program has its own memory manager
* It's allowable (but unadvisable) to define some but not all of the malloc callbacks
* An additional pointer value may be optionally passed to be sent to the callbacks (so they know who's asking)
/*
* libssh2_session_init_ex
*
* Allocate and initialize a libssh2 session structure. Allows for malloc
* callbacks in case the calling program has its own memory manager It's
* allowable (but unadvisable) to define some but not all of the malloc
* callbacks An additional pointer value may be optionally passed to be sent
* to the callbacks (so they know who's asking)
*/
LIBSSH2_API LIBSSH2_SESSION *
libssh2_session_init_ex(LIBSSH2_ALLOC_FUNC((*my_alloc)),
@@ -456,6 +434,7 @@ libssh2_session_init_ex(LIBSSH2_ALLOC_FUNC((*my_alloc)),
session->free = local_free;
session->realloc = local_realloc;
session->abstract = abstract;
session->api_block_mode = 1; /* blocking API by default */
_libssh2_debug(session, LIBSSH2_DBG_TRANS,
"New session resource allocated");
libssh2_crypto_init();
@@ -463,9 +442,9 @@ libssh2_session_init_ex(LIBSSH2_ALLOC_FUNC((*my_alloc)),
return session;
}
/* }}} */
/* {{{ libssh2_session_callback_set
/*
* libssh2_session_callback_set
*
* Set (or reset) a callback function
* Returns the prior address
*
@@ -510,17 +489,47 @@ libssh2_session_callback_set(LIBSSH2_SESSION * session,
return NULL;
}
/* }}} */
/* {{{ proto libssh2_session_startup
* session: LIBSSH2_SESSION struct allocated and owned by the calling program
* Returns: 0 on success, or non-zero on failure
* Any memory allocated by libssh2 will use alloc/realloc/free
* callbacks in session
* socket *must* be populated with an opened and connected socket.
/*
* _libssh2_wait_socket()
*
* Utility function that waits for action on the socket. Returns 0 when ready
* to run again or error on timeout.
*/
LIBSSH2_API int
libssh2_session_startup(LIBSSH2_SESSION * session, int sock)
int _libssh2_wait_socket(LIBSSH2_SESSION *session)
{
fd_set fd;
fd_set *writefd = NULL;
fd_set *readfd = NULL;
int dir;
int rc;
FD_ZERO(&fd);
FD_SET(session->socket_fd, &fd);
/* now make sure we wait in the correct direction */
dir = libssh2_session_block_directions(session);
if(dir & LIBSSH2_SESSION_BLOCK_INBOUND)
readfd = &fd;
if(dir & LIBSSH2_SESSION_BLOCK_OUTBOUND)
writefd = &fd;
/* Note that this COULD be made to use a timeout that perhaps could be
customizable by the app or something... */
rc = select(session->socket_fd + 1, readfd, writefd, NULL, NULL);
if(rc <= 0) {
/* timeout (or error), bail out with a timeout error */
session->err_code = LIBSSH2_ERROR_TIMEOUT;
return LIBSSH2_ERROR_TIMEOUT;
}
return 0; /* ready to try again */
}
static int
session_startup(LIBSSH2_SESSION *session, int sock)
{
int rc;
@@ -536,15 +545,12 @@ libssh2_session_startup(LIBSSH2_SESSION * session, int sock)
}
session->socket_fd = sock;
session->socket_block =
!_libssh2_get_socket_nonblocking(session->socket_fd);
if (session->socket_block) {
/*
* Since we can't be sure that we are in blocking or there
* was an error detecting the state, so set to blocking to
* be sure
*/
_libssh2_nonblock(session->socket_fd, 0);
session->socket_prev_blockstate =
!get_socket_nonblocking(session->socket_fd);
if (session->socket_prev_blockstate) {
/* If in blocking state chang to non-blocking */
session_nonblock(session->socket_fd, 1);
}
session->startup_state = libssh2_NB_state_created;
@@ -553,7 +559,7 @@ libssh2_session_startup(LIBSSH2_SESSION * session, int sock)
/* TODO: Liveness check */
if (session->startup_state == libssh2_NB_state_created) {
rc = libssh2_banner_send(session);
rc = banner_send(session);
if (rc == PACKET_EAGAIN) {
libssh2_error(session, LIBSSH2_ERROR_EAGAIN,
"Would block sending banner to remote host", 0);
@@ -569,7 +575,7 @@ libssh2_session_startup(LIBSSH2_SESSION * session, int sock)
}
if (session->startup_state == libssh2_NB_state_sent) {
rc = libssh2_banner_receive(session);
rc = banner_receive(session);
if (rc == PACKET_EAGAIN) {
libssh2_error(session, LIBSSH2_ERROR_EAGAIN,
"Would block waiting for banner", 0);
@@ -605,7 +611,7 @@ libssh2_session_startup(LIBSSH2_SESSION * session, int sock)
/* Request the userauth service */
session->startup_service[0] = SSH_MSG_SERVICE_REQUEST;
libssh2_htonu32(session->startup_service + 1,
_libssh2_htonu32(session->startup_service + 1,
sizeof("ssh-userauth") - 1);
memcpy(session->startup_service + 5, "ssh-userauth",
sizeof("ssh-userauth") - 1);
@@ -614,13 +620,14 @@ libssh2_session_startup(LIBSSH2_SESSION * session, int sock)
}
if (session->startup_state == libssh2_NB_state_sent3) {
rc = libssh2_packet_write(session, session->startup_service,
sizeof("ssh-userauth") + 5 - 1);
rc = _libssh2_transport_write(session, session->startup_service,
sizeof("ssh-userauth") + 5 - 1);
if (rc == PACKET_EAGAIN) {
libssh2_error(session, LIBSSH2_ERROR_EAGAIN,
"Would block asking for ssh-userauth service", 0);
return LIBSSH2_ERROR_EAGAIN;
} else if (rc) {
}
else if (rc) {
libssh2_error(session, LIBSSH2_ERROR_SOCKET_SEND,
"Unable to ask for ssh-userauth service", 0);
return LIBSSH2_ERROR_SOCKET_SEND;
@@ -630,17 +637,17 @@ libssh2_session_startup(LIBSSH2_SESSION * session, int sock)
}
if (session->startup_state == libssh2_NB_state_sent4) {
rc = libssh2_packet_require_ex(session, SSH_MSG_SERVICE_ACCEPT,
&session->startup_data,
&session->startup_data_len, 0, NULL, 0,
&session->startup_req_state);
rc = _libssh2_packet_require(session, SSH_MSG_SERVICE_ACCEPT,
&session->startup_data,
&session->startup_data_len, 0, NULL, 0,
&session->startup_req_state);
if (rc == PACKET_EAGAIN) {
return LIBSSH2_ERROR_EAGAIN;
} else if (rc) {
return LIBSSH2_ERROR_SOCKET_DISCONNECT;
}
session->startup_service_length =
libssh2_ntohu32(session->startup_data + 1);
_libssh2_ntohu32(session->startup_data + 1);
if ((session->startup_service_length != (sizeof("ssh-userauth") - 1))
|| strncmp("ssh-userauth", (char *) session->startup_data + 5,
@@ -663,14 +670,33 @@ libssh2_session_startup(LIBSSH2_SESSION * session, int sock)
return LIBSSH2_ERROR_INVAL;
}
/* }}} */
/*
* proto libssh2_session_startup
*
* session: LIBSSH2_SESSION struct allocated and owned by the calling program
* Returns: 0 on success, or non-zero on failure
* Any memory allocated by libssh2 will use alloc/realloc/free
* callbacks in session.
* The 'sock' socket *must* be populated with an opened and connected socket.
*/
LIBSSH2_API int
libssh2_session_startup(LIBSSH2_SESSION *session, int sock)
{
int rc;
/* {{{ proto libssh2_session_free
BLOCK_ADJUST(rc, session, session_startup(session, sock) );
return rc;
}
/*
* libssh2_session_free
*
* Frees the memory allocated to the session
* Also closes and frees any channels attached to this session
*/
LIBSSH2_API int
libssh2_session_free(LIBSSH2_SESSION * session)
static int
session_free(LIBSSH2_SESSION *session)
{
int rc;
@@ -699,7 +725,8 @@ libssh2_session_free(LIBSSH2_SESSION * session)
/* free */
LIBSSH2_FREE(session, tmp);
/* reverse linking isn't important here, we're killing the structure */
/* reverse linking isn't important here, we're killing the
* structure */
}
}
@@ -893,18 +920,37 @@ libssh2_session_free(LIBSSH2_SESSION * session)
LIBSSH2_FREE(session, tmp);
}
if(session->socket_prev_blockstate)
/* if the socket was previously blocking, put it back so */
session_nonblock(session->socket_fd, 0);
LIBSSH2_FREE(session, session);
return 0;
}
/* }}} */
/* {{{ libssh2_session_disconnect_ex
/*
* libssh2_session_free
*
* Frees the memory allocated to the session
* Also closes and frees any channels attached to this session
*/
LIBSSH2_API int
libssh2_session_disconnect_ex(LIBSSH2_SESSION * session, int reason,
const char *description, const char *lang)
libssh2_session_free(LIBSSH2_SESSION * session)
{
int rc;
BLOCK_ADJUST(rc, session, session_free(session) );
return rc;
}
/*
* libssh2_session_disconnect_ex
*/
static int
session_disconnect(LIBSSH2_SESSION *session, int reason,
const char *description, const char *lang)
{
unsigned char *s;
unsigned long descr_len = 0, lang_len = 0;
@@ -934,17 +980,17 @@ libssh2_session_disconnect_ex(LIBSSH2_SESSION * session, int reason,
}
*(s++) = SSH_MSG_DISCONNECT;
libssh2_htonu32(s, reason);
_libssh2_htonu32(s, reason);
s += 4;
libssh2_htonu32(s, descr_len);
_libssh2_htonu32(s, descr_len);
s += 4;
if (description) {
memcpy(s, description, descr_len);
s += descr_len;
}
libssh2_htonu32(s, lang_len);
_libssh2_htonu32(s, lang_len);
s += 4;
if (lang) {
memcpy(s, lang, lang_len);
@@ -954,8 +1000,8 @@ libssh2_session_disconnect_ex(LIBSSH2_SESSION * session, int reason,
session->disconnect_state = libssh2_NB_state_created;
}
rc = libssh2_packet_write(session, session->disconnect_data,
session->disconnect_data_len);
rc = _libssh2_transport_write(session, session->disconnect_data,
session->disconnect_data_len);
if (rc == PACKET_EAGAIN) {
return PACKET_EAGAIN;
}
@@ -967,12 +1013,27 @@ libssh2_session_disconnect_ex(LIBSSH2_SESSION * session, int reason,
return 0;
}
/* }}} */
/*
* libssh2_session_disconnect_ex
*/
LIBSSH2_API int
libssh2_session_disconnect_ex(LIBSSH2_SESSION *session, int reason,
const char *desc, const char *lang)
{
int rc;
/* {{{ libssh2_session_methods
BLOCK_ADJUST(rc, session,
session_disconnect(session, reason, desc, lang));
return rc;
}
/* libssh2_session_methods
*
* Return the currently active methods for method_type
* NOTE: Currently lang_cs and lang_sc are ALWAYS set to empty string regardless of actual negotiation
* Strings should NOT be freed
*
* NOTE: Currently lang_cs and lang_sc are ALWAYS set to empty string
* regardless of actual negotiation Strings should NOT be freed
*/
LIBSSH2_API const char *
libssh2_session_methods(LIBSSH2_SESSION * session, int method_type)
@@ -1037,9 +1098,7 @@ libssh2_session_methods(LIBSSH2_SESSION * session, int method_type)
return method->name;
}
/* }}} */
/* {{{ libssh2_session_abstract
/* libssh2_session_abstract
* Retrieve a pointer to the abstract property
*/
LIBSSH2_API void **
@@ -1048,12 +1107,11 @@ libssh2_session_abstract(LIBSSH2_SESSION * session)
return &session->abstract;
}
/* }}} */
/* {{{ libssh2_session_last_error
* Returns error code and populates an error string into errmsg
* If want_buf is non-zero then the string placed into errmsg must be freed by the calling program
* Otherwise it is assumed to be owned by libssh2
/* libssh2_session_last_error
*
* Returns error code and populates an error string into errmsg If want_buf is
* non-zero then the string placed into errmsg must be freed by the calling
* program. Otherwise it is assumed to be owned by libssh2
*/
LIBSSH2_API int
libssh2_session_last_error(LIBSSH2_SESSION * session, char **errmsg,
@@ -1106,9 +1164,7 @@ libssh2_session_last_error(LIBSSH2_SESSION * session, char **errmsg,
return session->err_code;
}
/* }}} */
/* {{{ libssh2_session_last_error
/* libssh2_session_last_error
* Returns error code
*/
LIBSSH2_API int
@@ -1117,9 +1173,7 @@ libssh2_session_last_errno(LIBSSH2_SESSION * session)
return session->err_code;
}
/* }}} */
/* {{{ libssh2_session_flag
/* libssh2_session_flag
* Set/Get session flags
* Passing flag==0 will avoid changing session->flags while still returning its current value
*/
@@ -1135,32 +1189,25 @@ libssh2_session_flag(LIBSSH2_SESSION * session, int flag, int value)
return session->flags;
}
/* }}} */
/* {{{ _libssh2_session_set_blocking
* Set a session's blocking mode on or off, return the previous status
* when this function is called.
/* _libssh2_session_set_blocking
*
* Set a session's blocking mode on or off, return the previous status when
* this function is called. Note this function does not alter the state of the
* actual socket involved.
*/
int
_libssh2_session_set_blocking(LIBSSH2_SESSION * session, int blocking)
_libssh2_session_set_blocking(LIBSSH2_SESSION *session, int blocking)
{
int bl = session->socket_block;
int bl = session->api_block_mode;
_libssh2_debug(session, LIBSSH2_DBG_CONN,
"Setting blocking mode on session %d", blocking);
if (blocking == session->socket_block) {
/* avoid if already correct */
return bl;
}
session->socket_block = blocking;
_libssh2_nonblock(session->socket_fd, !blocking);
"Setting blocking mode %s", blocking?"ON":"OFF");
session->api_block_mode = blocking;
return bl;
}
/* }}} */
/* {{{ libssh2_session_set_blocking
/* libssh2_session_set_blocking
*
* Set a channel's blocking mode on or off, similar to a socket's
* fcntl(fd, F_SETFL, O_NONBLOCK); type command
*/
@@ -1170,20 +1217,19 @@ libssh2_session_set_blocking(LIBSSH2_SESSION * session, int blocking)
(void) _libssh2_session_set_blocking(session, blocking);
}
/* }}} */
/* {{{ libssh2_session_get_blocking
* Returns a session's blocking mode on or off
*/
/* libssh2_session_get_blocking
*
* Returns a session's blocking mode on or off
*/
LIBSSH2_API int
libssh2_session_get_blocking(LIBSSH2_SESSION * session)
{
return session->socket_block;
return session->api_block_mode;
}
/* }}} */
/* {{{ libssh2_poll_channel_read
/*
* libssh2_poll_channel_read
*
* Returns 0 if no data is waiting on channel,
* non-0 if data is available
*/
@@ -1193,18 +1239,17 @@ libssh2_poll_channel_read(LIBSSH2_CHANNEL * channel, int extended)
LIBSSH2_SESSION *session = channel->session;
LIBSSH2_PACKET *packet = session->packets.head;
while (packet)
{
if ( channel->local.id == libssh2_ntohu32(packet->data + 1)) {
if ( extended == 1 &&
(packet->data[0] == SSH_MSG_CHANNEL_EXTENDED_DATA
|| packet->data[0] == SSH_MSG_CHANNEL_DATA )) {
return 1;
} else if ( extended == 0 &&
packet->data[0] == SSH_MSG_CHANNEL_DATA) {
return 1;
}
/* else - no data of any type is ready to be read */
while (packet) {
if ( channel->local.id == _libssh2_ntohu32(packet->data + 1)) {
if ( extended == 1 &&
(packet->data[0] == SSH_MSG_CHANNEL_EXTENDED_DATA
|| packet->data[0] == SSH_MSG_CHANNEL_DATA )) {
return 1;
} else if ( extended == 0 &&
packet->data[0] == SSH_MSG_CHANNEL_DATA) {
return 1;
}
/* else - no data of any type is ready to be read */
}
packet = packet->next;
}
@@ -1212,33 +1257,32 @@ libssh2_poll_channel_read(LIBSSH2_CHANNEL * channel, int extended)
return 0;
}
/* }}} */
/* {{{ libssh2_poll_channel_write
/*
* poll_channel_write
*
* Returns 0 if writing to channel would block,
* non-0 if data can be written without blocking
*/
static inline int
libssh2_poll_channel_write(LIBSSH2_CHANNEL * channel)
poll_channel_write(LIBSSH2_CHANNEL * channel)
{
return channel->local.window_size ? 1 : 0;
}
/* }}} */
/* {{{ libssh2_poll_listener_queued
/* poll_listener_queued
*
* Returns 0 if no connections are waiting to be accepted
* non-0 if one or more connections are available
*/
static inline int
libssh2_poll_listener_queued(LIBSSH2_LISTENER * listener)
poll_listener_queued(LIBSSH2_LISTENER * listener)
{
return listener->queue ? 1 : 0;
}
/* }}} */
/* {{{ libssh2_poll
/*
* libssh2_poll
*
* Poll sockets, channels, and listeners for activity
*/
LIBSSH2_API int
@@ -1360,25 +1404,30 @@ libssh2_poll(LIBSSH2_POLLFD * fds, unsigned int nfds, long timeout)
if (fds[i].events != fds[i].revents) {
switch (fds[i].type) {
case LIBSSH2_POLLFD_CHANNEL:
if ((fds[i].events & LIBSSH2_POLLFD_POLLIN) && /* Want to be ready for read */
((fds[i].revents & LIBSSH2_POLLFD_POLLIN) == 0)) { /* Not yet known to be ready for read */
if ((fds[i].events & LIBSSH2_POLLFD_POLLIN) &&
/* Want to be ready for read */
((fds[i].revents & LIBSSH2_POLLFD_POLLIN) == 0)) {
/* Not yet known to be ready for read */
fds[i].revents |=
libssh2_poll_channel_read(fds[i].fd.channel,
0) ?
LIBSSH2_POLLFD_POLLIN : 0;
}
if ((fds[i].events & LIBSSH2_POLLFD_POLLEXT) && /* Want to be ready for extended read */
((fds[i].revents & LIBSSH2_POLLFD_POLLEXT) == 0)) { /* Not yet known to be ready for extended read */
if ((fds[i].events & LIBSSH2_POLLFD_POLLEXT) &&
/* Want to be ready for extended read */
((fds[i].revents & LIBSSH2_POLLFD_POLLEXT) == 0)) {
/* Not yet known to be ready for extended read */
fds[i].revents |=
libssh2_poll_channel_read(fds[i].fd.channel,
1) ?
LIBSSH2_POLLFD_POLLEXT : 0;
}
if ((fds[i].events & LIBSSH2_POLLFD_POLLOUT) && /* Want to be ready for write */
((fds[i].revents & LIBSSH2_POLLFD_POLLOUT) == 0)) { /* Not yet known to be ready for write */
if ((fds[i].events & LIBSSH2_POLLFD_POLLOUT) &&
/* Want to be ready for write */
((fds[i].revents & LIBSSH2_POLLFD_POLLOUT) == 0)) {
/* Not yet known to be ready for write */
fds[i].revents |=
libssh2_poll_channel_write(fds[i].fd.
channel) ?
poll_channel_write(fds[i].fd. channel) ?
LIBSSH2_POLLFD_POLLOUT : 0;
}
if (fds[i].fd.channel->remote.close
@@ -1394,11 +1443,13 @@ libssh2_poll(LIBSSH2_POLLFD * fds, unsigned int nfds, long timeout)
break;
case LIBSSH2_POLLFD_LISTENER:
if ((fds[i].events & LIBSSH2_POLLFD_POLLIN) && /* Want a connection */
((fds[i].revents & LIBSSH2_POLLFD_POLLIN) == 0)) { /* No connections known of yet */
if ((fds[i].events & LIBSSH2_POLLFD_POLLIN) &&
/* Want a connection */
((fds[i].revents & LIBSSH2_POLLFD_POLLIN) == 0)) {
/* No connections known of yet */
fds[i].revents |=
libssh2_poll_listener_queued(fds[i].fd.
listener) ?
poll_listener_queued(fds[i].fd.
listener) ?
LIBSSH2_POLLFD_POLLIN : 0;
}
if (fds[i].fd.listener->session->socket_state ==
@@ -1416,7 +1467,8 @@ libssh2_poll(LIBSSH2_POLLFD * fds, unsigned int nfds, long timeout)
}
if (active_fds) {
/* Don't block on the sockets if we have channels/listeners which are ready */
/* Don't block on the sockets if we have channels/listeners which
are ready */
timeout_remaining = 0;
}
#ifdef HAVE_POLL
@@ -1444,7 +1496,7 @@ libssh2_poll(LIBSSH2_POLLFD * fds, unsigned int nfds, long timeout)
switch (fds[i].type) {
case LIBSSH2_POLLFD_SOCKET:
fds[i].revents = sockets[i].revents;
sockets[i].revents = 0; /* In case we loop again, be nice */
sockets[i].revents = 0; /* In case we loop again, be nice */
if (fds[i].revents) {
active_fds++;
}
@@ -1452,7 +1504,7 @@ libssh2_poll(LIBSSH2_POLLFD * fds, unsigned int nfds, long timeout)
case LIBSSH2_POLLFD_CHANNEL:
if (sockets[i].events & POLLIN) {
/* Spin session until no data available */
while (libssh2_packet_read(fds[i].fd.channel->session)
while (_libssh2_transport_read(fds[i].fd.channel->session)
> 0);
}
if (sockets[i].revents & POLLHUP) {
@@ -1465,7 +1517,7 @@ libssh2_poll(LIBSSH2_POLLFD * fds, unsigned int nfds, long timeout)
case LIBSSH2_POLLFD_LISTENER:
if (sockets[i].events & POLLIN) {
/* Spin session until no data available */
while (libssh2_packet_read(fds[i].fd.listener->session)
while (_libssh2_transport_read(fds[i].fd.listener->session)
> 0);
}
if (sockets[i].revents & POLLHUP) {
@@ -1518,7 +1570,7 @@ libssh2_poll(LIBSSH2_POLLFD * fds, unsigned int nfds, long timeout)
case LIBSSH2_POLLFD_CHANNEL:
if (FD_ISSET(fds[i].fd.channel->session->socket_fd, &rfds)) {
/* Spin session until no data available */
while (libssh2_packet_read(fds[i].fd.channel->session)
while (_libssh2_transport_read(fds[i].fd.channel->session)
> 0);
}
break;
@@ -1527,20 +1579,23 @@ libssh2_poll(LIBSSH2_POLLFD * fds, unsigned int nfds, long timeout)
if (FD_ISSET
(fds[i].fd.listener->session->socket_fd, &rfds)) {
/* Spin session until no data available */
while (libssh2_packet_read(fds[i].fd.listener->session)
while (_libssh2_transport_read(fds[i].fd.listener->session)
> 0);
}
break;
}
}
}
#endif /* else no select() or poll() -- timeout (and by extension timeout_remaining) will be equal to 0 */
#endif /* else no select() or poll() -- timeout (and by extension
* timeout_remaining) will be equal to 0 */
} while ((timeout_remaining > 0) && !active_fds);
return active_fds;
}
/* {{{ libssh2_session_block_direction
/*
* libssh2_session_block_direction
*
* Get blocked direction when a function returns LIBSSH2_ERROR_EAGAIN
* Returns LIBSSH2_SOCKET_BLOCK_INBOUND if recv() blocked
* or LIBSSH2_SOCKET_BLOCK_OUTBOUND if send() blocked
@@ -1551,4 +1606,3 @@ libssh2_session_block_directions(LIBSSH2_SESSION *session)
return session->socket_block_directions;
}
/* }}} */

File diff suppressed because it is too large Load Diff

View File

@@ -1,4 +1,5 @@
/* Copyright (C) 2007 The Written Word, Inc. All rights reserved.
* Copyright (C) 2009 by Daniel Stenberg
* Author: Daniel Stenberg <daniel@haxx.se>
*
* Redistribution and use in source and binary forms,
@@ -43,8 +44,10 @@
#include <assert.h>
#define MAX_BLOCKSIZE 32 /* MUST fit biggest crypto block size we use/get */
#define MAX_MACSIZE 20 /* MUST fit biggest MAC length we support */
#include "transport.h"
#define MAX_BLOCKSIZE 32 /* MUST fit biggest crypto block size we use/get */
#define MAX_MACSIZE 20 /* MUST fit biggest MAC length we support */
#ifdef LIBSSH2DEBUG
#define UNPRINTABLE_CHAR '.'
@@ -54,7 +57,7 @@ debugdump(LIBSSH2_SESSION * session,
{
size_t i;
size_t c;
FILE *stream = stdout;
FILE *stream = stderr;
unsigned int width = 0x10;
if (!(session->showmask & (1 << LIBSSH2_DBG_TRANS))) {
@@ -169,7 +172,8 @@ fullpacket(LIBSSH2_SESSION * session, int encrypted /* 1 or 0 */ )
session->fullpacket_payload_len -= p->padding_length;
/* Check for and deal with decompression */
if (session->remote.comp && strcmp(session->remote.comp->name, "none")) {
if (session->remote.comp &&
strcmp(session->remote.comp->name, "none")) {
unsigned char *data;
unsigned long data_len;
int free_payload = 1;
@@ -207,8 +211,7 @@ fullpacket(LIBSSH2_SESSION * session, int encrypted /* 1 or 0 */ )
p->payload = LIBSSH2_ALLOC(session, data_len);
if (!p->payload) {
libssh2_error(session, LIBSSH2_ERROR_ALLOC, (char *)
"Unable to allocate memory for copy of uncompressed data",
0);
"Unable to allocate memory", 0);
return PACKET_ENOMEM;
}
memcpy(p->payload, data, data_len);
@@ -219,16 +222,16 @@ fullpacket(LIBSSH2_SESSION * session, int encrypted /* 1 or 0 */ )
session->fullpacket_packet_type = p->payload[0];
debugdump(session, "libssh2_packet_read() plain",
debugdump(session, "libssh2_transport_read() plain",
p->payload, session->fullpacket_payload_len);
session->fullpacket_state = libssh2_NB_state_created;
}
if (session->fullpacket_state == libssh2_NB_state_created) {
rc = libssh2_packet_add(session, p->payload,
session->fullpacket_payload_len,
session->fullpacket_macstate);
rc = _libssh2_packet_add(session, p->payload,
session->fullpacket_payload_len,
session->fullpacket_macstate);
if (rc == PACKET_EAGAIN) {
return PACKET_EAGAIN;
} else if (rc < 0) {
@@ -242,10 +245,11 @@ fullpacket(LIBSSH2_SESSION * session, int encrypted /* 1 or 0 */ )
}
/* {{{ libssh2_packet_read
* Collect a packet into the input brigade
* block only controls whether or not to wait for a packet to start,
* Once a packet starts, libssh2 will block until it is complete
/*
* _libssh2_transport_read
*
* Collect a packet into the input brigade block only controls whether or not
* to wait for a packet to start.
*
* Returns packet type added to input brigade (PACKET_NONE if nothing added),
* or PACKET_FAIL on failure and PACKET_EAGAIN if it couldn't process a full
@@ -257,7 +261,7 @@ fullpacket(LIBSSH2_SESSION * session, int encrypted /* 1 or 0 */ )
* "The Secure Shell (SSH) Transport Layer Protocol"
*/
libssh2pack_t
libssh2_packet_read(LIBSSH2_SESSION * session)
_libssh2_transport_read(LIBSSH2_SESSION * session)
{
libssh2pack_t rc;
struct transportpacket *p = &session->packet;
@@ -274,12 +278,12 @@ libssh2_packet_read(LIBSSH2_SESSION * session)
/*
* All channels, systems, subsystems, etc eventually make it down here
* when looking for more incoming data. If a key exchange is going on
* (LIBSSH2_STATE_EXCHANGING_KEYS bit is set) then the remote end
* will ONLY send key exchange related traffic. In non-blocking mode,
* there is a chance to break out of the kex_exchange function with an
* EAGAIN status, and never come back to it. If LIBSSH2_STATE_EXCHANGING_KEYS
* is active, then we must redirect to the key exchange. However,
* if kex_exchange is active (as in it is the one that calls this execution
* (LIBSSH2_STATE_EXCHANGING_KEYS bit is set) then the remote end will
* ONLY send key exchange related traffic. In non-blocking mode, there is
* a chance to break out of the kex_exchange function with an EAGAIN
* status, and never come back to it. If LIBSSH2_STATE_EXCHANGING_KEYS is
* active, then we must redirect to the key exchange. However, if
* kex_exchange is active (as in it is the one that calls this execution
* of packet_read, then don't redirect, as that would be an infinite loop!
*/
@@ -311,7 +315,7 @@ libssh2_packet_read(LIBSSH2_SESSION * session)
if (session->readPack_state == libssh2_NB_state_jump1) {
session->readPack_state = libssh2_NB_state_idle;
encrypted = session->readPack_encrypted;
goto libssh2_packet_read_point1;
goto libssh2_transport_read_point1;
}
do {
@@ -358,32 +362,12 @@ libssh2_packet_read(LIBSSH2_SESSION * session)
/* now read a big chunk from the network into the temp buffer */
nread =
recv(session->socket_fd, &p->buf[remainbuf],
_libssh2_recv(session->socket_fd, &p->buf[remainbuf],
PACKETBUFSIZE - remainbuf,
LIBSSH2_SOCKET_RECV_FLAGS(session));
if (nread <= 0) {
/* check if this is due to EAGAIN and return the special
return code if so, error out normally otherwise */
#ifdef WIN32
switch (WSAGetLastError()) {
case WSAEWOULDBLOCK:
errno = EAGAIN;
break;
case WSAENOTSOCK:
errno = EBADF;
break;
case WSAENOTCONN:
case WSAECONNABORTED:
errno = WSAENOTCONN;
break;
case WSAEINTR:
errno = EINTR;
break;
}
#endif /* WIN32 */
if ((nread < 0) && (errno == EAGAIN)) {
session->socket_block_directions =
LIBSSH2_SESSION_BLOCK_INBOUND;
@@ -391,7 +375,7 @@ libssh2_packet_read(LIBSSH2_SESSION * session)
}
return PACKET_FAIL;
}
debugdump(session, "libssh2_packet_read() raw",
debugdump(session, "libssh2_transport_read() raw",
&p->buf[remainbuf], nread);
/* advance write pointer */
p->writeidx += nread;
@@ -436,7 +420,7 @@ libssh2_packet_read(LIBSSH2_SESSION * session)
/* we now have the initial blocksize bytes decrypted,
* and we can extract packet and padding length from it
*/
p->packet_length = libssh2_ntohu32(block);
p->packet_length = _libssh2_ntohu32(block);
p->padding_length = block[4];
/* total_num is the number of bytes following the initial
@@ -560,7 +544,7 @@ libssh2_packet_read(LIBSSH2_SESSION * session)
if (!remainpack) {
/* we have a full packet */
libssh2_packet_read_point1:
libssh2_transport_read_point1:
rc = fullpacket(session, encrypted);
if (rc == PACKET_EAGAIN) {
@@ -590,8 +574,6 @@ libssh2_packet_read(LIBSSH2_SESSION * session)
return PACKET_FAIL; /* we never reach this point */
}
/* }}} */
static libssh2pack_t
send_existing(LIBSSH2_SESSION * session, unsigned char *data,
unsigned long data_len, ssize_t * ret)
@@ -620,7 +602,7 @@ send_existing(LIBSSH2_SESSION * session, unsigned char *data,
/* number of bytes left to send */
length = p->ototal_num - p->osent;
rc = send(session->socket_fd, &p->outbuf[p->osent], length,
rc = _libssh2_send(session->socket_fd, &p->outbuf[p->osent], length,
LIBSSH2_SOCKET_SEND_FLAGS(session));
if (rc == length) {
@@ -638,14 +620,16 @@ send_existing(LIBSSH2_SESSION * session, unsigned char *data,
return PACKET_EAGAIN;
}
debugdump(session, "libssh2_packet_write send()", &p->outbuf[p->osent],
debugdump(session, "libssh2_transport_write send()", &p->outbuf[p->osent],
length);
p->osent += length; /* we sent away this much data */
return PACKET_NONE;
}
/* {{{ libssh2_packet_write
/*
* libssh2_transport_write
*
* Send a packet, encrypting it and adding a MAC code if necessary
* Returns 0 on success, non-zero on failure.
*
@@ -659,8 +643,8 @@ send_existing(LIBSSH2_SESSION * session, unsigned char *data,
* (RFC4253 section 6.1)
*/
int
libssh2_packet_write(LIBSSH2_SESSION * session, unsigned char *data,
unsigned long data_len)
_libssh2_transport_write(LIBSSH2_SESSION * session, unsigned char *data,
unsigned long data_len)
{
int blocksize =
(session->state & LIBSSH2_STATE_NEWKEYS) ? session->local.crypt->
@@ -681,7 +665,7 @@ libssh2_packet_write(LIBSSH2_SESSION * session, unsigned char *data,
unsigned char *orgdata = data;
unsigned long orgdata_len = data_len;
debugdump(session, "libssh2_packet_write plain", data, data_len);
debugdump(session, "libssh2_transport_write plain", data, data_len);
/* FIRST, check if we have a pending write to complete */
rc = send_existing(session, data, data_len, &ret);
@@ -750,7 +734,7 @@ libssh2_packet_write(LIBSSH2_SESSION * session, unsigned char *data,
/* store packet_length, which is the size of the whole packet except
the MAC and the packet_length field itself */
libssh2_htonu32(p->outbuf, packet_length - 4);
_libssh2_htonu32(p->outbuf, packet_length - 4);
/* store padding_length */
p->outbuf[4] = padding_length;
/* copy the payload data */
@@ -783,11 +767,11 @@ libssh2_packet_write(LIBSSH2_SESSION * session, unsigned char *data,
session->local.seqno++;
ret = send(session->socket_fd, p->outbuf, total_length,
ret = _libssh2_send(session->socket_fd, p->outbuf, total_length,
LIBSSH2_SOCKET_SEND_FLAGS(session));
if (ret != -1) {
debugdump(session, "libssh2_packet_write send()", p->outbuf, ret);
debugdump(session, "libssh2_transport_write send()", p->outbuf, ret);
}
if (ret != total_length) {
if ((ret > 0) || ((ret == -1) && (errno == EAGAIN))) {
@@ -811,5 +795,5 @@ libssh2_packet_write(LIBSSH2_SESSION * session, unsigned char *data,
return PACKET_NONE; /* all is good */
}
/* }}} */

80
src/transport.h Normal file
View File

@@ -0,0 +1,80 @@
#ifndef __LIBSSH2_TRANSPORT_H
#define __LIBSSH2_TRANSPORT_H
/* Copyright (C) 2007 The Written Word, Inc. All rights reserved.
* Copyright (C) 2009 by Daniel Stenberg
* Author: Daniel Stenberg <daniel@haxx.se>
*
* Redistribution and use in source and binary forms,
* with or without modification, are permitted provided
* that the following conditions are met:
*
* Redistributions of source code must retain the above
* copyright notice, this list of conditions and the
* following disclaimer.
*
* Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following
* disclaimer in the documentation and/or other materials
* provided with the distribution.
*
* Neither the name of the copyright holder nor the names
* of any other contributors may be used to endorse or
* promote products derived from this software without
* specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
* CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
* USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
* OF SUCH DAMAGE.
*
* This file handles reading and writing to the SECSH transport layer. RFC4253.
*/
#include "libssh2_priv.h"
/*
* libssh2_transport_write
*
* Send a packet, encrypting it and adding a MAC code if necessary
* Returns 0 on success, non-zero on failure.
*
* Returns PACKET_EAGAIN if it would block - and if it does so, you should
* call this function again as soon as it is likely that more data can be
* sent, and this function should then be called with the same argument set
* (same data pointer and same data_len) until zero or failure is returned.
*
* NOTE: this function does not verify that 'data_len' is less than ~35000
* which is what all implementations should support at least as packet size.
* (RFC4253 section 6.1)
*/
int _libssh2_transport_write(LIBSSH2_SESSION * session, unsigned char *data,
unsigned long data_len);
/*
* _libssh2_transport_read
*
* Collect a packet into the input brigade block only controls whether or not
* to wait for a packet to start.
*
* Returns packet type added to input brigade (PACKET_NONE if nothing added),
* or PACKET_FAIL on failure and PACKET_EAGAIN if it couldn't process a full
* packet.
*/
/*
* This function reads the binary stream as specified in chapter 6 of RFC4253
* "The Secure Shell (SSH) Transport Layer Protocol"
*/
libssh2pack_t _libssh2_transport_read(LIBSSH2_SESSION * session);
#endif /* __LIBSSH2_TRANSPORT_H */

File diff suppressed because it is too large Load Diff

54
src/version.c Normal file
View File

@@ -0,0 +1,54 @@
/* Copyright (C) 2009 Daniel Stenberg. All rights reserved.
*
* Redistribution and use in source and binary forms,
* with or without modification, are permitted provided
* that the following conditions are met:
*
* Redistributions of source code must retain the above
* copyright notice, this list of conditions and the
* following disclaimer.
*
* Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following
* disclaimer in the documentation and/or other materials
* provided with the distribution.
*
* Neither the name of the copyright holder nor the names
* of any other contributors may be used to endorse or
* promote products derived from this software without
* specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
* CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
* USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
* OF SUCH DAMAGE.
*
*/
#include "libssh2_priv.h"
/*
libssh2_version() can be used like this:
if (!libssh2_version(LIBSSH2_VERSION_NUM)) {
fprintf (stderr, "Runtime libssh2 version too old!\n");
exit(1);
}
*/
LIBSSH2_API
const char *libssh2_version(int req_version_num)
{
if(req_version_num <= LIBSSH2_VERSION_NUM)
return LIBSSH2_VERSION;
return NULL; /* this is not a suitable library! */
}

Some files were not shown because too many files have changed in this diff Show More