Compare commits
81 Commits
RELEASE.0.
...
RELEASE.1.
Author | SHA1 | Date | |
---|---|---|---|
![]() |
27197bcff3 | ||
![]() |
64b3e5e3f6 | ||
![]() |
ba79d6b52d | ||
![]() |
6b38e21fa7 | ||
![]() |
11330ee6da | ||
![]() |
b3649e86a8 | ||
![]() |
2f32080772 | ||
![]() |
7aac082782 | ||
![]() |
5a35edcb9a | ||
![]() |
079d20aca8 | ||
![]() |
b357379923 | ||
![]() |
62769b438f | ||
![]() |
d602478e87 | ||
![]() |
8eba2961ac | ||
![]() |
962a41e4ec | ||
![]() |
31841e7c74 | ||
![]() |
70f844e57c | ||
![]() |
942a81c8d5 | ||
![]() |
e26956be72 | ||
![]() |
2535c5c2ee | ||
![]() |
197a26ef8c | ||
![]() |
f1dae83d5e | ||
![]() |
bcad67636b | ||
![]() |
fbb25c7ad0 | ||
![]() |
e47bedf17c | ||
![]() |
19f78244de | ||
![]() |
9d5ba0dee2 | ||
![]() |
0934c4b39d | ||
![]() |
cc3a7d8e83 | ||
![]() |
8f860e249e | ||
![]() |
160f89f42e | ||
![]() |
881b01e522 | ||
![]() |
74d33d50ba | ||
![]() |
fcaa810350 | ||
![]() |
1f015d72b1 | ||
![]() |
8c8ba3bc20 | ||
![]() |
9d433d4f80 | ||
![]() |
50a3255dde | ||
![]() |
482072939a | ||
![]() |
f2253aeee9 | ||
![]() |
2b5becfe85 | ||
![]() |
8b25820589 | ||
![]() |
fd0bffdb2e | ||
![]() |
86eaae7886 | ||
![]() |
8e8dc43b0c | ||
![]() |
e45bddb9fd | ||
![]() |
e5a36fb1cf | ||
![]() |
5438cffd9a | ||
![]() |
95b73812e7 | ||
![]() |
85b953d0dd | ||
![]() |
c3447ea29f | ||
![]() |
8896b675f8 | ||
![]() |
b2334b227d | ||
![]() |
88d0ef1f3f | ||
![]() |
006f233361 | ||
![]() |
fa620b2a7b | ||
![]() |
b228f132f7 | ||
![]() |
8c43bc52b1 | ||
![]() |
d26a330483 | ||
![]() |
b4b8c51b32 | ||
![]() |
818e9edfb1 | ||
![]() |
61fda23340 | ||
![]() |
93ae080bbc | ||
![]() |
bd3dfed7e8 | ||
![]() |
99afc66665 | ||
![]() |
903307113e | ||
![]() |
9b31ca67ac | ||
![]() |
3f0d30d1d6 | ||
![]() |
d4aa801f6f | ||
![]() |
f56daac7fe | ||
![]() |
a55e6c10c9 | ||
![]() |
2fcaa00e3a | ||
![]() |
0242a3b6af | ||
![]() |
b310cc3465 | ||
![]() |
092e5f4b44 | ||
![]() |
c1a83abff9 | ||
![]() |
f3c344da22 | ||
![]() |
4600d108ed | ||
![]() |
76e8e81402 | ||
![]() |
d27dd927cd | ||
![]() |
63d863241a |
@@ -7,3 +7,5 @@ edink:Edink Kadribasic
|
|||||||
jehousley: James Housley
|
jehousley: James Housley
|
||||||
gknauf: Guenter Knauf
|
gknauf: Guenter Knauf
|
||||||
dfandrich: Dan Fandrich
|
dfandrich: Dan Fandrich
|
||||||
|
yangtse: Yang Tse
|
||||||
|
thomaspu: Paul Thomas
|
||||||
|
25
Makefile.am
25
Makefile.am
@@ -16,7 +16,7 @@ win32/config.mk win32/Makefile win32/test/Makefile.win32 win32/libssh2_lib.dsp \
|
|||||||
win32/libssh2_config.h win32/tests.dsp win32/rules.mk
|
win32/libssh2_config.h win32/tests.dsp win32/rules.mk
|
||||||
|
|
||||||
EXTRA_DIST = $(WIN32FILES) buildconf $(NETWAREFILES) get_ver.awk HACKING \
|
EXTRA_DIST = $(WIN32FILES) buildconf $(NETWAREFILES) get_ver.awk HACKING \
|
||||||
maketgz NMakefile
|
maketgz NMakefile TODO
|
||||||
|
|
||||||
ACLOCAL_AMFLAGS = -I m4
|
ACLOCAL_AMFLAGS = -I m4
|
||||||
|
|
||||||
@@ -34,3 +34,26 @@ dist-hook:
|
|||||||
strip=`echo $$file | sed -e s/^$(srcdir)// -e s/\.dist//`; \
|
strip=`echo $$file | sed -e s/^$(srcdir)// -e s/\.dist//`; \
|
||||||
cp $$file $(distdir)$$strip; \
|
cp $$file $(distdir)$$strip; \
|
||||||
done)
|
done)
|
||||||
|
|
||||||
|
# Code Coverage
|
||||||
|
|
||||||
|
init-coverage:
|
||||||
|
make clean
|
||||||
|
lcov --directory . --zerocounters
|
||||||
|
|
||||||
|
COVERAGE_CCOPTS ?= "-g --coverage"
|
||||||
|
COVERAGE_OUT ?= docs/coverage
|
||||||
|
|
||||||
|
build-coverage:
|
||||||
|
make CFLAGS=$(COVERAGE_CCOPTS) check
|
||||||
|
mkdir -p $(COVERAGE_OUT)
|
||||||
|
lcov --directory . --output-file $(COVERAGE_OUT)/$(PACKAGE).info \
|
||||||
|
--capture
|
||||||
|
|
||||||
|
gen-coverage:
|
||||||
|
genhtml --output-directory $(COVERAGE_OUT) \
|
||||||
|
$(COVERAGE_OUT)/$(PACKAGE).info \
|
||||||
|
--highlight --frames --legend \
|
||||||
|
--title "$(PACKAGE_NAME)"
|
||||||
|
|
||||||
|
coverage: init-coverage build-coverage gen-coverage
|
||||||
|
59
NEWS
59
NEWS
@@ -1,5 +1,60 @@
|
|||||||
Version 0.18
|
Version 1.0 ( )
|
||||||
------------
|
-------------------------------
|
||||||
|
|
||||||
|
- (Dec 20 2008) Based on Alexander Lamaison's patch, there's now a new
|
||||||
|
function called libssh2_sftp_tell64() that returns the 64 bit file offset,
|
||||||
|
as the existing libssh2_sftp_tell() only returns a size_t.
|
||||||
|
|
||||||
|
- (Dec 18 2008) Markus Moeller fixed the issue also reported by Alexander
|
||||||
|
Lamaison which caused SFTP reads with large buffers to fail.
|
||||||
|
|
||||||
|
- Several flaws were fixed that prevented at least SFTP to work reliably
|
||||||
|
|
||||||
|
- Vlad Grachov brought the new function called
|
||||||
|
libssh2_session_block_directions() which returns a bitmask for what
|
||||||
|
directions the connection blocks. It is to be used applications that use
|
||||||
|
non-blocking sockets and when a libssh2 function returns
|
||||||
|
LIBSSH2_ERROR_EAGAIN this function can be used to figure out in which
|
||||||
|
direction the socket would block and thus it can wait for the socket to
|
||||||
|
again be ready for communication in that direction before it calls libssh2
|
||||||
|
again.
|
||||||
|
|
||||||
|
- Vincent Jaulin brought the new libssh2_channel_request_pty_size_ex()
|
||||||
|
function.
|
||||||
|
|
||||||
|
- Carlo Bramini fixed the build for msys+mingw. Bug #1943976.
|
||||||
|
|
||||||
|
- Neil Gierman provided improved Visual Studio 2008 code in bug #1946268
|
||||||
|
|
||||||
|
- Bug #1862727 fixed libssh2_poll() to work on windows (by defining
|
||||||
|
HAVE_SELECT).
|
||||||
|
|
||||||
|
- Based on bug #1815692, we introduce libssh2_sftp_seek64() that allows
|
||||||
|
seeking beyond the 2GB margin even on 32bit machines.
|
||||||
|
|
||||||
|
- Based on a patch in bug #1878059 by Steven Ayre libssh2 now parses >2GB file
|
||||||
|
sizes when downloading SCP files.
|
||||||
|
|
||||||
|
- Bug #2064371 pointed out that the SSH2 banner may not use dash
|
||||||
|
('-'). Reported by Bjorn Stenborg.
|
||||||
|
|
||||||
|
- Sean Peterson fixed a key re-exchange bug:
|
||||||
|
http://daniel.haxx.se/projects/libssh2/mail/libssh2-devel-archive-2008-06/0002.shtml
|
||||||
|
|
||||||
|
- Mike Protts filed the bug report #1908724 that identified and fixed a problem
|
||||||
|
with SFTP stat on files >4GB in size. Previously it used 32bit math only.
|
||||||
|
|
||||||
|
- Removed a stderr debug message that was accidentally left in (bug #1863153)
|
||||||
|
|
||||||
|
- OpenSSL and libz detection changed to make cross-compiling to Mingw
|
||||||
|
work. See README for parameters to use if the auto-detection does
|
||||||
|
not work for you. From Simon Josefsson.
|
||||||
|
|
||||||
|
- Simon Josefsson added a self-test that uses libssh2 to connect to a
|
||||||
|
local sshd (only enabled if if OpenSSH is installed).
|
||||||
|
|
||||||
|
Version 0.18 (November 11 2007)
|
||||||
|
-------------------------------
|
||||||
|
|
||||||
- Various changes that improve non-blocking operations and prevent stalls.
|
- Various changes that improve non-blocking operations and prevent stalls.
|
||||||
Especially noticable on Windows since libssh2 just didn't work properly
|
Especially noticable on Windows since libssh2 just didn't work properly
|
||||||
|
54
README
54
README
@@ -4,6 +4,10 @@ libssh2 - SSH2 library
|
|||||||
libssh2 is a library implementing the SSH2 protocol, available under
|
libssh2 is a library implementing the SSH2 protocol, available under
|
||||||
the revised BSD license.
|
the revised BSD license.
|
||||||
|
|
||||||
|
Web site: http://www.libssh2.org/
|
||||||
|
|
||||||
|
Mailing list: https://lists.sourceforge.net/lists/listinfo/libssh2-devel
|
||||||
|
|
||||||
Generic installation instructions are in INSTALL. Some ./configure
|
Generic installation instructions are in INSTALL. Some ./configure
|
||||||
options deserve additional comments:
|
options deserve additional comments:
|
||||||
|
|
||||||
@@ -48,49 +52,43 @@ options deserve additional comments:
|
|||||||
the older more reliable method.
|
the older more reliable method.
|
||||||
|
|
||||||
* --with-libgcrypt
|
* --with-libgcrypt
|
||||||
|
* --without-libgcrypt
|
||||||
* --with-libgcrypt-prefix=DIR
|
* --with-libgcrypt-prefix=DIR
|
||||||
|
|
||||||
libssh2 can use the Libgcrypt library
|
libssh2 can use the Libgcrypt library
|
||||||
(http://www.gnupg.org/) for cryptographic operations.
|
(http://www.gnupg.org/) for cryptographic operations.
|
||||||
|
Either Libgcrypt or OpenSSL is required.
|
||||||
|
|
||||||
Configure will attempt to locate Libgcrypt in the
|
Configure will attempt to locate Libgcrypt
|
||||||
default location, but if you have installed it
|
automatically.
|
||||||
somewhere else, use the --with-libgrypt-prefix=DIR
|
|
||||||
parameter.
|
|
||||||
|
|
||||||
* --with-openssl=[DIR]
|
If your installation of Libgcrypt is in another
|
||||||
|
location, specify it using --with-libgcrypt-prefix.
|
||||||
|
|
||||||
|
* --with-openssl
|
||||||
|
* --without-openssl
|
||||||
|
* --with-libssl-prefix=[DIR]
|
||||||
|
|
||||||
libssh2 can use the OpenSSL library
|
libssh2 can use the OpenSSL library
|
||||||
(http://www.openssl.org) for cryptographic operations.
|
(http://www.openssl.org) for cryptographic operations.
|
||||||
|
Either Libgcrypt or OpenSSL is required.
|
||||||
|
|
||||||
Configure will attempt to locate OpenSSL in a number
|
Configure will attempt to locate OpenSSL in the
|
||||||
of default locations:
|
default location.
|
||||||
|
|
||||||
/usr/local/ssl
|
|
||||||
/usr/local
|
|
||||||
/usr
|
|
||||||
/usr/local/openssl
|
|
||||||
|
|
||||||
If your installation of OpenSSL is in another
|
If your installation of OpenSSL is in another
|
||||||
location, specify it here.
|
location, specify it using --with-libssl-prefix.
|
||||||
|
|
||||||
* --with-libz=[DIR]
|
* --with-libz
|
||||||
|
* --without-libz
|
||||||
|
* --with-libz-prefix=[DIR]
|
||||||
|
|
||||||
If present, libssh2 will attempt to use the zlib (http://www.zlib.org)
|
If present, libssh2 will attempt to use the zlib
|
||||||
for payload compression, however zlib is not required.
|
(http://www.zlib.org) for payload compression, however
|
||||||
|
zlib is not required.
|
||||||
|
|
||||||
Configure will attempt to location a zlib installation
|
If your installation of Libz is in another location,
|
||||||
in a number of default locations:
|
specify it using --with-libz-prefix.
|
||||||
|
|
||||||
/usr/local
|
|
||||||
/usr
|
|
||||||
/usr/local/libz
|
|
||||||
/usr/libz
|
|
||||||
/usr/local/zlib
|
|
||||||
/usr/zlib
|
|
||||||
|
|
||||||
If your installation of zlib is in another location,
|
|
||||||
you may specify it here.
|
|
||||||
|
|
||||||
* --enable-debug
|
* --enable-debug
|
||||||
|
|
||||||
|
30
TODO
Normal file
30
TODO
Normal file
@@ -0,0 +1,30 @@
|
|||||||
|
Things TODO
|
||||||
|
===========
|
||||||
|
|
||||||
|
* Add one of the missing man pages:
|
||||||
|
|
||||||
|
libssh2_channel_receive_window_adjust
|
||||||
|
libssh2_channel_request_pty_size_ex
|
||||||
|
libssh2_channel_window_read_ex
|
||||||
|
libssh2_channel_window_write_ex
|
||||||
|
libssh2_publickey_add_ex
|
||||||
|
libssh2_publickey_init
|
||||||
|
libssh2_publickey_list_fetch
|
||||||
|
libssh2_publickey_list_free
|
||||||
|
libssh2_publickey_remove_ex
|
||||||
|
libssh2_publickey_shutdown
|
||||||
|
libssh2_session_flag
|
||||||
|
libssh2_session_get_blocking
|
||||||
|
libssh2_userauth_hostbased_fromfile_ex
|
||||||
|
|
||||||
|
* Decrease the number of mallocs. Everywhere.
|
||||||
|
|
||||||
|
* Use SO_NOSIGPIPE for Mac OS/BSD systems where MSG_NOSIGNAL doesn't exist/work
|
||||||
|
|
||||||
|
* Extend the test suite to actually test lots of aspects of libssh2
|
||||||
|
|
||||||
|
|
||||||
|
At next SONAME bump
|
||||||
|
===================
|
||||||
|
|
||||||
|
* remove libssh2_base64_decode() from the API/ABI
|
217
configure.in
217
configure.in
@@ -1,7 +1,7 @@
|
|||||||
# AC_PREREQ(2.57)
|
# AC_PREREQ(2.57)
|
||||||
AC_INIT(libssh2, [-], libssh2-devel@lists.sourceforge.net)
|
AC_INIT(libssh2, [-], libssh2-devel@lists.sourceforge.net)
|
||||||
AC_CONFIG_SRCDIR([src])
|
AC_CONFIG_SRCDIR([src])
|
||||||
AC_CONFIG_HEADER([src/libssh2_config.h example/simple/config.h])
|
AC_CONFIG_HEADER([src/libssh2_config.h])
|
||||||
AM_MAINTAINER_MODE
|
AM_MAINTAINER_MODE
|
||||||
|
|
||||||
dnl SED is needed by some of the tools
|
dnl SED is needed by some of the tools
|
||||||
@@ -28,6 +28,10 @@ AB_INIT
|
|||||||
# get this removed.
|
# get this removed.
|
||||||
AC_CANONICAL_HOST
|
AC_CANONICAL_HOST
|
||||||
case "$host" in
|
case "$host" in
|
||||||
|
*-mingw*)
|
||||||
|
CFLAGS="$CFLAGS -DLIBSSH2_WIN32 -DWINSOCK_VERSION=0x0200"
|
||||||
|
LIBS="$LIBS -lws2_32"
|
||||||
|
;;
|
||||||
*-cygwin)
|
*-cygwin)
|
||||||
CFLAGS="$CFLAGS -DLIBSSH2_WIN32"
|
CFLAGS="$CFLAGS -DLIBSSH2_WIN32"
|
||||||
;;
|
;;
|
||||||
@@ -40,6 +44,11 @@ case "$host" in
|
|||||||
;;
|
;;
|
||||||
esac
|
esac
|
||||||
|
|
||||||
|
AC_CHECK_TYPE(long long,
|
||||||
|
[AC_DEFINE(HAVE_LONGLONG, 1,
|
||||||
|
[Define to 1 if the compiler supports the 'long long' data type.])]
|
||||||
|
longlong="yes"
|
||||||
|
)
|
||||||
# Some systems (Solaris?) have socket() in -lsocket.
|
# Some systems (Solaris?) have socket() in -lsocket.
|
||||||
AC_SEARCH_LIBS(socket, socket)
|
AC_SEARCH_LIBS(socket, socket)
|
||||||
|
|
||||||
@@ -52,153 +61,57 @@ AC_PROG_CC
|
|||||||
AC_PROG_INSTALL
|
AC_PROG_INSTALL
|
||||||
AC_PROG_LN_S
|
AC_PROG_LN_S
|
||||||
AC_PROG_MAKE_SET
|
AC_PROG_MAKE_SET
|
||||||
|
AC_PATH_PROGS(SSHD, [sshd], [],
|
||||||
|
[$PATH$PATH_SEPARATOR/usr/libexec$PATH_SEPARATOR]dnl
|
||||||
|
[/usr/sbin$PATH_SEPARATOR/usr/etc$PATH_SEPARATOR/etc])
|
||||||
|
AM_CONDITIONAL(SSHD, test -n "$SSHD")
|
||||||
|
AC_LIBTOOL_WIN32_DLL
|
||||||
AC_PROG_LIBTOOL
|
AC_PROG_LIBTOOL
|
||||||
AC_C_BIGENDIAN
|
AC_C_BIGENDIAN
|
||||||
if test -z "$PKG_CONFIG"; then
|
|
||||||
AC_PATH_PROG(PKG_CONFIG, pkg-config, no)
|
|
||||||
fi
|
|
||||||
|
|
||||||
dnl check for how to do large files
|
dnl check for how to do large files
|
||||||
AC_SYS_LARGEFILE
|
AC_SYS_LARGEFILE
|
||||||
|
|
||||||
# Look for libgcrypt.
|
# Configure parameters
|
||||||
AC_ARG_WITH(libgcrypt,
|
AC_ARG_WITH(libgcrypt,
|
||||||
AC_HELP_STRING([--with-libgcrypt],[Use libgcrypt for crypto]),
|
AC_HELP_STRING([--with-libgcrypt],[Use Libgcrypt for crypto]),
|
||||||
use_libgcrypt=$withval,use_libgcrypt=no)
|
use_libgcrypt=$withval,use_libgcrypt=auto)
|
||||||
if test "$use_libgcrypt" != "no"; then
|
AC_ARG_WITH(openssl,
|
||||||
|
AC_HELP_STRING([--with-openssl],[Use OpenSSL for crypto]),
|
||||||
|
use_openssl=$withval,use_openssl=auto)
|
||||||
|
AC_ARG_WITH(libz,
|
||||||
|
AC_HELP_STRING([--with-libz],[Use Libz for compression]),
|
||||||
|
use_libz=$withval,use_libz=auto)
|
||||||
|
|
||||||
|
# Look for OpenSSL (default)
|
||||||
|
if test "$use_openssl" != "no" && test "$use_libgcrypt" != "yes"; then
|
||||||
|
AC_LIB_HAVE_LINKFLAGS([ssl], [crypto], [#include <openssl/ssl.h>])
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Look for libgcrypt
|
||||||
|
if test "$ac_cv_libssl" != "yes" && test "$use_libgcrypt" != "no"; then
|
||||||
AC_LIB_HAVE_LINKFLAGS([gcrypt], [], [#include <gcrypt.h>])
|
AC_LIB_HAVE_LINKFLAGS([gcrypt], [], [#include <gcrypt.h>])
|
||||||
fi
|
fi
|
||||||
if test "$ac_cv_libgcrypt" = yes; then
|
|
||||||
use_libgcrypt=yes
|
if test "$ac_cv_libssl" != "yes" && test "$ac_cv_libgcrypt" != "yes"; then
|
||||||
|
AC_MSG_ERROR([cannot find OpenSSL or Libgcrypt,
|
||||||
|
try --with-libssl-prefix=PATH or --with-libgcrypt-prefix=PATH])
|
||||||
|
fi
|
||||||
|
|
||||||
|
if test "$ac_cv_libgcrypt" = "yes"; then
|
||||||
AC_DEFINE(LIBSSH2_LIBGCRYPT, 1, [Use libgcrypt])
|
AC_DEFINE(LIBSSH2_LIBGCRYPT, 1, [Use libgcrypt])
|
||||||
fi
|
fi
|
||||||
AM_CONDITIONAL(LIBGCRYPT, test "$use_libgcrypt" != "no")
|
AM_CONDITIONAL(LIBGCRYPT, test "$ac_cv_libgcrypt" = "yes")
|
||||||
|
|
||||||
# Need to define SHLIB_SUFFIX_NAME before checking for libcrypt and libz
|
# Look for Libz
|
||||||
# $shrext_cmds (from libtool) can contain commands so it must be eval'd
|
if test "$use_libz" != "no"; then
|
||||||
# Simon's note: replace the find-openssl/libz logic with Bruno's
|
AC_LIB_HAVE_LINKFLAGS([z], [], [#include <zlib.h>])
|
||||||
# AC_LIB_LINKFLAGS which is more portable and flexible.
|
if test "$ac_cv_libz" != yes; then
|
||||||
eval SHLIB_SUFFIX_NAME=\"$shrext_cmds\"
|
AC_MSG_NOTICE([Cannot find libz, disabling compression])
|
||||||
AC_SUBST(SHLIB_SUFFIX_NAME)
|
AC_MSG_NOTICE([Try --with-libz-prefix=PATH if you know you have it])
|
||||||
|
|
||||||
#
|
|
||||||
# Look for OpenSSL
|
|
||||||
#
|
|
||||||
AC_ARG_WITH(openssl,
|
|
||||||
AC_HELP_STRING([--with-openssl=DIR],[Look for OpenSSL in PATH]),
|
|
||||||
[LIBSSH2_OPENSSL_DIR=$withval],[LIBSSH2_OPENSSL_DIR=yes])
|
|
||||||
|
|
||||||
if test "$use_libgcrypt" = "no"; then
|
|
||||||
|
|
||||||
if test "$LIBSSH2_OPENSSL_DIR" = "no" || test "$LIBSSH2_OPENSSL_DIR" = "yes"; then
|
|
||||||
unset LIBSSH2_OPENSSL_DIR
|
|
||||||
fi
|
|
||||||
|
|
||||||
found_openssl=no
|
|
||||||
pkgcfg_openssl=no
|
|
||||||
unset OPENSSL_INCDIR
|
|
||||||
unset OPENSSL_INCLINE
|
|
||||||
unset OPENSSL_LIBLINE
|
|
||||||
|
|
||||||
AC_MSG_CHECKING([for OpenSSL])
|
|
||||||
|
|
||||||
# Explicit path given, use it rather than pkg-config
|
|
||||||
if test ! -z "$LIBSSH2_OPENSSL_DIR"; then
|
|
||||||
found_openssl=yes
|
|
||||||
OPENSSL_LIBLINE="-L$LIBSSH2_OPENSSL_DIR/lib -lcrypto"
|
|
||||||
OPENSSL_INCLINE="-I$LIBSSH2_OPENSSL_DIR/include"
|
|
||||||
OPENSSL_INCDIR=$LIBSSH2_OPENSSL_DIR/include
|
|
||||||
AC_MSG_RESULT([Using explicit path $LIBSSH2_OPENSSL_DIR])
|
|
||||||
fi
|
|
||||||
|
|
||||||
# If pkg-config is found try using it
|
|
||||||
if test "$found_openssl" = "no" && test -x "$PKG_CONFIG" && $PKG_CONFIG --exists openssl; then
|
|
||||||
found_openssl=yes
|
|
||||||
pkgcfg_openssl=yes
|
|
||||||
OPENSSL_LIBLINE=`$PKG_CONFIG --libs openssl`
|
|
||||||
OPENSSL_INCLINE=`$PKG_CONFIG --cflags-only-I openssl`
|
|
||||||
AC_MSG_RESULT([Using paths from pkg-config])
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Elsewise, search for OpenSSL wherever it might be
|
|
||||||
if test "$found_openssl" = "no"; then
|
|
||||||
OPENSSL_SEARCH_PATH="/usr/local/ssl /usr/local /usr /usr/local/openssl"
|
|
||||||
|
|
||||||
for i in $OPENSSL_SEARCH_PATH; do
|
|
||||||
if test -r $i/include/openssl/evp.h; then
|
|
||||||
OPENSSL_INCLINE="-I$i/include"
|
|
||||||
OPENSSL_INCDIR=$i/include
|
|
||||||
fi
|
|
||||||
if test -r $i/include/openssl/hmac.h; then
|
|
||||||
OPENSSL_INCLINE="-I$i/include"
|
|
||||||
OPENSSL_INCDIR=$i/include
|
|
||||||
fi
|
|
||||||
if test -r $i/lib/libcrypto.a -o -r $i/lib/libcrypto$SHLIB_SUFFIX_NAME; then
|
|
||||||
OPENSSL_LIBLINE="-L$i/lib -lcrypto"
|
|
||||||
fi
|
|
||||||
test -n "$OPENSSL_INCLINE" && test -n "$OPENSSL_LIBLINE" && break
|
|
||||||
done
|
|
||||||
|
|
||||||
if test -z "$OPENSSL_INCLINE"; then
|
|
||||||
AC_MSG_ERROR([Cannot find OpenSSL's <evp.h> or <hmac.h>])
|
|
||||||
fi
|
|
||||||
|
|
||||||
if test -z "$OPENSSL_LIBLINE"; then
|
|
||||||
AC_MSG_ERROR([Cannot find OpenSSL's libcrypto])
|
|
||||||
fi
|
|
||||||
|
|
||||||
AC_MSG_RESULT([$OPENSSL_INCLINE $OPENSSL_LIBLINE])
|
|
||||||
fi
|
|
||||||
|
|
||||||
#
|
|
||||||
# Confirm required OpenSSL libs
|
|
||||||
#
|
|
||||||
if test ! "$pkgcfg_openssl" = "yes"; then
|
|
||||||
if test ! -r $OPENSSL_INCDIR/openssl/bn.h || test ! -r $OPENSSL_INCDIR/openssl/evp.h || \
|
|
||||||
test ! -r $OPENSSL_INCDIR/openssl/hmac.h || test ! -r $OPENSSL_INCDIR/openssl/pem.h || \
|
|
||||||
test ! -r $OPENSSL_INCDIR/openssl/sha.h; then
|
|
||||||
AC_MSG_ERROR([Missing one or more of <openssl/bn.h>, <openssl/evp.h>, <openssl/hmac.h>, <openssl/pem.h>, <openssl/sha.h>])
|
|
||||||
fi
|
|
||||||
fi
|
|
||||||
|
|
||||||
CFLAGS="$CFLAGS $OPENSSL_INCLINE"
|
|
||||||
LDFLAGS="$LDFLAGS $OPENSSL_LIBLINE"
|
|
||||||
|
|
||||||
fi
|
|
||||||
|
|
||||||
#
|
|
||||||
# zlib
|
|
||||||
#
|
|
||||||
AC_ARG_WITH(libz,
|
|
||||||
AC_HELP_STRING([--with-libz=PATH],[Look for libz in PATH]),
|
|
||||||
[LIBSSH2_LIBZ_DIR=$withval],[LIBSSH2_LIBZ_DIR="/usr/local /usr /usr/local/libz /usr/libz /usr/local/zlib /usr/zlib"])
|
|
||||||
|
|
||||||
if test "$LIBSSH2_LIBZ_DIR" = "no" || test "$LIBSSH2_LIBZ_DIR" = "yes"; then
|
|
||||||
unset LIBSSH2_LIBZ_DIR
|
|
||||||
fi
|
|
||||||
|
|
||||||
unset LIBZ_INCDIR
|
|
||||||
unset LIBZ_LIBDIR
|
|
||||||
|
|
||||||
AC_MSG_CHECKING([for libz])
|
|
||||||
|
|
||||||
for i in $LIBSSH2_LIBZ_DIR; do
|
|
||||||
if test -r $i/include/zlib.h; then
|
|
||||||
LIBZ_INCDIR=$i/include
|
|
||||||
fi
|
|
||||||
if test -r $i/lib/libz.a -o -r $i/lib/libz$SHLIB_SUFFIX_NAME; then
|
|
||||||
LIBZ_LIBDIR=$i/lib
|
|
||||||
fi
|
|
||||||
test -n "$LIBZ_INCDIR" && test -n "$LIBZ_LIBDIR" && break
|
|
||||||
done
|
|
||||||
|
|
||||||
if test -n "$LIBZ_INCDIR" && test -n "$LIBZ_LIBDIR"; then
|
|
||||||
AC_MSG_RESULT([Found in $LIBZ_INCDIR $LIBZ_LIBDIR])
|
|
||||||
CFLAGS="$CFLAGS -I$LIBZ_INCDIR"
|
|
||||||
LDFLAGS="$LDFLAGS -L$LIBZ_LIBDIR -lz"
|
|
||||||
AC_DEFINE(LIBSSH2_HAVE_ZLIB, 1, [Compile in zlib support])
|
|
||||||
else
|
else
|
||||||
AC_MSG_RESULT([Cannot find libz's <zlib.h>])
|
AC_DEFINE(LIBSSH2_HAVE_ZLIB, 1, [Compile in zlib support])
|
||||||
|
fi
|
||||||
fi
|
fi
|
||||||
|
|
||||||
#
|
#
|
||||||
@@ -249,7 +162,39 @@ AC_HELP_STRING([--disable-debug],[Disable debug options]),
|
|||||||
AC_CHECK_HEADERS([errno.h fcntl.h stdio.h stdlib.h unistd.h sys/uio.h])
|
AC_CHECK_HEADERS([errno.h fcntl.h stdio.h stdlib.h unistd.h sys/uio.h])
|
||||||
AC_CHECK_HEADERS([sys/select.h sys/socket.h sys/ioctl.h sys/time.h])
|
AC_CHECK_HEADERS([sys/select.h sys/socket.h sys/ioctl.h sys/time.h])
|
||||||
AC_CHECK_HEADERS([arpa/inet.h netinet/in.h])
|
AC_CHECK_HEADERS([arpa/inet.h netinet/in.h])
|
||||||
AC_CHECK_FUNCS(poll gettimeofday select)
|
|
||||||
|
case $host in
|
||||||
|
*-*-cygwin* | *-*-cegcc*)
|
||||||
|
# These are POSIX-like systems using BSD-like sockets API.
|
||||||
|
;;
|
||||||
|
*)
|
||||||
|
AC_CHECK_HEADERS([windows.h winsock2.h ws2tcpip.h])
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
|
||||||
|
AC_CHECK_FUNCS(poll gettimeofday select strtoll)
|
||||||
|
|
||||||
|
dnl Check for select() into ws2_32 for Msys/Mingw
|
||||||
|
if test "$ac_cv_func_select" != "yes"; then
|
||||||
|
AC_MSG_CHECKING([for select in ws2_32])
|
||||||
|
AC_TRY_LINK([
|
||||||
|
#ifdef HAVE_WINSOCK2_H
|
||||||
|
#ifndef WIN32_LEAN_AND_MEAN
|
||||||
|
#define WIN32_LEAN_AND_MEAN
|
||||||
|
#endif
|
||||||
|
#include <winsock2.h>
|
||||||
|
#endif
|
||||||
|
],[
|
||||||
|
select(0,(fd_set *)NULL,(fd_set *)NULL,(fd_set *)NULL,(struct timeval *)NULL);
|
||||||
|
],[
|
||||||
|
AC_MSG_RESULT([yes])
|
||||||
|
HAVE_SELECT="1"
|
||||||
|
AC_DEFINE_UNQUOTED(HAVE_SELECT, 1,
|
||||||
|
[Define to 1 if you have the select function.])
|
||||||
|
],[
|
||||||
|
AC_MSG_RESULT([no])
|
||||||
|
])
|
||||||
|
fi
|
||||||
|
|
||||||
AC_FUNC_ALLOCA
|
AC_FUNC_ALLOCA
|
||||||
|
|
||||||
|
@@ -1,2 +1,3 @@
|
|||||||
Makefile
|
Makefile
|
||||||
Makefile.in
|
Makefile.in
|
||||||
|
coverage
|
||||||
|
@@ -1,4 +1,4 @@
|
|||||||
# $Id: Makefile.am,v 1.26 2007/06/15 11:01:22 jehousley Exp $
|
# $Id: Makefile.am,v 1.31 2008/12/26 07:46:45 bagder Exp $
|
||||||
|
|
||||||
EXTRA_DIST = template.3
|
EXTRA_DIST = template.3
|
||||||
|
|
||||||
@@ -23,11 +23,14 @@ dist_man_MANS = \
|
|||||||
libssh2_channel_set_blocking.3 \
|
libssh2_channel_set_blocking.3 \
|
||||||
libssh2_channel_setenv_ex.3 \
|
libssh2_channel_setenv_ex.3 \
|
||||||
libssh2_channel_wait_eof.3 \
|
libssh2_channel_wait_eof.3 \
|
||||||
|
libssh2_channel_wait_closed.3 \
|
||||||
|
libssh2_channel_write_ex.3 \
|
||||||
libssh2_channel_x11_req_ex.3 \
|
libssh2_channel_x11_req_ex.3 \
|
||||||
libssh2_hostkey_hash.3 \
|
libssh2_hostkey_hash.3 \
|
||||||
libssh2_scp_recv.3 \
|
libssh2_scp_recv.3 \
|
||||||
libssh2_scp_send_ex.3 \
|
libssh2_scp_send_ex.3 \
|
||||||
libssh2_session_abstract.3 \
|
libssh2_session_abstract.3 \
|
||||||
|
libssh2_session_block_directions.3 \
|
||||||
libssh2_session_callback_set.3 \
|
libssh2_session_callback_set.3 \
|
||||||
libssh2_session_free.3 \
|
libssh2_session_free.3 \
|
||||||
libssh2_session_disconnect_ex.3 \
|
libssh2_session_disconnect_ex.3 \
|
||||||
@@ -55,9 +58,13 @@ dist_man_MANS = \
|
|||||||
libssh2_sftp_stat_ex.3 \
|
libssh2_sftp_stat_ex.3 \
|
||||||
libssh2_sftp_symlink_ex.3 \
|
libssh2_sftp_symlink_ex.3 \
|
||||||
libssh2_sftp_tell.3 \
|
libssh2_sftp_tell.3 \
|
||||||
|
libssh2_sftp_tell64.3 \
|
||||||
libssh2_sftp_unlink_ex.3 \
|
libssh2_sftp_unlink_ex.3 \
|
||||||
libssh2_sftp_write.3 \
|
libssh2_sftp_write.3 \
|
||||||
libssh2_userauth_authenticated.3 \
|
libssh2_userauth_authenticated.3 \
|
||||||
|
libssh2_userauth_keyboard_interactive_ex.3 \
|
||||||
libssh2_userauth_list.3 \
|
libssh2_userauth_list.3 \
|
||||||
libssh2_userauth_password_ex.3 \
|
libssh2_userauth_password_ex.3 \
|
||||||
libssh2_userauth_publickey_fromfile.3
|
libssh2_userauth_publickey_fromfile.3 \
|
||||||
|
libssh2_base64_decode.3 \
|
||||||
|
libssh2_trace.3
|
||||||
|
27
docs/libssh2_base64_decode.3
Normal file
27
docs/libssh2_base64_decode.3
Normal file
@@ -0,0 +1,27 @@
|
|||||||
|
.\" $Id: libssh2_base64_decode.3,v 1.2 2008/12/26 07:37:55 bagder Exp $
|
||||||
|
.\"
|
||||||
|
.TH libssh2_base64_decode 3 "23 Dec 2008" "libssh2 1.0" "libssh2 manual"
|
||||||
|
.SH NAME
|
||||||
|
libssh2_base64_decode - decode a base64 encoded string
|
||||||
|
.SH SYNOPSIS
|
||||||
|
#include <libssh2.h>
|
||||||
|
|
||||||
|
int libssh2_base64_decode(LIBSSH2_SESSION *session, char **dest,
|
||||||
|
unsigned int *dest_len, const char *src,
|
||||||
|
unsigned int src_len);
|
||||||
|
.SH DESCRIPTION
|
||||||
|
This function is deemed DEPRECATED and will be removed from libssh2 in a
|
||||||
|
future version. Don't use it!
|
||||||
|
|
||||||
|
Decode a base64 chunk and store it into a newly allocated buffer. 'dest_len'
|
||||||
|
will be set to hold the length of the returned buffer that '*dest' will point
|
||||||
|
to.
|
||||||
|
|
||||||
|
The returned buffer is allocated by this function, but it is not clear how to
|
||||||
|
free that memory!
|
||||||
|
.SH BUGS
|
||||||
|
The memory that *dest points to is allocated by the malloc function libssh2
|
||||||
|
uses, but there's no way for an appliction to free this data in a safe and
|
||||||
|
reliable way!
|
||||||
|
.SH RETURN VALUE
|
||||||
|
0 if successful, -1 if any error occurred.
|
@@ -1,8 +1,8 @@
|
|||||||
.\" $Id: libssh2_channel_close.3,v 1.1 2007/06/13 17:03:38 jehousley Exp $
|
.\" $Id: libssh2_channel_close.3,v 1.2 2007/11/29 09:57:22 bagder Exp $
|
||||||
.\"
|
.\"
|
||||||
.TH libssh2_channel_close 3 "1 Jun 2007" "libssh2 0.15" "libssh2 manual"
|
.TH libssh2_channel_close 3 "1 Jun 2007" "libssh2 0.15" "libssh2 manual"
|
||||||
.SH NAME
|
.SH NAME
|
||||||
libssh2_channel_close - close a channel<
|
libssh2_channel_close - close a channel
|
||||||
.SH SYNOPSIS
|
.SH SYNOPSIS
|
||||||
#include <libssh2.h>
|
#include <libssh2.h>
|
||||||
|
|
||||||
|
24
docs/libssh2_channel_wait_closed.3
Normal file
24
docs/libssh2_channel_wait_closed.3
Normal file
@@ -0,0 +1,24 @@
|
|||||||
|
.\" $Id: libssh2_channel_wait_closed.3,v 1.2 2007/11/29 10:04:16 bagder Exp $
|
||||||
|
.\"
|
||||||
|
.TH libssh2_channel_wait_closed 3 "29 Nov 2007" "libssh2 0.19" "libssh2 manual"
|
||||||
|
.SH NAME
|
||||||
|
libssh2_channel_wait_closed - wait for the remote to close the channel
|
||||||
|
.SH SYNOPSIS
|
||||||
|
#include <libssh2.h>
|
||||||
|
|
||||||
|
int
|
||||||
|
libssh2_channel_wait_closed(LIBSSH2_CHANNEL *channel);
|
||||||
|
|
||||||
|
.SH DESCRIPTION
|
||||||
|
Enter a temporary blocking state until the remote host closes the named
|
||||||
|
channel. Typically sent after \fIlibssh2_channel_close(3)\fP in order to
|
||||||
|
examine the exit status.
|
||||||
|
|
||||||
|
.SH RETURN VALUE
|
||||||
|
Return 0 on success or negative on failure. It returns LIBSSH2_ERROR_EAGAIN
|
||||||
|
when it would otherwise block. While LIBSSH2_ERROR_EAGAIN is a negative
|
||||||
|
number, it isn't really a failure per se.
|
||||||
|
.SH SEE ALSO
|
||||||
|
.BR libssh2_channel_send_eof(3)
|
||||||
|
.BR libssh2_channel_eof(3)
|
||||||
|
.BR libssh2_channel_wait_eof(3)
|
@@ -1,4 +1,4 @@
|
|||||||
.\" $Id: libssh2_session_abstract.3,v 1.1 2007/06/14 15:26:58 jehousley Exp $
|
.\" $Id: libssh2_session_abstract.3,v 1.2 2008/07/03 10:58:53 bagder Exp $
|
||||||
.\"
|
.\"
|
||||||
.TH libssh2_session_abstract 3 "1 Jun 2007" "libssh2 0.15" "libssh2 manual"
|
.TH libssh2_session_abstract 3 "1 Jun 2007" "libssh2 0.15" "libssh2 manual"
|
||||||
.SH NAME
|
.SH NAME
|
||||||
@@ -14,9 +14,9 @@ libssh2_session_abstract(LIBSSH2_SESSION *session);
|
|||||||
.BR libssh2_session_init_ex(3)
|
.BR libssh2_session_init_ex(3)
|
||||||
|
|
||||||
Return a pointer to where the abstract pointer provided to
|
Return a pointer to where the abstract pointer provided to
|
||||||
.BR libssh2_session_init_ex(3)
|
\fBlibssh2_session_init_ex(3)\fP is stored. By providing a doubly
|
||||||
is stored. By providing a doubly de-referenced pointer, the internal
|
de-referenced pointer, the internal storage of the session instance may be
|
||||||
storage of the session instance may be modified in place.
|
modified in place.
|
||||||
|
|
||||||
.SH RETURN VALUE
|
.SH RETURN VALUE
|
||||||
A pointer to session internal storage whos contents point to previously
|
A pointer to session internal storage whos contents point to previously
|
||||||
|
31
docs/libssh2_session_block_directions.3
Normal file
31
docs/libssh2_session_block_directions.3
Normal file
@@ -0,0 +1,31 @@
|
|||||||
|
.\" $Id: libssh2_session_block_directions.3,v 1.2 2008/12/22 12:51:27 bagder Exp $
|
||||||
|
.\"
|
||||||
|
.TH libssh2_session_block_directions 3 "1 Oct 2008" "libssh2 1.0" "libssh2 manual"
|
||||||
|
.SH NAME
|
||||||
|
libssh2_session_block_directions - get directions that socket should wait for before calling libssh2 function again
|
||||||
|
.SH SYNOPSIS
|
||||||
|
#include <libssh2.h>
|
||||||
|
|
||||||
|
int
|
||||||
|
libssh2_session_block_directions(LIBSSH2_SESSION *session);
|
||||||
|
.SH DESCRIPTION
|
||||||
|
\fIsession\fP - Session instance as returned by \fBlibssh2_session_init(3)\fP
|
||||||
|
|
||||||
|
When any of libssh2 functions return \fBLIBSSH2_ERROR_EAGAIN\fP an application
|
||||||
|
should wait for the socket to have data available for reading or
|
||||||
|
writing. Depending on the return value of
|
||||||
|
\fIlibssh2_session_block_directions(3)\fP an application should wait for read,
|
||||||
|
write or both.
|
||||||
|
.SH RETURN VALUE
|
||||||
|
Returns the set of directions as a binary mask. Can be a combination of:
|
||||||
|
|
||||||
|
LIBSSH2_SESSION_BLOCK_INBOUND: Inbound direction blocked.
|
||||||
|
|
||||||
|
LIBSSH2_SESSION_BLOCK_OUTBOUND: Outbound direction blocked.
|
||||||
|
|
||||||
|
Application should wait for data to be available for socket prior to calling a
|
||||||
|
libssh2 function again. If \fBLIBSSH2_SESSION_BLOCK_INBOUND\fP is set select
|
||||||
|
should contain the session socket in readfds set. Correspondingly in case of
|
||||||
|
\fBLIBSSH2_SESSION_BLOCK_INBOUND\fP writefds set should contain the socket.
|
||||||
|
.SH AVAILABILITY
|
||||||
|
Added in 1.0
|
@@ -1,4 +1,4 @@
|
|||||||
.\" $Id: libssh2_session_set_blocking.3,v 1.1 2007/06/14 17:23:13 jehousley Exp $
|
.\" $Id: libssh2_session_set_blocking.3,v 1.2 2008/07/03 10:58:53 bagder Exp $
|
||||||
.\"
|
.\"
|
||||||
.TH libssh2_session_set_blocking 3 "1 Jun 2007" "libssh2 0.15" "libssh2 manual"
|
.TH libssh2_session_set_blocking 3 "1 Jun 2007" "libssh2 0.15" "libssh2 manual"
|
||||||
.SH NAME
|
.SH NAME
|
||||||
@@ -16,14 +16,14 @@ libssh2_session_set_blocking(LIBSSH2_SESSION *session, int blocking);
|
|||||||
\fIblocking\fP - Set to a non-zero value to make the channel block, or zero to
|
\fIblocking\fP - Set to a non-zero value to make the channel block, or zero to
|
||||||
make it non-blocking.
|
make it non-blocking.
|
||||||
|
|
||||||
Set or clear blocking mode on the selected on the sessoin. This will
|
Set or clear blocking mode on the selected on the session. This will
|
||||||
instantly affect any channels associtated with this session. If a read is
|
instantly affect any channels associated with this session. If a read is
|
||||||
performed on a session with no data currently available, a blocking
|
performed on a session with no data currently available, a blocking session
|
||||||
session will wait for data to arrive and return what it receives.
|
will wait for data to arrive and return what it receives. A non-blocking
|
||||||
A non-blocking session will return immediately with an empty buffer.
|
session will return immediately with an empty buffer. If a write is performed
|
||||||
If a write is performed on a session with
|
on a session with no room for more data, a blocking session will wait for
|
||||||
no room for more data, a blocking session will wait for room. A non-blocking
|
room. A non-blocking session will return immediately without writing
|
||||||
session will return immediately without writing anything.
|
anything.
|
||||||
|
|
||||||
.SH RETURN VALUE
|
.SH RETURN VALUE
|
||||||
None
|
None
|
||||||
|
@@ -1,8 +1,8 @@
|
|||||||
.\" $Id: libssh2_sftp_init.3,v 1.6 2007/06/13 16:41:33 jehousley Exp $
|
.\" $Id: libssh2_sftp_init.3,v 1.7 2007/11/21 14:07:32 dottedmag Exp $
|
||||||
.\"
|
.\"
|
||||||
.TH libssh2_sftp_init 3 "1 Jun 2007" "libssh2 0.15" "libssh2 manual"
|
.TH libssh2_sftp_init 3 "1 Jun 2007" "libssh2 0.15" "libssh2 manual"
|
||||||
.SH NAME
|
.SH NAME
|
||||||
libssh2_sftp_init -
|
libssh2_sftp_init - open SFTP channel for the given SSH session.
|
||||||
.SH SYNOPSIS
|
.SH SYNOPSIS
|
||||||
#include <libssh2.h>
|
#include <libssh2.h>
|
||||||
#include <libssh2_sftp.h>
|
#include <libssh2_sftp.h>
|
||||||
|
@@ -1,4 +1,4 @@
|
|||||||
.\" $Id: libssh2_sftp_last_error.3,v 1.1 2007/06/14 16:08:43 jehousley Exp $
|
.\" $Id: libssh2_sftp_last_error.3,v 1.2 2008/12/15 18:48:09 bagder Exp $
|
||||||
.\"
|
.\"
|
||||||
.TH libssh2_sftp_last_error 3 "1 Jun 2007" "libssh2 0.15" "libssh2 manual"
|
.TH libssh2_sftp_last_error 3 "1 Jun 2007" "libssh2 0.15" "libssh2 manual"
|
||||||
.SH NAME
|
.SH NAME
|
||||||
@@ -14,7 +14,10 @@ libssh2_sftp_last_error(LIBSSH2_SFTP *sftp);
|
|||||||
\fIsftp\fP - SFTP instance as returned by
|
\fIsftp\fP - SFTP instance as returned by
|
||||||
.BR libssh2_sftp_init(3)
|
.BR libssh2_sftp_init(3)
|
||||||
|
|
||||||
Determines the last error code produced by the SFTP layer.
|
Returns the last error code produced by the SFTP layer. Note that this only
|
||||||
|
returns a sensible error code if libssh2 returned LIBSSH2_ERROR_SFTP_PROTOCOL
|
||||||
|
in a previous call. Using \fBlibssh2_sftp_last_error(3)\fP without a
|
||||||
|
preceeding SFTP protocol error, it will return an unspecified value.
|
||||||
|
|
||||||
.SH RETURN VALUE
|
.SH RETURN VALUE
|
||||||
Current error code state of the SFTP instance.
|
Current error code state of the SFTP instance.
|
||||||
|
@@ -1,8 +1,8 @@
|
|||||||
.\" $Id: libssh2_sftp_open_ex.3,v 1.8 2007/06/13 16:41:33 jehousley Exp $
|
.\" $Id: libssh2_sftp_open_ex.3,v 1.9 2007/11/21 14:07:32 dottedmag Exp $
|
||||||
.\"
|
.\"
|
||||||
.TH libssh2_sftp_open_ex 3 "1 Jun 2007" "libssh2 0.15" "libssh2 manual"
|
.TH libssh2_sftp_open_ex 3 "1 Jun 2007" "libssh2 0.15" "libssh2 manual"
|
||||||
.SH NAME
|
.SH NAME
|
||||||
libssh2_sftp_open -
|
libssh2_sftp_open - open filehandle for file on SFTP.
|
||||||
.SH SYNOPSIS
|
.SH SYNOPSIS
|
||||||
#include <libssh2.h>
|
#include <libssh2.h>
|
||||||
#include <libssh2_sftp.h>
|
#include <libssh2_sftp.h>
|
||||||
|
@@ -1,8 +1,8 @@
|
|||||||
.\" $Id: libssh2_sftp_rename_ex.3,v 1.1 2007/06/14 16:08:43 jehousley Exp $
|
.\" $Id: libssh2_sftp_rename_ex.3,v 1.2 2008/12/23 12:34:17 bagder Exp $
|
||||||
.\"
|
.\"
|
||||||
.TH libssh2_sftp_rename_ex 3 "1 Jun 2007" "libssh2 0.15" "libssh2 manual"
|
.TH libssh2_sftp_rename_ex 3 "1 Jun 2007" "libssh2 0.15" "libssh2 manual"
|
||||||
.SH NAME
|
.SH NAME
|
||||||
libssh2_sftp_rename_ex - rename a file
|
libssh2_sftp_rename_ex - rename an SFTP file
|
||||||
.SH SYNOPSIS
|
.SH SYNOPSIS
|
||||||
#include <libssh2.h>
|
#include <libssh2.h>
|
||||||
#include <libssh2_sftp.h>
|
#include <libssh2_sftp.h>
|
||||||
|
@@ -1,8 +1,8 @@
|
|||||||
.\" $Id: libssh2_sftp_rmdir_ex.3,v 1.1 2007/06/14 16:08:43 jehousley Exp $
|
.\" $Id: libssh2_sftp_rmdir_ex.3,v 1.2 2008/12/23 12:34:17 bagder Exp $
|
||||||
.\"
|
.\"
|
||||||
.TH libssh2_sftp_rmdir_ex 3 "1 Jun 2007" "libssh2 0.15" "libssh2 manual"
|
.TH libssh2_sftp_rmdir_ex 3 "1 Jun 2007" "libssh2 0.15" "libssh2 manual"
|
||||||
.SH NAME
|
.SH NAME
|
||||||
libssh2_sftp_rmdir_ex - rename a file
|
libssh2_sftp_rmdir_ex - remove an SFTP directory
|
||||||
.SH SYNOPSIS
|
.SH SYNOPSIS
|
||||||
#include <libssh2.h>
|
#include <libssh2.h>
|
||||||
#include <libssh2_sftp.h>
|
#include <libssh2_sftp.h>
|
||||||
|
@@ -1,6 +1,6 @@
|
|||||||
.\" $Id: libssh2_sftp_seek.3,v 1.1 2007/06/14 16:08:43 jehousley Exp $
|
.\" $Id: libssh2_sftp_seek.3,v 1.3 2008/12/22 13:18:36 bagder Exp $
|
||||||
.\"
|
.\"
|
||||||
.TH libssh2_sftp_seek 3 "1 Jun 2007" "libssh2 0.15" "libssh2 manual"
|
.TH libssh2_sftp_seek 3 "22 Dec 2008" "libssh2 1.0" "libssh2 manual"
|
||||||
.SH NAME
|
.SH NAME
|
||||||
libssh2_sftp_seek - set the read/write position indicator within a file
|
libssh2_sftp_seek - set the read/write position indicator within a file
|
||||||
.SH SYNOPSIS
|
.SH SYNOPSIS
|
||||||
@@ -10,6 +10,9 @@ libssh2_sftp_seek - set the read/write position indicator within a file
|
|||||||
void
|
void
|
||||||
libssh2_sftp_seek(LIBSSH2_SFTP_HANDLE *handle, size_t offset);
|
libssh2_sftp_seek(LIBSSH2_SFTP_HANDLE *handle, size_t offset);
|
||||||
|
|
||||||
|
void
|
||||||
|
libssh2_sftp_seek64(LIBSSH2_SFTP_HANDLE *handle, libssh2_uint64_t offset);
|
||||||
|
|
||||||
.SH DESCRIPTION
|
.SH DESCRIPTION
|
||||||
\fIhandle\fP - SFTP File Handle as returned by
|
\fIhandle\fP - SFTP File Handle as returned by
|
||||||
.BR libssh2_sftp_open(3)
|
.BR libssh2_sftp_open(3)
|
||||||
@@ -21,6 +24,7 @@ Note that libssh2 implements file pointers as a localized concept to make
|
|||||||
file access appear more POSIX like. No packets are exchanged with the server
|
file access appear more POSIX like. No packets are exchanged with the server
|
||||||
during a seek operation. The localized file pointer is simply used as a
|
during a seek operation. The localized file pointer is simply used as a
|
||||||
convenience offset during read/write operations.
|
convenience offset during read/write operations.
|
||||||
|
.SH AVAILABILITY
|
||||||
|
libssh2_sftp_seek64(3) was added in 1.0
|
||||||
.SH SEE ALSO
|
.SH SEE ALSO
|
||||||
.BR libssh2_sftp_open(3)
|
.BR libssh2_sftp_open(3)
|
||||||
|
@@ -1,8 +1,8 @@
|
|||||||
.\" $Id: libssh2_sftp_stat_ex.3,v 1.1 2007/06/14 16:33:38 jehousley Exp $
|
.\" $Id: libssh2_sftp_stat_ex.3,v 1.2 2008/12/23 12:34:17 bagder Exp $
|
||||||
.\"
|
.\"
|
||||||
.TH libssh2_sftp_stat_ex 3 "1 Jun 2007" "libssh2 0.15" "libssh2 manual"
|
.TH libssh2_sftp_stat_ex 3 "1 Jun 2007" "libssh2 0.15" "libssh2 manual"
|
||||||
.SH NAME
|
.SH NAME
|
||||||
libssh2_sftp_stat_ex - rename a file
|
libssh2_sftp_stat_ex - get status about an SFTP file
|
||||||
.SH SYNOPSIS
|
.SH SYNOPSIS
|
||||||
#include <libssh2.h>
|
#include <libssh2.h>
|
||||||
#include <libssh2_sftp.h>
|
#include <libssh2_sftp.h>
|
||||||
|
@@ -1,4 +1,4 @@
|
|||||||
.\" $Id: libssh2_sftp_tell.3,v 1.1 2007/06/14 16:33:38 jehousley Exp $
|
.\" $Id: libssh2_sftp_tell.3,v 1.2 2008/12/22 12:46:45 bagder Exp $
|
||||||
.\"
|
.\"
|
||||||
.TH libssh2_sftp_tell 3 "1 Jun 2007" "libssh2 0.15" "libssh2 manual"
|
.TH libssh2_sftp_tell 3 "1 Jun 2007" "libssh2 0.15" "libssh2 manual"
|
||||||
.SH NAME
|
.SH NAME
|
||||||
@@ -11,16 +11,12 @@ size_t
|
|||||||
libssh2_sftp_tell(LIBSSH2_SFTP_HANDLE *handle);
|
libssh2_sftp_tell(LIBSSH2_SFTP_HANDLE *handle);
|
||||||
|
|
||||||
.SH DESCRIPTION
|
.SH DESCRIPTION
|
||||||
\fIhandle\fP - SFTP File Handle as returned by
|
\fIhandle\fP - SFTP File Handle as returned by \fBlibssh2_sftp_open(3)\fP.
|
||||||
.BR libssh2_sftp_open(3)
|
|
||||||
|
|
||||||
Identify the current offset of the file handle's internal pointer. Note
|
|
||||||
that the SSH2 protocol does not have a notion of file pointers and that
|
|
||||||
libssh2 implements this using a localized file pointer which is updated
|
|
||||||
with each read/write call.
|
|
||||||
|
|
||||||
|
Returns the current offset of the file handle's internal pointer. Note that
|
||||||
|
this is now deprecated. Use the newer \fBlibssh2_sftp_tell64(3)\fP instead!
|
||||||
.SH RETURN VALUE
|
.SH RETURN VALUE
|
||||||
Current offset from beginning of file in bytes.
|
Current offset from beginning of file in bytes.
|
||||||
|
|
||||||
.SH SEE ALSO
|
.SH SEE ALSO
|
||||||
.BR libssh2_sftp_open(3)
|
.BR libssh2_sftp_open(3),
|
||||||
|
.BR libssh2_sftp_tell64(3)
|
||||||
|
23
docs/libssh2_sftp_tell64.3
Normal file
23
docs/libssh2_sftp_tell64.3
Normal file
@@ -0,0 +1,23 @@
|
|||||||
|
.\" $Id: libssh2_sftp_tell64.3,v 1.1 2008/12/22 12:46:45 bagder Exp $
|
||||||
|
.\"
|
||||||
|
.TH libssh2_sftp_tell64 3 "22 Dec 2008" "libssh2 1.0" "libssh2 manual"
|
||||||
|
.SH NAME
|
||||||
|
libssh2_sftp_tell64 - get the current read/write position indicator for a file
|
||||||
|
.SH SYNOPSIS
|
||||||
|
#include <libssh2.h>
|
||||||
|
#include <libssh2_sftp.h>
|
||||||
|
|
||||||
|
libssh2_uint64_t
|
||||||
|
libssh2_sftp_tell64(LIBSSH2_SFTP_HANDLE *handle);
|
||||||
|
|
||||||
|
.SH DESCRIPTION
|
||||||
|
\fIhandle\fP - SFTP File Handle as returned by \fBlibssh2_sftp_open(3)\fP
|
||||||
|
|
||||||
|
Identify the current offset of the file handle's internal pointer.
|
||||||
|
.SH RETURN VALUE
|
||||||
|
Current offset from beginning of file in bytes.
|
||||||
|
.SH AVAILABILITY
|
||||||
|
Added in libssh2 1.0
|
||||||
|
.SH SEE ALSO
|
||||||
|
.BR libssh2_sftp_open(3),
|
||||||
|
.BR libssh2_sftp_tell(3)
|
@@ -1,8 +1,8 @@
|
|||||||
.\" $Id: libssh2_sftp_unlink_ex.3,v 1.1 2007/06/14 16:46:14 jehousley Exp $
|
.\" $Id: libssh2_sftp_unlink_ex.3,v 1.2 2008/12/23 12:34:17 bagder Exp $
|
||||||
.\"
|
.\"
|
||||||
.TH libssh2_sftp_unlink_ex 3 "1 Jun 2007" "libssh2 0.15" "libssh2 manual"
|
.TH libssh2_sftp_unlink_ex 3 "1 Jun 2007" "libssh2 0.15" "libssh2 manual"
|
||||||
.SH NAME
|
.SH NAME
|
||||||
libssh2_sftp_unlink_ex - rename a file
|
libssh2_sftp_unlink_ex - unlink an SFTP file
|
||||||
.SH SYNOPSIS
|
.SH SYNOPSIS
|
||||||
#include <libssh2.h>
|
#include <libssh2.h>
|
||||||
#include <libssh2_sftp.h>
|
#include <libssh2_sftp.h>
|
||||||
|
@@ -1,8 +1,8 @@
|
|||||||
.\" $Id: libssh2_sftp_write.3,v 1.1 2007/06/14 16:46:14 jehousley Exp $
|
.\" $Id: libssh2_sftp_write.3,v 1.2 2008/12/23 12:34:17 bagder Exp $
|
||||||
.\"
|
.\"
|
||||||
.TH libssh2_sftp_rename_ex 3 "1 Jun 2007" "libssh2 0.15" "libssh2 manual"
|
.TH libssh2_sftp_write 3 "1 Jun 2007" "libssh2 0.15" "libssh2 manual"
|
||||||
.SH NAME
|
.SH NAME
|
||||||
libssh2_sftp_rename_ex - rename a file
|
libssh2_sftp_write - write SFTP data
|
||||||
.SH SYNOPSIS
|
.SH SYNOPSIS
|
||||||
#include <libssh2.h>
|
#include <libssh2.h>
|
||||||
#include <libssh2_sftp.h>
|
#include <libssh2_sftp.h>
|
||||||
|
35
docs/libssh2_trace.3
Normal file
35
docs/libssh2_trace.3
Normal file
@@ -0,0 +1,35 @@
|
|||||||
|
.\" $Id: libssh2_trace.3,v 1.1 2008/12/26 07:46:45 bagder Exp $
|
||||||
|
.\"
|
||||||
|
.TH libssh2_trace 3 "26 Dec 2008" "libssh2 1.0" "libssh2 manual"
|
||||||
|
.SH NAME
|
||||||
|
libssh2_trace - enable debug info from inside libssh2
|
||||||
|
.SH SYNOPSIS
|
||||||
|
#include <libssh2.h>
|
||||||
|
|
||||||
|
void libssh2_trace(int bitmask);
|
||||||
|
|
||||||
|
.SH DESCRIPTION
|
||||||
|
This is a function present in the library that can be used to get debug info
|
||||||
|
from within libssh2 when it is running. Helpful when trying to trace or debug
|
||||||
|
behaviors. This function has no effect unless libssh2 was built to support
|
||||||
|
this option, and a typical "release build" might not.
|
||||||
|
|
||||||
|
\fBbitmask\fP can be set to none, one or more of these bits:
|
||||||
|
.RS
|
||||||
|
.IP LIBSSH2_TRACE_TRANS
|
||||||
|
Transport layer debugging
|
||||||
|
.IP LIBSSH2_TRACE_KEX
|
||||||
|
Key exchange debugging
|
||||||
|
.IP LIBSSH2_TRACE_AUTH
|
||||||
|
Authentication debugging
|
||||||
|
.IP LIBSSH2_TRACE_CONN
|
||||||
|
Connection layer debugging
|
||||||
|
.IP LIBSSH2_TRACE_SCP
|
||||||
|
SCP debugging
|
||||||
|
.IP LIBSSH2_TRACE_SFTP
|
||||||
|
SFTP debugging
|
||||||
|
.IP LIBSSH2_TRACE_ERROR
|
||||||
|
Error debugging
|
||||||
|
.IP LIBSSH2_TRACE_PUBLICKEY
|
||||||
|
Public Key debugging
|
||||||
|
.RE
|
43
docs/libssh2_userauth_keyboard_interactive_ex.3
Normal file
43
docs/libssh2_userauth_keyboard_interactive_ex.3
Normal file
@@ -0,0 +1,43 @@
|
|||||||
|
.\" $Id: libssh2_userauth_keyboard_interactive_ex.3,v 1.1 2008/03/08 18:26:32 dottedmag Exp $
|
||||||
|
.\"
|
||||||
|
.TH libssh2_userauth_keyboard_interactive_ex 3 "8 Mar 2008" "libssh2 0.19" "libssh2 manual"
|
||||||
|
.SH NAME
|
||||||
|
libssh2_userauth_keyboard_interactive_ex - authenticate a session using a challenge-response authentication
|
||||||
|
.SH SYNOPSIS
|
||||||
|
#include <libssh2.h>
|
||||||
|
|
||||||
|
int
|
||||||
|
libssh2_userauth_keyboard_interactive_ex(LIBSSH2_SESSION *session, const char *username, unsigned int username_len, LIBSSH2_USERAUTH_KBDINT_RESPONSE_FUNC(*response_callback));
|
||||||
|
|
||||||
|
int
|
||||||
|
libssh2_userauth_keyboard_interactive(LIBSSH2_SESSION *session, const char *username, LIBSSH2_USERAUTH_KBDINT_RESPONSE_FUNC(*response_callback));
|
||||||
|
|
||||||
|
.SH DESCRIPTION
|
||||||
|
\fIsession\fP - Session instance as returned by
|
||||||
|
.BR libssh2_session_init(3)
|
||||||
|
|
||||||
|
\fIusername\fP - Name of user to attempt plain password authentication for.
|
||||||
|
|
||||||
|
\fIusername_len\fP - Length of username parameter.
|
||||||
|
|
||||||
|
\fIresponse_callback\fP - As authentication proceeds, host issues several (1 or more) challenges and requires responses. This callback will be called at this moment. Callback is responsible to obtain responses for the challenges, fill the provided data structure and then return control. Responses will be sent to the host. String values will be free(3)ed by the library.
|
||||||
|
|
||||||
|
Attempts keyboard-interactive (challenge/response) authentication.
|
||||||
|
|
||||||
|
Note that many SSH servers will always issue single "password" challenge,
|
||||||
|
requesting actual password as response, but it is not required by the protocol,
|
||||||
|
and various authentication schemes, such as smartcard authentication may use
|
||||||
|
keyboard-interactive authentication type too.
|
||||||
|
|
||||||
|
.SH RETURN VALUE
|
||||||
|
Return 0 on success or negative on failure. It returns
|
||||||
|
LIBSSH2_ERROR_EAGAIN when it would otherwise block. While
|
||||||
|
LIBSSH2_ERROR_EAGAIN is a negative number, it isn't really a failure per se.
|
||||||
|
|
||||||
|
.SH ERRORS
|
||||||
|
\fILIBSSH2_ERROR_ALLOC\fP - An internal memory allocation call failed.
|
||||||
|
|
||||||
|
\fILIBSSH2_ERROR_SOCKET_SEND\fP - Unable to send data on socket.
|
||||||
|
|
||||||
|
.SH SEE ALSO
|
||||||
|
.BR libssh2_session_init(3)
|
@@ -2,8 +2,12 @@ Makefile
|
|||||||
Makefile.in
|
Makefile.in
|
||||||
.deps
|
.deps
|
||||||
.libs
|
.libs
|
||||||
|
*.gcno
|
||||||
|
*.gcda
|
||||||
scp
|
scp
|
||||||
scp_nonblock
|
scp_nonblock
|
||||||
|
scp_write
|
||||||
|
scp_write_nonblock
|
||||||
sftp
|
sftp
|
||||||
sftp_nonblock
|
sftp_nonblock
|
||||||
sftpdir
|
sftpdir
|
||||||
|
@@ -10,6 +10,7 @@ noinst_PROGRAMS = ssh2 \
|
|||||||
sftp_RW_nonblock \
|
sftp_RW_nonblock \
|
||||||
sftpdir sftpdir_nonblock
|
sftpdir sftpdir_nonblock
|
||||||
|
|
||||||
INCLUDES = -I. -I$(top_srcdir)/include
|
# the examples need the $(top_builddir)/src since when building outside of the
|
||||||
|
# source dir they still need to reach the libssh2_config.h header
|
||||||
|
AM_CPPFLAGS = -I$(top_srcdir)/src -I$(top_srcdir)/include -I$(top_builddir)/src
|
||||||
LDADD = $(top_builddir)/src/libssh2.la
|
LDADD = $(top_builddir)/src/libssh2.la
|
||||||
|
|
||||||
|
@@ -1,10 +1,10 @@
|
|||||||
/*
|
/*
|
||||||
* $Id: scp.c,v 1.10 2007/08/09 01:10:11 dfandrich Exp $
|
* $Id: scp.c,v 1.11 2008/11/10 16:48:41 bagder Exp $
|
||||||
*
|
*
|
||||||
* Sample showing how to do a simple SCP transfer.
|
* Sample showing how to do a simple SCP transfer.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "config.h"
|
#include "libssh2_config.h"
|
||||||
#include <libssh2.h>
|
#include <libssh2.h>
|
||||||
|
|
||||||
#ifdef HAVE_WINSOCK2_H
|
#ifdef HAVE_WINSOCK2_H
|
||||||
@@ -50,7 +50,7 @@ int main(int argc, char *argv[])
|
|||||||
#ifdef WIN32
|
#ifdef WIN32
|
||||||
WSADATA wsadata;
|
WSADATA wsadata;
|
||||||
|
|
||||||
WSAStartup(WINSOCK_VERSION, &wsadata);
|
WSAStartup(MAKEWORD(2,0), &wsadata);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (argc > 1) {
|
if (argc > 1) {
|
||||||
|
@@ -1,10 +1,10 @@
|
|||||||
/*
|
/*
|
||||||
* $Id: scp_nonblock.c,v 1.11 2007/09/24 12:15:45 bagder Exp $
|
* $Id: scp_nonblock.c,v 1.13 2008/11/10 16:48:41 bagder Exp $
|
||||||
*
|
*
|
||||||
* Sample showing how to do SCP transfers in a non-blocking manner.
|
* Sample showing how to do SCP transfers in a non-blocking manner.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "config.h"
|
#include "libssh2_config.h"
|
||||||
#include <libssh2.h>
|
#include <libssh2.h>
|
||||||
|
|
||||||
#ifdef HAVE_WINSOCK2_H
|
#ifdef HAVE_WINSOCK2_H
|
||||||
@@ -45,12 +45,15 @@ int main(int argc, char *argv[])
|
|||||||
const char *scppath="/tmp/TEST";
|
const char *scppath="/tmp/TEST";
|
||||||
struct stat fileinfo;
|
struct stat fileinfo;
|
||||||
int rc;
|
int rc;
|
||||||
|
#if defined(HAVE_IOCTLSOCKET)
|
||||||
|
long flag = 1;
|
||||||
|
#endif
|
||||||
off_t got=0;
|
off_t got=0;
|
||||||
|
|
||||||
#ifdef WIN32
|
#ifdef WIN32
|
||||||
WSADATA wsadata;
|
WSADATA wsadata;
|
||||||
|
|
||||||
WSAStartup(WINSOCK_VERSION, &wsadata);
|
WSAStartup(MAKEWORD(2,0), &wsadata);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (argc > 1) {
|
if (argc > 1) {
|
||||||
@@ -88,8 +91,15 @@ int main(int argc, char *argv[])
|
|||||||
/* FIXME: this can/should be done in a more portable manner */
|
/* FIXME: this can/should be done in a more portable manner */
|
||||||
rc = fcntl(sock, F_GETFL, 0);
|
rc = fcntl(sock, F_GETFL, 0);
|
||||||
fcntl(sock, F_SETFL, rc | O_NONBLOCK);
|
fcntl(sock, F_SETFL, rc | O_NONBLOCK);
|
||||||
|
#elif defined(HAVE_IOCTLSOCKET)
|
||||||
|
ioctlsocket(sock, FIONBIO, &flag);
|
||||||
|
#else
|
||||||
|
#ifdef WIN32
|
||||||
|
u_long mode = 1;
|
||||||
|
ioctlsocket (sock, FIONBIO, &mode);
|
||||||
#else
|
#else
|
||||||
#error "add support for setting the socket non-blocking here"
|
#error "add support for setting the socket non-blocking here"
|
||||||
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* Create a session instance */
|
/* Create a session instance */
|
||||||
|
@@ -1,10 +1,10 @@
|
|||||||
/*
|
/*
|
||||||
* $Id: scp_write.c,v 1.5 2007/08/09 01:10:11 dfandrich Exp $
|
* $Id: scp_write.c,v 1.6 2008/11/10 16:48:41 bagder Exp $
|
||||||
*
|
*
|
||||||
* Sample showing how to do a simple SCP transfer.
|
* Sample showing how to do a simple SCP transfer.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "config.h"
|
#include "libssh2_config.h"
|
||||||
#include <libssh2.h>
|
#include <libssh2.h>
|
||||||
|
|
||||||
#ifdef HAVE_WINSOCK2_H
|
#ifdef HAVE_WINSOCK2_H
|
||||||
@@ -54,7 +54,7 @@ int main(int argc, char *argv[])
|
|||||||
#ifdef WIN32
|
#ifdef WIN32
|
||||||
WSADATA wsadata;
|
WSADATA wsadata;
|
||||||
|
|
||||||
WSAStartup(WINSOCK_VERSION, &wsadata);
|
WSAStartup(MAKEWORD(2,0), &wsadata);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (argc > 1) {
|
if (argc > 1) {
|
||||||
|
@@ -1,10 +1,10 @@
|
|||||||
/*
|
/*
|
||||||
* $Id: scp_write_nonblock.c,v 1.7 2007/08/09 01:10:11 dfandrich Exp $
|
* $Id: scp_write_nonblock.c,v 1.9 2008/11/10 16:48:41 bagder Exp $
|
||||||
*
|
*
|
||||||
* Sample showing how to do a simple SCP transfer.
|
* Sample showing how to do a simple SCP transfer.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "config.h"
|
#include "libssh2_config.h"
|
||||||
|
|
||||||
#include <libssh2.h>
|
#include <libssh2.h>
|
||||||
|
|
||||||
@@ -47,6 +47,9 @@ int main(int argc, char *argv[])
|
|||||||
const char *scppath="/tmp/TEST";
|
const char *scppath="/tmp/TEST";
|
||||||
FILE *local;
|
FILE *local;
|
||||||
int rc;
|
int rc;
|
||||||
|
#if defined(HAVE_IOCTLSOCKET)
|
||||||
|
long flag = 1;
|
||||||
|
#endif
|
||||||
char mem[1024];
|
char mem[1024];
|
||||||
size_t nread;
|
size_t nread;
|
||||||
char *ptr;
|
char *ptr;
|
||||||
@@ -55,7 +58,7 @@ int main(int argc, char *argv[])
|
|||||||
#ifdef WIN32
|
#ifdef WIN32
|
||||||
WSADATA wsadata;
|
WSADATA wsadata;
|
||||||
|
|
||||||
WSAStartup(WINSOCK_VERSION, &wsadata);
|
WSAStartup(MAKEWORD(2,0), &wsadata);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (argc > 1) {
|
if (argc > 1) {
|
||||||
@@ -105,8 +108,15 @@ int main(int argc, char *argv[])
|
|||||||
/* FIXME: this can/should be done in a more portable manner */
|
/* FIXME: this can/should be done in a more portable manner */
|
||||||
rc = fcntl(sock, F_GETFL, 0);
|
rc = fcntl(sock, F_GETFL, 0);
|
||||||
fcntl(sock, F_SETFL, rc | O_NONBLOCK);
|
fcntl(sock, F_SETFL, rc | O_NONBLOCK);
|
||||||
|
#elif defined(HAVE_IOCTLSOCKET)
|
||||||
|
ioctlsocket(sock, FIONBIO, &flag);
|
||||||
|
#else
|
||||||
|
#ifdef WIN32
|
||||||
|
u_long mode = 1;
|
||||||
|
ioctlsocket (sock, FIONBIO, &mode);
|
||||||
#else
|
#else
|
||||||
#error "add support for setting the socket non-blocking here"
|
#error "add support for setting the socket non-blocking here"
|
||||||
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* Create a session instance
|
/* Create a session instance
|
||||||
|
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* $Id: sftp.c,v 1.14 2007/09/24 12:14:18 bagder Exp $
|
* $Id: sftp.c,v 1.15 2008/11/10 16:48:41 bagder Exp $
|
||||||
*
|
*
|
||||||
* Sample showing how to do SFTP transfers.
|
* Sample showing how to do SFTP transfers.
|
||||||
*
|
*
|
||||||
@@ -9,7 +9,7 @@
|
|||||||
* "sftp 192.168.0.1 user password /tmp/secrets -p|-i|-k"
|
* "sftp 192.168.0.1 user password /tmp/secrets -p|-i|-k"
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "config.h"
|
#include "libssh2_config.h"
|
||||||
#include <libssh2.h>
|
#include <libssh2.h>
|
||||||
#include <libssh2_sftp.h>
|
#include <libssh2_sftp.h>
|
||||||
|
|
||||||
@@ -80,7 +80,7 @@ int main(int argc, char *argv[])
|
|||||||
#ifdef WIN32
|
#ifdef WIN32
|
||||||
WSADATA wsadata;
|
WSADATA wsadata;
|
||||||
|
|
||||||
WSAStartup(WINSOCK_VERSION, &wsadata);
|
WSAStartup(MAKEWORD(2,0), &wsadata);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (argc > 1) {
|
if (argc > 1) {
|
||||||
|
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* $Id: sftp_RW_nonblock.c,v 1.10 2007/08/09 01:10:11 dfandrich Exp $
|
* $Id: sftp_RW_nonblock.c,v 1.12 2008/11/10 16:48:41 bagder Exp $
|
||||||
*
|
*
|
||||||
* Sample showing how to do SFTP transfers in a non-blocking manner.
|
* Sample showing how to do SFTP transfers in a non-blocking manner.
|
||||||
*
|
*
|
||||||
@@ -9,7 +9,7 @@
|
|||||||
* Using the SFTP server running on 127.0.0.1
|
* Using the SFTP server running on 127.0.0.1
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "config.h"
|
#include "libssh2_config.h"
|
||||||
#include <libssh2.h>
|
#include <libssh2.h>
|
||||||
#include <libssh2_sftp.h>
|
#include <libssh2_sftp.h>
|
||||||
|
|
||||||
@@ -53,6 +53,9 @@ int main(int argc, char *argv[])
|
|||||||
const char *sftppath="/tmp/TEST"; /* source path */
|
const char *sftppath="/tmp/TEST"; /* source path */
|
||||||
const char *dest="/tmp/TEST2"; /* destination path */
|
const char *dest="/tmp/TEST2"; /* destination path */
|
||||||
int rc;
|
int rc;
|
||||||
|
#if defined(HAVE_IOCTLSOCKET)
|
||||||
|
long flag = 1;
|
||||||
|
#endif
|
||||||
LIBSSH2_SFTP *sftp_session;
|
LIBSSH2_SFTP *sftp_session;
|
||||||
LIBSSH2_SFTP_HANDLE *sftp_handle;
|
LIBSSH2_SFTP_HANDLE *sftp_handle;
|
||||||
FILE *tempstorage;
|
FILE *tempstorage;
|
||||||
@@ -63,7 +66,7 @@ int main(int argc, char *argv[])
|
|||||||
#ifdef WIN32
|
#ifdef WIN32
|
||||||
WSADATA wsadata;
|
WSADATA wsadata;
|
||||||
|
|
||||||
WSAStartup(WINSOCK_VERSION, &wsadata);
|
WSAStartup(MAKEWORD(2,0), &wsadata);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* Ultra basic "connect to port 22 on localhost"
|
/* Ultra basic "connect to port 22 on localhost"
|
||||||
@@ -87,8 +90,15 @@ int main(int argc, char *argv[])
|
|||||||
/* FIXME: this can/should be done in a more portable manner */
|
/* FIXME: this can/should be done in a more portable manner */
|
||||||
rc = fcntl(sock, F_GETFL, 0);
|
rc = fcntl(sock, F_GETFL, 0);
|
||||||
fcntl(sock, F_SETFL, rc | O_NONBLOCK);
|
fcntl(sock, F_SETFL, rc | O_NONBLOCK);
|
||||||
|
#elif defined(HAVE_IOCTLSOCKET)
|
||||||
|
ioctlsocket(sock, FIONBIO, &flag);
|
||||||
|
#else
|
||||||
|
#ifdef WIN32
|
||||||
|
u_long mode = 1;
|
||||||
|
ioctlsocket (sock, FIONBIO, &mode);
|
||||||
#else
|
#else
|
||||||
#error "add support for setting the socket non-blocking here"
|
#error "add support for setting the socket non-blocking here"
|
||||||
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* Create a session instance
|
/* Create a session instance
|
||||||
|
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* $Id: sftp_mkdir.c,v 1.7 2007/08/09 01:10:11 dfandrich Exp $
|
* $Id: sftp_mkdir.c,v 1.8 2008/11/10 16:48:41 bagder Exp $
|
||||||
*
|
*
|
||||||
* Sample showing how to do SFTP mkdir
|
* Sample showing how to do SFTP mkdir
|
||||||
*
|
*
|
||||||
@@ -9,7 +9,7 @@
|
|||||||
* "sftp 192.168.0.1 user password /tmp/sftp_mkdir"
|
* "sftp 192.168.0.1 user password /tmp/sftp_mkdir"
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "config.h"
|
#include "libssh2_config.h"
|
||||||
#include <libssh2.h>
|
#include <libssh2.h>
|
||||||
#include <libssh2_sftp.h>
|
#include <libssh2_sftp.h>
|
||||||
|
|
||||||
@@ -51,7 +51,7 @@ int main(int argc, char *argv[])
|
|||||||
#ifdef WIN32
|
#ifdef WIN32
|
||||||
WSADATA wsadata;
|
WSADATA wsadata;
|
||||||
|
|
||||||
WSAStartup(WINSOCK_VERSION, &wsadata);
|
WSAStartup(MAKEWORD(2,0), &wsadata);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (argc > 1) {
|
if (argc > 1) {
|
||||||
|
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* $Id: sftp_mkdir_nonblock.c,v 1.9 2007/08/09 01:10:11 dfandrich Exp $
|
* $Id: sftp_mkdir_nonblock.c,v 1.11 2008/11/10 16:48:41 bagder Exp $
|
||||||
*
|
*
|
||||||
* Sample showing how to do SFTP non-blocking mkdir.
|
* Sample showing how to do SFTP non-blocking mkdir.
|
||||||
*
|
*
|
||||||
@@ -9,7 +9,7 @@
|
|||||||
* "sftp 192.168.0.1 user password /tmp/sftp_write_nonblock.c"
|
* "sftp 192.168.0.1 user password /tmp/sftp_write_nonblock.c"
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "config.h"
|
#include "libssh2_config.h"
|
||||||
#include <libssh2.h>
|
#include <libssh2.h>
|
||||||
#include <libssh2_sftp.h>
|
#include <libssh2_sftp.h>
|
||||||
|
|
||||||
@@ -46,12 +46,15 @@ int main(int argc, char *argv[])
|
|||||||
const char *password="password";
|
const char *password="password";
|
||||||
const char *sftppath="/tmp/sftp_mkdir_nonblock";
|
const char *sftppath="/tmp/sftp_mkdir_nonblock";
|
||||||
int rc;
|
int rc;
|
||||||
|
#if defined(HAVE_IOCTLSOCKET)
|
||||||
|
long flag = 1;
|
||||||
|
#endif
|
||||||
LIBSSH2_SFTP *sftp_session;
|
LIBSSH2_SFTP *sftp_session;
|
||||||
|
|
||||||
#ifdef WIN32
|
#ifdef WIN32
|
||||||
WSADATA wsadata;
|
WSADATA wsadata;
|
||||||
|
|
||||||
WSAStartup(WINSOCK_VERSION, &wsadata);
|
WSAStartup(MAKEWORD(2,0), &wsadata);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (argc > 1) {
|
if (argc > 1) {
|
||||||
@@ -91,8 +94,15 @@ int main(int argc, char *argv[])
|
|||||||
/* FIXME: this can/should be done in a more portable manner */
|
/* FIXME: this can/should be done in a more portable manner */
|
||||||
rc = fcntl(sock, F_GETFL, 0);
|
rc = fcntl(sock, F_GETFL, 0);
|
||||||
fcntl(sock, F_SETFL, rc | O_NONBLOCK);
|
fcntl(sock, F_SETFL, rc | O_NONBLOCK);
|
||||||
|
#elif defined(HAVE_IOCTLSOCKET)
|
||||||
|
ioctlsocket(sock, FIONBIO, &flag);
|
||||||
|
#else
|
||||||
|
#ifdef WIN32
|
||||||
|
u_long mode = 1;
|
||||||
|
ioctlsocket (sock, FIONBIO, &mode);
|
||||||
#else
|
#else
|
||||||
#error "add support for setting the socket non-blocking here"
|
#error "add support for setting the socket non-blocking here"
|
||||||
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* Create a session instance
|
/* Create a session instance
|
||||||
|
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* $Id: sftp_nonblock.c,v 1.13 2007/08/09 01:10:11 dfandrich Exp $
|
* $Id: sftp_nonblock.c,v 1.15 2008/11/10 16:48:41 bagder Exp $
|
||||||
*
|
*
|
||||||
* Sample showing how to do SFTP non-blocking transfers.
|
* Sample showing how to do SFTP non-blocking transfers.
|
||||||
*
|
*
|
||||||
@@ -9,7 +9,7 @@
|
|||||||
* "sftp 192.168.0.1 user password /tmp/secrets"
|
* "sftp 192.168.0.1 user password /tmp/secrets"
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "config.h"
|
#include "libssh2_config.h"
|
||||||
#include <libssh2.h>
|
#include <libssh2.h>
|
||||||
#include <libssh2_sftp.h>
|
#include <libssh2_sftp.h>
|
||||||
|
|
||||||
@@ -49,13 +49,16 @@ int main(int argc, char *argv[])
|
|||||||
const char *password="password";
|
const char *password="password";
|
||||||
const char *sftppath="/tmp/TEST";
|
const char *sftppath="/tmp/TEST";
|
||||||
int rc;
|
int rc;
|
||||||
|
#if defined(HAVE_IOCTLSOCKET)
|
||||||
|
long flag = 1;
|
||||||
|
#endif
|
||||||
LIBSSH2_SFTP *sftp_session;
|
LIBSSH2_SFTP *sftp_session;
|
||||||
LIBSSH2_SFTP_HANDLE *sftp_handle;
|
LIBSSH2_SFTP_HANDLE *sftp_handle;
|
||||||
|
|
||||||
#ifdef WIN32
|
#ifdef WIN32
|
||||||
WSADATA wsadata;
|
WSADATA wsadata;
|
||||||
|
|
||||||
WSAStartup(WINSOCK_VERSION, &wsadata);
|
WSAStartup(MAKEWORD(2,0), &wsadata);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (argc > 1) {
|
if (argc > 1) {
|
||||||
@@ -94,8 +97,15 @@ int main(int argc, char *argv[])
|
|||||||
/* FIXME: this can/should be done in a more portable manner */
|
/* FIXME: this can/should be done in a more portable manner */
|
||||||
rc = fcntl(sock, F_GETFL, 0);
|
rc = fcntl(sock, F_GETFL, 0);
|
||||||
fcntl(sock, F_SETFL, rc | O_NONBLOCK);
|
fcntl(sock, F_SETFL, rc | O_NONBLOCK);
|
||||||
|
#elif defined(HAVE_IOCTLSOCKET)
|
||||||
|
ioctlsocket(sock, FIONBIO, &flag);
|
||||||
|
#else
|
||||||
|
#ifdef WIN32
|
||||||
|
u_long mode = 1;
|
||||||
|
ioctlsocket (sock, FIONBIO, &mode);
|
||||||
#else
|
#else
|
||||||
#error "add support for setting the socket non-blocking here"
|
#error "add support for setting the socket non-blocking here"
|
||||||
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* Create a session instance */
|
/* Create a session instance */
|
||||||
|
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* $Id: sftp_write.c,v 1.8 2007/08/09 01:10:11 dfandrich Exp $
|
* $Id: sftp_write.c,v 1.9 2008/11/10 16:48:41 bagder Exp $
|
||||||
*
|
*
|
||||||
* Sample showing how to do SFTP write transfers.
|
* Sample showing how to do SFTP write transfers.
|
||||||
*
|
*
|
||||||
@@ -9,7 +9,7 @@
|
|||||||
* "sftp 192.168.0.1 user password sftp_write.c /tmp/secrets"
|
* "sftp 192.168.0.1 user password sftp_write.c /tmp/secrets"
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "config.h"
|
#include "libssh2_config.h"
|
||||||
#include <libssh2.h>
|
#include <libssh2.h>
|
||||||
#include <libssh2_sftp.h>
|
#include <libssh2_sftp.h>
|
||||||
|
|
||||||
@@ -57,7 +57,7 @@ int main(int argc, char *argv[])
|
|||||||
#ifdef WIN32
|
#ifdef WIN32
|
||||||
WSADATA wsadata;
|
WSADATA wsadata;
|
||||||
|
|
||||||
WSAStartup(WINSOCK_VERSION, &wsadata);
|
WSAStartup(MAKEWORD(2,0), &wsadata);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (argc > 1) {
|
if (argc > 1) {
|
||||||
|
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* $Id: sftp_write_nonblock.c,v 1.10 2007/08/09 01:10:11 dfandrich Exp $
|
* $Id: sftp_write_nonblock.c,v 1.12 2008/11/10 16:48:41 bagder Exp $
|
||||||
*
|
*
|
||||||
* Sample showing how to do SFTP non-blocking write transfers.
|
* Sample showing how to do SFTP non-blocking write transfers.
|
||||||
*
|
*
|
||||||
@@ -9,7 +9,7 @@
|
|||||||
* "sftp 192.168.0.1 user password sftp_write_nonblock.c /tmp/sftp_write_nonblock.c"
|
* "sftp 192.168.0.1 user password sftp_write_nonblock.c /tmp/sftp_write_nonblock.c"
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "config.h"
|
#include "libssh2_config.h"
|
||||||
#include <libssh2.h>
|
#include <libssh2.h>
|
||||||
#include <libssh2_sftp.h>
|
#include <libssh2_sftp.h>
|
||||||
|
|
||||||
@@ -47,6 +47,9 @@ int main(int argc, char *argv[])
|
|||||||
const char *loclfile="sftp_write_nonblock.c";
|
const char *loclfile="sftp_write_nonblock.c";
|
||||||
const char *sftppath="/tmp/sftp_write_nonblock.c";
|
const char *sftppath="/tmp/sftp_write_nonblock.c";
|
||||||
int rc;
|
int rc;
|
||||||
|
#if defined(HAVE_IOCTLSOCKET)
|
||||||
|
long flag = 1;
|
||||||
|
#endif
|
||||||
FILE *local;
|
FILE *local;
|
||||||
LIBSSH2_SFTP *sftp_session;
|
LIBSSH2_SFTP *sftp_session;
|
||||||
LIBSSH2_SFTP_HANDLE *sftp_handle;
|
LIBSSH2_SFTP_HANDLE *sftp_handle;
|
||||||
@@ -57,7 +60,7 @@ int main(int argc, char *argv[])
|
|||||||
#ifdef WIN32
|
#ifdef WIN32
|
||||||
WSADATA wsadata;
|
WSADATA wsadata;
|
||||||
|
|
||||||
WSAStartup(WINSOCK_VERSION, &wsadata);
|
WSAStartup(MAKEWORD(2,0), &wsadata);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (argc > 1) {
|
if (argc > 1) {
|
||||||
@@ -106,8 +109,15 @@ int main(int argc, char *argv[])
|
|||||||
/* FIXME: this can/should be done in a more portable manner */
|
/* FIXME: this can/should be done in a more portable manner */
|
||||||
rc = fcntl(sock, F_GETFL, 0);
|
rc = fcntl(sock, F_GETFL, 0);
|
||||||
fcntl(sock, F_SETFL, rc | O_NONBLOCK);
|
fcntl(sock, F_SETFL, rc | O_NONBLOCK);
|
||||||
|
#elif defined(HAVE_IOCTLSOCKET)
|
||||||
|
ioctlsocket(sock, FIONBIO, &flag);
|
||||||
|
#else
|
||||||
|
#ifdef WIN32
|
||||||
|
u_long mode = 1;
|
||||||
|
ioctlsocket (sock, FIONBIO, &mode);
|
||||||
#else
|
#else
|
||||||
#error "add support for setting the socket non-blocking here"
|
#error "add support for setting the socket non-blocking here"
|
||||||
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* Create a session instance
|
/* Create a session instance
|
||||||
|
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* $Id: sftpdir.c,v 1.9 2007/08/09 01:10:11 dfandrich Exp $
|
* $Id: sftpdir.c,v 1.10 2008/11/10 16:48:41 bagder Exp $
|
||||||
*
|
*
|
||||||
* Sample doing an SFTP directory listing.
|
* Sample doing an SFTP directory listing.
|
||||||
*
|
*
|
||||||
@@ -9,7 +9,7 @@
|
|||||||
* "sftpdir 192.168.0.1 user password /tmp/secretdir"
|
* "sftpdir 192.168.0.1 user password /tmp/secretdir"
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "config.h"
|
#include "libssh2_config.h"
|
||||||
#include <libssh2.h>
|
#include <libssh2.h>
|
||||||
#include <libssh2_sftp.h>
|
#include <libssh2_sftp.h>
|
||||||
|
|
||||||
@@ -52,7 +52,7 @@ int main(int argc, char *argv[])
|
|||||||
#ifdef WIN32
|
#ifdef WIN32
|
||||||
WSADATA wsadata;
|
WSADATA wsadata;
|
||||||
|
|
||||||
WSAStartup(WINSOCK_VERSION, &wsadata);
|
WSAStartup(MAKEWORD(2,0), &wsadata);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (argc > 1) {
|
if (argc > 1) {
|
||||||
|
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* $Id: sftpdir_nonblock.c,v 1.10 2007/08/09 01:10:11 dfandrich Exp $
|
* $Id: sftpdir_nonblock.c,v 1.12 2008/11/10 16:48:41 bagder Exp $
|
||||||
*
|
*
|
||||||
* Sample doing an SFTP directory listing.
|
* Sample doing an SFTP directory listing.
|
||||||
*
|
*
|
||||||
@@ -9,7 +9,7 @@
|
|||||||
* "sftpdir 192.168.0.1 user password /tmp/secretdir"
|
* "sftpdir 192.168.0.1 user password /tmp/secretdir"
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "config.h"
|
#include "libssh2_config.h"
|
||||||
#include <libssh2.h>
|
#include <libssh2.h>
|
||||||
#include <libssh2_sftp.h>
|
#include <libssh2_sftp.h>
|
||||||
|
|
||||||
@@ -46,13 +46,16 @@ int main(int argc, char *argv[])
|
|||||||
const char *password="password";
|
const char *password="password";
|
||||||
const char *sftppath="/tmp/secretdir";
|
const char *sftppath="/tmp/secretdir";
|
||||||
int rc;
|
int rc;
|
||||||
|
#if defined(HAVE_IOCTLSOCKET)
|
||||||
|
long flag = 1;
|
||||||
|
#endif
|
||||||
LIBSSH2_SFTP *sftp_session;
|
LIBSSH2_SFTP *sftp_session;
|
||||||
LIBSSH2_SFTP_HANDLE *sftp_handle;
|
LIBSSH2_SFTP_HANDLE *sftp_handle;
|
||||||
|
|
||||||
#ifdef WIN32
|
#ifdef WIN32
|
||||||
WSADATA wsadata;
|
WSADATA wsadata;
|
||||||
|
|
||||||
WSAStartup(WINSOCK_VERSION, &wsadata);
|
WSAStartup(MAKEWORD(2,0), &wsadata);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (argc > 1) {
|
if (argc > 1) {
|
||||||
@@ -91,8 +94,15 @@ int main(int argc, char *argv[])
|
|||||||
/* FIXME: this can/should be done in a more portable manner */
|
/* FIXME: this can/should be done in a more portable manner */
|
||||||
rc = fcntl(sock, F_GETFL, 0);
|
rc = fcntl(sock, F_GETFL, 0);
|
||||||
fcntl(sock, F_SETFL, rc | O_NONBLOCK);
|
fcntl(sock, F_SETFL, rc | O_NONBLOCK);
|
||||||
|
#elif defined(HAVE_IOCTLSOCKET)
|
||||||
|
ioctlsocket(sock, FIONBIO, &flag);
|
||||||
|
#else
|
||||||
|
#ifdef WIN32
|
||||||
|
u_long mode = 1;
|
||||||
|
ioctlsocket (sock, FIONBIO, &mode);
|
||||||
#else
|
#else
|
||||||
#error "add support for setting the socket non-blocking here"
|
#error "add support for setting the socket non-blocking here"
|
||||||
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* Create a session instance
|
/* Create a session instance
|
||||||
|
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* $Id: ssh2.c,v 1.17 2007/08/09 01:10:11 dfandrich Exp $
|
* $Id: ssh2.c,v 1.18 2008/11/10 16:48:41 bagder Exp $
|
||||||
*
|
*
|
||||||
* Sample showing how to do SSH2 connect.
|
* Sample showing how to do SSH2 connect.
|
||||||
*
|
*
|
||||||
@@ -9,10 +9,13 @@
|
|||||||
* "ssh2 host user password [-p|-i|-k]"
|
* "ssh2 host user password [-p|-i|-k]"
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "config.h"
|
#include "libssh2_config.h"
|
||||||
#include <libssh2.h>
|
#include <libssh2.h>
|
||||||
#include <libssh2_sftp.h>
|
#include <libssh2_sftp.h>
|
||||||
|
|
||||||
|
#ifdef HAVE_WINDOWS_H
|
||||||
|
# include <windows.h>
|
||||||
|
#endif
|
||||||
#ifdef HAVE_WINSOCK2_H
|
#ifdef HAVE_WINSOCK2_H
|
||||||
# include <winsock2.h>
|
# include <winsock2.h>
|
||||||
#endif
|
#endif
|
||||||
@@ -73,7 +76,7 @@ int main(int argc, char *argv[])
|
|||||||
#ifdef WIN32
|
#ifdef WIN32
|
||||||
WSADATA wsadata;
|
WSADATA wsadata;
|
||||||
|
|
||||||
WSAStartup(WINSOCK_VERSION, &wsadata);
|
WSAStartup(MAKEWORD(2,0), &wsadata);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (argc > 1) {
|
if (argc > 1) {
|
||||||
|
@@ -1,4 +1,4 @@
|
|||||||
/* Copyright (c) 2004-2007, Sara Golemon <sarag@libssh2.org>
|
/* Copyright (c) 2004-2008, Sara Golemon <sarag@libssh2.org>
|
||||||
* All rights reserved.
|
* All rights reserved.
|
||||||
*
|
*
|
||||||
* Redistribution and use in source and binary forms,
|
* Redistribution and use in source and binary forms,
|
||||||
@@ -82,12 +82,16 @@ typedef unsigned long long libssh2_uint64_t;
|
|||||||
typedef long long libssh2_int64_t;
|
typedef long long libssh2_int64_t;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#define LIBSSH2_VERSION "0.18.0-CVS"
|
/* We use underscore instead of dash when appending CVS in dev versions just
|
||||||
|
to make the BANNER define (used by src/session.c) be a valid SSH
|
||||||
|
banner. Release versions have no appended strings and may of coruse not
|
||||||
|
have dashes either. */
|
||||||
|
#define LIBSSH2_VERSION "1.0.0_CVS"
|
||||||
|
|
||||||
/* The numeric version number is also available "in parts" by using these
|
/* The numeric version number is also available "in parts" by using these
|
||||||
defines: */
|
defines: */
|
||||||
#define LIBSSH2_VERSION_MAJOR 0
|
#define LIBSSH2_VERSION_MAJOR 1
|
||||||
#define LIBSSH2_VERSION_MINOR 18
|
#define LIBSSH2_VERSION_MINOR 0
|
||||||
#define LIBSSH2_VERSION_PATCH 0
|
#define LIBSSH2_VERSION_PATCH 0
|
||||||
|
|
||||||
/* This is the numeric version of the libssh2 version number, meant for easier
|
/* This is the numeric version of the libssh2 version number, meant for easier
|
||||||
@@ -105,7 +109,7 @@ typedef long long libssh2_int64_t;
|
|||||||
and it is always a greater number in a more recent release. It makes
|
and it is always a greater number in a more recent release. It makes
|
||||||
comparisons with greater than and less than work.
|
comparisons with greater than and less than work.
|
||||||
*/
|
*/
|
||||||
#define LIBSSH2_VERSION_NUM 0x001200
|
#define LIBSSH2_VERSION_NUM 0x010000
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* This is the date and time when the full source package was created. The
|
* This is the date and time when the full source package was created. The
|
||||||
@@ -240,6 +244,11 @@ typedef struct _LIBSSH2_POLLFD {
|
|||||||
#define LIBSSH2_POLLFD_CHANNEL_CLOSED 0x0080 /* Channel Disconnect */
|
#define LIBSSH2_POLLFD_CHANNEL_CLOSED 0x0080 /* Channel Disconnect */
|
||||||
#define LIBSSH2_POLLFD_LISTENER_CLOSED 0x0080 /* Listener Disconnect */
|
#define LIBSSH2_POLLFD_LISTENER_CLOSED 0x0080 /* Listener Disconnect */
|
||||||
|
|
||||||
|
#define HAVE_LIBSSH2_SESSION_BLOCK_DIRECTION
|
||||||
|
/* Block Direction Types */
|
||||||
|
#define LIBSSH2_SESSION_BLOCK_INBOUND 0x0001
|
||||||
|
#define LIBSSH2_SESSION_BLOCK_OUTBOUND 0x0002
|
||||||
|
|
||||||
/* Hash Types */
|
/* Hash Types */
|
||||||
#define LIBSSH2_HOSTKEY_HASH_MD5 1
|
#define LIBSSH2_HOSTKEY_HASH_MD5 1
|
||||||
#define LIBSSH2_HOSTKEY_HASH_SHA1 2
|
#define LIBSSH2_HOSTKEY_HASH_SHA1 2
|
||||||
@@ -320,6 +329,7 @@ LIBSSH2_API int libssh2_session_method_pref(LIBSSH2_SESSION *session, int method
|
|||||||
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);
|
||||||
LIBSSH2_API int libssh2_session_last_error(LIBSSH2_SESSION *session, char **errmsg, int *errmsg_len, int want_buf);
|
LIBSSH2_API int libssh2_session_last_error(LIBSSH2_SESSION *session, char **errmsg, int *errmsg_len, int want_buf);
|
||||||
LIBSSH2_API int libssh2_session_last_errno(LIBSSH2_SESSION *session);
|
LIBSSH2_API int libssh2_session_last_errno(LIBSSH2_SESSION *session);
|
||||||
|
LIBSSH2_API int libssh2_session_block_directions(LIBSSH2_SESSION *session);
|
||||||
|
|
||||||
LIBSSH2_API int libssh2_session_flag(LIBSSH2_SESSION *session, int flag, int value);
|
LIBSSH2_API int libssh2_session_flag(LIBSSH2_SESSION *session, int flag, int value);
|
||||||
|
|
||||||
@@ -389,6 +399,9 @@ LIBSSH2_API int libssh2_channel_setenv_ex(LIBSSH2_CHANNEL *channel, const char *
|
|||||||
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);
|
LIBSSH2_API int libssh2_channel_request_pty_ex(LIBSSH2_CHANNEL *channel, const char *term, unsigned int term_len, const char *modes, unsigned int modes_len, int width, int height, int width_px, int height_px);
|
||||||
#define libssh2_channel_request_pty(channel, term) libssh2_channel_request_pty_ex((channel), (term), strlen(term), NULL, 0, LIBSSH2_TERM_WIDTH, LIBSSH2_TERM_HEIGHT, LIBSSH2_TERM_WIDTH_PX, LIBSSH2_TERM_HEIGHT_PX)
|
#define libssh2_channel_request_pty(channel, term) libssh2_channel_request_pty_ex((channel), (term), strlen(term), NULL, 0, LIBSSH2_TERM_WIDTH, LIBSSH2_TERM_HEIGHT, LIBSSH2_TERM_WIDTH_PX, LIBSSH2_TERM_HEIGHT_PX)
|
||||||
|
|
||||||
|
LIBSSH2_API int libssh2_channel_request_pty_size_ex(LIBSSH2_CHANNEL * channel, int width, int height, int width_px, int height_px);
|
||||||
|
#define libssh2_channel_request_pty_size(channel, width, height) libssh2_channel_request_pty_size_ex( (channel), (width), (height), 0, 0)
|
||||||
|
|
||||||
LIBSSH2_API int libssh2_channel_x11_req_ex(LIBSSH2_CHANNEL *channel, int single_connection, const char *auth_proto, const char *auth_cookie, int screen_number);
|
LIBSSH2_API int libssh2_channel_x11_req_ex(LIBSSH2_CHANNEL *channel, int single_connection, const char *auth_proto, const char *auth_cookie, int screen_number);
|
||||||
#define libssh2_channel_x11_req(channel, screen_number) libssh2_channel_x11_req_ex((channel), 0, NULL, NULL, (screen_number))
|
#define libssh2_channel_x11_req(channel, screen_number) libssh2_channel_x11_req_ex((channel), 0, NULL, NULL, (screen_number))
|
||||||
|
|
||||||
|
@@ -1,4 +1,4 @@
|
|||||||
/* Copyright (c) 2004-2007, Sara Golemon <sarag@libssh2.org>
|
/* Copyright (c) 2004-2008, Sara Golemon <sarag@libssh2.org>
|
||||||
* All rights reserved.
|
* All rights reserved.
|
||||||
*
|
*
|
||||||
* Redistribution and use in source and binary forms,
|
* Redistribution and use in source and binary forms,
|
||||||
@@ -206,9 +206,11 @@ LIBSSH2_API int libssh2_sftp_close_handle(LIBSSH2_SFTP_HANDLE *handle);
|
|||||||
#define libssh2_sftp_closedir(handle) libssh2_sftp_close_handle(handle)
|
#define libssh2_sftp_closedir(handle) libssh2_sftp_close_handle(handle)
|
||||||
|
|
||||||
LIBSSH2_API void libssh2_sftp_seek(LIBSSH2_SFTP_HANDLE *handle, size_t offset);
|
LIBSSH2_API void libssh2_sftp_seek(LIBSSH2_SFTP_HANDLE *handle, size_t offset);
|
||||||
#define libssh2_sftp_rewind(handle) libssh2_sftp_seek((handle), 0)
|
LIBSSH2_API void libssh2_sftp_seek64(LIBSSH2_SFTP_HANDLE *handle, libssh2_uint64_t offset);
|
||||||
|
#define libssh2_sftp_rewind(handle) libssh2_sftp_seek64((handle), 0)
|
||||||
|
|
||||||
LIBSSH2_API size_t libssh2_sftp_tell(LIBSSH2_SFTP_HANDLE *handle);
|
LIBSSH2_API size_t libssh2_sftp_tell(LIBSSH2_SFTP_HANDLE *handle);
|
||||||
|
LIBSSH2_API libssh2_uint64_t libssh2_sftp_tell64(LIBSSH2_SFTP_HANDLE *handle);
|
||||||
|
|
||||||
LIBSSH2_API int libssh2_sftp_fstat_ex(LIBSSH2_SFTP_HANDLE *handle, LIBSSH2_SFTP_ATTRIBUTES *attrs, int setstat);
|
LIBSSH2_API int libssh2_sftp_fstat_ex(LIBSSH2_SFTP_HANDLE *handle, LIBSSH2_SFTP_ATTRIBUTES *attrs, int setstat);
|
||||||
#define libssh2_sftp_fstat(handle, attrs) libssh2_sftp_fstat_ex((handle), (attrs), 0)
|
#define libssh2_sftp_fstat(handle, attrs) libssh2_sftp_fstat_ex((handle), (attrs), 0)
|
||||||
|
51
libssh2-style.el
Normal file
51
libssh2-style.el
Normal file
@@ -0,0 +1,51 @@
|
|||||||
|
;;;; Emacs Lisp help for writing libssh2 code. ;;;;
|
||||||
|
;;;; $Id: libssh2-style.el,v 1.1 2008/12/20 12:36:50 bagder Exp $
|
||||||
|
|
||||||
|
;;; The libssh2 hacker's C conventions.
|
||||||
|
;;; See the sample.emacs file on how this file can be made to take
|
||||||
|
;;; effect automatically when editing libssh2 source files.
|
||||||
|
|
||||||
|
(defconst libssh2-c-style
|
||||||
|
'((c-basic-offset . 4)
|
||||||
|
(c-comment-only-line-offset . 0)
|
||||||
|
(c-hanging-braces-alist . ((substatement-open before after)))
|
||||||
|
(c-offsets-alist . ((topmost-intro . 0)
|
||||||
|
(topmost-intro-cont . 0)
|
||||||
|
(substatement . +)
|
||||||
|
(substatement-open . 0)
|
||||||
|
(statement-case-intro . +)
|
||||||
|
(statement-case-open . 0)
|
||||||
|
(case-label . 0)
|
||||||
|
))
|
||||||
|
)
|
||||||
|
"Libssh2 C Programming Style")
|
||||||
|
|
||||||
|
(defun libssh2-code-cleanup ()
|
||||||
|
"tabify and delete trailing whitespace"
|
||||||
|
(interactive)
|
||||||
|
(untabify (point-min) (point-max))
|
||||||
|
(delete-trailing-whitespace)
|
||||||
|
)
|
||||||
|
|
||||||
|
;; Customizations for all of c-mode, c++-mode, and objc-mode
|
||||||
|
(defun libssh2-c-mode-common-hook ()
|
||||||
|
"Libssh2 C mode hook"
|
||||||
|
;; add libssh2 style and set it for the current buffer
|
||||||
|
(c-add-style "libssh2" libssh2-c-style t)
|
||||||
|
(setq tab-width 8
|
||||||
|
indent-tabs-mode nil ; Use spaces, not tabs.
|
||||||
|
comment-column 40
|
||||||
|
c-font-lock-extra-types (append '("libssh2_int64_t" "LIBSSH2_USERAUTH_KBDINT_PROMPT" "LIBSSH2_SESSION" "LIBSSH2_CHANNEL" "ssize_t" "size_t" "uint32_t" "LIBSSH2_LISTENER" "LIBSSH2_POLLFD"))
|
||||||
|
)
|
||||||
|
;; keybindings for C, C++, and Objective-C. We can put these in
|
||||||
|
;; c-mode-base-map because of inheritance ...
|
||||||
|
(define-key c-mode-base-map "\M-q" 'c-fill-paragraph)
|
||||||
|
(define-key c-mode-base-map "\M-m" 'libssh2-code-cleanup)
|
||||||
|
(setq c-recognize-knr-p nil)
|
||||||
|
;;; (add-hook 'write-file-hooks 'delete-trailing-whitespace t)
|
||||||
|
(setq show-trailing-whitespace t)
|
||||||
|
)
|
||||||
|
|
||||||
|
;; Set this is in your .emacs if you want to use the c-mode-hook as
|
||||||
|
;; defined here right out of the box.
|
||||||
|
; (add-hook 'c-mode-common-hook 'libssh2-c-mode-common-hook)
|
5
m4/.cvsignore
Normal file
5
m4/.cvsignore
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
libtool.m4
|
||||||
|
ltoptions.m4
|
||||||
|
ltsugar.m4
|
||||||
|
ltversion.m4
|
||||||
|
lt~obsolete.m4
|
@@ -5,6 +5,8 @@
|
|||||||
*.dll
|
*.dll
|
||||||
*.exe
|
*.exe
|
||||||
*.obj
|
*.obj
|
||||||
|
*.gcno
|
||||||
|
*.gcda
|
||||||
.*.swp
|
.*.swp
|
||||||
Debug
|
Debug
|
||||||
Release
|
Release
|
||||||
|
@@ -1,12 +1,12 @@
|
|||||||
# $Id: Makefile.am,v 1.10 2007/07/17 13:22:55 gknauf Exp $
|
# $Id: Makefile.am,v 1.13 2008/11/21 14:34:03 jas4711 Exp $
|
||||||
AUTOMAKE_OPTIONS = foreign nostdinc
|
AUTOMAKE_OPTIONS = foreign nostdinc
|
||||||
|
|
||||||
libssh2_la_SOURCES = channel.c comp.c crypt.c hostkey.c kex.c mac.c \
|
libssh2_la_SOURCES = channel.c comp.c crypt.c hostkey.c kex.c mac.c \
|
||||||
misc.c packet.c publickey.c scp.c session.c sftp.c userauth.c \
|
misc.c packet.c publickey.c scp.c session.c sftp.c userauth.c \
|
||||||
libssh2_priv.h openssl.h libgcrypt.h pem.c transport.c
|
libssh2_priv.h openssl.h libgcrypt.h transport.c
|
||||||
|
|
||||||
if LIBGCRYPT
|
if LIBGCRYPT
|
||||||
libssh2_la_SOURCES += libgcrypt.c
|
libssh2_la_SOURCES += libgcrypt.c pem.c
|
||||||
else
|
else
|
||||||
libssh2_la_SOURCES += openssl.c
|
libssh2_la_SOURCES += openssl.c
|
||||||
endif
|
endif
|
||||||
@@ -18,7 +18,7 @@ lib_LTLIBRARIES = libssh2.la
|
|||||||
# srcdir/include for the shipped headers
|
# srcdir/include for the shipped headers
|
||||||
# builddir/src for the generated config header when building out of the source
|
# builddir/src for the generated config header when building out of the source
|
||||||
# tree
|
# tree
|
||||||
INCLUDES = -I$(top_srcdir)/include -I$(top_builddir)/src
|
AM_CPPFLAGS = -I$(top_srcdir)/include -I$(top_builddir)/src
|
||||||
|
|
||||||
VERSION=-version-info 1:0:0
|
VERSION=-version-info 1:0:0
|
||||||
|
|
||||||
@@ -50,4 +50,5 @@ VERSION=-version-info 1:0:0
|
|||||||
# set age to 0. (c:r:a=0)
|
# set age to 0. (c:r:a=0)
|
||||||
#
|
#
|
||||||
|
|
||||||
libssh2_la_LDFLAGS = $(VERSION) -no-undefined $(LTLIBGCRYPT)
|
libssh2_la_LDFLAGS = $(VERSION) -no-undefined \
|
||||||
|
$(LTLIBGCRYPT) $(LTLIBSSL) $(LTLIBZ)
|
||||||
|
244
src/channel.c
244
src/channel.c
@@ -1,4 +1,6 @@
|
|||||||
/* Copyright (c) 2004-2007, Sara Golemon <sarag@libssh2.org>
|
/* Copyright (c) 2004-2007, Sara Golemon <sarag@libssh2.org>
|
||||||
|
* Copyright (c) 2008 by Daniel Stenberg
|
||||||
|
*
|
||||||
* All rights reserved.
|
* All rights reserved.
|
||||||
*
|
*
|
||||||
* Redistribution and use in source and binary forms,
|
* Redistribution and use in source and binary forms,
|
||||||
@@ -63,10 +65,12 @@ libssh2_channel_nextid(LIBSSH2_SESSION * session)
|
|||||||
channel = channel->next;
|
channel = channel->next;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* This is a shortcut to avoid waiting for close packets on channels we've forgotten about,
|
/* This is a shortcut to avoid waiting for close packets on channels we've
|
||||||
* This *could* be a problem if we request and close 4 billion or so channels in too rapid succession
|
* forgotten about, This *could* be a problem if we request and close 4
|
||||||
* for the remote end to respond, but the worst case scenario is that some data meant for another channel
|
* billion or so channels in too rapid succession for the remote end to
|
||||||
* Gets picked up by the new one.... Pretty unlikely all told...
|
* respond, but the worst case scenario is that some data meant for
|
||||||
|
* another channel Gets picked up by the new one.... Pretty unlikely all
|
||||||
|
* told...
|
||||||
*/
|
*/
|
||||||
session->next_channel = id + 1;
|
session->next_channel = id + 1;
|
||||||
_libssh2_debug(session, LIBSSH2_DBG_CONN, "Allocated new channel ID#%lu",
|
_libssh2_debug(session, LIBSSH2_DBG_CONN, "Allocated new channel ID#%lu",
|
||||||
@@ -95,7 +99,7 @@ libssh2_channel_locate(LIBSSH2_SESSION * session, unsigned long channel_id)
|
|||||||
|
|
||||||
/* }}} */
|
/* }}} */
|
||||||
|
|
||||||
#define libssh2_channel_add(session, channel) \
|
#define CHANNEL_ADD(session, channel) \
|
||||||
{ \
|
{ \
|
||||||
if ((session)->channels.tail) { \
|
if ((session)->channels.tail) { \
|
||||||
(session)->channels.tail->next = (channel); \
|
(session)->channels.tail->next = (channel); \
|
||||||
@@ -130,7 +134,8 @@ libssh2_channel_open_ex(LIBSSH2_SESSION * session, const char *channel_type,
|
|||||||
session->open_channel = NULL;
|
session->open_channel = NULL;
|
||||||
session->open_packet = NULL;
|
session->open_packet = NULL;
|
||||||
session->open_data = NULL;
|
session->open_data = NULL;
|
||||||
/* 17 = packet_type(1) + channel_type_len(4) + sender_channel(4) + window_size(4) + packet_size(4) */
|
/* 17 = packet_type(1) + channel_type_len(4) + sender_channel(4) +
|
||||||
|
* window_size(4) + packet_size(4) */
|
||||||
session->open_packet_len = channel_type_len + message_len + 17;
|
session->open_packet_len = channel_type_len + message_len + 17;
|
||||||
session->open_local_channel = libssh2_channel_nextid(session);
|
session->open_local_channel = libssh2_channel_nextid(session);
|
||||||
|
|
||||||
@@ -169,7 +174,7 @@ libssh2_channel_open_ex(LIBSSH2_SESSION * session, const char *channel_type,
|
|||||||
session->open_channel->remote.window_size_initial = window_size;
|
session->open_channel->remote.window_size_initial = window_size;
|
||||||
session->open_channel->remote.packet_size = packet_size;
|
session->open_channel->remote.packet_size = packet_size;
|
||||||
|
|
||||||
libssh2_channel_add(session, session->open_channel);
|
CHANNEL_ADD(session, session->open_channel);
|
||||||
|
|
||||||
s = session->open_packet =
|
s = session->open_packet =
|
||||||
LIBSSH2_ALLOC(session, session->open_packet_len);
|
LIBSSH2_ALLOC(session, session->open_packet_len);
|
||||||
@@ -242,7 +247,8 @@ libssh2_channel_open_ex(LIBSSH2_SESSION * session, const char *channel_type,
|
|||||||
session->open_channel->local.packet_size =
|
session->open_channel->local.packet_size =
|
||||||
libssh2_ntohu32(session->open_data + 13);
|
libssh2_ntohu32(session->open_data + 13);
|
||||||
_libssh2_debug(session, LIBSSH2_DBG_CONN,
|
_libssh2_debug(session, LIBSSH2_DBG_CONN,
|
||||||
"Connection Established - ID: %lu/%lu win: %lu/%lu pack: %lu/%lu",
|
"Connection Established - ID: %lu/%lu win: %lu/%lu"
|
||||||
|
" pack: %lu/%lu",
|
||||||
session->open_channel->local.id,
|
session->open_channel->local.id,
|
||||||
session->open_channel->remote.id,
|
session->open_channel->remote.id,
|
||||||
session->open_channel->local.window_size,
|
session->open_channel->local.window_size,
|
||||||
@@ -408,7 +414,8 @@ libssh2_channel_forward_listen_ex(LIBSSH2_SESSION * session, const char *host,
|
|||||||
if (session->fwdLstn_state == libssh2_NB_state_idle) {
|
if (session->fwdLstn_state == libssh2_NB_state_idle) {
|
||||||
session->fwdLstn_host_len =
|
session->fwdLstn_host_len =
|
||||||
(host ? strlen(host) : (sizeof("0.0.0.0") - 1));
|
(host ? strlen(host) : (sizeof("0.0.0.0") - 1));
|
||||||
/* 14 = packet_type(1) + request_len(4) + want_replay(1) + host_len(4) + port(4) */
|
/* 14 = packet_type(1) + request_len(4) + want_replay(1) + host_len(4)
|
||||||
|
+ port(4) */
|
||||||
session->fwdLstn_packet_len =
|
session->fwdLstn_packet_len =
|
||||||
session->fwdLstn_host_len + (sizeof("tcpip-forward") - 1) + 14;
|
session->fwdLstn_host_len + (sizeof("tcpip-forward") - 1) + 14;
|
||||||
|
|
||||||
@@ -450,12 +457,14 @@ libssh2_channel_forward_listen_ex(LIBSSH2_SESSION * session, const char *host,
|
|||||||
session->fwdLstn_packet_len);
|
session->fwdLstn_packet_len);
|
||||||
if (rc == PACKET_EAGAIN) {
|
if (rc == PACKET_EAGAIN) {
|
||||||
libssh2_error(session, LIBSSH2_ERROR_EAGAIN,
|
libssh2_error(session, LIBSSH2_ERROR_EAGAIN,
|
||||||
"Would block sending global-request packet for forward listen request",
|
"Would block sending global-request packet for "
|
||||||
|
"forward listen request",
|
||||||
0);
|
0);
|
||||||
return NULL;
|
return NULL;
|
||||||
} else if (rc) {
|
} else if (rc) {
|
||||||
libssh2_error(session, LIBSSH2_ERROR_SOCKET_SEND,
|
libssh2_error(session, LIBSSH2_ERROR_SOCKET_SEND,
|
||||||
"Unable to send global-request packet for forward listen request",
|
"Unable to send global-request packet for forward "
|
||||||
|
"listen request",
|
||||||
0);
|
0);
|
||||||
LIBSSH2_FREE(session, session->fwdLstn_packet);
|
LIBSSH2_FREE(session, session->fwdLstn_packet);
|
||||||
session->fwdLstn_packet = NULL;
|
session->fwdLstn_packet = NULL;
|
||||||
@@ -567,7 +576,8 @@ libssh2_channel_forward_cancel(LIBSSH2_LISTENER * listener)
|
|||||||
LIBSSH2_CHANNEL *queued = listener->queue;
|
LIBSSH2_CHANNEL *queued = listener->queue;
|
||||||
unsigned char *packet, *s;
|
unsigned char *packet, *s;
|
||||||
unsigned long host_len = strlen(listener->host);
|
unsigned long host_len = strlen(listener->host);
|
||||||
/* 14 = packet_type(1) + request_len(4) + want_replay(1) + host_len(4) + port(4) */
|
/* 14 = packet_type(1) + request_len(4) + want_replay(1) + host_len(4) +
|
||||||
|
port(4) */
|
||||||
unsigned long packet_len =
|
unsigned long packet_len =
|
||||||
host_len + 14 + sizeof("cancel-tcpip-forward") - 1;
|
host_len + 14 + sizeof("cancel-tcpip-forward") - 1;
|
||||||
int rc;
|
int rc;
|
||||||
@@ -609,7 +619,8 @@ libssh2_channel_forward_cancel(LIBSSH2_LISTENER * listener)
|
|||||||
listener->chanFwdCncl_data = packet;
|
listener->chanFwdCncl_data = packet;
|
||||||
} else if (rc) {
|
} else if (rc) {
|
||||||
libssh2_error(session, LIBSSH2_ERROR_SOCKET_SEND,
|
libssh2_error(session, LIBSSH2_ERROR_SOCKET_SEND,
|
||||||
"Unable to send global-request packet for forward listen request",
|
"Unable to send global-request packet for forward "
|
||||||
|
"listen request",
|
||||||
0);
|
0);
|
||||||
LIBSSH2_FREE(session, packet);
|
LIBSSH2_FREE(session, packet);
|
||||||
listener->chanFwdCncl_state = libssh2_NB_state_idle;
|
listener->chanFwdCncl_state = libssh2_NB_state_idle;
|
||||||
@@ -721,7 +732,8 @@ libssh2_channel_setenv_ex(LIBSSH2_CHANNEL * channel, const char *varname,
|
|||||||
sizeof(channel->setenv_packet_requirev_state));
|
sizeof(channel->setenv_packet_requirev_state));
|
||||||
|
|
||||||
_libssh2_debug(session, LIBSSH2_DBG_CONN,
|
_libssh2_debug(session, LIBSSH2_DBG_CONN,
|
||||||
"Setting remote environment variable: %s=%s on channel %lu/%lu",
|
"Setting remote environment variable: %s=%s on "
|
||||||
|
"channel %lu/%lu",
|
||||||
varname, value, channel->local.id, channel->remote.id);
|
varname, value, channel->local.id, channel->remote.id);
|
||||||
|
|
||||||
s = channel->setenv_packet =
|
s = channel->setenv_packet =
|
||||||
@@ -762,7 +774,8 @@ libssh2_channel_setenv_ex(LIBSSH2_CHANNEL * channel, const char *varname,
|
|||||||
return PACKET_EAGAIN;
|
return PACKET_EAGAIN;
|
||||||
} else if (rc) {
|
} else if (rc) {
|
||||||
libssh2_error(session, LIBSSH2_ERROR_SOCKET_SEND,
|
libssh2_error(session, LIBSSH2_ERROR_SOCKET_SEND,
|
||||||
"Unable to send channel-request packet for setenv request",
|
"Unable to send channel-request packet for "
|
||||||
|
"setenv request",
|
||||||
0);
|
0);
|
||||||
LIBSSH2_FREE(session, channel->setenv_packet);
|
LIBSSH2_FREE(session, channel->setenv_packet);
|
||||||
channel->setenv_packet = NULL;
|
channel->setenv_packet = NULL;
|
||||||
@@ -930,6 +943,81 @@ libssh2_channel_request_pty_ex(LIBSSH2_CHANNEL * channel, const char *term,
|
|||||||
|
|
||||||
/* }}} */
|
/* }}} */
|
||||||
|
|
||||||
|
LIBSSH2_API int
|
||||||
|
libssh2_channel_request_pty_size_ex(LIBSSH2_CHANNEL * channel, int width,
|
||||||
|
int height, int width_px, int height_px)
|
||||||
|
{
|
||||||
|
LIBSSH2_SESSION *session = channel->session;
|
||||||
|
unsigned char *s;
|
||||||
|
int rc;
|
||||||
|
|
||||||
|
if (channel->reqPTY_state == libssh2_NB_state_idle) {
|
||||||
|
channel->reqPTY_packet_len = 39;
|
||||||
|
|
||||||
|
/* Zero the whole thing out */
|
||||||
|
memset(&channel->reqPTY_packet_requirev_state, 0,
|
||||||
|
sizeof(channel->reqPTY_packet_requirev_state));
|
||||||
|
|
||||||
|
_libssh2_debug(session, LIBSSH2_DBG_CONN,
|
||||||
|
"changing tty size on channel %lu/%lu",
|
||||||
|
channel->local.id,
|
||||||
|
channel->remote.id);
|
||||||
|
|
||||||
|
s = channel->reqPTY_packet =
|
||||||
|
LIBSSH2_ALLOC(session, channel->reqPTY_packet_len);
|
||||||
|
|
||||||
|
if (!channel->reqPTY_packet) {
|
||||||
|
libssh2_error(session, LIBSSH2_ERROR_ALLOC,
|
||||||
|
"Unable to allocate memory for pty-request", 0);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
*(s++) = SSH_MSG_CHANNEL_REQUEST;
|
||||||
|
libssh2_htonu32(s, channel->remote.id);
|
||||||
|
s += 4;
|
||||||
|
libssh2_htonu32(s, sizeof("window-change") - 1);
|
||||||
|
s += 4;
|
||||||
|
memcpy(s, "window-change", sizeof("window-change") - 1);
|
||||||
|
s += sizeof("window-change") - 1;
|
||||||
|
|
||||||
|
*(s++) = 0x00; /* Don't reply */
|
||||||
|
libssh2_htonu32(s, width);
|
||||||
|
s += 4;
|
||||||
|
libssh2_htonu32(s, height);
|
||||||
|
s += 4;
|
||||||
|
libssh2_htonu32(s, width_px);
|
||||||
|
s += 4;
|
||||||
|
libssh2_htonu32(s, height_px);
|
||||||
|
s += 4;
|
||||||
|
|
||||||
|
channel->reqPTY_state = libssh2_NB_state_created;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (channel->reqPTY_state == libssh2_NB_state_created) {
|
||||||
|
rc = libssh2_packet_write(session, channel->reqPTY_packet,
|
||||||
|
channel->reqPTY_packet_len);
|
||||||
|
if (rc == PACKET_EAGAIN) {
|
||||||
|
return PACKET_EAGAIN;
|
||||||
|
} else if (rc) {
|
||||||
|
libssh2_error(session, LIBSSH2_ERROR_SOCKET_SEND,
|
||||||
|
"Unable to send window-change packet", 0);
|
||||||
|
LIBSSH2_FREE(session, channel->reqPTY_packet);
|
||||||
|
channel->reqPTY_packet = NULL;
|
||||||
|
channel->reqPTY_state = libssh2_NB_state_idle;
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
LIBSSH2_FREE(session, channel->reqPTY_packet);
|
||||||
|
channel->reqPTY_packet = NULL;
|
||||||
|
libssh2_htonu32(channel->reqPTY_local_channel, channel->local.id);
|
||||||
|
channel->reqPTY_state = libssh2_NB_state_sent;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
channel->reqPTY_state = libssh2_NB_state_idle;
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
/* Keep this an even number */
|
/* Keep this an even number */
|
||||||
#define LIBSSH2_X11_RANDOM_COOKIE_LEN 32
|
#define LIBSSH2_X11_RANDOM_COOKIE_LEN 32
|
||||||
|
|
||||||
@@ -963,7 +1051,8 @@ libssh2_channel_x11_req_ex(LIBSSH2_CHANNEL * channel, int single_connection,
|
|||||||
sizeof(channel->reqX11_packet_requirev_state));
|
sizeof(channel->reqX11_packet_requirev_state));
|
||||||
|
|
||||||
_libssh2_debug(session, LIBSSH2_DBG_CONN,
|
_libssh2_debug(session, LIBSSH2_DBG_CONN,
|
||||||
"Requesting x11-req for channel %lu/%lu: single=%d proto=%s cookie=%s screen=%d",
|
"Requesting x11-req for channel %lu/%lu: single=%d "
|
||||||
|
"proto=%s cookie=%s screen=%d",
|
||||||
channel->local.id, channel->remote.id,
|
channel->local.id, channel->remote.id,
|
||||||
single_connection,
|
single_connection,
|
||||||
auth_proto ? auth_proto : "MIT-MAGIC-COOKIE-1",
|
auth_proto ? auth_proto : "MIT-MAGIC-COOKIE-1",
|
||||||
@@ -1218,7 +1307,8 @@ libssh2_channel_flush_ex(LIBSSH2_CHANNEL * channel, int streamid)
|
|||||||
int bytes_to_flush = packet->data_len - packet->data_head;
|
int bytes_to_flush = packet->data_len - packet->data_head;
|
||||||
|
|
||||||
_libssh2_debug(channel->session, LIBSSH2_DBG_CONN,
|
_libssh2_debug(channel->session, LIBSSH2_DBG_CONN,
|
||||||
"Flushing %d bytes of data from stream %lu on channel %lu/%lu",
|
"Flushing %d bytes of data from stream "
|
||||||
|
"%lu on channel %lu/%lu",
|
||||||
bytes_to_flush, packet_stream_id,
|
bytes_to_flush, packet_stream_id,
|
||||||
channel->local.id, channel->remote.id);
|
channel->local.id, channel->remote.id);
|
||||||
|
|
||||||
@@ -1294,7 +1384,8 @@ libssh2_channel_receive_window_adjust(LIBSSH2_CHANNEL * channel,
|
|||||||
&& (adjustment + channel->adjust_queue <
|
&& (adjustment + channel->adjust_queue <
|
||||||
LIBSSH2_CHANNEL_MINADJUST)) {
|
LIBSSH2_CHANNEL_MINADJUST)) {
|
||||||
_libssh2_debug(channel->session, LIBSSH2_DBG_CONN,
|
_libssh2_debug(channel->session, LIBSSH2_DBG_CONN,
|
||||||
"Queueing %lu bytes for receive window adjustment for channel %lu/%lu",
|
"Queueing %lu bytes for receive window adjustment "
|
||||||
|
"for channel %lu/%lu",
|
||||||
adjustment, channel->local.id, channel->remote.id);
|
adjustment, channel->local.id, channel->remote.id);
|
||||||
channel->adjust_queue += adjustment;
|
channel->adjust_queue += adjustment;
|
||||||
return channel->remote.window_size;
|
return channel->remote.window_size;
|
||||||
@@ -1313,7 +1404,8 @@ libssh2_channel_receive_window_adjust(LIBSSH2_CHANNEL * channel,
|
|||||||
libssh2_htonu32(channel->adjust_adjust + 1, channel->remote.id);
|
libssh2_htonu32(channel->adjust_adjust + 1, channel->remote.id);
|
||||||
libssh2_htonu32(channel->adjust_adjust + 5, adjustment);
|
libssh2_htonu32(channel->adjust_adjust + 5, adjustment);
|
||||||
_libssh2_debug(channel->session, LIBSSH2_DBG_CONN,
|
_libssh2_debug(channel->session, LIBSSH2_DBG_CONN,
|
||||||
"Adjusting window %lu bytes for data flushed from channel %lu/%lu",
|
"Adjusting window %lu bytes for data flushed from "
|
||||||
|
"channel %lu/%lu",
|
||||||
adjustment, channel->local.id, channel->remote.id);
|
adjustment, channel->local.id, channel->remote.id);
|
||||||
|
|
||||||
channel->adjust_state = libssh2_NB_state_created;
|
channel->adjust_state = libssh2_NB_state_created;
|
||||||
@@ -1324,7 +1416,8 @@ libssh2_channel_receive_window_adjust(LIBSSH2_CHANNEL * channel,
|
|||||||
return PACKET_EAGAIN;
|
return PACKET_EAGAIN;
|
||||||
} else if (rc) {
|
} else if (rc) {
|
||||||
libssh2_error(channel->session, LIBSSH2_ERROR_SOCKET_SEND,
|
libssh2_error(channel->session, LIBSSH2_ERROR_SOCKET_SEND,
|
||||||
"Unable to send transfer-window adjustment packet, deferring",
|
"Unable to send transfer-window adjustment packet, "
|
||||||
|
"deferring",
|
||||||
0);
|
0);
|
||||||
channel->adjust_queue = adjustment;
|
channel->adjust_queue = adjustment;
|
||||||
channel->adjust_state = libssh2_NB_state_idle;
|
channel->adjust_state = libssh2_NB_state_idle;
|
||||||
@@ -1339,10 +1432,11 @@ libssh2_channel_receive_window_adjust(LIBSSH2_CHANNEL * channel,
|
|||||||
/* }}} */
|
/* }}} */
|
||||||
|
|
||||||
/* {{{ libssh2_channel_handle_extended_data
|
/* {{{ libssh2_channel_handle_extended_data
|
||||||
* How should extended data look to the calling app?
|
*
|
||||||
* Keep it in separate channels[_read() _read_stdder()]? (NORMAL)
|
* How should extended data look to the calling app? Keep it in separate
|
||||||
* Merge the extended data to the standard data? [everything via _read()]? (MERGE)
|
* channels[_read() _read_stdder()]? (NORMAL) Merge the extended data to the
|
||||||
* Ignore it entirely [toss out packets as they come in]? (IGNORE)
|
* standard data? [everything via _read()]? (MERGE) Ignore it entirely [toss
|
||||||
|
* out packets as they come in]? (IGNORE)
|
||||||
*/
|
*/
|
||||||
LIBSSH2_API void
|
LIBSSH2_API void
|
||||||
libssh2_channel_handle_extended_data(LIBSSH2_CHANNEL * channel,
|
libssh2_channel_handle_extended_data(LIBSSH2_CHANNEL * channel,
|
||||||
@@ -1414,14 +1508,11 @@ libssh2_channel_read_ex(LIBSSH2_CHANNEL * channel, int stream_id, char *buf,
|
|||||||
} while (rc > 0);
|
} while (rc > 0);
|
||||||
|
|
||||||
if ((rc < 0) && (rc != PACKET_EAGAIN)) {
|
if ((rc < 0) && (rc != PACKET_EAGAIN)) {
|
||||||
fprintf(stderr, "return rc = %d\n", rc);
|
|
||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
channel->read_bytes_read = 0;
|
channel->read_bytes_read = 0;
|
||||||
channel->read_block = 0;
|
|
||||||
|
|
||||||
channel->read_packet = session->packets.head;
|
channel->read_packet = session->packets.head;
|
||||||
|
|
||||||
channel->read_state = libssh2_NB_state_created;
|
channel->read_state = libssh2_NB_state_created;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1435,21 +1526,34 @@ libssh2_channel_read_ex(LIBSSH2_CHANNEL * channel, int stream_id, char *buf,
|
|||||||
}
|
}
|
||||||
|
|
||||||
rc = 0;
|
rc = 0;
|
||||||
|
channel->read_block = 0;
|
||||||
|
|
||||||
do {
|
do {
|
||||||
if (channel->read_block) {
|
if (channel->read_block) {
|
||||||
/* in the second lap and onwards, do this */
|
/* in the second lap and onwards, do this...
|
||||||
|
* If we haven't yet filled our buffer, try to read more
|
||||||
|
* data. */
|
||||||
|
if ( channel->read_bytes_read < (int) buflen) {
|
||||||
rc = libssh2_packet_read(session);
|
rc = libssh2_packet_read(session);
|
||||||
channel->read_packet = session->packets.head;
|
|
||||||
|
/* If we didn't find any more data to read */
|
||||||
|
if (rc < 0) {
|
||||||
|
if ( channel->read_bytes_read > 0){
|
||||||
|
break; /* finish processing and return */
|
||||||
}
|
}
|
||||||
|
|
||||||
if (rc < 0) {
|
/* no packets available, no data read. */
|
||||||
if (rc != PACKET_EAGAIN) {
|
|
||||||
channel->read_state = libssh2_NB_state_idle;
|
channel->read_state = libssh2_NB_state_idle;
|
||||||
}
|
|
||||||
/* no packets available */
|
|
||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
/* We read more data, restart our processing at the beginning
|
||||||
|
* of our packet list. */
|
||||||
|
channel->read_packet = session->packets.head;
|
||||||
|
}
|
||||||
|
else { /* The read buffer is full, finish processing and return */
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
while (channel->read_packet
|
while (channel->read_packet
|
||||||
&& (channel->read_bytes_read < (int) buflen)) {
|
&& (channel->read_bytes_read < (int) buflen)) {
|
||||||
@@ -1521,7 +1625,8 @@ libssh2_channel_read_ex(LIBSSH2_CHANNEL * channel, int stream_id, char *buf,
|
|||||||
|
|
||||||
|
|
||||||
_libssh2_debug(session, LIBSSH2_DBG_CONN,
|
_libssh2_debug(session, LIBSSH2_DBG_CONN,
|
||||||
"Unlinking empty packet buffer from channel %lu/%lu",
|
"Unlinking empty packet buffer from "
|
||||||
|
"channel %lu/%lu",
|
||||||
channel->local.id, channel->remote.id);
|
channel->local.id, channel->remote.id);
|
||||||
channel_read_ex_point1:
|
channel_read_ex_point1:
|
||||||
channel->read_state = libssh2_NB_state_jump1;
|
channel->read_state = libssh2_NB_state_jump1;
|
||||||
@@ -1597,7 +1702,8 @@ libssh2_channel_packet_data_len(LIBSSH2_CHANNEL * channel, int stream_id)
|
|||||||
&& (channel->local.id == read_local_id)
|
&& (channel->local.id == read_local_id)
|
||||||
&& (stream_id == (int) libssh2_ntohu32(read_packet->data + 5)))
|
&& (stream_id == (int) libssh2_ntohu32(read_packet->data + 5)))
|
||||||
|| (!stream_id && (read_packet->data[0] == SSH_MSG_CHANNEL_DATA)
|
|| (!stream_id && (read_packet->data[0] == SSH_MSG_CHANNEL_DATA)
|
||||||
&& (channel->local.id == read_local_id)) || (!stream_id
|
&& (channel->local.id == read_local_id)) ||
|
||||||
|
(!stream_id
|
||||||
&& (read_packet->
|
&& (read_packet->
|
||||||
data[0] ==
|
data[0] ==
|
||||||
SSH_MSG_CHANNEL_EXTENDED_DATA)
|
SSH_MSG_CHANNEL_EXTENDED_DATA)
|
||||||
@@ -1610,7 +1716,6 @@ libssh2_channel_packet_data_len(LIBSSH2_CHANNEL * channel, int stream_id)
|
|||||||
==
|
==
|
||||||
LIBSSH2_CHANNEL_EXTENDED_DATA_MERGE)))
|
LIBSSH2_CHANNEL_EXTENDED_DATA_MERGE)))
|
||||||
{
|
{
|
||||||
|
|
||||||
return (read_packet->data_len - read_packet->data_head);
|
return (read_packet->data_len - read_packet->data_head);
|
||||||
}
|
}
|
||||||
read_packet = read_packet->next;
|
read_packet = read_packet->next;
|
||||||
@@ -1651,32 +1756,8 @@ libssh2_channel_write_ex(LIBSSH2_CHANNEL * channel, int stream_id,
|
|||||||
0);
|
0);
|
||||||
}
|
}
|
||||||
|
|
||||||
#if 0
|
/* [13] 9 = packet_type(1) + channelno(4) [ + streamid(4) ] +
|
||||||
/*
|
buflen(4) */
|
||||||
The following chunk of code is #ifdef'ed out, since I wanted it to
|
|
||||||
remain here with the given explanation why having the code in here
|
|
||||||
is not a good idea. The text is taken from the email Gavrie
|
|
||||||
Philipson wrote to libssh2-devel on Nov 8 2007.
|
|
||||||
|
|
||||||
The logic behind this is that in nonblocking mode, if the local
|
|
||||||
window size has shrunk to zero, there's no point in trying to send
|
|
||||||
anything more. However, exiting the function at that point does not
|
|
||||||
allow any adjusts from the remote side to be received, since
|
|
||||||
libssh2_packet_read (that is called further on in this function) is
|
|
||||||
never called in this case.
|
|
||||||
|
|
||||||
Removing this bit of code fixes the problem. This should not cause
|
|
||||||
busy waiting, since after the libssh2_packet_read, the function
|
|
||||||
correctly returns PACKET_EAGAIN if the window size was not adjusted.
|
|
||||||
*/
|
|
||||||
if (!channel->session->socket_block &&
|
|
||||||
(channel->local.window_size <= 0)) {
|
|
||||||
/* Can't write anything */
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* [13] 9 = packet_type(1) + channelno(4) [ + streamid(4) ] + buflen(4) */
|
|
||||||
channel->write_packet_len = buflen + (stream_id ? 13 : 9);
|
channel->write_packet_len = buflen + (stream_id ? 13 : 9);
|
||||||
channel->write_packet =
|
channel->write_packet =
|
||||||
LIBSSH2_ALLOC(session, channel->write_packet_len);
|
LIBSSH2_ALLOC(session, channel->write_packet_len);
|
||||||
@@ -1733,14 +1814,16 @@ libssh2_channel_write_ex(LIBSSH2_CHANNEL * channel, int stream_id,
|
|||||||
/* REMEMBER local means local as the SOURCE of the data */
|
/* REMEMBER local means local as the SOURCE of the data */
|
||||||
if (channel->write_bufwrite > channel->local.window_size) {
|
if (channel->write_bufwrite > channel->local.window_size) {
|
||||||
_libssh2_debug(session, LIBSSH2_DBG_CONN,
|
_libssh2_debug(session, LIBSSH2_DBG_CONN,
|
||||||
"Splitting write block due to %lu byte window_size on %lu/%lu/%d",
|
"Splitting write block due to %lu byte "
|
||||||
|
"window_size on %lu/%lu/%d",
|
||||||
channel->local.window_size, channel->local.id,
|
channel->local.window_size, channel->local.id,
|
||||||
channel->remote.id, stream_id);
|
channel->remote.id, stream_id);
|
||||||
channel->write_bufwrite = channel->local.window_size;
|
channel->write_bufwrite = channel->local.window_size;
|
||||||
}
|
}
|
||||||
if (channel->write_bufwrite > channel->local.packet_size) {
|
if (channel->write_bufwrite > channel->local.packet_size) {
|
||||||
_libssh2_debug(session, LIBSSH2_DBG_CONN,
|
_libssh2_debug(session, LIBSSH2_DBG_CONN,
|
||||||
"Splitting write block due to %lu byte packet_size on %lu/%lu/%d",
|
"Splitting write block due to %lu byte "
|
||||||
|
"packet_size on %lu/%lu/%d",
|
||||||
channel->local.packet_size, channel->local.id,
|
channel->local.packet_size, channel->local.id,
|
||||||
channel->remote.id, stream_id);
|
channel->remote.id, stream_id);
|
||||||
channel->write_bufwrite = channel->local.packet_size;
|
channel->write_bufwrite = channel->local.packet_size;
|
||||||
@@ -1763,8 +1846,11 @@ libssh2_channel_write_ex(LIBSSH2_CHANNEL * channel, int stream_id,
|
|||||||
channel->write_s -
|
channel->write_s -
|
||||||
channel->write_packet);
|
channel->write_packet);
|
||||||
if (rc == PACKET_EAGAIN) {
|
if (rc == PACKET_EAGAIN) {
|
||||||
|
_libssh2_debug(session, LIBSSH2_DBG_CONN,
|
||||||
|
"libssh2_packet_write returned EAGAIN");
|
||||||
return PACKET_EAGAIN;
|
return PACKET_EAGAIN;
|
||||||
} else if (rc) {
|
}
|
||||||
|
else if (rc) {
|
||||||
libssh2_error(session, LIBSSH2_ERROR_SOCKET_SEND,
|
libssh2_error(session, LIBSSH2_ERROR_SOCKET_SEND,
|
||||||
"Unable to send channel data", 0);
|
"Unable to send channel data", 0);
|
||||||
LIBSSH2_FREE(session, channel->write_packet);
|
LIBSSH2_FREE(session, channel->write_packet);
|
||||||
@@ -1854,7 +1940,7 @@ libssh2_channel_eof(LIBSSH2_CHANNEL * channel)
|
|||||||
|
|
||||||
/* }}} */
|
/* }}} */
|
||||||
|
|
||||||
/* {{{ libssh2_channel_wait_closed
|
/* {{{ libssh2_channel_wait_eof
|
||||||
* Awaiting channel EOF
|
* Awaiting channel EOF
|
||||||
*/
|
*/
|
||||||
LIBSSH2_API int
|
LIBSSH2_API int
|
||||||
@@ -1976,7 +2062,8 @@ libssh2_channel_wait_closed(LIBSSH2_CHANNEL * channel)
|
|||||||
|
|
||||||
if (!libssh2_channel_eof(channel)) {
|
if (!libssh2_channel_eof(channel)) {
|
||||||
libssh2_error(session, LIBSSH2_ERROR_INVAL,
|
libssh2_error(session, LIBSSH2_ERROR_INVAL,
|
||||||
"libssh2_channel_wait_closed() invoked when channel is not in EOF state",
|
"libssh2_channel_wait_closed() invoked when channel is "
|
||||||
|
"not in EOF state",
|
||||||
0);
|
0);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
@@ -2007,7 +2094,7 @@ libssh2_channel_wait_closed(LIBSSH2_CHANNEL * channel)
|
|||||||
|
|
||||||
channel->wait_closed_state = libssh2_NB_state_idle;
|
channel->wait_closed_state = libssh2_NB_state_idle;
|
||||||
|
|
||||||
return 1;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* }}} */
|
/* }}} */
|
||||||
@@ -2110,10 +2197,12 @@ libssh2_channel_free(LIBSSH2_CHANNEL * channel)
|
|||||||
/* }}} */
|
/* }}} */
|
||||||
|
|
||||||
/* {{{ libssh2_channel_window_read_ex
|
/* {{{ libssh2_channel_window_read_ex
|
||||||
* Check the status of the read window
|
*
|
||||||
* Returns the number of bytes which the remote end may send without overflowing the window limit
|
* Check the status of the read window. Returns the number of bytes which the
|
||||||
* read_avail (if passed) will be populated with the number of bytes actually available to be read
|
* remote end may send without overflowing the window limit read_avail (if
|
||||||
* window_size_initial (if passed) will be populated with the window_size_initial as defined by the channel_open request
|
* passed) will be populated with the number of bytes actually available to be
|
||||||
|
* read window_size_initial (if passed) will be populated with the
|
||||||
|
* window_size_initial as defined by the channel_open request
|
||||||
*/
|
*/
|
||||||
LIBSSH2_API unsigned long
|
LIBSSH2_API unsigned long
|
||||||
libssh2_channel_window_read_ex(LIBSSH2_CHANNEL * channel,
|
libssh2_channel_window_read_ex(LIBSSH2_CHANNEL * channel,
|
||||||
@@ -2149,16 +2238,19 @@ libssh2_channel_window_read_ex(LIBSSH2_CHANNEL * channel,
|
|||||||
/* }}} */
|
/* }}} */
|
||||||
|
|
||||||
/* {{{ libssh2_channel_window_write_ex
|
/* {{{ libssh2_channel_window_write_ex
|
||||||
* Check the status of the write window
|
*
|
||||||
* Returns the number of bytes which may be safely writen on the channel without blocking
|
* Check the status of the write window Returns the number of bytes which may
|
||||||
* window_size_initial (if passed) will be populated with the size of the initial window as defined by the channel_open request
|
* be safely writen on the channel without blocking window_size_initial (if
|
||||||
|
* passed) will be populated with the size of the initial window as defined by
|
||||||
|
* the channel_open request
|
||||||
*/
|
*/
|
||||||
LIBSSH2_API unsigned long
|
LIBSSH2_API unsigned long
|
||||||
libssh2_channel_window_write_ex(LIBSSH2_CHANNEL * channel,
|
libssh2_channel_window_write_ex(LIBSSH2_CHANNEL * channel,
|
||||||
unsigned long *window_size_initial)
|
unsigned long *window_size_initial)
|
||||||
{
|
{
|
||||||
if (window_size_initial) {
|
if (window_size_initial) {
|
||||||
/* For locally initiated channels this is very often 0, so it's not *that* useful as information goes */
|
/* For locally initiated channels this is very often 0, so it's not
|
||||||
|
* *that* useful as information goes */
|
||||||
*window_size_initial = channel->local.window_size_initial;
|
*window_size_initial = channel->local.window_size_initial;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
14
src/kex.c
14
src/kex.c
@@ -818,7 +818,7 @@ static int
|
|||||||
{
|
{
|
||||||
unsigned char *s;
|
unsigned char *s;
|
||||||
unsigned long p_len, g_len;
|
unsigned long p_len, g_len;
|
||||||
int ret;
|
int ret = 0;
|
||||||
int rc;
|
int rc;
|
||||||
|
|
||||||
if (key_state->state == libssh2_NB_state_idle) {
|
if (key_state->state == libssh2_NB_state_idle) {
|
||||||
@@ -1674,12 +1674,14 @@ libssh2_kex_agree_methods(LIBSSH2_SESSION * session, unsigned char *data,
|
|||||||
* Returns 0 on success, non-zero on failure
|
* Returns 0 on success, non-zero on failure
|
||||||
*/
|
*/
|
||||||
int
|
int
|
||||||
libssh2_kex_exchange(LIBSSH2_SESSION * session, int reexchange, /* session->flags |= SERVER */
|
libssh2_kex_exchange(LIBSSH2_SESSION * session, int reexchange,
|
||||||
key_exchange_state_t * key_state)
|
key_exchange_state_t * key_state)
|
||||||
{
|
{
|
||||||
int rc = 0;
|
int rc = 0;
|
||||||
int retcode;
|
int retcode;
|
||||||
|
|
||||||
|
session->state |= LIBSSH2_STATE_KEX_ACTIVE;
|
||||||
|
|
||||||
if (key_state->state == libssh2_NB_state_idle) {
|
if (key_state->state == libssh2_NB_state_idle) {
|
||||||
/* Prevent loop in packet_add() */
|
/* Prevent loop in packet_add() */
|
||||||
session->state |= LIBSSH2_STATE_EXCHANGING_KEYS;
|
session->state |= LIBSSH2_STATE_EXCHANGING_KEYS;
|
||||||
@@ -1711,11 +1713,14 @@ libssh2_kex_exchange(LIBSSH2_SESSION * session, int reexchange, /* session->flag
|
|||||||
if (key_state->state == libssh2_NB_state_sent) {
|
if (key_state->state == libssh2_NB_state_sent) {
|
||||||
retcode = libssh2_kexinit(session);
|
retcode = libssh2_kexinit(session);
|
||||||
if (retcode == PACKET_EAGAIN) {
|
if (retcode == PACKET_EAGAIN) {
|
||||||
|
session->state &= ~LIBSSH2_STATE_KEX_ACTIVE;
|
||||||
return PACKET_EAGAIN;
|
return PACKET_EAGAIN;
|
||||||
} else if (retcode) {
|
} else if (retcode) {
|
||||||
session->local.kexinit = key_state->oldlocal;
|
session->local.kexinit = key_state->oldlocal;
|
||||||
session->local.kexinit_len = key_state->oldlocal_len;
|
session->local.kexinit_len = key_state->oldlocal_len;
|
||||||
key_state->state = libssh2_NB_state_idle;
|
key_state->state = libssh2_NB_state_idle;
|
||||||
|
session->state &= ~LIBSSH2_STATE_KEX_ACTIVE;
|
||||||
|
session->state &= ~LIBSSH2_STATE_EXCHANGING_KEYS;
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1729,6 +1734,7 @@ libssh2_kex_exchange(LIBSSH2_SESSION * session, int reexchange, /* session->flag
|
|||||||
&key_state->data_len, 0, NULL, 0,
|
&key_state->data_len, 0, NULL, 0,
|
||||||
&key_state->req_state);
|
&key_state->req_state);
|
||||||
if (retcode == PACKET_EAGAIN) {
|
if (retcode == PACKET_EAGAIN) {
|
||||||
|
session->state &= ~LIBSSH2_STATE_KEX_ACTIVE;
|
||||||
return PACKET_EAGAIN;
|
return PACKET_EAGAIN;
|
||||||
} else if (retcode) {
|
} else if (retcode) {
|
||||||
if (session->local.kexinit) {
|
if (session->local.kexinit) {
|
||||||
@@ -1737,6 +1743,8 @@ libssh2_kex_exchange(LIBSSH2_SESSION * session, int reexchange, /* session->flag
|
|||||||
session->local.kexinit = key_state->oldlocal;
|
session->local.kexinit = key_state->oldlocal;
|
||||||
session->local.kexinit_len = key_state->oldlocal_len;
|
session->local.kexinit_len = key_state->oldlocal_len;
|
||||||
key_state->state = libssh2_NB_state_idle;
|
key_state->state = libssh2_NB_state_idle;
|
||||||
|
session->state &= ~LIBSSH2_STATE_KEX_ACTIVE;
|
||||||
|
session->state &= ~LIBSSH2_STATE_EXCHANGING_KEYS;
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1763,6 +1771,7 @@ libssh2_kex_exchange(LIBSSH2_SESSION * session, int reexchange, /* session->flag
|
|||||||
session->kex->exchange_keys(session,
|
session->kex->exchange_keys(session,
|
||||||
&key_state->key_state_low);
|
&key_state->key_state_low);
|
||||||
if (retcode == PACKET_EAGAIN) {
|
if (retcode == PACKET_EAGAIN) {
|
||||||
|
session->state &= ~LIBSSH2_STATE_KEX_ACTIVE;
|
||||||
return PACKET_EAGAIN;
|
return PACKET_EAGAIN;
|
||||||
} else if (retcode) {
|
} else if (retcode) {
|
||||||
libssh2_error(session, LIBSSH2_ERROR_KEY_EXCHANGE_FAILURE,
|
libssh2_error(session, LIBSSH2_ERROR_KEY_EXCHANGE_FAILURE,
|
||||||
@@ -1782,6 +1791,7 @@ libssh2_kex_exchange(LIBSSH2_SESSION * session, int reexchange, /* session->flag
|
|||||||
session->remote.kexinit = NULL;
|
session->remote.kexinit = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
session->state &= ~LIBSSH2_STATE_KEX_ACTIVE;
|
||||||
session->state &= ~LIBSSH2_STATE_EXCHANGING_KEYS;
|
session->state &= ~LIBSSH2_STATE_EXCHANGING_KEYS;
|
||||||
|
|
||||||
key_state->state = libssh2_NB_state_idle;
|
key_state->state = libssh2_NB_state_idle;
|
||||||
|
@@ -1,5 +1,6 @@
|
|||||||
/* Copyright (C) 2006, 2007 The Written Word, Inc. All rights reserved.
|
/* Copyright (C) 2006, 2007, The Written Word, Inc.
|
||||||
* Author: Simon Josefsson
|
* Copyright (C) 2008, Simon Josefsson
|
||||||
|
* All rights reserved.
|
||||||
*
|
*
|
||||||
* Redistribution and use in source and binary forms,
|
* Redistribution and use in source and binary forms,
|
||||||
* with or without modification, are permitted provided
|
* with or without modification, are permitted provided
|
||||||
@@ -150,10 +151,10 @@ _libssh2_rsa_new_private(libssh2_rsa_ctx ** rsa,
|
|||||||
LIBSSH2_SESSION * session,
|
LIBSSH2_SESSION * session,
|
||||||
FILE * fp, unsigned const char *passphrase)
|
FILE * fp, unsigned const char *passphrase)
|
||||||
{
|
{
|
||||||
char *data, *save_data;
|
unsigned char *data, *save_data;
|
||||||
unsigned int datalen;
|
unsigned int datalen;
|
||||||
int ret;
|
int ret;
|
||||||
char *n, *e, *d, *p, *q, *e1, *e2, *coeff;
|
unsigned char *n, *e, *d, *p, *q, *e1, *e2, *coeff;
|
||||||
unsigned int nlen, elen, dlen, plen, qlen, e1len, e2len, coefflen;
|
unsigned int nlen, elen, dlen, plen, qlen, e1len, e2len, coefflen;
|
||||||
|
|
||||||
(void) passphrase;
|
(void) passphrase;
|
||||||
@@ -245,10 +246,10 @@ _libssh2_dsa_new_private(libssh2_dsa_ctx ** dsa,
|
|||||||
LIBSSH2_SESSION * session,
|
LIBSSH2_SESSION * session,
|
||||||
FILE * fp, unsigned const char *passphrase)
|
FILE * fp, unsigned const char *passphrase)
|
||||||
{
|
{
|
||||||
char *data, *save_data;
|
unsigned char *data, *save_data;
|
||||||
unsigned int datalen;
|
unsigned int datalen;
|
||||||
int ret;
|
int ret;
|
||||||
char *p, *q, *g, *y, *x;
|
unsigned char *p, *q, *g, *y, *x;
|
||||||
unsigned int plen, qlen, glen, ylen, xlen;
|
unsigned int plen, qlen, glen, ylen, xlen;
|
||||||
|
|
||||||
(void) passphrase;
|
(void) passphrase;
|
||||||
|
@@ -1,5 +1,6 @@
|
|||||||
/* Copyright (C) 2006, 2007 The Written Word, Inc. All rights reserved.
|
/* Copyright (C) 2006, 2007, The Written Word, Inc.
|
||||||
* Author: Simon Josefsson
|
* Copyright (C) 2008, Simon Josefsson
|
||||||
|
* All rights reserved.
|
||||||
*
|
*
|
||||||
* Redistribution and use in source and binary forms,
|
* Redistribution and use in source and binary forms,
|
||||||
* with or without modification, are permitted provided
|
* with or without modification, are permitted provided
|
||||||
@@ -174,7 +175,7 @@ int _libssh2_cipher_crypt(_libssh2_cipher_ctx * ctx,
|
|||||||
#define _libssh2_bn struct gcry_mpi
|
#define _libssh2_bn struct gcry_mpi
|
||||||
#define _libssh2_bn_ctx int
|
#define _libssh2_bn_ctx int
|
||||||
#define _libssh2_bn_ctx_new() 0
|
#define _libssh2_bn_ctx_new() 0
|
||||||
#define _libssh2_bn_ctx_free(bnctx) 0
|
#define _libssh2_bn_ctx_free(bnctx) ((void)0)
|
||||||
#define _libssh2_bn_init() gcry_mpi_new(0)
|
#define _libssh2_bn_init() gcry_mpi_new(0)
|
||||||
#define _libssh2_bn_rand(bn, bits, top, bottom) gcry_mpi_randomize (bn, bits, GCRY_WEAK_RANDOM)
|
#define _libssh2_bn_rand(bn, bits, top, bottom) gcry_mpi_randomize (bn, bits, GCRY_WEAK_RANDOM)
|
||||||
#define _libssh2_bn_mod_exp(r, a, p, m, ctx) gcry_mpi_powm (r, a, p, m)
|
#define _libssh2_bn_mod_exp(r, a, p, m, ctx) gcry_mpi_powm (r, a, p, m)
|
||||||
|
@@ -1,4 +1,4 @@
|
|||||||
/* Copyright (c) 2004-2007, Sara Golemon <sarag@libssh2.org>
|
/* Copyright (c) 2004-2008, Sara Golemon <sarag@libssh2.org>
|
||||||
* All rights reserved.
|
* All rights reserved.
|
||||||
*
|
*
|
||||||
* Redistribution and use in source and binary forms,
|
* Redistribution and use in source and binary forms,
|
||||||
@@ -41,6 +41,17 @@
|
|||||||
#define LIBSSH2_LIBRARY
|
#define LIBSSH2_LIBRARY
|
||||||
#include "libssh2_config.h"
|
#include "libssh2_config.h"
|
||||||
|
|
||||||
|
#ifdef HAVE_WINDOWS_H
|
||||||
|
#include <windows.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef HAVE_WS2TCPIP_H
|
||||||
|
#include <ws2tcpip.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <time.h>
|
||||||
|
|
||||||
/* The following CPP block should really only be in session.c and
|
/* The following CPP block should really only be in session.c and
|
||||||
packet.c. However, AIX have #define's for 'events' and 'revents'
|
packet.c. However, AIX have #define's for 'events' and 'revents'
|
||||||
and we are using those names in libssh2.h, so we need to include
|
and we are using those names in libssh2.h, so we need to include
|
||||||
@@ -51,12 +62,10 @@
|
|||||||
http://www.mail-archive.com/libssh2-devel%40lists.sourceforge.net/msg00003.html
|
http://www.mail-archive.com/libssh2-devel%40lists.sourceforge.net/msg00003.html
|
||||||
http://www.mail-archive.com/libssh2-devel%40lists.sourceforge.net/msg00224.html
|
http://www.mail-archive.com/libssh2-devel%40lists.sourceforge.net/msg00224.html
|
||||||
*/
|
*/
|
||||||
#include <stdio.h>
|
|
||||||
|
|
||||||
#ifdef HAVE_POLL
|
#ifdef HAVE_POLL
|
||||||
# include <sys/poll.h>
|
# include <sys/poll.h>
|
||||||
#else
|
#else
|
||||||
# ifdef HAVE_SELECT
|
# if defined(HAVE_SELECT) && !defined(WIN32)
|
||||||
# ifdef HAVE_SYS_SELECT_H
|
# ifdef HAVE_SYS_SELECT_H
|
||||||
# include <sys/select.h>
|
# include <sys/select.h>
|
||||||
# else
|
# else
|
||||||
@@ -70,6 +79,28 @@
|
|||||||
#include "libssh2_publickey.h"
|
#include "libssh2_publickey.h"
|
||||||
#include "libssh2_sftp.h"
|
#include "libssh2_sftp.h"
|
||||||
|
|
||||||
|
/* Provide iovec / writev on WIN32 platform. */
|
||||||
|
#ifdef WIN32
|
||||||
|
|
||||||
|
/* same as WSABUF */
|
||||||
|
struct iovec {
|
||||||
|
u_long iov_len;
|
||||||
|
char *iov_base;
|
||||||
|
};
|
||||||
|
|
||||||
|
#define inline __inline
|
||||||
|
|
||||||
|
static inline int writev(int sock, struct iovec *iov, int nvecs)
|
||||||
|
{
|
||||||
|
DWORD ret;
|
||||||
|
if (WSASend(sock, (LPWSABUF)iov, nvecs, &ret, 0, NULL, NULL) == 0) {
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif /* WIN32 */
|
||||||
|
|
||||||
/* Needed for struct iovec on some platforms */
|
/* Needed for struct iovec on some platforms */
|
||||||
#ifdef HAVE_SYS_UIO_H
|
#ifdef HAVE_SYS_UIO_H
|
||||||
#include <sys/uio.h>
|
#include <sys/uio.h>
|
||||||
@@ -91,6 +122,26 @@
|
|||||||
#include "openssl.h"
|
#include "openssl.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifdef HAVE_WINSOCK2_H
|
||||||
|
|
||||||
|
#include <winsock2.h>
|
||||||
|
#include <mswsock.h>
|
||||||
|
#include <ws2tcpip.h>
|
||||||
|
|
||||||
|
#ifdef _MSC_VER
|
||||||
|
/* "inline" keyword is valid only with C++ engine! */
|
||||||
|
#define inline __inline
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* not really usleep, but safe for the way we use it in this lib */
|
||||||
|
static inline int usleep(int udelay)
|
||||||
|
{
|
||||||
|
Sleep(udelay / 1000);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
/* RFC4253 section 6.1 Maximum Packet Length says:
|
/* RFC4253 section 6.1 Maximum Packet Length says:
|
||||||
*
|
*
|
||||||
* "All implementations MUST be able to process packets with
|
* "All implementations MUST be able to process packets with
|
||||||
@@ -481,12 +532,19 @@ struct _LIBSSH2_PUBLICKEY
|
|||||||
unsigned long listFetch_data_len;
|
unsigned long listFetch_data_len;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
#define SFTP_HANDLE_MAXLEN 256 /* according to spec! */
|
||||||
|
|
||||||
struct _LIBSSH2_SFTP_HANDLE
|
struct _LIBSSH2_SFTP_HANDLE
|
||||||
{
|
{
|
||||||
LIBSSH2_SFTP *sftp;
|
LIBSSH2_SFTP *sftp;
|
||||||
LIBSSH2_SFTP_HANDLE *prev, *next;
|
LIBSSH2_SFTP_HANDLE *prev, *next;
|
||||||
|
|
||||||
char *handle;
|
/* This is a pre-allocated buffer used for sending SFTP requests as the
|
||||||
|
whole thing might not get sent in one go. This buffer is used for read,
|
||||||
|
write, close and MUST thus be big enough to suit all these. */
|
||||||
|
unsigned char request_packet[SFTP_HANDLE_MAXLEN + 25];
|
||||||
|
|
||||||
|
char handle[SFTP_HANDLE_MAXLEN];
|
||||||
int handle_len;
|
int handle_len;
|
||||||
|
|
||||||
char handle_type;
|
char handle_type;
|
||||||
@@ -654,6 +712,7 @@ struct _LIBSSH2_SESSION
|
|||||||
int socket_fd;
|
int socket_fd;
|
||||||
int socket_block;
|
int socket_block;
|
||||||
int socket_state;
|
int socket_state;
|
||||||
|
int socket_block_directions;
|
||||||
|
|
||||||
/* Error tracking */
|
/* Error tracking */
|
||||||
char *err_msg;
|
char *err_msg;
|
||||||
@@ -811,7 +870,14 @@ struct _LIBSSH2_SESSION
|
|||||||
unsigned char scpRecv_response[LIBSSH2_SCP_RESPONSE_BUFLEN];
|
unsigned char scpRecv_response[LIBSSH2_SCP_RESPONSE_BUFLEN];
|
||||||
unsigned long scpRecv_response_len;
|
unsigned long scpRecv_response_len;
|
||||||
long scpRecv_mode;
|
long scpRecv_mode;
|
||||||
|
#if defined(HAVE_LONGLONG) && defined(strtoll)
|
||||||
|
/* we have the type and we can parse such numbers */
|
||||||
|
long long scpRecv_size;
|
||||||
|
#define scpsize_strtol strtoll
|
||||||
|
#else
|
||||||
long scpRecv_size;
|
long scpRecv_size;
|
||||||
|
#define scpsize_strtol strtol
|
||||||
|
#endif
|
||||||
long scpRecv_mtime;
|
long scpRecv_mtime;
|
||||||
long scpRecv_atime;
|
long scpRecv_atime;
|
||||||
char *scpRecv_err_msg;
|
char *scpRecv_err_msg;
|
||||||
@@ -833,6 +899,7 @@ struct _LIBSSH2_SESSION
|
|||||||
#define LIBSSH2_STATE_EXCHANGING_KEYS 0x00000001
|
#define LIBSSH2_STATE_EXCHANGING_KEYS 0x00000001
|
||||||
#define LIBSSH2_STATE_NEWKEYS 0x00000002
|
#define LIBSSH2_STATE_NEWKEYS 0x00000002
|
||||||
#define LIBSSH2_STATE_AUTHENTICATED 0x00000004
|
#define LIBSSH2_STATE_AUTHENTICATED 0x00000004
|
||||||
|
#define LIBSSH2_STATE_KEX_ACTIVE 0x00000008
|
||||||
|
|
||||||
/* session.flag helpers */
|
/* session.flag helpers */
|
||||||
#ifdef MSG_NOSIGNAL
|
#ifdef MSG_NOSIGNAL
|
||||||
@@ -1136,7 +1203,7 @@ const LIBSSH2_MAC_METHOD **libssh2_mac_methods(void);
|
|||||||
int _libssh2_pem_parse(LIBSSH2_SESSION * session,
|
int _libssh2_pem_parse(LIBSSH2_SESSION * session,
|
||||||
const char *headerbegin,
|
const char *headerbegin,
|
||||||
const char *headerend,
|
const char *headerend,
|
||||||
FILE * fp, char **data, unsigned int *datalen);
|
FILE * fp, unsigned char **data, unsigned int *datalen);
|
||||||
int _libssh2_pem_decode_sequence(unsigned 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,
|
int _libssh2_pem_decode_integer(unsigned char **data, unsigned int *datalen,
|
||||||
unsigned char **i, unsigned int *ilen);
|
unsigned char **i, unsigned int *ilen);
|
||||||
|
@@ -294,7 +294,7 @@ static const LIBSSH2_MAC_METHOD *_libssh2_mac_methods[] = {
|
|||||||
&libssh2_mac_method_hmac_sha1_96,
|
&libssh2_mac_method_hmac_sha1_96,
|
||||||
&libssh2_mac_method_hmac_md5,
|
&libssh2_mac_method_hmac_md5,
|
||||||
&libssh2_mac_method_hmac_md5_96,
|
&libssh2_mac_method_hmac_md5_96,
|
||||||
#ifdef LIBSSH2_HMAC_RIPEMD
|
#if LIBSSH2_HMAC_RIPEMD
|
||||||
&libssh2_mac_method_hmac_ripemd160,
|
&libssh2_mac_method_hmac_ripemd160,
|
||||||
&libssh2_mac_method_hmac_ripemd160_openssh_com,
|
&libssh2_mac_method_hmac_ripemd160_openssh_com,
|
||||||
#endif /* LIBSSH2_HMAC_RIPEMD */
|
#endif /* LIBSSH2_HMAC_RIPEMD */
|
||||||
|
@@ -51,8 +51,7 @@ libssh2_ntohu32(const unsigned char *buf)
|
|||||||
/* }}} */
|
/* }}} */
|
||||||
|
|
||||||
/* {{{ libssh2_ntohu64
|
/* {{{ 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_uint64_t
|
||||||
libssh2_ntohu64(const unsigned char *buf)
|
libssh2_ntohu64(const unsigned char *buf)
|
||||||
@@ -62,7 +61,7 @@ libssh2_ntohu64(const unsigned char *buf)
|
|||||||
msl = (buf[0] << 24) | (buf[1] << 16) | (buf[2] << 8) | buf[3];
|
msl = (buf[0] << 24) | (buf[1] << 16) | (buf[2] << 8) | buf[3];
|
||||||
lsl = (buf[4] << 24) | (buf[5] << 16) | (buf[6] << 8) | buf[7];
|
lsl = (buf[4] << 24) | (buf[5] << 16) | (buf[6] << 8) | buf[7];
|
||||||
|
|
||||||
return ((msl * 65536) * 65536) + lsl;
|
return ((libssh2_uint64_t)msl <<32) | lsl;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* }}} */
|
/* }}} */
|
||||||
@@ -85,7 +84,7 @@ libssh2_htonu32(unsigned char *buf, unsigned long value)
|
|||||||
void
|
void
|
||||||
libssh2_htonu64(unsigned char *buf, libssh2_uint64_t value)
|
libssh2_htonu64(unsigned char *buf, libssh2_uint64_t value)
|
||||||
{
|
{
|
||||||
unsigned long msl = (value / 65536) / 65536;
|
unsigned long msl = ((libssh2_uint64_t)value >> 32);
|
||||||
|
|
||||||
buf[0] = (msl >> 24) & 0xFF;
|
buf[0] = (msl >> 24) & 0xFF;
|
||||||
buf[1] = (msl >> 16) & 0xFF;
|
buf[1] = (msl >> 16) & 0xFF;
|
||||||
|
28
src/packet.c
28
src/packet.c
@@ -665,6 +665,8 @@ libssh2_packet_add(LIBSSH2_SESSION * session, unsigned char *data,
|
|||||||
datalen - 13,
|
datalen - 13,
|
||||||
0);
|
0);
|
||||||
if (rc == PACKET_EAGAIN) {
|
if (rc == PACKET_EAGAIN) {
|
||||||
|
session->socket_block_directions =
|
||||||
|
LIBSSH2_SESSION_BLOCK_OUTBOUND;
|
||||||
return PACKET_EAGAIN;
|
return PACKET_EAGAIN;
|
||||||
}
|
}
|
||||||
session->packAdd_state = libssh2_NB_state_idle;
|
session->packAdd_state = libssh2_NB_state_idle;
|
||||||
@@ -817,6 +819,8 @@ libssh2_packet_add(LIBSSH2_SESSION * session, unsigned char *data,
|
|||||||
&session->
|
&session->
|
||||||
packAdd_Qlstn_state);
|
packAdd_Qlstn_state);
|
||||||
if (rc == PACKET_EAGAIN) {
|
if (rc == PACKET_EAGAIN) {
|
||||||
|
session->socket_block_directions =
|
||||||
|
LIBSSH2_SESSION_BLOCK_OUTBOUND;
|
||||||
return PACKET_EAGAIN;
|
return PACKET_EAGAIN;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -833,6 +837,8 @@ libssh2_packet_add(LIBSSH2_SESSION * session, unsigned char *data,
|
|||||||
rc = libssh2_packet_x11_open(session, data, datalen,
|
rc = libssh2_packet_x11_open(session, data, datalen,
|
||||||
&session->packAdd_x11open_state);
|
&session->packAdd_x11open_state);
|
||||||
if (rc == PACKET_EAGAIN) {
|
if (rc == PACKET_EAGAIN) {
|
||||||
|
session->socket_block_directions =
|
||||||
|
LIBSSH2_SESSION_BLOCK_OUTBOUND;
|
||||||
return PACKET_EAGAIN;
|
return PACKET_EAGAIN;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -914,11 +920,31 @@ libssh2_packet_add(LIBSSH2_SESSION * session, unsigned char *data,
|
|||||||
|
|
||||||
session->packAdd_state = libssh2_NB_state_sent2;
|
session->packAdd_state = libssh2_NB_state_sent2;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* The KEXINIT message has been added to the queue.
|
||||||
|
* The packAdd and readPack states need to be reset
|
||||||
|
* because libssh2_kex_exchange (eventually) calls upon
|
||||||
|
* libssh2_packet_read to read the rest of the key exchange
|
||||||
|
* conversation.
|
||||||
|
*/
|
||||||
|
session->readPack_state = libssh2_NB_state_idle;
|
||||||
|
session->packet.total_num = 0;
|
||||||
|
session->packAdd_state = libssh2_NB_state_idle;
|
||||||
|
session->fullpacket_state = libssh2_NB_state_idle;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Also, don't use packAdd_key_state for key re-exchange,
|
||||||
|
* as it will be wiped out in the middle of the exchange.
|
||||||
|
* How about re-using the startup_key_state?
|
||||||
|
*/
|
||||||
|
memset(&session->startup_key_state, 0, sizeof(key_exchange_state_t));
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* If there was a key reexchange failure, let's just hope we didn't
|
* If there was a key reexchange failure, let's just hope we didn't
|
||||||
* send NEWKEYS yet, otherwise remote will drop us like a rock
|
* send NEWKEYS yet, otherwise remote will drop us like a rock
|
||||||
*/
|
*/
|
||||||
rc = libssh2_kex_exchange(session, 1, &session->packAdd_key_state);
|
rc = libssh2_kex_exchange(session, 1, &session->startup_key_state);
|
||||||
if (rc == PACKET_EAGAIN) {
|
if (rc == PACKET_EAGAIN) {
|
||||||
return PACKET_EAGAIN;
|
return PACKET_EAGAIN;
|
||||||
}
|
}
|
||||||
|
10
src/pem.c
10
src/pem.c
@@ -1,5 +1,6 @@
|
|||||||
/* Copyright (C) 2007 The Written Word, Inc. All rights reserved.
|
/* Copyright (C) 2007 The Written Word, Inc.
|
||||||
* Author: Simon Josefsson
|
* Copyright (C) 2008, Simon Josefsson
|
||||||
|
* All rights reserved.
|
||||||
*
|
*
|
||||||
* Redistribution and use in source and binary forms,
|
* Redistribution and use in source and binary forms,
|
||||||
* with or without modification, are permitted provided
|
* with or without modification, are permitted provided
|
||||||
@@ -58,7 +59,7 @@ int
|
|||||||
_libssh2_pem_parse(LIBSSH2_SESSION * session,
|
_libssh2_pem_parse(LIBSSH2_SESSION * session,
|
||||||
const char *headerbegin,
|
const char *headerbegin,
|
||||||
const char *headerend,
|
const char *headerend,
|
||||||
FILE * fp, char **data, unsigned int *datalen)
|
FILE * fp, unsigned char **data, unsigned int *datalen)
|
||||||
{
|
{
|
||||||
char line[LINE_SIZE];
|
char line[LINE_SIZE];
|
||||||
char *b64data = NULL;
|
char *b64data = NULL;
|
||||||
@@ -96,7 +97,8 @@ _libssh2_pem_parse(LIBSSH2_SESSION * session,
|
|||||||
}
|
}
|
||||||
} while (strcmp(line, headerend) != 0);
|
} while (strcmp(line, headerend) != 0);
|
||||||
|
|
||||||
if (libssh2_base64_decode(session, data, datalen, b64data, b64datalen)) {
|
if (libssh2_base64_decode(session, (char**) data, datalen,
|
||||||
|
b64data, b64datalen)) {
|
||||||
ret = -1;
|
ret = -1;
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
@@ -109,7 +109,7 @@ static const LIBSSH2_PUBLICKEY_CODE_LIST libssh2_publickey_status_codes[] = {
|
|||||||
* Format an error message from a status code
|
* Format an error message from a status code
|
||||||
*/
|
*/
|
||||||
#define LIBSSH2_PUBLICKEY_STATUS_TEXT_START "Publickey Subsystem Error: \""
|
#define LIBSSH2_PUBLICKEY_STATUS_TEXT_START "Publickey Subsystem Error: \""
|
||||||
#define LIBSSH2_PUBLICKEY_STATUS_TEXT_MID "\" Server Resports: \""
|
#define LIBSSH2_PUBLICKEY_STATUS_TEXT_MID "\" Server Reports: \""
|
||||||
#define LIBSSH2_PUBLICKEY_STATUS_TEXT_END "\""
|
#define LIBSSH2_PUBLICKEY_STATUS_TEXT_END "\""
|
||||||
static void
|
static void
|
||||||
libssh2_publickey_status_error(const LIBSSH2_PUBLICKEY * pkey,
|
libssh2_publickey_status_error(const LIBSSH2_PUBLICKEY * pkey,
|
||||||
@@ -404,7 +404,7 @@ libssh2_publickey_init(LIBSSH2_SESSION * session)
|
|||||||
"publickey", strlen("publickey"));
|
"publickey", strlen("publickey"));
|
||||||
if (rc == PACKET_EAGAIN) {
|
if (rc == PACKET_EAGAIN) {
|
||||||
libssh2_error(session, LIBSSH2_ERROR_EAGAIN,
|
libssh2_error(session, LIBSSH2_ERROR_EAGAIN,
|
||||||
"Would block starting publickkey subsystem", 0);
|
"Would block starting publickey subsystem", 0);
|
||||||
return NULL;
|
return NULL;
|
||||||
} else if (rc) {
|
} else if (rc) {
|
||||||
libssh2_error(session, LIBSSH2_ERROR_CHANNEL_FAILURE,
|
libssh2_error(session, LIBSSH2_ERROR_CHANNEL_FAILURE,
|
||||||
@@ -420,7 +420,7 @@ libssh2_publickey_init(LIBSSH2_SESSION * session)
|
|||||||
LIBSSH2_CHANNEL_EXTENDED_DATA_IGNORE);
|
LIBSSH2_CHANNEL_EXTENDED_DATA_IGNORE);
|
||||||
if (rc == PACKET_EAGAIN) {
|
if (rc == PACKET_EAGAIN) {
|
||||||
libssh2_error(session, LIBSSH2_ERROR_EAGAIN,
|
libssh2_error(session, LIBSSH2_ERROR_EAGAIN,
|
||||||
"Would block starting publickkey subsystem", 0);
|
"Would block starting publickey subsystem", 0);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -457,7 +457,7 @@ libssh2_publickey_init(LIBSSH2_SESSION * session)
|
|||||||
(char *) buffer, (s - buffer));
|
(char *) buffer, (s - buffer));
|
||||||
if (rc == PACKET_EAGAIN) {
|
if (rc == PACKET_EAGAIN) {
|
||||||
libssh2_error(session, LIBSSH2_ERROR_EAGAIN,
|
libssh2_error(session, LIBSSH2_ERROR_EAGAIN,
|
||||||
"Would block sending publickkey version packet", 0);
|
"Would block sending publickey version packet", 0);
|
||||||
return NULL;
|
return NULL;
|
||||||
} else if ((s - buffer) != rc) {
|
} else if ((s - buffer) != rc) {
|
||||||
libssh2_error(session, LIBSSH2_ERROR_SOCKET_SEND,
|
libssh2_error(session, LIBSSH2_ERROR_SOCKET_SEND,
|
||||||
|
@@ -1,4 +1,4 @@
|
|||||||
/* Copyright (c) 2004-2007, Sara Golemon <sarag@libssh2.org>
|
/* Copyright (c) 2004-2008, Sara Golemon <sarag@libssh2.org>
|
||||||
* All rights reserved.
|
* All rights reserved.
|
||||||
*
|
*
|
||||||
* Redistribution and use in source and binary forms,
|
* Redistribution and use in source and binary forms,
|
||||||
@@ -487,7 +487,7 @@ libssh2_scp_recv(LIBSSH2_SESSION * session, const char *path, struct stat * sb)
|
|||||||
*(s++) = '\0';
|
*(s++) = '\0';
|
||||||
/* Make sure we don't get fooled by leftover values */
|
/* Make sure we don't get fooled by leftover values */
|
||||||
errno = 0;
|
errno = 0;
|
||||||
session->scpRecv_size = strtol(p, &e, 10);
|
session->scpRecv_size = scpsize_strtol(p, &e, 10);
|
||||||
if ((e && *e) || errno) {
|
if ((e && *e) || errno) {
|
||||||
libssh2_error(session, LIBSSH2_ERROR_SCP_PROTOCOL,
|
libssh2_error(session, LIBSSH2_ERROR_SCP_PROTOCOL,
|
||||||
"Invalid response from SCP server, invalid size",
|
"Invalid response from SCP server, invalid size",
|
||||||
|
@@ -133,6 +133,8 @@ libssh2_banner_receive(LIBSSH2_SESSION * session)
|
|||||||
}
|
}
|
||||||
#endif /* WIN32 */
|
#endif /* WIN32 */
|
||||||
if (errno == EAGAIN) {
|
if (errno == EAGAIN) {
|
||||||
|
session->socket_block_directions =
|
||||||
|
LIBSSH2_SESSION_BLOCK_INBOUND;
|
||||||
session->banner_TxRx_total_send = banner_len;
|
session->banner_TxRx_total_send = banner_len;
|
||||||
return PACKET_EAGAIN;
|
return PACKET_EAGAIN;
|
||||||
}
|
}
|
||||||
@@ -235,6 +237,8 @@ libssh2_banner_send(LIBSSH2_SESSION * session)
|
|||||||
if (ret != (banner_len - session->banner_TxRx_total_send)) {
|
if (ret != (banner_len - session->banner_TxRx_total_send)) {
|
||||||
if ((ret > 0) || ((ret == -1) && (errno == EAGAIN))) {
|
if ((ret > 0) || ((ret == -1) && (errno == EAGAIN))) {
|
||||||
/* the whole packet could not be sent, save the what was */
|
/* the whole packet could not be sent, save the what was */
|
||||||
|
session->socket_block_directions =
|
||||||
|
LIBSSH2_SESSION_BLOCK_OUTBOUND;
|
||||||
session->banner_TxRx_total_send += ret;
|
session->banner_TxRx_total_send += ret;
|
||||||
return PACKET_EAGAIN;
|
return PACKET_EAGAIN;
|
||||||
}
|
}
|
||||||
@@ -1189,14 +1193,18 @@ libssh2_poll_channel_read(LIBSSH2_CHANNEL * channel, int extended)
|
|||||||
LIBSSH2_SESSION *session = channel->session;
|
LIBSSH2_SESSION *session = channel->session;
|
||||||
LIBSSH2_PACKET *packet = session->packets.head;
|
LIBSSH2_PACKET *packet = session->packets.head;
|
||||||
|
|
||||||
while (packet) {
|
while (packet)
|
||||||
if (((packet->data[0] == SSH_MSG_CHANNEL_DATA) && (extended == 0) &&
|
{
|
||||||
(channel->local.id == libssh2_ntohu32(packet->data + 1))) ||
|
if ( channel->local.id == libssh2_ntohu32(packet->data + 1)) {
|
||||||
((packet->data[0] == SSH_MSG_CHANNEL_EXTENDED_DATA)
|
if ( extended == 1 &&
|
||||||
&& (extended != 0)
|
(packet->data[0] == SSH_MSG_CHANNEL_EXTENDED_DATA
|
||||||
&& (channel->local.id == libssh2_ntohu32(packet->data + 1)))) {
|
|| packet->data[0] == SSH_MSG_CHANNEL_DATA )) {
|
||||||
/* Found data waiting to be read */
|
|
||||||
return 1;
|
return 1;
|
||||||
|
} else if ( extended == 0 &&
|
||||||
|
packet->data[0] == SSH_MSG_CHANNEL_DATA) {
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
/* else - no data of any type is ready to be read */
|
||||||
}
|
}
|
||||||
packet = packet->next;
|
packet = packet->next;
|
||||||
}
|
}
|
||||||
@@ -1478,7 +1486,7 @@ libssh2_poll(LIBSSH2_POLLFD * fds, unsigned int nfds, long timeout)
|
|||||||
struct timeval tv_begin, tv_end;
|
struct timeval tv_begin, tv_end;
|
||||||
|
|
||||||
gettimeofday((struct timeval *) &tv_begin, NULL);
|
gettimeofday((struct timeval *) &tv_begin, NULL);
|
||||||
sysret = select(maxfd, &rfds, &wfds, NULL, &tv);
|
sysret = select(maxfd+1, &rfds, &wfds, NULL, &tv);
|
||||||
gettimeofday((struct timeval *) &tv_end, NULL);
|
gettimeofday((struct timeval *) &tv_end, NULL);
|
||||||
|
|
||||||
timeout_remaining -= (tv_end.tv_sec - tv_begin.tv_sec) * 1000;
|
timeout_remaining -= (tv_end.tv_sec - tv_begin.tv_sec) * 1000;
|
||||||
@@ -1488,7 +1496,7 @@ libssh2_poll(LIBSSH2_POLLFD * fds, unsigned int nfds, long timeout)
|
|||||||
/* If the platform doesn't support gettimeofday,
|
/* If the platform doesn't support gettimeofday,
|
||||||
* then just make the call non-blocking and walk away
|
* then just make the call non-blocking and walk away
|
||||||
*/
|
*/
|
||||||
sysret = select(maxfd, &rfds, &wfds, NULL, &tv);
|
sysret = select(maxfd+1, &rfds, &wfds, NULL, &tv);
|
||||||
timeout_remaining = 0;
|
timeout_remaining = 0;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@@ -1532,4 +1540,15 @@ libssh2_poll(LIBSSH2_POLLFD * fds, unsigned int nfds, long timeout)
|
|||||||
return active_fds;
|
return active_fds;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* {{{ libssh2_session_block_direction
|
||||||
|
* Get blocked direction when a function returns LIBSSH2_ERROR_EAGAIN
|
||||||
|
* Returns LIBSSH2_SOCKET_BLOCK_INBOUND if recv() blocked
|
||||||
|
* or LIBSSH2_SOCKET_BLOCK_OUTBOUND if send() blocked
|
||||||
|
*/
|
||||||
|
LIBSSH2_API int
|
||||||
|
libssh2_session_block_directions(LIBSSH2_SESSION *session)
|
||||||
|
{
|
||||||
|
return session->socket_block_directions;
|
||||||
|
}
|
||||||
|
|
||||||
/* }}} */
|
/* }}} */
|
||||||
|
261
src/sftp.c
261
src/sftp.c
@@ -1,4 +1,4 @@
|
|||||||
/* Copyright (c) 2004-2007, Sara Golemon <sarag@libssh2.org>
|
/* Copyright (c) 2004-2008, Sara Golemon <sarag@libssh2.org>
|
||||||
* All rights reserved.
|
* All rights reserved.
|
||||||
*
|
*
|
||||||
* Redistribution and use in source and binary forms,
|
* Redistribution and use in source and binary forms,
|
||||||
@@ -82,18 +82,18 @@
|
|||||||
/* S_IFDIR */
|
/* S_IFDIR */
|
||||||
#define LIBSSH2_SFTP_ATTR_PFILETYPE_DIR 0040000
|
#define LIBSSH2_SFTP_ATTR_PFILETYPE_DIR 0040000
|
||||||
|
|
||||||
/* {{{ libssh2_sftp_packet_add
|
/* {{{ sftp_packet_add
|
||||||
* Add a packet to the SFTP packet brigade
|
* Add a packet to the SFTP packet brigade
|
||||||
*/
|
*/
|
||||||
static int
|
static int
|
||||||
libssh2_sftp_packet_add(LIBSSH2_SFTP * sftp, unsigned char *data,
|
sftp_packet_add(LIBSSH2_SFTP * sftp, unsigned char *data,
|
||||||
unsigned long data_len)
|
unsigned long data_len)
|
||||||
{
|
{
|
||||||
LIBSSH2_SESSION *session = sftp->channel->session;
|
LIBSSH2_SESSION *session = sftp->channel->session;
|
||||||
LIBSSH2_PACKET *packet;
|
LIBSSH2_PACKET *packet;
|
||||||
|
|
||||||
_libssh2_debug(session, LIBSSH2_DBG_SFTP, "Received packet %d",
|
_libssh2_debug(session, LIBSSH2_DBG_SFTP, "Received packet %d (len %d)",
|
||||||
(int) data[0]);
|
(int) data[0], data_len);
|
||||||
packet = LIBSSH2_ALLOC(session, sizeof(LIBSSH2_PACKET));
|
packet = LIBSSH2_ALLOC(session, sizeof(LIBSSH2_PACKET));
|
||||||
if (!packet) {
|
if (!packet) {
|
||||||
libssh2_error(session, LIBSSH2_ERROR_ALLOC,
|
libssh2_error(session, LIBSSH2_ERROR_ALLOC,
|
||||||
@@ -120,11 +120,11 @@ libssh2_sftp_packet_add(LIBSSH2_SFTP * sftp, unsigned char *data,
|
|||||||
|
|
||||||
/* }}} */
|
/* }}} */
|
||||||
|
|
||||||
/* {{{ libssh2_sftp_packet_read
|
/* {{{ sftp_packet_read
|
||||||
* Frame an SFTP packet off the channel
|
* Frame an SFTP packet off the channel
|
||||||
*/
|
*/
|
||||||
static int
|
static int
|
||||||
libssh2_sftp_packet_read(LIBSSH2_SFTP * sftp, int flush)
|
sftp_packet_read(LIBSSH2_SFTP * sftp)
|
||||||
{
|
{
|
||||||
LIBSSH2_CHANNEL *channel = sftp->channel;
|
LIBSSH2_CHANNEL *channel = sftp->channel;
|
||||||
LIBSSH2_SESSION *session = channel->session;
|
LIBSSH2_SESSION *session = channel->session;
|
||||||
@@ -136,30 +136,27 @@ libssh2_sftp_packet_read(LIBSSH2_SFTP * sftp, int flush)
|
|||||||
|
|
||||||
_libssh2_debug(session, LIBSSH2_DBG_SFTP, "Waiting for packet");
|
_libssh2_debug(session, LIBSSH2_DBG_SFTP, "Waiting for packet");
|
||||||
|
|
||||||
if (flush && sftp->partial_packet) {
|
|
||||||
/* When flushing, remove previous partial */
|
|
||||||
LIBSSH2_FREE(session, sftp->partial_packet);
|
|
||||||
sftp->partial_packet = NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* If there was a previous partial, start using it */
|
/* If there was a previous partial, start using it */
|
||||||
if (sftp->partial_packet) {
|
if (sftp->partial_packet) {
|
||||||
|
|
||||||
packet = sftp->partial_packet;
|
packet = sftp->partial_packet;
|
||||||
packet_len = sftp->partial_len;
|
packet_len = sftp->partial_len;
|
||||||
packet_received = sftp->partial_received;
|
packet_received = sftp->partial_received;
|
||||||
sftp->partial_packet = NULL;
|
sftp->partial_packet = NULL;
|
||||||
} else {
|
|
||||||
if (flush && session->socket_block && !libssh2_waitsocket(session, 0)) {
|
_libssh2_debug(session, LIBSSH2_DBG_SFTP,
|
||||||
/* While flushing in blocking mode, check before reading */
|
"partial read cont, len: %lu", packet_len);
|
||||||
return -1;
|
|
||||||
}
|
}
|
||||||
|
else {
|
||||||
rc = libssh2_channel_read_ex(channel, 0, (char *) buffer, 4);
|
rc = libssh2_channel_read_ex(channel, 0, (char *) buffer, 4);
|
||||||
if (flush && (rc < 0)) {
|
if (rc == PACKET_EAGAIN) {
|
||||||
/* When flushing, exit quickly */
|
|
||||||
return -1;
|
|
||||||
} else if (rc == PACKET_EAGAIN) {
|
|
||||||
return PACKET_EAGAIN;
|
return PACKET_EAGAIN;
|
||||||
} else if (4 != rc) {
|
}
|
||||||
|
else if (4 != rc) {
|
||||||
|
/* TODO: this is stupid since we can in fact get 1-3 bytes in a
|
||||||
|
legitimate working case as well if the connection happens to be
|
||||||
|
super slow or something */
|
||||||
libssh2_error(session, LIBSSH2_ERROR_SOCKET_TIMEOUT,
|
libssh2_error(session, LIBSSH2_ERROR_SOCKET_TIMEOUT,
|
||||||
"Timeout waiting for FXP packet", 0);
|
"Timeout waiting for FXP packet", 0);
|
||||||
return -1;
|
return -1;
|
||||||
@@ -191,14 +188,7 @@ libssh2_sftp_packet_read(LIBSSH2_SFTP * sftp, int flush)
|
|||||||
(char *) packet + packet_received,
|
(char *) packet + packet_received,
|
||||||
packet_len - packet_received);
|
packet_len - packet_received);
|
||||||
|
|
||||||
if (flush && (bytes_received < 0)) {
|
if (bytes_received == PACKET_EAGAIN) {
|
||||||
if (packet) {
|
|
||||||
/* When flushing, remove packet if existing */
|
|
||||||
LIBSSH2_FREE(session, packet);
|
|
||||||
}
|
|
||||||
/* When flushing, exit quickly */
|
|
||||||
return -1;
|
|
||||||
} else if (bytes_received == PACKET_EAGAIN) {
|
|
||||||
/*
|
/*
|
||||||
* We received EAGAIN, save what we have and
|
* We received EAGAIN, save what we have and
|
||||||
* return to EAGAIN to the caller
|
* return to EAGAIN to the caller
|
||||||
@@ -209,7 +199,8 @@ libssh2_sftp_packet_read(LIBSSH2_SFTP * sftp, int flush)
|
|||||||
packet = NULL;
|
packet = NULL;
|
||||||
|
|
||||||
return PACKET_EAGAIN;
|
return PACKET_EAGAIN;
|
||||||
} else if (bytes_received < 0) {
|
}
|
||||||
|
else if (bytes_received < 0) {
|
||||||
libssh2_error(session, LIBSSH2_ERROR_SOCKET_TIMEOUT,
|
libssh2_error(session, LIBSSH2_ERROR_SOCKET_TIMEOUT,
|
||||||
"Receive error waiting for SFTP packet", 0);
|
"Receive error waiting for SFTP packet", 0);
|
||||||
LIBSSH2_FREE(session, packet);
|
LIBSSH2_FREE(session, packet);
|
||||||
@@ -218,7 +209,7 @@ libssh2_sftp_packet_read(LIBSSH2_SFTP * sftp, int flush)
|
|||||||
packet_received += bytes_received;
|
packet_received += bytes_received;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (libssh2_sftp_packet_add(sftp, packet, packet_len)) {
|
if (sftp_packet_add(sftp, packet, packet_len)) {
|
||||||
LIBSSH2_FREE(session, packet);
|
LIBSSH2_FREE(session, packet);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
@@ -228,11 +219,11 @@ libssh2_sftp_packet_read(LIBSSH2_SFTP * sftp, int flush)
|
|||||||
|
|
||||||
/* }}} */
|
/* }}} */
|
||||||
|
|
||||||
/* {{{ libssh2_sftp_packet_ask
|
/* {{{ sftp_packet_ask
|
||||||
* A la libssh2_packet_ask()
|
* A la libssh2_packet_ask()
|
||||||
*/
|
*/
|
||||||
static int
|
static int
|
||||||
libssh2_sftp_packet_ask(LIBSSH2_SFTP * sftp, unsigned char packet_type,
|
sftp_packet_ask(LIBSSH2_SFTP * sftp, unsigned char packet_type,
|
||||||
unsigned long request_id, unsigned char **data,
|
unsigned long request_id, unsigned char **data,
|
||||||
unsigned long *data_len, int poll_channel)
|
unsigned long *data_len, int poll_channel)
|
||||||
{
|
{
|
||||||
@@ -244,7 +235,7 @@ libssh2_sftp_packet_ask(LIBSSH2_SFTP * sftp, unsigned char packet_type,
|
|||||||
_libssh2_debug(session, LIBSSH2_DBG_SFTP, "Asking for %d packet",
|
_libssh2_debug(session, LIBSSH2_DBG_SFTP, "Asking for %d packet",
|
||||||
(int) packet_type);
|
(int) packet_type);
|
||||||
if (poll_channel) {
|
if (poll_channel) {
|
||||||
int ret = libssh2_sftp_packet_read(sftp, 0);
|
int ret = sftp_packet_read(sftp);
|
||||||
if (ret == PACKET_EAGAIN) {
|
if (ret == PACKET_EAGAIN) {
|
||||||
return PACKET_EAGAIN;
|
return PACKET_EAGAIN;
|
||||||
} else if (ret < 0) {
|
} else if (ret < 0) {
|
||||||
@@ -288,11 +279,11 @@ libssh2_sftp_packet_ask(LIBSSH2_SFTP * sftp, unsigned char packet_type,
|
|||||||
|
|
||||||
/* }}} */
|
/* }}} */
|
||||||
|
|
||||||
/* {{{ libssh2_sftp_packet_require
|
/* {{{ sftp_packet_require
|
||||||
* A la libssh2_packet_require
|
* A la libssh2_packet_require
|
||||||
*/
|
*/
|
||||||
static int
|
static int
|
||||||
libssh2_sftp_packet_require(LIBSSH2_SFTP * sftp, unsigned char packet_type,
|
sftp_packet_require(LIBSSH2_SFTP * sftp, unsigned char packet_type,
|
||||||
unsigned long request_id, unsigned char **data,
|
unsigned long request_id, unsigned char **data,
|
||||||
unsigned long *data_len)
|
unsigned long *data_len)
|
||||||
{
|
{
|
||||||
@@ -302,14 +293,14 @@ libssh2_sftp_packet_require(LIBSSH2_SFTP * sftp, unsigned char packet_type,
|
|||||||
_libssh2_debug(session, LIBSSH2_DBG_SFTP, "Requiring %d packet",
|
_libssh2_debug(session, LIBSSH2_DBG_SFTP, "Requiring %d packet",
|
||||||
(int) packet_type);
|
(int) packet_type);
|
||||||
|
|
||||||
if (libssh2_sftp_packet_ask
|
if (sftp_packet_ask(sftp, packet_type, request_id, data,
|
||||||
(sftp, packet_type, request_id, data, data_len, 0) == 0) {
|
data_len, 0) == 0) {
|
||||||
/* The right packet was available in the packet brigade */
|
/* The right packet was available in the packet brigade */
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
while (session->socket_state == LIBSSH2_SOCKET_CONNECTED) {
|
while (session->socket_state == LIBSSH2_SOCKET_CONNECTED) {
|
||||||
ret = libssh2_sftp_packet_read(sftp, 0);
|
ret = sftp_packet_read(sftp);
|
||||||
if (ret == PACKET_EAGAIN) {
|
if (ret == PACKET_EAGAIN) {
|
||||||
return PACKET_EAGAIN;
|
return PACKET_EAGAIN;
|
||||||
} else if (ret <= 0) {
|
} else if (ret <= 0) {
|
||||||
@@ -318,7 +309,7 @@ libssh2_sftp_packet_require(LIBSSH2_SFTP * sftp, unsigned char packet_type,
|
|||||||
|
|
||||||
if (packet_type == ret) {
|
if (packet_type == ret) {
|
||||||
/* Be lazy, let packet_ask pull it out of the brigade */
|
/* Be lazy, let packet_ask pull it out of the brigade */
|
||||||
return libssh2_sftp_packet_ask(sftp, packet_type, request_id, data,
|
return sftp_packet_ask(sftp, packet_type, request_id, data,
|
||||||
data_len, 0);
|
data_len, 0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -329,11 +320,11 @@ libssh2_sftp_packet_require(LIBSSH2_SFTP * sftp, unsigned char packet_type,
|
|||||||
|
|
||||||
/* }}} */
|
/* }}} */
|
||||||
|
|
||||||
/* {{{ libssh2_sftp_packet_requirev
|
/* {{{ sftp_packet_requirev
|
||||||
* Requie one of N possible reponses
|
* Require one of N possible reponses
|
||||||
*/
|
*/
|
||||||
static int
|
static int
|
||||||
libssh2_sftp_packet_requirev(LIBSSH2_SFTP * sftp, int num_valid_responses,
|
sftp_packet_requirev(LIBSSH2_SFTP * sftp, int num_valid_responses,
|
||||||
const unsigned char *valid_responses,
|
const unsigned char *valid_responses,
|
||||||
unsigned long request_id, unsigned char **data,
|
unsigned long request_id, unsigned char **data,
|
||||||
unsigned long *data_len)
|
unsigned long *data_len)
|
||||||
@@ -341,24 +332,15 @@ libssh2_sftp_packet_requirev(LIBSSH2_SFTP * sftp, int num_valid_responses,
|
|||||||
int i;
|
int i;
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
/*
|
/* If no timeout is active, start a new one */
|
||||||
* If no timeout is active, start a new one and flush
|
|
||||||
* any pending packets
|
|
||||||
*/
|
|
||||||
if (sftp->requirev_start == 0) {
|
if (sftp->requirev_start == 0) {
|
||||||
_libssh2_debug(sftp->channel->session, LIBSSH2_DBG_SFTP,
|
|
||||||
"_requirev(): Initialize timeout");
|
|
||||||
sftp->requirev_start = time(NULL);
|
sftp->requirev_start = time(NULL);
|
||||||
|
|
||||||
/* Flush */
|
|
||||||
while (libssh2_sftp_packet_read(sftp, 1) > 0);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
while (sftp->channel->session->socket_state == LIBSSH2_SOCKET_CONNECTED) {
|
while (sftp->channel->session->socket_state == LIBSSH2_SOCKET_CONNECTED) {
|
||||||
for(i = 0; i < num_valid_responses; i++) {
|
for(i = 0; i < num_valid_responses; i++) {
|
||||||
if (libssh2_sftp_packet_ask
|
if (sftp_packet_ask(sftp, valid_responses[i], request_id,
|
||||||
(sftp, valid_responses[i], request_id, data, data_len,
|
data, data_len, 0) == 0) {
|
||||||
0) == 0) {
|
|
||||||
/*
|
/*
|
||||||
* Set to zero before all returns to say
|
* Set to zero before all returns to say
|
||||||
* the timeout is not active
|
* the timeout is not active
|
||||||
@@ -368,7 +350,7 @@ libssh2_sftp_packet_requirev(LIBSSH2_SFTP * sftp, int num_valid_responses,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ret = libssh2_sftp_packet_read(sftp, 0);
|
ret = sftp_packet_read(sftp);
|
||||||
if ((ret < 0) && (ret != PACKET_EAGAIN)) {
|
if ((ret < 0) && (ret != PACKET_EAGAIN)) {
|
||||||
sftp->requirev_start = 0;
|
sftp->requirev_start = 0;
|
||||||
return -1;
|
return -1;
|
||||||
@@ -534,7 +516,7 @@ LIBSSH2_CHANNEL_CLOSE_FUNC(libssh2_sftp_dtor)
|
|||||||
libssh2_sftp_close_handle(sftp->handles);
|
libssh2_sftp_close_handle(sftp->handles);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Free the partial packet storage for libssh2_sftp_packet_read */
|
/* Free the partial packet storage for sftp_packet_read */
|
||||||
if (sftp->partial_packet) {
|
if (sftp->partial_packet) {
|
||||||
LIBSSH2_FREE(session, sftp->partial_packet);
|
LIBSSH2_FREE(session, sftp->partial_packet);
|
||||||
}
|
}
|
||||||
@@ -659,7 +641,7 @@ libssh2_sftp_init(LIBSSH2_SESSION * session)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* For initiallization we are requiring blocking, probably reasonable */
|
/* For initiallization we are requiring blocking, probably reasonable */
|
||||||
rc = libssh2_sftp_packet_require(session->sftpInit_sftp, SSH_FXP_VERSION,
|
rc = sftp_packet_require(session->sftpInit_sftp, SSH_FXP_VERSION,
|
||||||
0, &data, &data_len);
|
0, &data, &data_len);
|
||||||
if (rc == PACKET_EAGAIN) {
|
if (rc == PACKET_EAGAIN) {
|
||||||
libssh2_error(session, LIBSSH2_ERROR_EAGAIN,
|
libssh2_error(session, LIBSSH2_ERROR_EAGAIN,
|
||||||
@@ -744,10 +726,6 @@ libssh2_sftp_shutdown(LIBSSH2_SFTP * sftp)
|
|||||||
LIBSSH2_FREE(sftp->channel->session, sftp->open_packet);
|
LIBSSH2_FREE(sftp->channel->session, sftp->open_packet);
|
||||||
sftp->open_packet = NULL;
|
sftp->open_packet = NULL;
|
||||||
}
|
}
|
||||||
if (sftp->read_packet) {
|
|
||||||
LIBSSH2_FREE(sftp->channel->session, sftp->read_packet);
|
|
||||||
sftp->read_packet = NULL;
|
|
||||||
}
|
|
||||||
if (sftp->readdir_packet) {
|
if (sftp->readdir_packet) {
|
||||||
LIBSSH2_FREE(sftp->channel->session, sftp->readdir_packet);
|
LIBSSH2_FREE(sftp->channel->session, sftp->readdir_packet);
|
||||||
sftp->readdir_packet = NULL;
|
sftp->readdir_packet = NULL;
|
||||||
@@ -814,7 +792,8 @@ libssh2_sftp_open_ex(LIBSSH2_SFTP * sftp, const char *filename,
|
|||||||
int rc;
|
int rc;
|
||||||
|
|
||||||
if (sftp->open_state == libssh2_NB_state_idle) {
|
if (sftp->open_state == libssh2_NB_state_idle) {
|
||||||
/* packet_len(4) + packet_type(1) + request_id(4) + filename_len(4) + flags(4) */
|
/* packet_len(4) + packet_type(1) + request_id(4) + filename_len(4) +
|
||||||
|
flags(4) */
|
||||||
sftp->open_packet_len = filename_len + 13 +
|
sftp->open_packet_len = filename_len + 13 +
|
||||||
((open_type ==
|
((open_type ==
|
||||||
LIBSSH2_SFTP_OPENFILE) ? (4 +
|
LIBSSH2_SFTP_OPENFILE) ? (4 +
|
||||||
@@ -823,7 +802,8 @@ libssh2_sftp_open_ex(LIBSSH2_SFTP * sftp, const char *filename,
|
|||||||
s = sftp->open_packet = LIBSSH2_ALLOC(session, sftp->open_packet_len);
|
s = sftp->open_packet = LIBSSH2_ALLOC(session, sftp->open_packet_len);
|
||||||
if (!sftp->open_packet) {
|
if (!sftp->open_packet) {
|
||||||
libssh2_error(session, LIBSSH2_ERROR_ALLOC,
|
libssh2_error(session, LIBSSH2_ERROR_ALLOC,
|
||||||
"Unable to allocate memory for FXP_OPEN or FXP_OPENDIR packet",
|
"Unable to allocate memory for FXP_OPEN or "
|
||||||
|
"FXP_OPENDIR packet",
|
||||||
0);
|
0);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
@@ -866,7 +846,11 @@ libssh2_sftp_open_ex(LIBSSH2_SFTP * sftp, const char *filename,
|
|||||||
"Would block sending FXP_OPEN or FXP_OPENDIR command",
|
"Would block sending FXP_OPEN or FXP_OPENDIR command",
|
||||||
0);
|
0);
|
||||||
return NULL;
|
return NULL;
|
||||||
} else if (sftp->open_packet_len != rc) {
|
}
|
||||||
|
else if (sftp->open_packet_len != rc) {
|
||||||
|
/* TODO: partial writes should be fine too and is not a sign of
|
||||||
|
an error when in non-blocking mode! */
|
||||||
|
|
||||||
libssh2_error(session, LIBSSH2_ERROR_SOCKET_SEND,
|
libssh2_error(session, LIBSSH2_ERROR_SOCKET_SEND,
|
||||||
"Unable to send FXP_OPEN or FXP_OPENDIR command", 0);
|
"Unable to send FXP_OPEN or FXP_OPENDIR command", 0);
|
||||||
LIBSSH2_FREE(session, sftp->open_packet);
|
LIBSSH2_FREE(session, sftp->open_packet);
|
||||||
@@ -881,14 +865,15 @@ libssh2_sftp_open_ex(LIBSSH2_SFTP * sftp, const char *filename,
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (sftp->open_state == libssh2_NB_state_sent) {
|
if (sftp->open_state == libssh2_NB_state_sent) {
|
||||||
rc = libssh2_sftp_packet_requirev(sftp, 2, fopen_responses,
|
rc = sftp_packet_requirev(sftp, 2, fopen_responses,
|
||||||
sftp->open_request_id, &data,
|
sftp->open_request_id, &data,
|
||||||
&data_len);
|
&data_len);
|
||||||
if (rc == PACKET_EAGAIN) {
|
if (rc == PACKET_EAGAIN) {
|
||||||
libssh2_error(session, LIBSSH2_ERROR_EAGAIN,
|
libssh2_error(session, LIBSSH2_ERROR_EAGAIN,
|
||||||
"Would block waiting for status message", 0);
|
"Would block waiting for status message", 0);
|
||||||
return NULL;
|
return NULL;
|
||||||
} else if (rc) {
|
}
|
||||||
|
else if (rc) {
|
||||||
libssh2_error(session, LIBSSH2_ERROR_SOCKET_TIMEOUT,
|
libssh2_error(session, LIBSSH2_ERROR_SOCKET_TIMEOUT,
|
||||||
"Timeout waiting for status message", 0);
|
"Timeout waiting for status message", 0);
|
||||||
sftp->open_state = libssh2_NB_state_idle;
|
sftp->open_state = libssh2_NB_state_idle;
|
||||||
@@ -898,13 +883,39 @@ libssh2_sftp_open_ex(LIBSSH2_SFTP * sftp, const char *filename,
|
|||||||
|
|
||||||
sftp->open_state = libssh2_NB_state_idle;
|
sftp->open_state = libssh2_NB_state_idle;
|
||||||
|
|
||||||
|
/* OPEN can basically get STATUS or HANDLE back, where HANDLE implies a
|
||||||
|
fine response while STATUS means error. It seems though that at times
|
||||||
|
we get an SSH_FX_OK back in a STATUS, followed the "real" HANDLE so
|
||||||
|
we need to properly deal with that. */
|
||||||
if (data[0] == SSH_FXP_STATUS) {
|
if (data[0] == SSH_FXP_STATUS) {
|
||||||
|
int badness = 1;
|
||||||
|
sftp->last_errno = libssh2_ntohu32(data + 5);
|
||||||
|
|
||||||
|
if(LIBSSH2_FX_OK == sftp->last_errno) {
|
||||||
|
_libssh2_debug(session, LIBSSH2_DBG_SFTP, "got HANDLE FXOK!");
|
||||||
|
|
||||||
|
/* silly situation, but check for a HANDLE */
|
||||||
|
rc = sftp_packet_require(sftp, SSH_FXP_HANDLE,
|
||||||
|
sftp->open_request_id, &data, &data_len);
|
||||||
|
if(rc == PACKET_EAGAIN) {
|
||||||
|
/* go back to sent state and wait for something else */
|
||||||
|
sftp->open_state = libssh2_NB_state_sent;
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
else if(!rc)
|
||||||
|
/* we got the handle so this is not a bad situation */
|
||||||
|
badness = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(badness) {
|
||||||
libssh2_error(session, LIBSSH2_ERROR_SFTP_PROTOCOL,
|
libssh2_error(session, LIBSSH2_ERROR_SFTP_PROTOCOL,
|
||||||
"Failed opening remote file", 0);
|
"Failed opening remote file", 0);
|
||||||
sftp->last_errno = libssh2_ntohu32(data + 5);
|
_libssh2_debug(session, LIBSSH2_DBG_SFTP, "got FXP_STATUS %d",
|
||||||
|
sftp->last_errno);
|
||||||
LIBSSH2_FREE(session, data);
|
LIBSSH2_FREE(session, data);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
fp = LIBSSH2_ALLOC(session, sizeof(LIBSSH2_SFTP_HANDLE));
|
fp = LIBSSH2_ALLOC(session, sizeof(LIBSSH2_SFTP_HANDLE));
|
||||||
if (!fp) {
|
if (!fp) {
|
||||||
@@ -920,18 +931,11 @@ libssh2_sftp_open_ex(LIBSSH2_SFTP * sftp, const char *filename,
|
|||||||
LIBSSH2_SFTP_HANDLE_DIR;
|
LIBSSH2_SFTP_HANDLE_DIR;
|
||||||
|
|
||||||
fp->handle_len = libssh2_ntohu32(data + 5);
|
fp->handle_len = libssh2_ntohu32(data + 5);
|
||||||
if (fp->handle_len > 256) {
|
if (fp->handle_len > SFTP_HANDLE_MAXLEN) {
|
||||||
/* SFTP doesn't allow handles longer than 256 characters */
|
/* SFTP doesn't allow handles longer than 256 characters */
|
||||||
fp->handle_len = 256;
|
fp->handle_len = SFTP_HANDLE_MAXLEN;
|
||||||
}
|
|
||||||
fp->handle = LIBSSH2_ALLOC(session, fp->handle_len);
|
|
||||||
if (!fp->handle) {
|
|
||||||
libssh2_error(session, LIBSSH2_ERROR_ALLOC,
|
|
||||||
"Unable to allocate space for SFTP file/dir handle", 0);
|
|
||||||
LIBSSH2_FREE(session, data);
|
|
||||||
LIBSSH2_FREE(session, fp);
|
|
||||||
return NULL;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
memcpy(fp->handle, data + 9, fp->handle_len);
|
memcpy(fp->handle, data + 9, fp->handle_len);
|
||||||
LIBSSH2_FREE(session, data);
|
LIBSSH2_FREE(session, data);
|
||||||
|
|
||||||
@@ -960,8 +964,9 @@ libssh2_sftp_read(LIBSSH2_SFTP_HANDLE * handle, char *buffer,
|
|||||||
LIBSSH2_SFTP *sftp = handle->sftp;
|
LIBSSH2_SFTP *sftp = handle->sftp;
|
||||||
LIBSSH2_CHANNEL *channel = sftp->channel;
|
LIBSSH2_CHANNEL *channel = sftp->channel;
|
||||||
LIBSSH2_SESSION *session = channel->session;
|
LIBSSH2_SESSION *session = channel->session;
|
||||||
unsigned long data_len, request_id;
|
unsigned long data_len, request_id = 0;
|
||||||
/* 25 = packet_len(4) + packet_type(1) + request_id(4) + handle_len(4) + offset(8) + length(4) */
|
/* 25 = packet_len(4) + packet_type(1) + request_id(4) + handle_len(4) +
|
||||||
|
offset(8) + length(4) */
|
||||||
ssize_t packet_len = handle->handle_len + 25;
|
ssize_t packet_len = handle->handle_len + 25;
|
||||||
unsigned char *packet, *s, *data;
|
unsigned char *packet, *s, *data;
|
||||||
static const unsigned char read_responses[2] =
|
static const unsigned char read_responses[2] =
|
||||||
@@ -975,12 +980,7 @@ libssh2_sftp_read(LIBSSH2_SFTP_HANDLE * handle, char *buffer,
|
|||||||
_libssh2_debug(session, LIBSSH2_DBG_SFTP,
|
_libssh2_debug(session, LIBSSH2_DBG_SFTP,
|
||||||
"Reading %lu bytes from SFTP handle",
|
"Reading %lu bytes from SFTP handle",
|
||||||
(unsigned long) buffer_maxlen);
|
(unsigned long) buffer_maxlen);
|
||||||
packet = LIBSSH2_ALLOC(session, packet_len);
|
packet = handle->request_packet;
|
||||||
if (!packet) {
|
|
||||||
libssh2_error(session, LIBSSH2_ERROR_ALLOC,
|
|
||||||
"Unable to allocate memory for FXP_CLOSE packet", 0);
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
sftp->read_state = libssh2_NB_state_allocated;
|
sftp->read_state = libssh2_NB_state_allocated;
|
||||||
} else {
|
} else {
|
||||||
packet = sftp->read_packet;
|
packet = sftp->read_packet;
|
||||||
@@ -996,9 +996,23 @@ libssh2_sftp_read(LIBSSH2_SFTP_HANDLE * handle, char *buffer,
|
|||||||
* So we request data by pieces.
|
* So we request data by pieces.
|
||||||
*/
|
*/
|
||||||
bytes_requested = buffer_maxlen - total_read;
|
bytes_requested = buffer_maxlen - total_read;
|
||||||
/* 10 = packet_type(1)+request_id(4)+data_length(4)+end_of_line_flag(1) */
|
/* 10 = packet_type(1) + request_id(4) + data_length(4) +
|
||||||
if (bytes_requested > LIBSSH2_SFTP_PACKET_MAXLEN - 10) {
|
end_of_line_flag(1)
|
||||||
bytes_requested = LIBSSH2_SFTP_PACKET_MAXLEN - 10;
|
|
||||||
|
10 is changed to 13 below simple because it seems there's a
|
||||||
|
"GlobalScape" SFTP server that responds with a slightly too big
|
||||||
|
buffer at times and we can apparently compensate for that by doing
|
||||||
|
this trick.
|
||||||
|
|
||||||
|
Further details on this issue:
|
||||||
|
|
||||||
|
https://sourceforge.net/mailarchive/forum.php?thread_name=9c3275a90811261517v6c0b1da2u918cc1b8370abf83%40mail.gmail.com&forum_name=libssh2-devel
|
||||||
|
|
||||||
|
http://forums.globalscape.com/tm.aspx?m=15249
|
||||||
|
|
||||||
|
*/
|
||||||
|
if (bytes_requested > LIBSSH2_SFTP_PACKET_MAXLEN - 13) {
|
||||||
|
bytes_requested = LIBSSH2_SFTP_PACKET_MAXLEN - 13;
|
||||||
}
|
}
|
||||||
#ifdef LIBSSH2_DEBUG_SFTP
|
#ifdef LIBSSH2_DEBUG_SFTP
|
||||||
_libssh2_debug(session, LIBSSH2_DBG_SFTP,
|
_libssh2_debug(session, LIBSSH2_DBG_SFTP,
|
||||||
@@ -1022,7 +1036,7 @@ libssh2_sftp_read(LIBSSH2_SFTP_HANDLE * handle, char *buffer,
|
|||||||
libssh2_htonu64(s, handle->u.file.offset);
|
libssh2_htonu64(s, handle->u.file.offset);
|
||||||
s += 8;
|
s += 8;
|
||||||
|
|
||||||
libssh2_htonu32(s, buffer_maxlen);
|
libssh2_htonu32(s, bytes_requested);
|
||||||
s += 4;
|
s += 4;
|
||||||
|
|
||||||
sftp->read_state = libssh2_NB_state_created;
|
sftp->read_state = libssh2_NB_state_created;
|
||||||
@@ -1038,9 +1052,10 @@ libssh2_sftp_read(LIBSSH2_SFTP_HANDLE * handle, char *buffer,
|
|||||||
sftp->read_total_read = total_read;
|
sftp->read_total_read = total_read;
|
||||||
return PACKET_EAGAIN;
|
return PACKET_EAGAIN;
|
||||||
} else if (packet_len != retcode) {
|
} else if (packet_len != retcode) {
|
||||||
|
/* TODO: a partial write is not a critical error when in
|
||||||
|
non-blocking mode! */
|
||||||
libssh2_error(session, LIBSSH2_ERROR_SOCKET_SEND,
|
libssh2_error(session, LIBSSH2_ERROR_SOCKET_SEND,
|
||||||
"Unable to send FXP_READ command", 0);
|
"Unable to send FXP_READ command", 0);
|
||||||
LIBSSH2_FREE(session, packet);
|
|
||||||
sftp->read_packet = NULL;
|
sftp->read_packet = NULL;
|
||||||
sftp->read_state = libssh2_NB_state_idle;
|
sftp->read_state = libssh2_NB_state_idle;
|
||||||
return -1;
|
return -1;
|
||||||
@@ -1053,14 +1068,13 @@ libssh2_sftp_read(LIBSSH2_SFTP_HANDLE * handle, char *buffer,
|
|||||||
|
|
||||||
if (sftp->read_state == libssh2_NB_state_sent) {
|
if (sftp->read_state == libssh2_NB_state_sent) {
|
||||||
retcode =
|
retcode =
|
||||||
libssh2_sftp_packet_requirev(sftp, 2, read_responses,
|
sftp_packet_requirev(sftp, 2, read_responses,
|
||||||
request_id, &data, &data_len);
|
request_id, &data, &data_len);
|
||||||
if (retcode == PACKET_EAGAIN) {
|
if (retcode == PACKET_EAGAIN) {
|
||||||
return PACKET_EAGAIN;
|
return PACKET_EAGAIN;
|
||||||
} else if (retcode) {
|
} else if (retcode) {
|
||||||
libssh2_error(session, LIBSSH2_ERROR_SOCKET_TIMEOUT,
|
libssh2_error(session, LIBSSH2_ERROR_SOCKET_TIMEOUT,
|
||||||
"Timeout waiting for status message", 0);
|
"Timeout waiting for status message", 0);
|
||||||
LIBSSH2_FREE(session, packet);
|
|
||||||
sftp->read_packet = NULL;
|
sftp->read_packet = NULL;
|
||||||
sftp->read_state = libssh2_NB_state_idle;
|
sftp->read_state = libssh2_NB_state_idle;
|
||||||
return -1;
|
return -1;
|
||||||
@@ -1072,7 +1086,6 @@ libssh2_sftp_read(LIBSSH2_SFTP_HANDLE * handle, char *buffer,
|
|||||||
switch (data[0]) {
|
switch (data[0]) {
|
||||||
case SSH_FXP_STATUS:
|
case SSH_FXP_STATUS:
|
||||||
retcode = libssh2_ntohu32(data + 5);
|
retcode = libssh2_ntohu32(data + 5);
|
||||||
LIBSSH2_FREE(session, packet);
|
|
||||||
LIBSSH2_FREE(session, data);
|
LIBSSH2_FREE(session, data);
|
||||||
sftp->read_packet = NULL;
|
sftp->read_packet = NULL;
|
||||||
sftp->read_state = libssh2_NB_state_idle;
|
sftp->read_state = libssh2_NB_state_idle;
|
||||||
@@ -1089,7 +1102,6 @@ libssh2_sftp_read(LIBSSH2_SFTP_HANDLE * handle, char *buffer,
|
|||||||
case SSH_FXP_DATA:
|
case SSH_FXP_DATA:
|
||||||
bytes_read = libssh2_ntohu32(data + 5);
|
bytes_read = libssh2_ntohu32(data + 5);
|
||||||
if (bytes_read > (data_len - 9)) {
|
if (bytes_read > (data_len - 9)) {
|
||||||
LIBSSH2_FREE(session, packet);
|
|
||||||
sftp->read_packet = NULL;
|
sftp->read_packet = NULL;
|
||||||
sftp->read_state = libssh2_NB_state_idle;
|
sftp->read_state = libssh2_NB_state_idle;
|
||||||
return -1;
|
return -1;
|
||||||
@@ -1110,7 +1122,6 @@ libssh2_sftp_read(LIBSSH2_SFTP_HANDLE * handle, char *buffer,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
LIBSSH2_FREE(session, packet);
|
|
||||||
sftp->read_packet = NULL;
|
sftp->read_packet = NULL;
|
||||||
sftp->read_state = libssh2_NB_state_idle;
|
sftp->read_state = libssh2_NB_state_idle;
|
||||||
return total_read;
|
return total_read;
|
||||||
@@ -1244,7 +1255,7 @@ libssh2_sftp_readdir_ex(LIBSSH2_SFTP_HANDLE * handle, char *buffer,
|
|||||||
}
|
}
|
||||||
|
|
||||||
retcode =
|
retcode =
|
||||||
libssh2_sftp_packet_requirev(sftp, 2, read_responses,
|
sftp_packet_requirev(sftp, 2, read_responses,
|
||||||
sftp->readdir_request_id, &data,
|
sftp->readdir_request_id, &data,
|
||||||
&data_len);
|
&data_len);
|
||||||
if (retcode == PACKET_EAGAIN) {
|
if (retcode == PACKET_EAGAIN) {
|
||||||
@@ -1331,7 +1342,8 @@ libssh2_sftp_write(LIBSSH2_SFTP_HANDLE * handle, const char *buffer,
|
|||||||
LIBSSH2_CHANNEL *channel = sftp->channel;
|
LIBSSH2_CHANNEL *channel = sftp->channel;
|
||||||
LIBSSH2_SESSION *session = channel->session;
|
LIBSSH2_SESSION *session = channel->session;
|
||||||
unsigned long data_len, retcode;
|
unsigned long data_len, retcode;
|
||||||
/* 25 = packet_len(4) + packet_type(1) + request_id(4) + handle_len(4) + offset(8) + count(4) */
|
/* 25 = packet_len(4) + packet_type(1) + request_id(4) + handle_len(4) +
|
||||||
|
offset(8) + count(4) */
|
||||||
ssize_t packet_len = handle->handle_len + count + 25;
|
ssize_t packet_len = handle->handle_len + count + 25;
|
||||||
unsigned char *s, *data;
|
unsigned char *s, *data;
|
||||||
int rc;
|
int rc;
|
||||||
@@ -1385,7 +1397,7 @@ libssh2_sftp_write(LIBSSH2_SFTP_HANDLE * handle, const char *buffer,
|
|||||||
sftp->write_state = libssh2_NB_state_sent;
|
sftp->write_state = libssh2_NB_state_sent;
|
||||||
}
|
}
|
||||||
|
|
||||||
rc = libssh2_sftp_packet_require(sftp, SSH_FXP_STATUS,
|
rc = sftp_packet_require(sftp, SSH_FXP_STATUS,
|
||||||
sftp->write_request_id, &data, &data_len);
|
sftp->write_request_id, &data, &data_len);
|
||||||
if (rc == PACKET_EAGAIN) {
|
if (rc == PACKET_EAGAIN) {
|
||||||
return PACKET_EAGAIN;
|
return PACKET_EAGAIN;
|
||||||
@@ -1468,8 +1480,8 @@ libssh2_sftp_fstat_ex(LIBSSH2_SFTP_HANDLE * handle,
|
|||||||
return PACKET_EAGAIN;
|
return PACKET_EAGAIN;
|
||||||
} else if (packet_len != rc) {
|
} else if (packet_len != rc) {
|
||||||
libssh2_error(session, LIBSSH2_ERROR_SOCKET_SEND,
|
libssh2_error(session, LIBSSH2_ERROR_SOCKET_SEND,
|
||||||
setstat ? (char *) "Unable to send FXP_FSETSTAT"
|
(setstat ? "Unable to send FXP_FSETSTAT"
|
||||||
: (char *) "Unable to send FXP_FSTAT command", 0);
|
: "Unable to send FXP_FSTAT command"), 0);
|
||||||
LIBSSH2_FREE(session, sftp->fstat_packet);
|
LIBSSH2_FREE(session, sftp->fstat_packet);
|
||||||
sftp->fstat_packet = NULL;
|
sftp->fstat_packet = NULL;
|
||||||
sftp->fstat_state = libssh2_NB_state_idle;
|
sftp->fstat_state = libssh2_NB_state_idle;
|
||||||
@@ -1481,7 +1493,7 @@ libssh2_sftp_fstat_ex(LIBSSH2_SFTP_HANDLE * handle,
|
|||||||
sftp->fstat_state = libssh2_NB_state_sent;
|
sftp->fstat_state = libssh2_NB_state_sent;
|
||||||
}
|
}
|
||||||
|
|
||||||
rc = libssh2_sftp_packet_requirev(sftp, 2, fstat_responses,
|
rc = sftp_packet_requirev(sftp, 2, fstat_responses,
|
||||||
sftp->fstat_request_id, &data,
|
sftp->fstat_request_id, &data,
|
||||||
&data_len);
|
&data_len);
|
||||||
if (rc == PACKET_EAGAIN) {
|
if (rc == PACKET_EAGAIN) {
|
||||||
@@ -1528,6 +1540,17 @@ libssh2_sftp_seek(LIBSSH2_SFTP_HANDLE * handle, size_t offset)
|
|||||||
|
|
||||||
/* }}} */
|
/* }}} */
|
||||||
|
|
||||||
|
/* {{{ libssh2_sftp_seek64
|
||||||
|
* Set the read/write pointer to an arbitrary position within the file
|
||||||
|
*/
|
||||||
|
LIBSSH2_API void
|
||||||
|
libssh2_sftp_seek64(LIBSSH2_SFTP_HANDLE * handle, libssh2_uint64_t offset)
|
||||||
|
{
|
||||||
|
handle->u.file.offset = offset;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* }}} */
|
||||||
|
|
||||||
/* {{{ libssh2_sftp_tell
|
/* {{{ libssh2_sftp_tell
|
||||||
* Return the current read/write pointer's offset
|
* Return the current read/write pointer's offset
|
||||||
*/
|
*/
|
||||||
@@ -1537,6 +1560,15 @@ libssh2_sftp_tell(LIBSSH2_SFTP_HANDLE * handle)
|
|||||||
return handle->u.file.offset;
|
return handle->u.file.offset;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* {{{ libssh2_sftp_tell64
|
||||||
|
* Return the current read/write pointer's offset
|
||||||
|
*/
|
||||||
|
LIBSSH2_API libssh2_uint64_t
|
||||||
|
libssh2_sftp_tell64(LIBSSH2_SFTP_HANDLE * handle)
|
||||||
|
{
|
||||||
|
return handle->u.file.offset;
|
||||||
|
}
|
||||||
|
|
||||||
/* }}} */
|
/* }}} */
|
||||||
|
|
||||||
|
|
||||||
@@ -1600,7 +1632,7 @@ libssh2_sftp_close_handle(LIBSSH2_SFTP_HANDLE * handle)
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (handle->close_state == libssh2_NB_state_sent) {
|
if (handle->close_state == libssh2_NB_state_sent) {
|
||||||
rc = libssh2_sftp_packet_require(sftp, SSH_FXP_STATUS,
|
rc = sftp_packet_require(sftp, SSH_FXP_STATUS,
|
||||||
handle->close_request_id, &data,
|
handle->close_request_id, &data,
|
||||||
&data_len);
|
&data_len);
|
||||||
if (rc == PACKET_EAGAIN) {
|
if (rc == PACKET_EAGAIN) {
|
||||||
@@ -1640,7 +1672,6 @@ libssh2_sftp_close_handle(LIBSSH2_SFTP_HANDLE * handle)
|
|||||||
|
|
||||||
handle->close_state = libssh2_NB_state_idle;
|
handle->close_state = libssh2_NB_state_idle;
|
||||||
|
|
||||||
LIBSSH2_FREE(session, handle->handle);
|
|
||||||
LIBSSH2_FREE(session, handle);
|
LIBSSH2_FREE(session, handle);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
@@ -1711,12 +1742,13 @@ libssh2_sftp_unlink_ex(LIBSSH2_SFTP * sftp, const char *filename,
|
|||||||
sftp->unlink_state = libssh2_NB_state_sent;
|
sftp->unlink_state = libssh2_NB_state_sent;
|
||||||
}
|
}
|
||||||
|
|
||||||
rc = libssh2_sftp_packet_require(sftp, SSH_FXP_STATUS,
|
rc = sftp_packet_require(sftp, SSH_FXP_STATUS,
|
||||||
sftp->unlink_request_id, &data,
|
sftp->unlink_request_id, &data,
|
||||||
&data_len);
|
&data_len);
|
||||||
if (rc == PACKET_EAGAIN) {
|
if (rc == PACKET_EAGAIN) {
|
||||||
return PACKET_EAGAIN;
|
return PACKET_EAGAIN;
|
||||||
} else if (rc) {
|
}
|
||||||
|
else if (rc) {
|
||||||
libssh2_error(session, LIBSSH2_ERROR_SOCKET_TIMEOUT,
|
libssh2_error(session, LIBSSH2_ERROR_SOCKET_TIMEOUT,
|
||||||
"Timeout waiting for status message", 0);
|
"Timeout waiting for status message", 0);
|
||||||
sftp->unlink_state = libssh2_NB_state_idle;
|
sftp->unlink_state = libssh2_NB_state_idle;
|
||||||
@@ -1820,7 +1852,7 @@ libssh2_sftp_rename_ex(LIBSSH2_SFTP * sftp, const char *source_filename,
|
|||||||
sftp->rename_state = libssh2_NB_state_sent;
|
sftp->rename_state = libssh2_NB_state_sent;
|
||||||
}
|
}
|
||||||
|
|
||||||
rc = libssh2_sftp_packet_require(sftp, SSH_FXP_STATUS,
|
rc = sftp_packet_require(sftp, SSH_FXP_STATUS,
|
||||||
sftp->rename_request_id, &data,
|
sftp->rename_request_id, &data,
|
||||||
&data_len);
|
&data_len);
|
||||||
if (rc == PACKET_EAGAIN) {
|
if (rc == PACKET_EAGAIN) {
|
||||||
@@ -1936,7 +1968,7 @@ libssh2_sftp_mkdir_ex(LIBSSH2_SFTP * sftp, const char *path,
|
|||||||
sftp->mkdir_packet = NULL;
|
sftp->mkdir_packet = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
rc = libssh2_sftp_packet_require(sftp, SSH_FXP_STATUS, request_id, &data,
|
rc = sftp_packet_require(sftp, SSH_FXP_STATUS, request_id, &data,
|
||||||
&data_len);
|
&data_len);
|
||||||
if (rc == PACKET_EAGAIN) {
|
if (rc == PACKET_EAGAIN) {
|
||||||
return PACKET_EAGAIN;
|
return PACKET_EAGAIN;
|
||||||
@@ -2023,7 +2055,7 @@ libssh2_sftp_rmdir_ex(LIBSSH2_SFTP * sftp, const char *path,
|
|||||||
sftp->rmdir_state = libssh2_NB_state_sent;
|
sftp->rmdir_state = libssh2_NB_state_sent;
|
||||||
}
|
}
|
||||||
|
|
||||||
rc = libssh2_sftp_packet_require(sftp, SSH_FXP_STATUS,
|
rc = sftp_packet_require(sftp, SSH_FXP_STATUS,
|
||||||
sftp->rmdir_request_id, &data, &data_len);
|
sftp->rmdir_request_id, &data, &data_len);
|
||||||
if (rc == PACKET_EAGAIN) {
|
if (rc == PACKET_EAGAIN) {
|
||||||
return PACKET_EAGAIN;
|
return PACKET_EAGAIN;
|
||||||
@@ -2133,7 +2165,7 @@ libssh2_sftp_stat_ex(LIBSSH2_SFTP * sftp, const char *path,
|
|||||||
sftp->stat_state = libssh2_NB_state_sent;
|
sftp->stat_state = libssh2_NB_state_sent;
|
||||||
}
|
}
|
||||||
|
|
||||||
rc = libssh2_sftp_packet_requirev(sftp, 2, stat_responses,
|
rc = sftp_packet_requirev(sftp, 2, stat_responses,
|
||||||
sftp->stat_request_id, &data, &data_len);
|
sftp->stat_request_id, &data, &data_len);
|
||||||
if (rc == PACKET_EAGAIN) {
|
if (rc == PACKET_EAGAIN) {
|
||||||
return PACKET_EAGAIN;
|
return PACKET_EAGAIN;
|
||||||
@@ -2200,8 +2232,8 @@ libssh2_sftp_symlink_ex(LIBSSH2_SFTP * sftp, const char *path,
|
|||||||
s = sftp->symlink_packet = LIBSSH2_ALLOC(session, packet_len);
|
s = sftp->symlink_packet = LIBSSH2_ALLOC(session, packet_len);
|
||||||
if (!sftp->symlink_packet) {
|
if (!sftp->symlink_packet) {
|
||||||
libssh2_error(session, LIBSSH2_ERROR_ALLOC,
|
libssh2_error(session, LIBSSH2_ERROR_ALLOC,
|
||||||
"Unable to allocate memory for SYMLINK/READLINK/REALPATH packet",
|
"Unable to allocate memory for SYMLINK/READLINK"
|
||||||
0);
|
"/REALPATH packet", 0);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -2263,12 +2295,13 @@ libssh2_sftp_symlink_ex(LIBSSH2_SFTP * sftp, const char *path,
|
|||||||
sftp->symlink_state = libssh2_NB_state_sent;
|
sftp->symlink_state = libssh2_NB_state_sent;
|
||||||
}
|
}
|
||||||
|
|
||||||
rc = libssh2_sftp_packet_requirev(sftp, 2, link_responses,
|
rc = sftp_packet_requirev(sftp, 2, link_responses,
|
||||||
sftp->symlink_request_id, &data,
|
sftp->symlink_request_id, &data,
|
||||||
&data_len);
|
&data_len);
|
||||||
if (rc == PACKET_EAGAIN) {
|
if (rc == PACKET_EAGAIN) {
|
||||||
return PACKET_EAGAIN;
|
return PACKET_EAGAIN;
|
||||||
} else if (rc) {
|
}
|
||||||
|
else if (rc) {
|
||||||
libssh2_error(session, LIBSSH2_ERROR_SOCKET_TIMEOUT,
|
libssh2_error(session, LIBSSH2_ERROR_SOCKET_TIMEOUT,
|
||||||
"Timeout waiting for status message", 0);
|
"Timeout waiting for status message", 0);
|
||||||
sftp->symlink_state = libssh2_NB_state_idle;
|
sftp->symlink_state = libssh2_NB_state_idle;
|
||||||
|
374
src/sshentry.c
Normal file
374
src/sshentry.c
Normal file
@@ -0,0 +1,374 @@
|
|||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <ctype.h>
|
||||||
|
|
||||||
|
#include "libssh2_priv.h"
|
||||||
|
|
||||||
|
static int
|
||||||
|
ssh_host_parse_hostnames (LIBSSH2_SESSION * session,
|
||||||
|
LIBSSH2_KNOWNHOSTS * s,
|
||||||
|
char *line,
|
||||||
|
char *end
|
||||||
|
);
|
||||||
|
|
||||||
|
static int
|
||||||
|
ssh_host_parse_key (LIBSSH2_SESSION * session,
|
||||||
|
LIBSSH2_KNOWNHOSTS * s,
|
||||||
|
char *line,
|
||||||
|
int is_base64_encoded
|
||||||
|
);
|
||||||
|
|
||||||
|
/* Returns zero if successful, > zero for malformed data, < 0 not supported. */
|
||||||
|
LIBSSH2_API int
|
||||||
|
libssh2_new_host_entry(LIBSSH2_SESSION * session,
|
||||||
|
LIBSSH2_KNOWNHOSTS ** s,
|
||||||
|
char *line)
|
||||||
|
{
|
||||||
|
char *tmp = NULL;
|
||||||
|
LIBSSH2_KNOWNHOSTS *t = NULL;
|
||||||
|
int i;
|
||||||
|
|
||||||
|
if (line == NULL || *line == 0)
|
||||||
|
return 1;
|
||||||
|
if (s == NULL)
|
||||||
|
return 2;
|
||||||
|
|
||||||
|
tmp = strchr (line, ' ');
|
||||||
|
if (tmp == NULL)
|
||||||
|
return 3;
|
||||||
|
|
||||||
|
|
||||||
|
t = (LIBSSH2_KNOWNHOSTS *)
|
||||||
|
LIBSSH2_ALLOC(session, sizeof(LIBSSH2_KNOWNHOSTS));
|
||||||
|
|
||||||
|
t->hostname_line = NULL;
|
||||||
|
t->hostnames = NULL;
|
||||||
|
t->hostnames_size = t->bits = t->exponent = -1;
|
||||||
|
t->modulus = NULL;
|
||||||
|
t->modulus_length = -1;
|
||||||
|
t->ssh_version = -1;
|
||||||
|
t->md5 = NULL;
|
||||||
|
|
||||||
|
i = ssh_host_parse_hostnames (session, t, line, tmp);
|
||||||
|
if (i != 0) {
|
||||||
|
libssh2_free_host_entry (session, t);
|
||||||
|
return ((i > 0) ? 4 : -1);
|
||||||
|
}
|
||||||
|
|
||||||
|
line = tmp + 1;
|
||||||
|
tmp = strchr (line, ' ');
|
||||||
|
if (tmp != NULL)
|
||||||
|
tmp = strchr (tmp + 1, ' ');
|
||||||
|
|
||||||
|
i = ssh_host_parse_key (session, t, line, tmp == NULL ? 1 : 0);
|
||||||
|
if (i != 0) {
|
||||||
|
libssh2_free_host_entry (session, t);
|
||||||
|
return ((i > 0) ? 5 : -2);
|
||||||
|
}
|
||||||
|
|
||||||
|
*s = t;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
ssh_host_parse_hostnames(LIBSSH2_SESSION * session,
|
||||||
|
LIBSSH2_KNOWNHOSTS * s,
|
||||||
|
char *line,
|
||||||
|
char *end)
|
||||||
|
{
|
||||||
|
char *start;
|
||||||
|
char *comma = NULL;
|
||||||
|
int i;
|
||||||
|
|
||||||
|
/* TODO: we don't handle the hashed name format because the hashing
|
||||||
|
* mechanism isnt defined (at least based on the man page)
|
||||||
|
*/
|
||||||
|
if (*line == '|')
|
||||||
|
return -1;
|
||||||
|
if (line == end || *line == ' ')
|
||||||
|
return 1;
|
||||||
|
|
||||||
|
s->hostname_line = (char *) LIBSSH2_ALLOC (session, (end - line) + 1);
|
||||||
|
strncpy (s->hostname_line, line, (end - line) + 1);
|
||||||
|
start = end = s->hostname_line + (end - line);
|
||||||
|
*end = 0;
|
||||||
|
|
||||||
|
s->hostnames_size = 1;
|
||||||
|
comma = s->hostname_line;
|
||||||
|
while ((comma = strchr (comma, ',')) != NULL) {
|
||||||
|
comma++;
|
||||||
|
if (*comma == ',' || *comma == 0) {
|
||||||
|
LIBSSH2_FREE (session, s->hostname_line);
|
||||||
|
s->hostname_line = NULL;
|
||||||
|
return 2;
|
||||||
|
}
|
||||||
|
s->hostnames_size++;
|
||||||
|
}
|
||||||
|
s->hostnames = (char **) LIBSSH2_ALLOC
|
||||||
|
(session, sizeof (char *) * s->hostnames_size);
|
||||||
|
|
||||||
|
start = comma = s->hostname_line;
|
||||||
|
i = 0;
|
||||||
|
while ((comma = strchr (comma, ',')) != NULL) {
|
||||||
|
*comma = 0;
|
||||||
|
s->hostnames[i] = start;
|
||||||
|
|
||||||
|
comma++;
|
||||||
|
start = comma;
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
s->hostnames[i] = start;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Returns the number of bytes read or -1. */
|
||||||
|
static int
|
||||||
|
ssh_proto_str_read(LIBSSH2_SESSION * session,
|
||||||
|
char *line,
|
||||||
|
char **val,
|
||||||
|
char *end
|
||||||
|
)
|
||||||
|
{
|
||||||
|
unsigned int len;
|
||||||
|
|
||||||
|
if (line + 4 > end)
|
||||||
|
return -1;
|
||||||
|
len = (line[0] << 24) + (line[1] << 16) + (line[2] << 8) + line[3];
|
||||||
|
if (line + 4 + len > end)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
*val = LIBSSH2_ALLOC (session, len);
|
||||||
|
memcpy (*val, line + 4, len);
|
||||||
|
return len + 4;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
ssh_host_parse_key(LIBSSH2_SESSION * session,
|
||||||
|
LIBSSH2_KNOWNHOSTS * s,
|
||||||
|
char *line,
|
||||||
|
int is_base64_encoded)
|
||||||
|
{
|
||||||
|
int i, j;
|
||||||
|
char *tmp, *tmp2;
|
||||||
|
/* workaround for the MD5 stuff */
|
||||||
|
libssh2_md5_ctx ctx;
|
||||||
|
|
||||||
|
/* the bits, exponent, modulus format */
|
||||||
|
if (is_base64_encoded == 0) {
|
||||||
|
s->ssh_version = 1;
|
||||||
|
s->key_type = 0;
|
||||||
|
if (!isdigit (*line))
|
||||||
|
return -1;
|
||||||
|
if (sscanf (line, "%hu %hu ", &(s->bits), &(s->exponent)) != 2)
|
||||||
|
return -2;
|
||||||
|
/* TODO:
|
||||||
|
* There's probably an acceptable range...
|
||||||
|
*/
|
||||||
|
if (s->bits <= 0 || s->exponent <= 0)
|
||||||
|
return 1;
|
||||||
|
|
||||||
|
line = strchr (line, ' ');
|
||||||
|
if (line == NULL)
|
||||||
|
return -3;
|
||||||
|
line++;
|
||||||
|
line = strchr (line, ' ');
|
||||||
|
if (line == NULL)
|
||||||
|
return -4;
|
||||||
|
line++;
|
||||||
|
/* TODO:
|
||||||
|
* figure out what format modulus is in since its not clear
|
||||||
|
* from the man page
|
||||||
|
*/
|
||||||
|
return -5;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
s->ssh_version = 2;
|
||||||
|
/* we only handle the rsa type */
|
||||||
|
if (strstr (line, "ssh-rsa") != line)
|
||||||
|
return -6;
|
||||||
|
s->key_type = 0;
|
||||||
|
line += 7;
|
||||||
|
if (*line != ' ')
|
||||||
|
return 2;
|
||||||
|
line++;
|
||||||
|
i = 0;
|
||||||
|
while (*line) {
|
||||||
|
if ((line[i] >= 0x30 && line[i] <= 0x39) ||
|
||||||
|
(line[i] >= 0x41 && line[i] <= 0x5a) ||
|
||||||
|
(line[i] >= 0x61 && line[i] <= 0x7a) ||
|
||||||
|
(line[i] == '+') || (line[i] == '/') || (line[i] == '='))
|
||||||
|
i++;
|
||||||
|
else
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (i == 0)
|
||||||
|
return 3;
|
||||||
|
tmp = LIBSSH2_ALLOC (session, sizeof (char) * (i + 5));
|
||||||
|
strncpy (tmp, line, i);
|
||||||
|
/* this should hopefully avoid any issues with reading
|
||||||
|
* past the array if its malformed */
|
||||||
|
tmp[i] = tmp[i + 1] = tmp[i + 2] = tmp[i + 3] = tmp[i + 4] = 0;
|
||||||
|
|
||||||
|
{
|
||||||
|
/* TODO: rework the api interface instead of making a local
|
||||||
|
instance */
|
||||||
|
i = libssh2_base64_decode(session, &tmp2, (unsigned int *)&j,
|
||||||
|
tmp, strlen(tmp));
|
||||||
|
LIBSSH2_FREE(session, tmp);
|
||||||
|
if (i != 0)
|
||||||
|
return 4;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/* printf("Decode Size: %d\n", i); */
|
||||||
|
/* free (tmp); */
|
||||||
|
|
||||||
|
|
||||||
|
#if LIBSSH2_MD5
|
||||||
|
s->md5 = LIBSSH2_ALLOC (session, 16);
|
||||||
|
|
||||||
|
libssh2_md5_init (&ctx);
|
||||||
|
libssh2_md5_update (ctx, tmp2, j);
|
||||||
|
libssh2_md5_final (ctx, s->md5);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
line = tmp2;
|
||||||
|
i = ssh_proto_str_read (session, line, &tmp, tmp2 + j);
|
||||||
|
if (i < 0) {
|
||||||
|
LIBSSH2_FREE (session, tmp2);
|
||||||
|
return 5;
|
||||||
|
}
|
||||||
|
/* TODO: verify that its ssh-rsa -- its the only one
|
||||||
|
* supported
|
||||||
|
*/
|
||||||
|
if (!(i == 11 && tmp[0] == 's' && tmp[1] == 's' &&
|
||||||
|
tmp[2] == 'h' && tmp[3] == '-' && tmp[4] == 'r' &&
|
||||||
|
tmp[5] == 's' && tmp[6] == 'a')) {
|
||||||
|
free (tmp);
|
||||||
|
free (tmp2);
|
||||||
|
return 8;
|
||||||
|
}
|
||||||
|
|
||||||
|
LIBSSH2_FREE (session, tmp);
|
||||||
|
line += i;
|
||||||
|
i = ssh_proto_str_read (session, line, &tmp, tmp2 + j);
|
||||||
|
if (i < 0) {
|
||||||
|
LIBSSH2_FREE (session, tmp2);
|
||||||
|
return 6;
|
||||||
|
}
|
||||||
|
/* TODO: verify that the exponent is valid */
|
||||||
|
if (i == 5)
|
||||||
|
s->exponent = (unsigned short) ((unsigned char) *tmp);
|
||||||
|
else {
|
||||||
|
LIBSSH2_FREE (session, tmp);
|
||||||
|
LIBSSH2_FREE (session, tmp2);
|
||||||
|
return 9;
|
||||||
|
}
|
||||||
|
|
||||||
|
LIBSSH2_FREE (session, tmp);
|
||||||
|
line += i;
|
||||||
|
i = ssh_proto_str_read (session, line, &tmp, tmp2 + j);
|
||||||
|
if (i < 0) {
|
||||||
|
LIBSSH2_FREE (session, tmp2);
|
||||||
|
return 7;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* TODO: the modulus may need to be converted to
|
||||||
|
* big integer format
|
||||||
|
*/
|
||||||
|
s->modulus_length = i - 4;
|
||||||
|
s->modulus = tmp;
|
||||||
|
|
||||||
|
s->bits = (s->modulus_length - 1) * 8;
|
||||||
|
|
||||||
|
LIBSSH2_FREE (session, tmp2);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
LIBSSH2_API void
|
||||||
|
libssh2_free_host_entry(LIBSSH2_SESSION * session, LIBSSH2_KNOWNHOSTS * s)
|
||||||
|
{
|
||||||
|
/* int i; */
|
||||||
|
if (s == NULL)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (s->hostname_line != NULL) {
|
||||||
|
LIBSSH2_FREE (session, s->hostname_line);
|
||||||
|
s->hostname_line = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (s->hostnames != NULL && s->hostnames_size > 0) {
|
||||||
|
LIBSSH2_FREE (session, s->hostnames);
|
||||||
|
s->hostnames = NULL;
|
||||||
|
}
|
||||||
|
s->hostnames_size = s->bits = s->exponent = -1;
|
||||||
|
|
||||||
|
if (s->modulus != NULL) {
|
||||||
|
LIBSSH2_FREE (session, s->modulus);
|
||||||
|
s->modulus = NULL;
|
||||||
|
}
|
||||||
|
s->modulus_length = -1;
|
||||||
|
s->ssh_version = -1;
|
||||||
|
|
||||||
|
if (s->md5 != NULL) {
|
||||||
|
LIBSSH2_FREE (session, s->md5);
|
||||||
|
s->md5 = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
LIBSSH2_FREE (session, s);
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef SSH_HOSTNAME_TESTS
|
||||||
|
int
|
||||||
|
ssh_unit_tests (int argc, char **argv)
|
||||||
|
{
|
||||||
|
char *l[] = {
|
||||||
|
"closenet,...,192.0.2.53 1024 37 159...93 closenet.example.net",
|
||||||
|
"cvs.example.net,192.0.2.10 ssh-rsa AAAA1234.....=",
|
||||||
|
" cvs.example.net,192.0.2.10 ssh-rsa AAAA1234.....=",
|
||||||
|
"",
|
||||||
|
",",
|
||||||
|
"f, ",
|
||||||
|
"cvs.example.net ssh-rsa AAAA1234.....=",
|
||||||
|
"192.168.30.118 ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAQEAwWVqxKm2Biwilakq9Ex8/tzHVQjRrzEkwlrWTDneptodVgqAzXUFQSa6Oj9AwzdDPhKe71vTv7RhXYg0ZvB1a5dIkzgCdoF/mIuTb80LvK7f0NxCaAHWODuHbwlJeMmjHV0WFsjsdOf690fPqeinD/8jfBQB950M1K3Qesib9H75gsnawF06MzZ52nC1HHi8mG2tGy2PMyP+mJs7KN1v4T+nobZ10ePe1dMqYXMdro/PB0JQmuGL7bBR5GRDEkK6nFcp2HsvuzXSeWZJcmWDdo+1n0cNg2th5VEIxrrFG5iy0CA2AXVPMqkf3VrAXGXV66dJTGtBqZ5GoxJCxDgW6w==",
|
||||||
|
"|1|JfKTdBh7rNbXkVAQCRp4OQoPfmI=|USECr3SWf1JUPsms5AqfD5QfxkM= ssh-rsaAAAA1234.....="
|
||||||
|
};
|
||||||
|
int s;
|
||||||
|
int cases = sizeof (l) / sizeof (char *);
|
||||||
|
|
||||||
|
if (argc == 2) {
|
||||||
|
s = atoi (argv[1]);
|
||||||
|
if (s >= 0 && s < cases) {
|
||||||
|
LIBSSH2_KNOWNHOSTS *x = NULL;
|
||||||
|
printf ("%d\n", s = new_ssh_host_entry (&x, l[s]));
|
||||||
|
libssh2_free_host_entry (x);
|
||||||
|
return s;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/** Returns 0 for a match, non-zero otherwise. */
|
||||||
|
LIBSSH2_API int
|
||||||
|
libssh2_host_entry_match(LIBSSH2_KNOWNHOSTS * x, char *host)
|
||||||
|
{
|
||||||
|
/* TODO: Add pattern matching and/or DNS matching against
|
||||||
|
* to entries found in x
|
||||||
|
*/
|
||||||
|
int i;
|
||||||
|
if (host == NULL || x == NULL)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
/* FIXME: this should use a case-insensitive compare as dns hostnames
|
||||||
|
* are generally case insensitive anyways
|
||||||
|
*/
|
||||||
|
for (i = 0; i < x->hostnames_size; i++)
|
||||||
|
if (!strcmp (x->hostnames[i], host))
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
}
|
@@ -269,6 +269,40 @@ libssh2_packet_read(LIBSSH2_SESSION * session)
|
|||||||
int blocksize;
|
int blocksize;
|
||||||
int encrypted = 1;
|
int encrypted = 1;
|
||||||
|
|
||||||
|
int status;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* All channels, systems, subsystems, etc eventually make it down here
|
||||||
|
* when looking for more incoming data. If a key exchange is going on
|
||||||
|
* (LIBSSH2_STATE_EXCHANGING_KEYS bit is set) then the remote end
|
||||||
|
* will ONLY send key exchange related traffic. In non-blocking mode,
|
||||||
|
* there is a chance to break out of the kex_exchange function with an
|
||||||
|
* EAGAIN status, and never come back to it. If LIBSSH2_STATE_EXCHANGING_KEYS
|
||||||
|
* is active, then we must redirect to the key exchange. However,
|
||||||
|
* if kex_exchange is active (as in it is the one that calls this execution
|
||||||
|
* of packet_read, then don't redirect, as that would be an infinite loop!
|
||||||
|
*/
|
||||||
|
|
||||||
|
if (session->state & LIBSSH2_STATE_EXCHANGING_KEYS &&
|
||||||
|
!(session->state & LIBSSH2_STATE_KEX_ACTIVE)) {
|
||||||
|
|
||||||
|
/* Whoever wants a packet won't get anything until the key re-exchange
|
||||||
|
* is done!
|
||||||
|
*/
|
||||||
|
_libssh2_debug(session, LIBSSH2_DBG_TRANS, "Redirecting into the"
|
||||||
|
" key re-exchange");
|
||||||
|
status = libssh2_kex_exchange(session, 1, &session->startup_key_state);
|
||||||
|
if (status == PACKET_EAGAIN) {
|
||||||
|
libssh2_error(session, LIBSSH2_ERROR_EAGAIN,
|
||||||
|
"Would block exchanging encryption keys", 0);
|
||||||
|
return PACKET_EAGAIN;
|
||||||
|
} else if (status) {
|
||||||
|
libssh2_error(session, LIBSSH2_ERROR_KEX_FAILURE,
|
||||||
|
"Unable to exchange encryption keys",0);
|
||||||
|
return LIBSSH2_ERROR_KEX_FAILURE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* =============================== NOTE ===============================
|
* =============================== NOTE ===============================
|
||||||
* I know this is very ugly and not a really good use of "goto", but
|
* I know this is very ugly and not a really good use of "goto", but
|
||||||
@@ -351,6 +385,8 @@ libssh2_packet_read(LIBSSH2_SESSION * session)
|
|||||||
}
|
}
|
||||||
#endif /* WIN32 */
|
#endif /* WIN32 */
|
||||||
if ((nread < 0) && (errno == EAGAIN)) {
|
if ((nread < 0) && (errno == EAGAIN)) {
|
||||||
|
session->socket_block_directions =
|
||||||
|
LIBSSH2_SESSION_BLOCK_INBOUND;
|
||||||
return PACKET_EAGAIN;
|
return PACKET_EAGAIN;
|
||||||
}
|
}
|
||||||
return PACKET_FAIL;
|
return PACKET_FAIL;
|
||||||
@@ -527,8 +563,21 @@ libssh2_packet_read(LIBSSH2_SESSION * session)
|
|||||||
libssh2_packet_read_point1:
|
libssh2_packet_read_point1:
|
||||||
rc = fullpacket(session, encrypted);
|
rc = fullpacket(session, encrypted);
|
||||||
if (rc == PACKET_EAGAIN) {
|
if (rc == PACKET_EAGAIN) {
|
||||||
|
|
||||||
|
if (session->packAdd_state != libssh2_NB_state_idle)
|
||||||
|
{
|
||||||
|
/* fullpacket only returns PACKET_EAGAIN if
|
||||||
|
* libssh2_packet_add returns PACKET_EAGAIN. If that
|
||||||
|
* returns PACKET_EAGAIN but the packAdd_state is idle,
|
||||||
|
* then the packet has been added to the brigade, but some
|
||||||
|
* immediate action that was taken based on the packet
|
||||||
|
* type (such as key re-exchange) is not yet complete.
|
||||||
|
* Clear the way for a new packet to be read in.
|
||||||
|
*/
|
||||||
session->readPack_encrypted = encrypted;
|
session->readPack_encrypted = encrypted;
|
||||||
session->readPack_state = libssh2_NB_state_jump1;
|
session->readPack_state = libssh2_NB_state_jump1;
|
||||||
|
}
|
||||||
|
|
||||||
return PACKET_EAGAIN;
|
return PACKET_EAGAIN;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -543,8 +592,6 @@ libssh2_packet_read(LIBSSH2_SESSION * session)
|
|||||||
|
|
||||||
/* }}} */
|
/* }}} */
|
||||||
|
|
||||||
#ifndef OLDSEND
|
|
||||||
|
|
||||||
static libssh2pack_t
|
static libssh2pack_t
|
||||||
send_existing(LIBSSH2_SESSION * session, unsigned char *data,
|
send_existing(LIBSSH2_SESSION * session, unsigned char *data,
|
||||||
unsigned long data_len, ssize_t * ret)
|
unsigned long data_len, ssize_t * ret)
|
||||||
@@ -587,6 +634,7 @@ send_existing(LIBSSH2_SESSION * session, unsigned char *data,
|
|||||||
/* send failure! */
|
/* send failure! */
|
||||||
return PACKET_FAIL;
|
return PACKET_FAIL;
|
||||||
}
|
}
|
||||||
|
session->socket_block_directions = LIBSSH2_SESSION_BLOCK_OUTBOUND;
|
||||||
return PACKET_EAGAIN;
|
return PACKET_EAGAIN;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -605,6 +653,10 @@ send_existing(LIBSSH2_SESSION * session, unsigned char *data,
|
|||||||
* call this function again as soon as it is likely that more data can be
|
* call this function again as soon as it is likely that more data can be
|
||||||
* sent, and this function should then be called with the same argument set
|
* 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.
|
* (same data pointer and same data_len) until zero or failure is returned.
|
||||||
|
*
|
||||||
|
* NOTE: this function does not verify that 'data_len' is less than ~35000
|
||||||
|
* which is what all implementations should support at least as packet size.
|
||||||
|
* (RFC4253 section 6.1)
|
||||||
*/
|
*/
|
||||||
int
|
int
|
||||||
libssh2_packet_write(LIBSSH2_SESSION * session, unsigned char *data,
|
libssh2_packet_write(LIBSSH2_SESSION * session, unsigned char *data,
|
||||||
@@ -641,9 +693,10 @@ libssh2_packet_write(LIBSSH2_SESSION * session, unsigned char *data,
|
|||||||
|
|
||||||
/* check if we should compress */
|
/* check if we should compress */
|
||||||
if (encrypted && strcmp(session->local.comp->name, "none")) {
|
if (encrypted && strcmp(session->local.comp->name, "none")) {
|
||||||
if (session->local.comp->
|
if (session->local.comp->comp(session, 1, &data, &data_len,
|
||||||
comp(session, 1, &data, &data_len, LIBSSH2_PACKET_MAXCOMP,
|
LIBSSH2_PACKET_MAXCOMP,
|
||||||
&free_data, data, data_len, &session->local.comp_abstract)) {
|
&free_data, data, data_len,
|
||||||
|
&session->local.comp_abstract)) {
|
||||||
return PACKET_COMPRESS; /* compression failure */
|
return PACKET_COMPRESS; /* compression failure */
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -722,8 +775,8 @@ libssh2_packet_write(LIBSSH2_SESSION * session, unsigned char *data,
|
|||||||
The MAC field is not encrypted. */
|
The MAC field is not encrypted. */
|
||||||
for(i = 0; i < packet_length; i += session->local.crypt->blocksize) {
|
for(i = 0; i < packet_length; i += session->local.crypt->blocksize) {
|
||||||
unsigned char *ptr = &p->outbuf[i];
|
unsigned char *ptr = &p->outbuf[i];
|
||||||
if (session->local.crypt->
|
if (session->local.crypt->crypt(session, ptr,
|
||||||
crypt(session, ptr, &session->local.crypt_abstract))
|
&session->local.crypt_abstract))
|
||||||
return PACKET_FAIL; /* encryption failure */
|
return PACKET_FAIL; /* encryption failure */
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -739,6 +792,7 @@ libssh2_packet_write(LIBSSH2_SESSION * session, unsigned char *data,
|
|||||||
if (ret != total_length) {
|
if (ret != total_length) {
|
||||||
if ((ret > 0) || ((ret == -1) && (errno == EAGAIN))) {
|
if ((ret > 0) || ((ret == -1) && (errno == EAGAIN))) {
|
||||||
/* the whole packet could not be sent, save the rest */
|
/* the whole packet could not be sent, save the rest */
|
||||||
|
session->socket_block_directions = LIBSSH2_SESSION_BLOCK_OUTBOUND;
|
||||||
p->odata = orgdata;
|
p->odata = orgdata;
|
||||||
p->olen = orgdata_len;
|
p->olen = orgdata_len;
|
||||||
p->osent = (ret == -1) ? 0 : ret;
|
p->osent = (ret == -1) ? 0 : ret;
|
||||||
@@ -758,4 +812,4 @@ libssh2_packet_write(LIBSSH2_SESSION * session, unsigned char *data,
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* }}} */
|
/* }}} */
|
||||||
#endif
|
|
||||||
|
@@ -149,7 +149,9 @@ libssh2_userauth_list(LIBSSH2_SESSION * session, const char *username,
|
|||||||
}
|
}
|
||||||
|
|
||||||
methods_len = libssh2_ntohu32(session->userauth_list_data + 1);
|
methods_len = libssh2_ntohu32(session->userauth_list_data + 1);
|
||||||
memcpy(session->userauth_list_data, session->userauth_list_data + 5,
|
|
||||||
|
/* Do note that the memory areas overlap! */
|
||||||
|
memmove(session->userauth_list_data, session->userauth_list_data + 5,
|
||||||
methods_len);
|
methods_len);
|
||||||
session->userauth_list_data[methods_len] = '\0';
|
session->userauth_list_data[methods_len] = '\0';
|
||||||
_libssh2_debug(session, LIBSSH2_DBG_AUTH, "Permitted auth methods: %s",
|
_libssh2_debug(session, LIBSSH2_DBG_AUTH, "Permitted auth methods: %s",
|
||||||
@@ -588,17 +590,19 @@ libssh2_userauth_hostbased_fromfile_ex(LIBSSH2_SESSION * session,
|
|||||||
const char *local_username,
|
const char *local_username,
|
||||||
unsigned int local_username_len)
|
unsigned int local_username_len)
|
||||||
{
|
{
|
||||||
const LIBSSH2_HOSTKEY_METHOD *privkeyobj;
|
|
||||||
void *abstract;
|
|
||||||
unsigned char buf[5];
|
|
||||||
struct iovec datavec[4];
|
|
||||||
unsigned char *pubkeydata, *sig;
|
|
||||||
static const unsigned char reply_codes[3] =
|
static const unsigned char reply_codes[3] =
|
||||||
{ SSH_MSG_USERAUTH_SUCCESS, SSH_MSG_USERAUTH_FAILURE, 0 };
|
{ SSH_MSG_USERAUTH_SUCCESS, SSH_MSG_USERAUTH_FAILURE, 0 };
|
||||||
unsigned long pubkeydata_len, sig_len, data_len;
|
|
||||||
int rc;
|
int rc;
|
||||||
|
|
||||||
if (session->userauth_host_state == libssh2_NB_state_idle) {
|
if (session->userauth_host_state == libssh2_NB_state_idle) {
|
||||||
|
const LIBSSH2_HOSTKEY_METHOD *privkeyobj;
|
||||||
|
unsigned char *pubkeydata, *sig;
|
||||||
|
unsigned long pubkeydata_len;
|
||||||
|
unsigned long sig_len;
|
||||||
|
void *abstract;
|
||||||
|
unsigned char buf[5];
|
||||||
|
struct iovec datavec[4];
|
||||||
|
|
||||||
/* Zero the whole thing out */
|
/* Zero the whole thing out */
|
||||||
memset(&session->userauth_host_packet_requirev_state, 0,
|
memset(&session->userauth_host_packet_requirev_state, 0,
|
||||||
sizeof(session->userauth_host_packet_requirev_state));
|
sizeof(session->userauth_host_packet_requirev_state));
|
||||||
@@ -775,6 +779,7 @@ libssh2_userauth_hostbased_fromfile_ex(LIBSSH2_SESSION * session,
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (session->userauth_host_state == libssh2_NB_state_sent) {
|
if (session->userauth_host_state == libssh2_NB_state_sent) {
|
||||||
|
unsigned long data_len;
|
||||||
rc = libssh2_packet_requirev_ex(session, reply_codes,
|
rc = libssh2_packet_requirev_ex(session, reply_codes,
|
||||||
&session->userauth_host_data,
|
&session->userauth_host_data,
|
||||||
&data_len, 0, NULL, 0,
|
&data_len, 0, NULL, 0,
|
||||||
@@ -822,19 +827,16 @@ libssh2_userauth_publickey_fromfile_ex(LIBSSH2_SESSION * session,
|
|||||||
const char *privatekey,
|
const char *privatekey,
|
||||||
const char *passphrase)
|
const char *passphrase)
|
||||||
{
|
{
|
||||||
const LIBSSH2_HOSTKEY_METHOD *privkeyobj;
|
unsigned long pubkeydata_len = 0;
|
||||||
void *abstract;
|
|
||||||
unsigned char buf[5];
|
|
||||||
struct iovec datavec[4];
|
|
||||||
unsigned char *pubkeydata, *sig;
|
|
||||||
unsigned char reply_codes[4] =
|
unsigned char reply_codes[4] =
|
||||||
{ SSH_MSG_USERAUTH_SUCCESS, SSH_MSG_USERAUTH_FAILURE,
|
{ SSH_MSG_USERAUTH_SUCCESS, SSH_MSG_USERAUTH_FAILURE,
|
||||||
SSH_MSG_USERAUTH_PK_OK, 0
|
SSH_MSG_USERAUTH_PK_OK, 0
|
||||||
};
|
};
|
||||||
unsigned long pubkeydata_len, sig_len;
|
|
||||||
int rc;
|
int rc;
|
||||||
|
|
||||||
if (session->userauth_pblc_state == libssh2_NB_state_idle) {
|
if (session->userauth_pblc_state == libssh2_NB_state_idle) {
|
||||||
|
unsigned char *pubkeydata;
|
||||||
|
|
||||||
/* Zero the whole thing out */
|
/* Zero the whole thing out */
|
||||||
memset(&session->userauth_pblc_packet_requirev_state, 0,
|
memset(&session->userauth_pblc_packet_requirev_state, 0,
|
||||||
sizeof(session->userauth_pblc_packet_requirev_state));
|
sizeof(session->userauth_pblc_packet_requirev_state));
|
||||||
@@ -933,6 +935,13 @@ libssh2_userauth_publickey_fromfile_ex(LIBSSH2_SESSION * session,
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (session->userauth_pblc_state == libssh2_NB_state_sent) {
|
if (session->userauth_pblc_state == libssh2_NB_state_sent) {
|
||||||
|
const LIBSSH2_HOSTKEY_METHOD *privkeyobj;
|
||||||
|
void *abstract;
|
||||||
|
unsigned char buf[5];
|
||||||
|
struct iovec datavec[4];
|
||||||
|
unsigned char *sig;
|
||||||
|
unsigned long sig_len;
|
||||||
|
|
||||||
rc = libssh2_packet_requirev_ex(session, reply_codes,
|
rc = libssh2_packet_requirev_ex(session, reply_codes,
|
||||||
&session->userauth_pblc_data,
|
&session->userauth_pblc_data,
|
||||||
&session->userauth_pblc_data_len, 0,
|
&session->userauth_pblc_data_len, 0,
|
||||||
@@ -1023,6 +1032,10 @@ libssh2_userauth_publickey_fromfile_ex(LIBSSH2_SESSION * session,
|
|||||||
privkeyobj->dtor(session, &abstract);
|
privkeyobj->dtor(session, &abstract);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* If this function was restarted, pubkeydata_len might still be 0
|
||||||
|
* which will cause an unnecessary but harmless realloc here.
|
||||||
|
*/
|
||||||
if (sig_len > pubkeydata_len) {
|
if (sig_len > pubkeydata_len) {
|
||||||
unsigned char *newpacket;
|
unsigned char *newpacket;
|
||||||
/* Should *NEVER* happen, but...well.. better safe than sorry */
|
/* Should *NEVER* happen, but...well.. better safe than sorry */
|
||||||
@@ -1044,6 +1057,7 @@ libssh2_userauth_publickey_fromfile_ex(LIBSSH2_SESSION * session,
|
|||||||
|
|
||||||
session->userauth_pblc_s =
|
session->userauth_pblc_s =
|
||||||
session->userauth_pblc_packet + session->userauth_pblc_packet_len;
|
session->userauth_pblc_packet + session->userauth_pblc_packet_len;
|
||||||
|
session->userauth_pblc_b = NULL;
|
||||||
|
|
||||||
libssh2_htonu32(session->userauth_pblc_s,
|
libssh2_htonu32(session->userauth_pblc_s,
|
||||||
4 + session->userauth_pblc_method_len + 4 + sig_len);
|
4 + session->userauth_pblc_method_len + 4 + sig_len);
|
||||||
|
@@ -1,5 +1,8 @@
|
|||||||
.deps
|
.deps
|
||||||
.libs
|
.libs
|
||||||
|
*.gcno
|
||||||
|
*.gcda
|
||||||
Makefile
|
Makefile
|
||||||
Makefile.in
|
Makefile.in
|
||||||
simple
|
simple
|
||||||
|
ssh2
|
||||||
|
@@ -1,6 +1,19 @@
|
|||||||
AM_CPPFLAGS = -I$(top_srcdir)/include
|
AM_CPPFLAGS = -I$(top_srcdir)/src -I$(top_srcdir)/include -I$(top_builddir)/src
|
||||||
LDADD = ../src/libssh2.la
|
LDADD = ../src/libssh2.la
|
||||||
|
|
||||||
|
if SSHD
|
||||||
|
noinst_PROGRAMS = ssh2
|
||||||
|
ssh2_SOURCES = ssh2.c
|
||||||
|
endif
|
||||||
|
|
||||||
ctests = simple
|
ctests = simple
|
||||||
TESTS = $(ctests)
|
TESTS = $(ctests)
|
||||||
|
if SSHD
|
||||||
|
TESTS += ssh2.sh
|
||||||
|
endif
|
||||||
check_PROGRAMS = $(ctests)
|
check_PROGRAMS = $(ctests)
|
||||||
|
|
||||||
|
TESTS_ENVIRONMENT = SSHD=$(SSHD) EXEEXT=$(EXEEXT)
|
||||||
|
|
||||||
|
EXTRA_DIST = ssh2.sh
|
||||||
|
EXTRA_DIST += etc/host etc/host.pub etc/user etc/user.pub
|
||||||
|
27
tests/etc/host
Normal file
27
tests/etc/host
Normal file
@@ -0,0 +1,27 @@
|
|||||||
|
-----BEGIN RSA PRIVATE KEY-----
|
||||||
|
MIIEogIBAAKCAQEAwJaOo3i1X3N401hMd92lRec0tPMBgaF6ZDanovBiQP+PNo6g
|
||||||
|
VNtuF15AspbyxrViqtAyjLWQQlKGWgEFb2ga3ukzJll4dKPtNff3mO++W19ia0WQ
|
||||||
|
ZFWTAGcYqet4fvSALIpG+t/3u5MZXMNZPyCU8u1l+QXX14f6dEjzgRw7s3fSy/uv
|
||||||
|
Qawkgn8TQFvtSBOfvUTJPTAhhZqxZAt3nGH8d6vqD1hBNvdOpsohy6EgFh8V+kxn
|
||||||
|
UdQntrYe9WSz0djt0RRrdAvRkM0hq1UY8C9FTQQWni1n168c7FVrf65+GdJOn7NQ
|
||||||
|
Du0Whmh/R3flXR0kIBG+F7e8+e9W9OhlionkPwIBIwKCAQEAqpP6rgvT2DMTPtkt
|
||||||
|
yUCoU9tpMo4XRu4b8lxLVc2Y2nvz391pb7sJvO0Uu2/BFmYkMORKB5l/xbbOxL8T
|
||||||
|
cU2UJIVn0YJyAOj2rCTFW5KEB8mDDo4SLPtWUNBXrHF5WoDJTAVyEWdJInr5NOeJ
|
||||||
|
j68k1yoJ3JAlkwNozWUvclrVytZNohPhiYdKkj2DPlWKL//0INGIo9TU31AGJx2R
|
||||||
|
ymy105EFCXWDv1GAIWwqBjNNxzlyxDauuGTwWr2iYDyectBYApCkjyJzMpFn4Yiu
|
||||||
|
Mq5XomwkQhefK3y32bRasm+HSrQsGswSvSyS8I5YosjSKMmiWdYj4WxrSciT6gG/
|
||||||
|
KHanEwKBgQDucA7E/s9aKs6rECypXPaCORxvbLqdqAiwzJ0edufE+g0aQU/Zm3xj
|
||||||
|
m6LGovdEcaBog4rfKCSB9NRKi35m4HV9PO4YBw6/lQ0NeO6jrb8OnZp/P97FbomT
|
||||||
|
AXBibzUjQ8fhbPCaJF/2TUEoyhNbzJkpl+M0zu2aQ3MUYVd4dZ4y4wKBgQDOxfeA
|
||||||
|
RH3ZPvdYI50jxW+/kKcio+APZZJ9xhtqOKzmEuJOPzlngWk5WQgS8B1aicHyFRhw
|
||||||
|
UT2vKeJvqqoeLbIE9Fm6qlpN22594S88+LOiMda4wRswxG9wBZ2J4+rrYKpcb1gt
|
||||||
|
JXvVKY7h5qLWGCR0x+ovOcNXABWsF8CAnOnb9QKBgA2gANgOj4F+yfslfuUbQUlF
|
||||||
|
F5FWq5P6+S6sm0ORxBniZyYSXFWT2zjkUnHAK2L/LbzUURQQ7CSu5487K8tdSIrQ
|
||||||
|
SB6hUUzGsEnppzyNleOT+jMoOJ2RSbCg/xuRU35bpQWRMlHzczKlVC43btILsPsP
|
||||||
|
/lrJ/vLfSGeQiKfMNOz3AoGAC9DMUHjxP50ytJRSH00cVBbk+qpHUVZC4p2bKqQn
|
||||||
|
IxcFnhI9y2Z7CpdfjA24iNSr/zRny+dinEuJSDWjUi5/M3utWx+tY4jhvgzeIL3B
|
||||||
|
HzYMRRJZUz5sxJKbSbVAn7xhgZ/2aPrT4EuEge/sDDvk03kjUyffRszOCdV4tuRl
|
||||||
|
IoMCgYEAnrexTd5GuxEEBg3qJgN4IMwoBzZlJ1voaI6I/AMuvQ5kVklYvHTPTZOI
|
||||||
|
kSIrvaG8xaOdf0f76XNdT7U/dkx0C0vcesy5++hqakmeRCHjfsE1wN7m+hGo5WcR
|
||||||
|
Jq8Ph9ZnH5RKjqDsHh7Y4BCewQNrMBqNQEzDebZCDBUTnK9OgOg=
|
||||||
|
-----END RSA PRIVATE KEY-----
|
1
tests/etc/host.pub
Normal file
1
tests/etc/host.pub
Normal file
@@ -0,0 +1 @@
|
|||||||
|
ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAQEAwJaOo3i1X3N401hMd92lRec0tPMBgaF6ZDanovBiQP+PNo6gVNtuF15AspbyxrViqtAyjLWQQlKGWgEFb2ga3ukzJll4dKPtNff3mO++W19ia0WQZFWTAGcYqet4fvSALIpG+t/3u5MZXMNZPyCU8u1l+QXX14f6dEjzgRw7s3fSy/uvQawkgn8TQFvtSBOfvUTJPTAhhZqxZAt3nGH8d6vqD1hBNvdOpsohy6EgFh8V+kxnUdQntrYe9WSz0djt0RRrdAvRkM0hq1UY8C9FTQQWni1n168c7FVrf65+GdJOn7NQDu0Whmh/R3flXR0kIBG+F7e8+e9W9OhlionkPw== jas@mocca
|
3
tests/etc/sshd_config
Normal file
3
tests/etc/sshd_config
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
Port 4711
|
||||||
|
Protocol 2
|
||||||
|
AuthorizedKeysFile /home/jas/src/libssh2/tests/etc/user.pub
|
27
tests/etc/user
Normal file
27
tests/etc/user
Normal file
@@ -0,0 +1,27 @@
|
|||||||
|
-----BEGIN RSA PRIVATE KEY-----
|
||||||
|
MIIEoQIBAAKCAQEAxIgBuZS39D4bFnWminE7svGQLdVKx1aWKnEYEa+XtNU4DKZ/
|
||||||
|
pxUHg0zbEBya+IkX1yqQYWALoiOwI8XhdemLp8g03BX7o+DLSWisfiHpCDVGAuNq
|
||||||
|
RDF7qnFyL/ZBH6e0XKMtsoB51TDuBc4Rxh6p1V2QL/fg8BoHcCrnKkoqN8PSoKUX
|
||||||
|
2lPKJ3JIF/P8cDLbKYCvbSTFOdf56eqg0GJe7jFtSwweE9yz3IWZ3kSS1E/9E6sX
|
||||||
|
aNCu/hUt1bvQthICQyBNoTtQP/igEUJ7n0GMetsnq9wiUSomLzWqIWNqmvOv62aC
|
||||||
|
XRi5sYgpSAR4Zvnm3Cx/Wl0BEPz2rrFkG+G0SQIBIwKCAQEAgSYtBOyzZfztOqUV
|
||||||
|
q277WFWZQrC8HJf8R8aparU3zpq+braOZnuImByP9KUVYX6pRECKw6WD/NWfonq4
|
||||||
|
uzMSoXTviVBGRx6xeWIK880kG1Y1UlruD447Ur+ULiV7QLAIzylnLCiKk2lL9S+l
|
||||||
|
R63AD95mEOS4Y0ROB+Gt2fY5ABHRMqhGLvRKK8qwn35C1Z9qnTGhgiRbeoc373A5
|
||||||
|
ZAYyegyLnbvyV47UfPYS/TVzxZ9RCx3D3I/9fI7ZAFafkkIufQX3QPaVxf0zFUwW
|
||||||
|
de/f+gTbySTL4RDF185Evunx+tYvzCyIimB0cTE5dfsCWcHDtO6DwehKiOgJsbeW
|
||||||
|
IrpeTwKBgQDnEMfv7ORR35Ouj91iNCSfLU/v0TSzAJBfqYovByhXRsopgWAKXUmH
|
||||||
|
mWpBBP5vcGu3NvKfiZcMMbBPfllvlxkafQwvCqrdn5mg01MdAHMWP/O9yfvuxMDE
|
||||||
|
KycU2G2CT8j85mIPn19WeIgXC/kws+P0RAVNCBNeq89Gvp4IdLN67wKBgQDZvTYh
|
||||||
|
TPCYG32jBK+CcWmOna2SLvBloDcNevhzfu3RGjLIXzUHGxLdx7slsP/tpndmXIAL
|
||||||
|
CgV6GfrLxix5bO08203S2qnnwP8VrjjNIv1CyZIbbQFAFIeC3QxZMZHnXieLrO0z
|
||||||
|
qF5CuUXcL3cMeGmF/0HN/rB+4sF0qfv8wD8kRwKBgFXTCG8O2HYueK6NNPiXBknA
|
||||||
|
X4T17wCocCOIHWHstzZcHzP82oeBvDmuAuTzOe7gnQmJcA9e/ZbQoJKOA/Y/b7lh
|
||||||
|
pXCO7wHcMb9kb1PqOWAJIASqG78V4TLrdOp8Re6Sqb0FHRu+2kSwbQ/f4DapN2lb
|
||||||
|
F+lpZke8KGq71ExImm99AoGAN/10UbSy5UjlytVRs9QFM00eAQTBeTfTpGFzFmJ3
|
||||||
|
qsw48bIU8zLY9zNcAmC21rXG7m+Oo8C/lG0UmsyPF+jPSinDjf22qU7iger4qccr
|
||||||
|
Lm5YxTlJduC1IaaOJZBnWMBwkaF+0sTlCdfew5ctPbiQKcVLb3wBf7amxjpWvVYB
|
||||||
|
m50CgYAT6t2/Suav21J5zpzyrrt+oMZQ3MMzBnPHFRUQ1FdqZnE4eW5a10g0P+E+
|
||||||
|
YeTol+fYxL34+cI5PREK3dcnW1E8g8KOsOQqMgWdTfZEDHYRLqEyGIhu20aqfJCY
|
||||||
|
qu9tBburQoSlym9aQp41CMxIyHrL4GnwRlJkTTEVhDuab1HmKw==
|
||||||
|
-----END RSA PRIVATE KEY-----
|
1
tests/etc/user.pub
Normal file
1
tests/etc/user.pub
Normal file
@@ -0,0 +1 @@
|
|||||||
|
ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAQEAxIgBuZS39D4bFnWminE7svGQLdVKx1aWKnEYEa+XtNU4DKZ/pxUHg0zbEBya+IkX1yqQYWALoiOwI8XhdemLp8g03BX7o+DLSWisfiHpCDVGAuNqRDF7qnFyL/ZBH6e0XKMtsoB51TDuBc4Rxh6p1V2QL/fg8BoHcCrnKkoqN8PSoKUX2lPKJ3JIF/P8cDLbKYCvbSTFOdf56eqg0GJe7jFtSwweE9yz3IWZ3kSS1E/9E6sXaNCu/hUt1bvQthICQyBNoTtQP/igEUJ7n0GMetsnq9wiUSomLzWqIWNqmvOv62aCXRi5sYgpSAR4Zvnm3Cx/Wl0BEPz2rrFkG+G0SQ== jas@mocca
|
@@ -1,5 +1,6 @@
|
|||||||
/* Copyright (C) 2007 The Written Word, Inc. All rights reserved.
|
/* Copyright (C) 2007 The Written Word, Inc.
|
||||||
* Author: Simon Josefsson
|
* Copyright (C) 2008 Simon Josefsson
|
||||||
|
* All rights reserved.
|
||||||
*
|
*
|
||||||
* Redistribution and use in source and binary forms,
|
* Redistribution and use in source and binary forms,
|
||||||
* with or without modification, are permitted provided
|
* with or without modification, are permitted provided
|
||||||
@@ -36,9 +37,36 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
|
||||||
#include "libssh2.h"
|
#include "libssh2.h"
|
||||||
|
|
||||||
|
int test_libssh2_base64_decode (LIBSSH2_SESSION *session)
|
||||||
|
{
|
||||||
|
char *data;
|
||||||
|
unsigned int datalen;
|
||||||
|
const char *src = "Zm5vcmQ=";
|
||||||
|
unsigned int src_len = strlen (src);
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
ret = libssh2_base64_decode(session, &data, &datalen,
|
||||||
|
src, src_len);
|
||||||
|
if (ret)
|
||||||
|
return ret;
|
||||||
|
|
||||||
|
if (datalen != 5 || strcmp (data, "fnord") != 0)
|
||||||
|
{
|
||||||
|
fprintf (stderr,
|
||||||
|
"libssh2_base64_decode() failed (%d, %.*s)\n",
|
||||||
|
datalen, datalen, data);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
free (data);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
int main(int argc, char *argv[])
|
int main(int argc, char *argv[])
|
||||||
{
|
{
|
||||||
LIBSSH2_SESSION *session;
|
LIBSSH2_SESSION *session;
|
||||||
@@ -50,6 +78,8 @@ int main(int argc, char *argv[])
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
test_libssh2_base64_decode (session);
|
||||||
|
|
||||||
libssh2_session_free(session);
|
libssh2_session_free(session);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
170
tests/ssh2.c
Normal file
170
tests/ssh2.c
Normal file
@@ -0,0 +1,170 @@
|
|||||||
|
/* Self test, based on examples/simple/ssh2.c. */
|
||||||
|
|
||||||
|
#include "libssh2_config.h"
|
||||||
|
#include <libssh2.h>
|
||||||
|
#include <libssh2_sftp.h>
|
||||||
|
|
||||||
|
#ifdef HAVE_WINDOWS_H
|
||||||
|
# include <windows.h>
|
||||||
|
#endif
|
||||||
|
#ifdef HAVE_WINSOCK2_H
|
||||||
|
# include <winsock2.h>
|
||||||
|
#endif
|
||||||
|
#ifdef HAVE_NETINET_IN_H
|
||||||
|
# include <netinet/in.h>
|
||||||
|
#endif
|
||||||
|
#ifdef HAVE_SYS_SOCKET_H
|
||||||
|
# include <sys/socket.h>
|
||||||
|
#endif
|
||||||
|
# ifdef HAVE_UNISTD_H
|
||||||
|
#include <unistd.h>
|
||||||
|
#endif
|
||||||
|
# ifdef HAVE_ARPA_INET_H
|
||||||
|
#include <arpa/inet.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include <sys/types.h>
|
||||||
|
#include <fcntl.h>
|
||||||
|
#include <errno.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <ctype.h>
|
||||||
|
|
||||||
|
int main(int argc, char *argv[])
|
||||||
|
{
|
||||||
|
unsigned long hostaddr;
|
||||||
|
int sock, i, auth_pw = 0;
|
||||||
|
struct sockaddr_in sin;
|
||||||
|
const char *fingerprint;
|
||||||
|
char *userauthlist;
|
||||||
|
LIBSSH2_SESSION *session;
|
||||||
|
LIBSSH2_CHANNEL *channel;
|
||||||
|
#ifdef WIN32
|
||||||
|
WSADATA wsadata;
|
||||||
|
|
||||||
|
WSAStartup(MAKEWORD(2,0), &wsadata);
|
||||||
|
#endif
|
||||||
|
const char *pubkeyfile="etc/user.pub";
|
||||||
|
const char *privkeyfile="etc/user";
|
||||||
|
const char *username="username";
|
||||||
|
const char *password="password";
|
||||||
|
int ec = 1;
|
||||||
|
|
||||||
|
if (getenv ("USER"))
|
||||||
|
username = getenv ("USER");
|
||||||
|
|
||||||
|
if (getenv ("PRIVKEY"))
|
||||||
|
privkeyfile = getenv ("PRIVKEY");
|
||||||
|
|
||||||
|
if (getenv ("PRIVKEY"))
|
||||||
|
pubkeyfile = getenv ("PUBKEY");
|
||||||
|
|
||||||
|
hostaddr = htonl(0x7F000001);
|
||||||
|
|
||||||
|
sock = socket(AF_INET, SOCK_STREAM, 0);
|
||||||
|
#ifndef WIN32
|
||||||
|
fcntl(sock, F_SETFL, 0);
|
||||||
|
#endif
|
||||||
|
sin.sin_family = AF_INET;
|
||||||
|
sin.sin_port = htons(4711);
|
||||||
|
sin.sin_addr.s_addr = hostaddr;
|
||||||
|
if (connect(sock, (struct sockaddr*)(&sin),
|
||||||
|
sizeof(struct sockaddr_in)) != 0) {
|
||||||
|
fprintf(stderr, "failed to connect!\n");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Create a session instance and start it up
|
||||||
|
* This will trade welcome banners, exchange keys, and setup crypto, compression, and MAC layers
|
||||||
|
*/
|
||||||
|
session = libssh2_session_init();
|
||||||
|
if (libssh2_session_startup(session, sock)) {
|
||||||
|
fprintf(stderr, "Failure establishing SSH session\n");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* At this point we havn't authenticated,
|
||||||
|
* The first thing to do is check the hostkey's fingerprint against our known hosts
|
||||||
|
* Your app may have it hard coded, may go to a file, may present it to the user, that's your call
|
||||||
|
*/
|
||||||
|
fingerprint = libssh2_hostkey_hash(session, LIBSSH2_HOSTKEY_HASH_MD5);
|
||||||
|
printf("Fingerprint: ");
|
||||||
|
for(i = 0; i < 16; i++) {
|
||||||
|
printf("%02X ", (unsigned char)fingerprint[i]);
|
||||||
|
}
|
||||||
|
printf("\n");
|
||||||
|
|
||||||
|
/* check what authentication methods are available */
|
||||||
|
userauthlist = libssh2_userauth_list(session, username, strlen(username));
|
||||||
|
printf("Authentication methods: %s\n", userauthlist);
|
||||||
|
if (strstr(userauthlist, "password") != NULL) {
|
||||||
|
auth_pw |= 1;
|
||||||
|
}
|
||||||
|
if (strstr(userauthlist, "keyboard-interactive") != NULL) {
|
||||||
|
auth_pw |= 2;
|
||||||
|
}
|
||||||
|
if (strstr(userauthlist, "publickey") != NULL) {
|
||||||
|
auth_pw |= 4;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (auth_pw & 4) {
|
||||||
|
/* Authenticate by public key */
|
||||||
|
if (libssh2_userauth_publickey_fromfile(session, username, pubkeyfile, privkeyfile, password)) {
|
||||||
|
printf("\tAuthentication by public key failed!\n");
|
||||||
|
goto shutdown;
|
||||||
|
} else {
|
||||||
|
printf("\tAuthentication by public key succeeded.\n");
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
printf("No supported authentication methods found!\n");
|
||||||
|
goto shutdown;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Request a shell */
|
||||||
|
if (!(channel = libssh2_channel_open_session(session))) {
|
||||||
|
fprintf(stderr, "Unable to open a session\n");
|
||||||
|
goto shutdown;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Some environment variables may be set,
|
||||||
|
* It's up to the server which ones it'll allow though
|
||||||
|
*/
|
||||||
|
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, "vanilla")) {
|
||||||
|
fprintf(stderr, "Failed requesting pty\n");
|
||||||
|
goto skip_shell;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Open a SHELL on that pty */
|
||||||
|
if (libssh2_channel_shell(channel)) {
|
||||||
|
fprintf(stderr, "Unable to request shell on allocated pty\n");
|
||||||
|
goto shutdown;
|
||||||
|
}
|
||||||
|
|
||||||
|
ec = 0;
|
||||||
|
|
||||||
|
skip_shell:
|
||||||
|
if (channel) {
|
||||||
|
libssh2_channel_free(channel);
|
||||||
|
channel = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
shutdown:
|
||||||
|
|
||||||
|
libssh2_session_disconnect(session, "Normal Shutdown");
|
||||||
|
libssh2_session_free(session);
|
||||||
|
|
||||||
|
#ifdef WIN32
|
||||||
|
Sleep(1000);
|
||||||
|
closesocket(sock);
|
||||||
|
#else
|
||||||
|
sleep(1);
|
||||||
|
close(sock);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
return ec;
|
||||||
|
}
|
39
tests/ssh2.sh
Executable file
39
tests/ssh2.sh
Executable file
@@ -0,0 +1,39 @@
|
|||||||
|
#!/bin/sh
|
||||||
|
|
||||||
|
# Written by Simon Josefsson.
|
||||||
|
|
||||||
|
# Start sshd, invoke parameters, saving exit code, kill sshd, and
|
||||||
|
# return exit code.
|
||||||
|
|
||||||
|
srcdir=${srcdir:-$PWD}
|
||||||
|
SSHD=${SSHD:-/usr/sbin/sshd}
|
||||||
|
|
||||||
|
cmd="./ssh2${EXEEXT}"
|
||||||
|
srcdir=`cd $srcdir; pwd`
|
||||||
|
|
||||||
|
PRIVKEY=$srcdir/etc/user
|
||||||
|
export PRIVKEY
|
||||||
|
PUBKEY=$srcdir/etc/user.pub
|
||||||
|
export PUBKEY
|
||||||
|
|
||||||
|
chmod go-r $srcdir/etc/host*
|
||||||
|
$SSHD -f /dev/null -h $srcdir/etc/host \
|
||||||
|
-o 'Port 4711' -o 'Protocol 2' \
|
||||||
|
-o "AuthorizedKeysFile $srcdir/etc/user.pub" -D &
|
||||||
|
sshdpid=$!
|
||||||
|
|
||||||
|
trap "kill ${sshdpid}; echo signal killing sshd; exit 1;" EXIT
|
||||||
|
|
||||||
|
: "started sshd (${sshdpid})"
|
||||||
|
|
||||||
|
sleep 3
|
||||||
|
|
||||||
|
: Invoking $cmd...
|
||||||
|
eval $cmd
|
||||||
|
ec=$?
|
||||||
|
: Self-test exit code $ec
|
||||||
|
|
||||||
|
: "killing sshd (${sshdpid})"
|
||||||
|
kill "${sshdpid}" > /dev/null 2>&1
|
||||||
|
trap "" EXIT
|
||||||
|
exit $ec
|
28
tests/sshdwrap
Executable file
28
tests/sshdwrap
Executable file
@@ -0,0 +1,28 @@
|
|||||||
|
#!/bin/sh -x
|
||||||
|
|
||||||
|
# Written by Simon Josefsson
|
||||||
|
|
||||||
|
# Start sshd, invoke parameters, saving exit code, kill sshd, and
|
||||||
|
# return exit code.
|
||||||
|
|
||||||
|
cmd="$@"
|
||||||
|
SSHD=${SSHD:-/usr/sbin/sshd}
|
||||||
|
|
||||||
|
$SSHD -f etc/sshd_config -h $PWD/etc/host -D &
|
||||||
|
sshdpid=$!
|
||||||
|
|
||||||
|
trap "kill ${sshdpid}; echo signal killing sshd; exit 1;" EXIT
|
||||||
|
|
||||||
|
: "started sshd (${sshdpid})"
|
||||||
|
|
||||||
|
sleep 1
|
||||||
|
|
||||||
|
: Invoking $cmd...
|
||||||
|
eval $cmd
|
||||||
|
ec=$?
|
||||||
|
: Self-test exit code $ec
|
||||||
|
|
||||||
|
: "killing sshd (${sshdpid})"
|
||||||
|
kill "${sshdpid}" > /dev/null 2>&1
|
||||||
|
trap "" EXIT
|
||||||
|
exit $ec
|
@@ -16,43 +16,21 @@
|
|||||||
|
|
||||||
#define HAVE_WINSOCK2_H
|
#define HAVE_WINSOCK2_H
|
||||||
#define HAVE_IOCTLSOCKET
|
#define HAVE_IOCTLSOCKET
|
||||||
|
#define HAVE_SELECT
|
||||||
/* same as WSABUF */
|
|
||||||
struct iovec {
|
|
||||||
u_long iov_len;
|
|
||||||
char *iov_base;
|
|
||||||
};
|
|
||||||
|
|
||||||
#define inline __inline
|
|
||||||
|
|
||||||
static inline int writev(int sock, struct iovec *iov, int nvecs)
|
|
||||||
{
|
|
||||||
DWORD ret;
|
|
||||||
if (WSASend(sock, (LPWSABUF)iov, nvecs, &ret, 0, NULL, NULL) == 0) {
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* not really usleep, but safe for the way we use it in this lib */
|
|
||||||
static inline int usleep(int udelay)
|
|
||||||
{
|
|
||||||
Sleep(udelay / 1000);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
#ifdef _MSC_VER
|
#ifdef _MSC_VER
|
||||||
#define snprintf _snprintf
|
#define snprintf _snprintf
|
||||||
|
#if _MSC_VER < 1500
|
||||||
#define vsnprintf _vsnprintf
|
#define vsnprintf _vsnprintf
|
||||||
|
#else
|
||||||
|
#define ssize_t SSIZE_T
|
||||||
|
#define uint32_t UINT32
|
||||||
|
#endif
|
||||||
#define strncasecmp _strnicmp
|
#define strncasecmp _strnicmp
|
||||||
#define strcasecmp _stricmp
|
#define strcasecmp _stricmp
|
||||||
#else
|
#else
|
||||||
#ifdef __MINGW32__
|
|
||||||
#define WINSOCK_VERSION MAKEWORD(2,0)
|
|
||||||
#else
|
|
||||||
#define strncasecmp strnicmp
|
#define strncasecmp strnicmp
|
||||||
#define strcasecmp stricmp
|
#define strcasecmp stricmp
|
||||||
#endif /* __MINGW32__ */
|
|
||||||
#endif /* _MSC_VER */
|
#endif /* _MSC_VER */
|
||||||
|
|
||||||
/* Compile in zlib support */
|
/* Compile in zlib support */
|
||||||
|
Reference in New Issue
Block a user