Compare commits
105 Commits
RELEASE.0.
...
RELEASE.1.
Author | SHA1 | Date | |
---|---|---|---|
![]() |
27197bcff3 | ||
![]() |
64b3e5e3f6 | ||
![]() |
ba79d6b52d | ||
![]() |
6b38e21fa7 | ||
![]() |
11330ee6da | ||
![]() |
b3649e86a8 | ||
![]() |
2f32080772 | ||
![]() |
7aac082782 | ||
![]() |
5a35edcb9a | ||
![]() |
079d20aca8 | ||
![]() |
b357379923 | ||
![]() |
62769b438f | ||
![]() |
d602478e87 | ||
![]() |
8eba2961ac | ||
![]() |
962a41e4ec | ||
![]() |
31841e7c74 | ||
![]() |
70f844e57c | ||
![]() |
942a81c8d5 | ||
![]() |
e26956be72 | ||
![]() |
2535c5c2ee | ||
![]() |
197a26ef8c | ||
![]() |
f1dae83d5e | ||
![]() |
bcad67636b | ||
![]() |
fbb25c7ad0 | ||
![]() |
e47bedf17c | ||
![]() |
19f78244de | ||
![]() |
9d5ba0dee2 | ||
![]() |
0934c4b39d | ||
![]() |
cc3a7d8e83 | ||
![]() |
8f860e249e | ||
![]() |
160f89f42e | ||
![]() |
881b01e522 | ||
![]() |
74d33d50ba | ||
![]() |
fcaa810350 | ||
![]() |
1f015d72b1 | ||
![]() |
8c8ba3bc20 | ||
![]() |
9d433d4f80 | ||
![]() |
50a3255dde | ||
![]() |
482072939a | ||
![]() |
f2253aeee9 | ||
![]() |
2b5becfe85 | ||
![]() |
8b25820589 | ||
![]() |
fd0bffdb2e | ||
![]() |
86eaae7886 | ||
![]() |
8e8dc43b0c | ||
![]() |
e45bddb9fd | ||
![]() |
e5a36fb1cf | ||
![]() |
5438cffd9a | ||
![]() |
95b73812e7 | ||
![]() |
85b953d0dd | ||
![]() |
c3447ea29f | ||
![]() |
8896b675f8 | ||
![]() |
b2334b227d | ||
![]() |
88d0ef1f3f | ||
![]() |
006f233361 | ||
![]() |
fa620b2a7b | ||
![]() |
b228f132f7 | ||
![]() |
8c43bc52b1 | ||
![]() |
d26a330483 | ||
![]() |
b4b8c51b32 | ||
![]() |
818e9edfb1 | ||
![]() |
61fda23340 | ||
![]() |
93ae080bbc | ||
![]() |
bd3dfed7e8 | ||
![]() |
99afc66665 | ||
![]() |
903307113e | ||
![]() |
9b31ca67ac | ||
![]() |
3f0d30d1d6 | ||
![]() |
d4aa801f6f | ||
![]() |
f56daac7fe | ||
![]() |
a55e6c10c9 | ||
![]() |
2fcaa00e3a | ||
![]() |
0242a3b6af | ||
![]() |
b310cc3465 | ||
![]() |
092e5f4b44 | ||
![]() |
c1a83abff9 | ||
![]() |
f3c344da22 | ||
![]() |
4600d108ed | ||
![]() |
76e8e81402 | ||
![]() |
d27dd927cd | ||
![]() |
63d863241a | ||
![]() |
dbbd9eafc6 | ||
![]() |
c92465930d | ||
![]() |
34d5c9a4b1 | ||
![]() |
e8bb993437 | ||
![]() |
030b670e2a | ||
![]() |
371a795443 | ||
![]() |
2d773f9322 | ||
![]() |
80f6c7c6d1 | ||
![]() |
46f26d3d0e | ||
![]() |
5d91d286f1 | ||
![]() |
5a854cfb26 | ||
![]() |
e905b206ed | ||
![]() |
fe7a6f967d | ||
![]() |
5879a0245b | ||
![]() |
d90d8bdae7 | ||
![]() |
f216b36328 | ||
![]() |
c4630d1ffb | ||
![]() |
17173aab0e | ||
![]() |
f8d4de78e9 | ||
![]() |
e32ff531a3 | ||
![]() |
a227554c26 | ||
![]() |
9f27d176f8 | ||
![]() |
bcc4fd6e82 | ||
![]() |
210459db4b |
@@ -7,3 +7,5 @@ edink:Edink Kadribasic
|
||||
jehousley: James Housley
|
||||
gknauf: Guenter Knauf
|
||||
dfandrich: Dan Fandrich
|
||||
yangtse: Yang Tse
|
||||
thomaspu: Paul Thomas
|
||||
|
7
AUTHORS
7
AUTHORS
@@ -4,8 +4,13 @@
|
||||
|
||||
* Simon Josefsson: libgcrypt support
|
||||
|
||||
* Daniel Stenberg: Nonblocking fixes, Build Improvements, and Daily snapshot artist
|
||||
* Daniel Stenberg: Nonblocking fixes, Build Improvements, and Daily snapshot
|
||||
artist
|
||||
|
||||
* Mikhail Gusarov: Keyboard Interactive Authentication
|
||||
|
||||
* Wez Furlong & Edink Kadribasic: Windows Port
|
||||
|
||||
* Dan Fandrich: bug fixes, cleanups
|
||||
|
||||
* Guenter Knauf: win32 work and more
|
||||
|
30
Makefile.am
30
Makefile.am
@@ -11,7 +11,12 @@ NETWAREFILES = nw/keepscreen.c \
|
||||
nw/nwlib.c \
|
||||
nw/test/Makefile.netware
|
||||
|
||||
EXTRA_DIST = win32 buildconf $(NETWAREFILES) get_ver.awk HACKING maketgz NMakefile
|
||||
WIN32FILES = win32/libssh2_dll.dsp win32/libssh2.dsw win32/Makefile.win32 \
|
||||
win32/config.mk win32/Makefile win32/test/Makefile.win32 win32/libssh2_lib.dsp \
|
||||
win32/libssh2_config.h win32/tests.dsp win32/rules.mk
|
||||
|
||||
EXTRA_DIST = $(WIN32FILES) buildconf $(NETWAREFILES) get_ver.awk HACKING \
|
||||
maketgz NMakefile TODO
|
||||
|
||||
ACLOCAL_AMFLAGS = -I m4
|
||||
|
||||
@@ -29,3 +34,26 @@ dist-hook:
|
||||
strip=`echo $$file | sed -e s/^$(srcdir)// -e s/\.dist//`; \
|
||||
cp $$file $(distdir)$$strip; \
|
||||
done)
|
||||
|
||||
# Code Coverage
|
||||
|
||||
init-coverage:
|
||||
make clean
|
||||
lcov --directory . --zerocounters
|
||||
|
||||
COVERAGE_CCOPTS ?= "-g --coverage"
|
||||
COVERAGE_OUT ?= docs/coverage
|
||||
|
||||
build-coverage:
|
||||
make CFLAGS=$(COVERAGE_CCOPTS) check
|
||||
mkdir -p $(COVERAGE_OUT)
|
||||
lcov --directory . --output-file $(COVERAGE_OUT)/$(PACKAGE).info \
|
||||
--capture
|
||||
|
||||
gen-coverage:
|
||||
genhtml --output-directory $(COVERAGE_OUT) \
|
||||
$(COVERAGE_OUT)/$(PACKAGE).info \
|
||||
--highlight --frames --legend \
|
||||
--title "$(PACKAGE_NAME)"
|
||||
|
||||
coverage: init-coverage build-coverage gen-coverage
|
||||
|
174
NEWS
174
NEWS
@@ -1,5 +1,101 @@
|
||||
Version 0.16
|
||||
------------
|
||||
Version 1.0 ( )
|
||||
-------------------------------
|
||||
|
||||
- (Dec 20 2008) Based on Alexander Lamaison's patch, there's now a new
|
||||
function called libssh2_sftp_tell64() that returns the 64 bit file offset,
|
||||
as the existing libssh2_sftp_tell() only returns a size_t.
|
||||
|
||||
- (Dec 18 2008) Markus Moeller fixed the issue also reported by Alexander
|
||||
Lamaison which caused SFTP reads with large buffers to fail.
|
||||
|
||||
- Several flaws were fixed that prevented at least SFTP to work reliably
|
||||
|
||||
- Vlad Grachov brought the new function called
|
||||
libssh2_session_block_directions() which returns a bitmask for what
|
||||
directions the connection blocks. It is to be used applications that use
|
||||
non-blocking sockets and when a libssh2 function returns
|
||||
LIBSSH2_ERROR_EAGAIN this function can be used to figure out in which
|
||||
direction the socket would block and thus it can wait for the socket to
|
||||
again be ready for communication in that direction before it calls libssh2
|
||||
again.
|
||||
|
||||
- Vincent Jaulin brought the new libssh2_channel_request_pty_size_ex()
|
||||
function.
|
||||
|
||||
- Carlo Bramini fixed the build for msys+mingw. Bug #1943976.
|
||||
|
||||
- Neil Gierman provided improved Visual Studio 2008 code in bug #1946268
|
||||
|
||||
- Bug #1862727 fixed libssh2_poll() to work on windows (by defining
|
||||
HAVE_SELECT).
|
||||
|
||||
- Based on bug #1815692, we introduce libssh2_sftp_seek64() that allows
|
||||
seeking beyond the 2GB margin even on 32bit machines.
|
||||
|
||||
- Based on a patch in bug #1878059 by Steven Ayre libssh2 now parses >2GB file
|
||||
sizes when downloading SCP files.
|
||||
|
||||
- Bug #2064371 pointed out that the SSH2 banner may not use dash
|
||||
('-'). Reported by Bjorn Stenborg.
|
||||
|
||||
- Sean Peterson fixed a key re-exchange bug:
|
||||
http://daniel.haxx.se/projects/libssh2/mail/libssh2-devel-archive-2008-06/0002.shtml
|
||||
|
||||
- Mike Protts filed the bug report #1908724 that identified and fixed a problem
|
||||
with SFTP stat on files >4GB in size. Previously it used 32bit math only.
|
||||
|
||||
- Removed a stderr debug message that was accidentally left in (bug #1863153)
|
||||
|
||||
- OpenSSL and libz detection changed to make cross-compiling to Mingw
|
||||
work. See README for parameters to use if the auto-detection does
|
||||
not work for you. From Simon Josefsson.
|
||||
|
||||
- Simon Josefsson added a self-test that uses libssh2 to connect to a
|
||||
local sshd (only enabled if if OpenSSH is installed).
|
||||
|
||||
Version 0.18 (November 11 2007)
|
||||
-------------------------------
|
||||
|
||||
- Various changes that improve non-blocking operations and prevent stalls.
|
||||
Especially noticable on Windows since libssh2 just didn't work properly
|
||||
non-blocking on Windows before.
|
||||
|
||||
- Peter O'Gorman reported how a SCP transfer would hang for him, and it was
|
||||
fairly easy reproducable. One bug was in the transport layer, ignoring to
|
||||
read more data while there was data left even though it couldn't decrypt the
|
||||
data that was left due to it being too little... The other bug was in the
|
||||
channel layer, where the libssh2_channel_receive_window_adjust() function
|
||||
missed to set the state variables at times and thus this function would
|
||||
misbehave on repeated invokes.
|
||||
|
||||
- Changed the signature of libssh2_channel_setenv_ex to add const to the
|
||||
"varname" parameter (Dan Fandrich)
|
||||
|
||||
- Satish Mittal and David J Sullivan fixed an infinit recv() loop in
|
||||
libssh2_banner_receive()
|
||||
|
||||
Version 0.17 (August 6 2007)
|
||||
----------------------------
|
||||
Changes since previous version include:
|
||||
|
||||
o Re-indented the source code with this GNU indent setup:
|
||||
|
||||
--braces-on-if-line
|
||||
--braces-after-struct-decl-line
|
||||
--space-after-cast
|
||||
--line-length 79
|
||||
--comment-line-length 79
|
||||
--cuddle-else
|
||||
--no-tabs
|
||||
--tab-size 8
|
||||
--indent-level 4
|
||||
--no-space-after-for
|
||||
--space-after-if
|
||||
--space-after-while
|
||||
--no-space-after-function-call-names
|
||||
|
||||
Version 0.16 (August 6 2007)
|
||||
----------------------------
|
||||
Changes since previous version include:
|
||||
|
||||
o CRLF stripping fix for PEM reading
|
||||
@@ -24,8 +120,8 @@ This release would not have been possible without these friendly contributors:
|
||||
Of course we would have nothing without the great work by Sara Golemon that
|
||||
we're extending and building upon.
|
||||
|
||||
Version 0.15
|
||||
------------
|
||||
Version 0.15 (June 15 2007)
|
||||
---------------------------
|
||||
Added libssh2_sftp_readdir_ex() and updated LIBSSH2_APINO to
|
||||
200706151200 (James Housley)
|
||||
|
||||
@@ -98,7 +194,8 @@ Version 0.14
|
||||
|
||||
Allow socket_fd == 0 in libssh2_session_startup(). (puudeli)
|
||||
|
||||
Swap ordering of packet_add/packet-inspection to avoid inspect after free. (Selcuk)
|
||||
Swap ordering of packet_add/packet-inspection to avoid inspect after
|
||||
free. (Selcuk)
|
||||
|
||||
Swap KEX_INIT ordering, send our KEX_INIT first.
|
||||
|
||||
@@ -109,9 +206,11 @@ Version 0.14
|
||||
Version 0.13
|
||||
------------
|
||||
|
||||
Fixed channel not being marked closed when CHANNEL_CLOSE package cannot be sent. (David Robins)
|
||||
Fixed channel not being marked closed when CHANNEL_CLOSE package cannot be
|
||||
sent. (David Robins)
|
||||
|
||||
Fixed payload packet allocation bug when invalid packet length received. (David Robins)
|
||||
Fixed payload packet allocation bug when invalid packet length
|
||||
received. (David Robins)
|
||||
|
||||
Fixed `make install' target for MacOSX.
|
||||
|
||||
@@ -128,9 +227,11 @@ Version 0.12
|
||||
(Thanks Simon Hart)
|
||||
|
||||
Fix generation of 'e' portion of Diffie-Hellman keyset.
|
||||
|
||||
Use appropriate order for BN_rand() rather than fixed group1-specific value.
|
||||
|
||||
Re-fixed libssh2_sftp_rename_ex()
|
||||
|
||||
Transport had right packet_len, but sftp layer still had extra 4 bytes.
|
||||
|
||||
Fixed build with newer OpenSSL headers.
|
||||
@@ -146,42 +247,52 @@ Version 0.11
|
||||
|
||||
Added libssh2_userauth_keyboard_interactive_ex() -- Mikhail
|
||||
|
||||
Added libssh2_channel_receive_window_adjust() to be able to increase the size of the receive window.
|
||||
Added libssh2_channel_receive_window_adjust() to be able to increase the
|
||||
size of the receive window.
|
||||
|
||||
Added queueing for small window_adjust packets to avoid unnecessary packet conversation.
|
||||
Added queueing for small window_adjust packets to avoid unnecessary packet
|
||||
conversation.
|
||||
|
||||
Fixed libssh2_sftp_rename_ex() to only send flags parameter if version >= 5 negotiated
|
||||
(not currently possible, but will be and might as well keep the API consistent).
|
||||
Fixed libssh2_sftp_rename_ex() to only send flags parameter if version >= 5
|
||||
negotiated (not currently possible, but will be and might as well keep the
|
||||
API consistent).
|
||||
|
||||
Version 0.10
|
||||
------------
|
||||
|
||||
Added developer debugging hooks. See --enable-debug-* options to ./configure
|
||||
|
||||
Ignore extended data in the SFTP layer. With no other mechanism to deal with that data it'd just fill up and get stuck.
|
||||
Ignore extended data in the SFTP layer. With no other mechanism to deal
|
||||
with that data it'd just fill up and get stuck.
|
||||
|
||||
(Re)Fixed channel_write() to provide an opportunity for window space to become available again.
|
||||
(Re)Fixed channel_write() to provide an opportunity for window space to
|
||||
become available again.
|
||||
|
||||
(Re)Fixed SFTP INIT to send the correct SFTP packet length.
|
||||
|
||||
Fixed segfault when client and host can't agree on a hostkey/crypt/mac/comp method. (Thanks puudeli)
|
||||
Fixed segfault when client and host can't agree on a hostkey/crypt/mac/comp
|
||||
method. (Thanks puudeli)
|
||||
|
||||
Fixed major issue with sftp packet buffering mechanism. Using wrong blocking semantics. (No puudeli, YOU the man)
|
||||
Fixed major issue with sftp packet buffering mechanism. Using wrong
|
||||
blocking semantics. (No puudeli, YOU the man)
|
||||
|
||||
Reduced busy-looping of libssh2_sftp_packet_requirev.
|
||||
|
||||
Version 0.9
|
||||
-----------
|
||||
|
||||
Changed blocking_read to only block as much as necessary and not an arbitrary length of time. (Thanks Felix)
|
||||
Changed blocking_read to only block as much as necessary and not an
|
||||
arbitrary length of time. (Thanks Felix)
|
||||
|
||||
Fixed SFTP INIT/VERSION to exclude request_id and send correct maximum version number.
|
||||
Fixed SFTP INIT/VERSION to exclude request_id and send correct maximum
|
||||
version number.
|
||||
|
||||
Fixed SFTP to be properly BC with version 1 and 2 servers.
|
||||
|
||||
Fixed libssh2_poll() to recognized closed sessions/channels.
|
||||
|
||||
Fixed libssh2_channel_write_ex() to fully block when set to blocking mode. Return actual bytes written as well. (Thanks deadem)
|
||||
Fixed libssh2_channel_write_ex() to fully block when set to blocking mode.
|
||||
Return actual bytes written as well. (Thanks deadem)
|
||||
|
||||
Added tests for -lm and -lsocket and add them when necessary.
|
||||
|
||||
@@ -195,9 +306,11 @@ Version 0.8
|
||||
|
||||
Fix compatability with older versions of OpenSSL
|
||||
|
||||
Swapped order of none,zlib compression modes to prefer no compression by default.
|
||||
Swapped order of none,zlib compression modes to prefer no compression by
|
||||
default.
|
||||
|
||||
Added sys/uio.h for platforms (FBSD) which need it in order to define struct iovec.
|
||||
Added sys/uio.h for platforms (FBSD) which need it in order to define struct
|
||||
iovec.
|
||||
|
||||
Added libssh2_poll() to check status of sockets/channels/listeners.
|
||||
|
||||
@@ -220,15 +333,18 @@ Version 0.7
|
||||
Version 0.6
|
||||
-----------
|
||||
|
||||
Added LIBSSH2_FLAG_SIGPIPE to enable/disable SIGPIPE generated by send()/recv() calls. Default off.
|
||||
Added LIBSSH2_FLAG_SIGPIPE to enable/disable SIGPIPE generated by
|
||||
send()/recv() calls. Default off.
|
||||
|
||||
Added libssh2_session_flag() to set optional session flags.
|
||||
|
||||
Collapsed exchanging_keys/newkeys/authenticated flags into single state attribute.
|
||||
Collapsed exchanging_keys/newkeys/authenticated flags into single state
|
||||
attribute.
|
||||
|
||||
Fix zlib compression issue when internal buffer state misses partial sync.
|
||||
|
||||
Fix segfault when libssh2_session_methods() is called prior to session_startup().
|
||||
Fix segfault when libssh2_session_methods() is called prior to
|
||||
session_startup().
|
||||
|
||||
Fixed client to server channel windowing. Pervent send queue overruns.
|
||||
|
||||
@@ -238,7 +354,8 @@ Version 0.5
|
||||
-----------
|
||||
|
||||
*** BC Break ***
|
||||
Reimplemented libssh2_session_methods() to match libssh2_session_method_pref() style
|
||||
Reimplemented libssh2_session_methods() to match
|
||||
libssh2_session_method_pref() style
|
||||
|
||||
Fixed libssh2_attr2bin() (effects any setstat style call).
|
||||
|
||||
@@ -248,11 +365,14 @@ Version 0.5
|
||||
|
||||
Fixed KEX_INIT cookie and packet padding to use actual random data
|
||||
|
||||
Added DESTDIR support to makefiles (Adam Go<47><6F>biowski -- I hope that character set translates right)
|
||||
Added DESTDIR support to makefiles (Adam Go<47><6F>biowski -- I hope that
|
||||
character set translates right)
|
||||
|
||||
Added libssh2_channel_forward_listen_ex(), libssh2_channel_forward_cancel(), and libssh2_channel_forward_accept().
|
||||
Added libssh2_channel_forward_listen_ex(), libssh2_channel_forward_cancel(),
|
||||
and libssh2_channel_forward_accept().
|
||||
|
||||
Added ./configure option '--disable-gex-new' to allow using the older group-exchange format
|
||||
Added ./configure option '--disable-gex-new' to allow using the older
|
||||
group-exchange format
|
||||
|
||||
Added MAC methods hmac-md5 and hmac-md5-96.
|
||||
|
||||
|
54
README
54
README
@@ -4,6 +4,10 @@ libssh2 - SSH2 library
|
||||
libssh2 is a library implementing the SSH2 protocol, available under
|
||||
the revised BSD license.
|
||||
|
||||
Web site: http://www.libssh2.org/
|
||||
|
||||
Mailing list: https://lists.sourceforge.net/lists/listinfo/libssh2-devel
|
||||
|
||||
Generic installation instructions are in INSTALL. Some ./configure
|
||||
options deserve additional comments:
|
||||
|
||||
@@ -48,49 +52,43 @@ options deserve additional comments:
|
||||
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 in the
|
||||
default location, but if you have installed it
|
||||
somewhere else, use the --with-libgrypt-prefix=DIR
|
||||
parameter.
|
||||
Configure will attempt to locate Libgcrypt
|
||||
automatically.
|
||||
|
||||
* --with-openssl=[DIR]
|
||||
If your installation of Libgcrypt is in another
|
||||
location, specify it using --with-libgcrypt-prefix.
|
||||
|
||||
* --with-openssl
|
||||
* --without-openssl
|
||||
* --with-libssl-prefix=[DIR]
|
||||
|
||||
libssh2 can use the OpenSSL library
|
||||
(http://www.openssl.org) for cryptographic operations.
|
||||
Either Libgcrypt or OpenSSL is required.
|
||||
|
||||
Configure will attempt to locate OpenSSL in a number
|
||||
of default locations:
|
||||
|
||||
/usr/local/ssl
|
||||
/usr/local
|
||||
/usr
|
||||
/usr/local/openssl
|
||||
Configure will attempt to locate OpenSSL in the
|
||||
default location.
|
||||
|
||||
If your installation of OpenSSL is in another
|
||||
location, specify it here.
|
||||
location, specify it using --with-libssl-prefix.
|
||||
|
||||
* --with-libz=[DIR]
|
||||
* --with-libz
|
||||
* --without-libz
|
||||
* --with-libz-prefix=[DIR]
|
||||
|
||||
If present, libssh2 will attempt to use the zlib (http://www.zlib.org)
|
||||
for payload compression, however zlib is not required.
|
||||
If present, libssh2 will attempt to use the zlib
|
||||
(http://www.zlib.org) for payload compression, however
|
||||
zlib is not required.
|
||||
|
||||
Configure will attempt to location a zlib installation
|
||||
in a number of default locations:
|
||||
|
||||
/usr/local
|
||||
/usr
|
||||
/usr/local/libz
|
||||
/usr/libz
|
||||
/usr/local/zlib
|
||||
/usr/zlib
|
||||
|
||||
If your installation of zlib is in another location,
|
||||
you may specify it here.
|
||||
If your installation of Libz is in another location,
|
||||
specify it using --with-libz-prefix.
|
||||
|
||||
* --enable-debug
|
||||
|
||||
|
30
TODO
Normal file
30
TODO
Normal file
@@ -0,0 +1,30 @@
|
||||
Things TODO
|
||||
===========
|
||||
|
||||
* Add one of the missing man pages:
|
||||
|
||||
libssh2_channel_receive_window_adjust
|
||||
libssh2_channel_request_pty_size_ex
|
||||
libssh2_channel_window_read_ex
|
||||
libssh2_channel_window_write_ex
|
||||
libssh2_publickey_add_ex
|
||||
libssh2_publickey_init
|
||||
libssh2_publickey_list_fetch
|
||||
libssh2_publickey_list_free
|
||||
libssh2_publickey_remove_ex
|
||||
libssh2_publickey_shutdown
|
||||
libssh2_session_flag
|
||||
libssh2_session_get_blocking
|
||||
libssh2_userauth_hostbased_fromfile_ex
|
||||
|
||||
* Decrease the number of mallocs. Everywhere.
|
||||
|
||||
* Use SO_NOSIGPIPE for Mac OS/BSD systems where MSG_NOSIGNAL doesn't exist/work
|
||||
|
||||
* Extend the test suite to actually test lots of aspects of libssh2
|
||||
|
||||
|
||||
At next SONAME bump
|
||||
===================
|
||||
|
||||
* remove libssh2_base64_decode() from the API/ABI
|
217
configure.in
217
configure.in
@@ -1,7 +1,7 @@
|
||||
# AC_PREREQ(2.57)
|
||||
AC_INIT(libssh2, [-], libssh2-devel@lists.sourceforge.net)
|
||||
AC_CONFIG_SRCDIR([src])
|
||||
AC_CONFIG_HEADER([src/libssh2_config.h example/simple/config.h])
|
||||
AC_CONFIG_HEADER([src/libssh2_config.h])
|
||||
AM_MAINTAINER_MODE
|
||||
|
||||
dnl SED is needed by some of the tools
|
||||
@@ -28,6 +28,10 @@ AB_INIT
|
||||
# get this removed.
|
||||
AC_CANONICAL_HOST
|
||||
case "$host" in
|
||||
*-mingw*)
|
||||
CFLAGS="$CFLAGS -DLIBSSH2_WIN32 -DWINSOCK_VERSION=0x0200"
|
||||
LIBS="$LIBS -lws2_32"
|
||||
;;
|
||||
*-cygwin)
|
||||
CFLAGS="$CFLAGS -DLIBSSH2_WIN32"
|
||||
;;
|
||||
@@ -40,6 +44,11 @@ case "$host" in
|
||||
;;
|
||||
esac
|
||||
|
||||
AC_CHECK_TYPE(long long,
|
||||
[AC_DEFINE(HAVE_LONGLONG, 1,
|
||||
[Define to 1 if the compiler supports the 'long long' data type.])]
|
||||
longlong="yes"
|
||||
)
|
||||
# Some systems (Solaris?) have socket() in -lsocket.
|
||||
AC_SEARCH_LIBS(socket, socket)
|
||||
|
||||
@@ -52,153 +61,57 @@ AC_PROG_CC
|
||||
AC_PROG_INSTALL
|
||||
AC_PROG_LN_S
|
||||
AC_PROG_MAKE_SET
|
||||
AC_PATH_PROGS(SSHD, [sshd], [],
|
||||
[$PATH$PATH_SEPARATOR/usr/libexec$PATH_SEPARATOR]dnl
|
||||
[/usr/sbin$PATH_SEPARATOR/usr/etc$PATH_SEPARATOR/etc])
|
||||
AM_CONDITIONAL(SSHD, test -n "$SSHD")
|
||||
AC_LIBTOOL_WIN32_DLL
|
||||
AC_PROG_LIBTOOL
|
||||
AC_C_BIGENDIAN
|
||||
if test -z "$PKG_CONFIG"; then
|
||||
AC_PATH_PROG(PKG_CONFIG, pkg-config, no)
|
||||
fi
|
||||
|
||||
dnl check for how to do large files
|
||||
AC_SYS_LARGEFILE
|
||||
|
||||
# Look for libgcrypt.
|
||||
# Configure parameters
|
||||
AC_ARG_WITH(libgcrypt,
|
||||
AC_HELP_STRING([--with-libgcrypt],[Use libgcrypt for crypto]),
|
||||
use_libgcrypt=$withval,use_libgcrypt=no)
|
||||
if test "$use_libgcrypt" != "no"; then
|
||||
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(libz,
|
||||
AC_HELP_STRING([--with-libz],[Use Libz for compression]),
|
||||
use_libz=$withval,use_libz=auto)
|
||||
|
||||
# Look for OpenSSL (default)
|
||||
if test "$use_openssl" != "no" && test "$use_libgcrypt" != "yes"; then
|
||||
AC_LIB_HAVE_LINKFLAGS([ssl], [crypto], [#include <openssl/ssl.h>])
|
||||
fi
|
||||
|
||||
# Look for libgcrypt
|
||||
if test "$ac_cv_libssl" != "yes" && test "$use_libgcrypt" != "no"; then
|
||||
AC_LIB_HAVE_LINKFLAGS([gcrypt], [], [#include <gcrypt.h>])
|
||||
fi
|
||||
if test "$ac_cv_libgcrypt" = yes; then
|
||||
use_libgcrypt=yes
|
||||
|
||||
if test "$ac_cv_libssl" != "yes" && test "$ac_cv_libgcrypt" != "yes"; then
|
||||
AC_MSG_ERROR([cannot find OpenSSL or Libgcrypt,
|
||||
try --with-libssl-prefix=PATH or --with-libgcrypt-prefix=PATH])
|
||||
fi
|
||||
|
||||
if test "$ac_cv_libgcrypt" = "yes"; then
|
||||
AC_DEFINE(LIBSSH2_LIBGCRYPT, 1, [Use libgcrypt])
|
||||
fi
|
||||
AM_CONDITIONAL(LIBGCRYPT, test "$use_libgcrypt" != "no")
|
||||
AM_CONDITIONAL(LIBGCRYPT, test "$ac_cv_libgcrypt" = "yes")
|
||||
|
||||
# Need to define SHLIB_SUFFIX_NAME before checking for libcrypt and libz
|
||||
# $shrext_cmds (from libtool) can contain commands so it must be eval'd
|
||||
# Simon's note: replace the find-openssl/libz logic with Bruno's
|
||||
# AC_LIB_LINKFLAGS which is more portable and flexible.
|
||||
eval SHLIB_SUFFIX_NAME=\"$shrext_cmds\"
|
||||
AC_SUBST(SHLIB_SUFFIX_NAME)
|
||||
|
||||
#
|
||||
# Look for OpenSSL
|
||||
#
|
||||
AC_ARG_WITH(openssl,
|
||||
AC_HELP_STRING([--with-openssl=DIR],[Look for OpenSSL in PATH]),
|
||||
[LIBSSH2_OPENSSL_DIR=$withval],[LIBSSH2_OPENSSL_DIR=yes])
|
||||
|
||||
if test "$use_libgcrypt" = "no"; then
|
||||
|
||||
if test "$LIBSSH2_OPENSSL_DIR" = "no" || test "$LIBSSH2_OPENSSL_DIR" = "yes"; then
|
||||
unset LIBSSH2_OPENSSL_DIR
|
||||
fi
|
||||
|
||||
found_openssl=no
|
||||
pkgcfg_openssl=no
|
||||
unset OPENSSL_INCDIR
|
||||
unset OPENSSL_INCLINE
|
||||
unset OPENSSL_LIBLINE
|
||||
|
||||
AC_MSG_CHECKING([for OpenSSL])
|
||||
|
||||
# Explicit path given, use it rather than pkg-config
|
||||
if test ! -z "$LIBSSH2_OPENSSL_DIR"; then
|
||||
found_openssl=yes
|
||||
OPENSSL_LIBLINE="-L$LIBSSH2_OPENSSL_DIR/lib -lcrypto"
|
||||
OPENSSL_INCLINE="-I$LIBSSH2_OPENSSL_DIR/include"
|
||||
OPENSSL_INCDIR=$LIBSSH2_OPENSSL_DIR/include
|
||||
AC_MSG_RESULT([Using explicit path $LIBSSH2_OPENSSL_DIR])
|
||||
fi
|
||||
|
||||
# If pkg-config is found try using it
|
||||
if test "$found_openssl" = "no" && test -x "$PKG_CONFIG" && $PKG_CONFIG --exists openssl; then
|
||||
found_openssl=yes
|
||||
pkgcfg_openssl=yes
|
||||
OPENSSL_LIBLINE=`$PKG_CONFIG --libs openssl`
|
||||
OPENSSL_INCLINE=`$PKG_CONFIG --cflags-only-I openssl`
|
||||
AC_MSG_RESULT([Using paths from pkg-config])
|
||||
fi
|
||||
|
||||
# Elsewise, search for OpenSSL wherever it might be
|
||||
if test "$found_openssl" = "no"; then
|
||||
OPENSSL_SEARCH_PATH="/usr/local/ssl /usr/local /usr /usr/local/openssl"
|
||||
|
||||
for i in $OPENSSL_SEARCH_PATH; do
|
||||
if test -r $i/include/openssl/evp.h; then
|
||||
OPENSSL_INCLINE="-I$i/include"
|
||||
OPENSSL_INCDIR=$i/include
|
||||
fi
|
||||
if test -r $i/include/openssl/hmac.h; then
|
||||
OPENSSL_INCLINE="-I$i/include"
|
||||
OPENSSL_INCDIR=$i/include
|
||||
fi
|
||||
if test -r $i/lib/libcrypto.a -o -r $i/lib/libcrypto$SHLIB_SUFFIX_NAME; then
|
||||
OPENSSL_LIBLINE="-L$i/lib -lcrypto"
|
||||
fi
|
||||
test -n "$OPENSSL_INCLINE" && test -n "$OPENSSL_LIBLINE" && break
|
||||
done
|
||||
|
||||
if test -z "$OPENSSL_INCLINE"; then
|
||||
AC_MSG_ERROR([Cannot find OpenSSL's <evp.h> or <hmac.h>])
|
||||
fi
|
||||
|
||||
if test -z "$OPENSSL_LIBLINE"; then
|
||||
AC_MSG_ERROR([Cannot find OpenSSL's libcrypto])
|
||||
fi
|
||||
|
||||
AC_MSG_RESULT([$OPENSSL_INCLINE $OPENSSL_LIBLINE])
|
||||
fi
|
||||
|
||||
#
|
||||
# Confirm required OpenSSL libs
|
||||
#
|
||||
if test ! "$pkgcfg_openssl" = "yes"; then
|
||||
if test ! -r $OPENSSL_INCDIR/openssl/bn.h || test ! -r $OPENSSL_INCDIR/openssl/evp.h || \
|
||||
test ! -r $OPENSSL_INCDIR/openssl/hmac.h || test ! -r $OPENSSL_INCDIR/openssl/pem.h || \
|
||||
test ! -r $OPENSSL_INCDIR/openssl/sha.h; then
|
||||
AC_MSG_ERROR([Missing one or more of <openssl/bn.h>, <openssl/evp.h>, <openssl/hmac.h>, <openssl/pem.h>, <openssl/sha.h>])
|
||||
fi
|
||||
fi
|
||||
|
||||
CFLAGS="$CFLAGS $OPENSSL_INCLINE"
|
||||
LDFLAGS="$LDFLAGS $OPENSSL_LIBLINE"
|
||||
|
||||
fi
|
||||
|
||||
#
|
||||
# zlib
|
||||
#
|
||||
AC_ARG_WITH(libz,
|
||||
AC_HELP_STRING([--with-libz=PATH],[Look for libz in PATH]),
|
||||
[LIBSSH2_LIBZ_DIR=$withval],[LIBSSH2_LIBZ_DIR="/usr/local /usr /usr/local/libz /usr/libz /usr/local/zlib /usr/zlib"])
|
||||
|
||||
if test "$LIBSSH2_LIBZ_DIR" = "no" || test "$LIBSSH2_LIBZ_DIR" = "yes"; then
|
||||
unset LIBSSH2_LIBZ_DIR
|
||||
fi
|
||||
|
||||
unset LIBZ_INCDIR
|
||||
unset LIBZ_LIBDIR
|
||||
|
||||
AC_MSG_CHECKING([for libz])
|
||||
|
||||
for i in $LIBSSH2_LIBZ_DIR; do
|
||||
if test -r $i/include/zlib.h; then
|
||||
LIBZ_INCDIR=$i/include
|
||||
fi
|
||||
if test -r $i/lib/libz.a -o -r $i/lib/libz$SHLIB_SUFFIX_NAME; then
|
||||
LIBZ_LIBDIR=$i/lib
|
||||
fi
|
||||
test -n "$LIBZ_INCDIR" && test -n "$LIBZ_LIBDIR" && break
|
||||
done
|
||||
|
||||
if test -n "$LIBZ_INCDIR" && test -n "$LIBZ_LIBDIR"; then
|
||||
AC_MSG_RESULT([Found in $LIBZ_INCDIR $LIBZ_LIBDIR])
|
||||
CFLAGS="$CFLAGS -I$LIBZ_INCDIR"
|
||||
LDFLAGS="$LDFLAGS -L$LIBZ_LIBDIR -lz"
|
||||
AC_DEFINE(LIBSSH2_HAVE_ZLIB, 1, [Compile in zlib support])
|
||||
# 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([Try --with-libz-prefix=PATH if you know you have it])
|
||||
else
|
||||
AC_MSG_RESULT([Cannot find libz's <zlib.h>])
|
||||
AC_DEFINE(LIBSSH2_HAVE_ZLIB, 1, [Compile in zlib support])
|
||||
fi
|
||||
fi
|
||||
|
||||
#
|
||||
@@ -249,7 +162,39 @@ AC_HELP_STRING([--disable-debug],[Disable debug options]),
|
||||
AC_CHECK_HEADERS([errno.h fcntl.h stdio.h stdlib.h unistd.h sys/uio.h])
|
||||
AC_CHECK_HEADERS([sys/select.h sys/socket.h sys/ioctl.h sys/time.h])
|
||||
AC_CHECK_HEADERS([arpa/inet.h netinet/in.h])
|
||||
AC_CHECK_FUNCS(poll gettimeofday select)
|
||||
|
||||
case $host in
|
||||
*-*-cygwin* | *-*-cegcc*)
|
||||
# These are POSIX-like systems using BSD-like sockets API.
|
||||
;;
|
||||
*)
|
||||
AC_CHECK_HEADERS([windows.h winsock2.h ws2tcpip.h])
|
||||
;;
|
||||
esac
|
||||
|
||||
AC_CHECK_FUNCS(poll gettimeofday select strtoll)
|
||||
|
||||
dnl Check for select() into ws2_32 for Msys/Mingw
|
||||
if test "$ac_cv_func_select" != "yes"; then
|
||||
AC_MSG_CHECKING([for select in ws2_32])
|
||||
AC_TRY_LINK([
|
||||
#ifdef HAVE_WINSOCK2_H
|
||||
#ifndef WIN32_LEAN_AND_MEAN
|
||||
#define WIN32_LEAN_AND_MEAN
|
||||
#endif
|
||||
#include <winsock2.h>
|
||||
#endif
|
||||
],[
|
||||
select(0,(fd_set *)NULL,(fd_set *)NULL,(fd_set *)NULL,(struct timeval *)NULL);
|
||||
],[
|
||||
AC_MSG_RESULT([yes])
|
||||
HAVE_SELECT="1"
|
||||
AC_DEFINE_UNQUOTED(HAVE_SELECT, 1,
|
||||
[Define to 1 if you have the select function.])
|
||||
],[
|
||||
AC_MSG_RESULT([no])
|
||||
])
|
||||
fi
|
||||
|
||||
AC_FUNC_ALLOCA
|
||||
|
||||
|
@@ -1,2 +1,3 @@
|
||||
Makefile
|
||||
Makefile.in
|
||||
coverage
|
||||
|
@@ -1,4 +1,4 @@
|
||||
# $Id: Makefile.am,v 1.26 2007/06/15 11:01:22 jehousley Exp $
|
||||
# $Id: Makefile.am,v 1.31 2008/12/26 07:46:45 bagder Exp $
|
||||
|
||||
EXTRA_DIST = template.3
|
||||
|
||||
@@ -23,11 +23,14 @@ dist_man_MANS = \
|
||||
libssh2_channel_set_blocking.3 \
|
||||
libssh2_channel_setenv_ex.3 \
|
||||
libssh2_channel_wait_eof.3 \
|
||||
libssh2_channel_wait_closed.3 \
|
||||
libssh2_channel_write_ex.3 \
|
||||
libssh2_channel_x11_req_ex.3 \
|
||||
libssh2_hostkey_hash.3 \
|
||||
libssh2_scp_recv.3 \
|
||||
libssh2_scp_send_ex.3 \
|
||||
libssh2_session_abstract.3 \
|
||||
libssh2_session_block_directions.3 \
|
||||
libssh2_session_callback_set.3 \
|
||||
libssh2_session_free.3 \
|
||||
libssh2_session_disconnect_ex.3 \
|
||||
@@ -55,9 +58,13 @@ dist_man_MANS = \
|
||||
libssh2_sftp_stat_ex.3 \
|
||||
libssh2_sftp_symlink_ex.3 \
|
||||
libssh2_sftp_tell.3 \
|
||||
libssh2_sftp_tell64.3 \
|
||||
libssh2_sftp_unlink_ex.3 \
|
||||
libssh2_sftp_write.3 \
|
||||
libssh2_userauth_authenticated.3 \
|
||||
libssh2_userauth_keyboard_interactive_ex.3 \
|
||||
libssh2_userauth_list.3 \
|
||||
libssh2_userauth_password_ex.3 \
|
||||
libssh2_userauth_publickey_fromfile.3
|
||||
libssh2_userauth_publickey_fromfile.3 \
|
||||
libssh2_base64_decode.3 \
|
||||
libssh2_trace.3
|
||||
|
27
docs/libssh2_base64_decode.3
Normal file
27
docs/libssh2_base64_decode.3
Normal file
@@ -0,0 +1,27 @@
|
||||
.\" $Id: libssh2_base64_decode.3,v 1.2 2008/12/26 07:37:55 bagder Exp $
|
||||
.\"
|
||||
.TH libssh2_base64_decode 3 "23 Dec 2008" "libssh2 1.0" "libssh2 manual"
|
||||
.SH NAME
|
||||
libssh2_base64_decode - decode a base64 encoded string
|
||||
.SH SYNOPSIS
|
||||
#include <libssh2.h>
|
||||
|
||||
int libssh2_base64_decode(LIBSSH2_SESSION *session, char **dest,
|
||||
unsigned int *dest_len, const char *src,
|
||||
unsigned int src_len);
|
||||
.SH DESCRIPTION
|
||||
This function is deemed DEPRECATED and will be removed from libssh2 in a
|
||||
future version. Don't use it!
|
||||
|
||||
Decode a base64 chunk and store it into a newly allocated buffer. 'dest_len'
|
||||
will be set to hold the length of the returned buffer that '*dest' will point
|
||||
to.
|
||||
|
||||
The returned buffer is allocated by this function, but it is not clear how to
|
||||
free that memory!
|
||||
.SH BUGS
|
||||
The memory that *dest points to is allocated by the malloc function libssh2
|
||||
uses, but there's no way for an appliction to free this data in a safe and
|
||||
reliable way!
|
||||
.SH RETURN VALUE
|
||||
0 if successful, -1 if any error occurred.
|
@@ -1,8 +1,8 @@
|
||||
.\" $Id: libssh2_channel_close.3,v 1.1 2007/06/13 17:03:38 jehousley Exp $
|
||||
.\" $Id: libssh2_channel_close.3,v 1.2 2007/11/29 09:57:22 bagder Exp $
|
||||
.\"
|
||||
.TH libssh2_channel_close 3 "1 Jun 2007" "libssh2 0.15" "libssh2 manual"
|
||||
.SH NAME
|
||||
libssh2_channel_close - close a channel<
|
||||
libssh2_channel_close - close a channel
|
||||
.SH SYNOPSIS
|
||||
#include <libssh2.h>
|
||||
|
||||
|
24
docs/libssh2_channel_wait_closed.3
Normal file
24
docs/libssh2_channel_wait_closed.3
Normal file
@@ -0,0 +1,24 @@
|
||||
.\" $Id: libssh2_channel_wait_closed.3,v 1.2 2007/11/29 10:04:16 bagder Exp $
|
||||
.\"
|
||||
.TH libssh2_channel_wait_closed 3 "29 Nov 2007" "libssh2 0.19" "libssh2 manual"
|
||||
.SH NAME
|
||||
libssh2_channel_wait_closed - wait for the remote to close the channel
|
||||
.SH SYNOPSIS
|
||||
#include <libssh2.h>
|
||||
|
||||
int
|
||||
libssh2_channel_wait_closed(LIBSSH2_CHANNEL *channel);
|
||||
|
||||
.SH DESCRIPTION
|
||||
Enter a temporary blocking state until the remote host closes the named
|
||||
channel. Typically sent after \fIlibssh2_channel_close(3)\fP in order to
|
||||
examine the exit status.
|
||||
|
||||
.SH RETURN VALUE
|
||||
Return 0 on success or negative on failure. It returns LIBSSH2_ERROR_EAGAIN
|
||||
when it would otherwise block. While LIBSSH2_ERROR_EAGAIN is a negative
|
||||
number, it isn't really a failure per se.
|
||||
.SH SEE ALSO
|
||||
.BR libssh2_channel_send_eof(3)
|
||||
.BR libssh2_channel_eof(3)
|
||||
.BR libssh2_channel_wait_eof(3)
|
@@ -1,4 +1,4 @@
|
||||
.\" $Id: libssh2_session_abstract.3,v 1.1 2007/06/14 15:26:58 jehousley Exp $
|
||||
.\" $Id: libssh2_session_abstract.3,v 1.2 2008/07/03 10:58:53 bagder Exp $
|
||||
.\"
|
||||
.TH libssh2_session_abstract 3 "1 Jun 2007" "libssh2 0.15" "libssh2 manual"
|
||||
.SH NAME
|
||||
@@ -14,9 +14,9 @@ libssh2_session_abstract(LIBSSH2_SESSION *session);
|
||||
.BR libssh2_session_init_ex(3)
|
||||
|
||||
Return a pointer to where the abstract pointer provided to
|
||||
.BR libssh2_session_init_ex(3)
|
||||
is stored. By providing a doubly de-referenced pointer, the internal
|
||||
storage of the session instance may be modified in place.
|
||||
\fBlibssh2_session_init_ex(3)\fP is stored. By providing a doubly
|
||||
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
|
||||
|
31
docs/libssh2_session_block_directions.3
Normal file
31
docs/libssh2_session_block_directions.3
Normal file
@@ -0,0 +1,31 @@
|
||||
.\" $Id: libssh2_session_block_directions.3,v 1.2 2008/12/22 12:51:27 bagder Exp $
|
||||
.\"
|
||||
.TH libssh2_session_block_directions 3 "1 Oct 2008" "libssh2 1.0" "libssh2 manual"
|
||||
.SH NAME
|
||||
libssh2_session_block_directions - get directions that socket should wait for before calling libssh2 function again
|
||||
.SH SYNOPSIS
|
||||
#include <libssh2.h>
|
||||
|
||||
int
|
||||
libssh2_session_block_directions(LIBSSH2_SESSION *session);
|
||||
.SH DESCRIPTION
|
||||
\fIsession\fP - Session instance as returned by \fBlibssh2_session_init(3)\fP
|
||||
|
||||
When any of libssh2 functions return \fBLIBSSH2_ERROR_EAGAIN\fP an application
|
||||
should wait for the socket to have data available for reading or
|
||||
writing. Depending on the return value of
|
||||
\fIlibssh2_session_block_directions(3)\fP an application should wait for read,
|
||||
write or both.
|
||||
.SH RETURN VALUE
|
||||
Returns the set of directions as a binary mask. Can be a combination of:
|
||||
|
||||
LIBSSH2_SESSION_BLOCK_INBOUND: Inbound direction blocked.
|
||||
|
||||
LIBSSH2_SESSION_BLOCK_OUTBOUND: Outbound direction blocked.
|
||||
|
||||
Application should wait for data to be available for socket prior to calling a
|
||||
libssh2 function again. If \fBLIBSSH2_SESSION_BLOCK_INBOUND\fP is set select
|
||||
should contain the session socket in readfds set. Correspondingly in case of
|
||||
\fBLIBSSH2_SESSION_BLOCK_INBOUND\fP writefds set should contain the socket.
|
||||
.SH AVAILABILITY
|
||||
Added in 1.0
|
@@ -1,4 +1,4 @@
|
||||
.\" $Id: libssh2_session_set_blocking.3,v 1.1 2007/06/14 17:23:13 jehousley Exp $
|
||||
.\" $Id: libssh2_session_set_blocking.3,v 1.2 2008/07/03 10:58:53 bagder Exp $
|
||||
.\"
|
||||
.TH libssh2_session_set_blocking 3 "1 Jun 2007" "libssh2 0.15" "libssh2 manual"
|
||||
.SH NAME
|
||||
@@ -16,14 +16,14 @@ libssh2_session_set_blocking(LIBSSH2_SESSION *session, int blocking);
|
||||
\fIblocking\fP - Set to a non-zero value to make the channel block, or zero to
|
||||
make it non-blocking.
|
||||
|
||||
Set or clear blocking mode on the selected on the sessoin. This will
|
||||
instantly affect any channels associtated with this session. If a read is
|
||||
performed on a session with no data currently available, a blocking
|
||||
session will wait for data to arrive and return what it receives.
|
||||
A non-blocking session will return immediately with an empty buffer.
|
||||
If a write is performed on a session with
|
||||
no room for more data, a blocking session will wait for room. A non-blocking
|
||||
session will return immediately without writing anything.
|
||||
Set or clear blocking mode on the selected on the session. This will
|
||||
instantly affect any channels associated with this session. If a read is
|
||||
performed on a session with no data currently available, a blocking session
|
||||
will wait for data to arrive and return what it receives. A non-blocking
|
||||
session will return immediately with an empty buffer. If a write is performed
|
||||
on a session with no room for more data, a blocking session will wait for
|
||||
room. A non-blocking session will return immediately without writing
|
||||
anything.
|
||||
|
||||
.SH RETURN VALUE
|
||||
None
|
||||
|
@@ -1,8 +1,8 @@
|
||||
.\" $Id: libssh2_sftp_init.3,v 1.6 2007/06/13 16:41:33 jehousley Exp $
|
||||
.\" $Id: libssh2_sftp_init.3,v 1.7 2007/11/21 14:07:32 dottedmag Exp $
|
||||
.\"
|
||||
.TH libssh2_sftp_init 3 "1 Jun 2007" "libssh2 0.15" "libssh2 manual"
|
||||
.SH NAME
|
||||
libssh2_sftp_init -
|
||||
libssh2_sftp_init - open SFTP channel for the given SSH session.
|
||||
.SH SYNOPSIS
|
||||
#include <libssh2.h>
|
||||
#include <libssh2_sftp.h>
|
||||
|
@@ -1,4 +1,4 @@
|
||||
.\" $Id: libssh2_sftp_last_error.3,v 1.1 2007/06/14 16:08:43 jehousley Exp $
|
||||
.\" $Id: libssh2_sftp_last_error.3,v 1.2 2008/12/15 18:48:09 bagder Exp $
|
||||
.\"
|
||||
.TH libssh2_sftp_last_error 3 "1 Jun 2007" "libssh2 0.15" "libssh2 manual"
|
||||
.SH NAME
|
||||
@@ -14,7 +14,10 @@ libssh2_sftp_last_error(LIBSSH2_SFTP *sftp);
|
||||
\fIsftp\fP - SFTP instance as returned by
|
||||
.BR libssh2_sftp_init(3)
|
||||
|
||||
Determines the last error code produced by the SFTP layer.
|
||||
Returns the last error code produced by the SFTP layer. Note that this only
|
||||
returns a sensible error code if libssh2 returned LIBSSH2_ERROR_SFTP_PROTOCOL
|
||||
in a previous call. Using \fBlibssh2_sftp_last_error(3)\fP without a
|
||||
preceeding SFTP protocol error, it will return an unspecified value.
|
||||
|
||||
.SH RETURN VALUE
|
||||
Current error code state of the SFTP instance.
|
||||
|
@@ -1,8 +1,8 @@
|
||||
.\" $Id: libssh2_sftp_open_ex.3,v 1.8 2007/06/13 16:41:33 jehousley Exp $
|
||||
.\" $Id: libssh2_sftp_open_ex.3,v 1.9 2007/11/21 14:07:32 dottedmag Exp $
|
||||
.\"
|
||||
.TH libssh2_sftp_open_ex 3 "1 Jun 2007" "libssh2 0.15" "libssh2 manual"
|
||||
.SH NAME
|
||||
libssh2_sftp_open -
|
||||
libssh2_sftp_open - open filehandle for file on SFTP.
|
||||
.SH SYNOPSIS
|
||||
#include <libssh2.h>
|
||||
#include <libssh2_sftp.h>
|
||||
|
@@ -1,8 +1,8 @@
|
||||
.\" $Id: libssh2_sftp_rename_ex.3,v 1.1 2007/06/14 16:08:43 jehousley Exp $
|
||||
.\" $Id: libssh2_sftp_rename_ex.3,v 1.2 2008/12/23 12:34:17 bagder Exp $
|
||||
.\"
|
||||
.TH libssh2_sftp_rename_ex 3 "1 Jun 2007" "libssh2 0.15" "libssh2 manual"
|
||||
.SH NAME
|
||||
libssh2_sftp_rename_ex - rename a file
|
||||
libssh2_sftp_rename_ex - rename an SFTP file
|
||||
.SH SYNOPSIS
|
||||
#include <libssh2.h>
|
||||
#include <libssh2_sftp.h>
|
||||
|
@@ -1,8 +1,8 @@
|
||||
.\" $Id: libssh2_sftp_rmdir_ex.3,v 1.1 2007/06/14 16:08:43 jehousley Exp $
|
||||
.\" $Id: libssh2_sftp_rmdir_ex.3,v 1.2 2008/12/23 12:34:17 bagder Exp $
|
||||
.\"
|
||||
.TH libssh2_sftp_rmdir_ex 3 "1 Jun 2007" "libssh2 0.15" "libssh2 manual"
|
||||
.SH NAME
|
||||
libssh2_sftp_rmdir_ex - rename a file
|
||||
libssh2_sftp_rmdir_ex - remove an SFTP directory
|
||||
.SH SYNOPSIS
|
||||
#include <libssh2.h>
|
||||
#include <libssh2_sftp.h>
|
||||
|
@@ -1,6 +1,6 @@
|
||||
.\" $Id: libssh2_sftp_seek.3,v 1.1 2007/06/14 16:08:43 jehousley Exp $
|
||||
.\" $Id: libssh2_sftp_seek.3,v 1.3 2008/12/22 13:18:36 bagder Exp $
|
||||
.\"
|
||||
.TH libssh2_sftp_seek 3 "1 Jun 2007" "libssh2 0.15" "libssh2 manual"
|
||||
.TH libssh2_sftp_seek 3 "22 Dec 2008" "libssh2 1.0" "libssh2 manual"
|
||||
.SH NAME
|
||||
libssh2_sftp_seek - set the read/write position indicator within a file
|
||||
.SH SYNOPSIS
|
||||
@@ -10,6 +10,9 @@ libssh2_sftp_seek - set the read/write position indicator within a file
|
||||
void
|
||||
libssh2_sftp_seek(LIBSSH2_SFTP_HANDLE *handle, size_t offset);
|
||||
|
||||
void
|
||||
libssh2_sftp_seek64(LIBSSH2_SFTP_HANDLE *handle, libssh2_uint64_t offset);
|
||||
|
||||
.SH DESCRIPTION
|
||||
\fIhandle\fP - SFTP File Handle as returned by
|
||||
.BR libssh2_sftp_open(3)
|
||||
@@ -21,6 +24,7 @@ Note that libssh2 implements file pointers as a localized concept to make
|
||||
file access appear more POSIX like. No packets are exchanged with the server
|
||||
during a seek operation. The localized file pointer is simply used as a
|
||||
convenience offset during read/write operations.
|
||||
|
||||
.SH AVAILABILITY
|
||||
libssh2_sftp_seek64(3) was added in 1.0
|
||||
.SH SEE ALSO
|
||||
.BR libssh2_sftp_open(3)
|
||||
|
@@ -1,8 +1,8 @@
|
||||
.\" $Id: libssh2_sftp_stat_ex.3,v 1.1 2007/06/14 16:33:38 jehousley Exp $
|
||||
.\" $Id: libssh2_sftp_stat_ex.3,v 1.2 2008/12/23 12:34:17 bagder Exp $
|
||||
.\"
|
||||
.TH libssh2_sftp_stat_ex 3 "1 Jun 2007" "libssh2 0.15" "libssh2 manual"
|
||||
.SH NAME
|
||||
libssh2_sftp_stat_ex - rename a file
|
||||
libssh2_sftp_stat_ex - get status about an SFTP file
|
||||
.SH SYNOPSIS
|
||||
#include <libssh2.h>
|
||||
#include <libssh2_sftp.h>
|
||||
|
@@ -1,4 +1,4 @@
|
||||
.\" $Id: libssh2_sftp_tell.3,v 1.1 2007/06/14 16:33:38 jehousley Exp $
|
||||
.\" $Id: libssh2_sftp_tell.3,v 1.2 2008/12/22 12:46:45 bagder Exp $
|
||||
.\"
|
||||
.TH libssh2_sftp_tell 3 "1 Jun 2007" "libssh2 0.15" "libssh2 manual"
|
||||
.SH NAME
|
||||
@@ -11,16 +11,12 @@ size_t
|
||||
libssh2_sftp_tell(LIBSSH2_SFTP_HANDLE *handle);
|
||||
|
||||
.SH DESCRIPTION
|
||||
\fIhandle\fP - SFTP File Handle as returned by
|
||||
.BR libssh2_sftp_open(3)
|
||||
|
||||
Identify the current offset of the file handle's internal pointer. Note
|
||||
that the SSH2 protocol does not have a notion of file pointers and that
|
||||
libssh2 implements this using a localized file pointer which is updated
|
||||
with each read/write call.
|
||||
\fIhandle\fP - SFTP File Handle as returned by \fBlibssh2_sftp_open(3)\fP.
|
||||
|
||||
Returns the current offset of the file handle's internal pointer. Note that
|
||||
this is now deprecated. Use the newer \fBlibssh2_sftp_tell64(3)\fP instead!
|
||||
.SH RETURN VALUE
|
||||
Current offset from beginning of file in bytes.
|
||||
|
||||
.SH SEE ALSO
|
||||
.BR libssh2_sftp_open(3)
|
||||
.BR libssh2_sftp_open(3),
|
||||
.BR libssh2_sftp_tell64(3)
|
||||
|
23
docs/libssh2_sftp_tell64.3
Normal file
23
docs/libssh2_sftp_tell64.3
Normal file
@@ -0,0 +1,23 @@
|
||||
.\" $Id: libssh2_sftp_tell64.3,v 1.1 2008/12/22 12:46:45 bagder Exp $
|
||||
.\"
|
||||
.TH libssh2_sftp_tell64 3 "22 Dec 2008" "libssh2 1.0" "libssh2 manual"
|
||||
.SH NAME
|
||||
libssh2_sftp_tell64 - get the current read/write position indicator for a file
|
||||
.SH SYNOPSIS
|
||||
#include <libssh2.h>
|
||||
#include <libssh2_sftp.h>
|
||||
|
||||
libssh2_uint64_t
|
||||
libssh2_sftp_tell64(LIBSSH2_SFTP_HANDLE *handle);
|
||||
|
||||
.SH DESCRIPTION
|
||||
\fIhandle\fP - SFTP File Handle as returned by \fBlibssh2_sftp_open(3)\fP
|
||||
|
||||
Identify the current offset of the file handle's internal pointer.
|
||||
.SH RETURN VALUE
|
||||
Current offset from beginning of file in bytes.
|
||||
.SH AVAILABILITY
|
||||
Added in libssh2 1.0
|
||||
.SH SEE ALSO
|
||||
.BR libssh2_sftp_open(3),
|
||||
.BR libssh2_sftp_tell(3)
|
@@ -1,8 +1,8 @@
|
||||
.\" $Id: libssh2_sftp_unlink_ex.3,v 1.1 2007/06/14 16:46:14 jehousley Exp $
|
||||
.\" $Id: libssh2_sftp_unlink_ex.3,v 1.2 2008/12/23 12:34:17 bagder Exp $
|
||||
.\"
|
||||
.TH libssh2_sftp_unlink_ex 3 "1 Jun 2007" "libssh2 0.15" "libssh2 manual"
|
||||
.SH NAME
|
||||
libssh2_sftp_unlink_ex - rename a file
|
||||
libssh2_sftp_unlink_ex - unlink an SFTP file
|
||||
.SH SYNOPSIS
|
||||
#include <libssh2.h>
|
||||
#include <libssh2_sftp.h>
|
||||
|
@@ -1,8 +1,8 @@
|
||||
.\" $Id: libssh2_sftp_write.3,v 1.1 2007/06/14 16:46:14 jehousley Exp $
|
||||
.\" $Id: libssh2_sftp_write.3,v 1.2 2008/12/23 12:34:17 bagder Exp $
|
||||
.\"
|
||||
.TH libssh2_sftp_rename_ex 3 "1 Jun 2007" "libssh2 0.15" "libssh2 manual"
|
||||
.TH libssh2_sftp_write 3 "1 Jun 2007" "libssh2 0.15" "libssh2 manual"
|
||||
.SH NAME
|
||||
libssh2_sftp_rename_ex - rename a file
|
||||
libssh2_sftp_write - write SFTP data
|
||||
.SH SYNOPSIS
|
||||
#include <libssh2.h>
|
||||
#include <libssh2_sftp.h>
|
||||
|
35
docs/libssh2_trace.3
Normal file
35
docs/libssh2_trace.3
Normal file
@@ -0,0 +1,35 @@
|
||||
.\" $Id: libssh2_trace.3,v 1.1 2008/12/26 07:46:45 bagder Exp $
|
||||
.\"
|
||||
.TH libssh2_trace 3 "26 Dec 2008" "libssh2 1.0" "libssh2 manual"
|
||||
.SH NAME
|
||||
libssh2_trace - enable debug info from inside libssh2
|
||||
.SH SYNOPSIS
|
||||
#include <libssh2.h>
|
||||
|
||||
void libssh2_trace(int bitmask);
|
||||
|
||||
.SH DESCRIPTION
|
||||
This is a function present in the library that can be used to get debug info
|
||||
from within libssh2 when it is running. Helpful when trying to trace or debug
|
||||
behaviors. This function has no effect unless libssh2 was built to support
|
||||
this option, and a typical "release build" might not.
|
||||
|
||||
\fBbitmask\fP can be set to none, one or more of these bits:
|
||||
.RS
|
||||
.IP LIBSSH2_TRACE_TRANS
|
||||
Transport layer debugging
|
||||
.IP LIBSSH2_TRACE_KEX
|
||||
Key exchange debugging
|
||||
.IP LIBSSH2_TRACE_AUTH
|
||||
Authentication debugging
|
||||
.IP LIBSSH2_TRACE_CONN
|
||||
Connection layer debugging
|
||||
.IP LIBSSH2_TRACE_SCP
|
||||
SCP debugging
|
||||
.IP LIBSSH2_TRACE_SFTP
|
||||
SFTP debugging
|
||||
.IP LIBSSH2_TRACE_ERROR
|
||||
Error debugging
|
||||
.IP LIBSSH2_TRACE_PUBLICKEY
|
||||
Public Key debugging
|
||||
.RE
|
43
docs/libssh2_userauth_keyboard_interactive_ex.3
Normal file
43
docs/libssh2_userauth_keyboard_interactive_ex.3
Normal file
@@ -0,0 +1,43 @@
|
||||
.\" $Id: libssh2_userauth_keyboard_interactive_ex.3,v 1.1 2008/03/08 18:26:32 dottedmag Exp $
|
||||
.\"
|
||||
.TH libssh2_userauth_keyboard_interactive_ex 3 "8 Mar 2008" "libssh2 0.19" "libssh2 manual"
|
||||
.SH NAME
|
||||
libssh2_userauth_keyboard_interactive_ex - authenticate a session using a challenge-response authentication
|
||||
.SH SYNOPSIS
|
||||
#include <libssh2.h>
|
||||
|
||||
int
|
||||
libssh2_userauth_keyboard_interactive_ex(LIBSSH2_SESSION *session, const char *username, unsigned int username_len, LIBSSH2_USERAUTH_KBDINT_RESPONSE_FUNC(*response_callback));
|
||||
|
||||
int
|
||||
libssh2_userauth_keyboard_interactive(LIBSSH2_SESSION *session, const char *username, LIBSSH2_USERAUTH_KBDINT_RESPONSE_FUNC(*response_callback));
|
||||
|
||||
.SH DESCRIPTION
|
||||
\fIsession\fP - Session instance as returned by
|
||||
.BR libssh2_session_init(3)
|
||||
|
||||
\fIusername\fP - Name of user to attempt plain password authentication for.
|
||||
|
||||
\fIusername_len\fP - Length of username parameter.
|
||||
|
||||
\fIresponse_callback\fP - As authentication proceeds, host issues several (1 or more) challenges and requires responses. This callback will be called at this moment. Callback is responsible to obtain responses for the challenges, fill the provided data structure and then return control. Responses will be sent to the host. String values will be free(3)ed by the library.
|
||||
|
||||
Attempts keyboard-interactive (challenge/response) authentication.
|
||||
|
||||
Note that many SSH servers will always issue single "password" challenge,
|
||||
requesting actual password as response, but it is not required by the protocol,
|
||||
and various authentication schemes, such as smartcard authentication may use
|
||||
keyboard-interactive authentication type too.
|
||||
|
||||
.SH RETURN VALUE
|
||||
Return 0 on success or negative on failure. It returns
|
||||
LIBSSH2_ERROR_EAGAIN when it would otherwise block. While
|
||||
LIBSSH2_ERROR_EAGAIN is a negative number, it isn't really a failure per se.
|
||||
|
||||
.SH ERRORS
|
||||
\fILIBSSH2_ERROR_ALLOC\fP - An internal memory allocation call failed.
|
||||
|
||||
\fILIBSSH2_ERROR_SOCKET_SEND\fP - Unable to send data on socket.
|
||||
|
||||
.SH SEE ALSO
|
||||
.BR libssh2_session_init(3)
|
@@ -2,8 +2,12 @@ Makefile
|
||||
Makefile.in
|
||||
.deps
|
||||
.libs
|
||||
*.gcno
|
||||
*.gcda
|
||||
scp
|
||||
scp_nonblock
|
||||
scp_write
|
||||
scp_write_nonblock
|
||||
sftp
|
||||
sftp_nonblock
|
||||
sftpdir
|
||||
|
@@ -10,34 +10,7 @@ noinst_PROGRAMS = ssh2 \
|
||||
sftp_RW_nonblock \
|
||||
sftpdir sftpdir_nonblock
|
||||
|
||||
INCLUDES = -I$(top_srcdir)/include
|
||||
# the examples need the $(top_builddir)/src since when building outside of the
|
||||
# source dir they still need to reach the libssh2_config.h header
|
||||
AM_CPPFLAGS = -I$(top_srcdir)/src -I$(top_srcdir)/include -I$(top_builddir)/src
|
||||
LDADD = $(top_builddir)/src/libssh2.la
|
||||
|
||||
ssh2_SOURCES = ssh2.c
|
||||
|
||||
scp_SOURCES = scp.c
|
||||
|
||||
scp_nonblock_SOURCES = scp_nonblock.c
|
||||
|
||||
scp_write_SOURCES = scp_write.c
|
||||
|
||||
scp_write_nonblock_SOURCES = scp_write_nonblock.c
|
||||
|
||||
sftp_SOURCES = sftp.c
|
||||
|
||||
sftp_nonblock_SOURCES = sftp_nonblock.c
|
||||
|
||||
sftp_write_SOURCES = sftp_write.c
|
||||
|
||||
sftp_write_nonblock_SOURCES = sftp_write_nonblock.c
|
||||
|
||||
sftp_mkdir_SOURCES = sftp_mkdir.c
|
||||
|
||||
sftp_mkdir_nonblock_SOURCES = sftp_mkdir_nonblock.c
|
||||
|
||||
sftpdir_SOURCES = sftpdir.c
|
||||
|
||||
sftpdir_nonblock_SOURCES = sftpdir_nonblock.c
|
||||
|
||||
sftp_RW_nonblock_SOURCES = sftp_RW_nonblock.c
|
||||
|
||||
|
@@ -1,10 +1,10 @@
|
||||
/*
|
||||
* $Id: scp.c,v 1.9 2007/07/31 11:00:29 bagder Exp $
|
||||
* $Id: scp.c,v 1.11 2008/11/10 16:48:41 bagder Exp $
|
||||
*
|
||||
* Sample showing how to do a simple SCP transfer.
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
#include "libssh2_config.h"
|
||||
#include <libssh2.h>
|
||||
|
||||
#ifdef HAVE_WINSOCK2_H
|
||||
@@ -40,9 +40,9 @@ int main(int argc, char *argv[])
|
||||
const char *fingerprint;
|
||||
LIBSSH2_SESSION *session;
|
||||
LIBSSH2_CHANNEL *channel;
|
||||
char *username=(char *)"username";
|
||||
char *password=(char *)"password";
|
||||
char *scppath=(char *)"/tmp/TEST";
|
||||
const char *username="username";
|
||||
const char *password="password";
|
||||
const char *scppath="/tmp/TEST";
|
||||
struct stat fileinfo;
|
||||
int rc;
|
||||
off_t got=0;
|
||||
@@ -50,7 +50,7 @@ int main(int argc, char *argv[])
|
||||
#ifdef WIN32
|
||||
WSADATA wsadata;
|
||||
|
||||
WSAStartup(WINSOCK_VERSION, &wsadata);
|
||||
WSAStartup(MAKEWORD(2,0), &wsadata);
|
||||
#endif
|
||||
|
||||
if (argc > 1) {
|
||||
|
@@ -1,10 +1,10 @@
|
||||
/*
|
||||
* $Id: scp_nonblock.c,v 1.8 2007/07/31 11:00:29 bagder Exp $
|
||||
* $Id: scp_nonblock.c,v 1.13 2008/11/10 16:48:41 bagder Exp $
|
||||
*
|
||||
* Sample showing how to do SCP transfers in a non-blocking manner.
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
#include "libssh2_config.h"
|
||||
#include <libssh2.h>
|
||||
|
||||
#ifdef HAVE_WINSOCK2_H
|
||||
@@ -40,17 +40,20 @@ int main(int argc, char *argv[])
|
||||
const char *fingerprint;
|
||||
LIBSSH2_SESSION *session;
|
||||
LIBSSH2_CHANNEL *channel;
|
||||
char *username=(char *)"username";
|
||||
char *password=(char *)"password";
|
||||
char *scppath=(char *)"/tmp/TEST";
|
||||
const char *username="username";
|
||||
const char *password="password";
|
||||
const char *scppath="/tmp/TEST";
|
||||
struct stat fileinfo;
|
||||
int rc;
|
||||
#if defined(HAVE_IOCTLSOCKET)
|
||||
long flag = 1;
|
||||
#endif
|
||||
off_t got=0;
|
||||
|
||||
#ifdef WIN32
|
||||
WSADATA wsadata;
|
||||
|
||||
WSAStartup(WINSOCK_VERSION, &wsadata);
|
||||
WSAStartup(MAKEWORD(2,0), &wsadata);
|
||||
#endif
|
||||
|
||||
if (argc > 1) {
|
||||
@@ -88,8 +91,15 @@ int main(int argc, char *argv[])
|
||||
/* FIXME: this can/should be done in a more portable manner */
|
||||
rc = fcntl(sock, F_GETFL, 0);
|
||||
fcntl(sock, F_SETFL, rc | O_NONBLOCK);
|
||||
#elif defined(HAVE_IOCTLSOCKET)
|
||||
ioctlsocket(sock, FIONBIO, &flag);
|
||||
#else
|
||||
#ifdef WIN32
|
||||
u_long mode = 1;
|
||||
ioctlsocket (sock, FIONBIO, &mode);
|
||||
#else
|
||||
#error "add support for setting the socket non-blocking here"
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/* Create a session instance */
|
||||
|
@@ -1,10 +1,10 @@
|
||||
/*
|
||||
* $Id: scp_write.c,v 1.4 2007/07/31 11:00:29 bagder Exp $
|
||||
* $Id: scp_write.c,v 1.6 2008/11/10 16:48:41 bagder Exp $
|
||||
*
|
||||
* Sample showing how to do a simple SCP transfer.
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
#include "libssh2_config.h"
|
||||
#include <libssh2.h>
|
||||
|
||||
#ifdef HAVE_WINSOCK2_H
|
||||
@@ -40,10 +40,10 @@ int main(int argc, char *argv[])
|
||||
const char *fingerprint;
|
||||
LIBSSH2_SESSION *session;
|
||||
LIBSSH2_CHANNEL *channel;
|
||||
char *username=(char *)"username";
|
||||
char *password=(char *)"password";
|
||||
char *loclfile=(char *)"scp_write.c";
|
||||
char *scppath=(char *)"/tmp/TEST";
|
||||
const char *username="username";
|
||||
const char *password="password";
|
||||
const char *loclfile="scp_write.c";
|
||||
const char *scppath="/tmp/TEST";
|
||||
FILE *local;
|
||||
int rc;
|
||||
char mem[1024];
|
||||
@@ -54,7 +54,7 @@ int main(int argc, char *argv[])
|
||||
#ifdef WIN32
|
||||
WSADATA wsadata;
|
||||
|
||||
WSAStartup(WINSOCK_VERSION, &wsadata);
|
||||
WSAStartup(MAKEWORD(2,0), &wsadata);
|
||||
#endif
|
||||
|
||||
if (argc > 1) {
|
||||
|
@@ -1,10 +1,10 @@
|
||||
/*
|
||||
* $Id: scp_write_nonblock.c,v 1.6 2007/07/31 11:00:29 bagder Exp $
|
||||
* $Id: scp_write_nonblock.c,v 1.9 2008/11/10 16:48:41 bagder Exp $
|
||||
*
|
||||
* Sample showing how to do a simple SCP transfer.
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
#include "libssh2_config.h"
|
||||
|
||||
#include <libssh2.h>
|
||||
|
||||
@@ -41,12 +41,15 @@ int main(int argc, char *argv[])
|
||||
const char *fingerprint;
|
||||
LIBSSH2_SESSION *session;
|
||||
LIBSSH2_CHANNEL *channel;
|
||||
char *username=(char *)"username";
|
||||
char *password=(char *)"password";
|
||||
char *loclfile=(char *)"scp_write.c";
|
||||
char *scppath=(char *)"/tmp/TEST";
|
||||
const char *username="username";
|
||||
const char *password="password";
|
||||
const char *loclfile="scp_write.c";
|
||||
const char *scppath="/tmp/TEST";
|
||||
FILE *local;
|
||||
int rc;
|
||||
#if defined(HAVE_IOCTLSOCKET)
|
||||
long flag = 1;
|
||||
#endif
|
||||
char mem[1024];
|
||||
size_t nread;
|
||||
char *ptr;
|
||||
@@ -55,7 +58,7 @@ int main(int argc, char *argv[])
|
||||
#ifdef WIN32
|
||||
WSADATA wsadata;
|
||||
|
||||
WSAStartup(WINSOCK_VERSION, &wsadata);
|
||||
WSAStartup(MAKEWORD(2,0), &wsadata);
|
||||
#endif
|
||||
|
||||
if (argc > 1) {
|
||||
@@ -105,8 +108,15 @@ int main(int argc, char *argv[])
|
||||
/* FIXME: this can/should be done in a more portable manner */
|
||||
rc = fcntl(sock, F_GETFL, 0);
|
||||
fcntl(sock, F_SETFL, rc | O_NONBLOCK);
|
||||
#elif defined(HAVE_IOCTLSOCKET)
|
||||
ioctlsocket(sock, FIONBIO, &flag);
|
||||
#else
|
||||
#ifdef WIN32
|
||||
u_long mode = 1;
|
||||
ioctlsocket (sock, FIONBIO, &mode);
|
||||
#else
|
||||
#error "add support for setting the socket non-blocking here"
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/* Create a session instance
|
||||
|
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* $Id: sftp.c,v 1.12 2007/07/31 11:00:29 bagder Exp $
|
||||
* $Id: sftp.c,v 1.15 2008/11/10 16:48:41 bagder Exp $
|
||||
*
|
||||
* Sample showing how to do SFTP transfers.
|
||||
*
|
||||
@@ -9,7 +9,7 @@
|
||||
* "sftp 192.168.0.1 user password /tmp/secrets -p|-i|-k"
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
#include "libssh2_config.h"
|
||||
#include <libssh2.h>
|
||||
#include <libssh2_sftp.h>
|
||||
|
||||
@@ -39,11 +39,11 @@
|
||||
#include <ctype.h>
|
||||
|
||||
|
||||
char *keyfile1=(char *)"~/.ssh/id_rsa.pub";
|
||||
char *keyfile2=(char *)"~/.ssh/id_rsa";
|
||||
char *username=(char *)"username";
|
||||
char *password=(char *)"password";
|
||||
char *sftppath=(char *)"/tmp/TEST";
|
||||
const char *keyfile1="~/.ssh/id_rsa.pub";
|
||||
const char *keyfile2="~/.ssh/id_rsa";
|
||||
const char *username="username";
|
||||
const char *password="password";
|
||||
const char *sftppath="/tmp/TEST";
|
||||
|
||||
|
||||
static void kbd_callback(const char *name, int name_len,
|
||||
@@ -80,7 +80,7 @@ int main(int argc, char *argv[])
|
||||
#ifdef WIN32
|
||||
WSADATA wsadata;
|
||||
|
||||
WSAStartup(WINSOCK_VERSION, &wsadata);
|
||||
WSAStartup(MAKEWORD(2,0), &wsadata);
|
||||
#endif
|
||||
|
||||
if (argc > 1) {
|
||||
@@ -147,7 +147,7 @@ int main(int argc, char *argv[])
|
||||
fprintf(stderr, "\n");
|
||||
|
||||
/* check what authentication methods are available */
|
||||
userauthlist = libssh2_userauth_list(session, username, sizeof(username));
|
||||
userauthlist = libssh2_userauth_list(session, username, strlen(username));
|
||||
printf("Authentication methods: %s\n", userauthlist);
|
||||
if (strstr(userauthlist, "password") != NULL) {
|
||||
auth_pw |= 1;
|
||||
|
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* $Id: sftp_RW_nonblock.c,v 1.9 2007/07/31 11:00:29 bagder Exp $
|
||||
* $Id: sftp_RW_nonblock.c,v 1.12 2008/11/10 16:48:41 bagder Exp $
|
||||
*
|
||||
* Sample showing how to do SFTP transfers in a non-blocking manner.
|
||||
*
|
||||
@@ -9,7 +9,7 @@
|
||||
* Using the SFTP server running on 127.0.0.1
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
#include "libssh2_config.h"
|
||||
#include <libssh2.h>
|
||||
#include <libssh2_sftp.h>
|
||||
|
||||
@@ -48,11 +48,14 @@ int main(int argc, char *argv[])
|
||||
struct sockaddr_in sin;
|
||||
const char *fingerprint;
|
||||
LIBSSH2_SESSION *session;
|
||||
char *username=(char *)"username";
|
||||
char *password=(char *)"password";
|
||||
char *sftppath=(char *)"/tmp/TEST"; /* source path */
|
||||
char *dest=(char *)"/tmp/TEST2"; /* destination path */
|
||||
const char *username="username";
|
||||
const char *password="password";
|
||||
const char *sftppath="/tmp/TEST"; /* source path */
|
||||
const char *dest="/tmp/TEST2"; /* destination path */
|
||||
int rc;
|
||||
#if defined(HAVE_IOCTLSOCKET)
|
||||
long flag = 1;
|
||||
#endif
|
||||
LIBSSH2_SFTP *sftp_session;
|
||||
LIBSSH2_SFTP_HANDLE *sftp_handle;
|
||||
FILE *tempstorage;
|
||||
@@ -63,7 +66,7 @@ int main(int argc, char *argv[])
|
||||
#ifdef WIN32
|
||||
WSADATA wsadata;
|
||||
|
||||
WSAStartup(WINSOCK_VERSION, &wsadata);
|
||||
WSAStartup(MAKEWORD(2,0), &wsadata);
|
||||
#endif
|
||||
|
||||
/* Ultra basic "connect to port 22 on localhost"
|
||||
@@ -87,8 +90,15 @@ int main(int argc, char *argv[])
|
||||
/* FIXME: this can/should be done in a more portable manner */
|
||||
rc = fcntl(sock, F_GETFL, 0);
|
||||
fcntl(sock, F_SETFL, rc | O_NONBLOCK);
|
||||
#elif defined(HAVE_IOCTLSOCKET)
|
||||
ioctlsocket(sock, FIONBIO, &flag);
|
||||
#else
|
||||
#ifdef WIN32
|
||||
u_long mode = 1;
|
||||
ioctlsocket (sock, FIONBIO, &mode);
|
||||
#else
|
||||
#error "add support for setting the socket non-blocking here"
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/* Create a session instance
|
||||
|
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* $Id: sftp_mkdir.c,v 1.6 2007/07/31 11:00:29 bagder Exp $
|
||||
* $Id: sftp_mkdir.c,v 1.8 2008/11/10 16:48:41 bagder Exp $
|
||||
*
|
||||
* Sample showing how to do SFTP mkdir
|
||||
*
|
||||
@@ -9,7 +9,7 @@
|
||||
* "sftp 192.168.0.1 user password /tmp/sftp_mkdir"
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
#include "libssh2_config.h"
|
||||
#include <libssh2.h>
|
||||
#include <libssh2_sftp.h>
|
||||
|
||||
@@ -42,16 +42,16 @@ int main(int argc, char *argv[])
|
||||
struct sockaddr_in sin;
|
||||
const char *fingerprint;
|
||||
LIBSSH2_SESSION *session;
|
||||
char *username=(char *)"username";
|
||||
char *password=(char *)"password";
|
||||
char *sftppath=(char *)"/tmp/sftp_mkdir";
|
||||
const char *username="username";
|
||||
const char *password="password";
|
||||
const char *sftppath="/tmp/sftp_mkdir";
|
||||
int rc;
|
||||
LIBSSH2_SFTP *sftp_session;
|
||||
|
||||
#ifdef WIN32
|
||||
WSADATA wsadata;
|
||||
|
||||
WSAStartup(WINSOCK_VERSION, &wsadata);
|
||||
WSAStartup(MAKEWORD(2,0), &wsadata);
|
||||
#endif
|
||||
|
||||
if (argc > 1) {
|
||||
|
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* $Id: sftp_mkdir_nonblock.c,v 1.8 2007/07/31 11:00:29 bagder Exp $
|
||||
* $Id: sftp_mkdir_nonblock.c,v 1.11 2008/11/10 16:48:41 bagder Exp $
|
||||
*
|
||||
* Sample showing how to do SFTP non-blocking mkdir.
|
||||
*
|
||||
@@ -9,7 +9,7 @@
|
||||
* "sftp 192.168.0.1 user password /tmp/sftp_write_nonblock.c"
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
#include "libssh2_config.h"
|
||||
#include <libssh2.h>
|
||||
#include <libssh2_sftp.h>
|
||||
|
||||
@@ -42,16 +42,19 @@ int main(int argc, char *argv[])
|
||||
struct sockaddr_in sin;
|
||||
const char *fingerprint;
|
||||
LIBSSH2_SESSION *session;
|
||||
char *username=(char *)"username";
|
||||
char *password=(char *)"password";
|
||||
char *sftppath=(char *)"/tmp/sftp_mkdir_nonblock";
|
||||
const char *username="username";
|
||||
const char *password="password";
|
||||
const char *sftppath="/tmp/sftp_mkdir_nonblock";
|
||||
int rc;
|
||||
#if defined(HAVE_IOCTLSOCKET)
|
||||
long flag = 1;
|
||||
#endif
|
||||
LIBSSH2_SFTP *sftp_session;
|
||||
|
||||
#ifdef WIN32
|
||||
WSADATA wsadata;
|
||||
|
||||
WSAStartup(WINSOCK_VERSION, &wsadata);
|
||||
WSAStartup(MAKEWORD(2,0), &wsadata);
|
||||
#endif
|
||||
|
||||
if (argc > 1) {
|
||||
@@ -91,8 +94,15 @@ int main(int argc, char *argv[])
|
||||
/* FIXME: this can/should be done in a more portable manner */
|
||||
rc = fcntl(sock, F_GETFL, 0);
|
||||
fcntl(sock, F_SETFL, rc | O_NONBLOCK);
|
||||
#elif defined(HAVE_IOCTLSOCKET)
|
||||
ioctlsocket(sock, FIONBIO, &flag);
|
||||
#else
|
||||
#ifdef WIN32
|
||||
u_long mode = 1;
|
||||
ioctlsocket (sock, FIONBIO, &mode);
|
||||
#else
|
||||
#error "add support for setting the socket non-blocking here"
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/* Create a session instance
|
||||
|
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* $Id: sftp_nonblock.c,v 1.12 2007/07/31 11:00:29 bagder Exp $
|
||||
* $Id: sftp_nonblock.c,v 1.15 2008/11/10 16:48:41 bagder Exp $
|
||||
*
|
||||
* Sample showing how to do SFTP non-blocking transfers.
|
||||
*
|
||||
@@ -9,7 +9,7 @@
|
||||
* "sftp 192.168.0.1 user password /tmp/secrets"
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
#include "libssh2_config.h"
|
||||
#include <libssh2.h>
|
||||
#include <libssh2_sftp.h>
|
||||
|
||||
@@ -45,17 +45,20 @@ int main(int argc, char *argv[])
|
||||
struct sockaddr_in sin;
|
||||
const char *fingerprint;
|
||||
LIBSSH2_SESSION *session;
|
||||
char *username=(char *)"username";
|
||||
char *password=(char *)"password";
|
||||
char *sftppath=(char *)"/tmp/TEST";
|
||||
const char *username="username";
|
||||
const char *password="password";
|
||||
const char *sftppath="/tmp/TEST";
|
||||
int rc;
|
||||
#if defined(HAVE_IOCTLSOCKET)
|
||||
long flag = 1;
|
||||
#endif
|
||||
LIBSSH2_SFTP *sftp_session;
|
||||
LIBSSH2_SFTP_HANDLE *sftp_handle;
|
||||
|
||||
#ifdef WIN32
|
||||
WSADATA wsadata;
|
||||
|
||||
WSAStartup(WINSOCK_VERSION, &wsadata);
|
||||
WSAStartup(MAKEWORD(2,0), &wsadata);
|
||||
#endif
|
||||
|
||||
if (argc > 1) {
|
||||
@@ -94,8 +97,15 @@ int main(int argc, char *argv[])
|
||||
/* FIXME: this can/should be done in a more portable manner */
|
||||
rc = fcntl(sock, F_GETFL, 0);
|
||||
fcntl(sock, F_SETFL, rc | O_NONBLOCK);
|
||||
#elif defined(HAVE_IOCTLSOCKET)
|
||||
ioctlsocket(sock, FIONBIO, &flag);
|
||||
#else
|
||||
#ifdef WIN32
|
||||
u_long mode = 1;
|
||||
ioctlsocket (sock, FIONBIO, &mode);
|
||||
#else
|
||||
#error "add support for setting the socket non-blocking here"
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/* Create a session instance */
|
||||
|
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* $Id: sftp_write.c,v 1.7 2007/07/31 11:00:29 bagder Exp $
|
||||
* $Id: sftp_write.c,v 1.9 2008/11/10 16:48:41 bagder Exp $
|
||||
*
|
||||
* Sample showing how to do SFTP write transfers.
|
||||
*
|
||||
@@ -9,7 +9,7 @@
|
||||
* "sftp 192.168.0.1 user password sftp_write.c /tmp/secrets"
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
#include "libssh2_config.h"
|
||||
#include <libssh2.h>
|
||||
#include <libssh2_sftp.h>
|
||||
|
||||
@@ -42,10 +42,10 @@ int main(int argc, char *argv[])
|
||||
struct sockaddr_in sin;
|
||||
const char *fingerprint;
|
||||
LIBSSH2_SESSION *session;
|
||||
char *username=(char *)"username";
|
||||
char *password=(char *)"password";
|
||||
char *loclfile=(char *)"sftp_write.c";
|
||||
char *sftppath=(char *)"/tmp/TEST";
|
||||
const char *username="username";
|
||||
const char *password="password";
|
||||
const char *loclfile="sftp_write.c";
|
||||
const char *sftppath="/tmp/TEST";
|
||||
int rc;
|
||||
FILE *local;
|
||||
LIBSSH2_SFTP *sftp_session;
|
||||
@@ -57,7 +57,7 @@ int main(int argc, char *argv[])
|
||||
#ifdef WIN32
|
||||
WSADATA wsadata;
|
||||
|
||||
WSAStartup(WINSOCK_VERSION, &wsadata);
|
||||
WSAStartup(MAKEWORD(2,0), &wsadata);
|
||||
#endif
|
||||
|
||||
if (argc > 1) {
|
||||
|
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* $Id: sftp_write_nonblock.c,v 1.9 2007/07/31 11:00:29 bagder Exp $
|
||||
* $Id: sftp_write_nonblock.c,v 1.12 2008/11/10 16:48:41 bagder Exp $
|
||||
*
|
||||
* Sample showing how to do SFTP non-blocking write transfers.
|
||||
*
|
||||
@@ -9,7 +9,7 @@
|
||||
* "sftp 192.168.0.1 user password sftp_write_nonblock.c /tmp/sftp_write_nonblock.c"
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
#include "libssh2_config.h"
|
||||
#include <libssh2.h>
|
||||
#include <libssh2_sftp.h>
|
||||
|
||||
@@ -42,11 +42,14 @@ int main(int argc, char *argv[])
|
||||
struct sockaddr_in sin;
|
||||
const char *fingerprint;
|
||||
LIBSSH2_SESSION *session;
|
||||
char *username=(char *)"username";
|
||||
char *password=(char *)"password";
|
||||
char *loclfile=(char *)"sftp_write_nonblock.c";
|
||||
char *sftppath=(char *)"/tmp/sftp_write_nonblock.c";
|
||||
const char *username="username";
|
||||
const char *password="password";
|
||||
const char *loclfile="sftp_write_nonblock.c";
|
||||
const char *sftppath="/tmp/sftp_write_nonblock.c";
|
||||
int rc;
|
||||
#if defined(HAVE_IOCTLSOCKET)
|
||||
long flag = 1;
|
||||
#endif
|
||||
FILE *local;
|
||||
LIBSSH2_SFTP *sftp_session;
|
||||
LIBSSH2_SFTP_HANDLE *sftp_handle;
|
||||
@@ -57,7 +60,7 @@ int main(int argc, char *argv[])
|
||||
#ifdef WIN32
|
||||
WSADATA wsadata;
|
||||
|
||||
WSAStartup(WINSOCK_VERSION, &wsadata);
|
||||
WSAStartup(MAKEWORD(2,0), &wsadata);
|
||||
#endif
|
||||
|
||||
if (argc > 1) {
|
||||
@@ -106,8 +109,15 @@ int main(int argc, char *argv[])
|
||||
/* FIXME: this can/should be done in a more portable manner */
|
||||
rc = fcntl(sock, F_GETFL, 0);
|
||||
fcntl(sock, F_SETFL, rc | O_NONBLOCK);
|
||||
#elif defined(HAVE_IOCTLSOCKET)
|
||||
ioctlsocket(sock, FIONBIO, &flag);
|
||||
#else
|
||||
#ifdef WIN32
|
||||
u_long mode = 1;
|
||||
ioctlsocket (sock, FIONBIO, &mode);
|
||||
#else
|
||||
#error "add support for setting the socket non-blocking here"
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/* Create a session instance
|
||||
|
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* $Id: sftpdir.c,v 1.8 2007/07/31 11:00:29 bagder Exp $
|
||||
* $Id: sftpdir.c,v 1.10 2008/11/10 16:48:41 bagder Exp $
|
||||
*
|
||||
* Sample doing an SFTP directory listing.
|
||||
*
|
||||
@@ -9,7 +9,7 @@
|
||||
* "sftpdir 192.168.0.1 user password /tmp/secretdir"
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
#include "libssh2_config.h"
|
||||
#include <libssh2.h>
|
||||
#include <libssh2_sftp.h>
|
||||
|
||||
@@ -42,9 +42,9 @@ int main(int argc, char *argv[])
|
||||
struct sockaddr_in sin;
|
||||
const char *fingerprint;
|
||||
LIBSSH2_SESSION *session;
|
||||
char *username=(char *)"username";
|
||||
char *password=(char *)"password";
|
||||
char *sftppath=(char *)"/tmp/secretdir";
|
||||
const char *username="username";
|
||||
const char *password="password";
|
||||
const char *sftppath="/tmp/secretdir";
|
||||
int rc;
|
||||
LIBSSH2_SFTP *sftp_session;
|
||||
LIBSSH2_SFTP_HANDLE *sftp_handle;
|
||||
@@ -52,7 +52,7 @@ int main(int argc, char *argv[])
|
||||
#ifdef WIN32
|
||||
WSADATA wsadata;
|
||||
|
||||
WSAStartup(WINSOCK_VERSION, &wsadata);
|
||||
WSAStartup(MAKEWORD(2,0), &wsadata);
|
||||
#endif
|
||||
|
||||
if (argc > 1) {
|
||||
|
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* $Id: sftpdir_nonblock.c,v 1.9 2007/07/31 11:00:29 bagder Exp $
|
||||
* $Id: sftpdir_nonblock.c,v 1.12 2008/11/10 16:48:41 bagder Exp $
|
||||
*
|
||||
* Sample doing an SFTP directory listing.
|
||||
*
|
||||
@@ -9,7 +9,7 @@
|
||||
* "sftpdir 192.168.0.1 user password /tmp/secretdir"
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
#include "libssh2_config.h"
|
||||
#include <libssh2.h>
|
||||
#include <libssh2_sftp.h>
|
||||
|
||||
@@ -42,17 +42,20 @@ int main(int argc, char *argv[])
|
||||
struct sockaddr_in sin;
|
||||
const char *fingerprint;
|
||||
LIBSSH2_SESSION *session;
|
||||
char *username=(char *)"username";
|
||||
char *password=(char *)"password";
|
||||
char *sftppath=(char *)"/tmp/secretdir";
|
||||
const char *username="username";
|
||||
const char *password="password";
|
||||
const char *sftppath="/tmp/secretdir";
|
||||
int rc;
|
||||
#if defined(HAVE_IOCTLSOCKET)
|
||||
long flag = 1;
|
||||
#endif
|
||||
LIBSSH2_SFTP *sftp_session;
|
||||
LIBSSH2_SFTP_HANDLE *sftp_handle;
|
||||
|
||||
#ifdef WIN32
|
||||
WSADATA wsadata;
|
||||
|
||||
WSAStartup(WINSOCK_VERSION, &wsadata);
|
||||
WSAStartup(MAKEWORD(2,0), &wsadata);
|
||||
#endif
|
||||
|
||||
if (argc > 1) {
|
||||
@@ -91,8 +94,15 @@ int main(int argc, char *argv[])
|
||||
/* FIXME: this can/should be done in a more portable manner */
|
||||
rc = fcntl(sock, F_GETFL, 0);
|
||||
fcntl(sock, F_SETFL, rc | O_NONBLOCK);
|
||||
#elif defined(HAVE_IOCTLSOCKET)
|
||||
ioctlsocket(sock, FIONBIO, &flag);
|
||||
#else
|
||||
#ifdef WIN32
|
||||
u_long mode = 1;
|
||||
ioctlsocket (sock, FIONBIO, &mode);
|
||||
#else
|
||||
#error "add support for setting the socket non-blocking here"
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/* Create a session instance
|
||||
|
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* $Id: ssh2.c,v 1.16 2007/08/03 15:08:28 jehousley Exp $
|
||||
* $Id: ssh2.c,v 1.18 2008/11/10 16:48:41 bagder Exp $
|
||||
*
|
||||
* Sample showing how to do SSH2 connect.
|
||||
*
|
||||
@@ -9,10 +9,13 @@
|
||||
* "ssh2 host user password [-p|-i|-k]"
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
#include "libssh2_config.h"
|
||||
#include <libssh2.h>
|
||||
#include <libssh2_sftp.h>
|
||||
|
||||
#ifdef HAVE_WINDOWS_H
|
||||
# include <windows.h>
|
||||
#endif
|
||||
#ifdef HAVE_WINSOCK2_H
|
||||
# include <winsock2.h>
|
||||
#endif
|
||||
@@ -36,10 +39,10 @@
|
||||
#include <ctype.h>
|
||||
|
||||
|
||||
char *keyfile1=(char *)"~/.ssh/id_rsa.pub";
|
||||
char *keyfile2=(char *)"~/.ssh/id_rsa";
|
||||
char *username=(char *)"username";
|
||||
char *password=(char *)"password";
|
||||
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,
|
||||
@@ -73,7 +76,7 @@ int main(int argc, char *argv[])
|
||||
#ifdef WIN32
|
||||
WSADATA wsadata;
|
||||
|
||||
WSAStartup(WINSOCK_VERSION, &wsadata);
|
||||
WSAStartup(MAKEWORD(2,0), &wsadata);
|
||||
#endif
|
||||
|
||||
if (argc > 1) {
|
||||
@@ -189,12 +192,12 @@ int main(int argc, char *argv[])
|
||||
/* Some environment variables may be set,
|
||||
* It's up to the server which ones it'll allow though
|
||||
*/
|
||||
libssh2_channel_setenv(channel, (char *)"FOO", (char *)"bar");
|
||||
libssh2_channel_setenv(channel, "FOO", "bar");
|
||||
|
||||
/* Request a terminal with 'vanilla' terminal emulation
|
||||
* See /etc/termcap for more options
|
||||
*/
|
||||
if (libssh2_channel_request_pty(channel, (char *)"vanilla")) {
|
||||
if (libssh2_channel_request_pty(channel, "vanilla")) {
|
||||
fprintf(stderr, "Failed requesting pty\n");
|
||||
goto skip_shell;
|
||||
}
|
||||
|
@@ -1,4 +1,4 @@
|
||||
/* Copyright (c) 2004-2007, Sara Golemon <sarag@libssh2.org>
|
||||
/* Copyright (c) 2004-2008, Sara Golemon <sarag@libssh2.org>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms,
|
||||
@@ -72,19 +72,26 @@ typedef unsigned int uint32_t;
|
||||
#if defined(LIBSSH2_WIN32) && defined(_MSC_VER) && (_MSC_VER <= 1400)
|
||||
typedef unsigned __int64 libssh2_uint64_t;
|
||||
typedef __int64 libssh2_int64_t;
|
||||
typedef long ssize_t;
|
||||
typedef unsigned int uint32_t;
|
||||
#ifndef _SSIZE_T_DEFINED
|
||||
typedef int ssize_t;
|
||||
#define _SSIZE_T_DEFINED
|
||||
#endif
|
||||
#else
|
||||
typedef unsigned long long libssh2_uint64_t;
|
||||
typedef long long libssh2_int64_t;
|
||||
#endif
|
||||
|
||||
#define LIBSSH2_VERSION "0.16.0-CVS"
|
||||
/* We use underscore instead of dash when appending CVS in dev versions just
|
||||
to make the BANNER define (used by src/session.c) be a valid SSH
|
||||
banner. Release versions have no appended strings and may of coruse not
|
||||
have dashes either. */
|
||||
#define LIBSSH2_VERSION "1.0.0_CVS"
|
||||
|
||||
/* The numeric version number is also available "in parts" by using these
|
||||
defines: */
|
||||
#define LIBSSH2_VERSION_MAJOR 0
|
||||
#define LIBSSH2_VERSION_MINOR 16
|
||||
#define LIBSSH2_VERSION_MAJOR 1
|
||||
#define LIBSSH2_VERSION_MINOR 0
|
||||
#define LIBSSH2_VERSION_PATCH 0
|
||||
|
||||
/* This is the numeric version of the libssh2 version number, meant for easier
|
||||
@@ -102,7 +109,7 @@ typedef long long libssh2_int64_t;
|
||||
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 0x001000
|
||||
#define LIBSSH2_VERSION_NUM 0x010000
|
||||
|
||||
/*
|
||||
* This is the date and time when the full source package was created. The
|
||||
@@ -237,6 +244,11 @@ typedef struct _LIBSSH2_POLLFD {
|
||||
#define LIBSSH2_POLLFD_CHANNEL_CLOSED 0x0080 /* Channel Disconnect */
|
||||
#define LIBSSH2_POLLFD_LISTENER_CLOSED 0x0080 /* Listener Disconnect */
|
||||
|
||||
#define HAVE_LIBSSH2_SESSION_BLOCK_DIRECTION
|
||||
/* Block Direction Types */
|
||||
#define LIBSSH2_SESSION_BLOCK_INBOUND 0x0001
|
||||
#define LIBSSH2_SESSION_BLOCK_OUTBOUND 0x0002
|
||||
|
||||
/* Hash Types */
|
||||
#define LIBSSH2_HOSTKEY_HASH_MD5 1
|
||||
#define LIBSSH2_HOSTKEY_HASH_SHA1 2
|
||||
@@ -306,7 +318,7 @@ LIBSSH2_API void **libssh2_session_abstract(LIBSSH2_SESSION *session);
|
||||
LIBSSH2_API void *libssh2_session_callback_set(LIBSSH2_SESSION *session, int cbtype, void *callback);
|
||||
LIBSSH2_API int libssh2_banner_set(LIBSSH2_SESSION *session, const char *banner);
|
||||
|
||||
LIBSSH2_API int libssh2_session_startup(LIBSSH2_SESSION *session, int socket);
|
||||
LIBSSH2_API int libssh2_session_startup(LIBSSH2_SESSION *session, int sock);
|
||||
LIBSSH2_API int libssh2_session_disconnect_ex(LIBSSH2_SESSION *session, int reason, const char *description, const char *lang);
|
||||
#define libssh2_session_disconnect(session, description) libssh2_session_disconnect_ex((session), SSH_DISCONNECT_BY_APPLICATION, (description), "")
|
||||
LIBSSH2_API int libssh2_session_free(LIBSSH2_SESSION *session);
|
||||
@@ -317,6 +329,7 @@ LIBSSH2_API int libssh2_session_method_pref(LIBSSH2_SESSION *session, int method
|
||||
LIBSSH2_API const char *libssh2_session_methods(LIBSSH2_SESSION *session, int method_type);
|
||||
LIBSSH2_API int libssh2_session_last_error(LIBSSH2_SESSION *session, char **errmsg, int *errmsg_len, int want_buf);
|
||||
LIBSSH2_API int libssh2_session_last_errno(LIBSSH2_SESSION *session);
|
||||
LIBSSH2_API int libssh2_session_block_directions(LIBSSH2_SESSION *session);
|
||||
|
||||
LIBSSH2_API int libssh2_session_flag(LIBSSH2_SESSION *session, int flag, int value);
|
||||
|
||||
@@ -380,12 +393,15 @@ LIBSSH2_API int libssh2_channel_forward_cancel(LIBSSH2_LISTENER *listener);
|
||||
|
||||
LIBSSH2_API LIBSSH2_CHANNEL *libssh2_channel_forward_accept(LIBSSH2_LISTENER *listener);
|
||||
|
||||
LIBSSH2_API int libssh2_channel_setenv_ex(LIBSSH2_CHANNEL *channel, char *varname, unsigned int varname_len, const char *value, unsigned int value_len);
|
||||
LIBSSH2_API int libssh2_channel_setenv_ex(LIBSSH2_CHANNEL *channel, const char *varname, unsigned int varname_len, 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))
|
||||
|
||||
LIBSSH2_API int libssh2_channel_request_pty_ex(LIBSSH2_CHANNEL *channel, const char *term, unsigned int term_len, const char *modes, unsigned int modes_len, int width, int height, int width_px, int height_px);
|
||||
#define libssh2_channel_request_pty(channel, term) libssh2_channel_request_pty_ex((channel), (term), strlen(term), NULL, 0, LIBSSH2_TERM_WIDTH, LIBSSH2_TERM_HEIGHT, LIBSSH2_TERM_WIDTH_PX, LIBSSH2_TERM_HEIGHT_PX)
|
||||
|
||||
LIBSSH2_API int libssh2_channel_request_pty_size_ex(LIBSSH2_CHANNEL * channel, int width, int height, int width_px, int height_px);
|
||||
#define libssh2_channel_request_pty_size(channel, width, height) libssh2_channel_request_pty_size_ex( (channel), (width), (height), 0, 0)
|
||||
|
||||
LIBSSH2_API int libssh2_channel_x11_req_ex(LIBSSH2_CHANNEL *channel, int single_connection, const char *auth_proto, const char *auth_cookie, int screen_number);
|
||||
#define libssh2_channel_x11_req(channel, screen_number) libssh2_channel_x11_req_ex((channel), 0, NULL, NULL, (screen_number))
|
||||
|
||||
|
@@ -1,4 +1,4 @@
|
||||
/* Copyright (c) 2004-2007, Sara Golemon <sarag@libssh2.org>
|
||||
/* Copyright (c) 2004-2008, Sara Golemon <sarag@libssh2.org>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms,
|
||||
@@ -206,9 +206,11 @@ LIBSSH2_API int libssh2_sftp_close_handle(LIBSSH2_SFTP_HANDLE *handle);
|
||||
#define libssh2_sftp_closedir(handle) libssh2_sftp_close_handle(handle)
|
||||
|
||||
LIBSSH2_API void libssh2_sftp_seek(LIBSSH2_SFTP_HANDLE *handle, size_t offset);
|
||||
#define libssh2_sftp_rewind(handle) libssh2_sftp_seek((handle), 0)
|
||||
LIBSSH2_API void libssh2_sftp_seek64(LIBSSH2_SFTP_HANDLE *handle, libssh2_uint64_t offset);
|
||||
#define libssh2_sftp_rewind(handle) libssh2_sftp_seek64((handle), 0)
|
||||
|
||||
LIBSSH2_API size_t libssh2_sftp_tell(LIBSSH2_SFTP_HANDLE *handle);
|
||||
LIBSSH2_API libssh2_uint64_t libssh2_sftp_tell64(LIBSSH2_SFTP_HANDLE *handle);
|
||||
|
||||
LIBSSH2_API int libssh2_sftp_fstat_ex(LIBSSH2_SFTP_HANDLE *handle, LIBSSH2_SFTP_ATTRIBUTES *attrs, int setstat);
|
||||
#define libssh2_sftp_fstat(handle, attrs) libssh2_sftp_fstat_ex((handle), (attrs), 0)
|
||||
|
51
libssh2-style.el
Normal file
51
libssh2-style.el
Normal file
@@ -0,0 +1,51 @@
|
||||
;;;; Emacs Lisp help for writing libssh2 code. ;;;;
|
||||
;;;; $Id: libssh2-style.el,v 1.1 2008/12/20 12:36:50 bagder Exp $
|
||||
|
||||
;;; The libssh2 hacker's C conventions.
|
||||
;;; See the sample.emacs file on how this file can be made to take
|
||||
;;; effect automatically when editing libssh2 source files.
|
||||
|
||||
(defconst libssh2-c-style
|
||||
'((c-basic-offset . 4)
|
||||
(c-comment-only-line-offset . 0)
|
||||
(c-hanging-braces-alist . ((substatement-open before after)))
|
||||
(c-offsets-alist . ((topmost-intro . 0)
|
||||
(topmost-intro-cont . 0)
|
||||
(substatement . +)
|
||||
(substatement-open . 0)
|
||||
(statement-case-intro . +)
|
||||
(statement-case-open . 0)
|
||||
(case-label . 0)
|
||||
))
|
||||
)
|
||||
"Libssh2 C Programming Style")
|
||||
|
||||
(defun libssh2-code-cleanup ()
|
||||
"tabify and delete trailing whitespace"
|
||||
(interactive)
|
||||
(untabify (point-min) (point-max))
|
||||
(delete-trailing-whitespace)
|
||||
)
|
||||
|
||||
;; Customizations for all of c-mode, c++-mode, and objc-mode
|
||||
(defun libssh2-c-mode-common-hook ()
|
||||
"Libssh2 C mode hook"
|
||||
;; add libssh2 style and set it for the current buffer
|
||||
(c-add-style "libssh2" libssh2-c-style t)
|
||||
(setq tab-width 8
|
||||
indent-tabs-mode nil ; Use spaces, not tabs.
|
||||
comment-column 40
|
||||
c-font-lock-extra-types (append '("libssh2_int64_t" "LIBSSH2_USERAUTH_KBDINT_PROMPT" "LIBSSH2_SESSION" "LIBSSH2_CHANNEL" "ssize_t" "size_t" "uint32_t" "LIBSSH2_LISTENER" "LIBSSH2_POLLFD"))
|
||||
)
|
||||
;; keybindings for C, C++, and Objective-C. We can put these in
|
||||
;; c-mode-base-map because of inheritance ...
|
||||
(define-key c-mode-base-map "\M-q" 'c-fill-paragraph)
|
||||
(define-key c-mode-base-map "\M-m" 'libssh2-code-cleanup)
|
||||
(setq c-recognize-knr-p nil)
|
||||
;;; (add-hook 'write-file-hooks 'delete-trailing-whitespace t)
|
||||
(setq show-trailing-whitespace t)
|
||||
)
|
||||
|
||||
;; Set this is in your .emacs if you want to use the c-mode-hook as
|
||||
;; defined here right out of the box.
|
||||
; (add-hook 'c-mode-common-hook 'libssh2-c-mode-common-hook)
|
5
m4/.cvsignore
Normal file
5
m4/.cvsignore
Normal file
@@ -0,0 +1,5 @@
|
||||
libtool.m4
|
||||
ltoptions.m4
|
||||
ltsugar.m4
|
||||
ltversion.m4
|
||||
lt~obsolete.m4
|
@@ -5,7 +5,7 @@
|
||||
##
|
||||
## Comments to: Guenter Knauf <eflash@gmx.net>
|
||||
##
|
||||
## $Id: Makefile.netware,v 1.7 2007/07/15 20:34:33 gknauf Exp $
|
||||
## $Id: Makefile.netware,v 1.8 2007/08/08 16:32:42 gknauf Exp $
|
||||
#
|
||||
#########################################################################
|
||||
|
||||
@@ -131,7 +131,7 @@ SDK_CLIB = $(NDK_ROOT)/nwsdk
|
||||
SDK_LIBC = $(NDK_ROOT)/libc
|
||||
SNPRINTF = $(NDKBASE)/snprintf
|
||||
|
||||
INCLUDES = -I.. -I../../include
|
||||
INCLUDES = -I. -I../../include
|
||||
|
||||
LDLIBS =
|
||||
|
||||
@@ -188,7 +188,7 @@ vpath %.c $(SAMPLES)
|
||||
|
||||
all: prebuild $(TARGETS)
|
||||
|
||||
prebuild: $(OBJDIR) $(OBJDIR)/version.inc
|
||||
prebuild: $(OBJDIR) $(OBJDIR)/version.inc config.h
|
||||
|
||||
$(OBJDIR)/%.o: %.c
|
||||
# @echo Compiling $<
|
||||
@@ -284,6 +284,130 @@ endif
|
||||
@echo $(DL)output $(notdir $(@:.def=.nlm))$(DL) >> $@
|
||||
endif
|
||||
|
||||
config.h: Makefile.netware
|
||||
@echo Creating $@
|
||||
@echo $(DL)/* $@ for NetWare target.$(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)#define VERSION "$(LIBSSH2_VERSION_STR)"$(DL) >> $@
|
||||
@echo $(DL)#define PACKAGE_BUGREPORT "http://sourceforge.net/projects/libssh2"$(DL) >> $@
|
||||
ifeq ($(LIBARCH),CLIB)
|
||||
@echo $(DL)#define OS "i586-pc-clib-NetWare"$(DL) >> $@
|
||||
@echo $(DL)#define NETDB_USE_INTERNET 1$(DL) >> $@
|
||||
@echo $(DL)#define HAVE_STRICMP 1$(DL) >> $@
|
||||
@echo $(DL)#define socklen_t int$(DL) >> $@
|
||||
@echo $(DL)#define sleep(s) delay(1000 * s)$(DL) >> $@
|
||||
else
|
||||
@echo $(DL)#define OS "i586-pc-libc-NetWare"$(DL) >> $@
|
||||
@echo $(DL)#define HAVE_DLFCN_H 1$(DL) >> $@
|
||||
@echo $(DL)#define HAVE_DLOPEN 1$(DL) >> $@
|
||||
@echo $(DL)#define HAVE_FTRUNCATE 1$(DL) >> $@
|
||||
@echo $(DL)#define HAVE_GETTIMEOFDAY 1$(DL) >> $@
|
||||
@echo $(DL)#define HAVE_INET_PTON 1$(DL) >> $@
|
||||
@echo $(DL)#define HAVE_INTTYPES_H 1$(DL) >> $@
|
||||
@echo $(DL)#define HAVE_LIMITS_H 1$(DL) >> $@
|
||||
@echo $(DL)#define HAVE_LONGLONG 1$(DL) >> $@
|
||||
@echo $(DL)#define HAVE_STDINT_H 1$(DL) >> $@
|
||||
@echo $(DL)#define HAVE_STRCASECMP 1$(DL) >> $@
|
||||
@echo $(DL)#define HAVE_STRLCAT 1$(DL) >> $@
|
||||
@echo $(DL)#define HAVE_STRLCPY 1$(DL) >> $@
|
||||
@echo $(DL)#define HAVE_STRTOLL 1$(DL) >> $@
|
||||
@echo $(DL)#define HAVE_SYS_PARAM_H 1$(DL) >> $@
|
||||
@echo $(DL)#define HAVE_SYS_SELECT_H 1$(DL) >> $@
|
||||
@echo $(DL)#define HAVE_TERMIOS_H 1$(DL) >> $@
|
||||
@echo $(DL)#define HAVE_AF_INET6 1$(DL) >> $@
|
||||
@echo $(DL)#define HAVE_PF_INET6 1$(DL) >> $@
|
||||
@echo $(DL)#define HAVE_STRUCT_IN6_ADDR 1$(DL) >> $@
|
||||
@echo $(DL)#define HAVE_STRUCT_SOCKADDR_IN6 1$(DL) >> $@
|
||||
@echo $(DL)#define SIZEOF_STRUCT_IN6_ADDR 16$(DL) >> $@
|
||||
ifdef ENABLE_IPV6
|
||||
@echo $(DL)#define ENABLE_IPV6 1$(DL) >> $@
|
||||
endif
|
||||
endif
|
||||
@echo $(DL)#define HAVE_ARPA_INET_H 1$(DL) >> $@
|
||||
@echo $(DL)#define HAVE_ASSERT_H 1$(DL) >> $@
|
||||
@echo $(DL)#define HAVE_CTYPE_H 1$(DL) >> $@
|
||||
@echo $(DL)#define HAVE_ERR_H 1$(DL) >> $@
|
||||
@echo $(DL)#define HAVE_ERRNO_H 1$(DL) >> $@
|
||||
@echo $(DL)#define HAVE_FCNTL_H 1$(DL) >> $@
|
||||
@echo $(DL)#define HAVE_FIONBIO 1$(DL) >> $@
|
||||
@echo $(DL)#define HAVE_GETHOSTBYADDR 1$(DL) >> $@
|
||||
@echo $(DL)#define HAVE_GETHOSTBYNAME 1$(DL) >> $@
|
||||
@echo $(DL)#define HAVE_GETPROTOBYNAME 1$(DL) >> $@
|
||||
@echo $(DL)#define HAVE_GMTIME_R 1$(DL) >> $@
|
||||
@echo $(DL)#define HAVE_INET_ADDR 1$(DL) >> $@
|
||||
@echo $(DL)#define HAVE_INET_NTOA 1$(DL) >> $@
|
||||
@echo $(DL)#define HAVE_LL 1$(DL) >> $@
|
||||
@echo $(DL)#define HAVE_LOCALTIME_R 1$(DL) >> $@
|
||||
@echo $(DL)#define HAVE_MALLOC_H 1$(DL) >> $@
|
||||
@echo $(DL)#define HAVE_NETINET_IN_H 1$(DL) >> $@
|
||||
@echo $(DL)#define HAVE_SELECT 1$(DL) >> $@
|
||||
@echo $(DL)#define HAVE_SETJMP_H 1$(DL) >> $@
|
||||
@echo $(DL)#define HAVE_SIGNAL 1$(DL) >> $@
|
||||
@echo $(DL)#define HAVE_SIGNAL_H 1$(DL) >> $@
|
||||
@echo $(DL)#define HAVE_SIG_ATOMIC_T 1$(DL) >> $@
|
||||
@echo $(DL)#define HAVE_SOCKET 1$(DL) >> $@
|
||||
@echo $(DL)#define HAVE_STDLIB_H 1$(DL) >> $@
|
||||
@echo $(DL)#define HAVE_STRDUP 1$(DL) >> $@
|
||||
@echo $(DL)#define HAVE_STRFTIME 1$(DL) >> $@
|
||||
@echo $(DL)#define HAVE_STRING_H 1$(DL) >> $@
|
||||
@echo $(DL)#define HAVE_STRSTR 1$(DL) >> $@
|
||||
@echo $(DL)#define HAVE_STRUCT_ADDRINFO 1$(DL) >> $@
|
||||
@echo $(DL)#define HAVE_STRUCT_TIMEVAL 1$(DL) >> $@
|
||||
@echo $(DL)#define HAVE_SYS_IOCTL_H 1$(DL) >> $@
|
||||
@echo $(DL)#define HAVE_SYS_STAT_H 1$(DL) >> $@
|
||||
@echo $(DL)#define HAVE_SYS_TIME_H 1$(DL) >> $@
|
||||
@echo $(DL)#define HAVE_TIME_H 1$(DL) >> $@
|
||||
@echo $(DL)#define HAVE_UNAME 1$(DL) >> $@
|
||||
@echo $(DL)#define HAVE_UNISTD_H 1$(DL) >> $@
|
||||
@echo $(DL)#define HAVE_UTIME 1$(DL) >> $@
|
||||
@echo $(DL)#define HAVE_UTIME_H 1$(DL) >> $@
|
||||
@echo $(DL)#define RETSIGTYPE void$(DL) >> $@
|
||||
@echo $(DL)#define SIZEOF_STRUCT_IN_ADDR 4$(DL) >> $@
|
||||
@echo $(DL)#define STDC_HEADERS 1$(DL) >> $@
|
||||
@echo $(DL)#define TIME_WITH_SYS_TIME 1$(DL) >> $@
|
||||
@echo $(DL)#define USE_SSLEAY 1$(DL) >> $@
|
||||
@echo $(DL)#define USE_OPENSSL 1$(DL) >> $@
|
||||
@echo $(DL)#define HAVE_OPENSSL_X509_H 1$(DL) >> $@
|
||||
@echo $(DL)#define HAVE_OPENSSL_SSL_H 1$(DL) >> $@
|
||||
@echo $(DL)#define HAVE_OPENSSL_RSA_H 1$(DL) >> $@
|
||||
@echo $(DL)#define HAVE_OPENSSL_PEM_H 1$(DL) >> $@
|
||||
@echo $(DL)#define HAVE_OPENSSL_ERR_H 1$(DL) >> $@
|
||||
@echo $(DL)#define HAVE_OPENSSL_CRYPTO_H 1$(DL) >> $@
|
||||
@echo $(DL)#define HAVE_OPENSSL_ENGINE_H 1$(DL) >> $@
|
||||
@echo $(DL)#define HAVE_O_NONBLOCK 1$(DL) >> $@
|
||||
@echo $(DL)#define HAVE_LIBSSL 1$(DL) >> $@
|
||||
@echo $(DL)#define HAVE_LIBCRYPTO 1$(DL) >> $@
|
||||
@echo $(DL)#define OPENSSL_NO_KRB5 1$(DL) >> $@
|
||||
ifdef WITH_ZLIB
|
||||
@echo $(DL)#define HAVE_ZLIB_H 1$(DL) >> $@
|
||||
@echo $(DL)#define HAVE_LIBZ 1$(DL) >> $@
|
||||
@echo $(DL)#define LIBSSH2_HAVE_ZLIB 1$(DL) >> $@
|
||||
endif
|
||||
ifdef NW_WINSOCK
|
||||
@echo $(DL)#define HAVE_CLOSESOCKET 1$(DL) >> $@
|
||||
else
|
||||
@echo $(DL)#define HAVE_SYS_TYPES_H 1$(DL) >> $@
|
||||
@echo $(DL)#define HAVE_SYS_SOCKET_H 1$(DL) >> $@
|
||||
@echo $(DL)#define HAVE_SYS_SOCKIO_H 1$(DL) >> $@
|
||||
@echo $(DL)#define HAVE_NETDB_H 1$(DL) >> $@
|
||||
endif
|
||||
ifdef OLD_NOVELLSDK
|
||||
@echo $(DL)#define socklen_t int$(DL) >> $@
|
||||
endif
|
||||
@echo $(DL)#define LIBSSH2_DH_GEX_NEW 1$(DL) >> $@
|
||||
ifeq ($(DB),DEBUG)
|
||||
@echo $(DL)#define LIBSSH2_DEBUG_CONNECTION 1$(DL) >> $@
|
||||
@echo $(DL)#define LIBSSH2_DEBUG_ERRORS 1$(DL) >> $@
|
||||
@echo $(DL)#define LIBSSH2_DEBUG_KEX 1$(DL) >> $@
|
||||
@echo $(DL)#define LIBSSH2_DEBUG_PUBLICKEY 1$(DL) >> $@
|
||||
@echo $(DL)#define LIBSSH2_DEBUG_SCP 1$(DL) >> $@
|
||||
@echo $(DL)#define LIBSSH2_DEBUG_SFTP 1$(DL) >> $@
|
||||
@echo $(DL)#define LIBSSH2_DEBUG_TRANSPORT 1$(DL) >> $@
|
||||
@echo $(DL)#define LIBSSH2_DEBUG_USERAUTH 1$(DL) >> $@
|
||||
endif
|
||||
|
||||
help: $(OBJDIR)/version.inc
|
||||
@echo $(DL)===========================================================$(DL)
|
||||
@echo $(DL)OpenSSL path = $(OPENSSL_PATH)$(DL)
|
||||
|
@@ -5,6 +5,8 @@
|
||||
*.dll
|
||||
*.exe
|
||||
*.obj
|
||||
*.gcno
|
||||
*.gcda
|
||||
.*.swp
|
||||
Debug
|
||||
Release
|
||||
|
@@ -1,12 +1,12 @@
|
||||
# $Id: Makefile.am,v 1.10 2007/07/17 13:22:55 gknauf Exp $
|
||||
# $Id: Makefile.am,v 1.13 2008/11/21 14:34:03 jas4711 Exp $
|
||||
AUTOMAKE_OPTIONS = foreign nostdinc
|
||||
|
||||
libssh2_la_SOURCES = channel.c comp.c crypt.c hostkey.c kex.c mac.c \
|
||||
misc.c packet.c publickey.c scp.c session.c sftp.c userauth.c \
|
||||
libssh2_priv.h openssl.h libgcrypt.h pem.c transport.c
|
||||
libssh2_priv.h openssl.h libgcrypt.h transport.c
|
||||
|
||||
if LIBGCRYPT
|
||||
libssh2_la_SOURCES += libgcrypt.c
|
||||
libssh2_la_SOURCES += libgcrypt.c pem.c
|
||||
else
|
||||
libssh2_la_SOURCES += openssl.c
|
||||
endif
|
||||
@@ -18,7 +18,7 @@ lib_LTLIBRARIES = libssh2.la
|
||||
# srcdir/include for the shipped headers
|
||||
# builddir/src for the generated config header when building out of the source
|
||||
# tree
|
||||
INCLUDES = -I$(top_srcdir)/include -I$(top_builddir)/src
|
||||
AM_CPPFLAGS = -I$(top_srcdir)/include -I$(top_builddir)/src
|
||||
|
||||
VERSION=-version-info 1:0:0
|
||||
|
||||
@@ -50,4 +50,5 @@ VERSION=-version-info 1:0:0
|
||||
# set age to 0. (c:r:a=0)
|
||||
#
|
||||
|
||||
libssh2_la_LDFLAGS = $(VERSION) -no-undefined $(LTLIBGCRYPT)
|
||||
libssh2_la_LDFLAGS = $(VERSION) -no-undefined \
|
||||
$(LTLIBGCRYPT) $(LTLIBSSL) $(LTLIBZ)
|
||||
|
1090
src/channel.c
1090
src/channel.c
File diff suppressed because it is too large
Load Diff
74
src/comp.c
74
src/comp.c
@@ -47,15 +47,15 @@
|
||||
/* {{{ libssh2_comp_method_none_comp
|
||||
* Minimalist compression: Absolutely none
|
||||
*/
|
||||
static int libssh2_comp_method_none_comp(LIBSSH2_SESSION *session,
|
||||
static int
|
||||
libssh2_comp_method_none_comp(LIBSSH2_SESSION * session,
|
||||
int compress,
|
||||
unsigned char **dest,
|
||||
unsigned long *dest_len,
|
||||
unsigned long payload_limit,
|
||||
int *free_dest,
|
||||
const unsigned char *src,
|
||||
unsigned long src_len,
|
||||
void **abstract)
|
||||
unsigned long src_len, void **abstract)
|
||||
{
|
||||
(void) session;
|
||||
(void) compress;
|
||||
@@ -68,6 +68,7 @@ static int libssh2_comp_method_none_comp(LIBSSH2_SESSION *session,
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* }}} */
|
||||
|
||||
static const LIBSSH2_COMP_METHOD libssh2_comp_method_none = {
|
||||
@@ -87,32 +88,39 @@ static const LIBSSH2_COMP_METHOD libssh2_comp_method_none = {
|
||||
* Deal...
|
||||
*/
|
||||
|
||||
static voidpf libssh2_comp_method_zlib_alloc(voidpf opaque, uInt items, uInt size)
|
||||
static voidpf
|
||||
libssh2_comp_method_zlib_alloc(voidpf opaque, uInt items, uInt size)
|
||||
{
|
||||
LIBSSH2_SESSION *session = (LIBSSH2_SESSION *) opaque;
|
||||
|
||||
return (voidpf) LIBSSH2_ALLOC(session, items * size);
|
||||
}
|
||||
|
||||
static void libssh2_comp_method_zlib_free(voidpf opaque, voidpf address)
|
||||
static void
|
||||
libssh2_comp_method_zlib_free(voidpf opaque, voidpf address)
|
||||
{
|
||||
LIBSSH2_SESSION *session = (LIBSSH2_SESSION *) opaque;
|
||||
|
||||
LIBSSH2_FREE(session, address);
|
||||
}
|
||||
|
||||
/* }}} */
|
||||
|
||||
/* {{{ libssh2_comp_method_zlib_init
|
||||
* All your bandwidth are belong to us (so save some)
|
||||
*/
|
||||
static int libssh2_comp_method_zlib_init(LIBSSH2_SESSION *session, int compress, void **abstract)
|
||||
static int
|
||||
libssh2_comp_method_zlib_init(LIBSSH2_SESSION * session, int compress,
|
||||
void **abstract)
|
||||
{
|
||||
z_stream *strm;
|
||||
int status;
|
||||
|
||||
strm = LIBSSH2_ALLOC(session, sizeof(z_stream));
|
||||
if (!strm) {
|
||||
libssh2_error(session, LIBSSH2_ERROR_ALLOC, "Unable to allocate memory for zlib compression/decompression", 0);
|
||||
libssh2_error(session, LIBSSH2_ERROR_ALLOC,
|
||||
"Unable to allocate memory for zlib compression/decompression",
|
||||
0);
|
||||
return -1;
|
||||
}
|
||||
memset(strm, 0, sizeof(z_stream));
|
||||
@@ -136,20 +144,21 @@ static int libssh2_comp_method_zlib_init(LIBSSH2_SESSION *session, int compress,
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* }}} */
|
||||
|
||||
/* {{{ libssh2_comp_method_zlib_comp
|
||||
* zlib, a compression standard for all occasions
|
||||
*/
|
||||
static int libssh2_comp_method_zlib_comp(LIBSSH2_SESSION *session,
|
||||
static int
|
||||
libssh2_comp_method_zlib_comp(LIBSSH2_SESSION * session,
|
||||
int compress,
|
||||
unsigned char **dest,
|
||||
unsigned long *dest_len,
|
||||
unsigned long payload_limit,
|
||||
int *free_dest,
|
||||
const unsigned char *src,
|
||||
unsigned long src_len,
|
||||
void **abstract)
|
||||
unsigned long src_len, void **abstract)
|
||||
{
|
||||
z_stream *strm = *abstract;
|
||||
/* A short-term alloc of a full data chunk is better than a series of
|
||||
@@ -173,7 +182,9 @@ static int libssh2_comp_method_zlib_comp(LIBSSH2_SESSION *session,
|
||||
out = (char *) strm->next_out;
|
||||
strm->avail_out = out_maxlen;
|
||||
if (!strm->next_out) {
|
||||
libssh2_error(session, LIBSSH2_ERROR_ALLOC, "Unable to allocate compression/decompression buffer", 0);
|
||||
libssh2_error(session, LIBSSH2_ERROR_ALLOC,
|
||||
"Unable to allocate compression/decompression buffer",
|
||||
0);
|
||||
return -1;
|
||||
}
|
||||
while (strm->avail_in) {
|
||||
@@ -185,7 +196,8 @@ static int libssh2_comp_method_zlib_comp(LIBSSH2_SESSION *session,
|
||||
status = inflate(strm, Z_PARTIAL_FLUSH);
|
||||
}
|
||||
if (status != Z_OK) {
|
||||
libssh2_error(session, LIBSSH2_ERROR_ZLIB, "compress/decompression failure", 0);
|
||||
libssh2_error(session, LIBSSH2_ERROR_ZLIB,
|
||||
"compress/decompression failure", 0);
|
||||
LIBSSH2_FREE(session, out);
|
||||
return -1;
|
||||
}
|
||||
@@ -193,10 +205,10 @@ static int libssh2_comp_method_zlib_comp(LIBSSH2_SESSION *session,
|
||||
unsigned long out_ofs = out_maxlen - strm->avail_out;
|
||||
char *newout;
|
||||
|
||||
out_maxlen += compress ? (strm->avail_in + 4) : (2 * strm->avail_in);
|
||||
out_maxlen +=
|
||||
compress ? (strm->avail_in + 4) : (2 * strm->avail_in);
|
||||
|
||||
if ((out_maxlen > (int)payload_limit) &&
|
||||
!compress && limiter++) {
|
||||
if ((out_maxlen > (int) payload_limit) && !compress && limiter++) {
|
||||
libssh2_error(session, LIBSSH2_ERROR_ZLIB,
|
||||
"Excessive growth in decompression phase", 0);
|
||||
LIBSSH2_FREE(session, out);
|
||||
@@ -205,14 +217,18 @@ static int libssh2_comp_method_zlib_comp(LIBSSH2_SESSION *session,
|
||||
|
||||
newout = LIBSSH2_REALLOC(session, out, out_maxlen);
|
||||
if (!newout) {
|
||||
libssh2_error(session, LIBSSH2_ERROR_ALLOC, "Unable to expand compress/decompression buffer", 0);
|
||||
libssh2_error(session, LIBSSH2_ERROR_ALLOC,
|
||||
"Unable to expand compress/decompression buffer",
|
||||
0);
|
||||
LIBSSH2_FREE(session, out);
|
||||
return -1;
|
||||
}
|
||||
out = newout;
|
||||
strm->next_out = (unsigned char *) out + out_ofs;
|
||||
strm->avail_out += compress ? (strm->avail_in + 4) : (2 * strm->avail_in);
|
||||
} else while (!strm->avail_out) {
|
||||
strm->avail_out +=
|
||||
compress ? (strm->avail_in + 4) : (2 * 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
|
||||
*/
|
||||
@@ -220,7 +236,9 @@ static int libssh2_comp_method_zlib_comp(LIBSSH2_SESSION *session,
|
||||
char *newout;
|
||||
|
||||
if (out_maxlen >= (int) payload_limit) {
|
||||
libssh2_error(session, LIBSSH2_ERROR_ZLIB, "Excessive growth in decompression phase", 0);
|
||||
libssh2_error(session, LIBSSH2_ERROR_ZLIB,
|
||||
"Excessive growth in decompression phase",
|
||||
0);
|
||||
LIBSSH2_FREE(session, out);
|
||||
return -1;
|
||||
}
|
||||
@@ -234,7 +252,9 @@ static int libssh2_comp_method_zlib_comp(LIBSSH2_SESSION *session,
|
||||
|
||||
newout = LIBSSH2_REALLOC(session, out, out_maxlen);
|
||||
if (!newout) {
|
||||
libssh2_error(session, LIBSSH2_ERROR_ALLOC, "Unable to expand final compress/decompress buffer", 0);
|
||||
libssh2_error(session, LIBSSH2_ERROR_ALLOC,
|
||||
"Unable to expand final compress/decompress buffer",
|
||||
0);
|
||||
LIBSSH2_FREE(session, out);
|
||||
return -1;
|
||||
}
|
||||
@@ -248,7 +268,8 @@ static int libssh2_comp_method_zlib_comp(LIBSSH2_SESSION *session,
|
||||
status = inflate(strm, Z_PARTIAL_FLUSH);
|
||||
}
|
||||
if (status != Z_OK) {
|
||||
libssh2_error(session, LIBSSH2_ERROR_ZLIB, "compress/decompression failure", 0);
|
||||
libssh2_error(session, LIBSSH2_ERROR_ZLIB,
|
||||
"compress/decompression failure", 0);
|
||||
LIBSSH2_FREE(session, out);
|
||||
return -1;
|
||||
}
|
||||
@@ -261,12 +282,15 @@ static int libssh2_comp_method_zlib_comp(LIBSSH2_SESSION *session,
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* }}} */
|
||||
|
||||
/* {{{ libssh2_comp_method_zlib_dtor
|
||||
* All done, no more compression for you
|
||||
*/
|
||||
static int libssh2_comp_method_zlib_dtor(LIBSSH2_SESSION *session, int compress, void **abstract)
|
||||
static int
|
||||
libssh2_comp_method_zlib_dtor(LIBSSH2_SESSION * session, int compress,
|
||||
void **abstract)
|
||||
{
|
||||
z_stream *strm = *abstract;
|
||||
|
||||
@@ -286,6 +310,7 @@ static int libssh2_comp_method_zlib_dtor(LIBSSH2_SESSION *session, int compress,
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* }}} */
|
||||
|
||||
static const LIBSSH2_COMP_METHOD libssh2_comp_method_zlib = {
|
||||
@@ -308,7 +333,8 @@ static const LIBSSH2_COMP_METHOD *_libssh2_comp_methods[] = {
|
||||
NULL
|
||||
};
|
||||
|
||||
const LIBSSH2_COMP_METHOD **libssh2_comp_methods(void) {
|
||||
const LIBSSH2_COMP_METHOD **
|
||||
libssh2_comp_methods(void)
|
||||
{
|
||||
return _libssh2_comp_methods;
|
||||
}
|
||||
|
||||
|
31
src/crypt.c
31
src/crypt.c
@@ -41,11 +41,14 @@
|
||||
/* {{{ libssh2_crypt_none_crypt
|
||||
* Minimalist cipher: VERY secure *wink*
|
||||
*/
|
||||
static int libssh2_crypt_none_crypt(LIBSSH2_SESSION *session, unsigned char *buf, void **abstract)
|
||||
static int
|
||||
libssh2_crypt_none_crypt(LIBSSH2_SESSION * session, unsigned char *buf,
|
||||
void **abstract)
|
||||
{
|
||||
/* Do nothing to the data! */
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* }}} */
|
||||
|
||||
static const LIBSSH2_CRYPT_METHOD libssh2_crypt_method_none = {
|
||||
@@ -60,13 +63,15 @@ static const LIBSSH2_CRYPT_METHOD libssh2_crypt_method_none = {
|
||||
};
|
||||
#endif /* LIBSSH2_CRYPT_NONE */
|
||||
|
||||
struct crypt_ctx {
|
||||
struct crypt_ctx
|
||||
{
|
||||
int encrypt;
|
||||
_libssh2_cipher_type(algo);
|
||||
_libssh2_cipher_ctx h;
|
||||
};
|
||||
|
||||
static int _libssh2_init (LIBSSH2_SESSION *session,
|
||||
static int
|
||||
_libssh2_init(LIBSSH2_SESSION * session,
|
||||
const LIBSSH2_CRYPT_METHOD * method,
|
||||
unsigned char *iv, int *free_iv,
|
||||
unsigned char *secret, int *free_secret,
|
||||
@@ -79,8 +84,7 @@ static int _libssh2_init (LIBSSH2_SESSION *session,
|
||||
}
|
||||
ctx->encrypt = encrypt;
|
||||
ctx->algo = method->algo;
|
||||
if (_libssh2_cipher_init (&ctx->h, ctx->algo, iv, secret, encrypt))
|
||||
{
|
||||
if (_libssh2_cipher_init(&ctx->h, ctx->algo, iv, secret, encrypt)) {
|
||||
LIBSSH2_FREE(session, ctx);
|
||||
return -1;
|
||||
}
|
||||
@@ -90,15 +94,17 @@ static int _libssh2_init (LIBSSH2_SESSION *session,
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int _libssh2_encrypt(LIBSSH2_SESSION *session, unsigned char *block, void **abstract)
|
||||
static int
|
||||
_libssh2_encrypt(LIBSSH2_SESSION * session, unsigned char *block,
|
||||
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);
|
||||
}
|
||||
|
||||
static int _libssh2_dtor(LIBSSH2_SESSION *session, void **abstract)
|
||||
static int
|
||||
_libssh2_dtor(LIBSSH2_SESSION * session, void **abstract)
|
||||
{
|
||||
struct crypt_ctx **cctx = (struct crypt_ctx **) abstract;
|
||||
if (cctx && *cctx) {
|
||||
@@ -147,7 +153,8 @@ static const LIBSSH2_CRYPT_METHOD libssh2_crypt_method_aes256_cbc = {
|
||||
};
|
||||
|
||||
/* rijndael-cbc@lysator.liu.se == aes256-cbc */
|
||||
static const LIBSSH2_CRYPT_METHOD libssh2_crypt_method_rijndael_cbc_lysator_liu_se = {
|
||||
static const LIBSSH2_CRYPT_METHOD
|
||||
libssh2_crypt_method_rijndael_cbc_lysator_liu_se = {
|
||||
"rijndael-cbc@lysator.liu.se",
|
||||
16, /* blocksize */
|
||||
16, /* initial value length */
|
||||
@@ -242,6 +249,8 @@ static const LIBSSH2_CRYPT_METHOD *_libssh2_crypt_methods[] = {
|
||||
};
|
||||
|
||||
/* Expose to kex.c */
|
||||
const LIBSSH2_CRYPT_METHOD **libssh2_crypt_methods(void) {
|
||||
const LIBSSH2_CRYPT_METHOD **
|
||||
libssh2_crypt_methods(void)
|
||||
{
|
||||
return _libssh2_crypt_methods;
|
||||
}
|
||||
|
130
src/hostkey.c
130
src/hostkey.c
@@ -47,7 +47,8 @@
|
||||
* ssh-rsa *
|
||||
*********** */
|
||||
|
||||
static int libssh2_hostkey_method_ssh_rsa_dtor(LIBSSH2_SESSION *session, void **abstract);
|
||||
static int libssh2_hostkey_method_ssh_rsa_dtor(LIBSSH2_SESSION * session,
|
||||
void **abstract);
|
||||
|
||||
/* {{{ libssh2_hostkey_method_ssh_rsa_init
|
||||
* Initialize the server hostkey working area with e/n pair
|
||||
@@ -81,9 +82,12 @@ libssh2_hostkey_method_ssh_rsa_init(LIBSSH2_SESSION *session,
|
||||
e_len = libssh2_ntohu32(s);
|
||||
s += 4;
|
||||
|
||||
e = s; s += e_len;
|
||||
n_len = libssh2_ntohu32(s); s += 4;
|
||||
n = s; s += n_len;
|
||||
e = s;
|
||||
s += e_len;
|
||||
n_len = libssh2_ntohu32(s);
|
||||
s += 4;
|
||||
n = s;
|
||||
s += n_len;
|
||||
|
||||
if (_libssh2_rsa_new(&rsactx, e, e_len, n, n_len, NULL, 0,
|
||||
NULL, 0, NULL, 0, NULL, 0, NULL, 0, NULL, 0))
|
||||
@@ -93,13 +97,17 @@ libssh2_hostkey_method_ssh_rsa_init(LIBSSH2_SESSION *session,
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* }}} */
|
||||
|
||||
/* {{{ libssh2_hostkey_method_ssh_rsa_initPEM
|
||||
* Load a Private Key from a PEM file
|
||||
*/
|
||||
static int libssh2_hostkey_method_ssh_rsa_initPEM(LIBSSH2_SESSION *session,
|
||||
const char *privkeyfile, unsigned const char *passphrase, void **abstract)
|
||||
static int
|
||||
libssh2_hostkey_method_ssh_rsa_initPEM(LIBSSH2_SESSION * session,
|
||||
const char *privkeyfile,
|
||||
unsigned const char *passphrase,
|
||||
void **abstract)
|
||||
{
|
||||
libssh2_rsa_ctx *rsactx;
|
||||
FILE *fp;
|
||||
@@ -125,32 +133,40 @@ static int libssh2_hostkey_method_ssh_rsa_initPEM(LIBSSH2_SESSION *session,
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* }}} */
|
||||
|
||||
/* {{{ libssh2_hostkey_method_ssh_rsa_sign
|
||||
* Verify signature created by remote
|
||||
*/
|
||||
static int libssh2_hostkey_method_ssh_rsa_sig_verify(LIBSSH2_SESSION *session,
|
||||
static int
|
||||
libssh2_hostkey_method_ssh_rsa_sig_verify(LIBSSH2_SESSION * session,
|
||||
const unsigned char *sig,
|
||||
unsigned long sig_len,
|
||||
const unsigned char *m,
|
||||
unsigned long m_len,
|
||||
void **abstract)
|
||||
unsigned long m_len, void **abstract)
|
||||
{
|
||||
libssh2_rsa_ctx *rsactx = (libssh2_rsa_ctx *) (*abstract);
|
||||
(void) session;
|
||||
|
||||
/* Skip past keyname_len(4) + keyname(7){"ssh-rsa"} + signature_len(4) */
|
||||
sig += 15; sig_len -= 15;
|
||||
sig += 15;
|
||||
sig_len -= 15;
|
||||
return _libssh2_rsa_sha1_verify(rsactx, sig, sig_len, m, m_len);
|
||||
}
|
||||
|
||||
/* }}} */
|
||||
|
||||
/* {{{ libssh2_hostkey_method_ssh_rsa_signv
|
||||
* Construct a signature from an array of vectors
|
||||
*/
|
||||
static int libssh2_hostkey_method_ssh_rsa_signv(LIBSSH2_SESSION *session, unsigned char **signature, unsigned long *signature_len,
|
||||
unsigned long veccount, const struct iovec datavec[], void **abstract)
|
||||
static int
|
||||
libssh2_hostkey_method_ssh_rsa_signv(LIBSSH2_SESSION * session,
|
||||
unsigned char **signature,
|
||||
unsigned long *signature_len,
|
||||
unsigned long veccount,
|
||||
const struct iovec datavec[],
|
||||
void **abstract)
|
||||
{
|
||||
libssh2_rsa_ctx *rsactx = (libssh2_rsa_ctx *) (*abstract);
|
||||
int ret;
|
||||
@@ -172,13 +188,14 @@ static int libssh2_hostkey_method_ssh_rsa_signv(LIBSSH2_SESSION *session, unsign
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* }}} */
|
||||
|
||||
/* {{{ libssh2_hostkey_method_ssh_rsa_dtor
|
||||
* Shutdown the hostkey
|
||||
*/
|
||||
static int libssh2_hostkey_method_ssh_rsa_dtor(LIBSSH2_SESSION *session,
|
||||
void **abstract)
|
||||
static int
|
||||
libssh2_hostkey_method_ssh_rsa_dtor(LIBSSH2_SESSION * session, void **abstract)
|
||||
{
|
||||
libssh2_rsa_ctx *rsactx = (libssh2_rsa_ctx *) (*abstract);
|
||||
(void) session;
|
||||
@@ -189,6 +206,7 @@ static int libssh2_hostkey_method_ssh_rsa_dtor(LIBSSH2_SESSION *session,
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* }}} */
|
||||
|
||||
static const LIBSSH2_HOSTKEY_METHOD libssh2_hostkey_method_ssh_rsa = {
|
||||
@@ -208,7 +226,8 @@ static const LIBSSH2_HOSTKEY_METHOD libssh2_hostkey_method_ssh_rsa = {
|
||||
* ssh-dss *
|
||||
*********** */
|
||||
|
||||
static int libssh2_hostkey_method_ssh_dss_dtor(LIBSSH2_SESSION *session, void **abstract);
|
||||
static int libssh2_hostkey_method_ssh_dss_dtor(LIBSSH2_SESSION * session,
|
||||
void **abstract);
|
||||
|
||||
/* {{{ libssh2_hostkey_method_ssh_dss_init
|
||||
* Initialize the server hostkey working area with p/q/g/y set
|
||||
@@ -230,33 +249,44 @@ libssh2_hostkey_method_ssh_dss_init(LIBSSH2_SESSION *session,
|
||||
}
|
||||
|
||||
s = hostkey_data;
|
||||
len = libssh2_ntohu32(s); s += 4;
|
||||
len = libssh2_ntohu32(s);
|
||||
s += 4;
|
||||
if (len != 7 || strncmp((char *) s, "ssh-dss", 7) != 0) {
|
||||
return -1;
|
||||
} s += 7;
|
||||
}
|
||||
s += 7;
|
||||
|
||||
p_len = libssh2_ntohu32(s); s += 4;
|
||||
p = s; s += p_len;
|
||||
q_len = libssh2_ntohu32(s); s += 4;
|
||||
q = s; s += q_len;
|
||||
g_len = libssh2_ntohu32(s); s += 4;
|
||||
g = s; s += g_len;
|
||||
y_len = libssh2_ntohu32(s); s += 4;
|
||||
y = s; s += y_len;
|
||||
p_len = libssh2_ntohu32(s);
|
||||
s += 4;
|
||||
p = s;
|
||||
s += p_len;
|
||||
q_len = libssh2_ntohu32(s);
|
||||
s += 4;
|
||||
q = s;
|
||||
s += q_len;
|
||||
g_len = libssh2_ntohu32(s);
|
||||
s += 4;
|
||||
g = s;
|
||||
s += g_len;
|
||||
y_len = libssh2_ntohu32(s);
|
||||
s += 4;
|
||||
y = s;
|
||||
s += y_len;
|
||||
|
||||
_libssh2_dsa_new(&dsactx, p, p_len, q, q_len, g, g_len,
|
||||
y, y_len, NULL, 0);
|
||||
_libssh2_dsa_new(&dsactx, p, p_len, q, q_len, g, g_len, y, y_len, NULL, 0);
|
||||
|
||||
*abstract = dsactx;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* }}} */
|
||||
|
||||
/* {{{ libssh2_hostkey_method_ssh_dss_initPEM
|
||||
* Load a Private Key from a PEM file
|
||||
*/
|
||||
static int libssh2_hostkey_method_ssh_dss_initPEM(LIBSSH2_SESSION *session,
|
||||
static int
|
||||
libssh2_hostkey_method_ssh_dss_initPEM(LIBSSH2_SESSION * session,
|
||||
const char *privkeyfile,
|
||||
unsigned const char *passphrase,
|
||||
void **abstract)
|
||||
@@ -285,31 +315,44 @@ static int libssh2_hostkey_method_ssh_dss_initPEM(LIBSSH2_SESSION *session,
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* }}} */
|
||||
|
||||
/* {{{ libssh2_hostkey_method_ssh_dss_sign
|
||||
* Verify signature created by remote
|
||||
*/
|
||||
static int libssh2_hostkey_method_ssh_dss_sig_verify(LIBSSH2_SESSION *session, const unsigned char *sig, unsigned long sig_len,
|
||||
const unsigned char *m, unsigned long m_len, void **abstract)
|
||||
static int
|
||||
libssh2_hostkey_method_ssh_dss_sig_verify(LIBSSH2_SESSION * session,
|
||||
const unsigned char *sig,
|
||||
unsigned long sig_len,
|
||||
const unsigned char *m,
|
||||
unsigned long m_len, void **abstract)
|
||||
{
|
||||
libssh2_dsa_ctx *dsactx = (libssh2_dsa_ctx *) (*abstract);
|
||||
|
||||
/* Skip past keyname_len(4) + keyname(7){"ssh-dss"} + signature_len(4) */
|
||||
sig += 15; sig_len -= 15;
|
||||
sig += 15;
|
||||
sig_len -= 15;
|
||||
if (sig_len != 40) {
|
||||
libssh2_error(session, LIBSSH2_ERROR_PROTO, "Invalid DSS signature length", 0);
|
||||
libssh2_error(session, LIBSSH2_ERROR_PROTO,
|
||||
"Invalid DSS signature length", 0);
|
||||
return -1;
|
||||
}
|
||||
return _libssh2_dsa_sha1_verify(dsactx, sig, m, m_len);
|
||||
}
|
||||
|
||||
/* }}} */
|
||||
|
||||
/* {{{ libssh2_hostkey_method_ssh_dss_signv
|
||||
* Construct a signature from an array of vectors
|
||||
*/
|
||||
static int libssh2_hostkey_method_ssh_dss_signv(LIBSSH2_SESSION *session, unsigned char **signature, unsigned long *signature_len,
|
||||
unsigned long veccount, const struct iovec datavec[], void **abstract)
|
||||
static int
|
||||
libssh2_hostkey_method_ssh_dss_signv(LIBSSH2_SESSION * session,
|
||||
unsigned char **signature,
|
||||
unsigned long *signature_len,
|
||||
unsigned long veccount,
|
||||
const struct iovec datavec[],
|
||||
void **abstract)
|
||||
{
|
||||
libssh2_dsa_ctx *dsactx = (libssh2_dsa_ctx *) (*abstract);
|
||||
unsigned char hash[SHA_DIGEST_LENGTH];
|
||||
@@ -330,22 +373,21 @@ static int libssh2_hostkey_method_ssh_dss_signv(LIBSSH2_SESSION *session, unsign
|
||||
}
|
||||
libssh2_sha1_final(ctx, hash);
|
||||
|
||||
if (_libssh2_dsa_sha1_sign(dsactx, hash, SHA_DIGEST_LENGTH,
|
||||
*signature))
|
||||
{
|
||||
if (_libssh2_dsa_sha1_sign(dsactx, hash, SHA_DIGEST_LENGTH, *signature)) {
|
||||
LIBSSH2_FREE(session, *signature);
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* }}} */
|
||||
|
||||
/* {{{ libssh2_hostkey_method_ssh_dss_dtor
|
||||
* Shutdown the hostkey method
|
||||
*/
|
||||
static int libssh2_hostkey_method_ssh_dss_dtor(LIBSSH2_SESSION *session,
|
||||
void **abstract)
|
||||
static int
|
||||
libssh2_hostkey_method_ssh_dss_dtor(LIBSSH2_SESSION * session, void **abstract)
|
||||
{
|
||||
libssh2_dsa_ctx *dsactx = (libssh2_dsa_ctx *) (*abstract);
|
||||
(void) session;
|
||||
@@ -356,6 +398,7 @@ static int libssh2_hostkey_method_ssh_dss_dtor(LIBSSH2_SESSION *session,
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* }}} */
|
||||
|
||||
static const LIBSSH2_HOSTKEY_METHOD libssh2_hostkey_method_ssh_dss = {
|
||||
@@ -380,7 +423,8 @@ static const LIBSSH2_HOSTKEY_METHOD *_libssh2_hostkey_methods[] = {
|
||||
NULL
|
||||
};
|
||||
|
||||
const LIBSSH2_HOSTKEY_METHOD **libssh2_hostkey_methods(void)
|
||||
const LIBSSH2_HOSTKEY_METHOD **
|
||||
libssh2_hostkey_methods(void)
|
||||
{
|
||||
return _libssh2_hostkey_methods;
|
||||
}
|
||||
@@ -391,7 +435,8 @@ const LIBSSH2_HOSTKEY_METHOD **libssh2_hostkey_methods(void)
|
||||
* Length of buffer is determined by hash type
|
||||
* i.e. MD5 == 16, SHA1 == 20
|
||||
*/
|
||||
LIBSSH2_API const char *libssh2_hostkey_hash(LIBSSH2_SESSION *session, int hash_type)
|
||||
LIBSSH2_API const char *
|
||||
libssh2_hostkey_hash(LIBSSH2_SESSION * session, int hash_type)
|
||||
{
|
||||
switch (hash_type) {
|
||||
#if LIBSSH2_MD5
|
||||
@@ -406,6 +451,5 @@ LIBSSH2_API const char *libssh2_hostkey_hash(LIBSSH2_SESSION *session, int hash_
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
/* }}} */
|
||||
|
||||
|
||||
|
@@ -1,5 +1,6 @@
|
||||
/* Copyright (C) 2006, 2007 The Written Word, Inc. All rights reserved.
|
||||
* Author: Simon Josefsson
|
||||
/* Copyright (C) 2006, 2007, The Written Word, Inc.
|
||||
* Copyright (C) 2008, Simon Josefsson
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms,
|
||||
* with or without modification, are permitted provided
|
||||
@@ -38,7 +39,8 @@
|
||||
#include "libssh2_priv.h"
|
||||
#include <string.h>
|
||||
|
||||
int _libssh2_rsa_new(libssh2_rsa_ctx **rsa,
|
||||
int
|
||||
_libssh2_rsa_new(libssh2_rsa_ctx ** rsa,
|
||||
const unsigned char *edata,
|
||||
unsigned long elen,
|
||||
const unsigned char *ndata,
|
||||
@@ -53,8 +55,7 @@ int _libssh2_rsa_new(libssh2_rsa_ctx **rsa,
|
||||
unsigned long e1len,
|
||||
const unsigned char *e2data,
|
||||
unsigned long e2len,
|
||||
const unsigned char *coeffdata,
|
||||
unsigned long coefflen)
|
||||
const unsigned char *coeffdata, unsigned long coefflen)
|
||||
{
|
||||
int rc;
|
||||
(void) e1data;
|
||||
@@ -72,8 +73,7 @@ int _libssh2_rsa_new(libssh2_rsa_ctx **rsa,
|
||||
rc = gcry_sexp_build(rsa, NULL, "(public-key(rsa(n%b)(e%b)))",
|
||||
nlen, ndata, elen, edata);
|
||||
}
|
||||
if (rc)
|
||||
{
|
||||
if (rc) {
|
||||
*rsa = NULL;
|
||||
return -1;
|
||||
}
|
||||
@@ -81,11 +81,11 @@ int _libssh2_rsa_new(libssh2_rsa_ctx **rsa,
|
||||
return 0;
|
||||
}
|
||||
|
||||
int _libssh2_rsa_sha1_verify(libssh2_rsa_ctx *rsa,
|
||||
int
|
||||
_libssh2_rsa_sha1_verify(libssh2_rsa_ctx * rsa,
|
||||
const unsigned char *sig,
|
||||
unsigned long sig_len,
|
||||
const unsigned char *m,
|
||||
unsigned long m_len)
|
||||
const unsigned char *m, unsigned long m_len)
|
||||
{
|
||||
unsigned char hash[SHA_DIGEST_LENGTH];
|
||||
gcry_sexp_t s_sig, s_hash;
|
||||
@@ -100,8 +100,7 @@ int _libssh2_rsa_sha1_verify(libssh2_rsa_ctx *rsa,
|
||||
return -1;
|
||||
}
|
||||
|
||||
rc = gcry_sexp_build (&s_sig, NULL, "(sig-val(rsa(s %b)))",
|
||||
sig_len, sig);
|
||||
rc = gcry_sexp_build(&s_sig, NULL, "(sig-val(rsa(s %b)))", sig_len, sig);
|
||||
if (rc != 0) {
|
||||
gcry_sexp_release(s_hash);
|
||||
return -1;
|
||||
@@ -114,7 +113,8 @@ int _libssh2_rsa_sha1_verify(libssh2_rsa_ctx *rsa,
|
||||
return (rc == 0) ? 0 : -1;
|
||||
}
|
||||
|
||||
int _libssh2_dsa_new(libssh2_dsa_ctx **dsactx,
|
||||
int
|
||||
_libssh2_dsa_new(libssh2_dsa_ctx ** dsactx,
|
||||
const unsigned char *p,
|
||||
unsigned long p_len,
|
||||
const unsigned char *q,
|
||||
@@ -123,8 +123,7 @@ int _libssh2_dsa_new(libssh2_dsa_ctx **dsactx,
|
||||
unsigned long g_len,
|
||||
const unsigned char *y,
|
||||
unsigned long y_len,
|
||||
const unsigned char *x,
|
||||
unsigned long x_len)
|
||||
const unsigned char *x, unsigned long x_len)
|
||||
{
|
||||
int rc;
|
||||
|
||||
@@ -147,15 +146,15 @@ int _libssh2_dsa_new(libssh2_dsa_ctx **dsactx,
|
||||
return 0;
|
||||
}
|
||||
|
||||
int _libssh2_rsa_new_private (libssh2_rsa_ctx **rsa,
|
||||
int
|
||||
_libssh2_rsa_new_private(libssh2_rsa_ctx ** rsa,
|
||||
LIBSSH2_SESSION * session,
|
||||
FILE *fp,
|
||||
unsigned const char *passphrase)
|
||||
FILE * fp, unsigned const char *passphrase)
|
||||
{
|
||||
char *data, *save_data;
|
||||
unsigned char *data, *save_data;
|
||||
unsigned int datalen;
|
||||
int ret;
|
||||
char *n, *e, *d, *p, *q, *e1, *e2, *coeff;
|
||||
unsigned char *n, *e, *d, *p, *q, *e1, *e2, *coeff;
|
||||
unsigned int nlen, elen, dlen, plen, qlen, e1len, e2len, coefflen;
|
||||
|
||||
(void) passphrase;
|
||||
@@ -230,8 +229,7 @@ int _libssh2_rsa_new_private (libssh2_rsa_ctx **rsa,
|
||||
}
|
||||
|
||||
if (_libssh2_rsa_new(rsa, e, elen, n, nlen, d, dlen, p, plen,
|
||||
q, qlen, e1, e1len, e2, e2len,
|
||||
coeff, coefflen)) {
|
||||
q, qlen, e1, e1len, e2, e2len, coeff, coefflen)) {
|
||||
ret = -1;
|
||||
goto fail;
|
||||
}
|
||||
@@ -243,15 +241,15 @@ fail:
|
||||
return ret;
|
||||
}
|
||||
|
||||
int _libssh2_dsa_new_private (libssh2_dsa_ctx **dsa,
|
||||
int
|
||||
_libssh2_dsa_new_private(libssh2_dsa_ctx ** dsa,
|
||||
LIBSSH2_SESSION * session,
|
||||
FILE *fp,
|
||||
unsigned const char *passphrase)
|
||||
FILE * fp, unsigned const char *passphrase)
|
||||
{
|
||||
char *data, *save_data;
|
||||
unsigned char *data, *save_data;
|
||||
unsigned int datalen;
|
||||
int ret;
|
||||
char *p, *q, *g, *y, *x;
|
||||
unsigned char *p, *q, *g, *y, *x;
|
||||
unsigned int plen, qlen, glen, ylen, xlen;
|
||||
|
||||
(void) passphrase;
|
||||
@@ -313,8 +311,7 @@ int _libssh2_dsa_new_private (libssh2_dsa_ctx **dsa,
|
||||
goto fail;
|
||||
}
|
||||
|
||||
if (_libssh2_dsa_new (dsa, p, plen, q, qlen,
|
||||
g, glen, y, ylen, x, xlen)) {
|
||||
if (_libssh2_dsa_new(dsa, p, plen, q, qlen, g, glen, y, ylen, x, xlen)) {
|
||||
ret = -1;
|
||||
goto fail;
|
||||
}
|
||||
@@ -326,12 +323,12 @@ fail:
|
||||
return ret;
|
||||
}
|
||||
|
||||
int _libssh2_rsa_sha1_sign(LIBSSH2_SESSION *session,
|
||||
int
|
||||
_libssh2_rsa_sha1_sign(LIBSSH2_SESSION * session,
|
||||
libssh2_dsa_ctx * rsactx,
|
||||
const unsigned char *hash,
|
||||
unsigned long hash_len,
|
||||
unsigned char **signature,
|
||||
unsigned long *signature_len)
|
||||
unsigned char **signature, unsigned long *signature_len)
|
||||
{
|
||||
gcry_sexp_t sig_sexp;
|
||||
gcry_sexp_t data;
|
||||
@@ -379,10 +376,10 @@ int _libssh2_rsa_sha1_sign(LIBSSH2_SESSION *session,
|
||||
return rc;
|
||||
}
|
||||
|
||||
int _libssh2_dsa_sha1_sign(libssh2_dsa_ctx *dsactx,
|
||||
int
|
||||
_libssh2_dsa_sha1_sign(libssh2_dsa_ctx * dsactx,
|
||||
const unsigned char *hash,
|
||||
unsigned long hash_len,
|
||||
unsigned char *sig)
|
||||
unsigned long hash_len, unsigned char *sig)
|
||||
{
|
||||
unsigned char zhash[SHA_DIGEST_LENGTH + 1];
|
||||
gcry_sexp_t sig_sexp;
|
||||
@@ -398,8 +395,7 @@ int _libssh2_dsa_sha1_sign(libssh2_dsa_ctx *dsactx,
|
||||
memcpy(zhash + 1, hash, hash_len);
|
||||
zhash[0] = 0;
|
||||
|
||||
if (gcry_sexp_build (&data, NULL, "(data (value %b))",
|
||||
hash_len + 1, zhash)) {
|
||||
if (gcry_sexp_build(&data, NULL, "(data (value %b))", hash_len + 1, zhash)) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
@@ -476,10 +472,10 @@ out:
|
||||
return ret;
|
||||
}
|
||||
|
||||
int _libssh2_dsa_sha1_verify(libssh2_dsa_ctx *dsactx,
|
||||
int
|
||||
_libssh2_dsa_sha1_verify(libssh2_dsa_ctx * dsactx,
|
||||
const unsigned char *sig,
|
||||
const unsigned char *m,
|
||||
unsigned long m_len)
|
||||
const unsigned char *m, unsigned long m_len)
|
||||
{
|
||||
unsigned char hash[SHA_DIGEST_LENGTH + 1];
|
||||
gcry_sexp_t s_sig, s_hash;
|
||||
@@ -506,11 +502,10 @@ int _libssh2_dsa_sha1_verify(libssh2_dsa_ctx *dsactx,
|
||||
return (rc == 0) ? 0 : -1;
|
||||
}
|
||||
|
||||
int _libssh2_cipher_init (_libssh2_cipher_ctx *h,
|
||||
int
|
||||
_libssh2_cipher_init(_libssh2_cipher_ctx * h,
|
||||
_libssh2_cipher_type(algo),
|
||||
unsigned char *iv,
|
||||
unsigned char *secret,
|
||||
int encrypt)
|
||||
unsigned char *iv, unsigned char *secret, int encrypt)
|
||||
{
|
||||
int mode = 0, ret;
|
||||
int keylen = gcry_cipher_get_algo_keylen(algo);
|
||||
@@ -544,10 +539,10 @@ int _libssh2_cipher_init (_libssh2_cipher_ctx *h,
|
||||
return 0;
|
||||
}
|
||||
|
||||
int _libssh2_cipher_crypt(_libssh2_cipher_ctx *ctx,
|
||||
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 = gcry_cipher_get_algo_blklen(algo);
|
||||
int ret;
|
||||
@@ -557,11 +552,9 @@ int _libssh2_cipher_crypt(_libssh2_cipher_ctx *ctx,
|
||||
}
|
||||
|
||||
if (encrypt) {
|
||||
ret = gcry_cipher_encrypt (*ctx, block, blklen,
|
||||
block, blklen);
|
||||
ret = gcry_cipher_encrypt(*ctx, block, blklen, block, blklen);
|
||||
} else {
|
||||
ret = gcry_cipher_decrypt (*ctx, block, blklen,
|
||||
block, blklen);
|
||||
ret = gcry_cipher_decrypt(*ctx, block, blklen, block, blklen);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
@@ -1,5 +1,6 @@
|
||||
/* Copyright (C) 2006, 2007 The Written Word, Inc. All rights reserved.
|
||||
* Author: Simon Josefsson
|
||||
/* Copyright (C) 2006, 2007, The Written Word, Inc.
|
||||
* Copyright (C) 2008, Simon Josefsson
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms,
|
||||
* with or without modification, are permitted provided
|
||||
@@ -108,17 +109,14 @@ int _libssh2_rsa_new(libssh2_rsa_ctx **rsa,
|
||||
unsigned long e1len,
|
||||
const unsigned char *e2data,
|
||||
unsigned long e2len,
|
||||
const unsigned char *coeffdata,
|
||||
unsigned long coefflen);
|
||||
const unsigned char *coeffdata, unsigned long coefflen);
|
||||
int _libssh2_rsa_new_private(libssh2_rsa_ctx ** rsa,
|
||||
LIBSSH2_SESSION * session,
|
||||
FILE *fp,
|
||||
unsigned const char *passphrase);
|
||||
FILE * fp, unsigned const char *passphrase);
|
||||
int _libssh2_rsa_sha1_verify(libssh2_rsa_ctx * rsa,
|
||||
const unsigned char *sig,
|
||||
unsigned long sig_len,
|
||||
const unsigned char *m,
|
||||
unsigned long m_len);
|
||||
const unsigned char *m, unsigned long m_len);
|
||||
int _libssh2_rsa_sha1_sign(LIBSSH2_SESSION * session,
|
||||
libssh2_rsa_ctx * rsactx,
|
||||
const unsigned char *hash,
|
||||
@@ -139,20 +137,16 @@ int _libssh2_dsa_new(libssh2_dsa_ctx **dsa,
|
||||
unsigned long glen,
|
||||
const unsigned char *ydata,
|
||||
unsigned long ylen,
|
||||
const unsigned char *x,
|
||||
unsigned long x_len);
|
||||
const unsigned char *x, unsigned long x_len);
|
||||
int _libssh2_dsa_new_private(libssh2_dsa_ctx ** dsa,
|
||||
LIBSSH2_SESSION * session,
|
||||
FILE *fp,
|
||||
unsigned const char *passphrase);
|
||||
FILE * fp, unsigned const char *passphrase);
|
||||
int _libssh2_dsa_sha1_verify(libssh2_dsa_ctx * dsa,
|
||||
const unsigned char *sig,
|
||||
const unsigned char *m,
|
||||
unsigned long m_len);
|
||||
const unsigned char *m, unsigned long m_len);
|
||||
int _libssh2_dsa_sha1_sign(libssh2_dsa_ctx * dsactx,
|
||||
const unsigned char *hash,
|
||||
unsigned long hash_len,
|
||||
unsigned char *sig);
|
||||
unsigned long hash_len, unsigned char *sig);
|
||||
|
||||
#define _libssh2_dsa_free(dsactx) gcry_sexp_release (dsactx)
|
||||
|
||||
@@ -170,20 +164,18 @@ int _libssh2_dsa_sha1_sign(libssh2_dsa_ctx *dsactx,
|
||||
int _libssh2_cipher_init(_libssh2_cipher_ctx * h,
|
||||
_libssh2_cipher_type(algo),
|
||||
unsigned char *iv,
|
||||
unsigned char *secret,
|
||||
int encrypt);
|
||||
unsigned char *secret, int encrypt);
|
||||
|
||||
int _libssh2_cipher_crypt(_libssh2_cipher_ctx * ctx,
|
||||
_libssh2_cipher_type(algo),
|
||||
int encrypt,
|
||||
unsigned char *block);
|
||||
int encrypt, unsigned char *block);
|
||||
|
||||
#define _libssh2_cipher_dtor(ctx) gcry_cipher_close(*(ctx))
|
||||
|
||||
#define _libssh2_bn struct gcry_mpi
|
||||
#define _libssh2_bn_ctx int
|
||||
#define _libssh2_bn_ctx_new() 0
|
||||
#define _libssh2_bn_ctx_free(bnctx) 0
|
||||
#define _libssh2_bn_ctx_free(bnctx) ((void)0)
|
||||
#define _libssh2_bn_init() gcry_mpi_new(0)
|
||||
#define _libssh2_bn_rand(bn, bits, top, bottom) gcry_mpi_randomize (bn, bits, GCRY_WEAK_RANDOM)
|
||||
#define _libssh2_bn_mod_exp(r, a, p, m, ctx) gcry_mpi_powm (r, a, p, m)
|
||||
|
@@ -1,4 +1,4 @@
|
||||
/* Copyright (c) 2004-2007, Sara Golemon <sarag@libssh2.org>
|
||||
/* Copyright (c) 2004-2008, Sara Golemon <sarag@libssh2.org>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms,
|
||||
@@ -41,6 +41,17 @@
|
||||
#define LIBSSH2_LIBRARY
|
||||
#include "libssh2_config.h"
|
||||
|
||||
#ifdef HAVE_WINDOWS_H
|
||||
#include <windows.h>
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_WS2TCPIP_H
|
||||
#include <ws2tcpip.h>
|
||||
#endif
|
||||
|
||||
#include <stdio.h>
|
||||
#include <time.h>
|
||||
|
||||
/* The following CPP block should really only be in session.c and
|
||||
packet.c. However, AIX have #define's for 'events' and 'revents'
|
||||
and we are using those names in libssh2.h, so we need to include
|
||||
@@ -51,12 +62,10 @@
|
||||
http://www.mail-archive.com/libssh2-devel%40lists.sourceforge.net/msg00003.html
|
||||
http://www.mail-archive.com/libssh2-devel%40lists.sourceforge.net/msg00224.html
|
||||
*/
|
||||
#include <stdio.h>
|
||||
|
||||
#ifdef HAVE_POLL
|
||||
# include <sys/poll.h>
|
||||
#else
|
||||
# ifdef HAVE_SELECT
|
||||
# if defined(HAVE_SELECT) && !defined(WIN32)
|
||||
# ifdef HAVE_SYS_SELECT_H
|
||||
# include <sys/select.h>
|
||||
# else
|
||||
@@ -70,6 +79,28 @@
|
||||
#include "libssh2_publickey.h"
|
||||
#include "libssh2_sftp.h"
|
||||
|
||||
/* Provide iovec / writev on WIN32 platform. */
|
||||
#ifdef WIN32
|
||||
|
||||
/* same as WSABUF */
|
||||
struct iovec {
|
||||
u_long iov_len;
|
||||
char *iov_base;
|
||||
};
|
||||
|
||||
#define inline __inline
|
||||
|
||||
static inline int writev(int sock, struct iovec *iov, int nvecs)
|
||||
{
|
||||
DWORD ret;
|
||||
if (WSASend(sock, (LPWSABUF)iov, nvecs, &ret, 0, NULL, NULL) == 0) {
|
||||
return ret;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
#endif /* WIN32 */
|
||||
|
||||
/* Needed for struct iovec on some platforms */
|
||||
#ifdef HAVE_SYS_UIO_H
|
||||
#include <sys/uio.h>
|
||||
@@ -91,6 +122,26 @@
|
||||
#include "openssl.h"
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_WINSOCK2_H
|
||||
|
||||
#include <winsock2.h>
|
||||
#include <mswsock.h>
|
||||
#include <ws2tcpip.h>
|
||||
|
||||
#ifdef _MSC_VER
|
||||
/* "inline" keyword is valid only with C++ engine! */
|
||||
#define inline __inline
|
||||
#endif
|
||||
|
||||
/* not really usleep, but safe for the way we use it in this lib */
|
||||
static inline int usleep(int udelay)
|
||||
{
|
||||
Sleep(udelay / 1000);
|
||||
return 0;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
/* RFC4253 section 6.1 Maximum Packet Length says:
|
||||
*
|
||||
* "All implementations MUST be able to process packets with
|
||||
@@ -127,7 +178,8 @@ typedef struct _LIBSSH2_CHANNEL_BRIGADE LIBSSH2_CHANNEL_BRIGADE;
|
||||
|
||||
typedef int libssh2pack_t;
|
||||
|
||||
typedef enum {
|
||||
typedef enum
|
||||
{
|
||||
libssh2_NB_state_idle = 0,
|
||||
libssh2_NB_state_allocated,
|
||||
libssh2_NB_state_created,
|
||||
@@ -144,16 +196,19 @@ typedef enum {
|
||||
libssh2_NB_state_jump3
|
||||
} libssh2_nonblocking_states;
|
||||
|
||||
typedef struct packet_require_state_t {
|
||||
typedef struct packet_require_state_t
|
||||
{
|
||||
libssh2_nonblocking_states state;
|
||||
time_t start;
|
||||
} packet_require_state_t;
|
||||
|
||||
typedef struct packet_requirev_state_t {
|
||||
typedef struct packet_requirev_state_t
|
||||
{
|
||||
time_t start;
|
||||
} packet_requirev_state_t;
|
||||
|
||||
typedef struct kmdhgGPsha1kex_state_t {
|
||||
typedef struct kmdhgGPsha1kex_state_t
|
||||
{
|
||||
libssh2_nonblocking_states state;
|
||||
unsigned char *e_packet;
|
||||
unsigned char *s_packet;
|
||||
@@ -180,7 +235,8 @@ typedef struct kmdhgGPsha1kex_state_t {
|
||||
libssh2_nonblocking_states burn_state;
|
||||
} kmdhgGPsha1kex_state_t;
|
||||
|
||||
typedef struct key_exchange_state_low_t {
|
||||
typedef struct key_exchange_state_low_t
|
||||
{
|
||||
libssh2_nonblocking_states state;
|
||||
packet_require_state_t req_state;
|
||||
kmdhgGPsha1kex_state_t exchange_state;
|
||||
@@ -192,7 +248,8 @@ typedef struct key_exchange_state_low_t {
|
||||
unsigned long data_len;
|
||||
} key_exchange_state_low_t;
|
||||
|
||||
typedef struct key_exchange_state_t {
|
||||
typedef struct key_exchange_state_t
|
||||
{
|
||||
libssh2_nonblocking_states state;
|
||||
packet_require_state_t req_state;
|
||||
key_exchange_state_low_t key_state_low;
|
||||
@@ -204,7 +261,8 @@ typedef struct key_exchange_state_t {
|
||||
|
||||
#define FwdNotReq "Forward not requested"
|
||||
|
||||
typedef struct packet_queue_listener_state_t {
|
||||
typedef struct packet_queue_listener_state_t
|
||||
{
|
||||
libssh2_nonblocking_states state;
|
||||
unsigned char packet[17 + (sizeof(FwdNotReq) - 1)];
|
||||
unsigned char *host;
|
||||
@@ -220,7 +278,8 @@ typedef struct packet_queue_listener_state_t {
|
||||
|
||||
#define X11FwdUnAvil "X11 Forward Unavailable"
|
||||
|
||||
typedef struct packet_x11_open_state_t {
|
||||
typedef struct packet_x11_open_state_t
|
||||
{
|
||||
libssh2_nonblocking_states state;
|
||||
unsigned char packet[17 + (sizeof(X11FwdUnAvil) - 1)];
|
||||
unsigned char *shost;
|
||||
@@ -231,7 +290,8 @@ typedef struct packet_x11_open_state_t {
|
||||
uint32_t shost_len;
|
||||
} packet_x11_open_state_t;
|
||||
|
||||
struct _LIBSSH2_PACKET {
|
||||
struct _LIBSSH2_PACKET
|
||||
{
|
||||
unsigned char type;
|
||||
|
||||
/* Unencrypted Payload (no type byte, no padding, just the facts ma'am) */
|
||||
@@ -250,11 +310,13 @@ struct _LIBSSH2_PACKET {
|
||||
LIBSSH2_PACKET *next, *prev;
|
||||
};
|
||||
|
||||
struct _LIBSSH2_PACKET_BRIGADE {
|
||||
struct _LIBSSH2_PACKET_BRIGADE
|
||||
{
|
||||
LIBSSH2_PACKET *head, *tail;
|
||||
};
|
||||
|
||||
typedef struct _libssh2_channel_data {
|
||||
typedef struct _libssh2_channel_data
|
||||
{
|
||||
/* Identifier */
|
||||
unsigned long id;
|
||||
|
||||
@@ -265,7 +327,8 @@ typedef struct _libssh2_channel_data {
|
||||
char close, eof, extended_data_ignore_mode;
|
||||
} libssh2_channel_data;
|
||||
|
||||
struct _LIBSSH2_CHANNEL {
|
||||
struct _LIBSSH2_CHANNEL
|
||||
{
|
||||
unsigned char *channel_type;
|
||||
unsigned channel_type_len;
|
||||
|
||||
@@ -355,11 +418,13 @@ struct _LIBSSH2_CHANNEL {
|
||||
libssh2_nonblocking_states extData2_state;
|
||||
};
|
||||
|
||||
struct _LIBSSH2_CHANNEL_BRIGADE {
|
||||
struct _LIBSSH2_CHANNEL_BRIGADE
|
||||
{
|
||||
LIBSSH2_CHANNEL *head, *tail;
|
||||
};
|
||||
|
||||
struct _LIBSSH2_LISTENER {
|
||||
struct _LIBSSH2_LISTENER
|
||||
{
|
||||
LIBSSH2_SESSION *session;
|
||||
|
||||
char *host;
|
||||
@@ -377,7 +442,8 @@ struct _LIBSSH2_LISTENER {
|
||||
size_t chanFwdCncl_data_len;
|
||||
};
|
||||
|
||||
typedef struct _libssh2_endpoint_data {
|
||||
typedef struct _libssh2_endpoint_data
|
||||
{
|
||||
unsigned char *banner;
|
||||
|
||||
unsigned char *kexinit;
|
||||
@@ -402,7 +468,8 @@ typedef struct _libssh2_endpoint_data {
|
||||
|
||||
#define PACKETBUFSIZE 4096
|
||||
|
||||
struct transportpacket {
|
||||
struct transportpacket
|
||||
{
|
||||
/* ------------- for incoming data --------------- */
|
||||
unsigned char buf[PACKETBUFSIZE];
|
||||
unsigned char init[5]; /* first 5 bytes of the incoming data stream,
|
||||
@@ -437,7 +504,8 @@ struct transportpacket {
|
||||
unsigned long osent; /* number of bytes already sent */
|
||||
};
|
||||
|
||||
struct _LIBSSH2_PUBLICKEY {
|
||||
struct _LIBSSH2_PUBLICKEY
|
||||
{
|
||||
LIBSSH2_CHANNEL *channel;
|
||||
unsigned long version;
|
||||
|
||||
@@ -464,20 +532,31 @@ struct _LIBSSH2_PUBLICKEY {
|
||||
unsigned long listFetch_data_len;
|
||||
};
|
||||
|
||||
struct _LIBSSH2_SFTP_HANDLE {
|
||||
#define SFTP_HANDLE_MAXLEN 256 /* according to spec! */
|
||||
|
||||
struct _LIBSSH2_SFTP_HANDLE
|
||||
{
|
||||
LIBSSH2_SFTP *sftp;
|
||||
LIBSSH2_SFTP_HANDLE *prev, *next;
|
||||
|
||||
char *handle;
|
||||
/* This is a pre-allocated buffer used for sending SFTP requests as the
|
||||
whole thing might not get sent in one go. This buffer is used for read,
|
||||
write, close and MUST thus be big enough to suit all these. */
|
||||
unsigned char request_packet[SFTP_HANDLE_MAXLEN + 25];
|
||||
|
||||
char handle[SFTP_HANDLE_MAXLEN];
|
||||
int handle_len;
|
||||
|
||||
char handle_type;
|
||||
|
||||
union _libssh2_sftp_handle_data {
|
||||
struct _libssh2_sftp_handle_file_data {
|
||||
union _libssh2_sftp_handle_data
|
||||
{
|
||||
struct _libssh2_sftp_handle_file_data
|
||||
{
|
||||
libssh2_uint64_t offset;
|
||||
} file;
|
||||
struct _libssh2_sftp_handle_dir_data {
|
||||
struct _libssh2_sftp_handle_dir_data
|
||||
{
|
||||
unsigned long names_left;
|
||||
void *names_packet;
|
||||
char *next_name;
|
||||
@@ -490,7 +569,8 @@ struct _LIBSSH2_SFTP_HANDLE {
|
||||
unsigned char *close_packet;
|
||||
};
|
||||
|
||||
struct _LIBSSH2_SFTP {
|
||||
struct _LIBSSH2_SFTP
|
||||
{
|
||||
LIBSSH2_CHANNEL *channel;
|
||||
|
||||
unsigned long request_id, version;
|
||||
@@ -570,7 +650,8 @@ struct _LIBSSH2_SFTP {
|
||||
|
||||
#define LIBSSH2_SCP_RESPONSE_BUFLEN 256
|
||||
|
||||
struct _LIBSSH2_SESSION {
|
||||
struct _LIBSSH2_SESSION
|
||||
{
|
||||
/* Memory management callbacks */
|
||||
void *abstract;
|
||||
LIBSSH2_ALLOC_FUNC((*alloc));
|
||||
@@ -631,6 +712,7 @@ struct _LIBSSH2_SESSION {
|
||||
int socket_fd;
|
||||
int socket_block;
|
||||
int socket_state;
|
||||
int socket_block_directions;
|
||||
|
||||
/* Error tracking */
|
||||
char *err_msg;
|
||||
@@ -788,7 +870,14 @@ struct _LIBSSH2_SESSION {
|
||||
unsigned char scpRecv_response[LIBSSH2_SCP_RESPONSE_BUFLEN];
|
||||
unsigned long scpRecv_response_len;
|
||||
long scpRecv_mode;
|
||||
#if defined(HAVE_LONGLONG) && defined(strtoll)
|
||||
/* we have the type and we can parse such numbers */
|
||||
long long scpRecv_size;
|
||||
#define scpsize_strtol strtoll
|
||||
#else
|
||||
long scpRecv_size;
|
||||
#define scpsize_strtol strtol
|
||||
#endif
|
||||
long scpRecv_mtime;
|
||||
long scpRecv_atime;
|
||||
char *scpRecv_err_msg;
|
||||
@@ -810,6 +899,7 @@ struct _LIBSSH2_SESSION {
|
||||
#define LIBSSH2_STATE_EXCHANGING_KEYS 0x00000001
|
||||
#define LIBSSH2_STATE_NEWKEYS 0x00000002
|
||||
#define LIBSSH2_STATE_AUTHENTICATED 0x00000004
|
||||
#define LIBSSH2_STATE_KEX_ACTIVE 0x00000008
|
||||
|
||||
/* session.flag helpers */
|
||||
#ifdef MSG_NOSIGNAL
|
||||
@@ -823,28 +913,40 @@ struct _LIBSSH2_SESSION {
|
||||
|
||||
/* libssh2 extensible ssh api, ultimately I'd like to allow loading additional methods via .so/.dll */
|
||||
|
||||
struct _LIBSSH2_KEX_METHOD {
|
||||
struct _LIBSSH2_KEX_METHOD
|
||||
{
|
||||
const char *name;
|
||||
|
||||
/* Key exchange, populates session->* and returns 0 on success, non-0 on error */
|
||||
int (*exchange_keys)(LIBSSH2_SESSION *session, key_exchange_state_low_t *key_state);
|
||||
int (*exchange_keys) (LIBSSH2_SESSION * session,
|
||||
key_exchange_state_low_t * key_state);
|
||||
|
||||
long flags;
|
||||
};
|
||||
|
||||
struct _LIBSSH2_HOSTKEY_METHOD {
|
||||
struct _LIBSSH2_HOSTKEY_METHOD
|
||||
{
|
||||
const char *name;
|
||||
unsigned long hash_len;
|
||||
|
||||
int (*init)(LIBSSH2_SESSION *session, const unsigned char *hostkey_data, unsigned long hostkey_data_len, void **abstract);
|
||||
int (*initPEM)(LIBSSH2_SESSION *session, const char *privkeyfile, unsigned const char *passphrase, void **abstract);
|
||||
int (*sig_verify)(LIBSSH2_SESSION *session, const unsigned char *sig, unsigned long sig_len, const unsigned char *m, unsigned long m_len, void **abstract);
|
||||
int (*signv)(LIBSSH2_SESSION *session, unsigned char **signature, unsigned long *signature_len, unsigned long veccount, const struct iovec datavec[], void **abstract);
|
||||
int (*encrypt)(LIBSSH2_SESSION *session, unsigned char **dst, unsigned long *dst_len, const unsigned char *src, unsigned long src_len, void **abstract);
|
||||
int (*init) (LIBSSH2_SESSION * session, const unsigned char *hostkey_data,
|
||||
unsigned long hostkey_data_len, void **abstract);
|
||||
int (*initPEM) (LIBSSH2_SESSION * session, const char *privkeyfile,
|
||||
unsigned const char *passphrase, void **abstract);
|
||||
int (*sig_verify) (LIBSSH2_SESSION * session, const unsigned char *sig,
|
||||
unsigned long sig_len, const unsigned char *m,
|
||||
unsigned long m_len, void **abstract);
|
||||
int (*signv) (LIBSSH2_SESSION * session, unsigned char **signature,
|
||||
unsigned long *signature_len, unsigned long veccount,
|
||||
const struct iovec datavec[], void **abstract);
|
||||
int (*encrypt) (LIBSSH2_SESSION * session, unsigned char **dst,
|
||||
unsigned long *dst_len, const unsigned char *src,
|
||||
unsigned long src_len, void **abstract);
|
||||
int (*dtor) (LIBSSH2_SESSION * session, void **abstract);
|
||||
};
|
||||
|
||||
struct _LIBSSH2_CRYPT_METHOD {
|
||||
struct _LIBSSH2_CRYPT_METHOD
|
||||
{
|
||||
const char *name;
|
||||
|
||||
int blocksize;
|
||||
@@ -855,23 +957,31 @@ struct _LIBSSH2_CRYPT_METHOD {
|
||||
|
||||
long flags;
|
||||
|
||||
int (*init)(LIBSSH2_SESSION *session, const LIBSSH2_CRYPT_METHOD *method, unsigned char *iv, int *free_iv, unsigned char *secret, int *free_secret, int encrypt, void **abstract);
|
||||
int (*crypt)(LIBSSH2_SESSION *session, unsigned char *block, void **abstract);
|
||||
int (*init) (LIBSSH2_SESSION * session,
|
||||
const LIBSSH2_CRYPT_METHOD * method, unsigned char *iv,
|
||||
int *free_iv, unsigned char *secret, int *free_secret,
|
||||
int encrypt, void **abstract);
|
||||
int (*crypt) (LIBSSH2_SESSION * session, unsigned char *block,
|
||||
void **abstract);
|
||||
int (*dtor) (LIBSSH2_SESSION * session, void **abstract);
|
||||
|
||||
_libssh2_cipher_type(algo);
|
||||
};
|
||||
|
||||
struct _LIBSSH2_COMP_METHOD {
|
||||
struct _LIBSSH2_COMP_METHOD
|
||||
{
|
||||
const char *name;
|
||||
|
||||
int (*init) (LIBSSH2_SESSION * session, int compress, void **abstract);
|
||||
int (*comp)(LIBSSH2_SESSION *session, int compress, unsigned char **dest, unsigned long *dest_len, unsigned long payload_limit, int *free_dest,
|
||||
const unsigned char *src, unsigned long src_len, void **abstract);
|
||||
int (*comp) (LIBSSH2_SESSION * session, int compress, unsigned char **dest,
|
||||
unsigned long *dest_len, unsigned long payload_limit,
|
||||
int *free_dest, const unsigned char *src,
|
||||
unsigned long src_len, void **abstract);
|
||||
int (*dtor) (LIBSSH2_SESSION * session, int compress, void **abstract);
|
||||
};
|
||||
|
||||
struct _LIBSSH2_MAC_METHOD {
|
||||
struct _LIBSSH2_MAC_METHOD
|
||||
{
|
||||
const char *name;
|
||||
|
||||
/* The length of a given MAC packet */
|
||||
@@ -881,8 +991,12 @@ struct _LIBSSH2_MAC_METHOD {
|
||||
int key_len;
|
||||
|
||||
/* Message Authentication Code Hashing algo */
|
||||
int (*init)(LIBSSH2_SESSION *session, unsigned char *key, int *free_key, void **abstract);
|
||||
int (*hash)(LIBSSH2_SESSION *session, unsigned char *buf, unsigned long seqno, const unsigned char *packet, unsigned long packet_len, const unsigned char *addtl, unsigned long addtl_len, void **abstract);
|
||||
int (*init) (LIBSSH2_SESSION * session, unsigned char *key, int *free_key,
|
||||
void **abstract);
|
||||
int (*hash) (LIBSSH2_SESSION * session, unsigned char *buf,
|
||||
unsigned long seqno, const unsigned char *packet,
|
||||
unsigned long packet_len, const unsigned char *addtl,
|
||||
unsigned long addtl_len, void **abstract);
|
||||
int (*dtor) (LIBSSH2_SESSION * session, void **abstract);
|
||||
};
|
||||
|
||||
@@ -895,7 +1009,8 @@ struct _LIBSSH2_MAC_METHOD {
|
||||
#define LIBSSH2_DBG_ERROR 7
|
||||
#define LIBSSH2_DBG_PUBLICKEY 8
|
||||
#ifdef LIBSSH2DEBUG
|
||||
void _libssh2_debug(LIBSSH2_SESSION *session, int context, const char *format, ...);
|
||||
void _libssh2_debug(LIBSSH2_SESSION * session, int context, const char *format,
|
||||
...);
|
||||
#else
|
||||
#if defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L)
|
||||
/* C99 style */
|
||||
@@ -905,8 +1020,10 @@ void _libssh2_debug(LIBSSH2_SESSION *session, int context, const char *format, .
|
||||
#define _libssh2_debug(x,y,z,...) do {} while (0)
|
||||
#else
|
||||
/* no gcc and not C99, do static and hopefully inline */
|
||||
static inline void _libssh2_debug(LIBSSH2_SESSION *session, int context,
|
||||
const char *format, ...) {}
|
||||
static inline void
|
||||
_libssh2_debug(LIBSSH2_SESSION * session, int context, const char *format, ...)
|
||||
{
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
|
||||
@@ -1037,16 +1154,38 @@ int libssh2_packet_ask_ex(LIBSSH2_SESSION *session, unsigned char packet_type,
|
||||
const unsigned char *match_buf,
|
||||
unsigned long match_len, int poll_socket);
|
||||
|
||||
int libssh2_packet_askv_ex(LIBSSH2_SESSION *session, const unsigned char *packet_types, unsigned char **data, unsigned long *data_len, unsigned long match_ofs, const unsigned char *match_buf, unsigned long match_len, int poll_socket);
|
||||
int libssh2_packet_require_ex(LIBSSH2_SESSION *session, unsigned char packet_type, unsigned char **data, unsigned long *data_len, unsigned long match_ofs, const unsigned char *match_buf, unsigned long match_len, packet_require_state_t *state);
|
||||
int libssh2_packet_requirev_ex(LIBSSH2_SESSION *session, const unsigned char *packet_types, unsigned char **data, unsigned long *data_len, unsigned long match_ofs, const unsigned char *match_buf, unsigned long match_len, packet_requirev_state_t *state);
|
||||
int libssh2_packet_burn(LIBSSH2_SESSION *session, libssh2_nonblocking_states *state);
|
||||
int libssh2_packet_write(LIBSSH2_SESSION *session, unsigned char *data, unsigned long data_len);
|
||||
int libssh2_packet_add(LIBSSH2_SESSION *session, unsigned char *data, size_t datalen, int macstate);
|
||||
int libssh2_kex_exchange(LIBSSH2_SESSION *session, int reexchange, key_exchange_state_t *state);
|
||||
int libssh2_packet_askv_ex(LIBSSH2_SESSION * session,
|
||||
const unsigned char *packet_types,
|
||||
unsigned char **data, unsigned long *data_len,
|
||||
unsigned long match_ofs,
|
||||
const unsigned char *match_buf,
|
||||
unsigned long match_len, int poll_socket);
|
||||
int libssh2_packet_require_ex(LIBSSH2_SESSION * session,
|
||||
unsigned char packet_type, unsigned char **data,
|
||||
unsigned long *data_len, unsigned long match_ofs,
|
||||
const unsigned char *match_buf,
|
||||
unsigned long match_len,
|
||||
packet_require_state_t * state);
|
||||
int libssh2_packet_requirev_ex(LIBSSH2_SESSION * session,
|
||||
const unsigned char *packet_types,
|
||||
unsigned char **data, unsigned long *data_len,
|
||||
unsigned long match_ofs,
|
||||
const unsigned char *match_buf,
|
||||
unsigned long match_len,
|
||||
packet_requirev_state_t * state);
|
||||
int libssh2_packet_burn(LIBSSH2_SESSION * session,
|
||||
libssh2_nonblocking_states * state);
|
||||
int libssh2_packet_write(LIBSSH2_SESSION * session, unsigned char *data,
|
||||
unsigned long data_len);
|
||||
int libssh2_packet_add(LIBSSH2_SESSION * session, unsigned char *data,
|
||||
size_t datalen, int macstate);
|
||||
int libssh2_kex_exchange(LIBSSH2_SESSION * session, int reexchange,
|
||||
key_exchange_state_t * state);
|
||||
unsigned long libssh2_channel_nextid(LIBSSH2_SESSION * session);
|
||||
LIBSSH2_CHANNEL *libssh2_channel_locate(LIBSSH2_SESSION *session, unsigned long channel_id);
|
||||
unsigned long libssh2_channel_packet_data_len(LIBSSH2_CHANNEL *channel, int stream_id);
|
||||
LIBSSH2_CHANNEL *libssh2_channel_locate(LIBSSH2_SESSION * session,
|
||||
unsigned long channel_id);
|
||||
unsigned long libssh2_channel_packet_data_len(LIBSSH2_CHANNEL * channel,
|
||||
int stream_id);
|
||||
|
||||
/* this is the lib-internal set blocking function */
|
||||
int _libssh2_session_set_blocking(LIBSSH2_SESSION * session, int blocking);
|
||||
@@ -1064,8 +1203,7 @@ const LIBSSH2_MAC_METHOD **libssh2_mac_methods(void);
|
||||
int _libssh2_pem_parse(LIBSSH2_SESSION * session,
|
||||
const char *headerbegin,
|
||||
const char *headerend,
|
||||
FILE *fp,
|
||||
char **data, unsigned int *datalen);
|
||||
FILE * fp, unsigned char **data, unsigned int *datalen);
|
||||
int _libssh2_pem_decode_sequence(unsigned char **data, unsigned int *datalen);
|
||||
int _libssh2_pem_decode_integer(unsigned char **data, unsigned int *datalen,
|
||||
unsigned char **i, unsigned int *ilen);
|
||||
|
87
src/mac.c
87
src/mac.c
@@ -41,12 +41,15 @@
|
||||
/* {{{ libssh2_mac_none_MAC
|
||||
* Minimalist MAC: No MAC
|
||||
*/
|
||||
static int libssh2_mac_none_MAC(LIBSSH2_SESSION *session, unsigned char *buf, unsigned long seqno,
|
||||
const unsigned char *packet, unsigned long packet_len,
|
||||
const unsigned char *addtl, unsigned long addtl_len, void **abstract)
|
||||
static int
|
||||
libssh2_mac_none_MAC(LIBSSH2_SESSION * session, unsigned char *buf,
|
||||
unsigned long seqno, const unsigned char *packet,
|
||||
unsigned long packet_len, const unsigned char *addtl,
|
||||
unsigned long addtl_len, void **abstract)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* }}} */
|
||||
|
||||
|
||||
@@ -63,7 +66,9 @@ static LIBSSH2_MAC_METHOD libssh2_mac_method_none = {
|
||||
/* {{{ libssh2_mac_method_common_init
|
||||
* Initialize simple mac methods
|
||||
*/
|
||||
static int libssh2_mac_method_common_init(LIBSSH2_SESSION *session, unsigned char *key, int *free_key, void **abstract)
|
||||
static int
|
||||
libssh2_mac_method_common_init(LIBSSH2_SESSION * session, unsigned char *key,
|
||||
int *free_key, void **abstract)
|
||||
{
|
||||
*abstract = key;
|
||||
*free_key = 0;
|
||||
@@ -71,12 +76,14 @@ static int libssh2_mac_method_common_init(LIBSSH2_SESSION *session, unsigned cha
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* }}} */
|
||||
|
||||
/* {{{ libssh2_mac_method_common_dtor
|
||||
* Cleanup simple mac methods
|
||||
*/
|
||||
static int libssh2_mac_method_common_dtor(LIBSSH2_SESSION *session, void **abstract)
|
||||
static int
|
||||
libssh2_mac_method_common_dtor(LIBSSH2_SESSION * session, void **abstract)
|
||||
{
|
||||
if (*abstract) {
|
||||
LIBSSH2_FREE(session, *abstract);
|
||||
@@ -85,14 +92,19 @@ static int libssh2_mac_method_common_dtor(LIBSSH2_SESSION *session, void **abstr
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* }}} */
|
||||
|
||||
/* {{{ libssh2_mac_method_hmac_sha1_hash
|
||||
* Calculate hash using full sha1 value
|
||||
*/
|
||||
static int libssh2_mac_method_hmac_sha1_hash(LIBSSH2_SESSION *session, unsigned char *buf, unsigned long seqno,
|
||||
const unsigned char *packet, unsigned long packet_len,
|
||||
const unsigned char *addtl, unsigned long addtl_len, void **abstract)
|
||||
static int
|
||||
libssh2_mac_method_hmac_sha1_hash(LIBSSH2_SESSION * session,
|
||||
unsigned char *buf, unsigned long seqno,
|
||||
const unsigned char *packet,
|
||||
unsigned long packet_len,
|
||||
const unsigned char *addtl,
|
||||
unsigned long addtl_len, void **abstract)
|
||||
{
|
||||
libssh2_hmac_ctx ctx;
|
||||
unsigned char seqno_buf[4];
|
||||
@@ -111,6 +123,7 @@ static int libssh2_mac_method_hmac_sha1_hash(LIBSSH2_SESSION *session, unsigned
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* }}} */
|
||||
|
||||
static const LIBSSH2_MAC_METHOD libssh2_mac_method_hmac_sha1 = {
|
||||
@@ -125,17 +138,23 @@ static const LIBSSH2_MAC_METHOD libssh2_mac_method_hmac_sha1 = {
|
||||
/* {{{ libssh2_mac_method_hmac_sha1_96_hash
|
||||
* Calculate hash using first 96 bits of sha1 value
|
||||
*/
|
||||
static int libssh2_mac_method_hmac_sha1_96_hash(LIBSSH2_SESSION *session, unsigned char *buf, unsigned long seqno,
|
||||
const unsigned char *packet, unsigned long packet_len,
|
||||
const unsigned char *addtl, unsigned long addtl_len, void **abstract)
|
||||
static int
|
||||
libssh2_mac_method_hmac_sha1_96_hash(LIBSSH2_SESSION * session,
|
||||
unsigned char *buf, unsigned long seqno,
|
||||
const unsigned char *packet,
|
||||
unsigned long packet_len,
|
||||
const unsigned char *addtl,
|
||||
unsigned long addtl_len, void **abstract)
|
||||
{
|
||||
unsigned char temp[SHA_DIGEST_LENGTH];
|
||||
|
||||
libssh2_mac_method_hmac_sha1_hash(session, temp, seqno, packet, packet_len, addtl, addtl_len, abstract);
|
||||
libssh2_mac_method_hmac_sha1_hash(session, temp, seqno, packet, packet_len,
|
||||
addtl, addtl_len, abstract);
|
||||
memcpy(buf, (char *) temp, 96 / 8);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* }}} */
|
||||
|
||||
static const LIBSSH2_MAC_METHOD libssh2_mac_method_hmac_sha1_96 = {
|
||||
@@ -150,9 +169,13 @@ static const LIBSSH2_MAC_METHOD libssh2_mac_method_hmac_sha1_96 = {
|
||||
/* {{{ libssh2_mac_method_hmac_md5_hash
|
||||
* Calculate hash using full md5 value
|
||||
*/
|
||||
static int libssh2_mac_method_hmac_md5_hash(LIBSSH2_SESSION *session, unsigned char *buf, unsigned long seqno,
|
||||
const unsigned char *packet, unsigned long packet_len,
|
||||
const unsigned char *addtl, unsigned long addtl_len, void **abstract)
|
||||
static int
|
||||
libssh2_mac_method_hmac_md5_hash(LIBSSH2_SESSION * session, unsigned char *buf,
|
||||
unsigned long seqno,
|
||||
const unsigned char *packet,
|
||||
unsigned long packet_len,
|
||||
const unsigned char *addtl,
|
||||
unsigned long addtl_len, void **abstract)
|
||||
{
|
||||
libssh2_hmac_ctx ctx;
|
||||
unsigned char seqno_buf[4];
|
||||
@@ -171,6 +194,7 @@ static int libssh2_mac_method_hmac_md5_hash(LIBSSH2_SESSION *session, unsigned c
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* }}} */
|
||||
|
||||
static const LIBSSH2_MAC_METHOD libssh2_mac_method_hmac_md5 = {
|
||||
@@ -185,17 +209,23 @@ static const LIBSSH2_MAC_METHOD libssh2_mac_method_hmac_md5 = {
|
||||
/* {{{ libssh2_mac_method_hmac_md5_96_hash
|
||||
* Calculate hash using first 96 bits of md5 value
|
||||
*/
|
||||
static int libssh2_mac_method_hmac_md5_96_hash(LIBSSH2_SESSION *session, unsigned char *buf, unsigned long seqno,
|
||||
const unsigned char *packet, unsigned long packet_len,
|
||||
const unsigned char *addtl, unsigned long addtl_len, void **abstract)
|
||||
static int
|
||||
libssh2_mac_method_hmac_md5_96_hash(LIBSSH2_SESSION * session,
|
||||
unsigned char *buf, unsigned long seqno,
|
||||
const unsigned char *packet,
|
||||
unsigned long packet_len,
|
||||
const unsigned char *addtl,
|
||||
unsigned long addtl_len, void **abstract)
|
||||
{
|
||||
unsigned char temp[MD5_DIGEST_LENGTH];
|
||||
|
||||
libssh2_mac_method_hmac_md5_hash(session, temp, seqno, packet, packet_len, addtl, addtl_len, abstract);
|
||||
libssh2_mac_method_hmac_md5_hash(session, temp, seqno, packet, packet_len,
|
||||
addtl, addtl_len, abstract);
|
||||
memcpy(buf, (char *) temp, 96 / 8);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* }}} */
|
||||
|
||||
static const LIBSSH2_MAC_METHOD libssh2_mac_method_hmac_md5_96 = {
|
||||
@@ -211,9 +241,14 @@ static const LIBSSH2_MAC_METHOD libssh2_mac_method_hmac_md5_96 = {
|
||||
/* {{{ libssh2_mac_method_hmac_ripemd160_hash
|
||||
* Calculate hash using ripemd160 value
|
||||
*/
|
||||
static int libssh2_mac_method_hmac_ripemd160_hash(LIBSSH2_SESSION *session, unsigned char *buf, unsigned long seqno,
|
||||
const unsigned char *packet, unsigned long packet_len,
|
||||
const unsigned char *addtl, unsigned long addtl_len, void **abstract)
|
||||
static int
|
||||
libssh2_mac_method_hmac_ripemd160_hash(LIBSSH2_SESSION * session,
|
||||
unsigned char *buf, unsigned long seqno,
|
||||
const unsigned char *packet,
|
||||
unsigned long packet_len,
|
||||
const unsigned char *addtl,
|
||||
unsigned long addtl_len,
|
||||
void **abstract)
|
||||
{
|
||||
libssh2_hmac_ctx ctx;
|
||||
unsigned char seqno_buf[4];
|
||||
@@ -232,6 +267,7 @@ static int libssh2_mac_method_hmac_ripemd160_hash(LIBSSH2_SESSION *session, unsi
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* }}} */
|
||||
|
||||
static const LIBSSH2_MAC_METHOD libssh2_mac_method_hmac_ripemd160 = {
|
||||
@@ -258,7 +294,7 @@ static const LIBSSH2_MAC_METHOD *_libssh2_mac_methods[] = {
|
||||
&libssh2_mac_method_hmac_sha1_96,
|
||||
&libssh2_mac_method_hmac_md5,
|
||||
&libssh2_mac_method_hmac_md5_96,
|
||||
#ifdef LIBSSH2_HMAC_RIPEMD
|
||||
#if LIBSSH2_HMAC_RIPEMD
|
||||
&libssh2_mac_method_hmac_ripemd160,
|
||||
&libssh2_mac_method_hmac_ripemd160_openssh_com,
|
||||
#endif /* LIBSSH2_HMAC_RIPEMD */
|
||||
@@ -268,7 +304,8 @@ static const LIBSSH2_MAC_METHOD *_libssh2_mac_methods[] = {
|
||||
NULL
|
||||
};
|
||||
|
||||
const LIBSSH2_MAC_METHOD **libssh2_mac_methods(void) {
|
||||
const LIBSSH2_MAC_METHOD **
|
||||
libssh2_mac_methods(void)
|
||||
{
|
||||
return _libssh2_mac_methods;
|
||||
}
|
||||
|
||||
|
44
src/misc.c
44
src/misc.c
@@ -42,43 +42,49 @@
|
||||
|
||||
/* {{{ libssh2_ntohu32
|
||||
*/
|
||||
unsigned long libssh2_ntohu32(const unsigned char *buf)
|
||||
unsigned long
|
||||
libssh2_ntohu32(const unsigned char *buf)
|
||||
{
|
||||
return (buf[0] << 24) | (buf[1] << 16) | (buf[2] << 8) | buf[3];
|
||||
}
|
||||
|
||||
/* }}} */
|
||||
|
||||
/* {{{ libssh2_ntohu64
|
||||
* Note: Some 32-bit platforms have issues with bitops on long longs
|
||||
* Work around this by doing expensive (but safer) arithmetic ops with optimization defying parentheses
|
||||
*
|
||||
*/
|
||||
libssh2_uint64_t libssh2_ntohu64(const unsigned char *buf)
|
||||
libssh2_uint64_t
|
||||
libssh2_ntohu64(const unsigned char *buf)
|
||||
{
|
||||
unsigned long msl, lsl;
|
||||
|
||||
msl = (buf[0] << 24) | (buf[1] << 16) | (buf[2] << 8) | buf[3];
|
||||
lsl = (buf[4] << 24) | (buf[5] << 16) | (buf[6] << 8) | buf[7];
|
||||
|
||||
return ((msl * 65536) * 65536) + lsl;
|
||||
return ((libssh2_uint64_t)msl <<32) | lsl;
|
||||
}
|
||||
|
||||
/* }}} */
|
||||
|
||||
/* {{{ libssh2_htonu32
|
||||
*/
|
||||
void libssh2_htonu32(unsigned char *buf, unsigned long value)
|
||||
void
|
||||
libssh2_htonu32(unsigned char *buf, unsigned long value)
|
||||
{
|
||||
buf[0] = (value >> 24) & 0xFF;
|
||||
buf[1] = (value >> 16) & 0xFF;
|
||||
buf[2] = (value >> 8) & 0xFF;
|
||||
buf[3] = value & 0xFF;
|
||||
}
|
||||
|
||||
/* }}} */
|
||||
|
||||
/* {{{ libssh2_htonu64
|
||||
*/
|
||||
void libssh2_htonu64(unsigned char *buf, libssh2_uint64_t value)
|
||||
void
|
||||
libssh2_htonu64(unsigned char *buf, libssh2_uint64_t value)
|
||||
{
|
||||
unsigned long msl = (value / 65536) / 65536;
|
||||
unsigned long msl = ((libssh2_uint64_t)value >> 32);
|
||||
|
||||
buf[0] = (msl >> 24) & 0xFF;
|
||||
buf[1] = (msl >> 16) & 0xFF;
|
||||
@@ -90,6 +96,7 @@ void libssh2_htonu64(unsigned char *buf, libssh2_uint64_t value)
|
||||
buf[6] = (value >> 8) & 0xFF;
|
||||
buf[7] = value & 0xFF;
|
||||
}
|
||||
|
||||
/* }}} */
|
||||
|
||||
/* Base64 Conversion */
|
||||
@@ -123,14 +130,17 @@ static const short libssh2_base64_reverse_table[256] = {
|
||||
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
|
||||
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1
|
||||
};
|
||||
|
||||
/* }}} */
|
||||
|
||||
|
||||
/* {{{ libssh2_base64_decode
|
||||
* Decode a base64 chunk and store it into a newly alloc'd buffer
|
||||
*/
|
||||
LIBSSH2_API int libssh2_base64_decode(LIBSSH2_SESSION *session, char **data, unsigned int *datalen,
|
||||
const char *src, unsigned int src_len)
|
||||
LIBSSH2_API int
|
||||
libssh2_base64_decode(LIBSSH2_SESSION * session, char **data,
|
||||
unsigned int *datalen, const char *src,
|
||||
unsigned int src_len)
|
||||
{
|
||||
unsigned char *s, *d;
|
||||
short v;
|
||||
@@ -143,7 +153,8 @@ LIBSSH2_API int libssh2_base64_decode(LIBSSH2_SESSION *session, char **data, uns
|
||||
}
|
||||
|
||||
for(s = (unsigned char *) src; ((char *) s) < (src + src_len); s++) {
|
||||
if ((v = libssh2_base64_reverse_table[*s]) < 0) continue;
|
||||
if ((v = libssh2_base64_reverse_table[*s]) < 0)
|
||||
continue;
|
||||
switch (i % 4) {
|
||||
case 0:
|
||||
d[len] = v << 2;
|
||||
@@ -171,17 +182,19 @@ LIBSSH2_API int libssh2_base64_decode(LIBSSH2_SESSION *session, char **data, uns
|
||||
*datalen = len;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* }}} */
|
||||
|
||||
#ifdef LIBSSH2DEBUG
|
||||
LIBSSH2_API int libssh2_trace(LIBSSH2_SESSION *session, int bitmask)
|
||||
LIBSSH2_API int
|
||||
libssh2_trace(LIBSSH2_SESSION * session, int bitmask)
|
||||
{
|
||||
session->showmask = bitmask;
|
||||
return 0;
|
||||
}
|
||||
|
||||
void _libssh2_debug(LIBSSH2_SESSION *session, int context,
|
||||
const char *format, ...)
|
||||
void
|
||||
_libssh2_debug(LIBSSH2_SESSION * session, int context, const char *format, ...)
|
||||
{
|
||||
char buffer[1536];
|
||||
int len;
|
||||
@@ -217,7 +230,8 @@ void _libssh2_debug(LIBSSH2_SESSION *session, int context,
|
||||
}
|
||||
|
||||
#else
|
||||
LIBSSH2_API int libssh2_trace(LIBSSH2_SESSION *session, int bitmask)
|
||||
LIBSSH2_API int
|
||||
libssh2_trace(LIBSSH2_SESSION * session, int bitmask)
|
||||
{
|
||||
(void) session;
|
||||
(void) bitmask;
|
||||
|
@@ -43,7 +43,8 @@
|
||||
#define EVP_MAX_BLOCK_LENGTH 32
|
||||
#endif
|
||||
|
||||
int _libssh2_rsa_new(libssh2_rsa_ctx **rsa,
|
||||
int
|
||||
_libssh2_rsa_new(libssh2_rsa_ctx ** rsa,
|
||||
const unsigned char *edata,
|
||||
unsigned long elen,
|
||||
const unsigned char *ndata,
|
||||
@@ -58,8 +59,7 @@ int _libssh2_rsa_new(libssh2_rsa_ctx **rsa,
|
||||
unsigned long e1len,
|
||||
const unsigned char *e2data,
|
||||
unsigned long e2len,
|
||||
const unsigned char *coeffdata,
|
||||
unsigned long coefflen)
|
||||
const unsigned char *coeffdata, unsigned long coefflen)
|
||||
{
|
||||
*rsa = RSA_new();
|
||||
|
||||
@@ -91,11 +91,11 @@ int _libssh2_rsa_new(libssh2_rsa_ctx **rsa,
|
||||
return 0;
|
||||
}
|
||||
|
||||
int _libssh2_rsa_sha1_verify(libssh2_rsa_ctx *rsactx,
|
||||
int
|
||||
_libssh2_rsa_sha1_verify(libssh2_rsa_ctx * rsactx,
|
||||
const unsigned char *sig,
|
||||
unsigned long sig_len,
|
||||
const unsigned char *m,
|
||||
unsigned long m_len)
|
||||
const unsigned char *m, unsigned long m_len)
|
||||
{
|
||||
unsigned char hash[SHA_DIGEST_LENGTH];
|
||||
int ret;
|
||||
@@ -106,7 +106,8 @@ int _libssh2_rsa_sha1_verify(libssh2_rsa_ctx *rsactx,
|
||||
return (ret == 1) ? 0 : -1;
|
||||
}
|
||||
|
||||
int _libssh2_dsa_new(libssh2_dsa_ctx **dsactx,
|
||||
int
|
||||
_libssh2_dsa_new(libssh2_dsa_ctx ** dsactx,
|
||||
const unsigned char *p,
|
||||
unsigned long p_len,
|
||||
const unsigned char *q,
|
||||
@@ -115,8 +116,7 @@ int _libssh2_dsa_new(libssh2_dsa_ctx **dsactx,
|
||||
unsigned long g_len,
|
||||
const unsigned char *y,
|
||||
unsigned long y_len,
|
||||
const unsigned char *x,
|
||||
unsigned long x_len)
|
||||
const unsigned char *x, unsigned long x_len)
|
||||
{
|
||||
*dsactx = DSA_new();
|
||||
|
||||
@@ -140,10 +140,10 @@ int _libssh2_dsa_new(libssh2_dsa_ctx **dsactx,
|
||||
return 0;
|
||||
}
|
||||
|
||||
int _libssh2_dsa_sha1_verify(libssh2_dsa_ctx *dsactx,
|
||||
int
|
||||
_libssh2_dsa_sha1_verify(libssh2_dsa_ctx * dsactx,
|
||||
const unsigned char *sig,
|
||||
const unsigned char *m,
|
||||
unsigned long m_len)
|
||||
const unsigned char *m, unsigned long m_len)
|
||||
{
|
||||
unsigned char hash[SHA_DIGEST_LENGTH];
|
||||
DSA_SIG dsasig;
|
||||
@@ -162,21 +162,20 @@ int _libssh2_dsa_sha1_verify(libssh2_dsa_ctx *dsactx,
|
||||
return (ret == 1) ? 0 : -1;
|
||||
}
|
||||
|
||||
int _libssh2_cipher_init (_libssh2_cipher_ctx *h,
|
||||
int
|
||||
_libssh2_cipher_init(_libssh2_cipher_ctx * h,
|
||||
_libssh2_cipher_type(algo),
|
||||
unsigned char *iv,
|
||||
unsigned char *secret,
|
||||
int encrypt)
|
||||
unsigned char *iv, unsigned char *secret, int encrypt)
|
||||
{
|
||||
EVP_CIPHER_CTX_init(h);
|
||||
EVP_CipherInit(h, algo(), secret, iv, encrypt);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int _libssh2_cipher_crypt(_libssh2_cipher_ctx *ctx,
|
||||
int
|
||||
_libssh2_cipher_crypt(_libssh2_cipher_ctx * ctx,
|
||||
_libssh2_cipher_type(algo),
|
||||
int encrypt,
|
||||
unsigned char *block)
|
||||
int encrypt, unsigned char *block)
|
||||
{
|
||||
int blocksize = ctx->cipher->block_size;
|
||||
unsigned char buf[EVP_MAX_BLOCK_LENGTH];
|
||||
@@ -199,8 +198,7 @@ int _libssh2_cipher_crypt(_libssh2_cipher_ctx *ctx,
|
||||
* calling program
|
||||
*/
|
||||
static int
|
||||
passphrase_cb(char *buf, int size,
|
||||
int rwflag, char *passphrase)
|
||||
passphrase_cb(char *buf, int size, int rwflag, char *passphrase)
|
||||
{
|
||||
int passphrase_len = strlen(passphrase);
|
||||
(void) rwflag;
|
||||
@@ -214,10 +212,10 @@ passphrase_cb(char *buf, int size,
|
||||
return passphrase_len;
|
||||
}
|
||||
|
||||
int _libssh2_rsa_new_private (libssh2_rsa_ctx **rsa,
|
||||
int
|
||||
_libssh2_rsa_new_private(libssh2_rsa_ctx ** rsa,
|
||||
LIBSSH2_SESSION * session,
|
||||
FILE *fp,
|
||||
unsigned const char *passphrase)
|
||||
FILE * fp, unsigned const char *passphrase)
|
||||
{
|
||||
(void) session;
|
||||
if (!EVP_get_cipherbyname("des")) {
|
||||
@@ -235,10 +233,10 @@ int _libssh2_rsa_new_private (libssh2_rsa_ctx **rsa,
|
||||
return 0;
|
||||
}
|
||||
|
||||
int _libssh2_dsa_new_private (libssh2_dsa_ctx **dsa,
|
||||
int
|
||||
_libssh2_dsa_new_private(libssh2_dsa_ctx ** dsa,
|
||||
LIBSSH2_SESSION * session,
|
||||
FILE *fp,
|
||||
unsigned const char *passphrase)
|
||||
FILE * fp, unsigned const char *passphrase)
|
||||
{
|
||||
(void) session;
|
||||
if (!EVP_get_cipherbyname("des")) {
|
||||
@@ -256,12 +254,12 @@ int _libssh2_dsa_new_private (libssh2_dsa_ctx **dsa,
|
||||
return 0;
|
||||
}
|
||||
|
||||
int _libssh2_rsa_sha1_sign(LIBSSH2_SESSION *session,
|
||||
int
|
||||
_libssh2_rsa_sha1_sign(LIBSSH2_SESSION * session,
|
||||
libssh2_rsa_ctx * rsactx,
|
||||
const unsigned char *hash,
|
||||
unsigned long hash_len,
|
||||
unsigned char **signature,
|
||||
unsigned long *signature_len)
|
||||
unsigned char **signature, unsigned long *signature_len)
|
||||
{
|
||||
int ret;
|
||||
unsigned char *sig;
|
||||
@@ -287,10 +285,10 @@ int _libssh2_rsa_sha1_sign(LIBSSH2_SESSION *session,
|
||||
return 0;
|
||||
}
|
||||
|
||||
int _libssh2_dsa_sha1_sign(libssh2_dsa_ctx *dsactx,
|
||||
int
|
||||
_libssh2_dsa_sha1_sign(libssh2_dsa_ctx * dsactx,
|
||||
const unsigned char *hash,
|
||||
unsigned long hash_len,
|
||||
unsigned char *signature)
|
||||
unsigned long hash_len, unsigned char *signature)
|
||||
{
|
||||
DSA_SIG *sig;
|
||||
int r_len, s_len, rs_pad;
|
||||
|
@@ -146,17 +146,14 @@ int _libssh2_rsa_new(libssh2_rsa_ctx **rsa,
|
||||
unsigned long e1len,
|
||||
const unsigned char *e2data,
|
||||
unsigned long e2len,
|
||||
const unsigned char *coeffdata,
|
||||
unsigned long coefflen);
|
||||
const unsigned char *coeffdata, unsigned long coefflen);
|
||||
int _libssh2_rsa_new_private(libssh2_rsa_ctx ** rsa,
|
||||
LIBSSH2_SESSION * session,
|
||||
FILE *fp,
|
||||
unsigned const char *passphrase);
|
||||
FILE * fp, unsigned const char *passphrase);
|
||||
int _libssh2_rsa_sha1_verify(libssh2_rsa_ctx * rsa,
|
||||
const unsigned char *sig,
|
||||
unsigned long sig_len,
|
||||
const unsigned char *m,
|
||||
unsigned long m_len);
|
||||
const unsigned char *m, unsigned long m_len);
|
||||
int _libssh2_rsa_sha1_sign(LIBSSH2_SESSION * session,
|
||||
libssh2_rsa_ctx * rsactx,
|
||||
const unsigned char *hash,
|
||||
@@ -177,20 +174,16 @@ int _libssh2_dsa_new(libssh2_dsa_ctx **dsa,
|
||||
unsigned long glen,
|
||||
const unsigned char *ydata,
|
||||
unsigned long ylen,
|
||||
const unsigned char *x,
|
||||
unsigned long x_len);
|
||||
const unsigned char *x, unsigned long x_len);
|
||||
int _libssh2_dsa_new_private(libssh2_dsa_ctx ** dsa,
|
||||
LIBSSH2_SESSION * session,
|
||||
FILE *fp,
|
||||
unsigned const char *passphrase);
|
||||
FILE * fp, unsigned const char *passphrase);
|
||||
int _libssh2_dsa_sha1_verify(libssh2_dsa_ctx * dsactx,
|
||||
const unsigned char *sig,
|
||||
const unsigned char *m,
|
||||
unsigned long m_len);
|
||||
const unsigned char *m, unsigned long m_len);
|
||||
int _libssh2_dsa_sha1_sign(libssh2_dsa_ctx * dsactx,
|
||||
const unsigned char *hash,
|
||||
unsigned long hash_len,
|
||||
unsigned char *sig);
|
||||
unsigned long hash_len, unsigned char *sig);
|
||||
|
||||
#define _libssh2_dsa_free(dsactx) DSA_free(dsactx)
|
||||
|
||||
@@ -208,13 +201,11 @@ int _libssh2_dsa_sha1_sign(libssh2_dsa_ctx *dsactx,
|
||||
int _libssh2_cipher_init(_libssh2_cipher_ctx * h,
|
||||
_libssh2_cipher_type(algo),
|
||||
unsigned char *iv,
|
||||
unsigned char *secret,
|
||||
int encrypt);
|
||||
unsigned char *secret, int encrypt);
|
||||
|
||||
int _libssh2_cipher_crypt(_libssh2_cipher_ctx * ctx,
|
||||
_libssh2_cipher_type(algo),
|
||||
int encrypt,
|
||||
unsigned char *block);
|
||||
int encrypt, unsigned char *block);
|
||||
|
||||
#define _libssh2_cipher_dtor(ctx) EVP_CIPHER_CTX_cleanup(ctx)
|
||||
|
||||
|
329
src/packet.c
329
src/packet.c
@@ -80,18 +80,27 @@ libssh2_packet_queue_listener(LIBSSH2_SESSION *session, unsigned char *data,
|
||||
(void) datalen;
|
||||
|
||||
if (listen_state->state == libssh2_NB_state_idle) {
|
||||
listen_state->sender_channel = libssh2_ntohu32(s); s += 4;
|
||||
listen_state->sender_channel = libssh2_ntohu32(s);
|
||||
s += 4;
|
||||
|
||||
listen_state->initial_window_size = libssh2_ntohu32(s); s += 4;
|
||||
listen_state->packet_size = libssh2_ntohu32(s); s += 4;
|
||||
listen_state->initial_window_size = libssh2_ntohu32(s);
|
||||
s += 4;
|
||||
listen_state->packet_size = libssh2_ntohu32(s);
|
||||
s += 4;
|
||||
|
||||
listen_state->host_len = libssh2_ntohu32(s); s += 4;
|
||||
listen_state->host = s; s += listen_state->host_len;
|
||||
listen_state->port = libssh2_ntohu32(s); s += 4;
|
||||
listen_state->host_len = libssh2_ntohu32(s);
|
||||
s += 4;
|
||||
listen_state->host = s;
|
||||
s += listen_state->host_len;
|
||||
listen_state->port = libssh2_ntohu32(s);
|
||||
s += 4;
|
||||
|
||||
listen_state->shost_len = libssh2_ntohu32(s); s += 4;
|
||||
listen_state->shost = s; s += listen_state->shost_len;
|
||||
listen_state->sport = libssh2_ntohu32(s); s += 4;
|
||||
listen_state->shost_len = libssh2_ntohu32(s);
|
||||
s += 4;
|
||||
listen_state->shost = s;
|
||||
s += listen_state->shost_len;
|
||||
listen_state->sport = libssh2_ntohu32(s);
|
||||
s += 4;
|
||||
|
||||
_libssh2_debug(session, LIBSSH2_DBG_CONN,
|
||||
"Remote received connection from %s:%ld to %s:%ld",
|
||||
@@ -105,7 +114,9 @@ libssh2_packet_queue_listener(LIBSSH2_SESSION *session, unsigned char *data,
|
||||
while (listen) {
|
||||
if ((listen->port == (int) listen_state->port) &&
|
||||
(strlen(listen->host) == listen_state->host_len) &&
|
||||
(memcmp(listen->host, listen_state->host, listen_state->host_len) == 0)) {
|
||||
(memcmp
|
||||
(listen->host, listen_state->host,
|
||||
listen_state->host_len) == 0)) {
|
||||
/* This is our listener */
|
||||
LIBSSH2_CHANNEL *channel, *last_queued = listen->queue;
|
||||
|
||||
@@ -135,7 +146,9 @@ libssh2_packet_queue_listener(LIBSSH2_SESSION *session, unsigned char *data,
|
||||
channel->session = session;
|
||||
channel->channel_type_len = sizeof("forwarded-tcpip") - 1;
|
||||
channel->channel_type = LIBSSH2_ALLOC(session,
|
||||
channel->channel_type_len + 1);
|
||||
channel->
|
||||
channel_type_len +
|
||||
1);
|
||||
if (!channel->channel_type) {
|
||||
libssh2_error(session, LIBSSH2_ERROR_ALLOC,
|
||||
"Unable to allocate a channel for new connection",
|
||||
@@ -149,13 +162,18 @@ libssh2_packet_queue_listener(LIBSSH2_SESSION *session, unsigned char *data,
|
||||
channel->channel_type_len + 1);
|
||||
|
||||
channel->remote.id = listen_state->sender_channel;
|
||||
channel->remote.window_size_initial = LIBSSH2_CHANNEL_WINDOW_DEFAULT;
|
||||
channel->remote.window_size = LIBSSH2_CHANNEL_WINDOW_DEFAULT;
|
||||
channel->remote.packet_size = LIBSSH2_CHANNEL_PACKET_DEFAULT;
|
||||
channel->remote.window_size_initial =
|
||||
LIBSSH2_CHANNEL_WINDOW_DEFAULT;
|
||||
channel->remote.window_size =
|
||||
LIBSSH2_CHANNEL_WINDOW_DEFAULT;
|
||||
channel->remote.packet_size =
|
||||
LIBSSH2_CHANNEL_PACKET_DEFAULT;
|
||||
|
||||
channel->local.id = libssh2_channel_nextid(session);
|
||||
channel->local.window_size_initial = listen_state->initial_window_size;
|
||||
channel->local.window_size = listen_state->initial_window_size;
|
||||
channel->local.window_size_initial =
|
||||
listen_state->initial_window_size;
|
||||
channel->local.window_size =
|
||||
listen_state->initial_window_size;
|
||||
channel->local.packet_size = listen_state->packet_size;
|
||||
|
||||
_libssh2_debug(session, LIBSSH2_DBG_CONN,
|
||||
@@ -185,8 +203,7 @@ libssh2_packet_queue_listener(LIBSSH2_SESSION *session, unsigned char *data,
|
||||
17);
|
||||
if (rc == PACKET_EAGAIN) {
|
||||
return PACKET_EAGAIN;
|
||||
}
|
||||
else if (rc) {
|
||||
} else if (rc) {
|
||||
libssh2_error(session, LIBSSH2_ERROR_SOCKET_SEND,
|
||||
"Unable to send channel open confirmation",
|
||||
0);
|
||||
@@ -239,8 +256,7 @@ libssh2_packet_queue_listener(LIBSSH2_SESSION *session, unsigned char *data,
|
||||
rc = libssh2_packet_write(session, listen_state->packet, packet_len);
|
||||
if (rc == PACKET_EAGAIN) {
|
||||
return PACKET_EAGAIN;
|
||||
}
|
||||
else if (rc) {
|
||||
} else if (rc) {
|
||||
libssh2_error(session, LIBSSH2_ERROR_SOCKET_SEND,
|
||||
"Unable to send open failure", 0);
|
||||
listen_state->state = libssh2_NB_state_idle;
|
||||
@@ -250,6 +266,7 @@ libssh2_packet_queue_listener(LIBSSH2_SESSION *session, unsigned char *data,
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
/* }}} */
|
||||
|
||||
/* {{{ libssh2_packet_x11_open
|
||||
@@ -271,12 +288,18 @@ libssh2_packet_x11_open(LIBSSH2_SESSION *session, unsigned char *data,
|
||||
(void) datalen;
|
||||
|
||||
if (x11open_state->state == libssh2_NB_state_idle) {
|
||||
x11open_state->sender_channel = libssh2_ntohu32(s); s += 4;
|
||||
x11open_state->initial_window_size = libssh2_ntohu32(s); s += 4;
|
||||
x11open_state->packet_size = libssh2_ntohu32(s); s += 4;
|
||||
x11open_state->shost_len = libssh2_ntohu32(s); s += 4;
|
||||
x11open_state->shost = s; s += x11open_state->shost_len;
|
||||
x11open_state->sport = libssh2_ntohu32(s); s += 4;
|
||||
x11open_state->sender_channel = libssh2_ntohu32(s);
|
||||
s += 4;
|
||||
x11open_state->initial_window_size = libssh2_ntohu32(s);
|
||||
s += 4;
|
||||
x11open_state->packet_size = libssh2_ntohu32(s);
|
||||
s += 4;
|
||||
x11open_state->shost_len = libssh2_ntohu32(s);
|
||||
s += 4;
|
||||
x11open_state->shost = s;
|
||||
s += x11open_state->shost_len;
|
||||
x11open_state->sport = libssh2_ntohu32(s);
|
||||
s += 4;
|
||||
|
||||
_libssh2_debug(session, LIBSSH2_DBG_CONN,
|
||||
"X11 Connection Received from %s:%ld on channel %lu",
|
||||
@@ -301,7 +324,8 @@ libssh2_packet_x11_open(LIBSSH2_SESSION *session, unsigned char *data,
|
||||
channel->session = session;
|
||||
channel->channel_type_len = sizeof("x11") - 1;
|
||||
channel->channel_type = LIBSSH2_ALLOC(session,
|
||||
channel->channel_type_len + 1);
|
||||
channel->channel_type_len +
|
||||
1);
|
||||
if (!channel->channel_type) {
|
||||
libssh2_error(session, LIBSSH2_ERROR_ALLOC,
|
||||
"Unable to allocate a channel for new connection",
|
||||
@@ -310,15 +334,18 @@ libssh2_packet_x11_open(LIBSSH2_SESSION *session, unsigned char *data,
|
||||
failure_code = 4; /* SSH_OPEN_RESOURCE_SHORTAGE */
|
||||
goto x11_exit;
|
||||
}
|
||||
memcpy(channel->channel_type, "x11", channel->channel_type_len + 1);
|
||||
memcpy(channel->channel_type, "x11",
|
||||
channel->channel_type_len + 1);
|
||||
|
||||
channel->remote.id = x11open_state->sender_channel;
|
||||
channel->remote.window_size_initial = LIBSSH2_CHANNEL_WINDOW_DEFAULT;
|
||||
channel->remote.window_size_initial =
|
||||
LIBSSH2_CHANNEL_WINDOW_DEFAULT;
|
||||
channel->remote.window_size = LIBSSH2_CHANNEL_WINDOW_DEFAULT;
|
||||
channel->remote.packet_size = LIBSSH2_CHANNEL_PACKET_DEFAULT;
|
||||
|
||||
channel->local.id = libssh2_channel_nextid(session);
|
||||
channel->local.window_size_initial = x11open_state->initial_window_size;
|
||||
channel->local.window_size_initial =
|
||||
x11open_state->initial_window_size;
|
||||
channel->local.window_size = x11open_state->initial_window_size;
|
||||
channel->local.packet_size = x11open_state->packet_size;
|
||||
|
||||
@@ -331,10 +358,14 @@ libssh2_packet_x11_open(LIBSSH2_SESSION *session, unsigned char *data,
|
||||
channel->remote.packet_size);
|
||||
p = x11open_state->packet;
|
||||
*(p++) = SSH_MSG_CHANNEL_OPEN_CONFIRMATION;
|
||||
libssh2_htonu32(p, channel->remote.id); p += 4;
|
||||
libssh2_htonu32(p, channel->local.id); p += 4;
|
||||
libssh2_htonu32(p, channel->remote.window_size_initial); p += 4;
|
||||
libssh2_htonu32(p, channel->remote.packet_size); p += 4;
|
||||
libssh2_htonu32(p, channel->remote.id);
|
||||
p += 4;
|
||||
libssh2_htonu32(p, channel->local.id);
|
||||
p += 4;
|
||||
libssh2_htonu32(p, channel->remote.window_size_initial);
|
||||
p += 4;
|
||||
libssh2_htonu32(p, channel->remote.packet_size);
|
||||
p += 4;
|
||||
|
||||
x11open_state->state = libssh2_NB_state_created;
|
||||
}
|
||||
@@ -343,8 +374,7 @@ libssh2_packet_x11_open(LIBSSH2_SESSION *session, unsigned char *data,
|
||||
rc = libssh2_packet_write(session, x11open_state->packet, 17);
|
||||
if (rc == PACKET_EAGAIN) {
|
||||
return PACKET_EAGAIN;
|
||||
}
|
||||
else if (rc) {
|
||||
} else if (rc) {
|
||||
libssh2_error(session, LIBSSH2_ERROR_SOCKET_SEND,
|
||||
"Unable to send channel open confirmation", 0);
|
||||
x11open_state->state = libssh2_NB_state_idle;
|
||||
@@ -366,7 +396,8 @@ libssh2_packet_x11_open(LIBSSH2_SESSION *session, unsigned char *data,
|
||||
* Pass control to the callback, they may turn right around and
|
||||
* free the channel, or actually use it
|
||||
*/
|
||||
LIBSSH2_X11_OPEN(channel, (char *)x11open_state->shost, x11open_state->sport);
|
||||
LIBSSH2_X11_OPEN(channel, (char *) x11open_state->shost,
|
||||
x11open_state->sport);
|
||||
|
||||
x11open_state->state = libssh2_NB_state_idle;
|
||||
return 0;
|
||||
@@ -378,9 +409,12 @@ libssh2_packet_x11_open(LIBSSH2_SESSION *session, unsigned char *data,
|
||||
x11_exit:
|
||||
p = x11open_state->packet;
|
||||
*(p++) = SSH_MSG_CHANNEL_OPEN_FAILURE;
|
||||
libssh2_htonu32(p, x11open_state->sender_channel); p += 4;
|
||||
libssh2_htonu32(p, failure_code); p += 4;
|
||||
libssh2_htonu32(p, sizeof(X11FwdUnAvil) - 1); p += 4;
|
||||
libssh2_htonu32(p, x11open_state->sender_channel);
|
||||
p += 4;
|
||||
libssh2_htonu32(p, failure_code);
|
||||
p += 4;
|
||||
libssh2_htonu32(p, sizeof(X11FwdUnAvil) - 1);
|
||||
p += 4;
|
||||
memcpy(s, X11FwdUnAvil, sizeof(X11FwdUnAvil) - 1);
|
||||
p += sizeof(X11FwdUnAvil) - 1;
|
||||
libssh2_htonu32(p, 0);
|
||||
@@ -388,8 +422,7 @@ x11_exit:
|
||||
rc = libssh2_packet_write(session, x11open_state->packet, packet_len);
|
||||
if (rc == PACKET_EAGAIN) {
|
||||
return PACKET_EAGAIN;
|
||||
}
|
||||
else if (rc) {
|
||||
} else if (rc) {
|
||||
libssh2_error(session, LIBSSH2_ERROR_SOCKET_SEND,
|
||||
"Unable to send open failure", 0);
|
||||
x11open_state->state = libssh2_NB_state_idle;
|
||||
@@ -398,12 +431,14 @@ x11_exit:
|
||||
x11open_state->state = libssh2_NB_state_idle;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* }}} */
|
||||
|
||||
/* {{{ libssh2_packet_new
|
||||
* Create a new packet and attach it to the brigade
|
||||
*/
|
||||
int libssh2_packet_add(LIBSSH2_SESSION *session, unsigned char *data,
|
||||
int
|
||||
libssh2_packet_add(LIBSSH2_SESSION * session, unsigned char *data,
|
||||
size_t datalen, int macstate)
|
||||
{
|
||||
int rc;
|
||||
@@ -469,11 +504,9 @@ int libssh2_packet_add(LIBSSH2_SESSION *session, unsigned char *data,
|
||||
*/
|
||||
if (session->packAdd_state == libssh2_NB_state_jump1) {
|
||||
goto libssh2_packet_add_jump_point1;
|
||||
}
|
||||
else if (session->packAdd_state == libssh2_NB_state_jump2) {
|
||||
} else if (session->packAdd_state == libssh2_NB_state_jump2) {
|
||||
goto libssh2_packet_add_jump_point2;
|
||||
}
|
||||
else if (session->packAdd_state == libssh2_NB_state_jump3) {
|
||||
} else if (session->packAdd_state == libssh2_NB_state_jump3) {
|
||||
goto libssh2_packet_add_jump_point3;
|
||||
}
|
||||
|
||||
@@ -586,7 +619,8 @@ int libssh2_packet_add(LIBSSH2_SESSION *session, unsigned char *data,
|
||||
session->packAdd_data_head += 9;
|
||||
{
|
||||
session->packAdd_channel = libssh2_channel_locate(session,
|
||||
libssh2_ntohu32(data + 1));
|
||||
libssh2_ntohu32
|
||||
(data + 1));
|
||||
|
||||
if (!session->packAdd_channel) {
|
||||
libssh2_error(session, LIBSSH2_ERROR_CHANNEL_UNKNOWN,
|
||||
@@ -606,14 +640,17 @@ int libssh2_packet_add(LIBSSH2_SESSION *session, unsigned char *data,
|
||||
|
||||
_libssh2_debug(session, LIBSSH2_DBG_CONN,
|
||||
"%d bytes received for channel %lu/%lu stream #%lu",
|
||||
(int)(datalen - session->packAdd_data_head),
|
||||
(int) (datalen -
|
||||
session->packAdd_data_head),
|
||||
session->packAdd_channel->local.id,
|
||||
session->packAdd_channel->remote.id,
|
||||
stream_id);
|
||||
}
|
||||
#endif
|
||||
if ((session->packAdd_channel->remote.extended_data_ignore_mode == LIBSSH2_CHANNEL_EXTENDED_DATA_IGNORE) &&
|
||||
(data[0] == SSH_MSG_CHANNEL_EXTENDED_DATA)) {
|
||||
if ((session->packAdd_channel->remote.
|
||||
extended_data_ignore_mode ==
|
||||
LIBSSH2_CHANNEL_EXTENDED_DATA_IGNORE)
|
||||
&& (data[0] == SSH_MSG_CHANNEL_EXTENDED_DATA)) {
|
||||
/* Pretend we didn't receive this */
|
||||
LIBSSH2_FREE(session, data);
|
||||
|
||||
@@ -623,9 +660,13 @@ int libssh2_packet_add(LIBSSH2_SESSION *session, unsigned char *data,
|
||||
/* Adjust the window based on the block we just freed */
|
||||
libssh2_packet_add_jump_point1:
|
||||
session->packAdd_state = libssh2_NB_state_jump1;
|
||||
rc = libssh2_channel_receive_window_adjust(session->packAdd_channel,
|
||||
datalen - 13, 0);
|
||||
rc = libssh2_channel_receive_window_adjust(session->
|
||||
packAdd_channel,
|
||||
datalen - 13,
|
||||
0);
|
||||
if (rc == PACKET_EAGAIN) {
|
||||
session->socket_block_directions =
|
||||
LIBSSH2_SESSION_BLOCK_OUTBOUND;
|
||||
return PACKET_EAGAIN;
|
||||
}
|
||||
session->packAdd_state = libssh2_NB_state_idle;
|
||||
@@ -636,7 +677,8 @@ libssh2_packet_add_jump_point1:
|
||||
* REMEMBER! remote means remote as source of data,
|
||||
* NOT remote window!
|
||||
*/
|
||||
if (session->packAdd_channel->remote.packet_size < (datalen - session->packAdd_data_head)) {
|
||||
if (session->packAdd_channel->remote.packet_size <
|
||||
(datalen - session->packAdd_data_head)) {
|
||||
/*
|
||||
* Spec says we MAY ignore bytes sent beyond
|
||||
* packet_size
|
||||
@@ -645,7 +687,9 @@ libssh2_packet_add_jump_point1:
|
||||
LIBSSH2_ERROR_CHANNEL_PACKET_EXCEEDED,
|
||||
"Packet contains more data than we offered to receive, truncating",
|
||||
0);
|
||||
datalen = session->packAdd_channel->remote.packet_size + session->packAdd_data_head;
|
||||
datalen =
|
||||
session->packAdd_channel->remote.packet_size +
|
||||
session->packAdd_data_head;
|
||||
}
|
||||
if (session->packAdd_channel->remote.window_size <= 0) {
|
||||
/*
|
||||
@@ -663,15 +707,19 @@ libssh2_packet_add_jump_point1:
|
||||
/* Reset EOF status */
|
||||
session->packAdd_channel->remote.eof = 0;
|
||||
|
||||
if ((datalen - session->packAdd_data_head) > session->packAdd_channel->remote.window_size) {
|
||||
if ((datalen - session->packAdd_data_head) >
|
||||
session->packAdd_channel->remote.window_size) {
|
||||
libssh2_error(session,
|
||||
LIBSSH2_ERROR_CHANNEL_WINDOW_EXCEEDED,
|
||||
"Remote sent more data than current window allows, truncating",
|
||||
0);
|
||||
datalen = session->packAdd_channel->remote.window_size + session->packAdd_data_head;
|
||||
datalen =
|
||||
session->packAdd_channel->remote.window_size +
|
||||
session->packAdd_data_head;
|
||||
} else {
|
||||
/* Now that we've received it, shrink our window */
|
||||
session->packAdd_channel->remote.window_size -= datalen - session->packAdd_data_head;
|
||||
session->packAdd_channel->remote.window_size -=
|
||||
datalen - session->packAdd_data_head;
|
||||
}
|
||||
}
|
||||
break;
|
||||
@@ -679,7 +727,8 @@ libssh2_packet_add_jump_point1:
|
||||
case SSH_MSG_CHANNEL_EOF:
|
||||
{
|
||||
session->packAdd_channel = libssh2_channel_locate(session,
|
||||
libssh2_ntohu32(data + 1));
|
||||
libssh2_ntohu32
|
||||
(data + 1));
|
||||
|
||||
if (!session->packAdd_channel) {
|
||||
/* We may have freed already, just quietly ignore this... */
|
||||
@@ -704,13 +753,17 @@ libssh2_packet_add_jump_point1:
|
||||
case SSH_MSG_CHANNEL_REQUEST:
|
||||
{
|
||||
if (libssh2_ntohu32(data + 5) == sizeof("exit-status") - 1
|
||||
&& !memcmp("exit-status", data + 9, sizeof("exit-status") - 1)) {
|
||||
&& !memcmp("exit-status", data + 9,
|
||||
sizeof("exit-status") - 1)) {
|
||||
|
||||
/* we've got "exit-status" packet. Set the session value */
|
||||
session->packAdd_channel = libssh2_channel_locate(session, libssh2_ntohu32(data+1));
|
||||
session->packAdd_channel =
|
||||
libssh2_channel_locate(session,
|
||||
libssh2_ntohu32(data + 1));
|
||||
|
||||
if (session->packAdd_channel) {
|
||||
session->packAdd_channel->exit_status = libssh2_ntohu32(data + 9 + sizeof("exit-status"));
|
||||
session->packAdd_channel->exit_status =
|
||||
libssh2_ntohu32(data + 9 + sizeof("exit-status"));
|
||||
_libssh2_debug(session, LIBSSH2_DBG_CONN,
|
||||
"Exit status %lu received for channel %lu/%lu",
|
||||
session->packAdd_channel->exit_status,
|
||||
@@ -728,7 +781,8 @@ libssh2_packet_add_jump_point1:
|
||||
case SSH_MSG_CHANNEL_CLOSE:
|
||||
{
|
||||
session->packAdd_channel = libssh2_channel_locate(session,
|
||||
libssh2_ntohu32(data + 1));
|
||||
libssh2_ntohu32
|
||||
(data + 1));
|
||||
|
||||
if (!session->packAdd_channel) {
|
||||
/* We may have freed already, just quietly ignore this... */
|
||||
@@ -753,14 +807,20 @@ libssh2_packet_add_jump_point1:
|
||||
|
||||
case SSH_MSG_CHANNEL_OPEN:
|
||||
if ((datalen >= (sizeof("forwarded-tcpip") + 4)) &&
|
||||
((sizeof("forwarded-tcpip")-1) == libssh2_ntohu32(data + 1)) &&
|
||||
(memcmp(data + 5, "forwarded-tcpip", sizeof("forwarded-tcpip") - 1) == 0)) {
|
||||
((sizeof("forwarded-tcpip") - 1) == libssh2_ntohu32(data + 1))
|
||||
&&
|
||||
(memcmp
|
||||
(data + 5, "forwarded-tcpip",
|
||||
sizeof("forwarded-tcpip") - 1) == 0)) {
|
||||
|
||||
libssh2_packet_add_jump_point2:
|
||||
session->packAdd_state = libssh2_NB_state_jump2;
|
||||
rc = libssh2_packet_queue_listener(session, data, datalen,
|
||||
&session->packAdd_Qlstn_state);
|
||||
&session->
|
||||
packAdd_Qlstn_state);
|
||||
if (rc == PACKET_EAGAIN) {
|
||||
session->socket_block_directions =
|
||||
LIBSSH2_SESSION_BLOCK_OUTBOUND;
|
||||
return PACKET_EAGAIN;
|
||||
}
|
||||
|
||||
@@ -777,6 +837,8 @@ libssh2_packet_add_jump_point3:
|
||||
rc = libssh2_packet_x11_open(session, data, datalen,
|
||||
&session->packAdd_x11open_state);
|
||||
if (rc == PACKET_EAGAIN) {
|
||||
session->socket_block_directions =
|
||||
LIBSSH2_SESSION_BLOCK_OUTBOUND;
|
||||
return PACKET_EAGAIN;
|
||||
}
|
||||
|
||||
@@ -790,7 +852,8 @@ libssh2_packet_add_jump_point3:
|
||||
{
|
||||
unsigned long bytestoadd = libssh2_ntohu32(data + 5);
|
||||
session->packAdd_channel = libssh2_channel_locate(session,
|
||||
libssh2_ntohu32(data + 1));
|
||||
libssh2_ntohu32
|
||||
(data + 1));
|
||||
|
||||
if (session->packAdd_channel && bytestoadd) {
|
||||
session->packAdd_channel->local.window_size += bytestoadd;
|
||||
@@ -813,7 +876,8 @@ libssh2_packet_add_jump_point3:
|
||||
}
|
||||
|
||||
if (session->packAdd_state == libssh2_NB_state_sent) {
|
||||
session->packAdd_packet = LIBSSH2_ALLOC(session, sizeof(LIBSSH2_PACKET));
|
||||
session->packAdd_packet =
|
||||
LIBSSH2_ALLOC(session, sizeof(LIBSSH2_PACKET));
|
||||
if (!session->packAdd_packet) {
|
||||
_libssh2_debug(session, LIBSSH2_ERROR_ALLOC,
|
||||
"Unable to allocate memory for LIBSSH2_PACKET");
|
||||
@@ -856,11 +920,31 @@ libssh2_packet_add_jump_point3:
|
||||
|
||||
session->packAdd_state = libssh2_NB_state_sent2;
|
||||
}
|
||||
|
||||
/*
|
||||
* The KEXINIT message has been added to the queue.
|
||||
* The packAdd and readPack states need to be reset
|
||||
* because libssh2_kex_exchange (eventually) calls upon
|
||||
* libssh2_packet_read to read the rest of the key exchange
|
||||
* conversation.
|
||||
*/
|
||||
session->readPack_state = libssh2_NB_state_idle;
|
||||
session->packet.total_num = 0;
|
||||
session->packAdd_state = libssh2_NB_state_idle;
|
||||
session->fullpacket_state = libssh2_NB_state_idle;
|
||||
|
||||
/*
|
||||
* Also, don't use packAdd_key_state for key re-exchange,
|
||||
* as it will be wiped out in the middle of the exchange.
|
||||
* How about re-using the startup_key_state?
|
||||
*/
|
||||
memset(&session->startup_key_state, 0, sizeof(key_exchange_state_t));
|
||||
|
||||
/*
|
||||
* If there was a key reexchange failure, let's just hope we didn't
|
||||
* send NEWKEYS yet, otherwise remote will drop us like a rock
|
||||
*/
|
||||
rc = libssh2_kex_exchange(session, 1, &session->packAdd_key_state);
|
||||
rc = libssh2_kex_exchange(session, 1, &session->startup_key_state);
|
||||
if (rc == PACKET_EAGAIN) {
|
||||
return PACKET_EAGAIN;
|
||||
}
|
||||
@@ -869,14 +953,18 @@ libssh2_packet_add_jump_point3:
|
||||
session->packAdd_state = libssh2_NB_state_idle;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* }}} */
|
||||
|
||||
/* {{{ libssh2_packet_ask
|
||||
* Scan the brigade for a matching packet type, optionally poll the socket for
|
||||
* a packet first
|
||||
*/
|
||||
int libssh2_packet_ask_ex(LIBSSH2_SESSION *session, unsigned char packet_type, unsigned char **data, unsigned long *data_len,
|
||||
unsigned long match_ofs, const unsigned char *match_buf, unsigned long match_len, int poll_socket)
|
||||
int
|
||||
libssh2_packet_ask_ex(LIBSSH2_SESSION * session, unsigned char packet_type,
|
||||
unsigned char **data, unsigned long *data_len,
|
||||
unsigned long match_ofs, const unsigned char *match_buf,
|
||||
unsigned long match_len, int poll_socket)
|
||||
{
|
||||
LIBSSH2_PACKET *packet = session->packets.head;
|
||||
|
||||
@@ -896,8 +984,16 @@ int libssh2_packet_ask_ex(LIBSSH2_SESSION *session, unsigned char packet_type, u
|
||||
"Looking for packet of type: %d", (int) packet_type);
|
||||
|
||||
while (packet) {
|
||||
if (packet->data[0] == packet_type && (packet->data_len >= (match_ofs + match_len)) &&
|
||||
(!match_buf || (memcmp(packet->data + match_ofs, match_buf, match_len) == 0))) {
|
||||
if (packet->data[0] == packet_type
|
||||
&& (packet->data_len >= (match_ofs + match_len)) && (!match_buf
|
||||
||
|
||||
(memcmp
|
||||
(packet->
|
||||
data +
|
||||
match_ofs,
|
||||
match_buf,
|
||||
match_len)
|
||||
== 0))) {
|
||||
*data = packet->data;
|
||||
*data_len = packet->data_len;
|
||||
|
||||
@@ -921,13 +1017,15 @@ int libssh2_packet_ask_ex(LIBSSH2_SESSION *session, unsigned char packet_type, u
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* }}} */
|
||||
|
||||
/* {{{ libssh2_packet_askv
|
||||
* Scan for any of a list of packet types in the brigade, optionally poll the
|
||||
* socket for a packet first
|
||||
*/
|
||||
int libssh2_packet_askv_ex(LIBSSH2_SESSION *session,
|
||||
int
|
||||
libssh2_packet_askv_ex(LIBSSH2_SESSION * session,
|
||||
const unsigned char *packet_types,
|
||||
unsigned char **data, unsigned long *data_len,
|
||||
unsigned long match_ofs,
|
||||
@@ -952,6 +1050,7 @@ int libssh2_packet_askv_ex(LIBSSH2_SESSION *session,
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* }}} */
|
||||
|
||||
/* {{{ waitsocket
|
||||
@@ -962,7 +1061,8 @@ int libssh2_packet_askv_ex(LIBSSH2_SESSION *session,
|
||||
*
|
||||
* FIXME: convert to use poll on systems that have it.
|
||||
*/
|
||||
int libssh2_waitsocket(LIBSSH2_SESSION *session, long seconds)
|
||||
int
|
||||
libssh2_waitsocket(LIBSSH2_SESSION * session, long seconds)
|
||||
{
|
||||
struct timeval timeout;
|
||||
int rc;
|
||||
@@ -987,42 +1087,48 @@ int libssh2_waitsocket(LIBSSH2_SESSION *session, long seconds)
|
||||
* Returns negative on error
|
||||
* Returns 0 when it has taken care of the requested packet.
|
||||
*/
|
||||
int libssh2_packet_require_ex(LIBSSH2_SESSION *session, unsigned char packet_type, unsigned char **data,
|
||||
unsigned long *data_len, unsigned long match_ofs, const unsigned char *match_buf,
|
||||
unsigned long match_len, packet_require_state_t *state)
|
||||
int
|
||||
libssh2_packet_require_ex(LIBSSH2_SESSION * session, unsigned char packet_type,
|
||||
unsigned char **data, unsigned long *data_len,
|
||||
unsigned long match_ofs,
|
||||
const unsigned char *match_buf,
|
||||
unsigned long match_len,
|
||||
packet_require_state_t * state)
|
||||
{
|
||||
if (state->start == 0) {
|
||||
if (libssh2_packet_ask_ex(session, packet_type, data, data_len, match_ofs, match_buf, match_len, 0) == 0) {
|
||||
if (libssh2_packet_ask_ex
|
||||
(session, packet_type, data, data_len, match_ofs, match_buf,
|
||||
match_len, 0) == 0) {
|
||||
/* A packet was available in the packet brigade */
|
||||
return 0;
|
||||
}
|
||||
|
||||
state->start = time(NULL);
|
||||
|
||||
_libssh2_debug(session, LIBSSH2_DBG_TRANS, "May block until packet of type %d becomes available", (int)packet_type);
|
||||
_libssh2_debug(session, LIBSSH2_DBG_TRANS,
|
||||
"May block until packet of type %d becomes available",
|
||||
(int) packet_type);
|
||||
}
|
||||
|
||||
while (session->socket_state == LIBSSH2_SOCKET_CONNECTED) {
|
||||
libssh2pack_t ret = libssh2_packet_read(session);
|
||||
if (ret == PACKET_EAGAIN) {
|
||||
return PACKET_EAGAIN;
|
||||
}
|
||||
else if ((ret == 0) && (!session->socket_block)) {
|
||||
} else if ((ret == 0) && (!session->socket_block)) {
|
||||
/* If we are in non-blocking and there is no data, return that */
|
||||
return PACKET_EAGAIN;
|
||||
}
|
||||
else if (ret < 0) {
|
||||
} else if (ret < 0) {
|
||||
state->start = 0;
|
||||
/* an error which is not just because of blocking */
|
||||
return ret;
|
||||
}
|
||||
else if (ret == packet_type) {
|
||||
} else if (ret == packet_type) {
|
||||
/* Be lazy, let packet_ask pull it out of the brigade */
|
||||
ret = libssh2_packet_ask_ex(session, packet_type, data, data_len, match_ofs, match_buf, match_len, 0);
|
||||
ret =
|
||||
libssh2_packet_ask_ex(session, packet_type, data, data_len,
|
||||
match_ofs, match_buf, match_len, 0);
|
||||
state->start = 0;
|
||||
return ret;
|
||||
}
|
||||
else if (ret == 0) {
|
||||
} else if (ret == 0) {
|
||||
/* nothing available, wait until data arrives or we time out */
|
||||
long left = LIBSSH2_READ_TIMEOUT - (time(NULL) - state->start);
|
||||
|
||||
@@ -1036,6 +1142,7 @@ int libssh2_packet_require_ex(LIBSSH2_SESSION *session, unsigned char packet_typ
|
||||
/* Only reached if the socket died */
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* }}} */
|
||||
|
||||
/* {{{ libssh2_packet_burn
|
||||
@@ -1043,7 +1150,9 @@ int libssh2_packet_require_ex(LIBSSH2_SESSION *session, unsigned char packet_typ
|
||||
* discards it
|
||||
* Used during KEX exchange to discard badly guessed KEX_INIT packets
|
||||
*/
|
||||
int libssh2_packet_burn(LIBSSH2_SESSION *session, libssh2_nonblocking_states *state)
|
||||
int
|
||||
libssh2_packet_burn(LIBSSH2_SESSION * session,
|
||||
libssh2_nonblocking_states * state)
|
||||
{
|
||||
unsigned char *data;
|
||||
unsigned long data_len;
|
||||
@@ -1056,32 +1165,34 @@ int libssh2_packet_burn(LIBSSH2_SESSION *session, libssh2_nonblocking_states *st
|
||||
all_packets[i - 1] = i;
|
||||
}
|
||||
|
||||
if (libssh2_packet_askv_ex(session, all_packets, &data, &data_len, 0, NULL, 0, 0) == 0) {
|
||||
if (libssh2_packet_askv_ex
|
||||
(session, all_packets, &data, &data_len, 0, NULL, 0, 0) == 0) {
|
||||
i = data[0];
|
||||
/* A packet was available in the packet brigade, burn it */
|
||||
LIBSSH2_FREE(session, data);
|
||||
return i;
|
||||
}
|
||||
|
||||
_libssh2_debug(session, LIBSSH2_DBG_TRANS, "Blocking until packet becomes available to burn");
|
||||
_libssh2_debug(session, LIBSSH2_DBG_TRANS,
|
||||
"Blocking until packet becomes available to burn");
|
||||
*state = libssh2_NB_state_created;
|
||||
}
|
||||
|
||||
while (session->socket_state == LIBSSH2_SOCKET_CONNECTED) {
|
||||
if ((ret = libssh2_packet_read(session)) == PACKET_EAGAIN) {
|
||||
return PACKET_EAGAIN;
|
||||
}
|
||||
else if (ret < 0) {
|
||||
} else if (ret < 0) {
|
||||
*state = libssh2_NB_state_idle;
|
||||
return ret;
|
||||
}
|
||||
else if (ret == 0) {
|
||||
} else if (ret == 0) {
|
||||
/* FIXME: this might busyloop */
|
||||
continue;
|
||||
}
|
||||
|
||||
/* Be lazy, let packet_ask pull it out of the brigade */
|
||||
if (0 == libssh2_packet_ask_ex(session, ret, &data, &data_len, 0, NULL, 0, 0)) {
|
||||
if (0 ==
|
||||
libssh2_packet_ask_ex(session, ret, &data, &data_len, 0, NULL, 0,
|
||||
0)) {
|
||||
/* Smoke 'em if you got 'em */
|
||||
LIBSSH2_FREE(session, data);
|
||||
*state = libssh2_NB_state_idle;
|
||||
@@ -1092,6 +1203,7 @@ int libssh2_packet_burn(LIBSSH2_SESSION *session, libssh2_nonblocking_states *st
|
||||
/* Only reached if the socket died */
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* }}} */
|
||||
|
||||
/*
|
||||
@@ -1103,11 +1215,18 @@ int libssh2_packet_burn(LIBSSH2_SESSION *session, libssh2_nonblocking_states *st
|
||||
* packet_types is a null terminated list of packet_type numbers
|
||||
*/
|
||||
|
||||
int libssh2_packet_requirev_ex(LIBSSH2_SESSION *session, const unsigned char *packet_types, unsigned char **data,
|
||||
unsigned long *data_len, unsigned long match_ofs, const unsigned char *match_buf,
|
||||
unsigned long match_len, packet_requirev_state_t *state)
|
||||
int
|
||||
libssh2_packet_requirev_ex(LIBSSH2_SESSION * session,
|
||||
const unsigned char *packet_types,
|
||||
unsigned char **data, unsigned long *data_len,
|
||||
unsigned long match_ofs,
|
||||
const unsigned char *match_buf,
|
||||
unsigned long match_len,
|
||||
packet_requirev_state_t * state)
|
||||
{
|
||||
if (libssh2_packet_askv_ex(session, packet_types, data, data_len, match_ofs, match_buf, match_len, 0) == 0) {
|
||||
if (libssh2_packet_askv_ex
|
||||
(session, packet_types, data, data_len, match_ofs, match_buf,
|
||||
match_len, 0) == 0) {
|
||||
/* One of the packets listed was available in the packet
|
||||
brigade */
|
||||
state->start = 0;
|
||||
@@ -1130,15 +1249,16 @@ int libssh2_packet_requirev_ex(LIBSSH2_SESSION *session, const unsigned char *pa
|
||||
if ((left <= 0) || (libssh2_waitsocket(session, left) <= 0)) {
|
||||
state->start = 0;
|
||||
return PACKET_TIMEOUT;
|
||||
}
|
||||
else if (ret == PACKET_EAGAIN) {
|
||||
} else if (ret == PACKET_EAGAIN) {
|
||||
return PACKET_EAGAIN;
|
||||
}
|
||||
}
|
||||
|
||||
if (strchr((char *) packet_types, ret)) {
|
||||
/* Be lazy, let packet_ask pull it out of the brigade */
|
||||
return libssh2_packet_askv_ex(session, packet_types, data, data_len, match_ofs, match_buf, match_len, 0);
|
||||
return libssh2_packet_askv_ex(session, packet_types, data,
|
||||
data_len, match_ofs, match_buf,
|
||||
match_len, 0);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1146,4 +1266,5 @@ int libssh2_packet_requirev_ex(LIBSSH2_SESSION *session, const unsigned char *pa
|
||||
state->start = 0;
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* }}} */
|
||||
|
98
src/pem.c
98
src/pem.c
@@ -1,5 +1,6 @@
|
||||
/* Copyright (C) 2007 The Written Word, Inc. All rights reserved.
|
||||
* Author: Simon Josefsson
|
||||
/* Copyright (C) 2007 The Written Word, Inc.
|
||||
* Copyright (C) 2008, Simon Josefsson
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms,
|
||||
* with or without modification, are permitted provided
|
||||
@@ -37,18 +38,16 @@
|
||||
|
||||
#include "libssh2_priv.h"
|
||||
|
||||
static int readline (char *line, int line_size, FILE *fp)
|
||||
{
|
||||
if (!fgets(line, line_size, fp))
|
||||
static int
|
||||
readline(char *line, int line_size, FILE * fp)
|
||||
{
|
||||
if (!fgets(line, line_size, fp)) {
|
||||
return -1;
|
||||
}
|
||||
if (*line && line[strlen(line) - 1] == '\n')
|
||||
{
|
||||
if (*line && line[strlen(line) - 1] == '\n') {
|
||||
line[strlen(line) - 1] = '\0';
|
||||
}
|
||||
if (*line && line[strlen(line) - 1] == '\r')
|
||||
{
|
||||
if (*line && line[strlen(line) - 1] == '\r') {
|
||||
line[strlen(line) - 1] = '\0';
|
||||
}
|
||||
return 0;
|
||||
@@ -56,21 +55,19 @@ static int readline (char *line, int line_size, FILE *fp)
|
||||
|
||||
#define LINE_SIZE 128
|
||||
|
||||
int _libssh2_pem_parse (LIBSSH2_SESSION *session,
|
||||
int
|
||||
_libssh2_pem_parse(LIBSSH2_SESSION * session,
|
||||
const char *headerbegin,
|
||||
const char *headerend,
|
||||
FILE *fp,
|
||||
char **data, unsigned int *datalen)
|
||||
FILE * fp, unsigned char **data, unsigned int *datalen)
|
||||
{
|
||||
char line[LINE_SIZE];
|
||||
char *b64data = NULL;
|
||||
unsigned int b64datalen = 0;
|
||||
int ret;
|
||||
|
||||
do
|
||||
{
|
||||
if (readline(line, LINE_SIZE, fp))
|
||||
{
|
||||
do {
|
||||
if (readline(line, LINE_SIZE, fp)) {
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
@@ -78,18 +75,14 @@ int _libssh2_pem_parse (LIBSSH2_SESSION *session,
|
||||
|
||||
*line = '\0';
|
||||
|
||||
do
|
||||
{
|
||||
if (*line)
|
||||
{
|
||||
do {
|
||||
if (*line) {
|
||||
char *tmp;
|
||||
size_t linelen;
|
||||
|
||||
linelen = strlen(line);
|
||||
tmp = LIBSSH2_REALLOC (session, b64data,
|
||||
b64datalen + linelen);
|
||||
if (!tmp)
|
||||
{
|
||||
tmp = LIBSSH2_REALLOC(session, b64data, b64datalen + linelen);
|
||||
if (!tmp) {
|
||||
ret = -1;
|
||||
goto out;
|
||||
}
|
||||
@@ -98,16 +91,14 @@ int _libssh2_pem_parse (LIBSSH2_SESSION *session,
|
||||
b64datalen += linelen;
|
||||
}
|
||||
|
||||
if (readline(line, LINE_SIZE, fp))
|
||||
{
|
||||
if (readline(line, LINE_SIZE, fp)) {
|
||||
ret = -1;
|
||||
goto out;
|
||||
}
|
||||
} while (strcmp(line, headerend) != 0);
|
||||
|
||||
if (libssh2_base64_decode(session, data, datalen,
|
||||
b64data, b64datalen))
|
||||
{
|
||||
if (libssh2_base64_decode(session, (char**) data, datalen,
|
||||
b64data, b64datalen)) {
|
||||
ret = -1;
|
||||
goto out;
|
||||
}
|
||||
@@ -120,59 +111,51 @@ out:
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int read_asn1_length (const unsigned char *data,
|
||||
unsigned int datalen,
|
||||
unsigned int *len)
|
||||
static int
|
||||
read_asn1_length(const unsigned char *data,
|
||||
unsigned int datalen, unsigned int *len)
|
||||
{
|
||||
unsigned int lenlen;
|
||||
int nextpos;
|
||||
|
||||
if (datalen < 1)
|
||||
{
|
||||
if (datalen < 1) {
|
||||
return -1;
|
||||
}
|
||||
*len = data[0];
|
||||
|
||||
if (*len >= 0x80)
|
||||
{
|
||||
if (*len >= 0x80) {
|
||||
lenlen = *len & 0x7F;
|
||||
*len = data[1];
|
||||
if (1 + lenlen > datalen)
|
||||
{
|
||||
if (1 + lenlen > datalen) {
|
||||
return -1;
|
||||
}
|
||||
if (lenlen > 1)
|
||||
{
|
||||
if (lenlen > 1) {
|
||||
*len <<= 8;
|
||||
*len |= data[2];
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
lenlen = 0;
|
||||
}
|
||||
|
||||
nextpos = 1 + lenlen;
|
||||
if (lenlen > 2 || 1 + lenlen + *len > datalen)
|
||||
{
|
||||
if (lenlen > 2 || 1 + lenlen + *len > datalen) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
return nextpos;
|
||||
}
|
||||
|
||||
int _libssh2_pem_decode_sequence (unsigned char **data, unsigned int *datalen)
|
||||
int
|
||||
_libssh2_pem_decode_sequence(unsigned char **data, unsigned int *datalen)
|
||||
{
|
||||
unsigned int len;
|
||||
int lenlen;
|
||||
|
||||
if (*datalen < 1)
|
||||
{
|
||||
if (*datalen < 1) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
if ((*data)[0] != '\x30')
|
||||
{
|
||||
if ((*data)[0] != '\x30') {
|
||||
return -1;
|
||||
}
|
||||
|
||||
@@ -180,8 +163,7 @@ int _libssh2_pem_decode_sequence (unsigned char **data, unsigned int *datalen)
|
||||
(*datalen)--;
|
||||
|
||||
lenlen = read_asn1_length(*data, *datalen, &len);
|
||||
if (lenlen < 0 || lenlen + len != *datalen)
|
||||
{
|
||||
if (lenlen < 0 || lenlen + len != *datalen) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
@@ -191,19 +173,18 @@ int _libssh2_pem_decode_sequence (unsigned char **data, unsigned int *datalen)
|
||||
return 0;
|
||||
}
|
||||
|
||||
int _libssh2_pem_decode_integer (unsigned char **data, unsigned int *datalen,
|
||||
int
|
||||
_libssh2_pem_decode_integer(unsigned char **data, unsigned int *datalen,
|
||||
unsigned char **i, unsigned int *ilen)
|
||||
{
|
||||
unsigned int len;
|
||||
int lenlen;
|
||||
|
||||
if (*datalen < 1)
|
||||
{
|
||||
if (*datalen < 1) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
if ((*data)[0] != '\x02')
|
||||
{
|
||||
if ((*data)[0] != '\x02') {
|
||||
return -1;
|
||||
}
|
||||
|
||||
@@ -211,8 +192,7 @@ int _libssh2_pem_decode_integer (unsigned char **data, unsigned int *datalen,
|
||||
(*datalen)--;
|
||||
|
||||
lenlen = read_asn1_length(*data, *datalen, &len);
|
||||
if (lenlen < 0 || lenlen + len > *datalen)
|
||||
{
|
||||
if (lenlen < 0 || lenlen + len > *datalen) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
572
src/publickey.c
572
src/publickey.c
File diff suppressed because it is too large
Load Diff
439
src/scp.c
439
src/scp.c
@@ -1,4 +1,4 @@
|
||||
/* Copyright (c) 2004-2007, Sara Golemon <sarag@libssh2.org>
|
||||
/* Copyright (c) 2004-2008, Sara Golemon <sarag@libssh2.org>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms,
|
||||
@@ -46,7 +46,8 @@
|
||||
* otherwise the blocking error code would erase the true
|
||||
* cause of the error.
|
||||
*/
|
||||
LIBSSH2_API LIBSSH2_CHANNEL *libssh2_scp_recv(LIBSSH2_SESSION *session, const char *path, struct stat *sb)
|
||||
LIBSSH2_API LIBSSH2_CHANNEL *
|
||||
libssh2_scp_recv(LIBSSH2_SESSION * session, const char *path, struct stat * sb)
|
||||
{
|
||||
int path_len = strlen(path);
|
||||
int rc;
|
||||
@@ -63,21 +64,28 @@ LIBSSH2_API LIBSSH2_CHANNEL *libssh2_scp_recv(LIBSSH2_SESSION *session, const ch
|
||||
session->scpRecv_command_len++;
|
||||
}
|
||||
|
||||
session->scpRecv_command = LIBSSH2_ALLOC(session, session->scpRecv_command_len);
|
||||
session->scpRecv_command =
|
||||
LIBSSH2_ALLOC(session, session->scpRecv_command_len);
|
||||
if (!session->scpRecv_command) {
|
||||
libssh2_error(session, LIBSSH2_ERROR_ALLOC, "Unable to allocate a command buffer for SCP session", 0);
|
||||
libssh2_error(session, LIBSSH2_ERROR_ALLOC,
|
||||
"Unable to allocate a command buffer for SCP session",
|
||||
0);
|
||||
return NULL;
|
||||
}
|
||||
if (sb) {
|
||||
memcpy(session->scpRecv_command, "scp -pf ", sizeof("scp -pf ") - 1);
|
||||
memcpy(session->scpRecv_command + sizeof("scp -pf ") - 1, path, path_len);
|
||||
memcpy(session->scpRecv_command, "scp -pf ",
|
||||
sizeof("scp -pf ") - 1);
|
||||
memcpy(session->scpRecv_command + sizeof("scp -pf ") - 1, path,
|
||||
path_len);
|
||||
} else {
|
||||
memcpy(session->scpRecv_command, "scp -f ", sizeof("scp -f ") - 1);
|
||||
memcpy(session->scpRecv_command + sizeof("scp -f ") - 1, path, path_len);
|
||||
memcpy(session->scpRecv_command + sizeof("scp -f ") - 1, path,
|
||||
path_len);
|
||||
}
|
||||
session->scpRecv_command[session->scpRecv_command_len - 1] = '\0';
|
||||
|
||||
_libssh2_debug(session, LIBSSH2_DBG_SCP, "Opening channel for SCP receive");
|
||||
_libssh2_debug(session, LIBSSH2_DBG_SCP,
|
||||
"Opening channel for SCP receive");
|
||||
|
||||
session->scpRecv_state = libssh2_NB_state_created;
|
||||
}
|
||||
@@ -85,18 +93,23 @@ LIBSSH2_API LIBSSH2_CHANNEL *libssh2_scp_recv(LIBSSH2_SESSION *session, const ch
|
||||
if (session->scpRecv_state == libssh2_NB_state_created) {
|
||||
/* Allocate a channel */
|
||||
do {
|
||||
session->scpRecv_channel = libssh2_channel_open_ex(session, "session", sizeof("session") - 1,
|
||||
LIBSSH2_CHANNEL_WINDOW_DEFAULT, LIBSSH2_CHANNEL_PACKET_DEFAULT,
|
||||
NULL, 0);
|
||||
session->scpRecv_channel =
|
||||
libssh2_channel_open_ex(session, "session",
|
||||
sizeof("session") - 1,
|
||||
LIBSSH2_CHANNEL_WINDOW_DEFAULT,
|
||||
LIBSSH2_CHANNEL_PACKET_DEFAULT, NULL,
|
||||
0);
|
||||
if (!session->scpRecv_channel) {
|
||||
if (libssh2_session_last_errno(session) != LIBSSH2_ERROR_EAGAIN) {
|
||||
if (libssh2_session_last_errno(session) !=
|
||||
LIBSSH2_ERROR_EAGAIN) {
|
||||
LIBSSH2_FREE(session, session->scpRecv_command);
|
||||
session->scpRecv_command = NULL;
|
||||
session->scpRecv_state = libssh2_NB_state_idle;
|
||||
return NULL;
|
||||
}
|
||||
else if (libssh2_session_last_errno(session) == LIBSSH2_ERROR_EAGAIN) {
|
||||
libssh2_error(session, LIBSSH2_ERROR_EAGAIN, "Would block starting up channel", 0);
|
||||
} else if (libssh2_session_last_errno(session) ==
|
||||
LIBSSH2_ERROR_EAGAIN) {
|
||||
libssh2_error(session, LIBSSH2_ERROR_EAGAIN,
|
||||
"Would block starting up channel", 0);
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
@@ -107,12 +120,15 @@ LIBSSH2_API LIBSSH2_CHANNEL *libssh2_scp_recv(LIBSSH2_SESSION *session, const ch
|
||||
|
||||
if (session->scpRecv_state == libssh2_NB_state_sent) {
|
||||
/* Request SCP for the desired file */
|
||||
rc = libssh2_channel_process_startup(session->scpRecv_channel, "exec", sizeof("exec") - 1, (char *)session->scpRecv_command, session->scpRecv_command_len);
|
||||
rc = libssh2_channel_process_startup(session->scpRecv_channel, "exec",
|
||||
sizeof("exec") - 1,
|
||||
(char *) session->scpRecv_command,
|
||||
session->scpRecv_command_len);
|
||||
if (rc == PACKET_EAGAIN) {
|
||||
libssh2_error(session, LIBSSH2_ERROR_EAGAIN, "Would block requesting SCP startup", 0);
|
||||
libssh2_error(session, LIBSSH2_ERROR_EAGAIN,
|
||||
"Would block requesting SCP startup", 0);
|
||||
return NULL;
|
||||
}
|
||||
else if (rc) {
|
||||
} else if (rc) {
|
||||
LIBSSH2_FREE(session, session->scpRecv_command);
|
||||
session->scpRecv_command = NULL;
|
||||
goto scp_recv_error;
|
||||
@@ -128,12 +144,13 @@ LIBSSH2_API LIBSSH2_CHANNEL *libssh2_scp_recv(LIBSSH2_SESSION *session, const ch
|
||||
}
|
||||
|
||||
if (session->scpRecv_state == libssh2_NB_state_sent1) {
|
||||
rc = libssh2_channel_write_ex(session->scpRecv_channel, 0, (char *)session->scpRecv_response, 1);
|
||||
rc = libssh2_channel_write_ex(session->scpRecv_channel, 0,
|
||||
(char *) session->scpRecv_response, 1);
|
||||
if (rc == PACKET_EAGAIN) {
|
||||
libssh2_error(session, LIBSSH2_ERROR_EAGAIN, "Would block sending initial wakeup", 0);
|
||||
libssh2_error(session, LIBSSH2_ERROR_EAGAIN,
|
||||
"Would block sending initial wakeup", 0);
|
||||
return NULL;
|
||||
}
|
||||
else if (rc != 1) {
|
||||
} else if (rc != 1) {
|
||||
goto scp_recv_error;
|
||||
}
|
||||
|
||||
@@ -143,20 +160,26 @@ LIBSSH2_API LIBSSH2_CHANNEL *libssh2_scp_recv(LIBSSH2_SESSION *session, const ch
|
||||
session->scpRecv_state = libssh2_NB_state_sent2;
|
||||
}
|
||||
|
||||
if ((session->scpRecv_state == libssh2_NB_state_sent2) || (session->scpRecv_state == libssh2_NB_state_sent3)) {
|
||||
while (sb && (session->scpRecv_response_len < LIBSSH2_SCP_RESPONSE_BUFLEN)) {
|
||||
if ((session->scpRecv_state == libssh2_NB_state_sent2)
|
||||
|| (session->scpRecv_state == libssh2_NB_state_sent3)) {
|
||||
while (sb
|
||||
&& (session->scpRecv_response_len <
|
||||
LIBSSH2_SCP_RESPONSE_BUFLEN)) {
|
||||
unsigned char *s, *p;
|
||||
|
||||
if (session->scpRecv_state == libssh2_NB_state_sent2) {
|
||||
rc = libssh2_channel_read_ex(session->scpRecv_channel, 0,
|
||||
(char *)session->scpRecv_response + session->scpRecv_response_len, 1);
|
||||
(char *) session->
|
||||
scpRecv_response +
|
||||
session->scpRecv_response_len, 1);
|
||||
if (rc == PACKET_EAGAIN) {
|
||||
libssh2_error(session, LIBSSH2_ERROR_EAGAIN, "Would block waiting for SCP response", 0);
|
||||
libssh2_error(session, LIBSSH2_ERROR_EAGAIN,
|
||||
"Would block waiting for SCP response", 0);
|
||||
return NULL;
|
||||
}
|
||||
else if (rc <= 0) {
|
||||
} else if (rc <= 0) {
|
||||
/* Timeout, give up */
|
||||
libssh2_error(session, LIBSSH2_ERROR_SCP_PROTOCOL, "Timed out waiting for SCP response", 0);
|
||||
libssh2_error(session, LIBSSH2_ERROR_SCP_PROTOCOL,
|
||||
"Timed out waiting for SCP response", 0);
|
||||
goto scp_recv_error;
|
||||
}
|
||||
session->scpRecv_response_len++;
|
||||
@@ -166,17 +189,25 @@ LIBSSH2_API LIBSSH2_CHANNEL *libssh2_scp_recv(LIBSSH2_SESSION *session, const ch
|
||||
* Set this as the default error for here, if
|
||||
* we are successful it will be replaced
|
||||
*/
|
||||
libssh2_error(session, LIBSSH2_ERROR_SCP_PROTOCOL, "Invalid data in SCP response, missing Time data", 0);
|
||||
libssh2_error(session, LIBSSH2_ERROR_SCP_PROTOCOL,
|
||||
"Invalid data in SCP response, missing Time data",
|
||||
0);
|
||||
|
||||
session->scpRecv_err_len = libssh2_channel_packet_data_len(session->scpRecv_channel, 0);
|
||||
session->scpRecv_err_msg = LIBSSH2_ALLOC(session, session->scpRecv_err_len+1);
|
||||
session->scpRecv_err_len =
|
||||
libssh2_channel_packet_data_len(session->
|
||||
scpRecv_channel, 0);
|
||||
session->scpRecv_err_msg =
|
||||
LIBSSH2_ALLOC(session, session->scpRecv_err_len + 1);
|
||||
if (!session->scpRecv_err_msg) {
|
||||
goto scp_recv_error;
|
||||
}
|
||||
memset(session->scpRecv_err_msg, 0, session->scpRecv_err_len+1);
|
||||
memset(session->scpRecv_err_msg, 0,
|
||||
session->scpRecv_err_len + 1);
|
||||
|
||||
/* Read the remote error message */
|
||||
rc = libssh2_channel_read_ex(session->scpRecv_channel, 0, session->scpRecv_err_msg, session->scpRecv_err_len);
|
||||
rc = libssh2_channel_read_ex(session->scpRecv_channel, 0,
|
||||
session->scpRecv_err_msg,
|
||||
session->scpRecv_err_len);
|
||||
if (rc <= 0) {
|
||||
/*
|
||||
* Since we have alread started reading this packet, it is
|
||||
@@ -184,29 +215,49 @@ LIBSSH2_API LIBSSH2_CHANNEL *libssh2_scp_recv(LIBSSH2_SESSION *session, const ch
|
||||
*/
|
||||
LIBSSH2_FREE(session, session->scpRecv_err_msg);
|
||||
session->scpRecv_err_msg = NULL;
|
||||
libssh2_error(session, LIBSSH2_ERROR_SCP_PROTOCOL, "Unknown error while getting error string", 0);
|
||||
libssh2_error(session, LIBSSH2_ERROR_SCP_PROTOCOL,
|
||||
"Unknown error while getting error string",
|
||||
0);
|
||||
goto scp_recv_error;
|
||||
}
|
||||
|
||||
libssh2_error(session, LIBSSH2_ERROR_SCP_PROTOCOL, session->scpRecv_err_msg, 1);
|
||||
libssh2_error(session, LIBSSH2_ERROR_SCP_PROTOCOL,
|
||||
session->scpRecv_err_msg, 1);
|
||||
session->scpRecv_err_msg = NULL;
|
||||
goto scp_recv_error;
|
||||
}
|
||||
|
||||
if ((session->scpRecv_response_len > 1) &&
|
||||
((session->scpRecv_response[session->scpRecv_response_len-1] < '0') ||
|
||||
(session->scpRecv_response[session->scpRecv_response_len-1] > '9')) &&
|
||||
(session->scpRecv_response[session->scpRecv_response_len-1] != ' ') &&
|
||||
(session->scpRecv_response[session->scpRecv_response_len-1] != '\r') &&
|
||||
(session->scpRecv_response[session->scpRecv_response_len-1] != '\n')) {
|
||||
libssh2_error(session, LIBSSH2_ERROR_SCP_PROTOCOL, "Invalid data in SCP response", 0);
|
||||
((session->
|
||||
scpRecv_response[session->scpRecv_response_len - 1] <
|
||||
'0')
|
||||
|| (session->
|
||||
scpRecv_response[session->scpRecv_response_len - 1] >
|
||||
'9'))
|
||||
&& (session->
|
||||
scpRecv_response[session->scpRecv_response_len - 1] !=
|
||||
' ')
|
||||
&& (session->
|
||||
scpRecv_response[session->scpRecv_response_len - 1] !=
|
||||
'\r')
|
||||
&& (session->
|
||||
scpRecv_response[session->scpRecv_response_len - 1] !=
|
||||
'\n')) {
|
||||
libssh2_error(session, LIBSSH2_ERROR_SCP_PROTOCOL,
|
||||
"Invalid data in SCP response", 0);
|
||||
goto scp_recv_error;
|
||||
}
|
||||
|
||||
if ((session->scpRecv_response_len < 9) || (session->scpRecv_response[session->scpRecv_response_len-1] != '\n')) {
|
||||
if (session->scpRecv_response_len == LIBSSH2_SCP_RESPONSE_BUFLEN) {
|
||||
if ((session->scpRecv_response_len < 9)
|
||||
|| (session->
|
||||
scpRecv_response[session->scpRecv_response_len - 1] !=
|
||||
'\n')) {
|
||||
if (session->scpRecv_response_len ==
|
||||
LIBSSH2_SCP_RESPONSE_BUFLEN) {
|
||||
/* You had your chance */
|
||||
libssh2_error(session, LIBSSH2_ERROR_SCP_PROTOCOL, "Unterminated response from SCP server", 0);
|
||||
libssh2_error(session, LIBSSH2_ERROR_SCP_PROTOCOL,
|
||||
"Unterminated response from SCP server",
|
||||
0);
|
||||
goto scp_recv_error;
|
||||
}
|
||||
/* Way too short to be an SCP response, or not done yet, short circuit */
|
||||
@@ -214,12 +265,21 @@ LIBSSH2_API LIBSSH2_CHANNEL *libssh2_scp_recv(LIBSSH2_SESSION *session, const ch
|
||||
}
|
||||
|
||||
/* We're guaranteed not to go under response_len == 0 by the logic above */
|
||||
while ((session->scpRecv_response[session->scpRecv_response_len-1] == '\r') || (session->scpRecv_response[session->scpRecv_response_len-1] == '\n')) session->scpRecv_response_len--;
|
||||
session->scpRecv_response[session->scpRecv_response_len] = '\0';
|
||||
while ((session->
|
||||
scpRecv_response[session->scpRecv_response_len - 1] ==
|
||||
'\r')
|
||||
|| (session->
|
||||
scpRecv_response[session->scpRecv_response_len -
|
||||
1] == '\n'))
|
||||
session->scpRecv_response_len--;
|
||||
session->scpRecv_response[session->scpRecv_response_len] =
|
||||
'\0';
|
||||
|
||||
if (session->scpRecv_response_len < 8) {
|
||||
/* EOL came too soon */
|
||||
libssh2_error(session, LIBSSH2_ERROR_SCP_PROTOCOL, "Invalid response from SCP server, too short", 0);
|
||||
libssh2_error(session, LIBSSH2_ERROR_SCP_PROTOCOL,
|
||||
"Invalid response from SCP server, too short",
|
||||
0);
|
||||
goto scp_recv_error;
|
||||
}
|
||||
|
||||
@@ -228,7 +288,9 @@ LIBSSH2_API LIBSSH2_CHANNEL *libssh2_scp_recv(LIBSSH2_SESSION *session, const ch
|
||||
p = (unsigned char *) strchr((char *) s, ' ');
|
||||
if (!p || ((p - s) <= 0)) {
|
||||
/* No spaces or space in the wrong spot */
|
||||
libssh2_error(session, LIBSSH2_ERROR_SCP_PROTOCOL, "Invalid response from SCP server, malformed mtime", 0);
|
||||
libssh2_error(session, LIBSSH2_ERROR_SCP_PROTOCOL,
|
||||
"Invalid response from SCP server, malformed mtime",
|
||||
0);
|
||||
goto scp_recv_error;
|
||||
}
|
||||
|
||||
@@ -237,13 +299,17 @@ LIBSSH2_API LIBSSH2_CHANNEL *libssh2_scp_recv(LIBSSH2_SESSION *session, const ch
|
||||
errno = 0;
|
||||
session->scpRecv_mtime = strtol((char *) s, NULL, 10);
|
||||
if (errno) {
|
||||
libssh2_error(session, LIBSSH2_ERROR_SCP_PROTOCOL, "Invalid response from SCP server, invalid mtime", 0);
|
||||
libssh2_error(session, LIBSSH2_ERROR_SCP_PROTOCOL,
|
||||
"Invalid response from SCP server, invalid mtime",
|
||||
0);
|
||||
goto scp_recv_error;
|
||||
}
|
||||
s = (unsigned char *) strchr((char *) p, ' ');
|
||||
if (!s || ((s - p) <= 0)) {
|
||||
/* No spaces or space in the wrong spot */
|
||||
libssh2_error(session, LIBSSH2_ERROR_SCP_PROTOCOL, "Invalid response from SCP server, malformed mtime.usec", 0);
|
||||
libssh2_error(session, LIBSSH2_ERROR_SCP_PROTOCOL,
|
||||
"Invalid response from SCP server, malformed mtime.usec",
|
||||
0);
|
||||
goto scp_recv_error;
|
||||
}
|
||||
|
||||
@@ -252,7 +318,9 @@ LIBSSH2_API LIBSSH2_CHANNEL *libssh2_scp_recv(LIBSSH2_SESSION *session, const ch
|
||||
p = (unsigned char *) strchr((char *) s, ' ');
|
||||
if (!p || ((p - s) <= 0)) {
|
||||
/* No spaces or space in the wrong spot */
|
||||
libssh2_error(session, LIBSSH2_ERROR_SCP_PROTOCOL, "Invalid response from SCP server, too short or malformed", 0);
|
||||
libssh2_error(session, LIBSSH2_ERROR_SCP_PROTOCOL,
|
||||
"Invalid response from SCP server, too short or malformed",
|
||||
0);
|
||||
goto scp_recv_error;
|
||||
}
|
||||
|
||||
@@ -261,7 +329,9 @@ LIBSSH2_API LIBSSH2_CHANNEL *libssh2_scp_recv(LIBSSH2_SESSION *session, const ch
|
||||
errno = 0;
|
||||
session->scpRecv_atime = strtol((char *) s, NULL, 10);
|
||||
if (errno) {
|
||||
libssh2_error(session, LIBSSH2_ERROR_SCP_PROTOCOL, "Invalid response from SCP server, invalid atime", 0);
|
||||
libssh2_error(session, LIBSSH2_ERROR_SCP_PROTOCOL,
|
||||
"Invalid response from SCP server, invalid atime",
|
||||
0);
|
||||
goto scp_recv_error;
|
||||
}
|
||||
|
||||
@@ -272,16 +342,20 @@ LIBSSH2_API LIBSSH2_CHANNEL *libssh2_scp_recv(LIBSSH2_SESSION *session, const ch
|
||||
}
|
||||
|
||||
if (session->scpRecv_state == libssh2_NB_state_sent3) {
|
||||
rc = libssh2_channel_write_ex(session->scpRecv_channel, 0, (char *)session->scpRecv_response, 1);
|
||||
rc = libssh2_channel_write_ex(session->scpRecv_channel, 0,
|
||||
(char *) session->
|
||||
scpRecv_response, 1);
|
||||
if (rc == PACKET_EAGAIN) {
|
||||
libssh2_error(session, LIBSSH2_ERROR_EAGAIN, "Would block waiting to send SCP ACK", 0);
|
||||
libssh2_error(session, LIBSSH2_ERROR_EAGAIN,
|
||||
"Would block waiting to send SCP ACK", 0);
|
||||
return NULL;
|
||||
}
|
||||
else if (rc != 1) {
|
||||
} else if (rc != 1) {
|
||||
goto scp_recv_error;
|
||||
}
|
||||
|
||||
_libssh2_debug(session, LIBSSH2_DBG_SCP, "mtime = %ld, atime = %ld", session->scpRecv_mtime, session->scpRecv_atime);
|
||||
_libssh2_debug(session, LIBSSH2_DBG_SCP,
|
||||
"mtime = %ld, atime = %ld",
|
||||
session->scpRecv_mtime, session->scpRecv_atime);
|
||||
|
||||
/* We *should* check that atime.usec is valid, but why let that stop use? */
|
||||
break;
|
||||
@@ -297,42 +371,62 @@ LIBSSH2_API LIBSSH2_CHANNEL *libssh2_scp_recv(LIBSSH2_SESSION *session, const ch
|
||||
session->scpRecv_state = libssh2_NB_state_sent5;
|
||||
}
|
||||
|
||||
if ((session->scpRecv_state == libssh2_NB_state_sent5) || (session->scpRecv_state == libssh2_NB_state_sent6)) {
|
||||
if ((session->scpRecv_state == libssh2_NB_state_sent5)
|
||||
|| (session->scpRecv_state == libssh2_NB_state_sent6)) {
|
||||
while (session->scpRecv_response_len < LIBSSH2_SCP_RESPONSE_BUFLEN) {
|
||||
char *s, *p, *e = NULL;
|
||||
|
||||
if (session->scpRecv_state == libssh2_NB_state_sent5) {
|
||||
rc = libssh2_channel_read_ex(session->scpRecv_channel, 0,
|
||||
(char *)session->scpRecv_response + session->scpRecv_response_len, 1);
|
||||
(char *) session->
|
||||
scpRecv_response +
|
||||
session->scpRecv_response_len, 1);
|
||||
if (rc == PACKET_EAGAIN) {
|
||||
libssh2_error(session, LIBSSH2_ERROR_EAGAIN, "Would block waiting for SCP response", 0);
|
||||
libssh2_error(session, LIBSSH2_ERROR_EAGAIN,
|
||||
"Would block waiting for SCP response", 0);
|
||||
return NULL;
|
||||
}
|
||||
else if (rc <= 0) {
|
||||
} else if (rc <= 0) {
|
||||
/* Timeout, give up */
|
||||
libssh2_error(session, LIBSSH2_ERROR_SCP_PROTOCOL, "Timed out waiting for SCP response", 0);
|
||||
libssh2_error(session, LIBSSH2_ERROR_SCP_PROTOCOL,
|
||||
"Timed out waiting for SCP response", 0);
|
||||
goto scp_recv_error;
|
||||
}
|
||||
session->scpRecv_response_len++;
|
||||
|
||||
if (session->scpRecv_response[0] != 'C') {
|
||||
libssh2_error(session, LIBSSH2_ERROR_SCP_PROTOCOL, "Invalid response from SCP server", 0);
|
||||
libssh2_error(session, LIBSSH2_ERROR_SCP_PROTOCOL,
|
||||
"Invalid response from SCP server", 0);
|
||||
goto scp_recv_error;
|
||||
}
|
||||
|
||||
if ((session->scpRecv_response_len > 1) &&
|
||||
(session->scpRecv_response[session->scpRecv_response_len-1] != '\r') &&
|
||||
(session->scpRecv_response[session->scpRecv_response_len-1] != '\n') &&
|
||||
((session->scpRecv_response[session->scpRecv_response_len-1] < 32) ||
|
||||
(session->scpRecv_response[session->scpRecv_response_len-1] > 126))) {
|
||||
libssh2_error(session, LIBSSH2_ERROR_SCP_PROTOCOL, "Invalid data in SCP response", 0);
|
||||
(session->
|
||||
scpRecv_response[session->scpRecv_response_len - 1] !=
|
||||
'\r')
|
||||
&& (session->
|
||||
scpRecv_response[session->scpRecv_response_len - 1] !=
|
||||
'\n')
|
||||
&&
|
||||
((session->
|
||||
scpRecv_response[session->scpRecv_response_len - 1] < 32)
|
||||
|| (session->
|
||||
scpRecv_response[session->scpRecv_response_len - 1] >
|
||||
126))) {
|
||||
libssh2_error(session, LIBSSH2_ERROR_SCP_PROTOCOL,
|
||||
"Invalid data in SCP response", 0);
|
||||
goto scp_recv_error;
|
||||
}
|
||||
|
||||
if ((session->scpRecv_response_len < 7) || (session->scpRecv_response[session->scpRecv_response_len-1] != '\n')) {
|
||||
if (session->scpRecv_response_len == LIBSSH2_SCP_RESPONSE_BUFLEN) {
|
||||
if ((session->scpRecv_response_len < 7)
|
||||
|| (session->
|
||||
scpRecv_response[session->scpRecv_response_len - 1] !=
|
||||
'\n')) {
|
||||
if (session->scpRecv_response_len ==
|
||||
LIBSSH2_SCP_RESPONSE_BUFLEN) {
|
||||
/* You had your chance */
|
||||
libssh2_error(session, LIBSSH2_ERROR_SCP_PROTOCOL, "Unterminated response from SCP server", 0);
|
||||
libssh2_error(session, LIBSSH2_ERROR_SCP_PROTOCOL,
|
||||
"Unterminated response from SCP server",
|
||||
0);
|
||||
goto scp_recv_error;
|
||||
}
|
||||
/* Way too short to be an SCP response, or not done yet, short circuit */
|
||||
@@ -340,15 +434,22 @@ LIBSSH2_API LIBSSH2_CHANNEL *libssh2_scp_recv(LIBSSH2_SESSION *session, const ch
|
||||
}
|
||||
|
||||
/* We're guaranteed not to go under response_len == 0 by the logic above */
|
||||
while ((session->scpRecv_response[session->scpRecv_response_len-1] == '\r') ||
|
||||
(session->scpRecv_response[session->scpRecv_response_len-1] == '\n')) {
|
||||
while ((session->
|
||||
scpRecv_response[session->scpRecv_response_len - 1] ==
|
||||
'\r')
|
||||
|| (session->
|
||||
scpRecv_response[session->scpRecv_response_len -
|
||||
1] == '\n')) {
|
||||
session->scpRecv_response_len--;
|
||||
}
|
||||
session->scpRecv_response[session->scpRecv_response_len] = '\0';
|
||||
session->scpRecv_response[session->scpRecv_response_len] =
|
||||
'\0';
|
||||
|
||||
if (session->scpRecv_response_len < 6) {
|
||||
/* EOL came too soon */
|
||||
libssh2_error(session, LIBSSH2_ERROR_SCP_PROTOCOL, "Invalid response from SCP server, too short", 0);
|
||||
libssh2_error(session, LIBSSH2_ERROR_SCP_PROTOCOL,
|
||||
"Invalid response from SCP server, too short",
|
||||
0);
|
||||
goto scp_recv_error;
|
||||
}
|
||||
|
||||
@@ -357,7 +458,9 @@ LIBSSH2_API LIBSSH2_CHANNEL *libssh2_scp_recv(LIBSSH2_SESSION *session, const ch
|
||||
p = strchr(s, ' ');
|
||||
if (!p || ((p - s) <= 0)) {
|
||||
/* No spaces or space in the wrong spot */
|
||||
libssh2_error(session, LIBSSH2_ERROR_SCP_PROTOCOL, "Invalid response from SCP server, malformed mode", 0);
|
||||
libssh2_error(session, LIBSSH2_ERROR_SCP_PROTOCOL,
|
||||
"Invalid response from SCP server, malformed mode",
|
||||
0);
|
||||
goto scp_recv_error;
|
||||
}
|
||||
|
||||
@@ -366,14 +469,17 @@ LIBSSH2_API LIBSSH2_CHANNEL *libssh2_scp_recv(LIBSSH2_SESSION *session, const ch
|
||||
errno = 0;
|
||||
session->scpRecv_mode = strtol(s, &e, 8);
|
||||
if ((e && *e) || errno) {
|
||||
libssh2_error(session, LIBSSH2_ERROR_SCP_PROTOCOL, "Invalid response from SCP server, invalid mode", 0);
|
||||
libssh2_error(session, LIBSSH2_ERROR_SCP_PROTOCOL,
|
||||
"Invalid response from SCP server, invalid mode",
|
||||
0);
|
||||
goto scp_recv_error;
|
||||
}
|
||||
|
||||
s = strchr(p, ' ');
|
||||
if (!s || ((s - p) <= 0)) {
|
||||
/* No spaces or space in the wrong spot */
|
||||
libssh2_error(session, LIBSSH2_ERROR_SCP_PROTOCOL, "Invalid response from SCP server, too short or malformed",
|
||||
libssh2_error(session, LIBSSH2_ERROR_SCP_PROTOCOL,
|
||||
"Invalid response from SCP server, too short or malformed",
|
||||
0);
|
||||
goto scp_recv_error;
|
||||
}
|
||||
@@ -381,9 +487,11 @@ LIBSSH2_API LIBSSH2_CHANNEL *libssh2_scp_recv(LIBSSH2_SESSION *session, const ch
|
||||
*(s++) = '\0';
|
||||
/* Make sure we don't get fooled by leftover values */
|
||||
errno = 0;
|
||||
session->scpRecv_size = strtol(p, &e, 10);
|
||||
session->scpRecv_size = scpsize_strtol(p, &e, 10);
|
||||
if ((e && *e) || errno) {
|
||||
libssh2_error(session, LIBSSH2_ERROR_SCP_PROTOCOL, "Invalid response from SCP server, invalid size", 0);
|
||||
libssh2_error(session, LIBSSH2_ERROR_SCP_PROTOCOL,
|
||||
"Invalid response from SCP server, invalid size",
|
||||
0);
|
||||
goto scp_recv_error;
|
||||
}
|
||||
|
||||
@@ -394,15 +502,19 @@ LIBSSH2_API LIBSSH2_CHANNEL *libssh2_scp_recv(LIBSSH2_SESSION *session, const ch
|
||||
}
|
||||
|
||||
if (session->scpRecv_state == libssh2_NB_state_sent6) {
|
||||
rc = libssh2_channel_write_ex(session->scpRecv_channel, 0, (char *)session->scpRecv_response, 1);
|
||||
rc = libssh2_channel_write_ex(session->scpRecv_channel, 0,
|
||||
(char *) session->
|
||||
scpRecv_response, 1);
|
||||
if (rc == PACKET_EAGAIN) {
|
||||
libssh2_error(session, LIBSSH2_ERROR_EAGAIN, "Would block sending SCP ACK", 0);
|
||||
libssh2_error(session, LIBSSH2_ERROR_EAGAIN,
|
||||
"Would block sending SCP ACK", 0);
|
||||
return NULL;
|
||||
}
|
||||
else if (rc != 1) {
|
||||
} else if (rc != 1) {
|
||||
goto scp_recv_error;
|
||||
}
|
||||
_libssh2_debug(session, LIBSSH2_DBG_SCP, "mode = 0%lo size = %ld", session->scpRecv_mode, session->scpRecv_size);
|
||||
_libssh2_debug(session, LIBSSH2_DBG_SCP,
|
||||
"mode = 0%lo size = %ld", session->scpRecv_mode,
|
||||
session->scpRecv_size);
|
||||
|
||||
/* We *should* check that basename is valid, but why let that stop us? */
|
||||
break;
|
||||
@@ -430,6 +542,7 @@ scp_recv_error:
|
||||
session->scpRecv_state = libssh2_NB_state_idle;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* }}} */
|
||||
|
||||
/* {{{ libssh2_scp_send_ex
|
||||
@@ -440,7 +553,8 @@ scp_recv_error:
|
||||
* cause of the error.
|
||||
*/
|
||||
LIBSSH2_API LIBSSH2_CHANNEL *
|
||||
libssh2_scp_send_ex(LIBSSH2_SESSION *session, const char *path, int mode, size_t size, long mtime, long atime)
|
||||
libssh2_scp_send_ex(LIBSSH2_SESSION * session, const char *path, int mode,
|
||||
size_t size, long mtime, long atime)
|
||||
{
|
||||
int path_len = strlen(path);
|
||||
unsigned const char *base;
|
||||
@@ -453,30 +567,39 @@ libssh2_scp_send_ex(LIBSSH2_SESSION *session, const char *path, int mode, size_t
|
||||
session->scpSend_command_len++;
|
||||
}
|
||||
|
||||
session->scpSend_command = LIBSSH2_ALLOC(session, session->scpSend_command_len);
|
||||
session->scpSend_command =
|
||||
LIBSSH2_ALLOC(session, session->scpSend_command_len);
|
||||
if (!session->scpSend_command) {
|
||||
libssh2_error(session, LIBSSH2_ERROR_ALLOC, "Unable to allocate a command buffer for scp session", 0);
|
||||
libssh2_error(session, LIBSSH2_ERROR_ALLOC,
|
||||
"Unable to allocate a command buffer for scp session",
|
||||
0);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (mtime || atime) {
|
||||
memcpy(session->scpSend_command, "scp -pt ", sizeof("scp -pt ") - 1);
|
||||
memcpy(session->scpSend_command + sizeof("scp -pt ") - 1, path, path_len);
|
||||
memcpy(session->scpSend_command, "scp -pt ",
|
||||
sizeof("scp -pt ") - 1);
|
||||
memcpy(session->scpSend_command + sizeof("scp -pt ") - 1, path,
|
||||
path_len);
|
||||
} else {
|
||||
memcpy(session->scpSend_command, "scp -t ", sizeof("scp -t ") - 1);
|
||||
memcpy(session->scpSend_command + sizeof("scp -t ") - 1, path, path_len);
|
||||
memcpy(session->scpSend_command + sizeof("scp -t ") - 1, path,
|
||||
path_len);
|
||||
}
|
||||
session->scpSend_command[session->scpSend_command_len - 1] = '\0';
|
||||
|
||||
_libssh2_debug(session, LIBSSH2_DBG_SCP, "Opening channel for SCP send");
|
||||
_libssh2_debug(session, LIBSSH2_DBG_SCP,
|
||||
"Opening channel for SCP send");
|
||||
/* Allocate a channel */
|
||||
|
||||
session->scpSend_state = libssh2_NB_state_created;
|
||||
}
|
||||
|
||||
if (session->scpSend_state == libssh2_NB_state_created) {
|
||||
session->scpSend_channel = libssh2_channel_open_ex(session, "session", sizeof("session") - 1,
|
||||
LIBSSH2_CHANNEL_WINDOW_DEFAULT, LIBSSH2_CHANNEL_PACKET_DEFAULT, NULL, 0);
|
||||
session->scpSend_channel =
|
||||
libssh2_channel_open_ex(session, "session", sizeof("session") - 1,
|
||||
LIBSSH2_CHANNEL_WINDOW_DEFAULT,
|
||||
LIBSSH2_CHANNEL_PACKET_DEFAULT, NULL, 0);
|
||||
if (!session->scpSend_channel) {
|
||||
if (libssh2_session_last_errno(session) != LIBSSH2_ERROR_EAGAIN) {
|
||||
/* previous call set libssh2_session_last_error(), pass it through */
|
||||
@@ -484,9 +607,10 @@ libssh2_scp_send_ex(LIBSSH2_SESSION *session, const char *path, int mode, size_t
|
||||
session->scpSend_command = NULL;
|
||||
session->scpSend_state = libssh2_NB_state_idle;
|
||||
return NULL;
|
||||
}
|
||||
else if (libssh2_session_last_errno(session) == LIBSSH2_ERROR_EAGAIN) {
|
||||
libssh2_error(session, LIBSSH2_ERROR_EAGAIN, "Would block starting up channel", 0);
|
||||
} else if (libssh2_session_last_errno(session) ==
|
||||
LIBSSH2_ERROR_EAGAIN) {
|
||||
libssh2_error(session, LIBSSH2_ERROR_EAGAIN,
|
||||
"Would block starting up channel", 0);
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
@@ -496,17 +620,20 @@ libssh2_scp_send_ex(LIBSSH2_SESSION *session, const char *path, int mode, size_t
|
||||
|
||||
if (session->scpSend_state == libssh2_NB_state_sent) {
|
||||
/* Request SCP for the desired file */
|
||||
rc = libssh2_channel_process_startup(session->scpSend_channel, "exec", sizeof("exec") - 1,
|
||||
(char *)session->scpSend_command, session->scpSend_command_len);
|
||||
rc = libssh2_channel_process_startup(session->scpSend_channel, "exec",
|
||||
sizeof("exec") - 1,
|
||||
(char *) session->scpSend_command,
|
||||
session->scpSend_command_len);
|
||||
if (rc == PACKET_EAGAIN) {
|
||||
libssh2_error(session, LIBSSH2_ERROR_EAGAIN, "Would block requesting SCP startup", 0);
|
||||
libssh2_error(session, LIBSSH2_ERROR_EAGAIN,
|
||||
"Would block requesting SCP startup", 0);
|
||||
return NULL;
|
||||
}
|
||||
else if (rc) {
|
||||
} else if (rc) {
|
||||
/* previous call set libssh2_session_last_error(), pass it through */
|
||||
LIBSSH2_FREE(session, session->scpSend_command);
|
||||
session->scpSend_command = NULL;
|
||||
libssh2_error(session, LIBSSH2_ERROR_SCP_PROTOCOL, "Unknown error while getting error string", 0);
|
||||
libssh2_error(session, LIBSSH2_ERROR_SCP_PROTOCOL,
|
||||
"Unknown error while getting error string", 0);
|
||||
goto scp_send_error;
|
||||
}
|
||||
LIBSSH2_FREE(session, session->scpSend_command);
|
||||
@@ -517,21 +644,26 @@ libssh2_scp_send_ex(LIBSSH2_SESSION *session, const char *path, int mode, size_t
|
||||
|
||||
if (session->scpSend_state == libssh2_NB_state_sent1) {
|
||||
/* Wait for ACK */
|
||||
rc = libssh2_channel_read_ex(session->scpSend_channel, 0, (char *)session->scpSend_response, 1);
|
||||
rc = libssh2_channel_read_ex(session->scpSend_channel, 0,
|
||||
(char *) session->scpSend_response, 1);
|
||||
if (rc == PACKET_EAGAIN) {
|
||||
libssh2_error(session, LIBSSH2_ERROR_EAGAIN, "Would block waiting for response from remote", 0);
|
||||
libssh2_error(session, LIBSSH2_ERROR_EAGAIN,
|
||||
"Would block waiting for response from remote", 0);
|
||||
return NULL;
|
||||
}
|
||||
else if ((rc <= 0) || (session->scpSend_response[0] != 0)) {
|
||||
libssh2_error(session, LIBSSH2_ERROR_SCP_PROTOCOL, "Invalid ACK response from remote", 0);
|
||||
} else if ((rc <= 0) || (session->scpSend_response[0] != 0)) {
|
||||
libssh2_error(session, LIBSSH2_ERROR_SCP_PROTOCOL,
|
||||
"Invalid ACK response from remote", 0);
|
||||
goto scp_send_error;
|
||||
}
|
||||
|
||||
if (mtime || atime) {
|
||||
/* Send mtime and atime to be used for file */
|
||||
session->scpSend_response_len = snprintf((char *)session->scpSend_response, LIBSSH2_SCP_RESPONSE_BUFLEN,
|
||||
"T%ld 0 %ld 0\n", mtime, atime);
|
||||
_libssh2_debug(session, LIBSSH2_DBG_SCP, "Sent %s", session->scpSend_response);
|
||||
session->scpSend_response_len =
|
||||
snprintf((char *) session->scpSend_response,
|
||||
LIBSSH2_SCP_RESPONSE_BUFLEN, "T%ld 0 %ld 0\n", mtime,
|
||||
atime);
|
||||
_libssh2_debug(session, LIBSSH2_DBG_SCP, "Sent %s",
|
||||
session->scpSend_response);
|
||||
}
|
||||
|
||||
session->scpSend_state = libssh2_NB_state_sent2;
|
||||
@@ -540,14 +672,16 @@ libssh2_scp_send_ex(LIBSSH2_SESSION *session, const char *path, int mode, size_t
|
||||
/* Send mtime and atime to be used for file */
|
||||
if (mtime || atime) {
|
||||
if (session->scpSend_state == libssh2_NB_state_sent2) {
|
||||
rc = libssh2_channel_write_ex(session->scpSend_channel, 0, (char *)session->scpSend_response,
|
||||
rc = libssh2_channel_write_ex(session->scpSend_channel, 0,
|
||||
(char *) session->scpSend_response,
|
||||
session->scpSend_response_len);
|
||||
if (rc == PACKET_EAGAIN) {
|
||||
libssh2_error(session, LIBSSH2_ERROR_EAGAIN, "Would block sending time data for SCP file", 0);
|
||||
libssh2_error(session, LIBSSH2_ERROR_EAGAIN,
|
||||
"Would block sending time data for SCP file", 0);
|
||||
return NULL;
|
||||
}
|
||||
else if (rc != session->scpSend_response_len) {
|
||||
libssh2_error(session, LIBSSH2_ERROR_SOCKET_SEND, "Unable to send time data for SCP file", 0);
|
||||
} else if (rc != session->scpSend_response_len) {
|
||||
libssh2_error(session, LIBSSH2_ERROR_SOCKET_SEND,
|
||||
"Unable to send time data for SCP file", 0);
|
||||
goto scp_send_error;
|
||||
}
|
||||
|
||||
@@ -556,13 +690,16 @@ libssh2_scp_send_ex(LIBSSH2_SESSION *session, const char *path, int mode, size_t
|
||||
|
||||
if (session->scpSend_state == libssh2_NB_state_sent3) {
|
||||
/* Wait for ACK */
|
||||
rc = libssh2_channel_read_ex(session->scpSend_channel, 0, (char *)session->scpSend_response, 1);
|
||||
rc = libssh2_channel_read_ex(session->scpSend_channel, 0,
|
||||
(char *) session->scpSend_response,
|
||||
1);
|
||||
if (rc == PACKET_EAGAIN) {
|
||||
libssh2_error(session, LIBSSH2_ERROR_EAGAIN, "Would block waiting for response", 0);
|
||||
libssh2_error(session, LIBSSH2_ERROR_EAGAIN,
|
||||
"Would block waiting for response", 0);
|
||||
return NULL;
|
||||
}
|
||||
else if ((rc <= 0) || (session->scpSend_response[0] != 0)) {
|
||||
libssh2_error(session, LIBSSH2_ERROR_SCP_PROTOCOL, "Invalid ACK response from remote", 0);
|
||||
} else if ((rc <= 0) || (session->scpSend_response[0] != 0)) {
|
||||
libssh2_error(session, LIBSSH2_ERROR_SCP_PROTOCOL,
|
||||
"Invalid ACK response from remote", 0);
|
||||
goto scp_send_error;
|
||||
}
|
||||
|
||||
@@ -583,22 +720,27 @@ libssh2_scp_send_ex(LIBSSH2_SESSION *session, const char *path, int mode, size_t
|
||||
base = (unsigned char *) path;
|
||||
}
|
||||
|
||||
session->scpSend_response_len = snprintf((char *)session->scpSend_response, LIBSSH2_SCP_RESPONSE_BUFLEN,
|
||||
"C0%o %lu %s\n", mode, (unsigned long)size, base);
|
||||
_libssh2_debug(session, LIBSSH2_DBG_SCP, "Sent %s", session->scpSend_response);
|
||||
session->scpSend_response_len =
|
||||
snprintf((char *) session->scpSend_response,
|
||||
LIBSSH2_SCP_RESPONSE_BUFLEN, "C0%o %lu %s\n", mode,
|
||||
(unsigned long) size, base);
|
||||
_libssh2_debug(session, LIBSSH2_DBG_SCP, "Sent %s",
|
||||
session->scpSend_response);
|
||||
|
||||
session->scpSend_state = libssh2_NB_state_sent5;
|
||||
}
|
||||
|
||||
if (session->scpSend_state == libssh2_NB_state_sent5) {
|
||||
rc = libssh2_channel_write_ex(session->scpSend_channel, 0, (char *)session->scpSend_response,
|
||||
rc = libssh2_channel_write_ex(session->scpSend_channel, 0,
|
||||
(char *) session->scpSend_response,
|
||||
session->scpSend_response_len);
|
||||
if (rc == PACKET_EAGAIN) {
|
||||
libssh2_error(session, LIBSSH2_ERROR_EAGAIN, "Would block send core file data for SCP file", 0);
|
||||
libssh2_error(session, LIBSSH2_ERROR_EAGAIN,
|
||||
"Would block send core file data for SCP file", 0);
|
||||
return NULL;
|
||||
}
|
||||
else if (rc != session->scpSend_response_len) {
|
||||
libssh2_error(session, LIBSSH2_ERROR_SOCKET_SEND, "Unable to send core file data for SCP file", 0);
|
||||
} else if (rc != session->scpSend_response_len) {
|
||||
libssh2_error(session, LIBSSH2_ERROR_SOCKET_SEND,
|
||||
"Unable to send core file data for SCP file", 0);
|
||||
goto scp_send_error;
|
||||
}
|
||||
|
||||
@@ -607,31 +749,37 @@ libssh2_scp_send_ex(LIBSSH2_SESSION *session, const char *path, int mode, size_t
|
||||
|
||||
if (session->scpSend_state == libssh2_NB_state_sent6) {
|
||||
/* Wait for ACK */
|
||||
rc = libssh2_channel_read_ex(session->scpSend_channel, 0, (char *)session->scpSend_response, 1);
|
||||
rc = libssh2_channel_read_ex(session->scpSend_channel, 0,
|
||||
(char *) session->scpSend_response, 1);
|
||||
if (rc == PACKET_EAGAIN) {
|
||||
libssh2_error(session, LIBSSH2_ERROR_EAGAIN, "Would block waiting for response", 0);
|
||||
libssh2_error(session, LIBSSH2_ERROR_EAGAIN,
|
||||
"Would block waiting for response", 0);
|
||||
return NULL;
|
||||
}
|
||||
else if (rc <= 0) {
|
||||
libssh2_error(session, LIBSSH2_ERROR_SCP_PROTOCOL, "Invalid ACK response from remote", 0);
|
||||
} else if (rc <= 0) {
|
||||
libssh2_error(session, LIBSSH2_ERROR_SCP_PROTOCOL,
|
||||
"Invalid ACK response from remote", 0);
|
||||
goto scp_send_error;
|
||||
}
|
||||
else if (session->scpSend_response[0] != 0) {
|
||||
} else if (session->scpSend_response[0] != 0) {
|
||||
/*
|
||||
* Set this as the default error for here, if
|
||||
* we are successful it will be replaced
|
||||
*/
|
||||
libssh2_error(session, LIBSSH2_ERROR_SCP_PROTOCOL, "Invalid ACK response from remote", 0);
|
||||
libssh2_error(session, LIBSSH2_ERROR_SCP_PROTOCOL,
|
||||
"Invalid ACK response from remote", 0);
|
||||
|
||||
session->scpSend_err_len = libssh2_channel_packet_data_len(session->scpSend_channel, 0);
|
||||
session->scpSend_err_msg = LIBSSH2_ALLOC(session, session->scpSend_err_len+1);
|
||||
session->scpSend_err_len =
|
||||
libssh2_channel_packet_data_len(session->scpSend_channel, 0);
|
||||
session->scpSend_err_msg =
|
||||
LIBSSH2_ALLOC(session, session->scpSend_err_len + 1);
|
||||
if (!session->scpSend_err_msg) {
|
||||
goto scp_send_error;
|
||||
}
|
||||
memset(session->scpSend_err_msg, 0, session->scpSend_err_len + 1);
|
||||
|
||||
/* Read the remote error message */
|
||||
rc = libssh2_channel_read_ex(session->scpSend_channel, 0, session->scpSend_err_msg, session->scpSend_err_len);
|
||||
rc = libssh2_channel_read_ex(session->scpSend_channel, 0,
|
||||
session->scpSend_err_msg,
|
||||
session->scpSend_err_len);
|
||||
if (rc <= 0) {
|
||||
/*
|
||||
* Since we have alread started reading this packet, it is
|
||||
@@ -642,7 +790,8 @@ libssh2_scp_send_ex(LIBSSH2_SESSION *session, const char *path, int mode, size_t
|
||||
goto scp_send_error;
|
||||
}
|
||||
|
||||
libssh2_error(session, LIBSSH2_ERROR_SCP_PROTOCOL, session->scpSend_err_msg, 1);
|
||||
libssh2_error(session, LIBSSH2_ERROR_SCP_PROTOCOL,
|
||||
session->scpSend_err_msg, 1);
|
||||
session->scpSend_err_msg = NULL;
|
||||
goto scp_send_error;
|
||||
}
|
||||
@@ -658,5 +807,5 @@ scp_send_error:
|
||||
session->scpSend_state = libssh2_NB_state_idle;
|
||||
return NULL;
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
/* }}} */
|
||||
|
393
src/session.c
393
src/session.c
@@ -52,29 +52,35 @@
|
||||
|
||||
/* {{{ libssh2_default_alloc
|
||||
*/
|
||||
static LIBSSH2_ALLOC_FUNC(libssh2_default_alloc)
|
||||
static
|
||||
LIBSSH2_ALLOC_FUNC(libssh2_default_alloc)
|
||||
{
|
||||
(void) abstract;
|
||||
return malloc(count);
|
||||
}
|
||||
|
||||
/* }}} */
|
||||
|
||||
/* {{{ libssh2_default_free
|
||||
*/
|
||||
static LIBSSH2_FREE_FUNC(libssh2_default_free)
|
||||
static
|
||||
LIBSSH2_FREE_FUNC(libssh2_default_free)
|
||||
{
|
||||
(void) abstract;
|
||||
free(ptr);
|
||||
}
|
||||
|
||||
/* }}} */
|
||||
|
||||
/* {{{ libssh2_default_realloc
|
||||
*/
|
||||
static LIBSSH2_REALLOC_FUNC(libssh2_default_realloc)
|
||||
static
|
||||
LIBSSH2_REALLOC_FUNC(libssh2_default_realloc)
|
||||
{
|
||||
(void) abstract;
|
||||
return realloc(ptr, count);
|
||||
}
|
||||
|
||||
/* }}} */
|
||||
|
||||
/* {{{ libssh2_banner_receive
|
||||
@@ -82,7 +88,8 @@ static LIBSSH2_REALLOC_FUNC(libssh2_default_realloc)
|
||||
* Allocate a buffer and store the banner in session->remote.banner
|
||||
* Returns: 0 on success, PACKET_EAGAIN if read would block, 1 on failure
|
||||
*/
|
||||
static int libssh2_banner_receive(LIBSSH2_SESSION *session)
|
||||
static int
|
||||
libssh2_banner_receive(LIBSSH2_SESSION * session)
|
||||
{
|
||||
int ret;
|
||||
int banner_len;
|
||||
@@ -96,10 +103,13 @@ static int libssh2_banner_receive(LIBSSH2_SESSION *session)
|
||||
}
|
||||
|
||||
while ((banner_len < (int) sizeof(session->banner_TxRx_banner)) &&
|
||||
((banner_len == 0) || (session->banner_TxRx_banner[banner_len-1] != '\n'))) {
|
||||
((banner_len == 0)
|
||||
|| (session->banner_TxRx_banner[banner_len - 1] != '\n'))) {
|
||||
char c = '\0';
|
||||
|
||||
ret = recv(session->socket_fd, &c, 1, LIBSSH2_SOCKET_RECV_FLAGS(session));
|
||||
ret =
|
||||
recv(session->socket_fd, &c, 1,
|
||||
LIBSSH2_SOCKET_RECV_FLAGS(session));
|
||||
|
||||
if (ret < 0) {
|
||||
#ifdef WIN32
|
||||
@@ -123,17 +133,22 @@ static int libssh2_banner_receive(LIBSSH2_SESSION *session)
|
||||
}
|
||||
#endif /* WIN32 */
|
||||
if (errno == EAGAIN) {
|
||||
session->socket_block_directions =
|
||||
LIBSSH2_SESSION_BLOCK_INBOUND;
|
||||
session->banner_TxRx_total_send = banner_len;
|
||||
return PACKET_EAGAIN;
|
||||
} else {
|
||||
}
|
||||
|
||||
/* Some kinda error */
|
||||
session->banner_TxRx_state = libssh2_NB_state_idle;
|
||||
session->banner_TxRx_total_send = 0;
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
if (ret <= 0) continue;
|
||||
if (ret == 0) {
|
||||
session->socket_state = LIBSSH2_SOCKET_DISCONNECTED;
|
||||
return PACKET_FAIL;
|
||||
}
|
||||
|
||||
if (c == '\0') {
|
||||
/* NULLs are not allowed in SSH banners */
|
||||
@@ -155,18 +170,22 @@ static int libssh2_banner_receive(LIBSSH2_SESSION *session)
|
||||
session->banner_TxRx_state = libssh2_NB_state_idle;
|
||||
session->banner_TxRx_total_send = 0;
|
||||
|
||||
if (!banner_len) return 1;
|
||||
if (!banner_len)
|
||||
return 1;
|
||||
|
||||
session->remote.banner = LIBSSH2_ALLOC(session, banner_len + 1);
|
||||
if (!session->remote.banner) {
|
||||
libssh2_error(session, LIBSSH2_ERROR_ALLOC, "Error allocating space for remote banner", 0);
|
||||
libssh2_error(session, LIBSSH2_ERROR_ALLOC,
|
||||
"Error allocating space for remote banner", 0);
|
||||
return 1;
|
||||
}
|
||||
memcpy(session->remote.banner, session->banner_TxRx_banner, banner_len);
|
||||
session->remote.banner[banner_len] = '\0';
|
||||
_libssh2_debug(session, LIBSSH2_DBG_TRANS, "Received Banner: %s", session->remote.banner);
|
||||
_libssh2_debug(session, LIBSSH2_DBG_TRANS, "Received Banner: %s",
|
||||
session->remote.banner);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* }}} */
|
||||
|
||||
/* {{{ libssh2_banner_send
|
||||
@@ -177,7 +196,8 @@ static int libssh2_banner_receive(LIBSSH2_SESSION *session)
|
||||
* sent, and this function should then be called with the same argument set
|
||||
* (same data pointer and same data_len) until zero or failure is returned.
|
||||
*/
|
||||
static int libssh2_banner_send(LIBSSH2_SESSION *session)
|
||||
static int
|
||||
libssh2_banner_send(LIBSSH2_SESSION * session)
|
||||
{
|
||||
char *banner = (char *) LIBSSH2_SSH_DEFAULT_BANNER_WITH_CRLF;
|
||||
int banner_len = sizeof(LIBSSH2_SSH_DEFAULT_BANNER_WITH_CRLF) - 1;
|
||||
@@ -192,7 +212,6 @@ static int libssh2_banner_send(LIBSSH2_SESSION *session)
|
||||
banner_len = strlen((char *) session->local.banner);
|
||||
banner = (char *) session->local.banner;
|
||||
}
|
||||
|
||||
#ifdef LIBSSH2DEBUG
|
||||
/* Hack and slash to avoid sending CRLF in debug output */
|
||||
if (banner_len < 256) {
|
||||
@@ -203,18 +222,23 @@ static int libssh2_banner_send(LIBSSH2_SESSION *session)
|
||||
banner[255] = '\0';
|
||||
}
|
||||
|
||||
_libssh2_debug(session, LIBSSH2_DBG_TRANS, "Sending Banner: %s", banner_dup);
|
||||
_libssh2_debug(session, LIBSSH2_DBG_TRANS, "Sending Banner: %s",
|
||||
banner_dup);
|
||||
#endif
|
||||
|
||||
session->banner_TxRx_state = libssh2_NB_state_created;
|
||||
}
|
||||
|
||||
ret = send(session->socket_fd, banner+session->banner_TxRx_total_send, banner_len-session->banner_TxRx_total_send,
|
||||
ret =
|
||||
send(session->socket_fd, banner + session->banner_TxRx_total_send,
|
||||
banner_len - session->banner_TxRx_total_send,
|
||||
LIBSSH2_SOCKET_SEND_FLAGS(session));
|
||||
|
||||
if (ret != (banner_len - session->banner_TxRx_total_send)) {
|
||||
if ((ret > 0) || ((ret == -1) && (errno == EAGAIN))) {
|
||||
/* the whole packet could not be sent, save the what was */
|
||||
session->socket_block_directions =
|
||||
LIBSSH2_SESSION_BLOCK_OUTBOUND;
|
||||
session->banner_TxRx_total_send += ret;
|
||||
return PACKET_EAGAIN;
|
||||
}
|
||||
@@ -229,6 +253,7 @@ static int libssh2_banner_send(LIBSSH2_SESSION *session)
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* }}} */
|
||||
|
||||
/*
|
||||
@@ -236,7 +261,8 @@ static int libssh2_banner_send(LIBSSH2_SESSION *session)
|
||||
* non-blocking mode based on the 'nonblock' boolean argument. This function
|
||||
* is copied from the libcurl sources with permission.
|
||||
*/
|
||||
static int _libssh2_nonblock(int sockfd, /* operate on this */
|
||||
static int
|
||||
_libssh2_nonblock(int sockfd, /* operate on this */
|
||||
int nonblock /* TRUE or FALSE */ )
|
||||
{
|
||||
#undef SETBLOCK
|
||||
@@ -304,8 +330,9 @@ static int _libssh2_nonblock(int sockfd, /* operate on this */
|
||||
* _libssh2_get_socket_nonblocking() gets the given blocking or non-blocking
|
||||
* state of the socket.
|
||||
*/
|
||||
static int _libssh2_get_socket_nonblocking(int sockfd) /* operate on this */
|
||||
{
|
||||
static int
|
||||
_libssh2_get_socket_nonblocking(int sockfd)
|
||||
{ /* operate on this */
|
||||
#undef GETBLOCK
|
||||
#define GETBLOCK 0
|
||||
#ifdef HAVE_O_NONBLOCK
|
||||
@@ -326,7 +353,8 @@ static int _libssh2_get_socket_nonblocking(int sockfd) /* operate on this */
|
||||
unsigned int option_value;
|
||||
socklen_t option_len = sizeof(option_value);
|
||||
|
||||
if (getsockopt(sockfd, SOL_SOCKET, SO_ERROR, (void*)&option_value, &option_len)) {
|
||||
if (getsockopt
|
||||
(sockfd, SOL_SOCKET, SO_ERROR, (void *) &option_value, &option_len)) {
|
||||
/* Assume blocking on error */
|
||||
return 1;
|
||||
}
|
||||
@@ -361,7 +389,8 @@ static int _libssh2_get_socket_nonblocking(int sockfd) /* operate on this */
|
||||
/* {{{ libssh2_banner_set
|
||||
* Set the local banner
|
||||
*/
|
||||
LIBSSH2_API int libssh2_banner_set(LIBSSH2_SESSION *session, const char *banner)
|
||||
LIBSSH2_API int
|
||||
libssh2_banner_set(LIBSSH2_SESSION * session, const char *banner)
|
||||
{
|
||||
int banner_len = banner ? strlen(banner) : 0;
|
||||
|
||||
@@ -376,19 +405,22 @@ LIBSSH2_API int libssh2_banner_set(LIBSSH2_SESSION *session, const char *banner)
|
||||
|
||||
session->local.banner = LIBSSH2_ALLOC(session, banner_len + 3);
|
||||
if (!session->local.banner) {
|
||||
libssh2_error(session, LIBSSH2_ERROR_ALLOC, "Unable to allocate memory for local banner", 0);
|
||||
libssh2_error(session, LIBSSH2_ERROR_ALLOC,
|
||||
"Unable to allocate memory for local banner", 0);
|
||||
return -1;
|
||||
}
|
||||
|
||||
memcpy(session->local.banner, banner, banner_len);
|
||||
session->local.banner[banner_len] = '\0';
|
||||
_libssh2_debug(session, LIBSSH2_DBG_TRANS, "Setting local Banner: %s", session->local.banner);
|
||||
_libssh2_debug(session, LIBSSH2_DBG_TRANS, "Setting local Banner: %s",
|
||||
session->local.banner);
|
||||
session->local.banner[banner_len++] = '\r';
|
||||
session->local.banner[banner_len++] = '\n';
|
||||
session->local.banner[banner_len++] = '\0';
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* }}} */
|
||||
|
||||
/* {{{ proto libssh2_session_init
|
||||
@@ -397,11 +429,10 @@ LIBSSH2_API int libssh2_banner_set(LIBSSH2_SESSION *session, const char *banner)
|
||||
* It's allowable (but unadvisable) to define some but not all of the malloc callbacks
|
||||
* An additional pointer value may be optionally passed to be sent to the callbacks (so they know who's asking)
|
||||
*/
|
||||
LIBSSH2_API LIBSSH2_SESSION *libssh2_session_init_ex(
|
||||
LIBSSH2_ALLOC_FUNC((*my_alloc)),
|
||||
LIBSSH2_API LIBSSH2_SESSION *
|
||||
libssh2_session_init_ex(LIBSSH2_ALLOC_FUNC((*my_alloc)),
|
||||
LIBSSH2_FREE_FUNC((*my_free)),
|
||||
LIBSSH2_REALLOC_FUNC((*my_realloc)),
|
||||
void *abstract)
|
||||
LIBSSH2_REALLOC_FUNC((*my_realloc)), void *abstract)
|
||||
{
|
||||
LIBSSH2_ALLOC_FUNC((*local_alloc)) = libssh2_default_alloc;
|
||||
LIBSSH2_FREE_FUNC((*local_free)) = libssh2_default_free;
|
||||
@@ -425,11 +456,13 @@ LIBSSH2_API LIBSSH2_SESSION *libssh2_session_init_ex(
|
||||
session->free = local_free;
|
||||
session->realloc = local_realloc;
|
||||
session->abstract = abstract;
|
||||
_libssh2_debug(session, LIBSSH2_DBG_TRANS, "New session resource allocated");
|
||||
_libssh2_debug(session, LIBSSH2_DBG_TRANS,
|
||||
"New session resource allocated");
|
||||
libssh2_crypto_init();
|
||||
}
|
||||
return session;
|
||||
}
|
||||
|
||||
/* }}} */
|
||||
|
||||
/* {{{ libssh2_session_callback_set
|
||||
@@ -439,7 +472,8 @@ LIBSSH2_API LIBSSH2_SESSION *libssh2_session_init_ex(
|
||||
* FIXME: this function relies on that we can typecast function pointers
|
||||
* to void pointers, which isn't allowed in ISO C!
|
||||
*/
|
||||
LIBSSH2_API void* libssh2_session_callback_set(LIBSSH2_SESSION *session,
|
||||
LIBSSH2_API void *
|
||||
libssh2_session_callback_set(LIBSSH2_SESSION * session,
|
||||
int cbtype, void *callback)
|
||||
{
|
||||
void *oldcb;
|
||||
@@ -475,6 +509,7 @@ LIBSSH2_API void* libssh2_session_callback_set(LIBSSH2_SESSION *session,
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* }}} */
|
||||
|
||||
/* {{{ proto libssh2_session_startup
|
||||
@@ -484,22 +519,25 @@ LIBSSH2_API void* libssh2_session_callback_set(LIBSSH2_SESSION *session,
|
||||
* callbacks in session
|
||||
* socket *must* be populated with an opened and connected socket.
|
||||
*/
|
||||
LIBSSH2_API int libssh2_session_startup(LIBSSH2_SESSION *session, int socket)
|
||||
LIBSSH2_API int
|
||||
libssh2_session_startup(LIBSSH2_SESSION * session, int sock)
|
||||
{
|
||||
int rc;
|
||||
|
||||
if (session->startup_state == libssh2_NB_state_idle) {
|
||||
_libssh2_debug(session, LIBSSH2_DBG_TRANS,
|
||||
"session_startup for socket %d", socket);
|
||||
"session_startup for socket %d", sock);
|
||||
/* FIXME: on some platforms (like win32) sockets are unsigned */
|
||||
if (socket < 0) {
|
||||
if (sock < 0) {
|
||||
/* Did we forget something? */
|
||||
libssh2_error(session, LIBSSH2_ERROR_SOCKET_NONE, "Bad socket provided", 0);
|
||||
libssh2_error(session, LIBSSH2_ERROR_SOCKET_NONE,
|
||||
"Bad socket provided", 0);
|
||||
return LIBSSH2_ERROR_SOCKET_NONE;
|
||||
}
|
||||
session->socket_fd = socket;
|
||||
session->socket_fd = sock;
|
||||
|
||||
session->socket_block = !_libssh2_get_socket_nonblocking(session->socket_fd);
|
||||
session->socket_block =
|
||||
!_libssh2_get_socket_nonblocking(session->socket_fd);
|
||||
if (session->socket_block) {
|
||||
/*
|
||||
* Since we can't be sure that we are in blocking or there
|
||||
@@ -517,12 +555,13 @@ LIBSSH2_API int libssh2_session_startup(LIBSSH2_SESSION *session, int socket)
|
||||
if (session->startup_state == libssh2_NB_state_created) {
|
||||
rc = libssh2_banner_send(session);
|
||||
if (rc == PACKET_EAGAIN) {
|
||||
libssh2_error(session, LIBSSH2_ERROR_EAGAIN, "Would block sending banner to remote host", 0);
|
||||
libssh2_error(session, LIBSSH2_ERROR_EAGAIN,
|
||||
"Would block sending banner to remote host", 0);
|
||||
return LIBSSH2_ERROR_EAGAIN;
|
||||
}
|
||||
else if (rc) {
|
||||
} else if (rc) {
|
||||
/* Unable to send banner? */
|
||||
libssh2_error(session, LIBSSH2_ERROR_BANNER_SEND, "Error sending banner to remote host", 0);
|
||||
libssh2_error(session, LIBSSH2_ERROR_BANNER_SEND,
|
||||
"Error sending banner to remote host", 0);
|
||||
return LIBSSH2_ERROR_BANNER_SEND;
|
||||
}
|
||||
|
||||
@@ -532,12 +571,13 @@ LIBSSH2_API int libssh2_session_startup(LIBSSH2_SESSION *session, int socket)
|
||||
if (session->startup_state == libssh2_NB_state_sent) {
|
||||
rc = libssh2_banner_receive(session);
|
||||
if (rc == PACKET_EAGAIN) {
|
||||
libssh2_error(session, LIBSSH2_ERROR_EAGAIN, "Would block waiting for banner", 0);
|
||||
libssh2_error(session, LIBSSH2_ERROR_EAGAIN,
|
||||
"Would block waiting for banner", 0);
|
||||
return LIBSSH2_ERROR_EAGAIN;
|
||||
}
|
||||
else if (rc) {
|
||||
} else if (rc) {
|
||||
/* Unable to receive banner from remote */
|
||||
libssh2_error(session, LIBSSH2_ERROR_BANNER_NONE, "Timeout waiting for banner", 0);
|
||||
libssh2_error(session, LIBSSH2_ERROR_BANNER_NONE,
|
||||
"Timeout waiting for banner", 0);
|
||||
return LIBSSH2_ERROR_BANNER_NONE;
|
||||
}
|
||||
|
||||
@@ -547,11 +587,12 @@ LIBSSH2_API int libssh2_session_startup(LIBSSH2_SESSION *session, int socket)
|
||||
if (session->startup_state == libssh2_NB_state_sent1) {
|
||||
rc = libssh2_kex_exchange(session, 0, &session->startup_key_state);
|
||||
if (rc == PACKET_EAGAIN) {
|
||||
libssh2_error(session, LIBSSH2_ERROR_EAGAIN, "Would block exchanging encryption keys", 0);
|
||||
libssh2_error(session, LIBSSH2_ERROR_EAGAIN,
|
||||
"Would block exchanging encryption keys", 0);
|
||||
return LIBSSH2_ERROR_EAGAIN;
|
||||
}
|
||||
else if (rc) {
|
||||
libssh2_error(session, LIBSSH2_ERROR_KEX_FAILURE, "Unable to exchange encryption keys", 0);
|
||||
} else if (rc) {
|
||||
libssh2_error(session, LIBSSH2_ERROR_KEX_FAILURE,
|
||||
"Unable to exchange encryption keys", 0);
|
||||
return LIBSSH2_ERROR_KEX_FAILURE;
|
||||
}
|
||||
|
||||
@@ -559,24 +600,29 @@ LIBSSH2_API int libssh2_session_startup(LIBSSH2_SESSION *session, int socket)
|
||||
}
|
||||
|
||||
if (session->startup_state == libssh2_NB_state_sent2) {
|
||||
_libssh2_debug(session, LIBSSH2_DBG_TRANS, "Requesting userauth service");
|
||||
_libssh2_debug(session, LIBSSH2_DBG_TRANS,
|
||||
"Requesting userauth service");
|
||||
|
||||
/* Request the userauth service */
|
||||
session->startup_service[0] = SSH_MSG_SERVICE_REQUEST;
|
||||
libssh2_htonu32(session->startup_service + 1, sizeof("ssh-userauth") - 1);
|
||||
memcpy(session->startup_service + 5, "ssh-userauth", sizeof("ssh-userauth") - 1);
|
||||
libssh2_htonu32(session->startup_service + 1,
|
||||
sizeof("ssh-userauth") - 1);
|
||||
memcpy(session->startup_service + 5, "ssh-userauth",
|
||||
sizeof("ssh-userauth") - 1);
|
||||
|
||||
session->startup_state = libssh2_NB_state_sent3;
|
||||
}
|
||||
|
||||
if (session->startup_state == libssh2_NB_state_sent3) {
|
||||
rc = libssh2_packet_write(session, session->startup_service, sizeof("ssh-userauth") + 5 - 1);
|
||||
rc = libssh2_packet_write(session, session->startup_service,
|
||||
sizeof("ssh-userauth") + 5 - 1);
|
||||
if (rc == PACKET_EAGAIN) {
|
||||
libssh2_error(session, LIBSSH2_ERROR_EAGAIN, "Would block asking for ssh-userauth service", 0);
|
||||
libssh2_error(session, LIBSSH2_ERROR_EAGAIN,
|
||||
"Would block asking for ssh-userauth service", 0);
|
||||
return LIBSSH2_ERROR_EAGAIN;
|
||||
}
|
||||
else if (rc) {
|
||||
libssh2_error(session, LIBSSH2_ERROR_SOCKET_SEND, "Unable to ask for ssh-userauth service", 0);
|
||||
} else if (rc) {
|
||||
libssh2_error(session, LIBSSH2_ERROR_SOCKET_SEND,
|
||||
"Unable to ask for ssh-userauth service", 0);
|
||||
return LIBSSH2_ERROR_SOCKET_SEND;
|
||||
}
|
||||
|
||||
@@ -584,21 +630,25 @@ LIBSSH2_API int libssh2_session_startup(LIBSSH2_SESSION *session, int socket)
|
||||
}
|
||||
|
||||
if (session->startup_state == libssh2_NB_state_sent4) {
|
||||
rc = libssh2_packet_require_ex(session, SSH_MSG_SERVICE_ACCEPT, &session->startup_data, &session->startup_data_len,
|
||||
0, NULL, 0, &session->startup_req_state);
|
||||
rc = libssh2_packet_require_ex(session, SSH_MSG_SERVICE_ACCEPT,
|
||||
&session->startup_data,
|
||||
&session->startup_data_len, 0, NULL, 0,
|
||||
&session->startup_req_state);
|
||||
if (rc == PACKET_EAGAIN) {
|
||||
return LIBSSH2_ERROR_EAGAIN;
|
||||
}
|
||||
else if (rc) {
|
||||
} else if (rc) {
|
||||
return LIBSSH2_ERROR_SOCKET_DISCONNECT;
|
||||
}
|
||||
session->startup_service_length = libssh2_ntohu32(session->startup_data + 1);
|
||||
session->startup_service_length =
|
||||
libssh2_ntohu32(session->startup_data + 1);
|
||||
|
||||
if ((session->startup_service_length != (sizeof("ssh-userauth") - 1)) ||
|
||||
strncmp("ssh-userauth", (char *)session->startup_data + 5, session->startup_service_length)) {
|
||||
if ((session->startup_service_length != (sizeof("ssh-userauth") - 1))
|
||||
|| strncmp("ssh-userauth", (char *) session->startup_data + 5,
|
||||
session->startup_service_length)) {
|
||||
LIBSSH2_FREE(session, session->startup_data);
|
||||
session->startup_data = NULL;
|
||||
libssh2_error(session, LIBSSH2_ERROR_PROTO, "Invalid response received from server", 0);
|
||||
libssh2_error(session, LIBSSH2_ERROR_PROTO,
|
||||
"Invalid response received from server", 0);
|
||||
return LIBSSH2_ERROR_PROTO;
|
||||
}
|
||||
LIBSSH2_FREE(session, session->startup_data);
|
||||
@@ -612,18 +662,21 @@ LIBSSH2_API int libssh2_session_startup(LIBSSH2_SESSION *session, int socket)
|
||||
/* just for safety return some error */
|
||||
return LIBSSH2_ERROR_INVAL;
|
||||
}
|
||||
|
||||
/* }}} */
|
||||
|
||||
/* {{{ proto libssh2_session_free
|
||||
* Frees the memory allocated to the session
|
||||
* Also closes and frees any channels attached to this session
|
||||
*/
|
||||
LIBSSH2_API int libssh2_session_free(LIBSSH2_SESSION *session)
|
||||
LIBSSH2_API int
|
||||
libssh2_session_free(LIBSSH2_SESSION * session)
|
||||
{
|
||||
int rc;
|
||||
|
||||
if (session->free_state == libssh2_NB_state_idle) {
|
||||
_libssh2_debug(session, LIBSSH2_DBG_TRANS, "Freeing session resource", session->remote.banner);
|
||||
_libssh2_debug(session, LIBSSH2_DBG_TRANS, "Freeing session resource",
|
||||
session->remote.banner);
|
||||
|
||||
session->state = libssh2_NB_state_created;
|
||||
}
|
||||
@@ -673,11 +726,13 @@ LIBSSH2_API int libssh2_session_free(LIBSSH2_SESSION *session)
|
||||
/* Client to Server */
|
||||
/* crypt */
|
||||
if (session->local.crypt && session->local.crypt->dtor) {
|
||||
session->local.crypt->dtor(session, &session->local.crypt_abstract);
|
||||
session->local.crypt->dtor(session,
|
||||
&session->local.crypt_abstract);
|
||||
}
|
||||
/* comp */
|
||||
if (session->local.comp && session->local.comp->dtor) {
|
||||
session->local.comp->dtor(session, 1, &session->local.comp_abstract);
|
||||
session->local.comp->dtor(session, 1,
|
||||
&session->local.comp_abstract);
|
||||
}
|
||||
/* mac */
|
||||
if (session->local.mac && session->local.mac->dtor) {
|
||||
@@ -687,11 +742,13 @@ LIBSSH2_API int libssh2_session_free(LIBSSH2_SESSION *session)
|
||||
/* Server to Client */
|
||||
/* crypt */
|
||||
if (session->remote.crypt && session->remote.crypt->dtor) {
|
||||
session->remote.crypt->dtor(session, &session->remote.crypt_abstract);
|
||||
session->remote.crypt->dtor(session,
|
||||
&session->remote.crypt_abstract);
|
||||
}
|
||||
/* comp */
|
||||
if (session->remote.comp && session->remote.comp->dtor) {
|
||||
session->remote.comp->dtor(session, 0, &session->remote.comp_abstract);
|
||||
session->remote.comp->dtor(session, 0,
|
||||
&session->remote.comp_abstract);
|
||||
}
|
||||
/* mac */
|
||||
if (session->remote.mac && session->remote.mac->dtor) {
|
||||
@@ -840,18 +897,23 @@ LIBSSH2_API int libssh2_session_free(LIBSSH2_SESSION *session)
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* }}} */
|
||||
|
||||
/* {{{ libssh2_session_disconnect_ex
|
||||
*/
|
||||
LIBSSH2_API int libssh2_session_disconnect_ex(LIBSSH2_SESSION *session, int reason, const char *description, const char *lang)
|
||||
LIBSSH2_API int
|
||||
libssh2_session_disconnect_ex(LIBSSH2_SESSION * session, int reason,
|
||||
const char *description, const char *lang)
|
||||
{
|
||||
unsigned char *s;
|
||||
unsigned long descr_len = 0, lang_len = 0;
|
||||
int rc;
|
||||
|
||||
if (session->disconnect_state == libssh2_NB_state_idle) {
|
||||
_libssh2_debug(session, LIBSSH2_DBG_TRANS, "Disconnecting: reason=%d, desc=%s, lang=%s", reason, description, lang);
|
||||
_libssh2_debug(session, LIBSSH2_DBG_TRANS,
|
||||
"Disconnecting: reason=%d, desc=%s, lang=%s", reason,
|
||||
description, lang);
|
||||
if (description) {
|
||||
descr_len = strlen(description);
|
||||
}
|
||||
@@ -861,23 +923,29 @@ LIBSSH2_API int libssh2_session_disconnect_ex(LIBSSH2_SESSION *session, int reas
|
||||
/* 13 = packet_type(1) + reason code(4) + descr_len(4) + lang_len(4) */
|
||||
session->disconnect_data_len = descr_len + lang_len + 13;
|
||||
|
||||
s = session->disconnect_data = LIBSSH2_ALLOC(session, session->disconnect_data_len);
|
||||
s = session->disconnect_data =
|
||||
LIBSSH2_ALLOC(session, session->disconnect_data_len);
|
||||
if (!session->disconnect_data) {
|
||||
libssh2_error(session, LIBSSH2_ERROR_ALLOC, "Unable to allocate memory for disconnect packet", 0);
|
||||
libssh2_error(session, LIBSSH2_ERROR_ALLOC,
|
||||
"Unable to allocate memory for disconnect packet",
|
||||
0);
|
||||
session->disconnect_state = libssh2_NB_state_idle;
|
||||
return -1;
|
||||
}
|
||||
|
||||
*(s++) = SSH_MSG_DISCONNECT;
|
||||
libssh2_htonu32(s, reason); s += 4;
|
||||
libssh2_htonu32(s, reason);
|
||||
s += 4;
|
||||
|
||||
libssh2_htonu32(s, descr_len); s += 4;
|
||||
libssh2_htonu32(s, descr_len);
|
||||
s += 4;
|
||||
if (description) {
|
||||
memcpy(s, description, descr_len);
|
||||
s += descr_len;
|
||||
}
|
||||
|
||||
libssh2_htonu32(s, lang_len); s += 4;
|
||||
libssh2_htonu32(s, lang_len);
|
||||
s += 4;
|
||||
if (lang) {
|
||||
memcpy(s, lang, lang_len);
|
||||
s += lang_len;
|
||||
@@ -886,7 +954,8 @@ LIBSSH2_API int libssh2_session_disconnect_ex(LIBSSH2_SESSION *session, int reas
|
||||
session->disconnect_state = libssh2_NB_state_created;
|
||||
}
|
||||
|
||||
rc = libssh2_packet_write(session, session->disconnect_data, session->disconnect_data_len);
|
||||
rc = libssh2_packet_write(session, session->disconnect_data,
|
||||
session->disconnect_data_len);
|
||||
if (rc == PACKET_EAGAIN) {
|
||||
return PACKET_EAGAIN;
|
||||
}
|
||||
@@ -897,6 +966,7 @@ LIBSSH2_API int libssh2_session_disconnect_ex(LIBSSH2_SESSION *session, int reas
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* }}} */
|
||||
|
||||
/* {{{ libssh2_session_methods
|
||||
@@ -904,7 +974,8 @@ LIBSSH2_API int libssh2_session_disconnect_ex(LIBSSH2_SESSION *session, int reas
|
||||
* NOTE: Currently lang_cs and lang_sc are ALWAYS set to empty string regardless of actual negotiation
|
||||
* Strings should NOT be freed
|
||||
*/
|
||||
LIBSSH2_API const char *libssh2_session_methods(LIBSSH2_SESSION *session, int method_type)
|
||||
LIBSSH2_API const char *
|
||||
libssh2_session_methods(LIBSSH2_SESSION * session, int method_type)
|
||||
{
|
||||
/* All methods have char *name as their first element */
|
||||
const LIBSSH2_KEX_METHOD *method = NULL;
|
||||
@@ -951,27 +1022,32 @@ LIBSSH2_API const char *libssh2_session_methods(LIBSSH2_SESSION *session, int me
|
||||
break;
|
||||
|
||||
default:
|
||||
libssh2_error(session, LIBSSH2_ERROR_INVAL, "Invalid parameter specified for method_type", 0);
|
||||
libssh2_error(session, LIBSSH2_ERROR_INVAL,
|
||||
"Invalid parameter specified for method_type", 0);
|
||||
return NULL;
|
||||
break;
|
||||
}
|
||||
|
||||
if (!method) {
|
||||
libssh2_error(session, LIBSSH2_ERROR_METHOD_NONE, "No method negotiated", 0);
|
||||
libssh2_error(session, LIBSSH2_ERROR_METHOD_NONE,
|
||||
"No method negotiated", 0);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return method->name;
|
||||
}
|
||||
|
||||
/* }}} */
|
||||
|
||||
/* {{{ libssh2_session_abstract
|
||||
* Retrieve a pointer to the abstract property
|
||||
*/
|
||||
LIBSSH2_API void **libssh2_session_abstract(LIBSSH2_SESSION *session)
|
||||
LIBSSH2_API void **
|
||||
libssh2_session_abstract(LIBSSH2_SESSION * session)
|
||||
{
|
||||
return &session->abstract;
|
||||
}
|
||||
|
||||
/* }}} */
|
||||
|
||||
/* {{{ libssh2_session_last_error
|
||||
@@ -980,7 +1056,8 @@ LIBSSH2_API void **libssh2_session_abstract(LIBSSH2_SESSION *session)
|
||||
* Otherwise it is assumed to be owned by libssh2
|
||||
*/
|
||||
LIBSSH2_API int
|
||||
libssh2_session_last_error(LIBSSH2_SESSION *session, char **errmsg, int *errmsg_len, int want_buf)
|
||||
libssh2_session_last_error(LIBSSH2_SESSION * session, char **errmsg,
|
||||
int *errmsg_len, int want_buf)
|
||||
{
|
||||
/* No error to report */
|
||||
if (!session->err_code) {
|
||||
@@ -1001,8 +1078,7 @@ libssh2_session_last_error(LIBSSH2_SESSION *session, char **errmsg, int *errmsg_
|
||||
}
|
||||
|
||||
if (errmsg) {
|
||||
char *serrmsg = session->err_msg ? session->err_msg :
|
||||
(char *)"";
|
||||
char *serrmsg = session->err_msg ? session->err_msg : (char *) "";
|
||||
int ownbuf = session->err_msg ? session->err_should_free : 0;
|
||||
|
||||
if (want_buf) {
|
||||
@@ -1029,6 +1105,7 @@ libssh2_session_last_error(LIBSSH2_SESSION *session, char **errmsg, int *errmsg_
|
||||
|
||||
return session->err_code;
|
||||
}
|
||||
|
||||
/* }}} */
|
||||
|
||||
/* {{{ libssh2_session_last_error
|
||||
@@ -1039,13 +1116,15 @@ libssh2_session_last_errno(LIBSSH2_SESSION *session)
|
||||
{
|
||||
return session->err_code;
|
||||
}
|
||||
|
||||
/* }}} */
|
||||
|
||||
/* {{{ libssh2_session_flag
|
||||
* Set/Get session flags
|
||||
* Passing flag==0 will avoid changing session->flags while still returning its current value
|
||||
*/
|
||||
LIBSSH2_API int libssh2_session_flag(LIBSSH2_SESSION *session, int flag, int value)
|
||||
LIBSSH2_API int
|
||||
libssh2_session_flag(LIBSSH2_SESSION * session, int flag, int value)
|
||||
{
|
||||
if (value) {
|
||||
session->flags |= flag;
|
||||
@@ -1055,16 +1134,19 @@ LIBSSH2_API int libssh2_session_flag(LIBSSH2_SESSION *session, int flag, int val
|
||||
|
||||
return session->flags;
|
||||
}
|
||||
|
||||
/* }}} */
|
||||
|
||||
/* {{{ _libssh2_session_set_blocking
|
||||
* Set a session's blocking mode on or off, return the previous status
|
||||
* when this function is called.
|
||||
*/
|
||||
int _libssh2_session_set_blocking(LIBSSH2_SESSION *session, int blocking)
|
||||
int
|
||||
_libssh2_session_set_blocking(LIBSSH2_SESSION * session, int blocking)
|
||||
{
|
||||
int bl = session->socket_block;
|
||||
_libssh2_debug(session, LIBSSH2_DBG_CONN, "Setting blocking mode on session %d", blocking);
|
||||
_libssh2_debug(session, LIBSSH2_DBG_CONN,
|
||||
"Setting blocking mode on session %d", blocking);
|
||||
if (blocking == session->socket_block) {
|
||||
/* avoid if already correct */
|
||||
return bl;
|
||||
@@ -1075,75 +1157,92 @@ int _libssh2_session_set_blocking(LIBSSH2_SESSION *session, int blocking)
|
||||
|
||||
return bl;
|
||||
}
|
||||
|
||||
/* }}} */
|
||||
|
||||
/* {{{ libssh2_session_set_blocking
|
||||
* Set a channel's blocking mode on or off, similar to a socket's
|
||||
* fcntl(fd, F_SETFL, O_NONBLOCK); type command
|
||||
*/
|
||||
LIBSSH2_API void libssh2_session_set_blocking(LIBSSH2_SESSION *session, int blocking)
|
||||
LIBSSH2_API void
|
||||
libssh2_session_set_blocking(LIBSSH2_SESSION * session, int blocking)
|
||||
{
|
||||
(void) _libssh2_session_set_blocking(session, blocking);
|
||||
}
|
||||
|
||||
/* }}} */
|
||||
|
||||
/* {{{ libssh2_session_get_blocking
|
||||
* Returns a session's blocking mode on or off
|
||||
*/
|
||||
LIBSSH2_API int libssh2_session_get_blocking(LIBSSH2_SESSION *session)
|
||||
LIBSSH2_API int
|
||||
libssh2_session_get_blocking(LIBSSH2_SESSION * session)
|
||||
{
|
||||
return session->socket_block;
|
||||
}
|
||||
|
||||
/* }}} */
|
||||
|
||||
/* {{{ libssh2_poll_channel_read
|
||||
* Returns 0 if no data is waiting on channel,
|
||||
* non-0 if data is available
|
||||
*/
|
||||
LIBSSH2_API int libssh2_poll_channel_read(LIBSSH2_CHANNEL *channel, int extended)
|
||||
LIBSSH2_API int
|
||||
libssh2_poll_channel_read(LIBSSH2_CHANNEL * channel, int extended)
|
||||
{
|
||||
LIBSSH2_SESSION *session = channel->session;
|
||||
LIBSSH2_PACKET *packet = session->packets.head;
|
||||
|
||||
while (packet) {
|
||||
if (((packet->data[0] == SSH_MSG_CHANNEL_DATA) && (extended == 0) &&
|
||||
(channel->local.id == libssh2_ntohu32(packet->data + 1))) ||
|
||||
((packet->data[0] == SSH_MSG_CHANNEL_EXTENDED_DATA) && (extended != 0) &&
|
||||
(channel->local.id == libssh2_ntohu32(packet->data + 1)))) {
|
||||
/* Found data waiting to be read */
|
||||
while (packet)
|
||||
{
|
||||
if ( channel->local.id == libssh2_ntohu32(packet->data + 1)) {
|
||||
if ( extended == 1 &&
|
||||
(packet->data[0] == SSH_MSG_CHANNEL_EXTENDED_DATA
|
||||
|| packet->data[0] == SSH_MSG_CHANNEL_DATA )) {
|
||||
return 1;
|
||||
} else if ( extended == 0 &&
|
||||
packet->data[0] == SSH_MSG_CHANNEL_DATA) {
|
||||
return 1;
|
||||
}
|
||||
/* else - no data of any type is ready to be read */
|
||||
}
|
||||
packet = packet->next;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* }}} */
|
||||
|
||||
/* {{{ libssh2_poll_channel_write
|
||||
* Returns 0 if writing to channel would block,
|
||||
* non-0 if data can be written without blocking
|
||||
*/
|
||||
static inline int libssh2_poll_channel_write(LIBSSH2_CHANNEL *channel)
|
||||
static inline int
|
||||
libssh2_poll_channel_write(LIBSSH2_CHANNEL * channel)
|
||||
{
|
||||
return channel->local.window_size ? 1 : 0;
|
||||
}
|
||||
|
||||
/* }}} */
|
||||
|
||||
/* {{{ libssh2_poll_listener_queued
|
||||
* Returns 0 if no connections are waiting to be accepted
|
||||
* non-0 if one or more connections are available
|
||||
*/
|
||||
static inline int libssh2_poll_listener_queued(LIBSSH2_LISTENER *listener)
|
||||
static inline int
|
||||
libssh2_poll_listener_queued(LIBSSH2_LISTENER * listener)
|
||||
{
|
||||
return listener->queue ? 1 : 0;
|
||||
}
|
||||
|
||||
/* }}} */
|
||||
|
||||
/* {{{ libssh2_poll
|
||||
* Poll sockets, channels, and listeners for activity
|
||||
*/
|
||||
LIBSSH2_API int libssh2_poll(LIBSSH2_POLLFD *fds, unsigned int nfds, long timeout)
|
||||
LIBSSH2_API int
|
||||
libssh2_poll(LIBSSH2_POLLFD * fds, unsigned int nfds, long timeout)
|
||||
{
|
||||
long timeout_remaining;
|
||||
unsigned int i, active_fds;
|
||||
@@ -1173,19 +1272,23 @@ LIBSSH2_API int libssh2_poll(LIBSSH2_POLLFD *fds, unsigned int nfds, long timeou
|
||||
sockets[i].fd = fds[i].fd.channel->session->socket_fd;
|
||||
sockets[i].events = POLLIN;
|
||||
sockets[i].revents = 0;
|
||||
if (!session) session = fds[i].fd.channel->session;
|
||||
if (!session)
|
||||
session = fds[i].fd.channel->session;
|
||||
break;
|
||||
|
||||
case LIBSSH2_POLLFD_LISTENER:
|
||||
sockets[i].fd = fds[i].fd.listener->session->socket_fd;
|
||||
sockets[i].events = POLLIN;
|
||||
sockets[i].revents = 0;
|
||||
if (!session) session = fds[i].fd.listener->session;
|
||||
if (!session)
|
||||
session = fds[i].fd.listener->session;
|
||||
break;
|
||||
|
||||
default:
|
||||
if (session) libssh2_error(session, LIBSSH2_ERROR_INVALID_POLL_TYPE,
|
||||
"Invalid descriptor passed to libssh2_poll()", 0);
|
||||
if (session)
|
||||
libssh2_error(session, LIBSSH2_ERROR_INVALID_POLL_TYPE,
|
||||
"Invalid descriptor passed to libssh2_poll()",
|
||||
0);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
@@ -1217,14 +1320,16 @@ LIBSSH2_API int libssh2_poll(LIBSSH2_POLLFD *fds, unsigned int nfds, long timeou
|
||||
FD_SET(fds[i].fd.channel->session->socket_fd, &rfds);
|
||||
if (fds[i].fd.channel->session->socket_fd > maxfd)
|
||||
maxfd = fds[i].fd.channel->session->socket_fd;
|
||||
if (!session) session = fds[i].fd.channel->session;
|
||||
if (!session)
|
||||
session = fds[i].fd.channel->session;
|
||||
break;
|
||||
|
||||
case LIBSSH2_POLLFD_LISTENER:
|
||||
FD_SET(fds[i].fd.listener->session->socket_fd, &rfds);
|
||||
if (fds[i].fd.listener->session->socket_fd > maxfd)
|
||||
maxfd = fds[i].fd.listener->session->socket_fd;
|
||||
if (!session) session = fds[i].fd.listener->session;
|
||||
if (!session)
|
||||
session = fds[i].fd.listener->session;
|
||||
break;
|
||||
|
||||
default:
|
||||
@@ -1257,31 +1362,50 @@ LIBSSH2_API int libssh2_poll(LIBSSH2_POLLFD *fds, unsigned int nfds, long timeou
|
||||
case LIBSSH2_POLLFD_CHANNEL:
|
||||
if ((fds[i].events & LIBSSH2_POLLFD_POLLIN) && /* Want to be ready for read */
|
||||
((fds[i].revents & LIBSSH2_POLLFD_POLLIN) == 0)) { /* Not yet known to be ready for read */
|
||||
fds[i].revents |= libssh2_poll_channel_read(fds[i].fd.channel, 0) ? LIBSSH2_POLLFD_POLLIN : 0;
|
||||
fds[i].revents |=
|
||||
libssh2_poll_channel_read(fds[i].fd.channel,
|
||||
0) ?
|
||||
LIBSSH2_POLLFD_POLLIN : 0;
|
||||
}
|
||||
if ((fds[i].events & LIBSSH2_POLLFD_POLLEXT) && /* Want to be ready for extended read */
|
||||
((fds[i].revents & LIBSSH2_POLLFD_POLLEXT) == 0)) { /* Not yet known to be ready for extended read */
|
||||
fds[i].revents |= libssh2_poll_channel_read(fds[i].fd.channel, 1) ? LIBSSH2_POLLFD_POLLEXT : 0;
|
||||
fds[i].revents |=
|
||||
libssh2_poll_channel_read(fds[i].fd.channel,
|
||||
1) ?
|
||||
LIBSSH2_POLLFD_POLLEXT : 0;
|
||||
}
|
||||
if ((fds[i].events & LIBSSH2_POLLFD_POLLOUT) && /* Want to be ready for write */
|
||||
((fds[i].revents & LIBSSH2_POLLFD_POLLOUT) == 0)) { /* Not yet known to be ready for write */
|
||||
fds[i].revents |= libssh2_poll_channel_write(fds[i].fd.channel) ? LIBSSH2_POLLFD_POLLOUT : 0;
|
||||
fds[i].revents |=
|
||||
libssh2_poll_channel_write(fds[i].fd.
|
||||
channel) ?
|
||||
LIBSSH2_POLLFD_POLLOUT : 0;
|
||||
}
|
||||
if (fds[i].fd.channel->remote.close || fds[i].fd.channel->local.close) {
|
||||
if (fds[i].fd.channel->remote.close
|
||||
|| fds[i].fd.channel->local.close) {
|
||||
fds[i].revents |= LIBSSH2_POLLFD_CHANNEL_CLOSED;
|
||||
}
|
||||
if (fds[i].fd.channel->session->socket_state == LIBSSH2_SOCKET_DISCONNECTED) {
|
||||
fds[i].revents |= LIBSSH2_POLLFD_CHANNEL_CLOSED | LIBSSH2_POLLFD_SESSION_CLOSED;
|
||||
if (fds[i].fd.channel->session->socket_state ==
|
||||
LIBSSH2_SOCKET_DISCONNECTED) {
|
||||
fds[i].revents |=
|
||||
LIBSSH2_POLLFD_CHANNEL_CLOSED |
|
||||
LIBSSH2_POLLFD_SESSION_CLOSED;
|
||||
}
|
||||
break;
|
||||
|
||||
case LIBSSH2_POLLFD_LISTENER:
|
||||
if ((fds[i].events & LIBSSH2_POLLFD_POLLIN) && /* Want a connection */
|
||||
((fds[i].revents & LIBSSH2_POLLFD_POLLIN) == 0)) { /* No connections known of yet */
|
||||
fds[i].revents |= libssh2_poll_listener_queued(fds[i].fd.listener) ? LIBSSH2_POLLFD_POLLIN : 0;
|
||||
fds[i].revents |=
|
||||
libssh2_poll_listener_queued(fds[i].fd.
|
||||
listener) ?
|
||||
LIBSSH2_POLLFD_POLLIN : 0;
|
||||
}
|
||||
if (fds[i].fd.listener->session->socket_state == LIBSSH2_SOCKET_DISCONNECTED) {
|
||||
fds[i].revents |= LIBSSH2_POLLFD_LISTENER_CLOSED | LIBSSH2_POLLFD_SESSION_CLOSED;
|
||||
if (fds[i].fd.listener->session->socket_state ==
|
||||
LIBSSH2_SOCKET_DISCONNECTED) {
|
||||
fds[i].revents |=
|
||||
LIBSSH2_POLLFD_LISTENER_CLOSED |
|
||||
LIBSSH2_POLLFD_SESSION_CLOSED;
|
||||
}
|
||||
break;
|
||||
}
|
||||
@@ -1295,7 +1419,6 @@ LIBSSH2_API int libssh2_poll(LIBSSH2_POLLFD *fds, unsigned int nfds, long timeou
|
||||
/* Don't block on the sockets if we have channels/listeners which are ready */
|
||||
timeout_remaining = 0;
|
||||
}
|
||||
|
||||
#ifdef HAVE_POLL
|
||||
|
||||
#ifdef HAVE_GETTIMEOFDAY
|
||||
@@ -1329,20 +1452,26 @@ LIBSSH2_API int libssh2_poll(LIBSSH2_POLLFD *fds, unsigned int nfds, long timeou
|
||||
case LIBSSH2_POLLFD_CHANNEL:
|
||||
if (sockets[i].events & POLLIN) {
|
||||
/* Spin session until no data available */
|
||||
while (libssh2_packet_read(fds[i].fd.channel->session) > 0);
|
||||
while (libssh2_packet_read(fds[i].fd.channel->session)
|
||||
> 0);
|
||||
}
|
||||
if (sockets[i].revents & POLLHUP) {
|
||||
fds[i].revents |= LIBSSH2_POLLFD_CHANNEL_CLOSED | LIBSSH2_POLLFD_SESSION_CLOSED;
|
||||
fds[i].revents |=
|
||||
LIBSSH2_POLLFD_CHANNEL_CLOSED |
|
||||
LIBSSH2_POLLFD_SESSION_CLOSED;
|
||||
}
|
||||
sockets[i].revents = 0;
|
||||
break;
|
||||
case LIBSSH2_POLLFD_LISTENER:
|
||||
if (sockets[i].events & POLLIN) {
|
||||
/* Spin session until no data available */
|
||||
while (libssh2_packet_read(fds[i].fd.listener->session) > 0);
|
||||
while (libssh2_packet_read(fds[i].fd.listener->session)
|
||||
> 0);
|
||||
}
|
||||
if (sockets[i].revents & POLLHUP) {
|
||||
fds[i].revents |= LIBSSH2_POLLFD_LISTENER_CLOSED | LIBSSH2_POLLFD_SESSION_CLOSED;
|
||||
fds[i].revents |=
|
||||
LIBSSH2_POLLFD_LISTENER_CLOSED |
|
||||
LIBSSH2_POLLFD_SESSION_CLOSED;
|
||||
}
|
||||
sockets[i].revents = 0;
|
||||
break;
|
||||
@@ -1357,7 +1486,7 @@ LIBSSH2_API int libssh2_poll(LIBSSH2_POLLFD *fds, unsigned int nfds, long timeou
|
||||
struct timeval tv_begin, tv_end;
|
||||
|
||||
gettimeofday((struct timeval *) &tv_begin, NULL);
|
||||
sysret = select(maxfd, &rfds, &wfds, NULL, &tv);
|
||||
sysret = select(maxfd+1, &rfds, &wfds, NULL, &tv);
|
||||
gettimeofday((struct timeval *) &tv_end, NULL);
|
||||
|
||||
timeout_remaining -= (tv_end.tv_sec - tv_begin.tv_sec) * 1000;
|
||||
@@ -1367,7 +1496,7 @@ LIBSSH2_API int libssh2_poll(LIBSSH2_POLLFD *fds, unsigned int nfds, long timeou
|
||||
/* If the platform doesn't support gettimeofday,
|
||||
* then just make the call non-blocking and walk away
|
||||
*/
|
||||
sysret = select(maxfd, &rfds, &wfds, NULL, &tv);
|
||||
sysret = select(maxfd+1, &rfds, &wfds, NULL, &tv);
|
||||
timeout_remaining = 0;
|
||||
#endif
|
||||
|
||||
@@ -1389,14 +1518,17 @@ LIBSSH2_API int libssh2_poll(LIBSSH2_POLLFD *fds, unsigned int nfds, long timeou
|
||||
case LIBSSH2_POLLFD_CHANNEL:
|
||||
if (FD_ISSET(fds[i].fd.channel->session->socket_fd, &rfds)) {
|
||||
/* Spin session until no data available */
|
||||
while (libssh2_packet_read(fds[i].fd.channel->session) > 0);
|
||||
while (libssh2_packet_read(fds[i].fd.channel->session)
|
||||
> 0);
|
||||
}
|
||||
break;
|
||||
|
||||
case LIBSSH2_POLLFD_LISTENER:
|
||||
if (FD_ISSET(fds[i].fd.listener->session->socket_fd, &rfds)) {
|
||||
if (FD_ISSET
|
||||
(fds[i].fd.listener->session->socket_fd, &rfds)) {
|
||||
/* Spin session until no data available */
|
||||
while (libssh2_packet_read(fds[i].fd.listener->session) > 0);
|
||||
while (libssh2_packet_read(fds[i].fd.listener->session)
|
||||
> 0);
|
||||
}
|
||||
break;
|
||||
}
|
||||
@@ -1407,5 +1539,16 @@ LIBSSH2_API int libssh2_poll(LIBSSH2_POLLFD *fds, unsigned int nfds, long timeou
|
||||
|
||||
return active_fds;
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
/* {{{ libssh2_session_block_direction
|
||||
* Get blocked direction when a function returns LIBSSH2_ERROR_EAGAIN
|
||||
* Returns LIBSSH2_SOCKET_BLOCK_INBOUND if recv() blocked
|
||||
* or LIBSSH2_SOCKET_BLOCK_OUTBOUND if send() blocked
|
||||
*/
|
||||
LIBSSH2_API int
|
||||
libssh2_session_block_directions(LIBSSH2_SESSION *session)
|
||||
{
|
||||
return session->socket_block_directions;
|
||||
}
|
||||
|
||||
/* }}} */
|
||||
|
1094
src/sftp.c
1094
src/sftp.c
File diff suppressed because it is too large
Load Diff
374
src/sshentry.c
Normal file
374
src/sshentry.c
Normal file
@@ -0,0 +1,374 @@
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <ctype.h>
|
||||
|
||||
#include "libssh2_priv.h"
|
||||
|
||||
static int
|
||||
ssh_host_parse_hostnames (LIBSSH2_SESSION * session,
|
||||
LIBSSH2_KNOWNHOSTS * s,
|
||||
char *line,
|
||||
char *end
|
||||
);
|
||||
|
||||
static int
|
||||
ssh_host_parse_key (LIBSSH2_SESSION * session,
|
||||
LIBSSH2_KNOWNHOSTS * s,
|
||||
char *line,
|
||||
int is_base64_encoded
|
||||
);
|
||||
|
||||
/* Returns zero if successful, > zero for malformed data, < 0 not supported. */
|
||||
LIBSSH2_API int
|
||||
libssh2_new_host_entry(LIBSSH2_SESSION * session,
|
||||
LIBSSH2_KNOWNHOSTS ** s,
|
||||
char *line)
|
||||
{
|
||||
char *tmp = NULL;
|
||||
LIBSSH2_KNOWNHOSTS *t = NULL;
|
||||
int i;
|
||||
|
||||
if (line == NULL || *line == 0)
|
||||
return 1;
|
||||
if (s == NULL)
|
||||
return 2;
|
||||
|
||||
tmp = strchr (line, ' ');
|
||||
if (tmp == NULL)
|
||||
return 3;
|
||||
|
||||
|
||||
t = (LIBSSH2_KNOWNHOSTS *)
|
||||
LIBSSH2_ALLOC(session, sizeof(LIBSSH2_KNOWNHOSTS));
|
||||
|
||||
t->hostname_line = NULL;
|
||||
t->hostnames = NULL;
|
||||
t->hostnames_size = t->bits = t->exponent = -1;
|
||||
t->modulus = NULL;
|
||||
t->modulus_length = -1;
|
||||
t->ssh_version = -1;
|
||||
t->md5 = NULL;
|
||||
|
||||
i = ssh_host_parse_hostnames (session, t, line, tmp);
|
||||
if (i != 0) {
|
||||
libssh2_free_host_entry (session, t);
|
||||
return ((i > 0) ? 4 : -1);
|
||||
}
|
||||
|
||||
line = tmp + 1;
|
||||
tmp = strchr (line, ' ');
|
||||
if (tmp != NULL)
|
||||
tmp = strchr (tmp + 1, ' ');
|
||||
|
||||
i = ssh_host_parse_key (session, t, line, tmp == NULL ? 1 : 0);
|
||||
if (i != 0) {
|
||||
libssh2_free_host_entry (session, t);
|
||||
return ((i > 0) ? 5 : -2);
|
||||
}
|
||||
|
||||
*s = t;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
ssh_host_parse_hostnames(LIBSSH2_SESSION * session,
|
||||
LIBSSH2_KNOWNHOSTS * s,
|
||||
char *line,
|
||||
char *end)
|
||||
{
|
||||
char *start;
|
||||
char *comma = NULL;
|
||||
int i;
|
||||
|
||||
/* TODO: we don't handle the hashed name format because the hashing
|
||||
* mechanism isnt defined (at least based on the man page)
|
||||
*/
|
||||
if (*line == '|')
|
||||
return -1;
|
||||
if (line == end || *line == ' ')
|
||||
return 1;
|
||||
|
||||
s->hostname_line = (char *) LIBSSH2_ALLOC (session, (end - line) + 1);
|
||||
strncpy (s->hostname_line, line, (end - line) + 1);
|
||||
start = end = s->hostname_line + (end - line);
|
||||
*end = 0;
|
||||
|
||||
s->hostnames_size = 1;
|
||||
comma = s->hostname_line;
|
||||
while ((comma = strchr (comma, ',')) != NULL) {
|
||||
comma++;
|
||||
if (*comma == ',' || *comma == 0) {
|
||||
LIBSSH2_FREE (session, s->hostname_line);
|
||||
s->hostname_line = NULL;
|
||||
return 2;
|
||||
}
|
||||
s->hostnames_size++;
|
||||
}
|
||||
s->hostnames = (char **) LIBSSH2_ALLOC
|
||||
(session, sizeof (char *) * s->hostnames_size);
|
||||
|
||||
start = comma = s->hostname_line;
|
||||
i = 0;
|
||||
while ((comma = strchr (comma, ',')) != NULL) {
|
||||
*comma = 0;
|
||||
s->hostnames[i] = start;
|
||||
|
||||
comma++;
|
||||
start = comma;
|
||||
i++;
|
||||
}
|
||||
s->hostnames[i] = start;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/** Returns the number of bytes read or -1. */
|
||||
static int
|
||||
ssh_proto_str_read(LIBSSH2_SESSION * session,
|
||||
char *line,
|
||||
char **val,
|
||||
char *end
|
||||
)
|
||||
{
|
||||
unsigned int len;
|
||||
|
||||
if (line + 4 > end)
|
||||
return -1;
|
||||
len = (line[0] << 24) + (line[1] << 16) + (line[2] << 8) + line[3];
|
||||
if (line + 4 + len > end)
|
||||
return -1;
|
||||
|
||||
*val = LIBSSH2_ALLOC (session, len);
|
||||
memcpy (*val, line + 4, len);
|
||||
return len + 4;
|
||||
}
|
||||
|
||||
static int
|
||||
ssh_host_parse_key(LIBSSH2_SESSION * session,
|
||||
LIBSSH2_KNOWNHOSTS * s,
|
||||
char *line,
|
||||
int is_base64_encoded)
|
||||
{
|
||||
int i, j;
|
||||
char *tmp, *tmp2;
|
||||
/* workaround for the MD5 stuff */
|
||||
libssh2_md5_ctx ctx;
|
||||
|
||||
/* the bits, exponent, modulus format */
|
||||
if (is_base64_encoded == 0) {
|
||||
s->ssh_version = 1;
|
||||
s->key_type = 0;
|
||||
if (!isdigit (*line))
|
||||
return -1;
|
||||
if (sscanf (line, "%hu %hu ", &(s->bits), &(s->exponent)) != 2)
|
||||
return -2;
|
||||
/* TODO:
|
||||
* There's probably an acceptable range...
|
||||
*/
|
||||
if (s->bits <= 0 || s->exponent <= 0)
|
||||
return 1;
|
||||
|
||||
line = strchr (line, ' ');
|
||||
if (line == NULL)
|
||||
return -3;
|
||||
line++;
|
||||
line = strchr (line, ' ');
|
||||
if (line == NULL)
|
||||
return -4;
|
||||
line++;
|
||||
/* TODO:
|
||||
* figure out what format modulus is in since its not clear
|
||||
* from the man page
|
||||
*/
|
||||
return -5;
|
||||
}
|
||||
else {
|
||||
s->ssh_version = 2;
|
||||
/* we only handle the rsa type */
|
||||
if (strstr (line, "ssh-rsa") != line)
|
||||
return -6;
|
||||
s->key_type = 0;
|
||||
line += 7;
|
||||
if (*line != ' ')
|
||||
return 2;
|
||||
line++;
|
||||
i = 0;
|
||||
while (*line) {
|
||||
if ((line[i] >= 0x30 && line[i] <= 0x39) ||
|
||||
(line[i] >= 0x41 && line[i] <= 0x5a) ||
|
||||
(line[i] >= 0x61 && line[i] <= 0x7a) ||
|
||||
(line[i] == '+') || (line[i] == '/') || (line[i] == '='))
|
||||
i++;
|
||||
else
|
||||
break;
|
||||
}
|
||||
if (i == 0)
|
||||
return 3;
|
||||
tmp = LIBSSH2_ALLOC (session, sizeof (char) * (i + 5));
|
||||
strncpy (tmp, line, i);
|
||||
/* this should hopefully avoid any issues with reading
|
||||
* past the array if its malformed */
|
||||
tmp[i] = tmp[i + 1] = tmp[i + 2] = tmp[i + 3] = tmp[i + 4] = 0;
|
||||
|
||||
{
|
||||
/* TODO: rework the api interface instead of making a local
|
||||
instance */
|
||||
i = libssh2_base64_decode(session, &tmp2, (unsigned int *)&j,
|
||||
tmp, strlen(tmp));
|
||||
LIBSSH2_FREE(session, tmp);
|
||||
if (i != 0)
|
||||
return 4;
|
||||
|
||||
}
|
||||
|
||||
/* printf("Decode Size: %d\n", i); */
|
||||
/* free (tmp); */
|
||||
|
||||
|
||||
#if LIBSSH2_MD5
|
||||
s->md5 = LIBSSH2_ALLOC (session, 16);
|
||||
|
||||
libssh2_md5_init (&ctx);
|
||||
libssh2_md5_update (ctx, tmp2, j);
|
||||
libssh2_md5_final (ctx, s->md5);
|
||||
#endif
|
||||
|
||||
|
||||
line = tmp2;
|
||||
i = ssh_proto_str_read (session, line, &tmp, tmp2 + j);
|
||||
if (i < 0) {
|
||||
LIBSSH2_FREE (session, tmp2);
|
||||
return 5;
|
||||
}
|
||||
/* TODO: verify that its ssh-rsa -- its the only one
|
||||
* supported
|
||||
*/
|
||||
if (!(i == 11 && tmp[0] == 's' && tmp[1] == 's' &&
|
||||
tmp[2] == 'h' && tmp[3] == '-' && tmp[4] == 'r' &&
|
||||
tmp[5] == 's' && tmp[6] == 'a')) {
|
||||
free (tmp);
|
||||
free (tmp2);
|
||||
return 8;
|
||||
}
|
||||
|
||||
LIBSSH2_FREE (session, tmp);
|
||||
line += i;
|
||||
i = ssh_proto_str_read (session, line, &tmp, tmp2 + j);
|
||||
if (i < 0) {
|
||||
LIBSSH2_FREE (session, tmp2);
|
||||
return 6;
|
||||
}
|
||||
/* TODO: verify that the exponent is valid */
|
||||
if (i == 5)
|
||||
s->exponent = (unsigned short) ((unsigned char) *tmp);
|
||||
else {
|
||||
LIBSSH2_FREE (session, tmp);
|
||||
LIBSSH2_FREE (session, tmp2);
|
||||
return 9;
|
||||
}
|
||||
|
||||
LIBSSH2_FREE (session, tmp);
|
||||
line += i;
|
||||
i = ssh_proto_str_read (session, line, &tmp, tmp2 + j);
|
||||
if (i < 0) {
|
||||
LIBSSH2_FREE (session, tmp2);
|
||||
return 7;
|
||||
}
|
||||
|
||||
/* TODO: the modulus may need to be converted to
|
||||
* big integer format
|
||||
*/
|
||||
s->modulus_length = i - 4;
|
||||
s->modulus = tmp;
|
||||
|
||||
s->bits = (s->modulus_length - 1) * 8;
|
||||
|
||||
LIBSSH2_FREE (session, tmp2);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
LIBSSH2_API void
|
||||
libssh2_free_host_entry(LIBSSH2_SESSION * session, LIBSSH2_KNOWNHOSTS * s)
|
||||
{
|
||||
/* int i; */
|
||||
if (s == NULL)
|
||||
return;
|
||||
|
||||
if (s->hostname_line != NULL) {
|
||||
LIBSSH2_FREE (session, s->hostname_line);
|
||||
s->hostname_line = NULL;
|
||||
}
|
||||
|
||||
if (s->hostnames != NULL && s->hostnames_size > 0) {
|
||||
LIBSSH2_FREE (session, s->hostnames);
|
||||
s->hostnames = NULL;
|
||||
}
|
||||
s->hostnames_size = s->bits = s->exponent = -1;
|
||||
|
||||
if (s->modulus != NULL) {
|
||||
LIBSSH2_FREE (session, s->modulus);
|
||||
s->modulus = NULL;
|
||||
}
|
||||
s->modulus_length = -1;
|
||||
s->ssh_version = -1;
|
||||
|
||||
if (s->md5 != NULL) {
|
||||
LIBSSH2_FREE (session, s->md5);
|
||||
s->md5 = NULL;
|
||||
}
|
||||
|
||||
LIBSSH2_FREE (session, s);
|
||||
}
|
||||
|
||||
#ifdef SSH_HOSTNAME_TESTS
|
||||
int
|
||||
ssh_unit_tests (int argc, char **argv)
|
||||
{
|
||||
char *l[] = {
|
||||
"closenet,...,192.0.2.53 1024 37 159...93 closenet.example.net",
|
||||
"cvs.example.net,192.0.2.10 ssh-rsa AAAA1234.....=",
|
||||
" cvs.example.net,192.0.2.10 ssh-rsa AAAA1234.....=",
|
||||
"",
|
||||
",",
|
||||
"f, ",
|
||||
"cvs.example.net ssh-rsa AAAA1234.....=",
|
||||
"192.168.30.118 ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAQEAwWVqxKm2Biwilakq9Ex8/tzHVQjRrzEkwlrWTDneptodVgqAzXUFQSa6Oj9AwzdDPhKe71vTv7RhXYg0ZvB1a5dIkzgCdoF/mIuTb80LvK7f0NxCaAHWODuHbwlJeMmjHV0WFsjsdOf690fPqeinD/8jfBQB950M1K3Qesib9H75gsnawF06MzZ52nC1HHi8mG2tGy2PMyP+mJs7KN1v4T+nobZ10ePe1dMqYXMdro/PB0JQmuGL7bBR5GRDEkK6nFcp2HsvuzXSeWZJcmWDdo+1n0cNg2th5VEIxrrFG5iy0CA2AXVPMqkf3VrAXGXV66dJTGtBqZ5GoxJCxDgW6w==",
|
||||
"|1|JfKTdBh7rNbXkVAQCRp4OQoPfmI=|USECr3SWf1JUPsms5AqfD5QfxkM= ssh-rsaAAAA1234.....="
|
||||
};
|
||||
int s;
|
||||
int cases = sizeof (l) / sizeof (char *);
|
||||
|
||||
if (argc == 2) {
|
||||
s = atoi (argv[1]);
|
||||
if (s >= 0 && s < cases) {
|
||||
LIBSSH2_KNOWNHOSTS *x = NULL;
|
||||
printf ("%d\n", s = new_ssh_host_entry (&x, l[s]));
|
||||
libssh2_free_host_entry (x);
|
||||
return s;
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
/** Returns 0 for a match, non-zero otherwise. */
|
||||
LIBSSH2_API int
|
||||
libssh2_host_entry_match(LIBSSH2_KNOWNHOSTS * x, char *host)
|
||||
{
|
||||
/* TODO: Add pattern matching and/or DNS matching against
|
||||
* to entries found in x
|
||||
*/
|
||||
int i;
|
||||
if (host == NULL || x == NULL)
|
||||
return -1;
|
||||
|
||||
/* FIXME: this should use a case-insensitive compare as dns hostnames
|
||||
* are generally case insensitive anyways
|
||||
*/
|
||||
for (i = 0; i < x->hostnames_size; i++)
|
||||
if (!strcmp (x->hostnames[i], host))
|
||||
return 0;
|
||||
|
||||
return 1;
|
||||
}
|
196
src/transport.c
196
src/transport.c
@@ -48,9 +48,9 @@
|
||||
|
||||
#ifdef LIBSSH2DEBUG
|
||||
#define UNPRINTABLE_CHAR '.'
|
||||
static void debugdump(LIBSSH2_SESSION *session,
|
||||
const char *desc, unsigned char *ptr,
|
||||
unsigned long size)
|
||||
static void
|
||||
debugdump(LIBSSH2_SESSION * session,
|
||||
const char *desc, unsigned char *ptr, unsigned long size)
|
||||
{
|
||||
size_t i;
|
||||
size_t c;
|
||||
@@ -66,7 +66,7 @@ static void debugdump(LIBSSH2_SESSION *session,
|
||||
|
||||
for(i = 0; i < size; i += width) {
|
||||
|
||||
fprintf(stream, "%04lx: ", i);
|
||||
fprintf(stream, "%04lx: ", (long)i);
|
||||
|
||||
/* hex not disabled, show it */
|
||||
for(c = 0; c < width; c++) {
|
||||
@@ -95,7 +95,8 @@ static void debugdump(LIBSSH2_SESSION *session,
|
||||
* returns PACKET_NONE on success and PACKET_FAIL on failure
|
||||
*/
|
||||
|
||||
static libssh2pack_t decrypt(LIBSSH2_SESSION *session, unsigned char *source,
|
||||
static libssh2pack_t
|
||||
decrypt(LIBSSH2_SESSION * session, unsigned char *source,
|
||||
unsigned char *dest, int len)
|
||||
{
|
||||
struct transportpacket *p = &session->packet;
|
||||
@@ -144,11 +145,11 @@ fullpacket(LIBSSH2_SESSION *session, int encrypted /* 1 or 0 */)
|
||||
if (encrypted) {
|
||||
|
||||
/* Calculate MAC hash */
|
||||
session->remote.mac->hash(session,
|
||||
macbuf, /* store hash here */
|
||||
session->remote.mac->hash(session, macbuf, /* store hash here */
|
||||
session->remote.seqno,
|
||||
p->init, 5,
|
||||
p->payload, session->fullpacket_payload_len,
|
||||
p->payload,
|
||||
session->fullpacket_payload_len,
|
||||
&session->remote.mac_abstract);
|
||||
|
||||
/* Compare the calculated hash with the MAC we just read from
|
||||
@@ -168,8 +169,7 @@ 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 &&
|
||||
strcmp(session->remote.comp->name, "none")) {
|
||||
if (session->remote.comp && strcmp(session->remote.comp->name, "none")) {
|
||||
unsigned char *data;
|
||||
unsigned long data_len;
|
||||
int free_payload = 1;
|
||||
@@ -178,7 +178,8 @@ fullpacket(LIBSSH2_SESSION *session, int encrypted /* 1 or 0 */)
|
||||
&data, &data_len,
|
||||
LIBSSH2_PACKET_MAXDECOMP,
|
||||
&free_payload,
|
||||
p->payload, session->fullpacket_payload_len,
|
||||
p->payload,
|
||||
session->fullpacket_payload_len,
|
||||
&session->remote.comp_abstract)) {
|
||||
LIBSSH2_FREE(session, p->payload);
|
||||
return PACKET_FAIL;
|
||||
@@ -188,16 +189,14 @@ fullpacket(LIBSSH2_SESSION *session, int encrypted /* 1 or 0 */)
|
||||
LIBSSH2_FREE(session, p->payload);
|
||||
p->payload = data;
|
||||
session->fullpacket_payload_len = data_len;
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
if (data == p->payload) {
|
||||
/* It's not to be freed, because the
|
||||
* compression layer reused payload, So let's
|
||||
* do the same!
|
||||
*/
|
||||
session->fullpacket_payload_len = data_len;
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
/* No comp_method actually lets this happen,
|
||||
* but let's prepare for the future */
|
||||
|
||||
@@ -207,9 +206,9 @@ fullpacket(LIBSSH2_SESSION *session, int encrypted /* 1 or 0 */)
|
||||
* brigade won't know what to do with it */
|
||||
p->payload = LIBSSH2_ALLOC(session, data_len);
|
||||
if (!p->payload) {
|
||||
libssh2_error(session,
|
||||
LIBSSH2_ERROR_ALLOC,
|
||||
(char *)"Unable to allocate memory for copy of uncompressed data", 0);
|
||||
libssh2_error(session, LIBSSH2_ERROR_ALLOC, (char *)
|
||||
"Unable to allocate memory for copy of uncompressed data",
|
||||
0);
|
||||
return PACKET_ENOMEM;
|
||||
}
|
||||
memcpy(p->payload, data, data_len);
|
||||
@@ -227,11 +226,12 @@ fullpacket(LIBSSH2_SESSION *session, int encrypted /* 1 or 0 */)
|
||||
}
|
||||
|
||||
if (session->fullpacket_state == libssh2_NB_state_created) {
|
||||
rc = libssh2_packet_add(session, p->payload, session->fullpacket_payload_len, session->fullpacket_macstate);
|
||||
rc = libssh2_packet_add(session, p->payload,
|
||||
session->fullpacket_payload_len,
|
||||
session->fullpacket_macstate);
|
||||
if (rc == PACKET_EAGAIN) {
|
||||
return PACKET_EAGAIN;
|
||||
}
|
||||
else if (rc < 0) {
|
||||
} else if (rc < 0) {
|
||||
return PACKET_FAIL;
|
||||
}
|
||||
}
|
||||
@@ -256,7 +256,8 @@ fullpacket(LIBSSH2_SESSION *session, int encrypted /* 1 or 0 */)
|
||||
* This function reads the binary stream as specified in chapter 6 of RFC4253
|
||||
* "The Secure Shell (SSH) Transport Layer Protocol"
|
||||
*/
|
||||
libssh2pack_t libssh2_packet_read(LIBSSH2_SESSION *session)
|
||||
libssh2pack_t
|
||||
libssh2_packet_read(LIBSSH2_SESSION * session)
|
||||
{
|
||||
libssh2pack_t rc;
|
||||
struct transportpacket *p = &session->packet;
|
||||
@@ -266,9 +267,42 @@ libssh2pack_t libssh2_packet_read(LIBSSH2_SESSION *session)
|
||||
int numdecrypt;
|
||||
unsigned char block[MAX_BLOCKSIZE];
|
||||
int blocksize;
|
||||
int minimum;
|
||||
int encrypted = 1;
|
||||
|
||||
int status;
|
||||
|
||||
/*
|
||||
* All channels, systems, subsystems, etc eventually make it down here
|
||||
* when looking for more incoming data. If a key exchange is going on
|
||||
* (LIBSSH2_STATE_EXCHANGING_KEYS bit is set) then the remote end
|
||||
* will ONLY send key exchange related traffic. In non-blocking mode,
|
||||
* there is a chance to break out of the kex_exchange function with an
|
||||
* EAGAIN status, and never come back to it. If LIBSSH2_STATE_EXCHANGING_KEYS
|
||||
* is active, then we must redirect to the key exchange. However,
|
||||
* if kex_exchange is active (as in it is the one that calls this execution
|
||||
* of packet_read, then don't redirect, as that would be an infinite loop!
|
||||
*/
|
||||
|
||||
if (session->state & LIBSSH2_STATE_EXCHANGING_KEYS &&
|
||||
!(session->state & LIBSSH2_STATE_KEX_ACTIVE)) {
|
||||
|
||||
/* Whoever wants a packet won't get anything until the key re-exchange
|
||||
* is done!
|
||||
*/
|
||||
_libssh2_debug(session, LIBSSH2_DBG_TRANS, "Redirecting into the"
|
||||
" key re-exchange");
|
||||
status = libssh2_kex_exchange(session, 1, &session->startup_key_state);
|
||||
if (status == PACKET_EAGAIN) {
|
||||
libssh2_error(session, LIBSSH2_ERROR_EAGAIN,
|
||||
"Would block exchanging encryption keys", 0);
|
||||
return PACKET_EAGAIN;
|
||||
} else if (status) {
|
||||
libssh2_error(session, LIBSSH2_ERROR_KEX_FAILURE,
|
||||
"Unable to exchange encryption keys",0);
|
||||
return LIBSSH2_ERROR_KEX_FAILURE;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* =============================== NOTE ===============================
|
||||
* I know this is very ugly and not a really good use of "goto", but
|
||||
@@ -292,7 +326,6 @@ libssh2pack_t libssh2_packet_read(LIBSSH2_SESSION *session)
|
||||
blocksize = 5; /* not strictly true, but we can use 5 here to
|
||||
make the checks below work fine still */
|
||||
}
|
||||
minimum = p->total_num ? p->total_num - p->data_num : blocksize;
|
||||
|
||||
/* read/use a whole big chunk into a temporary area stored in
|
||||
the LIBSSH2_SESSION struct. We will decrypt data from that
|
||||
@@ -307,8 +340,8 @@ libssh2pack_t libssh2_packet_read(LIBSSH2_SESSION *session)
|
||||
/* if remainbuf turns negative we have a bad internal error */
|
||||
assert(remainbuf >= 0);
|
||||
|
||||
if (remainbuf < minimum) {
|
||||
/* If we have less than a minimum left, it is too
|
||||
if (remainbuf < blocksize) {
|
||||
/* If we have less than a blocksize left, it is too
|
||||
little data to deal with, read more */
|
||||
ssize_t nread;
|
||||
|
||||
@@ -324,13 +357,36 @@ libssh2pack_t libssh2_packet_read(LIBSSH2_SESSION *session)
|
||||
}
|
||||
|
||||
/* now read a big chunk from the network into the temp buffer */
|
||||
nread = recv(session->socket_fd, &p->buf[remainbuf], PACKETBUFSIZE-remainbuf,
|
||||
nread =
|
||||
recv(session->socket_fd, &p->buf[remainbuf],
|
||||
PACKETBUFSIZE - remainbuf,
|
||||
LIBSSH2_SOCKET_RECV_FLAGS(session));
|
||||
if (nread <= 0) {
|
||||
/* check if this is due to EAGAIN and return
|
||||
the special return code if so, error out
|
||||
normally otherwise */
|
||||
/* check if this is due to EAGAIN and return the special
|
||||
return code if so, error out normally otherwise */
|
||||
#ifdef WIN32
|
||||
switch (WSAGetLastError()) {
|
||||
case WSAEWOULDBLOCK:
|
||||
errno = EAGAIN;
|
||||
break;
|
||||
|
||||
case WSAENOTSOCK:
|
||||
errno = EBADF;
|
||||
break;
|
||||
|
||||
case WSAENOTCONN:
|
||||
case WSAECONNABORTED:
|
||||
errno = WSAENOTCONN;
|
||||
break;
|
||||
|
||||
case WSAEINTR:
|
||||
errno = EINTR;
|
||||
break;
|
||||
}
|
||||
#endif /* WIN32 */
|
||||
if ((nread < 0) && (errno == EAGAIN)) {
|
||||
session->socket_block_directions =
|
||||
LIBSSH2_SESSION_BLOCK_INBOUND;
|
||||
return PACKET_EAGAIN;
|
||||
}
|
||||
return PACKET_FAIL;
|
||||
@@ -347,16 +403,19 @@ libssh2pack_t libssh2_packet_read(LIBSSH2_SESSION *session)
|
||||
/* how much data to deal with from the buffer */
|
||||
numbytes = remainbuf;
|
||||
|
||||
if (numbytes < blocksize) {
|
||||
/* we can't act on anything less than blocksize */
|
||||
return PACKET_EAGAIN;
|
||||
}
|
||||
|
||||
if (!p->total_num) {
|
||||
/* No payload package area allocated yet. To know the
|
||||
size of this payload, we need to decrypt the first
|
||||
blocksize data. */
|
||||
|
||||
if (numbytes < blocksize) {
|
||||
/* we can't act on anything less than blocksize, but this
|
||||
check is only done for the initial block since once we have
|
||||
got the start of a block we can in fact deal with fractions
|
||||
*/
|
||||
return PACKET_EAGAIN;
|
||||
}
|
||||
|
||||
if (encrypted) {
|
||||
rc = decrypt(session, &p->buf[p->readidx], block, blocksize);
|
||||
if (rc != PACKET_NONE) {
|
||||
@@ -382,7 +441,9 @@ libssh2pack_t libssh2_packet_read(LIBSSH2_SESSION *session)
|
||||
|
||||
/* total_num is the number of bytes following the initial
|
||||
(5 bytes) packet length and padding length fields */
|
||||
p->total_num = p->packet_length -1 + (encrypted ? session->remote.mac->mac_len : 0);
|
||||
p->total_num =
|
||||
p->packet_length - 1 +
|
||||
(encrypted ? session->remote.mac->mac_len : 0);
|
||||
|
||||
/* RFC4253 section 6.1 Maximum Packet Length says:
|
||||
*
|
||||
@@ -502,8 +563,21 @@ libssh2pack_t libssh2_packet_read(LIBSSH2_SESSION *session)
|
||||
libssh2_packet_read_point1:
|
||||
rc = fullpacket(session, encrypted);
|
||||
if (rc == PACKET_EAGAIN) {
|
||||
|
||||
if (session->packAdd_state != libssh2_NB_state_idle)
|
||||
{
|
||||
/* fullpacket only returns PACKET_EAGAIN if
|
||||
* libssh2_packet_add returns PACKET_EAGAIN. If that
|
||||
* returns PACKET_EAGAIN but the packAdd_state is idle,
|
||||
* then the packet has been added to the brigade, but some
|
||||
* immediate action that was taken based on the packet
|
||||
* type (such as key re-exchange) is not yet complete.
|
||||
* Clear the way for a new packet to be read in.
|
||||
*/
|
||||
session->readPack_encrypted = encrypted;
|
||||
session->readPack_state = libssh2_NB_state_jump1;
|
||||
}
|
||||
|
||||
return PACKET_EAGAIN;
|
||||
}
|
||||
|
||||
@@ -515,11 +589,12 @@ libssh2_packet_read_point1:
|
||||
|
||||
return PACKET_FAIL; /* we never reach this point */
|
||||
}
|
||||
|
||||
/* }}} */
|
||||
|
||||
#ifndef OLDSEND
|
||||
|
||||
static libssh2pack_t send_existing(LIBSSH2_SESSION *session, unsigned char *data, unsigned long data_len, ssize_t *ret)
|
||||
static libssh2pack_t
|
||||
send_existing(LIBSSH2_SESSION * session, unsigned char *data,
|
||||
unsigned long data_len, ssize_t * ret)
|
||||
{
|
||||
ssize_t rc;
|
||||
ssize_t length;
|
||||
@@ -545,24 +620,26 @@ static libssh2pack_t send_existing(LIBSSH2_SESSION *session, unsigned char *data
|
||||
/* number of bytes left to send */
|
||||
length = p->ototal_num - p->osent;
|
||||
|
||||
rc = send(session->socket_fd, &p->outbuf[p->osent], length, LIBSSH2_SOCKET_SEND_FLAGS(session));
|
||||
rc = send(session->socket_fd, &p->outbuf[p->osent], length,
|
||||
LIBSSH2_SOCKET_SEND_FLAGS(session));
|
||||
|
||||
if (rc == length) {
|
||||
/* the remainder of the package was sent */
|
||||
LIBSSH2_FREE(session, p->outbuf);
|
||||
p->outbuf = NULL;
|
||||
p->ototal_num = 0;
|
||||
}
|
||||
else if (rc < 0) {
|
||||
} else if (rc < 0) {
|
||||
/* nothing was sent */
|
||||
if (errno != EAGAIN) {
|
||||
/* send failure! */
|
||||
return PACKET_FAIL;
|
||||
}
|
||||
session->socket_block_directions = LIBSSH2_SESSION_BLOCK_OUTBOUND;
|
||||
return PACKET_EAGAIN;
|
||||
}
|
||||
|
||||
debugdump(session, "libssh2_packet_write send()", &p->outbuf[p->osent], length);
|
||||
debugdump(session, "libssh2_packet_write send()", &p->outbuf[p->osent],
|
||||
length);
|
||||
p->osent += length; /* we sent away this much data */
|
||||
|
||||
return PACKET_NONE;
|
||||
@@ -576,10 +653,18 @@ static libssh2pack_t send_existing(LIBSSH2_SESSION *session, unsigned char *data
|
||||
* call this function again as soon as it is likely that more data can be
|
||||
* sent, and this function should then be called with the same argument set
|
||||
* (same data pointer and same data_len) until zero or failure is returned.
|
||||
*
|
||||
* NOTE: this function does not verify that 'data_len' is less than ~35000
|
||||
* which is what all implementations should support at least as packet size.
|
||||
* (RFC4253 section 6.1)
|
||||
*/
|
||||
int libssh2_packet_write(LIBSSH2_SESSION *session, unsigned char *data, unsigned long data_len)
|
||||
int
|
||||
libssh2_packet_write(LIBSSH2_SESSION * session, unsigned char *data,
|
||||
unsigned long data_len)
|
||||
{
|
||||
int blocksize = (session->state & LIBSSH2_STATE_NEWKEYS) ? session->local.crypt->blocksize : 8;
|
||||
int blocksize =
|
||||
(session->state & LIBSSH2_STATE_NEWKEYS) ? session->local.crypt->
|
||||
blocksize : 8;
|
||||
int padding_length;
|
||||
int packet_length;
|
||||
int total_length;
|
||||
@@ -608,8 +693,10 @@ int libssh2_packet_write(LIBSSH2_SESSION *session, unsigned char *data, unsigned
|
||||
|
||||
/* check if we should compress */
|
||||
if (encrypted && strcmp(session->local.comp->name, "none")) {
|
||||
if (session->local.comp->comp(session, 1, &data, &data_len, LIBSSH2_PACKET_MAXCOMP,
|
||||
&free_data, data, data_len, &session->local.comp_abstract)) {
|
||||
if (session->local.comp->comp(session, 1, &data, &data_len,
|
||||
LIBSSH2_PACKET_MAXCOMP,
|
||||
&free_data, data, data_len,
|
||||
&session->local.comp_abstract)) {
|
||||
return PACKET_COMPRESS; /* compression failure */
|
||||
}
|
||||
}
|
||||
@@ -650,7 +737,8 @@ int libssh2_packet_write(LIBSSH2_SESSION *session, unsigned char *data, unsigned
|
||||
packet_length += padding_length;
|
||||
|
||||
/* append the MAC length to the total_length size */
|
||||
total_length = packet_length + (encrypted?session->local.mac->mac_len:0);
|
||||
total_length =
|
||||
packet_length + (encrypted ? session->local.mac->mac_len : 0);
|
||||
|
||||
/* allocate memory to store the outgoing packet in, in case we can't
|
||||
send the whole one and thus need to keep it after this function
|
||||
@@ -678,14 +766,17 @@ int libssh2_packet_write(LIBSSH2_SESSION *session, unsigned char *data, unsigned
|
||||
since that size includes the whole packet. The MAC is
|
||||
calculated on the entire unencrypted packet, including all
|
||||
fields except the MAC field itself. */
|
||||
session->local.mac->hash(session, p->outbuf + packet_length, session->local.seqno, p->outbuf, packet_length,
|
||||
NULL, 0, &session->local.mac_abstract);
|
||||
session->local.mac->hash(session, p->outbuf + packet_length,
|
||||
session->local.seqno, p->outbuf,
|
||||
packet_length, NULL, 0,
|
||||
&session->local.mac_abstract);
|
||||
|
||||
/* Encrypt the whole packet data, one block size at a time.
|
||||
The MAC field is not encrypted. */
|
||||
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_abstract))
|
||||
if (session->local.crypt->crypt(session, ptr,
|
||||
&session->local.crypt_abstract))
|
||||
return PACKET_FAIL; /* encryption failure */
|
||||
}
|
||||
}
|
||||
@@ -701,6 +792,7 @@ int libssh2_packet_write(LIBSSH2_SESSION *session, unsigned char *data, unsigned
|
||||
if (ret != total_length) {
|
||||
if ((ret > 0) || ((ret == -1) && (errno == EAGAIN))) {
|
||||
/* the whole packet could not be sent, save the rest */
|
||||
session->socket_block_directions = LIBSSH2_SESSION_BLOCK_OUTBOUND;
|
||||
p->odata = orgdata;
|
||||
p->olen = orgdata_len;
|
||||
p->osent = (ret == -1) ? 0 : ret;
|
||||
@@ -720,4 +812,4 @@ int libssh2_packet_write(LIBSSH2_SESSION *session, unsigned char *data, unsigned
|
||||
}
|
||||
|
||||
/* }}} */
|
||||
#endif
|
||||
|
||||
|
823
src/userauth.c
823
src/userauth.c
File diff suppressed because it is too large
Load Diff
@@ -1,5 +1,8 @@
|
||||
.deps
|
||||
.libs
|
||||
*.gcno
|
||||
*.gcda
|
||||
Makefile
|
||||
Makefile.in
|
||||
simple
|
||||
ssh2
|
||||
|
@@ -1,6 +1,19 @@
|
||||
AM_CPPFLAGS = -I$(top_srcdir)/include
|
||||
AM_CPPFLAGS = -I$(top_srcdir)/src -I$(top_srcdir)/include -I$(top_builddir)/src
|
||||
LDADD = ../src/libssh2.la
|
||||
|
||||
if SSHD
|
||||
noinst_PROGRAMS = ssh2
|
||||
ssh2_SOURCES = ssh2.c
|
||||
endif
|
||||
|
||||
ctests = simple
|
||||
TESTS = $(ctests)
|
||||
if SSHD
|
||||
TESTS += ssh2.sh
|
||||
endif
|
||||
check_PROGRAMS = $(ctests)
|
||||
|
||||
TESTS_ENVIRONMENT = SSHD=$(SSHD) EXEEXT=$(EXEEXT)
|
||||
|
||||
EXTRA_DIST = ssh2.sh
|
||||
EXTRA_DIST += etc/host etc/host.pub etc/user etc/user.pub
|
||||
|
27
tests/etc/host
Normal file
27
tests/etc/host
Normal file
@@ -0,0 +1,27 @@
|
||||
-----BEGIN RSA PRIVATE KEY-----
|
||||
MIIEogIBAAKCAQEAwJaOo3i1X3N401hMd92lRec0tPMBgaF6ZDanovBiQP+PNo6g
|
||||
VNtuF15AspbyxrViqtAyjLWQQlKGWgEFb2ga3ukzJll4dKPtNff3mO++W19ia0WQ
|
||||
ZFWTAGcYqet4fvSALIpG+t/3u5MZXMNZPyCU8u1l+QXX14f6dEjzgRw7s3fSy/uv
|
||||
Qawkgn8TQFvtSBOfvUTJPTAhhZqxZAt3nGH8d6vqD1hBNvdOpsohy6EgFh8V+kxn
|
||||
UdQntrYe9WSz0djt0RRrdAvRkM0hq1UY8C9FTQQWni1n168c7FVrf65+GdJOn7NQ
|
||||
Du0Whmh/R3flXR0kIBG+F7e8+e9W9OhlionkPwIBIwKCAQEAqpP6rgvT2DMTPtkt
|
||||
yUCoU9tpMo4XRu4b8lxLVc2Y2nvz391pb7sJvO0Uu2/BFmYkMORKB5l/xbbOxL8T
|
||||
cU2UJIVn0YJyAOj2rCTFW5KEB8mDDo4SLPtWUNBXrHF5WoDJTAVyEWdJInr5NOeJ
|
||||
j68k1yoJ3JAlkwNozWUvclrVytZNohPhiYdKkj2DPlWKL//0INGIo9TU31AGJx2R
|
||||
ymy105EFCXWDv1GAIWwqBjNNxzlyxDauuGTwWr2iYDyectBYApCkjyJzMpFn4Yiu
|
||||
Mq5XomwkQhefK3y32bRasm+HSrQsGswSvSyS8I5YosjSKMmiWdYj4WxrSciT6gG/
|
||||
KHanEwKBgQDucA7E/s9aKs6rECypXPaCORxvbLqdqAiwzJ0edufE+g0aQU/Zm3xj
|
||||
m6LGovdEcaBog4rfKCSB9NRKi35m4HV9PO4YBw6/lQ0NeO6jrb8OnZp/P97FbomT
|
||||
AXBibzUjQ8fhbPCaJF/2TUEoyhNbzJkpl+M0zu2aQ3MUYVd4dZ4y4wKBgQDOxfeA
|
||||
RH3ZPvdYI50jxW+/kKcio+APZZJ9xhtqOKzmEuJOPzlngWk5WQgS8B1aicHyFRhw
|
||||
UT2vKeJvqqoeLbIE9Fm6qlpN22594S88+LOiMda4wRswxG9wBZ2J4+rrYKpcb1gt
|
||||
JXvVKY7h5qLWGCR0x+ovOcNXABWsF8CAnOnb9QKBgA2gANgOj4F+yfslfuUbQUlF
|
||||
F5FWq5P6+S6sm0ORxBniZyYSXFWT2zjkUnHAK2L/LbzUURQQ7CSu5487K8tdSIrQ
|
||||
SB6hUUzGsEnppzyNleOT+jMoOJ2RSbCg/xuRU35bpQWRMlHzczKlVC43btILsPsP
|
||||
/lrJ/vLfSGeQiKfMNOz3AoGAC9DMUHjxP50ytJRSH00cVBbk+qpHUVZC4p2bKqQn
|
||||
IxcFnhI9y2Z7CpdfjA24iNSr/zRny+dinEuJSDWjUi5/M3utWx+tY4jhvgzeIL3B
|
||||
HzYMRRJZUz5sxJKbSbVAn7xhgZ/2aPrT4EuEge/sDDvk03kjUyffRszOCdV4tuRl
|
||||
IoMCgYEAnrexTd5GuxEEBg3qJgN4IMwoBzZlJ1voaI6I/AMuvQ5kVklYvHTPTZOI
|
||||
kSIrvaG8xaOdf0f76XNdT7U/dkx0C0vcesy5++hqakmeRCHjfsE1wN7m+hGo5WcR
|
||||
Jq8Ph9ZnH5RKjqDsHh7Y4BCewQNrMBqNQEzDebZCDBUTnK9OgOg=
|
||||
-----END RSA PRIVATE KEY-----
|
1
tests/etc/host.pub
Normal file
1
tests/etc/host.pub
Normal file
@@ -0,0 +1 @@
|
||||
ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAQEAwJaOo3i1X3N401hMd92lRec0tPMBgaF6ZDanovBiQP+PNo6gVNtuF15AspbyxrViqtAyjLWQQlKGWgEFb2ga3ukzJll4dKPtNff3mO++W19ia0WQZFWTAGcYqet4fvSALIpG+t/3u5MZXMNZPyCU8u1l+QXX14f6dEjzgRw7s3fSy/uvQawkgn8TQFvtSBOfvUTJPTAhhZqxZAt3nGH8d6vqD1hBNvdOpsohy6EgFh8V+kxnUdQntrYe9WSz0djt0RRrdAvRkM0hq1UY8C9FTQQWni1n168c7FVrf65+GdJOn7NQDu0Whmh/R3flXR0kIBG+F7e8+e9W9OhlionkPw== jas@mocca
|
3
tests/etc/sshd_config
Normal file
3
tests/etc/sshd_config
Normal file
@@ -0,0 +1,3 @@
|
||||
Port 4711
|
||||
Protocol 2
|
||||
AuthorizedKeysFile /home/jas/src/libssh2/tests/etc/user.pub
|
27
tests/etc/user
Normal file
27
tests/etc/user
Normal file
@@ -0,0 +1,27 @@
|
||||
-----BEGIN RSA PRIVATE KEY-----
|
||||
MIIEoQIBAAKCAQEAxIgBuZS39D4bFnWminE7svGQLdVKx1aWKnEYEa+XtNU4DKZ/
|
||||
pxUHg0zbEBya+IkX1yqQYWALoiOwI8XhdemLp8g03BX7o+DLSWisfiHpCDVGAuNq
|
||||
RDF7qnFyL/ZBH6e0XKMtsoB51TDuBc4Rxh6p1V2QL/fg8BoHcCrnKkoqN8PSoKUX
|
||||
2lPKJ3JIF/P8cDLbKYCvbSTFOdf56eqg0GJe7jFtSwweE9yz3IWZ3kSS1E/9E6sX
|
||||
aNCu/hUt1bvQthICQyBNoTtQP/igEUJ7n0GMetsnq9wiUSomLzWqIWNqmvOv62aC
|
||||
XRi5sYgpSAR4Zvnm3Cx/Wl0BEPz2rrFkG+G0SQIBIwKCAQEAgSYtBOyzZfztOqUV
|
||||
q277WFWZQrC8HJf8R8aparU3zpq+braOZnuImByP9KUVYX6pRECKw6WD/NWfonq4
|
||||
uzMSoXTviVBGRx6xeWIK880kG1Y1UlruD447Ur+ULiV7QLAIzylnLCiKk2lL9S+l
|
||||
R63AD95mEOS4Y0ROB+Gt2fY5ABHRMqhGLvRKK8qwn35C1Z9qnTGhgiRbeoc373A5
|
||||
ZAYyegyLnbvyV47UfPYS/TVzxZ9RCx3D3I/9fI7ZAFafkkIufQX3QPaVxf0zFUwW
|
||||
de/f+gTbySTL4RDF185Evunx+tYvzCyIimB0cTE5dfsCWcHDtO6DwehKiOgJsbeW
|
||||
IrpeTwKBgQDnEMfv7ORR35Ouj91iNCSfLU/v0TSzAJBfqYovByhXRsopgWAKXUmH
|
||||
mWpBBP5vcGu3NvKfiZcMMbBPfllvlxkafQwvCqrdn5mg01MdAHMWP/O9yfvuxMDE
|
||||
KycU2G2CT8j85mIPn19WeIgXC/kws+P0RAVNCBNeq89Gvp4IdLN67wKBgQDZvTYh
|
||||
TPCYG32jBK+CcWmOna2SLvBloDcNevhzfu3RGjLIXzUHGxLdx7slsP/tpndmXIAL
|
||||
CgV6GfrLxix5bO08203S2qnnwP8VrjjNIv1CyZIbbQFAFIeC3QxZMZHnXieLrO0z
|
||||
qF5CuUXcL3cMeGmF/0HN/rB+4sF0qfv8wD8kRwKBgFXTCG8O2HYueK6NNPiXBknA
|
||||
X4T17wCocCOIHWHstzZcHzP82oeBvDmuAuTzOe7gnQmJcA9e/ZbQoJKOA/Y/b7lh
|
||||
pXCO7wHcMb9kb1PqOWAJIASqG78V4TLrdOp8Re6Sqb0FHRu+2kSwbQ/f4DapN2lb
|
||||
F+lpZke8KGq71ExImm99AoGAN/10UbSy5UjlytVRs9QFM00eAQTBeTfTpGFzFmJ3
|
||||
qsw48bIU8zLY9zNcAmC21rXG7m+Oo8C/lG0UmsyPF+jPSinDjf22qU7iger4qccr
|
||||
Lm5YxTlJduC1IaaOJZBnWMBwkaF+0sTlCdfew5ctPbiQKcVLb3wBf7amxjpWvVYB
|
||||
m50CgYAT6t2/Suav21J5zpzyrrt+oMZQ3MMzBnPHFRUQ1FdqZnE4eW5a10g0P+E+
|
||||
YeTol+fYxL34+cI5PREK3dcnW1E8g8KOsOQqMgWdTfZEDHYRLqEyGIhu20aqfJCY
|
||||
qu9tBburQoSlym9aQp41CMxIyHrL4GnwRlJkTTEVhDuab1HmKw==
|
||||
-----END RSA PRIVATE KEY-----
|
1
tests/etc/user.pub
Normal file
1
tests/etc/user.pub
Normal file
@@ -0,0 +1 @@
|
||||
ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAQEAxIgBuZS39D4bFnWminE7svGQLdVKx1aWKnEYEa+XtNU4DKZ/pxUHg0zbEBya+IkX1yqQYWALoiOwI8XhdemLp8g03BX7o+DLSWisfiHpCDVGAuNqRDF7qnFyL/ZBH6e0XKMtsoB51TDuBc4Rxh6p1V2QL/fg8BoHcCrnKkoqN8PSoKUX2lPKJ3JIF/P8cDLbKYCvbSTFOdf56eqg0GJe7jFtSwweE9yz3IWZ3kSS1E/9E6sXaNCu/hUt1bvQthICQyBNoTtQP/igEUJ7n0GMetsnq9wiUSomLzWqIWNqmvOv62aCXRi5sYgpSAR4Zvnm3Cx/Wl0BEPz2rrFkG+G0SQ== jas@mocca
|
@@ -1,5 +1,6 @@
|
||||
/* Copyright (C) 2007 The Written Word, Inc. All rights reserved.
|
||||
* Author: Simon Josefsson
|
||||
/* Copyright (C) 2007 The Written Word, Inc.
|
||||
* Copyright (C) 2008 Simon Josefsson
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms,
|
||||
* with or without modification, are permitted provided
|
||||
@@ -36,9 +37,36 @@
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "libssh2.h"
|
||||
|
||||
int test_libssh2_base64_decode (LIBSSH2_SESSION *session)
|
||||
{
|
||||
char *data;
|
||||
unsigned int datalen;
|
||||
const char *src = "Zm5vcmQ=";
|
||||
unsigned int src_len = strlen (src);
|
||||
int ret;
|
||||
|
||||
ret = libssh2_base64_decode(session, &data, &datalen,
|
||||
src, src_len);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
if (datalen != 5 || strcmp (data, "fnord") != 0)
|
||||
{
|
||||
fprintf (stderr,
|
||||
"libssh2_base64_decode() failed (%d, %.*s)\n",
|
||||
datalen, datalen, data);
|
||||
return 1;
|
||||
}
|
||||
|
||||
free (data);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
LIBSSH2_SESSION *session;
|
||||
@@ -50,6 +78,8 @@ int main(int argc, char *argv[])
|
||||
return 1;
|
||||
}
|
||||
|
||||
test_libssh2_base64_decode (session);
|
||||
|
||||
libssh2_session_free(session);
|
||||
|
||||
return 0;
|
||||
|
170
tests/ssh2.c
Normal file
170
tests/ssh2.c
Normal file
@@ -0,0 +1,170 @@
|
||||
/* Self test, based on examples/simple/ssh2.c. */
|
||||
|
||||
#include "libssh2_config.h"
|
||||
#include <libssh2.h>
|
||||
#include <libssh2_sftp.h>
|
||||
|
||||
#ifdef HAVE_WINDOWS_H
|
||||
# include <windows.h>
|
||||
#endif
|
||||
#ifdef HAVE_WINSOCK2_H
|
||||
# include <winsock2.h>
|
||||
#endif
|
||||
#ifdef HAVE_NETINET_IN_H
|
||||
# include <netinet/in.h>
|
||||
#endif
|
||||
#ifdef HAVE_SYS_SOCKET_H
|
||||
# include <sys/socket.h>
|
||||
#endif
|
||||
# ifdef HAVE_UNISTD_H
|
||||
#include <unistd.h>
|
||||
#endif
|
||||
# ifdef HAVE_ARPA_INET_H
|
||||
#include <arpa/inet.h>
|
||||
#endif
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <fcntl.h>
|
||||
#include <errno.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <ctype.h>
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
unsigned long hostaddr;
|
||||
int sock, i, auth_pw = 0;
|
||||
struct sockaddr_in sin;
|
||||
const char *fingerprint;
|
||||
char *userauthlist;
|
||||
LIBSSH2_SESSION *session;
|
||||
LIBSSH2_CHANNEL *channel;
|
||||
#ifdef WIN32
|
||||
WSADATA wsadata;
|
||||
|
||||
WSAStartup(MAKEWORD(2,0), &wsadata);
|
||||
#endif
|
||||
const char *pubkeyfile="etc/user.pub";
|
||||
const char *privkeyfile="etc/user";
|
||||
const char *username="username";
|
||||
const char *password="password";
|
||||
int ec = 1;
|
||||
|
||||
if (getenv ("USER"))
|
||||
username = getenv ("USER");
|
||||
|
||||
if (getenv ("PRIVKEY"))
|
||||
privkeyfile = getenv ("PRIVKEY");
|
||||
|
||||
if (getenv ("PRIVKEY"))
|
||||
pubkeyfile = getenv ("PUBKEY");
|
||||
|
||||
hostaddr = htonl(0x7F000001);
|
||||
|
||||
sock = socket(AF_INET, SOCK_STREAM, 0);
|
||||
#ifndef WIN32
|
||||
fcntl(sock, F_SETFL, 0);
|
||||
#endif
|
||||
sin.sin_family = AF_INET;
|
||||
sin.sin_port = htons(4711);
|
||||
sin.sin_addr.s_addr = hostaddr;
|
||||
if (connect(sock, (struct sockaddr*)(&sin),
|
||||
sizeof(struct sockaddr_in)) != 0) {
|
||||
fprintf(stderr, "failed to connect!\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Create a session instance and start it up
|
||||
* This will trade welcome banners, exchange keys, and setup crypto, compression, and MAC layers
|
||||
*/
|
||||
session = libssh2_session_init();
|
||||
if (libssh2_session_startup(session, sock)) {
|
||||
fprintf(stderr, "Failure establishing SSH session\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* At this point we havn't authenticated,
|
||||
* The first thing to do is check the hostkey's fingerprint against our known hosts
|
||||
* Your app may have it hard coded, may go to a file, may present it to the user, that's your call
|
||||
*/
|
||||
fingerprint = libssh2_hostkey_hash(session, LIBSSH2_HOSTKEY_HASH_MD5);
|
||||
printf("Fingerprint: ");
|
||||
for(i = 0; i < 16; i++) {
|
||||
printf("%02X ", (unsigned char)fingerprint[i]);
|
||||
}
|
||||
printf("\n");
|
||||
|
||||
/* check what authentication methods are available */
|
||||
userauthlist = libssh2_userauth_list(session, username, strlen(username));
|
||||
printf("Authentication methods: %s\n", userauthlist);
|
||||
if (strstr(userauthlist, "password") != NULL) {
|
||||
auth_pw |= 1;
|
||||
}
|
||||
if (strstr(userauthlist, "keyboard-interactive") != NULL) {
|
||||
auth_pw |= 2;
|
||||
}
|
||||
if (strstr(userauthlist, "publickey") != NULL) {
|
||||
auth_pw |= 4;
|
||||
}
|
||||
|
||||
if (auth_pw & 4) {
|
||||
/* Authenticate by public key */
|
||||
if (libssh2_userauth_publickey_fromfile(session, username, pubkeyfile, privkeyfile, password)) {
|
||||
printf("\tAuthentication by public key failed!\n");
|
||||
goto shutdown;
|
||||
} else {
|
||||
printf("\tAuthentication by public key succeeded.\n");
|
||||
}
|
||||
} else {
|
||||
printf("No supported authentication methods found!\n");
|
||||
goto shutdown;
|
||||
}
|
||||
|
||||
/* Request a shell */
|
||||
if (!(channel = libssh2_channel_open_session(session))) {
|
||||
fprintf(stderr, "Unable to open a session\n");
|
||||
goto shutdown;
|
||||
}
|
||||
|
||||
/* Some environment variables may be set,
|
||||
* It's up to the server which ones it'll allow though
|
||||
*/
|
||||
libssh2_channel_setenv(channel, "FOO", "bar");
|
||||
|
||||
/* Request a terminal with 'vanilla' terminal emulation
|
||||
* See /etc/termcap for more options
|
||||
*/
|
||||
if (libssh2_channel_request_pty(channel, "vanilla")) {
|
||||
fprintf(stderr, "Failed requesting pty\n");
|
||||
goto skip_shell;
|
||||
}
|
||||
|
||||
/* Open a SHELL on that pty */
|
||||
if (libssh2_channel_shell(channel)) {
|
||||
fprintf(stderr, "Unable to request shell on allocated pty\n");
|
||||
goto shutdown;
|
||||
}
|
||||
|
||||
ec = 0;
|
||||
|
||||
skip_shell:
|
||||
if (channel) {
|
||||
libssh2_channel_free(channel);
|
||||
channel = NULL;
|
||||
}
|
||||
|
||||
shutdown:
|
||||
|
||||
libssh2_session_disconnect(session, "Normal Shutdown");
|
||||
libssh2_session_free(session);
|
||||
|
||||
#ifdef WIN32
|
||||
Sleep(1000);
|
||||
closesocket(sock);
|
||||
#else
|
||||
sleep(1);
|
||||
close(sock);
|
||||
#endif
|
||||
|
||||
return ec;
|
||||
}
|
39
tests/ssh2.sh
Executable file
39
tests/ssh2.sh
Executable file
@@ -0,0 +1,39 @@
|
||||
#!/bin/sh
|
||||
|
||||
# Written by Simon Josefsson.
|
||||
|
||||
# Start sshd, invoke parameters, saving exit code, kill sshd, and
|
||||
# return exit code.
|
||||
|
||||
srcdir=${srcdir:-$PWD}
|
||||
SSHD=${SSHD:-/usr/sbin/sshd}
|
||||
|
||||
cmd="./ssh2${EXEEXT}"
|
||||
srcdir=`cd $srcdir; pwd`
|
||||
|
||||
PRIVKEY=$srcdir/etc/user
|
||||
export PRIVKEY
|
||||
PUBKEY=$srcdir/etc/user.pub
|
||||
export PUBKEY
|
||||
|
||||
chmod go-r $srcdir/etc/host*
|
||||
$SSHD -f /dev/null -h $srcdir/etc/host \
|
||||
-o 'Port 4711' -o 'Protocol 2' \
|
||||
-o "AuthorizedKeysFile $srcdir/etc/user.pub" -D &
|
||||
sshdpid=$!
|
||||
|
||||
trap "kill ${sshdpid}; echo signal killing sshd; exit 1;" EXIT
|
||||
|
||||
: "started sshd (${sshdpid})"
|
||||
|
||||
sleep 3
|
||||
|
||||
: Invoking $cmd...
|
||||
eval $cmd
|
||||
ec=$?
|
||||
: Self-test exit code $ec
|
||||
|
||||
: "killing sshd (${sshdpid})"
|
||||
kill "${sshdpid}" > /dev/null 2>&1
|
||||
trap "" EXIT
|
||||
exit $ec
|
28
tests/sshdwrap
Executable file
28
tests/sshdwrap
Executable file
@@ -0,0 +1,28 @@
|
||||
#!/bin/sh -x
|
||||
|
||||
# Written by Simon Josefsson
|
||||
|
||||
# Start sshd, invoke parameters, saving exit code, kill sshd, and
|
||||
# return exit code.
|
||||
|
||||
cmd="$@"
|
||||
SSHD=${SSHD:-/usr/sbin/sshd}
|
||||
|
||||
$SSHD -f etc/sshd_config -h $PWD/etc/host -D &
|
||||
sshdpid=$!
|
||||
|
||||
trap "kill ${sshdpid}; echo signal killing sshd; exit 1;" EXIT
|
||||
|
||||
: "started sshd (${sshdpid})"
|
||||
|
||||
sleep 1
|
||||
|
||||
: Invoking $cmd...
|
||||
eval $cmd
|
||||
ec=$?
|
||||
: Self-test exit code $ec
|
||||
|
||||
: "killing sshd (${sshdpid})"
|
||||
kill "${sshdpid}" > /dev/null 2>&1
|
||||
trap "" EXIT
|
||||
exit $ec
|
@@ -5,7 +5,7 @@
|
||||
##
|
||||
## Comments to: Guenter Knauf <eflash@gmx.net>
|
||||
##
|
||||
## $Id: Makefile.win32,v 1.8 2007/07/21 22:59:24 gknauf Exp $
|
||||
## $Id: Makefile.win32,v 1.9 2007/08/18 18:53:26 gknauf Exp $
|
||||
#
|
||||
#########################################################################
|
||||
|
||||
@@ -67,6 +67,8 @@ else
|
||||
endif
|
||||
CP = cp -afv
|
||||
# RM = rm -f
|
||||
# Here you can find a native Win32 binary of the original awk:
|
||||
# http://www.gknw.net/development/prgtools/awk.zip
|
||||
AWK = awk
|
||||
ZIP = zip -qzr9
|
||||
|
||||
|
@@ -16,43 +16,21 @@
|
||||
|
||||
#define HAVE_WINSOCK2_H
|
||||
#define HAVE_IOCTLSOCKET
|
||||
|
||||
/* same as WSABUF */
|
||||
struct iovec {
|
||||
u_long iov_len;
|
||||
char *iov_base;
|
||||
};
|
||||
|
||||
#define inline __inline
|
||||
|
||||
static inline int writev(int sock, struct iovec *iov, int nvecs)
|
||||
{
|
||||
DWORD ret;
|
||||
if (WSASend(sock, (LPWSABUF)iov, nvecs, &ret, 0, NULL, NULL) == 0) {
|
||||
return ret;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* not really usleep, but safe for the way we use it in this lib */
|
||||
static inline int usleep(int udelay)
|
||||
{
|
||||
Sleep(udelay / 1000);
|
||||
return 0;
|
||||
}
|
||||
#define HAVE_SELECT
|
||||
|
||||
#ifdef _MSC_VER
|
||||
#define snprintf _snprintf
|
||||
#if _MSC_VER < 1500
|
||||
#define vsnprintf _vsnprintf
|
||||
#else
|
||||
#define ssize_t SSIZE_T
|
||||
#define uint32_t UINT32
|
||||
#endif
|
||||
#define strncasecmp _strnicmp
|
||||
#define strcasecmp _stricmp
|
||||
#else
|
||||
#ifdef __MINGW32__
|
||||
#define WINSOCK_VERSION MAKEWORD(2,0)
|
||||
#else
|
||||
#define strncasecmp strnicmp
|
||||
#define strcasecmp stricmp
|
||||
#endif /* __MINGW32__ */
|
||||
#endif /* _MSC_VER */
|
||||
|
||||
/* Compile in zlib support */
|
||||
|
@@ -5,7 +5,7 @@
|
||||
##
|
||||
## Comments to: Guenter Knauf <eflash@gmx.net>
|
||||
##
|
||||
## $Id: Makefile.win32,v 1.5 2007/04/21 23:36:51 gknauf Exp $
|
||||
## $Id: Makefile.win32,v 1.6 2007/08/18 18:53:26 gknauf Exp $
|
||||
#
|
||||
#########################################################################
|
||||
|
||||
@@ -55,6 +55,8 @@ else
|
||||
endif
|
||||
CP = cp -afv
|
||||
# RM = rm -f
|
||||
# Here you can find a native Win32 binary of the original awk:
|
||||
# http://www.gknw.net/development/prgtools/awk.zip
|
||||
AWK = awk
|
||||
ZIP = zip -qzr9
|
||||
|
||||
|
Reference in New Issue
Block a user