Compare commits

..

203 Commits

Author SHA1 Message Date
Daniel Stenberg
e16f638dca RELEASE-NOTES: 1.5.0 release 2015-03-11 08:07:45 +01:00
Mariusz Ziulek
7d94b69b80 kex: bail out on rubbish in the incoming packet
CVE-2015-1782

Bug: http://www.libssh2.org/adv_20150311.html
2015-03-07 11:57:04 +01:00
Daniel Stenberg
8bb6cf7f95 docs: move INSTALL, AUTHORS, HACKING and TODO to docs/
And with this, cleanup README to be shorter and mention the new source
code home.
2015-03-07 11:42:14 +01:00
Daniel Stenberg
5fcbb168b8 .gitignore: don't ignore INSTALL 2015-03-07 11:32:08 +01:00
Dan Fandrich
d811750645 examples/x11.c: include sys/select.h for improved portability 2015-03-04 22:57:25 +01:00
Daniel Stenberg
cfe94c715e RELEASE-NOTES: synced with a8473c819b
In preparation for the upcoming 1.5.0 release.
2015-03-04 09:38:17 +01:00
Guenter Knauf
a8473c819b NetWare build: added some missing exports. 2015-01-08 21:03:17 +01:00
Marc Hoersken
c71889017f knownhost.c: fix use of uninitialized argument variable wrote
Detected by clang scan in	line 1195, column 18.
2014-12-29 18:37:46 +01:00
Marc Hoersken
253d5922f2 examples/x11.c: fix result of operation is garbage or undefined
Fix use of uninitialized structure w_size_bck.
Detected by clang scan in	line 386, column 28.
2014-12-29 18:31:11 +01:00
Marc Hoersken
79d63df12d examples/x11.c: remove dead assigments of some return values
Detected by clang scan in line 212, column 9.
Detected by clang scan in line 222, column 13.
Detected by clang scan in	line 410, column 13.
2014-12-29 18:24:17 +01:00
Marc Hoersken
86552bf2bb examples/x11.c: fix possible memory leak if read fails
Detected by clang scan in line 224, column 21.
2014-12-27 14:00:48 +01:00
Marc Hoersken
477e609a84 examples/x11.c: fix invalid removal of first list element
Fix use of memory after it was being freed.
Detected by clang scan in line 56, column 12.
2014-12-27 13:48:51 +01:00
Marc Hoersken
3e47ca8a32 userauth.c: make sure that sp_len is positive and avoid overflows
... if the pointer subtraction of sp1 - pubkey - 1 resulted in a
negative or larger value than pubkey_len, memchr would fail.

Reported by Coverity CID 89846.
2014-12-26 14:08:35 +01:00
Marc Hoersken
6af0ee567b channel.c: remove logically dead code, host cannot be NULL here
... host cannot be NULL in line 525, because it is always
valid (e.g. at least set to "0.0.0.0") after lines 430 and 431.

Reported by Coverity CID 89807.
2014-12-26 13:51:27 +01:00
Marc Hoersken
c6d99bd3a4 session.c: check return value of session_nonblock during startup
Reported by Coverity CID 89803.
2014-12-26 13:45:59 +01:00
Marc Hoersken
d1eccb487a session.c: check return value of session_nonblock in debug mode
Reported by Coverity CID 89805.
2014-12-26 13:40:42 +01:00
Marc Hoersken
22204c4e2e pem.c: fix mixed line-endings introduced with 8670f5da24 2014-12-26 13:39:18 +01:00
Marc Hoersken
8670f5da24 pem.c: make sure there's a trailing zero and b64data is not NULL
... if there is no base64 data between PEM header and footer.
Reported by Coverity CID 89823.
2014-12-26 13:31:26 +01:00
Marc Hoersken
3835655f09 kex.c: make sure mlist is not set to NULL
... if the currently unsupported LANG methods are called.
Reported by Coverity CID 89834.
2014-12-26 13:20:14 +01:00
Marc Hoersken
dc199ed03a packet.c: i < 256 was always true and i would overflow to 0
Visualize that the 0-termination is intentional, because the array
is later passed to strlen within _libssh2_packet_askv.
2014-12-26 11:21:10 +01:00
Marc Hoersken
8f799f98d9 silence multiple data conversion warnings 2014-12-26 11:05:34 +01:00
Daniel Stenberg
637c90959b agent_connect_unix: make sure there's a trailing zero
... if the path name was too long. Reported by Coverity CID 89801.
2014-12-23 20:05:16 +01:00
Marc Hoersken
8a731d6217 examples on Windows: use native SOCKET-type instead of int
And check return values accordingly.
2014-12-22 17:03:42 +01:00
Marc Hoersken
d85f9a689f userauth.c: improve readability and clarity of for-loops 2014-12-22 16:18:36 +01:00
Daniel Stenberg
031566f9cc calloc: introduce LIBSSH2_CALLOC()
A simple function using LIBSSH2_ALLOC + memset, since this pattern was
used in multiple places and this simplies code in general.
2014-12-22 15:59:21 +01:00
Marc Hoersken
977a3b6a76 libssh2_priv.h: Ignore session, context and format parameters 2014-12-15 01:16:00 +01:00
Marc Hoersken
34dc1d61b4 x11 example: check return value of socket function 2014-12-15 01:10:29 +01:00
Marc Hoersken
be95032e29 examples: fixed mixed line-endings introduced with aedfba25b8 2014-12-15 01:09:13 +01:00
Marc Hoersken
c0bface8a7 wincng.c: explicitly ignore BCrypt*AlgorithmProvider return codes
Fixes VS2012 code analysis warning C6031:
return value ignored: <function> could return unexpected value
2014-12-15 01:00:52 +01:00
Marc Hoersken
f31c9fb221 wincng.c: fix possible invalid memory write access
Fixes VS2012 code analysis warning C6386:
buffer overrun: accessing 'pbOutput', the writable size is
'cbOutput' bytes, but '3' bytes may be written: libssh2 wincng.c 610
2014-12-15 01:00:48 +01:00
Marc Hoersken
f89bed9571 tests on Windows: check for WSAStartup return code
Fixes VS2012 code analysis warning C6031:
return value ignored: <function> could return unexpected value
2014-12-15 01:00:36 +01:00
Marc Hoersken
bc9d735664 wincng.c: fix possible NULL pointer de-reference of bignum
Fixes VS2012 code analysis warning C6011:
dereferencing NULL pointer 'bignum'. libssh2 wincng.c 1567
2014-12-15 00:59:11 +01:00
Marc Hoersken
06ff22f1a6 wincng.c: fix possible use of uninitialized memory
Fixes VS2012 code analysis warning C6001:
using uninitialized memory 'cbDecoded'. libssh2 wincng.c 553
2014-12-15 00:59:09 +01:00
Marc Hoersken
e57f29f8f6 packet.c: fix possible NULL pointer de-reference within listen_state
Fixes VS2012 code analysis warning C6011:
dereferencing NULL pointer 'listen_state->channel'. libssh2 packet.c 221
2014-12-15 00:59:05 +01:00
Marc Hoersken
1c1699545b kex.c: fix possible NULL pointer de-reference with session->kex
Fixes VS2012 code analysis warning C6011:
dereferencing NULL pointer 'session->kex'. libssh2 kex.c 1761
2014-12-15 00:59:03 +01:00
Marc Hoersken
abcc0d370f agent.c: check return code of MapViewOfFile
Fixes VS2012 code analysis warning C6387: 'p+4' may be '0':
this does not adhere to the specification for the function
'memcpy': libssh2 agent.c 330

Fixes VS2012 code analysis warning C6387: 'p' may be '0':
this does not adhere to the specification for the function
'UnmapViewOfFile': libssh2 agent.c 333
2014-12-15 00:59:00 +01:00
Marc Hoersken
977dbb7511 examples on Windows: check for socket return code
Fixes VS2012 code analysis warning C28193:
The variable holds a value that must be examined
2014-12-15 00:58:57 +01:00
Marc Hoersken
aedfba25b8 examples on Windows: check for WSAStartup return code
Fixes VS2012 code analysis warning C6031:
return value ignored: <function> could return unexpected value
2014-12-15 00:58:56 +01:00
Guenter Knauf
19f1402f1d wincng.c: silent some more gcc compiler warnings. 2014-12-11 21:39:47 +01:00
Guenter Knauf
df5c61dbca wincng.c: silent gcc compiler warnings. 2014-12-11 21:35:18 +01:00
Guenter Knauf
1689315fce Watcom build: added support for WinCNG build. 2014-12-08 02:56:34 +01:00
Guenter Knauf
7f7e65c54b build: updated dependencies in makefiles. 2014-12-07 16:16:21 +01:00
Daniel Stenberg
751e0087a8 configure: change LIBS not LDFLAGS when checking for libs
Closes #289

Patch-by: maurerpe
2014-12-04 22:45:30 +01:00
Guenter Knauf
600f26ce6e MinGW build: some more GNUMakefile tweaks.
test/GNUmakefile: added architecture autodetection; added switches to
CFLAGS and RCFLAGS to make sure that the right architecture is used.
Added support to build with WinCNG.
2014-12-03 16:24:35 +01:00
Guenter Knauf
3260beb07a sftpdir.c: added authentication method detection.
Stuff copied over from ssh2.c to make testing a bit easier.
2014-12-03 15:19:32 +01:00
Guenter Knauf
01a6210ab7 NMake build: fixed LIBS settings. 2014-12-01 13:21:50 +01:00
Guenter Knauf
6a3b5487cb NMake build: added support for WinCNG build. 2014-11-30 18:39:57 +01:00
Guenter Knauf
e4ba5fabec MinGW build: some GNUMakefile tweaks.
Added architecture autodetection; added switches to CFLAGS and
RCFLAGS to make sure that the right architecture is used.
Added support to build with WinCNG.
2014-11-30 16:19:01 +01:00
Guenter Knauf
46f017e751 MinGW build: Fixed redefine warnings. 2014-11-30 16:03:58 +01:00
Guenter Knauf
12adbc28b8 Updated copyright year. 2014-11-30 15:48:55 +01:00
Daniel Stenberg
424a27e007 COPYING: bump the copyright year 2014-08-31 00:41:58 +02:00
Dan Fandrich
1e4fb7ee9f docs: fixed a bunch of typos 2014-07-28 23:55:34 +02:00
Dan Fandrich
7b80a188dd docs: added missing libssh2_session_handshake.3 file 2014-07-28 23:54:55 +02:00
Marc Hoersken
9d50d43a83 wincng.c: specify the required libraries for dependencies using MSVC
Initially reported by Bob Kast as "for MS VS builds, specify the
libraries that are required so they don't need to go into all
project files that may use this library". Thanks a lot.
2014-05-19 20:45:14 +02:00
Bob Kast
c355d31ff9 windows build: do not export externals from static library
If you are building a DLL, then you need to explicitly export each
entry point. When building a static library, you should not.

libssh2 was exporting the entry points whether it was building a DLL or a
static library. To elaborate further, if libssh2 was used as a static
library, which was being linked into a DLL, the libssh2 API would be
exported from that separate DLL.
2014-05-19 19:17:30 +02:00
Mikhail Gusarov
18fe507324 Fix typos in manpages 2014-05-19 10:24:58 +02:00
Marc Hoersken
d63e32dd30 wincng.c: Fixed memory leak in case of an error during ASN.1 decoding 2014-05-18 14:58:21 +02:00
Marc Hoersken
c32e82e97b configure: Display individual crypto backends on separate lines
This avoids line-wrapping in between parameters and makes the
error message look like the following:

configure: error: No crypto library found!
Try --with-libssl-prefix=PATH
 or --with-libgcrypt-prefix=PATH
 or --with-wincng on Windows
2014-05-18 12:47:42 +02:00
Bob Kast
7d4b5a8e07 libssh2_priv.h: a 1 bit bit-field should be unsigned
some compilers may not like this
2014-05-18 12:25:56 +02:00
Marc Hoersken
200784c4e7 knownhost.c: Fixed warning that pointer targets differ in signedness 2014-05-18 11:51:19 +02:00
Marc Hoersken
b22b23703c wincng.c: Fixed warning about pointer targets differing in signedness 2014-05-18 11:39:22 +02:00
Marc Hoersken
0e4e14109a tcpip-forward.c: Fixed warning that pointer targets differ in signedness
libssh2_channel_forward_listen_ex uses ints instead of unsigned ints.
2014-05-18 11:35:19 +02:00
Marc Hoersken
5bcc2d4629 misc.c: Fixed warning about mixed declarations and code 2014-05-18 11:15:49 +02:00
Marc Hoersken
33df559967 libgcrypt.h: Fixed warning about pointer targets differing in signedness 2014-05-18 10:57:36 +02:00
Marc Hoersken
26f6d71885 wincng.h: Fixed warning about pointer targets differing in signedness 2014-05-18 10:57:17 +02:00
Marc Hoersken
62c91e2cd4 misc.c: Fixed warning about unused parameter abstract 2014-05-18 10:23:18 +02:00
Marc Hoersken
b9dc6112d7 tcpip-forward.c: Removed unused variables shost, sport and sockopt 2014-05-18 10:16:24 +02:00
Marc Hoersken
106bacdebc wincng.h: Added forward declarations for all WinCNG functions
Initially reported by Bob Kast as "Wincng - define function
prototypes for wincng routines". Thanks a lot.

Also replaced structure definitions with type definitions.
2014-05-18 00:51:31 +02:00
Bob Kast
23dec383f7 libssh2.h: on Windows, a socket is of type SOCKET, not int 2014-05-18 00:25:47 +02:00
Marc Hoersken
fc94046e6e win32: Added WinCNG targets to generated Visual Studio project
Inspired by Bob Kast's reports, this commit enables the compilation
of libssh2 with WinCNG using the generated Visual Studio project files.
This commit adds WinCNG support to parts of the existing Win32 build
infrastructure, until new build systems, like pre-defined VS project
files or CMake files may be added.

This commit and b20bfeb3e5 raise one
question: How to handle build systems, like VS project files, that
need to include all source files regardless of the desired target,
including all supported crypto backends? For now the mentioned commit
added a check for LIBSSH2_OPENSSL to openssl.c and with this commit
the supported crypto backends are hardcoded within Makefile.am.
2014-05-18 00:07:59 +02:00
Marc Hoersken
ee547fe90d libssh2_priv msvc: Removed redundant definition of inline keyword
Initially reported by Bob Kast as "Remove redundant 'inline' define".
Thanks a lot.
2014-05-17 23:47:20 +02:00
Marc Hoersken
a58b0dacb4 wincng: Made data parameter to hash update function constant
Initially reported by Bob Kast as "formal parameter must be const
since it is used in contexts where the actual parameter may be const".
Thanks a lot.
2014-05-17 23:35:11 +02:00
Marc Hoersken
6e710d7fb6 wincng: fix cross-compilation against the w64 mingw-runtime package 2014-04-25 14:20:08 +02:00
Marc Hoersken
b20bfeb3e5 openssl: Check for LIBSSH2_OPENSSL in order to compile with openssl 2014-04-25 13:40:44 +02:00
Marc Hoersken
aba11380a1 wincng: Fixed use of possible uninitialized variable pPaddingInfo
Reported by Bob Kast, thanks a lot.
2014-03-22 23:23:18 +01:00
Marc Hoersken
2c46c4bf95 wincng: Added cast for double to unsigned long conversion 2014-03-22 23:12:59 +01:00
Marc Hoersken
160776d218 wincng: Cleaned up includes and check NTSTATUS using macro
Removed header file combination that is not supported on a real
Windows platform and can only be compiled using MinGW. Replaced
custom NTSTATUS return code checks with BCRYPT_SUCCESS macro.
2014-03-22 23:08:14 +01:00
Daniel Stenberg
ee2d61a48b userauth_hostbased_fromfile: zero assign to avoid uninitialized use
Detected by clang-analyze
2014-03-16 23:09:08 +01:00
Daniel Stenberg
fcb601da7b channel_receive_window_adjust: store windows size always
Avoid it sometimes returning without storing it, leaving calling
functions with unknown content!

Detected by clang-analyzer
2014-03-16 20:02:37 +01:00
Daniel Stenberg
55bae8dd07 publickey_packet_receive: avoid junk in returned pointers
clang-analyzer found this risk it would return a non-initialized pointer
in a success case
2014-03-16 19:44:17 +01:00
Marc Hoersken
4440e05d48 Added Windows Cryptography API: Next Generation based backend 2014-03-16 17:01:16 +01:00
Marc Hoersken
378d0a6676 knownhost.c: fixed that 'key_type_len' may be used uninitialized
../src/knownhost.c: In function 'libssh2_knownhost_readline':
../src/knownhost.c:651:16: warning: 'key_type_len' may be used
uninitialized in this function [-Wmaybe-uninitialized]
             rc = knownhost_add(hosts, hostbuf, NULL,
                ^
../src/knownhost.c:745:12: note: 'key_type_len' was declared here
     size_t key_type_len;
            ^
2014-03-16 16:38:55 +01:00
Marc Hoersken
21cb7bfb36 pem.c: always compile pem.c independently of crypto backend 2014-03-16 16:38:55 +01:00
Peter Stuge
e1a5d1bc77 Fix non-autotools builds: Always define the LIBSSH2_OPENSSL CPP macro
Commit d512b25f69 introduced a crypto
library abstraction in the autotools build system, to allow us to more
easily support new crypto libraries. In that process it was found that
all other build system which we support are hard-coded to build with
OpenSSL. Commit f5c1a0d98b fixes automake
introduced into non-autotools build systems but still overlooked the
CPP macro saying that we are using OpenSSL.

Thanks to Marc Hörsken for identifying this issue and proposing a fix
for win32/{GNUmakefile,config.mk}. This commit uses a slightly different
approach but the end result is the same.
2014-03-16 16:36:13 +01:00
Dan Fandrich
189cf86df0 channel_close: Close the channel even in the case of errors 2014-03-15 02:15:16 +01:00
Dan Fandrich
30e376773a sftp_close_handle: ensure the handle is always closed
Errors are reported on return, but otherwise the close path is
completed as much as possible and the handle is freed on exit.
2014-03-15 00:32:11 +01:00
Alexander Lamaison
38e210af0e knownhost: Restore behaviour of libssh2_knownhost_writeline with short buffer.
Commit 85c6627c changed the behaviour of `libssh2_knownhost_writeline` so that it stopped returning the number of bytes needed when the given buffer was too small.  Also, the function changed such that is might write to part of the buffer before realising it is too small.

This commit restores the original behaviour, whilst keeping the unknown-key-type functionality that 85c6627c.  Instead of writing to the buffer piecemeal, the length of the various parts is calculated up front and the buffer written only if there is enough space.  The calculated necessary size is output in `outlen` regardless of whether the buffer was written to.

The main use-case for the original behaviour that this commit restores is to allow passing in a NULL buffer to get the actual buffer size needed, before calling the function again with the buffer allocated to the exact size required.
2014-03-06 23:34:28 +00:00
Alexander Lamaison
d145e04443 knownhost: Fix DSS keys being detected as unknown.
I missing `else` meant ssh-dss format keys were being re-detected as unknown format.
2014-03-06 23:10:58 +00:00
Dan Fandrich
feab568a7a knownhosts: Abort if the hosts buffer is too small
This could otherwise cause a match on the wrong host
2014-03-06 14:08:56 +01:00
Dan Fandrich
08973a00a1 agent_list_identities: Fixed memory leak on OOM 2014-02-28 22:34:29 +01:00
Dan Fandrich
c00efa5f93 Fixed a few typos 2014-02-24 23:23:13 +01:00
Dan Fandrich
adc5db29e3 userauth: Fixed an attempt to free from stack on error 2014-02-24 23:23:13 +01:00
Dan Fandrich
92d686fe19 Fixed a few memory leaks in error paths 2014-02-24 23:23:13 +01:00
Dan Fandrich
5559ad8fe1 Fixed two potential use-after-frees of the payload buffer
The first might occur if _libssh2_packet_add returns an error, as
fullpacket_state wasn't reset to idle so if it were possible for
fullpacket to be called again, it would return to the same state
handler and re-use the freed p->packet buffer.

The second could occur if decrypt returned an error, as it freed the
packet buffer but did not clear total_num, meaning that freed buffer
could be written into again later.
2014-02-24 23:23:13 +01:00
Alexander Lamaison
88366b5ec2 Fix missing _libssh2_error in _libssh2_channel_write.
In one case, the error code from `_libssh2_transport_read` was being returned from `_libssh2_channel_write` without setting it as the last error by calling `_libssh2_error`.  This commit fixes that.

Found when using a session whose socket had been inadvertently destroyed.  The calling code got confused because via `libssh2_session_last_error` it appeared no error had occurred, despite one being returned from the previous function.
2013-11-28 23:37:05 +00:00
Mark McPherson
61df22c460 openssl: initialise the digest context before calling EVP_DigestInit()
When using the OpenSSL libraries in FIPS mode, the function call
EVP_DigestInit() is actually #defined to FIPS_digestinit().
Unfortunately wheres EVP_DigestInit() initialises the context and then
calls EVP_DigestInit_ex(), this function assumes that the context has
been pre-initialised and crashes when it isn't.

Bug: https://trac.libssh2.org/ticket/279

Fixes #279
2013-11-21 11:35:12 +01:00
Marc Hörsken
d808080daf .gitignore: Ignore files like src/libssh2_config.h.in~ 2013-11-20 14:24:34 +01:00
Peter Stuge
f5c1a0d98b Move automake conditionals added by commit d512b25f out of Makefile.inc
Commit d512b25f69 added automake
conditionals to Makefile.inc but since Makefile.inc is included
from Makefile for all other build systems that does not work.

This commit instead adds Makefile.OpenSSL.inc and Makefile.libgcrypt.inc
and moves the automake conditional to its proper place, src/Makefile.am.

The automake conditional includes the correct Makefile.$name.inc per
the crypto library selection/detection done by configure.

All non-autotools build system files in libssh2 are hardcoded to use
OpenSSL and do not get a conditional but at least there is some reuse
because they can all include the new Makefile.OpenSSL.inc.
2013-11-13 02:37:06 +01:00
Salvador Fandino
85a827d1bc Set default window size to 2MB
The default channel window size used until now was 256KB. This value is
too small and results on a bottleneck on real-life networks where
round-trip delays can easily reach 300ms.

The issue was not visible because the configured channel window size
was being ignored and a hard-coded value of ~22MB being used instead,
but that was fixed on a previous commit.

This patch just changes the default window size
(LIBSSH2_CHANNEL_WINDOW_DEFAULT) to 2MB. It is the same value used by
OpenSSH and in our opinion represents a good compromise between memory
used and transfer speed.

Performance tests were run to determine the optimum value. The details
and related discussion are available from the following thread on the
libssh2 mailing-list:

http://www.libssh2.org/mail/libssh2-devel-archive-2013-10/0018.shtml
http://article.gmane.org/gmane.network.ssh.libssh2.devel/6543

An excerpt follows:

"I have been running some transfer test and measuring their speed.

My setup was composed of a quad-core Linux machine running Ubuntu 13.10
x86_64 with a LXC container inside. The data transfers were performed
from the container to the host (never crossing through a physical
network device).

Network delays were simulated using the tc tool. And ping was used to
verify that they worked as intended during the tests.

The operation performed was the equivalent to the following ssh command:

  $ ssh container "dd bs=16K count=8K if=/dev/zero" >/dev/null

Though, establishment and closing of the SSH connection was excluded
from the timings.

I run the tests several times transferring files of sizes up to 128MB
and the results were consistent between runs.

The results corresponding to the 128MB transfer are available here:

https://docs.google.com/spreadsheet/ccc?key=0Ao1yRmX6PQQzdG5wSFlrZl9HRWNET3ZyN0hnaGo5ZFE&usp=sharing

It clearly shows that 256KB is too small as the default window size.
Moving to a 512MB generates a great improvement and after the 1MB mark
the returns rapidly diminish. Other factors (TCP window size, probably)
become more limiting than the channel window size

For comparison I also performed the same transfers using OpenSSH. Its
speed is usually on par with that of libssh2 using a window size of 1MB
(even if it uses a 2MB window, maybe it is less aggressive sending the
window adjust msgs)."

Signed-off-by: Salvador Fandino <sfandino@yahoo.com>
2013-10-27 13:50:20 +01:00
Salvador
1b3307dda0 _libssh2_channel_read: Honour window_size_initial
_libssh2_channel_read was using an arbitrary hard-coded limit to trigger
the window adjusting code. The adjustment used was also hard-coded and
arbitrary, 15MB actually, which would limit the usability of libssh2 on
systems with little RAM.

This patch, uses the window_size parameter passed to
libssh2_channel_open_ex (stored as remote.window_size_initial) plus the
buflen as the base for the trigger and the adjustment calculation.

The memory usage when using the default window size is reduced from 22MB
to 256KB per channel (actually, if compression is used, these numbers
should be incremented by ~50% to account for the errors between the
decompressed packet sizes and the predicted sizes).

My tests indicate that this change does not impact the performance of
transfers across localhost or a LAN, being it on par with that of
OpenSSH. On the other hand, it will probably slow down transfers on
networks with high bandwidth*delay when the default window size
(LIBSSH2_CHANNEL_WINDOW_DEFAULT=256KB) is used.

Signed-off-by: Salvador Fandino <sfandino@yahoo.com>
2013-10-27 13:49:33 +01:00
Salvador Fandino
85c6627c86 knownhosts: handle unknown key types
Store but don't use keys of unsupported types on the known_hosts file.

Currently, when libssh2 parses a known_host file containing keys of some
type it doesn't natively support, it stops reading the file and returns
an error.

That means, that the known_host file can not be safely shared with other
software supporting other key types (i.e. OpenSSH).

This patch adds support for handling keys of unknown type. It can read
and write them, even if they are never going to be matched.

At the source level the patch does the following things:

- add a new unknown key type LIBSSH2_KNOWNHOST_KEY_UNKNOWN

- add a new slot (key_type_name) on the known_host struct that is
used to store the key type in ascii form when it is not supported

- parse correctly known_hosts entries with unknown key types and
populate the key_type_name slot

- print correctly known_hosts entries of unknown type

- when checking a host key ignore keys that do not match the key

Fixes #276
2013-10-27 10:57:31 +01:00
Daniel Stenberg
c49cc8411f windows build: fix build errors
Fixes various link errors with VS2010

Reported-by: "kdekker"
Fixes #272
2013-10-16 23:23:26 +02:00
Daniel Stenberg
fa15fded72 man page: add missing function argument
for libssh2_userauth_publickey_fromfile_ex()

Reported-by: "pastey"

Fixes #262
2013-10-16 23:19:14 +02:00
Salvador
c2329aa09e Fix zlib deflate usage
Deflate may return Z_OK even when not all data has been compressed
if the output buffer becomes full.

In practice this is very unlikely to happen because the output buffer
size is always some KBs larger than the size of the data passed for
compression from the upper layers and I think that zlib never expands
the data so much, even on the worst cases.

Anyway, this patch plays on the safe side checking that the output
buffer is not exhausted.

Signed-off-by: Salvador <sfandino@yahoo.com>
2013-10-16 23:06:47 +02:00
Salvador
94077f7a58 comp_method_zlib_decomp: Improve buffer growing algorithm
The old algorithm was O(N^2), causing lots and lots of reallocations
when highly compressed data was transferred.

This patch implements a simpler one that just doubles the buffer size
everytime it is exhausted. It results in O(N) complexity.

Also a smaller inflate ratio is used to calculate the initial size (x4).

Signed-off-by: Salvador <sfandino@yahoo.com>
2013-10-16 23:05:40 +02:00
Salvador
55a8b10ad9 Fix zlib usage
Data may remain in zlib internal buffers when inflate() returns Z_OK
and avail_out == 0. In that case, inflate has to be called again.

Also, once all the data has been inflated, it returns Z_BUF_ERROR to
signal that the input buffer has been exhausted.

Until now, the way to detect that a packet payload had been completely
decompressed was to check that no data remained on the input buffer
but that didn't account for the case where data remained on the internal
zlib buffers.

That resulted in packets not being completely decompressed and the
missing data reappearing on the next packet, though the bug was masked
by the buffer allocation algorithm most of the time and only manifested
when transferring highly compressible data.

This patch fixes the zlib usage.

Signed-off-by: Salvador <sfandino@yahoo.com>
2013-10-16 22:55:29 +02:00
Salvador
27f9ac2549 _libssh2_channel_read: fix data drop when out of window
After filling the read buffer with data from the read queue, when the
window size was too small, "libssh2_channel_receive_window_adjust" was
called to increase it. In non-blocking mode that function could return
EAGAIN and, in that case, the EAGAIN was propagated upwards and the data
already read on the buffer lost.

The function was also moving between the two read states
"libssh2_NB_state_idle" and "libssh2_NB_state_created" both of which
behave in the same way (excepting a debug statment).

This commit modifies "_libssh2_channel_read" so that the
"libssh2_channel_receive_window_adjust" call is performed first (when
required) and if everything goes well, then it reads the data from the
queued packets into the read buffer.

It also removes the useless "libssh2_NB_state_created" read state.

Some rotted comments have also been updated.

Signed-off-by: Salvador <sfandino@yahoo.com>
2013-10-16 22:53:36 +02:00
Salvador Fandino
cdeef54967 window_size: redid window handling for flow control reasons
Until now, the window size (channel->remote.window_size) was being
updated just after receiving the packet from the transport layer.

That behaviour is wrong because the channel queue may grow uncontrolled
when data arrives from the network faster that the upper layer consumes
it.

This patch adds a new counter, read_avail, which keeps a count of the
bytes available from the packet queue for reading. Also, now the window
size is adjusted when the data is actually read by an upper layer.

That way, if the upper layer stops reading data, the window will
eventually fill and the remote host will stop sending data. When the
upper layers reads enough data, a window adjust packet is delivered and
the transfer resumes.

The read_avail counter is used to detect the situation when the remote
server tries to send data surpassing the window size. In that case, the
extra data is discarded.

Signed-off-by: Salvador <sfandino@yahoo.com>
2013-10-16 22:52:12 +02:00
Peter Stuge
42aefdba79 configure.ac: Call zlib zlib and not libz in text but keep option names 2013-09-15 21:13:27 +02:00
Peter Stuge
d41f5e40aa configure.ac: Reorder --with-* options in --help output 2013-09-15 21:13:03 +02:00
Peter Stuge
2df6cd6606 configure.ac: Rework crypto library detection
This further simplifies adding new crypto libraries.
2013-09-15 21:11:39 +02:00
Peter Stuge
d512b25f69 Clean up crypto library abstraction in build system and source code
libssh2 used to explicitly check for libgcrypt and default to OpenSSL.

Now all possible crypto libraries are checked for explicitly, making
the addition of further crypto libraries both simpler and cleaner.
2013-09-15 20:56:54 +02:00
Peter Stuge
b4f71fd25a configure.ac: Add zlib to Requires.private in libssh2.pc if using zlib 2013-09-15 20:36:58 +02:00
Peter Stuge
a5bf809b80 Revert "Added Windows Cryptography API: Next Generation based backend"
This reverts commit d385230e15.
2013-09-15 13:32:38 +02:00
Leif Salomonsson
2157e178a3 sftp_statvfs: fix for servers not supporting statfvs extension
Fixes issue arising when server does not support statfvs and or fstatvfs
extensions. sftp_statvfs() and sftp_fstatvfs() after this patch will
handle the case when SSH_FXP_STATUS is returned from server.
2013-09-07 23:11:54 +02:00
Marc Hoersken
d385230e15 Added Windows Cryptography API: Next Generation based backend 2013-09-07 22:38:14 +02:00
Kamil Dudka
61e40a32ff partially revert "window_size: explicit adjustments only"
This partially reverts commit 03ca902075
in order to fix extreme slowdown when uploading to localhost via SFTP.

I was able to repeat the issue on RHEL-7 on localhost only.  It did not
occur when uploading via network and it did not occur on a RHEL-6 box
with the same version of libssh2.

The problem was that sftp_read() used a read-ahead logic to figure out
the window_size, but sftp_packet_read() called indirectly from
sftp_write() did not use any read-ahead logic.
2013-09-07 22:30:34 +02:00
Daniel Stenberg
e6c46cc249 _libssh2_channel_write: client spins on write when window full
When there's no window to "write to", there's no point in waiting for
the socket to become writable since it most likely just will continue to
be.

Patch-by: ncm
Fixes #258
2013-09-07 13:41:14 +02:00
Daniel Stenberg
9f1b89e99b _libssh2_channel_forward_cancel: avoid memory leaks on error
Fixes #257
2013-09-07 13:37:59 +02:00
Daniel Stenberg
8da30ea4d4 _libssh2_packet_add: avoid using uninitialized memory
In _libssh2_packet_add, called by _libssh2_packet_read, a call to
_libssh2_packet_send that is supposed to send a one-byte message
SSH_MSG_REQUEST_FAILURE would send an uninitialized byte upon re-entry
if its call to _send returns _EAGAIN.

Fixes #259
2013-09-07 13:36:51 +02:00
Daniel Stenberg
ff6c01e959 _libssh2_channel_forward_cancel: accessed struct after free
... and the assignment was pointless anyway since the struct was about
to be freed. Bug introduced in dde2b094.

Fixes #268
2013-09-05 19:57:47 +02:00
Marc Hoersken
c910cd382d Fixed compilation using mingw-w64 2013-06-02 19:15:58 +02:00
Marc Hoersken
edd42304a2 knownhost.c: use LIBSSH2_FREE macro instead of free
Use LIBSSH2_FREE instead of free since
_libssh2_base64_encode uses LIBSSH2_ALLOC
2013-05-19 00:17:00 +02:00
Matthias Kerestesch
1ad20ac7d3 libssh2_agent_init: init ->fd to LIBSSH2_INVALID_SOCKET
... previously it was left at 0 which is a valid file descriptor!

Bug: https://trac.libssh2.org/ticket/265

Fixes #265
2013-05-18 23:03:18 +02:00
Daniel Stenberg
d7f9cd57c5 userauth_password: pass on the underlying error code
_libssh2_packet_requirev() may return different errors and we pass that
to the parent instead of rewriting it.

Bug: http://libssh2.org/mail/libssh2-devel-archive-2013-04/0029.shtml
Reported by: Cosmin
2013-05-18 23:03:18 +02:00
Marc Hoersken
16ef83dd81 libcrypt.c: Fix typo in _libssh2_rsa_sha1_sign() parameter type 2013-05-09 22:13:14 +02:00
Kamil Dudka
951904418b configure.ac: replace AM_CONFIG_HEADER with AC_CONFIG_HEADERS
Reported by: Quintus
Bug: https://trac.libssh2.org/ticket/261
2013-05-04 22:52:41 +02:00
Guenter Knauf
80e5e20b00 Fixed copyright string for NetWare build. 2013-04-12 18:00:29 +02:00
Richard W.M. Jones
6e0d757f24 sftp: Add support for fsync (OpenSSH extension).
The new libssh2_sftp_fsync API causes data and metadata in the
currently open file to be committed to disk at the server.

This is an OpenSSH extension to the SFTP protocol.  See:

https://bugzilla.mindrot.org/show_bug.cgi?id=1798
2013-04-09 16:25:54 +02:00
Richard W.M. Jones
a12f3ffab5 sftp: statvfs: Along error path, reset the correct 'state' variable. 2013-04-08 22:11:15 +02:00
Richard W.M. Jones
486bb37621 sftp: seek: Don't flush buffers on same offset
Signed-off-by: Richard W.M. Jones <rjones@redhat.com>
2013-03-27 15:46:51 +01:00
Guenter Knauf
fe347a702f Updated dependency libs. 2013-02-09 01:38:53 +01:00
Guenter Knauf
07615610ba Fixed tool macro names. 2012-12-04 11:52:08 +01:00
Seth Willits
5aa7b29758 compiler warnings: typecast strlen in macros
... in macro parameters to avoid compiler warnings about lost precision.

Several macros in libssh2.h call strlen and pass the result directly to
unsigned int parameters of other functions, which warns about precision
loss because strlen returns size_t which is unsigned long on at least
some platforms (such as OS X). The fix is to simply typecast the
strlen() result to unsigned int.
2012-11-29 20:30:04 +01:00
Daniel Stenberg
a67ff056e6 libssh2.h: bump version to 1.4.4-DEV 2012-11-27 23:03:45 +01:00
Daniel Stenberg
f1cfa55b60 RELEASE-NOTES: fixed for 1.4.3 2012-11-27 22:44:09 +01:00
Daniel Stenberg
437a3b75ec sftp_read: return error if a too large package arrives 2012-11-20 08:23:39 +01:00
Peter Stuge
a3ad635db4 Only define _libssh2_dsa_*() functions when building with DSA support 2012-11-13 00:11:47 +01:00
Guenter Knauf
e5c5408564 Added .def file to output. 2012-11-08 18:57:14 +01:00
Kamil Dudka
fe8f3deb48 libssh2_hostkey_hash.3: update the description of return value
The function returns NULL also if the hash algorithm is not available.
2012-11-01 15:04:07 +01:00
Guenter Knauf
d49b8f303a Fixed mode acciedently committed. 2012-10-24 03:41:10 +02:00
Guenter Knauf
6f8777505f Ignore generated file. 2012-10-24 03:29:50 +02:00
Guenter Knauf
52b8da7dfa Added hack to make use of Makefile.inc.
This should avoid further maintainance of the objects list.
2012-10-24 03:22:07 +02:00
Guenter Knauf
de7b5d3bc0 Fixed MSVC NMakefile.
Added missing source files; added resource for DLL.
2012-10-24 02:37:55 +02:00
Kamil Dudka
b31e35aba6 examples: use stderr for messages, stdout for data
Reported by: Karel Srot
Bug: https://bugzilla.redhat.com/867462
2012-10-22 13:39:58 +02:00
Kamil Dudka
e2bb780d77 openssl: do not leak memory when handling errors
,.. in aes_ctr_init().  Detected by Coverity.
2012-10-08 14:30:40 +02:00
Kamil Dudka
a8cfc708c5 channel: fix possible NULL dereference
... in libssh2_channel_get_exit_signal().  Detected by Coverity.
2012-10-08 14:19:23 +02:00
Kamil Dudka
9f6fd5af82 Revert "aes: the init function fails when OpenSSL has AES support"
This partially reverts commit f4f2298ef3.

We need to use the EVP_aes_???_ctr() functions in FIPS mode.
2012-09-17 09:48:07 +02:00
Kamil Dudka
5d567faecc crypt: use hard-wired cipher block sizes consistently 2012-09-17 09:48:07 +02:00
Kamil Dudka
bfbb5a4dc7 openssl: do not ignore failure of EVP_CipherInit() 2012-09-17 09:48:07 +02:00
Kamil Dudka
43b730ce56 kex: do not ignore failure of libssh2_md5_init()
The MD5 algorithm is disabled when running in FIPS mode.
2012-09-17 09:48:05 +02:00
Peter Krempa
6af85b6053 known_hosts: Fail when parsing unknown keys in known_hosts file.
libssh2_knownhost_readfile() silently ignored problems when reading keys
in unsupported formats from the known hosts file. When the file is
written again from the internal structures of libssh2 it gets truntcated
to the point where the first unknown key was located.

 * src/knownhost.c:libssh2_knownhost_readfile() - return error if key
                                                  parsing fails
2012-08-21 20:27:28 +02:00
Daniel Stenberg
05641218bc AUTHORS: synced with 42fec44c8a
31 recent authors added
2012-08-19 23:34:53 +02:00
Dave Hayden
42fec44c8a compression: add support for zlib@openssh.com
Add a "use_in_auth" flag to the LIBSSH2_COMP_METHOD struct and a
separate "zlib@openssh.com" method, along with checking session->state
for LIBSSH2_STATE_AUTHENTICATED. Appears to work on the OpenSSH servers
I've tried against, and it should work as before with normal zlib
compression.
2012-08-19 13:47:50 +02:00
Dmitry Smirnov
e470738a0c configure: gcrypt doesn't come with pkg-config support
... so use plain old -lgcrypt to the linker to link with it.

Fixes #225
2012-08-13 23:35:50 +02:00
Daniel Stenberg
62cc59cd06 sftp_read: Value stored to 'next' is never read
Detected by clang-analyzer
2012-08-08 15:18:43 +02:00
Daniel Stenberg
1abf2057de publickey_init: errors are negative, fix check
Detected by clang-analyzer.
2012-08-08 15:15:30 +02:00
Maxime Larocque
6c27922ac1 session_free: wrong variable used for keeping state
If libssh2_session_free is called without the channel being freed
previously by libssh2_channel_free a memory leak could occur.

A mismatch of states variables in session_free() prevent the call to
libssh2_channel_free function. session->state member is used instead of
session->free_state.

It causes a leak of around 600 bytes on every connection on my systems
(Linux, x64 and PPC).

(Debugging done under contract for Accedian Networks)

Fixes #246
2012-07-25 01:08:03 +02:00
Guenter Knauf
112845df0b Small NetWare makefile tweak. 2012-06-29 17:20:56 +02:00
Guenter Knauf
499b22ca36 Some small Win32 makefile fixes. 2012-06-20 18:08:01 +02:00
Daniel Stenberg
6403519fcf libssh2_userauth_publickey_fromfile_ex.3: mention publickey == NULL 2012-06-19 22:08:45 +02:00
Daniel Stenberg
6f8dd9baff comp_method_zlib_decomp: handle Z_BUF_ERROR when inflating
When using libssh2 to perform an SFTP file transfer from the "JSCAPE MFT
Server" (http://www.jscape.com) the transfer failed. The default JSCAPE
configuration is to enforce zlib compression on SSH2 sessions so the
session was compressed. The relevant part of the debug trace contained:

 [libssh2] 1.052750 Transport: unhandled zlib error -5
 [libssh2] 1.052750 Failure Event: -29 - decompression failure

The trace comes from comp_method_zlib_decomp() in comp.c. The "unhandled
zlib error -5" is the status returned from the zlib function
inflate(). The -5 status corresponds to "Z_BUF_ERROR".

The inflate() function takes a pointer to a z_stream structure and
"inflates" (decompresses) as much as it can. The relevant fields of the
z_stream structure are:

  next_in - pointer to the input buffer containing compressed data
  avail_in - the number of bytes available at next_in
  next_out - pointer to the output buffer to be filled with uncompressed
             data
  avail_out - how much space available at next_out

To decompress data you set up a z_stream struct with the relevant fields
filled in and pass it to inflate(). On return the fields will have been
updated so next_in and avail_in show how much compressed data is yet to
be processed and next_out and avail_out show how much space is left in
the output buffer.

If the supplied output buffer is too small then on return there will be
compressed data yet to be processed (avail_in != 0) and inflate() will
return Z_OK. In this case the output buffer must be grown, avail_out
updated and inflate() called again.

If the supplied output buffer was big enough then on return the
compressed data will have been exhausted (avail_in == 0) and inflate()
will return Z_OK, so the data has all been uncompressed.

There is a corner case where inflate() makes no progress. That is, there
may be unprocessed compressed data and space available in the output
buffer and yet the function does nothing. In this case inflate() will
return Z_BUF_ERROR. From the zlib documentation and the source code it
is not clear under what circumstances this happens. It could be that it
needs to write multiple bytes (all in one go) from its internal state to
the output buffer before processing the next chunk of input but but
can't because there is not enough space (though my guesses as to the
cause are not really relevant). Recovery from Z_BUF_ERROR is pretty
simple - just grow the output buffer, update avail_out and call
inflate() again.

