Compare commits

..

78 Commits

Author SHA1 Message Date
Daniel Stenberg
dbbd9eafc6 mention Dan Fandrich and Guenter Knauf 2007-11-10 23:36:41 +00:00
Daniel Stenberg
c92465930d fix three compiler warnings on comparison between signed and unsigned 2007-11-08 15:53:04 +00:00
Daniel Stenberg
34d5c9a4b1 Added a note about recent changes in a summarized way, added dates to the three
most recent releases and made many lines < 80 columns.
2007-11-08 15:42:09 +00:00
Daniel Stenberg
e8bb993437 include specified files from the win32 dir, not everything within it since
that gives us CVS files too etc
2007-11-08 15:14:13 +00:00
Daniel Stenberg
030b670e2a Moved the check that the amount of data is larger than the blocksize to
only get done on the first block. Based on the bug report #1826989
https://sourceforge.net/tracker/?func=detail&atid=703942&aid=1826989&group_id=125852
2007-11-08 13:51:23 +00:00
Daniel Stenberg
371a795443 fix transfer stall bug with non-blocking transfers, by Gavrie Philipson 2007-11-08 13:46:54 +00:00
Dan Fandrich
2d773f9322 Stop shadowing a global declaration 2007-09-28 18:29:40 +00:00
Daniel Stenberg
80f6c7c6d1 Immanuel Gregoire made libssh2_packet_read() properly deal with blocks when
in non-blocking state. Until this fix, libssh2 just couldn't work properly
on Windows while non-blocking.
2007-09-24 20:49:43 +00:00
Daniel Stenberg
46f26d3d0e oops, that was debugging code that wasn't supposed to be committed! 2007-09-24 12:15:45 +00:00
Daniel Stenberg
5d91d286f1 fix by Immanuel Gregoire, sizeof != strlen! 2007-09-24 12:14:18 +00:00
Guenter Knauf
5a854cfb26 fixed ssize_t typedef; added a define to detect already defined ssize_t. 2007-09-18 18:13:18 +00:00
Guenter Knauf
e905b206ed fix line endings to crlf and flag binary to avoid nasty conversions. 2007-09-15 15:26:37 +00:00
Dan Fandrich
fe7a6f967d Mention the const change in libssh2_channel_setenv_ex since it's a (minor)
change to the API.
2007-08-20 23:26:58 +00:00
Guenter Knauf
5879a0245b added link to native Win32 awk. 2007-08-18 18:53:26 +00:00
Daniel Stenberg
d90d8bdae7 The libssh2_channel_receive_window_adjust() function failed to set the state
variables at times and thus this function would misbehave on repeated invokes.
2007-08-12 21:53:32 +00:00
Daniel Stenberg
f216b36328 When we have less than blocksize data left we MUST (attempt to) read more
since we can't decrypt anything in that situation.
2007-08-10 22:22:45 +00:00
Dan Fandrich
c4630d1ffb Removed unnecessary casts and added const where necessary. 2007-08-09 01:10:11 +00:00
Dan Fandrich
17173aab0e Added const to varname parameter of libssh2_channel_setenv_ex 2007-08-09 01:09:09 +00:00
Dan Fandrich
f8d4de78e9 Fixed the samples to build outside the source tree.
Removed redundant _SOURCES lines.
2007-08-09 00:42:05 +00:00
Daniel Stenberg
e32ff531a3 Satish Mittal and David J Sullivan fixed an infinit recv() loop in
libssh2_banner_receive()
2007-08-08 21:43:12 +00:00
Guenter Knauf
a227554c26 fixed test makefile to generate config.h. 2007-08-08 16:32:42 +00:00
Daniel Stenberg
9f27d176f8 we work on 0.18 now, although it might be 1.0 - who knows? 2007-08-06 20:59:08 +00:00
Daniel Stenberg
bcc4fd6e82 0.17 re-indent 2007-08-06 20:50:22 +00:00
Daniel Stenberg
210459db4b re-indented the source code with this script:
indent \
--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 \
*.[ch]
2007-08-06 20:48:04 +00:00
Daniel Stenberg
4c3dd3ea9f 0.16 news 2007-08-06 15:00:48 +00:00
James Housley
0d78e69016 libssh2_userauth_list() requires the lenght of the username to be passed,
and not the sizeof() the array holding it.
2007-08-03 15:08:28 +00:00
Daniel Stenberg
02e5b3b423 LIBSSH2_APINO is now gone, the sooner the better. This is gonna cause some
pains in apps relying on it, but it is broken by design and we should not
rely on it at all. Go for the LIBSSH2_VERSION_* defines instead if you need
to check for versions.
2007-08-03 08:05:36 +00:00
Daniel Stenberg
9399ef83c4 this is generated, no need to commit it 2007-08-03 08:04:15 +00:00
Daniel Stenberg
68c86e2c4c The examples no longer have an include path pointing to the private source dir
but instead uses its own config.h file, that now is included first to make
large file magic have an effect.
2007-07-31 11:00:29 +00:00
Daniel Stenberg
15e0f56d01 add large file magic checks, and make sure we update the config.h file in the
example/simple subdir as well
2007-07-31 10:04:57 +00:00
Daniel Stenberg
d2ef367552 create a private config.h file for the examples 2007-07-31 10:04:24 +00:00
Daniel Stenberg
3167f054ff Peter O'Gorman pointed out (and fixed) that the non-blocking check in
configure made libssh2 use blocking sockets on AIX 4 and 5, while that
wasn't the intention.
2007-07-30 22:55:43 +00:00
Daniel Stenberg
209d06d6c9 libssh2_poll() no longer relies on C99 features but instead uses alloca()
on systems that have it - and uses a fixed-size array on those that don't.
session.c was also cleaned from a large amount of trailing whitespace.
2007-07-23 21:18:43 +00:00
Guenter Knauf
2b7856ad32 ooups - forgotten var added. 2007-07-22 02:15:31 +00:00
Guenter Knauf
9a1ce06e31 added keyboard-interactive auth method;
added 5. argument to specify auth method.
2007-07-22 02:07:55 +00:00
Guenter Knauf
c9413c628d changed prelude file for gcc build. 2007-07-22 00:47:21 +00:00
Guenter Knauf
327c31a634 added var to specify cross compiler prefix. 2007-07-21 22:59:24 +00:00
Guenter Knauf
4ace76b30d added some defines for MSVC and other non-gcc compilers. 2007-07-20 09:52:02 +00:00
Guenter Knauf
2127c5967e moved the inclusion of libssh2_config.h to the top. 2007-07-20 09:51:05 +00:00
Guenter Knauf
242475c42a added keyboard-interactive auth method;
added 4. argument to specify auth method.
2007-07-20 01:23:10 +00:00
Guenter Knauf
854dffe0a4 moved blocks to make keyboard-interactive second choice (if implemented). 2007-07-19 17:08:54 +00:00
Guenter Knauf
278219fc0a few cosmetic changes; added block for future implementation of keyboard-interactive method. 2007-07-19 15:43:48 +00:00
Guenter Knauf
16be3fc778 removed obsolete line. 2007-07-19 15:29:06 +00:00
Guenter Knauf
edcfab905a added selection of authentication method based on what libssh2_userauth_list() returns; added vars for the key files. 2007-07-19 15:25:46 +00:00
James Housley
46f59112d9 * After setting the error to the error string from in the packet, set
the pointer to NULL so it can't be double freed.
* On session cleanup be sure to free the last error if it needs to be
2007-07-19 15:02:37 +00:00
James Housley
05c1164a67 The test after the memory allocation was backwards, so keyboard-interactive
would always fail due to a memory problem.
2007-07-18 19:54:51 +00:00
Guenter Knauf
3fc4caf42f fixed call to libssh2_userauth_list() since NULL isnt supported for the username. 2007-07-18 19:31:15 +00:00
Guenter Knauf
1a9fee074b added check for available authentication methods. 2007-07-18 11:46:25 +00:00
Guenter Knauf
8f62c7322f added NMakefile to Makefile.am so that it gets included with releases and daily snapshots. 2007-07-17 13:22:55 +00:00
Guenter Knauf
839be89a49 added test success messages. 2007-07-16 22:16:21 +00:00
Guenter Knauf
669e69966a another trial to fix the typedefs. 2007-07-16 22:05:30 +00:00
Guenter Knauf
138b1b3830 fixed MSVC project files to build static lib and dll in separate direcories. 2007-07-15 23:46:30 +00:00
Daniel Stenberg
4088283465 support --enable-maintainer-mode 2007-07-15 22:21:46 +00:00
Guenter Knauf
402978bd1b fixed MSVC project files. 2007-07-15 22:11:12 +00:00
Daniel Stenberg
387a1fdf4b add maketgz to release archives 2007-07-15 21:47:27 +00:00
Daniel Stenberg
d574d7dea0 Added LIBSSH2_TIMESTAMP to the public header and it contains the timestamp of
the making of the release archive.

Added 'maketgz' as a script to build release archives with, including automated
snapshots or whatever. It updates the defines in include/libssh2.h.

configure now extracts the version number from the include/libssh2.h header in
the source tree instead of using it fixed set in the script (to remove the
need for regenerating the configure script when we run maketgz).

Makefile.am now has a dist-hook that puts ".dist" files in the release tree
instead of the file without the .dist extension, so that we can easily add
modified files in release archives. Like maketgz.
2007-07-15 21:36:29 +00:00
Guenter Knauf
b2df0b26f7 fixed test makefile to build all samples. 2007-07-15 20:34:33 +00:00
Guenter Knauf
bb76ed34a0 fixed NMakefile stuff to build at least the DLL again. 2007-07-15 20:06:19 +00:00
Simon Josefsson
153e1959f4 Fix make distcheck. Noted by Daniel. 2007-07-15 08:22:00 +00:00
Daniel Stenberg
a3155d5d12 I'm fine with just name 2007-07-14 23:33:21 +00:00
Guenter Knauf
8485ee6fd5 introduced some more version defines. 2007-07-14 22:18:32 +00:00
Daniel Stenberg
4f76c2b80c Metion the current code style in the new file called HACKING. In this, we
could also add descriptions on how to send us patches and bug reports etc...
2007-07-14 21:28:02 +00:00
Daniel Stenberg
accd865aff converted to 4-level space indents, no trailing whitespace 2007-07-14 21:24:38 +00:00
Guenter Knauf
84e16944b4 some more NetWare makefile fixes. 2007-07-14 21:04:32 +00:00
Daniel Stenberg
e0254f3936 removed compiler warnings, narrowed some source lines, killed trailing
whitespace
2007-07-14 20:54:47 +00:00
James Housley
14881b2370 For now make LIBSSH2_APINO a long, some compilers make constants an int it
seems.
2007-07-14 16:21:50 +00:00
Guenter Knauf
4ec68bdc04 added build for older CLIB version. 2007-07-09 22:47:24 +00:00
James Housley
a87fdff9e9 The variable "packet" needs to be in LIBSSH2_SFTP_HANDLE for re-entry when
blocking in libssh2_sftp_close_handle()
2007-07-09 15:11:37 +00:00
James Housley
50fd6590f0 While the previous commit seemed to correct a problem, it actually exposed
another problem.  Commit this until a proper fix is found
2007-07-08 17:14:19 +00:00
James Housley
2b1c979d7e Remove a blocking while loop that wasn't removed when the code to
return PACKET_EAGAIN was added, but should have been.
2007-07-08 15:37:44 +00:00
James Housley
6ac790a477 * Since the packet as already had data read from it, it can't retrun
PACKET_EAGAIN while reading the rest of it.
* Get the error message in libssh2_scp_recv() in the same manner as it
  was gotten in libssh2_scp_send_ex()
2007-07-05 15:31:19 +00:00
Guenter Knauf
b53db3d3a9 fix bug #1701782 - for now we only define for the compiler versions where we know for sure - if later versions still need those defines please report to the list. 2007-07-05 12:52:30 +00:00
Guenter Knauf
83d77f3878 enter next round after release. 2007-07-05 12:46:42 +00:00
James Housley
530e57d4ac Gavrie Philipson sumitted a patch to get the actual text of the error
on scp upload.
2007-07-05 11:08:17 +00:00
James Housley
a9fc3bdb4e Change the wording of the return value to match the rest of the man pages 2007-07-04 10:44:40 +00:00
Mikhail Gusarov
e2c88f6ae3 Fixed manpage syntax (catched by Debian's lintian) 2007-07-04 09:42:08 +00:00
Daniel Stenberg
cf9ed016e7 as mentioned in bug #1655429, the CRLF pair was stripped off in the wrong
order!
2007-06-28 20:53:32 +00:00
Daniel Stenberg
1901324122 added missing files (in 0.15) to the release tarball 2007-06-25 20:48:07 +00:00
62 changed files with 8784 additions and 7506 deletions

View File

@@ -1,5 +1,5 @@
jas4711:Simon Josefsson <simon@josefsson.org> jas4711:Simon Josefsson <simon@josefsson.org>
bagder:Daniel Stenberg <daniel@haxx.se> bagder:Daniel Stenberg
sarag:Sara Golemon <pollita@libssh2.org> sarag:Sara Golemon <pollita@libssh2.org>
gusarov:Mikhail Gusarov <dottedmag@dottedmag.net> gusarov:Mikhail Gusarov <dottedmag@dottedmag.net>
wez:Wez Furlong wez:Wez Furlong

View File

@@ -4,8 +4,13 @@
* Simon Josefsson: libgcrypt support * 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 * Mikhail Gusarov: Keyboard Interactive Authentication
* Wez Furlong & Edink Kadribasic: Windows Port * Wez Furlong & Edink Kadribasic: Windows Port
* Dan Fandrich: bug fixes, cleanups
* Guenter Knauf: win32 work and more

1606
ChangeLog

File diff suppressed because it is too large Load Diff

32
HACKING Normal file
View File

@@ -0,0 +1,32 @@
libssh2 source code style guide:
- 4 level indent
- spaces-only (no tabs)
- open braces on the if/for line:
if (banana) {
go_nuts();
}
- write both braces on the else line:
if (banana) {
go_nuts();
} else {
stay_calm();
}
- use braces even for single-statement blocks
- keep source lines shorter than 80 columns
------------
Older libssh2 code that still hasn't quite transitioned to the above
mentioned style, used a different style:
- indented with tabs (only)
- no line length limits

View File

@@ -5,7 +5,18 @@ include_HEADERS = \
include/libssh2_publickey.h \ include/libssh2_publickey.h \
include/libssh2_sftp.h include/libssh2_sftp.h
EXTRA_DIST = win32 buildconf NETWAREFILES = nw/keepscreen.c \
nw/Makefile \
nw/Makefile.netware \
nw/nwlib.c \
nw/test/Makefile.netware
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
ACLOCAL_AMFLAGS = -I m4 ACLOCAL_AMFLAGS = -I m4
@@ -14,3 +25,12 @@ ChangeLog:
if test -f .cvsusers; then \ if test -f .cvsusers; then \
cvs2cl --utc --fsf --FSF --usermap .cvsusers -I ChangeLog -I .cvs; \ cvs2cl --utc --fsf --FSF --usermap .cvsusers -I ChangeLog -I .cvs; \
fi fi
dist-hook:
rm -rf $(top_builddir)/tests/log
find $(distdir) -name "*.dist" -exec rm {} \;
(distit=`find $(srcdir) -name "*.dist"`; \
for file in $$distit; do \
strip=`echo $$file | sed -e s/^$(srcdir)// -e s/\.dist//`; \
cp $$file $(distdir)$$strip; \
done)

143
NEWS
View File

@@ -1,5 +1,72 @@
Version Version 0.18
------------ ------------
- 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
o libssh2_scp_recv() error message fix
o added HACKING as an initial attempt to describe our source code format
o new public defines in include/libssh2.h to allow applictions to figure out
version number etc
o new script (maketgz) to build releases with
o updated files for building with MSVC and mingw
o keyboard-interactive would always fail due to claimed memory problem
o a few minor memory leaks fixed
o libssh2_poll() no longer relies on C99 features
o AIX 4 and 5 now supports non-blocking sockets
o large file magic checks in configure
o LIBSSH2_APINO was removed from the public header file
This release would not have been possible without these friendly contributors:
James Housley, Simon Josefsson, Dan Fandrich, Guenter Knauf and I too did
some poking. (Sorry if I forgot anyone I should've mentioned here.)
Of course we would have nothing without the great work by Sara Golemon that
we're extending and building upon.
Version 0.15 (June 15 2007)
---------------------------
Added libssh2_sftp_readdir_ex() and updated LIBSSH2_APINO to Added libssh2_sftp_readdir_ex() and updated LIBSSH2_APINO to
200706151200 (James Housley) 200706151200 (James Housley)
@@ -72,7 +139,8 @@ Version 0.14
Allow socket_fd == 0 in libssh2_session_startup(). (puudeli) 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. Swap KEX_INIT ordering, send our KEX_INIT first.
@@ -83,9 +151,11 @@ Version 0.14
Version 0.13 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. Fixed `make install' target for MacOSX.
@@ -102,10 +172,12 @@ Version 0.12
(Thanks Simon Hart) (Thanks Simon Hart)
Fix generation of 'e' portion of Diffie-Hellman keyset. Fix generation of 'e' portion of Diffie-Hellman keyset.
Use appropriate order for BN_rand() rather than fixed group1-specific value.
Use appropriate order for BN_rand() rather than fixed group1-specific value.
Re-fixed libssh2_sftp_rename_ex() Re-fixed libssh2_sftp_rename_ex()
Transport had right packet_len, but sftp layer still had extra 4 bytes.
Transport had right packet_len, but sftp layer still had extra 4 bytes.
Fixed build with newer OpenSSL headers. Fixed build with newer OpenSSL headers.
@@ -120,42 +192,52 @@ Version 0.11
Added libssh2_userauth_keyboard_interactive_ex() -- Mikhail 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 Fixed libssh2_sftp_rename_ex() to only send flags parameter if version >= 5
(not currently possible, but will be and might as well keep the API consistent). negotiated (not currently possible, but will be and might as well keep the
API consistent).
Version 0.10 Version 0.10
------------ ------------
Added developer debugging hooks. See --enable-debug-* options to ./configure 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. (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. Reduced busy-looping of libssh2_sftp_packet_requirev.
Version 0.9 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 SFTP to be properly BC with version 1 and 2 servers.
Fixed libssh2_poll() to recognized closed sessions/channels. 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. Added tests for -lm and -lsocket and add them when necessary.
@@ -169,9 +251,11 @@ Version 0.8
Fix compatability with older versions of OpenSSL 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. Added libssh2_poll() to check status of sockets/channels/listeners.
@@ -194,15 +278,18 @@ Version 0.7
Version 0.6 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. 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 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. Fixed client to server channel windowing. Pervent send queue overruns.
@@ -212,7 +299,8 @@ Version 0.5
----------- -----------
*** BC Break *** *** 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). Fixed libssh2_attr2bin() (effects any setstat style call).
@@ -222,11 +310,14 @@ Version 0.5
Fixed KEX_INIT cookie and packet padding to use actual random data 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. Added MAC methods hmac-md5 and hmac-md5-96.

View File

@@ -1,16 +1,19 @@
!include "win32/config.mk" !include "win32/config.mk"
# SUBDIRS=src example\simple
SUBDIRS=src SUBDIRS=src
all: all-sub ssh2_sample.exe
ssh2_sample.exe: ssh2_sample.c
$(CC) $(CFLAGS) -DWIN32 -o ssh2_sample.exe ssh2_sample.c libssh2$(SUFFIX).lib $(LIBS)
all-sub: all-sub:
-for %D in ($(SUBDIRS)) do $(MAKE) /nologo /f %D/NMakefile BUILD=$(BUILD) SUBDIR=%D all-sub -for %D in ($(SUBDIRS)) do $(MAKE) /nologo /f %D/NMakefile BUILD=$(BUILD) SUBDIR=%D all-sub
clean: clean:
rmdir /s/q $(TARGET) -rmdir /s/q $(TARGET)
real-clean: clean
-del libssh2.dll
-del libssh2.exp
-del libssh2.ilk
-del libssh2.lib
-del *.pdb

View File

@@ -178,7 +178,7 @@ AC_DEFUN([CURL_CHECK_NONBLOCKING_SOCKET],
# define PLATFORM_SUNOS4 # define PLATFORM_SUNOS4
# endif # endif
#endif #endif
#if (defined(_AIX) || defined(__xlC__)) && !defined(_AIX4) #if (defined(_AIX) || defined(__xlC__)) && !defined(_AIX41)
# define PLATFORM_AIX_V3 # define PLATFORM_AIX_V3
#endif #endif

View File

@@ -3,5 +3,9 @@
${LIBTOOLIZE:-libtoolize} --copy --automake --force ${LIBTOOLIZE:-libtoolize} --copy --automake --force
${ACLOCAL:-aclocal} -I m4 $ACLOCAL_FLAGS ${ACLOCAL:-aclocal} -I m4 $ACLOCAL_FLAGS
${AUTOHEADER:-autoheader} ${AUTOHEADER:-autoheader}
# copy the private libssh2_config.h.in to the examples dir so that
# it can be included without pointing the include path to the private
# source dir
cp src/libssh2_config.h.in example/simple/config.h.in
${AUTOCONF:-autoconf} ${AUTOCONF:-autoconf}
${AUTOMAKE:-automake} --add-missing --copy ${AUTOMAKE:-automake} --add-missing --copy

View File

@@ -1,8 +1,26 @@
# AC_PREREQ(2.57) # AC_PREREQ(2.57)
AC_INIT(libssh2, 0.15, libssh2-devel@lists.sourceforge.net) AC_INIT(libssh2, [-], libssh2-devel@lists.sourceforge.net)
AM_INIT_AUTOMAKE(libssh2, 0.15)
AC_CONFIG_SRCDIR([src]) AC_CONFIG_SRCDIR([src])
AC_CONFIG_HEADER([src/libssh2_config.h]) AC_CONFIG_HEADER([src/libssh2_config.h example/simple/config.h])
AM_MAINTAINER_MODE
dnl SED is needed by some of the tools
AC_PATH_PROG( SED, sed, sed-was-not-found-by-configure,
$PATH:/usr/bin:/usr/local/bin)
AC_SUBST(SED)
if test "x$SED" = "xsed-was-not-found-by-configure"; then
AC_MSG_WARN([sed was not found, this may ruin your chances to build fine])
fi
dnl figure out the libssh2 version
VERSION=`$SED -ne 's/^#define LIBSSH2_VERSION *"\(.*\)"/\1/p' ${srcdir}/include/libssh2.h`
AM_INIT_AUTOMAKE(libssh2,$VERSION)
AC_MSG_CHECKING([libssh2 version])
AC_MSG_RESULT($VERSION)
AB_VERSION=$VERSION
AB_INIT AB_INIT
# Check for the OS. # Check for the OS.
@@ -40,6 +58,9 @@ if test -z "$PKG_CONFIG"; then
AC_PATH_PROG(PKG_CONFIG, pkg-config, no) AC_PATH_PROG(PKG_CONFIG, pkg-config, no)
fi fi
dnl check for how to do large files
AC_SYS_LARGEFILE
# Look for libgcrypt. # Look for libgcrypt.
AC_ARG_WITH(libgcrypt, AC_ARG_WITH(libgcrypt,
AC_HELP_STRING([--with-libgcrypt],[Use libgcrypt for crypto]), AC_HELP_STRING([--with-libgcrypt],[Use libgcrypt for crypto]),
@@ -230,6 +251,8 @@ 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_HEADERS([arpa/inet.h netinet/in.h])
AC_CHECK_FUNCS(poll gettimeofday select) AC_CHECK_FUNCS(poll gettimeofday select)
AC_FUNC_ALLOCA
# Checks for typedefs, structures, and compiler characteristics. # Checks for typedefs, structures, and compiler characteristics.
AC_C_CONST AC_C_CONST
AC_C_INLINE AC_C_INLINE

View File

@@ -1,4 +1,4 @@
.\" $Id: libssh2_sftp_readdir.3,v 1.9 2007/06/15 17:22:49 jehousley Exp $ .\" $Id: libssh2_sftp_readdir.3,v 1.11 2007/07/04 10:44:40 jehousley Exp $
.\" .\"
.TH libssh2_sftp_readdir_ex 3 "1 Jun 2007" "libssh2 0.15" "libssh2 manual" .TH libssh2_sftp_readdir_ex 3 "1 Jun 2007" "libssh2 0.15" "libssh2 manual"
.SH NAME .SH NAME
@@ -41,7 +41,7 @@ however, it uses a variable sized directory entry (filename) buffer and
returns statbuf type data in the same call. returns statbuf type data in the same call.
.SH RETURN VALUE .SH RETURN VALUE
Number of bytes actually populated into buffer, or -1 on failure. It returns Number of bytes actually populated into buffer, or negative on failure. It returns
LIBSSH2_ERROR_EAGAIN when it would otherwise block. While LIBSSH2_ERROR_EAGAIN when it would otherwise block. While
LIBSSH2_ERROR_EAGAIN is a negative number, it isn't really a failure per se. LIBSSH2_ERROR_EAGAIN is a negative number, it isn't really a failure per se.
.SH ERRORS .SH ERRORS

View File

@@ -10,34 +10,6 @@ noinst_PROGRAMS = ssh2 \
sftp_RW_nonblock \ sftp_RW_nonblock \
sftpdir sftpdir_nonblock sftpdir sftpdir_nonblock
INCLUDES = -I$(top_srcdir)/include -I$(top_builddir)/src INCLUDES = -I. -I$(top_srcdir)/include
LDADD = $(top_builddir)/src/libssh2.la 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

View File

@@ -1,11 +1,11 @@
/* /*
* $Id: scp.c,v 1.7 2007/06/06 12:34:08 jehousley Exp $ * $Id: scp.c,v 1.10 2007/08/09 01:10:11 dfandrich Exp $
* *
* Sample showing how to do a simple SCP transfer. * Sample showing how to do a simple SCP transfer.
*/ */
#include "config.h"
#include <libssh2.h> #include <libssh2.h>
#include <libssh2_config.h>
#ifdef HAVE_WINSOCK2_H #ifdef HAVE_WINSOCK2_H
# include <winsock2.h> # include <winsock2.h>
@@ -40,9 +40,9 @@ int main(int argc, char *argv[])
const char *fingerprint; const char *fingerprint;
LIBSSH2_SESSION *session; LIBSSH2_SESSION *session;
LIBSSH2_CHANNEL *channel; LIBSSH2_CHANNEL *channel;
char *username=(char *)"username"; const char *username="username";
char *password=(char *)"password"; const char *password="password";
char *scppath=(char *)"/tmp/TEST"; const char *scppath="/tmp/TEST";
struct stat fileinfo; struct stat fileinfo;
int rc; int rc;
off_t got=0; off_t got=0;
@@ -67,7 +67,7 @@ int main(int argc, char *argv[])
if (argc > 4) { if (argc > 4) {
scppath = argv[4]; scppath = argv[4];
} }
/* Ultra basic "connect to port 22 on localhost" /* Ultra basic "connect to port 22 on localhost"
* Your code is responsible for creating the socket establishing the * Your code is responsible for creating the socket establishing the
* connection * connection

View File

@@ -1,11 +1,11 @@
/* /*
* $Id: scp_nonblock.c,v 1.5 2007/06/08 13:33:08 jehousley Exp $ * $Id: scp_nonblock.c,v 1.11 2007/09/24 12:15:45 bagder Exp $
* *
* Sample showing how to do SCP transfers in a non-blocking manner. * Sample showing how to do SCP transfers in a non-blocking manner.
*/ */
#include "config.h"
#include <libssh2.h> #include <libssh2.h>
#include <libssh2_config.h>
#ifdef HAVE_WINSOCK2_H #ifdef HAVE_WINSOCK2_H
# include <winsock2.h> # include <winsock2.h>
@@ -40,19 +40,19 @@ int main(int argc, char *argv[])
const char *fingerprint; const char *fingerprint;
LIBSSH2_SESSION *session; LIBSSH2_SESSION *session;
LIBSSH2_CHANNEL *channel; LIBSSH2_CHANNEL *channel;
char *username=(char *)"username"; const char *username="username";
char *password=(char *)"password"; const char *password="password";
char *scppath=(char *)"/tmp/TEST"; const char *scppath="/tmp/TEST";
struct stat fileinfo; struct stat fileinfo;
int rc; int rc;
off_t got=0; off_t got=0;
#ifdef WIN32 #ifdef WIN32
WSADATA wsadata; WSADATA wsadata;
WSAStartup(WINSOCK_VERSION, &wsadata); WSAStartup(WINSOCK_VERSION, &wsadata);
#endif #endif
if (argc > 1) { if (argc > 1) {
hostaddr = inet_addr(argv[1]); hostaddr = inet_addr(argv[1]);
} else { } else {
@@ -67,13 +67,13 @@ int main(int argc, char *argv[])
if (argc > 4) { if (argc > 4) {
scppath = argv[4]; scppath = argv[4];
} }
/* Ultra basic "connect to port 22 on localhost" /* Ultra basic "connect to port 22 on localhost"
* Your code is responsible for creating the socket establishing the * Your code is responsible for creating the socket establishing the
* connection * connection
*/ */
sock = socket(AF_INET, SOCK_STREAM, 0); sock = socket(AF_INET, SOCK_STREAM, 0);
sin.sin_family = AF_INET; sin.sin_family = AF_INET;
sin.sin_port = htons(22); sin.sin_port = htons(22);
sin.sin_addr.s_addr = hostaddr; sin.sin_addr.s_addr = hostaddr;
@@ -81,7 +81,7 @@ int main(int argc, char *argv[])
fprintf(stderr, "failed to connect!\n"); fprintf(stderr, "failed to connect!\n");
return -1; return -1;
} }
/* We set the socket non-blocking. We do it after the connect just to /* We set the socket non-blocking. We do it after the connect just to
simplify the example code. */ simplify the example code. */
#ifdef F_SETFL #ifdef F_SETFL
@@ -91,15 +91,15 @@ int main(int argc, char *argv[])
#else #else
#error "add support for setting the socket non-blocking here" #error "add support for setting the socket non-blocking here"
#endif #endif
/* Create a session instance */ /* Create a session instance */
session = libssh2_session_init(); session = libssh2_session_init();
if (!session) if (!session)
return -1; return -1;
/* Since we have set non-blocking, tell libssh2 we are non-blocking */ /* Since we have set non-blocking, tell libssh2 we are non-blocking */
libssh2_session_set_blocking(session, 0); libssh2_session_set_blocking(session, 0);
/* ... start it up. This will trade welcome banners, exchange keys, /* ... start it up. This will trade welcome banners, exchange keys,
* and setup crypto, compression, and MAC layers * and setup crypto, compression, and MAC layers
*/ */
@@ -108,7 +108,7 @@ int main(int argc, char *argv[])
fprintf(stderr, "Failure establishing SSH session: %d\n", rc); fprintf(stderr, "Failure establishing SSH session: %d\n", rc);
return -1; return -1;
} }
/* At this point we havn't yet authenticated. The first thing to do /* At this point we havn't yet authenticated. The first thing to do
* is check the hostkey's fingerprint against our known hosts Your app * 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 * may have it hard coded, may go to a file, may present it to the
@@ -120,7 +120,7 @@ int main(int argc, char *argv[])
fprintf(stderr, "%02X ", (unsigned char)fingerprint[i]); fprintf(stderr, "%02X ", (unsigned char)fingerprint[i]);
} }
fprintf(stderr, "\n"); fprintf(stderr, "\n");
if (auth_pw) { if (auth_pw) {
/* We could authenticate via password */ /* We could authenticate via password */
while ((rc = libssh2_userauth_password(session, username, password)) == LIBSSH2_ERROR_EAGAIN); while ((rc = libssh2_userauth_password(session, username, password)) == LIBSSH2_ERROR_EAGAIN);
@@ -139,33 +139,36 @@ int main(int argc, char *argv[])
goto shutdown; goto shutdown;
} }
} }
/* Request a file via SCP */ /* Request a file via SCP */
fprintf(stderr, "libssh2_scp_recv()!\n"); fprintf(stderr, "libssh2_scp_recv()!\n");
do { do {
channel = libssh2_scp_recv(session, scppath, &fileinfo); channel = libssh2_scp_recv(session, scppath, &fileinfo);
if ((!channel) && (libssh2_session_last_errno(session) != LIBSSH2_ERROR_EAGAIN)) { if ((!channel) && (libssh2_session_last_errno(session) != LIBSSH2_ERROR_EAGAIN)) {
fprintf(stderr, "Unable to open a session\n"); char *err_msg;
libssh2_session_last_error(session, &err_msg, NULL, 0);
fprintf(stderr, "%s\n", err_msg);
goto shutdown; goto shutdown;
} }
} while (!channel); } while (!channel);
fprintf(stderr, "libssh2_scp_recv() is done, now receive data!\n"); fprintf(stderr, "libssh2_scp_recv() is done, now receive data!\n");
while(got < fileinfo.st_size) { while(got < fileinfo.st_size) {
char mem[1000]; char mem[1000];
struct timeval timeout; struct timeval timeout;
int rc; int rc;
fd_set fd; fd_set fd;
do { do {
int amount=sizeof(mem); int amount=sizeof(mem);
if ((fileinfo.st_size -got) < amount) { if ((fileinfo.st_size -got) < amount) {
amount = fileinfo.st_size - got; amount = fileinfo.st_size - got;
} }
/* loop until we block */ /* loop until we block */
rc = libssh2_channel_read(channel, mem, amount); rc = libssh2_channel_read(channel, mem, amount);
if (rc > 0) { if (rc > 0) {
@@ -173,18 +176,18 @@ int main(int argc, char *argv[])
got += rc; got += rc;
} }
} while (rc > 0); } while (rc > 0);
if (rc == LIBSSH2_ERROR_EAGAIN) { if (rc == LIBSSH2_ERROR_EAGAIN) {
/* this is due to blocking that would occur otherwise /* this is due to blocking that would occur otherwise
so we loop on this condition */ so we loop on this condition */
timeout.tv_sec = 10; timeout.tv_sec = 10;
timeout.tv_usec = 0; timeout.tv_usec = 0;
FD_ZERO(&fd); FD_ZERO(&fd);
FD_SET(sock, &fd); FD_SET(sock, &fd);
rc = select(sock+1, &fd, &fd, NULL, &timeout); rc = select(sock+1, &fd, &fd, NULL, &timeout);
if (rc <= 0) { if (rc <= 0) {
/* negative is error /* negative is error
@@ -195,15 +198,15 @@ int main(int argc, char *argv[])
} }
break; break;
} }
libssh2_channel_free(channel); libssh2_channel_free(channel);
channel = NULL; channel = NULL;
shutdown: shutdown:
libssh2_session_disconnect(session, "Normal Shutdown, Thank you for playing"); libssh2_session_disconnect(session, "Normal Shutdown, Thank you for playing");
libssh2_session_free(session); libssh2_session_free(session);
#ifdef WIN32 #ifdef WIN32
Sleep(1000); Sleep(1000);
closesocket(sock); closesocket(sock);

View File

@@ -1,11 +1,11 @@
/* /*
* $Id: scp_write.c,v 1.1 2007/06/06 12:34:08 jehousley Exp $ * $Id: scp_write.c,v 1.5 2007/08/09 01:10:11 dfandrich Exp $
* *
* Sample showing how to do a simple SCP transfer. * Sample showing how to do a simple SCP transfer.
*/ */
#include "config.h"
#include <libssh2.h> #include <libssh2.h>
#include <libssh2_config.h>
#ifdef HAVE_WINSOCK2_H #ifdef HAVE_WINSOCK2_H
# include <winsock2.h> # include <winsock2.h>
@@ -40,10 +40,10 @@ int main(int argc, char *argv[])
const char *fingerprint; const char *fingerprint;
LIBSSH2_SESSION *session; LIBSSH2_SESSION *session;
LIBSSH2_CHANNEL *channel; LIBSSH2_CHANNEL *channel;
char *username=(char *)"username"; const char *username="username";
char *password=(char *)"password"; const char *password="password";
char *loclfile=(char *)"scp_write.c"; const char *loclfile="scp_write.c";
char *scppath=(char *)"/tmp/TEST"; const char *scppath="/tmp/TEST";
FILE *local; FILE *local;
int rc; int rc;
char mem[1024]; char mem[1024];
@@ -74,15 +74,15 @@ int main(int argc, char *argv[])
if (argc > 5) { if (argc > 5) {
scppath = argv[5]; scppath = argv[5];
} }
local = fopen(loclfile, "rb"); local = fopen(loclfile, "rb");
if (!local) { if (!local) {
fprintf(stderr, "Can't local file %s\n", loclfile); fprintf(stderr, "Can't local file %s\n", loclfile);
goto shutdown; goto shutdown;
} }
stat(loclfile, &fileinfo); stat(loclfile, &fileinfo);
/* Ultra basic "connect to port 22 on localhost" /* Ultra basic "connect to port 22 on localhost"
* Your code is responsible for creating the socket establishing the * Your code is responsible for creating the socket establishing the
* connection * connection
@@ -142,10 +142,9 @@ int main(int argc, char *argv[])
} }
} }
//libssh2_trace(session, 0xFFFF);
/* Request a file via SCP */ /* Request a file via SCP */
channel = libssh2_scp_send(session, scppath, 0x1FF & fileinfo.st_mode, (unsigned long)fileinfo.st_size); channel = libssh2_scp_send(session, scppath, 0x1FF & fileinfo.st_mode,
(unsigned long)fileinfo.st_size);
if (!channel) { if (!channel) {
fprintf(stderr, "Unable to open a session\n"); fprintf(stderr, "Unable to open a session\n");
@@ -160,7 +159,7 @@ int main(int argc, char *argv[])
break; break;
} }
ptr = mem; ptr = mem;
do { do {
/* write data in a loop until we block */ /* write data in a loop until we block */
rc = libssh2_channel_write(channel, ptr, nread); rc = libssh2_channel_write(channel, ptr, nread);
@@ -171,16 +170,13 @@ int main(int argc, char *argv[])
fprintf(stderr, "Sending EOF\n"); fprintf(stderr, "Sending EOF\n");
libssh2_channel_send_eof(channel); libssh2_channel_send_eof(channel);
fprintf(stderr, "Waiting for EOF\n"); fprintf(stderr, "Waiting for EOF\n");
libssh2_channel_wait_eof(channel); libssh2_channel_wait_eof(channel);
fprintf(stderr, "Waiting for channel to close\n"); fprintf(stderr, "Waiting for channel to close\n");
libssh2_channel_wait_closed(channel); libssh2_channel_wait_closed(channel);
// fprintf(stderr, "Closing channel\n");
// libssh2_channel_close(channel);
libssh2_channel_free(channel); libssh2_channel_free(channel);
channel = NULL; channel = NULL;

View File

@@ -1,11 +1,12 @@
/* /*
* $Id: scp_write_nonblock.c,v 1.2 2007/06/08 13:33:08 jehousley Exp $ * $Id: scp_write_nonblock.c,v 1.7 2007/08/09 01:10:11 dfandrich Exp $
* *
* Sample showing how to do a simple SCP transfer. * Sample showing how to do a simple SCP transfer.
*/ */
#include "config.h"
#include <libssh2.h> #include <libssh2.h>
#include <libssh2_config.h>
#ifdef HAVE_WINSOCK2_H #ifdef HAVE_WINSOCK2_H
# include <winsock2.h> # include <winsock2.h>
@@ -40,10 +41,10 @@ int main(int argc, char *argv[])
const char *fingerprint; const char *fingerprint;
LIBSSH2_SESSION *session; LIBSSH2_SESSION *session;
LIBSSH2_CHANNEL *channel; LIBSSH2_CHANNEL *channel;
char *username=(char *)"username"; const char *username="username";
char *password=(char *)"password"; const char *password="password";
char *loclfile=(char *)"scp_write.c"; const char *loclfile="scp_write.c";
char *scppath=(char *)"/tmp/TEST"; const char *scppath="/tmp/TEST";
FILE *local; FILE *local;
int rc; int rc;
char mem[1024]; char mem[1024];
@@ -74,15 +75,15 @@ int main(int argc, char *argv[])
if (argc > 5) { if (argc > 5) {
scppath = argv[5]; scppath = argv[5];
} }
local = fopen(loclfile, "rb"); local = fopen(loclfile, "rb");
if (!local) { if (!local) {
fprintf(stderr, "Can't local file %s\n", loclfile); fprintf(stderr, "Can't local file %s\n", loclfile);
goto shutdown; goto shutdown;
} }
stat(loclfile, &fileinfo); stat(loclfile, &fileinfo);
/* Ultra basic "connect to port 22 on localhost" /* Ultra basic "connect to port 22 on localhost"
* Your code is responsible for creating the socket establishing the * Your code is responsible for creating the socket establishing the
* connection * connection
@@ -107,7 +108,7 @@ int main(int argc, char *argv[])
#else #else
#error "add support for setting the socket non-blocking here" #error "add support for setting the socket non-blocking here"
#endif #endif
/* Create a session instance /* Create a session instance
*/ */
session = libssh2_session_init(); session = libssh2_session_init();
@@ -116,11 +117,11 @@ int main(int argc, char *argv[])
/* Since we have set non-blocking, tell libssh2 we are non-blocking */ /* Since we have set non-blocking, tell libssh2 we are non-blocking */
libssh2_session_set_blocking(session, 0); libssh2_session_set_blocking(session, 0);
/* ... start it up. This will trade welcome banners, exchange keys, /* ... start it up. This will trade welcome banners, exchange keys,
* and setup crypto, compression, and MAC layers * and setup crypto, compression, and MAC layers
*/ */
while ((rc = libssh2_session_startup(session, sock)) while ((rc = libssh2_session_startup(session, sock))
== LIBSSH2_ERROR_EAGAIN); == LIBSSH2_ERROR_EAGAIN);
if(rc) { if(rc) {
fprintf(stderr, "Failure establishing SSH session: %d\n", rc); fprintf(stderr, "Failure establishing SSH session: %d\n", rc);
@@ -141,7 +142,8 @@ int main(int argc, char *argv[])
if (auth_pw) { if (auth_pw) {
/* We could authenticate via password */ /* We could authenticate via password */
while ((rc = libssh2_userauth_password(session, username, password)) == LIBSSH2_ERROR_EAGAIN); while ((rc = libssh2_userauth_password(session, username, password)) ==
LIBSSH2_ERROR_EAGAIN);
if (rc) { if (rc) {
fprintf(stderr, "Authentication by password failed.\n"); fprintf(stderr, "Authentication by password failed.\n");
goto shutdown; goto shutdown;
@@ -158,14 +160,17 @@ int main(int argc, char *argv[])
} }
} }
// libssh2_trace(session, 0xFF7D);
/* Request a file via SCP */ /* Request a file via SCP */
do { do {
channel = libssh2_scp_send(session, scppath, 0x1FF & fileinfo.st_mode, (unsigned long)fileinfo.st_size); channel = libssh2_scp_send(session, scppath, 0x1FF & fileinfo.st_mode,
(unsigned long)fileinfo.st_size);
if ((!channel) && (libssh2_session_last_errno(session) != LIBSSH2_ERROR_EAGAIN)) {
fprintf(stderr, "Unable to open a session\n"); if ((!channel) && (libssh2_session_last_errno(session) !=
LIBSSH2_ERROR_EAGAIN)) {
char *err_msg;
libssh2_session_last_error(session, &err_msg, NULL, 0);
fprintf(stderr, "%s\n", err_msg);
goto shutdown; goto shutdown;
} }
} while (!channel); } while (!channel);
@@ -178,10 +183,11 @@ int main(int argc, char *argv[])
break; break;
} }
ptr = mem; ptr = mem;
do { do {
/* write data in a loop until we block */ /* write data in a loop until we block */
while ((rc = libssh2_channel_write(channel, ptr, nread)) == LIBSSH2_ERROR_EAGAIN); while ((rc = libssh2_channel_write(channel, ptr, nread)) ==
LIBSSH2_ERROR_EAGAIN);
if (rc < 0) { if (rc < 0) {
fprintf(stderr, "ERROR %d\n", rc); fprintf(stderr, "ERROR %d\n", rc);
} }
@@ -192,22 +198,20 @@ int main(int argc, char *argv[])
fprintf(stderr, "Sending EOF\n"); fprintf(stderr, "Sending EOF\n");
while (libssh2_channel_send_eof(channel) == LIBSSH2_ERROR_EAGAIN); while (libssh2_channel_send_eof(channel) == LIBSSH2_ERROR_EAGAIN);
fprintf(stderr, "Waiting for EOF\n"); fprintf(stderr, "Waiting for EOF\n");
while (libssh2_channel_wait_eof(channel) == LIBSSH2_ERROR_EAGAIN); while (libssh2_channel_wait_eof(channel) == LIBSSH2_ERROR_EAGAIN);
fprintf(stderr, "Waiting for channel to close\n"); fprintf(stderr, "Waiting for channel to close\n");
while (libssh2_channel_wait_closed(channel) == LIBSSH2_ERROR_EAGAIN); while (libssh2_channel_wait_closed(channel) == LIBSSH2_ERROR_EAGAIN);
// fprintf(stderr, "Closing channel\n");
// while (libssh2_channel_close(channel) == LIBSSH2_ERROR_EAGAIN);
libssh2_channel_free(channel); libssh2_channel_free(channel);
channel = NULL; channel = NULL;
shutdown: shutdown:
while ((rc = libssh2_session_disconnect(session, "Normal Shutdown, Thank you for playing")) == LIBSSH2_ERROR_EAGAIN); while ((rc = libssh2_session_disconnect(session,
"Normal Shutdown, Thank you for playing")) == LIBSSH2_ERROR_EAGAIN);
libssh2_session_free(session); libssh2_session_free(session);
#ifdef WIN32 #ifdef WIN32

View File

@@ -1,17 +1,17 @@
/* /*
* $Id: sftp.c,v 1.8 2007/06/06 12:34:08 jehousley Exp $ * $Id: sftp.c,v 1.14 2007/09/24 12:14:18 bagder Exp $
* *
* Sample showing how to do SFTP transfers. * Sample showing how to do SFTP transfers.
* *
* The sample code has default values for host name, user name, password * The sample code has default values for host name, user name, password
* and path to copy, but you can specify them on the command line like: * and path to copy, but you can specify them on the command line like:
* *
* "sftp 192.168.0.1 user password /tmp/secrets" * "sftp 192.168.0.1 user password /tmp/secrets -p|-i|-k"
*/ */
#include "config.h"
#include <libssh2.h> #include <libssh2.h>
#include <libssh2_sftp.h> #include <libssh2_sftp.h>
#include <libssh2_config.h>
#ifdef HAVE_WINSOCK2_H #ifdef HAVE_WINSOCK2_H
# include <winsock2.h> # include <winsock2.h>
@@ -38,155 +38,216 @@
#include <stdio.h> #include <stdio.h>
#include <ctype.h> #include <ctype.h>
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,
const char *instruction, int instruction_len, int num_prompts,
const LIBSSH2_USERAUTH_KBDINT_PROMPT *prompts,
LIBSSH2_USERAUTH_KBDINT_RESPONSE *responses,
void **abstract)
{
(void)name;
(void)name_len;
(void)instruction;
(void)instruction_len;
if (num_prompts == 1) {
responses[0].text = strdup(password);
responses[0].length = strlen(password);
}
(void)prompts;
(void)abstract;
} /* kbd_callback */
int main(int argc, char *argv[]) int main(int argc, char *argv[])
{ {
unsigned long hostaddr; unsigned long hostaddr;
int sock, i, auth_pw = 1; int sock, i, auth_pw = 0;
struct sockaddr_in sin; struct sockaddr_in sin;
const char *fingerprint; const char *fingerprint;
LIBSSH2_SESSION *session; char *userauthlist;
char *username=(char *)"username"; LIBSSH2_SESSION *session;
char *password=(char *)"password"; int rc;
char *sftppath=(char *)"/tmp/TEST"; LIBSSH2_SFTP *sftp_session;
int rc; LIBSSH2_SFTP_HANDLE *sftp_handle;
LIBSSH2_SFTP *sftp_session;
LIBSSH2_SFTP_HANDLE *sftp_handle;
#ifdef WIN32 #ifdef WIN32
WSADATA wsadata; WSADATA wsadata;
WSAStartup(WINSOCK_VERSION, &wsadata); WSAStartup(WINSOCK_VERSION, &wsadata);
#endif #endif
if (argc > 1) { if (argc > 1) {
hostaddr = inet_addr(argv[1]); hostaddr = inet_addr(argv[1]);
} else { } else {
hostaddr = htonl(0x7F000001); hostaddr = htonl(0x7F000001);
} }
if(argc > 2) { if(argc > 2) {
username = argv[2]; username = argv[2];
} }
if(argc > 3) { if(argc > 3) {
password = argv[3]; password = argv[3];
} }
if(argc > 4) { if(argc > 4) {
sftppath = argv[4]; sftppath = argv[4];
} }
/* /*
* The application code is responsible for creating the socket * The application code is responsible for creating the socket
* and establishing the connection * and establishing the connection
*/ */
sock = socket(AF_INET, SOCK_STREAM, 0); sock = socket(AF_INET, SOCK_STREAM, 0);
sin.sin_family = AF_INET; sin.sin_family = AF_INET;
sin.sin_port = htons(22); sin.sin_port = htons(22);
sin.sin_addr.s_addr = hostaddr; sin.sin_addr.s_addr = hostaddr;
if (connect(sock, (struct sockaddr*)(&sin), if (connect(sock, (struct sockaddr*)(&sin),
sizeof(struct sockaddr_in)) != 0) { sizeof(struct sockaddr_in)) != 0) {
fprintf(stderr, "failed to connect!\n"); fprintf(stderr, "failed to connect!\n");
return -1; return -1;
} }
/* Create a session instance /* Create a session instance
*/ */
session = libssh2_session_init(); session = libssh2_session_init();
if(!session) if(!session)
return -1; return -1;
/* Since we have set non-blocking, tell libssh2 we are blocking */ /* Since we have set non-blocking, tell libssh2 we are blocking */
libssh2_session_set_blocking(session, 1); libssh2_session_set_blocking(session, 1);
/* ... start it up. This will trade welcome banners, exchange keys,
* and setup crypto, compression, and MAC layers
*/
rc = libssh2_session_startup(session, sock);
if(rc) {
fprintf(stderr, "Failure establishing SSH session: %d\n", rc);
return -1;
}
/* Since we have not set non-blocking, tell libssh2 we are blocking */ /* ... start it up. This will trade welcome banners, exchange keys,
libssh2_session_set_blocking(session, 1); * and setup crypto, compression, and MAC layers
*/
rc = libssh2_session_startup(session, sock);
if(rc) {
fprintf(stderr, "Failure establishing SSH session: %d\n", rc);
return -1;
}
/* At this point we havn't yet authenticated. The first thing to do /* Since we have not set non-blocking, tell libssh2 we are blocking */
* is check the hostkey's fingerprint against our known hosts Your app libssh2_session_set_blocking(session, 1);
* 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);
fprintf(stderr, "Fingerprint: ");
for(i = 0; i < 16; i++) {
fprintf(stderr, "%02X ", (unsigned char)fingerprint[i]);
}
fprintf(stderr, "\n");
if (auth_pw) { /* At this point we havn't yet authenticated. The first thing to do
/* We could authenticate via password */ * is check the hostkey's fingerprint against our known hosts Your app
if (libssh2_userauth_password(session, username, password)) { * may have it hard coded, may go to a file, may present it to the
fprintf(stderr, "Authentication by password failed.\n"); * user, that's your call
goto shutdown; */
} fingerprint = libssh2_hostkey_hash(session, LIBSSH2_HOSTKEY_HASH_MD5);
} else { fprintf(stderr, "Fingerprint: ");
/* Or by public key */ for(i = 0; i < 16; i++) {
if (libssh2_userauth_publickey_fromfile(session, username, fprintf(stderr, "%02X ", (unsigned char)fingerprint[i]);
"/home/username/.ssh/id_rsa.pub", }
"/home/username/.ssh/id_rsa", fprintf(stderr, "\n");
password)) {
fprintf(stderr, "\tAuthentication by public key failed\n");
goto shutdown;
}
}
fprintf(stderr, "libssh2_sftp_init()!\n"); /* check what authentication methods are available */
sftp_session = libssh2_sftp_init(session); 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 (!sftp_session) { /* if we got an 4. argument we set this option if supported */
fprintf(stderr, "Unable to init SFTP session\n"); if(argc > 5) {
goto shutdown; if ((auth_pw & 1) && !strcasecmp(argv[5], "-p")) {
} auth_pw = 1;
/* Since we have not set non-blocking, tell libssh2 we are blocking */
libssh2_session_set_blocking(session, 1);
fprintf(stderr, "libssh2_sftp_open()!\n");
/* Request a file via SFTP */
sftp_handle =
libssh2_sftp_open(sftp_session, sftppath, LIBSSH2_FXF_READ, 0);
if (!sftp_handle) {
fprintf(stderr, "Unable to open file with SFTP\n");
goto shutdown;
}
fprintf(stderr, "libssh2_sftp_open() is done, now receive data!\n");
do {
char mem[1024];
/* loop until we fail */
fprintf(stderr, "libssh2_sftp_read()!\n");
rc = libssh2_sftp_read(sftp_handle, mem, sizeof(mem));
if (rc > 0) {
write(1, mem, rc);
} else {
break;
} }
} while (1); if ((auth_pw & 2) && !strcasecmp(argv[5], "-i")) {
auth_pw = 2;
}
if ((auth_pw & 4) && !strcasecmp(argv[5], "-k")) {
auth_pw = 4;
}
}
libssh2_sftp_close(sftp_handle); if (auth_pw & 1) {
libssh2_sftp_shutdown(sftp_session); /* We could authenticate via password */
if (libssh2_userauth_password(session, username, password)) {
fprintf(stderr, "Authentication by password failed.\n");
goto shutdown;
}
} else if (auth_pw & 2) {
/* Or via keyboard-interactive */
if (libssh2_userauth_keyboard_interactive(session, username, &kbd_callback) ) {
printf("\tAuthentication by keyboard-interactive failed!\n");
goto shutdown;
} else {
printf("\tAuthentication by keyboard-interactive succeeded.\n");
}
} else if (auth_pw & 4) {
/* Or by public key */
if (libssh2_userauth_publickey_fromfile(session, username, keyfile1, keyfile2, password)) {
printf("\tAuthentication by public key failed!\n");
goto shutdown;
} else {
printf("\tAuthentication by public key succeeded.\n");
}
} else {
printf("No supported authentication methods found!\n");
goto shutdown;
}
shutdown: fprintf(stderr, "libssh2_sftp_init()!\n");
sftp_session = libssh2_sftp_init(session);
libssh2_session_disconnect(session, "Normal Shutdown, Thank you for playing"); if (!sftp_session) {
libssh2_session_free(session); fprintf(stderr, "Unable to init SFTP session\n");
goto shutdown;
}
/* Since we have not set non-blocking, tell libssh2 we are blocking */
libssh2_session_set_blocking(session, 1);
fprintf(stderr, "libssh2_sftp_open()!\n");
/* Request a file via SFTP */
sftp_handle =
libssh2_sftp_open(sftp_session, sftppath, LIBSSH2_FXF_READ, 0);
if (!sftp_handle) {
fprintf(stderr, "Unable to open file with SFTP\n");
goto shutdown;
}
fprintf(stderr, "libssh2_sftp_open() is done, now receive data!\n");
do {
char mem[1024];
/* loop until we fail */
fprintf(stderr, "libssh2_sftp_read()!\n");
rc = libssh2_sftp_read(sftp_handle, mem, sizeof(mem));
if (rc > 0) {
write(1, mem, rc);
} else {
break;
}
} while (1);
libssh2_sftp_close(sftp_handle);
libssh2_sftp_shutdown(sftp_session);
shutdown:
libssh2_session_disconnect(session, "Normal Shutdown, Thank you for playing");
libssh2_session_free(session);
#ifdef WIN32 #ifdef WIN32
Sleep(1000); Sleep(1000);
closesocket(sock); closesocket(sock);
#else #else
sleep(1); sleep(1);
close(sock); close(sock);
#endif #endif
fprintf(stderr, "all done\n"); fprintf(stderr, "all done\n");
return 0; return 0;
} }

View File

@@ -1,5 +1,5 @@
/* /*
* $Id: sftp_RW_nonblock.c,v 1.7 2007/06/08 13:33:08 jehousley Exp $ * $Id: sftp_RW_nonblock.c,v 1.10 2007/08/09 01:10:11 dfandrich Exp $
* *
* Sample showing how to do SFTP transfers in a non-blocking manner. * Sample showing how to do SFTP transfers in a non-blocking manner.
* *
@@ -9,9 +9,9 @@
* Using the SFTP server running on 127.0.0.1 * Using the SFTP server running on 127.0.0.1
*/ */
#include "config.h"
#include <libssh2.h> #include <libssh2.h>
#include <libssh2_sftp.h> #include <libssh2_sftp.h>
#include <libssh2_config.h>
#ifdef HAVE_WINSOCK2_H #ifdef HAVE_WINSOCK2_H
# include <winsock2.h> # include <winsock2.h>
@@ -44,251 +44,251 @@
int main(int argc, char *argv[]) int main(int argc, char *argv[])
{ {
int sock, i, auth_pw = 1; int sock, i, auth_pw = 1;
struct sockaddr_in sin; struct sockaddr_in sin;
const char *fingerprint; const char *fingerprint;
LIBSSH2_SESSION *session; LIBSSH2_SESSION *session;
char *username=(char *)"username"; const char *username="username";
char *password=(char *)"password"; const char *password="password";
char *sftppath=(char *)"/tmp/TEST"; /* source path */ const char *sftppath="/tmp/TEST"; /* source path */
char *dest=(char *)"/tmp/TEST2"; /* destination path */ const char *dest="/tmp/TEST2"; /* destination path */
int rc; int rc;
LIBSSH2_SFTP *sftp_session; LIBSSH2_SFTP *sftp_session;
LIBSSH2_SFTP_HANDLE *sftp_handle; LIBSSH2_SFTP_HANDLE *sftp_handle;
FILE *tempstorage; FILE *tempstorage;
char mem[1000]; char mem[1000];
struct timeval timeout; struct timeval timeout;
fd_set fd; fd_set fd;
#ifdef WIN32 #ifdef WIN32
WSADATA wsadata; WSADATA wsadata;
WSAStartup(WINSOCK_VERSION, &wsadata); WSAStartup(WINSOCK_VERSION, &wsadata);
#endif #endif
/* Ultra basic "connect to port 22 on localhost" /* Ultra basic "connect to port 22 on localhost"
* The application is responsible for creating the socket establishing * The application is responsible for creating the socket establishing
* the connection * the connection
*/ */
sock = socket(AF_INET, SOCK_STREAM, 0); sock = socket(AF_INET, SOCK_STREAM, 0);
sin.sin_family = AF_INET; sin.sin_family = AF_INET;
sin.sin_port = htons(22); sin.sin_port = htons(22);
sin.sin_addr.s_addr = htonl(0x7F000001); sin.sin_addr.s_addr = htonl(0x7F000001);
if (connect(sock, (struct sockaddr*)(&sin), if (connect(sock, (struct sockaddr*)(&sin),
sizeof(struct sockaddr_in)) != 0) { sizeof(struct sockaddr_in)) != 0) {
fprintf(stderr, "failed to connect!\n"); fprintf(stderr, "failed to connect!\n");
return -1; return -1;
} }
/* We set the socket non-blocking. We do it after the connect just to /* We set the socket non-blocking. We do it after the connect just to
simplify the example code. */ simplify the example code. */
#ifdef F_SETFL #ifdef F_SETFL
/* FIXME: this can/should be done in a more portable manner */ /* FIXME: this can/should be done in a more portable manner */
rc = fcntl(sock, F_GETFL, 0); rc = fcntl(sock, F_GETFL, 0);
fcntl(sock, F_SETFL, rc | O_NONBLOCK); fcntl(sock, F_SETFL, rc | O_NONBLOCK);
#else #else
#error "add support for setting the socket non-blocking here" #error "add support for setting the socket non-blocking here"
#endif #endif
/* Create a session instance /* Create a session instance
*/ */
session = libssh2_session_init(); session = libssh2_session_init();
if(!session) if(!session)
return -1; return -1;
/* ... start it up. This will trade welcome banners, exchange keys, /* ... start it up. This will trade welcome banners, exchange keys,
* and setup crypto, compression, and MAC layers * and setup crypto, compression, and MAC layers
*/ */
rc = libssh2_session_startup(session, sock); rc = libssh2_session_startup(session, sock);
if(rc) { if(rc) {
fprintf(stderr, "Failure establishing SSH session: %d\n", rc); fprintf(stderr, "Failure establishing SSH session: %d\n", rc);
return -1; return -1;
} }
libssh2_session_set_blocking(session, 0); libssh2_session_set_blocking(session, 0);
/* At this point we havn't yet authenticated. The first thing to do /* At this point we havn't yet authenticated. The first thing to do
* is check the hostkey's fingerprint against our known hosts Your app * 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 * may have it hard coded, may go to a file, may present it to the
* user, that's your call * user, that's your call
*/ */
fingerprint = libssh2_hostkey_hash(session, LIBSSH2_HOSTKEY_HASH_MD5); fingerprint = libssh2_hostkey_hash(session, LIBSSH2_HOSTKEY_HASH_MD5);
printf("Fingerprint: "); printf("Fingerprint: ");
for(i = 0; i < 16; i++) { for(i = 0; i < 16; i++) {
printf("%02X ", (unsigned char)fingerprint[i]); printf("%02X ", (unsigned char)fingerprint[i]);
} }
printf("\n"); printf("\n");
if(argc > 1) { if(argc > 1) {
username = argv[1]; username = argv[1];
} }
if(argc > 2) { if(argc > 2) {
password = argv[2]; password = argv[2];
} }
if(argc > 3) { if(argc > 3) {
sftppath = argv[3]; sftppath = argv[3];
} }
if(argc > 4) { if(argc > 4) {
dest = argv[4]; dest = argv[4];
} }
tempstorage = fopen(STORAGE, "wb"); tempstorage = fopen(STORAGE, "wb");
if(!tempstorage) { if(!tempstorage) {
printf("Can't open temp storage file %s\n", STORAGE); printf("Can't open temp storage file %s\n", STORAGE);
goto shutdown; goto shutdown;
}
if (auth_pw) {
/* We could authenticate via password */
if (libssh2_userauth_password(session, username, password)) {
printf("Authentication by password failed.\n");
goto shutdown;
} }
} else {
if (auth_pw) { /* Or by public key */
/* We could authenticate via password */ if (libssh2_userauth_publickey_fromfile(session, username,
if (libssh2_userauth_password(session, username, password)) { "/home/username/.ssh/id_rsa.pub",
printf("Authentication by password failed.\n"); "/home/username/.ssh/id_rsa",
goto shutdown; password)) {
} printf("\tAuthentication by public key failed\n");
} else { goto shutdown;
/* Or by public key */
if (libssh2_userauth_publickey_fromfile(session, username,
"/home/username/.ssh/id_rsa.pub",
"/home/username/.ssh/id_rsa",
password)) {
printf("\tAuthentication by public key failed\n");
goto shutdown;
}
} }
}
sftp_session = libssh2_sftp_init(session); sftp_session = libssh2_sftp_init(session);
if (!sftp_session) { if (!sftp_session) {
fprintf(stderr, "Unable to init SFTP session\n"); fprintf(stderr, "Unable to init SFTP session\n");
goto shutdown; goto shutdown;
} }
/* Request a file via SFTP */ /* Request a file via SFTP */
sftp_handle = sftp_handle =
libssh2_sftp_open(sftp_session, sftppath, LIBSSH2_FXF_READ, 0); libssh2_sftp_open(sftp_session, sftppath, LIBSSH2_FXF_READ, 0);
if (!sftp_handle) { if (!sftp_handle) {
fprintf(stderr, "Unable to open file with SFTP\n"); fprintf(stderr, "Unable to open file with SFTP\n");
goto shutdown; goto shutdown;
} }
fprintf(stderr, "libssh2_sftp_open() is done, now receive data!\n"); fprintf(stderr, "libssh2_sftp_open() is done, now receive data!\n");
do {
do { do {
do { /* read in a loop until we block */
/* read in a loop until we block */ rc = libssh2_sftp_read(sftp_handle, mem, sizeof(mem));
rc = libssh2_sftp_read(sftp_handle, mem, sizeof(mem)); fprintf(stderr, "libssh2_sftp_read returned %d\n",
fprintf(stderr, "libssh2_sftp_read returned %d\n", rc);
rc);
if(rc > 0) { if(rc > 0) {
/* write to stderr */ /* write to stderr */
write(2, mem, rc); write(2, mem, rc);
/* write to temporary storage area */ /* write to temporary storage area */
fwrite(mem, rc, 1, tempstorage); fwrite(mem, rc, 1, tempstorage);
} }
} while (rc > 0); } while (rc > 0);
if(rc != LIBSSH2_ERROR_EAGAIN) { if(rc != LIBSSH2_ERROR_EAGAIN) {
/* error or end of file */ /* error or end of file */
break; break;
} }
timeout.tv_sec = 10; timeout.tv_sec = 10;
timeout.tv_usec = 0; timeout.tv_usec = 0;
FD_ZERO(&fd); FD_ZERO(&fd);
FD_SET(sock, &fd); FD_SET(sock, &fd);
/* wait for readable or writeable */ /* wait for readable or writeable */
rc = select(sock+1, &fd, &fd, NULL, &timeout); rc = select(sock+1, &fd, &fd, NULL, &timeout);
if(rc <= 0) { if(rc <= 0) {
/* negative is error /* negative is error
0 is timeout */ 0 is timeout */
fprintf(stderr, "SFTP download timed out: %d\n", rc); fprintf(stderr, "SFTP download timed out: %d\n", rc);
break; break;
} }
} while (1);
libssh2_sftp_close(sftp_handle);
fclose(tempstorage);
tempstorage = fopen(STORAGE, "rb");
if(!tempstorage) {
/* weird, we can't read the file we just wrote to... */
fprintf(stderr, "can't open %s for reading\n", STORAGE);
goto shutdown;
}
/* we're done downloading, now reverse the process and upload the
temporarily stored data to the destination path */
sftp_handle =
libssh2_sftp_open(sftp_session, dest,
LIBSSH2_FXF_WRITE|LIBSSH2_FXF_CREAT,
LIBSSH2_SFTP_S_IRUSR|LIBSSH2_SFTP_S_IWUSR|
LIBSSH2_SFTP_S_IRGRP|LIBSSH2_SFTP_S_IROTH);
if(sftp_handle) {
size_t nread;
char *ptr;
do {
nread = fread(mem, 1, sizeof(mem), tempstorage);
if(nread <= 0) {
/* end of file */
break;
}
ptr = mem;
do {
/* write data in a loop until we block */
rc = libssh2_sftp_write(sftp_handle, ptr,
nread);
ptr += rc;
nread -= nread;
} while (rc > 0);
if(rc != LIBSSH2_ERROR_EAGAIN) {
/* error or end of file */
break;
}
timeout.tv_sec = 10;
timeout.tv_usec = 0;
FD_ZERO(&fd);
FD_SET(sock, &fd);
/* wait for readable or writeable */
rc = select(sock+1, &fd, &fd, NULL, &timeout);
if(rc <= 0) {
/* negative is error
0 is timeout */
fprintf(stderr, "SFTP upload timed out: %d\n",
rc);
break;
}
} while (1); } while (1);
fprintf(stderr, "SFTP upload done!\n");
}
else {
fprintf(stderr, "SFTP failed to open destination path: %s\n",
dest);
}
libssh2_sftp_close(sftp_handle); libssh2_sftp_shutdown(sftp_session);
fclose(tempstorage);
tempstorage = fopen(STORAGE, "rb"); shutdown:
if(!tempstorage) {
/* weird, we can't read the file we just wrote to... */
fprintf(stderr, "can't open %s for reading\n", STORAGE);
goto shutdown;
}
/* we're done downloading, now reverse the process and upload the libssh2_session_disconnect(session, "Normal Shutdown, Thank you for playing");
temporarily stored data to the destination path */ libssh2_session_free(session);
sftp_handle =
libssh2_sftp_open(sftp_session, dest,
LIBSSH2_FXF_WRITE|LIBSSH2_FXF_CREAT,
LIBSSH2_SFTP_S_IRUSR|LIBSSH2_SFTP_S_IWUSR|
LIBSSH2_SFTP_S_IRGRP|LIBSSH2_SFTP_S_IROTH);
if(sftp_handle) {
size_t nread;
char *ptr;
do {
nread = fread(mem, 1, sizeof(mem), tempstorage);
if(nread <= 0) {
/* end of file */
break;
}
ptr = mem;
do {
/* write data in a loop until we block */
rc = libssh2_sftp_write(sftp_handle, ptr,
nread);
ptr += rc;
nread -= nread;
} while (rc > 0);
if(rc != LIBSSH2_ERROR_EAGAIN) {
/* error or end of file */
break;
}
timeout.tv_sec = 10;
timeout.tv_usec = 0;
FD_ZERO(&fd);
FD_SET(sock, &fd);
/* wait for readable or writeable */
rc = select(sock+1, &fd, &fd, NULL, &timeout);
if(rc <= 0) {
/* negative is error
0 is timeout */
fprintf(stderr, "SFTP upload timed out: %d\n",
rc);
break;
}
} while (1);
fprintf(stderr, "SFTP upload done!\n");
}
else {
fprintf(stderr, "SFTP failed to open destination path: %s\n",
dest);
}
libssh2_sftp_shutdown(sftp_session);
shutdown:
libssh2_session_disconnect(session, "Normal Shutdown, Thank you for playing");
libssh2_session_free(session);
#ifdef WIN32 #ifdef WIN32
Sleep(1000); Sleep(1000);
closesocket(sock); closesocket(sock);
#else #else
sleep(1); sleep(1);
close(sock); close(sock);
#endif #endif
printf("all done\n"); printf("all done\n");
return 0; return 0;
} }

View File

@@ -1,5 +1,5 @@
/* /*
* $Id: sftp_mkdir.c,v 1.4 2007/06/06 12:34:08 jehousley Exp $ * $Id: sftp_mkdir.c,v 1.7 2007/08/09 01:10:11 dfandrich Exp $
* *
* Sample showing how to do SFTP mkdir * Sample showing how to do SFTP mkdir
* *
@@ -9,9 +9,9 @@
* "sftp 192.168.0.1 user password /tmp/sftp_mkdir" * "sftp 192.168.0.1 user password /tmp/sftp_mkdir"
*/ */
#include "config.h"
#include <libssh2.h> #include <libssh2.h>
#include <libssh2_sftp.h> #include <libssh2_sftp.h>
#include <libssh2_config.h>
#ifdef HAVE_WINSOCK2_H #ifdef HAVE_WINSOCK2_H
# include <winsock2.h> # include <winsock2.h>
@@ -42,9 +42,9 @@ int main(int argc, char *argv[])
struct sockaddr_in sin; struct sockaddr_in sin;
const char *fingerprint; const char *fingerprint;
LIBSSH2_SESSION *session; LIBSSH2_SESSION *session;
char *username=(char *)"username"; const char *username="username";
char *password=(char *)"password"; const char *password="password";
char *sftppath=(char *)"/tmp/sftp_mkdir"; const char *sftppath="/tmp/sftp_mkdir";
int rc; int rc;
LIBSSH2_SFTP *sftp_session; LIBSSH2_SFTP *sftp_session;
@@ -69,7 +69,7 @@ int main(int argc, char *argv[])
if(argc > 4) { if(argc > 4) {
sftppath = argv[4]; sftppath = argv[4];
} }
/* /*
* The application code is responsible for creating the socket * The application code is responsible for creating the socket
* and establishing the connection * and establishing the connection
@@ -79,7 +79,7 @@ int main(int argc, char *argv[])
sin.sin_family = AF_INET; sin.sin_family = AF_INET;
sin.sin_port = htons(22); sin.sin_port = htons(22);
sin.sin_addr.s_addr = hostaddr; sin.sin_addr.s_addr = hostaddr;
if (connect(sock, (struct sockaddr*)(&sin), if (connect(sock, (struct sockaddr*)(&sin),
sizeof(struct sockaddr_in)) != 0) { sizeof(struct sockaddr_in)) != 0) {
fprintf(stderr, "failed to connect!\n"); fprintf(stderr, "failed to connect!\n");
return -1; return -1;
@@ -139,7 +139,7 @@ int main(int argc, char *argv[])
/* Since we have not set non-blocking, tell libssh2 we are blocking */ /* Since we have not set non-blocking, tell libssh2 we are blocking */
libssh2_session_set_blocking(session, 1); libssh2_session_set_blocking(session, 1);
fprintf(stderr, "libssh2_sftp_mkdir()!\n"); fprintf(stderr, "libssh2_sftp_mkdir()!\n");
/* Make a directory via SFTP */ /* Make a directory via SFTP */
rc = libssh2_sftp_mkdir(sftp_session, sftppath, rc = libssh2_sftp_mkdir(sftp_session, sftppath,

View File

@@ -1,5 +1,5 @@
/* /*
* $Id: sftp_mkdir_nonblock.c,v 1.6 2007/06/08 13:33:08 jehousley Exp $ * $Id: sftp_mkdir_nonblock.c,v 1.9 2007/08/09 01:10:11 dfandrich Exp $
* *
* Sample showing how to do SFTP non-blocking mkdir. * Sample showing how to do SFTP non-blocking mkdir.
* *
@@ -9,9 +9,9 @@
* "sftp 192.168.0.1 user password /tmp/sftp_write_nonblock.c" * "sftp 192.168.0.1 user password /tmp/sftp_write_nonblock.c"
*/ */
#include "config.h"
#include <libssh2.h> #include <libssh2.h>
#include <libssh2_sftp.h> #include <libssh2_sftp.h>
#include <libssh2_config.h>
#ifdef HAVE_WINSOCK2_H #ifdef HAVE_WINSOCK2_H
# include <winsock2.h> # include <winsock2.h>
@@ -42,9 +42,9 @@ int main(int argc, char *argv[])
struct sockaddr_in sin; struct sockaddr_in sin;
const char *fingerprint; const char *fingerprint;
LIBSSH2_SESSION *session; LIBSSH2_SESSION *session;
char *username=(char *)"username"; const char *username="username";
char *password=(char *)"password"; const char *password="password";
char *sftppath=(char *)"/tmp/sftp_mkdir_nonblock"; const char *sftppath="/tmp/sftp_mkdir_nonblock";
int rc; int rc;
LIBSSH2_SFTP *sftp_session; LIBSSH2_SFTP *sftp_session;
@@ -69,7 +69,7 @@ int main(int argc, char *argv[])
if(argc > 4) { if(argc > 4) {
sftppath = argv[4]; sftppath = argv[4];
} }
/* /*
* The application code is responsible for creating the socket * The application code is responsible for creating the socket
* and establishing the connection * and establishing the connection
@@ -79,7 +79,7 @@ int main(int argc, char *argv[])
sin.sin_family = AF_INET; sin.sin_family = AF_INET;
sin.sin_port = htons(22); sin.sin_port = htons(22);
sin.sin_addr.s_addr = hostaddr; sin.sin_addr.s_addr = hostaddr;
if (connect(sock, (struct sockaddr*)(&sin), if (connect(sock, (struct sockaddr*)(&sin),
sizeof(struct sockaddr_in)) != 0) { sizeof(struct sockaddr_in)) != 0) {
fprintf(stderr, "failed to connect!\n"); fprintf(stderr, "failed to connect!\n");
return -1; return -1;
@@ -149,7 +149,7 @@ int main(int argc, char *argv[])
/* Since we have set non-blocking, tell libssh2 we are non-blocking */ /* Since we have set non-blocking, tell libssh2 we are non-blocking */
libssh2_session_set_blocking(session, 0); libssh2_session_set_blocking(session, 0);
fprintf(stderr, "libssh2_sftp_mkdirnb()!\n"); fprintf(stderr, "libssh2_sftp_mkdirnb()!\n");
/* Make a directory via SFTP */ /* Make a directory via SFTP */
while ((rc = libssh2_sftp_mkdir(sftp_session, sftppath, while ((rc = libssh2_sftp_mkdir(sftp_session, sftppath,

View File

@@ -1,5 +1,5 @@
/* /*
* $Id: sftp_nonblock.c,v 1.10 2007/06/08 13:33:08 jehousley Exp $ * $Id: sftp_nonblock.c,v 1.13 2007/08/09 01:10:11 dfandrich Exp $
* *
* Sample showing how to do SFTP non-blocking transfers. * Sample showing how to do SFTP non-blocking transfers.
* *
@@ -9,9 +9,9 @@
* "sftp 192.168.0.1 user password /tmp/secrets" * "sftp 192.168.0.1 user password /tmp/secrets"
*/ */
#include "config.h"
#include <libssh2.h> #include <libssh2.h>
#include <libssh2_sftp.h> #include <libssh2_sftp.h>
#include <libssh2_config.h>
#ifdef HAVE_WINSOCK2_H #ifdef HAVE_WINSOCK2_H
# include <winsock2.h> # include <winsock2.h>
@@ -45,25 +45,25 @@ int main(int argc, char *argv[])
struct sockaddr_in sin; struct sockaddr_in sin;
const char *fingerprint; const char *fingerprint;
LIBSSH2_SESSION *session; LIBSSH2_SESSION *session;
char *username=(char *)"username"; const char *username="username";
char *password=(char *)"password"; const char *password="password";
char *sftppath=(char *)"/tmp/TEST"; const char *sftppath="/tmp/TEST";
int rc; int rc;
LIBSSH2_SFTP *sftp_session; LIBSSH2_SFTP *sftp_session;
LIBSSH2_SFTP_HANDLE *sftp_handle; LIBSSH2_SFTP_HANDLE *sftp_handle;
#ifdef WIN32 #ifdef WIN32
WSADATA wsadata; WSADATA wsadata;
WSAStartup(WINSOCK_VERSION, &wsadata); WSAStartup(WINSOCK_VERSION, &wsadata);
#endif #endif
if (argc > 1) { if (argc > 1) {
hostaddr = inet_addr(argv[1]); hostaddr = inet_addr(argv[1]);
} else { } else {
hostaddr = htonl(0x7F000001); hostaddr = htonl(0x7F000001);
} }
if (argc > 2) { if (argc > 2) {
username = argv[2]; username = argv[2];
} }
@@ -78,7 +78,7 @@ int main(int argc, char *argv[])
* and establishing the connection * and establishing the connection
*/ */
sock = socket(AF_INET, SOCK_STREAM, 0); sock = socket(AF_INET, SOCK_STREAM, 0);
sin.sin_family = AF_INET; sin.sin_family = AF_INET;
sin.sin_port = htons(22); sin.sin_port = htons(22);
sin.sin_addr.s_addr = hostaddr; sin.sin_addr.s_addr = hostaddr;
@@ -87,7 +87,7 @@ int main(int argc, char *argv[])
fprintf(stderr, "failed to connect!\n"); fprintf(stderr, "failed to connect!\n");
return -1; return -1;
} }
/* We set the socket non-blocking. We do it after the connect just to /* We set the socket non-blocking. We do it after the connect just to
simplify the example code. */ simplify the example code. */
#ifdef F_SETFL #ifdef F_SETFL
@@ -97,15 +97,15 @@ int main(int argc, char *argv[])
#else #else
#error "add support for setting the socket non-blocking here" #error "add support for setting the socket non-blocking here"
#endif #endif
/* Create a session instance */ /* Create a session instance */
session = libssh2_session_init(); session = libssh2_session_init();
if (!session) if (!session)
return -1; return -1;
/* Since we have set non-blocking, tell libssh2 we are non-blocking */ /* Since we have set non-blocking, tell libssh2 we are non-blocking */
libssh2_session_set_blocking(session, 0); libssh2_session_set_blocking(session, 0);
/* ... start it up. This will trade welcome banners, exchange keys, /* ... start it up. This will trade welcome banners, exchange keys,
* and setup crypto, compression, and MAC layers * and setup crypto, compression, and MAC layers
*/ */
@@ -114,7 +114,7 @@ int main(int argc, char *argv[])
fprintf(stderr, "Failure establishing SSH session: %d\n", rc); fprintf(stderr, "Failure establishing SSH session: %d\n", rc);
return -1; return -1;
} }
/* At this point we havn't yet authenticated. The first thing to do /* At this point we havn't yet authenticated. The first thing to do
* is check the hostkey's fingerprint against our known hosts Your app * 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 * may have it hard coded, may go to a file, may present it to the
@@ -126,11 +126,11 @@ int main(int argc, char *argv[])
fprintf(stderr, "%02X ", (unsigned char)fingerprint[i]); fprintf(stderr, "%02X ", (unsigned char)fingerprint[i]);
} }
fprintf(stderr, "\n"); fprintf(stderr, "\n");
if (auth_pw) { if (auth_pw) {
/* We could authenticate via password */ /* We could authenticate via password */
while ((rc = libssh2_userauth_password(session, username, password)) == LIBSSH2_ERROR_EAGAIN); while ((rc = libssh2_userauth_password(session, username, password)) == LIBSSH2_ERROR_EAGAIN);
if (rc) { if (rc) {
fprintf(stderr, "Authentication by password failed.\n"); fprintf(stderr, "Authentication by password failed.\n");
goto shutdown; goto shutdown;
} }
@@ -140,12 +140,12 @@ int main(int argc, char *argv[])
"/home/username/.ssh/id_rsa.pub", "/home/username/.ssh/id_rsa.pub",
"/home/username/.ssh/id_rsa", "/home/username/.ssh/id_rsa",
password)) == LIBSSH2_ERROR_EAGAIN); password)) == LIBSSH2_ERROR_EAGAIN);
if (rc) { if (rc) {
fprintf(stderr, "\tAuthentication by public key failed\n"); fprintf(stderr, "\tAuthentication by public key failed\n");
goto shutdown; goto shutdown;
} }
} }
fprintf(stderr, "libssh2_sftp_init()!\n"); fprintf(stderr, "libssh2_sftp_init()!\n");
do { do {
sftp_session = libssh2_sftp_init(session); sftp_session = libssh2_sftp_init(session);
@@ -155,22 +155,22 @@ int main(int argc, char *argv[])
goto shutdown; goto shutdown;
} }
} while (!sftp_session); } while (!sftp_session);
fprintf(stderr, "libssh2_sftp_open()!\n"); fprintf(stderr, "libssh2_sftp_open()!\n");
/* Request a file via SFTP */ /* Request a file via SFTP */
do { do {
sftp_handle = libssh2_sftp_open(sftp_session, sftppath, LIBSSH2_FXF_READ, 0); sftp_handle = libssh2_sftp_open(sftp_session, sftppath, LIBSSH2_FXF_READ, 0);
if ((!sftp_handle) && (libssh2_session_last_errno(session) != LIBSSH2_ERROR_EAGAIN)) { if ((!sftp_handle) && (libssh2_session_last_errno(session) != LIBSSH2_ERROR_EAGAIN)) {
fprintf(stderr, "Unable to open file with SFTP\n"); fprintf(stderr, "Unable to open file with SFTP\n");
goto shutdown; goto shutdown;
} }
} while (!sftp_handle); } while (!sftp_handle);
fprintf(stderr, "libssh2_sftp_open() is done, now receive data!\n"); fprintf(stderr, "libssh2_sftp_open() is done, now receive data!\n");
do { do {
char mem[1024]; char mem[1024];
/* loop until we fail */ /* loop until we fail */
fprintf(stderr, "libssh2_sftp_readnb()!\n"); fprintf(stderr, "libssh2_sftp_readnb()!\n");
while ((rc = libssh2_sftp_read(sftp_handle, mem, sizeof(mem))) == LIBSSH2_ERROR_EAGAIN) { while ((rc = libssh2_sftp_read(sftp_handle, mem, sizeof(mem))) == LIBSSH2_ERROR_EAGAIN) {
@@ -182,15 +182,15 @@ int main(int argc, char *argv[])
break; break;
} }
} while (1); } while (1);
libssh2_sftp_close(sftp_handle); libssh2_sftp_close(sftp_handle);
libssh2_sftp_shutdown(sftp_session); libssh2_sftp_shutdown(sftp_session);
shutdown: shutdown:
while ((rc = libssh2_session_disconnect(session, "Normal Shutdown, Thank you for playing")) == LIBSSH2_ERROR_EAGAIN); while ((rc = libssh2_session_disconnect(session, "Normal Shutdown, Thank you for playing")) == LIBSSH2_ERROR_EAGAIN);
libssh2_session_free(session); libssh2_session_free(session);
#ifdef WIN32 #ifdef WIN32
Sleep(1000); Sleep(1000);
closesocket(sock); closesocket(sock);

View File

@@ -1,5 +1,5 @@
/* /*
* $Id: sftp_write.c,v 1.4 2007/06/06 12:34:09 jehousley Exp $ * $Id: sftp_write.c,v 1.8 2007/08/09 01:10:11 dfandrich Exp $
* *
* Sample showing how to do SFTP write transfers. * Sample showing how to do SFTP write transfers.
* *
@@ -9,9 +9,9 @@
* "sftp 192.168.0.1 user password sftp_write.c /tmp/secrets" * "sftp 192.168.0.1 user password sftp_write.c /tmp/secrets"
*/ */
#include "config.h"
#include <libssh2.h> #include <libssh2.h>
#include <libssh2_sftp.h> #include <libssh2_sftp.h>
#include <libssh2_config.h>
#ifdef HAVE_WINSOCK2_H #ifdef HAVE_WINSOCK2_H
# include <winsock2.h> # include <winsock2.h>
@@ -42,10 +42,10 @@ int main(int argc, char *argv[])
struct sockaddr_in sin; struct sockaddr_in sin;
const char *fingerprint; const char *fingerprint;
LIBSSH2_SESSION *session; LIBSSH2_SESSION *session;
char *username=(char *)"username"; const char *username="username";
char *password=(char *)"password"; const char *password="password";
char *loclfile=(char *)"sftp_write.c"; const char *loclfile="sftp_write.c";
char *sftppath=(char *)"/tmp/TEST"; const char *sftppath="/tmp/TEST";
int rc; int rc;
FILE *local; FILE *local;
LIBSSH2_SFTP *sftp_session; LIBSSH2_SFTP *sftp_session;
@@ -78,13 +78,13 @@ int main(int argc, char *argv[])
if(argc > 5) { if(argc > 5) {
sftppath = argv[5]; sftppath = argv[5];
} }
local = fopen(loclfile, "rb"); local = fopen(loclfile, "rb");
if (!local) { if (!local) {
printf("Can't local file %s\n", loclfile); printf("Can't local file %s\n", loclfile);
goto shutdown; goto shutdown;
} }
/* /*
* The application code is responsible for creating the socket * The application code is responsible for creating the socket
* and establishing the connection * and establishing the connection
@@ -94,7 +94,7 @@ int main(int argc, char *argv[])
sin.sin_family = AF_INET; sin.sin_family = AF_INET;
sin.sin_port = htons(22); sin.sin_port = htons(22);
sin.sin_addr.s_addr = hostaddr; sin.sin_addr.s_addr = hostaddr;
if (connect(sock, (struct sockaddr*)(&sin), if (connect(sock, (struct sockaddr*)(&sin),
sizeof(struct sockaddr_in)) != 0) { sizeof(struct sockaddr_in)) != 0) {
fprintf(stderr, "failed to connect!\n"); fprintf(stderr, "failed to connect!\n");
return -1; return -1;
@@ -108,7 +108,7 @@ int main(int argc, char *argv[])
/* Since we have set non-blocking, tell libssh2 we are blocking */ /* Since we have set non-blocking, tell libssh2 we are blocking */
libssh2_session_set_blocking(session, 1); libssh2_session_set_blocking(session, 1);
/* ... start it up. This will trade welcome banners, exchange keys, /* ... start it up. This will trade welcome banners, exchange keys,
* and setup crypto, compression, and MAC layers * and setup crypto, compression, and MAC layers
*/ */
@@ -147,8 +147,6 @@ int main(int argc, char *argv[])
} }
} }
//libssh2_trace(session, 0xFFFF);
fprintf(stderr, "libssh2_sftp_init()!\n"); fprintf(stderr, "libssh2_sftp_init()!\n");
sftp_session = libssh2_sftp_init(session); sftp_session = libssh2_sftp_init(session);
@@ -159,7 +157,7 @@ int main(int argc, char *argv[])
/* Since we have not set non-blocking, tell libssh2 we are blocking */ /* Since we have not set non-blocking, tell libssh2 we are blocking */
libssh2_session_set_blocking(session, 1); libssh2_session_set_blocking(session, 1);
fprintf(stderr, "libssh2_sftp_open()!\n"); fprintf(stderr, "libssh2_sftp_open()!\n");
/* Request a file via SFTP */ /* Request a file via SFTP */
sftp_handle = sftp_handle =
@@ -167,7 +165,7 @@ int main(int argc, char *argv[])
LIBSSH2_FXF_WRITE|LIBSSH2_FXF_CREAT|LIBSSH2_FXF_TRUNC, LIBSSH2_FXF_WRITE|LIBSSH2_FXF_CREAT|LIBSSH2_FXF_TRUNC,
LIBSSH2_SFTP_S_IRUSR|LIBSSH2_SFTP_S_IWUSR| LIBSSH2_SFTP_S_IRUSR|LIBSSH2_SFTP_S_IWUSR|
LIBSSH2_SFTP_S_IRGRP|LIBSSH2_SFTP_S_IROTH); LIBSSH2_SFTP_S_IRGRP|LIBSSH2_SFTP_S_IROTH);
if (!sftp_handle) { if (!sftp_handle) {
fprintf(stderr, "Unable to open file with SFTP\n"); fprintf(stderr, "Unable to open file with SFTP\n");
goto shutdown; goto shutdown;
@@ -180,7 +178,7 @@ int main(int argc, char *argv[])
break; break;
} }
ptr = mem; ptr = mem;
do { do {
/* write data in a loop until we block */ /* write data in a loop until we block */
rc = libssh2_sftp_write(sftp_handle, ptr, nread); rc = libssh2_sftp_write(sftp_handle, ptr, nread);
@@ -195,7 +193,8 @@ int main(int argc, char *argv[])
shutdown: shutdown:
libssh2_session_disconnect(session, "Normal Shutdown, Thank you for playing"); libssh2_session_disconnect(session,
"Normal Shutdown, Thank you for playing");
libssh2_session_free(session); libssh2_session_free(session);
#ifdef WIN32 #ifdef WIN32

View File

@@ -1,5 +1,5 @@
/* /*
* $Id: sftp_write_nonblock.c,v 1.7 2007/06/08 13:33:08 jehousley Exp $ * $Id: sftp_write_nonblock.c,v 1.10 2007/08/09 01:10:11 dfandrich Exp $
* *
* Sample showing how to do SFTP non-blocking write transfers. * Sample showing how to do SFTP non-blocking write transfers.
* *
@@ -9,9 +9,9 @@
* "sftp 192.168.0.1 user password sftp_write_nonblock.c /tmp/sftp_write_nonblock.c" * "sftp 192.168.0.1 user password sftp_write_nonblock.c /tmp/sftp_write_nonblock.c"
*/ */
#include "config.h"
#include <libssh2.h> #include <libssh2.h>
#include <libssh2_sftp.h> #include <libssh2_sftp.h>
#include <libssh2_config.h>
#ifdef HAVE_WINSOCK2_H #ifdef HAVE_WINSOCK2_H
# include <winsock2.h> # include <winsock2.h>
@@ -42,10 +42,10 @@ int main(int argc, char *argv[])
struct sockaddr_in sin; struct sockaddr_in sin;
const char *fingerprint; const char *fingerprint;
LIBSSH2_SESSION *session; LIBSSH2_SESSION *session;
char *username=(char *)"username"; const char *username="username";
char *password=(char *)"password"; const char *password="password";
char *loclfile=(char *)"sftp_write_nonblock.c"; const char *loclfile="sftp_write_nonblock.c";
char *sftppath=(char *)"/tmp/sftp_write_nonblock.c"; const char *sftppath="/tmp/sftp_write_nonblock.c";
int rc; int rc;
FILE *local; FILE *local;
LIBSSH2_SFTP *sftp_session; LIBSSH2_SFTP *sftp_session;
@@ -53,19 +53,19 @@ int main(int argc, char *argv[])
char mem[1024]; char mem[1024];
size_t nread; size_t nread;
char *ptr; char *ptr;
#ifdef WIN32 #ifdef WIN32
WSADATA wsadata; WSADATA wsadata;
WSAStartup(WINSOCK_VERSION, &wsadata); WSAStartup(WINSOCK_VERSION, &wsadata);
#endif #endif
if (argc > 1) { if (argc > 1) {
hostaddr = inet_addr(argv[1]); hostaddr = inet_addr(argv[1]);
} else { } else {
hostaddr = htonl(0x7F000001); hostaddr = htonl(0x7F000001);
} }
if (argc > 2) { if (argc > 2) {
username = argv[2]; username = argv[2];
} }
@@ -78,28 +78,28 @@ int main(int argc, char *argv[])
if (argc > 5) { if (argc > 5) {
sftppath = argv[5]; sftppath = argv[5];
} }
local = fopen(loclfile, "rb"); local = fopen(loclfile, "rb");
if (!local) { if (!local) {
printf("Can't local file %s\n", loclfile); printf("Can't local file %s\n", loclfile);
goto shutdown; goto shutdown;
} }
/* /*
* The application code is responsible for creating the socket * The application code is responsible for creating the socket
* and establishing the connection * and establishing the connection
*/ */
sock = socket(AF_INET, SOCK_STREAM, 0); sock = socket(AF_INET, SOCK_STREAM, 0);
sin.sin_family = AF_INET; sin.sin_family = AF_INET;
sin.sin_port = htons(22); sin.sin_port = htons(22);
sin.sin_addr.s_addr = hostaddr; sin.sin_addr.s_addr = hostaddr;
if (connect(sock, (struct sockaddr*)(&sin), if (connect(sock, (struct sockaddr*)(&sin),
sizeof(struct sockaddr_in)) != 0) { sizeof(struct sockaddr_in)) != 0) {
fprintf(stderr, "failed to connect!\n"); fprintf(stderr, "failed to connect!\n");
return -1; return -1;
} }
/* We set the socket non-blocking. We do it after the connect just to /* We set the socket non-blocking. We do it after the connect just to
simplify the example code. */ simplify the example code. */
#ifdef F_SETFL #ifdef F_SETFL
@@ -109,26 +109,26 @@ int main(int argc, char *argv[])
#else #else
#error "add support for setting the socket non-blocking here" #error "add support for setting the socket non-blocking here"
#endif #endif
/* Create a session instance /* Create a session instance
*/ */
session = libssh2_session_init(); session = libssh2_session_init();
if (!session) if (!session)
return -1; return -1;
/* Since we have set non-blocking, tell libssh2 we are non-blocking */ /* Since we have set non-blocking, tell libssh2 we are non-blocking */
libssh2_session_set_blocking(session, 0); libssh2_session_set_blocking(session, 0);
/* ... start it up. This will trade welcome banners, exchange keys, /* ... start it up. This will trade welcome banners, exchange keys,
* and setup crypto, compression, and MAC layers * and setup crypto, compression, and MAC layers
*/ */
while ((rc = libssh2_session_startup(session, sock)) while ((rc = libssh2_session_startup(session, sock))
== LIBSSH2_ERROR_EAGAIN); == LIBSSH2_ERROR_EAGAIN);
if (rc) { if (rc) {
fprintf(stderr, "Failure establishing SSH session: %d\n", rc); fprintf(stderr, "Failure establishing SSH session: %d\n", rc);
return -1; return -1;
} }
/* At this point we havn't yet authenticated. The first thing to do /* At this point we havn't yet authenticated. The first thing to do
* is check the hostkey's fingerprint against our known hosts Your app * 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 * may have it hard coded, may go to a file, may present it to the
@@ -140,7 +140,7 @@ int main(int argc, char *argv[])
printf("%02X ", (unsigned char)fingerprint[i]); printf("%02X ", (unsigned char)fingerprint[i]);
} }
printf("\n"); printf("\n");
if (auth_pw) { if (auth_pw) {
/* We could authenticate via password */ /* We could authenticate via password */
while ((rc = libssh2_userauth_password(session, username, password)) == LIBSSH2_ERROR_EAGAIN); while ((rc = libssh2_userauth_password(session, username, password)) == LIBSSH2_ERROR_EAGAIN);
@@ -159,20 +159,20 @@ int main(int argc, char *argv[])
goto shutdown; goto shutdown;
} }
} }
fprintf(stderr, "libssh2_sftp_init()!\n"); fprintf(stderr, "libssh2_sftp_init()!\n");
do { do {
sftp_session = libssh2_sftp_init(session); sftp_session = libssh2_sftp_init(session);
if ((!sftp_session) && (libssh2_session_last_errno(session) != LIBSSH2_ERROR_EAGAIN)) { if ((!sftp_session) && (libssh2_session_last_errno(session) != LIBSSH2_ERROR_EAGAIN)) {
fprintf(stderr, "Unable to init SFTP session\n"); fprintf(stderr, "Unable to init SFTP session\n");
goto shutdown; goto shutdown;
} }
} while (!sftp_session); } while (!sftp_session);
/* Since we have set non-blocking, tell libssh2 we are non-blocking */ /* Since we have set non-blocking, tell libssh2 we are non-blocking */
libssh2_session_set_blocking(session, 0); libssh2_session_set_blocking(session, 0);
fprintf(stderr, "libssh2_sftp_open()!\n"); fprintf(stderr, "libssh2_sftp_open()!\n");
/* Request a file via SFTP */ /* Request a file via SFTP */
do { do {
@@ -181,13 +181,13 @@ int main(int argc, char *argv[])
LIBSSH2_FXF_WRITE|LIBSSH2_FXF_CREAT|LIBSSH2_FXF_TRUNC, LIBSSH2_FXF_WRITE|LIBSSH2_FXF_CREAT|LIBSSH2_FXF_TRUNC,
LIBSSH2_SFTP_S_IRUSR|LIBSSH2_SFTP_S_IWUSR| LIBSSH2_SFTP_S_IRUSR|LIBSSH2_SFTP_S_IWUSR|
LIBSSH2_SFTP_S_IRGRP|LIBSSH2_SFTP_S_IROTH); LIBSSH2_SFTP_S_IRGRP|LIBSSH2_SFTP_S_IROTH);
if ((!sftp_handle) && (libssh2_session_last_errno(session) != LIBSSH2_ERROR_EAGAIN)) { if ((!sftp_handle) && (libssh2_session_last_errno(session) != LIBSSH2_ERROR_EAGAIN)) {
fprintf(stderr, "Unable to open file with SFTP\n"); fprintf(stderr, "Unable to open file with SFTP\n");
goto shutdown; goto shutdown;
} }
} while (!sftp_handle); } while (!sftp_handle);
fprintf(stderr, "libssh2_sftp_open() is done, now send data!\n"); fprintf(stderr, "libssh2_sftp_open() is done, now send data!\n");
do { do {
nread = fread(mem, 1, sizeof(mem), local); nread = fread(mem, 1, sizeof(mem), local);
@@ -196,7 +196,7 @@ int main(int argc, char *argv[])
break; break;
} }
ptr = mem; ptr = mem;
do { do {
/* write data in a loop until we block */ /* write data in a loop until we block */
while ((rc = libssh2_sftp_write(sftp_handle, ptr, nread)) == LIBSSH2_ERROR_EAGAIN) { while ((rc = libssh2_sftp_write(sftp_handle, ptr, nread)) == LIBSSH2_ERROR_EAGAIN) {
@@ -206,16 +206,16 @@ int main(int argc, char *argv[])
nread -= nread; nread -= nread;
} while (rc > 0); } while (rc > 0);
} while (1); } while (1);
fclose(local); fclose(local);
libssh2_sftp_close(sftp_handle); libssh2_sftp_close(sftp_handle);
libssh2_sftp_shutdown(sftp_session); libssh2_sftp_shutdown(sftp_session);
shutdown: shutdown:
while ((rc = libssh2_session_disconnect(session, "Normal Shutdown, Thank you for playing")) == LIBSSH2_ERROR_EAGAIN); while ((rc = libssh2_session_disconnect(session, "Normal Shutdown, Thank you for playing")) == LIBSSH2_ERROR_EAGAIN);
libssh2_session_free(session); libssh2_session_free(session);
#ifdef WIN32 #ifdef WIN32
Sleep(1000); Sleep(1000);
closesocket(sock); closesocket(sock);

View File

@@ -1,5 +1,5 @@
/* /*
* $Id: sftpdir.c,v 1.6 2007/06/15 17:22:49 jehousley Exp $ * $Id: sftpdir.c,v 1.9 2007/08/09 01:10:11 dfandrich Exp $
* *
* Sample doing an SFTP directory listing. * Sample doing an SFTP directory listing.
* *
@@ -9,9 +9,9 @@
* "sftpdir 192.168.0.1 user password /tmp/secretdir" * "sftpdir 192.168.0.1 user password /tmp/secretdir"
*/ */
#include "config.h"
#include <libssh2.h> #include <libssh2.h>
#include <libssh2_sftp.h> #include <libssh2_sftp.h>
#include <libssh2_config.h>
#ifdef HAVE_WINSOCK2_H #ifdef HAVE_WINSOCK2_H
# include <winsock2.h> # include <winsock2.h>
@@ -42,9 +42,9 @@ int main(int argc, char *argv[])
struct sockaddr_in sin; struct sockaddr_in sin;
const char *fingerprint; const char *fingerprint;
LIBSSH2_SESSION *session; LIBSSH2_SESSION *session;
char *username=(char *)"username"; const char *username="username";
char *password=(char *)"password"; const char *password="password";
char *sftppath=(char *)"/tmp/secretdir"; const char *sftppath="/tmp/secretdir";
int rc; int rc;
LIBSSH2_SFTP *sftp_session; LIBSSH2_SFTP *sftp_session;
LIBSSH2_SFTP_HANDLE *sftp_handle; LIBSSH2_SFTP_HANDLE *sftp_handle;
@@ -139,7 +139,7 @@ int main(int argc, char *argv[])
/* Since we have not set non-blocking, tell libssh2 we are blocking */ /* Since we have not set non-blocking, tell libssh2 we are blocking */
libssh2_session_set_blocking(session, 1); libssh2_session_set_blocking(session, 1);
fprintf(stderr, "libssh2_sftp_opendir()!\n"); fprintf(stderr, "libssh2_sftp_opendir()!\n");
/* Request a dir listing via SFTP */ /* Request a dir listing via SFTP */
sftp_handle = libssh2_sftp_opendir(sftp_session, sftppath); sftp_handle = libssh2_sftp_opendir(sftp_session, sftppath);

View File

@@ -1,5 +1,5 @@
/* /*
* $Id: sftpdir_nonblock.c,v 1.7 2007/06/08 13:33:08 jehousley Exp $ * $Id: sftpdir_nonblock.c,v 1.10 2007/08/09 01:10:11 dfandrich Exp $
* *
* Sample doing an SFTP directory listing. * Sample doing an SFTP directory listing.
* *
@@ -9,9 +9,9 @@
* "sftpdir 192.168.0.1 user password /tmp/secretdir" * "sftpdir 192.168.0.1 user password /tmp/secretdir"
*/ */
#include "config.h"
#include <libssh2.h> #include <libssh2.h>
#include <libssh2_sftp.h> #include <libssh2_sftp.h>
#include <libssh2_config.h>
#ifdef HAVE_WINSOCK2_H #ifdef HAVE_WINSOCK2_H
# include <winsock2.h> # include <winsock2.h>
@@ -37,197 +37,201 @@
int main(int argc, char *argv[]) int main(int argc, char *argv[])
{ {
unsigned long hostaddr; unsigned long hostaddr;
int sock, i, auth_pw = 1; int sock, i, auth_pw = 1;
struct sockaddr_in sin; struct sockaddr_in sin;
const char *fingerprint; const char *fingerprint;
LIBSSH2_SESSION *session; LIBSSH2_SESSION *session;
char *username=(char *)"username"; const char *username="username";
char *password=(char *)"password"; const char *password="password";
char *sftppath=(char *)"/tmp/secretdir"; const char *sftppath="/tmp/secretdir";
int rc; int rc;
LIBSSH2_SFTP *sftp_session; LIBSSH2_SFTP *sftp_session;
LIBSSH2_SFTP_HANDLE *sftp_handle; LIBSSH2_SFTP_HANDLE *sftp_handle;
#ifdef WIN32 #ifdef WIN32
WSADATA wsadata; WSADATA wsadata;
WSAStartup(WINSOCK_VERSION, &wsadata); WSAStartup(WINSOCK_VERSION, &wsadata);
#endif #endif
if (argc > 1) { if (argc > 1) {
hostaddr = inet_addr(argv[1]); hostaddr = inet_addr(argv[1]);
} else { } else {
hostaddr = htonl(0x7F000001); hostaddr = htonl(0x7F000001);
} }
if(argc > 2) { if(argc > 2) {
username = argv[2]; username = argv[2];
} }
if(argc > 3) { if(argc > 3) {
password = argv[3]; password = argv[3];
} }
if(argc > 4) { if(argc > 4) {
sftppath = argv[4]; sftppath = argv[4];
} }
/* /*
* The application code is responsible for creating the socket * The application code is responsible for creating the socket
* and establishing the connection * and establishing the connection
*/ */
sock = socket(AF_INET, SOCK_STREAM, 0); sock = socket(AF_INET, SOCK_STREAM, 0);
sin.sin_family = AF_INET; sin.sin_family = AF_INET;
sin.sin_port = htons(22); sin.sin_port = htons(22);
sin.sin_addr.s_addr = hostaddr; sin.sin_addr.s_addr = hostaddr;
if (connect(sock, (struct sockaddr*)(&sin), if (connect(sock, (struct sockaddr*)(&sin),
sizeof(struct sockaddr_in)) != 0) { sizeof(struct sockaddr_in)) != 0) {
fprintf(stderr, "failed to connect!\n"); fprintf(stderr, "failed to connect!\n");
return -1; return -1;
} }
/* We set the socket non-blocking. We do it after the connect just to /* We set the socket non-blocking. We do it after the connect just to
simplify the example code. */ simplify the example code. */
#ifdef F_SETFL #ifdef F_SETFL
/* FIXME: this can/should be done in a more portable manner */ /* FIXME: this can/should be done in a more portable manner */
rc = fcntl(sock, F_GETFL, 0); rc = fcntl(sock, F_GETFL, 0);
fcntl(sock, F_SETFL, rc | O_NONBLOCK); fcntl(sock, F_SETFL, rc | O_NONBLOCK);
#else #else
#error "add support for setting the socket non-blocking here" #error "add support for setting the socket non-blocking here"
#endif #endif
/* Create a session instance /* Create a session instance
*/ */
session = libssh2_session_init(); session = libssh2_session_init();
if(!session) if(!session)
return -1; return -1;
/* Since we have set non-blocking, tell libssh2 we are non-blocking */ /* Since we have set non-blocking, tell libssh2 we are non-blocking */
libssh2_session_set_blocking(session, 0); libssh2_session_set_blocking(session, 0);
/* ... start it up. This will trade welcome banners, exchange keys,
* and setup crypto, compression, and MAC layers
*/
while ((rc = libssh2_session_startup(session, sock)) == LIBSSH2_ERROR_EAGAIN);
if(rc) {
fprintf(stderr, "Failure establishing SSH session: %d\n", rc);
return -1;
}
/* At this point we havn't yet authenticated. The first thing to do /* ... start it up. This will trade welcome banners, exchange keys,
* is check the hostkey's fingerprint against our known hosts Your app * and setup crypto, compression, and MAC layers
* may have it hard coded, may go to a file, may present it to the */
* user, that's your call while ((rc = libssh2_session_startup(session, sock)) == LIBSSH2_ERROR_EAGAIN);
*/ if(rc) {
fingerprint = libssh2_hostkey_hash(session, LIBSSH2_HOSTKEY_HASH_MD5); fprintf(stderr, "Failure establishing SSH session: %d\n", rc);
printf("Fingerprint: "); return -1;
for(i = 0; i < 16; i++) { }
printf("%02X ", (unsigned char)fingerprint[i]);
} /* At this point we havn't yet authenticated. The first thing to do
printf("\n"); * 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");
if (auth_pw) { if (auth_pw) {
/* We could authenticate via password */ /* We could authenticate via password */
while ((rc = libssh2_userauth_password(session, username, password)) == LIBSSH2_ERROR_EAGAIN); while ((rc = libssh2_userauth_password(session, username, password)) ==
if (rc) { LIBSSH2_ERROR_EAGAIN);
if (rc) {
fprintf(stderr, "Authentication by password failed.\n"); fprintf(stderr, "Authentication by password failed.\n");
goto shutdown; goto shutdown;
} }
} else { } else {
/* Or by public key */ /* Or by public key */
while ((rc = libssh2_userauth_publickey_fromfile(session, username, while ((rc = libssh2_userauth_publickey_fromfile(session, username,
"/home/username/.ssh/id_rsa.pub", "/home/username/.ssh/id_rsa.pub",
"/home/username/.ssh/id_rsa", "/home/username/.ssh/id_rsa",
password)) == LIBSSH2_ERROR_EAGAIN); password)) == LIBSSH2_ERROR_EAGAIN);
if (rc) { if (rc) {
fprintf(stderr, "\tAuthentication by public key failed\n"); fprintf(stderr, "\tAuthentication by public key failed\n");
goto shutdown; goto shutdown;
} }
} }
fprintf(stderr, "libssh2_sftp_init()!\n"); fprintf(stderr, "libssh2_sftp_init()!\n");
do { do {
sftp_session = libssh2_sftp_init(session); sftp_session = libssh2_sftp_init(session);
if ((!sftp_session) && (libssh2_session_last_errno(session) != LIBSSH2_ERROR_EAGAIN)) { if ((!sftp_session) && (libssh2_session_last_errno(session) !=
fprintf(stderr, "Unable to init SFTP session\n"); LIBSSH2_ERROR_EAGAIN)) {
goto shutdown; fprintf(stderr, "Unable to init SFTP session\n");
goto shutdown;
}
} while (!sftp_session);
fprintf(stderr, "libssh2_sftp_opendir()!\n");
/* Request a dir listing via SFTP */
do {
sftp_handle = libssh2_sftp_opendir(sftp_session, sftppath);
if ((!sftp_handle) && (libssh2_session_last_errno(session) !=
LIBSSH2_ERROR_EAGAIN)) {
fprintf(stderr, "Unable to open dir with SFTP\n");
goto shutdown;
}
} while (!sftp_handle);
fprintf(stderr, "libssh2_sftp_opendir() is done, now receive listing!\n");
do {
char mem[512];
LIBSSH2_SFTP_ATTRIBUTES attrs;
/* loop until we fail */
while ((rc = libssh2_sftp_readdir(sftp_handle, mem, sizeof(mem),
&attrs)) == LIBSSH2_ERROR_EAGAIN) {
;
}
if(rc > 0) {
/* rc is the length of the file name in the mem
buffer */
if(attrs.flags & LIBSSH2_SFTP_ATTR_PERMISSIONS) {
/* this should check what permissions it
is and print the output accordingly */
printf("--fix----- ");
} else {
printf("---------- ");
} }
} while (!sftp_session);
if(attrs.flags & LIBSSH2_SFTP_ATTR_UIDGID) {
fprintf(stderr, "libssh2_sftp_opendir()!\n"); printf("%4ld %4ld ", attrs.uid, attrs.gid);
/* Request a dir listing via SFTP */ } else {
do { printf(" - - ");
sftp_handle = libssh2_sftp_opendir(sftp_session, sftppath);
if ((!sftp_handle) && (libssh2_session_last_errno(session) != LIBSSH2_ERROR_EAGAIN)) {
fprintf(stderr, "Unable to open dir with SFTP\n");
goto shutdown;
} }
} while (!sftp_handle);
fprintf(stderr, "libssh2_sftp_opendir() is done, now receive listing!\n");
do {
char mem[512];
LIBSSH2_SFTP_ATTRIBUTES attrs;
/* loop until we fail */ if(attrs.flags & LIBSSH2_SFTP_ATTR_SIZE) {
while ((rc = libssh2_sftp_readdir(sftp_handle, mem, sizeof(mem), &attrs)) == LIBSSH2_ERROR_EAGAIN) { /* attrs.filesize is an uint64_t according to
; the docs but there is no really good and
} portable 64bit type for C before C99, and
if(rc > 0) { correspondingly there was no good printf()
/* rc is the length of the file name in the mem option for it... */
buffer */
if(attrs.flags & LIBSSH2_SFTP_ATTR_PERMISSIONS) { printf("%8lld ", attrs.filesize);
/* this should check what permissions it }
is and print the output accordingly */
printf("--fix----- ");
} else {
printf("---------- ");
}
if(attrs.flags & LIBSSH2_SFTP_ATTR_UIDGID) { printf("%s\n", mem);
printf("%4ld %4ld ", attrs.uid, attrs.gid); }
} else { else if (rc == LIBSSH2_ERROR_EAGAIN) {
printf(" - - "); /* blocking */
} fprintf(stderr, "Blocking\n");
} else {
break;
}
if(attrs.flags & LIBSSH2_SFTP_ATTR_SIZE) { } while (1);
/* attrs.filesize is an uint64_t according to
the docs but there is no really good and
portable 64bit type for C before C99, and
correspondingly there was no good printf()
option for it... */
printf("%8lld ", attrs.filesize); libssh2_sftp_closedir(sftp_handle);
} libssh2_sftp_shutdown(sftp_session);
printf("%s\n", mem); shutdown:
}
else if (rc == LIBSSH2_ERROR_EAGAIN) {
/* blocking */
fprintf(stderr, "Blocking\n");
} else {
break;
}
} while (1); libssh2_session_disconnect(session, "Normal Shutdown, Thank you for playing");
libssh2_session_free(session);
libssh2_sftp_closedir(sftp_handle);
libssh2_sftp_shutdown(sftp_session);
shutdown:
libssh2_session_disconnect(session, "Normal Shutdown, Thank you for playing");
libssh2_session_free(session);
#ifdef WIN32 #ifdef WIN32
Sleep(1000); Sleep(1000);
closesocket(sock); closesocket(sock);
#else #else
sleep(1); sleep(1);
close(sock); close(sock);
#endif #endif
printf("all done\n"); printf("all done\n");
return 0; return 0;
} }

View File

@@ -1,17 +1,17 @@
/* /*
* $Id: ssh2.c,v 1.3 2007/04/26 23:59:15 gknauf Exp $ * $Id: ssh2.c,v 1.17 2007/08/09 01:10:11 dfandrich Exp $
* *
* Sample showing how to do SSH2 connect. * Sample showing how to do SSH2 connect.
* *
* The sample code has default values for host name, user name, password * The sample code has default values for host name, user name, password
* and path to copy, but you can specify them on the command line like: * and path to copy, but you can specify them on the command line like:
* *
* "ssh2 host user password" * "ssh2 host user password [-p|-i|-k]"
*/ */
#include "config.h"
#include <libssh2.h> #include <libssh2.h>
#include <libssh2_sftp.h> #include <libssh2_sftp.h>
#include <libssh2_config.h>
#ifdef HAVE_WINSOCK2_H #ifdef HAVE_WINSOCK2_H
# include <winsock2.h> # include <winsock2.h>
@@ -25,6 +25,9 @@
# ifdef HAVE_UNISTD_H # ifdef HAVE_UNISTD_H
#include <unistd.h> #include <unistd.h>
#endif #endif
# ifdef HAVE_ARPA_INET_H
#include <arpa/inet.h>
#endif
#include <sys/types.h> #include <sys/types.h>
#include <fcntl.h> #include <fcntl.h>
@@ -32,147 +35,213 @@
#include <stdio.h> #include <stdio.h>
#include <ctype.h> #include <ctype.h>
const char *keyfile1="~/.ssh/id_rsa.pub";
const char *keyfile2="~/.ssh/id_rsa";
const char *username="username";
const char *password="password";
static void kbd_callback(const char *name, int name_len,
const char *instruction, int instruction_len, int num_prompts,
const LIBSSH2_USERAUTH_KBDINT_PROMPT *prompts,
LIBSSH2_USERAUTH_KBDINT_RESPONSE *responses,
void **abstract)
{
(void)name;
(void)name_len;
(void)instruction;
(void)instruction_len;
if (num_prompts == 1) {
responses[0].text = strdup(password);
responses[0].length = strlen(password);
}
(void)prompts;
(void)abstract;
} /* kbd_callback */
int main(int argc, char *argv[]) int main(int argc, char *argv[])
{ {
unsigned long hostaddr; unsigned long hostaddr;
int sock, i, auth_pw = 1; int sock, i, auth_pw = 0;
struct sockaddr_in sin; struct sockaddr_in sin;
const char *fingerprint; const char *fingerprint;
LIBSSH2_SESSION *session; char *userauthlist;
LIBSSH2_CHANNEL *channel; LIBSSH2_SESSION *session;
char *username=(char *)"username"; LIBSSH2_CHANNEL *channel;
char *password=(char *)"password";
#ifdef WIN32 #ifdef WIN32
WSADATA wsadata; WSADATA wsadata;
WSAStartup(WINSOCK_VERSION, &wsadata); WSAStartup(WINSOCK_VERSION, &wsadata);
#endif #endif
if (argc > 1) { if (argc > 1) {
hostaddr = inet_addr(argv[1]); hostaddr = inet_addr(argv[1]);
} else { } else {
hostaddr = htonl(0x7F000001); hostaddr = htonl(0x7F000001);
} }
if(argc > 2) { if(argc > 2) {
username = argv[2]; username = argv[2];
} }
if(argc > 3) { if(argc > 3) {
password = argv[3]; password = argv[3];
} }
/* Ultra basic "connect to port 22 on localhost" /* Ultra basic "connect to port 22 on localhost"
* Your code is responsible for creating the socket establishing the connection * Your code is responsible for creating the socket establishing the connection
*/ */
sock = socket(AF_INET, SOCK_STREAM, 0); sock = socket(AF_INET, SOCK_STREAM, 0);
#ifndef WIN32 #ifndef WIN32
fcntl(sock, F_SETFL, 0); fcntl(sock, F_SETFL, 0);
#endif #endif
sin.sin_family = AF_INET; sin.sin_family = AF_INET;
sin.sin_port = htons(22); sin.sin_port = htons(22);
sin.sin_addr.s_addr = hostaddr; sin.sin_addr.s_addr = hostaddr;
if (connect(sock, (struct sockaddr*)(&sin), if (connect(sock, (struct sockaddr*)(&sin),
sizeof(struct sockaddr_in)) != 0) { sizeof(struct sockaddr_in)) != 0) {
fprintf(stderr, "failed to connect!\n"); fprintf(stderr, "failed to connect!\n");
return -1; return -1;
} }
/* Create a session instance and start it up /* Create a session instance and start it up
* This will trade welcome banners, exchange keys, and setup crypto, compression, and MAC layers * This will trade welcome banners, exchange keys, and setup crypto, compression, and MAC layers
*/ */
session = libssh2_session_init(); session = libssh2_session_init();
if (libssh2_session_startup(session, sock)) { if (libssh2_session_startup(session, sock)) {
fprintf(stderr, "Failure establishing SSH session\n"); fprintf(stderr, "Failure establishing SSH session\n");
return -1; return -1;
} }
/* At this point we havn't authenticated, /* At this point we havn't authenticated,
* The first thing to do is check the hostkey's fingerprint against our known hosts * 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 * 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); fingerprint = libssh2_hostkey_hash(session, LIBSSH2_HOSTKEY_HASH_MD5);
printf("Fingerprint: "); printf("Fingerprint: ");
for(i = 0; i < 16; i++) { for(i = 0; i < 16; i++) {
printf("%02X ", (unsigned char)fingerprint[i]); printf("%02X ", (unsigned char)fingerprint[i]);
} }
printf("\n"); printf("\n");
if (auth_pw) { /* check what authentication methods are available */
/* We could authenticate via password */ userauthlist = libssh2_userauth_list(session, username, strlen(username));
if (libssh2_userauth_password(session, username, password)) { printf("Authentication methods: %s\n", userauthlist);
printf("Authentication by password failed.\n"); if (strstr(userauthlist, "password") != NULL) {
goto shutdown; auth_pw |= 1;
} }
} else { if (strstr(userauthlist, "keyboard-interactive") != NULL) {
/* Or by public key */ auth_pw |= 2;
if (libssh2_userauth_publickey_fromfile(session, username, "/home/username/.ssh/id_rsa.pub", "/home/username/.ssh/id_rsa", password)) { }
printf("\tAuthentication by public key failed\n"); if (strstr(userauthlist, "publickey") != NULL) {
goto shutdown; auth_pw |= 4;
} }
}
/* Request a shell */ /* if we got an 4. argument we set this option if supported */
if (!(channel = libssh2_channel_open_session(session))) { if(argc > 4) {
fprintf(stderr, "Unable to open a session\n"); if ((auth_pw & 1) && !strcasecmp(argv[4], "-p")) {
goto shutdown; auth_pw = 1;
} }
if ((auth_pw & 2) && !strcasecmp(argv[4], "-i")) {
auth_pw = 2;
}
if ((auth_pw & 4) && !strcasecmp(argv[4], "-k")) {
auth_pw = 4;
}
}
/* Some environment variables may be set, if (auth_pw & 1) {
* It's up to the server which ones it'll allow though /* We could authenticate via password */
*/ if (libssh2_userauth_password(session, username, password)) {
libssh2_channel_setenv(channel, (char *)"FOO", (char *)"bar"); printf("\tAuthentication by password failed!\n");
goto shutdown;
} else {
printf("\tAuthentication by password succeeded.\n");
}
} else if (auth_pw & 2) {
/* Or via keyboard-interactive */
if (libssh2_userauth_keyboard_interactive(session, username, &kbd_callback) ) {
printf("\tAuthentication by keyboard-interactive failed!\n");
goto shutdown;
} else {
printf("\tAuthentication by keyboard-interactive succeeded.\n");
}
} else if (auth_pw & 4) {
/* Or by public key */
if (libssh2_userauth_publickey_fromfile(session, username, keyfile1, keyfile2, password)) {
printf("\tAuthentication by public key failed!\n");
goto shutdown;
} else {
printf("\tAuthentication by public key succeeded.\n");
}
} else {
printf("No supported authentication methods found!\n");
goto shutdown;
}
/* Request a terminal with 'vanilla' terminal emulation /* Request a shell */
* See /etc/termcap for more options if (!(channel = libssh2_channel_open_session(session))) {
*/ fprintf(stderr, "Unable to open a session\n");
if (libssh2_channel_request_pty(channel, (char *)"vanilla")) { goto shutdown;
fprintf(stderr, "Failed requesting pty\n"); }
goto skip_shell;
}
/* Open a SHELL on that pty */ /* Some environment variables may be set,
if (libssh2_channel_shell(channel)) { * It's up to the server which ones it'll allow though
fprintf(stderr, "Unable to request shell on allocated pty\n"); */
goto shutdown; libssh2_channel_setenv(channel, "FOO", "bar");
}
/* At this point the shell can be interacted with using /* Request a terminal with 'vanilla' terminal emulation
* libssh2_channel_read() * See /etc/termcap for more options
* libssh2_channel_read_stderr() */
* libssh2_channel_write() if (libssh2_channel_request_pty(channel, "vanilla")) {
* libssh2_channel_write_stderr() fprintf(stderr, "Failed requesting pty\n");
* goto skip_shell;
* Blocking mode may be (en|dis)abled with: libssh2_channel_set_blocking() }
* If the server send EOF, libssh2_channel_eof() will return non-0
* To send EOF to the server use: libssh2_channel_send_eof()
* A channel can be closed with: libssh2_channel_close()
* A channel can be freed with: libssh2_channel_free()
*/
skip_shell: /* Open a SHELL on that pty */
if (channel) { if (libssh2_channel_shell(channel)) {
libssh2_channel_free(channel); fprintf(stderr, "Unable to request shell on allocated pty\n");
channel = NULL; goto shutdown;
} }
/* Other channel types are supported via: /* At this point the shell can be interacted with using
* libssh2_scp_send() * libssh2_channel_read()
* libssh2_scp_recv() * libssh2_channel_read_stderr()
* libssh2_channel_direct_tcpip() * libssh2_channel_write()
*/ * libssh2_channel_write_stderr()
*
* Blocking mode may be (en|dis)abled with: libssh2_channel_set_blocking()
* If the server send EOF, libssh2_channel_eof() will return non-0
* To send EOF to the server use: libssh2_channel_send_eof()
* A channel can be closed with: libssh2_channel_close()
* A channel can be freed with: libssh2_channel_free()
*/
shutdown: skip_shell:
if (channel) {
libssh2_channel_free(channel);
channel = NULL;
}
libssh2_session_disconnect(session, "Normal Shutdown, Thank you for playing"); /* Other channel types are supported via:
libssh2_session_free(session); * libssh2_scp_send()
* libssh2_scp_recv()
* libssh2_channel_direct_tcpip()
*/
shutdown:
libssh2_session_disconnect(session, "Normal Shutdown, Thank you for playing");
libssh2_session_free(session);
#ifdef WIN32 #ifdef WIN32
Sleep(1000); Sleep(1000);
closesocket(sock); closesocket(sock);
#else #else
sleep(1); sleep(1);
close(sock); close(sock);
#endif #endif
printf("all done\n"); printf("all done!\n");
return 0; return 0;
} }

View File

@@ -64,23 +64,62 @@ extern "C" {
# include <sys/uio.h> # include <sys/uio.h>
#endif #endif
#if defined(LIBSSH2_WIN32) && defined(_MSC_VER) && (_MSC_VER < 1300) #if (defined(NETWARE) && !defined(__NOVELL_LIBC__))
# include <sys/bsdskt.h>
typedef unsigned int uint32_t;
#endif
#if defined(LIBSSH2_WIN32) && defined(_MSC_VER) && (_MSC_VER <= 1400)
typedef unsigned __int64 libssh2_uint64_t; typedef unsigned __int64 libssh2_uint64_t;
typedef __int64 libssh2_int64_t; typedef __int64 libssh2_int64_t;
#if (_MSC_VER <= 1200)
typedef long ssize_t;
typedef unsigned int uint32_t; typedef unsigned int uint32_t;
#ifndef _SSIZE_T_DEFINED
typedef int ssize_t;
#define _SSIZE_T_DEFINED
#endif #endif
#else #else
typedef unsigned long long libssh2_uint64_t; typedef unsigned long long libssh2_uint64_t;
typedef long long libssh2_int64_t; typedef long long libssh2_int64_t;
#endif #endif
#define LIBSSH2_VERSION "0.15-CVS" #define LIBSSH2_VERSION "0.18.0-CVS"
#define LIBSSH2_APINO 200706151200
/* The numeric version number is also available "in parts" by using these
defines: */
#define LIBSSH2_VERSION_MAJOR 0
#define LIBSSH2_VERSION_MINOR 18
#define LIBSSH2_VERSION_PATCH 0
/* This is the numeric version of the libssh2 version number, meant for easier
parsing and comparions by programs. The LIBSSH2_VERSION_NUM define will
always follow this syntax:
0xXXYYZZ
Where XX, YY and ZZ are the main version, release and patch numbers in
hexadecimal (using 8 bits each). All three numbers are always represented
using two digits. 1.2 would appear as "0x010200" while version 9.11.7
appears as "0x090b07".
This 6-digit (24 bits) hexadecimal number does not show pre-release number,
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 0x001200
/*
* This is the date and time when the full source package was created. The
* timestamp is not stored in CVS, as the timestamp is properly set in the
* tarballs by the maketgz script.
*
* The format of the date should follow this template:
*
* "Mon Feb 12 11:35:33 UTC 2007"
*/
#define LIBSSH2_TIMESTAMP "CVS"
/* Part of every banner, user specified or not */ /* Part of every banner, user specified or not */
#define LIBSSH2_SSH_BANNER "SSH-2.0-libssh2_" LIBSSH2_VERSION #define LIBSSH2_SSH_BANNER "SSH-2.0-libssh2_" LIBSSH2_VERSION
/* We *could* add a comment here if we so chose */ /* We *could* add a comment here if we so chose */
#define LIBSSH2_SSH_DEFAULT_BANNER LIBSSH2_SSH_BANNER #define LIBSSH2_SSH_DEFAULT_BANNER LIBSSH2_SSH_BANNER
@@ -270,7 +309,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 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_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); 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), "") #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); LIBSSH2_API int libssh2_session_free(LIBSSH2_SESSION *session);
@@ -344,7 +383,7 @@ LIBSSH2_API int libssh2_channel_forward_cancel(LIBSSH2_LISTENER *listener);
LIBSSH2_API LIBSSH2_CHANNEL *libssh2_channel_forward_accept(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)) #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); 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);

73
maketgz Executable file
View File

@@ -0,0 +1,73 @@
#! /bin/sh
# Script to build release-archives with
#
version=$1
if [ -z "$version" ]; then
echo "Specify a version number!"
exit
fi
libversion="$version"
major=`echo $libversion |cut -d. -f1 | sed -e "s/[^0-9]//g"`
minor=`echo $libversion |cut -d. -f2 | sed -e "s/[^0-9]//g"`
patch=`echo $libversion |cut -d. -f3 | cut -d- -f1 | sed -e "s/[^0-9]//g"`
numeric=`perl -e 'printf("%02x%02x%02x\n", '"$major, $minor, $patch);"`
HEADER=include/libssh2.h
# requires a date command that knows -u for UTC time zone
datestamp=`date -u`
# Replace version number in header file:
sed -e 's/^#define LIBSSH2_VERSION .*/#define LIBSSH2_VERSION "'$libversion'"/g' \
-e 's/^#define LIBSSH2_VERSION_NUM .*/#define LIBSSH2_VERSION_NUM 0x'$numeric'/g' \
-e 's/^#define LIBSSH2_VERSION_MAJOR .*/#define LIBSSH2_VERSION_MAJOR '$major'/g' \
-e 's/^#define LIBSSH2_VERSION_MINOR .*/#define LIBSSH2_VERSION_MINOR '$minor'/g' \
-e 's/^#define LIBSSH2_VERSION_PATCH .*/#define LIBSSH2_VERSION_PATCH '$patch'/g' \
-e "s/^#define LIBSSH2_TIMESTAMP .*/#define LIBSSH2_TIMESTAMP \"$datestamp\"/g" \
$HEADER >$HEADER.dist
echo "libssh2 version $libversion"
echo "libssh2 numerical $numeric"
echo "datestamp $datestamp"
findprog()
{
file="$1"
for part in `echo $PATH| tr ':' ' '`; do
path="$part/$file"
if [ -x "$path" ]; then
# there it is!
return 1
fi
done
# no such executable
return 0
}
############################################################################
#
# automake is needed to run to make a non-GNU Makefile.in if Makefile.am has
# been modified.
#
if { findprog automake >/dev/null 2>/dev/null; } then
echo "- Could not find or run automake, I hope you know what you're doing!"
else
echo "Runs automake --include-deps"
automake --include-deps Makefile >/dev/null
fi
############################################################################
#
# Now run make dist to generate a tar.gz archive
#
echo "make dist"
targz="libssh2-$version.tar.gz"
make -s dist VERSION=$version

View File

@@ -5,7 +5,7 @@
## ##
## Comments to: Guenter Knauf <eflash@gmx.net> ## Comments to: Guenter Knauf <eflash@gmx.net>
## ##
## $Id: Makefile.netware,v 1.9 2007/06/20 23:44:58 gknauf Exp $ ## $Id: Makefile.netware,v 1.12 2007/07/22 00:47:21 gknauf Exp $
# #
######################################################################### #########################################################################
@@ -41,7 +41,7 @@ TARGET = libssh2
VERSION = $(LIBSSH2_VERSION) VERSION = $(LIBSSH2_VERSION)
COPYR = Copyright (c) 2004-2007 Sara Golemon <sarag@libssh2.org> COPYR = Copyright (c) 2004-2007 Sara Golemon <sarag@libssh2.org>
WWWURL = http://www.libssh2.org/ WWWURL = http://www.libssh2.org/
DESCR = libssh2 $(LIBSSH2_VERSION_STR) - $(WWWURL) DESCR = libssh2 $(LIBSSH2_VERSION_STR) ($(LIBARCH)) - $(WWWURL)
MTSAFE = YES MTSAFE = YES
STACK = 64000 STACK = 64000
SCREEN = none SCREEN = none
@@ -67,11 +67,13 @@ else
OBJDIR = debug OBJDIR = debug
endif endif
# Include the version info retrieved from libssh2.h # The following lines defines your compiler.
-include $(OBJDIR)/version.inc ifdef CWFolder
METROWERKS = $(CWFolder)
# The following line defines your compiler. endif
ifdef METROWERKS ifdef METROWERKS
# MWCW_PATH = $(subst \,/,$(METROWERKS))/Novell Support
MWCW_PATH = $(subst \,/,$(METROWERKS))/Novell Support/Metrowerks Support
CC = mwccnlm CC = mwccnlm
else else
CC = gcc CC = gcc
@@ -87,8 +89,15 @@ AWK = awk
MPKXDC = mkxdc MPKXDC = mkxdc
ZIP = zip -qzr9 ZIP = zip -qzr9
# LIBARCH_U = $(shell $(AWK) 'BEGIN {print toupper(ARGV[1])}' $(LIBARCH))
LIBARCH_L = $(shell $(AWK) 'BEGIN {print tolower(ARGV[1])}' $(LIBARCH))
# Include the version info retrieved from libssh2.h
-include $(OBJDIR)/version.inc
# Global flags for all compilers # Global flags for all compilers
CFLAGS = $(OPT) -D$(DB) -DNETWARE -nostdinc # -DHAVE_CONFIG_H CFLAGS = $(OPT) -D$(DB) -DNETWARE -nostdinc
#CFLAGS += -DHAVE_CONFIG_H
ifeq ($(CC),mwccnlm) ifeq ($(CC),mwccnlm)
LD = mwldnlm LD = mwldnlm
@@ -103,8 +112,10 @@ ifeq ($(LIBARCH),LIBC)
PRELUDE = $(SDK_LIBC)/imports/libcpre.o PRELUDE = $(SDK_LIBC)/imports/libcpre.o
CFLAGS += -align 4 CFLAGS += -align 4
else else
PRELUDE = "$(METROWERKS)/Novell Support/libraries/runtime/prelude.obj" # PRELUDE = $(SDK_CLIB)/imports/clibpre.o
# CFLAGS += -include "$(METROWERKS)/Novell Support/headers/nlm_prefix.h" # to avoid the __init_* / __deinit_* whoes dont use prelude from NDK
PRELUDE = "$(MWCW_PATH)/libraries/runtime/prelude.obj"
# CFLAGS += -include "$(MWCW_PATH)/headers/nlm_clib_prefix.h"
CFLAGS += -align 1 CFLAGS += -align 1
endif endif
else else
@@ -120,7 +131,10 @@ CFLAGS += -Wall # -pedantic
ifeq ($(LIBARCH),LIBC) ifeq ($(LIBARCH),LIBC)
PRELUDE = $(SDK_LIBC)/imports/libcpre.gcc.o PRELUDE = $(SDK_LIBC)/imports/libcpre.gcc.o
else else
PRELUDE = $(SDK_CLIB)/imports/clibpre.gcc.o # PRELUDE = $(SDK_CLIB)/imports/clibpre.gcc.o
# to avoid the __init_* / __deinit_* whoes dont use prelude from NDK
# http://www.gknw.net/development/mk_nlm/gcc_pre.zip
PRELUDE = $(NDK_ROOT)/pre/prelude.o
CFLAGS += -include $(NDKBASE)/nlmconv/genlm.h CFLAGS += -include $(NDKBASE)/nlmconv/genlm.h
endif endif
endif endif
@@ -130,34 +144,33 @@ LDLIBS =
NDK_ROOT = $(NDKBASE)/ndk NDK_ROOT = $(NDKBASE)/ndk
SDK_CLIB = $(NDK_ROOT)/nwsdk SDK_CLIB = $(NDK_ROOT)/nwsdk
SDK_LIBC = $(NDK_ROOT)/libc SDK_LIBC = $(NDK_ROOT)/libc
SDK_LDAP = $(NDK_ROOT)/cldapsdk/netware SNPRINTF = $(NDKBASE)/snprintf
INCLUDES = -I. -I../include INCLUDES = -I. -I../include
ifdef WITH_ZLIB ifdef WITH_ZLIB
INCLUDES += -I$(ZLIB_PATH) INCLUDES += -I$(ZLIB_PATH)
ifdef LINK_STATIC ifdef LINK_STATIC
LDLIBS += $(ZLIB_PATH)/nw/libz.$(LIBEXT) LDLIBS += $(ZLIB_PATH)/nw/$(LIBARCH)/libz.$(LIBEXT)
else else
MODULES += libz.nlm MODULES += libz.nlm
IMPORTS += @$(ZLIB_PATH)/nw/libz.imp IMPORTS += @$(ZLIB_PATH)/nw/$(LIBARCH)/libz.imp
endif endif
endif endif
INCLUDES += -I$(OPENSSL_PATH)/outinc_nw_libc -I$(OPENSSL_PATH)/outinc_nw_libc/openssl INCLUDES += -I$(OPENSSL_PATH)/outinc_nw_$(LIBARCH_L) -I$(OPENSSL_PATH)/outinc_nw_$(LIBARCH_L)/openssl
LDLIBS += $(OPENSSL_PATH)/out_nw_libc/ssl.$(LIBEXT) $(OPENSSL_PATH)/out_nw_libc/crypto.$(LIBEXT) LDLIBS += $(OPENSSL_PATH)/out_nw_$(LIBARCH_L)/ssl.$(LIBEXT)
LDLIBS += $(OPENSSL_PATH)/out_nw_$(LIBARCH_L)/crypto.$(LIBEXT)
IMPORTS += GetProcessSwitchCount RunningProcess IMPORTS += GetProcessSwitchCount RunningProcess
ifeq ($(LIBARCH),LIBC) ifeq ($(LIBARCH),LIBC)
INCLUDES += -I$(SDK_LIBC)/include -I$(SDK_LIBC)/include/nks INCLUDES += -I$(SDK_LIBC)/include
# INCLUDES += -I$(SDK_LIBC)/include/nks
# INCLUDES += -I$(SDK_LIBC)/include/winsock # INCLUDES += -I$(SDK_LIBC)/include/winsock
# INCLUDES += -I$(SDK_LDAP)/libc/inc
CFLAGS += -D_POSIX_SOURCE CFLAGS += -D_POSIX_SOURCE
# CFLAGS += -D__ANSIC__
else else
INCLUDES += -I$(SDK_CLIB)/include/nlm -I$(SDK_CLIB)/include INCLUDES += -I$(SDK_CLIB)/include/nlm
# INCLUDES += -I$(SDK_CLIB)/include/nlm/obsolete # INCLUDES += -I$(SDK_CLIB)/include/nlm/obsolete
# INCLUDES += -I$(SDK_LDAP)/clib/inc # INCLUDES += -I$(SDK_CLIB)/include
CFLAGS += -DNETDB_USE_INTERNET
endif endif
CFLAGS += $(INCLUDES) CFLAGS += $(INCLUDES)
@@ -199,8 +212,16 @@ OBJECTS = \
transport.o \ transport.o \
userauth.o userauth.o
ifeq ($(LIBARCH),CLIB)
# CLIB lacks of snprint() function - here's a replacement:
# http://www.ijs.si/software/snprintf/
OBJECTS += snprintf.o
vpath %.c $(SNPRINTF)
endif
OBJS := $(addprefix $(OBJDIR)/,$(OBJECTS)) OBJS := $(addprefix $(OBJDIR)/,$(OBJECTS))
OBJL = $(OBJS) $(OBJDIR)/nwlibc.o $(LDLIBS)
OBJL = $(OBJS) $(OBJDIR)/nwlib.o $(LDLIBS)
all: lib nlm all: lib nlm
@@ -212,7 +233,7 @@ prebuild: $(OBJDIR) $(OBJDIR)/version.inc libssh2_config.h
test: all test: all
$(MAKE) -C test -f Makefile.netware $(MAKE) -C test -f Makefile.netware
$(OBJDIR)/%.o: %.c $(OBJDIR)/%.o: %.c
# @echo Compiling $< # @echo Compiling $<
$(CC) $(CFLAGS) -c $< -o $@ $(CC) $(CFLAGS) -c $< -o $@
@@ -314,6 +335,7 @@ endif
ifdef XDCDATA ifdef XDCDATA
@echo $(DL)xdcdata $(XDCDATA)$(DL) >> $@ @echo $(DL)xdcdata $(XDCDATA)$(DL) >> $@
endif endif
@echo $(DL)flag_on 64$(DL) >> $@
ifeq ($(LIBARCH),CLIB) ifeq ($(LIBARCH),CLIB)
@echo $(DL)start _Prelude$(DL) >> $@ @echo $(DL)start _Prelude$(DL) >> $@
@echo $(DL)exit _Stop$(DL) >> $@ @echo $(DL)exit _Stop$(DL) >> $@
@@ -323,7 +345,6 @@ ifeq ($(LIBARCH),CLIB)
@echo $(DL)import @$(SDK_CLIB)/imports/socklib.imp$(DL) >> $@ @echo $(DL)import @$(SDK_CLIB)/imports/socklib.imp$(DL) >> $@
@echo $(DL)module clib$(DL) >> $@ @echo $(DL)module clib$(DL) >> $@
else else
@echo $(DL)flag_on 64$(DL) >> $@
@echo $(DL)pseudopreemption$(DL) >> $@ @echo $(DL)pseudopreemption$(DL) >> $@
@echo $(DL)start _LibCPrelude$(DL) >> $@ @echo $(DL)start _LibCPrelude$(DL) >> $@
@echo $(DL)exit _LibCPostlude$(DL) >> $@ @echo $(DL)exit _LibCPostlude$(DL) >> $@
@@ -353,62 +374,83 @@ libssh2_config.h: Makefile.netware
@echo $(DL)** Do not edit this file - it is created by make!$(DL) >> $@ @echo $(DL)** Do not edit this file - it is created by make!$(DL) >> $@
@echo $(DL)** All your changes will be lost!!$(DL) >> $@ @echo $(DL)** All your changes will be lost!!$(DL) >> $@
@echo $(DL)*/$(DL) >> $@ @echo $(DL)*/$(DL) >> $@
@echo $(DL)#define OS "i586-pc-NetWare"$(DL) >> $@
@echo $(DL)#define VERSION "$(LIBSSH2_VERSION_STR)"$(DL) >> $@ @echo $(DL)#define VERSION "$(LIBSSH2_VERSION_STR)"$(DL) >> $@
@echo $(DL)#define PACKAGE_BUGREPORT "http://sourceforge.net/projects/libssh2"$(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_ARPA_INET_H 1$(DL) >> $@
@echo $(DL)#define HAVE_ASSERT_H 1$(DL) >> $@ @echo $(DL)#define HAVE_ASSERT_H 1$(DL) >> $@
@echo $(DL)#define HAVE_CTYPE_H 1$(DL) >> $@ @echo $(DL)#define HAVE_CTYPE_H 1$(DL) >> $@
@echo $(DL)#define HAVE_DLFCN_H 1$(DL) >> $@
@echo $(DL)#define HAVE_DLOPEN 1$(DL) >> $@
@echo $(DL)#define HAVE_ERR_H 1$(DL) >> $@ @echo $(DL)#define HAVE_ERR_H 1$(DL) >> $@
@echo $(DL)#define HAVE_ERRNO_H 1$(DL) >> $@ @echo $(DL)#define HAVE_ERRNO_H 1$(DL) >> $@
@echo $(DL)#define HAVE_FCNTL_H 1$(DL) >> $@ @echo $(DL)#define HAVE_FCNTL_H 1$(DL) >> $@
@echo $(DL)#define HAVE_FIONBIO 1$(DL) >> $@ @echo $(DL)#define HAVE_FIONBIO 1$(DL) >> $@
@echo $(DL)#define HAVE_GETHOSTBYADDR 1$(DL) >> $@ @echo $(DL)#define HAVE_GETHOSTBYADDR 1$(DL) >> $@
@echo $(DL)#define HAVE_GETTIMEOFDAY 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_ADDR 1$(DL) >> $@
@echo $(DL)#define HAVE_INET_NTOA 1$(DL) >> $@ @echo $(DL)#define HAVE_INET_NTOA 1$(DL) >> $@
@echo $(DL)#define HAVE_INET_PTON 1$(DL) >> $@ @echo $(DL)#define HAVE_LL 1$(DL) >> $@
@echo $(DL)#define HAVE_INTTYPES_H 1$(DL) >> $@ @echo $(DL)#define HAVE_LOCALTIME_R 1$(DL) >> $@
@echo $(DL)#define HAVE_LIMITS_H 1$(DL) >> $@
@echo $(DL)#define HAVE_LONGLONG 1$(DL) >> $@
@echo $(DL)#define HAVE_MALLOC_H 1$(DL) >> $@ @echo $(DL)#define HAVE_MALLOC_H 1$(DL) >> $@
@echo $(DL)#define HAVE_MATH_H 1$(DL) >> $@
@echo $(DL)#define HAVE_NETINET_IN_H 1$(DL) >> $@ @echo $(DL)#define HAVE_NETINET_IN_H 1$(DL) >> $@
@echo $(DL)#define HAVE_SELECT 1$(DL) >> $@ @echo $(DL)#define HAVE_SELECT 1$(DL) >> $@
@echo $(DL)#define HAVE_SETJMP_H 1$(DL) >> $@ @echo $(DL)#define HAVE_SETJMP_H 1$(DL) >> $@
@echo $(DL)#define HAVE_SIGNAL 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_SOCKET 1$(DL) >> $@
@echo $(DL)#define HAVE_STDARG_H 1$(DL) >> $@
@echo $(DL)#define HAVE_STDDEF_H 1$(DL) >> $@
@echo $(DL)#define HAVE_STDINT_H 1$(DL) >> $@
@echo $(DL)#define HAVE_STDLIB_H 1$(DL) >> $@ @echo $(DL)#define HAVE_STDLIB_H 1$(DL) >> $@
@echo $(DL)#define HAVE_STRCASECMP 1$(DL) >> $@
@echo $(DL)#define HAVE_STRDUP 1$(DL) >> $@ @echo $(DL)#define HAVE_STRDUP 1$(DL) >> $@
@echo $(DL)#define HAVE_STRFTIME 1$(DL) >> $@ @echo $(DL)#define HAVE_STRFTIME 1$(DL) >> $@
@echo $(DL)#define HAVE_STRING_H 1$(DL) >> $@ @echo $(DL)#define HAVE_STRING_H 1$(DL) >> $@
@echo $(DL)#define HAVE_STRLCAT 1$(DL) >> $@
@echo $(DL)#define HAVE_STRLCPY 1$(DL) >> $@
@echo $(DL)#define HAVE_STRSTR 1$(DL) >> $@ @echo $(DL)#define HAVE_STRSTR 1$(DL) >> $@
@echo $(DL)#define HAVE_SYS_PARAM_H 1$(DL) >> $@ @echo $(DL)#define HAVE_STRUCT_ADDRINFO 1$(DL) >> $@
@echo $(DL)#define HAVE_SYS_SELECT_H 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_STAT_H 1$(DL) >> $@
@echo $(DL)#define HAVE_SYS_TIME_H 1$(DL) >> $@ @echo $(DL)#define HAVE_SYS_TIME_H 1$(DL) >> $@
@echo $(DL)#define HAVE_TERMIOS_H 1$(DL) >> $@
@echo $(DL)#define HAVE_TIME_H 1$(DL) >> $@ @echo $(DL)#define HAVE_TIME_H 1$(DL) >> $@
@echo $(DL)#define HAVE_UNAME 1$(DL) >> $@ @echo $(DL)#define HAVE_UNAME 1$(DL) >> $@
@echo $(DL)#define HAVE_UNISTD_H 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 RETSIGTYPE void$(DL) >> $@
@echo $(DL)#define SIZEOF_STRUCT_IN_ADDR 4$(DL) >> $@
@echo $(DL)#define STDC_HEADERS 1$(DL) >> $@ @echo $(DL)#define STDC_HEADERS 1$(DL) >> $@
@echo $(DL)#define TIME_WITH_SYS_TIME 1$(DL) >> $@ @echo $(DL)#define TIME_WITH_SYS_TIME 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 HAVE_STRUCT_ADDRINFO 1$(DL) >> $@
@echo $(DL)#define SIZEOF_STRUCT_IN6_ADDR 16$(DL) >> $@
@echo $(DL)#define SIZEOF_STRUCT_IN_ADDR 4$(DL) >> $@
@echo $(DL)#define USE_SSLEAY 1$(DL) >> $@ @echo $(DL)#define USE_SSLEAY 1$(DL) >> $@
@echo $(DL)#define USE_OPENSSL 1$(DL) >> $@ @echo $(DL)#define USE_OPENSSL 1$(DL) >> $@
@echo $(DL)#define HAVE_OPENSSL_X509_H 1$(DL) >> $@ @echo $(DL)#define HAVE_OPENSSL_X509_H 1$(DL) >> $@
@@ -427,9 +469,6 @@ ifdef WITH_ZLIB
@echo $(DL)#define HAVE_LIBZ 1$(DL) >> $@ @echo $(DL)#define HAVE_LIBZ 1$(DL) >> $@
@echo $(DL)#define LIBSSH2_HAVE_ZLIB 1$(DL) >> $@ @echo $(DL)#define LIBSSH2_HAVE_ZLIB 1$(DL) >> $@
endif endif
ifdef ENABLE_IPV6
@echo $(DL)#define ENABLE_IPV6 1$(DL) >> $@
endif
ifdef NW_WINSOCK ifdef NW_WINSOCK
@echo $(DL)#define HAVE_CLOSESOCKET 1$(DL) >> $@ @echo $(DL)#define HAVE_CLOSESOCKET 1$(DL) >> $@
else else
@@ -458,7 +497,11 @@ libssh2.imp: Makefile.netware
@echo $(DL)# $@ for NetWare target.$(DL) > $@ @echo $(DL)# $@ for NetWare target.$(DL) > $@
@echo $(DL)# Do not edit this file - it is created by make!$(DL) >> $@ @echo $(DL)# Do not edit this file - it is created by make!$(DL) >> $@
@echo $(DL)# All your changes will be lost!!$(DL) >> $@ @echo $(DL)# All your changes will be lost!!$(DL) >> $@
@echo $(DL) (LIBSSH2)$(DL) >> $@ ifeq ($(LIBARCH),CLIB)
@echo $(DL) (CLIB_LIBSSH2)$(DL) >> $@
else
@echo $(DL) (LIBC_LIBSSH2)$(DL) >> $@
endif
@echo $(DL) libssh2_banner_set,$(DL) >> $@ @echo $(DL) libssh2_banner_set,$(DL) >> $@
@echo $(DL) libssh2_channel_close,$(DL) >> $@ @echo $(DL) libssh2_channel_close,$(DL) >> $@
@echo $(DL) libssh2_channel_direct_tcpip_ex,$(DL) >> $@ @echo $(DL) libssh2_channel_direct_tcpip_ex,$(DL) >> $@
@@ -512,7 +555,7 @@ libssh2.imp: Makefile.netware
@echo $(DL) libssh2_userauth_list,$(DL) >> $@ @echo $(DL) libssh2_userauth_list,$(DL) >> $@
@echo $(DL) libssh2_userauth_password_ex,$(DL) >> $@ @echo $(DL) libssh2_userauth_password_ex,$(DL) >> $@
@echo $(DL) libssh2_userauth_publickey_fromfile_ex$(DL) >> $@ @echo $(DL) libssh2_userauth_publickey_fromfile_ex$(DL) >> $@
$(DISTDIR)/readme.txt: Makefile.netware $(DISTDIR)/readme.txt: Makefile.netware
@echo Creating $@ @echo Creating $@
@echo $(DL)This is a binary distribution for NetWare platform.$(DL) > $@ @echo $(DL)This is a binary distribution for NetWare platform.$(DL) > $@
@@ -531,7 +574,11 @@ $(DEVLDIR)/readme.txt: Makefile.netware
help: $(OBJDIR)/version.inc help: $(OBJDIR)/version.inc
@echo $(DL)===========================================================$(DL) @echo $(DL)===========================================================$(DL)
ifeq ($(LIBARCH),LIBC)
@echo $(DL)Novell LibC NDK = $(SDK_LIBC)$(DL) @echo $(DL)Novell LibC NDK = $(SDK_LIBC)$(DL)
else
@echo $(DL)Novell CLib NDK = $(SDK_CLIB)$(DL)
endif
@echo $(DL)OpenSSL path = $(OPENSSL_PATH)$(DL) @echo $(DL)OpenSSL path = $(OPENSSL_PATH)$(DL)
@echo $(DL)Zlib path = $(ZLIB_PATH)$(DL) @echo $(DL)Zlib path = $(ZLIB_PATH)$(DL)
@echo $(DL)===========================================================$(DL) @echo $(DL)===========================================================$(DL)

306
nw/nwlib.c Normal file
View File

@@ -0,0 +1,306 @@
/*********************************************************************
* Universal NetWare library stub. *
* written by Ulrich Neuman and given to OpenSource copyright-free. *
* Extended for CLIB support by Guenter Knauf. *
*********************************************************************
* $Id: nwlib.c,v 1.1 2007/07/09 22:50:02 gknauf Exp $ *
*********************************************************************/
#ifdef NETWARE /* Novell NetWare */
#include <stdlib.h>
#ifdef __NOVELL_LIBC__
/* For native LibC-based NLM we need to register as a real lib. */
#include <errno.h>
#include <string.h>
#include <library.h>
#include <netware.h>
#include <screen.h>
#include <nks/thread.h>
#include <nks/synch.h>
typedef struct
{
int _errno;
void *twentybytes;
} libthreaddata_t;
typedef struct
{
int x;
int y;
int z;
void *tenbytes;
NXKey_t perthreadkey; /* if -1, no key obtained... */
NXMutex_t *lock;
} libdata_t;
int gLibId = -1;
void *gLibHandle = (void *) NULL;
rtag_t gAllocTag = (rtag_t) NULL;
NXMutex_t *gLibLock = (NXMutex_t *) NULL;
/* internal library function prototypes... */
int DisposeLibraryData ( void * );
void DisposeThreadData ( void * );
int GetOrSetUpData ( int id, libdata_t **data, libthreaddata_t **threaddata );
int _NonAppStart( void *NLMHandle,
void *errorScreen,
const char *cmdLine,
const char *loadDirPath,
size_t uninitializedDataLength,
void *NLMFileHandle,
int (*readRoutineP)( int conn,
void *fileHandle, size_t offset,
size_t nbytes,
size_t *bytesRead,
void *buffer ),
size_t customDataOffset,
size_t customDataSize,
int messageCount,
const char **messages )
{
NX_LOCK_INFO_ALLOC(liblock, "Per-Application Data Lock", 0);
#ifndef __GNUC__
#pragma unused(cmdLine)
#pragma unused(loadDirPath)
#pragma unused(uninitializedDataLength)
#pragma unused(NLMFileHandle)
#pragma unused(readRoutineP)
#pragma unused(customDataOffset)
#pragma unused(customDataSize)
#pragma unused(messageCount)
#pragma unused(messages)
#endif
/*
** Here we process our command line, post errors (to the error screen),
** perform initializations and anything else we need to do before being able
** to accept calls into us. If we succeed, we return non-zero and the NetWare
** Loader will leave us up, otherwise we fail to load and get dumped.
*/
gAllocTag = AllocateResourceTag(NLMHandle,
"<library-name> memory allocations", AllocSignature);
if (!gAllocTag) {
OutputToScreen(errorScreen, "Unable to allocate resource tag for "
"library memory allocations.\n");
return -1;
}
gLibId = register_library(DisposeLibraryData);
if (gLibId < -1) {
OutputToScreen(errorScreen, "Unable to register library with kernel.\n");
return -1;
}
gLibHandle = NLMHandle;
gLibLock = NXMutexAlloc(0, 0, &liblock);
if (!gLibLock) {
OutputToScreen(errorScreen, "Unable to allocate library data lock.\n");
return -1;
}
return 0;
}
/*
** Here we clean up any resources we allocated. Resource tags is a big part
** of what we created, but NetWare doesn't ask us to free those.
*/
void _NonAppStop( void )
{
(void) unregister_library(gLibId);
NXMutexFree(gLibLock);
}
/*
** This function cannot be the first in the file for if the file is linked
** first, then the check-unload function's offset will be nlmname.nlm+0
** which is how to tell that there isn't one. When the check function is
** first in the linked objects, it is ambiguous. For this reason, we will
** put it inside this file after the stop function.
**
** Here we check to see if it's alright to ourselves to be unloaded. If not,
** we return a non-zero value. Right now, there isn't any reason not to allow
** it.
*/
int _NonAppCheckUnload( void )
{
return 0;
}
int GetOrSetUpData(int id, libdata_t **appData, libthreaddata_t **threadData)
{
int err;
libdata_t *app_data;
libthreaddata_t *thread_data;
NXKey_t key;
NX_LOCK_INFO_ALLOC(liblock, "Application Data Lock", 0);
err = 0;
thread_data = (libthreaddata_t *) NULL;
/*
** Attempt to get our data for the application calling us. This is where we
** store whatever application-specific information we need to carry in support
** of calling applications.
*/
app_data = (libdata_t *) get_app_data(id);
if (!app_data) {
/*
** This application hasn't called us before; set up application AND per-thread
** data. Of course, just in case a thread from this same application is calling
** us simultaneously, we better lock our application data-creation mutex. We
** also need to recheck for data after we acquire the lock because WE might be
** that other thread that was too late to create the data and the first thread
** in will have created it.
*/
NXLock(gLibLock);
if (!(app_data = (libdata_t *) get_app_data(id))) {
app_data = (libdata_t *) malloc(sizeof(libdata_t));
if (app_data) {
memset(app_data, 0, sizeof(libdata_t));
app_data->tenbytes = malloc(10);
app_data->lock = NXMutexAlloc(0, 0, &liblock);
if (!app_data->tenbytes || !app_data->lock) {
if (app_data->lock)
NXMutexFree(app_data->lock);
free(app_data);
app_data = (libdata_t *) NULL;
err = ENOMEM;
}
if (app_data) {
/*
** Here we burn in the application data that we were trying to get by calling
** get_app_data(). Next time we call the first function, we'll get this data
** we're just now setting. We also go on here to establish the per-thread data
** for the calling thread, something we'll have to do on each application
** thread the first time it calls us.
*/
err = set_app_data(gLibId, app_data);
if (err) {
free(app_data);
app_data = (libdata_t *) NULL;
err = ENOMEM;
}
else {
/* create key for thread-specific data... */
err = NXKeyCreate(DisposeThreadData, (void *) NULL, &key);
if (err) /* (no more keys left?) */
key = -1;
app_data->perthreadkey = key;
}
}
}
}
NXUnlock(gLibLock);
}
if (app_data) {
key = app_data->perthreadkey;
if (key != -1 /* couldn't create a key? no thread data */
&& !(err = NXKeyGetValue(key, (void **) &thread_data))
&& !thread_data) {
/*
** Allocate the per-thread data for the calling thread. Regardless of whether
** there was already application data or not, this may be the first call by a
** a new thread. The fact that we allocation 20 bytes on a pointer is not very
** important, this just helps to demonstrate that we can have arbitrarily
** complex per-thread data.
*/
thread_data = (libthreaddata_t *) malloc(sizeof(libthreaddata_t));
if (thread_data) {
thread_data->_errno = 0;
thread_data->twentybytes = malloc(20);
if (!thread_data->twentybytes) {
free(thread_data);
thread_data = (libthreaddata_t *) NULL;
err = ENOMEM;
}
if ((err = NXKeySetValue(key, thread_data))) {
free(thread_data->twentybytes);
free(thread_data);
thread_data = (libthreaddata_t *) NULL;
}
}
}
}
if (appData)
*appData = app_data;
if (threadData)
*threadData = thread_data;
return err;
}
int DisposeLibraryData( void *data )
{
if (data) {
void *tenbytes = ((libdata_t *) data)->tenbytes;
if (tenbytes)
free(tenbytes);
free(data);
}
return 0;
}
void DisposeThreadData( void *data )
{
if (data) {
void *twentybytes = ((libthreaddata_t *) data)->twentybytes;
if (twentybytes)
free(twentybytes);
free(data);
}
}
#else /* __NOVELL_LIBC__ */
/* For native CLib-based NLM seems we can do a bit more simple. */
#include <nwthread.h>
int main ( void )
{
/* initialize any globals here... */
/* do this if any global initializing was done
SynchronizeStart();
*/
ExitThread (TSR_THREAD, 0);
return 0;
}
#endif /* __NOVELL_LIBC__ */
#endif /* NETWARE */

View File

@@ -1,309 +0,0 @@
/*********************************************************************
* Universal NetWare library stub. *
* written by Ulrich Neuman and given to OpenSource copyright-free. *
* version: 1.0 *
*********************************************************************/
#include <errno.h>
#include <string.h>
#include <stdlib.h>
#include <library.h>
#include <netware.h>
#include <screen.h>
#include <nks/thread.h>
#include <nks/synch.h>
typedef struct
{
int _errno;
void *twentybytes;
} libthreaddata_t;
typedef struct
{
int x;
int y;
int z;
void *tenbytes;
NXKey_t perthreadkey; /* if -1, no key obtained... */
NXMutex_t *lock;
} libdata_t;
int gLibId = -1;
void *gLibHandle = (void *) NULL;
rtag_t gAllocTag = (rtag_t) NULL;
NXMutex_t *gLibLock = (NXMutex_t *) NULL;
/* internal library function prototypes... */
int DisposeLibraryData ( void * );
void DisposeThreadData ( void * );
int GetOrSetUpData ( int id, libdata_t **data, libthreaddata_t **threaddata );
int _NonAppStart
(
void *NLMHandle,
void *errorScreen,
const char *cmdLine,
const char *loadDirPath,
size_t uninitializedDataLength,
void *NLMFileHandle,
int (*readRoutineP)( int conn, void *fileHandle, size_t offset,
size_t nbytes, size_t *bytesRead, void *buffer ),
size_t customDataOffset,
size_t customDataSize,
int messageCount,
const char **messages
)
{
NX_LOCK_INFO_ALLOC(liblock, "Per-Application Data Lock", 0);
#ifndef __GNUC__
#pragma unused(cmdLine)
#pragma unused(loadDirPath)
#pragma unused(uninitializedDataLength)
#pragma unused(NLMFileHandle)
#pragma unused(readRoutineP)
#pragma unused(customDataOffset)
#pragma unused(customDataSize)
#pragma unused(messageCount)
#pragma unused(messages)
#endif
/*
** Here we process our command line, post errors (to the error screen),
** perform initializations and anything else we need to do before being able
** to accept calls into us. If we succeed, we return non-zero and the NetWare
** Loader will leave us up, otherwise we fail to load and get dumped.
*/
gAllocTag = AllocateResourceTag(NLMHandle,
"<library-name> memory allocations", AllocSignature);
if (!gAllocTag)
{
OutputToScreen(errorScreen, "Unable to allocate resource tag for "
"library memory allocations.\n");
return -1;
}
gLibId = register_library(DisposeLibraryData);
if (gLibId < -1)
{
OutputToScreen(errorScreen, "Unable to register library with kernel.\n");
return -1;
}
gLibHandle = NLMHandle;
gLibLock = NXMutexAlloc(0, 0, &liblock);
if (!gLibLock)
{
OutputToScreen(errorScreen, "Unable to allocate library data lock.\n");
return -1;
}
return 0;
}
/*
** Here we clean up any resources we allocated. Resource tags is a big part
** of what we created, but NetWare doesn't ask us to free those.
*/
void _NonAppStop( void )
{
(void) unregister_library(gLibId);
NXMutexFree(gLibLock);
}
/*
** This function cannot be the first in the file for if the file is linked
** first, then the check-unload function's offset will be nlmname.nlm+0
** which is how to tell that there isn't one. When the check function is
** first in the linked objects, it is ambiguous. For this reason, we will
** put it inside this file after the stop function.
**
** Here we check to see if it's alright to ourselves to be unloaded. If not,
** we return a non-zero value. Right now, there isn't any reason not to allow
** it.
*/
int _NonAppCheckUnload( void )
{
return 0;
}
int GetOrSetUpData
(
int id,
libdata_t **appData,
libthreaddata_t **threadData
)
{
int err;
libdata_t *app_data;
libthreaddata_t *thread_data;
NXKey_t key;
NX_LOCK_INFO_ALLOC(liblock, "Application Data Lock", 0);
err = 0;
thread_data = (libthreaddata_t *) NULL;
/*
** Attempt to get our data for the application calling us. This is where we
** store whatever application-specific information we need to carry in support
** of calling applications.
*/
app_data = (libdata_t *) get_app_data(id);
if (!app_data)
{
/*
** This application hasn't called us before; set up application AND per-thread
** data. Of course, just in case a thread from this same application is calling
** us simultaneously, we better lock our application data-creation mutex. We
** also need to recheck for data after we acquire the lock because WE might be
** that other thread that was too late to create the data and the first thread
** in will have created it.
*/
NXLock(gLibLock);
if (!(app_data = (libdata_t *) get_app_data(id)))
{
app_data = (libdata_t *) malloc(sizeof(libdata_t));
if (app_data)
{
memset(app_data, 0, sizeof(libdata_t));
app_data->tenbytes = malloc(10);
app_data->lock = NXMutexAlloc(0, 0, &liblock);
if (!app_data->tenbytes || !app_data->lock)
{
if (app_data->lock)
NXMutexFree(app_data->lock);
free(app_data);
app_data = (libdata_t *) NULL;
err = ENOMEM;
}
if (app_data)
{
/*
** Here we burn in the application data that we were trying to get by calling
** get_app_data(). Next time we call the first function, we'll get this data
** we're just now setting. We also go on here to establish the per-thread data
** for the calling thread, something we'll have to do on each application
** thread the first time it calls us.
*/
err = set_app_data(gLibId, app_data);
if (err)
{
free(app_data);
app_data = (libdata_t *) NULL;
err = ENOMEM;
}
else
{
/* create key for thread-specific data... */
err = NXKeyCreate(DisposeThreadData, (void *) NULL, &key);
if (err) /* (no more keys left?) */
key = -1;
app_data->perthreadkey = key;
}
}
}
}
NXUnlock(gLibLock);
}
if (app_data)
{
key = app_data->perthreadkey;
if ( key != -1 /* couldn't create a key? no thread data */
&& !(err = NXKeyGetValue(key, (void **) &thread_data))
&& !thread_data)
{
/*
** Allocate the per-thread data for the calling thread. Regardless of whether
** there was already application data or not, this may be the first call by a
** a new thread. The fact that we allocation 20 bytes on a pointer is not very
** important, this just helps to demonstrate that we can have arbitrarily
** complex per-thread data.
*/
thread_data = (libthreaddata_t *) malloc(sizeof(libthreaddata_t));
if (thread_data)
{
thread_data->_errno = 0;
thread_data->twentybytes = malloc(20);
if (!thread_data->twentybytes)
{
free(thread_data);
thread_data = (libthreaddata_t *) NULL;
err = ENOMEM;
}
if ((err = NXKeySetValue(key, thread_data)))
{
free(thread_data->twentybytes);
free(thread_data);
thread_data = (libthreaddata_t *) NULL;
}
}
}
}
if (appData)
*appData = app_data;
if (threadData)
*threadData = thread_data;
return err;
}
int DisposeLibraryData
(
void *data
)
{
if (data)
{
void *tenbytes = ((libdata_t *) data)->tenbytes;
if (tenbytes)
free(tenbytes);
free(data);
}
return 0;
}
void DisposeThreadData
(
void *data
)
{
if (data)
{
void *twentybytes = ((libthreaddata_t *) data)->twentybytes;
if (twentybytes)
free(twentybytes);
free(data);
}
}

View File

@@ -5,7 +5,7 @@
## ##
## Comments to: Guenter Knauf <eflash@gmx.net> ## Comments to: Guenter Knauf <eflash@gmx.net>
## ##
## $Id: Makefile.netware,v 1.5 2007/04/21 21:26:54 gknauf Exp $ ## $Id: Makefile.netware,v 1.8 2007/08/08 16:32:42 gknauf Exp $
# #
######################################################################### #########################################################################
@@ -28,17 +28,18 @@ endif
LINK_STATIC = 1 LINK_STATIC = 1
# Edit the vars below to change NLM target settings. # Edit the vars below to change NLM target settings.
TARGETS = scp.nlm sftp.nlm sftpdir.nlm ssh2.nlm SAMPLES = ../../example/simple
TARGETS := $(patsubst $(SAMPLES)/%.c,%.nlm,$(strip $(wildcard $(SAMPLES)/*.c)))
VERSION = $(LIBSSH2_VERSION) VERSION = $(LIBSSH2_VERSION)
COPYR = Copyright (c) 2004-2007, Sara Golemon <sarag@libssh2.org> COPYR = Copyright (c) 2004-2007, Sara Golemon <sarag@libssh2.org>
WWWURL = http://www.libssh2.org/ WWWURL = http://www.libssh2.org/
DESCR = libssh2 $(notdir $(@:.def=)) $(LIBSSH2_VERSION_STR) - $(WWWURL) DESCR = libssh2 $(notdir $(@:.def=)) $(LIBSSH2_VERSION_STR) ($(LIBARCH)) - $(WWWURL)
MTSAFE = YES MTSAFE = YES
STACK = 64000 STACK = 64000
SCREEN = NONE SCREEN = NONE
#SCREEN = libssh2 $(notdir $(@:.def=)) #SCREEN = libssh2 $(notdir $(@:.def=))
# Comment the line below if you dont want to load protected automatically. # Comment the line below if you dont want to load protected automatically.
LDRING = 3 #LDRING = 3
# Edit the var below to point to your lib architecture. # Edit the var below to point to your lib architecture.
ifndef LIBARCH ifndef LIBARCH
@@ -56,14 +57,17 @@ ifeq ($(DB),NDEBUG)
OBJDIR = release OBJDIR = release
else else
OPT = -g OPT = -g
OPT += -DLIBSSH2DEBUG
OBJDIR = debug OBJDIR = debug
endif endif
# Include the version info retrieved from xml2ver.h # The following lines defines your compiler.
-include $(OBJDIR)/version.inc ifdef CWFolder
METROWERKS = $(CWFolder)
# The following line defines your compiler. endif
ifdef METROWERKS ifdef METROWERKS
# MWCW_PATH = $(subst \,/,$(METROWERKS))/Novell Support
MWCW_PATH = $(subst \,/,$(METROWERKS))/Novell Support/Metrowerks Support
CC = mwccnlm CC = mwccnlm
else else
CC = gcc CC = gcc
@@ -78,8 +82,14 @@ AWK = awk
# http://www.gknw.net/development/prgtools/mkxdc.zip # http://www.gknw.net/development/prgtools/mkxdc.zip
MPKXDC = mkxdc MPKXDC = mkxdc
# LIBARCH_U = $(shell $(AWK) 'BEGIN {print toupper(ARGV[1])}' $(LIBARCH))
LIBARCH_L = $(shell $(AWK) 'BEGIN {print tolower(ARGV[1])}' $(LIBARCH))
# Include the version info retrieved from libssh2.h
-include $(OBJDIR)/version.inc
# Global flags for all compilers # Global flags for all compilers
CFLAGS = $(OPT) -D$(DB) -DNETWARE -nostdinc # -DHAVE_CONFIG_H CFLAGS = $(OPT) -D$(DB) -DNETWARE -nostdinc
ifeq ($(CC),mwccnlm) ifeq ($(CC),mwccnlm)
LD = mwldnlm LD = mwldnlm
@@ -94,8 +104,10 @@ ifeq ($(LIBARCH),LIBC)
PRELUDE = $(SDK_LIBC)/imports/libcpre.o PRELUDE = $(SDK_LIBC)/imports/libcpre.o
CFLAGS += -align 4 CFLAGS += -align 4
else else
PRELUDE = "$(METROWERKS)/Novell Support/libraries/runtime/prelude.obj" # PRELUDE = $(SDK_CLIB)/imports/clibpre.o
# CFLAGS += -include "$(METROWERKS)/Novell Support/headers/nlm_prefix.h" # to avoid the __init_* / __deinit_* whoes dont use prelude from NDK
PRELUDE = "$(MWCW_PATH)/libraries/runtime/prelude.obj"
# CFLAGS += -include "$(MWCW_PATH)/headers/nlm_clib_prefix.h"
CFLAGS += -align 1 CFLAGS += -align 1
endif endif
else else
@@ -117,16 +129,27 @@ endif
NDK_ROOT = $(NDKBASE)/ndk NDK_ROOT = $(NDKBASE)/ndk
SDK_CLIB = $(NDK_ROOT)/nwsdk SDK_CLIB = $(NDK_ROOT)/nwsdk
SDK_LIBC = $(NDK_ROOT)/libc SDK_LIBC = $(NDK_ROOT)/libc
SDK_LDAP = $(NDK_ROOT)/cldapsdk/netware SNPRINTF = $(NDKBASE)/snprintf
INCLUDES = -I. -I.. -I../../include INCLUDES = -I. -I../../include
LDLIBS = LDLIBS =
INCLUDES += -I$(OPENSSL_PATH)/outinc_nw_libc -I$(OPENSSL_PATH)/outinc_nw_libc/openssl INCLUDES += -I$(OPENSSL_PATH)/outinc_nw_$(LIBARCH_L) -I$(OPENSSL_PATH)/outinc_nw_$(LIBARCH_L)/openssl
LDLIBS += $(OPENSSL_PATH)/out_nw_libc/ssl.$(LIBEXT) $(OPENSSL_PATH)/out_nw_libc/crypto.$(LIBEXT) LDLIBS += $(OPENSSL_PATH)/out_nw_$(LIBARCH_L)/ssl.$(LIBEXT)
LDLIBS += $(OPENSSL_PATH)/out_nw_$(LIBARCH_L)/crypto.$(LIBEXT)
IMPORTS += GetProcessSwitchCount RunningProcess IMPORTS += GetProcessSwitchCount RunningProcess
ifdef WITH_ZLIB
INCLUDES += -I$(ZLIB_PATH)
ifdef LINK_STATIC
LDLIBS += $(ZLIB_PATH)/nw/$(LIBARCH)/libz.$(LIBEXT)
else
MODULES += libz.nlm
IMPORTS += @$(ZLIB_PATH)/nw/$(LIBARCH)/libz.imp
endif
endif
ifdef LINK_STATIC ifdef LINK_STATIC
LDLIBS += ../libssh2.$(LIBEXT) LDLIBS += ../libssh2.$(LIBEXT)
else else
@@ -134,27 +157,16 @@ else
MODULES += libssh2.nlm MODULES += libssh2.nlm
endif endif
ifdef WITH_ZLIB
INCLUDES += -I$(ZLIB_PATH)
ifdef LINK_STATIC
LDLIBS += $(ZLIB_PATH)/nw/libz.$(LIBEXT)
else
IMPORTS += @$(ZLIB_PATH)/nw/libz.imp
MODULES += libz.nlm
endif
endif
ifeq ($(LIBARCH),LIBC) ifeq ($(LIBARCH),LIBC)
INCLUDES += -I$(SDK_LIBC)/include -I$(SDK_LIBC)/include/nks INCLUDES += -I$(SDK_LIBC)/include
# INCLUDES += -I$(SDK_LIBC)/include/nks
# INCLUDES += -I$(SDK_LIBC)/include/winsock # INCLUDES += -I$(SDK_LIBC)/include/winsock
# INCLUDES += -I$(SDK_LDAP)/libc/inc
CFLAGS += -D_POSIX_SOURCE CFLAGS += -D_POSIX_SOURCE
# CFLAGS += -D__ANSIC__
else else
INCLUDES += -I$(SDK_CLIB)/include/nlm -I$(SDK_CLIB)/include INCLUDES += -I$(SDK_CLIB)/include/nlm
# INCLUDES += -I$(SDK_CLIB)/include/nlm/obsolete # INCLUDES += -I$(SDK_CLIB)/include/nlm/obsolete
# INCLUDES += -I$(SDK_LDAP)/clib/inc # INCLUDES += -I$(SDK_CLIB)/include
CFLAGS += -DNETDB_USE_INTERNET # CFLAGS += -DNETDB_USE_INTERNET
endif endif
CFLAGS += $(INCLUDES) CFLAGS += $(INCLUDES)
@@ -167,17 +179,16 @@ endif
ifeq ($(findstring linux,$(OSTYPE)),linux) ifeq ($(findstring linux,$(OSTYPE)),linux)
DL = ' DL = '
#-include $(NDKBASE)/nlmconv/ncpfs.inc
endif endif
vpath %.c ../../example/simple vpath %.c $(SAMPLES)
.PRECIOUS: $(OBJDIR)/%.o $(OBJDIR)/%.def $(OBJDIR)/%.xdc .PRECIOUS: $(OBJDIR)/%.o $(OBJDIR)/%.def $(OBJDIR)/%.xdc
all: prebuild $(TARGETS) all: prebuild $(TARGETS)
prebuild: $(OBJDIR) $(OBJDIR)/version.inc prebuild: $(OBJDIR) $(OBJDIR)/version.inc config.h
$(OBJDIR)/%.o: %.c $(OBJDIR)/%.o: %.c
# @echo Compiling $< # @echo Compiling $<
@@ -273,6 +284,130 @@ endif
@echo $(DL)output $(notdir $(@:.def=.nlm))$(DL) >> $@ @echo $(DL)output $(notdir $(@:.def=.nlm))$(DL) >> $@
endif 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 help: $(OBJDIR)/version.inc
@echo $(DL)===========================================================$(DL) @echo $(DL)===========================================================$(DL)
@echo $(DL)OpenSSL path = $(OPENSSL_PATH)$(DL) @echo $(DL)OpenSSL path = $(OPENSSL_PATH)$(DL)

View File

@@ -1,4 +1,4 @@
# $Id: Makefile.am,v 1.9 2007/04/05 10:23:55 jas4711 Exp $ # $Id: Makefile.am,v 1.10 2007/07/17 13:22:55 gknauf Exp $
AUTOMAKE_OPTIONS = foreign nostdinc AUTOMAKE_OPTIONS = foreign nostdinc
libssh2_la_SOURCES = channel.c comp.c crypt.c hostkey.c kex.c mac.c \ libssh2_la_SOURCES = channel.c comp.c crypt.c hostkey.c kex.c mac.c \
@@ -11,7 +11,7 @@ else
libssh2_la_SOURCES += openssl.c libssh2_la_SOURCES += openssl.c
endif endif
EXTRA_DIST = libssh2_config.h.in EXTRA_DIST = libssh2_config.h.in NMakefile
lib_LTLIBRARIES = libssh2.la lib_LTLIBRARIES = libssh2.la

View File

@@ -2,10 +2,23 @@
CFLAGS=$(CFLAGS) CFLAGS=$(CFLAGS)
OBJECTS = $(INTDIR)\channel.obj $(INTDIR)\comp.obj $(INTDIR)\crypt.obj \ OBJECTS = \
$(INTDIR)\hostkey.obj $(INTDIR)\kex.obj $(INTDIR)\mac.obj \ $(INTDIR)\channel.obj \
$(INTDIR)\misc.obj $(INTDIR)\packet.obj $(INTDIR)\scp.obj \ $(INTDIR)\comp.obj \
$(INTDIR)\session.obj $(INTDIR)\sftp.obj $(INTDIR)\userauth.obj $(INTDIR)\crypt.obj \
$(INTDIR)\hostkey.obj \
$(INTDIR)\kex.obj \
$(INTDIR)\mac.obj \
$(INTDIR)\misc.obj \
$(INTDIR)\openssl.obj \
$(INTDIR)\packet.obj \
$(INTDIR)\pem.obj \
$(INTDIR)\publickey.obj \
$(INTDIR)\scp.obj \
$(INTDIR)\session.obj \
$(INTDIR)\sftp.obj \
$(INTDIR)\transport.obj \
$(INTDIR)\userauth.obj
DLL=libssh2$(SUFFIX).dll DLL=libssh2$(SUFFIX).dll

File diff suppressed because it is too large Load Diff

View File

@@ -47,27 +47,28 @@
/* {{{ libssh2_comp_method_none_comp /* {{{ libssh2_comp_method_none_comp
* Minimalist compression: Absolutely none * Minimalist compression: Absolutely none
*/ */
static int libssh2_comp_method_none_comp(LIBSSH2_SESSION *session, static int
int compress, libssh2_comp_method_none_comp(LIBSSH2_SESSION * session,
unsigned char **dest, int compress,
unsigned long *dest_len, unsigned char **dest,
unsigned long payload_limit, unsigned long *dest_len,
int *free_dest, unsigned long payload_limit,
const unsigned char *src, int *free_dest,
unsigned long src_len, const unsigned char *src,
void **abstract) unsigned long src_len, void **abstract)
{ {
(void)session; (void) session;
(void)compress; (void) compress;
(void)payload_limit; (void) payload_limit;
(void)abstract; (void) abstract;
*dest = (unsigned char *)src; *dest = (unsigned char *) src;
*dest_len = src_len; *dest_len = src_len;
*free_dest = 0; *free_dest = 0;
return 0; return 0;
} }
/* }}} */ /* }}} */
static const LIBSSH2_COMP_METHOD libssh2_comp_method_none = { static const LIBSSH2_COMP_METHOD libssh2_comp_method_none = {
@@ -87,39 +88,46 @@ static const LIBSSH2_COMP_METHOD libssh2_comp_method_none = {
* Deal... * 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; LIBSSH2_SESSION *session = (LIBSSH2_SESSION *) opaque;
return (voidpf)LIBSSH2_ALLOC(session, items * size); 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_SESSION *session = (LIBSSH2_SESSION *) opaque;
LIBSSH2_FREE(session, address); LIBSSH2_FREE(session, address);
} }
/* }}} */ /* }}} */
/* {{{ libssh2_comp_method_zlib_init /* {{{ libssh2_comp_method_zlib_init
* All your bandwidth are belong to us (so save some) * 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; z_stream *strm;
int status; int status;
strm = LIBSSH2_ALLOC(session, sizeof(z_stream)); strm = LIBSSH2_ALLOC(session, sizeof(z_stream));
if (!strm) { 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; return -1;
} }
memset(strm, 0, sizeof(z_stream)); memset(strm, 0, sizeof(z_stream));
strm->opaque = (voidpf)session; strm->opaque = (voidpf) session;
strm->zalloc = (alloc_func)libssh2_comp_method_zlib_alloc; strm->zalloc = (alloc_func) libssh2_comp_method_zlib_alloc;
strm->zfree = (free_func)libssh2_comp_method_zlib_free; strm->zfree = (free_func) libssh2_comp_method_zlib_free;
if (compress) { if (compress) {
/* deflate */ /* deflate */
status = deflateInit(strm, Z_DEFAULT_COMPRESSION); status = deflateInit(strm, Z_DEFAULT_COMPRESSION);
@@ -136,20 +144,21 @@ static int libssh2_comp_method_zlib_init(LIBSSH2_SESSION *session, int compress,
return 0; return 0;
} }
/* }}} */ /* }}} */
/* {{{ libssh2_comp_method_zlib_comp /* {{{ libssh2_comp_method_zlib_comp
* zlib, a compression standard for all occasions * zlib, a compression standard for all occasions
*/ */
static int libssh2_comp_method_zlib_comp(LIBSSH2_SESSION *session, static int
int compress, libssh2_comp_method_zlib_comp(LIBSSH2_SESSION * session,
unsigned char **dest, int compress,
unsigned long *dest_len, unsigned char **dest,
unsigned long payload_limit, unsigned long *dest_len,
int *free_dest, unsigned long payload_limit,
const unsigned char *src, int *free_dest,
unsigned long src_len, const unsigned char *src,
void **abstract) unsigned long src_len, void **abstract)
{ {
z_stream *strm = *abstract; z_stream *strm = *abstract;
/* A short-term alloc of a full data chunk is better than a series of /* A short-term alloc of a full data chunk is better than a series of
@@ -163,17 +172,19 @@ static int libssh2_comp_method_zlib_comp(LIBSSH2_SESSION *session,
out_maxlen = 25; out_maxlen = 25;
} }
if (out_maxlen > (int)payload_limit) { if (out_maxlen > (int) payload_limit) {
out_maxlen = payload_limit; out_maxlen = payload_limit;
} }
strm->next_in = (unsigned char *)src; strm->next_in = (unsigned char *) src;
strm->avail_in = src_len; strm->avail_in = src_len;
strm->next_out = (unsigned char *)LIBSSH2_ALLOC(session, out_maxlen); strm->next_out = (unsigned char *) LIBSSH2_ALLOC(session, out_maxlen);
out = (char *)strm->next_out; out = (char *) strm->next_out;
strm->avail_out = out_maxlen; strm->avail_out = out_maxlen;
if (!strm->next_out) { 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; return -1;
} }
while (strm->avail_in) { while (strm->avail_in) {
@@ -185,7 +196,8 @@ static int libssh2_comp_method_zlib_comp(LIBSSH2_SESSION *session,
status = inflate(strm, Z_PARTIAL_FLUSH); status = inflate(strm, Z_PARTIAL_FLUSH);
} }
if (status != Z_OK) { 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); LIBSSH2_FREE(session, out);
return -1; return -1;
} }
@@ -193,80 +205,92 @@ static int libssh2_comp_method_zlib_comp(LIBSSH2_SESSION *session,
unsigned long out_ofs = out_maxlen - strm->avail_out; unsigned long out_ofs = out_maxlen - strm->avail_out;
char *newout; 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) && if ((out_maxlen > (int) payload_limit) && !compress && limiter++) {
!compress && limiter++) {
libssh2_error(session, LIBSSH2_ERROR_ZLIB, libssh2_error(session, LIBSSH2_ERROR_ZLIB,
"Excessive growth in decompression phase", 0); "Excessive growth in decompression phase", 0);
LIBSSH2_FREE(session, out); LIBSSH2_FREE(session, out);
return -1; return -1;
} }
newout = LIBSSH2_REALLOC(session, out, out_maxlen); newout = LIBSSH2_REALLOC(session, out, out_maxlen);
if (!newout) { 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); LIBSSH2_FREE(session, out);
return -1; return -1;
} }
out = newout; out = newout;
strm->next_out = (unsigned char *)out + out_ofs; strm->next_out = (unsigned char *) out + out_ofs;
strm->avail_out += compress ? (strm->avail_in + 4) : (2 * strm->avail_in); strm->avail_out +=
} else while (!strm->avail_out) { compress ? (strm->avail_in + 4) : (2 * strm->avail_in);
/* Done with input, might be a byte or two in internal buffer during compress } else
* Or potentially many bytes if it's a decompress while (!strm->avail_out) {
*/ /* Done with input, might be a byte or two in internal buffer during compress
int grow_size = compress ? 8 : 1024; * Or potentially many bytes if it's a decompress
char *newout; */
int grow_size = compress ? 8 : 1024;
char *newout;
if (out_maxlen >= (int)payload_limit) { if (out_maxlen >= (int) payload_limit) {
libssh2_error(session, LIBSSH2_ERROR_ZLIB, "Excessive growth in decompression phase", 0); libssh2_error(session, LIBSSH2_ERROR_ZLIB,
LIBSSH2_FREE(session, out); "Excessive growth in decompression phase",
return -1; 0);
} LIBSSH2_FREE(session, out);
return -1;
}
if (grow_size > (int)(payload_limit - out_maxlen)) { if (grow_size > (int) (payload_limit - out_maxlen)) {
grow_size = payload_limit - out_maxlen; grow_size = payload_limit - out_maxlen;
} }
out_maxlen += grow_size; out_maxlen += grow_size;
strm->avail_out = grow_size; strm->avail_out = grow_size;
newout = LIBSSH2_REALLOC(session, out, out_maxlen); newout = LIBSSH2_REALLOC(session, out, out_maxlen);
if (!newout) { if (!newout) {
libssh2_error(session, LIBSSH2_ERROR_ALLOC, "Unable to expand final compress/decompress buffer", 0); libssh2_error(session, LIBSSH2_ERROR_ALLOC,
LIBSSH2_FREE(session, out); "Unable to expand final compress/decompress buffer",
return -1; 0);
} LIBSSH2_FREE(session, out);
out = newout; return -1;
strm->next_out = (unsigned char *)out + out_maxlen - }
grow_size; out = newout;
strm->next_out = (unsigned char *) out + out_maxlen -
grow_size;
if (compress) { if (compress) {
status = deflate(strm, Z_PARTIAL_FLUSH); status = deflate(strm, Z_PARTIAL_FLUSH);
} else { } else {
status = inflate(strm, Z_PARTIAL_FLUSH); status = inflate(strm, Z_PARTIAL_FLUSH);
}
if (status != Z_OK) {
libssh2_error(session, LIBSSH2_ERROR_ZLIB,
"compress/decompression failure", 0);
LIBSSH2_FREE(session, out);
return -1;
}
} }
if (status != Z_OK) {
libssh2_error(session, LIBSSH2_ERROR_ZLIB, "compress/decompression failure", 0);
LIBSSH2_FREE(session, out);
return -1;
}
}
} }
*dest = (unsigned char *)out; *dest = (unsigned char *) out;
*dest_len = out_maxlen - strm->avail_out; *dest_len = out_maxlen - strm->avail_out;
*free_dest = 1; *free_dest = 1;
return 0; return 0;
} }
/* }}} */ /* }}} */
/* {{{ libssh2_comp_method_zlib_dtor /* {{{ libssh2_comp_method_zlib_dtor
* All done, no more compression for you * 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; z_stream *strm = *abstract;
@@ -286,6 +310,7 @@ static int libssh2_comp_method_zlib_dtor(LIBSSH2_SESSION *session, int compress,
return 0; return 0;
} }
/* }}} */ /* }}} */
static const LIBSSH2_COMP_METHOD libssh2_comp_method_zlib = { static const LIBSSH2_COMP_METHOD libssh2_comp_method_zlib = {
@@ -308,7 +333,8 @@ static const LIBSSH2_COMP_METHOD *_libssh2_comp_methods[] = {
NULL NULL
}; };
const LIBSSH2_COMP_METHOD **libssh2_comp_methods(void) { const LIBSSH2_COMP_METHOD **
libssh2_comp_methods(void)
{
return _libssh2_comp_methods; return _libssh2_comp_methods;
} }

View File

@@ -41,47 +41,51 @@
/* {{{ libssh2_crypt_none_crypt /* {{{ libssh2_crypt_none_crypt
* Minimalist cipher: VERY secure *wink* * 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! */ /* Do nothing to the data! */
return 0; return 0;
} }
/* }}} */ /* }}} */
static const LIBSSH2_CRYPT_METHOD libssh2_crypt_method_none = { static const LIBSSH2_CRYPT_METHOD libssh2_crypt_method_none = {
"none", "none",
8, /* blocksize (SSH2 defines minimum blocksize as 8) */ 8, /* blocksize (SSH2 defines minimum blocksize as 8) */
0, /* iv_len */ 0, /* iv_len */
0, /* secret_len */ 0, /* secret_len */
0, /* flags */ 0, /* flags */
NULL, NULL,
libssh2_crypt_none_crypt, libssh2_crypt_none_crypt,
NULL NULL
}; };
#endif /* LIBSSH2_CRYPT_NONE */ #endif /* LIBSSH2_CRYPT_NONE */
struct crypt_ctx { struct crypt_ctx
{
int encrypt; int encrypt;
_libssh2_cipher_type(algo); _libssh2_cipher_type(algo);
_libssh2_cipher_ctx h; _libssh2_cipher_ctx h;
}; };
static int _libssh2_init (LIBSSH2_SESSION *session, static int
const LIBSSH2_CRYPT_METHOD *method, _libssh2_init(LIBSSH2_SESSION * session,
unsigned char *iv, int *free_iv, const LIBSSH2_CRYPT_METHOD * method,
unsigned char *secret, int *free_secret, unsigned char *iv, int *free_iv,
int encrypt, void **abstract) unsigned char *secret, int *free_secret,
int encrypt, void **abstract)
{ {
struct crypt_ctx *ctx = LIBSSH2_ALLOC(session, struct crypt_ctx *ctx = LIBSSH2_ALLOC(session,
sizeof(struct crypt_ctx)); sizeof(struct crypt_ctx));
if (!ctx) { if (!ctx) {
return -1; return -1;
} }
ctx->encrypt = encrypt; ctx->encrypt = encrypt;
ctx->algo = method->algo; 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);
LIBSSH2_FREE (session, ctx);
return -1; return -1;
} }
*abstract = ctx; *abstract = ctx;
@@ -90,17 +94,19 @@ static int _libssh2_init (LIBSSH2_SESSION *session,
return 0; 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; struct crypt_ctx *cctx = *(struct crypt_ctx **) abstract;
(void)session; (void) session;
return _libssh2_cipher_crypt(&cctx->h, cctx->algo, return _libssh2_cipher_crypt(&cctx->h, cctx->algo, cctx->encrypt, block);
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; struct crypt_ctx **cctx = (struct crypt_ctx **) abstract;
if (cctx && *cctx) { if (cctx && *cctx) {
_libssh2_cipher_dtor(&(*cctx)->h); _libssh2_cipher_dtor(&(*cctx)->h);
LIBSSH2_FREE(session, *cctx); LIBSSH2_FREE(session, *cctx);
@@ -112,10 +118,10 @@ static int _libssh2_dtor(LIBSSH2_SESSION *session, void **abstract)
#if LIBSSH2_AES #if LIBSSH2_AES
static const LIBSSH2_CRYPT_METHOD libssh2_crypt_method_aes128_cbc = { static const LIBSSH2_CRYPT_METHOD libssh2_crypt_method_aes128_cbc = {
"aes128-cbc", "aes128-cbc",
16, /* blocksize */ 16, /* blocksize */
16, /* initial value length */ 16, /* initial value length */
16, /* secret length -- 16*8 == 128bit */ 16, /* secret length -- 16*8 == 128bit */
0, /* flags */ 0, /* flags */
&_libssh2_init, &_libssh2_init,
&_libssh2_encrypt, &_libssh2_encrypt,
&_libssh2_dtor, &_libssh2_dtor,
@@ -124,10 +130,10 @@ static const LIBSSH2_CRYPT_METHOD libssh2_crypt_method_aes128_cbc = {
static const LIBSSH2_CRYPT_METHOD libssh2_crypt_method_aes192_cbc = { static const LIBSSH2_CRYPT_METHOD libssh2_crypt_method_aes192_cbc = {
"aes192-cbc", "aes192-cbc",
16, /* blocksize */ 16, /* blocksize */
16, /* initial value length */ 16, /* initial value length */
24, /* secret length -- 24*8 == 192bit */ 24, /* secret length -- 24*8 == 192bit */
0, /* flags */ 0, /* flags */
&_libssh2_init, &_libssh2_init,
&_libssh2_encrypt, &_libssh2_encrypt,
&_libssh2_dtor, &_libssh2_dtor,
@@ -136,10 +142,10 @@ static const LIBSSH2_CRYPT_METHOD libssh2_crypt_method_aes192_cbc = {
static const LIBSSH2_CRYPT_METHOD libssh2_crypt_method_aes256_cbc = { static const LIBSSH2_CRYPT_METHOD libssh2_crypt_method_aes256_cbc = {
"aes256-cbc", "aes256-cbc",
16, /* blocksize */ 16, /* blocksize */
16, /* initial value length */ 16, /* initial value length */
32, /* secret length -- 32*8 == 256bit */ 32, /* secret length -- 32*8 == 256bit */
0, /* flags */ 0, /* flags */
&_libssh2_init, &_libssh2_init,
&_libssh2_encrypt, &_libssh2_encrypt,
&_libssh2_dtor, &_libssh2_dtor,
@@ -147,12 +153,13 @@ static const LIBSSH2_CRYPT_METHOD libssh2_crypt_method_aes256_cbc = {
}; };
/* rijndael-cbc@lysator.liu.se == 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", "rijndael-cbc@lysator.liu.se",
16, /* blocksize */ 16, /* blocksize */
16, /* initial value length */ 16, /* initial value length */
32, /* secret length -- 32*8 == 256bit */ 32, /* secret length -- 32*8 == 256bit */
0, /* flags */ 0, /* flags */
&_libssh2_init, &_libssh2_init,
&_libssh2_encrypt, &_libssh2_encrypt,
&_libssh2_dtor, &_libssh2_dtor,
@@ -163,10 +170,10 @@ static const LIBSSH2_CRYPT_METHOD libssh2_crypt_method_rijndael_cbc_lysator_liu_
#if LIBSSH2_BLOWFISH #if LIBSSH2_BLOWFISH
static const LIBSSH2_CRYPT_METHOD libssh2_crypt_method_blowfish_cbc = { static const LIBSSH2_CRYPT_METHOD libssh2_crypt_method_blowfish_cbc = {
"blowfish-cbc", "blowfish-cbc",
8, /* blocksize */ 8, /* blocksize */
8, /* initial value length */ 8, /* initial value length */
16, /* secret length */ 16, /* secret length */
0, /* flags */ 0, /* flags */
&_libssh2_init, &_libssh2_init,
&_libssh2_encrypt, &_libssh2_encrypt,
&_libssh2_dtor, &_libssh2_dtor,
@@ -177,10 +184,10 @@ static const LIBSSH2_CRYPT_METHOD libssh2_crypt_method_blowfish_cbc = {
#if LIBSSH2_RC4 #if LIBSSH2_RC4
static const LIBSSH2_CRYPT_METHOD libssh2_crypt_method_arcfour = { static const LIBSSH2_CRYPT_METHOD libssh2_crypt_method_arcfour = {
"arcfour", "arcfour",
8, /* blocksize */ 8, /* blocksize */
8, /* initial value length */ 8, /* initial value length */
16, /* secret length */ 16, /* secret length */
0, /* flags */ 0, /* flags */
&_libssh2_init, &_libssh2_init,
&_libssh2_encrypt, &_libssh2_encrypt,
&_libssh2_dtor, &_libssh2_dtor,
@@ -191,10 +198,10 @@ static const LIBSSH2_CRYPT_METHOD libssh2_crypt_method_arcfour = {
#if LIBSSH2_CAST #if LIBSSH2_CAST
static const LIBSSH2_CRYPT_METHOD libssh2_crypt_method_cast128_cbc = { static const LIBSSH2_CRYPT_METHOD libssh2_crypt_method_cast128_cbc = {
"cast128-cbc", "cast128-cbc",
8, /* blocksize */ 8, /* blocksize */
8, /* initial value length */ 8, /* initial value length */
16, /* secret length */ 16, /* secret length */
0, /* flags */ 0, /* flags */
&_libssh2_init, &_libssh2_init,
&_libssh2_encrypt, &_libssh2_encrypt,
&_libssh2_dtor, &_libssh2_dtor,
@@ -205,10 +212,10 @@ static const LIBSSH2_CRYPT_METHOD libssh2_crypt_method_cast128_cbc = {
#if LIBSSH2_3DES #if LIBSSH2_3DES
static const LIBSSH2_CRYPT_METHOD libssh2_crypt_method_3des_cbc = { static const LIBSSH2_CRYPT_METHOD libssh2_crypt_method_3des_cbc = {
"3des-cbc", "3des-cbc",
8, /* blocksize */ 8, /* blocksize */
8, /* initial value length */ 8, /* initial value length */
24, /* secret length */ 24, /* secret length */
0, /* flags */ 0, /* flags */
&_libssh2_init, &_libssh2_init,
&_libssh2_encrypt, &_libssh2_encrypt,
&_libssh2_dtor, &_libssh2_dtor,
@@ -219,7 +226,7 @@ static const LIBSSH2_CRYPT_METHOD libssh2_crypt_method_3des_cbc = {
static const LIBSSH2_CRYPT_METHOD *_libssh2_crypt_methods[] = { static const LIBSSH2_CRYPT_METHOD *_libssh2_crypt_methods[] = {
#if LIBSSH2_AES #if LIBSSH2_AES
&libssh2_crypt_method_aes256_cbc, &libssh2_crypt_method_aes256_cbc,
&libssh2_crypt_method_rijndael_cbc_lysator_liu_se, /* == aes256-cbc */ &libssh2_crypt_method_rijndael_cbc_lysator_liu_se, /* == aes256-cbc */
&libssh2_crypt_method_aes192_cbc, &libssh2_crypt_method_aes192_cbc,
&libssh2_crypt_method_aes128_cbc, &libssh2_crypt_method_aes128_cbc,
#endif /* LIBSSH2_AES */ #endif /* LIBSSH2_AES */
@@ -242,6 +249,8 @@ static const LIBSSH2_CRYPT_METHOD *_libssh2_crypt_methods[] = {
}; };
/* Expose to kex.c */ /* Expose to kex.c */
const LIBSSH2_CRYPT_METHOD **libssh2_crypt_methods(void) { const LIBSSH2_CRYPT_METHOD **
libssh2_crypt_methods(void)
{
return _libssh2_crypt_methods; return _libssh2_crypt_methods;
} }

View File

@@ -47,22 +47,23 @@
* ssh-rsa * * 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 /* {{{ libssh2_hostkey_method_ssh_rsa_init
* Initialize the server hostkey working area with e/n pair * Initialize the server hostkey working area with e/n pair
*/ */
static int static int
libssh2_hostkey_method_ssh_rsa_init(LIBSSH2_SESSION *session, libssh2_hostkey_method_ssh_rsa_init(LIBSSH2_SESSION * session,
const unsigned char *hostkey_data, const unsigned char *hostkey_data,
unsigned long hostkey_data_len, unsigned long hostkey_data_len,
void **abstract) void **abstract)
{ {
libssh2_rsa_ctx *rsactx; libssh2_rsa_ctx *rsactx;
const unsigned char *s, *e, *n; const unsigned char *s, *e, *n;
unsigned long len, e_len, n_len; unsigned long len, e_len, n_len;
(void)hostkey_data_len; (void) hostkey_data_len;
if (*abstract) { if (*abstract) {
libssh2_hostkey_method_ssh_rsa_dtor(session, abstract); libssh2_hostkey_method_ssh_rsa_dtor(session, abstract);
@@ -73,7 +74,7 @@ libssh2_hostkey_method_ssh_rsa_init(LIBSSH2_SESSION *session,
len = libssh2_ntohu32(s); len = libssh2_ntohu32(s);
s += 4; s += 4;
if (len != 7 || strncmp((char *)s, "ssh-rsa", 7) != 0) { if (len != 7 || strncmp((char *) s, "ssh-rsa", 7) != 0) {
return -1; return -1;
} }
s += 7; s += 7;
@@ -81,25 +82,32 @@ libssh2_hostkey_method_ssh_rsa_init(LIBSSH2_SESSION *session,
e_len = libssh2_ntohu32(s); e_len = libssh2_ntohu32(s);
s += 4; s += 4;
e = s; s += e_len; e = s;
n_len = libssh2_ntohu32(s); s += 4; s += e_len;
n = s; s += n_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, if (_libssh2_rsa_new(&rsactx, e, e_len, n, n_len, NULL, 0,
NULL, 0, NULL, 0, NULL, 0, NULL, 0, NULL, 0)) NULL, 0, NULL, 0, NULL, 0, NULL, 0, NULL, 0))
return -1; return -1;
*abstract = rsactx; *abstract = rsactx;
return 0; return 0;
} }
/* }}} */ /* }}} */
/* {{{ libssh2_hostkey_method_ssh_rsa_initPEM /* {{{ libssh2_hostkey_method_ssh_rsa_initPEM
* Load a Private Key from a PEM file * Load a Private Key from a PEM file
*/ */
static int libssh2_hostkey_method_ssh_rsa_initPEM(LIBSSH2_SESSION *session, static int
const char *privkeyfile, unsigned const char *passphrase, void **abstract) libssh2_hostkey_method_ssh_rsa_initPEM(LIBSSH2_SESSION * session,
const char *privkeyfile,
unsigned const char *passphrase,
void **abstract)
{ {
libssh2_rsa_ctx *rsactx; libssh2_rsa_ctx *rsactx;
FILE *fp; FILE *fp;
@@ -115,7 +123,7 @@ static int libssh2_hostkey_method_ssh_rsa_initPEM(LIBSSH2_SESSION *session,
return -1; return -1;
} }
ret = _libssh2_rsa_new_private (&rsactx, session, fp, passphrase); ret = _libssh2_rsa_new_private(&rsactx, session, fp, passphrase);
fclose(fp); fclose(fp);
if (ret) { if (ret) {
return -1; return -1;
@@ -125,34 +133,42 @@ static int libssh2_hostkey_method_ssh_rsa_initPEM(LIBSSH2_SESSION *session,
return 0; return 0;
} }
/* }}} */ /* }}} */
/* {{{ libssh2_hostkey_method_ssh_rsa_sign /* {{{ libssh2_hostkey_method_ssh_rsa_sign
* Verify signature created by remote * Verify signature created by remote
*/ */
static int libssh2_hostkey_method_ssh_rsa_sig_verify(LIBSSH2_SESSION *session, static int
const unsigned char *sig, libssh2_hostkey_method_ssh_rsa_sig_verify(LIBSSH2_SESSION * session,
unsigned long sig_len, const unsigned char *sig,
const unsigned char *m, unsigned long sig_len,
unsigned long m_len, const unsigned char *m,
void **abstract) unsigned long m_len, void **abstract)
{ {
libssh2_rsa_ctx *rsactx = (libssh2_rsa_ctx*)(*abstract); libssh2_rsa_ctx *rsactx = (libssh2_rsa_ctx *) (*abstract);
(void)session; (void) session;
/* Skip past keyname_len(4) + keyname(7){"ssh-rsa"} + signature_len(4) */ /* Skip past keyname_len(4) + keyname(7){"ssh-rsa"} + signature_len(4) */
sig += 15; sig_len -= 15; sig += 15;
return _libssh2_rsa_sha1_verify (rsactx, sig, sig_len, m, m_len); sig_len -= 15;
return _libssh2_rsa_sha1_verify(rsactx, sig, sig_len, m, m_len);
} }
/* }}} */ /* }}} */
/* {{{ libssh2_hostkey_method_ssh_rsa_signv /* {{{ libssh2_hostkey_method_ssh_rsa_signv
* Construct a signature from an array of vectors * 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, static int
unsigned long veccount, const struct iovec datavec[], void **abstract) 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); libssh2_rsa_ctx *rsactx = (libssh2_rsa_ctx *) (*abstract);
int ret; int ret;
unsigned int i; unsigned int i;
unsigned char hash[SHA_DIGEST_LENGTH]; unsigned char hash[SHA_DIGEST_LENGTH];
@@ -165,23 +181,24 @@ static int libssh2_hostkey_method_ssh_rsa_signv(LIBSSH2_SESSION *session, unsign
libssh2_sha1_final(ctx, hash); libssh2_sha1_final(ctx, hash);
ret = _libssh2_rsa_sha1_sign(session, rsactx, hash, SHA_DIGEST_LENGTH, ret = _libssh2_rsa_sha1_sign(session, rsactx, hash, SHA_DIGEST_LENGTH,
signature, signature_len); signature, signature_len);
if (ret) { if (ret) {
return -1; return -1;
} }
return 0; return 0;
} }
/* }}} */ /* }}} */
/* {{{ libssh2_hostkey_method_ssh_rsa_dtor /* {{{ libssh2_hostkey_method_ssh_rsa_dtor
* Shutdown the hostkey * Shutdown the hostkey
*/ */
static int libssh2_hostkey_method_ssh_rsa_dtor(LIBSSH2_SESSION *session, static int
void **abstract) libssh2_hostkey_method_ssh_rsa_dtor(LIBSSH2_SESSION * session, void **abstract)
{ {
libssh2_rsa_ctx *rsactx = (libssh2_rsa_ctx*)(*abstract); libssh2_rsa_ctx *rsactx = (libssh2_rsa_ctx *) (*abstract);
(void)session; (void) session;
_libssh2_rsa_free(rsactx); _libssh2_rsa_free(rsactx);
@@ -189,6 +206,7 @@ static int libssh2_hostkey_method_ssh_rsa_dtor(LIBSSH2_SESSION *session,
return 0; return 0;
} }
/* }}} */ /* }}} */
static const LIBSSH2_HOSTKEY_METHOD libssh2_hostkey_method_ssh_rsa = { static const LIBSSH2_HOSTKEY_METHOD libssh2_hostkey_method_ssh_rsa = {
@@ -198,7 +216,7 @@ static const LIBSSH2_HOSTKEY_METHOD libssh2_hostkey_method_ssh_rsa = {
libssh2_hostkey_method_ssh_rsa_initPEM, libssh2_hostkey_method_ssh_rsa_initPEM,
libssh2_hostkey_method_ssh_rsa_sig_verify, libssh2_hostkey_method_ssh_rsa_sig_verify,
libssh2_hostkey_method_ssh_rsa_signv, libssh2_hostkey_method_ssh_rsa_signv,
NULL, /* encrypt */ NULL, /* encrypt */
libssh2_hostkey_method_ssh_rsa_dtor, libssh2_hostkey_method_ssh_rsa_dtor,
}; };
#endif /* LIBSSH2_RSA */ #endif /* LIBSSH2_RSA */
@@ -208,21 +226,22 @@ static const LIBSSH2_HOSTKEY_METHOD libssh2_hostkey_method_ssh_rsa = {
* ssh-dss * * 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 /* {{{ libssh2_hostkey_method_ssh_dss_init
* Initialize the server hostkey working area with p/q/g/y set * Initialize the server hostkey working area with p/q/g/y set
*/ */
static int static int
libssh2_hostkey_method_ssh_dss_init(LIBSSH2_SESSION *session, libssh2_hostkey_method_ssh_dss_init(LIBSSH2_SESSION * session,
const unsigned char *hostkey_data, const unsigned char *hostkey_data,
unsigned long hostkey_data_len, unsigned long hostkey_data_len,
void **abstract) void **abstract)
{ {
libssh2_dsa_ctx *dsactx; libssh2_dsa_ctx *dsactx;
const unsigned char *p, *q, *g, *y, *s; const unsigned char *p, *q, *g, *y, *s;
unsigned long p_len, q_len, g_len, y_len, len; unsigned long p_len, q_len, g_len, y_len, len;
(void)hostkey_data_len; (void) hostkey_data_len;
if (*abstract) { if (*abstract) {
libssh2_hostkey_method_ssh_dss_dtor(session, abstract); libssh2_hostkey_method_ssh_dss_dtor(session, abstract);
@@ -230,36 +249,47 @@ libssh2_hostkey_method_ssh_dss_init(LIBSSH2_SESSION *session,
} }
s = hostkey_data; s = hostkey_data;
len = libssh2_ntohu32(s); s += 4; len = libssh2_ntohu32(s);
if (len != 7 || strncmp((char *)s, "ssh-dss", 7) != 0) { s += 4;
if (len != 7 || strncmp((char *) s, "ssh-dss", 7) != 0) {
return -1; return -1;
} s += 7; }
s += 7;
p_len = libssh2_ntohu32(s); s += 4; p_len = libssh2_ntohu32(s);
p = s; s += p_len; s += 4;
q_len = libssh2_ntohu32(s); s += 4; p = s;
q = s; s += q_len; s += p_len;
g_len = libssh2_ntohu32(s); s += 4; q_len = libssh2_ntohu32(s);
g = s; s += g_len; s += 4;
y_len = libssh2_ntohu32(s); s += 4; q = s;
y = s; s += y_len; 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, _libssh2_dsa_new(&dsactx, p, p_len, q, q_len, g, g_len, y, y_len, NULL, 0);
y, y_len, NULL, 0);
*abstract = dsactx; *abstract = dsactx;
return 0; return 0;
} }
/* }}} */ /* }}} */
/* {{{ libssh2_hostkey_method_ssh_dss_initPEM /* {{{ libssh2_hostkey_method_ssh_dss_initPEM
* Load a Private Key from a PEM file * Load a Private Key from a PEM file
*/ */
static int libssh2_hostkey_method_ssh_dss_initPEM(LIBSSH2_SESSION *session, static int
const char *privkeyfile, libssh2_hostkey_method_ssh_dss_initPEM(LIBSSH2_SESSION * session,
unsigned const char *passphrase, const char *privkeyfile,
void **abstract) unsigned const char *passphrase,
void **abstract)
{ {
libssh2_dsa_ctx *dsactx; libssh2_dsa_ctx *dsactx;
FILE *fp; FILE *fp;
@@ -275,7 +305,7 @@ static int libssh2_hostkey_method_ssh_dss_initPEM(LIBSSH2_SESSION *session,
return -1; return -1;
} }
ret = _libssh2_dsa_new_private (&dsactx, session, fp, passphrase); ret = _libssh2_dsa_new_private(&dsactx, session, fp, passphrase);
fclose(fp); fclose(fp);
if (ret) { if (ret) {
return -1; return -1;
@@ -285,33 +315,46 @@ static int libssh2_hostkey_method_ssh_dss_initPEM(LIBSSH2_SESSION *session,
return 0; return 0;
} }
/* }}} */ /* }}} */
/* {{{ libssh2_hostkey_method_ssh_dss_sign /* {{{ libssh2_hostkey_method_ssh_dss_sign
* Verify signature created by remote * 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, static int
const unsigned char *m, unsigned long m_len, void **abstract) 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); libssh2_dsa_ctx *dsactx = (libssh2_dsa_ctx *) (*abstract);
/* Skip past keyname_len(4) + keyname(7){"ssh-dss"} + signature_len(4) */ /* 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) { 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 -1;
} }
return _libssh2_dsa_sha1_verify(dsactx, sig, m, m_len); return _libssh2_dsa_sha1_verify(dsactx, sig, m, m_len);
} }
/* }}} */ /* }}} */
/* {{{ libssh2_hostkey_method_ssh_dss_signv /* {{{ libssh2_hostkey_method_ssh_dss_signv
* Construct a signature from an array of vectors * 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, static int
unsigned long veccount, const struct iovec datavec[], void **abstract) 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); libssh2_dsa_ctx *dsactx = (libssh2_dsa_ctx *) (*abstract);
unsigned char hash[SHA_DIGEST_LENGTH]; unsigned char hash[SHA_DIGEST_LENGTH];
libssh2_sha1_ctx ctx; libssh2_sha1_ctx ctx;
unsigned int i; unsigned int i;
@@ -330,25 +373,24 @@ static int libssh2_hostkey_method_ssh_dss_signv(LIBSSH2_SESSION *session, unsign
} }
libssh2_sha1_final(ctx, hash); libssh2_sha1_final(ctx, hash);
if (_libssh2_dsa_sha1_sign(dsactx, hash, SHA_DIGEST_LENGTH, if (_libssh2_dsa_sha1_sign(dsactx, hash, SHA_DIGEST_LENGTH, *signature)) {
*signature))
{
LIBSSH2_FREE(session, *signature); LIBSSH2_FREE(session, *signature);
return -1; return -1;
} }
return 0; return 0;
} }
/* }}} */ /* }}} */
/* {{{ libssh2_hostkey_method_ssh_dss_dtor /* {{{ libssh2_hostkey_method_ssh_dss_dtor
* Shutdown the hostkey method * Shutdown the hostkey method
*/ */
static int libssh2_hostkey_method_ssh_dss_dtor(LIBSSH2_SESSION *session, static int
void **abstract) libssh2_hostkey_method_ssh_dss_dtor(LIBSSH2_SESSION * session, void **abstract)
{ {
libssh2_dsa_ctx *dsactx = (libssh2_dsa_ctx*)(*abstract); libssh2_dsa_ctx *dsactx = (libssh2_dsa_ctx *) (*abstract);
(void)session; (void) session;
_libssh2_dsa_free(dsactx); _libssh2_dsa_free(dsactx);
@@ -356,6 +398,7 @@ static int libssh2_hostkey_method_ssh_dss_dtor(LIBSSH2_SESSION *session,
return 0; return 0;
} }
/* }}} */ /* }}} */
static const LIBSSH2_HOSTKEY_METHOD libssh2_hostkey_method_ssh_dss = { static const LIBSSH2_HOSTKEY_METHOD libssh2_hostkey_method_ssh_dss = {
@@ -365,7 +408,7 @@ static const LIBSSH2_HOSTKEY_METHOD libssh2_hostkey_method_ssh_dss = {
libssh2_hostkey_method_ssh_dss_initPEM, libssh2_hostkey_method_ssh_dss_initPEM,
libssh2_hostkey_method_ssh_dss_sig_verify, libssh2_hostkey_method_ssh_dss_sig_verify,
libssh2_hostkey_method_ssh_dss_signv, libssh2_hostkey_method_ssh_dss_signv,
NULL, /* encrypt */ NULL, /* encrypt */
libssh2_hostkey_method_ssh_dss_dtor, libssh2_hostkey_method_ssh_dss_dtor,
}; };
#endif /* LIBSSH2_DSA */ #endif /* LIBSSH2_DSA */
@@ -380,7 +423,8 @@ static const LIBSSH2_HOSTKEY_METHOD *_libssh2_hostkey_methods[] = {
NULL NULL
}; };
const LIBSSH2_HOSTKEY_METHOD **libssh2_hostkey_methods(void) const LIBSSH2_HOSTKEY_METHOD **
libssh2_hostkey_methods(void)
{ {
return _libssh2_hostkey_methods; return _libssh2_hostkey_methods;
} }
@@ -391,21 +435,21 @@ const LIBSSH2_HOSTKEY_METHOD **libssh2_hostkey_methods(void)
* Length of buffer is determined by hash type * Length of buffer is determined by hash type
* i.e. MD5 == 16, SHA1 == 20 * 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) { switch (hash_type) {
#if LIBSSH2_MD5 #if LIBSSH2_MD5
case LIBSSH2_HOSTKEY_HASH_MD5: case LIBSSH2_HOSTKEY_HASH_MD5:
return (char *)session->server_hostkey_md5; return (char *) session->server_hostkey_md5;
break; break;
#endif /* LIBSSH2_MD5 */ #endif /* LIBSSH2_MD5 */
case LIBSSH2_HOSTKEY_HASH_SHA1: case LIBSSH2_HOSTKEY_HASH_SHA1:
return (char *)session->server_hostkey_sha1; return (char *) session->server_hostkey_sha1;
break; break;
default: default:
return NULL; return NULL;
} }
} }
/* }}} */ /* }}} */

1152
src/kex.c

File diff suppressed because it is too large Load Diff

View File

@@ -38,29 +38,29 @@
#include "libssh2_priv.h" #include "libssh2_priv.h"
#include <string.h> #include <string.h>
int _libssh2_rsa_new(libssh2_rsa_ctx **rsa, int
const unsigned char *edata, _libssh2_rsa_new(libssh2_rsa_ctx ** rsa,
unsigned long elen, const unsigned char *edata,
const unsigned char *ndata, unsigned long elen,
unsigned long nlen, const unsigned char *ndata,
const unsigned char *ddata, unsigned long nlen,
unsigned long dlen, const unsigned char *ddata,
const unsigned char *pdata, unsigned long dlen,
unsigned long plen, const unsigned char *pdata,
const unsigned char *qdata, unsigned long plen,
unsigned long qlen, const unsigned char *qdata,
const unsigned char *e1data, unsigned long qlen,
unsigned long e1len, const unsigned char *e1data,
const unsigned char *e2data, unsigned long e1len,
unsigned long e2len, const unsigned char *e2data,
const unsigned char *coeffdata, unsigned long e2len,
unsigned long coefflen) const unsigned char *coeffdata, unsigned long coefflen)
{ {
int rc; int rc;
(void)e1data; (void) e1data;
(void)e1len; (void) e1len;
(void)e2data; (void) e2data;
(void)e2len; (void) e2len;
if (ddata) { if (ddata) {
rc = gcry_sexp_build rc = gcry_sexp_build
@@ -69,11 +69,10 @@ int _libssh2_rsa_new(libssh2_rsa_ctx **rsa,
nlen, ndata, elen, edata, dlen, ddata, plen, pdata, nlen, ndata, elen, edata, dlen, ddata, plen, pdata,
qlen, qdata, coefflen, coeffdata); qlen, qdata, coefflen, coeffdata);
} else { } else {
rc = gcry_sexp_build (rsa, NULL, "(public-key(rsa(n%b)(e%b)))", rc = gcry_sexp_build(rsa, NULL, "(public-key(rsa(n%b)(e%b)))",
nlen, ndata, elen, edata); nlen, ndata, elen, edata);
} }
if (rc) if (rc) {
{
*rsa = NULL; *rsa = NULL;
return -1; return -1;
} }
@@ -81,11 +80,11 @@ int _libssh2_rsa_new(libssh2_rsa_ctx **rsa,
return 0; return 0;
} }
int _libssh2_rsa_sha1_verify(libssh2_rsa_ctx *rsa, int
const unsigned char *sig, _libssh2_rsa_sha1_verify(libssh2_rsa_ctx * rsa,
unsigned long sig_len, const unsigned char *sig,
const unsigned char *m, unsigned long sig_len,
unsigned long m_len) const unsigned char *m, unsigned long m_len)
{ {
unsigned char hash[SHA_DIGEST_LENGTH]; unsigned char hash[SHA_DIGEST_LENGTH];
gcry_sexp_t s_sig, s_hash; gcry_sexp_t s_sig, s_hash;
@@ -93,38 +92,37 @@ int _libssh2_rsa_sha1_verify(libssh2_rsa_ctx *rsa,
libssh2_sha1(m, m_len, hash); libssh2_sha1(m, m_len, hash);
rc = gcry_sexp_build (&s_hash, NULL, rc = gcry_sexp_build(&s_hash, NULL,
"(data (flags pkcs1) (hash sha1 %b))", "(data (flags pkcs1) (hash sha1 %b))",
SHA_DIGEST_LENGTH, hash); SHA_DIGEST_LENGTH, hash);
if (rc != 0) { if (rc != 0) {
return -1; return -1;
} }
rc = gcry_sexp_build (&s_sig, NULL, "(sig-val(rsa(s %b)))", rc = gcry_sexp_build(&s_sig, NULL, "(sig-val(rsa(s %b)))", sig_len, sig);
sig_len, sig);
if (rc != 0) { if (rc != 0) {
gcry_sexp_release (s_hash); gcry_sexp_release(s_hash);
return -1; return -1;
} }
rc = gcry_pk_verify (s_sig, s_hash, rsa); rc = gcry_pk_verify(s_sig, s_hash, rsa);
gcry_sexp_release (s_sig); gcry_sexp_release(s_sig);
gcry_sexp_release (s_hash); gcry_sexp_release(s_hash);
return (rc == 0) ? 0 : -1; return (rc == 0) ? 0 : -1;
} }
int _libssh2_dsa_new(libssh2_dsa_ctx **dsactx, int
const unsigned char *p, _libssh2_dsa_new(libssh2_dsa_ctx ** dsactx,
unsigned long p_len, const unsigned char *p,
const unsigned char *q, unsigned long p_len,
unsigned long q_len, const unsigned char *q,
const unsigned char *g, unsigned long q_len,
unsigned long g_len, const unsigned char *g,
const unsigned char *y, unsigned long g_len,
unsigned long y_len, const unsigned char *y,
const unsigned char *x, unsigned long y_len,
unsigned long x_len) const unsigned char *x, unsigned long x_len)
{ {
int rc; int rc;
@@ -134,9 +132,9 @@ int _libssh2_dsa_new(libssh2_dsa_ctx **dsactx,
"(private-key(dsa(p%b)(q%b)(g%b)(y%b)(x%b)))", "(private-key(dsa(p%b)(q%b)(g%b)(y%b)(x%b)))",
p_len, p, q_len, q, g_len, g, y_len, y, x_len, x); p_len, p, q_len, q, g_len, g, y_len, y, x_len, x);
} else { } else {
rc = gcry_sexp_build (dsactx, NULL, rc = gcry_sexp_build(dsactx, NULL,
"(public-key(dsa(p%b)(q%b)(g%b)(y%b)))", "(public-key(dsa(p%b)(q%b)(g%b)(y%b)))",
p_len, p, q_len, q, g_len, g, y_len, y); p_len, p, q_len, q, g_len, g, y_len, y);
} }
if (rc) { if (rc) {
@@ -147,10 +145,10 @@ int _libssh2_dsa_new(libssh2_dsa_ctx **dsactx,
return 0; return 0;
} }
int _libssh2_rsa_new_private (libssh2_rsa_ctx **rsa, int
LIBSSH2_SESSION *session, _libssh2_rsa_new_private(libssh2_rsa_ctx ** rsa,
FILE *fp, LIBSSH2_SESSION * session,
unsigned const char *passphrase) FILE * fp, unsigned const char *passphrase)
{ {
char *data, *save_data; char *data, *save_data;
unsigned int datalen; unsigned int datalen;
@@ -158,95 +156,94 @@ int _libssh2_rsa_new_private (libssh2_rsa_ctx **rsa,
char *n, *e, *d, *p, *q, *e1, *e2, *coeff; char *n, *e, *d, *p, *q, *e1, *e2, *coeff;
unsigned int nlen, elen, dlen, plen, qlen, e1len, e2len, coefflen; unsigned int nlen, elen, dlen, plen, qlen, e1len, e2len, coefflen;
(void)passphrase; (void) passphrase;
ret = _libssh2_pem_parse (session, ret = _libssh2_pem_parse(session,
"-----BEGIN RSA PRIVATE KEY-----", "-----BEGIN RSA PRIVATE KEY-----",
"-----END RSA PRIVATE KEY-----", "-----END RSA PRIVATE KEY-----",
fp, &data, &datalen); fp, &data, &datalen);
if (ret) { if (ret) {
return -1; return -1;
} }
save_data = data; save_data = data;
if (_libssh2_pem_decode_sequence (&data, &datalen)) { if (_libssh2_pem_decode_sequence(&data, &datalen)) {
ret = -1; ret = -1;
goto fail; goto fail;
} }
/* First read Version field (should be 0). */ /* First read Version field (should be 0). */
ret = _libssh2_pem_decode_integer (&data, &datalen, &n, &nlen); ret = _libssh2_pem_decode_integer(&data, &datalen, &n, &nlen);
if (ret != 0 || (nlen != 1 && *n != '\0')) { if (ret != 0 || (nlen != 1 && *n != '\0')) {
ret = -1; ret = -1;
goto fail; goto fail;
} }
ret = _libssh2_pem_decode_integer (&data, &datalen, &n, &nlen); ret = _libssh2_pem_decode_integer(&data, &datalen, &n, &nlen);
if (ret != 0) { if (ret != 0) {
ret = -1; ret = -1;
goto fail; goto fail;
} }
ret = _libssh2_pem_decode_integer (&data, &datalen, &e, &elen); ret = _libssh2_pem_decode_integer(&data, &datalen, &e, &elen);
if (ret != 0) { if (ret != 0) {
ret = -1; ret = -1;
goto fail; goto fail;
} }
ret = _libssh2_pem_decode_integer (&data, &datalen, &d, &dlen); ret = _libssh2_pem_decode_integer(&data, &datalen, &d, &dlen);
if (ret != 0) { if (ret != 0) {
ret = -1; ret = -1;
goto fail; goto fail;
} }
ret = _libssh2_pem_decode_integer (&data, &datalen, &p, &plen); ret = _libssh2_pem_decode_integer(&data, &datalen, &p, &plen);
if (ret != 0) { if (ret != 0) {
ret = -1; ret = -1;
goto fail; goto fail;
} }
ret = _libssh2_pem_decode_integer (&data, &datalen, &q, &qlen); ret = _libssh2_pem_decode_integer(&data, &datalen, &q, &qlen);
if (ret != 0) { if (ret != 0) {
ret = -1; ret = -1;
goto fail; goto fail;
} }
ret = _libssh2_pem_decode_integer (&data, &datalen, &e1, &e1len); ret = _libssh2_pem_decode_integer(&data, &datalen, &e1, &e1len);
if (ret != 0) { if (ret != 0) {
ret = -1; ret = -1;
goto fail; goto fail;
} }
ret = _libssh2_pem_decode_integer (&data, &datalen, &e2, &e2len); ret = _libssh2_pem_decode_integer(&data, &datalen, &e2, &e2len);
if (ret != 0) { if (ret != 0) {
ret = -1; ret = -1;
goto fail; goto fail;
} }
ret = _libssh2_pem_decode_integer (&data, &datalen, &coeff, &coefflen); ret = _libssh2_pem_decode_integer(&data, &datalen, &coeff, &coefflen);
if (ret != 0) { if (ret != 0) {
ret = -1; ret = -1;
goto fail; goto fail;
} }
if (_libssh2_rsa_new (rsa, e, elen, n, nlen, d, dlen, p, plen, if (_libssh2_rsa_new(rsa, e, elen, n, nlen, d, dlen, p, plen,
q, qlen, e1, e1len, e2, e2len, q, qlen, e1, e1len, e2, e2len, coeff, coefflen)) {
coeff, coefflen)) {
ret = -1; ret = -1;
goto fail; goto fail;
} }
ret = 0; ret = 0;
fail: fail:
LIBSSH2_FREE (session, save_data); LIBSSH2_FREE(session, save_data);
return ret; return ret;
} }
int _libssh2_dsa_new_private (libssh2_dsa_ctx **dsa, int
LIBSSH2_SESSION *session, _libssh2_dsa_new_private(libssh2_dsa_ctx ** dsa,
FILE *fp, LIBSSH2_SESSION * session,
unsigned const char *passphrase) FILE * fp, unsigned const char *passphrase)
{ {
char *data, *save_data; char *data, *save_data;
unsigned int datalen; unsigned int datalen;
@@ -254,55 +251,55 @@ int _libssh2_dsa_new_private (libssh2_dsa_ctx **dsa,
char *p, *q, *g, *y, *x; char *p, *q, *g, *y, *x;
unsigned int plen, qlen, glen, ylen, xlen; unsigned int plen, qlen, glen, ylen, xlen;
(void)passphrase; (void) passphrase;
ret = _libssh2_pem_parse (session, ret = _libssh2_pem_parse(session,
"-----BEGIN DSA PRIVATE KEY-----", "-----BEGIN DSA PRIVATE KEY-----",
"-----END DSA PRIVATE KEY-----", "-----END DSA PRIVATE KEY-----",
fp, &data, &datalen); fp, &data, &datalen);
if (ret) { if (ret) {
return -1; return -1;
} }
save_data = data; save_data = data;
if (_libssh2_pem_decode_sequence (&data, &datalen)) { if (_libssh2_pem_decode_sequence(&data, &datalen)) {
ret = -1; ret = -1;
goto fail; goto fail;
} }
/* First read Version field (should be 0). */ /* First read Version field (should be 0). */
ret = _libssh2_pem_decode_integer (&data, &datalen, &p, &plen); ret = _libssh2_pem_decode_integer(&data, &datalen, &p, &plen);
if (ret != 0 || (plen != 1 && *p != '\0')) { if (ret != 0 || (plen != 1 && *p != '\0')) {
ret = -1; ret = -1;
goto fail; goto fail;
} }
ret = _libssh2_pem_decode_integer (&data, &datalen, &p, &plen); ret = _libssh2_pem_decode_integer(&data, &datalen, &p, &plen);
if (ret != 0) { if (ret != 0) {
ret = -1; ret = -1;
goto fail; goto fail;
} }
ret = _libssh2_pem_decode_integer (&data, &datalen, &q, &qlen); ret = _libssh2_pem_decode_integer(&data, &datalen, &q, &qlen);
if (ret != 0) { if (ret != 0) {
ret = -1; ret = -1;
goto fail; goto fail;
} }
ret = _libssh2_pem_decode_integer (&data, &datalen, &g, &glen); ret = _libssh2_pem_decode_integer(&data, &datalen, &g, &glen);
if (ret != 0) { if (ret != 0) {
ret = -1; ret = -1;
goto fail; goto fail;
} }
ret = _libssh2_pem_decode_integer (&data, &datalen, &y, &ylen); ret = _libssh2_pem_decode_integer(&data, &datalen, &y, &ylen);
if (ret != 0) { if (ret != 0) {
ret = -1; ret = -1;
goto fail; goto fail;
} }
ret = _libssh2_pem_decode_integer (&data, &datalen, &x, &xlen); ret = _libssh2_pem_decode_integer(&data, &datalen, &x, &xlen);
if (ret != 0) { if (ret != 0) {
ret = -1; ret = -1;
goto fail; goto fail;
@@ -313,25 +310,24 @@ int _libssh2_dsa_new_private (libssh2_dsa_ctx **dsa,
goto fail; goto fail;
} }
if (_libssh2_dsa_new (dsa, p, plen, q, qlen, if (_libssh2_dsa_new(dsa, p, plen, q, qlen, g, glen, y, ylen, x, xlen)) {
g, glen, y, ylen, x, xlen)) {
ret = -1; ret = -1;
goto fail; goto fail;
} }
ret = 0; ret = 0;
fail: fail:
LIBSSH2_FREE (session, save_data); LIBSSH2_FREE(session, save_data);
return ret; return ret;
} }
int _libssh2_rsa_sha1_sign(LIBSSH2_SESSION *session, int
libssh2_dsa_ctx *rsactx, _libssh2_rsa_sha1_sign(LIBSSH2_SESSION * session,
const unsigned char *hash, libssh2_dsa_ctx * rsactx,
unsigned long hash_len, const unsigned char *hash,
unsigned char **signature, unsigned long hash_len,
unsigned long *signature_len) unsigned char **signature, unsigned long *signature_len)
{ {
gcry_sexp_t sig_sexp; gcry_sexp_t sig_sexp;
gcry_sexp_t data; gcry_sexp_t data;
@@ -343,15 +339,15 @@ int _libssh2_rsa_sha1_sign(LIBSSH2_SESSION *session,
return -1; return -1;
} }
if (gcry_sexp_build (&data, NULL, if (gcry_sexp_build(&data, NULL,
"(data (flags pkcs1) (hash sha1 %b))", "(data (flags pkcs1) (hash sha1 %b))",
hash_len, hash)) { hash_len, hash)) {
return -1; return -1;
} }
rc = gcry_pk_sign (&sig_sexp, data, rsactx); rc = gcry_pk_sign(&sig_sexp, data, rsactx);
gcry_sexp_release (data); gcry_sexp_release(data);
if (rc != 0) { if (rc != 0) {
return -1; return -1;
@@ -373,18 +369,18 @@ int _libssh2_rsa_sha1_sign(LIBSSH2_SESSION *session,
} }
*signature = LIBSSH2_ALLOC(session, size); *signature = LIBSSH2_ALLOC(session, size);
memcpy (*signature, tmp, size); memcpy(*signature, tmp, size);
*signature_len = size; *signature_len = size;
return rc; return rc;
} }
int _libssh2_dsa_sha1_sign(libssh2_dsa_ctx *dsactx, int
const unsigned char *hash, _libssh2_dsa_sha1_sign(libssh2_dsa_ctx * dsactx,
unsigned long hash_len, const unsigned char *hash,
unsigned char *sig) unsigned long hash_len, unsigned char *sig)
{ {
unsigned char zhash[SHA_DIGEST_LENGTH+1]; unsigned char zhash[SHA_DIGEST_LENGTH + 1];
gcry_sexp_t sig_sexp; gcry_sexp_t sig_sexp;
gcry_sexp_t data; gcry_sexp_t data;
int ret; int ret;
@@ -395,17 +391,16 @@ int _libssh2_dsa_sha1_sign(libssh2_dsa_ctx *dsactx,
return -1; return -1;
} }
memcpy (zhash + 1, hash, hash_len); memcpy(zhash + 1, hash, hash_len);
zhash[0] = 0; zhash[0] = 0;
if (gcry_sexp_build (&data, NULL, "(data (value %b))", if (gcry_sexp_build(&data, NULL, "(data (value %b))", hash_len + 1, zhash)) {
hash_len + 1, zhash)) {
return -1; return -1;
} }
ret = gcry_pk_sign (&sig_sexp, data, dsactx); ret = gcry_pk_sign(&sig_sexp, data, dsactx);
gcry_sexp_release (data); gcry_sexp_release(data);
if (ret != 0) { if (ret != 0) {
return -1; return -1;
@@ -435,13 +430,13 @@ int _libssh2_dsa_sha1_sign(libssh2_dsa_ctx *dsactx,
goto out; goto out;
} }
memcpy (sig, tmp, 20); memcpy(sig, tmp, 20);
gcry_sexp_release (data); gcry_sexp_release(data);
/* Extract S. */ /* Extract S. */
data = gcry_sexp_find_token(sig_sexp, "s",0); data = gcry_sexp_find_token(sig_sexp, "s", 0);
if (!data) { if (!data) {
ret = -1; ret = -1;
goto out; goto out;
@@ -463,80 +458,79 @@ int _libssh2_dsa_sha1_sign(libssh2_dsa_ctx *dsactx,
goto out; goto out;
} }
memcpy (sig + 20, tmp, 20); memcpy(sig + 20, tmp, 20);
ret = 0; ret = 0;
out: out:
if (sig_sexp) { if (sig_sexp) {
gcry_sexp_release (sig_sexp); gcry_sexp_release(sig_sexp);
} }
if (data) { if (data) {
gcry_sexp_release (data); gcry_sexp_release(data);
} }
return ret; return ret;
} }
int _libssh2_dsa_sha1_verify(libssh2_dsa_ctx *dsactx, int
const unsigned char *sig, _libssh2_dsa_sha1_verify(libssh2_dsa_ctx * dsactx,
const unsigned char *m, const unsigned char *sig,
unsigned long m_len) const unsigned char *m, unsigned long m_len)
{ {
unsigned char hash[SHA_DIGEST_LENGTH+1]; unsigned char hash[SHA_DIGEST_LENGTH + 1];
gcry_sexp_t s_sig, s_hash; gcry_sexp_t s_sig, s_hash;
int rc = -1; int rc = -1;
libssh2_sha1(m, m_len, hash+1); libssh2_sha1(m, m_len, hash + 1);
hash[0] = 0; hash[0] = 0;
if (gcry_sexp_build (&s_hash, NULL, "(data(flags raw)(value %b))", if (gcry_sexp_build(&s_hash, NULL, "(data(flags raw)(value %b))",
SHA_DIGEST_LENGTH+1, hash)) { SHA_DIGEST_LENGTH + 1, hash)) {
return -1; return -1;
} }
if (gcry_sexp_build (&s_sig, NULL, "(sig-val(dsa(r %b)(s %b)))", if (gcry_sexp_build(&s_sig, NULL, "(sig-val(dsa(r %b)(s %b)))",
20, sig, 20, sig + 20)) { 20, sig, 20, sig + 20)) {
gcry_sexp_release (s_hash); gcry_sexp_release(s_hash);
return -1; return -1;
} }
rc = gcry_pk_verify (s_sig, s_hash, dsactx); rc = gcry_pk_verify(s_sig, s_hash, dsactx);
gcry_sexp_release (s_sig); gcry_sexp_release(s_sig);
gcry_sexp_release (s_hash); gcry_sexp_release(s_hash);
return (rc == 0) ? 0 : -1; return (rc == 0) ? 0 : -1;
} }
int _libssh2_cipher_init (_libssh2_cipher_ctx *h, int
_libssh2_cipher_type(algo), _libssh2_cipher_init(_libssh2_cipher_ctx * h,
unsigned char *iv, _libssh2_cipher_type(algo),
unsigned char *secret, unsigned char *iv, unsigned char *secret, int encrypt)
int encrypt)
{ {
int mode = 0, ret; int mode = 0, ret;
int keylen = gcry_cipher_get_algo_keylen (algo); int keylen = gcry_cipher_get_algo_keylen(algo);
(void)encrypt; (void) encrypt;
if (algo != GCRY_CIPHER_ARCFOUR) { if (algo != GCRY_CIPHER_ARCFOUR) {
mode = GCRY_CIPHER_MODE_CBC; mode = GCRY_CIPHER_MODE_CBC;
} }
ret = gcry_cipher_open (h, algo, mode, 0); ret = gcry_cipher_open(h, algo, mode, 0);
if (ret) { if (ret) {
return -1; return -1;
} }
ret = gcry_cipher_setkey (*h, secret, keylen); ret = gcry_cipher_setkey(*h, secret, keylen);
if (ret) { if (ret) {
gcry_cipher_close (*h); gcry_cipher_close(*h);
return -1; return -1;
} }
if (algo != GCRY_CIPHER_ARCFOUR) { if (algo != GCRY_CIPHER_ARCFOUR) {
int blklen = gcry_cipher_get_algo_blklen (algo); int blklen = gcry_cipher_get_algo_blklen(algo);
ret = gcry_cipher_setiv (*h, iv, blklen); ret = gcry_cipher_setiv(*h, iv, blklen);
if (ret) { if (ret) {
gcry_cipher_close (*h); gcry_cipher_close(*h);
return -1; return -1;
} }
} }
@@ -544,12 +538,12 @@ int _libssh2_cipher_init (_libssh2_cipher_ctx *h,
return 0; return 0;
} }
int _libssh2_cipher_crypt(_libssh2_cipher_ctx *ctx, int
_libssh2_cipher_type(algo), _libssh2_cipher_crypt(_libssh2_cipher_ctx * ctx,
int encrypt, _libssh2_cipher_type(algo),
unsigned char *block) int encrypt, unsigned char *block)
{ {
size_t blklen = gcry_cipher_get_algo_blklen (algo); size_t blklen = gcry_cipher_get_algo_blklen(algo);
int ret; int ret;
if (blklen == 1) { if (blklen == 1) {
/* Hack for arcfour. */ /* Hack for arcfour. */
@@ -557,11 +551,9 @@ int _libssh2_cipher_crypt(_libssh2_cipher_ctx *ctx,
} }
if (encrypt) { if (encrypt) {
ret = gcry_cipher_encrypt (*ctx, block, blklen, ret = gcry_cipher_encrypt(*ctx, block, blklen, block, blklen);
block, blklen);
} else { } else {
ret = gcry_cipher_decrypt (*ctx, block, blklen, ret = gcry_cipher_decrypt(*ctx, block, blklen, block, blklen);
block, blklen);
} }
return ret; return ret;
} }

View File

@@ -93,66 +93,59 @@
#define libssh2_rsa_ctx struct gcry_sexp #define libssh2_rsa_ctx struct gcry_sexp
int _libssh2_rsa_new(libssh2_rsa_ctx **rsa, int _libssh2_rsa_new(libssh2_rsa_ctx ** rsa,
const unsigned char *edata, const unsigned char *edata,
unsigned long elen, unsigned long elen,
const unsigned char *ndata, const unsigned char *ndata,
unsigned long nlen, unsigned long nlen,
const unsigned char *ddata, const unsigned char *ddata,
unsigned long dlen, unsigned long dlen,
const unsigned char *pdata, const unsigned char *pdata,
unsigned long plen, unsigned long plen,
const unsigned char *qdata, const unsigned char *qdata,
unsigned long qlen, unsigned long qlen,
const unsigned char *e1data, const unsigned char *e1data,
unsigned long e1len, unsigned long e1len,
const unsigned char *e2data, const unsigned char *e2data,
unsigned long e2len, unsigned long e2len,
const unsigned char *coeffdata, const unsigned char *coeffdata, unsigned long coefflen);
unsigned long coefflen); int _libssh2_rsa_new_private(libssh2_rsa_ctx ** rsa,
int _libssh2_rsa_new_private (libssh2_rsa_ctx **rsa, LIBSSH2_SESSION * session,
LIBSSH2_SESSION *session, FILE * fp, unsigned const char *passphrase);
FILE *fp, int _libssh2_rsa_sha1_verify(libssh2_rsa_ctx * rsa,
unsigned const char *passphrase); const unsigned char *sig,
int _libssh2_rsa_sha1_verify(libssh2_rsa_ctx *rsa, unsigned long sig_len,
const unsigned char *sig, const unsigned char *m, unsigned long m_len);
unsigned long sig_len, int _libssh2_rsa_sha1_sign(LIBSSH2_SESSION * session,
const unsigned char *m, libssh2_rsa_ctx * rsactx,
unsigned long m_len); const unsigned char *hash,
int _libssh2_rsa_sha1_sign(LIBSSH2_SESSION *session, unsigned long hash_len,
libssh2_rsa_ctx *rsactx, unsigned char **signature,
const unsigned char *hash, unsigned long *signature_len);
unsigned long hash_len,
unsigned char **signature,
unsigned long *signature_len);
#define _libssh2_rsa_free(rsactx) gcry_sexp_release (rsactx) #define _libssh2_rsa_free(rsactx) gcry_sexp_release (rsactx)
#define libssh2_dsa_ctx struct gcry_sexp #define libssh2_dsa_ctx struct gcry_sexp
int _libssh2_dsa_new(libssh2_dsa_ctx **dsa, int _libssh2_dsa_new(libssh2_dsa_ctx ** dsa,
const unsigned char *pdata, const unsigned char *pdata,
unsigned long plen, unsigned long plen,
const unsigned char *qdata, const unsigned char *qdata,
unsigned long qlen, unsigned long qlen,
const unsigned char *gdata, const unsigned char *gdata,
unsigned long glen, unsigned long glen,
const unsigned char *ydata, const unsigned char *ydata,
unsigned long ylen, unsigned long ylen,
const unsigned char *x, const unsigned char *x, unsigned long x_len);
unsigned long x_len); int _libssh2_dsa_new_private(libssh2_dsa_ctx ** dsa,
int _libssh2_dsa_new_private (libssh2_dsa_ctx **dsa, LIBSSH2_SESSION * session,
LIBSSH2_SESSION *session, FILE * fp, unsigned const char *passphrase);
FILE *fp, int _libssh2_dsa_sha1_verify(libssh2_dsa_ctx * dsa,
unsigned const char *passphrase); const unsigned char *sig,
int _libssh2_dsa_sha1_verify(libssh2_dsa_ctx *dsa, const unsigned char *m, unsigned long m_len);
const unsigned char *sig, int _libssh2_dsa_sha1_sign(libssh2_dsa_ctx * dsactx,
const unsigned char *m, const unsigned char *hash,
unsigned long m_len); unsigned long hash_len, unsigned char *sig);
int _libssh2_dsa_sha1_sign(libssh2_dsa_ctx *dsactx,
const unsigned char *hash,
unsigned long hash_len,
unsigned char *sig);
#define _libssh2_dsa_free(dsactx) gcry_sexp_release (dsactx) #define _libssh2_dsa_free(dsactx) gcry_sexp_release (dsactx)
@@ -167,16 +160,14 @@ int _libssh2_dsa_sha1_sign(libssh2_dsa_ctx *dsactx,
#define _libssh2_cipher_cast5 GCRY_CIPHER_CAST5 #define _libssh2_cipher_cast5 GCRY_CIPHER_CAST5
#define _libssh2_cipher_3des GCRY_CIPHER_3DES #define _libssh2_cipher_3des GCRY_CIPHER_3DES
int _libssh2_cipher_init (_libssh2_cipher_ctx *h, int _libssh2_cipher_init(_libssh2_cipher_ctx * h,
_libssh2_cipher_type(algo), _libssh2_cipher_type(algo),
unsigned char *iv, unsigned char *iv,
unsigned char *secret, unsigned char *secret, int encrypt);
int encrypt);
int _libssh2_cipher_crypt(_libssh2_cipher_ctx *ctx, int _libssh2_cipher_crypt(_libssh2_cipher_ctx * ctx,
_libssh2_cipher_type(algo), _libssh2_cipher_type(algo),
int encrypt, int encrypt, unsigned char *block);
unsigned char *block);
#define _libssh2_cipher_dtor(ctx) gcry_cipher_close(*(ctx)) #define _libssh2_cipher_dtor(ctx) gcry_cipher_close(*(ctx))

File diff suppressed because it is too large Load Diff

View File

@@ -41,12 +41,15 @@
/* {{{ libssh2_mac_none_MAC /* {{{ libssh2_mac_none_MAC
* Minimalist MAC: No MAC * Minimalist MAC: No MAC
*/ */
static int libssh2_mac_none_MAC(LIBSSH2_SESSION *session, unsigned char *buf, unsigned long seqno, static int
const unsigned char *packet, unsigned long packet_len, libssh2_mac_none_MAC(LIBSSH2_SESSION * session, unsigned char *buf,
const unsigned char *addtl, unsigned long addtl_len, void **abstract) unsigned long seqno, const unsigned char *packet,
unsigned long packet_len, const unsigned char *addtl,
unsigned long addtl_len, void **abstract)
{ {
return 0; return 0;
} }
/* }}} */ /* }}} */
@@ -63,20 +66,24 @@ static LIBSSH2_MAC_METHOD libssh2_mac_method_none = {
/* {{{ libssh2_mac_method_common_init /* {{{ libssh2_mac_method_common_init
* Initialize simple mac methods * 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; *abstract = key;
*free_key = 0; *free_key = 0;
(void)session; (void) session;
return 0; return 0;
} }
/* }}} */ /* }}} */
/* {{{ libssh2_mac_method_common_dtor /* {{{ libssh2_mac_method_common_dtor
* Cleanup simple mac methods * 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) { if (*abstract) {
LIBSSH2_FREE(session, *abstract); LIBSSH2_FREE(session, *abstract);
@@ -85,18 +92,23 @@ static int libssh2_mac_method_common_dtor(LIBSSH2_SESSION *session, void **abstr
return 0; return 0;
} }
/* }}} */ /* }}} */
/* {{{ libssh2_mac_method_hmac_sha1_hash /* {{{ libssh2_mac_method_hmac_sha1_hash
* Calculate hash using full sha1 value * Calculate hash using full sha1 value
*/ */
static int libssh2_mac_method_hmac_sha1_hash(LIBSSH2_SESSION *session, unsigned char *buf, unsigned long seqno, static int
const unsigned char *packet, unsigned long packet_len, libssh2_mac_method_hmac_sha1_hash(LIBSSH2_SESSION * session,
const unsigned char *addtl, unsigned long addtl_len, void **abstract) 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; libssh2_hmac_ctx ctx;
unsigned char seqno_buf[4]; unsigned char seqno_buf[4];
(void)session; (void) session;
libssh2_htonu32(seqno_buf, seqno); libssh2_htonu32(seqno_buf, seqno);
@@ -111,6 +123,7 @@ static int libssh2_mac_method_hmac_sha1_hash(LIBSSH2_SESSION *session, unsigned
return 0; return 0;
} }
/* }}} */ /* }}} */
static const LIBSSH2_MAC_METHOD libssh2_mac_method_hmac_sha1 = { 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 /* {{{ libssh2_mac_method_hmac_sha1_96_hash
* Calculate hash using first 96 bits of sha1 value * 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, static int
const unsigned char *packet, unsigned long packet_len, libssh2_mac_method_hmac_sha1_96_hash(LIBSSH2_SESSION * session,
const unsigned char *addtl, unsigned long addtl_len, void **abstract) 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]; 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,
memcpy(buf, (char *)temp, 96 / 8); addtl, addtl_len, abstract);
memcpy(buf, (char *) temp, 96 / 8);
return 0; return 0;
} }
/* }}} */ /* }}} */
static const LIBSSH2_MAC_METHOD libssh2_mac_method_hmac_sha1_96 = { static const LIBSSH2_MAC_METHOD libssh2_mac_method_hmac_sha1_96 = {
@@ -150,13 +169,17 @@ static const LIBSSH2_MAC_METHOD libssh2_mac_method_hmac_sha1_96 = {
/* {{{ libssh2_mac_method_hmac_md5_hash /* {{{ libssh2_mac_method_hmac_md5_hash
* Calculate hash using full md5 value * Calculate hash using full md5 value
*/ */
static int libssh2_mac_method_hmac_md5_hash(LIBSSH2_SESSION *session, unsigned char *buf, unsigned long seqno, static int
const unsigned char *packet, unsigned long packet_len, libssh2_mac_method_hmac_md5_hash(LIBSSH2_SESSION * session, unsigned char *buf,
const unsigned char *addtl, unsigned long addtl_len, void **abstract) 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; libssh2_hmac_ctx ctx;
unsigned char seqno_buf[4]; unsigned char seqno_buf[4];
(void)session; (void) session;
libssh2_htonu32(seqno_buf, seqno); libssh2_htonu32(seqno_buf, seqno);
@@ -171,6 +194,7 @@ static int libssh2_mac_method_hmac_md5_hash(LIBSSH2_SESSION *session, unsigned c
return 0; return 0;
} }
/* }}} */ /* }}} */
static const LIBSSH2_MAC_METHOD libssh2_mac_method_hmac_md5 = { 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 /* {{{ libssh2_mac_method_hmac_md5_96_hash
* Calculate hash using first 96 bits of md5 value * 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, static int
const unsigned char *packet, unsigned long packet_len, libssh2_mac_method_hmac_md5_96_hash(LIBSSH2_SESSION * session,
const unsigned char *addtl, unsigned long addtl_len, void **abstract) 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]; 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,
memcpy(buf, (char *)temp, 96 / 8); addtl, addtl_len, abstract);
memcpy(buf, (char *) temp, 96 / 8);
return 0; return 0;
} }
/* }}} */ /* }}} */
static const LIBSSH2_MAC_METHOD libssh2_mac_method_hmac_md5_96 = { static const LIBSSH2_MAC_METHOD libssh2_mac_method_hmac_md5_96 = {
@@ -211,13 +241,18 @@ static const LIBSSH2_MAC_METHOD libssh2_mac_method_hmac_md5_96 = {
/* {{{ libssh2_mac_method_hmac_ripemd160_hash /* {{{ libssh2_mac_method_hmac_ripemd160_hash
* Calculate hash using ripemd160 value * Calculate hash using ripemd160 value
*/ */
static int libssh2_mac_method_hmac_ripemd160_hash(LIBSSH2_SESSION *session, unsigned char *buf, unsigned long seqno, static int
const unsigned char *packet, unsigned long packet_len, libssh2_mac_method_hmac_ripemd160_hash(LIBSSH2_SESSION * session,
const unsigned char *addtl, unsigned long addtl_len, void **abstract) 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; libssh2_hmac_ctx ctx;
unsigned char seqno_buf[4]; unsigned char seqno_buf[4];
(void)session; (void) session;
libssh2_htonu32(seqno_buf, seqno); libssh2_htonu32(seqno_buf, seqno);
@@ -232,6 +267,7 @@ static int libssh2_mac_method_hmac_ripemd160_hash(LIBSSH2_SESSION *session, unsi
return 0; return 0;
} }
/* }}} */ /* }}} */
static const LIBSSH2_MAC_METHOD libssh2_mac_method_hmac_ripemd160 = { static const LIBSSH2_MAC_METHOD libssh2_mac_method_hmac_ripemd160 = {
@@ -268,7 +304,8 @@ static const LIBSSH2_MAC_METHOD *_libssh2_mac_methods[] = {
NULL NULL
}; };
const LIBSSH2_MAC_METHOD **libssh2_mac_methods(void) { const LIBSSH2_MAC_METHOD **
libssh2_mac_methods(void)
{
return _libssh2_mac_methods; return _libssh2_mac_methods;
} }

View File

@@ -42,17 +42,20 @@
/* {{{ libssh2_ntohu32 /* {{{ 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]; return (buf[0] << 24) | (buf[1] << 16) | (buf[2] << 8) | buf[3];
} }
/* }}} */ /* }}} */
/* {{{ libssh2_ntohu64 /* {{{ libssh2_ntohu64
* Note: Some 32-bit platforms have issues with bitops on long longs * 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 * 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; unsigned long msl, lsl;
@@ -61,22 +64,26 @@ libssh2_uint64_t libssh2_ntohu64(const unsigned char *buf)
return ((msl * 65536) * 65536) + lsl; return ((msl * 65536) * 65536) + lsl;
} }
/* }}} */ /* }}} */
/* {{{ libssh2_htonu32 /* {{{ 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[0] = (value >> 24) & 0xFF;
buf[1] = (value >> 16) & 0xFF; buf[1] = (value >> 16) & 0xFF;
buf[2] = (value >> 8) & 0xFF; buf[2] = (value >> 8) & 0xFF;
buf[3] = value & 0xFF; buf[3] = value & 0xFF;
} }
/* }}} */ /* }}} */
/* {{{ libssh2_htonu64 /* {{{ 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 = (value / 65536) / 65536;
@@ -90,6 +97,7 @@ void libssh2_htonu64(unsigned char *buf, libssh2_uint64_t value)
buf[6] = (value >> 8) & 0xFF; buf[6] = (value >> 8) & 0xFF;
buf[7] = value & 0xFF; buf[7] = value & 0xFF;
} }
/* }}} */ /* }}} */
/* Base64 Conversion */ /* Base64 Conversion */
@@ -97,11 +105,11 @@ void libssh2_htonu64(unsigned char *buf, libssh2_uint64_t value)
/* {{{ */ /* {{{ */
static const char libssh2_base64_table[] = static const char libssh2_base64_table[] =
{ 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', { 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M',
'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z',
'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm',
'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z',
'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '+', '/', '\0' '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '+', '/', '\0'
}; };
static const char libssh2_base64_pad = '='; static const char libssh2_base64_pad = '=';
@@ -110,7 +118,7 @@ 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,
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 62, -1, -1, -1, 63, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 62, -1, -1, -1, 63,
52, 53, 54, 55, 56, 57, 58, 59, 60, 61, -1, -1, -1, -1, -1, -1, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, -1, -1, -1, -1, -1, -1,
-1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, -1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14,
15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, -1, -1, -1, -1, -1, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, -1, -1, -1, -1, -1,
-1, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, -1, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40,
41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, -1, -1, -1, -1, -1, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, -1, -1, -1, -1, -1,
@@ -123,42 +131,46 @@ 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,
-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 /* {{{ libssh2_base64_decode
* Decode a base64 chunk and store it into a newly alloc'd buffer * 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, LIBSSH2_API int
const char *src, unsigned int src_len) libssh2_base64_decode(LIBSSH2_SESSION * session, char **data,
unsigned int *datalen, const char *src,
unsigned int src_len)
{ {
unsigned char *s, *d; unsigned char *s, *d;
short v; short v;
int i = 0, len = 0; int i = 0, len = 0;
*data = LIBSSH2_ALLOC(session, (3 * src_len / 4) + 1); *data = LIBSSH2_ALLOC(session, (3 * src_len / 4) + 1);
d = (unsigned char *)*data; d = (unsigned char *) *data;
if (!d) { if (!d) {
return -1; return -1;
} }
for(s = (unsigned char *)src; ((char*)s) < (src + src_len); s++) { 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) { switch (i % 4) {
case 0: case 0:
d[len] = v << 2; d[len] = v << 2;
break; break;
case 1: case 1:
d[len++] |= v >> 4; d[len++] |= v >> 4;
d[len] = v << 4; d[len] = v << 4;
break; break;
case 2: case 2:
d[len++] |= v >> 2; d[len++] |= v >> 2;
d[len] = v << 6; d[len] = v << 6;
break; break;
case 3: case 3:
d[len++] |= v; d[len++] |= v;
break; break;
} }
i++; i++;
} }
@@ -171,22 +183,24 @@ LIBSSH2_API int libssh2_base64_decode(LIBSSH2_SESSION *session, char **data, uns
*datalen = len; *datalen = len;
return 0; return 0;
} }
/* }}} */ /* }}} */
#ifdef LIBSSH2DEBUG #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; session->showmask = bitmask;
return 0; return 0;
} }
void _libssh2_debug(LIBSSH2_SESSION *session, int context, void
const char *format, ...) _libssh2_debug(LIBSSH2_SESSION * session, int context, const char *format, ...)
{ {
char buffer[1536]; char buffer[1536];
int len; int len;
va_list vargs; va_list vargs;
static const char * const contexts[9] = { static const char *const contexts[9] = {
"Unknown", "Unknown",
"Transport", "Transport",
"Key Exchange", "Key Exchange",
@@ -201,7 +215,7 @@ void _libssh2_debug(LIBSSH2_SESSION *session, int context,
if (context < 1 || context > 8) { if (context < 1 || context > 8) {
context = 0; context = 0;
} }
if (!(session->showmask & (1<<context))) { if (!(session->showmask & (1 << context))) {
/* no such output asked for */ /* no such output asked for */
return; return;
} }
@@ -217,10 +231,11 @@ void _libssh2_debug(LIBSSH2_SESSION *session, int context,
} }
#else #else
LIBSSH2_API int libssh2_trace(LIBSSH2_SESSION *session, int bitmask) LIBSSH2_API int
libssh2_trace(LIBSSH2_SESSION * session, int bitmask)
{ {
(void)session; (void) session;
(void)bitmask; (void) bitmask;
return 0; return 0;
} }
#endif #endif

View File

@@ -43,23 +43,23 @@
#define EVP_MAX_BLOCK_LENGTH 32 #define EVP_MAX_BLOCK_LENGTH 32
#endif #endif
int _libssh2_rsa_new(libssh2_rsa_ctx **rsa, int
const unsigned char *edata, _libssh2_rsa_new(libssh2_rsa_ctx ** rsa,
unsigned long elen, const unsigned char *edata,
const unsigned char *ndata, unsigned long elen,
unsigned long nlen, const unsigned char *ndata,
const unsigned char *ddata, unsigned long nlen,
unsigned long dlen, const unsigned char *ddata,
const unsigned char *pdata, unsigned long dlen,
unsigned long plen, const unsigned char *pdata,
const unsigned char *qdata, unsigned long plen,
unsigned long qlen, const unsigned char *qdata,
const unsigned char *e1data, unsigned long qlen,
unsigned long e1len, const unsigned char *e1data,
const unsigned char *e2data, unsigned long e1len,
unsigned long e2len, const unsigned char *e2data,
const unsigned char *coeffdata, unsigned long e2len,
unsigned long coefflen) const unsigned char *coeffdata, unsigned long coefflen)
{ {
*rsa = RSA_new(); *rsa = RSA_new();
@@ -91,32 +91,32 @@ int _libssh2_rsa_new(libssh2_rsa_ctx **rsa,
return 0; return 0;
} }
int _libssh2_rsa_sha1_verify(libssh2_rsa_ctx *rsactx, int
const unsigned char *sig, _libssh2_rsa_sha1_verify(libssh2_rsa_ctx * rsactx,
unsigned long sig_len, const unsigned char *sig,
const unsigned char *m, unsigned long sig_len,
unsigned long m_len) const unsigned char *m, unsigned long m_len)
{ {
unsigned char hash[SHA_DIGEST_LENGTH]; unsigned char hash[SHA_DIGEST_LENGTH];
int ret; int ret;
SHA1(m, m_len, hash); SHA1(m, m_len, hash);
ret = RSA_verify(NID_sha1, hash, SHA_DIGEST_LENGTH, ret = RSA_verify(NID_sha1, hash, SHA_DIGEST_LENGTH,
(unsigned char *)sig, sig_len, rsactx); (unsigned char *) sig, sig_len, rsactx);
return (ret == 1) ? 0 : -1; return (ret == 1) ? 0 : -1;
} }
int _libssh2_dsa_new(libssh2_dsa_ctx **dsactx, int
const unsigned char *p, _libssh2_dsa_new(libssh2_dsa_ctx ** dsactx,
unsigned long p_len, const unsigned char *p,
const unsigned char *q, unsigned long p_len,
unsigned long q_len, const unsigned char *q,
const unsigned char *g, unsigned long q_len,
unsigned long g_len, const unsigned char *g,
const unsigned char *y, unsigned long g_len,
unsigned long y_len, const unsigned char *y,
const unsigned char *x, unsigned long y_len,
unsigned long x_len) const unsigned char *x, unsigned long x_len)
{ {
*dsactx = DSA_new(); *dsactx = DSA_new();
@@ -140,10 +140,10 @@ int _libssh2_dsa_new(libssh2_dsa_ctx **dsactx,
return 0; return 0;
} }
int _libssh2_dsa_sha1_verify(libssh2_dsa_ctx *dsactx, int
const unsigned char *sig, _libssh2_dsa_sha1_verify(libssh2_dsa_ctx * dsactx,
const unsigned char *m, const unsigned char *sig,
unsigned long m_len) const unsigned char *m, unsigned long m_len)
{ {
unsigned char hash[SHA_DIGEST_LENGTH]; unsigned char hash[SHA_DIGEST_LENGTH];
DSA_SIG dsasig; DSA_SIG dsasig;
@@ -162,27 +162,26 @@ int _libssh2_dsa_sha1_verify(libssh2_dsa_ctx *dsactx,
return (ret == 1) ? 0 : -1; return (ret == 1) ? 0 : -1;
} }
int _libssh2_cipher_init (_libssh2_cipher_ctx *h, int
_libssh2_cipher_type(algo), _libssh2_cipher_init(_libssh2_cipher_ctx * h,
unsigned char *iv, _libssh2_cipher_type(algo),
unsigned char *secret, unsigned char *iv, unsigned char *secret, int encrypt)
int encrypt)
{ {
EVP_CIPHER_CTX_init(h); EVP_CIPHER_CTX_init(h);
EVP_CipherInit(h, algo(), secret, iv, encrypt); EVP_CipherInit(h, algo(), secret, iv, encrypt);
return 0; return 0;
} }
int _libssh2_cipher_crypt(_libssh2_cipher_ctx *ctx, int
_libssh2_cipher_type(algo), _libssh2_cipher_crypt(_libssh2_cipher_ctx * ctx,
int encrypt, _libssh2_cipher_type(algo),
unsigned char *block) int encrypt, unsigned char *block)
{ {
int blocksize = ctx->cipher->block_size; int blocksize = ctx->cipher->block_size;
unsigned char buf[EVP_MAX_BLOCK_LENGTH]; unsigned char buf[EVP_MAX_BLOCK_LENGTH];
int ret; int ret;
(void)algo; (void) algo;
(void)encrypt; (void) encrypt;
if (blocksize == 1) { if (blocksize == 1) {
/* Hack for arcfour. */ /* Hack for arcfour. */
@@ -199,11 +198,10 @@ int _libssh2_cipher_crypt(_libssh2_cipher_ctx *ctx,
* calling program * calling program
*/ */
static int static int
passphrase_cb(char *buf, int size, passphrase_cb(char *buf, int size, int rwflag, char *passphrase)
int rwflag, char *passphrase)
{ {
int passphrase_len = strlen(passphrase); int passphrase_len = strlen(passphrase);
(void)rwflag; (void) rwflag;
if (passphrase_len > (size - 1)) { if (passphrase_len > (size - 1)) {
passphrase_len = size - 1; passphrase_len = size - 1;
@@ -214,12 +212,12 @@ passphrase_cb(char *buf, int size,
return passphrase_len; return passphrase_len;
} }
int _libssh2_rsa_new_private (libssh2_rsa_ctx **rsa, int
LIBSSH2_SESSION *session, _libssh2_rsa_new_private(libssh2_rsa_ctx ** rsa,
FILE *fp, LIBSSH2_SESSION * session,
unsigned const char *passphrase) FILE * fp, unsigned const char *passphrase)
{ {
(void)session; (void) session;
if (!EVP_get_cipherbyname("des")) { if (!EVP_get_cipherbyname("des")) {
/* If this cipher isn't loaded it's a pretty good indication that none are. /* If this cipher isn't loaded it's a pretty good indication that none are.
* I have *NO DOUBT* that there's a better way to deal with this ($#&%#$(%$#( * I have *NO DOUBT* that there's a better way to deal with this ($#&%#$(%$#(
@@ -227,20 +225,20 @@ int _libssh2_rsa_new_private (libssh2_rsa_ctx **rsa,
*/ */
OpenSSL_add_all_ciphers(); OpenSSL_add_all_ciphers();
} }
*rsa = PEM_read_RSAPrivateKey(fp, NULL, (void*)passphrase_cb, *rsa = PEM_read_RSAPrivateKey(fp, NULL, (void *) passphrase_cb,
(void*)passphrase); (void *) passphrase);
if (!*rsa) { if (!*rsa) {
return -1; return -1;
} }
return 0; return 0;
} }
int _libssh2_dsa_new_private (libssh2_dsa_ctx **dsa, int
LIBSSH2_SESSION *session, _libssh2_dsa_new_private(libssh2_dsa_ctx ** dsa,
FILE *fp, LIBSSH2_SESSION * session,
unsigned const char *passphrase) FILE * fp, unsigned const char *passphrase)
{ {
(void)session; (void) session;
if (!EVP_get_cipherbyname("des")) { if (!EVP_get_cipherbyname("des")) {
/* If this cipher isn't loaded it's a pretty good indication that none are. /* If this cipher isn't loaded it's a pretty good indication that none are.
* I have *NO DOUBT* that there's a better way to deal with this ($#&%#$(%$#( * I have *NO DOUBT* that there's a better way to deal with this ($#&%#$(%$#(
@@ -248,20 +246,20 @@ int _libssh2_dsa_new_private (libssh2_dsa_ctx **dsa,
*/ */
OpenSSL_add_all_ciphers(); OpenSSL_add_all_ciphers();
} }
*dsa = PEM_read_DSAPrivateKey(fp, NULL, (void*)passphrase_cb, *dsa = PEM_read_DSAPrivateKey(fp, NULL, (void *) passphrase_cb,
(void*)passphrase); (void *) passphrase);
if (!*dsa) { if (!*dsa) {
return -1; return -1;
} }
return 0; return 0;
} }
int _libssh2_rsa_sha1_sign(LIBSSH2_SESSION *session, int
libssh2_rsa_ctx *rsactx, _libssh2_rsa_sha1_sign(LIBSSH2_SESSION * session,
const unsigned char *hash, libssh2_rsa_ctx * rsactx,
unsigned long hash_len, const unsigned char *hash,
unsigned char **signature, unsigned long hash_len,
unsigned long *signature_len) unsigned char **signature, unsigned long *signature_len)
{ {
int ret; int ret;
unsigned char *sig; unsigned char *sig;
@@ -287,14 +285,14 @@ int _libssh2_rsa_sha1_sign(LIBSSH2_SESSION *session,
return 0; return 0;
} }
int _libssh2_dsa_sha1_sign(libssh2_dsa_ctx *dsactx, int
const unsigned char *hash, _libssh2_dsa_sha1_sign(libssh2_dsa_ctx * dsactx,
unsigned long hash_len, const unsigned char *hash,
unsigned char *signature) unsigned long hash_len, unsigned char *signature)
{ {
DSA_SIG *sig; DSA_SIG *sig;
int r_len, s_len, rs_pad; int r_len, s_len, rs_pad;
(void)hash_len; (void) hash_len;
sig = DSA_do_sign(hash, SHA_DIGEST_LENGTH, dsactx); sig = DSA_do_sign(hash, SHA_DIGEST_LENGTH, dsactx);
if (!sig) { if (!sig) {

View File

@@ -131,66 +131,59 @@
#define libssh2_rsa_ctx RSA #define libssh2_rsa_ctx RSA
int _libssh2_rsa_new(libssh2_rsa_ctx **rsa, int _libssh2_rsa_new(libssh2_rsa_ctx ** rsa,
const unsigned char *edata, const unsigned char *edata,
unsigned long elen, unsigned long elen,
const unsigned char *ndata, const unsigned char *ndata,
unsigned long nlen, unsigned long nlen,
const unsigned char *ddata, const unsigned char *ddata,
unsigned long dlen, unsigned long dlen,
const unsigned char *pdata, const unsigned char *pdata,
unsigned long plen, unsigned long plen,
const unsigned char *qdata, const unsigned char *qdata,
unsigned long qlen, unsigned long qlen,
const unsigned char *e1data, const unsigned char *e1data,
unsigned long e1len, unsigned long e1len,
const unsigned char *e2data, const unsigned char *e2data,
unsigned long e2len, unsigned long e2len,
const unsigned char *coeffdata, const unsigned char *coeffdata, unsigned long coefflen);
unsigned long coefflen); int _libssh2_rsa_new_private(libssh2_rsa_ctx ** rsa,
int _libssh2_rsa_new_private (libssh2_rsa_ctx **rsa, LIBSSH2_SESSION * session,
LIBSSH2_SESSION *session, FILE * fp, unsigned const char *passphrase);
FILE *fp, int _libssh2_rsa_sha1_verify(libssh2_rsa_ctx * rsa,
unsigned const char *passphrase); const unsigned char *sig,
int _libssh2_rsa_sha1_verify(libssh2_rsa_ctx *rsa, unsigned long sig_len,
const unsigned char *sig, const unsigned char *m, unsigned long m_len);
unsigned long sig_len, int _libssh2_rsa_sha1_sign(LIBSSH2_SESSION * session,
const unsigned char *m, libssh2_rsa_ctx * rsactx,
unsigned long m_len); const unsigned char *hash,
int _libssh2_rsa_sha1_sign(LIBSSH2_SESSION *session, unsigned long hash_len,
libssh2_rsa_ctx *rsactx, unsigned char **signature,
const unsigned char *hash, unsigned long *signature_len);
unsigned long hash_len,
unsigned char **signature,
unsigned long *signature_len);
#define _libssh2_rsa_free(rsactx) RSA_free(rsactx) #define _libssh2_rsa_free(rsactx) RSA_free(rsactx)
#define libssh2_dsa_ctx DSA #define libssh2_dsa_ctx DSA
int _libssh2_dsa_new(libssh2_dsa_ctx **dsa, int _libssh2_dsa_new(libssh2_dsa_ctx ** dsa,
const unsigned char *pdata, const unsigned char *pdata,
unsigned long plen, unsigned long plen,
const unsigned char *qdata, const unsigned char *qdata,
unsigned long qlen, unsigned long qlen,
const unsigned char *gdata, const unsigned char *gdata,
unsigned long glen, unsigned long glen,
const unsigned char *ydata, const unsigned char *ydata,
unsigned long ylen, unsigned long ylen,
const unsigned char *x, const unsigned char *x, unsigned long x_len);
unsigned long x_len); int _libssh2_dsa_new_private(libssh2_dsa_ctx ** dsa,
int _libssh2_dsa_new_private (libssh2_dsa_ctx **dsa, LIBSSH2_SESSION * session,
LIBSSH2_SESSION *session, FILE * fp, unsigned const char *passphrase);
FILE *fp, int _libssh2_dsa_sha1_verify(libssh2_dsa_ctx * dsactx,
unsigned const char *passphrase); const unsigned char *sig,
int _libssh2_dsa_sha1_verify(libssh2_dsa_ctx *dsactx, const unsigned char *m, unsigned long m_len);
const unsigned char *sig, int _libssh2_dsa_sha1_sign(libssh2_dsa_ctx * dsactx,
const unsigned char *m, const unsigned char *hash,
unsigned long m_len); unsigned long hash_len, unsigned char *sig);
int _libssh2_dsa_sha1_sign(libssh2_dsa_ctx *dsactx,
const unsigned char *hash,
unsigned long hash_len,
unsigned char *sig);
#define _libssh2_dsa_free(dsactx) DSA_free(dsactx) #define _libssh2_dsa_free(dsactx) DSA_free(dsactx)
@@ -205,16 +198,14 @@ int _libssh2_dsa_sha1_sign(libssh2_dsa_ctx *dsactx,
#define _libssh2_cipher_cast5 EVP_cast5_cbc #define _libssh2_cipher_cast5 EVP_cast5_cbc
#define _libssh2_cipher_3des EVP_des_ede3_cbc #define _libssh2_cipher_3des EVP_des_ede3_cbc
int _libssh2_cipher_init (_libssh2_cipher_ctx *h, int _libssh2_cipher_init(_libssh2_cipher_ctx * h,
_libssh2_cipher_type(algo), _libssh2_cipher_type(algo),
unsigned char *iv, unsigned char *iv,
unsigned char *secret, unsigned char *secret, int encrypt);
int encrypt);
int _libssh2_cipher_crypt(_libssh2_cipher_ctx *ctx, int _libssh2_cipher_crypt(_libssh2_cipher_ctx * ctx,
_libssh2_cipher_type(algo), _libssh2_cipher_type(algo),
int encrypt, int encrypt, unsigned char *block);
unsigned char *block);
#define _libssh2_cipher_dtor(ctx) EVP_CIPHER_CTX_cleanup(ctx) #define _libssh2_cipher_dtor(ctx) EVP_CIPHER_CTX_cleanup(ctx)

File diff suppressed because it is too large Load Diff

114
src/pem.c
View File

@@ -37,18 +37,16 @@
#include "libssh2_priv.h" #include "libssh2_priv.h"
static int readline (char *line, int line_size, FILE *fp) static int
readline(char *line, int line_size, FILE * fp)
{ {
if (!fgets(line, line_size, fp)) if (!fgets(line, line_size, fp)) {
{
return -1; return -1;
} }
if (*line && line[strlen(line) - 1] == '\r') if (*line && line[strlen(line) - 1] == '\n') {
{
line[strlen(line) - 1] = '\0'; line[strlen(line) - 1] = '\0';
} }
if (*line && line[strlen(line) - 1] == '\n') if (*line && line[strlen(line) - 1] == '\r') {
{
line[strlen(line) - 1] = '\0'; line[strlen(line) - 1] = '\0';
} }
return 0; return 0;
@@ -56,132 +54,114 @@ static int readline (char *line, int line_size, FILE *fp)
#define LINE_SIZE 128 #define LINE_SIZE 128
int _libssh2_pem_parse (LIBSSH2_SESSION *session, int
const char *headerbegin, _libssh2_pem_parse(LIBSSH2_SESSION * session,
const char *headerend, const char *headerbegin,
FILE *fp, const char *headerend,
char **data, unsigned int *datalen) FILE * fp, char **data, unsigned int *datalen)
{ {
char line[LINE_SIZE]; char line[LINE_SIZE];
char *b64data = NULL; char *b64data = NULL;
unsigned int b64datalen = 0; unsigned int b64datalen = 0;
int ret; int ret;
do do {
{ if (readline(line, LINE_SIZE, fp)) {
if (readline(line, LINE_SIZE, fp))
{
return -1; return -1;
} }
} }
while (strcmp (line, headerbegin) != 0); while (strcmp(line, headerbegin) != 0);
*line = '\0'; *line = '\0';
do do {
{ if (*line) {
if (*line)
{
char *tmp; char *tmp;
size_t linelen; size_t linelen;
linelen = strlen (line); linelen = strlen(line);
tmp = LIBSSH2_REALLOC (session, b64data, tmp = LIBSSH2_REALLOC(session, b64data, b64datalen + linelen);
b64datalen + linelen); if (!tmp) {
if (!tmp)
{
ret = -1; ret = -1;
goto out; goto out;
} }
memcpy (tmp + b64datalen, line, linelen); memcpy(tmp + b64datalen, line, linelen);
b64data = tmp; b64data = tmp;
b64datalen += linelen; b64datalen += linelen;
} }
if (readline(line, LINE_SIZE, fp)) if (readline(line, LINE_SIZE, fp)) {
{
ret = -1; ret = -1;
goto out; goto out;
} }
} while (strcmp (line, headerend) != 0); } while (strcmp(line, headerend) != 0);
if (libssh2_base64_decode(session, data, datalen, if (libssh2_base64_decode(session, data, datalen, b64data, b64datalen)) {
b64data, b64datalen))
{
ret = -1; ret = -1;
goto out; goto out;
} }
ret = 0; ret = 0;
out: out:
if (b64data) { if (b64data) {
LIBSSH2_FREE (session, b64data); LIBSSH2_FREE(session, b64data);
} }
return ret; return ret;
} }
static int read_asn1_length (const unsigned char *data, static int
unsigned int datalen, read_asn1_length(const unsigned char *data,
unsigned int *len) unsigned int datalen, unsigned int *len)
{ {
unsigned int lenlen; unsigned int lenlen;
int nextpos; int nextpos;
if (datalen < 1) if (datalen < 1) {
{
return -1; return -1;
} }
*len = data[0]; *len = data[0];
if (*len >= 0x80) if (*len >= 0x80) {
{
lenlen = *len & 0x7F; lenlen = *len & 0x7F;
*len = data[1]; *len = data[1];
if (1 + lenlen > datalen) if (1 + lenlen > datalen) {
{
return -1; return -1;
} }
if (lenlen > 1) if (lenlen > 1) {
{
*len <<= 8; *len <<= 8;
*len |= data[2]; *len |= data[2];
} }
} } else {
else
{
lenlen = 0; lenlen = 0;
} }
nextpos = 1 + lenlen; nextpos = 1 + lenlen;
if (lenlen > 2 || 1 + lenlen + *len > datalen) if (lenlen > 2 || 1 + lenlen + *len > datalen) {
{
return -1; return -1;
} }
return nextpos; 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; unsigned int len;
int lenlen; int lenlen;
if (*datalen < 1) if (*datalen < 1) {
{
return -1; return -1;
} }
if ((*data)[0] != '\x30') if ((*data)[0] != '\x30') {
{
return -1; return -1;
} }
(*data)++; (*data)++;
(*datalen)--; (*datalen)--;
lenlen = read_asn1_length (*data, *datalen, &len); lenlen = read_asn1_length(*data, *datalen, &len);
if (lenlen < 0 || lenlen + len != *datalen) if (lenlen < 0 || lenlen + len != *datalen) {
{
return -1; return -1;
} }
@@ -191,28 +171,26 @@ int _libssh2_pem_decode_sequence (unsigned char **data, unsigned int *datalen)
return 0; return 0;
} }
int _libssh2_pem_decode_integer (unsigned char **data, unsigned int *datalen, int
unsigned char **i, unsigned int *ilen) _libssh2_pem_decode_integer(unsigned char **data, unsigned int *datalen,
unsigned char **i, unsigned int *ilen)
{ {
unsigned int len; unsigned int len;
int lenlen; int lenlen;
if (*datalen < 1) if (*datalen < 1) {
{
return -1; return -1;
} }
if ((*data)[0] != '\x02') if ((*data)[0] != '\x02') {
{
return -1; return -1;
} }
(*data)++; (*data)++;
(*datalen)--; (*datalen)--;
lenlen = read_asn1_length (*data, *datalen, &len); lenlen = read_asn1_length(*data, *datalen, &len);
if (lenlen < 0 || lenlen + len > *datalen) if (lenlen < 0 || lenlen + len > *datalen) {
{
return -1; return -1;
} }

File diff suppressed because it is too large Load Diff

565
src/scp.c
View File

@@ -46,7 +46,8 @@
* otherwise the blocking error code would erase the true * otherwise the blocking error code would erase the true
* cause of the error. * 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 path_len = strlen(path);
int rc; int rc;
@@ -56,63 +57,78 @@ LIBSSH2_API LIBSSH2_CHANNEL *libssh2_scp_recv(LIBSSH2_SESSION *session, const ch
session->scpRecv_size = 0; session->scpRecv_size = 0;
session->scpRecv_mtime = 0; session->scpRecv_mtime = 0;
session->scpRecv_atime = 0; session->scpRecv_atime = 0;
session->scpRecv_command_len = path_len + sizeof("scp -f "); session->scpRecv_command_len = path_len + sizeof("scp -f ");
if (sb) { if (sb) {
session->scpRecv_command_len++; 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) { 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; return NULL;
} }
if (sb) { if (sb) {
memcpy(session->scpRecv_command, "scp -pf ", sizeof("scp -pf ") - 1); memcpy(session->scpRecv_command, "scp -pf ",
memcpy(session->scpRecv_command + sizeof("scp -pf ") - 1, path, path_len); sizeof("scp -pf ") - 1);
memcpy(session->scpRecv_command + sizeof("scp -pf ") - 1, path,
path_len);
} else { } else {
memcpy(session->scpRecv_command, "scp -f ", sizeof("scp -f ") - 1); 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'; 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; session->scpRecv_state = libssh2_NB_state_created;
} }
if (session->scpRecv_state == libssh2_NB_state_created) { if (session->scpRecv_state == libssh2_NB_state_created) {
/* Allocate a channel */ /* Allocate a channel */
do { do {
session->scpRecv_channel = libssh2_channel_open_ex(session, "session", sizeof("session") - 1, session->scpRecv_channel =
LIBSSH2_CHANNEL_WINDOW_DEFAULT, LIBSSH2_CHANNEL_PACKET_DEFAULT, libssh2_channel_open_ex(session, "session",
NULL, 0); sizeof("session") - 1,
LIBSSH2_CHANNEL_WINDOW_DEFAULT,
LIBSSH2_CHANNEL_PACKET_DEFAULT, NULL,
0);
if (!session->scpRecv_channel) { 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); LIBSSH2_FREE(session, session->scpRecv_command);
session->scpRecv_command = NULL; session->scpRecv_command = NULL;
session->scpRecv_state = libssh2_NB_state_idle; session->scpRecv_state = libssh2_NB_state_idle;
return NULL; return NULL;
} } else if (libssh2_session_last_errno(session) ==
else if (libssh2_session_last_errno(session) == LIBSSH2_ERROR_EAGAIN) { LIBSSH2_ERROR_EAGAIN) {
libssh2_error(session, LIBSSH2_ERROR_EAGAIN, "Would block starting up channel", 0); libssh2_error(session, LIBSSH2_ERROR_EAGAIN,
"Would block starting up channel", 0);
return NULL; return NULL;
} }
} }
} while (!session->scpRecv_channel); } while (!session->scpRecv_channel);
session->scpRecv_state = libssh2_NB_state_sent; session->scpRecv_state = libssh2_NB_state_sent;
} }
if (session->scpRecv_state == libssh2_NB_state_sent) { if (session->scpRecv_state == libssh2_NB_state_sent) {
/* Request SCP for the desired file */ /* 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) { 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; return NULL;
} } else if (rc) {
else if (rc) {
LIBSSH2_FREE(session, session->scpRecv_command); LIBSSH2_FREE(session, session->scpRecv_command);
session->scpRecv_command = NULL; session->scpRecv_command = NULL;
goto scp_recv_error; goto scp_recv_error;
@@ -123,63 +139,125 @@ LIBSSH2_API LIBSSH2_CHANNEL *libssh2_scp_recv(LIBSSH2_SESSION *session, const ch
_libssh2_debug(session, LIBSSH2_DBG_SCP, "Sending initial wakeup"); _libssh2_debug(session, LIBSSH2_DBG_SCP, "Sending initial wakeup");
/* SCP ACK */ /* SCP ACK */
session->scpRecv_response[0] = '\0'; session->scpRecv_response[0] = '\0';
session->scpRecv_state = libssh2_NB_state_sent1; session->scpRecv_state = libssh2_NB_state_sent1;
} }
if (session->scpRecv_state == libssh2_NB_state_sent1) { 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) { 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; return NULL;
} } else if (rc != 1) {
else if (rc != 1) {
goto scp_recv_error; goto scp_recv_error;
} }
/* Parse SCP response */ /* Parse SCP response */
session->scpRecv_response_len = 0; session->scpRecv_response_len = 0;
session->scpRecv_state = libssh2_NB_state_sent2; session->scpRecv_state = libssh2_NB_state_sent2;
} }
if ((session->scpRecv_state == libssh2_NB_state_sent2) || (session->scpRecv_state == libssh2_NB_state_sent3)) { if ((session->scpRecv_state == libssh2_NB_state_sent2)
while (sb && (session->scpRecv_response_len < LIBSSH2_SCP_RESPONSE_BUFLEN)) { || (session->scpRecv_state == libssh2_NB_state_sent3)) {
while (sb
&& (session->scpRecv_response_len <
LIBSSH2_SCP_RESPONSE_BUFLEN)) {
unsigned char *s, *p; unsigned char *s, *p;
if (session->scpRecv_state == libssh2_NB_state_sent2) { if (session->scpRecv_state == libssh2_NB_state_sent2) {
rc = libssh2_channel_read_ex(session->scpRecv_channel, 0, 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) { 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; return NULL;
} } else if (rc <= 0) {
else if (rc <= 0) {
/* Timeout, give up */ /* 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; goto scp_recv_error;
} }
session->scpRecv_response_len++; session->scpRecv_response_len++;
if (session->scpRecv_response[0] != 'T') { if (session->scpRecv_response[0] != 'T') {
libssh2_error(session, LIBSSH2_ERROR_SCP_PROTOCOL, "Invalid data in SCP response, missing Time data", 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 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);
if (!session->scpRecv_err_msg) {
goto scp_recv_error;
}
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);
if (rc <= 0) {
/*
* Since we have alread started reading this packet, it is
* already in the systems so it can't return PACKET_EAGAIN
*/
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);
goto scp_recv_error;
}
libssh2_error(session, LIBSSH2_ERROR_SCP_PROTOCOL,
session->scpRecv_err_msg, 1);
session->scpRecv_err_msg = NULL;
goto scp_recv_error; goto scp_recv_error;
} }
if ((session->scpRecv_response_len > 1) && if ((session->scpRecv_response_len > 1) &&
((session->scpRecv_response[session->scpRecv_response_len-1] < '0') || ((session->
(session->scpRecv_response[session->scpRecv_response_len-1] > '9')) && scpRecv_response[session->scpRecv_response_len - 1] <
(session->scpRecv_response[session->scpRecv_response_len-1] != ' ') && '0')
(session->scpRecv_response[session->scpRecv_response_len-1] != '\r') && || (session->
(session->scpRecv_response[session->scpRecv_response_len-1] != '\n')) { scpRecv_response[session->scpRecv_response_len - 1] >
libssh2_error(session, LIBSSH2_ERROR_SCP_PROTOCOL, "Invalid data in SCP response", 0); '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; goto scp_recv_error;
} }
if ((session->scpRecv_response_len < 9) || (session->scpRecv_response[session->scpRecv_response_len-1] != '\n')) { if ((session->scpRecv_response_len < 9)
if (session->scpRecv_response_len == LIBSSH2_SCP_RESPONSE_BUFLEN) { || (session->
scpRecv_response[session->scpRecv_response_len - 1] !=
'\n')) {
if (session->scpRecv_response_len ==
LIBSSH2_SCP_RESPONSE_BUFLEN) {
/* You had your chance */ /* 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; goto scp_recv_error;
} }
/* Way too short to be an SCP response, or not done yet, short circuit */ /* Way too short to be an SCP response, or not done yet, short circuit */
@@ -187,125 +265,168 @@ 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 */ /* 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--; while ((session->
session->scpRecv_response[session->scpRecv_response_len] = '\0'; 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) { if (session->scpRecv_response_len < 8) {
/* EOL came too soon */ /* 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; goto scp_recv_error;
} }
s = session->scpRecv_response + 1; s = session->scpRecv_response + 1;
p = (unsigned char *)strchr((char *)s, ' '); p = (unsigned char *) strchr((char *) s, ' ');
if (!p || ((p - s) <= 0)) { if (!p || ((p - s) <= 0)) {
/* No spaces or space in the wrong spot */ /* 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; goto scp_recv_error;
} }
*(p++) = '\0'; *(p++) = '\0';
/* Make sure we don't get fooled by leftover values */ /* Make sure we don't get fooled by leftover values */
errno = 0; errno = 0;
session->scpRecv_mtime = strtol((char *)s, NULL, 10); session->scpRecv_mtime = strtol((char *) s, NULL, 10);
if (errno) { 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; goto scp_recv_error;
} }
s = (unsigned char *)strchr((char *)p, ' '); s = (unsigned char *) strchr((char *) p, ' ');
if (!s || ((s - p) <= 0)) { if (!s || ((s - p) <= 0)) {
/* No spaces or space in the wrong spot */ /* 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; goto scp_recv_error;
} }
/* Ignore mtime.usec */ /* Ignore mtime.usec */
s++; s++;
p = (unsigned char *)strchr((char *)s, ' '); p = (unsigned char *) strchr((char *) s, ' ');
if (!p || ((p - s) <= 0)) { if (!p || ((p - s) <= 0)) {
/* No spaces or space in the wrong spot */ /* 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; goto scp_recv_error;
} }
*(p++) = '\0'; *(p++) = '\0';
/* Make sure we don't get fooled by leftover values */ /* Make sure we don't get fooled by leftover values */
errno = 0; errno = 0;
session->scpRecv_atime = strtol((char *)s, NULL, 10); session->scpRecv_atime = strtol((char *) s, NULL, 10);
if (errno) { 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; goto scp_recv_error;
} }
/* SCP ACK */ /* SCP ACK */
session->scpRecv_response[0] = '\0'; session->scpRecv_response[0] = '\0';
session->scpRecv_state = libssh2_NB_state_sent3; session->scpRecv_state = libssh2_NB_state_sent3;
} }
if (session->scpRecv_state == libssh2_NB_state_sent3) { 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) { 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; return NULL;
} } else if (rc != 1) {
else if (rc != 1) {
goto scp_recv_error; 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? */ /* We *should* check that atime.usec is valid, but why let that stop use? */
break; break;
} }
} }
session->scpRecv_state = libssh2_NB_state_sent4; session->scpRecv_state = libssh2_NB_state_sent4;
} }
if (session->scpRecv_state == libssh2_NB_state_sent4) { if (session->scpRecv_state == libssh2_NB_state_sent4) {
session->scpRecv_response_len = 0; session->scpRecv_response_len = 0;
session->scpRecv_state = libssh2_NB_state_sent5; 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) { while (session->scpRecv_response_len < LIBSSH2_SCP_RESPONSE_BUFLEN) {
char *s, *p, *e = NULL; char *s, *p, *e = NULL;
if (session->scpRecv_state == libssh2_NB_state_sent5) { if (session->scpRecv_state == libssh2_NB_state_sent5) {
rc = libssh2_channel_read_ex(session->scpRecv_channel, 0, 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) { 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; return NULL;
} } else if (rc <= 0) {
else if (rc <= 0) {
/* Timeout, give up */ /* 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; goto scp_recv_error;
} }
session->scpRecv_response_len++; session->scpRecv_response_len++;
if (session->scpRecv_response[0] != 'C') { 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; goto scp_recv_error;
} }
if ((session->scpRecv_response_len > 1) && if ((session->scpRecv_response_len > 1) &&
(session->scpRecv_response[session->scpRecv_response_len-1] != '\r') && (session->
(session->scpRecv_response[session->scpRecv_response_len-1] != '\n') && scpRecv_response[session->scpRecv_response_len - 1] !=
((session->scpRecv_response[session->scpRecv_response_len-1] < 32) || '\r')
(session->scpRecv_response[session->scpRecv_response_len-1] > 126))) { && (session->
libssh2_error(session, LIBSSH2_ERROR_SCP_PROTOCOL, "Invalid data in SCP response", 0); 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; goto scp_recv_error;
} }
if ((session->scpRecv_response_len < 7) || (session->scpRecv_response[session->scpRecv_response_len-1] != '\n')) { if ((session->scpRecv_response_len < 7)
if (session->scpRecv_response_len == LIBSSH2_SCP_RESPONSE_BUFLEN) { || (session->
scpRecv_response[session->scpRecv_response_len - 1] !=
'\n')) {
if (session->scpRecv_response_len ==
LIBSSH2_SCP_RESPONSE_BUFLEN) {
/* You had your chance */ /* 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; goto scp_recv_error;
} }
/* Way too short to be an SCP response, or not done yet, short circuit */ /* Way too short to be an SCP response, or not done yet, short circuit */
@@ -313,24 +434,33 @@ 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 */ /* We're guaranteed not to go under response_len == 0 by the logic above */
while ((session->scpRecv_response[session->scpRecv_response_len-1] == '\r') || while ((session->
(session->scpRecv_response[session->scpRecv_response_len-1] == '\n')) { scpRecv_response[session->scpRecv_response_len - 1] ==
'\r')
|| (session->
scpRecv_response[session->scpRecv_response_len -
1] == '\n')) {
session->scpRecv_response_len--; 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) { if (session->scpRecv_response_len < 6) {
/* EOL came too soon */ /* 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; goto scp_recv_error;
} }
s = (char *)session->scpRecv_response + 1; s = (char *) session->scpRecv_response + 1;
p = strchr(s, ' '); p = strchr(s, ' ');
if (!p || ((p - s) <= 0)) { if (!p || ((p - s) <= 0)) {
/* No spaces or space in the wrong spot */ /* 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; goto scp_recv_error;
} }
@@ -339,14 +469,17 @@ LIBSSH2_API LIBSSH2_CHANNEL *libssh2_scp_recv(LIBSSH2_SESSION *session, const ch
errno = 0; errno = 0;
session->scpRecv_mode = strtol(s, &e, 8); session->scpRecv_mode = strtol(s, &e, 8);
if ((e && *e) || errno) { 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; goto scp_recv_error;
} }
s = strchr(p, ' '); s = strchr(p, ' ');
if (!s || ((s - p) <= 0)) { if (!s || ((s - p) <= 0)) {
/* No spaces or space in the wrong spot */ /* 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); 0);
goto scp_recv_error; goto scp_recv_error;
} }
@@ -356,32 +489,38 @@ LIBSSH2_API LIBSSH2_CHANNEL *libssh2_scp_recv(LIBSSH2_SESSION *session, const ch
errno = 0; errno = 0;
session->scpRecv_size = strtol(p, &e, 10); session->scpRecv_size = strtol(p, &e, 10);
if ((e && *e) || errno) { 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; goto scp_recv_error;
} }
/* SCP ACK */ /* SCP ACK */
session->scpRecv_response[0] = '\0'; session->scpRecv_response[0] = '\0';
session->scpRecv_state = libssh2_NB_state_sent6; session->scpRecv_state = libssh2_NB_state_sent6;
} }
if (session->scpRecv_state == libssh2_NB_state_sent6) { 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) { 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; return NULL;
} } else if (rc != 1) {
else if (rc != 1) {
goto scp_recv_error; 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? */ /* We *should* check that basename is valid, but why let that stop us? */
break; break;
} }
} }
session->scpRecv_state = libssh2_NB_state_sent7; session->scpRecv_state = libssh2_NB_state_sent7;
} }
@@ -396,13 +535,14 @@ LIBSSH2_API LIBSSH2_CHANNEL *libssh2_scp_recv(LIBSSH2_SESSION *session, const ch
session->scpRecv_state = libssh2_NB_state_idle; session->scpRecv_state = libssh2_NB_state_idle;
return session->scpRecv_channel; return session->scpRecv_channel;
scp_recv_error: scp_recv_error:
while (libssh2_channel_free(session->scpRecv_channel) == PACKET_EAGAIN); while (libssh2_channel_free(session->scpRecv_channel) == PACKET_EAGAIN);
session->scpRecv_channel = NULL; session->scpRecv_channel = NULL;
session->scpRecv_state = libssh2_NB_state_idle; session->scpRecv_state = libssh2_NB_state_idle;
return NULL; return NULL;
} }
/* }}} */ /* }}} */
/* {{{ libssh2_scp_send_ex /* {{{ libssh2_scp_send_ex
@@ -413,7 +553,8 @@ scp_recv_error:
* cause of the error. * cause of the error.
*/ */
LIBSSH2_API LIBSSH2_CHANNEL * 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); int path_len = strlen(path);
unsigned const char *base; unsigned const char *base;
@@ -421,123 +562,147 @@ libssh2_scp_send_ex(LIBSSH2_SESSION *session, const char *path, int mode, size_t
if (session->scpSend_state == libssh2_NB_state_idle) { if (session->scpSend_state == libssh2_NB_state_idle) {
session->scpSend_command_len = path_len + sizeof("scp -t "); session->scpSend_command_len = path_len + sizeof("scp -t ");
if (mtime || atime) { if (mtime || atime) {
session->scpSend_command_len++; 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) { 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; return NULL;
} }
if (mtime || atime) { if (mtime || atime) {
memcpy(session->scpSend_command, "scp -pt ", sizeof("scp -pt ") - 1); memcpy(session->scpSend_command, "scp -pt ",
memcpy(session->scpSend_command + sizeof("scp -pt ") - 1, path, path_len); sizeof("scp -pt ") - 1);
memcpy(session->scpSend_command + sizeof("scp -pt ") - 1, path,
path_len);
} else { } else {
memcpy(session->scpSend_command, "scp -t ", sizeof("scp -t ") - 1); 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'; 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 */ /* Allocate a channel */
session->scpSend_state = libssh2_NB_state_created; session->scpSend_state = libssh2_NB_state_created;
} }
if (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, session->scpSend_channel =
LIBSSH2_CHANNEL_WINDOW_DEFAULT, LIBSSH2_CHANNEL_PACKET_DEFAULT, NULL, 0); libssh2_channel_open_ex(session, "session", sizeof("session") - 1,
LIBSSH2_CHANNEL_WINDOW_DEFAULT,
LIBSSH2_CHANNEL_PACKET_DEFAULT, NULL, 0);
if (!session->scpSend_channel) { if (!session->scpSend_channel) {
if (libssh2_session_last_errno(session) != LIBSSH2_ERROR_EAGAIN) { if (libssh2_session_last_errno(session) != LIBSSH2_ERROR_EAGAIN) {
/* previous call set libssh2_session_last_error(), pass it through */ /* previous call set libssh2_session_last_error(), pass it through */
LIBSSH2_FREE(session, session->scpSend_command); LIBSSH2_FREE(session, session->scpSend_command);
session->scpSend_command = NULL; session->scpSend_command = NULL;
session->scpSend_state = libssh2_NB_state_idle; session->scpSend_state = libssh2_NB_state_idle;
return NULL; return NULL;
} } else if (libssh2_session_last_errno(session) ==
else if (libssh2_session_last_errno(session) == LIBSSH2_ERROR_EAGAIN) { LIBSSH2_ERROR_EAGAIN) {
libssh2_error(session, LIBSSH2_ERROR_EAGAIN, "Would block starting up channel", 0); libssh2_error(session, LIBSSH2_ERROR_EAGAIN,
"Would block starting up channel", 0);
return NULL; return NULL;
} }
} }
session->scpSend_state = libssh2_NB_state_sent; session->scpSend_state = libssh2_NB_state_sent;
} }
if (session->scpSend_state == libssh2_NB_state_sent) { if (session->scpSend_state == libssh2_NB_state_sent) {
/* Request SCP for the desired file */ /* Request SCP for the desired file */
rc = libssh2_channel_process_startup(session->scpSend_channel, "exec", sizeof("exec") - 1, rc = libssh2_channel_process_startup(session->scpSend_channel, "exec",
(char *)session->scpSend_command, session->scpSend_command_len); sizeof("exec") - 1,
(char *) session->scpSend_command,
session->scpSend_command_len);
if (rc == PACKET_EAGAIN) { 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; return NULL;
} } else if (rc) {
else if (rc) {
/* previous call set libssh2_session_last_error(), pass it through */ /* previous call set libssh2_session_last_error(), pass it through */
LIBSSH2_FREE(session, session->scpSend_command); LIBSSH2_FREE(session, session->scpSend_command);
session->scpSend_command = NULL; session->scpSend_command = NULL;
libssh2_error(session, LIBSSH2_ERROR_SCP_PROTOCOL,
"Unknown error while getting error string", 0);
goto scp_send_error; goto scp_send_error;
} }
LIBSSH2_FREE(session, session->scpSend_command); LIBSSH2_FREE(session, session->scpSend_command);
session->scpSend_command = NULL; session->scpSend_command = NULL;
session->scpSend_state = libssh2_NB_state_sent1; session->scpSend_state = libssh2_NB_state_sent1;
} }
if (session->scpSend_state == libssh2_NB_state_sent1) { if (session->scpSend_state == libssh2_NB_state_sent1) {
/* Wait for ACK */ /* 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) { 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; return NULL;
} } else if ((rc <= 0) || (session->scpSend_response[0] != 0)) {
else if ((rc <= 0) || (session->scpSend_response[0] != 0)) { libssh2_error(session, LIBSSH2_ERROR_SCP_PROTOCOL,
libssh2_error(session, LIBSSH2_ERROR_SCP_PROTOCOL, "Invalid ACK response from remote", 0); "Invalid ACK response from remote", 0);
goto scp_send_error; goto scp_send_error;
} }
if (mtime || atime) { if (mtime || atime) {
/* Send mtime and atime to be used for file */ /* Send mtime and atime to be used for file */
session->scpSend_response_len = snprintf((char *)session->scpSend_response, LIBSSH2_SCP_RESPONSE_BUFLEN, session->scpSend_response_len =
"T%ld 0 %ld 0\n", mtime, atime); snprintf((char *) session->scpSend_response,
_libssh2_debug(session, LIBSSH2_DBG_SCP, "Sent %s", 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; session->scpSend_state = libssh2_NB_state_sent2;
} }
/* Send mtime and atime to be used for file */ /* Send mtime and atime to be used for file */
if (mtime || atime) { if (mtime || atime) {
if (session->scpSend_state == libssh2_NB_state_sent2) { 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); session->scpSend_response_len);
if (rc == PACKET_EAGAIN) { 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; return NULL;
} } else if (rc != session->scpSend_response_len) {
else if (rc != session->scpSend_response_len) { libssh2_error(session, LIBSSH2_ERROR_SOCKET_SEND,
libssh2_error(session, LIBSSH2_ERROR_SOCKET_SEND, "Unable to send time data for SCP file", 0); "Unable to send time data for SCP file", 0);
goto scp_send_error; goto scp_send_error;
} }
session->scpSend_state = libssh2_NB_state_sent3; session->scpSend_state = libssh2_NB_state_sent3;
} }
if (session->scpSend_state == libssh2_NB_state_sent3) { if (session->scpSend_state == libssh2_NB_state_sent3) {
/* Wait for ACK */ /* 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) { 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; return NULL;
} } else if ((rc <= 0) || (session->scpSend_response[0] != 0)) {
else if ((rc <= 0) || (session->scpSend_response[0] != 0)) { libssh2_error(session, LIBSSH2_ERROR_SCP_PROTOCOL,
libssh2_error(session, LIBSSH2_ERROR_SCP_PROTOCOL, "Invalid ACK response from remote", 0); "Invalid ACK response from remote", 0);
goto scp_send_error; goto scp_send_error;
} }
session->scpSend_state = libssh2_NB_state_sent4; session->scpSend_state = libssh2_NB_state_sent4;
} }
} else { } else {
@@ -548,55 +713,99 @@ libssh2_scp_send_ex(LIBSSH2_SESSION *session, const char *path, int mode, size_t
if (session->scpSend_state == libssh2_NB_state_sent4) { if (session->scpSend_state == libssh2_NB_state_sent4) {
/* Send mode, size, and basename */ /* Send mode, size, and basename */
base = (unsigned char *)strrchr(path, '/'); base = (unsigned char *) strrchr(path, '/');
if (base) { if (base) {
base++; base++;
} else { } else {
base = (unsigned char *)path; base = (unsigned char *) path;
} }
session->scpSend_response_len = snprintf((char *)session->scpSend_response, LIBSSH2_SCP_RESPONSE_BUFLEN, session->scpSend_response_len =
"C0%o %lu %s\n", mode, (unsigned long)size, base); snprintf((char *) session->scpSend_response,
_libssh2_debug(session, LIBSSH2_DBG_SCP, "Sent %s", 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; session->scpSend_state = libssh2_NB_state_sent5;
} }
if (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); session->scpSend_response_len);
if (rc == PACKET_EAGAIN) { 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; return NULL;
} } else if (rc != session->scpSend_response_len) {
else if (rc != session->scpSend_response_len) { libssh2_error(session, LIBSSH2_ERROR_SOCKET_SEND,
libssh2_error(session, LIBSSH2_ERROR_SOCKET_SEND, "Unable to send core file data for SCP file", 0); "Unable to send core file data for SCP file", 0);
goto scp_send_error; goto scp_send_error;
} }
session->scpSend_state = libssh2_NB_state_sent6; session->scpSend_state = libssh2_NB_state_sent6;
} }
/* Wait for ACK */ if (session->scpSend_state == libssh2_NB_state_sent6) {
rc = libssh2_channel_read_ex(session->scpSend_channel, 0, (char *)session->scpSend_response, 1); /* Wait for ACK */
if (rc == PACKET_EAGAIN) { rc = libssh2_channel_read_ex(session->scpSend_channel, 0,
libssh2_error(session, LIBSSH2_ERROR_EAGAIN, "Would block waiting for response", 0); (char *) session->scpSend_response, 1);
return NULL; if (rc == PACKET_EAGAIN) {
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);
goto scp_send_error;
} 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);
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);
if (rc <= 0) {
/*
* Since we have alread started reading this packet, it is
* already in the systems so it can't return PACKET_EAGAIN
*/
LIBSSH2_FREE(session, session->scpSend_err_msg);
session->scpSend_err_msg = NULL;
goto scp_send_error;
}
libssh2_error(session, LIBSSH2_ERROR_SCP_PROTOCOL,
session->scpSend_err_msg, 1);
session->scpSend_err_msg = NULL;
goto scp_send_error;
}
} }
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;
}
session->scpSend_state = libssh2_NB_state_idle; session->scpSend_state = libssh2_NB_state_idle;
return session->scpSend_channel; return session->scpSend_channel;
scp_send_error: scp_send_error:
while (libssh2_channel_free(session->scpSend_channel) == PACKET_EAGAIN); while (libssh2_channel_free(session->scpSend_channel) == PACKET_EAGAIN);
session->scpSend_channel = NULL; session->scpSend_channel = NULL;
session->scpSend_state = libssh2_NB_state_idle; session->scpSend_state = libssh2_NB_state_idle;
return NULL; return NULL;
} }
/* }}} */
/* }}} */

File diff suppressed because it is too large Load Diff

1579
src/sftp.c

File diff suppressed because it is too large Load Diff

View File

@@ -43,47 +43,47 @@
#include <assert.h> #include <assert.h>
#define MAX_BLOCKSIZE 32 /* MUST fit biggest crypto block size we use/get */ #define MAX_BLOCKSIZE 32 /* MUST fit biggest crypto block size we use/get */
#define MAX_MACSIZE 20 /* MUST fit biggest MAC length we support */ #define MAX_MACSIZE 20 /* MUST fit biggest MAC length we support */
#ifdef LIBSSH2DEBUG #ifdef LIBSSH2DEBUG
#define UNPRINTABLE_CHAR '.' #define UNPRINTABLE_CHAR '.'
static void debugdump(LIBSSH2_SESSION *session, static void
const char *desc, unsigned char *ptr, debugdump(LIBSSH2_SESSION * session,
unsigned long size) const char *desc, unsigned char *ptr, unsigned long size)
{ {
size_t i; size_t i;
size_t c; size_t c;
FILE *stream = stdout; FILE *stream = stdout;
unsigned int width=0x10; unsigned int width = 0x10;
if (!(session->showmask & (1<< LIBSSH2_DBG_TRANS))) { if (!(session->showmask & (1 << LIBSSH2_DBG_TRANS))) {
/* not asked for, bail out */ /* not asked for, bail out */
return; return;
}
fprintf(stream, "=> %s (%d bytes)\n", desc, (int)size);
for(i=0; i<size; i+= width) {
fprintf(stream, "%04lx: ", i);
/* hex not disabled, show it */
for(c = 0; c < width; c++) {
if (i+c < size)
fprintf(stream, "%02x ", ptr[i+c]);
else
fputs(" ", stream);
} }
for(c = 0; (c < width) && (i+c < size); c++) { fprintf(stream, "=> %s (%d bytes)\n", desc, (int) size);
fprintf(stream, "%c",
(ptr[i+c]>=0x20) && for(i = 0; i < size; i += width) {
(ptr[i+c]<0x80)?ptr[i+c]:UNPRINTABLE_CHAR);
fprintf(stream, "%04lx: ", (long)i);
/* hex not disabled, show it */
for(c = 0; c < width; c++) {
if (i + c < size)
fprintf(stream, "%02x ", ptr[i + c]);
else
fputs(" ", stream);
}
for(c = 0; (c < width) && (i + c < size); c++) {
fprintf(stream, "%c",
(ptr[i + c] >= 0x20) &&
(ptr[i + c] < 0x80) ? ptr[i + c] : UNPRINTABLE_CHAR);
}
fputc('\n', stream); /* newline */
} }
fputc('\n', stream); /* newline */ fflush(stream);
}
fflush(stream);
} }
#else #else
#define debugdump(a,x,y,z) #define debugdump(a,x,y,z)
@@ -95,35 +95,36 @@ static void debugdump(LIBSSH2_SESSION *session,
* returns PACKET_NONE on success and PACKET_FAIL on failure * returns PACKET_NONE on success and PACKET_FAIL on failure
*/ */
static libssh2pack_t decrypt(LIBSSH2_SESSION *session, unsigned char *source, static libssh2pack_t
unsigned char *dest, int len) decrypt(LIBSSH2_SESSION * session, unsigned char *source,
unsigned char *dest, int len)
{ {
struct transportpacket *p = &session->packet; struct transportpacket *p = &session->packet;
int blocksize = session->remote.crypt->blocksize; int blocksize = session->remote.crypt->blocksize;
/* if we get called with a len that isn't an even number of blocksizes /* if we get called with a len that isn't an even number of blocksizes
we risk losing those extra bytes */ we risk losing those extra bytes */
assert((len % blocksize) == 0); assert((len % blocksize) == 0);
while(len >= blocksize) { while (len >= blocksize) {
if (session->remote.crypt->crypt(session, source, if (session->remote.crypt->crypt(session, source,
&session->remote.crypt_abstract)) { &session->remote.crypt_abstract)) {
libssh2_error(session, LIBSSH2_ERROR_DECRYPT, libssh2_error(session, LIBSSH2_ERROR_DECRYPT,
(char *)"Error decrypting packet", 0); (char *) "Error decrypting packet", 0);
LIBSSH2_FREE(session, p->payload); LIBSSH2_FREE(session, p->payload);
return PACKET_FAIL; return PACKET_FAIL;
} }
/* if the crypt() function would write to a given address it /* if the crypt() function would write to a given address it
wouldn't have to memcpy() and we could avoid this memcpy() wouldn't have to memcpy() and we could avoid this memcpy()
too */ too */
memcpy(dest, source, blocksize); memcpy(dest, source, blocksize);
len -= blocksize; /* less bytes left */ len -= blocksize; /* less bytes left */
dest += blocksize; /* advance write pointer */ dest += blocksize; /* advance write pointer */
source += blocksize; /* advance read pointer */ source += blocksize; /* advance read pointer */
} }
return PACKET_NONE; /* all is fine */ return PACKET_NONE; /* all is fine */
} }
/* /*
@@ -131,26 +132,26 @@ static libssh2pack_t decrypt(LIBSSH2_SESSION *session, unsigned char *source,
* collected. * collected.
*/ */
static libssh2pack_t static libssh2pack_t
fullpacket(LIBSSH2_SESSION *session, int encrypted /* 1 or 0 */) fullpacket(LIBSSH2_SESSION * session, int encrypted /* 1 or 0 */ )
{ {
unsigned char macbuf[MAX_MACSIZE]; unsigned char macbuf[MAX_MACSIZE];
struct transportpacket *p = &session->packet; struct transportpacket *p = &session->packet;
int rc; int rc;
if (session->fullpacket_state == libssh2_NB_state_idle) { if (session->fullpacket_state == libssh2_NB_state_idle) {
session->fullpacket_macstate = LIBSSH2_MAC_CONFIRMED; session->fullpacket_macstate = LIBSSH2_MAC_CONFIRMED;
session->fullpacket_payload_len = p->packet_length-1; session->fullpacket_payload_len = p->packet_length - 1;
if (encrypted) { if (encrypted) {
/* Calculate MAC hash */ /* Calculate MAC hash */
session->remote.mac->hash(session, session->remote.mac->hash(session, macbuf, /* store hash here */
macbuf, /* store hash here */
session->remote.seqno, session->remote.seqno,
p->init, 5, p->init, 5,
p->payload, session->fullpacket_payload_len, p->payload,
session->fullpacket_payload_len,
&session->remote.mac_abstract); &session->remote.mac_abstract);
/* Compare the calculated hash with the MAC we just read from /* Compare the calculated hash with the MAC we just read from
* the network. The read one is at the very end of the payload * the network. The read one is at the very end of the payload
* buffer. Note that 'payload_len' here is the packet_length * buffer. Note that 'payload_len' here is the packet_length
@@ -161,55 +162,53 @@ fullpacket(LIBSSH2_SESSION *session, int encrypted /* 1 or 0 */)
session->fullpacket_macstate = LIBSSH2_MAC_INVALID; session->fullpacket_macstate = LIBSSH2_MAC_INVALID;
} }
} }
session->remote.seqno++; session->remote.seqno++;
/* ignore the padding */ /* ignore the padding */
session->fullpacket_payload_len -= p->padding_length; session->fullpacket_payload_len -= p->padding_length;
/* Check for and deal with decompression */ /* Check for and deal with decompression */
if (session->remote.comp && if (session->remote.comp && strcmp(session->remote.comp->name, "none")) {
strcmp(session->remote.comp->name, "none")) {
unsigned char *data; unsigned char *data;
unsigned long data_len; unsigned long data_len;
int free_payload = 1; int free_payload = 1;
if (session->remote.comp->comp(session, 0, if (session->remote.comp->comp(session, 0,
&data, &data_len, &data, &data_len,
LIBSSH2_PACKET_MAXDECOMP, LIBSSH2_PACKET_MAXDECOMP,
&free_payload, &free_payload,
p->payload, session->fullpacket_payload_len, p->payload,
session->fullpacket_payload_len,
&session->remote.comp_abstract)) { &session->remote.comp_abstract)) {
LIBSSH2_FREE(session, p->payload); LIBSSH2_FREE(session, p->payload);
return PACKET_FAIL; return PACKET_FAIL;
} }
if (free_payload) { if (free_payload) {
LIBSSH2_FREE(session, p->payload); LIBSSH2_FREE(session, p->payload);
p->payload = data; p->payload = data;
session->fullpacket_payload_len = data_len; session->fullpacket_payload_len = data_len;
} } else {
else {
if (data == p->payload) { if (data == p->payload) {
/* It's not to be freed, because the /* It's not to be freed, because the
* compression layer reused payload, So let's * compression layer reused payload, So let's
* do the same! * do the same!
*/ */
session->fullpacket_payload_len = data_len; session->fullpacket_payload_len = data_len;
} } else {
else {
/* No comp_method actually lets this happen, /* No comp_method actually lets this happen,
* but let's prepare for the future */ * but let's prepare for the future */
LIBSSH2_FREE(session, p->payload); LIBSSH2_FREE(session, p->payload);
/* We need a freeable struct otherwise the /* We need a freeable struct otherwise the
* brigade won't know what to do with it */ * brigade won't know what to do with it */
p->payload = LIBSSH2_ALLOC(session, data_len); p->payload = LIBSSH2_ALLOC(session, data_len);
if (!p->payload) { if (!p->payload) {
libssh2_error(session, libssh2_error(session, LIBSSH2_ERROR_ALLOC, (char *)
LIBSSH2_ERROR_ALLOC, "Unable to allocate memory for copy of uncompressed data",
(char *)"Unable to allocate memory for copy of uncompressed data", 0); 0);
return PACKET_ENOMEM; return PACKET_ENOMEM;
} }
memcpy(p->payload, data, data_len); memcpy(p->payload, data, data_len);
@@ -217,27 +216,28 @@ fullpacket(LIBSSH2_SESSION *session, int encrypted /* 1 or 0 */)
} }
} }
} }
session->fullpacket_packet_type = p->payload[0]; session->fullpacket_packet_type = p->payload[0];
debugdump(session, "libssh2_packet_read() plain", debugdump(session, "libssh2_packet_read() plain",
p->payload, session->fullpacket_payload_len); p->payload, session->fullpacket_payload_len);
session->fullpacket_state = libssh2_NB_state_created; session->fullpacket_state = libssh2_NB_state_created;
} }
if (session->fullpacket_state == libssh2_NB_state_created) { 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) { if (rc == PACKET_EAGAIN) {
return PACKET_EAGAIN; return PACKET_EAGAIN;
} } else if (rc < 0) {
else if (rc < 0) {
return PACKET_FAIL; return PACKET_FAIL;
} }
} }
session->fullpacket_state = libssh2_NB_state_idle; session->fullpacket_state = libssh2_NB_state_idle;
return session->fullpacket_packet_type; return session->fullpacket_packet_type;
} }
@@ -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 * This function reads the binary stream as specified in chapter 6 of RFC4253
* "The Secure Shell (SSH) Transport Layer Protocol" * "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; libssh2pack_t rc;
struct transportpacket *p = &session->packet; struct transportpacket *p = &session->packet;
@@ -266,9 +267,8 @@ libssh2pack_t libssh2_packet_read(LIBSSH2_SESSION *session)
int numdecrypt; int numdecrypt;
unsigned char block[MAX_BLOCKSIZE]; unsigned char block[MAX_BLOCKSIZE];
int blocksize; int blocksize;
int minimum;
int encrypted = 1; int encrypted = 1;
/* /*
* =============================== NOTE =============================== * =============================== NOTE ===============================
* I know this is very ugly and not a really good use of "goto", but * I know this is very ugly and not a really good use of "goto", but
@@ -279,39 +279,38 @@ libssh2pack_t libssh2_packet_read(LIBSSH2_SESSION *session)
encrypted = session->readPack_encrypted; encrypted = session->readPack_encrypted;
goto libssh2_packet_read_point1; goto libssh2_packet_read_point1;
} }
do { do {
if (session->socket_state == LIBSSH2_SOCKET_DISCONNECTED) { if (session->socket_state == LIBSSH2_SOCKET_DISCONNECTED) {
return PACKET_NONE; return PACKET_NONE;
} }
if (session->state & LIBSSH2_STATE_NEWKEYS) { if (session->state & LIBSSH2_STATE_NEWKEYS) {
blocksize = session->remote.crypt->blocksize; blocksize = session->remote.crypt->blocksize;
} else { } else {
encrypted = 0; /* not encrypted */ encrypted = 0; /* not encrypted */
blocksize = 5; /* not strictly true, but we can use 5 here to blocksize = 5; /* not strictly true, but we can use 5 here to
make the checks below work fine still */ 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 /* read/use a whole big chunk into a temporary area stored in
the LIBSSH2_SESSION struct. We will decrypt data from that the LIBSSH2_SESSION struct. We will decrypt data from that
buffer into the packet buffer so this temp one doesn't have buffer into the packet buffer so this temp one doesn't have
to be able to keep a whole SSH packet, just be large enough to be able to keep a whole SSH packet, just be large enough
so that we can read big chunks from the network layer. */ so that we can read big chunks from the network layer. */
/* how much data there is remaining in the buffer to deal with /* how much data there is remaining in the buffer to deal with
before we should read more from the network */ before we should read more from the network */
remainbuf = p->writeidx - p->readidx; remainbuf = p->writeidx - p->readidx;
/* if remainbuf turns negative we have a bad internal error */ /* if remainbuf turns negative we have a bad internal error */
assert(remainbuf >= 0); assert(remainbuf >= 0);
if (remainbuf < minimum) { if (remainbuf < blocksize) {
/* If we have less than a minimum left, it is too /* If we have less than a blocksize left, it is too
little data to deal with, read more */ little data to deal with, read more */
ssize_t nread; ssize_t nread;
/* move any remainder to the start of the buffer so /* move any remainder to the start of the buffer so
that we can do a full refill */ that we can do a full refill */
if (remainbuf) { if (remainbuf) {
@@ -322,14 +321,35 @@ libssh2pack_t libssh2_packet_read(LIBSSH2_SESSION *session)
/* nothing to move, just zero the indexes */ /* nothing to move, just zero the indexes */
p->readidx = p->writeidx = 0; p->readidx = p->writeidx = 0;
} }
/* now read a big chunk from the network into the temp buffer */ /* now read a big chunk from the network into the temp buffer */
nread = recv(session->socket_fd, &p->buf[remainbuf], PACKETBUFSIZE-remainbuf, nread =
LIBSSH2_SOCKET_RECV_FLAGS(session)); recv(session->socket_fd, &p->buf[remainbuf],
PACKETBUFSIZE - remainbuf,
LIBSSH2_SOCKET_RECV_FLAGS(session));
if (nread <= 0) { if (nread <= 0) {
/* check if this is due to EAGAIN and return /* check if this is due to EAGAIN and return the special
the special return code if so, error out return code if so, error out normally otherwise */
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)) { if ((nread < 0) && (errno == EAGAIN)) {
return PACKET_EAGAIN; return PACKET_EAGAIN;
} }
@@ -339,30 +359,33 @@ libssh2pack_t libssh2_packet_read(LIBSSH2_SESSION *session)
&p->buf[remainbuf], nread); &p->buf[remainbuf], nread);
/* advance write pointer */ /* advance write pointer */
p->writeidx += nread; p->writeidx += nread;
/* update remainbuf counter */ /* update remainbuf counter */
remainbuf = p->writeidx - p->readidx; remainbuf = p->writeidx - p->readidx;
} }
/* how much data to deal with from the buffer */ /* how much data to deal with from the buffer */
numbytes = remainbuf; numbytes = remainbuf;
if (numbytes < blocksize) {
/* we can't act on anything less than blocksize */
return PACKET_EAGAIN;
}
if (!p->total_num) { if (!p->total_num) {
/* No payload package area allocated yet. To know the /* No payload package area allocated yet. To know the
size of this payload, we need to decrypt the first size of this payload, we need to decrypt the first
blocksize data. */ 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) { if (encrypted) {
rc = decrypt(session, &p->buf[p->readidx], block, blocksize); rc = decrypt(session, &p->buf[p->readidx], block, blocksize);
if (rc != PACKET_NONE) { if (rc != PACKET_NONE) {
return rc; return rc;
} }
/* save the first 5 bytes of the decrypted package, to be /* save the first 5 bytes of the decrypted package, to be
used in the hash calculation later down. */ used in the hash calculation later down. */
memcpy(p->init, &p->buf[p->readidx], 5); memcpy(p->init, &p->buf[p->readidx], 5);
} else { } else {
@@ -370,20 +393,22 @@ libssh2pack_t libssh2_packet_read(LIBSSH2_SESSION *session)
the working block buffer */ the working block buffer */
memcpy(block, &p->buf[p->readidx], blocksize); memcpy(block, &p->buf[p->readidx], blocksize);
} }
/* advance the read pointer */ /* advance the read pointer */
p->readidx += blocksize; p->readidx += blocksize;
/* we now have the initial blocksize bytes decrypted, /* we now have the initial blocksize bytes decrypted,
* and we can extract packet and padding length from it * and we can extract packet and padding length from it
*/ */
p->packet_length = libssh2_ntohu32(block); p->packet_length = libssh2_ntohu32(block);
p->padding_length = block[4]; p->padding_length = block[4];
/* total_num is the number of bytes following the initial /* total_num is the number of bytes following the initial
(5 bytes) packet length and padding length fields */ (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: /* RFC4253 section 6.1 Maximum Packet Length says:
* *
* "All implementations MUST be able to process * "All implementations MUST be able to process
@@ -395,7 +420,7 @@ libssh2pack_t libssh2_packet_read(LIBSSH2_SESSION *session)
if (p->total_num > LIBSSH2_PACKET_MAXPAYLOAD) { if (p->total_num > LIBSSH2_PACKET_MAXPAYLOAD) {
return PACKET_TOOBIG; return PACKET_TOOBIG;
} }
/* Get a packet handle put data into. We get one to /* Get a packet handle put data into. We get one to
hold all data, including padding and MAC. */ hold all data, including padding and MAC. */
p->payload = LIBSSH2_ALLOC(session, p->total_num); p->payload = LIBSSH2_ALLOC(session, p->total_num);
@@ -404,40 +429,40 @@ libssh2pack_t libssh2_packet_read(LIBSSH2_SESSION *session)
} }
/* init write pointer to start of payload buffer */ /* init write pointer to start of payload buffer */
p->wptr = p->payload; p->wptr = p->payload;
if (blocksize > 5) { if (blocksize > 5) {
/* copy the data from index 5 to the end of /* copy the data from index 5 to the end of
the blocksize from the temporary buffer to the blocksize from the temporary buffer to
the start of the decrypted buffer */ the start of the decrypted buffer */
memcpy(p->wptr, &block[5], blocksize-5); memcpy(p->wptr, &block[5], blocksize - 5);
p->wptr += blocksize-5; /* advance write pointer */ p->wptr += blocksize - 5; /* advance write pointer */
} }
/* init the data_num field to the number of bytes of /* init the data_num field to the number of bytes of
the package read so far */ the package read so far */
p->data_num = p->wptr - p->payload; p->data_num = p->wptr - p->payload;
/* we already dealt with a blocksize worth of data */ /* we already dealt with a blocksize worth of data */
numbytes -= blocksize; numbytes -= blocksize;
} }
/* how much there is left to add to the current payload /* how much there is left to add to the current payload
package */ package */
remainpack = p->total_num - p->data_num; remainpack = p->total_num - p->data_num;
if (numbytes > remainpack) { if (numbytes > remainpack) {
/* if we have more data in the buffer than what is going into this /* if we have more data in the buffer than what is going into this
particular packet, we limit this round to this packet only */ particular packet, we limit this round to this packet only */
numbytes = remainpack; numbytes = remainpack;
} }
if (encrypted) { if (encrypted) {
/* At the end of the incoming stream, there is a MAC, /* At the end of the incoming stream, there is a MAC,
and we don't want to decrypt that since we need it and we don't want to decrypt that since we need it
"raw". We MUST however decrypt the padding data "raw". We MUST however decrypt the padding data
since it is used for the hash later on. */ since it is used for the hash later on. */
int skip = session->remote.mac->mac_len; int skip = session->remote.mac->mac_len;
/* if what we have plus numbytes is bigger than the /* if what we have plus numbytes is bigger than the
total minus the skip margin, we should lower the total minus the skip margin, we should lower the
amount to decrypt even more */ amount to decrypt even more */
@@ -449,10 +474,10 @@ libssh2pack_t libssh2_packet_read(LIBSSH2_SESSION *session)
frac = numdecrypt % blocksize; frac = numdecrypt % blocksize;
if (frac) { if (frac) {
/* not an aligned amount of blocks, /* not an aligned amount of blocks,
align it */ align it */
numdecrypt -= frac; numdecrypt -= frac;
/* and make it no unencrypted data /* and make it no unencrypted data
after it */ after it */
numbytes = 0; numbytes = 0;
} }
} }
@@ -460,7 +485,7 @@ libssh2pack_t libssh2_packet_read(LIBSSH2_SESSION *session)
/* unencrypted data should not be decrypted at all */ /* unencrypted data should not be decrypted at all */
numdecrypt = 0; numdecrypt = 0;
} }
/* if there are bytes to decrypt, do that */ /* if there are bytes to decrypt, do that */
if (numdecrypt > 0) { if (numdecrypt > 0) {
/* now decrypt the lot */ /* now decrypt the lot */
@@ -468,23 +493,23 @@ libssh2pack_t libssh2_packet_read(LIBSSH2_SESSION *session)
if (rc != PACKET_NONE) { if (rc != PACKET_NONE) {
return rc; return rc;
} }
/* advance the read pointer */ /* advance the read pointer */
p->readidx += numdecrypt; p->readidx += numdecrypt;
/* advance write pointer */ /* advance write pointer */
p->wptr += numdecrypt; p->wptr += numdecrypt;
/* increse data_num */ /* increse data_num */
p->data_num += numdecrypt; p->data_num += numdecrypt;
/* bytes left to take care of without decryption */ /* bytes left to take care of without decryption */
numbytes -= numdecrypt; numbytes -= numdecrypt;
} }
/* if there are bytes to copy that aren't decrypted, simply /* if there are bytes to copy that aren't decrypted, simply
copy them as-is to the target buffer */ copy them as-is to the target buffer */
if (numbytes > 0) { if (numbytes > 0) {
memcpy(p->wptr, &p->buf[p->readidx], numbytes); memcpy(p->wptr, &p->buf[p->readidx], numbytes);
/* advance the read pointer */ /* advance the read pointer */
p->readidx += numbytes; p->readidx += numbytes;
/* advance write pointer */ /* advance write pointer */
@@ -492,68 +517,71 @@ libssh2pack_t libssh2_packet_read(LIBSSH2_SESSION *session)
/* increse data_num */ /* increse data_num */
p->data_num += numbytes; p->data_num += numbytes;
} }
/* now check how much data there's left to read to finish the /* now check how much data there's left to read to finish the
current packet */ current packet */
remainpack = p->total_num - p->data_num; remainpack = p->total_num - p->data_num;
if (!remainpack) { if (!remainpack) {
/* we have a full packet */ /* we have a full packet */
libssh2_packet_read_point1: libssh2_packet_read_point1:
rc = fullpacket(session, encrypted); rc = fullpacket(session, encrypted);
if (rc == PACKET_EAGAIN) { if (rc == PACKET_EAGAIN) {
session->readPack_encrypted = encrypted; session->readPack_encrypted = encrypted;
session->readPack_state = libssh2_NB_state_jump1; session->readPack_state = libssh2_NB_state_jump1;
return PACKET_EAGAIN; return PACKET_EAGAIN;
} }
p->total_num = 0; /* no packet buffer available */ p->total_num = 0; /* no packet buffer available */
return rc; return rc;
} }
} while (1); /* loop */ } while (1); /* loop */
return PACKET_FAIL; /* we never reach this point */ return PACKET_FAIL; /* we never reach this point */
} }
/* }}} */ /* }}} */
#ifndef OLDSEND #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 rc;
ssize_t length; ssize_t length;
struct transportpacket *p = &session->packet; struct transportpacket *p = &session->packet;
if (!p->outbuf) { if (!p->outbuf) {
*ret = 0; *ret = 0;
return PACKET_NONE; return PACKET_NONE;
} }
/* send as much as possible of the existing packet */ /* send as much as possible of the existing packet */
if ((data != p->odata) || (data_len != p->olen)) { if ((data != p->odata) || (data_len != p->olen)) {
/* When we are about to complete the sending of a packet, it is vital /* When we are about to complete the sending of a packet, it is vital
that the caller doesn't try to send a new/different packet since that the caller doesn't try to send a new/different packet since
we don't add this one up until the previous one has been sent. To we don't add this one up until the previous one has been sent. To
make the caller really notice his/hers flaw, we return error for make the caller really notice his/hers flaw, we return error for
this case */ this case */
return PACKET_BADUSE; return PACKET_BADUSE;
} }
*ret = 1; /* set to make our parent return */ *ret = 1; /* set to make our parent return */
/* number of bytes left to send */ /* number of bytes left to send */
length = p->ototal_num - p->osent; 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) { if (rc == length) {
/* the remainder of the package was sent */ /* the remainder of the package was sent */
LIBSSH2_FREE(session, p->outbuf); LIBSSH2_FREE(session, p->outbuf);
p->outbuf = NULL; p->outbuf = NULL;
p->ototal_num = 0; p->ototal_num = 0;
} } else if (rc < 0) {
else if (rc < 0) {
/* nothing was sent */ /* nothing was sent */
if (errno != EAGAIN) { if (errno != EAGAIN) {
/* send failure! */ /* send failure! */
@@ -561,10 +589,11 @@ static libssh2pack_t send_existing(LIBSSH2_SESSION *session, unsigned char *data
} }
return PACKET_EAGAIN; return PACKET_EAGAIN;
} }
debugdump(session, "libssh2_packet_write send()", &p->outbuf[p->osent], length); debugdump(session, "libssh2_packet_write send()", &p->outbuf[p->osent],
p->osent += length; /* we sent away this much data */ length);
p->osent += length; /* we sent away this much data */
return PACKET_NONE; return PACKET_NONE;
} }
@@ -577,16 +606,20 @@ static libssh2pack_t send_existing(LIBSSH2_SESSION *session, unsigned char *data
* sent, and this function should then be called with the same argument set * 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. * (same data pointer and same data_len) until zero or failure is returned.
*/ */
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 padding_length;
int packet_length; int packet_length;
int total_length; int total_length;
int free_data=0; int free_data = 0;
#ifdef RANDOM_PADDING #ifdef RANDOM_PADDING
int rand_max; int rand_max;
int seed = data[0]; /* FIXME: make this random */ int seed = data[0]; /* FIXME: make this random */
#endif #endif
struct transportpacket *p = &session->packet; struct transportpacket *p = &session->packet;
int encrypted; int encrypted;
@@ -595,41 +628,42 @@ int libssh2_packet_write(LIBSSH2_SESSION *session, unsigned char *data, unsigned
libssh2pack_t rc; libssh2pack_t rc;
unsigned char *orgdata = data; unsigned char *orgdata = data;
unsigned long orgdata_len = data_len; unsigned long orgdata_len = data_len;
debugdump(session, "libssh2_packet_write plain", data, data_len); debugdump(session, "libssh2_packet_write plain", data, data_len);
/* FIRST, check if we have a pending write to complete */ /* FIRST, check if we have a pending write to complete */
rc = send_existing(session, data, data_len, &ret); rc = send_existing(session, data, data_len, &ret);
if (rc || ret) { if (rc || ret) {
return rc; return rc;
} }
encrypted = (session->state & LIBSSH2_STATE_NEWKEYS)?1:0; encrypted = (session->state & LIBSSH2_STATE_NEWKEYS) ? 1 : 0;
/* check if we should compress */ /* check if we should compress */
if (encrypted && strcmp(session->local.comp->name, "none")) { if (encrypted && strcmp(session->local.comp->name, "none")) {
if (session->local.comp->comp(session, 1, &data, &data_len, LIBSSH2_PACKET_MAXCOMP, if (session->local.comp->
&free_data, data, data_len, &session->local.comp_abstract)) { comp(session, 1, &data, &data_len, LIBSSH2_PACKET_MAXCOMP,
return PACKET_COMPRESS; /* compression failure */ &free_data, data, data_len, &session->local.comp_abstract)) {
return PACKET_COMPRESS; /* compression failure */
} }
} }
/* RFC4253 says: Note that the length of the concatenation of /* RFC4253 says: Note that the length of the concatenation of
'packet_length', 'padding_length', 'payload', and 'random padding' 'packet_length', 'padding_length', 'payload', and 'random padding'
MUST be a multiple of the cipher block size or 8, whichever is MUST be a multiple of the cipher block size or 8, whichever is
larger. */ larger. */
/* Plain math: (4 + 1 + packet_length + padding_length) % blocksize == 0 */ /* Plain math: (4 + 1 + packet_length + padding_length) % blocksize == 0 */
packet_length = data_len + 1 + 4; /* 1 is for padding_length field packet_length = data_len + 1 + 4; /* 1 is for padding_length field
4 for the packet_length field */ 4 for the packet_length field */
/* at this point we have it all except the padding */ /* at this point we have it all except the padding */
/* first figure out our minimum padding amount to make it an even /* first figure out our minimum padding amount to make it an even
block size */ block size */
padding_length = blocksize - (packet_length % blocksize); padding_length = blocksize - (packet_length % blocksize);
/* if the padding becomes too small we add another blocksize worth /* if the padding becomes too small we add another blocksize worth
of it (taken from the original libssh2 where it didn't have any of it (taken from the original libssh2 where it didn't have any
real explanation) */ real explanation) */
@@ -639,19 +673,20 @@ int libssh2_packet_write(LIBSSH2_SESSION *session, unsigned char *data, unsigned
#ifdef RANDOM_PADDING #ifdef RANDOM_PADDING
/* FIXME: we can add padding here, but that also makes the packets /* FIXME: we can add padding here, but that also makes the packets
bigger etc */ bigger etc */
/* now we can add 'blocksize' to the padding_length N number of times /* now we can add 'blocksize' to the padding_length N number of times
(to "help thwart traffic analysis") but it must be less than 255 in (to "help thwart traffic analysis") but it must be less than 255 in
total */ total */
rand_max = (255 - padding_length)/blocksize + 1; rand_max = (255 - padding_length) / blocksize + 1;
padding_length += blocksize * (seed % rand_max); padding_length += blocksize * (seed % rand_max);
#endif #endif
packet_length += padding_length; packet_length += padding_length;
/* append the MAC length to the total_length size */ /* 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 /* 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 send the whole one and thus need to keep it after this function
returns. */ returns. */
@@ -659,7 +694,7 @@ int libssh2_packet_write(LIBSSH2_SESSION *session, unsigned char *data, unsigned
if (!p->outbuf) { if (!p->outbuf) {
return PACKET_ENOMEM; return PACKET_ENOMEM;
} }
/* store packet_length, which is the size of the whole packet except /* store packet_length, which is the size of the whole packet except
the MAC and the packet_length field itself */ the MAC and the packet_length field itself */
libssh2_htonu32(p->outbuf, packet_length - 4); libssh2_htonu32(p->outbuf, packet_length - 4);
@@ -672,51 +707,54 @@ int libssh2_packet_write(LIBSSH2_SESSION *session, unsigned char *data, unsigned
if (free_data) { if (free_data) {
LIBSSH2_FREE(session, data); LIBSSH2_FREE(session, data);
} }
if (encrypted) { if (encrypted) {
/* Calculate MAC hash. Put the output at index packet_length, /* Calculate MAC hash. Put the output at index packet_length,
since that size includes the whole packet. The MAC is since that size includes the whole packet. The MAC is
calculated on the entire unencrypted packet, including all calculated on the entire unencrypted packet, including all
fields except the MAC field itself. */ fields except the MAC field itself. */
session->local.mac->hash(session, p->outbuf + packet_length, session->local.seqno, p->outbuf, packet_length, session->local.mac->hash(session, p->outbuf + packet_length,
NULL, 0, &session->local.mac_abstract); session->local.seqno, p->outbuf,
packet_length, NULL, 0,
&session->local.mac_abstract);
/* Encrypt the whole packet data, one block size at a time. /* Encrypt the whole packet data, one block size at a time.
The MAC field is not encrypted. */ The MAC field is not encrypted. */
for(i=0; i < packet_length; i += session->local.crypt->blocksize) { for(i = 0; i < packet_length; i += session->local.crypt->blocksize) {
unsigned char *ptr = &p->outbuf[i]; unsigned char *ptr = &p->outbuf[i];
if (session->local.crypt->crypt(session, ptr, &session->local.crypt_abstract)) if (session->local.crypt->
return PACKET_FAIL; /* encryption failure */ crypt(session, ptr, &session->local.crypt_abstract))
return PACKET_FAIL; /* encryption failure */
} }
} }
session->local.seqno++; session->local.seqno++;
ret = send(session->socket_fd, p->outbuf, total_length, ret = send(session->socket_fd, p->outbuf, total_length,
LIBSSH2_SOCKET_SEND_FLAGS(session)); LIBSSH2_SOCKET_SEND_FLAGS(session));
if (ret != -1) { if (ret != -1) {
debugdump(session, "libssh2_packet_write send()", p->outbuf, ret); debugdump(session, "libssh2_packet_write send()", p->outbuf, ret);
} }
if (ret != total_length) { if (ret != total_length) {
if ((ret > 0 ) || ((ret == -1) && (errno == EAGAIN))) { if ((ret > 0) || ((ret == -1) && (errno == EAGAIN))) {
/* the whole packet could not be sent, save the rest */ /* the whole packet could not be sent, save the rest */
p->odata = orgdata; p->odata = orgdata;
p->olen = orgdata_len; p->olen = orgdata_len;
p->osent = (ret == -1)?0:ret; p->osent = (ret == -1) ? 0 : ret;
p->ototal_num = total_length; p->ototal_num = total_length;
return PACKET_EAGAIN; return PACKET_EAGAIN;
} }
return PACKET_FAIL; return PACKET_FAIL;
} }
/* the whole thing got sent away */ /* the whole thing got sent away */
p->odata = NULL; p->odata = NULL;
p->olen = 0; p->olen = 0;
LIBSSH2_FREE(session, p->outbuf); LIBSSH2_FREE(session, p->outbuf);
p->outbuf = NULL; p->outbuf = NULL;
return PACKET_NONE; /* all is good */ return PACKET_NONE; /* all is good */
} }
/* }}} */ /* }}} */

File diff suppressed because it is too large Load Diff

View File

@@ -5,7 +5,7 @@
## ##
## Comments to: Guenter Knauf <eflash@gmx.net> ## Comments to: Guenter Knauf <eflash@gmx.net>
## ##
## $Id: Makefile.win32,v 1.7 2007/04/21 23:36:51 gknauf Exp $ ## $Id: Makefile.win32,v 1.9 2007/08/18 18:53:26 gknauf Exp $
# #
######################################################################### #########################################################################
@@ -13,6 +13,8 @@
ifndef ZLIB_PATH ifndef ZLIB_PATH
ZLIB_PATH = ../../zlib-1.2.3 ZLIB_PATH = ../../zlib-1.2.3
endif endif
# since currently always enabled in libssh2_config.h set here too!
WITH_ZLIB = 1
# Edit the path below to point to the base of your OpenSSL package. # Edit the path below to point to the base of your OpenSSL package.
ifndef OPENSSL_PATH ifndef OPENSSL_PATH
@@ -61,10 +63,12 @@ endif
ifdef METROWERKS ifdef METROWERKS
CC = mwcc CC = mwcc
else else
CC = gcc CC = $(CRPREFIX)gcc
endif endif
CP = cp -afv CP = cp -afv
# RM = rm -f # 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 AWK = awk
ZIP = zip -qzr9 ZIP = zip -qzr9
@@ -87,13 +91,13 @@ CFLAGS += -nostdinc -gccinc -msgstyle gcc -inline off -opt nointrinsics -proc 58
CFLAGS += -ir "$(METROWERKS)/MSL" -ir "$(METROWERKS)/Win32-x86 Support" CFLAGS += -ir "$(METROWERKS)/MSL" -ir "$(METROWERKS)/Win32-x86 Support"
CFLAGS += -w on,nounused,nounusedexpr # -ansi strict CFLAGS += -w on,nounused,nounusedexpr # -ansi strict
else else
LD = gcc LD = $(CRPREFIX)gcc
RC = windres RC = $(CRPREFIX)windres
LDFLAGS = -s -shared -Wl,--out-implib,$(TARGET)dll.a LDFLAGS = -s -shared -Wl,--out-implib,$(TARGET)dll.a
AR = ar AR = $(CRPREFIX)ar
ARFLAGS = -cq ARFLAGS = -cq
LIBEXT = a LIBEXT = a
RANLIB = ranlib RANLIB = $(CRPREFIX)ranlib
#LDLIBS += -lwsock32 #LDLIBS += -lwsock32
LDLIBS += -lws2_32 LDLIBS += -lws2_32
RCFLAGS = -O coff -i RCFLAGS = -O coff -i

View File

@@ -1,10 +1,10 @@
# Tweak these for your system # Tweak these for your system
OPENSSLINC=..\libssh2_build\include OPENSSLINC=..\openssl-0.9.8e\inc32
OPENSSLLIB=..\libssh2_build\lib OPENSSLLIB=..\openssl-0.9.8e\out32dll
ZLIBINC=-DLIBSSH2_HAVE_ZLIB=1 /I..\libssh2_build\include ZLIBINC=-DLIBSSH2_HAVE_ZLIB=1 /I..\zlib-1.2.3
ZLIBLIB=..\libssh2_build\lib ZLIBLIB=..\zlib-1.2.3
!if "$(TARGET)" == "" !if "$(TARGET)" == ""
TARGET=Release TARGET=Release

View File

@@ -3,7 +3,7 @@ Microsoft Developer Studio Workspace File, Format Version 6.00
############################################################################### ###############################################################################
Project: "libssh2"=.\libssh2.dsp - Package Owner=<4> Project: "libssh2_dll"=".\libssh2_dll.dsp" - Package Owner=<4>
Package=<5> Package=<5>
{{{ {{{
@@ -15,7 +15,19 @@ Package=<4>
############################################################################### ###############################################################################
Project: "ssh2_sample"=.\ssh2_sample.dsp - Package Owner=<4> Project: "libssh2_lib"=".\libssh2_lib.dsp" - Package Owner=<4>
Package=<5>
{{{
}}}
Package=<4>
{{{
}}}
###############################################################################
Project: "tests"=".\tests.dsp" - Package Owner=<4>
Package=<5> Package=<5>
{{{ {{{

View File

@@ -9,7 +9,6 @@
#include <ws2tcpip.h> #include <ws2tcpip.h>
#ifdef __MINGW32__ #ifdef __MINGW32__
#define WINSOCK_VERSION MAKEWORD(2,0)
#define HAVE_UNISTD_H #define HAVE_UNISTD_H
#define HAVE_INTTYPES_H #define HAVE_INTTYPES_H
#define HAVE_SYS_TIME_H #define HAVE_SYS_TIME_H
@@ -42,8 +41,19 @@ static inline int usleep(int udelay)
return 0; return 0;
} }
#ifdef _MSC_VER
#define snprintf _snprintf #define snprintf _snprintf
#define vsnprintf _vsnprintf #define vsnprintf _vsnprintf
#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 */ /* Compile in zlib support */
#define LIBSSH2_HAVE_ZLIB 1 #define LIBSSH2_HAVE_ZLIB 1

184
win32/libssh2_dll.dsp Normal file
View File

@@ -0,0 +1,184 @@
# Microsoft Developer Studio Project File - Name="libssh2_dll" - Package Owner=<4>
# Microsoft Developer Studio Generated Build File, Format Version 6.00
# ** DO NOT EDIT **
# TARGTYPE "Win32 (x86) Dynamic-Link Library" 0x0102
CFG=libssh2_dll - Win32 Debug
!MESSAGE This is not a valid makefile. To build this project using NMAKE,
!MESSAGE use the Export Makefile command and run
!MESSAGE
!MESSAGE NMAKE /f "libssh2_dll.mak".
!MESSAGE
!MESSAGE You can specify a configuration when running NMAKE
!MESSAGE by defining the macro CFG on the command line. For example:
!MESSAGE
!MESSAGE NMAKE /f "libssh2_dll.mak" CFG="libssh2_dll - Win32 Debug"
!MESSAGE
!MESSAGE Possible choices for configuration are:
!MESSAGE
!MESSAGE "libssh2_dll - Win32 Release" (based on "Win32 (x86) Dynamic-Link Library")
!MESSAGE "libssh2_dll - Win32 Debug" (based on "Win32 (x86) Dynamic-Link Library")
!MESSAGE
# Begin Project
# PROP AllowPerConfigDependencies 0
# PROP Scc_ProjName ""
# PROP Scc_LocalPath ""
CPP=cl.exe
MTL=midl.exe
RSC=rc.exe
!IF "$(CFG)" == "libssh2_dll - Win32 Release"
# PROP BASE Use_MFC 0
# PROP BASE Use_Debug_Libraries 0
# PROP BASE Output_Dir "Release_dll"
# PROP BASE Intermediate_Dir "Release_dll"
# PROP BASE Target_Dir ""
# PROP Use_MFC 0
# PROP Use_Debug_Libraries 0
# PROP Output_Dir "Release_dll"
# PROP Intermediate_Dir "Release_dll"
# PROP Ignore_Export_Lib 0
# PROP Target_Dir ""
# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "LIBSSH2_WIN32" /D "_MBCS" /D "_LIB" /YX /FD /c
# ADD CPP /nologo /MD /W3 /GX /O2 /I "..\include" /I "..\win32" /D "WIN32" /D "NDEBUG" /D "LIBSSH2_WIN32" /D "_MBCS" /D "_LIB" /YX /FD /c
# SUBTRACT CPP /YX
# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32
# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32
# ADD BASE RSC /l 0x409 /d "NDEBUG"
# ADD RSC /l 0x409 /d "NDEBUG"
BSC32=bscmake.exe
# ADD BASE BSC32 /nologo
# ADD BSC32 /nologo
LINK32=link.exe
# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /machine:I386
# ADD LINK32 kernel32.lib ws2_32.lib libeay32.lib ssleay32.lib zlib.lib /nologo /dll /map /debug /machine:I386 /out:"Release_dll/libssh2.dll"
!ELSEIF "$(CFG)" == "libssh2_dll - Win32 Debug"
# PROP BASE Use_MFC 0
# PROP BASE Use_Debug_Libraries 1
# PROP BASE Output_Dir "Debug_dll"
# PROP BASE Intermediate_Dir "Debug_dll"
# PROP BASE Target_Dir ""
# PROP Use_MFC 0
# PROP Use_Debug_Libraries 1
# PROP Output_Dir "Debug_dll"
# PROP Intermediate_Dir "Debug_dll"
# PROP Ignore_Export_Lib 0
# PROP Target_Dir ""
# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "LIBSSH2_WIN32" /D "_MBCS" /D "_LIB" /YX /FD /GZ /c
# ADD CPP /nologo /MDd /W3 /Gm /GX /ZI /Od /I "..\include" /I "..\win32" /D "WIN32" /D "_DEBUG" /D "LIBSSH2_WIN32" /D "_MBCS" /D "_LIB" /YX /FD /GZ /c
# SUBTRACT CPP /WX /YX
# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32
# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32
# ADD BASE RSC /l 0x409 /d "_DEBUG"
# ADD RSC /l 0x409 /d "_DEBUG"
BSC32=bscmake.exe
# ADD BASE BSC32 /nologo
# ADD BSC32 /nologo
LINK32=link.exe
# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /debug /machine:I386 /pdbtype:sept
# ADD LINK32 kernel32.lib ws2_32.lib libeay32.lib ssleay32.lib zlib.lib /nologo /dll /incremental:no /map /debug /machine:I386 /out:"Debug_dll/libssh2.dll" /pdbtype:sept
# SUBTRACT LINK32 /nodefaultlib
!ENDIF
# Begin Target
# Name "libssh2_dll - Win32 Release"
# Name "libssh2_dll - Win32 Debug"
# Begin Group "Source Files"
# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat"
# Begin Source File
SOURCE=..\src\channel.c
# End Source File
# Begin Source File
SOURCE=..\src\comp.c
# End Source File
# Begin Source File
SOURCE=..\src\crypt.c
# End Source File
# Begin Source File
SOURCE=..\src\hostkey.c
# End Source File
# Begin Source File
SOURCE=..\src\kex.c
# End Source File
# Begin Source File
SOURCE=..\src\mac.c
# End Source File
# Begin Source File
SOURCE=..\src\misc.c
# End Source File
# Begin Source File
SOURCE=..\src\openssl.c
# End Source File
# Begin Source File
SOURCE=..\src\packet.c
# End Source File
# Begin Source File
SOURCE=..\src\pem.c
# End Source File
# Begin Source File
SOURCE=..\src\publickey.c
# End Source File
# Begin Source File
SOURCE=..\src\scp.c
# End Source File
# Begin Source File
SOURCE=..\src\session.c
# End Source File
# Begin Source File
SOURCE=..\src\sftp.c
# End Source File
# Begin Source File
SOURCE=..\src\transport.c
# End Source File
# Begin Source File
SOURCE=..\src\userauth.c
# End Source File
# End Group
# Begin Group "Header Files"
# PROP Default_Filter "h;hpp;hxx;hm;inl"
# Begin Source File
SOURCE=..\include\libssh2.h
# End Source File
# Begin Source File
SOURCE=.\libssh2_config.h
# End Source File
# Begin Source File
SOURCE=..\include\libssh2_priv.h
# End Source File
# Begin Source File
SOURCE=..\include\libssh2_sftp.h
# End Source File
# End Group
# End Target
# End Project

View File

@@ -1,25 +1,25 @@
# Microsoft Developer Studio Project File - Name="libssh2" - Package Owner=<4> # Microsoft Developer Studio Project File - Name="libssh2_lib" - Package Owner=<4>
# Microsoft Developer Studio Generated Build File, Format Version 6.00 # Microsoft Developer Studio Generated Build File, Format Version 6.00
# ** DO NOT EDIT ** # ** DO NOT EDIT **
# TARGTYPE "Win32 (x86) Static Library" 0x0104 # TARGTYPE "Win32 (x86) Static Library" 0x0104
CFG=libssh2 - Win32 Debug CFG=libssh2_lib - Win32 Debug
!MESSAGE This is not a valid makefile. To build this project using NMAKE, !MESSAGE This is not a valid makefile. To build this project using NMAKE,
!MESSAGE use the Export Makefile command and run !MESSAGE use the Export Makefile command and run
!MESSAGE !MESSAGE
!MESSAGE NMAKE /f "libssh2.mak". !MESSAGE NMAKE /f "libssh2_lib.mak".
!MESSAGE !MESSAGE
!MESSAGE You can specify a configuration when running NMAKE !MESSAGE You can specify a configuration when running NMAKE
!MESSAGE by defining the macro CFG on the command line. For example: !MESSAGE by defining the macro CFG on the command line. For example:
!MESSAGE !MESSAGE
!MESSAGE NMAKE /f "libssh2.mak" CFG="libssh2 - Win32 Debug" !MESSAGE NMAKE /f "libssh2_lib.mak" CFG="libssh2_lib - Win32 Debug"
!MESSAGE !MESSAGE
!MESSAGE Possible choices for configuration are: !MESSAGE Possible choices for configuration are:
!MESSAGE !MESSAGE
!MESSAGE "libssh2 - Win32 Release" (based on "Win32 (x86) Static Library") !MESSAGE "libssh2_lib - Win32 Release" (based on "Win32 (x86) Static Library")
!MESSAGE "libssh2 - Win32 Debug" (based on "Win32 (x86) Static Library") !MESSAGE "libssh2_lib - Win32 Debug" (based on "Win32 (x86) Static Library")
!MESSAGE !MESSAGE
# Begin Project # Begin Project
# PROP AllowPerConfigDependencies 0 # PROP AllowPerConfigDependencies 0
@@ -28,17 +28,17 @@ CFG=libssh2 - Win32 Debug
CPP=cl.exe CPP=cl.exe
RSC=rc.exe RSC=rc.exe
!IF "$(CFG)" == "libssh2 - Win32 Release" !IF "$(CFG)" == "libssh2_lib - Win32 Release"
# PROP BASE Use_MFC 0 # PROP BASE Use_MFC 0
# PROP BASE Use_Debug_Libraries 0 # PROP BASE Use_Debug_Libraries 0
# PROP BASE Output_Dir "libssh2___Win32_Release" # PROP BASE Output_Dir "Release_lib"
# PROP BASE Intermediate_Dir "libssh2___Win32_Release" # PROP BASE Intermediate_Dir "Release_lib"
# PROP BASE Target_Dir "" # PROP BASE Target_Dir ""
# PROP Use_MFC 0 # PROP Use_MFC 0
# PROP Use_Debug_Libraries 0 # PROP Use_Debug_Libraries 0
# PROP Output_Dir "Release" # PROP Output_Dir "Release_lib"
# PROP Intermediate_Dir "Release" # PROP Intermediate_Dir "Release_lib"
# PROP Target_Dir "" # PROP Target_Dir ""
# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "LIBSSH2_WIN32" /D "_MBCS" /D "_LIB" /YX /FD /c # ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "LIBSSH2_WIN32" /D "_MBCS" /D "_LIB" /YX /FD /c
# ADD CPP /nologo /MD /W3 /GX /O2 /I "..\include" /I "..\win32" /D "WIN32" /D "NDEBUG" /D "LIBSSH2_WIN32" /D "_MBCS" /D "_LIB" /YX /FD /c # ADD CPP /nologo /MD /W3 /GX /O2 /I "..\include" /I "..\win32" /D "WIN32" /D "NDEBUG" /D "LIBSSH2_WIN32" /D "_MBCS" /D "_LIB" /YX /FD /c
@@ -50,18 +50,19 @@ BSC32=bscmake.exe
LIB32=link.exe -lib LIB32=link.exe -lib
# ADD BASE LIB32 /nologo # ADD BASE LIB32 /nologo
# ADD LIB32 /nologo # ADD LIB32 /nologo
# ADD LIB32 /nologo /out:"Release_lib\libssh.lib"
!ELSEIF "$(CFG)" == "libssh2 - Win32 Debug" !ELSEIF "$(CFG)" == "libssh2_lib - Win32 Debug"
# PROP BASE Use_MFC 0 # PROP BASE Use_MFC 0
# PROP BASE Use_Debug_Libraries 1 # PROP BASE Use_Debug_Libraries 1
# PROP BASE Output_Dir "Debug" # PROP BASE Output_Dir "Debug_lib"
# PROP BASE Intermediate_Dir "Debug" # PROP BASE Intermediate_Dir "Debug_lib"
# PROP BASE Target_Dir "" # PROP BASE Target_Dir ""
# PROP Use_MFC 0 # PROP Use_MFC 0
# PROP Use_Debug_Libraries 1 # PROP Use_Debug_Libraries 1
# PROP Output_Dir "Debug" # PROP Output_Dir "Debug_lib"
# PROP Intermediate_Dir "Debug" # PROP Intermediate_Dir "Debug_lib"
# PROP Target_Dir "" # PROP Target_Dir ""
# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "LIBSSH2_WIN32" /D "_MBCS" /D "_LIB" /YX /FD /GZ /c # ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "LIBSSH2_WIN32" /D "_MBCS" /D "_LIB" /YX /FD /GZ /c
# ADD CPP /nologo /MDd /W3 /Gm /GX /ZI /Od /I "..\include" /I "..\win32" /D "WIN32" /D "_DEBUG" /D "LIBSSH2_WIN32" /D "_MBCS" /D "_LIB" /YX /FD /GZ /c # ADD CPP /nologo /MDd /W3 /Gm /GX /ZI /Od /I "..\include" /I "..\win32" /D "WIN32" /D "_DEBUG" /D "LIBSSH2_WIN32" /D "_MBCS" /D "_LIB" /YX /FD /GZ /c
@@ -72,14 +73,14 @@ BSC32=bscmake.exe
# ADD BSC32 /nologo # ADD BSC32 /nologo
LIB32=link.exe -lib LIB32=link.exe -lib
# ADD BASE LIB32 /nologo # ADD BASE LIB32 /nologo
# ADD LIB32 /nologo /out:"Debug\libssh2d.lib" # ADD LIB32 /nologo /out:"Debug_lib\libssh2d.lib"
!ENDIF !ENDIF
# Begin Target # Begin Target
# Name "libssh2 - Win32 Release" # Name "libssh2_lib - Win32 Release"
# Name "libssh2 - Win32 Debug" # Name "libssh2_lib - Win32 Debug"
# Begin Group "Source Files" # Begin Group "Source Files"
# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat" # PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat"
@@ -113,10 +114,22 @@ SOURCE=..\src\misc.c
# End Source File # End Source File
# Begin Source File # Begin Source File
SOURCE=..\src\openssl.c
# End Source File
# Begin Source File
SOURCE=..\src\packet.c SOURCE=..\src\packet.c
# End Source File # End Source File
# Begin Source File # Begin Source File
SOURCE=..\src\pem.c
# End Source File
# Begin Source File
SOURCE=..\src\publickey.c
# End Source File
# Begin Source File
SOURCE=..\src\scp.c SOURCE=..\src\scp.c
# End Source File # End Source File
# Begin Source File # Begin Source File
@@ -129,6 +142,10 @@ SOURCE=..\src\sftp.c
# End Source File # End Source File
# Begin Source File # Begin Source File
SOURCE=..\src\transport.c
# End Source File
# Begin Source File
SOURCE=..\src\userauth.c SOURCE=..\src\userauth.c
# End Source File # End Source File
# End Group # End Group
@@ -154,3 +171,5 @@ SOURCE=..\include\libssh2_sftp.h
# End Group # End Group
# End Target # End Target
# End Project # End Project

View File

@@ -5,7 +5,7 @@
## ##
## Comments to: Guenter Knauf <eflash@gmx.net> ## 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 endif
CP = cp -afv CP = cp -afv
# RM = rm -f # 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 AWK = awk
ZIP = zip -qzr9 ZIP = zip -qzr9

View File

@@ -1,24 +1,24 @@
# Microsoft Developer Studio Project File - Name="ssh2_sample" - Package Owner=<4> # Microsoft Developer Studio Project File - Name="tests" - Package Owner=<4>
# Microsoft Developer Studio Generated Build File, Format Version 6.00 # Microsoft Developer Studio Generated Build File, Format Version 6.00
# ** DO NOT EDIT ** # ** DO NOT EDIT **
# TARGTYPE "Win32 (x86) Console Application" 0x0103 # TARGTYPE "Win32 (x86) Console Application" 0x0103
CFG=ssh2_sample - Win32 Debug CFG=tests - Win32 Debug
!MESSAGE This is not a valid makefile. To build this project using NMAKE, !MESSAGE This is not a valid makefile. To build this project using NMAKE,
!MESSAGE use the Export Makefile command and run !MESSAGE use the Export Makefile command and run
!MESSAGE !MESSAGE
!MESSAGE NMAKE /f "ssh2_sample.mak". !MESSAGE NMAKE /f "tests.mak".
!MESSAGE !MESSAGE
!MESSAGE You can specify a configuration when running NMAKE !MESSAGE You can specify a configuration when running NMAKE
!MESSAGE by defining the macro CFG on the command line. For example: !MESSAGE by defining the macro CFG on the command line. For example:
!MESSAGE !MESSAGE
!MESSAGE NMAKE /f "ssh2_sample.mak" CFG="ssh2_sample - Win32 Debug" !MESSAGE NMAKE /f "tests.mak" CFG="tests - Win32 Debug"
!MESSAGE !MESSAGE
!MESSAGE Possible choices for configuration are: !MESSAGE Possible choices for configuration are:
!MESSAGE !MESSAGE
!MESSAGE "ssh2_sample - Win32 Release" (based on "Win32 (x86) Console Application") !MESSAGE "tests - Win32 Release" (based on "Win32 (x86) Console Application")
!MESSAGE "ssh2_sample - Win32 Debug" (based on "Win32 (x86) Console Application") !MESSAGE "tests - Win32 Debug" (based on "Win32 (x86) Console Application")
!MESSAGE !MESSAGE
# Begin Project # Begin Project
@@ -28,12 +28,12 @@ CFG=ssh2_sample - Win32 Debug
CPP=cl.exe CPP=cl.exe
RSC=rc.exe RSC=rc.exe
!IF "$(CFG)" == "ssh2_sample - Win32 Release" !IF "$(CFG)" == "tests - Win32 Release"
# PROP BASE Use_MFC 0 # PROP BASE Use_MFC 0
# PROP BASE Use_Debug_Libraries 0 # PROP BASE Use_Debug_Libraries 0
# PROP BASE Output_Dir "ssh2_sample___Win32_Release" # PROP BASE Output_Dir "tests___Win32_Release"
# PROP BASE Intermediate_Dir "ssh2_sample___Win32_Release" # PROP BASE Intermediate_Dir "tests___Win32_Release"
# PROP BASE Target_Dir "" # PROP BASE Target_Dir ""
# PROP Use_MFC 0 # PROP Use_MFC 0
# PROP Use_Debug_Libraries 0 # PROP Use_Debug_Libraries 0
@@ -42,7 +42,7 @@ RSC=rc.exe
# PROP Ignore_Export_Lib 0 # PROP Ignore_Export_Lib 0
# PROP Target_Dir "" # PROP Target_Dir ""
# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "LIBSSH2_WIN32" /D "_CONSOLE" /D "_MBCS" /YX /FD /c # ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "LIBSSH2_WIN32" /D "_CONSOLE" /D "_MBCS" /YX /FD /c
# ADD CPP /nologo /MD /W3 /GX /O2 /I "..\include" /I "..\win32" /D "WIN32" /D "NDEBUG" /D "LIBSSH2_WIN32" /D "_CONSOLE" /D "_MBCS" /D "LIBSSH2_LIBRARY" /YX /FD /c # ADD CPP /nologo /MD /W3 /GX /O2 /I "..\include" /I "..\win32" /D "WIN32" /D "NDEBUG" /D "LIBSSH2_WIN32" /D "_CONSOLE" /D "_MBCS" /YX /FD /c
# ADD BASE RSC /l 0x409 /d "NDEBUG" # ADD BASE RSC /l 0x409 /d "NDEBUG"
# ADD RSC /l 0x409 /d "NDEBUG" # ADD RSC /l 0x409 /d "NDEBUG"
BSC32=bscmake.exe BSC32=bscmake.exe
@@ -50,14 +50,14 @@ BSC32=bscmake.exe
# ADD BSC32 /nologo # ADD BSC32 /nologo
LINK32=link.exe LINK32=link.exe
# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 # ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386
# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib libeay32.lib ssleay32.lib ws2_32.lib zlib.lib libssh2.lib /nologo /subsystem:console /machine:I386 /libpath:"Release" # ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib libeay32.lib ssleay32.lib ws2_32.lib zlib.lib libssh2.lib /nologo /subsystem:console /machine:I386 /libpath:"Release" /out:"simple.exe"
!ELSEIF "$(CFG)" == "ssh2_sample - Win32 Debug" !ELSEIF "$(CFG)" == "tests - Win32 Debug"
# PROP BASE Use_MFC 0 # PROP BASE Use_MFC 0
# PROP BASE Use_Debug_Libraries 1 # PROP BASE Use_Debug_Libraries 1
# PROP BASE Output_Dir "ssh2_sample___Win32_Debug" # PROP BASE Output_Dir "tests___Win32_Debug"
# PROP BASE Intermediate_Dir "ssh2_sample___Win32_Debug" # PROP BASE Intermediate_Dir "tests___Win32_Debug"
# PROP BASE Target_Dir "" # PROP BASE Target_Dir ""
# PROP Use_MFC 0 # PROP Use_MFC 0
# PROP Use_Debug_Libraries 1 # PROP Use_Debug_Libraries 1
@@ -66,7 +66,7 @@ LINK32=link.exe
# PROP Ignore_Export_Lib 0 # PROP Ignore_Export_Lib 0
# PROP Target_Dir "" # PROP Target_Dir ""
# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "LIBSSH2_WIN32" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c # ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "LIBSSH2_WIN32" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c
# ADD CPP /nologo /MDd /W3 /Gm /GX /ZI /Od /I "..\include" /I "..\win32" /D "WIN32" /D "_DEBUG" /D "LIBSSH2_WIN32" /D "_CONSOLE" /D "_MBCS" /D "LIBSSH2_LIBRARY" /YX /FD /GZ /c # ADD CPP /nologo /MDd /W3 /Gm /GX /ZI /Od /I "..\include" /I "..\win32" /D "WIN32" /D "_DEBUG" /D "LIBSSH2_WIN32" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c
# ADD BASE RSC /l 0x409 /d "_DEBUG" # ADD BASE RSC /l 0x409 /d "_DEBUG"
# ADD RSC /l 0x409 /d "_DEBUG" # ADD RSC /l 0x409 /d "_DEBUG"
BSC32=bscmake.exe BSC32=bscmake.exe
@@ -74,20 +74,20 @@ BSC32=bscmake.exe
# ADD BSC32 /nologo # ADD BSC32 /nologo
LINK32=link.exe LINK32=link.exe
# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept # ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept
# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib libeay32.lib ssleay32.lib ws2_32.lib zlib.lib libssh2d.lib /nologo /subsystem:console /debug /machine:I386 /nodefaultlib:"msvcrt.lib" /pdbtype:sept /libpath:"Debug" # ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib libeay32.lib ssleay32.lib ws2_32.lib zlib.lib libssh2d.lib /nologo /subsystem:console /debug /machine:I386 /nodefaultlib:"msvcrt.lib" /pdbtype:sept /libpath:"Debug" /out:"simple.exe"
!ENDIF !ENDIF
# Begin Target # Begin Target
# Name "ssh2_sample - Win32 Release" # Name "tests - Win32 Release"
# Name "ssh2_sample - Win32 Debug" # Name "tests - Win32 Debug"
# Begin Group "Source Files" # Begin Group "Source Files"
# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat" # PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat"
# Begin Source File # Begin Source File
SOURCE=..\ssh2_sample.c SOURCE=..\tests\simple.c
# End Source File # End Source File
# End Group # End Group
# Begin Group "Header Files" # Begin Group "Header Files"