Compare commits
203 Commits
libssh2-1.
...
libssh2-1.
Author | SHA1 | Date | |
---|---|---|---|
![]() |
e16f638dca | ||
![]() |
7d94b69b80 | ||
![]() |
8bb6cf7f95 | ||
![]() |
5fcbb168b8 | ||
![]() |
d811750645 | ||
![]() |
cfe94c715e | ||
![]() |
a8473c819b | ||
![]() |
c71889017f | ||
![]() |
253d5922f2 | ||
![]() |
79d63df12d | ||
![]() |
86552bf2bb | ||
![]() |
477e609a84 | ||
![]() |
3e47ca8a32 | ||
![]() |
6af0ee567b | ||
![]() |
c6d99bd3a4 | ||
![]() |
d1eccb487a | ||
![]() |
22204c4e2e | ||
![]() |
8670f5da24 | ||
![]() |
3835655f09 | ||
![]() |
dc199ed03a | ||
![]() |
8f799f98d9 | ||
![]() |
637c90959b | ||
![]() |
8a731d6217 | ||
![]() |
d85f9a689f | ||
![]() |
031566f9cc | ||
![]() |
977a3b6a76 | ||
![]() |
34dc1d61b4 | ||
![]() |
be95032e29 | ||
![]() |
c0bface8a7 | ||
![]() |
f31c9fb221 | ||
![]() |
f89bed9571 | ||
![]() |
bc9d735664 | ||
![]() |
06ff22f1a6 | ||
![]() |
e57f29f8f6 | ||
![]() |
1c1699545b | ||
![]() |
abcc0d370f | ||
![]() |
977dbb7511 | ||
![]() |
aedfba25b8 | ||
![]() |
19f1402f1d | ||
![]() |
df5c61dbca | ||
![]() |
1689315fce | ||
![]() |
7f7e65c54b | ||
![]() |
751e0087a8 | ||
![]() |
600f26ce6e | ||
![]() |
3260beb07a | ||
![]() |
01a6210ab7 | ||
![]() |
6a3b5487cb | ||
![]() |
e4ba5fabec | ||
![]() |
46f017e751 | ||
![]() |
12adbc28b8 | ||
![]() |
424a27e007 | ||
![]() |
1e4fb7ee9f | ||
![]() |
7b80a188dd | ||
![]() |
9d50d43a83 | ||
![]() |
c355d31ff9 | ||
![]() |
18fe507324 | ||
![]() |
d63e32dd30 | ||
![]() |
c32e82e97b | ||
![]() |
7d4b5a8e07 | ||
![]() |
200784c4e7 | ||
![]() |
b22b23703c | ||
![]() |
0e4e14109a | ||
![]() |
5bcc2d4629 | ||
![]() |
33df559967 | ||
![]() |
26f6d71885 | ||
![]() |
62c91e2cd4 | ||
![]() |
b9dc6112d7 | ||
![]() |
106bacdebc | ||
![]() |
23dec383f7 | ||
![]() |
fc94046e6e | ||
![]() |
ee547fe90d | ||
![]() |
a58b0dacb4 | ||
![]() |
6e710d7fb6 | ||
![]() |
b20bfeb3e5 | ||
![]() |
aba11380a1 | ||
![]() |
2c46c4bf95 | ||
![]() |
160776d218 | ||
![]() |
ee2d61a48b | ||
![]() |
fcb601da7b | ||
![]() |
55bae8dd07 | ||
![]() |
4440e05d48 | ||
![]() |
378d0a6676 | ||
![]() |
21cb7bfb36 | ||
![]() |
e1a5d1bc77 | ||
![]() |
189cf86df0 | ||
![]() |
30e376773a | ||
![]() |
38e210af0e | ||
![]() |
d145e04443 | ||
![]() |
feab568a7a | ||
![]() |
08973a00a1 | ||
![]() |
c00efa5f93 | ||
![]() |
adc5db29e3 | ||
![]() |
92d686fe19 | ||
![]() |
5559ad8fe1 | ||
![]() |
88366b5ec2 | ||
![]() |
61df22c460 | ||
![]() |
d808080daf | ||
![]() |
f5c1a0d98b | ||
![]() |
85a827d1bc | ||
![]() |
1b3307dda0 | ||
![]() |
85c6627c86 | ||
![]() |
c49cc8411f | ||
![]() |
fa15fded72 | ||
![]() |
c2329aa09e | ||
![]() |
94077f7a58 | ||
![]() |
55a8b10ad9 | ||
![]() |
27f9ac2549 | ||
![]() |
cdeef54967 | ||
![]() |
42aefdba79 | ||
![]() |
d41f5e40aa | ||
![]() |
2df6cd6606 | ||
![]() |
d512b25f69 | ||
![]() |
b4f71fd25a | ||
![]() |
a5bf809b80 | ||
![]() |
2157e178a3 | ||
![]() |
d385230e15 | ||
![]() |
61e40a32ff | ||
![]() |
e6c46cc249 | ||
![]() |
9f1b89e99b | ||
![]() |
8da30ea4d4 | ||
![]() |
ff6c01e959 | ||
![]() |
c910cd382d | ||
![]() |
edd42304a2 | ||
![]() |
1ad20ac7d3 | ||
![]() |
d7f9cd57c5 | ||
![]() |
16ef83dd81 | ||
![]() |
951904418b | ||
![]() |
80e5e20b00 | ||
![]() |
6e0d757f24 | ||
![]() |
a12f3ffab5 | ||
![]() |
486bb37621 | ||
![]() |
fe347a702f | ||
![]() |
07615610ba | ||
![]() |
5aa7b29758 | ||
![]() |
a67ff056e6 | ||
![]() |
f1cfa55b60 | ||
![]() |
437a3b75ec | ||
![]() |
a3ad635db4 | ||
![]() |
e5c5408564 | ||
![]() |
fe8f3deb48 | ||
![]() |
d49b8f303a | ||
![]() |
6f8777505f | ||
![]() |
52b8da7dfa | ||
![]() |
de7b5d3bc0 | ||
![]() |
b31e35aba6 | ||
![]() |
e2bb780d77 | ||
![]() |
a8cfc708c5 | ||
![]() |
9f6fd5af82 | ||
![]() |
5d567faecc | ||
![]() |
bfbb5a4dc7 | ||
![]() |
43b730ce56 | ||
![]() |
6af85b6053 | ||
![]() |
05641218bc | ||
![]() |
42fec44c8a | ||
![]() |
e470738a0c | ||
![]() |
62cc59cd06 | ||
![]() |
1abf2057de | ||
![]() |
6c27922ac1 | ||
![]() |
112845df0b | ||
![]() |
499b22ca36 | ||
![]() |
6403519fcf | ||
![]() |
6f8dd9baff | ||
![]() |
a1c0d97ff9 | ||
![]() |
5c065bf1ff | ||
![]() |
5237177daf | ||
![]() |
bd627d38a1 | ||
![]() |
c55b0b0425 | ||
![]() |
38efbe8243 | ||
![]() |
34ecc09a3c | ||
![]() |
d6cf1c7df0 | ||
![]() |
a40c160cff | ||
![]() |
29e256e817 | ||
![]() |
137342a41d | ||
![]() |
79a7ca3085 | ||
![]() |
50e37bdadc | ||
![]() |
04e79e0c79 | ||
![]() |
9a36065b52 | ||
![]() |
1ac7bd09cc | ||
![]() |
9a7311ba57 | ||
![]() |
e07b11b7df | ||
![]() |
e885300b18 | ||
![]() |
92a9f95279 | ||
![]() |
e91d4c9790 | ||
![]() |
69a3354467 | ||
![]() |
3ede6e280e | ||
![]() |
b583311a93 | ||
![]() |
27ac5aa40d | ||
![]() |
a123051200 | ||
![]() |
62901253a4 | ||
![]() |
7c5ee0fa66 | ||
![]() |
1e15075a8e | ||
![]() |
ad63fc2df6 | ||
![]() |
d46185eaa5 | ||
![]() |
9c4b380dd6 | ||
![]() |
e887a8bd0f | ||
![]() |
04692445d4 | ||
![]() |
a955f8428b | ||
![]() |
ededdfa9c2 | ||
![]() |
11f9dce3d7 | ||
![]() |
6bbebcf36c | ||
![]() |
7a87bba02a | ||
![]() |
c8374cdc10 | ||
![]() |
9b2bed22fc |
2
.gitignore
vendored
2
.gitignore
vendored
@@ -24,7 +24,6 @@ ltmain.sh
|
|||||||
missing
|
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
|
17
Makefile.am
17
Makefile.am
@@ -1,6 +1,9 @@
|
|||||||
AUTOMAKE_OPTIONS = foreign nostdinc
|
AUTOMAKE_OPTIONS = foreign nostdinc
|
||||||
|
|
||||||
SUBDIRS = src example tests docs
|
SUBDIRS = src tests docs
|
||||||
|
if BUILD_EXAMPLES
|
||||||
|
SUBDIRS += example
|
||||||
|
endif
|
||||||
|
|
||||||
pkgconfigdir = $(libdir)/pkgconfig
|
pkgconfigdir = $(libdir)/pkgconfig
|
||||||
pkgconfig_DATA = libssh2.pc
|
pkgconfig_DATA = libssh2.pc
|
||||||
@@ -11,10 +14,9 @@ include_HEADERS = \
|
|||||||
include/libssh2_sftp.h
|
include/libssh2_sftp.h
|
||||||
|
|
||||||
NETWAREFILES = nw/keepscreen.c \
|
NETWAREFILES = nw/keepscreen.c \
|
||||||
nw/Makefile \
|
|
||||||
nw/Makefile.netware \
|
|
||||||
nw/nwlib.c \
|
nw/nwlib.c \
|
||||||
nw/test/Makefile.netware
|
nw/GNUmakefile \
|
||||||
|
nw/test/GNUmakefile
|
||||||
|
|
||||||
DSP = win32/libssh2.dsp
|
DSP = win32/libssh2.dsp
|
||||||
VCPROJ = win32/libssh2.vcproj
|
VCPROJ = win32/libssh2.vcproj
|
||||||
@@ -30,8 +32,8 @@ win32/libssh2_config.h win32/config.mk win32/rules.mk \
|
|||||||
win32/Makefile.Watcom win32/libssh2.dsw win32/tests.dsp $(DSP) \
|
win32/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
|
||||||
|
|
||||||
@@ -73,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,28 +1,83 @@
|
|||||||
libssh2 1.4.1
|
libssh2 1.5.0
|
||||||
|
|
||||||
|
This release includes the following changes:
|
||||||
|
|
||||||
|
o Added Windows Cryptography API: Next Generation based backend
|
||||||
|
|
||||||
This release includes the following bugfixes:
|
This release includes the following bugfixes:
|
||||||
|
|
||||||
o build error with gcrypt backend
|
o Security Advisory for CVE-2015-1782, using SSH_MSG_KEXINIT data unbounded
|
||||||
o always do "forced" window updates to avoid corner case stalls
|
o missing _libssh2_error in _libssh2_channel_write
|
||||||
o aes: the init function fails when OpenSSL has AES support
|
o knownhost: Fix DSS keys being detected as unknown.
|
||||||
o transport_send: Finish in-progress key exchange before sending data
|
o knownhost: Restore behaviour of `libssh2_knownhost_writeline` with short buffer.
|
||||||
o channel_write: acknowledge transport errors
|
o libssh2.h: on Windows, a socket is of type SOCKET, not int
|
||||||
o examples/x11.c: Make sure sizeof passed to read operation is correct
|
o libssh2_priv.h: a 1 bit bit-field should be unsigned
|
||||||
o examples/x11.c:,Fix suspicious sizeof usage
|
o windows build: do not export externals from static library
|
||||||
o sftp_packet_add: verify the packet before accepting it
|
o Fixed two potential use-after-frees of the payload buffer
|
||||||
o SFTP: preserve the original error code more
|
o Fixed a few memory leaks in error paths
|
||||||
o sftp_packet_read: adjust window size as necessary
|
o userauth: Fixed an attempt to free from stack on error
|
||||||
o Use safer snprintf rather then sprintf in several places
|
o agent_list_identities: Fixed memory leak on OOM
|
||||||
o Define and use LIBSSH2_INVALID_SOCKET instead of INVALID_SOCKET
|
o knownhosts: Abort if the hosts buffer is too small
|
||||||
o sftp_write: cannot return acked data *and* EAGAIN
|
o sftp_close_handle: ensure the handle is always closed
|
||||||
o sftp_read: avoid data *and* EAGAIN
|
o channel_close: Close the channel even in the case of errors
|
||||||
o libssh2.h: Add missing prototype for libssh2_session_banner_set()
|
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:
|
||||||
|
|
||||||
Armen Babakhanian, Paul Howarth, Matthew Booth, Steven Dake, Peter Stuge,
|
Alexander Lamaison, Bob Kast, Dan Fandrich, Daniel Stenberg, Guenter Knauf,
|
||||||
Matt Lawson, Tom Weber, Alexander Lamaison
|
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)
|
||||||
|
|
||||||
|
110
configure.ac
110
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,55 +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>])
|
||||||
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>])
|
||||||
fi
|
fi
|
||||||
|
|
||||||
if test "$ac_cv_libssl" != "yes" && test "$ac_cv_libgcrypt" != "yes"; then
|
|
||||||
AC_MSG_ERROR([cannot find OpenSSL or Libgcrypt,
|
|
||||||
try --with-libssl-prefix=PATH or --with-libgcrypt-prefix=PATH])
|
|
||||||
fi
|
|
||||||
|
|
||||||
if test "$ac_cv_libgcrypt" = "yes"; then
|
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
|
||||||
#
|
#
|
||||||
@@ -215,6 +262,22 @@ AC_HELP_STRING([--disable-hidden-symbols],[Leave all symbols with default visibi
|
|||||||
AC_MSG_RESULT(no)
|
AC_MSG_RESULT(no)
|
||||||
)
|
)
|
||||||
|
|
||||||
|
# Build example applications?
|
||||||
|
AC_MSG_CHECKING([whether to build example applications])
|
||||||
|
AC_ARG_ENABLE([examples-build],
|
||||||
|
AC_HELP_STRING([--enable-examples-build], [Build example applications (this is the default)])
|
||||||
|
AC_HELP_STRING([--disable-examples-build], [Do not build example applications]),
|
||||||
|
[case "$enableval" in
|
||||||
|
no | false)
|
||||||
|
build_examples='no'
|
||||||
|
;;
|
||||||
|
*)
|
||||||
|
build_examples='yes'
|
||||||
|
;;
|
||||||
|
esac], [build_examples='yes'])
|
||||||
|
AC_MSG_RESULT($build_examples)
|
||||||
|
AM_CONDITIONAL([BUILD_EXAMPLES], [test "x$build_examples" != "xno"])
|
||||||
|
|
||||||
# Checks for header files.
|
# Checks for header files.
|
||||||
# AC_HEADER_STDC
|
# AC_HEADER_STDC
|
||||||
AC_CHECK_HEADERS([errno.h fcntl.h stdio.h stdlib.h unistd.h sys/uio.h])
|
AC_CHECK_HEADERS([errno.h fcntl.h stdio.h stdlib.h unistd.h sys/uio.h])
|
||||||
@@ -298,8 +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
|
||||||
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) {
|
||||||
@@ -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,28 +157,70 @@ 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,
|
|
||||||
"/home/username/.ssh/id_rsa.pub",
|
|
||||||
"/home/username/.ssh/id_rsa",
|
|
||||||
password)) {
|
|
||||||
printf("\tAuthentication by public key failed\n");
|
|
||||||
goto shutdown;
|
goto shutdown;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
fprintf(stderr, "libssh2_sftp_init()!\n");
|
fprintf(stderr, "libssh2_sftp_init()!\n");
|
||||||
sftp_session = libssh2_sftp_init(session);
|
sftp_session = libssh2_sftp_init(session);
|
||||||
@@ -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,9 +49,9 @@ 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) {
|
||||||
@@ -209,7 +210,7 @@ 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);
|
||||||
@@ -218,11 +219,14 @@ static int x11_send_receive(LIBSSH2_CHANNEL *channel, int sock)
|
|||||||
|
|
||||||
/* 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);
|
||||||
@@ -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);
|
||||||
}
|
}
|
||||||
|
@@ -1,5 +1,5 @@
|
|||||||
/* Copyright (c) 2004-2009, Sara Golemon <sarag@libssh2.org>
|
/* Copyright (c) 2004-2009, Sara Golemon <sarag@libssh2.org>
|
||||||
* Copyright (c) 2009-2010 Daniel Stenberg
|
* Copyright (c) 2009-2012 Daniel Stenberg
|
||||||
* Copyright (c) 2010 Simon Josefsson <simon@josefsson.org>
|
* Copyright (c) 2010 Simon Josefsson <simon@josefsson.org>
|
||||||
* All rights reserved.
|
* All rights reserved.
|
||||||
*
|
*
|
||||||
@@ -40,19 +40,19 @@
|
|||||||
#ifndef LIBSSH2_H
|
#ifndef LIBSSH2_H
|
||||||
#define LIBSSH2_H 1
|
#define LIBSSH2_H 1
|
||||||
|
|
||||||
#define LIBSSH2_COPYRIGHT "2004-2011 The libssh2 project and its contributors."
|
#define LIBSSH2_COPYRIGHT "2004-2014 The libssh2 project and its contributors."
|
||||||
|
|
||||||
/* We use underscore instead of dash when appending DEV in dev versions just
|
/* 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.0_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 0
|
#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 0x010400
|
#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 _WINDLL
|
||||||
# ifdef LIBSSH2_LIBRARY
|
# ifdef LIBSSH2_LIBRARY
|
||||||
# define LIBSSH2_API __declspec(dllexport)
|
# define LIBSSH2_API __declspec(dllexport)
|
||||||
# else
|
# else
|
||||||
# define LIBSSH2_API __declspec(dllimport)
|
# define LIBSSH2_API __declspec(dllimport)
|
||||||
# endif /* LIBSSH2_LIBRARY */
|
# endif /* LIBSSH2_LIBRARY */
|
||||||
|
# else
|
||||||
|
# define LIBSSH2_API
|
||||||
|
# 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,
|
||||||
@@ -534,7 +541,8 @@ 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), \
|
||||||
|
(publickey), \
|
||||||
(privatekey), (passphrase))
|
(privatekey), (passphrase))
|
||||||
|
|
||||||
LIBSSH2_API int
|
LIBSSH2_API int
|
||||||
@@ -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), \
|
||||||
|
(publickey), \
|
||||||
(privatekey), (passphrase), \
|
(privatekey), (passphrase), \
|
||||||
(hostname), strlen(hostname), \
|
(hostname), \
|
||||||
(username), strlen(username))
|
(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,
|
||||||
@@ -580,13 +591,14 @@ libssh2_userauth_keyboard_interactive_ex(LIBSSH2_SESSION* session,
|
|||||||
#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
|
||||||
|
|
||||||
@@ -635,8 +647,9 @@ LIBSSH2_API int libssh2_channel_setenv_ex(LIBSSH2_CHANNEL *channel,
|
|||||||
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,
|
||||||
@@ -646,7 +659,9 @@ LIBSSH2_API int libssh2_channel_request_pty_ex(LIBSSH2_CHANNEL *channel,
|
|||||||
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), \
|
||||||
|
(unsigned int)strlen(term), \
|
||||||
|
NULL, 0, \
|
||||||
LIBSSH2_TERM_WIDTH, LIBSSH2_TERM_HEIGHT, \
|
LIBSSH2_TERM_WIDTH, LIBSSH2_TERM_HEIGHT, \
|
||||||
LIBSSH2_TERM_WIDTH_PX, LIBSSH2_TERM_HEIGHT_PX)
|
LIBSSH2_TERM_WIDTH_PX, LIBSSH2_TERM_HEIGHT_PX)
|
||||||
|
|
||||||
@@ -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)
|
||||||
|
@@ -11,6 +11,7 @@ Name: libssh2
|
|||||||
URL: http://www.libssh2.org/
|
URL: http://www.libssh2.org/
|
||||||
Description: Library for SSH-based communication
|
Description: Library for SSH-based communication
|
||||||
Version: @LIBSSH2VER@
|
Version: @LIBSSH2VER@
|
||||||
|
Requires.private: @LIBSREQUIRED@
|
||||||
Libs: -L${libdir} -lssh2 @LDFLAGS@ @LIBS@
|
Libs: -L${libdir} -lssh2 @LDFLAGS@ @LIBS@
|
||||||
Libs.private: @LIBS@
|
Libs.private: @LIBS@
|
||||||
Cflags: -I${includedir}
|
Cflags: -I${includedir}
|
||||||
|
@@ -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.5
|
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.8r
|
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,69 +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) ../COPYING $(DISTDIR)
|
@$(call COPY, ../AUTHORS, $(DISTDIR))
|
||||||
@-$(CP) ../INSTALL $(DISTDIR)
|
@$(call COPY, ../COPYING, $(DISTDIR))
|
||||||
@-$(CP) ../README $(DISTDIR)
|
@$(call COPY, ../INSTALL, $(DISTDIR))
|
||||||
@$(CP) $(TARGET).nlm $(DISTDIR)/bin
|
@$(call COPY, ../README, $(DISTDIR))
|
||||||
|
@$(call COPY, ../RELEASE-NOTES, $(DISTDIR))
|
||||||
|
@$(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) ../COPYING $(DISTDIR)
|
@$(call COPY, ../AUTHORS, $(DEVLDIR))
|
||||||
@-$(CP) ../INSTALL $(DEVLDIR)
|
@$(call COPY, ../COPYING, $(DEVLDIR))
|
||||||
@-$(CP) ../README $(DEVLDIR)
|
@$(call COPY, ../INSTALL, $(DEVLDIR))
|
||||||
@$(CP) $(TARGET).nlm $(DEVLDIR)/bin
|
@$(call COPY, ../README, $(DEVLDIR))
|
||||||
@$(CP) ../include/*.h $(DEVLDIR)/include
|
@$(call COPY, ../RELEASE-NOTES, $(DEVLDIR))
|
||||||
@$(CP) libssh2_config.h $(DEVLDIR)/include
|
@$(call COPY, ../include/*.h, $(DEVLDIR)/include)
|
||||||
@$(CP) $(TARGET).$(LIBEXT) $(DEVLDIR)/nw
|
@$(call COPY, libssh2_config.h, $(DEVLDIR)/include)
|
||||||
|
@$(call COPY, $(TARGET).nlm, $(DEVLDIR)/bin)
|
||||||
|
@$(call COPY, $(TARGET).imp, $(DEVLDIR)/nw)
|
||||||
|
@$(call COPY, $(TARGET).$(LIBEXT), $(DEVLDIR)/nw)
|
||||||
@echo Creating $(DEVLARC)
|
@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) $@
|
||||||
@@ -287,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
|
||||||
@@ -353,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) >> $@
|
||||||
@@ -479,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) >> $@
|
||||||
@@ -506,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) >> $@
|
||||||
@@ -552,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) >> $@
|
||||||
@@ -562,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.5
|
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.8r
|
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:
|
||||||
|
140
src/channel.c
140
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,18 +2300,21 @@ 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");
|
|
||||||
}
|
|
||||||
|
|
||||||
|
} 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;
|
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
|
||||||
*/
|
*/
|
||||||
|
108
src/comp.c
108
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,17 +197,16 @@ 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,
|
|
||||||
"unhandled zlib compression error %d", status);
|
|
||||||
return _libssh2_error(session, LIBSSH2_ERROR_ZLIB,
|
|
||||||
"compression failure");
|
|
||||||
}
|
|
||||||
|
|
||||||
*dest_len = out_maxlen - strm->avail_out;
|
*dest_len = out_maxlen - strm->avail_out;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
_libssh2_debug(session, LIBSSH2_TRACE_TRANS,
|
||||||
|
"unhandled zlib compression error %d, avail_out", status, strm->avail_out);
|
||||||
|
return _libssh2_error(session, LIBSSH2_ERROR_ZLIB, "compression failure");
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* libssh2_comp_method_zlib_decomp
|
* libssh2_comp_method_zlib_decomp
|
||||||
*
|
*
|
||||||
@@ -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,30 +246,40 @@ 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) {
|
||||||
|
|
||||||
if ((out_maxlen > (int) payload_limit) && limiter++) {
|
|
||||||
LIBSSH2_FREE(session, out);
|
LIBSSH2_FREE(session, out);
|
||||||
return _libssh2_error(session, LIBSSH2_ERROR_ZLIB,
|
return _libssh2_error(session, LIBSSH2_ERROR_ZLIB,
|
||||||
"Excessive growth in decompression phase");
|
"Excessive growth in decompression phase");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* If we get here we need to grow the output buffer and try again */
|
||||||
|
out_ofs = out_maxlen - strm->avail_out;
|
||||||
|
out_maxlen *= 2;
|
||||||
newout = LIBSSH2_REALLOC(session, out, out_maxlen);
|
newout = LIBSSH2_REALLOC(session, out, out_maxlen);
|
||||||
if (!newout) {
|
if (!newout) {
|
||||||
LIBSSH2_FREE(session, out);
|
LIBSSH2_FREE(session, out);
|
||||||
@@ -280,51 +288,7 @@ comp_method_zlib_decomp(LIBSSH2_SESSION * session,
|
|||||||
}
|
}
|
||||||
out = newout;
|
out = newout;
|
||||||
strm->next_out = (unsigned char *) out + out_ofs;
|
strm->next_out = (unsigned char *) out + out_ofs;
|
||||||
strm->avail_out += 8 * strm->avail_in;
|
strm->avail_out = out_maxlen - out_ofs;
|
||||||
} 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;
|
||||||
|
84
src/kex.c
84
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);
|
||||||
|
|
||||||
|
282
src/knownhost.c
282
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,7 +441,18 @@ 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;
|
||||||
|
int known_key_type =
|
||||||
|
node->typemask & LIBSSH2_KNOWNHOST_KEY_MASK;
|
||||||
|
/* match on key type as follows:
|
||||||
|
- never match on an unknown key type
|
||||||
|
- if key_type is set to zero, ignore it an match always
|
||||||
|
- otherwise match when both key types are equal
|
||||||
|
*/
|
||||||
|
if ( (host_key_type != LIBSSH2_KNOWNHOST_KEY_UNKNOWN ) &&
|
||||||
|
( (host_key_type == 0) ||
|
||||||
|
(host_key_type == known_key_type) ) ) {
|
||||||
|
/* host name and key type match, now compare the keys */
|
||||||
if(!strcmp(key, node->key)) {
|
if(!strcmp(key, node->key)) {
|
||||||
/* they match! */
|
/* they match! */
|
||||||
if (ext)
|
if (ext)
|
||||||
@@ -429,9 +467,10 @@ knownhost_check(LIBSSH2_KNOWNHOSTS *hosts,
|
|||||||
here */
|
here */
|
||||||
if(!badkey)
|
if(!badkey)
|
||||||
badkey = node;
|
badkey = node;
|
||||||
match = 0; /* don't count this as a match anymore */
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
match = 0; /* don't count this as a match anymore */
|
||||||
|
}
|
||||||
node= _libssh2_list_next(&node->node);
|
node= _libssh2_list_next(&node->node);
|
||||||
}
|
}
|
||||||
host = hostp;
|
host = hostp;
|
||||||
@@ -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;
|
||||||
|
|
||||||
|
name_base64_len = _libssh2_base64_encode(hosts->session, node->name,
|
||||||
node->name_len, &namealloc);
|
node->name_len, &namealloc);
|
||||||
if(!nlen)
|
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
|
else if (node->comment)
|
||||||
snprintf(buf, buflen, "|1|%s|%s %s %s\n", saltalloc, namealloc,
|
snprintf(buf, buflen, "|1|%s|%s %s %s\n", saltalloc, namealloc,
|
||||||
keytype, node->key);
|
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
|
||||||
rc = _libssh2_error(hosts->session, LIBSSH2_ERROR_BUFFER_TOO_SMALL,
|
snprintf(buf, buflen, "|1|%s|%s %s\n", saltalloc, namealloc,
|
||||||
"Known-host write buffer too small");
|
node->key);
|
||||||
|
}
|
||||||
|
|
||||||
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,
|
||||||
|
key_type_name, node->key, node->comment);
|
||||||
|
else if (node->comment)
|
||||||
|
snprintf(buf, buflen, "%s %s %s\n", node->name, node->key,
|
||||||
node->comment);
|
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");
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -1087,7 +1185,7 @@ 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,8 +77,9 @@ 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__)
|
#if defined(LIBSSH2_WIN32) && !defined(__MINGW32__) && !defined(__CYGWIN__)
|
||||||
/* provide a private one */
|
/* provide a private one */
|
||||||
#undef HAVE_GETTIMEOFDAY
|
#undef HAVE_GETTIMEOFDAY
|
||||||
int __cdecl _libssh2_gettimeofday(struct timeval *tp, void *tzp);
|
int __cdecl _libssh2_gettimeofday(struct timeval *tp, void *tzp);
|
||||||
|
@@ -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
|
||||||
|
62
src/packet.c
62
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 */
|
||||||
|
if (listen_state->channel) {
|
||||||
_libssh2_list_add(&listn->queue,
|
_libssh2_list_add(&listn->queue,
|
||||||
&listen_state->channel->node);
|
&listen_state->channel->node);
|
||||||
listn->queue_size++;
|
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;
|
||||||
|
|
||||||
@@ -751,7 +773,7 @@ _libssh2_packet_add(LIBSSH2_SESSION * session, unsigned char *data,
|
|||||||
if(datalen >= 9) {
|
if(datalen >= 9) {
|
||||||
uint32_t channel = _libssh2_ntohu32(data + 1);
|
uint32_t channel = _libssh2_ntohu32(data + 1);
|
||||||
uint32_t len = _libssh2_ntohu32(data + 5);
|
uint32_t len = _libssh2_ntohu32(data + 5);
|
||||||
unsigned char want_reply = 0;
|
unsigned char want_reply = 1;
|
||||||
|
|
||||||
if(len < (datalen - 10))
|
if(len < (datalen - 10))
|
||||||
want_reply = data[9 + len];
|
want_reply = data[9 + len];
|
||||||
@@ -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);
|
||||||
|
@@ -143,7 +143,7 @@ banner_receive(LIBSSH2_SESSION * session)
|
|||||||
|
|
||||||
if (ret == 0) {
|
if (ret == 0) {
|
||||||
session->socket_state = LIBSSH2_SOCKET_DISCONNECTED;
|
session->socket_state = LIBSSH2_SOCKET_DISCONNECTED;
|
||||||
return LIBSSH2_ERROR_SOCKET_RECV;
|
return LIBSSH2_ERROR_SOCKET_DISCONNECT;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (c == '\0') {
|
if (c == '\0') {
|
||||||
@@ -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;
|
||||||
|
335
src/sftp.c
335
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);
|
||||||
@@ -132,6 +131,66 @@ static void _libssh2_store_u64(unsigned char **ptr, libssh2_uint64_t value)
|
|||||||
*ptr += 8;
|
*ptr += 8;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Search list of zombied FXP_READ request IDs.
|
||||||
|
*
|
||||||
|
* Returns NULL if ID not in list.
|
||||||
|
*/
|
||||||
|
static struct sftp_zombie_requests *
|
||||||
|
find_zombie_request(LIBSSH2_SFTP *sftp, uint32_t request_id)
|
||||||
|
{
|
||||||
|
struct sftp_zombie_requests *zombie =
|
||||||
|
_libssh2_list_first(&sftp->zombie_requests);
|
||||||
|
|
||||||
|
while(zombie) {
|
||||||
|
if(zombie->request_id == request_id)
|
||||||
|
break;
|
||||||
|
else
|
||||||
|
zombie = _libssh2_list_next(&zombie->node);
|
||||||
|
}
|
||||||
|
|
||||||
|
return zombie;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
remove_zombie_request(LIBSSH2_SFTP *sftp, uint32_t request_id)
|
||||||
|
{
|
||||||
|
LIBSSH2_SESSION *session = sftp->channel->session;
|
||||||
|
|
||||||
|
struct sftp_zombie_requests *zombie = find_zombie_request(sftp,
|
||||||
|
request_id);
|
||||||
|
if(zombie) {
|
||||||
|
_libssh2_debug(session, LIBSSH2_TRACE_SFTP,
|
||||||
|
"Removing request ID %ld from the list of zombie requests",
|
||||||
|
request_id);
|
||||||
|
|
||||||
|
_libssh2_list_remove(&zombie->node);
|
||||||
|
LIBSSH2_FREE(session, zombie);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
add_zombie_request(LIBSSH2_SFTP *sftp, uint32_t request_id)
|
||||||
|
{
|
||||||
|
LIBSSH2_SESSION *session = sftp->channel->session;
|
||||||
|
|
||||||
|
struct sftp_zombie_requests *zombie;
|
||||||
|
|
||||||
|
_libssh2_debug(session, LIBSSH2_TRACE_SFTP,
|
||||||
|
"Marking request ID %ld as a zombie request", request_id);
|
||||||
|
|
||||||
|
zombie = LIBSSH2_ALLOC(sftp->channel->session,
|
||||||
|
sizeof(struct sftp_zombie_requests));
|
||||||
|
if (!zombie)
|
||||||
|
return _libssh2_error(session, LIBSSH2_ERROR_ALLOC,
|
||||||
|
"malloc fail for zombie request ID");
|
||||||
|
else {
|
||||||
|
zombie->request_id = request_id;
|
||||||
|
_libssh2_list_add(&sftp->zombie_requests, &zombie->node);
|
||||||
|
return LIBSSH2_ERROR_NONE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* sftp_packet_add
|
* sftp_packet_add
|
||||||
*
|
*
|
||||||
@@ -143,6 +202,7 @@ sftp_packet_add(LIBSSH2_SFTP *sftp, unsigned char *data,
|
|||||||
{
|
{
|
||||||
LIBSSH2_SESSION *session = sftp->channel->session;
|
LIBSSH2_SESSION *session = sftp->channel->session;
|
||||||
LIBSSH2_SFTP_PACKET *packet;
|
LIBSSH2_SFTP_PACKET *packet;
|
||||||
|
uint32_t request_id;
|
||||||
|
|
||||||
_libssh2_debug(session, LIBSSH2_TRACE_SFTP, "Received packet %d (len %d)",
|
_libssh2_debug(session, LIBSSH2_TRACE_SFTP, "Received packet %d (len %d)",
|
||||||
(int) data[0], data_len);
|
(int) data[0], data_len);
|
||||||
@@ -188,6 +248,21 @@ sftp_packet_add(LIBSSH2_SFTP *sftp, unsigned char *data,
|
|||||||
"Out of sync with the world");
|
"Out of sync with the world");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
request_id = _libssh2_ntohu32(&data[1]);
|
||||||
|
|
||||||
|
/* Don't add the packet if it answers a request we've given up on. */
|
||||||
|
if((data[0] == SSH_FXP_STATUS || data[0] == SSH_FXP_DATA)
|
||||||
|
&& find_zombie_request(sftp, request_id)) {
|
||||||
|
|
||||||
|
/* If we get here, the file ended before the response arrived. We
|
||||||
|
are no longer interested in the request so we discard it */
|
||||||
|
|
||||||
|
LIBSSH2_FREE(session, data);
|
||||||
|
|
||||||
|
remove_zombie_request(sftp, request_id);
|
||||||
|
return LIBSSH2_ERROR_NONE;
|
||||||
|
}
|
||||||
|
|
||||||
packet = LIBSSH2_ALLOC(session, sizeof(LIBSSH2_SFTP_PACKET));
|
packet = LIBSSH2_ALLOC(session, sizeof(LIBSSH2_SFTP_PACKET));
|
||||||
if (!packet) {
|
if (!packet) {
|
||||||
return _libssh2_error(session, LIBSSH2_ERROR_ALLOC,
|
return _libssh2_error(session, LIBSSH2_ERROR_ALLOC,
|
||||||
@@ -196,7 +271,7 @@ sftp_packet_add(LIBSSH2_SFTP *sftp, unsigned char *data,
|
|||||||
|
|
||||||
packet->data = data;
|
packet->data = data;
|
||||||
packet->data_len = data_len;
|
packet->data_len = data_len;
|
||||||
packet->request_id = _libssh2_ntohu32(&data[1]);
|
packet->request_id = request_id;
|
||||||
|
|
||||||
_libssh2_list_add(&sftp->packets, &packet->node);
|
_libssh2_list_add(&sftp->packets, &packet->node);
|
||||||
|
|
||||||
@@ -216,6 +291,7 @@ sftp_packet_read(LIBSSH2_SFTP *sftp)
|
|||||||
unsigned char *packet = NULL;
|
unsigned char *packet = NULL;
|
||||||
ssize_t rc;
|
ssize_t rc;
|
||||||
unsigned long recv_window;
|
unsigned long recv_window;
|
||||||
|
int packet_type;
|
||||||
|
|
||||||
_libssh2_debug(session, LIBSSH2_TRACE_SFTP, "recv packet");
|
_libssh2_debug(session, LIBSSH2_TRACE_SFTP, "recv packet");
|
||||||
|
|
||||||
@@ -324,13 +400,17 @@ sftp_packet_read(LIBSSH2_SFTP *sftp)
|
|||||||
|
|
||||||
sftp->partial_packet = NULL;
|
sftp->partial_packet = NULL;
|
||||||
|
|
||||||
|
/* sftp_packet_add takes ownership of the packet and might free it
|
||||||
|
so we take a copy of the packet type before we call it. */
|
||||||
|
packet_type = packet[0];
|
||||||
rc = sftp_packet_add(sftp, packet, sftp->partial_len);
|
rc = sftp_packet_add(sftp, packet, sftp->partial_len);
|
||||||
if (rc) {
|
if (rc) {
|
||||||
LIBSSH2_FREE(session, packet);
|
LIBSSH2_FREE(session, packet);
|
||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
else {
|
||||||
return packet[0];
|
return packet_type;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
/* WON'T REACH */
|
/* WON'T REACH */
|
||||||
}
|
}
|
||||||
@@ -363,6 +443,10 @@ static void sftp_packetlist_flush(LIBSSH2_SFTP_HANDLE *handle)
|
|||||||
if(!rc)
|
if(!rc)
|
||||||
/* we found a packet, free it */
|
/* we found a packet, free it */
|
||||||
LIBSSH2_FREE(session, data);
|
LIBSSH2_FREE(session, data);
|
||||||
|
else if(chunk->sent)
|
||||||
|
/* there was no incoming packet for this request, mark this
|
||||||
|
request as a zombie if it ever sent the request */
|
||||||
|
add_zombie_request(sftp, chunk->request_id);
|
||||||
|
|
||||||
_libssh2_list_remove(&chunk->node);
|
_libssh2_list_remove(&chunk->node);
|
||||||
LIBSSH2_FREE(session, chunk);
|
LIBSSH2_FREE(session, chunk);
|
||||||
@@ -433,10 +517,7 @@ sftp_packet_require(LIBSSH2_SFTP *sftp, unsigned char packet_type,
|
|||||||
|
|
||||||
while (session->socket_state == LIBSSH2_SOCKET_CONNECTED) {
|
while (session->socket_state == LIBSSH2_SOCKET_CONNECTED) {
|
||||||
rc = sftp_packet_read(sftp);
|
rc = sftp_packet_read(sftp);
|
||||||
if (rc == LIBSSH2_ERROR_EAGAIN)
|
if (rc < 0)
|
||||||
return rc;
|
|
||||||
else if (rc <= 0)
|
|
||||||
/* TODO: isn't this supposed to be < 0 only? */
|
|
||||||
return rc;
|
return rc;
|
||||||
|
|
||||||
/* data was read, check the queue again */
|
/* data was read, check the queue again */
|
||||||
@@ -453,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,
|
||||||
@@ -639,7 +720,7 @@ static LIBSSH2_SFTP *sftp_init(LIBSSH2_SESSION *session)
|
|||||||
*
|
*
|
||||||
* Note that you MUST NOT try to call libssh2_sftp_init() again to get
|
* 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).
|
||||||
*/
|
*/
|
||||||
|
|
||||||
@@ -700,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;
|
||||||
|
|
||||||
@@ -762,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;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -775,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;
|
||||||
@@ -904,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);
|
||||||
|
|
||||||
@@ -1087,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;
|
||||||
|
|
||||||
@@ -1377,6 +1461,11 @@ 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 */
|
||||||
|
|
||||||
|
_libssh2_list_remove(&chunk->node);
|
||||||
|
LIBSSH2_FREE(session, chunk);
|
||||||
|
|
||||||
/* we must remove all outstanding READ requests, as either we
|
/* we must remove all outstanding READ requests, as either we
|
||||||
got an error or we're at end of file */
|
got an error or we're at end of file */
|
||||||
sftp_packetlist_flush(handle);
|
sftp_packetlist_flush(handle);
|
||||||
@@ -1401,6 +1490,14 @@ static ssize_t sftp_read(LIBSSH2_SFTP_HANDLE * handle, char *buffer,
|
|||||||
return _libssh2_error(session, LIBSSH2_ERROR_SFTP_PROTOCOL,
|
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
|
||||||
@@ -1521,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;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1536,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;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1860,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;
|
||||||
@@ -1919,6 +2016,99 @@ libssh2_sftp_write(LIBSSH2_SFTP_HANDLE *hnd, const char *buffer,
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int sftp_fsync(LIBSSH2_SFTP_HANDLE *handle)
|
||||||
|
{
|
||||||
|
LIBSSH2_SFTP *sftp = handle->sftp;
|
||||||
|
LIBSSH2_CHANNEL *channel = sftp->channel;
|
||||||
|
LIBSSH2_SESSION *session = channel->session;
|
||||||
|
/* 34 = packet_len(4) + packet_type(1) + request_id(4) +
|
||||||
|
string_len(4) + strlen("fsync@openssh.com")(17) + handle_len(4) */
|
||||||
|
uint32_t packet_len = handle->handle_len + 34;
|
||||||
|
size_t data_len;
|
||||||
|
unsigned char *packet, *s, *data;
|
||||||
|
ssize_t rc;
|
||||||
|
uint32_t retcode;
|
||||||
|
|
||||||
|
if (sftp->fsync_state == libssh2_NB_state_idle) {
|
||||||
|
_libssh2_debug(session, LIBSSH2_TRACE_SFTP,
|
||||||
|
"Issuing fsync command");
|
||||||
|
s = packet = LIBSSH2_ALLOC(session, packet_len);
|
||||||
|
if (!packet) {
|
||||||
|
return _libssh2_error(session, LIBSSH2_ERROR_ALLOC,
|
||||||
|
"Unable to allocate memory for FXP_EXTENDED "
|
||||||
|
"packet");
|
||||||
|
}
|
||||||
|
|
||||||
|
_libssh2_store_u32(&s, packet_len - 4);
|
||||||
|
*(s++) = SSH_FXP_EXTENDED;
|
||||||
|
sftp->fsync_request_id = sftp->request_id++;
|
||||||
|
_libssh2_store_u32(&s, sftp->fsync_request_id);
|
||||||
|
_libssh2_store_str(&s, "fsync@openssh.com", 17);
|
||||||
|
_libssh2_store_str(&s, handle->handle, handle->handle_len);
|
||||||
|
|
||||||
|
sftp->fsync_state = libssh2_NB_state_created;
|
||||||
|
} else {
|
||||||
|
packet = sftp->fsync_packet;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (sftp->fsync_state == libssh2_NB_state_created) {
|
||||||
|
rc = _libssh2_channel_write(channel, 0, packet, packet_len);
|
||||||
|
if (rc == LIBSSH2_ERROR_EAGAIN ||
|
||||||
|
(0 <= rc && rc < (ssize_t)packet_len)) {
|
||||||
|
sftp->fsync_packet = packet;
|
||||||
|
return LIBSSH2_ERROR_EAGAIN;
|
||||||
|
}
|
||||||
|
|
||||||
|
LIBSSH2_FREE(session, packet);
|
||||||
|
sftp->fsync_packet = NULL;
|
||||||
|
|
||||||
|
if (rc < 0) {
|
||||||
|
sftp->fsync_state = libssh2_NB_state_idle;
|
||||||
|
return _libssh2_error(session, LIBSSH2_ERROR_SOCKET_SEND,
|
||||||
|
"_libssh2_channel_write() failed");
|
||||||
|
}
|
||||||
|
sftp->fsync_state = libssh2_NB_state_sent;
|
||||||
|
}
|
||||||
|
|
||||||
|
rc = sftp_packet_require(sftp, SSH_FXP_STATUS,
|
||||||
|
sftp->fsync_request_id, &data, &data_len);
|
||||||
|
if (rc == LIBSSH2_ERROR_EAGAIN) {
|
||||||
|
return rc;
|
||||||
|
} else if (rc) {
|
||||||
|
sftp->fsync_state = libssh2_NB_state_idle;
|
||||||
|
return _libssh2_error(session, rc,
|
||||||
|
"Error waiting for FXP EXTENDED REPLY");
|
||||||
|
}
|
||||||
|
|
||||||
|
sftp->fsync_state = libssh2_NB_state_idle;
|
||||||
|
|
||||||
|
retcode = _libssh2_ntohu32(data + 5);
|
||||||
|
LIBSSH2_FREE(session, data);
|
||||||
|
|
||||||
|
if (retcode != LIBSSH2_FX_OK) {
|
||||||
|
sftp->last_errno = retcode;
|
||||||
|
return _libssh2_error(session, LIBSSH2_ERROR_SFTP_PROTOCOL,
|
||||||
|
"fsync failed");
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* libssh2_sftp_fsync
|
||||||
|
* Commit data on the handle to disk.
|
||||||
|
*/
|
||||||
|
LIBSSH2_API int
|
||||||
|
libssh2_sftp_fsync(LIBSSH2_SFTP_HANDLE *hnd)
|
||||||
|
{
|
||||||
|
int rc;
|
||||||
|
if(!hnd)
|
||||||
|
return LIBSSH2_ERROR_BAD_USE;
|
||||||
|
BLOCK_ADJUST(rc, hnd->sftp->channel->session,
|
||||||
|
sftp_fsync(hnd));
|
||||||
|
return rc;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* sftp_fstat
|
* sftp_fstat
|
||||||
*
|
*
|
||||||
@@ -2037,7 +2227,11 @@ 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)
|
||||||
|
return;
|
||||||
|
if(handle->u.file.offset == offset && handle->u.file.offset_sent == offset)
|
||||||
|
return;
|
||||||
|
|
||||||
handle->u.file.offset = handle->u.file.offset_sent = offset;
|
handle->u.file.offset = handle->u.file.offset_sent = offset;
|
||||||
/* discard all pending requests and currently read data */
|
/* discard all pending requests and currently read data */
|
||||||
sftp_packetlist_flush(handle);
|
sftp_packetlist_flush(handle);
|
||||||
@@ -2052,7 +2246,6 @@ libssh2_sftp_seek64(LIBSSH2_SFTP_HANDLE *handle, libssh2_uint64_t offset)
|
|||||||
/* reset EOF to False */
|
/* reset EOF to False */
|
||||||
handle->u.file.eof = FALSE;
|
handle->u.file.eof = FALSE;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
/* libssh2_sftp_seek
|
/* libssh2_sftp_seek
|
||||||
* Set the read/write pointer to an arbitrary position within the file
|
* Set the read/write pointer to an arbitrary position within the file
|
||||||
@@ -2091,13 +2284,15 @@ libssh2_sftp_tell64(LIBSSH2_SFTP_HANDLE *handle)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Flush all remaining incoming SFTP packets.
|
* Flush all remaining incoming SFTP packets and zombies.
|
||||||
*/
|
*/
|
||||||
static void sftp_packet_flush(LIBSSH2_SFTP *sftp)
|
static void sftp_packet_flush(LIBSSH2_SFTP *sftp)
|
||||||
{
|
{
|
||||||
LIBSSH2_CHANNEL *channel = sftp->channel;
|
LIBSSH2_CHANNEL *channel = sftp->channel;
|
||||||
LIBSSH2_SESSION *session = channel->session;
|
LIBSSH2_SESSION *session = channel->session;
|
||||||
LIBSSH2_SFTP_PACKET *packet = _libssh2_list_first(&sftp->packets);
|
LIBSSH2_SFTP_PACKET *packet = _libssh2_list_first(&sftp->packets);
|
||||||
|
struct sftp_zombie_requests *zombie =
|
||||||
|
_libssh2_list_first(&sftp->zombie_requests);
|
||||||
|
|
||||||
while(packet) {
|
while(packet) {
|
||||||
LIBSSH2_SFTP_PACKET *next;
|
LIBSSH2_SFTP_PACKET *next;
|
||||||
@@ -2111,12 +2306,25 @@ static void sftp_packet_flush(LIBSSH2_SFTP *sftp)
|
|||||||
packet = next;
|
packet = next;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
while(zombie) {
|
||||||
|
/* figure out the next node */
|
||||||
|
struct sftp_zombie_requests *next = _libssh2_list_next(&zombie->node);
|
||||||
|
/* unlink the current one */
|
||||||
|
_libssh2_list_remove(&zombie->node);
|
||||||
|
/* free the memory */
|
||||||
|
LIBSSH2_FREE(session, zombie);
|
||||||
|
zombie = next;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* sftp_close_handle
|
/* 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)
|
||||||
@@ -2125,20 +2333,20 @@ 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;
|
||||||
|
rc = _libssh2_error(session, LIBSSH2_ERROR_ALLOC,
|
||||||
"Unable to allocate memory for FXP_CLOSE "
|
"Unable to allocate memory for FXP_CLOSE "
|
||||||
"packet");
|
"packet");
|
||||||
}
|
} else {
|
||||||
|
|
||||||
_libssh2_store_u32(&s, packet_len - 4);
|
_libssh2_store_u32(&s, packet_len - 4);
|
||||||
*(s++) = SSH_FXP_CLOSE;
|
*(s++) = SSH_FXP_CLOSE;
|
||||||
@@ -2147,6 +2355,7 @@ sftp_close_handle(LIBSSH2_SFTP_HANDLE *handle)
|
|||||||
_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) {
|
||||||
rc = _libssh2_channel_write(channel, 0, handle->close_packet,
|
rc = _libssh2_channel_write(channel, 0, handle->close_packet,
|
||||||
@@ -2154,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) {
|
||||||
@@ -2172,30 +2379,31 @@ 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 {
|
||||||
|
int retcode = _libssh2_ntohu32(data + 5);
|
||||||
LIBSSH2_FREE(session, data);
|
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 */
|
||||||
_libssh2_list_remove(&handle->node);
|
_libssh2_list_remove(&handle->node);
|
||||||
@@ -2216,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
|
||||||
@@ -2476,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,
|
||||||
@@ -2519,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,
|
||||||
@@ -2589,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,
|
||||||
@@ -2632,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");
|
||||||
}
|
}
|
||||||
|
13
src/sftp.h
13
src/sftp.h
@@ -60,6 +60,11 @@ struct sftp_pipeline_chunk {
|
|||||||
unsigned char packet[1]; /* data */
|
unsigned char packet[1]; /* data */
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct sftp_zombie_requests {
|
||||||
|
struct list_node node;
|
||||||
|
uint32_t request_id;
|
||||||
|
};
|
||||||
|
|
||||||
#ifndef MIN
|
#ifndef MIN
|
||||||
#define MIN(x,y) ((x)<(y)?(x):(y))
|
#define MIN(x,y) ((x)<(y)?(x):(y))
|
||||||
#endif
|
#endif
|
||||||
@@ -136,6 +141,9 @@ struct _LIBSSH2_SFTP
|
|||||||
|
|
||||||
struct list_head packets;
|
struct list_head packets;
|
||||||
|
|
||||||
|
/* List of FXP_READ responses to ignore because EOF already received. */
|
||||||
|
struct list_head zombie_requests;
|
||||||
|
|
||||||
/* a list of _LIBSSH2_SFTP_HANDLE structs */
|
/* a list of _LIBSSH2_SFTP_HANDLE structs */
|
||||||
struct list_head sftp_handles;
|
struct list_head sftp_handles;
|
||||||
|
|
||||||
@@ -167,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,
|
|
||||||
"Would block waiting");
|
return _libssh2_error(session, rc,
|
||||||
|
"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) && (c = fgetc(fd)) != '\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,7 +1505,7 @@ 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) {
|
||||||
@@ -1510,12 +1514,9 @@ userauth_keyboard_interactive(LIBSSH2_SESSION * session,
|
|||||||
"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) {
|
||||||
@@ -1524,17 +1525,14 @@ userauth_keyboard_interactive(LIBSSH2_SESSION * session,
|
|||||||
"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,
|
||||||
@@ -1542,8 +1540,6 @@ userauth_keyboard_interactive(LIBSSH2_SESSION * session,
|
|||||||
"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
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user