The comp_method_zlib_decomp() function does not handle the case when
inflate() returns Z_BUF_ERROR. It treats it as a non-recoverable error
and basically aborts the session.

Fixes #240
2012-06-14 16:11:48 +02:00
Guenter Knauf
a1c0d97ff9 MinGW makefile tweaks.
Use GNU tools when compiling on Linux.
Fixed dist and dev targets.
2012-06-12 01:03:14 +02:00
Guenter Knauf
5c065bf1ff NetWare makefile tweaks.
Changed to use Windows commandline tools instead of
GNU tools when compiling on Windows. Fixed dist and
dev targets. Enabled nlmconv error for unresolved
symbols.
2012-06-12 00:34:18 +02:00
Daniel Stenberg
5237177daf Revert "config.rpath: generated file, no need to keep in git"
This reverts commit 1ac7bd09cc.

This file still used by lib/*m4 functions so we need to keep the file
around.
2012-06-11 14:52:31 +02:00
Daniel Stenberg
bd627d38a1 BINDINGS: added PySsh2, a Python-ctypes binding 2012-06-09 00:14:17 +02:00
Guenter Knauf
c55b0b0425 Fixed MinGW debug build. 2012-06-08 08:03:24 +02:00
Daniel Stenberg
38efbe8243 BINDINGS: Added the Cocoa/Objective-C one
... and sorted the bindings after the languages, alphabetically

Reported by: Mike Abdullah
2012-06-05 15:43:50 +02:00
Daniel Stenberg
34ecc09a3c BINDINGS: document the bindings we know of 2012-06-05 11:40:51 +02:00
Guenter Knauf
d6cf1c7df0 Fixed LIBSSH2_INT64_T_FORMAT macro.
Usually a format macro should hold the whole format, otherwise
it should be named a prefix. Also fixed usage of this macro in
scp.c for a signed var where it was used as prefix for unsigned.
2012-06-04 22:54:25 +02:00
Guenter Knauf
a40c160cff Removed obsolete define from makefiles. 2012-06-04 17:01:27 +02:00
Guenter Knauf
29e256e817 Renamed NetWare makefiles. 2012-06-04 15:27:02 +02:00
Guenter Knauf
137342a41d Renamed NetWare makefiles. 2012-06-04 15:24:39 +02:00
Guenter Knauf
79a7ca3085 Synced MinGW makefiles with 56c64a6..39e438f.
Also synced MinGW test makefile with b092696..f8cb874.
2012-06-04 15:17:22 +02:00
Peter Stuge
50e37bdadc Revert "sftp: Don't send attrs.permissions on read-only SSH_FXP_OPEN"
This reverts commit 04e79e0c79.
2012-05-30 17:50:37 +02:00
Peter Stuge
04e79e0c79 sftp: Don't send attrs.permissions on read-only SSH_FXP_OPEN
This works around a protocol violation in the ProFTPD 1.3.4 mod_sftp
server, as reported by Will Cosgrove in:

http://libssh2.org/mail/libssh2-devel-archive-2012-05/0079.shtml

Based on a suggested fix by TJ Saunders in:

http://libssh2.org/mail/libssh2-devel-archive-2012-05/0104.shtml
2012-05-30 15:29:25 +02:00
Guenter Knauf
9a36065b52 Try to detect OpenSSL build type automatically.
Also fixed recently added libgdi32 linkage which is only
required when OpenSSL libs are linked statically.
2012-05-28 12:53:15 +02:00
Daniel Stenberg
1ac7bd09cc config.rpath: generated file, no need to keep in git 2012-05-25 09:07:18 +02:00
Guenter Knauf
9a7311ba57 Updated dependency libary versions. 2012-05-22 04:10:52 +02:00
Daniel Stenberg
e07b11b7df 1.4.3: towards the future 2012-05-18 23:44:07 +02:00
Daniel Stenberg
e885300b18 RELEASE-NOTES: synced with 92a9f95279 2012-05-18 23:30:04 +02:00
Alexander Lamaison
92a9f95279 win32/libssh2_config.h: Remove hardcoded #define LIBSSH2_HAVE_ZLIB.
Rationale: Everything else in this file states a fact about the win32
platform that is unconditional for that platform.  There is nothing
unconditional about the presence of zlib.  It is neither included with
Windows nor with the platform SDK.  Therefore, this is not an appropriate
place to assert its presence.  Especially as, once asserted, it cannot be
overridden using a compiler flag.

In contrast, if it is omitted, then it can easily be reasserted by adding
a compiler flag defining LIBSSH2_HAVE_ZLIB.
2012-05-15 17:32:06 +01:00
Daniel Stenberg
e91d4c9790 RELEASE-NOTES: synced with 69a3354467 2012-05-14 22:49:53 +02:00
Daniel Stenberg
69a3354467 _libssh2_packet_add: SSH_MSG_CHANNEL_REQUEST default to want_reply
RFC4254 says the default 'want_reply' is TRUE but the code defaulted to
FALSE. Now changed.

Fixes #233
2012-05-14 22:42:42 +02:00
Daniel Stenberg
3ede6e280e gettimeofday: no need for a replacement under cygwin
Fixes #224
2012-05-14 22:32:36 +02:00
Alexander Lamaison
b583311a93 Prevent sftp_packet_read accessing freed memory.
sftp_packet_add takes ownership of the packet passed to it and (now that we
handle zombies) might free the packet.  sftp_packet_read uses the packet type
byte as its return code but by this point sftp_packet_add might have freed
it.  This change fixes the problem by caching the packet type before calling
sftp_packet_add.

I don't understand why sftp_packet_read uses the packet type as its return
code.  A future change might get rid of this entirely.
2012-05-13 15:56:54 +01:00
Daniel Stenberg
27ac5aa40d sftp_packet_flush: flush zombies too
As this function is called when the SFTP session is closed, it needs to
also kill all zombies left in the SFTP session to avoid leaking memory
just in case some zombie would still be in there.
2012-05-12 22:42:40 +02:00
Daniel Stenberg
a123051200 sftp_packetlist_flush: zombies must not have responses already
When flushing the packetlist, we must only add the request as a zombie
if no response has already been received. Otherwise we could wrongly
make it a zombie even though the response was already received and then
we'd get a zombie stuck there "forever"...
2012-05-12 22:37:20 +02:00
Daniel Stenberg
62901253a4 sftp_read: on EOF remove packet before flush
Since the sftp_packetlist_flush() function will move all the existing
FXP_READ requests in this handle to the zombie list we must first remove
this just received packet as it is clearly not a zombie.
2012-05-10 23:11:07 +02:00
Daniel Stenberg
7c5ee0fa66 sftp_packet_require: sftp_packet_read() returning 0 is not an error
Exactly as the comment in the code said, checking the return code from
sftp_packet_read() with <= was wrong and it should be < 0. With the new
filtering on incoming packets that are "zombies" we can now see this
getting zero returned.
2012-05-10 23:09:37 +02:00
Daniel Stenberg
1e15075a8e sftp_packetlist_flush: only make it zombie if it was sent
The list of outgoing packets may also contain packets that never were
sent off and we better not make them zombies too.
2012-05-10 23:08:23 +02:00
Alexander Lamaison
ad63fc2df6 Mark outstanding read requests after EOF as zombies.
In order to be fast, sftp_read sends many read requests at once.  With a small
file, this can mean that when EOF is received back, many of these requests are
still outstanding.  Responses arriving after we close the file and abandon the
file handle are queued in the SFTP packet queue and never collected.  This
causes transfer speed to drop as a progressively longer queue must be searched
for every packet.

This change introduces a zombie request-ID list in the SFTP session that is
used to recognise these outstanding requests and prevent them being added to
the queue.
2012-05-10 19:35:25 +02:00
Rafael Kitover
d46185eaa5 Update win32/GNUmakefile to use OpenSSL 1.0.1a
libcrypto on win32 now depends on gdi32.dll, so move the OpenSSL LDLIBS
block to before the compiler definitions, so that libcrypto gets added
first, and then add -lgdi32 into the following common LDLIBS for gcc.
2012-04-23 20:04:41 +02:00
Guenter Knauf
9c4b380dd6 Changed 'Requires' to 'Requires.private'.
Only static builds need to link against the crypto libs.
2012-04-23 12:33:08 +02:00
Guenter Knauf
e887a8bd0f Fixed 'Requires:' names.
The 'Requires:' line lists the names of the .pc files.
2012-04-23 01:11:22 +02:00
Guenter Knauf
04692445d4 Added 'Requires:' line to libssh2.pc.
This is necessary so that other libs which lookup libssh2 info
via pkg-config can add the right crypto lib dependencies.
2012-04-23 00:35:03 +02:00
Guenter Knauf
a955f8428b Updated dependency lib versions. 2012-04-20 13:50:06 +02:00
Peter Stuge
ededdfa9c2 configure.ac: Add option to disable build of the example applications
Examples are built by default. Any of the following options on the
configure command line will skip building them:

  --disable-examples-build
  --enable-examples-build=no
  --enable-examples-build=false
2012-04-18 16:35:05 +02:00
Peter Stuge
11f9dce3d7 userauth.c: fread() from public key file to correctly detect any errors
If the filename parameter for file_read_publickey() was the name of a
directory instead of a file then libssh2 would spin trying to fgetc()
from the FILE * for the opened directory when trying to determine the
length of the encoded public key, since fgetc() can't report errors.

Use fread() instead to correctly detect this error condition along
with many others.

This fixes the problem reported in
http://www.libssh2.org/mail/libssh2-devel-archive-2012-04/0021.shtml

Reported-by: Oleksiy Zagorskyi <zalex_ua@i.ua>
2012-04-18 12:23:04 +02:00
Peter Stuge
6bbebcf36c Return LIBSSH2_ERROR_SOCKET_DISCONNECT on EOF when reading banner 2012-04-18 12:23:04 +02:00
Guenter Knauf
7a87bba02a Fixed copyright year. 2012-04-17 17:29:49 +02:00
Guenter Knauf
c8374cdc10 Updated dependency lib versions in static makefiles. 2012-04-12 22:01:45 +02:00
Daniel Stenberg
9b2bed22fc version: bump to 1.4.2
We're on the 1.4.2 track now (at least)
2012-04-06 15:28:18 +02:00
109 changed files with 5167 additions and 1243 deletions

2
.gitignore vendored
View File

@@ -24,7 +24,6 @@ ltmain.sh
missing
ssh2_sample
libssh2-*.tar.gz
INSTALL
install-sh
*.o
*.lo
@@ -33,3 +32,4 @@ mkinstalldirs
tags
libssh2.pc
TAGS
*~

View File

@@ -2,7 +2,7 @@
* Copyright (c) 2005,2006 Mikhail Gusarov <dottedmag@dottedmag.net>
* Copyright (c) 2006-2007 The Written Word, Inc.
* Copyright (c) 2007 Eli Fant <elifantu@mail.ru>
* Copyright (c) 2009 Daniel Stenberg
* Copyright (c) 2009-2014 Daniel Stenberg
* Copyright (C) 2008, 2009 Simon Josefsson
* All rights reserved.
*

2
Makefile.OpenSSL.inc Normal file
View File

@@ -0,0 +1,2 @@
CRYPTO_CSOURCES = openssl.c
CRYPTO_HHEADERS = openssl.h

2
Makefile.WinCNG.inc Normal file
View File

@@ -0,0 +1,2 @@
CRYPTO_CSOURCES = wincng.c
CRYPTO_HHEADERS = wincng.h

View File

@@ -1,6 +1,9 @@
AUTOMAKE_OPTIONS = foreign nostdinc
SUBDIRS = src example tests docs
SUBDIRS = src tests docs
if BUILD_EXAMPLES
SUBDIRS += example
endif
pkgconfigdir = $(libdir)/pkgconfig
pkgconfig_DATA = libssh2.pc
@@ -11,10 +14,9 @@ include_HEADERS = \
include/libssh2_sftp.h
NETWAREFILES = nw/keepscreen.c \
nw/Makefile \
nw/Makefile.netware \
nw/nwlib.c \
nw/test/Makefile.netware
nw/nwlib.c \
nw/GNUmakefile \
nw/test/GNUmakefile
DSP = win32/libssh2.dsp
VCPROJ = win32/libssh2.vcproj
@@ -30,8 +32,8 @@ win32/libssh2_config.h win32/config.mk win32/rules.mk \
win32/Makefile.Watcom win32/libssh2.dsw win32/tests.dsp $(DSP) \
win32/msvcproj.head win32/msvcproj.foot win32/libssh2.rc
EXTRA_DIST = $(WIN32FILES) buildconf $(NETWAREFILES) get_ver.awk HACKING \
maketgz NMakefile TODO RELEASE-NOTES libssh2.pc.in $(VMSFILES)
EXTRA_DIST = $(WIN32FILES) buildconf $(NETWAREFILES) get_ver.awk \
maketgz NMakefile RELEASE-NOTES libssh2.pc.in $(VMSFILES) config.rpath
ACLOCAL_AMFLAGS = -I m4
@@ -73,6 +75,9 @@ gen-coverage:
coverage: init-coverage build-coverage gen-coverage
# DSP/VCPROJ generation adapted from libcurl
# only OpenSSL and WinCNG are supported with this build system
CRYPTO_CSOURCES = openssl.c wincng.c
CRYPTO_HHEADERS = openssl.h wincng.h
# Makefile.inc provides the CSOURCES and HHEADERS defines
include Makefile.inc

View File

@@ -1,7 +1,6 @@
CSOURCES = channel.c comp.c crypt.c hostkey.c kex.c mac.c misc.c \
packet.c publickey.c scp.c session.c sftp.c userauth.c transport.c \
version.c knownhost.c agent.c openssl.c libgcrypt.c pem.c keepalive.c \
global.c
version.c knownhost.c agent.c $(CRYPTO_CSOURCES) pem.c keepalive.c global.c
HHEADERS = libssh2_priv.h openssl.h libgcrypt.h transport.h channel.h \
comp.h mac.h misc.h packet.h userauth.h session.h sftp.h crypto.h
HHEADERS = libssh2_priv.h $(CRYPTO_HHEADERS) transport.h channel.h comp.h \
mac.h misc.h packet.h userauth.h session.h sftp.h crypto.h

2
Makefile.libgcrypt.inc Normal file
View File

@@ -0,0 +1,2 @@
CRYPTO_CSOURCES = libgcrypt.c
CRYPTO_HHEADERS = libgcrypt.h

View File

@@ -1,19 +1,33 @@
!include "win32/config.mk"
!if "$(WITH_WINCNG)" == "1"
!include "Makefile.WinCNG.inc"
!else
!include "Makefile.OpenSSL.inc"
!endif
!include "Makefile.inc"
OBJECTS=$(CSOURCES:.c=.obj)
# SUBDIRS=src example
SUBDIRS=src
all-sub:
all-sub: win32\objects.mk
-for %D in ($(SUBDIRS)) do $(MAKE) /nologo /f %D/NMakefile BUILD=$(BUILD) SUBDIR=%D all-sub
clean:
-rmdir /s/q $(TARGET)
-rmdir 2>NUL /s/q $(TARGET)
-del 2>NUL win32\objects.mk
real-clean: clean
-del libssh2.dll
-del libssh2.exp
-del libssh2.ilk
-del libssh2.lib
-del *.pdb
real-clean vclean: clean
-del 2>NUL libssh2.dll
-del 2>NUL libssh2.exp
-del 2>NUL libssh2.ilk
-del 2>NUL libssh2.lib
-del 2>NUL *.pdb
win32\objects.mk: Makefile.inc
@echo OBJECTS = \>$@
@for %O in ($(OBJECTS)) do @echo $$(INTDIR)\%O \>>$@
@echo $$(EOL)>>$@

88
README
View File

@@ -8,90 +8,10 @@ Web site: http://www.libssh2.org/
Mailing list: http://cool.haxx.se/mailman/listinfo/libssh2-devel
Generic installation instructions are in INSTALL. Some ./configure
options deserve additional comments:
License: see COPYING
* --enable-crypt-none
Source code: https://github.com/bagder/libssh2
The SSH2 Transport allows for unencrypted data
transmission using the "none" cipher. Because this is
such a huge security hole, it is typically disabled on
SSH2 implementations and is disabled in libssh2 by
default as well.
Web site source code: https://github.com/bagder/libssh2-www
Enabling this option will allow for "none" as a
negotiable method, however it still requires that the
method be advertized by the remote end and that no
more-preferable methods are available.
* --enable-mac-none
The SSH2 Transport also allows implementations to
forego a message authentication code. While this is
less of a security risk than using a "none" cipher, it
is still not recommended as disabling MAC hashes
removes a layer of security.
Enabling this option will allow for "none" as a
negotiable method, however it still requires that the
method be advertized by the remote end and that no
more-preferable methods are available.
* --disable-gex-new
The diffie-hellman-group-exchange-sha1 (dh-gex) key
exchange method originally defined an exchange
negotiation using packet type 30 to request a
generation pair based on a single target value. Later
refinement of dh-gex provided for range and target
values. By default libssh2 will use the newer range
method.
If you experience trouble connecting to an old SSH
server using dh-gex, try this option to fallback on
the older more reliable method.
* --with-libgcrypt
* --without-libgcrypt
* --with-libgcrypt-prefix=DIR
libssh2 can use the Libgcrypt library
(http://www.gnupg.org/) for cryptographic operations.
Either Libgcrypt or OpenSSL is required.
Configure will attempt to locate Libgcrypt
automatically.
If your installation of Libgcrypt is in another
location, specify it using --with-libgcrypt-prefix.
* --with-openssl
* --without-openssl
* --with-libssl-prefix=[DIR]
libssh2 can use the OpenSSL library
(http://www.openssl.org) for cryptographic operations.
Either Libgcrypt or OpenSSL is required.
Configure will attempt to locate OpenSSL in the
default location.
If your installation of OpenSSL is in another
location, specify it using --with-libssl-prefix.
* --with-libz
* --without-libz
* --with-libz-prefix=[DIR]
If present, libssh2 will attempt to use the zlib
(http://www.zlib.org) for payload compression, however
zlib is not required.
If your installation of Libz is in another location,
specify it using --with-libz-prefix.
* --enable-debug
Will make the build use more pedantic and strict compiler
options as well as enable the libssh2_trace() function (for
showing debug traces).
Installation instructions are in docs/INSTALL

View File

@@ -1,28 +1,83 @@
libssh2 1.4.1
libssh2 1.5.0
This release includes the following changes:
o Added Windows Cryptography API: Next Generation based backend
This release includes the following bugfixes:
o build error with gcrypt backend
o always do "forced" window updates to avoid corner case stalls
o aes: the init function fails when OpenSSL has AES support
o transport_send: Finish in-progress key exchange before sending data
o channel_write: acknowledge transport errors
o examples/x11.c: Make sure sizeof passed to read operation is correct
o examples/x11.c:,Fix suspicious sizeof usage
o sftp_packet_add: verify the packet before accepting it
o SFTP: preserve the original error code more
o sftp_packet_read: adjust window size as necessary
o Use safer snprintf rather then sprintf in several places
o Define and use LIBSSH2_INVALID_SOCKET instead of INVALID_SOCKET
o sftp_write: cannot return acked data *and* EAGAIN
o sftp_read: avoid data *and* EAGAIN
o libssh2.h: Add missing prototype for libssh2_session_banner_set()
o Security Advisory for CVE-2015-1782, using SSH_MSG_KEXINIT data unbounded
o missing _libssh2_error in _libssh2_channel_write
o knownhost: Fix DSS keys being detected as unknown.
o knownhost: Restore behaviour of `libssh2_knownhost_writeline` with short buffer.
o libssh2.h: on Windows, a socket is of type SOCKET, not int
o libssh2_priv.h: a 1 bit bit-field should be unsigned
o windows build: do not export externals from static library
o Fixed two potential use-after-frees of the payload buffer
o Fixed a few memory leaks in error paths
o userauth: Fixed an attempt to free from stack on error
o agent_list_identities: Fixed memory leak on OOM
o knownhosts: Abort if the hosts buffer is too small
o sftp_close_handle: ensure the handle is always closed
o channel_close: Close the channel even in the case of errors
o docs: added missing libssh2_session_handshake.3 file
o docs: fixed a bunch of typos
o userauth_password: pass on the underlying error code
o _libssh2_channel_forward_cancel: accessed struct after free
o _libssh2_packet_add: avoid using uninitialized memory
o _libssh2_channel_forward_cancel: avoid memory leaks on error
o _libssh2_channel_write: client spins on write when window full
o windows build: fix build errors
o publickey_packet_receive: avoid junk in returned pointers
o channel_receive_window_adjust: store windows size always
o userauth_hostbased_fromfile: zero assign to avoid uninitialized use
o configure: change LIBS not LDFLAGS when checking for libs
o agent_connect_unix: make sure there's a trailing zero
o MinGW build: Fixed redefine warnings.
o sftpdir.c: added authentication method detection.
o Watcom build: added support for WinCNG build.
o configure.ac: replace AM_CONFIG_HEADER with AC_CONFIG_HEADERS
o sftp_statvfs: fix for servers not supporting statfvs extension
o knownhost.c: use LIBSSH2_FREE macro instead of free
o Fixed compilation using mingw-w64
o knownhost.c: fixed that 'key_type_len' may be used uninitialized
o configure: Display individual crypto backends on separate lines
o examples on Windows: check for WSAStartup return code
o examples on Windows: check for socket return code
o agent.c: check return code of MapViewOfFile
o kex.c: fix possible NULL pointer de-reference with session->kex
o packet.c: fix possible NULL pointer de-reference within listen_state
o tests on Windows: check for WSAStartup return code
o userauth.c: improve readability and clarity of for-loops
o examples on Windows: use native SOCKET-type instead of int
o packet.c: i < 256 was always true and i would overflow to 0
o kex.c: make sure mlist is not set to NULL
o session.c: check return value of session_nonblock in debug mode
o session.c: check return value of session_nonblock during startup
o userauth.c: make sure that sp_len is positive and avoid overflows
o knownhost.c: fix use of uninitialized argument variable wrote
o openssl: initialise the digest context before calling EVP_DigestInit()
o libssh2_agent_init: init ->fd to LIBSSH2_INVALID_SOCKET
o configure.ac: Add zlib to Requires.private in libssh2.pc if using zlib
o configure.ac: Rework crypto library detection
o configure.ac: Reorder --with-* options in --help output
o configure.ac: Call zlib zlib and not libz in text but keep option names
o Fix non-autotools builds: Always define the LIBSSH2_OPENSSL CPP macro
o sftp: seek: Don't flush buffers on same offset
o sftp: statvfs: Along error path, reset the correct 'state' variable.
o sftp: Add support for fsync (OpenSSH extension).
o _libssh2_channel_read: fix data drop when out of window
o comp_method_zlib_decomp: Improve buffer growing algorithm
o _libssh2_channel_read: Honour window_size_initial
o window_size: redid window handling for flow control reasons
o knownhosts: handle unknown key types
This release would not have looked like this without help, code, reports and
advice from friends like these:
Armen Babakhanian, Paul Howarth, Matthew Booth, Steven Dake, Peter Stuge,
Matt Lawson, Tom Weber, Alexander Lamaison
Alexander Lamaison, Bob Kast, Dan Fandrich, Daniel Stenberg, Guenter Knauf,
Kamil Dudka, Leif Salomonsson, Marc Hörsken, Mark McPherson,
Matthias Kerestesch, Mikhail Gusarov, Peter Stuge, Richard W.M. Jones,
Salvador Fandino, Seth Willits, Mariusz Ziulek
Thanks! (and sorry if I forgot to mention someone)

View File

@@ -2,7 +2,7 @@
AC_INIT(libssh2, [-], libssh2-devel@cool.haxx.se)
AC_CONFIG_MACRO_DIR([m4])
AC_CONFIG_SRCDIR([src])
AM_CONFIG_HEADER([src/libssh2_config.h example/libssh2_config.h])
AC_CONFIG_HEADERS([src/libssh2_config.h example/libssh2_config.h])
AM_MAINTAINER_MODE
dnl SED is needed by some of the tools
@@ -83,55 +83,102 @@ dnl check for how to do large files
AC_SYS_LARGEFILE
# Configure parameters
AC_ARG_WITH(libgcrypt,
AC_HELP_STRING([--with-libgcrypt],[Use Libgcrypt for crypto]),
use_libgcrypt=$withval,use_libgcrypt=auto)
AC_ARG_WITH(openssl,
AC_HELP_STRING([--with-openssl],[Use OpenSSL for crypto]),
use_openssl=$withval,use_openssl=auto)
AC_ARG_WITH(libgcrypt,
AC_HELP_STRING([--with-libgcrypt],[Use libgcrypt for crypto]),
use_libgcrypt=$withval,use_libgcrypt=auto)
AC_ARG_WITH(wincng,
AC_HELP_STRING([--with-wincng],[Use Windows CNG for crypto]),
use_wincng=$withval,use_wincng=auto)
AC_ARG_WITH(libz,
AC_HELP_STRING([--with-libz],[Use Libz for compression]),
AC_HELP_STRING([--with-libz],[Use zlib for compression]),
use_libz=$withval,use_libz=auto)
# Look for OpenSSL (default)
if test "$use_openssl" != "no" && test "$use_libgcrypt" != "yes"; then
found_crypto=none
# Look for OpenSSL
if test "$found_crypto" = "none" && test "$use_openssl" != "no"; then
AC_LIB_HAVE_LINKFLAGS([ssl], [crypto], [#include <openssl/ssl.h>])
fi
if test "$ac_cv_libssl" = "yes"; then
AC_DEFINE(LIBSSH2_OPENSSL, 1, [Use OpenSSL])
LIBSREQUIRED=libssl,libcrypto
# Not all OpenSSL have AES-CTR functions.
save_LIBS="$LIBS"
LIBS="$LIBS $LIBSSL"
AC_CHECK_FUNCS(EVP_aes_128_ctr)
LIBS="$save_LIBS"
found_crypto="OpenSSL (AES-CTR: ${ac_cv_func_EVP_aes_128_ctr:-N/A})"
fi
AM_CONDITIONAL(OPENSSL, test "$ac_cv_libssl" = "yes")
# Look for libgcrypt
if test "$ac_cv_libssl" != "yes" && test "$use_libgcrypt" != "no"; then
if test "$found_crypto" = "none" && test "$use_libgcrypt" != "no"; then
AC_LIB_HAVE_LINKFLAGS([gcrypt], [], [#include <gcrypt.h>])
fi
if test "$ac_cv_libssl" != "yes" && test "$ac_cv_libgcrypt" != "yes"; then
AC_MSG_ERROR([cannot find OpenSSL or Libgcrypt,
try --with-libssl-prefix=PATH or --with-libgcrypt-prefix=PATH])
fi
if test "$ac_cv_libgcrypt" = "yes"; then
AC_DEFINE(LIBSSH2_LIBGCRYPT, 1, [Use libgcrypt])
LIBSREQUIRED= # libgcrypt doesn't provide a .pc file. sad face.
LIBS="$LIBS -lgcrypt"
found_crypto=libgcrypt
fi
AM_CONDITIONAL(LIBGCRYPT, test "$ac_cv_libgcrypt" = "yes")
# Not all OpenSSL have AES-CTR functions.
if test "$ac_cv_libssl" = "yes"; then
save_LDFLAGS="$LDFLAGS"
LDFLAGS="$LDFLAGS $LIBSSL"
AC_CHECK_FUNCS(EVP_aes_128_ctr)
LDFLAGS="$save_LDFLAGS"
# Look for Windows Cryptography API: Next Generation
if test "$found_crypto" = "none" && test "$use_wincng" != "no"; then
AC_LIB_HAVE_LINKFLAGS([bcrypt], [], [
#include <windows.h>
#include <bcrypt.h>
])
AC_LIB_HAVE_LINKFLAGS([crypt32], [], [
#include <windows.h>
#include <wincrypt.h>
])
AC_CHECK_HEADERS([ntdef.h ntstatus.h], [], [], [
#include <windows.h>
])
fi
if test "$ac_cv_libbcrypt" = "yes"; then
AC_DEFINE(LIBSSH2_WINCNG, 1, [Use Windows CNG])
LIBSREQUIRED= # wincng doesn't provide a .pc file. sad face.
LIBS="$LIBS -lbcrypt"
if test "$ac_cv_libcrypt32" = "yes"; then
LIBS="$LIBS -lcrypt32"
fi
found_crypto="Windows Cryptography API: Next Generation"
fi
AM_CONDITIONAL(WINCNG, test "$ac_cv_libbcrypt" = "yes")
# Check if crypto library was found
if test "$found_crypto" = "none"; then
AC_MSG_ERROR([No crypto library found!
Try --with-libssl-prefix=PATH
or --with-libgcrypt-prefix=PATH
or --with-wincng on Windows\
])
fi
# Look for Libz
if test "$use_libz" != "no"; then
AC_LIB_HAVE_LINKFLAGS([z], [], [#include <zlib.h>])
if test "$ac_cv_libz" != yes; then
AC_MSG_NOTICE([Cannot find libz, disabling compression])
AC_MSG_NOTICE([Cannot find zlib, disabling compression])
AC_MSG_NOTICE([Try --with-libz-prefix=PATH if you know you have it])
else
AC_DEFINE(LIBSSH2_HAVE_ZLIB, 1, [Compile in zlib support])
if test "${LIBSREQUIRED}" != ""; then
LIBSREQUIRED="${LIBSREQUIRED},"
fi
LIBSREQUIRED="${LIBSREQUIRED}zlib"
fi
fi
AC_SUBST(LIBSREQUIRED)
#
# Optional Settings
#
@@ -215,6 +262,22 @@ AC_HELP_STRING([--disable-hidden-symbols],[Leave all symbols with default visibi
AC_MSG_RESULT(no)
)
# Build example applications?
AC_MSG_CHECKING([whether to build example applications])
AC_ARG_ENABLE([examples-build],
AC_HELP_STRING([--enable-examples-build], [Build example applications (this is the default)])
AC_HELP_STRING([--disable-examples-build], [Do not build example applications]),
[case "$enableval" in
no | false)
build_examples='no'
;;
*)
build_examples='yes'
;;
esac], [build_examples='yes'])
AC_MSG_RESULT($build_examples)
AM_CONDITIONAL([BUILD_EXAMPLES], [test "x$build_examples" != "xno"])
# Checks for header files.
# AC_HEADER_STDC
AC_CHECK_HEADERS([errno.h fcntl.h stdio.h stdlib.h unistd.h sys/uio.h])
@@ -298,8 +361,9 @@ AC_MSG_NOTICE([summary of build options:
Compiler: ${CC}
Compiler flags: ${CFLAGS}
Library types: Shared=${enable_shared}, Static=${enable_static}
Crypto library: openssl: ${ac_cv_libssl:-no} (AES-CTR: ${ac_cv_func_EVP_aes_128_ctr:-N/A}) libgcrypt: ${ac_cv_libgcrypt:-no}
Crypto library: ${found_crypto}
Debug build: $enable_debug
Build examples: $build_examples
Path to sshd: $ac_cv_path_SSHD (only for self-tests)
libz compression: $ac_cv_libz
zlib compression: $ac_cv_libz
])

View File

@@ -6,32 +6,57 @@
Adam Gobiowski
Alexander Holyapin
Alexander Lamaison
Alfred Gebert
Ben Kibbey
Bjorn Stenborg
Carlo Bramini
Cristian Rodríguez
Daiki Ueno
Dan Casey
Dan Fandrich
Daniel Stenberg
Dave Hayden
Dave McCaldon
David J Sullivan
David Robins
Dmitry Smirnov
Douglas Masterson
Edink Kadribasic
Erik Brossler
Francois Dupoux
Gellule Xg
Grubsky Grigory
Guenter Knauf
Heiner Steven
Henrik Nordstrom
James Housleys
Jasmeet Bagga
Jean-Louis Charton
Jernej Kovacic
Joey Degges
John Little
Jose Baars
Jussi Mononen
Kamil Dudka
Lars Nordin
Mark McPherson
Mark Smith
Markus Moeller
Matt Lilley
Matthew Booth
Maxime Larocque
Mike Protts
Mikhail Gusarov
Neil Gierman
Olivier Hervieu
Paul Howarth
Paul Querna
Paul Veldkamp
Peter Krempa
Peter O'Gorman
Peter Stuge
Pierre Joye
Rafael Kitover
Romain Bondue
Sara Golemon
Satish Mittal
@@ -39,10 +64,16 @@ Sean Peterson
Selcuk Gueney
Simon Hart
Simon Josefsson
Sofian Brabez
Steven Ayre
Steven Dake
Steven Van Ingelgem
TJ Saunders
Tommy Lindgren
Tor Arntsen
Vincent Jaulin
Vincent Torri
Vlad Grachov
Wez Furlong
Yang Tse
Zl Liu

29
docs/BINDINGS Normal file
View 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
View 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).

View File

@@ -1,6 +1,6 @@
# $Id: Makefile.am,v 1.37 2009/03/26 15:41:15 bagder Exp $
EXTRA_DIST = template.3
EXTRA_DIST = template.3 BINDINGS INSTALL HACKING TODO AUTHORS
dist_man_MANS = \
libssh2_agent_connect.3 \
@@ -102,6 +102,7 @@ dist_man_MANS = \
libssh2_session_free.3 \
libssh2_session_get_blocking.3 \
libssh2_session_get_timeout.3 \
libssh2_session_handshake.3 \
libssh2_session_hostkey.3 \
libssh2_session_init.3 \
libssh2_session_init_ex.3 \
@@ -120,6 +121,7 @@ dist_man_MANS = \
libssh2_sftp_fstat.3 \
libssh2_sftp_fstat_ex.3 \
libssh2_sftp_fstatvfs.3 \
libssh2_sftp_fsync.3 \
libssh2_sftp_get_channel.3 \
libssh2_sftp_init.3 \
libssh2_sftp_last_error.3 \

View File

View File

@@ -1,6 +1,6 @@
.TH libssh2_banner_set 3 "1 Jun 2007" "libssh2 0.15" "libssh2 manual"
.SH NAME
libssh2_banner_set - set the SSH prococol banner for the local client
libssh2_banner_set - set the SSH protocol banner for the local client
.SH SYNOPSIS
#include <libssh2.h>

View File

@@ -19,7 +19,7 @@ The returned buffer is allocated by this function, but it is not clear how to
free that memory!
.SH BUGS
The memory that *dest points to is allocated by the malloc function libssh2
uses, but there's no way for an appliction to free this data in a safe and
uses, but there's no way for an application to free this data in a safe and
reliable way!
.SH RETURN VALUE
0 if successful, \-1 if any error occurred.

View File

@@ -8,7 +8,7 @@ int
libssh2_channel_get_exit_status(LIBSSH2_CHANNEL* channel)
.SH DESCRIPTION
\fIchannel\fP - Closed channel stream to retreive exit status from.
\fIchannel\fP - Closed channel stream to retrieve exit status from.
Returns the exit code raised by the process running on the remote host at
the other end of the named channel. Note that the exit status may not be

View File

@@ -4,7 +4,7 @@ libssh2_channel_window_write - convenience macro for \fIlibssh2_channel_window_w
.SH SYNOPSIS
#include <libssh2.h>
unsigend long libssh2_channel_window_write(LIBSSH2_CHANNEL *channel);
unsigned long libssh2_channel_window_write(LIBSSH2_CHANNEL *channel);
.SH DESCRIPTION
This is a macro defined in a public libssh2 header file that is using the

View File

@@ -9,11 +9,11 @@ libssh2_channel_window_write_ex(LIBSSH2_CHANNEL *channel,
unsigned long *window_size_initial)
.SH DESCRIPTION
Check the status of the write window Returns the number of bytes which may be
safely writen on the channel without blocking. 'window_size_initial' (if
safely written on the channel without blocking. 'window_size_initial' (if
passed) will be populated with the size of the initial window as defined by
the channel_open request
.SH RETURN VALUE
Number of bytes which may be safely writen on the channel without blocking.
Number of bytes which may be safely written on the channel without blocking.
.SH ERRORS
.SH SEE ALSO

View File

@@ -18,8 +18,9 @@ Returns the computed digest of the remote system's hostkey. The length of
the returned string is hash_type specific (e.g. 16 bytes for MD5,
20 bytes for SHA1).
.SH RETURN VALUE
Computed hostkey hash value. or NULL if the session has not yet been started
up. (The hash consists of raw binary bytes, not hex digits, so is not
directly printable.)
Computed hostkey hash value, or NULL if the information is not available
(either the session has not yet been started up, or the requested hash
algorithm was not available). The hash consists of raw binary bytes, not hex
digits, so it is not directly printable.
.SH SEE ALSO
.BR libssh2_session_init_ex(3)

View File

@@ -36,7 +36,7 @@ The salt has to be provided base64 encoded with a trailing zero byte.
argument
\fItypemask\fP is a bitmask that specifies format and info about the data
passed to this function. Specificly, it details what format the host name is,
passed to this function. Specifically, it details what format the host name is,
what format the key is and what key type it is.
The host name is given as one of the following types:

View File

@@ -40,7 +40,7 @@ argument
\fIcommentlen\fP is the total size in bytes of the comment pointed to by the \fIcomment\fP argument
\fItypemask\fP is a bitmask that specifies format and info about the data
passed to this function. Specificly, it details what format the host name is,
passed to this function. Specifically, it details what format the host name is,
what format the key is and what key type it is.
The host name is given as one of the following types:

View File

@@ -25,7 +25,7 @@ IP numerical address of the host or the full name.
argument
\fItypemask\fP is a bitmask that specifies format and info about the data
passed to this function. Specificly, it details what format the host name is,
passed to this function. Specifically, it details what format the host name is,
what format the key is and what key type it is.
The host name is given as one of the following types:

View File

@@ -30,7 +30,7 @@ addition to the plain host name only check.
argument
\fItypemask\fP is a bitmask that specifies format and info about the data
passed to this function. Specificly, it details what format the host name is,
passed to this function. Specifically, it details what format the host name is,
what format the key is and what key type it is.
The host name is given as one of the following types:

View File

@@ -8,7 +8,7 @@ int libssh2_poll(LIBSSH2_POLLFD *fds, unsigned int nfds, long timeout);
.SH DESCRIPTION
This function is deprecated. Do note use. We encourage users to instead use
the \fIpoll(3)\fP or \fIselect(3)\fP functions to check for socket activity or
when specific sockets are ready to get recevied from or send to.
when specific sockets are ready to get received from or send to.
Poll for activity on a socket, channel, listener, or any combination of these
three types. The calling semantics for this function generally match

View File

@@ -17,7 +17,7 @@ de-referenced pointer, the internal storage of the session instance may be
modified in place.
.SH RETURN VALUE
A pointer to session internal storage whos contents point to previously
A pointer to session internal storage who's contents point to previously
provided abstract data.
.SH SEE ALSO

View File

@@ -1,6 +1,6 @@
.TH libssh2_session_banner_set 3 "9 Sep 2011" "libssh2 1.4.0" "libssh2 manual"
.SH NAME
libssh2_session_banner_set - set the SSH prococol banner for the local client
libssh2_session_banner_set - set the SSH protocol banner for the local client
.SH SYNOPSIS
#include <libssh2.h>

View File

@@ -18,7 +18,7 @@ libssh2_session_disconnect(LIBSSH2_SESSION *session, const char *description);
\fIdescription\fP - Human readable reason for disconnection.
\fIlang\fP - Localization string describing the langauge/encoding of the description provided.
\fIlang\fP - Localization string describing the language/encoding of the description provided.
Send a disconnect message to the remote host associated with \fIsession\fP,
along with a \fIreason\fP symbol and a verbose \fIdescription\fP.

View File

@@ -19,7 +19,7 @@ If a method is listed which is not supported by libssh2 it will be
ignored and not sent to the remote host during protocol negotiation.
Set preferred methods to be negotiated. These
preferrences must be set prior to calling
preferences must be set prior to calling
.BR libssh2_session_handshake(3)
as they are used during the protocol initiation phase.

View File

@@ -12,7 +12,7 @@ int libssh2_session_supported_algs(LIBSSH2_SESSION* session,
\fIsession\fP - An instance of initialized LIBSSH2_SESSION (the function will
use its pointer to the memory allocation function). \fImethod_type\fP - Method
type. See .BR \fIlibssh2_session_method_pref(3)\fP. \fIalgs\fP - Address of a
pointer that will point to an array af returned algorithms
pointer that will point to an array of returned algorithms
Get a list of supported algorithms for the given \fImethod_type\fP. The
method_type parameter is equivalent to method_type in
@@ -36,7 +36,7 @@ const char **algorithms;
int rc, i;
LIBSSH2_SESSION *session;
/* initilize session */
/* initialize session */
session = libssh2_session_init();
rc = libssh2_session_supported_algs(session,
LIBSSH2_METHOD_CRYPT_CS,

View File

@@ -20,7 +20,7 @@ or \fBlibssh2_sftp_opendir(3)\fP (which is a macro).
Close an active LIBSSH2_SFTP_HANDLE. Because files and directories share the
same underlying storage mechanism these methods may be used
interchangably. \fBlibssh2_sftp_close(3)\fP and \fBlibssh2_sftp_closedir(3)\fP
interchangeably. \fBlibssh2_sftp_close(3)\fP and \fBlibssh2_sftp_closedir(3)\fP
are macros for \fBlibssh2_sftp_close_handle(3)\fP.
.SH RETURN VALUE

View File

@@ -10,7 +10,7 @@ int
libssh2_sftp_fstat_ex(LIBSSH2_SFTP_HANDLE *handle,
LIBSSH2_SFTP_ATTRIBUTES *attrs, int setstat)
#define libbssh2_sftp_fstat(handle, attrs) \\
#define libssh2_sftp_fstat(handle, attrs) \\
libssh2_sftp_fstat_ex((handle), (attrs), 0)
#define libssh2_sftp_fsetstat(handle, attrs) \\
libssh2_sftp_fstat_ex((handle), (attrs), 1)
@@ -60,7 +60,7 @@ most common ones are:
To check for specific user permissions, the set of defines are in the
pattern LIBSSH2_SFTP_S_I<action><who> where <action> is R, W or X for
read, write and excutable and <who> is USR, GRP and OTH for user,
read, write and executable and <who> is USR, GRP and OTH for user,
group and other. So, you check for a user readable file, use the bit
\fILIBSSH2_SFTP_S_IRUSR\fP while you want to see if it is executable
for other, you use \fILIBSSH2_SFTP_S_IXOTH\fP and so on.

39
docs/libssh2_sftp_fsync.3 Normal file
View 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)

