Compare commits
203 Commits
libssh2-1.
...
libssh2-1.
Author | SHA1 | Date | |
---|---|---|---|
![]() |
e16f638dca | ||
![]() |
7d94b69b80 | ||
![]() |
8bb6cf7f95 | ||
![]() |
5fcbb168b8 | ||
![]() |
d811750645 | ||
![]() |
cfe94c715e | ||
![]() |
a8473c819b | ||
![]() |
c71889017f | ||
![]() |
253d5922f2 | ||
![]() |
79d63df12d | ||
![]() |
86552bf2bb | ||
![]() |
477e609a84 | ||
![]() |
3e47ca8a32 | ||
![]() |
6af0ee567b | ||
![]() |
c6d99bd3a4 | ||
![]() |
d1eccb487a | ||
![]() |
22204c4e2e | ||
![]() |
8670f5da24 | ||
![]() |
3835655f09 | ||
![]() |
dc199ed03a | ||
![]() |
8f799f98d9 | ||
![]() |
637c90959b | ||
![]() |
8a731d6217 | ||
![]() |
d85f9a689f | ||
![]() |
031566f9cc | ||
![]() |
977a3b6a76 | ||
![]() |
34dc1d61b4 | ||
![]() |
be95032e29 | ||
![]() |
c0bface8a7 | ||
![]() |
f31c9fb221 | ||
![]() |
f89bed9571 | ||
![]() |
bc9d735664 | ||
![]() |
06ff22f1a6 | ||
![]() |
e57f29f8f6 | ||
![]() |
1c1699545b | ||
![]() |
abcc0d370f | ||
![]() |
977dbb7511 | ||
![]() |
aedfba25b8 | ||
![]() |
19f1402f1d | ||
![]() |
df5c61dbca | ||
![]() |
1689315fce | ||
![]() |
7f7e65c54b | ||
![]() |
751e0087a8 | ||
![]() |
600f26ce6e | ||
![]() |
3260beb07a | ||
![]() |
01a6210ab7 | ||
![]() |
6a3b5487cb | ||
![]() |
e4ba5fabec | ||
![]() |
46f017e751 | ||
![]() |
12adbc28b8 | ||
![]() |
424a27e007 | ||
![]() |
1e4fb7ee9f | ||
![]() |
7b80a188dd | ||
![]() |
9d50d43a83 | ||
![]() |
c355d31ff9 | ||
![]() |
18fe507324 | ||
![]() |
d63e32dd30 | ||
![]() |
c32e82e97b | ||
![]() |
7d4b5a8e07 | ||
![]() |
200784c4e7 | ||
![]() |
b22b23703c | ||
![]() |
0e4e14109a | ||
![]() |
5bcc2d4629 | ||
![]() |
33df559967 | ||
![]() |
26f6d71885 | ||
![]() |
62c91e2cd4 | ||
![]() |
b9dc6112d7 | ||
![]() |
106bacdebc | ||
![]() |
23dec383f7 | ||
![]() |
fc94046e6e | ||
![]() |
ee547fe90d | ||
![]() |
a58b0dacb4 | ||
![]() |
6e710d7fb6 | ||
![]() |
b20bfeb3e5 | ||
![]() |
aba11380a1 | ||
![]() |
2c46c4bf95 | ||
![]() |
160776d218 | ||
![]() |
ee2d61a48b | ||
![]() |
fcb601da7b | ||
![]() |
55bae8dd07 | ||
![]() |
4440e05d48 | ||
![]() |
378d0a6676 | ||
![]() |
21cb7bfb36 | ||
![]() |
e1a5d1bc77 | ||
![]() |
189cf86df0 | ||
![]() |
30e376773a | ||
![]() |
38e210af0e | ||
![]() |
d145e04443 | ||
![]() |
feab568a7a | ||
![]() |
08973a00a1 | ||
![]() |
c00efa5f93 | ||
![]() |
adc5db29e3 | ||
![]() |
92d686fe19 | ||
![]() |
5559ad8fe1 | ||
![]() |
88366b5ec2 | ||
![]() |
61df22c460 | ||
![]() |
d808080daf | ||
![]() |
f5c1a0d98b | ||
![]() |
85a827d1bc | ||
![]() |
1b3307dda0 | ||
![]() |
85c6627c86 | ||
![]() |
c49cc8411f | ||
![]() |
fa15fded72 | ||
![]() |
c2329aa09e | ||
![]() |
94077f7a58 | ||
![]() |
55a8b10ad9 | ||
![]() |
27f9ac2549 | ||
![]() |
cdeef54967 | ||
![]() |
42aefdba79 | ||
![]() |
d41f5e40aa | ||
![]() |
2df6cd6606 | ||
![]() |
d512b25f69 | ||
![]() |
b4f71fd25a | ||
![]() |
a5bf809b80 | ||
![]() |
2157e178a3 | ||
![]() |
d385230e15 | ||
![]() |
61e40a32ff | ||
![]() |
e6c46cc249 | ||
![]() |
9f1b89e99b | ||
![]() |
8da30ea4d4 | ||
![]() |
ff6c01e959 | ||
![]() |
c910cd382d | ||
![]() |
edd42304a2 | ||
![]() |
1ad20ac7d3 | ||
![]() |
d7f9cd57c5 | ||
![]() |
16ef83dd81 | ||
![]() |
951904418b | ||
![]() |
80e5e20b00 | ||
![]() |
6e0d757f24 | ||
![]() |
a12f3ffab5 | ||
![]() |
486bb37621 | ||
![]() |
fe347a702f | ||
![]() |
07615610ba | ||
![]() |
5aa7b29758 | ||
![]() |
a67ff056e6 | ||
![]() |
f1cfa55b60 | ||
![]() |
437a3b75ec | ||
![]() |
a3ad635db4 | ||
![]() |
e5c5408564 | ||
![]() |
fe8f3deb48 | ||
![]() |
d49b8f303a | ||
![]() |
6f8777505f | ||
![]() |
52b8da7dfa | ||
![]() |
de7b5d3bc0 | ||
![]() |
b31e35aba6 | ||
![]() |
e2bb780d77 | ||
![]() |
a8cfc708c5 | ||
![]() |
9f6fd5af82 | ||
![]() |
5d567faecc | ||
![]() |
bfbb5a4dc7 | ||
![]() |
43b730ce56 | ||
![]() |
6af85b6053 | ||
![]() |
05641218bc | ||
![]() |
42fec44c8a | ||
![]() |
e470738a0c | ||
![]() |
62cc59cd06 | ||
![]() |
1abf2057de | ||
![]() |
6c27922ac1 | ||
![]() |
112845df0b | ||
![]() |
499b22ca36 | ||
![]() |
6403519fcf | ||
![]() |
6f8dd9baff | ||
![]() |
a1c0d97ff9 | ||
![]() |
5c065bf1ff | ||
![]() |
5237177daf | ||
![]() |
bd627d38a1 | ||
![]() |
c55b0b0425 | ||
![]() |
38efbe8243 | ||
![]() |
34ecc09a3c | ||
![]() |
d6cf1c7df0 | ||
![]() |
a40c160cff | ||
![]() |
29e256e817 | ||
![]() |
137342a41d | ||
![]() |
79a7ca3085 | ||
![]() |
50e37bdadc | ||
![]() |
04e79e0c79 | ||
![]() |
9a36065b52 | ||
![]() |
1ac7bd09cc | ||
![]() |
9a7311ba57 | ||
![]() |
e07b11b7df | ||
![]() |
e885300b18 | ||
![]() |
92a9f95279 | ||
![]() |
e91d4c9790 | ||
![]() |
69a3354467 | ||
![]() |
3ede6e280e | ||
![]() |
b583311a93 | ||
![]() |
27ac5aa40d | ||
![]() |
a123051200 | ||
![]() |
62901253a4 | ||
![]() |
7c5ee0fa66 | ||
![]() |
1e15075a8e | ||
![]() |
ad63fc2df6 | ||
![]() |
d46185eaa5 | ||
![]() |
9c4b380dd6 | ||
![]() |
e887a8bd0f | ||
![]() |
04692445d4 | ||
![]() |
a955f8428b | ||
![]() |
ededdfa9c2 | ||
![]() |
11f9dce3d7 | ||
![]() |
6bbebcf36c | ||
![]() |
7a87bba02a | ||
![]() |
c8374cdc10 | ||
![]() |
9b2bed22fc |
2
.gitignore
vendored
2
.gitignore
vendored
@@ -24,7 +24,6 @@ ltmain.sh
|
||||
missing
|
||||
ssh2_sample
|
||||
libssh2-*.tar.gz
|
||||
INSTALL
|
||||
install-sh
|
||||
*.o
|
||||
*.lo
|
||||
@@ -33,3 +32,4 @@ mkinstalldirs
|
||||
tags
|
||||
libssh2.pc
|
||||
TAGS
|
||||
*~
|
||||
|
2
COPYING
2
COPYING
@@ -2,7 +2,7 @@
|
||||
* Copyright (c) 2005,2006 Mikhail Gusarov <dottedmag@dottedmag.net>
|
||||
* Copyright (c) 2006-2007 The Written Word, Inc.
|
||||
* Copyright (c) 2007 Eli Fant <elifantu@mail.ru>
|
||||
* Copyright (c) 2009 Daniel Stenberg
|
||||
* Copyright (c) 2009-2014 Daniel Stenberg
|
||||
* Copyright (C) 2008, 2009 Simon Josefsson
|
||||
* All rights reserved.
|
||||
*
|
||||
|
2
Makefile.OpenSSL.inc
Normal file
2
Makefile.OpenSSL.inc
Normal file
@@ -0,0 +1,2 @@
|
||||
CRYPTO_CSOURCES = openssl.c
|
||||
CRYPTO_HHEADERS = openssl.h
|
2
Makefile.WinCNG.inc
Normal file
2
Makefile.WinCNG.inc
Normal file
@@ -0,0 +1,2 @@
|
||||
CRYPTO_CSOURCES = wincng.c
|
||||
CRYPTO_HHEADERS = wincng.h
|
19
Makefile.am
19
Makefile.am
@@ -1,6 +1,9 @@
|
||||
AUTOMAKE_OPTIONS = foreign nostdinc
|
||||
|
||||
SUBDIRS = src example tests docs
|
||||
SUBDIRS = src tests docs
|
||||
if BUILD_EXAMPLES
|
||||
SUBDIRS += example
|
||||
endif
|
||||
|
||||
pkgconfigdir = $(libdir)/pkgconfig
|
||||
pkgconfig_DATA = libssh2.pc
|
||||
@@ -11,10 +14,9 @@ include_HEADERS = \
|
||||
include/libssh2_sftp.h
|
||||
|
||||
NETWAREFILES = nw/keepscreen.c \
|
||||
nw/Makefile \
|
||||
nw/Makefile.netware \
|
||||
nw/nwlib.c \
|
||||
nw/test/Makefile.netware
|
||||
nw/nwlib.c \
|
||||
nw/GNUmakefile \
|
||||
nw/test/GNUmakefile
|
||||
|
||||
DSP = win32/libssh2.dsp
|
||||
VCPROJ = win32/libssh2.vcproj
|
||||
@@ -30,8 +32,8 @@ win32/libssh2_config.h win32/config.mk win32/rules.mk \
|
||||
win32/Makefile.Watcom win32/libssh2.dsw win32/tests.dsp $(DSP) \
|
||||
win32/msvcproj.head win32/msvcproj.foot win32/libssh2.rc
|
||||
|
||||
EXTRA_DIST = $(WIN32FILES) buildconf $(NETWAREFILES) get_ver.awk HACKING \
|
||||
maketgz NMakefile TODO RELEASE-NOTES libssh2.pc.in $(VMSFILES)
|
||||
EXTRA_DIST = $(WIN32FILES) buildconf $(NETWAREFILES) get_ver.awk \
|
||||
maketgz NMakefile RELEASE-NOTES libssh2.pc.in $(VMSFILES) config.rpath
|
||||
|
||||
ACLOCAL_AMFLAGS = -I m4
|
||||
|
||||
@@ -73,6 +75,9 @@ gen-coverage:
|
||||
coverage: init-coverage build-coverage gen-coverage
|
||||
|
||||
# DSP/VCPROJ generation adapted from libcurl
|
||||
# only OpenSSL and WinCNG are supported with this build system
|
||||
CRYPTO_CSOURCES = openssl.c wincng.c
|
||||
CRYPTO_HHEADERS = openssl.h wincng.h
|
||||
# Makefile.inc provides the CSOURCES and HHEADERS defines
|
||||
include Makefile.inc
|
||||
|
||||
|
@@ -1,7 +1,6 @@
|
||||
CSOURCES = 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 transport.c \
|
||||
version.c knownhost.c agent.c openssl.c libgcrypt.c pem.c keepalive.c \
|
||||
global.c
|
||||
version.c knownhost.c agent.c $(CRYPTO_CSOURCES) pem.c keepalive.c global.c
|
||||
|
||||
HHEADERS = libssh2_priv.h openssl.h libgcrypt.h transport.h channel.h \
|
||||
comp.h mac.h misc.h packet.h userauth.h session.h sftp.h crypto.h
|
||||
HHEADERS = libssh2_priv.h $(CRYPTO_HHEADERS) transport.h channel.h comp.h \
|
||||
mac.h misc.h packet.h userauth.h session.h sftp.h crypto.h
|
||||
|
2
Makefile.libgcrypt.inc
Normal file
2
Makefile.libgcrypt.inc
Normal file
@@ -0,0 +1,2 @@
|
||||
CRYPTO_CSOURCES = libgcrypt.c
|
||||
CRYPTO_HHEADERS = libgcrypt.h
|
30
NMakefile
30
NMakefile
@@ -1,19 +1,33 @@
|
||||
!include "win32/config.mk"
|
||||
|
||||
!if "$(WITH_WINCNG)" == "1"
|
||||
!include "Makefile.WinCNG.inc"
|
||||
!else
|
||||
!include "Makefile.OpenSSL.inc"
|
||||
!endif
|
||||
!include "Makefile.inc"
|
||||
|
||||
OBJECTS=$(CSOURCES:.c=.obj)
|
||||
|
||||
# SUBDIRS=src example
|
||||
SUBDIRS=src
|
||||
|
||||
all-sub:
|
||||
all-sub: win32\objects.mk
|
||||
-for %D in ($(SUBDIRS)) do $(MAKE) /nologo /f %D/NMakefile BUILD=$(BUILD) SUBDIR=%D all-sub
|
||||
|
||||
clean:
|
||||
-rmdir /s/q $(TARGET)
|
||||
-rmdir 2>NUL /s/q $(TARGET)
|
||||
-del 2>NUL win32\objects.mk
|
||||
|
||||
real-clean: clean
|
||||
-del libssh2.dll
|
||||
-del libssh2.exp
|
||||
-del libssh2.ilk
|
||||
-del libssh2.lib
|
||||
-del *.pdb
|
||||
real-clean vclean: clean
|
||||
-del 2>NUL libssh2.dll
|
||||
-del 2>NUL libssh2.exp
|
||||
-del 2>NUL libssh2.ilk
|
||||
-del 2>NUL libssh2.lib
|
||||
-del 2>NUL *.pdb
|
||||
|
||||
win32\objects.mk: Makefile.inc
|
||||
@echo OBJECTS = \>$@
|
||||
@for %O in ($(OBJECTS)) do @echo $$(INTDIR)\%O \>>$@
|
||||
@echo $$(EOL)>>$@
|
||||
|
||||
|
88
README
88
README
@@ -8,90 +8,10 @@ Web site: http://www.libssh2.org/
|
||||
|
||||
Mailing list: http://cool.haxx.se/mailman/listinfo/libssh2-devel
|
||||
|
||||
Generic installation instructions are in INSTALL. Some ./configure
|
||||
options deserve additional comments:
|
||||
License: see COPYING
|
||||
|
||||
* --enable-crypt-none
|
||||
Source code: https://github.com/bagder/libssh2
|
||||
|
||||
The SSH2 Transport allows for unencrypted data
|
||||
transmission using the "none" cipher. Because this is
|
||||
such a huge security hole, it is typically disabled on
|
||||
SSH2 implementations and is disabled in libssh2 by
|
||||
default as well.
|
||||
Web site source code: https://github.com/bagder/libssh2-www
|
||||
|
||||
Enabling this option will allow for "none" as a
|
||||
negotiable method, however it still requires that the
|
||||
method be advertized by the remote end and that no
|
||||
more-preferable methods are available.
|
||||
|
||||
* --enable-mac-none
|
||||
|
||||
The SSH2 Transport also allows implementations to
|
||||
forego a message authentication code. While this is
|
||||
less of a security risk than using a "none" cipher, it
|
||||
is still not recommended as disabling MAC hashes
|
||||
removes a layer of security.
|
||||
|
||||
Enabling this option will allow for "none" as a
|
||||
negotiable method, however it still requires that the
|
||||
method be advertized by the remote end and that no
|
||||
more-preferable methods are available.
|
||||
|
||||
* --disable-gex-new
|
||||
|
||||
The diffie-hellman-group-exchange-sha1 (dh-gex) key
|
||||
exchange method originally defined an exchange
|
||||
negotiation using packet type 30 to request a
|
||||
generation pair based on a single target value. Later
|
||||
refinement of dh-gex provided for range and target
|
||||
values. By default libssh2 will use the newer range
|
||||
method.
|
||||
|
||||
If you experience trouble connecting to an old SSH
|
||||
server using dh-gex, try this option to fallback on
|
||||
the older more reliable method.
|
||||
|
||||
* --with-libgcrypt
|
||||
* --without-libgcrypt
|
||||
* --with-libgcrypt-prefix=DIR
|
||||
|
||||
libssh2 can use the Libgcrypt library
|
||||
(http://www.gnupg.org/) for cryptographic operations.
|
||||
Either Libgcrypt or OpenSSL is required.
|
||||
|
||||
Configure will attempt to locate Libgcrypt
|
||||
automatically.
|
||||
|
||||
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
|
||||
(http://www.openssl.org) for cryptographic operations.
|
||||
Either Libgcrypt or OpenSSL is required.
|
||||
|
||||
Configure will attempt to locate OpenSSL in the
|
||||
default location.
|
||||
|
||||
If your installation of OpenSSL is in another
|
||||
location, specify it using --with-libssl-prefix.
|
||||
|
||||
* --with-libz
|
||||
* --without-libz
|
||||
* --with-libz-prefix=[DIR]
|
||||
|
||||
If present, libssh2 will attempt to use the zlib
|
||||
(http://www.zlib.org) for payload compression, however
|
||||
zlib is not required.
|
||||
|
||||
If your installation of Libz is in another location,
|
||||
specify it using --with-libz-prefix.
|
||||
|
||||
* --enable-debug
|
||||
|
||||
Will make the build use more pedantic and strict compiler
|
||||
options as well as enable the libssh2_trace() function (for
|
||||
showing debug traces).
|
||||
Installation instructions are in docs/INSTALL
|
||||
|
@@ -1,28 +1,83 @@
|
||||
libssh2 1.4.1
|
||||
libssh2 1.5.0
|
||||
|
||||
This release includes the following changes:
|
||||
|
||||
o Added Windows Cryptography API: Next Generation based backend
|
||||
|
||||
This release includes the following bugfixes:
|
||||
|
||||
o build error with gcrypt backend
|
||||
o always do "forced" window updates to avoid corner case stalls
|
||||
o aes: the init function fails when OpenSSL has AES support
|
||||
o transport_send: Finish in-progress key exchange before sending data
|
||||
o channel_write: acknowledge transport errors
|
||||
o examples/x11.c: Make sure sizeof passed to read operation is correct
|
||||
o examples/x11.c:,Fix suspicious sizeof usage
|
||||
o sftp_packet_add: verify the packet before accepting it
|
||||
o SFTP: preserve the original error code more
|
||||
o sftp_packet_read: adjust window size as necessary
|
||||
o Use safer snprintf rather then sprintf in several places
|
||||
o Define and use LIBSSH2_INVALID_SOCKET instead of INVALID_SOCKET
|
||||
o sftp_write: cannot return acked data *and* EAGAIN
|
||||
o sftp_read: avoid data *and* EAGAIN
|
||||
o libssh2.h: Add missing prototype for libssh2_session_banner_set()
|
||||
o Security Advisory for CVE-2015-1782, using SSH_MSG_KEXINIT data unbounded
|
||||
o missing _libssh2_error in _libssh2_channel_write
|
||||
o knownhost: Fix DSS keys being detected as unknown.
|
||||
o knownhost: Restore behaviour of `libssh2_knownhost_writeline` with short buffer.
|
||||
o libssh2.h: on Windows, a socket is of type SOCKET, not int
|
||||
o libssh2_priv.h: a 1 bit bit-field should be unsigned
|
||||
o windows build: do not export externals from static library
|
||||
o Fixed two potential use-after-frees of the payload buffer
|
||||
o Fixed a few memory leaks in error paths
|
||||
o userauth: Fixed an attempt to free from stack on error
|
||||
o agent_list_identities: Fixed memory leak on OOM
|
||||
o knownhosts: Abort if the hosts buffer is too small
|
||||
o sftp_close_handle: ensure the handle is always closed
|
||||
o channel_close: Close the channel even in the case of errors
|
||||
o docs: added missing libssh2_session_handshake.3 file
|
||||
o docs: fixed a bunch of typos
|
||||
o userauth_password: pass on the underlying error code
|
||||
o _libssh2_channel_forward_cancel: accessed struct after free
|
||||
o _libssh2_packet_add: avoid using uninitialized memory
|
||||
o _libssh2_channel_forward_cancel: avoid memory leaks on error
|
||||
o _libssh2_channel_write: client spins on write when window full
|
||||
o windows build: fix build errors
|
||||
o publickey_packet_receive: avoid junk in returned pointers
|
||||
o channel_receive_window_adjust: store windows size always
|
||||
o userauth_hostbased_fromfile: zero assign to avoid uninitialized use
|
||||
o configure: change LIBS not LDFLAGS when checking for libs
|
||||
o agent_connect_unix: make sure there's a trailing zero
|
||||
o MinGW build: Fixed redefine warnings.
|
||||
o sftpdir.c: added authentication method detection.
|
||||
o Watcom build: added support for WinCNG build.
|
||||
o configure.ac: replace AM_CONFIG_HEADER with AC_CONFIG_HEADERS
|
||||
o sftp_statvfs: fix for servers not supporting statfvs extension
|
||||
o knownhost.c: use LIBSSH2_FREE macro instead of free
|
||||
o Fixed compilation using mingw-w64
|
||||
o knownhost.c: fixed that 'key_type_len' may be used uninitialized
|
||||
o configure: Display individual crypto backends on separate lines
|
||||
o examples on Windows: check for WSAStartup return code
|
||||
o examples on Windows: check for socket return code
|
||||
o agent.c: check return code of MapViewOfFile
|
||||
o kex.c: fix possible NULL pointer de-reference with session->kex
|
||||
o packet.c: fix possible NULL pointer de-reference within listen_state
|
||||
o tests on Windows: check for WSAStartup return code
|
||||
o userauth.c: improve readability and clarity of for-loops
|
||||
o examples on Windows: use native SOCKET-type instead of int
|
||||
o packet.c: i < 256 was always true and i would overflow to 0
|
||||
o kex.c: make sure mlist is not set to NULL
|
||||
o session.c: check return value of session_nonblock in debug mode
|
||||
o session.c: check return value of session_nonblock during startup
|
||||
o userauth.c: make sure that sp_len is positive and avoid overflows
|
||||
o knownhost.c: fix use of uninitialized argument variable wrote
|
||||
o openssl: initialise the digest context before calling EVP_DigestInit()
|
||||
o libssh2_agent_init: init ->fd to LIBSSH2_INVALID_SOCKET
|
||||
o configure.ac: Add zlib to Requires.private in libssh2.pc if using zlib
|
||||
o configure.ac: Rework crypto library detection
|
||||
o configure.ac: Reorder --with-* options in --help output
|
||||
o configure.ac: Call zlib zlib and not libz in text but keep option names
|
||||
o Fix non-autotools builds: Always define the LIBSSH2_OPENSSL CPP macro
|
||||
o sftp: seek: Don't flush buffers on same offset
|
||||
o sftp: statvfs: Along error path, reset the correct 'state' variable.
|
||||
o sftp: Add support for fsync (OpenSSH extension).
|
||||
o _libssh2_channel_read: fix data drop when out of window
|
||||
o comp_method_zlib_decomp: Improve buffer growing algorithm
|
||||
o _libssh2_channel_read: Honour window_size_initial
|
||||
o window_size: redid window handling for flow control reasons
|
||||
o knownhosts: handle unknown key types
|
||||
|
||||
This release would not have looked like this without help, code, reports and
|
||||
advice from friends like these:
|
||||
|
||||
Armen Babakhanian, Paul Howarth, Matthew Booth, Steven Dake, Peter Stuge,
|
||||
Matt Lawson, Tom Weber, Alexander Lamaison
|
||||
Alexander Lamaison, Bob Kast, Dan Fandrich, Daniel Stenberg, Guenter Knauf,
|
||||
Kamil Dudka, Leif Salomonsson, Marc Hörsken, Mark McPherson,
|
||||
Matthias Kerestesch, Mikhail Gusarov, Peter Stuge, Richard W.M. Jones,
|
||||
Salvador Fandino, Seth Willits, Mariusz Ziulek
|
||||
|
||||
Thanks! (and sorry if I forgot to mention someone)
|
||||
|
||||
|
110
configure.ac
110
configure.ac
@@ -2,7 +2,7 @@
|
||||
AC_INIT(libssh2, [-], libssh2-devel@cool.haxx.se)
|
||||
AC_CONFIG_MACRO_DIR([m4])
|
||||
AC_CONFIG_SRCDIR([src])
|
||||
AM_CONFIG_HEADER([src/libssh2_config.h example/libssh2_config.h])
|
||||
AC_CONFIG_HEADERS([src/libssh2_config.h example/libssh2_config.h])
|
||||
AM_MAINTAINER_MODE
|
||||
|
||||
dnl SED is needed by some of the tools
|
||||
@@ -83,55 +83,102 @@ dnl check for how to do large files
|
||||
AC_SYS_LARGEFILE
|
||||
|
||||
# Configure parameters
|
||||
AC_ARG_WITH(libgcrypt,
|
||||
AC_HELP_STRING([--with-libgcrypt],[Use Libgcrypt for crypto]),
|
||||
use_libgcrypt=$withval,use_libgcrypt=auto)
|
||||
AC_ARG_WITH(openssl,
|
||||
AC_HELP_STRING([--with-openssl],[Use OpenSSL for crypto]),
|
||||
use_openssl=$withval,use_openssl=auto)
|
||||
AC_ARG_WITH(libgcrypt,
|
||||
AC_HELP_STRING([--with-libgcrypt],[Use libgcrypt for crypto]),
|
||||
use_libgcrypt=$withval,use_libgcrypt=auto)
|
||||
AC_ARG_WITH(wincng,
|
||||
AC_HELP_STRING([--with-wincng],[Use Windows CNG for crypto]),
|
||||
use_wincng=$withval,use_wincng=auto)
|
||||
AC_ARG_WITH(libz,
|
||||
AC_HELP_STRING([--with-libz],[Use Libz for compression]),
|
||||
AC_HELP_STRING([--with-libz],[Use zlib for compression]),
|
||||
use_libz=$withval,use_libz=auto)
|
||||
|
||||
# Look for OpenSSL (default)
|
||||
if test "$use_openssl" != "no" && test "$use_libgcrypt" != "yes"; then
|
||||
found_crypto=none
|
||||
|
||||
# Look for OpenSSL
|
||||
if test "$found_crypto" = "none" && test "$use_openssl" != "no"; then
|
||||
AC_LIB_HAVE_LINKFLAGS([ssl], [crypto], [#include <openssl/ssl.h>])
|
||||
fi
|
||||
if test "$ac_cv_libssl" = "yes"; then
|
||||
AC_DEFINE(LIBSSH2_OPENSSL, 1, [Use OpenSSL])
|
||||
LIBSREQUIRED=libssl,libcrypto
|
||||
|
||||
# Not all OpenSSL have AES-CTR functions.
|
||||
save_LIBS="$LIBS"
|
||||
LIBS="$LIBS $LIBSSL"
|
||||
AC_CHECK_FUNCS(EVP_aes_128_ctr)
|
||||
LIBS="$save_LIBS"
|
||||
|
||||
found_crypto="OpenSSL (AES-CTR: ${ac_cv_func_EVP_aes_128_ctr:-N/A})"
|
||||
fi
|
||||
AM_CONDITIONAL(OPENSSL, test "$ac_cv_libssl" = "yes")
|
||||
|
||||
# Look for libgcrypt
|
||||
if test "$ac_cv_libssl" != "yes" && test "$use_libgcrypt" != "no"; then
|
||||
if test "$found_crypto" = "none" && test "$use_libgcrypt" != "no"; then
|
||||
AC_LIB_HAVE_LINKFLAGS([gcrypt], [], [#include <gcrypt.h>])
|
||||
fi
|
||||
|
||||
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])
|
||||
LIBSREQUIRED= # libgcrypt doesn't provide a .pc file. sad face.
|
||||
LIBS="$LIBS -lgcrypt"
|
||||
found_crypto=libgcrypt
|
||||
fi
|
||||
AM_CONDITIONAL(LIBGCRYPT, test "$ac_cv_libgcrypt" = "yes")
|
||||
|
||||
# Not all OpenSSL have AES-CTR functions.
|
||||
if test "$ac_cv_libssl" = "yes"; then
|
||||
save_LDFLAGS="$LDFLAGS"
|
||||
LDFLAGS="$LDFLAGS $LIBSSL"
|
||||
AC_CHECK_FUNCS(EVP_aes_128_ctr)
|
||||
LDFLAGS="$save_LDFLAGS"
|
||||
# Look for Windows Cryptography API: Next Generation
|
||||
if test "$found_crypto" = "none" && test "$use_wincng" != "no"; then
|
||||
AC_LIB_HAVE_LINKFLAGS([bcrypt], [], [
|
||||
#include <windows.h>
|
||||
#include <bcrypt.h>
|
||||
])
|
||||
AC_LIB_HAVE_LINKFLAGS([crypt32], [], [
|
||||
#include <windows.h>
|
||||
#include <wincrypt.h>
|
||||
])
|
||||
AC_CHECK_HEADERS([ntdef.h ntstatus.h], [], [], [
|
||||
#include <windows.h>
|
||||
])
|
||||
fi
|
||||
if test "$ac_cv_libbcrypt" = "yes"; then
|
||||
AC_DEFINE(LIBSSH2_WINCNG, 1, [Use Windows CNG])
|
||||
LIBSREQUIRED= # wincng doesn't provide a .pc file. sad face.
|
||||
LIBS="$LIBS -lbcrypt"
|
||||
if test "$ac_cv_libcrypt32" = "yes"; then
|
||||
LIBS="$LIBS -lcrypt32"
|
||||
fi
|
||||
found_crypto="Windows Cryptography API: Next Generation"
|
||||
fi
|
||||
AM_CONDITIONAL(WINCNG, test "$ac_cv_libbcrypt" = "yes")
|
||||
|
||||
# Check if crypto library was found
|
||||
if test "$found_crypto" = "none"; then
|
||||
AC_MSG_ERROR([No crypto library found!
|
||||
Try --with-libssl-prefix=PATH
|
||||
or --with-libgcrypt-prefix=PATH
|
||||
or --with-wincng on Windows\
|
||||
])
|
||||
fi
|
||||
|
||||
# Look for Libz
|
||||
if test "$use_libz" != "no"; then
|
||||
AC_LIB_HAVE_LINKFLAGS([z], [], [#include <zlib.h>])
|
||||
if test "$ac_cv_libz" != yes; then
|
||||
AC_MSG_NOTICE([Cannot find libz, disabling compression])
|
||||
AC_MSG_NOTICE([Cannot find zlib, disabling compression])
|
||||
AC_MSG_NOTICE([Try --with-libz-prefix=PATH if you know you have it])
|
||||
else
|
||||
AC_DEFINE(LIBSSH2_HAVE_ZLIB, 1, [Compile in zlib support])
|
||||
if test "${LIBSREQUIRED}" != ""; then
|
||||
LIBSREQUIRED="${LIBSREQUIRED},"
|
||||
fi
|
||||
LIBSREQUIRED="${LIBSREQUIRED}zlib"
|
||||
fi
|
||||
fi
|
||||
|
||||
AC_SUBST(LIBSREQUIRED)
|
||||
|
||||
#
|
||||
# Optional Settings
|
||||
#
|
||||
@@ -215,6 +262,22 @@ AC_HELP_STRING([--disable-hidden-symbols],[Leave all symbols with default visibi
|
||||
AC_MSG_RESULT(no)
|
||||
)
|
||||
|
||||
# Build example applications?
|
||||
AC_MSG_CHECKING([whether to build example applications])
|
||||
AC_ARG_ENABLE([examples-build],
|
||||
AC_HELP_STRING([--enable-examples-build], [Build example applications (this is the default)])
|
||||
AC_HELP_STRING([--disable-examples-build], [Do not build example applications]),
|
||||
[case "$enableval" in
|
||||
no | false)
|
||||
build_examples='no'
|
||||
;;
|
||||
*)
|
||||
build_examples='yes'
|
||||
;;
|
||||
esac], [build_examples='yes'])
|
||||
AC_MSG_RESULT($build_examples)
|
||||
AM_CONDITIONAL([BUILD_EXAMPLES], [test "x$build_examples" != "xno"])
|
||||
|
||||
# Checks for header files.
|
||||
# AC_HEADER_STDC
|
||||
AC_CHECK_HEADERS([errno.h fcntl.h stdio.h stdlib.h unistd.h sys/uio.h])
|
||||
@@ -298,8 +361,9 @@ AC_MSG_NOTICE([summary of build options:
|
||||
Compiler: ${CC}
|
||||
Compiler flags: ${CFLAGS}
|
||||
Library types: Shared=${enable_shared}, Static=${enable_static}
|
||||
Crypto library: openssl: ${ac_cv_libssl:-no} (AES-CTR: ${ac_cv_func_EVP_aes_128_ctr:-N/A}) libgcrypt: ${ac_cv_libgcrypt:-no}
|
||||
Crypto library: ${found_crypto}
|
||||
Debug build: $enable_debug
|
||||
Build examples: $build_examples
|
||||
Path to sshd: $ac_cv_path_SSHD (only for self-tests)
|
||||
libz compression: $ac_cv_libz
|
||||
zlib compression: $ac_cv_libz
|
||||
])
|
||||
|
@@ -6,32 +6,57 @@
|
||||
Adam Gobiowski
|
||||
Alexander Holyapin
|
||||
Alexander Lamaison
|
||||
Alfred Gebert
|
||||
Ben Kibbey
|
||||
Bjorn Stenborg
|
||||
Carlo Bramini
|
||||
Cristian Rodríguez
|
||||
Daiki Ueno
|
||||
Dan Casey
|
||||
Dan Fandrich
|
||||
Daniel Stenberg
|
||||
Dave Hayden
|
||||
Dave McCaldon
|
||||
David J Sullivan
|
||||
David Robins
|
||||
Dmitry Smirnov
|
||||
Douglas Masterson
|
||||
Edink Kadribasic
|
||||
Erik Brossler
|
||||
Francois Dupoux
|
||||
Gellule Xg
|
||||
Grubsky Grigory
|
||||
Guenter Knauf
|
||||
Heiner Steven
|
||||
Henrik Nordstrom
|
||||
James Housleys
|
||||
Jasmeet Bagga
|
||||
Jean-Louis Charton
|
||||
Jernej Kovacic
|
||||
Joey Degges
|
||||
John Little
|
||||
Jose Baars
|
||||
Jussi Mononen
|
||||
Kamil Dudka
|
||||
Lars Nordin
|
||||
Mark McPherson
|
||||
Mark Smith
|
||||
Markus Moeller
|
||||
Matt Lilley
|
||||
Matthew Booth
|
||||
Maxime Larocque
|
||||
Mike Protts
|
||||
Mikhail Gusarov
|
||||
Neil Gierman
|
||||
Olivier Hervieu
|
||||
Paul Howarth
|
||||
Paul Querna
|
||||
Paul Veldkamp
|
||||
Peter Krempa
|
||||
Peter O'Gorman
|
||||
Peter Stuge
|
||||
Pierre Joye
|
||||
Rafael Kitover
|
||||
Romain Bondue
|
||||
Sara Golemon
|
||||
Satish Mittal
|
||||
@@ -39,10 +64,16 @@ Sean Peterson
|
||||
Selcuk Gueney
|
||||
Simon Hart
|
||||
Simon Josefsson
|
||||
Sofian Brabez
|
||||
Steven Ayre
|
||||
Steven Dake
|
||||
Steven Van Ingelgem
|
||||
TJ Saunders
|
||||
Tommy Lindgren
|
||||
Tor Arntsen
|
||||
Vincent Jaulin
|
||||
Vincent Torri
|
||||
Vlad Grachov
|
||||
Wez Furlong
|
||||
Yang Tse
|
||||
Zl Liu
|
29
docs/BINDINGS
Normal file
29
docs/BINDINGS
Normal file
@@ -0,0 +1,29 @@
|
||||
|
||||
Creative people have written bindings or interfaces for various environments
|
||||
and programming languages. Using one of these bindings allows you to take
|
||||
advantage of libssh2 directly from within your favourite language.
|
||||
|
||||
The bindings listed below are not part of the libssh2 distribution archives,
|
||||
but must be downloaded and installed separately.
|
||||
|
||||
Cocoa/Objective-C
|
||||
https://github.com/karelia/libssh2_sftp-Cocoa-wrapper
|
||||
|
||||
Haskell
|
||||
FFI bindings - http://hackage.haskell.org/package/libssh2
|
||||
|
||||
Perl
|
||||
Net::SSH2 - http://search.cpan.org/~rkitover/Net-SSH2-0.45/lib/Net/SSH2.pm
|
||||
|
||||
PHP
|
||||
ssh2 - http://pecl.php.net/package/ssh2
|
||||
|
||||
Python
|
||||
pylibssh2 - http://www.wallix.org/pylibssh2-project/
|
||||
|
||||
Python-ctypes
|
||||
|
||||
PySsh2 - https://github.com/gellule/PySsh2
|
||||
|
||||
Ruby
|
||||
libssh2-ruby - https://github.com/mitchellh/libssh2-ruby
|
325
docs/INSTALL
Normal file
325
docs/INSTALL
Normal file
@@ -0,0 +1,325 @@
|
||||
Installation Instructions
|
||||
*************************
|
||||
|
||||
Copyright (C) 1994, 1995, 1996, 1999, 2000, 2001, 2002, 2004, 2005 Free
|
||||
Software Foundation, Inc.
|
||||
|
||||
This file is free documentation; the Free Software Foundation gives
|
||||
unlimited permission to copy, distribute and modify it.
|
||||
|
||||
Basic Installation
|
||||
==================
|
||||
|
||||
These are generic installation instructions.
|
||||
|
||||
The `configure' shell script attempts to guess correct values for
|
||||
various system-dependent variables used during compilation. It uses
|
||||
those values to create a `Makefile' in each directory of the package.
|
||||
It may also create one or more `.h' files containing system-dependent
|
||||
definitions. Finally, it creates a shell script `config.status' that
|
||||
you can run in the future to recreate the current configuration, and a
|
||||
file `config.log' containing compiler output (useful mainly for
|
||||
debugging `configure').
|
||||
|
||||
It can also use an optional file (typically called `config.cache'
|
||||
and enabled with `--cache-file=config.cache' or simply `-C') that saves
|
||||
the results of its tests to speed up reconfiguring. (Caching is
|
||||
disabled by default to prevent problems with accidental use of stale
|
||||
cache files.)
|
||||
|
||||
If you need to do unusual things to compile the package, please try
|
||||
to figure out how `configure' could check whether to do them, and mail
|
||||
diffs or instructions to the address given in the `README' so they can
|
||||
be considered for the next release. If you are using the cache, and at
|
||||
some point `config.cache' contains results you don't want to keep, you
|
||||
may remove or edit it.
|
||||
|
||||
The file `configure.ac' (or `configure.in') is used to create
|
||||
`configure' by a program called `autoconf'. You only need
|
||||
`configure.ac' if you want to change it or regenerate `configure' using
|
||||
a newer version of `autoconf'.
|
||||
|
||||
The simplest way to compile this package is:
|
||||
|
||||
1. `cd' to the directory containing the package's source code and type
|
||||
`./configure' to configure the package for your system. If you're
|
||||
using `csh' on an old version of System V, you might need to type
|
||||
`sh ./configure' instead to prevent `csh' from trying to execute
|
||||
`configure' itself.
|
||||
|
||||
Running `configure' takes awhile. While running, it prints some
|
||||
messages telling which features it is checking for.
|
||||
|
||||
2. Type `make' to compile the package.
|
||||
|
||||
3. Optionally, type `make check' to run any self-tests that come with
|
||||
the package.
|
||||
|
||||
4. Type `make install' to install the programs and any data files and
|
||||
documentation.
|
||||
|
||||
5. You can remove the program binaries and object files from the
|
||||
source code directory by typing `make clean'. To also remove the
|
||||
files that `configure' created (so you can compile the package for
|
||||
a different kind of computer), type `make distclean'. There is
|
||||
also a `make maintainer-clean' target, but that is intended mainly
|
||||
for the package's developers. If you use it, you may have to get
|
||||
all sorts of other programs in order to regenerate files that came
|
||||
with the distribution.
|
||||
|
||||
Compilers and Options
|
||||
=====================
|
||||
|
||||
Some systems require unusual options for compilation or linking that the
|
||||
`configure' script does not know about. Run `./configure --help' for
|
||||
details on some of the pertinent environment variables.
|
||||
|
||||
You can give `configure' initial values for configuration parameters
|
||||
by setting variables in the command line or in the environment. Here
|
||||
is an example:
|
||||
|
||||
./configure CC=c89 CFLAGS=-O2 LIBS=-lposix
|
||||
|
||||
*Note Defining Variables::, for more details.
|
||||
|
||||
Compiling For Multiple Architectures
|
||||
====================================
|
||||
|
||||
You can compile the package for more than one kind of computer at the
|
||||
same time, by placing the object files for each architecture in their
|
||||
own directory. To do this, you must use a version of `make' that
|
||||
supports the `VPATH' variable, such as GNU `make'. `cd' to the
|
||||
directory where you want the object files and executables to go and run
|
||||
the `configure' script. `configure' automatically checks for the
|
||||
source code in the directory that `configure' is in and in `..'.
|
||||
|
||||
If you have to use a `make' that does not support the `VPATH'
|
||||
variable, you have to compile the package for one architecture at a
|
||||
time in the source code directory. After you have installed the
|
||||
package for one architecture, use `make distclean' before reconfiguring
|
||||
for another architecture.
|
||||
|
||||
Installation Names
|
||||
==================
|
||||
|
||||
By default, `make install' installs the package's commands under
|
||||
`/usr/local/bin', include files under `/usr/local/include', etc. You
|
||||
can specify an installation prefix other than `/usr/local' by giving
|
||||
`configure' the option `--prefix=PREFIX'.
|
||||
|
||||
You can specify separate installation prefixes for
|
||||
architecture-specific files and architecture-independent files. If you
|
||||
pass the option `--exec-prefix=PREFIX' to `configure', the package uses
|
||||
PREFIX as the prefix for installing programs and libraries.
|
||||
Documentation and other data files still use the regular prefix.
|
||||
|
||||
In addition, if you use an unusual directory layout you can give
|
||||
options like `--bindir=DIR' to specify different values for particular
|
||||
kinds of files. Run `configure --help' for a list of the directories
|
||||
you can set and what kinds of files go in them.
|
||||
|
||||
If the package supports it, you can cause programs to be installed
|
||||
with an extra prefix or suffix on their names by giving `configure' the
|
||||
option `--program-prefix=PREFIX' or `--program-suffix=SUFFIX'.
|
||||
|
||||
Optional Features
|
||||
=================
|
||||
|
||||
Some packages pay attention to `--enable-FEATURE' options to
|
||||
`configure', where FEATURE indicates an optional part of the package.
|
||||
They may also pay attention to `--with-PACKAGE' options, where PACKAGE
|
||||
is something like `gnu-as' or `x' (for the X Window System). The
|
||||
`README' should mention any `--enable-' and `--with-' options that the
|
||||
package recognizes.
|
||||
|
||||
For packages that use the X Window System, `configure' can usually
|
||||
find the X include and library files automatically, but if it doesn't,
|
||||
you can use the `configure' options `--x-includes=DIR' and
|
||||
`--x-libraries=DIR' to specify their locations.
|
||||
|
||||
Specifying the System Type
|
||||
==========================
|
||||
|
||||
There may be some features `configure' cannot figure out automatically,
|
||||
but needs to determine by the type of machine the package will run on.
|
||||
Usually, assuming the package is built to be run on the _same_
|
||||
architectures, `configure' can figure that out, but if it prints a
|
||||
message saying it cannot guess the machine type, give it the
|
||||
`--build=TYPE' option. TYPE can either be a short name for the system
|
||||
type, such as `sun4', or a canonical name which has the form:
|
||||
|
||||
CPU-COMPANY-SYSTEM
|
||||
|
||||
where SYSTEM can have one of these forms:
|
||||
|
||||
OS KERNEL-OS
|
||||
|
||||
See the file `config.sub' for the possible values of each field. If
|
||||
`config.sub' isn't included in this package, then this package doesn't
|
||||
need to know the machine type.
|
||||
|
||||
If you are _building_ compiler tools for cross-compiling, you should
|
||||
use the option `--target=TYPE' to select the type of system they will
|
||||
produce code for.
|
||||
|
||||
If you want to _use_ a cross compiler, that generates code for a
|
||||
platform different from the build platform, you should specify the
|
||||
"host" platform (i.e., that on which the generated programs will
|
||||
eventually be run) with `--host=TYPE'.
|
||||
|
||||
Sharing Defaults
|
||||
================
|
||||
|
||||
If you want to set default values for `configure' scripts to share, you
|
||||
can create a site shell script called `config.site' that gives default
|
||||
values for variables like `CC', `cache_file', and `prefix'.
|
||||
`configure' looks for `PREFIX/share/config.site' if it exists, then
|
||||
`PREFIX/etc/config.site' if it exists. Or, you can set the
|
||||
`CONFIG_SITE' environment variable to the location of the site script.
|
||||
A warning: not all `configure' scripts look for a site script.
|
||||
|
||||
Defining Variables
|
||||
==================
|
||||
|
||||
Variables not defined in a site shell script can be set in the
|
||||
environment passed to `configure'. However, some packages may run
|
||||
configure again during the build, and the customized values of these
|
||||
variables may be lost. In order to avoid this problem, you should set
|
||||
them in the `configure' command line, using `VAR=value'. For example:
|
||||
|
||||
./configure CC=/usr/local2/bin/gcc
|
||||
|
||||
causes the specified `gcc' to be used as the C compiler (unless it is
|
||||
overridden in the site shell script). Here is a another example:
|
||||
|
||||
/bin/bash ./configure CONFIG_SHELL=/bin/bash
|
||||
|
||||
Here the `CONFIG_SHELL=/bin/bash' operand causes subsequent
|
||||
configuration-related scripts to be executed by `/bin/bash'.
|
||||
|
||||
`configure' Invocation
|
||||
======================
|
||||
|
||||
`configure' recognizes the following options to control how it operates.
|
||||
|
||||
`--help'
|
||||
`-h'
|
||||
Print a summary of the options to `configure', and exit.
|
||||
|
||||
`--version'
|
||||
`-V'
|
||||
Print the version of Autoconf used to generate the `configure'
|
||||
script, and exit.
|
||||
|
||||
`--cache-file=FILE'
|
||||
Enable the cache: use and save the results of the tests in FILE,
|
||||
traditionally `config.cache'. FILE defaults to `/dev/null' to
|
||||
disable caching.
|
||||
|
||||
`--config-cache'
|
||||
`-C'
|
||||
Alias for `--cache-file=config.cache'.
|
||||
|
||||
`--quiet'
|
||||
`--silent'
|
||||
`-q'
|
||||
Do not print messages saying which checks are being made. To
|
||||
suppress all normal output, redirect it to `/dev/null' (any error
|
||||
messages will still be shown).
|
||||
|
||||
`--srcdir=DIR'
|
||||
Look for the package's source code in directory DIR. Usually
|
||||
`configure' can determine that directory automatically.
|
||||
|
||||
`configure' also accepts some other, not widely useful, options. Run
|
||||
`configure --help' for more details.
|
||||
|
||||
More configure options
|
||||
======================
|
||||
|
||||
Some ./configure options deserve additional comments:
|
||||
|
||||
* --enable-crypt-none
|
||||
|
||||
The SSH2 Transport allows for unencrypted data
|
||||
transmission using the "none" cipher. Because this is
|
||||
such a huge security hole, it is typically disabled on
|
||||
SSH2 implementations and is disabled in libssh2 by
|
||||
default as well.
|
||||
|
||||
Enabling this option will allow for "none" as a
|
||||
negotiable method, however it still requires that the
|
||||
method be advertized by the remote end and that no
|
||||
more-preferable methods are available.
|
||||
|
||||
* --enable-mac-none
|
||||
|
||||
The SSH2 Transport also allows implementations to
|
||||
forego a message authentication code. While this is
|
||||
less of a security risk than using a "none" cipher, it
|
||||
is still not recommended as disabling MAC hashes
|
||||
removes a layer of security.
|
||||
|
||||
Enabling this option will allow for "none" as a
|
||||
negotiable method, however it still requires that the
|
||||
method be advertized by the remote end and that no
|
||||
more-preferable methods are available.
|
||||
|
||||
* --disable-gex-new
|
||||
|
||||
The diffie-hellman-group-exchange-sha1 (dh-gex) key
|
||||
exchange method originally defined an exchange
|
||||
negotiation using packet type 30 to request a
|
||||
generation pair based on a single target value. Later
|
||||
refinement of dh-gex provided for range and target
|
||||
values. By default libssh2 will use the newer range
|
||||
method.
|
||||
|
||||
If you experience trouble connecting to an old SSH
|
||||
server using dh-gex, try this option to fallback on
|
||||
the older more reliable method.
|
||||
|
||||
* --with-libgcrypt
|
||||
* --without-libgcrypt
|
||||
* --with-libgcrypt-prefix=DIR
|
||||
|
||||
libssh2 can use the Libgcrypt library
|
||||
(http://www.gnupg.org/) for cryptographic operations.
|
||||
Either Libgcrypt or OpenSSL is required.
|
||||
|
||||
Configure will attempt to locate Libgcrypt
|
||||
automatically.
|
||||
|
||||
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
|
||||
(http://www.openssl.org) for cryptographic operations.
|
||||
Either Libgcrypt or OpenSSL is required.
|
||||
|
||||
Configure will attempt to locate OpenSSL in the
|
||||
default location.
|
||||
|
||||
If your installation of OpenSSL is in another
|
||||
location, specify it using --with-libssl-prefix.
|
||||
|
||||
* --with-libz
|
||||
* --without-libz
|
||||
* --with-libz-prefix=[DIR]
|
||||
|
||||
If present, libssh2 will attempt to use the zlib
|
||||
(http://www.zlib.org) for payload compression, however
|
||||
zlib is not required.
|
||||
|
||||
If your installation of Libz is in another location,
|
||||
specify it using --with-libz-prefix.
|
||||
|
||||
* --enable-debug
|
||||
|
||||
Will make the build use more pedantic and strict compiler
|
||||
options as well as enable the libssh2_trace() function (for
|
||||
showing debug traces).
|
@@ -1,6 +1,6 @@
|
||||
# $Id: Makefile.am,v 1.37 2009/03/26 15:41:15 bagder Exp $
|
||||
|
||||
EXTRA_DIST = template.3
|
||||
EXTRA_DIST = template.3 BINDINGS INSTALL HACKING TODO AUTHORS
|
||||
|
||||
dist_man_MANS = \
|
||||
libssh2_agent_connect.3 \
|
||||
@@ -102,6 +102,7 @@ dist_man_MANS = \
|
||||
libssh2_session_free.3 \
|
||||
libssh2_session_get_blocking.3 \
|
||||
libssh2_session_get_timeout.3 \
|
||||
libssh2_session_handshake.3 \
|
||||
libssh2_session_hostkey.3 \
|
||||
libssh2_session_init.3 \
|
||||
libssh2_session_init_ex.3 \
|
||||
@@ -120,6 +121,7 @@ dist_man_MANS = \
|
||||
libssh2_sftp_fstat.3 \
|
||||
libssh2_sftp_fstat_ex.3 \
|
||||
libssh2_sftp_fstatvfs.3 \
|
||||
libssh2_sftp_fsync.3 \
|
||||
libssh2_sftp_get_channel.3 \
|
||||
libssh2_sftp_init.3 \
|
||||
libssh2_sftp_last_error.3 \
|
||||
|
@@ -1,6 +1,6 @@
|
||||
.TH libssh2_banner_set 3 "1 Jun 2007" "libssh2 0.15" "libssh2 manual"
|
||||
.SH NAME
|
||||
libssh2_banner_set - set the SSH prococol banner for the local client
|
||||
libssh2_banner_set - set the SSH protocol banner for the local client
|
||||
.SH SYNOPSIS
|
||||
#include <libssh2.h>
|
||||
|
||||
|
@@ -19,7 +19,7 @@ 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
|
||||
uses, but there's no way for an application to free this data in a safe and
|
||||
reliable way!
|
||||
.SH RETURN VALUE
|
||||
0 if successful, \-1 if any error occurred.
|
||||
|
@@ -8,7 +8,7 @@ int
|
||||
libssh2_channel_get_exit_status(LIBSSH2_CHANNEL* channel)
|
||||
|
||||
.SH DESCRIPTION
|
||||
\fIchannel\fP - Closed channel stream to retreive exit status from.
|
||||
\fIchannel\fP - Closed channel stream to retrieve exit status from.
|
||||
|
||||
Returns the exit code raised by the process running on the remote host at
|
||||
the other end of the named channel. Note that the exit status may not be
|
||||
|
@@ -4,7 +4,7 @@ libssh2_channel_window_write - convenience macro for \fIlibssh2_channel_window_w
|
||||
.SH SYNOPSIS
|
||||
#include <libssh2.h>
|
||||
|
||||
unsigend long libssh2_channel_window_write(LIBSSH2_CHANNEL *channel);
|
||||
unsigned long libssh2_channel_window_write(LIBSSH2_CHANNEL *channel);
|
||||
|
||||
.SH DESCRIPTION
|
||||
This is a macro defined in a public libssh2 header file that is using the
|
||||
|
@@ -9,11 +9,11 @@ libssh2_channel_window_write_ex(LIBSSH2_CHANNEL *channel,
|
||||
unsigned long *window_size_initial)
|
||||
.SH DESCRIPTION
|
||||
Check the status of the write window Returns the number of bytes which may be
|
||||
safely writen on the channel without blocking. 'window_size_initial' (if
|
||||
safely written on the channel without blocking. 'window_size_initial' (if
|
||||
passed) will be populated with the size of the initial window as defined by
|
||||
the channel_open request
|
||||
.SH RETURN VALUE
|
||||
Number of bytes which may be safely writen on the channel without blocking.
|
||||
Number of bytes which may be safely written on the channel without blocking.
|
||||
.SH ERRORS
|
||||
|
||||
.SH SEE ALSO
|
||||
|
@@ -18,8 +18,9 @@ Returns the computed digest of the remote system's hostkey. The length of
|
||||
the returned string is hash_type specific (e.g. 16 bytes for MD5,
|
||||
20 bytes for SHA1).
|
||||
.SH RETURN VALUE
|
||||
Computed hostkey hash value. or NULL if the session has not yet been started
|
||||
up. (The hash consists of raw binary bytes, not hex digits, so is not
|
||||
directly printable.)
|
||||
Computed hostkey hash value, or NULL if the information is not available
|
||||
(either the session has not yet been started up, or the requested hash
|
||||
algorithm was not available). The hash consists of raw binary bytes, not hex
|
||||
digits, so it is not directly printable.
|
||||
.SH SEE ALSO
|
||||
.BR libssh2_session_init_ex(3)
|
||||
|
@@ -36,7 +36,7 @@ The salt has to be provided base64 encoded with a trailing zero byte.
|
||||
argument
|
||||
|
||||
\fItypemask\fP is a bitmask that specifies format and info about the data
|
||||
passed to this function. Specificly, it details what format the host name is,
|
||||
passed to this function. Specifically, it details what format the host name is,
|
||||
what format the key is and what key type it is.
|
||||
|
||||
The host name is given as one of the following types:
|
||||
|
@@ -40,7 +40,7 @@ argument
|
||||
\fIcommentlen\fP is the total size in bytes of the comment pointed to by the \fIcomment\fP argument
|
||||
|
||||
\fItypemask\fP is a bitmask that specifies format and info about the data
|
||||
passed to this function. Specificly, it details what format the host name is,
|
||||
passed to this function. Specifically, it details what format the host name is,
|
||||
what format the key is and what key type it is.
|
||||
|
||||
The host name is given as one of the following types:
|
||||
|
@@ -25,7 +25,7 @@ IP numerical address of the host or the full name.
|
||||
argument
|
||||
|
||||
\fItypemask\fP is a bitmask that specifies format and info about the data
|
||||
passed to this function. Specificly, it details what format the host name is,
|
||||
passed to this function. Specifically, it details what format the host name is,
|
||||
what format the key is and what key type it is.
|
||||
|
||||
The host name is given as one of the following types:
|
||||
|
@@ -30,7 +30,7 @@ addition to the plain host name only check.
|
||||
argument
|
||||
|
||||
\fItypemask\fP is a bitmask that specifies format and info about the data
|
||||
passed to this function. Specificly, it details what format the host name is,
|
||||
passed to this function. Specifically, it details what format the host name is,
|
||||
what format the key is and what key type it is.
|
||||
|
||||
The host name is given as one of the following types:
|
||||
|
@@ -8,7 +8,7 @@ int libssh2_poll(LIBSSH2_POLLFD *fds, unsigned int nfds, long timeout);
|
||||
.SH DESCRIPTION
|
||||
This function is deprecated. Do note use. We encourage users to instead use
|
||||
the \fIpoll(3)\fP or \fIselect(3)\fP functions to check for socket activity or
|
||||
when specific sockets are ready to get recevied from or send to.
|
||||
when specific sockets are ready to get received from or send to.
|
||||
|
||||
Poll for activity on a socket, channel, listener, or any combination of these
|
||||
three types. The calling semantics for this function generally match
|
||||
|
@@ -17,7 +17,7 @@ de-referenced pointer, the internal storage of the session instance may be
|
||||
modified in place.
|
||||
|
||||
.SH RETURN VALUE
|
||||
A pointer to session internal storage whos contents point to previously
|
||||
A pointer to session internal storage who's contents point to previously
|
||||
provided abstract data.
|
||||
|
||||
.SH SEE ALSO
|
||||
|
@@ -1,6 +1,6 @@
|
||||
.TH libssh2_session_banner_set 3 "9 Sep 2011" "libssh2 1.4.0" "libssh2 manual"
|
||||
.SH NAME
|
||||
libssh2_session_banner_set - set the SSH prococol banner for the local client
|
||||
libssh2_session_banner_set - set the SSH protocol banner for the local client
|
||||
.SH SYNOPSIS
|
||||
#include <libssh2.h>
|
||||
|
||||
|
@@ -18,7 +18,7 @@ libssh2_session_disconnect(LIBSSH2_SESSION *session, const char *description);
|
||||
|
||||
\fIdescription\fP - Human readable reason for disconnection.
|
||||
|
||||
\fIlang\fP - Localization string describing the langauge/encoding of the description provided.
|
||||
\fIlang\fP - Localization string describing the language/encoding of the description provided.
|
||||
|
||||
Send a disconnect message to the remote host associated with \fIsession\fP,
|
||||
along with a \fIreason\fP symbol and a verbose \fIdescription\fP.
|
||||
|
@@ -19,7 +19,7 @@ If a method is listed which is not supported by libssh2 it will be
|
||||
ignored and not sent to the remote host during protocol negotiation.
|
||||
|
||||
Set preferred methods to be negotiated. These
|
||||
preferrences must be set prior to calling
|
||||
preferences must be set prior to calling
|
||||
.BR libssh2_session_handshake(3)
|
||||
as they are used during the protocol initiation phase.
|
||||
|
||||
|
@@ -12,7 +12,7 @@ int libssh2_session_supported_algs(LIBSSH2_SESSION* session,
|
||||
\fIsession\fP - An instance of initialized LIBSSH2_SESSION (the function will
|
||||
use its pointer to the memory allocation function). \fImethod_type\fP - Method
|
||||
type. See .BR \fIlibssh2_session_method_pref(3)\fP. \fIalgs\fP - Address of a
|
||||
pointer that will point to an array af returned algorithms
|
||||
pointer that will point to an array of returned algorithms
|
||||
|
||||
Get a list of supported algorithms for the given \fImethod_type\fP. The
|
||||
method_type parameter is equivalent to method_type in
|
||||
@@ -36,7 +36,7 @@ const char **algorithms;
|
||||
int rc, i;
|
||||
LIBSSH2_SESSION *session;
|
||||
|
||||
/* initilize session */
|
||||
/* initialize session */
|
||||
session = libssh2_session_init();
|
||||
rc = libssh2_session_supported_algs(session,
|
||||
LIBSSH2_METHOD_CRYPT_CS,
|
||||
|
@@ -20,7 +20,7 @@ or \fBlibssh2_sftp_opendir(3)\fP (which is a macro).
|
||||
|
||||
Close an active LIBSSH2_SFTP_HANDLE. Because files and directories share the
|
||||
same underlying storage mechanism these methods may be used
|
||||
interchangably. \fBlibssh2_sftp_close(3)\fP and \fBlibssh2_sftp_closedir(3)\fP
|
||||
interchangeably. \fBlibssh2_sftp_close(3)\fP and \fBlibssh2_sftp_closedir(3)\fP
|
||||
are macros for \fBlibssh2_sftp_close_handle(3)\fP.
|
||||
|
||||
.SH RETURN VALUE
|
||||
|
@@ -10,7 +10,7 @@ int
|
||||
libssh2_sftp_fstat_ex(LIBSSH2_SFTP_HANDLE *handle,
|
||||
LIBSSH2_SFTP_ATTRIBUTES *attrs, int setstat)
|
||||
|
||||
#define libbssh2_sftp_fstat(handle, attrs) \\
|
||||
#define libssh2_sftp_fstat(handle, attrs) \\
|
||||
libssh2_sftp_fstat_ex((handle), (attrs), 0)
|
||||
#define libssh2_sftp_fsetstat(handle, attrs) \\
|
||||
libssh2_sftp_fstat_ex((handle), (attrs), 1)
|
||||
@@ -60,7 +60,7 @@ most common ones are:
|
||||
|
||||
To check for specific user permissions, the set of defines are in the
|
||||
pattern LIBSSH2_SFTP_S_I<action><who> where <action> is R, W or X for
|
||||
read, write and excutable and <who> is USR, GRP and OTH for user,
|
||||
read, write and executable and <who> is USR, GRP and OTH for user,
|
||||
group and other. So, you check for a user readable file, use the bit
|
||||
\fILIBSSH2_SFTP_S_IRUSR\fP while you want to see if it is executable
|
||||
for other, you use \fILIBSSH2_SFTP_S_IXOTH\fP and so on.
|
||||
|
39
docs/libssh2_sftp_fsync.3
Normal file
39
docs/libssh2_sftp_fsync.3
Normal file
@@ -0,0 +1,39 @@
|
||||
.TH libssh2_sftp_fsync 3 "8 Apr 2013" "libssh2 1.4.4" "libssh2 manual"
|
||||
.SH NAME
|
||||
libssh2_sftp_fsync - synchronize file to disk
|
||||
.SH SYNOPSIS
|
||||
.nf
|
||||
#include <libssh2.h>
|
||||
#include <libssh2_sftp.h>
|
||||
|
||||
int
|
||||
libssh2_sftp_fsync(LIBSSH2_SFTP_HANDLE *handle)
|
||||
.fi
|
||||
.SH DESCRIPTION
|
||||
This function causes the remote server to synchronize the file
|
||||
data and metadata to disk (like fsync(2)).
|
||||
|
||||
For this to work requires fsync@openssh.com support on the server.
|
||||
|
||||
\fIhandle\fP - SFTP File Handle as returned by
|
||||
.BR libssh2_sftp_open_ex(3)
|
||||
|
||||
.SH RETURN VALUE
|
||||
Returns 0 on success or negative on failure. If used in non-blocking mode, it
|
||||
returns LIBSSH2_ERROR_EAGAIN when it would otherwise block. While
|
||||
LIBSSH2_ERROR_EAGAIN is a negative number, it isn't really a failure per se.
|
||||
.SH ERRORS
|
||||
\fILIBSSH2_ERROR_ALLOC\fP - An internal memory allocation call failed.
|
||||
|
||||
\fILIBSSH2_ERROR_SOCKET_SEND\fP - Unable to send data on socket.
|
||||
|
||||
\fILIBSSH2_ERROR_SFTP_PROTOCOL\fP - An invalid SFTP protocol response
|
||||
was received on the socket, or an SFTP operation caused an errorcode
|
||||
to be returned by the server. In particular, this can be returned if
|
||||
the SSH server does not support the fsync operation: the SFTP subcode
|
||||
\fILIBSSH2_FX_OP_UNSUPPORTED\fP will be returned in this case.
|
||||
|
||||
.SH AVAILABILITY
|
||||
Added in libssh2 1.4.4 and OpenSSH 6.3.
|
||||
.SH SEE ALSO
|
||||
.BR fsync(2)
|
@@ -15,7 +15,7 @@ libssh2_sftp_mkdir(LIBSSH2_SFTP *sftp, const char *path, long mode);
|
||||
.BR libssh2_sftp_init(3)
|
||||
|
||||
\fIpath\fP - full path of the new directory to create. Note that the new
|
||||
directory's parents must all exist priot to making this call.
|
||||
directory's parents must all exist prior to making this call.
|
||||
|
||||
\fIpath_len\fP - length of the full path of the new directory to create.
|
||||
|
||||
|
@@ -29,7 +29,7 @@ filesystem entry
|
||||
Bitmask flags made up of LIBSSH2_SFTP_RENAME_* constants.
|
||||
|
||||
Rename a filesystem object on the remote filesystem. The semantics of
|
||||
this command typically include the ability to move a filsystem object
|
||||
this command typically include the ability to move a filesystem object
|
||||
between folders and/or filesystem mounts. If the LIBSSH2_SFTP_RENAME_OVERWRITE
|
||||
flag is not set and the destfile entry already exists, the operation
|
||||
will fail. Use of the other two flags indicate a preference (but not a
|
||||
|
@@ -4,7 +4,7 @@ libssh2_sftp_rewind - convenience macro for \fIlibssh2_sftp_seek64(3)\fP calls
|
||||
.SH SYNOPSIS
|
||||
#include <libssh2.h>
|
||||
|
||||
int libssh2_sftp_rewind(LINBSSH2_SFTP_HANDLE *handle);
|
||||
int libssh2_sftp_rewind(LIBSSH2_SFTP_HANDLE *handle);
|
||||
|
||||
.SH DESCRIPTION
|
||||
This is a macro defined in a public libssh2 header file that is using the
|
||||
|
@@ -4,7 +4,7 @@ libssh2_sftp_stat - convenience macro for \fIlibssh2_sftp_fstat_ex(3)\fP calls
|
||||
.SH SYNOPSIS
|
||||
#include <libssh2.h>
|
||||
|
||||
int libssh2_sftp_stat(LIBSSH2_SFTP *sftp, const char *path, LIBSSH2_STFP_ATTRIBUTES *attrs);
|
||||
int libssh2_sftp_stat(LIBSSH2_SFTP *sftp, const char *path, LIBSSH2_SFTP_ATTRIBUTES *attrs);
|
||||
|
||||
.SH DESCRIPTION
|
||||
This is a macro defined in a public libssh2 header file that is using the
|
||||
|
@@ -48,7 +48,7 @@ These are convenience macros:
|
||||
.BR libssh2_sftp_realpath(3)
|
||||
: Resolve a complex, relative, or symlinked filepath to its effective target.
|
||||
.SH RETURN VALUE
|
||||
When using LIBSSH2_SFTP_SYMLINK, this funtion returns 0 on success or negative
|
||||
When using LIBSSH2_SFTP_SYMLINK, this function returns 0 on success or negative
|
||||
on failure.
|
||||
|
||||
When using LIBSSH2_SFTP_READLINK or LIBSSH2_SFTP_REALPATH, it returns the
|
||||
|
@@ -28,7 +28,7 @@ distinguished from a failing case by examining
|
||||
\fIlibssh2_userauth_authenticated(3)\fP.
|
||||
.SH RETURN VALUE
|
||||
On success a comma delimited list of supported authentication schemes. This
|
||||
list is internally managed by libssh2. On failure ruturns NULL.
|
||||
list is internally managed by libssh2. On failure returns NULL.
|
||||
.SH ERRORS
|
||||
\fILIBSSH2_ERROR_ALLOC\fP - An internal memory allocation call failed.
|
||||
|
||||
|
@@ -7,24 +7,28 @@ libssh2_userauth_publickey_fromfile - authenticate a session with a public key,
|
||||
.nf
|
||||
int libssh2_userauth_publickey_fromfile_ex(LIBSSH2_SESSION *session,
|
||||
const char *username,
|
||||
unsigned int ousername_len,
|
||||
const char *publickey,
|
||||
const char *privatekey,
|
||||
const char *passphrase);
|
||||
.SH DESCRIPTION
|
||||
\fIsession\fP - Session instance as returned by
|
||||
.BR libssh2_session_init_ex(3)
|
||||
\fIsession\fP - Session instance as returned by
|
||||
\fBlibssh2_session_init_ex(3)\fP
|
||||
|
||||
\fIusername\fP - Remote user name to authenticate as.
|
||||
\fIusername\fP - Pointer to user name to authenticate as.
|
||||
|
||||
\fIusername_len\fP - Length of username.
|
||||
\fIusername_len\fP - Length of \fIusername\fP.
|
||||
|
||||
\fIpublickey\fP - Path and name of public key file. (e.g. /etc/ssh/hostkey.pub)
|
||||
\fIpublickey\fP - Path name of the public key file.
|
||||
(e.g. /etc/ssh/hostkey.pub). If libssh2 is built against OpenSSL, this option
|
||||
can be set to NULL.
|
||||
|
||||
\fIprivatekey\fP - Path and name of private key file. (e.g. /etc/ssh/hostkey)
|
||||
\fIprivatekey\fP - Path name of the private key file. (e.g. /etc/ssh/hostkey)
|
||||
|
||||
\fIpassphrase\fP - Passphrase to use when decoding private key file.
|
||||
\fIpassphrase\fP - Passphrase to use when decoding \fIprivatekey\fP.
|
||||
|
||||
Attempt public key authentication using a PEM encoded private key file stored on disk
|
||||
Attempt public key authentication using a PEM encoded private key file stored
|
||||
on disk
|
||||
|
||||
.SH RETURN VALUE
|
||||
Return 0 on success or negative on failure. It returns
|
||||
|
@@ -48,7 +48,7 @@ enum {
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
int rc, sock = -1, listensock = -1, forwardsock = -1, i, auth = AUTH_NONE;
|
||||
int rc, i, auth = AUTH_NONE;
|
||||
struct sockaddr_in sin;
|
||||
socklen_t sinlen;
|
||||
const char *fingerprint;
|
||||
@@ -64,11 +64,19 @@ int main(int argc, char *argv[])
|
||||
|
||||
#ifdef WIN32
|
||||
char sockopt;
|
||||
SOCKET sock = INVALID_SOCKET;
|
||||
SOCKET listensock = INVALID_SOCKET, forwardsock = INVALID_SOCKET;
|
||||
WSADATA wsadata;
|
||||
int err;
|
||||
|
||||
WSAStartup(MAKEWORD(2,0), &wsadata);
|
||||
err = WSAStartup(MAKEWORD(2,0), &wsadata);
|
||||
if (err != 0) {
|
||||
fprintf(stderr, "WSAStartup failed with error: %d\n", err);
|
||||
return 1;
|
||||
}
|
||||
#else
|
||||
int sockopt;
|
||||
int sockopt, sock = -1;
|
||||
int listensock = -1, forwardsock = -1;
|
||||
#endif
|
||||
|
||||
if (argc > 1)
|
||||
@@ -94,6 +102,18 @@ int main(int argc, char *argv[])
|
||||
|
||||
/* Connect to SSH server */
|
||||
sock = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP);
|
||||
#ifdef WIN32
|
||||
if (sock == INVALID_SOCKET) {
|
||||
fprintf(stderr, "failed to open socket!\n");
|
||||
return -1;
|
||||
}
|
||||
#else
|
||||
if (sock == -1) {
|
||||
perror("socket");
|
||||
return -1;
|
||||
}
|
||||
#endif
|
||||
|
||||
sin.sin_family = AF_INET;
|
||||
if (INADDR_NONE == (sin.sin_addr.s_addr = inet_addr(server_ip))) {
|
||||
perror("inet_addr");
|
||||
@@ -135,7 +155,7 @@ int main(int argc, char *argv[])
|
||||
|
||||
/* check what authentication methods are available */
|
||||
userauthlist = libssh2_userauth_list(session, username, strlen(username));
|
||||
printf("Authentication methods: %s\n", userauthlist);
|
||||
fprintf(stderr, "Authentication methods: %s\n", userauthlist);
|
||||
if (strstr(userauthlist, "password"))
|
||||
auth |= AUTH_PASSWORD;
|
||||
if (strstr(userauthlist, "publickey"))
|
||||
@@ -157,16 +177,28 @@ int main(int argc, char *argv[])
|
||||
} else if (auth & AUTH_PUBLICKEY) {
|
||||
if (libssh2_userauth_publickey_fromfile(session, username, keyfile1,
|
||||
keyfile2, password)) {
|
||||
printf("\tAuthentication by public key failed!\n");
|
||||
fprintf(stderr, "\tAuthentication by public key failed!\n");
|
||||
goto shutdown;
|
||||
}
|
||||
printf("\tAuthentication by public key succeeded.\n");
|
||||
fprintf(stderr, "\tAuthentication by public key succeeded.\n");
|
||||
} else {
|
||||
printf("No supported authentication methods found!\n");
|
||||
fprintf(stderr, "No supported authentication methods found!\n");
|
||||
goto shutdown;
|
||||
}
|
||||
|
||||
listensock = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP);
|
||||
#ifdef WIN32
|
||||
if (listensock == INVALID_SOCKET) {
|
||||
fprintf(stderr, "failed to open listen socket!\n");
|
||||
return -1;
|
||||
}
|
||||
#else
|
||||
if (listensock == -1) {
|
||||
perror("socket");
|
||||
return -1;
|
||||
}
|
||||
#endif
|
||||
|
||||
sin.sin_family = AF_INET;
|
||||
sin.sin_port = htons(local_listenport);
|
||||
if (INADDR_NONE == (sin.sin_addr.s_addr = inet_addr(local_listenip))) {
|
||||
@@ -185,20 +217,27 @@ int main(int argc, char *argv[])
|
||||
goto shutdown;
|
||||
}
|
||||
|
||||
printf("Waiting for TCP connection on %s:%d...\n",
|
||||
fprintf(stderr, "Waiting for TCP connection on %s:%d...\n",
|
||||
inet_ntoa(sin.sin_addr), ntohs(sin.sin_port));
|
||||
|
||||
forwardsock = accept(listensock, (struct sockaddr *)&sin, &sinlen);
|
||||
if (-1 == forwardsock) {
|
||||
#ifdef WIN32
|
||||
if (forwardsock == INVALID_SOCKET) {
|
||||
fprintf(stderr, "failed to accept forward socket!\n");
|
||||
goto shutdown;
|
||||
}
|
||||
#else
|
||||
if (forwardsock == -1) {
|
||||
perror("accept");
|
||||
goto shutdown;
|
||||
}
|
||||
#endif
|
||||
|
||||
shost = inet_ntoa(sin.sin_addr);
|
||||
sport = ntohs(sin.sin_port);
|
||||
|
||||
printf("Forwarding connection from %s:%d here to remote %s:%d\n", shost,
|
||||
sport, remote_desthost, remote_destport);
|
||||
fprintf(stderr, "Forwarding connection from %s:%d here to remote %s:%d\n",
|
||||
shost, sport, remote_desthost, remote_destport);
|
||||
|
||||
channel = libssh2_channel_direct_tcpip_ex(session, remote_desthost,
|
||||
remote_destport, shost, sport);
|
||||
@@ -228,7 +267,8 @@ int main(int argc, char *argv[])
|
||||
perror("read");
|
||||
goto shutdown;
|
||||
} else if (0 == len) {
|
||||
printf("The client at %s:%d disconnected!\n", shost, sport);
|
||||
fprintf(stderr, "The client at %s:%d disconnected!\n", shost,
|
||||
sport);
|
||||
goto shutdown;
|
||||
}
|
||||
wr = 0;
|
||||
@@ -259,7 +299,7 @@ int main(int argc, char *argv[])
|
||||
wr += i;
|
||||
}
|
||||
if (libssh2_channel_eof(channel)) {
|
||||
printf("The server at %s:%d disconnected!\n",
|
||||
fprintf(stderr, "The server at %s:%d disconnected!\n",
|
||||
remote_desthost, remote_destport);
|
||||
goto shutdown;
|
||||
}
|
||||
|
@@ -47,8 +47,13 @@ int main(int argc, char *argv[])
|
||||
|
||||
#ifdef WIN32
|
||||
WSADATA wsadata;
|
||||
int err;
|
||||
|
||||
WSAStartup(MAKEWORD(2,0), &wsadata);
|
||||
err = WSAStartup(MAKEWORD(2,0), &wsadata);
|
||||
if (err != 0) {
|
||||
fprintf(stderr, "WSAStartup failed with error: %d\n", err);
|
||||
return 1;
|
||||
}
|
||||
#endif
|
||||
|
||||
if (argc > 1) {
|
||||
|
@@ -97,8 +97,13 @@ int main(int argc, char *argv[])
|
||||
|
||||
#ifdef WIN32
|
||||
WSADATA wsadata;
|
||||
int err;
|
||||
|
||||
WSAStartup(MAKEWORD(2,0), &wsadata);
|
||||
err = WSAStartup(MAKEWORD(2,0), &wsadata);
|
||||
if (err != 0) {
|
||||
fprintf(stderr, "WSAStartup failed with error: %d\n", err);
|
||||
return 1;
|
||||
}
|
||||
#endif
|
||||
|
||||
if (argc > 1) {
|
||||
@@ -250,7 +255,7 @@ int main(int argc, char *argv[])
|
||||
gettimeofday(&end, NULL);
|
||||
|
||||
time_ms = tvdiff(end, start);
|
||||
printf("Got %d bytes in %ld ms = %.1f bytes/sec spin: %d\n", total,
|
||||
fprintf(stderr, "Got %d bytes in %ld ms = %.1f bytes/sec spin: %d\n", total,
|
||||
time_ms, total/(time_ms/1000.0), spin );
|
||||
|
||||
libssh2_channel_free(channel);
|
||||
|
@@ -51,8 +51,13 @@ int main(int argc, char *argv[])
|
||||
|
||||
#ifdef WIN32
|
||||
WSADATA wsadata;
|
||||
int err;
|
||||
|
||||
WSAStartup(MAKEWORD(2,0), &wsadata);
|
||||
err = WSAStartup(MAKEWORD(2,0), &wsadata);
|
||||
if (err != 0) {
|
||||
fprintf(stderr, "WSAStartup failed with error: %d\n", err);
|
||||
return 1;
|
||||
}
|
||||
#endif
|
||||
|
||||
if (argc > 1) {
|
||||
|
@@ -90,8 +90,13 @@ int main(int argc, char *argv[])
|
||||
|
||||
#ifdef WIN32
|
||||
WSADATA wsadata;
|
||||
int err;
|
||||
|
||||
WSAStartup(MAKEWORD(2,0), &wsadata);
|
||||
err = WSAStartup(MAKEWORD(2,0), &wsadata);
|
||||
if (err != 0) {
|
||||
fprintf(stderr, "WSAStartup failed with error: %d\n", err);
|
||||
return 1;
|
||||
}
|
||||
#endif
|
||||
|
||||
if (argc > 1) {
|
||||
@@ -243,7 +248,7 @@ int main(int argc, char *argv[])
|
||||
|
||||
duration = (int)(time(NULL)-start);
|
||||
|
||||
printf("%ld bytes in %d seconds makes %.1f bytes/sec\n",
|
||||
fprintf(stderr, "%ld bytes in %d seconds makes %.1f bytes/sec\n",
|
||||
total, duration, total/(double)duration);
|
||||
|
||||
fprintf(stderr, "Sending EOF\n");
|
||||
|
@@ -55,24 +55,24 @@ static void kbd_callback(const char *name, int name_len,
|
||||
char buf[1024];
|
||||
(void)abstract;
|
||||
|
||||
printf("Performing keyboard-interactive authentication.\n");
|
||||
fprintf(stderr, "Performing keyboard-interactive authentication.\n");
|
||||
|
||||
printf("Authentication name: '");
|
||||
fwrite(name, 1, name_len, stdout);
|
||||
printf("'\n");
|
||||
fprintf(stderr, "Authentication name: '");
|
||||
fwrite(name, 1, name_len, stderr);
|
||||
fprintf(stderr, "'\n");
|
||||
|
||||
printf("Authentication instruction: '");
|
||||
fwrite(instruction, 1, instruction_len, stdout);
|
||||
printf("'\n");
|
||||
fprintf(stderr, "Authentication instruction: '");
|
||||
fwrite(instruction, 1, instruction_len, stderr);
|
||||
fprintf(stderr, "'\n");
|
||||
|
||||
printf("Number of prompts: %d\n\n", num_prompts);
|
||||
fprintf(stderr, "Number of prompts: %d\n\n", num_prompts);
|
||||
|
||||
for (i = 0; i < num_prompts; i++) {
|
||||
printf("Prompt %d from server: '", i);
|
||||
fwrite(prompts[i].text, 1, prompts[i].length, stdout);
|
||||
printf("'\n");
|
||||
fprintf(stderr, "Prompt %d from server: '", i);
|
||||
fwrite(prompts[i].text, 1, prompts[i].length, stderr);
|
||||
fprintf(stderr, "'\n");
|
||||
|
||||
printf("Please type response: ");
|
||||
fprintf(stderr, "Please type response: ");
|
||||
fgets(buf, sizeof(buf), stdin);
|
||||
n = strlen(buf);
|
||||
while (n > 0 && strchr("\r\n", buf[n - 1]))
|
||||
@@ -82,12 +82,13 @@ static void kbd_callback(const char *name, int name_len,
|
||||
responses[i].text = strdup(buf);
|
||||
responses[i].length = n;
|
||||
|
||||
printf("Response %d from user is '", i);
|
||||
fwrite(responses[i].text, 1, responses[i].length, stdout);
|
||||
printf("'\n\n");
|
||||
fprintf(stderr, "Response %d from user is '", i);
|
||||
fwrite(responses[i].text, 1, responses[i].length, stderr);
|
||||
fprintf(stderr, "'\n\n");
|
||||
}
|
||||
|
||||
printf("Done. Sending keyboard-interactive responses to server now.\n");
|
||||
fprintf(stderr,
|
||||
"Done. Sending keyboard-interactive responses to server now.\n");
|
||||
}
|
||||
|
||||
|
||||
@@ -105,8 +106,13 @@ int main(int argc, char *argv[])
|
||||
|
||||
#ifdef WIN32
|
||||
WSADATA wsadata;
|
||||
int err;
|
||||
|
||||
WSAStartup(MAKEWORD(2,0), &wsadata);
|
||||
err = WSAStartup(MAKEWORD(2,0), &wsadata);
|
||||
if (err != 0) {
|
||||
fprintf(stderr, "WSAStartup failed with error: %d\n", err);
|
||||
return 1;
|
||||
}
|
||||
#endif
|
||||
|
||||
if (argc > 1) {
|
||||
@@ -127,7 +133,7 @@ int main(int argc, char *argv[])
|
||||
|
||||
rc = libssh2_init (0);
|
||||
if (rc != 0) {
|
||||
fprintf (stderr, "libssh2 initialization failed (%d)\n", rc);
|
||||
fprintf(stderr, "libssh2 initialization failed (%d)\n", rc);
|
||||
return 1;
|
||||
}
|
||||
|
||||
@@ -178,7 +184,7 @@ int main(int argc, char *argv[])
|
||||
|
||||
/* check what authentication methods are available */
|
||||
userauthlist = libssh2_userauth_list(session, username, strlen(username));
|
||||
printf("Authentication methods: %s\n", userauthlist);
|
||||
fprintf(stderr, "Authentication methods: %s\n", userauthlist);
|
||||
if (strstr(userauthlist, "password") != NULL) {
|
||||
auth_pw |= 1;
|
||||
}
|
||||
@@ -211,21 +217,23 @@ int main(int argc, char *argv[])
|
||||
} else if (auth_pw & 2) {
|
||||
/* Or via keyboard-interactive */
|
||||
if (libssh2_userauth_keyboard_interactive(session, username, &kbd_callback) ) {
|
||||
printf("\tAuthentication by keyboard-interactive failed!\n");
|
||||
fprintf(stderr,
|
||||
"\tAuthentication by keyboard-interactive failed!\n");
|
||||
goto shutdown;
|
||||
} else {
|
||||
printf("\tAuthentication by keyboard-interactive succeeded.\n");
|
||||
fprintf(stderr,
|
||||
"\tAuthentication by keyboard-interactive succeeded.\n");
|
||||
}
|
||||
} else if (auth_pw & 4) {
|
||||
/* Or by public key */
|
||||
if (libssh2_userauth_publickey_fromfile(session, username, keyfile1, keyfile2, password)) {
|
||||
printf("\tAuthentication by public key failed!\n");
|
||||
fprintf(stderr, "\tAuthentication by public key failed!\n");
|
||||
goto shutdown;
|
||||
} else {
|
||||
printf("\tAuthentication by public key succeeded.\n");
|
||||
fprintf(stderr, "\tAuthentication by public key succeeded.\n");
|
||||
}
|
||||
} else {
|
||||
printf("No supported authentication methods found!\n");
|
||||
fprintf(stderr, "No supported authentication methods found!\n");
|
||||
goto shutdown;
|
||||
}
|
||||
|
||||
|
@@ -93,8 +93,13 @@ int main(int argc, char *argv[])
|
||||
|
||||
#ifdef WIN32
|
||||
WSADATA wsadata;
|
||||
int err;
|
||||
|
||||
WSAStartup(MAKEWORD(2,0), &wsadata);
|
||||
err = WSAStartup(MAKEWORD(2,0), &wsadata);
|
||||
if (err != 0) {
|
||||
fprintf(stderr, "WSAStartup failed with error: %d\n", err);
|
||||
return 1;
|
||||
}
|
||||
#endif
|
||||
|
||||
rc = libssh2_init (0);
|
||||
@@ -141,11 +146,11 @@ int main(int argc, char *argv[])
|
||||
* user, that's your call
|
||||
*/
|
||||
fingerprint = libssh2_hostkey_hash(session, LIBSSH2_HOSTKEY_HASH_SHA1);
|
||||
printf("Fingerprint: ");
|
||||
fprintf(stderr, "Fingerprint: ");
|
||||
for(i = 0; i < 20; i++) {
|
||||
printf("%02X ", (unsigned char)fingerprint[i]);
|
||||
fprintf(stderr, "%02X ", (unsigned char)fingerprint[i]);
|
||||
}
|
||||
printf("\n");
|
||||
fprintf(stderr, "\n");
|
||||
|
||||
if(argc > 1) {
|
||||
username = argv[1];
|
||||
@@ -162,7 +167,7 @@ int main(int argc, char *argv[])
|
||||
|
||||
tempstorage = fopen(STORAGE, "wb");
|
||||
if(!tempstorage) {
|
||||
printf("Can't open temp storage file %s\n", STORAGE);
|
||||
fprintf(stderr, "Can't open temp storage file %s\n", STORAGE);
|
||||
goto shutdown;
|
||||
}
|
||||
|
||||
@@ -171,7 +176,7 @@ int main(int argc, char *argv[])
|
||||
while ((rc = libssh2_userauth_password(session, username, password))
|
||||
== LIBSSH2_ERROR_EAGAIN);
|
||||
if (rc) {
|
||||
printf("Authentication by password failed.\n");
|
||||
fprintf(stderr, "Authentication by password failed.\n");
|
||||
goto shutdown;
|
||||
}
|
||||
} else {
|
||||
@@ -185,7 +190,7 @@ int main(int argc, char *argv[])
|
||||
password)) ==
|
||||
LIBSSH2_ERROR_EAGAIN);
|
||||
if (rc) {
|
||||
printf("\tAuthentication by public key failed\n");
|
||||
fprintf(stderr, "\tAuthentication by public key failed\n");
|
||||
goto shutdown;
|
||||
}
|
||||
}
|
||||
@@ -341,7 +346,7 @@ int main(int argc, char *argv[])
|
||||
#endif
|
||||
if (tempstorage)
|
||||
fclose(tempstorage);
|
||||
printf("all done\n");
|
||||
fprintf(stderr, "all done\n");
|
||||
|
||||
libssh2_exit();
|
||||
|
||||
|
@@ -55,8 +55,13 @@ int main(int argc, char *argv[])
|
||||
|
||||
#ifdef WIN32
|
||||
WSADATA wsadata;
|
||||
int err;
|
||||
|
||||
WSAStartup(MAKEWORD(2,0), &wsadata);
|
||||
err = WSAStartup(MAKEWORD(2,0), &wsadata);
|
||||
if (err != 0) {
|
||||
fprintf(stderr, "WSAStartup failed with error: %d\n", err);
|
||||
return 1;
|
||||
}
|
||||
#endif
|
||||
|
||||
if (argc > 1) {
|
||||
@@ -86,7 +91,7 @@ int main(int argc, char *argv[])
|
||||
|
||||
local = fopen(loclfile, "rb");
|
||||
if (!local) {
|
||||
printf("Can't local file %s\n", loclfile);
|
||||
fprintf(stderr, "Can't open local file %s\n", loclfile);
|
||||
return -1;
|
||||
}
|
||||
|
||||
@@ -129,16 +134,16 @@ int main(int argc, char *argv[])
|
||||
* user, that's your call
|
||||
*/
|
||||
fingerprint = libssh2_hostkey_hash(session, LIBSSH2_HOSTKEY_HASH_SHA1);
|
||||
printf("Fingerprint: ");
|
||||
fprintf(stderr, "Fingerprint: ");
|
||||
for(i = 0; i < 20; i++) {
|
||||
printf("%02X ", (unsigned char)fingerprint[i]);
|
||||
fprintf(stderr, "%02X ", (unsigned char)fingerprint[i]);
|
||||
}
|
||||
printf("\n");
|
||||
fprintf(stderr, "\n");
|
||||
|
||||
if (auth_pw) {
|
||||
/* We could authenticate via password */
|
||||
if (libssh2_userauth_password(session, username, password)) {
|
||||
printf("Authentication by password failed.\n");
|
||||
fprintf(stderr, "Authentication by password failed.\n");
|
||||
goto shutdown;
|
||||
}
|
||||
} else {
|
||||
@@ -147,7 +152,7 @@ int main(int argc, char *argv[])
|
||||
"/home/username/.ssh/id_rsa.pub",
|
||||
"/home/username/.ssh/id_rsa",
|
||||
password)) {
|
||||
printf("\tAuthentication by public key failed\n");
|
||||
fprintf(stderr, "\tAuthentication by public key failed\n");
|
||||
goto shutdown;
|
||||
}
|
||||
}
|
||||
@@ -174,12 +179,12 @@ int main(int argc, char *argv[])
|
||||
}
|
||||
|
||||
if(libssh2_sftp_fstat_ex(sftp_handle, &attrs, 0) < 0) {
|
||||
printf("libssh2_sftp_fstat_ex failed\n");
|
||||
fprintf(stderr, "libssh2_sftp_fstat_ex failed\n");
|
||||
goto shutdown;
|
||||
}
|
||||
else
|
||||
libssh2_sftp_seek64(sftp_handle, attrs.filesize);
|
||||
printf("Did a seek to position %ld\n", (long) attrs.filesize);
|
||||
fprintf(stderr, "Did a seek to position %ld\n", (long) attrs.filesize);
|
||||
|
||||
fprintf(stderr, "libssh2_sftp_open() a handle for APPEND\n");
|
||||
|
||||
@@ -222,7 +227,7 @@ shutdown:
|
||||
#endif
|
||||
if (local)
|
||||
fclose(local);
|
||||
printf("all done\n");
|
||||
fprintf(stderr, "all done\n");
|
||||
|
||||
libssh2_exit();
|
||||
|
||||
|
@@ -48,8 +48,13 @@ int main(int argc, char *argv[])
|
||||
|
||||
#ifdef WIN32
|
||||
WSADATA wsadata;
|
||||
int err;
|
||||
|
||||
WSAStartup(MAKEWORD(2,0), &wsadata);
|
||||
err = WSAStartup(MAKEWORD(2,0), &wsadata);
|
||||
if (err != 0) {
|
||||
fprintf(stderr, "WSAStartup failed with error: %d\n", err);
|
||||
return 1;
|
||||
}
|
||||
#endif
|
||||
|
||||
if (argc > 1) {
|
||||
@@ -110,16 +115,16 @@ int main(int argc, char *argv[])
|
||||
* user, that's your call
|
||||
*/
|
||||
fingerprint = libssh2_hostkey_hash(session, LIBSSH2_HOSTKEY_HASH_SHA1);
|
||||
printf("Fingerprint: ");
|
||||
fprintf(stderr, "Fingerprint: ");
|
||||
for(i = 0; i < 20; i++) {
|
||||
printf("%02X ", (unsigned char)fingerprint[i]);
|
||||
fprintf(stderr, "%02X ", (unsigned char)fingerprint[i]);
|
||||
}
|
||||
printf("\n");
|
||||
fprintf(stderr, "\n");
|
||||
|
||||
if (auth_pw) {
|
||||
/* We could authenticate via password */
|
||||
if (libssh2_userauth_password(session, username, password)) {
|
||||
printf("Authentication by password failed.\n");
|
||||
fprintf(stderr, "Authentication by password failed.\n");
|
||||
goto shutdown;
|
||||
}
|
||||
} else {
|
||||
@@ -128,7 +133,7 @@ int main(int argc, char *argv[])
|
||||
"/home/username/.ssh/id_rsa.pub",
|
||||
"/home/username/.ssh/id_rsa",
|
||||
password)) {
|
||||
printf("\tAuthentication by public key failed\n");
|
||||
fprintf(stderr, "\tAuthentication by public key failed\n");
|
||||
goto shutdown;
|
||||
}
|
||||
}
|
||||
@@ -164,7 +169,7 @@ int main(int argc, char *argv[])
|
||||
#else
|
||||
close(sock);
|
||||
#endif
|
||||
printf("all done\n");
|
||||
fprintf(stderr, "all done\n");
|
||||
|
||||
libssh2_exit();
|
||||
|
||||
|
@@ -48,8 +48,13 @@ int main(int argc, char *argv[])
|
||||
|
||||
#ifdef WIN32
|
||||
WSADATA wsadata;
|
||||
int err;
|
||||
|
||||
WSAStartup(MAKEWORD(2,0), &wsadata);
|
||||
err = WSAStartup(MAKEWORD(2,0), &wsadata);
|
||||
if (err != 0) {
|
||||
fprintf(stderr, "WSAStartup failed with error: %d\n", err);
|
||||
return 1;
|
||||
}
|
||||
#endif
|
||||
|
||||
if (argc > 1) {
|
||||
@@ -110,16 +115,16 @@ int main(int argc, char *argv[])
|
||||
* user, that's your call
|
||||
*/
|
||||
fingerprint = libssh2_hostkey_hash(session, LIBSSH2_HOSTKEY_HASH_SHA1);
|
||||
printf("Fingerprint: ");
|
||||
fprintf(stderr, "Fingerprint: ");
|
||||
for(i = 0; i < 20; i++) {
|
||||
printf("%02X ", (unsigned char)fingerprint[i]);
|
||||
fprintf(stderr, "%02X ", (unsigned char)fingerprint[i]);
|
||||
}
|
||||
printf("\n");
|
||||
fprintf(stderr, "\n");
|
||||
|
||||
if (auth_pw) {
|
||||
/* We could authenticate via password */
|
||||
if (libssh2_userauth_password(session, username, password)) {
|
||||
printf("Authentication by password failed.\n");
|
||||
fprintf(stderr, "Authentication by password failed.\n");
|
||||
goto shutdown;
|
||||
}
|
||||
} else {
|
||||
@@ -128,7 +133,7 @@ int main(int argc, char *argv[])
|
||||
"/home/username/.ssh/id_rsa.pub",
|
||||
"/home/username/.ssh/id_rsa",
|
||||
password)) {
|
||||
printf("\tAuthentication by public key failed\n");
|
||||
fprintf(stderr, "\tAuthentication by public key failed\n");
|
||||
goto shutdown;
|
||||
}
|
||||
}
|
||||
@@ -164,7 +169,7 @@ int main(int argc, char *argv[])
|
||||
#else
|
||||
close(sock);
|
||||
#endif
|
||||
printf("all done\n");
|
||||
fprintf(stderr, "all done\n");
|
||||
|
||||
libssh2_exit();
|
||||
|
||||
|
@@ -97,8 +97,13 @@ int main(int argc, char *argv[])
|
||||
|
||||
#ifdef WIN32
|
||||
WSADATA wsadata;
|
||||
int err;
|
||||
|
||||
WSAStartup(MAKEWORD(2,0), &wsadata);
|
||||
err = WSAStartup(MAKEWORD(2,0), &wsadata);
|
||||
if (err != 0) {
|
||||
fprintf(stderr, "WSAStartup failed with error: %d\n", err);
|
||||
return 1;
|
||||
}
|
||||
#endif
|
||||
|
||||
if (argc > 1) {
|
||||
@@ -251,7 +256,7 @@ int main(int argc, char *argv[])
|
||||
|
||||
gettimeofday(&end, NULL);
|
||||
time_ms = tvdiff(end, start);
|
||||
printf("Got %d bytes in %ld ms = %.1f bytes/sec spin: %d\n", total,
|
||||
fprintf(stderr, "Got %d bytes in %ld ms = %.1f bytes/sec spin: %d\n", total,
|
||||
time_ms, total/(time_ms/1000.0), spin );
|
||||
|
||||
libssh2_sftp_close(sftp_handle);
|
||||
@@ -259,7 +264,7 @@ int main(int argc, char *argv[])
|
||||
|
||||
shutdown:
|
||||
|
||||
printf("libssh2_session_disconnect\n");
|
||||
fprintf(stderr, "libssh2_session_disconnect\n");
|
||||
while (libssh2_session_disconnect(session,
|
||||
"Normal Shutdown, Thank you") ==
|
||||
LIBSSH2_ERROR_EAGAIN);
|
||||
|
@@ -54,8 +54,13 @@ int main(int argc, char *argv[])
|
||||
|
||||
#ifdef WIN32
|
||||
WSADATA wsadata;
|
||||
int err;
|
||||
|
||||
WSAStartup(MAKEWORD(2,0), &wsadata);
|
||||
err = WSAStartup(MAKEWORD(2,0), &wsadata);
|
||||
if (err != 0) {
|
||||
fprintf(stderr, "WSAStartup failed with error: %d\n", err);
|
||||
return 1;
|
||||
}
|
||||
#endif
|
||||
|
||||
if (argc > 1) {
|
||||
@@ -85,7 +90,7 @@ int main(int argc, char *argv[])
|
||||
|
||||
local = fopen(loclfile, "rb");
|
||||
if (!local) {
|
||||
printf("Can't local file %s\n", loclfile);
|
||||
fprintf(stderr, "Can't open local file %s\n", loclfile);
|
||||
return -1;
|
||||
}
|
||||
|
||||
@@ -128,16 +133,16 @@ int main(int argc, char *argv[])
|
||||
* user, that's your call
|
||||
*/
|
||||
fingerprint = libssh2_hostkey_hash(session, LIBSSH2_HOSTKEY_HASH_SHA1);
|
||||
printf("Fingerprint: ");
|
||||
fprintf(stderr, "Fingerprint: ");
|
||||
for(i = 0; i < 20; i++) {
|
||||
printf("%02X ", (unsigned char)fingerprint[i]);
|
||||
fprintf(stderr, "%02X ", (unsigned char)fingerprint[i]);
|
||||
}
|
||||
printf("\n");
|
||||
fprintf(stderr, "\n");
|
||||
|
||||
if (auth_pw) {
|
||||
/* We could authenticate via password */
|
||||
if (libssh2_userauth_password(session, username, password)) {
|
||||
printf("Authentication by password failed.\n");
|
||||
fprintf(stderr, "Authentication by password failed.\n");
|
||||
goto shutdown;
|
||||
}
|
||||
} else {
|
||||
@@ -146,7 +151,7 @@ int main(int argc, char *argv[])
|
||||
"/home/username/.ssh/id_rsa.pub",
|
||||
"/home/username/.ssh/id_rsa",
|
||||
password)) {
|
||||
printf("\tAuthentication by public key failed\n");
|
||||
fprintf(stderr, "\tAuthentication by public key failed\n");
|
||||
goto shutdown;
|
||||
}
|
||||
}
|
||||
@@ -206,7 +211,7 @@ shutdown:
|
||||
#endif
|
||||
if (local)
|
||||
fclose(local);
|
||||
printf("all done\n");
|
||||
fprintf(stderr, "all done\n");
|
||||
|
||||
libssh2_exit();
|
||||
|
||||
|
@@ -94,8 +94,13 @@ int main(int argc, char *argv[])
|
||||
|
||||
#ifdef WIN32
|
||||
WSADATA wsadata;
|
||||
int err;
|
||||
|
||||
WSAStartup(MAKEWORD(2,0), &wsadata);
|
||||
err = WSAStartup(MAKEWORD(2,0), &wsadata);
|
||||
if (err != 0) {
|
||||
fprintf(stderr, "WSAStartup failed with error: %d\n", err);
|
||||
return 1;
|
||||
}
|
||||
#endif
|
||||
|
||||
if (argc > 1) {
|
||||
@@ -125,7 +130,7 @@ int main(int argc, char *argv[])
|
||||
|
||||
local = fopen(loclfile, "rb");
|
||||
if (!local) {
|
||||
printf("Can't local file %s\n", loclfile);
|
||||
fprintf(stderr, "Can't open local file %s\n", loclfile);
|
||||
return -1;
|
||||
}
|
||||
|
||||
@@ -169,18 +174,18 @@ int main(int argc, char *argv[])
|
||||
* that's your call
|
||||
*/
|
||||
fingerprint = libssh2_hostkey_hash(session, LIBSSH2_HOSTKEY_HASH_SHA1);
|
||||
printf("Fingerprint: ");
|
||||
fprintf(stderr, "Fingerprint: ");
|
||||
for(i = 0; i < 20; i++) {
|
||||
printf("%02X ", (unsigned char)fingerprint[i]);
|
||||
fprintf(stderr, "%02X ", (unsigned char)fingerprint[i]);
|
||||
}
|
||||
printf("\n");
|
||||
fprintf(stderr, "\n");
|
||||
|
||||
if (auth_pw) {
|
||||
/* We could authenticate via password */
|
||||
while ((rc = libssh2_userauth_password(session, username, password)) ==
|
||||
LIBSSH2_ERROR_EAGAIN);
|
||||
if (rc) {
|
||||
printf("Authentication by password failed.\n");
|
||||
fprintf(stderr, "Authentication by password failed.\n");
|
||||
goto shutdown;
|
||||
}
|
||||
} else {
|
||||
@@ -191,7 +196,7 @@ int main(int argc, char *argv[])
|
||||
password)) ==
|
||||
LIBSSH2_ERROR_EAGAIN);
|
||||
if (rc) {
|
||||
printf("\tAuthentication by public key failed\n");
|
||||
fprintf(stderr, "\tAuthentication by public key failed\n");
|
||||
goto shutdown;
|
||||
}
|
||||
}
|
||||
@@ -253,7 +258,7 @@ int main(int argc, char *argv[])
|
||||
|
||||
duration = (int)(time(NULL)-start);
|
||||
|
||||
printf("%ld bytes in %d seconds makes %.1f bytes/sec\n",
|
||||
fprintf(stderr, "%ld bytes in %d seconds makes %.1f bytes/sec\n",
|
||||
total, duration, total/(double)duration);
|
||||
|
||||
|
||||
@@ -272,7 +277,7 @@ shutdown:
|
||||
#else
|
||||
close(sock);
|
||||
#endif
|
||||
printf("all done\n");
|
||||
fprintf(stderr, "all done\n");
|
||||
|
||||
libssh2_exit();
|
||||
|
||||
|
@@ -94,8 +94,13 @@ int main(int argc, char *argv[])
|
||||
|
||||
#ifdef WIN32
|
||||
WSADATA wsadata;
|
||||
int err;
|
||||
|
||||
WSAStartup(MAKEWORD(2,0), &wsadata);
|
||||
err = WSAStartup(MAKEWORD(2,0), &wsadata);
|
||||
if (err != 0) {
|
||||
fprintf(stderr, "WSAStartup failed with error: %d\n", err);
|
||||
return 1;
|
||||
}
|
||||
#endif
|
||||
|
||||
if (argc > 1) {
|
||||
@@ -125,7 +130,7 @@ int main(int argc, char *argv[])
|
||||
|
||||
local = fopen(loclfile, "rb");
|
||||
if (!local) {
|
||||
printf("Can't local file %s\n", loclfile);
|
||||
fprintf(stderr, "Can't open local file %s\n", loclfile);
|
||||
return -1;
|
||||
}
|
||||
|
||||
@@ -169,18 +174,18 @@ int main(int argc, char *argv[])
|
||||
* that's your call
|
||||
*/
|
||||
fingerprint = libssh2_hostkey_hash(session, LIBSSH2_HOSTKEY_HASH_SHA1);
|
||||
printf("Fingerprint: ");
|
||||
fprintf(stderr, "Fingerprint: ");
|
||||
for(i = 0; i < 20; i++) {
|
||||
printf("%02X ", (unsigned char)fingerprint[i]);
|
||||
fprintf(stderr, "%02X ", (unsigned char)fingerprint[i]);
|
||||
}
|
||||
printf("\n");
|
||||
fprintf(stderr, "\n");
|
||||
|
||||
if (auth_pw) {
|
||||
/* We could authenticate via password */
|
||||
while ((rc = libssh2_userauth_password(session, username, password)) ==
|
||||
LIBSSH2_ERROR_EAGAIN);
|
||||
if (rc) {
|
||||
printf("Authentication by password failed.\n");
|
||||
fprintf(stderr, "Authentication by password failed.\n");
|
||||
goto shutdown;
|
||||
}
|
||||
} else {
|
||||
@@ -191,7 +196,7 @@ int main(int argc, char *argv[])
|
||||
password)) ==
|
||||
LIBSSH2_ERROR_EAGAIN);
|
||||
if (rc) {
|
||||
printf("\tAuthentication by public key failed\n");
|
||||
fprintf(stderr, "\tAuthentication by public key failed\n");
|
||||
goto shutdown;
|
||||
}
|
||||
}
|
||||
@@ -262,7 +267,7 @@ int main(int argc, char *argv[])
|
||||
|
||||
duration = (int)(time(NULL)-start);
|
||||
|
||||
printf("%ld bytes in %d seconds makes %.1f bytes/sec\n",
|
||||
fprintf(stderr, "%ld bytes in %d seconds makes %.1f bytes/sec\n",
|
||||
total, duration, total/(double)duration);
|
||||
|
||||
|
||||
@@ -281,7 +286,7 @@ shutdown:
|
||||
#else
|
||||
close(sock);
|
||||
#endif
|
||||
printf("all done\n");
|
||||
fprintf(stderr, "all done\n");
|
||||
|
||||
libssh2_exit();
|
||||
|
||||
|
@@ -52,24 +52,51 @@
|
||||
#define PRIu64 __PRI64_PREFIX "u"
|
||||
#endif /* PRIu64 */
|
||||
|
||||
const char *keyfile1="~/.ssh/id_rsa.pub";
|
||||
const char *keyfile2="~/.ssh/id_rsa";
|
||||
const char *username="username";
|
||||
const char *password="password";
|
||||
|
||||
static void kbd_callback(const char *name, int name_len,
|
||||
const char *instruction, int instruction_len,
|
||||
int num_prompts,
|
||||
const LIBSSH2_USERAUTH_KBDINT_PROMPT *prompts,
|
||||
LIBSSH2_USERAUTH_KBDINT_RESPONSE *responses,
|
||||
void **abstract)
|
||||
{
|
||||
(void)name;
|
||||
(void)name_len;
|
||||
(void)instruction;
|
||||
(void)instruction_len;
|
||||
if (num_prompts == 1) {
|
||||
responses[0].text = strdup(password);
|
||||
responses[0].length = strlen(password);
|
||||
}
|
||||
(void)prompts;
|
||||
(void)abstract;
|
||||
} /* kbd_callback */
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
unsigned long hostaddr;
|
||||
int sock, i, auth_pw = 1;
|
||||
int rc, sock, i, auth_pw = 0;
|
||||
struct sockaddr_in sin;
|
||||
const char *fingerprint;
|
||||
char *userauthlist;
|
||||
LIBSSH2_SESSION *session;
|
||||
const char *username="username";
|
||||
const char *password="password";
|
||||
const char *sftppath="/tmp/secretdir";
|
||||
int rc;
|
||||
LIBSSH2_SFTP *sftp_session;
|
||||
LIBSSH2_SFTP_HANDLE *sftp_handle;
|
||||
|
||||
#ifdef WIN32
|
||||
WSADATA wsadata;
|
||||
int err;
|
||||
|
||||
WSAStartup(MAKEWORD(2,0), &wsadata);
|
||||
err = WSAStartup(MAKEWORD(2,0), &wsadata);
|
||||
if (err != 0) {
|
||||
fprintf(stderr, "WSAStartup failed with error: %d\n", err);
|
||||
return 1;
|
||||
}
|
||||
#endif
|
||||
|
||||
if (argc > 1) {
|
||||
@@ -130,27 +157,69 @@ int main(int argc, char *argv[])
|
||||
* user, that's your call
|
||||
*/
|
||||
fingerprint = libssh2_hostkey_hash(session, LIBSSH2_HOSTKEY_HASH_SHA1);
|
||||
printf("Fingerprint: ");
|
||||
fprintf(stderr, "Fingerprint: ");
|
||||
for(i = 0; i < 20; i++) {
|
||||
printf("%02X ", (unsigned char)fingerprint[i]);
|
||||
fprintf(stderr, "%02X ", (unsigned char)fingerprint[i]);
|
||||
}
|
||||
printf("\n");
|
||||
fprintf(stderr, "\n");
|
||||
|
||||
if (auth_pw) {
|
||||
/* check what authentication methods are available */
|
||||
userauthlist = libssh2_userauth_list(session, username, strlen(username));
|
||||
fprintf(stderr, "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 we got an 5. argument we set this option if supported */
|
||||
if(argc > 5) {
|
||||
if ((auth_pw & 1) && !strcasecmp(argv[5], "-p")) {
|
||||
auth_pw = 1;
|
||||
}
|
||||
if ((auth_pw & 2) && !strcasecmp(argv[5], "-i")) {
|
||||
auth_pw = 2;
|
||||
}
|
||||
if ((auth_pw & 4) && !strcasecmp(argv[5], "-k")) {
|
||||
auth_pw = 4;
|
||||
}
|
||||
}
|
||||
|
||||
if (auth_pw & 1) {
|
||||
/* We could authenticate via password */
|
||||
if (libssh2_userauth_password(session, username, password)) {
|
||||
printf("Authentication by password failed.\n");
|
||||
fprintf(stderr, "\tAuthentication by password failed!\n");
|
||||
goto shutdown;
|
||||
} else {
|
||||
fprintf(stderr, "\tAuthentication by password succeeded.\n");
|
||||
}
|
||||
} else if (auth_pw & 2) {
|
||||
/* Or via keyboard-interactive */
|
||||
if (libssh2_userauth_keyboard_interactive(session, username,
|
||||
&kbd_callback) ) {
|
||||
fprintf(stderr,
|
||||
"\tAuthentication by keyboard-interactive failed!\n");
|
||||
goto shutdown;
|
||||
} else {
|
||||
fprintf(stderr,
|
||||
"\tAuthentication by keyboard-interactive succeeded.\n");
|
||||
}
|
||||
} else if (auth_pw & 4) {
|
||||
/* Or by public key */
|
||||
if (libssh2_userauth_publickey_fromfile(session, username, keyfile1,
|
||||
keyfile2, password)) {
|
||||
fprintf(stderr, "\tAuthentication by public key failed!\n");
|
||||
goto shutdown;
|
||||
} else {
|
||||
fprintf(stderr, "\tAuthentication by public key succeeded.\n");
|
||||
}
|
||||
} else {
|
||||
/* Or by public key */
|
||||
if (libssh2_userauth_publickey_fromfile(session, username,
|
||||
"/home/username/.ssh/id_rsa.pub",
|
||||
"/home/username/.ssh/id_rsa",
|
||||
password)) {
|
||||
printf("\tAuthentication by public key failed\n");
|
||||
goto shutdown;
|
||||
}
|
||||
fprintf(stderr, "No supported authentication methods found!\n");
|
||||
goto shutdown;
|
||||
}
|
||||
|
||||
fprintf(stderr, "libssh2_sftp_init()!\n");
|
||||
@@ -229,7 +298,7 @@ int main(int argc, char *argv[])
|
||||
#else
|
||||
close(sock);
|
||||
#endif
|
||||
printf("all done\n");
|
||||
fprintf(stderr, "all done\n");
|
||||
|
||||
libssh2_exit();
|
||||
|
||||
|
@@ -68,8 +68,13 @@ int main(int argc, char *argv[])
|
||||
|
||||
#ifdef WIN32
|
||||
WSADATA wsadata;
|
||||
int err;
|
||||
|
||||
WSAStartup(MAKEWORD(2,0), &wsadata);
|
||||
err = WSAStartup(MAKEWORD(2,0), &wsadata);
|
||||
if (err != 0) {
|
||||
fprintf(stderr, "WSAStartup failed with error: %d\n", err);
|
||||
return 1;
|
||||
}
|
||||
#endif
|
||||
|
||||
if (argc > 1) {
|
||||
@@ -134,11 +139,11 @@ int main(int argc, char *argv[])
|
||||
* user, that's your call
|
||||
*/
|
||||
fingerprint = libssh2_hostkey_hash(session, LIBSSH2_HOSTKEY_HASH_SHA1);
|
||||
printf("Fingerprint: ");
|
||||
fprintf(stderr, "Fingerprint: ");
|
||||
for(i = 0; i < 20; i++) {
|
||||
printf("%02X ", (unsigned char)fingerprint[i]);
|
||||
fprintf(stderr, "%02X ", (unsigned char)fingerprint[i]);
|
||||
}
|
||||
printf("\n");
|
||||
fprintf(stderr, "\n");
|
||||
|
||||
if (auth_pw) {
|
||||
/* We could authenticate via password */
|
||||
@@ -239,7 +244,7 @@ int main(int argc, char *argv[])
|
||||
#else
|
||||
close(sock);
|
||||
#endif
|
||||
printf("all done\n");
|
||||
fprintf(stderr, "all done\n");
|
||||
|
||||
libssh2_exit();
|
||||
|
||||
|
@@ -72,10 +72,16 @@ int main(int argc, char *argv[])
|
||||
char *userauthlist;
|
||||
LIBSSH2_SESSION *session;
|
||||
LIBSSH2_CHANNEL *channel;
|
||||
|
||||
#ifdef WIN32
|
||||
WSADATA wsadata;
|
||||
int err;
|
||||
|
||||
WSAStartup(MAKEWORD(2,0), &wsadata);
|
||||
err = WSAStartup(MAKEWORD(2,0), &wsadata);
|
||||
if (err != 0) {
|
||||
fprintf(stderr, "WSAStartup failed with error: %d\n", err);
|
||||
return 1;
|
||||
}
|
||||
#endif
|
||||
|
||||
if (argc > 1) {
|
||||
@@ -126,15 +132,15 @@ int main(int argc, char *argv[])
|
||||
* call
|
||||
*/
|
||||
fingerprint = libssh2_hostkey_hash(session, LIBSSH2_HOSTKEY_HASH_SHA1);
|
||||
printf("Fingerprint: ");
|
||||
fprintf(stderr, "Fingerprint: ");
|
||||
for(i = 0; i < 20; i++) {
|
||||
printf("%02X ", (unsigned char)fingerprint[i]);
|
||||
fprintf(stderr, "%02X ", (unsigned char)fingerprint[i]);
|
||||
}
|
||||
printf("\n");
|
||||
fprintf(stderr, "\n");
|
||||
|
||||
/* check what authentication methods are available */
|
||||
userauthlist = libssh2_userauth_list(session, username, strlen(username));
|
||||
printf("Authentication methods: %s\n", userauthlist);
|
||||
fprintf(stderr, "Authentication methods: %s\n", userauthlist);
|
||||
if (strstr(userauthlist, "password") != NULL) {
|
||||
auth_pw |= 1;
|
||||
}
|
||||
@@ -161,31 +167,33 @@ int main(int argc, char *argv[])
|
||||
if (auth_pw & 1) {
|
||||
/* We could authenticate via password */
|
||||
if (libssh2_userauth_password(session, username, password)) {
|
||||
printf("\tAuthentication by password failed!\n");
|
||||
fprintf(stderr, "\tAuthentication by password failed!\n");
|
||||
goto shutdown;
|
||||
} else {
|
||||
printf("\tAuthentication by password succeeded.\n");
|
||||
fprintf(stderr, "\tAuthentication by password succeeded.\n");
|
||||
}
|
||||
} else if (auth_pw & 2) {
|
||||
/* Or via keyboard-interactive */
|
||||
if (libssh2_userauth_keyboard_interactive(session, username,
|
||||
&kbd_callback) ) {
|
||||
printf("\tAuthentication by keyboard-interactive failed!\n");
|
||||
fprintf(stderr,
|
||||
"\tAuthentication by keyboard-interactive failed!\n");
|
||||
goto shutdown;
|
||||
} else {
|
||||
printf("\tAuthentication by keyboard-interactive succeeded.\n");
|
||||
fprintf(stderr,
|
||||
"\tAuthentication by keyboard-interactive succeeded.\n");
|
||||
}
|
||||
} else if (auth_pw & 4) {
|
||||
/* Or by public key */
|
||||
if (libssh2_userauth_publickey_fromfile(session, username, keyfile1,
|
||||
keyfile2, password)) {
|
||||
printf("\tAuthentication by public key failed!\n");
|
||||
fprintf(stderr, "\tAuthentication by public key failed!\n");
|
||||
goto shutdown;
|
||||
} else {
|
||||
printf("\tAuthentication by public key succeeded.\n");
|
||||
fprintf(stderr, "\tAuthentication by public key succeeded.\n");
|
||||
}
|
||||
} else {
|
||||
printf("No supported authentication methods found!\n");
|
||||
fprintf(stderr, "No supported authentication methods found!\n");
|
||||
goto shutdown;
|
||||
}
|
||||
|
||||
@@ -250,7 +258,7 @@ int main(int argc, char *argv[])
|
||||
#else
|
||||
close(sock);
|
||||
#endif
|
||||
printf("all done!\n");
|
||||
fprintf(stderr, "all done!\n");
|
||||
|
||||
libssh2_exit();
|
||||
|
||||
|
@@ -49,10 +49,16 @@ int main(int argc, char *argv[])
|
||||
LIBSSH2_CHANNEL *channel;
|
||||
LIBSSH2_AGENT *agent = NULL;
|
||||
struct libssh2_agent_publickey *identity, *prev_identity = NULL;
|
||||
|
||||
#ifdef WIN32
|
||||
WSADATA wsadata;
|
||||
int err;
|
||||
|
||||
WSAStartup(MAKEWORD(2,0), &wsadata);
|
||||
err = WSAStartup(MAKEWORD(2,0), &wsadata);
|
||||
if (err != 0) {
|
||||
fprintf(stderr, "WSAStartup failed with error: %d\n", err);
|
||||
return 1;
|
||||
}
|
||||
#endif
|
||||
|
||||
if (argc > 1) {
|
||||
@@ -105,15 +111,15 @@ int main(int argc, char *argv[])
|
||||
* call
|
||||
*/
|
||||
fingerprint = libssh2_hostkey_hash(session, LIBSSH2_HOSTKEY_HASH_SHA1);
|
||||
printf("Fingerprint: ");
|
||||
fprintf(stderr, "Fingerprint: ");
|
||||
for(i = 0; i < 20; i++) {
|
||||
printf("%02X ", (unsigned char)fingerprint[i]);
|
||||
fprintf(stderr, "%02X ", (unsigned char)fingerprint[i]);
|
||||
}
|
||||
printf("\n");
|
||||
fprintf(stderr, "\n");
|
||||
|
||||
/* check what authentication methods are available */
|
||||
userauthlist = libssh2_userauth_list(session, username, strlen(username));
|
||||
printf("Authentication methods: %s\n", userauthlist);
|
||||
fprintf(stderr, "Authentication methods: %s\n", userauthlist);
|
||||
if (strstr(userauthlist, "publickey") == NULL) {
|
||||
fprintf(stderr, "\"publickey\" authentication is not supported\n");
|
||||
goto shutdown;
|
||||
@@ -147,11 +153,11 @@ int main(int argc, char *argv[])
|
||||
goto shutdown;
|
||||
}
|
||||
if (libssh2_agent_userauth(agent, username, identity)) {
|
||||
printf("\tAuthentication with username %s and "
|
||||
fprintf(stderr, "\tAuthentication with username %s and "
|
||||
"public key %s failed!\n",
|
||||
username, identity->comment);
|
||||
} else {
|
||||
printf("\tAuthentication with username %s and "
|
||||
fprintf(stderr, "\tAuthentication with username %s and "
|
||||
"public key %s succeeded!\n",
|
||||
username, identity->comment);
|
||||
break;
|
||||
@@ -234,7 +240,7 @@ int main(int argc, char *argv[])
|
||||
#endif
|
||||
}
|
||||
|
||||
printf("all done!\n");
|
||||
fprintf(stderr, "all done!\n");
|
||||
|
||||
libssh2_exit();
|
||||
|
||||
|
@@ -91,8 +91,15 @@ int main(int argc, char *argv[])
|
||||
|
||||
#ifdef WIN32
|
||||
WSADATA wsadata;
|
||||
WSAStartup(MAKEWORD(2,0), &wsadata);
|
||||
int err;
|
||||
|
||||
err = WSAStartup(MAKEWORD(2,0), &wsadata);
|
||||
if (err != 0) {
|
||||
fprintf(stderr, "WSAStartup failed with error: %d\n", err);
|
||||
return 1;
|
||||
}
|
||||
#endif
|
||||
|
||||
if (argc > 1)
|
||||
/* must be ip address only */
|
||||
hostname = argv[1];
|
||||
@@ -327,7 +334,7 @@ int main(int argc, char *argv[])
|
||||
}
|
||||
|
||||
if (exitsignal)
|
||||
printf("\nGot signal: %s\n", exitsignal);
|
||||
fprintf(stderr, "\nGot signal: %s\n", exitsignal);
|
||||
|
||||
libssh2_channel_free(channel);
|
||||
channel = NULL;
|
||||
|
@@ -92,8 +92,15 @@ int main(int argc, char *argv[])
|
||||
|
||||
#ifdef WIN32
|
||||
WSADATA wsadata;
|
||||
WSAStartup(MAKEWORD(2,0), &wsadata);
|
||||
int err;
|
||||
|
||||
err = WSAStartup(MAKEWORD(2,0), &wsadata);
|
||||
if (err != 0) {
|
||||
fprintf(stderr, "WSAStartup failed with error: %d\n", err);
|
||||
return 1;
|
||||
}
|
||||
#endif
|
||||
|
||||
if (argc > 1)
|
||||
/* must be ip address only */
|
||||
hostname = argv[1];
|
||||
@@ -292,9 +299,9 @@ int main(int argc, char *argv[])
|
||||
}
|
||||
|
||||
if (exitsignal)
|
||||
printf("\nGot signal: %s\n", exitsignal);
|
||||
fprintf(stderr, "\nGot signal: %s\n", exitsignal);
|
||||
else
|
||||
printf("\nEXIT: %d bytecount: %d\n", exitcode, bytecount);
|
||||
fprintf(stderr, "\nEXIT: %d bytecount: %d\n", exitcode, bytecount);
|
||||
|
||||
libssh2_channel_free(channel);
|
||||
channel = NULL;
|
||||
|
@@ -102,7 +102,7 @@ static int netconf_read_until(LIBSSH2_CHANNEL *channel, const char *endtag,
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
int rc, sock = -1, i, auth = AUTH_NONE;
|
||||
int rc, i, auth = AUTH_NONE;
|
||||
struct sockaddr_in sin;
|
||||
const char *fingerprint;
|
||||
char *userauthlist;
|
||||
@@ -112,9 +112,17 @@ int main(int argc, char *argv[])
|
||||
ssize_t len;
|
||||
|
||||
#ifdef WIN32
|
||||
SOCKET sock = INVALID_SOCKET;
|
||||
WSADATA wsadata;
|
||||
int err;
|
||||
|
||||
WSAStartup(MAKEWORD(2,0), &wsadata);
|
||||
err = WSAStartup(MAKEWORD(2,0), &wsadata);
|
||||
if (err != 0) {
|
||||
fprintf(stderr, "WSAStartup failed with error: %d\n", err);
|
||||
return 1;
|
||||
}
|
||||
#else
|
||||
int sock = -1;
|
||||
#endif
|
||||
|
||||
if (argc > 1)
|
||||
@@ -132,6 +140,18 @@ int main(int argc, char *argv[])
|
||||
|
||||
/* Connect to SSH server */
|
||||
sock = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP);
|
||||
#ifdef WIN32
|
||||
if (sock == INVALID_SOCKET) {
|
||||
fprintf(stderr, "failed to open socket!\n");
|
||||
return -1;
|
||||
}
|
||||
#else
|
||||
if (sock == -1) {
|
||||
perror("socket");
|
||||
return -1;
|
||||
}
|
||||
#endif
|
||||
|
||||
sin.sin_family = AF_INET;
|
||||
if (INADDR_NONE == (sin.sin_addr.s_addr = inet_addr(server_ip))) {
|
||||
fprintf(stderr, "inet_addr: Invalid IP address \"%s\"\n", server_ip);
|
||||
@@ -173,7 +193,7 @@ int main(int argc, char *argv[])
|
||||
|
||||
/* check what authentication methods are available */
|
||||
userauthlist = libssh2_userauth_list(session, username, strlen(username));
|
||||
printf("Authentication methods: %s\n", userauthlist);
|
||||
fprintf(stderr, "Authentication methods: %s\n", userauthlist);
|
||||
if (strstr(userauthlist, "password"))
|
||||
auth |= AUTH_PASSWORD;
|
||||
if (strstr(userauthlist, "publickey"))
|
||||
@@ -195,12 +215,12 @@ int main(int argc, char *argv[])
|
||||
} else if (auth & AUTH_PUBLICKEY) {
|
||||
if (libssh2_userauth_publickey_fromfile(session, username, keyfile1,
|
||||
keyfile2, password)) {
|
||||
printf("Authentication by public key failed!\n");
|
||||
fprintf(stderr, "Authentication by public key failed!\n");
|
||||
goto shutdown;
|
||||
}
|
||||
printf("Authentication by public key succeeded.\n");
|
||||
fprintf(stderr, "Authentication by public key succeeded.\n");
|
||||
} else {
|
||||
printf("No supported authentication methods found!\n");
|
||||
fprintf(stderr, "No supported authentication methods found!\n");
|
||||
goto shutdown;
|
||||
}
|
||||
|
||||
@@ -223,7 +243,7 @@ int main(int argc, char *argv[])
|
||||
|
||||
/* NETCONF: http://tools.ietf.org/html/draft-ietf-netconf-ssh-06 */
|
||||
|
||||
printf("Sending NETCONF client <hello>\n");
|
||||
fprintf(stderr, "Sending NETCONF client <hello>\n");
|
||||
snprintf(buf, sizeof(buf),
|
||||
"<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"
|
||||
"<hello>"
|
||||
@@ -235,14 +255,14 @@ int main(int argc, char *argv[])
|
||||
if (-1 == netconf_write(channel, buf, len))
|
||||
goto shutdown;
|
||||
|
||||
printf("Reading NETCONF server <hello>\n");
|
||||
fprintf(stderr, "Reading NETCONF server <hello>\n");
|
||||
len = netconf_read_until(channel, "</hello>", buf, sizeof(buf));
|
||||
if (-1 == len)
|
||||
goto shutdown;
|
||||
|
||||
printf("Got %d bytes:\n----------------------\n%s", (int)len, buf);
|
||||
fprintf(stderr, "Got %d bytes:\n----------------------\n%s", (int)len, buf);
|
||||
|
||||
printf("Sending NETCONF <rpc>\n");
|
||||
fprintf(stderr, "Sending NETCONF <rpc>\n");
|
||||
snprintf(buf, sizeof(buf),
|
||||
"<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"
|
||||
"<rpc xmlns=\"urn:ietf:params:xml:ns:netconf:base:1.0\">"
|
||||
@@ -252,12 +272,12 @@ int main(int argc, char *argv[])
|
||||
if (-1 == netconf_write(channel, buf, len))
|
||||
goto shutdown;
|
||||
|
||||
printf("Reading NETCONF <rpc-reply>\n");
|
||||
fprintf(stderr, "Reading NETCONF <rpc-reply>\n");
|
||||
len = netconf_read_until(channel, "</rpc-reply>", buf, sizeof(buf));
|
||||
if (-1 == len)
|
||||
goto shutdown;
|
||||
|
||||
printf("Got %d bytes:\n----------------------\n%s", (int)len, buf);
|
||||
fprintf(stderr, "Got %d bytes:\n----------------------\n%s", (int)len, buf);
|
||||
|
||||
shutdown:
|
||||
if (channel)
|
||||
|
@@ -35,11 +35,11 @@ const char *password = "";
|
||||
const char *server_ip = "127.0.0.1";
|
||||
|
||||
const char *remote_listenhost = "localhost"; /* resolved by the server */
|
||||
unsigned int remote_wantport = 2222;
|
||||
unsigned int remote_listenport;
|
||||
int remote_wantport = 2222;
|
||||
int remote_listenport;
|
||||
|
||||
const char *local_destip = "127.0.0.1";
|
||||
unsigned int local_destport = 22;
|
||||
int local_destport = 22;
|
||||
|
||||
enum {
|
||||
AUTH_NONE = 0,
|
||||
@@ -49,7 +49,7 @@ enum {
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
int rc, sock = -1, forwardsock = -1, i, auth = AUTH_NONE;
|
||||
int rc, i, auth = AUTH_NONE;
|
||||
struct sockaddr_in sin;
|
||||
socklen_t sinlen = sizeof(sin);
|
||||
const char *fingerprint;
|
||||
@@ -57,20 +57,23 @@ int main(int argc, char *argv[])
|
||||
LIBSSH2_SESSION *session;
|
||||
LIBSSH2_LISTENER *listener = NULL;
|
||||
LIBSSH2_CHANNEL *channel = NULL;
|
||||
const char *shost;
|
||||
unsigned int sport;
|
||||
fd_set fds;
|
||||
struct timeval tv;
|
||||
ssize_t len, wr;
|
||||
char buf[16384];
|
||||
|
||||
#ifdef WIN32
|
||||
char sockopt;
|
||||
SOCKET sock = INVALID_SOCKET, forwardsock = INVALID_SOCKET;
|
||||
WSADATA wsadata;
|
||||
int err;
|
||||
|
||||
WSAStartup(MAKEWORD(2,0), &wsadata);
|
||||
err = WSAStartup(MAKEWORD(2,0), &wsadata);
|
||||
if (err != 0) {
|
||||
fprintf(stderr, "WSAStartup failed with error: %d\n", err);
|
||||
return 1;
|
||||
}
|
||||
#else
|
||||
int sockopt;
|
||||
int sock = -1, forwardsock = -1;
|
||||
#endif
|
||||
|
||||
if (argc > 1)
|
||||
@@ -96,6 +99,18 @@ int main(int argc, char *argv[])
|
||||
|
||||
/* Connect to SSH server */
|
||||
sock = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP);
|
||||
#ifdef WIN32
|
||||
if (sock == INVALID_SOCKET) {
|
||||
fprintf(stderr, "failed to open socket!\n");
|
||||
return -1;
|
||||
}
|
||||
#else
|
||||
if (sock == -1) {
|
||||
perror("socket");
|
||||
return -1;
|
||||
}
|
||||
#endif
|
||||
|
||||
sin.sin_family = AF_INET;
|
||||
if (INADDR_NONE == (sin.sin_addr.s_addr = inet_addr(server_ip))) {
|
||||
perror("inet_addr");
|
||||
@@ -137,7 +152,7 @@ int main(int argc, char *argv[])
|
||||
|
||||
/* check what authentication methods are available */
|
||||
userauthlist = libssh2_userauth_list(session, username, strlen(username));
|
||||
printf("Authentication methods: %s\n", userauthlist);
|
||||
fprintf(stderr, "Authentication methods: %s\n", userauthlist);
|
||||
if (strstr(userauthlist, "password"))
|
||||
auth |= AUTH_PASSWORD;
|
||||
if (strstr(userauthlist, "publickey"))
|
||||
@@ -159,17 +174,17 @@ int main(int argc, char *argv[])
|
||||
} else if (auth & AUTH_PUBLICKEY) {
|
||||
if (libssh2_userauth_publickey_fromfile(session, username, keyfile1,
|
||||
keyfile2, password)) {
|
||||
printf("\tAuthentication by public key failed!\n");
|
||||
fprintf(stderr, "\tAuthentication by public key failed!\n");
|
||||
goto shutdown;
|
||||
}
|
||||
printf("\tAuthentication by public key succeeded.\n");
|
||||
fprintf(stderr, "\tAuthentication by public key succeeded.\n");
|
||||
} else {
|
||||
printf("No supported authentication methods found!\n");
|
||||
fprintf(stderr, "No supported authentication methods found!\n");
|
||||
goto shutdown;
|
||||
}
|
||||
|
||||
printf("Asking server to listen on remote %s:%d\n", remote_listenhost,
|
||||
remote_wantport);
|
||||
fprintf(stderr, "Asking server to listen on remote %s:%d\n",
|
||||
remote_listenhost, remote_wantport);
|
||||
|
||||
listener = libssh2_channel_forward_listen_ex(session, remote_listenhost,
|
||||
remote_wantport, &remote_listenport, 1);
|
||||
@@ -180,10 +195,10 @@ int main(int argc, char *argv[])
|
||||
goto shutdown;
|
||||
}
|
||||
|
||||
printf("Server is listening on %s:%d\n", remote_listenhost,
|
||||
fprintf(stderr, "Server is listening on %s:%d\n", remote_listenhost,
|
||||
remote_listenport);
|
||||
|
||||
printf("Waiting for remote connection\n");
|
||||
fprintf(stderr, "Waiting for remote connection\n");
|
||||
channel = libssh2_channel_forward_accept(listener);
|
||||
if (!channel) {
|
||||
fprintf(stderr, "Could not accept connection!\n"
|
||||
@@ -192,9 +207,22 @@ int main(int argc, char *argv[])
|
||||
goto shutdown;
|
||||
}
|
||||
|
||||
printf("Accepted remote connection. Connecting to local server %s:%d\n",
|
||||
fprintf(stderr,
|
||||
"Accepted remote connection. Connecting to local server %s:%d\n",
|
||||
local_destip, local_destport);
|
||||
forwardsock = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP);
|
||||
#ifdef WIN32
|
||||
if (forwardsock == INVALID_SOCKET) {
|
||||
fprintf(stderr, "failed to open forward socket!\n");
|
||||
goto shutdown;
|
||||
}
|
||||
#else
|
||||
if (forwardsock == -1) {
|
||||
perror("socket");
|
||||
goto shutdown;
|
||||
}
|
||||
#endif
|
||||
|
||||
sin.sin_family = AF_INET;
|
||||
sin.sin_port = htons(local_destport);
|
||||
if (INADDR_NONE == (sin.sin_addr.s_addr = inet_addr(local_destip))) {
|
||||
@@ -206,7 +234,7 @@ int main(int argc, char *argv[])
|
||||
goto shutdown;
|
||||
}
|
||||
|
||||
printf("Forwarding connection from remote %s:%d to local %s:%d\n",
|
||||
fprintf(stderr, "Forwarding connection from remote %s:%d to local %s:%d\n",
|
||||
remote_listenhost, remote_listenport, local_destip, local_destport);
|
||||
|
||||
/* Must use non-blocking IO hereafter due to the current libssh2 API */
|
||||
@@ -228,7 +256,7 @@ int main(int argc, char *argv[])
|
||||
perror("read");
|
||||
goto shutdown;
|
||||
} else if (0 == len) {
|
||||
printf("The local server at %s:%d disconnected!\n",
|
||||
fprintf(stderr, "The local server at %s:%d disconnected!\n",
|
||||
local_destip, local_destport);
|
||||
goto shutdown;
|
||||
}
|
||||
@@ -260,7 +288,7 @@ int main(int argc, char *argv[])
|
||||
wr += i;
|
||||
}
|
||||
if (libssh2_channel_eof(channel)) {
|
||||
printf("The remote client at %s:%d disconnected!\n",
|
||||
fprintf(stderr, "The remote client at %s:%d disconnected!\n",
|
||||
remote_listenhost, remote_listenport);
|
||||
goto shutdown;
|
||||
}
|
||||
|
@@ -10,6 +10,7 @@
|
||||
#include <sys/ioctl.h>
|
||||
#include <netinet/in.h>
|
||||
#include <sys/socket.h>
|
||||
#include <sys/select.h>
|
||||
#include <arpa/inet.h>
|
||||
#include <unistd.h>
|
||||
#include <sys/types.h>
|
||||
@@ -48,13 +49,13 @@ static void remove_node(struct chan_X11_list *elem)
|
||||
current_node = gp_x11_chan;
|
||||
|
||||
if (gp_x11_chan == elem) {
|
||||
/* Removing the only one element in the list */
|
||||
free(gp_x11_chan);
|
||||
gp_x11_chan = NULL;
|
||||
gp_x11_chan = gp_x11_chan->next;
|
||||
free(current_node);
|
||||
return;
|
||||
}
|
||||
|
||||
while( current_node->next != NULL) {
|
||||
if (current_node->next ==elem) {
|
||||
while (current_node->next != NULL) {
|
||||
if (current_node->next == elem) {
|
||||
current_node->next = current_node->next->next;
|
||||
current_node = current_node->next;
|
||||
free(current_node);
|
||||
@@ -209,24 +210,27 @@ static int x11_send_receive(LIBSSH2_CHANNEL *channel, int sock)
|
||||
rc = libssh2_poll(fds, nfds, 0);
|
||||
if (rc >0) {
|
||||
rc = libssh2_channel_read(channel, buf, bufsize);
|
||||
rc = write(sock, buf, rc);
|
||||
write(sock, buf, rc);
|
||||
}
|
||||
|
||||
rc = select(sock+1,&set,NULL,NULL,&timeval_out);
|
||||
rc = select(sock+1, &set, NULL, NULL, &timeval_out);
|
||||
if (rc > 0) {
|
||||
memset((void *)buf,0,bufsize);
|
||||
memset((void *)buf, 0, bufsize);
|
||||
|
||||
/* Data in sock*/
|
||||
rc = read(sock, buf, bufsize);
|
||||
if (rc > 0)
|
||||
rc = libssh2_channel_write(channel,buf, rc);
|
||||
else
|
||||
if (rc > 0) {
|
||||
libssh2_channel_write(channel, buf, rc);
|
||||
}
|
||||
else {
|
||||
free(buf);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
free(fds);
|
||||
free(buf);
|
||||
if (libssh2_channel_eof (channel) == 1) {
|
||||
if (libssh2_channel_eof(channel) == 1) {
|
||||
return -1;
|
||||
}
|
||||
return 0;
|
||||
@@ -289,6 +293,10 @@ main (int argc, char *argv[])
|
||||
}
|
||||
|
||||
sock = socket (AF_INET, SOCK_STREAM, 0);
|
||||
if (sock == -1) {
|
||||
perror("socket");
|
||||
return -1;
|
||||
}
|
||||
|
||||
sin.sin_family = AF_INET;
|
||||
sin.sin_port = htons (22);
|
||||
@@ -369,6 +377,9 @@ main (int argc, char *argv[])
|
||||
return -1;
|
||||
}
|
||||
|
||||
memset(&w_size, 0, sizeof(struct winsize));
|
||||
memset(&w_size_bck, 0, sizeof(struct winsize));
|
||||
|
||||
while (1) {
|
||||
|
||||
FD_ZERO(&set);
|
||||
@@ -400,7 +411,7 @@ main (int argc, char *argv[])
|
||||
|
||||
rc = libssh2_poll(fds, nfds, 0);
|
||||
if (rc >0) {
|
||||
rc = libssh2_channel_read(channel, buf,sizeof(buf));
|
||||
libssh2_channel_read(channel, buf, sizeof(buf));
|
||||
fprintf(stdout, "%s", buf);
|
||||
fflush(stdout);
|
||||
}
|
||||
|
@@ -1,5 +1,5 @@
|
||||
/* Copyright (c) 2004-2009, Sara Golemon <sarag@libssh2.org>
|
||||
* Copyright (c) 2009-2010 Daniel Stenberg
|
||||
* Copyright (c) 2009-2012 Daniel Stenberg
|
||||
* Copyright (c) 2010 Simon Josefsson <simon@josefsson.org>
|
||||
* All rights reserved.
|
||||
*
|
||||
@@ -40,19 +40,19 @@
|
||||
#ifndef LIBSSH2_H
|
||||
#define LIBSSH2_H 1
|
||||
|
||||
#define LIBSSH2_COPYRIGHT "2004-2011 The libssh2 project and its contributors."
|
||||
#define LIBSSH2_COPYRIGHT "2004-2014 The libssh2 project and its contributors."
|
||||
|
||||
/* We use underscore instead of dash when appending DEV 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 course not
|
||||
have dashes either. */
|
||||
#define LIBSSH2_VERSION "1.4.0_DEV"
|
||||
#define LIBSSH2_VERSION "1.4.4_DEV"
|
||||
|
||||
/* The numeric version number is also available "in parts" by using these
|
||||
defines: */
|
||||
#define LIBSSH2_VERSION_MAJOR 1
|
||||
#define LIBSSH2_VERSION_MINOR 4
|
||||
#define LIBSSH2_VERSION_PATCH 0
|
||||
#define LIBSSH2_VERSION_PATCH 4
|
||||
|
||||
/* This is the numeric version of the libssh2 version number, meant for easier
|
||||
parsing and comparions by programs. The LIBSSH2_VERSION_NUM define will
|
||||
@@ -69,7 +69,7 @@
|
||||
and it is always a greater number in a more recent release. It makes
|
||||
comparisons with greater than and less than work.
|
||||
*/
|
||||
#define LIBSSH2_VERSION_NUM 0x010400
|
||||
#define LIBSSH2_VERSION_NUM 0x010404
|
||||
|
||||
/*
|
||||
* This is the date and time when the full source package was created. The
|
||||
@@ -100,11 +100,15 @@ extern "C" {
|
||||
/* Allow alternate API prefix from CFLAGS or calling app */
|
||||
#ifndef LIBSSH2_API
|
||||
# ifdef LIBSSH2_WIN32
|
||||
# ifdef LIBSSH2_LIBRARY
|
||||
# define LIBSSH2_API __declspec(dllexport)
|
||||
# ifdef _WINDLL
|
||||
# ifdef LIBSSH2_LIBRARY
|
||||
# define LIBSSH2_API __declspec(dllexport)
|
||||
# else
|
||||
# define LIBSSH2_API __declspec(dllimport)
|
||||
# endif /* LIBSSH2_LIBRARY */
|
||||
# else
|
||||
# define LIBSSH2_API __declspec(dllimport)
|
||||
# endif /* LIBSSH2_LIBRARY */
|
||||
# define LIBSSH2_API
|
||||
# endif
|
||||
# else /* !LIBSSH2_WIN32 */
|
||||
# define LIBSSH2_API
|
||||
# endif /* LIBSSH2_WIN32 */
|
||||
@@ -281,7 +285,8 @@ typedef struct _LIBSSH2_POLLFD {
|
||||
unsigned char type; /* LIBSSH2_POLLFD_* below */
|
||||
|
||||
union {
|
||||
int socket; /* File descriptors -- examined with system select() call */
|
||||
libssh2_socket_t socket; /* File descriptors -- examined with
|
||||
system select() call */
|
||||
LIBSSH2_CHANNEL *channel; /* Examined by checking internal state */
|
||||
LIBSSH2_LISTENER *listener; /* Read polls only -- are inbound
|
||||
connections waiting to be accepted? */
|
||||
@@ -405,6 +410,7 @@ typedef struct _LIBSSH2_POLLFD {
|
||||
#define LIBSSH2_ERROR_SOCKET_RECV -43
|
||||
#define LIBSSH2_ERROR_ENCRYPT -44
|
||||
#define LIBSSH2_ERROR_BAD_SOCKET -45
|
||||
#define LIBSSH2_ERROR_KNOWN_HOSTS -46
|
||||
|
||||
/* this is a define to provide the old (<= 1.2.7) name */
|
||||
#define LIBSSH2_ERROR_BANNER_NONE LIBSSH2_ERROR_BANNER_RECV
|
||||
@@ -520,8 +526,9 @@ LIBSSH2_API int libssh2_userauth_password_ex(LIBSSH2_SESSION *session,
|
||||
LIBSSH2_PASSWD_CHANGEREQ_FUNC((*passwd_change_cb)));
|
||||
|
||||
#define libssh2_userauth_password(session, username, password) \
|
||||
libssh2_userauth_password_ex((session), (username), strlen(username), \
|
||||
(password), strlen(password), NULL)
|
||||
libssh2_userauth_password_ex((session), (username), \
|
||||
(unsigned int)strlen(username), \
|
||||
(password), (unsigned int)strlen(password), NULL)
|
||||
|
||||
LIBSSH2_API int
|
||||
libssh2_userauth_publickey_fromfile_ex(LIBSSH2_SESSION *session,
|
||||
@@ -533,9 +540,10 @@ libssh2_userauth_publickey_fromfile_ex(LIBSSH2_SESSION *session,
|
||||
|
||||
#define libssh2_userauth_publickey_fromfile(session, username, publickey, \
|
||||
privatekey, passphrase) \
|
||||
libssh2_userauth_publickey_fromfile_ex((session), (username), \
|
||||
strlen(username), (publickey), \
|
||||
(privatekey), (passphrase))
|
||||
libssh2_userauth_publickey_fromfile_ex((session), (username), \
|
||||
(unsigned int)strlen(username), \
|
||||
(publickey), \
|
||||
(privatekey), (passphrase))
|
||||
|
||||
LIBSSH2_API int
|
||||
libssh2_userauth_publickey(LIBSSH2_SESSION *session,
|
||||
@@ -560,10 +568,13 @@ libssh2_userauth_hostbased_fromfile_ex(LIBSSH2_SESSION *session,
|
||||
#define libssh2_userauth_hostbased_fromfile(session, username, publickey, \
|
||||
privatekey, passphrase, hostname) \
|
||||
libssh2_userauth_hostbased_fromfile_ex((session), (username), \
|
||||
strlen(username), (publickey), \
|
||||
(privatekey), (passphrase), \
|
||||
(hostname), strlen(hostname), \
|
||||
(username), strlen(username))
|
||||
(unsigned int)strlen(username), \
|
||||
(publickey), \
|
||||
(privatekey), (passphrase), \
|
||||
(hostname), \
|
||||
(unsigned int)strlen(hostname), \
|
||||
(username), \
|
||||
(unsigned int)strlen(username))
|
||||
|
||||
/*
|
||||
* response_callback is provided with filled by library prompts array,
|
||||
@@ -577,16 +588,17 @@ libssh2_userauth_keyboard_interactive_ex(LIBSSH2_SESSION* session,
|
||||
unsigned int username_len,
|
||||
LIBSSH2_USERAUTH_KBDINT_RESPONSE_FUNC((*response_callback)));
|
||||
|
||||
#define libssh2_userauth_keyboard_interactive(session, username, \
|
||||
response_callback) \
|
||||
libssh2_userauth_keyboard_interactive_ex((session), (username), \
|
||||
strlen(username), (response_callback))
|
||||
#define libssh2_userauth_keyboard_interactive(session, username, \
|
||||
response_callback) \
|
||||
libssh2_userauth_keyboard_interactive_ex((session), (username), \
|
||||
(unsigned int)strlen(username), \
|
||||
(response_callback))
|
||||
|
||||
LIBSSH2_API int libssh2_poll(LIBSSH2_POLLFD *fds, unsigned int nfds,
|
||||
long timeout);
|
||||
|
||||
/* Channel API */
|
||||
#define LIBSSH2_CHANNEL_WINDOW_DEFAULT (256*1024)
|
||||
#define LIBSSH2_CHANNEL_WINDOW_DEFAULT (2*1024*1024)
|
||||
#define LIBSSH2_CHANNEL_PACKET_DEFAULT 32768
|
||||
#define LIBSSH2_CHANNEL_MINADJUST 1024
|
||||
|
||||
@@ -634,9 +646,10 @@ LIBSSH2_API int libssh2_channel_setenv_ex(LIBSSH2_CHANNEL *channel,
|
||||
const char *value,
|
||||
unsigned int value_len);
|
||||
|
||||
#define libssh2_channel_setenv(channel, varname, value) \
|
||||
libssh2_channel_setenv_ex((channel), (varname), strlen(varname), (value), \
|
||||
strlen(value))
|
||||
#define libssh2_channel_setenv(channel, varname, value) \
|
||||
libssh2_channel_setenv_ex((channel), (varname), \
|
||||
(unsigned int)strlen(varname), (value), \
|
||||
(unsigned int)strlen(value))
|
||||
|
||||
LIBSSH2_API int libssh2_channel_request_pty_ex(LIBSSH2_CHANNEL *channel,
|
||||
const char *term,
|
||||
@@ -645,10 +658,12 @@ LIBSSH2_API int libssh2_channel_request_pty_ex(LIBSSH2_CHANNEL *channel,
|
||||
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), \
|
||||
(unsigned int)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,
|
||||
@@ -675,11 +690,11 @@ LIBSSH2_API int libssh2_channel_process_startup(LIBSSH2_CHANNEL *channel,
|
||||
NULL, 0)
|
||||
#define libssh2_channel_exec(channel, command) \
|
||||
libssh2_channel_process_startup((channel), "exec", sizeof("exec") - 1, \
|
||||
(command), strlen(command))
|
||||
(command), (unsigned int)strlen(command))
|
||||
#define libssh2_channel_subsystem(channel, subsystem) \
|
||||
libssh2_channel_process_startup((channel), "subsystem", \
|
||||
sizeof("subsystem") - 1, (subsystem), \
|
||||
strlen(subsystem))
|
||||
(unsigned int)strlen(subsystem))
|
||||
|
||||
LIBSSH2_API ssize_t libssh2_channel_read_ex(LIBSSH2_CHANNEL *channel,
|
||||
int stream_id, char *buf,
|
||||
@@ -855,11 +870,12 @@ libssh2_knownhost_init(LIBSSH2_SESSION *session);
|
||||
#define LIBSSH2_KNOWNHOST_KEYENC_BASE64 (2<<16)
|
||||
|
||||
/* type of key (2 bits) */
|
||||
#define LIBSSH2_KNOWNHOST_KEY_MASK (3<<18)
|
||||
#define LIBSSH2_KNOWNHOST_KEY_MASK (7<<18)
|
||||
#define LIBSSH2_KNOWNHOST_KEY_SHIFT 18
|
||||
#define LIBSSH2_KNOWNHOST_KEY_RSA1 (1<<18)
|
||||
#define LIBSSH2_KNOWNHOST_KEY_SSHRSA (2<<18)
|
||||
#define LIBSSH2_KNOWNHOST_KEY_SSHDSS (3<<18)
|
||||
#define LIBSSH2_KNOWNHOST_KEY_UNKNOWN (7<<18)
|
||||
|
||||
LIBSSH2_API int
|
||||
libssh2_knownhost_add(LIBSSH2_KNOWNHOSTS *hosts,
|
||||
|
@@ -247,6 +247,7 @@ LIBSSH2_API int libssh2_sftp_readdir_ex(LIBSSH2_SFTP_HANDLE *handle, \
|
||||
|
||||
LIBSSH2_API ssize_t libssh2_sftp_write(LIBSSH2_SFTP_HANDLE *handle,
|
||||
const char *buffer, size_t count);
|
||||
LIBSSH2_API int libssh2_sftp_fsync(LIBSSH2_SFTP_HANDLE *handle);
|
||||
|
||||
LIBSSH2_API int libssh2_sftp_close_handle(LIBSSH2_SFTP_HANDLE *handle);
|
||||
#define libssh2_sftp_close(handle) libssh2_sftp_close_handle(handle)
|
||||
|
@@ -11,6 +11,7 @@ Name: libssh2
|
||||
URL: http://www.libssh2.org/
|
||||
Description: Library for SSH-based communication
|
||||
Version: @LIBSSH2VER@
|
||||
Requires.private: @LIBSREQUIRED@
|
||||
Libs: -L${libdir} -lssh2 @LDFLAGS@ @LIBS@
|
||||
Libs.private: @LIBS@
|
||||
Cflags: -I${includedir}
|
||||
|
@@ -1,7 +1,7 @@
|
||||
#########################################################################
|
||||
#
|
||||
## Makefile for building libssh2 (NetWare version - gnu make)
|
||||
## Use: make -f Makefile.netware [help|all|clean|dev|devclean|dist|distclean|lib|nlm|objclean]
|
||||
## Use: make [help|all|clean|dev|devclean|dist|distclean|lib|nlm|objclean]
|
||||
##
|
||||
## Hacked by: Guenter Knauf
|
||||
#
|
||||
@@ -14,12 +14,12 @@ endif
|
||||
|
||||
# Edit the path below to point to the base of your Zlib sources.
|
||||
ifndef ZLIB_PATH
|
||||
ZLIB_PATH = ../../zlib-1.2.5
|
||||
ZLIB_PATH = ../../zlib-1.2.8
|
||||
endif
|
||||
|
||||
# Edit the path below to point to the base of your OpenSSL package.
|
||||
ifndef OPENSSL_PATH
|
||||
OPENSSL_PATH = ../../openssl-0.9.8r
|
||||
OPENSSL_PATH = ../../openssl-0.9.8zc
|
||||
endif
|
||||
|
||||
# Edit the path below to point to your Distribution folder.
|
||||
@@ -37,7 +37,7 @@ DEVLARC = $(DEVLDIR).zip
|
||||
# Edit the vars below to change NLM target settings.
|
||||
TARGET = libssh2
|
||||
VERSION = $(LIBSSH2_VERSION)
|
||||
COPYR = Copyright (c) $(LIBSSH2_COPYRIGHT_STR)
|
||||
CPRIGHT = Copyright (c) $(LIBSSH2_COPYRIGHT_STR)
|
||||
WWWURL = http://www.libssh2.org/
|
||||
DESCR = libssh2 $(LIBSSH2_VERSION_STR) ($(LIBARCH)) - $(WWWURL)
|
||||
MTSAFE = YES
|
||||
@@ -76,10 +76,7 @@ ifdef METROWERKS
|
||||
else
|
||||
CC = $(CROSSPREFIX)gcc
|
||||
endif
|
||||
CP = cp -afv
|
||||
MD = mkdir
|
||||
RD = rm -fr
|
||||
# RM = rm -f
|
||||
|
||||
# Here you can find a native Win32 binary of the original awk:
|
||||
# http://www.gknw.net/development/prgtools/awk-20100523.zip
|
||||
AWK = awk
|
||||
@@ -89,6 +86,34 @@ AWK = awk
|
||||
MPKXDC = mkxdc
|
||||
ZIP = zip -qzr9
|
||||
|
||||
# Platform-dependent helper tool macros
|
||||
ifeq ($(findstring /sh,$(SHELL)),/sh)
|
||||
DEL = rm -f $1
|
||||
RMDIR = rm -fr $1
|
||||
MKDIR = mkdir -p $1
|
||||
COPY = -cp -afv $1 $2
|
||||
#COPYR = -cp -afr $1/* $2
|
||||
COPYR = -rsync -aC $1/* $2
|
||||
TOUCH = touch $1
|
||||
CAT = cat
|
||||
ECHONL = echo ""
|
||||
DL = '
|
||||
else
|
||||
ifeq "$(OS)" "Windows_NT"
|
||||
DEL = -del 2>NUL /q /f $(subst /,\,$1)
|
||||
RMDIR = -rd 2>NUL /q /s $(subst /,\,$1)
|
||||
else
|
||||
DEL = -del 2>NUL $(subst /,\,$1)
|
||||
RMDIR = -deltree 2>NUL /y $(subst /,\,$1)
|
||||
endif
|
||||
MKDIR = -md 2>NUL $(subst /,\,$1)
|
||||
COPY = -copy 2>NUL /y $(subst /,\,$1) $(subst /,\,$2)
|
||||
COPYR = -xcopy 2>NUL /q /y /e $(subst /,\,$1) $(subst /,\,$2)
|
||||
TOUCH = copy 2>&1>NUL /b $(subst /,\,$1) +,,
|
||||
CAT = type
|
||||
ECHONL = $(ComSpec) /c echo.
|
||||
endif
|
||||
|
||||
# LIBARCH_U = $(shell $(AWK) 'BEGIN {print toupper(ARGV[1])}' $(LIBARCH))
|
||||
LIBARCH_L = $(shell $(AWK) 'BEGIN {print tolower(ARGV[1])}' $(LIBARCH))
|
||||
|
||||
@@ -120,13 +145,14 @@ else
|
||||
endif
|
||||
else
|
||||
LD = $(CROSSPREFIX)nlmconv
|
||||
LDFLAGS = -T
|
||||
LDFLAGS = -UT
|
||||
AR = $(CROSSPREFIX)ar
|
||||
ARFLAGS = -cq
|
||||
LIBEXT = a
|
||||
RANLIB = $(CROSSPREFIX)ranlib
|
||||
CFLAGS += -m32
|
||||
CFLAGS += -fno-builtin -fpcc-struct-return -fno-strict-aliasing
|
||||
CFLAGS += -m32
|
||||
CFLAGS += -fno-builtin -fpcc-struct-return
|
||||
CFLAGS += -fno-strict-aliasing
|
||||
CFLAGS += -Wall # -pedantic
|
||||
#CFLAGS += -Wno-pointer-sign
|
||||
ifeq ($(LIBARCH),LIBC)
|
||||
@@ -185,15 +211,12 @@ ifdef XDCOPT
|
||||
XDCDATA = $(OBJDIR)/$(TARGET).xdc
|
||||
endif
|
||||
|
||||
ifeq ($(findstring /sh,$(SHELL)),/sh)
|
||||
DL = '
|
||||
DS = /
|
||||
else
|
||||
DS = \\
|
||||
endif
|
||||
|
||||
vpath %.c . ../src
|
||||
|
||||
# only OpenSSL is supported with this build system
|
||||
CFLAGS += -DLIBSSH2_OPENSSL
|
||||
include ../Makefile.OpenSSL.inc
|
||||
|
||||
# include Makefile.inc to get CSOURCES define
|
||||
include ../Makefile.inc
|
||||
|
||||
@@ -217,69 +240,74 @@ lib: prebuild $(TARGET).$(LIBEXT)
|
||||
prebuild: $(OBJDIR) $(OBJDIR)/version.inc libssh2_config.h
|
||||
|
||||
test: all
|
||||
$(MAKE) -C test -f Makefile.netware
|
||||
$(MAKE) -C test
|
||||
|
||||
$(OBJDIR)/%.o: %.c
|
||||
# @echo Compiling $<
|
||||
$(CC) $(CFLAGS) -c $< -o $@
|
||||
|
||||
$(OBJDIR)/version.inc: ../include/libssh2.h $(OBJDIR)
|
||||
$(OBJDIR)/version.inc: ../get_ver.awk ../include/libssh2.h $(OBJDIR)
|
||||
@echo Creating $@
|
||||
@$(AWK) -f ../get_ver.awk $< > $@
|
||||
@$(AWK) -f $^ > $@
|
||||
|
||||
dist: all $(DISTDIR) $(DISTDIR)/readme.txt
|
||||
@-$(MD) $(DISTDIR)$(DS)bin
|
||||
@-$(CP) ../COPYING $(DISTDIR)
|
||||
@-$(CP) ../INSTALL $(DISTDIR)
|
||||
@-$(CP) ../README $(DISTDIR)
|
||||
@$(CP) $(TARGET).nlm $(DISTDIR)/bin
|
||||
@$(call MKDIR, $(DISTDIR)/bin)
|
||||
@$(call COPY, ../AUTHORS, $(DISTDIR))
|
||||
@$(call COPY, ../COPYING, $(DISTDIR))
|
||||
@$(call COPY, ../INSTALL, $(DISTDIR))
|
||||
@$(call COPY, ../README, $(DISTDIR))
|
||||
@$(call COPY, ../RELEASE-NOTES, $(DISTDIR))
|
||||
@$(call COPY, $(TARGET).nlm, $(DISTDIR)/bin)
|
||||
@echo Creating $(DISTARC)
|
||||
@$(ZIP) $(DISTARC) $(DISTDIR)/* < $(DISTDIR)/readme.txt
|
||||
|
||||
dev: all $(DEVLDIR) $(DEVLDIR)/readme.txt
|
||||
@-$(MD) $(DEVLDIR)$(DS)bin
|
||||
@-$(MD) $(DEVLDIR)$(DS)include
|
||||
@-$(MD) $(DEVLDIR)$(DS)nw
|
||||
@-$(CP) ../COPYING $(DISTDIR)
|
||||
@-$(CP) ../INSTALL $(DEVLDIR)
|
||||
@-$(CP) ../README $(DEVLDIR)
|
||||
@$(CP) $(TARGET).nlm $(DEVLDIR)/bin
|
||||
@$(CP) ../include/*.h $(DEVLDIR)/include
|
||||
@$(CP) libssh2_config.h $(DEVLDIR)/include
|
||||
@$(CP) $(TARGET).$(LIBEXT) $(DEVLDIR)/nw
|
||||
@$(call MKDIR, $(DEVLDIR)/bin)
|
||||
@$(call MKDIR, $(DEVLDIR)/include)
|
||||
@$(call MKDIR, $(DEVLDIR)/nw)
|
||||
@$(call COPY, ../AUTHORS, $(DEVLDIR))
|
||||
@$(call COPY, ../COPYING, $(DEVLDIR))
|
||||
@$(call COPY, ../INSTALL, $(DEVLDIR))
|
||||
@$(call COPY, ../README, $(DEVLDIR))
|
||||
@$(call COPY, ../RELEASE-NOTES, $(DEVLDIR))
|
||||
@$(call COPY, ../include/*.h, $(DEVLDIR)/include)
|
||||
@$(call COPY, libssh2_config.h, $(DEVLDIR)/include)
|
||||
@$(call COPY, $(TARGET).nlm, $(DEVLDIR)/bin)
|
||||
@$(call COPY, $(TARGET).imp, $(DEVLDIR)/nw)
|
||||
@$(call COPY, $(TARGET).$(LIBEXT), $(DEVLDIR)/nw)
|
||||
@echo Creating $(DEVLARC)
|
||||
@$(ZIP) $(DEVLARC) $(DEVLDIR)/* < $(DEVLDIR)/readme.txt
|
||||
|
||||
distclean: clean
|
||||
-$(RD) $(DISTDIR)
|
||||
-$(RM) $(DISTARC)
|
||||
$(call RMDIR, $(DISTDIR))
|
||||
$(call DEL, $(DISTARC))
|
||||
|
||||
devclean: clean
|
||||
-$(RD) $(DEVLDIR)
|
||||
-$(RM) $(DEVLARC)
|
||||
$(call RMDIR, $(DEVLDIR))
|
||||
$(call DEL, $(DEVLARC))
|
||||
|
||||
objclean:
|
||||
-$(RD) $(OBJDIR)
|
||||
$(call RMDIR, $(OBJDIR))
|
||||
|
||||
testclean: clean
|
||||
$(MAKE) -C test -f Makefile.netware clean
|
||||
$(MAKE) -C test clean
|
||||
|
||||
clean: objclean
|
||||
-$(RM) libssh2_config.h
|
||||
-$(RM) $(TARGET).nlm $(TARGET).$(LIBEXT) $(TARGET).imp
|
||||
$(call DEL, libssh2_config.h)
|
||||
$(call DEL, $(TARGET).*)
|
||||
|
||||
$(OBJDIR):
|
||||
@$(MD) $@
|
||||
@$(call MKDIR, $@)
|
||||
|
||||
$(DISTDIR):
|
||||
@$(MD) $@
|
||||
@$(call MKDIR, $@)
|
||||
|
||||
$(DEVLDIR):
|
||||
@$(MD) $@
|
||||
@$(call MKDIR, $@)
|
||||
|
||||
$(TARGET).$(LIBEXT): $(OBJS)
|
||||
@echo Creating $@
|
||||
@-$(RM) $@
|
||||
@$(call DEL, $@)
|
||||
@$(AR) $(ARFLAGS) $@ $^
|
||||
ifdef RANLIB
|
||||
@$(RANLIB) $@
|
||||
@@ -287,19 +315,19 @@ endif
|
||||
|
||||
$(TARGET).nlm: $(OBJDIR)/$(TARGET).def $(TARGET).imp $(OBJL) $(XDCDATA)
|
||||
@echo Linking $@
|
||||
@-$(RM) $@
|
||||
@$(call DEL, $@)
|
||||
@$(LD) $(LDFLAGS) $<
|
||||
|
||||
$(OBJDIR)/%.xdc: Makefile.netware
|
||||
$(OBJDIR)/%.xdc: GNUmakefile
|
||||
@echo Creating $@
|
||||
@$(MPKXDC) $(XDCOPT) $@
|
||||
|
||||
$(OBJDIR)/%.def: Makefile.netware
|
||||
$(OBJDIR)/%.def: GNUmakefile
|
||||
@echo $(DL)# DEF file for linking with $(LD)$(DL) > $@
|
||||
@echo $(DL)# Do not edit this file - it is created by make!$(DL) >> $@
|
||||
@echo $(DL)# All your changes will be lost!!$(DL) >> $@
|
||||
@echo $(DL)#$(DL) >> $@
|
||||
@echo $(DL)copyright "$(COPYR)"$(DL) >> $@
|
||||
@echo $(DL)copyright "$(CPRIGHT)"$(DL) >> $@
|
||||
@echo $(DL)description "$(DESCR)"$(DL) >> $@
|
||||
@echo $(DL)version $(VERSION)$(DL) >> $@
|
||||
ifdef NLMTYPE
|
||||
@@ -353,7 +381,7 @@ ifeq ($(LD),nlmconv)
|
||||
@echo $(DL)output $(TARGET).nlm$(DL) >> $@
|
||||
endif
|
||||
|
||||
libssh2_config.h: Makefile.netware
|
||||
libssh2_config.h: GNUmakefile
|
||||
@echo Creating $@
|
||||
@echo $(DL)/* $@ for NetWare target.$(DL) > $@
|
||||
@echo $(DL)** Do not edit this file - it is created by make!$(DL) >> $@
|
||||
@@ -479,7 +507,7 @@ ifeq ($(DB),DEBUG)
|
||||
@echo $(DL)#define LIBSSH2_DEBUG_USERAUTH 1$(DL) >> $@
|
||||
endif
|
||||
|
||||
libssh2.imp: Makefile.netware
|
||||
libssh2.imp: GNUmakefile
|
||||
@echo Creating $@
|
||||
@echo $(DL)# $@ for NetWare target.$(DL) > $@
|
||||
@echo $(DL)# Do not edit this file - it is created by make!$(DL) >> $@
|
||||
@@ -506,21 +534,25 @@ endif
|
||||
@echo $(DL) libssh2_channel_wait_closed,$(DL) >> $@
|
||||
@echo $(DL) libssh2_channel_wait_eof,$(DL) >> $@
|
||||
@echo $(DL) libssh2_channel_write_ex,$(DL) >> $@
|
||||
@echo $(DL) libssh2_exit,$(DL) >> $@
|
||||
@echo $(DL) libssh2_hostkey_hash,$(DL) >> $@
|
||||
@echo $(DL) libssh2_scp_recv,$(DL) >> $@
|
||||
@echo $(DL) libssh2_scp_send64,$(DL) >> $@
|
||||
@echo $(DL) libssh2_scp_send_ex,$(DL) >> $@
|
||||
@echo $(DL) libssh2_init,$(DL) >> $@
|
||||
@echo $(DL) libssh2_knownhost_add,$(DL) >> $@
|
||||
@echo $(DL) libssh2_knownhost_check,$(DL) >> $@
|
||||
@echo $(DL) libssh2_knownhost_checkp,$(DL) >> $@
|
||||
@echo $(DL) libssh2_knownhost_free,$(DL) >> $@
|
||||
@echo $(DL) libssh2_knownhost_init,$(DL) >> $@
|
||||
@echo $(DL) libssh2_knownhost_readfile,$(DL) >> $@
|
||||
@echo $(DL) libssh2_knownhost_writefile,$(DL) >> $@
|
||||
@echo $(DL) libssh2_scp_recv,$(DL) >> $@
|
||||
@echo $(DL) libssh2_scp_send64,$(DL) >> $@
|
||||
@echo $(DL) libssh2_scp_send_ex,$(DL) >> $@
|
||||
@echo $(DL) libssh2_session_abstract,$(DL) >> $@
|
||||
@echo $(DL) libssh2_session_block_directions,$(DL) >> $@
|
||||
@echo $(DL) libssh2_session_callback_set,$(DL) >> $@
|
||||
@echo $(DL) libssh2_session_disconnect_ex,$(DL) >> $@
|
||||
@echo $(DL) libssh2_session_free,$(DL) >> $@
|
||||
@echo $(DL) libssh2_session_handshake,$(DL) >> $@
|
||||
@echo $(DL) libssh2_session_hostkey,$(DL) >> $@
|
||||
@echo $(DL) libssh2_session_init_ex,$(DL) >> $@
|
||||
@echo $(DL) libssh2_session_last_errno,$(DL) >> $@
|
||||
@@ -552,9 +584,10 @@ endif
|
||||
@echo $(DL) libssh2_userauth_keyboard_interactive_ex,$(DL) >> $@
|
||||
@echo $(DL) libssh2_userauth_list,$(DL) >> $@
|
||||
@echo $(DL) libssh2_userauth_password_ex,$(DL) >> $@
|
||||
@echo $(DL) libssh2_userauth_publickey_fromfile_ex$(DL) >> $@
|
||||
@echo $(DL) libssh2_userauth_publickey_fromfile_ex,$(DL) >> $@
|
||||
@echo $(DL) libssh2_version$(DL) >> $@
|
||||
|
||||
$(DISTDIR)/readme.txt: Makefile.netware
|
||||
$(DISTDIR)/readme.txt: GNUmakefile
|
||||
@echo Creating $@
|
||||
@echo $(DL)This is a binary distribution for NetWare platform.$(DL) > $@
|
||||
@echo $(DL)libssh2 version $(LIBSSH2_VERSION_STR)$(DL) >> $@
|
||||
@@ -562,7 +595,7 @@ $(DISTDIR)/readme.txt: Makefile.netware
|
||||
@echo $(DL)any further documentation:$(DL) >> $@
|
||||
@echo $(DL)$(WWWURL)$(DL) >> $@
|
||||
|
||||
$(DEVLDIR)/readme.txt: Makefile.netware
|
||||
$(DEVLDIR)/readme.txt: GNUmakefile
|
||||
@echo Creating $@
|
||||
@echo $(DL)This is a development distribution for NetWare platform.$(DL) > $@
|
||||
@echo $(DL)libssh2 version $(LIBSSH2_VERSION_STR)$(DL) >> $@
|
@@ -1,2 +0,0 @@
|
||||
include Makefile.netware
|
||||
|
@@ -1,7 +1,6 @@
|
||||
#########################################################################
|
||||
#
|
||||
## Makefile for building libssh2 (NetWare version - gnu make)
|
||||
## Use: make -f Makefile.netware
|
||||
##
|
||||
## Hacked by: Guenter Knauf
|
||||
#
|
||||
@@ -14,12 +13,12 @@ endif
|
||||
|
||||
# Edit the path below to point to the base of your Zlib sources.
|
||||
ifndef ZLIB_PATH
|
||||
ZLIB_PATH = ../../../zlib-1.2.5
|
||||
ZLIB_PATH = ../../../zlib-1.2.8
|
||||
endif
|
||||
|
||||
# Edit the path below to point to the base of your OpenSSL package.
|
||||
ifndef OPENSSL_PATH
|
||||
OPENSSL_PATH = ../../../openssl-0.9.8r
|
||||
OPENSSL_PATH = ../../../openssl-0.9.8zc
|
||||
endif
|
||||
|
||||
# Edit the var below to enable static linking of libssh2 and libz
|
||||
@@ -70,10 +69,7 @@ ifdef METROWERKS
|
||||
else
|
||||
CC = $(CROSSPREFIX)gcc
|
||||
endif
|
||||
CP = cp -afv
|
||||
MD = mkdir
|
||||
RD = rm -fr
|
||||
# RM = rm -f
|
||||
|
||||
# Here you can find a native Win32 binary of the original awk:
|
||||
# http://www.gknw.net/development/prgtools/awk-20100523.zip
|
||||
AWK = awk
|
||||
@@ -82,6 +78,34 @@ AWK = awk
|
||||
# http://www.gknw.net/development/prgtools/mkxdc.zip
|
||||
MPKXDC = mkxdc
|
||||
|
||||
# Platform-dependent helper tool macros
|
||||
ifeq ($(findstring /sh,$(SHELL)),/sh)
|
||||
DEL = rm -f $1
|
||||
RMDIR = rm -fr $1
|
||||
MKDIR = mkdir -p $1
|
||||
COPY = -cp -afv $1 $2
|
||||
#COPYR = -cp -afr $1/* $2
|
||||
COPYR = -rsync -aC $1/* $2
|
||||
TOUCH = touch $1
|
||||
CAT = cat
|
||||
ECHONL = echo ""
|
||||
DL = '
|
||||
else
|
||||
ifeq "$(OS)" "Windows_NT"
|
||||
DEL = -del 2>NUL /q /f $(subst /,\,$1)
|
||||
RMDIR = -rd 2>NUL /q /s $(subst /,\,$1)
|
||||
else
|
||||
DEL = -del 2>NUL $(subst /,\,$1)
|
||||
RMDIR = -deltree 2>NUL /y $(subst /,\,$1)
|
||||
endif
|
||||
MKDIR = -md 2>NUL $(subst /,\,$1)
|
||||
COPY = -copy 2>NUL /y $(subst /,\,$1) $(subst /,\,$2)
|
||||
COPYR = -xcopy 2>NUL /q /y /e $(subst /,\,$1) $(subst /,\,$2)
|
||||
TOUCH = copy 2>&1>NUL /b $(subst /,\,$1) +,,
|
||||
CAT = type
|
||||
ECHONL = $(ComSpec) /c echo.
|
||||
endif
|
||||
|
||||
# LIBARCH_U = $(shell $(AWK) 'BEGIN {print toupper(ARGV[1])}' $(LIBARCH))
|
||||
LIBARCH_L = $(shell $(AWK) 'BEGIN {print tolower(ARGV[1])}' $(LIBARCH))
|
||||
|
||||
@@ -112,12 +136,13 @@ else
|
||||
endif
|
||||
else
|
||||
LD = nlmconv
|
||||
LDFLAGS = -T
|
||||
LDFLAGS = -UT
|
||||
AR = ar
|
||||
ARFLAGS = -cq
|
||||
LIBEXT = a
|
||||
CFLAGS += -m32
|
||||
CFLAGS += -fno-builtin -fpcc-struct-return -fno-strict-aliasing
|
||||
CFLAGS += -fno-builtin -fpcc-struct-return
|
||||
CFLAGS += -fno-strict-aliasing
|
||||
CFLAGS += -Wall # -pedantic
|
||||
ifeq ($(LIBARCH),LIBC)
|
||||
PRELUDE = $(SDK_LIBC)/imports/libcpre.gcc.o
|
||||
@@ -181,13 +206,6 @@ ifeq ($(MTSAFE),NO)
|
||||
XDCOPT = -u
|
||||
endif
|
||||
|
||||
ifeq ($(findstring /sh,$(SHELL)),/sh)
|
||||
DL = '
|
||||
DS = /
|
||||
else
|
||||
DS = \\
|
||||
endif
|
||||
|
||||
vpath %.c $(SAMPLES)
|
||||
|
||||
.PRECIOUS: $(OBJDIR)/%.o $(OBJDIR)/%.def $(OBJDIR)/%.xdc
|
||||
@@ -201,29 +219,29 @@ $(OBJDIR)/%.o: %.c
|
||||
# @echo Compiling $<
|
||||
$(CC) $(CFLAGS) -c $< -o $@
|
||||
|
||||
$(OBJDIR)/version.inc: ../../include/libssh2.h $(OBJDIR)
|
||||
$(OBJDIR)/version.inc: ../../get_ver.awk ../../include/libssh2.h $(OBJDIR)
|
||||
@echo Creating $@
|
||||
@$(AWK) -f ../../get_ver.awk $< > $@
|
||||
@$(AWK) -f $^ > $@
|
||||
|
||||
objclean:
|
||||
-$(RD) $(OBJDIR)
|
||||
$(call RMDIR, $(OBJDIR))
|
||||
|
||||
clean: objclean
|
||||
-$(RM) $(TARGETS)
|
||||
$(foreach f, $(TARGETS), $(call DEL, $(f)))
|
||||
|
||||
$(OBJDIR):
|
||||
@$(MD) $@
|
||||
@$(call MKDIR, $@)
|
||||
|
||||
%.nlm: $(OBJDIR)/%.def $(OBJDIR)/%.o $(OBJDIR)/%.xdc
|
||||
@echo Linking $@
|
||||
@-$(RM) $@
|
||||
@$(call DEL, $@)
|
||||
@$(LD) $(LDFLAGS) $<
|
||||
|
||||
$(OBJDIR)/%.xdc: Makefile.netware
|
||||
$(OBJDIR)/%.xdc: GNUmakefile
|
||||
@echo Creating $@
|
||||
@$(MPKXDC) $(XDCOPT) $@
|
||||
|
||||
$(OBJDIR)/%.def: Makefile.netware
|
||||
$(OBJDIR)/%.def: GNUmakefile
|
||||
@echo $(DL)# DEF file for linking with $(LD)$(DL) > $@
|
||||
@echo $(DL)# Do not edit this file - it is created by make!$(DL) >> $@
|
||||
@echo $(DL)# All your changes will be lost!!$(DL) >> $@
|
@@ -1,6 +1,17 @@
|
||||
# $Id: Makefile.am,v 1.21 2009/05/07 17:21:56 bagder Exp $
|
||||
AUTOMAKE_OPTIONS = foreign nostdinc
|
||||
|
||||
# Get the CRYPTO_CSOURCES and CRYPTO_HHEADERS defines
|
||||
if OPENSSL
|
||||
include ../Makefile.OpenSSL.inc
|
||||
endif
|
||||
if LIBGCRYPT
|
||||
include ../Makefile.libgcrypt.inc
|
||||
endif
|
||||
if WINCNG
|
||||
include ../Makefile.WinCNG.inc
|
||||
endif
|
||||
|
||||
# Makefile.inc provides the CSOURCES and HHEADERS defines
|
||||
include ../Makefile.inc
|
||||
|
||||
|
@@ -1,33 +1,30 @@
|
||||
!include "win32/config.mk"
|
||||
|
||||
!include "win32/objects.mk"
|
||||
|
||||
CFLAGS=$(CFLAGS)
|
||||
|
||||
OBJECTS = \
|
||||
$(INTDIR)\channel.obj \
|
||||
$(INTDIR)\comp.obj \
|
||||
$(INTDIR)\crypt.obj \
|
||||
$(INTDIR)\global.obj \
|
||||
$(INTDIR)\hostkey.obj \
|
||||
$(INTDIR)\keepalive.obj \
|
||||
$(INTDIR)\kex.obj \
|
||||
$(INTDIR)\mac.obj \
|
||||
$(INTDIR)\misc.obj \
|
||||
$(INTDIR)\openssl.obj \
|
||||
$(INTDIR)\packet.obj \
|
||||
$(INTDIR)\pem.obj \
|
||||
$(INTDIR)\publickey.obj \
|
||||
$(INTDIR)\scp.obj \
|
||||
$(INTDIR)\session.obj \
|
||||
$(INTDIR)\sftp.obj \
|
||||
$(INTDIR)\transport.obj \
|
||||
$(INTDIR)\userauth.obj
|
||||
AR = lib
|
||||
ARFLAGS = -nologo /LTCG
|
||||
|
||||
RESOURCE=$(INTDIR)\libssh2.res
|
||||
DLL=libssh2$(SUFFIX).dll
|
||||
STATICLIB=$(INTDIR)\libssh2.lib
|
||||
|
||||
$(DLL): $(OBJECTS)
|
||||
$(CC) -o $(DLL) $(DLLFLAGS) $(OBJECTS) $(LIBS)
|
||||
|
||||
!if "$(BUILD_STATIC_LIB)" == ""
|
||||
all: $(DLL)
|
||||
!else
|
||||
all: $(STATICLIB)
|
||||
!endif
|
||||
|
||||
$(DLL): $(OBJECTS) $(RESOURCE)
|
||||
$(CC) -o $(DLL) $(DLLFLAGS) $(OBJECTS) $(RESOURCE) $(LIBS)
|
||||
|
||||
$(STATICLIB): $(OBJECTS)
|
||||
$(AR) $(ARFLAGS) -out:$@ $(OBJECTS)
|
||||
|
||||
$(RESOURCE): win32\libssh2.rc
|
||||
$(RC) $(RCFLAGS) /Fo"$@" $?
|
||||
|
||||
!include "win32/rules.mk"
|
||||
|
||||
|
37
src/agent.c
37
src/agent.c
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* Copyright (c) 2009 by Daiki Ueno
|
||||
* Copyright (C) 2010 by Daniel Stenberg
|
||||
* Copyright (C) 2010-2014 by Daniel Stenberg
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms,
|
||||
@@ -159,6 +159,8 @@ agent_connect_unix(LIBSSH2_AGENT *agent)
|
||||
|
||||
s_un.sun_family = AF_UNIX;
|
||||
strncpy (s_un.sun_path, path, sizeof s_un.sun_path);
|
||||
s_un.sun_path[sizeof(s_un.sun_path)-1]=0; /* make sure there's a trailing
|
||||
zero */
|
||||
if (connect(agent->fd, (struct sockaddr*)(&s_un), sizeof s_un) != 0) {
|
||||
close (agent->fd);
|
||||
return _libssh2_error(agent->session, LIBSSH2_ERROR_AGENT_PROTOCOL,
|
||||
@@ -303,6 +305,12 @@ agent_transact_pageant(LIBSSH2_AGENT *agent, agent_transaction_ctx_t transctx)
|
||||
"failed setting up pageant filemap");
|
||||
|
||||
p2 = p = MapViewOfFile(filemap, FILE_MAP_WRITE, 0, 0, 0);
|
||||
if (p == NULL || p2 == NULL) {
|
||||
CloseHandle(filemap);
|
||||
return _libssh2_error(agent->session, LIBSSH2_ERROR_AGENT_PROTOCOL,
|
||||
"failed to open pageant filemap for writing");
|
||||
}
|
||||
|
||||
_libssh2_store_str(&p2, (const char *)transctx->request,
|
||||
transctx->request_len);
|
||||
|
||||
@@ -537,18 +545,17 @@ agent_list_identities(LIBSSH2_AGENT *agent)
|
||||
struct agent_publickey *identity;
|
||||
ssize_t comment_len;
|
||||
|
||||
identity = LIBSSH2_ALLOC(agent->session, sizeof *identity);
|
||||
if (!identity) {
|
||||
rc = LIBSSH2_ERROR_ALLOC;
|
||||
goto error;
|
||||
}
|
||||
|
||||
/* Read the length of the blob */
|
||||
len -= 4;
|
||||
if (len < 0) {
|
||||
rc = LIBSSH2_ERROR_AGENT_PROTOCOL;
|
||||
goto error;
|
||||
}
|
||||
identity = LIBSSH2_ALLOC(agent->session, sizeof *identity);
|
||||
if (!identity) {
|
||||
rc = LIBSSH2_ERROR_ALLOC;
|
||||
goto error;
|
||||
}
|
||||
identity->external.blob_len = _libssh2_ntohu32(s);
|
||||
s += 4;
|
||||
|
||||
@@ -556,12 +563,15 @@ agent_list_identities(LIBSSH2_AGENT *agent)
|
||||
len -= identity->external.blob_len;
|
||||
if (len < 0) {
|
||||
rc = LIBSSH2_ERROR_AGENT_PROTOCOL;
|
||||
LIBSSH2_FREE(agent->session, identity);
|
||||
goto error;
|
||||
}
|
||||
|
||||
identity->external.blob = LIBSSH2_ALLOC(agent->session,
|
||||
identity->external.blob_len);
|
||||
if (!identity->external.blob) {
|
||||
rc = LIBSSH2_ERROR_ALLOC;
|
||||
LIBSSH2_FREE(agent->session, identity);
|
||||
goto error;
|
||||
}
|
||||
memcpy(identity->external.blob, s, identity->external.blob_len);
|
||||
@@ -571,6 +581,8 @@ agent_list_identities(LIBSSH2_AGENT *agent)
|
||||
len -= 4;
|
||||
if (len < 0) {
|
||||
rc = LIBSSH2_ERROR_AGENT_PROTOCOL;
|
||||
LIBSSH2_FREE(agent->session, identity->external.blob);
|
||||
LIBSSH2_FREE(agent->session, identity);
|
||||
goto error;
|
||||
}
|
||||
comment_len = _libssh2_ntohu32(s);
|
||||
@@ -580,12 +592,17 @@ agent_list_identities(LIBSSH2_AGENT *agent)
|
||||
len -= comment_len;
|
||||
if (len < 0) {
|
||||
rc = LIBSSH2_ERROR_AGENT_PROTOCOL;
|
||||
LIBSSH2_FREE(agent->session, identity->external.blob);
|
||||
LIBSSH2_FREE(agent->session, identity);
|
||||
goto error;
|
||||
}
|
||||
|
||||
identity->external.comment = LIBSSH2_ALLOC(agent->session,
|
||||
comment_len + 1);
|
||||
if (!identity->external.comment) {
|
||||
rc = LIBSSH2_ERROR_ALLOC;
|
||||
LIBSSH2_FREE(agent->session, identity->external.blob);
|
||||
LIBSSH2_FREE(agent->session, identity);
|
||||
goto error;
|
||||
}
|
||||
identity->external.comment[comment_len] = '\0';
|
||||
@@ -645,13 +662,13 @@ libssh2_agent_init(LIBSSH2_SESSION *session)
|
||||
{
|
||||
LIBSSH2_AGENT *agent;
|
||||
|
||||
agent = LIBSSH2_ALLOC(session, sizeof *agent);
|
||||
agent = LIBSSH2_CALLOC(session, sizeof *agent);
|
||||
if (!agent) {
|
||||
_libssh2_error(session, LIBSSH2_ERROR_ALLOC,
|
||||
"Unable to allocate space for agent connection");
|
||||
return NULL;
|
||||
}
|
||||
memset(agent, 0, sizeof *agent);
|
||||
agent->fd = LIBSSH2_INVALID_SOCKET;
|
||||
agent->session = session;
|
||||
_libssh2_list_init(&agent->head);
|
||||
|
||||
@@ -698,7 +715,7 @@ libssh2_agent_list_identities(LIBSSH2_AGENT *agent)
|
||||
* libssh2_agent_get_identity()
|
||||
*
|
||||
* Traverse the internal list of public keys. Pass NULL to 'prev' to get
|
||||
* the first one. Or pass a poiner to the previously returned one to get the
|
||||
* the first one. Or pass a pointer to the previously returned one to get the
|
||||
* next.
|
||||
*
|
||||
* Returns:
|
||||
|
154
src/channel.c
154
src/channel.c
@@ -1,6 +1,6 @@
|
||||
/* Copyright (c) 2004-2007 Sara Golemon <sarag@libssh2.org>
|
||||
* Copyright (c) 2005 Mikhail Gusarov <dottedmag@dottedmag.net>
|
||||
* Copyright (c) 2008-2011 by Daniel Stenberg
|
||||
* Copyright (c) 2008-2014 by Daniel Stenberg
|
||||
*
|
||||
* All rights reserved.
|
||||
*
|
||||
@@ -158,14 +158,12 @@ _libssh2_channel_open(LIBSSH2_SESSION * session, const char *channel_type,
|
||||
"Opening Channel - win %d pack %d", window_size,
|
||||
packet_size);
|
||||
session->open_channel =
|
||||
LIBSSH2_ALLOC(session, sizeof(LIBSSH2_CHANNEL));
|
||||
LIBSSH2_CALLOC(session, sizeof(LIBSSH2_CHANNEL));
|
||||
if (!session->open_channel) {
|
||||
_libssh2_error(session, LIBSSH2_ERROR_ALLOC,
|
||||
"Unable to allocate space for channel data");
|
||||
return NULL;
|
||||
}
|
||||
memset(session->open_channel, 0, sizeof(LIBSSH2_CHANNEL));
|
||||
|
||||
session->open_channel->channel_type_len = channel_type_len;
|
||||
session->open_channel->channel_type =
|
||||
LIBSSH2_ALLOC(session, channel_type_len);
|
||||
@@ -451,7 +449,7 @@ channel_forward_listen(LIBSSH2_SESSION * session, const char *host,
|
||||
LIBSSH2_ALLOC(session, session->fwdLstn_packet_len);
|
||||
if (!session->fwdLstn_packet) {
|
||||
_libssh2_error(session, LIBSSH2_ERROR_ALLOC,
|
||||
"Unable to allocate memeory for setenv packet");
|
||||
"Unable to allocate memory for setenv packet");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@@ -509,12 +507,11 @@ channel_forward_listen(LIBSSH2_SESSION * session, const char *host,
|
||||
if (data[0] == SSH_MSG_REQUEST_SUCCESS) {
|
||||
LIBSSH2_LISTENER *listener;
|
||||
|
||||
listener = LIBSSH2_ALLOC(session, sizeof(LIBSSH2_LISTENER));
|
||||
listener = LIBSSH2_CALLOC(session, sizeof(LIBSSH2_LISTENER));
|
||||
if (!listener)
|
||||
_libssh2_error(session, LIBSSH2_ERROR_ALLOC,
|
||||
"Unable to allocate memory for listener queue");
|
||||
else {
|
||||
memset(listener, 0, sizeof(LIBSSH2_LISTENER));
|
||||
listener->host =
|
||||
LIBSSH2_ALLOC(session, session->fwdLstn_host_len + 1);
|
||||
if (!listener->host) {
|
||||
@@ -525,8 +522,7 @@ channel_forward_listen(LIBSSH2_SESSION * session, const char *host,
|
||||
}
|
||||
else {
|
||||
listener->session = session;
|
||||
memcpy(listener->host, host ? host : "0.0.0.0",
|
||||
session->fwdLstn_host_len);
|
||||
memcpy(listener->host, host, session->fwdLstn_host_len);
|
||||
listener->host[session->fwdLstn_host_len] = 0;
|
||||
if (data_len >= 5 && !port) {
|
||||
listener->port = _libssh2_ntohu32(data + 1);
|
||||
@@ -606,6 +602,7 @@ int _libssh2_channel_forward_cancel(LIBSSH2_LISTENER *listener)
|
||||
size_t packet_len =
|
||||
host_len + 14 + sizeof("cancel-tcpip-forward") - 1;
|
||||
int rc;
|
||||
int retcode = 0;
|
||||
|
||||
if (listener->chanFwdCncl_state == libssh2_NB_state_idle) {
|
||||
_libssh2_debug(session, LIBSSH2_TRACE_CONN,
|
||||
@@ -615,7 +612,7 @@ int _libssh2_channel_forward_cancel(LIBSSH2_LISTENER *listener)
|
||||
s = packet = LIBSSH2_ALLOC(session, packet_len);
|
||||
if (!packet) {
|
||||
_libssh2_error(session, LIBSSH2_ERROR_ALLOC,
|
||||
"Unable to allocate memeory for setenv packet");
|
||||
"Unable to allocate memory for setenv packet");
|
||||
return LIBSSH2_ERROR_ALLOC;
|
||||
}
|
||||
|
||||
@@ -644,9 +641,11 @@ int _libssh2_channel_forward_cancel(LIBSSH2_LISTENER *listener)
|
||||
_libssh2_error(session, LIBSSH2_ERROR_SOCKET_SEND,
|
||||
"Unable to send global-request packet for forward "
|
||||
"listen request");
|
||||
LIBSSH2_FREE(session, packet);
|
||||
listener->chanFwdCncl_state = libssh2_NB_state_idle;
|
||||
return LIBSSH2_ERROR_SOCKET_SEND;
|
||||
/* set the state to something we don't check for, for the
|
||||
unfortunate situation where we get an EAGAIN further down
|
||||
when trying to bail out due to errors! */
|
||||
listener->chanFwdCncl_state = libssh2_NB_state_sent;
|
||||
retcode = LIBSSH2_ERROR_SOCKET_SEND;
|
||||
}
|
||||
LIBSSH2_FREE(session, packet);
|
||||
|
||||
@@ -670,9 +669,7 @@ int _libssh2_channel_forward_cancel(LIBSSH2_LISTENER *listener)
|
||||
|
||||
LIBSSH2_FREE(session, listener);
|
||||
|
||||
listener->chanFwdCncl_state = libssh2_NB_state_idle;
|
||||
|
||||
return 0;
|
||||
return retcode;
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -787,7 +784,7 @@ static int channel_setenv(LIBSSH2_CHANNEL *channel,
|
||||
LIBSSH2_ALLOC(session, channel->setenv_packet_len);
|
||||
if (!channel->setenv_packet) {
|
||||
return _libssh2_error(session, LIBSSH2_ERROR_ALLOC,
|
||||
"Unable to allocate memeory "
|
||||
"Unable to allocate memory "
|
||||
"for setenv packet");
|
||||
}
|
||||
|
||||
@@ -1413,6 +1410,9 @@ _libssh2_channel_flush(LIBSSH2_CHANNEL *channel, int streamid)
|
||||
channel->flush_state = libssh2_NB_state_created;
|
||||
}
|
||||
|
||||
channel->read_avail -= channel->flush_flush_bytes;
|
||||
channel->remote.window_size -= channel->flush_flush_bytes;
|
||||
|
||||
if (channel->flush_refund_bytes) {
|
||||
int rc;
|
||||
|
||||
@@ -1483,10 +1483,11 @@ libssh2_channel_get_exit_signal(LIBSSH2_CHANNEL *channel,
|
||||
char **langtag,
|
||||
size_t *langtag_len)
|
||||
{
|
||||
LIBSSH2_SESSION *session = channel->session;
|
||||
size_t namelen = 0;
|
||||
|
||||
if (channel) {
|
||||
LIBSSH2_SESSION *session = channel->session;
|
||||
|
||||
if (channel->exit_signal) {
|
||||
namelen = strlen(channel->exit_signal);
|
||||
if (exitsignal) {
|
||||
@@ -1542,6 +1543,9 @@ _libssh2_channel_receive_window_adjust(LIBSSH2_CHANNEL * channel,
|
||||
{
|
||||
int rc;
|
||||
|
||||
if(store)
|
||||
*store = channel->remote.window_size;
|
||||
|
||||
if (channel->adjust_state == libssh2_NB_state_idle) {
|
||||
if (!force
|
||||
&& (adjustment + channel->adjust_queue <
|
||||
@@ -1551,14 +1555,10 @@ _libssh2_channel_receive_window_adjust(LIBSSH2_CHANNEL * channel,
|
||||
"for channel %lu/%lu",
|
||||
adjustment, channel->local.id, channel->remote.id);
|
||||
channel->adjust_queue += adjustment;
|
||||
if(store)
|
||||
*store = channel->remote.window_size;
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (!adjustment && !channel->adjust_queue) {
|
||||
if(store)
|
||||
*store = channel->remote.window_size;
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -1596,8 +1596,6 @@ _libssh2_channel_receive_window_adjust(LIBSSH2_CHANNEL * channel,
|
||||
|
||||
channel->adjust_state = libssh2_NB_state_idle;
|
||||
|
||||
if(store)
|
||||
*store = channel->remote.window_size;
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -1623,7 +1621,7 @@ libssh2_channel_receive_window_adjust(LIBSSH2_CHANNEL *channel,
|
||||
int rc;
|
||||
|
||||
if(!channel)
|
||||
return LIBSSH2_ERROR_BAD_USE;
|
||||
return (unsigned long)LIBSSH2_ERROR_BAD_USE;
|
||||
|
||||
BLOCK_ADJUST(rc, channel->session,
|
||||
_libssh2_channel_receive_window_adjust(channel, adj,
|
||||
@@ -1670,7 +1668,7 @@ _libssh2_channel_extended_data(LIBSSH2_CHANNEL *channel, int ignore_mode)
|
||||
"Setting channel %lu/%lu handle_extended_data"
|
||||
" mode to %d",
|
||||
channel->local.id, channel->remote.id, ignore_mode);
|
||||
channel->remote.extended_data_ignore_mode = ignore_mode;
|
||||
channel->remote.extended_data_ignore_mode = (char)ignore_mode;
|
||||
|
||||
channel->extData2_state = libssh2_NB_state_created;
|
||||
}
|
||||
@@ -1749,22 +1747,36 @@ ssize_t _libssh2_channel_read(LIBSSH2_CHANNEL *channel, int stream_id,
|
||||
LIBSSH2_PACKET *read_packet;
|
||||
LIBSSH2_PACKET *read_next;
|
||||
|
||||
if (channel->read_state == libssh2_NB_state_idle) {
|
||||
_libssh2_debug(session, LIBSSH2_TRACE_CONN,
|
||||
"channel_read() wants %d bytes from channel %lu/%lu "
|
||||
"stream #%d",
|
||||
(int) buflen, channel->local.id, channel->remote.id,
|
||||
stream_id);
|
||||
channel->read_state = libssh2_NB_state_created;
|
||||
_libssh2_debug(session, LIBSSH2_TRACE_CONN,
|
||||
"channel_read() wants %d bytes from channel %lu/%lu "
|
||||
"stream #%d",
|
||||
(int) buflen, channel->local.id, channel->remote.id,
|
||||
stream_id);
|
||||
|
||||
/* expand the receiving window first if it has become too narrow */
|
||||
if( (channel->read_state == libssh2_NB_state_jump1) ||
|
||||
(channel->remote.window_size < channel->remote.window_size_initial / 4 * 3 + buflen) ) {
|
||||
|
||||
uint32_t adjustment = channel->remote.window_size_initial + buflen - channel->remote.window_size;
|
||||
if (adjustment < LIBSSH2_CHANNEL_MINADJUST)
|
||||
adjustment = LIBSSH2_CHANNEL_MINADJUST;
|
||||
|
||||
/* the actual window adjusting may not finish so we need to deal with
|
||||
this special state here */
|
||||
channel->read_state = libssh2_NB_state_jump1;
|
||||
rc = _libssh2_channel_receive_window_adjust(channel, adjustment,
|
||||
0, NULL);
|
||||
if (rc)
|
||||
return rc;
|
||||
|
||||
channel->read_state = libssh2_NB_state_idle;
|
||||
}
|
||||
|
||||
rc = 1; /* set to >0 to let the while loop start */
|
||||
|
||||
/* Process all pending incoming packets in all states in order to "even
|
||||
out" the network readings. Tests prove that this way produces faster
|
||||
transfers. */
|
||||
while (rc > 0)
|
||||
/* Process all pending incoming packets. Tests prove that this way
|
||||
produces faster transfers. */
|
||||
do {
|
||||
rc = _libssh2_transport_read(session);
|
||||
} while (rc > 0);
|
||||
|
||||
if ((rc < 0) && (rc != LIBSSH2_ERROR_EAGAIN))
|
||||
return _libssh2_error(session, rc, "transport read");
|
||||
@@ -1846,8 +1858,6 @@ ssize_t _libssh2_channel_read(LIBSSH2_CHANNEL *channel, int stream_id,
|
||||
}
|
||||
|
||||
if (!bytes_read) {
|
||||
channel->read_state = libssh2_NB_state_idle;
|
||||
|
||||
/* If the channel is already at EOF or even closed, we need to signal
|
||||
that back. We may have gotten that info while draining the incoming
|
||||
transport layer until EAGAIN so we must not be fooled by that
|
||||
@@ -1860,11 +1870,9 @@ ssize_t _libssh2_channel_read(LIBSSH2_CHANNEL *channel, int stream_id,
|
||||
/* if the transport layer said EAGAIN then we say so as well */
|
||||
return _libssh2_error(session, rc, "would block");
|
||||
}
|
||||
else
|
||||
/* make sure we remain in the created state to focus on emptying the
|
||||
data we already have in the packet brigade before we try to read
|
||||
more off the network again */
|
||||
channel->read_state = libssh2_NB_state_created;
|
||||
|
||||
channel->read_avail -= bytes_read;
|
||||
channel->remote.window_size -= bytes_read;
|
||||
|
||||
return bytes_read;
|
||||
}
|
||||
@@ -2008,12 +2016,22 @@ _libssh2_channel_write(LIBSSH2_CHANNEL *channel, int stream_id,
|
||||
rc = _libssh2_transport_read(session);
|
||||
while (rc > 0);
|
||||
|
||||
if((rc < 0) && (rc != LIBSSH2_ERROR_EAGAIN))
|
||||
return rc;
|
||||
if((rc < 0) && (rc != LIBSSH2_ERROR_EAGAIN)) {
|
||||
return _libssh2_error(channel->session, rc,
|
||||
"Failure while draining incoming flow");
|
||||
}
|
||||
|
||||
if(channel->local.window_size <= 0)
|
||||
if(channel->local.window_size <= 0) {
|
||||
/* there's no room for data so we stop */
|
||||
|
||||
/* Waiting on the socket to be writable would be wrong because we
|
||||
* would be back here immediately, but a readable socket might
|
||||
* herald an incoming window adjustment.
|
||||
*/
|
||||
session->socket_block_directions = LIBSSH2_SESSION_BLOCK_INBOUND;
|
||||
|
||||
return (rc==LIBSSH2_ERROR_EAGAIN?rc:0);
|
||||
}
|
||||
|
||||
channel->write_bufwrite = buflen;
|
||||
|
||||
@@ -2250,7 +2268,6 @@ int _libssh2_channel_close(LIBSSH2_CHANNEL * channel)
|
||||
{
|
||||
LIBSSH2_SESSION *session = channel->session;
|
||||
int rc = 0;
|
||||
int retcode;
|
||||
|
||||
if (channel->local.close) {
|
||||
/* Already closed, act like we sent another close,
|
||||
@@ -2259,9 +2276,15 @@ int _libssh2_channel_close(LIBSSH2_CHANNEL * channel)
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (!channel->local.eof)
|
||||
if ((retcode = channel_send_eof(channel)))
|
||||
return retcode;
|
||||
if (!channel->local.eof) {
|
||||
if ((rc = channel_send_eof(channel))) {
|
||||
if (rc == LIBSSH2_ERROR_EAGAIN) {
|
||||
return rc;
|
||||
}
|
||||
_libssh2_error(session, rc,
|
||||
"Unable to send EOF, but closing channel anyway");
|
||||
}
|
||||
}
|
||||
|
||||
/* ignore if we have received a remote eof or not, as it is now too
|
||||
late for us to wait for it. Continue closing! */
|
||||
@@ -2277,19 +2300,22 @@ int _libssh2_channel_close(LIBSSH2_CHANNEL * channel)
|
||||
}
|
||||
|
||||
if (channel->close_state == libssh2_NB_state_created) {
|
||||
retcode = _libssh2_transport_send(session, channel->close_packet, 5,
|
||||
NULL, 0);
|
||||
if (retcode == LIBSSH2_ERROR_EAGAIN) {
|
||||
rc = _libssh2_transport_send(session, channel->close_packet, 5,
|
||||
NULL, 0);
|
||||
if (rc == LIBSSH2_ERROR_EAGAIN) {
|
||||
_libssh2_error(session, rc,
|
||||
"Would block sending close-channel");
|
||||
return retcode;
|
||||
} else if (retcode) {
|
||||
channel->close_state = libssh2_NB_state_idle;
|
||||
return _libssh2_error(session, retcode,
|
||||
"Unable to send close-channel request");
|
||||
}
|
||||
return rc;
|
||||
|
||||
channel->close_state = libssh2_NB_state_sent;
|
||||
} else if (rc) {
|
||||
_libssh2_error(session, rc,
|
||||
"Unable to send close-channel request, "
|
||||
"but closing anyway");
|
||||
/* skip waiting for the response and fall through to
|
||||
LIBSSH2_CHANNEL_CLOSE below */
|
||||
|
||||
} else
|
||||
channel->close_state = libssh2_NB_state_sent;
|
||||
}
|
||||
|
||||
if (channel->close_state == libssh2_NB_state_sent) {
|
||||
@@ -2549,7 +2575,7 @@ libssh2_channel_window_read_ex(LIBSSH2_CHANNEL *channel,
|
||||
* 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 window_size_initial (if
|
||||
* be safely written 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
|
||||
*/
|
||||
|
132
src/comp.c
132
src/comp.c
@@ -1,5 +1,5 @@
|
||||
/* Copyright (c) 2004-2007, Sara Golemon <sarag@libssh2.org>
|
||||
* Copyright (c) 2010, Daniel Stenberg <daniel@haxx.se>
|
||||
* Copyright (c) 2010-2014, Daniel Stenberg <daniel@haxx.se>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms,
|
||||
@@ -96,6 +96,7 @@ comp_method_none_decomp(LIBSSH2_SESSION * session,
|
||||
static const LIBSSH2_COMP_METHOD comp_method_none = {
|
||||
"none",
|
||||
0, /* not really compressing */
|
||||
0, /* isn't used in userauth, go figure */
|
||||
NULL,
|
||||
comp_method_none_comp,
|
||||
comp_method_none_decomp,
|
||||
@@ -140,13 +141,12 @@ comp_method_zlib_init(LIBSSH2_SESSION * session, int compr,
|
||||
z_stream *strm;
|
||||
int status;
|
||||
|
||||
strm = LIBSSH2_ALLOC(session, sizeof(z_stream));
|
||||
strm = LIBSSH2_CALLOC(session, sizeof(z_stream));
|
||||
if (!strm) {
|
||||
return _libssh2_error(session, LIBSSH2_ERROR_ALLOC,
|
||||
"Unable to allocate memory for "
|
||||
"zlib compression/decompression");
|
||||
}
|
||||
memset(strm, 0, sizeof(z_stream));
|
||||
|
||||
strm->opaque = (voidpf) session;
|
||||
strm->zalloc = (alloc_func) comp_method_zlib_alloc;
|
||||
@@ -197,15 +197,14 @@ comp_method_zlib_comp(LIBSSH2_SESSION *session,
|
||||
|
||||
status = deflate(strm, Z_PARTIAL_FLUSH);
|
||||
|
||||
if (status != Z_OK) {
|
||||
_libssh2_debug(session, LIBSSH2_TRACE_TRANS,
|
||||
"unhandled zlib compression error %d", status);
|
||||
return _libssh2_error(session, LIBSSH2_ERROR_ZLIB,
|
||||
"compression failure");
|
||||
if ((status == Z_OK) && (strm->avail_out > 0)) {
|
||||
*dest_len = out_maxlen - strm->avail_out;
|
||||
return 0;
|
||||
}
|
||||
|
||||
*dest_len = out_maxlen - strm->avail_out;
|
||||
return 0;
|
||||
_libssh2_debug(session, LIBSSH2_TRACE_TRANS,
|
||||
"unhandled zlib compression error %d, avail_out", status, strm->avail_out);
|
||||
return _libssh2_error(session, LIBSSH2_ERROR_ZLIB, "compression failure");
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -225,13 +224,12 @@ comp_method_zlib_decomp(LIBSSH2_SESSION * session,
|
||||
/* A short-term alloc of a full data chunk is better than a series of
|
||||
reallocs */
|
||||
char *out;
|
||||
int out_maxlen = 8 * src_len;
|
||||
int limiter = 0;
|
||||
int out_maxlen = 4 * src_len;
|
||||
|
||||
/* If strm is null, then we have not yet been initialized. */
|
||||
if (strm == NULL)
|
||||
return _libssh2_error(session, LIBSSH2_ERROR_COMPRESS,
|
||||
"decompression unitilized");;
|
||||
"decompression uninitialized");;
|
||||
|
||||
/* In practice they never come smaller than this */
|
||||
if (out_maxlen < 25)
|
||||
@@ -248,83 +246,49 @@ comp_method_zlib_decomp(LIBSSH2_SESSION * session,
|
||||
if (!strm->next_out)
|
||||
return _libssh2_error(session, LIBSSH2_ERROR_ALLOC,
|
||||
"Unable to allocate decompression buffer");
|
||||
while (strm->avail_in) {
|
||||
|
||||
/* Loop until it's all inflated or hit error */
|
||||
for (;;) {
|
||||
int status;
|
||||
size_t out_ofs;
|
||||
char *newout;
|
||||
|
||||
status = inflate(strm, Z_PARTIAL_FLUSH);
|
||||
|
||||
if (status != Z_OK) {
|
||||
if (status == Z_OK) {
|
||||
if (strm->avail_out > 0)
|
||||
/* status is OK and the output buffer has not been exhausted so we're done */
|
||||
break;
|
||||
} else if (status == Z_BUF_ERROR) {
|
||||
/* the input data has been exhausted so we are done */
|
||||
break;
|
||||
} else {
|
||||
/* error state */
|
||||
LIBSSH2_FREE(session, out);
|
||||
_libssh2_debug(session, LIBSSH2_TRACE_TRANS,
|
||||
"unhandled zlib error %d", status);
|
||||
return _libssh2_error(session, LIBSSH2_ERROR_ZLIB,
|
||||
"decompression failure");
|
||||
}
|
||||
if (strm->avail_in) {
|
||||
size_t out_ofs = out_maxlen - strm->avail_out;
|
||||
char *newout;
|
||||
|
||||
out_maxlen += 8 * strm->avail_in;
|
||||
if (out_maxlen >= (int) payload_limit) {
|
||||
LIBSSH2_FREE(session, out);
|
||||
return _libssh2_error(session, LIBSSH2_ERROR_ZLIB,
|
||||
"Excessive growth in decompression phase");
|
||||
}
|
||||
|
||||
if ((out_maxlen > (int) payload_limit) && limiter++) {
|
||||
LIBSSH2_FREE(session, out);
|
||||
return _libssh2_error(session, LIBSSH2_ERROR_ZLIB,
|
||||
"Excessive growth in decompression phase");
|
||||
}
|
||||
|
||||
newout = LIBSSH2_REALLOC(session, out, out_maxlen);
|
||||
if (!newout) {
|
||||
LIBSSH2_FREE(session, out);
|
||||
return _libssh2_error(session, LIBSSH2_ERROR_ALLOC,
|
||||
"Unable to expand decompression buffer");
|
||||
}
|
||||
out = newout;
|
||||
strm->next_out = (unsigned char *) out + out_ofs;
|
||||
strm->avail_out += 8 * strm->avail_in;
|
||||
} else
|
||||
while (!strm->avail_out) {
|
||||
/* Done with input, might be a byte or two in internal buffer
|
||||
* during compress. Or potentially many bytes if it's a
|
||||
* decompress
|
||||
*/
|
||||
int grow_size = 2048;
|
||||
char *newout;
|
||||
|
||||
if (out_maxlen >= (int) payload_limit) {
|
||||
LIBSSH2_FREE(session, out);
|
||||
return _libssh2_error(session, LIBSSH2_ERROR_ZLIB,
|
||||
"Excessive growth in decompression "
|
||||
"phase");
|
||||
}
|
||||
|
||||
if (grow_size > (int) (payload_limit - out_maxlen)) {
|
||||
grow_size = payload_limit - out_maxlen;
|
||||
}
|
||||
|
||||
out_maxlen += grow_size;
|
||||
strm->avail_out = grow_size;
|
||||
|
||||
newout = LIBSSH2_REALLOC(session, out, out_maxlen);
|
||||
if (!newout) {
|
||||
LIBSSH2_FREE(session, out);
|
||||
return _libssh2_error(session, LIBSSH2_ERROR_ALLOC,
|
||||
"Unable to expand final "
|
||||
"decompress buffer");
|
||||
}
|
||||
out = newout;
|
||||
strm->next_out = (unsigned char *) out + out_maxlen -
|
||||
grow_size;
|
||||
|
||||
status = inflate(strm, Z_PARTIAL_FLUSH);
|
||||
|
||||
if (status != Z_OK) {
|
||||
LIBSSH2_FREE(session, out);
|
||||
_libssh2_debug(session, LIBSSH2_TRACE_TRANS,
|
||||
"unhandled zlib error %d", status);
|
||||
return _libssh2_error(session, LIBSSH2_ERROR_ZLIB,
|
||||
"decompression failure");
|
||||
}
|
||||
}
|
||||
/* If we get here we need to grow the output buffer and try again */
|
||||
out_ofs = out_maxlen - strm->avail_out;
|
||||
out_maxlen *= 2;
|
||||
newout = LIBSSH2_REALLOC(session, out, out_maxlen);
|
||||
if (!newout) {
|
||||
LIBSSH2_FREE(session, out);
|
||||
return _libssh2_error(session, LIBSSH2_ERROR_ALLOC,
|
||||
"Unable to expand decompression buffer");
|
||||
}
|
||||
out = newout;
|
||||
strm->next_out = (unsigned char *) out + out_ofs;
|
||||
strm->avail_out = out_maxlen - out_ofs;
|
||||
}
|
||||
|
||||
*dest = (unsigned char *) out;
|
||||
@@ -357,6 +321,17 @@ comp_method_zlib_dtor(LIBSSH2_SESSION *session, int compr, void **abstract)
|
||||
static const LIBSSH2_COMP_METHOD comp_method_zlib = {
|
||||
"zlib",
|
||||
1, /* yes, this compresses */
|
||||
1, /* do compression during userauth */
|
||||
comp_method_zlib_init,
|
||||
comp_method_zlib_comp,
|
||||
comp_method_zlib_decomp,
|
||||
comp_method_zlib_dtor,
|
||||
};
|
||||
|
||||
static const LIBSSH2_COMP_METHOD comp_method_zlib_openssh = {
|
||||
"zlib@openssh.com",
|
||||
1, /* yes, this compresses */
|
||||
0, /* don't use compression during userauth */
|
||||
comp_method_zlib_init,
|
||||
comp_method_zlib_comp,
|
||||
comp_method_zlib_decomp,
|
||||
@@ -369,6 +344,7 @@ static const LIBSSH2_COMP_METHOD comp_method_zlib = {
|
||||
static const LIBSSH2_COMP_METHOD *comp_methods[] = {
|
||||
#ifdef LIBSSH2_HAVE_ZLIB
|
||||
&comp_method_zlib,
|
||||
&comp_method_zlib_openssh,
|
||||
#endif /* LIBSSH2_HAVE_ZLIB */
|
||||
&comp_method_none,
|
||||
NULL
|
||||
|
@@ -96,11 +96,12 @@ crypt_init(LIBSSH2_SESSION * session,
|
||||
|
||||
static int
|
||||
crypt_encrypt(LIBSSH2_SESSION * session, unsigned char *block,
|
||||
void **abstract)
|
||||
size_t blocksize, void **abstract)
|
||||
{
|
||||
struct crypt_ctx *cctx = *(struct crypt_ctx **) abstract;
|
||||
(void) session;
|
||||
return _libssh2_cipher_crypt(&cctx->h, cctx->algo, cctx->encrypt, block);
|
||||
return _libssh2_cipher_crypt(&cctx->h, cctx->algo, cctx->encrypt, block,
|
||||
blocksize);
|
||||
}
|
||||
|
||||
static int
|
||||
@@ -248,7 +249,8 @@ crypt_init_arcfour128(LIBSSH2_SESSION * session,
|
||||
unsigned char block[8];
|
||||
size_t discard = 1536;
|
||||
for (; discard; discard -= 8)
|
||||
_libssh2_cipher_crypt(&cctx->h, cctx->algo, cctx->encrypt, block);
|
||||
_libssh2_cipher_crypt(&cctx->h, cctx->algo, cctx->encrypt, block,
|
||||
method->blocksize);
|
||||
}
|
||||
|
||||
return rc;
|
||||
|
14
src/crypto.h
14
src/crypto.h
@@ -38,10 +38,16 @@
|
||||
#ifndef LIBSSH2_CRYPTO_H
|
||||
#define LIBSSH2_CRYPTO_H
|
||||
|
||||
#ifdef LIBSSH2_OPENSSL
|
||||
#include "openssl.h"
|
||||
#endif
|
||||
|
||||
#ifdef LIBSSH2_LIBGCRYPT
|
||||
#include "libgcrypt.h"
|
||||
#else
|
||||
#include "openssl.h"
|
||||
#endif
|
||||
|
||||
#ifdef LIBSSH2_WINCNG
|
||||
#include "wincng.h"
|
||||
#endif
|
||||
|
||||
int _libssh2_rsa_new(libssh2_rsa_ctx ** rsa,
|
||||
@@ -75,6 +81,7 @@ int _libssh2_rsa_sha1_sign(LIBSSH2_SESSION * session,
|
||||
unsigned char **signature,
|
||||
size_t *signature_len);
|
||||
|
||||
#if LIBSSH2_DSA
|
||||
int _libssh2_dsa_new(libssh2_dsa_ctx ** dsa,
|
||||
const unsigned char *pdata,
|
||||
unsigned long plen,
|
||||
@@ -95,6 +102,7 @@ int _libssh2_dsa_sha1_verify(libssh2_dsa_ctx * dsactx,
|
||||
int _libssh2_dsa_sha1_sign(libssh2_dsa_ctx * dsactx,
|
||||
const unsigned char *hash,
|
||||
unsigned long hash_len, unsigned char *sig);
|
||||
#endif
|
||||
|
||||
int _libssh2_cipher_init(_libssh2_cipher_ctx * h,
|
||||
_libssh2_cipher_type(algo),
|
||||
@@ -103,7 +111,7 @@ int _libssh2_cipher_init(_libssh2_cipher_ctx * h,
|
||||
|
||||
int _libssh2_cipher_crypt(_libssh2_cipher_ctx * ctx,
|
||||
_libssh2_cipher_type(algo),
|
||||
int encrypt, unsigned char *block);
|
||||
int encrypt, unsigned char *block, size_t blocksize);
|
||||
|
||||
int _libssh2_pub_priv_keyfile(LIBSSH2_SESSION *session,
|
||||
unsigned char **method,
|
||||
|
@@ -1,5 +1,5 @@
|
||||
/* Copyright (c) 2004-2006, Sara Golemon <sarag@libssh2.org>
|
||||
* Copyright (c) 2009 by Daniel Stenberg
|
||||
* Copyright (c) 2009-2014 by Daniel Stenberg
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms,
|
||||
@@ -347,13 +347,12 @@ hostkey_method_ssh_dss_signv(LIBSSH2_SESSION * session,
|
||||
libssh2_sha1_ctx ctx;
|
||||
int i;
|
||||
|
||||
*signature = LIBSSH2_ALLOC(session, 2 * SHA_DIGEST_LENGTH);
|
||||
*signature = LIBSSH2_CALLOC(session, 2 * SHA_DIGEST_LENGTH);
|
||||
if (!*signature) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
*signature_len = 2 * SHA_DIGEST_LENGTH;
|
||||
memset(*signature, 0, 2 * SHA_DIGEST_LENGTH);
|
||||
|
||||
libssh2_sha1_init(&ctx);
|
||||
for(i = 0; i < veccount; i++) {
|
||||
@@ -429,7 +428,9 @@ libssh2_hostkey_hash(LIBSSH2_SESSION * session, int hash_type)
|
||||
switch (hash_type) {
|
||||
#if LIBSSH2_MD5
|
||||
case LIBSSH2_HOSTKEY_HASH_MD5:
|
||||
return (char *) session->server_hostkey_md5;
|
||||
return (session->server_hostkey_md5_valid)
|
||||
? (char *) session->server_hostkey_md5
|
||||
: NULL;
|
||||
break;
|
||||
#endif /* LIBSSH2_MD5 */
|
||||
case LIBSSH2_HOSTKEY_HASH_SHA1:
|
||||
|
@@ -75,7 +75,8 @@ libssh2_keepalive_send (LIBSSH2_SESSION *session,
|
||||
size_t len = sizeof (keepalive_data) - 1;
|
||||
int rc;
|
||||
|
||||
keepalive_data[len - 1] = session->keepalive_want_reply;
|
||||
keepalive_data[len - 1] =
|
||||
(unsigned char)session->keepalive_want_reply;
|
||||
|
||||
rc = _libssh2_transport_send(session, keepalive_data, len, NULL, 0);
|
||||
/* Silently ignore PACKET_EAGAIN here: if the write buffer is
|
||||
@@ -90,8 +91,8 @@ libssh2_keepalive_send (LIBSSH2_SESSION *session,
|
||||
if (seconds_to_next)
|
||||
*seconds_to_next = session->keepalive_interval;
|
||||
} else if (seconds_to_next) {
|
||||
*seconds_to_next = (int) session->keepalive_last_sent
|
||||
+ session->keepalive_interval - now;
|
||||
*seconds_to_next = (int) (session->keepalive_last_sent - now)
|
||||
+ session->keepalive_interval;
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
90
src/kex.c
90
src/kex.c
@@ -218,10 +218,15 @@ static int diffie_hellman_sha1(LIBSSH2_SESSION *session,
|
||||
{
|
||||
libssh2_md5_ctx fingerprint_ctx;
|
||||
|
||||
libssh2_md5_init(&fingerprint_ctx);
|
||||
libssh2_md5_update(fingerprint_ctx, session->server_hostkey,
|
||||
session->server_hostkey_len);
|
||||
libssh2_md5_final(fingerprint_ctx, session->server_hostkey_md5);
|
||||
if (libssh2_md5_init(&fingerprint_ctx)) {
|
||||
libssh2_md5_update(fingerprint_ctx, session->server_hostkey,
|
||||
session->server_hostkey_len);
|
||||
libssh2_md5_final(fingerprint_ctx, session->server_hostkey_md5);
|
||||
session->server_hostkey_md5_valid = TRUE;
|
||||
}
|
||||
else {
|
||||
session->server_hostkey_md5_valid = FALSE;
|
||||
}
|
||||
}
|
||||
#ifdef LIBSSH2DEBUG
|
||||
{
|
||||
@@ -1544,6 +1549,30 @@ static int kex_agree_comp(LIBSSH2_SESSION *session,
|
||||
* The Client gets to make the final call on "agreed methods"
|
||||
*/
|
||||
|
||||
/*
|
||||
* kex_string_pair() extracts a string from the packet and makes sure it fits
|
||||
* within the given packet.
|
||||
*/
|
||||
static int kex_string_pair(unsigned char **sp, /* parsing position */
|
||||
unsigned char *data, /* start pointer to packet */
|
||||
size_t data_len, /* size of total packet */
|
||||
size_t *lenp, /* length of the string */
|
||||
unsigned char **strp) /* pointer to string start */
|
||||
{
|
||||
unsigned char *s = *sp;
|
||||
*lenp = _libssh2_ntohu32(s);
|
||||
|
||||
/* the length of the string must fit within the current pointer and the
|
||||
end of the packet */
|
||||
if (*lenp > (data_len - (s - data) -4))
|
||||
return 1;
|
||||
*strp = s + 4;
|
||||
s += 4 + *lenp;
|
||||
|
||||
*sp = s;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* kex_agree_methods
|
||||
* Decide which specific method to use of the methods offered by each party
|
||||
*/
|
||||
@@ -1563,38 +1592,23 @@ static int kex_agree_methods(LIBSSH2_SESSION * session, unsigned char *data,
|
||||
s += 16;
|
||||
|
||||
/* Locate each string */
|
||||
kex_len = _libssh2_ntohu32(s);
|
||||
kex = s + 4;
|
||||
s += 4 + kex_len;
|
||||
hostkey_len = _libssh2_ntohu32(s);
|
||||
hostkey = s + 4;
|
||||
s += 4 + hostkey_len;
|
||||
crypt_cs_len = _libssh2_ntohu32(s);
|
||||
crypt_cs = s + 4;
|
||||
s += 4 + crypt_cs_len;
|
||||
crypt_sc_len = _libssh2_ntohu32(s);
|
||||
crypt_sc = s + 4;
|
||||
s += 4 + crypt_sc_len;
|
||||
mac_cs_len = _libssh2_ntohu32(s);
|
||||
mac_cs = s + 4;
|
||||
s += 4 + mac_cs_len;
|
||||
mac_sc_len = _libssh2_ntohu32(s);
|
||||
mac_sc = s + 4;
|
||||
s += 4 + mac_sc_len;
|
||||
comp_cs_len = _libssh2_ntohu32(s);
|
||||
comp_cs = s + 4;
|
||||
s += 4 + comp_cs_len;
|
||||
comp_sc_len = _libssh2_ntohu32(s);
|
||||
comp_sc = s + 4;
|
||||
#if 0
|
||||
s += 4 + comp_sc_len;
|
||||
lang_cs_len = _libssh2_ntohu32(s);
|
||||
lang_cs = s + 4;
|
||||
s += 4 + lang_cs_len;
|
||||
lang_sc_len = _libssh2_ntohu32(s);
|
||||
lang_sc = s + 4;
|
||||
s += 4 + lang_sc_len;
|
||||
#endif
|
||||
if(kex_string_pair(&s, data, data_len, &kex_len, &kex))
|
||||
return -1;
|
||||
if(kex_string_pair(&s, data, data_len, &hostkey_len, &hostkey))
|
||||
return -1;
|
||||
if(kex_string_pair(&s, data, data_len, &crypt_cs_len, &crypt_cs))
|
||||
return -1;
|
||||
if(kex_string_pair(&s, data, data_len, &crypt_sc_len, &crypt_sc))
|
||||
return -1;
|
||||
if(kex_string_pair(&s, data, data_len, &mac_cs_len, &mac_cs))
|
||||
return -1;
|
||||
if(kex_string_pair(&s, data, data_len, &mac_sc_len, &mac_sc))
|
||||
return -1;
|
||||
if(kex_string_pair(&s, data, data_len, &comp_cs_len, &comp_cs))
|
||||
return -1;
|
||||
if(kex_string_pair(&s, data, data_len, &comp_sc_len, &comp_sc))
|
||||
return -1;
|
||||
|
||||
/* If the server sent an optimistic packet, assume that it guessed wrong.
|
||||
* If the guess is determined to be right (by kex_agree_kex_hostkey)
|
||||
* This flag will be reset to zero so that it's not ignored */
|
||||
@@ -1751,7 +1765,7 @@ _libssh2_kex_exchange(LIBSSH2_SESSION * session, int reexchange,
|
||||
key_state->state = libssh2_NB_state_sent2;
|
||||
}
|
||||
|
||||
if (rc == 0) {
|
||||
if (rc == 0 && session->kex) {
|
||||
if (key_state->state == libssh2_NB_state_sent2) {
|
||||
retcode = session->kex->exchange_keys(session,
|
||||
&key_state->key_state_low);
|
||||
@@ -1861,7 +1875,7 @@ libssh2_session_method_pref(LIBSSH2_SESSION * session, int method_type,
|
||||
}
|
||||
memcpy(s, prefs, prefs_len + 1);
|
||||
|
||||
while (s && *s) {
|
||||
while (s && *s && mlist) {
|
||||
char *p = strchr(s, ',');
|
||||
int method_len = p ? (p - s) : (int) strlen(s);
|
||||
|
||||
|
326
src/knownhost.c
326
src/knownhost.c
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2009-2011 by Daniel Stenberg
|
||||
* Copyright (c) 2009-2014 by Daniel Stenberg
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms,
|
||||
@@ -50,7 +50,11 @@ struct known_host {
|
||||
size_t salt_len; /* size of salt */
|
||||
char *key; /* the (allocated) associated key. This is kept base64
|
||||
encoded in memory. */
|
||||
char *comment; /* the (allocated) optional comment text, may be NULL */
|
||||
char *key_type_name; /* the (allocated) key type name */
|
||||
size_t key_type_len; /* size of key_type_name */
|
||||
char *comment; /* the (allocated) optional comment text, may be
|
||||
NULL */
|
||||
size_t comment_len; /* the size of comment */
|
||||
|
||||
/* this is the struct we expose externally */
|
||||
struct libssh2_knownhost external;
|
||||
@@ -67,6 +71,8 @@ static void free_host(LIBSSH2_SESSION *session, struct known_host *entry)
|
||||
if(entry) {
|
||||
if(entry->comment)
|
||||
LIBSSH2_FREE(session, entry->comment);
|
||||
if (entry->key_type_name)
|
||||
LIBSSH2_FREE(session, entry->key_type_name);
|
||||
if(entry->key)
|
||||
LIBSSH2_FREE(session, entry->key);
|
||||
if(entry->salt)
|
||||
@@ -127,6 +133,7 @@ static struct libssh2_knownhost *knownhost_to_external(struct known_host *node)
|
||||
static int
|
||||
knownhost_add(LIBSSH2_KNOWNHOSTS *hosts,
|
||||
const char *host, const char *salt,
|
||||
const char *key_type_name, size_t key_type_len,
|
||||
const char *key, size_t keylen,
|
||||
const char *comment, size_t commentlen,
|
||||
int typemask, struct libssh2_knownhost **store)
|
||||
@@ -142,13 +149,11 @@ knownhost_add(LIBSSH2_KNOWNHOSTS *hosts,
|
||||
return _libssh2_error(hosts->session, LIBSSH2_ERROR_INVAL,
|
||||
"No key type set");
|
||||
|
||||
if(!(entry = LIBSSH2_ALLOC(hosts->session, sizeof(struct known_host))))
|
||||
if(!(entry = LIBSSH2_CALLOC(hosts->session, sizeof(struct known_host))))
|
||||
return _libssh2_error(hosts->session, LIBSSH2_ERROR_ALLOC,
|
||||
"Unable to allocate memory for known host "
|
||||
"entry");
|
||||
|
||||
memset(entry, 0, sizeof(struct known_host));
|
||||
|
||||
entry->typemask = typemask;
|
||||
|
||||
switch(entry->typemask & LIBSSH2_KNOWNHOST_TYPE_MASK) {
|
||||
@@ -161,6 +166,7 @@ knownhost_add(LIBSSH2_KNOWNHOSTS *hosts,
|
||||
goto error;
|
||||
}
|
||||
memcpy(entry->name, host, hostlen+1);
|
||||
entry->name_len = hostlen;
|
||||
break;
|
||||
case LIBSSH2_KNOWNHOST_TYPE_SHA1:
|
||||
rc = libssh2_base64_decode(hosts->session, &ptr, &ptrlen,
|
||||
@@ -210,6 +216,19 @@ knownhost_add(LIBSSH2_KNOWNHOSTS *hosts,
|
||||
entry->key = ptr;
|
||||
}
|
||||
|
||||
if (key_type_name && ((typemask & LIBSSH2_KNOWNHOST_KEY_MASK) ==
|
||||
LIBSSH2_KNOWNHOST_KEY_UNKNOWN)) {
|
||||
entry->key_type_name = LIBSSH2_ALLOC(hosts->session, key_type_len+1);
|
||||
if (!entry->key_type_name) {
|
||||
rc = _libssh2_error(hosts->session, LIBSSH2_ERROR_ALLOC,
|
||||
"Unable to allocate memory for key type");
|
||||
goto error;
|
||||
}
|
||||
memcpy(entry->key_type_name, key_type_name, key_type_len);
|
||||
entry->key_type_name[key_type_len]=0;
|
||||
entry->key_type_len = key_type_len;
|
||||
}
|
||||
|
||||
if (comment) {
|
||||
entry->comment = LIBSSH2_ALLOC(hosts->session, commentlen+1);
|
||||
if(!entry->comment) {
|
||||
@@ -219,6 +238,7 @@ knownhost_add(LIBSSH2_KNOWNHOSTS *hosts,
|
||||
}
|
||||
memcpy(entry->comment, comment, commentlen+1);
|
||||
entry->comment[commentlen]=0; /* force a terminating zero trailer */
|
||||
entry->comment_len = commentlen;
|
||||
}
|
||||
else {
|
||||
entry->comment = NULL;
|
||||
@@ -264,8 +284,8 @@ libssh2_knownhost_add(LIBSSH2_KNOWNHOSTS *hosts,
|
||||
const char *key, size_t keylen,
|
||||
int typemask, struct libssh2_knownhost **store)
|
||||
{
|
||||
return knownhost_add(hosts, host, salt, key, keylen, NULL, 0, typemask,
|
||||
store);
|
||||
return knownhost_add(hosts, host, salt, NULL, 0, key, keylen, NULL,
|
||||
0, typemask, store);
|
||||
}
|
||||
|
||||
|
||||
@@ -303,8 +323,8 @@ libssh2_knownhost_addc(LIBSSH2_KNOWNHOSTS *hosts,
|
||||
const char *comment, size_t commentlen,
|
||||
int typemask, struct libssh2_knownhost **store)
|
||||
{
|
||||
return knownhost_add(hosts, host, salt, key, keylen, comment, commentlen,
|
||||
typemask, store);
|
||||
return knownhost_add(hosts, host, salt, NULL, 0, key, keylen,
|
||||
comment, commentlen, typemask, store);
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -346,6 +366,24 @@ knownhost_check(LIBSSH2_KNOWNHOSTS *hosts,
|
||||
/* we can't work with a sha1 as given input */
|
||||
return LIBSSH2_KNOWNHOST_CHECK_MISMATCH;
|
||||
|
||||
/* if a port number is given, check for a '[host]:port' first before the
|
||||
plain 'host' */
|
||||
if(port >= 0) {
|
||||
int len = snprintf(hostbuff, sizeof(hostbuff), "[%s]:%d", hostp, port);
|
||||
if (len < 0 || len >= (int)sizeof(hostbuff)) {
|
||||
_libssh2_error(hosts->session,
|
||||
LIBSSH2_ERROR_BUFFER_TOO_SMALL,
|
||||
"Known-host write buffer too small");
|
||||
return LIBSSH2_KNOWNHOST_CHECK_FAILURE;
|
||||
}
|
||||
host = hostbuff;
|
||||
numcheck = 2; /* check both combos, start with this */
|
||||
}
|
||||
else {
|
||||
host = hostp;
|
||||
numcheck = 1; /* only check this host version */
|
||||
}
|
||||
|
||||
if(!(typemask & LIBSSH2_KNOWNHOST_KEYENC_BASE64)) {
|
||||
/* we got a raw key input, convert it to base64 for the checks below */
|
||||
size_t nlen = _libssh2_base64_encode(hosts->session, key, keylen,
|
||||
@@ -361,18 +399,6 @@ knownhost_check(LIBSSH2_KNOWNHOSTS *hosts,
|
||||
key = keyalloc;
|
||||
}
|
||||
|
||||
/* if a port number is given, check for a '[host]:port' first before the
|
||||
plain 'host' */
|
||||
if(port >= 0) {
|
||||
snprintf(hostbuff, sizeof(hostbuff), "[%s]:%d", hostp, port);
|
||||
host = hostbuff;
|
||||
numcheck = 2; /* check both combos, start with this */
|
||||
}
|
||||
else {
|
||||
host = hostp;
|
||||
numcheck = 1; /* only check this host version */
|
||||
}
|
||||
|
||||
do {
|
||||
node = _libssh2_list_first(&hosts->head);
|
||||
while (node) {
|
||||
@@ -399,7 +425,8 @@ knownhost_check(LIBSSH2_KNOWNHOSTS *hosts,
|
||||
we can't match it */
|
||||
break;
|
||||
}
|
||||
libssh2_hmac_sha1_init(&ctx, node->salt, node->salt_len);
|
||||
libssh2_hmac_sha1_init(&ctx, (unsigned char *)node->salt,
|
||||
node->salt_len);
|
||||
libssh2_hmac_update(ctx, (unsigned char *)host,
|
||||
strlen(host));
|
||||
libssh2_hmac_final(ctx, hash);
|
||||
@@ -414,23 +441,35 @@ knownhost_check(LIBSSH2_KNOWNHOSTS *hosts,
|
||||
break;
|
||||
}
|
||||
if(match) {
|
||||
/* host name match, now compare the keys */
|
||||
if(!strcmp(key, node->key)) {
|
||||
/* they match! */
|
||||
if (ext)
|
||||
*ext = knownhost_to_external(node);
|
||||
badkey = NULL;
|
||||
rc = LIBSSH2_KNOWNHOST_CHECK_MATCH;
|
||||
break;
|
||||
}
|
||||
else {
|
||||
/* remember the first node that had a host match but a
|
||||
failed key match since we continue our search from
|
||||
here */
|
||||
if(!badkey)
|
||||
badkey = node;
|
||||
match = 0; /* don't count this as a match anymore */
|
||||
int host_key_type = typemask & LIBSSH2_KNOWNHOST_KEY_MASK;
|
||||
int known_key_type =
|
||||
node->typemask & LIBSSH2_KNOWNHOST_KEY_MASK;
|
||||
/* match on key type as follows:
|
||||
- never match on an unknown key type
|
||||
- if key_type is set to zero, ignore it an match always
|
||||
- otherwise match when both key types are equal
|
||||
*/
|
||||
if ( (host_key_type != LIBSSH2_KNOWNHOST_KEY_UNKNOWN ) &&
|
||||
( (host_key_type == 0) ||
|
||||
(host_key_type == known_key_type) ) ) {
|
||||
/* host name and key type match, now compare the keys */
|
||||
if(!strcmp(key, node->key)) {
|
||||
/* they match! */
|
||||
if (ext)
|
||||
*ext = knownhost_to_external(node);
|
||||
badkey = NULL;
|
||||
rc = LIBSSH2_KNOWNHOST_CHECK_MATCH;
|
||||
break;
|
||||
}
|
||||
else {
|
||||
/* remember the first node that had a host match but a
|
||||
failed key match since we continue our search from
|
||||
here */
|
||||
if(!badkey)
|
||||
badkey = node;
|
||||
}
|
||||
}
|
||||
match = 0; /* don't count this as a match anymore */
|
||||
}
|
||||
node= _libssh2_list_next(&node->node);
|
||||
}
|
||||
@@ -573,6 +612,7 @@ libssh2_knownhost_free(LIBSSH2_KNOWNHOSTS *hosts)
|
||||
*/
|
||||
static int oldstyle_hostline(LIBSSH2_KNOWNHOSTS *hosts,
|
||||
const char *host, size_t hostlen,
|
||||
const char *key_type_name, size_t key_type_len,
|
||||
const char *key, size_t keylen, int key_type,
|
||||
const char *comment, size_t commentlen)
|
||||
{
|
||||
@@ -607,7 +647,9 @@ static int oldstyle_hostline(LIBSSH2_KNOWNHOSTS *hosts,
|
||||
memcpy(hostbuf, name, namelen);
|
||||
hostbuf[namelen]=0;
|
||||
|
||||
rc = knownhost_add(hosts, hostbuf, NULL, key, keylen,
|
||||
rc = knownhost_add(hosts, hostbuf, NULL,
|
||||
key_type_name, key_type_len,
|
||||
key, keylen,
|
||||
comment, commentlen,
|
||||
key_type | LIBSSH2_KNOWNHOST_TYPE_PLAIN |
|
||||
LIBSSH2_KNOWNHOST_KEYENC_BASE64, NULL);
|
||||
@@ -627,6 +669,7 @@ static int oldstyle_hostline(LIBSSH2_KNOWNHOSTS *hosts,
|
||||
/* |1|[salt]|[hash] */
|
||||
static int hashed_hostline(LIBSSH2_KNOWNHOSTS *hosts,
|
||||
const char *host, size_t hostlen,
|
||||
const char *key_type_name, size_t key_type_len,
|
||||
const char *key, size_t keylen, int key_type,
|
||||
const char *comment, size_t commentlen)
|
||||
{
|
||||
@@ -670,9 +713,11 @@ static int hashed_hostline(LIBSSH2_KNOWNHOSTS *hosts,
|
||||
memcpy(hostbuf, host, hostlen);
|
||||
hostbuf[hostlen]=0;
|
||||
|
||||
return knownhost_add(hosts, hostbuf, salt, key, keylen, comment,
|
||||
commentlen,
|
||||
key_type | LIBSSH2_KNOWNHOST_TYPE_SHA1 |
|
||||
return knownhost_add(hosts, hostbuf, salt,
|
||||
key_type_name, key_type_len,
|
||||
key, keylen,
|
||||
comment, commentlen,
|
||||
key_type | LIBSSH2_KNOWNHOST_TYPE_SHA1 |
|
||||
LIBSSH2_KNOWNHOST_KEYENC_BASE64, NULL);
|
||||
}
|
||||
else
|
||||
@@ -694,7 +739,9 @@ static int hostline(LIBSSH2_KNOWNHOSTS *hosts,
|
||||
const char *key, size_t keylen)
|
||||
{
|
||||
const char *comment = NULL;
|
||||
const char *key_type_name = NULL;
|
||||
size_t commentlen = 0;
|
||||
size_t key_type_len = 0;
|
||||
int key_type;
|
||||
|
||||
/* make some checks that the lengths seem sensible */
|
||||
@@ -703,7 +750,7 @@ static int hostline(LIBSSH2_KNOWNHOSTS *hosts,
|
||||
LIBSSH2_ERROR_METHOD_NOT_SUPPORTED,
|
||||
"Failed to parse known_hosts line "
|
||||
"(key too short)");
|
||||
|
||||
|
||||
switch(key[0]) {
|
||||
case '0': case '1': case '2': case '3': case '4':
|
||||
case '5': case '6': case '7': case '8': case '9':
|
||||
@@ -716,19 +763,21 @@ static int hostline(LIBSSH2_KNOWNHOSTS *hosts,
|
||||
*/
|
||||
break;
|
||||
|
||||
case 's': /* ssh-dss or ssh-rsa */
|
||||
if(!strncmp(key, "ssh-dss", 7))
|
||||
default:
|
||||
key_type_name = key;
|
||||
while (keylen && *key &&
|
||||
(*key != ' ') && (*key != '\t')) {
|
||||
key++;
|
||||
keylen--;
|
||||
}
|
||||
key_type_len = key - key_type_name;
|
||||
|
||||
if (!strncmp(key_type_name, "ssh-dss", key_type_len))
|
||||
key_type = LIBSSH2_KNOWNHOST_KEY_SSHDSS;
|
||||
else if(!strncmp(key, "ssh-rsa", 7))
|
||||
else if (!strncmp(key_type_name, "ssh-rsa", key_type_len))
|
||||
key_type = LIBSSH2_KNOWNHOST_KEY_SSHRSA;
|
||||
else
|
||||
/* unknown key type */
|
||||
return _libssh2_error(hosts->session,
|
||||
LIBSSH2_ERROR_METHOD_NOT_SUPPORTED,
|
||||
"Unknown key type");
|
||||
|
||||
key += 7;
|
||||
keylen -= 7;
|
||||
key_type = LIBSSH2_KNOWNHOST_KEY_UNKNOWN;
|
||||
|
||||
/* skip whitespaces */
|
||||
while((*key ==' ') || (*key == '\t')) {
|
||||
@@ -760,11 +809,6 @@ static int hostline(LIBSSH2_KNOWNHOSTS *hosts,
|
||||
commentlen--;
|
||||
}
|
||||
break;
|
||||
|
||||
default: /* unknown key format */
|
||||
return _libssh2_error(hosts->session,
|
||||
LIBSSH2_ERROR_METHOD_NOT_SUPPORTED,
|
||||
"Unknown key format");
|
||||
}
|
||||
|
||||
/* Figure out host format */
|
||||
@@ -774,12 +818,14 @@ static int hostline(LIBSSH2_KNOWNHOSTS *hosts,
|
||||
for the sake of simplicity, we add them as separate hosts with the
|
||||
same key
|
||||
*/
|
||||
return oldstyle_hostline(hosts, host, hostlen, key, keylen, key_type,
|
||||
return oldstyle_hostline(hosts, host, hostlen, key_type_name,
|
||||
key_type_len, key, keylen, key_type,
|
||||
comment, commentlen);
|
||||
}
|
||||
else {
|
||||
/* |1|[salt]|[hash] */
|
||||
return hashed_hostline(hosts, host, hostlen, key, keylen, key_type,
|
||||
return hashed_hostline(hosts, host, hostlen, key_type_name,
|
||||
key_type_len, key, keylen, key_type,
|
||||
comment, commentlen);
|
||||
}
|
||||
}
|
||||
@@ -910,8 +956,11 @@ libssh2_knownhost_readfile(LIBSSH2_KNOWNHOSTS *hosts,
|
||||
file = fopen(filename, "r");
|
||||
if(file) {
|
||||
while(fgets(buf, sizeof(buf), file)) {
|
||||
if(libssh2_knownhost_readline(hosts, buf, strlen(buf), type))
|
||||
if(libssh2_knownhost_readline(hosts, buf, strlen(buf), type)) {
|
||||
num = _libssh2_error(hosts->session, LIBSSH2_ERROR_KNOWN_HOSTS,
|
||||
"Failed to parse known hosts file");
|
||||
break;
|
||||
}
|
||||
num++;
|
||||
}
|
||||
fclose(file);
|
||||
@@ -940,17 +989,10 @@ knownhost_writeline(LIBSSH2_KNOWNHOSTS *hosts,
|
||||
char *buf, size_t buflen,
|
||||
size_t *outlen, int type)
|
||||
{
|
||||
int rc = LIBSSH2_ERROR_NONE;
|
||||
int tindex;
|
||||
const char *keytypes[4]={
|
||||
"", /* not used */
|
||||
"", /* this type has no name in the file */
|
||||
" ssh-rsa",
|
||||
" ssh-dss"
|
||||
};
|
||||
const char *keytype;
|
||||
size_t nlen;
|
||||
size_t commentlen = 0;
|
||||
size_t required_size;
|
||||
|
||||
const char *key_type_name;
|
||||
size_t key_type_len;
|
||||
|
||||
/* we only support this single file type for now, bail out on all other
|
||||
attempts */
|
||||
@@ -960,75 +1002,131 @@ knownhost_writeline(LIBSSH2_KNOWNHOSTS *hosts,
|
||||
"Unsupported type of known-host information "
|
||||
"store");
|
||||
|
||||
tindex = (node->typemask & LIBSSH2_KNOWNHOST_KEY_MASK) >>
|
||||
LIBSSH2_KNOWNHOST_KEY_SHIFT;
|
||||
switch(node->typemask & LIBSSH2_KNOWNHOST_KEY_MASK) {
|
||||
case LIBSSH2_KNOWNHOST_KEY_RSA1:
|
||||
key_type_name = NULL;
|
||||
key_type_len = 0;
|
||||
break;
|
||||
case LIBSSH2_KNOWNHOST_KEY_SSHRSA:
|
||||
key_type_name = "ssh-rsa";
|
||||
key_type_len = 7;
|
||||
break;
|
||||
case LIBSSH2_KNOWNHOST_KEY_SSHDSS:
|
||||
key_type_name = "ssh-dss";
|
||||
key_type_len = 7;
|
||||
break;
|
||||
case LIBSSH2_KNOWNHOST_KEY_UNKNOWN:
|
||||
key_type_name = node->key_type_name;
|
||||
if (key_type_name) {
|
||||
key_type_len = node->key_type_len;
|
||||
break;
|
||||
}
|
||||
/* otherwise fallback to default and error */
|
||||
default:
|
||||
return _libssh2_error(hosts->session,
|
||||
LIBSSH2_ERROR_METHOD_NOT_SUPPORTED,
|
||||
"Unsupported type of known-host entry");
|
||||
}
|
||||
|
||||
/* set the string used in the file */
|
||||
keytype = keytypes[tindex];
|
||||
/* When putting together the host line there are three aspects to consider:
|
||||
- Hashed (SHA1) or unhashed hostname
|
||||
- key name or no key name (RSA1)
|
||||
- comment or no comment
|
||||
|
||||
This means there are 2^3 different formats:
|
||||
("|1|%s|%s %s %s %s\n", salt, hashed_host, key_name, key, comment)
|
||||
("|1|%s|%s %s %s\n", salt, hashed_host, key_name, key)
|
||||
("|1|%s|%s %s %s\n", salt, hashed_host, key, comment)
|
||||
("|1|%s|%s %s\n", salt, hashed_host, key)
|
||||
("%s %s %s %s\n", host, key_name, key, comment)
|
||||
("%s %s %s\n", host, key_name, key)
|
||||
("%s %s %s\n", host, key, comment)
|
||||
("%s %s\n", host, key)
|
||||
|
||||
Even if the buffer is too small, we have to set outlen to the number of
|
||||
characters the complete line would have taken. We also don't write
|
||||
anything to the buffer unless we are sure we can write everything to the
|
||||
buffer. */
|
||||
|
||||
/* calculate extra space needed for comment */
|
||||
required_size = strlen(node->key);
|
||||
|
||||
if(key_type_len)
|
||||
required_size += key_type_len + 1; /* ' ' = 1 */
|
||||
if(node->comment)
|
||||
commentlen = strlen(node->comment) + 1;
|
||||
required_size += node->comment_len + 1; /* ' ' = 1 */
|
||||
|
||||
if((node->typemask & LIBSSH2_KNOWNHOST_TYPE_MASK) ==
|
||||
LIBSSH2_KNOWNHOST_TYPE_SHA1) {
|
||||
char *namealloc;
|
||||
size_t name_base64_len;
|
||||
char *saltalloc;
|
||||
nlen = _libssh2_base64_encode(hosts->session, node->name,
|
||||
node->name_len, &namealloc);
|
||||
if(!nlen)
|
||||
size_t salt_base64_len;
|
||||
|
||||
name_base64_len = _libssh2_base64_encode(hosts->session, node->name,
|
||||
node->name_len, &namealloc);
|
||||
if(!name_base64_len)
|
||||
return _libssh2_error(hosts->session, LIBSSH2_ERROR_ALLOC,
|
||||
"Unable to allocate memory for "
|
||||
"base64-encoded host name");
|
||||
|
||||
nlen = _libssh2_base64_encode(hosts->session,
|
||||
node->salt, node->salt_len,
|
||||
&saltalloc);
|
||||
if(!nlen) {
|
||||
free(namealloc);
|
||||
salt_base64_len = _libssh2_base64_encode(hosts->session,
|
||||
node->salt, node->salt_len,
|
||||
&saltalloc);
|
||||
if(!salt_base64_len) {
|
||||
LIBSSH2_FREE(hosts->session, namealloc);
|
||||
return _libssh2_error(hosts->session, LIBSSH2_ERROR_ALLOC,
|
||||
"Unable to allocate memory for "
|
||||
"base64-encoded salt");
|
||||
}
|
||||
|
||||
nlen = strlen(saltalloc) + strlen(namealloc) + strlen(keytype) +
|
||||
strlen(node->key) + commentlen + 7;
|
||||
required_size += salt_base64_len + name_base64_len + 7;
|
||||
/* |1| + | + ' ' + \n + \0 = 7 */
|
||||
|
||||
if(nlen <= buflen)
|
||||
if(node->comment)
|
||||
snprintf(buf, buflen, "|1|%s|%s%s %s %s\n", saltalloc, namealloc,
|
||||
keytype, node->key, node->comment);
|
||||
if(required_size <= buflen) {
|
||||
if(node->comment && key_type_len)
|
||||
snprintf(buf, buflen, "|1|%s|%s %s %s %s\n", saltalloc,
|
||||
namealloc, key_type_name, node->key, node->comment);
|
||||
else if (node->comment)
|
||||
snprintf(buf, buflen, "|1|%s|%s %s %s\n", saltalloc, namealloc,
|
||||
node->key, node->comment);
|
||||
else if (key_type_len)
|
||||
snprintf(buf, buflen, "|1|%s|%s %s %s\n", saltalloc, namealloc,
|
||||
key_type_name, node->key);
|
||||
else
|
||||
snprintf(buf, buflen, "|1|%s|%s%s %s\n", saltalloc, namealloc,
|
||||
keytype, node->key);
|
||||
else
|
||||
rc = _libssh2_error(hosts->session, LIBSSH2_ERROR_BUFFER_TOO_SMALL,
|
||||
"Known-host write buffer too small");
|
||||
snprintf(buf, buflen, "|1|%s|%s %s\n", saltalloc, namealloc,
|
||||
node->key);
|
||||
}
|
||||
|
||||
free(namealloc);
|
||||
free(saltalloc);
|
||||
LIBSSH2_FREE(hosts->session, namealloc);
|
||||
LIBSSH2_FREE(hosts->session, saltalloc);
|
||||
}
|
||||
else {
|
||||
nlen = strlen(node->name) + strlen(keytype) + strlen(node->key) +
|
||||
commentlen + 3;
|
||||
required_size += node->name_len + 3;
|
||||
/* ' ' + '\n' + \0 = 3 */
|
||||
if(nlen <= buflen)
|
||||
/* these types have the plain name */
|
||||
if(node->comment)
|
||||
snprintf(buf, buflen, "%s%s %s %s\n", node->name, keytype, node->key,
|
||||
node->comment);
|
||||
|
||||
if(required_size <= buflen) {
|
||||
if(node->comment && key_type_len)
|
||||
snprintf(buf, buflen, "%s %s %s %s\n", node->name,
|
||||
key_type_name, node->key, node->comment);
|
||||
else if (node->comment)
|
||||
snprintf(buf, buflen, "%s %s %s\n", node->name, node->key,
|
||||
node->comment);
|
||||
else if (key_type_len)
|
||||
snprintf(buf, buflen, "%s %s %s\n", node->name, key_type_name,
|
||||
node->key);
|
||||
else
|
||||
snprintf(buf, buflen, "%s%s %s\n", node->name, keytype, node->key);
|
||||
else
|
||||
rc = _libssh2_error(hosts->session, LIBSSH2_ERROR_BUFFER_TOO_SMALL,
|
||||
"Known-host write buffer too small");
|
||||
snprintf(buf, buflen, "%s %s\n", node->name, node->key);
|
||||
}
|
||||
}
|
||||
|
||||
/* we report the full length of the data with the trailing zero excluded */
|
||||
*outlen = nlen-1;
|
||||
*outlen = required_size-1;
|
||||
|
||||
return rc;
|
||||
if(required_size <= buflen)
|
||||
return LIBSSH2_ERROR_NONE;
|
||||
else
|
||||
return _libssh2_error(hosts->session, LIBSSH2_ERROR_BUFFER_TOO_SMALL,
|
||||
"Known-host write buffer too small");
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -1086,8 +1184,8 @@ libssh2_knownhost_writefile(LIBSSH2_KNOWNHOSTS *hosts,
|
||||
|
||||
for(node = _libssh2_list_first(&hosts->head);
|
||||
node;
|
||||
node= _libssh2_list_next(&node->node) ) {
|
||||
size_t wrote;
|
||||
node = _libssh2_list_next(&node->node)) {
|
||||
size_t wrote = 0;
|
||||
size_t nwrote;
|
||||
rc = knownhost_writeline(hosts, node, buffer, sizeof(buffer), &wrote,
|
||||
type);
|
||||
|
@@ -342,7 +342,7 @@ _libssh2_dsa_new_private(libssh2_dsa_ctx ** dsa,
|
||||
|
||||
int
|
||||
_libssh2_rsa_sha1_sign(LIBSSH2_SESSION * session,
|
||||
libssh2_dsa_ctx * rsactx,
|
||||
libssh2_rsa_ctx * rsactx,
|
||||
const unsigned char *hash,
|
||||
size_t hash_len,
|
||||
unsigned char **signature, size_t *signature_len)
|
||||
@@ -553,17 +553,11 @@ _libssh2_cipher_init(_libssh2_cipher_ctx * h,
|
||||
int
|
||||
_libssh2_cipher_crypt(_libssh2_cipher_ctx * ctx,
|
||||
_libssh2_cipher_type(algo),
|
||||
int encrypt, unsigned char *block)
|
||||
int encrypt, unsigned char *block, size_t blklen)
|
||||
{
|
||||
int cipher = _libssh2_gcry_cipher (algo);
|
||||
size_t blklen = gcry_cipher_get_algo_blklen(cipher);
|
||||
int ret;
|
||||
|
||||
if (blklen == 1) {
|
||||
/* Hack for arcfour. */
|
||||
blklen = 8;
|
||||
}
|
||||
|
||||
if (encrypt) {
|
||||
ret = gcry_cipher_encrypt(*ctx, block, blklen, block, blklen);
|
||||
} else {
|
||||
|
@@ -61,15 +61,21 @@
|
||||
|
||||
#define libssh2_sha1_ctx gcry_md_hd_t
|
||||
#define libssh2_sha1_init(ctx) gcry_md_open (ctx, GCRY_MD_SHA1, 0);
|
||||
#define libssh2_sha1_update(ctx, data, len) gcry_md_write (ctx, data, len)
|
||||
#define libssh2_sha1_update(ctx, data, len) \
|
||||
gcry_md_write (ctx, (unsigned char *) data, len)
|
||||
#define libssh2_sha1_final(ctx, out) \
|
||||
memcpy (out, gcry_md_read (ctx, 0), SHA_DIGEST_LENGTH), gcry_md_close (ctx)
|
||||
#define libssh2_sha1(message, len, out) \
|
||||
gcry_md_hash_buffer (GCRY_MD_SHA1, out, message, len)
|
||||
|
||||
#define libssh2_md5_ctx gcry_md_hd_t
|
||||
#define libssh2_md5_init(ctx) gcry_md_open (ctx, GCRY_MD_MD5, 0);
|
||||
#define libssh2_md5_update(ctx, data, len) gcry_md_write (ctx, data, len)
|
||||
|
||||
/* returns 0 in case of failure */
|
||||
#define libssh2_md5_init(ctx) \
|
||||
(GPG_ERR_NO_ERROR == gcry_md_open (ctx, GCRY_MD_MD5, 0))
|
||||
|
||||
#define libssh2_md5_update(ctx, data, len) \
|
||||
gcry_md_write (ctx, (unsigned char *) data, len)
|
||||
#define libssh2_md5_final(ctx, out) \
|
||||
memcpy (out, gcry_md_read (ctx, 0), MD5_DIGEST_LENGTH), gcry_md_close (ctx)
|
||||
#define libssh2_md5(message, len, out) \
|
||||
@@ -86,7 +92,7 @@
|
||||
gcry_md_open (ctx, GCRY_MD_RMD160, GCRY_MD_FLAG_HMAC), \
|
||||
gcry_md_setkey (*ctx, key, keylen)
|
||||
#define libssh2_hmac_update(ctx, data, datalen) \
|
||||
gcry_md_write (ctx, data, datalen)
|
||||
gcry_md_write (ctx, (unsigned char *) data, datalen)
|
||||
#define libssh2_hmac_final(ctx, data) \
|
||||
memcpy (data, gcry_md_read (ctx, 0), \
|
||||
gcry_md_get_algo_dlen (gcry_md_get_algo (ctx)))
|
||||
|
@@ -1,5 +1,5 @@
|
||||
/* Copyright (c) 2004-2008, 2010, Sara Golemon <sarag@libssh2.org>
|
||||
* Copyright (c) 2009-2011 by Daniel Stenberg
|
||||
* Copyright (c) 2009-2014 by Daniel Stenberg
|
||||
* Copyright (c) 2010 Simon Josefsson
|
||||
* All rights reserved.
|
||||
*
|
||||
@@ -108,6 +108,11 @@
|
||||
#define TRUE 1
|
||||
#endif
|
||||
|
||||
#ifdef _MSC_VER
|
||||
/* "inline" keyword is valid only with C++ engine! */
|
||||
#define inline __inline
|
||||
#endif
|
||||
|
||||
/* Provide iovec / writev on WIN32 platform. */
|
||||
#ifdef WIN32
|
||||
|
||||
@@ -116,8 +121,6 @@ struct iovec {
|
||||
void * iov_base;
|
||||
};
|
||||
|
||||
#define inline __inline
|
||||
|
||||
static inline int writev(int sock, struct iovec *iov, int nvecs)
|
||||
{
|
||||
DWORD ret;
|
||||
@@ -134,14 +137,8 @@ static inline int writev(int sock, struct iovec *iov, int nvecs)
|
||||
#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
|
||||
|
||||
#endif
|
||||
|
||||
/* RFC4253 section 6.1 Maximum Packet Length says:
|
||||
@@ -155,6 +152,7 @@ static inline int writev(int sock, struct iovec *iov, int nvecs)
|
||||
|
||||
#define LIBSSH2_ALLOC(session, count) \
|
||||
session->alloc((count), &(session)->abstract)
|
||||
#define LIBSSH2_CALLOC(session, count) _libssh2_calloc(session, count)
|
||||
#define LIBSSH2_REALLOC(session, ptr, count) \
|
||||
((ptr) ? session->realloc((ptr), (count), &(session)->abstract) : \
|
||||
session->alloc((count), &(session)->abstract))
|
||||
@@ -357,6 +355,8 @@ struct _LIBSSH2_CHANNEL
|
||||
libssh2_channel_data local, remote;
|
||||
/* Amount of bytes to be refunded to receive window (but not yet sent) */
|
||||
uint32_t adjust_queue;
|
||||
/* Data immediately available for reading */
|
||||
uint32_t read_avail;
|
||||
|
||||
LIBSSH2_SESSION *session;
|
||||
|
||||
@@ -575,7 +575,7 @@ struct _LIBSSH2_SESSION
|
||||
|
||||
/* Agreed Key Exchange Method */
|
||||
const LIBSSH2_KEX_METHOD *kex;
|
||||
int burn_optimistic_kexinit:1;
|
||||
unsigned int burn_optimistic_kexinit:1;
|
||||
|
||||
unsigned char *session_id;
|
||||
uint32_t session_id_len;
|
||||
@@ -597,6 +597,7 @@ struct _LIBSSH2_SESSION
|
||||
uint32_t server_hostkey_len;
|
||||
#if LIBSSH2_MD5
|
||||
unsigned char server_hostkey_md5[MD5_DIGEST_LENGTH];
|
||||
int server_hostkey_md5_valid;
|
||||
#endif /* ! LIBSSH2_MD5 */
|
||||
unsigned char server_hostkey_sha1[SHA_DIGEST_LENGTH];
|
||||
|
||||
@@ -882,7 +883,7 @@ struct _LIBSSH2_CRYPT_METHOD
|
||||
int *free_iv, unsigned char *secret, int *free_secret,
|
||||
int encrypt, void **abstract);
|
||||
int (*crypt) (LIBSSH2_SESSION * session, unsigned char *block,
|
||||
void **abstract);
|
||||
size_t blocksize, void **abstract);
|
||||
int (*dtor) (LIBSSH2_SESSION * session, void **abstract);
|
||||
|
||||
_libssh2_cipher_type(algo);
|
||||
@@ -892,6 +893,7 @@ struct _LIBSSH2_COMP_METHOD
|
||||
{
|
||||
const char *name;
|
||||
int compress; /* 1 if it does compress, 0 if it doesn't */
|
||||
int use_in_auth; /* 1 if compression should be used in userauth */
|
||||
int (*init) (LIBSSH2_SESSION *session, int compress, void **abstract);
|
||||
int (*comp) (LIBSSH2_SESSION *session,
|
||||
unsigned char *dest,
|
||||
@@ -921,6 +923,9 @@ void _libssh2_debug(LIBSSH2_SESSION * session, int context, const char *format,
|
||||
static inline void
|
||||
_libssh2_debug(LIBSSH2_SESSION * session, int context, const char *format, ...)
|
||||
{
|
||||
(void)session;
|
||||
(void)context;
|
||||
(void)format;
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
@@ -1030,9 +1035,9 @@ void _libssh2_init_if_needed (void);
|
||||
|
||||
/* define to output the libssh2_int64_t type in a *printf() */
|
||||
#if defined( __BORLANDC__ ) || defined( _MSC_VER ) || defined( __MINGW32__ )
|
||||
#define LIBSSH2_INT64_T_FORMAT "I64"
|
||||
#define LIBSSH2_INT64_T_FORMAT "I64d"
|
||||
#else
|
||||
#define LIBSSH2_INT64_T_FORMAT "ll"
|
||||
#define LIBSSH2_INT64_T_FORMAT "lld"
|
||||
#endif
|
||||
|
||||
#endif /* LIBSSH2_H */
|
||||
|
34
src/misc.c
34
src/misc.c
@@ -1,5 +1,5 @@
|
||||
/* Copyright (c) 2004-2007 Sara Golemon <sarag@libssh2.org>
|
||||
* Copyright (c) 2009-2010 by Daniel Stenberg
|
||||
* Copyright (c) 2009-2014 by Daniel Stenberg
|
||||
* Copyright (c) 2010 Simon Josefsson
|
||||
* All rights reserved.
|
||||
*
|
||||
@@ -94,9 +94,14 @@ static int wsa2errno(void)
|
||||
* Replacement for the standard recv, return -errno on failure.
|
||||
*/
|
||||
ssize_t
|
||||
_libssh2_recv(libssh2_socket_t sock, void *buffer, size_t length, int flags, void **abstract)
|
||||
_libssh2_recv(libssh2_socket_t sock, void *buffer, size_t length,
|
||||
int flags, void **abstract)
|
||||
{
|
||||
ssize_t rc = recv(sock, buffer, length, flags);
|
||||
ssize_t rc;
|
||||
|
||||
(void) abstract;
|
||||
|
||||
rc = recv(sock, buffer, length, flags);
|
||||
#ifdef WIN32
|
||||
if (rc < 0 )
|
||||
return -wsa2errno();
|
||||
@@ -128,7 +133,11 @@ ssize_t
|
||||
_libssh2_send(libssh2_socket_t sock, const void *buffer, size_t length,
|
||||
int flags, void **abstract)
|
||||
{
|
||||
ssize_t rc = send(sock, buffer, length, flags);
|
||||
ssize_t rc;
|
||||
|
||||
(void) abstract;
|
||||
|
||||
rc = send(sock, buffer, length, flags);
|
||||
#ifdef WIN32
|
||||
if (rc < 0 )
|
||||
return -wsa2errno();
|
||||
@@ -257,15 +266,15 @@ libssh2_base64_decode(LIBSSH2_SESSION *session, char **data,
|
||||
continue;
|
||||
switch (i % 4) {
|
||||
case 0:
|
||||
d[len] = v << 2;
|
||||
d[len] = (unsigned char)(v << 2);
|
||||
break;
|
||||
case 1:
|
||||
d[len++] |= v >> 4;
|
||||
d[len] = v << 4;
|
||||
d[len] = (unsigned char)(v << 4);
|
||||
break;
|
||||
case 2:
|
||||
d[len++] |= v >> 2;
|
||||
d[len] = v << 6;
|
||||
d[len] = (unsigned char)(v << 6);
|
||||
break;
|
||||
case 3:
|
||||
d[len++] |= v;
|
||||
@@ -596,7 +605,7 @@ int __cdecl _libssh2_gettimeofday(struct timeval *tp, void *tzp)
|
||||
unsigned __int64 ns100; /*time since 1 Jan 1601 in 100ns units */
|
||||
FILETIME ft;
|
||||
} _now;
|
||||
|
||||
(void)tzp;
|
||||
if(tp)
|
||||
{
|
||||
GetSystemTimeAsFileTime (&_now.ft);
|
||||
@@ -610,3 +619,12 @@ int __cdecl _libssh2_gettimeofday(struct timeval *tp, void *tzp)
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
void *_libssh2_calloc(LIBSSH2_SESSION* session, size_t size)
|
||||
{
|
||||
void *p = LIBSSH2_ALLOC(session, size);
|
||||
if(p) {
|
||||
memset(p, 0, size);
|
||||
}
|
||||
return p;
|
||||
}
|
||||
|
@@ -1,6 +1,6 @@
|
||||
#ifndef __LIBSSH2_MISC_H
|
||||
#define __LIBSSH2_MISC_H
|
||||
/* Copyright (c) 2009-2011 by Daniel Stenberg
|
||||
/* Copyright (c) 2009-2014 by Daniel Stenberg
|
||||
*
|
||||
* All rights reserved.
|
||||
*
|
||||
@@ -77,8 +77,9 @@ libssh2_uint64_t _libssh2_ntohu64(const unsigned char *buf);
|
||||
void _libssh2_htonu32(unsigned char *buf, uint32_t val);
|
||||
void _libssh2_store_u32(unsigned char **buf, uint32_t value);
|
||||
void _libssh2_store_str(unsigned char **buf, const char *str, size_t len);
|
||||
void *_libssh2_calloc(LIBSSH2_SESSION* session, size_t size);
|
||||
|
||||
#if defined(LIBSSH2_WIN32) && !defined(__MINGW32__)
|
||||
#if defined(LIBSSH2_WIN32) && !defined(__MINGW32__) && !defined(__CYGWIN__)
|
||||
/* provide a private one */
|
||||
#undef HAVE_GETTIMEOFDAY
|
||||
int __cdecl _libssh2_gettimeofday(struct timeval *tp, void *tzp);
|
||||
|
@@ -40,7 +40,7 @@
|
||||
|
||||
#include "libssh2_priv.h"
|
||||
|
||||
#ifndef LIBSSH2_LIBGCRYPT /* compile only if we build with OpenSSL */
|
||||
#ifdef LIBSSH2_OPENSSL /* compile only if we build with openssl */
|
||||
|
||||
#include <string.h>
|
||||
|
||||
@@ -175,25 +175,19 @@ _libssh2_cipher_init(_libssh2_cipher_ctx * h,
|
||||
unsigned char *iv, unsigned char *secret, int encrypt)
|
||||
{
|
||||
EVP_CIPHER_CTX_init(h);
|
||||
EVP_CipherInit(h, algo(), secret, iv, encrypt);
|
||||
return 0;
|
||||
return !EVP_CipherInit(h, algo(), secret, iv, encrypt);
|
||||
}
|
||||
|
||||
int
|
||||
_libssh2_cipher_crypt(_libssh2_cipher_ctx * ctx,
|
||||
_libssh2_cipher_type(algo),
|
||||
int encrypt, unsigned char *block)
|
||||
int encrypt, unsigned char *block, size_t blocksize)
|
||||
{
|
||||
int blocksize = ctx->cipher->block_size;
|
||||
unsigned char buf[EVP_MAX_BLOCK_LENGTH];
|
||||
int ret;
|
||||
(void) algo;
|
||||
(void) encrypt;
|
||||
|
||||
if (blocksize == 1) {
|
||||
/* Hack for arcfour. */
|
||||
blocksize = 8;
|
||||
}
|
||||
ret = EVP_Cipher(ctx, buf, block, blocksize);
|
||||
if (ret == 1) {
|
||||
memcpy(block, buf, blocksize);
|
||||
@@ -221,13 +215,10 @@ aes_ctr_init(EVP_CIPHER_CTX *ctx, const unsigned char *key,
|
||||
* variable "c" is leaked from this scope, but is later freed
|
||||
* in aes_ctr_cleanup
|
||||
*/
|
||||
aes_ctr_ctx *c = malloc(sizeof(*c));
|
||||
aes_ctr_ctx *c;
|
||||
const EVP_CIPHER *aes_cipher;
|
||||
(void) enc;
|
||||
|
||||
if (c == NULL)
|
||||
return 0;
|
||||
|
||||
switch (ctx->key_len) {
|
||||
case 16:
|
||||
aes_cipher = EVP_aes_128_ecb();
|
||||
@@ -241,11 +232,20 @@ aes_ctr_init(EVP_CIPHER_CTX *ctx, const unsigned char *key,
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
c->aes_ctx = malloc(sizeof(EVP_CIPHER_CTX));
|
||||
if (c->aes_ctx == NULL)
|
||||
|
||||
c = malloc(sizeof(*c));
|
||||
if (c == NULL)
|
||||
return 0;
|
||||
|
||||
c->aes_ctx = malloc(sizeof(EVP_CIPHER_CTX));
|
||||
if (c->aes_ctx == NULL) {
|
||||
free(c);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (EVP_EncryptInit(c->aes_ctx, aes_cipher, key, NULL) != 1) {
|
||||
free(c->aes_ctx);
|
||||
free(c);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -509,23 +509,39 @@ _libssh2_dsa_sha1_sign(libssh2_dsa_ctx * dsactx,
|
||||
}
|
||||
#endif /* LIBSSH_DSA */
|
||||
|
||||
int
|
||||
libssh2_sha1_init(libssh2_sha1_ctx *ctx)
|
||||
{
|
||||
EVP_MD_CTX_init(ctx);
|
||||
return EVP_DigestInit(ctx, EVP_get_digestbyname("sha1"));
|
||||
}
|
||||
|
||||
void
|
||||
libssh2_sha1(const unsigned char *message, unsigned long len,
|
||||
unsigned char *out)
|
||||
{
|
||||
EVP_MD_CTX ctx;
|
||||
|
||||
EVP_MD_CTX_init(&ctx);
|
||||
EVP_DigestInit(&ctx, EVP_get_digestbyname("sha1"));
|
||||
EVP_DigestUpdate(&ctx, message, len);
|
||||
EVP_DigestFinal(&ctx, out, NULL);
|
||||
}
|
||||
|
||||
int
|
||||
libssh2_md5_init(libssh2_md5_ctx *ctx)
|
||||
{
|
||||
EVP_MD_CTX_init(ctx);
|
||||
return EVP_DigestInit(ctx, EVP_get_digestbyname("md5"));
|
||||
}
|
||||
|
||||
void
|
||||
libssh2_md5(const unsigned char *message, unsigned long len,
|
||||
unsigned char *out)
|
||||
{
|
||||
EVP_MD_CTX ctx;
|
||||
|
||||
EVP_MD_CTX_init(&ctx);
|
||||
EVP_DigestInit(&ctx, EVP_get_digestbyname("md5"));
|
||||
EVP_DigestUpdate(&ctx, message, len);
|
||||
EVP_DigestFinal(&ctx, out, NULL);
|
||||
@@ -801,4 +817,4 @@ _libssh2_pub_priv_keyfile(LIBSSH2_SESSION *session,
|
||||
return st;
|
||||
}
|
||||
|
||||
#endif /* !LIBSSH2_LIBGCRYPT */
|
||||
#endif /* LIBSSH2_OPENSSL */
|
||||
|
@@ -107,13 +107,15 @@
|
||||
#define _libssh2_random(buf, len) RAND_bytes ((buf), (len))
|
||||
|
||||
#define libssh2_sha1_ctx EVP_MD_CTX
|
||||
#define libssh2_sha1_init(ctx) EVP_DigestInit(ctx, EVP_get_digestbyname("sha1"))
|
||||
int libssh2_sha1_init(libssh2_sha1_ctx *ctx);
|
||||
#define libssh2_sha1_update(ctx, data, len) EVP_DigestUpdate(&(ctx), data, len)
|
||||
#define libssh2_sha1_final(ctx, out) EVP_DigestFinal(&(ctx), out, NULL)
|
||||
void libssh2_sha1(const unsigned char *message, unsigned long len, unsigned char *out);
|
||||
|
||||
#define libssh2_md5_ctx EVP_MD_CTX
|
||||
#define libssh2_md5_init(ctx) EVP_DigestInit(ctx, EVP_get_digestbyname("md5"))
|
||||
|
||||
/* returns 0 in case of failure */
|
||||
int libssh2_md5_init(libssh2_md5_ctx *);
|
||||
#define libssh2_md5_update(ctx, data, len) EVP_DigestUpdate(&(ctx), data, len)
|
||||
#define libssh2_md5_final(ctx, out) EVP_DigestFinal(&(ctx), out, NULL)
|
||||
void libssh2_md5(const unsigned char *message, unsigned long len, unsigned char *out);
|
||||
@@ -148,9 +150,15 @@ void libssh2_md5(const unsigned char *message, unsigned long len, unsigned char
|
||||
#define _libssh2_cipher_aes256 EVP_aes_256_cbc
|
||||
#define _libssh2_cipher_aes192 EVP_aes_192_cbc
|
||||
#define _libssh2_cipher_aes128 EVP_aes_128_cbc
|
||||
#ifdef HAVE_EVP_AES_128_CTR
|
||||
#define _libssh2_cipher_aes128ctr EVP_aes_128_ctr
|
||||
#define _libssh2_cipher_aes192ctr EVP_aes_192_ctr
|
||||
#define _libssh2_cipher_aes256ctr EVP_aes_256_ctr
|
||||
#else
|
||||
#define _libssh2_cipher_aes128ctr _libssh2_EVP_aes_128_ctr
|
||||
#define _libssh2_cipher_aes192ctr _libssh2_EVP_aes_192_ctr
|
||||
#define _libssh2_cipher_aes256ctr _libssh2_EVP_aes_256_ctr
|
||||
#endif
|
||||
#define _libssh2_cipher_blowfish EVP_bf_cbc
|
||||
#define _libssh2_cipher_arcfour EVP_rc4
|
||||
#define _libssh2_cipher_cast5 EVP_cast5_cbc
|
||||
|
68
src/packet.c
68
src/packet.c
@@ -1,6 +1,6 @@
|
||||
/* Copyright (c) 2004-2007, Sara Golemon <sarag@libssh2.org>
|
||||
* Copyright (c) 2005,2006 Mikhail Gusarov
|
||||
* Copyright (c) 2009-2010 by Daniel Stenberg
|
||||
* Copyright (c) 2009-2014 by Daniel Stenberg
|
||||
* Copyright (c) 2010 Simon Josefsson
|
||||
* All rights reserved.
|
||||
*
|
||||
@@ -139,7 +139,7 @@ packet_queue_listener(LIBSSH2_SESSION * session, unsigned char *data,
|
||||
break;
|
||||
}
|
||||
|
||||
channel = LIBSSH2_ALLOC(session, sizeof(LIBSSH2_CHANNEL));
|
||||
channel = LIBSSH2_CALLOC(session, sizeof(LIBSSH2_CHANNEL));
|
||||
if (!channel) {
|
||||
_libssh2_error(session, LIBSSH2_ERROR_ALLOC,
|
||||
"Unable to allocate a channel for "
|
||||
@@ -150,8 +150,6 @@ packet_queue_listener(LIBSSH2_SESSION * session, unsigned char *data,
|
||||
}
|
||||
listen_state->channel = channel;
|
||||
|
||||
memset(channel, 0, sizeof(LIBSSH2_CHANNEL));
|
||||
|
||||
channel->session = session;
|
||||
channel->channel_type_len = sizeof("forwarded-tcpip") - 1;
|
||||
channel->channel_type = LIBSSH2_ALLOC(session,
|
||||
@@ -218,9 +216,11 @@ packet_queue_listener(LIBSSH2_SESSION * session, unsigned char *data,
|
||||
}
|
||||
|
||||
/* Link the channel into the end of the queue list */
|
||||
_libssh2_list_add(&listn->queue,
|
||||
&listen_state->channel->node);
|
||||
listn->queue_size++;
|
||||
if (listen_state->channel) {
|
||||
_libssh2_list_add(&listn->queue,
|
||||
&listen_state->channel->node);
|
||||
listn->queue_size++;
|
||||
}
|
||||
|
||||
listen_state->state = libssh2_NB_state_idle;
|
||||
return 0;
|
||||
@@ -297,14 +297,13 @@ packet_x11_open(LIBSSH2_SESSION * session, unsigned char *data,
|
||||
|
||||
if (session->x11) {
|
||||
if (x11open_state->state == libssh2_NB_state_allocated) {
|
||||
channel = LIBSSH2_ALLOC(session, sizeof(LIBSSH2_CHANNEL));
|
||||
channel = LIBSSH2_CALLOC(session, sizeof(LIBSSH2_CHANNEL));
|
||||
if (!channel) {
|
||||
_libssh2_error(session, LIBSSH2_ERROR_ALLOC,
|
||||
"allocate a channel for new connection");
|
||||
failure_code = SSH_OPEN_RESOURCE_SHORTAGE;
|
||||
goto x11_exit;
|
||||
}
|
||||
memset(channel, 0, sizeof(LIBSSH2_CHANNEL));
|
||||
|
||||
channel->session = session;
|
||||
channel->channel_type_len = sizeof("x11") - 1;
|
||||
@@ -408,6 +407,7 @@ packet_x11_open(LIBSSH2_SESSION * session, unsigned char *data,
|
||||
*
|
||||
* The input pointer 'data' is pointing to allocated data that this function
|
||||
* is asked to deal with so on failure OR success, it must be freed fine.
|
||||
* The only exception is when the return code is LIBSSH2_ERROR_EAGAIN.
|
||||
*
|
||||
* This function will always be called with 'datalen' greater than zero.
|
||||
*/
|
||||
@@ -583,7 +583,8 @@ _libssh2_packet_add(LIBSSH2_SESSION * session, unsigned char *data,
|
||||
|
||||
|
||||
if (want_reply) {
|
||||
unsigned char packet = SSH_MSG_REQUEST_FAILURE;
|
||||
static const unsigned char packet =
|
||||
SSH_MSG_REQUEST_FAILURE;
|
||||
libssh2_packet_add_jump_point5:
|
||||
session->packAdd_state = libssh2_NB_state_jump5;
|
||||
rc = _libssh2_transport_send(session, &packet, 1, NULL, 0);
|
||||
@@ -653,6 +654,18 @@ _libssh2_packet_add(LIBSSH2_SESSION * session, unsigned char *data,
|
||||
_libssh2_debug(session, LIBSSH2_TRACE_CONN,
|
||||
"Ignoring extended data and refunding %d bytes",
|
||||
(int) (datalen - 13));
|
||||
if (channelp->read_avail + datalen - data_head >=
|
||||
channelp->remote.window_size)
|
||||
datalen = channelp->remote.window_size -
|
||||
channelp->read_avail + data_head;
|
||||
|
||||
channelp->remote.window_size -= datalen - data_head;
|
||||
_libssh2_debug(session, LIBSSH2_TRACE_CONN,
|
||||
"shrinking window size by %lu bytes to %lu, read_avail %lu",
|
||||
datalen - data_head,
|
||||
channelp->remote.window_size,
|
||||
channelp->read_avail);
|
||||
|
||||
session->packAdd_channelp = channelp;
|
||||
|
||||
/* Adjust the window based on the block we just freed */
|
||||
@@ -684,7 +697,7 @@ _libssh2_packet_add(LIBSSH2_SESSION * session, unsigned char *data,
|
||||
" to receive, truncating");
|
||||
datalen = channelp->remote.packet_size + data_head;
|
||||
}
|
||||
if (channelp->remote.window_size <= 0) {
|
||||
if (channelp->remote.window_size <= channelp->read_avail) {
|
||||
/*
|
||||
* Spec says we MAY ignore bytes sent beyond
|
||||
* window_size
|
||||
@@ -700,17 +713,26 @@ _libssh2_packet_add(LIBSSH2_SESSION * session, unsigned char *data,
|
||||
/* Reset EOF status */
|
||||
channelp->remote.eof = 0;
|
||||
|
||||
if ((datalen - data_head) > channelp->remote.window_size) {
|
||||
if (channelp->read_avail + datalen - data_head >
|
||||
channelp->remote.window_size) {
|
||||
_libssh2_error(session,
|
||||
LIBSSH2_ERROR_CHANNEL_WINDOW_EXCEEDED,
|
||||
"Remote sent more data than current "
|
||||
"window allows, truncating");
|
||||
datalen = channelp->remote.window_size + data_head;
|
||||
channelp->remote.window_size = 0;
|
||||
datalen = channelp->remote.window_size -
|
||||
channelp->read_avail + data_head;
|
||||
}
|
||||
else
|
||||
/* Now that we've received it, shrink our window */
|
||||
channelp->remote.window_size -= datalen - data_head;
|
||||
|
||||
/* Update the read_avail counter. The window size will be
|
||||
* updated once the data is actually read from the queue
|
||||
* from an upper layer */
|
||||
channelp->read_avail += datalen - data_head;
|
||||
|
||||
_libssh2_debug(session, LIBSSH2_TRACE_CONN,
|
||||
"increasing read_avail by %lu bytes to %lu/%lu",
|
||||
(long)(datalen - data_head),
|
||||
(long)channelp->read_avail,
|
||||
(long)channelp->remote.window_size);
|
||||
|
||||
break;
|
||||
|
||||
@@ -751,7 +773,7 @@ _libssh2_packet_add(LIBSSH2_SESSION * session, unsigned char *data,
|
||||
if(datalen >= 9) {
|
||||
uint32_t channel = _libssh2_ntohu32(data + 1);
|
||||
uint32_t len = _libssh2_ntohu32(data + 5);
|
||||
unsigned char want_reply = 0;
|
||||
unsigned char want_reply = 1;
|
||||
|
||||
if(len < (datalen - 10))
|
||||
want_reply = data[9 + len];
|
||||
@@ -945,6 +967,7 @@ _libssh2_packet_add(LIBSSH2_SESSION * session, unsigned char *data,
|
||||
if (!packetp) {
|
||||
_libssh2_debug(session, LIBSSH2_ERROR_ALLOC,
|
||||
"memory for packet");
|
||||
LIBSSH2_FREE(session, data);
|
||||
session->packAdd_state = libssh2_NB_state_idle;
|
||||
return LIBSSH2_ERROR_ALLOC;
|
||||
}
|
||||
@@ -1134,14 +1157,14 @@ _libssh2_packet_burn(LIBSSH2_SESSION * session,
|
||||
{
|
||||
unsigned char *data;
|
||||
size_t data_len;
|
||||
unsigned char all_packets[255];
|
||||
int i;
|
||||
unsigned char i, all_packets[255];
|
||||
int ret;
|
||||
|
||||
if (*state == libssh2_NB_state_idle) {
|
||||
for(i = 1; i < 256; i++) {
|
||||
for(i = 1; i < 255; i++) {
|
||||
all_packets[i - 1] = i;
|
||||
}
|
||||
all_packets[254] = 0;
|
||||
|
||||
if (_libssh2_packet_askv(session, all_packets, &data, &data_len, 0,
|
||||
NULL, 0) == 0) {
|
||||
@@ -1170,7 +1193,8 @@ _libssh2_packet_burn(LIBSSH2_SESSION * session,
|
||||
|
||||
/* Be lazy, let packet_ask pull it out of the brigade */
|
||||
if (0 ==
|
||||
_libssh2_packet_ask(session, ret, &data, &data_len, 0, NULL, 0)) {
|
||||
_libssh2_packet_ask(session, (unsigned char)ret,
|
||||
&data, &data_len, 0, NULL, 0)) {
|
||||
/* Smoke 'em if you got 'em */
|
||||
LIBSSH2_FREE(session, data);
|
||||
*state = libssh2_NB_state_idle;
|
||||
|
12
src/pem.c
12
src/pem.c
@@ -38,8 +38,6 @@
|
||||
|
||||
#include "libssh2_priv.h"
|
||||
|
||||
#ifdef LIBSSH2_LIBGCRYPT /* compile only if we build with libgcrypt */
|
||||
|
||||
static int
|
||||
readline(char *line, int line_size, FILE * fp)
|
||||
{
|
||||
@@ -69,6 +67,8 @@ _libssh2_pem_parse(LIBSSH2_SESSION * session,
|
||||
int ret;
|
||||
|
||||
do {
|
||||
*line = '\0';
|
||||
|
||||
if (readline(line, LINE_SIZE, fp)) {
|
||||
return -1;
|
||||
}
|
||||
@@ -93,12 +93,18 @@ _libssh2_pem_parse(LIBSSH2_SESSION * session,
|
||||
b64datalen += linelen;
|
||||
}
|
||||
|
||||
*line = '\0';
|
||||
|
||||
if (readline(line, LINE_SIZE, fp)) {
|
||||
ret = -1;
|
||||
goto out;
|
||||
}
|
||||
} while (strcmp(line, headerend) != 0);
|
||||
|
||||
if (!b64data) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (libssh2_base64_decode(session, (char**) data, datalen,
|
||||
b64data, b64datalen)) {
|
||||
ret = -1;
|
||||
@@ -209,5 +215,3 @@ _libssh2_pem_decode_integer(unsigned char **data, unsigned int *datalen,
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
#endif /* LIBSSH2_LIBGCRYPT */
|
||||
|
@@ -1,5 +1,5 @@
|
||||
/* Copyright (c) 2004-2007, Sara Golemon <sarag@libssh2.org>
|
||||
* Copyright (c) 2010 by Daniel Stenberg
|
||||
* Copyright (c) 2010-2014 by Daniel Stenberg
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms,
|
||||
@@ -136,6 +136,8 @@ publickey_packet_receive(LIBSSH2_PUBLICKEY * pkey,
|
||||
LIBSSH2_SESSION *session = channel->session;
|
||||
unsigned char buffer[4];
|
||||
int rc;
|
||||
*data = NULL; /* default to nothing returned */
|
||||
*data_len = 0;
|
||||
|
||||
if (pkey->receive_state == libssh2_NB_state_idle) {
|
||||
rc = _libssh2_channel_read(channel, 0, (char *) buffer, 4);
|
||||
@@ -348,13 +350,12 @@ static LIBSSH2_PUBLICKEY *publickey_init(LIBSSH2_SESSION *session)
|
||||
}
|
||||
|
||||
session->pkeyInit_pkey =
|
||||
LIBSSH2_ALLOC(session, sizeof(LIBSSH2_PUBLICKEY));
|
||||
LIBSSH2_CALLOC(session, sizeof(LIBSSH2_PUBLICKEY));
|
||||
if (!session->pkeyInit_pkey) {
|
||||
_libssh2_error(session, LIBSSH2_ERROR_ALLOC,
|
||||
"Unable to allocate a new publickey structure");
|
||||
goto err_exit;
|
||||
}
|
||||
memset(session->pkeyInit_pkey, 0, sizeof(LIBSSH2_PUBLICKEY));
|
||||
session->pkeyInit_pkey->channel = session->pkeyInit_channel;
|
||||
session->pkeyInit_pkey->version = 0;
|
||||
|
||||
@@ -384,7 +385,7 @@ static LIBSSH2_PUBLICKEY *publickey_init(LIBSSH2_SESSION *session)
|
||||
_libssh2_error(session, LIBSSH2_ERROR_EAGAIN,
|
||||
"Would block sending publickey version packet");
|
||||
return NULL;
|
||||
} else if (rc) {
|
||||
} else if (rc < 0) {
|
||||
_libssh2_error(session, rc,
|
||||
"Unable to send publickey version packet");
|
||||
goto err_exit;
|
||||
|
@@ -133,7 +133,7 @@ shell_quotearg(const char *path, unsigned char *buf,
|
||||
* Processing States:
|
||||
* UQSTRING: unquoted string: ... -- used for quoting exclamation
|
||||
* marks. This is the initial state
|
||||
* SQSTRING: single-qouted-string: '... -- any character may follow
|
||||
* SQSTRING: single-quoted-string: '... -- any character may follow
|
||||
* QSTRING: quoted string: "... -- only apostrophes may follow
|
||||
*/
|
||||
enum { UQSTRING, SQSTRING, QSTRING } state = UQSTRING;
|
||||
@@ -727,7 +727,7 @@ scp_recv(LIBSSH2_SESSION * session, const char *path, struct stat * sb)
|
||||
sb->st_mtime = session->scpRecv_mtime;
|
||||
sb->st_atime = session->scpRecv_atime;
|
||||
sb->st_size = session->scpRecv_size;
|
||||
sb->st_mode = session->scpRecv_mode;
|
||||
sb->st_mode = (unsigned short)session->scpRecv_mode;
|
||||
}
|
||||
|
||||
session->scpRecv_state = libssh2_NB_state_idle;
|
||||
@@ -957,7 +957,7 @@ scp_send(LIBSSH2_SESSION * session, const char *path, int mode,
|
||||
session->scpSend_response_len =
|
||||
snprintf((char *) session->scpSend_response,
|
||||
LIBSSH2_SCP_RESPONSE_BUFLEN, "C0%o %"
|
||||
LIBSSH2_INT64_T_FORMAT "u %s\n", mode,
|
||||
LIBSSH2_INT64_T_FORMAT " %s\n", mode,
|
||||
size, base);
|
||||
_libssh2_debug(session, LIBSSH2_TRACE_SCP, "Sent %s",
|
||||
session->scpSend_response);
|
||||
|
@@ -143,7 +143,7 @@ banner_receive(LIBSSH2_SESSION * session)
|
||||
|
||||
if (ret == 0) {
|
||||
session->socket_state = LIBSSH2_SOCKET_DISCONNECTED;
|
||||
return LIBSSH2_ERROR_SOCKET_RECV;
|
||||
return LIBSSH2_ERROR_SOCKET_DISCONNECT;
|
||||
}
|
||||
|
||||
if (c == '\0') {
|
||||
@@ -686,8 +686,13 @@ session_startup(LIBSSH2_SESSION *session, libssh2_socket_t sock)
|
||||
!get_socket_nonblocking(session->socket_fd);
|
||||
|
||||
if (session->socket_prev_blockstate) {
|
||||
/* If in blocking state chang to non-blocking */
|
||||
session_nonblock(session->socket_fd, 1);
|
||||
/* If in blocking state change to non-blocking */
|
||||
rc = session_nonblock(session->socket_fd, 1);
|
||||
if (rc) {
|
||||
return _libssh2_error(session, rc,
|
||||
"Failed changing socket's "
|
||||
"blocking state to non-blocking");
|
||||
}
|
||||
}
|
||||
|
||||
session->startup_state = libssh2_NB_state_created;
|
||||
@@ -834,7 +839,7 @@ session_free(LIBSSH2_SESSION *session)
|
||||
_libssh2_debug(session, LIBSSH2_TRACE_TRANS, "Freeing session resource",
|
||||
session->remote.banner);
|
||||
|
||||
session->state = libssh2_NB_state_created;
|
||||
session->free_state = libssh2_NB_state_created;
|
||||
}
|
||||
|
||||
if (session->free_state == libssh2_NB_state_created) {
|
||||
@@ -845,17 +850,17 @@ session_free(LIBSSH2_SESSION *session)
|
||||
return rc;
|
||||
}
|
||||
|
||||
session->state = libssh2_NB_state_sent;
|
||||
session->free_state = libssh2_NB_state_sent;
|
||||
}
|
||||
|
||||
if (session->state == libssh2_NB_state_sent) {
|
||||
if (session->free_state == libssh2_NB_state_sent) {
|
||||
while ((l = _libssh2_list_first(&session->listeners))) {
|
||||
rc = _libssh2_channel_forward_cancel(l);
|
||||
if (rc == LIBSSH2_ERROR_EAGAIN)
|
||||
return rc;
|
||||
}
|
||||
|
||||
session->state = libssh2_NB_state_sent1;
|
||||
session->free_state = libssh2_NB_state_sent1;
|
||||
}
|
||||
|
||||
if (session->state & LIBSSH2_STATE_NEWKEYS) {
|
||||
@@ -1016,6 +1021,14 @@ session_free(LIBSSH2_SESSION *session)
|
||||
if (session->scpSend_command) {
|
||||
LIBSSH2_FREE(session, session->scpSend_command);
|
||||
}
|
||||
if (session->sftpInit_sftp) {
|
||||
LIBSSH2_FREE(session, session->sftpInit_sftp);
|
||||
}
|
||||
|
||||
/* Free payload buffer */
|
||||
if (session->packet.total_num) {
|
||||
LIBSSH2_FREE(session, session->packet.payload);
|
||||
}
|
||||
|
||||
/* Cleanup all remaining packets */
|
||||
while ((pkg = _libssh2_list_first(&session->packets))) {
|
||||
@@ -1032,9 +1045,14 @@ session_free(LIBSSH2_SESSION *session)
|
||||
_libssh2_debug(session, LIBSSH2_TRACE_TRANS,
|
||||
"Extra packets left %d", packets_left);
|
||||
|
||||
if(session->socket_prev_blockstate)
|
||||
if(session->socket_prev_blockstate) {
|
||||
/* if the socket was previously blocking, put it back so */
|
||||
session_nonblock(session->socket_fd, 0);
|
||||
rc = session_nonblock(session->socket_fd, 0);
|
||||
if (rc) {
|
||||
_libssh2_debug(session, LIBSSH2_TRACE_TRANS,
|
||||
"unable to reset socket's blocking state");
|
||||
}
|
||||
}
|
||||
|
||||
if (session->server_hostkey) {
|
||||
LIBSSH2_FREE(session, session->server_hostkey);
|
||||
@@ -1514,7 +1532,7 @@ libssh2_poll(LIBSSH2_POLLFD * fds, unsigned int nfds, long timeout)
|
||||
}
|
||||
#else
|
||||
/* No select() or poll()
|
||||
* no sockets sturcture to setup
|
||||
* no sockets structure to setup
|
||||
*/
|
||||
|
||||
timeout = 0;
|
||||
|
391
src/sftp.c
391
src/sftp.c
@@ -1,6 +1,6 @@
|
||||
/* Copyright (c) 2004-2008, Sara Golemon <sarag@libssh2.org>
|
||||
* Copyright (c) 2007 Eli Fant <elifantu@mail.ru>
|
||||
* Copyright (c) 2009-2012 by Daniel Stenberg
|
||||
* Copyright (c) 2009-2014 by Daniel Stenberg
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms,
|
||||
@@ -93,7 +93,6 @@
|
||||
some kind of server problem. */
|
||||
#define LIBSSH2_SFTP_PACKET_MAXLEN 80000
|
||||
|
||||
static int sftp_close_handle(LIBSSH2_SFTP_HANDLE *handle);
|
||||
static int sftp_packet_ask(LIBSSH2_SFTP *sftp, unsigned char packet_type,
|
||||
uint32_t request_id, unsigned char **data,
|
||||
size_t *data_len);
|
||||
@@ -132,6 +131,66 @@ static void _libssh2_store_u64(unsigned char **ptr, libssh2_uint64_t value)
|
||||
*ptr += 8;
|
||||
}
|
||||
|
||||
/*
|
||||
* Search list of zombied FXP_READ request IDs.
|
||||
*
|
||||
* Returns NULL if ID not in list.
|
||||
*/
|
||||
static struct sftp_zombie_requests *
|
||||
find_zombie_request(LIBSSH2_SFTP *sftp, uint32_t request_id)
|
||||
{
|
||||
struct sftp_zombie_requests *zombie =
|
||||
_libssh2_list_first(&sftp->zombie_requests);
|
||||
|
||||
while(zombie) {
|
||||
if(zombie->request_id == request_id)
|
||||
break;
|
||||
else
|
||||
zombie = _libssh2_list_next(&zombie->node);
|
||||
}
|
||||
|
||||
return zombie;
|
||||
}
|
||||
|
||||
static void
|
||||
remove_zombie_request(LIBSSH2_SFTP *sftp, uint32_t request_id)
|
||||
{
|
||||
LIBSSH2_SESSION *session = sftp->channel->session;
|
||||
|
||||
struct sftp_zombie_requests *zombie = find_zombie_request(sftp,
|
||||
request_id);
|
||||
if(zombie) {
|
||||
_libssh2_debug(session, LIBSSH2_TRACE_SFTP,
|
||||
"Removing request ID %ld from the list of zombie requests",
|
||||
request_id);
|
||||
|
||||
_libssh2_list_remove(&zombie->node);
|
||||
LIBSSH2_FREE(session, zombie);
|
||||
}
|
||||
}
|
||||
|
||||
static int
|
||||
add_zombie_request(LIBSSH2_SFTP *sftp, uint32_t request_id)
|
||||
{
|
||||
LIBSSH2_SESSION *session = sftp->channel->session;
|
||||
|
||||
struct sftp_zombie_requests *zombie;
|
||||
|
||||
_libssh2_debug(session, LIBSSH2_TRACE_SFTP,
|
||||
"Marking request ID %ld as a zombie request", request_id);
|
||||
|
||||
zombie = LIBSSH2_ALLOC(sftp->channel->session,
|
||||
sizeof(struct sftp_zombie_requests));
|
||||
if (!zombie)
|
||||
return _libssh2_error(session, LIBSSH2_ERROR_ALLOC,
|
||||
"malloc fail for zombie request ID");
|
||||
else {
|
||||
zombie->request_id = request_id;
|
||||
_libssh2_list_add(&sftp->zombie_requests, &zombie->node);
|
||||
return LIBSSH2_ERROR_NONE;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* sftp_packet_add
|
||||
*
|
||||
@@ -143,6 +202,7 @@ sftp_packet_add(LIBSSH2_SFTP *sftp, unsigned char *data,
|
||||
{
|
||||
LIBSSH2_SESSION *session = sftp->channel->session;
|
||||
LIBSSH2_SFTP_PACKET *packet;
|
||||
uint32_t request_id;
|
||||
|
||||
_libssh2_debug(session, LIBSSH2_TRACE_SFTP, "Received packet %d (len %d)",
|
||||
(int) data[0], data_len);
|
||||
@@ -188,6 +248,21 @@ sftp_packet_add(LIBSSH2_SFTP *sftp, unsigned char *data,
|
||||
"Out of sync with the world");
|
||||
}
|
||||
|
||||
request_id = _libssh2_ntohu32(&data[1]);
|
||||
|
||||
/* Don't add the packet if it answers a request we've given up on. */
|
||||
if((data[0] == SSH_FXP_STATUS || data[0] == SSH_FXP_DATA)
|
||||
&& find_zombie_request(sftp, request_id)) {
|
||||
|
||||
/* If we get here, the file ended before the response arrived. We
|
||||
are no longer interested in the request so we discard it */
|
||||
|
||||
LIBSSH2_FREE(session, data);
|
||||
|
||||
remove_zombie_request(sftp, request_id);
|
||||
return LIBSSH2_ERROR_NONE;
|
||||
}
|
||||
|
||||
packet = LIBSSH2_ALLOC(session, sizeof(LIBSSH2_SFTP_PACKET));
|
||||
if (!packet) {
|
||||
return _libssh2_error(session, LIBSSH2_ERROR_ALLOC,
|
||||
@@ -196,7 +271,7 @@ sftp_packet_add(LIBSSH2_SFTP *sftp, unsigned char *data,
|
||||
|
||||
packet->data = data;
|
||||
packet->data_len = data_len;
|
||||
packet->request_id = _libssh2_ntohu32(&data[1]);
|
||||
packet->request_id = request_id;
|
||||
|
||||
_libssh2_list_add(&sftp->packets, &packet->node);
|
||||
|
||||
@@ -216,6 +291,7 @@ sftp_packet_read(LIBSSH2_SFTP *sftp)
|
||||
unsigned char *packet = NULL;
|
||||
ssize_t rc;
|
||||
unsigned long recv_window;
|
||||
int packet_type;
|
||||
|
||||
_libssh2_debug(session, LIBSSH2_TRACE_SFTP, "recv packet");
|
||||
|
||||
@@ -324,13 +400,17 @@ sftp_packet_read(LIBSSH2_SFTP *sftp)
|
||||
|
||||
sftp->partial_packet = NULL;
|
||||
|
||||
/* sftp_packet_add takes ownership of the packet and might free it
|
||||
so we take a copy of the packet type before we call it. */
|
||||
packet_type = packet[0];
|
||||
rc = sftp_packet_add(sftp, packet, sftp->partial_len);
|
||||
if (rc) {
|
||||
LIBSSH2_FREE(session, packet);
|
||||
return rc;
|
||||
}
|
||||
|
||||
return packet[0];
|
||||
else {
|
||||
return packet_type;
|
||||
}
|
||||
}
|
||||
/* WON'T REACH */
|
||||
}
|
||||
@@ -363,6 +443,10 @@ static void sftp_packetlist_flush(LIBSSH2_SFTP_HANDLE *handle)
|
||||
if(!rc)
|
||||
/* we found a packet, free it */
|
||||
LIBSSH2_FREE(session, data);
|
||||
else if(chunk->sent)
|
||||
/* there was no incoming packet for this request, mark this
|
||||
request as a zombie if it ever sent the request */
|
||||
add_zombie_request(sftp, chunk->request_id);
|
||||
|
||||
_libssh2_list_remove(&chunk->node);
|
||||
LIBSSH2_FREE(session, chunk);
|
||||
@@ -433,10 +517,7 @@ sftp_packet_require(LIBSSH2_SFTP *sftp, unsigned char packet_type,
|
||||
|
||||
while (session->socket_state == LIBSSH2_SOCKET_CONNECTED) {
|
||||
rc = sftp_packet_read(sftp);
|
||||
if (rc == LIBSSH2_ERROR_EAGAIN)
|
||||
return rc;
|
||||
else if (rc <= 0)
|
||||
/* TODO: isn't this supposed to be < 0 only? */
|
||||
if (rc < 0)
|
||||
return rc;
|
||||
|
||||
/* data was read, check the queue again */
|
||||
@@ -453,7 +534,7 @@ sftp_packet_require(LIBSSH2_SFTP *sftp, unsigned char packet_type,
|
||||
}
|
||||
|
||||
/* sftp_packet_requirev
|
||||
* Require one of N possible reponses
|
||||
* Require one of N possible responses
|
||||
*/
|
||||
static int
|
||||
sftp_packet_requirev(LIBSSH2_SFTP *sftp, int num_valid_responses,
|
||||
@@ -639,7 +720,7 @@ static LIBSSH2_SFTP *sftp_init(LIBSSH2_SESSION *session)
|
||||
*
|
||||
* Note that you MUST NOT try to call libssh2_sftp_init() again to get
|
||||
* another handle until the previous call has finished and either
|
||||
* succesffully made a handle or failed and returned error (not
|
||||
* successfully made a handle or failed and returned error (not
|
||||
* including *EAGAIN).
|
||||
*/
|
||||
|
||||
@@ -700,13 +781,12 @@ static LIBSSH2_SFTP *sftp_init(LIBSSH2_SESSION *session)
|
||||
|
||||
sftp_handle =
|
||||
session->sftpInit_sftp =
|
||||
LIBSSH2_ALLOC(session, sizeof(LIBSSH2_SFTP));
|
||||
LIBSSH2_CALLOC(session, sizeof(LIBSSH2_SFTP));
|
||||
if (!sftp_handle) {
|
||||
_libssh2_error(session, LIBSSH2_ERROR_ALLOC,
|
||||
"Unable to allocate a new SFTP structure");
|
||||
goto sftp_init_error;
|
||||
}
|
||||
memset(sftp_handle, 0, sizeof(LIBSSH2_SFTP));
|
||||
sftp_handle->channel = session->sftpInit_channel;
|
||||
sftp_handle->request_id = 0;
|
||||
|
||||
@@ -762,6 +842,7 @@ static LIBSSH2_SFTP *sftp_init(LIBSSH2_SESSION *session)
|
||||
if (data_len < 5) {
|
||||
_libssh2_error(session, LIBSSH2_ERROR_SFTP_PROTOCOL,
|
||||
"Invalid SSH_FXP_VERSION response");
|
||||
LIBSSH2_FREE(session, data);
|
||||
goto sftp_init_error;
|
||||
}
|
||||
|
||||
@@ -775,7 +856,7 @@ static LIBSSH2_SFTP *sftp_init(LIBSSH2_SESSION *session)
|
||||
sftp_handle->version = LIBSSH2_SFTP_VERSION;
|
||||
}
|
||||
_libssh2_debug(session, LIBSSH2_TRACE_SFTP,
|
||||
"Enabling SFTP version %lu compatability",
|
||||
"Enabling SFTP version %lu compatibility",
|
||||
sftp_handle->version);
|
||||
while (s < (data + data_len)) {
|
||||
size_t extname_len, extdata_len;
|
||||
@@ -846,7 +927,7 @@ LIBSSH2_API LIBSSH2_SFTP *libssh2_sftp_init(LIBSSH2_SESSION *session)
|
||||
/*
|
||||
* sftp_shutdown
|
||||
*
|
||||
* Shutsdown the SFTP subsystem
|
||||
* Shuts down the SFTP subsystem
|
||||
*/
|
||||
static int
|
||||
sftp_shutdown(LIBSSH2_SFTP *sftp)
|
||||
@@ -904,6 +985,10 @@ sftp_shutdown(LIBSSH2_SFTP *sftp)
|
||||
LIBSSH2_FREE(session, sftp->symlink_packet);
|
||||
sftp->symlink_packet = NULL;
|
||||
}
|
||||
if (sftp->fsync_packet) {
|
||||
LIBSSH2_FREE(session, sftp->fsync_packet);
|
||||
sftp->fsync_packet = NULL;
|
||||
}
|
||||
|
||||
sftp_packet_flush(sftp);
|
||||
|
||||
@@ -1087,14 +1172,13 @@ sftp_open(LIBSSH2_SFTP *sftp, const char *filename,
|
||||
return NULL;
|
||||
}
|
||||
|
||||
fp = LIBSSH2_ALLOC(session, sizeof(LIBSSH2_SFTP_HANDLE));
|
||||
fp = LIBSSH2_CALLOC(session, sizeof(LIBSSH2_SFTP_HANDLE));
|
||||
if (!fp) {
|
||||
_libssh2_error(session, LIBSSH2_ERROR_ALLOC,
|
||||
"Unable to allocate new SFTP handle structure");
|
||||
LIBSSH2_FREE(session, data);
|
||||
return NULL;
|
||||
}
|
||||
memset(fp, 0, sizeof(LIBSSH2_SFTP_HANDLE));
|
||||
fp->handle_type = open_file ? LIBSSH2_SFTP_HANDLE_FILE :
|
||||
LIBSSH2_SFTP_HANDLE_DIR;
|
||||
|
||||
@@ -1377,6 +1461,11 @@ static ssize_t sftp_read(LIBSSH2_SFTP_HANDLE * handle, char *buffer,
|
||||
|
||||
switch (data[0]) {
|
||||
case SSH_FXP_STATUS:
|
||||
/* remove the chunk we just processed */
|
||||
|
||||
_libssh2_list_remove(&chunk->node);
|
||||
LIBSSH2_FREE(session, chunk);
|
||||
|
||||
/* we must remove all outstanding READ requests, as either we
|
||||
got an error or we're at end of file */
|
||||
sftp_packetlist_flush(handle);
|
||||
@@ -1401,6 +1490,14 @@ static ssize_t sftp_read(LIBSSH2_SFTP_HANDLE * handle, char *buffer,
|
||||
return _libssh2_error(session, LIBSSH2_ERROR_SFTP_PROTOCOL,
|
||||
"SFTP Protocol badness");
|
||||
|
||||
if(rc32 > chunk->len) {
|
||||
/* A chunk larger than we requested was returned to us.
|
||||
This is a protocol violation and we don't know how to
|
||||
deal with it. Bail out! */
|
||||
return _libssh2_error(session, LIBSSH2_ERROR_SFTP_PROTOCOL,
|
||||
"FXP_READ response too big");
|
||||
}
|
||||
|
||||
if(rc32 != chunk->len) {
|
||||
/* a short read does not imply end of file, but we must
|
||||
adjust the offset_sent since it was advanced with a
|
||||
@@ -1521,7 +1618,7 @@ static ssize_t sftp_readdir(LIBSSH2_SFTP_HANDLE *handle, char *buffer,
|
||||
|
||||
filename_len = real_filename_len;
|
||||
if (filename_len >= buffer_maxlen) {
|
||||
filename_len = LIBSSH2_ERROR_BUFFER_TOO_SMALL;
|
||||
filename_len = (size_t)LIBSSH2_ERROR_BUFFER_TOO_SMALL;
|
||||
goto end;
|
||||
}
|
||||
|
||||
@@ -1536,7 +1633,7 @@ static ssize_t sftp_readdir(LIBSSH2_SFTP_HANDLE *handle, char *buffer,
|
||||
longentry_len = real_longentry_len;
|
||||
|
||||
if (longentry_len >= longentry_maxlen) {
|
||||
filename_len = LIBSSH2_ERROR_BUFFER_TOO_SMALL;
|
||||
filename_len = (size_t)LIBSSH2_ERROR_BUFFER_TOO_SMALL;
|
||||
goto end;
|
||||
}
|
||||
|
||||
@@ -1860,7 +1957,7 @@ static ssize_t sftp_write(LIBSSH2_SFTP_HANDLE *handle, const char *buffer,
|
||||
/* flush all pending packets from the outgoing list */
|
||||
sftp_packetlist_flush(handle);
|
||||
|
||||
/* since we return error now, the applicaton will not get any
|
||||
/* since we return error now, the application will not get any
|
||||
outstanding data acked, so we need to rewind the offset to
|
||||
where the application knows it has reached with acked data */
|
||||
handle->u.file.offset -= handle->u.file.acked;
|
||||
@@ -1919,6 +2016,99 @@ libssh2_sftp_write(LIBSSH2_SFTP_HANDLE *hnd, const char *buffer,
|
||||
|
||||
}
|
||||
|
||||
static int sftp_fsync(LIBSSH2_SFTP_HANDLE *handle)
|
||||
{
|
||||
LIBSSH2_SFTP *sftp = handle->sftp;
|
||||
LIBSSH2_CHANNEL *channel = sftp->channel;
|
||||
LIBSSH2_SESSION *session = channel->session;
|
||||
/* 34 = packet_len(4) + packet_type(1) + request_id(4) +
|
||||
string_len(4) + strlen("fsync@openssh.com")(17) + handle_len(4) */
|
||||
uint32_t packet_len = handle->handle_len + 34;
|
||||
size_t data_len;
|
||||
unsigned char *packet, *s, *data;
|
||||
ssize_t rc;
|
||||
uint32_t retcode;
|
||||
|
||||
if (sftp->fsync_state == libssh2_NB_state_idle) {
|
||||
_libssh2_debug(session, LIBSSH2_TRACE_SFTP,
|
||||
"Issuing fsync command");
|
||||
s = packet = LIBSSH2_ALLOC(session, packet_len);
|
||||
if (!packet) {
|
||||
return _libssh2_error(session, LIBSSH2_ERROR_ALLOC,
|
||||
"Unable to allocate memory for FXP_EXTENDED "
|
||||
"packet");
|
||||
}
|
||||
|
||||
_libssh2_store_u32(&s, packet_len - 4);
|
||||
*(s++) = SSH_FXP_EXTENDED;
|
||||
sftp->fsync_request_id = sftp->request_id++;
|
||||
_libssh2_store_u32(&s, sftp->fsync_request_id);
|
||||
_libssh2_store_str(&s, "fsync@openssh.com", 17);
|
||||
_libssh2_store_str(&s, handle->handle, handle->handle_len);
|
||||
|
||||
sftp->fsync_state = libssh2_NB_state_created;
|
||||
} else {
|
||||
packet = sftp->fsync_packet;
|
||||
}
|
||||
|
||||
if (sftp->fsync_state == libssh2_NB_state_created) {
|
||||
rc = _libssh2_channel_write(channel, 0, packet, packet_len);
|
||||
if (rc == LIBSSH2_ERROR_EAGAIN ||
|
||||
(0 <= rc && rc < (ssize_t)packet_len)) {
|
||||
sftp->fsync_packet = packet;
|
||||
return LIBSSH2_ERROR_EAGAIN;
|
||||
}
|
||||
|
||||
LIBSSH2_FREE(session, packet);
|
||||
sftp->fsync_packet = NULL;
|
||||
|
||||
if (rc < 0) {
|
||||
sftp->fsync_state = libssh2_NB_state_idle;
|
||||
return _libssh2_error(session, LIBSSH2_ERROR_SOCKET_SEND,
|
||||
"_libssh2_channel_write() failed");
|
||||
}
|
||||
sftp->fsync_state = libssh2_NB_state_sent;
|
||||
}
|
||||
|
||||
rc = sftp_packet_require(sftp, SSH_FXP_STATUS,
|
||||
sftp->fsync_request_id, &data, &data_len);
|
||||
if (rc == LIBSSH2_ERROR_EAGAIN) {
|
||||
return rc;
|
||||
} else if (rc) {
|
||||
sftp->fsync_state = libssh2_NB_state_idle;
|
||||
return _libssh2_error(session, rc,
|
||||
"Error waiting for FXP EXTENDED REPLY");
|
||||
}
|
||||
|
||||
sftp->fsync_state = libssh2_NB_state_idle;
|
||||
|
||||
retcode = _libssh2_ntohu32(data + 5);
|
||||
LIBSSH2_FREE(session, data);
|
||||
|
||||
if (retcode != LIBSSH2_FX_OK) {
|
||||
sftp->last_errno = retcode;
|
||||
return _libssh2_error(session, LIBSSH2_ERROR_SFTP_PROTOCOL,
|
||||
"fsync failed");
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* libssh2_sftp_fsync
|
||||
* Commit data on the handle to disk.
|
||||
*/
|
||||
LIBSSH2_API int
|
||||
libssh2_sftp_fsync(LIBSSH2_SFTP_HANDLE *hnd)
|
||||
{
|
||||
int rc;
|
||||
if(!hnd)
|
||||
return LIBSSH2_ERROR_BAD_USE;
|
||||
BLOCK_ADJUST(rc, hnd->sftp->channel->session,
|
||||
sftp_fsync(hnd));
|
||||
return rc;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* sftp_fstat
|
||||
*
|
||||
@@ -2037,21 +2227,24 @@ libssh2_sftp_fstat_ex(LIBSSH2_SFTP_HANDLE *hnd,
|
||||
LIBSSH2_API void
|
||||
libssh2_sftp_seek64(LIBSSH2_SFTP_HANDLE *handle, libssh2_uint64_t offset)
|
||||
{
|
||||
if(handle) {
|
||||
handle->u.file.offset = handle->u.file.offset_sent = offset;
|
||||
/* discard all pending requests and currently read data */
|
||||
sftp_packetlist_flush(handle);
|
||||
if(!handle)
|
||||
return;
|
||||
if(handle->u.file.offset == offset && handle->u.file.offset_sent == offset)
|
||||
return;
|
||||
|
||||
/* free the left received buffered data */
|
||||
if (handle->u.file.data_left) {
|
||||
LIBSSH2_FREE(handle->sftp->channel->session, handle->u.file.data);
|
||||
handle->u.file.data_left = handle->u.file.data_len = 0;
|
||||
handle->u.file.data = NULL;
|
||||
}
|
||||
handle->u.file.offset = handle->u.file.offset_sent = offset;
|
||||
/* discard all pending requests and currently read data */
|
||||
sftp_packetlist_flush(handle);
|
||||
|
||||
/* reset EOF to False */
|
||||
handle->u.file.eof = FALSE;
|
||||
/* free the left received buffered data */
|
||||
if (handle->u.file.data_left) {
|
||||
LIBSSH2_FREE(handle->sftp->channel->session, handle->u.file.data);
|
||||
handle->u.file.data_left = handle->u.file.data_len = 0;
|
||||
handle->u.file.data = NULL;
|
||||
}
|
||||
|
||||
/* reset EOF to False */
|
||||
handle->u.file.eof = FALSE;
|
||||
}
|
||||
|
||||
/* libssh2_sftp_seek
|
||||
@@ -2091,13 +2284,15 @@ libssh2_sftp_tell64(LIBSSH2_SFTP_HANDLE *handle)
|
||||
}
|
||||
|
||||
/*
|
||||
* Flush all remaining incoming SFTP packets.
|
||||
* Flush all remaining incoming SFTP packets and zombies.
|
||||
*/
|
||||
static void sftp_packet_flush(LIBSSH2_SFTP *sftp)
|
||||
{
|
||||
LIBSSH2_CHANNEL *channel = sftp->channel;
|
||||
LIBSSH2_SESSION *session = channel->session;
|
||||
LIBSSH2_SFTP_PACKET *packet = _libssh2_list_first(&sftp->packets);
|
||||
struct sftp_zombie_requests *zombie =
|
||||
_libssh2_list_first(&sftp->zombie_requests);
|
||||
|
||||
while(packet) {
|
||||
LIBSSH2_SFTP_PACKET *next;
|
||||
@@ -2111,12 +2306,25 @@ static void sftp_packet_flush(LIBSSH2_SFTP *sftp)
|
||||
packet = next;
|
||||
}
|
||||
|
||||
while(zombie) {
|
||||
/* figure out the next node */
|
||||
struct sftp_zombie_requests *next = _libssh2_list_next(&zombie->node);
|
||||
/* unlink the current one */
|
||||
_libssh2_list_remove(&zombie->node);
|
||||
/* free the memory */
|
||||
LIBSSH2_FREE(session, zombie);
|
||||
zombie = next;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/* sftp_close_handle
|
||||
*
|
||||
* Close a file or directory handle
|
||||
* Also frees handle resource and unlinks it from the SFTP structure
|
||||
* Close a file or directory handle.
|
||||
* Also frees handle resource and unlinks it from the SFTP structure.
|
||||
* The handle is no longer usable after return of this function, unless
|
||||
* the return value is LIBSSH2_ERROR_EAGAIN in which case this function
|
||||
* should be called again.
|
||||
*/
|
||||
static int
|
||||
sftp_close_handle(LIBSSH2_SFTP_HANDLE *handle)
|
||||
@@ -2125,27 +2333,28 @@ sftp_close_handle(LIBSSH2_SFTP_HANDLE *handle)
|
||||
LIBSSH2_CHANNEL *channel = sftp->channel;
|
||||
LIBSSH2_SESSION *session = channel->session;
|
||||
size_t data_len;
|
||||
int retcode;
|
||||
/* 13 = packet_len(4) + packet_type(1) + request_id(4) + handle_len(4) */
|
||||
uint32_t packet_len = handle->handle_len + 13;
|
||||
unsigned char *s, *data = NULL;
|
||||
int rc;
|
||||
int rc = 0;
|
||||
|
||||
if (handle->close_state == libssh2_NB_state_idle) {
|
||||
_libssh2_debug(session, LIBSSH2_TRACE_SFTP, "Closing handle");
|
||||
s = handle->close_packet = LIBSSH2_ALLOC(session, packet_len);
|
||||
if (!handle->close_packet) {
|
||||
return _libssh2_error(session, LIBSSH2_ERROR_ALLOC,
|
||||
"Unable to allocate memory for FXP_CLOSE "
|
||||
"packet");
|
||||
}
|
||||
handle->close_state = libssh2_NB_state_idle;
|
||||
rc = _libssh2_error(session, LIBSSH2_ERROR_ALLOC,
|
||||
"Unable to allocate memory for FXP_CLOSE "
|
||||
"packet");
|
||||
} else {
|
||||
|
||||
_libssh2_store_u32(&s, packet_len - 4);
|
||||
*(s++) = SSH_FXP_CLOSE;
|
||||
handle->close_request_id = sftp->request_id++;
|
||||
_libssh2_store_u32(&s, handle->close_request_id);
|
||||
_libssh2_store_str(&s, handle->handle, handle->handle_len);
|
||||
handle->close_state = libssh2_NB_state_created;
|
||||
_libssh2_store_u32(&s, packet_len - 4);
|
||||
*(s++) = SSH_FXP_CLOSE;
|
||||
handle->close_request_id = sftp->request_id++;
|
||||
_libssh2_store_u32(&s, handle->close_request_id);
|
||||
_libssh2_store_str(&s, handle->handle, handle->handle_len);
|
||||
handle->close_state = libssh2_NB_state_created;
|
||||
}
|
||||
}
|
||||
|
||||
if (handle->close_state == libssh2_NB_state_created) {
|
||||
@@ -2154,16 +2363,14 @@ sftp_close_handle(LIBSSH2_SFTP_HANDLE *handle)
|
||||
if (rc == LIBSSH2_ERROR_EAGAIN) {
|
||||
return rc;
|
||||
} else if ((ssize_t)packet_len != rc) {
|
||||
LIBSSH2_FREE(session, handle->close_packet);
|
||||
handle->close_packet = NULL;
|
||||
handle->close_state = libssh2_NB_state_idle;
|
||||
return _libssh2_error(session, LIBSSH2_ERROR_SOCKET_SEND,
|
||||
"Unable to send FXP_CLOSE command");
|
||||
}
|
||||
rc = _libssh2_error(session, LIBSSH2_ERROR_SOCKET_SEND,
|
||||
"Unable to send FXP_CLOSE command");
|
||||
} else
|
||||
handle->close_state = libssh2_NB_state_sent;
|
||||
|
||||
LIBSSH2_FREE(session, handle->close_packet);
|
||||
handle->close_packet = NULL;
|
||||
|
||||
handle->close_state = libssh2_NB_state_sent;
|
||||
}
|
||||
|
||||
if (handle->close_state == libssh2_NB_state_sent) {
|
||||
@@ -2172,29 +2379,30 @@ sftp_close_handle(LIBSSH2_SFTP_HANDLE *handle)
|
||||
&data_len);
|
||||
if (rc == LIBSSH2_ERROR_EAGAIN) {
|
||||
return rc;
|
||||
|
||||
} else if (rc) {
|
||||
handle->close_state = libssh2_NB_state_idle;
|
||||
return _libssh2_error(session, rc,
|
||||
"Error waiting for status message");
|
||||
_libssh2_error(session, rc,
|
||||
"Error waiting for status message");
|
||||
}
|
||||
|
||||
handle->close_state = libssh2_NB_state_sent1;
|
||||
}
|
||||
|
||||
if(!data)
|
||||
if(!data) {
|
||||
/* if it reaches this point with data unset, something unwanted
|
||||
happened (like this function is called again when in
|
||||
libssh2_NB_state_sent1 state) and we just bail out */
|
||||
return LIBSSH2_ERROR_INVAL;
|
||||
happened for which we should have set an error code */
|
||||
assert(rc);
|
||||
|
||||
retcode = _libssh2_ntohu32(data + 5);
|
||||
LIBSSH2_FREE(session, data);
|
||||
} else {
|
||||
int retcode = _libssh2_ntohu32(data + 5);
|
||||
LIBSSH2_FREE(session, data);
|
||||
|
||||
if (retcode != LIBSSH2_FX_OK) {
|
||||
sftp->last_errno = retcode;
|
||||
handle->close_state = libssh2_NB_state_idle;
|
||||
return _libssh2_error(session, LIBSSH2_ERROR_SFTP_PROTOCOL,
|
||||
"SFTP Protocol Error");
|
||||
if (retcode != LIBSSH2_FX_OK) {
|
||||
sftp->last_errno = retcode;
|
||||
handle->close_state = libssh2_NB_state_idle;
|
||||
rc = _libssh2_error(session, LIBSSH2_ERROR_SFTP_PROTOCOL,
|
||||
"SFTP Protocol Error");
|
||||
}
|
||||
}
|
||||
|
||||
/* remove this handle from the parent's list */
|
||||
@@ -2216,7 +2424,7 @@ sftp_close_handle(LIBSSH2_SFTP_HANDLE *handle)
|
||||
|
||||
LIBSSH2_FREE(session, handle);
|
||||
|
||||
return 0;
|
||||
return rc;
|
||||
}
|
||||
|
||||
/* libssh2_sftp_close_handle
|
||||
@@ -2476,6 +2684,8 @@ static int sftp_fstatvfs(LIBSSH2_SFTP_HANDLE *handle, LIBSSH2_SFTP_STATVFS *st)
|
||||
unsigned char *packet, *s, *data;
|
||||
ssize_t rc;
|
||||
unsigned int flag;
|
||||
static const unsigned char responses[2] =
|
||||
{ SSH_FXP_EXTENDED_REPLY, SSH_FXP_STATUS };
|
||||
|
||||
if (sftp->fstatvfs_state == libssh2_NB_state_idle) {
|
||||
_libssh2_debug(session, LIBSSH2_TRACE_SFTP,
|
||||
@@ -2519,15 +2729,27 @@ static int sftp_fstatvfs(LIBSSH2_SFTP_HANDLE *handle, LIBSSH2_SFTP_STATVFS *st)
|
||||
sftp->fstatvfs_state = libssh2_NB_state_sent;
|
||||
}
|
||||
|
||||
rc = sftp_packet_require(sftp, SSH_FXP_EXTENDED_REPLY,
|
||||
sftp->fstatvfs_request_id, &data, &data_len);
|
||||
rc = sftp_packet_requirev(sftp, 2, responses, sftp->fstatvfs_request_id,
|
||||
&data, &data_len);
|
||||
|
||||
if (rc == LIBSSH2_ERROR_EAGAIN) {
|
||||
return rc;
|
||||
} else if (rc) {
|
||||
sftp->fstatvfs_state = libssh2_NB_state_idle;
|
||||
return _libssh2_error(session, rc,
|
||||
"Error waiting for FXP EXTENDED REPLY");
|
||||
} else if (data_len < 93) {
|
||||
}
|
||||
|
||||
if (data[0] == SSH_FXP_STATUS) {
|
||||
int retcode = _libssh2_ntohu32(data + 5);
|
||||
sftp->fstatvfs_state = libssh2_NB_state_idle;
|
||||
LIBSSH2_FREE(session, data);
|
||||
sftp->last_errno = retcode;
|
||||
return _libssh2_error(session, LIBSSH2_ERROR_SFTP_PROTOCOL,
|
||||
"SFTP Protocol Error");
|
||||
}
|
||||
|
||||
if (data_len < 93) {
|
||||
LIBSSH2_FREE(session, data);
|
||||
sftp->fstatvfs_state = libssh2_NB_state_idle;
|
||||
return _libssh2_error(session, LIBSSH2_ERROR_SFTP_PROTOCOL,
|
||||
@@ -2549,9 +2771,9 @@ static int sftp_fstatvfs(LIBSSH2_SFTP_HANDLE *handle, LIBSSH2_SFTP_STATVFS *st)
|
||||
st->f_namemax = _libssh2_ntohu64(data + 85);
|
||||
|
||||
st->f_flag = (flag & SSH_FXE_STATVFS_ST_RDONLY)
|
||||
? LIBSSH2_SFTP_ST_RDONLY : 0;
|
||||
? LIBSSH2_SFTP_ST_RDONLY : 0;
|
||||
st->f_flag |= (flag & SSH_FXE_STATVFS_ST_NOSUID)
|
||||
? LIBSSH2_SFTP_ST_NOSUID : 0;
|
||||
? LIBSSH2_SFTP_ST_NOSUID : 0;
|
||||
|
||||
LIBSSH2_FREE(session, data);
|
||||
return 0;
|
||||
@@ -2589,6 +2811,8 @@ static int sftp_statvfs(LIBSSH2_SFTP *sftp, const char *path,
|
||||
unsigned char *packet, *s, *data;
|
||||
ssize_t rc;
|
||||
unsigned int flag;
|
||||
static const unsigned char responses[2] =
|
||||
{ SSH_FXP_EXTENDED_REPLY, SSH_FXP_STATUS };
|
||||
|
||||
if (sftp->statvfs_state == libssh2_NB_state_idle) {
|
||||
_libssh2_debug(session, LIBSSH2_TRACE_SFTP,
|
||||
@@ -2632,17 +2856,28 @@ static int sftp_statvfs(LIBSSH2_SFTP *sftp, const char *path,
|
||||
sftp->statvfs_state = libssh2_NB_state_sent;
|
||||
}
|
||||
|
||||
rc = sftp_packet_require(sftp, SSH_FXP_EXTENDED_REPLY,
|
||||
sftp->statvfs_request_id, &data, &data_len);
|
||||
rc = sftp_packet_requirev(sftp, 2, responses, sftp->statvfs_request_id,
|
||||
&data, &data_len);
|
||||
if (rc == LIBSSH2_ERROR_EAGAIN) {
|
||||
return rc;
|
||||
} else if (rc) {
|
||||
sftp->statvfs_state = libssh2_NB_state_idle;
|
||||
return _libssh2_error(session, rc,
|
||||
"Error waiting for FXP EXTENDED REPLY");
|
||||
} else if (data_len < 93) {
|
||||
}
|
||||
|
||||
if (data[0] == SSH_FXP_STATUS) {
|
||||
int retcode = _libssh2_ntohu32(data + 5);
|
||||
sftp->statvfs_state = libssh2_NB_state_idle;
|
||||
LIBSSH2_FREE(session, data);
|
||||
sftp->fstatvfs_state = libssh2_NB_state_idle;
|
||||
sftp->last_errno = retcode;
|
||||
return _libssh2_error(session, LIBSSH2_ERROR_SFTP_PROTOCOL,
|
||||
"SFTP Protocol Error");
|
||||
}
|
||||
|
||||
if (data_len < 93) {
|
||||
LIBSSH2_FREE(session, data);
|
||||
sftp->statvfs_state = libssh2_NB_state_idle;
|
||||
return _libssh2_error(session, LIBSSH2_ERROR_SFTP_PROTOCOL,
|
||||
"SFTP Protocol Error: short response");
|
||||
}
|
||||
|
13
src/sftp.h
13
src/sftp.h
@@ -60,6 +60,11 @@ struct sftp_pipeline_chunk {
|
||||
unsigned char packet[1]; /* data */
|
||||
};
|
||||
|
||||
struct sftp_zombie_requests {
|
||||
struct list_node node;
|
||||
uint32_t request_id;
|
||||
};
|
||||
|
||||
#ifndef MIN
|
||||
#define MIN(x,y) ((x)<(y)?(x):(y))
|
||||
#endif
|
||||
@@ -136,6 +141,9 @@ struct _LIBSSH2_SFTP
|
||||
|
||||
struct list_head packets;
|
||||
|
||||
/* List of FXP_READ responses to ignore because EOF already received. */
|
||||
struct list_head zombie_requests;
|
||||
|
||||
/* a list of _LIBSSH2_SFTP_HANDLE structs */
|
||||
struct list_head sftp_handles;
|
||||
|
||||
@@ -167,6 +175,11 @@ struct _LIBSSH2_SFTP
|
||||
/* State variable used in sftp_write() */
|
||||
libssh2_nonblocking_states write_state;
|
||||
|
||||
/* State variables used in sftp_fsync() */
|
||||
libssh2_nonblocking_states fsync_state;
|
||||
unsigned char *fsync_packet;
|
||||
uint32_t fsync_request_id;
|
||||
|
||||
/* State variables used in libssh2_sftp_readdir() */
|
||||
libssh2_nonblocking_states readdir_state;
|
||||
unsigned char *readdir_packet;
|
||||
|
@@ -139,7 +139,7 @@ decrypt(LIBSSH2_SESSION * session, unsigned char *source,
|
||||
assert((len % blocksize) == 0);
|
||||
|
||||
while (len >= blocksize) {
|
||||
if (session->remote.crypt->crypt(session, source,
|
||||
if (session->remote.crypt->crypt(session, source, blocksize,
|
||||
&session->remote.crypt_abstract)) {
|
||||
LIBSSH2_FREE(session, p->payload);
|
||||
return LIBSSH2_ERROR_DECRYPT;
|
||||
@@ -167,6 +167,7 @@ fullpacket(LIBSSH2_SESSION * session, int encrypted /* 1 or 0 */ )
|
||||
unsigned char macbuf[MAX_MACSIZE];
|
||||
struct transportpacket *p = &session->packet;
|
||||
int rc;
|
||||
int compressed;
|
||||
|
||||
if (session->fullpacket_state == libssh2_NB_state_idle) {
|
||||
session->fullpacket_macstate = LIBSSH2_MAC_CONFIRMED;
|
||||
@@ -199,9 +200,13 @@ fullpacket(LIBSSH2_SESSION * session, int encrypted /* 1 or 0 */ )
|
||||
session->fullpacket_payload_len -= p->padding_length;
|
||||
|
||||
/* Check for and deal with decompression */
|
||||
if (session->remote.comp &&
|
||||
session->remote.comp->compress &&
|
||||
session->remote.comp_abstract) {
|
||||
compressed =
|
||||
session->local.comp != NULL &&
|
||||
session->local.comp->compress &&
|
||||
((session->state & LIBSSH2_STATE_AUTHENTICATED) ||
|
||||
session->local.comp->use_in_auth);
|
||||
|
||||
if (compressed && session->remote.comp_abstract) {
|
||||
/*
|
||||
* The buffer for the decompression (remote.comp_abstract) is
|
||||
* initialised in time when it is needed so as long it is NULL we
|
||||
@@ -236,8 +241,12 @@ fullpacket(LIBSSH2_SESSION * session, int encrypted /* 1 or 0 */ )
|
||||
rc = _libssh2_packet_add(session, p->payload,
|
||||
session->fullpacket_payload_len,
|
||||
session->fullpacket_macstate);
|
||||
if (rc)
|
||||
if (rc == LIBSSH2_ERROR_EAGAIN)
|
||||
return rc;
|
||||
if (rc) {
|
||||
session->fullpacket_state = libssh2_NB_state_idle;
|
||||
return rc;
|
||||
}
|
||||
}
|
||||
|
||||
session->fullpacket_state = libssh2_NB_state_idle;
|
||||
@@ -519,6 +528,7 @@ int _libssh2_transport_read(LIBSSH2_SESSION * session)
|
||||
/* now decrypt the lot */
|
||||
rc = decrypt(session, &p->buf[p->readidx], p->wptr, numdecrypt);
|
||||
if (rc != LIBSSH2_ERROR_NONE) {
|
||||
p->total_num = 0; /* no packet buffer available */
|
||||
return rc;
|
||||
}
|
||||
|
||||
@@ -526,7 +536,7 @@ int _libssh2_transport_read(LIBSSH2_SESSION * session)
|
||||
p->readidx += numdecrypt;
|
||||
/* advance write pointer */
|
||||
p->wptr += numdecrypt;
|
||||
/* increse data_num */
|
||||
/* increase data_num */
|
||||
p->data_num += numdecrypt;
|
||||
|
||||
/* bytes left to take care of without decryption */
|
||||
@@ -542,7 +552,7 @@ int _libssh2_transport_read(LIBSSH2_SESSION * session)
|
||||
p->readidx += numbytes;
|
||||
/* advance write pointer */
|
||||
p->wptr += numbytes;
|
||||
/* increse data_num */
|
||||
/* increase data_num */
|
||||
p->data_num += numbytes;
|
||||
}
|
||||
|
||||
@@ -682,6 +692,7 @@ int _libssh2_transport_send(LIBSSH2_SESSION *session,
|
||||
#endif
|
||||
struct transportpacket *p = &session->packet;
|
||||
int encrypted;
|
||||
int compressed;
|
||||
ssize_t ret;
|
||||
int rc;
|
||||
const unsigned char *orgdata = data;
|
||||
@@ -723,7 +734,13 @@ int _libssh2_transport_send(LIBSSH2_SESSION *session,
|
||||
|
||||
encrypted = (session->state & LIBSSH2_STATE_NEWKEYS) ? 1 : 0;
|
||||
|
||||
if (encrypted && session->local.comp->compress) {
|
||||
compressed =
|
||||
session->local.comp != NULL &&
|
||||
session->local.comp->compress &&
|
||||
((session->state & LIBSSH2_STATE_AUTHENTICATED) ||
|
||||
session->local.comp->use_in_auth);
|
||||
|
||||
if (encrypted && compressed) {
|
||||
/* the idea here is that these function must fail if the output gets
|
||||
larger than what fits in the assigned buffer so thus they don't
|
||||
check the input size as we don't know how much it compresses */
|
||||
@@ -812,7 +829,7 @@ int _libssh2_transport_send(LIBSSH2_SESSION *session,
|
||||
the MAC and the packet_length field itself */
|
||||
_libssh2_htonu32(p->outbuf, packet_length - 4);
|
||||
/* store padding_length */
|
||||
p->outbuf[4] = padding_length;
|
||||
p->outbuf[4] = (unsigned char)padding_length;
|
||||
|
||||
/* fill the padding area with random junk */
|
||||
_libssh2_random(p->outbuf + 5 + data_len, padding_length);
|
||||
@@ -834,6 +851,7 @@ int _libssh2_transport_send(LIBSSH2_SESSION *session,
|
||||
for(i = 0; i < packet_length; i += session->local.crypt->blocksize) {
|
||||
unsigned char *ptr = &p->outbuf[i];
|
||||
if (session->local.crypt->crypt(session, ptr,
|
||||
session->local.crypt->blocksize,
|
||||
&session->local.crypt_abstract))
|
||||
return LIBSSH2_ERROR_ENCRYPT; /* encryption failure */
|
||||
}
|
||||
|
@@ -1,6 +1,6 @@
|
||||
/* Copyright (c) 2004-2007, Sara Golemon <sarag@libssh2.org>
|
||||
* Copyright (c) 2005 Mikhail Gusarov <dottedmag@dottedmag.net>
|
||||
* Copyright (c) 2009-2011 by Daniel Stenberg
|
||||
* Copyright (c) 2009-2014 by Daniel Stenberg
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms,
|
||||
@@ -211,12 +211,13 @@ userauth_password(LIBSSH2_SESSION *session,
|
||||
sizeof(session->userauth_pswd_packet_requirev_state));
|
||||
|
||||
/*
|
||||
* 40 = acket_type(1) + username_len(4) + service_len(4) +
|
||||
* 40 = packet_type(1) + username_len(4) + service_len(4) +
|
||||
* service(14)"ssh-connection" + method_len(4) + method(8)"password" +
|
||||
* chgpwdbool(1) + password_len(4) */
|
||||
session->userauth_pswd_data_len = username_len + 40;
|
||||
|
||||
session->userauth_pswd_data0 = ~SSH_MSG_USERAUTH_PASSWD_CHANGEREQ;
|
||||
session->userauth_pswd_data0 =
|
||||
(unsigned char) ~SSH_MSG_USERAUTH_PASSWD_CHANGEREQ;
|
||||
|
||||
/* TODO: remove this alloc with a fixed buffer in the session
|
||||
struct */
|
||||
@@ -276,13 +277,13 @@ userauth_password(LIBSSH2_SESSION *session,
|
||||
0, NULL, 0,
|
||||
&session->
|
||||
userauth_pswd_packet_requirev_state);
|
||||
if (rc == LIBSSH2_ERROR_EAGAIN) {
|
||||
return _libssh2_error(session, LIBSSH2_ERROR_EAGAIN,
|
||||
"Would block waiting");
|
||||
} else if (rc) {
|
||||
session->userauth_pswd_state = libssh2_NB_state_idle;
|
||||
return _libssh2_error(session, LIBSSH2_ERROR_TIMEOUT,
|
||||
"Would block waiting");
|
||||
|
||||
if (rc) {
|
||||
if (rc != LIBSSH2_ERROR_EAGAIN)
|
||||
session->userauth_pswd_state = libssh2_NB_state_idle;
|
||||
|
||||
return _libssh2_error(session, rc,
|
||||
"Waiting for password response");
|
||||
}
|
||||
|
||||
if (session->userauth_pswd_data[0] == SSH_MSG_USERAUTH_SUCCESS) {
|
||||
@@ -461,7 +462,7 @@ file_read_publickey(LIBSSH2_SESSION * session, unsigned char **method,
|
||||
FILE *fd;
|
||||
char c;
|
||||
unsigned char *pubkey = NULL, *sp1, *sp2, *tmp;
|
||||
size_t pubkey_len = 0;
|
||||
size_t pubkey_len = 0, sp_len;
|
||||
unsigned int tmp_len;
|
||||
|
||||
_libssh2_debug(session, LIBSSH2_TRACE_AUTH, "Loading public key file: %s",
|
||||
@@ -472,8 +473,9 @@ file_read_publickey(LIBSSH2_SESSION * session, unsigned char **method,
|
||||
return _libssh2_error(session, LIBSSH2_ERROR_FILE,
|
||||
"Unable to open public key file");
|
||||
}
|
||||
while (!feof(fd) && (c = fgetc(fd)) != '\r' && c != '\n')
|
||||
while (!feof(fd) && 1 == fread(&c, 1, 1, fd) && c != '\r' && c != '\n') {
|
||||
pubkey_len++;
|
||||
}
|
||||
if (feof(fd)) {
|
||||
/* the last character was EOF */
|
||||
pubkey_len--;
|
||||
@@ -502,8 +504,9 @@ file_read_publickey(LIBSSH2_SESSION * session, unsigned char **method,
|
||||
/*
|
||||
* Remove trailing whitespace
|
||||
*/
|
||||
while (pubkey_len && isspace(pubkey[pubkey_len - 1]))
|
||||
while (pubkey_len && isspace(pubkey[pubkey_len - 1])) {
|
||||
pubkey_len--;
|
||||
}
|
||||
|
||||
if (!pubkey_len) {
|
||||
LIBSSH2_FREE(session, pubkey);
|
||||
@@ -519,7 +522,8 @@ file_read_publickey(LIBSSH2_SESSION * session, unsigned char **method,
|
||||
|
||||
sp1++;
|
||||
|
||||
if ((sp2 = memchr(sp1, ' ', pubkey_len - (sp1 - pubkey - 1))) == NULL) {
|
||||
sp_len = sp1 > pubkey ? (sp1 - pubkey) - 1 : 0;
|
||||
if ((sp2 = memchr(sp1, ' ', pubkey_len - sp_len)) == NULL) {
|
||||
/* Assume that the id string is missing, but that it's okay */
|
||||
sp2 = pubkey + pubkey_len;
|
||||
}
|
||||
@@ -615,7 +619,7 @@ sign_fromfile(LIBSSH2_SESSION *session, unsigned char **sig, size_t *sig_len,
|
||||
if (privkeyobj->signv(session, sig, sig_len, 1, &datavec,
|
||||
&hostkey_abstract)) {
|
||||
if (privkeyobj->dtor) {
|
||||
privkeyobj->dtor(session, abstract);
|
||||
privkeyobj->dtor(session, &hostkey_abstract);
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
@@ -645,7 +649,7 @@ userauth_hostbased_fromfile(LIBSSH2_SESSION *session,
|
||||
if (session->userauth_host_state == libssh2_NB_state_idle) {
|
||||
const LIBSSH2_HOSTKEY_METHOD *privkeyobj;
|
||||
unsigned char *pubkeydata, *sig;
|
||||
size_t pubkeydata_len;
|
||||
size_t pubkeydata_len = 0;
|
||||
size_t sig_len;
|
||||
void *abstract;
|
||||
unsigned char buf[5];
|
||||
@@ -1501,49 +1505,41 @@ userauth_keyboard_interactive(LIBSSH2_SESSION * session,
|
||||
|
||||
if(session->userauth_kybd_num_prompts) {
|
||||
session->userauth_kybd_prompts =
|
||||
LIBSSH2_ALLOC(session,
|
||||
sizeof(LIBSSH2_USERAUTH_KBDINT_PROMPT) *
|
||||
session->userauth_kybd_num_prompts);
|
||||
LIBSSH2_CALLOC(session,
|
||||
sizeof(LIBSSH2_USERAUTH_KBDINT_PROMPT) *
|
||||
session->userauth_kybd_num_prompts);
|
||||
if (!session->userauth_kybd_prompts) {
|
||||
_libssh2_error(session, LIBSSH2_ERROR_ALLOC,
|
||||
"Unable to allocate memory for "
|
||||
"keyboard-interactive prompts array");
|
||||
goto cleanup;
|
||||
}
|
||||
memset(session->userauth_kybd_prompts, 0,
|
||||
sizeof(LIBSSH2_USERAUTH_KBDINT_PROMPT) *
|
||||
session->userauth_kybd_num_prompts);
|
||||
|
||||
session->userauth_kybd_responses =
|
||||
LIBSSH2_ALLOC(session,
|
||||
sizeof(LIBSSH2_USERAUTH_KBDINT_RESPONSE) *
|
||||
session->userauth_kybd_num_prompts);
|
||||
LIBSSH2_CALLOC(session,
|
||||
sizeof(LIBSSH2_USERAUTH_KBDINT_RESPONSE) *
|
||||
session->userauth_kybd_num_prompts);
|
||||
if (!session->userauth_kybd_responses) {
|
||||
_libssh2_error(session, LIBSSH2_ERROR_ALLOC,
|
||||
"Unable to allocate memory for "
|
||||
"keyboard-interactive responses array");
|
||||
goto cleanup;
|
||||
}
|
||||
memset(session->userauth_kybd_responses, 0,
|
||||
sizeof(LIBSSH2_USERAUTH_KBDINT_RESPONSE) *
|
||||
session->userauth_kybd_num_prompts);
|
||||
|
||||
for(i = 0; i != session->userauth_kybd_num_prompts; ++i) {
|
||||
for(i = 0; i < session->userauth_kybd_num_prompts; i++) {
|
||||
/* string prompt[1] (ISO-10646 UTF-8) */
|
||||
session->userauth_kybd_prompts[i].length =
|
||||
_libssh2_ntohu32(s);
|
||||
s += 4;
|
||||
session->userauth_kybd_prompts[i].text =
|
||||
LIBSSH2_ALLOC(session,
|
||||
session->userauth_kybd_prompts[i].length);
|
||||
LIBSSH2_CALLOC(session,
|
||||
session->userauth_kybd_prompts[i].length);
|
||||
if (!session->userauth_kybd_prompts[i].text) {
|
||||
_libssh2_error(session, LIBSSH2_ERROR_ALLOC,
|
||||
"Unable to allocate memory for "
|
||||
"keyboard-interactive prompt message");
|
||||
goto cleanup;
|
||||
}
|
||||
memcpy(session->userauth_kybd_prompts[i].text, s,
|
||||
session->userauth_kybd_prompts[i].length);
|
||||
s += session->userauth_kybd_prompts[i].length;
|
||||
|
||||
/* boolean echo[1] */
|
||||
@@ -1569,7 +1565,7 @@ userauth_keyboard_interactive(LIBSSH2_SESSION * session,
|
||||
+ 4 /* int num-responses */
|
||||
;
|
||||
|
||||
for(i = 0; i != session->userauth_kybd_num_prompts; ++i) {
|
||||
for(i = 0; i < session->userauth_kybd_num_prompts; i++) {
|
||||
/* string response[1] (ISO-10646 UTF-8) */
|
||||
session->userauth_kybd_packet_len +=
|
||||
4 + session->userauth_kybd_responses[i].length;
|
||||
@@ -1592,7 +1588,7 @@ userauth_keyboard_interactive(LIBSSH2_SESSION * session,
|
||||
s++;
|
||||
_libssh2_store_u32(&s, session->userauth_kybd_num_prompts);
|
||||
|
||||
for(i = 0; i != session->userauth_kybd_num_prompts; ++i) {
|
||||
for(i = 0; i < session->userauth_kybd_num_prompts; i++) {
|
||||
_libssh2_store_str(&s,
|
||||
session->userauth_kybd_responses[i].text,
|
||||
session->userauth_kybd_responses[i].length);
|
||||
@@ -1628,14 +1624,14 @@ userauth_keyboard_interactive(LIBSSH2_SESSION * session,
|
||||
session->userauth_kybd_data = NULL;
|
||||
|
||||
if (session->userauth_kybd_prompts) {
|
||||
for(i = 0; i != session->userauth_kybd_num_prompts; ++i) {
|
||||
for(i = 0; i < session->userauth_kybd_num_prompts; i++) {
|
||||
LIBSSH2_FREE(session, session->userauth_kybd_prompts[i].text);
|
||||
session->userauth_kybd_prompts[i].text = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
if (session->userauth_kybd_responses) {
|
||||
for(i = 0; i != session->userauth_kybd_num_prompts; ++i) {
|
||||
for(i = 0; i < session->userauth_kybd_num_prompts; i++) {
|
||||
LIBSSH2_FREE(session,
|
||||
session->userauth_kybd_responses[i].text);
|
||||
session->userauth_kybd_responses[i].text = NULL;
|
||||
|
1827
src/wincng.c
Normal file
1827
src/wincng.c
Normal file
File diff suppressed because it is too large
Load Diff
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user