Compare commits

..

224 Commits

Author SHA1 Message Date
James Housley
9896c291e4 libssh2_packet_read() was checking the "errno" even when recv() didn't
return an error.  "errno" should have been zero by the recv() call but
doesn't seem to be on all systems.  Only check when recv() says there
is an error.

Bug:		1703467
Patch:		1703468
2007-06-06 10:13:30 +00:00
James Housley
412b25d971 Initially the libssh2 code was indented with tabs of 4 spaces. Some of
the recent commits converted the tabs to 4 spaces, which matched the
initial indent size.  Other commits converted the tabs to 8 spaces, this
didn't match.

All the code has been converted to 4 space indents.  No changes to line
lengths or actual code was performed.  This is in preperation to my up
coming non-blocking work so my commits should only be code changes and
line lengths in the code I am working on.
2007-05-28 17:56:08 +00:00
Daniel Stenberg
355c9c634b Eberhard Mattes' fix for libssh2_packet_read() for when reading very small
chunks at a time.
2007-05-08 19:20:05 +00:00
Dan Fandrich
62f77b1e4b Fix building out of the source tree. 2007-05-01 20:07:08 +00:00
Guenter Knauf
145bbabb96 include libssh_config.h to get the configure vars in. 2007-04-26 23:59:14 +00:00
Guenter Knauf
40970adb53 changed to configure defines to control inclusion of headers from libssh2_config.h. 2007-04-26 22:59:29 +00:00
James Housley
34bcc69a1a Add more of the new programs to be ignored 2007-04-22 19:53:58 +00:00
James Housley
046edb478f Test programs for libssh2_sftp_mkdir_ex() and libssh2_sftp_mkdirnb_ex() 2007-04-22 19:52:51 +00:00
James Housley
54e6528822 Document libssh2_sftp_mkdir_ex() and libssh2_sftp_mkdirnb_ex() 2007-04-22 19:51:53 +00:00
James Housley
a66885c51c Make _libssh2_sftp_mkdir_ex() fully non-blocking safe. This makes
libssh2_sftp_mkdirnb_ex() non-blocking safe and libssh2_sftp_mkdir_ex()
blocking safe
2007-04-22 19:51:24 +00:00
James Housley
510df9bf52 libssh2_sftp.h is needed for all of these functions 2007-04-22 17:18:03 +00:00
James Housley
61807e8d4d Fix a couple of locations where read should have been readdir 2007-04-22 17:09:23 +00:00
James Housley
9ff217b6d2 libssh2_sftp_seek() and libssh2_sftp_tell() are NB-SAFE, since they
only set variables
2007-04-22 16:42:54 +00:00
James Housley
c43c390a7d Create two sample programs, similar to sftp.c and sftp_nonblock.c, that
will test blocking and non-blocking write SFTP transfers
2007-04-22 15:57:52 +00:00
James Housley
7eccfc7fbc Make _libssh2_sftp_write() fully non-blocking safe. This makes
libssh2_sftp_writenb() non-blocking safe and libssh2_sftp_write() blocking
safe
2007-04-22 15:56:06 +00:00
James Housley
d79939fc3a Commit the version that actually uses the non-blocking code 2007-04-22 15:05:06 +00:00
James Housley
c5fb9d8f1a Commit the version that actually uses the non-blocking read 2007-04-22 14:51:21 +00:00
James Housley
e85a2199b6 Update comment 2007-04-22 14:47:27 +00:00
James Housley
3bd3eb35b3 Make sftp_nonblock.c a non-blocking version of sftp.c, just like sftpdir.c 2007-04-22 14:16:26 +00:00
James Housley
08fd7e259b Move sftp_nonblock.c to sftp_RW_nonblock.c, since it isn't just a
non-blocking version of sftp.c.  It has different command line parameters
and tries to do more
2007-04-22 14:15:47 +00:00
James Housley
42f0f69a35 Make _libssh2_sftp_read() fully non-blocking safe. This makes
libssh2_sftp_readnb() non-blocking safe and libssh2_sftp_read() blocking
safe
2007-04-22 13:13:51 +00:00
James Housley
75ac861c7a * Explicity set blocking 2007-04-22 13:10:48 +00:00
James Housley
04e975b6c7 Unless we tell libssh2 that we are blocking, which we are because didn't
set the socket to non-blocking it will think we are in non-blocking mode
in a lot of places
2007-04-22 11:01:54 +00:00
James Housley
f14aa01bb8 Add comment about setting non-blocking 2007-04-22 11:00:02 +00:00
Guenter Knauf
ab7c3fb2d4 fixed ARFLAGS for CodeWarrior build. 2007-04-21 23:36:51 +00:00
Guenter Knauf
1ebe0a64b3 some more makefile fixes. 2007-04-21 21:26:54 +00:00
Guenter Knauf
6cd1c7528e fixed debug option. 2007-04-21 20:15:33 +00:00
Guenter Knauf
91c8715da4 fixed ARFLAGS for CodeWarrior build;
added libssh2_sftp_writenb to export list.
2007-04-21 18:46:30 +00:00
James Housley
2dc313d365 Non-blocking work
* The following low level packet routines now fully support non-blocking:
    libssh2_sftp_packet_read()
    libssh2_sftp_packet_ask()
    libssh2_sftp_packet_require()
    libssh2_sftp_packet_requirev()

* libssh2_sftp_readdirnb() functions completely in non-blocking mode

* The rest of the routines which call the libssh2_sftp_packet_* routine
  loop on a return code of PACKET_EAGAIN.  This maintains the current
  functionality until they fully support non-blocking

* The state of all function are labeled with either NB-SAFE or NB-UNSAFE,
  for those that are know.  NB-UNSAFE?? for those that haven't been
  examined.
2007-04-21 18:16:23 +00:00
James Housley
f8fe38e3a5 Create a simple test for sftp readdir with non-blocking 2007-04-21 18:08:00 +00:00
James Housley
bda32b6bbf Document libssh2_sftp_readdir() and libssh2_sftp_readdirnb() 2007-04-21 18:07:17 +00:00
Dan Fandrich
09deb228f1 Added some consts to struct members 2007-04-19 19:40:45 +00:00
Dan Fandrich
1a6e00cfef Fixed some compiler warnings and made some more tables 'const'. 2007-04-18 21:03:42 +00:00
Dan Fandrich
9b81a01376 Made some function parameters in the API const. This is an API change,
but correctly-written applications should see no source or binary
compatibility issues.  Also fixed a few compiler warnings.
2007-04-18 18:51:03 +00:00
Dan Fandrich
4c6bfdd5b2 Bail out on a short kex packet. 2007-04-17 18:30:05 +00:00
Dan Fandrich
5dd66e604f Made most internal tables 'static const'. 2007-04-17 18:12:41 +00:00
Guenter Knauf
d45d509a09 added ranlib when library is created with ar. 2007-04-16 20:56:08 +00:00
Guenter Knauf
d44e222b75 added sftpdir target; fixed linking. 2007-04-14 21:26:03 +00:00
Dan Fandrich
197764afcc Properly propagate out of memory errors. 2007-04-13 18:28:10 +00:00
Simon Josefsson
d79f906b52 Add. 2007-04-13 06:09:12 +00:00
Simon Josefsson
08cf9fd7de Add. 2007-04-13 06:08:25 +00:00
Simon Josefsson
7edad3046e Make ChangeLog a phony target. 2007-04-13 06:06:15 +00:00
Guenter Knauf
f33375bc03 changed to configure defines to control inclusion of headers from libssh2_config.h. 2007-04-12 22:20:18 +00:00
Guenter Knauf
159c351d05 Win32 has no ENOTCONN - checked MSVC6, MingW32, Borland C++ 5.5, OpenWatcom 1.6; all have this define in winsock2.h but blocked with '#if 0';
changed to configure defines to control inclusion of headers from libssh2_config.h
2007-04-12 22:18:27 +00:00
Guenter Knauf
8371fa7b87 updated Makefile.netware to add more exports; fixed linking;
updated OpenSSL version to have users use latest.
2007-04-12 22:15:12 +00:00
Guenter Knauf
0eefd06af0 removed HAVE_IOCTLSOCKET define;
updated OpenSSL version to have users use latest.
2007-04-12 22:13:14 +00:00
Guenter Knauf
86ca80028b blocked unistd.h inclusion for Win32 builds. 2007-04-12 22:10:12 +00:00
Guenter Knauf
0c060e1ccb added two more typedefs but blocked them so they are only used with MSVC6 or lower (dont know if later MSVC versions still need them). 2007-04-12 22:08:42 +00:00
Guenter Knauf
51e49f5a1e fixed wrong type and sync with usage. 2007-04-12 22:03:27 +00:00
Guenter Knauf
93e36271a6 check for sys/time.h 2007-04-12 22:00:55 +00:00
Dan Fandrich
6dfb2e3009 Better handle out of memory situations. 2007-04-12 21:51:57 +00:00
Daniel Stenberg
a84d2ca430 added --enable-debug 2007-04-12 21:40:22 +00:00
Guenter Knauf
3026c46109 removed ENOTCONN define, added HAVE_IOCTLSOCKET define;
added the new defines for inclusion of headers.
2007-04-12 21:37:09 +00:00
Dan Fandrich
4e920fe2be Fixed some spelling mistakes in documentation. 2007-04-12 21:30:03 +00:00
Dan Fandrich
164c6e9fc5 libssh2_channel_close now waits for a SSH_MSG_CHANNEL_CLOSE message
from the server as mandated by the RFC.  Not doing so causes an OpenSSH
server to occasionally corrupt (truncate) short files uploaded by scp
(which manifests itself as a failure of test603 in the curl regression
test suite).
2007-04-12 21:24:36 +00:00
Simon Josefsson
0cf3845302 Replace #if !WIN32 with #if HAVE_SYS_SOCKET_H and HAVE_SYS_IOCTL_H
(AIX needs sys/ioctl.h).  Reported by Michael Augustin
<maugustin-hi6Y0CQ0nG0@public.gmane.org>.
2007-04-11 07:22:33 +00:00
Simon Josefsson
149af707de Use _libssh2_* namespace. Suggested by Guenter Knauf
<eflash-hi6Y0CQ0nG0@public.gmane.org>.
2007-04-05 20:36:17 +00:00
Simon Josefsson
e1bc0adcb1 Use Bruno's M4 macros to search for libgcrypt. 2007-04-05 10:23:54 +00:00
Simon Josefsson
2f207bdad5 *** empty log message *** 2007-04-05 10:21:09 +00:00
Simon Josefsson
7972822465 Remove generated files. 2007-04-05 10:00:26 +00:00
Simon Josefsson
b370b89eeb Moved to README. 2007-04-05 09:59:48 +00:00
Simon Josefsson
01d7396160 Need sys/ioctl.h for FIONBIO, tiny patch from Michael Augustin
<maugustin@gmx.net>.
2007-04-05 09:58:25 +00:00
Simon Josefsson
43e377c08e Fix AIX problem, based on patch from Michael Augustin <maugustin@gmx.net>. 2007-04-05 09:31:38 +00:00
Simon Josefsson
348b914ab7 Protect #include of zlib.h if we build without zlib. 2007-04-04 14:44:50 +00:00
Mikhail Gusarov
e7b3a2efc5 Enabled fragmenting SFTP requests to LIBSSH2_SFTP_PACKET_MAXLEN.
(Thanks to elifantu@mail.ru for the patch)
2007-04-01 08:04:32 +00:00
Mikhail Gusarov
56608a799f Missing brace added 2007-04-01 07:40:49 +00:00
Mikhail Gusarov
f29f85f482 libssh2_sftp_read should not return error if it receives SSH_FX_EOF code in
SSH_FXP_STATUS packet.

(Thanks to elifantu@mail.ru for the patch)
2007-04-01 06:23:49 +00:00
Daniel Stenberg
2a48f54937 Callers should be using libssh2_packet_require_ex instead of
libssh2_packet_ask_ex. The purpose of these calls is to clear out any packets
that may have arrived already, so there's no need to poll for more.
(Dan Fandrich)
2007-03-31 20:28:29 +00:00
Simon Josefsson
4c7ecad34d Don't use CPP symbol _MSC_VER unless it is defined, because undefined
CPP symbols means 0.  Tiny patch from "Yang Tse" <yangsita@gmail.com>.
2007-03-29 08:11:51 +00:00
Simon Josefsson
53d6597569 Need -no-undefined for AIX/cygwin/mingw32 etc. Reported by "Yang Tse"
<yangsita@gmail.com>.
2007-03-29 08:10:22 +00:00
Simon Josefsson
af12b96a80 Add comment. 2007-03-27 15:57:23 +00:00
Simon Josefsson
e854459839 Set $SHLIB_SUFFIX_NAME properly, tiny patch from Daniel Johnson
<daniel@daniel-johnson.org>.
2007-03-27 15:56:08 +00:00
Simon Josefsson
af00ce242e Remove -no-install since it breaks Darwin builds (probably a libtool
bug), report from Daniel Johnson <daniel@daniel-johnson.org>.
2007-03-27 15:35:37 +00:00
Simon Josefsson
fa1d8da7a3 Generated. 2007-03-27 13:33:18 +00:00
Simon Josefsson
2d7f1ad47c fix 2007-03-27 13:32:57 +00:00
Simon Josefsson
0ace54f5b6 Add. 2007-03-27 13:27:13 +00:00
Simon Josefsson
7ebafd3999 Add. 2007-03-27 13:24:01 +00:00
Simon Josefsson
86cdc614c8 Add -lsocket/-lnsl. End sentences with '.'. 2007-03-27 13:21:24 +00:00
Simon Josefsson
15d9b50be4 Add. Start sentences with uppercase. 2007-03-27 13:20:18 +00:00
Simon Josefsson
ebc55b5d75 Use AC_SEARCH_LIBS on socket() for -lsocket, so we don't link with
-lsocket unless it is necessary.
Remove SHLIB_LDFLAGS, it was never used by anything.
2007-03-27 13:11:19 +00:00
Simon Josefsson
cf9ffc053a Add jehousley. 2007-03-27 13:07:20 +00:00
Simon Josefsson
25a810bbc8 Fix typo. 2007-03-27 13:05:35 +00:00
Simon Josefsson
db2a895ecf (libssh2_poll_channel_write, libssh2_poll_listener_queued): Mark as
static.  Remove unneeded prototypes.  Break Solaris 10 builds
according to "Heiko Jansen" <jansen@hbz-nrw.de>.
2007-03-27 13:03:46 +00:00
Simon Josefsson
94a71fe995 (libssh2_packet_x11_open, libssh2_packet_queue_listener): Mark as
static functions.  Remove unnecessary prototypes.  Breaks Solaris 10
builds according to "Heiko Jansen" <jansen@hbz-nrw.de>.
2007-03-27 13:02:01 +00:00
Simon Josefsson
0eabcb386e Search -lnsl for inet_addr, suggested by "Heiko Jansen"
<jansen@hbz-nrw.de>.
2007-03-27 12:59:00 +00:00
Simon Josefsson
93dc3f565e Fix typo, reported by "Heiko Jansen" <jansen@hbz-nrw.de>. 2007-03-27 12:52:16 +00:00
Simon Josefsson
48410937b2 Dist buildconf, suggested by "Heiko Jansen" <jansen@hbz-nrw.de>. 2007-03-27 12:50:09 +00:00
Simon Josefsson
864ceec7bd Add 'dist_' to make sure man pages are included in the release. 2007-03-27 12:48:53 +00:00
Simon Josefsson
8ac3f7e485 Add rule to generate ChangeLog.
No need for foreign or nostdinc (correct me if I'm wrong?).
2007-03-27 12:44:44 +00:00
Simon Josefsson
2e20808f8c Add, needed by cvs2cl. 2007-03-27 12:32:56 +00:00
Simon Josefsson
53fb8b1969 Add. 2007-03-27 12:28:18 +00:00
Simon Josefsson
7dfbbf9c1c Remove. 2007-03-27 12:24:56 +00:00
Simon Josefsson
d131f6457c Add, from LICENSE. 2007-03-27 12:24:35 +00:00
Simon Josefsson
a3a9b0385e Rewrite, based on INSTALL. 2007-03-27 12:22:22 +00:00
Simon Josefsson
20297b51bd Add, from README. 2007-03-27 12:10:25 +00:00
Daniel Stenberg
ba9f0b2ce6 Dan Fandrich fixed another memory leak, this time in the OpenSSL interface
code:

It's not clear to me whether all the BN_news in _libssh2_rsa_new need to
be cleaned up, too.  The OpenSSL docs for RSA_free implies that you don't
need to, and valgrind doesn't complain, so it's probably OK as is.
2007-03-15 21:37:43 +00:00
Daniel Stenberg
56f606a98e give credit to those who made the changes 2007-03-15 20:57:11 +00:00
Daniel Stenberg
b553f1087e fixed a memory leak in the packet handling (Dan Fandrich) 2007-03-15 20:56:45 +00:00
Daniel Stenberg
75ceed5776 Dan Fandrich patch:
1 - let libssh2 compile with OpenSSL 0.9.6b.  This is due to 'crypt' is found
in one of its header files and EVP_MAX_BLOCK_LENGTH not being found.

2 - The EXEEXT patch is because automake 1.7 doesn't support it, and recent
automakes add it automatically
2007-03-14 21:59:12 +00:00
Daniel Stenberg
689c394c57 Added sftpdir, a sample doing an SFTP directory listing 2007-02-23 11:18:41 +00:00
Daniel Stenberg
de60096af1 nicer look 2007-02-23 10:38:14 +00:00
Daniel Stenberg
9aa460b55b more/updated man pages 2007-02-23 10:20:56 +00:00
Daniel Stenberg
7c115d350c Lucas Newman found and fixed a problem where libssh2_packet_read() could "lose"
bytes when it read data from the network that was an unaligned number of bytes
compared to the blocksize.
2007-02-14 20:50:43 +00:00
Daniel Stenberg
1ce26ef4a2 add include to fix compiler warning 2007-02-08 14:50:33 +00:00
Daniel Stenberg
92c75854fb Guenter Knauf added support for another IP and I changed the order of the
arguments and updated some comments.
2007-02-08 14:44:32 +00:00
Daniel Stenberg
f015b10b02 Guenter Knauf's Netware+Win32 updates after my recent changes 2007-02-08 14:34:41 +00:00
Daniel Stenberg
972d6d8bd4 removed unused variable 2007-02-07 21:42:45 +00:00
Daniel Stenberg
fee0239211 setting sockets non-blocking using more portable code and configure macros
from the libcurl project (written by me)
2007-02-07 21:39:17 +00:00
Daniel Stenberg
e7181a8c36 Netware and Windows fixes by Guenter Knauf 2007-02-07 21:21:06 +00:00
Daniel Stenberg
b88eb6a096 let's call the current version 0.15-CVS 2007-02-06 14:19:59 +00:00
Simon Josefsson
f6e26916ac Remove unused uses of -lm and math.h. 2007-02-04 13:16:17 +00:00
Simon Josefsson
39876b2ee3 Fix. 2007-02-04 13:10:46 +00:00
Daniel Stenberg
4f1cfb20a9 1 - new public function libssh2_trace() that enables tracing/debug output on
various stuff if libssh2 was built with debug. If built without debug, the
 function does nothing.
2 - configure --enable-debug is now enough to build a debug version (including
picky compiler options)
3 - internally, we no longer need/use #ifdef/#endif around all uses of the
_libssh2_debug() function/macro.

The scp.c example is the first application to test this new debug logging.
2007-02-02 23:23:36 +00:00
Daniel Stenberg
6304383c91 non-blocking and man pages 2007-02-02 22:28:48 +00:00
Daniel Stenberg
bd1980ea1c Include man pages in distro tarball and make install. Note that this is still
(by far) an incomplete set of man pages.
2007-02-02 22:27:06 +00:00
Daniel Stenberg
be4c3f59d4 bump the version-info due to the changes in the API we're working on and due
to the fact that there's release of the previous CVS-state shipped in Debian
(and possibly others distros).
2007-02-02 22:09:30 +00:00
Daniel Stenberg
9d55db6501 Adding src/transport.c for the SECSH transport layer read/write in a non-
blocking way. The channel code is now responsible for enabling/disabling
blocking status and to work with it.

I've also modified indenting and fixed compiler warnings at places, and
added a bunch of new examples in example/simple that I've used to verify that
the code still runs like before.

libssh2_channel_{read|write}nb_ex() and libssh2_sftp_{read|write}nb() are the
four new functions that supposedly work non-blocking.
2007-02-02 16:21:20 +00:00
Daniel Stenberg
c63ef86075 non-blocking stuff removed, see *readnb_ex() 2007-02-02 16:11:55 +00:00
Daniel Stenberg
1b733d1196 more docs, including a template.3 for new man pages 2007-02-02 16:09:12 +00:00
Simon Josefsson
3c61a44224 Libgcrypt stuff works. 2007-02-02 11:22:39 +00:00
Simon Josefsson
20527d9688 Mind your p's and q's! RSA authentication now works. 2007-02-02 11:18:34 +00:00
Daniel Stenberg
09ee2d4086 Chris Nystrom helped me realize I must count the received bytes myself to
know when the transfer is complete
2007-02-01 22:39:45 +00:00
Daniel Stenberg
5859642888 oops, it shouldn't be non-blocking when doing blocking transfers... 2007-01-30 11:10:26 +00:00
Daniel Stenberg
ba1eb9f8fc simple (blocking) SCP transfer 2007-01-30 11:07:14 +00:00
Daniel Stenberg
e2f6518d95 two simple samples 2007-01-24 14:15:36 +00:00
Daniel Stenberg
a139ab0b45 fix compiler warnings 2007-01-23 21:36:40 +00:00
Simon Josefsson
f1e7eb7ae8 Fix RSA private key reading (still not working). 2007-01-23 15:12:41 +00:00
Simon Josefsson
b790cabf6a Fix warnings. 2007-01-23 13:55:11 +00:00
Simon Josefsson
d2be40421a Fix warnings. 2007-01-23 12:44:14 +00:00
Simon Josefsson
b1d855d1ac Fix warnings. 2007-01-23 12:44:14 +00:00
Simon Josefsson
1826e7365d Fix warnings. 2007-01-23 12:32:06 +00:00
Simon Josefsson
7f9ea39a5d Fix mem leak. 2007-01-23 12:26:36 +00:00
Simon Josefsson
6cf4420264 Fix mem leak. 2007-01-23 12:18:50 +00:00
Simon Josefsson
bfb71f3075 Need more #include's. 2007-01-23 11:53:27 +00:00
Simon Josefsson
1f232d69ed Fix warnings. 2007-01-23 11:52:23 +00:00
Simon Josefsson
f252d350ec Fix warnings. 2007-01-23 11:52:08 +00:00
Simon Josefsson
4c2c468b08 Remove OpenSSL #include. 2007-01-23 11:29:13 +00:00
Simon Josefsson
a86a4e0cfc Fix mem leak. 2007-01-23 11:28:05 +00:00
Simon Josefsson
b1f8bafb64 If --with-libgcrypt is specified, don't check for OpenSSL. 2007-01-23 10:37:14 +00:00
Simon Josefsson
c9d40afa14 Abstract bignum API. 2007-01-23 10:29:55 +00:00
Simon Josefsson
51b9ff0f16 Abstract RSA/DSA private key file reading and RSA/DSA signing, and
implement them in openssl/libgcrypt layer.
2007-01-23 08:22:54 +00:00
Simon Josefsson
0d9a7e3c2e Add prototypes for pem.c functions. 2007-01-23 08:14:14 +00:00
Simon Josefsson
75115045ae Add pem.c. 2007-01-23 08:13:32 +00:00
Simon Josefsson
be984707e2 Add. Functions for reading PEM files and decoding ASN.1. 2007-01-23 08:13:10 +00:00
Daniel Stenberg
2afd706ca1 please picky compiler 2007-01-22 21:40:44 +00:00
Simon Josefsson
fe979040a2 Remove non-iovec based RSA/DSA signing (not used, and DSA code even buggy). 2007-01-22 14:15:38 +00:00
Daniel Stenberg
0fab9e9614 fix warning for memcpy() 2007-01-19 21:32:31 +00:00
Simon Josefsson
576d37dafd Indent.
Fix mem leak on errors.
2007-01-18 11:37:32 +00:00
Simon Josefsson
a0eda7365e Remove openssl #include.
Protect use of 3DES.
Reorder definitions to match preference order.
2007-01-18 11:32:20 +00:00
Simon Josefsson
1f79c7da95 Remove debug code. 2007-01-18 11:30:23 +00:00
Simon Josefsson
6ede32c5e2 Use new generic crypto APIs. 2007-01-18 11:22:10 +00:00
Simon Josefsson
10efccbb83 Align with new _LIBSSH2_CRYPT_METHOD API, for libgcrypt support. 2007-01-18 11:21:39 +00:00
Simon Josefsson
2e8d9217b4 Fix _LIBSSH2_CRYPT_METHOD for libgcrypt support. 2007-01-18 11:21:12 +00:00
Simon Josefsson
d3c334c3d6 Implement new _libssh2_cipher_* API. 2007-01-18 11:20:17 +00:00
Simon Josefsson
e1bebf979b Support DSA verifications. 2007-01-18 07:51:41 +00:00
Simon Josefsson
50d587e2bc Check return value.
Fix SHA1_Final.
2007-01-18 07:47:54 +00:00
Simon Josefsson
e0fe196e45 Add. 2007-01-17 20:22:12 +00:00
Simon Josefsson
dc994f64a9 Add more files. 2007-01-17 20:21:47 +00:00
Simon Josefsson
46cd4f42d8 Add more files. 2007-01-17 20:20:49 +00:00
Simon Josefsson
19690441cd Fix 3DES check. 2007-01-17 15:09:04 +00:00
Simon Josefsson
dc7cdb8cb0 Use libssh2_sha1 instead of SHA1. 2007-01-17 15:07:54 +00:00
Simon Josefsson
be4461e4cd Fix last commit. 2007-01-17 15:06:53 +00:00
Simon Josefsson
23d772867e Use libssh2_* wrappers for SHA-1. 2007-01-17 15:05:57 +00:00
Simon Josefsson
c090ac7ed1 Use LIBSSH2_* instead of OPENSSL_NO_* (should ultimately be possible
to chose by ./configure?).
2007-01-17 15:01:29 +00:00
Simon Josefsson
6873ada0b7 Use LIBSSH2_* instead of OPENSSL_NO_* (should ultimately be possible
to chose by ./configure?).
2007-01-17 14:41:06 +00:00
Simon Josefsson
5c904b112e Unconditionally use SHA-1. 2007-01-17 14:35:40 +00:00
Simon Josefsson
b4d7a4eede Add. 2007-01-16 15:51:31 +00:00
Simon Josefsson
22225099bc Add. 2007-01-16 15:36:43 +00:00
Simon Josefsson
2d8ee8b37c Begin to abstract RSA operations. 2007-01-16 15:33:09 +00:00
Simon Josefsson
219fa19a5f Also build openssl.c or libgcrypt.c. 2007-01-16 15:32:17 +00:00
Simon Josefsson
5443c76c8e Define an automake conditional iff libgcrypt is used. 2007-01-16 15:13:50 +00:00
Simon Josefsson
79761a6455 Use generic APIs for (HMAC-)MD5/SHA1 and RNG, and implement them via OpenSSL/libgcrypt. 2007-01-15 21:12:00 +00:00
Simon Josefsson
362d3466cf Add, for libgcrypt. 2007-01-15 18:16:27 +00:00
Simon Josefsson
6d65428511 Look for libgcrypt if --with-libgcrypt is given to ./configure.
Note that until the libgcrypt work is complete, libssh2 also link to OpenSSL.
2007-01-15 18:16:07 +00:00
Simon Josefsson
677005375b Remove unfinished OPENSSL_NO_SHA ifdef stuff, since SHA-1 is required for libssh2 to work. 2007-01-10 17:29:46 +00:00
Simon Josefsson
8a2421bad1 Add basic self test. 2007-01-09 09:49:15 +00:00
Mikhail Gusarov
5cd3efc297 --copy added to automake --add-missing to avoid symlinks in bootstrapped CVS snapshot tarballs 2007-01-03 09:56:31 +00:00
Mikhail Gusarov
f527a88095 Minus sign escaped to not be treated as emdash in man pages. 2007-01-02 05:47:00 +00:00
Daniel Stenberg
fd2368d2b1 fix compiler warnings (and some indent changes) 2006-12-21 14:21:38 +00:00
Daniel Stenberg
036bb51421 fix compiler warnings 2006-12-21 14:20:20 +00:00
Daniel Stenberg
c92d1a5a23 fix compiler warnings, minor re-indenting 2006-12-21 14:19:42 +00:00
Daniel Stenberg
862a758026 Added an initial set of man pages. 2006-12-21 14:09:12 +00:00
Daniel Stenberg
f7f897df07 fix warnings and allow passing user name and password on the command line 2006-12-21 14:06:49 +00:00
Daniel Stenberg
ef8d1a2af8 Added the configure option --enable-debug-build which not only enables a
debug build (using -g and disabling all -O options), but also sets a whole
range of picky/strict compiler options depending on what compiler and version
that is used. This function is ripped right off the curl configure script,
written by yours truly. I left it using the same name as in the curl script
to 1) make it obvious where it comes from, so that 2) it will be easier to
update and keep it in sync with future modifications.

Now, this shows MAAAAAAAAANY warnings...
2006-12-13 08:45:49 +00:00
Daniel Stenberg
556cafc457 Removed use of ceil() since that is a math lib function and getting the
exact accuracy of the microsecond to millisecond conversion simply cannot
be that important. We don't even explicitly link with -lm...
2006-12-13 08:42:54 +00:00
Simon Josefsson
75b5e06773 Fix indentation. 2006-12-09 09:06:06 +00:00
Simon Josefsson
91e496ff41 Add. 2006-12-07 16:12:44 +00:00
Simon Josefsson
6b1dc88b14 Add autobuild.m4, to make it easier to use http://autobuild.josefsson.org/. 2006-12-07 15:53:01 +00:00
Simon Josefsson
14b9deef24 Move symmetric OpenSSL EVP crypto calls to crypt.c. 2006-12-07 15:44:07 +00:00
Mikhail Gusarov
82d762cae5 Improve detection of closed channel. Eleminates lock-ups on
multi-channel operation.
2006-11-27 07:37:40 +00:00
Mikhail Gusarov
1c1c74479e Reading bigger blocks from network before decryption.
Significantly increases performance.
2006-11-27 07:31:28 +00:00
Mikhail Gusarov
3a33680e14 write(2) may write only part of passed data under FreeBSD.
Make sure whole buffer is written.
2006-11-27 07:24:18 +00:00
Daniel Stenberg
38fea1973d mention a few recent changes 2006-11-24 10:14:31 +00:00
Daniel Stenberg
c63a212559 Add builddir/src to the include path, for the generated config header when
building out of the source tree.
2006-11-20 22:21:01 +00:00
Daniel Stenberg
a8451f58df ssh2_sample now gets the right include path to the current include directory 2006-11-20 22:19:40 +00:00
Daniel Stenberg
1dbe8ff365 check for inline in configure 2006-11-20 22:10:56 +00:00
Daniel Stenberg
82424d6735 Starting now, we use automake and libtool for the build. 2006-11-20 08:58:29 +00:00
Daniel Stenberg
3b1b45e644 Moved the private include files libssh2_priv.h and libssh2_config.h.in from
include/ into the src/ directory. The include/ dir is now strictly for public
headers.

Also, I removed the special win32 source package creation target in the
makefile and I modified the contact email address in configure.in to point out
the libssh2-devel list.
2006-11-20 08:41:04 +00:00
Daniel Stenberg
84f10fca87 kill compiler warnings 2006-11-19 13:39:01 +00:00
Daniel Stenberg
077ba3efd5 until we automake, let 'make' build all by default 2006-11-19 13:28:03 +00:00
Daniel Stenberg
ab26693769 kill warnings 2006-11-19 13:26:19 +00:00
Daniel Stenberg
1854b4536f Use pkg-config --cflags-only-I when getting the include files necessary to
build with OpenSSL. Previous approach caused a bad compiler option get set.
2006-11-17 10:26:11 +00:00
James Housley
1baaa31792 Patch from Daniel Stenberg
1 - #include <inttypes.h> and uses uint32_t (this is not very portable and
    need attention as I mentioned in my separate mail)

2 - changes libssh2_blocking_read() to return ssize_t and all code that uses
    this function explicitly checks its return code (better).

3 - I fixed a bunch of compiler warnings where functions got called with
    unsigned char * when they expect char *. I strongly suggest we patch away
    all warnings - now.
2006-11-14 01:30:39 +00:00
James Housley
7058b7fc2a Reproduce most of the POSIX permission/file type defines from sys/stat.h
so that if compiled with a non-POSIX compiler these are still available
for client software.
2006-11-13 22:35:02 +00:00
James Housley
1e889ca947 As pointed out, feof() will always fail after a rewind 2006-11-13 15:10:38 +00:00
James Housley
bebd14a011 Bug: [ 1592645 ] Public key can not be readed from file
While posting a public key file to a remote server via cut-n-paste it
is possible that the key won't have the proper ending.  It might not have
the standard carriage return or line feed.  It might even have extra
spaces.  This patch is based on the originators original patch, but is
more extensive.  If reading the file ends in EOF, remove that character.
Then if there are spaces at the end of the file remove them also.

This does not fix the posibility of the same error in a multi-key file, but
it is a start.
2006-11-13 11:33:03 +00:00
James Housley
7063d24724 /* RFC4253 section 6.1 Maximum Packet Length says:
*
 * "All implementations MUST be able to process packets with
 * uncompressed payload length of 32768 bytes or less and
 * total packet size of 35000 bytes or less (including length,
 * padding length, payload, padding, and MAC.)."
 */
Protect against an improper packet from producing unreasonable values.
Credit goes to Daniel Stenberg
2006-11-10 13:47:13 +00:00
James Housley
8069fa6f9a libssh2_sftp_readdir() wasn't null terminating the filename. If there is
enough room in the buffer, all a null to the end.
2006-11-10 12:16:24 +00:00
James Housley
1961e07287 The public *_ex() API functions, most of them, used "int" for length values.
The convience functions pass in the return from strlen() which is "size_t",
usually an "unsigned long".  This created the possiblility of passing in
a value that could look negative.

All "int" lengths were converted to "unsigned int".  Ideally they should
all become "size_t", but that is a bigger change.  This is a good start.
2006-11-04 19:30:31 +00:00
Sara Golemon
ace0c8f00b Bump for release 2006-06-22 18:50:26 +00:00
Sara Golemon
adee5e5653 Don't wait for KEX_INIT prior to sending our own packet.
Watch out for bad KEX_INIT guesses and burn packets if necessary.
2006-06-22 18:45:29 +00:00
Sara Golemon
5f85317efa Swap ordering of packet_add/packet-inspection to avoid inspect after free. Fix OpenSSL detection using pkg-config. 2006-05-26 22:36:48 +00:00
Sara Golemon
09b93e4bb6 Map Win32 errno values 2006-04-17 02:49:44 +00:00
Sara Golemon
19cad102f4 autoconf already handles -g for us 2006-04-07 20:44:26 +00:00
Sara Golemon
4d7726c551 Plug leaks caused by not using OpenSSL's EVP interface correctly 2006-04-06 21:50:37 +00:00
Sara Golemon
37307a8778 Map win32 error codes 2006-04-05 05:36:53 +00:00
Sara Golemon
fbcdff2161 Allow socket_fd == 0 in libssh2_session_startup() 2006-03-08 19:10:53 +00:00
Sara Golemon
c45992da55 Bump copyright year 2006-03-02 01:10:52 +00:00
Sara Golemon
2207b99afb Bump version number 2006-03-02 01:10:06 +00:00
Sara Golemon
1d7522bc06 BugFix#1436593: Apply build options for HPUX targets 2006-02-23 23:14:35 +00:00
Mikhail Gusarov
a4e61c265b Fixed errorneous flushing packets for unrelated channels when one is closed
(thanks to Alexander Holyapin)
2006-02-20 08:39:54 +00:00
Sara Golemon
502a48afa1 Fix make install on MacOSX 2006-01-06 17:34:03 +00:00
Sara Golemon
efc3841fd2 Add terminating NULL to readlin/realpath results 2005-11-17 23:20:32 +00:00
Sara Golemon
f9d65b0984 Fix miscellaneous bugs in src/channel.c and src/packet.c
Courtessy David Robins
2005-11-02 00:26:24 +00:00
101 changed files with 19905 additions and 11692 deletions

View File

@@ -1,3 +1,5 @@
.deps
.libs
*.lib *.lib
*.pdb *.pdb
*.dll *.dll
@@ -7,3 +9,20 @@
Debug Debug
Release Release
*.exp *.exp
Makefile
Makefile.in
aclocal.m4
autom4te.cache
config.guess
config.log
config.status
config.sub
configure
depcomp
libtool
ltmain.sh
missing
ssh2_sample
libssh2-*.tar.gz
INSTALL
install-sh

9
.cvsusers Normal file
View File

@@ -0,0 +1,9 @@
jas4711:Simon Josefsson <simon@josefsson.org>
bagder:Daniel Stenberg <daniel@haxx.se>
sarag:Sara Golemon <pollita@libssh2.org>
gusarov:Mikhail Gusarov <dottedmag@dottedmag.net>
wez:Wez Furlong
edink:Edink Kadribasic
jehousley: James Housley
gknauf: Guenter Knauf
dfandrich: Dan Fandrich

9
AUTHORS Normal file
View File

@@ -0,0 +1,9 @@
* Sara Golemon: Author / Project Manager
* Simon Josefsson: libgcrypt support
* Daniel Stenberg: Nonblocking fixes, Build Improvements, and Daily snapshot artist
* Mikhail Gusarov: Keyboard Interactive Authentication
* Wez Furlong & Edink Kadribasic: Windows Port

View File

@@ -1,4 +1,5 @@
/* Copyright (c) 2004-2005, Sara Golemon <sarag@libssh2.org> /* Copyright (c) 2004-2007 Sara Golemon <sarag@libssh2.org>
* Copyright (C) 2006-2007 The Written Word, Inc.
* All rights reserved. * All rights reserved.
* *
* Redistribution and use in source and binary forms, * Redistribution and use in source and binary forms,

1567
ChangeLog Normal file

File diff suppressed because it is too large Load Diff

60
INSTALL
View File

@@ -1,60 +0,0 @@
Installing libssh2
==================
* Untar this tarball (which, if you're reading this, you've already done)
* Run: ./configure (passing additional options as desired)
In addition the the standard set of ./configure options (e.g. --prefix)
there are five switches which you may wish to pay attention to:
* --with-openssl=[DIR]
libssh2 requires the OpenSSL library (http://www.openssl.org) for
cipher and hash method implementations.
./configure will attempt to locate OpenSSL in a number of default locations:
/usr/local/ssl /usr/local /usr /usr/local/openssl
If your installation of OpenSSL is in another location, specify it here.
* --with-zlib=[DIR]
If present, libssh2 will attempt to use the zlib (http://www.zlib.org)
for payload compression, however zlib is not required.
./configure will attempt to location a zlib installation in a number of default locations:
/usr/local /usr /usr/local/libz /usr/libz /usr/local/zlib /usr/zlib
If your installation of zlib is in another location, you may specify it here.
* --enable-crypt-none
The SSH2 Transport allows for unencrypted data transmission using the "none" cipher.
Because this is such a huge security hole, it is typically disabled on
SSH2 implementations and is diabled in libssh2 by default as well.
Enabling this option will allow for "none" as a negotiable method,
however it still requires that the method be advertized by the remote end
and that no more-prefferable methods are available.
* --enable-mac-none
The SSH2 Transport also allows implementations to forego a message authentication code.
While this is less of a security risk than using a "none" cipher, it is still not
recommended as disabling MAC hashes removes a layer of security.
Enabling this option will allow for "none" as a negotiable method,
however it still requires that the method be advertized by the remote end
and that no more-prefferable methods are available.
* --disable-gex-new
The diffie-hellman-group-exchange-sha1 (dh-gex) key exchange method originally defined
an exchange negotiation using packet type 30 to request a generation pair based
on a single target value. Later refinement of dh-gex provided for range and target
values. By default libssh2 will use the newer range method.
If you experience trouble connecting to an old SSH server using dh-gex,
try this option to fallback on the older more reliable method.
* Run: make all install

14
Makefile.am Normal file
View File

@@ -0,0 +1,14 @@
SUBDIRS = src example tests docs
include_HEADERS = \
include/libssh2.h \
include/libssh2_publickey.h \
include/libssh2_sftp.h
EXTRA_DIST = win32 buildconf
ACLOCAL_AMFLAGS = -I m4
.PHONY: ChangeLog
ChangeLog:
cvs2cl --utc --fsf --FSF --usermap .cvsusers -I ChangeLog -I .cvs

View File

@@ -1,66 +0,0 @@
subdirs = src/
top_srcdir = @top_srcdir@
prefix = @prefix@
exec_prefix = @exec_prefix@
libdir = @exec_prefix@/lib
incldir = @prefix@/include
distdir = @top_srcdir@/dist
CC = @CC@
CFLAGS = -c @CFLAGS@ -Iinclude/ -Wall -g
LIBS = -lssh2 -Lsrc/
INSTALL = @INSTALL@
VERSION=@PACKAGE_VERSION@
DISTLIB=libssh2-$(VERSION)
all:
@for dir in ${subdirs}; do \
(cd $$dir && $(MAKE) all) \
|| case "$(MFLAGS)" in *k*) fail=yes;; *) exit 1;; esac; \
done && test -z "$$fail"
$(CC) -o ssh2_sample.o ssh2_sample.c $(CFLAGS)
$(CC) -o ssh2_sample ssh2_sample.o $(LIBS)
install:
$(top_srcdir)/mkinstalldirs $(DESTDIR)$(incldir)
$(top_srcdir)/mkinstalldirs $(DESTDIR)$(libdir)
@for dir in ${subdirs}; do \
(cd $$dir && $(MAKE) install) \
|| case "$(MFLAGS)" in *k*) fail=yes;; *) exit 1;; esac; \
done && test -z "$$fail"
$(INSTALL) -m 644 include/libssh2.h $(DESTDIR)$(incldir)/
$(INSTALL) -m 644 include/libssh2_sftp.h $(DESTDIR)$(incldir)/
$(INSTALL) -m 644 include/libssh2_publickey.h $(DESTDIR)$(incldir)/
clean:
@for dir in ${subdirs}; do \
(cd $$dir && $(MAKE) clean) \
|| case "$(MFLAGS)" in *k*) fail=yes;; *) exit 1;; esac; \
done && test -z "$$fail"
rm -f ssh2_sample.o ssh2_sample
dist:
autoheader
autoconf
rm -f $(DISTLIB)
ln -s . $(DISTLIB)
tar -zcf $(DISTLIB).tar.gz \
$(DISTLIB)/configure $(DISTLIB)/Makefile.in $(DISTLIB)/ssh2_sample.c \
$(DISTLIB)/LICENSE $(DISTLIB)/README $(DISTLIB)/INSTALL \
$(DISTLIB)/mkinstalldirs $(DISTLIB)/install-sh $(DISTLIB)/config.sub $(DISTLIB)/config.guess \
$(DISTLIB)/src/*.c $(DISTLIB)/src/Makefile.in \
$(DISTLIB)/include/libssh2.h $(DISTLIB)/include/libssh2_priv.h $(DISTLIB)/include/libssh2_sftp.h \
$(DISTLIB)/include/libssh2_publickey.h $(DISTLIB)/include/libssh2_config.h.in \
$(DISTLIB)/win32/config.mk $(DISTLIB)/win32/libssh2_config.h $(DISTLIB)/win32/rules.mk \
$(DISTLIB)/win32/libssh2.dsp $(DISTLIB)/win32/libssh2.dsw $(DISTLIB)/win32/ssh2_sample.dsp
rm -f $(DISTLIB)
dist_nmake:
autoheader
autoconf
rm -f $(DISTLIB)
ln -s . $(DISTLIB)
tar -zcf $(DISTLIB)-win32.tar.gz \
$(DISTLIB)/NMakefile $(DISTLIB)/ssh2_sample.c $(DISTLIB)/src/*.c \
$(DISTLIB)/LICENSE $(DISTLIB)/README $(DISTLIB)/TODO $(DISTLIB)/INSTALL \
$(DISTLIB)/include/libssh2.h $(DISTLIB)/include/libssh2_priv.h $(DISTLIB)/include/libssh2_sftp.h \
$(DISTLIB)/include/libssh2_publickey.h \
$(DISTLIB)/win32/config.mk $(DISTLIB)/win32/libssh2_config.h $(DISTLIB)/win32/rules.mk
rm -f $(DISTLIB)

280
NEWS Normal file
View File

@@ -0,0 +1,280 @@
Version
------------
Added the following functions for non-blocking operations: (Daniel Stenberg)
libssh2_channel_readnb_ex()
libssh2_channel_writenb_ex()
libssh2_sftp_readnb()
libssh2_sftp_writenb()
Size parameter changed from 'int' to 'unsigned int' in several
public APIs.
Added (a few) man pages in docs/. (Daniel Stenberg)
Maximum SSH packet size is now some 35000 bytes.
Private include files are now in src/ and only public headers are in
include/. (Daniel Stenberg)
Automake and libtool are being used (increased portability). (Daniel
Stenberg)
Fixed OpenSSL detection using pkg-config. (Daniel Stenberg)
Simple self test added to tests/. (Simon Josefsson)
Libgcrypt can now be used instead of OpenSSL if you specify
--with-libgcrypt. (Simon Josefsson)
Fixed a memory leak in the packet handling, and better handle out of
memory situations. (Dan Fandrich)
Made libssh2 build with OpenSSL 0.9.6. (Dan Fandrich)
Improved portability to Solaris related to -lsocket and
-lnsl. (Simon Josefsson)
Clean up of README, INSTALL, NEWS, added ChangeLog. (Simon
Josefsson)
Improve debugging code. Avoids many #ifdef's.
Improved session closing to avoid potentially truncated files on
OpenSSH servers (Dan Fandrich)
Made some function parameters in the API const (Dan Fandrich)
Version 0.14
------------
Plug leaks in EVP cipher init/shutdown. (Selcuk Gueney)
Allow socket_fd == 0 in libssh2_session_startup(). (puudeli)
Swap ordering of packet_add/packet-inspection to avoid inspect after free. (Selcuk)
Swap KEX_INIT ordering, send our KEX_INIT first.
Add check for oportunistic KEX_INIT packets. Burn bad guess if necessary.
Fix OpenSSL detection using pkg-config. (Dan Casey)
Version 0.13
------------
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 `make install' target for MacOSX.
Add terminating NULL character to readlink()/realpath() results.
BugFix#1436593: Apply build options for HPUX targets.
Version 0.12
------------
Added support for publickey subsytem (not the same as publickey auth).
Fix x11_req. Multiple packet_len issues and error handling logic.
(Thanks Simon Hart)
Fix generation of 'e' portion of Diffie-Hellman keyset.
Use appropriate order for BN_rand() rather than fixed group1-specific value.
Re-fixed libssh2_sftp_rename_ex()
Transport had right packet_len, but sftp layer still had extra 4 bytes.
Fixed build with newer OpenSSL headers.
Added extern "C" declarations to libssh2_sftp.h for C++ compatability.
Version 0.11
------------
Added libssh2_chnnale_get_exit_status() -- Mikhail
Added libssh2_channel_wait_closed() -- 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 queueing for small window_adjust packets to avoid unnecessary packet conversation.
Fixed libssh2_sftp_rename_ex() to only send flags parameter if version >= 5 negotiated
(not currently possible, but will be and might as well keep the API consistent).
Version 0.10
------------
Added developer debugging hooks. See --enable-debug-* options to ./configure
Ignore extended data in the SFTP layer. With no other mechanism to deal with that data it'd just fill up and get stuck.
(Re)Fixed channel_write() to provide an opportunity for window space to become available again.
(Re)Fixed SFTP INIT to send the correct SFTP packet length.
Fixed segfault when client and host can't agree on a hostkey/crypt/mac/comp method. (Thanks puudeli)
Fixed major issue with sftp packet buffering mechanism. Using wrong blocking semantics. (No puudeli, YOU the man)
Reduced busy-looping of libssh2_sftp_packet_requirev.
Version 0.9
-----------
Changed blocking_read to only block as much as necessary and not an arbitrary length of time. (Thanks Felix)
Fixed SFTP INIT/VERSION to exclude request_id and send correct maximum version number.
Fixed SFTP to be properly BC with version 1 and 2 servers.
Fixed libssh2_poll() to recognized closed sessions/channels.
Fixed libssh2_channel_write_ex() to fully block when set to blocking mode. Return actual bytes written as well. (Thanks deadem)
Added tests for -lm and -lsocket and add them when necessary.
Added libssh2_channel_window_read_ex() and libssh2_channel_window_write_ex()
for examining the ssh transport windowing states.
Version 0.8
-----------
Fix potential segfault in compression/decompression.
Fix compatability with older versions of OpenSSL
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 libssh2_poll() to check status of sockets/channels/listeners.
Removed unnecessary inclusion of stdio.h (holdover from debugging)
Version 0.7
-----------
Added libssh2_userauth_hostbased_fromfile_ex() for authenticating from hostkey.
Added configure recognition for MacOSX (Darwin) (Thanks Gabe)
Fixed extended data identification in libssh2_channel_read().
Fixed window adjust code. Hadn't acknowledged adjustments correctly.
Removed initial_window_size requirement for sending window adjust packet.
Version 0.6
-----------
Added LIBSSH2_FLAG_SIGPIPE to enable/disable SIGPIPE generated by send()/recv() calls. Default off.
Added libssh2_session_flag() to set optional session flags.
Collapsed exchanging_keys/newkeys/authenticated flags into single state attribute.
Fix zlib compression issue when internal buffer state misses partial sync.
Fix segfault when libssh2_session_methods() is called prior to session_startup().
Fixed client to server channel windowing. Pervent send queue overruns.
Swapped banner send/receive order (send first, then wait for response).
Version 0.5
-----------
*** BC Break ***
Reimplemented libssh2_session_methods() to match libssh2_session_method_pref() style
Fixed libssh2_attr2bin() (effects any setstat style call).
Fixed authenticating with encrypted private key.
Fixed authenticating via ssh-dss public key.
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 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 MAC methods hmac-md5 and hmac-md5-96.
Version 0.4
-----------
Fixed crash when trying to free sftp_dirhandle data from a filehandle struct.
Fixed leak in sftp_open_ex(), handle->handle not freed in handle_close().
Fixed leak in sftp_symlink_ex(), result for READLINK and REALPATH not freed unless there was an error.
Added libssh2_banner_set(), specify an arbitrary banner to send on introduction.
Version 0.3
-----------
Fixed libssh2_channel_read_ex(). Packet loop initialized BEFORE transport polled for new packets (should have been after).
Fixed blocking issues in scp_send()/scp_recv().
Fixed degree of indirection in macerror callback.
Changed packet read mechanism to use a fixed buffer and avoid unnecessary alloc/free calls. (especially while non-block looping)
Added channel close callback.
Added SFTP support (Using its own header file: libssh2_sftp.h)
Version 0.2
-----------
Changed extended data ignorance mechanism:
libssh2_channel_ignore_extended_data() changed to libssh2_channel_handle_extended_data()
Macro introduced for backward compatability during beta phase.
*** THE LIBSSH2_CHANNEL_IGNORE_EXTENDED_DATA() MACRO WILL BE REMOVED PRIOR TO 1.0 RELEASE ***
libssh2_channel_handle_extended_data() may be passed one of three "ignore_mode" constants
LIBSSH2_CHANNEL_EXTENDED_DATA_NONE Default behavior, queue ED packets and return them with read_ex
LIBSSH2_CHANNEL_EXTENDED_DATA_IGNORE Equivalent to libssh2_channel_ignore_extended_data()
IGNORE will implicitly flush the extended data stream(s)
LIBSSH2_CHANNEL_EXTENDED_DATA_MERGE Calls to channel_read() will check both the standard data stream
and the extended data stream(s) for the first available packet
Changed libssh2_session_disconnect_ex() to return an error code when alloc fails
Added libssh2_channel_flush_ex() and basic macros: ..._flush() ..._flush_stderr()
flush_ex accepts either the streamid (0 for standard data, 1 for stderr) or one of the two following constants:
LIBSSH2_CHANNEL_FLUSH_ALL Flush all streams
LIBSSH2_CHANNEL_FLUSH_EXTENDED_DATA Flush all streams EXCEPT the standard data stream
Added libssh2_session_callback_set() for setting ignore/debug/disconnect/macerror callbacks
Added libssh2_session_method_pref() to selectively set methods and method preferences.
Added libssh2_session_methods() to determine what methods were negotiated.
Added libssh2_session_abstract() for retreiving &session->abstract
Added libssh2_session_last_error() for retreiving error codes/messages
Version 0.1
-----------
Initial Release:
KEX methods: diffie-hellman-group14-sha1, diffie-hellman-group-exchange-sha1, diffie-hellman-group1-sha1
Hostkey methods: ssh-rsa, ssh-dss
Cipher methods: aes256-cbc, rijndael-cbc@lysator.liu.se, aes192-cbc, aes128-cbc, blowfish-cbc, arcfour, cast128-cbc, 3des-cbc, none*
Compression methods: zlib, none
MAC methods: hmac-sha1, hmac-sha1-96, hmac-ripemd160, hmac-ripemd160@openssh.com none*
*Cipher/MAC "none" is disabled by default for security purposes,
Use --enable-crypt-none and/or --enable-mac-none with ./configure to enable

251
README
View File

@@ -1,208 +1,99 @@
libssh2 - SSH2 library libssh2 - SSH2 library
====================== ======================
Version 0.12 libssh2 is a library implementing the SSH2 protocol, available under
------------ the revised BSD license.
Added support for publickey subsytem (not the same as publickey auth). Generic installation instructions are in INSTALL. Some ./configure
options deserve additional comments:
Fix x11_req. Multiple packet_len issues and error handling logic. * --enable-crypt-none
(Thanks Simon Hart)
Fix generation of 'e' portion of Diffie-Hellman keyset. The SSH2 Transport allows for unencrypted data
Use appropriate order for BN_rand() rather than fixed group1-specific value. transmission using the "none" cipher. Because this is
such a huge security hole, it is typically disabled on
SSH2 implementations and is disabled in libssh2 by
default as well.
Re-fixed libssh2_sftp_rename_ex() Enabling this option will allow for "none" as a
Transport had right packet_len, but sftp layer still had extra 4 bytes. negotiable method, however it still requires that the
method be advertized by the remote end and that no
more-preferable methods are available.
Fixed build with newer OpenSSL headers. * --enable-mac-none
Added extern "C" declarations to libssh2_sftp.h for C++ compatability. The SSH2 Transport also allows implementations to
forego a message authentication code. While this is
less of a security risk than using a "none" cipher, it
is still not recommended as disabling MAC hashes
removes a layer of security.
Version 0.11 Enabling this option will allow for "none" as a
------------ negotiable method, however it still requires that the
method be advertized by the remote end and that no
more-preferable methods are available.
Added libssh2_chnnale_get_exit_status() -- Mikhail * --disable-gex-new
Added libssh2_channel_wait_closed() -- Mikhail The diffie-hellman-group-exchange-sha1 (dh-gex) key
exchange method originally defined an exchange
negotiation using packet type 30 to request a
generation pair based on a single target value. Later
refinement of dh-gex provided for range and target
values. By default libssh2 will use the newer range
method.
Added libssh2_userauth_keyboard_interactive_ex() -- Mikhail If you experience trouble connecting to an old SSH
server using dh-gex, try this option to fallback on
the older more reliable method.
Added libssh2_channel_receive_window_adjust() to be able to increase the size of the receive window. * --with-libgcrypt
* --with-libgcrypt-prefix=DIR
Added queueing for small window_adjust packets to avoid unnecessary packet conversation. libssh2 can use the Libgcrypt library
(http://www.gnupg.org/) for cryptographic operations.
Fixed libssh2_sftp_rename_ex() to only send flags parameter if version >= 5 negotiated Configure will attempt to locate Libgcrypt in the
(not currently possible, but will be and might as well keep the API consistent). default location, but if you have installed it
somewhere else, use the --with-libgrypt-prefix=DIR
parameter.
Version 0.10 * --with-openssl=[DIR]
------------
Added developer debugging hooks. See --enable-debug-* options to ./configure libssh2 can use the OpenSSL library
(http://www.openssl.org) for cryptographic operations.
Ignore extended data in the SFTP layer. With no other mechanism to deal with that data it'd just fill up and get stuck. Configure will attempt to locate OpenSSL in a number
of default locations:
(Re)Fixed channel_write() to provide an opportunity for window space to become available again. /usr/local/ssl
/usr/local
/usr
/usr/local/openssl
(Re)Fixed SFTP INIT to send the correct SFTP packet length. If your installation of OpenSSL is in another
location, specify it here.
Fixed segfault when client and host can't agree on a hostkey/crypt/mac/comp method. (Thanks puudeli) * --with-libz=[DIR]
Fixed major issue with sftp packet buffering mechanism. Using wrong blocking semantics. (No puudeli, YOU the man) If present, libssh2 will attempt to use the zlib (http://www.zlib.org)
for payload compression, however zlib is not required.
Reduced busy-looping of libssh2_sftp_packet_requirev. Configure will attempt to location a zlib installation
in a number of default locations:
Version 0.9 /usr/local
----------- /usr
/usr/local/libz
/usr/libz
/usr/local/zlib
/usr/zlib
Changed blocking_read to only block as much as necessary and not an arbitrary length of time. (Thanks Felix) If your installation of zlib is in another location,
you may specify it here.
Fixed SFTP INIT/VERSION to exclude request_id and send correct maximum version number. * --enable-debug
Fixed SFTP to be properly BC with version 1 and 2 servers. Will make the build use more pedantic and strict compiler
options as well as enable the libssh2_trace() function (for
Fixed libssh2_poll() to recognized closed sessions/channels. showing debug traces).
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 libssh2_channel_window_read_ex() and libssh2_channel_window_write_ex()
for examining the ssh transport windowing states.
Version 0.8
-----------
Fix potential segfault in compression/decompression.
Fix compatability with older versions of OpenSSL
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 libssh2_poll() to check status of sockets/channels/listeners.
Removed unnecessary inclusion of stdio.h (holdover from debugging)
Version 0.7
-----------
Added libssh2_userauth_hostbased_fromfile_ex() for authenticating from hostkey.
Added configure recognition for MacOSX (Darwin) (Thanks Gabe)
Fixed extended data identification in libssh2_channel_read().
Fixed window adjust code. Hadn't acknowledged adjustments correctly.
Removed initial_window_size requirement for sending window adjust packet.
Version 0.6
-----------
Added LIBSSH2_FLAG_SIGPIPE to enable/disable SIGPIPE generated by send()/recv() calls. Default off.
Added libssh2_session_flag() to set optional session flags.
Collapsed exchanging_keys/newkeys/authenticated flags into single state attribute.
Fix zlib compression issue when internal buffer state misses partial sync.
Fix segfault when libssh2_session_methods() is called prior to session_startup().
Fixed client to server channel windowing. Pervent send queue overruns.
Swapped banner send/receive order (send first, then wait for response).
Version 0.5
-----------
*** BC Break ***
Reimplemented libssh2_session_methods() to match libssh2_session_method_pref() style
Fixed libssh2_attr2bin() (effects any setstat style call).
Fixed authenticating with encrypted private key.
Fixed authenticating via ssh-dss public key.
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 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 MAC methods hmac-md5 and hmac-md5-96.
Version 0.4
-----------
Fixed crash when trying to free sftp_dirhandle data from a filehandle struct.
Fixed leak in sftp_open_ex(), handle->handle not freed in handle_close().
Fixed leak in sftp_symlink_ex(), result for READLINK and REALPATH not freed unless there was an error.
Added libssh2_banner_set(), specify an arbitrary banner to send on introduction.
Version 0.3
-----------
Fixed libssh2_channel_read_ex(). Packet loop initialized BEFORE transport polled for new packets (should have been after).
Fixed blocking issues in scp_send()/scp_recv().
Fixed degree of indirection in macerror callback.
Changed packet read mechanism to use a fixed buffer and avoid unnecessary alloc/free calls. (especially while non-block looping)
Added channel close callback.
Added SFTP support (Using its own header file: libssh2_sftp.h)
Version 0.2
-----------
Changed extended data ignorance mechanism:
libssh2_channel_ignore_extended_data() changed to libssh2_channel_handle_extended_data()
Macro introduced for backward compatability during beta phase.
*** THE LIBSSH2_CHANNEL_IGNORE_EXTENDED_DATA() MACRO WILL BE REMOVED PRIOR TO 1.0 RELEASE ***
libssh2_channel_handle_extended_data() may be passed one of three "ignore_mode" constants
LIBSSH2_CHANNEL_EXTENDED_DATA_NONE Default behavior, queue ED packets and return them with read_ex
LIBSSH2_CHANNEL_EXTENDED_DATA_IGNORE Equivalent to libssh2_channel_ignore_extended_data()
IGNORE will implicitly flush the extended data stream(s)
LIBSSH2_CHANNEL_EXTENDED_DATA_MERGE Calls to channel_read() will check both the standard data stream
and the extended data stream(s) for the first available packet
Changed libssh2_session_disconnect_ex() to return an error code when alloc fails
Added libssh2_channel_flush_ex() and basic macros: ..._flush() ..._flush_stderr()
flush_ex accepts either the streamid (0 for standard data, 1 for stderr) or one of the two following constants:
LIBSSH2_CHANNEL_FLUSH_ALL Flush all streams
LIBSSH2_CHANNEL_FLUSH_EXTENDED_DATA Flush all streams EXCEPT the standard data stream
Added libssh2_session_callback_set() for setting ignore/debug/disconnect/macerror callbacks
Added libssh2_session_method_pref() to selectively set methods and method preferences.
Added libssh2_session_methods() to determine what methods were negotiated.
Added libssh2_session_abstract() for retreiving &session->abstract
Added libssh2_session_last_error() for retreiving error codes/messages
Version 0.1
-----------
Initial Release:
KEX methods: diffie-hellman-group14-sha1, diffie-hellman-group-exchange-sha1, diffie-hellman-group1-sha1
Hostkey methods: ssh-rsa, ssh-dss
Cipher methods: aes256-cbc, rijndael-cbc@lysator.liu.se, aes192-cbc, aes128-cbc, blowfish-cbc, arcfour, cast128-cbc, 3des-cbc, none*
Compression methods: zlib, none
MAC methods: hmac-sha1, hmac-sha1-96, hmac-ripemd160, hmac-ripemd160@openssh.com none*
*Cipher/MAC "none" is disabled by default for security purposes,
Use --enable-crypt-none and/or --enable-mac-none with ./configure to enable

290
acinclude.m4 Normal file
View File

@@ -0,0 +1,290 @@
dnl **********************************************************************
dnl CURL_DETECT_ICC ([ACTION-IF-YES])
dnl
dnl check if this is the Intel ICC compiler, and if so run the ACTION-IF-YES
dnl sets the $ICC variable to "yes" or "no"
dnl **********************************************************************
AC_DEFUN([CURL_DETECT_ICC],
[
ICC="no"
AC_MSG_CHECKING([for icc in use])
if test "$GCC" = "yes"; then
dnl check if this is icc acting as gcc in disguise
AC_EGREP_CPP([^__INTEL_COMPILER], [__INTEL_COMPILER],
dnl action if the text is found, this it has not been replaced by the
dnl cpp
ICC="no",
dnl the text was not found, it was replaced by the cpp
ICC="yes"
AC_MSG_RESULT([yes])
[$1]
)
fi
if test "$ICC" = "no"; then
# this is not ICC
AC_MSG_RESULT([no])
fi
])
dnl We create a function for detecting which compiler we use and then set as
dnl pendantic compiler options as possible for that particular compiler. The
dnl options are only used for debug-builds.
AC_DEFUN([CURL_CC_DEBUG_OPTS],
[
if test "z$ICC" = "z"; then
CURL_DETECT_ICC
fi
if test "$GCC" = "yes"; then
dnl figure out gcc version!
AC_MSG_CHECKING([gcc version])
gccver=`$CC -dumpversion`
num1=`echo $gccver | cut -d . -f1`
num2=`echo $gccver | cut -d . -f2`
gccnum=`(expr $num1 "*" 100 + $num2) 2>/dev/null`
AC_MSG_RESULT($gccver)
if test "$ICC" = "yes"; then
dnl this is icc, not gcc.
dnl ICC warnings we ignore:
dnl * 269 warns on our "%Od" printf formatters for curl_off_t output:
dnl "invalid format string conversion"
dnl * 279 warns on static conditions in while expressions
dnl * 981 warns on "operands are evaluated in unspecified order"
dnl * 1418 "external definition with no prior declaration"
dnl * 1419 warns on "external declaration in primary source file"
dnl which we know and do on purpose.
WARN="-wd279,269,981,1418,1419"
if test "$gccnum" -gt "600"; then
dnl icc 6.0 and older doesn't have the -Wall flag
WARN="-Wall $WARN"
fi
else dnl $ICC = yes
dnl this is a set of options we believe *ALL* gcc versions support:
WARN="-W -Wall -Wwrite-strings -pedantic -Wpointer-arith -Wnested-externs -Winline -Wmissing-prototypes"
dnl -Wcast-align is a bit too annoying on all gcc versions ;-)
if test "$gccnum" -ge "207"; then
dnl gcc 2.7 or later
WARN="$WARN -Wmissing-declarations"
fi
if test "$gccnum" -gt "295"; then
dnl only if the compiler is newer than 2.95 since we got lots of
dnl "`_POSIX_C_SOURCE' is not defined" in system headers with
dnl gcc 2.95.4 on FreeBSD 4.9!
WARN="$WARN -Wundef -Wno-long-long -Wsign-compare"
fi
if test "$gccnum" -ge "296"; then
dnl gcc 2.96 or later
WARN="$WARN -Wfloat-equal"
fi
if test "$gccnum" -gt "296"; then
dnl this option does not exist in 2.96
WARN="$WARN -Wno-format-nonliteral"
fi
dnl -Wunreachable-code seems totally unreliable on my gcc 3.3.2 on
dnl on i686-Linux as it gives us heaps with false positives.
dnl Also, on gcc 4.0.X it is totally unbearable and complains all
dnl over making it unusable for generic purposes. Let's not use it.
if test "$gccnum" -ge "303"; then
dnl gcc 3.3 and later
WARN="$WARN -Wendif-labels -Wstrict-prototypes"
fi
if test "$gccnum" -ge "304"; then
# try these on gcc 3.4
WARN="$WARN -Wdeclaration-after-statement"
fi
for flag in $CPPFLAGS; do
case "$flag" in
-I*)
dnl Include path, provide a -isystem option for the same dir
dnl to prevent warnings in those dirs. The -isystem was not very
dnl reliable on earlier gcc versions.
add=`echo $flag | sed 's/^-I/-isystem /g'`
WARN="$WARN $add"
;;
esac
done
fi dnl $ICC = no
CFLAGS="$CFLAGS $WARN"
AC_MSG_NOTICE([Added this set of compiler options: $WARN])
else dnl $GCC = yes
AC_MSG_NOTICE([Added no extra compiler options])
fi dnl $GCC = yes
dnl strip off optimizer flags
NEWFLAGS=""
for flag in $CFLAGS; do
case "$flag" in
-O*)
dnl echo "cut off $flag"
;;
*)
NEWFLAGS="$NEWFLAGS $flag"
;;
esac
done
CFLAGS=$NEWFLAGS
]) dnl end of AC_DEFUN()
dnl CURL_CHECK_NONBLOCKING_SOCKET
dnl -------------------------------------------------
dnl Check for how to set a socket to non-blocking state. There seems to exist
dnl four known different ways, with the one used almost everywhere being POSIX
dnl and XPG3, while the other different ways for different systems (old BSD,
dnl Windows and Amiga).
dnl
dnl There are two known platforms (AIX 3.x and SunOS 4.1.x) where the
dnl O_NONBLOCK define is found but does not work. This condition is attempted
dnl to get caught in this script by using an excessive number of #ifdefs...
dnl
AC_DEFUN([CURL_CHECK_NONBLOCKING_SOCKET],
[
AC_MSG_CHECKING([non-blocking sockets style])
AC_TRY_COMPILE([
/* headers for O_NONBLOCK test */
#include <sys/types.h>
#include <unistd.h>
#include <fcntl.h>
],[
/* try to compile O_NONBLOCK */
#if defined(sun) || defined(__sun__) || defined(__SUNPRO_C) || defined(__SUNPRO_CC)
# if defined(__SVR4) || defined(__srv4__)
# define PLATFORM_SOLARIS
# else
# define PLATFORM_SUNOS4
# endif
#endif
#if (defined(_AIX) || defined(__xlC__)) && !defined(_AIX4)
# define PLATFORM_AIX_V3
#endif
#if defined(PLATFORM_SUNOS4) || defined(PLATFORM_AIX_V3) || defined(__BEOS__)
#error "O_NONBLOCK does not work on this platform"
#endif
int socket;
int flags = fcntl(socket, F_SETFL, flags | O_NONBLOCK);
],[
dnl the O_NONBLOCK test was fine
nonblock="O_NONBLOCK"
AC_DEFINE(HAVE_O_NONBLOCK, 1, [use O_NONBLOCK for non-blocking sockets])
],[
dnl the code was bad, try a different program now, test 2
AC_TRY_COMPILE([
/* headers for FIONBIO test */
#include <unistd.h>
#include <stropts.h>
],[
/* FIONBIO source test (old-style unix) */
int socket;
int flags = ioctl(socket, FIONBIO, &flags);
],[
dnl FIONBIO test was good
nonblock="FIONBIO"
AC_DEFINE(HAVE_FIONBIO, 1, [use FIONBIO for non-blocking sockets])
],[
dnl FIONBIO test was also bad
dnl the code was bad, try a different program now, test 3
AC_TRY_COMPILE([
/* headers for ioctlsocket test (Windows) */
#undef inline
#ifdef HAVE_WINDOWS_H
#ifndef WIN32_LEAN_AND_MEAN
#define WIN32_LEAN_AND_MEAN
#endif
#include <windows.h>
#ifdef HAVE_WINSOCK2_H
#include <winsock2.h>
#else
#ifdef HAVE_WINSOCK_H
#include <winsock.h>
#endif
#endif
#endif
],[
/* ioctlsocket source code */
SOCKET sd;
unsigned long flags = 0;
sd = socket(0, 0, 0);
ioctlsocket(sd, FIONBIO, &flags);
],[
dnl ioctlsocket test was good
nonblock="ioctlsocket"
AC_DEFINE(HAVE_IOCTLSOCKET, 1, [use ioctlsocket() for non-blocking sockets])
],[
dnl ioctlsocket didnt compile!, go to test 4
AC_TRY_LINK([
/* headers for IoctlSocket test (Amiga?) */
#include <sys/ioctl.h>
],[
/* IoctlSocket source code */
int socket;
int flags = IoctlSocket(socket, FIONBIO, (long)1);
],[
dnl ioctlsocket test was good
nonblock="IoctlSocket"
AC_DEFINE(HAVE_IOCTLSOCKET_CASE, 1, [use Ioctlsocket() for non-blocking sockets])
],[
dnl Ioctlsocket didnt compile, do test 5!
AC_TRY_COMPILE([
/* headers for SO_NONBLOCK test (BeOS) */
#include <socket.h>
],[
/* SO_NONBLOCK source code */
long b = 1;
int socket;
int flags = setsockopt(socket, SOL_SOCKET, SO_NONBLOCK, &b, sizeof(b));
],[
dnl the SO_NONBLOCK test was good
nonblock="SO_NONBLOCK"
AC_DEFINE(HAVE_SO_NONBLOCK, 1, [use SO_NONBLOCK for non-blocking sockets])
],[
dnl test 5 didnt compile!
nonblock="nada"
AC_DEFINE(HAVE_DISABLED_NONBLOCKING, 1, [disabled non-blocking sockets])
])
dnl end of fifth test
])
dnl end of forth test
])
dnl end of third test
])
dnl end of second test
])
dnl end of non-blocking try-compile test
AC_MSG_RESULT($nonblock)
if test "$nonblock" = "nada"; then
AC_MSG_WARN([non-block sockets disabled])
fi
])

7
buildconf Executable file
View File

@@ -0,0 +1,7 @@
#!/bin/sh
${LIBTOOLIZE:-libtoolize} --copy --automake --force
${ACLOCAL:-aclocal} -I m4 $ACLOCAL_FLAGS
${AUTOHEADER:-autoheader}
${AUTOCONF:-autoconf}
${AUTOMAKE:-automake} --add-missing --copy

1415
config.guess vendored

File diff suppressed because it is too large Load Diff

660
config.rpath Executable file
View File

@@ -0,0 +1,660 @@
#! /bin/sh
# Output a system dependent set of variables, describing how to set the
# run time search path of shared libraries in an executable.
#
# Copyright 1996-2006 Free Software Foundation, Inc.
# Taken from GNU libtool, 2001
# Originally by Gordon Matzigkeit <gord@gnu.ai.mit.edu>, 1996
#
# This file is free software; the Free Software Foundation gives
# unlimited permission to copy and/or distribute it, with or without
# modifications, as long as this notice is preserved.
#
# The first argument passed to this file is the canonical host specification,
# CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM
# or
# CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM
# The environment variables CC, GCC, LDFLAGS, LD, with_gnu_ld
# should be set by the caller.
#
# The set of defined variables is at the end of this script.
# Known limitations:
# - On IRIX 6.5 with CC="cc", the run time search patch must not be longer
# than 256 bytes, otherwise the compiler driver will dump core. The only
# known workaround is to choose shorter directory names for the build
# directory and/or the installation directory.
# All known linkers require a `.a' archive for static linking (except MSVC,
# which needs '.lib').
libext=a
shrext=.so
host="$1"
host_cpu=`echo "$host" | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\1/'`
host_vendor=`echo "$host" | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\2/'`
host_os=`echo "$host" | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\3/'`
# Code taken from libtool.m4's _LT_CC_BASENAME.
for cc_temp in $CC""; do
case $cc_temp in
compile | *[\\/]compile | ccache | *[\\/]ccache ) ;;
distcc | *[\\/]distcc | purify | *[\\/]purify ) ;;
\-*) ;;
*) break;;
esac
done
cc_basename=`echo "$cc_temp" | sed -e 's%^.*/%%'`
# Code taken from libtool.m4's AC_LIBTOOL_PROG_COMPILER_PIC.
wl=
if test "$GCC" = yes; then
wl='-Wl,'
else
case "$host_os" in
aix*)
wl='-Wl,'
;;
darwin*)
case $cc_basename in
xlc*)
wl='-Wl,'
;;
esac
;;
mingw* | pw32* | os2*)
;;
hpux9* | hpux10* | hpux11*)
wl='-Wl,'
;;
irix5* | irix6* | nonstopux*)
wl='-Wl,'
;;
newsos6)
;;
linux*)
case $cc_basename in
icc* | ecc*)
wl='-Wl,'
;;
pgcc | pgf77 | pgf90)
wl='-Wl,'
;;
ccc*)
wl='-Wl,'
;;
como)
wl='-lopt='
;;
*)
case `$CC -V 2>&1 | sed 5q` in
*Sun\ C*)
wl='-Wl,'
;;
esac
;;
esac
;;
osf3* | osf4* | osf5*)
wl='-Wl,'
;;
sco3.2v5*)
;;
solaris*)
wl='-Wl,'
;;
sunos4*)
wl='-Qoption ld '
;;
sysv4 | sysv4.2uw2* | sysv4.3* | sysv5*)
wl='-Wl,'
;;
sysv4*MP*)
;;
unicos*)
wl='-Wl,'
;;
uts4*)
;;
esac
fi
# Code taken from libtool.m4's AC_LIBTOOL_PROG_LD_SHLIBS.
hardcode_libdir_flag_spec=
hardcode_libdir_separator=
hardcode_direct=no
hardcode_minus_L=no
case "$host_os" in
cygwin* | mingw* | pw32*)
# FIXME: the MSVC++ port hasn't been tested in a loooong time
# When not using gcc, we currently assume that we are using
# Microsoft Visual C++.
if test "$GCC" != yes; then
with_gnu_ld=no
fi
;;
interix*)
# we just hope/assume this is gcc and not c89 (= MSVC++)
with_gnu_ld=yes
;;
openbsd*)
with_gnu_ld=no
;;
esac
ld_shlibs=yes
if test "$with_gnu_ld" = yes; then
# Set some defaults for GNU ld with shared library support. These
# are reset later if shared libraries are not supported. Putting them
# here allows them to be overridden if necessary.
# Unlike libtool, we use -rpath here, not --rpath, since the documented
# option of GNU ld is called -rpath, not --rpath.
hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir'
case "$host_os" in
aix3* | aix4* | aix5*)
# On AIX/PPC, the GNU linker is very broken
if test "$host_cpu" != ia64; then
ld_shlibs=no
fi
;;
amigaos*)
hardcode_libdir_flag_spec='-L$libdir'
hardcode_minus_L=yes
# Samuel A. Falvo II <kc5tja@dolphin.openprojects.net> reports
# that the semantics of dynamic libraries on AmigaOS, at least up
# to version 4, is to share data among multiple programs linked
# with the same dynamic library. Since this doesn't match the
# behavior of shared libraries on other platforms, we cannot use
# them.
ld_shlibs=no
;;
beos*)
if $LD --help 2>&1 | grep ': supported targets:.* elf' > /dev/null; then
:
else
ld_shlibs=no
fi
;;
cygwin* | mingw* | pw32*)
# hardcode_libdir_flag_spec is actually meaningless, as there is
# no search path for DLLs.
hardcode_libdir_flag_spec='-L$libdir'
if $LD --help 2>&1 | grep 'auto-import' > /dev/null; then
:
else
ld_shlibs=no
fi
;;
interix3*)
hardcode_direct=no
hardcode_libdir_flag_spec='${wl}-rpath,$libdir'
;;
linux*)
if $LD --help 2>&1 | grep ': supported targets:.* elf' > /dev/null; then
:
else
ld_shlibs=no
fi
;;
netbsd*)
;;
solaris*)
if $LD -v 2>&1 | grep 'BFD 2\.8' > /dev/null; then
ld_shlibs=no
elif $LD --help 2>&1 | grep ': supported targets:.* elf' > /dev/null; then
:
else
ld_shlibs=no
fi
;;
sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX*)
case `$LD -v 2>&1` in
*\ [01].* | *\ 2.[0-9].* | *\ 2.1[0-5].*)
ld_shlibs=no
;;
*)
if $LD --help 2>&1 | grep ': supported targets:.* elf' > /dev/null; then
hardcode_libdir_flag_spec='`test -z "$SCOABSPATH" && echo ${wl}-rpath,$libdir`'
else
ld_shlibs=no
fi
;;
esac
;;
sunos4*)
hardcode_direct=yes
;;
*)
if $LD --help 2>&1 | grep ': supported targets:.* elf' > /dev/null; then
:
else
ld_shlibs=no
fi
;;
esac
if test "$ld_shlibs" = no; then
hardcode_libdir_flag_spec=
fi
else
case "$host_os" in
aix3*)
# Note: this linker hardcodes the directories in LIBPATH if there
# are no directories specified by -L.
hardcode_minus_L=yes
if test "$GCC" = yes; then
# Neither direct hardcoding nor static linking is supported with a
# broken collect2.
hardcode_direct=unsupported
fi
;;
aix4* | aix5*)
if test "$host_cpu" = ia64; then
# On IA64, the linker does run time linking by default, so we don't
# have to do anything special.
aix_use_runtimelinking=no
else
aix_use_runtimelinking=no
# Test if we are trying to use run time linking or normal
# AIX style linking. If -brtl is somewhere in LDFLAGS, we
# need to do runtime linking.
case $host_os in aix4.[23]|aix4.[23].*|aix5*)
for ld_flag in $LDFLAGS; do
if (test $ld_flag = "-brtl" || test $ld_flag = "-Wl,-brtl"); then
aix_use_runtimelinking=yes
break
fi
done
;;
esac
fi
hardcode_direct=yes
hardcode_libdir_separator=':'
if test "$GCC" = yes; then
case $host_os in aix4.[012]|aix4.[012].*)
collect2name=`${CC} -print-prog-name=collect2`
if test -f "$collect2name" && \
strings "$collect2name" | grep resolve_lib_name >/dev/null
then
# We have reworked collect2
hardcode_direct=yes
else
# We have old collect2
hardcode_direct=unsupported
hardcode_minus_L=yes
hardcode_libdir_flag_spec='-L$libdir'
hardcode_libdir_separator=
fi
;;
esac
fi
# Begin _LT_AC_SYS_LIBPATH_AIX.
echo 'int main () { return 0; }' > conftest.c
${CC} ${LDFLAGS} conftest.c -o conftest
aix_libpath=`dump -H conftest 2>/dev/null | sed -n -e '/Import File Strings/,/^$/ { /^0/ { s/^0 *\(.*\)$/\1/; p; }
}'`
if test -z "$aix_libpath"; then
aix_libpath=`dump -HX64 conftest 2>/dev/null | sed -n -e '/Import File Strings/,/^$/ { /^0/ { s/^0 *\(.*\)$/\1/; p; }
}'`
fi
if test -z "$aix_libpath"; then
aix_libpath="/usr/lib:/lib"
fi
rm -f conftest.c conftest
# End _LT_AC_SYS_LIBPATH_AIX.
if test "$aix_use_runtimelinking" = yes; then
hardcode_libdir_flag_spec='${wl}-blibpath:$libdir:'"$aix_libpath"
else
if test "$host_cpu" = ia64; then
hardcode_libdir_flag_spec='${wl}-R $libdir:/usr/lib:/lib'
else
hardcode_libdir_flag_spec='${wl}-blibpath:$libdir:'"$aix_libpath"
fi
fi
;;
amigaos*)
hardcode_libdir_flag_spec='-L$libdir'
hardcode_minus_L=yes
# see comment about different semantics on the GNU ld section
ld_shlibs=no
;;
bsdi[45]*)
;;
cygwin* | mingw* | pw32*)
# When not using gcc, we currently assume that we are using
# Microsoft Visual C++.
# hardcode_libdir_flag_spec is actually meaningless, as there is
# no search path for DLLs.
hardcode_libdir_flag_spec=' '
libext=lib
;;
darwin* | rhapsody*)
hardcode_direct=no
if test "$GCC" = yes ; then
:
else
case $cc_basename in
xlc*)
;;
*)
ld_shlibs=no
;;
esac
fi
;;
dgux*)
hardcode_libdir_flag_spec='-L$libdir'
;;
freebsd1*)
ld_shlibs=no
;;
freebsd2.2*)
hardcode_libdir_flag_spec='-R$libdir'
hardcode_direct=yes
;;
freebsd2*)
hardcode_direct=yes
hardcode_minus_L=yes
;;
freebsd* | kfreebsd*-gnu | dragonfly*)
hardcode_libdir_flag_spec='-R$libdir'
hardcode_direct=yes
;;
hpux9*)
hardcode_libdir_flag_spec='${wl}+b ${wl}$libdir'
hardcode_libdir_separator=:
hardcode_direct=yes
# hardcode_minus_L: Not really in the search PATH,
# but as the default location of the library.
hardcode_minus_L=yes
;;
hpux10*)
if test "$with_gnu_ld" = no; then
hardcode_libdir_flag_spec='${wl}+b ${wl}$libdir'
hardcode_libdir_separator=:
hardcode_direct=yes
# hardcode_minus_L: Not really in the search PATH,
# but as the default location of the library.
hardcode_minus_L=yes
fi
;;
hpux11*)
if test "$with_gnu_ld" = no; then
hardcode_libdir_flag_spec='${wl}+b ${wl}$libdir'
hardcode_libdir_separator=:
case $host_cpu in
hppa*64*|ia64*)
hardcode_direct=no
;;
*)
hardcode_direct=yes
# hardcode_minus_L: Not really in the search PATH,
# but as the default location of the library.
hardcode_minus_L=yes
;;
esac
fi
;;
irix5* | irix6* | nonstopux*)
hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir'
hardcode_libdir_separator=:
;;
netbsd*)
hardcode_libdir_flag_spec='-R$libdir'
hardcode_direct=yes
;;
newsos6)
hardcode_direct=yes
hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir'
hardcode_libdir_separator=:
;;
openbsd*)
hardcode_direct=yes
if test -z "`echo __ELF__ | $CC -E - | grep __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then
hardcode_libdir_flag_spec='${wl}-rpath,$libdir'
else
case "$host_os" in
openbsd[01].* | openbsd2.[0-7] | openbsd2.[0-7].*)
hardcode_libdir_flag_spec='-R$libdir'
;;
*)
hardcode_libdir_flag_spec='${wl}-rpath,$libdir'
;;
esac
fi
;;
os2*)
hardcode_libdir_flag_spec='-L$libdir'
hardcode_minus_L=yes
;;
osf3*)
hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir'
hardcode_libdir_separator=:
;;
osf4* | osf5*)
if test "$GCC" = yes; then
hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir'
else
# Both cc and cxx compiler support -rpath directly
hardcode_libdir_flag_spec='-rpath $libdir'
fi
hardcode_libdir_separator=:
;;
solaris*)
hardcode_libdir_flag_spec='-R$libdir'
;;
sunos4*)
hardcode_libdir_flag_spec='-L$libdir'
hardcode_direct=yes
hardcode_minus_L=yes
;;
sysv4)
case $host_vendor in
sni)
hardcode_direct=yes # is this really true???
;;
siemens)
hardcode_direct=no
;;
motorola)
hardcode_direct=no #Motorola manual says yes, but my tests say they lie
;;
esac
;;
sysv4.3*)
;;
sysv4*MP*)
if test -d /usr/nec; then
ld_shlibs=yes
fi
;;
sysv4*uw2* | sysv5OpenUNIX* | sysv5UnixWare7.[01].[10]* | unixware7*)
;;
sysv5* | sco3.2v5* | sco5v6*)
hardcode_libdir_flag_spec='`test -z "$SCOABSPATH" && echo ${wl}-R,$libdir`'
hardcode_libdir_separator=':'
;;
uts4*)
hardcode_libdir_flag_spec='-L$libdir'
;;
*)
ld_shlibs=no
;;
esac
fi
# Check dynamic linker characteristics
# Code taken from libtool.m4's AC_LIBTOOL_SYS_DYNAMIC_LINKER.
# Unlike libtool.m4, here we don't care about _all_ names of the library, but
# only about the one the linker finds when passed -lNAME. This is the last
# element of library_names_spec in libtool.m4, or possibly two of them if the
# linker has special search rules.
library_names_spec= # the last element of library_names_spec in libtool.m4
libname_spec='lib$name'
case "$host_os" in
aix3*)
library_names_spec='$libname.a'
;;
aix4* | aix5*)
library_names_spec='$libname$shrext'
;;
amigaos*)
library_names_spec='$libname.a'
;;
beos*)
library_names_spec='$libname$shrext'
;;
bsdi[45]*)
library_names_spec='$libname$shrext'
;;
cygwin* | mingw* | pw32*)
shrext=.dll
library_names_spec='$libname.dll.a $libname.lib'
;;
darwin* | rhapsody*)
shrext=.dylib
library_names_spec='$libname$shrext'
;;
dgux*)
library_names_spec='$libname$shrext'
;;
freebsd1*)
;;
kfreebsd*-gnu)
library_names_spec='$libname$shrext'
;;
freebsd* | dragonfly*)
case "$host_os" in
freebsd[123]*)
library_names_spec='$libname$shrext$versuffix' ;;
*)
library_names_spec='$libname$shrext' ;;
esac
;;
gnu*)
library_names_spec='$libname$shrext'
;;
hpux9* | hpux10* | hpux11*)
case $host_cpu in
ia64*)
shrext=.so
;;
hppa*64*)
shrext=.sl
;;
*)
shrext=.sl
;;
esac
library_names_spec='$libname$shrext'
;;
interix3*)
library_names_spec='$libname$shrext'
;;
irix5* | irix6* | nonstopux*)
library_names_spec='$libname$shrext'
case "$host_os" in
irix5* | nonstopux*)
libsuff= shlibsuff=
;;
*)
case $LD in
*-32|*"-32 "|*-melf32bsmip|*"-melf32bsmip ") libsuff= shlibsuff= ;;
*-n32|*"-n32 "|*-melf32bmipn32|*"-melf32bmipn32 ") libsuff=32 shlibsuff=N32 ;;
*-64|*"-64 "|*-melf64bmip|*"-melf64bmip ") libsuff=64 shlibsuff=64 ;;
*) libsuff= shlibsuff= ;;
esac
;;
esac
;;
linux*oldld* | linux*aout* | linux*coff*)
;;
linux*)
library_names_spec='$libname$shrext'
;;
knetbsd*-gnu)
library_names_spec='$libname$shrext'
;;
netbsd*)
library_names_spec='$libname$shrext'
;;
newsos6)
library_names_spec='$libname$shrext'
;;
nto-qnx*)
library_names_spec='$libname$shrext'
;;
openbsd*)
library_names_spec='$libname$shrext$versuffix'
;;
os2*)
libname_spec='$name'
shrext=.dll
library_names_spec='$libname.a'
;;
osf3* | osf4* | osf5*)
library_names_spec='$libname$shrext'
;;
solaris*)
library_names_spec='$libname$shrext'
;;
sunos4*)
library_names_spec='$libname$shrext$versuffix'
;;
sysv4 | sysv4.3*)
library_names_spec='$libname$shrext'
;;
sysv4*MP*)
library_names_spec='$libname$shrext'
;;
sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX* | sysv4*uw2*)
library_names_spec='$libname$shrext'
;;
uts4*)
library_names_spec='$libname$shrext'
;;
esac
sed_quote_subst='s/\(["`$\\]\)/\\\1/g'
escaped_wl=`echo "X$wl" | sed -e 's/^X//' -e "$sed_quote_subst"`
shlibext=`echo "$shrext" | sed -e 's,^\.,,'`
escaped_libname_spec=`echo "X$libname_spec" | sed -e 's/^X//' -e "$sed_quote_subst"`
escaped_library_names_spec=`echo "X$library_names_spec" | sed -e 's/^X//' -e "$sed_quote_subst"`
escaped_hardcode_libdir_flag_spec=`echo "X$hardcode_libdir_flag_spec" | sed -e 's/^X//' -e "$sed_quote_subst"`
LC_ALL=C sed -e 's/^\([a-zA-Z0-9_]*\)=/acl_cv_\1=/' <<EOF
# How to pass a linker flag through the compiler.
wl="$escaped_wl"
# Static library suffix (normally "a").
libext="$libext"
# Shared library suffix (normally "so").
shlibext="$shlibext"
# Format of library name prefix.
libname_spec="$escaped_libname_spec"
# Library names that the linker finds when passed -lNAME.
library_names_spec="$escaped_library_names_spec"
# Flag to hardcode \$libdir into a binary during linking.
# This must work even if \$libdir does not exist.
hardcode_libdir_flag_spec="$escaped_hardcode_libdir_flag_spec"
# Whether we need a single -rpath flag with a separated argument.
hardcode_libdir_separator="$hardcode_libdir_separator"
# Set to yes if using DIR/libNAME.so during linking hardcodes DIR into the
# resulting binary.
hardcode_direct="$hardcode_direct"
# Set to yes if using the -LDIR flag during linking hardcodes DIR into the
# resulting binary.
hardcode_minus_L="$hardcode_minus_L"
EOF

1510
config.sub vendored

File diff suppressed because it is too large Load Diff

View File

@@ -1,48 +1,65 @@
# AC_PREREQ(2.57) # AC_PREREQ(2.57)
AC_INIT(libssh2,0.12,sarag@libssh2.org) AC_INIT(libssh2, 0.15, libssh2-devel@lists.sourceforge.net)
AM_INIT_AUTOMAKE(libssh2, 0.15)
AC_CONFIG_SRCDIR([src]) AC_CONFIG_SRCDIR([src])
AC_CONFIG_HEADER([include/libssh2_config.h]) AC_CONFIG_HEADER([src/libssh2_config.h])
AB_INIT
# Check for the OS. # Check for the OS.
# Daniel's note: this should not be necessary and we need to work to
# get this removed.
AC_CANONICAL_HOST AC_CANONICAL_HOST
case "$host" in case "$host" in
*-cygwin) *-cygwin)
SHLIB_SUFFIX_NAME="dll"
SHLIB_LDFLAGS="-shared"
CFLAGS="$CFLAGS -DLIBSSH2_WIN32" CFLAGS="$CFLAGS -DLIBSSH2_WIN32"
;; ;;
*darwin*) *darwin*)
SHLIB_SUFFIX_NAME="dylib"
SHLIB_LDFLAGS="-dynamiclib -flat_namespace"
CFLAGS="$CFLAGS -DLIBSSH2_DARWIN" CFLAGS="$CFLAGS -DLIBSSH2_DARWIN"
;; ;;
*hpux*)
;;
*) *)
SHLIB_SUFFIX_NAME="so"
SHLIB_LDFLAGS="-shared"
;; ;;
esac esac
AC_CHECK_LIB(socket, socket, [ # Some systems (Solaris?) have socket() in -lsocket.
SHLIB_LDFLAGS="$SHLIB_LDFLAGS -lsocket" AC_SEARCH_LIBS(socket, socket)
LIBS="$LIBS -lsocket"
])
AC_CHECK_LIB(m, ceil, [ SHLIB_LDFLAGS="$SHLIB_LDFLAGS -lm" ])
# Solaris has inet_addr() in -lnsl.
AC_SEARCH_LIBS(inet_addr, nsl)
AC_SUBST(SHLIB_SUFFIX_NAME)
AC_SUBST(SHLIB_LDFLAGS)
AC_SUBST(LIBS) AC_SUBST(LIBS)
AC_PROG_CC AC_PROG_CC
AC_PROG_INSTALL AC_PROG_INSTALL
AC_PROG_LN_S AC_PROG_LN_S
AC_PROG_MAKE_SET AC_PROG_MAKE_SET
AC_PROG_RANLIB AC_PROG_LIBTOOL
AC_C_BIGENDIAN AC_C_BIGENDIAN
if test -z "$PKG_CONFIG"; then if test -z "$PKG_CONFIG"; then
AC_PATH_PROG(PKG_CONFIG, pkg-config, no) AC_PATH_PROG(PKG_CONFIG, pkg-config, no)
fi fi
# Look for libgcrypt.
AC_ARG_WITH(libgcrypt,
AC_HELP_STRING([--with-libgcrypt],[Use libgcrypt for crypto]),
use_libgcrypt=$withval,use_libgcrypt=no)
if test "$use_libgcrypt" != "no"; then
AC_LIB_HAVE_LINKFLAGS([gcrypt], [], [#include <gcrypt.h>])
fi
if test "$ac_cv_libgcrypt" = yes; then
use_libgcrypt=yes
AC_DEFINE(LIBSSH2_LIBGCRYPT, 1, [Use libgcrypt])
fi
AM_CONDITIONAL(LIBGCRYPT, test "$use_libgcrypt" != "no")
# Need to define SHLIB_SUFFIX_NAME before checking for libcrypt and libz
# $shrext_cmds (from libtool) can contain commands so it must be eval'd
# Simon's note: replace the find-openssl/libz logic with Bruno's
# AC_LIB_LINKFLAGS which is more portable and flexible.
eval SHLIB_SUFFIX_NAME=\"$shrext_cmds\"
AC_SUBST(SHLIB_SUFFIX_NAME)
# #
# Look for OpenSSL # Look for OpenSSL
# #
@@ -50,20 +67,25 @@ AC_ARG_WITH(openssl,
AC_HELP_STRING([--with-openssl=DIR],[Look for OpenSSL in PATH]), AC_HELP_STRING([--with-openssl=DIR],[Look for OpenSSL in PATH]),
[LIBSSH2_OPENSSL_DIR=$withval],[LIBSSH2_OPENSSL_DIR=yes]) [LIBSSH2_OPENSSL_DIR=$withval],[LIBSSH2_OPENSSL_DIR=yes])
if test "$use_libgcrypt" = "no"; then
if test "$LIBSSH2_OPENSSL_DIR" = "no" || test "$LIBSSH2_OPENSSL_DIR" = "yes"; then if test "$LIBSSH2_OPENSSL_DIR" = "no" || test "$LIBSSH2_OPENSSL_DIR" = "yes"; then
unset LIBSSH2_OPENSSL_DIR unset LIBSSH2_OPENSSL_DIR
fi fi
found_openssl=no found_openssl=no
pkgcfg_openssl=no
unset OPENSSL_INCDIR unset OPENSSL_INCDIR
unset OPENSSL_LIBDIR unset OPENSSL_INCLINE
unset OPENSSL_LIBLINE
AC_MSG_CHECKING([for OpenSSL]) AC_MSG_CHECKING([for OpenSSL])
# Explicit path given, use it rather than pkg-config # Explicit path given, use it rather than pkg-config
if test ! -z "$LIBSSH2_OPENSSL_DIR"; then if test ! -z "$LIBSSH2_OPENSSL_DIR"; then
found_openssl=yes found_openssl=yes
OPENSSL_LIBDIR=$LIBSSH2_OPENSSL_DIR/lib OPENSSL_LIBLINE="-L$LIBSSH2_OPENSSL_DIR/lib -lcrypto"
OPENSSL_INCLINE="-I$LIBSSH2_OPENSSL_DIR/include"
OPENSSL_INCDIR=$LIBSSH2_OPENSSL_DIR/include OPENSSL_INCDIR=$LIBSSH2_OPENSSL_DIR/include
AC_MSG_RESULT([Using explicit path $LIBSSH2_OPENSSL_DIR]) AC_MSG_RESULT([Using explicit path $LIBSSH2_OPENSSL_DIR])
fi fi
@@ -71,8 +93,9 @@ fi
# If pkg-config is found try using it # If pkg-config is found try using it
if test "$found_openssl" = "no" && test -x "$PKG_CONFIG" && $PKG_CONFIG --exists openssl; then if test "$found_openssl" = "no" && test -x "$PKG_CONFIG" && $PKG_CONFIG --exists openssl; then
found_openssl=yes found_openssl=yes
OPENSSL_LIBDIR=`$PKG_CONFIG --libs openssl` pkgcfg_openssl=yes
OPENSSL_INCDIR=`$PKG_CONFIG --variable=includedir openssl` OPENSSL_LIBLINE=`$PKG_CONFIG --libs openssl`
OPENSSL_INCLINE=`$PKG_CONFIG --cflags-only-I openssl`
AC_MSG_RESULT([Using paths from pkg-config]) AC_MSG_RESULT([Using paths from pkg-config])
fi fi
@@ -82,39 +105,45 @@ if test "$found_openssl" = "no"; then
for i in $OPENSSL_SEARCH_PATH; do for i in $OPENSSL_SEARCH_PATH; do
if test -r $i/include/openssl/evp.h; then if test -r $i/include/openssl/evp.h; then
OPENSSL_INCLINE="-I$i/include"
OPENSSL_INCDIR=$i/include OPENSSL_INCDIR=$i/include
fi fi
if test -r $i/include/openssl/hmac.h; then if test -r $i/include/openssl/hmac.h; then
OPENSSL_INCLINE="-I$i/include"
OPENSSL_INCDIR=$i/include OPENSSL_INCDIR=$i/include
fi fi
if test -r $i/lib/libcrypto.a -o -r $i/lib/libcrypto.$SHLIB_SUFFIX_NAME; then if test -r $i/lib/libcrypto.a -o -r $i/lib/libcrypto$SHLIB_SUFFIX_NAME; then
OPENSSL_LIBDIR=$i/lib OPENSSL_LIBLINE="-L$i/lib -lcrypto"
fi fi
test -n "$OPENSSL_INCDIR" && test -n "$OPENSSL_LIBDIR" && break test -n "$OPENSSL_INCLINE" && test -n "$OPENSSL_LIBLINE" && break
done done
if test -z "$OPENSSL_INCDIR"; then if test -z "$OPENSSL_INCLINE"; then
AC_MSG_ERROR([Cannot find OpenSSL's <evp.h> or <hmac.h>]) AC_MSG_ERROR([Cannot find OpenSSL's <evp.h> or <hmac.h>])
fi fi
if test -z "$OPENSSL_LIBDIR"; then if test -z "$OPENSSL_LIBLINE"; then
AC_MSG_ERROR([Cannot find OpenSSL's libcrypto]) AC_MSG_ERROR([Cannot find OpenSSL's libcrypto])
fi fi
AC_MSG_RESULT([$OPENSSL_INCDIR $OPENSSL_LIBDIR]) AC_MSG_RESULT([$OPENSSL_INCLINE $OPENSSL_LIBLINE])
fi fi
# #
# Confirm required OpenSSL libs # Confirm required OpenSSL libs
# #
if test ! -r $OPENSSL_INCDIR/openssl/bn.h || test ! -r $OPENSSL_INCDIR/openssl/evp.h || \ if test ! "$pkgcfg_openssl" = "yes"; then
if test ! -r $OPENSSL_INCDIR/openssl/bn.h || test ! -r $OPENSSL_INCDIR/openssl/evp.h || \
test ! -r $OPENSSL_INCDIR/openssl/hmac.h || test ! -r $OPENSSL_INCDIR/openssl/pem.h || \ test ! -r $OPENSSL_INCDIR/openssl/hmac.h || test ! -r $OPENSSL_INCDIR/openssl/pem.h || \
test ! -r $OPENSSL_INCDIR/openssl/sha.h; then test ! -r $OPENSSL_INCDIR/openssl/sha.h; then
AC_MSG_ERROR([Missing one or more of <openssl/bn.h>, <openssl/evp.h>, <openssl/hmac.h>, <openssl/pem.h>, <openssl/sha.h>]) AC_MSG_ERROR([Missing one or more of <openssl/bn.h>, <openssl/evp.h>, <openssl/hmac.h>, <openssl/pem.h>, <openssl/sha.h>])
fi
fi fi
CFLAGS="$CFLAGS -I$OPENSSL_INCDIR" CFLAGS="$CFLAGS $OPENSSL_INCLINE"
LDFLAGS="$LDFLAGS -L$OPENSSL_LIBDIR -lcrypto" LDFLAGS="$LDFLAGS $OPENSSL_LIBLINE"
fi
# #
# zlib # zlib
@@ -136,7 +165,7 @@ for i in $LIBSSH2_LIBZ_DIR; do
if test -r $i/include/zlib.h; then if test -r $i/include/zlib.h; then
LIBZ_INCDIR=$i/include LIBZ_INCDIR=$i/include
fi fi
if test -r $i/lib/libz.a -o -r $i/lib/libz.$SHLIB_SUFFIX_NAME; then if test -r $i/lib/libz.a -o -r $i/lib/libz$SHLIB_SUFFIX_NAME; then
LIBZ_LIBDIR=$i/lib LIBZ_LIBDIR=$i/lib
fi fi
test -n "$LIBZ_INCDIR" && test -n "$LIBZ_LIBDIR" && break test -n "$LIBZ_INCDIR" && test -n "$LIBZ_LIBDIR" && break
@@ -169,56 +198,48 @@ if test "$GEX_NEW" != "no"; then
AC_DEFINE(LIBSSH2_DH_GEX_NEW, 1, [Enable newer diffie-hellman-group-exchange-sha1 syntax]) AC_DEFINE(LIBSSH2_DH_GEX_NEW, 1, [Enable newer diffie-hellman-group-exchange-sha1 syntax])
fi fi
# dnl ************************************************************
# Optional debugging -- Meant for developer maintenance only dnl option to switch on compiler debug options
# When enabled, the relevant debugging information will be written on stderr dnl
# AC_MSG_CHECKING([whether to enable pedantic and debug compiler options])
AC_ARG_ENABLE(debug-transport, AC_ARG_ENABLE(debug,
AC_HELP_STRING([--enable-debug-transport],[Output transport layer debugging info to stderr]), AC_HELP_STRING([--enable-debug],[Enable pedantic and debug options])
[AC_DEFINE(LIBSSH2_DEBUG_TRANSPORT, 1, [Output transport layer debugging info to stderr])]) AC_HELP_STRING([--disable-debug],[Disable debug options]),
AC_ARG_ENABLE(debug-kex, [ case "$enableval" in
AC_HELP_STRING([--enable-debug-kex],[Output Key Exchange debugging info to stderr]), no)
[AC_DEFINE(LIBSSH2_DEBUG_KEX, 1, [Output Key Exchange debugging info to stderr])]) AC_MSG_RESULT(no)
AC_ARG_ENABLE(debug-userauth, ;;
AC_HELP_STRING([--enable-debug-userauth],[Output userauth debugging info to stderr]), *) AC_MSG_RESULT(yes)
[AC_DEFINE(LIBSSH2_DEBUG_USERAUTH, 1, [Output userauth layer debugging info to stderr])])
AC_ARG_ENABLE(debug-channel,
AC_HELP_STRING([--enable-debug-connection],[Output connection layer debugging info to stderr]),
[AC_DEFINE(LIBSSH2_DEBUG_CONNECTION, 1, [Output connection layer debugging info to stderr])])
AC_ARG_ENABLE(debug-scp,
AC_HELP_STRING([--enable-debug-scp],[Output scp subsystem debugging info to stderr]),
[AC_DEFINE(LIBSSH2_DEBUG_SCP, 1, [Output scp subsystem debugging info to stderr])])
AC_ARG_ENABLE(debug-sftp,
AC_HELP_STRING([--enable-debug-sftp],[Output sftp subsystem debugging info to stderr]),
[AC_DEFINE(LIBSSH2_DEBUG_SFTP, 1, [Output sftp subsystem debugging info to stderr])])
AC_ARG_ENABLE(debug-publickey,
AC_HELP_STRING([--enable-debug-publickey],[Output publickey subsystem debugging info to stderr]),
[AC_DEFINE(LIBSSH2_DEBUG_PUBLICKEY, 1, [Output publickey subsystem debugging info to stderr])])
AC_ARG_ENABLE(debug-errors,
AC_HELP_STRING([--enable-debug-errors],[Output failure events to stderr]),
[AC_DEFINE(LIBSSH2_DEBUG_ERRORS, 1, [Output failure events to stderr])])
AC_ARG_ENABLE(debug-all,
AC_HELP_STRING([--enable-debug-all],[Output debugging info for all layers to stderr]),
[
AC_DEFINE(LIBSSH2_DEBUG_TRANSPORT, 1, [Output transport layer debugging info to stderr])
AC_DEFINE(LIBSSH2_DEBUG_KEX, 1, [Output Key Exchange debugging info to stderr])
AC_DEFINE(LIBSSH2_DEBUG_USERAUTH, 1, [Output userauth layer debugging info to stderr])
AC_DEFINE(LIBSSH2_DEBUG_CONNECTION, 1, [Output connection layer debugging info to stderr])
AC_DEFINE(LIBSSH2_DEBUG_SCP, 1, [Output scp subsystem debugging info to stderr])
AC_DEFINE(LIBSSH2_DEBUG_SFTP, 1, [Output sftp subsystem debugging info to stderr])
AC_DEFINE(LIBSSH2_DEBUG_PUBLICKEY, 1, [Output publickey subsystem debugging info to stderr])
AC_DEFINE(LIBSSH2_DEBUG_ERRORS, 1, [Output failure events to stderr])
])
CPPFLAGS="$CPPFLAGS -DLIBSSH2DEBUG"
CFLAGS="$CFLAGS -g"
dnl set compiler "debug" options to become more picky, and remove
dnl optimize options from CFLAGS
CURL_CC_DEBUG_OPTS
;;
esac
],
AC_MSG_RESULT(no)
)
# Checks for header files. # Checks for header files.
# AC_HEADER_STDC # AC_HEADER_STDC
AC_CHECK_HEADERS([errno.h fcntl.h stdio.h stdlib.h unistd.h sys/uio.h sys/select.h]) AC_CHECK_HEADERS([errno.h fcntl.h stdio.h stdlib.h unistd.h sys/uio.h])
AC_CHECK_HEADERS([sys/select.h sys/socket.h sys/ioctl.h sys/time.h])
AC_CHECK_HEADERS([arpa/inet.h netinet/in.h])
AC_CHECK_FUNCS(poll gettimeofday select) AC_CHECK_FUNCS(poll gettimeofday select)
# Checks for typedefs, structures, and compiler characteristics. # Checks for typedefs, structures, and compiler characteristics.
AC_C_CONST AC_C_CONST
AC_C_INLINE
CURL_CHECK_NONBLOCKING_SOCKET
AC_CONFIG_FILES([Makefile AC_CONFIG_FILES([Makefile
src/Makefile]) src/Makefile
tests/Makefile
example/Makefile
example/simple/Makefile
docs/Makefile])
AC_OUTPUT AC_OUTPUT

2
docs/.cvsignore Normal file
View File

@@ -0,0 +1,2 @@
Makefile
Makefile.in

13
docs/Makefile.am Normal file
View File

@@ -0,0 +1,13 @@
# $Id: Makefile.am,v 1.5 2007/04/22 19:51:53 jehousley Exp $
EXTRA_DIST = template.3
dist_man_MANS = libssh2_channel_forward_accept.3 \
libssh2_session_init.3 libssh2_channel_forward_listen_ex.3 \
libssh2_session_startup.3 libssh2_channel_read_ex.3 \
libssh2_sftp_init.3 libssh2_channel_readnb_ex.3 \
libssh2_sftp_open_ex.3 libssh2_channel_set_blocking.3 \
libssh2_session_free.3 libssh2_poll.3 libssh2_poll_channel_read.3 \
libssh2_sftp_read.3 libssh2_sftp_readnb.3 libssh2_sftp_readdir.3 \
libssh2_sftp_readdirnb.3 libssh2_sftp_mkdir_ex.3 \
libssh2_sftp_mkdirnb_ex.3

View File

@@ -0,0 +1,16 @@
.\" $Id: libssh2_channel_forward_accept.3,v 1.1 2006/12/21 14:09:12 bagder Exp $
.\"
.TH libssh2_channel_forward_accept 3 "14 Dec 2006" "libssh2 0.15" "libssh2 manual"
.SH NAME
libssh2_channel_forward_accept - accept a queued connection
.SH SYNOPSIS
.B #include <libssh2.h>
.B LIBSSH2_CHANNEL * libssh2_channel_forward_accept(LIBSSH2_LISTENER *listener);
.SH DESCRIPTION
\fIlistener\fP is a forwarding listener instance as returned by
\fBlibssh2_channel_forward_listen(3)\fP.
.SH RETURN VALUE
A newly allocated channel instance or NULL on failure.
.SH "SEE ALSO"
.BI libssh2_channel_forward_listen(3)

View File

@@ -0,0 +1,40 @@
.\" $Id: libssh2_channel_forward_listen_ex.3,v 1.2 2007/04/12 21:30:03 dfandrich Exp $
.\"
.TH libssh2_channel_forward_listen_ex 3 "14 Dec 2006" "libssh2 0.15" "libssh2 manual"
.SH NAME
libssh2_channel_forward_listen_ex - listen to inbound connections
.SH SYNOPSIS
#include <libssh2.h>
LIBSSH2_LISTENER * libssh2_channel_forward_listen_ex(LIBSSH2_SESSION *session,
char *host,
int port,
int *bound_port,
int queue_maxsize);
LIBSSH2_LISTENER * libssh2_channel_forward_listen(LIBSSH2_SESSION *session,
int port);
.SH DESCRIPTION
Instruct the remote SSH server to begin listening for inbound TCP/IP
connections. New connections will be queued by the library until accepted by
\fIlibssh2_channel_forward_accept(3)\fP.
\fIsession\fP - instance as returned by libssh2_session_init().
\fIhost\fP - specific address to bind to on the remote host. Binding to
0.0.0.0 (default when NULL is passed) will bind to all available addresses.
\fIport\fP - port to bind to on the remote host. When 0 is passed, the remote
host will select the first available dynamic port.
\fIbound_port\fP - Populated with the actual port bound on the remote
host. Useful when requesting dynamic port numbers.
\fIqueue_maxsize\fP - Maximum number of pending connections to queue before
rejecting further attempts.
\fIlibssh2_channel_forward_listen(3)\fP is a macro.
.SH RETURN VALUE
A newly allocated LIBSSH2_LISTENER instance or NULL on failure.
.SH "SEE ALSO"
.BI libssh2_channel_forward_accept(3)

View File

@@ -0,0 +1,36 @@
.\" $Id: libssh2_channel_read_ex.3,v 1.5 2007/02/23 10:20:56 bagder Exp $
.\"
.TH libssh2_channel_read_ex 3 "14 Dec 2006" "libssh2 0.15" "libssh2 manual"
.SH NAME
libssh2_channel_read_ex - read data from a channel stream
.SH SYNOPSIS
#include <libssh2.h>
int libssh2_channel_read_ex(LIBSSH2_CHANNEL *channel, int stream_id,
char *buf, size_t buflen);
int libssh2_channel_read(LIBSSH2_CHANNEL *channel, char *buf,
size_t buflen);
int libssh2_channel_read_stderr(LIBSSH2_CHANNEL *channel, char *buf,
size_t buflen);
.SH DESCRIPTION
Attempt to read data from an active channel stream. All channel streams have
one standard I/O substream (stream_id == 0), and may have up to 2^32 extended
data streams as identified by the selected \fIstream_id\fP. The SSH2 protocol
currently defines a stream ID of 1 to be the stderr substream.
\fIchannel\fP - active channel stream to read from.
\fIstream_id\fP - substream ID number (e.g. 0 or SSH_EXTENDED_DATA_STDERR)
\fIbuf\fP - pointer to storage buffer to read data into
\fIbuflen\fP - size of the buf storage
\fIlibssh2_channel_read(3)\fP and \fIlibssh2_channel_read_stderr(3)\fP are
macros.
.SH RETURN VALUE
Actual number of bytes read or negative on failure.
.SH "SEE ALSO"
.BR libssh2_poll_channel_read(3)

View File

@@ -0,0 +1,39 @@
.\" $Id: libssh2_channel_readnb_ex.3,v 1.2 2007/02/23 10:20:56 bagder Exp $
.\"
.TH libssh2_channel_read_ex 3 "14 Dec 2006" "libssh2 0.15" "libssh2 manual"
.SH NAME
libssh2_channel_read_ex - read data from a channel stream
.SH SYNOPSIS
#include <libssh2.h>
int libssh2_channel_readnb_ex(LIBSSH2_CHANNEL *channel, int stream_id,
char *buf, size_t buflen);
int libssh2_channel_readnb(LIBSSH2_CHANNEL *channel, char *buf,
size_t buflen);
int libssh2_channel_readnb_stderr(LIBSSH2_CHANNEL *channel, char *buf,
size_t buflen);
.SH DESCRIPTION
Attempt to read data from an active channel stream. All channel streams have
one standard I/O substream (stream_id == 0), and may have up to 2^32 extended
data streams as identified by the selected \fIstream_id\fP. The SSH2 protocol
currently defines a stream ID of 1 to be the stderr substream.
\fIchannel\fP - active channel stream to read from.
\fIstream_id\fP - substream ID number (e.g. 0 or SSH_EXTENDED_DATA_STDERR)
\fIbuf\fP - pointer to storage buffer to read data into
\fIbuflen\fP - size of the buf storage
\fIlibssh2_channel_read(3)\fP and \fIlibssh2_channel_read_stderr(3)\fP are
macros.
.SH RETURN VALUE
Actual number of bytes read or negative on failure. It returns
LIBSSH2CHANNEL_EAGAIN when it would otherwise block. While
LIBSSH2CHANNEL_EAGAIN is a negative number, it isn't really a failure per se.
.SH "SEE ALSO"
.BR libssh2_poll_channel_read(3)

View File

@@ -0,0 +1,23 @@
.\" $Id: libssh2_channel_set_blocking.3,v 1.1 2006/12/21 14:09:13 bagder Exp $
.\"
.TH libssh2_channel_set_blocking 3 "14 Dec 2006" "libssh2 0.15" "libssh2 manual"
.SH NAME
libssh2_channel_set_blocking - set or clear blocking mode on channel
.SH SYNOPSIS
#include <libssh2.h>
void libssh2_channel_set_blocking(LIBSSH2_CHANNEL *channel, int blocking);
.SH DESCRIPTION
Set or clear blocking mode on the selected channel. If a read is performed on
a channel with no data currently available, a blocking channel will wait for
data to arrive and return what it receives. A non-blocking channel will return
immediately with an empty buffer.
\fIchannel\fP - channel stream to set or clean blocking status on.
\fIblocking\fP - Set to a non-zero value to make the channel block, or zero to
make it non-blocking.
.SH RETURN VALUE
None
.SH "SEE ALSO"
.BI libssh2_channel_read_ex(3)

View File

@@ -0,0 +1,37 @@
.\" $Id: libssh2_channel_write_ex.3,v 1.1 2007/02/23 10:20:56 bagder Exp $
.\"
.TH libssh2_channel_write_ex 3 "6 Feb 2007" "libssh2 0.15" "libssh2 manual"
.SH NAME
libssh2_channel_write_ex - write data to a channel stream blocking
.SH SYNOPSIS
#include <libssh2.h>
int libssh2_channel_write_ex(LIBSSH2_CHANNEL *channel, int stream_id,
char *buf, size_t buflen);
int libssh2_channel_write(LIBSSH2_CHANNEL *channel, char *buf,
size_t buflen);
int libssh2_channel_write_stderr(LIBSSH2_CHANNEL *channel, char *buf,
size_t buflen);
.SH DESCRIPTION
Write data to a channel stream. All channel streams have one standard I/O
substream (stream_id == 0), and may have up to 2^32 extended data streams as
identified by the selected \fIstream_id\fP. The SSH2 protocol currently
defines a stream ID of 1 to be the stderr substream.
\fIchannel\fP - active channel stream to write to.
\fIstream_id\fP - substream ID number (e.g. 0 or SSH_EXTENDED_DATA_STDERR)
\fIbuf\fP - pointer to buffer to write
\fIbuflen\fP - size of the data to write
\fIlibssh2_channel_write(3)\fP and \fIlibssh2_channel_write_stderr(3)\fP are
macros.
.SH RETURN VALUE
Actual number of bytes written or negative on failure.
.SH "SEE ALSO"
.BR libssh2_channel_open_session(3)
.BR libssh2_channel_read(3)

19
docs/libssh2_poll.3 Normal file
View File

@@ -0,0 +1,19 @@
.\" $Id: libssh2_poll.3,v 1.2 2007/04/12 21:30:03 dfandrich Exp $
.\"
.TH libssh2_poll 3 "14 Dec 2006" "libssh2 0.15" "libssh2 manual"
.SH NAME
libssh2_poll - poll for activity on a socket, channel or listener
.SH SYNOPSIS
#include <libssh2.h>
int libssh2_poll(LIBSSH2_POLLFD *fds, unsigned int nfds, long timeout);
.SH DESCRIPTION
Poll for activity on a socket, channel, listener, or any combination of these
three types. The calling semantics for this function generally match
\fIpoll(2)\fP however the structure of fds is somewhat more complex in order
to accommodate the disparate datatypes, POLLFD constants have been namespaced
to avoid platform discrepancies, and revents has additional values defined.
.SH "RETURN VALUE"
Number of fds with interesting events.
.SH "SEE ALSO"
.BR libssh2_poll_channel_read(3)

View File

@@ -0,0 +1,18 @@
.\" $Id: libssh2_poll_channel_read.3,v 1.1 2007/02/23 10:20:56 bagder Exp $
.\"
.TH libssh2_poll_channel_read 3 "14 Dec 2006" "libssh2 0.15" "libssh2 manual"
.SH NAME
libssh2_poll_channel_read - check if data is available
.SH SYNOPSIS
#include <libssh2.h>
int libssh2_poll_channel_read(LIBSSH2_CHANNEL *channel, int extended);
.SH DESCRIPTION
\fIlibssh2_poll_channel_read(3)\fP checks to see if data is available in the
\fIchannel\fP's read buffer. No attempt is made with this method to see if
packets are available to be processed. For full polling support, use
\fIlibssh2_poll(3)\fP.
.SH RETURN VALUE
Returns 1 when data is available and 0 otherwise.
.SH "SEE ALSO"
.BR libssh2_poll(3)

View File

@@ -0,0 +1,17 @@
.\" $Id: libssh2_session_free.3,v 1.1 2006/12/21 14:09:13 bagder Exp $
.\"
.TH libssh2_session_free 3 "14 Dec 2006" "libssh2 0.15" "libssh2 manual"
.SH NAME
libssh2_session_free - frees resources associated with a session instance
.SH SYNOPSIS
#include <libssh2.h>
void libssh2_session_free(LIBSSH2_SESSION *session);
.SH DESCRIPTION
Frees resources associated with a session instance. Typically called after
\fIlibssh2_session_disconnect(3)\fP.
.SH RETURN VALUE
None
.SH "SEE ALSO"
.BI libssh2_session_init(3),
.BI libssh2_session_disconnect(3)

View File

@@ -0,0 +1,29 @@
.\" $Id: libssh2_session_init.3,v 1.2 2007/04/12 21:30:03 dfandrich Exp $
.\"
.TH libssh2_session_init 3 "14 Dec 2006" "libssh2 0.15" "libssh2 manual"
.SH NAME
libssh2_session_init - initializes an SSH session object
.SH SYNOPSIS
#include <libssh2.h>
LIBSSH2_SESSION *libssh2_session_init_ex(
LIBSSH2_ALLOC_FUNC((*myalloc)),
LIBSSH2_FREE_FUNC((*myfree)),
LIBSSH2_REALLOC_FUNC((*myrealloc)),
void *abstract);
LIBSSH2_SESSION *libssh2_session_init(void);
.SH DESCRIPTION
Initializes an SSH session object. By default system memory allocators
(malloc(), free(), realloc()) will be used for any dynamically allocated memory
blocks. Alternate memory allocation functions may be specified using the
extended version of this API call, and/or optional application specific data
may be attached to the session object.
This method must be called first, prior to configuring session options or
starting up an SSH session with a remote server.
.SH RETURN VALUE
Pointer to a newly allocated LIBSSH2_SESSION instance, or NULL on errors.
.SH "SEE ALSO"
.BI libssh2_session_free(3),
.BI libssh2_session_startup(3)

View File

@@ -0,0 +1,16 @@
.\" $Id: libssh2_session_startup.3,v 1.2 2007/01/02 05:47:00 gusarov Exp $
.\"
.TH libssh2_session_startup 3 "14 Dec 2006" "libssh2 0.15" "libssh2 manual"
.SH NAME
libssh2_session_startup - begin transport layer
.SH SYNOPSIS
#include <libssh2.h>
int libssh2_session_startup(LIBSSH2_SESSION *session, int socket);
.SH DESCRIPTION
Begin transport layer protocol negotiation with the connected host.
.SH RETURN VALUE
0 on success, \-1 on failure
.SH "SEE ALSO"
.BI libssh2_session_free(3),
.BI libssh2_session_init(3)

21
docs/libssh2_sftp_init.3 Normal file
View File

@@ -0,0 +1,21 @@
.\" $Id: libssh2_sftp_init.3,v 1.2 2007/04/22 17:18:03 jehousley Exp $
.\"
.TH libssh2_sftp_init 3 "23 Jan 2007" "libssh2 0.15" "libssh2 manual"
.SH NAME
libssh2_sftp_init -
.SH SYNOPSIS
#include <libssh2.h>
#include <libssh2_sftp.h>
LIBSSH2_SFTP *libssh2_sftp_init(LIBSSH2_SESSION *session);
.SH DESCRIPTION
Open a channel and initialize the SFTP subsystem. Although the SFTP subsystem
operates over the same type of channel as those exported by the Channel API,
the protocol itself implements its own unique binary packet protocol which
must be managed with the libssh2_sftp_*() family of functions. When an SFTP
session is complete, it must be destroyed using the
\fIlibssh2_sftp_shutdown(3)\fP function.
.SH RETURN VALUE
A pointer to the newly allocated SFTP instance or NULL on failure.
.SH "SEE ALSO"
.BI libssh2_sftp_shutdown(3), libssh2_sftp_open_ex(3)

View File

@@ -0,0 +1,26 @@
.\" $Id: libssh2_sftp_mkdir_ex.3,v 1.1 2007/04/22 19:51:53 jehousley Exp $
.\"
.TH libssh2_sftp_mkdir_ex 3 "16 Apr 2007" "libssh2 0.15" "libssh2 manual"
.SH NAME
libssh2_sftp_mkdir_ex - create a directory on the remote file system
.SH SYNOPSIS
#include <libssh2.h>
#include <libssh2_sftp.h>
int libssh2_sftp_mkdir_ex(LIBSSH2_SFTP *sftp, const char *path,
unsigned int path_len, long mode);
.SH DESCRIPTION
\fIsftp\fP SFTP instance as returned by \fIlibssh2_sftp_init(3)\fP.
\fIpath\fP full path of the new directory to create. Note that the new
directory's parents must all exist priot to making this call.
\fIpath_len\fP length of the full path of the new directory to create.
\fImode\fP directory creation mode (e.g. 0755).
.SH RETURN VALUE
0 on success, or -1 on failure.
.SH "SEE ALSO"
.BR libssh2_sftp_opendir(3)

View File

@@ -0,0 +1,29 @@
.\" $Id: libssh2_sftp_mkdirnb_ex.3,v 1.1 2007/04/22 19:51:54 jehousley Exp $
.\"
.TH libssh2_sftp_mkdir_ex 3 "16 Apr 2007" "libssh2 0.15" "libssh2 manual"
.SH NAME
libssh2_sftp_mkdir_ex - create a directory on the remote file system in
non-blocking mode
.SH SYNOPSIS
#include <libssh2.h>
#include <libssh2_sftp.h>
int libssh2_sftp_mkdir_ex(LIBSSH2_SFTP *sftp, const char *path,
unsigned int path_len, long mode);
.SH DESCRIPTION
\fIsftp\fP SFTP instance as returned by \fIlibssh2_sftp_init(3)\fP.
\fIpath\fP full path of the new directory to create. Note that the new
directory's parents must all exist priot to making this call.
\fIpath_len\fP length of the full path of the new directory to create.
\fImode\fP directory creation mode (e.g. 0755).
.SH RETURN VALUE
0 on success, or -1 on failure. It returns LIBSSH2CHANNEL_EAGAIN when
it would otherwise block. While LIBSSH2CHANNEL_EAGAIN is a negative
number, it isn't really a failure per se.
.SH "SEE ALSO"
.BR libssh2_sftp_opendir(3)

View File

@@ -0,0 +1,39 @@
.\" $Id: libssh2_sftp_open_ex.3,v 1.3 2007/04/22 17:18:03 jehousley Exp $
.\"
.TH libssh2_sftp_open_ex 3 "23 Jan 2007" "libssh2 0.15" "libssh2 manual"
.SH NAME
libssh2_sftp_open -
.SH SYNOPSIS
#include <libssh2.h>
#include <libssh2_sftp.h>
LIBSSH2_SFTP_HANDLE *libssh2_sftp_open_ex(LIBSSH2_SFTP *sftp,
char *filename, int filename_len,
unsigned long flags, long mode, int open_type);
LIBSSH2_SFTP_HANDLE *libssh2_sftp_open(LIBSSH2_SFTP *sftp,
char *filename, unsigned long flags, long mode);
LIBSSH2_SFTP_HANDLE *libssh2_sftp_opendir(LIBSSH2_SFTP *sftp,
char *path);
.SH DESCRIPTION
\fIsftp\fP - SFTP instance as returned by libssh2_sftp_init().
\fIfilename\fP - Remote file/directory resource to open
\fIfilename_len\fP - Length of filename
\fIflags\fP - Any (reasonable) combination of the LIBSSH2_FXF_* constants
corresponding fopen modes.
\fImode\fP - POSIX file permissions to assign if the file is being newly
created.
\fIopen_type\fP - Either of LIBSSH2_SFTP_OPENFILE (to open a file) or
LIBSSH2_SFTP_OPENDIR (to open a directory).
.SH RETURN VALUE
A pointer to the newly created LIBSSH2_SFTP_HANDLE instance or NULL on
failure.
.SH "SEE ALSO"
.BI libssh_sftp_close(3)

27
docs/libssh2_sftp_read.3 Normal file
View File

@@ -0,0 +1,27 @@
.\" $Id: libssh2_sftp_read.3,v 1.3 2007/04/22 17:18:03 jehousley Exp $
.\"
.TH libssh2_sftp_read 3 "6 Feb 2007" "libssh2 0.15" "libssh2 manual"
.SH NAME
libssh2_sftp_read - read data from an SFTP handle
.SH SYNOPSIS
#include <libssh2.h>
#include <libssh2_sftp.h>
ssize_t libssh2_sftp_read(LIBSSH2_SFTP_HANDLE *handle,
char *buffer, size_t buffer_maxlen);
.SH DESCRIPTION
Reads a block of data from an LIBSSH2_SFTP_HANDLE. This method is modelled
after the POSIX \Iread(3)\fP function and uses the same calling
semantics. \fIlibssh2_sftp_read(3)\fP will attempt to read as much as possible
however it may not fill all of buffer if the file pointer reaches the end or
if further reads would cause the socket to block.
\fIhandle\fP is the SFTP File Handle as returned by \fIlibssh2_sftp_open(3)\fP.
\fIbuffer\fP is a pointer to a pre-allocated buffer of at least
\fIbuffer_maxlen\fP bytes to read data into.
.SH RETURN VALUE
Number of bytes actually populated into buffer, or -1 on failure.
.SH "SEE ALSO"
.BR libssh2_sftp_open(3)
.BR libssh2_sftp_readnb(3)

View File

@@ -0,0 +1,35 @@
.\" $Id: libssh2_sftp_readdir.3,v 1.3 2007/04/22 17:18:03 jehousley Exp $
.\"
.TH libssh2_sftp_readdir 3 "16 Apr 2007" "libssh2 0.15" "libssh2 manual"
.SH NAME
libssh2_sftp_readdir - read directory data from an SFTP handle
.SH SYNOPSIS
#include <libssh2.h>
#include <libssh2_sftp.h>
int libssh2_sftp_readdir(LIBSSH2_SFTP_HANDLE *handle, char *buffer,
size_t buffer_maxlen, LIBSSH2_SFTP_ATTRIBUTES *attrs);
.SH DESCRIPTION
Read a block of data from a LIBSSH2_SFTP_HANDLE. This method is modeled
after the POSIX \fIreaddir(3)\fP however, it uses a variable sized directory
entry (filename) buffer and returns statbuf type data in the same call.
\fIhandle\fP is the SFTP File Handle as returned by
\fIlibssh2_sftp_diropen(3)\fP.
\fIbuffer\fP is a pointer to a pre-allocated buffer of at least
\fIbuffer_maxlen\fP bytes to read data into.
\fIbuffer_maxlen\fP is the length of buffer in bytes. If the length of the
filename is longer than the space provided by buffer_maxlen it will be
truncated to fit.
\fIattrs\fP is a pointer to LIBSSH2_SFTP_ATTRIBUTES storage to populate
statbuf style data into.
.SH RETURN VALUE
Number of bytes actually populated into buffer, or -1 on failure.
.SH "SEE ALSO"
.BR libssh2_sftp_opendir(3)
.BR libssh2_sftp_readdirnb(3)

View File

@@ -0,0 +1,40 @@
.\" $Id: libssh2_sftp_readdirnb.3,v 1.3 2007/04/22 17:18:03 jehousley Exp $
.\"
.TH libssh2_sftp_readdir 3 "16 Apr 2007" "libssh2 0.15" "libssh2 manual"
.SH NAME
libssh2_sftp_readdirnb - read directory data from an SFTP handle non-blocking
.SH SYNOPSIS
#include <libssh2.h>
#include <libssh2_sftp.h>
int libssh2_sftp_readdirnb(LIBSSH2_SFTP_HANDLE *handle, char *buffer,
size_t buffer_maxlen, LIBSSH2_SFTP_ATTRIBUTES *attrs);
.SH DESCRIPTION
Read a block of data from a LIBSSH2_SFTP_HANDLE non-blocking. This method is
modeled after the POSIX \fIreaddir(3)\fP however, it uses a variable sized
directory entry (filename) buffer and returns statbuf type data in the same
call.
\fIhandle\fP is the SFTP File Handle as returned by
\fIlibssh2_sftp_diropen(3)\fP.
\fIbuffer\fP is a pointer to a pre-allocated buffer of at least
\fIbuffer_maxlen\fP bytes to read data into.
\fIbuffer_maxlen\fP is the length of buffer in bytes. If the length of the
filename is longer than the space provided by buffer_maxlen it will be
truncated to fit.
\fIattrs\fP is a pointer to LIBSSH2_SFTP_ATTRIBUTES storage to populate
statbuf style data into.
.SH RETURN VALUE
Number of bytes actually populated into buffer, or negative on failure. It
returns LIBSSH2CHANNEL_EAGAIN when it would otherwise block. While
LIBSSH2CHANNEL_EAGAIN is a negative number, it isn't really a failure per se.
.SH "SEE ALSO"
.BR libssh2_sftp_opendir(3)
.BR libssh2_sftp_readdirnb(3)

View File

@@ -0,0 +1,29 @@
.\" $Id: libssh2_sftp_readnb.3,v 1.3 2007/04/22 17:18:03 jehousley Exp $
.\"
.TH libssh2_sftp_read 3 "6 Feb 2007" "libssh2 0.15" "libssh2 manual"
.SH NAME
libssh2_sftp_readnb - read data from an SFTP handle non-blocking
.SH SYNOPSIS
#include <libssh2.h>
#include <libssh2_sftp.h>
ssize_t libssh2_sftp_readnb(LIBSSH2_SFTP_HANDLE *handle,
char *buffer, size_t buffer_maxlen);
.SH DESCRIPTION
Reads a block of data from an LIBSSH2_SFTP_HANDLE non-blocking. This method is
modelled after the POSIX \Iread(3)\fP function and uses the same calling
semantics. \fIlibssh2_sftp_read(3)\fP will attempt to read as much as possible
however it may not fill all of buffer if the file pointer reaches the end or
if further reads would cause the socket to block.
\fIhandle\fP is the SFTP File Handle as returned by \fIlibssh2_sftp_open(3)\fP.
\fIbuffer\fP is a pointer to a pre-allocated buffer of at least
\fIbuffer_maxlen\fP bytes to read data into.
.SH RETURN VALUE
Number of bytes actually populated into buffer, or negative on failure. It
returns LIBSSH2CHANNEL_EAGAIN when it would otherwise block. While
LIBSSH2CHANNEL_EAGAIN is a negative number, it isn't really a failure per se.
.SH "SEE ALSO"
.BR libssh2_sftp_read(3)
.BR libssh2_sftp_open(3)

15
docs/template.3 Normal file
View File

@@ -0,0 +1,15 @@
.\" $Id: template.3,v 1.2 2007/04/12 21:30:03 dfandrich Exp $
.\"
.TH libssh2_template 3 "14 Dec 2006" "libssh2 0.15" "libssh2 manual"
.SH NAME
libssh2_template - short function description
.SH SYNOPSIS
#include <libssh2.h>
void libssh2_template(void);
.SH DESCRIPTION
Long text describing the function and its input arguments.
.SH RETURN VALUE
Describe what the function returns.
.SH "SEE ALSO"
Add related functions

2
example/.cvsignore Normal file
View File

@@ -0,0 +1,2 @@
Makefile
Makefile.in

2
example/Makefile.am Normal file
View File

@@ -0,0 +1,2 @@
AUTOMAKE_OPTIONS = foreign nostdinc
SUBDIRS = simple

17
example/simple/.cvsignore Normal file
View File

@@ -0,0 +1,17 @@
Makefile
Makefile.in
.deps
.libs
scp
scp_nonblock
sftp
sftp_nonblock
sftpdir
sftpdir_nonblock
ssh2
sftp_RW_nonblock
sftp_mkdir
sftp_mkdir_nonblock
sftp_write
sftp_write_nonblock

View File

@@ -0,0 +1,38 @@
AUTOMAKE_OPTIONS = foreign nostdinc
# samples
noinst_PROGRAMS = ssh2 \
scp scp_nonblock \
sftp sftp_nonblock \
sftp_write sftp_write_nonblock \
sftp_mkdir sftp_mkdir_nonblock \
sftp_RW_nonblock \
sftpdir sftpdir_nonblock
INCLUDES = -I$(top_srcdir)/include -I$(top_builddir)/src
LDADD = $(top_builddir)/src/libssh2.la
ssh2_SOURCES = ssh2.c
scp_SOURCES = scp.c
scp_nonblock_SOURCES = scp_nonblock.c
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

170
example/simple/scp.c Normal file
View File

@@ -0,0 +1,170 @@
/*
* $Id: scp.c,v 1.6 2007/04/26 23:59:14 gknauf Exp $
*
* Sample showing how to do a simple SCP transfer.
*/
#include <libssh2.h>
#include <libssh2_config.h>
#ifdef HAVE_WINSOCK2_H
# include <winsock2.h>
#endif
#ifdef HAVE_NETINET_IN_H
# include <netinet/in.h>
#endif
#ifdef HAVE_SYS_SOCKET_H
# include <sys/socket.h>
#endif
# ifdef HAVE_UNISTD_H
#include <unistd.h>
#endif
#ifdef HAVE_SYS_TIME_H
# include <sys/time.h>
#endif
#include <sys/types.h>
#include <fcntl.h>
#include <errno.h>
#include <stdio.h>
#include <ctype.h>
int main(int argc, char *argv[])
{
int sock, i, auth_pw = 1;
struct sockaddr_in sin;
const char *fingerprint;
LIBSSH2_SESSION *session;
LIBSSH2_CHANNEL *channel;
char *username=(char *)"username";
char *password=(char *)"password";
char *scppath=(char *)"/tmp/TEST";
struct stat fileinfo;
int rc;
off_t got=0;
#ifdef WIN32
WSADATA wsadata;
WSAStartup(WINSOCK_VERSION, &wsadata);
#endif
/* Ultra basic "connect to port 22 on localhost"
* Your code is responsible for creating the socket establishing the
* connection
*/
sock = socket(AF_INET, SOCK_STREAM, 0);
sin.sin_family = AF_INET;
sin.sin_port = htons(22);
sin.sin_addr.s_addr = htonl(0x7F000001);
if (connect(sock, (struct sockaddr*)(&sin),
sizeof(struct sockaddr_in)) != 0) {
fprintf(stderr, "failed to connect!\n");
return -1;
}
/* Create a session instance
*/
session = libssh2_session_init();
if(!session)
return -1;
/* trace transport layer stuff*/
libssh2_trace(session, LIBSSH2_TRACE_TRANS);
/* ... 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;
}
/* 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
* 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(argc > 1) {
username = argv[1];
}
if(argc > 2) {
password = argv[2];
}
if(argc > 3) {
scppath = argv[3];
}
if (auth_pw) {
/* We could authenticate via password */
if (libssh2_userauth_password(session, username, password)) {
printf("Authentication by password failed.\n");
goto shutdown;
}
} else {
/* Or by public key */
if (libssh2_userauth_publickey_fromfile(session, username,
"/home/username/.ssh/id_rsa.pub",
"/home/username/.ssh/id_rsa",
password)) {
printf("\tAuthentication by public key failed\n");
goto shutdown;
}
}
/* Request a file via SCP */
channel = libssh2_scp_recv(session, scppath, &fileinfo);
if (!channel) {
fprintf(stderr, "Unable to open a session\n");
goto shutdown;
}
while(got < fileinfo.st_size) {
char mem[1024];
int amount=sizeof(mem);
if((fileinfo.st_size -got) < amount) {
amount = fileinfo.st_size -got;
}
rc = libssh2_channel_read(channel, mem, amount);
if(rc == amount) {
write(2, mem, rc);
}
else {
fprintf(stderr, "libssh2_channel_read() failed: %d\n",
rc);
break;
}
got += rc;
}
libssh2_channel_free(channel);
channel = NULL;
shutdown:
libssh2_session_disconnect(session, "Normal Shutdown, Thank you for playing");
libssh2_session_free(session);
#ifdef WIN32
Sleep(1000);
closesocket(sock);
#else
sleep(1);
close(sock);
#endif
printf("all done\n");
return 0;
}

View File

@@ -0,0 +1,202 @@
/*
* $Id: scp_nonblock.c,v 1.3 2007/04/26 23:59:14 gknauf Exp $
*
* Sample showing how to do SCP transfers in a non-blocking manner.
*/
#include <libssh2.h>
#include <libssh2_config.h>
#ifdef HAVE_WINSOCK2_H
# include <winsock2.h>
#endif
#ifdef HAVE_NETINET_IN_H
# include <netinet/in.h>
#endif
#ifdef HAVE_SYS_SOCKET_H
# include <sys/socket.h>
#endif
# ifdef HAVE_UNISTD_H
#include <unistd.h>
#endif
#ifdef HAVE_SYS_TIME_H
# include <sys/time.h>
#endif
#include <sys/types.h>
#include <fcntl.h>
#include <errno.h>
#include <stdio.h>
#include <ctype.h>
int main(int argc, char *argv[])
{
int sock, i, auth_pw = 1;
struct sockaddr_in sin;
const char *fingerprint;
LIBSSH2_SESSION *session;
LIBSSH2_CHANNEL *channel;
char *username=(char *)"username";
char *password=(char *)"password";
char *scppath=(char *)"/tmp/TEST";
struct stat fileinfo;
int rc;
off_t got=0;
#ifdef WIN32
WSADATA wsadata;
WSAStartup(WINSOCK_VERSION, &wsadata);
#endif
/* Ultra basic "connect to port 22 on localhost"
* Your code is responsible for creating the socket establishing the
* connection
*/
sock = socket(AF_INET, SOCK_STREAM, 0);
sin.sin_family = AF_INET;
sin.sin_port = htons(22);
sin.sin_addr.s_addr = htonl(0x7F000001);
if (connect(sock, (struct sockaddr*)(&sin),
sizeof(struct sockaddr_in)) != 0) {
fprintf(stderr, "failed to connect!\n");
return -1;
}
/* We set the socket non-blocking. We do it after the connect just to
simplify the example code. */
#ifdef F_SETFL
/* FIXME: this can/should be done in a more portable manner */
rc = fcntl(sock, F_GETFL, 0);
fcntl(sock, F_SETFL, rc | O_NONBLOCK);
#else
#error "add support for setting the socket non-blocking here"
#endif
/* Create a session instance
*/
session = libssh2_session_init();
if(!session)
return -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;
}
/* 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
* 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(argc > 1) {
username = argv[1];
}
if(argc > 2) {
password = argv[2];
}
if(argc > 3) {
scppath = argv[3];
}
if (auth_pw) {
/* We could authenticate via password */
if (libssh2_userauth_password(session, username, password)) {
printf("Authentication by password failed.\n");
goto shutdown;
}
} else {
/* Or by public key */
if (libssh2_userauth_publickey_fromfile(session, username,
"/home/username/.ssh/id_rsa.pub",
"/home/username/.ssh/id_rsa",
password)) {
printf("\tAuthentication by public key failed\n");
goto shutdown;
}
}
/* Request a file via SCP */
channel = libssh2_scp_recv(session, scppath, &fileinfo);
if (!channel) {
fprintf(stderr, "Unable to open a session\n");
goto shutdown;
}
fprintf(stderr, "libssh2_scp_recv() is done, now receive data!\n");
while(got < fileinfo.st_size) {
char mem[1000];
struct timeval timeout;
int rc;
fd_set fd;
do {
int amount=sizeof(mem);
if((fileinfo.st_size -got) < amount) {
amount = fileinfo.st_size -got;
}
/* loop until we block */
rc = libssh2_channel_readnb(channel, mem, amount);
if(rc > 0) {
write(2, mem, rc);
got += rc;
}
} while (rc > 0);
if(rc == LIBSSH2CHANNEL_EAGAIN) {
/* this is due to blocking that would occur otherwise
so we loop on this condition */
timeout.tv_sec = 10;
timeout.tv_usec = 0;
FD_ZERO(&fd);
FD_SET(sock, &fd);
rc = select(sock+1, &fd, &fd, NULL, &timeout);
if(rc <= 0) {
/* negative is error
0 is timeout */
fprintf(stderr, "SCP timed out: %d\n", rc);
}
continue;
}
break;
}
libssh2_channel_free(channel);
channel = NULL;
shutdown:
libssh2_session_disconnect(session,
"Normal Shutdown, Thank you for playing");
libssh2_session_free(session);
#ifdef WIN32
Sleep(1000);
closesocket(sock);
#else
sleep(1);
close(sock);
#endif
printf("all done\n");
return 0;
}

186
example/simple/sftp.c Normal file
View File

@@ -0,0 +1,186 @@
/*
* $Id: sftp.c,v 1.7 2007/04/26 23:59:14 gknauf Exp $
*
* Sample showing how to do SFTP transfers.
*
* 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:
*
* "sftp 192.168.0.1 user password /tmp/secrets"
*/
#include <libssh2.h>
#include <libssh2_sftp.h>
#include <libssh2_config.h>
#ifdef HAVE_WINSOCK2_H
# include <winsock2.h>
#endif
#ifdef HAVE_NETINET_IN_H
# include <netinet/in.h>
#endif
#ifdef HAVE_SYS_SOCKET_H
# include <sys/socket.h>
#endif
# ifdef HAVE_UNISTD_H
#include <unistd.h>
#endif
#ifdef HAVE_ARPA_INET_H
# include <arpa/inet.h>
#endif
#ifdef HAVE_SYS_TIME_H
# include <sys/time.h>
#endif
#include <sys/types.h>
#include <fcntl.h>
#include <errno.h>
#include <stdio.h>
#include <ctype.h>
int main(int argc, char *argv[])
{
unsigned long hostaddr;
int sock, i, auth_pw = 1;
struct sockaddr_in sin;
const char *fingerprint;
LIBSSH2_SESSION *session;
char *username=(char *)"username";
char *password=(char *)"password";
char *sftppath=(char *)"/tmp/TEST";
int rc;
LIBSSH2_SFTP *sftp_session;
LIBSSH2_SFTP_HANDLE *sftp_handle;
#ifdef WIN32
WSADATA wsadata;
WSAStartup(WINSOCK_VERSION, &wsadata);
#endif
if (argc > 1) {
hostaddr = inet_addr(argv[1]);
} else {
hostaddr = htonl(0x7F000001);
}
if(argc > 2) {
username = argv[2];
}
if(argc > 3) {
password = argv[3];
}
if(argc > 4) {
sftppath = argv[4];
}
/*
* The application code is responsible for creating the socket
* and establishing the connection
*/
sock = socket(AF_INET, SOCK_STREAM, 0);
sin.sin_family = AF_INET;
sin.sin_port = htons(22);
sin.sin_addr.s_addr = hostaddr;
if (connect(sock, (struct sockaddr*)(&sin),
sizeof(struct sockaddr_in)) != 0) {
fprintf(stderr, "failed to connect!\n");
return -1;
}
/* Create a session instance
*/
session = libssh2_session_init();
if(!session)
return -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;
}
/* 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
* 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) {
/* We could authenticate via password */
if (libssh2_userauth_password(session, username, password)) {
printf("Authentication by password failed.\n");
goto shutdown;
}
} else {
/* Or by public key */
if (libssh2_userauth_publickey_fromfile(session, username,
"/home/username/.ssh/id_rsa.pub",
"/home/username/.ssh/id_rsa",
password)) {
printf("\tAuthentication by public key failed\n");
goto shutdown;
}
}
fprintf(stderr, "libssh2_sftp_init()!\n");
sftp_session = libssh2_sftp_init(session);
if (!sftp_session) {
fprintf(stderr, "Unable to init SFTP session\n");
goto shutdown;
}
/* Since we have not set non-blocking, tell libssh2 we are blocking */
libssh2_sftp_set_blocking(sftp_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(2, 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
Sleep(1000);
closesocket(sock);
#else
sleep(1);
close(sock);
#endif
printf("all done\n");
return 0;
}

View File

@@ -0,0 +1,293 @@
/*
* $Id: sftp_RW_nonblock.c,v 1.3 2007/04/26 23:59:15 gknauf Exp $
*
* Sample showing how to do SFTP transfers in a non-blocking manner.
*
* It will first download a given source file, store it locally and then
* upload the file again to a given destination file.
*
* Using the SFTP server running on 127.0.0.1
*/
#include <libssh2.h>
#include <libssh2_sftp.h>
#include <libssh2_config.h>
#ifdef HAVE_WINSOCK2_H
# include <winsock2.h>
#endif
#ifdef HAVE_NETINET_IN_H
# include <netinet/in.h>
#endif
#ifdef HAVE_SYS_SOCKET_H
# include <sys/socket.h>
#endif
# ifdef HAVE_UNISTD_H
#include <unistd.h>
#endif
#ifdef HAVE_ARPA_INET_H
# include <arpa/inet.h>
#endif
#ifdef HAVE_SYS_TIME_H
# include <sys/time.h>
#endif
#include <sys/types.h>
#include <fcntl.h>
#include <errno.h>
#include <stdio.h>
#include <ctype.h>
#define STORAGE "/tmp/sftp-storage" /* this is the local file name this
example uses to store the downloaded
file in */
int main(int argc, char *argv[])
{
int sock, i, auth_pw = 1;
struct sockaddr_in sin;
const char *fingerprint;
LIBSSH2_SESSION *session;
char *username=(char *)"username";
char *password=(char *)"password";
char *sftppath=(char *)"/tmp/TEST"; /* source path */
char *dest=(char *)"/tmp/TEST2"; /* destination path */
int rc;
LIBSSH2_SFTP *sftp_session;
LIBSSH2_SFTP_HANDLE *sftp_handle;
FILE *tempstorage;
char mem[1000];
struct timeval timeout;
fd_set fd;
#ifdef WIN32
WSADATA wsadata;
WSAStartup(WINSOCK_VERSION, &wsadata);
#endif
/* Ultra basic "connect to port 22 on localhost"
* The application is responsible for creating the socket establishing
* the connection
*/
sock = socket(AF_INET, SOCK_STREAM, 0);
sin.sin_family = AF_INET;
sin.sin_port = htons(22);
sin.sin_addr.s_addr = htonl(0x7F000001);
if (connect(sock, (struct sockaddr*)(&sin),
sizeof(struct sockaddr_in)) != 0) {
fprintf(stderr, "failed to connect!\n");
return -1;
}
/* We set the socket non-blocking. We do it after the connect just to
simplify the example code. */
#ifdef F_SETFL
/* FIXME: this can/should be done in a more portable manner */
rc = fcntl(sock, F_GETFL, 0);
fcntl(sock, F_SETFL, rc | O_NONBLOCK);
#else
#error "add support for setting the socket non-blocking here"
#endif
/* Create a session instance
*/
session = libssh2_session_init();
if(!session)
return -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;
}
/* 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
* 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(argc > 1) {
username = argv[1];
}
if(argc > 2) {
password = argv[2];
}
if(argc > 3) {
sftppath = argv[3];
}
if(argc > 4) {
dest = argv[4];
}
tempstorage = fopen(STORAGE, "wb");
if(!tempstorage) {
printf("Can't open temp storage file %s\n", STORAGE);
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 {
/* 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);
if (!sftp_session) {
fprintf(stderr, "Unable to init SFTP session\n");
goto shutdown;
}
/* 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 {
do {
/* read in a loop until we block */
rc = libssh2_sftp_readnb(sftp_handle, mem,
sizeof(mem));
fprintf(stderr, "libssh2_sftp_read returned %d\n",
rc);
if(rc > 0) {
/* write to stderr */
write(2, mem, rc);
/* write to temporary storage area */
fwrite(mem, rc, 1, tempstorage);
}
} while (rc > 0);
if(rc != LIBSSH2SFTP_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 download timed out: %d\n", rc);
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_writenb(sftp_handle, ptr,
nread);
ptr += rc;
nread -= nread;
} while (rc > 0);
if(rc != LIBSSH2SFTP_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
Sleep(1000);
closesocket(sock);
#else
sleep(1);
close(sock);
#endif
printf("all done\n");
return 0;
}

166
example/simple/sftp_mkdir.c Normal file
View File

@@ -0,0 +1,166 @@
/*
* $Id: sftp_mkdir.c,v 1.3 2007/04/26 23:59:15 gknauf Exp $
*
* Sample showing how to do SFTP mkdir
*
* 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:
*
* "sftp 192.168.0.1 user password /tmp/sftp_mkdir"
*/
#include <libssh2.h>
#include <libssh2_sftp.h>
#include <libssh2_config.h>
#ifdef HAVE_WINSOCK2_H
# include <winsock2.h>
#endif
#ifdef HAVE_NETINET_IN_H
# include <netinet/in.h>
#endif
#ifdef HAVE_SYS_SOCKET_H
# include <sys/socket.h>
#endif
# ifdef HAVE_UNISTD_H
#include <unistd.h>
#endif
#ifdef HAVE_ARPA_INET_H
# include <arpa/inet.h>
#endif
#include <sys/types.h>
#include <fcntl.h>
#include <errno.h>
#include <stdio.h>
#include <ctype.h>
int main(int argc, char *argv[])
{
unsigned long hostaddr;
int sock, i, auth_pw = 1;
struct sockaddr_in sin;
const char *fingerprint;
LIBSSH2_SESSION *session;
char *username=(char *)"username";
char *password=(char *)"password";
char *sftppath=(char *)"/tmp/sftp_mkdir";
int rc;
LIBSSH2_SFTP *sftp_session;
#ifdef WIN32
WSADATA wsadata;
WSAStartup(WINSOCK_VERSION, &wsadata);
#endif
if (argc > 1) {
hostaddr = inet_addr(argv[1]);
} else {
hostaddr = htonl(0x7F000001);
}
if(argc > 2) {
username = argv[2];
}
if(argc > 3) {
password = argv[3];
}
if(argc > 4) {
sftppath = argv[4];
}
/*
* The application code is responsible for creating the socket
* and establishing the connection
*/
sock = socket(AF_INET, SOCK_STREAM, 0);
sin.sin_family = AF_INET;
sin.sin_port = htons(22);
sin.sin_addr.s_addr = hostaddr;
if (connect(sock, (struct sockaddr*)(&sin),
sizeof(struct sockaddr_in)) != 0) {
fprintf(stderr, "failed to connect!\n");
return -1;
}
/* Create a session instance
*/
session = libssh2_session_init();
if(!session)
return -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;
}
/* 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
* 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) {
/* We could authenticate via password */
if (libssh2_userauth_password(session, username, password)) {
printf("Authentication by password failed.\n");
goto shutdown;
}
} else {
/* Or by public key */
if (libssh2_userauth_publickey_fromfile(session, username,
"/home/username/.ssh/id_rsa.pub",
"/home/username/.ssh/id_rsa",
password)) {
printf("\tAuthentication by public key failed\n");
goto shutdown;
}
}
fprintf(stderr, "libssh2_sftp_init()!\n");
sftp_session = libssh2_sftp_init(session);
if (!sftp_session) {
fprintf(stderr, "Unable to init SFTP session\n");
goto shutdown;
}
/* Since we have not set non-blocking, tell libssh2 we are blocking */
libssh2_sftp_set_blocking(sftp_session, 1);
fprintf(stderr, "libssh2_sftp_mkdir()!\n");
/* Make a directory via SFTP */
rc = libssh2_sftp_mkdir(sftp_session, sftppath,
LIBSSH2_SFTP_S_IRWXU|
LIBSSH2_SFTP_S_IRGRP|LIBSSH2_SFTP_S_IXGRP|
LIBSSH2_SFTP_S_IROTH|LIBSSH2_SFTP_S_IXOTH);
libssh2_sftp_shutdown(sftp_session);
shutdown:
libssh2_session_disconnect(session, "Normal Shutdown, Thank you for playing");
libssh2_session_free(session);
#ifdef WIN32
Sleep(1000);
closesocket(sock);
#else
sleep(1);
close(sock);
#endif
printf("all done\n");
return 0;
}

View File

@@ -0,0 +1,179 @@
/*
* $Id: sftp_mkdir_nonblock.c,v 1.3 2007/04/26 23:59:15 gknauf Exp $
*
* Sample showing how to do SFTP non-blocking mkdir.
*
* 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:
*
* "sftp 192.168.0.1 user password /tmp/sftp_write_nonblock.c"
*/
#include <libssh2.h>
#include <libssh2_sftp.h>
#include <libssh2_config.h>
#ifdef HAVE_WINSOCK2_H
# include <winsock2.h>
#endif
#ifdef HAVE_NETINET_IN_H
# include <netinet/in.h>
#endif
#ifdef HAVE_SYS_SOCKET_H
# include <sys/socket.h>
#endif
# ifdef HAVE_UNISTD_H
#include <unistd.h>
#endif
#ifdef HAVE_ARPA_INET_H
# include <arpa/inet.h>
#endif
#include <sys/types.h>
#include <fcntl.h>
#include <errno.h>
#include <stdio.h>
#include <ctype.h>
int main(int argc, char *argv[])
{
unsigned long hostaddr;
int sock, i, auth_pw = 1;
struct sockaddr_in sin;
const char *fingerprint;
LIBSSH2_SESSION *session;
char *username=(char *)"username";
char *password=(char *)"password";
char *sftppath=(char *)"/tmp/sftp_mkdir_nonblock";
int rc;
LIBSSH2_SFTP *sftp_session;
#ifdef WIN32
WSADATA wsadata;
WSAStartup(WINSOCK_VERSION, &wsadata);
#endif
if (argc > 1) {
hostaddr = inet_addr(argv[1]);
} else {
hostaddr = htonl(0x7F000001);
}
if(argc > 2) {
username = argv[2];
}
if(argc > 3) {
password = argv[3];
}
if(argc > 4) {
sftppath = argv[4];
}
/*
* The application code is responsible for creating the socket
* and establishing the connection
*/
sock = socket(AF_INET, SOCK_STREAM, 0);
sin.sin_family = AF_INET;
sin.sin_port = htons(22);
sin.sin_addr.s_addr = hostaddr;
if (connect(sock, (struct sockaddr*)(&sin),
sizeof(struct sockaddr_in)) != 0) {
fprintf(stderr, "failed to connect!\n");
return -1;
}
/* We set the socket non-blocking. We do it after the connect just to
simplify the example code. */
#ifdef F_SETFL
/* FIXME: this can/should be done in a more portable manner */
rc = fcntl(sock, F_GETFL, 0);
fcntl(sock, F_SETFL, rc | O_NONBLOCK);
#else
#error "add support for setting the socket non-blocking here"
#endif
/* Create a session instance
*/
session = libssh2_session_init();
if(!session)
return -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;
}
/* 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
* 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) {
/* We could authenticate via password */
if (libssh2_userauth_password(session, username, password)) {
printf("Authentication by password failed.\n");
goto shutdown;
}
} else {
/* Or by public key */
if (libssh2_userauth_publickey_fromfile(session, username,
"/home/username/.ssh/id_rsa.pub",
"/home/username/.ssh/id_rsa",
password)) {
printf("\tAuthentication by public key failed\n");
goto shutdown;
}
}
fprintf(stderr, "libssh2_sftp_init()!\n");
sftp_session = libssh2_sftp_init(session);
if (!sftp_session) {
fprintf(stderr, "Unable to init SFTP session\n");
goto shutdown;
}
/* Since we have set non-blocking, tell libssh2 we are non-blocking */
libssh2_sftp_set_blocking(sftp_session, 0);
fprintf(stderr, "libssh2_sftp_mkdirnb()!\n");
/* Make a directory via SFTP */
while ((rc = libssh2_sftp_mkdirnb(sftp_session, sftppath,
LIBSSH2_SFTP_S_IRWXU|
LIBSSH2_SFTP_S_IRGRP|LIBSSH2_SFTP_S_IXGRP|
LIBSSH2_SFTP_S_IROTH|LIBSSH2_SFTP_S_IXOTH))
== LIBSSH2SFTP_EAGAIN) {
;
}
libssh2_sftp_shutdown(sftp_session);
shutdown:
libssh2_session_disconnect(session, "Normal Shutdown, Thank you for playing");
libssh2_session_free(session);
#ifdef WIN32
Sleep(1000);
closesocket(sock);
#else
sleep(1);
close(sock);
#endif
printf("all done\n");
return 0;
}

View File

@@ -0,0 +1,198 @@
/*
* $Id: sftp_nonblock.c,v 1.7 2007/04/26 23:59:15 gknauf Exp $
*
* Sample showing how to do SFTP non-blocking transfers.
*
* 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:
*
* "sftp 192.168.0.1 user password /tmp/secrets"
*/
#include <libssh2.h>
#include <libssh2_sftp.h>
#include <libssh2_config.h>
#ifdef HAVE_WINSOCK2_H
# include <winsock2.h>
#endif
#ifdef HAVE_NETINET_IN_H
# include <netinet/in.h>
#endif
#ifdef HAVE_SYS_SOCKET_H
# include <sys/socket.h>
#endif
# ifdef HAVE_UNISTD_H
#include <unistd.h>
#endif
#ifdef HAVE_ARPA_INET_H
# include <arpa/inet.h>
#endif
#ifdef HAVE_SYS_TIME_H
# include <sys/time.h>
#endif
#include <sys/types.h>
#include <fcntl.h>
#include <errno.h>
#include <stdio.h>
#include <ctype.h>
int main(int argc, char *argv[])
{
unsigned long hostaddr;
int sock, i, auth_pw = 1;
struct sockaddr_in sin;
const char *fingerprint;
LIBSSH2_SESSION *session;
char *username=(char *)"username";
char *password=(char *)"password";
char *sftppath=(char *)"/tmp/TEST";
int rc;
LIBSSH2_SFTP *sftp_session;
LIBSSH2_SFTP_HANDLE *sftp_handle;
#ifdef WIN32
WSADATA wsadata;
WSAStartup(WINSOCK_VERSION, &wsadata);
#endif
if (argc > 1) {
hostaddr = inet_addr(argv[1]);
} else {
hostaddr = htonl(0x7F000001);
}
if(argc > 2) {
username = argv[2];
}
if(argc > 3) {
password = argv[3];
}
if(argc > 4) {
sftppath = argv[4];
}
/*
* The application code is responsible for creating the socket
* and establishing the connection
*/
sock = socket(AF_INET, SOCK_STREAM, 0);
sin.sin_family = AF_INET;
sin.sin_port = htons(22);
sin.sin_addr.s_addr = hostaddr;
if (connect(sock, (struct sockaddr*)(&sin),
sizeof(struct sockaddr_in)) != 0) {
fprintf(stderr, "failed to connect!\n");
return -1;
}
/* We set the socket non-blocking. We do it after the connect just to
simplify the example code. */
#ifdef F_SETFL
/* FIXME: this can/should be done in a more portable manner */
rc = fcntl(sock, F_GETFL, 0);
fcntl(sock, F_SETFL, rc | O_NONBLOCK);
#else
#error "add support for setting the socket non-blocking here"
#endif
/* Create a session instance
*/
session = libssh2_session_init();
if(!session)
return -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;
}
/* 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
* 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) {
/* We could authenticate via password */
if (libssh2_userauth_password(session, username, password)) {
printf("Authentication by password failed.\n");
goto shutdown;
}
} else {
/* Or by public key */
if (libssh2_userauth_publickey_fromfile(session, username,
"/home/username/.ssh/id_rsa.pub",
"/home/username/.ssh/id_rsa",
password)) {
printf("\tAuthentication by public key failed\n");
goto shutdown;
}
}
fprintf(stderr, "libssh2_sftp_init()!\n");
sftp_session = libssh2_sftp_init(session);
if (!sftp_session) {
fprintf(stderr, "Unable to init SFTP session\n");
goto shutdown;
}
/* Since we have set non-blocking, tell libssh2 we are non-blocking */
libssh2_sftp_set_blocking(sftp_session, 0);
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_readnb()!\n");
while ((rc = libssh2_sftp_readnb(sftp_handle, mem, sizeof(mem))) == LIBSSH2SFTP_EAGAIN) {
;
}
if (rc > 0) {
write(2, 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
Sleep(1000);
closesocket(sock);
#else
sleep(1);
close(sock);
#endif
printf("all done\n");
return 0;
}

205
example/simple/sftp_write.c Normal file
View File

@@ -0,0 +1,205 @@
/*
* $Id: sftp_write.c,v 1.3 2007/04/26 23:59:15 gknauf Exp $
*
* Sample showing how to do SFTP write transfers.
*
* 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:
*
* "sftp 192.168.0.1 user password sftp_write.c /tmp/secrets"
*/
#include <libssh2.h>
#include <libssh2_sftp.h>
#include <libssh2_config.h>
#ifdef HAVE_WINSOCK2_H
# include <winsock2.h>
#endif
#ifdef HAVE_NETINET_IN_H
# include <netinet/in.h>
#endif
#ifdef HAVE_SYS_SOCKET_H
# include <sys/socket.h>
#endif
# ifdef HAVE_UNISTD_H
#include <unistd.h>
#endif
#ifdef HAVE_ARPA_INET_H
# include <arpa/inet.h>
#endif
#include <sys/types.h>
#include <fcntl.h>
#include <errno.h>
#include <stdio.h>
#include <ctype.h>
int main(int argc, char *argv[])
{
unsigned long hostaddr;
int sock, i, auth_pw = 1;
struct sockaddr_in sin;
const char *fingerprint;
LIBSSH2_SESSION *session;
char *username=(char *)"username";
char *password=(char *)"password";
char *loclfile=(char *)"sftp_write.c";
char *sftppath=(char *)"/tmp/TEST";
int rc;
FILE *local;
LIBSSH2_SFTP *sftp_session;
LIBSSH2_SFTP_HANDLE *sftp_handle;
char mem[1024];
size_t nread;
char *ptr;
#ifdef WIN32
WSADATA wsadata;
WSAStartup(WINSOCK_VERSION, &wsadata);
#endif
if (argc > 1) {
hostaddr = inet_addr(argv[1]);
} else {
hostaddr = htonl(0x7F000001);
}
if(argc > 2) {
username = argv[2];
}
if(argc > 3) {
password = argv[3];
}
if(argc > 4) {
loclfile = argv[4];
}
if(argc > 5) {
sftppath = argv[5];
}
local = fopen(loclfile, "rb");
if (!local) {
printf("Can't local file %s\n", loclfile);
goto shutdown;
}
/*
* The application code is responsible for creating the socket
* and establishing the connection
*/
sock = socket(AF_INET, SOCK_STREAM, 0);
sin.sin_family = AF_INET;
sin.sin_port = htons(22);
sin.sin_addr.s_addr = hostaddr;
if (connect(sock, (struct sockaddr*)(&sin),
sizeof(struct sockaddr_in)) != 0) {
fprintf(stderr, "failed to connect!\n");
return -1;
}
/* Create a session instance
*/
session = libssh2_session_init();
if(!session)
return -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;
}
/* 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
* 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) {
/* We could authenticate via password */
if (libssh2_userauth_password(session, username, password)) {
printf("Authentication by password failed.\n");
goto shutdown;
}
} else {
/* Or by public key */
if (libssh2_userauth_publickey_fromfile(session, username,
"/home/username/.ssh/id_rsa.pub",
"/home/username/.ssh/id_rsa",
password)) {
printf("\tAuthentication by public key failed\n");
goto shutdown;
}
}
fprintf(stderr, "libssh2_sftp_init()!\n");
sftp_session = libssh2_sftp_init(session);
if (!sftp_session) {
fprintf(stderr, "Unable to init SFTP session\n");
goto shutdown;
}
/* Since we have not set non-blocking, tell libssh2 we are blocking */
libssh2_sftp_set_blocking(sftp_session, 1);
fprintf(stderr, "libssh2_sftp_open()!\n");
/* Request a file via SFTP */
sftp_handle =
libssh2_sftp_open(sftp_session, sftppath,
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) {
fprintf(stderr, "Unable to open file with SFTP\n");
goto shutdown;
}
fprintf(stderr, "libssh2_sftp_open() is done, now send data!\n");
do {
nread = fread(mem, 1, sizeof(mem), local);
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);
} while (1);
fclose(local);
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
Sleep(1000);
closesocket(sock);
#else
sleep(1);
close(sock);
#endif
printf("all done\n");
return 0;
}

View File

@@ -0,0 +1,217 @@
/*
* $Id: sftp_write_nonblock.c,v 1.3 2007/04/26 23:59:15 gknauf Exp $
*
* Sample showing how to do SFTP non-blocking write transfers.
*
* 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:
*
* "sftp 192.168.0.1 user password sftp_write_nonblock.c /tmp/sftp_write_nonblock.c"
*/
#include <libssh2.h>
#include <libssh2_sftp.h>
#include <libssh2_config.h>
#ifdef HAVE_WINSOCK2_H
# include <winsock2.h>
#endif
#ifdef HAVE_NETINET_IN_H
# include <netinet/in.h>
#endif
#ifdef HAVE_SYS_SOCKET_H
# include <sys/socket.h>
#endif
# ifdef HAVE_UNISTD_H
#include <unistd.h>
#endif
#ifdef HAVE_ARPA_INET_H
# include <arpa/inet.h>
#endif
#include <sys/types.h>
#include <fcntl.h>
#include <errno.h>
#include <stdio.h>
#include <ctype.h>
int main(int argc, char *argv[])
{
unsigned long hostaddr;
int sock, i, auth_pw = 1;
struct sockaddr_in sin;
const char *fingerprint;
LIBSSH2_SESSION *session;
char *username=(char *)"username";
char *password=(char *)"password";
char *loclfile=(char *)"sftp_write_nonblock.c";
char *sftppath=(char *)"/tmp/sftp_write_nonblock.c";
int rc;
FILE *local;
LIBSSH2_SFTP *sftp_session;
LIBSSH2_SFTP_HANDLE *sftp_handle;
char mem[1024];
size_t nread;
char *ptr;
#ifdef WIN32
WSADATA wsadata;
WSAStartup(WINSOCK_VERSION, &wsadata);
#endif
if (argc > 1) {
hostaddr = inet_addr(argv[1]);
} else {
hostaddr = htonl(0x7F000001);
}
if(argc > 2) {
username = argv[2];
}
if(argc > 3) {
password = argv[3];
}
if(argc > 4) {
loclfile = argv[4];
}
if(argc > 5) {
sftppath = argv[5];
}
local = fopen(loclfile, "rb");
if (!local) {
printf("Can't local file %s\n", loclfile);
goto shutdown;
}
/*
* The application code is responsible for creating the socket
* and establishing the connection
*/
sock = socket(AF_INET, SOCK_STREAM, 0);
sin.sin_family = AF_INET;
sin.sin_port = htons(22);
sin.sin_addr.s_addr = hostaddr;
if (connect(sock, (struct sockaddr*)(&sin),
sizeof(struct sockaddr_in)) != 0) {
fprintf(stderr, "failed to connect!\n");
return -1;
}
/* We set the socket non-blocking. We do it after the connect just to
simplify the example code. */
#ifdef F_SETFL
/* FIXME: this can/should be done in a more portable manner */
rc = fcntl(sock, F_GETFL, 0);
fcntl(sock, F_SETFL, rc | O_NONBLOCK);
#else
#error "add support for setting the socket non-blocking here"
#endif
/* Create a session instance
*/
session = libssh2_session_init();
if(!session)
return -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;
}
/* 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
* 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) {
/* We could authenticate via password */
if (libssh2_userauth_password(session, username, password)) {
printf("Authentication by password failed.\n");
goto shutdown;
}
} else {
/* Or by public key */
if (libssh2_userauth_publickey_fromfile(session, username,
"/home/username/.ssh/id_rsa.pub",
"/home/username/.ssh/id_rsa",
password)) {
printf("\tAuthentication by public key failed\n");
goto shutdown;
}
}
fprintf(stderr, "libssh2_sftp_init()!\n");
sftp_session = libssh2_sftp_init(session);
if (!sftp_session) {
fprintf(stderr, "Unable to init SFTP session\n");
goto shutdown;
}
/* Since we have set non-blocking, tell libssh2 we are non-blocking */
libssh2_sftp_set_blocking(sftp_session, 0);
fprintf(stderr, "libssh2_sftp_open()!\n");
/* Request a file via SFTP */
sftp_handle =
libssh2_sftp_open(sftp_session, sftppath,
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) {
fprintf(stderr, "Unable to open file with SFTP\n");
goto shutdown;
}
fprintf(stderr, "libssh2_sftp_open() is done, now send data!\n");
do {
nread = fread(mem, 1, sizeof(mem), local);
if (nread <= 0) {
/* end of file */
break;
}
ptr = mem;
do {
/* write data in a loop until we block */
while ((rc = libssh2_sftp_writenb(sftp_handle, ptr, nread)) == LIBSSH2SFTP_EAGAIN) {
;
}
ptr += rc;
nread -= nread;
} while (rc > 0);
} while (1);
fclose(local);
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
Sleep(1000);
closesocket(sock);
#else
sleep(1);
close(sock);
#endif
printf("all done\n");
return 0;
}

213
example/simple/sftpdir.c Normal file
View File

@@ -0,0 +1,213 @@
/*
* $Id: sftpdir.c,v 1.4 2007/04/26 23:59:15 gknauf Exp $
*
* Sample doing an SFTP directory listing.
*
* The sample code has default values for host name, user name, password and
* path, but you can specify them on the command line like:
*
* "sftpdir 192.168.0.1 user password /tmp/secretdir"
*/
#include <libssh2.h>
#include <libssh2_sftp.h>
#include <libssh2_config.h>
#ifdef HAVE_WINSOCK2_H
# include <winsock2.h>
#endif
#ifdef HAVE_NETINET_IN_H
# include <netinet/in.h>
#endif
#ifdef HAVE_SYS_SOCKET_H
# include <sys/socket.h>
#endif
# ifdef HAVE_UNISTD_H
#include <unistd.h>
#endif
#ifdef HAVE_ARPA_INET_H
# include <arpa/inet.h>
#endif
#include <sys/types.h>
#include <fcntl.h>
#include <errno.h>
#include <stdio.h>
#include <ctype.h>
int main(int argc, char *argv[])
{
unsigned long hostaddr;
int sock, i, auth_pw = 1;
struct sockaddr_in sin;
const char *fingerprint;
LIBSSH2_SESSION *session;
char *username=(char *)"username";
char *password=(char *)"password";
char *sftppath=(char *)"/tmp/secretdir";
int rc;
LIBSSH2_SFTP *sftp_session;
LIBSSH2_SFTP_HANDLE *sftp_handle;
#ifdef WIN32
WSADATA wsadata;
WSAStartup(WINSOCK_VERSION, &wsadata);
#endif
if (argc > 1) {
hostaddr = inet_addr(argv[1]);
} else {
hostaddr = htonl(0x7F000001);
}
if(argc > 2) {
username = argv[2];
}
if(argc > 3) {
password = argv[3];
}
if(argc > 4) {
sftppath = argv[4];
}
/*
* The application code is responsible for creating the socket
* and establishing the connection
*/
sock = socket(AF_INET, SOCK_STREAM, 0);
sin.sin_family = AF_INET;
sin.sin_port = htons(22);
sin.sin_addr.s_addr = hostaddr;
if (connect(sock, (struct sockaddr*)(&sin),
sizeof(struct sockaddr_in)) != 0) {
fprintf(stderr, "failed to connect!\n");
return -1;
}
/* Create a session instance
*/
session = libssh2_session_init();
if(!session)
return -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;
}
/* 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
* 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) {
/* We could authenticate via password */
if (libssh2_userauth_password(session, username, password)) {
printf("Authentication by password failed.\n");
goto shutdown;
}
} else {
/* Or by public key */
if (libssh2_userauth_publickey_fromfile(session, username,
"/home/username/.ssh/id_rsa.pub",
"/home/username/.ssh/id_rsa",
password)) {
printf("\tAuthentication by public key failed\n");
goto shutdown;
}
}
fprintf(stderr, "libssh2_sftp_init()!\n");
sftp_session = libssh2_sftp_init(session);
if (!sftp_session) {
fprintf(stderr, "Unable to init SFTP session\n");
goto shutdown;
}
/* Since we have not set non-blocking, tell libssh2 we are blocking */
libssh2_sftp_set_blocking(sftp_session, 1);
fprintf(stderr, "libssh2_sftp_opendir()!\n");
/* Request a dir listing via SFTP */
sftp_handle = libssh2_sftp_opendir(sftp_session, sftppath);
if (!sftp_handle) {
fprintf(stderr, "Unable to open dir with SFTP\n");
goto shutdown;
}
fprintf(stderr, "libssh2_sftp_opendir() is done, now receive listing!\n");
do {
char mem[512];
LIBSSH2_SFTP_ATTRIBUTES attrs;
/* loop until we fail */
rc = libssh2_sftp_readdir(sftp_handle, mem, sizeof(mem),
&attrs);
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("---------- ");
}
if(attrs.flags & LIBSSH2_SFTP_ATTR_UIDGID) {
printf("%4ld %4ld ", attrs.uid, attrs.gid);
}
else {
printf(" - - ");
}
if(attrs.flags & LIBSSH2_SFTP_ATTR_SIZE) {
/* 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);
}
printf("%s\n", mem);
}
else
break;
} while (1);
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
Sleep(1000);
closesocket(sock);
#else
sleep(1);
close(sock);
#endif
printf("all done\n");
return 0;
}

View File

@@ -0,0 +1,227 @@
/*
* $Id: sftpdir_nonblock.c,v 1.4 2007/04/26 23:59:15 gknauf Exp $
*
* Sample doing an SFTP directory listing.
*
* The sample code has default values for host name, user name, password and
* path, but you can specify them on the command line like:
*
* "sftpdir 192.168.0.1 user password /tmp/secretdir"
*/
#include <libssh2.h>
#include <libssh2_sftp.h>
#include <libssh2_config.h>
#ifdef HAVE_WINSOCK2_H
# include <winsock2.h>
#endif
#ifdef HAVE_NETINET_IN_H
# include <netinet/in.h>
#endif
#ifdef HAVE_SYS_SOCKET_H
# include <sys/socket.h>
#endif
# ifdef HAVE_UNISTD_H
#include <unistd.h>
#endif
#ifdef HAVE_ARPA_INET_H
# include <arpa/inet.h>
#endif
#include <sys/types.h>
#include <fcntl.h>
#include <errno.h>
#include <stdio.h>
#include <ctype.h>
int main(int argc, char *argv[])
{
unsigned long hostaddr;
int sock, i, auth_pw = 1;
struct sockaddr_in sin;
const char *fingerprint;
LIBSSH2_SESSION *session;
char *username=(char *)"username";
char *password=(char *)"password";
char *sftppath=(char *)"/tmp/secretdir";
int rc;
LIBSSH2_SFTP *sftp_session;
LIBSSH2_SFTP_HANDLE *sftp_handle;
#ifdef WIN32
WSADATA wsadata;
WSAStartup(WINSOCK_VERSION, &wsadata);
#endif
if (argc > 1) {
hostaddr = inet_addr(argv[1]);
} else {
hostaddr = htonl(0x7F000001);
}
if(argc > 2) {
username = argv[2];
}
if(argc > 3) {
password = argv[3];
}
if(argc > 4) {
sftppath = argv[4];
}
/*
* The application code is responsible for creating the socket
* and establishing the connection
*/
sock = socket(AF_INET, SOCK_STREAM, 0);
sin.sin_family = AF_INET;
sin.sin_port = htons(22);
sin.sin_addr.s_addr = hostaddr;
if (connect(sock, (struct sockaddr*)(&sin),
sizeof(struct sockaddr_in)) != 0) {
fprintf(stderr, "failed to connect!\n");
return -1;
}
/* We set the socket non-blocking. We do it after the connect just to
simplify the example code. */
#ifdef F_SETFL
/* FIXME: this can/should be done in a more portable manner */
rc = fcntl(sock, F_GETFL, 0);
fcntl(sock, F_SETFL, rc | O_NONBLOCK);
#else
#error "add support for setting the socket non-blocking here"
#endif
/* Create a session instance
*/
session = libssh2_session_init();
if(!session)
return -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;
}
/* 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
* 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) {
/* We could authenticate via password */
if (libssh2_userauth_password(session, username, password)) {
printf("Authentication by password failed.\n");
goto shutdown;
}
} else {
/* Or by public key */
if (libssh2_userauth_publickey_fromfile(session, username,
"/home/username/.ssh/id_rsa.pub",
"/home/username/.ssh/id_rsa",
password)) {
printf("\tAuthentication by public key failed\n");
goto shutdown;
}
}
fprintf(stderr, "libssh2_sftp_init()!\n");
sftp_session = libssh2_sftp_init(session);
if (!sftp_session) {
fprintf(stderr, "Unable to init SFTP session\n");
goto shutdown;
}
/* Since we have set non-blocking, tell libssh2 we are non-blocking */
libssh2_sftp_set_blocking(sftp_session, 0);
fprintf(stderr, "libssh2_sftp_opendir()!\n");
/* Request a dir listing via SFTP */
sftp_handle = libssh2_sftp_opendir(sftp_session, sftppath);
if (!sftp_handle) {
fprintf(stderr, "Unable to open dir with SFTP\n");
goto shutdown;
}
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_readdirnb(sftp_handle, mem, sizeof(mem), &attrs)) == LIBSSH2SFTP_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("---------- ");
}
if(attrs.flags & LIBSSH2_SFTP_ATTR_UIDGID) {
printf("%4ld %4ld ", attrs.uid, attrs.gid);
} else {
printf(" - - ");
}
if(attrs.flags & LIBSSH2_SFTP_ATTR_SIZE) {
/* 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);
}
printf("%s\n", mem);
}
else if (rc == LIBSSH2SFTP_EAGAIN) {
/* blocking */
fprintf(stderr, "Blocking\n");
} else {
break;
}
} while (1);
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
Sleep(1000);
closesocket(sock);
#else
sleep(1);
close(sock);
#endif
printf("all done\n");
return 0;
}

View File

@@ -1,12 +1,30 @@
#include "libssh2.h" /*
* $Id: ssh2.c,v 1.3 2007/04/26 23:59:15 gknauf Exp $
*
* Sample showing how to do SSH2 connect.
*
* 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:
*
* "ssh2 host user password"
*/
#ifndef WIN32 #include <libssh2.h>
# include <netinet/in.h> #include <libssh2_sftp.h>
# include <sys/socket.h> #include <libssh2_config.h>
# include <unistd.h>
#else #ifdef HAVE_WINSOCK2_H
# include <winsock2.h> # include <winsock2.h>
#endif #endif
#ifdef HAVE_NETINET_IN_H
# include <netinet/in.h>
#endif
#ifdef HAVE_SYS_SOCKET_H
# include <sys/socket.h>
#endif
# ifdef HAVE_UNISTD_H
#include <unistd.h>
#endif
#include <sys/types.h> #include <sys/types.h>
#include <fcntl.h> #include <fcntl.h>
@@ -14,18 +32,35 @@
#include <stdio.h> #include <stdio.h>
#include <ctype.h> #include <ctype.h>
int main(int argc, char *argv[]) { int main(int argc, char *argv[])
{
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;
LIBSSH2_CHANNEL *channel; LIBSSH2_CHANNEL *channel;
char *username=(char *)"username";
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) {
hostaddr = inet_addr(argv[1]);
} else {
hostaddr = htonl(0x7F000001);
}
if(argc > 2) {
username = argv[2];
}
if(argc > 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
*/ */
@@ -35,8 +70,9 @@ int main(int argc, char *argv[]) {
#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 = htonl(0x7F000001); sin.sin_addr.s_addr = hostaddr;
if (connect(sock, (struct sockaddr*)(&sin), sizeof(struct sockaddr_in)) != 0) { if (connect(sock, (struct sockaddr*)(&sin),
sizeof(struct sockaddr_in)) != 0) {
fprintf(stderr, "failed to connect!\n"); fprintf(stderr, "failed to connect!\n");
return -1; return -1;
} }
@@ -63,13 +99,13 @@ int main(int argc, char *argv[]) {
if (auth_pw) { if (auth_pw) {
/* We could authenticate via password */ /* We could authenticate via password */
if (libssh2_userauth_password(session, "username", "password")) { if (libssh2_userauth_password(session, username, password)) {
printf("Authentication by password failed.\n"); printf("Authentication by password failed.\n");
goto shutdown; goto shutdown;
} }
} else { } else {
/* Or by public key */ /* Or by public key */
if (libssh2_userauth_publickey_fromfile(session, "username", "/home/username/.ssh/id_rsa.pub", "/home/username/.ssh/id_rsa", "pasphrase")) { 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"); printf("\tAuthentication by public key failed\n");
goto shutdown; goto shutdown;
} }
@@ -84,12 +120,12 @@ int main(int argc, char *argv[]) {
/* Some environment variables may be set, /* Some environment variables may be set,
* It's up to the server which ones it'll allow though * It's up to the server which ones it'll allow though
*/ */
libssh2_channel_setenv(channel, "FOO", "bar"); libssh2_channel_setenv(channel, (char *)"FOO", (char *)"bar");
/* Request a terminal with 'vanilla' terminal emulation /* Request a terminal with 'vanilla' terminal emulation
* See /etc/termcap for more options * See /etc/termcap for more options
*/ */
if (libssh2_channel_request_pty(channel, "vanilla")) { if (libssh2_channel_request_pty(channel, (char *)"vanilla")) {
fprintf(stderr, "Failed requesting pty\n"); fprintf(stderr, "Failed requesting pty\n");
goto skip_shell; goto skip_shell;
} }

20
get_ver.awk Executable file
View File

@@ -0,0 +1,20 @@
# fetch libssh2 version number from input file and write them to STDOUT
BEGIN {
while ((getline < ARGV[1]) > 0) {
if (match ($0, /^#define LIBSSH2_VERSION[\s|\t]+"[^"]+"/)) {
my_ver_str = substr($3, 2, length($3) - 2);
split(my_ver_str, v, ".");
if (v[3])
gsub("[^0-9].*$", "", v[3]);
else
v[3] = 0;
if (v[2])
gsub("[^0-9].*$", "", v[2]);
else
v[2] = 0;
my_ver = v[1] "," v[2] "," v[3];
}
}
print "LIBSSH2_VERSION = " my_ver "";
print "LIBSSH2_VERSION_STR = " my_ver_str "";
}

View File

@@ -1,4 +1,4 @@
/* Copyright (c) 2004-2005, Sara Golemon <sarag@libssh2.org> /* Copyright (c) 2004-2007, Sara Golemon <sarag@libssh2.org>
* All rights reserved. * All rights reserved.
* *
* Redistribution and use in source and binary forms, * Redistribution and use in source and binary forms,
@@ -59,19 +59,23 @@ extern "C" {
# endif /* LIBSSH2_WIN32 */ # endif /* LIBSSH2_WIN32 */
#endif /* LIBSSH2_API */ #endif /* LIBSSH2_API */
#if defined(LIBSSH2_DARWIN) || (defined(LIBSSH2_WIN32) && !defined(_MSC_VER)) #if defined(LIBSSH2_DARWIN) || (defined(LIBSSH2_WIN32) && !defined(_MSC_VER) && !defined(__MINGW32__))
# include <sys/uio.h> # include <sys/uio.h>
#endif #endif
#if defined(LIBSSH2_WIN32) && _MSC_VER < 1300 #if defined(LIBSSH2_WIN32) && defined(_MSC_VER) && (_MSC_VER < 1300)
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;
#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.12" #define LIBSSH2_VERSION "0.15-CVS"
#define LIBSSH2_APINO 200507211326 #define LIBSSH2_APINO 200507211326
/* Part of every banner, user specified or not */ /* Part of every banner, user specified or not */
@@ -133,7 +137,7 @@ typedef struct _LIBSSH2_USERAUTH_KBDINT_RESPONSE
#define LIBSSH2_DISCONNECT_FUNC(name) void name(LIBSSH2_SESSION *session, int reason, const char *message, int message_len, const char *language, int language_len, void **abstract) #define LIBSSH2_DISCONNECT_FUNC(name) void name(LIBSSH2_SESSION *session, int reason, const char *message, int message_len, const char *language, int language_len, void **abstract)
#define LIBSSH2_PASSWD_CHANGEREQ_FUNC(name) void name(LIBSSH2_SESSION *session, char **newpw, int *newpw_len, void **abstract) #define LIBSSH2_PASSWD_CHANGEREQ_FUNC(name) void name(LIBSSH2_SESSION *session, char **newpw, int *newpw_len, void **abstract)
#define LIBSSH2_MACERROR_FUNC(name) int name(LIBSSH2_SESSION *session, const char *packet, int packet_len, void **abstract) #define LIBSSH2_MACERROR_FUNC(name) int name(LIBSSH2_SESSION *session, const char *packet, int packet_len, void **abstract)
#define LIBSSH2_X11_OPEN_FUNC(name) void name(LIBSSH2_SESSION *session, LIBSSH2_CHANNEL *channel, char *shost, int sport, void **abstract) #define LIBSSH2_X11_OPEN_FUNC(name) void name(LIBSSH2_SESSION *session, LIBSSH2_CHANNEL *channel, const char *shost, int sport, void **abstract)
#define LIBSSH2_CHANNEL_CLOSE_FUNC(name) void name(LIBSSH2_SESSION *session, void **session_abstract, LIBSSH2_CHANNEL *channel, void **channel_abstract) #define LIBSSH2_CHANNEL_CLOSE_FUNC(name) void name(LIBSSH2_SESSION *session, void **session_abstract, LIBSSH2_CHANNEL *channel, void **channel_abstract)
@@ -277,21 +281,21 @@ LIBSSH2_API int libssh2_session_last_error(LIBSSH2_SESSION *session, char **errm
LIBSSH2_API int libssh2_session_flag(LIBSSH2_SESSION *session, int flag, int value); LIBSSH2_API int libssh2_session_flag(LIBSSH2_SESSION *session, int flag, int value);
/* Userauth API */ /* Userauth API */
LIBSSH2_API char *libssh2_userauth_list(LIBSSH2_SESSION *session, const char *username, int username_len); LIBSSH2_API char *libssh2_userauth_list(LIBSSH2_SESSION *session, const char *username, unsigned int username_len);
LIBSSH2_API int libssh2_userauth_authenticated(LIBSSH2_SESSION *session); LIBSSH2_API int libssh2_userauth_authenticated(LIBSSH2_SESSION *session);
LIBSSH2_API int libssh2_userauth_password_ex(LIBSSH2_SESSION *session, const char *username, int username_len, const char *password, int password_len, LIBSSH2_PASSWD_CHANGEREQ_FUNC((*passwd_change_cb))); LIBSSH2_API int libssh2_userauth_password_ex(LIBSSH2_SESSION *session, const char *username, unsigned int username_len, const char *password, unsigned int password_len, LIBSSH2_PASSWD_CHANGEREQ_FUNC((*passwd_change_cb)));
#define libssh2_userauth_password(session, username, password) libssh2_userauth_password_ex((session), (username), strlen(username), (password), strlen(password), NULL) #define libssh2_userauth_password(session, username, password) libssh2_userauth_password_ex((session), (username), strlen(username), (password), strlen(password), NULL)
LIBSSH2_API int libssh2_userauth_publickey_fromfile_ex(LIBSSH2_SESSION *session, const char *username, int username_len, LIBSSH2_API int libssh2_userauth_publickey_fromfile_ex(LIBSSH2_SESSION *session, const char *username, unsigned int username_len,
const char *publickey, const char *privatekey, const char *publickey, const char *privatekey,
const char *passphrase); const char *passphrase);
#define libssh2_userauth_publickey_fromfile(session, username, publickey, privatekey, passphrase) \ #define libssh2_userauth_publickey_fromfile(session, username, publickey, privatekey, passphrase) \
libssh2_userauth_publickey_fromfile_ex((session), (username), strlen(username), (publickey), (privatekey), (passphrase)) libssh2_userauth_publickey_fromfile_ex((session), (username), strlen(username), (publickey), (privatekey), (passphrase))
LIBSSH2_API int libssh2_userauth_hostbased_fromfile_ex(LIBSSH2_SESSION *session, const char *username, int username_len, LIBSSH2_API int libssh2_userauth_hostbased_fromfile_ex(LIBSSH2_SESSION *session, const char *username, unsigned int username_len,
const char *publickey, const char *privatekey, const char *publickey, const char *privatekey,
const char *passphrase, const char *passphrase,
const char *hostname, int hostname_len, const char *hostname, unsigned int hostname_len,
const char *local_username, int local_username_len); const char *local_username, unsigned int local_username_len);
#define libssh2_userauth_hostbased_fromfile(session, username, publickey, privatekey, passphrase, hostname) \ #define libssh2_userauth_hostbased_fromfile(session, username, publickey, privatekey, passphrase, hostname) \
libssh2_userauth_hostbased_fromfile_ex((session), (username), strlen(username), (publickey), (privatekey), (passphrase), (hostname), strlen(hostname), (username), strlen(username)) libssh2_userauth_hostbased_fromfile_ex((session), (username), strlen(username), (publickey), (privatekey), (passphrase), (hostname), strlen(hostname), (username), strlen(username))
@@ -301,7 +305,7 @@ LIBSSH2_API int libssh2_userauth_hostbased_fromfile_ex(LIBSSH2_SESSION *session,
* array is already allocated. Responses data will be freed by libssh2 * array is already allocated. Responses data will be freed by libssh2
* after callback return, but before subsequent callback invokation. * after callback return, but before subsequent callback invokation.
*/ */
LIBSSH2_API int libssh2_userauth_keyboard_interactive_ex(LIBSSH2_SESSION* session, const char *username, int username_len, LIBSSH2_API int libssh2_userauth_keyboard_interactive_ex(LIBSSH2_SESSION* session, const char *username, unsigned int username_len,
LIBSSH2_USERAUTH_KBDINT_RESPONSE_FUNC((*response_callback))); LIBSSH2_USERAUTH_KBDINT_RESPONSE_FUNC((*response_callback)));
#define libssh2_userauth_keyboard_interactive(session, username, response_callback) \ #define libssh2_userauth_keyboard_interactive(session, username, response_callback) \
libssh2_userauth_keyboard_interactive_ex((session), (username), strlen(username), (response_callback)) libssh2_userauth_keyboard_interactive_ex((session), (username), strlen(username), (response_callback))
@@ -320,36 +324,49 @@ LIBSSH2_API int libssh2_poll(LIBSSH2_POLLFD *fds, unsigned int nfds, long timeou
#define SSH_EXTENDED_DATA_STDERR 1 #define SSH_EXTENDED_DATA_STDERR 1
LIBSSH2_API LIBSSH2_CHANNEL *libssh2_channel_open_ex(LIBSSH2_SESSION *session, const char *channel_type, int channel_type_len, int window_size, int packet_size, const char *message, int message_len); LIBSSH2_API LIBSSH2_CHANNEL *libssh2_channel_open_ex(LIBSSH2_SESSION *session, const char *channel_type, unsigned int channel_type_len, unsigned int window_size, unsigned int packet_size, const char *message, unsigned int message_len);
#define libssh2_channel_open_session(session) libssh2_channel_open_ex((session), "session", sizeof("session") - 1, LIBSSH2_CHANNEL_WINDOW_DEFAULT, LIBSSH2_CHANNEL_PACKET_DEFAULT, NULL, 0) #define libssh2_channel_open_session(session) libssh2_channel_open_ex((session), "session", sizeof("session") - 1, LIBSSH2_CHANNEL_WINDOW_DEFAULT, LIBSSH2_CHANNEL_PACKET_DEFAULT, NULL, 0)
LIBSSH2_API LIBSSH2_CHANNEL *libssh2_channel_direct_tcpip_ex(LIBSSH2_SESSION *session, char *host, int port, char *shost, int sport); LIBSSH2_API LIBSSH2_CHANNEL *libssh2_channel_direct_tcpip_ex(LIBSSH2_SESSION *session, const char *host, int port, const char *shost, int sport);
#define libssh2_channel_direct_tcpip(session, host, port) libssh2_channel_direct_tcpip_ex((session), (host), (port), "127.0.0.1", 22) #define libssh2_channel_direct_tcpip(session, host, port) libssh2_channel_direct_tcpip_ex((session), (host), (port), "127.0.0.1", 22)
LIBSSH2_API LIBSSH2_LISTENER *libssh2_channel_forward_listen_ex(LIBSSH2_SESSION *session, char *host, int port, int *bound_port, int queue_maxsize); LIBSSH2_API LIBSSH2_LISTENER *libssh2_channel_forward_listen_ex(LIBSSH2_SESSION *session, const char *host, int port, int *bound_port, int queue_maxsize);
#define libssh2_channel_forward_listen(session, port) libssh2_channel_forward_listen_ex((session), NULL, (port), NULL, 16) #define libssh2_channel_forward_listen(session, port) libssh2_channel_forward_listen_ex((session), NULL, (port), NULL, 16)
LIBSSH2_API int libssh2_channel_forward_cancel(LIBSSH2_LISTENER *listener); 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, int varname_len, char *value, int value_len); LIBSSH2_API int libssh2_channel_setenv_ex(LIBSSH2_CHANNEL *channel, 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, char *term, int term_len, char *modes, 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);
#define libssh2_channel_request_pty(channel, term) libssh2_channel_request_pty_ex((channel), (term), strlen(term), NULL, 0, LIBSSH2_TERM_WIDTH, LIBSSH2_TERM_HEIGHT, LIBSSH2_TERM_WIDTH_PX, LIBSSH2_TERM_HEIGHT_PX) #define libssh2_channel_request_pty(channel, term) libssh2_channel_request_pty_ex((channel), (term), strlen(term), NULL, 0, LIBSSH2_TERM_WIDTH, LIBSSH2_TERM_HEIGHT, LIBSSH2_TERM_WIDTH_PX, LIBSSH2_TERM_HEIGHT_PX)
LIBSSH2_API int libssh2_channel_x11_req_ex(LIBSSH2_CHANNEL *channel, int single_connection, char *auth_proto, char *auth_cookie, int screen_number); LIBSSH2_API int libssh2_channel_x11_req_ex(LIBSSH2_CHANNEL *channel, int single_connection, const char *auth_proto, const char *auth_cookie, int screen_number);
#define libssh2_channel_x11_req(channel, screen_number) libssh2_channel_x11_req_ex((channel), 0, NULL, NULL, (screen_number)) #define libssh2_channel_x11_req(channel, screen_number) libssh2_channel_x11_req_ex((channel), 0, NULL, NULL, (screen_number))
LIBSSH2_API int libssh2_channel_process_startup(LIBSSH2_CHANNEL *channel, const char *request, int request_len, const char *message, int message_len); LIBSSH2_API int libssh2_channel_process_startup(LIBSSH2_CHANNEL *channel, const char *request, unsigned int request_len, const char *message, unsigned int message_len);
#define libssh2_channel_shell(channel) libssh2_channel_process_startup((channel), "shell", sizeof("shell") - 1, NULL, 0) #define libssh2_channel_shell(channel) libssh2_channel_process_startup((channel), "shell", sizeof("shell") - 1, NULL, 0)
#define libssh2_channel_exec(channel, command) libssh2_channel_process_startup((channel), "exec", sizeof("exec") - 1, (command), strlen(command)) #define libssh2_channel_exec(channel, command) libssh2_channel_process_startup((channel), "exec", sizeof("exec") - 1, (command), strlen(command))
#define libssh2_channel_subsystem(channel, subsystem) libssh2_channel_process_startup((channel), "subsystem", sizeof("subsystem") - 1, (subsystem), strlen(subsystem)) #define libssh2_channel_subsystem(channel, subsystem) libssh2_channel_process_startup((channel), "subsystem", sizeof("subsystem") - 1, (subsystem), strlen(subsystem))
LIBSSH2_API int libssh2_channel_read_ex(LIBSSH2_CHANNEL *channel, int stream_id, char *buf, size_t buflen); LIBSSH2_API int libssh2_channel_read_ex(LIBSSH2_CHANNEL *channel,
#define libssh2_channel_read(channel, buf, buflen) libssh2_channel_read_ex((channel), 0, (buf), (buflen)) int stream_id, char *buf,
size_t buflen);
LIBSSH2_API int libssh2_channel_readnb_ex(LIBSSH2_CHANNEL *channel,
int stream_id, char *buf,
size_t buflen);
/* This is a public error code from libssh2_channel_read() that is returned
when it would otherwise block. */
#define LIBSSH2CHANNEL_EAGAIN -2
#define libssh2_channel_read(channel, buf, buflen) \
libssh2_channel_read_ex((channel), 0, (buf), (buflen))
#define libssh2_channel_read_stderr(channel, buf, buflen) libssh2_channel_read_ex((channel), SSH_EXTENDED_DATA_STDERR, (buf), (buflen)) #define libssh2_channel_read_stderr(channel, buf, buflen) libssh2_channel_read_ex((channel), SSH_EXTENDED_DATA_STDERR, (buf), (buflen))
#define libssh2_channel_readnb(channel, buf, buflen) \
libssh2_channel_readnb_ex((channel), 0, (buf), (buflen))
LIBSSH2_API int libssh2_poll_channel_read(LIBSSH2_CHANNEL *channel, int extended); LIBSSH2_API int libssh2_poll_channel_read(LIBSSH2_CHANNEL *channel, int extended);
@@ -358,14 +375,25 @@ LIBSSH2_API unsigned long libssh2_channel_window_read_ex(LIBSSH2_CHANNEL *channe
LIBSSH2_API unsigned long libssh2_channel_receive_window_adjust(LIBSSH2_CHANNEL *channel, unsigned long adjustment, unsigned char force); LIBSSH2_API unsigned long libssh2_channel_receive_window_adjust(LIBSSH2_CHANNEL *channel, unsigned long adjustment, unsigned char force);
LIBSSH2_API int libssh2_channel_write_ex(LIBSSH2_CHANNEL *channel, int stream_id, const char *buf, size_t buflen); LIBSSH2_API int libssh2_channel_write_ex(LIBSSH2_CHANNEL *channel,
#define libssh2_channel_write(channel, buf, buflen) libssh2_channel_write_ex((channel), 0, (buf), (buflen)) int stream_id, const char *buf,
size_t buflen);
LIBSSH2_API int libssh2_channel_writenb_ex(LIBSSH2_CHANNEL *channel,
int stream_id, const char *buf,
size_t buflen);
#define libssh2_channel_write(channel, buf, buflen) \
libssh2_channel_write_ex((channel), 0, (buf), (buflen))
#define libssh2_channel_writenb(channel, buf, buflen) \
libssh2_channel_writenb_ex((channel), 0, (buf), (buflen))
#define libssh2_channel_write_stderr(channel, buf, buflen) libssh2_channel_write_ex((channel), SSH_EXTENDED_DATA_STDERR, (buf), (buflen)) #define libssh2_channel_write_stderr(channel, buf, buflen) libssh2_channel_write_ex((channel), SSH_EXTENDED_DATA_STDERR, (buf), (buflen))
LIBSSH2_API unsigned long libssh2_channel_window_write_ex(LIBSSH2_CHANNEL *channel, unsigned long *window_size_initial); LIBSSH2_API unsigned long libssh2_channel_window_write_ex(LIBSSH2_CHANNEL *channel, unsigned long *window_size_initial);
#define libssh2_channel_window_write(channel) libssh2_channel_window_write_ex((channel), NULL) #define libssh2_channel_window_write(channel) libssh2_channel_window_write_ex((channel), NULL)
LIBSSH2_API void libssh2_channel_set_blocking(LIBSSH2_CHANNEL *channel, int blocking); LIBSSH2_API void libssh2_channel_set_blocking(LIBSSH2_CHANNEL *channel, int blocking);
LIBSSH2_API int libssh2_channel_get_blocking(LIBSSH2_CHANNEL *channel);
LIBSSH2_API void libssh2_channel_handle_extended_data(LIBSSH2_CHANNEL *channel, int ignore_mode); LIBSSH2_API void libssh2_channel_handle_extended_data(LIBSSH2_CHANNEL *channel, int ignore_mode);
/* libssh2_channel_ignore_extended_data() is defined below for BC with version 0.1 /* libssh2_channel_ignore_extended_data() is defined below for BC with version 0.1
* Future uses should use libssh2_channel_handle_extended_data() directly * Future uses should use libssh2_channel_handle_extended_data() directly
@@ -391,7 +419,21 @@ LIBSSH2_API LIBSSH2_CHANNEL *libssh2_scp_recv(LIBSSH2_SESSION *session, const ch
LIBSSH2_API LIBSSH2_CHANNEL *libssh2_scp_send_ex(LIBSSH2_SESSION *session, const char *path, int mode, size_t size, long mtime, long atime); LIBSSH2_API LIBSSH2_CHANNEL *libssh2_scp_send_ex(LIBSSH2_SESSION *session, const char *path, int mode, size_t size, long mtime, long atime);
#define libssh2_scp_send(session, path, mode, size) libssh2_scp_send_ex((session), (path), (mode), (size), 0, 0) #define libssh2_scp_send(session, path, mode, size) libssh2_scp_send_ex((session), (path), (mode), (size), 0, 0)
LIBSSH2_API int libssh2_base64_decode(LIBSSH2_SESSION *session, char **dest, int *dest_len, char *src, int src_len); LIBSSH2_API int libssh2_base64_decode(LIBSSH2_SESSION *session, char **dest, unsigned int *dest_len, const char *src, unsigned int src_len);
/* NOTE NOTE NOTE
libssh2_trace() has no function in builds that aren't built with debug
enabled
*/
LIBSSH2_API int libssh2_trace(LIBSSH2_SESSION *session, int bitmask);
#define LIBSSH2_TRACE_TRANS (1<<1)
#define LIBSSH2_TRACE_KEX (1<<2)
#define LIBSSH2_TRACE_AUTH (1<<3)
#define LIBSSH2_TRACE_CONN (1<<4)
#define LIBSSH2_TRACE_SCP (1<<5)
#define LIBSSH2_TRACE_SFTP (1<<6)
#define LIBSSH2_TRACE_ERROR (1<<7)
#define LIBSSH2_TRACE_PUBLICKEY (1<<8)
#ifdef __cplusplus #ifdef __cplusplus
} /* extern "C" */ } /* extern "C" */

View File

@@ -1,113 +0,0 @@
/* include/libssh2_config.h.in. Generated from configure.in by autoheader. */
/* Define to 1 if you have the <errno.h> header file. */
#undef HAVE_ERRNO_H
/* Define to 1 if you have the <fcntl.h> header file. */
#undef HAVE_FCNTL_H
/* Define to 1 if you have the `gettimeofday' function. */
#undef HAVE_GETTIMEOFDAY
/* Define to 1 if you have the <inttypes.h> header file. */
#undef HAVE_INTTYPES_H
/* Define to 1 if you have the <memory.h> header file. */
#undef HAVE_MEMORY_H
/* Define to 1 if you have the `poll' function. */
#undef HAVE_POLL
/* Define to 1 if you have the `select' function. */
#undef HAVE_SELECT
/* Define to 1 if you have the <stdint.h> header file. */
#undef HAVE_STDINT_H
/* Define to 1 if you have the <stdio.h> header file. */
#undef HAVE_STDIO_H
/* Define to 1 if you have the <stdlib.h> header file. */
#undef HAVE_STDLIB_H
/* Define to 1 if you have the <strings.h> header file. */
#undef HAVE_STRINGS_H
/* Define to 1 if you have the <string.h> header file. */
#undef HAVE_STRING_H
/* Define to 1 if you have the <sys/select.h> header file. */
#undef HAVE_SYS_SELECT_H
/* Define to 1 if you have the <sys/stat.h> header file. */
#undef HAVE_SYS_STAT_H
/* Define to 1 if you have the <sys/types.h> header file. */
#undef HAVE_SYS_TYPES_H
/* Define to 1 if you have the <sys/uio.h> header file. */
#undef HAVE_SYS_UIO_H
/* Define to 1 if you have the <unistd.h> header file. */
#undef HAVE_UNISTD_H
/* Enable "none" cipher -- NOT RECOMMENDED */
#undef LIBSSH2_CRYPT_NONE
/* Output connection layer debugging info to stderr */
#undef LIBSSH2_DEBUG_CONNECTION
/* Output failure events to stderr */
#undef LIBSSH2_DEBUG_ERRORS
/* Output Key Exchange debugging info to stderr */
#undef LIBSSH2_DEBUG_KEX
/* Output publickey subsystem debugging info to stderr */
#undef LIBSSH2_DEBUG_PUBLICKEY
/* Output scp subsystem debugging info to stderr */
#undef LIBSSH2_DEBUG_SCP
/* Output sftp subsystem debugging info to stderr */
#undef LIBSSH2_DEBUG_SFTP
/* Output transport layer debugging info to stderr */
#undef LIBSSH2_DEBUG_TRANSPORT
/* Output userauth layer debugging info to stderr */
#undef LIBSSH2_DEBUG_USERAUTH
/* Enable newer diffie-hellman-group-exchange-sha1 syntax */
#undef LIBSSH2_DH_GEX_NEW
/* Compile in zlib support */
#undef LIBSSH2_HAVE_ZLIB
/* Enable "none" MAC -- NOT RECOMMENDED */
#undef LIBSSH2_MAC_NONE
/* Define to the address where bug reports for this package should be sent. */
#undef PACKAGE_BUGREPORT
/* Define to the full name of this package. */
#undef PACKAGE_NAME
/* Define to the full name and version of this package. */
#undef PACKAGE_STRING
/* Define to the one symbol short name of this package. */
#undef PACKAGE_TARNAME
/* Define to the version of this package. */
#undef PACKAGE_VERSION
/* Define to 1 if you have the ANSI C header files. */
#undef STDC_HEADERS
/* Define to 1 if your processor stores words with the most significant byte
first (like Motorola and SPARC, unlike Intel and VAX). */
#undef WORDS_BIGENDIAN
/* Define to empty if `const' does not conform to ANSI C. */
#undef const

View File

@@ -1,475 +0,0 @@
/* Copyright (c) 2004-2005, Sara Golemon <sarag@libssh2.org>
* All rights reserved.
*
* Redistribution and use in source and binary forms,
* with or without modification, are permitted provided
* that the following conditions are met:
*
* Redistributions of source code must retain the above
* copyright notice, this list of conditions and the
* following disclaimer.
*
* Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following
* disclaimer in the documentation and/or other materials
* provided with the distribution.
*
* Neither the name of the copyright holder nor the names
* of any other contributors may be used to endorse or
* promote products derived from this software without
* specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
* CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
* USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
* OF SUCH DAMAGE.
*/
#ifndef LIBSSH2_PRIV_H
#define LIBSSH2_PRIV_H 1
#define LIBSSH2_LIBRARY
#include "libssh2_config.h"
#include "libssh2.h"
#ifndef WIN32
#include <sys/socket.h>
#endif
#include <openssl/evp.h>
#ifndef OPENSSL_NO_SHA
#include <openssl/sha.h>
#endif
#ifndef OPENSSL_NO_MD5
#include <openssl/md5.h>
#endif
#define LIBSSH2_ALLOC(session, count) session->alloc((count), &(session)->abstract)
#define LIBSSH2_REALLOC(session, ptr, count) ((ptr) ? session->realloc((ptr), (count), &(session)->abstract) : session->alloc((count), &(session)->abstract))
#define LIBSSH2_FREE(session, ptr) session->free((ptr), &(session)->abstract)
#define LIBSSH2_IGNORE(session, data, datalen) session->ssh_msg_ignore((session), (data), (datalen), &(session)->abstract)
#define LIBSSH2_DEBUG(session, always_display, message, message_len, language, language_len) \
session->ssh_msg_disconnect((session), (always_display), (message), (message_len), (language), (language_len), &(session)->abstract)
#define LIBSSH2_DISCONNECT(session, reason, message, message_len, language, language_len) \
session->ssh_msg_disconnect((session), (reason), (message), (message_len), (language), (language_len), &(session)->abstract)
#define LIBSSH2_MACERROR(session, data, datalen) session->macerror((session), (data), (datalen), &(session)->abstract)
#define LIBSSH2_X11_OPEN(channel, shost, sport) channel->session->x11(((channel)->session), (channel), (shost), (sport), (&(channel)->session->abstract))
#define LIBSSH2_CHANNEL_CLOSE(session, channel) channel->close_cb((session), &(session)->abstract, (channel), &(channel)->abstract)
typedef struct _LIBSSH2_KEX_METHOD LIBSSH2_KEX_METHOD;
typedef struct _LIBSSH2_HOSTKEY_METHOD LIBSSH2_HOSTKEY_METHOD;
typedef struct _LIBSSH2_MAC_METHOD LIBSSH2_MAC_METHOD;
typedef struct _LIBSSH2_CRYPT_METHOD LIBSSH2_CRYPT_METHOD;
typedef struct _LIBSSH2_COMP_METHOD LIBSSH2_COMP_METHOD;
typedef struct _LIBSSH2_PACKET LIBSSH2_PACKET;
typedef struct _LIBSSH2_PACKET_BRIGADE LIBSSH2_PACKET_BRIGADE;
typedef struct _LIBSSH2_CHANNEL_BRIGADE LIBSSH2_CHANNEL_BRIGADE;
struct _LIBSSH2_PACKET {
unsigned char type;
/* Unencrypted Payload (no type byte, no padding, just the facts ma'am) */
unsigned char *data;
unsigned long data_len;
/* Where to start reading data from,
* used for channel data that's been partially consumed */
unsigned long data_head;
/* Can the message be confirmed? */
int mac;
LIBSSH2_PACKET_BRIGADE *brigade;
LIBSSH2_PACKET *next, *prev;
};
struct _LIBSSH2_PACKET_BRIGADE {
LIBSSH2_PACKET *head, *tail;
};
typedef struct _libssh2_channel_data {
/* Identifier */
unsigned long id;
/* Limits and restrictions */
unsigned long window_size_initial, window_size, packet_size;
/* Set to 1 when CHANNEL_CLOSE / CHANNEL_EOF sent/received */
char close, eof, extended_data_ignore_mode;
} libssh2_channel_data;
struct _LIBSSH2_CHANNEL {
unsigned char *channel_type;
unsigned channel_type_len;
int blocking;
/* channel's program exit status */
int exit_status;
libssh2_channel_data local, remote;
unsigned long adjust_queue; /* Amount of bytes to be refunded to receive window (but not yet sent) */
LIBSSH2_SESSION *session;
LIBSSH2_CHANNEL *next, *prev;
void *abstract;
LIBSSH2_CHANNEL_CLOSE_FUNC((*close_cb));
};
struct _LIBSSH2_CHANNEL_BRIGADE {
LIBSSH2_CHANNEL *head, *tail;
};
struct _LIBSSH2_LISTENER {
LIBSSH2_SESSION *session;
char *host;
int port;
LIBSSH2_CHANNEL *queue;
int queue_size;
int queue_maxsize;
LIBSSH2_LISTENER *prev, *next;
};
typedef struct _libssh2_endpoint_data {
unsigned char *banner;
unsigned char *kexinit;
unsigned long kexinit_len;
LIBSSH2_CRYPT_METHOD *crypt;
void *crypt_abstract;
LIBSSH2_MAC_METHOD *mac;
unsigned long seqno;
void *mac_abstract;
LIBSSH2_COMP_METHOD *comp;
void *comp_abstract;
/* Method Preferences -- NULL yields "load order" */
char *crypt_prefs;
char *mac_prefs;
char *comp_prefs;
char *lang_prefs;
} libssh2_endpoint_data;
struct _LIBSSH2_SESSION {
/* Memory management callbacks */
void *abstract;
LIBSSH2_ALLOC_FUNC((*alloc));
LIBSSH2_REALLOC_FUNC((*realloc));
LIBSSH2_FREE_FUNC((*free));
/* Other callbacks */
LIBSSH2_IGNORE_FUNC((*ssh_msg_ignore));
LIBSSH2_DEBUG_FUNC((*ssh_msg_debug));
LIBSSH2_DISCONNECT_FUNC((*ssh_msg_disconnect));
LIBSSH2_MACERROR_FUNC((*macerror));
LIBSSH2_X11_OPEN_FUNC((*x11));
/* Method preferences -- NULL yields "load order" */
char *kex_prefs;
char *hostkey_prefs;
int state;
int flags;
/* Agreed Key Exchange Method */
LIBSSH2_KEX_METHOD *kex;
unsigned char *session_id;
unsigned long session_id_len;
/* Server's public key */
LIBSSH2_HOSTKEY_METHOD *hostkey;
void *server_hostkey_abstract;
/* Either set with libssh2_session_hostkey() (for server mode)
* Or read from server in (eg) KEXDH_INIT (for client mode)
*/
unsigned char *server_hostkey;
unsigned long server_hostkey_len;
#ifndef OPENSSL_NO_MD5
unsigned char server_hostkey_md5[MD5_DIGEST_LENGTH];
#endif /* ! OPENSSL_NO_MD5 */
#ifndef OPENSSL_NO_SHA
unsigned char server_hostkey_sha1[SHA_DIGEST_LENGTH];
#endif
/* (remote as source of data -- packet_read ) */
libssh2_endpoint_data remote;
/* (local as source of data -- packet_write ) */
libssh2_endpoint_data local;
/* Inbound Data buffer -- Sometimes the packet that comes in isn't the packet we're ready for */
LIBSSH2_PACKET_BRIGADE packets;
/* Active connection channels */
LIBSSH2_CHANNEL_BRIGADE channels;
unsigned long next_channel;
LIBSSH2_LISTENER *listeners;
/* Actual I/O socket */
int socket_fd;
int socket_block;
int socket_state;
/* Error tracking */
char *err_msg;
unsigned long err_msglen;
int err_should_free;
int err_code;
};
/* session.state bits */
#define LIBSSH2_STATE_EXCHANGING_KEYS 0x00000001
#define LIBSSH2_STATE_NEWKEYS 0x00000002
#define LIBSSH2_STATE_AUTHENTICATED 0x00000004
/* session.flag helpers */
#ifdef MSG_NOSIGNAL
#define LIBSSH2_SOCKET_SEND_FLAGS(session) (((session)->flags & LIBSSH2_FLAG_SIGPIPE) ? 0 : MSG_NOSIGNAL)
#define LIBSSH2_SOCKET_RECV_FLAGS(session) (((session)->flags & LIBSSH2_FLAG_SIGPIPE) ? 0 : MSG_NOSIGNAL)
#else
/* If MSG_NOSIGNAL isn't defined we're SOL on blocking SIGPIPE */
#define LIBSSH2_SOCKET_SEND_FLAGS(session) 0
#define LIBSSH2_SOCKET_RECV_FLAGS(session) 0
#endif
/* libssh2 extensible ssh api, ultimately I'd like to allow loading additional methods via .so/.dll */
struct _LIBSSH2_KEX_METHOD {
char *name;
/* Key exchange, populates session->* and returns 0 on success, non-0 on error */
int (*exchange_keys)(LIBSSH2_SESSION *session);
long flags;
};
struct _LIBSSH2_HOSTKEY_METHOD {
char *name;
unsigned long hash_len;
int (*init)(LIBSSH2_SESSION *session, unsigned char *hostkey_data, unsigned long hostkey_data_len, void **abstract);
int (*initPEM)(LIBSSH2_SESSION *session, unsigned const char *privkeyfile, unsigned const char *passphrase, void **abstract);
int (*sig_verify)(LIBSSH2_SESSION *session, const unsigned char *sig, unsigned long sig_len, const unsigned char *m, unsigned long m_len, void **abstract);
int (*sign)(LIBSSH2_SESSION *session, unsigned char **signature, unsigned long *signature_len, const unsigned char *data, unsigned long data_len, void **abstract);
int (*signv)(LIBSSH2_SESSION *session, unsigned char **signature, unsigned long *signature_len, unsigned long veccount, const struct iovec datavec[], void **abstract);
int (*encrypt)(LIBSSH2_SESSION *session, unsigned char **dst, unsigned long *dst_len, const unsigned char *src, unsigned long src_len, void **abstract);
int (*dtor)(LIBSSH2_SESSION *session, void **abstract);
};
/* When FLAG_EVP is set, crypt contains a pointer to an EVP_CIPHER generator and init and dtor are ignored
* Yes, I know it's a hack.
*/
#define LIBSSH2_CRYPT_METHOD_FLAG_EVP 0x0001
struct _LIBSSH2_CRYPT_METHOD {
char *name;
int blocksize;
/* iv and key sizes (-1 for variable length) */
int iv_len;
int secret_len;
long flags;
int (*init)(LIBSSH2_SESSION *session, unsigned char *iv, int *free_iv, unsigned char *secret, int *free_secret, int encrypt, void **abstract);
int (*crypt)(LIBSSH2_SESSION *session, unsigned char *block, void **abstract);
int (*dtor)(LIBSSH2_SESSION *session, void **abstract);
};
struct _LIBSSH2_COMP_METHOD {
char *name;
int (*init)(LIBSSH2_SESSION *session, int compress, void **abstract);
int (*comp)(LIBSSH2_SESSION *session, int compress, unsigned char **dest, unsigned long *dest_len, unsigned long payload_limit, int *free_dest,
const unsigned char *src, unsigned long src_len, void **abstract);
int (*dtor)(LIBSSH2_SESSION *session, int compress, void **abstract);
};
struct _LIBSSH2_MAC_METHOD {
char *name;
/* The length of a given MAC packet */
int mac_len;
/* integrity key length */
int key_len;
/* Message Authentication Code Hashing algo */
int (*init)(LIBSSH2_SESSION *session, unsigned char *key, int *free_key, void **abstract);
int (*hash)(LIBSSH2_SESSION *session, unsigned char *buf, unsigned long seqno, const unsigned char *packet, unsigned long packet_len, const unsigned char *addtl, unsigned long addtl_len, void **abstract);
int (*dtor)(LIBSSH2_SESSION *session, void **abstract);
};
#if defined(LIBSSH2_DEBUG_TRANSPORT) || defined(LIBSSH2_DEBUG_KEX) || defined(LIBSSH2_DEBUG_USERAUTH) || defined(LIBSSH2_DEBUG_CONNECTION) || defined(LIBSSH2_DEBUG_SCP) || defined(LIBSSH2_DEBUG_SFTP) || defined(LIBSSH2_DEBUG_ERRORS)
#define LIBSSH2_DEBUG_ENABLED
/* Internal debugging contexts -- Used with --enable-debug-* */
#define LIBSSH2_DBG_TRANS 1
#define LIBSSH2_DBG_KEX 2
#define LIBSSH2_DBG_AUTH 3
#define LIBSSH2_DBG_CONN 4
#define LIBSSH2_DBG_SCP 5
#define LIBSSH2_DBG_SFTP 6
#define LIBSSH2_DBG_ERROR 7
#define LIBSSH2_DBG_PUBLICKEY 8
void _libssh2_debug(LIBSSH2_SESSION *session, int context, const char *format, ...);
#endif /* LIBSSH2_DEBUG_ENABLED */
#ifdef LIBSSH2_DEBUG_ERRORS
#define libssh2_error(session, errcode, errmsg, should_free) \
{ \
if (session->err_msg && session->err_should_free) { \
LIBSSH2_FREE(session, session->err_msg); \
} \
session->err_msg = errmsg; \
session->err_msglen = strlen(errmsg); \
session->err_should_free = should_free; \
session->err_code = errcode; \
_libssh2_debug(session, LIBSSH2_DBG_ERROR, "%d - %s", session->err_code, session->err_msg); \
}
#else /* ! LIBSSH2_DEBUG_ERRORS */
#define libssh2_error(session, errcode, errmsg, should_free) \
{ \
if (session->err_msg && session->err_should_free) { \
LIBSSH2_FREE(session, session->err_msg); \
} \
session->err_msg = errmsg; \
session->err_msglen = strlen(errmsg); \
session->err_should_free = should_free; \
session->err_code = errcode; \
}
#endif /* LIBSSH2_DEBUG_ENABLED */
#define LIBSSH2_SOCKET_UNKNOWN 1
#define LIBSSH2_SOCKET_CONNECTED 0
#define LIBSSH2_SOCKET_DISCONNECTED -1
/* Initial packet state, prior to MAC check */
#define LIBSSH2_MAC_UNCONFIRMED 1
/* When MAC type is "none" (proto initiation phase) all packets are deemed "confirmed" */
#define LIBSSH2_MAC_CONFIRMED 0
/* Something very bad is going on */
#define LIBSSH2_MAC_INVALID -1
/* SSH Packet Types -- Defined by internet draft */
/* Transport Layer */
#define SSH_MSG_DISCONNECT 1
#define SSH_MSG_IGNORE 2
#define SSH_MSG_UNIMPLEMENTED 3
#define SSH_MSG_DEBUG 4
#define SSH_MSG_SERVICE_REQUEST 5
#define SSH_MSG_SERVICE_ACCEPT 6
#define SSH_MSG_KEXINIT 20
#define SSH_MSG_NEWKEYS 21
/* diffie-hellman-group1-sha1 */
#define SSH_MSG_KEXDH_INIT 30
#define SSH_MSG_KEXDH_REPLY 31
/* diffie-hellman-group-exchange-sha1 */
#define SSH_MSG_KEX_DH_GEX_REQUEST_OLD 30
#define SSH_MSG_KEX_DH_GEX_REQUEST 34
#define SSH_MSG_KEX_DH_GEX_GROUP 31
#define SSH_MSG_KEX_DH_GEX_INIT 32
#define SSH_MSG_KEX_DH_GEX_REPLY 33
/* User Authentication */
#define SSH_MSG_USERAUTH_REQUEST 50
#define SSH_MSG_USERAUTH_FAILURE 51
#define SSH_MSG_USERAUTH_SUCCESS 52
#define SSH_MSG_USERAUTH_BANNER 53
/* "public key" method */
#define SSH_MSG_USERAUTH_PK_OK 60
/* "password" method */
#define SSH_MSG_USERAUTH_PASSWD_CHANGEREQ 60
/* "keyboard-interactive" method */
#define SSH_MSG_USERAUTH_INFO_REQUEST 60
#define SSH_MSG_USERAUTH_INFO_RESPONSE 61
/* Channels */
#define SSH_MSG_GLOBAL_REQUEST 80
#define SSH_MSG_REQUEST_SUCCESS 81
#define SSH_MSG_REQUEST_FAILURE 82
#define SSH_MSG_CHANNEL_OPEN 90
#define SSH_MSG_CHANNEL_OPEN_CONFIRMATION 91
#define SSH_MSG_CHANNEL_OPEN_FAILURE 92
#define SSH_MSG_CHANNEL_WINDOW_ADJUST 93
#define SSH_MSG_CHANNEL_DATA 94
#define SSH_MSG_CHANNEL_EXTENDED_DATA 95
#define SSH_MSG_CHANNEL_EOF 96
#define SSH_MSG_CHANNEL_CLOSE 97
#define SSH_MSG_CHANNEL_REQUEST 98
#define SSH_MSG_CHANNEL_SUCCESS 99
#define SSH_MSG_CHANNEL_FAILURE 100
void libssh2_session_shutdown(LIBSSH2_SESSION *session);
unsigned long libssh2_ntohu32(const unsigned char *buf);
libssh2_uint64_t libssh2_ntohu64(const unsigned char *buf);
void libssh2_htonu32(unsigned char *buf, unsigned long val);
void libssh2_htonu64(unsigned char *buf, libssh2_uint64_t val);
int libssh2_packet_read(LIBSSH2_SESSION *session, int block);
int libssh2_packet_ask_ex(LIBSSH2_SESSION *session, unsigned char packet_type, unsigned char **data, unsigned long *data_len, unsigned long match_ofs, const unsigned char *match_buf, unsigned long match_len, int poll_socket);
#define libssh2_packet_ask(session, packet_type, data, data_len, poll_socket) \
libssh2_packet_ask_ex((session), (packet_type), (data), (data_len), 0, NULL, 0, (poll_socket))
int libssh2_packet_askv_ex(LIBSSH2_SESSION *session, unsigned char *packet_types, unsigned char **data, unsigned long *data_len, unsigned long match_ofs, const unsigned char *match_buf, unsigned long match_len, int poll_socket);
#define libssh2_packet_askv(session, packet_types, data, data_len, poll_socket) \
libssh2_packet_askv_ex((session), (packet_types), (data), (data_len), 0, NULL, 0, (poll_socket))
int libssh2_packet_require_ex(LIBSSH2_SESSION *session, unsigned char packet_type, unsigned char **data, unsigned long *data_len, unsigned long match_ofs, const unsigned char *match_buf, unsigned long match_len);
#define libssh2_packet_require(session, packet_type, data, data_len) \
libssh2_packet_require_ex((session), (packet_type), (data), (data_len), 0, NULL, 0)
int libssh2_packet_requirev_ex(LIBSSH2_SESSION *session, unsigned char *packet_types, unsigned char **data, unsigned long *data_len, unsigned long match_ofs, const unsigned char *match_buf, unsigned long match_len);
#define libssh2_packet_requirev(session, packet_types, data, data_len) \
libssh2_packet_requirev_ex((session), (packet_types), (data), (data_len), 0, NULL, 0)
int libssh2_packet_write(LIBSSH2_SESSION *session, unsigned char *data, unsigned long data_len);
int libssh2_kex_exchange(LIBSSH2_SESSION *session, int reexchange);
unsigned long libssh2_channel_nextid(LIBSSH2_SESSION *session);
LIBSSH2_CHANNEL *libssh2_channel_locate(LIBSSH2_SESSION *session, unsigned long channel_id);
/* Let crypt.c/hostkey.c/comp.c/mac.c expose their method structs */
LIBSSH2_CRYPT_METHOD **libssh2_crypt_methods(void);
LIBSSH2_HOSTKEY_METHOD **libssh2_hostkey_methods(void);
LIBSSH2_COMP_METHOD **libssh2_comp_methods(void);
LIBSSH2_MAC_METHOD **libssh2_mac_methods(void);
/* Language API doesn't exist yet. Just act like we've agreed on a language */
#define libssh2_kex_agree_lang(session, endpoint, str, str_len) 0
#endif /* LIBSSH2_H */

View File

@@ -1,4 +1,4 @@
/* Copyright (c) 2004-2005, Sara Golemon <sarag@libssh2.org> /* Copyright (c) 2004-2006, Sara Golemon <sarag@libssh2.org>
* All rights reserved. * All rights reserved.
* *
* Redistribution and use in source and binary forms, * Redistribution and use in source and binary forms,
@@ -49,9 +49,9 @@
typedef struct _LIBSSH2_PUBLICKEY LIBSSH2_PUBLICKEY; typedef struct _LIBSSH2_PUBLICKEY LIBSSH2_PUBLICKEY;
typedef struct _libssh2_publickey_attribute { typedef struct _libssh2_publickey_attribute {
char *name; const char *name;
unsigned long name_len; unsigned long name_len;
char *value; const char *value;
unsigned long value_len; unsigned long value_len;
char mandatory; char mandatory;
} libssh2_publickey_attribute; } libssh2_publickey_attribute;
@@ -59,9 +59,9 @@ typedef struct _libssh2_publickey_attribute {
typedef struct _libssh2_publickey_list { typedef struct _libssh2_publickey_list {
unsigned char *packet; /* For freeing */ unsigned char *packet; /* For freeing */
unsigned char *name; const unsigned char *name;
unsigned long name_len; unsigned long name_len;
unsigned char *blob; const unsigned char *blob;
unsigned long blob_len; unsigned long blob_len;
unsigned long num_attrs; unsigned long num_attrs;
libssh2_publickey_attribute *attrs; /* free me */ libssh2_publickey_attribute *attrs; /* free me */
@@ -80,7 +80,7 @@ LIBSSH2_API LIBSSH2_PUBLICKEY *libssh2_publickey_init(LIBSSH2_SESSION *session);
LIBSSH2_API int libssh2_publickey_add_ex(LIBSSH2_PUBLICKEY *pkey, const unsigned char *name, unsigned long name_len, LIBSSH2_API int libssh2_publickey_add_ex(LIBSSH2_PUBLICKEY *pkey, const unsigned char *name, unsigned long name_len,
const unsigned char *blob, unsigned long blob_len, char overwrite, const unsigned char *blob, unsigned long blob_len, char overwrite,
unsigned long num_attrs, libssh2_publickey_attribute attrs[]); unsigned long num_attrs, const libssh2_publickey_attribute attrs[]);
#define libssh2_publickey_add(pkey, name, blob, blob_len, overwrite, num_attrs, attrs) \ #define libssh2_publickey_add(pkey, name, blob, blob_len, overwrite, num_attrs, attrs) \
libssh2_publickey_add_ex((pkey), (name), strlen(name), (blob), (blob_len), (overwrite), (num_attrs), (attrs)) libssh2_publickey_add_ex((pkey), (name), strlen(name), (blob), (blob_len), (overwrite), (num_attrs), (attrs))

View File

@@ -1,4 +1,4 @@
/* Copyright (c) 2004-2005, Sara Golemon <sarag@libssh2.org> /* Copyright (c) 2004-2007, Sara Golemon <sarag@libssh2.org>
* All rights reserved. * All rights reserved.
* *
* Redistribution and use in source and binary forms, * Redistribution and use in source and binary forms,
@@ -38,6 +38,10 @@
#ifndef LIBSSH2_SFTP_H #ifndef LIBSSH2_SFTP_H
#define LIBSSH2_SFTP_H 1 #define LIBSSH2_SFTP_H 1
#ifndef WIN32
#include <unistd.h>
#endif
#ifdef __cplusplus #ifdef __cplusplus
extern "C" { extern "C" {
#endif #endif
@@ -103,6 +107,39 @@ struct _LIBSSH2_SFTP_ATTRIBUTES {
#define LIBSSH2_SFTP_TYPE_BLOCK_DEVICE 8 #define LIBSSH2_SFTP_TYPE_BLOCK_DEVICE 8
#define LIBSSH2_SFTP_TYPE_FIFO 9 #define LIBSSH2_SFTP_TYPE_FIFO 9
/*
* Reproduce the POSIX file modes here for systems that are not
* POSIX compliant.
*
* These is used in "permissions" of "struct _LIBSSH2_SFTP_ATTRIBUTES"
*/
/* File type */
#define LIBSSH2_SFTP_S_IFMT 0170000 /* type of file mask */
#define LIBSSH2_SFTP_S_IFIFO 0010000 /* named pipe (fifo) */
#define LIBSSH2_SFTP_S_IFCHR 0020000 /* character special */
#define LIBSSH2_SFTP_S_IFDIR 0040000 /* directory */
#define LIBSSH2_SFTP_S_IFBLK 0060000 /* block special */
#define LIBSSH2_SFTP_S_IFREG 0100000 /* regular */
#define LIBSSH2_SFTP_S_IFLNK 0120000 /* symbolic link */
#define LIBSSH2_SFTP_S_IFSOCK 0140000 /* socket */
/* File mode */
/* Read, write, execute/search by owner */
#define LIBSSH2_SFTP_S_IRWXU 0000700 /* RWX mask for owner */
#define LIBSSH2_SFTP_S_IRUSR 0000400 /* R for owner */
#define LIBSSH2_SFTP_S_IWUSR 0000200 /* W for owner */
#define LIBSSH2_SFTP_S_IXUSR 0000100 /* X for owner */
/* Read, write, execute/search by group */
#define LIBSSH2_SFTP_S_IRWXG 0000070 /* RWX mask for group */
#define LIBSSH2_SFTP_S_IRGRP 0000040 /* R for group */
#define LIBSSH2_SFTP_S_IWGRP 0000020 /* W for group */
#define LIBSSH2_SFTP_S_IXGRP 0000010 /* X for group */
/* Read, write, execute/search by others */
#define LIBSSH2_SFTP_S_IRWXO 0000007 /* RWX mask for other */
#define LIBSSH2_SFTP_S_IROTH 0000004 /* R for other */
#define LIBSSH2_SFTP_S_IWOTH 0000002 /* W for other */
#define LIBSSH2_SFTP_S_IXOTH 0000001 /* X for other */
/* SFTP File Transfer Flags -- (e.g. flags parameter to sftp_open()) /* SFTP File Transfer Flags -- (e.g. flags parameter to sftp_open())
* Danger will robinson... APPEND doesn't have any effect on OpenSSH servers */ * Danger will robinson... APPEND doesn't have any effect on OpenSSH servers */
#define LIBSSH2_FXF_READ 0x00000001 #define LIBSSH2_FXF_READ 0x00000001
@@ -142,13 +179,27 @@ LIBSSH2_API int libssh2_sftp_shutdown(LIBSSH2_SFTP *sftp);
LIBSSH2_API unsigned long libssh2_sftp_last_error(LIBSSH2_SFTP *sftp); LIBSSH2_API unsigned long libssh2_sftp_last_error(LIBSSH2_SFTP *sftp);
/* File / Directory Ops */ /* File / Directory Ops */
LIBSSH2_API LIBSSH2_SFTP_HANDLE *libssh2_sftp_open_ex(LIBSSH2_SFTP *sftp, char *filename, int filename_len, unsigned long flags, long mode, int open_type); LIBSSH2_API LIBSSH2_SFTP_HANDLE *libssh2_sftp_open_ex(LIBSSH2_SFTP *sftp, const char *filename, unsigned int filename_len, unsigned long flags, long mode, int open_type);
#define libssh2_sftp_open(sftp, filename, flags, mode) libssh2_sftp_open_ex((sftp), (filename), strlen(filename), (flags), (mode), LIBSSH2_SFTP_OPENFILE) #define libssh2_sftp_open(sftp, filename, flags, mode) libssh2_sftp_open_ex((sftp), (filename), strlen(filename), (flags), (mode), LIBSSH2_SFTP_OPENFILE)
#define libssh2_sftp_opendir(sftp, path) libssh2_sftp_open_ex((sftp), (path), strlen(path), 0, 0, LIBSSH2_SFTP_OPENDIR) #define libssh2_sftp_opendir(sftp, path) libssh2_sftp_open_ex((sftp), (path), strlen(path), 0, 0, LIBSSH2_SFTP_OPENDIR)
LIBSSH2_API size_t libssh2_sftp_read(LIBSSH2_SFTP_HANDLE *handle, char *buffer, size_t buffer_maxlen); /* This is a public error code from libssh2_sftp_read() that is returned
LIBSSH2_API int libssh2_sftp_readdir(LIBSSH2_SFTP_HANDLE *handle, char *buffer, size_t buffer_maxlen, LIBSSH2_SFTP_ATTRIBUTES *attrs); when it would otherwise block. */
LIBSSH2_API size_t libssh2_sftp_write(LIBSSH2_SFTP_HANDLE *handle, const char *buffer, size_t count); #define LIBSSH2SFTP_EAGAIN -2
LIBSSH2_API ssize_t libssh2_sftp_read(LIBSSH2_SFTP_HANDLE *handle,
char *buffer, size_t buffer_maxlen);
LIBSSH2_API ssize_t libssh2_sftp_readnb(LIBSSH2_SFTP_HANDLE *handle,
char *buffer, size_t buffer_maxlen);
LIBSSH2_API int libssh2_sftp_readdir(LIBSSH2_SFTP_HANDLE *handle, char *buffer,
size_t buffer_maxlen, LIBSSH2_SFTP_ATTRIBUTES *attrs);
LIBSSH2_API int libssh2_sftp_readdirnb(LIBSSH2_SFTP_HANDLE *handle, char *buffer,
size_t buffer_maxlen, LIBSSH2_SFTP_ATTRIBUTES *attrs);
LIBSSH2_API ssize_t libssh2_sftp_write(LIBSSH2_SFTP_HANDLE *handle,
const char *buffer, size_t count);
LIBSSH2_API ssize_t libssh2_sftp_writenb(LIBSSH2_SFTP_HANDLE *handle,
const char *buffer, size_t count);
LIBSSH2_API int libssh2_sftp_close_handle(LIBSSH2_SFTP_HANDLE *handle); LIBSSH2_API int libssh2_sftp_close_handle(LIBSSH2_SFTP_HANDLE *handle);
#define libssh2_sftp_close(handle) libssh2_sftp_close_handle(handle) #define libssh2_sftp_close(handle) libssh2_sftp_close_handle(handle)
@@ -166,31 +217,36 @@ LIBSSH2_API int libssh2_sftp_fstat_ex(LIBSSH2_SFTP_HANDLE *handle, LIBSSH2_SFTP_
/* Miscellaneous Ops */ /* Miscellaneous Ops */
LIBSSH2_API int libssh2_sftp_rename_ex(LIBSSH2_SFTP *sftp, char *source_filename, int srouce_filename_len, LIBSSH2_API int libssh2_sftp_rename_ex(LIBSSH2_SFTP *sftp, const char *source_filename, unsigned int srouce_filename_len,
char *dest_filename, int dest_filename_len, const char *dest_filename, unsigned int dest_filename_len,
long flags); long flags);
#define libssh2_sftp_rename(sftp, sourcefile, destfile) libssh2_sftp_rename_ex((sftp), (sourcefile), strlen(sourcefile), (destfile), strlen(destfile), \ #define libssh2_sftp_rename(sftp, sourcefile, destfile) libssh2_sftp_rename_ex((sftp), (sourcefile), strlen(sourcefile), (destfile), strlen(destfile), \
LIBSSH2_SFTP_RENAME_OVERWRITE | LIBSSH2_SFTP_RENAME_ATOMIC | LIBSSH2_SFTP_RENAME_NATIVE) LIBSSH2_SFTP_RENAME_OVERWRITE | LIBSSH2_SFTP_RENAME_ATOMIC | LIBSSH2_SFTP_RENAME_NATIVE)
LIBSSH2_API int libssh2_sftp_unlink_ex(LIBSSH2_SFTP *sftp, char *filename, int filename_len); LIBSSH2_API int libssh2_sftp_unlink_ex(LIBSSH2_SFTP *sftp, const char *filename, unsigned int filename_len);
#define libssh2_sftp_unlink(sftp, filename) libssh2_sftp_unlink_ex((sftp), (filename), strlen(filename)) #define libssh2_sftp_unlink(sftp, filename) libssh2_sftp_unlink_ex((sftp), (filename), strlen(filename))
LIBSSH2_API int libssh2_sftp_mkdir_ex(LIBSSH2_SFTP *sftp, char *path, int path_len, long mode); LIBSSH2_API int libssh2_sftp_mkdir_ex(LIBSSH2_SFTP *sftp, const char *path, unsigned int path_len, long mode);
#define libssh2_sftp_mkdir(sftp, path, mode) libssh2_sftp_mkdir_ex((sftp), (path), strlen(path), (mode)) #define libssh2_sftp_mkdir(sftp, path, mode) libssh2_sftp_mkdir_ex((sftp), (path), strlen(path), (mode))
LIBSSH2_API int libssh2_sftp_mkdirnb_ex(LIBSSH2_SFTP *sftp, const char *path, unsigned int path_len, long mode);
#define libssh2_sftp_mkdirnb(sftp, path, mode) libssh2_sftp_mkdirnb_ex((sftp), (path), strlen(path), (mode))
LIBSSH2_API int libssh2_sftp_rmdir_ex(LIBSSH2_SFTP *sftp, char *path, int path_len); LIBSSH2_API int libssh2_sftp_rmdir_ex(LIBSSH2_SFTP *sftp, const char *path, unsigned int path_len);
#define libssh2_sftp_rmdir(sftp, path) libssh2_sftp_rmdir_ex((sftp), (path), strlen(path)) #define libssh2_sftp_rmdir(sftp, path) libssh2_sftp_rmdir_ex((sftp), (path), strlen(path))
LIBSSH2_API int libssh2_sftp_stat_ex(LIBSSH2_SFTP *sftp, char *path, int path_len, int stat_type, LIBSSH2_SFTP_ATTRIBUTES *attrs); LIBSSH2_API int libssh2_sftp_stat_ex(LIBSSH2_SFTP *sftp, const char *path, unsigned int path_len, int stat_type, LIBSSH2_SFTP_ATTRIBUTES *attrs);
#define libssh2_sftp_stat(sftp, path, attrs) libssh2_sftp_stat_ex((sftp), (path), strlen(path), LIBSSH2_SFTP_STAT, (attrs)) #define libssh2_sftp_stat(sftp, path, attrs) libssh2_sftp_stat_ex((sftp), (path), strlen(path), LIBSSH2_SFTP_STAT, (attrs))
#define libssh2_sftp_lstat(sftp, path, attrs) libssh2_sftp_stat_ex((sftp), (path), strlen(path), LIBSSH2_SFTP_LSTAT, (attrs)) #define libssh2_sftp_lstat(sftp, path, attrs) libssh2_sftp_stat_ex((sftp), (path), strlen(path), LIBSSH2_SFTP_LSTAT, (attrs))
#define libssh2_sftp_setstat(sftp, path, attrs) libssh2_sftp_stat_ex((sftp), (path), strlen(path), LIBSSH2_SFTP_SETSTAT, (attrs)) #define libssh2_sftp_setstat(sftp, path, attrs) libssh2_sftp_stat_ex((sftp), (path), strlen(path), LIBSSH2_SFTP_SETSTAT, (attrs))
LIBSSH2_API int libssh2_sftp_symlink_ex(LIBSSH2_SFTP *sftp, const char *path, int path_len, char *target, int target_len, int link_type); LIBSSH2_API int libssh2_sftp_symlink_ex(LIBSSH2_SFTP *sftp, const char *path, unsigned int path_len, char *target, unsigned int target_len, int link_type);
#define libssh2_sftp_symlink(sftp, orig, linkpath) libssh2_sftp_symlink_ex((sftp), (orig), strlen(orig), (linkpath), strlen(linkpath), LIBSSH2_SFTP_SYMLINK) #define libssh2_sftp_symlink(sftp, orig, linkpath) libssh2_sftp_symlink_ex((sftp), (orig), strlen(orig), (linkpath), strlen(linkpath), LIBSSH2_SFTP_SYMLINK)
#define libssh2_sftp_readlink(sftp, path, target, maxlen) libssh2_sftp_symlink_ex((sftp), (path), strlen(path), (target), (maxlen), LIBSSH2_SFTP_READLINK) #define libssh2_sftp_readlink(sftp, path, target, maxlen) libssh2_sftp_symlink_ex((sftp), (path), strlen(path), (target), (maxlen), LIBSSH2_SFTP_READLINK)
#define libssh2_sftp_realpath(sftp, path, target, maxlen) libssh2_sftp_symlink_ex((sftp), (path), strlen(path), (target), (maxlen), LIBSSH2_SFTP_REALPATH) #define libssh2_sftp_realpath(sftp, path, target, maxlen) libssh2_sftp_symlink_ex((sftp), (path), strlen(path), (target), (maxlen), LIBSSH2_SFTP_REALPATH)
LIBSSH2_API void libssh2_sftp_set_blocking(LIBSSH2_SFTP *session, int blocking);
LIBSSH2_API int libssh2_sftp_get_blocking(LIBSSH2_SFTP *session);
#ifdef __cplusplus #ifdef __cplusplus
} /* extern "C" */ } /* extern "C" */
#endif #endif

View File

@@ -1,251 +0,0 @@
#!/bin/sh
#
# install - install a program, script, or datafile
# This comes from X11R5 (mit/util/scripts/install.sh).
#
# Copyright 1991 by the Massachusetts Institute of Technology
#
# Permission to use, copy, modify, distribute, and sell this software and its
# documentation for any purpose is hereby granted without fee, provided that
# the above copyright notice appear in all copies and that both that
# copyright notice and this permission notice appear in supporting
# documentation, and that the name of M.I.T. not be used in advertising or
# publicity pertaining to distribution of the software without specific,
# written prior permission. M.I.T. makes no representations about the
# suitability of this software for any purpose. It is provided "as is"
# without express or implied warranty.
#
# Calling this script install-sh is preferred over install.sh, to prevent
# `make' implicit rules from creating a file called install from it
# when there is no Makefile.
#
# This script is compatible with the BSD install script, but was written
# from scratch. It can only install one file at a time, a restriction
# shared with many OS's install programs.
# set DOITPROG to echo to test this script
# Don't use :- since 4.3BSD and earlier shells don't like it.
doit="${DOITPROG-}"
# put in absolute paths if you don't have them in your path; or use env. vars.
mvprog="${MVPROG-mv}"
cpprog="${CPPROG-cp}"
chmodprog="${CHMODPROG-chmod}"
chownprog="${CHOWNPROG-chown}"
chgrpprog="${CHGRPPROG-chgrp}"
stripprog="${STRIPPROG-strip}"
rmprog="${RMPROG-rm}"
mkdirprog="${MKDIRPROG-mkdir}"
transformbasename=""
transform_arg=""
instcmd="$mvprog"
chmodcmd="$chmodprog 0755"
chowncmd=""
chgrpcmd=""
stripcmd=""
rmcmd="$rmprog -f"
mvcmd="$mvprog"
src=""
dst=""
dir_arg=""
while [ x"$1" != x ]; do
case $1 in
-c) instcmd="$cpprog"
shift
continue;;
-d) dir_arg=true
shift
continue;;
-m) chmodcmd="$chmodprog $2"
shift
shift
continue;;
-o) chowncmd="$chownprog $2"
shift
shift
continue;;
-g) chgrpcmd="$chgrpprog $2"
shift
shift
continue;;
-s) stripcmd="$stripprog"
shift
continue;;
-t=*) transformarg=`echo $1 | sed 's/-t=//'`
shift
continue;;
-b=*) transformbasename=`echo $1 | sed 's/-b=//'`
shift
continue;;
*) if [ x"$src" = x ]
then
src=$1
else
# this colon is to work around a 386BSD /bin/sh bug
:
dst=$1
fi
shift
continue;;
esac
done
if [ x"$src" = x ]
then
echo "install: no input file specified"
exit 1
else
true
fi
if [ x"$dir_arg" != x ]; then
dst=$src
src=""
if [ -d $dst ]; then
instcmd=:
chmodcmd=""
else
instcmd=mkdir
fi
else
# Waiting for this to be detected by the "$instcmd $src $dsttmp" command
# might cause directories to be created, which would be especially bad
# if $src (and thus $dsttmp) contains '*'.
if [ -f $src -o -d $src ]
then
true
else
echo "install: $src does not exist"
exit 1
fi
if [ x"$dst" = x ]
then
echo "install: no destination specified"
exit 1
else
true
fi
# If destination is a directory, append the input filename; if your system
# does not like double slashes in filenames, you may need to add some logic
if [ -d $dst ]
then
dst="$dst"/`basename $src`
else
true
fi
fi
## this sed command emulates the dirname command
dstdir=`echo $dst | sed -e 's,[^/]*$,,;s,/$,,;s,^$,.,'`
# Make sure that the destination directory exists.
# this part is taken from Noah Friedman's mkinstalldirs script
# Skip lots of stat calls in the usual case.
if [ ! -d "$dstdir" ]; then
defaultIFS='
'
IFS="${IFS-${defaultIFS}}"
oIFS="${IFS}"
# Some sh's can't handle IFS=/ for some reason.
IFS='%'
set - `echo ${dstdir} | sed -e 's@/@%@g' -e 's@^%@/@'`
IFS="${oIFS}"
pathcomp=''
while [ $# -ne 0 ] ; do
pathcomp="${pathcomp}${1}"
shift
if [ ! -d "${pathcomp}" ] ;
then
$mkdirprog "${pathcomp}"
else
true
fi
pathcomp="${pathcomp}/"
done
fi
if [ x"$dir_arg" != x ]
then
$doit $instcmd $dst &&
if [ x"$chowncmd" != x ]; then $doit $chowncmd $dst; else true ; fi &&
if [ x"$chgrpcmd" != x ]; then $doit $chgrpcmd $dst; else true ; fi &&
if [ x"$stripcmd" != x ]; then $doit $stripcmd $dst; else true ; fi &&
if [ x"$chmodcmd" != x ]; then $doit $chmodcmd $dst; else true ; fi
else
# If we're going to rename the final executable, determine the name now.
if [ x"$transformarg" = x ]
then
dstfile=`basename $dst`
else
dstfile=`basename $dst $transformbasename |
sed $transformarg`$transformbasename
fi
# don't allow the sed command to completely eliminate the filename
if [ x"$dstfile" = x ]
then
dstfile=`basename $dst`
else
true
fi
# Make a temp file name in the proper directory.
dsttmp=$dstdir/#inst.$$#
# Move or copy the file name to the temp name
$doit $instcmd $src $dsttmp &&
trap "rm -f ${dsttmp}" 0 &&
# and set any options; do chmod last to preserve setuid bits
# If any of these fail, we abort the whole thing. If we want to
# ignore errors from any of these, just make sure not to ignore
# errors from the above "$doit $instcmd $src $dsttmp" command.
if [ x"$chowncmd" != x ]; then $doit $chowncmd $dsttmp; else true;fi &&
if [ x"$chgrpcmd" != x ]; then $doit $chgrpcmd $dsttmp; else true;fi &&
if [ x"$stripcmd" != x ]; then $doit $stripcmd $dsttmp; else true;fi &&
if [ x"$chmodcmd" != x ]; then $doit $chmodcmd $dsttmp; else true;fi &&
# Now rename the file to the real destination.
$doit $rmcmd -f $dstdir/$dstfile &&
$doit $mvcmd $dsttmp $dstdir/$dstfile
fi &&
exit 0

44
m4/autobuild.m4 Normal file
View File

@@ -0,0 +1,44 @@
# autobuild.m4 serial 3
# Copyright (C) 2004, 2006 Simon Josefsson
#
# This file is free software, distributed under the terms of the GNU
# General Public License. As a special exception to the GNU General
# Public License, this file may be distributed as part of a program
# that contains a configuration script generated by Autoconf, under
# the same distribution terms as the rest of that program.
#
# This file can can be used in projects which are not available under
# the GNU General Public License or the GNU Library General Public
# License but which still want to provide support for Autobuild.
# Usage: AB_INIT([MODE]).
AC_DEFUN([AB_INIT],
[
AC_REQUIRE([AC_CANONICAL_BUILD])
AC_REQUIRE([AC_CANONICAL_HOST])
if test -z "$AB_PACKAGE"; then
AB_PACKAGE=${PACKAGE_NAME:-$PACKAGE}
fi
AC_MSG_NOTICE([autobuild project... $AB_PACKAGE])
if test -z "$AB_VERSION"; then
AB_VERSION=${PACKAGE_VERSION:-$VERSION}
fi
AC_MSG_NOTICE([autobuild revision... $AB_VERSION])
hostname=`hostname`
if test "$hostname"; then
AC_MSG_NOTICE([autobuild hostname... $hostname])
fi
ifelse([$1],[],,[AC_MSG_NOTICE([autobuild mode... $1])])
date=`date +%Y%m%d-%H%M%S`
if test "$?" != 0; then
date=`date`
fi
if test "$date"; then
AC_MSG_NOTICE([autobuild timestamp... $date])
fi
])

110
m4/lib-ld.m4 Normal file
View File

@@ -0,0 +1,110 @@
# lib-ld.m4 serial 3 (gettext-0.13)
dnl Copyright (C) 1996-2003 Free Software Foundation, Inc.
dnl This file is free software; the Free Software Foundation
dnl gives unlimited permission to copy and/or distribute it,
dnl with or without modifications, as long as this notice is preserved.
dnl Subroutines of libtool.m4,
dnl with replacements s/AC_/AC_LIB/ and s/lt_cv/acl_cv/ to avoid collision
dnl with libtool.m4.
dnl From libtool-1.4. Sets the variable with_gnu_ld to yes or no.
AC_DEFUN([AC_LIB_PROG_LD_GNU],
[AC_CACHE_CHECK([if the linker ($LD) is GNU ld], acl_cv_prog_gnu_ld,
[# I'd rather use --version here, but apparently some GNU ld's only accept -v.
case `$LD -v 2>&1 </dev/null` in
*GNU* | *'with BFD'*)
acl_cv_prog_gnu_ld=yes ;;
*)
acl_cv_prog_gnu_ld=no ;;
esac])
with_gnu_ld=$acl_cv_prog_gnu_ld
])
dnl From libtool-1.4. Sets the variable LD.
AC_DEFUN([AC_LIB_PROG_LD],
[AC_ARG_WITH(gnu-ld,
[ --with-gnu-ld assume the C compiler uses GNU ld [default=no]],
test "$withval" = no || with_gnu_ld=yes, with_gnu_ld=no)
AC_REQUIRE([AC_PROG_CC])dnl
AC_REQUIRE([AC_CANONICAL_HOST])dnl
# Prepare PATH_SEPARATOR.
# The user is always right.
if test "${PATH_SEPARATOR+set}" != set; then
echo "#! /bin/sh" >conf$$.sh
echo "exit 0" >>conf$$.sh
chmod +x conf$$.sh
if (PATH="/nonexistent;."; conf$$.sh) >/dev/null 2>&1; then
PATH_SEPARATOR=';'
else
PATH_SEPARATOR=:
fi
rm -f conf$$.sh
fi
ac_prog=ld
if test "$GCC" = yes; then
# Check if gcc -print-prog-name=ld gives a path.
AC_MSG_CHECKING([for ld used by GCC])
case $host in
*-*-mingw*)
# gcc leaves a trailing carriage return which upsets mingw
ac_prog=`($CC -print-prog-name=ld) 2>&5 | tr -d '\015'` ;;
*)
ac_prog=`($CC -print-prog-name=ld) 2>&5` ;;
esac
case $ac_prog in
# Accept absolute paths.
[[\\/]* | [A-Za-z]:[\\/]*)]
[re_direlt='/[^/][^/]*/\.\./']
# Canonicalize the path of ld
ac_prog=`echo $ac_prog| sed 's%\\\\%/%g'`
while echo $ac_prog | grep "$re_direlt" > /dev/null 2>&1; do
ac_prog=`echo $ac_prog| sed "s%$re_direlt%/%"`
done
test -z "$LD" && LD="$ac_prog"
;;
"")
# If it fails, then pretend we aren't using GCC.
ac_prog=ld
;;
*)
# If it is relative, then search for the first ld in PATH.
with_gnu_ld=unknown
;;
esac
elif test "$with_gnu_ld" = yes; then
AC_MSG_CHECKING([for GNU ld])
else
AC_MSG_CHECKING([for non-GNU ld])
fi
AC_CACHE_VAL(acl_cv_path_LD,
[if test -z "$LD"; then
IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS="${IFS}${PATH_SEPARATOR-:}"
for ac_dir in $PATH; do
test -z "$ac_dir" && ac_dir=.
if test -f "$ac_dir/$ac_prog" || test -f "$ac_dir/$ac_prog$ac_exeext"; then
acl_cv_path_LD="$ac_dir/$ac_prog"
# Check to see if the program is GNU ld. I'd rather use --version,
# but apparently some GNU ld's only accept -v.
# Break only if it was the GNU/non-GNU ld that we prefer.
case `"$acl_cv_path_LD" -v 2>&1 < /dev/null` in
*GNU* | *'with BFD'*)
test "$with_gnu_ld" != no && break ;;
*)
test "$with_gnu_ld" != yes && break ;;
esac
fi
done
IFS="$ac_save_ifs"
else
acl_cv_path_LD="$LD" # Let the user override the test with a path.
fi])
LD="$acl_cv_path_LD"
if test -n "$LD"; then
AC_MSG_RESULT($LD)
else
AC_MSG_RESULT(no)
fi
test -z "$LD" && AC_MSG_ERROR([no acceptable ld found in \$PATH])
AC_LIB_PROG_LD_GNU
])

709
m4/lib-link.m4 Normal file
View File

@@ -0,0 +1,709 @@
# lib-link.m4 serial 13 (gettext-0.16.2)
dnl Copyright (C) 2001-2007 Free Software Foundation, Inc.
dnl This file is free software; the Free Software Foundation
dnl gives unlimited permission to copy and/or distribute it,
dnl with or without modifications, as long as this notice is preserved.
dnl From Bruno Haible.
AC_PREREQ(2.54)
dnl AC_LIB_LINKFLAGS(name [, dependencies]) searches for libname and
dnl the libraries corresponding to explicit and implicit dependencies.
dnl Sets and AC_SUBSTs the LIB${NAME} and LTLIB${NAME} variables and
dnl augments the CPPFLAGS variable.
dnl Sets and AC_SUBSTs the LIB${NAME}_PREFIX variable to nonempty if libname
dnl was found in ${LIB${NAME}_PREFIX}/$acl_libdirstem.
AC_DEFUN([AC_LIB_LINKFLAGS],
[
AC_REQUIRE([AC_LIB_PREPARE_PREFIX])
AC_REQUIRE([AC_LIB_RPATH])
define([Name],[translit([$1],[./-], [___])])
define([NAME],[translit([$1],[abcdefghijklmnopqrstuvwxyz./-],
[ABCDEFGHIJKLMNOPQRSTUVWXYZ___])])
AC_CACHE_CHECK([how to link with lib[]$1], [ac_cv_lib[]Name[]_libs], [
AC_LIB_LINKFLAGS_BODY([$1], [$2])
ac_cv_lib[]Name[]_libs="$LIB[]NAME"
ac_cv_lib[]Name[]_ltlibs="$LTLIB[]NAME"
ac_cv_lib[]Name[]_cppflags="$INC[]NAME"
ac_cv_lib[]Name[]_prefix="$LIB[]NAME[]_PREFIX"
])
LIB[]NAME="$ac_cv_lib[]Name[]_libs"
LTLIB[]NAME="$ac_cv_lib[]Name[]_ltlibs"
INC[]NAME="$ac_cv_lib[]Name[]_cppflags"
LIB[]NAME[]_PREFIX="$ac_cv_lib[]Name[]_prefix"
AC_LIB_APPENDTOVAR([CPPFLAGS], [$INC]NAME)
AC_SUBST([LIB]NAME)
AC_SUBST([LTLIB]NAME)
AC_SUBST([LIB]NAME[_PREFIX])
dnl Also set HAVE_LIB[]NAME so that AC_LIB_HAVE_LINKFLAGS can reuse the
dnl results of this search when this library appears as a dependency.
HAVE_LIB[]NAME=yes
undefine([Name])
undefine([NAME])
])
dnl AC_LIB_HAVE_LINKFLAGS(name, dependencies, includes, testcode)
dnl searches for libname and the libraries corresponding to explicit and
dnl implicit dependencies, together with the specified include files and
dnl the ability to compile and link the specified testcode. If found, it
dnl sets and AC_SUBSTs HAVE_LIB${NAME}=yes and the LIB${NAME} and
dnl LTLIB${NAME} variables and augments the CPPFLAGS variable, and
dnl #defines HAVE_LIB${NAME} to 1. Otherwise, it sets and AC_SUBSTs
dnl HAVE_LIB${NAME}=no and LIB${NAME} and LTLIB${NAME} to empty.
dnl Sets and AC_SUBSTs the LIB${NAME}_PREFIX variable to nonempty if libname
dnl was found in ${LIB${NAME}_PREFIX}/$acl_libdirstem.
AC_DEFUN([AC_LIB_HAVE_LINKFLAGS],
[
AC_REQUIRE([AC_LIB_PREPARE_PREFIX])
AC_REQUIRE([AC_LIB_RPATH])
define([Name],[translit([$1],[./-], [___])])
define([NAME],[translit([$1],[abcdefghijklmnopqrstuvwxyz./-],
[ABCDEFGHIJKLMNOPQRSTUVWXYZ___])])
dnl Search for lib[]Name and define LIB[]NAME, LTLIB[]NAME and INC[]NAME
dnl accordingly.
AC_LIB_LINKFLAGS_BODY([$1], [$2])
dnl Add $INC[]NAME to CPPFLAGS before performing the following checks,
dnl because if the user has installed lib[]Name and not disabled its use
dnl via --without-lib[]Name-prefix, he wants to use it.
ac_save_CPPFLAGS="$CPPFLAGS"
AC_LIB_APPENDTOVAR([CPPFLAGS], [$INC]NAME)
AC_CACHE_CHECK([for lib[]$1], [ac_cv_lib[]Name], [
ac_save_LIBS="$LIBS"
LIBS="$LIBS $LIB[]NAME"
AC_TRY_LINK([$3], [$4], [ac_cv_lib[]Name=yes], [ac_cv_lib[]Name=no])
LIBS="$ac_save_LIBS"
])
if test "$ac_cv_lib[]Name" = yes; then
HAVE_LIB[]NAME=yes
AC_DEFINE([HAVE_LIB]NAME, 1, [Define if you have the $1 library.])
AC_MSG_CHECKING([how to link with lib[]$1])
AC_MSG_RESULT([$LIB[]NAME])
else
HAVE_LIB[]NAME=no
dnl If $LIB[]NAME didn't lead to a usable library, we don't need
dnl $INC[]NAME either.
CPPFLAGS="$ac_save_CPPFLAGS"
LIB[]NAME=
LTLIB[]NAME=
LIB[]NAME[]_PREFIX=
fi
AC_SUBST([HAVE_LIB]NAME)
AC_SUBST([LIB]NAME)
AC_SUBST([LTLIB]NAME)
AC_SUBST([LIB]NAME[_PREFIX])
undefine([Name])
undefine([NAME])
])
dnl Determine the platform dependent parameters needed to use rpath:
dnl acl_libext,
dnl acl_shlibext,
dnl acl_hardcode_libdir_flag_spec,
dnl acl_hardcode_libdir_separator,
dnl acl_hardcode_direct,
dnl acl_hardcode_minus_L.
AC_DEFUN([AC_LIB_RPATH],
[
dnl Tell automake >= 1.10 to complain if config.rpath is missing.
m4_ifdef([AC_REQUIRE_AUX_FILE], [AC_REQUIRE_AUX_FILE([config.rpath])])
AC_REQUIRE([AC_PROG_CC]) dnl we use $CC, $GCC, $LDFLAGS
AC_REQUIRE([AC_LIB_PROG_LD]) dnl we use $LD, $with_gnu_ld
AC_REQUIRE([AC_CANONICAL_HOST]) dnl we use $host
AC_REQUIRE([AC_CONFIG_AUX_DIR_DEFAULT]) dnl we use $ac_aux_dir
AC_CACHE_CHECK([for shared library run path origin], acl_cv_rpath, [
CC="$CC" GCC="$GCC" LDFLAGS="$LDFLAGS" LD="$LD" with_gnu_ld="$with_gnu_ld" \
${CONFIG_SHELL-/bin/sh} "$ac_aux_dir/config.rpath" "$host" > conftest.sh
. ./conftest.sh
rm -f ./conftest.sh
acl_cv_rpath=done
])
wl="$acl_cv_wl"
acl_libext="$acl_cv_libext"
acl_shlibext="$acl_cv_shlibext"
acl_libname_spec="$acl_cv_libname_spec"
acl_library_names_spec="$acl_cv_library_names_spec"
acl_hardcode_libdir_flag_spec="$acl_cv_hardcode_libdir_flag_spec"
acl_hardcode_libdir_separator="$acl_cv_hardcode_libdir_separator"
acl_hardcode_direct="$acl_cv_hardcode_direct"
acl_hardcode_minus_L="$acl_cv_hardcode_minus_L"
dnl Determine whether the user wants rpath handling at all.
AC_ARG_ENABLE(rpath,
[ --disable-rpath do not hardcode runtime library paths],
:, enable_rpath=yes)
])
dnl AC_LIB_LINKFLAGS_BODY(name [, dependencies]) searches for libname and
dnl the libraries corresponding to explicit and implicit dependencies.
dnl Sets the LIB${NAME}, LTLIB${NAME} and INC${NAME} variables.
dnl Also, sets the LIB${NAME}_PREFIX variable to nonempty if libname was found
dnl in ${LIB${NAME}_PREFIX}/$acl_libdirstem.
AC_DEFUN([AC_LIB_LINKFLAGS_BODY],
[
AC_REQUIRE([AC_LIB_PREPARE_MULTILIB])
define([NAME],[translit([$1],[abcdefghijklmnopqrstuvwxyz./-],
[ABCDEFGHIJKLMNOPQRSTUVWXYZ___])])
dnl Autoconf >= 2.61 supports dots in --with options.
define([N_A_M_E],[m4_if(m4_version_compare(m4_defn([m4_PACKAGE_VERSION]),[2.61]),[-1],[translit([$1],[.],[_])],[$1])])
dnl By default, look in $includedir and $libdir.
use_additional=yes
AC_LIB_WITH_FINAL_PREFIX([
eval additional_includedir=\"$includedir\"
eval additional_libdir=\"$libdir\"
])
AC_LIB_ARG_WITH([lib]N_A_M_E[-prefix],
[ --with-lib]N_A_M_E[-prefix[=DIR] search for lib$1 in DIR/include and DIR/lib
--without-lib]N_A_M_E[-prefix don't search for lib$1 in includedir and libdir],
[
if test "X$withval" = "Xno"; then
use_additional=no
else
if test "X$withval" = "X"; then
AC_LIB_WITH_FINAL_PREFIX([
eval additional_includedir=\"$includedir\"
eval additional_libdir=\"$libdir\"
])
else
additional_includedir="$withval/include"
additional_libdir="$withval/$acl_libdirstem"
fi
fi
])
dnl Search the library and its dependencies in $additional_libdir and
dnl $LDFLAGS. Using breadth-first-seach.
LIB[]NAME=
LTLIB[]NAME=
INC[]NAME=
LIB[]NAME[]_PREFIX=
rpathdirs=
ltrpathdirs=
names_already_handled=
names_next_round='$1 $2'
while test -n "$names_next_round"; do
names_this_round="$names_next_round"
names_next_round=
for name in $names_this_round; do
already_handled=
for n in $names_already_handled; do
if test "$n" = "$name"; then
already_handled=yes
break
fi
done
if test -z "$already_handled"; then
names_already_handled="$names_already_handled $name"
dnl See if it was already located by an earlier AC_LIB_LINKFLAGS
dnl or AC_LIB_HAVE_LINKFLAGS call.
uppername=`echo "$name" | sed -e 'y|abcdefghijklmnopqrstuvwxyz./-|ABCDEFGHIJKLMNOPQRSTUVWXYZ___|'`
eval value=\"\$HAVE_LIB$uppername\"
if test -n "$value"; then
if test "$value" = yes; then
eval value=\"\$LIB$uppername\"
test -z "$value" || LIB[]NAME="${LIB[]NAME}${LIB[]NAME:+ }$value"
eval value=\"\$LTLIB$uppername\"
test -z "$value" || LTLIB[]NAME="${LTLIB[]NAME}${LTLIB[]NAME:+ }$value"
else
dnl An earlier call to AC_LIB_HAVE_LINKFLAGS has determined
dnl that this library doesn't exist. So just drop it.
:
fi
else
dnl Search the library lib$name in $additional_libdir and $LDFLAGS
dnl and the already constructed $LIBNAME/$LTLIBNAME.
found_dir=
found_la=
found_so=
found_a=
eval libname=\"$acl_libname_spec\" # typically: libname=lib$name
if test -n "$acl_shlibext"; then
shrext=".$acl_shlibext" # typically: shrext=.so
else
shrext=
fi
if test $use_additional = yes; then
dir="$additional_libdir"
dnl The same code as in the loop below:
dnl First look for a shared library.
if test -n "$acl_shlibext"; then
if test -f "$dir/$libname$shrext"; then
found_dir="$dir"
found_so="$dir/$libname$shrext"
else
if test "$acl_library_names_spec" = '$libname$shrext$versuffix'; then
ver=`(cd "$dir" && \
for f in "$libname$shrext".*; do echo "$f"; done \
| sed -e "s,^$libname$shrext\\\\.,," \
| sort -t '.' -n -r -k1,1 -k2,2 -k3,3 -k4,4 -k5,5 \
| sed 1q ) 2>/dev/null`
if test -n "$ver" && test -f "$dir/$libname$shrext.$ver"; then
found_dir="$dir"
found_so="$dir/$libname$shrext.$ver"
fi
else
eval library_names=\"$acl_library_names_spec\"
for f in $library_names; do
if test -f "$dir/$f"; then
found_dir="$dir"
found_so="$dir/$f"
break
fi
done
fi
fi
fi
dnl Then look for a static library.
if test "X$found_dir" = "X"; then
if test -f "$dir/$libname.$acl_libext"; then
found_dir="$dir"
found_a="$dir/$libname.$acl_libext"
fi
fi
if test "X$found_dir" != "X"; then
if test -f "$dir/$libname.la"; then
found_la="$dir/$libname.la"
fi
fi
fi
if test "X$found_dir" = "X"; then
for x in $LDFLAGS $LTLIB[]NAME; do
AC_LIB_WITH_FINAL_PREFIX([eval x=\"$x\"])
case "$x" in
-L*)
dir=`echo "X$x" | sed -e 's/^X-L//'`
dnl First look for a shared library.
if test -n "$acl_shlibext"; then
if test -f "$dir/$libname$shrext"; then
found_dir="$dir"
found_so="$dir/$libname$shrext"
else
if test "$acl_library_names_spec" = '$libname$shrext$versuffix'; then
ver=`(cd "$dir" && \
for f in "$libname$shrext".*; do echo "$f"; done \
| sed -e "s,^$libname$shrext\\\\.,," \
| sort -t '.' -n -r -k1,1 -k2,2 -k3,3 -k4,4 -k5,5 \
| sed 1q ) 2>/dev/null`
if test -n "$ver" && test -f "$dir/$libname$shrext.$ver"; then
found_dir="$dir"
found_so="$dir/$libname$shrext.$ver"
fi
else
eval library_names=\"$acl_library_names_spec\"
for f in $library_names; do
if test -f "$dir/$f"; then
found_dir="$dir"
found_so="$dir/$f"
break
fi
done
fi
fi
fi
dnl Then look for a static library.
if test "X$found_dir" = "X"; then
if test -f "$dir/$libname.$acl_libext"; then
found_dir="$dir"
found_a="$dir/$libname.$acl_libext"
fi
fi
if test "X$found_dir" != "X"; then
if test -f "$dir/$libname.la"; then
found_la="$dir/$libname.la"
fi
fi
;;
esac
if test "X$found_dir" != "X"; then
break
fi
done
fi
if test "X$found_dir" != "X"; then
dnl Found the library.
LTLIB[]NAME="${LTLIB[]NAME}${LTLIB[]NAME:+ }-L$found_dir -l$name"
if test "X$found_so" != "X"; then
dnl Linking with a shared library. We attempt to hardcode its
dnl directory into the executable's runpath, unless it's the
dnl standard /usr/lib.
if test "$enable_rpath" = no || test "X$found_dir" = "X/usr/$acl_libdirstem"; then
dnl No hardcoding is needed.
LIB[]NAME="${LIB[]NAME}${LIB[]NAME:+ }$found_so"
else
dnl Use an explicit option to hardcode DIR into the resulting
dnl binary.
dnl Potentially add DIR to ltrpathdirs.
dnl The ltrpathdirs will be appended to $LTLIBNAME at the end.
haveit=
for x in $ltrpathdirs; do
if test "X$x" = "X$found_dir"; then
haveit=yes
break
fi
done
if test -z "$haveit"; then
ltrpathdirs="$ltrpathdirs $found_dir"
fi
dnl The hardcoding into $LIBNAME is system dependent.
if test "$acl_hardcode_direct" = yes; then
dnl Using DIR/libNAME.so during linking hardcodes DIR into the
dnl resulting binary.
LIB[]NAME="${LIB[]NAME}${LIB[]NAME:+ }$found_so"
else
if test -n "$acl_hardcode_libdir_flag_spec" && test "$acl_hardcode_minus_L" = no; then
dnl Use an explicit option to hardcode DIR into the resulting
dnl binary.
LIB[]NAME="${LIB[]NAME}${LIB[]NAME:+ }$found_so"
dnl Potentially add DIR to rpathdirs.
dnl The rpathdirs will be appended to $LIBNAME at the end.
haveit=
for x in $rpathdirs; do
if test "X$x" = "X$found_dir"; then
haveit=yes
break
fi
done
if test -z "$haveit"; then
rpathdirs="$rpathdirs $found_dir"
fi
else
dnl Rely on "-L$found_dir".
dnl But don't add it if it's already contained in the LDFLAGS
dnl or the already constructed $LIBNAME
haveit=
for x in $LDFLAGS $LIB[]NAME; do
AC_LIB_WITH_FINAL_PREFIX([eval x=\"$x\"])
if test "X$x" = "X-L$found_dir"; then
haveit=yes
break
fi
done
if test -z "$haveit"; then
LIB[]NAME="${LIB[]NAME}${LIB[]NAME:+ }-L$found_dir"
fi
if test "$acl_hardcode_minus_L" != no; then
dnl FIXME: Not sure whether we should use
dnl "-L$found_dir -l$name" or "-L$found_dir $found_so"
dnl here.
LIB[]NAME="${LIB[]NAME}${LIB[]NAME:+ }$found_so"
else
dnl We cannot use $acl_hardcode_runpath_var and LD_RUN_PATH
dnl here, because this doesn't fit in flags passed to the
dnl compiler. So give up. No hardcoding. This affects only
dnl very old systems.
dnl FIXME: Not sure whether we should use
dnl "-L$found_dir -l$name" or "-L$found_dir $found_so"
dnl here.
LIB[]NAME="${LIB[]NAME}${LIB[]NAME:+ }-l$name"
fi
fi
fi
fi
else
if test "X$found_a" != "X"; then
dnl Linking with a static library.
LIB[]NAME="${LIB[]NAME}${LIB[]NAME:+ }$found_a"
else
dnl We shouldn't come here, but anyway it's good to have a
dnl fallback.
LIB[]NAME="${LIB[]NAME}${LIB[]NAME:+ }-L$found_dir -l$name"
fi
fi
dnl Assume the include files are nearby.
additional_includedir=
case "$found_dir" in
*/$acl_libdirstem | */$acl_libdirstem/)
basedir=`echo "X$found_dir" | sed -e 's,^X,,' -e "s,/$acl_libdirstem/"'*$,,'`
LIB[]NAME[]_PREFIX="$basedir"
additional_includedir="$basedir/include"
;;
esac
if test "X$additional_includedir" != "X"; then
dnl Potentially add $additional_includedir to $INCNAME.
dnl But don't add it
dnl 1. if it's the standard /usr/include,
dnl 2. if it's /usr/local/include and we are using GCC on Linux,
dnl 3. if it's already present in $CPPFLAGS or the already
dnl constructed $INCNAME,
dnl 4. if it doesn't exist as a directory.
if test "X$additional_includedir" != "X/usr/include"; then
haveit=
if test "X$additional_includedir" = "X/usr/local/include"; then
if test -n "$GCC"; then
case $host_os in
linux* | gnu* | k*bsd*-gnu) haveit=yes;;
esac
fi
fi
if test -z "$haveit"; then
for x in $CPPFLAGS $INC[]NAME; do
AC_LIB_WITH_FINAL_PREFIX([eval x=\"$x\"])
if test "X$x" = "X-I$additional_includedir"; then
haveit=yes
break
fi
done
if test -z "$haveit"; then
if test -d "$additional_includedir"; then
dnl Really add $additional_includedir to $INCNAME.
INC[]NAME="${INC[]NAME}${INC[]NAME:+ }-I$additional_includedir"
fi
fi
fi
fi
fi
dnl Look for dependencies.
if test -n "$found_la"; then
dnl Read the .la file. It defines the variables
dnl dlname, library_names, old_library, dependency_libs, current,
dnl age, revision, installed, dlopen, dlpreopen, libdir.
save_libdir="$libdir"
case "$found_la" in
*/* | *\\*) . "$found_la" ;;
*) . "./$found_la" ;;
esac
libdir="$save_libdir"
dnl We use only dependency_libs.
for dep in $dependency_libs; do
case "$dep" in
-L*)
additional_libdir=`echo "X$dep" | sed -e 's/^X-L//'`
dnl Potentially add $additional_libdir to $LIBNAME and $LTLIBNAME.
dnl But don't add it
dnl 1. if it's the standard /usr/lib,
dnl 2. if it's /usr/local/lib and we are using GCC on Linux,
dnl 3. if it's already present in $LDFLAGS or the already
dnl constructed $LIBNAME,
dnl 4. if it doesn't exist as a directory.
if test "X$additional_libdir" != "X/usr/$acl_libdirstem"; then
haveit=
if test "X$additional_libdir" = "X/usr/local/$acl_libdirstem"; then
if test -n "$GCC"; then
case $host_os in
linux* | gnu* | k*bsd*-gnu) haveit=yes;;
esac
fi
fi
if test -z "$haveit"; then
haveit=
for x in $LDFLAGS $LIB[]NAME; do
AC_LIB_WITH_FINAL_PREFIX([eval x=\"$x\"])
if test "X$x" = "X-L$additional_libdir"; then
haveit=yes
break
fi
done
if test -z "$haveit"; then
if test -d "$additional_libdir"; then
dnl Really add $additional_libdir to $LIBNAME.
LIB[]NAME="${LIB[]NAME}${LIB[]NAME:+ }-L$additional_libdir"
fi
fi
haveit=
for x in $LDFLAGS $LTLIB[]NAME; do
AC_LIB_WITH_FINAL_PREFIX([eval x=\"$x\"])
if test "X$x" = "X-L$additional_libdir"; then
haveit=yes
break
fi
done
if test -z "$haveit"; then
if test -d "$additional_libdir"; then
dnl Really add $additional_libdir to $LTLIBNAME.
LTLIB[]NAME="${LTLIB[]NAME}${LTLIB[]NAME:+ }-L$additional_libdir"
fi
fi
fi
fi
;;
-R*)
dir=`echo "X$dep" | sed -e 's/^X-R//'`
if test "$enable_rpath" != no; then
dnl Potentially add DIR to rpathdirs.
dnl The rpathdirs will be appended to $LIBNAME at the end.
haveit=
for x in $rpathdirs; do
if test "X$x" = "X$dir"; then
haveit=yes
break
fi
done
if test -z "$haveit"; then
rpathdirs="$rpathdirs $dir"
fi
dnl Potentially add DIR to ltrpathdirs.
dnl The ltrpathdirs will be appended to $LTLIBNAME at the end.
haveit=
for x in $ltrpathdirs; do
if test "X$x" = "X$dir"; then
haveit=yes
break
fi
done
if test -z "$haveit"; then
ltrpathdirs="$ltrpathdirs $dir"
fi
fi
;;
-l*)
dnl Handle this in the next round.
names_next_round="$names_next_round "`echo "X$dep" | sed -e 's/^X-l//'`
;;
*.la)
dnl Handle this in the next round. Throw away the .la's
dnl directory; it is already contained in a preceding -L
dnl option.
names_next_round="$names_next_round "`echo "X$dep" | sed -e 's,^X.*/,,' -e 's,^lib,,' -e 's,\.la$,,'`
;;
*)
dnl Most likely an immediate library name.
LIB[]NAME="${LIB[]NAME}${LIB[]NAME:+ }$dep"
LTLIB[]NAME="${LTLIB[]NAME}${LTLIB[]NAME:+ }$dep"
;;
esac
done
fi
else
dnl Didn't find the library; assume it is in the system directories
dnl known to the linker and runtime loader. (All the system
dnl directories known to the linker should also be known to the
dnl runtime loader, otherwise the system is severely misconfigured.)
LIB[]NAME="${LIB[]NAME}${LIB[]NAME:+ }-l$name"
LTLIB[]NAME="${LTLIB[]NAME}${LTLIB[]NAME:+ }-l$name"
fi
fi
fi
done
done
if test "X$rpathdirs" != "X"; then
if test -n "$acl_hardcode_libdir_separator"; then
dnl Weird platform: only the last -rpath option counts, the user must
dnl pass all path elements in one option. We can arrange that for a
dnl single library, but not when more than one $LIBNAMEs are used.
alldirs=
for found_dir in $rpathdirs; do
alldirs="${alldirs}${alldirs:+$acl_hardcode_libdir_separator}$found_dir"
done
dnl Note: acl_hardcode_libdir_flag_spec uses $libdir and $wl.
acl_save_libdir="$libdir"
libdir="$alldirs"
eval flag=\"$acl_hardcode_libdir_flag_spec\"
libdir="$acl_save_libdir"
LIB[]NAME="${LIB[]NAME}${LIB[]NAME:+ }$flag"
else
dnl The -rpath options are cumulative.
for found_dir in $rpathdirs; do
acl_save_libdir="$libdir"
libdir="$found_dir"
eval flag=\"$acl_hardcode_libdir_flag_spec\"
libdir="$acl_save_libdir"
LIB[]NAME="${LIB[]NAME}${LIB[]NAME:+ }$flag"
done
fi
fi
if test "X$ltrpathdirs" != "X"; then
dnl When using libtool, the option that works for both libraries and
dnl executables is -R. The -R options are cumulative.
for found_dir in $ltrpathdirs; do
LTLIB[]NAME="${LTLIB[]NAME}${LTLIB[]NAME:+ }-R$found_dir"
done
fi
])
dnl AC_LIB_APPENDTOVAR(VAR, CONTENTS) appends the elements of CONTENTS to VAR,
dnl unless already present in VAR.
dnl Works only for CPPFLAGS, not for LIB* variables because that sometimes
dnl contains two or three consecutive elements that belong together.
AC_DEFUN([AC_LIB_APPENDTOVAR],
[
for element in [$2]; do
haveit=
for x in $[$1]; do
AC_LIB_WITH_FINAL_PREFIX([eval x=\"$x\"])
if test "X$x" = "X$element"; then
haveit=yes
break
fi
done
if test -z "$haveit"; then
[$1]="${[$1]}${[$1]:+ }$element"
fi
done
])
dnl For those cases where a variable contains several -L and -l options
dnl referring to unknown libraries and directories, this macro determines the
dnl necessary additional linker options for the runtime path.
dnl AC_LIB_LINKFLAGS_FROM_LIBS([LDADDVAR], [LIBSVALUE], [USE-LIBTOOL])
dnl sets LDADDVAR to linker options needed together with LIBSVALUE.
dnl If USE-LIBTOOL evaluates to non-empty, linking with libtool is assumed,
dnl otherwise linking without libtool is assumed.
AC_DEFUN([AC_LIB_LINKFLAGS_FROM_LIBS],
[
AC_REQUIRE([AC_LIB_RPATH])
AC_REQUIRE([AC_LIB_PREPARE_MULTILIB])
$1=
if test "$enable_rpath" != no; then
if test -n "$acl_hardcode_libdir_flag_spec" && test "$acl_hardcode_minus_L" = no; then
dnl Use an explicit option to hardcode directories into the resulting
dnl binary.
rpathdirs=
next=
for opt in $2; do
if test -n "$next"; then
dir="$next"
dnl No need to hardcode the standard /usr/lib.
if test "X$dir" != "X/usr/$acl_libdirstem"; then
rpathdirs="$rpathdirs $dir"
fi
next=
else
case $opt in
-L) next=yes ;;
-L*) dir=`echo "X$opt" | sed -e 's,^X-L,,'`
dnl No need to hardcode the standard /usr/lib.
if test "X$dir" != "X/usr/$acl_libdirstem"; then
rpathdirs="$rpathdirs $dir"
fi
next= ;;
*) next= ;;
esac
fi
done
if test "X$rpathdirs" != "X"; then
if test -n ""$3""; then
dnl libtool is used for linking. Use -R options.
for dir in $rpathdirs; do
$1="${$1}${$1:+ }-R$dir"
done
else
dnl The linker is used for linking directly.
if test -n "$acl_hardcode_libdir_separator"; then
dnl Weird platform: only the last -rpath option counts, the user
dnl must pass all path elements in one option.
alldirs=
for dir in $rpathdirs; do
alldirs="${alldirs}${alldirs:+$acl_hardcode_libdir_separator}$dir"
done
acl_save_libdir="$libdir"
libdir="$alldirs"
eval flag=\"$acl_hardcode_libdir_flag_spec\"
libdir="$acl_save_libdir"
$1="$flag"
else
dnl The -rpath options are cumulative.
for dir in $rpathdirs; do
acl_save_libdir="$libdir"
libdir="$dir"
eval flag=\"$acl_hardcode_libdir_flag_spec\"
libdir="$acl_save_libdir"
$1="${$1}${$1:+ }$flag"
done
fi
fi
fi
fi
fi
AC_SUBST([$1])
])

185
m4/lib-prefix.m4 Normal file
View File

@@ -0,0 +1,185 @@
# lib-prefix.m4 serial 5 (gettext-0.15)
dnl Copyright (C) 2001-2005 Free Software Foundation, Inc.
dnl This file is free software; the Free Software Foundation
dnl gives unlimited permission to copy and/or distribute it,
dnl with or without modifications, as long as this notice is preserved.
dnl From Bruno Haible.
dnl AC_LIB_ARG_WITH is synonymous to AC_ARG_WITH in autoconf-2.13, and
dnl similar to AC_ARG_WITH in autoconf 2.52...2.57 except that is doesn't
dnl require excessive bracketing.
ifdef([AC_HELP_STRING],
[AC_DEFUN([AC_LIB_ARG_WITH], [AC_ARG_WITH([$1],[[$2]],[$3],[$4])])],
[AC_DEFUN([AC_][LIB_ARG_WITH], [AC_ARG_WITH([$1],[$2],[$3],[$4])])])
dnl AC_LIB_PREFIX adds to the CPPFLAGS and LDFLAGS the flags that are needed
dnl to access previously installed libraries. The basic assumption is that
dnl a user will want packages to use other packages he previously installed
dnl with the same --prefix option.
dnl This macro is not needed if only AC_LIB_LINKFLAGS is used to locate
dnl libraries, but is otherwise very convenient.
AC_DEFUN([AC_LIB_PREFIX],
[
AC_BEFORE([$0], [AC_LIB_LINKFLAGS])
AC_REQUIRE([AC_PROG_CC])
AC_REQUIRE([AC_CANONICAL_HOST])
AC_REQUIRE([AC_LIB_PREPARE_MULTILIB])
AC_REQUIRE([AC_LIB_PREPARE_PREFIX])
dnl By default, look in $includedir and $libdir.
use_additional=yes
AC_LIB_WITH_FINAL_PREFIX([
eval additional_includedir=\"$includedir\"
eval additional_libdir=\"$libdir\"
])
AC_LIB_ARG_WITH([lib-prefix],
[ --with-lib-prefix[=DIR] search for libraries in DIR/include and DIR/lib
--without-lib-prefix don't search for libraries in includedir and libdir],
[
if test "X$withval" = "Xno"; then
use_additional=no
else
if test "X$withval" = "X"; then
AC_LIB_WITH_FINAL_PREFIX([
eval additional_includedir=\"$includedir\"
eval additional_libdir=\"$libdir\"
])
else
additional_includedir="$withval/include"
additional_libdir="$withval/$acl_libdirstem"
fi
fi
])
if test $use_additional = yes; then
dnl Potentially add $additional_includedir to $CPPFLAGS.
dnl But don't add it
dnl 1. if it's the standard /usr/include,
dnl 2. if it's already present in $CPPFLAGS,
dnl 3. if it's /usr/local/include and we are using GCC on Linux,
dnl 4. if it doesn't exist as a directory.
if test "X$additional_includedir" != "X/usr/include"; then
haveit=
for x in $CPPFLAGS; do
AC_LIB_WITH_FINAL_PREFIX([eval x=\"$x\"])
if test "X$x" = "X-I$additional_includedir"; then
haveit=yes
break
fi
done
if test -z "$haveit"; then
if test "X$additional_includedir" = "X/usr/local/include"; then
if test -n "$GCC"; then
case $host_os in
linux* | gnu* | k*bsd*-gnu) haveit=yes;;
esac
fi
fi
if test -z "$haveit"; then
if test -d "$additional_includedir"; then
dnl Really add $additional_includedir to $CPPFLAGS.
CPPFLAGS="${CPPFLAGS}${CPPFLAGS:+ }-I$additional_includedir"
fi
fi
fi
fi
dnl Potentially add $additional_libdir to $LDFLAGS.
dnl But don't add it
dnl 1. if it's the standard /usr/lib,
dnl 2. if it's already present in $LDFLAGS,
dnl 3. if it's /usr/local/lib and we are using GCC on Linux,
dnl 4. if it doesn't exist as a directory.
if test "X$additional_libdir" != "X/usr/$acl_libdirstem"; then
haveit=
for x in $LDFLAGS; do
AC_LIB_WITH_FINAL_PREFIX([eval x=\"$x\"])
if test "X$x" = "X-L$additional_libdir"; then
haveit=yes
break
fi
done
if test -z "$haveit"; then
if test "X$additional_libdir" = "X/usr/local/$acl_libdirstem"; then
if test -n "$GCC"; then
case $host_os in
linux*) haveit=yes;;
esac
fi
fi
if test -z "$haveit"; then
if test -d "$additional_libdir"; then
dnl Really add $additional_libdir to $LDFLAGS.
LDFLAGS="${LDFLAGS}${LDFLAGS:+ }-L$additional_libdir"
fi
fi
fi
fi
fi
])
dnl AC_LIB_PREPARE_PREFIX creates variables acl_final_prefix,
dnl acl_final_exec_prefix, containing the values to which $prefix and
dnl $exec_prefix will expand at the end of the configure script.
AC_DEFUN([AC_LIB_PREPARE_PREFIX],
[
dnl Unfortunately, prefix and exec_prefix get only finally determined
dnl at the end of configure.
if test "X$prefix" = "XNONE"; then
acl_final_prefix="$ac_default_prefix"
else
acl_final_prefix="$prefix"
fi
if test "X$exec_prefix" = "XNONE"; then
acl_final_exec_prefix='${prefix}'
else
acl_final_exec_prefix="$exec_prefix"
fi
acl_save_prefix="$prefix"
prefix="$acl_final_prefix"
eval acl_final_exec_prefix=\"$acl_final_exec_prefix\"
prefix="$acl_save_prefix"
])
dnl AC_LIB_WITH_FINAL_PREFIX([statement]) evaluates statement, with the
dnl variables prefix and exec_prefix bound to the values they will have
dnl at the end of the configure script.
AC_DEFUN([AC_LIB_WITH_FINAL_PREFIX],
[
acl_save_prefix="$prefix"
prefix="$acl_final_prefix"
acl_save_exec_prefix="$exec_prefix"
exec_prefix="$acl_final_exec_prefix"
$1
exec_prefix="$acl_save_exec_prefix"
prefix="$acl_save_prefix"
])
dnl AC_LIB_PREPARE_MULTILIB creates a variable acl_libdirstem, containing
dnl the basename of the libdir, either "lib" or "lib64".
AC_DEFUN([AC_LIB_PREPARE_MULTILIB],
[
dnl There is no formal standard regarding lib and lib64. The current
dnl practice is that on a system supporting 32-bit and 64-bit instruction
dnl sets or ABIs, 64-bit libraries go under $prefix/lib64 and 32-bit
dnl libraries go under $prefix/lib. We determine the compiler's default
dnl mode by looking at the compiler's library search path. If at least
dnl of its elements ends in /lib64 or points to a directory whose absolute
dnl pathname ends in /lib64, we assume a 64-bit ABI. Otherwise we use the
dnl default, namely "lib".
acl_libdirstem=lib
searchpath=`(LC_ALL=C $CC -print-search-dirs) 2>/dev/null | sed -n -e 's,^libraries: ,,p' | sed -e 's,^=,,'`
if test -n "$searchpath"; then
acl_save_IFS="${IFS= }"; IFS=":"
for searchdir in $searchpath; do
if test -d "$searchdir"; then
case "$searchdir" in
*/lib64/ | */lib64 ) acl_libdirstem=lib64 ;;
*) searchdir=`cd "$searchdir" && pwd`
case "$searchdir" in
*/lib64 ) acl_libdirstem=lib64 ;;
esac ;;
esac
fi
done
IFS="$acl_save_IFS"
fi
])

View File

@@ -1,40 +0,0 @@
#! /bin/sh
# mkinstalldirs --- make directory hierarchy
# Author: Noah Friedman <friedman@prep.ai.mit.edu>
# Created: 1993-05-16
# Public domain
# $Id: mkinstalldirs,v 1.1 2004/12/07 21:17:20 sarag Exp $
errstatus=0
for file
do
set fnord `echo ":$file" | sed -ne 's/^:\//#/;s/^://;s/\// /g;s/^#/\//;p'`
shift
pathcomp=
for d
do
pathcomp="$pathcomp$d"
case "$pathcomp" in
-* ) pathcomp=./$pathcomp ;;
esac
if test ! -d "$pathcomp"; then
echo "mkdir $pathcomp"
mkdir "$pathcomp" || lasterr=$?
if test ! -d "$pathcomp"; then
errstatus=$lasterr
fi
fi
pathcomp="$pathcomp/"
done
done
exit $errstatus
# mkinstalldirs ends here

2
nw/Makefile Normal file
View File

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

551
nw/Makefile.netware Normal file
View File

@@ -0,0 +1,551 @@
#########################################################################
#
## Makefile for building libssh2 (NetWare version - gnu make)
## Use: make -f Makefile.netware [help|all|clean|dev|devclean|dist|distclean|lib|nlm|objclean]
##
## Comments to: Guenter Knauf <eflash@gmx.net>
##
## $Id: Makefile.netware,v 1.6 2007/04/21 20:15:33 gknauf Exp $
#
#########################################################################
# Edit the path below to point to the base of your Novell NDK.
ifndef NDKBASE
NDKBASE = c:/novell
endif
# Edit the path below to point to the base of your Zlib sources.
ifndef ZLIB_PATH
ZLIB_PATH = ../../zlib-1.2.3
endif
# Edit the path below to point to the base of your OpenSSL package.
ifndef OPENSSL_PATH
OPENSSL_PATH = ../../openssl-0.9.8e
endif
# Edit the path below to point to your Distribution folder.
ifndef DISTDIR
DISTDIR = libssh2-$(LIBSSH2_VERSION_STR)-bin-nw
endif
DISTARC = $(DISTDIR).zip
# Edit the path below to point to your Development folder.
ifndef DEVLDIR
DEVLDIR = libssh2-$(LIBSSH2_VERSION_STR)-dev-nw
endif
DEVLARC = $(DEVLDIR).zip
# Edit the vars below to change NLM target settings.
TARGET = libssh2
VERSION = $(LIBSSH2_VERSION)
COPYR = Copyright (c) 2004-2007 Sara Golemon <sarag@libssh2.org>
WWWURL = http://www.libssh2.org/
DESCR = libssh2 $(LIBSSH2_VERSION_STR) - $(WWWURL)
MTSAFE = YES
STACK = 64000
SCREEN = none
EXPORTS = @$(TARGET).imp
# Edit the var below to point to your lib architecture.
ifndef LIBARCH
LIBARCH = LIBC
endif
# must be equal to DEBUG or NDEBUG
ifndef DB
DB = NDEBUG
# DB = DEBUG
endif
# Optimization: -O<n> or debugging: -g
ifeq ($(DB),NDEBUG)
OPT = -O2
OBJDIR = release
else
OPT = -g
OPT += -DLIBSSH2DEBUG
OBJDIR = debug
endif
# Include the version info retrieved from libssh2.h
-include $(OBJDIR)/version.inc
# The following line defines your compiler.
ifdef METROWERKS
CC = mwccnlm
else
CC = gcc
endif
CP = cp -afv
# RM = rm -f
# Here you can find a native Win32 binary of the original awk:
# http://www.gknw.net/development/prgtools/awk.zip
AWK = awk
# if you want to mark the target as MTSAFE you will need a tool for
# generating the xdc data for the linker; here's a minimal tool:
# http://www.gknw.net/development/prgtools/mkxdc.zip
MPKXDC = mkxdc
ZIP = zip -qzr9
# Global flags for all compilers
CFLAGS = $(OPT) -D$(DB) -DNETWARE -nostdinc # -DHAVE_CONFIG_H
ifeq ($(CC),mwccnlm)
LD = mwldnlm
LDFLAGS = -nostdlib $(PRELUDE) $(OBJL) -o $@ -commandfile
AR = mwldnlm
ARFLAGS = -nostdlib -type library -o
LIBEXT = lib
CFLAGS += -msgstyle gcc -gccinc -inline on -opt nointrinsics -proc 586
CFLAGS += -relax_pointers
#CFLAGS += -w on
ifeq ($(LIBARCH),LIBC)
PRELUDE = $(SDK_LIBC)/imports/libcpre.o
CFLAGS += -align 4
else
PRELUDE = "$(METROWERKS)/Novell Support/libraries/runtime/prelude.obj"
# CFLAGS += -include "$(METROWERKS)/Novell Support/headers/nlm_prefix.h"
CFLAGS += -align 1
endif
else
LD = nlmconv
LDFLAGS = -T
AR = ar
ARFLAGS = -cq
LIBEXT = a
RANLIB = ranlib
CFLAGS += -fno-builtin -fpcc-struct-return -fno-strict-aliasing
CFLAGS += -Wall # -pedantic
#CFLAGS += -Wno-pointer-sign
ifeq ($(LIBARCH),LIBC)
PRELUDE = $(SDK_LIBC)/imports/libcpre.gcc.o
else
PRELUDE = $(SDK_CLIB)/imports/clibpre.gcc.o
CFLAGS += -include $(NDKBASE)/nlmconv/genlm.h
endif
endif
LDLIBS =
NDK_ROOT = $(NDKBASE)/ndk
SDK_CLIB = $(NDK_ROOT)/nwsdk
SDK_LIBC = $(NDK_ROOT)/libc
SDK_LDAP = $(NDK_ROOT)/cldapsdk/netware
INCLUDES = -I. -I../include
ifdef WITH_ZLIB
INCLUDES += -I$(ZLIB_PATH)
ifdef LINK_STATIC
LDLIBS += $(ZLIB_PATH)/nw/libz.$(LIBEXT)
else
MODULES += libz.nlm
IMPORTS += @$(ZLIB_PATH)/nw/libz.imp
endif
endif
INCLUDES += -I$(OPENSSL_PATH)/outinc_nw_libc -I$(OPENSSL_PATH)/outinc_nw_libc/openssl
LDLIBS += $(OPENSSL_PATH)/out_nw_libc/ssl.$(LIBEXT) $(OPENSSL_PATH)/out_nw_libc/crypto.$(LIBEXT)
IMPORTS += GetProcessSwitchCount RunningProcess
ifeq ($(LIBARCH),LIBC)
INCLUDES += -I$(SDK_LIBC)/include -I$(SDK_LIBC)/include/nks
# INCLUDES += -I$(SDK_LIBC)/include/winsock
# INCLUDES += -I$(SDK_LDAP)/libc/inc
CFLAGS += -D_POSIX_SOURCE
# CFLAGS += -D__ANSIC__
else
INCLUDES += -I$(SDK_CLIB)/include/nlm -I$(SDK_CLIB)/include
# INCLUDES += -I$(SDK_CLIB)/include/nlm/obsolete
# INCLUDES += -I$(SDK_LDAP)/clib/inc
CFLAGS += -DNETDB_USE_INTERNET
endif
CFLAGS += $(INCLUDES)
ifeq ($(MTSAFE),YES)
XDCOPT = -n
endif
ifeq ($(MTSAFE),NO)
XDCOPT = -u
endif
ifdef XDCOPT
XDCDATA = $(OBJDIR)/$(TARGET).xdc
endif
ifeq ($(findstring linux,$(OSTYPE)),linux)
#-include $(NDKBASE)/nlmconv/ncpfs.inc
DL = '
DS = /
else
DS = \\
endif
vpath %.c . ../src
OBJECTS = \
channel.o \
comp.o \
crypt.o \
hostkey.o \
kex.o \
mac.o \
misc.o \
openssl.o \
packet.o \
pem.o \
publickey.o \
scp.o \
session.o \
sftp.o \
transport.o \
userauth.o
OBJS := $(addprefix $(OBJDIR)/,$(OBJECTS))
OBJL = $(OBJS) $(OBJDIR)/nwlibc.o $(LDLIBS)
all: lib nlm
nlm: prebuild $(TARGET).nlm
lib: prebuild $(TARGET).$(LIBEXT)
prebuild: $(OBJDIR) $(OBJDIR)/version.inc libssh2_config.h
test: all
$(MAKE) -C test -f Makefile.netware
$(OBJDIR)/%.o: %.c
# @echo Compiling $<
$(CC) $(CFLAGS) -c $< -o $@
$(OBJDIR)/version.inc: ../include/libssh2.h $(OBJDIR)
@echo Creating $@
@$(AWK) -f ../get_ver.awk $< > $@
dist: all $(DISTDIR) $(DISTDIR)/readme.txt
@-mkdir $(DISTDIR)$(DS)bin
@-$(CP) ../INSTALL $(DISTDIR)
@-$(CP) ../LICENSE $(DISTDIR)
@-$(CP) ../README $(DISTDIR)
@$(CP) $(TARGET).nlm $(DISTDIR)/bin
@echo Creating $(DISTARC)
@$(ZIP) $(DISTARC) $(DISTDIR)/* < $(DISTDIR)/readme.txt
dev: all $(DEVLDIR) $(DEVLDIR)/readme.txt
@-mkdir $(DEVLDIR)$(DS)bin
@-mkdir $(DEVLDIR)$(DS)include
@-mkdir $(DEVLDIR)$(DS)nw
@-$(CP) ../INSTALL $(DEVLDIR)
@-$(CP) ../LICENSE $(DEVLDIR)
@-$(CP) ../README $(DEVLDIR)
@$(CP) $(TARGET).nlm $(DEVLDIR)/bin
@$(CP) ../include/*.h $(DEVLDIR)/include
@$(CP) libssh2_config.h $(DEVLDIR)/include
@$(CP) $(TARGET).$(LIBEXT) $(DEVLDIR)/nw
@echo Creating $(DEVLARC)
@$(ZIP) $(DEVLARC) $(DEVLDIR)/* < $(DEVLDIR)/readme.txt
distclean: clean
-$(RM) -r $(DISTDIR)
-$(RM) $(DISTARC)
devclean: clean
-$(RM) -r $(DEVLDIR)
-$(RM) $(DEVLARC)
objclean:
-$(RM) -r $(OBJDIR)
testclean: clean
$(MAKE) -C test -f Makefile.netware clean
clean: objclean
-$(RM) libssh2_config.h
-$(RM) $(TARGET).nlm $(TARGET).$(LIBEXT) $(TARGET).imp
$(OBJDIR):
@mkdir $@
$(DISTDIR):
@mkdir $@
$(DEVLDIR):
@mkdir $@
$(TARGET).$(LIBEXT): $(OBJS)
@echo Creating $@
@-$(RM) $@
@$(AR) $(ARFLAGS) $@ $^
ifdef RANLIB
@$(RANLIB) $@
endif
$(TARGET).nlm: $(OBJDIR)/$(TARGET).def $(TARGET).imp $(OBJL) $(XDCDATA)
@echo Linking $@
@-$(RM) $@
@$(LD) $(LDFLAGS) $<
$(OBJDIR)/%.xdc: Makefile.netware
@echo Creating $@
@$(MPKXDC) $(XDCOPT) $@
$(OBJDIR)/%.def: Makefile.netware
@echo $(DL)# DEF file for linking with $(LD)$(DL) > $@
@echo $(DL)# Do not edit this file - it is created by make!$(DL) >> $@
@echo $(DL)# All your changes will be lost!!$(DL) >> $@
@echo $(DL)#$(DL) >> $@
@echo $(DL)copyright "$(COPYR)"$(DL) >> $@
@echo $(DL)description "$(DESCR)"$(DL) >> $@
@echo $(DL)version $(VERSION)$(DL) >> $@
ifdef NLMTYPE
@echo $(DL)type $(NLMTYPE)$(DL) >> $@
endif
ifdef STACK
@echo $(DL)stack $(STACK)$(DL) >> $@
endif
ifdef SCREEN
@echo $(DL)screenname "$(SCREEN)"$(DL) >> $@
else
@echo $(DL)screenname "DEFAULT"$(DL) >> $@
endif
ifeq ($(DB),DEBUG)
@echo $(DL)debug$(DL) >> $@
endif
@echo $(DL)threadname "$(TARGET)"$(DL) >> $@
ifdef XDCDATA
@echo $(DL)xdcdata $(XDCDATA)$(DL) >> $@
endif
ifeq ($(LIBARCH),CLIB)
@echo $(DL)start _Prelude$(DL) >> $@
@echo $(DL)exit _Stop$(DL) >> $@
@echo $(DL)import @$(SDK_CLIB)/imports/clib.imp$(DL) >> $@
@echo $(DL)import @$(SDK_CLIB)/imports/threads.imp$(DL) >> $@
@echo $(DL)import @$(SDK_CLIB)/imports/nlmlib.imp$(DL) >> $@
@echo $(DL)import @$(SDK_CLIB)/imports/socklib.imp$(DL) >> $@
@echo $(DL)module clib$(DL) >> $@
else
@echo $(DL)flag_on 64$(DL) >> $@
@echo $(DL)pseudopreemption$(DL) >> $@
@echo $(DL)start _LibCPrelude$(DL) >> $@
@echo $(DL)exit _LibCPostlude$(DL) >> $@
@echo $(DL)check _LibCCheckUnload$(DL) >> $@
@echo $(DL)import @$(SDK_LIBC)/imports/libc.imp$(DL) >> $@
@echo $(DL)import @$(SDK_LIBC)/imports/netware.imp$(DL) >> $@
@echo $(DL)module libc$(DL) >> $@
endif
ifdef MODULES
@echo $(DL)module $(MODULES)$(DL) >> $@
endif
ifdef EXPORTS
@echo $(DL)export $(EXPORTS)$(DL) >> $@
endif
ifdef IMPORTS
@echo $(DL)import $(IMPORTS)$(DL) >> $@
endif
ifeq ($(LD),nlmconv)
@echo $(DL)input $(OBJL)$(DL) >> $@
@echo $(DL)input $(PRELUDE)$(DL) >> $@
@echo $(DL)output $(TARGET).nlm$(DL) >> $@
endif
libssh2_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 OS "i586-pc-NetWare"$(DL) >> $@
@echo $(DL)#define VERSION "$(LIBSSH2_VERSION_STR)"$(DL) >> $@
@echo $(DL)#define PACKAGE_BUGREPORT "http://sourceforge.net/projects/libssh2"$(DL) >> $@
@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_DLFCN_H 1$(DL) >> $@
@echo $(DL)#define HAVE_DLOPEN 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_GETTIMEOFDAY 1$(DL) >> $@
@echo $(DL)#define HAVE_INET_ADDR 1$(DL) >> $@
@echo $(DL)#define HAVE_INET_NTOA 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_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_SELECT 1$(DL) >> $@
@echo $(DL)#define HAVE_SETJMP_H 1$(DL) >> $@
@echo $(DL)#define HAVE_SIGNAL 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_STRCASECMP 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_STRLCAT 1$(DL) >> $@
@echo $(DL)#define HAVE_STRLCPY 1$(DL) >> $@
@echo $(DL)#define HAVE_STRSTR 1$(DL) >> $@
@echo $(DL)#define HAVE_SYS_PARAM_H 1$(DL) >> $@
@echo $(DL)#define HAVE_SYS_SELECT_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_TERMIOS_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 RETSIGTYPE void$(DL) >> $@
@echo $(DL)#define STDC_HEADERS 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_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 ENABLE_IPV6
@echo $(DL)#define ENABLE_IPV6 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
libssh2.imp: 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) (LIBSSH2)$(DL) >> $@
@echo $(DL) libssh2_banner_set,$(DL) >> $@
@echo $(DL) libssh2_channel_close,$(DL) >> $@
@echo $(DL) libssh2_channel_direct_tcpip_ex,$(DL) >> $@
@echo $(DL) libssh2_channel_eof,$(DL) >> $@
@echo $(DL) libssh2_channel_flush_ex,$(DL) >> $@
@echo $(DL) libssh2_channel_free,$(DL) >> $@
@echo $(DL) libssh2_channel_open_ex,$(DL) >> $@
@echo $(DL) libssh2_channel_process_startup,$(DL) >> $@
@echo $(DL) libssh2_channel_read_ex,$(DL) >> $@
@echo $(DL) libssh2_channel_readnb_ex,$(DL) >> $@
@echo $(DL) libssh2_channel_request_pty_ex,$(DL) >> $@
@echo $(DL) libssh2_channel_send_eof,$(DL) >> $@
@echo $(DL) libssh2_channel_set_blocking,$(DL) >> $@
@echo $(DL) libssh2_channel_setenv_ex,$(DL) >> $@
@echo $(DL) libssh2_channel_write_ex,$(DL) >> $@
@echo $(DL) libssh2_channel_writenb_ex,$(DL) >> $@
@echo $(DL) libssh2_hostkey_hash,$(DL) >> $@
@echo $(DL) libssh2_scp_recv,$(DL) >> $@
@echo $(DL) libssh2_scp_send_ex,$(DL) >> $@
@echo $(DL) libssh2_session_abstract,$(DL) >> $@
@echo $(DL) libssh2_session_callback_set,$(DL) >> $@
@echo $(DL) libssh2_session_disconnect_ex,$(DL) >> $@
@echo $(DL) libssh2_session_free,$(DL) >> $@
@echo $(DL) libssh2_session_init_ex,$(DL) >> $@
@echo $(DL) libssh2_session_last_error,$(DL) >> $@
@echo $(DL) libssh2_session_method_pref,$(DL) >> $@
@echo $(DL) libssh2_session_methods,$(DL) >> $@
@echo $(DL) libssh2_session_startup,$(DL) >> $@
@echo $(DL) libssh2_sftp_close_handle,$(DL) >> $@
@echo $(DL) libssh2_sftp_fstat_ex,$(DL) >> $@
@echo $(DL) libssh2_sftp_init,$(DL) >> $@
@echo $(DL) libssh2_sftp_last_error,$(DL) >> $@
@echo $(DL) libssh2_sftp_mkdir_ex,$(DL) >> $@
@echo $(DL) libssh2_sftp_open_ex,$(DL) >> $@
@echo $(DL) libssh2_sftp_read,$(DL) >> $@
@echo $(DL) libssh2_sftp_readdir,$(DL) >> $@
@echo $(DL) libssh2_sftp_readnb,$(DL) >> $@
@echo $(DL) libssh2_sftp_rename_ex,$(DL) >> $@
@echo $(DL) libssh2_sftp_rmdir_ex,$(DL) >> $@
@echo $(DL) libssh2_sftp_seek,$(DL) >> $@
@echo $(DL) libssh2_sftp_shutdown,$(DL) >> $@
@echo $(DL) libssh2_sftp_stat_ex,$(DL) >> $@
@echo $(DL) libssh2_sftp_symlink_ex,$(DL) >> $@
@echo $(DL) libssh2_sftp_tell,$(DL) >> $@
@echo $(DL) libssh2_sftp_unlink_ex,$(DL) >> $@
@echo $(DL) libssh2_sftp_write,$(DL) >> $@
@echo $(DL) libssh2_sftp_writenb,$(DL) >> $@
@echo $(DL) libssh2_trace,$(DL) >> $@
@echo $(DL) libssh2_userauth_authenticated,$(DL) >> $@
@echo $(DL) libssh2_userauth_keyboard_interactive_ex,$(DL) >> $@
@echo $(DL) libssh2_userauth_list,$(DL) >> $@
@echo $(DL) libssh2_userauth_password_ex,$(DL) >> $@
@echo $(DL) libssh2_userauth_publickey_fromfile_ex$(DL) >> $@
$(DISTDIR)/readme.txt: Makefile.netware
@echo Creating $@
@echo $(DL)This is a binary distribution for NetWare platform.$(DL) > $@
@echo $(DL)libssh version $(LIBSSH2_VERSION_STR)$(DL) >> $@
@echo $(DL)Please download the complete libssh package for$(DL) >> $@
@echo $(DL)any further documentation:$(DL) >> $@
@echo $(DL)$(WWWURL)$(DL) >> $@
$(DEVLDIR)/readme.txt: Makefile.netware
@echo Creating $@
@echo $(DL)This is a development distribution for NetWare platform.$(DL) > $@
@echo $(DL)libssh version $(LIBSSH2_VERSION_STR)$(DL) >> $@
@echo $(DL)Please download the complete libssh package for$(DL) >> $@
@echo $(DL)any further documentation:$(DL) >> $@
@echo $(DL)$(WWWURL)$(DL) >> $@
help: $(OBJDIR)/version.inc
@echo $(DL)===========================================================$(DL)
@echo $(DL)Novell LibC NDK = $(SDK_LIBC)$(DL)
@echo $(DL)OpenSSL path = $(OPENSSL_PATH)$(DL)
@echo $(DL)Zlib path = $(ZLIB_PATH)$(DL)
@echo $(DL)===========================================================$(DL)
@echo $(DL)libssh $(LIBSSH2_VERSION_STR) - available targets are:$(DL)
@echo $(DL)$(MAKE) all$(DL)
@echo $(DL)$(MAKE) nlm$(DL)
@echo $(DL)$(MAKE) lib$(DL)
@echo $(DL)$(MAKE) clean$(DL)
@echo $(DL)$(MAKE) dev$(DL)
@echo $(DL)$(MAKE) devclean$(DL)
@echo $(DL)$(MAKE) dist$(DL)
@echo $(DL)$(MAKE) distclean$(DL)
@echo $(DL)$(MAKE) objclean$(DL)
@echo $(DL)$(MAKE) test$(DL)
@echo $(DL)===========================================================$(DL)

25
nw/keepscreen.c Normal file
View File

@@ -0,0 +1,25 @@
/* Simple _NonAppStop() implementation which can be linked to your
* NLM in order to keep the screen open when the NLM terminates
* (the good old clib behaviour).
* You dont have to call it, its done automatically from LibC.
*
* 2004-Aug-11 by Guenter Knauf
*
* URL: http://www.gknw.net/development/mk_nlm/
*/
#include <stdio.h>
#include <screen.h>
void _NonAppStop()
{
uint16_t row, col;
GetScreenSize(&row, &col);
gotorowcol(row-1, 0);
/* pressanykey(); */
printf("<Press any key to close screen> ");
getcharacter();
}

309
nw/nwlibc.c Normal file
View File

@@ -0,0 +1,309 @@
/*********************************************************************
* 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);
}
}

287
nw/test/Makefile.netware Normal file
View File

@@ -0,0 +1,287 @@
#########################################################################
#
## Makefile for building libssh2 (NetWare version - gnu make)
## Use: make -f Makefile.netware
##
## Comments to: Guenter Knauf <eflash@gmx.net>
##
## $Id: Makefile.netware,v 1.5 2007/04/21 21:26:54 gknauf Exp $
#
#########################################################################
# Edit the path below to point to the base of your Novell NDK.
ifndef NDKBASE
NDKBASE = c:/novell
endif
# Edit the path below to point to the base of your Zlib sources.
ifndef ZLIB_PATH
ZLIB_PATH = ../../../zlib-1.2.3
endif
# Edit the path below to point to the base of your OpenSSL package.
ifndef OPENSSL_PATH
OPENSSL_PATH = ../../../openssl-0.9.8e
endif
# Edit the var below to enable static linking of libssh2 and libz
LINK_STATIC = 1
# Edit the vars below to change NLM target settings.
TARGETS = scp.nlm sftp.nlm sftpdir.nlm ssh2.nlm
VERSION = $(LIBSSH2_VERSION)
COPYR = Copyright (c) 2004-2007, Sara Golemon <sarag@libssh2.org>
WWWURL = http://www.libssh2.org/
DESCR = libssh2 $(notdir $(@:.def=)) $(LIBSSH2_VERSION_STR) - $(WWWURL)
MTSAFE = YES
STACK = 64000
SCREEN = NONE
#SCREEN = libssh2 $(notdir $(@:.def=))
# Comment the line below if you dont want to load protected automatically.
LDRING = 3
# Edit the var below to point to your lib architecture.
ifndef LIBARCH
LIBARCH = LIBC
endif
# must be equal to DEBUG or NDEBUG
ifndef DB
DB = NDEBUG
# DB = DEBUG
endif
# Optimization: -O<n> or debugging: -g
ifeq ($(DB),NDEBUG)
OPT = -O2
OBJDIR = release
else
OPT = -g
OBJDIR = debug
endif
# Include the version info retrieved from xml2ver.h
-include $(OBJDIR)/version.inc
# The following line defines your compiler.
ifdef METROWERKS
CC = mwccnlm
else
CC = gcc
endif
CP = cp -afv
# RM = rm -f
# Here you can find a native Win32 binary of the original awk:
# http://www.gknw.net/development/prgtools/awk.zip
AWK = awk
# if you want to mark the target as MTSAFE you will need a tool for
# generating the xdc data for the linker; here's a minimal tool:
# http://www.gknw.net/development/prgtools/mkxdc.zip
MPKXDC = mkxdc
# Global flags for all compilers
CFLAGS = $(OPT) -D$(DB) -DNETWARE -nostdinc # -DHAVE_CONFIG_H
ifeq ($(CC),mwccnlm)
LD = mwldnlm
LDFLAGS = -nostdlib $(<:.def=.o) $(PRELUDE) $(LDLIBS) -o $@ -commandfile
AR = mwldnlm
ARFLAGS = -type library -w nocmdline $(OBJS) -o
LIBEXT = lib
CFLAGS += -msgstyle gcc -gccinc -inline off -opt nointrinsics -proc 586
CFLAGS += -relax_pointers
#CFLAGS += -w on
ifeq ($(LIBARCH),LIBC)
PRELUDE = $(SDK_LIBC)/imports/libcpre.o
CFLAGS += -align 4
else
PRELUDE = "$(METROWERKS)/Novell Support/libraries/runtime/prelude.obj"
# CFLAGS += -include "$(METROWERKS)/Novell Support/headers/nlm_prefix.h"
CFLAGS += -align 1
endif
else
LD = nlmconv
LDFLAGS = -T
AR = ar
ARFLAGS = -cq
LIBEXT = a
CFLAGS += -fno-builtin -fpack-struct -fpcc-struct-return -fno-strict-aliasing
CFLAGS += -Wall,no-unused # -pedantic
ifeq ($(LIBARCH),LIBC)
PRELUDE = $(SDK_LIBC)/imports/libcpre.gcc.o
else
PRELUDE = $(SDK_CLIB)/imports/clibpre.gcc.o
CFLAGS += -include $(NDKBASE)/nlmconv/genlm.h
endif
endif
NDK_ROOT = $(NDKBASE)/ndk
SDK_CLIB = $(NDK_ROOT)/nwsdk
SDK_LIBC = $(NDK_ROOT)/libc
SDK_LDAP = $(NDK_ROOT)/cldapsdk/netware
INCLUDES = -I. -I.. -I../../include
LDLIBS =
INCLUDES += -I$(OPENSSL_PATH)/outinc_nw_libc -I$(OPENSSL_PATH)/outinc_nw_libc/openssl
LDLIBS += $(OPENSSL_PATH)/out_nw_libc/ssl.$(LIBEXT) $(OPENSSL_PATH)/out_nw_libc/crypto.$(LIBEXT)
IMPORTS += GetProcessSwitchCount RunningProcess
ifdef LINK_STATIC
LDLIBS += ../libssh2.$(LIBEXT)
else
IMPORTS += @../libssh2.imp
MODULES += libssh2.nlm
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)
INCLUDES += -I$(SDK_LIBC)/include -I$(SDK_LIBC)/include/nks
# INCLUDES += -I$(SDK_LIBC)/include/winsock
# INCLUDES += -I$(SDK_LDAP)/libc/inc
CFLAGS += -D_POSIX_SOURCE
# CFLAGS += -D__ANSIC__
else
INCLUDES += -I$(SDK_CLIB)/include/nlm -I$(SDK_CLIB)/include
# INCLUDES += -I$(SDK_CLIB)/include/nlm/obsolete
# INCLUDES += -I$(SDK_LDAP)/clib/inc
CFLAGS += -DNETDB_USE_INTERNET
endif
CFLAGS += $(INCLUDES)
ifeq ($(MTSAFE),YES)
XDCOPT = -n
endif
ifeq ($(MTSAFE),NO)
XDCOPT = -u
endif
ifeq ($(findstring linux,$(OSTYPE)),linux)
DL = '
#-include $(NDKBASE)/nlmconv/ncpfs.inc
endif
vpath %.c ../../example/simple
.PRECIOUS: $(OBJDIR)/%.o $(OBJDIR)/%.def $(OBJDIR)/%.xdc
all: prebuild $(TARGETS)
prebuild: $(OBJDIR) $(OBJDIR)/version.inc
$(OBJDIR)/%.o: %.c
# @echo Compiling $<
$(CC) $(CFLAGS) -c $< -o $@
$(OBJDIR)/version.inc: ../../include/libssh2.h $(OBJDIR)
@echo Creating $@
@$(AWK) -f ../../get_ver.awk $< > $@
objclean:
-$(RM) -r $(OBJDIR)
clean: objclean
-$(RM) $(TARGETS)
$(OBJDIR):
@mkdir $@
%.nlm: $(OBJDIR)/%.def $(OBJDIR)/%.o $(OBJDIR)/%.xdc
@echo Linking $@
@-$(RM) $@
@$(LD) $(LDFLAGS) $<
$(OBJDIR)/%.xdc: Makefile.netware
@echo Creating $@
@$(MPKXDC) $(XDCOPT) $@
$(OBJDIR)/%.def: Makefile.netware
@echo $(DL)# DEF file for linking with $(LD)$(DL) > $@
@echo $(DL)# Do not edit this file - it is created by make!$(DL) >> $@
@echo $(DL)# All your changes will be lost!!$(DL) >> $@
@echo $(DL)#$(DL) >> $@
@echo $(DL)copyright "$(COPYR)"$(DL) >> $@
@echo $(DL)description "$(DESCR)"$(DL) >> $@
@echo $(DL)version $(VERSION)$(DL) >> $@
ifdef NLMTYPE
@echo $(DL)type $(NLMTYPE)$(DL) >> $@
endif
ifdef STACK
@echo $(DL)stack $(STACK)$(DL) >> $@
endif
ifdef SCREEN
@echo $(DL)screenname "$(SCREEN)"$(DL) >> $@
else
@echo $(DL)screenname "DEFAULT"$(DL) >> $@
endif
ifeq ($(DB),DEBUG)
@echo $(DL)debug$(DL) >> $@
endif
@echo $(DL)threadname "$(notdir $(@:.def=))"$(DL) >> $@
ifdef XDCOPT
@echo $(DL)xdcdata $(@:.def=.xdc)$(DL) >> $@
endif
ifeq ($(LDRING),0)
@echo $(DL)flag_on 16$(DL) >> $@
endif
ifeq ($(LDRING),3)
@echo $(DL)flag_on 512$(DL) >> $@
endif
ifeq ($(LIBARCH),CLIB)
@echo $(DL)start _Prelude$(DL) >> $@
@echo $(DL)exit _Stop$(DL) >> $@
@echo $(DL)import @$(SDK_CLIB)/imports/clib.imp$(DL) >> $@
@echo $(DL)import @$(SDK_CLIB)/imports/threads.imp$(DL) >> $@
@echo $(DL)import @$(SDK_CLIB)/imports/nlmlib.imp$(DL) >> $@
@echo $(DL)import @$(SDK_CLIB)/imports/socklib.imp$(DL) >> $@
@echo $(DL)module clib$(DL) >> $@
else
@echo $(DL)flag_on 64$(DL) >> $@
@echo $(DL)pseudopreemption$(DL) >> $@
@echo $(DL)start _LibCPrelude$(DL) >> $@
@echo $(DL)exit _LibCPostlude$(DL) >> $@
@echo $(DL)check _LibCCheckUnload$(DL) >> $@
@echo $(DL)import @$(SDK_LIBC)/imports/libc.imp$(DL) >> $@
@echo $(DL)import @$(SDK_LIBC)/imports/netware.imp$(DL) >> $@
@echo $(DL)module libc$(DL) >> $@
endif
ifdef MODULES
@echo $(DL)module $(MODULES)$(DL) >> $@
endif
ifdef EXPORTS
@echo $(DL)export $(EXPORTS)$(DL) >> $@
endif
ifdef IMPORTS
@echo $(DL)import $(IMPORTS)$(DL) >> $@
endif
ifeq ($(LD),nlmconv)
@echo $(DL)input $(<:.def=.o)$(DL) >> $@
@echo $(DL)input $(PRELUDE)$(DL) >> $@
ifdef LDLIBS
@echo $(DL)input $(LDLIBS)$(DL) >> $@
endif
@echo $(DL)output $(notdir $(@:.def=.nlm))$(DL) >> $@
endif
help: $(OBJDIR)/version.inc
@echo $(DL)===========================================================$(DL)
@echo $(DL)OpenSSL path = $(OPENSSL_PATH)$(DL)
@echo $(DL)Zlib path = $(ZLIB_PATH)$(DL)
@echo $(DL)===========================================================$(DL)
@echo $(DL)libssh $(LIBSSH2_VERSION_STR) - available targets are:$(DL)
@echo $(DL)$(MAKE) all$(DL)
@echo $(DL)$(MAKE) clean$(DL)
@echo $(DL)$(MAKE) objclean$(DL)
@echo $(DL)===========================================================$(DL)

View File

@@ -1,3 +1,5 @@
.deps
.libs
*.lib *.lib
*.pdb *.pdb
*.dll *.dll
@@ -7,3 +9,10 @@
Debug Debug
Release Release
*.exp *.exp
Makefile
Makefile.in
*.lo
libssh2.la
libssh2_config.h
libssh2_config.h.in
stamp-h1

53
src/Makefile.am Normal file
View File

@@ -0,0 +1,53 @@
# $Id: Makefile.am,v 1.9 2007/04/05 10:23:55 jas4711 Exp $
AUTOMAKE_OPTIONS = foreign nostdinc
libssh2_la_SOURCES = channel.c comp.c crypt.c hostkey.c kex.c mac.c \
misc.c packet.c publickey.c scp.c session.c sftp.c userauth.c \
libssh2_priv.h openssl.h libgcrypt.h pem.c transport.c
if LIBGCRYPT
libssh2_la_SOURCES += libgcrypt.c
else
libssh2_la_SOURCES += openssl.c
endif
EXTRA_DIST = libssh2_config.h.in
lib_LTLIBRARIES = libssh2.la
# srcdir/include for the shipped headers
# builddir/src for the generated config header when building out of the source
# tree
INCLUDES = -I$(top_srcdir)/include -I$(top_builddir)/src
VERSION=-version-info 1:0:0
# This flag accepts an argument of the form current[:revision[:age]]. So,
# passing -version-info 3:12:1 sets current to 3, revision to 12, and age to
# 1.
#
# If either revision or age are omitted, they default to 0. Also note that age
# must be less than or equal to the current interface number.
#
# Here are a set of rules to help you update your library version information:
#
# 1.Start with version information of 0:0:0 for each libtool library.
#
# 2.Update the version information only immediately before a public release of
# your software. More frequent updates are unnecessary, and only guarantee
# that the current interface number gets larger faster.
#
# 3.If the library source code has changed at all since the last update, then
# increment revision (c:r+1:a)
#
# 4.If any interfaces have been added, removed, or changed since the last
# update, increment current, and set revision to 0. (c+1:r=0:a)
#
# 5.If any interfaces have been added since the last public release, then
# increment age. (c:r:a+1)
#
# 6.If any interfaces have been removed since the last public release, then
# set age to 0. (c:r:a=0)
#
libssh2_la_LDFLAGS = $(VERSION) -no-undefined $(LTLIBGCRYPT)

View File

@@ -1,66 +0,0 @@
OBJECTS = channel.o comp.o crypt.o hostkey.o kex.o mac.o misc.o packet.o publickey.o scp.o session.o sftp.o userauth.o
top_srcdir = @top_srcdir@
prefix = @prefix@
exec_prefix = @exec_prefix@
libdir = @exec_prefix@/lib
incldir = @prefix@/include
CC = @CC@
CFLAGS = -c @CFLAGS@ -Wall -g -I../include/ -fPIC
LDFLAGS = @LDFLAGS@
LIBS = @LIBS@
INSTALL = @INSTALL@
channel.o: channel.c
$(CC) -o channel.o channel.c $(CFLAGS) $(LIBS)
comp.o: comp.c
$(CC) -o comp.o comp.c $(CFLAGS) $(LIBS)
crypt.o: crypt.c
$(CC) -o crypt.o crypt.c $(CFLAGS) $(LIBS)
hostkey.o: hostkey.c
$(CC) -o hostkey.o hostkey.c $(CFLAGS) $(LIBS)
kex.o: kex.c
$(CC) -o kex.o kex.c $(CFLAGS) $(LIBS)
mac.o: mac.c
$(CC) -o mac.o mac.c $(CFLAGS) $(LIBS)
misc.o: misc.c
$(CC) -o misc.o misc.c $(CFLAGS) $(LIBS)
packet.o: packet.c
$(CC) -o packet.o packet.c $(CFLAGS) $(LIBS)
publickey.o: publickey.c
$(CC) -o publickey.o publickey.c $(CFLAGS) $(LIBS)
scp.o: scp.c
$(CC) -o scp.o scp.c $(CFLAGS) $(LIBS)
session.o: session.c
$(CC) -o session.o session.c $(CFLAGS) $(LIBS)
sftp.o: sftp.c
$(CC) -o sftp.o sftp.c $(CFLAGS) $(LIBS)
userauth.o: userauth.c
$(CC) -o userauth.o userauth.c $(CFLAGS) $(LIBS)
all: libssh2.@SHLIB_SUFFIX_NAME@
libssh2.@SHLIB_SUFFIX_NAME@: $(OBJECTS)
$(CC) -o libssh2.@SHLIB_SUFFIX_NAME@ $(SHLIB_LDFLAGS) $(OBJECTS) $(LIBS) $(LDFLAGS) @SHLIB_LDFLAGS@
libssh2.a: $(OBJECTS)
rm -f libssh2.a
ar q libssh2.a $(OBJECTS)
@RANLIB@ libssh2.a
install: all
$(INSTALL) libssh2.@SHLIB_SUFFIX_NAME@ $(DESTDIR)$(libdir)
clean:
rm -f *~ libssh2.a libssh2.@SHLIB_SUFFIX_NAME@ *.o

View File

@@ -1,4 +1,4 @@
/* Copyright (c) 2004-2005, Sara Golemon <sarag@libssh2.org> /* Copyright (c) 2004-2007, Sara Golemon <sarag@libssh2.org>
* All rights reserved. * All rights reserved.
* *
* Redistribution and use in source and binary forms, * Redistribution and use in source and binary forms,
@@ -36,10 +36,83 @@
*/ */
#include "libssh2_priv.h" #include "libssh2_priv.h"
#include <openssl/rand.h> #ifdef HAVE_UNISTD_H
#ifndef WIN32
#include <unistd.h> #include <unistd.h>
#endif #endif
#include <fcntl.h>
#ifdef HAVE_INTTYPES_H
#include <inttypes.h>
#endif
/*
* _libssh2_nonblock() sets the given socket to either blocking or
* non-blocking mode based on the 'nonblock' boolean argument. This function
* is copied from the libcurl sources with permission.
*/
static int _libssh2_nonblock(int sockfd, /* operate on this */
int nonblock /* TRUE or FALSE */)
{
#undef SETBLOCK
#define SETBLOCK 0
#ifdef HAVE_O_NONBLOCK
/* most recent unix versions */
int flags;
flags = fcntl(sockfd, F_GETFL, 0);
if (nonblock)
return fcntl(sockfd, F_SETFL, flags | O_NONBLOCK);
else
return fcntl(sockfd, F_SETFL, flags & (~O_NONBLOCK));
#undef SETBLOCK
#define SETBLOCK 1
#endif
#if defined(HAVE_FIONBIO) && (SETBLOCK == 0)
/* older unix versions */
int flags;
flags = nonblock;
return ioctl(sockfd, FIONBIO, &flags);
#undef SETBLOCK
#define SETBLOCK 2
#endif
#if defined(HAVE_IOCTLSOCKET) && (SETBLOCK == 0)
/* Windows? */
unsigned long flags;
flags = nonblock;
return ioctlsocket(sockfd, FIONBIO, &flags);
#undef SETBLOCK
#define SETBLOCK 3
#endif
#if defined(HAVE_IOCTLSOCKET_CASE) && (SETBLOCK == 0)
/* presumably for Amiga */
return IoctlSocket(sockfd, FIONBIO, (long)nonblock);
#undef SETBLOCK
#define SETBLOCK 4
#endif
#if defined(HAVE_SO_NONBLOCK) && (SETBLOCK == 0)
/* BeOS */
long b = nonblock ? 1 : 0;
return setsockopt(sockfd, SOL_SOCKET, SO_NONBLOCK, &b, sizeof(b));
#undef SETBLOCK
#define SETBLOCK 5
#endif
#ifdef HAVE_DISABLED_NONBLOCKING
return 0; /* returns success */
#undef SETBLOCK
#define SETBLOCK 6
#endif
#if (SETBLOCK == 0)
#error "no non-blocking method was found/used/set"
#endif
}
/* {{{ libssh2_channel_nextid /* {{{ libssh2_channel_nextid
* Determine the next channel ID we can use at our end * Determine the next channel ID we can use at our end
@@ -64,9 +137,7 @@ unsigned long libssh2_channel_nextid(LIBSSH2_SESSION *session)
* Gets picked up by the new one.... Pretty unlikely all told... * Gets picked up by the new one.... Pretty unlikely all told...
*/ */
session->next_channel = id + 1; session->next_channel = id + 1;
#ifdef LIBSSH2_DEBUG_CONNECTION
_libssh2_debug(session, LIBSSH2_DBG_CONN, "Allocated new channel ID#%lu", id); _libssh2_debug(session, LIBSSH2_DBG_CONN, "Allocated new channel ID#%lu", id);
#endif
return id; return id;
} }
/* }}} */ /* }}} */
@@ -105,24 +176,37 @@ LIBSSH2_CHANNEL *libssh2_channel_locate(LIBSSH2_SESSION *session, unsigned long
/* {{{ libssh2_channel_open_session /* {{{ libssh2_channel_open_session
* Establish a generic session channel * Establish a generic session channel
*/ */
LIBSSH2_API LIBSSH2_CHANNEL *libssh2_channel_open_ex(LIBSSH2_SESSION *session, const char *channel_type, int channel_type_len, int window_size, int packet_size, LIBSSH2_API LIBSSH2_CHANNEL *
const char *message, int message_len) libssh2_channel_open_ex(LIBSSH2_SESSION *session, const char *channel_type,
unsigned int channel_type_len,
unsigned int window_size,
unsigned int packet_size, const char *message,
unsigned int message_len)
{ {
unsigned char reply_codes[3] = { SSH_MSG_CHANNEL_OPEN_CONFIRMATION, SSH_MSG_CHANNEL_OPEN_FAILURE, 0 }; static const unsigned char reply_codes[3] = {
SSH_MSG_CHANNEL_OPEN_CONFIRMATION,
SSH_MSG_CHANNEL_OPEN_FAILURE,
0
};
LIBSSH2_CHANNEL *channel = NULL; LIBSSH2_CHANNEL *channel = NULL;
unsigned long local_channel = libssh2_channel_nextid(session); unsigned long local_channel = libssh2_channel_nextid(session);
unsigned char *s, *packet = NULL; unsigned char *s, *packet = NULL;
unsigned long packet_len = channel_type_len + message_len + 17; /* packet_type(1) + channel_type_len(4) + sender_channel(4) + unsigned long packet_len =
window_size(4) + packet_size(4) */ channel_type_len + message_len + 17; /* packet_type(1) +
channel_type_len(4) +
sender_channel(4) +
window_size(4) +
packet_size(4) */
unsigned char *data = NULL; unsigned char *data = NULL;
unsigned long data_len; unsigned long data_len;
#ifdef LIBSSH2_DEBUG_CONNECTION _libssh2_debug(session, LIBSSH2_DBG_CONN,
_libssh2_debug(session, LIBSSH2_DBG_CONN, "Opening Channel - win %d pack %d", window_size, packet_size); "Opening Channel - win %d pack %d",
#endif window_size, packet_size);
channel = LIBSSH2_ALLOC(session, sizeof(LIBSSH2_CHANNEL)); channel = LIBSSH2_ALLOC(session, sizeof(LIBSSH2_CHANNEL));
if (!channel) { if (!channel) {
libssh2_error(session, LIBSSH2_ERROR_ALLOC, "Unable to allocate space for channel data", 0); libssh2_error(session, LIBSSH2_ERROR_ALLOC,
"Unable to allocate space for channel data", 0);
return NULL; return NULL;
} }
memset(channel, 0, sizeof(LIBSSH2_CHANNEL)); memset(channel, 0, sizeof(LIBSSH2_CHANNEL));
@@ -130,7 +214,8 @@ LIBSSH2_API LIBSSH2_CHANNEL *libssh2_channel_open_ex(LIBSSH2_SESSION *session, c
channel->channel_type_len = channel_type_len; channel->channel_type_len = channel_type_len;
channel->channel_type = LIBSSH2_ALLOC(session, channel_type_len); channel->channel_type = LIBSSH2_ALLOC(session, channel_type_len);
if (!channel->channel_type) { if (!channel->channel_type) {
libssh2_error(session, LIBSSH2_ERROR_ALLOC, "Failed allocating memory for channel type name", 0); libssh2_error(session, LIBSSH2_ERROR_ALLOC,
"Failed allocating memory for channel type name", 0);
LIBSSH2_FREE(session, channel); LIBSSH2_FREE(session, channel);
return NULL; return NULL;
} }
@@ -146,27 +231,40 @@ LIBSSH2_API LIBSSH2_CHANNEL *libssh2_channel_open_ex(LIBSSH2_SESSION *session, c
s = packet = LIBSSH2_ALLOC(session, packet_len); s = packet = LIBSSH2_ALLOC(session, packet_len);
if (!packet) { if (!packet) {
libssh2_error(session, LIBSSH2_ERROR_ALLOC, "Unable to allocate temporary space for packet", 0); libssh2_error(session, LIBSSH2_ERROR_ALLOC,
return NULL; "Unable to allocate temporary space for packet",
0);
goto channel_error;
} }
*(s++) = SSH_MSG_CHANNEL_OPEN; *(s++) = SSH_MSG_CHANNEL_OPEN;
libssh2_htonu32(s, channel_type_len); s += 4; libssh2_htonu32(s, channel_type_len);
memcpy(s, channel_type, channel_type_len); s += channel_type_len; s += 4;
libssh2_htonu32(s, local_channel); s += 4; memcpy(s, channel_type, channel_type_len);
libssh2_htonu32(s, window_size); s += 4; s += channel_type_len;
libssh2_htonu32(s, packet_size); s += 4;
libssh2_htonu32(s, local_channel);
s += 4;
libssh2_htonu32(s, window_size);
s += 4;
libssh2_htonu32(s, packet_size);
s += 4;
if (message && message_len) { if (message && message_len) {
memcpy(s, message, message_len); s += message_len; memcpy(s, message, message_len);
s += message_len;
} }
if (libssh2_packet_write(session, packet, packet_len)) { if (libssh2_packet_write(session, packet, packet_len)) {
libssh2_error(session, LIBSSH2_ERROR_SOCKET_SEND, "Unable to send channel-open request", 0); libssh2_error(session, LIBSSH2_ERROR_SOCKET_SEND,
"Unable to send channel-open request", 0);
goto channel_error; goto channel_error;
} }
if (libssh2_packet_requirev_ex(session, reply_codes, &data, &data_len, 1, packet + 5 + channel_type_len, 4)) { if (libssh2_packet_requirev_ex(session, reply_codes, &data, &data_len,
1, packet + 5 + channel_type_len, 4)) {
goto channel_error; goto channel_error;
} }
@@ -175,12 +273,11 @@ LIBSSH2_API LIBSSH2_CHANNEL *libssh2_channel_open_ex(LIBSSH2_SESSION *session, c
channel->local.window_size = libssh2_ntohu32(data + 9); channel->local.window_size = libssh2_ntohu32(data + 9);
channel->local.window_size_initial = libssh2_ntohu32(data + 9); channel->local.window_size_initial = libssh2_ntohu32(data + 9);
channel->local.packet_size = libssh2_ntohu32(data + 13); channel->local.packet_size = libssh2_ntohu32(data + 13);
#ifdef LIBSSH2_DEBUG_CONNECTION _libssh2_debug(session, LIBSSH2_DBG_CONN,
_libssh2_debug(session, LIBSSH2_DBG_CONN, "Connection Established - ID: %lu/%lu win: %lu/%lu pack: %lu/%lu", "Connection Established - ID: %lu/%lu win: %lu/%lu pack: %lu/%lu",
channel->local.id, channel->remote.id, channel->local.id, channel->remote.id,
channel->local.window_size, channel->remote.window_size, channel->local.window_size, channel->remote.window_size,
channel->local.packet_size, channel->remote.packet_size); channel->local.packet_size, channel->remote.packet_size);
#endif
LIBSSH2_FREE(session, packet); LIBSSH2_FREE(session, packet);
LIBSSH2_FREE(session, data); LIBSSH2_FREE(session, data);
@@ -188,7 +285,8 @@ LIBSSH2_API LIBSSH2_CHANNEL *libssh2_channel_open_ex(LIBSSH2_SESSION *session, c
} }
if (data[0] == SSH_MSG_CHANNEL_OPEN_FAILURE) { if (data[0] == SSH_MSG_CHANNEL_OPEN_FAILURE) {
libssh2_error(session, LIBSSH2_ERROR_CHANNEL_FAILURE, "Channel open failure", 0); libssh2_error(session, LIBSSH2_ERROR_CHANNEL_FAILURE,
"Channel open failure", 0);
} }
channel_error: channel_error:
@@ -218,8 +316,12 @@ LIBSSH2_API LIBSSH2_CHANNEL *libssh2_channel_open_ex(LIBSSH2_SESSION *session, c
/* Clear out packets meant for this channel */ /* Clear out packets meant for this channel */
libssh2_htonu32(channel_id, channel->local.id); libssh2_htonu32(channel_id, channel->local.id);
while ((libssh2_packet_ask_ex(session, SSH_MSG_CHANNEL_DATA, &data, &data_len, 1, channel_id, 4, 1) >= 0) || while ((libssh2_packet_ask_ex(session, SSH_MSG_CHANNEL_DATA,
(libssh2_packet_ask_ex(session, SSH_MSG_CHANNEL_EXTENDED_DATA, &data, &data_len, 1, channel_id, 4, 1) >= 0)) { &data, &data_len, 1, channel_id,
4, 0) >= 0) ||
(libssh2_packet_ask_ex(session, SSH_MSG_CHANNEL_EXTENDED_DATA,
&data, &data_len, 1, channel_id,
4, 0) >= 0)) {
LIBSSH2_FREE(session, data); LIBSSH2_FREE(session, data);
} }
@@ -233,16 +335,14 @@ LIBSSH2_API LIBSSH2_CHANNEL *libssh2_channel_open_ex(LIBSSH2_SESSION *session, c
/* {{{ libssh2_channel_direct_tcpip_ex /* {{{ libssh2_channel_direct_tcpip_ex
* Tunnel TCP/IP connect through the SSH session to direct host/port * Tunnel TCP/IP connect through the SSH session to direct host/port
*/ */
LIBSSH2_API LIBSSH2_CHANNEL *libssh2_channel_direct_tcpip_ex(LIBSSH2_SESSION *session, char *host, int port, char *shost, int sport) LIBSSH2_API LIBSSH2_CHANNEL *libssh2_channel_direct_tcpip_ex(LIBSSH2_SESSION *session, const char *host, int port, const char *shost, int sport)
{ {
LIBSSH2_CHANNEL *channel; LIBSSH2_CHANNEL *channel;
unsigned char *message, *s; unsigned char *message, *s;
unsigned long host_len = strlen(host), shost_len = strlen(shost); unsigned long host_len = strlen(host), shost_len = strlen(shost);
unsigned long message_len = host_len + shost_len + 16; /* host_len(4) + port(4) + shost_len(4) + sport(4) */ unsigned long message_len = host_len + shost_len + 16; /* host_len(4) + port(4) + shost_len(4) + sport(4) */
#ifdef LIBSSH2_DEBUG_CONNECTION
_libssh2_debug(session, LIBSSH2_DBG_CONN, "Requesting direct-tcpip session to from %s:%d to %s:%d", shost, sport, host, port); _libssh2_debug(session, LIBSSH2_DBG_CONN, "Requesting direct-tcpip session to from %s:%d to %s:%d", shost, sport, host, port);
#endif
s = message = LIBSSH2_ALLOC(session, message_len); s = message = LIBSSH2_ALLOC(session, message_len);
if (!message) { if (!message) {
@@ -257,7 +357,11 @@ LIBSSH2_API LIBSSH2_CHANNEL *libssh2_channel_direct_tcpip_ex(LIBSSH2_SESSION *se
memcpy(s, shost, shost_len); s += shost_len; memcpy(s, shost, shost_len); s += shost_len;
libssh2_htonu32(s, sport); s += 4; libssh2_htonu32(s, sport); s += 4;
channel = libssh2_channel_open_ex(session, "direct-tcpip", sizeof("direct-tcpip") - 1, LIBSSH2_CHANNEL_WINDOW_DEFAULT, LIBSSH2_CHANNEL_PACKET_DEFAULT, message, message_len); channel = libssh2_channel_open_ex(session, "direct-tcpip",
sizeof("direct-tcpip") - 1,
LIBSSH2_CHANNEL_WINDOW_DEFAULT,
LIBSSH2_CHANNEL_PACKET_DEFAULT,
(char *)message, message_len);
LIBSSH2_FREE(session, message); LIBSSH2_FREE(session, message);
return channel; return channel;
@@ -267,17 +371,16 @@ LIBSSH2_API LIBSSH2_CHANNEL *libssh2_channel_direct_tcpip_ex(LIBSSH2_SESSION *se
/* {{{ libssh2_channel_forward_listen_ex /* {{{ libssh2_channel_forward_listen_ex
* Bind a port on the remote host and listen for connections * Bind a port on the remote host and listen for connections
*/ */
LIBSSH2_API LIBSSH2_LISTENER *libssh2_channel_forward_listen_ex(LIBSSH2_SESSION *session, char *host, int port, int *bound_port, int queue_maxsize) LIBSSH2_API LIBSSH2_LISTENER *libssh2_channel_forward_listen_ex(LIBSSH2_SESSION *session, const char *host, int port, int *bound_port, int queue_maxsize)
{ {
unsigned char *packet, *s, *data, reply_codes[3] = { SSH_MSG_REQUEST_SUCCESS, SSH_MSG_REQUEST_FAILURE, 0 }; unsigned char *packet, *s, *data;
static const unsigned char reply_codes[3] = { SSH_MSG_REQUEST_SUCCESS, SSH_MSG_REQUEST_FAILURE, 0 };
unsigned long data_len; unsigned long data_len;
unsigned long host_len = (host ? strlen(host) : (sizeof("0.0.0.0") - 1)); unsigned long host_len = (host ? strlen(host) : (sizeof("0.0.0.0") - 1));
unsigned long packet_len = host_len + (sizeof("tcpip-forward") - 1) + 14; unsigned long packet_len = host_len + (sizeof("tcpip-forward") - 1) + 14;
/* packet_type(1) + request_len(4) + want_replay(1) + host_len(4) + port(4) */ /* packet_type(1) + request_len(4) + want_replay(1) + host_len(4) + port(4) */
#ifdef LIBSSH2_DEBUG_CONNECTION
_libssh2_debug(session, LIBSSH2_DBG_CONN, "Requesting tcpip-forward session for %s:%d", host, port); _libssh2_debug(session, LIBSSH2_DBG_CONN, "Requesting tcpip-forward session for %s:%d", host, port);
#endif
s = packet = LIBSSH2_ALLOC(session, packet_len); s = packet = LIBSSH2_ALLOC(session, packet_len);
if (!packet) { if (!packet) {
@@ -327,9 +430,9 @@ LIBSSH2_API LIBSSH2_LISTENER *libssh2_channel_forward_listen_ex(LIBSSH2_SESSION
listener->host[host_len] = 0; listener->host[host_len] = 0;
if (data_len >= 5 && !port) { if (data_len >= 5 && !port) {
listener->port = libssh2_ntohu32(data + 1); listener->port = libssh2_ntohu32(data + 1);
#ifdef LIBSSH2_DEBUG_CONNECTION _libssh2_debug(session, LIBSSH2_DBG_CONN,
_libssh2_debug(session, LIBSSH2_DBG_CONN, "Dynamic tcpip-forward port allocated: %d", listener->port); "Dynamic tcpip-forward port allocated: %d",
#endif listener->port);
} else { } else {
listener->port = port; listener->port = port;
} }
@@ -375,9 +478,7 @@ LIBSSH2_API int libssh2_channel_forward_cancel(LIBSSH2_LISTENER *listener)
unsigned long packet_len = host_len + 14 + sizeof("cancel-tcpip-forward") - 1; unsigned long packet_len = host_len + 14 + sizeof("cancel-tcpip-forward") - 1;
/* packet_type(1) + request_len(4) + want_replay(1) + host_len(4) + port(4) */ /* packet_type(1) + request_len(4) + want_replay(1) + host_len(4) + port(4) */
#ifdef LIBSSH2_DEBUG_CONNECTION
_libssh2_debug(session, LIBSSH2_DBG_CONN, "Cancelling tcpip-forward session for %s:%d", listener->host, listener->port); _libssh2_debug(session, LIBSSH2_DBG_CONN, "Cancelling tcpip-forward session for %s:%d", listener->host, listener->port);
#endif
s = packet = LIBSSH2_ALLOC(session, packet_len); s = packet = LIBSSH2_ALLOC(session, packet_len);
if (!packet) { if (!packet) {
@@ -427,9 +528,18 @@ LIBSSH2_API int libssh2_channel_forward_cancel(LIBSSH2_LISTENER *listener)
/* {{{ libssh2_channel_forward_accept /* {{{ libssh2_channel_forward_accept
* Accept a connection * Accept a connection
*/ */
LIBSSH2_API LIBSSH2_CHANNEL *libssh2_channel_forward_accept(LIBSSH2_LISTENER *listener) LIBSSH2_API LIBSSH2_CHANNEL *
libssh2_channel_forward_accept(LIBSSH2_LISTENER *listener)
{ {
while (libssh2_packet_read(listener->session, 0) > 0); libssh2pack_t rc;
int loop=-1;
do {
rc = libssh2_packet_read(listener->session);
loop++;
} while (rc > 0);
/* dast: now this might have returned with EAGAIN status which might
be somehow signalled to the caller... */
if (listener->queue) { if (listener->queue) {
LIBSSH2_SESSION *session = listener->session; LIBSSH2_SESSION *session = listener->session;
@@ -463,17 +573,16 @@ LIBSSH2_API LIBSSH2_CHANNEL *libssh2_channel_forward_accept(LIBSSH2_LISTENER *li
/* {{{ libssh2_channel_setenv_ex /* {{{ libssh2_channel_setenv_ex
* Set an environment variable prior to requesting a shell/program/subsystem * Set an environment variable prior to requesting a shell/program/subsystem
*/ */
LIBSSH2_API int libssh2_channel_setenv_ex(LIBSSH2_CHANNEL *channel, char *varname, int varname_len, char *value, int value_len) LIBSSH2_API int libssh2_channel_setenv_ex(LIBSSH2_CHANNEL *channel, char *varname, unsigned int varname_len, const char *value, unsigned int value_len)
{ {
LIBSSH2_SESSION *session = channel->session; LIBSSH2_SESSION *session = channel->session;
unsigned char *s, *packet, *data, reply_codes[3] = { SSH_MSG_CHANNEL_SUCCESS, SSH_MSG_CHANNEL_FAILURE, 0 }, local_channel[4]; unsigned char *s, *packet, *data, local_channel[4];
static const unsigned char reply_codes[3] = { SSH_MSG_CHANNEL_SUCCESS, SSH_MSG_CHANNEL_FAILURE, 0 };
unsigned long data_len; unsigned long data_len;
unsigned long packet_len = varname_len + value_len + 21; /* packet_type(1) + channel_id(4) + request_len(4) + request(3)"env" + unsigned long packet_len = varname_len + value_len + 21; /* packet_type(1) + channel_id(4) + request_len(4) + request(3)"env" +
want_reply(1) + varname_len(4) + value_len(4) */ want_reply(1) + varname_len(4) + value_len(4) */
#ifdef LIBSSH2_DEBUG_CONNECTION
_libssh2_debug(session, LIBSSH2_DBG_CONN, "Setting remote environment variable: %s=%s on channel %lu/%lu", varname, value, channel->local.id, channel->remote.id); _libssh2_debug(session, LIBSSH2_DBG_CONN, "Setting remote environment variable: %s=%s on channel %lu/%lu", varname, value, channel->local.id, channel->remote.id);
#endif
s = packet = LIBSSH2_ALLOC(session, packet_len); s = packet = LIBSSH2_ALLOC(session, packet_len);
if (!packet) { if (!packet) {
@@ -512,7 +621,8 @@ LIBSSH2_API int libssh2_channel_setenv_ex(LIBSSH2_CHANNEL *channel, char *varnam
} }
LIBSSH2_FREE(session, data); LIBSSH2_FREE(session, data);
libssh2_error(session, LIBSSH2_ERROR_CHANNEL_REQUEST_DENIED, "Unable to complete request for channel-setenv", 0); libssh2_error(session, LIBSSH2_ERROR_CHANNEL_REQUEST_DENIED,
"Unable to complete request for channel-setenv", 0);
return -1; return -1;
} }
/* }}} */ /* }}} */
@@ -520,20 +630,19 @@ LIBSSH2_API int libssh2_channel_setenv_ex(LIBSSH2_CHANNEL *channel, char *varnam
/* {{{ libssh2_channel_request_pty_ex /* {{{ libssh2_channel_request_pty_ex
* Duh... Request a PTY * Duh... Request a PTY
*/ */
LIBSSH2_API int libssh2_channel_request_pty_ex(LIBSSH2_CHANNEL *channel, char *term, int term_len, LIBSSH2_API int libssh2_channel_request_pty_ex(LIBSSH2_CHANNEL *channel, const char *term, unsigned int term_len,
char *modes, int modes_len, const char *modes, unsigned int modes_len,
int width, int height, int width, int height,
int width_px, int height_px) int width_px, int height_px)
{ {
LIBSSH2_SESSION *session = channel->session; LIBSSH2_SESSION *session = channel->session;
unsigned char *s, *packet, *data, reply_codes[3] = { SSH_MSG_CHANNEL_SUCCESS, SSH_MSG_CHANNEL_FAILURE, 0 }, local_channel[4]; unsigned char *s, *packet, *data, local_channel[4];
static const unsigned char reply_codes[3] = { SSH_MSG_CHANNEL_SUCCESS, SSH_MSG_CHANNEL_FAILURE, 0 };
unsigned long data_len; unsigned long data_len;
unsigned long packet_len = term_len + modes_len + 41; /* packet_type(1) + channel(4) + pty_req_len(4) + "pty_req"(7) + want_reply(1) + unsigned long packet_len = term_len + modes_len + 41; /* packet_type(1) + channel(4) + pty_req_len(4) + "pty_req"(7) + want_reply(1) +
term_len(4) + width(4) + height(4) + width_px(4) + height_px(4) + modes_len(4) */ term_len(4) + width(4) + height(4) + width_px(4) + height_px(4) + modes_len(4) */
#ifdef LIBSSH2_DEBUG_CONNECTION
_libssh2_debug(session, LIBSSH2_DBG_CONN, "Allocating tty on channel %lu/%lu", channel->local.id, channel->remote.id); _libssh2_debug(session, LIBSSH2_DBG_CONN, "Allocating tty on channel %lu/%lu", channel->local.id, channel->remote.id);
#endif
s = packet = LIBSSH2_ALLOC(session, packet_len); s = packet = LIBSSH2_ALLOC(session, packet_len);
if (!packet) { if (!packet) {
@@ -591,22 +700,21 @@ LIBSSH2_API int libssh2_channel_request_pty_ex(LIBSSH2_CHANNEL *channel, char *t
/* {{{ libssh2_channel_x11_req_ex /* {{{ libssh2_channel_x11_req_ex
* Request X11 forwarding * Request X11 forwarding
*/ */
LIBSSH2_API int libssh2_channel_x11_req_ex(LIBSSH2_CHANNEL *channel, int single_connection, char *auth_proto, char *auth_cookie, int screen_number) LIBSSH2_API int libssh2_channel_x11_req_ex(LIBSSH2_CHANNEL *channel, int single_connection, const char *auth_proto, const char *auth_cookie, int screen_number)
{ {
LIBSSH2_SESSION *session = channel->session; LIBSSH2_SESSION *session = channel->session;
unsigned char *s, *packet, *data, reply_codes[3] = { SSH_MSG_CHANNEL_SUCCESS, SSH_MSG_CHANNEL_FAILURE, 0 }, local_channel[4]; unsigned char *s, *packet, *data, local_channel[4];
static const unsigned char reply_codes[3] = { SSH_MSG_CHANNEL_SUCCESS, SSH_MSG_CHANNEL_FAILURE, 0 };
unsigned long data_len; unsigned long data_len;
unsigned long proto_len = auth_proto ? strlen(auth_proto) : (sizeof("MIT-MAGIC-COOKIE-1") - 1); unsigned long proto_len = auth_proto ? strlen(auth_proto) : (sizeof("MIT-MAGIC-COOKIE-1") - 1);
unsigned long cookie_len = auth_cookie ? strlen(auth_cookie) : LIBSSH2_X11_RANDOM_COOKIE_LEN; unsigned long cookie_len = auth_cookie ? strlen(auth_cookie) : LIBSSH2_X11_RANDOM_COOKIE_LEN;
unsigned long packet_len = proto_len + cookie_len + 30; /* packet_type(1) + channel(4) + x11_req_len(4) + "x11-req"(7) + want_reply(1) + unsigned long packet_len = proto_len + cookie_len + 30; /* packet_type(1) + channel(4) + x11_req_len(4) + "x11-req"(7) + want_reply(1) +
single_cnx(1) + proto_len(4) + cookie_len(4) + screen_num(4) */ single_cnx(1) + proto_len(4) + cookie_len(4) + screen_num(4) */
#ifdef LIBSSH2_DEBUG_CONNECTION
_libssh2_debug(session, LIBSSH2_DBG_CONN, "Requesting x11-req for channel %lu/%lu: single=%d proto=%s cookie=%s screen=%d", _libssh2_debug(session, LIBSSH2_DBG_CONN, "Requesting x11-req for channel %lu/%lu: single=%d proto=%s cookie=%s screen=%d",
channel->local.id, channel->remote.id, single_connection, channel->local.id, channel->remote.id, single_connection,
auth_proto ? auth_proto : "MIT-MAGIC-COOKIE-1", auth_proto ? auth_proto : "MIT-MAGIC-COOKIE-1",
auth_cookie ? auth_cookie : "<random>", screen_number); auth_cookie ? auth_cookie : "<random>", screen_number);
#endif
s = packet = LIBSSH2_ALLOC(session, packet_len); s = packet = LIBSSH2_ALLOC(session, packet_len);
if (!packet) { if (!packet) {
@@ -631,11 +739,11 @@ LIBSSH2_API int libssh2_channel_x11_req_ex(LIBSSH2_CHANNEL *channel, int single_
memcpy(s, auth_cookie, cookie_len); memcpy(s, auth_cookie, cookie_len);
} else { } else {
int i; int i;
char buffer[LIBSSH2_X11_RANDOM_COOKIE_LEN / 2]; unsigned char buffer[LIBSSH2_X11_RANDOM_COOKIE_LEN / 2];
RAND_bytes(buffer, LIBSSH2_X11_RANDOM_COOKIE_LEN / 2); libssh2_random(buffer, LIBSSH2_X11_RANDOM_COOKIE_LEN / 2);
for (i = 0; i < (LIBSSH2_X11_RANDOM_COOKIE_LEN / 2); i++) { for (i = 0; i < (LIBSSH2_X11_RANDOM_COOKIE_LEN / 2); i++) {
snprintf(s + (i * 2), 2, "%02X", buffer[i]); snprintf((char *)s + (i * 2), 2, "%02X", buffer[i]);
} }
} }
s += cookie_len; s += cookie_len;
@@ -669,21 +777,20 @@ LIBSSH2_API int libssh2_channel_x11_req_ex(LIBSSH2_CHANNEL *channel, int single_
/* {{{ libssh2_channel_process_startup /* {{{ libssh2_channel_process_startup
* Primitive for libssh2_channel_(shell|exec|subsystem) * Primitive for libssh2_channel_(shell|exec|subsystem)
*/ */
LIBSSH2_API int libssh2_channel_process_startup(LIBSSH2_CHANNEL *channel, const char *request, int request_len, const char *message, int message_len) LIBSSH2_API int libssh2_channel_process_startup(LIBSSH2_CHANNEL *channel, const char *request, unsigned int request_len, const char *message, unsigned int message_len)
{ {
LIBSSH2_SESSION *session = channel->session; LIBSSH2_SESSION *session = channel->session;
unsigned char *s, *packet, *data, reply_codes[3] = { SSH_MSG_CHANNEL_SUCCESS, SSH_MSG_CHANNEL_FAILURE, 0 }, local_channel[4]; unsigned char *s, *packet, *data, local_channel[4];
static const unsigned char reply_codes[3] = { SSH_MSG_CHANNEL_SUCCESS, SSH_MSG_CHANNEL_FAILURE, 0 };
unsigned long data_len; unsigned long data_len;
unsigned long packet_len = request_len + 10; /* packet_type(1) + channel(4) + request_len(4) + want_reply(1) */ unsigned long packet_len = request_len + 10; /* packet_type(1) + channel(4) + request_len(4) + want_reply(1) */
libssh2pack_t rc;
if (message) { if (message) {
packet_len += message_len + 4; packet_len += message_len + 4;
} }
#ifdef LIBSSH2_DEBUG_CONNECTION
_libssh2_debug(session, LIBSSH2_DBG_CONN, "starting request(%s) on channel %lu/%lu, message=%s", request, channel->local.id, channel->remote.id, message); _libssh2_debug(session, LIBSSH2_DBG_CONN, "starting request(%s) on channel %lu/%lu, message=%s", request, channel->local.id, channel->remote.id, message);
#endif
s = packet = LIBSSH2_ALLOC(session, packet_len); s = packet = LIBSSH2_ALLOC(session, packet_len);
if (!packet) { if (!packet) {
libssh2_error(session, LIBSSH2_ERROR_ALLOC, "Unable to allocate memory for channel-process request", 0); libssh2_error(session, LIBSSH2_ERROR_ALLOC, "Unable to allocate memory for channel-process request", 0);
@@ -702,7 +809,8 @@ LIBSSH2_API int libssh2_channel_process_startup(LIBSSH2_CHANNEL *channel, const
memcpy(s, message, message_len); s += message_len; memcpy(s, message, message_len); s += message_len;
} }
if (libssh2_packet_write(session, packet, packet_len)) { rc = libssh2_packet_write(session, packet, packet_len);
if(rc) {
libssh2_error(session, LIBSSH2_ERROR_SOCKET_SEND, "Unable to send channel request", 0); libssh2_error(session, LIBSSH2_ERROR_SOCKET_SEND, "Unable to send channel request", 0);
LIBSSH2_FREE(session, packet); LIBSSH2_FREE(session, packet);
return -1; return -1;
@@ -725,15 +833,46 @@ LIBSSH2_API int libssh2_channel_process_startup(LIBSSH2_CHANNEL *channel, const
} }
/* }}} */ /* }}} */
/* {{{ libssh2_channel_set_blocking /* {{{ _libssh2_channel_set_blocking
* Set a channel's blocking mode on or off, similar to a socket's fcntl(fd, F_SETFL, O_NONBLOCK); type command * Set a channel's blocking mode on or off, return the status when this
* function is called.
*/ */
LIBSSH2_API void libssh2_channel_set_blocking(LIBSSH2_CHANNEL *channel, int blocking) int _libssh2_channel_set_blocking(LIBSSH2_CHANNEL *channel,
int blocking)
{ {
#ifdef LIBSSH2_DEBUG_CONNECTION int bl = channel->blocking;
_libssh2_debug(channel->session, LIBSSH2_DBG_CONN, "Setting blocking mode on channel %lu/%lu to %d", channel->local.id, channel->remote.id, blocking); _libssh2_debug(channel->session, LIBSSH2_DBG_CONN,
#endif "Setting blocking mode on channel %lu/%lu to %d",
channel->local.id, channel->remote.id, blocking);
if(blocking == channel->blocking) {
/* avoid if already correct */
return bl;
}
channel->blocking = blocking; channel->blocking = blocking;
_libssh2_nonblock(channel->session->socket_fd, !blocking);
return bl;
}
/* }}} */
/* {{{ libssh2_channel_set_blocking
* Set a channel's blocking mode on or off, similar to a socket's
* fcntl(fd, F_SETFL, O_NONBLOCK); type command
*/
LIBSSH2_API void libssh2_channel_set_blocking(LIBSSH2_CHANNEL *channel,
int blocking)
{
(void)_libssh2_channel_set_blocking(channel, blocking);
}
/* }}} */
/* {{{ libssh2_channel_get_blocking
* Returns a channel's blocking mode on or off
*/
int libssh2_channel_get_blocking(LIBSSH2_CHANNEL *channel)
{
return channel->blocking;
} }
/* }}} */ /* }}} */
@@ -750,18 +889,29 @@ LIBSSH2_API int libssh2_channel_flush_ex(LIBSSH2_CHANNEL *channel, int streamid)
LIBSSH2_PACKET *next = packet->next; LIBSSH2_PACKET *next = packet->next;
unsigned char packet_type = packet->data[0]; unsigned char packet_type = packet->data[0];
if (((packet_type == SSH_MSG_CHANNEL_DATA) || (packet_type == SSH_MSG_CHANNEL_EXTENDED_DATA)) && if (((packet_type == SSH_MSG_CHANNEL_DATA) ||
(packet_type == SSH_MSG_CHANNEL_EXTENDED_DATA)) &&
(libssh2_ntohu32(packet->data + 1) == channel->local.id)) { (libssh2_ntohu32(packet->data + 1) == channel->local.id)) {
/* It's our channel at least */ /* It's our channel at least */
unsigned long packet_stream_id = (packet_type == SSH_MSG_CHANNEL_DATA) ? 0 : libssh2_ntohu32(packet->data + 5); long packet_stream_id =
(packet_type == SSH_MSG_CHANNEL_DATA) ?
0 : libssh2_ntohu32(packet->data + 5);
if ((streamid == LIBSSH2_CHANNEL_FLUSH_ALL) || if ((streamid == LIBSSH2_CHANNEL_FLUSH_ALL) ||
((packet_type == SSH_MSG_CHANNEL_EXTENDED_DATA) && ((streamid == LIBSSH2_CHANNEL_FLUSH_EXTENDED_DATA) || (streamid == packet_stream_id))) || ((packet_type == SSH_MSG_CHANNEL_EXTENDED_DATA) &&
((packet_type == SSH_MSG_CHANNEL_DATA) && (streamid == 0))) { ((streamid == LIBSSH2_CHANNEL_FLUSH_EXTENDED_DATA) ||
int bytes_to_flush = packet->data_len - packet->data_head; (streamid == packet_stream_id))) ||
#ifdef LIBSSH2_DEBUG_CONNECTION ((packet_type == SSH_MSG_CHANNEL_DATA) &&
_libssh2_debug(channel->session, LIBSSH2_DBG_CONN, "Flushing %d bytes of data from stream %lu on channel %lu/%lu", bytes_to_flush, (streamid == 0))) {
packet_stream_id, channel->local.id, channel->remote.id); int bytes_to_flush =
#endif packet->data_len - packet->data_head;
_libssh2_debug(channel->session,
LIBSSH2_DBG_CONN,
"Flushing %d bytes of data from "
"stream %lu on channel %lu/%lu",
bytes_to_flush,
packet_stream_id,
channel->local.id,
channel->remote.id);
/* It's one of the streams we wanted to flush */ /* It's one of the streams we wanted to flush */
refund_bytes += packet->data_len - 13; refund_bytes += packet->data_len - 13;
@@ -814,9 +964,7 @@ LIBSSH2_API unsigned long libssh2_channel_receive_window_adjust(LIBSSH2_CHANNEL
unsigned char adjust[9]; /* packet_type(1) + channel(4) + adjustment(4) */ unsigned char adjust[9]; /* packet_type(1) + channel(4) + adjustment(4) */
if (!force && (adjustment + channel->adjust_queue < LIBSSH2_CHANNEL_MINADJUST)) { if (!force && (adjustment + channel->adjust_queue < LIBSSH2_CHANNEL_MINADJUST)) {
#ifdef LIBSSH2_DEBUG_CONNECTION _libssh2_debug(channel->session, LIBSSH2_DBG_CONN, "Queueing %lu bytes for receive window adjustment for channel %lu/%lu", adjustment, channel->local.id, channel->remote.id);
_libssh2_debug(channel->session, LIBSSH2_DBG_CONN, "Queing %lu bytes for receive window adjustment for channel %lu/%lu", adjustment, channel->local.id, channel->remote.id);
#endif
channel->adjust_queue += adjustment; channel->adjust_queue += adjustment;
return channel->remote.window_size; return channel->remote.window_size;
} }
@@ -833,9 +981,7 @@ LIBSSH2_API unsigned long libssh2_channel_receive_window_adjust(LIBSSH2_CHANNEL
adjust[0] = SSH_MSG_CHANNEL_WINDOW_ADJUST; adjust[0] = SSH_MSG_CHANNEL_WINDOW_ADJUST;
libssh2_htonu32(adjust + 1, channel->remote.id); libssh2_htonu32(adjust + 1, channel->remote.id);
libssh2_htonu32(adjust + 5, adjustment); libssh2_htonu32(adjust + 5, adjustment);
#ifdef LIBSSH2_DEBUG_CONNECTION
_libssh2_debug(channel->session, LIBSSH2_DBG_CONN, "Adjusting window %lu bytes for data flushed from channel %lu/%lu", adjustment, channel->local.id, channel->remote.id); _libssh2_debug(channel->session, LIBSSH2_DBG_CONN, "Adjusting window %lu bytes for data flushed from channel %lu/%lu", adjustment, channel->local.id, channel->remote.id);
#endif
if (libssh2_packet_write(channel->session, adjust, 9)) { if (libssh2_packet_write(channel->session, adjust, 9)) {
libssh2_error(channel->session, LIBSSH2_ERROR_SOCKET_SEND, "Unable to send transfer-window adjustment packet, deferring", 0); libssh2_error(channel->session, LIBSSH2_ERROR_SOCKET_SEND, "Unable to send transfer-window adjustment packet, deferring", 0);
@@ -856,9 +1002,7 @@ LIBSSH2_API unsigned long libssh2_channel_receive_window_adjust(LIBSSH2_CHANNEL
*/ */
LIBSSH2_API void libssh2_channel_handle_extended_data(LIBSSH2_CHANNEL *channel, int ignore_mode) LIBSSH2_API void libssh2_channel_handle_extended_data(LIBSSH2_CHANNEL *channel, int ignore_mode)
{ {
#ifdef LIBSSH2_DEBUG_CONNECTION
_libssh2_debug(channel->session, LIBSSH2_DBG_CONN, "Setting channel %lu/%lu handle_extended_data mode to %d", channel->local.id, channel->remote.id, ignore_mode); _libssh2_debug(channel->session, LIBSSH2_DBG_CONN, "Setting channel %lu/%lu handle_extended_data mode to %d", channel->local.id, channel->remote.id, ignore_mode);
#endif
channel->remote.extended_data_ignore_mode = ignore_mode; channel->remote.extended_data_ignore_mode = ignore_mode;
if (ignore_mode == LIBSSH2_CHANNEL_EXTENDED_DATA_IGNORE) { if (ignore_mode == LIBSSH2_CHANNEL_EXTENDED_DATA_IGNORE) {
@@ -867,46 +1011,99 @@ LIBSSH2_API void libssh2_channel_handle_extended_data(LIBSSH2_CHANNEL *channel,
} }
/* }}} */ /* }}} */
/* {{{ libssh2_channel_read_ex /* {{{ _libssh2_channel_read_ex
* Read data from a channel * Read data from a channel blocking or non-blocking depending on set state
*
* When this is done non-blocking, it is important to not return 0 until the
* currently read channel is complete. If we read stuff from the wire but it
* was no payload data to fill in the buffer with, we MUST make sure to return
* PACKET_EAGAIN.
*/ */
LIBSSH2_API int libssh2_channel_read_ex(LIBSSH2_CHANNEL *channel, int stream_id, char *buf, size_t buflen) ssize_t _libssh2_channel_read_ex(LIBSSH2_CHANNEL *channel,
int stream_id, char *buf, size_t buflen)
{ {
LIBSSH2_SESSION *session = channel->session; LIBSSH2_SESSION *session = channel->session;
int bytes_read = 0, blocking_read = 0; int bytes_read = 0;
#ifdef LIBSSH2_DEBUG_CONNECTION
_libssh2_debug(session, LIBSSH2_DBG_CONN, "Attempting to read %d bytes from channel %lu/%lu stream #%d", (int)buflen, channel->local.id, channel->remote.id, stream_id);
#endif
do {
LIBSSH2_PACKET *packet; LIBSSH2_PACKET *packet;
libssh2pack_t rc=0;
int bl;
int block=0;
_libssh2_debug(session, LIBSSH2_DBG_CONN,
"Attempting to read %d bytes from channel %lu/%lu stream #%d",
(int)buflen,
channel->local.id, channel->remote.id, stream_id);
/* set non-blocking and remember previous state */
bl = _libssh2_channel_set_blocking(channel, 0);
/* process all incoming packets */
do {
rc = libssh2_packet_read(session);
} while (rc > 0);
if((rc < 0) && (rc != PACKET_EAGAIN)) {
return rc;
}
rc = 0;
/* restore blocking state */
_libssh2_channel_set_blocking(channel, bl);
/* Process any waiting packets */
while (libssh2_packet_read(session, blocking_read) > 0) blocking_read = 0;
packet = session->packets.head; packet = session->packets.head;
while (packet && (bytes_read < buflen)) { do {
/* In case packet gets destroyed during this iteration */
if(block) {
/* in the second lap and onwards, do this */
rc = libssh2_packet_read(session);
packet = session->packets.head;
}
if(rc < 0) {
/* no packets available */
return rc;
}
while (packet && (bytes_read < (int)buflen)) {
/* In case packet gets destroyed during this
iteration */
LIBSSH2_PACKET *next = packet->next; LIBSSH2_PACKET *next = packet->next;
/* Either we asked for a specific extended data stream (and data was available), uint32_t local_id = libssh2_ntohu32(packet->data + 1);
/* Either we asked for a specific extended data stream
* (and data was available),
* or the standard stream (and data was available), * or the standard stream (and data was available),
* or the standard stream with extended_data_merge enabled and data was available * or the standard stream with extended_data_merge
* enabled and data was available
*/ */
if ((stream_id && (packet->data[0] == SSH_MSG_CHANNEL_EXTENDED_DATA) && (channel->local.id == libssh2_ntohu32(packet->data + 1)) && (stream_id == libssh2_ntohu32(packet->data + 5))) || if ((stream_id &&
(!stream_id && (packet->data[0] == SSH_MSG_CHANNEL_DATA) && (channel->local.id == libssh2_ntohu32(packet->data + 1))) || (packet->data[0] == SSH_MSG_CHANNEL_EXTENDED_DATA) &&
(!stream_id && (packet->data[0] == SSH_MSG_CHANNEL_EXTENDED_DATA) && (channel->local.id == libssh2_ntohu32(packet->data + 1)) && (channel->remote.extended_data_ignore_mode == LIBSSH2_CHANNEL_EXTENDED_DATA_MERGE))) { (channel->local.id == local_id) &&
(stream_id == (int)libssh2_ntohu32(packet->data + 5))) ||
(!stream_id &&
(packet->data[0] == SSH_MSG_CHANNEL_DATA) &&
(channel->local.id == local_id)) ||
(!stream_id &&
(packet->data[0] == SSH_MSG_CHANNEL_EXTENDED_DATA) &&
(channel->local.id == local_id) &&
(channel->remote.extended_data_ignore_mode == LIBSSH2_CHANNEL_EXTENDED_DATA_MERGE))) {
int want = buflen - bytes_read; int want = buflen - bytes_read;
int unlink_packet = 0; int unlink_packet = 0;
if (want >= (packet->data_len - packet->data_head)) { if (want >= (int)(packet->data_len - packet->data_head)) {
want = packet->data_len - packet->data_head; want = packet->data_len - packet->data_head;
unlink_packet = 1; unlink_packet = 1;
} }
#ifdef LIBSSH2_DEBUG_CONNECTION _libssh2_debug(session, LIBSSH2_DBG_CONN,
_libssh2_debug(session, LIBSSH2_DBG_CONN, "Reading %d of buffered data from %lu/%lu/%d", want, channel->local.id, channel->remote.id, stream_id); "Reading %d of buffered data from %lu/%lu/%d",
#endif want, channel->local.id,
channel->remote.id, stream_id);
memcpy(buf + bytes_read, packet->data + packet->data_head, want); memcpy(buf + bytes_read, packet->data + packet->data_head, want);
packet->data_head += want; packet->data_head += want;
bytes_read += want; bytes_read += want;
@@ -924,38 +1121,96 @@ LIBSSH2_API int libssh2_channel_read_ex(LIBSSH2_CHANNEL *channel, int stream_id,
} }
LIBSSH2_FREE(session, packet->data); LIBSSH2_FREE(session, packet->data);
#ifdef LIBSSH2_DEBUG_CONNECTION
_libssh2_debug(session, LIBSSH2_DBG_CONN, "Unlinking empty packet buffer from channel %lu/%lu", channel->local.id, channel->remote.id); _libssh2_debug(session,
#endif LIBSSH2_DBG_CONN,
"Unlinking empty packet buffer from channel %lu/%lu",
channel->local.id, channel->remote.id);
libssh2_channel_receive_window_adjust(channel, packet->data_len - (stream_id ? 13 : 9), 0); libssh2_channel_receive_window_adjust(channel, packet->data_len - (stream_id ? 13 : 9), 0);
LIBSSH2_FREE(session, packet); LIBSSH2_FREE(session, packet);
} }
} }
packet = next; packet = next;
} }
blocking_read = 1; block=1;
} while (channel->blocking && (bytes_read == 0) && !channel->remote.close);
if (channel->blocking && (bytes_read == 0)) { } while (channel->blocking && (bytes_read == 0) &&
libssh2_error(session, LIBSSH2_ERROR_CHANNEL_CLOSED, "Remote end has closed this channel", 0); !channel->remote.close);
if (bytes_read == 0) {
if(channel->blocking) {
libssh2_error(session, LIBSSH2_ERROR_CHANNEL_CLOSED,
"Remote end has closed this channel", 0);
}
else {
/* when non-blocking, we must return PACKET_EAGAIN if
we haven't completed reading the channel */
if(!libssh2_channel_eof(channel)) {
return PACKET_EAGAIN;
}
}
} }
return bytes_read; return bytes_read;
} }
/* }}} */ /* }}} */
LIBSSH2_API int libssh2_channel_read_ex(LIBSSH2_CHANNEL *channel,
int stream_id,
char *buf, size_t buflen)
{
ssize_t rc;
int bl;
/* set blocking */
bl = _libssh2_channel_set_blocking(channel, 1);
rc = _libssh2_channel_read_ex(channel, stream_id, buf, buflen);
/* restore state */
_libssh2_channel_set_blocking(channel, bl);
if(rc < 0) {
/* precent accidental returning of other return codes since
this API does not support/provide those */
return -1;
}
return rc;
}
LIBSSH2_API int libssh2_channel_readnb_ex(LIBSSH2_CHANNEL *channel,
int stream_id,
char *buf, size_t buflen)
{
ssize_t rc;
/* set non-blocking */
int bl = _libssh2_channel_set_blocking(channel, 0);
rc = _libssh2_channel_read_ex(channel, stream_id, buf, buflen);
/* restore state */
_libssh2_channel_set_blocking(channel, bl);
return rc;
}
/* {{{ libssh2_channel_write_ex /* {{{ libssh2_channel_write_ex
* Send data to a channel * Send data to a channel
*/ */
LIBSSH2_API int libssh2_channel_write_ex(LIBSSH2_CHANNEL *channel, int stream_id, const char *buf, size_t buflen) int _libssh2_channel_write_ex(LIBSSH2_CHANNEL *channel,
int stream_id,
const char *buf, size_t buflen)
{ {
LIBSSH2_SESSION *session = channel->session; LIBSSH2_SESSION *session = channel->session;
unsigned char *packet; unsigned char *packet;
unsigned long packet_len, bufwrote = 0; unsigned long packet_len, bufwrote = 0;
#ifdef LIBSSH2_DEBUG_CONNECTION
_libssh2_debug(session, LIBSSH2_DBG_CONN, "Writing %d bytes on channel %lu/%lu, stream #%d", (int)buflen, channel->local.id, channel->remote.id, stream_id); _libssh2_debug(session, LIBSSH2_DBG_CONN, "Writing %d bytes on channel %lu/%lu, stream #%d", (int)buflen, channel->local.id, channel->remote.id, stream_id);
#endif
if (channel->local.close) { if (channel->local.close) {
libssh2_error(session, LIBSSH2_ERROR_CHANNEL_CLOSED, "We've already closed this channel", 0); libssh2_error(session, LIBSSH2_ERROR_CHANNEL_CLOSED, "We've already closed this channel", 0);
return -1; return -1;
@@ -980,6 +1235,7 @@ LIBSSH2_API int libssh2_channel_write_ex(LIBSSH2_CHANNEL *channel, int stream_id
while (buflen > 0) { while (buflen > 0) {
size_t bufwrite = buflen; size_t bufwrite = buflen;
unsigned char *s = packet; unsigned char *s = packet;
libssh2pack_t rc;
*(s++) = stream_id ? SSH_MSG_CHANNEL_EXTENDED_DATA : SSH_MSG_CHANNEL_DATA; *(s++) = stream_id ? SSH_MSG_CHANNEL_EXTENDED_DATA : SSH_MSG_CHANNEL_DATA;
libssh2_htonu32(s, channel->remote.id); s += 4; libssh2_htonu32(s, channel->remote.id); s += 4;
@@ -989,34 +1245,36 @@ LIBSSH2_API int libssh2_channel_write_ex(LIBSSH2_CHANNEL *channel, int stream_id
/* twiddle our thumbs until there's window space available */ /* twiddle our thumbs until there's window space available */
while (channel->local.window_size <= 0) { while (channel->local.window_size <= 0) {
/* Don't worry -- This is never hit unless it's a blocking channel anyway */ /* Don't worry -- This is never hit unless it's a
if (libssh2_packet_read(session, 1) < 0) { blocking channel anyway */
/* Error occured, disconnect? */ rc = libssh2_packet_read(session);
return -1;
if (rc < 0) {
/* Error or EAGAIN occurred, disconnect? */
return rc;
} }
/* FIXME: (dast) if rc == 0 here then this busyloops
like hell until data arrives on the network which
seems like a very bad idea */
} }
/* Don't exceed the remote end's limits */ /* Don't exceed the remote end's limits */
/* REMEMBER local means local as the SOURCE of the data */ /* REMEMBER local means local as the SOURCE of the data */
if (bufwrite > channel->local.window_size) { if (bufwrite > channel->local.window_size) {
#ifdef LIBSSH2_DEBUG_CONNECTION
_libssh2_debug(session, LIBSSH2_DBG_CONN, "Splitting write block due to %lu byte window_size on %lu/%lu/%d", channel->local.window_size, channel->local.id, channel->remote.id, stream_id); _libssh2_debug(session, LIBSSH2_DBG_CONN, "Splitting write block due to %lu byte window_size on %lu/%lu/%d", channel->local.window_size, channel->local.id, channel->remote.id, stream_id);
#endif
bufwrite = channel->local.window_size; bufwrite = channel->local.window_size;
} }
if (bufwrite > channel->local.packet_size) { if (bufwrite > channel->local.packet_size) {
#ifdef LIBSSH2_DEBUG_CONNECTION
_libssh2_debug(session, LIBSSH2_DBG_CONN, "Splitting write block due to %lu byte packet_size on %lu/%lu/%d", channel->local.packet_size, channel->local.id, channel->remote.id, stream_id); _libssh2_debug(session, LIBSSH2_DBG_CONN, "Splitting write block due to %lu byte packet_size on %lu/%lu/%d", channel->local.packet_size, channel->local.id, channel->remote.id, stream_id);
#endif
bufwrite = channel->local.packet_size; bufwrite = channel->local.packet_size;
} }
libssh2_htonu32(s, bufwrite); s += 4; libssh2_htonu32(s, bufwrite); s += 4;
memcpy(s, buf, bufwrite); s += bufwrite; memcpy(s, buf, bufwrite); s += bufwrite;
#ifdef LIBSSH2_DEBUG_CONNECTION
_libssh2_debug(session, LIBSSH2_DBG_CONN, "Sending %d bytes on channel %lu/%lu, stream_id=%d", (int)bufwrite, channel->local.id, channel->remote.id, stream_id); _libssh2_debug(session, LIBSSH2_DBG_CONN, "Sending %d bytes on channel %lu/%lu, stream_id=%d", (int)bufwrite, channel->local.id, channel->remote.id, stream_id);
#endif rc = libssh2_packet_write(session, packet, s - packet);
if (libssh2_packet_write(session, packet, s - packet)) { if(rc) {
libssh2_error(session, LIBSSH2_ERROR_SOCKET_SEND, "Unable to send channel data", 0); libssh2_error(session, LIBSSH2_ERROR_SOCKET_SEND, "Unable to send channel data", 0);
LIBSSH2_FREE(session, packet); LIBSSH2_FREE(session, packet);
return -1; return -1;
@@ -1040,6 +1298,50 @@ LIBSSH2_API int libssh2_channel_write_ex(LIBSSH2_CHANNEL *channel, int stream_id
} }
/* }}} */ /* }}} */
/* {{{ libssh2_channel_write_ex
* Send data to a channel blocking
*/
LIBSSH2_API int libssh2_channel_write_ex(LIBSSH2_CHANNEL *channel,
int stream_id,
const char *buf, size_t buflen)
{
ssize_t rc;
/* set blocking */
int bl = _libssh2_channel_set_blocking(channel, 1);
rc = _libssh2_channel_write_ex(channel, stream_id, buf, buflen);
/* restore state */
_libssh2_channel_set_blocking(channel, bl);
return rc;
}
/* }}} */
/* {{{ libssh2_channel_writenb_ex
* Send data to a channel non-blocking
*/
LIBSSH2_API int libssh2_channel_writenb_ex(LIBSSH2_CHANNEL *channel,
int stream_id,
const char *buf, size_t buflen)
{
ssize_t rc;
int bl;
/* set non-blocking */
bl = _libssh2_channel_set_blocking(channel, 0);
rc = _libssh2_channel_write_ex(channel, stream_id, buf, buflen);
/* restore state */
(void)_libssh2_channel_set_blocking(channel, bl);
return rc;
}
/* }}} */
/* {{{ libssh2_channel_send_eof /* {{{ libssh2_channel_send_eof
* Send EOF on channel * Send EOF on channel
*/ */
@@ -1048,9 +1350,7 @@ LIBSSH2_API int libssh2_channel_send_eof(LIBSSH2_CHANNEL *channel)
LIBSSH2_SESSION *session = channel->session; LIBSSH2_SESSION *session = channel->session;
unsigned char packet[5]; /* packet_type(1) + channelno(4) */ unsigned char packet[5]; /* packet_type(1) + channelno(4) */
#ifdef LIBSSH2_DEBUG_CONNECTION
_libssh2_debug(session, LIBSSH2_DBG_CONN, "Sending EOF on channel %lu/%lu",channel->local.id, channel->remote.id); _libssh2_debug(session, LIBSSH2_DBG_CONN, "Sending EOF on channel %lu/%lu",channel->local.id, channel->remote.id);
#endif
packet[0] = SSH_MSG_CHANNEL_EOF; packet[0] = SSH_MSG_CHANNEL_EOF;
libssh2_htonu32(packet + 1, channel->remote.id); libssh2_htonu32(packet + 1, channel->remote.id);
if (libssh2_packet_write(session, packet, 5)) { if (libssh2_packet_write(session, packet, 5)) {
@@ -1091,19 +1391,19 @@ LIBSSH2_API int libssh2_channel_close(LIBSSH2_CHANNEL *channel)
{ {
LIBSSH2_SESSION *session = channel->session; LIBSSH2_SESSION *session = channel->session;
unsigned char packet[5]; unsigned char packet[5];
int rc = 0;
if (channel->local.close) { if (channel->local.close) {
/* Already closed, act like we sent another close, even though we didn't... shhhhhh */ /* Already closed, act like we sent another close, even though we didn't... shhhhhh */
return 0; return 0;
} }
#ifdef LIBSSH2_DEBUG_CONNECTION
_libssh2_debug(session, LIBSSH2_DBG_CONN, "Closing channel %lu/%lu", channel->local.id, channel->remote.id); _libssh2_debug(session, LIBSSH2_DBG_CONN, "Closing channel %lu/%lu", channel->local.id, channel->remote.id);
#endif
if (channel->close_cb) { if (channel->close_cb) {
LIBSSH2_CHANNEL_CLOSE(session, channel); LIBSSH2_CHANNEL_CLOSE(session, channel);
} }
channel->local.close = 1;
packet[0] = SSH_MSG_CHANNEL_CLOSE; packet[0] = SSH_MSG_CHANNEL_CLOSE;
libssh2_htonu32(packet + 1, channel->remote.id); libssh2_htonu32(packet + 1, channel->remote.id);
@@ -1111,11 +1411,23 @@ LIBSSH2_API int libssh2_channel_close(LIBSSH2_CHANNEL *channel)
libssh2_error(session, LIBSSH2_ERROR_SOCKET_SEND, "Unable to send close-channel request", 0); libssh2_error(session, LIBSSH2_ERROR_SOCKET_SEND, "Unable to send close-channel request", 0);
return -1; return -1;
} }
channel->local.close = 1;
/* TODO: Wait up to a timeout value for a CHANNEL_CLOSE to come back, to avoid the problem alluded to in channel_nextid */ /* We must wait for the remote SSH_MSG_CHANNEL_CLOSE message */
if (!channel->remote.close) {
libssh2pack_t ret;
/* set blocking mode */
int bl = _libssh2_channel_set_blocking(channel, 1);
do {
ret = libssh2_packet_read(session);
if ((ret < 0) && (ret != PACKET_EAGAIN)) {
rc = -1;
}
} while (ret != SSH_MSG_CHANNEL_CLOSE && rc == 0);
return 0; _libssh2_channel_set_blocking(channel, bl);
}
return rc;
} }
/* }}} */ /* }}} */
@@ -1131,16 +1443,14 @@ LIBSSH2_API int libssh2_channel_wait_closed(LIBSSH2_CHANNEL *channel)
return -1; return -1;
} }
#ifdef LIBSSH2_DEBUG_CONNECTION
_libssh2_debug(session, LIBSSH2_DBG_CONN, "Awaiting close of channel %lu/%lu", channel->local.id, channel->remote.id); _libssh2_debug(session, LIBSSH2_DBG_CONN, "Awaiting close of channel %lu/%lu", channel->local.id, channel->remote.id);
#endif
/* while channel is not closed, read more /* while channel is not closed, read more
* packets from the network. * packets from the network.
* Either or channel will be closed * Either or channel will be closed
* or network timeout will occur * or network timeout will occur
*/ */
while (!channel->remote.close && libssh2_packet_read(session, 1) > 0) while (!channel->remote.close && libssh2_packet_read(session) > 0)
; ;
return 1; return 1;
@@ -1157,9 +1467,7 @@ LIBSSH2_API int libssh2_channel_free(LIBSSH2_CHANNEL *channel)
unsigned char channel_id[4], *data; unsigned char channel_id[4], *data;
unsigned long data_len; unsigned long data_len;
#ifdef LIBSSH2_DEBUG_CONNECTION
_libssh2_debug(session, LIBSSH2_DBG_CONN, "Freeing channel %lu/%lu resources", channel->local.id, channel->remote.id); _libssh2_debug(session, LIBSSH2_DBG_CONN, "Freeing channel %lu/%lu resources", channel->local.id, channel->remote.id);
#endif
/* Allow channel freeing even when the socket has lost its connection */ /* Allow channel freeing even when the socket has lost its connection */
if (!channel->local.close && (session->socket_state == LIBSSH2_SOCKET_CONNECTED) && if (!channel->local.close && (session->socket_state == LIBSSH2_SOCKET_CONNECTED) &&
libssh2_channel_close(channel)) { libssh2_channel_close(channel)) {
@@ -1173,8 +1481,8 @@ LIBSSH2_API int libssh2_channel_free(LIBSSH2_CHANNEL *channel)
/* Clear out packets meant for this channel */ /* Clear out packets meant for this channel */
libssh2_htonu32(channel_id, channel->local.id); libssh2_htonu32(channel_id, channel->local.id);
while ((libssh2_packet_ask_ex(session, SSH_MSG_CHANNEL_DATA, &data, &data_len, 1, channel_id, 4, 1) >= 0) || while ((libssh2_packet_ask_ex(session, SSH_MSG_CHANNEL_DATA, &data, &data_len, 1, channel_id, 4, 0) >= 0) ||
(libssh2_packet_ask_ex(session, SSH_MSG_CHANNEL_EXTENDED_DATA, &data, &data_len, 1, channel_id, 4, 1) >= 0)) { (libssh2_packet_ask_ex(session, SSH_MSG_CHANNEL_EXTENDED_DATA, &data, &data_len, 1, channel_id, 4, 0) >= 0)) {
LIBSSH2_FREE(session, data); LIBSSH2_FREE(session, data);
} }

View File

@@ -1,4 +1,4 @@
/* Copyright (c) 2004-2005, Sara Golemon <sarag@libssh2.org> /* Copyright (c) 2004-2007, Sara Golemon <sarag@libssh2.org>
* All rights reserved. * All rights reserved.
* *
* Redistribution and use in source and binary forms, * Redistribution and use in source and binary forms,
@@ -36,7 +36,9 @@
*/ */
#include "libssh2_priv.h" #include "libssh2_priv.h"
#include <zlib.h> #ifdef LIBSSH2_HAVE_ZLIB
# include <zlib.h>
#endif
/* ******** /* ********
* none * * none *
@@ -45,10 +47,20 @@
/* {{{ 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, int compress, static int libssh2_comp_method_none_comp(LIBSSH2_SESSION *session,
unsigned char **dest, unsigned long *dest_len, unsigned long payload_limit, int *free_dest, int compress,
const unsigned char *src, unsigned long src_len, void **abstract) unsigned char **dest,
unsigned long *dest_len,
unsigned long payload_limit,
int *free_dest,
const unsigned char *src,
unsigned long src_len,
void **abstract)
{ {
(void)session;
(void)compress;
(void)payload_limit;
(void)abstract;
*dest = (unsigned char *)src; *dest = (unsigned char *)src;
*dest_len = src_len; *dest_len = src_len;
@@ -58,7 +70,7 @@ static int libssh2_comp_method_none_comp(LIBSSH2_SESSION *session, int compress,
} }
/* }}} */ /* }}} */
static LIBSSH2_COMP_METHOD libssh2_comp_method_none = { static const LIBSSH2_COMP_METHOD libssh2_comp_method_none = {
"none", "none",
NULL, NULL,
libssh2_comp_method_none_comp, libssh2_comp_method_none_comp,
@@ -129,12 +141,19 @@ static int libssh2_comp_method_zlib_init(LIBSSH2_SESSION *session, int compress,
/* {{{ 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, int compress, static int libssh2_comp_method_zlib_comp(LIBSSH2_SESSION *session,
unsigned char **dest, unsigned long *dest_len, unsigned long payload_limit, int *free_dest, int compress,
const unsigned char *src, unsigned long src_len, void **abstract) unsigned char **dest,
unsigned long *dest_len,
unsigned long payload_limit,
int *free_dest,
const unsigned char *src,
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 reallocs */ /* A short-term alloc of a full data chunk is better than a series of
reallocs */
char *out; char *out;
int out_maxlen = compress ? (src_len + 4) : (2 * src_len); int out_maxlen = compress ? (src_len + 4) : (2 * src_len);
int limiter = 0; int limiter = 0;
@@ -144,13 +163,14 @@ static int libssh2_comp_method_zlib_comp(LIBSSH2_SESSION *session, int compress,
out_maxlen = 25; out_maxlen = 25;
} }
if (out_maxlen > payload_limit) { if (out_maxlen > (int)payload_limit) {
out_maxlen = payload_limit; out_maxlen = payload_limit;
} }
strm->next_in = (char *)src; strm->next_in = (unsigned char *)src;
strm->avail_in = src_len; strm->avail_in = src_len;
out = strm->next_out = LIBSSH2_ALLOC(session, out_maxlen); strm->next_out = (unsigned char *)LIBSSH2_ALLOC(session, out_maxlen);
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);
@@ -171,47 +191,56 @@ static int libssh2_comp_method_zlib_comp(LIBSSH2_SESSION *session, int compress,
} }
if (strm->avail_in) { if (strm->avail_in) {
unsigned long out_ofs = out_maxlen - strm->avail_out; unsigned long out_ofs = out_maxlen - strm->avail_out;
char *newout;
out_maxlen += compress ? (strm->avail_in + 4) : (2 * strm->avail_in); out_maxlen += compress ? (strm->avail_in + 4) : (2 * strm->avail_in);
if ((out_maxlen > payload_limit) && !compress && limiter++) { if ((out_maxlen > (int)payload_limit) &&
libssh2_error(session, LIBSSH2_ERROR_ZLIB, "Excessive growth in decompression phase", 0); !compress && limiter++) {
libssh2_error(session, LIBSSH2_ERROR_ZLIB,
"Excessive growth in decompression phase", 0);
LIBSSH2_FREE(session, out); LIBSSH2_FREE(session, out);
return -1; return -1;
} }
out = LIBSSH2_REALLOC(session, out, out_maxlen); newout = LIBSSH2_REALLOC(session, out, out_maxlen);
if (!out) { if (!newout) {
libssh2_error(session, LIBSSH2_ERROR_ALLOC, "Unable to expand compress/decompression buffer", 0); libssh2_error(session, LIBSSH2_ERROR_ALLOC, "Unable to expand compress/decompression buffer", 0);
LIBSSH2_FREE(session, out);
return -1; return -1;
} }
strm->next_out = out + out_ofs; out = newout;
strm->next_out = (unsigned char *)out + out_ofs;
strm->avail_out += compress ? (strm->avail_in + 4) : (2 * strm->avail_in); strm->avail_out += compress ? (strm->avail_in + 4) : (2 * strm->avail_in);
} else while (!strm->avail_out) { } else while (!strm->avail_out) {
/* Done with input, might be a byte or two in internal buffer during compress /* Done with input, might be a byte or two in internal buffer during compress
* Or potentially many bytes if it's a decompress * Or potentially many bytes if it's a decompress
*/ */
int grow_size = compress ? 8 : 1024; int grow_size = compress ? 8 : 1024;
char *newout;
if (out_maxlen >= 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, "Excessive growth in decompression phase", 0);
LIBSSH2_FREE(session, out); LIBSSH2_FREE(session, out);
return -1; return -1;
} }
if (grow_size > (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;
out = LIBSSH2_REALLOC(session, out, out_maxlen); newout = LIBSSH2_REALLOC(session, out, out_maxlen);
if (!out) { if (!newout) {
libssh2_error(session, LIBSSH2_ERROR_ALLOC, "Unable to expand final compress/decompress buffer", 0); libssh2_error(session, LIBSSH2_ERROR_ALLOC, "Unable to expand final compress/decompress buffer", 0);
LIBSSH2_FREE(session, out);
return -1; return -1;
} }
strm->next_out = 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);
@@ -226,7 +255,7 @@ static int libssh2_comp_method_zlib_comp(LIBSSH2_SESSION *session, int compress,
} }
} }
*dest = 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;
@@ -259,7 +288,7 @@ static int libssh2_comp_method_zlib_dtor(LIBSSH2_SESSION *session, int compress,
} }
/* }}} */ /* }}} */
static LIBSSH2_COMP_METHOD libssh2_comp_method_zlib = { static const LIBSSH2_COMP_METHOD libssh2_comp_method_zlib = {
"zlib", "zlib",
libssh2_comp_method_zlib_init, libssh2_comp_method_zlib_init,
libssh2_comp_method_zlib_comp, libssh2_comp_method_zlib_comp,
@@ -271,7 +300,7 @@ static LIBSSH2_COMP_METHOD libssh2_comp_method_zlib = {
* Compression Methods * * Compression Methods *
*********************** */ *********************** */
static LIBSSH2_COMP_METHOD *_libssh2_comp_methods[] = { static const LIBSSH2_COMP_METHOD *_libssh2_comp_methods[] = {
&libssh2_comp_method_none, &libssh2_comp_method_none,
#ifdef LIBSSH2_HAVE_ZLIB #ifdef LIBSSH2_HAVE_ZLIB
&libssh2_comp_method_zlib, &libssh2_comp_method_zlib,
@@ -279,7 +308,7 @@ static LIBSSH2_COMP_METHOD *_libssh2_comp_methods[] = {
NULL NULL
}; };
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

@@ -1,4 +1,4 @@
/* Copyright (c) 2004-2005, Sara Golemon <sarag@libssh2.org> /* Copyright (c) 2004-2007, Sara Golemon <sarag@libssh2.org>
* All rights reserved. * All rights reserved.
* *
* Redistribution and use in source and binary forms, * Redistribution and use in source and binary forms,
@@ -36,7 +36,6 @@
*/ */
#include "libssh2_priv.h" #include "libssh2_priv.h"
#include <openssl/evp.h>
#ifdef LIBSSH2_CRYPT_NONE #ifdef LIBSSH2_CRYPT_NONE
/* {{{ libssh2_crypt_none_crypt /* {{{ libssh2_crypt_none_crypt
@@ -49,7 +48,7 @@ static int libssh2_crypt_none_crypt(LIBSSH2_SESSION *session, unsigned char *buf
} }
/* }}} */ /* }}} */
static 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 */
@@ -59,124 +58,183 @@ static LIBSSH2_CRYPT_METHOD libssh2_crypt_method_none = {
libssh2_crypt_none_crypt, libssh2_crypt_none_crypt,
NULL NULL
}; };
#endif #endif /* LIBSSH2_CRYPT_NONE */
static LIBSSH2_CRYPT_METHOD libssh2_crypt_method_3des_cbc = { struct crypt_ctx {
"3des-cbc", int encrypt;
8, /* blocksize */ _libssh2_cipher_type(algo);
8, /* initial value length */ _libssh2_cipher_ctx h;
24, /* secret length */
LIBSSH2_CRYPT_METHOD_FLAG_EVP,
NULL,
(void*)EVP_des_ede3_cbc,
NULL,
}; };
#if OPENSSL_VERSION_NUMBER >= 0x00907000L && !defined(OPENSSL_NO_AES) static int _libssh2_init (LIBSSH2_SESSION *session,
static LIBSSH2_CRYPT_METHOD libssh2_crypt_method_aes128_cbc = { const LIBSSH2_CRYPT_METHOD *method,
unsigned char *iv, int *free_iv,
unsigned char *secret, int *free_secret,
int encrypt, void **abstract)
{
struct crypt_ctx *ctx = LIBSSH2_ALLOC(session,
sizeof(struct crypt_ctx));
if (!ctx) {
return -1;
}
ctx->encrypt = encrypt;
ctx->algo = method->algo;
if (_libssh2_cipher_init (&ctx->h, ctx->algo, iv, secret, encrypt))
{
LIBSSH2_FREE (session, ctx);
return -1;
}
*abstract = ctx;
*free_iv = 1;
*free_secret = 1;
return 0;
}
static int _libssh2_encrypt(LIBSSH2_SESSION *session, unsigned char *block, void **abstract)
{
struct crypt_ctx *cctx = *(struct crypt_ctx **)abstract;
(void)session;
return _libssh2_cipher_crypt(&cctx->h, cctx->algo,
cctx->encrypt, block);
}
static int _libssh2_dtor(LIBSSH2_SESSION *session, void **abstract)
{
struct crypt_ctx **cctx = (struct crypt_ctx **)abstract;
if (cctx && *cctx) {
_libssh2_cipher_dtor(&(*cctx)->h);
LIBSSH2_FREE(session, *cctx);
*abstract = NULL;
}
return 0;
}
#if LIBSSH2_AES
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 */
LIBSSH2_CRYPT_METHOD_FLAG_EVP, 0, /* flags */
NULL, &_libssh2_init,
(void*)EVP_aes_128_cbc, &_libssh2_encrypt,
NULL, &_libssh2_dtor,
_libssh2_cipher_aes128
}; };
static 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 */
LIBSSH2_CRYPT_METHOD_FLAG_EVP, 0, /* flags */
NULL, &_libssh2_init,
(void*)EVP_aes_192_cbc, &_libssh2_encrypt,
NULL, &_libssh2_dtor,
_libssh2_cipher_aes192
}; };
static 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 */
LIBSSH2_CRYPT_METHOD_FLAG_EVP, 0, /* flags */
NULL, &_libssh2_init,
(void*)EVP_aes_256_cbc, &_libssh2_encrypt,
NULL, &_libssh2_dtor,
_libssh2_cipher_aes256
}; };
/* rijndael-cbc@lysator.liu.se == aes256-cbc */ /* rijndael-cbc@lysator.liu.se == aes256-cbc */
static 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 */
LIBSSH2_CRYPT_METHOD_FLAG_EVP, 0, /* flags */
NULL, &_libssh2_init,
(void*)EVP_aes_256_cbc, &_libssh2_encrypt,
NULL, &_libssh2_dtor,
_libssh2_cipher_aes256
}; };
#endif /* OPENSSL_VERSION_NUMBER >= 0x00907000L && !defined(OPENSSL_NO_AES)*/ #endif /* LIBSSH2_AES */
#ifndef OPENSSL_NO_BLOWFISH #if LIBSSH2_BLOWFISH
static 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 */
LIBSSH2_CRYPT_METHOD_FLAG_EVP, 0, /* flags */
NULL, &_libssh2_init,
(void*)EVP_bf_cbc, &_libssh2_encrypt,
NULL, &_libssh2_dtor,
_libssh2_cipher_blowfish
}; };
#endif /* ! OPENSSL_NO_BLOWFISH */ #endif /* LIBSSH2_BLOWFISH */
#ifndef OPENSSL_NO_CAST #if LIBSSH2_RC4
static LIBSSH2_CRYPT_METHOD libssh2_crypt_method_cast128_cbc = { static const LIBSSH2_CRYPT_METHOD libssh2_crypt_method_arcfour = {
"cast128-cbc",
8, /* blocksize */
8, /* initial value length */
16, /* secret length */
LIBSSH2_CRYPT_METHOD_FLAG_EVP,
NULL,
(void*)EVP_cast5_cbc,
NULL,
};
#endif /* ! OPENSSL_NO_CAST */
#ifndef OPENSSL_NO_RC4
static 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 */
LIBSSH2_CRYPT_METHOD_FLAG_EVP, 0, /* flags */
NULL, &_libssh2_init,
(void*)EVP_rc4, &_libssh2_encrypt,
NULL, &_libssh2_dtor,
_libssh2_cipher_arcfour
}; };
#endif /* ! OPENSSL_NO_RC4 */ #endif /* LIBSSH2_RC4 */
static LIBSSH2_CRYPT_METHOD *_libssh2_crypt_methods[] = { #if LIBSSH2_CAST
#if OPENSSL_VERSION_NUMBER >= 0x00907000L && !defined(OPENSSL_NO_AES) static const LIBSSH2_CRYPT_METHOD libssh2_crypt_method_cast128_cbc = {
"cast128-cbc",
8, /* blocksize */
8, /* initial value length */
16, /* secret length */
0, /* flags */
&_libssh2_init,
&_libssh2_encrypt,
&_libssh2_dtor,
_libssh2_cipher_cast5
};
#endif /* LIBSSH2_CAST */
#if LIBSSH2_3DES
static const LIBSSH2_CRYPT_METHOD libssh2_crypt_method_3des_cbc = {
"3des-cbc",
8, /* blocksize */
8, /* initial value length */
24, /* secret length */
0, /* flags */
&_libssh2_init,
&_libssh2_encrypt,
&_libssh2_dtor,
_libssh2_cipher_3des
};
#endif
static const LIBSSH2_CRYPT_METHOD *_libssh2_crypt_methods[] = {
#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 /* OPENSSL_VERSION_NUMBER >= 0x00907000L && !defined(OPENSSL_NO_AES) */ #endif /* LIBSSH2_AES */
#ifndef OPENSSL_NO_BLOWFISH #if LIBSSH2_BLOWFISH
&libssh2_crypt_method_blowfish_cbc, &libssh2_crypt_method_blowfish_cbc,
#endif /* ! OPENSSL_NO_BLOWFISH */ #endif /* LIBSSH2_BLOWFISH */
#ifndef OPENSSL_NO_RC4 #if LIBSSH2_RC4
&libssh2_crypt_method_arcfour, &libssh2_crypt_method_arcfour,
#endif /* ! OPENSSL_NO_RC4 */ #endif /* LIBSSH2_RC4 */
#ifndef OPENSSL_NO_CAST #if LIBSSH2_CAST
&libssh2_crypt_method_cast128_cbc, &libssh2_crypt_method_cast128_cbc,
#endif /* ! OPENSSL_NO_CAST */ #endif /* LIBSSH2_CAST */
#ifndef OPENSSL_NO_DES #if LIBSSH2_3DES
&libssh2_crypt_method_3des_cbc, &libssh2_crypt_method_3des_cbc,
#endif /* ! OPENSSL_NO_DES */ #endif /* LIBSSH2_DES */
#ifdef LIBSSH2_CRYPT_NONE #ifdef LIBSSH2_CRYPT_NONE
&libssh2_crypt_method_none, &libssh2_crypt_method_none,
#endif #endif
@@ -184,6 +242,6 @@ static LIBSSH2_CRYPT_METHOD *_libssh2_crypt_methods[] = {
}; };
/* Expose to kex.c */ /* Expose to kex.c */
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

@@ -1,4 +1,4 @@
/* Copyright (c) 2004-2005, Sara Golemon <sarag@libssh2.org> /* Copyright (c) 2004-2006, Sara Golemon <sarag@libssh2.org>
* All rights reserved. * All rights reserved.
* *
* Redistribution and use in source and binary forms, * Redistribution and use in source and binary forms,
@@ -36,16 +36,13 @@
*/ */
#include "libssh2_priv.h" #include "libssh2_priv.h"
#include <openssl/bn.h>
#include <openssl/pem.h>
#include <openssl/evp.h>
/* Needed for struct iovec on some platforms */ /* Needed for struct iovec on some platforms */
#ifdef HAVE_SYS_UIO_H #ifdef HAVE_SYS_UIO_H
#include <sys/uio.h> #include <sys/uio.h>
#endif #endif
#ifndef OPENSSL_NO_RSA #if LIBSSH2_RSA
/* *********** /* ***********
* ssh-rsa * * ssh-rsa *
*********** */ *********** */
@@ -55,33 +52,42 @@ static int libssh2_hostkey_method_ssh_rsa_dtor(LIBSSH2_SESSION *session, void **
/* {{{ 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 libssh2_hostkey_method_ssh_rsa_init(LIBSSH2_SESSION *session, unsigned char *hostkey_data, unsigned long hostkey_data_len, void **abstract) static int
libssh2_hostkey_method_ssh_rsa_init(LIBSSH2_SESSION *session,
const unsigned char *hostkey_data,
unsigned long hostkey_data_len,
void **abstract)
{ {
RSA *rsactx; libssh2_rsa_ctx *rsactx;
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;
if (*abstract) { if (*abstract) {
libssh2_hostkey_method_ssh_rsa_dtor(session, abstract); libssh2_hostkey_method_ssh_rsa_dtor(session, abstract);
*abstract = NULL; *abstract = NULL;
} }
s = hostkey_data; s = hostkey_data;
len = libssh2_ntohu32(s); s += 4; len = libssh2_ntohu32(s);
if (len != 7 || strncmp(s, "ssh-rsa", 7) != 0) { s += 4;
return -1;
} s += 7; if (len != 7 || strncmp((char *)s, "ssh-rsa", 7) != 0) {
return -1;
}
s += 7;
e_len = libssh2_ntohu32(s);
s += 4;
e_len = libssh2_ntohu32(s); s += 4;
e = s; s += e_len; e = s; s += e_len;
n_len = libssh2_ntohu32(s); s += 4; n_len = libssh2_ntohu32(s); s += 4;
n = s; s += n_len; n = s; s += n_len;
rsactx = RSA_new(); if (_libssh2_rsa_new (&rsactx, e, e_len, n, n_len, NULL, 0,
rsactx->e = BN_new(); NULL, 0, NULL, 0, NULL, 0, NULL, 0, NULL, 0))
BN_bin2bn(e, e_len, rsactx->e); return -1;
rsactx->n = BN_new();
BN_bin2bn(n, n_len, rsactx->n);
*abstract = rsactx; *abstract = rsactx;
@@ -89,30 +95,15 @@ static int libssh2_hostkey_method_ssh_rsa_init(LIBSSH2_SESSION *session, unsigne
} }
/* }}} */ /* }}} */
/* {{{ libssh2_hostkey_method_ssh_rsa_passphrase_cb
* TODO: Optionally call a passphrase callback specified by the calling program
*/
static int libssh2_hostkey_method_ssh_rsadsa_passphrase_cb(char *buf, int size, int rwflag, char *passphrase)
{
int passphrase_len = strlen(passphrase);
if (passphrase_len > (size - 1)) {
passphrase_len = size - 1;
}
memcpy(buf, passphrase, passphrase_len);
buf[passphrase_len] = '\0';
return passphrase_len;
}
/* }}} */
/* {{{ 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, unsigned const char *privkeyfile, unsigned const char *passphrase, void **abstract) static int libssh2_hostkey_method_ssh_rsa_initPEM(LIBSSH2_SESSION *session,
const char *privkeyfile, unsigned const char *passphrase, void **abstract)
{ {
RSA *rsactx; libssh2_rsa_ctx *rsactx;
FILE *fp; FILE *fp;
int ret;
if (*abstract) { if (*abstract) {
libssh2_hostkey_method_ssh_rsa_dtor(session, abstract); libssh2_hostkey_method_ssh_rsa_dtor(session, abstract);
@@ -124,19 +115,11 @@ static int libssh2_hostkey_method_ssh_rsa_initPEM(LIBSSH2_SESSION *session, unsi
return -1; return -1;
} }
if (!EVP_get_cipherbyname("des")) { ret = _libssh2_rsa_new_private (&rsactx, session, fp, passphrase);
/* 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 ($#&%#$(%$#(
* Someone buy me an OpenSSL manual and I'll read up on it.
*/
OpenSSL_add_all_ciphers();
}
rsactx = PEM_read_RSAPrivateKey(fp, NULL, (void*)libssh2_hostkey_method_ssh_rsadsa_passphrase_cb, (void*)passphrase);
if (!rsactx) {
fclose(fp); fclose(fp);
if (ret) {
return -1; return -1;
} }
fclose(fp);
*abstract = rsactx; *abstract = rsactx;
@@ -147,56 +130,19 @@ static int libssh2_hostkey_method_ssh_rsa_initPEM(LIBSSH2_SESSION *session, unsi
/* {{{ 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, const unsigned char *sig, unsigned long sig_len, static int libssh2_hostkey_method_ssh_rsa_sig_verify(LIBSSH2_SESSION *session,
const unsigned char *m, unsigned long m_len, void **abstract) const unsigned char *sig,
unsigned long sig_len,
const unsigned char *m,
unsigned long m_len,
void **abstract)
{ {
RSA *rsactx = (RSA*)(*abstract); libssh2_rsa_ctx *rsactx = (libssh2_rsa_ctx*)(*abstract);
unsigned char hash[SHA_DIGEST_LENGTH]; (void)session;
int ret;
/* 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; sig_len -= 15;
SHA1(m, m_len, hash); return _libssh2_rsa_sha1_verify (rsactx, sig, sig_len, m, m_len);
ret = RSA_verify(NID_sha1, hash, SHA_DIGEST_LENGTH, (char *)sig, sig_len, rsactx);
return (ret == 1) ? 0 : -1;
}
/* }}} */
/* {{{ libssh2_hostkey_method_ssh_rsa_sign
* Sign data to send to remote
*/
static int libssh2_hostkey_method_ssh_rsa_sign(LIBSSH2_SESSION *session, unsigned char **signature, unsigned long *signature_len,
const unsigned char *buf, unsigned long buf_len, void **abstract)
{
RSA *rsactx = (RSA*)(*abstract);
int ret;
unsigned char hash[SHA_DIGEST_LENGTH];
SHA_CTX ctx;
char *sig;
int sig_len;
sig_len = RSA_size(rsactx);
sig = LIBSSH2_ALLOC(session, sig_len);
if (!sig) {
return -1;
}
SHA1_Init(&ctx);
SHA1_Update(&ctx, buf, buf_len);
SHA1_Final(hash, &ctx);
ret = RSA_sign(NID_sha1, hash, SHA_DIGEST_LENGTH, sig, &sig_len, rsactx);
if (!ret) {
LIBSSH2_FREE(session, sig);
return -1;
}
*signature = sig;
*signature_len = sig_len;
return 0;
} }
/* }}} */ /* }}} */
@@ -206,36 +152,24 @@ static int libssh2_hostkey_method_ssh_rsa_sign(LIBSSH2_SESSION *session, unsigne
static int libssh2_hostkey_method_ssh_rsa_signv(LIBSSH2_SESSION *session, unsigned char **signature, unsigned long *signature_len, static int libssh2_hostkey_method_ssh_rsa_signv(LIBSSH2_SESSION *session, unsigned char **signature, unsigned long *signature_len,
unsigned long veccount, const struct iovec datavec[], void **abstract) unsigned long veccount, const struct iovec datavec[], void **abstract)
{ {
RSA *rsactx = (RSA*)(*abstract); libssh2_rsa_ctx *rsactx = (libssh2_rsa_ctx*)(*abstract);
int ret, i; int ret;
unsigned int i;
unsigned char hash[SHA_DIGEST_LENGTH]; unsigned char hash[SHA_DIGEST_LENGTH];
SHA_CTX ctx; libssh2_sha1_ctx ctx;
char *sig;
int sig_len;
sig_len = RSA_size(rsactx); libssh2_sha1_init(&ctx);
sig = LIBSSH2_ALLOC(session, sig_len);
if (!sig) {
return -1;
}
SHA1_Init(&ctx);
for(i = 0; i < veccount; i++) { for(i = 0; i < veccount; i++) {
SHA1_Update(&ctx, datavec[i].iov_base, datavec[i].iov_len); libssh2_sha1_update(ctx, datavec[i].iov_base, datavec[i].iov_len);
} }
SHA1_Final(hash, &ctx); libssh2_sha1_final(ctx, hash);
ret = RSA_sign(NID_sha1, hash, SHA_DIGEST_LENGTH, sig, &sig_len, rsactx); ret = _libssh2_rsa_sha1_sign(session, rsactx, hash, SHA_DIGEST_LENGTH,
signature, signature_len);
if (!ret) { if (ret) {
LIBSSH2_FREE(session, sig);
return -1; return -1;
} }
*signature = sig;
*signature_len = sig_len;
return 0; return 0;
} }
/* }}} */ /* }}} */
@@ -243,11 +177,13 @@ static int libssh2_hostkey_method_ssh_rsa_signv(LIBSSH2_SESSION *session, unsign
/* {{{ 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, void **abstract) static int libssh2_hostkey_method_ssh_rsa_dtor(LIBSSH2_SESSION *session,
void **abstract)
{ {
RSA *rsactx = (RSA*)(*abstract); libssh2_rsa_ctx *rsactx = (libssh2_rsa_ctx*)(*abstract);
(void)session;
RSA_free(rsactx); _libssh2_rsa_free(rsactx);
*abstract = NULL; *abstract = NULL;
@@ -255,20 +191,19 @@ static int libssh2_hostkey_method_ssh_rsa_dtor(LIBSSH2_SESSION *session, void **
} }
/* }}} */ /* }}} */
static LIBSSH2_HOSTKEY_METHOD libssh2_hostkey_method_ssh_rsa = { static const LIBSSH2_HOSTKEY_METHOD libssh2_hostkey_method_ssh_rsa = {
"ssh-rsa", "ssh-rsa",
MD5_DIGEST_LENGTH, MD5_DIGEST_LENGTH,
libssh2_hostkey_method_ssh_rsa_init, libssh2_hostkey_method_ssh_rsa_init,
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_sign,
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 /* ! OPENSSL_NO_RSA */ #endif /* LIBSSH2_RSA */
#ifndef OPENSSL_NO_DSA #if LIBSSH2_DSA
/* *********** /* ***********
* ssh-dss * * ssh-dss *
*********** */ *********** */
@@ -278,11 +213,16 @@ static int libssh2_hostkey_method_ssh_dss_dtor(LIBSSH2_SESSION *session, void **
/* {{{ 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 libssh2_hostkey_method_ssh_dss_init(LIBSSH2_SESSION *session, unsigned char *hostkey_data, unsigned long hostkey_data_len, void **abstract) static int
libssh2_hostkey_method_ssh_dss_init(LIBSSH2_SESSION *session,
const unsigned char *hostkey_data,
unsigned long hostkey_data_len,
void **abstract)
{ {
DSA *dsactx; libssh2_dsa_ctx *dsactx;
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;
if (*abstract) { if (*abstract) {
libssh2_hostkey_method_ssh_dss_dtor(session, abstract); libssh2_hostkey_method_ssh_dss_dtor(session, abstract);
@@ -291,7 +231,7 @@ static int libssh2_hostkey_method_ssh_dss_init(LIBSSH2_SESSION *session, unsigne
s = hostkey_data; s = hostkey_data;
len = libssh2_ntohu32(s); s += 4; len = libssh2_ntohu32(s); s += 4;
if (len != 7 || strncmp(s, "ssh-dss", 7) != 0) { if (len != 7 || strncmp((char *)s, "ssh-dss", 7) != 0) {
return -1; return -1;
} s += 7; } s += 7;
@@ -304,15 +244,8 @@ static int libssh2_hostkey_method_ssh_dss_init(LIBSSH2_SESSION *session, unsigne
y_len = libssh2_ntohu32(s); s += 4; y_len = libssh2_ntohu32(s); s += 4;
y = s; s += y_len; y = s; s += y_len;
dsactx = DSA_new(); _libssh2_dsa_new(&dsactx, p, p_len, q, q_len, g, g_len,
dsactx->p = BN_new(); y, y_len, NULL, 0);
BN_bin2bn(p, p_len, dsactx->p);
dsactx->q = BN_new();
BN_bin2bn(q, q_len, dsactx->q);
dsactx->g = BN_new();
BN_bin2bn(g, g_len, dsactx->g);
dsactx->pub_key = BN_new();
BN_bin2bn(y, y_len, dsactx->pub_key);
*abstract = dsactx; *abstract = dsactx;
@@ -323,10 +256,14 @@ static int libssh2_hostkey_method_ssh_dss_init(LIBSSH2_SESSION *session, unsigne
/* {{{ 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, unsigned const char *privkeyfile, unsigned const char *passphrase, void **abstract) static int libssh2_hostkey_method_ssh_dss_initPEM(LIBSSH2_SESSION *session,
const char *privkeyfile,
unsigned const char *passphrase,
void **abstract)
{ {
DSA *dsactx; libssh2_dsa_ctx *dsactx;
FILE *fp; FILE *fp;
int ret;
if (*abstract) { if (*abstract) {
libssh2_hostkey_method_ssh_dss_dtor(session, abstract); libssh2_hostkey_method_ssh_dss_dtor(session, abstract);
@@ -338,19 +275,11 @@ static int libssh2_hostkey_method_ssh_dss_initPEM(LIBSSH2_SESSION *session, unsi
return -1; return -1;
} }
if (!EVP_get_cipherbyname("des")) { ret = _libssh2_dsa_new_private (&dsactx, session, fp, passphrase);
/* 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 ($#&%#$(%$#(
* Someone buy me an OpenSSL manual and I'll read up on it.
*/
OpenSSL_add_all_ciphers();
}
dsactx = PEM_read_DSAPrivateKey(fp, NULL, (void*)libssh2_hostkey_method_ssh_rsadsa_passphrase_cb, (void*)passphrase);
if (!dsactx) {
fclose(fp); fclose(fp);
if (ret) {
return -1; return -1;
} }
fclose(fp);
*abstract = dsactx; *abstract = dsactx;
@@ -364,10 +293,7 @@ static int libssh2_hostkey_method_ssh_dss_initPEM(LIBSSH2_SESSION *session, unsi
static int libssh2_hostkey_method_ssh_dss_sig_verify(LIBSSH2_SESSION *session, const unsigned char *sig, unsigned long sig_len, static int libssh2_hostkey_method_ssh_dss_sig_verify(LIBSSH2_SESSION *session, const unsigned char *sig, unsigned long sig_len,
const unsigned char *m, unsigned long m_len, void **abstract) const unsigned char *m, unsigned long m_len, void **abstract)
{ {
DSA *dsactx = (DSA*)(*abstract); libssh2_dsa_ctx *dsactx = (libssh2_dsa_ctx*)(*abstract);
unsigned char hash[SHA_DIGEST_LENGTH];
DSA_SIG dsasig;
int ret;
/* 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;
@@ -375,52 +301,7 @@ static int libssh2_hostkey_method_ssh_dss_sig_verify(LIBSSH2_SESSION *session, c
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;
} }
dsasig.r = BN_new(); return _libssh2_dsa_sha1_verify(dsactx, sig, m, m_len);
BN_bin2bn(sig, 20, dsasig.r);
dsasig.s = BN_new();
BN_bin2bn(sig + 20, 20, dsasig.s);
SHA1(m, m_len, hash);
ret = DSA_do_verify(hash, SHA_DIGEST_LENGTH, &dsasig, dsactx);
return (ret == 1) ? 0 : -1;
}
/* }}} */
/* {{{ libssh2_hostkey_method_ssh_dss_sign
* Sign data to send to remote
*/
static int libssh2_hostkey_method_ssh_dss_sign(LIBSSH2_SESSION *session, unsigned char **signature, unsigned long *signature_len,
const unsigned char *buf, unsigned long buf_len, void **abstract)
{
DSA *dsactx = (DSA*)(*abstract);
DSA_SIG *sig;
unsigned char hash[SHA_DIGEST_LENGTH];
SHA_CTX ctx;
*signature = LIBSSH2_ALLOC(session, 2 * SHA_DIGEST_LENGTH);
*signature_len = 2 * SHA_DIGEST_LENGTH;
if (!(*signature)) {
return -1;
}
SHA1_Init(&ctx);
SHA1_Update(&ctx, buf, buf_len);
SHA1_Final(hash, &ctx);
sig = DSA_do_sign(hash, SHA_DIGEST_LENGTH, dsactx);
if (!sig) {
LIBSSH2_FREE(session, *signature);
return -1;
}
BN_bn2bin(sig->r, *signature);
BN_bn2bin(sig->s, *signature + SHA_DIGEST_LENGTH);
DSA_SIG_free(sig);
return 0;
} }
/* }}} */ /* }}} */
@@ -430,46 +311,32 @@ static int libssh2_hostkey_method_ssh_dss_sign(LIBSSH2_SESSION *session, unsigne
static int libssh2_hostkey_method_ssh_dss_signv(LIBSSH2_SESSION *session, unsigned char **signature, unsigned long *signature_len, static int libssh2_hostkey_method_ssh_dss_signv(LIBSSH2_SESSION *session, unsigned char **signature, unsigned long *signature_len,
unsigned long veccount, const struct iovec datavec[], void **abstract) unsigned long veccount, const struct iovec datavec[], void **abstract)
{ {
DSA *dsactx = (DSA*)(*abstract); libssh2_dsa_ctx *dsactx = (libssh2_dsa_ctx*)(*abstract);
DSA_SIG *sig;
unsigned char hash[SHA_DIGEST_LENGTH]; unsigned char hash[SHA_DIGEST_LENGTH];
SHA_CTX ctx; libssh2_sha1_ctx ctx;
int r_len, s_len, rs_pad, i; unsigned int i;
*signature = LIBSSH2_ALLOC(session, 2 * SHA_DIGEST_LENGTH); *signature = LIBSSH2_ALLOC(session, 2 * SHA_DIGEST_LENGTH);
if (!*signature) {
return -1;
}
*signature_len = 2 * SHA_DIGEST_LENGTH; *signature_len = 2 * SHA_DIGEST_LENGTH;
memset(*signature, 0, 2 * SHA_DIGEST_LENGTH); memset(*signature, 0, 2 * SHA_DIGEST_LENGTH);
if (!(*signature)) { libssh2_sha1_init(&ctx);
return -1;
}
SHA1_Init(&ctx);
for(i = 0; i < veccount; i++) { for(i = 0; i < veccount; i++) {
SHA1_Update(&ctx, datavec[i].iov_base, datavec[i].iov_len); libssh2_sha1_update(ctx, datavec[i].iov_base, datavec[i].iov_len);
} }
SHA1_Final(hash, &ctx); libssh2_sha1_final(ctx, hash);
sig = DSA_do_sign(hash, SHA_DIGEST_LENGTH, dsactx); if (_libssh2_dsa_sha1_sign(dsactx, hash, SHA_DIGEST_LENGTH,
if (!sig) { *signature))
{
LIBSSH2_FREE(session, *signature); LIBSSH2_FREE(session, *signature);
return -1; return -1;
} }
r_len = BN_num_bytes(sig->r);
s_len = BN_num_bytes(sig->s);
rs_pad = (2 * SHA_DIGEST_LENGTH) - (r_len + s_len);
if (rs_pad < 0) {
DSA_SIG_free(sig);
LIBSSH2_FREE(session, *signature);
return -1;
}
BN_bn2bin(sig->r, *signature + rs_pad);
BN_bn2bin(sig->s, *signature + rs_pad + r_len);
DSA_SIG_free(sig);
return 0; return 0;
} }
/* }}} */ /* }}} */
@@ -477,11 +344,13 @@ static int libssh2_hostkey_method_ssh_dss_signv(LIBSSH2_SESSION *session, unsign
/* {{{ 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, void **abstract) static int libssh2_hostkey_method_ssh_dss_dtor(LIBSSH2_SESSION *session,
void **abstract)
{ {
DSA *dsactx = (DSA*)(*abstract); libssh2_dsa_ctx *dsactx = (libssh2_dsa_ctx*)(*abstract);
(void)session;
DSA_free(dsactx); _libssh2_dsa_free(dsactx);
*abstract = NULL; *abstract = NULL;
@@ -489,30 +358,29 @@ static int libssh2_hostkey_method_ssh_dss_dtor(LIBSSH2_SESSION *session, void **
} }
/* }}} */ /* }}} */
static LIBSSH2_HOSTKEY_METHOD libssh2_hostkey_method_ssh_dss = { static const LIBSSH2_HOSTKEY_METHOD libssh2_hostkey_method_ssh_dss = {
"ssh-dss", "ssh-dss",
MD5_DIGEST_LENGTH, MD5_DIGEST_LENGTH,
libssh2_hostkey_method_ssh_dss_init, libssh2_hostkey_method_ssh_dss_init,
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_sign,
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 /* ! OPENSSL_NO_DSA */ #endif /* LIBSSH2_DSA */
static LIBSSH2_HOSTKEY_METHOD *_libssh2_hostkey_methods[] = { static const LIBSSH2_HOSTKEY_METHOD *_libssh2_hostkey_methods[] = {
#ifndef OPENSSL_NO_RSA #if LIBSSH2_RSA
&libssh2_hostkey_method_ssh_rsa, &libssh2_hostkey_method_ssh_rsa,
#endif /* ! OPENSSL_NO_RSA */ #endif /* LIBSSH2_RSA */
#ifndef OPENSSL_NO_DSA #if LIBSSH2_DSA
&libssh2_hostkey_method_ssh_dss, &libssh2_hostkey_method_ssh_dss,
#endif /* ! OPENSSL_NO_DSA */ #endif /* LIBSSH2_DSA */
NULL NULL
}; };
LIBSSH2_HOSTKEY_METHOD **libssh2_hostkey_methods(void) const LIBSSH2_HOSTKEY_METHOD **libssh2_hostkey_methods(void)
{ {
return _libssh2_hostkey_methods; return _libssh2_hostkey_methods;
} }
@@ -526,16 +394,14 @@ LIBSSH2_HOSTKEY_METHOD **libssh2_hostkey_methods(void)
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) {
#ifndef OPENSSL_NO_MD5 #if LIBSSH2_MD5
case LIBSSH2_HOSTKEY_HASH_MD5: case LIBSSH2_HOSTKEY_HASH_MD5:
return session->server_hostkey_md5; return (char *)session->server_hostkey_md5;
break; break;
#endif /* ! OPENSSL_NO_MD5 */ #endif /* LIBSSH2_MD5 */
#ifndef OPENSSL_NO_SHA
case LIBSSH2_HOSTKEY_HASH_SHA1: case LIBSSH2_HOSTKEY_HASH_SHA1:
return session->server_hostkey_sha1; return (char *)session->server_hostkey_sha1;
break; break;
#endif /* ! OPENSSL_NO_SHA */
default: default:
return NULL; return NULL;
} }

486
src/kex.c

File diff suppressed because it is too large Load Diff

567
src/libgcrypt.c Normal file
View File

@@ -0,0 +1,567 @@
/* Copyright (C) 2006, 2007 The Written Word, Inc. All rights reserved.
* Author: Simon Josefsson
*
* Redistribution and use in source and binary forms,
* with or without modification, are permitted provided
* that the following conditions are met:
*
* Redistributions of source code must retain the above
* copyright notice, this list of conditions and the
* following disclaimer.
*
* Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following
* disclaimer in the documentation and/or other materials
* provided with the distribution.
*
* Neither the name of the copyright holder nor the names
* of any other contributors may be used to endorse or
* promote products derived from this software without
* specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
* CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
* USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
* OF SUCH DAMAGE.
*/
#include "libssh2_priv.h"
#include <string.h>
int _libssh2_rsa_new(libssh2_rsa_ctx **rsa,
const unsigned char *edata,
unsigned long elen,
const unsigned char *ndata,
unsigned long nlen,
const unsigned char *ddata,
unsigned long dlen,
const unsigned char *pdata,
unsigned long plen,
const unsigned char *qdata,
unsigned long qlen,
const unsigned char *e1data,
unsigned long e1len,
const unsigned char *e2data,
unsigned long e2len,
const unsigned char *coeffdata,
unsigned long coefflen)
{
int rc;
(void)e1data;
(void)e1len;
(void)e2data;
(void)e2len;
if (ddata) {
rc = gcry_sexp_build
(rsa, NULL,
"(private-key(rsa(n%b)(e%b)(d%b)(q%b)(p%b)(u%b)))",
nlen, ndata, elen, edata, dlen, ddata, plen, pdata,
qlen, qdata, coefflen, coeffdata);
} else {
rc = gcry_sexp_build (rsa, NULL, "(public-key(rsa(n%b)(e%b)))",
nlen, ndata, elen, edata);
}
if (rc)
{
*rsa = NULL;
return -1;
}
return 0;
}
int _libssh2_rsa_sha1_verify(libssh2_rsa_ctx *rsa,
const unsigned char *sig,
unsigned long sig_len,
const unsigned char *m,
unsigned long m_len)
{
unsigned char hash[SHA_DIGEST_LENGTH];
gcry_sexp_t s_sig, s_hash;
int rc = -1;
libssh2_sha1(m, m_len, hash);
rc = gcry_sexp_build (&s_hash, NULL,
"(data (flags pkcs1) (hash sha1 %b))",
SHA_DIGEST_LENGTH, hash);
if (rc != 0) {
return -1;
}
rc = gcry_sexp_build (&s_sig, NULL, "(sig-val(rsa(s %b)))",
sig_len, sig);
if (rc != 0) {
gcry_sexp_release (s_hash);
return -1;
}
rc = gcry_pk_verify (s_sig, s_hash, rsa);
gcry_sexp_release (s_sig);
gcry_sexp_release (s_hash);
return (rc == 0) ? 0 : -1;
}
int _libssh2_dsa_new(libssh2_dsa_ctx **dsactx,
const unsigned char *p,
unsigned long p_len,
const unsigned char *q,
unsigned long q_len,
const unsigned char *g,
unsigned long g_len,
const unsigned char *y,
unsigned long y_len,
const unsigned char *x,
unsigned long x_len)
{
int rc;
if (x_len) {
rc = gcry_sexp_build
(dsactx, NULL,
"(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);
} else {
rc = gcry_sexp_build (dsactx, NULL,
"(public-key(dsa(p%b)(q%b)(g%b)(y%b)))",
p_len, p, q_len, q, g_len, g, y_len, y);
}
if (rc) {
*dsactx = NULL;
return -1;
}
return 0;
}
int _libssh2_rsa_new_private (libssh2_rsa_ctx **rsa,
LIBSSH2_SESSION *session,
FILE *fp,
unsigned const char *passphrase)
{
char *data, *save_data;
unsigned int datalen;
int ret;
char *n, *e, *d, *p, *q, *e1, *e2, *coeff;
unsigned int nlen, elen, dlen, plen, qlen, e1len, e2len, coefflen;
(void)passphrase;
ret = _libssh2_pem_parse (session,
"-----BEGIN RSA PRIVATE KEY-----",
"-----END RSA PRIVATE KEY-----",
fp, &data, &datalen);
if (ret) {
return -1;
}
save_data = data;
if (_libssh2_pem_decode_sequence (&data, &datalen)) {
ret = -1;
goto fail;
}
/* First read Version field (should be 0). */
ret = _libssh2_pem_decode_integer (&data, &datalen, &n, &nlen);
if (ret != 0 || (nlen != 1 && *n != '\0')) {
ret = -1;
goto fail;
}
ret = _libssh2_pem_decode_integer (&data, &datalen, &n, &nlen);
if (ret != 0) {
ret = -1;
goto fail;
}
ret = _libssh2_pem_decode_integer (&data, &datalen, &e, &elen);
if (ret != 0) {
ret = -1;
goto fail;
}
ret = _libssh2_pem_decode_integer (&data, &datalen, &d, &dlen);
if (ret != 0) {
ret = -1;
goto fail;
}
ret = _libssh2_pem_decode_integer (&data, &datalen, &p, &plen);
if (ret != 0) {
ret = -1;
goto fail;
}
ret = _libssh2_pem_decode_integer (&data, &datalen, &q, &qlen);
if (ret != 0) {
ret = -1;
goto fail;
}
ret = _libssh2_pem_decode_integer (&data, &datalen, &e1, &e1len);
if (ret != 0) {
ret = -1;
goto fail;
}
ret = _libssh2_pem_decode_integer (&data, &datalen, &e2, &e2len);
if (ret != 0) {
ret = -1;
goto fail;
}
ret = _libssh2_pem_decode_integer (&data, &datalen, &coeff, &coefflen);
if (ret != 0) {
ret = -1;
goto fail;
}
if (_libssh2_rsa_new (rsa, e, elen, n, nlen, d, dlen, p, plen,
q, qlen, e1, e1len, e2, e2len,
coeff, coefflen)) {
ret = -1;
goto fail;
}
ret = 0;
fail:
LIBSSH2_FREE (session, save_data);
return ret;
}
int _libssh2_dsa_new_private (libssh2_dsa_ctx **dsa,
LIBSSH2_SESSION *session,
FILE *fp,
unsigned const char *passphrase)
{
char *data, *save_data;
unsigned int datalen;
int ret;
char *p, *q, *g, *y, *x;
unsigned int plen, qlen, glen, ylen, xlen;
(void)passphrase;
ret = _libssh2_pem_parse (session,
"-----BEGIN DSA PRIVATE KEY-----",
"-----END DSA PRIVATE KEY-----",
fp, &data, &datalen);
if (ret) {
return -1;
}
save_data = data;
if (_libssh2_pem_decode_sequence (&data, &datalen)) {
ret = -1;
goto fail;
}
/* First read Version field (should be 0). */
ret = _libssh2_pem_decode_integer (&data, &datalen, &p, &plen);
if (ret != 0 || (plen != 1 && *p != '\0')) {
ret = -1;
goto fail;
}
ret = _libssh2_pem_decode_integer (&data, &datalen, &p, &plen);
if (ret != 0) {
ret = -1;
goto fail;
}
ret = _libssh2_pem_decode_integer (&data, &datalen, &q, &qlen);
if (ret != 0) {
ret = -1;
goto fail;
}
ret = _libssh2_pem_decode_integer (&data, &datalen, &g, &glen);
if (ret != 0) {
ret = -1;
goto fail;
}
ret = _libssh2_pem_decode_integer (&data, &datalen, &y, &ylen);
if (ret != 0) {
ret = -1;
goto fail;
}
ret = _libssh2_pem_decode_integer (&data, &datalen, &x, &xlen);
if (ret != 0) {
ret = -1;
goto fail;
}
if (datalen != 0) {
ret = -1;
goto fail;
}
if (_libssh2_dsa_new (dsa, p, plen, q, qlen,
g, glen, y, ylen, x, xlen)) {
ret = -1;
goto fail;
}
ret = 0;
fail:
LIBSSH2_FREE (session, save_data);
return ret;
}
int _libssh2_rsa_sha1_sign(LIBSSH2_SESSION *session,
libssh2_dsa_ctx *rsactx,
const unsigned char *hash,
unsigned long hash_len,
unsigned char **signature,
unsigned long *signature_len)
{
gcry_sexp_t sig_sexp;
gcry_sexp_t data;
int rc;
const char *tmp;
size_t size;
if (hash_len != SHA_DIGEST_LENGTH) {
return -1;
}
if (gcry_sexp_build (&data, NULL,
"(data (flags pkcs1) (hash sha1 %b))",
hash_len, hash)) {
return -1;
}
rc = gcry_pk_sign (&sig_sexp, data, rsactx);
gcry_sexp_release (data);
if (rc != 0) {
return -1;
}
data = gcry_sexp_find_token(sig_sexp, "s", 0);
if (!data) {
return -1;
}
tmp = gcry_sexp_nth_data(data, 1, &size);
if (!tmp) {
return -1;
}
if (tmp[0] == '\0') {
tmp++;
size--;
}
*signature = LIBSSH2_ALLOC(session, size);
memcpy (*signature, tmp, size);
*signature_len = size;
return rc;
}
int _libssh2_dsa_sha1_sign(libssh2_dsa_ctx *dsactx,
const unsigned char *hash,
unsigned long hash_len,
unsigned char *sig)
{
unsigned char zhash[SHA_DIGEST_LENGTH+1];
gcry_sexp_t sig_sexp;
gcry_sexp_t data;
int ret;
const char *tmp;
size_t size;
if (hash_len != SHA_DIGEST_LENGTH) {
return -1;
}
memcpy (zhash + 1, hash, hash_len);
zhash[0] = 0;
if (gcry_sexp_build (&data, NULL, "(data (value %b))",
hash_len + 1, zhash)) {
return -1;
}
ret = gcry_pk_sign (&sig_sexp, data, dsactx);
gcry_sexp_release (data);
if (ret != 0) {
return -1;
}
/* Extract R. */
data = gcry_sexp_find_token(sig_sexp, "r", 0);
if (!data) {
ret = -1;
goto out;
}
tmp = gcry_sexp_nth_data(data, 1, &size);
if (!tmp) {
ret = -1;
goto out;
}
if (tmp[0] == '\0') {
tmp++;
size--;
}
if (size != 20) {
ret = -1;
goto out;
}
memcpy (sig, tmp, 20);
gcry_sexp_release (data);
/* Extract S. */
data = gcry_sexp_find_token(sig_sexp, "s",0);
if (!data) {
ret = -1;
goto out;
}
tmp = gcry_sexp_nth_data(data, 1, &size);
if (!tmp) {
ret = -1;
goto out;
}
if (tmp[0] == '\0') {
tmp++;
size--;
}
if (size != 20) {
ret = -1;
goto out;
}
memcpy (sig + 20, tmp, 20);
ret = 0;
out:
if (sig_sexp) {
gcry_sexp_release (sig_sexp);
}
if (data) {
gcry_sexp_release (data);
}
return ret;
}
int _libssh2_dsa_sha1_verify(libssh2_dsa_ctx *dsactx,
const unsigned char *sig,
const unsigned char *m,
unsigned long m_len)
{
unsigned char hash[SHA_DIGEST_LENGTH+1];
gcry_sexp_t s_sig, s_hash;
int rc = -1;
libssh2_sha1(m, m_len, hash+1);
hash[0] = 0;
if (gcry_sexp_build (&s_hash, NULL, "(data(flags raw)(value %b))",
SHA_DIGEST_LENGTH+1, hash)) {
return -1;
}
if (gcry_sexp_build (&s_sig, NULL, "(sig-val(dsa(r %b)(s %b)))",
20, sig, 20, sig + 20)) {
gcry_sexp_release (s_hash);
return -1;
}
rc = gcry_pk_verify (s_sig, s_hash, dsactx);
gcry_sexp_release (s_sig);
gcry_sexp_release (s_hash);
return (rc == 0) ? 0 : -1;
}
int _libssh2_cipher_init (_libssh2_cipher_ctx *h,
_libssh2_cipher_type(algo),
unsigned char *iv,
unsigned char *secret,
int encrypt)
{
int mode = 0, ret;
int keylen = gcry_cipher_get_algo_keylen (algo);
(void)encrypt;
if (algo != GCRY_CIPHER_ARCFOUR) {
mode = GCRY_CIPHER_MODE_CBC;
}
ret = gcry_cipher_open (h, algo, mode, 0);
if (ret) {
return -1;
}
ret = gcry_cipher_setkey (*h, secret, keylen);
if (ret) {
gcry_cipher_close (*h);
return -1;
}
if (algo != GCRY_CIPHER_ARCFOUR) {
int blklen = gcry_cipher_get_algo_blklen (algo);
ret = gcry_cipher_setiv (*h, iv, blklen);
if (ret) {
gcry_cipher_close (*h);
return -1;
}
}
return 0;
}
int _libssh2_cipher_crypt(_libssh2_cipher_ctx *ctx,
_libssh2_cipher_type(algo),
int encrypt,
unsigned char *block)
{
size_t blklen = gcry_cipher_get_algo_blklen (algo);
int ret;
if (blklen == 1) {
/* Hack for arcfour. */
blklen = 8;
}
if (encrypt) {
ret = gcry_cipher_encrypt (*ctx, block, blklen,
block, blklen);
} else {
ret = gcry_cipher_decrypt (*ctx, block, blklen,
block, blklen);
}
return ret;
}

195
src/libgcrypt.h Normal file
View File

@@ -0,0 +1,195 @@
/* Copyright (C) 2006, 2007 The Written Word, Inc. All rights reserved.
* Author: Simon Josefsson
*
* Redistribution and use in source and binary forms,
* with or without modification, are permitted provided
* that the following conditions are met:
*
* Redistributions of source code must retain the above
* copyright notice, this list of conditions and the
* following disclaimer.
*
* Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following
* disclaimer in the documentation and/or other materials
* provided with the distribution.
*
* Neither the name of the copyright holder nor the names
* of any other contributors may be used to endorse or
* promote products derived from this software without
* specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
* CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
* USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
* OF SUCH DAMAGE.
*/
#include <gcrypt.h>
#define LIBSSH2_MD5 1
#define LIBSSH2_HMAC_RIPEMD 1
#define LIBSSH2_AES 1
#define LIBSSH2_BLOWFISH 1
#define LIBSSH2_RC4 1
#define LIBSSH2_CAST 1
#define LIBSSH2_3DES 1
#define LIBSSH2_RSA 1
#define LIBSSH2_DSA 1
#define MD5_DIGEST_LENGTH 16
#define SHA_DIGEST_LENGTH 20
#define libssh2_random(buf, len) \
(gcry_randomize ((buf), (len), GCRY_STRONG_RANDOM), 1)
#define libssh2_sha1_ctx gcry_md_hd_t
#define libssh2_sha1_init(ctx) gcry_md_open (ctx, GCRY_MD_SHA1, 0);
#define libssh2_sha1_update(ctx, data, len) gcry_md_write (ctx, data, len)
#define libssh2_sha1_final(ctx, out) \
memcpy (out, gcry_md_read (ctx, 0), 20), gcry_md_close (ctx)
#define libssh2_sha1(message, len, out) \
gcry_md_hash_buffer (GCRY_MD_SHA1, out, message, len)
#define libssh2_md5_ctx gcry_md_hd_t
#define libssh2_md5_init(ctx) gcry_md_open (ctx, GCRY_MD_MD5, 0);
#define libssh2_md5_update(ctx, data, len) gcry_md_write (ctx, data, len)
#define libssh2_md5_final(ctx, out) \
memcpy (out, gcry_md_read (ctx, 0), 20), gcry_md_close (ctx)
#define libssh2_md5(message, len, out) \
gcry_md_hash_buffer (GCRY_MD_MD5, out, message, len)
#define libssh2_hmac_ctx gcry_md_hd_t
#define libssh2_hmac_sha1_init(ctx, key, keylen) \
gcry_md_open (ctx, GCRY_MD_SHA1, GCRY_MD_FLAG_HMAC), \
gcry_md_setkey (*ctx, key, keylen)
#define libssh2_hmac_md5_init(ctx, key, keylen) \
gcry_md_open (ctx, GCRY_MD_MD5, GCRY_MD_FLAG_HMAC), \
gcry_md_setkey (*ctx, key, keylen)
#define libssh2_hmac_ripemd160_init(ctx, key, keylen) \
gcry_md_open (ctx, GCRY_MD_RMD160, GCRY_MD_FLAG_HMAC), \
gcry_md_setkey (*ctx, key, keylen)
#define libssh2_hmac_update(ctx, data, datalen) \
gcry_md_write (ctx, data, datalen)
#define libssh2_hmac_final(ctx, data) \
memcpy (data, gcry_md_read (ctx, 0), \
gcry_md_get_algo_dlen (gcry_md_get_algo (ctx)))
#define libssh2_hmac_cleanup(ctx) gcry_md_close (*ctx);
#define libssh2_crypto_init() gcry_control (GCRYCTL_DISABLE_SECMEM)
#define libssh2_rsa_ctx struct gcry_sexp
int _libssh2_rsa_new(libssh2_rsa_ctx **rsa,
const unsigned char *edata,
unsigned long elen,
const unsigned char *ndata,
unsigned long nlen,
const unsigned char *ddata,
unsigned long dlen,
const unsigned char *pdata,
unsigned long plen,
const unsigned char *qdata,
unsigned long qlen,
const unsigned char *e1data,
unsigned long e1len,
const unsigned char *e2data,
unsigned long e2len,
const unsigned char *coeffdata,
unsigned long coefflen);
int _libssh2_rsa_new_private (libssh2_rsa_ctx **rsa,
LIBSSH2_SESSION *session,
FILE *fp,
unsigned const char *passphrase);
int _libssh2_rsa_sha1_verify(libssh2_rsa_ctx *rsa,
const unsigned char *sig,
unsigned long sig_len,
const unsigned char *m,
unsigned long m_len);
int _libssh2_rsa_sha1_sign(LIBSSH2_SESSION *session,
libssh2_rsa_ctx *rsactx,
const unsigned char *hash,
unsigned long hash_len,
unsigned char **signature,
unsigned long *signature_len);
#define _libssh2_rsa_free(rsactx) gcry_sexp_release (rsactx)
#define libssh2_dsa_ctx struct gcry_sexp
int _libssh2_dsa_new(libssh2_dsa_ctx **dsa,
const unsigned char *pdata,
unsigned long plen,
const unsigned char *qdata,
unsigned long qlen,
const unsigned char *gdata,
unsigned long glen,
const unsigned char *ydata,
unsigned long ylen,
const unsigned char *x,
unsigned long x_len);
int _libssh2_dsa_new_private (libssh2_dsa_ctx **dsa,
LIBSSH2_SESSION *session,
FILE *fp,
unsigned const char *passphrase);
int _libssh2_dsa_sha1_verify(libssh2_dsa_ctx *dsa,
const unsigned char *sig,
const unsigned char *m,
unsigned long m_len);
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_cipher_type(name) int name
#define _libssh2_cipher_ctx gcry_cipher_hd_t
#define _libssh2_cipher_aes256 GCRY_CIPHER_AES256
#define _libssh2_cipher_aes192 GCRY_CIPHER_AES192
#define _libssh2_cipher_aes128 GCRY_CIPHER_AES128
#define _libssh2_cipher_blowfish GCRY_CIPHER_BLOWFISH
#define _libssh2_cipher_arcfour GCRY_CIPHER_ARCFOUR
#define _libssh2_cipher_cast5 GCRY_CIPHER_CAST5
#define _libssh2_cipher_3des GCRY_CIPHER_3DES
int _libssh2_cipher_init (_libssh2_cipher_ctx *h,
_libssh2_cipher_type(algo),
unsigned char *iv,
unsigned char *secret,
int encrypt);
int _libssh2_cipher_crypt(_libssh2_cipher_ctx *ctx,
_libssh2_cipher_type(algo),
int encrypt,
unsigned char *block);
#define _libssh2_cipher_dtor(ctx) gcry_cipher_close(*(ctx))
#define _libssh2_bn struct gcry_mpi
#define _libssh2_bn_ctx int
#define _libssh2_bn_ctx_new() 0
#define _libssh2_bn_ctx_free(bnctx) 0
#define _libssh2_bn_init() gcry_mpi_new(0)
#define _libssh2_bn_rand(bn, bits, top, bottom) gcry_mpi_randomize (bn, bits, GCRY_WEAK_RANDOM)
#define _libssh2_bn_mod_exp(r, a, p, m, ctx) gcry_mpi_powm (r, a, p, m)
#define _libssh2_bn_set_word(bn, val) gcry_mpi_set_ui(bn, val)
#define _libssh2_bn_from_bin(bn, len, val) gcry_mpi_scan(&((bn)), GCRYMPI_FMT_USG, val, len, NULL)
#define _libssh2_bn_to_bin(bn, val) gcry_mpi_print (GCRYMPI_FMT_USG, val, _libssh2_bn_bytes(bn), NULL, bn)
#define _libssh2_bn_bytes(bn) (gcry_mpi_get_nbits (bn) / 8 + ((gcry_mpi_get_nbits (bn) % 8 == 0) ? 0 : 1))
#define _libssh2_bn_bits(bn) gcry_mpi_get_nbits (bn)
#define _libssh2_bn_free(bn) gcry_mpi_release(bn)

603
src/libssh2_priv.h Normal file
View File

@@ -0,0 +1,603 @@
/* Copyright (c) 2004-2007, Sara Golemon <sarag@libssh2.org>
* All rights reserved.
*
* Redistribution and use in source and binary forms,
* with or without modification, are permitted provided
* that the following conditions are met:
*
* Redistributions of source code must retain the above
* copyright notice, this list of conditions and the
* following disclaimer.
*
* Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following
* disclaimer in the documentation and/or other materials
* provided with the distribution.
*
* Neither the name of the copyright holder nor the names
* of any other contributors may be used to endorse or
* promote products derived from this software without
* specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
* CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
* USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
* OF SUCH DAMAGE.
*/
#ifndef LIBSSH2_PRIV_H
#define LIBSSH2_PRIV_H 1
#define LIBSSH2_LIBRARY
#include "libssh2_config.h"
/* The following CPP block should really only be in session.c and
packet.c. However, AIX have #define's for 'events' and 'revents'
and we are using those names in libssh2.h, so we need to include
the AIX headers first, to make sure all code is compiled with
consistent names of these fields. While arguable the best would to
change libssh2.h to use other names, that would break backwards
compatibility. For more information, see:
http://www.mail-archive.com/libssh2-devel%40lists.sourceforge.net/msg00003.html
http://www.mail-archive.com/libssh2-devel%40lists.sourceforge.net/msg00224.html
*/
#ifdef HAVE_POLL
# include <sys/poll.h>
#else
# ifdef HAVE_SELECT
# ifdef HAVE_SYS_SELECT_H
# include <sys/select.h>
# else
# include <sys/time.h>
# include <sys/types.h>
# endif
# endif
#endif
#include "libssh2.h"
#include <stdio.h>
#ifdef HAVE_SYS_SOCKET_H
# include <sys/socket.h>
#endif
#ifdef HAVE_SYS_IOCTL_H
# include <sys/ioctl.h>
#endif
#ifdef LIBSSH2_LIBGCRYPT
#include "libgcrypt.h"
#else
#include "openssl.h"
#endif
/* RFC4253 section 6.1 Maximum Packet Length says:
*
* "All implementations MUST be able to process packets with
* uncompressed payload length of 32768 bytes or less and
* total packet size of 35000 bytes or less (including length,
* padding length, payload, padding, and MAC.)."
*/
#define MAX_SSH_PACKET_LEN 35000
#define LIBSSH2_ALLOC(session, count) session->alloc((count), &(session)->abstract)
#define LIBSSH2_REALLOC(session, ptr, count) ((ptr) ? session->realloc((ptr), (count), &(session)->abstract) : session->alloc((count), &(session)->abstract))
#define LIBSSH2_FREE(session, ptr) session->free((ptr), &(session)->abstract)
#define LIBSSH2_IGNORE(session, data, datalen) session->ssh_msg_ignore((session), (data), (datalen), &(session)->abstract)
#define LIBSSH2_DEBUG(session, always_display, message, message_len, language, language_len) \
session->ssh_msg_disconnect((session), (always_display), (message), (message_len), (language), (language_len), &(session)->abstract)
#define LIBSSH2_DISCONNECT(session, reason, message, message_len, language, language_len) \
session->ssh_msg_disconnect((session), (reason), (message), (message_len), (language), (language_len), &(session)->abstract)
#define LIBSSH2_MACERROR(session, data, datalen) session->macerror((session), (data), (datalen), &(session)->abstract)
#define LIBSSH2_X11_OPEN(channel, shost, sport) channel->session->x11(((channel)->session), (channel), (shost), (sport), (&(channel)->session->abstract))
#define LIBSSH2_CHANNEL_CLOSE(session, channel) channel->close_cb((session), &(session)->abstract, (channel), &(channel)->abstract)
typedef struct _LIBSSH2_KEX_METHOD LIBSSH2_KEX_METHOD;
typedef struct _LIBSSH2_HOSTKEY_METHOD LIBSSH2_HOSTKEY_METHOD;
typedef struct _LIBSSH2_MAC_METHOD LIBSSH2_MAC_METHOD;
typedef struct _LIBSSH2_CRYPT_METHOD LIBSSH2_CRYPT_METHOD;
typedef struct _LIBSSH2_COMP_METHOD LIBSSH2_COMP_METHOD;
typedef struct _LIBSSH2_PACKET LIBSSH2_PACKET;
typedef struct _LIBSSH2_PACKET_BRIGADE LIBSSH2_PACKET_BRIGADE;
typedef struct _LIBSSH2_CHANNEL_BRIGADE LIBSSH2_CHANNEL_BRIGADE;
struct _LIBSSH2_PACKET {
unsigned char type;
/* Unencrypted Payload (no type byte, no padding, just the facts ma'am) */
unsigned char *data;
unsigned long data_len;
/* Where to start reading data from,
* used for channel data that's been partially consumed */
unsigned long data_head;
/* Can the message be confirmed? */
int mac;
LIBSSH2_PACKET_BRIGADE *brigade;
LIBSSH2_PACKET *next, *prev;
};
struct _LIBSSH2_PACKET_BRIGADE {
LIBSSH2_PACKET *head, *tail;
};
typedef struct _libssh2_channel_data {
/* Identifier */
unsigned long id;
/* Limits and restrictions */
unsigned long window_size_initial, window_size, packet_size;
/* Set to 1 when CHANNEL_CLOSE / CHANNEL_EOF sent/received */
char close, eof, extended_data_ignore_mode;
} libssh2_channel_data;
struct _LIBSSH2_CHANNEL {
unsigned char *channel_type;
unsigned channel_type_len;
int blocking;
/* channel's program exit status */
int exit_status;
libssh2_channel_data local, remote;
unsigned long adjust_queue; /* Amount of bytes to be refunded to receive window (but not yet sent) */
LIBSSH2_SESSION *session;
LIBSSH2_CHANNEL *next, *prev;
void *abstract;
LIBSSH2_CHANNEL_CLOSE_FUNC((*close_cb));
};
struct _LIBSSH2_CHANNEL_BRIGADE {
LIBSSH2_CHANNEL *head, *tail;
};
struct _LIBSSH2_LISTENER {
LIBSSH2_SESSION *session;
char *host;
int port;
LIBSSH2_CHANNEL *queue;
int queue_size;
int queue_maxsize;
LIBSSH2_LISTENER *prev, *next;
};
typedef struct _libssh2_endpoint_data {
unsigned char *banner;
unsigned char *kexinit;
unsigned long kexinit_len;
const LIBSSH2_CRYPT_METHOD *crypt;
void *crypt_abstract;
const LIBSSH2_MAC_METHOD *mac;
unsigned long seqno;
void *mac_abstract;
const LIBSSH2_COMP_METHOD *comp;
void *comp_abstract;
/* Method Preferences -- NULL yields "load order" */
char *crypt_prefs;
char *mac_prefs;
char *comp_prefs;
char *lang_prefs;
} libssh2_endpoint_data;
#define PACKETBUFSIZE 4096
struct transportpacket {
/* ------------- for incoming data --------------- */
unsigned char buf[PACKETBUFSIZE];
unsigned char init[5]; /* first 5 bytes of the incoming data stream,
still encrypted */
int writeidx; /* at what array index we do the next write into
the buffer */
int readidx; /* at what array index we do the next read from
the buffer */
int packet_length; /* the most recent packet_length as read from the
network data */
int padding_length; /* the most recent padding_length as read from the
network data */
int data_num; /* How much of the total package that has been read
so far. */
int total_num; /* How much a total package is supposed to be, in
number of bytes. A full package is
packet_length + padding_length + 4 +
mac_length. */
unsigned char *payload; /* this is a pointer to a LIBSSH2_ALLOC()
area to which we write decrypted data */
unsigned char *wptr; /* write pointer into the payload to where we
are currently writing decrypted data */
/* ------------- for outgoing data --------------- */
unsigned char *outbuf; /* pointer to a LIBSSH2_ALLOC() area for the
outgoing data */
int ototal_num; /* size of outbuf in number of bytes */
unsigned char *odata; /* original pointer to the data we stored in
outbuf */
unsigned long olen; /* original size of the data we stored in
outbuf */
unsigned long osent; /* number of bytes already sent */
};
struct _LIBSSH2_SESSION {
/* Memory management callbacks */
void *abstract;
LIBSSH2_ALLOC_FUNC((*alloc));
LIBSSH2_REALLOC_FUNC((*realloc));
LIBSSH2_FREE_FUNC((*free));
/* Other callbacks */
LIBSSH2_IGNORE_FUNC((*ssh_msg_ignore));
LIBSSH2_DEBUG_FUNC((*ssh_msg_debug));
LIBSSH2_DISCONNECT_FUNC((*ssh_msg_disconnect));
LIBSSH2_MACERROR_FUNC((*macerror));
LIBSSH2_X11_OPEN_FUNC((*x11));
/* Method preferences -- NULL yields "load order" */
char *kex_prefs;
char *hostkey_prefs;
int state;
int flags;
/* Agreed Key Exchange Method */
const LIBSSH2_KEX_METHOD *kex;
int burn_optimistic_kexinit:1;
unsigned char *session_id;
unsigned long session_id_len;
/* Server's public key */
const LIBSSH2_HOSTKEY_METHOD *hostkey;
void *server_hostkey_abstract;
/* Either set with libssh2_session_hostkey() (for server mode)
* Or read from server in (eg) KEXDH_INIT (for client mode)
*/
unsigned char *server_hostkey;
unsigned long server_hostkey_len;
#if LIBSSH2_MD5
unsigned char server_hostkey_md5[MD5_DIGEST_LENGTH];
#endif /* ! LIBSSH2_MD5 */
unsigned char server_hostkey_sha1[SHA_DIGEST_LENGTH];
/* (remote as source of data -- packet_read ) */
libssh2_endpoint_data remote;
/* (local as source of data -- packet_write ) */
libssh2_endpoint_data local;
/* Inbound Data buffer -- Sometimes the packet that comes in isn't the packet we're ready for */
LIBSSH2_PACKET_BRIGADE packets;
/* Active connection channels */
LIBSSH2_CHANNEL_BRIGADE channels;
unsigned long next_channel;
LIBSSH2_LISTENER *listeners;
/* Actual I/O socket */
int socket_fd;
int socket_block;
int socket_state;
/* Error tracking */
char *err_msg;
unsigned long err_msglen;
int err_should_free;
int err_code;
/* struct members for packet-level reading */
struct transportpacket packet;
#ifdef LIBSSH2DEBUG
int showmask; /* what debug/trace messages to display */
#endif
};
/* session.state bits */
#define LIBSSH2_STATE_EXCHANGING_KEYS 0x00000001
#define LIBSSH2_STATE_NEWKEYS 0x00000002
#define LIBSSH2_STATE_AUTHENTICATED 0x00000004
/* session.flag helpers */
#ifdef MSG_NOSIGNAL
#define LIBSSH2_SOCKET_SEND_FLAGS(session) (((session)->flags & LIBSSH2_FLAG_SIGPIPE) ? 0 : MSG_NOSIGNAL)
#define LIBSSH2_SOCKET_RECV_FLAGS(session) (((session)->flags & LIBSSH2_FLAG_SIGPIPE) ? 0 : MSG_NOSIGNAL)
#else
/* If MSG_NOSIGNAL isn't defined we're SOL on blocking SIGPIPE */
#define LIBSSH2_SOCKET_SEND_FLAGS(session) 0
#define LIBSSH2_SOCKET_RECV_FLAGS(session) 0
#endif
/* libssh2 extensible ssh api, ultimately I'd like to allow loading additional methods via .so/.dll */
struct _LIBSSH2_KEX_METHOD {
const char *name;
/* Key exchange, populates session->* and returns 0 on success, non-0 on error */
int (*exchange_keys)(LIBSSH2_SESSION *session);
long flags;
};
struct _LIBSSH2_HOSTKEY_METHOD {
const char *name;
unsigned long hash_len;
int (*init)(LIBSSH2_SESSION *session, const unsigned char *hostkey_data, unsigned long hostkey_data_len, void **abstract);
int (*initPEM)(LIBSSH2_SESSION *session, const char *privkeyfile, unsigned const char *passphrase, void **abstract);
int (*sig_verify)(LIBSSH2_SESSION *session, const unsigned char *sig, unsigned long sig_len, const unsigned char *m, unsigned long m_len, void **abstract);
int (*signv)(LIBSSH2_SESSION *session, unsigned char **signature, unsigned long *signature_len, unsigned long veccount, const struct iovec datavec[], void **abstract);
int (*encrypt)(LIBSSH2_SESSION *session, unsigned char **dst, unsigned long *dst_len, const unsigned char *src, unsigned long src_len, void **abstract);
int (*dtor)(LIBSSH2_SESSION *session, void **abstract);
};
struct _LIBSSH2_CRYPT_METHOD {
const char *name;
int blocksize;
/* iv and key sizes (-1 for variable length) */
int iv_len;
int secret_len;
long flags;
int (*init)(LIBSSH2_SESSION *session, const LIBSSH2_CRYPT_METHOD *method, unsigned char *iv, int *free_iv, unsigned char *secret, int *free_secret, int encrypt, void **abstract);
int (*crypt)(LIBSSH2_SESSION *session, unsigned char *block, void **abstract);
int (*dtor)(LIBSSH2_SESSION *session, void **abstract);
_libssh2_cipher_type(algo);
};
struct _LIBSSH2_COMP_METHOD {
const char *name;
int (*init)(LIBSSH2_SESSION *session, int compress, void **abstract);
int (*comp)(LIBSSH2_SESSION *session, int compress, unsigned char **dest, unsigned long *dest_len, unsigned long payload_limit, int *free_dest,
const unsigned char *src, unsigned long src_len, void **abstract);
int (*dtor)(LIBSSH2_SESSION *session, int compress, void **abstract);
};
struct _LIBSSH2_MAC_METHOD {
const char *name;
/* The length of a given MAC packet */
int mac_len;
/* integrity key length */
int key_len;
/* Message Authentication Code Hashing algo */
int (*init)(LIBSSH2_SESSION *session, unsigned char *key, int *free_key, void **abstract);
int (*hash)(LIBSSH2_SESSION *session, unsigned char *buf, unsigned long seqno, const unsigned char *packet, unsigned long packet_len, const unsigned char *addtl, unsigned long addtl_len, void **abstract);
int (*dtor)(LIBSSH2_SESSION *session, void **abstract);
};
#define LIBSSH2_DBG_TRANS 1
#define LIBSSH2_DBG_KEX 2
#define LIBSSH2_DBG_AUTH 3
#define LIBSSH2_DBG_CONN 4
#define LIBSSH2_DBG_SCP 5
#define LIBSSH2_DBG_SFTP 6
#define LIBSSH2_DBG_ERROR 7
#define LIBSSH2_DBG_PUBLICKEY 8
#ifdef LIBSSH2DEBUG
void _libssh2_debug(LIBSSH2_SESSION *session, int context, const char *format, ...);
#else
#if defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L)
/* C99 style */
#define _libssh2_debug(x,y,z, __VA_ARGS__) do {} while (0)
#elif defined(__GNUC__)
/* GNU style */
#define _libssh2_debug(x,y,z,...) do {} while (0)
#else
/* no gcc and not C99, do static and hopefully inline */
static inline void _libssh2_debug(LIBSSH2_SESSION *session, int context,
const char *format, ...) {}
#endif
#endif
#ifdef LIBSSH2DEBUG
#define libssh2_error(session, errcode, errmsg, should_free) \
{ \
if (session->err_msg && session->err_should_free) { \
LIBSSH2_FREE(session, session->err_msg); \
} \
session->err_msg = (char *)errmsg; \
session->err_msglen = strlen(errmsg); \
session->err_should_free = should_free; \
session->err_code = errcode; \
_libssh2_debug(session, LIBSSH2_DBG_ERROR, "%d - %s", session->err_code, session->err_msg); \
}
#else /* ! LIBSSH2DEBUG */
#define libssh2_error(session, errcode, errmsg, should_free) \
{ \
if (session->err_msg && session->err_should_free) { \
LIBSSH2_FREE(session, session->err_msg); \
} \
session->err_msg = (char *)errmsg; \
session->err_msglen = strlen(errmsg); \
session->err_should_free = should_free; \
session->err_code = errcode; \
}
#endif /* LIBSSH2_DEBUG_ENABLED */
#define LIBSSH2_SOCKET_UNKNOWN 1
#define LIBSSH2_SOCKET_CONNECTED 0
#define LIBSSH2_SOCKET_DISCONNECTED -1
/* Initial packet state, prior to MAC check */
#define LIBSSH2_MAC_UNCONFIRMED 1
/* When MAC type is "none" (proto initiation phase) all packets are deemed "confirmed" */
#define LIBSSH2_MAC_CONFIRMED 0
/* Something very bad is going on */
#define LIBSSH2_MAC_INVALID -1
/* SSH Packet Types -- Defined by internet draft */
/* Transport Layer */
#define SSH_MSG_DISCONNECT 1
#define SSH_MSG_IGNORE 2
#define SSH_MSG_UNIMPLEMENTED 3
#define SSH_MSG_DEBUG 4
#define SSH_MSG_SERVICE_REQUEST 5
#define SSH_MSG_SERVICE_ACCEPT 6
#define SSH_MSG_KEXINIT 20
#define SSH_MSG_NEWKEYS 21
/* diffie-hellman-group1-sha1 */
#define SSH_MSG_KEXDH_INIT 30
#define SSH_MSG_KEXDH_REPLY 31
/* diffie-hellman-group-exchange-sha1 */
#define SSH_MSG_KEX_DH_GEX_REQUEST_OLD 30
#define SSH_MSG_KEX_DH_GEX_REQUEST 34
#define SSH_MSG_KEX_DH_GEX_GROUP 31
#define SSH_MSG_KEX_DH_GEX_INIT 32
#define SSH_MSG_KEX_DH_GEX_REPLY 33
/* User Authentication */
#define SSH_MSG_USERAUTH_REQUEST 50
#define SSH_MSG_USERAUTH_FAILURE 51
#define SSH_MSG_USERAUTH_SUCCESS 52
#define SSH_MSG_USERAUTH_BANNER 53
/* "public key" method */
#define SSH_MSG_USERAUTH_PK_OK 60
/* "password" method */
#define SSH_MSG_USERAUTH_PASSWD_CHANGEREQ 60
/* "keyboard-interactive" method */
#define SSH_MSG_USERAUTH_INFO_REQUEST 60
#define SSH_MSG_USERAUTH_INFO_RESPONSE 61
/* Channels */
#define SSH_MSG_GLOBAL_REQUEST 80
#define SSH_MSG_REQUEST_SUCCESS 81
#define SSH_MSG_REQUEST_FAILURE 82
#define SSH_MSG_CHANNEL_OPEN 90
#define SSH_MSG_CHANNEL_OPEN_CONFIRMATION 91
#define SSH_MSG_CHANNEL_OPEN_FAILURE 92
#define SSH_MSG_CHANNEL_WINDOW_ADJUST 93
#define SSH_MSG_CHANNEL_DATA 94
#define SSH_MSG_CHANNEL_EXTENDED_DATA 95
#define SSH_MSG_CHANNEL_EOF 96
#define SSH_MSG_CHANNEL_CLOSE 97
#define SSH_MSG_CHANNEL_REQUEST 98
#define SSH_MSG_CHANNEL_SUCCESS 99
#define SSH_MSG_CHANNEL_FAILURE 100
void libssh2_session_shutdown(LIBSSH2_SESSION *session);
unsigned long libssh2_ntohu32(const unsigned char *buf);
libssh2_uint64_t libssh2_ntohu64(const unsigned char *buf);
void libssh2_htonu32(unsigned char *buf, unsigned long val);
void libssh2_htonu64(unsigned char *buf, libssh2_uint64_t val);
#define LIBSSH2_READ_TIMEOUT 60 /* generic timeout in seconds used when
waiting for more data to arrive */
int libssh2_waitsocket(LIBSSH2_SESSION *session, long seconds);
/* CAUTION: some of these error codes are returned in the public API and is
there known with other #defined names from the public header file. They
should not be changed. */
typedef int libssh2pack_t;
#define PACKET_TIMEOUT -7
#define PACKET_BADUSE -6
#define PACKET_COMPRESS -5
#define PACKET_TOOBIG -4
#define PACKET_ENOMEM -3
#define PACKET_EAGAIN -2
#define PACKET_FAIL -1
#define PACKET_NONE 0
libssh2pack_t libssh2_packet_read(LIBSSH2_SESSION *session);
int libssh2_packet_ask_ex(LIBSSH2_SESSION *session, unsigned char packet_type, unsigned char **data, unsigned long *data_len, unsigned long match_ofs, const unsigned char *match_buf, unsigned long match_len, int poll_socket);
#define libssh2_packet_ask(session, packet_type, data, data_len, poll_socket) \
libssh2_packet_ask_ex((session), (packet_type), (data), (data_len), 0, NULL, 0, (poll_socket))
int libssh2_packet_askv_ex(LIBSSH2_SESSION *session, const unsigned char *packet_types, unsigned char **data, unsigned long *data_len, unsigned long match_ofs, const unsigned char *match_buf, unsigned long match_len, int poll_socket);
#define libssh2_packet_askv(session, packet_types, data, data_len, poll_socket) \
libssh2_packet_askv_ex((session), (packet_types), (data), (data_len), 0, NULL, 0, (poll_socket))
int libssh2_packet_require_ex(LIBSSH2_SESSION *session, unsigned char packet_type, unsigned char **data, unsigned long *data_len, unsigned long match_ofs, const unsigned char *match_buf, unsigned long match_len);
#define libssh2_packet_require(session, packet_type, data, data_len) \
libssh2_packet_require_ex((session), (packet_type), (data), (data_len), 0, NULL, 0)
int libssh2_packet_requirev_ex(LIBSSH2_SESSION *session, const unsigned char *packet_types, unsigned char **data, unsigned long *data_len, unsigned long match_ofs, const unsigned char *match_buf, unsigned long match_len);
#define libssh2_packet_requirev(session, packet_types, data, data_len) \
libssh2_packet_requirev_ex((session), (packet_types), (data), (data_len), 0, NULL, 0)
int libssh2_packet_burn(LIBSSH2_SESSION *session);
int libssh2_packet_write(LIBSSH2_SESSION *session, unsigned char *data, unsigned long data_len);
int libssh2_packet_add(LIBSSH2_SESSION *session, unsigned char *data, size_t datalen, int macstate);
int libssh2_kex_exchange(LIBSSH2_SESSION *session, int reexchange);
unsigned long libssh2_channel_nextid(LIBSSH2_SESSION *session);
LIBSSH2_CHANNEL *libssh2_channel_locate(LIBSSH2_SESSION *session, unsigned long channel_id);
ssize_t _libssh2_channel_read_ex(LIBSSH2_CHANNEL *channel,
int stream_id, char *buf, size_t buflen);
#define _libssh2_channel_read(channel, buf, buflen) \
_libssh2_channel_read_ex((channel), 0, (buf), (buflen))
#undef libssh2_channel_read /* never use this internally */
#define libssh2_channel_read fix this code
int _libssh2_channel_write_ex(LIBSSH2_CHANNEL *channel,
int stream_id,
const char *buf, size_t buflen);
#define _libssh2_channel_write(channel, buf, buflen) \
_libssh2_channel_write_ex((channel), 0, (buf), (buflen))
/* this is the lib-internal set blocking function */
int _libssh2_channel_set_blocking(LIBSSH2_CHANNEL *channel, int blocking);
/* Let crypt.c/hostkey.c/comp.c/mac.c expose their method structs */
const LIBSSH2_CRYPT_METHOD **libssh2_crypt_methods(void);
const LIBSSH2_HOSTKEY_METHOD **libssh2_hostkey_methods(void);
const LIBSSH2_COMP_METHOD **libssh2_comp_methods(void);
const LIBSSH2_MAC_METHOD **libssh2_mac_methods(void);
/* Language API doesn't exist yet. Just act like we've agreed on a language */
#define libssh2_kex_agree_lang(session, endpoint, str, str_len) 0
/* pem.c */
int _libssh2_pem_parse (LIBSSH2_SESSION *session,
const char *headerbegin,
const char *headerend,
FILE *fp,
char **data, unsigned int *datalen);
int _libssh2_pem_decode_sequence (unsigned char **data, unsigned int *datalen);
int _libssh2_pem_decode_integer (unsigned char **data, unsigned int *datalen,
unsigned char **i, unsigned int *ilen);
#endif /* LIBSSH2_H */

View File

@@ -1,4 +1,4 @@
/* Copyright (c) 2004-2005, Sara Golemon <sarag@libssh2.org> /* Copyright (c) 2004-2007, Sara Golemon <sarag@libssh2.org>
* All rights reserved. * All rights reserved.
* *
* Redistribution and use in source and binary forms, * Redistribution and use in source and binary forms,
@@ -36,7 +36,6 @@
*/ */
#include "libssh2_priv.h" #include "libssh2_priv.h"
#include <openssl/hmac.h>
#ifdef LIBSSH2_MAC_NONE #ifdef LIBSSH2_MAC_NONE
/* {{{ libssh2_mac_none_MAC /* {{{ libssh2_mac_none_MAC
@@ -68,6 +67,7 @@ static int libssh2_mac_method_common_init(LIBSSH2_SESSION *session, unsigned cha
{ {
*abstract = key; *abstract = key;
*free_key = 0; *free_key = 0;
(void)session;
return 0; return 0;
} }
@@ -94,25 +94,26 @@ static int libssh2_mac_method_hmac_sha1_hash(LIBSSH2_SESSION *session, unsigned
const unsigned char *packet, unsigned long packet_len, const unsigned char *packet, unsigned long packet_len,
const unsigned char *addtl, unsigned long addtl_len, void **abstract) const unsigned char *addtl, unsigned long addtl_len, void **abstract)
{ {
HMAC_CTX ctx; libssh2_hmac_ctx ctx;
unsigned char seqno_buf[4]; unsigned char seqno_buf[4];
(void)session;
libssh2_htonu32(seqno_buf, seqno); libssh2_htonu32(seqno_buf, seqno);
HMAC_Init(&ctx, *abstract, 20, EVP_sha1()); libssh2_hmac_sha1_init(&ctx, *abstract, 20);
HMAC_Update(&ctx, seqno_buf, 4); libssh2_hmac_update(ctx, seqno_buf, 4);
HMAC_Update(&ctx, packet, packet_len); libssh2_hmac_update(ctx, packet, packet_len);
if (addtl && addtl_len) { if (addtl && addtl_len) {
HMAC_Update(&ctx, addtl, addtl_len); libssh2_hmac_update(ctx, addtl, addtl_len);
} }
HMAC_Final(&ctx, buf, NULL); libssh2_hmac_final(ctx, buf);
HMAC_cleanup(&ctx); libssh2_hmac_cleanup(&ctx);
return 0; return 0;
} }
/* }}} */ /* }}} */
static LIBSSH2_MAC_METHOD libssh2_mac_method_hmac_sha1 = { static const LIBSSH2_MAC_METHOD libssh2_mac_method_hmac_sha1 = {
"hmac-sha1", "hmac-sha1",
20, 20,
20, 20,
@@ -128,16 +129,16 @@ static int libssh2_mac_method_hmac_sha1_96_hash(LIBSSH2_SESSION *session, unsign
const unsigned char *packet, unsigned long packet_len, const unsigned char *packet, unsigned long packet_len,
const unsigned char *addtl, unsigned long addtl_len, void **abstract) const unsigned char *addtl, unsigned long addtl_len, void **abstract)
{ {
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, addtl, addtl_len, abstract);
memcpy(buf, temp, 96 / 8); memcpy(buf, (char *)temp, 96 / 8);
return 0; return 0;
} }
/* }}} */ /* }}} */
static LIBSSH2_MAC_METHOD libssh2_mac_method_hmac_sha1_96 = { static const LIBSSH2_MAC_METHOD libssh2_mac_method_hmac_sha1_96 = {
"hmac-sha1-96", "hmac-sha1-96",
12, 12,
20, 20,
@@ -153,25 +154,26 @@ static int libssh2_mac_method_hmac_md5_hash(LIBSSH2_SESSION *session, unsigned c
const unsigned char *packet, unsigned long packet_len, const unsigned char *packet, unsigned long packet_len,
const unsigned char *addtl, unsigned long addtl_len, void **abstract) const unsigned char *addtl, unsigned long addtl_len, void **abstract)
{ {
HMAC_CTX ctx; libssh2_hmac_ctx ctx;
unsigned char seqno_buf[4]; unsigned char seqno_buf[4];
(void)session;
libssh2_htonu32(seqno_buf, seqno); libssh2_htonu32(seqno_buf, seqno);
HMAC_Init(&ctx, *abstract, 16, EVP_md5()); libssh2_hmac_md5_init(&ctx, *abstract, 16);
HMAC_Update(&ctx, seqno_buf, 4); libssh2_hmac_update(ctx, seqno_buf, 4);
HMAC_Update(&ctx, packet, packet_len); libssh2_hmac_update(ctx, packet, packet_len);
if (addtl && addtl_len) { if (addtl && addtl_len) {
HMAC_Update(&ctx, addtl, addtl_len); libssh2_hmac_update(ctx, addtl, addtl_len);
} }
HMAC_Final(&ctx, buf, NULL); libssh2_hmac_final(ctx, buf);
HMAC_cleanup(&ctx); libssh2_hmac_cleanup(&ctx);
return 0; return 0;
} }
/* }}} */ /* }}} */
static LIBSSH2_MAC_METHOD libssh2_mac_method_hmac_md5 = { static const LIBSSH2_MAC_METHOD libssh2_mac_method_hmac_md5 = {
"hmac-md5", "hmac-md5",
16, 16,
16, 16,
@@ -187,16 +189,16 @@ static int libssh2_mac_method_hmac_md5_96_hash(LIBSSH2_SESSION *session, unsigne
const unsigned char *packet, unsigned long packet_len, const unsigned char *packet, unsigned long packet_len,
const unsigned char *addtl, unsigned long addtl_len, void **abstract) const unsigned char *addtl, unsigned long addtl_len, void **abstract)
{ {
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, addtl, addtl_len, abstract);
memcpy(buf, temp, 96 / 8); memcpy(buf, (char *)temp, 96 / 8);
return 0; return 0;
} }
/* }}} */ /* }}} */
static LIBSSH2_MAC_METHOD libssh2_mac_method_hmac_md5_96 = { static const LIBSSH2_MAC_METHOD libssh2_mac_method_hmac_md5_96 = {
"hmac-md5-96", "hmac-md5-96",
12, 12,
16, 16,
@@ -205,7 +207,7 @@ static LIBSSH2_MAC_METHOD libssh2_mac_method_hmac_md5_96 = {
libssh2_mac_method_common_dtor, libssh2_mac_method_common_dtor,
}; };
#ifndef OPENSSL_NO_RIPEMD #if LIBSSH2_HMAC_RIPEMD
/* {{{ libssh2_mac_method_hmac_ripemd160_hash /* {{{ libssh2_mac_method_hmac_ripemd160_hash
* Calculate hash using ripemd160 value * Calculate hash using ripemd160 value
*/ */
@@ -213,25 +215,26 @@ static int libssh2_mac_method_hmac_ripemd160_hash(LIBSSH2_SESSION *session, unsi
const unsigned char *packet, unsigned long packet_len, const unsigned char *packet, unsigned long packet_len,
const unsigned char *addtl, unsigned long addtl_len, void **abstract) const unsigned char *addtl, unsigned long addtl_len, void **abstract)
{ {
HMAC_CTX ctx; libssh2_hmac_ctx ctx;
unsigned char seqno_buf[4]; unsigned char seqno_buf[4];
(void)session;
libssh2_htonu32(seqno_buf, seqno); libssh2_htonu32(seqno_buf, seqno);
HMAC_Init(&ctx, *abstract, 20, EVP_ripemd160()); libssh2_hmac_ripemd160_init(&ctx, *abstract, 20);
HMAC_Update(&ctx, seqno_buf, 4); libssh2_hmac_update(ctx, seqno_buf, 4);
HMAC_Update(&ctx, packet, packet_len); libssh2_hmac_update(ctx, packet, packet_len);
if (addtl && addtl_len) { if (addtl && addtl_len) {
HMAC_Update(&ctx, addtl, addtl_len); libssh2_hmac_update(ctx, addtl, addtl_len);
} }
HMAC_Final(&ctx, buf, NULL); libssh2_hmac_final(ctx, buf);
HMAC_cleanup(&ctx); libssh2_hmac_cleanup(&ctx);
return 0; return 0;
} }
/* }}} */ /* }}} */
static LIBSSH2_MAC_METHOD libssh2_mac_method_hmac_ripemd160 = { static const LIBSSH2_MAC_METHOD libssh2_mac_method_hmac_ripemd160 = {
"hmac-ripemd160", "hmac-ripemd160",
20, 20,
20, 20,
@@ -240,7 +243,7 @@ static LIBSSH2_MAC_METHOD libssh2_mac_method_hmac_ripemd160 = {
libssh2_mac_method_common_dtor, libssh2_mac_method_common_dtor,
}; };
static LIBSSH2_MAC_METHOD libssh2_mac_method_hmac_ripemd160_openssh_com = { static const LIBSSH2_MAC_METHOD libssh2_mac_method_hmac_ripemd160_openssh_com = {
"hmac-ripemd160@openssh.com", "hmac-ripemd160@openssh.com",
20, 20,
20, 20,
@@ -248,24 +251,24 @@ static LIBSSH2_MAC_METHOD libssh2_mac_method_hmac_ripemd160_openssh_com = {
libssh2_mac_method_hmac_ripemd160_hash, libssh2_mac_method_hmac_ripemd160_hash,
libssh2_mac_method_common_dtor, libssh2_mac_method_common_dtor,
}; };
#endif /* ! OPENSSL_NO_RIPEMD */ #endif /* LIBSSH2_HMAC_RIPEMD */
static LIBSSH2_MAC_METHOD *_libssh2_mac_methods[] = { static const LIBSSH2_MAC_METHOD *_libssh2_mac_methods[] = {
&libssh2_mac_method_hmac_sha1, &libssh2_mac_method_hmac_sha1,
&libssh2_mac_method_hmac_sha1_96, &libssh2_mac_method_hmac_sha1_96,
&libssh2_mac_method_hmac_md5, &libssh2_mac_method_hmac_md5,
&libssh2_mac_method_hmac_md5_96, &libssh2_mac_method_hmac_md5_96,
#ifndef OPENSSL_NO_RIPEMD #ifdef LIBSSH2_HMAC_RIPEMD
&libssh2_mac_method_hmac_ripemd160, &libssh2_mac_method_hmac_ripemd160,
&libssh2_mac_method_hmac_ripemd160_openssh_com, &libssh2_mac_method_hmac_ripemd160_openssh_com,
#endif /* ! OPENSSL_NO_RIPEMD */ #endif /* LIBSSH2_HMAC_RIPEMD */
#ifdef LIBSSH2_MAC_NONE #ifdef LIBSSH2_MAC_NONE
&libssh2_mac_method_none, &libssh2_mac_method_none,
#endif /* LIBSSH2_MAC_NONE */ #endif /* LIBSSH2_MAC_NONE */
NULL NULL
}; };
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

@@ -1,4 +1,4 @@
/* Copyright (c) 2004-2005, Sara Golemon <sarag@libssh2.org> /* Copyright (c) 2004-2007, Sara Golemon <sarag@libssh2.org>
* All rights reserved. * All rights reserved.
* *
* Redistribution and use in source and binary forms, * Redistribution and use in source and binary forms,
@@ -36,6 +36,9 @@
*/ */
#include "libssh2_priv.h" #include "libssh2_priv.h"
#ifdef HAVE_UNISTD_H
#include <unistd.h>
#endif
/* {{{ libssh2_ntohu32 /* {{{ libssh2_ntohu32
*/ */
@@ -126,19 +129,20 @@ static const short libssh2_base64_reverse_table[256] = {
/* {{{ 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, int *datalen, LIBSSH2_API int libssh2_base64_decode(LIBSSH2_SESSION *session, char **data, unsigned int *datalen,
char *src, int src_len) 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 = d = LIBSSH2_ALLOC(session, (3 * src_len / 4) + 1); *data = LIBSSH2_ALLOC(session, (3 * src_len / 4) + 1);
d = (unsigned char *)*data;
if (!d) { if (!d) {
return -1; return -1;
} }
for(s = 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:
@@ -169,19 +173,23 @@ LIBSSH2_API int libssh2_base64_decode(LIBSSH2_SESSION *session, char **data, int
} }
/* }}} */ /* }}} */
#ifdef LIBSSH2_DEBUG_ENABLED #ifdef LIBSSH2DEBUG
/* {{{ _libssh2_debug LIBSSH2_API int libssh2_trace(LIBSSH2_SESSION *session, int bitmask)
* Internal debug logging facility {
* Just writes to stderr until a good reason comes up to support anything else session->showmask = bitmask;
*/ return 0;
void _libssh2_debug(LIBSSH2_SESSION *session, int context, const char *format, ...) }
void _libssh2_debug(LIBSSH2_SESSION *session, int context,
const char *format, ...)
{ {
char buffer[1536]; char buffer[1536];
int len; int len;
va_list vargs; va_list vargs;
char *contexts[9] = { "Unknown", static const char * const contexts[9] = {
"Unknown",
"Transport", "Transport",
"Key Exhange", "Key Exchange",
"Userauth", "Userauth",
"Connection", "Connection",
"scp", "scp",
@@ -193,6 +201,10 @@ void _libssh2_debug(LIBSSH2_SESSION *session, int context, const char *format, .
if (context < 1 || context > 8) { if (context < 1 || context > 8) {
context = 0; context = 0;
} }
if(!(session->showmask & (1<<context))) {
/* no such output asked for */
return;
}
len = snprintf(buffer, 1535, "[libssh2] %s: ", contexts[context]); len = snprintf(buffer, 1535, "[libssh2] %s: ", contexts[context]);
@@ -201,6 +213,14 @@ void _libssh2_debug(LIBSSH2_SESSION *session, int context, const char *format, .
buffer[len] = '\n'; buffer[len] = '\n';
va_end(vargs); va_end(vargs);
write(2, buffer, len + 1); write(2, buffer, len + 1);
}
#else
LIBSSH2_API int libssh2_trace(LIBSSH2_SESSION *session, int bitmask)
{
(void)session;
(void)bitmask;
return 0;
} }
/* }}} */
#endif #endif

318
src/openssl.c Normal file
View File

@@ -0,0 +1,318 @@
/* Copyright (C) 2006, 2007 The Written Word, Inc. All rights reserved.
* Author: Simon Josefsson
* Copyright (c) 2004-2006, Sara Golemon <sarag@libssh2.org>
*
* Redistribution and use in source and binary forms,
* with or without modification, are permitted provided
* that the following conditions are met:
*
* Redistributions of source code must retain the above
* copyright notice, this list of conditions and the
* following disclaimer.
*
* Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following
* disclaimer in the documentation and/or other materials
* provided with the distribution.
*
* Neither the name of the copyright holder nor the names
* of any other contributors may be used to endorse or
* promote products derived from this software without
* specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
* CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
* USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
* OF SUCH DAMAGE.
*/
#include "libssh2_priv.h"
#include <string.h>
#ifndef EVP_MAX_BLOCK_LENGTH
#define EVP_MAX_BLOCK_LENGTH 32
#endif
int _libssh2_rsa_new(libssh2_rsa_ctx **rsa,
const unsigned char *edata,
unsigned long elen,
const unsigned char *ndata,
unsigned long nlen,
const unsigned char *ddata,
unsigned long dlen,
const unsigned char *pdata,
unsigned long plen,
const unsigned char *qdata,
unsigned long qlen,
const unsigned char *e1data,
unsigned long e1len,
const unsigned char *e2data,
unsigned long e2len,
const unsigned char *coeffdata,
unsigned long coefflen)
{
*rsa = RSA_new();
(*rsa)->e = BN_new();
BN_bin2bn(edata, elen, (*rsa)->e);
(*rsa)->n = BN_new();
BN_bin2bn(ndata, nlen, (*rsa)->n);
if (ddata) {
(*rsa)->d = BN_new();
BN_bin2bn(ddata, dlen, (*rsa)->d);
(*rsa)->p = BN_new();
BN_bin2bn(pdata, plen, (*rsa)->p);
(*rsa)->q = BN_new();
BN_bin2bn(qdata, qlen, (*rsa)->q);
(*rsa)->dmp1 = BN_new();
BN_bin2bn(e1data, e1len, (*rsa)->dmp1);
(*rsa)->dmq1 = BN_new();
BN_bin2bn(e2data, e2len, (*rsa)->dmq1);
(*rsa)->iqmp = BN_new();
BN_bin2bn(coeffdata, coefflen, (*rsa)->iqmp);
}
return 0;
}
int _libssh2_rsa_sha1_verify(libssh2_rsa_ctx *rsactx,
const unsigned char *sig,
unsigned long sig_len,
const unsigned char *m,
unsigned long m_len)
{
unsigned char hash[SHA_DIGEST_LENGTH];
int ret;
SHA1(m, m_len, hash);
ret = RSA_verify(NID_sha1, hash, SHA_DIGEST_LENGTH,
(unsigned char *)sig, sig_len, rsactx);
return (ret == 1) ? 0 : -1;
}
int _libssh2_dsa_new(libssh2_dsa_ctx **dsactx,
const unsigned char *p,
unsigned long p_len,
const unsigned char *q,
unsigned long q_len,
const unsigned char *g,
unsigned long g_len,
const unsigned char *y,
unsigned long y_len,
const unsigned char *x,
unsigned long x_len)
{
*dsactx = DSA_new();
(*dsactx)->p = BN_new();
BN_bin2bn(p, p_len, (*dsactx)->p);
(*dsactx)->q = BN_new();
BN_bin2bn(q, q_len, (*dsactx)->q);
(*dsactx)->g = BN_new();
BN_bin2bn(g, g_len, (*dsactx)->g);
(*dsactx)->pub_key = BN_new();
BN_bin2bn(y, y_len, (*dsactx)->pub_key);
if (x_len) {
(*dsactx)->priv_key = BN_new();
BN_bin2bn(x, x_len, (*dsactx)->priv_key);
}
return 0;
}
int _libssh2_dsa_sha1_verify(libssh2_dsa_ctx *dsactx,
const unsigned char *sig,
const unsigned char *m,
unsigned long m_len)
{
unsigned char hash[SHA_DIGEST_LENGTH];
DSA_SIG dsasig;
int ret;
dsasig.r = BN_new();
BN_bin2bn(sig, 20, dsasig.r);
dsasig.s = BN_new();
BN_bin2bn(sig + 20, 20, dsasig.s);
libssh2_sha1(m, m_len, hash);
ret = DSA_do_verify(hash, SHA_DIGEST_LENGTH, &dsasig, dsactx);
BN_clear_free(dsasig.s);
BN_clear_free(dsasig.r);
return (ret == 1) ? 0 : -1;
}
int _libssh2_cipher_init (_libssh2_cipher_ctx *h,
_libssh2_cipher_type(algo),
unsigned char *iv,
unsigned char *secret,
int encrypt)
{
EVP_CIPHER_CTX_init(h);
EVP_CipherInit(h, algo(), secret, iv, encrypt);
return 0;
}
int _libssh2_cipher_crypt(_libssh2_cipher_ctx *ctx,
_libssh2_cipher_type(algo),
int encrypt,
unsigned char *block)
{
int blocksize = ctx->cipher->block_size;
unsigned char buf[EVP_MAX_BLOCK_LENGTH];
int ret;
(void)algo;
(void)encrypt;
if (blocksize == 1) {
/* Hack for arcfour. */
blocksize = 8;
}
ret = EVP_Cipher(ctx, buf, block, blocksize);
if (ret == 1) {
memcpy(block, buf, blocksize);
}
return ret == 1 ? 0 : 1;
}
/* TODO: Optionally call a passphrase callback specified by the
* calling program
*/
static int
passphrase_cb(char *buf, int size,
int rwflag, char *passphrase)
{
int passphrase_len = strlen(passphrase);
(void)rwflag;
if (passphrase_len > (size - 1)) {
passphrase_len = size - 1;
}
memcpy(buf, passphrase, passphrase_len);
buf[passphrase_len] = '\0';
return passphrase_len;
}
int _libssh2_rsa_new_private (libssh2_rsa_ctx **rsa,
LIBSSH2_SESSION *session,
FILE *fp,
unsigned const char *passphrase)
{
(void)session;
if (!EVP_get_cipherbyname("des")) {
/* 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 ($#&%#$(%$#(
* Someone buy me an OpenSSL manual and I'll read up on it.
*/
OpenSSL_add_all_ciphers();
}
*rsa = PEM_read_RSAPrivateKey(fp, NULL, (void*)passphrase_cb,
(void*)passphrase);
if (!*rsa) {
return -1;
}
return 0;
}
int _libssh2_dsa_new_private (libssh2_dsa_ctx **dsa,
LIBSSH2_SESSION *session,
FILE *fp,
unsigned const char *passphrase)
{
(void)session;
if (!EVP_get_cipherbyname("des")) {
/* 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 ($#&%#$(%$#(
* Someone buy me an OpenSSL manual and I'll read up on it.
*/
OpenSSL_add_all_ciphers();
}
*dsa = PEM_read_DSAPrivateKey(fp, NULL, (void*)passphrase_cb,
(void*)passphrase);
if (!*dsa) {
return -1;
}
return 0;
}
int _libssh2_rsa_sha1_sign(LIBSSH2_SESSION *session,
libssh2_rsa_ctx *rsactx,
const unsigned char *hash,
unsigned long hash_len,
unsigned char **signature,
unsigned long *signature_len)
{
int ret;
unsigned char *sig;
unsigned int sig_len;
sig_len = RSA_size(rsactx);
sig = LIBSSH2_ALLOC(session, sig_len);
if (!sig) {
return -1;
}
ret = RSA_sign(NID_sha1, hash, hash_len, sig, &sig_len, rsactx);
if (!ret) {
LIBSSH2_FREE(session, sig);
return -1;
}
*signature = sig;
*signature_len = sig_len;
return 0;
}
int _libssh2_dsa_sha1_sign(libssh2_dsa_ctx *dsactx,
const unsigned char *hash,
unsigned long hash_len,
unsigned char *signature)
{
DSA_SIG *sig;
int r_len, s_len, rs_pad;
(void)hash_len;
sig = DSA_do_sign(hash, SHA_DIGEST_LENGTH, dsactx);
if (!sig) {
return -1;
}
r_len = BN_num_bytes(sig->r);
s_len = BN_num_bytes(sig->s);
rs_pad = (2 * SHA_DIGEST_LENGTH) - (r_len + s_len);
if (rs_pad < 0) {
DSA_SIG_free(sig);
return -1;
}
BN_bn2bin(sig->r, signature + rs_pad);
BN_bn2bin(sig->s, signature + rs_pad + r_len);
DSA_SIG_free(sig);
return 0;
}

233
src/openssl.h Normal file
View File

@@ -0,0 +1,233 @@
/* Copyright (C) 2006, 2007 The Written Word, Inc. All rights reserved.
* Author: Simon Josefsson
*
* Redistribution and use in source and binary forms,
* with or without modification, are permitted provided
* that the following conditions are met:
*
* Redistributions of source code must retain the above
* copyright notice, this list of conditions and the
* following disclaimer.
*
* Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following
* disclaimer in the documentation and/or other materials
* provided with the distribution.
*
* Neither the name of the copyright holder nor the names
* of any other contributors may be used to endorse or
* promote products derived from this software without
* specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
* CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
* USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
* OF SUCH DAMAGE.
*/
#include <openssl/opensslconf.h>
#include <openssl/sha.h>
#ifndef OPENSSL_NO_MD5
#include <openssl/md5.h>
#endif
#include <openssl/evp.h>
#include <openssl/hmac.h>
#include <openssl/bn.h>
#include <openssl/pem.h>
#include <openssl/rand.h>
#ifdef OPENSSL_NO_RSA
# define LIBSSH2_RSA 0
#else
# define LIBSSH2_RSA 1
#endif
#ifdef OPENSSL_NO_DSA
# define LIBSSH2_DSA 0
#else
# define LIBSSH2_DSA 1
#endif
#ifdef OPENSSL_NO_MD5
# define LIBSSH2_MD5 0
#else
# define LIBSSH2_MD5 1
#endif
#ifdef OPENSSL_NO_RIPEMD
# define LIBSSH2_HMAC_RIPEMD 0
#else
# define LIBSSH2_HMAC_RIPEMD 1
#endif
#if OPENSSL_VERSION_NUMBER >= 0x00907000L && !defined(OPENSSL_NO_AES)
# define LIBSSH2_AES 1
#else
# define LIBSSH2_AES 0
#endif
#ifdef OPENSSL_NO_BLOWFISH
# define LIBSSH2_BLOWFISH 0
#else
# define LIBSSH2_BLOWFISH 1
#endif
#ifdef OPENSSL_NO_RC4
# define LIBSSH2_RC4 0
#else
# define LIBSSH2_RC4 1
#endif
#ifdef OPENSSL_NO_CAST
# define LIBSSH2_CAST 0
#else
# define LIBSSH2_CAST 1
#endif
#ifdef OPENSSL_NO_DES
# define LIBSSH2_3DES 0
#else
# define LIBSSH2_3DES 1
#endif
#define libssh2_random(buf, len) \
RAND_bytes ((buf), (len))
#define libssh2_sha1_ctx SHA_CTX
#define libssh2_sha1_init(ctx) SHA1_Init(ctx)
#define libssh2_sha1_update(ctx, data, len) SHA1_Update(&(ctx), data, len)
#define libssh2_sha1_final(ctx, out) SHA1_Final(out, &(ctx))
#define libssh2_sha1(message, len, out) SHA1(message, len, out)
#define libssh2_md5_ctx MD5_CTX
#define libssh2_md5_init(ctx) MD5_Init(ctx)
#define libssh2_md5_update(ctx, data, len) MD5_Update(&(ctx), data, len)
#define libssh2_md5_final(ctx, out) MD5_Final(out, &(ctx))
#define libssh2_md5(message, len, out) MD5(message, len, out)
#define libssh2_hmac_ctx HMAC_CTX
#define libssh2_hmac_sha1_init(ctx, key, keylen) \
HMAC_Init(ctx, key, keylen, EVP_sha1())
#define libssh2_hmac_md5_init(ctx, key, keylen) \
HMAC_Init(ctx, key, keylen, EVP_md5())
#define libssh2_hmac_ripemd160_init(ctx, key, keylen) \
HMAC_Init(ctx, key, keylen, EVP_ripemd160())
#define libssh2_hmac_update(ctx, data, datalen) \
HMAC_Update(&(ctx), data, datalen)
#define libssh2_hmac_final(ctx, data) HMAC_Final(&(ctx), data, NULL)
#define libssh2_hmac_cleanup(ctx) HMAC_cleanup(ctx)
#define libssh2_crypto_init()
#define libssh2_rsa_ctx RSA
int _libssh2_rsa_new(libssh2_rsa_ctx **rsa,
const unsigned char *edata,
unsigned long elen,
const unsigned char *ndata,
unsigned long nlen,
const unsigned char *ddata,
unsigned long dlen,
const unsigned char *pdata,
unsigned long plen,
const unsigned char *qdata,
unsigned long qlen,
const unsigned char *e1data,
unsigned long e1len,
const unsigned char *e2data,
unsigned long e2len,
const unsigned char *coeffdata,
unsigned long coefflen);
int _libssh2_rsa_new_private (libssh2_rsa_ctx **rsa,
LIBSSH2_SESSION *session,
FILE *fp,
unsigned const char *passphrase);
int _libssh2_rsa_sha1_verify(libssh2_rsa_ctx *rsa,
const unsigned char *sig,
unsigned long sig_len,
const unsigned char *m,
unsigned long m_len);
int _libssh2_rsa_sha1_sign(LIBSSH2_SESSION *session,
libssh2_rsa_ctx *rsactx,
const unsigned char *hash,
unsigned long hash_len,
unsigned char **signature,
unsigned long *signature_len);
#define _libssh2_rsa_free(rsactx) RSA_free(rsactx)
#define libssh2_dsa_ctx DSA
int _libssh2_dsa_new(libssh2_dsa_ctx **dsa,
const unsigned char *pdata,
unsigned long plen,
const unsigned char *qdata,
unsigned long qlen,
const unsigned char *gdata,
unsigned long glen,
const unsigned char *ydata,
unsigned long ylen,
const unsigned char *x,
unsigned long x_len);
int _libssh2_dsa_new_private (libssh2_dsa_ctx **dsa,
LIBSSH2_SESSION *session,
FILE *fp,
unsigned const char *passphrase);
int _libssh2_dsa_sha1_verify(libssh2_dsa_ctx *dsactx,
const unsigned char *sig,
const unsigned char *m,
unsigned long m_len);
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_cipher_type(name) const EVP_CIPHER *(*name)(void)
#define _libssh2_cipher_ctx EVP_CIPHER_CTX
#define _libssh2_cipher_aes256 EVP_aes_256_cbc
#define _libssh2_cipher_aes192 EVP_aes_192_cbc
#define _libssh2_cipher_aes128 EVP_aes_128_cbc
#define _libssh2_cipher_blowfish EVP_bf_cbc
#define _libssh2_cipher_arcfour EVP_rc4
#define _libssh2_cipher_cast5 EVP_cast5_cbc
#define _libssh2_cipher_3des EVP_des_ede3_cbc
int _libssh2_cipher_init (_libssh2_cipher_ctx *h,
_libssh2_cipher_type(algo),
unsigned char *iv,
unsigned char *secret,
int encrypt);
int _libssh2_cipher_crypt(_libssh2_cipher_ctx *ctx,
_libssh2_cipher_type(algo),
int encrypt,
unsigned char *block);
#define _libssh2_cipher_dtor(ctx) EVP_CIPHER_CTX_cleanup(ctx)
#define _libssh2_bn BIGNUM
#define _libssh2_bn_ctx BN_CTX
#define _libssh2_bn_ctx_new() BN_CTX_new()
#define _libssh2_bn_ctx_free(bnctx) BN_CTX_free(bnctx)
#define _libssh2_bn_init() BN_new()
#define _libssh2_bn_rand(bn, bits, top, bottom) BN_rand(bn, bits, top, bottom)
#define _libssh2_bn_mod_exp(r, a, p, m, ctx) BN_mod_exp(r, a, p, m, ctx)
#define _libssh2_bn_set_word(bn, val) BN_set_word(bn, val)
#define _libssh2_bn_from_bin(bn, len, val) BN_bin2bn(val, len, bn)
#define _libssh2_bn_to_bin(bn, val) BN_bn2bin(bn, val)
#define _libssh2_bn_bytes(bn) BN_num_bytes(bn)
#define _libssh2_bn_bits(bn) BN_num_bits(bn)
#define _libssh2_bn_free(bn) BN_clear_free(bn)

File diff suppressed because it is too large Load Diff

229
src/pem.c Normal file
View File

@@ -0,0 +1,229 @@
/* Copyright (C) 2007 The Written Word, Inc. All rights reserved.
* Author: Simon Josefsson
*
* Redistribution and use in source and binary forms,
* with or without modification, are permitted provided
* that the following conditions are met:
*
* Redistributions of source code must retain the above
* copyright notice, this list of conditions and the
* following disclaimer.
*
* Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following
* disclaimer in the documentation and/or other materials
* provided with the distribution.
*
* Neither the name of the copyright holder nor the names
* of any other contributors may be used to endorse or
* promote products derived from this software without
* specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
* CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
* USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
* OF SUCH DAMAGE.
*/
#include "libssh2_priv.h"
static int readline (char *line, int line_size, FILE *fp)
{
if (!fgets(line, line_size, fp))
{
return -1;
}
if (*line && line[strlen(line) - 1] == '\r')
{
line[strlen(line) - 1] = '\0';
}
if (*line && line[strlen(line) - 1] == '\n')
{
line[strlen(line) - 1] = '\0';
}
return 0;
}
#define LINE_SIZE 128
int _libssh2_pem_parse (LIBSSH2_SESSION *session,
const char *headerbegin,
const char *headerend,
FILE *fp,
char **data, unsigned int *datalen)
{
char line[LINE_SIZE];
char *b64data = NULL;
unsigned int b64datalen = 0;
int ret;
do
{
if (readline(line, LINE_SIZE, fp))
{
return -1;
}
}
while (strcmp (line, headerbegin) != 0);
*line = '\0';
do
{
if (*line)
{
char *tmp;
size_t linelen;
linelen = strlen (line);
tmp = LIBSSH2_REALLOC (session, b64data,
b64datalen + linelen);
if (!tmp)
{
ret = -1;
goto out;
}
memcpy (tmp + b64datalen, line, linelen);
b64data = tmp;
b64datalen += linelen;
}
if (readline(line, LINE_SIZE, fp))
{
ret = -1;
goto out;
}
} while (strcmp (line, headerend) != 0);
if (libssh2_base64_decode(session, data, datalen,
b64data, b64datalen))
{
ret = -1;
goto out;
}
ret = 0;
out:
if (b64data) {
LIBSSH2_FREE (session, b64data);
}
return ret;
}
static int read_asn1_length (const unsigned char *data,
unsigned int datalen,
unsigned int *len)
{
unsigned int lenlen;
int nextpos;
if (datalen < 1)
{
return -1;
}
*len = data[0];
if (*len >= 0x80)
{
lenlen = *len & 0x7F;
*len = data[1];
if (1 + lenlen > datalen)
{
return -1;
}
if (lenlen > 1)
{
*len <<= 8;
*len |= data[2];
}
}
else
{
lenlen = 0;
}
nextpos = 1 + lenlen;
if (lenlen > 2 || 1 + lenlen + *len > datalen)
{
return -1;
}
return nextpos;
}
int _libssh2_pem_decode_sequence (unsigned char **data, unsigned int *datalen)
{
unsigned int len;
int lenlen;
if (*datalen < 1)
{
return -1;
}
if ((*data)[0] != '\x30')
{
return -1;
}
(*data)++;
(*datalen)--;
lenlen = read_asn1_length (*data, *datalen, &len);
if (lenlen < 0 || lenlen + len != *datalen)
{
return -1;
}
*data += lenlen;
*datalen -= lenlen;
return 0;
}
int _libssh2_pem_decode_integer (unsigned char **data, unsigned int *datalen,
unsigned char **i, unsigned int *ilen)
{
unsigned int len;
int lenlen;
if (*datalen < 1)
{
return -1;
}
if ((*data)[0] != '\x02')
{
return -1;
}
(*data)++;
(*datalen)--;
lenlen = read_asn1_length (*data, *datalen, &len);
if (lenlen < 0 || lenlen + len > *datalen)
{
return -1;
}
*data += lenlen;
*datalen -= lenlen;
*i = *data;
*ilen = len;
*data += len;
*datalen -= len;
return 0;
}

View File

@@ -1,4 +1,4 @@
/* Copyright (c) 2004-2005, Sara Golemon <sarag@libssh2.org> /* Copyright (c) 2004-2007, Sara Golemon <sarag@libssh2.org>
* All rights reserved. * All rights reserved.
* *
* Redistribution and use in source and binary forms, * Redistribution and use in source and binary forms,
@@ -52,11 +52,11 @@ struct _LIBSSH2_PUBLICKEY {
typedef struct _LIBSSH2_PUBLICKEY_CODE_LIST { typedef struct _LIBSSH2_PUBLICKEY_CODE_LIST {
int code; int code;
char *name; const char *name;
int name_len; int name_len;
} LIBSSH2_PUBLICKEY_CODE_LIST; } LIBSSH2_PUBLICKEY_CODE_LIST;
static LIBSSH2_PUBLICKEY_CODE_LIST libssh2_publickey_response_codes[] = { static const LIBSSH2_PUBLICKEY_CODE_LIST libssh2_publickey_response_codes[] = {
{ LIBSSH2_PUBLICKEY_RESPONSE_STATUS, "status", sizeof("status") - 1 }, { LIBSSH2_PUBLICKEY_RESPONSE_STATUS, "status", sizeof("status") - 1 },
{ LIBSSH2_PUBLICKEY_RESPONSE_VERSION, "version", sizeof("version") - 1 }, { LIBSSH2_PUBLICKEY_RESPONSE_VERSION, "version", sizeof("version") - 1 },
{ LIBSSH2_PUBLICKEY_RESPONSE_PUBLICKEY, "publickey", sizeof("publickey") - 1 }, { LIBSSH2_PUBLICKEY_RESPONSE_PUBLICKEY, "publickey", sizeof("publickey") - 1 },
@@ -76,7 +76,7 @@ static LIBSSH2_PUBLICKEY_CODE_LIST libssh2_publickey_response_codes[] = {
#define LIBSSH2_PUBLICKEY_STATUS_CODE_MAX 8 #define LIBSSH2_PUBLICKEY_STATUS_CODE_MAX 8
static LIBSSH2_PUBLICKEY_CODE_LIST libssh2_publickey_status_codes[] = { static const LIBSSH2_PUBLICKEY_CODE_LIST libssh2_publickey_status_codes[] = {
{ LIBSSH2_PUBLICKEY_SUCCESS, "success", sizeof("success") - 1 }, { LIBSSH2_PUBLICKEY_SUCCESS, "success", sizeof("success") - 1 },
{ LIBSSH2_PUBLICKEY_ACCESS_DENIED, "access denied", sizeof("access denied") - 1 }, { LIBSSH2_PUBLICKEY_ACCESS_DENIED, "access denied", sizeof("access denied") - 1 },
{ LIBSSH2_PUBLICKEY_STORAGE_EXCEEDED, "storage exceeded", sizeof("storage exceeded") - 1 }, { LIBSSH2_PUBLICKEY_STORAGE_EXCEEDED, "storage exceeded", sizeof("storage exceeded") - 1 },
@@ -95,9 +95,9 @@ static LIBSSH2_PUBLICKEY_CODE_LIST libssh2_publickey_status_codes[] = {
#define LIBSSH2_PUBLICKEY_STATUS_TEXT_START "Publickey Subsystem Error: \"" #define LIBSSH2_PUBLICKEY_STATUS_TEXT_START "Publickey Subsystem Error: \""
#define LIBSSH2_PUBLICKEY_STATUS_TEXT_MID "\" Server Resports: \"" #define LIBSSH2_PUBLICKEY_STATUS_TEXT_MID "\" Server Resports: \""
#define LIBSSH2_PUBLICKEY_STATUS_TEXT_END "\"" #define LIBSSH2_PUBLICKEY_STATUS_TEXT_END "\""
static void libssh2_publickey_status_error(LIBSSH2_PUBLICKEY *pkey, LIBSSH2_SESSION *session, int status, unsigned char *message, int message_len) static void libssh2_publickey_status_error(const LIBSSH2_PUBLICKEY *pkey, LIBSSH2_SESSION *session, int status, const unsigned char *message, int message_len)
{ {
char *status_text; const char *status_text;
int status_text_len; int status_text_len;
char *m, *s; char *m, *s;
int m_len; int m_len;
@@ -147,7 +147,7 @@ static int libssh2_publickey_packet_receive(LIBSSH2_PUBLICKEY *pkey, unsigned ch
unsigned long packet_len; unsigned long packet_len;
unsigned char *packet; unsigned char *packet;
if (libssh2_channel_read(channel, buffer, 4) != 4) { if (_libssh2_channel_read(channel, (char *)buffer, 4) != 4) {
libssh2_error(session, LIBSSH2_ERROR_PUBLICKEY_PROTOCOL, "Invalid response from publickey subsystem", 0); libssh2_error(session, LIBSSH2_ERROR_PUBLICKEY_PROTOCOL, "Invalid response from publickey subsystem", 0);
return -1; return -1;
} }
@@ -159,7 +159,7 @@ static int libssh2_publickey_packet_receive(LIBSSH2_PUBLICKEY *pkey, unsigned ch
return -1; return -1;
} }
if (libssh2_channel_read(channel, packet, packet_len) != packet_len) { if (_libssh2_channel_read(channel, (char *)packet, packet_len) != packet_len) {
libssh2_error(session, LIBSSH2_ERROR_SOCKET_TIMEOUT, "Timeout waiting for publickey subsystem response packet", 0); libssh2_error(session, LIBSSH2_ERROR_SOCKET_TIMEOUT, "Timeout waiting for publickey subsystem response packet", 0);
LIBSSH2_FREE(session, packet); LIBSSH2_FREE(session, packet);
return -1; return -1;
@@ -180,7 +180,7 @@ static int libssh2_publickey_response_id(unsigned char **pdata, int data_len)
{ {
unsigned long response_len; unsigned long response_len;
unsigned char *data = *pdata; unsigned char *data = *pdata;
LIBSSH2_PUBLICKEY_CODE_LIST *codes = libssh2_publickey_response_codes; const LIBSSH2_PUBLICKEY_CODE_LIST *codes = libssh2_publickey_response_codes;
if (data_len < 4) { if (data_len < 4) {
/* Malformed response */ /* Malformed response */
@@ -194,7 +194,7 @@ static int libssh2_publickey_response_id(unsigned char **pdata, int data_len)
while (codes->name) { while (codes->name) {
if (codes->name_len == response_len && if (codes->name_len == response_len &&
strncmp(codes->name, data, response_len) == 0) { strncmp(codes->name, (char *)data, response_len) == 0) {
*pdata = data + response_len; *pdata = data + response_len;
return codes->code; return codes->code;
} }
@@ -212,7 +212,8 @@ static int libssh2_publickey_response_success(LIBSSH2_PUBLICKEY *pkey)
{ {
LIBSSH2_SESSION *session = pkey->channel->session; LIBSSH2_SESSION *session = pkey->channel->session;
unsigned char *data, *s; unsigned char *data, *s;
unsigned long data_len, response; unsigned long data_len;
int response;
while (1) { while (1) {
if (libssh2_publickey_packet_receive(pkey, &data, &data_len)) { if (libssh2_publickey_packet_receive(pkey, &data, &data_len)) {
@@ -288,9 +289,7 @@ LIBSSH2_API LIBSSH2_PUBLICKEY *libssh2_publickey_init(LIBSSH2_SESSION *session)
unsigned long data_len; unsigned long data_len;
int response; int response;
#ifdef LIBSSH2_DEBUG_PUBLICKEY
_libssh2_debug(session, LIBSSH2_DBG_PUBLICKEY, "Initializing publickey subsystem"); _libssh2_debug(session, LIBSSH2_DBG_PUBLICKEY, "Initializing publickey subsystem");
#endif
channel = libssh2_channel_open_session(session); channel = libssh2_channel_open_session(session);
if (!channel) { if (!channel) {
@@ -319,10 +318,8 @@ LIBSSH2_API LIBSSH2_PUBLICKEY *libssh2_publickey_init(LIBSSH2_SESSION *session)
memcpy(s, "version", sizeof("version") - 1); s += sizeof("version") - 1; memcpy(s, "version", sizeof("version") - 1); s += sizeof("version") - 1;
libssh2_htonu32(s, LIBSSH2_PUBLICKEY_VERSION); s += 4; libssh2_htonu32(s, LIBSSH2_PUBLICKEY_VERSION); s += 4;
#ifdef LIBSSH2_DEBUG_PUBLICKEY
_libssh2_debug(session, LIBSSH2_DBG_PUBLICKEY, "Sending publickey version packet advertising version %d support", (int)LIBSSH2_PUBLICKEY_VERSION); _libssh2_debug(session, LIBSSH2_DBG_PUBLICKEY, "Sending publickey version packet advertising version %d support", (int)LIBSSH2_PUBLICKEY_VERSION);
#endif if ((s - buffer) != libssh2_channel_write(channel, (char*)buffer, (s - buffer))) {
if ((s - buffer) != libssh2_channel_write(channel, buffer, (s - buffer))) {
libssh2_error(session, LIBSSH2_ERROR_SOCKET_SEND, "Unable to send publickey version packet", 0); libssh2_error(session, LIBSSH2_ERROR_SOCKET_SEND, "Unable to send publickey version packet", 0);
goto err_exit; goto err_exit;
} }
@@ -364,14 +361,10 @@ LIBSSH2_API LIBSSH2_PUBLICKEY *libssh2_publickey_init(LIBSSH2_SESSION *session)
/* What we want */ /* What we want */
pkey->version = libssh2_ntohu32(s); pkey->version = libssh2_ntohu32(s);
if (pkey->version > LIBSSH2_PUBLICKEY_VERSION) { if (pkey->version > LIBSSH2_PUBLICKEY_VERSION) {
#ifdef LIBSSH2_DEBUG_PUBLICKEY
_libssh2_debug(session, LIBSSH2_DBG_PUBLICKEY, "Truncating remote publickey version from %lu", pkey->version); _libssh2_debug(session, LIBSSH2_DBG_PUBLICKEY, "Truncating remote publickey version from %lu", pkey->version);
#endif
pkey->version = LIBSSH2_PUBLICKEY_VERSION; pkey->version = LIBSSH2_PUBLICKEY_VERSION;
} }
#ifdef LIBSSH2_DEBUG_PUBLICKEY
_libssh2_debug(session, LIBSSH2_DBG_PUBLICKEY, "Enabling publickey subsystem version %lu", pkey->version); _libssh2_debug(session, LIBSSH2_DBG_PUBLICKEY, "Enabling publickey subsystem version %lu", pkey->version);
#endif
LIBSSH2_FREE(session, data); LIBSSH2_FREE(session, data);
return pkey; return pkey;
default: default:
@@ -402,7 +395,7 @@ LIBSSH2_API LIBSSH2_PUBLICKEY *libssh2_publickey_init(LIBSSH2_SESSION *session)
*/ */
LIBSSH2_API int libssh2_publickey_add_ex(LIBSSH2_PUBLICKEY *pkey, const unsigned char *name, unsigned long name_len, LIBSSH2_API int libssh2_publickey_add_ex(LIBSSH2_PUBLICKEY *pkey, const unsigned char *name, unsigned long name_len,
const unsigned char *blob, unsigned long blob_len, char overwrite, const unsigned char *blob, unsigned long blob_len, char overwrite,
unsigned long num_attrs, libssh2_publickey_attribute attrs[]) unsigned long num_attrs, const libssh2_publickey_attribute attrs[])
{ {
LIBSSH2_CHANNEL *channel = pkey->channel; LIBSSH2_CHANNEL *channel = pkey->channel;
LIBSSH2_SESSION *session = channel->session; LIBSSH2_SESSION *session = channel->session;
@@ -418,16 +411,14 @@ LIBSSH2_API int libssh2_publickey_add_ex(LIBSSH2_PUBLICKEY *pkey, const unsigned
blob_len(4) + blob_len(4) +
{blob} */ {blob} */
#ifdef LIBSSH2_DEBUG_PUBLICKEY
_libssh2_debug(session, LIBSSH2_DBG_PUBLICKEY, "Adding %s pubickey", name); _libssh2_debug(session, LIBSSH2_DBG_PUBLICKEY, "Adding %s pubickey", name);
#endif
if (pkey->version == 1) { if (pkey->version == 1) {
for(i = 0; i < num_attrs; i++) { for(i = 0; i < num_attrs; i++) {
/* Search for a comment attribute */ /* Search for a comment attribute */
if (attrs[i].name_len == (sizeof("comment") - 1) && if (attrs[i].name_len == (sizeof("comment") - 1) &&
strncmp(attrs[i].name, "comment", sizeof("comment") - 1) == 0) { strncmp(attrs[i].name, "comment", sizeof("comment") - 1) == 0) {
comment = attrs[i].value; comment = (unsigned char *)attrs[i].value;
comment_len = attrs[i].value_len; comment_len = attrs[i].value_len;
break; break;
} }
@@ -479,10 +470,10 @@ LIBSSH2_API int libssh2_publickey_add_ex(LIBSSH2_PUBLICKEY *pkey, const unsigned
} }
} }
#ifdef LIBSSH2_DEBUG_PUBLICKEY _libssh2_debug(session, LIBSSH2_DBG_PUBLICKEY,
_libssh2_debug(session, LIBSSH2_DBG_PUBLICKEY, "Sending publickey \"add\" packet: type=%s blob_len=%ld num_attrs=%ld", name, blob_len, num_attrs); "Sending publickey \"add\" packet: type=%s blob_len=%ld num_attrs=%ld",
#endif name, blob_len, num_attrs);
if ((s - packet) != libssh2_channel_write(channel, packet, (s - packet))) { if ((s - packet) != libssh2_channel_write(channel, (char *)packet, (s - packet))) {
libssh2_error(session, LIBSSH2_ERROR_SOCKET_SEND, "Unable to send publickey add packet", 0); libssh2_error(session, LIBSSH2_ERROR_SOCKET_SEND, "Unable to send publickey add packet", 0);
LIBSSH2_FREE(session, packet); LIBSSH2_FREE(session, packet);
return -1; return -1;
@@ -527,10 +518,8 @@ LIBSSH2_API int libssh2_publickey_remove_ex(LIBSSH2_PUBLICKEY *pkey, const unsig
libssh2_htonu32(s, blob_len); s += 4; libssh2_htonu32(s, blob_len); s += 4;
memcpy(s, blob, blob_len); s += blob_len; memcpy(s, blob, blob_len); s += blob_len;
#ifdef LIBSSH2_DEBUG_PUBLICKEY
_libssh2_debug(session, LIBSSH2_DBG_PUBLICKEY, "Sending publickey \"remove\" packet: type=%s blob_len=%ld", name, blob_len); _libssh2_debug(session, LIBSSH2_DBG_PUBLICKEY, "Sending publickey \"remove\" packet: type=%s blob_len=%ld", name, blob_len);
#endif if ((s - packet) != libssh2_channel_write(channel, (char *)packet, (s - packet))) {
if ((s - packet) != libssh2_channel_write(channel, packet, (s - packet))) {
libssh2_error(session, LIBSSH2_ERROR_SOCKET_SEND, "Unable to send publickey remove packet", 0); libssh2_error(session, LIBSSH2_ERROR_SOCKET_SEND, "Unable to send publickey remove packet", 0);
LIBSSH2_FREE(session, packet); LIBSSH2_FREE(session, packet);
return -1; return -1;
@@ -551,20 +540,19 @@ LIBSSH2_API int libssh2_publickey_list_fetch(LIBSSH2_PUBLICKEY *pkey, unsigned l
LIBSSH2_SESSION *session = channel->session; LIBSSH2_SESSION *session = channel->session;
libssh2_publickey_list *list = NULL; libssh2_publickey_list *list = NULL;
unsigned char *s, buffer[12], *data = NULL; unsigned char *s, buffer[12], *data = NULL;
unsigned long buffer_len = 12, keys = 0, max_keys = 0, data_len, i, response; unsigned long buffer_len = 12, keys = 0, max_keys = 0, data_len, i;
/* packet_len(4) + /* packet_len(4) +
list_len(4) + list_len(4) +
"list"(4) */ "list"(4) */
int response;
s = buffer; s = buffer;
libssh2_htonu32(s, buffer_len - 4); s += 4; libssh2_htonu32(s, buffer_len - 4); s += 4;
libssh2_htonu32(s, sizeof("list") - 1); s += 4; libssh2_htonu32(s, sizeof("list") - 1); s += 4;
memcpy(s, "list", sizeof("list") - 1); s += sizeof("list") - 1; memcpy(s, "list", sizeof("list") - 1); s += sizeof("list") - 1;
#ifdef LIBSSH2_DEBUG_PUBLICKEY
_libssh2_debug(session, LIBSSH2_DBG_PUBLICKEY, "Sending publickey \"list\" packet"); _libssh2_debug(session, LIBSSH2_DBG_PUBLICKEY, "Sending publickey \"list\" packet");
#endif if ((s - buffer) != libssh2_channel_write(channel, (char *)buffer, (s - buffer))) {
if ((s - buffer) != libssh2_channel_write(channel, buffer, (s - buffer))) {
libssh2_error(session, LIBSSH2_ERROR_SOCKET_SEND, "Unable to send publickey list packet", 0); libssh2_error(session, LIBSSH2_ERROR_SOCKET_SEND, "Unable to send publickey list packet", 0);
return -1; return -1;
} }
@@ -612,13 +600,15 @@ LIBSSH2_API int libssh2_publickey_list_fetch(LIBSSH2_PUBLICKEY *pkey, unsigned l
case LIBSSH2_PUBLICKEY_RESPONSE_PUBLICKEY: case LIBSSH2_PUBLICKEY_RESPONSE_PUBLICKEY:
/* What we want */ /* What we want */
if (keys >= max_keys) { if (keys >= max_keys) {
libssh2_publickey_list *newlist;
/* Grow the key list if necessary */ /* Grow the key list if necessary */
max_keys += 8; max_keys += 8;
list = LIBSSH2_REALLOC(session, list, (max_keys + 1) * sizeof(libssh2_publickey_list)); newlist = LIBSSH2_REALLOC(session, list, (max_keys + 1) * sizeof(libssh2_publickey_list));
if (!list) { if (!newlist) {
libssh2_error(session, LIBSSH2_ERROR_ALLOC, "Unable to allocate memory for publickey list", 0); libssh2_error(session, LIBSSH2_ERROR_ALLOC, "Unable to allocate memory for publickey list", 0);
goto err_exit; goto err_exit;
} }
list = newlist;
} }
if (pkey->version == 1) { if (pkey->version == 1) {
unsigned long comment_len; unsigned long comment_len;
@@ -633,7 +623,7 @@ LIBSSH2_API int libssh2_publickey_list_fetch(LIBSSH2_PUBLICKEY *pkey, unsigned l
} }
list[keys].attrs[0].name = "comment"; list[keys].attrs[0].name = "comment";
list[keys].attrs[0].name_len = sizeof("comment") - 1; list[keys].attrs[0].name_len = sizeof("comment") - 1;
list[keys].attrs[0].value = s; list[keys].attrs[0].value = (char *)s;
list[keys].attrs[0].value_len = comment_len; list[keys].attrs[0].value_len = comment_len;
list[keys].attrs[0].mandatory = 0; list[keys].attrs[0].mandatory = 0;
@@ -661,9 +651,9 @@ LIBSSH2_API int libssh2_publickey_list_fetch(LIBSSH2_PUBLICKEY *pkey, unsigned l
} }
for(i = 0; i < list[keys].num_attrs; i++) { for(i = 0; i < list[keys].num_attrs; i++) {
list[keys].attrs[i].name_len = libssh2_ntohu32(s); s += 4; list[keys].attrs[i].name_len = libssh2_ntohu32(s); s += 4;
list[keys].attrs[i].name = s; s += list[keys].attrs[i].name_len; list[keys].attrs[i].name = (char *)s; s += list[keys].attrs[i].name_len;
list[keys].attrs[i].value_len = libssh2_ntohu32(s); s += 4; list[keys].attrs[i].value_len = libssh2_ntohu32(s); s += 4;
list[keys].attrs[i].value = s; s += list[keys].attrs[i].value_len; list[keys].attrs[i].value = (char *)s; s += list[keys].attrs[i].value_len;
list[keys].attrs[i].mandatory = 0; /* actually an ignored value */ list[keys].attrs[i].mandatory = 0; /* actually an ignored value */
} }
} else { } else {

View File

@@ -1,4 +1,4 @@
/* Copyright (c) 2004-2005, Sara Golemon <sarag@libssh2.org> /* Copyright (c) 2004-2007, Sara Golemon <sarag@libssh2.org>
* All rights reserved. * All rights reserved.
* *
* Redistribution and use in source and binary forms, * Redistribution and use in source and binary forms,
@@ -42,9 +42,12 @@
#define LIBSSH2_SCP_RESPONSE_BUFLEN 256 #define LIBSSH2_SCP_RESPONSE_BUFLEN 256
/* {{{ libssh2_scp_recv /* {{{ libssh2_scp_recv
* [BLOCKING]
* Open a channel and request a remote file via SCP * Open a channel and request a remote file via SCP
*/ */
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);
unsigned char *command, response[LIBSSH2_SCP_RESPONSE_BUFLEN]; unsigned char *command, response[LIBSSH2_SCP_RESPONSE_BUFLEN];
@@ -70,9 +73,7 @@ LIBSSH2_API LIBSSH2_CHANNEL *libssh2_scp_recv(LIBSSH2_SESSION *session, const ch
} }
command[command_len - 1] = '\0'; command[command_len - 1] = '\0';
#ifdef LIBSSH2_DEBUG_SCP
_libssh2_debug(session, LIBSSH2_DBG_SCP, "Opening channel for SCP receive"); _libssh2_debug(session, LIBSSH2_DBG_SCP, "Opening channel for SCP receive");
#endif
/* Allocate a channel */ /* Allocate a channel */
if ((channel = libssh2_channel_open_session(session)) == NULL) { if ((channel = libssh2_channel_open_session(session)) == NULL) {
LIBSSH2_FREE(session, command); LIBSSH2_FREE(session, command);
@@ -89,9 +90,7 @@ LIBSSH2_API LIBSSH2_CHANNEL *libssh2_scp_recv(LIBSSH2_SESSION *session, const ch
} }
LIBSSH2_FREE(session, command); LIBSSH2_FREE(session, command);
#ifdef LIBSSH2_DEBUG_SCP
_libssh2_debug(session, LIBSSH2_DBG_SCP, "Sending initial wakeup"); _libssh2_debug(session, LIBSSH2_DBG_SCP, "Sending initial wakeup");
#endif
/* SCP ACK */ /* SCP ACK */
response[0] = '\0'; response[0] = '\0';
if (libssh2_channel_write(channel, response, 1) != 1) { if (libssh2_channel_write(channel, response, 1) != 1) {
@@ -103,8 +102,10 @@ LIBSSH2_API LIBSSH2_CHANNEL *libssh2_scp_recv(LIBSSH2_SESSION *session, const ch
response_len = 0; response_len = 0;
while (sb && (response_len < LIBSSH2_SCP_RESPONSE_BUFLEN)) { while (sb && (response_len < LIBSSH2_SCP_RESPONSE_BUFLEN)) {
unsigned char *s, *p; unsigned char *s, *p;
int rc;
if (libssh2_channel_read(channel, response + response_len, 1) <= 0) { rc = _libssh2_channel_read(channel, response + response_len, 1);
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);
libssh2_channel_free(channel); libssh2_channel_free(channel);
@@ -203,9 +204,8 @@ LIBSSH2_API LIBSSH2_CHANNEL *libssh2_scp_recv(LIBSSH2_SESSION *session, const ch
libssh2_channel_free(channel); libssh2_channel_free(channel);
return NULL; return NULL;
} }
#ifdef LIBSSH2_DEBUG_SCP
_libssh2_debug(session, LIBSSH2_DBG_SCP, "mtime = %ld, atime = %ld", mtime, atime); _libssh2_debug(session, LIBSSH2_DBG_SCP, "mtime = %ld, atime = %ld", mtime, atime);
#endif
/* 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;
@@ -215,7 +215,7 @@ LIBSSH2_API LIBSSH2_CHANNEL *libssh2_scp_recv(LIBSSH2_SESSION *session, const ch
while (response_len < LIBSSH2_SCP_RESPONSE_BUFLEN) { while (response_len < LIBSSH2_SCP_RESPONSE_BUFLEN) {
char *s, *p, *e = NULL; char *s, *p, *e = NULL;
if (libssh2_channel_read(channel, response + response_len, 1) <= 0) { if (_libssh2_channel_read(channel, response + response_len, 1) <= 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);
libssh2_channel_free(channel); libssh2_channel_free(channel);
@@ -304,9 +304,7 @@ LIBSSH2_API LIBSSH2_CHANNEL *libssh2_scp_recv(LIBSSH2_SESSION *session, const ch
libssh2_channel_free(channel); libssh2_channel_free(channel);
return NULL; return NULL;
} }
#ifdef LIBSSH2_DEBUG_SCP
_libssh2_debug(session, LIBSSH2_DBG_SCP, "mod = 0%lo size = %ld", mode, size); _libssh2_debug(session, LIBSSH2_DBG_SCP, "mod = 0%lo size = %ld", mode, size);
#endif
/* 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;
@@ -357,9 +355,7 @@ LIBSSH2_API LIBSSH2_CHANNEL *libssh2_scp_send_ex(LIBSSH2_SESSION *session, const
} }
command[command_len - 1] = '\0'; command[command_len - 1] = '\0';
#ifdef LIBSSH2_DEBUG_SCP
_libssh2_debug(session, LIBSSH2_DBG_SCP, "Opening channel for SCP send"); _libssh2_debug(session, LIBSSH2_DBG_SCP, "Opening channel for SCP send");
#endif
/* Allocate a channel */ /* Allocate a channel */
if ((channel = libssh2_channel_open_session(session)) == NULL) { if ((channel = libssh2_channel_open_session(session)) == NULL) {
/* previous call set libssh2_session_last_error(), pass it through */ /* previous call set libssh2_session_last_error(), pass it through */
@@ -379,7 +375,7 @@ LIBSSH2_API LIBSSH2_CHANNEL *libssh2_scp_send_ex(LIBSSH2_SESSION *session, const
LIBSSH2_FREE(session, command); LIBSSH2_FREE(session, command);
/* Wait for ACK */ /* Wait for ACK */
if ((libssh2_channel_read(channel, response, 1) <= 0) || (response[0] != 0)) { if ((_libssh2_channel_read(channel, response, 1) <= 0) || (response[0] != 0)) {
libssh2_error(session, LIBSSH2_ERROR_SCP_PROTOCOL, "Invalid ACK response from remote", 0); libssh2_error(session, LIBSSH2_ERROR_SCP_PROTOCOL, "Invalid ACK response from remote", 0);
libssh2_channel_free(channel); libssh2_channel_free(channel);
return NULL; return NULL;
@@ -388,16 +384,15 @@ LIBSSH2_API LIBSSH2_CHANNEL *libssh2_scp_send_ex(LIBSSH2_SESSION *session, const
/* Send mtime and atime to be used for file */ /* Send mtime and atime to be used for file */
if (mtime || atime) { if (mtime || atime) {
response_len = snprintf(response, LIBSSH2_SCP_RESPONSE_BUFLEN, "T%ld 0 %ld 0\n", mtime, atime); response_len = snprintf(response, LIBSSH2_SCP_RESPONSE_BUFLEN, "T%ld 0 %ld 0\n", mtime, atime);
#ifdef LIBSSH2_DEBUG_SCP
_libssh2_debug(session, LIBSSH2_DBG_SCP, "Sent %s", response); _libssh2_debug(session, LIBSSH2_DBG_SCP, "Sent %s", response);
#endif
if (libssh2_channel_write(channel, response, response_len) != response_len) { if (libssh2_channel_write(channel, response, response_len) != response_len) {
libssh2_error(session, LIBSSH2_ERROR_SOCKET_SEND, "Unable to send time data for SCP file", 0); libssh2_error(session, LIBSSH2_ERROR_SOCKET_SEND, "Unable to send time data for SCP file", 0);
libssh2_channel_free(channel); libssh2_channel_free(channel);
return NULL; return NULL;
} }
/* Wait for ACK */ /* Wait for ACK */
if ((libssh2_channel_read(channel, response, 1) <= 0) || (response[0] != 0)) { if ((_libssh2_channel_read(channel, response, 1) <= 0) || (response[0] != 0)) {
libssh2_error(session, LIBSSH2_ERROR_SCP_PROTOCOL, "Invalid ACK response from remote", 0); libssh2_error(session, LIBSSH2_ERROR_SCP_PROTOCOL, "Invalid ACK response from remote", 0);
libssh2_channel_free(channel); libssh2_channel_free(channel);
return NULL; return NULL;
@@ -413,16 +408,14 @@ LIBSSH2_API LIBSSH2_CHANNEL *libssh2_scp_send_ex(LIBSSH2_SESSION *session, const
} }
response_len = snprintf(response, LIBSSH2_SCP_RESPONSE_BUFLEN, "C0%o %lu %s\n", mode, (unsigned long)size, base); response_len = snprintf(response, LIBSSH2_SCP_RESPONSE_BUFLEN, "C0%o %lu %s\n", mode, (unsigned long)size, base);
#ifdef LIBSSH2_DEBUG_SCP
_libssh2_debug(session, LIBSSH2_DBG_SCP, "Sent %s", response); _libssh2_debug(session, LIBSSH2_DBG_SCP, "Sent %s", response);
#endif
if (libssh2_channel_write(channel, response, response_len) != response_len) { if (libssh2_channel_write(channel, response, response_len) != response_len) {
libssh2_error(session, LIBSSH2_ERROR_SOCKET_SEND, "Unable to send core file data for SCP file", 0); libssh2_error(session, LIBSSH2_ERROR_SOCKET_SEND, "Unable to send core file data for SCP file", 0);
libssh2_channel_free(channel); libssh2_channel_free(channel);
return NULL; return NULL;
} }
/* Wait for ACK */ /* Wait for ACK */
if ((libssh2_channel_read(channel, response, 1) <= 0) || (response[0] != 0)) { if ((_libssh2_channel_read(channel, response, 1) <= 0) || (response[0] != 0)) {
libssh2_error(session, LIBSSH2_ERROR_SCP_PROTOCOL, "Invalid ACK response from remote", 0); libssh2_error(session, LIBSSH2_ERROR_SCP_PROTOCOL, "Invalid ACK response from remote", 0);
libssh2_channel_free(channel); libssh2_channel_free(channel);
return NULL; return NULL;

View File

@@ -1,4 +1,4 @@
/* Copyright (c) 2004-2005, Sara Golemon <sarag@libssh2.org> /* Copyright (c) 2004-2007, Sara Golemon <sarag@libssh2.org>
* All rights reserved. * All rights reserved.
* *
* Redistribution and use in source and binary forms, * Redistribution and use in source and binary forms,
@@ -37,35 +37,20 @@
#include "libssh2_priv.h" #include "libssh2_priv.h"
#include <errno.h> #include <errno.h>
#ifndef WIN32 #ifdef HAVE_UNISTD_H
#include <unistd.h> #include <unistd.h>
#endif #endif
#include <stdlib.h> #include <stdlib.h>
#ifdef HAVE_GETTIMEOFDAY #ifdef HAVE_GETTIMEOFDAY
#include <sys/time.h> #include <sys/time.h>
#include <math.h>
#endif #endif
#ifdef HAVE_POLL
# include <sys/poll.h>
#else
# ifdef HAVE_SELECT
# ifdef HAVE_SYS_SELECT_H
# include <sys/select.h>
# else
# include <sys/time.h>
# include <sys/types.h>
# endif
# endif
#endif
/* {{{ libssh2_default_alloc /* {{{ libssh2_default_alloc
*/ */
static LIBSSH2_ALLOC_FUNC(libssh2_default_alloc) static LIBSSH2_ALLOC_FUNC(libssh2_default_alloc)
{ {
(void)abstract;
return malloc(count); return malloc(count);
} }
/* }}} */ /* }}} */
@@ -74,6 +59,7 @@ static LIBSSH2_ALLOC_FUNC(libssh2_default_alloc)
*/ */
static LIBSSH2_FREE_FUNC(libssh2_default_free) static LIBSSH2_FREE_FUNC(libssh2_default_free)
{ {
(void)abstract;
free(ptr); free(ptr);
} }
/* }}} */ /* }}} */
@@ -82,6 +68,7 @@ static LIBSSH2_FREE_FUNC(libssh2_default_free)
*/ */
static LIBSSH2_REALLOC_FUNC(libssh2_default_realloc) static LIBSSH2_REALLOC_FUNC(libssh2_default_realloc)
{ {
(void)abstract;
return realloc(ptr, count); return realloc(ptr, count);
} }
/* }}} */ /* }}} */
@@ -96,17 +83,36 @@ static int libssh2_banner_receive(LIBSSH2_SESSION *session)
char banner[256]; char banner[256];
int banner_len = 0; int banner_len = 0;
while ((banner_len < sizeof(banner)) && while ((banner_len < (int)sizeof(banner)) &&
((banner_len == 0) || (banner[banner_len-1] != '\n'))) { ((banner_len == 0) || (banner[banner_len-1] != '\n'))) {
char c = '\0'; char c = '\0';
int ret; int ret;
ret = recv(session->socket_fd, &c, 1, LIBSSH2_SOCKET_RECV_FLAGS(session)); ret = recv(session->socket_fd, &c, 1, LIBSSH2_SOCKET_RECV_FLAGS(session));
if ((ret < 0) && (ret != EAGAIN)) { if (ret < 0) {
#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 (errno != EAGAIN) {
/* Some kinda error, but don't break for non-blocking issues */ /* Some kinda error, but don't break for non-blocking issues */
return 1; return 1;
} }
}
if (ret <= 0) continue; if (ret <= 0) continue;
@@ -126,11 +132,13 @@ static int libssh2_banner_receive(LIBSSH2_SESSION *session)
if (!banner_len) return 1; if (!banner_len) return 1;
session->remote.banner = LIBSSH2_ALLOC(session, banner_len + 1); session->remote.banner = LIBSSH2_ALLOC(session, banner_len + 1);
if (!session->remote.banner) {
libssh2_error(session, LIBSSH2_ERROR_ALLOC, "Error allocating space for remote banner", 0);
return 1;
}
memcpy(session->remote.banner, banner, banner_len); memcpy(session->remote.banner, banner, banner_len);
session->remote.banner[banner_len] = '\0'; session->remote.banner[banner_len] = '\0';
#ifdef LIBSSH2_DEBUG_TRANSPORT
_libssh2_debug(session, LIBSSH2_DBG_TRANS, "Received Banner: %s", session->remote.banner); _libssh2_debug(session, LIBSSH2_DBG_TRANS, "Received Banner: %s", session->remote.banner);
#endif
return 0; return 0;
} }
/* }}} */ /* }}} */
@@ -140,15 +148,15 @@ static int libssh2_banner_receive(LIBSSH2_SESSION *session)
*/ */
static int libssh2_banner_send(LIBSSH2_SESSION *session) static int libssh2_banner_send(LIBSSH2_SESSION *session)
{ {
char *banner = LIBSSH2_SSH_DEFAULT_BANNER_WITH_CRLF; char *banner = (char *)LIBSSH2_SSH_DEFAULT_BANNER_WITH_CRLF;
int banner_len = sizeof(LIBSSH2_SSH_DEFAULT_BANNER_WITH_CRLF) - 1; int banner_len = sizeof(LIBSSH2_SSH_DEFAULT_BANNER_WITH_CRLF) - 1;
if (session->local.banner) { if (session->local.banner) {
/* setopt_string will have given us our \r\n characters */ /* setopt_string will have given us our \r\n characters */
banner_len = strlen(session->local.banner); banner_len = strlen((char *)session->local.banner);
banner = session->local.banner; banner = (char *)session->local.banner;
} }
#ifdef LIBSSH2_DEBUG_TRANSPORT #ifdef LIBSSH2DEBUG
{ {
/* Hack and slash to avoid sending CRLF in debug output */ /* Hack and slash to avoid sending CRLF in debug output */
char banner_dup[256]; char banner_dup[256];
@@ -187,15 +195,15 @@ LIBSSH2_API int libssh2_banner_set(LIBSSH2_SESSION *session, const char *banner)
session->local.banner = LIBSSH2_ALLOC(session, banner_len + 3); session->local.banner = LIBSSH2_ALLOC(session, banner_len + 3);
if (!session->local.banner) { if (!session->local.banner) {
libssh2_error(session, LIBSSH2_ERROR_ALLOC, "Unable to allocate memory for local banner", 0); libssh2_error(session, LIBSSH2_ERROR_ALLOC,
"Unable to allocate memory for local banner", 0);
return -1; return -1;
} }
memcpy(session->local.banner, banner, banner_len); memcpy(session->local.banner, banner, banner_len);
#ifdef LIBSSH2_DEBUG_TRANSPORT
session->local.banner[banner_len] = '\0'; session->local.banner[banner_len] = '\0';
_libssh2_debug(session, LIBSSH2_DBG_TRANS, "Setting local Banner: %s", session->local.banner); _libssh2_debug(session, LIBSSH2_DBG_TRANS,
#endif "Setting local Banner: %s", session->local.banner);
session->local.banner[banner_len++] = '\r'; session->local.banner[banner_len++] = '\r';
session->local.banner[banner_len++] = '\n'; session->local.banner[banner_len++] = '\n';
session->local.banner[banner_len++] = '\0'; session->local.banner[banner_len++] = '\0';
@@ -221,20 +229,24 @@ LIBSSH2_API LIBSSH2_SESSION *libssh2_session_init_ex(
LIBSSH2_REALLOC_FUNC((*local_realloc)) = libssh2_default_realloc; LIBSSH2_REALLOC_FUNC((*local_realloc)) = libssh2_default_realloc;
LIBSSH2_SESSION *session; LIBSSH2_SESSION *session;
if (my_alloc) local_alloc = my_alloc; if (my_alloc)
if (my_free) local_free = my_free; local_alloc = my_alloc;
if (my_realloc) local_realloc = my_realloc; if (my_free)
local_free = my_free;
if (my_realloc)
local_realloc = my_realloc;
session = local_alloc(sizeof(LIBSSH2_SESSION), abstract); session = local_alloc(sizeof(LIBSSH2_SESSION), abstract);
if (session) {
memset(session, 0, sizeof(LIBSSH2_SESSION)); memset(session, 0, sizeof(LIBSSH2_SESSION));
session->alloc = local_alloc; session->alloc = local_alloc;
session->free = local_free; session->free = local_free;
session->realloc = local_realloc; session->realloc = local_realloc;
session->abstract = abstract; session->abstract = abstract;
#ifdef LIBSSH2_DEBUG_TRANSPORT _libssh2_debug(session, LIBSSH2_DBG_TRANS,
_libssh2_debug(session, LIBSSH2_DBG_TRANS, "New session resource allocated"); "New session resource allocated");
#endif libssh2_crypto_init ();
}
return session; return session;
} }
/* }}} */ /* }}} */
@@ -243,7 +255,9 @@ LIBSSH2_API LIBSSH2_SESSION *libssh2_session_init_ex(
* Set (or reset) a callback function * Set (or reset) a callback function
* Returns the prior address * Returns the prior address
*/ */
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)
{ {
void *oldcb; void *oldcb;
@@ -252,31 +266,29 @@ LIBSSH2_API void* libssh2_session_callback_set(LIBSSH2_SESSION *session, int cbt
oldcb = session->ssh_msg_ignore; oldcb = session->ssh_msg_ignore;
session->ssh_msg_ignore = callback; session->ssh_msg_ignore = callback;
return oldcb; return oldcb;
break;
case LIBSSH2_CALLBACK_DEBUG: case LIBSSH2_CALLBACK_DEBUG:
oldcb = session->ssh_msg_debug; oldcb = session->ssh_msg_debug;
session->ssh_msg_debug = callback; session->ssh_msg_debug = callback;
return oldcb; return oldcb;
break;
case LIBSSH2_CALLBACK_DISCONNECT: case LIBSSH2_CALLBACK_DISCONNECT:
oldcb = session->ssh_msg_disconnect; oldcb = session->ssh_msg_disconnect;
session->ssh_msg_disconnect = callback; session->ssh_msg_disconnect = callback;
return oldcb; return oldcb;
break;
case LIBSSH2_CALLBACK_MACERROR: case LIBSSH2_CALLBACK_MACERROR:
oldcb = session->macerror; oldcb = session->macerror;
session->macerror = callback; session->macerror = callback;
return oldcb; return oldcb;
break;
case LIBSSH2_CALLBACK_X11: case LIBSSH2_CALLBACK_X11:
oldcb = session->x11; oldcb = session->x11;
session->x11 = callback; session->x11 = callback;
return oldcb; return oldcb;
break;
} }
#ifdef LIBSSH2_DEBUG_TRANSPORT
_libssh2_debug(session, LIBSSH2_DBG_TRANS, "Setting Callback %d", cbtype); _libssh2_debug(session, LIBSSH2_DBG_TRANS, "Setting Callback %d", cbtype);
#endif
return NULL; return NULL;
} }
@@ -285,8 +297,9 @@ LIBSSH2_API void* libssh2_session_callback_set(LIBSSH2_SESSION *session, int cbt
/* {{{ proto libssh2_session_startup /* {{{ proto libssh2_session_startup
* session: LIBSSH2_SESSION struct allocated and owned by the calling program * session: LIBSSH2_SESSION struct allocated and owned by the calling program
* Returns: 0 on success, or non-zero on failure * Returns: 0 on success, or non-zero on failure
* Any memory allocated by libssh2 will use alloc/realloc/free callbacks in session * Any memory allocated by libssh2 will use alloc/realloc/free
* socket *must* be populated with an opened socket * callbacks in session
* socket *must* be populated with an opened and connected socket.
*/ */
LIBSSH2_API int libssh2_session_startup(LIBSSH2_SESSION *session, int socket) LIBSSH2_API int libssh2_session_startup(LIBSSH2_SESSION *session, int socket)
{ {
@@ -294,13 +307,15 @@ LIBSSH2_API int libssh2_session_startup(LIBSSH2_SESSION *session, int socket)
unsigned long data_len; unsigned long data_len;
unsigned char service[sizeof("ssh-userauth") + 5 - 1]; unsigned char service[sizeof("ssh-userauth") + 5 - 1];
unsigned long service_length; unsigned long service_length;
int rc;
#ifdef LIBSSH2_DEBUG_TRANSPORT _libssh2_debug(session, LIBSSH2_DBG_TRANS,
_libssh2_debug(session, LIBSSH2_DBG_TRANS, "session_startup for socket %d", socket); "session_startup for socket %d", socket);
#endif /* FIXME: on some platforms (like win32) sockets are unsigned */
if (socket <= 0) { if (socket < 0) {
/* Did we forget something? */ /* Did we forget something? */
libssh2_error(session, LIBSSH2_ERROR_SOCKET_NONE, "No socket provided", 0); libssh2_error(session, LIBSSH2_ERROR_SOCKET_NONE,
"Bad socket provided", 0);
return LIBSSH2_ERROR_SOCKET_NONE; return LIBSSH2_ERROR_SOCKET_NONE;
} }
session->socket_fd = socket; session->socket_fd = socket;
@@ -308,42 +323,50 @@ LIBSSH2_API int libssh2_session_startup(LIBSSH2_SESSION *session, int socket)
/* TODO: Liveness check */ /* TODO: Liveness check */
if (libssh2_banner_send(session)) { if (libssh2_banner_send(session)) {
/* Unable to send banner? */ /* Unable to send banner? */
libssh2_error(session, LIBSSH2_ERROR_BANNER_SEND, "Error sending banner to remote host", 0); libssh2_error(session, LIBSSH2_ERROR_BANNER_SEND,
"Error sending banner to remote host", 0);
return LIBSSH2_ERROR_BANNER_SEND; return LIBSSH2_ERROR_BANNER_SEND;
} }
if (libssh2_banner_receive(session)) { if (libssh2_banner_receive(session)) {
/* Unable to receive banner from remote */ /* Unable to receive banner from remote */
libssh2_error(session, LIBSSH2_ERROR_BANNER_NONE, "Timeout waiting for banner", 0); libssh2_error(session, LIBSSH2_ERROR_BANNER_NONE,
"Timeout waiting for banner", 0);
return LIBSSH2_ERROR_BANNER_NONE; return LIBSSH2_ERROR_BANNER_NONE;
} }
if (libssh2_kex_exchange(session, 0)) { rc = libssh2_kex_exchange(session, 0);
libssh2_error(session, LIBSSH2_ERROR_KEX_FAILURE, "Unable to exchange encryption keys", 0); if(rc) {
libssh2_error(session, LIBSSH2_ERROR_KEX_FAILURE,
"Unable to exchange encryption keys", 0);
return LIBSSH2_ERROR_KEX_FAILURE; return LIBSSH2_ERROR_KEX_FAILURE;
} }
#ifdef LIBSSH2_DEBUG_TRANSPORT _libssh2_debug(session, LIBSSH2_DBG_TRANS,
_libssh2_debug(session, LIBSSH2_DBG_TRANS, "Requesting userauth service"); "Requesting userauth service");
#endif
/* Request the userauth service */ /* Request the userauth service */
service[0] = SSH_MSG_SERVICE_REQUEST; service[0] = SSH_MSG_SERVICE_REQUEST;
libssh2_htonu32(service + 1, sizeof("ssh-userauth") - 1); libssh2_htonu32(service + 1, sizeof("ssh-userauth") - 1);
memcpy(service + 5, "ssh-userauth", sizeof("ssh-userauth") - 1); memcpy(service + 5, "ssh-userauth", sizeof("ssh-userauth") - 1);
if (libssh2_packet_write(session, service, sizeof("ssh-userauth") + 5 - 1)) { if (libssh2_packet_write(session, service,
libssh2_error(session, LIBSSH2_ERROR_SOCKET_SEND, "Unable to ask for ssh-userauth service", 0); sizeof("ssh-userauth") + 5 - 1)) {
libssh2_error(session, LIBSSH2_ERROR_SOCKET_SEND,
"Unable to ask for ssh-userauth service", 0);
return LIBSSH2_ERROR_SOCKET_SEND; return LIBSSH2_ERROR_SOCKET_SEND;
} }
if (libssh2_packet_require(session, SSH_MSG_SERVICE_ACCEPT, &data, &data_len)) { rc = libssh2_packet_require(session, SSH_MSG_SERVICE_ACCEPT, &data,
&data_len);
if(rc) {
return LIBSSH2_ERROR_SOCKET_DISCONNECT; return LIBSSH2_ERROR_SOCKET_DISCONNECT;
} }
service_length = libssh2_ntohu32(data + 1); service_length = libssh2_ntohu32(data + 1);
if ((service_length != (sizeof("ssh-userauth") - 1)) || if ((service_length != (sizeof("ssh-userauth") - 1)) ||
strncmp("ssh-userauth", data + 5, service_length)) { strncmp("ssh-userauth", (char *)data + 5, service_length)) {
LIBSSH2_FREE(session, data); LIBSSH2_FREE(session, data);
libssh2_error(session, LIBSSH2_ERROR_PROTO, "Invalid response received from server", 0); libssh2_error(session, LIBSSH2_ERROR_PROTO,
"Invalid response received from server", 0);
return LIBSSH2_ERROR_PROTO; return LIBSSH2_ERROR_PROTO;
} }
LIBSSH2_FREE(session, data); LIBSSH2_FREE(session, data);
@@ -358,9 +381,7 @@ LIBSSH2_API int libssh2_session_startup(LIBSSH2_SESSION *session, int socket)
*/ */
LIBSSH2_API void libssh2_session_free(LIBSSH2_SESSION *session) LIBSSH2_API void libssh2_session_free(LIBSSH2_SESSION *session)
{ {
#ifdef LIBSSH2_DEBUG_TRANSPORT
_libssh2_debug(session, LIBSSH2_DBG_TRANS, "Freeing session resource", session->remote.banner); _libssh2_debug(session, LIBSSH2_DBG_TRANS, "Freeing session resource", session->remote.banner);
#endif
while (session->channels.head) { while (session->channels.head) {
LIBSSH2_CHANNEL *tmp = session->channels.head; LIBSSH2_CHANNEL *tmp = session->channels.head;
@@ -391,16 +412,9 @@ LIBSSH2_API void libssh2_session_free(LIBSSH2_SESSION *session)
/* Client to Server */ /* Client to Server */
/* crypt */ /* crypt */
if (session->local.crypt) { if (session->local.crypt && session->local.crypt->dtor) {
if (session->local.crypt->flags & LIBSSH2_CRYPT_METHOD_FLAG_EVP) {
if (session->local.crypt_abstract) {
LIBSSH2_FREE(session, session->local.crypt_abstract);
session->local.crypt_abstract = NULL;
}
} else if (session->local.crypt->dtor) {
session->local.crypt->dtor(session, &session->local.crypt_abstract); session->local.crypt->dtor(session, &session->local.crypt_abstract);
} }
}
/* comp */ /* comp */
if (session->local.comp && session->local.comp->dtor) { if (session->local.comp && session->local.comp->dtor) {
session->local.comp->dtor(session, 1, &session->local.comp_abstract); session->local.comp->dtor(session, 1, &session->local.comp_abstract);
@@ -412,16 +426,9 @@ LIBSSH2_API void libssh2_session_free(LIBSSH2_SESSION *session)
/* Server to Client */ /* Server to Client */
/* crypt */ /* crypt */
if (session->remote.crypt) { if (session->remote.crypt && session->remote.crypt->dtor) {
if (session->remote.crypt->flags & LIBSSH2_CRYPT_METHOD_FLAG_EVP) {
if (session->remote.crypt_abstract) {
LIBSSH2_FREE(session, session->remote.crypt_abstract);
session->remote.crypt_abstract = NULL;
}
} else if (session->remote.crypt->dtor) {
session->remote.crypt->dtor(session, &session->remote.crypt_abstract); session->remote.crypt->dtor(session, &session->remote.crypt_abstract);
} }
}
/* comp */ /* comp */
if (session->remote.comp && session->remote.comp->dtor) { if (session->remote.comp && session->remote.comp->dtor) {
session->remote.comp->dtor(session, 0, &session->remote.comp_abstract); session->remote.comp->dtor(session, 0, &session->remote.comp_abstract);
@@ -502,9 +509,7 @@ LIBSSH2_API int libssh2_session_disconnect_ex(LIBSSH2_SESSION *session, int reas
unsigned char *s, *data; unsigned char *s, *data;
unsigned long data_len, descr_len = 0, lang_len = 0; unsigned long data_len, descr_len = 0, lang_len = 0;
#ifdef LIBSSH2_DEBUG_TRANSPORT
_libssh2_debug(session, LIBSSH2_DBG_TRANS, "Disconnecting: reason=%d, desc=%s, lang=%s", reason, description, lang); _libssh2_debug(session, LIBSSH2_DBG_TRANS, "Disconnecting: reason=%d, desc=%s, lang=%s", reason, description, lang);
#endif
if (description) { if (description) {
descr_len = strlen(description); descr_len = strlen(description);
} }
@@ -550,7 +555,7 @@ LIBSSH2_API int libssh2_session_disconnect_ex(LIBSSH2_SESSION *session, int reas
LIBSSH2_API const char *libssh2_session_methods(LIBSSH2_SESSION *session, int method_type) LIBSSH2_API const char *libssh2_session_methods(LIBSSH2_SESSION *session, int method_type)
{ {
/* All methods have char *name as their first element */ /* All methods have char *name as their first element */
LIBSSH2_KEX_METHOD *method = NULL; const LIBSSH2_KEX_METHOD *method = NULL;
switch(method_type) { switch(method_type) {
case LIBSSH2_METHOD_KEX: case LIBSSH2_METHOD_KEX:
@@ -612,7 +617,9 @@ LIBSSH2_API void **libssh2_session_abstract(LIBSSH2_SESSION *session)
* If want_buf is non-zero then the string placed into errmsg must be freed by the calling program * If want_buf is non-zero then the string placed into errmsg must be freed by the calling program
* Otherwise it is assumed to be owned by libssh2 * Otherwise it is assumed to be owned by libssh2
*/ */
LIBSSH2_API int libssh2_session_last_error(LIBSSH2_SESSION *session, char **errmsg, int *errmsg_len, int want_buf) LIBSSH2_API int
libssh2_session_last_error(LIBSSH2_SESSION *session, char **errmsg,
int *errmsg_len, int want_buf)
{ {
/* No error to report */ /* No error to report */
if (!session->err_code) { if (!session->err_code) {
@@ -623,7 +630,7 @@ LIBSSH2_API int libssh2_session_last_error(LIBSSH2_SESSION *session, char **errm
**errmsg = 0; **errmsg = 0;
} }
} else { } else {
*errmsg = ""; *errmsg = (char *)"";
} }
} }
if (errmsg_len) { if (errmsg_len) {
@@ -633,7 +640,8 @@ LIBSSH2_API int libssh2_session_last_error(LIBSSH2_SESSION *session, char **errm
} }
if (errmsg) { if (errmsg) {
char *serrmsg = session->err_msg ? session->err_msg : ""; char *serrmsg = session->err_msg ? session->err_msg :
(char *)"";
int ownbuf = session->err_msg ? session->err_should_free : 0; int ownbuf = session->err_msg ? session->err_should_free : 0;
if (want_buf) { if (want_buf) {
@@ -704,7 +712,7 @@ LIBSSH2_API int libssh2_poll_channel_read(LIBSSH2_CHANNEL *channel, int extended
* Returns 0 if writing to channel would block, * Returns 0 if writing to channel would block,
* non-0 if data can be written without blocking * non-0 if data can be written without blocking
*/ */
inline int libssh2_poll_channel_write(LIBSSH2_CHANNEL *channel) static inline int libssh2_poll_channel_write(LIBSSH2_CHANNEL *channel)
{ {
return channel->local.window_size ? 1 : 0; return channel->local.window_size ? 1 : 0;
} }
@@ -714,7 +722,7 @@ inline int libssh2_poll_channel_write(LIBSSH2_CHANNEL *channel)
* Returns 0 if no connections are waiting to be accepted * Returns 0 if no connections are waiting to be accepted
* non-0 if one or more connections are available * non-0 if one or more connections are available
*/ */
inline int libssh2_poll_listener_queued(LIBSSH2_LISTENER *listener) static inline int libssh2_poll_listener_queued(LIBSSH2_LISTENER *listener)
{ {
return listener->queue ? 1 : 0; return listener->queue ? 1 : 0;
} }
@@ -723,13 +731,18 @@ inline int libssh2_poll_listener_queued(LIBSSH2_LISTENER *listener)
/* {{{ libssh2_poll /* {{{ libssh2_poll
* Poll sockets, channels, and listeners for activity * Poll sockets, channels, and listeners for activity
*/ */
LIBSSH2_API int libssh2_poll(LIBSSH2_POLLFD *fds, unsigned int nfds, long timeout) LIBSSH2_API int libssh2_poll(LIBSSH2_POLLFD *fds, unsigned int nfds,
long timeout)
{ {
long timeout_remaining; long timeout_remaining;
int i, active_fds; unsigned int i, active_fds;
#ifdef HAVE_POLL #ifdef HAVE_POLL
LIBSSH2_SESSION *session = NULL; LIBSSH2_SESSION *session = NULL;
struct pollfd sockets[nfds]; struct pollfd sockets[nfds];
/* FIXME: (dast) this is not C89 code! However, the prototype for this
function doesn't provide a session struct so we can't easily use
the user-provided malloc replacement here... I suggest we modify
the proto to make it possible. */
/* Setup sockets for polling */ /* Setup sockets for polling */
for(i = 0; i < nfds; i++) { for(i = 0; i < nfds; i++) {
@@ -863,7 +876,7 @@ LIBSSH2_API int libssh2_poll(LIBSSH2_POLLFD *fds, unsigned int nfds, long timeou
sysret = poll(sockets, nfds, timeout_remaining); sysret = poll(sockets, nfds, timeout_remaining);
gettimeofday((struct timeval *)&tv_end, NULL); gettimeofday((struct timeval *)&tv_end, NULL);
timeout_remaining -= (tv_end.tv_sec - tv_begin.tv_sec) * 1000; timeout_remaining -= (tv_end.tv_sec - tv_begin.tv_sec) * 1000;
timeout_remaining -= ceil((tv_end.tv_usec - tv_begin.tv_usec) / 1000); timeout_remaining -= (tv_end.tv_usec - tv_begin.tv_usec) / 1000;
} }
#else #else
/* If the platform doesn't support gettimeofday, /* If the platform doesn't support gettimeofday,
@@ -886,7 +899,7 @@ LIBSSH2_API int libssh2_poll(LIBSSH2_POLLFD *fds, unsigned int nfds, long timeou
case LIBSSH2_POLLFD_CHANNEL: case LIBSSH2_POLLFD_CHANNEL:
if (sockets[i].events & POLLIN) { if (sockets[i].events & POLLIN) {
/* Spin session until no data available */ /* Spin session until no data available */
while (libssh2_packet_read(fds[i].fd.channel->session, 0) > 0); while (libssh2_packet_read(fds[i].fd.channel->session) > 0);
} }
if (sockets[i].revents & POLLHUP) { if (sockets[i].revents & POLLHUP) {
fds[i].revents |= LIBSSH2_POLLFD_CHANNEL_CLOSED | LIBSSH2_POLLFD_SESSION_CLOSED; fds[i].revents |= LIBSSH2_POLLFD_CHANNEL_CLOSED | LIBSSH2_POLLFD_SESSION_CLOSED;
@@ -896,7 +909,7 @@ LIBSSH2_API int libssh2_poll(LIBSSH2_POLLFD *fds, unsigned int nfds, long timeou
case LIBSSH2_POLLFD_LISTENER: case LIBSSH2_POLLFD_LISTENER:
if (sockets[i].events & POLLIN) { if (sockets[i].events & POLLIN) {
/* Spin session until no data available */ /* Spin session until no data available */
while (libssh2_packet_read(fds[i].fd.listener->session, 0) > 0); while (libssh2_packet_read(fds[i].fd.listener->session) > 0);
} }
if (sockets[i].revents & POLLHUP) { if (sockets[i].revents & POLLHUP) {
fds[i].revents |= LIBSSH2_POLLFD_LISTENER_CLOSED | LIBSSH2_POLLFD_SESSION_CLOSED; fds[i].revents |= LIBSSH2_POLLFD_LISTENER_CLOSED | LIBSSH2_POLLFD_SESSION_CLOSED;
@@ -918,7 +931,7 @@ LIBSSH2_API int libssh2_poll(LIBSSH2_POLLFD *fds, unsigned int nfds, long timeou
gettimeofday((struct timeval *)&tv_end, NULL); gettimeofday((struct timeval *)&tv_end, NULL);
timeout_remaining -= (tv_end.tv_sec - tv_begin.tv_sec) * 1000; timeout_remaining -= (tv_end.tv_sec - tv_begin.tv_sec) * 1000;
timeout_remaining -= ceil((tv_end.tv_usec - tv_begin.tv_usec) / 1000); timeout_remaining -= (tv_end.tv_usec - tv_begin.tv_usec) / 1000;
} }
#else #else
/* If the platform doesn't support gettimeofday, /* If the platform doesn't support gettimeofday,
@@ -945,13 +958,13 @@ LIBSSH2_API int libssh2_poll(LIBSSH2_POLLFD *fds, unsigned int nfds, long timeou
case LIBSSH2_POLLFD_CHANNEL: case LIBSSH2_POLLFD_CHANNEL:
if (FD_ISSET(fds[i].fd.channel->session->socket_fd, &rfds)) { if (FD_ISSET(fds[i].fd.channel->session->socket_fd, &rfds)) {
/* Spin session until no data available */ /* Spin session until no data available */
while (libssh2_packet_read(fds[i].fd.channel->session, 0) > 0); while (libssh2_packet_read(fds[i].fd.channel->session) > 0);
} }
break; break;
case LIBSSH2_POLLFD_LISTENER: case LIBSSH2_POLLFD_LISTENER:
if (FD_ISSET(fds[i].fd.listener->session->socket_fd, &rfds)) { if (FD_ISSET(fds[i].fd.listener->session->socket_fd, &rfds)) {
/* Spin session until no data available */ /* Spin session until no data available */
while (libssh2_packet_read(fds[i].fd.listener->session, 0) > 0); while (libssh2_packet_read(fds[i].fd.listener->session) > 0);
} }
break; break;
} }

1025
src/sftp.c

File diff suppressed because it is too large Load Diff

725
src/transport.c Normal file
View File

@@ -0,0 +1,725 @@
/* Copyright (C) 2007 The Written Word, Inc. All rights reserved.
* Author: Daniel Stenberg <daniel@haxx.se>
*
* Redistribution and use in source and binary forms,
* with or without modification, are permitted provided
* that the following conditions are met:
*
* Redistributions of source code must retain the above
* copyright notice, this list of conditions and the
* following disclaimer.
*
* Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following
* disclaimer in the documentation and/or other materials
* provided with the distribution.
*
* Neither the name of the copyright holder nor the names
* of any other contributors may be used to endorse or
* promote products derived from this software without
* specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
* CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
* USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
* OF SUCH DAMAGE.
*
* This file handles reading and writing to the SECSH transport layer. RFC4253.
*/
#include "libssh2_priv.h"
#include <errno.h>
#include <fcntl.h>
#include <assert.h>
#define MAX_BLOCKSIZE 32 /* MUST fit biggest crypto block size we use/get */
#define MAX_MACSIZE 20 /* MUST fit biggest MAC length we support */
#ifdef LIBSSH2DEBUG
#define UNPRINTABLE_CHAR '.'
static void debugdump(LIBSSH2_SESSION *session,
const char *desc, unsigned char *ptr,
unsigned long size)
{
size_t i;
size_t c;
FILE *stream = stdout;
unsigned int width=0x10;
if(!(session->showmask & (1<< LIBSSH2_DBG_TRANS))) {
/* not asked for, bail out */
return;
}
fprintf(stream, "=> %s (%d bytes)\n", desc, (int)size);
for(i=0; i<size; i+= width) {
fprintf(stream, "%04x: ", 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 */
}
fflush(stream);
}
#else
#define debugdump(a,x,y,z)
#endif
/* decrypt() decrypts 'len' bytes from 'source' to 'dest'.
*
* returns PACKET_NONE on success and PACKET_FAIL on failure
*/
static libssh2pack_t decrypt(LIBSSH2_SESSION *session, unsigned char *source,
unsigned char *dest, int len)
{
struct transportpacket *p = &session->packet;
int blocksize = session->remote.crypt->blocksize;
/* if we get called with a len that isn't an even number of blocksizes
we risk losing those extra bytes */
assert((len % blocksize) == 0);
while(len >= blocksize) {
if (session->remote.crypt->crypt(session, source,
&session->remote.crypt_abstract)) {
libssh2_error(session, LIBSSH2_ERROR_DECRYPT,
(char *)"Error decrypting packet", 0);
LIBSSH2_FREE(session, p->payload);
return PACKET_FAIL;
}
/* if the crypt() function would write to a given address it
wouldn't have to memcpy() and we could avoid this memcpy()
too */
memcpy(dest, source, blocksize);
len -= blocksize; /* less bytes left */
dest += blocksize; /* advance write pointer */
source += blocksize; /* advance read pointer */
}
return PACKET_NONE; /* all is fine */
}
/*
* fullpacket() gets called when a full packet has been received and properly
* collected.
*/
static libssh2pack_t fullpacket(LIBSSH2_SESSION *session,
int encrypted /* 1 or 0 */)
{
unsigned char macbuf[MAX_MACSIZE];
struct transportpacket *p = &session->packet;
int payload_len = p->packet_length-1;
libssh2pack_t packet_type;
int macstate = LIBSSH2_MAC_CONFIRMED;
if(encrypted) {
/* Calculate MAC hash */
session->remote.mac->hash(session,
macbuf, /* store hash here */
session->remote.seqno,
p->init, 5,
p->payload, payload_len,
&session->remote.mac_abstract);
/* Compare the calculated hash with the MAC we just read from
* the network. The read one is at the very end of the payload
* buffer. Note that 'payload_len' here is the packet_length
* field which includes the padding but not the MAC.
*/
if(memcmp(macbuf, p->payload + payload_len,
session->remote.mac->mac_len)) {
macstate = LIBSSH2_MAC_INVALID;
}
}
session->remote.seqno++;
/* ignore the padding */
payload_len -= p->padding_length;
/* Check for and deal with decompression */
if (session->remote.comp &&
strcmp(session->remote.comp->name, "none")) {
unsigned char *data;
unsigned long data_len;
int free_payload = 1;
if (session->remote.comp->comp(session, 0,
&data, &data_len,
LIBSSH2_PACKET_MAXDECOMP,
&free_payload,
p->payload, payload_len,
&session->remote.comp_abstract)) {
LIBSSH2_FREE(session, p->payload);
return PACKET_FAIL;
}
if (free_payload) {
LIBSSH2_FREE(session, p->payload);
p->payload = data;
payload_len = data_len;
}
else {
if (data == p->payload) {
/* It's not to be freed, because the
* compression layer reused payload, So let's
* do the same!
*/
payload_len = data_len;
}
else {
/* No comp_method actually lets this happen,
* but let's prepare for the future */
LIBSSH2_FREE(session, p->payload);
/* We need a freeable struct otherwise the
* brigade won't know what to do with it */
p->payload = LIBSSH2_ALLOC(session, data_len);
if (!p->payload) {
libssh2_error(session,
LIBSSH2_ERROR_ALLOC,
(char *)"Unable to allocate memory for copy of uncompressed data", 0);
return PACKET_ENOMEM;
}
memcpy(p->payload, data, data_len);
payload_len = data_len;
}
}
}
packet_type = p->payload[0];
debugdump(session, "libssh2_packet_read() plain",
p->payload, payload_len);
if (libssh2_packet_add(session, p->payload, payload_len, macstate) < 0)
return PACKET_FAIL;
return packet_type;
}
/* {{{ libssh2_packet_read
* Collect a packet into the input brigade
* block only controls whether or not to wait for a packet to start,
* Once a packet starts, libssh2 will block until it is complete
* Returns packet type added to input brigade (PACKET_NONE if nothing added),
* or PACKET_FAIL on failure and PACKET_EAGAIN if it couldn't process a full
* packet.
*/
/*
* This function reads the binary stream as specified in chapter 6 of RFC4253
* "The Secure Shell (SSH) Transport Layer Protocol"
*/
libssh2pack_t libssh2_packet_read(LIBSSH2_SESSION *session)
{
libssh2pack_t rc;
struct transportpacket *p = &session->packet;
int remainbuf;
int remainpack;
int numbytes;
int numdecrypt;
unsigned char block[MAX_BLOCKSIZE];
int blocksize;
int minimum;
int encrypted = 1;
do {
if (session->socket_state == LIBSSH2_SOCKET_DISCONNECTED) {
return PACKET_NONE;
}
if (session->state & LIBSSH2_STATE_NEWKEYS) {
blocksize = session->remote.crypt->blocksize;
}
else {
encrypted = 0; /* not encrypted */
blocksize = 5; /* not strictly true, but we can use 5
here to make the checks below work
fine still */
}
minimum = p->total_num ? p->total_num - p->data_num : blocksize;
/* read/use a whole big chunk into a temporary area stored in
the LIBSSH2_SESSION struct. We will decrypt data from that
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
so that we can read big chunks from the network layer. */
/* how much data there is remaining in the buffer to deal with
before we should read more from the network */
remainbuf = p->writeidx - p->readidx;
/* if remainbuf turns negative we have a bad internal error */
assert(remainbuf >= 0);
while(remainbuf < minimum) {
/* While there is too little data to deal with, read
more */
ssize_t nread;
/* move any remainder to the start of the buffer so
that we can do a full refill */
if(remainbuf) {
memmove(p->buf, &p->buf[p->readidx],
remainbuf);
p->readidx = 0;
p->writeidx = remainbuf;
}
else {
/* nothing to move, just zero the indexes */
p->readidx = p->writeidx = 0;
}
/* now read a big chunk from the network into the temp
buffer */
nread = recv(session->socket_fd, &p->buf[remainbuf],
PACKETBUFSIZE-remainbuf,
LIBSSH2_SOCKET_RECV_FLAGS(session));
if (nread <= 0) {
/* check if this is due to EAGAIN and return
the special return code if so, error out
normally otherwise */
if ((nread < 0) && (errno == EAGAIN)) {
return PACKET_EAGAIN;
}
return PACKET_FAIL;
}
debugdump(session, "libssh2_packet_read() raw",
&p->buf[remainbuf], nread);
/* advance write pointer */
p->writeidx += nread;
/* update remainbuf counter */
remainbuf = p->writeidx - p->readidx;
}
/* how much data to deal with from the buffer */
numbytes = remainbuf;
if(!p->total_num) {
/* No payload package area allocated yet. To know the
size of this payload, we need to decrypt the first
blocksize data. */
if(encrypted) {
rc = decrypt(session, &p->buf[p->readidx],
block, blocksize);
if(rc != PACKET_NONE) {
return rc;
}
/* save the first 5 bytes of the decrypted
package, to be used in the hash calculation
later down. */
memcpy(p->init, &p->buf[p->readidx], 5);
}
else {
/* the data is plain, just copy it verbatim to
the working block buffer */
memcpy(block, &p->buf[p->readidx], blocksize);
}
/* advance the read pointer */
p->readidx += blocksize;
/* we now have the initial blocksize bytes decrypted,
and we can extract packet and padding length from it
*/
p->packet_length = libssh2_ntohu32(block);
p->padding_length = block[4];
/* total_num is the number of bytes following the
initial (5 bytes) packet length and padding length
fields */
p->total_num = p->packet_length -1 +
(encrypted?session->remote.mac->mac_len:0);
/* RFC4253 section 6.1 Maximum Packet Length says:
*
* "All implementations MUST be able to process
* packets with uncompressed payload length of 32768
* bytes or less and total packet size of 35000 bytes
* or less (including length, padding length, payload,
* padding, and MAC.)."
*/
if(p->total_num > LIBSSH2_PACKET_MAXPAYLOAD) {
return PACKET_TOOBIG;
}
/* Get a packet handle put data into. We get one to
hold all data, including padding and MAC. */
p->payload = LIBSSH2_ALLOC(session, p->total_num);
if(!p->payload) {
return PACKET_ENOMEM;
}
/* init write pointer to start of payload buffer */
p->wptr = p->payload;
if(blocksize > 5) {
/* copy the data from index 5 to the end of
the blocksize from the temporary buffer to
the start of the decrypted buffer */
memcpy(p->wptr, &block[5], blocksize-5);
p->wptr += blocksize-5; /* advance write
pointer */
}
/* init the data_num field to the number of bytes of
the package read so far */
p->data_num = p->wptr - p->payload;
/* we already dealt with a blocksize worth of data */
numbytes -= blocksize;
}
/* how much there is left to add to the current payload
package */
remainpack = p->total_num - p->data_num;
if(numbytes > remainpack) {
/* if we have more data in the buffer than what is
going into this particular packet, we limit this
round to this packet only */
numbytes = remainpack;
}
if(encrypted) {
/* At the end of the incoming stream, there is a MAC,
and we don't want to decrypt that since we need it
"raw". We MUST however decrypt the padding data
since it is used for the hash later on. */
int skip = session->remote.mac->mac_len;
/* if what we have plus numbytes is bigger than the
total minus the skip margin, we should lower the
amount to decrypt even more */
if((p->data_num + numbytes) > (p->total_num - skip)) {
numdecrypt = (p->total_num - skip) -
p->data_num;
}
else {
int frac;
numdecrypt = numbytes;
frac = numdecrypt % blocksize;
if(frac) {
/* not an aligned amount of blocks,
align it */
numdecrypt -= frac;
/* and make it no unencrypted data
after it */
numbytes = 0;
}
}
}
else {
/* unencrypted data should not be decrypted at all */
numdecrypt = 0;
}
/* if there are bytes to decrypt, do that */
if(numdecrypt > 0) {
/* now decrypt the lot */
rc = decrypt(session, &p->buf[p->readidx],
p->wptr, numdecrypt);
if(rc != PACKET_NONE) {
return rc;
}
/* advance the read pointer */
p->readidx += numdecrypt;
/* advance write pointer */
p->wptr += numdecrypt;
/* increse data_num */
p->data_num += numdecrypt;
/* bytes left to take care of without decryption */
numbytes -= numdecrypt;
}
/* if there are bytes to copy that aren't decrypted, simply
copy them as-is to the target buffer */
if(numbytes > 0) {
memcpy(p->wptr, &p->buf[p->readidx], numbytes);
/* advance the read pointer */
p->readidx += numbytes;
/* advance write pointer */
p->wptr += numbytes;
/* increse data_num */
p->data_num += numbytes;
}
/* now check how much data there's left to read to finish the
current packet */
remainpack = p->total_num - p->data_num;
if(!remainpack) {
/* we have a full packet */
rc = fullpacket(session, encrypted);
p->total_num = 0; /* no packet buffer available */
return rc;
}
} while (1); /* loop */
return PACKET_FAIL; /* we never reach this point */
}
/* }}} */
#ifndef OLDSEND
static libssh2pack_t send_existing(LIBSSH2_SESSION *session,
unsigned char *data,
unsigned long data_len,
ssize_t *ret)
{
ssize_t rc;
ssize_t length;
struct transportpacket *p = &session->packet;
if(!p->outbuf) {
*ret = 0;
return PACKET_NONE;
}
/* send as much as possible of the existing packet */
if((data != p->odata) || (data_len != p->olen)) {
/* 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 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 this case */
return PACKET_BADUSE;
}
*ret = 1; /* set to make our parent return */
/* number of bytes left to send */
length = p->ototal_num - p->osent;
rc = send(session->socket_fd,
&p->outbuf[p->osent],
length, LIBSSH2_SOCKET_SEND_FLAGS(session));
if(rc == length) {
/* the remainder of the package was sent */
LIBSSH2_FREE(session, p->outbuf);
p->outbuf = NULL;
p->ototal_num = 0;
}
else if(rc < 0) {
/* nothing was sent */
if(errno != EAGAIN) {
/* send failure! */
return PACKET_FAIL;
}
return PACKET_EAGAIN;
}
debugdump(session, "libssh2_packet_write send()",
&p->outbuf[p->osent], length);
p->osent += length; /* we sent away this much data */
return PACKET_NONE;
}
/* {{{ libssh2_packet_write
* Send a packet, encrypting it and adding a MAC code if necessary
* Returns 0 on success, non-zero on failure.
*
* Returns PACKET_EAGAIN if it would block - and if it does so, you should
* call this function again as soon as it is likely that more data can be
* sent, and this function should then be called with the same argument set
* (same data pointer and same data_len) until zero or failure is returned.
*/
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 padding_length;
int packet_length;
int total_length;
int free_data=0;
#ifdef RANDOM_PADDING
int rand_max;
int seed = data[0]; /* FIXME: make this random */
#endif
struct transportpacket *p = &session->packet;
int encrypted;
int i;
ssize_t ret;
libssh2pack_t rc;
unsigned char *orgdata = data;
unsigned long orgdata_len = data_len;
debugdump(session, "libssh2_packet_write plain", data, data_len);
/* FIRST, check if we have a pending write to complete */
rc = send_existing(session, data, data_len, &ret);
if(rc || ret)
return rc;
encrypted = (session->state & LIBSSH2_STATE_NEWKEYS)?1:0;
/* check if we should compress */
if (encrypted && strcmp(session->local.comp->name, "none")) {
if (session->local.comp->comp(session, 1, &data, &data_len,
LIBSSH2_PACKET_MAXCOMP,
&free_data, data, data_len,
&session->local.comp_abstract)) {
return PACKET_COMPRESS; /* compression failure */
}
}
/* RFC4253 says: Note that the length of the concatenation of
'packet_length', 'padding_length', 'payload', and 'random padding'
MUST be a multiple of the cipher block size or 8, whichever is
larger. */
/* Plain math: (4 + 1 + packet_length + padding_length) % blocksize ==
0 */
packet_length = data_len + 1 + 4; /* 1 is for padding_length field
4 for the packet_length field */
/* at this point we have it all except the padding */
/* first figure out our minimum padding amount to make it an even
block size */
padding_length = blocksize - (packet_length % blocksize);
/* if the padding becomes too small we add another blocksize worth
of it (taken from the original libssh2 where it didn't have any
real explanation) */
if (padding_length < 4) {
padding_length += blocksize;
}
#ifdef RANDOM_PADDING
/* FIXME: we can add padding here, but that also makes the packets
bigger etc */
/* 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
total */
rand_max = (255 - padding_length)/blocksize + 1;
padding_length += blocksize * (seed % rand_max);
#endif
packet_length += padding_length;
/* append the MAC length to the total_length size */
total_length = packet_length +
(encrypted?session->local.mac->mac_len:0);
/* allocate memory to store the outgoing packet in, in case we can't
send the whole one and thus need to keep it after this function
returns. */
p->outbuf = LIBSSH2_ALLOC(session, total_length);
if(!p->outbuf) {
return PACKET_ENOMEM;
}
/* store packet_length, which is the size of the whole packet except
the MAC and the packet_length field itself */
libssh2_htonu32(p->outbuf, packet_length - 4);
/* store padding_length */
p->outbuf[4] = padding_length;
/* copy the payload data */
memcpy(p->outbuf + 5, data, data_len);
/* fill the padding area with random junk */
libssh2_random(p->outbuf + 5 + data_len, padding_length);
if (free_data) {
LIBSSH2_FREE(session, data);
}
if(encrypted) {
/* Calculate MAC hash. Put the output at index packet_length,
since that size includes the whole packet. The MAC is
calculated on the entire unencrypted packet, including all
fields except the MAC field itself. */
session->local.mac->hash(session,
p->outbuf + packet_length,
session->local.seqno,
p->outbuf, packet_length,
NULL, 0,
&session->local.mac_abstract);
/* Encrypt the whole packet data, one block size at a time.
The MAC field is not encrypted. */
for(i=0; i < packet_length;
i += session->local.crypt->blocksize) {
unsigned char *ptr = &p->outbuf[i];
if(session->local.crypt->crypt(session, ptr,
&session->local.crypt_abstract))
return PACKET_FAIL; /* encryption failure */
}
}
session->local.seqno++;
ret = send(session->socket_fd, p->outbuf,
total_length, LIBSSH2_SOCKET_SEND_FLAGS(session));
if(ret != -1) {
debugdump(session, "libssh2_packet_write send()",
p->outbuf, ret);
}
if(ret != total_length) {
if((ret > 0 ) ||
((ret == -1) && (errno == EAGAIN))) {
/* the whole packet could not be sent, save the rest */
p->odata = orgdata;
p->olen = orgdata_len;
p->osent = (ret == -1)?0:ret;
p->ototal_num = total_length;
return PACKET_EAGAIN;
}
return PACKET_FAIL;
}
/* the whole thing got sent away */
p->odata = NULL;
p->olen = 0;
LIBSSH2_FREE(session, p->outbuf);
p->outbuf = NULL;
return PACKET_NONE; /* all is good */
}
/* }}} */
#endif

View File

@@ -1,4 +1,4 @@
/* Copyright (c) 2004-2005, Sara Golemon <sarag@libssh2.org> /* Copyright (c) 2004-2007, Sara Golemon <sarag@libssh2.org>
* All rights reserved. * All rights reserved.
* *
* Redistribution and use in source and binary forms, * Redistribution and use in source and binary forms,
@@ -37,6 +37,9 @@
#include "libssh2_priv.h" #include "libssh2_priv.h"
#include <ctype.h>
#include <stdio.h>
/* Needed for struct iovec on some platforms */ /* Needed for struct iovec on some platforms */
#ifdef HAVE_SYS_UIO_H #ifdef HAVE_SYS_UIO_H
#include <sys/uio.h> #include <sys/uio.h>
@@ -49,9 +52,9 @@
* Not a common configuration for any SSH server though * Not a common configuration for any SSH server though
* username should be NULL, or a null terminated string * username should be NULL, or a null terminated string
*/ */
LIBSSH2_API char *libssh2_userauth_list(LIBSSH2_SESSION *session, const char *username, int username_len) LIBSSH2_API char *libssh2_userauth_list(LIBSSH2_SESSION *session, const char *username, unsigned int username_len)
{ {
unsigned char reply_codes[3] = { SSH_MSG_USERAUTH_SUCCESS, SSH_MSG_USERAUTH_FAILURE, 0 }; static const unsigned char reply_codes[3] = { SSH_MSG_USERAUTH_SUCCESS, SSH_MSG_USERAUTH_FAILURE, 0 };
unsigned long data_len = username_len + 31; /* packet_type(1) + username_len(4) + service_len(4) + service(14)"ssh-connection" + unsigned long data_len = username_len + 31; /* packet_type(1) + username_len(4) + service_len(4) + service(14)"ssh-connection" +
method_len(4) + method(4)"none" */ method_len(4) + method(4)"none" */
unsigned long methods_len; unsigned long methods_len;
@@ -96,10 +99,8 @@ LIBSSH2_API char *libssh2_userauth_list(LIBSSH2_SESSION *session, const char *us
methods_len = libssh2_ntohu32(data + 1); methods_len = libssh2_ntohu32(data + 1);
memcpy(data, data + 5, methods_len); memcpy(data, data + 5, methods_len);
data[methods_len] = '\0'; data[methods_len] = '\0';
#ifdef LIBSSH2_DEBUG_USERAUTH
_libssh2_debug(session, LIBSSH2_DBG_AUTH, "Permitted auth methods: %s", data); _libssh2_debug(session, LIBSSH2_DBG_AUTH, "Permitted auth methods: %s", data);
#endif return (char *)data;
return data;
} }
/* }}} */ /* }}} */
@@ -116,11 +117,12 @@ LIBSSH2_API int libssh2_userauth_authenticated(LIBSSH2_SESSION *session)
/* {{{ libssh2_userauth_password /* {{{ libssh2_userauth_password
* Plain ol' login * Plain ol' login
*/ */
LIBSSH2_API int libssh2_userauth_password_ex(LIBSSH2_SESSION *session, const char *username, int username_len, LIBSSH2_API int libssh2_userauth_password_ex(LIBSSH2_SESSION *session, const char *username, unsigned int username_len,
const char *password, int password_len, const char *password, unsigned int password_len,
LIBSSH2_PASSWD_CHANGEREQ_FUNC((*passwd_change_cb))) LIBSSH2_PASSWD_CHANGEREQ_FUNC((*passwd_change_cb)))
{ {
unsigned char *data, *s, reply_codes[4] = { SSH_MSG_USERAUTH_SUCCESS, SSH_MSG_USERAUTH_FAILURE, SSH_MSG_USERAUTH_PASSWD_CHANGEREQ, 0 }; unsigned char *data, *s;
static const unsigned char reply_codes[4] = { SSH_MSG_USERAUTH_SUCCESS, SSH_MSG_USERAUTH_FAILURE, SSH_MSG_USERAUTH_PASSWD_CHANGEREQ, 0 };
unsigned long data_len = username_len + password_len + 40; /* packet_type(1) + username_len(4) + service_len(4) + service(14)"ssh-connection" + unsigned long data_len = username_len + password_len + 40; /* packet_type(1) + username_len(4) + service_len(4) + service(14)"ssh-connection" +
method_len(4) + method(8)"password" + chgpwdbool(1) + password_len(4) */ method_len(4) + method(8)"password" + chgpwdbool(1) + password_len(4) */
@@ -145,9 +147,7 @@ LIBSSH2_API int libssh2_userauth_password_ex(LIBSSH2_SESSION *session, const cha
libssh2_htonu32(s, password_len); s += 4; libssh2_htonu32(s, password_len); s += 4;
memcpy(s, password, password_len); s += password_len; memcpy(s, password, password_len); s += password_len;
#ifdef LIBSSH2_DEBUG_USERAUTH
_libssh2_debug(session, LIBSSH2_DBG_AUTH, "Attempting to login using password authentication"); _libssh2_debug(session, LIBSSH2_DBG_AUTH, "Attempting to login using password authentication");
#endif
if (libssh2_packet_write(session, data, data_len)) { if (libssh2_packet_write(session, data, data_len)) {
libssh2_error(session, LIBSSH2_ERROR_SOCKET_SEND, "Unable to send userauth-password request", 0); libssh2_error(session, LIBSSH2_ERROR_SOCKET_SEND, "Unable to send userauth-password request", 0);
LIBSSH2_FREE(session, data); LIBSSH2_FREE(session, data);
@@ -161,9 +161,7 @@ LIBSSH2_API int libssh2_userauth_password_ex(LIBSSH2_SESSION *session, const cha
} }
if (data[0] == SSH_MSG_USERAUTH_SUCCESS) { if (data[0] == SSH_MSG_USERAUTH_SUCCESS) {
#ifdef LIBSSH2_DEBUG_USERAUTH
_libssh2_debug(session, LIBSSH2_DBG_AUTH, "Password authentication successful"); _libssh2_debug(session, LIBSSH2_DBG_AUTH, "Password authentication successful");
#endif
LIBSSH2_FREE(session, data); LIBSSH2_FREE(session, data);
session->state |= LIBSSH2_STATE_AUTHENTICATED; session->state |= LIBSSH2_STATE_AUTHENTICATED;
return 0; return 0;
@@ -173,9 +171,7 @@ LIBSSH2_API int libssh2_userauth_password_ex(LIBSSH2_SESSION *session, const cha
char *newpw = NULL; char *newpw = NULL;
int newpw_len = 0; int newpw_len = 0;
#ifdef LIBSSH2_DEBUG_USERAUTH
_libssh2_debug(session, LIBSSH2_DBG_AUTH, "Password change required"); _libssh2_debug(session, LIBSSH2_DBG_AUTH, "Password change required");
#endif
LIBSSH2_FREE(session, data); LIBSSH2_FREE(session, data);
if (passwd_change_cb) { if (passwd_change_cb) {
passwd_change_cb(session, &newpw, &newpw_len, &session->abstract); passwd_change_cb(session, &newpw, &newpw_len, &session->abstract);
@@ -187,6 +183,7 @@ LIBSSH2_API int libssh2_userauth_password_ex(LIBSSH2_SESSION *session, const cha
s = data = LIBSSH2_ALLOC(session, data_len); s = data = LIBSSH2_ALLOC(session, data_len);
if (!data) { if (!data) {
libssh2_error(session, LIBSSH2_ERROR_ALLOC, "Unable to allocate memory for userauth-password-change request", 0); libssh2_error(session, LIBSSH2_ERROR_ALLOC, "Unable to allocate memory for userauth-password-change request", 0);
LIBSSH2_FREE(session, newpw);
return -1; return -1;
} }
@@ -211,6 +208,7 @@ LIBSSH2_API int libssh2_userauth_password_ex(LIBSSH2_SESSION *session, const cha
if (libssh2_packet_write(session, data, data_len)) { if (libssh2_packet_write(session, data, data_len)) {
libssh2_error(session, LIBSSH2_ERROR_SOCKET_SEND, "Unable to send userauth-password-change request", 0); libssh2_error(session, LIBSSH2_ERROR_SOCKET_SEND, "Unable to send userauth-password-change request", 0);
LIBSSH2_FREE(session, data); LIBSSH2_FREE(session, data);
LIBSSH2_FREE(session, newpw);
return -1; return -1;
} }
LIBSSH2_FREE(session, data); LIBSSH2_FREE(session, data);
@@ -238,12 +236,12 @@ static int libssh2_file_read_publickey(LIBSSH2_SESSION *session, unsigned char *
const char *pubkeyfile) const char *pubkeyfile)
{ {
FILE *fd; FILE *fd;
char *pubkey = NULL, c, *sp1, *sp2, *tmp; char c;
int pubkey_len = 0, tmp_len; unsigned char *pubkey = NULL, *sp1, *sp2, *tmp;
size_t pubkey_len = 0;
unsigned int tmp_len;
#ifdef LIBSSH2_DEBUG_USERAUTH
_libssh2_debug(session, LIBSSH2_DBG_AUTH, "Loading public key file: %s", pubkeyfile); _libssh2_debug(session, LIBSSH2_DBG_AUTH, "Loading public key file: %s", pubkeyfile);
#endif
/* Read Public Key */ /* Read Public Key */
fd = fopen(pubkeyfile, "r"); fd = fopen(pubkeyfile, "r");
if (!fd) { if (!fd) {
@@ -251,6 +249,10 @@ static int libssh2_file_read_publickey(LIBSSH2_SESSION *session, unsigned char *
return -1; return -1;
} }
while (!feof(fd) && (c = fgetc(fd)) != '\r' && c != '\n') pubkey_len++; while (!feof(fd) && (c = fgetc(fd)) != '\r' && c != '\n') pubkey_len++;
if (feof(fd)) {
/* the last character was EOF */
pubkey_len--;
}
rewind(fd); rewind(fd);
if (pubkey_len <= 1) { if (pubkey_len <= 1) {
@@ -272,7 +274,10 @@ static int libssh2_file_read_publickey(LIBSSH2_SESSION *session, unsigned char *
return -1; return -1;
} }
fclose(fd); fclose(fd);
while (pubkey_len && (pubkey[pubkey_len-1] == '\r' || pubkey[pubkey_len-1] == '\n')) pubkey_len--; /*
* Remove trailing whitespace
*/
while (pubkey_len && isspace(pubkey[pubkey_len-1])) pubkey_len--;
if (!pubkey_len) { if (!pubkey_len) {
libssh2_error(session, LIBSSH2_ERROR_FILE, "Missing public key data", 0); libssh2_error(session, LIBSSH2_ERROR_FILE, "Missing public key data", 0);
@@ -298,7 +303,7 @@ static int libssh2_file_read_publickey(LIBSSH2_SESSION *session, unsigned char *
sp2 = pubkey + pubkey_len; sp2 = pubkey + pubkey_len;
} }
if (libssh2_base64_decode(session, &tmp, &tmp_len, sp1, sp2 - sp1)) { if (libssh2_base64_decode(session, (char **)&tmp, &tmp_len, (char *)sp1, sp2 - sp1)) {
libssh2_error(session, LIBSSH2_ERROR_FILE, "Invalid key data, not base64 encoded", 0); libssh2_error(session, LIBSSH2_ERROR_FILE, "Invalid key data, not base64 encoded", 0);
LIBSSH2_FREE(session, pubkey); LIBSSH2_FREE(session, pubkey);
return -1; return -1;
@@ -313,20 +318,18 @@ static int libssh2_file_read_publickey(LIBSSH2_SESSION *session, unsigned char *
/* {{{ libssh2_file_read_privatekey /* {{{ libssh2_file_read_privatekey
* Read a PEM encoded private key from an id_??? style file * Read a PEM encoded private key from an id_??? style file
*/ */
static int libssh2_file_read_privatekey(LIBSSH2_SESSION *session, LIBSSH2_HOSTKEY_METHOD **hostkey_method, void **hostkey_abstract, static int libssh2_file_read_privatekey(LIBSSH2_SESSION *session, const LIBSSH2_HOSTKEY_METHOD **hostkey_method, void **hostkey_abstract,
const char *method, int method_len, const unsigned char *method, int method_len,
const char *privkeyfile, const char *passphrase) const char *privkeyfile, const char *passphrase)
{ {
LIBSSH2_HOSTKEY_METHOD **hostkey_methods_avail = libssh2_hostkey_methods(); const LIBSSH2_HOSTKEY_METHOD **hostkey_methods_avail = libssh2_hostkey_methods();
#ifdef LIBSSH2_DEBUG_USERAUTH
_libssh2_debug(session, LIBSSH2_DBG_AUTH, "Loading private key file: %s", privkeyfile); _libssh2_debug(session, LIBSSH2_DBG_AUTH, "Loading private key file: %s", privkeyfile);
#endif
*hostkey_method = NULL; *hostkey_method = NULL;
*hostkey_abstract = NULL; *hostkey_abstract = NULL;
while (*hostkey_methods_avail && (*hostkey_methods_avail)->name) { while (*hostkey_methods_avail && (*hostkey_methods_avail)->name) {
if ((*hostkey_methods_avail)->initPEM && if ((*hostkey_methods_avail)->initPEM &&
strncmp((*hostkey_methods_avail)->name, method, method_len) == 0) { strncmp((*hostkey_methods_avail)->name, (const char *)method, method_len) == 0) {
*hostkey_method = *hostkey_methods_avail; *hostkey_method = *hostkey_methods_avail;
break; break;
} }
@@ -349,17 +352,18 @@ static int libssh2_file_read_privatekey(LIBSSH2_SESSION *session, LIBSSH2_HOSTKE
/* {{{ libssh2_userauth_hostbased_fromfile_ex /* {{{ libssh2_userauth_hostbased_fromfile_ex
* Authenticate using a keypair found in the named files * Authenticate using a keypair found in the named files
*/ */
LIBSSH2_API int libssh2_userauth_hostbased_fromfile_ex(LIBSSH2_SESSION *session, const char *username, int username_len, LIBSSH2_API int libssh2_userauth_hostbased_fromfile_ex(LIBSSH2_SESSION *session, const char *username, unsigned int username_len,
const char *publickey, const char *privatekey, const char *publickey, const char *privatekey,
const char *passphrase, const char *passphrase,
const char *hostname, int hostname_len, const char *hostname, unsigned int hostname_len,
const char *local_username, int local_username_len) const char *local_username, unsigned int local_username_len)
{ {
LIBSSH2_HOSTKEY_METHOD *privkeyobj; const LIBSSH2_HOSTKEY_METHOD *privkeyobj;
void *abstract; void *abstract;
unsigned char buf[5]; unsigned char buf[5];
struct iovec datavec[4]; struct iovec datavec[4];
unsigned char *method, *pubkeydata, *packet, *s, *sig, *data, reply_codes[3] = { SSH_MSG_USERAUTH_SUCCESS, SSH_MSG_USERAUTH_FAILURE, 0 }; unsigned char *method, *pubkeydata, *packet, *s, *sig, *data;
static const unsigned char reply_codes[3] = { SSH_MSG_USERAUTH_SUCCESS, SSH_MSG_USERAUTH_FAILURE, 0 };
unsigned long method_len, pubkeydata_len, packet_len, sig_len, data_len; unsigned long method_len, pubkeydata_len, packet_len, sig_len, data_len;
if (libssh2_file_read_publickey(session, &method, &method_len, &pubkeydata, &pubkeydata_len, publickey)) { if (libssh2_file_read_publickey(session, &method, &method_len, &pubkeydata, &pubkeydata_len, publickey)) {
@@ -374,6 +378,10 @@ LIBSSH2_API int libssh2_userauth_hostbased_fromfile_ex(LIBSSH2_SESSION *session,
/* Preallocate space for an overall length, method name again, /* Preallocate space for an overall length, method name again,
* and the signature, which won't be any larger than the size of the publickeydata itself */ * and the signature, which won't be any larger than the size of the publickeydata itself */
s = packet = LIBSSH2_ALLOC(session, packet_len + 4 + (4 + method_len) + (4 + pubkeydata_len)); s = packet = LIBSSH2_ALLOC(session, packet_len + 4 + (4 + method_len) + (4 + pubkeydata_len));
if (!packet) {
LIBSSH2_FREE(session, method);
return -1;
}
*(s++) = SSH_MSG_USERAUTH_REQUEST; *(s++) = SSH_MSG_USERAUTH_REQUEST;
libssh2_htonu32(s, username_len); s += 4; libssh2_htonu32(s, username_len); s += 4;
@@ -424,14 +432,18 @@ LIBSSH2_API int libssh2_userauth_hostbased_fromfile_ex(LIBSSH2_SESSION *session,
privkeyobj->dtor(session, &abstract); privkeyobj->dtor(session, &abstract);
} }
if (sig_len > pubkeydata_len ) { if (sig_len > pubkeydata_len) {
unsigned char *newpacket;
/* Should *NEVER* happen, but...well.. better safe than sorry */ /* Should *NEVER* happen, but...well.. better safe than sorry */
packet = LIBSSH2_REALLOC(session, packet, packet_len + 4 + (4 + method_len) + (4 + sig_len)); /* PK sigblob */ newpacket = LIBSSH2_REALLOC(session, packet, packet_len + 4 + (4 + method_len) + (4 + sig_len)); /* PK sigblob */
if (!packet) { if (!newpacket) {
libssh2_error(session, LIBSSH2_ERROR_ALLOC, "Failed allocating additional space for userauth-hostbased packet", 0); libssh2_error(session, LIBSSH2_ERROR_ALLOC, "Failed allocating additional space for userauth-hostbased packet", 0);
LIBSSH2_FREE(session, sig);
LIBSSH2_FREE(session, packet);
LIBSSH2_FREE(session, method); LIBSSH2_FREE(session, method);
return -1; return -1;
} }
packet = newpacket;
} }
s = packet + packet_len; s = packet + packet_len;
@@ -446,9 +458,7 @@ LIBSSH2_API int libssh2_userauth_hostbased_fromfile_ex(LIBSSH2_SESSION *session,
memcpy(s, sig, sig_len); s += sig_len; memcpy(s, sig, sig_len); s += sig_len;
LIBSSH2_FREE(session, sig); LIBSSH2_FREE(session, sig);
#ifdef LIBSSH2_DEBUG_USERAUTH
_libssh2_debug(session, LIBSSH2_DBG_AUTH, "Attempting hostbased authentication"); _libssh2_debug(session, LIBSSH2_DBG_AUTH, "Attempting hostbased authentication");
#endif
if (libssh2_packet_write(session, packet, s - packet)) { if (libssh2_packet_write(session, packet, s - packet)) {
libssh2_error(session, LIBSSH2_ERROR_SOCKET_SEND, "Unable to send userauth-hostbased request", 0); libssh2_error(session, LIBSSH2_ERROR_SOCKET_SEND, "Unable to send userauth-hostbased request", 0);
LIBSSH2_FREE(session, packet); LIBSSH2_FREE(session, packet);
@@ -461,9 +471,8 @@ LIBSSH2_API int libssh2_userauth_hostbased_fromfile_ex(LIBSSH2_SESSION *session,
} }
if (data[0] == SSH_MSG_USERAUTH_SUCCESS) { if (data[0] == SSH_MSG_USERAUTH_SUCCESS) {
#ifdef LIBSSH2_DEBUG_USERAUTH _libssh2_debug(session, LIBSSH2_DBG_AUTH,
_libssh2_debug(session, LIBSSH2_DBG_AUTH, "Hostbased authentication successful"); "Hostbased authentication successful");
#endif
/* We are us and we've proved it. */ /* We are us and we've proved it. */
LIBSSH2_FREE(session, data); LIBSSH2_FREE(session, data);
session->state |= LIBSSH2_STATE_AUTHENTICATED; session->state |= LIBSSH2_STATE_AUTHENTICATED;
@@ -480,11 +489,11 @@ LIBSSH2_API int libssh2_userauth_hostbased_fromfile_ex(LIBSSH2_SESSION *session,
/* {{{ libssh2_userauth_publickey_fromfile_ex /* {{{ libssh2_userauth_publickey_fromfile_ex
* Authenticate using a keypair found in the named files * Authenticate using a keypair found in the named files
*/ */
LIBSSH2_API int libssh2_userauth_publickey_fromfile_ex(LIBSSH2_SESSION *session, const char *username, int username_len, LIBSSH2_API int libssh2_userauth_publickey_fromfile_ex(LIBSSH2_SESSION *session, const char *username, unsigned int username_len,
const char *publickey, const char *privatekey, const char *publickey, const char *privatekey,
const char *passphrase) const char *passphrase)
{ {
LIBSSH2_HOSTKEY_METHOD *privkeyobj; const LIBSSH2_HOSTKEY_METHOD *privkeyobj;
void *abstract; void *abstract;
unsigned char buf[5]; unsigned char buf[5];
struct iovec datavec[4]; struct iovec datavec[4];
@@ -503,6 +512,11 @@ LIBSSH2_API int libssh2_userauth_publickey_fromfile_ex(LIBSSH2_SESSION *session,
/* Preallocate space for an overall length, method name again, /* Preallocate space for an overall length, method name again,
* and the signature, which won't be any larger than the size of the publickeydata itself */ * and the signature, which won't be any larger than the size of the publickeydata itself */
s = packet = LIBSSH2_ALLOC(session, packet_len + 4 + (4 + method_len) + (4 + pubkeydata_len)); s = packet = LIBSSH2_ALLOC(session, packet_len + 4 + (4 + method_len) + (4 + pubkeydata_len));
if (!packet) {
LIBSSH2_FREE(session, method);
LIBSSH2_FREE(session, pubkeydata);
return -1;
}
*(s++) = SSH_MSG_USERAUTH_REQUEST; *(s++) = SSH_MSG_USERAUTH_REQUEST;
libssh2_htonu32(s, username_len); s += 4; libssh2_htonu32(s, username_len); s += 4;
@@ -522,34 +536,28 @@ LIBSSH2_API int libssh2_userauth_publickey_fromfile_ex(LIBSSH2_SESSION *session,
libssh2_htonu32(s, pubkeydata_len); s += 4; libssh2_htonu32(s, pubkeydata_len); s += 4;
memcpy(s, pubkeydata, pubkeydata_len); s += pubkeydata_len; memcpy(s, pubkeydata, pubkeydata_len); s += pubkeydata_len;
LIBSSH2_FREE(session, pubkeydata);
#ifdef LIBSSH2_DEBUG_USERAUTH
_libssh2_debug(session, LIBSSH2_DBG_AUTH, "Attempting publickey authentication"); _libssh2_debug(session, LIBSSH2_DBG_AUTH, "Attempting publickey authentication");
#endif
if (libssh2_packet_write(session, packet, packet_len)) { if (libssh2_packet_write(session, packet, packet_len)) {
libssh2_error(session, LIBSSH2_ERROR_SOCKET_SEND, "Unable to send userauth-publickey request", 0); libssh2_error(session, LIBSSH2_ERROR_SOCKET_SEND, "Unable to send userauth-publickey request", 0);
LIBSSH2_FREE(session, packet); LIBSSH2_FREE(session, packet);
LIBSSH2_FREE(session, method); LIBSSH2_FREE(session, method);
LIBSSH2_FREE(session, pubkeydata);
return -1; return -1;
} }
if (libssh2_packet_requirev(session, reply_codes, &data, &data_len)) { if (libssh2_packet_requirev(session, reply_codes, &data, &data_len)) {
LIBSSH2_FREE(session, packet); LIBSSH2_FREE(session, packet);
LIBSSH2_FREE(session, method); LIBSSH2_FREE(session, method);
LIBSSH2_FREE(session, pubkeydata);
return -1; return -1;
} }
if (data[0] == SSH_MSG_USERAUTH_SUCCESS) { if (data[0] == SSH_MSG_USERAUTH_SUCCESS) {
#ifdef LIBSSH2_DEBUG_USERAUTH
_libssh2_debug(session, LIBSSH2_DBG_AUTH, "Pubkey authentication prematurely successful"); _libssh2_debug(session, LIBSSH2_DBG_AUTH, "Pubkey authentication prematurely successful");
#endif
/* God help any SSH server that allows an UNVERIFIED public key to validate the user */ /* God help any SSH server that allows an UNVERIFIED public key to validate the user */
LIBSSH2_FREE(session, data); LIBSSH2_FREE(session, data);
LIBSSH2_FREE(session, packet); LIBSSH2_FREE(session, packet);
LIBSSH2_FREE(session, method); LIBSSH2_FREE(session, method);
LIBSSH2_FREE(session, pubkeydata);
session->state |= LIBSSH2_STATE_AUTHENTICATED; session->state |= LIBSSH2_STATE_AUTHENTICATED;
return 0; return 0;
} }
@@ -559,14 +567,12 @@ LIBSSH2_API int libssh2_userauth_publickey_fromfile_ex(LIBSSH2_SESSION *session,
LIBSSH2_FREE(session, data); LIBSSH2_FREE(session, data);
LIBSSH2_FREE(session, packet); LIBSSH2_FREE(session, packet);
LIBSSH2_FREE(session, method); LIBSSH2_FREE(session, method);
LIBSSH2_FREE(session, pubkeydata);
libssh2_error(session, LIBSSH2_ERROR_PUBLICKEY_UNRECOGNIZED, "Username/PublicKey combination invalid", 0); libssh2_error(session, LIBSSH2_ERROR_PUBLICKEY_UNRECOGNIZED, "Username/PublicKey combination invalid", 0);
return -1; return -1;
} }
/* Semi-Success! */ /* Semi-Success! */
LIBSSH2_FREE(session, data); LIBSSH2_FREE(session, data);
LIBSSH2_FREE(session, pubkeydata);
if (libssh2_file_read_privatekey(session, &privkeyobj, &abstract, method, method_len, privatekey, passphrase)) { if (libssh2_file_read_privatekey(session, &privkeyobj, &abstract, method, method_len, privatekey, passphrase)) {
LIBSSH2_FREE(session, method); LIBSSH2_FREE(session, method);
@@ -598,13 +604,17 @@ LIBSSH2_API int libssh2_userauth_publickey_fromfile_ex(LIBSSH2_SESSION *session,
} }
if (sig_len > pubkeydata_len) { if (sig_len > pubkeydata_len) {
unsigned char *newpacket;
/* Should *NEVER* happen, but...well.. better safe than sorry */ /* Should *NEVER* happen, but...well.. better safe than sorry */
packet = LIBSSH2_REALLOC(session, packet, packet_len + 4 + (4 + method_len) + (4 + sig_len)); /* PK sigblob */ newpacket = LIBSSH2_REALLOC(session, packet, packet_len + 4 + (4 + method_len) + (4 + sig_len)); /* PK sigblob */
if (!packet) { if (!newpacket) {
libssh2_error(session, LIBSSH2_ERROR_ALLOC, "Failed allocating additional space for userauth-publickey packet", 0); libssh2_error(session, LIBSSH2_ERROR_ALLOC, "Failed allocating additional space for userauth-publickey packet", 0);
LIBSSH2_FREE(session, sig);
LIBSSH2_FREE(session, packet);
LIBSSH2_FREE(session, method); LIBSSH2_FREE(session, method);
return -1; return -1;
} }
packet = newpacket;
} }
s = packet + packet_len; s = packet + packet_len;
@@ -619,9 +629,7 @@ LIBSSH2_API int libssh2_userauth_publickey_fromfile_ex(LIBSSH2_SESSION *session,
memcpy(s, sig, sig_len); s += sig_len; memcpy(s, sig, sig_len); s += sig_len;
LIBSSH2_FREE(session, sig); LIBSSH2_FREE(session, sig);
#ifdef LIBSSH2_DEBUG_USERAUTH
_libssh2_debug(session, LIBSSH2_DBG_AUTH, "Attempting publickey authentication -- phase 2"); _libssh2_debug(session, LIBSSH2_DBG_AUTH, "Attempting publickey authentication -- phase 2");
#endif
if (libssh2_packet_write(session, packet, s - packet)) { if (libssh2_packet_write(session, packet, s - packet)) {
libssh2_error(session, LIBSSH2_ERROR_SOCKET_SEND, "Unable to send userauth-publickey request", 0); libssh2_error(session, LIBSSH2_ERROR_SOCKET_SEND, "Unable to send userauth-publickey request", 0);
LIBSSH2_FREE(session, packet); LIBSSH2_FREE(session, packet);
@@ -637,9 +645,7 @@ LIBSSH2_API int libssh2_userauth_publickey_fromfile_ex(LIBSSH2_SESSION *session,
} }
if (data[0] == SSH_MSG_USERAUTH_SUCCESS) { if (data[0] == SSH_MSG_USERAUTH_SUCCESS) {
#ifdef LIBSSH2_DEBUG_USERAUTH
_libssh2_debug(session, LIBSSH2_DBG_AUTH, "Publickey authentication successful"); _libssh2_debug(session, LIBSSH2_DBG_AUTH, "Publickey authentication successful");
#endif
/* We are us and we've proved it. */ /* We are us and we've proved it. */
LIBSSH2_FREE(session, data); LIBSSH2_FREE(session, data);
session->state |= LIBSSH2_STATE_AUTHENTICATED; session->state |= LIBSSH2_STATE_AUTHENTICATED;
@@ -656,7 +662,7 @@ LIBSSH2_API int libssh2_userauth_publickey_fromfile_ex(LIBSSH2_SESSION *session,
/* {{{ libssh2_userauth_keyboard_interactive /* {{{ libssh2_userauth_keyboard_interactive
* Authenticate using a challenge-response authentication * Authenticate using a challenge-response authentication
*/ */
LIBSSH2_API int libssh2_userauth_keyboard_interactive_ex(LIBSSH2_SESSION *session, const char *username, int username_len, LIBSSH2_API int libssh2_userauth_keyboard_interactive_ex(LIBSSH2_SESSION *session, const char *username, unsigned int username_len,
LIBSSH2_USERAUTH_KBDINT_RESPONSE_FUNC((*response_callback))) LIBSSH2_USERAUTH_KBDINT_RESPONSE_FUNC((*response_callback)))
{ {
unsigned char *s, *data; /* packet */ unsigned char *s, *data; /* packet */
@@ -695,9 +701,7 @@ LIBSSH2_API int libssh2_userauth_keyboard_interactive_ex(LIBSSH2_SESSION *sessio
/* submethods */ /* submethods */
libssh2_htonu32(s, 0); s += 4; libssh2_htonu32(s, 0); s += 4;
#ifdef LIBSSH2_DEBUG_USERAUTH
_libssh2_debug(session, LIBSSH2_DBG_AUTH, "Attempting keyboard-interactive authentication"); _libssh2_debug(session, LIBSSH2_DBG_AUTH, "Attempting keyboard-interactive authentication");
#endif
if (libssh2_packet_write(session, data, packet_len)) { if (libssh2_packet_write(session, data, packet_len)) {
libssh2_error(session, LIBSSH2_ERROR_SOCKET_SEND, "Unable to send keyboard-interactive request", 0); libssh2_error(session, LIBSSH2_ERROR_SOCKET_SEND, "Unable to send keyboard-interactive request", 0);
LIBSSH2_FREE(session, data); LIBSSH2_FREE(session, data);
@@ -706,7 +710,7 @@ LIBSSH2_API int libssh2_userauth_keyboard_interactive_ex(LIBSSH2_SESSION *sessio
LIBSSH2_FREE(session, data); LIBSSH2_FREE(session, data);
for (;;) { for (;;) {
unsigned char reply_codes[4] = { SSH_MSG_USERAUTH_SUCCESS, SSH_MSG_USERAUTH_FAILURE, SSH_MSG_USERAUTH_INFO_REQUEST, 0 }; static const unsigned char reply_codes[4] = { SSH_MSG_USERAUTH_SUCCESS, SSH_MSG_USERAUTH_FAILURE, SSH_MSG_USERAUTH_INFO_REQUEST, 0 };
unsigned int auth_name_len; unsigned int auth_name_len;
char* auth_name = NULL; char* auth_name = NULL;
unsigned auth_instruction_len; unsigned auth_instruction_len;
@@ -724,9 +728,7 @@ LIBSSH2_API int libssh2_userauth_keyboard_interactive_ex(LIBSSH2_SESSION *sessio
} }
if (data[0] == SSH_MSG_USERAUTH_SUCCESS) { if (data[0] == SSH_MSG_USERAUTH_SUCCESS) {
#ifdef LIBSSH2_DEBUG_USERAUTH
_libssh2_debug(session, LIBSSH2_DBG_AUTH, "Keyboard-interactive authentication successful"); _libssh2_debug(session, LIBSSH2_DBG_AUTH, "Keyboard-interactive authentication successful");
#endif
LIBSSH2_FREE(session, data); LIBSSH2_FREE(session, data);
session->state |= LIBSSH2_STATE_AUTHENTICATED; session->state |= LIBSSH2_STATE_AUTHENTICATED;
return 0; return 0;
@@ -793,9 +795,7 @@ LIBSSH2_API int libssh2_userauth_keyboard_interactive_ex(LIBSSH2_SESSION *sessio
response_callback(auth_name, auth_name_len, auth_instruction, auth_instruction_len, num_prompts, prompts, responses, &session->abstract); response_callback(auth_name, auth_name_len, auth_instruction, auth_instruction_len, num_prompts, prompts, responses, &session->abstract);
#ifdef LIBSSH2_DEBUG_USERAUTH
_libssh2_debug(session, LIBSSH2_DBG_AUTH, "Keyboard-interactive response callback function invoked"); _libssh2_debug(session, LIBSSH2_DBG_AUTH, "Keyboard-interactive response callback function invoked");
#endif
packet_len = 1 /* byte SSH_MSG_USERAUTH_INFO_RESPONSE */ packet_len = 1 /* byte SSH_MSG_USERAUTH_INFO_RESPONSE */
+ 4 /* int num-responses */ + 4 /* int num-responses */

5
tests/.cvsignore Normal file
View File

@@ -0,0 +1,5 @@
.deps
.libs
Makefile
Makefile.in
simple

6
tests/Makefile.am Normal file
View File

@@ -0,0 +1,6 @@
AM_CPPFLAGS = -I$(top_srcdir)/include
LDADD = ../src/libssh2.la
ctests = simple
TESTS = $(ctests)
check_PROGRAMS = $(ctests)

56
tests/simple.c Normal file
View File

@@ -0,0 +1,56 @@
/* Copyright (C) 2007 The Written Word, Inc. All rights reserved.
* Author: Simon Josefsson
*
* Redistribution and use in source and binary forms,
* with or without modification, are permitted provided
* that the following conditions are met:
*
* Redistributions of source code must retain the above
* copyright notice, this list of conditions and the
* following disclaimer.
*
* Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following
* disclaimer in the documentation and/or other materials
* provided with the distribution.
*
* Neither the name of the copyright holder nor the names
* of any other contributors may be used to endorse or
* promote products derived from this software without
* specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
* CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
* USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
* OF SUCH DAMAGE.
*/
#include <stdio.h>
#include "libssh2.h"
int main(int argc, char *argv[])
{
LIBSSH2_SESSION *session;
session = libssh2_session_init();
if (!session)
{
fprintf (stderr, "libssh2_session_init() failed\n");
return 1;
}
libssh2_session_free(session);
return 0;
}

2
win32/Makefile Normal file
View File

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

311
win32/Makefile.win32 Normal file
View File

@@ -0,0 +1,311 @@
#########################################################################
#
## Makefile for building libssh2 (Win32 version - gnu make)
## Use: make -f Makefile.win32 [help|all|clean|dev|devclean|dist|distclean|dll|objclean]
##
## Comments to: Guenter Knauf <eflash@gmx.net>
##
## $Id: Makefile.win32,v 1.7 2007/04/21 23:36:51 gknauf Exp $
#
#########################################################################
# Edit the path below to point to the base of your Zlib sources.
ifndef ZLIB_PATH
ZLIB_PATH = ../../zlib-1.2.3
endif
# Edit the path below to point to the base of your OpenSSL package.
ifndef OPENSSL_PATH
OPENSSL_PATH = ../../openssl-0.9.8e
endif
# Edit the path below to point to your Distribution folder.
ifndef DISTDIR
DISTDIR = libssh2-$(LIBSSH2_VERSION_STR)-bin-w32
endif
DISTARC = $(DISTDIR).zip
# Edit the path below to point to your Development folder.
ifndef DEVLDIR
DEVLDIR = libssh2-$(LIBSSH2_VERSION_STR)-dev-w32
endif
DEVLARC = $(DEVLDIR).zip
# Edit the vars below to change target settings.
TARGET = libssh2
VERSION = $(LIBSSH2_VERSION)
COPYR = (c) 2004-2007 Sara Golemon <sarag@libssh2.org>
WWWURL = http://www.libssh2.org/
DESCR = libssh2 $(LIBSSH2_VERSION_STR)
#STACK = 64000
# must be equal to DEBUG or NDEBUG
ifndef DB
DB = NDEBUG
# DB = DEBUG
endif
# Optimization: -O<n> or debugging: -g
ifeq ($(DB),NDEBUG)
OPT = -O2
OBJDIR = release
else
OPT = -g
OPT += -DLIBSSH2DEBUG
OBJDIR = debug
endif
# Include the version info retrieved from libssh2.h
-include $(OBJDIR)/version.inc
# The following line defines your compiler.
ifdef METROWERKS
CC = mwcc
else
CC = gcc
endif
CP = cp -afv
# RM = rm -f
AWK = awk
ZIP = zip -qzr9
# Global flags for all compilers
CFLAGS = $(OPT) -D$(DB) -DWIN32 -DLIBSSH2_WIN32 # -DHAVE_CONFIG_H
ifeq ($(CC),mwcc)
LD = mwld
RC = mwwinrc
LDFLAGS = -nostdlib
AR = $(LD)
ARFLAGS = -nostdlib -library -o
LIBEXT = lib
#RANLIB =
LIBPATH += -lr "$(METROWERKS)/MSL" -lr "$(METROWERKS)/Win32-x86 Support"
LDLIBS += -lMSL_Runtime_x86.lib -lMSL_C_x86.lib -lMSL_Extras_x86.lib
LDLIBS += -lkernel32.lib -luser32.lib -lwsock32.lib
RCFLAGS =
CFLAGS += -nostdinc -gccinc -msgstyle gcc -inline off -opt nointrinsics -proc 586
CFLAGS += -ir "$(METROWERKS)/MSL" -ir "$(METROWERKS)/Win32-x86 Support"
CFLAGS += -w on,nounused,nounusedexpr # -ansi strict
else
LD = gcc
RC = windres
LDFLAGS = -s -shared -Wl,--out-implib,$(TARGET)dll.a
AR = ar
ARFLAGS = -cq
LIBEXT = a
RANLIB = ranlib
#LDLIBS += -lwsock32
LDLIBS += -lws2_32
RCFLAGS = -O coff -i
CFLAGS += -fno-strict-aliasing
CFLAGS += -Wall # -pedantic
endif
INCLUDES = -I. -I../include
INCLUDES += -I$(OPENSSL_PATH)/outinc -I$(OPENSSL_PATH)/outinc/openssl
ifdef LINK_STATIC
LDLIBS += $(OPENSSL_PATH)/out/libcrypto.$(LIBEXT) $(OPENSSL_PATH)/out/libssl.$(LIBEXT)
else
LDLIBS += $(OPENSSL_PATH)/out/libeay32.$(LIBEXT) $(OPENSSL_PATH)/out/libssl32.$(LIBEXT)
endif
ifdef WITH_ZLIB
INCLUDES += -I$(ZLIB_PATH)
LDLIBS += $(ZLIB_PATH)/libz.$(LIBEXT)
endif
CFLAGS += $(INCLUDES)
#ifeq ($(findstring msys,$(OSTYPE)),msys)
ifdef __MSYS__
DL = '
DS = /
else
DS = \\
endif
vpath %.c . ../src
OBJECTS = \
channel.o \
comp.o \
crypt.o \
hostkey.o \
kex.o \
mac.o \
misc.o \
openssl.o \
packet.o \
pem.o \
publickey.o \
scp.o \
session.o \
sftp.o \
transport.o \
userauth.o
OBJS := $(addprefix $(OBJDIR)/,$(OBJECTS))
OBJL = $(OBJS) $(OBJDIR)/$(TARGET).res
all: lib dll
dll: prebuild $(TARGET).dll
lib: prebuild $(TARGET).$(LIBEXT)
prebuild: $(OBJDIR) $(OBJDIR)/version.inc
# libssh2_config.h
test: all
$(MAKE) -C test -f Makefile.win32
$(OBJDIR)/%.o: %.c
# @echo Compiling $<
$(CC) $(CFLAGS) -c $< -o $@
$(OBJDIR)/version.inc: ../include/libssh2.h $(OBJDIR)
@echo Creating $@
@$(AWK) -f ../get_ver.awk $< > $@
dist: all $(DISTDIR) $(DISTDIR)/readme.txt
@-mkdir $(DISTDIR)$(DS)bin
@-$(CP) ../INSTALL $(DISTDIR)
@-$(CP) ../LICENSE $(DISTDIR)
@-$(CP) ../README $(DISTDIR)
@$(CP) $(TARGET).dll $(DISTDIR)/bin
@echo Creating $(DISTARC)
@$(ZIP) $(DISTARC) $(DISTDIR)/* < $(DISTDIR)/readme.txt
dev: all $(DEVLDIR) $(DEVLDIR)/readme.txt
@-mkdir $(DEVLDIR)$(DS)bin
@-mkdir $(DEVLDIR)$(DS)include
@-mkdir $(DEVLDIR)$(DS)win32
@-$(CP) ../INSTALL $(DEVLDIR)
@-$(CP) ../LICENSE $(DEVLDIR)
@-$(CP) ../README $(DEVLDIR)
@$(CP) $(TARGET).dll $(DEVLDIR)/bin
@$(CP) ../include/*.h $(DEVLDIR)/include
@$(CP) libssh2_config.h $(DEVLDIR)/include
@$(CP) *.$(LIBEXT) $(DEVLDIR)/win32
@echo Creating $(DEVLARC)
@$(ZIP) $(DEVLARC) $(DEVLDIR)/* < $(DEVLDIR)/readme.txt
distclean: clean
-$(RM) -r $(DISTDIR)
-$(RM) $(DISTARC)
devclean: clean
-$(RM) -r $(DEVLDIR)
-$(RM) $(DEVLARC)
objclean: all
-$(RM) -r $(OBJDIR)
testclean: clean
$(MAKE) -C test -f Makefile.win32 clean
clean:
# -$(RM) libssh2_config.h
-$(RM) $(TARGET).dll $(TARGET).$(LIBEXT) $(TARGET)dll.$(LIBEXT)
-$(RM) -r $(OBJDIR)
$(OBJDIR):
@mkdir $@
$(DISTDIR):
@mkdir $@
$(DEVLDIR):
@mkdir $@
$(TARGET).$(LIBEXT): $(OBJS)
@echo Creating $@
@-$(RM) $@
@$(AR) $(ARFLAGS) $@ $^
ifdef RANLIB
@$(RANLIB) $@
endif
$(TARGET).dll $(TARGET)dll.a: $(OBJL)
@echo Linking $@
@-$(RM) $@
@$(LD) $(LDFLAGS) $^ -o $@ $(LIBPATH) $(LDLIBS)
$(OBJDIR)/%.res: $(OBJDIR)/%.rc
@echo Creating $@
@$(RC) $(RCFLAGS) $< -o $@
$(OBJDIR)/%.rc: Makefile.win32 $(OBJDIR)/version.inc
@echo $(DL)1 VERSIONINFO$(DL) > $@
@echo $(DL) FILEVERSION $(LIBSSH2_VERSION),0$(DL) >> $@
@echo $(DL) PRODUCTVERSION $(LIBSSH2_VERSION),0$(DL) >> $@
@echo $(DL) FILEFLAGSMASK 0x3fL$(DL) >> $@
@echo $(DL) FILEOS 0x40004L$(DL) >> $@
@echo $(DL) FILEFLAGS 0x0L$(DL) >> $@
@echo $(DL) FILETYPE 0x1L$(DL) >> $@
@echo $(DL) FILESUBTYPE 0x0L$(DL) >> $@
@echo $(DL)BEGIN$(DL) >> $@
@echo $(DL) BLOCK "StringFileInfo"$(DL) >> $@
@echo $(DL) BEGIN$(DL) >> $@
@echo $(DL) BLOCK "040904E4"$(DL) >> $@
@echo $(DL) BEGIN$(DL) >> $@
@echo $(DL) VALUE "LegalCopyright","$(COPYR)\0"$(DL) >> $@
ifdef COMPANY
@echo $(DL) VALUE "CompanyName","$(COMPANY)\0"$(DL) >> $@
endif
@echo $(DL) VALUE "ProductName","$(notdir $(@:.rc=.dll))\0"$(DL) >> $@
@echo $(DL) VALUE "ProductVersion","$(LIBSSH2_VERSION_STR)\0"$(DL) >> $@
@echo $(DL) VALUE "License","Released under GPL.\0"$(DL) >> $@
@echo $(DL) VALUE "FileDescription","$(DESCR)\0"$(DL) >> $@
@echo $(DL) VALUE "FileVersion","$(LIBSSH2_VERSION_STR)\0"$(DL) >> $@
@echo $(DL) VALUE "InternalName","$(notdir $(@:.rc=))\0"$(DL) >> $@
@echo $(DL) VALUE "OriginalFilename","$(notdir $(@:.rc=.dll))\0"$(DL) >> $@
@echo $(DL) VALUE "WWW","$(WWWURL)\0"$(DL) >> $@
@echo $(DL) END$(DL) >> $@
@echo $(DL) END$(DL) >> $@
@echo $(DL) BLOCK "VarFileInfo"$(DL) >> $@
@echo $(DL) BEGIN$(DL) >> $@
@echo $(DL) VALUE "Translation", 0x409, 1252$(DL) >> $@
@echo $(DL) END$(DL) >> $@
@echo $(DL)END$(DL) >> $@
ifdef ICON
@echo $(DL)10 ICON DISCARDABLE "$(ICON)"$(DL) >> $@
endif
$(DISTDIR)/readme.txt: Makefile.win32
@echo Creating $@
@echo $(DL)This is a binary distribution for Win32 platform.$(DL) > $@
@echo $(DL)libssh version $(LIBSSH2_VERSION_STR)$(DL) >> $@
@echo $(DL)Please download the complete libssh package for$(DL) >> $@
@echo $(DL)any further documentation:$(DL) >> $@
@echo $(DL)$(WWWURL)$(DL) >> $@
$(DEVLDIR)/readme.txt: Makefile.win32
@echo Creating $@
@echo $(DL)This is a development distribution for Win32 platform.$(DL) > $@
@echo $(DL)libssh version $(LIBSSH2_VERSION_STR)$(DL) >> $@
@echo $(DL)Please download the complete libssh package for$(DL) >> $@
@echo $(DL)any further documentation:$(DL) >> $@
@echo $(DL)$(WWWURL)$(DL) >> $@
help: $(OBJDIR)/version.inc
@echo $(DL)===========================================================$(DL)
@echo $(DL)OpenSSL path = $(OPENSSL_PATH)$(DL)
@echo $(DL)Zlib path = $(ZLIB_PATH)$(DL)
@echo $(DL)===========================================================$(DL)
@echo $(DL)libssh $(LIBSSH2_VERSION_STR) - available targets are:$(DL)
@echo $(DL)$(MAKE) all$(DL)
@echo $(DL)$(MAKE) dll$(DL)
@echo $(DL)$(MAKE) lib$(DL)
@echo $(DL)$(MAKE) clean$(DL)
@echo $(DL)$(MAKE) dev$(DL)
@echo $(DL)$(MAKE) devclean$(DL)
@echo $(DL)$(MAKE) dist$(DL)
@echo $(DL)$(MAKE) distclean$(DL)
@echo $(DL)$(MAKE) objclean$(DL)
@echo $(DL)$(MAKE) test$(DL)
@echo $(DL)===========================================================$(DL)

View File

@@ -1,3 +1,6 @@
#ifndef LIBSSH2_CONFIG_H
#define LIBSSH2_CONFIG_H
#ifndef WIN32 #ifndef WIN32
#define WIN32 #define WIN32
#endif #endif
@@ -5,6 +8,16 @@
#include <mswsock.h> #include <mswsock.h>
#include <ws2tcpip.h> #include <ws2tcpip.h>
#ifdef __MINGW32__
#define WINSOCK_VERSION MAKEWORD(2,0)
#define HAVE_UNISTD_H
#define HAVE_INTTYPES_H
#define HAVE_SYS_TIME_H
#endif
#define HAVE_WINSOCK2_H
#define HAVE_IOCTLSOCKET
/* same as WSABUF */ /* same as WSABUF */
struct iovec { struct iovec {
u_long iov_len; u_long iov_len;
@@ -36,3 +49,7 @@ static inline int usleep(int udelay)
/* Enable newer diffie-hellman-group-exchange-sha1 syntax */ /* Enable newer diffie-hellman-group-exchange-sha1 syntax */
#define LIBSSH2_DH_GEX_NEW 1 #define LIBSSH2_DH_GEX_NEW 1
#endif /* LIBSSH2_CONFIG_H */

Some files were not shown because too many files have changed in this diff Show More