Compare commits
24 Commits
RELEASE.0.
...
RELEASE.0.
Author | SHA1 | Date | |
---|---|---|---|
![]() |
dbbd9eafc6 | ||
![]() |
c92465930d | ||
![]() |
34d5c9a4b1 | ||
![]() |
e8bb993437 | ||
![]() |
030b670e2a | ||
![]() |
371a795443 | ||
![]() |
2d773f9322 | ||
![]() |
80f6c7c6d1 | ||
![]() |
46f26d3d0e | ||
![]() |
5d91d286f1 | ||
![]() |
5a854cfb26 | ||
![]() |
e905b206ed | ||
![]() |
fe7a6f967d | ||
![]() |
5879a0245b | ||
![]() |
d90d8bdae7 | ||
![]() |
f216b36328 | ||
![]() |
c4630d1ffb | ||
![]() |
17173aab0e | ||
![]() |
f8d4de78e9 | ||
![]() |
e32ff531a3 | ||
![]() |
a227554c26 | ||
![]() |
9f27d176f8 | ||
![]() |
bcc4fd6e82 | ||
![]() |
210459db4b |
7
AUTHORS
7
AUTHORS
@@ -4,8 +4,13 @@
|
||||
|
||||
* Simon Josefsson: libgcrypt support
|
||||
|
||||
* Daniel Stenberg: Nonblocking fixes, Build Improvements, and Daily snapshot artist
|
||||
* Daniel Stenberg: Nonblocking fixes, Build Improvements, and Daily snapshot
|
||||
artist
|
||||
|
||||
* Mikhail Gusarov: Keyboard Interactive Authentication
|
||||
|
||||
* Wez Furlong & Edink Kadribasic: Windows Port
|
||||
|
||||
* Dan Fandrich: bug fixes, cleanups
|
||||
|
||||
* Guenter Knauf: win32 work and more
|
||||
|
@@ -11,7 +11,12 @@ NETWAREFILES = nw/keepscreen.c \
|
||||
nw/nwlib.c \
|
||||
nw/test/Makefile.netware
|
||||
|
||||
EXTRA_DIST = win32 buildconf $(NETWAREFILES) get_ver.awk HACKING maketgz NMakefile
|
||||
WIN32FILES = win32/libssh2_dll.dsp win32/libssh2.dsw win32/Makefile.win32 \
|
||||
win32/config.mk win32/Makefile win32/test/Makefile.win32 win32/libssh2_lib.dsp \
|
||||
win32/libssh2_config.h win32/tests.dsp win32/rules.mk
|
||||
|
||||
EXTRA_DIST = $(WIN32FILES) buildconf $(NETWAREFILES) get_ver.awk HACKING \
|
||||
maketgz NMakefile
|
||||
|
||||
ACLOCAL_AMFLAGS = -I m4
|
||||
|
||||
|
117
NEWS
117
NEWS
@@ -1,5 +1,46 @@
|
||||
Version 0.16
|
||||
Version 0.18
|
||||
------------
|
||||
|
||||
- Various changes that improve non-blocking operations and prevent stalls.
|
||||
Especially noticable on Windows since libssh2 just didn't work properly
|
||||
non-blocking on Windows before.
|
||||
|
||||
- Peter O'Gorman reported how a SCP transfer would hang for him, and it was
|
||||
fairly easy reproducable. One bug was in the transport layer, ignoring to
|
||||
read more data while there was data left even though it couldn't decrypt the
|
||||
data that was left due to it being too little... The other bug was in the
|
||||
channel layer, where the libssh2_channel_receive_window_adjust() function
|
||||
missed to set the state variables at times and thus this function would
|
||||
misbehave on repeated invokes.
|
||||
|
||||
- Changed the signature of libssh2_channel_setenv_ex to add const to the
|
||||
"varname" parameter (Dan Fandrich)
|
||||
|
||||
- Satish Mittal and David J Sullivan fixed an infinit recv() loop in
|
||||
libssh2_banner_receive()
|
||||
|
||||
Version 0.17 (August 6 2007)
|
||||
----------------------------
|
||||
Changes since previous version include:
|
||||
|
||||
o Re-indented the source code with this GNU indent setup:
|
||||
|
||||
--braces-on-if-line
|
||||
--braces-after-struct-decl-line
|
||||
--space-after-cast
|
||||
--line-length 79
|
||||
--comment-line-length 79
|
||||
--cuddle-else
|
||||
--no-tabs
|
||||
--tab-size 8
|
||||
--indent-level 4
|
||||
--no-space-after-for
|
||||
--space-after-if
|
||||
--space-after-while
|
||||
--no-space-after-function-call-names
|
||||
|
||||
Version 0.16 (August 6 2007)
|
||||
----------------------------
|
||||
Changes since previous version include:
|
||||
|
||||
o CRLF stripping fix for PEM reading
|
||||
@@ -24,8 +65,8 @@ This release would not have been possible without these friendly contributors:
|
||||
Of course we would have nothing without the great work by Sara Golemon that
|
||||
we're extending and building upon.
|
||||
|
||||
Version 0.15
|
||||
------------
|
||||
Version 0.15 (June 15 2007)
|
||||
---------------------------
|
||||
Added libssh2_sftp_readdir_ex() and updated LIBSSH2_APINO to
|
||||
200706151200 (James Housley)
|
||||
|
||||
@@ -98,7 +139,8 @@ Version 0.14
|
||||
|
||||
Allow socket_fd == 0 in libssh2_session_startup(). (puudeli)
|
||||
|
||||
Swap ordering of packet_add/packet-inspection to avoid inspect after free. (Selcuk)
|
||||
Swap ordering of packet_add/packet-inspection to avoid inspect after
|
||||
free. (Selcuk)
|
||||
|
||||
Swap KEX_INIT ordering, send our KEX_INIT first.
|
||||
|
||||
@@ -109,9 +151,11 @@ Version 0.14
|
||||
Version 0.13
|
||||
------------
|
||||
|
||||
Fixed channel not being marked closed when CHANNEL_CLOSE package cannot be sent. (David Robins)
|
||||
Fixed channel not being marked closed when CHANNEL_CLOSE package cannot be
|
||||
sent. (David Robins)
|
||||
|
||||
Fixed payload packet allocation bug when invalid packet length received. (David Robins)
|
||||
Fixed payload packet allocation bug when invalid packet length
|
||||
received. (David Robins)
|
||||
|
||||
Fixed `make install' target for MacOSX.
|
||||
|
||||
@@ -128,9 +172,11 @@ Version 0.12
|
||||
(Thanks Simon Hart)
|
||||
|
||||
Fix generation of 'e' portion of Diffie-Hellman keyset.
|
||||
|
||||
Use appropriate order for BN_rand() rather than fixed group1-specific value.
|
||||
|
||||
Re-fixed libssh2_sftp_rename_ex()
|
||||
|
||||
Transport had right packet_len, but sftp layer still had extra 4 bytes.
|
||||
|
||||
Fixed build with newer OpenSSL headers.
|
||||
@@ -146,42 +192,52 @@ Version 0.11
|
||||
|
||||
Added libssh2_userauth_keyboard_interactive_ex() -- Mikhail
|
||||
|
||||
Added libssh2_channel_receive_window_adjust() to be able to increase the size of the receive window.
|
||||
Added libssh2_channel_receive_window_adjust() to be able to increase the
|
||||
size of the receive window.
|
||||
|
||||
Added queueing for small window_adjust packets to avoid unnecessary packet conversation.
|
||||
Added queueing for small window_adjust packets to avoid unnecessary packet
|
||||
conversation.
|
||||
|
||||
Fixed libssh2_sftp_rename_ex() to only send flags parameter if version >= 5 negotiated
|
||||
(not currently possible, but will be and might as well keep the API consistent).
|
||||
Fixed libssh2_sftp_rename_ex() to only send flags parameter if version >= 5
|
||||
negotiated (not currently possible, but will be and might as well keep the
|
||||
API consistent).
|
||||
|
||||
Version 0.10
|
||||
------------
|
||||
|
||||
Added developer debugging hooks. See --enable-debug-* options to ./configure
|
||||
|
||||
Ignore extended data in the SFTP layer. With no other mechanism to deal with that data it'd just fill up and get stuck.
|
||||
Ignore extended data in the SFTP layer. With no other mechanism to deal
|
||||
with that data it'd just fill up and get stuck.
|
||||
|
||||
(Re)Fixed channel_write() to provide an opportunity for window space to become available again.
|
||||
(Re)Fixed channel_write() to provide an opportunity for window space to
|
||||
become available again.
|
||||
|
||||
(Re)Fixed SFTP INIT to send the correct SFTP packet length.
|
||||
|
||||
Fixed segfault when client and host can't agree on a hostkey/crypt/mac/comp method. (Thanks puudeli)
|
||||
Fixed segfault when client and host can't agree on a hostkey/crypt/mac/comp
|
||||
method. (Thanks puudeli)
|
||||
|
||||
Fixed major issue with sftp packet buffering mechanism. Using wrong blocking semantics. (No puudeli, YOU the man)
|
||||
Fixed major issue with sftp packet buffering mechanism. Using wrong
|
||||
blocking semantics. (No puudeli, YOU the man)
|
||||
|
||||
Reduced busy-looping of libssh2_sftp_packet_requirev.
|
||||
|
||||
Version 0.9
|
||||
-----------
|
||||
|
||||
Changed blocking_read to only block as much as necessary and not an arbitrary length of time. (Thanks Felix)
|
||||
Changed blocking_read to only block as much as necessary and not an
|
||||
arbitrary length of time. (Thanks Felix)
|
||||
|
||||
Fixed SFTP INIT/VERSION to exclude request_id and send correct maximum version number.
|
||||
Fixed SFTP INIT/VERSION to exclude request_id and send correct maximum
|
||||
version number.
|
||||
|
||||
Fixed SFTP to be properly BC with version 1 and 2 servers.
|
||||
|
||||
Fixed libssh2_poll() to recognized closed sessions/channels.
|
||||
|
||||
Fixed libssh2_channel_write_ex() to fully block when set to blocking mode. Return actual bytes written as well. (Thanks deadem)
|
||||
Fixed libssh2_channel_write_ex() to fully block when set to blocking mode.
|
||||
Return actual bytes written as well. (Thanks deadem)
|
||||
|
||||
Added tests for -lm and -lsocket and add them when necessary.
|
||||
|
||||
@@ -195,9 +251,11 @@ Version 0.8
|
||||
|
||||
Fix compatability with older versions of OpenSSL
|
||||
|
||||
Swapped order of none,zlib compression modes to prefer no compression by default.
|
||||
Swapped order of none,zlib compression modes to prefer no compression by
|
||||
default.
|
||||
|
||||
Added sys/uio.h for platforms (FBSD) which need it in order to define struct iovec.
|
||||
Added sys/uio.h for platforms (FBSD) which need it in order to define struct
|
||||
iovec.
|
||||
|
||||
Added libssh2_poll() to check status of sockets/channels/listeners.
|
||||
|
||||
@@ -220,15 +278,18 @@ Version 0.7
|
||||
Version 0.6
|
||||
-----------
|
||||
|
||||
Added LIBSSH2_FLAG_SIGPIPE to enable/disable SIGPIPE generated by send()/recv() calls. Default off.
|
||||
Added LIBSSH2_FLAG_SIGPIPE to enable/disable SIGPIPE generated by
|
||||
send()/recv() calls. Default off.
|
||||
|
||||
Added libssh2_session_flag() to set optional session flags.
|
||||
|
||||
Collapsed exchanging_keys/newkeys/authenticated flags into single state attribute.
|
||||
Collapsed exchanging_keys/newkeys/authenticated flags into single state
|
||||
attribute.
|
||||
|
||||
Fix zlib compression issue when internal buffer state misses partial sync.
|
||||
|
||||
Fix segfault when libssh2_session_methods() is called prior to session_startup().
|
||||
Fix segfault when libssh2_session_methods() is called prior to
|
||||
session_startup().
|
||||
|
||||
Fixed client to server channel windowing. Pervent send queue overruns.
|
||||
|
||||
@@ -238,7 +299,8 @@ Version 0.5
|
||||
-----------
|
||||
|
||||
*** BC Break ***
|
||||
Reimplemented libssh2_session_methods() to match libssh2_session_method_pref() style
|
||||
Reimplemented libssh2_session_methods() to match
|
||||
libssh2_session_method_pref() style
|
||||
|
||||
Fixed libssh2_attr2bin() (effects any setstat style call).
|
||||
|
||||
@@ -248,11 +310,14 @@ Version 0.5
|
||||
|
||||
Fixed KEX_INIT cookie and packet padding to use actual random data
|
||||
|
||||
Added DESTDIR support to makefiles (Adam Go<47><6F>biowski -- I hope that character set translates right)
|
||||
Added DESTDIR support to makefiles (Adam Go<47><6F>biowski -- I hope that
|
||||
character set translates right)
|
||||
|
||||
Added libssh2_channel_forward_listen_ex(), libssh2_channel_forward_cancel(), and libssh2_channel_forward_accept().
|
||||
Added libssh2_channel_forward_listen_ex(), libssh2_channel_forward_cancel(),
|
||||
and libssh2_channel_forward_accept().
|
||||
|
||||
Added ./configure option '--disable-gex-new' to allow using the older group-exchange format
|
||||
Added ./configure option '--disable-gex-new' to allow using the older
|
||||
group-exchange format
|
||||
|
||||
Added MAC methods hmac-md5 and hmac-md5-96.
|
||||
|
||||
|
@@ -10,34 +10,6 @@ noinst_PROGRAMS = ssh2 \
|
||||
sftp_RW_nonblock \
|
||||
sftpdir sftpdir_nonblock
|
||||
|
||||
INCLUDES = -I$(top_srcdir)/include
|
||||
INCLUDES = -I. -I$(top_srcdir)/include
|
||||
LDADD = $(top_builddir)/src/libssh2.la
|
||||
|
||||
ssh2_SOURCES = ssh2.c
|
||||
|
||||
scp_SOURCES = scp.c
|
||||
|
||||
scp_nonblock_SOURCES = scp_nonblock.c
|
||||
|
||||
scp_write_SOURCES = scp_write.c
|
||||
|
||||
scp_write_nonblock_SOURCES = scp_write_nonblock.c
|
||||
|
||||
sftp_SOURCES = sftp.c
|
||||
|
||||
sftp_nonblock_SOURCES = sftp_nonblock.c
|
||||
|
||||
sftp_write_SOURCES = sftp_write.c
|
||||
|
||||
sftp_write_nonblock_SOURCES = sftp_write_nonblock.c
|
||||
|
||||
sftp_mkdir_SOURCES = sftp_mkdir.c
|
||||
|
||||
sftp_mkdir_nonblock_SOURCES = sftp_mkdir_nonblock.c
|
||||
|
||||
sftpdir_SOURCES = sftpdir.c
|
||||
|
||||
sftpdir_nonblock_SOURCES = sftpdir_nonblock.c
|
||||
|
||||
sftp_RW_nonblock_SOURCES = sftp_RW_nonblock.c
|
||||
|
||||
|
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* $Id: scp.c,v 1.9 2007/07/31 11:00:29 bagder Exp $
|
||||
* $Id: scp.c,v 1.10 2007/08/09 01:10:11 dfandrich Exp $
|
||||
*
|
||||
* Sample showing how to do a simple SCP transfer.
|
||||
*/
|
||||
@@ -40,9 +40,9 @@ int main(int argc, char *argv[])
|
||||
const char *fingerprint;
|
||||
LIBSSH2_SESSION *session;
|
||||
LIBSSH2_CHANNEL *channel;
|
||||
char *username=(char *)"username";
|
||||
char *password=(char *)"password";
|
||||
char *scppath=(char *)"/tmp/TEST";
|
||||
const char *username="username";
|
||||
const char *password="password";
|
||||
const char *scppath="/tmp/TEST";
|
||||
struct stat fileinfo;
|
||||
int rc;
|
||||
off_t got=0;
|
||||
|
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* $Id: scp_nonblock.c,v 1.8 2007/07/31 11:00:29 bagder Exp $
|
||||
* $Id: scp_nonblock.c,v 1.11 2007/09/24 12:15:45 bagder Exp $
|
||||
*
|
||||
* Sample showing how to do SCP transfers in a non-blocking manner.
|
||||
*/
|
||||
@@ -40,9 +40,9 @@ int main(int argc, char *argv[])
|
||||
const char *fingerprint;
|
||||
LIBSSH2_SESSION *session;
|
||||
LIBSSH2_CHANNEL *channel;
|
||||
char *username=(char *)"username";
|
||||
char *password=(char *)"password";
|
||||
char *scppath=(char *)"/tmp/TEST";
|
||||
const char *username="username";
|
||||
const char *password="password";
|
||||
const char *scppath="/tmp/TEST";
|
||||
struct stat fileinfo;
|
||||
int rc;
|
||||
off_t got=0;
|
||||
|
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* $Id: scp_write.c,v 1.4 2007/07/31 11:00:29 bagder Exp $
|
||||
* $Id: scp_write.c,v 1.5 2007/08/09 01:10:11 dfandrich Exp $
|
||||
*
|
||||
* Sample showing how to do a simple SCP transfer.
|
||||
*/
|
||||
@@ -40,10 +40,10 @@ int main(int argc, char *argv[])
|
||||
const char *fingerprint;
|
||||
LIBSSH2_SESSION *session;
|
||||
LIBSSH2_CHANNEL *channel;
|
||||
char *username=(char *)"username";
|
||||
char *password=(char *)"password";
|
||||
char *loclfile=(char *)"scp_write.c";
|
||||
char *scppath=(char *)"/tmp/TEST";
|
||||
const char *username="username";
|
||||
const char *password="password";
|
||||
const char *loclfile="scp_write.c";
|
||||
const char *scppath="/tmp/TEST";
|
||||
FILE *local;
|
||||
int rc;
|
||||
char mem[1024];
|
||||
|
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* $Id: scp_write_nonblock.c,v 1.6 2007/07/31 11:00:29 bagder Exp $
|
||||
* $Id: scp_write_nonblock.c,v 1.7 2007/08/09 01:10:11 dfandrich Exp $
|
||||
*
|
||||
* Sample showing how to do a simple SCP transfer.
|
||||
*/
|
||||
@@ -41,10 +41,10 @@ int main(int argc, char *argv[])
|
||||
const char *fingerprint;
|
||||
LIBSSH2_SESSION *session;
|
||||
LIBSSH2_CHANNEL *channel;
|
||||
char *username=(char *)"username";
|
||||
char *password=(char *)"password";
|
||||
char *loclfile=(char *)"scp_write.c";
|
||||
char *scppath=(char *)"/tmp/TEST";
|
||||
const char *username="username";
|
||||
const char *password="password";
|
||||
const char *loclfile="scp_write.c";
|
||||
const char *scppath="/tmp/TEST";
|
||||
FILE *local;
|
||||
int rc;
|
||||
char mem[1024];
|
||||
|
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* $Id: sftp.c,v 1.12 2007/07/31 11:00:29 bagder Exp $
|
||||
* $Id: sftp.c,v 1.14 2007/09/24 12:14:18 bagder Exp $
|
||||
*
|
||||
* Sample showing how to do SFTP transfers.
|
||||
*
|
||||
@@ -39,11 +39,11 @@
|
||||
#include <ctype.h>
|
||||
|
||||
|
||||
char *keyfile1=(char *)"~/.ssh/id_rsa.pub";
|
||||
char *keyfile2=(char *)"~/.ssh/id_rsa";
|
||||
char *username=(char *)"username";
|
||||
char *password=(char *)"password";
|
||||
char *sftppath=(char *)"/tmp/TEST";
|
||||
const char *keyfile1="~/.ssh/id_rsa.pub";
|
||||
const char *keyfile2="~/.ssh/id_rsa";
|
||||
const char *username="username";
|
||||
const char *password="password";
|
||||
const char *sftppath="/tmp/TEST";
|
||||
|
||||
|
||||
static void kbd_callback(const char *name, int name_len,
|
||||
@@ -147,7 +147,7 @@ int main(int argc, char *argv[])
|
||||
fprintf(stderr, "\n");
|
||||
|
||||
/* check what authentication methods are available */
|
||||
userauthlist = libssh2_userauth_list(session, username, sizeof(username));
|
||||
userauthlist = libssh2_userauth_list(session, username, strlen(username));
|
||||
printf("Authentication methods: %s\n", userauthlist);
|
||||
if (strstr(userauthlist, "password") != NULL) {
|
||||
auth_pw |= 1;
|
||||
|
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* $Id: sftp_RW_nonblock.c,v 1.9 2007/07/31 11:00:29 bagder Exp $
|
||||
* $Id: sftp_RW_nonblock.c,v 1.10 2007/08/09 01:10:11 dfandrich Exp $
|
||||
*
|
||||
* Sample showing how to do SFTP transfers in a non-blocking manner.
|
||||
*
|
||||
@@ -48,10 +48,10 @@ int main(int argc, char *argv[])
|
||||
struct sockaddr_in sin;
|
||||
const char *fingerprint;
|
||||
LIBSSH2_SESSION *session;
|
||||
char *username=(char *)"username";
|
||||
char *password=(char *)"password";
|
||||
char *sftppath=(char *)"/tmp/TEST"; /* source path */
|
||||
char *dest=(char *)"/tmp/TEST2"; /* destination path */
|
||||
const char *username="username";
|
||||
const char *password="password";
|
||||
const char *sftppath="/tmp/TEST"; /* source path */
|
||||
const char *dest="/tmp/TEST2"; /* destination path */
|
||||
int rc;
|
||||
LIBSSH2_SFTP *sftp_session;
|
||||
LIBSSH2_SFTP_HANDLE *sftp_handle;
|
||||
|
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* $Id: sftp_mkdir.c,v 1.6 2007/07/31 11:00:29 bagder Exp $
|
||||
* $Id: sftp_mkdir.c,v 1.7 2007/08/09 01:10:11 dfandrich Exp $
|
||||
*
|
||||
* Sample showing how to do SFTP mkdir
|
||||
*
|
||||
@@ -42,9 +42,9 @@ int main(int argc, char *argv[])
|
||||
struct sockaddr_in sin;
|
||||
const char *fingerprint;
|
||||
LIBSSH2_SESSION *session;
|
||||
char *username=(char *)"username";
|
||||
char *password=(char *)"password";
|
||||
char *sftppath=(char *)"/tmp/sftp_mkdir";
|
||||
const char *username="username";
|
||||
const char *password="password";
|
||||
const char *sftppath="/tmp/sftp_mkdir";
|
||||
int rc;
|
||||
LIBSSH2_SFTP *sftp_session;
|
||||
|
||||
|
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* $Id: sftp_mkdir_nonblock.c,v 1.8 2007/07/31 11:00:29 bagder Exp $
|
||||
* $Id: sftp_mkdir_nonblock.c,v 1.9 2007/08/09 01:10:11 dfandrich Exp $
|
||||
*
|
||||
* Sample showing how to do SFTP non-blocking mkdir.
|
||||
*
|
||||
@@ -42,9 +42,9 @@ int main(int argc, char *argv[])
|
||||
struct sockaddr_in sin;
|
||||
const char *fingerprint;
|
||||
LIBSSH2_SESSION *session;
|
||||
char *username=(char *)"username";
|
||||
char *password=(char *)"password";
|
||||
char *sftppath=(char *)"/tmp/sftp_mkdir_nonblock";
|
||||
const char *username="username";
|
||||
const char *password="password";
|
||||
const char *sftppath="/tmp/sftp_mkdir_nonblock";
|
||||
int rc;
|
||||
LIBSSH2_SFTP *sftp_session;
|
||||
|
||||
|
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* $Id: sftp_nonblock.c,v 1.12 2007/07/31 11:00:29 bagder Exp $
|
||||
* $Id: sftp_nonblock.c,v 1.13 2007/08/09 01:10:11 dfandrich Exp $
|
||||
*
|
||||
* Sample showing how to do SFTP non-blocking transfers.
|
||||
*
|
||||
@@ -45,9 +45,9 @@ int main(int argc, char *argv[])
|
||||
struct sockaddr_in sin;
|
||||
const char *fingerprint;
|
||||
LIBSSH2_SESSION *session;
|
||||
char *username=(char *)"username";
|
||||
char *password=(char *)"password";
|
||||
char *sftppath=(char *)"/tmp/TEST";
|
||||
const char *username="username";
|
||||
const char *password="password";
|
||||
const char *sftppath="/tmp/TEST";
|
||||
int rc;
|
||||
LIBSSH2_SFTP *sftp_session;
|
||||
LIBSSH2_SFTP_HANDLE *sftp_handle;
|
||||
|
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* $Id: sftp_write.c,v 1.7 2007/07/31 11:00:29 bagder Exp $
|
||||
* $Id: sftp_write.c,v 1.8 2007/08/09 01:10:11 dfandrich Exp $
|
||||
*
|
||||
* Sample showing how to do SFTP write transfers.
|
||||
*
|
||||
@@ -42,10 +42,10 @@ int main(int argc, char *argv[])
|
||||
struct sockaddr_in sin;
|
||||
const char *fingerprint;
|
||||
LIBSSH2_SESSION *session;
|
||||
char *username=(char *)"username";
|
||||
char *password=(char *)"password";
|
||||
char *loclfile=(char *)"sftp_write.c";
|
||||
char *sftppath=(char *)"/tmp/TEST";
|
||||
const char *username="username";
|
||||
const char *password="password";
|
||||
const char *loclfile="sftp_write.c";
|
||||
const char *sftppath="/tmp/TEST";
|
||||
int rc;
|
||||
FILE *local;
|
||||
LIBSSH2_SFTP *sftp_session;
|
||||
|
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* $Id: sftp_write_nonblock.c,v 1.9 2007/07/31 11:00:29 bagder Exp $
|
||||
* $Id: sftp_write_nonblock.c,v 1.10 2007/08/09 01:10:11 dfandrich Exp $
|
||||
*
|
||||
* Sample showing how to do SFTP non-blocking write transfers.
|
||||
*
|
||||
@@ -42,10 +42,10 @@ int main(int argc, char *argv[])
|
||||
struct sockaddr_in sin;
|
||||
const char *fingerprint;
|
||||
LIBSSH2_SESSION *session;
|
||||
char *username=(char *)"username";
|
||||
char *password=(char *)"password";
|
||||
char *loclfile=(char *)"sftp_write_nonblock.c";
|
||||
char *sftppath=(char *)"/tmp/sftp_write_nonblock.c";
|
||||
const char *username="username";
|
||||
const char *password="password";
|
||||
const char *loclfile="sftp_write_nonblock.c";
|
||||
const char *sftppath="/tmp/sftp_write_nonblock.c";
|
||||
int rc;
|
||||
FILE *local;
|
||||
LIBSSH2_SFTP *sftp_session;
|
||||
|
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* $Id: sftpdir.c,v 1.8 2007/07/31 11:00:29 bagder Exp $
|
||||
* $Id: sftpdir.c,v 1.9 2007/08/09 01:10:11 dfandrich Exp $
|
||||
*
|
||||
* Sample doing an SFTP directory listing.
|
||||
*
|
||||
@@ -42,9 +42,9 @@ int main(int argc, char *argv[])
|
||||
struct sockaddr_in sin;
|
||||
const char *fingerprint;
|
||||
LIBSSH2_SESSION *session;
|
||||
char *username=(char *)"username";
|
||||
char *password=(char *)"password";
|
||||
char *sftppath=(char *)"/tmp/secretdir";
|
||||
const char *username="username";
|
||||
const char *password="password";
|
||||
const char *sftppath="/tmp/secretdir";
|
||||
int rc;
|
||||
LIBSSH2_SFTP *sftp_session;
|
||||
LIBSSH2_SFTP_HANDLE *sftp_handle;
|
||||
|
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* $Id: sftpdir_nonblock.c,v 1.9 2007/07/31 11:00:29 bagder Exp $
|
||||
* $Id: sftpdir_nonblock.c,v 1.10 2007/08/09 01:10:11 dfandrich Exp $
|
||||
*
|
||||
* Sample doing an SFTP directory listing.
|
||||
*
|
||||
@@ -42,9 +42,9 @@ int main(int argc, char *argv[])
|
||||
struct sockaddr_in sin;
|
||||
const char *fingerprint;
|
||||
LIBSSH2_SESSION *session;
|
||||
char *username=(char *)"username";
|
||||
char *password=(char *)"password";
|
||||
char *sftppath=(char *)"/tmp/secretdir";
|
||||
const char *username="username";
|
||||
const char *password="password";
|
||||
const char *sftppath="/tmp/secretdir";
|
||||
int rc;
|
||||
LIBSSH2_SFTP *sftp_session;
|
||||
LIBSSH2_SFTP_HANDLE *sftp_handle;
|
||||
|
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* $Id: ssh2.c,v 1.16 2007/08/03 15:08:28 jehousley Exp $
|
||||
* $Id: ssh2.c,v 1.17 2007/08/09 01:10:11 dfandrich Exp $
|
||||
*
|
||||
* Sample showing how to do SSH2 connect.
|
||||
*
|
||||
@@ -36,10 +36,10 @@
|
||||
#include <ctype.h>
|
||||
|
||||
|
||||
char *keyfile1=(char *)"~/.ssh/id_rsa.pub";
|
||||
char *keyfile2=(char *)"~/.ssh/id_rsa";
|
||||
char *username=(char *)"username";
|
||||
char *password=(char *)"password";
|
||||
const char *keyfile1="~/.ssh/id_rsa.pub";
|
||||
const char *keyfile2="~/.ssh/id_rsa";
|
||||
const char *username="username";
|
||||
const char *password="password";
|
||||
|
||||
|
||||
static void kbd_callback(const char *name, int name_len,
|
||||
@@ -189,12 +189,12 @@ int main(int argc, char *argv[])
|
||||
/* Some environment variables may be set,
|
||||
* It's up to the server which ones it'll allow though
|
||||
*/
|
||||
libssh2_channel_setenv(channel, (char *)"FOO", (char *)"bar");
|
||||
libssh2_channel_setenv(channel, "FOO", "bar");
|
||||
|
||||
/* Request a terminal with 'vanilla' terminal emulation
|
||||
* See /etc/termcap for more options
|
||||
*/
|
||||
if (libssh2_channel_request_pty(channel, (char *)"vanilla")) {
|
||||
if (libssh2_channel_request_pty(channel, "vanilla")) {
|
||||
fprintf(stderr, "Failed requesting pty\n");
|
||||
goto skip_shell;
|
||||
}
|
||||
|
@@ -72,19 +72,22 @@ typedef unsigned int uint32_t;
|
||||
#if defined(LIBSSH2_WIN32) && defined(_MSC_VER) && (_MSC_VER <= 1400)
|
||||
typedef unsigned __int64 libssh2_uint64_t;
|
||||
typedef __int64 libssh2_int64_t;
|
||||
typedef long ssize_t;
|
||||
typedef unsigned int uint32_t;
|
||||
#ifndef _SSIZE_T_DEFINED
|
||||
typedef int ssize_t;
|
||||
#define _SSIZE_T_DEFINED
|
||||
#endif
|
||||
#else
|
||||
typedef unsigned long long libssh2_uint64_t;
|
||||
typedef long long libssh2_int64_t;
|
||||
#endif
|
||||
|
||||
#define LIBSSH2_VERSION "0.16.0-CVS"
|
||||
#define LIBSSH2_VERSION "0.18.0-CVS"
|
||||
|
||||
/* The numeric version number is also available "in parts" by using these
|
||||
defines: */
|
||||
#define LIBSSH2_VERSION_MAJOR 0
|
||||
#define LIBSSH2_VERSION_MINOR 16
|
||||
#define LIBSSH2_VERSION_MINOR 18
|
||||
#define LIBSSH2_VERSION_PATCH 0
|
||||
|
||||
/* This is the numeric version of the libssh2 version number, meant for easier
|
||||
@@ -102,7 +105,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 0x001000
|
||||
#define LIBSSH2_VERSION_NUM 0x001200
|
||||
|
||||
/*
|
||||
* This is the date and time when the full source package was created. The
|
||||
@@ -306,7 +309,7 @@ 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 int libssh2_session_startup(LIBSSH2_SESSION *session, int socket);
|
||||
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_free(LIBSSH2_SESSION *session);
|
||||
@@ -380,7 +383,7 @@ LIBSSH2_API int libssh2_channel_forward_cancel(LIBSSH2_LISTENER *listener);
|
||||
|
||||
LIBSSH2_API LIBSSH2_CHANNEL *libssh2_channel_forward_accept(LIBSSH2_LISTENER *listener);
|
||||
|
||||
LIBSSH2_API int libssh2_channel_setenv_ex(LIBSSH2_CHANNEL *channel, char *varname, unsigned int varname_len, const char *value, unsigned int value_len);
|
||||
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_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);
|
||||
|
@@ -5,7 +5,7 @@
|
||||
##
|
||||
## Comments to: Guenter Knauf <eflash@gmx.net>
|
||||
##
|
||||
## $Id: Makefile.netware,v 1.7 2007/07/15 20:34:33 gknauf Exp $
|
||||
## $Id: Makefile.netware,v 1.8 2007/08/08 16:32:42 gknauf Exp $
|
||||
#
|
||||
#########################################################################
|
||||
|
||||
@@ -131,7 +131,7 @@ SDK_CLIB = $(NDK_ROOT)/nwsdk
|
||||
SDK_LIBC = $(NDK_ROOT)/libc
|
||||
SNPRINTF = $(NDKBASE)/snprintf
|
||||
|
||||
INCLUDES = -I.. -I../../include
|
||||
INCLUDES = -I. -I../../include
|
||||
|
||||
LDLIBS =
|
||||
|
||||
@@ -188,7 +188,7 @@ vpath %.c $(SAMPLES)
|
||||
|
||||
all: prebuild $(TARGETS)
|
||||
|
||||
prebuild: $(OBJDIR) $(OBJDIR)/version.inc
|
||||
prebuild: $(OBJDIR) $(OBJDIR)/version.inc config.h
|
||||
|
||||
$(OBJDIR)/%.o: %.c
|
||||
# @echo Compiling $<
|
||||
@@ -284,6 +284,130 @@ endif
|
||||
@echo $(DL)output $(notdir $(@:.def=.nlm))$(DL) >> $@
|
||||
endif
|
||||
|
||||
config.h: Makefile.netware
|
||||
@echo Creating $@
|
||||
@echo $(DL)/* $@ for NetWare target.$(DL) > $@
|
||||
@echo $(DL)** Do not edit this file - it is created by make!$(DL) >> $@
|
||||
@echo $(DL)** All your changes will be lost!!$(DL) >> $@
|
||||
@echo $(DL)*/$(DL) >> $@
|
||||
@echo $(DL)#define VERSION "$(LIBSSH2_VERSION_STR)"$(DL) >> $@
|
||||
@echo $(DL)#define PACKAGE_BUGREPORT "http://sourceforge.net/projects/libssh2"$(DL) >> $@
|
||||
ifeq ($(LIBARCH),CLIB)
|
||||
@echo $(DL)#define OS "i586-pc-clib-NetWare"$(DL) >> $@
|
||||
@echo $(DL)#define NETDB_USE_INTERNET 1$(DL) >> $@
|
||||
@echo $(DL)#define HAVE_STRICMP 1$(DL) >> $@
|
||||
@echo $(DL)#define socklen_t int$(DL) >> $@
|
||||
@echo $(DL)#define sleep(s) delay(1000 * s)$(DL) >> $@
|
||||
else
|
||||
@echo $(DL)#define OS "i586-pc-libc-NetWare"$(DL) >> $@
|
||||
@echo $(DL)#define HAVE_DLFCN_H 1$(DL) >> $@
|
||||
@echo $(DL)#define HAVE_DLOPEN 1$(DL) >> $@
|
||||
@echo $(DL)#define HAVE_FTRUNCATE 1$(DL) >> $@
|
||||
@echo $(DL)#define HAVE_GETTIMEOFDAY 1$(DL) >> $@
|
||||
@echo $(DL)#define HAVE_INET_PTON 1$(DL) >> $@
|
||||
@echo $(DL)#define HAVE_INTTYPES_H 1$(DL) >> $@
|
||||
@echo $(DL)#define HAVE_LIMITS_H 1$(DL) >> $@
|
||||
@echo $(DL)#define HAVE_LONGLONG 1$(DL) >> $@
|
||||
@echo $(DL)#define HAVE_STDINT_H 1$(DL) >> $@
|
||||
@echo $(DL)#define HAVE_STRCASECMP 1$(DL) >> $@
|
||||
@echo $(DL)#define HAVE_STRLCAT 1$(DL) >> $@
|
||||
@echo $(DL)#define HAVE_STRLCPY 1$(DL) >> $@
|
||||
@echo $(DL)#define HAVE_STRTOLL 1$(DL) >> $@
|
||||
@echo $(DL)#define HAVE_SYS_PARAM_H 1$(DL) >> $@
|
||||
@echo $(DL)#define HAVE_SYS_SELECT_H 1$(DL) >> $@
|
||||
@echo $(DL)#define HAVE_TERMIOS_H 1$(DL) >> $@
|
||||
@echo $(DL)#define HAVE_AF_INET6 1$(DL) >> $@
|
||||
@echo $(DL)#define HAVE_PF_INET6 1$(DL) >> $@
|
||||
@echo $(DL)#define HAVE_STRUCT_IN6_ADDR 1$(DL) >> $@
|
||||
@echo $(DL)#define HAVE_STRUCT_SOCKADDR_IN6 1$(DL) >> $@
|
||||
@echo $(DL)#define SIZEOF_STRUCT_IN6_ADDR 16$(DL) >> $@
|
||||
ifdef ENABLE_IPV6
|
||||
@echo $(DL)#define ENABLE_IPV6 1$(DL) >> $@
|
||||
endif
|
||||
endif
|
||||
@echo $(DL)#define HAVE_ARPA_INET_H 1$(DL) >> $@
|
||||
@echo $(DL)#define HAVE_ASSERT_H 1$(DL) >> $@
|
||||
@echo $(DL)#define HAVE_CTYPE_H 1$(DL) >> $@
|
||||
@echo $(DL)#define HAVE_ERR_H 1$(DL) >> $@
|
||||
@echo $(DL)#define HAVE_ERRNO_H 1$(DL) >> $@
|
||||
@echo $(DL)#define HAVE_FCNTL_H 1$(DL) >> $@
|
||||
@echo $(DL)#define HAVE_FIONBIO 1$(DL) >> $@
|
||||
@echo $(DL)#define HAVE_GETHOSTBYADDR 1$(DL) >> $@
|
||||
@echo $(DL)#define HAVE_GETHOSTBYNAME 1$(DL) >> $@
|
||||
@echo $(DL)#define HAVE_GETPROTOBYNAME 1$(DL) >> $@
|
||||
@echo $(DL)#define HAVE_GMTIME_R 1$(DL) >> $@
|
||||
@echo $(DL)#define HAVE_INET_ADDR 1$(DL) >> $@
|
||||
@echo $(DL)#define HAVE_INET_NTOA 1$(DL) >> $@
|
||||
@echo $(DL)#define HAVE_LL 1$(DL) >> $@
|
||||
@echo $(DL)#define HAVE_LOCALTIME_R 1$(DL) >> $@
|
||||
@echo $(DL)#define HAVE_MALLOC_H 1$(DL) >> $@
|
||||
@echo $(DL)#define HAVE_NETINET_IN_H 1$(DL) >> $@
|
||||
@echo $(DL)#define HAVE_SELECT 1$(DL) >> $@
|
||||
@echo $(DL)#define HAVE_SETJMP_H 1$(DL) >> $@
|
||||
@echo $(DL)#define HAVE_SIGNAL 1$(DL) >> $@
|
||||
@echo $(DL)#define HAVE_SIGNAL_H 1$(DL) >> $@
|
||||
@echo $(DL)#define HAVE_SIG_ATOMIC_T 1$(DL) >> $@
|
||||
@echo $(DL)#define HAVE_SOCKET 1$(DL) >> $@
|
||||
@echo $(DL)#define HAVE_STDLIB_H 1$(DL) >> $@
|
||||
@echo $(DL)#define HAVE_STRDUP 1$(DL) >> $@
|
||||
@echo $(DL)#define HAVE_STRFTIME 1$(DL) >> $@
|
||||
@echo $(DL)#define HAVE_STRING_H 1$(DL) >> $@
|
||||
@echo $(DL)#define HAVE_STRSTR 1$(DL) >> $@
|
||||
@echo $(DL)#define HAVE_STRUCT_ADDRINFO 1$(DL) >> $@
|
||||
@echo $(DL)#define HAVE_STRUCT_TIMEVAL 1$(DL) >> $@
|
||||
@echo $(DL)#define HAVE_SYS_IOCTL_H 1$(DL) >> $@
|
||||
@echo $(DL)#define HAVE_SYS_STAT_H 1$(DL) >> $@
|
||||
@echo $(DL)#define HAVE_SYS_TIME_H 1$(DL) >> $@
|
||||
@echo $(DL)#define HAVE_TIME_H 1$(DL) >> $@
|
||||
@echo $(DL)#define HAVE_UNAME 1$(DL) >> $@
|
||||
@echo $(DL)#define HAVE_UNISTD_H 1$(DL) >> $@
|
||||
@echo $(DL)#define HAVE_UTIME 1$(DL) >> $@
|
||||
@echo $(DL)#define HAVE_UTIME_H 1$(DL) >> $@
|
||||
@echo $(DL)#define RETSIGTYPE void$(DL) >> $@
|
||||
@echo $(DL)#define SIZEOF_STRUCT_IN_ADDR 4$(DL) >> $@
|
||||
@echo $(DL)#define STDC_HEADERS 1$(DL) >> $@
|
||||
@echo $(DL)#define TIME_WITH_SYS_TIME 1$(DL) >> $@
|
||||
@echo $(DL)#define USE_SSLEAY 1$(DL) >> $@
|
||||
@echo $(DL)#define USE_OPENSSL 1$(DL) >> $@
|
||||
@echo $(DL)#define HAVE_OPENSSL_X509_H 1$(DL) >> $@
|
||||
@echo $(DL)#define HAVE_OPENSSL_SSL_H 1$(DL) >> $@
|
||||
@echo $(DL)#define HAVE_OPENSSL_RSA_H 1$(DL) >> $@
|
||||
@echo $(DL)#define HAVE_OPENSSL_PEM_H 1$(DL) >> $@
|
||||
@echo $(DL)#define HAVE_OPENSSL_ERR_H 1$(DL) >> $@
|
||||
@echo $(DL)#define HAVE_OPENSSL_CRYPTO_H 1$(DL) >> $@
|
||||
@echo $(DL)#define HAVE_OPENSSL_ENGINE_H 1$(DL) >> $@
|
||||
@echo $(DL)#define HAVE_O_NONBLOCK 1$(DL) >> $@
|
||||
@echo $(DL)#define HAVE_LIBSSL 1$(DL) >> $@
|
||||
@echo $(DL)#define HAVE_LIBCRYPTO 1$(DL) >> $@
|
||||
@echo $(DL)#define OPENSSL_NO_KRB5 1$(DL) >> $@
|
||||
ifdef WITH_ZLIB
|
||||
@echo $(DL)#define HAVE_ZLIB_H 1$(DL) >> $@
|
||||
@echo $(DL)#define HAVE_LIBZ 1$(DL) >> $@
|
||||
@echo $(DL)#define LIBSSH2_HAVE_ZLIB 1$(DL) >> $@
|
||||
endif
|
||||
ifdef NW_WINSOCK
|
||||
@echo $(DL)#define HAVE_CLOSESOCKET 1$(DL) >> $@
|
||||
else
|
||||
@echo $(DL)#define HAVE_SYS_TYPES_H 1$(DL) >> $@
|
||||
@echo $(DL)#define HAVE_SYS_SOCKET_H 1$(DL) >> $@
|
||||
@echo $(DL)#define HAVE_SYS_SOCKIO_H 1$(DL) >> $@
|
||||
@echo $(DL)#define HAVE_NETDB_H 1$(DL) >> $@
|
||||
endif
|
||||
ifdef OLD_NOVELLSDK
|
||||
@echo $(DL)#define socklen_t int$(DL) >> $@
|
||||
endif
|
||||
@echo $(DL)#define LIBSSH2_DH_GEX_NEW 1$(DL) >> $@
|
||||
ifeq ($(DB),DEBUG)
|
||||
@echo $(DL)#define LIBSSH2_DEBUG_CONNECTION 1$(DL) >> $@
|
||||
@echo $(DL)#define LIBSSH2_DEBUG_ERRORS 1$(DL) >> $@
|
||||
@echo $(DL)#define LIBSSH2_DEBUG_KEX 1$(DL) >> $@
|
||||
@echo $(DL)#define LIBSSH2_DEBUG_PUBLICKEY 1$(DL) >> $@
|
||||
@echo $(DL)#define LIBSSH2_DEBUG_SCP 1$(DL) >> $@
|
||||
@echo $(DL)#define LIBSSH2_DEBUG_SFTP 1$(DL) >> $@
|
||||
@echo $(DL)#define LIBSSH2_DEBUG_TRANSPORT 1$(DL) >> $@
|
||||
@echo $(DL)#define LIBSSH2_DEBUG_USERAUTH 1$(DL) >> $@
|
||||
endif
|
||||
|
||||
help: $(OBJDIR)/version.inc
|
||||
@echo $(DL)===========================================================$(DL)
|
||||
@echo $(DL)OpenSSL path = $(OPENSSL_PATH)$(DL)
|
||||
|
920
src/channel.c
920
src/channel.c
File diff suppressed because it is too large
Load Diff
74
src/comp.c
74
src/comp.c
@@ -47,15 +47,15 @@
|
||||
/* {{{ libssh2_comp_method_none_comp
|
||||
* Minimalist compression: Absolutely none
|
||||
*/
|
||||
static int libssh2_comp_method_none_comp(LIBSSH2_SESSION *session,
|
||||
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)
|
||||
unsigned long src_len, void **abstract)
|
||||
{
|
||||
(void) session;
|
||||
(void) compress;
|
||||
@@ -68,6 +68,7 @@ static int libssh2_comp_method_none_comp(LIBSSH2_SESSION *session,
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* }}} */
|
||||
|
||||
static const LIBSSH2_COMP_METHOD libssh2_comp_method_none = {
|
||||
@@ -87,32 +88,39 @@ static const LIBSSH2_COMP_METHOD libssh2_comp_method_none = {
|
||||
* Deal...
|
||||
*/
|
||||
|
||||
static voidpf libssh2_comp_method_zlib_alloc(voidpf opaque, uInt items, uInt size)
|
||||
static voidpf
|
||||
libssh2_comp_method_zlib_alloc(voidpf opaque, uInt items, uInt size)
|
||||
{
|
||||
LIBSSH2_SESSION *session = (LIBSSH2_SESSION *) opaque;
|
||||
|
||||
return (voidpf) LIBSSH2_ALLOC(session, items * size);
|
||||
}
|
||||
|
||||
static void libssh2_comp_method_zlib_free(voidpf opaque, voidpf address)
|
||||
static void
|
||||
libssh2_comp_method_zlib_free(voidpf opaque, voidpf address)
|
||||
{
|
||||
LIBSSH2_SESSION *session = (LIBSSH2_SESSION *) opaque;
|
||||
|
||||
LIBSSH2_FREE(session, address);
|
||||
}
|
||||
|
||||
/* }}} */
|
||||
|
||||
/* {{{ 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)
|
||||
static int
|
||||
libssh2_comp_method_zlib_init(LIBSSH2_SESSION * session, int compress,
|
||||
void **abstract)
|
||||
{
|
||||
z_stream *strm;
|
||||
int status;
|
||||
|
||||
strm = LIBSSH2_ALLOC(session, sizeof(z_stream));
|
||||
if (!strm) {
|
||||
libssh2_error(session, LIBSSH2_ERROR_ALLOC, "Unable to allocate memory for zlib compression/decompression", 0);
|
||||
libssh2_error(session, LIBSSH2_ERROR_ALLOC,
|
||||
"Unable to allocate memory for zlib compression/decompression",
|
||||
0);
|
||||
return -1;
|
||||
}
|
||||
memset(strm, 0, sizeof(z_stream));
|
||||
@@ -136,20 +144,21 @@ static int libssh2_comp_method_zlib_init(LIBSSH2_SESSION *session, int compress,
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* }}} */
|
||||
|
||||
/* {{{ libssh2_comp_method_zlib_comp
|
||||
* zlib, a compression standard for all occasions
|
||||
*/
|
||||
static int libssh2_comp_method_zlib_comp(LIBSSH2_SESSION *session,
|
||||
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)
|
||||
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
|
||||
@@ -173,7 +182,9 @@ static int libssh2_comp_method_zlib_comp(LIBSSH2_SESSION *session,
|
||||
out = (char *) strm->next_out;
|
||||
strm->avail_out = out_maxlen;
|
||||
if (!strm->next_out) {
|
||||
libssh2_error(session, LIBSSH2_ERROR_ALLOC, "Unable to allocate compression/decompression buffer", 0);
|
||||
libssh2_error(session, LIBSSH2_ERROR_ALLOC,
|
||||
"Unable to allocate compression/decompression buffer",
|
||||
0);
|
||||
return -1;
|
||||
}
|
||||
while (strm->avail_in) {
|
||||
@@ -185,7 +196,8 @@ static int libssh2_comp_method_zlib_comp(LIBSSH2_SESSION *session,
|
||||
status = inflate(strm, Z_PARTIAL_FLUSH);
|
||||
}
|
||||
if (status != Z_OK) {
|
||||
libssh2_error(session, LIBSSH2_ERROR_ZLIB, "compress/decompression failure", 0);
|
||||
libssh2_error(session, LIBSSH2_ERROR_ZLIB,
|
||||
"compress/decompression failure", 0);
|
||||
LIBSSH2_FREE(session, out);
|
||||
return -1;
|
||||
}
|
||||
@@ -193,10 +205,10 @@ static int libssh2_comp_method_zlib_comp(LIBSSH2_SESSION *session,
|
||||
unsigned long out_ofs = out_maxlen - strm->avail_out;
|
||||
char *newout;
|
||||
|
||||
out_maxlen += compress ? (strm->avail_in + 4) : (2 * strm->avail_in);
|
||||
out_maxlen +=
|
||||
compress ? (strm->avail_in + 4) : (2 * strm->avail_in);
|
||||
|
||||
if ((out_maxlen > (int)payload_limit) &&
|
||||
!compress && limiter++) {
|
||||
if ((out_maxlen > (int) payload_limit) && !compress && limiter++) {
|
||||
libssh2_error(session, LIBSSH2_ERROR_ZLIB,
|
||||
"Excessive growth in decompression phase", 0);
|
||||
LIBSSH2_FREE(session, out);
|
||||
@@ -205,14 +217,18 @@ static int libssh2_comp_method_zlib_comp(LIBSSH2_SESSION *session,
|
||||
|
||||
newout = LIBSSH2_REALLOC(session, out, out_maxlen);
|
||||
if (!newout) {
|
||||
libssh2_error(session, LIBSSH2_ERROR_ALLOC, "Unable to expand compress/decompression buffer", 0);
|
||||
libssh2_error(session, LIBSSH2_ERROR_ALLOC,
|
||||
"Unable to expand compress/decompression buffer",
|
||||
0);
|
||||
LIBSSH2_FREE(session, out);
|
||||
return -1;
|
||||
}
|
||||
out = newout;
|
||||
strm->next_out = (unsigned char *) out + out_ofs;
|
||||
strm->avail_out += compress ? (strm->avail_in + 4) : (2 * strm->avail_in);
|
||||
} else while (!strm->avail_out) {
|
||||
strm->avail_out +=
|
||||
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
|
||||
*/
|
||||
@@ -220,7 +236,9 @@ static int libssh2_comp_method_zlib_comp(LIBSSH2_SESSION *session,
|
||||
char *newout;
|
||||
|
||||
if (out_maxlen >= (int) payload_limit) {
|
||||
libssh2_error(session, LIBSSH2_ERROR_ZLIB, "Excessive growth in decompression phase", 0);
|
||||
libssh2_error(session, LIBSSH2_ERROR_ZLIB,
|
||||
"Excessive growth in decompression phase",
|
||||
0);
|
||||
LIBSSH2_FREE(session, out);
|
||||
return -1;
|
||||
}
|
||||
@@ -234,7 +252,9 @@ static int libssh2_comp_method_zlib_comp(LIBSSH2_SESSION *session,
|
||||
|
||||
newout = LIBSSH2_REALLOC(session, out, out_maxlen);
|
||||
if (!newout) {
|
||||
libssh2_error(session, LIBSSH2_ERROR_ALLOC, "Unable to expand final compress/decompress buffer", 0);
|
||||
libssh2_error(session, LIBSSH2_ERROR_ALLOC,
|
||||
"Unable to expand final compress/decompress buffer",
|
||||
0);
|
||||
LIBSSH2_FREE(session, out);
|
||||
return -1;
|
||||
}
|
||||
@@ -248,7 +268,8 @@ static int libssh2_comp_method_zlib_comp(LIBSSH2_SESSION *session,
|
||||
status = inflate(strm, Z_PARTIAL_FLUSH);
|
||||
}
|
||||
if (status != Z_OK) {
|
||||
libssh2_error(session, LIBSSH2_ERROR_ZLIB, "compress/decompression failure", 0);
|
||||
libssh2_error(session, LIBSSH2_ERROR_ZLIB,
|
||||
"compress/decompression failure", 0);
|
||||
LIBSSH2_FREE(session, out);
|
||||
return -1;
|
||||
}
|
||||
@@ -261,12 +282,15 @@ static int libssh2_comp_method_zlib_comp(LIBSSH2_SESSION *session,
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* }}} */
|
||||
|
||||
/* {{{ 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)
|
||||
static int
|
||||
libssh2_comp_method_zlib_dtor(LIBSSH2_SESSION * session, int compress,
|
||||
void **abstract)
|
||||
{
|
||||
z_stream *strm = *abstract;
|
||||
|
||||
@@ -286,6 +310,7 @@ static int libssh2_comp_method_zlib_dtor(LIBSSH2_SESSION *session, int compress,
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* }}} */
|
||||
|
||||
static const LIBSSH2_COMP_METHOD libssh2_comp_method_zlib = {
|
||||
@@ -308,7 +333,8 @@ static const LIBSSH2_COMP_METHOD *_libssh2_comp_methods[] = {
|
||||
NULL
|
||||
};
|
||||
|
||||
const LIBSSH2_COMP_METHOD **libssh2_comp_methods(void) {
|
||||
const LIBSSH2_COMP_METHOD **
|
||||
libssh2_comp_methods(void)
|
||||
{
|
||||
return _libssh2_comp_methods;
|
||||
}
|
||||
|
||||
|
31
src/crypt.c
31
src/crypt.c
@@ -41,11 +41,14 @@
|
||||
/* {{{ libssh2_crypt_none_crypt
|
||||
* Minimalist cipher: VERY secure *wink*
|
||||
*/
|
||||
static int libssh2_crypt_none_crypt(LIBSSH2_SESSION *session, unsigned char *buf, void **abstract)
|
||||
static int
|
||||
libssh2_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 = {
|
||||
@@ -60,13 +63,15 @@ static const LIBSSH2_CRYPT_METHOD libssh2_crypt_method_none = {
|
||||
};
|
||||
#endif /* LIBSSH2_CRYPT_NONE */
|
||||
|
||||
struct crypt_ctx {
|
||||
struct crypt_ctx
|
||||
{
|
||||
int encrypt;
|
||||
_libssh2_cipher_type(algo);
|
||||
_libssh2_cipher_ctx h;
|
||||
};
|
||||
|
||||
static int _libssh2_init (LIBSSH2_SESSION *session,
|
||||
static int
|
||||
_libssh2_init(LIBSSH2_SESSION * session,
|
||||
const LIBSSH2_CRYPT_METHOD * method,
|
||||
unsigned char *iv, int *free_iv,
|
||||
unsigned char *secret, int *free_secret,
|
||||
@@ -79,8 +84,7 @@ static int _libssh2_init (LIBSSH2_SESSION *session,
|
||||
}
|
||||
ctx->encrypt = encrypt;
|
||||
ctx->algo = method->algo;
|
||||
if (_libssh2_cipher_init (&ctx->h, ctx->algo, iv, secret, encrypt))
|
||||
{
|
||||
if (_libssh2_cipher_init(&ctx->h, ctx->algo, iv, secret, encrypt)) {
|
||||
LIBSSH2_FREE(session, ctx);
|
||||
return -1;
|
||||
}
|
||||
@@ -90,15 +94,17 @@ static int _libssh2_init (LIBSSH2_SESSION *session,
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int _libssh2_encrypt(LIBSSH2_SESSION *session, unsigned char *block, void **abstract)
|
||||
static int
|
||||
_libssh2_encrypt(LIBSSH2_SESSION * session, unsigned char *block,
|
||||
void **abstract)
|
||||
{
|
||||
struct crypt_ctx *cctx = *(struct crypt_ctx **) abstract;
|
||||
(void) session;
|
||||
return _libssh2_cipher_crypt(&cctx->h, cctx->algo,
|
||||
cctx->encrypt, block);
|
||||
return _libssh2_cipher_crypt(&cctx->h, cctx->algo, cctx->encrypt, block);
|
||||
}
|
||||
|
||||
static int _libssh2_dtor(LIBSSH2_SESSION *session, void **abstract)
|
||||
static int
|
||||
_libssh2_dtor(LIBSSH2_SESSION * session, void **abstract)
|
||||
{
|
||||
struct crypt_ctx **cctx = (struct crypt_ctx **) abstract;
|
||||
if (cctx && *cctx) {
|
||||
@@ -147,7 +153,8 @@ static const LIBSSH2_CRYPT_METHOD libssh2_crypt_method_aes256_cbc = {
|
||||
};
|
||||
|
||||
/* rijndael-cbc@lysator.liu.se == aes256-cbc */
|
||||
static const LIBSSH2_CRYPT_METHOD libssh2_crypt_method_rijndael_cbc_lysator_liu_se = {
|
||||
static const LIBSSH2_CRYPT_METHOD
|
||||
libssh2_crypt_method_rijndael_cbc_lysator_liu_se = {
|
||||
"rijndael-cbc@lysator.liu.se",
|
||||
16, /* blocksize */
|
||||
16, /* initial value length */
|
||||
@@ -242,6 +249,8 @@ static const LIBSSH2_CRYPT_METHOD *_libssh2_crypt_methods[] = {
|
||||
};
|
||||
|
||||
/* Expose to kex.c */
|
||||
const LIBSSH2_CRYPT_METHOD **libssh2_crypt_methods(void) {
|
||||
const LIBSSH2_CRYPT_METHOD **
|
||||
libssh2_crypt_methods(void)
|
||||
{
|
||||
return _libssh2_crypt_methods;
|
||||
}
|
||||
|
130
src/hostkey.c
130
src/hostkey.c
@@ -47,7 +47,8 @@
|
||||
* ssh-rsa *
|
||||
*********** */
|
||||
|
||||
static int libssh2_hostkey_method_ssh_rsa_dtor(LIBSSH2_SESSION *session, void **abstract);
|
||||
static int libssh2_hostkey_method_ssh_rsa_dtor(LIBSSH2_SESSION * session,
|
||||
void **abstract);
|
||||
|
||||
/* {{{ libssh2_hostkey_method_ssh_rsa_init
|
||||
* Initialize the server hostkey working area with e/n pair
|
||||
@@ -81,9 +82,12 @@ libssh2_hostkey_method_ssh_rsa_init(LIBSSH2_SESSION *session,
|
||||
e_len = libssh2_ntohu32(s);
|
||||
s += 4;
|
||||
|
||||
e = s; s += e_len;
|
||||
n_len = libssh2_ntohu32(s); s += 4;
|
||||
n = s; s += n_len;
|
||||
e = s;
|
||||
s += e_len;
|
||||
n_len = libssh2_ntohu32(s);
|
||||
s += 4;
|
||||
n = s;
|
||||
s += n_len;
|
||||
|
||||
if (_libssh2_rsa_new(&rsactx, e, e_len, n, n_len, NULL, 0,
|
||||
NULL, 0, NULL, 0, NULL, 0, NULL, 0, NULL, 0))
|
||||
@@ -93,13 +97,17 @@ libssh2_hostkey_method_ssh_rsa_init(LIBSSH2_SESSION *session,
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* }}} */
|
||||
|
||||
/* {{{ libssh2_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)
|
||||
static int
|
||||
libssh2_hostkey_method_ssh_rsa_initPEM(LIBSSH2_SESSION * session,
|
||||
const char *privkeyfile,
|
||||
unsigned const char *passphrase,
|
||||
void **abstract)
|
||||
{
|
||||
libssh2_rsa_ctx *rsactx;
|
||||
FILE *fp;
|
||||
@@ -125,32 +133,40 @@ static int libssh2_hostkey_method_ssh_rsa_initPEM(LIBSSH2_SESSION *session,
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* }}} */
|
||||
|
||||
/* {{{ libssh2_hostkey_method_ssh_rsa_sign
|
||||
* Verify signature created by remote
|
||||
*/
|
||||
static int libssh2_hostkey_method_ssh_rsa_sig_verify(LIBSSH2_SESSION *session,
|
||||
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)
|
||||
unsigned long m_len, void **abstract)
|
||||
{
|
||||
libssh2_rsa_ctx *rsactx = (libssh2_rsa_ctx *) (*abstract);
|
||||
(void) session;
|
||||
|
||||
/* Skip past keyname_len(4) + keyname(7){"ssh-rsa"} + signature_len(4) */
|
||||
sig += 15; sig_len -= 15;
|
||||
sig += 15;
|
||||
sig_len -= 15;
|
||||
return _libssh2_rsa_sha1_verify(rsactx, sig, sig_len, m, m_len);
|
||||
}
|
||||
|
||||
/* }}} */
|
||||
|
||||
/* {{{ libssh2_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)
|
||||
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)
|
||||
{
|
||||
libssh2_rsa_ctx *rsactx = (libssh2_rsa_ctx *) (*abstract);
|
||||
int ret;
|
||||
@@ -172,13 +188,14 @@ static int libssh2_hostkey_method_ssh_rsa_signv(LIBSSH2_SESSION *session, unsign
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* }}} */
|
||||
|
||||
/* {{{ libssh2_hostkey_method_ssh_rsa_dtor
|
||||
* Shutdown the hostkey
|
||||
*/
|
||||
static int libssh2_hostkey_method_ssh_rsa_dtor(LIBSSH2_SESSION *session,
|
||||
void **abstract)
|
||||
static int
|
||||
libssh2_hostkey_method_ssh_rsa_dtor(LIBSSH2_SESSION * session, void **abstract)
|
||||
{
|
||||
libssh2_rsa_ctx *rsactx = (libssh2_rsa_ctx *) (*abstract);
|
||||
(void) session;
|
||||
@@ -189,6 +206,7 @@ static int libssh2_hostkey_method_ssh_rsa_dtor(LIBSSH2_SESSION *session,
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* }}} */
|
||||
|
||||
static const LIBSSH2_HOSTKEY_METHOD libssh2_hostkey_method_ssh_rsa = {
|
||||
@@ -208,7 +226,8 @@ 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 libssh2_hostkey_method_ssh_dss_dtor(LIBSSH2_SESSION * session,
|
||||
void **abstract);
|
||||
|
||||
/* {{{ libssh2_hostkey_method_ssh_dss_init
|
||||
* Initialize the server hostkey working area with p/q/g/y set
|
||||
@@ -230,33 +249,44 @@ libssh2_hostkey_method_ssh_dss_init(LIBSSH2_SESSION *session,
|
||||
}
|
||||
|
||||
s = hostkey_data;
|
||||
len = libssh2_ntohu32(s); s += 4;
|
||||
len = libssh2_ntohu32(s);
|
||||
s += 4;
|
||||
if (len != 7 || strncmp((char *) s, "ssh-dss", 7) != 0) {
|
||||
return -1;
|
||||
} s += 7;
|
||||
}
|
||||
s += 7;
|
||||
|
||||
p_len = libssh2_ntohu32(s); s += 4;
|
||||
p = s; s += p_len;
|
||||
q_len = libssh2_ntohu32(s); s += 4;
|
||||
q = s; s += q_len;
|
||||
g_len = libssh2_ntohu32(s); s += 4;
|
||||
g = s; s += g_len;
|
||||
y_len = libssh2_ntohu32(s); s += 4;
|
||||
y = s; s += y_len;
|
||||
p_len = libssh2_ntohu32(s);
|
||||
s += 4;
|
||||
p = s;
|
||||
s += p_len;
|
||||
q_len = libssh2_ntohu32(s);
|
||||
s += 4;
|
||||
q = s;
|
||||
s += q_len;
|
||||
g_len = libssh2_ntohu32(s);
|
||||
s += 4;
|
||||
g = s;
|
||||
s += g_len;
|
||||
y_len = libssh2_ntohu32(s);
|
||||
s += 4;
|
||||
y = s;
|
||||
s += y_len;
|
||||
|
||||
_libssh2_dsa_new(&dsactx, p, p_len, q, q_len, g, g_len,
|
||||
y, y_len, NULL, 0);
|
||||
_libssh2_dsa_new(&dsactx, p, p_len, q, q_len, g, g_len, y, y_len, NULL, 0);
|
||||
|
||||
*abstract = dsactx;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* }}} */
|
||||
|
||||
/* {{{ libssh2_hostkey_method_ssh_dss_initPEM
|
||||
* Load a Private Key from a PEM file
|
||||
*/
|
||||
static int libssh2_hostkey_method_ssh_dss_initPEM(LIBSSH2_SESSION *session,
|
||||
static int
|
||||
libssh2_hostkey_method_ssh_dss_initPEM(LIBSSH2_SESSION * session,
|
||||
const char *privkeyfile,
|
||||
unsigned const char *passphrase,
|
||||
void **abstract)
|
||||
@@ -285,31 +315,44 @@ static int libssh2_hostkey_method_ssh_dss_initPEM(LIBSSH2_SESSION *session,
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* }}} */
|
||||
|
||||
/* {{{ 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)
|
||||
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)
|
||||
{
|
||||
libssh2_dsa_ctx *dsactx = (libssh2_dsa_ctx *) (*abstract);
|
||||
|
||||
/* Skip past keyname_len(4) + keyname(7){"ssh-dss"} + signature_len(4) */
|
||||
sig += 15; sig_len -= 15;
|
||||
sig += 15;
|
||||
sig_len -= 15;
|
||||
if (sig_len != 40) {
|
||||
libssh2_error(session, LIBSSH2_ERROR_PROTO, "Invalid DSS signature length", 0);
|
||||
libssh2_error(session, LIBSSH2_ERROR_PROTO,
|
||||
"Invalid DSS signature length", 0);
|
||||
return -1;
|
||||
}
|
||||
return _libssh2_dsa_sha1_verify(dsactx, sig, m, m_len);
|
||||
}
|
||||
|
||||
/* }}} */
|
||||
|
||||
/* {{{ libssh2_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)
|
||||
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)
|
||||
{
|
||||
libssh2_dsa_ctx *dsactx = (libssh2_dsa_ctx *) (*abstract);
|
||||
unsigned char hash[SHA_DIGEST_LENGTH];
|
||||
@@ -330,22 +373,21 @@ static int libssh2_hostkey_method_ssh_dss_signv(LIBSSH2_SESSION *session, unsign
|
||||
}
|
||||
libssh2_sha1_final(ctx, hash);
|
||||
|
||||
if (_libssh2_dsa_sha1_sign(dsactx, hash, SHA_DIGEST_LENGTH,
|
||||
*signature))
|
||||
{
|
||||
if (_libssh2_dsa_sha1_sign(dsactx, hash, SHA_DIGEST_LENGTH, *signature)) {
|
||||
LIBSSH2_FREE(session, *signature);
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* }}} */
|
||||
|
||||
/* {{{ libssh2_hostkey_method_ssh_dss_dtor
|
||||
* Shutdown the hostkey method
|
||||
*/
|
||||
static int libssh2_hostkey_method_ssh_dss_dtor(LIBSSH2_SESSION *session,
|
||||
void **abstract)
|
||||
static int
|
||||
libssh2_hostkey_method_ssh_dss_dtor(LIBSSH2_SESSION * session, void **abstract)
|
||||
{
|
||||
libssh2_dsa_ctx *dsactx = (libssh2_dsa_ctx *) (*abstract);
|
||||
(void) session;
|
||||
@@ -356,6 +398,7 @@ static int libssh2_hostkey_method_ssh_dss_dtor(LIBSSH2_SESSION *session,
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* }}} */
|
||||
|
||||
static const LIBSSH2_HOSTKEY_METHOD libssh2_hostkey_method_ssh_dss = {
|
||||
@@ -380,7 +423,8 @@ static const LIBSSH2_HOSTKEY_METHOD *_libssh2_hostkey_methods[] = {
|
||||
NULL
|
||||
};
|
||||
|
||||
const LIBSSH2_HOSTKEY_METHOD **libssh2_hostkey_methods(void)
|
||||
const LIBSSH2_HOSTKEY_METHOD **
|
||||
libssh2_hostkey_methods(void)
|
||||
{
|
||||
return _libssh2_hostkey_methods;
|
||||
}
|
||||
@@ -391,7 +435,8 @@ const LIBSSH2_HOSTKEY_METHOD **libssh2_hostkey_methods(void)
|
||||
* Length of buffer is determined by hash type
|
||||
* i.e. MD5 == 16, SHA1 == 20
|
||||
*/
|
||||
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)
|
||||
{
|
||||
switch (hash_type) {
|
||||
#if LIBSSH2_MD5
|
||||
@@ -406,6 +451,5 @@ LIBSSH2_API const char *libssh2_hostkey_hash(LIBSSH2_SESSION *session, int hash_
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
/* }}} */
|
||||
|
||||
|
||||
|
@@ -38,7 +38,8 @@
|
||||
#include "libssh2_priv.h"
|
||||
#include <string.h>
|
||||
|
||||
int _libssh2_rsa_new(libssh2_rsa_ctx **rsa,
|
||||
int
|
||||
_libssh2_rsa_new(libssh2_rsa_ctx ** rsa,
|
||||
const unsigned char *edata,
|
||||
unsigned long elen,
|
||||
const unsigned char *ndata,
|
||||
@@ -53,8 +54,7 @@ int _libssh2_rsa_new(libssh2_rsa_ctx **rsa,
|
||||
unsigned long e1len,
|
||||
const unsigned char *e2data,
|
||||
unsigned long e2len,
|
||||
const unsigned char *coeffdata,
|
||||
unsigned long coefflen)
|
||||
const unsigned char *coeffdata, unsigned long coefflen)
|
||||
{
|
||||
int rc;
|
||||
(void) e1data;
|
||||
@@ -72,8 +72,7 @@ int _libssh2_rsa_new(libssh2_rsa_ctx **rsa,
|
||||
rc = gcry_sexp_build(rsa, NULL, "(public-key(rsa(n%b)(e%b)))",
|
||||
nlen, ndata, elen, edata);
|
||||
}
|
||||
if (rc)
|
||||
{
|
||||
if (rc) {
|
||||
*rsa = NULL;
|
||||
return -1;
|
||||
}
|
||||
@@ -81,11 +80,11 @@ int _libssh2_rsa_new(libssh2_rsa_ctx **rsa,
|
||||
return 0;
|
||||
}
|
||||
|
||||
int _libssh2_rsa_sha1_verify(libssh2_rsa_ctx *rsa,
|
||||
int
|
||||
_libssh2_rsa_sha1_verify(libssh2_rsa_ctx * rsa,
|
||||
const unsigned char *sig,
|
||||
unsigned long sig_len,
|
||||
const unsigned char *m,
|
||||
unsigned long m_len)
|
||||
const unsigned char *m, unsigned long m_len)
|
||||
{
|
||||
unsigned char hash[SHA_DIGEST_LENGTH];
|
||||
gcry_sexp_t s_sig, s_hash;
|
||||
@@ -100,8 +99,7 @@ int _libssh2_rsa_sha1_verify(libssh2_rsa_ctx *rsa,
|
||||
return -1;
|
||||
}
|
||||
|
||||
rc = gcry_sexp_build (&s_sig, NULL, "(sig-val(rsa(s %b)))",
|
||||
sig_len, sig);
|
||||
rc = gcry_sexp_build(&s_sig, NULL, "(sig-val(rsa(s %b)))", sig_len, sig);
|
||||
if (rc != 0) {
|
||||
gcry_sexp_release(s_hash);
|
||||
return -1;
|
||||
@@ -114,7 +112,8 @@ int _libssh2_rsa_sha1_verify(libssh2_rsa_ctx *rsa,
|
||||
return (rc == 0) ? 0 : -1;
|
||||
}
|
||||
|
||||
int _libssh2_dsa_new(libssh2_dsa_ctx **dsactx,
|
||||
int
|
||||
_libssh2_dsa_new(libssh2_dsa_ctx ** dsactx,
|
||||
const unsigned char *p,
|
||||
unsigned long p_len,
|
||||
const unsigned char *q,
|
||||
@@ -123,8 +122,7 @@ int _libssh2_dsa_new(libssh2_dsa_ctx **dsactx,
|
||||
unsigned long g_len,
|
||||
const unsigned char *y,
|
||||
unsigned long y_len,
|
||||
const unsigned char *x,
|
||||
unsigned long x_len)
|
||||
const unsigned char *x, unsigned long x_len)
|
||||
{
|
||||
int rc;
|
||||
|
||||
@@ -147,10 +145,10 @@ int _libssh2_dsa_new(libssh2_dsa_ctx **dsactx,
|
||||
return 0;
|
||||
}
|
||||
|
||||
int _libssh2_rsa_new_private (libssh2_rsa_ctx **rsa,
|
||||
int
|
||||
_libssh2_rsa_new_private(libssh2_rsa_ctx ** rsa,
|
||||
LIBSSH2_SESSION * session,
|
||||
FILE *fp,
|
||||
unsigned const char *passphrase)
|
||||
FILE * fp, unsigned const char *passphrase)
|
||||
{
|
||||
char *data, *save_data;
|
||||
unsigned int datalen;
|
||||
@@ -230,8 +228,7 @@ int _libssh2_rsa_new_private (libssh2_rsa_ctx **rsa,
|
||||
}
|
||||
|
||||
if (_libssh2_rsa_new(rsa, e, elen, n, nlen, d, dlen, p, plen,
|
||||
q, qlen, e1, e1len, e2, e2len,
|
||||
coeff, coefflen)) {
|
||||
q, qlen, e1, e1len, e2, e2len, coeff, coefflen)) {
|
||||
ret = -1;
|
||||
goto fail;
|
||||
}
|
||||
@@ -243,10 +240,10 @@ fail:
|
||||
return ret;
|
||||
}
|
||||
|
||||
int _libssh2_dsa_new_private (libssh2_dsa_ctx **dsa,
|
||||
int
|
||||
_libssh2_dsa_new_private(libssh2_dsa_ctx ** dsa,
|
||||
LIBSSH2_SESSION * session,
|
||||
FILE *fp,
|
||||
unsigned const char *passphrase)
|
||||
FILE * fp, unsigned const char *passphrase)
|
||||
{
|
||||
char *data, *save_data;
|
||||
unsigned int datalen;
|
||||
@@ -313,8 +310,7 @@ int _libssh2_dsa_new_private (libssh2_dsa_ctx **dsa,
|
||||
goto fail;
|
||||
}
|
||||
|
||||
if (_libssh2_dsa_new (dsa, p, plen, q, qlen,
|
||||
g, glen, y, ylen, x, xlen)) {
|
||||
if (_libssh2_dsa_new(dsa, p, plen, q, qlen, g, glen, y, ylen, x, xlen)) {
|
||||
ret = -1;
|
||||
goto fail;
|
||||
}
|
||||
@@ -326,12 +322,12 @@ fail:
|
||||
return ret;
|
||||
}
|
||||
|
||||
int _libssh2_rsa_sha1_sign(LIBSSH2_SESSION *session,
|
||||
int
|
||||
_libssh2_rsa_sha1_sign(LIBSSH2_SESSION * session,
|
||||
libssh2_dsa_ctx * rsactx,
|
||||
const unsigned char *hash,
|
||||
unsigned long hash_len,
|
||||
unsigned char **signature,
|
||||
unsigned long *signature_len)
|
||||
unsigned char **signature, unsigned long *signature_len)
|
||||
{
|
||||
gcry_sexp_t sig_sexp;
|
||||
gcry_sexp_t data;
|
||||
@@ -379,10 +375,10 @@ int _libssh2_rsa_sha1_sign(LIBSSH2_SESSION *session,
|
||||
return rc;
|
||||
}
|
||||
|
||||
int _libssh2_dsa_sha1_sign(libssh2_dsa_ctx *dsactx,
|
||||
int
|
||||
_libssh2_dsa_sha1_sign(libssh2_dsa_ctx * dsactx,
|
||||
const unsigned char *hash,
|
||||
unsigned long hash_len,
|
||||
unsigned char *sig)
|
||||
unsigned long hash_len, unsigned char *sig)
|
||||
{
|
||||
unsigned char zhash[SHA_DIGEST_LENGTH + 1];
|
||||
gcry_sexp_t sig_sexp;
|
||||
@@ -398,8 +394,7 @@ int _libssh2_dsa_sha1_sign(libssh2_dsa_ctx *dsactx,
|
||||
memcpy(zhash + 1, hash, hash_len);
|
||||
zhash[0] = 0;
|
||||
|
||||
if (gcry_sexp_build (&data, NULL, "(data (value %b))",
|
||||
hash_len + 1, zhash)) {
|
||||
if (gcry_sexp_build(&data, NULL, "(data (value %b))", hash_len + 1, zhash)) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
@@ -476,10 +471,10 @@ out:
|
||||
return ret;
|
||||
}
|
||||
|
||||
int _libssh2_dsa_sha1_verify(libssh2_dsa_ctx *dsactx,
|
||||
int
|
||||
_libssh2_dsa_sha1_verify(libssh2_dsa_ctx * dsactx,
|
||||
const unsigned char *sig,
|
||||
const unsigned char *m,
|
||||
unsigned long m_len)
|
||||
const unsigned char *m, unsigned long m_len)
|
||||
{
|
||||
unsigned char hash[SHA_DIGEST_LENGTH + 1];
|
||||
gcry_sexp_t s_sig, s_hash;
|
||||
@@ -506,11 +501,10 @@ int _libssh2_dsa_sha1_verify(libssh2_dsa_ctx *dsactx,
|
||||
return (rc == 0) ? 0 : -1;
|
||||
}
|
||||
|
||||
int _libssh2_cipher_init (_libssh2_cipher_ctx *h,
|
||||
int
|
||||
_libssh2_cipher_init(_libssh2_cipher_ctx * h,
|
||||
_libssh2_cipher_type(algo),
|
||||
unsigned char *iv,
|
||||
unsigned char *secret,
|
||||
int encrypt)
|
||||
unsigned char *iv, unsigned char *secret, int encrypt)
|
||||
{
|
||||
int mode = 0, ret;
|
||||
int keylen = gcry_cipher_get_algo_keylen(algo);
|
||||
@@ -544,10 +538,10 @@ int _libssh2_cipher_init (_libssh2_cipher_ctx *h,
|
||||
return 0;
|
||||
}
|
||||
|
||||
int _libssh2_cipher_crypt(_libssh2_cipher_ctx *ctx,
|
||||
int
|
||||
_libssh2_cipher_crypt(_libssh2_cipher_ctx * ctx,
|
||||
_libssh2_cipher_type(algo),
|
||||
int encrypt,
|
||||
unsigned char *block)
|
||||
int encrypt, unsigned char *block)
|
||||
{
|
||||
size_t blklen = gcry_cipher_get_algo_blklen(algo);
|
||||
int ret;
|
||||
@@ -557,11 +551,9 @@ int _libssh2_cipher_crypt(_libssh2_cipher_ctx *ctx,
|
||||
}
|
||||
|
||||
if (encrypt) {
|
||||
ret = gcry_cipher_encrypt (*ctx, block, blklen,
|
||||
block, blklen);
|
||||
ret = gcry_cipher_encrypt(*ctx, block, blklen, block, blklen);
|
||||
} else {
|
||||
ret = gcry_cipher_decrypt (*ctx, block, blklen,
|
||||
block, blklen);
|
||||
ret = gcry_cipher_decrypt(*ctx, block, blklen, block, blklen);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
@@ -108,17 +108,14 @@ int _libssh2_rsa_new(libssh2_rsa_ctx **rsa,
|
||||
unsigned long e1len,
|
||||
const unsigned char *e2data,
|
||||
unsigned long e2len,
|
||||
const unsigned char *coeffdata,
|
||||
unsigned long coefflen);
|
||||
const unsigned char *coeffdata, unsigned long coefflen);
|
||||
int _libssh2_rsa_new_private(libssh2_rsa_ctx ** rsa,
|
||||
LIBSSH2_SESSION * session,
|
||||
FILE *fp,
|
||||
unsigned const char *passphrase);
|
||||
FILE * fp, unsigned const char *passphrase);
|
||||
int _libssh2_rsa_sha1_verify(libssh2_rsa_ctx * rsa,
|
||||
const unsigned char *sig,
|
||||
unsigned long sig_len,
|
||||
const unsigned char *m,
|
||||
unsigned long m_len);
|
||||
const unsigned char *m, unsigned long m_len);
|
||||
int _libssh2_rsa_sha1_sign(LIBSSH2_SESSION * session,
|
||||
libssh2_rsa_ctx * rsactx,
|
||||
const unsigned char *hash,
|
||||
@@ -139,20 +136,16 @@ int _libssh2_dsa_new(libssh2_dsa_ctx **dsa,
|
||||
unsigned long glen,
|
||||
const unsigned char *ydata,
|
||||
unsigned long ylen,
|
||||
const unsigned char *x,
|
||||
unsigned long x_len);
|
||||
const unsigned char *x, unsigned long x_len);
|
||||
int _libssh2_dsa_new_private(libssh2_dsa_ctx ** dsa,
|
||||
LIBSSH2_SESSION * session,
|
||||
FILE *fp,
|
||||
unsigned const char *passphrase);
|
||||
FILE * fp, unsigned const char *passphrase);
|
||||
int _libssh2_dsa_sha1_verify(libssh2_dsa_ctx * dsa,
|
||||
const unsigned char *sig,
|
||||
const unsigned char *m,
|
||||
unsigned long m_len);
|
||||
const unsigned char *m, unsigned long m_len);
|
||||
int _libssh2_dsa_sha1_sign(libssh2_dsa_ctx * dsactx,
|
||||
const unsigned char *hash,
|
||||
unsigned long hash_len,
|
||||
unsigned char *sig);
|
||||
unsigned long hash_len, unsigned char *sig);
|
||||
|
||||
#define _libssh2_dsa_free(dsactx) gcry_sexp_release (dsactx)
|
||||
|
||||
@@ -170,13 +163,11 @@ int _libssh2_dsa_sha1_sign(libssh2_dsa_ctx *dsactx,
|
||||
int _libssh2_cipher_init(_libssh2_cipher_ctx * h,
|
||||
_libssh2_cipher_type(algo),
|
||||
unsigned char *iv,
|
||||
unsigned char *secret,
|
||||
int encrypt);
|
||||
unsigned char *secret, int encrypt);
|
||||
|
||||
int _libssh2_cipher_crypt(_libssh2_cipher_ctx * ctx,
|
||||
_libssh2_cipher_type(algo),
|
||||
int encrypt,
|
||||
unsigned char *block);
|
||||
int encrypt, unsigned char *block);
|
||||
|
||||
#define _libssh2_cipher_dtor(ctx) gcry_cipher_close(*(ctx))
|
||||
|
||||
|
@@ -127,7 +127,8 @@ typedef struct _LIBSSH2_CHANNEL_BRIGADE LIBSSH2_CHANNEL_BRIGADE;
|
||||
|
||||
typedef int libssh2pack_t;
|
||||
|
||||
typedef enum {
|
||||
typedef enum
|
||||
{
|
||||
libssh2_NB_state_idle = 0,
|
||||
libssh2_NB_state_allocated,
|
||||
libssh2_NB_state_created,
|
||||
@@ -144,16 +145,19 @@ typedef enum {
|
||||
libssh2_NB_state_jump3
|
||||
} libssh2_nonblocking_states;
|
||||
|
||||
typedef struct packet_require_state_t {
|
||||
typedef struct packet_require_state_t
|
||||
{
|
||||
libssh2_nonblocking_states state;
|
||||
time_t start;
|
||||
} packet_require_state_t;
|
||||
|
||||
typedef struct packet_requirev_state_t {
|
||||
typedef struct packet_requirev_state_t
|
||||
{
|
||||
time_t start;
|
||||
} packet_requirev_state_t;
|
||||
|
||||
typedef struct kmdhgGPsha1kex_state_t {
|
||||
typedef struct kmdhgGPsha1kex_state_t
|
||||
{
|
||||
libssh2_nonblocking_states state;
|
||||
unsigned char *e_packet;
|
||||
unsigned char *s_packet;
|
||||
@@ -180,7 +184,8 @@ typedef struct kmdhgGPsha1kex_state_t {
|
||||
libssh2_nonblocking_states burn_state;
|
||||
} kmdhgGPsha1kex_state_t;
|
||||
|
||||
typedef struct key_exchange_state_low_t {
|
||||
typedef struct key_exchange_state_low_t
|
||||
{
|
||||
libssh2_nonblocking_states state;
|
||||
packet_require_state_t req_state;
|
||||
kmdhgGPsha1kex_state_t exchange_state;
|
||||
@@ -192,7 +197,8 @@ typedef struct key_exchange_state_low_t {
|
||||
unsigned long data_len;
|
||||
} key_exchange_state_low_t;
|
||||
|
||||
typedef struct key_exchange_state_t {
|
||||
typedef struct key_exchange_state_t
|
||||
{
|
||||
libssh2_nonblocking_states state;
|
||||
packet_require_state_t req_state;
|
||||
key_exchange_state_low_t key_state_low;
|
||||
@@ -204,7 +210,8 @@ typedef struct key_exchange_state_t {
|
||||
|
||||
#define FwdNotReq "Forward not requested"
|
||||
|
||||
typedef struct packet_queue_listener_state_t {
|
||||
typedef struct packet_queue_listener_state_t
|
||||
{
|
||||
libssh2_nonblocking_states state;
|
||||
unsigned char packet[17 + (sizeof(FwdNotReq) - 1)];
|
||||
unsigned char *host;
|
||||
@@ -220,7 +227,8 @@ typedef struct packet_queue_listener_state_t {
|
||||
|
||||
#define X11FwdUnAvil "X11 Forward Unavailable"
|
||||
|
||||
typedef struct packet_x11_open_state_t {
|
||||
typedef struct packet_x11_open_state_t
|
||||
{
|
||||
libssh2_nonblocking_states state;
|
||||
unsigned char packet[17 + (sizeof(X11FwdUnAvil) - 1)];
|
||||
unsigned char *shost;
|
||||
@@ -231,7 +239,8 @@ typedef struct packet_x11_open_state_t {
|
||||
uint32_t shost_len;
|
||||
} packet_x11_open_state_t;
|
||||
|
||||
struct _LIBSSH2_PACKET {
|
||||
struct _LIBSSH2_PACKET
|
||||
{
|
||||
unsigned char type;
|
||||
|
||||
/* Unencrypted Payload (no type byte, no padding, just the facts ma'am) */
|
||||
@@ -250,11 +259,13 @@ struct _LIBSSH2_PACKET {
|
||||
LIBSSH2_PACKET *next, *prev;
|
||||
};
|
||||
|
||||
struct _LIBSSH2_PACKET_BRIGADE {
|
||||
struct _LIBSSH2_PACKET_BRIGADE
|
||||
{
|
||||
LIBSSH2_PACKET *head, *tail;
|
||||
};
|
||||
|
||||
typedef struct _libssh2_channel_data {
|
||||
typedef struct _libssh2_channel_data
|
||||
{
|
||||
/* Identifier */
|
||||
unsigned long id;
|
||||
|
||||
@@ -265,7 +276,8 @@ typedef struct _libssh2_channel_data {
|
||||
char close, eof, extended_data_ignore_mode;
|
||||
} libssh2_channel_data;
|
||||
|
||||
struct _LIBSSH2_CHANNEL {
|
||||
struct _LIBSSH2_CHANNEL
|
||||
{
|
||||
unsigned char *channel_type;
|
||||
unsigned channel_type_len;
|
||||
|
||||
@@ -355,11 +367,13 @@ struct _LIBSSH2_CHANNEL {
|
||||
libssh2_nonblocking_states extData2_state;
|
||||
};
|
||||
|
||||
struct _LIBSSH2_CHANNEL_BRIGADE {
|
||||
struct _LIBSSH2_CHANNEL_BRIGADE
|
||||
{
|
||||
LIBSSH2_CHANNEL *head, *tail;
|
||||
};
|
||||
|
||||
struct _LIBSSH2_LISTENER {
|
||||
struct _LIBSSH2_LISTENER
|
||||
{
|
||||
LIBSSH2_SESSION *session;
|
||||
|
||||
char *host;
|
||||
@@ -377,7 +391,8 @@ struct _LIBSSH2_LISTENER {
|
||||
size_t chanFwdCncl_data_len;
|
||||
};
|
||||
|
||||
typedef struct _libssh2_endpoint_data {
|
||||
typedef struct _libssh2_endpoint_data
|
||||
{
|
||||
unsigned char *banner;
|
||||
|
||||
unsigned char *kexinit;
|
||||
@@ -402,7 +417,8 @@ typedef struct _libssh2_endpoint_data {
|
||||
|
||||
#define PACKETBUFSIZE 4096
|
||||
|
||||
struct transportpacket {
|
||||
struct transportpacket
|
||||
{
|
||||
/* ------------- for incoming data --------------- */
|
||||
unsigned char buf[PACKETBUFSIZE];
|
||||
unsigned char init[5]; /* first 5 bytes of the incoming data stream,
|
||||
@@ -437,7 +453,8 @@ struct transportpacket {
|
||||
unsigned long osent; /* number of bytes already sent */
|
||||
};
|
||||
|
||||
struct _LIBSSH2_PUBLICKEY {
|
||||
struct _LIBSSH2_PUBLICKEY
|
||||
{
|
||||
LIBSSH2_CHANNEL *channel;
|
||||
unsigned long version;
|
||||
|
||||
@@ -464,7 +481,8 @@ struct _LIBSSH2_PUBLICKEY {
|
||||
unsigned long listFetch_data_len;
|
||||
};
|
||||
|
||||
struct _LIBSSH2_SFTP_HANDLE {
|
||||
struct _LIBSSH2_SFTP_HANDLE
|
||||
{
|
||||
LIBSSH2_SFTP *sftp;
|
||||
LIBSSH2_SFTP_HANDLE *prev, *next;
|
||||
|
||||
@@ -473,11 +491,14 @@ struct _LIBSSH2_SFTP_HANDLE {
|
||||
|
||||
char handle_type;
|
||||
|
||||
union _libssh2_sftp_handle_data {
|
||||
struct _libssh2_sftp_handle_file_data {
|
||||
union _libssh2_sftp_handle_data
|
||||
{
|
||||
struct _libssh2_sftp_handle_file_data
|
||||
{
|
||||
libssh2_uint64_t offset;
|
||||
} file;
|
||||
struct _libssh2_sftp_handle_dir_data {
|
||||
struct _libssh2_sftp_handle_dir_data
|
||||
{
|
||||
unsigned long names_left;
|
||||
void *names_packet;
|
||||
char *next_name;
|
||||
@@ -490,7 +511,8 @@ struct _LIBSSH2_SFTP_HANDLE {
|
||||
unsigned char *close_packet;
|
||||
};
|
||||
|
||||
struct _LIBSSH2_SFTP {
|
||||
struct _LIBSSH2_SFTP
|
||||
{
|
||||
LIBSSH2_CHANNEL *channel;
|
||||
|
||||
unsigned long request_id, version;
|
||||
@@ -570,7 +592,8 @@ struct _LIBSSH2_SFTP {
|
||||
|
||||
#define LIBSSH2_SCP_RESPONSE_BUFLEN 256
|
||||
|
||||
struct _LIBSSH2_SESSION {
|
||||
struct _LIBSSH2_SESSION
|
||||
{
|
||||
/* Memory management callbacks */
|
||||
void *abstract;
|
||||
LIBSSH2_ALLOC_FUNC((*alloc));
|
||||
@@ -823,28 +846,40 @@ struct _LIBSSH2_SESSION {
|
||||
|
||||
/* libssh2 extensible ssh api, ultimately I'd like to allow loading additional methods via .so/.dll */
|
||||
|
||||
struct _LIBSSH2_KEX_METHOD {
|
||||
struct _LIBSSH2_KEX_METHOD
|
||||
{
|
||||
const char *name;
|
||||
|
||||
/* Key exchange, populates session->* and returns 0 on success, non-0 on error */
|
||||
int (*exchange_keys)(LIBSSH2_SESSION *session, key_exchange_state_low_t *key_state);
|
||||
int (*exchange_keys) (LIBSSH2_SESSION * session,
|
||||
key_exchange_state_low_t * key_state);
|
||||
|
||||
long flags;
|
||||
};
|
||||
|
||||
struct _LIBSSH2_HOSTKEY_METHOD {
|
||||
struct _LIBSSH2_HOSTKEY_METHOD
|
||||
{
|
||||
const char *name;
|
||||
unsigned long hash_len;
|
||||
|
||||
int (*init)(LIBSSH2_SESSION *session, const unsigned char *hostkey_data, unsigned long hostkey_data_len, void **abstract);
|
||||
int (*initPEM)(LIBSSH2_SESSION *session, const char *privkeyfile, unsigned const char *passphrase, void **abstract);
|
||||
int (*sig_verify)(LIBSSH2_SESSION *session, const unsigned char *sig, unsigned long sig_len, const unsigned char *m, unsigned long m_len, void **abstract);
|
||||
int (*signv)(LIBSSH2_SESSION *session, unsigned char **signature, unsigned long *signature_len, unsigned long veccount, const struct iovec datavec[], void **abstract);
|
||||
int (*encrypt)(LIBSSH2_SESSION *session, unsigned char **dst, unsigned long *dst_len, const unsigned char *src, unsigned long src_len, void **abstract);
|
||||
int (*init) (LIBSSH2_SESSION * session, const unsigned char *hostkey_data,
|
||||
unsigned long hostkey_data_len, void **abstract);
|
||||
int (*initPEM) (LIBSSH2_SESSION * session, const char *privkeyfile,
|
||||
unsigned const char *passphrase, void **abstract);
|
||||
int (*sig_verify) (LIBSSH2_SESSION * session, const unsigned char *sig,
|
||||
unsigned long sig_len, const unsigned char *m,
|
||||
unsigned long m_len, void **abstract);
|
||||
int (*signv) (LIBSSH2_SESSION * session, unsigned char **signature,
|
||||
unsigned long *signature_len, unsigned long veccount,
|
||||
const struct iovec datavec[], void **abstract);
|
||||
int (*encrypt) (LIBSSH2_SESSION * session, unsigned char **dst,
|
||||
unsigned long *dst_len, const unsigned char *src,
|
||||
unsigned long src_len, void **abstract);
|
||||
int (*dtor) (LIBSSH2_SESSION * session, void **abstract);
|
||||
};
|
||||
|
||||
struct _LIBSSH2_CRYPT_METHOD {
|
||||
struct _LIBSSH2_CRYPT_METHOD
|
||||
{
|
||||
const char *name;
|
||||
|
||||
int blocksize;
|
||||
@@ -855,23 +890,31 @@ struct _LIBSSH2_CRYPT_METHOD {
|
||||
|
||||
long flags;
|
||||
|
||||
int (*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);
|
||||
int (*crypt)(LIBSSH2_SESSION *session, unsigned char *block, void **abstract);
|
||||
int (*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);
|
||||
int (*crypt) (LIBSSH2_SESSION * session, unsigned char *block,
|
||||
void **abstract);
|
||||
int (*dtor) (LIBSSH2_SESSION * session, void **abstract);
|
||||
|
||||
_libssh2_cipher_type(algo);
|
||||
};
|
||||
|
||||
struct _LIBSSH2_COMP_METHOD {
|
||||
struct _LIBSSH2_COMP_METHOD
|
||||
{
|
||||
const char *name;
|
||||
|
||||
int (*init) (LIBSSH2_SESSION * session, int compress, void **abstract);
|
||||
int (*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);
|
||||
int (*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);
|
||||
int (*dtor) (LIBSSH2_SESSION * session, int compress, void **abstract);
|
||||
};
|
||||
|
||||
struct _LIBSSH2_MAC_METHOD {
|
||||
struct _LIBSSH2_MAC_METHOD
|
||||
{
|
||||
const char *name;
|
||||
|
||||
/* The length of a given MAC packet */
|
||||
@@ -881,8 +924,12 @@ struct _LIBSSH2_MAC_METHOD {
|
||||
int key_len;
|
||||
|
||||
/* Message Authentication Code Hashing algo */
|
||||
int (*init)(LIBSSH2_SESSION *session, unsigned char *key, int *free_key, void **abstract);
|
||||
int (*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);
|
||||
int (*init) (LIBSSH2_SESSION * session, unsigned char *key, int *free_key,
|
||||
void **abstract);
|
||||
int (*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);
|
||||
int (*dtor) (LIBSSH2_SESSION * session, void **abstract);
|
||||
};
|
||||
|
||||
@@ -895,7 +942,8 @@ struct _LIBSSH2_MAC_METHOD {
|
||||
#define LIBSSH2_DBG_ERROR 7
|
||||
#define LIBSSH2_DBG_PUBLICKEY 8
|
||||
#ifdef LIBSSH2DEBUG
|
||||
void _libssh2_debug(LIBSSH2_SESSION *session, int context, const char *format, ...);
|
||||
void _libssh2_debug(LIBSSH2_SESSION * session, int context, const char *format,
|
||||
...);
|
||||
#else
|
||||
#if defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L)
|
||||
/* C99 style */
|
||||
@@ -905,8 +953,10 @@ void _libssh2_debug(LIBSSH2_SESSION *session, int context, const char *format, .
|
||||
#define _libssh2_debug(x,y,z,...) do {} while (0)
|
||||
#else
|
||||
/* no gcc and not C99, do static and hopefully inline */
|
||||
static inline void _libssh2_debug(LIBSSH2_SESSION *session, int context,
|
||||
const char *format, ...) {}
|
||||
static inline void
|
||||
_libssh2_debug(LIBSSH2_SESSION * session, int context, const char *format, ...)
|
||||
{
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
|
||||
@@ -1037,16 +1087,38 @@ int libssh2_packet_ask_ex(LIBSSH2_SESSION *session, unsigned char packet_type,
|
||||
const unsigned char *match_buf,
|
||||
unsigned long match_len, int poll_socket);
|
||||
|
||||
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_kex_exchange(LIBSSH2_SESSION *session, int reexchange, key_exchange_state_t *state);
|
||||
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_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);
|
||||
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);
|
||||
@@ -1064,8 +1136,7 @@ const LIBSSH2_MAC_METHOD **libssh2_mac_methods(void);
|
||||
int _libssh2_pem_parse(LIBSSH2_SESSION * session,
|
||||
const char *headerbegin,
|
||||
const char *headerend,
|
||||
FILE *fp,
|
||||
char **data, unsigned int *datalen);
|
||||
FILE * fp, char **data, unsigned int *datalen);
|
||||
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);
|
||||
|
85
src/mac.c
85
src/mac.c
@@ -41,12 +41,15 @@
|
||||
/* {{{ libssh2_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)
|
||||
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)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* }}} */
|
||||
|
||||
|
||||
@@ -63,7 +66,9 @@ static LIBSSH2_MAC_METHOD libssh2_mac_method_none = {
|
||||
/* {{{ libssh2_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)
|
||||
static int
|
||||
libssh2_mac_method_common_init(LIBSSH2_SESSION * session, unsigned char *key,
|
||||
int *free_key, void **abstract)
|
||||
{
|
||||
*abstract = key;
|
||||
*free_key = 0;
|
||||
@@ -71,12 +76,14 @@ static int libssh2_mac_method_common_init(LIBSSH2_SESSION *session, unsigned cha
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* }}} */
|
||||
|
||||
/* {{{ libssh2_mac_method_common_dtor
|
||||
* Cleanup simple mac methods
|
||||
*/
|
||||
static int libssh2_mac_method_common_dtor(LIBSSH2_SESSION *session, void **abstract)
|
||||
static int
|
||||
libssh2_mac_method_common_dtor(LIBSSH2_SESSION * session, void **abstract)
|
||||
{
|
||||
if (*abstract) {
|
||||
LIBSSH2_FREE(session, *abstract);
|
||||
@@ -85,14 +92,19 @@ static int libssh2_mac_method_common_dtor(LIBSSH2_SESSION *session, void **abstr
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* }}} */
|
||||
|
||||
/* {{{ libssh2_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)
|
||||
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)
|
||||
{
|
||||
libssh2_hmac_ctx ctx;
|
||||
unsigned char seqno_buf[4];
|
||||
@@ -111,6 +123,7 @@ static int libssh2_mac_method_hmac_sha1_hash(LIBSSH2_SESSION *session, unsigned
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* }}} */
|
||||
|
||||
static const LIBSSH2_MAC_METHOD libssh2_mac_method_hmac_sha1 = {
|
||||
@@ -125,17 +138,23 @@ static const LIBSSH2_MAC_METHOD libssh2_mac_method_hmac_sha1 = {
|
||||
/* {{{ libssh2_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)
|
||||
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)
|
||||
{
|
||||
unsigned char temp[SHA_DIGEST_LENGTH];
|
||||
|
||||
libssh2_mac_method_hmac_sha1_hash(session, temp, seqno, packet, packet_len, addtl, addtl_len, abstract);
|
||||
libssh2_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 = {
|
||||
@@ -150,9 +169,13 @@ static const LIBSSH2_MAC_METHOD libssh2_mac_method_hmac_sha1_96 = {
|
||||
/* {{{ libssh2_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)
|
||||
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)
|
||||
{
|
||||
libssh2_hmac_ctx ctx;
|
||||
unsigned char seqno_buf[4];
|
||||
@@ -171,6 +194,7 @@ static int libssh2_mac_method_hmac_md5_hash(LIBSSH2_SESSION *session, unsigned c
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* }}} */
|
||||
|
||||
static const LIBSSH2_MAC_METHOD libssh2_mac_method_hmac_md5 = {
|
||||
@@ -185,17 +209,23 @@ static const LIBSSH2_MAC_METHOD libssh2_mac_method_hmac_md5 = {
|
||||
/* {{{ libssh2_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)
|
||||
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)
|
||||
{
|
||||
unsigned char temp[MD5_DIGEST_LENGTH];
|
||||
|
||||
libssh2_mac_method_hmac_md5_hash(session, temp, seqno, packet, packet_len, addtl, addtl_len, abstract);
|
||||
libssh2_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 = {
|
||||
@@ -211,9 +241,14 @@ static const LIBSSH2_MAC_METHOD libssh2_mac_method_hmac_md5_96 = {
|
||||
/* {{{ libssh2_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)
|
||||
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)
|
||||
{
|
||||
libssh2_hmac_ctx ctx;
|
||||
unsigned char seqno_buf[4];
|
||||
@@ -232,6 +267,7 @@ static int libssh2_mac_method_hmac_ripemd160_hash(LIBSSH2_SESSION *session, unsi
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* }}} */
|
||||
|
||||
static const LIBSSH2_MAC_METHOD libssh2_mac_method_hmac_ripemd160 = {
|
||||
@@ -268,7 +304,8 @@ static const LIBSSH2_MAC_METHOD *_libssh2_mac_methods[] = {
|
||||
NULL
|
||||
};
|
||||
|
||||
const LIBSSH2_MAC_METHOD **libssh2_mac_methods(void) {
|
||||
const LIBSSH2_MAC_METHOD **
|
||||
libssh2_mac_methods(void)
|
||||
{
|
||||
return _libssh2_mac_methods;
|
||||
}
|
||||
|
||||
|
37
src/misc.c
37
src/misc.c
@@ -42,17 +42,20 @@
|
||||
|
||||
/* {{{ libssh2_ntohu32
|
||||
*/
|
||||
unsigned long libssh2_ntohu32(const unsigned char *buf)
|
||||
unsigned long
|
||||
libssh2_ntohu32(const unsigned char *buf)
|
||||
{
|
||||
return (buf[0] << 24) | (buf[1] << 16) | (buf[2] << 8) | buf[3];
|
||||
}
|
||||
|
||||
/* }}} */
|
||||
|
||||
/* {{{ libssh2_ntohu64
|
||||
* Note: Some 32-bit platforms have issues with bitops on long longs
|
||||
* Work around this by doing expensive (but safer) arithmetic ops with optimization defying parentheses
|
||||
*/
|
||||
libssh2_uint64_t libssh2_ntohu64(const unsigned char *buf)
|
||||
libssh2_uint64_t
|
||||
libssh2_ntohu64(const unsigned char *buf)
|
||||
{
|
||||
unsigned long msl, lsl;
|
||||
|
||||
@@ -61,22 +64,26 @@ libssh2_uint64_t libssh2_ntohu64(const unsigned char *buf)
|
||||
|
||||
return ((msl * 65536) * 65536) + lsl;
|
||||
}
|
||||
|
||||
/* }}} */
|
||||
|
||||
/* {{{ libssh2_htonu32
|
||||
*/
|
||||
void libssh2_htonu32(unsigned char *buf, unsigned long value)
|
||||
void
|
||||
libssh2_htonu32(unsigned char *buf, unsigned long value)
|
||||
{
|
||||
buf[0] = (value >> 24) & 0xFF;
|
||||
buf[1] = (value >> 16) & 0xFF;
|
||||
buf[2] = (value >> 8) & 0xFF;
|
||||
buf[3] = value & 0xFF;
|
||||
}
|
||||
|
||||
/* }}} */
|
||||
|
||||
/* {{{ libssh2_htonu64
|
||||
*/
|
||||
void libssh2_htonu64(unsigned char *buf, libssh2_uint64_t value)
|
||||
void
|
||||
libssh2_htonu64(unsigned char *buf, libssh2_uint64_t value)
|
||||
{
|
||||
unsigned long msl = (value / 65536) / 65536;
|
||||
|
||||
@@ -90,6 +97,7 @@ void libssh2_htonu64(unsigned char *buf, libssh2_uint64_t value)
|
||||
buf[6] = (value >> 8) & 0xFF;
|
||||
buf[7] = value & 0xFF;
|
||||
}
|
||||
|
||||
/* }}} */
|
||||
|
||||
/* Base64 Conversion */
|
||||
@@ -123,14 +131,17 @@ static const short libssh2_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
|
||||
};
|
||||
|
||||
/* }}} */
|
||||
|
||||
|
||||
/* {{{ libssh2_base64_decode
|
||||
* Decode a base64 chunk and store it into a newly alloc'd buffer
|
||||
*/
|
||||
LIBSSH2_API int libssh2_base64_decode(LIBSSH2_SESSION *session, char **data, unsigned int *datalen,
|
||||
const char *src, unsigned int src_len)
|
||||
LIBSSH2_API int
|
||||
libssh2_base64_decode(LIBSSH2_SESSION * session, char **data,
|
||||
unsigned int *datalen, const char *src,
|
||||
unsigned int src_len)
|
||||
{
|
||||
unsigned char *s, *d;
|
||||
short v;
|
||||
@@ -143,7 +154,8 @@ LIBSSH2_API int libssh2_base64_decode(LIBSSH2_SESSION *session, char **data, uns
|
||||
}
|
||||
|
||||
for(s = (unsigned char *) src; ((char *) s) < (src + src_len); s++) {
|
||||
if ((v = libssh2_base64_reverse_table[*s]) < 0) continue;
|
||||
if ((v = libssh2_base64_reverse_table[*s]) < 0)
|
||||
continue;
|
||||
switch (i % 4) {
|
||||
case 0:
|
||||
d[len] = v << 2;
|
||||
@@ -171,17 +183,19 @@ LIBSSH2_API int libssh2_base64_decode(LIBSSH2_SESSION *session, char **data, uns
|
||||
*datalen = len;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* }}} */
|
||||
|
||||
#ifdef LIBSSH2DEBUG
|
||||
LIBSSH2_API int libssh2_trace(LIBSSH2_SESSION *session, int bitmask)
|
||||
LIBSSH2_API int
|
||||
libssh2_trace(LIBSSH2_SESSION * session, int bitmask)
|
||||
{
|
||||
session->showmask = bitmask;
|
||||
return 0;
|
||||
}
|
||||
|
||||
void _libssh2_debug(LIBSSH2_SESSION *session, int context,
|
||||
const char *format, ...)
|
||||
void
|
||||
_libssh2_debug(LIBSSH2_SESSION * session, int context, const char *format, ...)
|
||||
{
|
||||
char buffer[1536];
|
||||
int len;
|
||||
@@ -217,7 +231,8 @@ void _libssh2_debug(LIBSSH2_SESSION *session, int context,
|
||||
}
|
||||
|
||||
#else
|
||||
LIBSSH2_API int libssh2_trace(LIBSSH2_SESSION *session, int bitmask)
|
||||
LIBSSH2_API int
|
||||
libssh2_trace(LIBSSH2_SESSION * session, int bitmask)
|
||||
{
|
||||
(void) session;
|
||||
(void) bitmask;
|
||||
|
@@ -43,7 +43,8 @@
|
||||
#define EVP_MAX_BLOCK_LENGTH 32
|
||||
#endif
|
||||
|
||||
int _libssh2_rsa_new(libssh2_rsa_ctx **rsa,
|
||||
int
|
||||
_libssh2_rsa_new(libssh2_rsa_ctx ** rsa,
|
||||
const unsigned char *edata,
|
||||
unsigned long elen,
|
||||
const unsigned char *ndata,
|
||||
@@ -58,8 +59,7 @@ int _libssh2_rsa_new(libssh2_rsa_ctx **rsa,
|
||||
unsigned long e1len,
|
||||
const unsigned char *e2data,
|
||||
unsigned long e2len,
|
||||
const unsigned char *coeffdata,
|
||||
unsigned long coefflen)
|
||||
const unsigned char *coeffdata, unsigned long coefflen)
|
||||
{
|
||||
*rsa = RSA_new();
|
||||
|
||||
@@ -91,11 +91,11 @@ int _libssh2_rsa_new(libssh2_rsa_ctx **rsa,
|
||||
return 0;
|
||||
}
|
||||
|
||||
int _libssh2_rsa_sha1_verify(libssh2_rsa_ctx *rsactx,
|
||||
int
|
||||
_libssh2_rsa_sha1_verify(libssh2_rsa_ctx * rsactx,
|
||||
const unsigned char *sig,
|
||||
unsigned long sig_len,
|
||||
const unsigned char *m,
|
||||
unsigned long m_len)
|
||||
const unsigned char *m, unsigned long m_len)
|
||||
{
|
||||
unsigned char hash[SHA_DIGEST_LENGTH];
|
||||
int ret;
|
||||
@@ -106,7 +106,8 @@ int _libssh2_rsa_sha1_verify(libssh2_rsa_ctx *rsactx,
|
||||
return (ret == 1) ? 0 : -1;
|
||||
}
|
||||
|
||||
int _libssh2_dsa_new(libssh2_dsa_ctx **dsactx,
|
||||
int
|
||||
_libssh2_dsa_new(libssh2_dsa_ctx ** dsactx,
|
||||
const unsigned char *p,
|
||||
unsigned long p_len,
|
||||
const unsigned char *q,
|
||||
@@ -115,8 +116,7 @@ int _libssh2_dsa_new(libssh2_dsa_ctx **dsactx,
|
||||
unsigned long g_len,
|
||||
const unsigned char *y,
|
||||
unsigned long y_len,
|
||||
const unsigned char *x,
|
||||
unsigned long x_len)
|
||||
const unsigned char *x, unsigned long x_len)
|
||||
{
|
||||
*dsactx = DSA_new();
|
||||
|
||||
@@ -140,10 +140,10 @@ int _libssh2_dsa_new(libssh2_dsa_ctx **dsactx,
|
||||
return 0;
|
||||
}
|
||||
|
||||
int _libssh2_dsa_sha1_verify(libssh2_dsa_ctx *dsactx,
|
||||
int
|
||||
_libssh2_dsa_sha1_verify(libssh2_dsa_ctx * dsactx,
|
||||
const unsigned char *sig,
|
||||
const unsigned char *m,
|
||||
unsigned long m_len)
|
||||
const unsigned char *m, unsigned long m_len)
|
||||
{
|
||||
unsigned char hash[SHA_DIGEST_LENGTH];
|
||||
DSA_SIG dsasig;
|
||||
@@ -162,21 +162,20 @@ int _libssh2_dsa_sha1_verify(libssh2_dsa_ctx *dsactx,
|
||||
return (ret == 1) ? 0 : -1;
|
||||
}
|
||||
|
||||
int _libssh2_cipher_init (_libssh2_cipher_ctx *h,
|
||||
int
|
||||
_libssh2_cipher_init(_libssh2_cipher_ctx * h,
|
||||
_libssh2_cipher_type(algo),
|
||||
unsigned char *iv,
|
||||
unsigned char *secret,
|
||||
int encrypt)
|
||||
unsigned char *iv, unsigned char *secret, int encrypt)
|
||||
{
|
||||
EVP_CIPHER_CTX_init(h);
|
||||
EVP_CipherInit(h, algo(), secret, iv, encrypt);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int _libssh2_cipher_crypt(_libssh2_cipher_ctx *ctx,
|
||||
int
|
||||
_libssh2_cipher_crypt(_libssh2_cipher_ctx * ctx,
|
||||
_libssh2_cipher_type(algo),
|
||||
int encrypt,
|
||||
unsigned char *block)
|
||||
int encrypt, unsigned char *block)
|
||||
{
|
||||
int blocksize = ctx->cipher->block_size;
|
||||
unsigned char buf[EVP_MAX_BLOCK_LENGTH];
|
||||
@@ -199,8 +198,7 @@ int _libssh2_cipher_crypt(_libssh2_cipher_ctx *ctx,
|
||||
* calling program
|
||||
*/
|
||||
static int
|
||||
passphrase_cb(char *buf, int size,
|
||||
int rwflag, char *passphrase)
|
||||
passphrase_cb(char *buf, int size, int rwflag, char *passphrase)
|
||||
{
|
||||
int passphrase_len = strlen(passphrase);
|
||||
(void) rwflag;
|
||||
@@ -214,10 +212,10 @@ passphrase_cb(char *buf, int size,
|
||||
return passphrase_len;
|
||||
}
|
||||
|
||||
int _libssh2_rsa_new_private (libssh2_rsa_ctx **rsa,
|
||||
int
|
||||
_libssh2_rsa_new_private(libssh2_rsa_ctx ** rsa,
|
||||
LIBSSH2_SESSION * session,
|
||||
FILE *fp,
|
||||
unsigned const char *passphrase)
|
||||
FILE * fp, unsigned const char *passphrase)
|
||||
{
|
||||
(void) session;
|
||||
if (!EVP_get_cipherbyname("des")) {
|
||||
@@ -235,10 +233,10 @@ int _libssh2_rsa_new_private (libssh2_rsa_ctx **rsa,
|
||||
return 0;
|
||||
}
|
||||
|
||||
int _libssh2_dsa_new_private (libssh2_dsa_ctx **dsa,
|
||||
int
|
||||
_libssh2_dsa_new_private(libssh2_dsa_ctx ** dsa,
|
||||
LIBSSH2_SESSION * session,
|
||||
FILE *fp,
|
||||
unsigned const char *passphrase)
|
||||
FILE * fp, unsigned const char *passphrase)
|
||||
{
|
||||
(void) session;
|
||||
if (!EVP_get_cipherbyname("des")) {
|
||||
@@ -256,12 +254,12 @@ int _libssh2_dsa_new_private (libssh2_dsa_ctx **dsa,
|
||||
return 0;
|
||||
}
|
||||
|
||||
int _libssh2_rsa_sha1_sign(LIBSSH2_SESSION *session,
|
||||
int
|
||||
_libssh2_rsa_sha1_sign(LIBSSH2_SESSION * session,
|
||||
libssh2_rsa_ctx * rsactx,
|
||||
const unsigned char *hash,
|
||||
unsigned long hash_len,
|
||||
unsigned char **signature,
|
||||
unsigned long *signature_len)
|
||||
unsigned char **signature, unsigned long *signature_len)
|
||||
{
|
||||
int ret;
|
||||
unsigned char *sig;
|
||||
@@ -287,10 +285,10 @@ int _libssh2_rsa_sha1_sign(LIBSSH2_SESSION *session,
|
||||
return 0;
|
||||
}
|
||||
|
||||
int _libssh2_dsa_sha1_sign(libssh2_dsa_ctx *dsactx,
|
||||
int
|
||||
_libssh2_dsa_sha1_sign(libssh2_dsa_ctx * dsactx,
|
||||
const unsigned char *hash,
|
||||
unsigned long hash_len,
|
||||
unsigned char *signature)
|
||||
unsigned long hash_len, unsigned char *signature)
|
||||
{
|
||||
DSA_SIG *sig;
|
||||
int r_len, s_len, rs_pad;
|
||||
|
@@ -146,17 +146,14 @@ int _libssh2_rsa_new(libssh2_rsa_ctx **rsa,
|
||||
unsigned long e1len,
|
||||
const unsigned char *e2data,
|
||||
unsigned long e2len,
|
||||
const unsigned char *coeffdata,
|
||||
unsigned long coefflen);
|
||||
const unsigned char *coeffdata, unsigned long coefflen);
|
||||
int _libssh2_rsa_new_private(libssh2_rsa_ctx ** rsa,
|
||||
LIBSSH2_SESSION * session,
|
||||
FILE *fp,
|
||||
unsigned const char *passphrase);
|
||||
FILE * fp, unsigned const char *passphrase);
|
||||
int _libssh2_rsa_sha1_verify(libssh2_rsa_ctx * rsa,
|
||||
const unsigned char *sig,
|
||||
unsigned long sig_len,
|
||||
const unsigned char *m,
|
||||
unsigned long m_len);
|
||||
const unsigned char *m, unsigned long m_len);
|
||||
int _libssh2_rsa_sha1_sign(LIBSSH2_SESSION * session,
|
||||
libssh2_rsa_ctx * rsactx,
|
||||
const unsigned char *hash,
|
||||
@@ -177,20 +174,16 @@ int _libssh2_dsa_new(libssh2_dsa_ctx **dsa,
|
||||
unsigned long glen,
|
||||
const unsigned char *ydata,
|
||||
unsigned long ylen,
|
||||
const unsigned char *x,
|
||||
unsigned long x_len);
|
||||
const unsigned char *x, unsigned long x_len);
|
||||
int _libssh2_dsa_new_private(libssh2_dsa_ctx ** dsa,
|
||||
LIBSSH2_SESSION * session,
|
||||
FILE *fp,
|
||||
unsigned const char *passphrase);
|
||||
FILE * fp, unsigned const char *passphrase);
|
||||
int _libssh2_dsa_sha1_verify(libssh2_dsa_ctx * dsactx,
|
||||
const unsigned char *sig,
|
||||
const unsigned char *m,
|
||||
unsigned long m_len);
|
||||
const unsigned char *m, unsigned long m_len);
|
||||
int _libssh2_dsa_sha1_sign(libssh2_dsa_ctx * dsactx,
|
||||
const unsigned char *hash,
|
||||
unsigned long hash_len,
|
||||
unsigned char *sig);
|
||||
unsigned long hash_len, unsigned char *sig);
|
||||
|
||||
#define _libssh2_dsa_free(dsactx) DSA_free(dsactx)
|
||||
|
||||
@@ -208,13 +201,11 @@ int _libssh2_dsa_sha1_sign(libssh2_dsa_ctx *dsactx,
|
||||
int _libssh2_cipher_init(_libssh2_cipher_ctx * h,
|
||||
_libssh2_cipher_type(algo),
|
||||
unsigned char *iv,
|
||||
unsigned char *secret,
|
||||
int encrypt);
|
||||
unsigned char *secret, int encrypt);
|
||||
|
||||
int _libssh2_cipher_crypt(_libssh2_cipher_ctx * ctx,
|
||||
_libssh2_cipher_type(algo),
|
||||
int encrypt,
|
||||
unsigned char *block);
|
||||
int encrypt, unsigned char *block);
|
||||
|
||||
#define _libssh2_cipher_dtor(ctx) EVP_CIPHER_CTX_cleanup(ctx)
|
||||
|
||||
|
301
src/packet.c
301
src/packet.c
@@ -80,18 +80,27 @@ 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); s += 4;
|
||||
listen_state->sender_channel = libssh2_ntohu32(s);
|
||||
s += 4;
|
||||
|
||||
listen_state->initial_window_size = libssh2_ntohu32(s); s += 4;
|
||||
listen_state->packet_size = libssh2_ntohu32(s); s += 4;
|
||||
listen_state->initial_window_size = libssh2_ntohu32(s);
|
||||
s += 4;
|
||||
listen_state->packet_size = libssh2_ntohu32(s);
|
||||
s += 4;
|
||||
|
||||
listen_state->host_len = libssh2_ntohu32(s); s += 4;
|
||||
listen_state->host = s; s += listen_state->host_len;
|
||||
listen_state->port = libssh2_ntohu32(s); s += 4;
|
||||
listen_state->host_len = libssh2_ntohu32(s);
|
||||
s += 4;
|
||||
listen_state->host = s;
|
||||
s += listen_state->host_len;
|
||||
listen_state->port = libssh2_ntohu32(s);
|
||||
s += 4;
|
||||
|
||||
listen_state->shost_len = libssh2_ntohu32(s); s += 4;
|
||||
listen_state->shost = s; s += listen_state->shost_len;
|
||||
listen_state->sport = libssh2_ntohu32(s); s += 4;
|
||||
listen_state->shost_len = libssh2_ntohu32(s);
|
||||
s += 4;
|
||||
listen_state->shost = s;
|
||||
s += listen_state->shost_len;
|
||||
listen_state->sport = libssh2_ntohu32(s);
|
||||
s += 4;
|
||||
|
||||
_libssh2_debug(session, LIBSSH2_DBG_CONN,
|
||||
"Remote received connection from %s:%ld to %s:%ld",
|
||||
@@ -105,7 +114,9 @@ libssh2_packet_queue_listener(LIBSSH2_SESSION *session, unsigned char *data,
|
||||
while (listen) {
|
||||
if ((listen->port == (int) listen_state->port) &&
|
||||
(strlen(listen->host) == listen_state->host_len) &&
|
||||
(memcmp(listen->host, listen_state->host, listen_state->host_len) == 0)) {
|
||||
(memcmp
|
||||
(listen->host, listen_state->host,
|
||||
listen_state->host_len) == 0)) {
|
||||
/* This is our listener */
|
||||
LIBSSH2_CHANNEL *channel, *last_queued = listen->queue;
|
||||
|
||||
@@ -135,7 +146,9 @@ libssh2_packet_queue_listener(LIBSSH2_SESSION *session, unsigned char *data,
|
||||
channel->session = session;
|
||||
channel->channel_type_len = sizeof("forwarded-tcpip") - 1;
|
||||
channel->channel_type = LIBSSH2_ALLOC(session,
|
||||
channel->channel_type_len + 1);
|
||||
channel->
|
||||
channel_type_len +
|
||||
1);
|
||||
if (!channel->channel_type) {
|
||||
libssh2_error(session, LIBSSH2_ERROR_ALLOC,
|
||||
"Unable to allocate a channel for new connection",
|
||||
@@ -149,13 +162,18 @@ libssh2_packet_queue_listener(LIBSSH2_SESSION *session, unsigned char *data,
|
||||
channel->channel_type_len + 1);
|
||||
|
||||
channel->remote.id = listen_state->sender_channel;
|
||||
channel->remote.window_size_initial = LIBSSH2_CHANNEL_WINDOW_DEFAULT;
|
||||
channel->remote.window_size = LIBSSH2_CHANNEL_WINDOW_DEFAULT;
|
||||
channel->remote.packet_size = LIBSSH2_CHANNEL_PACKET_DEFAULT;
|
||||
channel->remote.window_size_initial =
|
||||
LIBSSH2_CHANNEL_WINDOW_DEFAULT;
|
||||
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.window_size_initial = listen_state->initial_window_size;
|
||||
channel->local.window_size = listen_state->initial_window_size;
|
||||
channel->local.window_size_initial =
|
||||
listen_state->initial_window_size;
|
||||
channel->local.window_size =
|
||||
listen_state->initial_window_size;
|
||||
channel->local.packet_size = listen_state->packet_size;
|
||||
|
||||
_libssh2_debug(session, LIBSSH2_DBG_CONN,
|
||||
@@ -185,8 +203,7 @@ libssh2_packet_queue_listener(LIBSSH2_SESSION *session, unsigned char *data,
|
||||
17);
|
||||
if (rc == PACKET_EAGAIN) {
|
||||
return PACKET_EAGAIN;
|
||||
}
|
||||
else if (rc) {
|
||||
} else if (rc) {
|
||||
libssh2_error(session, LIBSSH2_ERROR_SOCKET_SEND,
|
||||
"Unable to send channel open confirmation",
|
||||
0);
|
||||
@@ -239,8 +256,7 @@ libssh2_packet_queue_listener(LIBSSH2_SESSION *session, unsigned char *data,
|
||||
rc = libssh2_packet_write(session, listen_state->packet, packet_len);
|
||||
if (rc == PACKET_EAGAIN) {
|
||||
return PACKET_EAGAIN;
|
||||
}
|
||||
else if (rc) {
|
||||
} else if (rc) {
|
||||
libssh2_error(session, LIBSSH2_ERROR_SOCKET_SEND,
|
||||
"Unable to send open failure", 0);
|
||||
listen_state->state = libssh2_NB_state_idle;
|
||||
@@ -250,6 +266,7 @@ libssh2_packet_queue_listener(LIBSSH2_SESSION *session, unsigned char *data,
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
/* }}} */
|
||||
|
||||
/* {{{ libssh2_packet_x11_open
|
||||
@@ -271,12 +288,18 @@ 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); s += 4;
|
||||
x11open_state->initial_window_size = libssh2_ntohu32(s); s += 4;
|
||||
x11open_state->packet_size = libssh2_ntohu32(s); s += 4;
|
||||
x11open_state->shost_len = libssh2_ntohu32(s); s += 4;
|
||||
x11open_state->shost = s; s += x11open_state->shost_len;
|
||||
x11open_state->sport = libssh2_ntohu32(s); s += 4;
|
||||
x11open_state->sender_channel = libssh2_ntohu32(s);
|
||||
s += 4;
|
||||
x11open_state->initial_window_size = libssh2_ntohu32(s);
|
||||
s += 4;
|
||||
x11open_state->packet_size = libssh2_ntohu32(s);
|
||||
s += 4;
|
||||
x11open_state->shost_len = libssh2_ntohu32(s);
|
||||
s += 4;
|
||||
x11open_state->shost = s;
|
||||
s += x11open_state->shost_len;
|
||||
x11open_state->sport = libssh2_ntohu32(s);
|
||||
s += 4;
|
||||
|
||||
_libssh2_debug(session, LIBSSH2_DBG_CONN,
|
||||
"X11 Connection Received from %s:%ld on channel %lu",
|
||||
@@ -301,7 +324,8 @@ libssh2_packet_x11_open(LIBSSH2_SESSION *session, unsigned char *data,
|
||||
channel->session = session;
|
||||
channel->channel_type_len = sizeof("x11") - 1;
|
||||
channel->channel_type = LIBSSH2_ALLOC(session,
|
||||
channel->channel_type_len + 1);
|
||||
channel->channel_type_len +
|
||||
1);
|
||||
if (!channel->channel_type) {
|
||||
libssh2_error(session, LIBSSH2_ERROR_ALLOC,
|
||||
"Unable to allocate a channel for new connection",
|
||||
@@ -310,15 +334,18 @@ libssh2_packet_x11_open(LIBSSH2_SESSION *session, unsigned char *data,
|
||||
failure_code = 4; /* SSH_OPEN_RESOURCE_SHORTAGE */
|
||||
goto x11_exit;
|
||||
}
|
||||
memcpy(channel->channel_type, "x11", channel->channel_type_len + 1);
|
||||
memcpy(channel->channel_type, "x11",
|
||||
channel->channel_type_len + 1);
|
||||
|
||||
channel->remote.id = x11open_state->sender_channel;
|
||||
channel->remote.window_size_initial = LIBSSH2_CHANNEL_WINDOW_DEFAULT;
|
||||
channel->remote.window_size_initial =
|
||||
LIBSSH2_CHANNEL_WINDOW_DEFAULT;
|
||||
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.window_size_initial = x11open_state->initial_window_size;
|
||||
channel->local.window_size_initial =
|
||||
x11open_state->initial_window_size;
|
||||
channel->local.window_size = x11open_state->initial_window_size;
|
||||
channel->local.packet_size = x11open_state->packet_size;
|
||||
|
||||
@@ -331,10 +358,14 @@ 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); p += 4;
|
||||
libssh2_htonu32(p, channel->local.id); p += 4;
|
||||
libssh2_htonu32(p, channel->remote.window_size_initial); p += 4;
|
||||
libssh2_htonu32(p, channel->remote.packet_size); p += 4;
|
||||
libssh2_htonu32(p, channel->remote.id);
|
||||
p += 4;
|
||||
libssh2_htonu32(p, channel->local.id);
|
||||
p += 4;
|
||||
libssh2_htonu32(p, channel->remote.window_size_initial);
|
||||
p += 4;
|
||||
libssh2_htonu32(p, channel->remote.packet_size);
|
||||
p += 4;
|
||||
|
||||
x11open_state->state = libssh2_NB_state_created;
|
||||
}
|
||||
@@ -343,8 +374,7 @@ libssh2_packet_x11_open(LIBSSH2_SESSION *session, unsigned char *data,
|
||||
rc = libssh2_packet_write(session, x11open_state->packet, 17);
|
||||
if (rc == PACKET_EAGAIN) {
|
||||
return PACKET_EAGAIN;
|
||||
}
|
||||
else if (rc) {
|
||||
} else if (rc) {
|
||||
libssh2_error(session, LIBSSH2_ERROR_SOCKET_SEND,
|
||||
"Unable to send channel open confirmation", 0);
|
||||
x11open_state->state = libssh2_NB_state_idle;
|
||||
@@ -366,7 +396,8 @@ libssh2_packet_x11_open(LIBSSH2_SESSION *session, unsigned char *data,
|
||||
* Pass control to the callback, they may turn right around and
|
||||
* free the channel, or actually use it
|
||||
*/
|
||||
LIBSSH2_X11_OPEN(channel, (char *)x11open_state->shost, x11open_state->sport);
|
||||
LIBSSH2_X11_OPEN(channel, (char *) x11open_state->shost,
|
||||
x11open_state->sport);
|
||||
|
||||
x11open_state->state = libssh2_NB_state_idle;
|
||||
return 0;
|
||||
@@ -378,9 +409,12 @@ 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); p += 4;
|
||||
libssh2_htonu32(p, failure_code); p += 4;
|
||||
libssh2_htonu32(p, sizeof(X11FwdUnAvil) - 1); p += 4;
|
||||
libssh2_htonu32(p, x11open_state->sender_channel);
|
||||
p += 4;
|
||||
libssh2_htonu32(p, failure_code);
|
||||
p += 4;
|
||||
libssh2_htonu32(p, sizeof(X11FwdUnAvil) - 1);
|
||||
p += 4;
|
||||
memcpy(s, X11FwdUnAvil, sizeof(X11FwdUnAvil) - 1);
|
||||
p += sizeof(X11FwdUnAvil) - 1;
|
||||
libssh2_htonu32(p, 0);
|
||||
@@ -388,8 +422,7 @@ x11_exit:
|
||||
rc = libssh2_packet_write(session, x11open_state->packet, packet_len);
|
||||
if (rc == PACKET_EAGAIN) {
|
||||
return PACKET_EAGAIN;
|
||||
}
|
||||
else if (rc) {
|
||||
} else if (rc) {
|
||||
libssh2_error(session, LIBSSH2_ERROR_SOCKET_SEND,
|
||||
"Unable to send open failure", 0);
|
||||
x11open_state->state = libssh2_NB_state_idle;
|
||||
@@ -398,12 +431,14 @@ x11_exit:
|
||||
x11open_state->state = libssh2_NB_state_idle;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* }}} */
|
||||
|
||||
/* {{{ libssh2_packet_new
|
||||
* Create a new packet and attach it to the brigade
|
||||
*/
|
||||
int libssh2_packet_add(LIBSSH2_SESSION *session, unsigned char *data,
|
||||
int
|
||||
libssh2_packet_add(LIBSSH2_SESSION * session, unsigned char *data,
|
||||
size_t datalen, int macstate)
|
||||
{
|
||||
int rc;
|
||||
@@ -469,11 +504,9 @@ int libssh2_packet_add(LIBSSH2_SESSION *session, unsigned char *data,
|
||||
*/
|
||||
if (session->packAdd_state == libssh2_NB_state_jump1) {
|
||||
goto libssh2_packet_add_jump_point1;
|
||||
}
|
||||
else if (session->packAdd_state == libssh2_NB_state_jump2) {
|
||||
} else if (session->packAdd_state == libssh2_NB_state_jump2) {
|
||||
goto libssh2_packet_add_jump_point2;
|
||||
}
|
||||
else if (session->packAdd_state == libssh2_NB_state_jump3) {
|
||||
} else if (session->packAdd_state == libssh2_NB_state_jump3) {
|
||||
goto libssh2_packet_add_jump_point3;
|
||||
}
|
||||
|
||||
@@ -586,7 +619,8 @@ int libssh2_packet_add(LIBSSH2_SESSION *session, unsigned char *data,
|
||||
session->packAdd_data_head += 9;
|
||||
{
|
||||
session->packAdd_channel = libssh2_channel_locate(session,
|
||||
libssh2_ntohu32(data + 1));
|
||||
libssh2_ntohu32
|
||||
(data + 1));
|
||||
|
||||
if (!session->packAdd_channel) {
|
||||
libssh2_error(session, LIBSSH2_ERROR_CHANNEL_UNKNOWN,
|
||||
@@ -606,14 +640,17 @@ int libssh2_packet_add(LIBSSH2_SESSION *session, unsigned char *data,
|
||||
|
||||
_libssh2_debug(session, LIBSSH2_DBG_CONN,
|
||||
"%d bytes received for channel %lu/%lu stream #%lu",
|
||||
(int)(datalen - session->packAdd_data_head),
|
||||
(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)) {
|
||||
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);
|
||||
|
||||
@@ -623,8 +660,10 @@ int libssh2_packet_add(LIBSSH2_SESSION *session, unsigned char *data,
|
||||
/* 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);
|
||||
rc = libssh2_channel_receive_window_adjust(session->
|
||||
packAdd_channel,
|
||||
datalen - 13,
|
||||
0);
|
||||
if (rc == PACKET_EAGAIN) {
|
||||
return PACKET_EAGAIN;
|
||||
}
|
||||
@@ -636,7 +675,8 @@ libssh2_packet_add_jump_point1:
|
||||
* REMEMBER! remote means remote as source of data,
|
||||
* NOT remote window!
|
||||
*/
|
||||
if (session->packAdd_channel->remote.packet_size < (datalen - session->packAdd_data_head)) {
|
||||
if (session->packAdd_channel->remote.packet_size <
|
||||
(datalen - session->packAdd_data_head)) {
|
||||
/*
|
||||
* Spec says we MAY ignore bytes sent beyond
|
||||
* packet_size
|
||||
@@ -645,7 +685,9 @@ libssh2_packet_add_jump_point1:
|
||||
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;
|
||||
datalen =
|
||||
session->packAdd_channel->remote.packet_size +
|
||||
session->packAdd_data_head;
|
||||
}
|
||||
if (session->packAdd_channel->remote.window_size <= 0) {
|
||||
/*
|
||||
@@ -663,15 +705,19 @@ libssh2_packet_add_jump_point1:
|
||||
/* Reset EOF status */
|
||||
session->packAdd_channel->remote.eof = 0;
|
||||
|
||||
if ((datalen - session->packAdd_data_head) > session->packAdd_channel->remote.window_size) {
|
||||
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;
|
||||
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;
|
||||
session->packAdd_channel->remote.window_size -=
|
||||
datalen - session->packAdd_data_head;
|
||||
}
|
||||
}
|
||||
break;
|
||||
@@ -679,7 +725,8 @@ libssh2_packet_add_jump_point1:
|
||||
case SSH_MSG_CHANNEL_EOF:
|
||||
{
|
||||
session->packAdd_channel = libssh2_channel_locate(session,
|
||||
libssh2_ntohu32(data + 1));
|
||||
libssh2_ntohu32
|
||||
(data + 1));
|
||||
|
||||
if (!session->packAdd_channel) {
|
||||
/* We may have freed already, just quietly ignore this... */
|
||||
@@ -704,13 +751,17 @@ libssh2_packet_add_jump_point1:
|
||||
case SSH_MSG_CHANNEL_REQUEST:
|
||||
{
|
||||
if (libssh2_ntohu32(data + 5) == sizeof("exit-status") - 1
|
||||
&& !memcmp("exit-status", data + 9, 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));
|
||||
session->packAdd_channel =
|
||||
libssh2_channel_locate(session,
|
||||
libssh2_ntohu32(data + 1));
|
||||
|
||||
if (session->packAdd_channel) {
|
||||
session->packAdd_channel->exit_status = libssh2_ntohu32(data + 9 + sizeof("exit-status"));
|
||||
session->packAdd_channel->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,
|
||||
@@ -728,7 +779,8 @@ libssh2_packet_add_jump_point1:
|
||||
case SSH_MSG_CHANNEL_CLOSE:
|
||||
{
|
||||
session->packAdd_channel = libssh2_channel_locate(session,
|
||||
libssh2_ntohu32(data + 1));
|
||||
libssh2_ntohu32
|
||||
(data + 1));
|
||||
|
||||
if (!session->packAdd_channel) {
|
||||
/* We may have freed already, just quietly ignore this... */
|
||||
@@ -753,13 +805,17 @@ libssh2_packet_add_jump_point1:
|
||||
|
||||
case SSH_MSG_CHANNEL_OPEN:
|
||||
if ((datalen >= (sizeof("forwarded-tcpip") + 4)) &&
|
||||
((sizeof("forwarded-tcpip")-1) == libssh2_ntohu32(data + 1)) &&
|
||||
(memcmp(data + 5, "forwarded-tcpip", sizeof("forwarded-tcpip") - 1) == 0)) {
|
||||
((sizeof("forwarded-tcpip") - 1) == libssh2_ntohu32(data + 1))
|
||||
&&
|
||||
(memcmp
|
||||
(data + 5, "forwarded-tcpip",
|
||||
sizeof("forwarded-tcpip") - 1) == 0)) {
|
||||
|
||||
libssh2_packet_add_jump_point2:
|
||||
session->packAdd_state = libssh2_NB_state_jump2;
|
||||
rc = libssh2_packet_queue_listener(session, data, datalen,
|
||||
&session->packAdd_Qlstn_state);
|
||||
&session->
|
||||
packAdd_Qlstn_state);
|
||||
if (rc == PACKET_EAGAIN) {
|
||||
return PACKET_EAGAIN;
|
||||
}
|
||||
@@ -790,7 +846,8 @@ libssh2_packet_add_jump_point3:
|
||||
{
|
||||
unsigned long bytestoadd = libssh2_ntohu32(data + 5);
|
||||
session->packAdd_channel = libssh2_channel_locate(session,
|
||||
libssh2_ntohu32(data + 1));
|
||||
libssh2_ntohu32
|
||||
(data + 1));
|
||||
|
||||
if (session->packAdd_channel && bytestoadd) {
|
||||
session->packAdd_channel->local.window_size += bytestoadd;
|
||||
@@ -813,7 +870,8 @@ libssh2_packet_add_jump_point3:
|
||||
}
|
||||
|
||||
if (session->packAdd_state == libssh2_NB_state_sent) {
|
||||
session->packAdd_packet = LIBSSH2_ALLOC(session, sizeof(LIBSSH2_PACKET));
|
||||
session->packAdd_packet =
|
||||
LIBSSH2_ALLOC(session, sizeof(LIBSSH2_PACKET));
|
||||
if (!session->packAdd_packet) {
|
||||
_libssh2_debug(session, LIBSSH2_ERROR_ALLOC,
|
||||
"Unable to allocate memory for LIBSSH2_PACKET");
|
||||
@@ -869,14 +927,18 @@ libssh2_packet_add_jump_point3:
|
||||
session->packAdd_state = libssh2_NB_state_idle;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* }}} */
|
||||
|
||||
/* {{{ 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)
|
||||
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 *packet = session->packets.head;
|
||||
|
||||
@@ -896,8 +958,16 @@ int libssh2_packet_ask_ex(LIBSSH2_SESSION *session, unsigned char packet_type, u
|
||||
"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))) {
|
||||
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))) {
|
||||
*data = packet->data;
|
||||
*data_len = packet->data_len;
|
||||
|
||||
@@ -921,13 +991,15 @@ int libssh2_packet_ask_ex(LIBSSH2_SESSION *session, unsigned char packet_type, u
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* }}} */
|
||||
|
||||
/* {{{ 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,
|
||||
int
|
||||
libssh2_packet_askv_ex(LIBSSH2_SESSION * session,
|
||||
const unsigned char *packet_types,
|
||||
unsigned char **data, unsigned long *data_len,
|
||||
unsigned long match_ofs,
|
||||
@@ -952,6 +1024,7 @@ int libssh2_packet_askv_ex(LIBSSH2_SESSION *session,
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* }}} */
|
||||
|
||||
/* {{{ waitsocket
|
||||
@@ -962,7 +1035,8 @@ int libssh2_packet_askv_ex(LIBSSH2_SESSION *session,
|
||||
*
|
||||
* FIXME: convert to use poll on systems that have it.
|
||||
*/
|
||||
int libssh2_waitsocket(LIBSSH2_SESSION *session, long seconds)
|
||||
int
|
||||
libssh2_waitsocket(LIBSSH2_SESSION * session, long seconds)
|
||||
{
|
||||
struct timeval timeout;
|
||||
int rc;
|
||||
@@ -987,42 +1061,48 @@ int libssh2_waitsocket(LIBSSH2_SESSION *session, long seconds)
|
||||
* 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)
|
||||
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)
|
||||
{
|
||||
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_ex
|
||||
(session, packet_type, data, data_len, match_ofs, match_buf,
|
||||
match_len, 0) == 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);
|
||||
_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);
|
||||
if (ret == PACKET_EAGAIN) {
|
||||
return PACKET_EAGAIN;
|
||||
}
|
||||
else if ((ret == 0) && (!session->socket_block)) {
|
||||
} else if ((ret == 0) && (!session->socket_block)) {
|
||||
/* If we are in non-blocking and there is no data, return that */
|
||||
return PACKET_EAGAIN;
|
||||
}
|
||||
else if (ret < 0) {
|
||||
} else if (ret < 0) {
|
||||
state->start = 0;
|
||||
/* an error which is not just because of blocking */
|
||||
return ret;
|
||||
}
|
||||
else if (ret == packet_type) {
|
||||
} 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_ex(session, packet_type, data, data_len,
|
||||
match_ofs, match_buf, match_len, 0);
|
||||
state->start = 0;
|
||||
return ret;
|
||||
}
|
||||
else if (ret == 0) {
|
||||
} else if (ret == 0) {
|
||||
/* nothing available, wait until data arrives or we time out */
|
||||
long left = LIBSSH2_READ_TIMEOUT - (time(NULL) - state->start);
|
||||
|
||||
@@ -1036,6 +1116,7 @@ int libssh2_packet_require_ex(LIBSSH2_SESSION *session, unsigned char packet_typ
|
||||
/* Only reached if the socket died */
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* }}} */
|
||||
|
||||
/* {{{ libssh2_packet_burn
|
||||
@@ -1043,7 +1124,9 @@ int libssh2_packet_require_ex(LIBSSH2_SESSION *session, unsigned char packet_typ
|
||||
* discards it
|
||||
* Used during KEX exchange to discard badly guessed KEX_INIT packets
|
||||
*/
|
||||
int libssh2_packet_burn(LIBSSH2_SESSION *session, libssh2_nonblocking_states *state)
|
||||
int
|
||||
libssh2_packet_burn(LIBSSH2_SESSION * session,
|
||||
libssh2_nonblocking_states * state)
|
||||
{
|
||||
unsigned char *data;
|
||||
unsigned long data_len;
|
||||
@@ -1056,32 +1139,34 @@ int libssh2_packet_burn(LIBSSH2_SESSION *session, libssh2_nonblocking_states *st
|
||||
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_ex
|
||||
(session, all_packets, &data, &data_len, 0, NULL, 0, 0) == 0) {
|
||||
i = data[0];
|
||||
/* A packet was available in the packet brigade, burn it */
|
||||
LIBSSH2_FREE(session, data);
|
||||
return i;
|
||||
}
|
||||
|
||||
_libssh2_debug(session, LIBSSH2_DBG_TRANS, "Blocking until packet becomes available to burn");
|
||||
_libssh2_debug(session, LIBSSH2_DBG_TRANS,
|
||||
"Blocking until packet becomes available to burn");
|
||||
*state = libssh2_NB_state_created;
|
||||
}
|
||||
|
||||
while (session->socket_state == LIBSSH2_SOCKET_CONNECTED) {
|
||||
if ((ret = libssh2_packet_read(session)) == PACKET_EAGAIN) {
|
||||
return PACKET_EAGAIN;
|
||||
}
|
||||
else if (ret < 0) {
|
||||
} else if (ret < 0) {
|
||||
*state = libssh2_NB_state_idle;
|
||||
return ret;
|
||||
}
|
||||
else if (ret == 0) {
|
||||
} else if (ret == 0) {
|
||||
/* FIXME: this might busyloop */
|
||||
continue;
|
||||
}
|
||||
|
||||
/* 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)) {
|
||||
if (0 ==
|
||||
libssh2_packet_ask_ex(session, ret, &data, &data_len, 0, NULL, 0,
|
||||
0)) {
|
||||
/* Smoke 'em if you got 'em */
|
||||
LIBSSH2_FREE(session, data);
|
||||
*state = libssh2_NB_state_idle;
|
||||
@@ -1092,6 +1177,7 @@ int libssh2_packet_burn(LIBSSH2_SESSION *session, libssh2_nonblocking_states *st
|
||||
/* Only reached if the socket died */
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* }}} */
|
||||
|
||||
/*
|
||||
@@ -1103,11 +1189,18 @@ int libssh2_packet_burn(LIBSSH2_SESSION *session, libssh2_nonblocking_states *st
|
||||
* 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)
|
||||
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)
|
||||
{
|
||||
if (libssh2_packet_askv_ex(session, packet_types, data, data_len, match_ofs, match_buf, match_len, 0) == 0) {
|
||||
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 */
|
||||
state->start = 0;
|
||||
@@ -1130,15 +1223,16 @@ int libssh2_packet_requirev_ex(LIBSSH2_SESSION *session, const unsigned char *pa
|
||||
if ((left <= 0) || (libssh2_waitsocket(session, 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_ex(session, packet_types, data,
|
||||
data_len, match_ofs, match_buf,
|
||||
match_len, 0);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1146,4 +1240,5 @@ int libssh2_packet_requirev_ex(LIBSSH2_SESSION *session, const unsigned char *pa
|
||||
state->start = 0;
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* }}} */
|
||||
|
92
src/pem.c
92
src/pem.c
@@ -37,18 +37,16 @@
|
||||
|
||||
#include "libssh2_priv.h"
|
||||
|
||||
static int readline (char *line, int line_size, FILE *fp)
|
||||
{
|
||||
if (!fgets(line, line_size, fp))
|
||||
static int
|
||||
readline(char *line, int line_size, FILE * fp)
|
||||
{
|
||||
if (!fgets(line, line_size, fp)) {
|
||||
return -1;
|
||||
}
|
||||
if (*line && line[strlen(line) - 1] == '\n')
|
||||
{
|
||||
if (*line && line[strlen(line) - 1] == '\n') {
|
||||
line[strlen(line) - 1] = '\0';
|
||||
}
|
||||
if (*line && line[strlen(line) - 1] == '\r')
|
||||
{
|
||||
if (*line && line[strlen(line) - 1] == '\r') {
|
||||
line[strlen(line) - 1] = '\0';
|
||||
}
|
||||
return 0;
|
||||
@@ -56,21 +54,19 @@ static int readline (char *line, int line_size, FILE *fp)
|
||||
|
||||
#define LINE_SIZE 128
|
||||
|
||||
int _libssh2_pem_parse (LIBSSH2_SESSION *session,
|
||||
int
|
||||
_libssh2_pem_parse(LIBSSH2_SESSION * session,
|
||||
const char *headerbegin,
|
||||
const char *headerend,
|
||||
FILE *fp,
|
||||
char **data, unsigned int *datalen)
|
||||
FILE * fp, char **data, unsigned int *datalen)
|
||||
{
|
||||
char line[LINE_SIZE];
|
||||
char *b64data = NULL;
|
||||
unsigned int b64datalen = 0;
|
||||
int ret;
|
||||
|
||||
do
|
||||
{
|
||||
if (readline(line, LINE_SIZE, fp))
|
||||
{
|
||||
do {
|
||||
if (readline(line, LINE_SIZE, fp)) {
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
@@ -78,18 +74,14 @@ int _libssh2_pem_parse (LIBSSH2_SESSION *session,
|
||||
|
||||
*line = '\0';
|
||||
|
||||
do
|
||||
{
|
||||
if (*line)
|
||||
{
|
||||
do {
|
||||
if (*line) {
|
||||
char *tmp;
|
||||
size_t linelen;
|
||||
|
||||
linelen = strlen(line);
|
||||
tmp = LIBSSH2_REALLOC (session, b64data,
|
||||
b64datalen + linelen);
|
||||
if (!tmp)
|
||||
{
|
||||
tmp = LIBSSH2_REALLOC(session, b64data, b64datalen + linelen);
|
||||
if (!tmp) {
|
||||
ret = -1;
|
||||
goto out;
|
||||
}
|
||||
@@ -98,16 +90,13 @@ int _libssh2_pem_parse (LIBSSH2_SESSION *session,
|
||||
b64datalen += linelen;
|
||||
}
|
||||
|
||||
if (readline(line, LINE_SIZE, fp))
|
||||
{
|
||||
if (readline(line, LINE_SIZE, fp)) {
|
||||
ret = -1;
|
||||
goto out;
|
||||
}
|
||||
} while (strcmp(line, headerend) != 0);
|
||||
|
||||
if (libssh2_base64_decode(session, data, datalen,
|
||||
b64data, b64datalen))
|
||||
{
|
||||
if (libssh2_base64_decode(session, data, datalen, b64data, b64datalen)) {
|
||||
ret = -1;
|
||||
goto out;
|
||||
}
|
||||
@@ -120,59 +109,51 @@ out:
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int read_asn1_length (const unsigned char *data,
|
||||
unsigned int datalen,
|
||||
unsigned int *len)
|
||||
static int
|
||||
read_asn1_length(const unsigned char *data,
|
||||
unsigned int datalen, unsigned int *len)
|
||||
{
|
||||
unsigned int lenlen;
|
||||
int nextpos;
|
||||
|
||||
if (datalen < 1)
|
||||
{
|
||||
if (datalen < 1) {
|
||||
return -1;
|
||||
}
|
||||
*len = data[0];
|
||||
|
||||
if (*len >= 0x80)
|
||||
{
|
||||
if (*len >= 0x80) {
|
||||
lenlen = *len & 0x7F;
|
||||
*len = data[1];
|
||||
if (1 + lenlen > datalen)
|
||||
{
|
||||
if (1 + lenlen > datalen) {
|
||||
return -1;
|
||||
}
|
||||
if (lenlen > 1)
|
||||
{
|
||||
if (lenlen > 1) {
|
||||
*len <<= 8;
|
||||
*len |= data[2];
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
lenlen = 0;
|
||||
}
|
||||
|
||||
nextpos = 1 + lenlen;
|
||||
if (lenlen > 2 || 1 + lenlen + *len > datalen)
|
||||
{
|
||||
if (lenlen > 2 || 1 + lenlen + *len > datalen) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
return nextpos;
|
||||
}
|
||||
|
||||
int _libssh2_pem_decode_sequence (unsigned char **data, unsigned int *datalen)
|
||||
int
|
||||
_libssh2_pem_decode_sequence(unsigned char **data, unsigned int *datalen)
|
||||
{
|
||||
unsigned int len;
|
||||
int lenlen;
|
||||
|
||||
if (*datalen < 1)
|
||||
{
|
||||
if (*datalen < 1) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
if ((*data)[0] != '\x30')
|
||||
{
|
||||
if ((*data)[0] != '\x30') {
|
||||
return -1;
|
||||
}
|
||||
|
||||
@@ -180,8 +161,7 @@ int _libssh2_pem_decode_sequence (unsigned char **data, unsigned int *datalen)
|
||||
(*datalen)--;
|
||||
|
||||
lenlen = read_asn1_length(*data, *datalen, &len);
|
||||
if (lenlen < 0 || lenlen + len != *datalen)
|
||||
{
|
||||
if (lenlen < 0 || lenlen + len != *datalen) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
@@ -191,19 +171,18 @@ int _libssh2_pem_decode_sequence (unsigned char **data, unsigned int *datalen)
|
||||
return 0;
|
||||
}
|
||||
|
||||
int _libssh2_pem_decode_integer (unsigned char **data, unsigned int *datalen,
|
||||
int
|
||||
_libssh2_pem_decode_integer(unsigned char **data, unsigned int *datalen,
|
||||
unsigned char **i, unsigned int *ilen)
|
||||
{
|
||||
unsigned int len;
|
||||
int lenlen;
|
||||
|
||||
if (*datalen < 1)
|
||||
{
|
||||
if (*datalen < 1) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
if ((*data)[0] != '\x02')
|
||||
{
|
||||
if ((*data)[0] != '\x02') {
|
||||
return -1;
|
||||
}
|
||||
|
||||
@@ -211,8 +190,7 @@ int _libssh2_pem_decode_integer (unsigned char **data, unsigned int *datalen,
|
||||
(*datalen)--;
|
||||
|
||||
lenlen = read_asn1_length(*data, *datalen, &len);
|
||||
if (lenlen < 0 || lenlen + len > *datalen)
|
||||
{
|
||||
if (lenlen < 0 || lenlen + len > *datalen) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
570
src/publickey.c
570
src/publickey.c
File diff suppressed because it is too large
Load Diff
435
src/scp.c
435
src/scp.c
@@ -46,7 +46,8 @@
|
||||
* 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)
|
||||
LIBSSH2_API LIBSSH2_CHANNEL *
|
||||
libssh2_scp_recv(LIBSSH2_SESSION * session, const char *path, struct stat * sb)
|
||||
{
|
||||
int path_len = strlen(path);
|
||||
int rc;
|
||||
@@ -63,21 +64,28 @@ LIBSSH2_API LIBSSH2_CHANNEL *libssh2_scp_recv(LIBSSH2_SESSION *session, const ch
|
||||
session->scpRecv_command_len++;
|
||||
}
|
||||
|
||||
session->scpRecv_command = LIBSSH2_ALLOC(session, session->scpRecv_command_len);
|
||||
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);
|
||||
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);
|
||||
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);
|
||||
memcpy(session->scpRecv_command + sizeof("scp -f ") - 1, path,
|
||||
path_len);
|
||||
}
|
||||
session->scpRecv_command[session->scpRecv_command_len - 1] = '\0';
|
||||
|
||||
_libssh2_debug(session, LIBSSH2_DBG_SCP, "Opening channel for SCP receive");
|
||||
_libssh2_debug(session, LIBSSH2_DBG_SCP,
|
||||
"Opening channel for SCP receive");
|
||||
|
||||
session->scpRecv_state = libssh2_NB_state_created;
|
||||
}
|
||||
@@ -85,18 +93,23 @@ LIBSSH2_API LIBSSH2_CHANNEL *libssh2_scp_recv(LIBSSH2_SESSION *session, const ch
|
||||
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);
|
||||
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) {
|
||||
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);
|
||||
} else if (libssh2_session_last_errno(session) ==
|
||||
LIBSSH2_ERROR_EAGAIN) {
|
||||
libssh2_error(session, LIBSSH2_ERROR_EAGAIN,
|
||||
"Would block starting up channel", 0);
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
@@ -107,12 +120,15 @@ LIBSSH2_API LIBSSH2_CHANNEL *libssh2_scp_recv(LIBSSH2_SESSION *session, const ch
|
||||
|
||||
if (session->scpRecv_state == libssh2_NB_state_sent) {
|
||||
/* Request SCP for the desired file */
|
||||
rc = libssh2_channel_process_startup(session->scpRecv_channel, "exec", sizeof("exec") - 1, (char *)session->scpRecv_command, session->scpRecv_command_len);
|
||||
rc = libssh2_channel_process_startup(session->scpRecv_channel, "exec",
|
||||
sizeof("exec") - 1,
|
||||
(char *) session->scpRecv_command,
|
||||
session->scpRecv_command_len);
|
||||
if (rc == PACKET_EAGAIN) {
|
||||
libssh2_error(session, LIBSSH2_ERROR_EAGAIN, "Would block requesting SCP startup", 0);
|
||||
libssh2_error(session, LIBSSH2_ERROR_EAGAIN,
|
||||
"Would block requesting SCP startup", 0);
|
||||
return NULL;
|
||||
}
|
||||
else if (rc) {
|
||||
} else if (rc) {
|
||||
LIBSSH2_FREE(session, session->scpRecv_command);
|
||||
session->scpRecv_command = NULL;
|
||||
goto scp_recv_error;
|
||||
@@ -128,12 +144,13 @@ LIBSSH2_API LIBSSH2_CHANNEL *libssh2_scp_recv(LIBSSH2_SESSION *session, const ch
|
||||
}
|
||||
|
||||
if (session->scpRecv_state == libssh2_NB_state_sent1) {
|
||||
rc = libssh2_channel_write_ex(session->scpRecv_channel, 0, (char *)session->scpRecv_response, 1);
|
||||
rc = libssh2_channel_write_ex(session->scpRecv_channel, 0,
|
||||
(char *) session->scpRecv_response, 1);
|
||||
if (rc == PACKET_EAGAIN) {
|
||||
libssh2_error(session, LIBSSH2_ERROR_EAGAIN, "Would block sending initial wakeup", 0);
|
||||
libssh2_error(session, LIBSSH2_ERROR_EAGAIN,
|
||||
"Would block sending initial wakeup", 0);
|
||||
return NULL;
|
||||
}
|
||||
else if (rc != 1) {
|
||||
} else if (rc != 1) {
|
||||
goto scp_recv_error;
|
||||
}
|
||||
|
||||
@@ -143,20 +160,26 @@ LIBSSH2_API LIBSSH2_CHANNEL *libssh2_scp_recv(LIBSSH2_SESSION *session, const ch
|
||||
session->scpRecv_state = libssh2_NB_state_sent2;
|
||||
}
|
||||
|
||||
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)) {
|
||||
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)) {
|
||||
unsigned char *s, *p;
|
||||
|
||||
if (session->scpRecv_state == libssh2_NB_state_sent2) {
|
||||
rc = libssh2_channel_read_ex(session->scpRecv_channel, 0,
|
||||
(char *)session->scpRecv_response + session->scpRecv_response_len, 1);
|
||||
(char *) session->
|
||||
scpRecv_response +
|
||||
session->scpRecv_response_len, 1);
|
||||
if (rc == PACKET_EAGAIN) {
|
||||
libssh2_error(session, LIBSSH2_ERROR_EAGAIN, "Would block waiting for SCP response", 0);
|
||||
libssh2_error(session, LIBSSH2_ERROR_EAGAIN,
|
||||
"Would block waiting for SCP response", 0);
|
||||
return NULL;
|
||||
}
|
||||
else if (rc <= 0) {
|
||||
} else if (rc <= 0) {
|
||||
/* Timeout, give up */
|
||||
libssh2_error(session, LIBSSH2_ERROR_SCP_PROTOCOL, "Timed out waiting for SCP response", 0);
|
||||
libssh2_error(session, LIBSSH2_ERROR_SCP_PROTOCOL,
|
||||
"Timed out waiting for SCP response", 0);
|
||||
goto scp_recv_error;
|
||||
}
|
||||
session->scpRecv_response_len++;
|
||||
@@ -166,17 +189,25 @@ LIBSSH2_API LIBSSH2_CHANNEL *libssh2_scp_recv(LIBSSH2_SESSION *session, const ch
|
||||
* Set this as the default error for here, if
|
||||
* we are successful it will be replaced
|
||||
*/
|
||||
libssh2_error(session, LIBSSH2_ERROR_SCP_PROTOCOL, "Invalid data in SCP response, missing Time data", 0);
|
||||
libssh2_error(session, LIBSSH2_ERROR_SCP_PROTOCOL,
|
||||
"Invalid data in SCP response, missing Time data",
|
||||
0);
|
||||
|
||||
session->scpRecv_err_len = libssh2_channel_packet_data_len(session->scpRecv_channel, 0);
|
||||
session->scpRecv_err_msg = LIBSSH2_ALLOC(session, session->scpRecv_err_len+1);
|
||||
session->scpRecv_err_len =
|
||||
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) {
|
||||
goto scp_recv_error;
|
||||
}
|
||||
memset(session->scpRecv_err_msg, 0, session->scpRecv_err_len+1);
|
||||
memset(session->scpRecv_err_msg, 0,
|
||||
session->scpRecv_err_len + 1);
|
||||
|
||||
/* Read the remote error message */
|
||||
rc = libssh2_channel_read_ex(session->scpRecv_channel, 0, session->scpRecv_err_msg, session->scpRecv_err_len);
|
||||
rc = libssh2_channel_read_ex(session->scpRecv_channel, 0,
|
||||
session->scpRecv_err_msg,
|
||||
session->scpRecv_err_len);
|
||||
if (rc <= 0) {
|
||||
/*
|
||||
* Since we have alread started reading this packet, it is
|
||||
@@ -184,29 +215,49 @@ LIBSSH2_API LIBSSH2_CHANNEL *libssh2_scp_recv(LIBSSH2_SESSION *session, const ch
|
||||
*/
|
||||
LIBSSH2_FREE(session, session->scpRecv_err_msg);
|
||||
session->scpRecv_err_msg = NULL;
|
||||
libssh2_error(session, LIBSSH2_ERROR_SCP_PROTOCOL, "Unknown error while getting error string", 0);
|
||||
libssh2_error(session, LIBSSH2_ERROR_SCP_PROTOCOL,
|
||||
"Unknown error while getting error string",
|
||||
0);
|
||||
goto scp_recv_error;
|
||||
}
|
||||
|
||||
libssh2_error(session, LIBSSH2_ERROR_SCP_PROTOCOL, session->scpRecv_err_msg, 1);
|
||||
libssh2_error(session, LIBSSH2_ERROR_SCP_PROTOCOL,
|
||||
session->scpRecv_err_msg, 1);
|
||||
session->scpRecv_err_msg = NULL;
|
||||
goto scp_recv_error;
|
||||
}
|
||||
|
||||
if ((session->scpRecv_response_len > 1) &&
|
||||
((session->scpRecv_response[session->scpRecv_response_len-1] < '0') ||
|
||||
(session->scpRecv_response[session->scpRecv_response_len-1] > '9')) &&
|
||||
(session->scpRecv_response[session->scpRecv_response_len-1] != ' ') &&
|
||||
(session->scpRecv_response[session->scpRecv_response_len-1] != '\r') &&
|
||||
(session->scpRecv_response[session->scpRecv_response_len-1] != '\n')) {
|
||||
libssh2_error(session, LIBSSH2_ERROR_SCP_PROTOCOL, "Invalid data in SCP response", 0);
|
||||
((session->
|
||||
scpRecv_response[session->scpRecv_response_len - 1] <
|
||||
'0')
|
||||
|| (session->
|
||||
scpRecv_response[session->scpRecv_response_len - 1] >
|
||||
'9'))
|
||||
&& (session->
|
||||
scpRecv_response[session->scpRecv_response_len - 1] !=
|
||||
' ')
|
||||
&& (session->
|
||||
scpRecv_response[session->scpRecv_response_len - 1] !=
|
||||
'\r')
|
||||
&& (session->
|
||||
scpRecv_response[session->scpRecv_response_len - 1] !=
|
||||
'\n')) {
|
||||
libssh2_error(session, LIBSSH2_ERROR_SCP_PROTOCOL,
|
||||
"Invalid data in SCP response", 0);
|
||||
goto scp_recv_error;
|
||||
}
|
||||
|
||||
if ((session->scpRecv_response_len < 9) || (session->scpRecv_response[session->scpRecv_response_len-1] != '\n')) {
|
||||
if (session->scpRecv_response_len == LIBSSH2_SCP_RESPONSE_BUFLEN) {
|
||||
if ((session->scpRecv_response_len < 9)
|
||||
|| (session->
|
||||
scpRecv_response[session->scpRecv_response_len - 1] !=
|
||||
'\n')) {
|
||||
if (session->scpRecv_response_len ==
|
||||
LIBSSH2_SCP_RESPONSE_BUFLEN) {
|
||||
/* You had your chance */
|
||||
libssh2_error(session, LIBSSH2_ERROR_SCP_PROTOCOL, "Unterminated response from SCP server", 0);
|
||||
libssh2_error(session, LIBSSH2_ERROR_SCP_PROTOCOL,
|
||||
"Unterminated response from SCP server",
|
||||
0);
|
||||
goto scp_recv_error;
|
||||
}
|
||||
/* Way too short to be an SCP response, or not done yet, short circuit */
|
||||
@@ -214,12 +265,21 @@ LIBSSH2_API LIBSSH2_CHANNEL *libssh2_scp_recv(LIBSSH2_SESSION *session, const ch
|
||||
}
|
||||
|
||||
/* We're guaranteed not to go under response_len == 0 by the logic above */
|
||||
while ((session->scpRecv_response[session->scpRecv_response_len-1] == '\r') || (session->scpRecv_response[session->scpRecv_response_len-1] == '\n')) session->scpRecv_response_len--;
|
||||
session->scpRecv_response[session->scpRecv_response_len] = '\0';
|
||||
while ((session->
|
||||
scpRecv_response[session->scpRecv_response_len - 1] ==
|
||||
'\r')
|
||||
|| (session->
|
||||
scpRecv_response[session->scpRecv_response_len -
|
||||
1] == '\n'))
|
||||
session->scpRecv_response_len--;
|
||||
session->scpRecv_response[session->scpRecv_response_len] =
|
||||
'\0';
|
||||
|
||||
if (session->scpRecv_response_len < 8) {
|
||||
/* EOL came too soon */
|
||||
libssh2_error(session, LIBSSH2_ERROR_SCP_PROTOCOL, "Invalid response from SCP server, too short", 0);
|
||||
libssh2_error(session, LIBSSH2_ERROR_SCP_PROTOCOL,
|
||||
"Invalid response from SCP server, too short",
|
||||
0);
|
||||
goto scp_recv_error;
|
||||
}
|
||||
|
||||
@@ -228,7 +288,9 @@ LIBSSH2_API LIBSSH2_CHANNEL *libssh2_scp_recv(LIBSSH2_SESSION *session, const ch
|
||||
p = (unsigned char *) strchr((char *) s, ' ');
|
||||
if (!p || ((p - s) <= 0)) {
|
||||
/* No spaces or space in the wrong spot */
|
||||
libssh2_error(session, LIBSSH2_ERROR_SCP_PROTOCOL, "Invalid response from SCP server, malformed mtime", 0);
|
||||
libssh2_error(session, LIBSSH2_ERROR_SCP_PROTOCOL,
|
||||
"Invalid response from SCP server, malformed mtime",
|
||||
0);
|
||||
goto scp_recv_error;
|
||||
}
|
||||
|
||||
@@ -237,13 +299,17 @@ LIBSSH2_API LIBSSH2_CHANNEL *libssh2_scp_recv(LIBSSH2_SESSION *session, const ch
|
||||
errno = 0;
|
||||
session->scpRecv_mtime = strtol((char *) s, NULL, 10);
|
||||
if (errno) {
|
||||
libssh2_error(session, LIBSSH2_ERROR_SCP_PROTOCOL, "Invalid response from SCP server, invalid mtime", 0);
|
||||
libssh2_error(session, LIBSSH2_ERROR_SCP_PROTOCOL,
|
||||
"Invalid response from SCP server, invalid mtime",
|
||||
0);
|
||||
goto scp_recv_error;
|
||||
}
|
||||
s = (unsigned char *) strchr((char *) p, ' ');
|
||||
if (!s || ((s - p) <= 0)) {
|
||||
/* No spaces or space in the wrong spot */
|
||||
libssh2_error(session, LIBSSH2_ERROR_SCP_PROTOCOL, "Invalid response from SCP server, malformed mtime.usec", 0);
|
||||
libssh2_error(session, LIBSSH2_ERROR_SCP_PROTOCOL,
|
||||
"Invalid response from SCP server, malformed mtime.usec",
|
||||
0);
|
||||
goto scp_recv_error;
|
||||
}
|
||||
|
||||
@@ -252,7 +318,9 @@ LIBSSH2_API LIBSSH2_CHANNEL *libssh2_scp_recv(LIBSSH2_SESSION *session, const ch
|
||||
p = (unsigned char *) strchr((char *) s, ' ');
|
||||
if (!p || ((p - s) <= 0)) {
|
||||
/* No spaces or space in the wrong spot */
|
||||
libssh2_error(session, LIBSSH2_ERROR_SCP_PROTOCOL, "Invalid response from SCP server, too short or malformed", 0);
|
||||
libssh2_error(session, LIBSSH2_ERROR_SCP_PROTOCOL,
|
||||
"Invalid response from SCP server, too short or malformed",
|
||||
0);
|
||||
goto scp_recv_error;
|
||||
}
|
||||
|
||||
@@ -261,7 +329,9 @@ LIBSSH2_API LIBSSH2_CHANNEL *libssh2_scp_recv(LIBSSH2_SESSION *session, const ch
|
||||
errno = 0;
|
||||
session->scpRecv_atime = strtol((char *) s, NULL, 10);
|
||||
if (errno) {
|
||||
libssh2_error(session, LIBSSH2_ERROR_SCP_PROTOCOL, "Invalid response from SCP server, invalid atime", 0);
|
||||
libssh2_error(session, LIBSSH2_ERROR_SCP_PROTOCOL,
|
||||
"Invalid response from SCP server, invalid atime",
|
||||
0);
|
||||
goto scp_recv_error;
|
||||
}
|
||||
|
||||
@@ -272,16 +342,20 @@ LIBSSH2_API LIBSSH2_CHANNEL *libssh2_scp_recv(LIBSSH2_SESSION *session, const ch
|
||||
}
|
||||
|
||||
if (session->scpRecv_state == libssh2_NB_state_sent3) {
|
||||
rc = libssh2_channel_write_ex(session->scpRecv_channel, 0, (char *)session->scpRecv_response, 1);
|
||||
rc = libssh2_channel_write_ex(session->scpRecv_channel, 0,
|
||||
(char *) session->
|
||||
scpRecv_response, 1);
|
||||
if (rc == PACKET_EAGAIN) {
|
||||
libssh2_error(session, LIBSSH2_ERROR_EAGAIN, "Would block waiting to send SCP ACK", 0);
|
||||
libssh2_error(session, LIBSSH2_ERROR_EAGAIN,
|
||||
"Would block waiting to send SCP ACK", 0);
|
||||
return NULL;
|
||||
}
|
||||
else if (rc != 1) {
|
||||
} else if (rc != 1) {
|
||||
goto scp_recv_error;
|
||||
}
|
||||
|
||||
_libssh2_debug(session, LIBSSH2_DBG_SCP, "mtime = %ld, atime = %ld", session->scpRecv_mtime, session->scpRecv_atime);
|
||||
_libssh2_debug(session, LIBSSH2_DBG_SCP,
|
||||
"mtime = %ld, atime = %ld",
|
||||
session->scpRecv_mtime, session->scpRecv_atime);
|
||||
|
||||
/* We *should* check that atime.usec is valid, but why let that stop use? */
|
||||
break;
|
||||
@@ -297,42 +371,62 @@ LIBSSH2_API LIBSSH2_CHANNEL *libssh2_scp_recv(LIBSSH2_SESSION *session, const ch
|
||||
session->scpRecv_state = libssh2_NB_state_sent5;
|
||||
}
|
||||
|
||||
if ((session->scpRecv_state == libssh2_NB_state_sent5) || (session->scpRecv_state == libssh2_NB_state_sent6)) {
|
||||
if ((session->scpRecv_state == libssh2_NB_state_sent5)
|
||||
|| (session->scpRecv_state == libssh2_NB_state_sent6)) {
|
||||
while (session->scpRecv_response_len < LIBSSH2_SCP_RESPONSE_BUFLEN) {
|
||||
char *s, *p, *e = NULL;
|
||||
|
||||
if (session->scpRecv_state == libssh2_NB_state_sent5) {
|
||||
rc = libssh2_channel_read_ex(session->scpRecv_channel, 0,
|
||||
(char *)session->scpRecv_response + session->scpRecv_response_len, 1);
|
||||
(char *) session->
|
||||
scpRecv_response +
|
||||
session->scpRecv_response_len, 1);
|
||||
if (rc == PACKET_EAGAIN) {
|
||||
libssh2_error(session, LIBSSH2_ERROR_EAGAIN, "Would block waiting for SCP response", 0);
|
||||
libssh2_error(session, LIBSSH2_ERROR_EAGAIN,
|
||||
"Would block waiting for SCP response", 0);
|
||||
return NULL;
|
||||
}
|
||||
else if (rc <= 0) {
|
||||
} else if (rc <= 0) {
|
||||
/* Timeout, give up */
|
||||
libssh2_error(session, LIBSSH2_ERROR_SCP_PROTOCOL, "Timed out waiting for SCP response", 0);
|
||||
libssh2_error(session, LIBSSH2_ERROR_SCP_PROTOCOL,
|
||||
"Timed out waiting for SCP response", 0);
|
||||
goto scp_recv_error;
|
||||
}
|
||||
session->scpRecv_response_len++;
|
||||
|
||||
if (session->scpRecv_response[0] != 'C') {
|
||||
libssh2_error(session, LIBSSH2_ERROR_SCP_PROTOCOL, "Invalid response from SCP server", 0);
|
||||
libssh2_error(session, LIBSSH2_ERROR_SCP_PROTOCOL,
|
||||
"Invalid response from SCP server", 0);
|
||||
goto scp_recv_error;
|
||||
}
|
||||
|
||||
if ((session->scpRecv_response_len > 1) &&
|
||||
(session->scpRecv_response[session->scpRecv_response_len-1] != '\r') &&
|
||||
(session->scpRecv_response[session->scpRecv_response_len-1] != '\n') &&
|
||||
((session->scpRecv_response[session->scpRecv_response_len-1] < 32) ||
|
||||
(session->scpRecv_response[session->scpRecv_response_len-1] > 126))) {
|
||||
libssh2_error(session, LIBSSH2_ERROR_SCP_PROTOCOL, "Invalid data in SCP response", 0);
|
||||
(session->
|
||||
scpRecv_response[session->scpRecv_response_len - 1] !=
|
||||
'\r')
|
||||
&& (session->
|
||||
scpRecv_response[session->scpRecv_response_len - 1] !=
|
||||
'\n')
|
||||
&&
|
||||
((session->
|
||||
scpRecv_response[session->scpRecv_response_len - 1] < 32)
|
||||
|| (session->
|
||||
scpRecv_response[session->scpRecv_response_len - 1] >
|
||||
126))) {
|
||||
libssh2_error(session, LIBSSH2_ERROR_SCP_PROTOCOL,
|
||||
"Invalid data in SCP response", 0);
|
||||
goto scp_recv_error;
|
||||
}
|
||||
|
||||
if ((session->scpRecv_response_len < 7) || (session->scpRecv_response[session->scpRecv_response_len-1] != '\n')) {
|
||||
if (session->scpRecv_response_len == LIBSSH2_SCP_RESPONSE_BUFLEN) {
|
||||
if ((session->scpRecv_response_len < 7)
|
||||
|| (session->
|
||||
scpRecv_response[session->scpRecv_response_len - 1] !=
|
||||
'\n')) {
|
||||
if (session->scpRecv_response_len ==
|
||||
LIBSSH2_SCP_RESPONSE_BUFLEN) {
|
||||
/* You had your chance */
|
||||
libssh2_error(session, LIBSSH2_ERROR_SCP_PROTOCOL, "Unterminated response from SCP server", 0);
|
||||
libssh2_error(session, LIBSSH2_ERROR_SCP_PROTOCOL,
|
||||
"Unterminated response from SCP server",
|
||||
0);
|
||||
goto scp_recv_error;
|
||||
}
|
||||
/* Way too short to be an SCP response, or not done yet, short circuit */
|
||||
@@ -340,15 +434,22 @@ LIBSSH2_API LIBSSH2_CHANNEL *libssh2_scp_recv(LIBSSH2_SESSION *session, const ch
|
||||
}
|
||||
|
||||
/* We're guaranteed not to go under response_len == 0 by the logic above */
|
||||
while ((session->scpRecv_response[session->scpRecv_response_len-1] == '\r') ||
|
||||
(session->scpRecv_response[session->scpRecv_response_len-1] == '\n')) {
|
||||
while ((session->
|
||||
scpRecv_response[session->scpRecv_response_len - 1] ==
|
||||
'\r')
|
||||
|| (session->
|
||||
scpRecv_response[session->scpRecv_response_len -
|
||||
1] == '\n')) {
|
||||
session->scpRecv_response_len--;
|
||||
}
|
||||
session->scpRecv_response[session->scpRecv_response_len] = '\0';
|
||||
session->scpRecv_response[session->scpRecv_response_len] =
|
||||
'\0';
|
||||
|
||||
if (session->scpRecv_response_len < 6) {
|
||||
/* EOL came too soon */
|
||||
libssh2_error(session, LIBSSH2_ERROR_SCP_PROTOCOL, "Invalid response from SCP server, too short", 0);
|
||||
libssh2_error(session, LIBSSH2_ERROR_SCP_PROTOCOL,
|
||||
"Invalid response from SCP server, too short",
|
||||
0);
|
||||
goto scp_recv_error;
|
||||
}
|
||||
|
||||
@@ -357,7 +458,9 @@ LIBSSH2_API LIBSSH2_CHANNEL *libssh2_scp_recv(LIBSSH2_SESSION *session, const ch
|
||||
p = strchr(s, ' ');
|
||||
if (!p || ((p - s) <= 0)) {
|
||||
/* No spaces or space in the wrong spot */
|
||||
libssh2_error(session, LIBSSH2_ERROR_SCP_PROTOCOL, "Invalid response from SCP server, malformed mode", 0);
|
||||
libssh2_error(session, LIBSSH2_ERROR_SCP_PROTOCOL,
|
||||
"Invalid response from SCP server, malformed mode",
|
||||
0);
|
||||
goto scp_recv_error;
|
||||
}
|
||||
|
||||
@@ -366,14 +469,17 @@ LIBSSH2_API LIBSSH2_CHANNEL *libssh2_scp_recv(LIBSSH2_SESSION *session, const ch
|
||||
errno = 0;
|
||||
session->scpRecv_mode = strtol(s, &e, 8);
|
||||
if ((e && *e) || errno) {
|
||||
libssh2_error(session, LIBSSH2_ERROR_SCP_PROTOCOL, "Invalid response from SCP server, invalid mode", 0);
|
||||
libssh2_error(session, LIBSSH2_ERROR_SCP_PROTOCOL,
|
||||
"Invalid response from SCP server, invalid mode",
|
||||
0);
|
||||
goto scp_recv_error;
|
||||
}
|
||||
|
||||
s = strchr(p, ' ');
|
||||
if (!s || ((s - p) <= 0)) {
|
||||
/* No spaces or space in the wrong spot */
|
||||
libssh2_error(session, LIBSSH2_ERROR_SCP_PROTOCOL, "Invalid response from SCP server, too short or malformed",
|
||||
libssh2_error(session, LIBSSH2_ERROR_SCP_PROTOCOL,
|
||||
"Invalid response from SCP server, too short or malformed",
|
||||
0);
|
||||
goto scp_recv_error;
|
||||
}
|
||||
@@ -383,7 +489,9 @@ LIBSSH2_API LIBSSH2_CHANNEL *libssh2_scp_recv(LIBSSH2_SESSION *session, const ch
|
||||
errno = 0;
|
||||
session->scpRecv_size = strtol(p, &e, 10);
|
||||
if ((e && *e) || errno) {
|
||||
libssh2_error(session, LIBSSH2_ERROR_SCP_PROTOCOL, "Invalid response from SCP server, invalid size", 0);
|
||||
libssh2_error(session, LIBSSH2_ERROR_SCP_PROTOCOL,
|
||||
"Invalid response from SCP server, invalid size",
|
||||
0);
|
||||
goto scp_recv_error;
|
||||
}
|
||||
|
||||
@@ -394,15 +502,19 @@ LIBSSH2_API LIBSSH2_CHANNEL *libssh2_scp_recv(LIBSSH2_SESSION *session, const ch
|
||||
}
|
||||
|
||||
if (session->scpRecv_state == libssh2_NB_state_sent6) {
|
||||
rc = libssh2_channel_write_ex(session->scpRecv_channel, 0, (char *)session->scpRecv_response, 1);
|
||||
rc = libssh2_channel_write_ex(session->scpRecv_channel, 0,
|
||||
(char *) session->
|
||||
scpRecv_response, 1);
|
||||
if (rc == PACKET_EAGAIN) {
|
||||
libssh2_error(session, LIBSSH2_ERROR_EAGAIN, "Would block sending SCP ACK", 0);
|
||||
libssh2_error(session, LIBSSH2_ERROR_EAGAIN,
|
||||
"Would block sending SCP ACK", 0);
|
||||
return NULL;
|
||||
}
|
||||
else if (rc != 1) {
|
||||
} else if (rc != 1) {
|
||||
goto scp_recv_error;
|
||||
}
|
||||
_libssh2_debug(session, LIBSSH2_DBG_SCP, "mode = 0%lo size = %ld", session->scpRecv_mode, session->scpRecv_size);
|
||||
_libssh2_debug(session, LIBSSH2_DBG_SCP,
|
||||
"mode = 0%lo size = %ld", session->scpRecv_mode,
|
||||
session->scpRecv_size);
|
||||
|
||||
/* We *should* check that basename is valid, but why let that stop us? */
|
||||
break;
|
||||
@@ -430,6 +542,7 @@ scp_recv_error:
|
||||
session->scpRecv_state = libssh2_NB_state_idle;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* }}} */
|
||||
|
||||
/* {{{ libssh2_scp_send_ex
|
||||
@@ -440,7 +553,8 @@ scp_recv_error:
|
||||
* 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)
|
||||
libssh2_scp_send_ex(LIBSSH2_SESSION * session, const char *path, int mode,
|
||||
size_t size, long mtime, long atime)
|
||||
{
|
||||
int path_len = strlen(path);
|
||||
unsigned const char *base;
|
||||
@@ -453,30 +567,39 @@ libssh2_scp_send_ex(LIBSSH2_SESSION *session, const char *path, int mode, size_t
|
||||
session->scpSend_command_len++;
|
||||
}
|
||||
|
||||
session->scpSend_command = LIBSSH2_ALLOC(session, session->scpSend_command_len);
|
||||
session->scpSend_command =
|
||||
LIBSSH2_ALLOC(session, session->scpSend_command_len);
|
||||
if (!session->scpSend_command) {
|
||||
libssh2_error(session, LIBSSH2_ERROR_ALLOC, "Unable to allocate a command buffer for scp session", 0);
|
||||
libssh2_error(session, LIBSSH2_ERROR_ALLOC,
|
||||
"Unable to allocate a command buffer for scp session",
|
||||
0);
|
||||
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);
|
||||
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);
|
||||
memcpy(session->scpSend_command + sizeof("scp -t ") - 1, path,
|
||||
path_len);
|
||||
}
|
||||
session->scpSend_command[session->scpSend_command_len - 1] = '\0';
|
||||
|
||||
_libssh2_debug(session, LIBSSH2_DBG_SCP, "Opening channel for SCP send");
|
||||
_libssh2_debug(session, LIBSSH2_DBG_SCP,
|
||||
"Opening channel for SCP send");
|
||||
/* Allocate a channel */
|
||||
|
||||
session->scpSend_state = libssh2_NB_state_created;
|
||||
}
|
||||
|
||||
if (session->scpSend_state == libssh2_NB_state_created) {
|
||||
session->scpSend_channel = libssh2_channel_open_ex(session, "session", sizeof("session") - 1,
|
||||
LIBSSH2_CHANNEL_WINDOW_DEFAULT, LIBSSH2_CHANNEL_PACKET_DEFAULT, NULL, 0);
|
||||
session->scpSend_channel =
|
||||
libssh2_channel_open_ex(session, "session", sizeof("session") - 1,
|
||||
LIBSSH2_CHANNEL_WINDOW_DEFAULT,
|
||||
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 */
|
||||
@@ -484,9 +607,10 @@ libssh2_scp_send_ex(LIBSSH2_SESSION *session, const char *path, int mode, size_t
|
||||
session->scpSend_command = NULL;
|
||||
session->scpSend_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);
|
||||
} else if (libssh2_session_last_errno(session) ==
|
||||
LIBSSH2_ERROR_EAGAIN) {
|
||||
libssh2_error(session, LIBSSH2_ERROR_EAGAIN,
|
||||
"Would block starting up channel", 0);
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
@@ -496,17 +620,20 @@ libssh2_scp_send_ex(LIBSSH2_SESSION *session, const char *path, int mode, size_t
|
||||
|
||||
if (session->scpSend_state == libssh2_NB_state_sent) {
|
||||
/* Request SCP for the desired file */
|
||||
rc = libssh2_channel_process_startup(session->scpSend_channel, "exec", sizeof("exec") - 1,
|
||||
(char *)session->scpSend_command, session->scpSend_command_len);
|
||||
rc = libssh2_channel_process_startup(session->scpSend_channel, "exec",
|
||||
sizeof("exec") - 1,
|
||||
(char *) session->scpSend_command,
|
||||
session->scpSend_command_len);
|
||||
if (rc == PACKET_EAGAIN) {
|
||||
libssh2_error(session, LIBSSH2_ERROR_EAGAIN, "Would block requesting SCP startup", 0);
|
||||
libssh2_error(session, LIBSSH2_ERROR_EAGAIN,
|
||||
"Would block requesting SCP startup", 0);
|
||||
return NULL;
|
||||
}
|
||||
else if (rc) {
|
||||
} 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, "Unknown error while getting error string", 0);
|
||||
libssh2_error(session, LIBSSH2_ERROR_SCP_PROTOCOL,
|
||||
"Unknown error while getting error string", 0);
|
||||
goto scp_send_error;
|
||||
}
|
||||
LIBSSH2_FREE(session, session->scpSend_command);
|
||||
@@ -517,21 +644,26 @@ libssh2_scp_send_ex(LIBSSH2_SESSION *session, const char *path, int mode, size_t
|
||||
|
||||
if (session->scpSend_state == libssh2_NB_state_sent1) {
|
||||
/* Wait for ACK */
|
||||
rc = libssh2_channel_read_ex(session->scpSend_channel, 0, (char *)session->scpSend_response, 1);
|
||||
rc = libssh2_channel_read_ex(session->scpSend_channel, 0,
|
||||
(char *) session->scpSend_response, 1);
|
||||
if (rc == PACKET_EAGAIN) {
|
||||
libssh2_error(session, LIBSSH2_ERROR_EAGAIN, "Would block waiting for response from remote", 0);
|
||||
libssh2_error(session, LIBSSH2_ERROR_EAGAIN,
|
||||
"Would block waiting for response from remote", 0);
|
||||
return NULL;
|
||||
}
|
||||
else if ((rc <= 0) || (session->scpSend_response[0] != 0)) {
|
||||
libssh2_error(session, LIBSSH2_ERROR_SCP_PROTOCOL, "Invalid ACK response from remote", 0);
|
||||
} else if ((rc <= 0) || (session->scpSend_response[0] != 0)) {
|
||||
libssh2_error(session, LIBSSH2_ERROR_SCP_PROTOCOL,
|
||||
"Invalid ACK response from remote", 0);
|
||||
goto scp_send_error;
|
||||
}
|
||||
|
||||
if (mtime || atime) {
|
||||
/* Send mtime and atime to be used for file */
|
||||
session->scpSend_response_len = snprintf((char *)session->scpSend_response, LIBSSH2_SCP_RESPONSE_BUFLEN,
|
||||
"T%ld 0 %ld 0\n", mtime, atime);
|
||||
_libssh2_debug(session, LIBSSH2_DBG_SCP, "Sent %s", session->scpSend_response);
|
||||
session->scpSend_response_len =
|
||||
snprintf((char *) session->scpSend_response,
|
||||
LIBSSH2_SCP_RESPONSE_BUFLEN, "T%ld 0 %ld 0\n", mtime,
|
||||
atime);
|
||||
_libssh2_debug(session, LIBSSH2_DBG_SCP, "Sent %s",
|
||||
session->scpSend_response);
|
||||
}
|
||||
|
||||
session->scpSend_state = libssh2_NB_state_sent2;
|
||||
@@ -540,14 +672,16 @@ libssh2_scp_send_ex(LIBSSH2_SESSION *session, const char *path, int mode, size_t
|
||||
/* Send mtime and atime to be used for file */
|
||||
if (mtime || atime) {
|
||||
if (session->scpSend_state == libssh2_NB_state_sent2) {
|
||||
rc = libssh2_channel_write_ex(session->scpSend_channel, 0, (char *)session->scpSend_response,
|
||||
rc = libssh2_channel_write_ex(session->scpSend_channel, 0,
|
||||
(char *) session->scpSend_response,
|
||||
session->scpSend_response_len);
|
||||
if (rc == PACKET_EAGAIN) {
|
||||
libssh2_error(session, LIBSSH2_ERROR_EAGAIN, "Would block sending time data for SCP file", 0);
|
||||
libssh2_error(session, LIBSSH2_ERROR_EAGAIN,
|
||||
"Would block sending time data for SCP file", 0);
|
||||
return NULL;
|
||||
}
|
||||
else if (rc != session->scpSend_response_len) {
|
||||
libssh2_error(session, LIBSSH2_ERROR_SOCKET_SEND, "Unable to send time data for SCP file", 0);
|
||||
} else if (rc != session->scpSend_response_len) {
|
||||
libssh2_error(session, LIBSSH2_ERROR_SOCKET_SEND,
|
||||
"Unable to send time data for SCP file", 0);
|
||||
goto scp_send_error;
|
||||
}
|
||||
|
||||
@@ -556,13 +690,16 @@ libssh2_scp_send_ex(LIBSSH2_SESSION *session, const char *path, int mode, size_t
|
||||
|
||||
if (session->scpSend_state == libssh2_NB_state_sent3) {
|
||||
/* Wait for ACK */
|
||||
rc = libssh2_channel_read_ex(session->scpSend_channel, 0, (char *)session->scpSend_response, 1);
|
||||
rc = libssh2_channel_read_ex(session->scpSend_channel, 0,
|
||||
(char *) session->scpSend_response,
|
||||
1);
|
||||
if (rc == PACKET_EAGAIN) {
|
||||
libssh2_error(session, LIBSSH2_ERROR_EAGAIN, "Would block waiting for response", 0);
|
||||
libssh2_error(session, LIBSSH2_ERROR_EAGAIN,
|
||||
"Would block waiting for response", 0);
|
||||
return NULL;
|
||||
}
|
||||
else if ((rc <= 0) || (session->scpSend_response[0] != 0)) {
|
||||
libssh2_error(session, LIBSSH2_ERROR_SCP_PROTOCOL, "Invalid ACK response from remote", 0);
|
||||
} else if ((rc <= 0) || (session->scpSend_response[0] != 0)) {
|
||||
libssh2_error(session, LIBSSH2_ERROR_SCP_PROTOCOL,
|
||||
"Invalid ACK response from remote", 0);
|
||||
goto scp_send_error;
|
||||
}
|
||||
|
||||
@@ -583,22 +720,27 @@ libssh2_scp_send_ex(LIBSSH2_SESSION *session, const char *path, int mode, size_t
|
||||
base = (unsigned char *) path;
|
||||
}
|
||||
|
||||
session->scpSend_response_len = snprintf((char *)session->scpSend_response, LIBSSH2_SCP_RESPONSE_BUFLEN,
|
||||
"C0%o %lu %s\n", mode, (unsigned long)size, base);
|
||||
_libssh2_debug(session, LIBSSH2_DBG_SCP, "Sent %s", session->scpSend_response);
|
||||
session->scpSend_response_len =
|
||||
snprintf((char *) session->scpSend_response,
|
||||
LIBSSH2_SCP_RESPONSE_BUFLEN, "C0%o %lu %s\n", mode,
|
||||
(unsigned long) size, base);
|
||||
_libssh2_debug(session, LIBSSH2_DBG_SCP, "Sent %s",
|
||||
session->scpSend_response);
|
||||
|
||||
session->scpSend_state = libssh2_NB_state_sent5;
|
||||
}
|
||||
|
||||
if (session->scpSend_state == libssh2_NB_state_sent5) {
|
||||
rc = libssh2_channel_write_ex(session->scpSend_channel, 0, (char *)session->scpSend_response,
|
||||
rc = libssh2_channel_write_ex(session->scpSend_channel, 0,
|
||||
(char *) session->scpSend_response,
|
||||
session->scpSend_response_len);
|
||||
if (rc == PACKET_EAGAIN) {
|
||||
libssh2_error(session, LIBSSH2_ERROR_EAGAIN, "Would block send core file data for SCP file", 0);
|
||||
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) {
|
||||
libssh2_error(session, LIBSSH2_ERROR_SOCKET_SEND, "Unable to send core file data for SCP file", 0);
|
||||
} else if (rc != 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;
|
||||
}
|
||||
|
||||
@@ -607,31 +749,37 @@ libssh2_scp_send_ex(LIBSSH2_SESSION *session, const char *path, int mode, size_t
|
||||
|
||||
if (session->scpSend_state == libssh2_NB_state_sent6) {
|
||||
/* Wait for ACK */
|
||||
rc = libssh2_channel_read_ex(session->scpSend_channel, 0, (char *)session->scpSend_response, 1);
|
||||
rc = libssh2_channel_read_ex(session->scpSend_channel, 0,
|
||||
(char *) session->scpSend_response, 1);
|
||||
if (rc == PACKET_EAGAIN) {
|
||||
libssh2_error(session, LIBSSH2_ERROR_EAGAIN, "Would block waiting for response", 0);
|
||||
libssh2_error(session, LIBSSH2_ERROR_EAGAIN,
|
||||
"Would block waiting for response", 0);
|
||||
return NULL;
|
||||
}
|
||||
else if (rc <= 0) {
|
||||
libssh2_error(session, LIBSSH2_ERROR_SCP_PROTOCOL, "Invalid ACK response from remote", 0);
|
||||
} else if (rc <= 0) {
|
||||
libssh2_error(session, LIBSSH2_ERROR_SCP_PROTOCOL,
|
||||
"Invalid ACK response from remote", 0);
|
||||
goto scp_send_error;
|
||||
}
|
||||
else if (session->scpSend_response[0] != 0) {
|
||||
} else if (session->scpSend_response[0] != 0) {
|
||||
/*
|
||||
* Set this as the default error for here, if
|
||||
* we are successful it will be replaced
|
||||
*/
|
||||
libssh2_error(session, LIBSSH2_ERROR_SCP_PROTOCOL, "Invalid ACK response from remote", 0);
|
||||
libssh2_error(session, LIBSSH2_ERROR_SCP_PROTOCOL,
|
||||
"Invalid ACK response from remote", 0);
|
||||
|
||||
session->scpSend_err_len = libssh2_channel_packet_data_len(session->scpSend_channel, 0);
|
||||
session->scpSend_err_msg = LIBSSH2_ALLOC(session, session->scpSend_err_len+1);
|
||||
session->scpSend_err_len =
|
||||
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) {
|
||||
goto scp_send_error;
|
||||
}
|
||||
memset(session->scpSend_err_msg, 0, session->scpSend_err_len + 1);
|
||||
|
||||
/* Read the remote error message */
|
||||
rc = libssh2_channel_read_ex(session->scpSend_channel, 0, session->scpSend_err_msg, session->scpSend_err_len);
|
||||
rc = libssh2_channel_read_ex(session->scpSend_channel, 0,
|
||||
session->scpSend_err_msg,
|
||||
session->scpSend_err_len);
|
||||
if (rc <= 0) {
|
||||
/*
|
||||
* Since we have alread started reading this packet, it is
|
||||
@@ -642,7 +790,8 @@ libssh2_scp_send_ex(LIBSSH2_SESSION *session, const char *path, int mode, size_t
|
||||
goto scp_send_error;
|
||||
}
|
||||
|
||||
libssh2_error(session, LIBSSH2_ERROR_SCP_PROTOCOL, session->scpSend_err_msg, 1);
|
||||
libssh2_error(session, LIBSSH2_ERROR_SCP_PROTOCOL,
|
||||
session->scpSend_err_msg, 1);
|
||||
session->scpSend_err_msg = NULL;
|
||||
goto scp_send_error;
|
||||
}
|
||||
@@ -658,5 +807,5 @@ scp_send_error:
|
||||
session->scpSend_state = libssh2_NB_state_idle;
|
||||
return NULL;
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
/* }}} */
|
||||
|
362
src/session.c
362
src/session.c
@@ -52,29 +52,35 @@
|
||||
|
||||
/* {{{ libssh2_default_alloc
|
||||
*/
|
||||
static LIBSSH2_ALLOC_FUNC(libssh2_default_alloc)
|
||||
static
|
||||
LIBSSH2_ALLOC_FUNC(libssh2_default_alloc)
|
||||
{
|
||||
(void) abstract;
|
||||
return malloc(count);
|
||||
}
|
||||
|
||||
/* }}} */
|
||||
|
||||
/* {{{ libssh2_default_free
|
||||
*/
|
||||
static LIBSSH2_FREE_FUNC(libssh2_default_free)
|
||||
static
|
||||
LIBSSH2_FREE_FUNC(libssh2_default_free)
|
||||
{
|
||||
(void) abstract;
|
||||
free(ptr);
|
||||
}
|
||||
|
||||
/* }}} */
|
||||
|
||||
/* {{{ libssh2_default_realloc
|
||||
*/
|
||||
static LIBSSH2_REALLOC_FUNC(libssh2_default_realloc)
|
||||
static
|
||||
LIBSSH2_REALLOC_FUNC(libssh2_default_realloc)
|
||||
{
|
||||
(void) abstract;
|
||||
return realloc(ptr, count);
|
||||
}
|
||||
|
||||
/* }}} */
|
||||
|
||||
/* {{{ libssh2_banner_receive
|
||||
@@ -82,7 +88,8 @@ static LIBSSH2_REALLOC_FUNC(libssh2_default_realloc)
|
||||
* 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)
|
||||
static int
|
||||
libssh2_banner_receive(LIBSSH2_SESSION * session)
|
||||
{
|
||||
int ret;
|
||||
int banner_len;
|
||||
@@ -96,10 +103,13 @@ static int libssh2_banner_receive(LIBSSH2_SESSION *session)
|
||||
}
|
||||
|
||||
while ((banner_len < (int) sizeof(session->banner_TxRx_banner)) &&
|
||||
((banner_len == 0) || (session->banner_TxRx_banner[banner_len-1] != '\n'))) {
|
||||
((banner_len == 0)
|
||||
|| (session->banner_TxRx_banner[banner_len - 1] != '\n'))) {
|
||||
char c = '\0';
|
||||
|
||||
ret = recv(session->socket_fd, &c, 1, LIBSSH2_SOCKET_RECV_FLAGS(session));
|
||||
ret =
|
||||
recv(session->socket_fd, &c, 1,
|
||||
LIBSSH2_SOCKET_RECV_FLAGS(session));
|
||||
|
||||
if (ret < 0) {
|
||||
#ifdef WIN32
|
||||
@@ -125,15 +135,18 @@ static int libssh2_banner_receive(LIBSSH2_SESSION *session)
|
||||
if (errno == EAGAIN) {
|
||||
session->banner_TxRx_total_send = banner_len;
|
||||
return PACKET_EAGAIN;
|
||||
} else {
|
||||
}
|
||||
|
||||
/* Some kinda error */
|
||||
session->banner_TxRx_state = libssh2_NB_state_idle;
|
||||
session->banner_TxRx_total_send = 0;
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
if (ret <= 0) continue;
|
||||
if (ret == 0) {
|
||||
session->socket_state = LIBSSH2_SOCKET_DISCONNECTED;
|
||||
return PACKET_FAIL;
|
||||
}
|
||||
|
||||
if (c == '\0') {
|
||||
/* NULLs are not allowed in SSH banners */
|
||||
@@ -155,18 +168,22 @@ static int libssh2_banner_receive(LIBSSH2_SESSION *session)
|
||||
session->banner_TxRx_state = libssh2_NB_state_idle;
|
||||
session->banner_TxRx_total_send = 0;
|
||||
|
||||
if (!banner_len) return 1;
|
||||
if (!banner_len)
|
||||
return 1;
|
||||
|
||||
session->remote.banner = LIBSSH2_ALLOC(session, banner_len + 1);
|
||||
if (!session->remote.banner) {
|
||||
libssh2_error(session, LIBSSH2_ERROR_ALLOC, "Error allocating space for remote banner", 0);
|
||||
libssh2_error(session, LIBSSH2_ERROR_ALLOC,
|
||||
"Error allocating space for remote banner", 0);
|
||||
return 1;
|
||||
}
|
||||
memcpy(session->remote.banner, session->banner_TxRx_banner, banner_len);
|
||||
session->remote.banner[banner_len] = '\0';
|
||||
_libssh2_debug(session, LIBSSH2_DBG_TRANS, "Received Banner: %s", session->remote.banner);
|
||||
_libssh2_debug(session, LIBSSH2_DBG_TRANS, "Received Banner: %s",
|
||||
session->remote.banner);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* }}} */
|
||||
|
||||
/* {{{ libssh2_banner_send
|
||||
@@ -177,7 +194,8 @@ static int libssh2_banner_receive(LIBSSH2_SESSION *session)
|
||||
* 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.
|
||||
*/
|
||||
static int libssh2_banner_send(LIBSSH2_SESSION *session)
|
||||
static int
|
||||
libssh2_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;
|
||||
@@ -192,7 +210,6 @@ static int libssh2_banner_send(LIBSSH2_SESSION *session)
|
||||
banner_len = strlen((char *) session->local.banner);
|
||||
banner = (char *) session->local.banner;
|
||||
}
|
||||
|
||||
#ifdef LIBSSH2DEBUG
|
||||
/* Hack and slash to avoid sending CRLF in debug output */
|
||||
if (banner_len < 256) {
|
||||
@@ -203,13 +220,16 @@ static int libssh2_banner_send(LIBSSH2_SESSION *session)
|
||||
banner[255] = '\0';
|
||||
}
|
||||
|
||||
_libssh2_debug(session, LIBSSH2_DBG_TRANS, "Sending Banner: %s", banner_dup);
|
||||
_libssh2_debug(session, LIBSSH2_DBG_TRANS, "Sending Banner: %s",
|
||||
banner_dup);
|
||||
#endif
|
||||
|
||||
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,
|
||||
ret =
|
||||
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)) {
|
||||
@@ -229,6 +249,7 @@ static int libssh2_banner_send(LIBSSH2_SESSION *session)
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* }}} */
|
||||
|
||||
/*
|
||||
@@ -236,7 +257,8 @@ static int libssh2_banner_send(LIBSSH2_SESSION *session)
|
||||
* 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 */
|
||||
static int
|
||||
_libssh2_nonblock(int sockfd, /* operate on this */
|
||||
int nonblock /* TRUE or FALSE */ )
|
||||
{
|
||||
#undef SETBLOCK
|
||||
@@ -304,8 +326,9 @@ static int _libssh2_nonblock(int sockfd, /* operate on this */
|
||||
* _libssh2_get_socket_nonblocking() gets the given blocking or non-blocking
|
||||
* state of the socket.
|
||||
*/
|
||||
static int _libssh2_get_socket_nonblocking(int sockfd) /* operate on this */
|
||||
{
|
||||
static int
|
||||
_libssh2_get_socket_nonblocking(int sockfd)
|
||||
{ /* operate on this */
|
||||
#undef GETBLOCK
|
||||
#define GETBLOCK 0
|
||||
#ifdef HAVE_O_NONBLOCK
|
||||
@@ -326,7 +349,8 @@ static int _libssh2_get_socket_nonblocking(int sockfd) /* operate on this */
|
||||
unsigned int option_value;
|
||||
socklen_t option_len = sizeof(option_value);
|
||||
|
||||
if (getsockopt(sockfd, SOL_SOCKET, SO_ERROR, (void*)&option_value, &option_len)) {
|
||||
if (getsockopt
|
||||
(sockfd, SOL_SOCKET, SO_ERROR, (void *) &option_value, &option_len)) {
|
||||
/* Assume blocking on error */
|
||||
return 1;
|
||||
}
|
||||
@@ -361,7 +385,8 @@ static int _libssh2_get_socket_nonblocking(int sockfd) /* operate on this */
|
||||
/* {{{ libssh2_banner_set
|
||||
* Set the local banner
|
||||
*/
|
||||
LIBSSH2_API int libssh2_banner_set(LIBSSH2_SESSION *session, const char *banner)
|
||||
LIBSSH2_API int
|
||||
libssh2_banner_set(LIBSSH2_SESSION * session, const char *banner)
|
||||
{
|
||||
int banner_len = banner ? strlen(banner) : 0;
|
||||
|
||||
@@ -376,19 +401,22 @@ LIBSSH2_API int libssh2_banner_set(LIBSSH2_SESSION *session, const char *banner)
|
||||
|
||||
session->local.banner = LIBSSH2_ALLOC(session, banner_len + 3);
|
||||
if (!session->local.banner) {
|
||||
libssh2_error(session, LIBSSH2_ERROR_ALLOC, "Unable to allocate memory for local banner", 0);
|
||||
libssh2_error(session, LIBSSH2_ERROR_ALLOC,
|
||||
"Unable to allocate memory for local banner", 0);
|
||||
return -1;
|
||||
}
|
||||
|
||||
memcpy(session->local.banner, banner, banner_len);
|
||||
session->local.banner[banner_len] = '\0';
|
||||
_libssh2_debug(session, LIBSSH2_DBG_TRANS, "Setting local Banner: %s", session->local.banner);
|
||||
_libssh2_debug(session, LIBSSH2_DBG_TRANS, "Setting local Banner: %s",
|
||||
session->local.banner);
|
||||
session->local.banner[banner_len++] = '\r';
|
||||
session->local.banner[banner_len++] = '\n';
|
||||
session->local.banner[banner_len++] = '\0';
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* }}} */
|
||||
|
||||
/* {{{ proto libssh2_session_init
|
||||
@@ -397,11 +425,10 @@ LIBSSH2_API int libssh2_banner_set(LIBSSH2_SESSION *session, const char *banner)
|
||||
* 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)),
|
||||
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)
|
||||
LIBSSH2_REALLOC_FUNC((*my_realloc)), void *abstract)
|
||||
{
|
||||
LIBSSH2_ALLOC_FUNC((*local_alloc)) = libssh2_default_alloc;
|
||||
LIBSSH2_FREE_FUNC((*local_free)) = libssh2_default_free;
|
||||
@@ -425,11 +452,13 @@ LIBSSH2_API LIBSSH2_SESSION *libssh2_session_init_ex(
|
||||
session->free = local_free;
|
||||
session->realloc = local_realloc;
|
||||
session->abstract = abstract;
|
||||
_libssh2_debug(session, LIBSSH2_DBG_TRANS, "New session resource allocated");
|
||||
_libssh2_debug(session, LIBSSH2_DBG_TRANS,
|
||||
"New session resource allocated");
|
||||
libssh2_crypto_init();
|
||||
}
|
||||
return session;
|
||||
}
|
||||
|
||||
/* }}} */
|
||||
|
||||
/* {{{ libssh2_session_callback_set
|
||||
@@ -439,7 +468,8 @@ LIBSSH2_API LIBSSH2_SESSION *libssh2_session_init_ex(
|
||||
* FIXME: this function relies on that we can typecast function pointers
|
||||
* to void pointers, which isn't allowed in ISO C!
|
||||
*/
|
||||
LIBSSH2_API void* libssh2_session_callback_set(LIBSSH2_SESSION *session,
|
||||
LIBSSH2_API void *
|
||||
libssh2_session_callback_set(LIBSSH2_SESSION * session,
|
||||
int cbtype, void *callback)
|
||||
{
|
||||
void *oldcb;
|
||||
@@ -475,6 +505,7 @@ LIBSSH2_API void* libssh2_session_callback_set(LIBSSH2_SESSION *session,
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* }}} */
|
||||
|
||||
/* {{{ proto libssh2_session_startup
|
||||
@@ -484,22 +515,25 @@ LIBSSH2_API void* libssh2_session_callback_set(LIBSSH2_SESSION *session,
|
||||
* callbacks in session
|
||||
* socket *must* be populated with an opened and connected socket.
|
||||
*/
|
||||
LIBSSH2_API int libssh2_session_startup(LIBSSH2_SESSION *session, int socket)
|
||||
LIBSSH2_API int
|
||||
libssh2_session_startup(LIBSSH2_SESSION * session, int sock)
|
||||
{
|
||||
int rc;
|
||||
|
||||
if (session->startup_state == libssh2_NB_state_idle) {
|
||||
_libssh2_debug(session, LIBSSH2_DBG_TRANS,
|
||||
"session_startup for socket %d", socket);
|
||||
"session_startup for socket %d", sock);
|
||||
/* FIXME: on some platforms (like win32) sockets are unsigned */
|
||||
if (socket < 0) {
|
||||
if (sock < 0) {
|
||||
/* Did we forget something? */
|
||||
libssh2_error(session, LIBSSH2_ERROR_SOCKET_NONE, "Bad socket provided", 0);
|
||||
libssh2_error(session, LIBSSH2_ERROR_SOCKET_NONE,
|
||||
"Bad socket provided", 0);
|
||||
return LIBSSH2_ERROR_SOCKET_NONE;
|
||||
}
|
||||
session->socket_fd = socket;
|
||||
session->socket_fd = sock;
|
||||
|
||||
session->socket_block = !_libssh2_get_socket_nonblocking(session->socket_fd);
|
||||
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
|
||||
@@ -517,12 +551,13 @@ LIBSSH2_API int libssh2_session_startup(LIBSSH2_SESSION *session, int socket)
|
||||
if (session->startup_state == libssh2_NB_state_created) {
|
||||
rc = libssh2_banner_send(session);
|
||||
if (rc == PACKET_EAGAIN) {
|
||||
libssh2_error(session, LIBSSH2_ERROR_EAGAIN, "Would block sending banner to remote host", 0);
|
||||
libssh2_error(session, LIBSSH2_ERROR_EAGAIN,
|
||||
"Would block sending banner to remote host", 0);
|
||||
return LIBSSH2_ERROR_EAGAIN;
|
||||
}
|
||||
else if (rc) {
|
||||
} else if (rc) {
|
||||
/* Unable to send banner? */
|
||||
libssh2_error(session, LIBSSH2_ERROR_BANNER_SEND, "Error sending banner to remote host", 0);
|
||||
libssh2_error(session, LIBSSH2_ERROR_BANNER_SEND,
|
||||
"Error sending banner to remote host", 0);
|
||||
return LIBSSH2_ERROR_BANNER_SEND;
|
||||
}
|
||||
|
||||
@@ -532,12 +567,13 @@ LIBSSH2_API int libssh2_session_startup(LIBSSH2_SESSION *session, int socket)
|
||||
if (session->startup_state == libssh2_NB_state_sent) {
|
||||
rc = libssh2_banner_receive(session);
|
||||
if (rc == PACKET_EAGAIN) {
|
||||
libssh2_error(session, LIBSSH2_ERROR_EAGAIN, "Would block waiting for banner", 0);
|
||||
libssh2_error(session, LIBSSH2_ERROR_EAGAIN,
|
||||
"Would block waiting for banner", 0);
|
||||
return LIBSSH2_ERROR_EAGAIN;
|
||||
}
|
||||
else if (rc) {
|
||||
} else if (rc) {
|
||||
/* Unable to receive banner from remote */
|
||||
libssh2_error(session, LIBSSH2_ERROR_BANNER_NONE, "Timeout waiting for banner", 0);
|
||||
libssh2_error(session, LIBSSH2_ERROR_BANNER_NONE,
|
||||
"Timeout waiting for banner", 0);
|
||||
return LIBSSH2_ERROR_BANNER_NONE;
|
||||
}
|
||||
|
||||
@@ -547,11 +583,12 @@ LIBSSH2_API int libssh2_session_startup(LIBSSH2_SESSION *session, int socket)
|
||||
if (session->startup_state == libssh2_NB_state_sent1) {
|
||||
rc = libssh2_kex_exchange(session, 0, &session->startup_key_state);
|
||||
if (rc == PACKET_EAGAIN) {
|
||||
libssh2_error(session, LIBSSH2_ERROR_EAGAIN, "Would block exchanging encryption keys", 0);
|
||||
libssh2_error(session, LIBSSH2_ERROR_EAGAIN,
|
||||
"Would block exchanging encryption keys", 0);
|
||||
return LIBSSH2_ERROR_EAGAIN;
|
||||
}
|
||||
else if (rc) {
|
||||
libssh2_error(session, LIBSSH2_ERROR_KEX_FAILURE, "Unable to exchange encryption keys", 0);
|
||||
} else if (rc) {
|
||||
libssh2_error(session, LIBSSH2_ERROR_KEX_FAILURE,
|
||||
"Unable to exchange encryption keys", 0);
|
||||
return LIBSSH2_ERROR_KEX_FAILURE;
|
||||
}
|
||||
|
||||
@@ -559,24 +596,29 @@ LIBSSH2_API int libssh2_session_startup(LIBSSH2_SESSION *session, int socket)
|
||||
}
|
||||
|
||||
if (session->startup_state == libssh2_NB_state_sent2) {
|
||||
_libssh2_debug(session, LIBSSH2_DBG_TRANS, "Requesting userauth service");
|
||||
_libssh2_debug(session, LIBSSH2_DBG_TRANS,
|
||||
"Requesting userauth service");
|
||||
|
||||
/* Request the userauth service */
|
||||
session->startup_service[0] = SSH_MSG_SERVICE_REQUEST;
|
||||
libssh2_htonu32(session->startup_service + 1, sizeof("ssh-userauth") - 1);
|
||||
memcpy(session->startup_service + 5, "ssh-userauth", sizeof("ssh-userauth") - 1);
|
||||
libssh2_htonu32(session->startup_service + 1,
|
||||
sizeof("ssh-userauth") - 1);
|
||||
memcpy(session->startup_service + 5, "ssh-userauth",
|
||||
sizeof("ssh-userauth") - 1);
|
||||
|
||||
session->startup_state = libssh2_NB_state_sent3;
|
||||
}
|
||||
|
||||
if (session->startup_state == libssh2_NB_state_sent3) {
|
||||
rc = libssh2_packet_write(session, session->startup_service, sizeof("ssh-userauth") + 5 - 1);
|
||||
rc = libssh2_packet_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);
|
||||
libssh2_error(session, LIBSSH2_ERROR_EAGAIN,
|
||||
"Would block asking for ssh-userauth service", 0);
|
||||
return LIBSSH2_ERROR_EAGAIN;
|
||||
}
|
||||
else if (rc) {
|
||||
libssh2_error(session, LIBSSH2_ERROR_SOCKET_SEND, "Unable to ask for ssh-userauth service", 0);
|
||||
} else if (rc) {
|
||||
libssh2_error(session, LIBSSH2_ERROR_SOCKET_SEND,
|
||||
"Unable to ask for ssh-userauth service", 0);
|
||||
return LIBSSH2_ERROR_SOCKET_SEND;
|
||||
}
|
||||
|
||||
@@ -584,21 +626,25 @@ LIBSSH2_API int libssh2_session_startup(LIBSSH2_SESSION *session, int socket)
|
||||
}
|
||||
|
||||
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_ex(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) {
|
||||
} else if (rc) {
|
||||
return LIBSSH2_ERROR_SOCKET_DISCONNECT;
|
||||
}
|
||||
session->startup_service_length = libssh2_ntohu32(session->startup_data + 1);
|
||||
session->startup_service_length =
|
||||
libssh2_ntohu32(session->startup_data + 1);
|
||||
|
||||
if ((session->startup_service_length != (sizeof("ssh-userauth") - 1)) ||
|
||||
strncmp("ssh-userauth", (char *)session->startup_data + 5, session->startup_service_length)) {
|
||||
if ((session->startup_service_length != (sizeof("ssh-userauth") - 1))
|
||||
|| strncmp("ssh-userauth", (char *) session->startup_data + 5,
|
||||
session->startup_service_length)) {
|
||||
LIBSSH2_FREE(session, session->startup_data);
|
||||
session->startup_data = NULL;
|
||||
libssh2_error(session, LIBSSH2_ERROR_PROTO, "Invalid response received from server", 0);
|
||||
libssh2_error(session, LIBSSH2_ERROR_PROTO,
|
||||
"Invalid response received from server", 0);
|
||||
return LIBSSH2_ERROR_PROTO;
|
||||
}
|
||||
LIBSSH2_FREE(session, session->startup_data);
|
||||
@@ -612,18 +658,21 @@ LIBSSH2_API int libssh2_session_startup(LIBSSH2_SESSION *session, int socket)
|
||||
/* just for safety return some error */
|
||||
return LIBSSH2_ERROR_INVAL;
|
||||
}
|
||||
|
||||
/* }}} */
|
||||
|
||||
/* {{{ proto 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)
|
||||
LIBSSH2_API int
|
||||
libssh2_session_free(LIBSSH2_SESSION * session)
|
||||
{
|
||||
int rc;
|
||||
|
||||
if (session->free_state == libssh2_NB_state_idle) {
|
||||
_libssh2_debug(session, LIBSSH2_DBG_TRANS, "Freeing session resource", session->remote.banner);
|
||||
_libssh2_debug(session, LIBSSH2_DBG_TRANS, "Freeing session resource",
|
||||
session->remote.banner);
|
||||
|
||||
session->state = libssh2_NB_state_created;
|
||||
}
|
||||
@@ -673,11 +722,13 @@ LIBSSH2_API int libssh2_session_free(LIBSSH2_SESSION *session)
|
||||
/* Client to Server */
|
||||
/* crypt */
|
||||
if (session->local.crypt && session->local.crypt->dtor) {
|
||||
session->local.crypt->dtor(session, &session->local.crypt_abstract);
|
||||
session->local.crypt->dtor(session,
|
||||
&session->local.crypt_abstract);
|
||||
}
|
||||
/* comp */
|
||||
if (session->local.comp && session->local.comp->dtor) {
|
||||
session->local.comp->dtor(session, 1, &session->local.comp_abstract);
|
||||
session->local.comp->dtor(session, 1,
|
||||
&session->local.comp_abstract);
|
||||
}
|
||||
/* mac */
|
||||
if (session->local.mac && session->local.mac->dtor) {
|
||||
@@ -687,11 +738,13 @@ LIBSSH2_API int libssh2_session_free(LIBSSH2_SESSION *session)
|
||||
/* Server to Client */
|
||||
/* crypt */
|
||||
if (session->remote.crypt && session->remote.crypt->dtor) {
|
||||
session->remote.crypt->dtor(session, &session->remote.crypt_abstract);
|
||||
session->remote.crypt->dtor(session,
|
||||
&session->remote.crypt_abstract);
|
||||
}
|
||||
/* comp */
|
||||
if (session->remote.comp && session->remote.comp->dtor) {
|
||||
session->remote.comp->dtor(session, 0, &session->remote.comp_abstract);
|
||||
session->remote.comp->dtor(session, 0,
|
||||
&session->remote.comp_abstract);
|
||||
}
|
||||
/* mac */
|
||||
if (session->remote.mac && session->remote.mac->dtor) {
|
||||
@@ -840,18 +893,23 @@ LIBSSH2_API int libssh2_session_free(LIBSSH2_SESSION *session)
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* }}} */
|
||||
|
||||
/* {{{ libssh2_session_disconnect_ex
|
||||
*/
|
||||
LIBSSH2_API int libssh2_session_disconnect_ex(LIBSSH2_SESSION *session, int reason, const char *description, const char *lang)
|
||||
LIBSSH2_API int
|
||||
libssh2_session_disconnect_ex(LIBSSH2_SESSION * session, int reason,
|
||||
const char *description, const char *lang)
|
||||
{
|
||||
unsigned char *s;
|
||||
unsigned long descr_len = 0, lang_len = 0;
|
||||
int rc;
|
||||
|
||||
if (session->disconnect_state == libssh2_NB_state_idle) {
|
||||
_libssh2_debug(session, LIBSSH2_DBG_TRANS, "Disconnecting: reason=%d, desc=%s, lang=%s", reason, description, lang);
|
||||
_libssh2_debug(session, LIBSSH2_DBG_TRANS,
|
||||
"Disconnecting: reason=%d, desc=%s, lang=%s", reason,
|
||||
description, lang);
|
||||
if (description) {
|
||||
descr_len = strlen(description);
|
||||
}
|
||||
@@ -861,23 +919,29 @@ LIBSSH2_API int libssh2_session_disconnect_ex(LIBSSH2_SESSION *session, int reas
|
||||
/* 13 = packet_type(1) + reason code(4) + descr_len(4) + lang_len(4) */
|
||||
session->disconnect_data_len = descr_len + lang_len + 13;
|
||||
|
||||
s = session->disconnect_data = LIBSSH2_ALLOC(session, session->disconnect_data_len);
|
||||
s = session->disconnect_data =
|
||||
LIBSSH2_ALLOC(session, session->disconnect_data_len);
|
||||
if (!session->disconnect_data) {
|
||||
libssh2_error(session, LIBSSH2_ERROR_ALLOC, "Unable to allocate memory for disconnect packet", 0);
|
||||
libssh2_error(session, LIBSSH2_ERROR_ALLOC,
|
||||
"Unable to allocate memory for disconnect packet",
|
||||
0);
|
||||
session->disconnect_state = libssh2_NB_state_idle;
|
||||
return -1;
|
||||
}
|
||||
|
||||
*(s++) = SSH_MSG_DISCONNECT;
|
||||
libssh2_htonu32(s, reason); s += 4;
|
||||
libssh2_htonu32(s, reason);
|
||||
s += 4;
|
||||
|
||||
libssh2_htonu32(s, descr_len); s += 4;
|
||||
libssh2_htonu32(s, descr_len);
|
||||
s += 4;
|
||||
if (description) {
|
||||
memcpy(s, description, descr_len);
|
||||
s += descr_len;
|
||||
}
|
||||
|
||||
libssh2_htonu32(s, lang_len); s += 4;
|
||||
libssh2_htonu32(s, lang_len);
|
||||
s += 4;
|
||||
if (lang) {
|
||||
memcpy(s, lang, lang_len);
|
||||
s += lang_len;
|
||||
@@ -886,7 +950,8 @@ LIBSSH2_API int libssh2_session_disconnect_ex(LIBSSH2_SESSION *session, int reas
|
||||
session->disconnect_state = libssh2_NB_state_created;
|
||||
}
|
||||
|
||||
rc = libssh2_packet_write(session, session->disconnect_data, session->disconnect_data_len);
|
||||
rc = libssh2_packet_write(session, session->disconnect_data,
|
||||
session->disconnect_data_len);
|
||||
if (rc == PACKET_EAGAIN) {
|
||||
return PACKET_EAGAIN;
|
||||
}
|
||||
@@ -897,6 +962,7 @@ LIBSSH2_API int libssh2_session_disconnect_ex(LIBSSH2_SESSION *session, int reas
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* }}} */
|
||||
|
||||
/* {{{ libssh2_session_methods
|
||||
@@ -904,7 +970,8 @@ LIBSSH2_API int libssh2_session_disconnect_ex(LIBSSH2_SESSION *session, int reas
|
||||
* 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)
|
||||
LIBSSH2_API const char *
|
||||
libssh2_session_methods(LIBSSH2_SESSION * session, int method_type)
|
||||
{
|
||||
/* All methods have char *name as their first element */
|
||||
const LIBSSH2_KEX_METHOD *method = NULL;
|
||||
@@ -951,27 +1018,32 @@ LIBSSH2_API const char *libssh2_session_methods(LIBSSH2_SESSION *session, int me
|
||||
break;
|
||||
|
||||
default:
|
||||
libssh2_error(session, LIBSSH2_ERROR_INVAL, "Invalid parameter specified for method_type", 0);
|
||||
libssh2_error(session, LIBSSH2_ERROR_INVAL,
|
||||
"Invalid parameter specified for method_type", 0);
|
||||
return NULL;
|
||||
break;
|
||||
}
|
||||
|
||||
if (!method) {
|
||||
libssh2_error(session, LIBSSH2_ERROR_METHOD_NONE, "No method negotiated", 0);
|
||||
libssh2_error(session, LIBSSH2_ERROR_METHOD_NONE,
|
||||
"No method negotiated", 0);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return method->name;
|
||||
}
|
||||
|
||||
/* }}} */
|
||||
|
||||
/* {{{ libssh2_session_abstract
|
||||
* Retrieve a pointer to the abstract property
|
||||
*/
|
||||
LIBSSH2_API void **libssh2_session_abstract(LIBSSH2_SESSION *session)
|
||||
LIBSSH2_API void **
|
||||
libssh2_session_abstract(LIBSSH2_SESSION * session)
|
||||
{
|
||||
return &session->abstract;
|
||||
}
|
||||
|
||||
/* }}} */
|
||||
|
||||
/* {{{ libssh2_session_last_error
|
||||
@@ -980,7 +1052,8 @@ LIBSSH2_API void **libssh2_session_abstract(LIBSSH2_SESSION *session)
|
||||
* Otherwise it is assumed to be owned by libssh2
|
||||
*/
|
||||
LIBSSH2_API int
|
||||
libssh2_session_last_error(LIBSSH2_SESSION *session, char **errmsg, int *errmsg_len, int want_buf)
|
||||
libssh2_session_last_error(LIBSSH2_SESSION * session, char **errmsg,
|
||||
int *errmsg_len, int want_buf)
|
||||
{
|
||||
/* No error to report */
|
||||
if (!session->err_code) {
|
||||
@@ -1001,8 +1074,7 @@ libssh2_session_last_error(LIBSSH2_SESSION *session, char **errmsg, int *errmsg_
|
||||
}
|
||||
|
||||
if (errmsg) {
|
||||
char *serrmsg = session->err_msg ? session->err_msg :
|
||||
(char *)"";
|
||||
char *serrmsg = session->err_msg ? session->err_msg : (char *) "";
|
||||
int ownbuf = session->err_msg ? session->err_should_free : 0;
|
||||
|
||||
if (want_buf) {
|
||||
@@ -1029,6 +1101,7 @@ libssh2_session_last_error(LIBSSH2_SESSION *session, char **errmsg, int *errmsg_
|
||||
|
||||
return session->err_code;
|
||||
}
|
||||
|
||||
/* }}} */
|
||||
|
||||
/* {{{ libssh2_session_last_error
|
||||
@@ -1039,13 +1112,15 @@ libssh2_session_last_errno(LIBSSH2_SESSION *session)
|
||||
{
|
||||
return session->err_code;
|
||||
}
|
||||
|
||||
/* }}} */
|
||||
|
||||
/* {{{ libssh2_session_flag
|
||||
* Set/Get session flags
|
||||
* Passing flag==0 will avoid changing session->flags while still returning its current value
|
||||
*/
|
||||
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)
|
||||
{
|
||||
if (value) {
|
||||
session->flags |= flag;
|
||||
@@ -1055,16 +1130,19 @@ LIBSSH2_API int libssh2_session_flag(LIBSSH2_SESSION *session, int flag, int val
|
||||
|
||||
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.
|
||||
*/
|
||||
int _libssh2_session_set_blocking(LIBSSH2_SESSION *session, int blocking)
|
||||
int
|
||||
_libssh2_session_set_blocking(LIBSSH2_SESSION * session, int blocking)
|
||||
{
|
||||
int bl = session->socket_block;
|
||||
_libssh2_debug(session, LIBSSH2_DBG_CONN, "Setting blocking mode on session %d", blocking);
|
||||
_libssh2_debug(session, LIBSSH2_DBG_CONN,
|
||||
"Setting blocking mode on session %d", blocking);
|
||||
if (blocking == session->socket_block) {
|
||||
/* avoid if already correct */
|
||||
return bl;
|
||||
@@ -1075,32 +1153,38 @@ int _libssh2_session_set_blocking(LIBSSH2_SESSION *session, int blocking)
|
||||
|
||||
return bl;
|
||||
}
|
||||
|
||||
/* }}} */
|
||||
|
||||
/* {{{ 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
|
||||
*/
|
||||
LIBSSH2_API void libssh2_session_set_blocking(LIBSSH2_SESSION *session, int blocking)
|
||||
LIBSSH2_API void
|
||||
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_API int libssh2_session_get_blocking(LIBSSH2_SESSION *session)
|
||||
LIBSSH2_API int
|
||||
libssh2_session_get_blocking(LIBSSH2_SESSION * session)
|
||||
{
|
||||
return session->socket_block;
|
||||
}
|
||||
|
||||
/* }}} */
|
||||
|
||||
/* {{{ libssh2_poll_channel_read
|
||||
* Returns 0 if no data is waiting on channel,
|
||||
* non-0 if data is available
|
||||
*/
|
||||
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_SESSION *session = channel->session;
|
||||
LIBSSH2_PACKET *packet = session->packets.head;
|
||||
@@ -1108,8 +1192,9 @@ LIBSSH2_API int libssh2_poll_channel_read(LIBSSH2_CHANNEL *channel, int extended
|
||||
while (packet) {
|
||||
if (((packet->data[0] == SSH_MSG_CHANNEL_DATA) && (extended == 0) &&
|
||||
(channel->local.id == libssh2_ntohu32(packet->data + 1))) ||
|
||||
((packet->data[0] == SSH_MSG_CHANNEL_EXTENDED_DATA) && (extended != 0) &&
|
||||
(channel->local.id == libssh2_ntohu32(packet->data + 1)))) {
|
||||
((packet->data[0] == SSH_MSG_CHANNEL_EXTENDED_DATA)
|
||||
&& (extended != 0)
|
||||
&& (channel->local.id == libssh2_ntohu32(packet->data + 1)))) {
|
||||
/* Found data waiting to be read */
|
||||
return 1;
|
||||
}
|
||||
@@ -1118,32 +1203,38 @@ LIBSSH2_API int libssh2_poll_channel_read(LIBSSH2_CHANNEL *channel, int extended
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* }}} */
|
||||
|
||||
/* {{{ libssh2_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)
|
||||
static inline int
|
||||
libssh2_poll_channel_write(LIBSSH2_CHANNEL * channel)
|
||||
{
|
||||
return channel->local.window_size ? 1 : 0;
|
||||
}
|
||||
|
||||
/* }}} */
|
||||
|
||||
/* {{{ libssh2_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)
|
||||
static inline int
|
||||
libssh2_poll_listener_queued(LIBSSH2_LISTENER * listener)
|
||||
{
|
||||
return listener->queue ? 1 : 0;
|
||||
}
|
||||
|
||||
/* }}} */
|
||||
|
||||
/* {{{ libssh2_poll
|
||||
* Poll sockets, channels, and listeners for activity
|
||||
*/
|
||||
LIBSSH2_API int libssh2_poll(LIBSSH2_POLLFD *fds, unsigned int nfds, long timeout)
|
||||
LIBSSH2_API int
|
||||
libssh2_poll(LIBSSH2_POLLFD * fds, unsigned int nfds, long timeout)
|
||||
{
|
||||
long timeout_remaining;
|
||||
unsigned int i, active_fds;
|
||||
@@ -1173,19 +1264,23 @@ LIBSSH2_API int libssh2_poll(LIBSSH2_POLLFD *fds, unsigned int nfds, long timeou
|
||||
sockets[i].fd = fds[i].fd.channel->session->socket_fd;
|
||||
sockets[i].events = POLLIN;
|
||||
sockets[i].revents = 0;
|
||||
if (!session) session = fds[i].fd.channel->session;
|
||||
if (!session)
|
||||
session = fds[i].fd.channel->session;
|
||||
break;
|
||||
|
||||
case LIBSSH2_POLLFD_LISTENER:
|
||||
sockets[i].fd = fds[i].fd.listener->session->socket_fd;
|
||||
sockets[i].events = POLLIN;
|
||||
sockets[i].revents = 0;
|
||||
if (!session) session = fds[i].fd.listener->session;
|
||||
if (!session)
|
||||
session = fds[i].fd.listener->session;
|
||||
break;
|
||||
|
||||
default:
|
||||
if (session) libssh2_error(session, LIBSSH2_ERROR_INVALID_POLL_TYPE,
|
||||
"Invalid descriptor passed to libssh2_poll()", 0);
|
||||
if (session)
|
||||
libssh2_error(session, LIBSSH2_ERROR_INVALID_POLL_TYPE,
|
||||
"Invalid descriptor passed to libssh2_poll()",
|
||||
0);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
@@ -1217,14 +1312,16 @@ LIBSSH2_API int libssh2_poll(LIBSSH2_POLLFD *fds, unsigned int nfds, long timeou
|
||||
FD_SET(fds[i].fd.channel->session->socket_fd, &rfds);
|
||||
if (fds[i].fd.channel->session->socket_fd > maxfd)
|
||||
maxfd = fds[i].fd.channel->session->socket_fd;
|
||||
if (!session) session = fds[i].fd.channel->session;
|
||||
if (!session)
|
||||
session = fds[i].fd.channel->session;
|
||||
break;
|
||||
|
||||
case LIBSSH2_POLLFD_LISTENER:
|
||||
FD_SET(fds[i].fd.listener->session->socket_fd, &rfds);
|
||||
if (fds[i].fd.listener->session->socket_fd > maxfd)
|
||||
maxfd = fds[i].fd.listener->session->socket_fd;
|
||||
if (!session) session = fds[i].fd.listener->session;
|
||||
if (!session)
|
||||
session = fds[i].fd.listener->session;
|
||||
break;
|
||||
|
||||
default:
|
||||
@@ -1257,31 +1354,50 @@ LIBSSH2_API int libssh2_poll(LIBSSH2_POLLFD *fds, unsigned int nfds, long timeou
|
||||
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 */
|
||||
fds[i].revents |= libssh2_poll_channel_read(fds[i].fd.channel, 0) ? LIBSSH2_POLLFD_POLLIN : 0;
|
||||
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 */
|
||||
fds[i].revents |= libssh2_poll_channel_read(fds[i].fd.channel, 1) ? LIBSSH2_POLLFD_POLLEXT : 0;
|
||||
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 */
|
||||
fds[i].revents |= libssh2_poll_channel_write(fds[i].fd.channel) ? LIBSSH2_POLLFD_POLLOUT : 0;
|
||||
fds[i].revents |=
|
||||
libssh2_poll_channel_write(fds[i].fd.
|
||||
channel) ?
|
||||
LIBSSH2_POLLFD_POLLOUT : 0;
|
||||
}
|
||||
if (fds[i].fd.channel->remote.close || fds[i].fd.channel->local.close) {
|
||||
if (fds[i].fd.channel->remote.close
|
||||
|| fds[i].fd.channel->local.close) {
|
||||
fds[i].revents |= LIBSSH2_POLLFD_CHANNEL_CLOSED;
|
||||
}
|
||||
if (fds[i].fd.channel->session->socket_state == LIBSSH2_SOCKET_DISCONNECTED) {
|
||||
fds[i].revents |= LIBSSH2_POLLFD_CHANNEL_CLOSED | LIBSSH2_POLLFD_SESSION_CLOSED;
|
||||
if (fds[i].fd.channel->session->socket_state ==
|
||||
LIBSSH2_SOCKET_DISCONNECTED) {
|
||||
fds[i].revents |=
|
||||
LIBSSH2_POLLFD_CHANNEL_CLOSED |
|
||||
LIBSSH2_POLLFD_SESSION_CLOSED;
|
||||
}
|
||||
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 */
|
||||
fds[i].revents |= libssh2_poll_listener_queued(fds[i].fd.listener) ? LIBSSH2_POLLFD_POLLIN : 0;
|
||||
fds[i].revents |=
|
||||
libssh2_poll_listener_queued(fds[i].fd.
|
||||
listener) ?
|
||||
LIBSSH2_POLLFD_POLLIN : 0;
|
||||
}
|
||||
if (fds[i].fd.listener->session->socket_state == LIBSSH2_SOCKET_DISCONNECTED) {
|
||||
fds[i].revents |= LIBSSH2_POLLFD_LISTENER_CLOSED | LIBSSH2_POLLFD_SESSION_CLOSED;
|
||||
if (fds[i].fd.listener->session->socket_state ==
|
||||
LIBSSH2_SOCKET_DISCONNECTED) {
|
||||
fds[i].revents |=
|
||||
LIBSSH2_POLLFD_LISTENER_CLOSED |
|
||||
LIBSSH2_POLLFD_SESSION_CLOSED;
|
||||
}
|
||||
break;
|
||||
}
|
||||
@@ -1295,7 +1411,6 @@ LIBSSH2_API int libssh2_poll(LIBSSH2_POLLFD *fds, unsigned int nfds, long timeou
|
||||
/* Don't block on the sockets if we have channels/listeners which are ready */
|
||||
timeout_remaining = 0;
|
||||
}
|
||||
|
||||
#ifdef HAVE_POLL
|
||||
|
||||
#ifdef HAVE_GETTIMEOFDAY
|
||||
@@ -1329,20 +1444,26 @@ LIBSSH2_API int libssh2_poll(LIBSSH2_POLLFD *fds, unsigned int nfds, long timeou
|
||||
case LIBSSH2_POLLFD_CHANNEL:
|
||||
if (sockets[i].events & POLLIN) {
|
||||
/* Spin session until no data available */
|
||||
while (libssh2_packet_read(fds[i].fd.channel->session) > 0);
|
||||
while (libssh2_packet_read(fds[i].fd.channel->session)
|
||||
> 0);
|
||||
}
|
||||
if (sockets[i].revents & POLLHUP) {
|
||||
fds[i].revents |= LIBSSH2_POLLFD_CHANNEL_CLOSED | LIBSSH2_POLLFD_SESSION_CLOSED;
|
||||
fds[i].revents |=
|
||||
LIBSSH2_POLLFD_CHANNEL_CLOSED |
|
||||
LIBSSH2_POLLFD_SESSION_CLOSED;
|
||||
}
|
||||
sockets[i].revents = 0;
|
||||
break;
|
||||
case LIBSSH2_POLLFD_LISTENER:
|
||||
if (sockets[i].events & POLLIN) {
|
||||
/* Spin session until no data available */
|
||||
while (libssh2_packet_read(fds[i].fd.listener->session) > 0);
|
||||
while (libssh2_packet_read(fds[i].fd.listener->session)
|
||||
> 0);
|
||||
}
|
||||
if (sockets[i].revents & POLLHUP) {
|
||||
fds[i].revents |= LIBSSH2_POLLFD_LISTENER_CLOSED | LIBSSH2_POLLFD_SESSION_CLOSED;
|
||||
fds[i].revents |=
|
||||
LIBSSH2_POLLFD_LISTENER_CLOSED |
|
||||
LIBSSH2_POLLFD_SESSION_CLOSED;
|
||||
}
|
||||
sockets[i].revents = 0;
|
||||
break;
|
||||
@@ -1389,14 +1510,17 @@ LIBSSH2_API int libssh2_poll(LIBSSH2_POLLFD *fds, unsigned int nfds, long timeou
|
||||
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) > 0);
|
||||
while (libssh2_packet_read(fds[i].fd.channel->session)
|
||||
> 0);
|
||||
}
|
||||
break;
|
||||
|
||||
case LIBSSH2_POLLFD_LISTENER:
|
||||
if (FD_ISSET(fds[i].fd.listener->session->socket_fd, &rfds)) {
|
||||
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) > 0);
|
||||
while (libssh2_packet_read(fds[i].fd.listener->session)
|
||||
> 0);
|
||||
}
|
||||
break;
|
||||
}
|
||||
@@ -1407,5 +1531,5 @@ LIBSSH2_API int libssh2_poll(LIBSSH2_POLLFD *fds, unsigned int nfds, long timeou
|
||||
|
||||
return active_fds;
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
/* }}} */
|
||||
|
949
src/sftp.c
949
src/sftp.c
File diff suppressed because it is too large
Load Diff
134
src/transport.c
134
src/transport.c
@@ -48,9 +48,9 @@
|
||||
|
||||
#ifdef LIBSSH2DEBUG
|
||||
#define UNPRINTABLE_CHAR '.'
|
||||
static void debugdump(LIBSSH2_SESSION *session,
|
||||
const char *desc, unsigned char *ptr,
|
||||
unsigned long size)
|
||||
static void
|
||||
debugdump(LIBSSH2_SESSION * session,
|
||||
const char *desc, unsigned char *ptr, unsigned long size)
|
||||
{
|
||||
size_t i;
|
||||
size_t c;
|
||||
@@ -66,7 +66,7 @@ static void debugdump(LIBSSH2_SESSION *session,
|
||||
|
||||
for(i = 0; i < size; i += width) {
|
||||
|
||||
fprintf(stream, "%04lx: ", i);
|
||||
fprintf(stream, "%04lx: ", (long)i);
|
||||
|
||||
/* hex not disabled, show it */
|
||||
for(c = 0; c < width; c++) {
|
||||
@@ -95,7 +95,8 @@ static void debugdump(LIBSSH2_SESSION *session,
|
||||
* returns PACKET_NONE on success and PACKET_FAIL on failure
|
||||
*/
|
||||
|
||||
static libssh2pack_t decrypt(LIBSSH2_SESSION *session, unsigned char *source,
|
||||
static libssh2pack_t
|
||||
decrypt(LIBSSH2_SESSION * session, unsigned char *source,
|
||||
unsigned char *dest, int len)
|
||||
{
|
||||
struct transportpacket *p = &session->packet;
|
||||
@@ -144,11 +145,11 @@ fullpacket(LIBSSH2_SESSION *session, int encrypted /* 1 or 0 */)
|
||||
if (encrypted) {
|
||||
|
||||
/* Calculate MAC hash */
|
||||
session->remote.mac->hash(session,
|
||||
macbuf, /* store hash here */
|
||||
session->remote.mac->hash(session, macbuf, /* store hash here */
|
||||
session->remote.seqno,
|
||||
p->init, 5,
|
||||
p->payload, session->fullpacket_payload_len,
|
||||
p->payload,
|
||||
session->fullpacket_payload_len,
|
||||
&session->remote.mac_abstract);
|
||||
|
||||
/* Compare the calculated hash with the MAC we just read from
|
||||
@@ -168,8 +169,7 @@ 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;
|
||||
@@ -178,7 +178,8 @@ fullpacket(LIBSSH2_SESSION *session, int encrypted /* 1 or 0 */)
|
||||
&data, &data_len,
|
||||
LIBSSH2_PACKET_MAXDECOMP,
|
||||
&free_payload,
|
||||
p->payload, session->fullpacket_payload_len,
|
||||
p->payload,
|
||||
session->fullpacket_payload_len,
|
||||
&session->remote.comp_abstract)) {
|
||||
LIBSSH2_FREE(session, p->payload);
|
||||
return PACKET_FAIL;
|
||||
@@ -188,16 +189,14 @@ fullpacket(LIBSSH2_SESSION *session, int encrypted /* 1 or 0 */)
|
||||
LIBSSH2_FREE(session, p->payload);
|
||||
p->payload = data;
|
||||
session->fullpacket_payload_len = data_len;
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
if (data == p->payload) {
|
||||
/* It's not to be freed, because the
|
||||
* compression layer reused payload, So let's
|
||||
* do the same!
|
||||
*/
|
||||
session->fullpacket_payload_len = data_len;
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
/* No comp_method actually lets this happen,
|
||||
* but let's prepare for the future */
|
||||
|
||||
@@ -207,9 +206,9 @@ fullpacket(LIBSSH2_SESSION *session, int encrypted /* 1 or 0 */)
|
||||
* brigade won't know what to do with it */
|
||||
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);
|
||||
libssh2_error(session, LIBSSH2_ERROR_ALLOC, (char *)
|
||||
"Unable to allocate memory for copy of uncompressed data",
|
||||
0);
|
||||
return PACKET_ENOMEM;
|
||||
}
|
||||
memcpy(p->payload, data, data_len);
|
||||
@@ -227,11 +226,12 @@ fullpacket(LIBSSH2_SESSION *session, int encrypted /* 1 or 0 */)
|
||||
}
|
||||
|
||||
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) {
|
||||
} else if (rc < 0) {
|
||||
return PACKET_FAIL;
|
||||
}
|
||||
}
|
||||
@@ -256,7 +256,8 @@ fullpacket(LIBSSH2_SESSION *session, int encrypted /* 1 or 0 */)
|
||||
* This function reads the binary stream as specified in chapter 6 of RFC4253
|
||||
* "The Secure Shell (SSH) Transport Layer Protocol"
|
||||
*/
|
||||
libssh2pack_t libssh2_packet_read(LIBSSH2_SESSION *session)
|
||||
libssh2pack_t
|
||||
libssh2_packet_read(LIBSSH2_SESSION * session)
|
||||
{
|
||||
libssh2pack_t rc;
|
||||
struct transportpacket *p = &session->packet;
|
||||
@@ -266,7 +267,6 @@ libssh2pack_t libssh2_packet_read(LIBSSH2_SESSION *session)
|
||||
int numdecrypt;
|
||||
unsigned char block[MAX_BLOCKSIZE];
|
||||
int blocksize;
|
||||
int minimum;
|
||||
int encrypted = 1;
|
||||
|
||||
/*
|
||||
@@ -292,7 +292,6 @@ libssh2pack_t libssh2_packet_read(LIBSSH2_SESSION *session)
|
||||
blocksize = 5; /* not strictly true, but we can use 5 here to
|
||||
make the checks below work fine still */
|
||||
}
|
||||
minimum = p->total_num ? p->total_num - p->data_num : blocksize;
|
||||
|
||||
/* read/use a whole big chunk into a temporary area stored in
|
||||
the LIBSSH2_SESSION struct. We will decrypt data from that
|
||||
@@ -307,8 +306,8 @@ libssh2pack_t libssh2_packet_read(LIBSSH2_SESSION *session)
|
||||
/* if remainbuf turns negative we have a bad internal error */
|
||||
assert(remainbuf >= 0);
|
||||
|
||||
if (remainbuf < minimum) {
|
||||
/* If we have less than a minimum left, it is too
|
||||
if (remainbuf < blocksize) {
|
||||
/* If we have less than a blocksize left, it is too
|
||||
little data to deal with, read more */
|
||||
ssize_t nread;
|
||||
|
||||
@@ -324,12 +323,33 @@ libssh2pack_t 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], PACKETBUFSIZE-remainbuf,
|
||||
nread =
|
||||
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 */
|
||||
/* 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)) {
|
||||
return PACKET_EAGAIN;
|
||||
}
|
||||
@@ -347,16 +367,19 @@ libssh2pack_t libssh2_packet_read(LIBSSH2_SESSION *session)
|
||||
/* how much data to deal with from the buffer */
|
||||
numbytes = remainbuf;
|
||||
|
||||
if (numbytes < blocksize) {
|
||||
/* we can't act on anything less than blocksize */
|
||||
return PACKET_EAGAIN;
|
||||
}
|
||||
|
||||
if (!p->total_num) {
|
||||
/* No payload package area allocated yet. To know the
|
||||
size of this payload, we need to decrypt the first
|
||||
blocksize data. */
|
||||
|
||||
if (numbytes < blocksize) {
|
||||
/* we can't act on anything less than blocksize, but this
|
||||
check is only done for the initial block since once we have
|
||||
got the start of a block we can in fact deal with fractions
|
||||
*/
|
||||
return PACKET_EAGAIN;
|
||||
}
|
||||
|
||||
if (encrypted) {
|
||||
rc = decrypt(session, &p->buf[p->readidx], block, blocksize);
|
||||
if (rc != PACKET_NONE) {
|
||||
@@ -382,7 +405,9 @@ libssh2pack_t libssh2_packet_read(LIBSSH2_SESSION *session)
|
||||
|
||||
/* total_num is the number of bytes following the initial
|
||||
(5 bytes) packet length and padding length fields */
|
||||
p->total_num = p->packet_length -1 + (encrypted ? session->remote.mac->mac_len : 0);
|
||||
p->total_num =
|
||||
p->packet_length - 1 +
|
||||
(encrypted ? session->remote.mac->mac_len : 0);
|
||||
|
||||
/* RFC4253 section 6.1 Maximum Packet Length says:
|
||||
*
|
||||
@@ -515,11 +540,14 @@ libssh2_packet_read_point1:
|
||||
|
||||
return PACKET_FAIL; /* we never reach this point */
|
||||
}
|
||||
|
||||
/* }}} */
|
||||
|
||||
#ifndef OLDSEND
|
||||
|
||||
static libssh2pack_t send_existing(LIBSSH2_SESSION *session, unsigned char *data, unsigned long data_len, ssize_t *ret)
|
||||
static libssh2pack_t
|
||||
send_existing(LIBSSH2_SESSION * session, unsigned char *data,
|
||||
unsigned long data_len, ssize_t * ret)
|
||||
{
|
||||
ssize_t rc;
|
||||
ssize_t length;
|
||||
@@ -545,15 +573,15 @@ static libssh2pack_t 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, LIBSSH2_SOCKET_SEND_FLAGS(session));
|
||||
rc = send(session->socket_fd, &p->outbuf[p->osent], length,
|
||||
LIBSSH2_SOCKET_SEND_FLAGS(session));
|
||||
|
||||
if (rc == length) {
|
||||
/* the remainder of the package was sent */
|
||||
LIBSSH2_FREE(session, p->outbuf);
|
||||
p->outbuf = NULL;
|
||||
p->ototal_num = 0;
|
||||
}
|
||||
else if (rc < 0) {
|
||||
} else if (rc < 0) {
|
||||
/* nothing was sent */
|
||||
if (errno != EAGAIN) {
|
||||
/* send failure! */
|
||||
@@ -562,7 +590,8 @@ static libssh2pack_t send_existing(LIBSSH2_SESSION *session, unsigned char *data
|
||||
return PACKET_EAGAIN;
|
||||
}
|
||||
|
||||
debugdump(session, "libssh2_packet_write send()", &p->outbuf[p->osent], length);
|
||||
debugdump(session, "libssh2_packet_write send()", &p->outbuf[p->osent],
|
||||
length);
|
||||
p->osent += length; /* we sent away this much data */
|
||||
|
||||
return PACKET_NONE;
|
||||
@@ -577,9 +606,13 @@ static libssh2pack_t send_existing(LIBSSH2_SESSION *session, unsigned char *data
|
||||
* 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.
|
||||
*/
|
||||
int libssh2_packet_write(LIBSSH2_SESSION *session, unsigned char *data, unsigned long data_len)
|
||||
int
|
||||
libssh2_packet_write(LIBSSH2_SESSION * session, unsigned char *data,
|
||||
unsigned long data_len)
|
||||
{
|
||||
int blocksize = (session->state & LIBSSH2_STATE_NEWKEYS) ? session->local.crypt->blocksize : 8;
|
||||
int blocksize =
|
||||
(session->state & LIBSSH2_STATE_NEWKEYS) ? session->local.crypt->
|
||||
blocksize : 8;
|
||||
int padding_length;
|
||||
int packet_length;
|
||||
int total_length;
|
||||
@@ -608,7 +641,8 @@ int libssh2_packet_write(LIBSSH2_SESSION *session, unsigned char *data, unsigned
|
||||
|
||||
/* check if we should compress */
|
||||
if (encrypted && strcmp(session->local.comp->name, "none")) {
|
||||
if (session->local.comp->comp(session, 1, &data, &data_len, LIBSSH2_PACKET_MAXCOMP,
|
||||
if (session->local.comp->
|
||||
comp(session, 1, &data, &data_len, LIBSSH2_PACKET_MAXCOMP,
|
||||
&free_data, data, data_len, &session->local.comp_abstract)) {
|
||||
return PACKET_COMPRESS; /* compression failure */
|
||||
}
|
||||
@@ -650,7 +684,8 @@ int libssh2_packet_write(LIBSSH2_SESSION *session, unsigned char *data, unsigned
|
||||
packet_length += padding_length;
|
||||
|
||||
/* append the MAC length to the total_length size */
|
||||
total_length = packet_length + (encrypted?session->local.mac->mac_len:0);
|
||||
total_length =
|
||||
packet_length + (encrypted ? session->local.mac->mac_len : 0);
|
||||
|
||||
/* allocate memory to store the outgoing packet in, in case we can't
|
||||
send the whole one and thus need to keep it after this function
|
||||
@@ -678,14 +713,17 @@ int libssh2_packet_write(LIBSSH2_SESSION *session, unsigned char *data, unsigned
|
||||
since that size includes the whole packet. The MAC is
|
||||
calculated on the entire unencrypted packet, including all
|
||||
fields except the MAC field itself. */
|
||||
session->local.mac->hash(session, p->outbuf + packet_length, session->local.seqno, p->outbuf, packet_length,
|
||||
NULL, 0, &session->local.mac_abstract);
|
||||
session->local.mac->hash(session, p->outbuf + packet_length,
|
||||
session->local.seqno, p->outbuf,
|
||||
packet_length, NULL, 0,
|
||||
&session->local.mac_abstract);
|
||||
|
||||
/* Encrypt the whole packet data, one block size at a time.
|
||||
The MAC field is not encrypted. */
|
||||
for(i = 0; i < packet_length; i += session->local.crypt->blocksize) {
|
||||
unsigned char *ptr = &p->outbuf[i];
|
||||
if (session->local.crypt->crypt(session, ptr, &session->local.crypt_abstract))
|
||||
if (session->local.crypt->
|
||||
crypt(session, ptr, &session->local.crypt_abstract))
|
||||
return PACKET_FAIL; /* encryption failure */
|
||||
}
|
||||
}
|
||||
|
781
src/userauth.c
781
src/userauth.c
File diff suppressed because it is too large
Load Diff
@@ -5,7 +5,7 @@
|
||||
##
|
||||
## Comments to: Guenter Knauf <eflash@gmx.net>
|
||||
##
|
||||
## $Id: Makefile.win32,v 1.8 2007/07/21 22:59:24 gknauf Exp $
|
||||
## $Id: Makefile.win32,v 1.9 2007/08/18 18:53:26 gknauf Exp $
|
||||
#
|
||||
#########################################################################
|
||||
|
||||
@@ -67,6 +67,8 @@ else
|
||||
endif
|
||||
CP = cp -afv
|
||||
# RM = rm -f
|
||||
# Here you can find a native Win32 binary of the original awk:
|
||||
# http://www.gknw.net/development/prgtools/awk.zip
|
||||
AWK = awk
|
||||
ZIP = zip -qzr9
|
||||
|
||||
|
@@ -5,7 +5,7 @@
|
||||
##
|
||||
## Comments to: Guenter Knauf <eflash@gmx.net>
|
||||
##
|
||||
## $Id: Makefile.win32,v 1.5 2007/04/21 23:36:51 gknauf Exp $
|
||||
## $Id: Makefile.win32,v 1.6 2007/08/18 18:53:26 gknauf Exp $
|
||||
#
|
||||
#########################################################################
|
||||
|
||||
@@ -55,6 +55,8 @@ else
|
||||
endif
|
||||
CP = cp -afv
|
||||
# RM = rm -f
|
||||
# Here you can find a native Win32 binary of the original awk:
|
||||
# http://www.gknw.net/development/prgtools/awk.zip
|
||||
AWK = awk
|
||||
ZIP = zip -qzr9
|
||||
|
||||
|
Reference in New Issue
Block a user