Compare commits
180 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 |
2
.gitignore
vendored
2
.gitignore
vendored
@@ -24,7 +24,6 @@ ltmain.sh
|
|||||||
missing
|
missing
|
||||||
ssh2_sample
|
ssh2_sample
|
||||||
libssh2-*.tar.gz
|
libssh2-*.tar.gz
|
||||||
INSTALL
|
|
||||||
install-sh
|
install-sh
|
||||||
*.o
|
*.o
|
||||||
*.lo
|
*.lo
|
||||||
@@ -33,3 +32,4 @@ mkinstalldirs
|
|||||||
tags
|
tags
|
||||||
libssh2.pc
|
libssh2.pc
|
||||||
TAGS
|
TAGS
|
||||||
|
*~
|
||||||
|
2
COPYING
2
COPYING
@@ -2,7 +2,7 @@
|
|||||||
* Copyright (c) 2005,2006 Mikhail Gusarov <dottedmag@dottedmag.net>
|
* Copyright (c) 2005,2006 Mikhail Gusarov <dottedmag@dottedmag.net>
|
||||||
* Copyright (c) 2006-2007 The Written Word, Inc.
|
* Copyright (c) 2006-2007 The Written Word, Inc.
|
||||||
* Copyright (c) 2007 Eli Fant <elifantu@mail.ru>
|
* 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
|
* Copyright (C) 2008, 2009 Simon Josefsson
|
||||||
* All rights reserved.
|
* 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
|
14
Makefile.am
14
Makefile.am
@@ -14,10 +14,9 @@ include_HEADERS = \
|
|||||||
include/libssh2_sftp.h
|
include/libssh2_sftp.h
|
||||||
|
|
||||||
NETWAREFILES = nw/keepscreen.c \
|
NETWAREFILES = nw/keepscreen.c \
|
||||||
nw/Makefile \
|
nw/nwlib.c \
|
||||||
nw/Makefile.netware \
|
nw/GNUmakefile \
|
||||||
nw/nwlib.c \
|
nw/test/GNUmakefile
|
||||||
nw/test/Makefile.netware
|
|
||||||
|
|
||||||
DSP = win32/libssh2.dsp
|
DSP = win32/libssh2.dsp
|
||||||
VCPROJ = win32/libssh2.vcproj
|
VCPROJ = win32/libssh2.vcproj
|
||||||
@@ -33,8 +32,8 @@ win32/libssh2_config.h win32/config.mk win32/rules.mk \
|
|||||||
win32/Makefile.Watcom win32/libssh2.dsw win32/tests.dsp $(DSP) \
|
win32/Makefile.Watcom win32/libssh2.dsw win32/tests.dsp $(DSP) \
|
||||||
win32/msvcproj.head win32/msvcproj.foot win32/libssh2.rc
|
win32/msvcproj.head win32/msvcproj.foot win32/libssh2.rc
|
||||||
|
|
||||||
EXTRA_DIST = $(WIN32FILES) buildconf $(NETWAREFILES) get_ver.awk HACKING \
|
EXTRA_DIST = $(WIN32FILES) buildconf $(NETWAREFILES) get_ver.awk \
|
||||||
maketgz NMakefile TODO RELEASE-NOTES libssh2.pc.in $(VMSFILES)
|
maketgz NMakefile RELEASE-NOTES libssh2.pc.in $(VMSFILES) config.rpath
|
||||||
|
|
||||||
ACLOCAL_AMFLAGS = -I m4
|
ACLOCAL_AMFLAGS = -I m4
|
||||||
|
|
||||||
@@ -76,6 +75,9 @@ gen-coverage:
|
|||||||
coverage: init-coverage build-coverage gen-coverage
|
coverage: init-coverage build-coverage gen-coverage
|
||||||
|
|
||||||
# DSP/VCPROJ generation adapted from libcurl
|
# 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
|
# Makefile.inc provides the CSOURCES and HHEADERS defines
|
||||||
include Makefile.inc
|
include Makefile.inc
|
||||||
|
|
||||||
|
@@ -1,7 +1,6 @@
|
|||||||
CSOURCES = channel.c comp.c crypt.c hostkey.c kex.c mac.c misc.c \
|
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 \
|
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 \
|
version.c knownhost.c agent.c $(CRYPTO_CSOURCES) pem.c keepalive.c global.c
|
||||||
global.c
|
|
||||||
|
|
||||||
HHEADERS = libssh2_priv.h openssl.h libgcrypt.h transport.h channel.h \
|
HHEADERS = libssh2_priv.h $(CRYPTO_HHEADERS) transport.h channel.h comp.h \
|
||||||
comp.h mac.h misc.h packet.h userauth.h session.h sftp.h crypto.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"
|
!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 example
|
||||||
SUBDIRS=src
|
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
|
-for %D in ($(SUBDIRS)) do $(MAKE) /nologo /f %D/NMakefile BUILD=$(BUILD) SUBDIR=%D all-sub
|
||||||
|
|
||||||
clean:
|
clean:
|
||||||
-rmdir /s/q $(TARGET)
|
-rmdir 2>NUL /s/q $(TARGET)
|
||||||
|
-del 2>NUL win32\objects.mk
|
||||||
|
|
||||||
real-clean: clean
|
real-clean vclean: clean
|
||||||
-del libssh2.dll
|
-del 2>NUL libssh2.dll
|
||||||
-del libssh2.exp
|
-del 2>NUL libssh2.exp
|
||||||
-del libssh2.ilk
|
-del 2>NUL libssh2.ilk
|
||||||
-del libssh2.lib
|
-del 2>NUL libssh2.lib
|
||||||
-del *.pdb
|
-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
|
Mailing list: http://cool.haxx.se/mailman/listinfo/libssh2-devel
|
||||||
|
|
||||||
Generic installation instructions are in INSTALL. Some ./configure
|
License: see COPYING
|
||||||
options deserve additional comments:
|
|
||||||
|
|
||||||
* --enable-crypt-none
|
Source code: https://github.com/bagder/libssh2
|
||||||
|
|
||||||
The SSH2 Transport allows for unencrypted data
|
Web site source code: https://github.com/bagder/libssh2-www
|
||||||
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
|
Installation instructions are in docs/INSTALL
|
||||||
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,21 +1,83 @@
|
|||||||
libssh2 1.4.2
|
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:
|
This release includes the following bugfixes:
|
||||||
|
|
||||||
o Return LIBSSH2_ERROR_SOCKET_DISCONNECT on EOF when reading banner
|
o Security Advisory for CVE-2015-1782, using SSH_MSG_KEXINIT data unbounded
|
||||||
o userauth.c: fread() from public key file to correctly detect any errors
|
o missing _libssh2_error in _libssh2_channel_write
|
||||||
o configure.ac: Add option to disable build of the example applications
|
o knownhost: Fix DSS keys being detected as unknown.
|
||||||
o Added 'Requires.private:' line to libssh2.pc
|
o knownhost: Restore behaviour of `libssh2_knownhost_writeline` with short buffer.
|
||||||
o SFTP: filter off incoming "zombie" responses
|
o libssh2.h: on Windows, a socket is of type SOCKET, not int
|
||||||
o gettimeofday: no need for a replacement under cygwin
|
o libssh2_priv.h: a 1 bit bit-field should be unsigned
|
||||||
o SSH_MSG_CHANNEL_REQUEST: default to want_reply
|
o windows build: do not export externals from static library
|
||||||
o win32/libssh2_config.h: Remove hardcoded #define LIBSSH2_HAVE_ZLIB
|
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
|
This release would not have looked like this without help, code, reports and
|
||||||
advice from friends like these:
|
advice from friends like these:
|
||||||
|
|
||||||
Alexander Lamaison, Rafael Kitover, Guenter Knauf, Peter Stuge,
|
Alexander Lamaison, Bob Kast, Dan Fandrich, Daniel Stenberg, Guenter Knauf,
|
||||||
Oleksiy Zagorskyi
|
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)
|
Thanks! (and sorry if I forgot to mention someone)
|
||||||
|
|
||||||
|
97
configure.ac
97
configure.ac
@@ -2,7 +2,7 @@
|
|||||||
AC_INIT(libssh2, [-], libssh2-devel@cool.haxx.se)
|
AC_INIT(libssh2, [-], libssh2-devel@cool.haxx.se)
|
||||||
AC_CONFIG_MACRO_DIR([m4])
|
AC_CONFIG_MACRO_DIR([m4])
|
||||||
AC_CONFIG_SRCDIR([src])
|
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
|
AM_MAINTAINER_MODE
|
||||||
|
|
||||||
dnl SED is needed by some of the tools
|
dnl SED is needed by some of the tools
|
||||||
@@ -83,59 +83,102 @@ dnl check for how to do large files
|
|||||||
AC_SYS_LARGEFILE
|
AC_SYS_LARGEFILE
|
||||||
|
|
||||||
# Configure parameters
|
# 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_ARG_WITH(openssl,
|
||||||
AC_HELP_STRING([--with-openssl],[Use OpenSSL for crypto]),
|
AC_HELP_STRING([--with-openssl],[Use OpenSSL for crypto]),
|
||||||
use_openssl=$withval,use_openssl=auto)
|
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_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)
|
use_libz=$withval,use_libz=auto)
|
||||||
|
|
||||||
# Look for OpenSSL (default)
|
found_crypto=none
|
||||||
if test "$use_openssl" != "no" && test "$use_libgcrypt" != "yes"; then
|
|
||||||
|
# Look for OpenSSL
|
||||||
|
if test "$found_crypto" = "none" && test "$use_openssl" != "no"; then
|
||||||
AC_LIB_HAVE_LINKFLAGS([ssl], [crypto], [#include <openssl/ssl.h>])
|
AC_LIB_HAVE_LINKFLAGS([ssl], [crypto], [#include <openssl/ssl.h>])
|
||||||
LIBSREQUIRED=libssl,libcrypto
|
|
||||||
fi
|
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
|
# 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>])
|
AC_LIB_HAVE_LINKFLAGS([gcrypt], [], [#include <gcrypt.h>])
|
||||||
LIBSREQUIRED=libgcrypt
|
|
||||||
fi
|
fi
|
||||||
|
|
||||||
AC_SUBST(LIBSREQUIRED)
|
|
||||||
|
|
||||||
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
|
if test "$ac_cv_libgcrypt" = "yes"; then
|
||||||
AC_DEFINE(LIBSSH2_LIBGCRYPT, 1, [Use libgcrypt])
|
AC_DEFINE(LIBSSH2_LIBGCRYPT, 1, [Use libgcrypt])
|
||||||
|
LIBSREQUIRED= # libgcrypt doesn't provide a .pc file. sad face.
|
||||||
|
LIBS="$LIBS -lgcrypt"
|
||||||
|
found_crypto=libgcrypt
|
||||||
fi
|
fi
|
||||||
AM_CONDITIONAL(LIBGCRYPT, test "$ac_cv_libgcrypt" = "yes")
|
AM_CONDITIONAL(LIBGCRYPT, test "$ac_cv_libgcrypt" = "yes")
|
||||||
|
|
||||||
# Not all OpenSSL have AES-CTR functions.
|
# Look for Windows Cryptography API: Next Generation
|
||||||
if test "$ac_cv_libssl" = "yes"; then
|
if test "$found_crypto" = "none" && test "$use_wincng" != "no"; then
|
||||||
save_LDFLAGS="$LDFLAGS"
|
AC_LIB_HAVE_LINKFLAGS([bcrypt], [], [
|
||||||
LDFLAGS="$LDFLAGS $LIBSSL"
|
#include <windows.h>
|
||||||
AC_CHECK_FUNCS(EVP_aes_128_ctr)
|
#include <bcrypt.h>
|
||||||
LDFLAGS="$save_LDFLAGS"
|
])
|
||||||
|
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
|
fi
|
||||||
|
|
||||||
# Look for Libz
|
# Look for Libz
|
||||||
if test "$use_libz" != "no"; then
|
if test "$use_libz" != "no"; then
|
||||||
AC_LIB_HAVE_LINKFLAGS([z], [], [#include <zlib.h>])
|
AC_LIB_HAVE_LINKFLAGS([z], [], [#include <zlib.h>])
|
||||||
if test "$ac_cv_libz" != yes; then
|
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])
|
AC_MSG_NOTICE([Try --with-libz-prefix=PATH if you know you have it])
|
||||||
else
|
else
|
||||||
AC_DEFINE(LIBSSH2_HAVE_ZLIB, 1, [Compile in zlib support])
|
AC_DEFINE(LIBSSH2_HAVE_ZLIB, 1, [Compile in zlib support])
|
||||||
|
if test "${LIBSREQUIRED}" != ""; then
|
||||||
|
LIBSREQUIRED="${LIBSREQUIRED},"
|
||||||
|
fi
|
||||||
|
LIBSREQUIRED="${LIBSREQUIRED}zlib"
|
||||||
fi
|
fi
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
AC_SUBST(LIBSREQUIRED)
|
||||||
|
|
||||||
#
|
#
|
||||||
# Optional Settings
|
# Optional Settings
|
||||||
#
|
#
|
||||||
@@ -318,9 +361,9 @@ AC_MSG_NOTICE([summary of build options:
|
|||||||
Compiler: ${CC}
|
Compiler: ${CC}
|
||||||
Compiler flags: ${CFLAGS}
|
Compiler flags: ${CFLAGS}
|
||||||
Library types: Shared=${enable_shared}, Static=${enable_static}
|
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
|
Debug build: $enable_debug
|
||||||
Build examples: $build_examples
|
Build examples: $build_examples
|
||||||
Path to sshd: $ac_cv_path_SSHD (only for self-tests)
|
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
|
Adam Gobiowski
|
||||||
Alexander Holyapin
|
Alexander Holyapin
|
||||||
Alexander Lamaison
|
Alexander Lamaison
|
||||||
|
Alfred Gebert
|
||||||
Ben Kibbey
|
Ben Kibbey
|
||||||
Bjorn Stenborg
|
Bjorn Stenborg
|
||||||
Carlo Bramini
|
Carlo Bramini
|
||||||
|
Cristian Rodríguez
|
||||||
|
Daiki Ueno
|
||||||
Dan Casey
|
Dan Casey
|
||||||
Dan Fandrich
|
Dan Fandrich
|
||||||
Daniel Stenberg
|
Daniel Stenberg
|
||||||
|
Dave Hayden
|
||||||
|
Dave McCaldon
|
||||||
David J Sullivan
|
David J Sullivan
|
||||||
David Robins
|
David Robins
|
||||||
|
Dmitry Smirnov
|
||||||
|
Douglas Masterson
|
||||||
Edink Kadribasic
|
Edink Kadribasic
|
||||||
Erik Brossler
|
Erik Brossler
|
||||||
Francois Dupoux
|
Francois Dupoux
|
||||||
|
Gellule Xg
|
||||||
|
Grubsky Grigory
|
||||||
Guenter Knauf
|
Guenter Knauf
|
||||||
Heiner Steven
|
Heiner Steven
|
||||||
|
Henrik Nordstrom
|
||||||
James Housleys
|
James Housleys
|
||||||
|
Jasmeet Bagga
|
||||||
Jean-Louis Charton
|
Jean-Louis Charton
|
||||||
|
Jernej Kovacic
|
||||||
|
Joey Degges
|
||||||
|
John Little
|
||||||
|
Jose Baars
|
||||||
Jussi Mononen
|
Jussi Mononen
|
||||||
|
Kamil Dudka
|
||||||
|
Lars Nordin
|
||||||
Mark McPherson
|
Mark McPherson
|
||||||
|
Mark Smith
|
||||||
Markus Moeller
|
Markus Moeller
|
||||||
|
Matt Lilley
|
||||||
|
Matthew Booth
|
||||||
|
Maxime Larocque
|
||||||
Mike Protts
|
Mike Protts
|
||||||
Mikhail Gusarov
|
Mikhail Gusarov
|
||||||
Neil Gierman
|
Neil Gierman
|
||||||
Olivier Hervieu
|
Olivier Hervieu
|
||||||
|
Paul Howarth
|
||||||
|
Paul Querna
|
||||||
Paul Veldkamp
|
Paul Veldkamp
|
||||||
Peter Krempa
|
Peter Krempa
|
||||||
Peter O'Gorman
|
Peter O'Gorman
|
||||||
Peter Stuge
|
Peter Stuge
|
||||||
|
Pierre Joye
|
||||||
|
Rafael Kitover
|
||||||
Romain Bondue
|
Romain Bondue
|
||||||
Sara Golemon
|
Sara Golemon
|
||||||
Satish Mittal
|
Satish Mittal
|
||||||
@@ -39,10 +64,16 @@ Sean Peterson
|
|||||||
Selcuk Gueney
|
Selcuk Gueney
|
||||||
Simon Hart
|
Simon Hart
|
||||||
Simon Josefsson
|
Simon Josefsson
|
||||||
|
Sofian Brabez
|
||||||
Steven Ayre
|
Steven Ayre
|
||||||
|
Steven Dake
|
||||||
Steven Van Ingelgem
|
Steven Van Ingelgem
|
||||||
|
TJ Saunders
|
||||||
|
Tommy Lindgren
|
||||||
Tor Arntsen
|
Tor Arntsen
|
||||||
Vincent Jaulin
|
Vincent Jaulin
|
||||||
|
Vincent Torri
|
||||||
Vlad Grachov
|
Vlad Grachov
|
||||||
Wez Furlong
|
Wez Furlong
|
||||||
Yang Tse
|
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 $
|
# $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 = \
|
dist_man_MANS = \
|
||||||
libssh2_agent_connect.3 \
|
libssh2_agent_connect.3 \
|
||||||
@@ -102,6 +102,7 @@ dist_man_MANS = \
|
|||||||
libssh2_session_free.3 \
|
libssh2_session_free.3 \
|
||||||
libssh2_session_get_blocking.3 \
|
libssh2_session_get_blocking.3 \
|
||||||
libssh2_session_get_timeout.3 \
|
libssh2_session_get_timeout.3 \
|
||||||
|
libssh2_session_handshake.3 \
|
||||||
libssh2_session_hostkey.3 \
|
libssh2_session_hostkey.3 \
|
||||||
libssh2_session_init.3 \
|
libssh2_session_init.3 \
|
||||||
libssh2_session_init_ex.3 \
|
libssh2_session_init_ex.3 \
|
||||||
@@ -120,6 +121,7 @@ dist_man_MANS = \
|
|||||||
libssh2_sftp_fstat.3 \
|
libssh2_sftp_fstat.3 \
|
||||||
libssh2_sftp_fstat_ex.3 \
|
libssh2_sftp_fstat_ex.3 \
|
||||||
libssh2_sftp_fstatvfs.3 \
|
libssh2_sftp_fstatvfs.3 \
|
||||||
|
libssh2_sftp_fsync.3 \
|
||||||
libssh2_sftp_get_channel.3 \
|
libssh2_sftp_get_channel.3 \
|
||||||
libssh2_sftp_init.3 \
|
libssh2_sftp_init.3 \
|
||||||
libssh2_sftp_last_error.3 \
|
libssh2_sftp_last_error.3 \
|
||||||
|
@@ -1,6 +1,6 @@
|
|||||||
.TH libssh2_banner_set 3 "1 Jun 2007" "libssh2 0.15" "libssh2 manual"
|
.TH libssh2_banner_set 3 "1 Jun 2007" "libssh2 0.15" "libssh2 manual"
|
||||||
.SH NAME
|
.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
|
.SH SYNOPSIS
|
||||||
#include <libssh2.h>
|
#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!
|
free that memory!
|
||||||
.SH BUGS
|
.SH BUGS
|
||||||
The memory that *dest points to is allocated by the malloc function libssh2
|
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!
|
reliable way!
|
||||||
.SH RETURN VALUE
|
.SH RETURN VALUE
|
||||||
0 if successful, \-1 if any error occurred.
|
0 if successful, \-1 if any error occurred.
|
||||||
|
@@ -8,7 +8,7 @@ int
|
|||||||
libssh2_channel_get_exit_status(LIBSSH2_CHANNEL* channel)
|
libssh2_channel_get_exit_status(LIBSSH2_CHANNEL* channel)
|
||||||
|
|
||||||
.SH DESCRIPTION
|
.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
|
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
|
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
|
.SH SYNOPSIS
|
||||||
#include <libssh2.h>
|
#include <libssh2.h>
|
||||||
|
|
||||||
unsigend long libssh2_channel_window_write(LIBSSH2_CHANNEL *channel);
|
unsigned long libssh2_channel_window_write(LIBSSH2_CHANNEL *channel);
|
||||||
|
|
||||||
.SH DESCRIPTION
|
.SH DESCRIPTION
|
||||||
This is a macro defined in a public libssh2 header file that is using the
|
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)
|
unsigned long *window_size_initial)
|
||||||
.SH DESCRIPTION
|
.SH DESCRIPTION
|
||||||
Check the status of the write window Returns the number of bytes which may be
|
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
|
passed) will be populated with the size of the initial window as defined by
|
||||||
the channel_open request
|
the channel_open request
|
||||||
.SH RETURN VALUE
|
.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 ERRORS
|
||||||
|
|
||||||
.SH SEE ALSO
|
.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,
|
the returned string is hash_type specific (e.g. 16 bytes for MD5,
|
||||||
20 bytes for SHA1).
|
20 bytes for SHA1).
|
||||||
.SH RETURN VALUE
|
.SH RETURN VALUE
|
||||||
Computed hostkey hash value. or NULL if the session has not yet been started
|
Computed hostkey hash value, or NULL if the information is not available
|
||||||
up. (The hash consists of raw binary bytes, not hex digits, so is not
|
(either the session has not yet been started up, or the requested hash
|
||||||
directly printable.)
|
algorithm was not available). The hash consists of raw binary bytes, not hex
|
||||||
|
digits, so it is not directly printable.
|
||||||
.SH SEE ALSO
|
.SH SEE ALSO
|
||||||
.BR libssh2_session_init_ex(3)
|
.BR libssh2_session_init_ex(3)
|
||||||
|
@@ -36,7 +36,7 @@ The salt has to be provided base64 encoded with a trailing zero byte.
|
|||||||
argument
|
argument
|
||||||
|
|
||||||
\fItypemask\fP is a bitmask that specifies format and info about the data
|
\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.
|
what format the key is and what key type it is.
|
||||||
|
|
||||||
The host name is given as one of the following types:
|
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
|
\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
|
\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.
|
what format the key is and what key type it is.
|
||||||
|
|
||||||
The host name is given as one of the following types:
|
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
|
argument
|
||||||
|
|
||||||
\fItypemask\fP is a bitmask that specifies format and info about the data
|
\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.
|
what format the key is and what key type it is.
|
||||||
|
|
||||||
The host name is given as one of the following types:
|
The host name is given as one of the following types:
|
||||||
|
@@ -30,7 +30,7 @@ addition to the plain host name only check.
|
|||||||
argument
|
argument
|
||||||
|
|
||||||
\fItypemask\fP is a bitmask that specifies format and info about the data
|
\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.
|
what format the key is and what key type it is.
|
||||||
|
|
||||||
The host name is given as one of the following types:
|
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
|
.SH DESCRIPTION
|
||||||
This function is deprecated. Do note use. We encourage users to instead use
|
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
|
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
|
Poll for activity on a socket, channel, listener, or any combination of these
|
||||||
three types. The calling semantics for this function generally match
|
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.
|
modified in place.
|
||||||
|
|
||||||
.SH RETURN VALUE
|
.SH RETURN VALUE
|
||||||
A pointer to session internal storage whos contents point to previously
|
A pointer to session internal storage who's contents point to previously
|
||||||
provided abstract data.
|
provided abstract data.
|
||||||
|
|
||||||
.SH SEE ALSO
|
.SH SEE ALSO
|
||||||
|
@@ -1,6 +1,6 @@
|
|||||||
.TH libssh2_session_banner_set 3 "9 Sep 2011" "libssh2 1.4.0" "libssh2 manual"
|
.TH libssh2_session_banner_set 3 "9 Sep 2011" "libssh2 1.4.0" "libssh2 manual"
|
||||||
.SH NAME
|
.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
|
.SH SYNOPSIS
|
||||||
#include <libssh2.h>
|
#include <libssh2.h>
|
||||||
|
|
||||||
|
@@ -18,7 +18,7 @@ libssh2_session_disconnect(LIBSSH2_SESSION *session, const char *description);
|
|||||||
|
|
||||||
\fIdescription\fP - Human readable reason for disconnection.
|
\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,
|
Send a disconnect message to the remote host associated with \fIsession\fP,
|
||||||
along with a \fIreason\fP symbol and a verbose \fIdescription\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.
|
ignored and not sent to the remote host during protocol negotiation.
|
||||||
|
|
||||||
Set preferred methods to be negotiated. These
|
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)
|
.BR libssh2_session_handshake(3)
|
||||||
as they are used during the protocol initiation phase.
|
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
|
\fIsession\fP - An instance of initialized LIBSSH2_SESSION (the function will
|
||||||
use its pointer to the memory allocation function). \fImethod_type\fP - Method
|
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
|
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
|
Get a list of supported algorithms for the given \fImethod_type\fP. The
|
||||||
method_type parameter is equivalent to method_type in
|
method_type parameter is equivalent to method_type in
|
||||||
@@ -36,7 +36,7 @@ const char **algorithms;
|
|||||||
int rc, i;
|
int rc, i;
|
||||||
LIBSSH2_SESSION *session;
|
LIBSSH2_SESSION *session;
|
||||||
|
|
||||||
/* initilize session */
|
/* initialize session */
|
||||||
session = libssh2_session_init();
|
session = libssh2_session_init();
|
||||||
rc = libssh2_session_supported_algs(session,
|
rc = libssh2_session_supported_algs(session,
|
||||||
LIBSSH2_METHOD_CRYPT_CS,
|
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
|
Close an active LIBSSH2_SFTP_HANDLE. Because files and directories share the
|
||||||
same underlying storage mechanism these methods may be used
|
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.
|
are macros for \fBlibssh2_sftp_close_handle(3)\fP.
|
||||||
|
|
||||||
.SH RETURN VALUE
|
.SH RETURN VALUE
|
||||||
|
@@ -10,7 +10,7 @@ int
|
|||||||
libssh2_sftp_fstat_ex(LIBSSH2_SFTP_HANDLE *handle,
|
libssh2_sftp_fstat_ex(LIBSSH2_SFTP_HANDLE *handle,
|
||||||
LIBSSH2_SFTP_ATTRIBUTES *attrs, int setstat)
|
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)
|
libssh2_sftp_fstat_ex((handle), (attrs), 0)
|
||||||
#define libssh2_sftp_fsetstat(handle, attrs) \\
|
#define libssh2_sftp_fsetstat(handle, attrs) \\
|
||||||
libssh2_sftp_fstat_ex((handle), (attrs), 1)
|
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
|
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
|
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
|
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
|
\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.
|
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)
|
.BR libssh2_sftp_init(3)
|
||||||
|
|
||||||
\fIpath\fP - full path of the new directory to create. Note that the new
|
\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.
|
\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.
|
Bitmask flags made up of LIBSSH2_SFTP_RENAME_* constants.
|
||||||
|
|
||||||
Rename a filesystem object on the remote filesystem. The semantics of
|
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
|
between folders and/or filesystem mounts. If the LIBSSH2_SFTP_RENAME_OVERWRITE
|
||||||
flag is not set and the destfile entry already exists, the operation
|
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
|
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
|
.SH SYNOPSIS
|
||||||
#include <libssh2.h>
|
#include <libssh2.h>
|
||||||
|
|
||||||
int libssh2_sftp_rewind(LINBSSH2_SFTP_HANDLE *handle);
|
int libssh2_sftp_rewind(LIBSSH2_SFTP_HANDLE *handle);
|
||||||
|
|
||||||
.SH DESCRIPTION
|
.SH DESCRIPTION
|
||||||
This is a macro defined in a public libssh2 header file that is using the
|
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
|
.SH SYNOPSIS
|
||||||
#include <libssh2.h>
|
#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
|
.SH DESCRIPTION
|
||||||
This is a macro defined in a public libssh2 header file that is using the
|
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)
|
.BR libssh2_sftp_realpath(3)
|
||||||
: Resolve a complex, relative, or symlinked filepath to its effective target.
|
: Resolve a complex, relative, or symlinked filepath to its effective target.
|
||||||
.SH RETURN VALUE
|
.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.
|
on failure.
|
||||||
|
|
||||||
When using LIBSSH2_SFTP_READLINK or LIBSSH2_SFTP_REALPATH, it returns the
|
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.
|
\fIlibssh2_userauth_authenticated(3)\fP.
|
||||||
.SH RETURN VALUE
|
.SH RETURN VALUE
|
||||||
On success a comma delimited list of supported authentication schemes. This
|
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
|
.SH ERRORS
|
||||||
\fILIBSSH2_ERROR_ALLOC\fP - An internal memory allocation call failed.
|
\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
|
.nf
|
||||||
int libssh2_userauth_publickey_fromfile_ex(LIBSSH2_SESSION *session,
|
int libssh2_userauth_publickey_fromfile_ex(LIBSSH2_SESSION *session,
|
||||||
const char *username,
|
const char *username,
|
||||||
|
unsigned int ousername_len,
|
||||||
const char *publickey,
|
const char *publickey,
|
||||||
const char *privatekey,
|
const char *privatekey,
|
||||||
const char *passphrase);
|
const char *passphrase);
|
||||||
.SH DESCRIPTION
|
.SH DESCRIPTION
|
||||||
\fIsession\fP - Session instance as returned by
|
\fIsession\fP - Session instance as returned by
|
||||||
.BR libssh2_session_init_ex(3)
|
\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
|
.SH RETURN VALUE
|
||||||
Return 0 on success or negative on failure. It returns
|
Return 0 on success or negative on failure. It returns
|
||||||
|
@@ -48,7 +48,7 @@ enum {
|
|||||||
|
|
||||||
int main(int argc, char *argv[])
|
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;
|
struct sockaddr_in sin;
|
||||||
socklen_t sinlen;
|
socklen_t sinlen;
|
||||||
const char *fingerprint;
|
const char *fingerprint;
|
||||||
@@ -64,11 +64,19 @@ int main(int argc, char *argv[])
|
|||||||
|
|
||||||
#ifdef WIN32
|
#ifdef WIN32
|
||||||
char sockopt;
|
char sockopt;
|
||||||
|
SOCKET sock = INVALID_SOCKET;
|
||||||
|
SOCKET listensock = INVALID_SOCKET, forwardsock = INVALID_SOCKET;
|
||||||
WSADATA wsadata;
|
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
|
#else
|
||||||
int sockopt;
|
int sockopt, sock = -1;
|
||||||
|
int listensock = -1, forwardsock = -1;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (argc > 1)
|
if (argc > 1)
|
||||||
@@ -94,6 +102,18 @@ int main(int argc, char *argv[])
|
|||||||
|
|
||||||
/* Connect to SSH server */
|
/* Connect to SSH server */
|
||||||
sock = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP);
|
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;
|
sin.sin_family = AF_INET;
|
||||||
if (INADDR_NONE == (sin.sin_addr.s_addr = inet_addr(server_ip))) {
|
if (INADDR_NONE == (sin.sin_addr.s_addr = inet_addr(server_ip))) {
|
||||||
perror("inet_addr");
|
perror("inet_addr");
|
||||||
@@ -135,7 +155,7 @@ int main(int argc, char *argv[])
|
|||||||
|
|
||||||
/* check what authentication methods are available */
|
/* check what authentication methods are available */
|
||||||
userauthlist = libssh2_userauth_list(session, username, strlen(username));
|
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"))
|
if (strstr(userauthlist, "password"))
|
||||||
auth |= AUTH_PASSWORD;
|
auth |= AUTH_PASSWORD;
|
||||||
if (strstr(userauthlist, "publickey"))
|
if (strstr(userauthlist, "publickey"))
|
||||||
@@ -157,16 +177,28 @@ int main(int argc, char *argv[])
|
|||||||
} else if (auth & AUTH_PUBLICKEY) {
|
} else if (auth & AUTH_PUBLICKEY) {
|
||||||
if (libssh2_userauth_publickey_fromfile(session, username, keyfile1,
|
if (libssh2_userauth_publickey_fromfile(session, username, keyfile1,
|
||||||
keyfile2, password)) {
|
keyfile2, password)) {
|
||||||
printf("\tAuthentication by public key failed!\n");
|
fprintf(stderr, "\tAuthentication by public key failed!\n");
|
||||||
goto shutdown;
|
goto shutdown;
|
||||||
}
|
}
|
||||||
printf("\tAuthentication by public key succeeded.\n");
|
fprintf(stderr, "\tAuthentication by public key succeeded.\n");
|
||||||
} else {
|
} else {
|
||||||
printf("No supported authentication methods found!\n");
|
fprintf(stderr, "No supported authentication methods found!\n");
|
||||||
goto shutdown;
|
goto shutdown;
|
||||||
}
|
}
|
||||||
|
|
||||||
listensock = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP);
|
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_family = AF_INET;
|
||||||
sin.sin_port = htons(local_listenport);
|
sin.sin_port = htons(local_listenport);
|
||||||
if (INADDR_NONE == (sin.sin_addr.s_addr = inet_addr(local_listenip))) {
|
if (INADDR_NONE == (sin.sin_addr.s_addr = inet_addr(local_listenip))) {
|
||||||
@@ -185,20 +217,27 @@ int main(int argc, char *argv[])
|
|||||||
goto shutdown;
|
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));
|
inet_ntoa(sin.sin_addr), ntohs(sin.sin_port));
|
||||||
|
|
||||||
forwardsock = accept(listensock, (struct sockaddr *)&sin, &sinlen);
|
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");
|
perror("accept");
|
||||||
goto shutdown;
|
goto shutdown;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
shost = inet_ntoa(sin.sin_addr);
|
shost = inet_ntoa(sin.sin_addr);
|
||||||
sport = ntohs(sin.sin_port);
|
sport = ntohs(sin.sin_port);
|
||||||
|
|
||||||
printf("Forwarding connection from %s:%d here to remote %s:%d\n", shost,
|
fprintf(stderr, "Forwarding connection from %s:%d here to remote %s:%d\n",
|
||||||
sport, remote_desthost, remote_destport);
|
shost, sport, remote_desthost, remote_destport);
|
||||||
|
|
||||||
channel = libssh2_channel_direct_tcpip_ex(session, remote_desthost,
|
channel = libssh2_channel_direct_tcpip_ex(session, remote_desthost,
|
||||||
remote_destport, shost, sport);
|
remote_destport, shost, sport);
|
||||||
@@ -228,7 +267,8 @@ int main(int argc, char *argv[])
|
|||||||
perror("read");
|
perror("read");
|
||||||
goto shutdown;
|
goto shutdown;
|
||||||
} else if (0 == len) {
|
} 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;
|
goto shutdown;
|
||||||
}
|
}
|
||||||
wr = 0;
|
wr = 0;
|
||||||
@@ -259,7 +299,7 @@ int main(int argc, char *argv[])
|
|||||||
wr += i;
|
wr += i;
|
||||||
}
|
}
|
||||||
if (libssh2_channel_eof(channel)) {
|
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);
|
remote_desthost, remote_destport);
|
||||||
goto shutdown;
|
goto shutdown;
|
||||||
}
|
}
|
||||||
|
@@ -47,8 +47,13 @@ int main(int argc, char *argv[])
|
|||||||
|
|
||||||
#ifdef WIN32
|
#ifdef WIN32
|
||||||
WSADATA wsadata;
|
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
|
#endif
|
||||||
|
|
||||||
if (argc > 1) {
|
if (argc > 1) {
|
||||||
|
@@ -97,8 +97,13 @@ int main(int argc, char *argv[])
|
|||||||
|
|
||||||
#ifdef WIN32
|
#ifdef WIN32
|
||||||
WSADATA wsadata;
|
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
|
#endif
|
||||||
|
|
||||||
if (argc > 1) {
|
if (argc > 1) {
|
||||||
@@ -250,7 +255,7 @@ int main(int argc, char *argv[])
|
|||||||
gettimeofday(&end, NULL);
|
gettimeofday(&end, NULL);
|
||||||
|
|
||||||
time_ms = tvdiff(end, start);
|
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 );
|
time_ms, total/(time_ms/1000.0), spin );
|
||||||
|
|
||||||
libssh2_channel_free(channel);
|
libssh2_channel_free(channel);
|
||||||
|
@@ -51,8 +51,13 @@ int main(int argc, char *argv[])
|
|||||||
|
|
||||||
#ifdef WIN32
|
#ifdef WIN32
|
||||||
WSADATA wsadata;
|
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
|
#endif
|
||||||
|
|
||||||
if (argc > 1) {
|
if (argc > 1) {
|
||||||
|
@@ -90,8 +90,13 @@ int main(int argc, char *argv[])
|
|||||||
|
|
||||||
#ifdef WIN32
|
#ifdef WIN32
|
||||||
WSADATA wsadata;
|
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
|
#endif
|
||||||
|
|
||||||
if (argc > 1) {
|
if (argc > 1) {
|
||||||
@@ -243,7 +248,7 @@ int main(int argc, char *argv[])
|
|||||||
|
|
||||||
duration = (int)(time(NULL)-start);
|
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);
|
total, duration, total/(double)duration);
|
||||||
|
|
||||||
fprintf(stderr, "Sending EOF\n");
|
fprintf(stderr, "Sending EOF\n");
|
||||||
|
@@ -55,24 +55,24 @@ static void kbd_callback(const char *name, int name_len,
|
|||||||
char buf[1024];
|
char buf[1024];
|
||||||
(void)abstract;
|
(void)abstract;
|
||||||
|
|
||||||
printf("Performing keyboard-interactive authentication.\n");
|
fprintf(stderr, "Performing keyboard-interactive authentication.\n");
|
||||||
|
|
||||||
printf("Authentication name: '");
|
fprintf(stderr, "Authentication name: '");
|
||||||
fwrite(name, 1, name_len, stdout);
|
fwrite(name, 1, name_len, stderr);
|
||||||
printf("'\n");
|
fprintf(stderr, "'\n");
|
||||||
|
|
||||||
printf("Authentication instruction: '");
|
fprintf(stderr, "Authentication instruction: '");
|
||||||
fwrite(instruction, 1, instruction_len, stdout);
|
fwrite(instruction, 1, instruction_len, stderr);
|
||||||
printf("'\n");
|
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++) {
|
for (i = 0; i < num_prompts; i++) {
|
||||||
printf("Prompt %d from server: '", i);
|
fprintf(stderr, "Prompt %d from server: '", i);
|
||||||
fwrite(prompts[i].text, 1, prompts[i].length, stdout);
|
fwrite(prompts[i].text, 1, prompts[i].length, stderr);
|
||||||
printf("'\n");
|
fprintf(stderr, "'\n");
|
||||||
|
|
||||||
printf("Please type response: ");
|
fprintf(stderr, "Please type response: ");
|
||||||
fgets(buf, sizeof(buf), stdin);
|
fgets(buf, sizeof(buf), stdin);
|
||||||
n = strlen(buf);
|
n = strlen(buf);
|
||||||
while (n > 0 && strchr("\r\n", buf[n - 1]))
|
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].text = strdup(buf);
|
||||||
responses[i].length = n;
|
responses[i].length = n;
|
||||||
|
|
||||||
printf("Response %d from user is '", i);
|
fprintf(stderr, "Response %d from user is '", i);
|
||||||
fwrite(responses[i].text, 1, responses[i].length, stdout);
|
fwrite(responses[i].text, 1, responses[i].length, stderr);
|
||||||
printf("'\n\n");
|
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
|
#ifdef WIN32
|
||||||
WSADATA wsadata;
|
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
|
#endif
|
||||||
|
|
||||||
if (argc > 1) {
|
if (argc > 1) {
|
||||||
@@ -127,7 +133,7 @@ int main(int argc, char *argv[])
|
|||||||
|
|
||||||
rc = libssh2_init (0);
|
rc = libssh2_init (0);
|
||||||
if (rc != 0) {
|
if (rc != 0) {
|
||||||
fprintf (stderr, "libssh2 initialization failed (%d)\n", rc);
|
fprintf(stderr, "libssh2 initialization failed (%d)\n", rc);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -178,7 +184,7 @@ int main(int argc, char *argv[])
|
|||||||
|
|
||||||
/* check what authentication methods are available */
|
/* check what authentication methods are available */
|
||||||
userauthlist = libssh2_userauth_list(session, username, strlen(username));
|
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) {
|
if (strstr(userauthlist, "password") != NULL) {
|
||||||
auth_pw |= 1;
|
auth_pw |= 1;
|
||||||
}
|
}
|
||||||
@@ -211,21 +217,23 @@ int main(int argc, char *argv[])
|
|||||||
} else if (auth_pw & 2) {
|
} else if (auth_pw & 2) {
|
||||||
/* Or via keyboard-interactive */
|
/* Or via keyboard-interactive */
|
||||||
if (libssh2_userauth_keyboard_interactive(session, username, &kbd_callback) ) {
|
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;
|
goto shutdown;
|
||||||
} else {
|
} else {
|
||||||
printf("\tAuthentication by keyboard-interactive succeeded.\n");
|
fprintf(stderr,
|
||||||
|
"\tAuthentication by keyboard-interactive succeeded.\n");
|
||||||
}
|
}
|
||||||
} else if (auth_pw & 4) {
|
} else if (auth_pw & 4) {
|
||||||
/* Or by public key */
|
/* Or by public key */
|
||||||
if (libssh2_userauth_publickey_fromfile(session, username, keyfile1, keyfile2, password)) {
|
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;
|
goto shutdown;
|
||||||
} else {
|
} else {
|
||||||
printf("\tAuthentication by public key succeeded.\n");
|
fprintf(stderr, "\tAuthentication by public key succeeded.\n");
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
printf("No supported authentication methods found!\n");
|
fprintf(stderr, "No supported authentication methods found!\n");
|
||||||
goto shutdown;
|
goto shutdown;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -93,8 +93,13 @@ int main(int argc, char *argv[])
|
|||||||
|
|
||||||
#ifdef WIN32
|
#ifdef WIN32
|
||||||
WSADATA wsadata;
|
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
|
#endif
|
||||||
|
|
||||||
rc = libssh2_init (0);
|
rc = libssh2_init (0);
|
||||||
@@ -141,11 +146,11 @@ int main(int argc, char *argv[])
|
|||||||
* user, that's your call
|
* user, that's your call
|
||||||
*/
|
*/
|
||||||
fingerprint = libssh2_hostkey_hash(session, LIBSSH2_HOSTKEY_HASH_SHA1);
|
fingerprint = libssh2_hostkey_hash(session, LIBSSH2_HOSTKEY_HASH_SHA1);
|
||||||
printf("Fingerprint: ");
|
fprintf(stderr, "Fingerprint: ");
|
||||||
for(i = 0; i < 20; i++) {
|
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) {
|
if(argc > 1) {
|
||||||
username = argv[1];
|
username = argv[1];
|
||||||
@@ -162,7 +167,7 @@ int main(int argc, char *argv[])
|
|||||||
|
|
||||||
tempstorage = fopen(STORAGE, "wb");
|
tempstorage = fopen(STORAGE, "wb");
|
||||||
if(!tempstorage) {
|
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;
|
goto shutdown;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -171,7 +176,7 @@ int main(int argc, char *argv[])
|
|||||||
while ((rc = libssh2_userauth_password(session, username, password))
|
while ((rc = libssh2_userauth_password(session, username, password))
|
||||||
== LIBSSH2_ERROR_EAGAIN);
|
== LIBSSH2_ERROR_EAGAIN);
|
||||||
if (rc) {
|
if (rc) {
|
||||||
printf("Authentication by password failed.\n");
|
fprintf(stderr, "Authentication by password failed.\n");
|
||||||
goto shutdown;
|
goto shutdown;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
@@ -185,7 +190,7 @@ int main(int argc, char *argv[])
|
|||||||
password)) ==
|
password)) ==
|
||||||
LIBSSH2_ERROR_EAGAIN);
|
LIBSSH2_ERROR_EAGAIN);
|
||||||
if (rc) {
|
if (rc) {
|
||||||
printf("\tAuthentication by public key failed\n");
|
fprintf(stderr, "\tAuthentication by public key failed\n");
|
||||||
goto shutdown;
|
goto shutdown;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -341,7 +346,7 @@ int main(int argc, char *argv[])
|
|||||||
#endif
|
#endif
|
||||||
if (tempstorage)
|
if (tempstorage)
|
||||||
fclose(tempstorage);
|
fclose(tempstorage);
|
||||||
printf("all done\n");
|
fprintf(stderr, "all done\n");
|
||||||
|
|
||||||
libssh2_exit();
|
libssh2_exit();
|
||||||
|
|
||||||
|
@@ -55,8 +55,13 @@ int main(int argc, char *argv[])
|
|||||||
|
|
||||||
#ifdef WIN32
|
#ifdef WIN32
|
||||||
WSADATA wsadata;
|
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
|
#endif
|
||||||
|
|
||||||
if (argc > 1) {
|
if (argc > 1) {
|
||||||
@@ -86,7 +91,7 @@ int main(int argc, char *argv[])
|
|||||||
|
|
||||||
local = fopen(loclfile, "rb");
|
local = fopen(loclfile, "rb");
|
||||||
if (!local) {
|
if (!local) {
|
||||||
printf("Can't local file %s\n", loclfile);
|
fprintf(stderr, "Can't open local file %s\n", loclfile);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -129,16 +134,16 @@ int main(int argc, char *argv[])
|
|||||||
* user, that's your call
|
* user, that's your call
|
||||||
*/
|
*/
|
||||||
fingerprint = libssh2_hostkey_hash(session, LIBSSH2_HOSTKEY_HASH_SHA1);
|
fingerprint = libssh2_hostkey_hash(session, LIBSSH2_HOSTKEY_HASH_SHA1);
|
||||||
printf("Fingerprint: ");
|
fprintf(stderr, "Fingerprint: ");
|
||||||
for(i = 0; i < 20; i++) {
|
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) {
|
if (auth_pw) {
|
||||||
/* We could authenticate via password */
|
/* We could authenticate via password */
|
||||||
if (libssh2_userauth_password(session, username, password)) {
|
if (libssh2_userauth_password(session, username, password)) {
|
||||||
printf("Authentication by password failed.\n");
|
fprintf(stderr, "Authentication by password failed.\n");
|
||||||
goto shutdown;
|
goto shutdown;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
@@ -147,7 +152,7 @@ int main(int argc, char *argv[])
|
|||||||
"/home/username/.ssh/id_rsa.pub",
|
"/home/username/.ssh/id_rsa.pub",
|
||||||
"/home/username/.ssh/id_rsa",
|
"/home/username/.ssh/id_rsa",
|
||||||
password)) {
|
password)) {
|
||||||
printf("\tAuthentication by public key failed\n");
|
fprintf(stderr, "\tAuthentication by public key failed\n");
|
||||||
goto shutdown;
|
goto shutdown;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -174,12 +179,12 @@ int main(int argc, char *argv[])
|
|||||||
}
|
}
|
||||||
|
|
||||||
if(libssh2_sftp_fstat_ex(sftp_handle, &attrs, 0) < 0) {
|
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;
|
goto shutdown;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
libssh2_sftp_seek64(sftp_handle, attrs.filesize);
|
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");
|
fprintf(stderr, "libssh2_sftp_open() a handle for APPEND\n");
|
||||||
|
|
||||||
@@ -222,7 +227,7 @@ shutdown:
|
|||||||
#endif
|
#endif
|
||||||
if (local)
|
if (local)
|
||||||
fclose(local);
|
fclose(local);
|
||||||
printf("all done\n");
|
fprintf(stderr, "all done\n");
|
||||||
|
|
||||||
libssh2_exit();
|
libssh2_exit();
|
||||||
|
|
||||||
|
@@ -48,8 +48,13 @@ int main(int argc, char *argv[])
|
|||||||
|
|
||||||
#ifdef WIN32
|
#ifdef WIN32
|
||||||
WSADATA wsadata;
|
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
|
#endif
|
||||||
|
|
||||||
if (argc > 1) {
|
if (argc > 1) {
|
||||||
@@ -110,16 +115,16 @@ int main(int argc, char *argv[])
|
|||||||
* user, that's your call
|
* user, that's your call
|
||||||
*/
|
*/
|
||||||
fingerprint = libssh2_hostkey_hash(session, LIBSSH2_HOSTKEY_HASH_SHA1);
|
fingerprint = libssh2_hostkey_hash(session, LIBSSH2_HOSTKEY_HASH_SHA1);
|
||||||
printf("Fingerprint: ");
|
fprintf(stderr, "Fingerprint: ");
|
||||||
for(i = 0; i < 20; i++) {
|
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) {
|
if (auth_pw) {
|
||||||
/* We could authenticate via password */
|
/* We could authenticate via password */
|
||||||
if (libssh2_userauth_password(session, username, password)) {
|
if (libssh2_userauth_password(session, username, password)) {
|
||||||
printf("Authentication by password failed.\n");
|
fprintf(stderr, "Authentication by password failed.\n");
|
||||||
goto shutdown;
|
goto shutdown;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
@@ -128,7 +133,7 @@ int main(int argc, char *argv[])
|
|||||||
"/home/username/.ssh/id_rsa.pub",
|
"/home/username/.ssh/id_rsa.pub",
|
||||||
"/home/username/.ssh/id_rsa",
|
"/home/username/.ssh/id_rsa",
|
||||||
password)) {
|
password)) {
|
||||||
printf("\tAuthentication by public key failed\n");
|
fprintf(stderr, "\tAuthentication by public key failed\n");
|
||||||
goto shutdown;
|
goto shutdown;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -164,7 +169,7 @@ int main(int argc, char *argv[])
|
|||||||
#else
|
#else
|
||||||
close(sock);
|
close(sock);
|
||||||
#endif
|
#endif
|
||||||
printf("all done\n");
|
fprintf(stderr, "all done\n");
|
||||||
|
|
||||||
libssh2_exit();
|
libssh2_exit();
|
||||||
|
|
||||||
|
@@ -48,8 +48,13 @@ int main(int argc, char *argv[])
|
|||||||
|
|
||||||
#ifdef WIN32
|
#ifdef WIN32
|
||||||
WSADATA wsadata;
|
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
|
#endif
|
||||||
|
|
||||||
if (argc > 1) {
|
if (argc > 1) {
|
||||||
@@ -110,16 +115,16 @@ int main(int argc, char *argv[])
|
|||||||
* user, that's your call
|
* user, that's your call
|
||||||
*/
|
*/
|
||||||
fingerprint = libssh2_hostkey_hash(session, LIBSSH2_HOSTKEY_HASH_SHA1);
|
fingerprint = libssh2_hostkey_hash(session, LIBSSH2_HOSTKEY_HASH_SHA1);
|
||||||
printf("Fingerprint: ");
|
fprintf(stderr, "Fingerprint: ");
|
||||||
for(i = 0; i < 20; i++) {
|
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) {
|
if (auth_pw) {
|
||||||
/* We could authenticate via password */
|
/* We could authenticate via password */
|
||||||
if (libssh2_userauth_password(session, username, password)) {
|
if (libssh2_userauth_password(session, username, password)) {
|
||||||
printf("Authentication by password failed.\n");
|
fprintf(stderr, "Authentication by password failed.\n");
|
||||||
goto shutdown;
|
goto shutdown;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
@@ -128,7 +133,7 @@ int main(int argc, char *argv[])
|
|||||||
"/home/username/.ssh/id_rsa.pub",
|
"/home/username/.ssh/id_rsa.pub",
|
||||||
"/home/username/.ssh/id_rsa",
|
"/home/username/.ssh/id_rsa",
|
||||||
password)) {
|
password)) {
|
||||||
printf("\tAuthentication by public key failed\n");
|
fprintf(stderr, "\tAuthentication by public key failed\n");
|
||||||
goto shutdown;
|
goto shutdown;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -164,7 +169,7 @@ int main(int argc, char *argv[])
|
|||||||
#else
|
#else
|
||||||
close(sock);
|
close(sock);
|
||||||
#endif
|
#endif
|
||||||
printf("all done\n");
|
fprintf(stderr, "all done\n");
|
||||||
|
|
||||||
libssh2_exit();
|
libssh2_exit();
|
||||||
|
|
||||||
|
@@ -97,8 +97,13 @@ int main(int argc, char *argv[])
|
|||||||
|
|
||||||
#ifdef WIN32
|
#ifdef WIN32
|
||||||
WSADATA wsadata;
|
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
|
#endif
|
||||||
|
|
||||||
if (argc > 1) {
|
if (argc > 1) {
|
||||||
@@ -251,7 +256,7 @@ int main(int argc, char *argv[])
|
|||||||
|
|
||||||
gettimeofday(&end, NULL);
|
gettimeofday(&end, NULL);
|
||||||
time_ms = tvdiff(end, start);
|
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 );
|
time_ms, total/(time_ms/1000.0), spin );
|
||||||
|
|
||||||
libssh2_sftp_close(sftp_handle);
|
libssh2_sftp_close(sftp_handle);
|
||||||
@@ -259,7 +264,7 @@ int main(int argc, char *argv[])
|
|||||||
|
|
||||||
shutdown:
|
shutdown:
|
||||||
|
|
||||||
printf("libssh2_session_disconnect\n");
|
fprintf(stderr, "libssh2_session_disconnect\n");
|
||||||
while (libssh2_session_disconnect(session,
|
while (libssh2_session_disconnect(session,
|
||||||
"Normal Shutdown, Thank you") ==
|
"Normal Shutdown, Thank you") ==
|
||||||
LIBSSH2_ERROR_EAGAIN);
|
LIBSSH2_ERROR_EAGAIN);
|
||||||
|
@@ -54,8 +54,13 @@ int main(int argc, char *argv[])
|
|||||||
|
|
||||||
#ifdef WIN32
|
#ifdef WIN32
|
||||||
WSADATA wsadata;
|
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
|
#endif
|
||||||
|
|
||||||
if (argc > 1) {
|
if (argc > 1) {
|
||||||
@@ -85,7 +90,7 @@ int main(int argc, char *argv[])
|
|||||||
|
|
||||||
local = fopen(loclfile, "rb");
|
local = fopen(loclfile, "rb");
|
||||||
if (!local) {
|
if (!local) {
|
||||||
printf("Can't local file %s\n", loclfile);
|
fprintf(stderr, "Can't open local file %s\n", loclfile);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -128,16 +133,16 @@ int main(int argc, char *argv[])
|
|||||||
* user, that's your call
|
* user, that's your call
|
||||||
*/
|
*/
|
||||||
fingerprint = libssh2_hostkey_hash(session, LIBSSH2_HOSTKEY_HASH_SHA1);
|
fingerprint = libssh2_hostkey_hash(session, LIBSSH2_HOSTKEY_HASH_SHA1);
|
||||||
printf("Fingerprint: ");
|
fprintf(stderr, "Fingerprint: ");
|
||||||
for(i = 0; i < 20; i++) {
|
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) {
|
if (auth_pw) {
|
||||||
/* We could authenticate via password */
|
/* We could authenticate via password */
|
||||||
if (libssh2_userauth_password(session, username, password)) {
|
if (libssh2_userauth_password(session, username, password)) {
|
||||||
printf("Authentication by password failed.\n");
|
fprintf(stderr, "Authentication by password failed.\n");
|
||||||
goto shutdown;
|
goto shutdown;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
@@ -146,7 +151,7 @@ int main(int argc, char *argv[])
|
|||||||
"/home/username/.ssh/id_rsa.pub",
|
"/home/username/.ssh/id_rsa.pub",
|
||||||
"/home/username/.ssh/id_rsa",
|
"/home/username/.ssh/id_rsa",
|
||||||
password)) {
|
password)) {
|
||||||
printf("\tAuthentication by public key failed\n");
|
fprintf(stderr, "\tAuthentication by public key failed\n");
|
||||||
goto shutdown;
|
goto shutdown;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -206,7 +211,7 @@ shutdown:
|
|||||||
#endif
|
#endif
|
||||||
if (local)
|
if (local)
|
||||||
fclose(local);
|
fclose(local);
|
||||||
printf("all done\n");
|
fprintf(stderr, "all done\n");
|
||||||
|
|
||||||
libssh2_exit();
|
libssh2_exit();
|
||||||
|
|
||||||
|
@@ -94,8 +94,13 @@ int main(int argc, char *argv[])
|
|||||||
|
|
||||||
#ifdef WIN32
|
#ifdef WIN32
|
||||||
WSADATA wsadata;
|
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
|
#endif
|
||||||
|
|
||||||
if (argc > 1) {
|
if (argc > 1) {
|
||||||
@@ -125,7 +130,7 @@ int main(int argc, char *argv[])
|
|||||||
|
|
||||||
local = fopen(loclfile, "rb");
|
local = fopen(loclfile, "rb");
|
||||||
if (!local) {
|
if (!local) {
|
||||||
printf("Can't local file %s\n", loclfile);
|
fprintf(stderr, "Can't open local file %s\n", loclfile);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -169,18 +174,18 @@ int main(int argc, char *argv[])
|
|||||||
* that's your call
|
* that's your call
|
||||||
*/
|
*/
|
||||||
fingerprint = libssh2_hostkey_hash(session, LIBSSH2_HOSTKEY_HASH_SHA1);
|
fingerprint = libssh2_hostkey_hash(session, LIBSSH2_HOSTKEY_HASH_SHA1);
|
||||||
printf("Fingerprint: ");
|
fprintf(stderr, "Fingerprint: ");
|
||||||
for(i = 0; i < 20; i++) {
|
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) {
|
if (auth_pw) {
|
||||||
/* We could authenticate via password */
|
/* We could authenticate via password */
|
||||||
while ((rc = libssh2_userauth_password(session, username, password)) ==
|
while ((rc = libssh2_userauth_password(session, username, password)) ==
|
||||||
LIBSSH2_ERROR_EAGAIN);
|
LIBSSH2_ERROR_EAGAIN);
|
||||||
if (rc) {
|
if (rc) {
|
||||||
printf("Authentication by password failed.\n");
|
fprintf(stderr, "Authentication by password failed.\n");
|
||||||
goto shutdown;
|
goto shutdown;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
@@ -191,7 +196,7 @@ int main(int argc, char *argv[])
|
|||||||
password)) ==
|
password)) ==
|
||||||
LIBSSH2_ERROR_EAGAIN);
|
LIBSSH2_ERROR_EAGAIN);
|
||||||
if (rc) {
|
if (rc) {
|
||||||
printf("\tAuthentication by public key failed\n");
|
fprintf(stderr, "\tAuthentication by public key failed\n");
|
||||||
goto shutdown;
|
goto shutdown;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -253,7 +258,7 @@ int main(int argc, char *argv[])
|
|||||||
|
|
||||||
duration = (int)(time(NULL)-start);
|
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);
|
total, duration, total/(double)duration);
|
||||||
|
|
||||||
|
|
||||||
@@ -272,7 +277,7 @@ shutdown:
|
|||||||
#else
|
#else
|
||||||
close(sock);
|
close(sock);
|
||||||
#endif
|
#endif
|
||||||
printf("all done\n");
|
fprintf(stderr, "all done\n");
|
||||||
|
|
||||||
libssh2_exit();
|
libssh2_exit();
|
||||||
|
|
||||||
|
@@ -94,8 +94,13 @@ int main(int argc, char *argv[])
|
|||||||
|
|
||||||
#ifdef WIN32
|
#ifdef WIN32
|
||||||
WSADATA wsadata;
|
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
|
#endif
|
||||||
|
|
||||||
if (argc > 1) {
|
if (argc > 1) {
|
||||||
@@ -125,7 +130,7 @@ int main(int argc, char *argv[])
|
|||||||
|
|
||||||
local = fopen(loclfile, "rb");
|
local = fopen(loclfile, "rb");
|
||||||
if (!local) {
|
if (!local) {
|
||||||
printf("Can't local file %s\n", loclfile);
|
fprintf(stderr, "Can't open local file %s\n", loclfile);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -169,18 +174,18 @@ int main(int argc, char *argv[])
|
|||||||
* that's your call
|
* that's your call
|
||||||
*/
|
*/
|
||||||
fingerprint = libssh2_hostkey_hash(session, LIBSSH2_HOSTKEY_HASH_SHA1);
|
fingerprint = libssh2_hostkey_hash(session, LIBSSH2_HOSTKEY_HASH_SHA1);
|
||||||
printf("Fingerprint: ");
|
fprintf(stderr, "Fingerprint: ");
|
||||||
for(i = 0; i < 20; i++) {
|
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) {
|
if (auth_pw) {
|
||||||
/* We could authenticate via password */
|
/* We could authenticate via password */
|
||||||
while ((rc = libssh2_userauth_password(session, username, password)) ==
|
while ((rc = libssh2_userauth_password(session, username, password)) ==
|
||||||
LIBSSH2_ERROR_EAGAIN);
|
LIBSSH2_ERROR_EAGAIN);
|
||||||
if (rc) {
|
if (rc) {
|
||||||
printf("Authentication by password failed.\n");
|
fprintf(stderr, "Authentication by password failed.\n");
|
||||||
goto shutdown;
|
goto shutdown;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
@@ -191,7 +196,7 @@ int main(int argc, char *argv[])
|
|||||||
password)) ==
|
password)) ==
|
||||||
LIBSSH2_ERROR_EAGAIN);
|
LIBSSH2_ERROR_EAGAIN);
|
||||||
if (rc) {
|
if (rc) {
|
||||||
printf("\tAuthentication by public key failed\n");
|
fprintf(stderr, "\tAuthentication by public key failed\n");
|
||||||
goto shutdown;
|
goto shutdown;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -262,7 +267,7 @@ int main(int argc, char *argv[])
|
|||||||
|
|
||||||
duration = (int)(time(NULL)-start);
|
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);
|
total, duration, total/(double)duration);
|
||||||
|
|
||||||
|
|
||||||
@@ -281,7 +286,7 @@ shutdown:
|
|||||||
#else
|
#else
|
||||||
close(sock);
|
close(sock);
|
||||||
#endif
|
#endif
|
||||||
printf("all done\n");
|
fprintf(stderr, "all done\n");
|
||||||
|
|
||||||
libssh2_exit();
|
libssh2_exit();
|
||||||
|
|
||||||
|
@@ -52,24 +52,51 @@
|
|||||||
#define PRIu64 __PRI64_PREFIX "u"
|
#define PRIu64 __PRI64_PREFIX "u"
|
||||||
#endif /* PRIu64 */
|
#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[])
|
int main(int argc, char *argv[])
|
||||||
{
|
{
|
||||||
unsigned long hostaddr;
|
unsigned long hostaddr;
|
||||||
int sock, i, auth_pw = 1;
|
int rc, sock, i, auth_pw = 0;
|
||||||
struct sockaddr_in sin;
|
struct sockaddr_in sin;
|
||||||
const char *fingerprint;
|
const char *fingerprint;
|
||||||
|
char *userauthlist;
|
||||||
LIBSSH2_SESSION *session;
|
LIBSSH2_SESSION *session;
|
||||||
const char *username="username";
|
|
||||||
const char *password="password";
|
|
||||||
const char *sftppath="/tmp/secretdir";
|
const char *sftppath="/tmp/secretdir";
|
||||||
int rc;
|
|
||||||
LIBSSH2_SFTP *sftp_session;
|
LIBSSH2_SFTP *sftp_session;
|
||||||
LIBSSH2_SFTP_HANDLE *sftp_handle;
|
LIBSSH2_SFTP_HANDLE *sftp_handle;
|
||||||
|
|
||||||
#ifdef WIN32
|
#ifdef WIN32
|
||||||
WSADATA wsadata;
|
WSADATA wsadata;
|
||||||
|
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
|
#endif
|
||||||
|
|
||||||
if (argc > 1) {
|
if (argc > 1) {
|
||||||
@@ -130,27 +157,69 @@ int main(int argc, char *argv[])
|
|||||||
* user, that's your call
|
* user, that's your call
|
||||||
*/
|
*/
|
||||||
fingerprint = libssh2_hostkey_hash(session, LIBSSH2_HOSTKEY_HASH_SHA1);
|
fingerprint = libssh2_hostkey_hash(session, LIBSSH2_HOSTKEY_HASH_SHA1);
|
||||||
printf("Fingerprint: ");
|
fprintf(stderr, "Fingerprint: ");
|
||||||
for(i = 0; i < 20; i++) {
|
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 */
|
/* We could authenticate via password */
|
||||||
if (libssh2_userauth_password(session, username, password)) {
|
if (libssh2_userauth_password(session, username, password)) {
|
||||||
printf("Authentication by password failed.\n");
|
fprintf(stderr, "\tAuthentication by password failed!\n");
|
||||||
goto shutdown;
|
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 {
|
} else {
|
||||||
/* Or by public key */
|
fprintf(stderr, "No supported authentication methods found!\n");
|
||||||
if (libssh2_userauth_publickey_fromfile(session, username,
|
goto shutdown;
|
||||||
"/home/username/.ssh/id_rsa.pub",
|
|
||||||
"/home/username/.ssh/id_rsa",
|
|
||||||
password)) {
|
|
||||||
printf("\tAuthentication by public key failed\n");
|
|
||||||
goto shutdown;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fprintf(stderr, "libssh2_sftp_init()!\n");
|
fprintf(stderr, "libssh2_sftp_init()!\n");
|
||||||
@@ -229,7 +298,7 @@ int main(int argc, char *argv[])
|
|||||||
#else
|
#else
|
||||||
close(sock);
|
close(sock);
|
||||||
#endif
|
#endif
|
||||||
printf("all done\n");
|
fprintf(stderr, "all done\n");
|
||||||
|
|
||||||
libssh2_exit();
|
libssh2_exit();
|
||||||
|
|
||||||
|
@@ -68,8 +68,13 @@ int main(int argc, char *argv[])
|
|||||||
|
|
||||||
#ifdef WIN32
|
#ifdef WIN32
|
||||||
WSADATA wsadata;
|
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
|
#endif
|
||||||
|
|
||||||
if (argc > 1) {
|
if (argc > 1) {
|
||||||
@@ -134,11 +139,11 @@ int main(int argc, char *argv[])
|
|||||||
* user, that's your call
|
* user, that's your call
|
||||||
*/
|
*/
|
||||||
fingerprint = libssh2_hostkey_hash(session, LIBSSH2_HOSTKEY_HASH_SHA1);
|
fingerprint = libssh2_hostkey_hash(session, LIBSSH2_HOSTKEY_HASH_SHA1);
|
||||||
printf("Fingerprint: ");
|
fprintf(stderr, "Fingerprint: ");
|
||||||
for(i = 0; i < 20; i++) {
|
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) {
|
if (auth_pw) {
|
||||||
/* We could authenticate via password */
|
/* We could authenticate via password */
|
||||||
@@ -239,7 +244,7 @@ int main(int argc, char *argv[])
|
|||||||
#else
|
#else
|
||||||
close(sock);
|
close(sock);
|
||||||
#endif
|
#endif
|
||||||
printf("all done\n");
|
fprintf(stderr, "all done\n");
|
||||||
|
|
||||||
libssh2_exit();
|
libssh2_exit();
|
||||||
|
|
||||||
|
@@ -72,10 +72,16 @@ int main(int argc, char *argv[])
|
|||||||
char *userauthlist;
|
char *userauthlist;
|
||||||
LIBSSH2_SESSION *session;
|
LIBSSH2_SESSION *session;
|
||||||
LIBSSH2_CHANNEL *channel;
|
LIBSSH2_CHANNEL *channel;
|
||||||
|
|
||||||
#ifdef WIN32
|
#ifdef WIN32
|
||||||
WSADATA wsadata;
|
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
|
#endif
|
||||||
|
|
||||||
if (argc > 1) {
|
if (argc > 1) {
|
||||||
@@ -126,15 +132,15 @@ int main(int argc, char *argv[])
|
|||||||
* call
|
* call
|
||||||
*/
|
*/
|
||||||
fingerprint = libssh2_hostkey_hash(session, LIBSSH2_HOSTKEY_HASH_SHA1);
|
fingerprint = libssh2_hostkey_hash(session, LIBSSH2_HOSTKEY_HASH_SHA1);
|
||||||
printf("Fingerprint: ");
|
fprintf(stderr, "Fingerprint: ");
|
||||||
for(i = 0; i < 20; i++) {
|
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 */
|
/* check what authentication methods are available */
|
||||||
userauthlist = libssh2_userauth_list(session, username, strlen(username));
|
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) {
|
if (strstr(userauthlist, "password") != NULL) {
|
||||||
auth_pw |= 1;
|
auth_pw |= 1;
|
||||||
}
|
}
|
||||||
@@ -161,31 +167,33 @@ int main(int argc, char *argv[])
|
|||||||
if (auth_pw & 1) {
|
if (auth_pw & 1) {
|
||||||
/* We could authenticate via password */
|
/* We could authenticate via password */
|
||||||
if (libssh2_userauth_password(session, username, password)) {
|
if (libssh2_userauth_password(session, username, password)) {
|
||||||
printf("\tAuthentication by password failed!\n");
|
fprintf(stderr, "\tAuthentication by password failed!\n");
|
||||||
goto shutdown;
|
goto shutdown;
|
||||||
} else {
|
} else {
|
||||||
printf("\tAuthentication by password succeeded.\n");
|
fprintf(stderr, "\tAuthentication by password succeeded.\n");
|
||||||
}
|
}
|
||||||
} else if (auth_pw & 2) {
|
} else if (auth_pw & 2) {
|
||||||
/* Or via keyboard-interactive */
|
/* Or via keyboard-interactive */
|
||||||
if (libssh2_userauth_keyboard_interactive(session, username,
|
if (libssh2_userauth_keyboard_interactive(session, username,
|
||||||
&kbd_callback) ) {
|
&kbd_callback) ) {
|
||||||
printf("\tAuthentication by keyboard-interactive failed!\n");
|
fprintf(stderr,
|
||||||
|
"\tAuthentication by keyboard-interactive failed!\n");
|
||||||
goto shutdown;
|
goto shutdown;
|
||||||
} else {
|
} else {
|
||||||
printf("\tAuthentication by keyboard-interactive succeeded.\n");
|
fprintf(stderr,
|
||||||
|
"\tAuthentication by keyboard-interactive succeeded.\n");
|
||||||
}
|
}
|
||||||
} else if (auth_pw & 4) {
|
} else if (auth_pw & 4) {
|
||||||
/* Or by public key */
|
/* Or by public key */
|
||||||
if (libssh2_userauth_publickey_fromfile(session, username, keyfile1,
|
if (libssh2_userauth_publickey_fromfile(session, username, keyfile1,
|
||||||
keyfile2, password)) {
|
keyfile2, password)) {
|
||||||
printf("\tAuthentication by public key failed!\n");
|
fprintf(stderr, "\tAuthentication by public key failed!\n");
|
||||||
goto shutdown;
|
goto shutdown;
|
||||||
} else {
|
} else {
|
||||||
printf("\tAuthentication by public key succeeded.\n");
|
fprintf(stderr, "\tAuthentication by public key succeeded.\n");
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
printf("No supported authentication methods found!\n");
|
fprintf(stderr, "No supported authentication methods found!\n");
|
||||||
goto shutdown;
|
goto shutdown;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -250,7 +258,7 @@ int main(int argc, char *argv[])
|
|||||||
#else
|
#else
|
||||||
close(sock);
|
close(sock);
|
||||||
#endif
|
#endif
|
||||||
printf("all done!\n");
|
fprintf(stderr, "all done!\n");
|
||||||
|
|
||||||
libssh2_exit();
|
libssh2_exit();
|
||||||
|
|
||||||
|
@@ -49,10 +49,16 @@ int main(int argc, char *argv[])
|
|||||||
LIBSSH2_CHANNEL *channel;
|
LIBSSH2_CHANNEL *channel;
|
||||||
LIBSSH2_AGENT *agent = NULL;
|
LIBSSH2_AGENT *agent = NULL;
|
||||||
struct libssh2_agent_publickey *identity, *prev_identity = NULL;
|
struct libssh2_agent_publickey *identity, *prev_identity = NULL;
|
||||||
|
|
||||||
#ifdef WIN32
|
#ifdef WIN32
|
||||||
WSADATA wsadata;
|
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
|
#endif
|
||||||
|
|
||||||
if (argc > 1) {
|
if (argc > 1) {
|
||||||
@@ -105,15 +111,15 @@ int main(int argc, char *argv[])
|
|||||||
* call
|
* call
|
||||||
*/
|
*/
|
||||||
fingerprint = libssh2_hostkey_hash(session, LIBSSH2_HOSTKEY_HASH_SHA1);
|
fingerprint = libssh2_hostkey_hash(session, LIBSSH2_HOSTKEY_HASH_SHA1);
|
||||||
printf("Fingerprint: ");
|
fprintf(stderr, "Fingerprint: ");
|
||||||
for(i = 0; i < 20; i++) {
|
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 */
|
/* check what authentication methods are available */
|
||||||
userauthlist = libssh2_userauth_list(session, username, strlen(username));
|
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) {
|
if (strstr(userauthlist, "publickey") == NULL) {
|
||||||
fprintf(stderr, "\"publickey\" authentication is not supported\n");
|
fprintf(stderr, "\"publickey\" authentication is not supported\n");
|
||||||
goto shutdown;
|
goto shutdown;
|
||||||
@@ -147,11 +153,11 @@ int main(int argc, char *argv[])
|
|||||||
goto shutdown;
|
goto shutdown;
|
||||||
}
|
}
|
||||||
if (libssh2_agent_userauth(agent, username, identity)) {
|
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",
|
"public key %s failed!\n",
|
||||||
username, identity->comment);
|
username, identity->comment);
|
||||||
} else {
|
} else {
|
||||||
printf("\tAuthentication with username %s and "
|
fprintf(stderr, "\tAuthentication with username %s and "
|
||||||
"public key %s succeeded!\n",
|
"public key %s succeeded!\n",
|
||||||
username, identity->comment);
|
username, identity->comment);
|
||||||
break;
|
break;
|
||||||
@@ -234,7 +240,7 @@ int main(int argc, char *argv[])
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
printf("all done!\n");
|
fprintf(stderr, "all done!\n");
|
||||||
|
|
||||||
libssh2_exit();
|
libssh2_exit();
|
||||||
|
|
||||||
|
@@ -91,8 +91,15 @@ int main(int argc, char *argv[])
|
|||||||
|
|
||||||
#ifdef WIN32
|
#ifdef WIN32
|
||||||
WSADATA wsadata;
|
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
|
#endif
|
||||||
|
|
||||||
if (argc > 1)
|
if (argc > 1)
|
||||||
/* must be ip address only */
|
/* must be ip address only */
|
||||||
hostname = argv[1];
|
hostname = argv[1];
|
||||||
@@ -327,7 +334,7 @@ int main(int argc, char *argv[])
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (exitsignal)
|
if (exitsignal)
|
||||||
printf("\nGot signal: %s\n", exitsignal);
|
fprintf(stderr, "\nGot signal: %s\n", exitsignal);
|
||||||
|
|
||||||
libssh2_channel_free(channel);
|
libssh2_channel_free(channel);
|
||||||
channel = NULL;
|
channel = NULL;
|
||||||
|
@@ -92,8 +92,15 @@ int main(int argc, char *argv[])
|
|||||||
|
|
||||||
#ifdef WIN32
|
#ifdef WIN32
|
||||||
WSADATA wsadata;
|
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
|
#endif
|
||||||
|
|
||||||
if (argc > 1)
|
if (argc > 1)
|
||||||
/* must be ip address only */
|
/* must be ip address only */
|
||||||
hostname = argv[1];
|
hostname = argv[1];
|
||||||
@@ -292,9 +299,9 @@ int main(int argc, char *argv[])
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (exitsignal)
|
if (exitsignal)
|
||||||
printf("\nGot signal: %s\n", exitsignal);
|
fprintf(stderr, "\nGot signal: %s\n", exitsignal);
|
||||||
else
|
else
|
||||||
printf("\nEXIT: %d bytecount: %d\n", exitcode, bytecount);
|
fprintf(stderr, "\nEXIT: %d bytecount: %d\n", exitcode, bytecount);
|
||||||
|
|
||||||
libssh2_channel_free(channel);
|
libssh2_channel_free(channel);
|
||||||
channel = NULL;
|
channel = NULL;
|
||||||
|
@@ -102,7 +102,7 @@ static int netconf_read_until(LIBSSH2_CHANNEL *channel, const char *endtag,
|
|||||||
|
|
||||||
int main(int argc, char *argv[])
|
int main(int argc, char *argv[])
|
||||||
{
|
{
|
||||||
int rc, sock = -1, i, auth = AUTH_NONE;
|
int rc, i, auth = AUTH_NONE;
|
||||||
struct sockaddr_in sin;
|
struct sockaddr_in sin;
|
||||||
const char *fingerprint;
|
const char *fingerprint;
|
||||||
char *userauthlist;
|
char *userauthlist;
|
||||||
@@ -112,9 +112,17 @@ int main(int argc, char *argv[])
|
|||||||
ssize_t len;
|
ssize_t len;
|
||||||
|
|
||||||
#ifdef WIN32
|
#ifdef WIN32
|
||||||
|
SOCKET sock = INVALID_SOCKET;
|
||||||
WSADATA wsadata;
|
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
|
#endif
|
||||||
|
|
||||||
if (argc > 1)
|
if (argc > 1)
|
||||||
@@ -132,6 +140,18 @@ int main(int argc, char *argv[])
|
|||||||
|
|
||||||
/* Connect to SSH server */
|
/* Connect to SSH server */
|
||||||
sock = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP);
|
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;
|
sin.sin_family = AF_INET;
|
||||||
if (INADDR_NONE == (sin.sin_addr.s_addr = inet_addr(server_ip))) {
|
if (INADDR_NONE == (sin.sin_addr.s_addr = inet_addr(server_ip))) {
|
||||||
fprintf(stderr, "inet_addr: Invalid IP address \"%s\"\n", 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 */
|
/* check what authentication methods are available */
|
||||||
userauthlist = libssh2_userauth_list(session, username, strlen(username));
|
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"))
|
if (strstr(userauthlist, "password"))
|
||||||
auth |= AUTH_PASSWORD;
|
auth |= AUTH_PASSWORD;
|
||||||
if (strstr(userauthlist, "publickey"))
|
if (strstr(userauthlist, "publickey"))
|
||||||
@@ -195,12 +215,12 @@ int main(int argc, char *argv[])
|
|||||||
} else if (auth & AUTH_PUBLICKEY) {
|
} else if (auth & AUTH_PUBLICKEY) {
|
||||||
if (libssh2_userauth_publickey_fromfile(session, username, keyfile1,
|
if (libssh2_userauth_publickey_fromfile(session, username, keyfile1,
|
||||||
keyfile2, password)) {
|
keyfile2, password)) {
|
||||||
printf("Authentication by public key failed!\n");
|
fprintf(stderr, "Authentication by public key failed!\n");
|
||||||
goto shutdown;
|
goto shutdown;
|
||||||
}
|
}
|
||||||
printf("Authentication by public key succeeded.\n");
|
fprintf(stderr, "Authentication by public key succeeded.\n");
|
||||||
} else {
|
} else {
|
||||||
printf("No supported authentication methods found!\n");
|
fprintf(stderr, "No supported authentication methods found!\n");
|
||||||
goto shutdown;
|
goto shutdown;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -223,7 +243,7 @@ int main(int argc, char *argv[])
|
|||||||
|
|
||||||
/* NETCONF: http://tools.ietf.org/html/draft-ietf-netconf-ssh-06 */
|
/* 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),
|
snprintf(buf, sizeof(buf),
|
||||||
"<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"
|
"<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"
|
||||||
"<hello>"
|
"<hello>"
|
||||||
@@ -235,14 +255,14 @@ int main(int argc, char *argv[])
|
|||||||
if (-1 == netconf_write(channel, buf, len))
|
if (-1 == netconf_write(channel, buf, len))
|
||||||
goto shutdown;
|
goto shutdown;
|
||||||
|
|
||||||
printf("Reading NETCONF server <hello>\n");
|
fprintf(stderr, "Reading NETCONF server <hello>\n");
|
||||||
len = netconf_read_until(channel, "</hello>", buf, sizeof(buf));
|
len = netconf_read_until(channel, "</hello>", buf, sizeof(buf));
|
||||||
if (-1 == len)
|
if (-1 == len)
|
||||||
goto shutdown;
|
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),
|
snprintf(buf, sizeof(buf),
|
||||||
"<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"
|
"<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"
|
||||||
"<rpc xmlns=\"urn:ietf:params:xml:ns:netconf:base:1.0\">"
|
"<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))
|
if (-1 == netconf_write(channel, buf, len))
|
||||||
goto shutdown;
|
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));
|
len = netconf_read_until(channel, "</rpc-reply>", buf, sizeof(buf));
|
||||||
if (-1 == len)
|
if (-1 == len)
|
||||||
goto shutdown;
|
goto shutdown;
|
||||||
|
|
||||||
printf("Got %d bytes:\n----------------------\n%s", (int)len, buf);
|
fprintf(stderr, "Got %d bytes:\n----------------------\n%s", (int)len, buf);
|
||||||
|
|
||||||
shutdown:
|
shutdown:
|
||||||
if (channel)
|
if (channel)
|
||||||
|
@@ -35,11 +35,11 @@ const char *password = "";
|
|||||||
const char *server_ip = "127.0.0.1";
|
const char *server_ip = "127.0.0.1";
|
||||||
|
|
||||||
const char *remote_listenhost = "localhost"; /* resolved by the server */
|
const char *remote_listenhost = "localhost"; /* resolved by the server */
|
||||||
unsigned int remote_wantport = 2222;
|
int remote_wantport = 2222;
|
||||||
unsigned int remote_listenport;
|
int remote_listenport;
|
||||||
|
|
||||||
const char *local_destip = "127.0.0.1";
|
const char *local_destip = "127.0.0.1";
|
||||||
unsigned int local_destport = 22;
|
int local_destport = 22;
|
||||||
|
|
||||||
enum {
|
enum {
|
||||||
AUTH_NONE = 0,
|
AUTH_NONE = 0,
|
||||||
@@ -49,7 +49,7 @@ enum {
|
|||||||
|
|
||||||
int main(int argc, char *argv[])
|
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;
|
struct sockaddr_in sin;
|
||||||
socklen_t sinlen = sizeof(sin);
|
socklen_t sinlen = sizeof(sin);
|
||||||
const char *fingerprint;
|
const char *fingerprint;
|
||||||
@@ -57,20 +57,23 @@ int main(int argc, char *argv[])
|
|||||||
LIBSSH2_SESSION *session;
|
LIBSSH2_SESSION *session;
|
||||||
LIBSSH2_LISTENER *listener = NULL;
|
LIBSSH2_LISTENER *listener = NULL;
|
||||||
LIBSSH2_CHANNEL *channel = NULL;
|
LIBSSH2_CHANNEL *channel = NULL;
|
||||||
const char *shost;
|
|
||||||
unsigned int sport;
|
|
||||||
fd_set fds;
|
fd_set fds;
|
||||||
struct timeval tv;
|
struct timeval tv;
|
||||||
ssize_t len, wr;
|
ssize_t len, wr;
|
||||||
char buf[16384];
|
char buf[16384];
|
||||||
|
|
||||||
#ifdef WIN32
|
#ifdef WIN32
|
||||||
char sockopt;
|
SOCKET sock = INVALID_SOCKET, forwardsock = INVALID_SOCKET;
|
||||||
WSADATA wsadata;
|
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
|
#else
|
||||||
int sockopt;
|
int sock = -1, forwardsock = -1;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (argc > 1)
|
if (argc > 1)
|
||||||
@@ -96,6 +99,18 @@ int main(int argc, char *argv[])
|
|||||||
|
|
||||||
/* Connect to SSH server */
|
/* Connect to SSH server */
|
||||||
sock = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP);
|
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;
|
sin.sin_family = AF_INET;
|
||||||
if (INADDR_NONE == (sin.sin_addr.s_addr = inet_addr(server_ip))) {
|
if (INADDR_NONE == (sin.sin_addr.s_addr = inet_addr(server_ip))) {
|
||||||
perror("inet_addr");
|
perror("inet_addr");
|
||||||
@@ -137,7 +152,7 @@ int main(int argc, char *argv[])
|
|||||||
|
|
||||||
/* check what authentication methods are available */
|
/* check what authentication methods are available */
|
||||||
userauthlist = libssh2_userauth_list(session, username, strlen(username));
|
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"))
|
if (strstr(userauthlist, "password"))
|
||||||
auth |= AUTH_PASSWORD;
|
auth |= AUTH_PASSWORD;
|
||||||
if (strstr(userauthlist, "publickey"))
|
if (strstr(userauthlist, "publickey"))
|
||||||
@@ -159,17 +174,17 @@ int main(int argc, char *argv[])
|
|||||||
} else if (auth & AUTH_PUBLICKEY) {
|
} else if (auth & AUTH_PUBLICKEY) {
|
||||||
if (libssh2_userauth_publickey_fromfile(session, username, keyfile1,
|
if (libssh2_userauth_publickey_fromfile(session, username, keyfile1,
|
||||||
keyfile2, password)) {
|
keyfile2, password)) {
|
||||||
printf("\tAuthentication by public key failed!\n");
|
fprintf(stderr, "\tAuthentication by public key failed!\n");
|
||||||
goto shutdown;
|
goto shutdown;
|
||||||
}
|
}
|
||||||
printf("\tAuthentication by public key succeeded.\n");
|
fprintf(stderr, "\tAuthentication by public key succeeded.\n");
|
||||||
} else {
|
} else {
|
||||||
printf("No supported authentication methods found!\n");
|
fprintf(stderr, "No supported authentication methods found!\n");
|
||||||
goto shutdown;
|
goto shutdown;
|
||||||
}
|
}
|
||||||
|
|
||||||
printf("Asking server to listen on remote %s:%d\n", remote_listenhost,
|
fprintf(stderr, "Asking server to listen on remote %s:%d\n",
|
||||||
remote_wantport);
|
remote_listenhost, remote_wantport);
|
||||||
|
|
||||||
listener = libssh2_channel_forward_listen_ex(session, remote_listenhost,
|
listener = libssh2_channel_forward_listen_ex(session, remote_listenhost,
|
||||||
remote_wantport, &remote_listenport, 1);
|
remote_wantport, &remote_listenport, 1);
|
||||||
@@ -180,10 +195,10 @@ int main(int argc, char *argv[])
|
|||||||
goto shutdown;
|
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);
|
remote_listenport);
|
||||||
|
|
||||||
printf("Waiting for remote connection\n");
|
fprintf(stderr, "Waiting for remote connection\n");
|
||||||
channel = libssh2_channel_forward_accept(listener);
|
channel = libssh2_channel_forward_accept(listener);
|
||||||
if (!channel) {
|
if (!channel) {
|
||||||
fprintf(stderr, "Could not accept connection!\n"
|
fprintf(stderr, "Could not accept connection!\n"
|
||||||
@@ -192,9 +207,22 @@ int main(int argc, char *argv[])
|
|||||||
goto shutdown;
|
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);
|
local_destip, local_destport);
|
||||||
forwardsock = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP);
|
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_family = AF_INET;
|
||||||
sin.sin_port = htons(local_destport);
|
sin.sin_port = htons(local_destport);
|
||||||
if (INADDR_NONE == (sin.sin_addr.s_addr = inet_addr(local_destip))) {
|
if (INADDR_NONE == (sin.sin_addr.s_addr = inet_addr(local_destip))) {
|
||||||
@@ -206,7 +234,7 @@ int main(int argc, char *argv[])
|
|||||||
goto shutdown;
|
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);
|
remote_listenhost, remote_listenport, local_destip, local_destport);
|
||||||
|
|
||||||
/* Must use non-blocking IO hereafter due to the current libssh2 API */
|
/* Must use non-blocking IO hereafter due to the current libssh2 API */
|
||||||
@@ -228,7 +256,7 @@ int main(int argc, char *argv[])
|
|||||||
perror("read");
|
perror("read");
|
||||||
goto shutdown;
|
goto shutdown;
|
||||||
} else if (0 == len) {
|
} 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);
|
local_destip, local_destport);
|
||||||
goto shutdown;
|
goto shutdown;
|
||||||
}
|
}
|
||||||
@@ -260,7 +288,7 @@ int main(int argc, char *argv[])
|
|||||||
wr += i;
|
wr += i;
|
||||||
}
|
}
|
||||||
if (libssh2_channel_eof(channel)) {
|
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);
|
remote_listenhost, remote_listenport);
|
||||||
goto shutdown;
|
goto shutdown;
|
||||||
}
|
}
|
||||||
|
@@ -10,6 +10,7 @@
|
|||||||
#include <sys/ioctl.h>
|
#include <sys/ioctl.h>
|
||||||
#include <netinet/in.h>
|
#include <netinet/in.h>
|
||||||
#include <sys/socket.h>
|
#include <sys/socket.h>
|
||||||
|
#include <sys/select.h>
|
||||||
#include <arpa/inet.h>
|
#include <arpa/inet.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
@@ -48,13 +49,13 @@ static void remove_node(struct chan_X11_list *elem)
|
|||||||
current_node = gp_x11_chan;
|
current_node = gp_x11_chan;
|
||||||
|
|
||||||
if (gp_x11_chan == elem) {
|
if (gp_x11_chan == elem) {
|
||||||
/* Removing the only one element in the list */
|
gp_x11_chan = gp_x11_chan->next;
|
||||||
free(gp_x11_chan);
|
free(current_node);
|
||||||
gp_x11_chan = NULL;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
while( current_node->next != NULL) {
|
while (current_node->next != NULL) {
|
||||||
if (current_node->next ==elem) {
|
if (current_node->next == elem) {
|
||||||
current_node->next = current_node->next->next;
|
current_node->next = current_node->next->next;
|
||||||
current_node = current_node->next;
|
current_node = current_node->next;
|
||||||
free(current_node);
|
free(current_node);
|
||||||
@@ -209,24 +210,27 @@ static int x11_send_receive(LIBSSH2_CHANNEL *channel, int sock)
|
|||||||
rc = libssh2_poll(fds, nfds, 0);
|
rc = libssh2_poll(fds, nfds, 0);
|
||||||
if (rc >0) {
|
if (rc >0) {
|
||||||
rc = libssh2_channel_read(channel, buf, bufsize);
|
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) {
|
if (rc > 0) {
|
||||||
memset((void *)buf,0,bufsize);
|
memset((void *)buf, 0, bufsize);
|
||||||
|
|
||||||
/* Data in sock*/
|
/* Data in sock*/
|
||||||
rc = read(sock, buf, bufsize);
|
rc = read(sock, buf, bufsize);
|
||||||
if (rc > 0)
|
if (rc > 0) {
|
||||||
rc = libssh2_channel_write(channel,buf, rc);
|
libssh2_channel_write(channel, buf, rc);
|
||||||
else
|
}
|
||||||
|
else {
|
||||||
|
free(buf);
|
||||||
return -1;
|
return -1;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
free(fds);
|
free(fds);
|
||||||
free(buf);
|
free(buf);
|
||||||
if (libssh2_channel_eof (channel) == 1) {
|
if (libssh2_channel_eof(channel) == 1) {
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
@@ -289,6 +293,10 @@ main (int argc, char *argv[])
|
|||||||
}
|
}
|
||||||
|
|
||||||
sock = socket (AF_INET, SOCK_STREAM, 0);
|
sock = socket (AF_INET, SOCK_STREAM, 0);
|
||||||
|
if (sock == -1) {
|
||||||
|
perror("socket");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
sin.sin_family = AF_INET;
|
sin.sin_family = AF_INET;
|
||||||
sin.sin_port = htons (22);
|
sin.sin_port = htons (22);
|
||||||
@@ -369,6 +377,9 @@ main (int argc, char *argv[])
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
memset(&w_size, 0, sizeof(struct winsize));
|
||||||
|
memset(&w_size_bck, 0, sizeof(struct winsize));
|
||||||
|
|
||||||
while (1) {
|
while (1) {
|
||||||
|
|
||||||
FD_ZERO(&set);
|
FD_ZERO(&set);
|
||||||
@@ -400,7 +411,7 @@ main (int argc, char *argv[])
|
|||||||
|
|
||||||
rc = libssh2_poll(fds, nfds, 0);
|
rc = libssh2_poll(fds, nfds, 0);
|
||||||
if (rc >0) {
|
if (rc >0) {
|
||||||
rc = libssh2_channel_read(channel, buf,sizeof(buf));
|
libssh2_channel_read(channel, buf, sizeof(buf));
|
||||||
fprintf(stdout, "%s", buf);
|
fprintf(stdout, "%s", buf);
|
||||||
fflush(stdout);
|
fflush(stdout);
|
||||||
}
|
}
|
||||||
|
@@ -40,19 +40,19 @@
|
|||||||
#ifndef LIBSSH2_H
|
#ifndef LIBSSH2_H
|
||||||
#define LIBSSH2_H 1
|
#define LIBSSH2_H 1
|
||||||
|
|
||||||
#define LIBSSH2_COPYRIGHT "2004-2012 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
|
/* 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
|
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
|
banner. Release versions have no appended strings and may of course not
|
||||||
have dashes either. */
|
have dashes either. */
|
||||||
#define LIBSSH2_VERSION "1.4.2_DEV"
|
#define LIBSSH2_VERSION "1.4.4_DEV"
|
||||||
|
|
||||||
/* The numeric version number is also available "in parts" by using these
|
/* The numeric version number is also available "in parts" by using these
|
||||||
defines: */
|
defines: */
|
||||||
#define LIBSSH2_VERSION_MAJOR 1
|
#define LIBSSH2_VERSION_MAJOR 1
|
||||||
#define LIBSSH2_VERSION_MINOR 4
|
#define LIBSSH2_VERSION_MINOR 4
|
||||||
#define LIBSSH2_VERSION_PATCH 2
|
#define LIBSSH2_VERSION_PATCH 4
|
||||||
|
|
||||||
/* This is the numeric version of the libssh2 version number, meant for easier
|
/* This is the numeric version of the libssh2 version number, meant for easier
|
||||||
parsing and comparions by programs. The LIBSSH2_VERSION_NUM define will
|
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
|
and it is always a greater number in a more recent release. It makes
|
||||||
comparisons with greater than and less than work.
|
comparisons with greater than and less than work.
|
||||||
*/
|
*/
|
||||||
#define LIBSSH2_VERSION_NUM 0x010402
|
#define LIBSSH2_VERSION_NUM 0x010404
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* This is the date and time when the full source package was created. The
|
* This is the date and time when the full source package was created. The
|
||||||
@@ -100,11 +100,15 @@ extern "C" {
|
|||||||
/* Allow alternate API prefix from CFLAGS or calling app */
|
/* Allow alternate API prefix from CFLAGS or calling app */
|
||||||
#ifndef LIBSSH2_API
|
#ifndef LIBSSH2_API
|
||||||
# ifdef LIBSSH2_WIN32
|
# ifdef LIBSSH2_WIN32
|
||||||
# ifdef LIBSSH2_LIBRARY
|
# ifdef _WINDLL
|
||||||
# define LIBSSH2_API __declspec(dllexport)
|
# ifdef LIBSSH2_LIBRARY
|
||||||
|
# define LIBSSH2_API __declspec(dllexport)
|
||||||
|
# else
|
||||||
|
# define LIBSSH2_API __declspec(dllimport)
|
||||||
|
# endif /* LIBSSH2_LIBRARY */
|
||||||
# else
|
# else
|
||||||
# define LIBSSH2_API __declspec(dllimport)
|
# define LIBSSH2_API
|
||||||
# endif /* LIBSSH2_LIBRARY */
|
# endif
|
||||||
# else /* !LIBSSH2_WIN32 */
|
# else /* !LIBSSH2_WIN32 */
|
||||||
# define LIBSSH2_API
|
# define LIBSSH2_API
|
||||||
# endif /* LIBSSH2_WIN32 */
|
# endif /* LIBSSH2_WIN32 */
|
||||||
@@ -281,7 +285,8 @@ typedef struct _LIBSSH2_POLLFD {
|
|||||||
unsigned char type; /* LIBSSH2_POLLFD_* below */
|
unsigned char type; /* LIBSSH2_POLLFD_* below */
|
||||||
|
|
||||||
union {
|
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_CHANNEL *channel; /* Examined by checking internal state */
|
||||||
LIBSSH2_LISTENER *listener; /* Read polls only -- are inbound
|
LIBSSH2_LISTENER *listener; /* Read polls only -- are inbound
|
||||||
connections waiting to be accepted? */
|
connections waiting to be accepted? */
|
||||||
@@ -405,6 +410,7 @@ typedef struct _LIBSSH2_POLLFD {
|
|||||||
#define LIBSSH2_ERROR_SOCKET_RECV -43
|
#define LIBSSH2_ERROR_SOCKET_RECV -43
|
||||||
#define LIBSSH2_ERROR_ENCRYPT -44
|
#define LIBSSH2_ERROR_ENCRYPT -44
|
||||||
#define LIBSSH2_ERROR_BAD_SOCKET -45
|
#define LIBSSH2_ERROR_BAD_SOCKET -45
|
||||||
|
#define LIBSSH2_ERROR_KNOWN_HOSTS -46
|
||||||
|
|
||||||
/* this is a define to provide the old (<= 1.2.7) name */
|
/* this is a define to provide the old (<= 1.2.7) name */
|
||||||
#define LIBSSH2_ERROR_BANNER_NONE LIBSSH2_ERROR_BANNER_RECV
|
#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)));
|
LIBSSH2_PASSWD_CHANGEREQ_FUNC((*passwd_change_cb)));
|
||||||
|
|
||||||
#define libssh2_userauth_password(session, username, password) \
|
#define libssh2_userauth_password(session, username, password) \
|
||||||
libssh2_userauth_password_ex((session), (username), strlen(username), \
|
libssh2_userauth_password_ex((session), (username), \
|
||||||
(password), strlen(password), NULL)
|
(unsigned int)strlen(username), \
|
||||||
|
(password), (unsigned int)strlen(password), NULL)
|
||||||
|
|
||||||
LIBSSH2_API int
|
LIBSSH2_API int
|
||||||
libssh2_userauth_publickey_fromfile_ex(LIBSSH2_SESSION *session,
|
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, \
|
#define libssh2_userauth_publickey_fromfile(session, username, publickey, \
|
||||||
privatekey, passphrase) \
|
privatekey, passphrase) \
|
||||||
libssh2_userauth_publickey_fromfile_ex((session), (username), \
|
libssh2_userauth_publickey_fromfile_ex((session), (username), \
|
||||||
strlen(username), (publickey), \
|
(unsigned int)strlen(username), \
|
||||||
(privatekey), (passphrase))
|
(publickey), \
|
||||||
|
(privatekey), (passphrase))
|
||||||
|
|
||||||
LIBSSH2_API int
|
LIBSSH2_API int
|
||||||
libssh2_userauth_publickey(LIBSSH2_SESSION *session,
|
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, \
|
#define libssh2_userauth_hostbased_fromfile(session, username, publickey, \
|
||||||
privatekey, passphrase, hostname) \
|
privatekey, passphrase, hostname) \
|
||||||
libssh2_userauth_hostbased_fromfile_ex((session), (username), \
|
libssh2_userauth_hostbased_fromfile_ex((session), (username), \
|
||||||
strlen(username), (publickey), \
|
(unsigned int)strlen(username), \
|
||||||
(privatekey), (passphrase), \
|
(publickey), \
|
||||||
(hostname), strlen(hostname), \
|
(privatekey), (passphrase), \
|
||||||
(username), strlen(username))
|
(hostname), \
|
||||||
|
(unsigned int)strlen(hostname), \
|
||||||
|
(username), \
|
||||||
|
(unsigned int)strlen(username))
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* response_callback is provided with filled by library prompts array,
|
* 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,
|
unsigned int username_len,
|
||||||
LIBSSH2_USERAUTH_KBDINT_RESPONSE_FUNC((*response_callback)));
|
LIBSSH2_USERAUTH_KBDINT_RESPONSE_FUNC((*response_callback)));
|
||||||
|
|
||||||
#define libssh2_userauth_keyboard_interactive(session, username, \
|
#define libssh2_userauth_keyboard_interactive(session, username, \
|
||||||
response_callback) \
|
response_callback) \
|
||||||
libssh2_userauth_keyboard_interactive_ex((session), (username), \
|
libssh2_userauth_keyboard_interactive_ex((session), (username), \
|
||||||
strlen(username), (response_callback))
|
(unsigned int)strlen(username), \
|
||||||
|
(response_callback))
|
||||||
|
|
||||||
LIBSSH2_API int libssh2_poll(LIBSSH2_POLLFD *fds, unsigned int nfds,
|
LIBSSH2_API int libssh2_poll(LIBSSH2_POLLFD *fds, unsigned int nfds,
|
||||||
long timeout);
|
long timeout);
|
||||||
|
|
||||||
/* Channel API */
|
/* 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_PACKET_DEFAULT 32768
|
||||||
#define LIBSSH2_CHANNEL_MINADJUST 1024
|
#define LIBSSH2_CHANNEL_MINADJUST 1024
|
||||||
|
|
||||||
@@ -634,9 +646,10 @@ LIBSSH2_API int libssh2_channel_setenv_ex(LIBSSH2_CHANNEL *channel,
|
|||||||
const char *value,
|
const char *value,
|
||||||
unsigned int value_len);
|
unsigned int value_len);
|
||||||
|
|
||||||
#define libssh2_channel_setenv(channel, varname, value) \
|
#define libssh2_channel_setenv(channel, varname, value) \
|
||||||
libssh2_channel_setenv_ex((channel), (varname), strlen(varname), (value), \
|
libssh2_channel_setenv_ex((channel), (varname), \
|
||||||
strlen(value))
|
(unsigned int)strlen(varname), (value), \
|
||||||
|
(unsigned int)strlen(value))
|
||||||
|
|
||||||
LIBSSH2_API int libssh2_channel_request_pty_ex(LIBSSH2_CHANNEL *channel,
|
LIBSSH2_API int libssh2_channel_request_pty_ex(LIBSSH2_CHANNEL *channel,
|
||||||
const char *term,
|
const char *term,
|
||||||
@@ -645,10 +658,12 @@ LIBSSH2_API int libssh2_channel_request_pty_ex(LIBSSH2_CHANNEL *channel,
|
|||||||
unsigned int modes_len,
|
unsigned int modes_len,
|
||||||
int width, int height,
|
int width, int height,
|
||||||
int width_px, int height_px);
|
int width_px, int height_px);
|
||||||
#define libssh2_channel_request_pty(channel, term) \
|
#define libssh2_channel_request_pty(channel, term) \
|
||||||
libssh2_channel_request_pty_ex((channel), (term), strlen(term), NULL, 0, \
|
libssh2_channel_request_pty_ex((channel), (term), \
|
||||||
LIBSSH2_TERM_WIDTH, LIBSSH2_TERM_HEIGHT, \
|
(unsigned int)strlen(term), \
|
||||||
LIBSSH2_TERM_WIDTH_PX, LIBSSH2_TERM_HEIGHT_PX)
|
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,
|
LIBSSH2_API int libssh2_channel_request_pty_size_ex(LIBSSH2_CHANNEL *channel,
|
||||||
int width, int height,
|
int width, int height,
|
||||||
@@ -675,11 +690,11 @@ LIBSSH2_API int libssh2_channel_process_startup(LIBSSH2_CHANNEL *channel,
|
|||||||
NULL, 0)
|
NULL, 0)
|
||||||
#define libssh2_channel_exec(channel, command) \
|
#define libssh2_channel_exec(channel, command) \
|
||||||
libssh2_channel_process_startup((channel), "exec", sizeof("exec") - 1, \
|
libssh2_channel_process_startup((channel), "exec", sizeof("exec") - 1, \
|
||||||
(command), strlen(command))
|
(command), (unsigned int)strlen(command))
|
||||||
#define libssh2_channel_subsystem(channel, subsystem) \
|
#define libssh2_channel_subsystem(channel, subsystem) \
|
||||||
libssh2_channel_process_startup((channel), "subsystem", \
|
libssh2_channel_process_startup((channel), "subsystem", \
|
||||||
sizeof("subsystem") - 1, (subsystem), \
|
sizeof("subsystem") - 1, (subsystem), \
|
||||||
strlen(subsystem))
|
(unsigned int)strlen(subsystem))
|
||||||
|
|
||||||
LIBSSH2_API ssize_t libssh2_channel_read_ex(LIBSSH2_CHANNEL *channel,
|
LIBSSH2_API ssize_t libssh2_channel_read_ex(LIBSSH2_CHANNEL *channel,
|
||||||
int stream_id, char *buf,
|
int stream_id, char *buf,
|
||||||
@@ -855,11 +870,12 @@ libssh2_knownhost_init(LIBSSH2_SESSION *session);
|
|||||||
#define LIBSSH2_KNOWNHOST_KEYENC_BASE64 (2<<16)
|
#define LIBSSH2_KNOWNHOST_KEYENC_BASE64 (2<<16)
|
||||||
|
|
||||||
/* type of key (2 bits) */
|
/* 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_SHIFT 18
|
||||||
#define LIBSSH2_KNOWNHOST_KEY_RSA1 (1<<18)
|
#define LIBSSH2_KNOWNHOST_KEY_RSA1 (1<<18)
|
||||||
#define LIBSSH2_KNOWNHOST_KEY_SSHRSA (2<<18)
|
#define LIBSSH2_KNOWNHOST_KEY_SSHRSA (2<<18)
|
||||||
#define LIBSSH2_KNOWNHOST_KEY_SSHDSS (3<<18)
|
#define LIBSSH2_KNOWNHOST_KEY_SSHDSS (3<<18)
|
||||||
|
#define LIBSSH2_KNOWNHOST_KEY_UNKNOWN (7<<18)
|
||||||
|
|
||||||
LIBSSH2_API int
|
LIBSSH2_API int
|
||||||
libssh2_knownhost_add(LIBSSH2_KNOWNHOSTS *hosts,
|
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,
|
LIBSSH2_API ssize_t libssh2_sftp_write(LIBSSH2_SFTP_HANDLE *handle,
|
||||||
const char *buffer, size_t count);
|
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);
|
LIBSSH2_API int libssh2_sftp_close_handle(LIBSSH2_SFTP_HANDLE *handle);
|
||||||
#define libssh2_sftp_close(handle) libssh2_sftp_close_handle(handle)
|
#define libssh2_sftp_close(handle) libssh2_sftp_close_handle(handle)
|
||||||
|
@@ -1,7 +1,7 @@
|
|||||||
#########################################################################
|
#########################################################################
|
||||||
#
|
#
|
||||||
## Makefile for building libssh2 (NetWare version - gnu make)
|
## 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
|
## Hacked by: Guenter Knauf
|
||||||
#
|
#
|
||||||
@@ -14,12 +14,12 @@ endif
|
|||||||
|
|
||||||
# Edit the path below to point to the base of your Zlib sources.
|
# Edit the path below to point to the base of your Zlib sources.
|
||||||
ifndef ZLIB_PATH
|
ifndef ZLIB_PATH
|
||||||
ZLIB_PATH = ../../zlib-1.2.6
|
ZLIB_PATH = ../../zlib-1.2.8
|
||||||
endif
|
endif
|
||||||
|
|
||||||
# Edit the path below to point to the base of your OpenSSL package.
|
# Edit the path below to point to the base of your OpenSSL package.
|
||||||
ifndef OPENSSL_PATH
|
ifndef OPENSSL_PATH
|
||||||
OPENSSL_PATH = ../../openssl-0.9.8v
|
OPENSSL_PATH = ../../openssl-0.9.8zc
|
||||||
endif
|
endif
|
||||||
|
|
||||||
# Edit the path below to point to your Distribution folder.
|
# 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.
|
# Edit the vars below to change NLM target settings.
|
||||||
TARGET = libssh2
|
TARGET = libssh2
|
||||||
VERSION = $(LIBSSH2_VERSION)
|
VERSION = $(LIBSSH2_VERSION)
|
||||||
COPYR = Copyright (c) $(LIBSSH2_COPYRIGHT_STR)
|
CPRIGHT = Copyright (c) $(LIBSSH2_COPYRIGHT_STR)
|
||||||
WWWURL = http://www.libssh2.org/
|
WWWURL = http://www.libssh2.org/
|
||||||
DESCR = libssh2 $(LIBSSH2_VERSION_STR) ($(LIBARCH)) - $(WWWURL)
|
DESCR = libssh2 $(LIBSSH2_VERSION_STR) ($(LIBARCH)) - $(WWWURL)
|
||||||
MTSAFE = YES
|
MTSAFE = YES
|
||||||
@@ -76,10 +76,7 @@ ifdef METROWERKS
|
|||||||
else
|
else
|
||||||
CC = $(CROSSPREFIX)gcc
|
CC = $(CROSSPREFIX)gcc
|
||||||
endif
|
endif
|
||||||
CP = cp -afv
|
|
||||||
MD = mkdir
|
|
||||||
RD = rm -fr
|
|
||||||
# RM = rm -f
|
|
||||||
# Here you can find a native Win32 binary of the original awk:
|
# Here you can find a native Win32 binary of the original awk:
|
||||||
# http://www.gknw.net/development/prgtools/awk-20100523.zip
|
# http://www.gknw.net/development/prgtools/awk-20100523.zip
|
||||||
AWK = awk
|
AWK = awk
|
||||||
@@ -89,6 +86,34 @@ AWK = awk
|
|||||||
MPKXDC = mkxdc
|
MPKXDC = mkxdc
|
||||||
ZIP = zip -qzr9
|
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_U = $(shell $(AWK) 'BEGIN {print toupper(ARGV[1])}' $(LIBARCH))
|
||||||
LIBARCH_L = $(shell $(AWK) 'BEGIN {print tolower(ARGV[1])}' $(LIBARCH))
|
LIBARCH_L = $(shell $(AWK) 'BEGIN {print tolower(ARGV[1])}' $(LIBARCH))
|
||||||
|
|
||||||
@@ -120,13 +145,14 @@ else
|
|||||||
endif
|
endif
|
||||||
else
|
else
|
||||||
LD = $(CROSSPREFIX)nlmconv
|
LD = $(CROSSPREFIX)nlmconv
|
||||||
LDFLAGS = -T
|
LDFLAGS = -UT
|
||||||
AR = $(CROSSPREFIX)ar
|
AR = $(CROSSPREFIX)ar
|
||||||
ARFLAGS = -cq
|
ARFLAGS = -cq
|
||||||
LIBEXT = a
|
LIBEXT = a
|
||||||
RANLIB = $(CROSSPREFIX)ranlib
|
RANLIB = $(CROSSPREFIX)ranlib
|
||||||
CFLAGS += -m32
|
CFLAGS += -m32
|
||||||
CFLAGS += -fno-builtin -fpcc-struct-return -fno-strict-aliasing
|
CFLAGS += -fno-builtin -fpcc-struct-return
|
||||||
|
CFLAGS += -fno-strict-aliasing
|
||||||
CFLAGS += -Wall # -pedantic
|
CFLAGS += -Wall # -pedantic
|
||||||
#CFLAGS += -Wno-pointer-sign
|
#CFLAGS += -Wno-pointer-sign
|
||||||
ifeq ($(LIBARCH),LIBC)
|
ifeq ($(LIBARCH),LIBC)
|
||||||
@@ -185,15 +211,12 @@ ifdef XDCOPT
|
|||||||
XDCDATA = $(OBJDIR)/$(TARGET).xdc
|
XDCDATA = $(OBJDIR)/$(TARGET).xdc
|
||||||
endif
|
endif
|
||||||
|
|
||||||
ifeq ($(findstring /sh,$(SHELL)),/sh)
|
|
||||||
DL = '
|
|
||||||
DS = /
|
|
||||||
else
|
|
||||||
DS = \\
|
|
||||||
endif
|
|
||||||
|
|
||||||
vpath %.c . ../src
|
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 to get CSOURCES define
|
||||||
include ../Makefile.inc
|
include ../Makefile.inc
|
||||||
|
|
||||||
@@ -217,73 +240,74 @@ lib: prebuild $(TARGET).$(LIBEXT)
|
|||||||
prebuild: $(OBJDIR) $(OBJDIR)/version.inc libssh2_config.h
|
prebuild: $(OBJDIR) $(OBJDIR)/version.inc libssh2_config.h
|
||||||
|
|
||||||
test: all
|
test: all
|
||||||
$(MAKE) -C test -f Makefile.netware
|
$(MAKE) -C test
|
||||||
|
|
||||||
$(OBJDIR)/%.o: %.c
|
$(OBJDIR)/%.o: %.c
|
||||||
# @echo Compiling $<
|
# @echo Compiling $<
|
||||||
$(CC) $(CFLAGS) -c $< -o $@
|
$(CC) $(CFLAGS) -c $< -o $@
|
||||||
|
|
||||||
$(OBJDIR)/version.inc: ../include/libssh2.h $(OBJDIR)
|
$(OBJDIR)/version.inc: ../get_ver.awk ../include/libssh2.h $(OBJDIR)
|
||||||
@echo Creating $@
|
@echo Creating $@
|
||||||
@$(AWK) -f ../get_ver.awk $< > $@
|
@$(AWK) -f $^ > $@
|
||||||
|
|
||||||
dist: all $(DISTDIR) $(DISTDIR)/readme.txt
|
dist: all $(DISTDIR) $(DISTDIR)/readme.txt
|
||||||
@-$(MD) $(DISTDIR)$(DS)bin
|
@$(call MKDIR, $(DISTDIR)/bin)
|
||||||
@-$(CP) ../AUTHORS $(DISTDIR)
|
@$(call COPY, ../AUTHORS, $(DISTDIR))
|
||||||
@-$(CP) ../COPYING $(DISTDIR)
|
@$(call COPY, ../COPYING, $(DISTDIR))
|
||||||
@-$(CP) ../INSTALL $(DISTDIR)
|
@$(call COPY, ../INSTALL, $(DISTDIR))
|
||||||
@-$(CP) ../README $(DISTDIR)
|
@$(call COPY, ../README, $(DISTDIR))
|
||||||
@-$(CP) ../RELEASE-NOTES $(DEVLDIR)
|
@$(call COPY, ../RELEASE-NOTES, $(DISTDIR))
|
||||||
@$(CP) $(TARGET).nlm $(DISTDIR)/bin
|
@$(call COPY, $(TARGET).nlm, $(DISTDIR)/bin)
|
||||||
@echo Creating $(DISTARC)
|
@echo Creating $(DISTARC)
|
||||||
@$(ZIP) $(DISTARC) $(DISTDIR)/* < $(DISTDIR)/readme.txt
|
@$(ZIP) $(DISTARC) $(DISTDIR)/* < $(DISTDIR)/readme.txt
|
||||||
|
|
||||||
dev: all $(DEVLDIR) $(DEVLDIR)/readme.txt
|
dev: all $(DEVLDIR) $(DEVLDIR)/readme.txt
|
||||||
@-$(MD) $(DEVLDIR)$(DS)bin
|
@$(call MKDIR, $(DEVLDIR)/bin)
|
||||||
@-$(MD) $(DEVLDIR)$(DS)include
|
@$(call MKDIR, $(DEVLDIR)/include)
|
||||||
@-$(MD) $(DEVLDIR)$(DS)nw
|
@$(call MKDIR, $(DEVLDIR)/nw)
|
||||||
@-$(CP) ../AUTHORS $(DISTDIR)
|
@$(call COPY, ../AUTHORS, $(DEVLDIR))
|
||||||
@-$(CP) ../COPYING $(DISTDIR)
|
@$(call COPY, ../COPYING, $(DEVLDIR))
|
||||||
@-$(CP) ../INSTALL $(DEVLDIR)
|
@$(call COPY, ../INSTALL, $(DEVLDIR))
|
||||||
@-$(CP) ../README $(DEVLDIR)
|
@$(call COPY, ../README, $(DEVLDIR))
|
||||||
@-$(CP) ../RELEASE-NOTES $(DEVLDIR)
|
@$(call COPY, ../RELEASE-NOTES, $(DEVLDIR))
|
||||||
@$(CP) $(TARGET).nlm $(DEVLDIR)/bin
|
@$(call COPY, ../include/*.h, $(DEVLDIR)/include)
|
||||||
@$(CP) ../include/*.h $(DEVLDIR)/include
|
@$(call COPY, libssh2_config.h, $(DEVLDIR)/include)
|
||||||
@$(CP) libssh2_config.h $(DEVLDIR)/include
|
@$(call COPY, $(TARGET).nlm, $(DEVLDIR)/bin)
|
||||||
@$(CP) $(TARGET).$(LIBEXT) $(DEVLDIR)/nw
|
@$(call COPY, $(TARGET).imp, $(DEVLDIR)/nw)
|
||||||
|
@$(call COPY, $(TARGET).$(LIBEXT), $(DEVLDIR)/nw)
|
||||||
@echo Creating $(DEVLARC)
|
@echo Creating $(DEVLARC)
|
||||||
@$(ZIP) $(DEVLARC) $(DEVLDIR)/* < $(DEVLDIR)/readme.txt
|
@$(ZIP) $(DEVLARC) $(DEVLDIR)/* < $(DEVLDIR)/readme.txt
|
||||||
|
|
||||||
distclean: clean
|
distclean: clean
|
||||||
-$(RD) $(DISTDIR)
|
$(call RMDIR, $(DISTDIR))
|
||||||
-$(RM) $(DISTARC)
|
$(call DEL, $(DISTARC))
|
||||||
|
|
||||||
devclean: clean
|
devclean: clean
|
||||||
-$(RD) $(DEVLDIR)
|
$(call RMDIR, $(DEVLDIR))
|
||||||
-$(RM) $(DEVLARC)
|
$(call DEL, $(DEVLARC))
|
||||||
|
|
||||||
objclean:
|
objclean:
|
||||||
-$(RD) $(OBJDIR)
|
$(call RMDIR, $(OBJDIR))
|
||||||
|
|
||||||
testclean: clean
|
testclean: clean
|
||||||
$(MAKE) -C test -f Makefile.netware clean
|
$(MAKE) -C test clean
|
||||||
|
|
||||||
clean: objclean
|
clean: objclean
|
||||||
-$(RM) libssh2_config.h
|
$(call DEL, libssh2_config.h)
|
||||||
-$(RM) $(TARGET).nlm $(TARGET).$(LIBEXT) $(TARGET).imp
|
$(call DEL, $(TARGET).*)
|
||||||
|
|
||||||
$(OBJDIR):
|
$(OBJDIR):
|
||||||
@$(MD) $@
|
@$(call MKDIR, $@)
|
||||||
|
|
||||||
$(DISTDIR):
|
$(DISTDIR):
|
||||||
@$(MD) $@
|
@$(call MKDIR, $@)
|
||||||
|
|
||||||
$(DEVLDIR):
|
$(DEVLDIR):
|
||||||
@$(MD) $@
|
@$(call MKDIR, $@)
|
||||||
|
|
||||||
$(TARGET).$(LIBEXT): $(OBJS)
|
$(TARGET).$(LIBEXT): $(OBJS)
|
||||||
@echo Creating $@
|
@echo Creating $@
|
||||||
@-$(RM) $@
|
@$(call DEL, $@)
|
||||||
@$(AR) $(ARFLAGS) $@ $^
|
@$(AR) $(ARFLAGS) $@ $^
|
||||||
ifdef RANLIB
|
ifdef RANLIB
|
||||||
@$(RANLIB) $@
|
@$(RANLIB) $@
|
||||||
@@ -291,19 +315,19 @@ endif
|
|||||||
|
|
||||||
$(TARGET).nlm: $(OBJDIR)/$(TARGET).def $(TARGET).imp $(OBJL) $(XDCDATA)
|
$(TARGET).nlm: $(OBJDIR)/$(TARGET).def $(TARGET).imp $(OBJL) $(XDCDATA)
|
||||||
@echo Linking $@
|
@echo Linking $@
|
||||||
@-$(RM) $@
|
@$(call DEL, $@)
|
||||||
@$(LD) $(LDFLAGS) $<
|
@$(LD) $(LDFLAGS) $<
|
||||||
|
|
||||||
$(OBJDIR)/%.xdc: Makefile.netware
|
$(OBJDIR)/%.xdc: GNUmakefile
|
||||||
@echo Creating $@
|
@echo Creating $@
|
||||||
@$(MPKXDC) $(XDCOPT) $@
|
@$(MPKXDC) $(XDCOPT) $@
|
||||||
|
|
||||||
$(OBJDIR)/%.def: Makefile.netware
|
$(OBJDIR)/%.def: GNUmakefile
|
||||||
@echo $(DL)# DEF file for linking with $(LD)$(DL) > $@
|
@echo $(DL)# DEF file for linking with $(LD)$(DL) > $@
|
||||||
@echo $(DL)# Do not edit this file - it is created by make!$(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)# All your changes will be lost!!$(DL) >> $@
|
||||||
@echo $(DL)#$(DL) >> $@
|
@echo $(DL)#$(DL) >> $@
|
||||||
@echo $(DL)copyright "$(COPYR)"$(DL) >> $@
|
@echo $(DL)copyright "$(CPRIGHT)"$(DL) >> $@
|
||||||
@echo $(DL)description "$(DESCR)"$(DL) >> $@
|
@echo $(DL)description "$(DESCR)"$(DL) >> $@
|
||||||
@echo $(DL)version $(VERSION)$(DL) >> $@
|
@echo $(DL)version $(VERSION)$(DL) >> $@
|
||||||
ifdef NLMTYPE
|
ifdef NLMTYPE
|
||||||
@@ -357,7 +381,7 @@ ifeq ($(LD),nlmconv)
|
|||||||
@echo $(DL)output $(TARGET).nlm$(DL) >> $@
|
@echo $(DL)output $(TARGET).nlm$(DL) >> $@
|
||||||
endif
|
endif
|
||||||
|
|
||||||
libssh2_config.h: Makefile.netware
|
libssh2_config.h: GNUmakefile
|
||||||
@echo Creating $@
|
@echo Creating $@
|
||||||
@echo $(DL)/* $@ for NetWare target.$(DL) > $@
|
@echo $(DL)/* $@ for NetWare target.$(DL) > $@
|
||||||
@echo $(DL)** Do not edit this file - it is created by make!$(DL) >> $@
|
@echo $(DL)** Do not edit this file - it is created by make!$(DL) >> $@
|
||||||
@@ -483,7 +507,7 @@ ifeq ($(DB),DEBUG)
|
|||||||
@echo $(DL)#define LIBSSH2_DEBUG_USERAUTH 1$(DL) >> $@
|
@echo $(DL)#define LIBSSH2_DEBUG_USERAUTH 1$(DL) >> $@
|
||||||
endif
|
endif
|
||||||
|
|
||||||
libssh2.imp: Makefile.netware
|
libssh2.imp: GNUmakefile
|
||||||
@echo Creating $@
|
@echo Creating $@
|
||||||
@echo $(DL)# $@ for NetWare target.$(DL) > $@
|
@echo $(DL)# $@ for NetWare target.$(DL) > $@
|
||||||
@echo $(DL)# Do not edit this file - it is created by make!$(DL) >> $@
|
@echo $(DL)# Do not edit this file - it is created by make!$(DL) >> $@
|
||||||
@@ -510,21 +534,25 @@ endif
|
|||||||
@echo $(DL) libssh2_channel_wait_closed,$(DL) >> $@
|
@echo $(DL) libssh2_channel_wait_closed,$(DL) >> $@
|
||||||
@echo $(DL) libssh2_channel_wait_eof,$(DL) >> $@
|
@echo $(DL) libssh2_channel_wait_eof,$(DL) >> $@
|
||||||
@echo $(DL) libssh2_channel_write_ex,$(DL) >> $@
|
@echo $(DL) libssh2_channel_write_ex,$(DL) >> $@
|
||||||
|
@echo $(DL) libssh2_exit,$(DL) >> $@
|
||||||
@echo $(DL) libssh2_hostkey_hash,$(DL) >> $@
|
@echo $(DL) libssh2_hostkey_hash,$(DL) >> $@
|
||||||
@echo $(DL) libssh2_scp_recv,$(DL) >> $@
|
@echo $(DL) libssh2_init,$(DL) >> $@
|
||||||
@echo $(DL) libssh2_scp_send64,$(DL) >> $@
|
|
||||||
@echo $(DL) libssh2_scp_send_ex,$(DL) >> $@
|
|
||||||
@echo $(DL) libssh2_knownhost_add,$(DL) >> $@
|
@echo $(DL) libssh2_knownhost_add,$(DL) >> $@
|
||||||
@echo $(DL) libssh2_knownhost_check,$(DL) >> $@
|
@echo $(DL) libssh2_knownhost_check,$(DL) >> $@
|
||||||
|
@echo $(DL) libssh2_knownhost_checkp,$(DL) >> $@
|
||||||
@echo $(DL) libssh2_knownhost_free,$(DL) >> $@
|
@echo $(DL) libssh2_knownhost_free,$(DL) >> $@
|
||||||
@echo $(DL) libssh2_knownhost_init,$(DL) >> $@
|
@echo $(DL) libssh2_knownhost_init,$(DL) >> $@
|
||||||
@echo $(DL) libssh2_knownhost_readfile,$(DL) >> $@
|
@echo $(DL) libssh2_knownhost_readfile,$(DL) >> $@
|
||||||
@echo $(DL) libssh2_knownhost_writefile,$(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_abstract,$(DL) >> $@
|
||||||
@echo $(DL) libssh2_session_block_directions,$(DL) >> $@
|
@echo $(DL) libssh2_session_block_directions,$(DL) >> $@
|
||||||
@echo $(DL) libssh2_session_callback_set,$(DL) >> $@
|
@echo $(DL) libssh2_session_callback_set,$(DL) >> $@
|
||||||
@echo $(DL) libssh2_session_disconnect_ex,$(DL) >> $@
|
@echo $(DL) libssh2_session_disconnect_ex,$(DL) >> $@
|
||||||
@echo $(DL) libssh2_session_free,$(DL) >> $@
|
@echo $(DL) libssh2_session_free,$(DL) >> $@
|
||||||
|
@echo $(DL) libssh2_session_handshake,$(DL) >> $@
|
||||||
@echo $(DL) libssh2_session_hostkey,$(DL) >> $@
|
@echo $(DL) libssh2_session_hostkey,$(DL) >> $@
|
||||||
@echo $(DL) libssh2_session_init_ex,$(DL) >> $@
|
@echo $(DL) libssh2_session_init_ex,$(DL) >> $@
|
||||||
@echo $(DL) libssh2_session_last_errno,$(DL) >> $@
|
@echo $(DL) libssh2_session_last_errno,$(DL) >> $@
|
||||||
@@ -556,9 +584,10 @@ endif
|
|||||||
@echo $(DL) libssh2_userauth_keyboard_interactive_ex,$(DL) >> $@
|
@echo $(DL) libssh2_userauth_keyboard_interactive_ex,$(DL) >> $@
|
||||||
@echo $(DL) libssh2_userauth_list,$(DL) >> $@
|
@echo $(DL) libssh2_userauth_list,$(DL) >> $@
|
||||||
@echo $(DL) libssh2_userauth_password_ex,$(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 Creating $@
|
||||||
@echo $(DL)This is a binary distribution for NetWare platform.$(DL) > $@
|
@echo $(DL)This is a binary distribution for NetWare platform.$(DL) > $@
|
||||||
@echo $(DL)libssh2 version $(LIBSSH2_VERSION_STR)$(DL) >> $@
|
@echo $(DL)libssh2 version $(LIBSSH2_VERSION_STR)$(DL) >> $@
|
||||||
@@ -566,7 +595,7 @@ $(DISTDIR)/readme.txt: Makefile.netware
|
|||||||
@echo $(DL)any further documentation:$(DL) >> $@
|
@echo $(DL)any further documentation:$(DL) >> $@
|
||||||
@echo $(DL)$(WWWURL)$(DL) >> $@
|
@echo $(DL)$(WWWURL)$(DL) >> $@
|
||||||
|
|
||||||
$(DEVLDIR)/readme.txt: Makefile.netware
|
$(DEVLDIR)/readme.txt: GNUmakefile
|
||||||
@echo Creating $@
|
@echo Creating $@
|
||||||
@echo $(DL)This is a development distribution for NetWare platform.$(DL) > $@
|
@echo $(DL)This is a development distribution for NetWare platform.$(DL) > $@
|
||||||
@echo $(DL)libssh2 version $(LIBSSH2_VERSION_STR)$(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)
|
## Makefile for building libssh2 (NetWare version - gnu make)
|
||||||
## Use: make -f Makefile.netware
|
|
||||||
##
|
##
|
||||||
## Hacked by: Guenter Knauf
|
## Hacked by: Guenter Knauf
|
||||||
#
|
#
|
||||||
@@ -14,12 +13,12 @@ endif
|
|||||||
|
|
||||||
# Edit the path below to point to the base of your Zlib sources.
|
# Edit the path below to point to the base of your Zlib sources.
|
||||||
ifndef ZLIB_PATH
|
ifndef ZLIB_PATH
|
||||||
ZLIB_PATH = ../../../zlib-1.2.6
|
ZLIB_PATH = ../../../zlib-1.2.8
|
||||||
endif
|
endif
|
||||||
|
|
||||||
# Edit the path below to point to the base of your OpenSSL package.
|
# Edit the path below to point to the base of your OpenSSL package.
|
||||||
ifndef OPENSSL_PATH
|
ifndef OPENSSL_PATH
|
||||||
OPENSSL_PATH = ../../../openssl-0.9.8v
|
OPENSSL_PATH = ../../../openssl-0.9.8zc
|
||||||
endif
|
endif
|
||||||
|
|
||||||
# Edit the var below to enable static linking of libssh2 and libz
|
# Edit the var below to enable static linking of libssh2 and libz
|
||||||
@@ -70,10 +69,7 @@ ifdef METROWERKS
|
|||||||
else
|
else
|
||||||
CC = $(CROSSPREFIX)gcc
|
CC = $(CROSSPREFIX)gcc
|
||||||
endif
|
endif
|
||||||
CP = cp -afv
|
|
||||||
MD = mkdir
|
|
||||||
RD = rm -fr
|
|
||||||
# RM = rm -f
|
|
||||||
# Here you can find a native Win32 binary of the original awk:
|
# Here you can find a native Win32 binary of the original awk:
|
||||||
# http://www.gknw.net/development/prgtools/awk-20100523.zip
|
# http://www.gknw.net/development/prgtools/awk-20100523.zip
|
||||||
AWK = awk
|
AWK = awk
|
||||||
@@ -82,6 +78,34 @@ AWK = awk
|
|||||||
# http://www.gknw.net/development/prgtools/mkxdc.zip
|
# http://www.gknw.net/development/prgtools/mkxdc.zip
|
||||||
MPKXDC = mkxdc
|
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_U = $(shell $(AWK) 'BEGIN {print toupper(ARGV[1])}' $(LIBARCH))
|
||||||
LIBARCH_L = $(shell $(AWK) 'BEGIN {print tolower(ARGV[1])}' $(LIBARCH))
|
LIBARCH_L = $(shell $(AWK) 'BEGIN {print tolower(ARGV[1])}' $(LIBARCH))
|
||||||
|
|
||||||
@@ -112,12 +136,13 @@ else
|
|||||||
endif
|
endif
|
||||||
else
|
else
|
||||||
LD = nlmconv
|
LD = nlmconv
|
||||||
LDFLAGS = -T
|
LDFLAGS = -UT
|
||||||
AR = ar
|
AR = ar
|
||||||
ARFLAGS = -cq
|
ARFLAGS = -cq
|
||||||
LIBEXT = a
|
LIBEXT = a
|
||||||
CFLAGS += -m32
|
CFLAGS += -m32
|
||||||
CFLAGS += -fno-builtin -fpcc-struct-return -fno-strict-aliasing
|
CFLAGS += -fno-builtin -fpcc-struct-return
|
||||||
|
CFLAGS += -fno-strict-aliasing
|
||||||
CFLAGS += -Wall # -pedantic
|
CFLAGS += -Wall # -pedantic
|
||||||
ifeq ($(LIBARCH),LIBC)
|
ifeq ($(LIBARCH),LIBC)
|
||||||
PRELUDE = $(SDK_LIBC)/imports/libcpre.gcc.o
|
PRELUDE = $(SDK_LIBC)/imports/libcpre.gcc.o
|
||||||
@@ -181,13 +206,6 @@ ifeq ($(MTSAFE),NO)
|
|||||||
XDCOPT = -u
|
XDCOPT = -u
|
||||||
endif
|
endif
|
||||||
|
|
||||||
ifeq ($(findstring /sh,$(SHELL)),/sh)
|
|
||||||
DL = '
|
|
||||||
DS = /
|
|
||||||
else
|
|
||||||
DS = \\
|
|
||||||
endif
|
|
||||||
|
|
||||||
vpath %.c $(SAMPLES)
|
vpath %.c $(SAMPLES)
|
||||||
|
|
||||||
.PRECIOUS: $(OBJDIR)/%.o $(OBJDIR)/%.def $(OBJDIR)/%.xdc
|
.PRECIOUS: $(OBJDIR)/%.o $(OBJDIR)/%.def $(OBJDIR)/%.xdc
|
||||||
@@ -201,29 +219,29 @@ $(OBJDIR)/%.o: %.c
|
|||||||
# @echo Compiling $<
|
# @echo Compiling $<
|
||||||
$(CC) $(CFLAGS) -c $< -o $@
|
$(CC) $(CFLAGS) -c $< -o $@
|
||||||
|
|
||||||
$(OBJDIR)/version.inc: ../../include/libssh2.h $(OBJDIR)
|
$(OBJDIR)/version.inc: ../../get_ver.awk ../../include/libssh2.h $(OBJDIR)
|
||||||
@echo Creating $@
|
@echo Creating $@
|
||||||
@$(AWK) -f ../../get_ver.awk $< > $@
|
@$(AWK) -f $^ > $@
|
||||||
|
|
||||||
objclean:
|
objclean:
|
||||||
-$(RD) $(OBJDIR)
|
$(call RMDIR, $(OBJDIR))
|
||||||
|
|
||||||
clean: objclean
|
clean: objclean
|
||||||
-$(RM) $(TARGETS)
|
$(foreach f, $(TARGETS), $(call DEL, $(f)))
|
||||||
|
|
||||||
$(OBJDIR):
|
$(OBJDIR):
|
||||||
@$(MD) $@
|
@$(call MKDIR, $@)
|
||||||
|
|
||||||
%.nlm: $(OBJDIR)/%.def $(OBJDIR)/%.o $(OBJDIR)/%.xdc
|
%.nlm: $(OBJDIR)/%.def $(OBJDIR)/%.o $(OBJDIR)/%.xdc
|
||||||
@echo Linking $@
|
@echo Linking $@
|
||||||
@-$(RM) $@
|
@$(call DEL, $@)
|
||||||
@$(LD) $(LDFLAGS) $<
|
@$(LD) $(LDFLAGS) $<
|
||||||
|
|
||||||
$(OBJDIR)/%.xdc: Makefile.netware
|
$(OBJDIR)/%.xdc: GNUmakefile
|
||||||
@echo Creating $@
|
@echo Creating $@
|
||||||
@$(MPKXDC) $(XDCOPT) $@
|
@$(MPKXDC) $(XDCOPT) $@
|
||||||
|
|
||||||
$(OBJDIR)/%.def: Makefile.netware
|
$(OBJDIR)/%.def: GNUmakefile
|
||||||
@echo $(DL)# DEF file for linking with $(LD)$(DL) > $@
|
@echo $(DL)# DEF file for linking with $(LD)$(DL) > $@
|
||||||
@echo $(DL)# Do not edit this file - it is created by make!$(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)# 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 $
|
# $Id: Makefile.am,v 1.21 2009/05/07 17:21:56 bagder Exp $
|
||||||
AUTOMAKE_OPTIONS = foreign nostdinc
|
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
|
# Makefile.inc provides the CSOURCES and HHEADERS defines
|
||||||
include ../Makefile.inc
|
include ../Makefile.inc
|
||||||
|
|
||||||
|
@@ -1,33 +1,30 @@
|
|||||||
!include "win32/config.mk"
|
!include "win32/config.mk"
|
||||||
|
|
||||||
|
!include "win32/objects.mk"
|
||||||
|
|
||||||
CFLAGS=$(CFLAGS)
|
CFLAGS=$(CFLAGS)
|
||||||
|
|
||||||
OBJECTS = \
|
AR = lib
|
||||||
$(INTDIR)\channel.obj \
|
ARFLAGS = -nologo /LTCG
|
||||||
$(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
|
|
||||||
|
|
||||||
|
RESOURCE=$(INTDIR)\libssh2.res
|
||||||
DLL=libssh2$(SUFFIX).dll
|
DLL=libssh2$(SUFFIX).dll
|
||||||
|
STATICLIB=$(INTDIR)\libssh2.lib
|
||||||
|
|
||||||
$(DLL): $(OBJECTS)
|
!if "$(BUILD_STATIC_LIB)" == ""
|
||||||
$(CC) -o $(DLL) $(DLLFLAGS) $(OBJECTS) $(LIBS)
|
|
||||||
|
|
||||||
all: $(DLL)
|
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"
|
!include "win32/rules.mk"
|
||||||
|
|
||||||
|
37
src/agent.c
37
src/agent.c
@@ -1,6 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2009 by Daiki Ueno
|
* Copyright (c) 2009 by Daiki Ueno
|
||||||
* Copyright (C) 2010 by Daniel Stenberg
|
* Copyright (C) 2010-2014 by Daniel Stenberg
|
||||||
* All rights reserved.
|
* All rights reserved.
|
||||||
*
|
*
|
||||||
* Redistribution and use in source and binary forms,
|
* Redistribution and use in source and binary forms,
|
||||||
@@ -159,6 +159,8 @@ agent_connect_unix(LIBSSH2_AGENT *agent)
|
|||||||
|
|
||||||
s_un.sun_family = AF_UNIX;
|
s_un.sun_family = AF_UNIX;
|
||||||
strncpy (s_un.sun_path, path, sizeof s_un.sun_path);
|
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) {
|
if (connect(agent->fd, (struct sockaddr*)(&s_un), sizeof s_un) != 0) {
|
||||||
close (agent->fd);
|
close (agent->fd);
|
||||||
return _libssh2_error(agent->session, LIBSSH2_ERROR_AGENT_PROTOCOL,
|
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");
|
"failed setting up pageant filemap");
|
||||||
|
|
||||||
p2 = p = MapViewOfFile(filemap, FILE_MAP_WRITE, 0, 0, 0);
|
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,
|
_libssh2_store_str(&p2, (const char *)transctx->request,
|
||||||
transctx->request_len);
|
transctx->request_len);
|
||||||
|
|
||||||
@@ -537,18 +545,17 @@ agent_list_identities(LIBSSH2_AGENT *agent)
|
|||||||
struct agent_publickey *identity;
|
struct agent_publickey *identity;
|
||||||
ssize_t comment_len;
|
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 */
|
/* Read the length of the blob */
|
||||||
len -= 4;
|
len -= 4;
|
||||||
if (len < 0) {
|
if (len < 0) {
|
||||||
rc = LIBSSH2_ERROR_AGENT_PROTOCOL;
|
rc = LIBSSH2_ERROR_AGENT_PROTOCOL;
|
||||||
goto error;
|
goto error;
|
||||||
}
|
}
|
||||||
|
identity = LIBSSH2_ALLOC(agent->session, sizeof *identity);
|
||||||
|
if (!identity) {
|
||||||
|
rc = LIBSSH2_ERROR_ALLOC;
|
||||||
|
goto error;
|
||||||
|
}
|
||||||
identity->external.blob_len = _libssh2_ntohu32(s);
|
identity->external.blob_len = _libssh2_ntohu32(s);
|
||||||
s += 4;
|
s += 4;
|
||||||
|
|
||||||
@@ -556,12 +563,15 @@ agent_list_identities(LIBSSH2_AGENT *agent)
|
|||||||
len -= identity->external.blob_len;
|
len -= identity->external.blob_len;
|
||||||
if (len < 0) {
|
if (len < 0) {
|
||||||
rc = LIBSSH2_ERROR_AGENT_PROTOCOL;
|
rc = LIBSSH2_ERROR_AGENT_PROTOCOL;
|
||||||
|
LIBSSH2_FREE(agent->session, identity);
|
||||||
goto error;
|
goto error;
|
||||||
}
|
}
|
||||||
|
|
||||||
identity->external.blob = LIBSSH2_ALLOC(agent->session,
|
identity->external.blob = LIBSSH2_ALLOC(agent->session,
|
||||||
identity->external.blob_len);
|
identity->external.blob_len);
|
||||||
if (!identity->external.blob) {
|
if (!identity->external.blob) {
|
||||||
rc = LIBSSH2_ERROR_ALLOC;
|
rc = LIBSSH2_ERROR_ALLOC;
|
||||||
|
LIBSSH2_FREE(agent->session, identity);
|
||||||
goto error;
|
goto error;
|
||||||
}
|
}
|
||||||
memcpy(identity->external.blob, s, identity->external.blob_len);
|
memcpy(identity->external.blob, s, identity->external.blob_len);
|
||||||
@@ -571,6 +581,8 @@ agent_list_identities(LIBSSH2_AGENT *agent)
|
|||||||
len -= 4;
|
len -= 4;
|
||||||
if (len < 0) {
|
if (len < 0) {
|
||||||
rc = LIBSSH2_ERROR_AGENT_PROTOCOL;
|
rc = LIBSSH2_ERROR_AGENT_PROTOCOL;
|
||||||
|
LIBSSH2_FREE(agent->session, identity->external.blob);
|
||||||
|
LIBSSH2_FREE(agent->session, identity);
|
||||||
goto error;
|
goto error;
|
||||||
}
|
}
|
||||||
comment_len = _libssh2_ntohu32(s);
|
comment_len = _libssh2_ntohu32(s);
|
||||||
@@ -580,12 +592,17 @@ agent_list_identities(LIBSSH2_AGENT *agent)
|
|||||||
len -= comment_len;
|
len -= comment_len;
|
||||||
if (len < 0) {
|
if (len < 0) {
|
||||||
rc = LIBSSH2_ERROR_AGENT_PROTOCOL;
|
rc = LIBSSH2_ERROR_AGENT_PROTOCOL;
|
||||||
|
LIBSSH2_FREE(agent->session, identity->external.blob);
|
||||||
|
LIBSSH2_FREE(agent->session, identity);
|
||||||
goto error;
|
goto error;
|
||||||
}
|
}
|
||||||
|
|
||||||
identity->external.comment = LIBSSH2_ALLOC(agent->session,
|
identity->external.comment = LIBSSH2_ALLOC(agent->session,
|
||||||
comment_len + 1);
|
comment_len + 1);
|
||||||
if (!identity->external.comment) {
|
if (!identity->external.comment) {
|
||||||
rc = LIBSSH2_ERROR_ALLOC;
|
rc = LIBSSH2_ERROR_ALLOC;
|
||||||
|
LIBSSH2_FREE(agent->session, identity->external.blob);
|
||||||
|
LIBSSH2_FREE(agent->session, identity);
|
||||||
goto error;
|
goto error;
|
||||||
}
|
}
|
||||||
identity->external.comment[comment_len] = '\0';
|
identity->external.comment[comment_len] = '\0';
|
||||||
@@ -645,13 +662,13 @@ libssh2_agent_init(LIBSSH2_SESSION *session)
|
|||||||
{
|
{
|
||||||
LIBSSH2_AGENT *agent;
|
LIBSSH2_AGENT *agent;
|
||||||
|
|
||||||
agent = LIBSSH2_ALLOC(session, sizeof *agent);
|
agent = LIBSSH2_CALLOC(session, sizeof *agent);
|
||||||
if (!agent) {
|
if (!agent) {
|
||||||
_libssh2_error(session, LIBSSH2_ERROR_ALLOC,
|
_libssh2_error(session, LIBSSH2_ERROR_ALLOC,
|
||||||
"Unable to allocate space for agent connection");
|
"Unable to allocate space for agent connection");
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
memset(agent, 0, sizeof *agent);
|
agent->fd = LIBSSH2_INVALID_SOCKET;
|
||||||
agent->session = session;
|
agent->session = session;
|
||||||
_libssh2_list_init(&agent->head);
|
_libssh2_list_init(&agent->head);
|
||||||
|
|
||||||
@@ -698,7 +715,7 @@ libssh2_agent_list_identities(LIBSSH2_AGENT *agent)
|
|||||||
* libssh2_agent_get_identity()
|
* libssh2_agent_get_identity()
|
||||||
*
|
*
|
||||||
* Traverse the internal list of public keys. Pass NULL to 'prev' to get
|
* 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.
|
* next.
|
||||||
*
|
*
|
||||||
* Returns:
|
* Returns:
|
||||||
|
154
src/channel.c
154
src/channel.c
@@ -1,6 +1,6 @@
|
|||||||
/* Copyright (c) 2004-2007 Sara Golemon <sarag@libssh2.org>
|
/* Copyright (c) 2004-2007 Sara Golemon <sarag@libssh2.org>
|
||||||
* Copyright (c) 2005 Mikhail Gusarov <dottedmag@dottedmag.net>
|
* 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.
|
* 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,
|
"Opening Channel - win %d pack %d", window_size,
|
||||||
packet_size);
|
packet_size);
|
||||||
session->open_channel =
|
session->open_channel =
|
||||||
LIBSSH2_ALLOC(session, sizeof(LIBSSH2_CHANNEL));
|
LIBSSH2_CALLOC(session, sizeof(LIBSSH2_CHANNEL));
|
||||||
if (!session->open_channel) {
|
if (!session->open_channel) {
|
||||||
_libssh2_error(session, LIBSSH2_ERROR_ALLOC,
|
_libssh2_error(session, LIBSSH2_ERROR_ALLOC,
|
||||||
"Unable to allocate space for channel data");
|
"Unable to allocate space for channel data");
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
memset(session->open_channel, 0, sizeof(LIBSSH2_CHANNEL));
|
|
||||||
|
|
||||||
session->open_channel->channel_type_len = channel_type_len;
|
session->open_channel->channel_type_len = channel_type_len;
|
||||||
session->open_channel->channel_type =
|
session->open_channel->channel_type =
|
||||||
LIBSSH2_ALLOC(session, channel_type_len);
|
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);
|
LIBSSH2_ALLOC(session, session->fwdLstn_packet_len);
|
||||||
if (!session->fwdLstn_packet) {
|
if (!session->fwdLstn_packet) {
|
||||||
_libssh2_error(session, LIBSSH2_ERROR_ALLOC,
|
_libssh2_error(session, LIBSSH2_ERROR_ALLOC,
|
||||||
"Unable to allocate memeory for setenv packet");
|
"Unable to allocate memory for setenv packet");
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -509,12 +507,11 @@ channel_forward_listen(LIBSSH2_SESSION * session, const char *host,
|
|||||||
if (data[0] == SSH_MSG_REQUEST_SUCCESS) {
|
if (data[0] == SSH_MSG_REQUEST_SUCCESS) {
|
||||||
LIBSSH2_LISTENER *listener;
|
LIBSSH2_LISTENER *listener;
|
||||||
|
|
||||||
listener = LIBSSH2_ALLOC(session, sizeof(LIBSSH2_LISTENER));
|
listener = LIBSSH2_CALLOC(session, sizeof(LIBSSH2_LISTENER));
|
||||||
if (!listener)
|
if (!listener)
|
||||||
_libssh2_error(session, LIBSSH2_ERROR_ALLOC,
|
_libssh2_error(session, LIBSSH2_ERROR_ALLOC,
|
||||||
"Unable to allocate memory for listener queue");
|
"Unable to allocate memory for listener queue");
|
||||||
else {
|
else {
|
||||||
memset(listener, 0, sizeof(LIBSSH2_LISTENER));
|
|
||||||
listener->host =
|
listener->host =
|
||||||
LIBSSH2_ALLOC(session, session->fwdLstn_host_len + 1);
|
LIBSSH2_ALLOC(session, session->fwdLstn_host_len + 1);
|
||||||
if (!listener->host) {
|
if (!listener->host) {
|
||||||
@@ -525,8 +522,7 @@ channel_forward_listen(LIBSSH2_SESSION * session, const char *host,
|
|||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
listener->session = session;
|
listener->session = session;
|
||||||
memcpy(listener->host, host ? host : "0.0.0.0",
|
memcpy(listener->host, host, session->fwdLstn_host_len);
|
||||||
session->fwdLstn_host_len);
|
|
||||||
listener->host[session->fwdLstn_host_len] = 0;
|
listener->host[session->fwdLstn_host_len] = 0;
|
||||||
if (data_len >= 5 && !port) {
|
if (data_len >= 5 && !port) {
|
||||||
listener->port = _libssh2_ntohu32(data + 1);
|
listener->port = _libssh2_ntohu32(data + 1);
|
||||||
@@ -606,6 +602,7 @@ int _libssh2_channel_forward_cancel(LIBSSH2_LISTENER *listener)
|
|||||||
size_t packet_len =
|
size_t packet_len =
|
||||||
host_len + 14 + sizeof("cancel-tcpip-forward") - 1;
|
host_len + 14 + sizeof("cancel-tcpip-forward") - 1;
|
||||||
int rc;
|
int rc;
|
||||||
|
int retcode = 0;
|
||||||
|
|
||||||
if (listener->chanFwdCncl_state == libssh2_NB_state_idle) {
|
if (listener->chanFwdCncl_state == libssh2_NB_state_idle) {
|
||||||
_libssh2_debug(session, LIBSSH2_TRACE_CONN,
|
_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);
|
s = packet = LIBSSH2_ALLOC(session, packet_len);
|
||||||
if (!packet) {
|
if (!packet) {
|
||||||
_libssh2_error(session, LIBSSH2_ERROR_ALLOC,
|
_libssh2_error(session, LIBSSH2_ERROR_ALLOC,
|
||||||
"Unable to allocate memeory for setenv packet");
|
"Unable to allocate memory for setenv packet");
|
||||||
return LIBSSH2_ERROR_ALLOC;
|
return LIBSSH2_ERROR_ALLOC;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -644,9 +641,11 @@ int _libssh2_channel_forward_cancel(LIBSSH2_LISTENER *listener)
|
|||||||
_libssh2_error(session, LIBSSH2_ERROR_SOCKET_SEND,
|
_libssh2_error(session, LIBSSH2_ERROR_SOCKET_SEND,
|
||||||
"Unable to send global-request packet for forward "
|
"Unable to send global-request packet for forward "
|
||||||
"listen request");
|
"listen request");
|
||||||
LIBSSH2_FREE(session, packet);
|
/* set the state to something we don't check for, for the
|
||||||
listener->chanFwdCncl_state = libssh2_NB_state_idle;
|
unfortunate situation where we get an EAGAIN further down
|
||||||
return LIBSSH2_ERROR_SOCKET_SEND;
|
when trying to bail out due to errors! */
|
||||||
|
listener->chanFwdCncl_state = libssh2_NB_state_sent;
|
||||||
|
retcode = LIBSSH2_ERROR_SOCKET_SEND;
|
||||||
}
|
}
|
||||||
LIBSSH2_FREE(session, packet);
|
LIBSSH2_FREE(session, packet);
|
||||||
|
|
||||||
@@ -670,9 +669,7 @@ int _libssh2_channel_forward_cancel(LIBSSH2_LISTENER *listener)
|
|||||||
|
|
||||||
LIBSSH2_FREE(session, listener);
|
LIBSSH2_FREE(session, listener);
|
||||||
|
|
||||||
listener->chanFwdCncl_state = libssh2_NB_state_idle;
|
return retcode;
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -787,7 +784,7 @@ static int channel_setenv(LIBSSH2_CHANNEL *channel,
|
|||||||
LIBSSH2_ALLOC(session, channel->setenv_packet_len);
|
LIBSSH2_ALLOC(session, channel->setenv_packet_len);
|
||||||
if (!channel->setenv_packet) {
|
if (!channel->setenv_packet) {
|
||||||
return _libssh2_error(session, LIBSSH2_ERROR_ALLOC,
|
return _libssh2_error(session, LIBSSH2_ERROR_ALLOC,
|
||||||
"Unable to allocate memeory "
|
"Unable to allocate memory "
|
||||||
"for setenv packet");
|
"for setenv packet");
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1413,6 +1410,9 @@ _libssh2_channel_flush(LIBSSH2_CHANNEL *channel, int streamid)
|
|||||||
channel->flush_state = libssh2_NB_state_created;
|
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) {
|
if (channel->flush_refund_bytes) {
|
||||||
int rc;
|
int rc;
|
||||||
|
|
||||||
@@ -1483,10 +1483,11 @@ libssh2_channel_get_exit_signal(LIBSSH2_CHANNEL *channel,
|
|||||||
char **langtag,
|
char **langtag,
|
||||||
size_t *langtag_len)
|
size_t *langtag_len)
|
||||||
{
|
{
|
||||||
LIBSSH2_SESSION *session = channel->session;
|
|
||||||
size_t namelen = 0;
|
size_t namelen = 0;
|
||||||
|
|
||||||
if (channel) {
|
if (channel) {
|
||||||
|
LIBSSH2_SESSION *session = channel->session;
|
||||||
|
|
||||||
if (channel->exit_signal) {
|
if (channel->exit_signal) {
|
||||||
namelen = strlen(channel->exit_signal);
|
namelen = strlen(channel->exit_signal);
|
||||||
if (exitsignal) {
|
if (exitsignal) {
|
||||||
@@ -1542,6 +1543,9 @@ _libssh2_channel_receive_window_adjust(LIBSSH2_CHANNEL * channel,
|
|||||||
{
|
{
|
||||||
int rc;
|
int rc;
|
||||||
|
|
||||||
|
if(store)
|
||||||
|
*store = channel->remote.window_size;
|
||||||
|
|
||||||
if (channel->adjust_state == libssh2_NB_state_idle) {
|
if (channel->adjust_state == libssh2_NB_state_idle) {
|
||||||
if (!force
|
if (!force
|
||||||
&& (adjustment + channel->adjust_queue <
|
&& (adjustment + channel->adjust_queue <
|
||||||
@@ -1551,14 +1555,10 @@ _libssh2_channel_receive_window_adjust(LIBSSH2_CHANNEL * channel,
|
|||||||
"for channel %lu/%lu",
|
"for channel %lu/%lu",
|
||||||
adjustment, channel->local.id, channel->remote.id);
|
adjustment, channel->local.id, channel->remote.id);
|
||||||
channel->adjust_queue += adjustment;
|
channel->adjust_queue += adjustment;
|
||||||
if(store)
|
|
||||||
*store = channel->remote.window_size;
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!adjustment && !channel->adjust_queue) {
|
if (!adjustment && !channel->adjust_queue) {
|
||||||
if(store)
|
|
||||||
*store = channel->remote.window_size;
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1596,8 +1596,6 @@ _libssh2_channel_receive_window_adjust(LIBSSH2_CHANNEL * channel,
|
|||||||
|
|
||||||
channel->adjust_state = libssh2_NB_state_idle;
|
channel->adjust_state = libssh2_NB_state_idle;
|
||||||
|
|
||||||
if(store)
|
|
||||||
*store = channel->remote.window_size;
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1623,7 +1621,7 @@ libssh2_channel_receive_window_adjust(LIBSSH2_CHANNEL *channel,
|
|||||||
int rc;
|
int rc;
|
||||||
|
|
||||||
if(!channel)
|
if(!channel)
|
||||||
return LIBSSH2_ERROR_BAD_USE;
|
return (unsigned long)LIBSSH2_ERROR_BAD_USE;
|
||||||
|
|
||||||
BLOCK_ADJUST(rc, channel->session,
|
BLOCK_ADJUST(rc, channel->session,
|
||||||
_libssh2_channel_receive_window_adjust(channel, adj,
|
_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"
|
"Setting channel %lu/%lu handle_extended_data"
|
||||||
" mode to %d",
|
" mode to %d",
|
||||||
channel->local.id, channel->remote.id, ignore_mode);
|
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;
|
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_packet;
|
||||||
LIBSSH2_PACKET *read_next;
|
LIBSSH2_PACKET *read_next;
|
||||||
|
|
||||||
if (channel->read_state == libssh2_NB_state_idle) {
|
_libssh2_debug(session, LIBSSH2_TRACE_CONN,
|
||||||
_libssh2_debug(session, LIBSSH2_TRACE_CONN,
|
"channel_read() wants %d bytes from channel %lu/%lu "
|
||||||
"channel_read() wants %d bytes from channel %lu/%lu "
|
"stream #%d",
|
||||||
"stream #%d",
|
(int) buflen, channel->local.id, channel->remote.id,
|
||||||
(int) buflen, channel->local.id, channel->remote.id,
|
stream_id);
|
||||||
stream_id);
|
|
||||||
channel->read_state = libssh2_NB_state_created;
|
/* 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. Tests prove that this way
|
||||||
|
produces faster transfers. */
|
||||||
/* Process all pending incoming packets in all states in order to "even
|
do {
|
||||||
out" the network readings. Tests prove that this way produces faster
|
|
||||||
transfers. */
|
|
||||||
while (rc > 0)
|
|
||||||
rc = _libssh2_transport_read(session);
|
rc = _libssh2_transport_read(session);
|
||||||
|
} while (rc > 0);
|
||||||
|
|
||||||
if ((rc < 0) && (rc != LIBSSH2_ERROR_EAGAIN))
|
if ((rc < 0) && (rc != LIBSSH2_ERROR_EAGAIN))
|
||||||
return _libssh2_error(session, rc, "transport read");
|
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) {
|
if (!bytes_read) {
|
||||||
channel->read_state = libssh2_NB_state_idle;
|
|
||||||
|
|
||||||
/* If the channel is already at EOF or even closed, we need to signal
|
/* 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
|
that back. We may have gotten that info while draining the incoming
|
||||||
transport layer until EAGAIN so we must not be fooled by that
|
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 */
|
/* if the transport layer said EAGAIN then we say so as well */
|
||||||
return _libssh2_error(session, rc, "would block");
|
return _libssh2_error(session, rc, "would block");
|
||||||
}
|
}
|
||||||
else
|
|
||||||
/* make sure we remain in the created state to focus on emptying the
|
channel->read_avail -= bytes_read;
|
||||||
data we already have in the packet brigade before we try to read
|
channel->remote.window_size -= bytes_read;
|
||||||
more off the network again */
|
|
||||||
channel->read_state = libssh2_NB_state_created;
|
|
||||||
|
|
||||||
return bytes_read;
|
return bytes_read;
|
||||||
}
|
}
|
||||||
@@ -2008,12 +2016,22 @@ _libssh2_channel_write(LIBSSH2_CHANNEL *channel, int stream_id,
|
|||||||
rc = _libssh2_transport_read(session);
|
rc = _libssh2_transport_read(session);
|
||||||
while (rc > 0);
|
while (rc > 0);
|
||||||
|
|
||||||
if((rc < 0) && (rc != LIBSSH2_ERROR_EAGAIN))
|
if((rc < 0) && (rc != LIBSSH2_ERROR_EAGAIN)) {
|
||||||
return rc;
|
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 */
|
/* 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);
|
return (rc==LIBSSH2_ERROR_EAGAIN?rc:0);
|
||||||
|
}
|
||||||
|
|
||||||
channel->write_bufwrite = buflen;
|
channel->write_bufwrite = buflen;
|
||||||
|
|
||||||
@@ -2250,7 +2268,6 @@ int _libssh2_channel_close(LIBSSH2_CHANNEL * channel)
|
|||||||
{
|
{
|
||||||
LIBSSH2_SESSION *session = channel->session;
|
LIBSSH2_SESSION *session = channel->session;
|
||||||
int rc = 0;
|
int rc = 0;
|
||||||
int retcode;
|
|
||||||
|
|
||||||
if (channel->local.close) {
|
if (channel->local.close) {
|
||||||
/* Already closed, act like we sent another close,
|
/* Already closed, act like we sent another close,
|
||||||
@@ -2259,9 +2276,15 @@ int _libssh2_channel_close(LIBSSH2_CHANNEL * channel)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!channel->local.eof)
|
if (!channel->local.eof) {
|
||||||
if ((retcode = channel_send_eof(channel)))
|
if ((rc = channel_send_eof(channel))) {
|
||||||
return retcode;
|
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
|
/* ignore if we have received a remote eof or not, as it is now too
|
||||||
late for us to wait for it. Continue closing! */
|
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) {
|
if (channel->close_state == libssh2_NB_state_created) {
|
||||||
retcode = _libssh2_transport_send(session, channel->close_packet, 5,
|
rc = _libssh2_transport_send(session, channel->close_packet, 5,
|
||||||
NULL, 0);
|
NULL, 0);
|
||||||
if (retcode == LIBSSH2_ERROR_EAGAIN) {
|
if (rc == LIBSSH2_ERROR_EAGAIN) {
|
||||||
_libssh2_error(session, rc,
|
_libssh2_error(session, rc,
|
||||||
"Would block sending close-channel");
|
"Would block sending close-channel");
|
||||||
return retcode;
|
return rc;
|
||||||
} else if (retcode) {
|
|
||||||
channel->close_state = libssh2_NB_state_idle;
|
|
||||||
return _libssh2_error(session, retcode,
|
|
||||||
"Unable to send close-channel request");
|
|
||||||
}
|
|
||||||
|
|
||||||
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) {
|
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
|
* libssh2_channel_window_write_ex
|
||||||
*
|
*
|
||||||
* Check the status of the write window Returns the number of bytes which may
|
* 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
|
* passed) will be populated with the size of the initial window as defined by
|
||||||
* the channel_open request
|
* 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) 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.
|
* All rights reserved.
|
||||||
*
|
*
|
||||||
* Redistribution and use in source and binary forms,
|
* 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 = {
|
static const LIBSSH2_COMP_METHOD comp_method_none = {
|
||||||
"none",
|
"none",
|
||||||
0, /* not really compressing */
|
0, /* not really compressing */
|
||||||
|
0, /* isn't used in userauth, go figure */
|
||||||
NULL,
|
NULL,
|
||||||
comp_method_none_comp,
|
comp_method_none_comp,
|
||||||
comp_method_none_decomp,
|
comp_method_none_decomp,
|
||||||
@@ -140,13 +141,12 @@ comp_method_zlib_init(LIBSSH2_SESSION * session, int compr,
|
|||||||
z_stream *strm;
|
z_stream *strm;
|
||||||
int status;
|
int status;
|
||||||
|
|
||||||
strm = LIBSSH2_ALLOC(session, sizeof(z_stream));
|
strm = LIBSSH2_CALLOC(session, sizeof(z_stream));
|
||||||
if (!strm) {
|
if (!strm) {
|
||||||
return _libssh2_error(session, LIBSSH2_ERROR_ALLOC,
|
return _libssh2_error(session, LIBSSH2_ERROR_ALLOC,
|
||||||
"Unable to allocate memory for "
|
"Unable to allocate memory for "
|
||||||
"zlib compression/decompression");
|
"zlib compression/decompression");
|
||||||
}
|
}
|
||||||
memset(strm, 0, sizeof(z_stream));
|
|
||||||
|
|
||||||
strm->opaque = (voidpf) session;
|
strm->opaque = (voidpf) session;
|
||||||
strm->zalloc = (alloc_func) comp_method_zlib_alloc;
|
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);
|
status = deflate(strm, Z_PARTIAL_FLUSH);
|
||||||
|
|
||||||
if (status != Z_OK) {
|
if ((status == Z_OK) && (strm->avail_out > 0)) {
|
||||||
_libssh2_debug(session, LIBSSH2_TRACE_TRANS,
|
*dest_len = out_maxlen - strm->avail_out;
|
||||||
"unhandled zlib compression error %d", status);
|
return 0;
|
||||||
return _libssh2_error(session, LIBSSH2_ERROR_ZLIB,
|
|
||||||
"compression failure");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
*dest_len = out_maxlen - strm->avail_out;
|
_libssh2_debug(session, LIBSSH2_TRACE_TRANS,
|
||||||
return 0;
|
"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
|
/* A short-term alloc of a full data chunk is better than a series of
|
||||||
reallocs */
|
reallocs */
|
||||||
char *out;
|
char *out;
|
||||||
int out_maxlen = 8 * src_len;
|
int out_maxlen = 4 * src_len;
|
||||||
int limiter = 0;
|
|
||||||
|
|
||||||
/* If strm is null, then we have not yet been initialized. */
|
/* If strm is null, then we have not yet been initialized. */
|
||||||
if (strm == NULL)
|
if (strm == NULL)
|
||||||
return _libssh2_error(session, LIBSSH2_ERROR_COMPRESS,
|
return _libssh2_error(session, LIBSSH2_ERROR_COMPRESS,
|
||||||
"decompression unitilized");;
|
"decompression uninitialized");;
|
||||||
|
|
||||||
/* In practice they never come smaller than this */
|
/* In practice they never come smaller than this */
|
||||||
if (out_maxlen < 25)
|
if (out_maxlen < 25)
|
||||||
@@ -248,83 +246,49 @@ comp_method_zlib_decomp(LIBSSH2_SESSION * session,
|
|||||||
if (!strm->next_out)
|
if (!strm->next_out)
|
||||||
return _libssh2_error(session, LIBSSH2_ERROR_ALLOC,
|
return _libssh2_error(session, LIBSSH2_ERROR_ALLOC,
|
||||||
"Unable to allocate decompression buffer");
|
"Unable to allocate decompression buffer");
|
||||||
while (strm->avail_in) {
|
|
||||||
|
/* Loop until it's all inflated or hit error */
|
||||||
|
for (;;) {
|
||||||
int status;
|
int status;
|
||||||
|
size_t out_ofs;
|
||||||
|
char *newout;
|
||||||
|
|
||||||
status = inflate(strm, Z_PARTIAL_FLUSH);
|
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_FREE(session, out);
|
||||||
_libssh2_debug(session, LIBSSH2_TRACE_TRANS,
|
_libssh2_debug(session, LIBSSH2_TRACE_TRANS,
|
||||||
"unhandled zlib error %d", status);
|
"unhandled zlib error %d", status);
|
||||||
return _libssh2_error(session, LIBSSH2_ERROR_ZLIB,
|
return _libssh2_error(session, LIBSSH2_ERROR_ZLIB,
|
||||||
"decompression failure");
|
"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++) {
|
/* If we get here we need to grow the output buffer and try again */
|
||||||
LIBSSH2_FREE(session, out);
|
out_ofs = out_maxlen - strm->avail_out;
|
||||||
return _libssh2_error(session, LIBSSH2_ERROR_ZLIB,
|
out_maxlen *= 2;
|
||||||
"Excessive growth in decompression phase");
|
newout = LIBSSH2_REALLOC(session, out, out_maxlen);
|
||||||
}
|
if (!newout) {
|
||||||
|
LIBSSH2_FREE(session, out);
|
||||||
newout = LIBSSH2_REALLOC(session, out, out_maxlen);
|
return _libssh2_error(session, LIBSSH2_ERROR_ALLOC,
|
||||||
if (!newout) {
|
"Unable to expand decompression buffer");
|
||||||
LIBSSH2_FREE(session, out);
|
}
|
||||||
return _libssh2_error(session, LIBSSH2_ERROR_ALLOC,
|
out = newout;
|
||||||
"Unable to expand decompression buffer");
|
strm->next_out = (unsigned char *) out + out_ofs;
|
||||||
}
|
strm->avail_out = out_maxlen - out_ofs;
|
||||||
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");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
*dest = (unsigned char *) out;
|
*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 = {
|
static const LIBSSH2_COMP_METHOD comp_method_zlib = {
|
||||||
"zlib",
|
"zlib",
|
||||||
1, /* yes, this compresses */
|
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_init,
|
||||||
comp_method_zlib_comp,
|
comp_method_zlib_comp,
|
||||||
comp_method_zlib_decomp,
|
comp_method_zlib_decomp,
|
||||||
@@ -369,6 +344,7 @@ static const LIBSSH2_COMP_METHOD comp_method_zlib = {
|
|||||||
static const LIBSSH2_COMP_METHOD *comp_methods[] = {
|
static const LIBSSH2_COMP_METHOD *comp_methods[] = {
|
||||||
#ifdef LIBSSH2_HAVE_ZLIB
|
#ifdef LIBSSH2_HAVE_ZLIB
|
||||||
&comp_method_zlib,
|
&comp_method_zlib,
|
||||||
|
&comp_method_zlib_openssh,
|
||||||
#endif /* LIBSSH2_HAVE_ZLIB */
|
#endif /* LIBSSH2_HAVE_ZLIB */
|
||||||
&comp_method_none,
|
&comp_method_none,
|
||||||
NULL
|
NULL
|
||||||
|
@@ -96,11 +96,12 @@ crypt_init(LIBSSH2_SESSION * session,
|
|||||||
|
|
||||||
static int
|
static int
|
||||||
crypt_encrypt(LIBSSH2_SESSION * session, unsigned char *block,
|
crypt_encrypt(LIBSSH2_SESSION * session, unsigned char *block,
|
||||||
void **abstract)
|
size_t blocksize, void **abstract)
|
||||||
{
|
{
|
||||||
struct crypt_ctx *cctx = *(struct crypt_ctx **) abstract;
|
struct crypt_ctx *cctx = *(struct crypt_ctx **) abstract;
|
||||||
(void) session;
|
(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
|
static int
|
||||||
@@ -248,7 +249,8 @@ crypt_init_arcfour128(LIBSSH2_SESSION * session,
|
|||||||
unsigned char block[8];
|
unsigned char block[8];
|
||||||
size_t discard = 1536;
|
size_t discard = 1536;
|
||||||
for (; discard; discard -= 8)
|
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;
|
return rc;
|
||||||
|
14
src/crypto.h
14
src/crypto.h
@@ -38,10 +38,16 @@
|
|||||||
#ifndef LIBSSH2_CRYPTO_H
|
#ifndef LIBSSH2_CRYPTO_H
|
||||||
#define LIBSSH2_CRYPTO_H
|
#define LIBSSH2_CRYPTO_H
|
||||||
|
|
||||||
|
#ifdef LIBSSH2_OPENSSL
|
||||||
|
#include "openssl.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifdef LIBSSH2_LIBGCRYPT
|
#ifdef LIBSSH2_LIBGCRYPT
|
||||||
#include "libgcrypt.h"
|
#include "libgcrypt.h"
|
||||||
#else
|
#endif
|
||||||
#include "openssl.h"
|
|
||||||
|
#ifdef LIBSSH2_WINCNG
|
||||||
|
#include "wincng.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
int _libssh2_rsa_new(libssh2_rsa_ctx ** rsa,
|
int _libssh2_rsa_new(libssh2_rsa_ctx ** rsa,
|
||||||
@@ -75,6 +81,7 @@ int _libssh2_rsa_sha1_sign(LIBSSH2_SESSION * session,
|
|||||||
unsigned char **signature,
|
unsigned char **signature,
|
||||||
size_t *signature_len);
|
size_t *signature_len);
|
||||||
|
|
||||||
|
#if LIBSSH2_DSA
|
||||||
int _libssh2_dsa_new(libssh2_dsa_ctx ** dsa,
|
int _libssh2_dsa_new(libssh2_dsa_ctx ** dsa,
|
||||||
const unsigned char *pdata,
|
const unsigned char *pdata,
|
||||||
unsigned long plen,
|
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,
|
int _libssh2_dsa_sha1_sign(libssh2_dsa_ctx * dsactx,
|
||||||
const unsigned char *hash,
|
const unsigned char *hash,
|
||||||
unsigned long hash_len, unsigned char *sig);
|
unsigned long hash_len, unsigned char *sig);
|
||||||
|
#endif
|
||||||
|
|
||||||
int _libssh2_cipher_init(_libssh2_cipher_ctx * h,
|
int _libssh2_cipher_init(_libssh2_cipher_ctx * h,
|
||||||
_libssh2_cipher_type(algo),
|
_libssh2_cipher_type(algo),
|
||||||
@@ -103,7 +111,7 @@ int _libssh2_cipher_init(_libssh2_cipher_ctx * h,
|
|||||||
|
|
||||||
int _libssh2_cipher_crypt(_libssh2_cipher_ctx * ctx,
|
int _libssh2_cipher_crypt(_libssh2_cipher_ctx * ctx,
|
||||||
_libssh2_cipher_type(algo),
|
_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,
|
int _libssh2_pub_priv_keyfile(LIBSSH2_SESSION *session,
|
||||||
unsigned char **method,
|
unsigned char **method,
|
||||||
|
@@ -1,5 +1,5 @@
|
|||||||
/* Copyright (c) 2004-2006, Sara Golemon <sarag@libssh2.org>
|
/* 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.
|
* All rights reserved.
|
||||||
*
|
*
|
||||||
* Redistribution and use in source and binary forms,
|
* Redistribution and use in source and binary forms,
|
||||||
@@ -347,13 +347,12 @@ hostkey_method_ssh_dss_signv(LIBSSH2_SESSION * session,
|
|||||||
libssh2_sha1_ctx ctx;
|
libssh2_sha1_ctx ctx;
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
*signature = LIBSSH2_ALLOC(session, 2 * SHA_DIGEST_LENGTH);
|
*signature = LIBSSH2_CALLOC(session, 2 * SHA_DIGEST_LENGTH);
|
||||||
if (!*signature) {
|
if (!*signature) {
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
*signature_len = 2 * SHA_DIGEST_LENGTH;
|
*signature_len = 2 * SHA_DIGEST_LENGTH;
|
||||||
memset(*signature, 0, 2 * SHA_DIGEST_LENGTH);
|
|
||||||
|
|
||||||
libssh2_sha1_init(&ctx);
|
libssh2_sha1_init(&ctx);
|
||||||
for(i = 0; i < veccount; i++) {
|
for(i = 0; i < veccount; i++) {
|
||||||
@@ -429,7 +428,9 @@ libssh2_hostkey_hash(LIBSSH2_SESSION * session, int hash_type)
|
|||||||
switch (hash_type) {
|
switch (hash_type) {
|
||||||
#if LIBSSH2_MD5
|
#if LIBSSH2_MD5
|
||||||
case LIBSSH2_HOSTKEY_HASH_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;
|
break;
|
||||||
#endif /* LIBSSH2_MD5 */
|
#endif /* LIBSSH2_MD5 */
|
||||||
case LIBSSH2_HOSTKEY_HASH_SHA1:
|
case LIBSSH2_HOSTKEY_HASH_SHA1:
|
||||||
|
@@ -75,7 +75,8 @@ libssh2_keepalive_send (LIBSSH2_SESSION *session,
|
|||||||
size_t len = sizeof (keepalive_data) - 1;
|
size_t len = sizeof (keepalive_data) - 1;
|
||||||
int rc;
|
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);
|
rc = _libssh2_transport_send(session, keepalive_data, len, NULL, 0);
|
||||||
/* Silently ignore PACKET_EAGAIN here: if the write buffer is
|
/* Silently ignore PACKET_EAGAIN here: if the write buffer is
|
||||||
@@ -90,8 +91,8 @@ libssh2_keepalive_send (LIBSSH2_SESSION *session,
|
|||||||
if (seconds_to_next)
|
if (seconds_to_next)
|
||||||
*seconds_to_next = session->keepalive_interval;
|
*seconds_to_next = session->keepalive_interval;
|
||||||
} else if (seconds_to_next) {
|
} else if (seconds_to_next) {
|
||||||
*seconds_to_next = (int) session->keepalive_last_sent
|
*seconds_to_next = (int) (session->keepalive_last_sent - now)
|
||||||
+ session->keepalive_interval - now;
|
+ session->keepalive_interval;
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
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_ctx fingerprint_ctx;
|
||||||
|
|
||||||
libssh2_md5_init(&fingerprint_ctx);
|
if (libssh2_md5_init(&fingerprint_ctx)) {
|
||||||
libssh2_md5_update(fingerprint_ctx, session->server_hostkey,
|
libssh2_md5_update(fingerprint_ctx, session->server_hostkey,
|
||||||
session->server_hostkey_len);
|
session->server_hostkey_len);
|
||||||
libssh2_md5_final(fingerprint_ctx, session->server_hostkey_md5);
|
libssh2_md5_final(fingerprint_ctx, session->server_hostkey_md5);
|
||||||
|
session->server_hostkey_md5_valid = TRUE;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
session->server_hostkey_md5_valid = FALSE;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
#ifdef LIBSSH2DEBUG
|
#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"
|
* 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
|
/* kex_agree_methods
|
||||||
* Decide which specific method to use of the methods offered by each party
|
* 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;
|
s += 16;
|
||||||
|
|
||||||
/* Locate each string */
|
/* Locate each string */
|
||||||
kex_len = _libssh2_ntohu32(s);
|
if(kex_string_pair(&s, data, data_len, &kex_len, &kex))
|
||||||
kex = s + 4;
|
return -1;
|
||||||
s += 4 + kex_len;
|
if(kex_string_pair(&s, data, data_len, &hostkey_len, &hostkey))
|
||||||
hostkey_len = _libssh2_ntohu32(s);
|
return -1;
|
||||||
hostkey = s + 4;
|
if(kex_string_pair(&s, data, data_len, &crypt_cs_len, &crypt_cs))
|
||||||
s += 4 + hostkey_len;
|
return -1;
|
||||||
crypt_cs_len = _libssh2_ntohu32(s);
|
if(kex_string_pair(&s, data, data_len, &crypt_sc_len, &crypt_sc))
|
||||||
crypt_cs = s + 4;
|
return -1;
|
||||||
s += 4 + crypt_cs_len;
|
if(kex_string_pair(&s, data, data_len, &mac_cs_len, &mac_cs))
|
||||||
crypt_sc_len = _libssh2_ntohu32(s);
|
return -1;
|
||||||
crypt_sc = s + 4;
|
if(kex_string_pair(&s, data, data_len, &mac_sc_len, &mac_sc))
|
||||||
s += 4 + crypt_sc_len;
|
return -1;
|
||||||
mac_cs_len = _libssh2_ntohu32(s);
|
if(kex_string_pair(&s, data, data_len, &comp_cs_len, &comp_cs))
|
||||||
mac_cs = s + 4;
|
return -1;
|
||||||
s += 4 + mac_cs_len;
|
if(kex_string_pair(&s, data, data_len, &comp_sc_len, &comp_sc))
|
||||||
mac_sc_len = _libssh2_ntohu32(s);
|
return -1;
|
||||||
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 the server sent an optimistic packet, assume that it guessed wrong.
|
/* 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)
|
* 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 */
|
* 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;
|
key_state->state = libssh2_NB_state_sent2;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (rc == 0) {
|
if (rc == 0 && session->kex) {
|
||||||
if (key_state->state == libssh2_NB_state_sent2) {
|
if (key_state->state == libssh2_NB_state_sent2) {
|
||||||
retcode = session->kex->exchange_keys(session,
|
retcode = session->kex->exchange_keys(session,
|
||||||
&key_state->key_state_low);
|
&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);
|
memcpy(s, prefs, prefs_len + 1);
|
||||||
|
|
||||||
while (s && *s) {
|
while (s && *s && mlist) {
|
||||||
char *p = strchr(s, ',');
|
char *p = strchr(s, ',');
|
||||||
int method_len = p ? (p - s) : (int) strlen(s);
|
int method_len = p ? (p - s) : (int) strlen(s);
|
||||||
|
|
||||||
|
322
src/knownhost.c
322
src/knownhost.c
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2009-2011 by Daniel Stenberg
|
* Copyright (c) 2009-2014 by Daniel Stenberg
|
||||||
* All rights reserved.
|
* All rights reserved.
|
||||||
*
|
*
|
||||||
* Redistribution and use in source and binary forms,
|
* Redistribution and use in source and binary forms,
|
||||||
@@ -50,7 +50,11 @@ struct known_host {
|
|||||||
size_t salt_len; /* size of salt */
|
size_t salt_len; /* size of salt */
|
||||||
char *key; /* the (allocated) associated key. This is kept base64
|
char *key; /* the (allocated) associated key. This is kept base64
|
||||||
encoded in memory. */
|
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 */
|
/* this is the struct we expose externally */
|
||||||
struct libssh2_knownhost external;
|
struct libssh2_knownhost external;
|
||||||
@@ -67,6 +71,8 @@ static void free_host(LIBSSH2_SESSION *session, struct known_host *entry)
|
|||||||
if(entry) {
|
if(entry) {
|
||||||
if(entry->comment)
|
if(entry->comment)
|
||||||
LIBSSH2_FREE(session, entry->comment);
|
LIBSSH2_FREE(session, entry->comment);
|
||||||
|
if (entry->key_type_name)
|
||||||
|
LIBSSH2_FREE(session, entry->key_type_name);
|
||||||
if(entry->key)
|
if(entry->key)
|
||||||
LIBSSH2_FREE(session, entry->key);
|
LIBSSH2_FREE(session, entry->key);
|
||||||
if(entry->salt)
|
if(entry->salt)
|
||||||
@@ -127,6 +133,7 @@ static struct libssh2_knownhost *knownhost_to_external(struct known_host *node)
|
|||||||
static int
|
static int
|
||||||
knownhost_add(LIBSSH2_KNOWNHOSTS *hosts,
|
knownhost_add(LIBSSH2_KNOWNHOSTS *hosts,
|
||||||
const char *host, const char *salt,
|
const char *host, const char *salt,
|
||||||
|
const char *key_type_name, size_t key_type_len,
|
||||||
const char *key, size_t keylen,
|
const char *key, size_t keylen,
|
||||||
const char *comment, size_t commentlen,
|
const char *comment, size_t commentlen,
|
||||||
int typemask, struct libssh2_knownhost **store)
|
int typemask, struct libssh2_knownhost **store)
|
||||||
@@ -142,13 +149,11 @@ knownhost_add(LIBSSH2_KNOWNHOSTS *hosts,
|
|||||||
return _libssh2_error(hosts->session, LIBSSH2_ERROR_INVAL,
|
return _libssh2_error(hosts->session, LIBSSH2_ERROR_INVAL,
|
||||||
"No key type set");
|
"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,
|
return _libssh2_error(hosts->session, LIBSSH2_ERROR_ALLOC,
|
||||||
"Unable to allocate memory for known host "
|
"Unable to allocate memory for known host "
|
||||||
"entry");
|
"entry");
|
||||||
|
|
||||||
memset(entry, 0, sizeof(struct known_host));
|
|
||||||
|
|
||||||
entry->typemask = typemask;
|
entry->typemask = typemask;
|
||||||
|
|
||||||
switch(entry->typemask & LIBSSH2_KNOWNHOST_TYPE_MASK) {
|
switch(entry->typemask & LIBSSH2_KNOWNHOST_TYPE_MASK) {
|
||||||
@@ -161,6 +166,7 @@ knownhost_add(LIBSSH2_KNOWNHOSTS *hosts,
|
|||||||
goto error;
|
goto error;
|
||||||
}
|
}
|
||||||
memcpy(entry->name, host, hostlen+1);
|
memcpy(entry->name, host, hostlen+1);
|
||||||
|
entry->name_len = hostlen;
|
||||||
break;
|
break;
|
||||||
case LIBSSH2_KNOWNHOST_TYPE_SHA1:
|
case LIBSSH2_KNOWNHOST_TYPE_SHA1:
|
||||||
rc = libssh2_base64_decode(hosts->session, &ptr, &ptrlen,
|
rc = libssh2_base64_decode(hosts->session, &ptr, &ptrlen,
|
||||||
@@ -210,6 +216,19 @@ knownhost_add(LIBSSH2_KNOWNHOSTS *hosts,
|
|||||||
entry->key = ptr;
|
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) {
|
if (comment) {
|
||||||
entry->comment = LIBSSH2_ALLOC(hosts->session, commentlen+1);
|
entry->comment = LIBSSH2_ALLOC(hosts->session, commentlen+1);
|
||||||
if(!entry->comment) {
|
if(!entry->comment) {
|
||||||
@@ -219,6 +238,7 @@ knownhost_add(LIBSSH2_KNOWNHOSTS *hosts,
|
|||||||
}
|
}
|
||||||
memcpy(entry->comment, comment, commentlen+1);
|
memcpy(entry->comment, comment, commentlen+1);
|
||||||
entry->comment[commentlen]=0; /* force a terminating zero trailer */
|
entry->comment[commentlen]=0; /* force a terminating zero trailer */
|
||||||
|
entry->comment_len = commentlen;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
entry->comment = NULL;
|
entry->comment = NULL;
|
||||||
@@ -264,8 +284,8 @@ libssh2_knownhost_add(LIBSSH2_KNOWNHOSTS *hosts,
|
|||||||
const char *key, size_t keylen,
|
const char *key, size_t keylen,
|
||||||
int typemask, struct libssh2_knownhost **store)
|
int typemask, struct libssh2_knownhost **store)
|
||||||
{
|
{
|
||||||
return knownhost_add(hosts, host, salt, key, keylen, NULL, 0, typemask,
|
return knownhost_add(hosts, host, salt, NULL, 0, key, keylen, NULL,
|
||||||
store);
|
0, typemask, store);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -303,8 +323,8 @@ libssh2_knownhost_addc(LIBSSH2_KNOWNHOSTS *hosts,
|
|||||||
const char *comment, size_t commentlen,
|
const char *comment, size_t commentlen,
|
||||||
int typemask, struct libssh2_knownhost **store)
|
int typemask, struct libssh2_knownhost **store)
|
||||||
{
|
{
|
||||||
return knownhost_add(hosts, host, salt, key, keylen, comment, commentlen,
|
return knownhost_add(hosts, host, salt, NULL, 0, key, keylen,
|
||||||
typemask, store);
|
comment, commentlen, typemask, store);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -346,6 +366,24 @@ knownhost_check(LIBSSH2_KNOWNHOSTS *hosts,
|
|||||||
/* we can't work with a sha1 as given input */
|
/* we can't work with a sha1 as given input */
|
||||||
return LIBSSH2_KNOWNHOST_CHECK_MISMATCH;
|
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)) {
|
if(!(typemask & LIBSSH2_KNOWNHOST_KEYENC_BASE64)) {
|
||||||
/* we got a raw key input, convert it to base64 for the checks below */
|
/* we got a raw key input, convert it to base64 for the checks below */
|
||||||
size_t nlen = _libssh2_base64_encode(hosts->session, key, keylen,
|
size_t nlen = _libssh2_base64_encode(hosts->session, key, keylen,
|
||||||
@@ -361,18 +399,6 @@ knownhost_check(LIBSSH2_KNOWNHOSTS *hosts,
|
|||||||
key = keyalloc;
|
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 {
|
do {
|
||||||
node = _libssh2_list_first(&hosts->head);
|
node = _libssh2_list_first(&hosts->head);
|
||||||
while (node) {
|
while (node) {
|
||||||
@@ -399,7 +425,8 @@ knownhost_check(LIBSSH2_KNOWNHOSTS *hosts,
|
|||||||
we can't match it */
|
we can't match it */
|
||||||
break;
|
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,
|
libssh2_hmac_update(ctx, (unsigned char *)host,
|
||||||
strlen(host));
|
strlen(host));
|
||||||
libssh2_hmac_final(ctx, hash);
|
libssh2_hmac_final(ctx, hash);
|
||||||
@@ -414,23 +441,35 @@ knownhost_check(LIBSSH2_KNOWNHOSTS *hosts,
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if(match) {
|
if(match) {
|
||||||
/* host name match, now compare the keys */
|
int host_key_type = typemask & LIBSSH2_KNOWNHOST_KEY_MASK;
|
||||||
if(!strcmp(key, node->key)) {
|
int known_key_type =
|
||||||
/* they match! */
|
node->typemask & LIBSSH2_KNOWNHOST_KEY_MASK;
|
||||||
if (ext)
|
/* match on key type as follows:
|
||||||
*ext = knownhost_to_external(node);
|
- never match on an unknown key type
|
||||||
badkey = NULL;
|
- if key_type is set to zero, ignore it an match always
|
||||||
rc = LIBSSH2_KNOWNHOST_CHECK_MATCH;
|
- otherwise match when both key types are equal
|
||||||
break;
|
*/
|
||||||
}
|
if ( (host_key_type != LIBSSH2_KNOWNHOST_KEY_UNKNOWN ) &&
|
||||||
else {
|
( (host_key_type == 0) ||
|
||||||
/* remember the first node that had a host match but a
|
(host_key_type == known_key_type) ) ) {
|
||||||
failed key match since we continue our search from
|
/* host name and key type match, now compare the keys */
|
||||||
here */
|
if(!strcmp(key, node->key)) {
|
||||||
if(!badkey)
|
/* they match! */
|
||||||
badkey = node;
|
if (ext)
|
||||||
match = 0; /* don't count this as a match anymore */
|
*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);
|
node= _libssh2_list_next(&node->node);
|
||||||
}
|
}
|
||||||
@@ -573,6 +612,7 @@ libssh2_knownhost_free(LIBSSH2_KNOWNHOSTS *hosts)
|
|||||||
*/
|
*/
|
||||||
static int oldstyle_hostline(LIBSSH2_KNOWNHOSTS *hosts,
|
static int oldstyle_hostline(LIBSSH2_KNOWNHOSTS *hosts,
|
||||||
const char *host, size_t hostlen,
|
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 *key, size_t keylen, int key_type,
|
||||||
const char *comment, size_t commentlen)
|
const char *comment, size_t commentlen)
|
||||||
{
|
{
|
||||||
@@ -607,7 +647,9 @@ static int oldstyle_hostline(LIBSSH2_KNOWNHOSTS *hosts,
|
|||||||
memcpy(hostbuf, name, namelen);
|
memcpy(hostbuf, name, namelen);
|
||||||
hostbuf[namelen]=0;
|
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,
|
comment, commentlen,
|
||||||
key_type | LIBSSH2_KNOWNHOST_TYPE_PLAIN |
|
key_type | LIBSSH2_KNOWNHOST_TYPE_PLAIN |
|
||||||
LIBSSH2_KNOWNHOST_KEYENC_BASE64, NULL);
|
LIBSSH2_KNOWNHOST_KEYENC_BASE64, NULL);
|
||||||
@@ -627,6 +669,7 @@ static int oldstyle_hostline(LIBSSH2_KNOWNHOSTS *hosts,
|
|||||||
/* |1|[salt]|[hash] */
|
/* |1|[salt]|[hash] */
|
||||||
static int hashed_hostline(LIBSSH2_KNOWNHOSTS *hosts,
|
static int hashed_hostline(LIBSSH2_KNOWNHOSTS *hosts,
|
||||||
const char *host, size_t hostlen,
|
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 *key, size_t keylen, int key_type,
|
||||||
const char *comment, size_t commentlen)
|
const char *comment, size_t commentlen)
|
||||||
{
|
{
|
||||||
@@ -670,8 +713,10 @@ static int hashed_hostline(LIBSSH2_KNOWNHOSTS *hosts,
|
|||||||
memcpy(hostbuf, host, hostlen);
|
memcpy(hostbuf, host, hostlen);
|
||||||
hostbuf[hostlen]=0;
|
hostbuf[hostlen]=0;
|
||||||
|
|
||||||
return knownhost_add(hosts, hostbuf, salt, key, keylen, comment,
|
return knownhost_add(hosts, hostbuf, salt,
|
||||||
commentlen,
|
key_type_name, key_type_len,
|
||||||
|
key, keylen,
|
||||||
|
comment, commentlen,
|
||||||
key_type | LIBSSH2_KNOWNHOST_TYPE_SHA1 |
|
key_type | LIBSSH2_KNOWNHOST_TYPE_SHA1 |
|
||||||
LIBSSH2_KNOWNHOST_KEYENC_BASE64, NULL);
|
LIBSSH2_KNOWNHOST_KEYENC_BASE64, NULL);
|
||||||
}
|
}
|
||||||
@@ -694,7 +739,9 @@ static int hostline(LIBSSH2_KNOWNHOSTS *hosts,
|
|||||||
const char *key, size_t keylen)
|
const char *key, size_t keylen)
|
||||||
{
|
{
|
||||||
const char *comment = NULL;
|
const char *comment = NULL;
|
||||||
|
const char *key_type_name = NULL;
|
||||||
size_t commentlen = 0;
|
size_t commentlen = 0;
|
||||||
|
size_t key_type_len = 0;
|
||||||
int key_type;
|
int key_type;
|
||||||
|
|
||||||
/* make some checks that the lengths seem sensible */
|
/* make some checks that the lengths seem sensible */
|
||||||
@@ -716,19 +763,21 @@ static int hostline(LIBSSH2_KNOWNHOSTS *hosts,
|
|||||||
*/
|
*/
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 's': /* ssh-dss or ssh-rsa */
|
default:
|
||||||
if(!strncmp(key, "ssh-dss", 7))
|
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;
|
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;
|
key_type = LIBSSH2_KNOWNHOST_KEY_SSHRSA;
|
||||||
else
|
else
|
||||||
/* unknown key type */
|
key_type = LIBSSH2_KNOWNHOST_KEY_UNKNOWN;
|
||||||
return _libssh2_error(hosts->session,
|
|
||||||
LIBSSH2_ERROR_METHOD_NOT_SUPPORTED,
|
|
||||||
"Unknown key type");
|
|
||||||
|
|
||||||
key += 7;
|
|
||||||
keylen -= 7;
|
|
||||||
|
|
||||||
/* skip whitespaces */
|
/* skip whitespaces */
|
||||||
while((*key ==' ') || (*key == '\t')) {
|
while((*key ==' ') || (*key == '\t')) {
|
||||||
@@ -760,11 +809,6 @@ static int hostline(LIBSSH2_KNOWNHOSTS *hosts,
|
|||||||
commentlen--;
|
commentlen--;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default: /* unknown key format */
|
|
||||||
return _libssh2_error(hosts->session,
|
|
||||||
LIBSSH2_ERROR_METHOD_NOT_SUPPORTED,
|
|
||||||
"Unknown key format");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Figure out host 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
|
for the sake of simplicity, we add them as separate hosts with the
|
||||||
same key
|
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);
|
comment, commentlen);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
/* |1|[salt]|[hash] */
|
/* |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);
|
comment, commentlen);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -910,8 +956,11 @@ libssh2_knownhost_readfile(LIBSSH2_KNOWNHOSTS *hosts,
|
|||||||
file = fopen(filename, "r");
|
file = fopen(filename, "r");
|
||||||
if(file) {
|
if(file) {
|
||||||
while(fgets(buf, sizeof(buf), 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;
|
break;
|
||||||
|
}
|
||||||
num++;
|
num++;
|
||||||
}
|
}
|
||||||
fclose(file);
|
fclose(file);
|
||||||
@@ -940,17 +989,10 @@ knownhost_writeline(LIBSSH2_KNOWNHOSTS *hosts,
|
|||||||
char *buf, size_t buflen,
|
char *buf, size_t buflen,
|
||||||
size_t *outlen, int type)
|
size_t *outlen, int type)
|
||||||
{
|
{
|
||||||
int rc = LIBSSH2_ERROR_NONE;
|
size_t required_size;
|
||||||
int tindex;
|
|
||||||
const char *keytypes[4]={
|
const char *key_type_name;
|
||||||
"", /* not used */
|
size_t key_type_len;
|
||||||
"", /* this type has no name in the file */
|
|
||||||
" ssh-rsa",
|
|
||||||
" ssh-dss"
|
|
||||||
};
|
|
||||||
const char *keytype;
|
|
||||||
size_t nlen;
|
|
||||||
size_t commentlen = 0;
|
|
||||||
|
|
||||||
/* we only support this single file type for now, bail out on all other
|
/* we only support this single file type for now, bail out on all other
|
||||||
attempts */
|
attempts */
|
||||||
@@ -960,75 +1002,131 @@ knownhost_writeline(LIBSSH2_KNOWNHOSTS *hosts,
|
|||||||
"Unsupported type of known-host information "
|
"Unsupported type of known-host information "
|
||||||
"store");
|
"store");
|
||||||
|
|
||||||
tindex = (node->typemask & LIBSSH2_KNOWNHOST_KEY_MASK) >>
|
switch(node->typemask & LIBSSH2_KNOWNHOST_KEY_MASK) {
|
||||||
LIBSSH2_KNOWNHOST_KEY_SHIFT;
|
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 */
|
/* When putting together the host line there are three aspects to consider:
|
||||||
keytype = keytypes[tindex];
|
- Hashed (SHA1) or unhashed hostname
|
||||||
|
- key name or no key name (RSA1)
|
||||||
|
- comment or no comment
|
||||||
|
|
||||||
/* calculate extra space needed for 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. */
|
||||||
|
|
||||||
|
required_size = strlen(node->key);
|
||||||
|
|
||||||
|
if(key_type_len)
|
||||||
|
required_size += key_type_len + 1; /* ' ' = 1 */
|
||||||
if(node->comment)
|
if(node->comment)
|
||||||
commentlen = strlen(node->comment) + 1;
|
required_size += node->comment_len + 1; /* ' ' = 1 */
|
||||||
|
|
||||||
if((node->typemask & LIBSSH2_KNOWNHOST_TYPE_MASK) ==
|
if((node->typemask & LIBSSH2_KNOWNHOST_TYPE_MASK) ==
|
||||||
LIBSSH2_KNOWNHOST_TYPE_SHA1) {
|
LIBSSH2_KNOWNHOST_TYPE_SHA1) {
|
||||||
char *namealloc;
|
char *namealloc;
|
||||||
|
size_t name_base64_len;
|
||||||
char *saltalloc;
|
char *saltalloc;
|
||||||
nlen = _libssh2_base64_encode(hosts->session, node->name,
|
size_t salt_base64_len;
|
||||||
node->name_len, &namealloc);
|
|
||||||
if(!nlen)
|
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,
|
return _libssh2_error(hosts->session, LIBSSH2_ERROR_ALLOC,
|
||||||
"Unable to allocate memory for "
|
"Unable to allocate memory for "
|
||||||
"base64-encoded host name");
|
"base64-encoded host name");
|
||||||
|
|
||||||
nlen = _libssh2_base64_encode(hosts->session,
|
salt_base64_len = _libssh2_base64_encode(hosts->session,
|
||||||
node->salt, node->salt_len,
|
node->salt, node->salt_len,
|
||||||
&saltalloc);
|
&saltalloc);
|
||||||
if(!nlen) {
|
if(!salt_base64_len) {
|
||||||
free(namealloc);
|
LIBSSH2_FREE(hosts->session, namealloc);
|
||||||
return _libssh2_error(hosts->session, LIBSSH2_ERROR_ALLOC,
|
return _libssh2_error(hosts->session, LIBSSH2_ERROR_ALLOC,
|
||||||
"Unable to allocate memory for "
|
"Unable to allocate memory for "
|
||||||
"base64-encoded salt");
|
"base64-encoded salt");
|
||||||
}
|
}
|
||||||
|
|
||||||
nlen = strlen(saltalloc) + strlen(namealloc) + strlen(keytype) +
|
required_size += salt_base64_len + name_base64_len + 7;
|
||||||
strlen(node->key) + commentlen + 7;
|
|
||||||
/* |1| + | + ' ' + \n + \0 = 7 */
|
/* |1| + | + ' ' + \n + \0 = 7 */
|
||||||
|
|
||||||
if(nlen <= buflen)
|
if(required_size <= buflen) {
|
||||||
if(node->comment)
|
if(node->comment && key_type_len)
|
||||||
snprintf(buf, buflen, "|1|%s|%s%s %s %s\n", saltalloc, namealloc,
|
snprintf(buf, buflen, "|1|%s|%s %s %s %s\n", saltalloc,
|
||||||
keytype, node->key, node->comment);
|
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
|
else
|
||||||
snprintf(buf, buflen, "|1|%s|%s%s %s\n", saltalloc, namealloc,
|
snprintf(buf, buflen, "|1|%s|%s %s\n", saltalloc, namealloc,
|
||||||
keytype, node->key);
|
node->key);
|
||||||
else
|
}
|
||||||
rc = _libssh2_error(hosts->session, LIBSSH2_ERROR_BUFFER_TOO_SMALL,
|
|
||||||
"Known-host write buffer too small");
|
|
||||||
|
|
||||||
free(namealloc);
|
LIBSSH2_FREE(hosts->session, namealloc);
|
||||||
free(saltalloc);
|
LIBSSH2_FREE(hosts->session, saltalloc);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
nlen = strlen(node->name) + strlen(keytype) + strlen(node->key) +
|
required_size += node->name_len + 3;
|
||||||
commentlen + 3;
|
|
||||||
/* ' ' + '\n' + \0 = 3 */
|
/* ' ' + '\n' + \0 = 3 */
|
||||||
if(nlen <= buflen)
|
|
||||||
/* these types have the plain name */
|
if(required_size <= buflen) {
|
||||||
if(node->comment)
|
if(node->comment && key_type_len)
|
||||||
snprintf(buf, buflen, "%s%s %s %s\n", node->name, keytype, node->key,
|
snprintf(buf, buflen, "%s %s %s %s\n", node->name,
|
||||||
node->comment);
|
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
|
else
|
||||||
snprintf(buf, buflen, "%s%s %s\n", node->name, keytype, node->key);
|
snprintf(buf, buflen, "%s %s\n", node->name, node->key);
|
||||||
else
|
}
|
||||||
rc = _libssh2_error(hosts->session, LIBSSH2_ERROR_BUFFER_TOO_SMALL,
|
|
||||||
"Known-host write buffer too small");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* we report the full length of the data with the trailing zero excluded */
|
/* 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);
|
for(node = _libssh2_list_first(&hosts->head);
|
||||||
node;
|
node;
|
||||||
node= _libssh2_list_next(&node->node) ) {
|
node = _libssh2_list_next(&node->node)) {
|
||||||
size_t wrote;
|
size_t wrote = 0;
|
||||||
size_t nwrote;
|
size_t nwrote;
|
||||||
rc = knownhost_writeline(hosts, node, buffer, sizeof(buffer), &wrote,
|
rc = knownhost_writeline(hosts, node, buffer, sizeof(buffer), &wrote,
|
||||||
type);
|
type);
|
||||||
|
@@ -342,7 +342,7 @@ _libssh2_dsa_new_private(libssh2_dsa_ctx ** dsa,
|
|||||||
|
|
||||||
int
|
int
|
||||||
_libssh2_rsa_sha1_sign(LIBSSH2_SESSION * session,
|
_libssh2_rsa_sha1_sign(LIBSSH2_SESSION * session,
|
||||||
libssh2_dsa_ctx * rsactx,
|
libssh2_rsa_ctx * rsactx,
|
||||||
const unsigned char *hash,
|
const unsigned char *hash,
|
||||||
size_t hash_len,
|
size_t hash_len,
|
||||||
unsigned char **signature, size_t *signature_len)
|
unsigned char **signature, size_t *signature_len)
|
||||||
@@ -553,17 +553,11 @@ _libssh2_cipher_init(_libssh2_cipher_ctx * h,
|
|||||||
int
|
int
|
||||||
_libssh2_cipher_crypt(_libssh2_cipher_ctx * ctx,
|
_libssh2_cipher_crypt(_libssh2_cipher_ctx * ctx,
|
||||||
_libssh2_cipher_type(algo),
|
_libssh2_cipher_type(algo),
|
||||||
int encrypt, unsigned char *block)
|
int encrypt, unsigned char *block, size_t blklen)
|
||||||
{
|
{
|
||||||
int cipher = _libssh2_gcry_cipher (algo);
|
int cipher = _libssh2_gcry_cipher (algo);
|
||||||
size_t blklen = gcry_cipher_get_algo_blklen(cipher);
|
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
if (blklen == 1) {
|
|
||||||
/* Hack for arcfour. */
|
|
||||||
blklen = 8;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (encrypt) {
|
if (encrypt) {
|
||||||
ret = gcry_cipher_encrypt(*ctx, block, blklen, block, blklen);
|
ret = gcry_cipher_encrypt(*ctx, block, blklen, block, blklen);
|
||||||
} else {
|
} else {
|
||||||
|
@@ -61,15 +61,21 @@
|
|||||||
|
|
||||||
#define libssh2_sha1_ctx gcry_md_hd_t
|
#define libssh2_sha1_ctx gcry_md_hd_t
|
||||||
#define libssh2_sha1_init(ctx) gcry_md_open (ctx, GCRY_MD_SHA1, 0);
|
#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) \
|
#define libssh2_sha1_final(ctx, out) \
|
||||||
memcpy (out, gcry_md_read (ctx, 0), SHA_DIGEST_LENGTH), gcry_md_close (ctx)
|
memcpy (out, gcry_md_read (ctx, 0), SHA_DIGEST_LENGTH), gcry_md_close (ctx)
|
||||||
#define libssh2_sha1(message, len, out) \
|
#define libssh2_sha1(message, len, out) \
|
||||||
gcry_md_hash_buffer (GCRY_MD_SHA1, out, message, len)
|
gcry_md_hash_buffer (GCRY_MD_SHA1, out, message, len)
|
||||||
|
|
||||||
#define libssh2_md5_ctx gcry_md_hd_t
|
#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) \
|
#define libssh2_md5_final(ctx, out) \
|
||||||
memcpy (out, gcry_md_read (ctx, 0), MD5_DIGEST_LENGTH), gcry_md_close (ctx)
|
memcpy (out, gcry_md_read (ctx, 0), MD5_DIGEST_LENGTH), gcry_md_close (ctx)
|
||||||
#define libssh2_md5(message, len, out) \
|
#define libssh2_md5(message, len, out) \
|
||||||
@@ -86,7 +92,7 @@
|
|||||||
gcry_md_open (ctx, GCRY_MD_RMD160, GCRY_MD_FLAG_HMAC), \
|
gcry_md_open (ctx, GCRY_MD_RMD160, GCRY_MD_FLAG_HMAC), \
|
||||||
gcry_md_setkey (*ctx, key, keylen)
|
gcry_md_setkey (*ctx, key, keylen)
|
||||||
#define libssh2_hmac_update(ctx, data, datalen) \
|
#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) \
|
#define libssh2_hmac_final(ctx, data) \
|
||||||
memcpy (data, gcry_md_read (ctx, 0), \
|
memcpy (data, gcry_md_read (ctx, 0), \
|
||||||
gcry_md_get_algo_dlen (gcry_md_get_algo (ctx)))
|
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) 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
|
* Copyright (c) 2010 Simon Josefsson
|
||||||
* All rights reserved.
|
* All rights reserved.
|
||||||
*
|
*
|
||||||
@@ -108,6 +108,11 @@
|
|||||||
#define TRUE 1
|
#define TRUE 1
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifdef _MSC_VER
|
||||||
|
/* "inline" keyword is valid only with C++ engine! */
|
||||||
|
#define inline __inline
|
||||||
|
#endif
|
||||||
|
|
||||||
/* Provide iovec / writev on WIN32 platform. */
|
/* Provide iovec / writev on WIN32 platform. */
|
||||||
#ifdef WIN32
|
#ifdef WIN32
|
||||||
|
|
||||||
@@ -116,8 +121,6 @@ struct iovec {
|
|||||||
void * iov_base;
|
void * iov_base;
|
||||||
};
|
};
|
||||||
|
|
||||||
#define inline __inline
|
|
||||||
|
|
||||||
static inline int writev(int sock, struct iovec *iov, int nvecs)
|
static inline int writev(int sock, struct iovec *iov, int nvecs)
|
||||||
{
|
{
|
||||||
DWORD ret;
|
DWORD ret;
|
||||||
@@ -134,14 +137,8 @@ static inline int writev(int sock, struct iovec *iov, int nvecs)
|
|||||||
#ifdef HAVE_WINSOCK2_H
|
#ifdef HAVE_WINSOCK2_H
|
||||||
|
|
||||||
#include <winsock2.h>
|
#include <winsock2.h>
|
||||||
#include <mswsock.h>
|
|
||||||
#include <ws2tcpip.h>
|
#include <ws2tcpip.h>
|
||||||
|
|
||||||
#ifdef _MSC_VER
|
|
||||||
/* "inline" keyword is valid only with C++ engine! */
|
|
||||||
#define inline __inline
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* RFC4253 section 6.1 Maximum Packet Length says:
|
/* 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) \
|
#define LIBSSH2_ALLOC(session, count) \
|
||||||
session->alloc((count), &(session)->abstract)
|
session->alloc((count), &(session)->abstract)
|
||||||
|
#define LIBSSH2_CALLOC(session, count) _libssh2_calloc(session, count)
|
||||||
#define LIBSSH2_REALLOC(session, ptr, count) \
|
#define LIBSSH2_REALLOC(session, ptr, count) \
|
||||||
((ptr) ? session->realloc((ptr), (count), &(session)->abstract) : \
|
((ptr) ? session->realloc((ptr), (count), &(session)->abstract) : \
|
||||||
session->alloc((count), &(session)->abstract))
|
session->alloc((count), &(session)->abstract))
|
||||||
@@ -357,6 +355,8 @@ struct _LIBSSH2_CHANNEL
|
|||||||
libssh2_channel_data local, remote;
|
libssh2_channel_data local, remote;
|
||||||
/* Amount of bytes to be refunded to receive window (but not yet sent) */
|
/* Amount of bytes to be refunded to receive window (but not yet sent) */
|
||||||
uint32_t adjust_queue;
|
uint32_t adjust_queue;
|
||||||
|
/* Data immediately available for reading */
|
||||||
|
uint32_t read_avail;
|
||||||
|
|
||||||
LIBSSH2_SESSION *session;
|
LIBSSH2_SESSION *session;
|
||||||
|
|
||||||
@@ -575,7 +575,7 @@ struct _LIBSSH2_SESSION
|
|||||||
|
|
||||||
/* Agreed Key Exchange Method */
|
/* Agreed Key Exchange Method */
|
||||||
const LIBSSH2_KEX_METHOD *kex;
|
const LIBSSH2_KEX_METHOD *kex;
|
||||||
int burn_optimistic_kexinit:1;
|
unsigned int burn_optimistic_kexinit:1;
|
||||||
|
|
||||||
unsigned char *session_id;
|
unsigned char *session_id;
|
||||||
uint32_t session_id_len;
|
uint32_t session_id_len;
|
||||||
@@ -597,6 +597,7 @@ struct _LIBSSH2_SESSION
|
|||||||
uint32_t server_hostkey_len;
|
uint32_t server_hostkey_len;
|
||||||
#if LIBSSH2_MD5
|
#if LIBSSH2_MD5
|
||||||
unsigned char server_hostkey_md5[MD5_DIGEST_LENGTH];
|
unsigned char server_hostkey_md5[MD5_DIGEST_LENGTH];
|
||||||
|
int server_hostkey_md5_valid;
|
||||||
#endif /* ! LIBSSH2_MD5 */
|
#endif /* ! LIBSSH2_MD5 */
|
||||||
unsigned char server_hostkey_sha1[SHA_DIGEST_LENGTH];
|
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 *free_iv, unsigned char *secret, int *free_secret,
|
||||||
int encrypt, void **abstract);
|
int encrypt, void **abstract);
|
||||||
int (*crypt) (LIBSSH2_SESSION * session, unsigned char *block,
|
int (*crypt) (LIBSSH2_SESSION * session, unsigned char *block,
|
||||||
void **abstract);
|
size_t blocksize, void **abstract);
|
||||||
int (*dtor) (LIBSSH2_SESSION * session, void **abstract);
|
int (*dtor) (LIBSSH2_SESSION * session, void **abstract);
|
||||||
|
|
||||||
_libssh2_cipher_type(algo);
|
_libssh2_cipher_type(algo);
|
||||||
@@ -892,6 +893,7 @@ struct _LIBSSH2_COMP_METHOD
|
|||||||
{
|
{
|
||||||
const char *name;
|
const char *name;
|
||||||
int compress; /* 1 if it does compress, 0 if it doesn't */
|
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 (*init) (LIBSSH2_SESSION *session, int compress, void **abstract);
|
||||||
int (*comp) (LIBSSH2_SESSION *session,
|
int (*comp) (LIBSSH2_SESSION *session,
|
||||||
unsigned char *dest,
|
unsigned char *dest,
|
||||||
@@ -921,6 +923,9 @@ void _libssh2_debug(LIBSSH2_SESSION * session, int context, const char *format,
|
|||||||
static inline void
|
static inline void
|
||||||
_libssh2_debug(LIBSSH2_SESSION * session, int context, const char *format, ...)
|
_libssh2_debug(LIBSSH2_SESSION * session, int context, const char *format, ...)
|
||||||
{
|
{
|
||||||
|
(void)session;
|
||||||
|
(void)context;
|
||||||
|
(void)format;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
@@ -1030,9 +1035,9 @@ void _libssh2_init_if_needed (void);
|
|||||||
|
|
||||||
/* define to output the libssh2_int64_t type in a *printf() */
|
/* define to output the libssh2_int64_t type in a *printf() */
|
||||||
#if defined( __BORLANDC__ ) || defined( _MSC_VER ) || defined( __MINGW32__ )
|
#if defined( __BORLANDC__ ) || defined( _MSC_VER ) || defined( __MINGW32__ )
|
||||||
#define LIBSSH2_INT64_T_FORMAT "I64"
|
#define LIBSSH2_INT64_T_FORMAT "I64d"
|
||||||
#else
|
#else
|
||||||
#define LIBSSH2_INT64_T_FORMAT "ll"
|
#define LIBSSH2_INT64_T_FORMAT "lld"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#endif /* LIBSSH2_H */
|
#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) 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
|
* Copyright (c) 2010 Simon Josefsson
|
||||||
* All rights reserved.
|
* All rights reserved.
|
||||||
*
|
*
|
||||||
@@ -94,9 +94,14 @@ static int wsa2errno(void)
|
|||||||
* Replacement for the standard recv, return -errno on failure.
|
* Replacement for the standard recv, return -errno on failure.
|
||||||
*/
|
*/
|
||||||
ssize_t
|
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
|
#ifdef WIN32
|
||||||
if (rc < 0 )
|
if (rc < 0 )
|
||||||
return -wsa2errno();
|
return -wsa2errno();
|
||||||
@@ -128,7 +133,11 @@ ssize_t
|
|||||||
_libssh2_send(libssh2_socket_t sock, const void *buffer, size_t length,
|
_libssh2_send(libssh2_socket_t sock, const void *buffer, size_t length,
|
||||||
int flags, void **abstract)
|
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
|
#ifdef WIN32
|
||||||
if (rc < 0 )
|
if (rc < 0 )
|
||||||
return -wsa2errno();
|
return -wsa2errno();
|
||||||
@@ -257,15 +266,15 @@ libssh2_base64_decode(LIBSSH2_SESSION *session, char **data,
|
|||||||
continue;
|
continue;
|
||||||
switch (i % 4) {
|
switch (i % 4) {
|
||||||
case 0:
|
case 0:
|
||||||
d[len] = v << 2;
|
d[len] = (unsigned char)(v << 2);
|
||||||
break;
|
break;
|
||||||
case 1:
|
case 1:
|
||||||
d[len++] |= v >> 4;
|
d[len++] |= v >> 4;
|
||||||
d[len] = v << 4;
|
d[len] = (unsigned char)(v << 4);
|
||||||
break;
|
break;
|
||||||
case 2:
|
case 2:
|
||||||
d[len++] |= v >> 2;
|
d[len++] |= v >> 2;
|
||||||
d[len] = v << 6;
|
d[len] = (unsigned char)(v << 6);
|
||||||
break;
|
break;
|
||||||
case 3:
|
case 3:
|
||||||
d[len++] |= v;
|
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 */
|
unsigned __int64 ns100; /*time since 1 Jan 1601 in 100ns units */
|
||||||
FILETIME ft;
|
FILETIME ft;
|
||||||
} _now;
|
} _now;
|
||||||
|
(void)tzp;
|
||||||
if(tp)
|
if(tp)
|
||||||
{
|
{
|
||||||
GetSystemTimeAsFileTime (&_now.ft);
|
GetSystemTimeAsFileTime (&_now.ft);
|
||||||
@@ -610,3 +619,12 @@ int __cdecl _libssh2_gettimeofday(struct timeval *tp, void *tzp)
|
|||||||
|
|
||||||
|
|
||||||
#endif
|
#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
|
#ifndef __LIBSSH2_MISC_H
|
||||||
#define __LIBSSH2_MISC_H
|
#define __LIBSSH2_MISC_H
|
||||||
/* Copyright (c) 2009-2011 by Daniel Stenberg
|
/* Copyright (c) 2009-2014 by Daniel Stenberg
|
||||||
*
|
*
|
||||||
* All rights reserved.
|
* All rights reserved.
|
||||||
*
|
*
|
||||||
@@ -77,6 +77,7 @@ libssh2_uint64_t _libssh2_ntohu64(const unsigned char *buf);
|
|||||||
void _libssh2_htonu32(unsigned char *buf, uint32_t val);
|
void _libssh2_htonu32(unsigned char *buf, uint32_t val);
|
||||||
void _libssh2_store_u32(unsigned char **buf, uint32_t value);
|
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_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__) && !defined(__CYGWIN__)
|
#if defined(LIBSSH2_WIN32) && !defined(__MINGW32__) && !defined(__CYGWIN__)
|
||||||
/* provide a private one */
|
/* provide a private one */
|
||||||
|
@@ -40,7 +40,7 @@
|
|||||||
|
|
||||||
#include "libssh2_priv.h"
|
#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>
|
#include <string.h>
|
||||||
|
|
||||||
@@ -175,25 +175,19 @@ _libssh2_cipher_init(_libssh2_cipher_ctx * h,
|
|||||||
unsigned char *iv, unsigned char *secret, int encrypt)
|
unsigned char *iv, unsigned char *secret, int encrypt)
|
||||||
{
|
{
|
||||||
EVP_CIPHER_CTX_init(h);
|
EVP_CIPHER_CTX_init(h);
|
||||||
EVP_CipherInit(h, algo(), secret, iv, encrypt);
|
return !EVP_CipherInit(h, algo(), secret, iv, encrypt);
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
_libssh2_cipher_crypt(_libssh2_cipher_ctx * ctx,
|
_libssh2_cipher_crypt(_libssh2_cipher_ctx * ctx,
|
||||||
_libssh2_cipher_type(algo),
|
_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];
|
unsigned char buf[EVP_MAX_BLOCK_LENGTH];
|
||||||
int ret;
|
int ret;
|
||||||
(void) algo;
|
(void) algo;
|
||||||
(void) encrypt;
|
(void) encrypt;
|
||||||
|
|
||||||
if (blocksize == 1) {
|
|
||||||
/* Hack for arcfour. */
|
|
||||||
blocksize = 8;
|
|
||||||
}
|
|
||||||
ret = EVP_Cipher(ctx, buf, block, blocksize);
|
ret = EVP_Cipher(ctx, buf, block, blocksize);
|
||||||
if (ret == 1) {
|
if (ret == 1) {
|
||||||
memcpy(block, buf, blocksize);
|
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
|
* variable "c" is leaked from this scope, but is later freed
|
||||||
* in aes_ctr_cleanup
|
* in aes_ctr_cleanup
|
||||||
*/
|
*/
|
||||||
aes_ctr_ctx *c = malloc(sizeof(*c));
|
aes_ctr_ctx *c;
|
||||||
const EVP_CIPHER *aes_cipher;
|
const EVP_CIPHER *aes_cipher;
|
||||||
(void) enc;
|
(void) enc;
|
||||||
|
|
||||||
if (c == NULL)
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
switch (ctx->key_len) {
|
switch (ctx->key_len) {
|
||||||
case 16:
|
case 16:
|
||||||
aes_cipher = EVP_aes_128_ecb();
|
aes_cipher = EVP_aes_128_ecb();
|
||||||
@@ -241,11 +232,20 @@ aes_ctr_init(EVP_CIPHER_CTX *ctx, const unsigned char *key,
|
|||||||
default:
|
default:
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
c->aes_ctx = malloc(sizeof(EVP_CIPHER_CTX));
|
|
||||||
if (c->aes_ctx == NULL)
|
c = malloc(sizeof(*c));
|
||||||
|
if (c == NULL)
|
||||||
return 0;
|
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) {
|
if (EVP_EncryptInit(c->aes_ctx, aes_cipher, key, NULL) != 1) {
|
||||||
|
free(c->aes_ctx);
|
||||||
|
free(c);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -509,23 +509,39 @@ _libssh2_dsa_sha1_sign(libssh2_dsa_ctx * dsactx,
|
|||||||
}
|
}
|
||||||
#endif /* LIBSSH_DSA */
|
#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
|
void
|
||||||
libssh2_sha1(const unsigned char *message, unsigned long len,
|
libssh2_sha1(const unsigned char *message, unsigned long len,
|
||||||
unsigned char *out)
|
unsigned char *out)
|
||||||
{
|
{
|
||||||
EVP_MD_CTX ctx;
|
EVP_MD_CTX ctx;
|
||||||
|
|
||||||
|
EVP_MD_CTX_init(&ctx);
|
||||||
EVP_DigestInit(&ctx, EVP_get_digestbyname("sha1"));
|
EVP_DigestInit(&ctx, EVP_get_digestbyname("sha1"));
|
||||||
EVP_DigestUpdate(&ctx, message, len);
|
EVP_DigestUpdate(&ctx, message, len);
|
||||||
EVP_DigestFinal(&ctx, out, NULL);
|
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
|
void
|
||||||
libssh2_md5(const unsigned char *message, unsigned long len,
|
libssh2_md5(const unsigned char *message, unsigned long len,
|
||||||
unsigned char *out)
|
unsigned char *out)
|
||||||
{
|
{
|
||||||
EVP_MD_CTX ctx;
|
EVP_MD_CTX ctx;
|
||||||
|
|
||||||
|
EVP_MD_CTX_init(&ctx);
|
||||||
EVP_DigestInit(&ctx, EVP_get_digestbyname("md5"));
|
EVP_DigestInit(&ctx, EVP_get_digestbyname("md5"));
|
||||||
EVP_DigestUpdate(&ctx, message, len);
|
EVP_DigestUpdate(&ctx, message, len);
|
||||||
EVP_DigestFinal(&ctx, out, NULL);
|
EVP_DigestFinal(&ctx, out, NULL);
|
||||||
@@ -801,4 +817,4 @@ _libssh2_pub_priv_keyfile(LIBSSH2_SESSION *session,
|
|||||||
return st;
|
return st;
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif /* !LIBSSH2_LIBGCRYPT */
|
#endif /* LIBSSH2_OPENSSL */
|
||||||
|
@@ -107,13 +107,15 @@
|
|||||||
#define _libssh2_random(buf, len) RAND_bytes ((buf), (len))
|
#define _libssh2_random(buf, len) RAND_bytes ((buf), (len))
|
||||||
|
|
||||||
#define libssh2_sha1_ctx EVP_MD_CTX
|
#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_update(ctx, data, len) EVP_DigestUpdate(&(ctx), data, len)
|
||||||
#define libssh2_sha1_final(ctx, out) EVP_DigestFinal(&(ctx), out, NULL)
|
#define libssh2_sha1_final(ctx, out) EVP_DigestFinal(&(ctx), out, NULL)
|
||||||
void libssh2_sha1(const unsigned char *message, unsigned long len, unsigned char *out);
|
void libssh2_sha1(const unsigned char *message, unsigned long len, unsigned char *out);
|
||||||
|
|
||||||
#define libssh2_md5_ctx EVP_MD_CTX
|
#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_update(ctx, data, len) EVP_DigestUpdate(&(ctx), data, len)
|
||||||
#define libssh2_md5_final(ctx, out) EVP_DigestFinal(&(ctx), out, NULL)
|
#define libssh2_md5_final(ctx, out) EVP_DigestFinal(&(ctx), out, NULL)
|
||||||
void libssh2_md5(const unsigned char *message, unsigned long len, unsigned char *out);
|
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_aes256 EVP_aes_256_cbc
|
||||||
#define _libssh2_cipher_aes192 EVP_aes_192_cbc
|
#define _libssh2_cipher_aes192 EVP_aes_192_cbc
|
||||||
#define _libssh2_cipher_aes128 EVP_aes_128_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_aes128ctr _libssh2_EVP_aes_128_ctr
|
||||||
#define _libssh2_cipher_aes192ctr _libssh2_EVP_aes_192_ctr
|
#define _libssh2_cipher_aes192ctr _libssh2_EVP_aes_192_ctr
|
||||||
#define _libssh2_cipher_aes256ctr _libssh2_EVP_aes_256_ctr
|
#define _libssh2_cipher_aes256ctr _libssh2_EVP_aes_256_ctr
|
||||||
|
#endif
|
||||||
#define _libssh2_cipher_blowfish EVP_bf_cbc
|
#define _libssh2_cipher_blowfish EVP_bf_cbc
|
||||||
#define _libssh2_cipher_arcfour EVP_rc4
|
#define _libssh2_cipher_arcfour EVP_rc4
|
||||||
#define _libssh2_cipher_cast5 EVP_cast5_cbc
|
#define _libssh2_cipher_cast5 EVP_cast5_cbc
|
||||||
|
66
src/packet.c
66
src/packet.c
@@ -1,6 +1,6 @@
|
|||||||
/* Copyright (c) 2004-2007, Sara Golemon <sarag@libssh2.org>
|
/* Copyright (c) 2004-2007, Sara Golemon <sarag@libssh2.org>
|
||||||
* Copyright (c) 2005,2006 Mikhail Gusarov
|
* 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
|
* Copyright (c) 2010 Simon Josefsson
|
||||||
* All rights reserved.
|
* All rights reserved.
|
||||||
*
|
*
|
||||||
@@ -139,7 +139,7 @@ packet_queue_listener(LIBSSH2_SESSION * session, unsigned char *data,
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
channel = LIBSSH2_ALLOC(session, sizeof(LIBSSH2_CHANNEL));
|
channel = LIBSSH2_CALLOC(session, sizeof(LIBSSH2_CHANNEL));
|
||||||
if (!channel) {
|
if (!channel) {
|
||||||
_libssh2_error(session, LIBSSH2_ERROR_ALLOC,
|
_libssh2_error(session, LIBSSH2_ERROR_ALLOC,
|
||||||
"Unable to allocate a channel for "
|
"Unable to allocate a channel for "
|
||||||
@@ -150,8 +150,6 @@ packet_queue_listener(LIBSSH2_SESSION * session, unsigned char *data,
|
|||||||
}
|
}
|
||||||
listen_state->channel = channel;
|
listen_state->channel = channel;
|
||||||
|
|
||||||
memset(channel, 0, sizeof(LIBSSH2_CHANNEL));
|
|
||||||
|
|
||||||
channel->session = session;
|
channel->session = session;
|
||||||
channel->channel_type_len = sizeof("forwarded-tcpip") - 1;
|
channel->channel_type_len = sizeof("forwarded-tcpip") - 1;
|
||||||
channel->channel_type = LIBSSH2_ALLOC(session,
|
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 */
|
/* Link the channel into the end of the queue list */
|
||||||
_libssh2_list_add(&listn->queue,
|
if (listen_state->channel) {
|
||||||
&listen_state->channel->node);
|
_libssh2_list_add(&listn->queue,
|
||||||
listn->queue_size++;
|
&listen_state->channel->node);
|
||||||
|
listn->queue_size++;
|
||||||
|
}
|
||||||
|
|
||||||
listen_state->state = libssh2_NB_state_idle;
|
listen_state->state = libssh2_NB_state_idle;
|
||||||
return 0;
|
return 0;
|
||||||
@@ -297,14 +297,13 @@ packet_x11_open(LIBSSH2_SESSION * session, unsigned char *data,
|
|||||||
|
|
||||||
if (session->x11) {
|
if (session->x11) {
|
||||||
if (x11open_state->state == libssh2_NB_state_allocated) {
|
if (x11open_state->state == libssh2_NB_state_allocated) {
|
||||||
channel = LIBSSH2_ALLOC(session, sizeof(LIBSSH2_CHANNEL));
|
channel = LIBSSH2_CALLOC(session, sizeof(LIBSSH2_CHANNEL));
|
||||||
if (!channel) {
|
if (!channel) {
|
||||||
_libssh2_error(session, LIBSSH2_ERROR_ALLOC,
|
_libssh2_error(session, LIBSSH2_ERROR_ALLOC,
|
||||||
"allocate a channel for new connection");
|
"allocate a channel for new connection");
|
||||||
failure_code = SSH_OPEN_RESOURCE_SHORTAGE;
|
failure_code = SSH_OPEN_RESOURCE_SHORTAGE;
|
||||||
goto x11_exit;
|
goto x11_exit;
|
||||||
}
|
}
|
||||||
memset(channel, 0, sizeof(LIBSSH2_CHANNEL));
|
|
||||||
|
|
||||||
channel->session = session;
|
channel->session = session;
|
||||||
channel->channel_type_len = sizeof("x11") - 1;
|
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
|
* 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.
|
* 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.
|
* 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) {
|
if (want_reply) {
|
||||||
unsigned char packet = SSH_MSG_REQUEST_FAILURE;
|
static const unsigned char packet =
|
||||||
|
SSH_MSG_REQUEST_FAILURE;
|
||||||
libssh2_packet_add_jump_point5:
|
libssh2_packet_add_jump_point5:
|
||||||
session->packAdd_state = libssh2_NB_state_jump5;
|
session->packAdd_state = libssh2_NB_state_jump5;
|
||||||
rc = _libssh2_transport_send(session, &packet, 1, NULL, 0);
|
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,
|
_libssh2_debug(session, LIBSSH2_TRACE_CONN,
|
||||||
"Ignoring extended data and refunding %d bytes",
|
"Ignoring extended data and refunding %d bytes",
|
||||||
(int) (datalen - 13));
|
(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;
|
session->packAdd_channelp = channelp;
|
||||||
|
|
||||||
/* Adjust the window based on the block we just freed */
|
/* 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");
|
" to receive, truncating");
|
||||||
datalen = channelp->remote.packet_size + data_head;
|
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
|
* Spec says we MAY ignore bytes sent beyond
|
||||||
* window_size
|
* window_size
|
||||||
@@ -700,17 +713,26 @@ _libssh2_packet_add(LIBSSH2_SESSION * session, unsigned char *data,
|
|||||||
/* Reset EOF status */
|
/* Reset EOF status */
|
||||||
channelp->remote.eof = 0;
|
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(session,
|
||||||
LIBSSH2_ERROR_CHANNEL_WINDOW_EXCEEDED,
|
LIBSSH2_ERROR_CHANNEL_WINDOW_EXCEEDED,
|
||||||
"Remote sent more data than current "
|
"Remote sent more data than current "
|
||||||
"window allows, truncating");
|
"window allows, truncating");
|
||||||
datalen = channelp->remote.window_size + data_head;
|
datalen = channelp->remote.window_size -
|
||||||
channelp->remote.window_size = 0;
|
channelp->read_avail + data_head;
|
||||||
}
|
}
|
||||||
else
|
|
||||||
/* Now that we've received it, shrink our window */
|
/* Update the read_avail counter. The window size will be
|
||||||
channelp->remote.window_size -= datalen - data_head;
|
* 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;
|
break;
|
||||||
|
|
||||||
@@ -945,6 +967,7 @@ _libssh2_packet_add(LIBSSH2_SESSION * session, unsigned char *data,
|
|||||||
if (!packetp) {
|
if (!packetp) {
|
||||||
_libssh2_debug(session, LIBSSH2_ERROR_ALLOC,
|
_libssh2_debug(session, LIBSSH2_ERROR_ALLOC,
|
||||||
"memory for packet");
|
"memory for packet");
|
||||||
|
LIBSSH2_FREE(session, data);
|
||||||
session->packAdd_state = libssh2_NB_state_idle;
|
session->packAdd_state = libssh2_NB_state_idle;
|
||||||
return LIBSSH2_ERROR_ALLOC;
|
return LIBSSH2_ERROR_ALLOC;
|
||||||
}
|
}
|
||||||
@@ -1134,14 +1157,14 @@ _libssh2_packet_burn(LIBSSH2_SESSION * session,
|
|||||||
{
|
{
|
||||||
unsigned char *data;
|
unsigned char *data;
|
||||||
size_t data_len;
|
size_t data_len;
|
||||||
unsigned char all_packets[255];
|
unsigned char i, all_packets[255];
|
||||||
int i;
|
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
if (*state == libssh2_NB_state_idle) {
|
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[i - 1] = i;
|
||||||
}
|
}
|
||||||
|
all_packets[254] = 0;
|
||||||
|
|
||||||
if (_libssh2_packet_askv(session, all_packets, &data, &data_len, 0,
|
if (_libssh2_packet_askv(session, all_packets, &data, &data_len, 0,
|
||||||
NULL, 0) == 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 */
|
/* Be lazy, let packet_ask pull it out of the brigade */
|
||||||
if (0 ==
|
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 */
|
/* Smoke 'em if you got 'em */
|
||||||
LIBSSH2_FREE(session, data);
|
LIBSSH2_FREE(session, data);
|
||||||
*state = libssh2_NB_state_idle;
|
*state = libssh2_NB_state_idle;
|
||||||
|
12
src/pem.c
12
src/pem.c
@@ -38,8 +38,6 @@
|
|||||||
|
|
||||||
#include "libssh2_priv.h"
|
#include "libssh2_priv.h"
|
||||||
|
|
||||||
#ifdef LIBSSH2_LIBGCRYPT /* compile only if we build with libgcrypt */
|
|
||||||
|
|
||||||
static int
|
static int
|
||||||
readline(char *line, int line_size, FILE * fp)
|
readline(char *line, int line_size, FILE * fp)
|
||||||
{
|
{
|
||||||
@@ -69,6 +67,8 @@ _libssh2_pem_parse(LIBSSH2_SESSION * session,
|
|||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
do {
|
do {
|
||||||
|
*line = '\0';
|
||||||
|
|
||||||
if (readline(line, LINE_SIZE, fp)) {
|
if (readline(line, LINE_SIZE, fp)) {
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
@@ -93,12 +93,18 @@ _libssh2_pem_parse(LIBSSH2_SESSION * session,
|
|||||||
b64datalen += linelen;
|
b64datalen += linelen;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
*line = '\0';
|
||||||
|
|
||||||
if (readline(line, LINE_SIZE, fp)) {
|
if (readline(line, LINE_SIZE, fp)) {
|
||||||
ret = -1;
|
ret = -1;
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
} while (strcmp(line, headerend) != 0);
|
} while (strcmp(line, headerend) != 0);
|
||||||
|
|
||||||
|
if (!b64data) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
if (libssh2_base64_decode(session, (char**) data, datalen,
|
if (libssh2_base64_decode(session, (char**) data, datalen,
|
||||||
b64data, b64datalen)) {
|
b64data, b64datalen)) {
|
||||||
ret = -1;
|
ret = -1;
|
||||||
@@ -209,5 +215,3 @@ _libssh2_pem_decode_integer(unsigned char **data, unsigned int *datalen,
|
|||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif /* LIBSSH2_LIBGCRYPT */
|
|
||||||
|
@@ -1,5 +1,5 @@
|
|||||||
/* Copyright (c) 2004-2007, Sara Golemon <sarag@libssh2.org>
|
/* 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.
|
* All rights reserved.
|
||||||
*
|
*
|
||||||
* Redistribution and use in source and binary forms,
|
* Redistribution and use in source and binary forms,
|
||||||
@@ -136,6 +136,8 @@ publickey_packet_receive(LIBSSH2_PUBLICKEY * pkey,
|
|||||||
LIBSSH2_SESSION *session = channel->session;
|
LIBSSH2_SESSION *session = channel->session;
|
||||||
unsigned char buffer[4];
|
unsigned char buffer[4];
|
||||||
int rc;
|
int rc;
|
||||||
|
*data = NULL; /* default to nothing returned */
|
||||||
|
*data_len = 0;
|
||||||
|
|
||||||
if (pkey->receive_state == libssh2_NB_state_idle) {
|
if (pkey->receive_state == libssh2_NB_state_idle) {
|
||||||
rc = _libssh2_channel_read(channel, 0, (char *) buffer, 4);
|
rc = _libssh2_channel_read(channel, 0, (char *) buffer, 4);
|
||||||
@@ -348,13 +350,12 @@ static LIBSSH2_PUBLICKEY *publickey_init(LIBSSH2_SESSION *session)
|
|||||||
}
|
}
|
||||||
|
|
||||||
session->pkeyInit_pkey =
|
session->pkeyInit_pkey =
|
||||||
LIBSSH2_ALLOC(session, sizeof(LIBSSH2_PUBLICKEY));
|
LIBSSH2_CALLOC(session, sizeof(LIBSSH2_PUBLICKEY));
|
||||||
if (!session->pkeyInit_pkey) {
|
if (!session->pkeyInit_pkey) {
|
||||||
_libssh2_error(session, LIBSSH2_ERROR_ALLOC,
|
_libssh2_error(session, LIBSSH2_ERROR_ALLOC,
|
||||||
"Unable to allocate a new publickey structure");
|
"Unable to allocate a new publickey structure");
|
||||||
goto err_exit;
|
goto err_exit;
|
||||||
}
|
}
|
||||||
memset(session->pkeyInit_pkey, 0, sizeof(LIBSSH2_PUBLICKEY));
|
|
||||||
session->pkeyInit_pkey->channel = session->pkeyInit_channel;
|
session->pkeyInit_pkey->channel = session->pkeyInit_channel;
|
||||||
session->pkeyInit_pkey->version = 0;
|
session->pkeyInit_pkey->version = 0;
|
||||||
|
|
||||||
@@ -384,7 +385,7 @@ static LIBSSH2_PUBLICKEY *publickey_init(LIBSSH2_SESSION *session)
|
|||||||
_libssh2_error(session, LIBSSH2_ERROR_EAGAIN,
|
_libssh2_error(session, LIBSSH2_ERROR_EAGAIN,
|
||||||
"Would block sending publickey version packet");
|
"Would block sending publickey version packet");
|
||||||
return NULL;
|
return NULL;
|
||||||
} else if (rc) {
|
} else if (rc < 0) {
|
||||||
_libssh2_error(session, rc,
|
_libssh2_error(session, rc,
|
||||||
"Unable to send publickey version packet");
|
"Unable to send publickey version packet");
|
||||||
goto err_exit;
|
goto err_exit;
|
||||||
|
@@ -133,7 +133,7 @@ shell_quotearg(const char *path, unsigned char *buf,
|
|||||||
* Processing States:
|
* Processing States:
|
||||||
* UQSTRING: unquoted string: ... -- used for quoting exclamation
|
* UQSTRING: unquoted string: ... -- used for quoting exclamation
|
||||||
* marks. This is the initial state
|
* 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
|
* QSTRING: quoted string: "... -- only apostrophes may follow
|
||||||
*/
|
*/
|
||||||
enum { UQSTRING, SQSTRING, QSTRING } state = UQSTRING;
|
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_mtime = session->scpRecv_mtime;
|
||||||
sb->st_atime = session->scpRecv_atime;
|
sb->st_atime = session->scpRecv_atime;
|
||||||
sb->st_size = session->scpRecv_size;
|
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;
|
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 =
|
session->scpSend_response_len =
|
||||||
snprintf((char *) session->scpSend_response,
|
snprintf((char *) session->scpSend_response,
|
||||||
LIBSSH2_SCP_RESPONSE_BUFLEN, "C0%o %"
|
LIBSSH2_SCP_RESPONSE_BUFLEN, "C0%o %"
|
||||||
LIBSSH2_INT64_T_FORMAT "u %s\n", mode,
|
LIBSSH2_INT64_T_FORMAT " %s\n", mode,
|
||||||
size, base);
|
size, base);
|
||||||
_libssh2_debug(session, LIBSSH2_TRACE_SCP, "Sent %s",
|
_libssh2_debug(session, LIBSSH2_TRACE_SCP, "Sent %s",
|
||||||
session->scpSend_response);
|
session->scpSend_response);
|
||||||
|
@@ -686,8 +686,13 @@ session_startup(LIBSSH2_SESSION *session, libssh2_socket_t sock)
|
|||||||
!get_socket_nonblocking(session->socket_fd);
|
!get_socket_nonblocking(session->socket_fd);
|
||||||
|
|
||||||
if (session->socket_prev_blockstate) {
|
if (session->socket_prev_blockstate) {
|
||||||
/* If in blocking state chang to non-blocking */
|
/* If in blocking state change to non-blocking */
|
||||||
session_nonblock(session->socket_fd, 1);
|
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;
|
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",
|
_libssh2_debug(session, LIBSSH2_TRACE_TRANS, "Freeing session resource",
|
||||||
session->remote.banner);
|
session->remote.banner);
|
||||||
|
|
||||||
session->state = libssh2_NB_state_created;
|
session->free_state = libssh2_NB_state_created;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (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;
|
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))) {
|
while ((l = _libssh2_list_first(&session->listeners))) {
|
||||||
rc = _libssh2_channel_forward_cancel(l);
|
rc = _libssh2_channel_forward_cancel(l);
|
||||||
if (rc == LIBSSH2_ERROR_EAGAIN)
|
if (rc == LIBSSH2_ERROR_EAGAIN)
|
||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
session->state = libssh2_NB_state_sent1;
|
session->free_state = libssh2_NB_state_sent1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (session->state & LIBSSH2_STATE_NEWKEYS) {
|
if (session->state & LIBSSH2_STATE_NEWKEYS) {
|
||||||
@@ -1016,6 +1021,14 @@ session_free(LIBSSH2_SESSION *session)
|
|||||||
if (session->scpSend_command) {
|
if (session->scpSend_command) {
|
||||||
LIBSSH2_FREE(session, 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 */
|
/* Cleanup all remaining packets */
|
||||||
while ((pkg = _libssh2_list_first(&session->packets))) {
|
while ((pkg = _libssh2_list_first(&session->packets))) {
|
||||||
@@ -1032,9 +1045,14 @@ session_free(LIBSSH2_SESSION *session)
|
|||||||
_libssh2_debug(session, LIBSSH2_TRACE_TRANS,
|
_libssh2_debug(session, LIBSSH2_TRACE_TRANS,
|
||||||
"Extra packets left %d", packets_left);
|
"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 */
|
/* 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) {
|
if (session->server_hostkey) {
|
||||||
LIBSSH2_FREE(session, session->server_hostkey);
|
LIBSSH2_FREE(session, session->server_hostkey);
|
||||||
@@ -1514,7 +1532,7 @@ libssh2_poll(LIBSSH2_POLLFD * fds, unsigned int nfds, long timeout)
|
|||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
/* No select() or poll()
|
/* No select() or poll()
|
||||||
* no sockets sturcture to setup
|
* no sockets structure to setup
|
||||||
*/
|
*/
|
||||||
|
|
||||||
timeout = 0;
|
timeout = 0;
|
||||||
|
281
src/sftp.c
281
src/sftp.c
@@ -1,6 +1,6 @@
|
|||||||
/* Copyright (c) 2004-2008, Sara Golemon <sarag@libssh2.org>
|
/* Copyright (c) 2004-2008, Sara Golemon <sarag@libssh2.org>
|
||||||
* Copyright (c) 2007 Eli Fant <elifantu@mail.ru>
|
* 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.
|
* All rights reserved.
|
||||||
*
|
*
|
||||||
* Redistribution and use in source and binary forms,
|
* Redistribution and use in source and binary forms,
|
||||||
@@ -93,7 +93,6 @@
|
|||||||
some kind of server problem. */
|
some kind of server problem. */
|
||||||
#define LIBSSH2_SFTP_PACKET_MAXLEN 80000
|
#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,
|
static int sftp_packet_ask(LIBSSH2_SFTP *sftp, unsigned char packet_type,
|
||||||
uint32_t request_id, unsigned char **data,
|
uint32_t request_id, unsigned char **data,
|
||||||
size_t *data_len);
|
size_t *data_len);
|
||||||
@@ -535,7 +534,7 @@ sftp_packet_require(LIBSSH2_SFTP *sftp, unsigned char packet_type,
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* sftp_packet_requirev
|
/* sftp_packet_requirev
|
||||||
* Require one of N possible reponses
|
* Require one of N possible responses
|
||||||
*/
|
*/
|
||||||
static int
|
static int
|
||||||
sftp_packet_requirev(LIBSSH2_SFTP *sftp, int num_valid_responses,
|
sftp_packet_requirev(LIBSSH2_SFTP *sftp, int num_valid_responses,
|
||||||
@@ -721,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
|
* Note that you MUST NOT try to call libssh2_sftp_init() again to get
|
||||||
* another handle until the previous call has finished and either
|
* 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).
|
* including *EAGAIN).
|
||||||
*/
|
*/
|
||||||
|
|
||||||
@@ -782,13 +781,12 @@ static LIBSSH2_SFTP *sftp_init(LIBSSH2_SESSION *session)
|
|||||||
|
|
||||||
sftp_handle =
|
sftp_handle =
|
||||||
session->sftpInit_sftp =
|
session->sftpInit_sftp =
|
||||||
LIBSSH2_ALLOC(session, sizeof(LIBSSH2_SFTP));
|
LIBSSH2_CALLOC(session, sizeof(LIBSSH2_SFTP));
|
||||||
if (!sftp_handle) {
|
if (!sftp_handle) {
|
||||||
_libssh2_error(session, LIBSSH2_ERROR_ALLOC,
|
_libssh2_error(session, LIBSSH2_ERROR_ALLOC,
|
||||||
"Unable to allocate a new SFTP structure");
|
"Unable to allocate a new SFTP structure");
|
||||||
goto sftp_init_error;
|
goto sftp_init_error;
|
||||||
}
|
}
|
||||||
memset(sftp_handle, 0, sizeof(LIBSSH2_SFTP));
|
|
||||||
sftp_handle->channel = session->sftpInit_channel;
|
sftp_handle->channel = session->sftpInit_channel;
|
||||||
sftp_handle->request_id = 0;
|
sftp_handle->request_id = 0;
|
||||||
|
|
||||||
@@ -844,6 +842,7 @@ static LIBSSH2_SFTP *sftp_init(LIBSSH2_SESSION *session)
|
|||||||
if (data_len < 5) {
|
if (data_len < 5) {
|
||||||
_libssh2_error(session, LIBSSH2_ERROR_SFTP_PROTOCOL,
|
_libssh2_error(session, LIBSSH2_ERROR_SFTP_PROTOCOL,
|
||||||
"Invalid SSH_FXP_VERSION response");
|
"Invalid SSH_FXP_VERSION response");
|
||||||
|
LIBSSH2_FREE(session, data);
|
||||||
goto sftp_init_error;
|
goto sftp_init_error;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -857,7 +856,7 @@ static LIBSSH2_SFTP *sftp_init(LIBSSH2_SESSION *session)
|
|||||||
sftp_handle->version = LIBSSH2_SFTP_VERSION;
|
sftp_handle->version = LIBSSH2_SFTP_VERSION;
|
||||||
}
|
}
|
||||||
_libssh2_debug(session, LIBSSH2_TRACE_SFTP,
|
_libssh2_debug(session, LIBSSH2_TRACE_SFTP,
|
||||||
"Enabling SFTP version %lu compatability",
|
"Enabling SFTP version %lu compatibility",
|
||||||
sftp_handle->version);
|
sftp_handle->version);
|
||||||
while (s < (data + data_len)) {
|
while (s < (data + data_len)) {
|
||||||
size_t extname_len, extdata_len;
|
size_t extname_len, extdata_len;
|
||||||
@@ -928,7 +927,7 @@ LIBSSH2_API LIBSSH2_SFTP *libssh2_sftp_init(LIBSSH2_SESSION *session)
|
|||||||
/*
|
/*
|
||||||
* sftp_shutdown
|
* sftp_shutdown
|
||||||
*
|
*
|
||||||
* Shutsdown the SFTP subsystem
|
* Shuts down the SFTP subsystem
|
||||||
*/
|
*/
|
||||||
static int
|
static int
|
||||||
sftp_shutdown(LIBSSH2_SFTP *sftp)
|
sftp_shutdown(LIBSSH2_SFTP *sftp)
|
||||||
@@ -986,6 +985,10 @@ sftp_shutdown(LIBSSH2_SFTP *sftp)
|
|||||||
LIBSSH2_FREE(session, sftp->symlink_packet);
|
LIBSSH2_FREE(session, sftp->symlink_packet);
|
||||||
sftp->symlink_packet = NULL;
|
sftp->symlink_packet = NULL;
|
||||||
}
|
}
|
||||||
|
if (sftp->fsync_packet) {
|
||||||
|
LIBSSH2_FREE(session, sftp->fsync_packet);
|
||||||
|
sftp->fsync_packet = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
sftp_packet_flush(sftp);
|
sftp_packet_flush(sftp);
|
||||||
|
|
||||||
@@ -1169,14 +1172,13 @@ sftp_open(LIBSSH2_SFTP *sftp, const char *filename,
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
fp = LIBSSH2_ALLOC(session, sizeof(LIBSSH2_SFTP_HANDLE));
|
fp = LIBSSH2_CALLOC(session, sizeof(LIBSSH2_SFTP_HANDLE));
|
||||||
if (!fp) {
|
if (!fp) {
|
||||||
_libssh2_error(session, LIBSSH2_ERROR_ALLOC,
|
_libssh2_error(session, LIBSSH2_ERROR_ALLOC,
|
||||||
"Unable to allocate new SFTP handle structure");
|
"Unable to allocate new SFTP handle structure");
|
||||||
LIBSSH2_FREE(session, data);
|
LIBSSH2_FREE(session, data);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
memset(fp, 0, sizeof(LIBSSH2_SFTP_HANDLE));
|
|
||||||
fp->handle_type = open_file ? LIBSSH2_SFTP_HANDLE_FILE :
|
fp->handle_type = open_file ? LIBSSH2_SFTP_HANDLE_FILE :
|
||||||
LIBSSH2_SFTP_HANDLE_DIR;
|
LIBSSH2_SFTP_HANDLE_DIR;
|
||||||
|
|
||||||
@@ -1459,9 +1461,8 @@ static ssize_t sftp_read(LIBSSH2_SFTP_HANDLE * handle, char *buffer,
|
|||||||
|
|
||||||
switch (data[0]) {
|
switch (data[0]) {
|
||||||
case SSH_FXP_STATUS:
|
case SSH_FXP_STATUS:
|
||||||
/* remove the chunk we just processed keeping track of the
|
/* remove the chunk we just processed */
|
||||||
* next one in case we need it */
|
|
||||||
next = _libssh2_list_next(&chunk->node);
|
|
||||||
_libssh2_list_remove(&chunk->node);
|
_libssh2_list_remove(&chunk->node);
|
||||||
LIBSSH2_FREE(session, chunk);
|
LIBSSH2_FREE(session, chunk);
|
||||||
|
|
||||||
@@ -1489,6 +1490,14 @@ static ssize_t sftp_read(LIBSSH2_SFTP_HANDLE * handle, char *buffer,
|
|||||||
return _libssh2_error(session, LIBSSH2_ERROR_SFTP_PROTOCOL,
|
return _libssh2_error(session, LIBSSH2_ERROR_SFTP_PROTOCOL,
|
||||||
"SFTP Protocol badness");
|
"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) {
|
if(rc32 != chunk->len) {
|
||||||
/* a short read does not imply end of file, but we must
|
/* a short read does not imply end of file, but we must
|
||||||
adjust the offset_sent since it was advanced with a
|
adjust the offset_sent since it was advanced with a
|
||||||
@@ -1609,7 +1618,7 @@ static ssize_t sftp_readdir(LIBSSH2_SFTP_HANDLE *handle, char *buffer,
|
|||||||
|
|
||||||
filename_len = real_filename_len;
|
filename_len = real_filename_len;
|
||||||
if (filename_len >= buffer_maxlen) {
|
if (filename_len >= buffer_maxlen) {
|
||||||
filename_len = LIBSSH2_ERROR_BUFFER_TOO_SMALL;
|
filename_len = (size_t)LIBSSH2_ERROR_BUFFER_TOO_SMALL;
|
||||||
goto end;
|
goto end;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1624,7 +1633,7 @@ static ssize_t sftp_readdir(LIBSSH2_SFTP_HANDLE *handle, char *buffer,
|
|||||||
longentry_len = real_longentry_len;
|
longentry_len = real_longentry_len;
|
||||||
|
|
||||||
if (longentry_len >= longentry_maxlen) {
|
if (longentry_len >= longentry_maxlen) {
|
||||||
filename_len = LIBSSH2_ERROR_BUFFER_TOO_SMALL;
|
filename_len = (size_t)LIBSSH2_ERROR_BUFFER_TOO_SMALL;
|
||||||
goto end;
|
goto end;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1948,7 +1957,7 @@ static ssize_t sftp_write(LIBSSH2_SFTP_HANDLE *handle, const char *buffer,
|
|||||||
/* flush all pending packets from the outgoing list */
|
/* flush all pending packets from the outgoing list */
|
||||||
sftp_packetlist_flush(handle);
|
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
|
outstanding data acked, so we need to rewind the offset to
|
||||||
where the application knows it has reached with acked data */
|
where the application knows it has reached with acked data */
|
||||||
handle->u.file.offset -= handle->u.file.acked;
|
handle->u.file.offset -= handle->u.file.acked;
|
||||||
@@ -2007,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
|
* sftp_fstat
|
||||||
*
|
*
|
||||||
@@ -2125,21 +2227,24 @@ libssh2_sftp_fstat_ex(LIBSSH2_SFTP_HANDLE *hnd,
|
|||||||
LIBSSH2_API void
|
LIBSSH2_API void
|
||||||
libssh2_sftp_seek64(LIBSSH2_SFTP_HANDLE *handle, libssh2_uint64_t offset)
|
libssh2_sftp_seek64(LIBSSH2_SFTP_HANDLE *handle, libssh2_uint64_t offset)
|
||||||
{
|
{
|
||||||
if(handle) {
|
if(!handle)
|
||||||
handle->u.file.offset = handle->u.file.offset_sent = offset;
|
return;
|
||||||
/* discard all pending requests and currently read data */
|
if(handle->u.file.offset == offset && handle->u.file.offset_sent == offset)
|
||||||
sftp_packetlist_flush(handle);
|
return;
|
||||||
|
|
||||||
/* free the left received buffered data */
|
handle->u.file.offset = handle->u.file.offset_sent = offset;
|
||||||
if (handle->u.file.data_left) {
|
/* discard all pending requests and currently read data */
|
||||||
LIBSSH2_FREE(handle->sftp->channel->session, handle->u.file.data);
|
sftp_packetlist_flush(handle);
|
||||||
handle->u.file.data_left = handle->u.file.data_len = 0;
|
|
||||||
handle->u.file.data = NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* reset EOF to False */
|
/* free the left received buffered data */
|
||||||
handle->u.file.eof = FALSE;
|
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
|
/* libssh2_sftp_seek
|
||||||
@@ -2215,8 +2320,11 @@ static void sftp_packet_flush(LIBSSH2_SFTP *sftp)
|
|||||||
|
|
||||||
/* sftp_close_handle
|
/* sftp_close_handle
|
||||||
*
|
*
|
||||||
* Close a file or directory handle
|
* Close a file or directory handle.
|
||||||
* Also frees handle resource and unlinks it from the SFTP structure
|
* 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
|
static int
|
||||||
sftp_close_handle(LIBSSH2_SFTP_HANDLE *handle)
|
sftp_close_handle(LIBSSH2_SFTP_HANDLE *handle)
|
||||||
@@ -2225,27 +2333,28 @@ sftp_close_handle(LIBSSH2_SFTP_HANDLE *handle)
|
|||||||
LIBSSH2_CHANNEL *channel = sftp->channel;
|
LIBSSH2_CHANNEL *channel = sftp->channel;
|
||||||
LIBSSH2_SESSION *session = channel->session;
|
LIBSSH2_SESSION *session = channel->session;
|
||||||
size_t data_len;
|
size_t data_len;
|
||||||
int retcode;
|
|
||||||
/* 13 = packet_len(4) + packet_type(1) + request_id(4) + handle_len(4) */
|
/* 13 = packet_len(4) + packet_type(1) + request_id(4) + handle_len(4) */
|
||||||
uint32_t packet_len = handle->handle_len + 13;
|
uint32_t packet_len = handle->handle_len + 13;
|
||||||
unsigned char *s, *data = NULL;
|
unsigned char *s, *data = NULL;
|
||||||
int rc;
|
int rc = 0;
|
||||||
|
|
||||||
if (handle->close_state == libssh2_NB_state_idle) {
|
if (handle->close_state == libssh2_NB_state_idle) {
|
||||||
_libssh2_debug(session, LIBSSH2_TRACE_SFTP, "Closing handle");
|
_libssh2_debug(session, LIBSSH2_TRACE_SFTP, "Closing handle");
|
||||||
s = handle->close_packet = LIBSSH2_ALLOC(session, packet_len);
|
s = handle->close_packet = LIBSSH2_ALLOC(session, packet_len);
|
||||||
if (!handle->close_packet) {
|
if (!handle->close_packet) {
|
||||||
return _libssh2_error(session, LIBSSH2_ERROR_ALLOC,
|
handle->close_state = libssh2_NB_state_idle;
|
||||||
"Unable to allocate memory for FXP_CLOSE "
|
rc = _libssh2_error(session, LIBSSH2_ERROR_ALLOC,
|
||||||
"packet");
|
"Unable to allocate memory for FXP_CLOSE "
|
||||||
}
|
"packet");
|
||||||
|
} else {
|
||||||
|
|
||||||
_libssh2_store_u32(&s, packet_len - 4);
|
_libssh2_store_u32(&s, packet_len - 4);
|
||||||
*(s++) = SSH_FXP_CLOSE;
|
*(s++) = SSH_FXP_CLOSE;
|
||||||
handle->close_request_id = sftp->request_id++;
|
handle->close_request_id = sftp->request_id++;
|
||||||
_libssh2_store_u32(&s, handle->close_request_id);
|
_libssh2_store_u32(&s, handle->close_request_id);
|
||||||
_libssh2_store_str(&s, handle->handle, handle->handle_len);
|
_libssh2_store_str(&s, handle->handle, handle->handle_len);
|
||||||
handle->close_state = libssh2_NB_state_created;
|
handle->close_state = libssh2_NB_state_created;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (handle->close_state == libssh2_NB_state_created) {
|
if (handle->close_state == libssh2_NB_state_created) {
|
||||||
@@ -2254,16 +2363,14 @@ sftp_close_handle(LIBSSH2_SFTP_HANDLE *handle)
|
|||||||
if (rc == LIBSSH2_ERROR_EAGAIN) {
|
if (rc == LIBSSH2_ERROR_EAGAIN) {
|
||||||
return rc;
|
return rc;
|
||||||
} else if ((ssize_t)packet_len != 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;
|
handle->close_state = libssh2_NB_state_idle;
|
||||||
return _libssh2_error(session, LIBSSH2_ERROR_SOCKET_SEND,
|
rc = _libssh2_error(session, LIBSSH2_ERROR_SOCKET_SEND,
|
||||||
"Unable to send FXP_CLOSE command");
|
"Unable to send FXP_CLOSE command");
|
||||||
}
|
} else
|
||||||
|
handle->close_state = libssh2_NB_state_sent;
|
||||||
|
|
||||||
LIBSSH2_FREE(session, handle->close_packet);
|
LIBSSH2_FREE(session, handle->close_packet);
|
||||||
handle->close_packet = NULL;
|
handle->close_packet = NULL;
|
||||||
|
|
||||||
handle->close_state = libssh2_NB_state_sent;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (handle->close_state == libssh2_NB_state_sent) {
|
if (handle->close_state == libssh2_NB_state_sent) {
|
||||||
@@ -2272,29 +2379,30 @@ sftp_close_handle(LIBSSH2_SFTP_HANDLE *handle)
|
|||||||
&data_len);
|
&data_len);
|
||||||
if (rc == LIBSSH2_ERROR_EAGAIN) {
|
if (rc == LIBSSH2_ERROR_EAGAIN) {
|
||||||
return rc;
|
return rc;
|
||||||
|
|
||||||
} else if (rc) {
|
} else if (rc) {
|
||||||
handle->close_state = libssh2_NB_state_idle;
|
_libssh2_error(session, rc,
|
||||||
return _libssh2_error(session, rc,
|
"Error waiting for status message");
|
||||||
"Error waiting for status message");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
handle->close_state = libssh2_NB_state_sent1;
|
handle->close_state = libssh2_NB_state_sent1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(!data)
|
if(!data) {
|
||||||
/* if it reaches this point with data unset, something unwanted
|
/* if it reaches this point with data unset, something unwanted
|
||||||
happened (like this function is called again when in
|
happened for which we should have set an error code */
|
||||||
libssh2_NB_state_sent1 state) and we just bail out */
|
assert(rc);
|
||||||
return LIBSSH2_ERROR_INVAL;
|
|
||||||
|
|
||||||
retcode = _libssh2_ntohu32(data + 5);
|
} else {
|
||||||
LIBSSH2_FREE(session, data);
|
int retcode = _libssh2_ntohu32(data + 5);
|
||||||
|
LIBSSH2_FREE(session, data);
|
||||||
|
|
||||||
if (retcode != LIBSSH2_FX_OK) {
|
if (retcode != LIBSSH2_FX_OK) {
|
||||||
sftp->last_errno = retcode;
|
sftp->last_errno = retcode;
|
||||||
handle->close_state = libssh2_NB_state_idle;
|
handle->close_state = libssh2_NB_state_idle;
|
||||||
return _libssh2_error(session, LIBSSH2_ERROR_SFTP_PROTOCOL,
|
rc = _libssh2_error(session, LIBSSH2_ERROR_SFTP_PROTOCOL,
|
||||||
"SFTP Protocol Error");
|
"SFTP Protocol Error");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* remove this handle from the parent's list */
|
/* remove this handle from the parent's list */
|
||||||
@@ -2316,7 +2424,7 @@ sftp_close_handle(LIBSSH2_SFTP_HANDLE *handle)
|
|||||||
|
|
||||||
LIBSSH2_FREE(session, handle);
|
LIBSSH2_FREE(session, handle);
|
||||||
|
|
||||||
return 0;
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* libssh2_sftp_close_handle
|
/* libssh2_sftp_close_handle
|
||||||
@@ -2576,6 +2684,8 @@ static int sftp_fstatvfs(LIBSSH2_SFTP_HANDLE *handle, LIBSSH2_SFTP_STATVFS *st)
|
|||||||
unsigned char *packet, *s, *data;
|
unsigned char *packet, *s, *data;
|
||||||
ssize_t rc;
|
ssize_t rc;
|
||||||
unsigned int flag;
|
unsigned int flag;
|
||||||
|
static const unsigned char responses[2] =
|
||||||
|
{ SSH_FXP_EXTENDED_REPLY, SSH_FXP_STATUS };
|
||||||
|
|
||||||
if (sftp->fstatvfs_state == libssh2_NB_state_idle) {
|
if (sftp->fstatvfs_state == libssh2_NB_state_idle) {
|
||||||
_libssh2_debug(session, LIBSSH2_TRACE_SFTP,
|
_libssh2_debug(session, LIBSSH2_TRACE_SFTP,
|
||||||
@@ -2619,15 +2729,27 @@ static int sftp_fstatvfs(LIBSSH2_SFTP_HANDLE *handle, LIBSSH2_SFTP_STATVFS *st)
|
|||||||
sftp->fstatvfs_state = libssh2_NB_state_sent;
|
sftp->fstatvfs_state = libssh2_NB_state_sent;
|
||||||
}
|
}
|
||||||
|
|
||||||
rc = sftp_packet_require(sftp, SSH_FXP_EXTENDED_REPLY,
|
rc = sftp_packet_requirev(sftp, 2, responses, sftp->fstatvfs_request_id,
|
||||||
sftp->fstatvfs_request_id, &data, &data_len);
|
&data, &data_len);
|
||||||
|
|
||||||
if (rc == LIBSSH2_ERROR_EAGAIN) {
|
if (rc == LIBSSH2_ERROR_EAGAIN) {
|
||||||
return rc;
|
return rc;
|
||||||
} else if (rc) {
|
} else if (rc) {
|
||||||
sftp->fstatvfs_state = libssh2_NB_state_idle;
|
sftp->fstatvfs_state = libssh2_NB_state_idle;
|
||||||
return _libssh2_error(session, rc,
|
return _libssh2_error(session, rc,
|
||||||
"Error waiting for FXP EXTENDED REPLY");
|
"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);
|
LIBSSH2_FREE(session, data);
|
||||||
sftp->fstatvfs_state = libssh2_NB_state_idle;
|
sftp->fstatvfs_state = libssh2_NB_state_idle;
|
||||||
return _libssh2_error(session, LIBSSH2_ERROR_SFTP_PROTOCOL,
|
return _libssh2_error(session, LIBSSH2_ERROR_SFTP_PROTOCOL,
|
||||||
@@ -2649,9 +2771,9 @@ static int sftp_fstatvfs(LIBSSH2_SFTP_HANDLE *handle, LIBSSH2_SFTP_STATVFS *st)
|
|||||||
st->f_namemax = _libssh2_ntohu64(data + 85);
|
st->f_namemax = _libssh2_ntohu64(data + 85);
|
||||||
|
|
||||||
st->f_flag = (flag & SSH_FXE_STATVFS_ST_RDONLY)
|
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)
|
st->f_flag |= (flag & SSH_FXE_STATVFS_ST_NOSUID)
|
||||||
? LIBSSH2_SFTP_ST_NOSUID : 0;
|
? LIBSSH2_SFTP_ST_NOSUID : 0;
|
||||||
|
|
||||||
LIBSSH2_FREE(session, data);
|
LIBSSH2_FREE(session, data);
|
||||||
return 0;
|
return 0;
|
||||||
@@ -2689,6 +2811,8 @@ static int sftp_statvfs(LIBSSH2_SFTP *sftp, const char *path,
|
|||||||
unsigned char *packet, *s, *data;
|
unsigned char *packet, *s, *data;
|
||||||
ssize_t rc;
|
ssize_t rc;
|
||||||
unsigned int flag;
|
unsigned int flag;
|
||||||
|
static const unsigned char responses[2] =
|
||||||
|
{ SSH_FXP_EXTENDED_REPLY, SSH_FXP_STATUS };
|
||||||
|
|
||||||
if (sftp->statvfs_state == libssh2_NB_state_idle) {
|
if (sftp->statvfs_state == libssh2_NB_state_idle) {
|
||||||
_libssh2_debug(session, LIBSSH2_TRACE_SFTP,
|
_libssh2_debug(session, LIBSSH2_TRACE_SFTP,
|
||||||
@@ -2732,17 +2856,28 @@ static int sftp_statvfs(LIBSSH2_SFTP *sftp, const char *path,
|
|||||||
sftp->statvfs_state = libssh2_NB_state_sent;
|
sftp->statvfs_state = libssh2_NB_state_sent;
|
||||||
}
|
}
|
||||||
|
|
||||||
rc = sftp_packet_require(sftp, SSH_FXP_EXTENDED_REPLY,
|
rc = sftp_packet_requirev(sftp, 2, responses, sftp->statvfs_request_id,
|
||||||
sftp->statvfs_request_id, &data, &data_len);
|
&data, &data_len);
|
||||||
if (rc == LIBSSH2_ERROR_EAGAIN) {
|
if (rc == LIBSSH2_ERROR_EAGAIN) {
|
||||||
return rc;
|
return rc;
|
||||||
} else if (rc) {
|
} else if (rc) {
|
||||||
sftp->statvfs_state = libssh2_NB_state_idle;
|
sftp->statvfs_state = libssh2_NB_state_idle;
|
||||||
return _libssh2_error(session, rc,
|
return _libssh2_error(session, rc,
|
||||||
"Error waiting for FXP EXTENDED REPLY");
|
"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);
|
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,
|
return _libssh2_error(session, LIBSSH2_ERROR_SFTP_PROTOCOL,
|
||||||
"SFTP Protocol Error: short response");
|
"SFTP Protocol Error: short response");
|
||||||
}
|
}
|
||||||
|
@@ -175,6 +175,11 @@ struct _LIBSSH2_SFTP
|
|||||||
/* State variable used in sftp_write() */
|
/* State variable used in sftp_write() */
|
||||||
libssh2_nonblocking_states write_state;
|
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() */
|
/* State variables used in libssh2_sftp_readdir() */
|
||||||
libssh2_nonblocking_states readdir_state;
|
libssh2_nonblocking_states readdir_state;
|
||||||
unsigned char *readdir_packet;
|
unsigned char *readdir_packet;
|
||||||
|
@@ -139,7 +139,7 @@ decrypt(LIBSSH2_SESSION * session, unsigned char *source,
|
|||||||
assert((len % blocksize) == 0);
|
assert((len % blocksize) == 0);
|
||||||
|
|
||||||
while (len >= blocksize) {
|
while (len >= blocksize) {
|
||||||
if (session->remote.crypt->crypt(session, source,
|
if (session->remote.crypt->crypt(session, source, blocksize,
|
||||||
&session->remote.crypt_abstract)) {
|
&session->remote.crypt_abstract)) {
|
||||||
LIBSSH2_FREE(session, p->payload);
|
LIBSSH2_FREE(session, p->payload);
|
||||||
return LIBSSH2_ERROR_DECRYPT;
|
return LIBSSH2_ERROR_DECRYPT;
|
||||||
@@ -167,6 +167,7 @@ fullpacket(LIBSSH2_SESSION * session, int encrypted /* 1 or 0 */ )
|
|||||||
unsigned char macbuf[MAX_MACSIZE];
|
unsigned char macbuf[MAX_MACSIZE];
|
||||||
struct transportpacket *p = &session->packet;
|
struct transportpacket *p = &session->packet;
|
||||||
int rc;
|
int rc;
|
||||||
|
int compressed;
|
||||||
|
|
||||||
if (session->fullpacket_state == libssh2_NB_state_idle) {
|
if (session->fullpacket_state == libssh2_NB_state_idle) {
|
||||||
session->fullpacket_macstate = LIBSSH2_MAC_CONFIRMED;
|
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;
|
session->fullpacket_payload_len -= p->padding_length;
|
||||||
|
|
||||||
/* Check for and deal with decompression */
|
/* Check for and deal with decompression */
|
||||||
if (session->remote.comp &&
|
compressed =
|
||||||
session->remote.comp->compress &&
|
session->local.comp != NULL &&
|
||||||
session->remote.comp_abstract) {
|
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
|
* The buffer for the decompression (remote.comp_abstract) is
|
||||||
* initialised in time when it is needed so as long it is NULL we
|
* 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,
|
rc = _libssh2_packet_add(session, p->payload,
|
||||||
session->fullpacket_payload_len,
|
session->fullpacket_payload_len,
|
||||||
session->fullpacket_macstate);
|
session->fullpacket_macstate);
|
||||||
if (rc)
|
if (rc == LIBSSH2_ERROR_EAGAIN)
|
||||||
return rc;
|
return rc;
|
||||||
|
if (rc) {
|
||||||
|
session->fullpacket_state = libssh2_NB_state_idle;
|
||||||
|
return rc;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
session->fullpacket_state = libssh2_NB_state_idle;
|
session->fullpacket_state = libssh2_NB_state_idle;
|
||||||
@@ -519,6 +528,7 @@ int _libssh2_transport_read(LIBSSH2_SESSION * session)
|
|||||||
/* now decrypt the lot */
|
/* now decrypt the lot */
|
||||||
rc = decrypt(session, &p->buf[p->readidx], p->wptr, numdecrypt);
|
rc = decrypt(session, &p->buf[p->readidx], p->wptr, numdecrypt);
|
||||||
if (rc != LIBSSH2_ERROR_NONE) {
|
if (rc != LIBSSH2_ERROR_NONE) {
|
||||||
|
p->total_num = 0; /* no packet buffer available */
|
||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -526,7 +536,7 @@ int _libssh2_transport_read(LIBSSH2_SESSION * session)
|
|||||||
p->readidx += numdecrypt;
|
p->readidx += numdecrypt;
|
||||||
/* advance write pointer */
|
/* advance write pointer */
|
||||||
p->wptr += numdecrypt;
|
p->wptr += numdecrypt;
|
||||||
/* increse data_num */
|
/* increase data_num */
|
||||||
p->data_num += numdecrypt;
|
p->data_num += numdecrypt;
|
||||||
|
|
||||||
/* bytes left to take care of without decryption */
|
/* bytes left to take care of without decryption */
|
||||||
@@ -542,7 +552,7 @@ int _libssh2_transport_read(LIBSSH2_SESSION * session)
|
|||||||
p->readidx += numbytes;
|
p->readidx += numbytes;
|
||||||
/* advance write pointer */
|
/* advance write pointer */
|
||||||
p->wptr += numbytes;
|
p->wptr += numbytes;
|
||||||
/* increse data_num */
|
/* increase data_num */
|
||||||
p->data_num += numbytes;
|
p->data_num += numbytes;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -682,6 +692,7 @@ int _libssh2_transport_send(LIBSSH2_SESSION *session,
|
|||||||
#endif
|
#endif
|
||||||
struct transportpacket *p = &session->packet;
|
struct transportpacket *p = &session->packet;
|
||||||
int encrypted;
|
int encrypted;
|
||||||
|
int compressed;
|
||||||
ssize_t ret;
|
ssize_t ret;
|
||||||
int rc;
|
int rc;
|
||||||
const unsigned char *orgdata = data;
|
const unsigned char *orgdata = data;
|
||||||
@@ -723,7 +734,13 @@ int _libssh2_transport_send(LIBSSH2_SESSION *session,
|
|||||||
|
|
||||||
encrypted = (session->state & LIBSSH2_STATE_NEWKEYS) ? 1 : 0;
|
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
|
/* 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
|
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 */
|
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 */
|
the MAC and the packet_length field itself */
|
||||||
_libssh2_htonu32(p->outbuf, packet_length - 4);
|
_libssh2_htonu32(p->outbuf, packet_length - 4);
|
||||||
/* store padding_length */
|
/* store padding_length */
|
||||||
p->outbuf[4] = padding_length;
|
p->outbuf[4] = (unsigned char)padding_length;
|
||||||
|
|
||||||
/* fill the padding area with random junk */
|
/* fill the padding area with random junk */
|
||||||
_libssh2_random(p->outbuf + 5 + data_len, padding_length);
|
_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) {
|
for(i = 0; i < packet_length; i += session->local.crypt->blocksize) {
|
||||||
unsigned char *ptr = &p->outbuf[i];
|
unsigned char *ptr = &p->outbuf[i];
|
||||||
if (session->local.crypt->crypt(session, ptr,
|
if (session->local.crypt->crypt(session, ptr,
|
||||||
|
session->local.crypt->blocksize,
|
||||||
&session->local.crypt_abstract))
|
&session->local.crypt_abstract))
|
||||||
return LIBSSH2_ERROR_ENCRYPT; /* encryption failure */
|
return LIBSSH2_ERROR_ENCRYPT; /* encryption failure */
|
||||||
}
|
}
|
||||||
|
@@ -1,6 +1,6 @@
|
|||||||
/* Copyright (c) 2004-2007, Sara Golemon <sarag@libssh2.org>
|
/* Copyright (c) 2004-2007, Sara Golemon <sarag@libssh2.org>
|
||||||
* Copyright (c) 2005 Mikhail Gusarov <dottedmag@dottedmag.net>
|
* 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.
|
* All rights reserved.
|
||||||
*
|
*
|
||||||
* Redistribution and use in source and binary forms,
|
* Redistribution and use in source and binary forms,
|
||||||
@@ -211,12 +211,13 @@ userauth_password(LIBSSH2_SESSION *session,
|
|||||||
sizeof(session->userauth_pswd_packet_requirev_state));
|
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" +
|
* service(14)"ssh-connection" + method_len(4) + method(8)"password" +
|
||||||
* chgpwdbool(1) + password_len(4) */
|
* chgpwdbool(1) + password_len(4) */
|
||||||
session->userauth_pswd_data_len = username_len + 40;
|
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
|
/* TODO: remove this alloc with a fixed buffer in the session
|
||||||
struct */
|
struct */
|
||||||
@@ -276,13 +277,13 @@ userauth_password(LIBSSH2_SESSION *session,
|
|||||||
0, NULL, 0,
|
0, NULL, 0,
|
||||||
&session->
|
&session->
|
||||||
userauth_pswd_packet_requirev_state);
|
userauth_pswd_packet_requirev_state);
|
||||||
if (rc == LIBSSH2_ERROR_EAGAIN) {
|
|
||||||
return _libssh2_error(session, LIBSSH2_ERROR_EAGAIN,
|
if (rc) {
|
||||||
"Would block waiting");
|
if (rc != LIBSSH2_ERROR_EAGAIN)
|
||||||
} else if (rc) {
|
session->userauth_pswd_state = libssh2_NB_state_idle;
|
||||||
session->userauth_pswd_state = libssh2_NB_state_idle;
|
|
||||||
return _libssh2_error(session, LIBSSH2_ERROR_TIMEOUT,
|
return _libssh2_error(session, rc,
|
||||||
"Would block waiting");
|
"Waiting for password response");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (session->userauth_pswd_data[0] == SSH_MSG_USERAUTH_SUCCESS) {
|
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;
|
FILE *fd;
|
||||||
char c;
|
char c;
|
||||||
unsigned char *pubkey = NULL, *sp1, *sp2, *tmp;
|
unsigned char *pubkey = NULL, *sp1, *sp2, *tmp;
|
||||||
size_t pubkey_len = 0;
|
size_t pubkey_len = 0, sp_len;
|
||||||
unsigned int tmp_len;
|
unsigned int tmp_len;
|
||||||
|
|
||||||
_libssh2_debug(session, LIBSSH2_TRACE_AUTH, "Loading public key file: %s",
|
_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,
|
return _libssh2_error(session, LIBSSH2_ERROR_FILE,
|
||||||
"Unable to open public key file");
|
"Unable to open public key file");
|
||||||
}
|
}
|
||||||
while (!feof(fd) && 1 == fread(&c, 1, 1, fd) && c != '\r' && c != '\n')
|
while (!feof(fd) && 1 == fread(&c, 1, 1, fd) && c != '\r' && c != '\n') {
|
||||||
pubkey_len++;
|
pubkey_len++;
|
||||||
|
}
|
||||||
if (feof(fd)) {
|
if (feof(fd)) {
|
||||||
/* the last character was EOF */
|
/* the last character was EOF */
|
||||||
pubkey_len--;
|
pubkey_len--;
|
||||||
@@ -502,8 +504,9 @@ file_read_publickey(LIBSSH2_SESSION * session, unsigned char **method,
|
|||||||
/*
|
/*
|
||||||
* Remove trailing whitespace
|
* Remove trailing whitespace
|
||||||
*/
|
*/
|
||||||
while (pubkey_len && isspace(pubkey[pubkey_len - 1]))
|
while (pubkey_len && isspace(pubkey[pubkey_len - 1])) {
|
||||||
pubkey_len--;
|
pubkey_len--;
|
||||||
|
}
|
||||||
|
|
||||||
if (!pubkey_len) {
|
if (!pubkey_len) {
|
||||||
LIBSSH2_FREE(session, pubkey);
|
LIBSSH2_FREE(session, pubkey);
|
||||||
@@ -519,7 +522,8 @@ file_read_publickey(LIBSSH2_SESSION * session, unsigned char **method,
|
|||||||
|
|
||||||
sp1++;
|
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 */
|
/* Assume that the id string is missing, but that it's okay */
|
||||||
sp2 = pubkey + pubkey_len;
|
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,
|
if (privkeyobj->signv(session, sig, sig_len, 1, &datavec,
|
||||||
&hostkey_abstract)) {
|
&hostkey_abstract)) {
|
||||||
if (privkeyobj->dtor) {
|
if (privkeyobj->dtor) {
|
||||||
privkeyobj->dtor(session, abstract);
|
privkeyobj->dtor(session, &hostkey_abstract);
|
||||||
}
|
}
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
@@ -645,7 +649,7 @@ userauth_hostbased_fromfile(LIBSSH2_SESSION *session,
|
|||||||
if (session->userauth_host_state == libssh2_NB_state_idle) {
|
if (session->userauth_host_state == libssh2_NB_state_idle) {
|
||||||
const LIBSSH2_HOSTKEY_METHOD *privkeyobj;
|
const LIBSSH2_HOSTKEY_METHOD *privkeyobj;
|
||||||
unsigned char *pubkeydata, *sig;
|
unsigned char *pubkeydata, *sig;
|
||||||
size_t pubkeydata_len;
|
size_t pubkeydata_len = 0;
|
||||||
size_t sig_len;
|
size_t sig_len;
|
||||||
void *abstract;
|
void *abstract;
|
||||||
unsigned char buf[5];
|
unsigned char buf[5];
|
||||||
@@ -1501,49 +1505,41 @@ userauth_keyboard_interactive(LIBSSH2_SESSION * session,
|
|||||||
|
|
||||||
if(session->userauth_kybd_num_prompts) {
|
if(session->userauth_kybd_num_prompts) {
|
||||||
session->userauth_kybd_prompts =
|
session->userauth_kybd_prompts =
|
||||||
LIBSSH2_ALLOC(session,
|
LIBSSH2_CALLOC(session,
|
||||||
sizeof(LIBSSH2_USERAUTH_KBDINT_PROMPT) *
|
sizeof(LIBSSH2_USERAUTH_KBDINT_PROMPT) *
|
||||||
session->userauth_kybd_num_prompts);
|
session->userauth_kybd_num_prompts);
|
||||||
if (!session->userauth_kybd_prompts) {
|
if (!session->userauth_kybd_prompts) {
|
||||||
_libssh2_error(session, LIBSSH2_ERROR_ALLOC,
|
_libssh2_error(session, LIBSSH2_ERROR_ALLOC,
|
||||||
"Unable to allocate memory for "
|
"Unable to allocate memory for "
|
||||||
"keyboard-interactive prompts array");
|
"keyboard-interactive prompts array");
|
||||||
goto cleanup;
|
goto cleanup;
|
||||||
}
|
}
|
||||||
memset(session->userauth_kybd_prompts, 0,
|
|
||||||
sizeof(LIBSSH2_USERAUTH_KBDINT_PROMPT) *
|
|
||||||
session->userauth_kybd_num_prompts);
|
|
||||||
|
|
||||||
session->userauth_kybd_responses =
|
session->userauth_kybd_responses =
|
||||||
LIBSSH2_ALLOC(session,
|
LIBSSH2_CALLOC(session,
|
||||||
sizeof(LIBSSH2_USERAUTH_KBDINT_RESPONSE) *
|
sizeof(LIBSSH2_USERAUTH_KBDINT_RESPONSE) *
|
||||||
session->userauth_kybd_num_prompts);
|
session->userauth_kybd_num_prompts);
|
||||||
if (!session->userauth_kybd_responses) {
|
if (!session->userauth_kybd_responses) {
|
||||||
_libssh2_error(session, LIBSSH2_ERROR_ALLOC,
|
_libssh2_error(session, LIBSSH2_ERROR_ALLOC,
|
||||||
"Unable to allocate memory for "
|
"Unable to allocate memory for "
|
||||||
"keyboard-interactive responses array");
|
"keyboard-interactive responses array");
|
||||||
goto cleanup;
|
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) */
|
/* string prompt[1] (ISO-10646 UTF-8) */
|
||||||
session->userauth_kybd_prompts[i].length =
|
session->userauth_kybd_prompts[i].length =
|
||||||
_libssh2_ntohu32(s);
|
_libssh2_ntohu32(s);
|
||||||
s += 4;
|
s += 4;
|
||||||
session->userauth_kybd_prompts[i].text =
|
session->userauth_kybd_prompts[i].text =
|
||||||
LIBSSH2_ALLOC(session,
|
LIBSSH2_CALLOC(session,
|
||||||
session->userauth_kybd_prompts[i].length);
|
session->userauth_kybd_prompts[i].length);
|
||||||
if (!session->userauth_kybd_prompts[i].text) {
|
if (!session->userauth_kybd_prompts[i].text) {
|
||||||
_libssh2_error(session, LIBSSH2_ERROR_ALLOC,
|
_libssh2_error(session, LIBSSH2_ERROR_ALLOC,
|
||||||
"Unable to allocate memory for "
|
"Unable to allocate memory for "
|
||||||
"keyboard-interactive prompt message");
|
"keyboard-interactive prompt message");
|
||||||
goto cleanup;
|
goto cleanup;
|
||||||
}
|
}
|
||||||
memcpy(session->userauth_kybd_prompts[i].text, s,
|
|
||||||
session->userauth_kybd_prompts[i].length);
|
|
||||||
s += session->userauth_kybd_prompts[i].length;
|
s += session->userauth_kybd_prompts[i].length;
|
||||||
|
|
||||||
/* boolean echo[1] */
|
/* boolean echo[1] */
|
||||||
@@ -1569,7 +1565,7 @@ userauth_keyboard_interactive(LIBSSH2_SESSION * session,
|
|||||||
+ 4 /* int num-responses */
|
+ 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) */
|
/* string response[1] (ISO-10646 UTF-8) */
|
||||||
session->userauth_kybd_packet_len +=
|
session->userauth_kybd_packet_len +=
|
||||||
4 + session->userauth_kybd_responses[i].length;
|
4 + session->userauth_kybd_responses[i].length;
|
||||||
@@ -1592,7 +1588,7 @@ userauth_keyboard_interactive(LIBSSH2_SESSION * session,
|
|||||||
s++;
|
s++;
|
||||||
_libssh2_store_u32(&s, session->userauth_kybd_num_prompts);
|
_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,
|
_libssh2_store_str(&s,
|
||||||
session->userauth_kybd_responses[i].text,
|
session->userauth_kybd_responses[i].text,
|
||||||
session->userauth_kybd_responses[i].length);
|
session->userauth_kybd_responses[i].length);
|
||||||
@@ -1628,14 +1624,14 @@ userauth_keyboard_interactive(LIBSSH2_SESSION * session,
|
|||||||
session->userauth_kybd_data = NULL;
|
session->userauth_kybd_data = NULL;
|
||||||
|
|
||||||
if (session->userauth_kybd_prompts) {
|
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);
|
LIBSSH2_FREE(session, session->userauth_kybd_prompts[i].text);
|
||||||
session->userauth_kybd_prompts[i].text = NULL;
|
session->userauth_kybd_prompts[i].text = NULL;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (session->userauth_kybd_responses) {
|
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,
|
LIBSSH2_FREE(session,
|
||||||
session->userauth_kybd_responses[i].text);
|
session->userauth_kybd_responses[i].text);
|
||||||
session->userauth_kybd_responses[i].text = NULL;
|
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
475
src/wincng.h
Normal file
475
src/wincng.h
Normal file
@@ -0,0 +1,475 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2013-2014 Marc Hoersken <info@marc-hoersken.de>
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms,
|
||||||
|
* with or without modification, are permitted provided
|
||||||
|
* that the following conditions are met:
|
||||||
|
*
|
||||||
|
* Redistributions of source code must retain the above
|
||||||
|
* copyright notice, this list of conditions and the
|
||||||
|
* following disclaimer.
|
||||||
|
*
|
||||||
|
* Redistributions in binary form must reproduce the above
|
||||||
|
* copyright notice, this list of conditions and the following
|
||||||
|
* disclaimer in the documentation and/or other materials
|
||||||
|
* provided with the distribution.
|
||||||
|
*
|
||||||
|
* Neither the name of the copyright holder nor the names
|
||||||
|
* of any other contributors may be used to endorse or
|
||||||
|
* promote products derived from this software without
|
||||||
|
* specific prior written permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
|
||||||
|
* CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
|
||||||
|
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||||
|
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||||
|
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
|
||||||
|
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||||
|
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||||
|
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||||
|
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||||
|
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||||
|
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||||
|
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
|
||||||
|
* USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
|
||||||
|
* OF SUCH DAMAGE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* required for cross-compilation against the w64 mingw-runtime package */
|
||||||
|
#if defined(_WIN32_WINNT) && (_WIN32_WINNT < 0x0600)
|
||||||
|
#undef _WIN32_WINNT
|
||||||
|
#endif
|
||||||
|
#ifndef _WIN32_WINNT
|
||||||
|
#define _WIN32_WINNT 0x0600
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include <windows.h>
|
||||||
|
#include <bcrypt.h>
|
||||||
|
|
||||||
|
|
||||||
|
#define LIBSSH2_MD5 1
|
||||||
|
|
||||||
|
#define LIBSSH2_HMAC_RIPEMD 0
|
||||||
|
|
||||||
|
#define LIBSSH2_AES 1
|
||||||
|
#define LIBSSH2_AES_CTR 0
|
||||||
|
#define LIBSSH2_BLOWFISH 0
|
||||||
|
#define LIBSSH2_RC4 1
|
||||||
|
#define LIBSSH2_CAST 0
|
||||||
|
#define LIBSSH2_3DES 1
|
||||||
|
|
||||||
|
#define LIBSSH2_RSA 1
|
||||||
|
#define LIBSSH2_DSA 1
|
||||||
|
|
||||||
|
#define MD5_DIGEST_LENGTH 16
|
||||||
|
#define SHA_DIGEST_LENGTH 20
|
||||||
|
|
||||||
|
|
||||||
|
/*******************************************************************/
|
||||||
|
/*
|
||||||
|
* Windows CNG backend: Global context handles
|
||||||
|
*/
|
||||||
|
|
||||||
|
struct _libssh2_wincng_ctx {
|
||||||
|
BCRYPT_ALG_HANDLE hAlgRNG;
|
||||||
|
BCRYPT_ALG_HANDLE hAlgHashMD5;
|
||||||
|
BCRYPT_ALG_HANDLE hAlgHashSHA1;
|
||||||
|
BCRYPT_ALG_HANDLE hAlgHmacMD5;
|
||||||
|
BCRYPT_ALG_HANDLE hAlgHmacSHA1;
|
||||||
|
BCRYPT_ALG_HANDLE hAlgRSA;
|
||||||
|
BCRYPT_ALG_HANDLE hAlgDSA;
|
||||||
|
BCRYPT_ALG_HANDLE hAlgAES_CBC;
|
||||||
|
BCRYPT_ALG_HANDLE hAlgRC4_NA;
|
||||||
|
BCRYPT_ALG_HANDLE hAlg3DES_CBC;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct _libssh2_wincng_ctx _libssh2_wincng;
|
||||||
|
|
||||||
|
|
||||||
|
/*******************************************************************/
|
||||||
|
/*
|
||||||
|
* Windows CNG backend: Generic functions
|
||||||
|
*/
|
||||||
|
|
||||||
|
void _libssh2_wincng_init(void);
|
||||||
|
void _libssh2_wincng_free(void);
|
||||||
|
|
||||||
|
#define libssh2_crypto_init() \
|
||||||
|
_libssh2_wincng_init()
|
||||||
|
#define libssh2_crypto_exit() \
|
||||||
|
_libssh2_wincng_free()
|
||||||
|
|
||||||
|
#define _libssh2_random(buf, len) \
|
||||||
|
_libssh2_wincng_random(buf, len)
|
||||||
|
|
||||||
|
|
||||||
|
/*******************************************************************/
|
||||||
|
/*
|
||||||
|
* Windows CNG backend: Hash structure
|
||||||
|
*/
|
||||||
|
|
||||||
|
typedef struct __libssh2_wincng_hash_ctx {
|
||||||
|
BCRYPT_HASH_HANDLE hHash;
|
||||||
|
unsigned char *pbHashObject;
|
||||||
|
unsigned long dwHashObject;
|
||||||
|
unsigned long cbHash;
|
||||||
|
} _libssh2_wincng_hash_ctx;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Windows CNG backend: Hash functions
|
||||||
|
*/
|
||||||
|
|
||||||
|
#define libssh2_sha1_ctx _libssh2_wincng_hash_ctx
|
||||||
|
#define libssh2_sha1_init(ctx) \
|
||||||
|
_libssh2_wincng_hash_init(ctx, _libssh2_wincng.hAlgHashSHA1, \
|
||||||
|
SHA_DIGEST_LENGTH, NULL, 0)
|
||||||
|
#define libssh2_sha1_update(ctx, data, datalen) \
|
||||||
|
_libssh2_wincng_hash_update(&ctx, (unsigned char *) data, datalen)
|
||||||
|
#define libssh2_sha1_final(ctx, hash) \
|
||||||
|
_libssh2_wincng_hash_final(&ctx, hash)
|
||||||
|
#define libssh2_sha1(data, datalen, hash) \
|
||||||
|
_libssh2_wincng_hash(data, datalen, _libssh2_wincng.hAlgHashSHA1, \
|
||||||
|
hash, SHA_DIGEST_LENGTH)
|
||||||
|
|
||||||
|
#define libssh2_md5_ctx _libssh2_wincng_hash_ctx
|
||||||
|
#define libssh2_md5_init(ctx) \
|
||||||
|
_libssh2_wincng_hash_init(ctx, _libssh2_wincng.hAlgHashMD5, \
|
||||||
|
MD5_DIGEST_LENGTH, NULL, 0)
|
||||||
|
#define libssh2_md5_update(ctx, data, datalen) \
|
||||||
|
_libssh2_wincng_hash_update(&ctx, (unsigned char *) data, datalen)
|
||||||
|
#define libssh2_md5_final(ctx, hash) \
|
||||||
|
_libssh2_wincng_hash_final(&ctx, hash)
|
||||||
|
#define libssh2_md5(data, datalen, hash) \
|
||||||
|
_libssh2_wincng_hash(data, datalen, _libssh2_wincng.hAlgHashMD5, \
|
||||||
|
hash, MD5_DIGEST_LENGTH)
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Windows CNG backend: HMAC functions
|
||||||
|
*/
|
||||||
|
|
||||||
|
#define libssh2_hmac_ctx _libssh2_wincng_hash_ctx
|
||||||
|
#define libssh2_hmac_sha1_init(ctx, key, keylen) \
|
||||||
|
_libssh2_wincng_hash_init(ctx, _libssh2_wincng.hAlgHmacSHA1, \
|
||||||
|
SHA_DIGEST_LENGTH, key, keylen)
|
||||||
|
#define libssh2_hmac_md5_init(ctx, key, keylen) \
|
||||||
|
_libssh2_wincng_hash_init(ctx, _libssh2_wincng.hAlgHmacMD5, \
|
||||||
|
MD5_DIGEST_LENGTH, key, keylen)
|
||||||
|
#define libssh2_hmac_ripemd160_init(ctx, key, keylen)
|
||||||
|
/* not implemented */
|
||||||
|
#define libssh2_hmac_update(ctx, data, datalen) \
|
||||||
|
_libssh2_wincng_hash_update(&ctx, (unsigned char *) data, datalen)
|
||||||
|
#define libssh2_hmac_final(ctx, hash) \
|
||||||
|
_libssh2_wincng_hmac_final(&ctx, hash)
|
||||||
|
#define libssh2_hmac_cleanup(ctx) \
|
||||||
|
_libssh2_wincng_hmac_cleanup(ctx)
|
||||||
|
|
||||||
|
|
||||||
|
/*******************************************************************/
|
||||||
|
/*
|
||||||
|
* Windows CNG backend: Key Context structure
|
||||||
|
*/
|
||||||
|
|
||||||
|
typedef struct __libssh2_wincng_key_ctx {
|
||||||
|
BCRYPT_KEY_HANDLE hKey;
|
||||||
|
unsigned char *pbKeyObject;
|
||||||
|
unsigned long cbKeyObject;
|
||||||
|
} _libssh2_wincng_key_ctx;
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Windows CNG backend: RSA functions
|
||||||
|
*/
|
||||||
|
|
||||||
|
#define libssh2_rsa_ctx _libssh2_wincng_key_ctx
|
||||||
|
#define _libssh2_rsa_new(rsactx, e, e_len, n, n_len, \
|
||||||
|
d, d_len, p, p_len, q, q_len, \
|
||||||
|
e1, e1_len, e2, e2_len, c, c_len) \
|
||||||
|
_libssh2_wincng_rsa_new(rsactx, e, e_len, n, n_len, \
|
||||||
|
d, d_len, p, p_len, q, q_len, \
|
||||||
|
e1, e1_len, e2, e2_len, c, c_len)
|
||||||
|
#define _libssh2_rsa_new_private(rsactx, s, filename, passphrase) \
|
||||||
|
_libssh2_wincng_rsa_new_private(rsactx, s, filename, passphrase)
|
||||||
|
#define _libssh2_rsa_sha1_sign(s, rsactx, hash, hash_len, sig, sig_len) \
|
||||||
|
_libssh2_wincng_rsa_sha1_sign(s, rsactx, hash, hash_len, sig, sig_len)
|
||||||
|
#define _libssh2_rsa_sha1_verify(rsactx, sig, sig_len, m, m_len) \
|
||||||
|
_libssh2_wincng_rsa_sha1_verify(rsactx, sig, sig_len, m, m_len)
|
||||||
|
#define _libssh2_rsa_free(rsactx) \
|
||||||
|
_libssh2_wincng_rsa_free(rsactx)
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Windows CNG backend: DSA functions
|
||||||
|
*/
|
||||||
|
|
||||||
|
#define libssh2_dsa_ctx _libssh2_wincng_key_ctx
|
||||||
|
#define _libssh2_dsa_new(dsactx, p, p_len, q, q_len, \
|
||||||
|
g, g_len, y, y_len, x, x_len) \
|
||||||
|
_libssh2_wincng_dsa_new(dsactx, p, p_len, q, q_len, \
|
||||||
|
g, g_len, y, y_len, x, x_len)
|
||||||
|
#define _libssh2_dsa_new_private(rsactx, s, filename, passphrase) \
|
||||||
|
_libssh2_wincng_dsa_new_private(rsactx, s, filename, passphrase)
|
||||||
|
#define _libssh2_dsa_sha1_sign(dsactx, hash, hash_len, sig) \
|
||||||
|
_libssh2_wincng_dsa_sha1_sign(dsactx, hash, hash_len, sig)
|
||||||
|
#define _libssh2_dsa_sha1_verify(dsactx, sig, m, m_len) \
|
||||||
|
_libssh2_wincng_dsa_sha1_verify(dsactx, sig, m, m_len)
|
||||||
|
#define _libssh2_dsa_free(dsactx) \
|
||||||
|
_libssh2_wincng_dsa_free(dsactx)
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Windows CNG backend: Key functions
|
||||||
|
*/
|
||||||
|
|
||||||
|
#define _libssh2_pub_priv_keyfile(s, m, m_len, p, p_len, pk, pw) \
|
||||||
|
_libssh2_wincng_pub_priv_keyfile(s, m, m_len, p, p_len, pk, pw)
|
||||||
|
|
||||||
|
|
||||||
|
/*******************************************************************/
|
||||||
|
/*
|
||||||
|
* Windows CNG backend: Cipher Context structure
|
||||||
|
*/
|
||||||
|
|
||||||
|
struct _libssh2_wincng_cipher_ctx {
|
||||||
|
BCRYPT_KEY_HANDLE hKey;
|
||||||
|
unsigned char *pbKeyObject;
|
||||||
|
unsigned char *pbIV;
|
||||||
|
unsigned long dwKeyObject;
|
||||||
|
unsigned long dwIV;
|
||||||
|
unsigned long dwBlockLength;
|
||||||
|
};
|
||||||
|
|
||||||
|
#define _libssh2_cipher_ctx struct _libssh2_wincng_cipher_ctx
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Windows CNG backend: Cipher Type structure
|
||||||
|
*/
|
||||||
|
|
||||||
|
struct _libssh2_wincng_cipher_type {
|
||||||
|
BCRYPT_ALG_HANDLE *phAlg;
|
||||||
|
unsigned long dwKeyLength;
|
||||||
|
unsigned long dwUseIV;
|
||||||
|
};
|
||||||
|
|
||||||
|
#define _libssh2_cipher_type(type) struct _libssh2_wincng_cipher_type type
|
||||||
|
|
||||||
|
#define _libssh2_cipher_aes256ctr { NULL, 32, 1 } /* not supported */
|
||||||
|
#define _libssh2_cipher_aes192ctr { NULL, 24, 1 } /* not supported */
|
||||||
|
#define _libssh2_cipher_aes128ctr { NULL, 16, 1 } /* not supported */
|
||||||
|
#define _libssh2_cipher_aes256 { &_libssh2_wincng.hAlgAES_CBC, 32, 1 }
|
||||||
|
#define _libssh2_cipher_aes192 { &_libssh2_wincng.hAlgAES_CBC, 24, 1 }
|
||||||
|
#define _libssh2_cipher_aes128 { &_libssh2_wincng.hAlgAES_CBC, 16, 1 }
|
||||||
|
#define _libssh2_cipher_blowfish { NULL, 16, 0 } /* not supported */
|
||||||
|
#define _libssh2_cipher_arcfour { &_libssh2_wincng.hAlgRC4_NA, 16, 0 }
|
||||||
|
#define _libssh2_cipher_cast5 { NULL, 16, 0 } /* not supported */
|
||||||
|
#define _libssh2_cipher_3des { &_libssh2_wincng.hAlg3DES_CBC, 24, 1 }
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Windows CNG backend: Cipher functions
|
||||||
|
*/
|
||||||
|
|
||||||
|
#define _libssh2_cipher_init(ctx, type, iv, secret, encrypt) \
|
||||||
|
_libssh2_wincng_cipher_init(ctx, type, iv, secret, encrypt)
|
||||||
|
#define _libssh2_cipher_crypt(ctx, type, encrypt, block, blocklen) \
|
||||||
|
_libssh2_wincng_cipher_crypt(ctx, type, encrypt, block, blocklen)
|
||||||
|
#define _libssh2_cipher_dtor(ctx) \
|
||||||
|
_libssh2_wincng_cipher_dtor(ctx)
|
||||||
|
|
||||||
|
/*******************************************************************/
|
||||||
|
/*
|
||||||
|
* Windows CNG backend: BigNumber Context
|
||||||
|
*/
|
||||||
|
|
||||||
|
#define _libssh2_bn_ctx int /* not used */
|
||||||
|
#define _libssh2_bn_ctx_new() 0 /* not used */
|
||||||
|
#define _libssh2_bn_ctx_free(bnctx) ((void)0) /* not used */
|
||||||
|
|
||||||
|
|
||||||
|
/*******************************************************************/
|
||||||
|
/*
|
||||||
|
* Windows CNG backend: BigNumber structure
|
||||||
|
*/
|
||||||
|
|
||||||
|
struct _libssh2_wincng_bignum {
|
||||||
|
unsigned char *bignum;
|
||||||
|
unsigned long length;
|
||||||
|
};
|
||||||
|
|
||||||
|
#define _libssh2_bn struct _libssh2_wincng_bignum
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Windows CNG backend: BigNumber functions
|
||||||
|
*/
|
||||||
|
|
||||||
|
_libssh2_bn *_libssh2_wincng_bignum_init(void);
|
||||||
|
|
||||||
|
#define _libssh2_bn_init() \
|
||||||
|
_libssh2_wincng_bignum_init()
|
||||||
|
#define _libssh2_bn_rand(bn, bits, top, bottom) \
|
||||||
|
_libssh2_wincng_bignum_rand(bn, bits, top, bottom)
|
||||||
|
#define _libssh2_bn_mod_exp(r, a, p, m, ctx) \
|
||||||
|
_libssh2_wincng_bignum_mod_exp(r, a, p, m, ctx)
|
||||||
|
#define _libssh2_bn_set_word(bn, word) \
|
||||||
|
_libssh2_wincng_bignum_set_word(bn, word)
|
||||||
|
#define _libssh2_bn_from_bin(bn, len, bin) \
|
||||||
|
_libssh2_wincng_bignum_from_bin(bn, len, bin)
|
||||||
|
#define _libssh2_bn_to_bin(bn, bin) \
|
||||||
|
_libssh2_wincng_bignum_to_bin(bn, bin)
|
||||||
|
#define _libssh2_bn_bytes(bn) bn->length
|
||||||
|
#define _libssh2_bn_bits(bn) \
|
||||||
|
_libssh2_wincng_bignum_bits(bn)
|
||||||
|
#define _libssh2_bn_free(bn) \
|
||||||
|
_libssh2_wincng_bignum_free(bn)
|
||||||
|
|
||||||
|
/*******************************************************************/
|
||||||
|
/*
|
||||||
|
* Windows CNG backend: forward declarations
|
||||||
|
*/
|
||||||
|
void _libssh2_wincng_init(void);
|
||||||
|
void _libssh2_wincng_free(void);
|
||||||
|
int _libssh2_wincng_random(void *buf, int len);
|
||||||
|
void _libssh2_init_aes_ctr(void);
|
||||||
|
|
||||||
|
int
|
||||||
|
_libssh2_wincng_hash_init(_libssh2_wincng_hash_ctx *ctx,
|
||||||
|
BCRYPT_ALG_HANDLE hAlg, unsigned long hashlen,
|
||||||
|
unsigned char *key, unsigned long keylen);
|
||||||
|
int
|
||||||
|
_libssh2_wincng_hash_update(_libssh2_wincng_hash_ctx *ctx,
|
||||||
|
const unsigned char *data, unsigned long datalen);
|
||||||
|
int
|
||||||
|
_libssh2_wincng_hash_final(_libssh2_wincng_hash_ctx *ctx,
|
||||||
|
unsigned char *hash);
|
||||||
|
int
|
||||||
|
_libssh2_wincng_hash(unsigned char *data, unsigned long datalen,
|
||||||
|
BCRYPT_ALG_HANDLE hAlg,
|
||||||
|
unsigned char *hash, unsigned long hashlen);
|
||||||
|
|
||||||
|
int
|
||||||
|
_libssh2_wincng_hmac_final(_libssh2_wincng_hash_ctx *ctx,
|
||||||
|
unsigned char *hash);
|
||||||
|
void
|
||||||
|
_libssh2_wincng_hmac_cleanup(_libssh2_wincng_hash_ctx *ctx);
|
||||||
|
|
||||||
|
int
|
||||||
|
_libssh2_wincng_key_sha1_verify(_libssh2_wincng_key_ctx *ctx,
|
||||||
|
const unsigned char *sig,
|
||||||
|
unsigned long sig_len,
|
||||||
|
const unsigned char *m,
|
||||||
|
unsigned long m_len,
|
||||||
|
unsigned long flags);
|
||||||
|
|
||||||
|
int
|
||||||
|
_libssh2_wincng_rsa_new(libssh2_rsa_ctx **rsa,
|
||||||
|
const unsigned char *edata,
|
||||||
|
unsigned long elen,
|
||||||
|
const unsigned char *ndata,
|
||||||
|
unsigned long nlen,
|
||||||
|
const unsigned char *ddata,
|
||||||
|
unsigned long dlen,
|
||||||
|
const unsigned char *pdata,
|
||||||
|
unsigned long plen,
|
||||||
|
const unsigned char *qdata,
|
||||||
|
unsigned long qlen,
|
||||||
|
const unsigned char *e1data,
|
||||||
|
unsigned long e1len,
|
||||||
|
const unsigned char *e2data,
|
||||||
|
unsigned long e2len,
|
||||||
|
const unsigned char *coeffdata,
|
||||||
|
unsigned long coefflen);
|
||||||
|
int
|
||||||
|
_libssh2_wincng_rsa_new_private(libssh2_rsa_ctx **rsa,
|
||||||
|
LIBSSH2_SESSION *session,
|
||||||
|
const char *filename,
|
||||||
|
const unsigned char *passphrase);
|
||||||
|
int
|
||||||
|
_libssh2_wincng_rsa_sha1_verify(libssh2_rsa_ctx *rsa,
|
||||||
|
const unsigned char *sig,
|
||||||
|
unsigned long sig_len,
|
||||||
|
const unsigned char *m,
|
||||||
|
unsigned long m_len);
|
||||||
|
int
|
||||||
|
_libssh2_wincng_rsa_sha1_sign(LIBSSH2_SESSION *session,
|
||||||
|
libssh2_rsa_ctx *rsa,
|
||||||
|
const unsigned char *hash,
|
||||||
|
size_t hash_len,
|
||||||
|
unsigned char **signature,
|
||||||
|
size_t *signature_len);
|
||||||
|
void
|
||||||
|
_libssh2_wincng_rsa_free(libssh2_rsa_ctx *rsa);
|
||||||
|
|
||||||
|
#if LIBSSH2_DSA
|
||||||
|
int
|
||||||
|
_libssh2_wincng_dsa_new(libssh2_dsa_ctx **dsa,
|
||||||
|
const unsigned char *pdata,
|
||||||
|
unsigned long plen,
|
||||||
|
const unsigned char *qdata,
|
||||||
|
unsigned long qlen,
|
||||||
|
const unsigned char *gdata,
|
||||||
|
unsigned long glen,
|
||||||
|
const unsigned char *ydata,
|
||||||
|
unsigned long ylen,
|
||||||
|
const unsigned char *xdata,
|
||||||
|
unsigned long xlen);
|
||||||
|
int
|
||||||
|
_libssh2_wincng_dsa_new_private(libssh2_dsa_ctx **dsa,
|
||||||
|
LIBSSH2_SESSION *session,
|
||||||
|
const char *filename,
|
||||||
|
const unsigned char *passphrase);
|
||||||
|
int
|
||||||
|
_libssh2_wincng_dsa_sha1_verify(libssh2_dsa_ctx *dsa,
|
||||||
|
const unsigned char *sig_fixed,
|
||||||
|
const unsigned char *m,
|
||||||
|
unsigned long m_len);
|
||||||
|
int
|
||||||
|
_libssh2_wincng_dsa_sha1_sign(libssh2_dsa_ctx *dsa,
|
||||||
|
const unsigned char *hash,
|
||||||
|
unsigned long hash_len,
|
||||||
|
unsigned char *sig_fixed);
|
||||||
|
void
|
||||||
|
_libssh2_wincng_dsa_free(libssh2_dsa_ctx *dsa);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
int
|
||||||
|
_libssh2_wincng_pub_priv_keyfile(LIBSSH2_SESSION *session,
|
||||||
|
unsigned char **method,
|
||||||
|
size_t *method_len,
|
||||||
|
unsigned char **pubkeydata,
|
||||||
|
size_t *pubkeydata_len,
|
||||||
|
const char *privatekey,
|
||||||
|
const char *passphrase);
|
||||||
|
|
||||||
|
int
|
||||||
|
_libssh2_wincng_cipher_init(_libssh2_cipher_ctx *ctx,
|
||||||
|
_libssh2_cipher_type(type),
|
||||||
|
unsigned char *iv,
|
||||||
|
unsigned char *secret,
|
||||||
|
int encrypt);
|
||||||
|
int
|
||||||
|
_libssh2_wincng_cipher_crypt(_libssh2_cipher_ctx *ctx,
|
||||||
|
_libssh2_cipher_type(type),
|
||||||
|
int encrypt,
|
||||||
|
unsigned char *block,
|
||||||
|
size_t blocklen);
|
||||||
|
void
|
||||||
|
_libssh2_wincng_cipher_dtor(_libssh2_cipher_ctx *ctx);
|
||||||
|
|
||||||
|
_libssh2_bn *
|
||||||
|
_libssh2_wincng_bignum_init(void);
|
||||||
|
int
|
||||||
|
_libssh2_wincng_bignum_rand(_libssh2_bn *rnd, int bits, int top, int bottom);
|
||||||
|
int
|
||||||
|
_libssh2_wincng_bignum_mod_exp(_libssh2_bn *r,
|
||||||
|
_libssh2_bn *a,
|
||||||
|
_libssh2_bn *p,
|
||||||
|
_libssh2_bn *m,
|
||||||
|
_libssh2_bn_ctx *bnctx);
|
||||||
|
int
|
||||||
|
_libssh2_wincng_bignum_set_word(_libssh2_bn *bn, unsigned long word);
|
||||||
|
unsigned long
|
||||||
|
_libssh2_wincng_bignum_bits(const _libssh2_bn *bn);
|
||||||
|
void
|
||||||
|
_libssh2_wincng_bignum_from_bin(_libssh2_bn *bn, unsigned long len,
|
||||||
|
const unsigned char *bin);
|
||||||
|
void
|
||||||
|
_libssh2_wincng_bignum_to_bin(const _libssh2_bn *bn, unsigned char *bin);
|
||||||
|
void
|
||||||
|
_libssh2_wincng_bignum_free(_libssh2_bn *bn);
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user