View File

@@ -15,7 +15,7 @@ libssh2_sftp_mkdir(LIBSSH2_SFTP *sftp, const char *path, long mode);
.BR libssh2_sftp_init(3)
\fIpath\fP - full path of the new directory to create. Note that the new
directory's parents must all exist priot to making this call.
directory's parents must all exist prior to making this call.
\fIpath_len\fP - length of the full path of the new directory to create.

View File

@@ -29,7 +29,7 @@ filesystem entry
Bitmask flags made up of LIBSSH2_SFTP_RENAME_* constants.
Rename a filesystem object on the remote filesystem. The semantics of
this command typically include the ability to move a filsystem object
this command typically include the ability to move a filesystem object
between folders and/or filesystem mounts. If the LIBSSH2_SFTP_RENAME_OVERWRITE
flag is not set and the destfile entry already exists, the operation
will fail. Use of the other two flags indicate a preference (but not a

View File

@@ -4,7 +4,7 @@ libssh2_sftp_rewind - convenience macro for \fIlibssh2_sftp_seek64(3)\fP calls
.SH SYNOPSIS
#include <libssh2.h>
int libssh2_sftp_rewind(LINBSSH2_SFTP_HANDLE *handle);
int libssh2_sftp_rewind(LIBSSH2_SFTP_HANDLE *handle);
.SH DESCRIPTION
This is a macro defined in a public libssh2 header file that is using the

View File

@@ -4,7 +4,7 @@ libssh2_sftp_stat - convenience macro for \fIlibssh2_sftp_fstat_ex(3)\fP calls
.SH SYNOPSIS
#include <libssh2.h>
int libssh2_sftp_stat(LIBSSH2_SFTP *sftp, const char *path, LIBSSH2_STFP_ATTRIBUTES *attrs);
int libssh2_sftp_stat(LIBSSH2_SFTP *sftp, const char *path, LIBSSH2_SFTP_ATTRIBUTES *attrs);
.SH DESCRIPTION
This is a macro defined in a public libssh2 header file that is using the

View File

@@ -48,7 +48,7 @@ These are convenience macros:
.BR libssh2_sftp_realpath(3)
: Resolve a complex, relative, or symlinked filepath to its effective target.
.SH RETURN VALUE
When using LIBSSH2_SFTP_SYMLINK, this funtion returns 0 on success or negative
When using LIBSSH2_SFTP_SYMLINK, this function returns 0 on success or negative
on failure.
When using LIBSSH2_SFTP_READLINK or LIBSSH2_SFTP_REALPATH, it returns the

View File

@@ -28,7 +28,7 @@ distinguished from a failing case by examining
\fIlibssh2_userauth_authenticated(3)\fP.
.SH RETURN VALUE
On success a comma delimited list of supported authentication schemes. This
list is internally managed by libssh2. On failure ruturns NULL.
list is internally managed by libssh2. On failure returns NULL.
.SH ERRORS
\fILIBSSH2_ERROR_ALLOC\fP - An internal memory allocation call failed.

View File

@@ -7,24 +7,28 @@ libssh2_userauth_publickey_fromfile - authenticate a session with a public key,
.nf
int libssh2_userauth_publickey_fromfile_ex(LIBSSH2_SESSION *session,
const char *username,
unsigned int ousername_len,
const char *publickey,
const char *privatekey,
const char *passphrase);
.SH DESCRIPTION
\fIsession\fP - Session instance as returned by
.BR libssh2_session_init_ex(3)
\fIsession\fP - Session instance as returned by
\fBlibssh2_session_init_ex(3)\fP
\fIusername\fP - Remote user name to authenticate as.
\fIusername\fP - Pointer to user name to authenticate as.
\fIusername_len\fP - Length of username.
\fIusername_len\fP - Length of \fIusername\fP.
\fIpublickey\fP - Path and name of public key file. (e.g. /etc/ssh/hostkey.pub)
\fIpublickey\fP - Path name of the public key file.
(e.g. /etc/ssh/hostkey.pub). If libssh2 is built against OpenSSL, this option
can be set to NULL.
\fIprivatekey\fP - Path and name of private key file. (e.g. /etc/ssh/hostkey)
\fIprivatekey\fP - Path name of the private key file. (e.g. /etc/ssh/hostkey)
\fIpassphrase\fP - Passphrase to use when decoding private key file.
\fIpassphrase\fP - Passphrase to use when decoding \fIprivatekey\fP.
Attempt public key authentication using a PEM encoded private key file stored on disk
Attempt public key authentication using a PEM encoded private key file stored
on disk
.SH RETURN VALUE
Return 0 on success or negative on failure. It returns

View File

@@ -48,7 +48,7 @@ enum {
int main(int argc, char *argv[])
{
int rc, sock = -1, listensock = -1, forwardsock = -1, i, auth = AUTH_NONE;
int rc, i, auth = AUTH_NONE;
struct sockaddr_in sin;
socklen_t sinlen;
const char *fingerprint;
@@ -64,11 +64,19 @@ int main(int argc, char *argv[])
#ifdef WIN32
char sockopt;
SOCKET sock = INVALID_SOCKET;
SOCKET listensock = INVALID_SOCKET, forwardsock = INVALID_SOCKET;
WSADATA wsadata;
int err;
WSAStartup(MAKEWORD(2,0), &wsadata);
err = WSAStartup(MAKEWORD(2,0), &wsadata);
if (err != 0) {
fprintf(stderr, "WSAStartup failed with error: %d\n", err);
return 1;
}
#else
int sockopt;
int sockopt, sock = -1;
int listensock = -1, forwardsock = -1;
#endif
if (argc > 1)
@@ -94,6 +102,18 @@ int main(int argc, char *argv[])
/* Connect to SSH server */
sock = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP);
#ifdef WIN32
if (sock == INVALID_SOCKET) {
fprintf(stderr, "failed to open socket!\n");
return -1;
}
#else
if (sock == -1) {
perror("socket");
return -1;
}
#endif
sin.sin_family = AF_INET;
if (INADDR_NONE == (sin.sin_addr.s_addr = inet_addr(server_ip))) {
perror("inet_addr");
@@ -135,7 +155,7 @@ int main(int argc, char *argv[])
/* check what authentication methods are available */
userauthlist = libssh2_userauth_list(session, username, strlen(username));
printf("Authentication methods: %s\n", userauthlist);
fprintf(stderr, "Authentication methods: %s\n", userauthlist);
if (strstr(userauthlist, "password"))
auth |= AUTH_PASSWORD;
if (strstr(userauthlist, "publickey"))
@@ -157,16 +177,28 @@ int main(int argc, char *argv[])
} else if (auth & AUTH_PUBLICKEY) {
if (libssh2_userauth_publickey_fromfile(session, username, keyfile1,
keyfile2, password)) {
printf("\tAuthentication by public key failed!\n");
fprintf(stderr, "\tAuthentication by public key failed!\n");
goto shutdown;
}
printf("\tAuthentication by public key succeeded.\n");
fprintf(stderr, "\tAuthentication by public key succeeded.\n");
} else {
printf("No supported authentication methods found!\n");
fprintf(stderr, "No supported authentication methods found!\n");
goto shutdown;
}
listensock = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP);
#ifdef WIN32
if (listensock == INVALID_SOCKET) {
fprintf(stderr, "failed to open listen socket!\n");
return -1;
}
#else
if (listensock == -1) {
perror("socket");
return -1;
}
#endif
sin.sin_family = AF_INET;
sin.sin_port = htons(local_listenport);
if (INADDR_NONE == (sin.sin_addr.s_addr = inet_addr(local_listenip))) {
@@ -185,20 +217,27 @@ int main(int argc, char *argv[])
goto shutdown;
}
printf("Waiting for TCP connection on %s:%d...\n",
fprintf(stderr, "Waiting for TCP connection on %s:%d...\n",
inet_ntoa(sin.sin_addr), ntohs(sin.sin_port));
forwardsock = accept(listensock, (struct sockaddr *)&sin, &sinlen);
if (-1 == forwardsock) {
#ifdef WIN32
if (forwardsock == INVALID_SOCKET) {
fprintf(stderr, "failed to accept forward socket!\n");
goto shutdown;
}
#else
if (forwardsock == -1) {
perror("accept");
goto shutdown;
}
#endif
shost = inet_ntoa(sin.sin_addr);
sport = ntohs(sin.sin_port);
printf("Forwarding connection from %s:%d here to remote %s:%d\n", shost,
sport, remote_desthost, remote_destport);
fprintf(stderr, "Forwarding connection from %s:%d here to remote %s:%d\n",
shost, sport, remote_desthost, remote_destport);
channel = libssh2_channel_direct_tcpip_ex(session, remote_desthost,
remote_destport, shost, sport);
@@ -228,7 +267,8 @@ int main(int argc, char *argv[])
perror("read");
goto shutdown;
} else if (0 == len) {
printf("The client at %s:%d disconnected!\n", shost, sport);
fprintf(stderr, "The client at %s:%d disconnected!\n", shost,
sport);
goto shutdown;
}
wr = 0;
@@ -259,7 +299,7 @@ int main(int argc, char *argv[])
wr += i;
}
if (libssh2_channel_eof(channel)) {
printf("The server at %s:%d disconnected!\n",
fprintf(stderr, "The server at %s:%d disconnected!\n",
remote_desthost, remote_destport);
goto shutdown;
}

View File

@@ -47,8 +47,13 @@ int main(int argc, char *argv[])
#ifdef WIN32
WSADATA wsadata;
int err;
WSAStartup(MAKEWORD(2,0), &wsadata);
err = WSAStartup(MAKEWORD(2,0), &wsadata);
if (err != 0) {
fprintf(stderr, "WSAStartup failed with error: %d\n", err);
return 1;
}
#endif
if (argc > 1) {

View File

@@ -97,8 +97,13 @@ int main(int argc, char *argv[])
#ifdef WIN32
WSADATA wsadata;
int err;
WSAStartup(MAKEWORD(2,0), &wsadata);
err = WSAStartup(MAKEWORD(2,0), &wsadata);
if (err != 0) {
fprintf(stderr, "WSAStartup failed with error: %d\n", err);
return 1;
}
#endif
if (argc > 1) {
@@ -250,7 +255,7 @@ int main(int argc, char *argv[])
gettimeofday(&end, NULL);
time_ms = tvdiff(end, start);
printf("Got %d bytes in %ld ms = %.1f bytes/sec spin: %d\n", total,
fprintf(stderr, "Got %d bytes in %ld ms = %.1f bytes/sec spin: %d\n", total,
time_ms, total/(time_ms/1000.0), spin );
libssh2_channel_free(channel);

View File

@@ -51,8 +51,13 @@ int main(int argc, char *argv[])
#ifdef WIN32
WSADATA wsadata;
int err;
WSAStartup(MAKEWORD(2,0), &wsadata);
err = WSAStartup(MAKEWORD(2,0), &wsadata);
if (err != 0) {
fprintf(stderr, "WSAStartup failed with error: %d\n", err);
return 1;
}
#endif
if (argc > 1) {

View File

@@ -90,8 +90,13 @@ int main(int argc, char *argv[])
#ifdef WIN32
WSADATA wsadata;
int err;
WSAStartup(MAKEWORD(2,0), &wsadata);
err = WSAStartup(MAKEWORD(2,0), &wsadata);
if (err != 0) {
fprintf(stderr, "WSAStartup failed with error: %d\n", err);
return 1;
}
#endif
if (argc > 1) {
@@ -243,7 +248,7 @@ int main(int argc, char *argv[])
duration = (int)(time(NULL)-start);
printf("%ld bytes in %d seconds makes %.1f bytes/sec\n",
fprintf(stderr, "%ld bytes in %d seconds makes %.1f bytes/sec\n",
total, duration, total/(double)duration);
fprintf(stderr, "Sending EOF\n");

View File

@@ -55,24 +55,24 @@ static void kbd_callback(const char *name, int name_len,
char buf[1024];
(void)abstract;
printf("Performing keyboard-interactive authentication.\n");
fprintf(stderr, "Performing keyboard-interactive authentication.\n");
printf("Authentication name: '");
fwrite(name, 1, name_len, stdout);
printf("'\n");
fprintf(stderr, "Authentication name: '");
fwrite(name, 1, name_len, stderr);
fprintf(stderr, "'\n");
printf("Authentication instruction: '");
fwrite(instruction, 1, instruction_len, stdout);
printf("'\n");
fprintf(stderr, "Authentication instruction: '");
fwrite(instruction, 1, instruction_len, stderr);
fprintf(stderr, "'\n");
printf("Number of prompts: %d\n\n", num_prompts);
fprintf(stderr, "Number of prompts: %d\n\n", num_prompts);
for (i = 0; i < num_prompts; i++) {
printf("Prompt %d from server: '", i);
fwrite(prompts[i].text, 1, prompts[i].length, stdout);
printf("'\n");
fprintf(stderr, "Prompt %d from server: '", i);
fwrite(prompts[i].text, 1, prompts[i].length, stderr);
fprintf(stderr, "'\n");
printf("Please type response: ");
fprintf(stderr, "Please type response: ");
fgets(buf, sizeof(buf), stdin);
n = strlen(buf);
while (n > 0 && strchr("\r\n", buf[n - 1]))
@@ -82,12 +82,13 @@ static void kbd_callback(const char *name, int name_len,
responses[i].text = strdup(buf);
responses[i].length = n;
printf("Response %d from user is '", i);
fwrite(responses[i].text, 1, responses[i].length, stdout);
printf("'\n\n");
fprintf(stderr, "Response %d from user is '", i);
fwrite(responses[i].text, 1, responses[i].length, stderr);
fprintf(stderr, "'\n\n");
}
printf("Done. Sending keyboard-interactive responses to server now.\n");
fprintf(stderr,
"Done. Sending keyboard-interactive responses to server now.\n");
}
@@ -105,8 +106,13 @@ int main(int argc, char *argv[])
#ifdef WIN32
WSADATA wsadata;
int err;
WSAStartup(MAKEWORD(2,0), &wsadata);
err = WSAStartup(MAKEWORD(2,0), &wsadata);
if (err != 0) {
fprintf(stderr, "WSAStartup failed with error: %d\n", err);
return 1;
}
#endif
if (argc > 1) {
@@ -127,7 +133,7 @@ int main(int argc, char *argv[])
rc = libssh2_init (0);
if (rc != 0) {
fprintf (stderr, "libssh2 initialization failed (%d)\n", rc);
fprintf(stderr, "libssh2 initialization failed (%d)\n", rc);
return 1;
}
@@ -178,7 +184,7 @@ int main(int argc, char *argv[])
/* check what authentication methods are available */
userauthlist = libssh2_userauth_list(session, username, strlen(username));
printf("Authentication methods: %s\n", userauthlist);
fprintf(stderr, "Authentication methods: %s\n", userauthlist);
if (strstr(userauthlist, "password") != NULL) {
auth_pw |= 1;
}
@@ -211,21 +217,23 @@ int main(int argc, char *argv[])
} else if (auth_pw & 2) {
/* Or via keyboard-interactive */
if (libssh2_userauth_keyboard_interactive(session, username, &kbd_callback) ) {
printf("\tAuthentication by keyboard-interactive failed!\n");
fprintf(stderr,
"\tAuthentication by keyboard-interactive failed!\n");
goto shutdown;
} else {
printf("\tAuthentication by keyboard-interactive succeeded.\n");
fprintf(stderr,
"\tAuthentication by keyboard-interactive succeeded.\n");
}
} else if (auth_pw & 4) {
/* Or by public key */
if (libssh2_userauth_publickey_fromfile(session, username, keyfile1, keyfile2, password)) {
printf("\tAuthentication by public key failed!\n");
fprintf(stderr, "\tAuthentication by public key failed!\n");
goto shutdown;
} else {
printf("\tAuthentication by public key succeeded.\n");
fprintf(stderr, "\tAuthentication by public key succeeded.\n");
}
} else {
printf("No supported authentication methods found!\n");
fprintf(stderr, "No supported authentication methods found!\n");
goto shutdown;
}

View File

@@ -93,8 +93,13 @@ int main(int argc, char *argv[])
#ifdef WIN32
WSADATA wsadata;
int err;
WSAStartup(MAKEWORD(2,0), &wsadata);
err = WSAStartup(MAKEWORD(2,0), &wsadata);
if (err != 0) {
fprintf(stderr, "WSAStartup failed with error: %d\n", err);
return 1;
}
#endif
rc = libssh2_init (0);
@@ -141,11 +146,11 @@ int main(int argc, char *argv[])
* user, that's your call
*/
fingerprint = libssh2_hostkey_hash(session, LIBSSH2_HOSTKEY_HASH_SHA1);
printf("Fingerprint: ");
fprintf(stderr, "Fingerprint: ");
for(i = 0; i < 20; i++) {
printf("%02X ", (unsigned char)fingerprint[i]);
fprintf(stderr, "%02X ", (unsigned char)fingerprint[i]);
}
printf("\n");
fprintf(stderr, "\n");
if(argc > 1) {
username = argv[1];
@@ -162,7 +167,7 @@ int main(int argc, char *argv[])
tempstorage = fopen(STORAGE, "wb");
if(!tempstorage) {
printf("Can't open temp storage file %s\n", STORAGE);
fprintf(stderr, "Can't open temp storage file %s\n", STORAGE);
goto shutdown;
}
@@ -171,7 +176,7 @@ int main(int argc, char *argv[])
while ((rc = libssh2_userauth_password(session, username, password))
== LIBSSH2_ERROR_EAGAIN);
if (rc) {
printf("Authentication by password failed.\n");
fprintf(stderr, "Authentication by password failed.\n");
goto shutdown;
}
} else {
@@ -185,7 +190,7 @@ int main(int argc, char *argv[])
password)) ==
LIBSSH2_ERROR_EAGAIN);
if (rc) {
printf("\tAuthentication by public key failed\n");
fprintf(stderr, "\tAuthentication by public key failed\n");
goto shutdown;
}
}
@@ -341,7 +346,7 @@ int main(int argc, char *argv[])
#endif
if (tempstorage)
fclose(tempstorage);
printf("all done\n");
fprintf(stderr, "all done\n");
libssh2_exit();

View File

@@ -55,8 +55,13 @@ int main(int argc, char *argv[])
#ifdef WIN32
WSADATA wsadata;
int err;
WSAStartup(MAKEWORD(2,0), &wsadata);
err = WSAStartup(MAKEWORD(2,0), &wsadata);
if (err != 0) {
fprintf(stderr, "WSAStartup failed with error: %d\n", err);
return 1;
}
#endif
if (argc > 1) {
@@ -86,7 +91,7 @@ int main(int argc, char *argv[])
local = fopen(loclfile, "rb");
if (!local) {
printf("Can't local file %s\n", loclfile);
fprintf(stderr, "Can't open local file %s\n", loclfile);
return -1;
}
@@ -129,16 +134,16 @@ int main(int argc, char *argv[])
* user, that's your call
*/
fingerprint = libssh2_hostkey_hash(session, LIBSSH2_HOSTKEY_HASH_SHA1);
printf("Fingerprint: ");
fprintf(stderr, "Fingerprint: ");
for(i = 0; i < 20; i++) {
printf("%02X ", (unsigned char)fingerprint[i]);
fprintf(stderr, "%02X ", (unsigned char)fingerprint[i]);
}
printf("\n");
fprintf(stderr, "\n");
if (auth_pw) {
/* We could authenticate via password */
if (libssh2_userauth_password(session, username, password)) {
printf("Authentication by password failed.\n");
fprintf(stderr, "Authentication by password failed.\n");
goto shutdown;
}
} else {
@@ -147,7 +152,7 @@ int main(int argc, char *argv[])
"/home/username/.ssh/id_rsa.pub",
"/home/username/.ssh/id_rsa",
password)) {
printf("\tAuthentication by public key failed\n");
fprintf(stderr, "\tAuthentication by public key failed\n");
goto shutdown;
}
}
@@ -174,12 +179,12 @@ int main(int argc, char *argv[])
}
if(libssh2_sftp_fstat_ex(sftp_handle, &attrs, 0) < 0) {
printf("libssh2_sftp_fstat_ex failed\n");
fprintf(stderr, "libssh2_sftp_fstat_ex failed\n");
goto shutdown;
}
else
libssh2_sftp_seek64(sftp_handle, attrs.filesize);
printf("Did a seek to position %ld\n", (long) attrs.filesize);
fprintf(stderr, "Did a seek to position %ld\n", (long) attrs.filesize);
fprintf(stderr, "libssh2_sftp_open() a handle for APPEND\n");
@@ -222,7 +227,7 @@ shutdown:
#endif
if (local)
fclose(local);
printf("all done\n");
fprintf(stderr, "all done\n");
libssh2_exit();

View File

@@ -48,8 +48,13 @@ int main(int argc, char *argv[])
#ifdef WIN32
WSADATA wsadata;
int err;
WSAStartup(MAKEWORD(2,0), &wsadata);
err = WSAStartup(MAKEWORD(2,0), &wsadata);
if (err != 0) {
fprintf(stderr, "WSAStartup failed with error: %d\n", err);
return 1;
}
#endif
if (argc > 1) {
@@ -110,16 +115,16 @@ int main(int argc, char *argv[])
* user, that's your call
*/
fingerprint = libssh2_hostkey_hash(session, LIBSSH2_HOSTKEY_HASH_SHA1);
printf("Fingerprint: ");
fprintf(stderr, "Fingerprint: ");
for(i = 0; i < 20; i++) {
printf("%02X ", (unsigned char)fingerprint[i]);
fprintf(stderr, "%02X ", (unsigned char)fingerprint[i]);
}
printf("\n");
fprintf(stderr, "\n");
if (auth_pw) {
/* We could authenticate via password */
if (libssh2_userauth_password(session, username, password)) {
printf("Authentication by password failed.\n");
fprintf(stderr, "Authentication by password failed.\n");
goto shutdown;
}
} else {
@@ -128,7 +133,7 @@ int main(int argc, char *argv[])
"/home/username/.ssh/id_rsa.pub",
"/home/username/.ssh/id_rsa",
password)) {
printf("\tAuthentication by public key failed\n");
fprintf(stderr, "\tAuthentication by public key failed\n");
goto shutdown;
}
}
@@ -164,7 +169,7 @@ int main(int argc, char *argv[])
#else
close(sock);
#endif
printf("all done\n");
fprintf(stderr, "all done\n");
libssh2_exit();

View File

@@ -48,8 +48,13 @@ int main(int argc, char *argv[])
#ifdef WIN32
WSADATA wsadata;
int err;
WSAStartup(MAKEWORD(2,0), &wsadata);
err = WSAStartup(MAKEWORD(2,0), &wsadata);
if (err != 0) {
fprintf(stderr, "WSAStartup failed with error: %d\n", err);
return 1;
}
#endif
if (argc > 1) {
@@ -110,16 +115,16 @@ int main(int argc, char *argv[])
* user, that's your call
*/
fingerprint = libssh2_hostkey_hash(session, LIBSSH2_HOSTKEY_HASH_SHA1);
printf("Fingerprint: ");
fprintf(stderr, "Fingerprint: ");
for(i = 0; i < 20; i++) {
printf("%02X ", (unsigned char)fingerprint[i]);
fprintf(stderr, "%02X ", (unsigned char)fingerprint[i]);
}
printf("\n");
fprintf(stderr, "\n");
if (auth_pw) {
/* We could authenticate via password */
if (libssh2_userauth_password(session, username, password)) {
printf("Authentication by password failed.\n");
fprintf(stderr, "Authentication by password failed.\n");
goto shutdown;
}
} else {
@@ -128,7 +133,7 @@ int main(int argc, char *argv[])
"/home/username/.ssh/id_rsa.pub",
"/home/username/.ssh/id_rsa",
password)) {
printf("\tAuthentication by public key failed\n");
fprintf(stderr, "\tAuthentication by public key failed\n");
goto shutdown;
}
}
@@ -164,7 +169,7 @@ int main(int argc, char *argv[])
#else
close(sock);
#endif
printf("all done\n");
fprintf(stderr, "all done\n");
libssh2_exit();

View File

@@ -97,8 +97,13 @@ int main(int argc, char *argv[])
#ifdef WIN32
WSADATA wsadata;
int err;
WSAStartup(MAKEWORD(2,0), &wsadata);
err = WSAStartup(MAKEWORD(2,0), &wsadata);
if (err != 0) {
fprintf(stderr, "WSAStartup failed with error: %d\n", err);
return 1;
}
#endif
if (argc > 1) {
@@ -251,7 +256,7 @@ int main(int argc, char *argv[])
gettimeofday(&end, NULL);
time_ms = tvdiff(end, start);
printf("Got %d bytes in %ld ms = %.1f bytes/sec spin: %d\n", total,
fprintf(stderr, "Got %d bytes in %ld ms = %.1f bytes/sec spin: %d\n", total,
time_ms, total/(time_ms/1000.0), spin );
libssh2_sftp_close(sftp_handle);
@@ -259,7 +264,7 @@ int main(int argc, char *argv[])
shutdown:
printf("libssh2_session_disconnect\n");
fprintf(stderr, "libssh2_session_disconnect\n");
while (libssh2_session_disconnect(session,
"Normal Shutdown, Thank you") ==
LIBSSH2_ERROR_EAGAIN);

View File

@@ -54,8 +54,13 @@ int main(int argc, char *argv[])
#ifdef WIN32
WSADATA wsadata;
int err;
WSAStartup(MAKEWORD(2,0), &wsadata);
err = WSAStartup(MAKEWORD(2,0), &wsadata);
if (err != 0) {
fprintf(stderr, "WSAStartup failed with error: %d\n", err);
return 1;
}
#endif
if (argc > 1) {
@@ -85,7 +90,7 @@ int main(int argc, char *argv[])
local = fopen(loclfile, "rb");
if (!local) {
printf("Can't local file %s\n", loclfile);
fprintf(stderr, "Can't open local file %s\n", loclfile);
return -1;
}
@@ -128,16 +133,16 @@ int main(int argc, char *argv[])
* user, that's your call
*/
fingerprint = libssh2_hostkey_hash(session, LIBSSH2_HOSTKEY_HASH_SHA1);
printf("Fingerprint: ");
fprintf(stderr, "Fingerprint: ");
for(i = 0; i < 20; i++) {
printf("%02X ", (unsigned char)fingerprint[i]);
fprintf(stderr, "%02X ", (unsigned char)fingerprint[i]);
}
printf("\n");
fprintf(stderr, "\n");
if (auth_pw) {
/* We could authenticate via password */
if (libssh2_userauth_password(session, username, password)) {
printf("Authentication by password failed.\n");
fprintf(stderr, "Authentication by password failed.\n");
goto shutdown;
}
} else {
@@ -146,7 +151,7 @@ int main(int argc, char *argv[])
"/home/username/.ssh/id_rsa.pub",
"/home/username/.ssh/id_rsa",
password)) {
printf("\tAuthentication by public key failed\n");
fprintf(stderr, "\tAuthentication by public key failed\n");
goto shutdown;
}
}
@@ -206,7 +211,7 @@ shutdown:
#endif
if (local)
fclose(local);
printf("all done\n");
fprintf(stderr, "all done\n");
libssh2_exit();

View File

@@ -94,8 +94,13 @@ int main(int argc, char *argv[])
#ifdef WIN32
WSADATA wsadata;
int err;
WSAStartup(MAKEWORD(2,0), &wsadata);
err = WSAStartup(MAKEWORD(2,0), &wsadata);
if (err != 0) {
fprintf(stderr, "WSAStartup failed with error: %d\n", err);
return 1;
}
#endif
if (argc > 1) {
@@ -125,7 +130,7 @@ int main(int argc, char *argv[])
local = fopen(loclfile, "rb");
if (!local) {
printf("Can't local file %s\n", loclfile);
fprintf(stderr, "Can't open local file %s\n", loclfile);
return -1;
}
@@ -169,18 +174,18 @@ int main(int argc, char *argv[])
* that's your call
*/
fingerprint = libssh2_hostkey_hash(session, LIBSSH2_HOSTKEY_HASH_SHA1);
printf("Fingerprint: ");
fprintf(stderr, "Fingerprint: ");
for(i = 0; i < 20; i++) {
printf("%02X ", (unsigned char)fingerprint[i]);
fprintf(stderr, "%02X ", (unsigned char)fingerprint[i]);
}
printf("\n");
fprintf(stderr, "\n");
if (auth_pw) {
/* We could authenticate via password */
while ((rc = libssh2_userauth_password(session, username, password)) ==
LIBSSH2_ERROR_EAGAIN);
if (rc) {
printf("Authentication by password failed.\n");
fprintf(stderr, "Authentication by password failed.\n");
goto shutdown;
}
} else {
@@ -191,7 +196,7 @@ int main(int argc, char *argv[])
password)) ==
LIBSSH2_ERROR_EAGAIN);
if (rc) {
printf("\tAuthentication by public key failed\n");
fprintf(stderr, "\tAuthentication by public key failed\n");
goto shutdown;
}
}
@@ -253,7 +258,7 @@ int main(int argc, char *argv[])
duration = (int)(time(NULL)-start);
printf("%ld bytes in %d seconds makes %.1f bytes/sec\n",
fprintf(stderr, "%ld bytes in %d seconds makes %.1f bytes/sec\n",
total, duration, total/(double)duration);
@@ -272,7 +277,7 @@ shutdown:
#else
close(sock);
#endif
printf("all done\n");
fprintf(stderr, "all done\n");
libssh2_exit();

View File

@@ -94,8 +94,13 @@ int main(int argc, char *argv[])
#ifdef WIN32
WSADATA wsadata;
int err;
WSAStartup(MAKEWORD(2,0), &wsadata);
err = WSAStartup(MAKEWORD(2,0), &wsadata);
if (err != 0) {
fprintf(stderr, "WSAStartup failed with error: %d\n", err);
return 1;
}
#endif
if (argc > 1) {
@@ -125,7 +130,7 @@ int main(int argc, char *argv[])
local = fopen(loclfile, "rb");
if (!local) {
printf("Can't local file %s\n", loclfile);
fprintf(stderr, "Can't open local file %s\n", loclfile);
return -1;
}
@@ -169,18 +174,18 @@ int main(int argc, char *argv[])
* that's your call
*/
fingerprint = libssh2_hostkey_hash(session, LIBSSH2_HOSTKEY_HASH_SHA1);
printf("Fingerprint: ");
fprintf(stderr, "Fingerprint: ");
for(i = 0; i < 20; i++) {
printf("%02X ", (unsigned char)fingerprint[i]);
fprintf(stderr, "%02X ", (unsigned char)fingerprint[i]);
}
printf("\n");
fprintf(stderr, "\n");
if (auth_pw) {
/* We could authenticate via password */
while ((rc = libssh2_userauth_password(session, username, password)) ==
LIBSSH2_ERROR_EAGAIN);
if (rc) {
printf("Authentication by password failed.\n");
fprintf(stderr, "Authentication by password failed.\n");
goto shutdown;
}
} else {
@@ -191,7 +196,7 @@ int main(int argc, char *argv[])
password)) ==
LIBSSH2_ERROR_EAGAIN);
if (rc) {
printf("\tAuthentication by public key failed\n");
fprintf(stderr, "\tAuthentication by public key failed\n");
goto shutdown;
}
}
@@ -262,7 +267,7 @@ int main(int argc, char *argv[])
duration = (int)(time(NULL)-start);
printf("%ld bytes in %d seconds makes %.1f bytes/sec\n",
fprintf(stderr, "%ld bytes in %d seconds makes %.1f bytes/sec\n",
total, duration, total/(double)duration);
@@ -281,7 +286,7 @@ shutdown:
#else
close(sock);
#endif
printf("all done\n");
fprintf(stderr, "all done\n");
libssh2_exit();

View File

@@ -52,24 +52,51 @@
#define PRIu64 __PRI64_PREFIX "u"
#endif /* PRIu64 */
const char *keyfile1="~/.ssh/id_rsa.pub";
const char *keyfile2="~/.ssh/id_rsa";
const char *username="username";
const char *password="password";
static void kbd_callback(const char *name, int name_len,
const char *instruction, int instruction_len,
int num_prompts,
const LIBSSH2_USERAUTH_KBDINT_PROMPT *prompts,
LIBSSH2_USERAUTH_KBDINT_RESPONSE *responses,
void **abstract)
{
(void)name;
(void)name_len;
(void)instruction;
(void)instruction_len;
if (num_prompts == 1) {
responses[0].text = strdup(password);
responses[0].length = strlen(password);
}
(void)prompts;
(void)abstract;
} /* kbd_callback */
int main(int argc, char *argv[])
{
unsigned long hostaddr;
int sock, i, auth_pw = 1;
int rc, sock, i, auth_pw = 0;
struct sockaddr_in sin;
const char *fingerprint;
char *userauthlist;
LIBSSH2_SESSION *session;
const char *username="username";
const char *password="password";
const char *sftppath="/tmp/secretdir";
int rc;
LIBSSH2_SFTP *sftp_session;
LIBSSH2_SFTP_HANDLE *sftp_handle;
#ifdef WIN32
WSADATA wsadata;
int err;
WSAStartup(MAKEWORD(2,0), &wsadata);
err = WSAStartup(MAKEWORD(2,0), &wsadata);
if (err != 0) {
fprintf(stderr, "WSAStartup failed with error: %d\n", err);
return 1;
}
#endif
if (argc > 1) {
@@ -130,27 +157,69 @@ int main(int argc, char *argv[])
* user, that's your call
*/
fingerprint = libssh2_hostkey_hash(session, LIBSSH2_HOSTKEY_HASH_SHA1);
printf("Fingerprint: ");
fprintf(stderr, "Fingerprint: ");
for(i = 0; i < 20; i++) {
printf("%02X ", (unsigned char)fingerprint[i]);
fprintf(stderr, "%02X ", (unsigned char)fingerprint[i]);
}
printf("\n");
fprintf(stderr, "\n");
if (auth_pw) {
/* check what authentication methods are available */
userauthlist = libssh2_userauth_list(session, username, strlen(username));
fprintf(stderr, "Authentication methods: %s\n", userauthlist);
if (strstr(userauthlist, "password") != NULL) {
auth_pw |= 1;
}
if (strstr(userauthlist, "keyboard-interactive") != NULL) {
auth_pw |= 2;
}
if (strstr(userauthlist, "publickey") != NULL) {
auth_pw |= 4;
}
/* if we got an 5. argument we set this option if supported */
if(argc > 5) {
if ((auth_pw & 1) && !strcasecmp(argv[5], "-p")) {
auth_pw = 1;
}
if ((auth_pw & 2) && !strcasecmp(argv[5], "-i")) {
auth_pw = 2;
}
if ((auth_pw & 4) && !strcasecmp(argv[5], "-k")) {
auth_pw = 4;
}
}
if (auth_pw & 1) {
/* We could authenticate via password */
if (libssh2_userauth_password(session, username, password)) {
printf("Authentication by password failed.\n");
fprintf(stderr, "\tAuthentication by password failed!\n");
goto shutdown;
} else {
fprintf(stderr, "\tAuthentication by password succeeded.\n");
}
} else if (auth_pw & 2) {
/* Or via keyboard-interactive */
if (libssh2_userauth_keyboard_interactive(session, username,
&kbd_callback) ) {
fprintf(stderr,
"\tAuthentication by keyboard-interactive failed!\n");
goto shutdown;
} else {
fprintf(stderr,
"\tAuthentication by keyboard-interactive succeeded.\n");
}
} else if (auth_pw & 4) {
/* Or by public key */
if (libssh2_userauth_publickey_fromfile(session, username, keyfile1,
keyfile2, password)) {
fprintf(stderr, "\tAuthentication by public key failed!\n");
goto shutdown;
} else {
fprintf(stderr, "\tAuthentication by public key succeeded.\n");
}
} else {
/* Or by public key */
if (libssh2_userauth_publickey_fromfile(session, username,
"/home/username/.ssh/id_rsa.pub",
"/home/username/.ssh/id_rsa",
password)) {
printf("\tAuthentication by public key failed\n");
goto shutdown;
}
fprintf(stderr, "No supported authentication methods found!\n");
goto shutdown;
}
fprintf(stderr, "libssh2_sftp_init()!\n");
@@ -229,7 +298,7 @@ int main(int argc, char *argv[])
#else
close(sock);
#endif
printf("all done\n");
fprintf(stderr, "all done\n");
libssh2_exit();

View File

@@ -68,8 +68,13 @@ int main(int argc, char *argv[])
#ifdef WIN32
WSADATA wsadata;
int err;
WSAStartup(MAKEWORD(2,0), &wsadata);
err = WSAStartup(MAKEWORD(2,0), &wsadata);
if (err != 0) {
fprintf(stderr, "WSAStartup failed with error: %d\n", err);
return 1;
}
#endif
if (argc > 1) {
@@ -134,11 +139,11 @@ int main(int argc, char *argv[])
* user, that's your call
*/
fingerprint = libssh2_hostkey_hash(session, LIBSSH2_HOSTKEY_HASH_SHA1);
printf("Fingerprint: ");
fprintf(stderr, "Fingerprint: ");
for(i = 0; i < 20; i++) {
printf("%02X ", (unsigned char)fingerprint[i]);
fprintf(stderr, "%02X ", (unsigned char)fingerprint[i]);
}
printf("\n");
fprintf(stderr, "\n");
if (auth_pw) {
/* We could authenticate via password */
@@ -239,7 +244,7 @@ int main(int argc, char *argv[])
#else
close(sock);
#endif
printf("all done\n");
fprintf(stderr, "all done\n");
libssh2_exit();

View File

@@ -72,10 +72,16 @@ int main(int argc, char *argv[])
char *userauthlist;
LIBSSH2_SESSION *session;
LIBSSH2_CHANNEL *channel;
#ifdef WIN32
WSADATA wsadata;
int err;
WSAStartup(MAKEWORD(2,0), &wsadata);
err = WSAStartup(MAKEWORD(2,0), &wsadata);
if (err != 0) {
fprintf(stderr, "WSAStartup failed with error: %d\n", err);
return 1;
}
#endif
if (argc > 1) {
@@ -126,15 +132,15 @@ int main(int argc, char *argv[])
* call
*/
fingerprint = libssh2_hostkey_hash(session, LIBSSH2_HOSTKEY_HASH_SHA1);
printf("Fingerprint: ");
fprintf(stderr, "Fingerprint: ");
for(i = 0; i < 20; i++) {
printf("%02X ", (unsigned char)fingerprint[i]);
fprintf(stderr, "%02X ", (unsigned char)fingerprint[i]);
}
printf("\n");
fprintf(stderr, "\n");
/* check what authentication methods are available */
userauthlist = libssh2_userauth_list(session, username, strlen(username));
printf("Authentication methods: %s\n", userauthlist);
fprintf(stderr, "Authentication methods: %s\n", userauthlist);
if (strstr(userauthlist, "password") != NULL) {
auth_pw |= 1;
}
@@ -161,31 +167,33 @@ int main(int argc, char *argv[])
if (auth_pw & 1) {
/* We could authenticate via password */
if (libssh2_userauth_password(session, username, password)) {
printf("\tAuthentication by password failed!\n");
fprintf(stderr, "\tAuthentication by password failed!\n");
goto shutdown;
} else {
printf("\tAuthentication by password succeeded.\n");
fprintf(stderr, "\tAuthentication by password succeeded.\n");
}
} else if (auth_pw & 2) {
/* Or via keyboard-interactive */
if (libssh2_userauth_keyboard_interactive(session, username,
&kbd_callback) ) {
printf("\tAuthentication by keyboard-interactive failed!\n");
fprintf(stderr,
"\tAuthentication by keyboard-interactive failed!\n");
goto shutdown;
} else {
printf("\tAuthentication by keyboard-interactive succeeded.\n");
fprintf(stderr,
"\tAuthentication by keyboard-interactive succeeded.\n");
}
} else if (auth_pw & 4) {
/* Or by public key */
if (libssh2_userauth_publickey_fromfile(session, username, keyfile1,
keyfile2, password)) {
printf("\tAuthentication by public key failed!\n");
fprintf(stderr, "\tAuthentication by public key failed!\n");
goto shutdown;
} else {
printf("\tAuthentication by public key succeeded.\n");
fprintf(stderr, "\tAuthentication by public key succeeded.\n");
}
} else {
printf("No supported authentication methods found!\n");
fprintf(stderr, "No supported authentication methods found!\n");
goto shutdown;
}
@@ -250,7 +258,7 @@ int main(int argc, char *argv[])
#else
close(sock);
#endif
printf("all done!\n");
fprintf(stderr, "all done!\n");
libssh2_exit();

View File

@@ -49,10 +49,16 @@ int main(int argc, char *argv[])
LIBSSH2_CHANNEL *channel;
LIBSSH2_AGENT *agent = NULL;
struct libssh2_agent_publickey *identity, *prev_identity = NULL;
#ifdef WIN32
WSADATA wsadata;
int err;
WSAStartup(MAKEWORD(2,0), &wsadata);
err = WSAStartup(MAKEWORD(2,0), &wsadata);
if (err != 0) {
fprintf(stderr, "WSAStartup failed with error: %d\n", err);
return 1;
}
#endif
if (argc > 1) {
@@ -105,15 +111,15 @@ int main(int argc, char *argv[])
* call
*/
fingerprint = libssh2_hostkey_hash(session, LIBSSH2_HOSTKEY_HASH_SHA1);
printf("Fingerprint: ");
fprintf(stderr, "Fingerprint: ");
for(i = 0; i < 20; i++) {
printf("%02X ", (unsigned char)fingerprint[i]);
fprintf(stderr, "%02X ", (unsigned char)fingerprint[i]);
}
printf("\n");
fprintf(stderr, "\n");
/* check what authentication methods are available */
userauthlist = libssh2_userauth_list(session, username, strlen(username));
printf("Authentication methods: %s\n", userauthlist);
fprintf(stderr, "Authentication methods: %s\n", userauthlist);
if (strstr(userauthlist, "publickey") == NULL) {
fprintf(stderr, "\"publickey\" authentication is not supported\n");
goto shutdown;
@@ -147,11 +153,11 @@ int main(int argc, char *argv[])
goto shutdown;
}
if (libssh2_agent_userauth(agent, username, identity)) {
printf("\tAuthentication with username %s and "
fprintf(stderr, "\tAuthentication with username %s and "
"public key %s failed!\n",
username, identity->comment);
} else {
printf("\tAuthentication with username %s and "
fprintf(stderr, "\tAuthentication with username %s and "
"public key %s succeeded!\n",
username, identity->comment);
break;
@@ -234,7 +240,7 @@ int main(int argc, char *argv[])
#endif
}
printf("all done!\n");
fprintf(stderr, "all done!\n");
libssh2_exit();

View File

@@ -91,8 +91,15 @@ int main(int argc, char *argv[])
#ifdef WIN32
WSADATA wsadata;
WSAStartup(MAKEWORD(2,0), &wsadata);
int err;
err = WSAStartup(MAKEWORD(2,0), &wsadata);
if (err != 0) {
fprintf(stderr, "WSAStartup failed with error: %d\n", err);
return 1;
}
#endif
if (argc > 1)
/* must be ip address only */
hostname = argv[1];
@@ -327,7 +334,7 @@ int main(int argc, char *argv[])
}
if (exitsignal)
printf("\nGot signal: %s\n", exitsignal);
fprintf(stderr, "\nGot signal: %s\n", exitsignal);
libssh2_channel_free(channel);
channel = NULL;

View File

@@ -92,8 +92,15 @@ int main(int argc, char *argv[])
#ifdef WIN32
WSADATA wsadata;
WSAStartup(MAKEWORD(2,0), &wsadata);
int err;
err = WSAStartup(MAKEWORD(2,0), &wsadata);
if (err != 0) {
fprintf(stderr, "WSAStartup failed with error: %d\n", err);
return 1;
}
#endif
if (argc > 1)
/* must be ip address only */
hostname = argv[1];
@@ -292,9 +299,9 @@ int main(int argc, char *argv[])
}
if (exitsignal)
printf("\nGot signal: %s\n", exitsignal);
fprintf(stderr, "\nGot signal: %s\n", exitsignal);
else
printf("\nEXIT: %d bytecount: %d\n", exitcode, bytecount);
fprintf(stderr, "\nEXIT: %d bytecount: %d\n", exitcode, bytecount);
libssh2_channel_free(channel);
channel = NULL;

View File

@@ -102,7 +102,7 @@ static int netconf_read_until(LIBSSH2_CHANNEL *channel, const char *endtag,
int main(int argc, char *argv[])
{
int rc, sock = -1, i, auth = AUTH_NONE;
int rc, i, auth = AUTH_NONE;
struct sockaddr_in sin;
const char *fingerprint;
char *userauthlist;
@@ -112,9 +112,17 @@ int main(int argc, char *argv[])
ssize_t len;
#ifdef WIN32
SOCKET sock = INVALID_SOCKET;
WSADATA wsadata;
int err;
WSAStartup(MAKEWORD(2,0), &wsadata);
err = WSAStartup(MAKEWORD(2,0), &wsadata);
if (err != 0) {
fprintf(stderr, "WSAStartup failed with error: %d\n", err);
return 1;
}
#else
int sock = -1;
#endif
if (argc > 1)
@@ -132,6 +140,18 @@ int main(int argc, char *argv[])
/* Connect to SSH server */
sock = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP);
#ifdef WIN32
if (sock == INVALID_SOCKET) {
fprintf(stderr, "failed to open socket!\n");
return -1;
}
#else
if (sock == -1) {
perror("socket");
return -1;
}
#endif
sin.sin_family = AF_INET;
if (INADDR_NONE == (sin.sin_addr.s_addr = inet_addr(server_ip))) {
fprintf(stderr, "inet_addr: Invalid IP address \"%s\"\n", server_ip);
@@ -173,7 +193,7 @@ int main(int argc, char *argv[])
/* check what authentication methods are available */
userauthlist = libssh2_userauth_list(session, username, strlen(username));
printf("Authentication methods: %s\n", userauthlist);
fprintf(stderr, "Authentication methods: %s\n", userauthlist);
if (strstr(userauthlist, "password"))
auth |= AUTH_PASSWORD;
if (strstr(userauthlist, "publickey"))
@@ -195,12 +215,12 @@ int main(int argc, char *argv[])
} else if (auth & AUTH_PUBLICKEY) {
if (libssh2_userauth_publickey_fromfile(session, username, keyfile1,
keyfile2, password)) {
printf("Authentication by public key failed!\n");
fprintf(stderr, "Authentication by public key failed!\n");
goto shutdown;
}
printf("Authentication by public key succeeded.\n");
fprintf(stderr, "Authentication by public key succeeded.\n");
} else {
printf("No supported authentication methods found!\n");
fprintf(stderr, "No supported authentication methods found!\n");
goto shutdown;
}
@@ -223,7 +243,7 @@ int main(int argc, char *argv[])
/* NETCONF: http://tools.ietf.org/html/draft-ietf-netconf-ssh-06 */
printf("Sending NETCONF client <hello>\n");
fprintf(stderr, "Sending NETCONF client <hello>\n");
snprintf(buf, sizeof(buf),
"<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"
"<hello>"
@@ -235,14 +255,14 @@ int main(int argc, char *argv[])
if (-1 == netconf_write(channel, buf, len))
goto shutdown;
printf("Reading NETCONF server <hello>\n");
fprintf(stderr, "Reading NETCONF server <hello>\n");
len = netconf_read_until(channel, "</hello>", buf, sizeof(buf));
if (-1 == len)
goto shutdown;
printf("Got %d bytes:\n----------------------\n%s", (int)len, buf);
fprintf(stderr, "Got %d bytes:\n----------------------\n%s", (int)len, buf);
printf("Sending NETCONF <rpc>\n");
fprintf(stderr, "Sending NETCONF <rpc>\n");
snprintf(buf, sizeof(buf),
"<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"
"<rpc xmlns=\"urn:ietf:params:xml:ns:netconf:base:1.0\">"
@@ -252,12 +272,12 @@ int main(int argc, char *argv[])
if (-1 == netconf_write(channel, buf, len))
goto shutdown;
printf("Reading NETCONF <rpc-reply>\n");
fprintf(stderr, "Reading NETCONF <rpc-reply>\n");
len = netconf_read_until(channel, "</rpc-reply>", buf, sizeof(buf));
if (-1 == len)
goto shutdown;
printf("Got %d bytes:\n----------------------\n%s", (int)len, buf);
fprintf(stderr, "Got %d bytes:\n----------------------\n%s", (int)len, buf);
shutdown:
if (channel)

View File

@@ -35,11 +35,11 @@ const char *password = "";
const char *server_ip = "127.0.0.1";
const char *remote_listenhost = "localhost"; /* resolved by the server */
unsigned int remote_wantport = 2222;
unsigned int remote_listenport;
int remote_wantport = 2222;
int remote_listenport;
const char *local_destip = "127.0.0.1";
unsigned int local_destport = 22;
int local_destport = 22;
enum {
AUTH_NONE = 0,
@@ -49,7 +49,7 @@ enum {
int main(int argc, char *argv[])
{
int rc, sock = -1, forwardsock = -1, i, auth = AUTH_NONE;
int rc, i, auth = AUTH_NONE;
struct sockaddr_in sin;
socklen_t sinlen = sizeof(sin);
const char *fingerprint;
@@ -57,20 +57,23 @@ int main(int argc, char *argv[])
LIBSSH2_SESSION *session;
LIBSSH2_LISTENER *listener = NULL;
LIBSSH2_CHANNEL *channel = NULL;
const char *shost;
unsigned int sport;
fd_set fds;
struct timeval tv;
ssize_t len, wr;
char buf[16384];
#ifdef WIN32
char sockopt;
SOCKET sock = INVALID_SOCKET, forwardsock = INVALID_SOCKET;
WSADATA wsadata;
int err;
WSAStartup(MAKEWORD(2,0), &wsadata);
err = WSAStartup(MAKEWORD(2,0), &wsadata);
if (err != 0) {
fprintf(stderr, "WSAStartup failed with error: %d\n", err);
return 1;
}
#else
int sockopt;
int sock = -1, forwardsock = -1;
#endif
if (argc > 1)
@@ -96,6 +99,18 @@ int main(int argc, char *argv[])
/* Connect to SSH server */
sock = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP);
#ifdef WIN32
if (sock == INVALID_SOCKET) {
fprintf(stderr, "failed to open socket!\n");
return -1;
}
#else
if (sock == -1) {
perror("socket");
return -1;
}
#endif
sin.sin_family = AF_INET;
if (INADDR_NONE == (sin.sin_addr.s_addr = inet_addr(server_ip))) {
perror("inet_addr");
@@ -137,7 +152,7 @@ int main(int argc, char *argv[])
/* check what authentication methods are available */
userauthlist = libssh2_userauth_list(session, username, strlen(username));
printf("Authentication methods: %s\n", userauthlist);
fprintf(stderr, "Authentication methods: %s\n", userauthlist);
if (strstr(userauthlist, "password"))
auth |= AUTH_PASSWORD;
if (strstr(userauthlist, "publickey"))
@@ -159,17 +174,17 @@ int main(int argc, char *argv[])
} else if (auth & AUTH_PUBLICKEY) {
if (libssh2_userauth_publickey_fromfile(session, username, keyfile1,
keyfile2, password)) {
printf("\tAuthentication by public key failed!\n");
fprintf(stderr, "\tAuthentication by public key failed!\n");
goto shutdown;
}
printf("\tAuthentication by public key succeeded.\n");
fprintf(stderr, "\tAuthentication by public key succeeded.\n");
} else {
printf("No supported authentication methods found!\n");
fprintf(stderr, "No supported authentication methods found!\n");
goto shutdown;
}
printf("Asking server to listen on remote %s:%d\n", remote_listenhost,
remote_wantport);
fprintf(stderr, "Asking server to listen on remote %s:%d\n",
remote_listenhost, remote_wantport);
listener = libssh2_channel_forward_listen_ex(session, remote_listenhost,
remote_wantport, &remote_listenport, 1);
@@ -180,10 +195,10 @@ int main(int argc, char *argv[])
goto shutdown;
}
printf("Server is listening on %s:%d\n", remote_listenhost,
fprintf(stderr, "Server is listening on %s:%d\n", remote_listenhost,
remote_listenport);
printf("Waiting for remote connection\n");
fprintf(stderr, "Waiting for remote connection\n");
channel = libssh2_channel_forward_accept(listener);
if (!channel) {
fprintf(stderr, "Could not accept connection!\n"
@@ -192,9 +207,22 @@ int main(int argc, char *argv[])
goto shutdown;
}
printf("Accepted remote connection. Connecting to local server %s:%d\n",
fprintf(stderr,
"Accepted remote connection. Connecting to local server %s:%d\n",
local_destip, local_destport);
forwardsock = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP);
#ifdef WIN32
if (forwardsock == INVALID_SOCKET) {
fprintf(stderr, "failed to open forward socket!\n");
goto shutdown;
}
#else
if (forwardsock == -1) {
perror("socket");
goto shutdown;
}
#endif
sin.sin_family = AF_INET;
sin.sin_port = htons(local_destport);
if (INADDR_NONE == (sin.sin_addr.s_addr = inet_addr(local_destip))) {
@@ -206,7 +234,7 @@ int main(int argc, char *argv[])
goto shutdown;
}
printf("Forwarding connection from remote %s:%d to local %s:%d\n",
fprintf(stderr, "Forwarding connection from remote %s:%d to local %s:%d\n",
remote_listenhost, remote_listenport, local_destip, local_destport);
/* Must use non-blocking IO hereafter due to the current libssh2 API */
@@ -228,7 +256,7 @@ int main(int argc, char *argv[])
perror("read");
goto shutdown;
} else if (0 == len) {
printf("The local server at %s:%d disconnected!\n",
fprintf(stderr, "The local server at %s:%d disconnected!\n",
local_destip, local_destport);
goto shutdown;
}
@@ -260,7 +288,7 @@ int main(int argc, char *argv[])
wr += i;
}
if (libssh2_channel_eof(channel)) {
printf("The remote client at %s:%d disconnected!\n",
fprintf(stderr, "The remote client at %s:%d disconnected!\n",
remote_listenhost, remote_listenport);
goto shutdown;
}

View File

@@ -10,6 +10,7 @@
#include <sys/ioctl.h>
#include <netinet/in.h>
#include <sys/socket.h>
#include <sys/select.h>
#include <arpa/inet.h>
#include <unistd.h>
#include <sys/types.h>
@@ -48,13 +49,13 @@ static void remove_node(struct chan_X11_list *elem)
current_node = gp_x11_chan;
if (gp_x11_chan == elem) {
/* Removing the only one element in the list */
free(gp_x11_chan);
gp_x11_chan = NULL;
gp_x11_chan = gp_x11_chan->next;
free(current_node);
return;
}
while( current_node->next != NULL) {
if (current_node->next ==elem) {
while (current_node->next != NULL) {
if (current_node->next == elem) {
current_node->next = current_node->next->next;
current_node = current_node->next;
free(current_node);
@@ -209,24 +210,27 @@ static int x11_send_receive(LIBSSH2_CHANNEL *channel, int sock)
rc = libssh2_poll(fds, nfds, 0);
if (rc >0) {
rc = libssh2_channel_read(channel, buf, bufsize);
rc = write(sock, buf, rc);
write(sock, buf, rc);
}
rc = select(sock+1,&set,NULL,NULL,&timeval_out);
rc = select(sock+1, &set, NULL, NULL, &timeval_out);
if (rc > 0) {
memset((void *)buf,0,bufsize);
memset((void *)buf, 0, bufsize);
/* Data in sock*/
rc = read(sock, buf, bufsize);
if (rc > 0)
rc = libssh2_channel_write(channel,buf, rc);
else
if (rc > 0) {
libssh2_channel_write(channel, buf, rc);
}
else {
free(buf);
return -1;
}
}
free(fds);
free(buf);
if (libssh2_channel_eof (channel) == 1) {
if (libssh2_channel_eof(channel) == 1) {
return -1;
}
return 0;
@@ -289,6 +293,10 @@ main (int argc, char *argv[])
}
sock = socket (AF_INET, SOCK_STREAM, 0);
if (sock == -1) {
perror("socket");
return -1;
}
sin.sin_family = AF_INET;
sin.sin_port = htons (22);
@@ -369,6 +377,9 @@ main (int argc, char *argv[])
return -1;
}
memset(&w_size, 0, sizeof(struct winsize));
memset(&w_size_bck, 0, sizeof(struct winsize));
while (1) {
FD_ZERO(&set);
@@ -400,7 +411,7 @@ main (int argc, char *argv[])
rc = libssh2_poll(fds, nfds, 0);
if (rc >0) {
rc = libssh2_channel_read(channel, buf,sizeof(buf));
libssh2_channel_read(channel, buf, sizeof(buf));
fprintf(stdout, "%s", buf);
fflush(stdout);
}

View File

@@ -1,5 +1,5 @@
/* Copyright (c) 2004-2009, Sara Golemon <sarag@libssh2.org>
* Copyright (c) 2009-2010 Daniel Stenberg
* Copyright (c) 2009-2012 Daniel Stenberg
* Copyright (c) 2010 Simon Josefsson <simon@josefsson.org>
* All rights reserved.
*
@@ -40,19 +40,19 @@
#ifndef LIBSSH2_H
#define LIBSSH2_H 1
#define LIBSSH2_COPYRIGHT "2004-2011 The libssh2 project and its contributors."
#define LIBSSH2_COPYRIGHT "2004-2014 The libssh2 project and its contributors."
/* We use underscore instead of dash when appending DEV in dev versions just
to make the BANNER define (used by src/session.c) be a valid SSH
banner. Release versions have no appended strings and may of course not
have dashes either. */
#define LIBSSH2_VERSION "1.4.0_DEV"
#define LIBSSH2_VERSION "1.4.4_DEV"
/* The numeric version number is also available "in parts" by using these
defines: */
#define LIBSSH2_VERSION_MAJOR 1
#define LIBSSH2_VERSION_MINOR 4
#define LIBSSH2_VERSION_PATCH 0
#define LIBSSH2_VERSION_PATCH 4
/* This is the numeric version of the libssh2 version number, meant for easier
parsing and comparions by programs. The LIBSSH2_VERSION_NUM define will
@@ -69,7 +69,7 @@
and it is always a greater number in a more recent release. It makes
comparisons with greater than and less than work.
*/
#define LIBSSH2_VERSION_NUM 0x010400
#define LIBSSH2_VERSION_NUM 0x010404
/*
* This is the date and time when the full source package was created. The
@@ -100,11 +100,15 @@ extern "C" {
/* Allow alternate API prefix from CFLAGS or calling app */
#ifndef LIBSSH2_API
# ifdef LIBSSH2_WIN32
# ifdef LIBSSH2_LIBRARY
# define LIBSSH2_API __declspec(dllexport)
# ifdef _WINDLL
# ifdef LIBSSH2_LIBRARY
# define LIBSSH2_API __declspec(dllexport)
# else
# define LIBSSH2_API __declspec(dllimport)
# endif /* LIBSSH2_LIBRARY */
# else
# define LIBSSH2_API __declspec(dllimport)
# endif /* LIBSSH2_LIBRARY */
# define LIBSSH2_API
# endif
# else /* !LIBSSH2_WIN32 */
# define LIBSSH2_API
# endif /* LIBSSH2_WIN32 */
@@ -281,7 +285,8 @@ typedef struct _LIBSSH2_POLLFD {
unsigned char type; /* LIBSSH2_POLLFD_* below */
union {
int socket; /* File descriptors -- examined with system select() call */
libssh2_socket_t socket; /* File descriptors -- examined with
system select() call */
LIBSSH2_CHANNEL *channel; /* Examined by checking internal state */
LIBSSH2_LISTENER *listener; /* Read polls only -- are inbound
connections waiting to be accepted? */
@@ -405,6 +410,7 @@ typedef struct _LIBSSH2_POLLFD {
#define LIBSSH2_ERROR_SOCKET_RECV -43
#define LIBSSH2_ERROR_ENCRYPT -44
#define LIBSSH2_ERROR_BAD_SOCKET -45
#define LIBSSH2_ERROR_KNOWN_HOSTS -46
/* this is a define to provide the old (<= 1.2.7) name */
#define LIBSSH2_ERROR_BANNER_NONE LIBSSH2_ERROR_BANNER_RECV
@@ -520,8 +526,9 @@ LIBSSH2_API int libssh2_userauth_password_ex(LIBSSH2_SESSION *session,
LIBSSH2_PASSWD_CHANGEREQ_FUNC((*passwd_change_cb)));
#define libssh2_userauth_password(session, username, password) \
libssh2_userauth_password_ex((session), (username), strlen(username), \
(password), strlen(password), NULL)
libssh2_userauth_password_ex((session), (username), \
(unsigned int)strlen(username), \
(password), (unsigned int)strlen(password), NULL)
LIBSSH2_API int
libssh2_userauth_publickey_fromfile_ex(LIBSSH2_SESSION *session,
@@ -533,9 +540,10 @@ libssh2_userauth_publickey_fromfile_ex(LIBSSH2_SESSION *session,
#define libssh2_userauth_publickey_fromfile(session, username, publickey, \
privatekey, passphrase) \
libssh2_userauth_publickey_fromfile_ex((session), (username), \
strlen(username), (publickey), \
(privatekey), (passphrase))
libssh2_userauth_publickey_fromfile_ex((session), (username), \
(unsigned int)strlen(username), \
(publickey), \
(privatekey), (passphrase))
LIBSSH2_API int
libssh2_userauth_publickey(LIBSSH2_SESSION *session,
@@ -560,10 +568,13 @@ libssh2_userauth_hostbased_fromfile_ex(LIBSSH2_SESSION *session,
#define libssh2_userauth_hostbased_fromfile(session, username, publickey, \
privatekey, passphrase, hostname) \
libssh2_userauth_hostbased_fromfile_ex((session), (username), \
strlen(username), (publickey), \
(privatekey), (passphrase), \
(hostname), strlen(hostname), \
(username), strlen(username))
(unsigned int)strlen(username), \
(publickey), \
(privatekey), (passphrase), \
(hostname), \
(unsigned int)strlen(hostname), \
(username), \
(unsigned int)strlen(username))
/*
* response_callback is provided with filled by library prompts array,
@@ -577,16 +588,17 @@ libssh2_userauth_keyboard_interactive_ex(LIBSSH2_SESSION* session,
unsigned int username_len,
LIBSSH2_USERAUTH_KBDINT_RESPONSE_FUNC((*response_callback)));
#define libssh2_userauth_keyboard_interactive(session, username, \
response_callback) \
libssh2_userauth_keyboard_interactive_ex((session), (username), \
strlen(username), (response_callback))
#define libssh2_userauth_keyboard_interactive(session, username, \
response_callback) \
libssh2_userauth_keyboard_interactive_ex((session), (username), \
(unsigned int)strlen(username), \
(response_callback))
LIBSSH2_API int libssh2_poll(LIBSSH2_POLLFD *fds, unsigned int nfds,
long timeout);
/* Channel API */
#define LIBSSH2_CHANNEL_WINDOW_DEFAULT (256*1024)
#define LIBSSH2_CHANNEL_WINDOW_DEFAULT (2*1024*1024)
#define LIBSSH2_CHANNEL_PACKET_DEFAULT 32768
#define LIBSSH2_CHANNEL_MINADJUST 1024
@@ -634,9 +646,10 @@ LIBSSH2_API int libssh2_channel_setenv_ex(LIBSSH2_CHANNEL *channel,
const char *value,
unsigned int value_len);
#define libssh2_channel_setenv(channel, varname, value) \
libssh2_channel_setenv_ex((channel), (varname), strlen(varname), (value), \
strlen(value))
#define libssh2_channel_setenv(channel, varname, value) \
libssh2_channel_setenv_ex((channel), (varname), \
(unsigned int)strlen(varname), (value), \
(unsigned int)strlen(value))
LIBSSH2_API int libssh2_channel_request_pty_ex(LIBSSH2_CHANNEL *channel,
const char *term,
@@ -645,10 +658,12 @@ LIBSSH2_API int libssh2_channel_request_pty_ex(LIBSSH2_CHANNEL *channel,
unsigned int modes_len,
int width, int height,
int width_px, int height_px);
#define libssh2_channel_request_pty(channel, term) \
libssh2_channel_request_pty_ex((channel), (term), strlen(term), NULL, 0, \
LIBSSH2_TERM_WIDTH, LIBSSH2_TERM_HEIGHT, \
LIBSSH2_TERM_WIDTH_PX, LIBSSH2_TERM_HEIGHT_PX)
#define libssh2_channel_request_pty(channel, term) \
libssh2_channel_request_pty_ex((channel), (term), \
(unsigned int)strlen(term), \
NULL, 0, \
LIBSSH2_TERM_WIDTH, LIBSSH2_TERM_HEIGHT, \
LIBSSH2_TERM_WIDTH_PX, LIBSSH2_TERM_HEIGHT_PX)
LIBSSH2_API int libssh2_channel_request_pty_size_ex(LIBSSH2_CHANNEL *channel,
int width, int height,
@@ -675,11 +690,11 @@ LIBSSH2_API int libssh2_channel_process_startup(LIBSSH2_CHANNEL *channel,
NULL, 0)
#define libssh2_channel_exec(channel, command) \
libssh2_channel_process_startup((channel), "exec", sizeof("exec") - 1, \
(command), strlen(command))
(command), (unsigned int)strlen(command))
#define libssh2_channel_subsystem(channel, subsystem) \
libssh2_channel_process_startup((channel), "subsystem", \
sizeof("subsystem") - 1, (subsystem), \
strlen(subsystem))
(unsigned int)strlen(subsystem))
LIBSSH2_API ssize_t libssh2_channel_read_ex(LIBSSH2_CHANNEL *channel,
int stream_id, char *buf,
@@ -855,11 +870,12 @@ libssh2_knownhost_init(LIBSSH2_SESSION *session);
#define LIBSSH2_KNOWNHOST_KEYENC_BASE64 (2<<16)
/* type of key (2 bits) */
#define LIBSSH2_KNOWNHOST_KEY_MASK (3<<18)
#define LIBSSH2_KNOWNHOST_KEY_MASK (7<<18)
#define LIBSSH2_KNOWNHOST_KEY_SHIFT 18
#define LIBSSH2_KNOWNHOST_KEY_RSA1 (1<<18)
#define LIBSSH2_KNOWNHOST_KEY_SSHRSA (2<<18)
#define LIBSSH2_KNOWNHOST_KEY_SSHDSS (3<<18)
#define LIBSSH2_KNOWNHOST_KEY_UNKNOWN (7<<18)
LIBSSH2_API int
libssh2_knownhost_add(LIBSSH2_KNOWNHOSTS *hosts,

View File

@@ -247,6 +247,7 @@ LIBSSH2_API int libssh2_sftp_readdir_ex(LIBSSH2_SFTP_HANDLE *handle, \
LIBSSH2_API ssize_t libssh2_sftp_write(LIBSSH2_SFTP_HANDLE *handle,
const char *buffer, size_t count);
LIBSSH2_API int libssh2_sftp_fsync(LIBSSH2_SFTP_HANDLE *handle);
LIBSSH2_API int libssh2_sftp_close_handle(LIBSSH2_SFTP_HANDLE *handle);
#define libssh2_sftp_close(handle) libssh2_sftp_close_handle(handle)

View File

@@ -11,6 +11,7 @@ Name: libssh2
URL: http://www.libssh2.org/
Description: Library for SSH-based communication
Version: @LIBSSH2VER@
Requires.private: @LIBSREQUIRED@
Libs: -L${libdir} -lssh2 @LDFLAGS@ @LIBS@
Libs.private: @LIBS@
Cflags: -I${includedir}

View File

@@ -1,7 +1,7 @@
#########################################################################
#
## Makefile for building libssh2 (NetWare version - gnu make)
## Use: make -f Makefile.netware [help|all|clean|dev|devclean|dist|distclean|lib|nlm|objclean]
## Use: make [help|all|clean|dev|devclean|dist|distclean|lib|nlm|objclean]
##
## Hacked by: Guenter Knauf
#
@@ -14,12 +14,12 @@ endif
# Edit the path below to point to the base of your Zlib sources.
ifndef ZLIB_PATH
ZLIB_PATH = ../../zlib-1.2.5
ZLIB_PATH = ../../zlib-1.2.8
endif
# Edit the path below to point to the base of your OpenSSL package.
ifndef OPENSSL_PATH
OPENSSL_PATH = ../../openssl-0.9.8r
OPENSSL_PATH = ../../openssl-0.9.8zc
endif
# Edit the path below to point to your Distribution folder.
@@ -37,7 +37,7 @@ DEVLARC = $(DEVLDIR).zip
# Edit the vars below to change NLM target settings.
TARGET = libssh2
VERSION = $(LIBSSH2_VERSION)
COPYR = Copyright (c) $(LIBSSH2_COPYRIGHT_STR)
CPRIGHT = Copyright (c) $(LIBSSH2_COPYRIGHT_STR)
WWWURL = http://www.libssh2.org/
DESCR = libssh2 $(LIBSSH2_VERSION_STR) ($(LIBARCH)) - $(WWWURL)
MTSAFE = YES
@@ -76,10 +76,7 @@ ifdef METROWERKS
else
CC = $(CROSSPREFIX)gcc
endif
CP = cp -afv
MD = mkdir
RD = rm -fr
# RM = rm -f
# Here you can find a native Win32 binary of the original awk:
# http://www.gknw.net/development/prgtools/awk-20100523.zip
AWK = awk
@@ -89,6 +86,34 @@ AWK = awk
MPKXDC = mkxdc
ZIP = zip -qzr9
# Platform-dependent helper tool macros
ifeq ($(findstring /sh,$(SHELL)),/sh)
DEL = rm -f $1
RMDIR = rm -fr $1
MKDIR = mkdir -p $1
COPY = -cp -afv $1 $2
#COPYR = -cp -afr $1/* $2
COPYR = -rsync -aC $1/* $2
TOUCH = touch $1
CAT = cat
ECHONL = echo ""
DL = '
else
ifeq "$(OS)" "Windows_NT"
DEL = -del 2>NUL /q /f $(subst /,\,$1)
RMDIR = -rd 2>NUL /q /s $(subst /,\,$1)
else
DEL = -del 2>NUL $(subst /,\,$1)
RMDIR = -deltree 2>NUL /y $(subst /,\,$1)
endif
MKDIR = -md 2>NUL $(subst /,\,$1)
COPY = -copy 2>NUL /y $(subst /,\,$1) $(subst /,\,$2)
COPYR = -xcopy 2>NUL /q /y /e $(subst /,\,$1) $(subst /,\,$2)
TOUCH = copy 2>&1>NUL /b $(subst /,\,$1) +,,
CAT = type
ECHONL = $(ComSpec) /c echo.
endif
# LIBARCH_U = $(shell $(AWK) 'BEGIN {print toupper(ARGV[1])}' $(LIBARCH))
LIBARCH_L = $(shell $(AWK) 'BEGIN {print tolower(ARGV[1])}' $(LIBARCH))
@@ -120,13 +145,14 @@ else
endif
else
LD = $(CROSSPREFIX)nlmconv
LDFLAGS = -T
LDFLAGS = -UT
AR = $(CROSSPREFIX)ar
ARFLAGS = -cq
LIBEXT = a
RANLIB = $(CROSSPREFIX)ranlib
CFLAGS += -m32
CFLAGS += -fno-builtin -fpcc-struct-return -fno-strict-aliasing
CFLAGS += -m32
CFLAGS += -fno-builtin -fpcc-struct-return
CFLAGS += -fno-strict-aliasing
CFLAGS += -Wall # -pedantic
#CFLAGS += -Wno-pointer-sign
ifeq ($(LIBARCH),LIBC)
@@ -185,15 +211,12 @@ ifdef XDCOPT
XDCDATA = $(OBJDIR)/$(TARGET).xdc
endif
ifeq ($(findstring /sh,$(SHELL)),/sh)
DL = '
DS = /
else
DS = \\
endif
vpath %.c . ../src
# only OpenSSL is supported with this build system
CFLAGS += -DLIBSSH2_OPENSSL
include ../Makefile.OpenSSL.inc
# include Makefile.inc to get CSOURCES define
include ../Makefile.inc
@@ -217,69 +240,74 @@ lib: prebuild $(TARGET).$(LIBEXT)
prebuild: $(OBJDIR) $(OBJDIR)/version.inc libssh2_config.h
test: all
$(MAKE) -C test -f Makefile.netware
$(MAKE) -C test
$(OBJDIR)/%.o: %.c
# @echo Compiling $<
$(CC) $(CFLAGS) -c $< -o $@
$(OBJDIR)/version.inc: ../include/libssh2.h $(OBJDIR)
$(OBJDIR)/version.inc: ../get_ver.awk ../include/libssh2.h $(OBJDIR)
@echo Creating $@
@$(AWK) -f ../get_ver.awk $< > $@
@$(AWK) -f $^ > $@
dist: all $(DISTDIR) $(DISTDIR)/readme.txt
@-$(MD) $(DISTDIR)$(DS)bin
@-$(CP) ../COPYING $(DISTDIR)
@-$(CP) ../INSTALL $(DISTDIR)
@-$(CP) ../README $(DISTDIR)
@$(CP) $(TARGET).nlm $(DISTDIR)/bin
@$(call MKDIR, $(DISTDIR)/bin)
@$(call COPY, ../AUTHORS, $(DISTDIR))
@$(call COPY, ../COPYING, $(DISTDIR))
@$(call COPY, ../INSTALL, $(DISTDIR))
@$(call COPY, ../README, $(DISTDIR))
@$(call COPY, ../RELEASE-NOTES, $(DISTDIR))
@$(call COPY, $(TARGET).nlm, $(DISTDIR)/bin)
@echo Creating $(DISTARC)
@$(ZIP) $(DISTARC) $(DISTDIR)/* < $(DISTDIR)/readme.txt
dev: all $(DEVLDIR) $(DEVLDIR)/readme.txt
@-$(MD) $(DEVLDIR)$(DS)bin
@-$(MD) $(DEVLDIR)$(DS)include
@-$(MD) $(DEVLDIR)$(DS)nw
@-$(CP) ../COPYING $(DISTDIR)
@-$(CP) ../INSTALL $(DEVLDIR)
@-$(CP) ../README $(DEVLDIR)
@$(CP) $(TARGET).nlm $(DEVLDIR)/bin
@$(CP) ../include/*.h $(DEVLDIR)/include
@$(CP) libssh2_config.h $(DEVLDIR)/include
@$(CP) $(TARGET).$(LIBEXT) $(DEVLDIR)/nw
@$(call MKDIR, $(DEVLDIR)/bin)
@$(call MKDIR, $(DEVLDIR)/include)
@$(call MKDIR, $(DEVLDIR)/nw)
@$(call COPY, ../AUTHORS, $(DEVLDIR))
@$(call COPY, ../COPYING, $(DEVLDIR))
@$(call COPY, ../INSTALL, $(DEVLDIR))
@$(call COPY, ../README, $(DEVLDIR))
@$(call COPY, ../RELEASE-NOTES, $(DEVLDIR))
@$(call COPY, ../include/*.h, $(DEVLDIR)/include)
@$(call COPY, libssh2_config.h, $(DEVLDIR)/include)
@$(call COPY, $(TARGET).nlm, $(DEVLDIR)/bin)
@$(call COPY, $(TARGET).imp, $(DEVLDIR)/nw)
@$(call COPY, $(TARGET).$(LIBEXT), $(DEVLDIR)/nw)
@echo Creating $(DEVLARC)
@$(ZIP) $(DEVLARC) $(DEVLDIR)/* < $(DEVLDIR)/readme.txt
distclean: clean
-$(RD) $(DISTDIR)
-$(RM) $(DISTARC)
$(call RMDIR, $(DISTDIR))
$(call DEL, $(DISTARC))
devclean: clean
-$(RD) $(DEVLDIR)
-$(RM) $(DEVLARC)
$(call RMDIR, $(DEVLDIR))
$(call DEL, $(DEVLARC))
objclean:
-$(RD) $(OBJDIR)
$(call RMDIR, $(OBJDIR))
testclean: clean
$(MAKE) -C test -f Makefile.netware clean
$(MAKE) -C test clean
clean: objclean
-$(RM) libssh2_config.h
-$(RM) $(TARGET).nlm $(TARGET).$(LIBEXT) $(TARGET).imp
$(call DEL, libssh2_config.h)
$(call DEL, $(TARGET).*)
$(OBJDIR):
@$(MD) $@
@$(call MKDIR, $@)
$(DISTDIR):
@$(MD) $@
@$(call MKDIR, $@)
$(DEVLDIR):
@$(MD) $@
@$(call MKDIR, $@)
$(TARGET).$(LIBEXT): $(OBJS)
@echo Creating $@
@-$(RM) $@
@$(call DEL, $@)
@$(AR) $(ARFLAGS) $@ $^
ifdef RANLIB
@$(RANLIB) $@
@@ -287,19 +315,19 @@ endif
$(TARGET).nlm: $(OBJDIR)/$(TARGET).def $(TARGET).imp $(OBJL) $(XDCDATA)
@echo Linking $@
@-$(RM) $@
@$(call DEL, $@)
@$(LD) $(LDFLAGS) $<
$(OBJDIR)/%.xdc: Makefile.netware
$(OBJDIR)/%.xdc: GNUmakefile
@echo Creating $@
@$(MPKXDC) $(XDCOPT) $@
$(OBJDIR)/%.def: Makefile.netware
$(OBJDIR)/%.def: GNUmakefile
@echo $(DL)# DEF file for linking with $(LD)$(DL) > $@
@echo $(DL)# Do not edit this file - it is created by make!$(DL) >> $@
@echo $(DL)# All your changes will be lost!!$(DL) >> $@
@echo $(DL)#$(DL) >> $@
@echo $(DL)copyright "$(COPYR)"$(DL) >> $@
@echo $(DL)copyright "$(CPRIGHT)"$(DL) >> $@
@echo $(DL)description "$(DESCR)"$(DL) >> $@
@echo $(DL)version $(VERSION)$(DL) >> $@
ifdef NLMTYPE
@@ -353,7 +381,7 @@ ifeq ($(LD),nlmconv)
@echo $(DL)output $(TARGET).nlm$(DL) >> $@
endif
libssh2_config.h: Makefile.netware
libssh2_config.h: GNUmakefile
@echo Creating $@
@echo $(DL)/* $@ for NetWare target.$(DL) > $@
@echo $(DL)** Do not edit this file - it is created by make!$(DL) >> $@
@@ -479,7 +507,7 @@ ifeq ($(DB),DEBUG)
@echo $(DL)#define LIBSSH2_DEBUG_USERAUTH 1$(DL) >> $@
endif
libssh2.imp: Makefile.netware
libssh2.imp: GNUmakefile
@echo Creating $@
@echo $(DL)# $@ for NetWare target.$(DL) > $@
@echo $(DL)# Do not edit this file - it is created by make!$(DL) >> $@
@@ -506,21 +534,25 @@ endif
@echo $(DL) libssh2_channel_wait_closed,$(DL) >> $@
@echo $(DL) libssh2_channel_wait_eof,$(DL) >> $@
@echo $(DL) libssh2_channel_write_ex,$(DL) >> $@
@echo $(DL) libssh2_exit,$(DL) >> $@
@echo $(DL) libssh2_hostkey_hash,$(DL) >> $@
@echo $(DL) libssh2_scp_recv,$(DL) >> $@
@echo $(DL) libssh2_scp_send64,$(DL) >> $@
@echo $(DL) libssh2_scp_send_ex,$(DL) >> $@
@echo $(DL) libssh2_init,$(DL) >> $@
@echo $(DL) libssh2_knownhost_add,$(DL) >> $@
@echo $(DL) libssh2_knownhost_check,$(DL) >> $@
@echo $(DL) libssh2_knownhost_checkp,$(DL) >> $@
@echo $(DL) libssh2_knownhost_free,$(DL) >> $@
@echo $(DL) libssh2_knownhost_init,$(DL) >> $@
@echo $(DL) libssh2_knownhost_readfile,$(DL) >> $@
@echo $(DL) libssh2_knownhost_writefile,$(DL) >> $@
@echo $(DL) libssh2_scp_recv,$(DL) >> $@
@echo $(DL) libssh2_scp_send64,$(DL) >> $@
@echo $(DL) libssh2_scp_send_ex,$(DL) >> $@
@echo $(DL) libssh2_session_abstract,$(DL) >> $@
@echo $(DL) libssh2_session_block_directions,$(DL) >> $@
@echo $(DL) libssh2_session_callback_set,$(DL) >> $@
@echo $(DL) libssh2_session_disconnect_ex,$(DL) >> $@
@echo $(DL) libssh2_session_free,$(DL) >> $@
@echo $(DL) libssh2_session_handshake,$(DL) >> $@
@echo $(DL) libssh2_session_hostkey,$(DL) >> $@
@echo $(DL) libssh2_session_init_ex,$(DL) >> $@
@echo $(DL) libssh2_session_last_errno,$(DL) >> $@
@@ -552,9 +584,10 @@ endif
@echo $(DL) libssh2_userauth_keyboard_interactive_ex,$(DL) >> $@
@echo $(DL) libssh2_userauth_list,$(DL) >> $@
@echo $(DL) libssh2_userauth_password_ex,$(DL) >> $@
@echo $(DL) libssh2_userauth_publickey_fromfile_ex$(DL) >> $@
@echo $(DL) libssh2_userauth_publickey_fromfile_ex,$(DL) >> $@
@echo $(DL) libssh2_version$(DL) >> $@
$(DISTDIR)/readme.txt: Makefile.netware
$(DISTDIR)/readme.txt: GNUmakefile
@echo Creating $@
@echo $(DL)This is a binary distribution for NetWare platform.$(DL) > $@
@echo $(DL)libssh2 version $(LIBSSH2_VERSION_STR)$(DL) >> $@
@@ -562,7 +595,7 @@ $(DISTDIR)/readme.txt: Makefile.netware
@echo $(DL)any further documentation:$(DL) >> $@
@echo $(DL)$(WWWURL)$(DL) >> $@
$(DEVLDIR)/readme.txt: Makefile.netware
$(DEVLDIR)/readme.txt: GNUmakefile
@echo Creating $@
@echo $(DL)This is a development distribution for NetWare platform.$(DL) > $@
@echo $(DL)libssh2 version $(LIBSSH2_VERSION_STR)$(DL) >> $@

View File

@@ -1,2 +0,0 @@
include Makefile.netware

View File

@@ -1,7 +1,6 @@
#########################################################################
#
## Makefile for building libssh2 (NetWare version - gnu make)
## Use: make -f Makefile.netware
##
## Hacked by: Guenter Knauf
#
@@ -14,12 +13,12 @@ endif
# Edit the path below to point to the base of your Zlib sources.
ifndef ZLIB_PATH
ZLIB_PATH = ../../../zlib-1.2.5
ZLIB_PATH = ../../../zlib-1.2.8
endif
# Edit the path below to point to the base of your OpenSSL package.
ifndef OPENSSL_PATH
OPENSSL_PATH = ../../../openssl-0.9.8r
OPENSSL_PATH = ../../../openssl-0.9.8zc
endif
# Edit the var below to enable static linking of libssh2 and libz
@@ -70,10 +69,7 @@ ifdef METROWERKS
else
CC = $(CROSSPREFIX)gcc
endif
CP = cp -afv
MD = mkdir
RD = rm -fr
# RM = rm -f
# Here you can find a native Win32 binary of the original awk:
# http://www.gknw.net/development/prgtools/awk-20100523.zip
AWK = awk
@@ -82,6 +78,34 @@ AWK = awk
# http://www.gknw.net/development/prgtools/mkxdc.zip
MPKXDC = mkxdc
# Platform-dependent helper tool macros
ifeq ($(findstring /sh,$(SHELL)),/sh)
DEL = rm -f $1
RMDIR = rm -fr $1
MKDIR = mkdir -p $1
COPY = -cp -afv $1 $2
#COPYR = -cp -afr $1/* $2
COPYR = -rsync -aC $1/* $2
TOUCH = touch $1
CAT = cat
ECHONL = echo ""
DL = '
else
ifeq "$(OS)" "Windows_NT"
DEL = -del 2>NUL /q /f $(subst /,\,$1)
RMDIR = -rd 2>NUL /q /s $(subst /,\,$1)
else
DEL = -del 2>NUL $(subst /,\,$1)
RMDIR = -deltree 2>NUL /y $(subst /,\,$1)
endif
MKDIR = -md 2>NUL $(subst /,\,$1)
COPY = -copy 2>NUL /y $(subst /,\,$1) $(subst /,\,$2)
COPYR = -xcopy 2>NUL /q /y /e $(subst /,\,$1) $(subst /,\,$2)
TOUCH = copy 2>&1>NUL /b $(subst /,\,$1) +,,
CAT = type
ECHONL = $(ComSpec) /c echo.
endif
# LIBARCH_U = $(shell $(AWK) 'BEGIN {print toupper(ARGV[1])}' $(LIBARCH))
LIBARCH_L = $(shell $(AWK) 'BEGIN {print tolower(ARGV[1])}' $(LIBARCH))
@@ -112,12 +136,13 @@ else
endif
else
LD = nlmconv
LDFLAGS = -T
LDFLAGS = -UT
AR = ar
ARFLAGS = -cq
LIBEXT = a
CFLAGS += -m32
CFLAGS += -fno-builtin -fpcc-struct-return -fno-strict-aliasing
CFLAGS += -fno-builtin -fpcc-struct-return
CFLAGS += -fno-strict-aliasing
CFLAGS += -Wall # -pedantic
ifeq ($(LIBARCH),LIBC)
PRELUDE = $(SDK_LIBC)/imports/libcpre.gcc.o
@@ -181,13 +206,6 @@ ifeq ($(MTSAFE),NO)
XDCOPT = -u
endif
ifeq ($(findstring /sh,$(SHELL)),/sh)
DL = '
DS = /
else
DS = \\
endif
vpath %.c $(SAMPLES)
.PRECIOUS: $(OBJDIR)/%.o $(OBJDIR)/%.def $(OBJDIR)/%.xdc
@@ -201,29 +219,29 @@ $(OBJDIR)/%.o: %.c
# @echo Compiling $<
$(CC) $(CFLAGS) -c $< -o $@
$(OBJDIR)/version.inc: ../../include/libssh2.h $(OBJDIR)
$(OBJDIR)/version.inc: ../../get_ver.awk ../../include/libssh2.h $(OBJDIR)
@echo Creating $@
@$(AWK) -f ../../get_ver.awk $< > $@
@$(AWK) -f $^ > $@
objclean:
-$(RD) $(OBJDIR)
$(call RMDIR, $(OBJDIR))
clean: objclean
-$(RM) $(TARGETS)
$(foreach f, $(TARGETS), $(call DEL, $(f)))
$(OBJDIR):
@$(MD) $@
@$(call MKDIR, $@)
%.nlm: $(OBJDIR)/%.def $(OBJDIR)/%.o $(OBJDIR)/%.xdc
@echo Linking $@
@-$(RM) $@
@$(call DEL, $@)
@$(LD) $(LDFLAGS) $<
$(OBJDIR)/%.xdc: Makefile.netware
$(OBJDIR)/%.xdc: GNUmakefile
@echo Creating $@
@$(MPKXDC) $(XDCOPT) $@
$(OBJDIR)/%.def: Makefile.netware
$(OBJDIR)/%.def: GNUmakefile
@echo $(DL)# DEF file for linking with $(LD)$(DL) > $@
@echo $(DL)# Do not edit this file - it is created by make!$(DL) >> $@
@echo $(DL)# All your changes will be lost!!$(DL) >> $@

View File

@@ -1,6 +1,17 @@
# $Id: Makefile.am,v 1.21 2009/05/07 17:21:56 bagder Exp $
AUTOMAKE_OPTIONS = foreign nostdinc
# Get the CRYPTO_CSOURCES and CRYPTO_HHEADERS defines
if OPENSSL
include ../Makefile.OpenSSL.inc
endif
if LIBGCRYPT
include ../Makefile.libgcrypt.inc
endif
if WINCNG
include ../Makefile.WinCNG.inc
endif
# Makefile.inc provides the CSOURCES and HHEADERS defines
include ../Makefile.inc

View File

@@ -1,33 +1,30 @@
!include "win32/config.mk"
!include "win32/objects.mk"
CFLAGS=$(CFLAGS)
OBJECTS = \
$(INTDIR)\channel.obj \
$(INTDIR)\comp.obj \
$(INTDIR)\crypt.obj \
$(INTDIR)\global.obj \
$(INTDIR)\hostkey.obj \
$(INTDIR)\keepalive.obj \
$(INTDIR)\kex.obj \
$(INTDIR)\mac.obj \
$(INTDIR)\misc.obj \
$(INTDIR)\openssl.obj \
$(INTDIR)\packet.obj \
$(INTDIR)\pem.obj \
$(INTDIR)\publickey.obj \
$(INTDIR)\scp.obj \
$(INTDIR)\session.obj \
$(INTDIR)\sftp.obj \
$(INTDIR)\transport.obj \
$(INTDIR)\userauth.obj
AR = lib
ARFLAGS = -nologo /LTCG
RESOURCE=$(INTDIR)\libssh2.res
DLL=libssh2$(SUFFIX).dll
STATICLIB=$(INTDIR)\libssh2.lib
$(DLL): $(OBJECTS)
$(CC) -o $(DLL) $(DLLFLAGS) $(OBJECTS) $(LIBS)
!if "$(BUILD_STATIC_LIB)" == ""
all: $(DLL)
!else
all: $(STATICLIB)
!endif
$(DLL): $(OBJECTS) $(RESOURCE)
$(CC) -o $(DLL) $(DLLFLAGS) $(OBJECTS) $(RESOURCE) $(LIBS)
$(STATICLIB): $(OBJECTS)
$(AR) $(ARFLAGS) -out:$@ $(OBJECTS)
$(RESOURCE): win32\libssh2.rc
$(RC) $(RCFLAGS) /Fo"$@" $?
!include "win32/rules.mk"

View File

@@ -1,6 +1,6 @@
/*
* Copyright (c) 2009 by Daiki Ueno
* Copyright (C) 2010 by Daniel Stenberg
* Copyright (C) 2010-2014 by Daniel Stenberg
* All rights reserved.
*
* Redistribution and use in source and binary forms,
@@ -159,6 +159,8 @@ agent_connect_unix(LIBSSH2_AGENT *agent)
s_un.sun_family = AF_UNIX;
strncpy (s_un.sun_path, path, sizeof s_un.sun_path);
s_un.sun_path[sizeof(s_un.sun_path)-1]=0; /* make sure there's a trailing
zero */
if (connect(agent->fd, (struct sockaddr*)(&s_un), sizeof s_un) != 0) {
close (agent->fd);
return _libssh2_error(agent->session, LIBSSH2_ERROR_AGENT_PROTOCOL,
@@ -303,6 +305,12 @@ agent_transact_pageant(LIBSSH2_AGENT *agent, agent_transaction_ctx_t transctx)
"failed setting up pageant filemap");
p2 = p = MapViewOfFile(filemap, FILE_MAP_WRITE, 0, 0, 0);
if (p == NULL || p2 == NULL) {
CloseHandle(filemap);
return _libssh2_error(agent->session, LIBSSH2_ERROR_AGENT_PROTOCOL,
"failed to open pageant filemap for writing");
}
_libssh2_store_str(&p2, (const char *)transctx->request,
transctx->request_len);
@@ -537,18 +545,17 @@ agent_list_identities(LIBSSH2_AGENT *agent)
struct agent_publickey *identity;
ssize_t comment_len;
identity = LIBSSH2_ALLOC(agent->session, sizeof *identity);
if (!identity) {
rc = LIBSSH2_ERROR_ALLOC;
goto error;
}
/* Read the length of the blob */
len -= 4;
if (len < 0) {
rc = LIBSSH2_ERROR_AGENT_PROTOCOL;
goto error;
}
identity = LIBSSH2_ALLOC(agent->session, sizeof *identity);
if (!identity) {
rc = LIBSSH2_ERROR_ALLOC;
goto error;
}
identity->external.blob_len = _libssh2_ntohu32(s);
s += 4;
@@ -556,12 +563,15 @@ agent_list_identities(LIBSSH2_AGENT *agent)
len -= identity->external.blob_len;
if (len < 0) {
rc = LIBSSH2_ERROR_AGENT_PROTOCOL;
LIBSSH2_FREE(agent->session, identity);
goto error;
}
identity->external.blob = LIBSSH2_ALLOC(agent->session,
identity->external.blob_len);
if (!identity->external.blob) {
rc = LIBSSH2_ERROR_ALLOC;
LIBSSH2_FREE(agent->session, identity);
goto error;
}
memcpy(identity->external.blob, s, identity->external.blob_len);
@@ -571,6 +581,8 @@ agent_list_identities(LIBSSH2_AGENT *agent)
len -= 4;
if (len < 0) {
rc = LIBSSH2_ERROR_AGENT_PROTOCOL;
LIBSSH2_FREE(agent->session, identity->external.blob);
LIBSSH2_FREE(agent->session, identity);
goto error;
}
comment_len = _libssh2_ntohu32(s);
@@ -580,12 +592,17 @@ agent_list_identities(LIBSSH2_AGENT *agent)
len -= comment_len;
if (len < 0) {
rc = LIBSSH2_ERROR_AGENT_PROTOCOL;
LIBSSH2_FREE(agent->session, identity->external.blob);
LIBSSH2_FREE(agent->session, identity);
goto error;
}
identity->external.comment = LIBSSH2_ALLOC(agent->session,
comment_len + 1);
if (!identity->external.comment) {
rc = LIBSSH2_ERROR_ALLOC;
LIBSSH2_FREE(agent->session, identity->external.blob);
LIBSSH2_FREE(agent->session, identity);
goto error;
}
identity->external.comment[comment_len] = '\0';
@@ -645,13 +662,13 @@ libssh2_agent_init(LIBSSH2_SESSION *session)
{
LIBSSH2_AGENT *agent;
agent = LIBSSH2_ALLOC(session, sizeof *agent);
agent = LIBSSH2_CALLOC(session, sizeof *agent);
if (!agent) {
_libssh2_error(session, LIBSSH2_ERROR_ALLOC,
"Unable to allocate space for agent connection");
return NULL;
}
memset(agent, 0, sizeof *agent);
agent->fd = LIBSSH2_INVALID_SOCKET;
agent->session = session;
_libssh2_list_init(&agent->head);
@@ -698,7 +715,7 @@ libssh2_agent_list_identities(LIBSSH2_AGENT *agent)
* libssh2_agent_get_identity()
*
* Traverse the internal list of public keys. Pass NULL to 'prev' to get
* the first one. Or pass a poiner to the previously returned one to get the
* the first one. Or pass a pointer to the previously returned one to get the
* next.
*
* Returns:

View File

@@ -1,6 +1,6 @@
/* Copyright (c) 2004-2007 Sara Golemon <sarag@libssh2.org>
* Copyright (c) 2005 Mikhail Gusarov <dottedmag@dottedmag.net>
* Copyright (c) 2008-2011 by Daniel Stenberg
* Copyright (c) 2008-2014 by Daniel Stenberg
*
* All rights reserved.
*
@@ -158,14 +158,12 @@ _libssh2_channel_open(LIBSSH2_SESSION * session, const char *channel_type,
"Opening Channel - win %d pack %d", window_size,
packet_size);
session->open_channel =
LIBSSH2_ALLOC(session, sizeof(LIBSSH2_CHANNEL));
LIBSSH2_CALLOC(session, sizeof(LIBSSH2_CHANNEL));
if (!session->open_channel) {
_libssh2_error(session, LIBSSH2_ERROR_ALLOC,
"Unable to allocate space for channel data");
return NULL;
}
memset(session->open_channel, 0, sizeof(LIBSSH2_CHANNEL));
session->open_channel->channel_type_len = channel_type_len;
session->open_channel->channel_type =
LIBSSH2_ALLOC(session, channel_type_len);
@@ -451,7 +449,7 @@ channel_forward_listen(LIBSSH2_SESSION * session, const char *host,
LIBSSH2_ALLOC(session, session->fwdLstn_packet_len);
if (!session->fwdLstn_packet) {
_libssh2_error(session, LIBSSH2_ERROR_ALLOC,
"Unable to allocate memeory for setenv packet");
"Unable to allocate memory for setenv packet");
return NULL;
}
@@ -509,12 +507,11 @@ channel_forward_listen(LIBSSH2_SESSION * session, const char *host,
if (data[0] == SSH_MSG_REQUEST_SUCCESS) {
LIBSSH2_LISTENER *listener;
listener = LIBSSH2_ALLOC(session, sizeof(LIBSSH2_LISTENER));
listener = LIBSSH2_CALLOC(session, sizeof(LIBSSH2_LISTENER));
if (!listener)
_libssh2_error(session, LIBSSH2_ERROR_ALLOC,
"Unable to allocate memory for listener queue");
else {
memset(listener, 0, sizeof(LIBSSH2_LISTENER));
listener->host =
LIBSSH2_ALLOC(session, session->fwdLstn_host_len + 1);
if (!listener->host) {
@@ -525,8 +522,7 @@ channel_forward_listen(LIBSSH2_SESSION * session, const char *host,
}
else {
listener->session = session;
memcpy(listener->host, host ? host : "0.0.0.0",
session->fwdLstn_host_len);
memcpy(listener->host, host, session->fwdLstn_host_len);
listener->host[session->fwdLstn_host_len] = 0;
if (data_len >= 5 && !port) {
listener->port = _libssh2_ntohu32(data + 1);
@@ -606,6 +602,7 @@ int _libssh2_channel_forward_cancel(LIBSSH2_LISTENER *listener)
size_t packet_len =
host_len + 14 + sizeof("cancel-tcpip-forward") - 1;
int rc;
int retcode = 0;
if (listener->chanFwdCncl_state == libssh2_NB_state_idle) {
_libssh2_debug(session, LIBSSH2_TRACE_CONN,
@@ -615,7 +612,7 @@ int _libssh2_channel_forward_cancel(LIBSSH2_LISTENER *listener)
s = packet = LIBSSH2_ALLOC(session, packet_len);
if (!packet) {
_libssh2_error(session, LIBSSH2_ERROR_ALLOC,
"Unable to allocate memeory for setenv packet");
"Unable to allocate memory for setenv packet");
return LIBSSH2_ERROR_ALLOC;
}
@@ -644,9 +641,11 @@ int _libssh2_channel_forward_cancel(LIBSSH2_LISTENER *listener)
_libssh2_error(session, LIBSSH2_ERROR_SOCKET_SEND,
"Unable to send global-request packet for forward "
"listen request");
LIBSSH2_FREE(session, packet);
listener->chanFwdCncl_state = libssh2_NB_state_idle;
return LIBSSH2_ERROR_SOCKET_SEND;
/* set the state to something we don't check for, for the
unfortunate situation where we get an EAGAIN further down
when trying to bail out due to errors! */
listener->chanFwdCncl_state = libssh2_NB_state_sent;
retcode = LIBSSH2_ERROR_SOCKET_SEND;
}
LIBSSH2_FREE(session, packet);
@@ -670,9 +669,7 @@ int _libssh2_channel_forward_cancel(LIBSSH2_LISTENER *listener)
LIBSSH2_FREE(session, listener);
listener->chanFwdCncl_state = libssh2_NB_state_idle;
return 0;
return retcode;
}
/*
@@ -787,7 +784,7 @@ static int channel_setenv(LIBSSH2_CHANNEL *channel,
LIBSSH2_ALLOC(session, channel->setenv_packet_len);
if (!channel->setenv_packet) {
return _libssh2_error(session, LIBSSH2_ERROR_ALLOC,
"Unable to allocate memeory "
"Unable to allocate memory "
"for setenv packet");
}
@@ -1413,6 +1410,9 @@ _libssh2_channel_flush(LIBSSH2_CHANNEL *channel, int streamid)
channel->flush_state = libssh2_NB_state_created;
}
channel->read_avail -= channel->flush_flush_bytes;
channel->remote.window_size -= channel->flush_flush_bytes;
if (channel->flush_refund_bytes) {
int rc;
@@ -1483,10 +1483,11 @@ libssh2_channel_get_exit_signal(LIBSSH2_CHANNEL *channel,
char **langtag,
size_t *langtag_len)
{
LIBSSH2_SESSION *session = channel->session;
size_t namelen = 0;
if (channel) {
LIBSSH2_SESSION *session = channel->session;
if (channel->exit_signal) {
namelen = strlen(channel->exit_signal);
if (exitsignal) {
@@ -1542,6 +1543,9 @@ _libssh2_channel_receive_window_adjust(LIBSSH2_CHANNEL * channel,
{
int rc;
if(store)
*store = channel->remote.window_size;
if (channel->adjust_state == libssh2_NB_state_idle) {
if (!force
&& (adjustment + channel->adjust_queue <
@@ -1551,14 +1555,10 @@ _libssh2_channel_receive_window_adjust(LIBSSH2_CHANNEL * channel,
"for channel %lu/%lu",
adjustment, channel->local.id, channel->remote.id);
channel->adjust_queue += adjustment;
if(store)
*store = channel->remote.window_size;
return 0;
}
if (!adjustment && !channel->adjust_queue) {
if(store)
*store = channel->remote.window_size;
return 0;
}
@@ -1596,8 +1596,6 @@ _libssh2_channel_receive_window_adjust(LIBSSH2_CHANNEL * channel,
channel->adjust_state = libssh2_NB_state_idle;
if(store)
*store = channel->remote.window_size;
return 0;
}
@@ -1623,7 +1621,7 @@ libssh2_channel_receive_window_adjust(LIBSSH2_CHANNEL *channel,
int rc;
if(!channel)
return LIBSSH2_ERROR_BAD_USE;
return (unsigned long)LIBSSH2_ERROR_BAD_USE;
BLOCK_ADJUST(rc, channel->session,
_libssh2_channel_receive_window_adjust(channel, adj,
@@ -1670,7 +1668,7 @@ _libssh2_channel_extended_data(LIBSSH2_CHANNEL *channel, int ignore_mode)
"Setting channel %lu/%lu handle_extended_data"
" mode to %d",
channel->local.id, channel->remote.id, ignore_mode);
channel->remote.extended_data_ignore_mode = ignore_mode;
channel->remote.extended_data_ignore_mode = (char)ignore_mode;
channel->extData2_state = libssh2_NB_state_created;
}
@@ -1749,22 +1747,36 @@ ssize_t _libssh2_channel_read(LIBSSH2_CHANNEL *channel, int stream_id,
LIBSSH2_PACKET *read_packet;
LIBSSH2_PACKET *read_next;
if (channel->read_state == libssh2_NB_state_idle) {
_libssh2_debug(session, LIBSSH2_TRACE_CONN,
"channel_read() wants %d bytes from channel %lu/%lu "
"stream #%d",
(int) buflen, channel->local.id, channel->remote.id,
stream_id);
channel->read_state = libssh2_NB_state_created;
_libssh2_debug(session, LIBSSH2_TRACE_CONN,
"channel_read() wants %d bytes from channel %lu/%lu "
"stream #%d",
(int) buflen, channel->local.id, channel->remote.id,
stream_id);
/* expand the receiving window first if it has become too narrow */
if( (channel->read_state == libssh2_NB_state_jump1) ||
(channel->remote.window_size < channel->remote.window_size_initial / 4 * 3 + buflen) ) {
uint32_t adjustment = channel->remote.window_size_initial + buflen - channel->remote.window_size;
if (adjustment < LIBSSH2_CHANNEL_MINADJUST)
adjustment = LIBSSH2_CHANNEL_MINADJUST;
/* the actual window adjusting may not finish so we need to deal with
this special state here */
channel->read_state = libssh2_NB_state_jump1;
rc = _libssh2_channel_receive_window_adjust(channel, adjustment,
0, NULL);
if (rc)
return rc;
channel->read_state = libssh2_NB_state_idle;
}
rc = 1; /* set to >0 to let the while loop start */
/* Process all pending incoming packets in all states in order to "even
out" the network readings. Tests prove that this way produces faster
transfers. */
while (rc > 0)
/* Process all pending incoming packets. Tests prove that this way
produces faster transfers. */
do {
rc = _libssh2_transport_read(session);
} while (rc > 0);
if ((rc < 0) && (rc != LIBSSH2_ERROR_EAGAIN))
return _libssh2_error(session, rc, "transport read");
@@ -1846,8 +1858,6 @@ ssize_t _libssh2_channel_read(LIBSSH2_CHANNEL *channel, int stream_id,
}
if (!bytes_read) {
channel->read_state = libssh2_NB_state_idle;
/* If the channel is already at EOF or even closed, we need to signal
that back. We may have gotten that info while draining the incoming
transport layer until EAGAIN so we must not be fooled by that
@@ -1860,11 +1870,9 @@ ssize_t _libssh2_channel_read(LIBSSH2_CHANNEL *channel, int stream_id,
/* if the transport layer said EAGAIN then we say so as well */
return _libssh2_error(session, rc, "would block");
}
else
/* make sure we remain in the created state to focus on emptying the
data we already have in the packet brigade before we try to read
more off the network again */
channel->read_state = libssh2_NB_state_created;
channel->read_avail -= bytes_read;
channel->remote.window_size -= bytes_read;
return bytes_read;
}
@@ -2008,12 +2016,22 @@ _libssh2_channel_write(LIBSSH2_CHANNEL *channel, int stream_id,
rc = _libssh2_transport_read(session);
while (rc > 0);
if((rc < 0) && (rc != LIBSSH2_ERROR_EAGAIN))
return rc;
if((rc < 0) && (rc != LIBSSH2_ERROR_EAGAIN)) {
return _libssh2_error(channel->session, rc,
"Failure while draining incoming flow");
}
if(channel->local.window_size <= 0)
if(channel->local.window_size <= 0) {
/* there's no room for data so we stop */
/* Waiting on the socket to be writable would be wrong because we
* would be back here immediately, but a readable socket might
* herald an incoming window adjustment.
*/
session->socket_block_directions = LIBSSH2_SESSION_BLOCK_INBOUND;
return (rc==LIBSSH2_ERROR_EAGAIN?rc:0);
}
channel->write_bufwrite = buflen;
@@ -2250,7 +2268,6 @@ int _libssh2_channel_close(LIBSSH2_CHANNEL * channel)
{
LIBSSH2_SESSION *session = channel->session;
int rc = 0;
int retcode;
if (channel->local.close) {
/* Already closed, act like we sent another close,
@@ -2259,9 +2276,15 @@ int _libssh2_channel_close(LIBSSH2_CHANNEL * channel)
return 0;
}
if (!channel->local.eof)
if ((retcode = channel_send_eof(channel)))
return retcode;
if (!channel->local.eof) {
if ((rc = channel_send_eof(channel))) {
if (rc == LIBSSH2_ERROR_EAGAIN) {
return rc;
}
_libssh2_error(session, rc,
"Unable to send EOF, but closing channel anyway");
}
}
/* ignore if we have received a remote eof or not, as it is now too
late for us to wait for it. Continue closing! */
@@ -2277,19 +2300,22 @@ int _libssh2_channel_close(LIBSSH2_CHANNEL * channel)
}
if (channel->close_state == libssh2_NB_state_created) {
retcode = _libssh2_transport_send(session, channel->close_packet, 5,
NULL, 0);
if (retcode == LIBSSH2_ERROR_EAGAIN) {
rc = _libssh2_transport_send(session, channel->close_packet, 5,
NULL, 0);
if (rc == LIBSSH2_ERROR_EAGAIN) {
_libssh2_error(session, rc,
"Would block sending close-channel");
return retcode;
} else if (retcode) {
channel->close_state = libssh2_NB_state_idle;
return _libssh2_error(session, retcode,
"Unable to send close-channel request");
}
return rc;
channel->close_state = libssh2_NB_state_sent;
} else if (rc) {
_libssh2_error(session, rc,
"Unable to send close-channel request, "
"but closing anyway");
/* skip waiting for the response and fall through to
LIBSSH2_CHANNEL_CLOSE below */
} else
channel->close_state = libssh2_NB_state_sent;
}
if (channel->close_state == libssh2_NB_state_sent) {
@@ -2549,7 +2575,7 @@ libssh2_channel_window_read_ex(LIBSSH2_CHANNEL *channel,
* libssh2_channel_window_write_ex
*
* Check the status of the write window Returns the number of bytes which may
* be safely writen on the channel without blocking window_size_initial (if
* be safely written on the channel without blocking window_size_initial (if
* passed) will be populated with the size of the initial window as defined by
* the channel_open request
*/

View File

@@ -1,5 +1,5 @@
/* Copyright (c) 2004-2007, Sara Golemon <sarag@libssh2.org>
* Copyright (c) 2010, Daniel Stenberg <daniel@haxx.se>
* Copyright (c) 2010-2014, Daniel Stenberg <daniel@haxx.se>
* All rights reserved.
*
* Redistribution and use in source and binary forms,
@@ -96,6 +96,7 @@ comp_method_none_decomp(LIBSSH2_SESSION * session,
static const LIBSSH2_COMP_METHOD comp_method_none = {
"none",
0, /* not really compressing */
0, /* isn't used in userauth, go figure */
NULL,
comp_method_none_comp,
comp_method_none_decomp,
@@ -140,13 +141,12 @@ comp_method_zlib_init(LIBSSH2_SESSION * session, int compr,
z_stream *strm;
int status;
strm = LIBSSH2_ALLOC(session, sizeof(z_stream));
strm = LIBSSH2_CALLOC(session, sizeof(z_stream));
if (!strm) {
return _libssh2_error(session, LIBSSH2_ERROR_ALLOC,
"Unable to allocate memory for "
"zlib compression/decompression");
}
memset(strm, 0, sizeof(z_stream));
strm->opaque = (voidpf) session;
strm->zalloc = (alloc_func) comp_method_zlib_alloc;
@@ -197,15 +197,14 @@ comp_method_zlib_comp(LIBSSH2_SESSION *session,
status = deflate(strm, Z_PARTIAL_FLUSH);
if (status != Z_OK) {
_libssh2_debug(session, LIBSSH2_TRACE_TRANS,
"unhandled zlib compression error %d", status);
return _libssh2_error(session, LIBSSH2_ERROR_ZLIB,
"compression failure");
if ((status == Z_OK) && (strm->avail_out > 0)) {
*dest_len = out_maxlen - strm->avail_out;
return 0;
}
*dest_len = out_maxlen - strm->avail_out;
return 0;
_libssh2_debug(session, LIBSSH2_TRACE_TRANS,
"unhandled zlib compression error %d, avail_out", status, strm->avail_out);
return _libssh2_error(session, LIBSSH2_ERROR_ZLIB, "compression failure");
}
/*
@@ -225,13 +224,12 @@ comp_method_zlib_decomp(LIBSSH2_SESSION * session,
/* A short-term alloc of a full data chunk is better than a series of
reallocs */
char *out;
int out_maxlen = 8 * src_len;
int limiter = 0;
int out_maxlen = 4 * src_len;
/* If strm is null, then we have not yet been initialized. */
if (strm == NULL)
return _libssh2_error(session, LIBSSH2_ERROR_COMPRESS,
"decompression unitilized");;
"decompression uninitialized");;
/* In practice they never come smaller than this */
if (out_maxlen < 25)
@@ -248,83 +246,49 @@ comp_method_zlib_decomp(LIBSSH2_SESSION * session,
if (!strm->next_out)
return _libssh2_error(session, LIBSSH2_ERROR_ALLOC,
"Unable to allocate decompression buffer");
while (strm->avail_in) {
/* Loop until it's all inflated or hit error */
for (;;) {
int status;
size_t out_ofs;
char *newout;
status = inflate(strm, Z_PARTIAL_FLUSH);
if (status != Z_OK) {
if (status == Z_OK) {
if (strm->avail_out > 0)
/* status is OK and the output buffer has not been exhausted so we're done */
break;
} else if (status == Z_BUF_ERROR) {
/* the input data has been exhausted so we are done */
break;
} else {
/* error state */
LIBSSH2_FREE(session, out);
_libssh2_debug(session, LIBSSH2_TRACE_TRANS,
"unhandled zlib error %d", status);
return _libssh2_error(session, LIBSSH2_ERROR_ZLIB,
"decompression failure");
}
if (strm->avail_in) {
size_t out_ofs = out_maxlen - strm->avail_out;
char *newout;
out_maxlen += 8 * strm->avail_in;
if (out_maxlen >= (int) payload_limit) {
LIBSSH2_FREE(session, out);
return _libssh2_error(session, LIBSSH2_ERROR_ZLIB,
"Excessive growth in decompression phase");
}
if ((out_maxlen > (int) payload_limit) && limiter++) {
LIBSSH2_FREE(session, out);
return _libssh2_error(session, LIBSSH2_ERROR_ZLIB,
"Excessive growth in decompression phase");
}
newout = LIBSSH2_REALLOC(session, out, out_maxlen);
if (!newout) {
LIBSSH2_FREE(session, out);
return _libssh2_error(session, LIBSSH2_ERROR_ALLOC,
"Unable to expand decompression buffer");
}
out = newout;
strm->next_out = (unsigned char *) out + out_ofs;
strm->avail_out += 8 * strm->avail_in;
} else
while (!strm->avail_out) {
/* Done with input, might be a byte or two in internal buffer
* during compress. Or potentially many bytes if it's a
* decompress
*/
int grow_size = 2048;
char *newout;
if (out_maxlen >= (int) payload_limit) {
LIBSSH2_FREE(session, out);
return _libssh2_error(session, LIBSSH2_ERROR_ZLIB,
"Excessive growth in decompression "
"phase");
}
if (grow_size > (int) (payload_limit - out_maxlen)) {
grow_size = payload_limit - out_maxlen;
}
out_maxlen += grow_size;
strm->avail_out = grow_size;
newout = LIBSSH2_REALLOC(session, out, out_maxlen);
if (!newout) {
LIBSSH2_FREE(session, out);
return _libssh2_error(session, LIBSSH2_ERROR_ALLOC,
"Unable to expand final "
"decompress buffer");
}
out = newout;
strm->next_out = (unsigned char *) out + out_maxlen -
grow_size;
status = inflate(strm, Z_PARTIAL_FLUSH);
if (status != Z_OK) {
LIBSSH2_FREE(session, out);
_libssh2_debug(session, LIBSSH2_TRACE_TRANS,
"unhandled zlib error %d", status);
return _libssh2_error(session, LIBSSH2_ERROR_ZLIB,
"decompression failure");
}
}
/* If we get here we need to grow the output buffer and try again */
out_ofs = out_maxlen - strm->avail_out;
out_maxlen *= 2;
newout = LIBSSH2_REALLOC(session, out, out_maxlen);
if (!newout) {
LIBSSH2_FREE(session, out);
return _libssh2_error(session, LIBSSH2_ERROR_ALLOC,
"Unable to expand decompression buffer");
}
out = newout;
strm->next_out = (unsigned char *) out + out_ofs;
strm->avail_out = out_maxlen - out_ofs;
}
*dest = (unsigned char *) out;
@@ -357,6 +321,17 @@ comp_method_zlib_dtor(LIBSSH2_SESSION *session, int compr, void **abstract)
static const LIBSSH2_COMP_METHOD comp_method_zlib = {
"zlib",
1, /* yes, this compresses */
1, /* do compression during userauth */
comp_method_zlib_init,
comp_method_zlib_comp,
comp_method_zlib_decomp,
comp_method_zlib_dtor,
};
static const LIBSSH2_COMP_METHOD comp_method_zlib_openssh = {
"zlib@openssh.com",
1, /* yes, this compresses */
0, /* don't use compression during userauth */
comp_method_zlib_init,
comp_method_zlib_comp,
comp_method_zlib_decomp,
@@ -369,6 +344,7 @@ static const LIBSSH2_COMP_METHOD comp_method_zlib = {
static const LIBSSH2_COMP_METHOD *comp_methods[] = {
#ifdef LIBSSH2_HAVE_ZLIB
&comp_method_zlib,
&comp_method_zlib_openssh,
#endif /* LIBSSH2_HAVE_ZLIB */
&comp_method_none,
NULL

View File

@@ -96,11 +96,12 @@ crypt_init(LIBSSH2_SESSION * session,
static int
crypt_encrypt(LIBSSH2_SESSION * session, unsigned char *block,
void **abstract)
size_t blocksize, void **abstract)
{
struct crypt_ctx *cctx = *(struct crypt_ctx **) abstract;
(void) session;
return _libssh2_cipher_crypt(&cctx->h, cctx->algo, cctx->encrypt, block);
return _libssh2_cipher_crypt(&cctx->h, cctx->algo, cctx->encrypt, block,
blocksize);
}
static int
@@ -248,7 +249,8 @@ crypt_init_arcfour128(LIBSSH2_SESSION * session,
unsigned char block[8];
size_t discard = 1536;
for (; discard; discard -= 8)
_libssh2_cipher_crypt(&cctx->h, cctx->algo, cctx->encrypt, block);
_libssh2_cipher_crypt(&cctx->h, cctx->algo, cctx->encrypt, block,
method->blocksize);
}
return rc;

View File

@@ -38,10 +38,16 @@
#ifndef LIBSSH2_CRYPTO_H
#define LIBSSH2_CRYPTO_H
#ifdef LIBSSH2_OPENSSL
#include "openssl.h"
#endif
#ifdef LIBSSH2_LIBGCRYPT
#include "libgcrypt.h"
#else
#include "openssl.h"
#endif
#ifdef LIBSSH2_WINCNG
#include "wincng.h"
#endif
int _libssh2_rsa_new(libssh2_rsa_ctx ** rsa,
@@ -75,6 +81,7 @@ int _libssh2_rsa_sha1_sign(LIBSSH2_SESSION * session,
unsigned char **signature,
size_t *signature_len);
#if LIBSSH2_DSA
int _libssh2_dsa_new(libssh2_dsa_ctx ** dsa,
const unsigned char *pdata,
unsigned long plen,
@@ -95,6 +102,7 @@ int _libssh2_dsa_sha1_verify(libssh2_dsa_ctx * dsactx,
int _libssh2_dsa_sha1_sign(libssh2_dsa_ctx * dsactx,
const unsigned char *hash,
unsigned long hash_len, unsigned char *sig);
#endif
int _libssh2_cipher_init(_libssh2_cipher_ctx * h,
_libssh2_cipher_type(algo),
@@ -103,7 +111,7 @@ int _libssh2_cipher_init(_libssh2_cipher_ctx * h,
int _libssh2_cipher_crypt(_libssh2_cipher_ctx * ctx,
_libssh2_cipher_type(algo),
int encrypt, unsigned char *block);
int encrypt, unsigned char *block, size_t blocksize);
int _libssh2_pub_priv_keyfile(LIBSSH2_SESSION *session,
unsigned char **method,

View File

@@ -1,5 +1,5 @@
/* Copyright (c) 2004-2006, Sara Golemon <sarag@libssh2.org>
* Copyright (c) 2009 by Daniel Stenberg
* Copyright (c) 2009-2014 by Daniel Stenberg
* All rights reserved.
*
* Redistribution and use in source and binary forms,
@@ -347,13 +347,12 @@ hostkey_method_ssh_dss_signv(LIBSSH2_SESSION * session,
libssh2_sha1_ctx ctx;
int i;
*signature = LIBSSH2_ALLOC(session, 2 * SHA_DIGEST_LENGTH);
*signature = LIBSSH2_CALLOC(session, 2 * SHA_DIGEST_LENGTH);
if (!*signature) {
return -1;
}
*signature_len = 2 * SHA_DIGEST_LENGTH;
memset(*signature, 0, 2 * SHA_DIGEST_LENGTH);
libssh2_sha1_init(&ctx);
for(i = 0; i < veccount; i++) {
@@ -429,7 +428,9 @@ libssh2_hostkey_hash(LIBSSH2_SESSION * session, int hash_type)
switch (hash_type) {
#if LIBSSH2_MD5
case LIBSSH2_HOSTKEY_HASH_MD5:
return (char *) session->server_hostkey_md5;
return (session->server_hostkey_md5_valid)
? (char *) session->server_hostkey_md5
: NULL;
break;
#endif /* LIBSSH2_MD5 */
case LIBSSH2_HOSTKEY_HASH_SHA1:

View File

@@ -75,7 +75,8 @@ libssh2_keepalive_send (LIBSSH2_SESSION *session,
size_t len = sizeof (keepalive_data) - 1;
int rc;
keepalive_data[len - 1] = session->keepalive_want_reply;
keepalive_data[len - 1] =
(unsigned char)session->keepalive_want_reply;
rc = _libssh2_transport_send(session, keepalive_data, len, NULL, 0);
/* Silently ignore PACKET_EAGAIN here: if the write buffer is
@@ -90,8 +91,8 @@ libssh2_keepalive_send (LIBSSH2_SESSION *session,
if (seconds_to_next)
*seconds_to_next = session->keepalive_interval;
} else if (seconds_to_next) {
*seconds_to_next = (int) session->keepalive_last_sent
+ session->keepalive_interval - now;
*seconds_to_next = (int) (session->keepalive_last_sent - now)
+ session->keepalive_interval;
}
return 0;

View File

@@ -218,10 +218,15 @@ static int diffie_hellman_sha1(LIBSSH2_SESSION *session,
{
libssh2_md5_ctx fingerprint_ctx;
libssh2_md5_init(&fingerprint_ctx);
libssh2_md5_update(fingerprint_ctx, session->server_hostkey,
session->server_hostkey_len);
libssh2_md5_final(fingerprint_ctx, session->server_hostkey_md5);
if (libssh2_md5_init(&fingerprint_ctx)) {
libssh2_md5_update(fingerprint_ctx, session->server_hostkey,
session->server_hostkey_len);
libssh2_md5_final(fingerprint_ctx, session->server_hostkey_md5);
session->server_hostkey_md5_valid = TRUE;
}
else {
session->server_hostkey_md5_valid = FALSE;
}
}
#ifdef LIBSSH2DEBUG
{
@@ -1544,6 +1549,30 @@ static int kex_agree_comp(LIBSSH2_SESSION *session,
* The Client gets to make the final call on "agreed methods"
*/
/*
* kex_string_pair() extracts a string from the packet and makes sure it fits
* within the given packet.
*/
static int kex_string_pair(unsigned char **sp, /* parsing position */
unsigned char *data, /* start pointer to packet */
size_t data_len, /* size of total packet */
size_t *lenp, /* length of the string */
unsigned char **strp) /* pointer to string start */
{
unsigned char *s = *sp;
*lenp = _libssh2_ntohu32(s);
/* the length of the string must fit within the current pointer and the
end of the packet */
if (*lenp > (data_len - (s - data) -4))
return 1;
*strp = s + 4;
s += 4 + *lenp;
*sp = s;
return 0;
}
/* kex_agree_methods
* Decide which specific method to use of the methods offered by each party
*/
@@ -1563,38 +1592,23 @@ static int kex_agree_methods(LIBSSH2_SESSION * session, unsigned char *data,
s += 16;
/* Locate each string */
kex_len = _libssh2_ntohu32(s);
kex = s + 4;
s += 4 + kex_len;
hostkey_len = _libssh2_ntohu32(s);
hostkey = s + 4;
s += 4 + hostkey_len;
crypt_cs_len = _libssh2_ntohu32(s);
crypt_cs = s + 4;
s += 4 + crypt_cs_len;
crypt_sc_len = _libssh2_ntohu32(s);
crypt_sc = s + 4;
s += 4 + crypt_sc_len;
mac_cs_len = _libssh2_ntohu32(s);
mac_cs = s + 4;
s += 4 + mac_cs_len;
mac_sc_len = _libssh2_ntohu32(s);
mac_sc = s + 4;
s += 4 + mac_sc_len;
comp_cs_len = _libssh2_ntohu32(s);
comp_cs = s + 4;
s += 4 + comp_cs_len;
comp_sc_len = _libssh2_ntohu32(s);
comp_sc = s + 4;
#if 0
s += 4 + comp_sc_len;
lang_cs_len = _libssh2_ntohu32(s);
lang_cs = s + 4;
s += 4 + lang_cs_len;
lang_sc_len = _libssh2_ntohu32(s);
lang_sc = s + 4;
s += 4 + lang_sc_len;
#endif
if(kex_string_pair(&s, data, data_len, &kex_len, &kex))
return -1;
if(kex_string_pair(&s, data, data_len, &hostkey_len, &hostkey))
return -1;
if(kex_string_pair(&s, data, data_len, &crypt_cs_len, &crypt_cs))
return -1;
if(kex_string_pair(&s, data, data_len, &crypt_sc_len, &crypt_sc))
return -1;
if(kex_string_pair(&s, data, data_len, &mac_cs_len, &mac_cs))
return -1;
if(kex_string_pair(&s, data, data_len, &mac_sc_len, &mac_sc))
return -1;
if(kex_string_pair(&s, data, data_len, &comp_cs_len, &comp_cs))
return -1;
if(kex_string_pair(&s, data, data_len, &comp_sc_len, &comp_sc))
return -1;
/* If the server sent an optimistic packet, assume that it guessed wrong.
* If the guess is determined to be right (by kex_agree_kex_hostkey)
* This flag will be reset to zero so that it's not ignored */
@@ -1751,7 +1765,7 @@ _libssh2_kex_exchange(LIBSSH2_SESSION * session, int reexchange,
key_state->state = libssh2_NB_state_sent2;
}
if (rc == 0) {
if (rc == 0 && session->kex) {
if (key_state->state == libssh2_NB_state_sent2) {
retcode = session->kex->exchange_keys(session,
&key_state->key_state_low);
@@ -1861,7 +1875,7 @@ libssh2_session_method_pref(LIBSSH2_SESSION * session, int method_type,
}
memcpy(s, prefs, prefs_len + 1);
while (s && *s) {
while (s && *s && mlist) {
char *p = strchr(s, ',');
int method_len = p ? (p - s) : (int) strlen(s);

View File

@@ -1,5 +1,5 @@
/*
* Copyright (c) 2009-2011 by Daniel Stenberg
* Copyright (c) 2009-2014 by Daniel Stenberg
* All rights reserved.
*
* Redistribution and use in source and binary forms,
@@ -50,7 +50,11 @@ struct known_host {
size_t salt_len; /* size of salt */
char *key; /* the (allocated) associated key. This is kept base64
encoded in memory. */
char *comment; /* the (allocated) optional comment text, may be NULL */
char *key_type_name; /* the (allocated) key type name */
size_t key_type_len; /* size of key_type_name */
char *comment; /* the (allocated) optional comment text, may be
NULL */
size_t comment_len; /* the size of comment */
/* this is the struct we expose externally */
struct libssh2_knownhost external;
@@ -67,6 +71,8 @@ static void free_host(LIBSSH2_SESSION *session, struct known_host *entry)
if(entry) {
if(entry->comment)
LIBSSH2_FREE(session, entry->comment);
if (entry->key_type_name)
LIBSSH2_FREE(session, entry->key_type_name);
if(entry->key)
LIBSSH2_FREE(session, entry->key);
if(entry->salt)
@@ -127,6 +133,7 @@ static struct libssh2_knownhost *knownhost_to_external(struct known_host *node)
static int
knownhost_add(LIBSSH2_KNOWNHOSTS *hosts,
const char *host, const char *salt,
const char *key_type_name, size_t key_type_len,
const char *key, size_t keylen,
const char *comment, size_t commentlen,
int typemask, struct libssh2_knownhost **store)
@@ -142,13 +149,11 @@ knownhost_add(LIBSSH2_KNOWNHOSTS *hosts,
return _libssh2_error(hosts->session, LIBSSH2_ERROR_INVAL,
"No key type set");
if(!(entry = LIBSSH2_ALLOC(hosts->session, sizeof(struct known_host))))
if(!(entry = LIBSSH2_CALLOC(hosts->session, sizeof(struct known_host))))
return _libssh2_error(hosts->session, LIBSSH2_ERROR_ALLOC,
"Unable to allocate memory for known host "
"entry");
memset(entry, 0, sizeof(struct known_host));
entry->typemask = typemask;
switch(entry->typemask & LIBSSH2_KNOWNHOST_TYPE_MASK) {
@@ -161,6 +166,7 @@ knownhost_add(LIBSSH2_KNOWNHOSTS *hosts,
goto error;
}
memcpy(entry->name, host, hostlen+1);
entry->name_len = hostlen;
break;
case LIBSSH2_KNOWNHOST_TYPE_SHA1:
rc = libssh2_base64_decode(hosts->session, &ptr, &ptrlen,
@@ -210,6 +216,19 @@ knownhost_add(LIBSSH2_KNOWNHOSTS *hosts,
entry->key = ptr;
}
if (key_type_name && ((typemask & LIBSSH2_KNOWNHOST_KEY_MASK) ==
LIBSSH2_KNOWNHOST_KEY_UNKNOWN)) {
entry->key_type_name = LIBSSH2_ALLOC(hosts->session, key_type_len+1);
if (!entry->key_type_name) {
rc = _libssh2_error(hosts->session, LIBSSH2_ERROR_ALLOC,
"Unable to allocate memory for key type");
goto error;
}
memcpy(entry->key_type_name, key_type_name, key_type_len);
entry->key_type_name[key_type_len]=0;
entry->key_type_len = key_type_len;
}
if (comment) {
entry->comment = LIBSSH2_ALLOC(hosts->session, commentlen+1);
if(!entry->comment) {
@@ -219,6 +238,7 @@ knownhost_add(LIBSSH2_KNOWNHOSTS *hosts,
}
memcpy(entry->comment, comment, commentlen+1);
entry->comment[commentlen]=0; /* force a terminating zero trailer */
entry->comment_len = commentlen;
}
else {
entry->comment = NULL;
@@ -264,8 +284,8 @@ libssh2_knownhost_add(LIBSSH2_KNOWNHOSTS *hosts,
const char *key, size_t keylen,
int typemask, struct libssh2_knownhost **store)
{
return knownhost_add(hosts, host, salt, key, keylen, NULL, 0, typemask,
store);
return knownhost_add(hosts, host, salt, NULL, 0, key, keylen, NULL,
0, typemask, store);
}
@@ -303,8 +323,8 @@ libssh2_knownhost_addc(LIBSSH2_KNOWNHOSTS *hosts,
const char *comment, size_t commentlen,
int typemask, struct libssh2_knownhost **store)
{
return knownhost_add(hosts, host, salt, key, keylen, comment, commentlen,
typemask, store);
return knownhost_add(hosts, host, salt, NULL, 0, key, keylen,
comment, commentlen, typemask, store);
}
/*
@@ -346,6 +366,24 @@ knownhost_check(LIBSSH2_KNOWNHOSTS *hosts,
/* we can't work with a sha1 as given input */
return LIBSSH2_KNOWNHOST_CHECK_MISMATCH;
/* if a port number is given, check for a '[host]:port' first before the
plain 'host' */
if(port >= 0) {
int len = snprintf(hostbuff, sizeof(hostbuff), "[%s]:%d", hostp, port);
if (len < 0 || len >= (int)sizeof(hostbuff)) {
_libssh2_error(hosts->session,
LIBSSH2_ERROR_BUFFER_TOO_SMALL,
"Known-host write buffer too small");
return LIBSSH2_KNOWNHOST_CHECK_FAILURE;
}
host = hostbuff;
numcheck = 2; /* check both combos, start with this */
}
else {
host = hostp;
numcheck = 1; /* only check this host version */
}
if(!(typemask & LIBSSH2_KNOWNHOST_KEYENC_BASE64)) {
/* we got a raw key input, convert it to base64 for the checks below */
size_t nlen = _libssh2_base64_encode(hosts->session, key, keylen,
@@ -361,18 +399,6 @@ knownhost_check(LIBSSH2_KNOWNHOSTS *hosts,
key = keyalloc;
}
/* if a port number is given, check for a '[host]:port' first before the
plain 'host' */
if(port >= 0) {
snprintf(hostbuff, sizeof(hostbuff), "[%s]:%d", hostp, port);
host = hostbuff;
numcheck = 2; /* check both combos, start with this */
}
else {
host = hostp;
numcheck = 1; /* only check this host version */
}
do {
node = _libssh2_list_first(&hosts->head);
while (node) {
@@ -399,7 +425,8 @@ knownhost_check(LIBSSH2_KNOWNHOSTS *hosts,
we can't match it */
break;
}
libssh2_hmac_sha1_init(&ctx, node->salt, node->salt_len);
libssh2_hmac_sha1_init(&ctx, (unsigned char *)node->salt,
node->salt_len);
libssh2_hmac_update(ctx, (unsigned char *)host,
strlen(host));
libssh2_hmac_final(ctx, hash);
@@ -414,23 +441,35 @@ knownhost_check(LIBSSH2_KNOWNHOSTS *hosts,
break;
}
if(match) {
/* host name match, now compare the keys */
if(!strcmp(key, node->key)) {
/* they match! */
if (ext)
*ext = knownhost_to_external(node);
badkey = NULL;
rc = LIBSSH2_KNOWNHOST_CHECK_MATCH;
break;
}
else {
/* remember the first node that had a host match but a
failed key match since we continue our search from
here */
if(!badkey)
badkey = node;
match = 0; /* don't count this as a match anymore */
int host_key_type = typemask & LIBSSH2_KNOWNHOST_KEY_MASK;
int known_key_type =
node->typemask & LIBSSH2_KNOWNHOST_KEY_MASK;
/* match on key type as follows:
- never match on an unknown key type
- if key_type is set to zero, ignore it an match always
- otherwise match when both key types are equal
*/
if ( (host_key_type != LIBSSH2_KNOWNHOST_KEY_UNKNOWN ) &&
( (host_key_type == 0) ||
(host_key_type == known_key_type) ) ) {
/* host name and key type match, now compare the keys */
if(!strcmp(key, node->key)) {
/* they match! */
if (ext)
*ext = knownhost_to_external(node);
badkey = NULL;
rc = LIBSSH2_KNOWNHOST_CHECK_MATCH;
break;
}
else {
/* remember the first node that had a host match but a
failed key match since we continue our search from
here */
if(!badkey)
badkey = node;
}
}
match = 0; /* don't count this as a match anymore */
}
node= _libssh2_list_next(&node->node);
}
@@ -573,6 +612,7 @@ libssh2_knownhost_free(LIBSSH2_KNOWNHOSTS *hosts)
*/
static int oldstyle_hostline(LIBSSH2_KNOWNHOSTS *hosts,
const char *host, size_t hostlen,
const char *key_type_name, size_t key_type_len,
const char *key, size_t keylen, int key_type,
const char *comment, size_t commentlen)
{
@@ -607,7 +647,9 @@ static int oldstyle_hostline(LIBSSH2_KNOWNHOSTS *hosts,
memcpy(hostbuf, name, namelen);
hostbuf[namelen]=0;
rc = knownhost_add(hosts, hostbuf, NULL, key, keylen,
rc = knownhost_add(hosts, hostbuf, NULL,
key_type_name, key_type_len,
key, keylen,
comment, commentlen,
key_type | LIBSSH2_KNOWNHOST_TYPE_PLAIN |
LIBSSH2_KNOWNHOST_KEYENC_BASE64, NULL);
@@ -627,6 +669,7 @@ static int oldstyle_hostline(LIBSSH2_KNOWNHOSTS *hosts,
/* |1|[salt]|[hash] */
static int hashed_hostline(LIBSSH2_KNOWNHOSTS *hosts,
const char *host, size_t hostlen,
const char *key_type_name, size_t key_type_len,
const char *key, size_t keylen, int key_type,
const char *comment, size_t commentlen)
{
@@ -670,9 +713,11 @@ static int hashed_hostline(LIBSSH2_KNOWNHOSTS *hosts,
memcpy(hostbuf, host, hostlen);
hostbuf[hostlen]=0;
return knownhost_add(hosts, hostbuf, salt, key, keylen, comment,
commentlen,
key_type | LIBSSH2_KNOWNHOST_TYPE_SHA1 |
return knownhost_add(hosts, hostbuf, salt,
key_type_name, key_type_len,
key, keylen,
comment, commentlen,
key_type | LIBSSH2_KNOWNHOST_TYPE_SHA1 |
LIBSSH2_KNOWNHOST_KEYENC_BASE64, NULL);
}
else
@@ -694,7 +739,9 @@ static int hostline(LIBSSH2_KNOWNHOSTS *hosts,
const char *key, size_t keylen)
{
const char *comment = NULL;
const char *key_type_name = NULL;
size_t commentlen = 0;
size_t key_type_len = 0;
int key_type;
/* make some checks that the lengths seem sensible */
@@ -703,7 +750,7 @@ static int hostline(LIBSSH2_KNOWNHOSTS *hosts,
LIBSSH2_ERROR_METHOD_NOT_SUPPORTED,
"Failed to parse known_hosts line "
"(key too short)");
switch(key[0]) {
case '0': case '1': case '2': case '3': case '4':
case '5': case '6': case '7': case '8': case '9':
@@ -716,19 +763,21 @@ static int hostline(LIBSSH2_KNOWNHOSTS *hosts,
*/
break;
case 's': /* ssh-dss or ssh-rsa */
if(!strncmp(key, "ssh-dss", 7))
default:
key_type_name = key;
while (keylen && *key &&
(*key != ' ') && (*key != '\t')) {
key++;
keylen--;
}
key_type_len = key - key_type_name;
if (!strncmp(key_type_name, "ssh-dss", key_type_len))
key_type = LIBSSH2_KNOWNHOST_KEY_SSHDSS;
else if(!strncmp(key, "ssh-rsa", 7))
else if (!strncmp(key_type_name, "ssh-rsa", key_type_len))
key_type = LIBSSH2_KNOWNHOST_KEY_SSHRSA;
else
/* unknown key type */
return _libssh2_error(hosts->session,
LIBSSH2_ERROR_METHOD_NOT_SUPPORTED,
"Unknown key type");
key += 7;
keylen -= 7;
key_type = LIBSSH2_KNOWNHOST_KEY_UNKNOWN;
/* skip whitespaces */
while((*key ==' ') || (*key == '\t')) {
@@ -760,11 +809,6 @@ static int hostline(LIBSSH2_KNOWNHOSTS *hosts,
commentlen--;
}
break;
default: /* unknown key format */
return _libssh2_error(hosts->session,
LIBSSH2_ERROR_METHOD_NOT_SUPPORTED,
"Unknown key format");
}
/* Figure out host format */
@@ -774,12 +818,14 @@ static int hostline(LIBSSH2_KNOWNHOSTS *hosts,
for the sake of simplicity, we add them as separate hosts with the
same key
*/
return oldstyle_hostline(hosts, host, hostlen, key, keylen, key_type,
return oldstyle_hostline(hosts, host, hostlen, key_type_name,
key_type_len, key, keylen, key_type,
comment, commentlen);
}
else {
/* |1|[salt]|[hash] */
return hashed_hostline(hosts, host, hostlen, key, keylen, key_type,
return hashed_hostline(hosts, host, hostlen, key_type_name,
key_type_len, key, keylen, key_type,
comment, commentlen);
}
}
@@ -910,8 +956,11 @@ libssh2_knownhost_readfile(LIBSSH2_KNOWNHOSTS *hosts,
file = fopen(filename, "r");
if(file) {
while(fgets(buf, sizeof(buf), file)) {
if(libssh2_knownhost_readline(hosts, buf, strlen(buf), type))
if(libssh2_knownhost_readline(hosts, buf, strlen(buf), type)) {
num = _libssh2_error(hosts->session, LIBSSH2_ERROR_KNOWN_HOSTS,
"Failed to parse known hosts file");
break;
}
num++;
}
fclose(file);
@@ -940,17 +989,10 @@ knownhost_writeline(LIBSSH2_KNOWNHOSTS *hosts,
char *buf, size_t buflen,
size_t *outlen, int type)
{
int rc = LIBSSH2_ERROR_NONE;
int tindex;
const char *keytypes[4]={
"", /* not used */
"", /* this type has no name in the file */
" ssh-rsa",
" ssh-dss"
};
const char *keytype;
size_t nlen;
size_t commentlen = 0;
size_t required_size;
const char *key_type_name;
size_t key_type_len;
/* we only support this single file type for now, bail out on all other
attempts */
@@ -960,75 +1002,131 @@ knownhost_writeline(LIBSSH2_KNOWNHOSTS *hosts,
"Unsupported type of known-host information "
"store");
tindex = (node->typemask & LIBSSH2_KNOWNHOST_KEY_MASK) >>
LIBSSH2_KNOWNHOST_KEY_SHIFT;
switch(node->typemask & LIBSSH2_KNOWNHOST_KEY_MASK) {
case LIBSSH2_KNOWNHOST_KEY_RSA1:
key_type_name = NULL;
key_type_len = 0;
break;
case LIBSSH2_KNOWNHOST_KEY_SSHRSA:
key_type_name = "ssh-rsa";
key_type_len = 7;
break;
case LIBSSH2_KNOWNHOST_KEY_SSHDSS:
key_type_name = "ssh-dss";
key_type_len = 7;
break;
case LIBSSH2_KNOWNHOST_KEY_UNKNOWN:
key_type_name = node->key_type_name;
if (key_type_name) {
key_type_len = node->key_type_len;
break;
}
/* otherwise fallback to default and error */
default:
return _libssh2_error(hosts->session,
LIBSSH2_ERROR_METHOD_NOT_SUPPORTED,
"Unsupported type of known-host entry");
}
/* set the string used in the file */
keytype = keytypes[tindex];
/* When putting together the host line there are three aspects to consider:
- Hashed (SHA1) or unhashed hostname
- key name or no key name (RSA1)
- comment or no comment
This means there are 2^3 different formats:
("|1|%s|%s %s %s %s\n", salt, hashed_host, key_name, key, comment)
("|1|%s|%s %s %s\n", salt, hashed_host, key_name, key)
("|1|%s|%s %s %s\n", salt, hashed_host, key, comment)
("|1|%s|%s %s\n", salt, hashed_host, key)
("%s %s %s %s\n", host, key_name, key, comment)
("%s %s %s\n", host, key_name, key)
("%s %s %s\n", host, key, comment)
("%s %s\n", host, key)
Even if the buffer is too small, we have to set outlen to the number of
characters the complete line would have taken. We also don't write
anything to the buffer unless we are sure we can write everything to the
buffer. */
/* calculate extra space needed for comment */
required_size = strlen(node->key);
if(key_type_len)
required_size += key_type_len + 1; /* ' ' = 1 */
if(node->comment)
commentlen = strlen(node->comment) + 1;
required_size += node->comment_len + 1; /* ' ' = 1 */
if((node->typemask & LIBSSH2_KNOWNHOST_TYPE_MASK) ==
LIBSSH2_KNOWNHOST_TYPE_SHA1) {
char *namealloc;
size_t name_base64_len;
char *saltalloc;
nlen = _libssh2_base64_encode(hosts->session, node->name,
node->name_len, &namealloc);
if(!nlen)
size_t salt_base64_len;
name_base64_len = _libssh2_base64_encode(hosts->session, node->name,
node->name_len, &namealloc);
if(!name_base64_len)
return _libssh2_error(hosts->session, LIBSSH2_ERROR_ALLOC,
"Unable to allocate memory for "
"base64-encoded host name");
nlen = _libssh2_base64_encode(hosts->session,
node->salt, node->salt_len,
&saltalloc);
if(!nlen) {
free(namealloc);
salt_base64_len = _libssh2_base64_encode(hosts->session,
node->salt, node->salt_len,
&saltalloc);
if(!salt_base64_len) {
LIBSSH2_FREE(hosts->session, namealloc);
return _libssh2_error(hosts->session, LIBSSH2_ERROR_ALLOC,
"Unable to allocate memory for "
"base64-encoded salt");
}
nlen = strlen(saltalloc) + strlen(namealloc) + strlen(keytype) +
strlen(node->key) + commentlen + 7;
required_size += salt_base64_len + name_base64_len + 7;
/* |1| + | + ' ' + \n + \0 = 7 */
if(nlen <= buflen)
if(node->comment)
snprintf(buf, buflen, "|1|%s|%s%s %s %s\n", saltalloc, namealloc,
keytype, node->key, node->comment);
if(required_size <= buflen) {
if(node->comment && key_type_len)
snprintf(buf, buflen, "|1|%s|%s %s %s %s\n", saltalloc,
namealloc, key_type_name, node->key, node->comment);
else if (node->comment)
snprintf(buf, buflen, "|1|%s|%s %s %s\n", saltalloc, namealloc,
node->key, node->comment);
else if (key_type_len)
snprintf(buf, buflen, "|1|%s|%s %s %s\n", saltalloc, namealloc,
key_type_name, node->key);
else
snprintf(buf, buflen, "|1|%s|%s%s %s\n", saltalloc, namealloc,
keytype, node->key);
else
rc = _libssh2_error(hosts->session, LIBSSH2_ERROR_BUFFER_TOO_SMALL,
"Known-host write buffer too small");
snprintf(buf, buflen, "|1|%s|%s %s\n", saltalloc, namealloc,
node->key);
}
free(namealloc);
free(saltalloc);
LIBSSH2_FREE(hosts->session, namealloc);
LIBSSH2_FREE(hosts->session, saltalloc);
}
else {
nlen = strlen(node->name) + strlen(keytype) + strlen(node->key) +
commentlen + 3;
required_size += node->name_len + 3;
/* ' ' + '\n' + \0 = 3 */
if(nlen <= buflen)
/* these types have the plain name */
if(node->comment)
snprintf(buf, buflen, "%s%s %s %s\n", node->name, keytype, node->key,
node->comment);
if(required_size <= buflen) {
if(node->comment && key_type_len)
snprintf(buf, buflen, "%s %s %s %s\n", node->name,
key_type_name, node->key, node->comment);
else if (node->comment)
snprintf(buf, buflen, "%s %s %s\n", node->name, node->key,
node->comment);
else if (key_type_len)
snprintf(buf, buflen, "%s %s %s\n", node->name, key_type_name,
node->key);
else
snprintf(buf, buflen, "%s%s %s\n", node->name, keytype, node->key);
else
rc = _libssh2_error(hosts->session, LIBSSH2_ERROR_BUFFER_TOO_SMALL,
"Known-host write buffer too small");
snprintf(buf, buflen, "%s %s\n", node->name, node->key);
}
}
/* we report the full length of the data with the trailing zero excluded */
*outlen = nlen-1;
*outlen = required_size-1;
return rc;
if(required_size <= buflen)
return LIBSSH2_ERROR_NONE;
else
return _libssh2_error(hosts->session, LIBSSH2_ERROR_BUFFER_TOO_SMALL,
"Known-host write buffer too small");
}
/*
@@ -1086,8 +1184,8 @@ libssh2_knownhost_writefile(LIBSSH2_KNOWNHOSTS *hosts,
for(node = _libssh2_list_first(&hosts->head);
node;
node= _libssh2_list_next(&node->node) ) {
size_t wrote;
node = _libssh2_list_next(&node->node)) {
size_t wrote = 0;
size_t nwrote;
rc = knownhost_writeline(hosts, node, buffer, sizeof(buffer), &wrote,
type);

View File

@@ -342,7 +342,7 @@ _libssh2_dsa_new_private(libssh2_dsa_ctx ** dsa,
int
_libssh2_rsa_sha1_sign(LIBSSH2_SESSION * session,
libssh2_dsa_ctx * rsactx,
libssh2_rsa_ctx * rsactx,
const unsigned char *hash,
size_t hash_len,
unsigned char **signature, size_t *signature_len)
@@ -553,17 +553,11 @@ _libssh2_cipher_init(_libssh2_cipher_ctx * h,
int
_libssh2_cipher_crypt(_libssh2_cipher_ctx * ctx,
_libssh2_cipher_type(algo),
int encrypt, unsigned char *block)
int encrypt, unsigned char *block, size_t blklen)
{
int cipher = _libssh2_gcry_cipher (algo);
size_t blklen = gcry_cipher_get_algo_blklen(cipher);
int ret;
if (blklen == 1) {
/* Hack for arcfour. */
blklen = 8;
}
if (encrypt) {
ret = gcry_cipher_encrypt(*ctx, block, blklen, block, blklen);
} else {

View File

@@ -61,15 +61,21 @@
#define libssh2_sha1_ctx gcry_md_hd_t
#define libssh2_sha1_init(ctx) gcry_md_open (ctx, GCRY_MD_SHA1, 0);
#define libssh2_sha1_update(ctx, data, len) gcry_md_write (ctx, data, len)
#define libssh2_sha1_update(ctx, data, len) \
gcry_md_write (ctx, (unsigned char *) data, len)
#define libssh2_sha1_final(ctx, out) \
memcpy (out, gcry_md_read (ctx, 0), SHA_DIGEST_LENGTH), gcry_md_close (ctx)
#define libssh2_sha1(message, len, out) \
gcry_md_hash_buffer (GCRY_MD_SHA1, out, message, len)
#define libssh2_md5_ctx gcry_md_hd_t
#define libssh2_md5_init(ctx) gcry_md_open (ctx, GCRY_MD_MD5, 0);
#define libssh2_md5_update(ctx, data, len) gcry_md_write (ctx, data, len)
/* returns 0 in case of failure */
#define libssh2_md5_init(ctx) \
(GPG_ERR_NO_ERROR == gcry_md_open (ctx, GCRY_MD_MD5, 0))
#define libssh2_md5_update(ctx, data, len) \
gcry_md_write (ctx, (unsigned char *) data, len)
#define libssh2_md5_final(ctx, out) \
memcpy (out, gcry_md_read (ctx, 0), MD5_DIGEST_LENGTH), gcry_md_close (ctx)
#define libssh2_md5(message, len, out) \
@@ -86,7 +92,7 @@
gcry_md_open (ctx, GCRY_MD_RMD160, GCRY_MD_FLAG_HMAC), \
gcry_md_setkey (*ctx, key, keylen)
#define libssh2_hmac_update(ctx, data, datalen) \
gcry_md_write (ctx, data, datalen)
gcry_md_write (ctx, (unsigned char *) data, datalen)
#define libssh2_hmac_final(ctx, data) \
memcpy (data, gcry_md_read (ctx, 0), \
gcry_md_get_algo_dlen (gcry_md_get_algo (ctx)))

View File

@@ -1,5 +1,5 @@
/* Copyright (c) 2004-2008, 2010, Sara Golemon <sarag@libssh2.org>
* Copyright (c) 2009-2011 by Daniel Stenberg
* Copyright (c) 2009-2014 by Daniel Stenberg
* Copyright (c) 2010 Simon Josefsson
* All rights reserved.
*
@@ -108,6 +108,11 @@
#define TRUE 1
#endif
#ifdef _MSC_VER
/* "inline" keyword is valid only with C++ engine! */
#define inline __inline
#endif
/* Provide iovec / writev on WIN32 platform. */
#ifdef WIN32
@@ -116,8 +121,6 @@ struct iovec {
void * iov_base;
};
#define inline __inline
static inline int writev(int sock, struct iovec *iov, int nvecs)
{
DWORD ret;
@@ -134,14 +137,8 @@ static inline int writev(int sock, struct iovec *iov, int nvecs)
#ifdef HAVE_WINSOCK2_H
#include <winsock2.h>
#include <mswsock.h>
#include <ws2tcpip.h>
#ifdef _MSC_VER
/* "inline" keyword is valid only with C++ engine! */
#define inline __inline
#endif
#endif
/* RFC4253 section 6.1 Maximum Packet Length says:
@@ -155,6 +152,7 @@ static inline int writev(int sock, struct iovec *iov, int nvecs)
#define LIBSSH2_ALLOC(session, count) \
session->alloc((count), &(session)->abstract)
#define LIBSSH2_CALLOC(session, count) _libssh2_calloc(session, count)
#define LIBSSH2_REALLOC(session, ptr, count) \
((ptr) ? session->realloc((ptr), (count), &(session)->abstract) : \
session->alloc((count), &(session)->abstract))
@@ -357,6 +355,8 @@ struct _LIBSSH2_CHANNEL
libssh2_channel_data local, remote;
/* Amount of bytes to be refunded to receive window (but not yet sent) */
uint32_t adjust_queue;
/* Data immediately available for reading */
uint32_t read_avail;
LIBSSH2_SESSION *session;
@@ -575,7 +575,7 @@ struct _LIBSSH2_SESSION
/* Agreed Key Exchange Method */
const LIBSSH2_KEX_METHOD *kex;
int burn_optimistic_kexinit:1;
unsigned int burn_optimistic_kexinit:1;
unsigned char *session_id;
uint32_t session_id_len;
@@ -597,6 +597,7 @@ struct _LIBSSH2_SESSION
uint32_t server_hostkey_len;
#if LIBSSH2_MD5
unsigned char server_hostkey_md5[MD5_DIGEST_LENGTH];
int server_hostkey_md5_valid;
#endif /* ! LIBSSH2_MD5 */
unsigned char server_hostkey_sha1[SHA_DIGEST_LENGTH];
@@ -882,7 +883,7 @@ struct _LIBSSH2_CRYPT_METHOD
int *free_iv, unsigned char *secret, int *free_secret,
int encrypt, void **abstract);
int (*crypt) (LIBSSH2_SESSION * session, unsigned char *block,
void **abstract);
size_t blocksize, void **abstract);
int (*dtor) (LIBSSH2_SESSION * session, void **abstract);
_libssh2_cipher_type(algo);
@@ -892,6 +893,7 @@ struct _LIBSSH2_COMP_METHOD
{
const char *name;
int compress; /* 1 if it does compress, 0 if it doesn't */
int use_in_auth; /* 1 if compression should be used in userauth */
int (*init) (LIBSSH2_SESSION *session, int compress, void **abstract);
int (*comp) (LIBSSH2_SESSION *session,
unsigned char *dest,
@@ -921,6 +923,9 @@ void _libssh2_debug(LIBSSH2_SESSION * session, int context, const char *format,
static inline void
_libssh2_debug(LIBSSH2_SESSION * session, int context, const char *format, ...)
{
(void)session;
(void)context;
(void)format;
}
#endif
#endif
@@ -1030,9 +1035,9 @@ void _libssh2_init_if_needed (void);
/* define to output the libssh2_int64_t type in a *printf() */
#if defined( __BORLANDC__ ) || defined( _MSC_VER ) || defined( __MINGW32__ )
#define LIBSSH2_INT64_T_FORMAT "I64"
#define LIBSSH2_INT64_T_FORMAT "I64d"
#else
#define LIBSSH2_INT64_T_FORMAT "ll"
#define LIBSSH2_INT64_T_FORMAT "lld"
#endif
#endif /* LIBSSH2_H */

View File

@@ -1,5 +1,5 @@
/* Copyright (c) 2004-2007 Sara Golemon <sarag@libssh2.org>
* Copyright (c) 2009-2010 by Daniel Stenberg
* Copyright (c) 2009-2014 by Daniel Stenberg
* Copyright (c) 2010 Simon Josefsson
* All rights reserved.
*
@@ -94,9 +94,14 @@ static int wsa2errno(void)
* Replacement for the standard recv, return -errno on failure.
*/
ssize_t
_libssh2_recv(libssh2_socket_t sock, void *buffer, size_t length, int flags, void **abstract)
_libssh2_recv(libssh2_socket_t sock, void *buffer, size_t length,
int flags, void **abstract)
{
ssize_t rc = recv(sock, buffer, length, flags);
ssize_t rc;
(void) abstract;
rc = recv(sock, buffer, length, flags);
#ifdef WIN32
if (rc < 0 )
return -wsa2errno();
@@ -128,7 +133,11 @@ ssize_t
_libssh2_send(libssh2_socket_t sock, const void *buffer, size_t length,
int flags, void **abstract)
{
ssize_t rc = send(sock, buffer, length, flags);
ssize_t rc;
(void) abstract;
rc = send(sock, buffer, length, flags);
#ifdef WIN32
if (rc < 0 )
return -wsa2errno();
@@ -257,15 +266,15 @@ libssh2_base64_decode(LIBSSH2_SESSION *session, char **data,
continue;
switch (i % 4) {
case 0:
d[len] = v << 2;
d[len] = (unsigned char)(v << 2);
break;
case 1:
d[len++] |= v >> 4;
d[len] = v << 4;
d[len] = (unsigned char)(v << 4);
break;
case 2:
d[len++] |= v >> 2;
d[len] = v << 6;
d[len] = (unsigned char)(v << 6);
break;
case 3:
d[len++] |= v;
@@ -596,7 +605,7 @@ int __cdecl _libssh2_gettimeofday(struct timeval *tp, void *tzp)
unsigned __int64 ns100; /*time since 1 Jan 1601 in 100ns units */
FILETIME ft;
} _now;
(void)tzp;
if(tp)
{
GetSystemTimeAsFileTime (&_now.ft);
@@ -610,3 +619,12 @@ int __cdecl _libssh2_gettimeofday(struct timeval *tp, void *tzp)
#endif
void *_libssh2_calloc(LIBSSH2_SESSION* session, size_t size)
{
void *p = LIBSSH2_ALLOC(session, size);
if(p) {
memset(p, 0, size);
}
return p;
}

View File

@@ -1,6 +1,6 @@
#ifndef __LIBSSH2_MISC_H
#define __LIBSSH2_MISC_H
/* Copyright (c) 2009-2011 by Daniel Stenberg
/* Copyright (c) 2009-2014 by Daniel Stenberg
*
* All rights reserved.
*
@@ -77,8 +77,9 @@ libssh2_uint64_t _libssh2_ntohu64(const unsigned char *buf);
void _libssh2_htonu32(unsigned char *buf, uint32_t val);
void _libssh2_store_u32(unsigned char **buf, uint32_t value);
void _libssh2_store_str(unsigned char **buf, const char *str, size_t len);
void *_libssh2_calloc(LIBSSH2_SESSION* session, size_t size);
#if defined(LIBSSH2_WIN32) && !defined(__MINGW32__)
#if defined(LIBSSH2_WIN32) && !defined(__MINGW32__) && !defined(__CYGWIN__)
/* provide a private one */
#undef HAVE_GETTIMEOFDAY
int __cdecl _libssh2_gettimeofday(struct timeval *tp, void *tzp);

View File

@@ -40,7 +40,7 @@
#include "libssh2_priv.h"
#ifndef LIBSSH2_LIBGCRYPT /* compile only if we build with OpenSSL */
#ifdef LIBSSH2_OPENSSL /* compile only if we build with openssl */
#include <string.h>
@@ -175,25 +175,19 @@ _libssh2_cipher_init(_libssh2_cipher_ctx * h,
unsigned char *iv, unsigned char *secret, int encrypt)
{
EVP_CIPHER_CTX_init(h);
EVP_CipherInit(h, algo(), secret, iv, encrypt);
return 0;
return !EVP_CipherInit(h, algo(), secret, iv, encrypt);
}
int
_libssh2_cipher_crypt(_libssh2_cipher_ctx * ctx,
_libssh2_cipher_type(algo),
int encrypt, unsigned char *block)
int encrypt, unsigned char *block, size_t blocksize)
{
int blocksize = ctx->cipher->block_size;
unsigned char buf[EVP_MAX_BLOCK_LENGTH];
int ret;
(void) algo;
(void) encrypt;
if (blocksize == 1) {
/* Hack for arcfour. */
blocksize = 8;
}
ret = EVP_Cipher(ctx, buf, block, blocksize);
if (ret == 1) {
memcpy(block, buf, blocksize);
@@ -221,13 +215,10 @@ aes_ctr_init(EVP_CIPHER_CTX *ctx, const unsigned char *key,
* variable "c" is leaked from this scope, but is later freed
* in aes_ctr_cleanup
*/
aes_ctr_ctx *c = malloc(sizeof(*c));
aes_ctr_ctx *c;
const EVP_CIPHER *aes_cipher;
(void) enc;
if (c == NULL)
return 0;
switch (ctx->key_len) {
case 16:
aes_cipher = EVP_aes_128_ecb();
@@ -241,11 +232,20 @@ aes_ctr_init(EVP_CIPHER_CTX *ctx, const unsigned char *key,
default:
return 0;
}
c->aes_ctx = malloc(sizeof(EVP_CIPHER_CTX));
if (c->aes_ctx == NULL)
c = malloc(sizeof(*c));
if (c == NULL)
return 0;
c->aes_ctx = malloc(sizeof(EVP_CIPHER_CTX));
if (c->aes_ctx == NULL) {
free(c);
return 0;
}
if (EVP_EncryptInit(c->aes_ctx, aes_cipher, key, NULL) != 1) {
free(c->aes_ctx);
free(c);
return 0;
}
@@ -509,23 +509,39 @@ _libssh2_dsa_sha1_sign(libssh2_dsa_ctx * dsactx,
}
#endif /* LIBSSH_DSA */
int
libssh2_sha1_init(libssh2_sha1_ctx *ctx)
{
EVP_MD_CTX_init(ctx);
return EVP_DigestInit(ctx, EVP_get_digestbyname("sha1"));
}
void
libssh2_sha1(const unsigned char *message, unsigned long len,
unsigned char *out)
{
EVP_MD_CTX ctx;
EVP_MD_CTX_init(&ctx);
EVP_DigestInit(&ctx, EVP_get_digestbyname("sha1"));
EVP_DigestUpdate(&ctx, message, len);
EVP_DigestFinal(&ctx, out, NULL);
}
int
libssh2_md5_init(libssh2_md5_ctx *ctx)
{
EVP_MD_CTX_init(ctx);
return EVP_DigestInit(ctx, EVP_get_digestbyname("md5"));
}
void
libssh2_md5(const unsigned char *message, unsigned long len,
unsigned char *out)
{
EVP_MD_CTX ctx;
EVP_MD_CTX_init(&ctx);
EVP_DigestInit(&ctx, EVP_get_digestbyname("md5"));
EVP_DigestUpdate(&ctx, message, len);
EVP_DigestFinal(&ctx, out, NULL);
@@ -801,4 +817,4 @@ _libssh2_pub_priv_keyfile(LIBSSH2_SESSION *session,
return st;
}
#endif /* !LIBSSH2_LIBGCRYPT */
#endif /* LIBSSH2_OPENSSL */

View File

@@ -107,13 +107,15 @@
#define _libssh2_random(buf, len) RAND_bytes ((buf), (len))
#define libssh2_sha1_ctx EVP_MD_CTX
#define libssh2_sha1_init(ctx) EVP_DigestInit(ctx, EVP_get_digestbyname("sha1"))
int libssh2_sha1_init(libssh2_sha1_ctx *ctx);
#define libssh2_sha1_update(ctx, data, len) EVP_DigestUpdate(&(ctx), data, len)
#define libssh2_sha1_final(ctx, out) EVP_DigestFinal(&(ctx), out, NULL)
void libssh2_sha1(const unsigned char *message, unsigned long len, unsigned char *out);
#define libssh2_md5_ctx EVP_MD_CTX
#define libssh2_md5_init(ctx) EVP_DigestInit(ctx, EVP_get_digestbyname("md5"))
/* returns 0 in case of failure */
int libssh2_md5_init(libssh2_md5_ctx *);
#define libssh2_md5_update(ctx, data, len) EVP_DigestUpdate(&(ctx), data, len)
#define libssh2_md5_final(ctx, out) EVP_DigestFinal(&(ctx), out, NULL)
void libssh2_md5(const unsigned char *message, unsigned long len, unsigned char *out);
@@ -148,9 +150,15 @@ void libssh2_md5(const unsigned char *message, unsigned long len, unsigned char
#define _libssh2_cipher_aes256 EVP_aes_256_cbc
#define _libssh2_cipher_aes192 EVP_aes_192_cbc
#define _libssh2_cipher_aes128 EVP_aes_128_cbc
#ifdef HAVE_EVP_AES_128_CTR
#define _libssh2_cipher_aes128ctr EVP_aes_128_ctr
#define _libssh2_cipher_aes192ctr EVP_aes_192_ctr
#define _libssh2_cipher_aes256ctr EVP_aes_256_ctr
#else
#define _libssh2_cipher_aes128ctr _libssh2_EVP_aes_128_ctr
#define _libssh2_cipher_aes192ctr _libssh2_EVP_aes_192_ctr
#define _libssh2_cipher_aes256ctr _libssh2_EVP_aes_256_ctr
#endif
#define _libssh2_cipher_blowfish EVP_bf_cbc
#define _libssh2_cipher_arcfour EVP_rc4
#define _libssh2_cipher_cast5 EVP_cast5_cbc

View File

@@ -1,6 +1,6 @@
/* Copyright (c) 2004-2007, Sara Golemon <sarag@libssh2.org>
* Copyright (c) 2005,2006 Mikhail Gusarov
* Copyright (c) 2009-2010 by Daniel Stenberg
* Copyright (c) 2009-2014 by Daniel Stenberg
* Copyright (c) 2010 Simon Josefsson
* All rights reserved.
*
@@ -139,7 +139,7 @@ packet_queue_listener(LIBSSH2_SESSION * session, unsigned char *data,
break;
}
channel = LIBSSH2_ALLOC(session, sizeof(LIBSSH2_CHANNEL));
channel = LIBSSH2_CALLOC(session, sizeof(LIBSSH2_CHANNEL));
if (!channel) {
_libssh2_error(session, LIBSSH2_ERROR_ALLOC,
"Unable to allocate a channel for "
@@ -150,8 +150,6 @@ packet_queue_listener(LIBSSH2_SESSION * session, unsigned char *data,
}
listen_state->channel = channel;
memset(channel, 0, sizeof(LIBSSH2_CHANNEL));
channel->session = session;
channel->channel_type_len = sizeof("forwarded-tcpip") - 1;
channel->channel_type = LIBSSH2_ALLOC(session,
@@ -218,9 +216,11 @@ packet_queue_listener(LIBSSH2_SESSION * session, unsigned char *data,
}
/* Link the channel into the end of the queue list */
_libssh2_list_add(&listn->queue,
&listen_state->channel->node);
listn->queue_size++;
if (listen_state->channel) {
_libssh2_list_add(&listn->queue,
&listen_state->channel->node);
listn->queue_size++;
}
listen_state->state = libssh2_NB_state_idle;
return 0;
@@ -297,14 +297,13 @@ packet_x11_open(LIBSSH2_SESSION * session, unsigned char *data,
if (session->x11) {
if (x11open_state->state == libssh2_NB_state_allocated) {
channel = LIBSSH2_ALLOC(session, sizeof(LIBSSH2_CHANNEL));
channel = LIBSSH2_CALLOC(session, sizeof(LIBSSH2_CHANNEL));
if (!channel) {
_libssh2_error(session, LIBSSH2_ERROR_ALLOC,
"allocate a channel for new connection");
failure_code = SSH_OPEN_RESOURCE_SHORTAGE;
goto x11_exit;
}
memset(channel, 0, sizeof(LIBSSH2_CHANNEL));
channel->session = session;
channel->channel_type_len = sizeof("x11") - 1;
@@ -408,6 +407,7 @@ packet_x11_open(LIBSSH2_SESSION * session, unsigned char *data,
*
* The input pointer 'data' is pointing to allocated data that this function
* is asked to deal with so on failure OR success, it must be freed fine.
* The only exception is when the return code is LIBSSH2_ERROR_EAGAIN.
*
* This function will always be called with 'datalen' greater than zero.
*/
@@ -583,7 +583,8 @@ _libssh2_packet_add(LIBSSH2_SESSION * session, unsigned char *data,
if (want_reply) {
unsigned char packet = SSH_MSG_REQUEST_FAILURE;
static const unsigned char packet =
SSH_MSG_REQUEST_FAILURE;
libssh2_packet_add_jump_point5:
session->packAdd_state = libssh2_NB_state_jump5;
rc = _libssh2_transport_send(session, &packet, 1, NULL, 0);
@@ -653,6 +654,18 @@ _libssh2_packet_add(LIBSSH2_SESSION * session, unsigned char *data,
_libssh2_debug(session, LIBSSH2_TRACE_CONN,
"Ignoring extended data and refunding %d bytes",
(int) (datalen - 13));
if (channelp->read_avail + datalen - data_head >=
channelp->remote.window_size)
datalen = channelp->remote.window_size -
channelp->read_avail + data_head;
channelp->remote.window_size -= datalen - data_head;
_libssh2_debug(session, LIBSSH2_TRACE_CONN,
"shrinking window size by %lu bytes to %lu, read_avail %lu",
datalen - data_head,
channelp->remote.window_size,
channelp->read_avail);
session->packAdd_channelp = channelp;
/* Adjust the window based on the block we just freed */
@@ -684,7 +697,7 @@ _libssh2_packet_add(LIBSSH2_SESSION * session, unsigned char *data,
" to receive, truncating");
datalen = channelp->remote.packet_size + data_head;
}
if (channelp->remote.window_size <= 0) {
if (channelp->remote.window_size <= channelp->read_avail) {
/*
* Spec says we MAY ignore bytes sent beyond
* window_size
@@ -700,17 +713,26 @@ _libssh2_packet_add(LIBSSH2_SESSION * session, unsigned char *data,
/* Reset EOF status */
channelp->remote.eof = 0;
if ((datalen - data_head) > channelp->remote.window_size) {
if (channelp->read_avail + datalen - data_head >
channelp->remote.window_size) {
_libssh2_error(session,
LIBSSH2_ERROR_CHANNEL_WINDOW_EXCEEDED,
"Remote sent more data than current "
"window allows, truncating");
datalen = channelp->remote.window_size + data_head;
channelp->remote.window_size = 0;
datalen = channelp->remote.window_size -
channelp->read_avail + data_head;
}
else
/* Now that we've received it, shrink our window */
channelp->remote.window_size -= datalen - data_head;
/* Update the read_avail counter. The window size will be
* updated once the data is actually read from the queue
* from an upper layer */
channelp->read_avail += datalen - data_head;
_libssh2_debug(session, LIBSSH2_TRACE_CONN,
"increasing read_avail by %lu bytes to %lu/%lu",
(long)(datalen - data_head),
(long)channelp->read_avail,
(long)channelp->remote.window_size);
break;
@@ -751,7 +773,7 @@ _libssh2_packet_add(LIBSSH2_SESSION * session, unsigned char *data,
if(datalen >= 9) {
uint32_t channel = _libssh2_ntohu32(data + 1);
uint32_t len = _libssh2_ntohu32(data + 5);
unsigned char want_reply = 0;
unsigned char want_reply = 1;
if(len < (datalen - 10))
want_reply = data[9 + len];
@@ -945,6 +967,7 @@ _libssh2_packet_add(LIBSSH2_SESSION * session, unsigned char *data,
if (!packetp) {
_libssh2_debug(session, LIBSSH2_ERROR_ALLOC,
"memory for packet");
LIBSSH2_FREE(session, data);
session->packAdd_state = libssh2_NB_state_idle;
return LIBSSH2_ERROR_ALLOC;
}
@@ -1134,14 +1157,14 @@ _libssh2_packet_burn(LIBSSH2_SESSION * session,
{
unsigned char *data;
size_t data_len;
unsigned char all_packets[255];
int i;
unsigned char i, all_packets[255];
int ret;
if (*state == libssh2_NB_state_idle) {
for(i = 1; i < 256; i++) {
for(i = 1; i < 255; i++) {
all_packets[i - 1] = i;
}
all_packets[254] = 0;
if (_libssh2_packet_askv(session, all_packets, &data, &data_len, 0,
NULL, 0) == 0) {
@@ -1170,7 +1193,8 @@ _libssh2_packet_burn(LIBSSH2_SESSION * session,
/* Be lazy, let packet_ask pull it out of the brigade */
if (0 ==
_libssh2_packet_ask(session, ret, &data, &data_len, 0, NULL, 0)) {
_libssh2_packet_ask(session, (unsigned char)ret,
&data, &data_len, 0, NULL, 0)) {
/* Smoke 'em if you got 'em */
LIBSSH2_FREE(session, data);
*state = libssh2_NB_state_idle;

View File

@@ -38,8 +38,6 @@
#include "libssh2_priv.h"
#ifdef LIBSSH2_LIBGCRYPT /* compile only if we build with libgcrypt */
static int
readline(char *line, int line_size, FILE * fp)
{
@@ -69,6 +67,8 @@ _libssh2_pem_parse(LIBSSH2_SESSION * session,
int ret;
do {
*line = '\0';
if (readline(line, LINE_SIZE, fp)) {
return -1;
}
@@ -93,12 +93,18 @@ _libssh2_pem_parse(LIBSSH2_SESSION * session,
b64datalen += linelen;
}
*line = '\0';
if (readline(line, LINE_SIZE, fp)) {
ret = -1;
goto out;
}
} while (strcmp(line, headerend) != 0);
if (!b64data) {
return -1;
}
if (libssh2_base64_decode(session, (char**) data, datalen,
b64data, b64datalen)) {
ret = -1;
@@ -209,5 +215,3 @@ _libssh2_pem_decode_integer(unsigned char **data, unsigned int *datalen,
return 0;
}
#endif /* LIBSSH2_LIBGCRYPT */

View File

@@ -1,5 +1,5 @@
/* Copyright (c) 2004-2007, Sara Golemon <sarag@libssh2.org>
* Copyright (c) 2010 by Daniel Stenberg
* Copyright (c) 2010-2014 by Daniel Stenberg
* All rights reserved.
*
* Redistribution and use in source and binary forms,
@@ -136,6 +136,8 @@ publickey_packet_receive(LIBSSH2_PUBLICKEY * pkey,
LIBSSH2_SESSION *session = channel->session;
unsigned char buffer[4];
int rc;
*data = NULL; /* default to nothing returned */
*data_len = 0;
if (pkey->receive_state == libssh2_NB_state_idle) {
rc = _libssh2_channel_read(channel, 0, (char *) buffer, 4);
@@ -348,13 +350,12 @@ static LIBSSH2_PUBLICKEY *publickey_init(LIBSSH2_SESSION *session)
}
session->pkeyInit_pkey =
LIBSSH2_ALLOC(session, sizeof(LIBSSH2_PUBLICKEY));
LIBSSH2_CALLOC(session, sizeof(LIBSSH2_PUBLICKEY));
if (!session->pkeyInit_pkey) {
_libssh2_error(session, LIBSSH2_ERROR_ALLOC,
"Unable to allocate a new publickey structure");
goto err_exit;
}
memset(session->pkeyInit_pkey, 0, sizeof(LIBSSH2_PUBLICKEY));
session->pkeyInit_pkey->channel = session->pkeyInit_channel;
session->pkeyInit_pkey->version = 0;
@@ -384,7 +385,7 @@ static LIBSSH2_PUBLICKEY *publickey_init(LIBSSH2_SESSION *session)
_libssh2_error(session, LIBSSH2_ERROR_EAGAIN,
"Would block sending publickey version packet");
return NULL;
} else if (rc) {
} else if (rc < 0) {
_libssh2_error(session, rc,
"Unable to send publickey version packet");
goto err_exit;

View File

@@ -133,7 +133,7 @@ shell_quotearg(const char *path, unsigned char *buf,
* Processing States:
* UQSTRING: unquoted string: ... -- used for quoting exclamation
* marks. This is the initial state
* SQSTRING: single-qouted-string: '... -- any character may follow
* SQSTRING: single-quoted-string: '... -- any character may follow
* QSTRING: quoted string: "... -- only apostrophes may follow
*/
enum { UQSTRING, SQSTRING, QSTRING } state = UQSTRING;
@@ -727,7 +727,7 @@ scp_recv(LIBSSH2_SESSION * session, const char *path, struct stat * sb)
sb->st_mtime = session->scpRecv_mtime;
sb->st_atime = session->scpRecv_atime;
sb->st_size = session->scpRecv_size;
sb->st_mode = session->scpRecv_mode;
sb->st_mode = (unsigned short)session->scpRecv_mode;
}
session->scpRecv_state = libssh2_NB_state_idle;
@@ -957,7 +957,7 @@ scp_send(LIBSSH2_SESSION * session, const char *path, int mode,
session->scpSend_response_len =
snprintf((char *) session->scpSend_response,
LIBSSH2_SCP_RESPONSE_BUFLEN, "C0%o %"
LIBSSH2_INT64_T_FORMAT "u %s\n", mode,
LIBSSH2_INT64_T_FORMAT " %s\n", mode,
size, base);
_libssh2_debug(session, LIBSSH2_TRACE_SCP, "Sent %s",
session->scpSend_response);

View File

@@ -143,7 +143,7 @@ banner_receive(LIBSSH2_SESSION * session)
if (ret == 0) {
session->socket_state = LIBSSH2_SOCKET_DISCONNECTED;
return LIBSSH2_ERROR_SOCKET_RECV;
return LIBSSH2_ERROR_SOCKET_DISCONNECT;
}
if (c == '\0') {
@@ -686,8 +686,13 @@ session_startup(LIBSSH2_SESSION *session, libssh2_socket_t sock)
!get_socket_nonblocking(session->socket_fd);
if (session->socket_prev_blockstate) {
/* If in blocking state chang to non-blocking */
session_nonblock(session->socket_fd, 1);
/* If in blocking state change to non-blocking */
rc = session_nonblock(session->socket_fd, 1);
if (rc) {
return _libssh2_error(session, rc,
"Failed changing socket's "
"blocking state to non-blocking");
}
}
session->startup_state = libssh2_NB_state_created;
@@ -834,7 +839,7 @@ session_free(LIBSSH2_SESSION *session)
_libssh2_debug(session, LIBSSH2_TRACE_TRANS, "Freeing session resource",
session->remote.banner);
session->state = libssh2_NB_state_created;
session->free_state = libssh2_NB_state_created;
}
if (session->free_state == libssh2_NB_state_created) {
@@ -845,17 +850,17 @@ session_free(LIBSSH2_SESSION *session)
return rc;
}
session->state = libssh2_NB_state_sent;
session->free_state = libssh2_NB_state_sent;
}
if (session->state == libssh2_NB_state_sent) {
if (session->free_state == libssh2_NB_state_sent) {
while ((l = _libssh2_list_first(&session->listeners))) {
rc = _libssh2_channel_forward_cancel(l);
if (rc == LIBSSH2_ERROR_EAGAIN)
return rc;
}
session->state = libssh2_NB_state_sent1;
session->free_state = libssh2_NB_state_sent1;
}
if (session->state & LIBSSH2_STATE_NEWKEYS) {
@@ -1016,6 +1021,14 @@ session_free(LIBSSH2_SESSION *session)
if (session->scpSend_command) {
LIBSSH2_FREE(session, session->scpSend_command);
}
if (session->sftpInit_sftp) {
LIBSSH2_FREE(session, session->sftpInit_sftp);
}
/* Free payload buffer */
if (session->packet.total_num) {
LIBSSH2_FREE(session, session->packet.payload);
}
/* Cleanup all remaining packets */
while ((pkg = _libssh2_list_first(&session->packets))) {
@@ -1032,9 +1045,14 @@ session_free(LIBSSH2_SESSION *session)
_libssh2_debug(session, LIBSSH2_TRACE_TRANS,
"Extra packets left %d", packets_left);
if(session->socket_prev_blockstate)
if(session->socket_prev_blockstate) {
/* if the socket was previously blocking, put it back so */
session_nonblock(session->socket_fd, 0);
rc = session_nonblock(session->socket_fd, 0);
if (rc) {
_libssh2_debug(session, LIBSSH2_TRACE_TRANS,
"unable to reset socket's blocking state");
}
}
if (session->server_hostkey) {
LIBSSH2_FREE(session, session->server_hostkey);
@@ -1514,7 +1532,7 @@ libssh2_poll(LIBSSH2_POLLFD * fds, unsigned int nfds, long timeout)
}
#else
/* No select() or poll()
* no sockets sturcture to setup
* no sockets structure to setup
*/
timeout = 0;

View File

@@ -1,6 +1,6 @@
/* Copyright (c) 2004-2008, Sara Golemon <sarag@libssh2.org>
* Copyright (c) 2007 Eli Fant <elifantu@mail.ru>
* Copyright (c) 2009-2012 by Daniel Stenberg
* Copyright (c) 2009-2014 by Daniel Stenberg
* All rights reserved.
*
* Redistribution and use in source and binary forms,
@@ -93,7 +93,6 @@
some kind of server problem. */
#define LIBSSH2_SFTP_PACKET_MAXLEN 80000
static int sftp_close_handle(LIBSSH2_SFTP_HANDLE *handle);
static int sftp_packet_ask(LIBSSH2_SFTP *sftp, unsigned char packet_type,
uint32_t request_id, unsigned char **data,
size_t *data_len);
@@ -132,6 +131,66 @@ static void _libssh2_store_u64(unsigned char **ptr, libssh2_uint64_t value)
*ptr += 8;
}
/*
* Search list of zombied FXP_READ request IDs.
*
* Returns NULL if ID not in list.
*/
static struct sftp_zombie_requests *
find_zombie_request(LIBSSH2_SFTP *sftp, uint32_t request_id)
{
struct sftp_zombie_requests *zombie =
_libssh2_list_first(&sftp->zombie_requests);
while(zombie) {
if(zombie->request_id == request_id)
break;
else
zombie = _libssh2_list_next(&zombie->node);
}
return zombie;
}
static void
remove_zombie_request(LIBSSH2_SFTP *sftp, uint32_t request_id)
{
LIBSSH2_SESSION *session = sftp->channel->session;
struct sftp_zombie_requests *zombie = find_zombie_request(sftp,
request_id);
if(zombie) {
_libssh2_debug(session, LIBSSH2_TRACE_SFTP,
"Removing request ID %ld from the list of zombie requests",
request_id);
_libssh2_list_remove(&zombie->node);
LIBSSH2_FREE(session, zombie);
}
}
static int
add_zombie_request(LIBSSH2_SFTP *sftp, uint32_t request_id)
{
LIBSSH2_SESSION *session = sftp->channel->session;
struct sftp_zombie_requests *zombie;
_libssh2_debug(session, LIBSSH2_TRACE_SFTP,
"Marking request ID %ld as a zombie request", request_id);
zombie = LIBSSH2_ALLOC(sftp->channel->session,
sizeof(struct sftp_zombie_requests));
if (!zombie)
return _libssh2_error(session, LIBSSH2_ERROR_ALLOC,
"malloc fail for zombie request ID");
else {
zombie->request_id = request_id;
_libssh2_list_add(&sftp->zombie_requests, &zombie->node);
return LIBSSH2_ERROR_NONE;
}
}
/*
* sftp_packet_add
*
@@ -143,6 +202,7 @@ sftp_packet_add(LIBSSH2_SFTP *sftp, unsigned char *data,
{
LIBSSH2_SESSION *session = sftp->channel->session;
LIBSSH2_SFTP_PACKET *packet;
uint32_t request_id;
_libssh2_debug(session, LIBSSH2_TRACE_SFTP, "Received packet %d (len %d)",
(int) data[0], data_len);
@@ -188,6 +248,21 @@ sftp_packet_add(LIBSSH2_SFTP *sftp, unsigned char *data,
"Out of sync with the world");
}
request_id = _libssh2_ntohu32(&data[1]);
/* Don't add the packet if it answers a request we've given up on. */
if((data[0] == SSH_FXP_STATUS || data[0] == SSH_FXP_DATA)
&& find_zombie_request(sftp, request_id)) {
/* If we get here, the file ended before the response arrived. We
are no longer interested in the request so we discard it */
LIBSSH2_FREE(session, data);
remove_zombie_request(sftp, request_id);
return LIBSSH2_ERROR_NONE;
}
packet = LIBSSH2_ALLOC(session, sizeof(LIBSSH2_SFTP_PACKET));
if (!packet) {
return _libssh2_error(session, LIBSSH2_ERROR_ALLOC,
@@ -196,7 +271,7 @@ sftp_packet_add(LIBSSH2_SFTP *sftp, unsigned char *data,
packet->data = data;
packet->data_len = data_len;
packet->request_id = _libssh2_ntohu32(&data[1]);
packet->request_id = request_id;
_libssh2_list_add(&sftp->packets, &packet->node);
@@ -216,6 +291,7 @@ sftp_packet_read(LIBSSH2_SFTP *sftp)
unsigned char *packet = NULL;
ssize_t rc;
unsigned long recv_window;
int packet_type;
_libssh2_debug(session, LIBSSH2_TRACE_SFTP, "recv packet");
@@ -324,13 +400,17 @@ sftp_packet_read(LIBSSH2_SFTP *sftp)
sftp->partial_packet = NULL;
/* sftp_packet_add takes ownership of the packet and might free it
so we take a copy of the packet type before we call it. */
packet_type = packet[0];
rc = sftp_packet_add(sftp, packet, sftp->partial_len);
if (rc) {
LIBSSH2_FREE(session, packet);
return rc;
}
return packet[0];
else {
return packet_type;
}
}
/* WON'T REACH */
}
@@ -363,6 +443,10 @@ static void sftp_packetlist_flush(LIBSSH2_SFTP_HANDLE *handle)
if(!rc)
/* we found a packet, free it */
LIBSSH2_FREE(session, data);
else if(chunk->sent)
/* there was no incoming packet for this request, mark this
request as a zombie if it ever sent the request */
add_zombie_request(sftp, chunk->request_id);
_libssh2_list_remove(&chunk->node);
LIBSSH2_FREE(session, chunk);
@@ -433,10 +517,7 @@ sftp_packet_require(LIBSSH2_SFTP *sftp, unsigned char packet_type,
while (session->socket_state == LIBSSH2_SOCKET_CONNECTED) {
rc = sftp_packet_read(sftp);
if (rc == LIBSSH2_ERROR_EAGAIN)
return rc;
else if (rc <= 0)
/* TODO: isn't this supposed to be < 0 only? */
if (rc < 0)
return rc;
/* data was read, check the queue again */
@@ -453,7 +534,7 @@ sftp_packet_require(LIBSSH2_SFTP *sftp, unsigned char packet_type,
}
/* sftp_packet_requirev
* Require one of N possible reponses
* Require one of N possible responses
*/
static int
sftp_packet_requirev(LIBSSH2_SFTP *sftp, int num_valid_responses,
@@ -639,7 +720,7 @@ static LIBSSH2_SFTP *sftp_init(LIBSSH2_SESSION *session)
*
* Note that you MUST NOT try to call libssh2_sftp_init() again to get
* another handle until the previous call has finished and either
* succesffully made a handle or failed and returned error (not
* successfully made a handle or failed and returned error (not
* including *EAGAIN).
*/
@@ -700,13 +781,12 @@ static LIBSSH2_SFTP *sftp_init(LIBSSH2_SESSION *session)
sftp_handle =
session->sftpInit_sftp =
LIBSSH2_ALLOC(session, sizeof(LIBSSH2_SFTP));
LIBSSH2_CALLOC(session, sizeof(LIBSSH2_SFTP));
if (!sftp_handle) {
_libssh2_error(session, LIBSSH2_ERROR_ALLOC,
"Unable to allocate a new SFTP structure");
goto sftp_init_error;
}
memset(sftp_handle, 0, sizeof(LIBSSH2_SFTP));
sftp_handle->channel = session->sftpInit_channel;
sftp_handle->request_id = 0;
@@ -762,6 +842,7 @@ static LIBSSH2_SFTP *sftp_init(LIBSSH2_SESSION *session)
if (data_len < 5) {
_libssh2_error(session, LIBSSH2_ERROR_SFTP_PROTOCOL,
"Invalid SSH_FXP_VERSION response");
LIBSSH2_FREE(session, data);
goto sftp_init_error;
}
@@ -775,7 +856,7 @@ static LIBSSH2_SFTP *sftp_init(LIBSSH2_SESSION *session)
sftp_handle->version = LIBSSH2_SFTP_VERSION;
}
_libssh2_debug(session, LIBSSH2_TRACE_SFTP,
"Enabling SFTP version %lu compatability",
"Enabling SFTP version %lu compatibility",
sftp_handle->version);
while (s < (data + data_len)) {
size_t extname_len, extdata_len;
@@ -846,7 +927,7 @@ LIBSSH2_API LIBSSH2_SFTP *libssh2_sftp_init(LIBSSH2_SESSION *session)
/*
* sftp_shutdown
*
* Shutsdown the SFTP subsystem
* Shuts down the SFTP subsystem
*/
static int
sftp_shutdown(LIBSSH2_SFTP *sftp)
@@ -904,6 +985,10 @@ sftp_shutdown(LIBSSH2_SFTP *sftp)
LIBSSH2_FREE(session, sftp->symlink_packet);
sftp->symlink_packet = NULL;
}
if (sftp->fsync_packet) {
LIBSSH2_FREE(session, sftp->fsync_packet);
sftp->fsync_packet = NULL;
}
sftp_packet_flush(sftp);
@@ -1087,14 +1172,13 @@ sftp_open(LIBSSH2_SFTP *sftp, const char *filename,
return NULL;
}
fp = LIBSSH2_ALLOC(session, sizeof(LIBSSH2_SFTP_HANDLE));
fp = LIBSSH2_CALLOC(session, sizeof(LIBSSH2_SFTP_HANDLE));
if (!fp) {
_libssh2_error(session, LIBSSH2_ERROR_ALLOC,
"Unable to allocate new SFTP handle structure");
LIBSSH2_FREE(session, data);
return NULL;
}
memset(fp, 0, sizeof(LIBSSH2_SFTP_HANDLE));
fp->handle_type = open_file ? LIBSSH2_SFTP_HANDLE_FILE :
LIBSSH2_SFTP_HANDLE_DIR;
@@ -1377,6 +1461,11 @@ static ssize_t sftp_read(LIBSSH2_SFTP_HANDLE * handle, char *buffer,
switch (data[0]) {
case SSH_FXP_STATUS:
/* remove the chunk we just processed */
_libssh2_list_remove(&chunk->node);
LIBSSH2_FREE(session, chunk);
/* we must remove all outstanding READ requests, as either we
got an error or we're at end of file */
sftp_packetlist_flush(handle);
@@ -1401,6 +1490,14 @@ static ssize_t sftp_read(LIBSSH2_SFTP_HANDLE * handle, char *buffer,
return _libssh2_error(session, LIBSSH2_ERROR_SFTP_PROTOCOL,
"SFTP Protocol badness");
if(rc32 > chunk->len) {
/* A chunk larger than we requested was returned to us.
This is a protocol violation and we don't know how to
deal with it. Bail out! */
return _libssh2_error(session, LIBSSH2_ERROR_SFTP_PROTOCOL,
"FXP_READ response too big");
}
if(rc32 != chunk->len) {
/* a short read does not imply end of file, but we must
adjust the offset_sent since it was advanced with a
@@ -1521,7 +1618,7 @@ static ssize_t sftp_readdir(LIBSSH2_SFTP_HANDLE *handle, char *buffer,
filename_len = real_filename_len;
if (filename_len >= buffer_maxlen) {
filename_len = LIBSSH2_ERROR_BUFFER_TOO_SMALL;
filename_len = (size_t)LIBSSH2_ERROR_BUFFER_TOO_SMALL;
goto end;
}
@@ -1536,7 +1633,7 @@ static ssize_t sftp_readdir(LIBSSH2_SFTP_HANDLE *handle, char *buffer,
longentry_len = real_longentry_len;
if (longentry_len >= longentry_maxlen) {
filename_len = LIBSSH2_ERROR_BUFFER_TOO_SMALL;
filename_len = (size_t)LIBSSH2_ERROR_BUFFER_TOO_SMALL;
goto end;
}
@@ -1860,7 +1957,7 @@ static ssize_t sftp_write(LIBSSH2_SFTP_HANDLE *handle, const char *buffer,
/* flush all pending packets from the outgoing list */
sftp_packetlist_flush(handle);
/* since we return error now, the applicaton will not get any
/* since we return error now, the application will not get any
outstanding data acked, so we need to rewind the offset to
where the application knows it has reached with acked data */
handle->u.file.offset -= handle->u.file.acked;
@@ -1919,6 +2016,99 @@ libssh2_sftp_write(LIBSSH2_SFTP_HANDLE *hnd, const char *buffer,
}
static int sftp_fsync(LIBSSH2_SFTP_HANDLE *handle)
{
LIBSSH2_SFTP *sftp = handle->sftp;
LIBSSH2_CHANNEL *channel = sftp->channel;
LIBSSH2_SESSION *session = channel->session;
/* 34 = packet_len(4) + packet_type(1) + request_id(4) +
string_len(4) + strlen("fsync@openssh.com")(17) + handle_len(4) */
uint32_t packet_len = handle->handle_len + 34;
size_t data_len;
unsigned char *packet, *s, *data;
ssize_t rc;
uint32_t retcode;
if (sftp->fsync_state == libssh2_NB_state_idle) {
_libssh2_debug(session, LIBSSH2_TRACE_SFTP,
"Issuing fsync command");
s = packet = LIBSSH2_ALLOC(session, packet_len);
if (!packet) {
return _libssh2_error(session, LIBSSH2_ERROR_ALLOC,
"Unable to allocate memory for FXP_EXTENDED "
"packet");
}
_libssh2_store_u32(&s, packet_len - 4);
*(s++) = SSH_FXP_EXTENDED;
sftp->fsync_request_id = sftp->request_id++;
_libssh2_store_u32(&s, sftp->fsync_request_id);
_libssh2_store_str(&s, "fsync@openssh.com", 17);
_libssh2_store_str(&s, handle->handle, handle->handle_len);
sftp->fsync_state = libssh2_NB_state_created;
} else {
packet = sftp->fsync_packet;
}
if (sftp->fsync_state == libssh2_NB_state_created) {
rc = _libssh2_channel_write(channel, 0, packet, packet_len);
if (rc == LIBSSH2_ERROR_EAGAIN ||
(0 <= rc && rc < (ssize_t)packet_len)) {
sftp->fsync_packet = packet;
return LIBSSH2_ERROR_EAGAIN;
}
LIBSSH2_FREE(session, packet);
sftp->fsync_packet = NULL;
if (rc < 0) {
sftp->fsync_state = libssh2_NB_state_idle;
return _libssh2_error(session, LIBSSH2_ERROR_SOCKET_SEND,
"_libssh2_channel_write() failed");
}
sftp->fsync_state = libssh2_NB_state_sent;
}
rc = sftp_packet_require(sftp, SSH_FXP_STATUS,
sftp->fsync_request_id, &data, &data_len);
if (rc == LIBSSH2_ERROR_EAGAIN) {
return rc;
} else if (rc) {
sftp->fsync_state = libssh2_NB_state_idle;
return _libssh2_error(session, rc,
"Error waiting for FXP EXTENDED REPLY");
}
sftp->fsync_state = libssh2_NB_state_idle;
retcode = _libssh2_ntohu32(data + 5);
LIBSSH2_FREE(session, data);
if (retcode != LIBSSH2_FX_OK) {
sftp->last_errno = retcode;
return _libssh2_error(session, LIBSSH2_ERROR_SFTP_PROTOCOL,
"fsync failed");
}
return 0;
}
/* libssh2_sftp_fsync
* Commit data on the handle to disk.
*/
LIBSSH2_API int
libssh2_sftp_fsync(LIBSSH2_SFTP_HANDLE *hnd)
{
int rc;
if(!hnd)
return LIBSSH2_ERROR_BAD_USE;
BLOCK_ADJUST(rc, hnd->sftp->channel->session,
sftp_fsync(hnd));
return rc;
}
/*
* sftp_fstat
*
@@ -2037,21 +2227,24 @@ libssh2_sftp_fstat_ex(LIBSSH2_SFTP_HANDLE *hnd,
LIBSSH2_API void
libssh2_sftp_seek64(LIBSSH2_SFTP_HANDLE *handle, libssh2_uint64_t offset)
{
if(handle) {
handle->u.file.offset = handle->u.file.offset_sent = offset;
/* discard all pending requests and currently read data */
sftp_packetlist_flush(handle);
if(!handle)
return;
if(handle->u.file.offset == offset && handle->u.file.offset_sent == offset)
return;
/* free the left received buffered data */
if (handle->u.file.data_left) {
LIBSSH2_FREE(handle->sftp->channel->session, handle->u.file.data);
handle->u.file.data_left = handle->u.file.data_len = 0;
handle->u.file.data = NULL;
}
handle->u.file.offset = handle->u.file.offset_sent = offset;
/* discard all pending requests and currently read data */
sftp_packetlist_flush(handle);
/* reset EOF to False */
handle->u.file.eof = FALSE;
/* free the left received buffered data */
if (handle->u.file.data_left) {
LIBSSH2_FREE(handle->sftp->channel->session, handle->u.file.data);
handle->u.file.data_left = handle->u.file.data_len = 0;
handle->u.file.data = NULL;
}
/* reset EOF to False */
handle->u.file.eof = FALSE;
}
/* libssh2_sftp_seek
@@ -2091,13 +2284,15 @@ libssh2_sftp_tell64(LIBSSH2_SFTP_HANDLE *handle)
}
/*
* Flush all remaining incoming SFTP packets.
* Flush all remaining incoming SFTP packets and zombies.
*/
static void sftp_packet_flush(LIBSSH2_SFTP *sftp)
{
LIBSSH2_CHANNEL *channel = sftp->channel;
LIBSSH2_SESSION *session = channel->session;
LIBSSH2_SFTP_PACKET *packet = _libssh2_list_first(&sftp->packets);
struct sftp_zombie_requests *zombie =
_libssh2_list_first(&sftp->zombie_requests);
while(packet) {
LIBSSH2_SFTP_PACKET *next;
@@ -2111,12 +2306,25 @@ static void sftp_packet_flush(LIBSSH2_SFTP *sftp)
packet = next;
}
while(zombie) {
/* figure out the next node */
struct sftp_zombie_requests *next = _libssh2_list_next(&zombie->node);
/* unlink the current one */
_libssh2_list_remove(&zombie->node);
/* free the memory */
LIBSSH2_FREE(session, zombie);
zombie = next;
}
}
/* sftp_close_handle
*
* Close a file or directory handle
* Also frees handle resource and unlinks it from the SFTP structure
* Close a file or directory handle.
* Also frees handle resource and unlinks it from the SFTP structure.
* The handle is no longer usable after return of this function, unless
* the return value is LIBSSH2_ERROR_EAGAIN in which case this function
* should be called again.
*/
static int
sftp_close_handle(LIBSSH2_SFTP_HANDLE *handle)
@@ -2125,27 +2333,28 @@ sftp_close_handle(LIBSSH2_SFTP_HANDLE *handle)
LIBSSH2_CHANNEL *channel = sftp->channel;
LIBSSH2_SESSION *session = channel->session;
size_t data_len;
int retcode;
/* 13 = packet_len(4) + packet_type(1) + request_id(4) + handle_len(4) */
uint32_t packet_len = handle->handle_len + 13;
unsigned char *s, *data = NULL;
int rc;
int rc = 0;
if (handle->close_state == libssh2_NB_state_idle) {
_libssh2_debug(session, LIBSSH2_TRACE_SFTP, "Closing handle");
s = handle->close_packet = LIBSSH2_ALLOC(session, packet_len);
if (!handle->close_packet) {
return _libssh2_error(session, LIBSSH2_ERROR_ALLOC,
"Unable to allocate memory for FXP_CLOSE "
"packet");
}
handle->close_state = libssh2_NB_state_idle;
rc = _libssh2_error(session, LIBSSH2_ERROR_ALLOC,
"Unable to allocate memory for FXP_CLOSE "
"packet");
} else {
_libssh2_store_u32(&s, packet_len - 4);
*(s++) = SSH_FXP_CLOSE;
handle->close_request_id = sftp->request_id++;
_libssh2_store_u32(&s, handle->close_request_id);
_libssh2_store_str(&s, handle->handle, handle->handle_len);
handle->close_state = libssh2_NB_state_created;
_libssh2_store_u32(&s, packet_len - 4);
*(s++) = SSH_FXP_CLOSE;
handle->close_request_id = sftp->request_id++;
_libssh2_store_u32(&s, handle->close_request_id);
_libssh2_store_str(&s, handle->handle, handle->handle_len);
handle->close_state = libssh2_NB_state_created;
}
}
if (handle->close_state == libssh2_NB_state_created) {
@@ -2154,16 +2363,14 @@ sftp_close_handle(LIBSSH2_SFTP_HANDLE *handle)
if (rc == LIBSSH2_ERROR_EAGAIN) {
return rc;
} else if ((ssize_t)packet_len != rc) {
LIBSSH2_FREE(session, handle->close_packet);
handle->close_packet = NULL;
handle->close_state = libssh2_NB_state_idle;
return _libssh2_error(session, LIBSSH2_ERROR_SOCKET_SEND,
"Unable to send FXP_CLOSE command");
}
rc = _libssh2_error(session, LIBSSH2_ERROR_SOCKET_SEND,
"Unable to send FXP_CLOSE command");
} else
handle->close_state = libssh2_NB_state_sent;
LIBSSH2_FREE(session, handle->close_packet);
handle->close_packet = NULL;
handle->close_state = libssh2_NB_state_sent;
}
if (handle->close_state == libssh2_NB_state_sent) {
@@ -2172,29 +2379,30 @@ sftp_close_handle(LIBSSH2_SFTP_HANDLE *handle)
&data_len);
if (rc == LIBSSH2_ERROR_EAGAIN) {
return rc;
} else if (rc) {
handle->close_state = libssh2_NB_state_idle;
return _libssh2_error(session, rc,
"Error waiting for status message");
_libssh2_error(session, rc,
"Error waiting for status message");
}
handle->close_state = libssh2_NB_state_sent1;
}
if(!data)
if(!data) {
/* if it reaches this point with data unset, something unwanted
happened (like this function is called again when in
libssh2_NB_state_sent1 state) and we just bail out */
return LIBSSH2_ERROR_INVAL;
happened for which we should have set an error code */
assert(rc);
retcode = _libssh2_ntohu32(data + 5);
LIBSSH2_FREE(session, data);
} else {
int retcode = _libssh2_ntohu32(data + 5);
LIBSSH2_FREE(session, data);
if (retcode != LIBSSH2_FX_OK) {
sftp->last_errno = retcode;
handle->close_state = libssh2_NB_state_idle;
return _libssh2_error(session, LIBSSH2_ERROR_SFTP_PROTOCOL,
"SFTP Protocol Error");
if (retcode != LIBSSH2_FX_OK) {
sftp->last_errno = retcode;
handle->close_state = libssh2_NB_state_idle;
rc = _libssh2_error(session, LIBSSH2_ERROR_SFTP_PROTOCOL,
"SFTP Protocol Error");
}
}
/* remove this handle from the parent's list */
@@ -2216,7 +2424,7 @@ sftp_close_handle(LIBSSH2_SFTP_HANDLE *handle)
LIBSSH2_FREE(session, handle);
return 0;
return rc;
}
/* libssh2_sftp_close_handle
@@ -2476,6 +2684,8 @@ static int sftp_fstatvfs(LIBSSH2_SFTP_HANDLE *handle, LIBSSH2_SFTP_STATVFS *st)
unsigned char *packet, *s, *data;
ssize_t rc;
unsigned int flag;
static const unsigned char responses[2] =
{ SSH_FXP_EXTENDED_REPLY, SSH_FXP_STATUS };
if (sftp->fstatvfs_state == libssh2_NB_state_idle) {
_libssh2_debug(session, LIBSSH2_TRACE_SFTP,
@@ -2519,15 +2729,27 @@ static int sftp_fstatvfs(LIBSSH2_SFTP_HANDLE *handle, LIBSSH2_SFTP_STATVFS *st)
sftp->fstatvfs_state = libssh2_NB_state_sent;
}
rc = sftp_packet_require(sftp, SSH_FXP_EXTENDED_REPLY,
sftp->fstatvfs_request_id, &data, &data_len);
rc = sftp_packet_requirev(sftp, 2, responses, sftp->fstatvfs_request_id,
&data, &data_len);
if (rc == LIBSSH2_ERROR_EAGAIN) {
return rc;
} else if (rc) {
sftp->fstatvfs_state = libssh2_NB_state_idle;
return _libssh2_error(session, rc,
"Error waiting for FXP EXTENDED REPLY");
} else if (data_len < 93) {
}
if (data[0] == SSH_FXP_STATUS) {
int retcode = _libssh2_ntohu32(data + 5);
sftp->fstatvfs_state = libssh2_NB_state_idle;
LIBSSH2_FREE(session, data);
sftp->last_errno = retcode;
return _libssh2_error(session, LIBSSH2_ERROR_SFTP_PROTOCOL,
"SFTP Protocol Error");
}
if (data_len < 93) {
LIBSSH2_FREE(session, data);
sftp->fstatvfs_state = libssh2_NB_state_idle;
return _libssh2_error(session, LIBSSH2_ERROR_SFTP_PROTOCOL,
@@ -2549,9 +2771,9 @@ static int sftp_fstatvfs(LIBSSH2_SFTP_HANDLE *handle, LIBSSH2_SFTP_STATVFS *st)
st->f_namemax = _libssh2_ntohu64(data + 85);
st->f_flag = (flag & SSH_FXE_STATVFS_ST_RDONLY)
? LIBSSH2_SFTP_ST_RDONLY : 0;
? LIBSSH2_SFTP_ST_RDONLY : 0;
st->f_flag |= (flag & SSH_FXE_STATVFS_ST_NOSUID)
? LIBSSH2_SFTP_ST_NOSUID : 0;
? LIBSSH2_SFTP_ST_NOSUID : 0;
LIBSSH2_FREE(session, data);
return 0;
@@ -2589,6 +2811,8 @@ static int sftp_statvfs(LIBSSH2_SFTP *sftp, const char *path,
unsigned char *packet, *s, *data;
ssize_t rc;
unsigned int flag;
static const unsigned char responses[2] =
{ SSH_FXP_EXTENDED_REPLY, SSH_FXP_STATUS };
if (sftp->statvfs_state == libssh2_NB_state_idle) {
_libssh2_debug(session, LIBSSH2_TRACE_SFTP,
@@ -2632,17 +2856,28 @@ static int sftp_statvfs(LIBSSH2_SFTP *sftp, const char *path,
sftp->statvfs_state = libssh2_NB_state_sent;
}
rc = sftp_packet_require(sftp, SSH_FXP_EXTENDED_REPLY,
sftp->statvfs_request_id, &data, &data_len);
rc = sftp_packet_requirev(sftp, 2, responses, sftp->statvfs_request_id,
&data, &data_len);
if (rc == LIBSSH2_ERROR_EAGAIN) {
return rc;
} else if (rc) {
sftp->statvfs_state = libssh2_NB_state_idle;
return _libssh2_error(session, rc,
"Error waiting for FXP EXTENDED REPLY");
} else if (data_len < 93) {
}
if (data[0] == SSH_FXP_STATUS) {
int retcode = _libssh2_ntohu32(data + 5);
sftp->statvfs_state = libssh2_NB_state_idle;
LIBSSH2_FREE(session, data);
sftp->fstatvfs_state = libssh2_NB_state_idle;
sftp->last_errno = retcode;
return _libssh2_error(session, LIBSSH2_ERROR_SFTP_PROTOCOL,
"SFTP Protocol Error");
}
if (data_len < 93) {
LIBSSH2_FREE(session, data);
sftp->statvfs_state = libssh2_NB_state_idle;
return _libssh2_error(session, LIBSSH2_ERROR_SFTP_PROTOCOL,
"SFTP Protocol Error: short response");
}

View File

@@ -60,6 +60,11 @@ struct sftp_pipeline_chunk {
unsigned char packet[1]; /* data */
};
struct sftp_zombie_requests {
struct list_node node;
uint32_t request_id;
};
#ifndef MIN
#define MIN(x,y) ((x)<(y)?(x):(y))
#endif
@@ -136,6 +141,9 @@ struct _LIBSSH2_SFTP
struct list_head packets;
/* List of FXP_READ responses to ignore because EOF already received. */
struct list_head zombie_requests;
/* a list of _LIBSSH2_SFTP_HANDLE structs */
struct list_head sftp_handles;
@@ -167,6 +175,11 @@ struct _LIBSSH2_SFTP
/* State variable used in sftp_write() */
libssh2_nonblocking_states write_state;
/* State variables used in sftp_fsync() */
libssh2_nonblocking_states fsync_state;
unsigned char *fsync_packet;
uint32_t fsync_request_id;
/* State variables used in libssh2_sftp_readdir() */
libssh2_nonblocking_states readdir_state;
unsigned char *readdir_packet;

View File

@@ -139,7 +139,7 @@ decrypt(LIBSSH2_SESSION * session, unsigned char *source,
assert((len % blocksize) == 0);
while (len >= blocksize) {
if (session->remote.crypt->crypt(session, source,
if (session->remote.crypt->crypt(session, source, blocksize,
&session->remote.crypt_abstract)) {
LIBSSH2_FREE(session, p->payload);
return LIBSSH2_ERROR_DECRYPT;
@@ -167,6 +167,7 @@ fullpacket(LIBSSH2_SESSION * session, int encrypted /* 1 or 0 */ )
unsigned char macbuf[MAX_MACSIZE];
struct transportpacket *p = &session->packet;
int rc;
int compressed;
if (session->fullpacket_state == libssh2_NB_state_idle) {
session->fullpacket_macstate = LIBSSH2_MAC_CONFIRMED;
@@ -199,9 +200,13 @@ fullpacket(LIBSSH2_SESSION * session, int encrypted /* 1 or 0 */ )
session->fullpacket_payload_len -= p->padding_length;
/* Check for and deal with decompression */
if (session->remote.comp &&
session->remote.comp->compress &&
session->remote.comp_abstract) {
compressed =
session->local.comp != NULL &&
session->local.comp->compress &&
((session->state & LIBSSH2_STATE_AUTHENTICATED) ||
session->local.comp->use_in_auth);
if (compressed && session->remote.comp_abstract) {
/*
* The buffer for the decompression (remote.comp_abstract) is
* initialised in time when it is needed so as long it is NULL we
@@ -236,8 +241,12 @@ fullpacket(LIBSSH2_SESSION * session, int encrypted /* 1 or 0 */ )
rc = _libssh2_packet_add(session, p->payload,
session->fullpacket_payload_len,
session->fullpacket_macstate);
if (rc)
if (rc == LIBSSH2_ERROR_EAGAIN)
return rc;
if (rc) {
session->fullpacket_state = libssh2_NB_state_idle;
return rc;
}
}
session->fullpacket_state = libssh2_NB_state_idle;
@@ -519,6 +528,7 @@ int _libssh2_transport_read(LIBSSH2_SESSION * session)
/* now decrypt the lot */
rc = decrypt(session, &p->buf[p->readidx], p->wptr, numdecrypt);
if (rc != LIBSSH2_ERROR_NONE) {
p->total_num = 0; /* no packet buffer available */
return rc;
}
@@ -526,7 +536,7 @@ int _libssh2_transport_read(LIBSSH2_SESSION * session)
p->readidx += numdecrypt;
/* advance write pointer */
p->wptr += numdecrypt;
/* increse data_num */
/* increase data_num */
p->data_num += numdecrypt;
/* bytes left to take care of without decryption */
@@ -542,7 +552,7 @@ int _libssh2_transport_read(LIBSSH2_SESSION * session)
p->readidx += numbytes;
/* advance write pointer */
p->wptr += numbytes;
/* increse data_num */
/* increase data_num */
p->data_num += numbytes;
}
@@ -682,6 +692,7 @@ int _libssh2_transport_send(LIBSSH2_SESSION *session,
#endif
struct transportpacket *p = &session->packet;
int encrypted;
int compressed;
ssize_t ret;
int rc;
const unsigned char *orgdata = data;
@@ -723,7 +734,13 @@ int _libssh2_transport_send(LIBSSH2_SESSION *session,
encrypted = (session->state & LIBSSH2_STATE_NEWKEYS) ? 1 : 0;
if (encrypted && session->local.comp->compress) {
compressed =
session->local.comp != NULL &&
session->local.comp->compress &&
((session->state & LIBSSH2_STATE_AUTHENTICATED) ||
session->local.comp->use_in_auth);
if (encrypted && compressed) {
/* the idea here is that these function must fail if the output gets
larger than what fits in the assigned buffer so thus they don't
check the input size as we don't know how much it compresses */
@@ -812,7 +829,7 @@ int _libssh2_transport_send(LIBSSH2_SESSION *session,
the MAC and the packet_length field itself */
_libssh2_htonu32(p->outbuf, packet_length - 4);
/* store padding_length */
p->outbuf[4] = padding_length;
p->outbuf[4] = (unsigned char)padding_length;
/* fill the padding area with random junk */
_libssh2_random(p->outbuf + 5 + data_len, padding_length);
@@ -834,6 +851,7 @@ int _libssh2_transport_send(LIBSSH2_SESSION *session,
for(i = 0; i < packet_length; i += session->local.crypt->blocksize) {
unsigned char *ptr = &p->outbuf[i];
if (session->local.crypt->crypt(session, ptr,
session->local.crypt->blocksize,
&session->local.crypt_abstract))
return LIBSSH2_ERROR_ENCRYPT; /* encryption failure */
}

View File

@@ -1,6 +1,6 @@
/* Copyright (c) 2004-2007, Sara Golemon <sarag@libssh2.org>
* Copyright (c) 2005 Mikhail Gusarov <dottedmag@dottedmag.net>
* Copyright (c) 2009-2011 by Daniel Stenberg
* Copyright (c) 2009-2014 by Daniel Stenberg
* All rights reserved.
*
* Redistribution and use in source and binary forms,
@@ -211,12 +211,13 @@ userauth_password(LIBSSH2_SESSION *session,
sizeof(session->userauth_pswd_packet_requirev_state));
/*
* 40 = acket_type(1) + username_len(4) + service_len(4) +
* 40 = packet_type(1) + username_len(4) + service_len(4) +
* service(14)"ssh-connection" + method_len(4) + method(8)"password" +
* chgpwdbool(1) + password_len(4) */
session->userauth_pswd_data_len = username_len + 40;
session->userauth_pswd_data0 = ~SSH_MSG_USERAUTH_PASSWD_CHANGEREQ;
session->userauth_pswd_data0 =
(unsigned char) ~SSH_MSG_USERAUTH_PASSWD_CHANGEREQ;
/* TODO: remove this alloc with a fixed buffer in the session
struct */
@@ -276,13 +277,13 @@ userauth_password(LIBSSH2_SESSION *session,
0, NULL, 0,
&session->
userauth_pswd_packet_requirev_state);
if (rc == LIBSSH2_ERROR_EAGAIN) {
return _libssh2_error(session, LIBSSH2_ERROR_EAGAIN,
"Would block waiting");
} else if (rc) {
session->userauth_pswd_state = libssh2_NB_state_idle;
return _libssh2_error(session, LIBSSH2_ERROR_TIMEOUT,
"Would block waiting");
if (rc) {
if (rc != LIBSSH2_ERROR_EAGAIN)
session->userauth_pswd_state = libssh2_NB_state_idle;
return _libssh2_error(session, rc,
"Waiting for password response");
}
if (session->userauth_pswd_data[0] == SSH_MSG_USERAUTH_SUCCESS) {
@@ -461,7 +462,7 @@ file_read_publickey(LIBSSH2_SESSION * session, unsigned char **method,
FILE *fd;
char c;
unsigned char *pubkey = NULL, *sp1, *sp2, *tmp;
size_t pubkey_len = 0;
size_t pubkey_len = 0, sp_len;
unsigned int tmp_len;
_libssh2_debug(session, LIBSSH2_TRACE_AUTH, "Loading public key file: %s",
@@ -472,8 +473,9 @@ file_read_publickey(LIBSSH2_SESSION * session, unsigned char **method,
return _libssh2_error(session, LIBSSH2_ERROR_FILE,
"Unable to open public key file");
}
while (!feof(fd) && (c = fgetc(fd)) != '\r' && c != '\n')
while (!feof(fd) && 1 == fread(&c, 1, 1, fd) && c != '\r' && c != '\n') {
pubkey_len++;
}
if (feof(fd)) {
/* the last character was EOF */
pubkey_len--;
@@ -502,8 +504,9 @@ file_read_publickey(LIBSSH2_SESSION * session, unsigned char **method,
/*
* Remove trailing whitespace
*/
while (pubkey_len && isspace(pubkey[pubkey_len - 1]))
while (pubkey_len && isspace(pubkey[pubkey_len - 1])) {
pubkey_len--;
}
if (!pubkey_len) {
LIBSSH2_FREE(session, pubkey);
@@ -519,7 +522,8 @@ file_read_publickey(LIBSSH2_SESSION * session, unsigned char **method,
sp1++;
if ((sp2 = memchr(sp1, ' ', pubkey_len - (sp1 - pubkey - 1))) == NULL) {
sp_len = sp1 > pubkey ? (sp1 - pubkey) - 1 : 0;
if ((sp2 = memchr(sp1, ' ', pubkey_len - sp_len)) == NULL) {
/* Assume that the id string is missing, but that it's okay */
sp2 = pubkey + pubkey_len;
}
@@ -615,7 +619,7 @@ sign_fromfile(LIBSSH2_SESSION *session, unsigned char **sig, size_t *sig_len,
if (privkeyobj->signv(session, sig, sig_len, 1, &datavec,
&hostkey_abstract)) {
if (privkeyobj->dtor) {
privkeyobj->dtor(session, abstract);
privkeyobj->dtor(session, &hostkey_abstract);
}
return -1;
}
@@ -645,7 +649,7 @@ userauth_hostbased_fromfile(LIBSSH2_SESSION *session,
if (session->userauth_host_state == libssh2_NB_state_idle) {
const LIBSSH2_HOSTKEY_METHOD *privkeyobj;
unsigned char *pubkeydata, *sig;
size_t pubkeydata_len;
size_t pubkeydata_len = 0;
size_t sig_len;
void *abstract;
unsigned char buf[5];
@@ -1501,49 +1505,41 @@ userauth_keyboard_interactive(LIBSSH2_SESSION * session,
if(session->userauth_kybd_num_prompts) {
session->userauth_kybd_prompts =
LIBSSH2_ALLOC(session,
sizeof(LIBSSH2_USERAUTH_KBDINT_PROMPT) *
session->userauth_kybd_num_prompts);
LIBSSH2_CALLOC(session,
sizeof(LIBSSH2_USERAUTH_KBDINT_PROMPT) *
session->userauth_kybd_num_prompts);
if (!session->userauth_kybd_prompts) {
_libssh2_error(session, LIBSSH2_ERROR_ALLOC,
"Unable to allocate memory for "
"keyboard-interactive prompts array");
goto cleanup;
}
memset(session->userauth_kybd_prompts, 0,
sizeof(LIBSSH2_USERAUTH_KBDINT_PROMPT) *
session->userauth_kybd_num_prompts);
session->userauth_kybd_responses =
LIBSSH2_ALLOC(session,
sizeof(LIBSSH2_USERAUTH_KBDINT_RESPONSE) *
session->userauth_kybd_num_prompts);
LIBSSH2_CALLOC(session,
sizeof(LIBSSH2_USERAUTH_KBDINT_RESPONSE) *
session->userauth_kybd_num_prompts);
if (!session->userauth_kybd_responses) {
_libssh2_error(session, LIBSSH2_ERROR_ALLOC,
"Unable to allocate memory for "
"keyboard-interactive responses array");
goto cleanup;
}
memset(session->userauth_kybd_responses, 0,
sizeof(LIBSSH2_USERAUTH_KBDINT_RESPONSE) *
session->userauth_kybd_num_prompts);
for(i = 0; i != session->userauth_kybd_num_prompts; ++i) {
for(i = 0; i < session->userauth_kybd_num_prompts; i++) {
/* string prompt[1] (ISO-10646 UTF-8) */
session->userauth_kybd_prompts[i].length =
_libssh2_ntohu32(s);
s += 4;
session->userauth_kybd_prompts[i].text =
LIBSSH2_ALLOC(session,
session->userauth_kybd_prompts[i].length);
LIBSSH2_CALLOC(session,
session->userauth_kybd_prompts[i].length);
if (!session->userauth_kybd_prompts[i].text) {
_libssh2_error(session, LIBSSH2_ERROR_ALLOC,
"Unable to allocate memory for "
"keyboard-interactive prompt message");
goto cleanup;
}
memcpy(session->userauth_kybd_prompts[i].text, s,
session->userauth_kybd_prompts[i].length);
s += session->userauth_kybd_prompts[i].length;
/* boolean echo[1] */
@@ -1569,7 +1565,7 @@ userauth_keyboard_interactive(LIBSSH2_SESSION * session,
+ 4 /* int num-responses */
;
for(i = 0; i != session->userauth_kybd_num_prompts; ++i) {
for(i = 0; i < session->userauth_kybd_num_prompts; i++) {
/* string response[1] (ISO-10646 UTF-8) */
session->userauth_kybd_packet_len +=
4 + session->userauth_kybd_responses[i].length;
@@ -1592,7 +1588,7 @@ userauth_keyboard_interactive(LIBSSH2_SESSION * session,
s++;
_libssh2_store_u32(&s, session->userauth_kybd_num_prompts);
for(i = 0; i != session->userauth_kybd_num_prompts; ++i) {
for(i = 0; i < session->userauth_kybd_num_prompts; i++) {
_libssh2_store_str(&s,
session->userauth_kybd_responses[i].text,
session->userauth_kybd_responses[i].length);
@@ -1628,14 +1624,14 @@ userauth_keyboard_interactive(LIBSSH2_SESSION * session,
session->userauth_kybd_data = NULL;
if (session->userauth_kybd_prompts) {
for(i = 0; i != session->userauth_kybd_num_prompts; ++i) {
for(i = 0; i < session->userauth_kybd_num_prompts; i++) {
LIBSSH2_FREE(session, session->userauth_kybd_prompts[i].text);
session->userauth_kybd_prompts[i].text = NULL;
}
}
if (session->userauth_kybd_responses) {
for(i = 0; i != session->userauth_kybd_num_prompts; ++i) {
for(i = 0; i < session->userauth_kybd_num_prompts; i++) {
LIBSSH2_FREE(session,
session->userauth_kybd_responses[i].text);
session->userauth_kybd_responses[i].text = NULL;

1827
src/wincng.c Normal file

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