Compare commits
117 Commits
beforenb-0
...
beforenb2-
Author | SHA1 | Date | |
---|---|---|---|
![]() |
9896c291e4 | ||
![]() |
412b25d971 | ||
![]() |
355c9c634b | ||
![]() |
62f77b1e4b | ||
![]() |
145bbabb96 | ||
![]() |
40970adb53 | ||
![]() |
34bcc69a1a | ||
![]() |
046edb478f | ||
![]() |
54e6528822 | ||
![]() |
a66885c51c | ||
![]() |
510df9bf52 | ||
![]() |
61807e8d4d | ||
![]() |
9ff217b6d2 | ||
![]() |
c43c390a7d | ||
![]() |
7eccfc7fbc | ||
![]() |
d79939fc3a | ||
![]() |
c5fb9d8f1a | ||
![]() |
e85a2199b6 | ||
![]() |
3bd3eb35b3 | ||
![]() |
08fd7e259b | ||
![]() |
42f0f69a35 | ||
![]() |
75ac861c7a | ||
![]() |
04e975b6c7 | ||
![]() |
f14aa01bb8 | ||
![]() |
ab7c3fb2d4 | ||
![]() |
1ebe0a64b3 | ||
![]() |
6cd1c7528e | ||
![]() |
91c8715da4 | ||
![]() |
2dc313d365 | ||
![]() |
f8fe38e3a5 | ||
![]() |
bda32b6bbf | ||
![]() |
09deb228f1 | ||
![]() |
1a6e00cfef | ||
![]() |
9b81a01376 | ||
![]() |
4c6bfdd5b2 | ||
![]() |
5dd66e604f | ||
![]() |
d45d509a09 | ||
![]() |
d44e222b75 | ||
![]() |
197764afcc | ||
![]() |
d79f906b52 | ||
![]() |
08cf9fd7de | ||
![]() |
7edad3046e | ||
![]() |
f33375bc03 | ||
![]() |
159c351d05 | ||
![]() |
8371fa7b87 | ||
![]() |
0eefd06af0 | ||
![]() |
86ca80028b | ||
![]() |
0c060e1ccb | ||
![]() |
51e49f5a1e | ||
![]() |
93e36271a6 | ||
![]() |
6dfb2e3009 | ||
![]() |
a84d2ca430 | ||
![]() |
3026c46109 | ||
![]() |
4e920fe2be | ||
![]() |
164c6e9fc5 | ||
![]() |
0cf3845302 | ||
![]() |
149af707de | ||
![]() |
e1bc0adcb1 | ||
![]() |
2f207bdad5 | ||
![]() |
7972822465 | ||
![]() |
b370b89eeb | ||
![]() |
01d7396160 | ||
![]() |
43e377c08e | ||
![]() |
348b914ab7 | ||
![]() |
e7b3a2efc5 | ||
![]() |
56608a799f | ||
![]() |
f29f85f482 | ||
![]() |
2a48f54937 | ||
![]() |
4c7ecad34d | ||
![]() |
53d6597569 | ||
![]() |
af12b96a80 | ||
![]() |
e854459839 | ||
![]() |
af00ce242e | ||
![]() |
fa1d8da7a3 | ||
![]() |
2d7f1ad47c | ||
![]() |
0ace54f5b6 | ||
![]() |
7ebafd3999 | ||
![]() |
86cdc614c8 | ||
![]() |
15d9b50be4 | ||
![]() |
ebc55b5d75 | ||
![]() |
cf9ffc053a | ||
![]() |
25a810bbc8 | ||
![]() |
db2a895ecf | ||
![]() |
94a71fe995 | ||
![]() |
0eabcb386e | ||
![]() |
93dc3f565e | ||
![]() |
48410937b2 | ||
![]() |
864ceec7bd | ||
![]() |
8ac3f7e485 | ||
![]() |
2e20808f8c | ||
![]() |
53fb8b1969 | ||
![]() |
7dfbbf9c1c | ||
![]() |
d131f6457c | ||
![]() |
a3a9b0385e | ||
![]() |
20297b51bd | ||
![]() |
ba9f0b2ce6 | ||
![]() |
56f606a98e | ||
![]() |
b553f1087e | ||
![]() |
75ceed5776 | ||
![]() |
689c394c57 | ||
![]() |
de60096af1 | ||
![]() |
9aa460b55b | ||
![]() |
7c115d350c | ||
![]() |
1ce26ef4a2 | ||
![]() |
92c75854fb | ||
![]() |
f015b10b02 | ||
![]() |
972d6d8bd4 | ||
![]() |
fee0239211 | ||
![]() |
e7181a8c36 | ||
![]() |
b88eb6a096 | ||
![]() |
f6e26916ac | ||
![]() |
39876b2ee3 | ||
![]() |
4f1cfb20a9 | ||
![]() |
6304383c91 | ||
![]() |
bd1980ea1c | ||
![]() |
be4c3f59d4 | ||
![]() |
9d55db6501 |
@@ -23,3 +23,6 @@ libtool
|
||||
ltmain.sh
|
||||
missing
|
||||
ssh2_sample
|
||||
libssh2-*.tar.gz
|
||||
INSTALL
|
||||
install-sh
|
||||
|
9
.cvsusers
Normal file
9
.cvsusers
Normal 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
9
AUTHORS
Normal 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
|
@@ -1,4 +1,5 @@
|
||||
/* Copyright (c) 2004-2006, 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.
|
||||
*
|
||||
* Redistribution and use in source and binary forms,
|
60
INSTALL
60
INSTALL
@@ -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
|
||||
|
23
Makefile.am
23
Makefile.am
@@ -1,19 +1,14 @@
|
||||
AUTOMAKE_OPTIONS = foreign nostdinc
|
||||
SUBDIRS = src example tests docs
|
||||
|
||||
SUBDIRS = src tests
|
||||
|
||||
include_HEADERS = include/libssh2.h include/libssh2_publickey.h \
|
||||
include_HEADERS = \
|
||||
include/libssh2.h \
|
||||
include/libssh2_publickey.h \
|
||||
include/libssh2_sftp.h
|
||||
|
||||
# and a sample tool
|
||||
noinst_PROGRAMS = ssh2_sample
|
||||
|
||||
INCLUDES = -I$(top_srcdir)/include
|
||||
|
||||
ssh2_sample_SOURCES = ssh2_sample.c
|
||||
|
||||
ssh2_sample_LDADD = src/libssh2.la
|
||||
|
||||
EXTRA_DIST = LICENSE win32
|
||||
EXTRA_DIST = win32 buildconf
|
||||
|
||||
ACLOCAL_AMFLAGS = -I m4
|
||||
|
||||
.PHONY: ChangeLog
|
||||
ChangeLog:
|
||||
cvs2cl --utc --fsf --FSF --usermap .cvsusers -I ChangeLog -I .cvs
|
||||
|
280
NEWS
Normal file
280
NEWS
Normal 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
|
296
README
296
README
@@ -1,253 +1,99 @@
|
||||
libssh2 - SSH2 library
|
||||
======================
|
||||
|
||||
libssh2 is a library implementing the SSH2 protocol
|
||||
libssh2 is a library implementing the SSH2 protocol, available under
|
||||
the revised BSD license.
|
||||
|
||||
Version
|
||||
------------
|
||||
Generic installation instructions are in INSTALL. Some ./configure
|
||||
options deserve additional comments:
|
||||
|
||||
maximum SSH packet size is now some 35000 bytes
|
||||
* --enable-crypt-none
|
||||
|
||||
private include files are now in src/ and only public headers are in include/
|
||||
The SSH2 Transport allows for unencrypted data
|
||||
transmission using the "none" cipher. Because this is
|
||||
such a huge security hole, it is typically disabled on
|
||||
SSH2 implementations and is disabled in libssh2 by
|
||||
default as well.
|
||||
|
||||
automake and libtool are being used (increased portability)
|
||||
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.
|
||||
|
||||
fixed OpenSSL detection using pkg-config
|
||||
* --enable-mac-none
|
||||
|
||||
simple self test added to tests/
|
||||
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.
|
||||
|
||||
libgcrypt is fully supported
|
||||
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.
|
||||
|
||||
Version 0.14
|
||||
------------
|
||||
* --disable-gex-new
|
||||
|
||||
Plug leaks in EVP cipher init/shutdown. (Selcuk Gueney)
|
||||
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.
|
||||
|
||||
Allow socket_fd == 0 in libssh2_session_startup(). (puudeli)
|
||||
If you experience trouble connecting to an old SSH
|
||||
server using dh-gex, try this option to fallback on
|
||||
the older more reliable method.
|
||||
|
||||
Swap ordering of packet_add/packet-inspection to avoid inspect after free. (Selcuk)
|
||||
* --with-libgcrypt
|
||||
* --with-libgcrypt-prefix=DIR
|
||||
|
||||
Swap KEX_INIT ordering, send our KEX_INIT first.
|
||||
libssh2 can use the Libgcrypt library
|
||||
(http://www.gnupg.org/) for cryptographic operations.
|
||||
|
||||
Add check for oportunistic KEX_INIT packets. Burn bad guess if necessary.
|
||||
Configure will attempt to locate Libgcrypt in the
|
||||
default location, but if you have installed it
|
||||
somewhere else, use the --with-libgrypt-prefix=DIR
|
||||
parameter.
|
||||
|
||||
Fix OpenSSL detection using pkg-config. (Dan Casey)
|
||||
* --with-openssl=[DIR]
|
||||
|
||||
Version 0.13
|
||||
------------
|
||||
libssh2 can use the OpenSSL library
|
||||
(http://www.openssl.org) for cryptographic operations.
|
||||
|
||||
Fixed channel not being marked closed when CHANNEL_CLOSE package cannot be sent. (David Robins)
|
||||
Configure will attempt to locate OpenSSL in a number
|
||||
of default locations:
|
||||
|
||||
Fixed payload packet allocation bug when invalid packet length received. (David Robins)
|
||||
/usr/local/ssl
|
||||
/usr/local
|
||||
/usr
|
||||
/usr/local/openssl
|
||||
|
||||
Fixed `make install' target for MacOSX.
|
||||
If your installation of OpenSSL is in another
|
||||
location, specify it here.
|
||||
|
||||
Add terminating NULL character to readlink()/realpath() results.
|
||||
* --with-libz=[DIR]
|
||||
|
||||
BugFix#1436593: Apply build options for HPUX targets.
|
||||
If present, libssh2 will attempt to use the zlib (http://www.zlib.org)
|
||||
for payload compression, however zlib is not required.
|
||||
|
||||
Version 0.12
|
||||
------------
|
||||
Configure will attempt to location a zlib installation
|
||||
in a number of default locations:
|
||||
|
||||
Added support for publickey subsytem (not the same as publickey auth).
|
||||
/usr/local
|
||||
/usr
|
||||
/usr/local/libz
|
||||
/usr/libz
|
||||
/usr/local/zlib
|
||||
/usr/zlib
|
||||
|
||||
Fix x11_req. Multiple packet_len issues and error handling logic.
|
||||
(Thanks Simon Hart)
|
||||
If your installation of zlib is in another location,
|
||||
you may specify it here.
|
||||
|
||||
Fix generation of 'e' portion of Diffie-Hellman keyset.
|
||||
Use appropriate order for BN_rand() rather than fixed group1-specific value.
|
||||
* --enable-debug
|
||||
|
||||
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
|
||||
Will make the build use more pedantic and strict compiler
|
||||
options as well as enable the libssh2_trace() function (for
|
||||
showing debug traces).
|
||||
|
141
acinclude.m4
141
acinclude.m4
@@ -147,3 +147,144 @@ AC_DEFUN([CURL_CC_DEBUG_OPTS],
|
||||
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
|
||||
])
|
||||
|
660
config.rpath
Executable file
660
config.rpath
Executable 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
|
88
configure.in
88
configure.in
@@ -22,15 +22,12 @@ case "$host" in
|
||||
;;
|
||||
esac
|
||||
|
||||
AC_CHECK_LIB(socket, socket, [
|
||||
SHLIB_LDFLAGS="$SHLIB_LDFLAGS -lsocket"
|
||||
LIBS="$LIBS -lsocket"
|
||||
])
|
||||
AC_CHECK_LIB(m, ceil, [ SHLIB_LDFLAGS="$SHLIB_LDFLAGS -lm" ])
|
||||
# Some systems (Solaris?) have socket() in -lsocket.
|
||||
AC_SEARCH_LIBS(socket, socket)
|
||||
|
||||
# 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_PROG_CC
|
||||
@@ -48,15 +45,21 @@ 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
|
||||
AM_PATH_LIBGCRYPT(1:1.2.2,,use_libgcrypt=no)
|
||||
AC_LIB_HAVE_LINKFLAGS([gcrypt], [], [#include <gcrypt.h>])
|
||||
fi
|
||||
if test "$use_libgcrypt" != "no"; then
|
||||
CFLAGS="$CFLAGS $LIBGCRYPT_CFLAGS"
|
||||
LDFLAGS="$LDFLAGS $LIBGCRYPT_LIBS"
|
||||
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
|
||||
#
|
||||
@@ -109,7 +112,7 @@ if test "$found_openssl" = "no"; then
|
||||
OPENSSL_INCLINE="-I$i/include"
|
||||
OPENSSL_INCDIR=$i/include
|
||||
fi
|
||||
if test -r $i/lib/libcrypto.a -o -r $i/lib/libcrypto.$SHLIB_SUFFIX_NAME; then
|
||||
if test -r $i/lib/libcrypto.a -o -r $i/lib/libcrypto$SHLIB_SUFFIX_NAME; then
|
||||
OPENSSL_LIBLINE="-L$i/lib -lcrypto"
|
||||
fi
|
||||
test -n "$OPENSSL_INCLINE" && test -n "$OPENSSL_LIBLINE" && break
|
||||
@@ -162,7 +165,7 @@ for i in $LIBSSH2_LIBZ_DIR; do
|
||||
if test -r $i/include/zlib.h; then
|
||||
LIBZ_INCDIR=$i/include
|
||||
fi
|
||||
if test -r $i/lib/libz.a -o -r $i/lib/libz.$SHLIB_SUFFIX_NAME; then
|
||||
if test -r $i/lib/libz.a -o -r $i/lib/libz$SHLIB_SUFFIX_NAME; then
|
||||
LIBZ_LIBDIR=$i/lib
|
||||
fi
|
||||
test -n "$LIBZ_INCDIR" && test -n "$LIBZ_LIBDIR" && break
|
||||
@@ -195,55 +198,13 @@ if test "$GEX_NEW" != "no"; then
|
||||
AC_DEFINE(LIBSSH2_DH_GEX_NEW, 1, [Enable newer diffie-hellman-group-exchange-sha1 syntax])
|
||||
fi
|
||||
|
||||
#
|
||||
# Optional debugging -- Meant for developer maintenance only
|
||||
# When enabled, the relevant debugging information will be written on stderr
|
||||
#
|
||||
AC_ARG_ENABLE(debug-transport,
|
||||
AC_HELP_STRING([--enable-debug-transport],[Output transport layer debugging info to stderr]),
|
||||
[AC_DEFINE(LIBSSH2_DEBUG_TRANSPORT, 1, [Output transport layer debugging info to stderr])])
|
||||
AC_ARG_ENABLE(debug-kex,
|
||||
AC_HELP_STRING([--enable-debug-kex],[Output Key Exchange debugging info to stderr]),
|
||||
[AC_DEFINE(LIBSSH2_DEBUG_KEX, 1, [Output Key Exchange debugging info to stderr])])
|
||||
AC_ARG_ENABLE(debug-userauth,
|
||||
AC_HELP_STRING([--enable-debug-userauth],[Output userauth debugging info to stderr]),
|
||||
[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])
|
||||
])
|
||||
|
||||
|
||||
dnl ************************************************************
|
||||
dnl option to switch on compiler debug options
|
||||
dnl
|
||||
AC_MSG_CHECKING([whether to enable pedantic and debug compiler options])
|
||||
AC_ARG_ENABLE(debug-build,
|
||||
AC_HELP_STRING([--enable-debug-build],[Enable pedantic debug options])
|
||||
AC_HELP_STRING([--disable-debug-build],[Disable debug options]),
|
||||
AC_ARG_ENABLE(debug,
|
||||
AC_HELP_STRING([--enable-debug],[Enable pedantic and debug options])
|
||||
AC_HELP_STRING([--disable-debug],[Disable debug options]),
|
||||
[ case "$enableval" in
|
||||
no)
|
||||
AC_MSG_RESULT(no)
|
||||
@@ -264,14 +225,21 @@ AC_HELP_STRING([--disable-debug-build],[Disable debug options]),
|
||||
|
||||
# Checks for header files.
|
||||
# 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)
|
||||
|
||||
# Checks for typedefs, structures, and compiler characteristics.
|
||||
AC_C_CONST
|
||||
AC_C_INLINE
|
||||
|
||||
CURL_CHECK_NONBLOCKING_SOCKET
|
||||
|
||||
AC_CONFIG_FILES([Makefile
|
||||
src/Makefile
|
||||
tests/Makefile])
|
||||
tests/Makefile
|
||||
example/Makefile
|
||||
example/simple/Makefile
|
||||
docs/Makefile])
|
||||
AC_OUTPUT
|
||||
|
2
docs/.cvsignore
Normal file
2
docs/.cvsignore
Normal file
@@ -0,0 +1,2 @@
|
||||
Makefile
|
||||
Makefile.in
|
13
docs/Makefile.am
Normal file
13
docs/Makefile.am
Normal 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
|
@@ -1,4 +1,4 @@
|
||||
.\" $Id: libssh2_channel_forward_listen_ex.3,v 1.1 2006/12/21 14:09:13 bagder Exp $
|
||||
.\" $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
|
||||
@@ -30,7 +30,7 @@ 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 nuber of pending connections to queue before
|
||||
\fIqueue_maxsize\fP - Maximum number of pending connections to queue before
|
||||
rejecting further attempts.
|
||||
|
||||
\fIlibssh2_channel_forward_listen(3)\fP is a macro.
|
||||
|
@@ -1,4 +1,4 @@
|
||||
.\" $Id: libssh2_channel_read_ex.3,v 1.4 2007/02/02 16:11:55 bagder Exp $
|
||||
.\" $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
|
||||
@@ -33,4 +33,4 @@ macros.
|
||||
.SH RETURN VALUE
|
||||
Actual number of bytes read or negative on failure.
|
||||
.SH "SEE ALSO"
|
||||
|
||||
.BR libssh2_poll_channel_read(3)
|
||||
|
@@ -1,4 +1,4 @@
|
||||
.\" $Id: libssh2_channel_readnb_ex.3,v 1.1 2007/02/02 16:09:12 bagder Exp $
|
||||
.\" $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
|
||||
@@ -35,3 +35,5 @@ 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)
|
||||
|
||||
|
37
docs/libssh2_channel_write_ex.3
Normal file
37
docs/libssh2_channel_write_ex.3
Normal 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
19
docs/libssh2_poll.3
Normal 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)
|
18
docs/libssh2_poll_channel_read.3
Normal file
18
docs/libssh2_poll_channel_read.3
Normal 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)
|
@@ -1,4 +1,4 @@
|
||||
.\" $Id: libssh2_session_init.3,v 1.1 2006/12/21 14:09:13 bagder Exp $
|
||||
.\" $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
|
||||
@@ -15,7 +15,7 @@ LIBSSH2_SESSION *libssh2_session_init_ex(
|
||||
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 dynamicly allocated memory
|
||||
(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.
|
||||
|
@@ -1,10 +1,11 @@
|
||||
.\" $Id: libssh2_sftp_init.3,v 1.1 2007/02/02 16:09:12 bagder Exp $
|
||||
.\" $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
|
||||
|
26
docs/libssh2_sftp_mkdir_ex.3
Normal file
26
docs/libssh2_sftp_mkdir_ex.3
Normal 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)
|
29
docs/libssh2_sftp_mkdirnb_ex.3
Normal file
29
docs/libssh2_sftp_mkdirnb_ex.3
Normal 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)
|
@@ -1,10 +1,11 @@
|
||||
.\" $Id: libssh2_sftp_open_ex.3,v 1.1 2007/02/02 16:09:12 bagder Exp $
|
||||
.\" $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,
|
||||
@@ -16,29 +17,20 @@ LIBSSH2_SFTP_HANDLE *libssh2_sftp_open(LIBSSH2_SFTP *sftp,
|
||||
LIBSSH2_SFTP_HANDLE *libssh2_sftp_opendir(LIBSSH2_SFTP *sftp,
|
||||
char *path);
|
||||
.SH DESCRIPTION
|
||||
* sftp
|
||||
\fIsftp\fP - SFTP instance as returned by libssh2_sftp_init().
|
||||
|
||||
SFTP instance as returned by libssh2_sftp_init().
|
||||
\fIfilename\fP - Remote file/directory resource to open
|
||||
|
||||
* filename
|
||||
\fIfilename_len\fP - Length of filename
|
||||
|
||||
Remote file/directory resource to open
|
||||
\fIflags\fP - Any (reasonable) combination of the LIBSSH2_FXF_* constants
|
||||
corresponding fopen modes.
|
||||
|
||||
* filename_len
|
||||
\fImode\fP - POSIX file permissions to assign if the file is being newly
|
||||
created.
|
||||
|
||||
Length of filename
|
||||
|
||||
* flags
|
||||
|
||||
Any (reasonable) combination of the LIBSSH2_FXF_* constants corresponding fopen modes.
|
||||
|
||||
* mode
|
||||
|
||||
POSIX file permissions to assign if the file is being newly created.
|
||||
|
||||
* open_type
|
||||
|
||||
Either of LIBSSH2_SFTP_OPENFILE (to open a file) or LIBSSH2_SFTP_OPENDIR (to open a directory).
|
||||
\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.
|
||||
|
27
docs/libssh2_sftp_read.3
Normal file
27
docs/libssh2_sftp_read.3
Normal 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)
|
35
docs/libssh2_sftp_readdir.3
Normal file
35
docs/libssh2_sftp_readdir.3
Normal 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)
|
40
docs/libssh2_sftp_readdirnb.3
Normal file
40
docs/libssh2_sftp_readdirnb.3
Normal 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)
|
29
docs/libssh2_sftp_readnb.3
Normal file
29
docs/libssh2_sftp_readnb.3
Normal 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)
|
@@ -1,4 +1,4 @@
|
||||
.\" $Id: template.3,v 1.1 2007/02/02 16:09:12 bagder Exp $
|
||||
.\" $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
|
||||
@@ -10,6 +10,6 @@ void libssh2_template(void);
|
||||
.SH DESCRIPTION
|
||||
Long text describing the function and its input arguments.
|
||||
.SH RETURN VALUE
|
||||
Describe what the funtion returns.
|
||||
Describe what the function returns.
|
||||
.SH "SEE ALSO"
|
||||
Add related functions
|
||||
|
2
example/.cvsignore
Normal file
2
example/.cvsignore
Normal file
@@ -0,0 +1,2 @@
|
||||
Makefile
|
||||
Makefile.in
|
2
example/Makefile.am
Normal file
2
example/Makefile.am
Normal file
@@ -0,0 +1,2 @@
|
||||
AUTOMAKE_OPTIONS = foreign nostdinc
|
||||
SUBDIRS = simple
|
17
example/simple/.cvsignore
Normal file
17
example/simple/.cvsignore
Normal 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
|
||||
|
38
example/simple/Makefile.am
Normal file
38
example/simple/Makefile.am
Normal 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
|
||||
|
@@ -1,18 +1,27 @@
|
||||
/*
|
||||
* $Id: scp.c,v 1.3 2007/02/01 22:39:45 bagder Exp $
|
||||
* $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>
|
||||
|
||||
#ifndef WIN32
|
||||
# include <netinet/in.h>
|
||||
# include <sys/socket.h>
|
||||
# include <unistd.h>
|
||||
#else
|
||||
#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>
|
||||
@@ -61,6 +70,9 @@ int main(int argc, char *argv[])
|
||||
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
|
||||
*/
|
||||
|
202
example/simple/scp_nonblock.c
Normal file
202
example/simple/scp_nonblock.c
Normal 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;
|
||||
}
|
@@ -1,19 +1,36 @@
|
||||
/*
|
||||
* $Id: sftp.c,v 1.1 2007/01/24 14:15:36 bagder Exp $
|
||||
* $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>
|
||||
|
||||
#ifndef WIN32
|
||||
# include <netinet/in.h>
|
||||
# include <sys/socket.h>
|
||||
# include <unistd.h>
|
||||
#else
|
||||
#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>
|
||||
@@ -23,6 +40,7 @@
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
unsigned long hostaddr;
|
||||
int sock, i, auth_pw = 1;
|
||||
struct sockaddr_in sin;
|
||||
const char *fingerprint;
|
||||
@@ -40,15 +58,30 @@ int main(int argc, char *argv[])
|
||||
WSAStartup(WINSOCK_VERSION, &wsadata);
|
||||
#endif
|
||||
|
||||
/* Ultra basic "connect to port 22 on localhost"
|
||||
* Your code is responsible for creating the socket establishing the
|
||||
* connection
|
||||
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 = htonl(0x7F000001);
|
||||
sin.sin_addr.s_addr = hostaddr;
|
||||
if (connect(sock, (struct sockaddr*)(&sin),
|
||||
sizeof(struct sockaddr_in)) != 0) {
|
||||
fprintf(stderr, "failed to connect!\n");
|
||||
@@ -82,16 +115,6 @@ int main(int argc, char *argv[])
|
||||
}
|
||||
printf("\n");
|
||||
|
||||
if(argc > 1) {
|
||||
username = argv[1];
|
||||
}
|
||||
if(argc > 2) {
|
||||
password = argv[2];
|
||||
}
|
||||
if(argc > 3) {
|
||||
sftppath = argv[3];
|
||||
}
|
||||
|
||||
if (auth_pw) {
|
||||
/* We could authenticate via password */
|
||||
if (libssh2_userauth_password(session, username, password)) {
|
||||
@@ -109,6 +132,7 @@ int main(int argc, char *argv[])
|
||||
}
|
||||
}
|
||||
|
||||
fprintf(stderr, "libssh2_sftp_init()!\n");
|
||||
sftp_session = libssh2_sftp_init(session);
|
||||
|
||||
if (!sftp_session) {
|
||||
@@ -116,6 +140,10 @@ int main(int argc, char *argv[])
|
||||
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);
|
||||
@@ -126,17 +154,16 @@ int main(int argc, char *argv[])
|
||||
}
|
||||
fprintf(stderr, "libssh2_sftp_open() is done, now receive data!\n");
|
||||
do {
|
||||
char mem[512];
|
||||
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;
|
||||
}
|
||||
else
|
||||
break;
|
||||
break;
|
||||
|
||||
} while (1);
|
||||
|
||||
libssh2_sftp_close(sftp_handle);
|
||||
|
293
example/simple/sftp_RW_nonblock.c
Normal file
293
example/simple/sftp_RW_nonblock.c
Normal 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
166
example/simple/sftp_mkdir.c
Normal 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;
|
||||
}
|
179
example/simple/sftp_mkdir_nonblock.c
Normal file
179
example/simple/sftp_mkdir_nonblock.c
Normal 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;
|
||||
}
|
198
example/simple/sftp_nonblock.c
Normal file
198
example/simple/sftp_nonblock.c
Normal 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
205
example/simple/sftp_write.c
Normal 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;
|
||||
}
|
217
example/simple/sftp_write_nonblock.c
Normal file
217
example/simple/sftp_write_nonblock.c
Normal 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
213
example/simple/sftpdir.c
Normal 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;
|
||||
}
|
227
example/simple/sftpdir_nonblock.c
Normal file
227
example/simple/sftpdir_nonblock.c
Normal 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;
|
||||
}
|
@@ -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 <netinet/in.h>
|
||||
# include <sys/socket.h>
|
||||
# include <unistd.h>
|
||||
#else
|
||||
#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
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <fcntl.h>
|
||||
@@ -16,6 +34,7 @@
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
unsigned long hostaddr;
|
||||
int sock, i, auth_pw = 1;
|
||||
struct sockaddr_in sin;
|
||||
const char *fingerprint;
|
||||
@@ -29,6 +48,19 @@ int main(int argc, char *argv[])
|
||||
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];
|
||||
}
|
||||
|
||||
/* Ultra basic "connect to port 22 on localhost"
|
||||
* Your code is responsible for creating the socket establishing the connection
|
||||
*/
|
||||
@@ -38,8 +70,9 @@ int main(int argc, char *argv[])
|
||||
#endif
|
||||
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) {
|
||||
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;
|
||||
}
|
||||
@@ -64,13 +97,6 @@ int main(int argc, char *argv[])
|
||||
}
|
||||
printf("\n");
|
||||
|
||||
if(argc > 1) {
|
||||
username = argv[1];
|
||||
}
|
||||
if(argc > 2) {
|
||||
password = argv[2];
|
||||
}
|
||||
|
||||
if (auth_pw) {
|
||||
/* We could authenticate via password */
|
||||
if (libssh2_userauth_password(session, username, password)) {
|
||||
|
20
get_ver.awk
Executable file
20
get_ver.awk
Executable 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 "";
|
||||
}
|
@@ -1,4 +1,4 @@
|
||||
/* Copyright (c) 2004-2006, Sara Golemon <sarag@libssh2.org>
|
||||
/* Copyright (c) 2004-2007, Sara Golemon <sarag@libssh2.org>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms,
|
||||
@@ -59,19 +59,23 @@ extern "C" {
|
||||
# endif /* LIBSSH2_WIN32 */
|
||||
#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>
|
||||
#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 __int64 libssh2_int64_t;
|
||||
#if (_MSC_VER <= 1200)
|
||||
typedef long ssize_t;
|
||||
typedef unsigned int uint32_t;
|
||||
#endif
|
||||
#else
|
||||
typedef unsigned long long libssh2_uint64_t;
|
||||
typedef long long libssh2_int64_t;
|
||||
#endif
|
||||
|
||||
#define LIBSSH2_VERSION "0.14"
|
||||
#define LIBSSH2_VERSION "0.15-CVS"
|
||||
#define LIBSSH2_APINO 200507211326
|
||||
|
||||
/* 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_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_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)
|
||||
|
||||
@@ -323,23 +327,23 @@ LIBSSH2_API int libssh2_poll(LIBSSH2_POLLFD *fds, unsigned int nfds, long timeou
|
||||
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)
|
||||
|
||||
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)
|
||||
|
||||
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)
|
||||
|
||||
LIBSSH2_API int libssh2_channel_forward_cancel(LIBSSH2_LISTENER *listener);
|
||||
|
||||
LIBSSH2_API LIBSSH2_CHANNEL *libssh2_channel_forward_accept(LIBSSH2_LISTENER *listener);
|
||||
|
||||
LIBSSH2_API int libssh2_channel_setenv_ex(LIBSSH2_CHANNEL *channel, char *varname, unsigned int varname_len, char *value, unsigned 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))
|
||||
|
||||
LIBSSH2_API int libssh2_channel_request_pty_ex(LIBSSH2_CHANNEL *channel, char *term, unsigned int term_len, char *modes, unsigned int modes_len, int width, int height, int width_px, int height_px);
|
||||
LIBSSH2_API int libssh2_channel_request_pty_ex(LIBSSH2_CHANNEL *channel, const char *term, unsigned int term_len, const char *modes, unsigned int modes_len, int width, int height, int width_px, int height_px);
|
||||
#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))
|
||||
|
||||
LIBSSH2_API int libssh2_channel_process_startup(LIBSSH2_CHANNEL *channel, const char *request, unsigned int request_len, const char *message, unsigned int message_len);
|
||||
@@ -347,9 +351,22 @@ LIBSSH2_API int libssh2_channel_process_startup(LIBSSH2_CHANNEL *channel, const
|
||||
#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))
|
||||
|
||||
LIBSSH2_API int 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))
|
||||
LIBSSH2_API int libssh2_channel_read_ex(LIBSSH2_CHANNEL *channel,
|
||||
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_readnb(channel, buf, buflen) \
|
||||
libssh2_channel_readnb_ex((channel), 0, (buf), (buflen))
|
||||
|
||||
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 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))
|
||||
LIBSSH2_API int libssh2_channel_write_ex(LIBSSH2_CHANNEL *channel,
|
||||
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))
|
||||
|
||||
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)
|
||||
|
||||
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_channel_ignore_extended_data() is defined below for BC with version 0.1
|
||||
* 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);
|
||||
#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, unsigned int *dest_len, char *src, unsigned 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
|
||||
} /* extern "C" */
|
||||
|
@@ -49,9 +49,9 @@
|
||||
typedef struct _LIBSSH2_PUBLICKEY LIBSSH2_PUBLICKEY;
|
||||
|
||||
typedef struct _libssh2_publickey_attribute {
|
||||
char *name;
|
||||
const char *name;
|
||||
unsigned long name_len;
|
||||
char *value;
|
||||
const char *value;
|
||||
unsigned long value_len;
|
||||
char mandatory;
|
||||
} libssh2_publickey_attribute;
|
||||
@@ -59,9 +59,9 @@ typedef struct _libssh2_publickey_attribute {
|
||||
typedef struct _libssh2_publickey_list {
|
||||
unsigned char *packet; /* For freeing */
|
||||
|
||||
unsigned char *name;
|
||||
const unsigned char *name;
|
||||
unsigned long name_len;
|
||||
unsigned char *blob;
|
||||
const unsigned char *blob;
|
||||
unsigned long blob_len;
|
||||
unsigned long num_attrs;
|
||||
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,
|
||||
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) \
|
||||
libssh2_publickey_add_ex((pkey), (name), strlen(name), (blob), (blob_len), (overwrite), (num_attrs), (attrs))
|
||||
|
||||
|
@@ -1,4 +1,4 @@
|
||||
/* Copyright (c) 2004-2006, Sara Golemon <sarag@libssh2.org>
|
||||
/* Copyright (c) 2004-2007, Sara Golemon <sarag@libssh2.org>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms,
|
||||
@@ -38,6 +38,10 @@
|
||||
#ifndef LIBSSH2_SFTP_H
|
||||
#define LIBSSH2_SFTP_H 1
|
||||
|
||||
#ifndef WIN32
|
||||
#include <unistd.h>
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
@@ -175,13 +179,27 @@ LIBSSH2_API int libssh2_sftp_shutdown(LIBSSH2_SFTP *sftp);
|
||||
LIBSSH2_API unsigned long libssh2_sftp_last_error(LIBSSH2_SFTP *sftp);
|
||||
|
||||
/* File / Directory Ops */
|
||||
LIBSSH2_API LIBSSH2_SFTP_HANDLE *libssh2_sftp_open_ex(LIBSSH2_SFTP *sftp, char *filename, unsigned 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_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);
|
||||
LIBSSH2_API int libssh2_sftp_readdir(LIBSSH2_SFTP_HANDLE *handle, char *buffer, size_t buffer_maxlen, LIBSSH2_SFTP_ATTRIBUTES *attrs);
|
||||
LIBSSH2_API size_t libssh2_sftp_write(LIBSSH2_SFTP_HANDLE *handle, const char *buffer, size_t count);
|
||||
/* This is a public error code from libssh2_sftp_read() that is returned
|
||||
when it would otherwise block. */
|
||||
#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);
|
||||
#define libssh2_sftp_close(handle) libssh2_sftp_close_handle(handle)
|
||||
@@ -199,22 +217,24 @@ LIBSSH2_API int libssh2_sftp_fstat_ex(LIBSSH2_SFTP_HANDLE *handle, LIBSSH2_SFTP_
|
||||
|
||||
|
||||
/* Miscellaneous Ops */
|
||||
LIBSSH2_API int libssh2_sftp_rename_ex(LIBSSH2_SFTP *sftp, char *source_filename, unsigned int srouce_filename_len,
|
||||
char *dest_filename, unsigned int dest_filename_len,
|
||||
LIBSSH2_API int libssh2_sftp_rename_ex(LIBSSH2_SFTP *sftp, const char *source_filename, unsigned int srouce_filename_len,
|
||||
const char *dest_filename, unsigned int dest_filename_len,
|
||||
long flags);
|
||||
#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_API int libssh2_sftp_unlink_ex(LIBSSH2_SFTP *sftp, char *filename, unsigned 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))
|
||||
|
||||
LIBSSH2_API int libssh2_sftp_mkdir_ex(LIBSSH2_SFTP *sftp, char *path, unsigned 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))
|
||||
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, unsigned 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))
|
||||
|
||||
LIBSSH2_API int libssh2_sftp_stat_ex(LIBSSH2_SFTP *sftp, char *path, unsigned 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_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))
|
||||
@@ -224,6 +244,9 @@ LIBSSH2_API int libssh2_sftp_symlink_ex(LIBSSH2_SFTP *sftp, const char *path, un
|
||||
#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)
|
||||
|
||||
LIBSSH2_API void libssh2_sftp_set_blocking(LIBSSH2_SFTP *session, int blocking);
|
||||
LIBSSH2_API int libssh2_sftp_get_blocking(LIBSSH2_SFTP *session);
|
||||
|
||||
#ifdef __cplusplus
|
||||
} /* extern "C" */
|
||||
#endif
|
||||
|
251
install-sh
251
install-sh
@@ -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
|
110
m4/lib-ld.m4
Normal file
110
m4/lib-ld.m4
Normal 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
709
m4/lib-link.m4
Normal 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
185
m4/lib-prefix.m4
Normal 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
|
||||
])
|
108
m4/libgcrypt.m4
108
m4/libgcrypt.m4
@@ -1,108 +0,0 @@
|
||||
dnl Autoconf macros for libgcrypt
|
||||
dnl Copyright (C) 2002, 2004 Free Software Foundation, Inc.
|
||||
dnl
|
||||
dnl This file is free software; as a special exception the author gives
|
||||
dnl unlimited permission to copy and/or distribute it, with or without
|
||||
dnl modifications, as long as this notice is preserved.
|
||||
dnl
|
||||
dnl This file is distributed in the hope that it will be useful, but
|
||||
dnl WITHOUT ANY WARRANTY, to the extent permitted by law; without even the
|
||||
dnl implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
|
||||
|
||||
dnl AM_PATH_LIBGCRYPT([MINIMUM-VERSION,
|
||||
dnl [ACTION-IF-FOUND [, ACTION-IF-NOT-FOUND ]]])
|
||||
dnl Test for libgcrypt and define LIBGCRYPT_CFLAGS and LIBGCRYPT_LIBS.
|
||||
dnl MINIMUN-VERSION is a string with the version number optionalliy prefixed
|
||||
dnl with the API version to also check the API compatibility. Example:
|
||||
dnl a MINIMUN-VERSION of 1:1.2.5 won't pass the test unless the installed
|
||||
dnl version of libgcrypt is at least 1.2.5 *and* the API number is 1. Using
|
||||
dnl this features allows to prevent build against newer versions of libgcrypt
|
||||
dnl with a changed API.
|
||||
dnl
|
||||
AC_DEFUN([AM_PATH_LIBGCRYPT],
|
||||
[ AC_ARG_WITH(libgcrypt-prefix,
|
||||
AC_HELP_STRING([--with-libgcrypt-prefix=PFX],
|
||||
[prefix where LIBGCRYPT is installed (optional)]),
|
||||
libgcrypt_config_prefix="$withval", libgcrypt_config_prefix="")
|
||||
if test x$libgcrypt_config_prefix != x ; then
|
||||
if test x${LIBGCRYPT_CONFIG+set} != xset ; then
|
||||
LIBGCRYPT_CONFIG=$libgcrypt_config_prefix/bin/libgcrypt-config
|
||||
fi
|
||||
fi
|
||||
|
||||
AC_PATH_PROG(LIBGCRYPT_CONFIG, libgcrypt-config, no)
|
||||
tmp=ifelse([$1], ,1:1.2.0,$1)
|
||||
if echo "$tmp" | grep ':' >/dev/null 2>/dev/null ; then
|
||||
req_libgcrypt_api=`echo "$tmp" | sed 's/\(.*\):\(.*\)/\1/'`
|
||||
min_libgcrypt_version=`echo "$tmp" | sed 's/\(.*\):\(.*\)/\2/'`
|
||||
else
|
||||
req_libgcrypt_api=0
|
||||
min_libgcrypt_version="$tmp"
|
||||
fi
|
||||
|
||||
AC_MSG_CHECKING(for LIBGCRYPT - version >= $min_libgcrypt_version)
|
||||
ok=no
|
||||
if test "$LIBGCRYPT_CONFIG" != "no" ; then
|
||||
req_major=`echo $min_libgcrypt_version | \
|
||||
sed 's/\([[0-9]]*\)\.\([[0-9]]*\)\.\([[0-9]]*\)/\1/'`
|
||||
req_minor=`echo $min_libgcrypt_version | \
|
||||
sed 's/\([[0-9]]*\)\.\([[0-9]]*\)\.\([[0-9]]*\)/\2/'`
|
||||
req_micro=`echo $min_libgcrypt_version | \
|
||||
sed 's/\([[0-9]]*\)\.\([[0-9]]*\)\.\([[0-9]]*\)/\3/'`
|
||||
libgcrypt_config_version=`$LIBGCRYPT_CONFIG --version`
|
||||
major=`echo $libgcrypt_config_version | \
|
||||
sed 's/\([[0-9]]*\)\.\([[0-9]]*\)\.\([[0-9]]*\).*/\1/'`
|
||||
minor=`echo $libgcrypt_config_version | \
|
||||
sed 's/\([[0-9]]*\)\.\([[0-9]]*\)\.\([[0-9]]*\).*/\2/'`
|
||||
micro=`echo $libgcrypt_config_version | \
|
||||
sed 's/\([[0-9]]*\)\.\([[0-9]]*\)\.\([[0-9]]*\).*/\3/'`
|
||||
if test "$major" -gt "$req_major"; then
|
||||
ok=yes
|
||||
else
|
||||
if test "$major" -eq "$req_major"; then
|
||||
if test "$minor" -gt "$req_minor"; then
|
||||
ok=yes
|
||||
else
|
||||
if test "$minor" -eq "$req_minor"; then
|
||||
if test "$micro" -ge "$req_micro"; then
|
||||
ok=yes
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
if test $ok = yes; then
|
||||
AC_MSG_RESULT(yes)
|
||||
else
|
||||
AC_MSG_RESULT(no)
|
||||
fi
|
||||
if test $ok = yes; then
|
||||
# If we have a recent libgcrypt, we should also check that the
|
||||
# API is compatible
|
||||
if test "$req_libgcrypt_api" -gt 0 ; then
|
||||
tmp=`$LIBGCRYPT_CONFIG --api-version 2>/dev/null || echo 0`
|
||||
if test "$tmp" -gt 0 ; then
|
||||
AC_MSG_CHECKING([LIBGCRYPT API version])
|
||||
if test "$req_libgcrypt_api" -eq "$tmp" ; then
|
||||
AC_MSG_RESULT(okay)
|
||||
else
|
||||
ok=no
|
||||
AC_MSG_RESULT([does not match. want=$req_libgcrypt_api got=$tmp])
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
if test $ok = yes; then
|
||||
LIBGCRYPT_CFLAGS=`$LIBGCRYPT_CONFIG --cflags`
|
||||
LIBGCRYPT_LIBS=`$LIBGCRYPT_CONFIG --libs`
|
||||
ifelse([$2], , :, [$2])
|
||||
else
|
||||
LIBGCRYPT_CFLAGS=""
|
||||
LIBGCRYPT_LIBS=""
|
||||
ifelse([$3], , :, [$3])
|
||||
fi
|
||||
AC_SUBST(LIBGCRYPT_CFLAGS)
|
||||
AC_SUBST(LIBGCRYPT_LIBS)
|
||||
])
|
@@ -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
2
nw/Makefile
Normal file
@@ -0,0 +1,2 @@
|
||||
include Makefile.netware
|
||||
|
551
nw/Makefile.netware
Normal file
551
nw/Makefile.netware
Normal 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
25
nw/keepscreen.c
Normal 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
309
nw/nwlibc.c
Normal 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
287
nw/test/Makefile.netware
Normal 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)
|
||||
|
||||
|
@@ -1,8 +1,9 @@
|
||||
# $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
|
||||
libssh2_priv.h openssl.h libgcrypt.h pem.c transport.c
|
||||
|
||||
if LIBGCRYPT
|
||||
libssh2_la_SOURCES += libgcrypt.c
|
||||
@@ -19,7 +20,7 @@ lib_LTLIBRARIES = libssh2.la
|
||||
# tree
|
||||
INCLUDES = -I$(top_srcdir)/include -I$(top_builddir)/src
|
||||
|
||||
VERSION=-version-info 0:0:0
|
||||
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
|
||||
@@ -49,4 +50,4 @@ VERSION=-version-info 0:0:0
|
||||
# set age to 0. (c:r:a=0)
|
||||
#
|
||||
|
||||
libssh2_la_LDFLAGS = $(VERSION)
|
||||
libssh2_la_LDFLAGS = $(VERSION) -no-undefined $(LTLIBGCRYPT)
|
||||
|
587
src/channel.c
587
src/channel.c
@@ -1,4 +1,4 @@
|
||||
/* Copyright (c) 2004-2006, Sara Golemon <sarag@libssh2.org>
|
||||
/* Copyright (c) 2004-2007, Sara Golemon <sarag@libssh2.org>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms,
|
||||
@@ -36,9 +36,83 @@
|
||||
*/
|
||||
|
||||
#include "libssh2_priv.h"
|
||||
#ifndef WIN32
|
||||
#ifdef HAVE_UNISTD_H
|
||||
#include <unistd.h>
|
||||
#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
|
||||
* Determine the next channel ID we can use at our end
|
||||
@@ -63,9 +137,7 @@ unsigned long libssh2_channel_nextid(LIBSSH2_SESSION *session)
|
||||
* Gets picked up by the new one.... Pretty unlikely all told...
|
||||
*/
|
||||
session->next_channel = id + 1;
|
||||
#ifdef LIBSSH2_DEBUG_CONNECTION
|
||||
_libssh2_debug(session, LIBSSH2_DBG_CONN, "Allocated new channel ID#%lu", id);
|
||||
#endif
|
||||
return id;
|
||||
}
|
||||
/* }}} */
|
||||
@@ -104,24 +176,37 @@ LIBSSH2_CHANNEL *libssh2_channel_locate(LIBSSH2_SESSION *session, unsigned long
|
||||
/* {{{ libssh2_channel_open_session
|
||||
* Establish a generic session channel
|
||||
*/
|
||||
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)
|
||||
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)
|
||||
{
|
||||
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;
|
||||
unsigned long local_channel = libssh2_channel_nextid(session);
|
||||
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) +
|
||||
window_size(4) + packet_size(4) */
|
||||
unsigned long packet_len =
|
||||
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 long data_len;
|
||||
|
||||
#ifdef LIBSSH2_DEBUG_CONNECTION
|
||||
_libssh2_debug(session, LIBSSH2_DBG_CONN, "Opening Channel - win %d pack %d", window_size, packet_size);
|
||||
#endif
|
||||
_libssh2_debug(session, LIBSSH2_DBG_CONN,
|
||||
"Opening Channel - win %d pack %d",
|
||||
window_size, packet_size);
|
||||
channel = LIBSSH2_ALLOC(session, sizeof(LIBSSH2_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;
|
||||
}
|
||||
memset(channel, 0, sizeof(LIBSSH2_CHANNEL));
|
||||
@@ -129,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 = LIBSSH2_ALLOC(session, channel_type_len);
|
||||
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);
|
||||
return NULL;
|
||||
}
|
||||
@@ -145,27 +231,40 @@ LIBSSH2_API LIBSSH2_CHANNEL *libssh2_channel_open_ex(LIBSSH2_SESSION *session, c
|
||||
|
||||
s = packet = LIBSSH2_ALLOC(session, packet_len);
|
||||
if (!packet) {
|
||||
libssh2_error(session, LIBSSH2_ERROR_ALLOC, "Unable to allocate temporary space for packet", 0);
|
||||
return NULL;
|
||||
libssh2_error(session, LIBSSH2_ERROR_ALLOC,
|
||||
"Unable to allocate temporary space for packet",
|
||||
0);
|
||||
goto channel_error;
|
||||
}
|
||||
*(s++) = SSH_MSG_CHANNEL_OPEN;
|
||||
libssh2_htonu32(s, channel_type_len); s += 4;
|
||||
memcpy(s, channel_type, channel_type_len); s += channel_type_len;
|
||||
libssh2_htonu32(s, channel_type_len);
|
||||
s += 4;
|
||||
|
||||
libssh2_htonu32(s, local_channel); s += 4;
|
||||
libssh2_htonu32(s, window_size); s += 4;
|
||||
libssh2_htonu32(s, packet_size); s += 4;
|
||||
memcpy(s, channel_type, channel_type_len);
|
||||
s += channel_type_len;
|
||||
|
||||
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) {
|
||||
memcpy(s, message, message_len); s += message_len;
|
||||
memcpy(s, message, message_len);
|
||||
s += message_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;
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
@@ -174,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_initial = libssh2_ntohu32(data + 9);
|
||||
channel->local.packet_size = libssh2_ntohu32(data + 13);
|
||||
#ifdef LIBSSH2_DEBUG_CONNECTION
|
||||
_libssh2_debug(session, LIBSSH2_DBG_CONN, "Connection Established - ID: %lu/%lu win: %lu/%lu pack: %lu/%lu",
|
||||
_libssh2_debug(session, LIBSSH2_DBG_CONN,
|
||||
"Connection Established - ID: %lu/%lu win: %lu/%lu pack: %lu/%lu",
|
||||
channel->local.id, channel->remote.id,
|
||||
channel->local.window_size, channel->remote.window_size,
|
||||
channel->local.packet_size, channel->remote.packet_size);
|
||||
#endif
|
||||
LIBSSH2_FREE(session, packet);
|
||||
LIBSSH2_FREE(session, data);
|
||||
|
||||
@@ -187,7 +285,8 @@ LIBSSH2_API LIBSSH2_CHANNEL *libssh2_channel_open_ex(LIBSSH2_SESSION *session, c
|
||||
}
|
||||
|
||||
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:
|
||||
@@ -217,8 +316,12 @@ LIBSSH2_API LIBSSH2_CHANNEL *libssh2_channel_open_ex(LIBSSH2_SESSION *session, c
|
||||
|
||||
/* Clear out packets meant for this channel */
|
||||
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) ||
|
||||
(libssh2_packet_ask_ex(session, SSH_MSG_CHANNEL_EXTENDED_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, 0) >= 0)) {
|
||||
LIBSSH2_FREE(session, data);
|
||||
}
|
||||
|
||||
@@ -232,16 +335,14 @@ LIBSSH2_API LIBSSH2_CHANNEL *libssh2_channel_open_ex(LIBSSH2_SESSION *session, c
|
||||
/* {{{ libssh2_channel_direct_tcpip_ex
|
||||
* 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;
|
||||
unsigned char *message, *s;
|
||||
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) */
|
||||
|
||||
#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);
|
||||
#endif
|
||||
|
||||
s = message = LIBSSH2_ALLOC(session, message_len);
|
||||
if (!message) {
|
||||
@@ -270,17 +371,16 @@ LIBSSH2_API LIBSSH2_CHANNEL *libssh2_channel_direct_tcpip_ex(LIBSSH2_SESSION *se
|
||||
/* {{{ libssh2_channel_forward_listen_ex
|
||||
* 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 host_len = (host ? strlen(host) : (sizeof("0.0.0.0") - 1));
|
||||
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) */
|
||||
|
||||
#ifdef LIBSSH2_DEBUG_CONNECTION
|
||||
_libssh2_debug(session, LIBSSH2_DBG_CONN, "Requesting tcpip-forward session for %s:%d", host, port);
|
||||
#endif
|
||||
|
||||
s = packet = LIBSSH2_ALLOC(session, packet_len);
|
||||
if (!packet) {
|
||||
@@ -330,9 +430,9 @@ LIBSSH2_API LIBSSH2_LISTENER *libssh2_channel_forward_listen_ex(LIBSSH2_SESSION
|
||||
listener->host[host_len] = 0;
|
||||
if (data_len >= 5 && !port) {
|
||||
listener->port = libssh2_ntohu32(data + 1);
|
||||
#ifdef LIBSSH2_DEBUG_CONNECTION
|
||||
_libssh2_debug(session, LIBSSH2_DBG_CONN, "Dynamic tcpip-forward port allocated: %d", listener->port);
|
||||
#endif
|
||||
_libssh2_debug(session, LIBSSH2_DBG_CONN,
|
||||
"Dynamic tcpip-forward port allocated: %d",
|
||||
listener->port);
|
||||
} else {
|
||||
listener->port = port;
|
||||
}
|
||||
@@ -378,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;
|
||||
/* 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);
|
||||
#endif
|
||||
|
||||
s = packet = LIBSSH2_ALLOC(session, packet_len);
|
||||
if (!packet) {
|
||||
@@ -430,9 +528,18 @@ LIBSSH2_API int libssh2_channel_forward_cancel(LIBSSH2_LISTENER *listener)
|
||||
/* {{{ libssh2_channel_forward_accept
|
||||
* 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) {
|
||||
LIBSSH2_SESSION *session = listener->session;
|
||||
@@ -466,17 +573,16 @@ LIBSSH2_API LIBSSH2_CHANNEL *libssh2_channel_forward_accept(LIBSSH2_LISTENER *li
|
||||
/* {{{ libssh2_channel_setenv_ex
|
||||
* Set an environment variable prior to requesting a shell/program/subsystem
|
||||
*/
|
||||
LIBSSH2_API int libssh2_channel_setenv_ex(LIBSSH2_CHANNEL *channel, char *varname, unsigned int varname_len, char *value, unsigned 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;
|
||||
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 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) */
|
||||
|
||||
#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);
|
||||
#endif
|
||||
|
||||
s = packet = LIBSSH2_ALLOC(session, packet_len);
|
||||
if (!packet) {
|
||||
@@ -515,7 +621,8 @@ LIBSSH2_API int libssh2_channel_setenv_ex(LIBSSH2_CHANNEL *channel, char *varnam
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
/* }}} */
|
||||
@@ -523,20 +630,19 @@ LIBSSH2_API int libssh2_channel_setenv_ex(LIBSSH2_CHANNEL *channel, char *varnam
|
||||
/* {{{ libssh2_channel_request_pty_ex
|
||||
* Duh... Request a PTY
|
||||
*/
|
||||
LIBSSH2_API int libssh2_channel_request_pty_ex(LIBSSH2_CHANNEL *channel, char *term, unsigned int term_len,
|
||||
char *modes, unsigned int modes_len,
|
||||
LIBSSH2_API int libssh2_channel_request_pty_ex(LIBSSH2_CHANNEL *channel, const char *term, unsigned int term_len,
|
||||
const char *modes, unsigned int modes_len,
|
||||
int width, int height,
|
||||
int width_px, int height_px)
|
||||
{
|
||||
LIBSSH2_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 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) */
|
||||
|
||||
#ifdef LIBSSH2_DEBUG_CONNECTION
|
||||
_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);
|
||||
if (!packet) {
|
||||
@@ -594,22 +700,21 @@ LIBSSH2_API int libssh2_channel_request_pty_ex(LIBSSH2_CHANNEL *channel, char *t
|
||||
/* {{{ libssh2_channel_x11_req_ex
|
||||
* 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;
|
||||
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 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 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) */
|
||||
|
||||
#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",
|
||||
channel->local.id, channel->remote.id, single_connection,
|
||||
auth_proto ? auth_proto : "MIT-MAGIC-COOKIE-1",
|
||||
auth_cookie ? auth_cookie : "<random>", screen_number);
|
||||
#endif
|
||||
|
||||
s = packet = LIBSSH2_ALLOC(session, packet_len);
|
||||
if (!packet) {
|
||||
@@ -675,18 +780,17 @@ LIBSSH2_API int libssh2_channel_x11_req_ex(LIBSSH2_CHANNEL *channel, int single_
|
||||
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;
|
||||
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 packet_len = request_len + 10; /* packet_type(1) + channel(4) + request_len(4) + want_reply(1) */
|
||||
libssh2pack_t rc;
|
||||
|
||||
if (message) {
|
||||
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);
|
||||
#endif
|
||||
|
||||
s = packet = LIBSSH2_ALLOC(session, packet_len);
|
||||
if (!packet) {
|
||||
libssh2_error(session, LIBSSH2_ERROR_ALLOC, "Unable to allocate memory for channel-process request", 0);
|
||||
@@ -705,7 +809,8 @@ LIBSSH2_API int libssh2_channel_process_startup(LIBSSH2_CHANNEL *channel, const
|
||||
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_FREE(session, packet);
|
||||
return -1;
|
||||
@@ -728,15 +833,46 @@ LIBSSH2_API int libssh2_channel_process_startup(LIBSSH2_CHANNEL *channel, const
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
/* {{{ 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_channel_set_blocking
|
||||
* 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
|
||||
_libssh2_debug(channel->session, LIBSSH2_DBG_CONN, "Setting blocking mode on channel %lu/%lu to %d", channel->local.id, channel->remote.id, blocking);
|
||||
#endif
|
||||
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);
|
||||
if(blocking == channel->blocking) {
|
||||
/* avoid if already correct */
|
||||
return bl;
|
||||
}
|
||||
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;
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
@@ -753,18 +889,29 @@ LIBSSH2_API int libssh2_channel_flush_ex(LIBSSH2_CHANNEL *channel, int streamid)
|
||||
LIBSSH2_PACKET *next = packet->next;
|
||||
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)) {
|
||||
/* 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) ||
|
||||
((packet_type == SSH_MSG_CHANNEL_EXTENDED_DATA) && ((streamid == LIBSSH2_CHANNEL_FLUSH_EXTENDED_DATA) || (streamid == packet_stream_id))) ||
|
||||
((packet_type == SSH_MSG_CHANNEL_DATA) && (streamid == 0))) {
|
||||
int bytes_to_flush = packet->data_len - packet->data_head;
|
||||
#ifdef LIBSSH2_DEBUG_CONNECTION
|
||||
_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);
|
||||
#endif
|
||||
((packet_type == SSH_MSG_CHANNEL_EXTENDED_DATA) &&
|
||||
((streamid == LIBSSH2_CHANNEL_FLUSH_EXTENDED_DATA) ||
|
||||
(streamid == packet_stream_id))) ||
|
||||
((packet_type == SSH_MSG_CHANNEL_DATA) &&
|
||||
(streamid == 0))) {
|
||||
int bytes_to_flush =
|
||||
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 */
|
||||
refund_bytes += packet->data_len - 13;
|
||||
@@ -817,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) */
|
||||
|
||||
if (!force && (adjustment + channel->adjust_queue < LIBSSH2_CHANNEL_MINADJUST)) {
|
||||
#ifdef LIBSSH2_DEBUG_CONNECTION
|
||||
_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
|
||||
_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);
|
||||
channel->adjust_queue += adjustment;
|
||||
return channel->remote.window_size;
|
||||
}
|
||||
@@ -836,9 +981,7 @@ LIBSSH2_API unsigned long libssh2_channel_receive_window_adjust(LIBSSH2_CHANNEL
|
||||
adjust[0] = SSH_MSG_CHANNEL_WINDOW_ADJUST;
|
||||
libssh2_htonu32(adjust + 1, channel->remote.id);
|
||||
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);
|
||||
#endif
|
||||
|
||||
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);
|
||||
@@ -859,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)
|
||||
{
|
||||
#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);
|
||||
#endif
|
||||
channel->remote.extended_data_ignore_mode = ignore_mode;
|
||||
|
||||
if (ignore_mode == LIBSSH2_CHANNEL_EXTENDED_DATA_IGNORE) {
|
||||
@@ -870,46 +1011,99 @@ LIBSSH2_API void libssh2_channel_handle_extended_data(LIBSSH2_CHANNEL *channel,
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
/* {{{ libssh2_channel_read_ex
|
||||
* Read data from a channel
|
||||
/* {{{ _libssh2_channel_read_ex
|
||||
* 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;
|
||||
int bytes_read = 0, blocking_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 {
|
||||
int bytes_read = 0;
|
||||
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;
|
||||
|
||||
while (packet && (bytes_read < buflen)) {
|
||||
/* In case packet gets destroyed during this iteration */
|
||||
do {
|
||||
|
||||
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;
|
||||
|
||||
/* 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 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))) ||
|
||||
(!stream_id && (packet->data[0] == SSH_MSG_CHANNEL_DATA) && (channel->local.id == libssh2_ntohu32(packet->data + 1))) ||
|
||||
(!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))) {
|
||||
if ((stream_id &&
|
||||
(packet->data[0] == SSH_MSG_CHANNEL_EXTENDED_DATA) &&
|
||||
(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 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;
|
||||
unlink_packet = 1;
|
||||
}
|
||||
|
||||
#ifdef LIBSSH2_DEBUG_CONNECTION
|
||||
_libssh2_debug(session, LIBSSH2_DBG_CONN, "Reading %d of buffered data from %lu/%lu/%d", want, channel->local.id, channel->remote.id, stream_id);
|
||||
#endif
|
||||
_libssh2_debug(session, LIBSSH2_DBG_CONN,
|
||||
"Reading %d of buffered data from %lu/%lu/%d",
|
||||
want, channel->local.id,
|
||||
channel->remote.id, stream_id);
|
||||
memcpy(buf + bytes_read, packet->data + packet->data_head, want);
|
||||
packet->data_head += want;
|
||||
bytes_read += want;
|
||||
@@ -927,38 +1121,96 @@ LIBSSH2_API int libssh2_channel_read_ex(LIBSSH2_CHANNEL *channel, int stream_id,
|
||||
}
|
||||
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);
|
||||
#endif
|
||||
|
||||
_libssh2_debug(session,
|
||||
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_FREE(session, packet);
|
||||
}
|
||||
}
|
||||
packet = next;
|
||||
}
|
||||
blocking_read = 1;
|
||||
} while (channel->blocking && (bytes_read == 0) && !channel->remote.close);
|
||||
block=1;
|
||||
|
||||
if (channel->blocking && (bytes_read == 0)) {
|
||||
libssh2_error(session, LIBSSH2_ERROR_CHANNEL_CLOSED, "Remote end has closed this channel", 0);
|
||||
} while (channel->blocking && (bytes_read == 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;
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
|
||||
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
|
||||
* 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;
|
||||
unsigned char *packet;
|
||||
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);
|
||||
#endif
|
||||
if (channel->local.close) {
|
||||
libssh2_error(session, LIBSSH2_ERROR_CHANNEL_CLOSED, "We've already closed this channel", 0);
|
||||
return -1;
|
||||
@@ -983,6 +1235,7 @@ LIBSSH2_API int libssh2_channel_write_ex(LIBSSH2_CHANNEL *channel, int stream_id
|
||||
while (buflen > 0) {
|
||||
size_t bufwrite = buflen;
|
||||
unsigned char *s = packet;
|
||||
libssh2pack_t rc;
|
||||
|
||||
*(s++) = stream_id ? SSH_MSG_CHANNEL_EXTENDED_DATA : SSH_MSG_CHANNEL_DATA;
|
||||
libssh2_htonu32(s, channel->remote.id); s += 4;
|
||||
@@ -992,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 */
|
||||
while (channel->local.window_size <= 0) {
|
||||
/* Don't worry -- This is never hit unless it's a blocking channel anyway */
|
||||
if (libssh2_packet_read(session, 1) < 0) {
|
||||
/* Error occured, disconnect? */
|
||||
return -1;
|
||||
/* Don't worry -- This is never hit unless it's a
|
||||
blocking channel anyway */
|
||||
rc = libssh2_packet_read(session);
|
||||
|
||||
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 */
|
||||
/* REMEMBER local means local as the SOURCE of the data */
|
||||
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);
|
||||
#endif
|
||||
bufwrite = channel->local.window_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);
|
||||
#endif
|
||||
bufwrite = channel->local.packet_size;
|
||||
}
|
||||
libssh2_htonu32(s, bufwrite); s += 4;
|
||||
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);
|
||||
#endif
|
||||
if (libssh2_packet_write(session, packet, s - packet)) {
|
||||
rc = libssh2_packet_write(session, packet, s - packet);
|
||||
if(rc) {
|
||||
libssh2_error(session, LIBSSH2_ERROR_SOCKET_SEND, "Unable to send channel data", 0);
|
||||
LIBSSH2_FREE(session, packet);
|
||||
return -1;
|
||||
@@ -1043,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
|
||||
* Send EOF on channel
|
||||
*/
|
||||
@@ -1051,9 +1350,7 @@ LIBSSH2_API int libssh2_channel_send_eof(LIBSSH2_CHANNEL *channel)
|
||||
LIBSSH2_SESSION *session = channel->session;
|
||||
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);
|
||||
#endif
|
||||
packet[0] = SSH_MSG_CHANNEL_EOF;
|
||||
libssh2_htonu32(packet + 1, channel->remote.id);
|
||||
if (libssh2_packet_write(session, packet, 5)) {
|
||||
@@ -1094,15 +1391,14 @@ LIBSSH2_API int libssh2_channel_close(LIBSSH2_CHANNEL *channel)
|
||||
{
|
||||
LIBSSH2_SESSION *session = channel->session;
|
||||
unsigned char packet[5];
|
||||
int rc = 0;
|
||||
|
||||
if (channel->local.close) {
|
||||
/* Already closed, act like we sent another close, even though we didn't... shhhhhh */
|
||||
return 0;
|
||||
}
|
||||
|
||||
#ifdef LIBSSH2_DEBUG_CONNECTION
|
||||
_libssh2_debug(session, LIBSSH2_DBG_CONN, "Closing channel %lu/%lu", channel->local.id, channel->remote.id);
|
||||
#endif
|
||||
|
||||
if (channel->close_cb) {
|
||||
LIBSSH2_CHANNEL_CLOSE(session, channel);
|
||||
@@ -1116,9 +1412,22 @@ LIBSSH2_API int libssh2_channel_close(LIBSSH2_CHANNEL *channel)
|
||||
return -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;
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
@@ -1134,16 +1443,14 @@ LIBSSH2_API int libssh2_channel_wait_closed(LIBSSH2_CHANNEL *channel)
|
||||
return -1;
|
||||
}
|
||||
|
||||
#ifdef LIBSSH2_DEBUG_CONNECTION
|
||||
_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
|
||||
* packets from the network.
|
||||
* Either or channel will be closed
|
||||
* 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;
|
||||
@@ -1160,9 +1467,7 @@ LIBSSH2_API int libssh2_channel_free(LIBSSH2_CHANNEL *channel)
|
||||
unsigned char channel_id[4], *data;
|
||||
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);
|
||||
#endif
|
||||
/* Allow channel freeing even when the socket has lost its connection */
|
||||
if (!channel->local.close && (session->socket_state == LIBSSH2_SOCKET_CONNECTED) &&
|
||||
libssh2_channel_close(channel)) {
|
||||
@@ -1176,8 +1481,8 @@ LIBSSH2_API int libssh2_channel_free(LIBSSH2_CHANNEL *channel)
|
||||
|
||||
/* Clear out packets meant for this channel */
|
||||
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) ||
|
||||
(libssh2_packet_ask_ex(session, SSH_MSG_CHANNEL_EXTENDED_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, 0) >= 0)) {
|
||||
LIBSSH2_FREE(session, data);
|
||||
}
|
||||
|
||||
|
30
src/comp.c
30
src/comp.c
@@ -1,4 +1,4 @@
|
||||
/* Copyright (c) 2004-2006, Sara Golemon <sarag@libssh2.org>
|
||||
/* Copyright (c) 2004-2007, Sara Golemon <sarag@libssh2.org>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms,
|
||||
@@ -36,7 +36,9 @@
|
||||
*/
|
||||
|
||||
#include "libssh2_priv.h"
|
||||
#ifdef LIBSSH2_HAVE_ZLIB
|
||||
# include <zlib.h>
|
||||
#endif
|
||||
|
||||
/* ********
|
||||
* none *
|
||||
@@ -68,8 +70,8 @@ static int libssh2_comp_method_none_comp(LIBSSH2_SESSION *session,
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
static LIBSSH2_COMP_METHOD libssh2_comp_method_none = {
|
||||
(char *)"none",
|
||||
static const LIBSSH2_COMP_METHOD libssh2_comp_method_none = {
|
||||
"none",
|
||||
NULL,
|
||||
libssh2_comp_method_none_comp,
|
||||
NULL
|
||||
@@ -189,6 +191,7 @@ static int libssh2_comp_method_zlib_comp(LIBSSH2_SESSION *session,
|
||||
}
|
||||
if (strm->avail_in) {
|
||||
unsigned long out_ofs = out_maxlen - strm->avail_out;
|
||||
char *newout;
|
||||
|
||||
out_maxlen += compress ? (strm->avail_in + 4) : (2 * strm->avail_in);
|
||||
|
||||
@@ -200,11 +203,13 @@ static int libssh2_comp_method_zlib_comp(LIBSSH2_SESSION *session,
|
||||
return -1;
|
||||
}
|
||||
|
||||
out = LIBSSH2_REALLOC(session, out, out_maxlen);
|
||||
if (!out) {
|
||||
newout = LIBSSH2_REALLOC(session, out, out_maxlen);
|
||||
if (!newout) {
|
||||
libssh2_error(session, LIBSSH2_ERROR_ALLOC, "Unable to expand compress/decompression buffer", 0);
|
||||
LIBSSH2_FREE(session, out);
|
||||
return -1;
|
||||
}
|
||||
out = newout;
|
||||
strm->next_out = (unsigned char *)out + out_ofs;
|
||||
strm->avail_out += compress ? (strm->avail_in + 4) : (2 * strm->avail_in);
|
||||
} else while (!strm->avail_out) {
|
||||
@@ -212,6 +217,7 @@ static int libssh2_comp_method_zlib_comp(LIBSSH2_SESSION *session,
|
||||
* Or potentially many bytes if it's a decompress
|
||||
*/
|
||||
int grow_size = compress ? 8 : 1024;
|
||||
char *newout;
|
||||
|
||||
if (out_maxlen >= (int)payload_limit) {
|
||||
libssh2_error(session, LIBSSH2_ERROR_ZLIB, "Excessive growth in decompression phase", 0);
|
||||
@@ -226,11 +232,13 @@ static int libssh2_comp_method_zlib_comp(LIBSSH2_SESSION *session,
|
||||
out_maxlen += grow_size;
|
||||
strm->avail_out = grow_size;
|
||||
|
||||
out = LIBSSH2_REALLOC(session, out, out_maxlen);
|
||||
if (!out) {
|
||||
newout = LIBSSH2_REALLOC(session, out, out_maxlen);
|
||||
if (!newout) {
|
||||
libssh2_error(session, LIBSSH2_ERROR_ALLOC, "Unable to expand final compress/decompress buffer", 0);
|
||||
LIBSSH2_FREE(session, out);
|
||||
return -1;
|
||||
}
|
||||
out = newout;
|
||||
strm->next_out = (unsigned char *)out + out_maxlen -
|
||||
grow_size;
|
||||
|
||||
@@ -280,8 +288,8 @@ static int libssh2_comp_method_zlib_dtor(LIBSSH2_SESSION *session, int compress,
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
static LIBSSH2_COMP_METHOD libssh2_comp_method_zlib = {
|
||||
(char *)"zlib",
|
||||
static const LIBSSH2_COMP_METHOD libssh2_comp_method_zlib = {
|
||||
"zlib",
|
||||
libssh2_comp_method_zlib_init,
|
||||
libssh2_comp_method_zlib_comp,
|
||||
libssh2_comp_method_zlib_dtor,
|
||||
@@ -292,7 +300,7 @@ static LIBSSH2_COMP_METHOD libssh2_comp_method_zlib = {
|
||||
* Compression Methods *
|
||||
*********************** */
|
||||
|
||||
static LIBSSH2_COMP_METHOD *_libssh2_comp_methods[] = {
|
||||
static const LIBSSH2_COMP_METHOD *_libssh2_comp_methods[] = {
|
||||
&libssh2_comp_method_none,
|
||||
#ifdef LIBSSH2_HAVE_ZLIB
|
||||
&libssh2_comp_method_zlib,
|
||||
@@ -300,7 +308,7 @@ static LIBSSH2_COMP_METHOD *_libssh2_comp_methods[] = {
|
||||
NULL
|
||||
};
|
||||
|
||||
LIBSSH2_COMP_METHOD **libssh2_comp_methods(void) {
|
||||
const LIBSSH2_COMP_METHOD **libssh2_comp_methods(void) {
|
||||
return _libssh2_comp_methods;
|
||||
}
|
||||
|
||||
|
85
src/crypt.c
85
src/crypt.c
@@ -1,4 +1,4 @@
|
||||
/* Copyright (c) 2004-2006, Sara Golemon <sarag@libssh2.org>
|
||||
/* Copyright (c) 2004-2007, Sara Golemon <sarag@libssh2.org>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms,
|
||||
@@ -37,7 +37,7 @@
|
||||
|
||||
#include "libssh2_priv.h"
|
||||
|
||||
#if LIBSSH2_CRYPT_NONE
|
||||
#ifdef LIBSSH2_CRYPT_NONE
|
||||
/* {{{ libssh2_crypt_none_crypt
|
||||
* Minimalist cipher: VERY secure *wink*
|
||||
*/
|
||||
@@ -48,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",
|
||||
8, /* blocksize (SSH2 defines minimum blocksize as 8) */
|
||||
0, /* iv_len */
|
||||
@@ -66,8 +66,8 @@ struct crypt_ctx {
|
||||
_libssh2_cipher_ctx h;
|
||||
};
|
||||
|
||||
static int init (LIBSSH2_SESSION *session,
|
||||
LIBSSH2_CRYPT_METHOD *method,
|
||||
static int _libssh2_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)
|
||||
@@ -90,14 +90,15 @@ static int init (LIBSSH2_SESSION *session,
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int crypt(LIBSSH2_SESSION *session, unsigned char *block, void **abstract)
|
||||
static int _libssh2_encrypt(LIBSSH2_SESSION *session, unsigned char *block, void **abstract)
|
||||
{
|
||||
struct crypt_ctx *cctx = *(struct crypt_ctx **)abstract;
|
||||
(void)session;
|
||||
return _libssh2_cipher_crypt(&cctx->h, cctx->algo,
|
||||
cctx->encrypt, block);
|
||||
}
|
||||
|
||||
static int dtor(LIBSSH2_SESSION *session, void **abstract)
|
||||
static int _libssh2_dtor(LIBSSH2_SESSION *session, void **abstract)
|
||||
{
|
||||
struct crypt_ctx **cctx = (struct crypt_ctx **)abstract;
|
||||
if (cctx && *cctx) {
|
||||
@@ -109,113 +110,113 @@ static int dtor(LIBSSH2_SESSION *session, void **abstract)
|
||||
}
|
||||
|
||||
#if LIBSSH2_AES
|
||||
static LIBSSH2_CRYPT_METHOD libssh2_crypt_method_aes128_cbc = {
|
||||
static const LIBSSH2_CRYPT_METHOD libssh2_crypt_method_aes128_cbc = {
|
||||
"aes128-cbc",
|
||||
16, /* blocksize */
|
||||
16, /* initial value length */
|
||||
16, /* secret length -- 16*8 == 128bit */
|
||||
0, /* flags */
|
||||
&init,
|
||||
&crypt,
|
||||
&dtor,
|
||||
&_libssh2_init,
|
||||
&_libssh2_encrypt,
|
||||
&_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",
|
||||
16, /* blocksize */
|
||||
16, /* initial value length */
|
||||
24, /* secret length -- 24*8 == 192bit */
|
||||
0, /* flags */
|
||||
&init,
|
||||
&crypt,
|
||||
&dtor,
|
||||
&_libssh2_init,
|
||||
&_libssh2_encrypt,
|
||||
&_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",
|
||||
16, /* blocksize */
|
||||
16, /* initial value length */
|
||||
32, /* secret length -- 32*8 == 256bit */
|
||||
0, /* flags */
|
||||
&init,
|
||||
&crypt,
|
||||
&dtor,
|
||||
&_libssh2_init,
|
||||
&_libssh2_encrypt,
|
||||
&_libssh2_dtor,
|
||||
_libssh2_cipher_aes256
|
||||
};
|
||||
|
||||
/* 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",
|
||||
16, /* blocksize */
|
||||
16, /* initial value length */
|
||||
32, /* secret length -- 32*8 == 256bit */
|
||||
0, /* flags */
|
||||
&init,
|
||||
&crypt,
|
||||
&dtor,
|
||||
&_libssh2_init,
|
||||
&_libssh2_encrypt,
|
||||
&_libssh2_dtor,
|
||||
_libssh2_cipher_aes256
|
||||
};
|
||||
#endif /* LIBSSH2_AES */
|
||||
|
||||
#if LIBSSH2_BLOWFISH
|
||||
static LIBSSH2_CRYPT_METHOD libssh2_crypt_method_blowfish_cbc = {
|
||||
static const LIBSSH2_CRYPT_METHOD libssh2_crypt_method_blowfish_cbc = {
|
||||
"blowfish-cbc",
|
||||
8, /* blocksize */
|
||||
8, /* initial value length */
|
||||
16, /* secret length */
|
||||
0, /* flags */
|
||||
&init,
|
||||
&crypt,
|
||||
&dtor,
|
||||
&_libssh2_init,
|
||||
&_libssh2_encrypt,
|
||||
&_libssh2_dtor,
|
||||
_libssh2_cipher_blowfish
|
||||
};
|
||||
#endif /* LIBSSH2_BLOWFISH */
|
||||
|
||||
#if LIBSSH2_RC4
|
||||
static LIBSSH2_CRYPT_METHOD libssh2_crypt_method_arcfour = {
|
||||
static const LIBSSH2_CRYPT_METHOD libssh2_crypt_method_arcfour = {
|
||||
"arcfour",
|
||||
8, /* blocksize */
|
||||
8, /* initial value length */
|
||||
16, /* secret length */
|
||||
0, /* flags */
|
||||
&init,
|
||||
&crypt,
|
||||
&dtor,
|
||||
&_libssh2_init,
|
||||
&_libssh2_encrypt,
|
||||
&_libssh2_dtor,
|
||||
_libssh2_cipher_arcfour
|
||||
};
|
||||
#endif /* LIBSSH2_RC4 */
|
||||
|
||||
#if LIBSSH2_CAST
|
||||
static LIBSSH2_CRYPT_METHOD libssh2_crypt_method_cast128_cbc = {
|
||||
static const LIBSSH2_CRYPT_METHOD libssh2_crypt_method_cast128_cbc = {
|
||||
"cast128-cbc",
|
||||
8, /* blocksize */
|
||||
8, /* initial value length */
|
||||
16, /* secret length */
|
||||
0, /* flags */
|
||||
&init,
|
||||
&crypt,
|
||||
&dtor,
|
||||
&_libssh2_init,
|
||||
&_libssh2_encrypt,
|
||||
&_libssh2_dtor,
|
||||
_libssh2_cipher_cast5
|
||||
};
|
||||
#endif /* LIBSSH2_CAST */
|
||||
|
||||
#if LIBSSH2_3DES
|
||||
static LIBSSH2_CRYPT_METHOD libssh2_crypt_method_3des_cbc = {
|
||||
static const LIBSSH2_CRYPT_METHOD libssh2_crypt_method_3des_cbc = {
|
||||
"3des-cbc",
|
||||
8, /* blocksize */
|
||||
8, /* initial value length */
|
||||
24, /* secret length */
|
||||
0, /* flags */
|
||||
&init,
|
||||
&crypt,
|
||||
&dtor,
|
||||
&_libssh2_init,
|
||||
&_libssh2_encrypt,
|
||||
&_libssh2_dtor,
|
||||
_libssh2_cipher_3des
|
||||
};
|
||||
#endif
|
||||
|
||||
static LIBSSH2_CRYPT_METHOD *_libssh2_crypt_methods[] = {
|
||||
static const LIBSSH2_CRYPT_METHOD *_libssh2_crypt_methods[] = {
|
||||
#if LIBSSH2_AES
|
||||
&libssh2_crypt_method_aes256_cbc,
|
||||
&libssh2_crypt_method_rijndael_cbc_lysator_liu_se, /* == aes256-cbc */
|
||||
@@ -234,13 +235,13 @@ static LIBSSH2_CRYPT_METHOD *_libssh2_crypt_methods[] = {
|
||||
#if LIBSSH2_3DES
|
||||
&libssh2_crypt_method_3des_cbc,
|
||||
#endif /* LIBSSH2_DES */
|
||||
#if LIBSSH2_CRYPT_NONE
|
||||
#ifdef LIBSSH2_CRYPT_NONE
|
||||
&libssh2_crypt_method_none,
|
||||
#endif
|
||||
NULL
|
||||
};
|
||||
|
||||
/* Expose to kex.c */
|
||||
LIBSSH2_CRYPT_METHOD **libssh2_crypt_methods(void) {
|
||||
const LIBSSH2_CRYPT_METHOD **libssh2_crypt_methods(void) {
|
||||
return _libssh2_crypt_methods;
|
||||
}
|
||||
|
@@ -54,12 +54,12 @@ static int libssh2_hostkey_method_ssh_rsa_dtor(LIBSSH2_SESSION *session, void **
|
||||
*/
|
||||
static int
|
||||
libssh2_hostkey_method_ssh_rsa_init(LIBSSH2_SESSION *session,
|
||||
unsigned char *hostkey_data,
|
||||
const unsigned char *hostkey_data,
|
||||
unsigned long hostkey_data_len,
|
||||
void **abstract)
|
||||
{
|
||||
libssh2_rsa_ctx *rsactx;
|
||||
unsigned char *s, *e, *n;
|
||||
const unsigned char *s, *e, *n;
|
||||
unsigned long len, e_len, n_len;
|
||||
|
||||
(void)hostkey_data_len;
|
||||
@@ -191,7 +191,7 @@ static int libssh2_hostkey_method_ssh_rsa_dtor(LIBSSH2_SESSION *session,
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
static LIBSSH2_HOSTKEY_METHOD libssh2_hostkey_method_ssh_rsa = {
|
||||
static const LIBSSH2_HOSTKEY_METHOD libssh2_hostkey_method_ssh_rsa = {
|
||||
"ssh-rsa",
|
||||
MD5_DIGEST_LENGTH,
|
||||
libssh2_hostkey_method_ssh_rsa_init,
|
||||
@@ -215,12 +215,12 @@ static int libssh2_hostkey_method_ssh_dss_dtor(LIBSSH2_SESSION *session, void **
|
||||
*/
|
||||
static int
|
||||
libssh2_hostkey_method_ssh_dss_init(LIBSSH2_SESSION *session,
|
||||
unsigned char *hostkey_data,
|
||||
const unsigned char *hostkey_data,
|
||||
unsigned long hostkey_data_len,
|
||||
void **abstract)
|
||||
{
|
||||
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;
|
||||
(void)hostkey_data_len;
|
||||
|
||||
@@ -317,13 +317,13 @@ static int libssh2_hostkey_method_ssh_dss_signv(LIBSSH2_SESSION *session, unsign
|
||||
unsigned int i;
|
||||
|
||||
*signature = LIBSSH2_ALLOC(session, 2 * SHA_DIGEST_LENGTH);
|
||||
*signature_len = 2 * SHA_DIGEST_LENGTH;
|
||||
memset(*signature, 0, 2 * SHA_DIGEST_LENGTH);
|
||||
|
||||
if (!(*signature)) {
|
||||
if (!*signature) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
*signature_len = 2 * SHA_DIGEST_LENGTH;
|
||||
memset(*signature, 0, 2 * SHA_DIGEST_LENGTH);
|
||||
|
||||
libssh2_sha1_init(&ctx);
|
||||
for(i = 0; i < veccount; i++) {
|
||||
libssh2_sha1_update(ctx, datavec[i].iov_base, datavec[i].iov_len);
|
||||
@@ -358,7 +358,7 @@ static int libssh2_hostkey_method_ssh_dss_dtor(LIBSSH2_SESSION *session,
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
static LIBSSH2_HOSTKEY_METHOD libssh2_hostkey_method_ssh_dss = {
|
||||
static const LIBSSH2_HOSTKEY_METHOD libssh2_hostkey_method_ssh_dss = {
|
||||
"ssh-dss",
|
||||
MD5_DIGEST_LENGTH,
|
||||
libssh2_hostkey_method_ssh_dss_init,
|
||||
@@ -370,7 +370,7 @@ static LIBSSH2_HOSTKEY_METHOD libssh2_hostkey_method_ssh_dss = {
|
||||
};
|
||||
#endif /* LIBSSH2_DSA */
|
||||
|
||||
static LIBSSH2_HOSTKEY_METHOD *_libssh2_hostkey_methods[] = {
|
||||
static const LIBSSH2_HOSTKEY_METHOD *_libssh2_hostkey_methods[] = {
|
||||
#if LIBSSH2_RSA
|
||||
&libssh2_hostkey_method_ssh_rsa,
|
||||
#endif /* LIBSSH2_RSA */
|
||||
@@ -380,7 +380,7 @@ static LIBSSH2_HOSTKEY_METHOD *_libssh2_hostkey_methods[] = {
|
||||
NULL
|
||||
};
|
||||
|
||||
LIBSSH2_HOSTKEY_METHOD **libssh2_hostkey_methods(void)
|
||||
const LIBSSH2_HOSTKEY_METHOD **libssh2_hostkey_methods(void)
|
||||
{
|
||||
return _libssh2_hostkey_methods;
|
||||
}
|
||||
|
188
src/kex.c
188
src/kex.c
@@ -1,4 +1,4 @@
|
||||
/* Copyright (c) 2004-2006, Sara Golemon <sarag@libssh2.org>
|
||||
/* Copyright (c) 2004-2007, Sara Golemon <sarag@libssh2.org>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms,
|
||||
@@ -46,6 +46,7 @@
|
||||
if (!(value)) { \
|
||||
value = LIBSSH2_ALLOC(session, reqlen + SHA_DIGEST_LENGTH); \
|
||||
} \
|
||||
if (value) \
|
||||
while (len < reqlen) { \
|
||||
libssh2_sha1_init(&hash); \
|
||||
libssh2_sha1_update(hash, k_value, k_value_len); \
|
||||
@@ -79,6 +80,7 @@ static int libssh2_kex_method_diffie_hellman_groupGP_sha1_key_exchange(LIBSSH2_S
|
||||
unsigned char *s, *f_value, *k_value = NULL, *h_sig;
|
||||
unsigned long f_value_len, k_value_len, h_sig_len;
|
||||
libssh2_sha1_ctx exchange_hash;
|
||||
int rc;
|
||||
|
||||
/* Generate x and e */
|
||||
_libssh2_bn_rand(x, group_order, 0, -1);
|
||||
@@ -105,10 +107,9 @@ static int libssh2_kex_method_diffie_hellman_groupGP_sha1_key_exchange(LIBSSH2_S
|
||||
_libssh2_bn_to_bin(e, e_packet + 6);
|
||||
}
|
||||
|
||||
#ifdef LIBSSH2_DEBUG_KEX
|
||||
_libssh2_debug(session, LIBSSH2_DBG_KEX, "Sending KEX packet %d", (int)packet_type_init);
|
||||
#endif
|
||||
if (libssh2_packet_write(session, e_packet, e_packet_len)) {
|
||||
rc = libssh2_packet_write(session, e_packet, e_packet_len);
|
||||
if (rc) {
|
||||
libssh2_error(session, LIBSSH2_ERROR_SOCKET_SEND, "Unable to send KEX init message", 0);
|
||||
ret = -11;
|
||||
goto clean_exit;
|
||||
@@ -118,9 +119,7 @@ static int libssh2_kex_method_diffie_hellman_groupGP_sha1_key_exchange(LIBSSH2_S
|
||||
/* The first KEX packet to come along will be the guess initially sent by the server
|
||||
* That guess turned out to be wrong so we need to silently ignore it */
|
||||
int burn_type;
|
||||
#ifdef LIBSSH2_DEBUG_KEX
|
||||
_libssh2_debug(session, LIBSSH2_DBG_KEX, "Waiting for badly guessed KEX packet (to be ignored)");
|
||||
#endif
|
||||
burn_type = libssh2_packet_burn(session);
|
||||
if (burn_type <= 0) {
|
||||
/* Failed to receive a packet */
|
||||
@@ -129,14 +128,15 @@ static int libssh2_kex_method_diffie_hellman_groupGP_sha1_key_exchange(LIBSSH2_S
|
||||
}
|
||||
session->burn_optimistic_kexinit = 0;
|
||||
|
||||
#ifdef LIBSSH2_DEBUG_KEX
|
||||
_libssh2_debug(session, LIBSSH2_DBG_KEX, "Burnt packet of type: %02x", (unsigned int)burn_type);
|
||||
#endif
|
||||
}
|
||||
|
||||
/* Wait for KEX reply */
|
||||
if (libssh2_packet_require(session, packet_type_reply, &s_packet, &s_packet_len)) {
|
||||
libssh2_error(session, LIBSSH2_ERROR_TIMEOUT, "Timed out waiting for KEX reply", 0);
|
||||
rc = libssh2_packet_require(session, packet_type_reply, &s_packet,
|
||||
&s_packet_len);
|
||||
if (rc) {
|
||||
libssh2_error(session, LIBSSH2_ERROR_TIMEOUT,
|
||||
"Timed out waiting for KEX reply", 0);
|
||||
ret = -1;
|
||||
goto clean_exit;
|
||||
}
|
||||
@@ -162,7 +162,7 @@ static int libssh2_kex_method_diffie_hellman_groupGP_sha1_key_exchange(LIBSSH2_S
|
||||
libssh2_md5_update(fingerprint_ctx, session->server_hostkey, session->server_hostkey_len);
|
||||
libssh2_md5_final(fingerprint_ctx, session->server_hostkey_md5);
|
||||
}
|
||||
#ifdef LIBSSH2_DEBUG_KEX
|
||||
#ifdef LIBSSH2DEBUG
|
||||
{
|
||||
char fingerprint[50], *fprint = fingerprint;
|
||||
int i;
|
||||
@@ -172,7 +172,7 @@ static int libssh2_kex_method_diffie_hellman_groupGP_sha1_key_exchange(LIBSSH2_S
|
||||
*(--fprint) = '\0';
|
||||
_libssh2_debug(session, LIBSSH2_DBG_KEX, "Server's MD5 Fingerprint: %s", fingerprint);
|
||||
}
|
||||
#endif /* LIBSSH2_DEBUG_KEX */
|
||||
#endif /* LIBSSH2DEBUG */
|
||||
#endif /* ! LIBSSH2_MD5 */
|
||||
|
||||
{
|
||||
@@ -182,7 +182,7 @@ static int libssh2_kex_method_diffie_hellman_groupGP_sha1_key_exchange(LIBSSH2_S
|
||||
libssh2_sha1_update (fingerprint_ctx, session->server_hostkey, session->server_hostkey_len);
|
||||
libssh2_sha1_final(fingerprint_ctx, session->server_hostkey_sha1);
|
||||
}
|
||||
#ifdef LIBSSH2_DEBUG_KEX
|
||||
#ifdef LIBSSH2DEBUG
|
||||
{
|
||||
char fingerprint[64], *fprint = fingerprint;
|
||||
int i;
|
||||
@@ -192,7 +192,7 @@ static int libssh2_kex_method_diffie_hellman_groupGP_sha1_key_exchange(LIBSSH2_S
|
||||
*(--fprint) = '\0';
|
||||
_libssh2_debug(session, LIBSSH2_DBG_KEX, "Server's SHA1 Fingerprint: %s", fingerprint);
|
||||
}
|
||||
#endif /* LIBSSH2_DEBUG_KEX */
|
||||
#endif /* LIBSSH2DEBUG */
|
||||
|
||||
if (session->hostkey->init(session, session->server_hostkey, session->server_hostkey_len, &session->server_hostkey_abstract)) {
|
||||
libssh2_error(session, LIBSSH2_ERROR_HOSTKEY_INIT, "Unable to initialize hostkey importer", 0);
|
||||
@@ -292,9 +292,7 @@ static int libssh2_kex_method_diffie_hellman_groupGP_sha1_key_exchange(LIBSSH2_S
|
||||
goto clean_exit;
|
||||
}
|
||||
|
||||
#ifdef LIBSSH2_DEBUG_KEX
|
||||
_libssh2_debug(session, LIBSSH2_DBG_KEX, "Sending NEWKEYS message");
|
||||
#endif
|
||||
c = SSH_MSG_NEWKEYS;
|
||||
if (libssh2_packet_write(session, &c, 1)) {
|
||||
libssh2_error(session, LIBSSH2_ERROR_SOCKET_SEND, "Unable to send NEWKEYS message", 0);
|
||||
@@ -309,9 +307,7 @@ static int libssh2_kex_method_diffie_hellman_groupGP_sha1_key_exchange(LIBSSH2_S
|
||||
}
|
||||
/* The first key exchange has been performed, switch to active crypt/comp/mac mode */
|
||||
session->state |= LIBSSH2_STATE_NEWKEYS;
|
||||
#ifdef LIBSSH2_DEBUG_KEX
|
||||
_libssh2_debug(session, LIBSSH2_DBG_KEX, "Received NEWKEYS message");
|
||||
#endif
|
||||
|
||||
/* This will actually end up being just packet_type(1) for this packet type anyway */
|
||||
LIBSSH2_FREE(session, tmp);
|
||||
@@ -324,9 +320,8 @@ static int libssh2_kex_method_diffie_hellman_groupGP_sha1_key_exchange(LIBSSH2_S
|
||||
}
|
||||
memcpy(session->session_id, h_sig_comp, SHA_DIGEST_LENGTH);
|
||||
session->session_id_len = SHA_DIGEST_LENGTH;
|
||||
#ifdef LIBSSH2_DEBUG_KEX
|
||||
_libssh2_debug(session, LIBSSH2_DBG_KEX, "session_id calculated");
|
||||
#endif
|
||||
_libssh2_debug(session, LIBSSH2_DBG_KEX,
|
||||
"session_id calculated");
|
||||
}
|
||||
|
||||
/* Cleanup any existing cipher */
|
||||
@@ -340,7 +335,16 @@ static int libssh2_kex_method_diffie_hellman_groupGP_sha1_key_exchange(LIBSSH2_S
|
||||
int free_iv = 0, free_secret = 0;
|
||||
|
||||
LIBSSH2_KEX_METHOD_DIFFIE_HELLMAN_SHA1_HASH(iv, session->local.crypt->iv_len, "A");
|
||||
if (!iv) {
|
||||
ret = -1;
|
||||
goto clean_exit;
|
||||
}
|
||||
LIBSSH2_KEX_METHOD_DIFFIE_HELLMAN_SHA1_HASH(secret, session->local.crypt->secret_len, "C");
|
||||
if (!secret) {
|
||||
LIBSSH2_FREE(session, iv);
|
||||
ret = -1;
|
||||
goto clean_exit;
|
||||
}
|
||||
if (session->local.crypt->init(session, session->local.crypt, iv, &free_iv, secret, &free_secret, 1, &session->local.crypt_abstract)) {
|
||||
LIBSSH2_FREE(session, iv);
|
||||
LIBSSH2_FREE(session, secret);
|
||||
@@ -358,9 +362,8 @@ static int libssh2_kex_method_diffie_hellman_groupGP_sha1_key_exchange(LIBSSH2_S
|
||||
LIBSSH2_FREE(session, secret);
|
||||
}
|
||||
}
|
||||
#ifdef LIBSSH2_DEBUG_KEX
|
||||
_libssh2_debug(session, LIBSSH2_DBG_KEX, "Client to Server IV and Key calculated");
|
||||
#endif
|
||||
_libssh2_debug(session, LIBSSH2_DBG_KEX,
|
||||
"Client to Server IV and Key calculated");
|
||||
|
||||
if (session->remote.crypt->dtor) {
|
||||
/* Cleanup any existing cipher */
|
||||
@@ -372,7 +375,16 @@ static int libssh2_kex_method_diffie_hellman_groupGP_sha1_key_exchange(LIBSSH2_S
|
||||
int free_iv = 0, free_secret = 0;
|
||||
|
||||
LIBSSH2_KEX_METHOD_DIFFIE_HELLMAN_SHA1_HASH(iv, session->remote.crypt->iv_len, "B");
|
||||
if (!iv) {
|
||||
ret = -1;
|
||||
goto clean_exit;
|
||||
}
|
||||
LIBSSH2_KEX_METHOD_DIFFIE_HELLMAN_SHA1_HASH(secret, session->remote.crypt->secret_len, "D");
|
||||
if (!secret) {
|
||||
LIBSSH2_FREE(session, iv);
|
||||
ret = -1;
|
||||
goto clean_exit;
|
||||
}
|
||||
if (session->remote.crypt->init(session, session->remote.crypt, iv, &free_iv, secret, &free_secret, 0, &session->remote.crypt_abstract)) {
|
||||
LIBSSH2_FREE(session, iv);
|
||||
LIBSSH2_FREE(session, secret);
|
||||
@@ -390,9 +402,7 @@ static int libssh2_kex_method_diffie_hellman_groupGP_sha1_key_exchange(LIBSSH2_S
|
||||
LIBSSH2_FREE(session, secret);
|
||||
}
|
||||
}
|
||||
#ifdef LIBSSH2_DEBUG_KEX
|
||||
_libssh2_debug(session, LIBSSH2_DBG_KEX, "Server to Client IV and Key calculated");
|
||||
#endif
|
||||
|
||||
if (session->local.mac->dtor) {
|
||||
session->local.mac->dtor(session, &session->local.mac_abstract);
|
||||
@@ -403,6 +413,10 @@ static int libssh2_kex_method_diffie_hellman_groupGP_sha1_key_exchange(LIBSSH2_S
|
||||
int free_key = 0;
|
||||
|
||||
LIBSSH2_KEX_METHOD_DIFFIE_HELLMAN_SHA1_HASH(key, session->local.mac->key_len, "E");
|
||||
if (!key) {
|
||||
ret = -1;
|
||||
goto clean_exit;
|
||||
}
|
||||
session->local.mac->init(session, key, &free_key, &session->local.mac_abstract);
|
||||
|
||||
if (free_key) {
|
||||
@@ -410,9 +424,7 @@ static int libssh2_kex_method_diffie_hellman_groupGP_sha1_key_exchange(LIBSSH2_S
|
||||
LIBSSH2_FREE(session, key);
|
||||
}
|
||||
}
|
||||
#ifdef LIBSSH2_DEBUG_KEX
|
||||
_libssh2_debug(session, LIBSSH2_DBG_KEX, "Client to Server HMAC Key calculated");
|
||||
#endif
|
||||
|
||||
if (session->remote.mac->dtor) {
|
||||
session->remote.mac->dtor(session, &session->remote.mac_abstract);
|
||||
@@ -423,6 +435,10 @@ static int libssh2_kex_method_diffie_hellman_groupGP_sha1_key_exchange(LIBSSH2_S
|
||||
int free_key = 0;
|
||||
|
||||
LIBSSH2_KEX_METHOD_DIFFIE_HELLMAN_SHA1_HASH(key, session->remote.mac->key_len, "F");
|
||||
if (!key) {
|
||||
ret = -1;
|
||||
goto clean_exit;
|
||||
}
|
||||
session->remote.mac->init(session, key, &free_key, &session->remote.mac_abstract);
|
||||
|
||||
if (free_key) {
|
||||
@@ -430,9 +446,7 @@ static int libssh2_kex_method_diffie_hellman_groupGP_sha1_key_exchange(LIBSSH2_S
|
||||
LIBSSH2_FREE(session, key);
|
||||
}
|
||||
}
|
||||
#ifdef LIBSSH2_DEBUG_KEX
|
||||
_libssh2_debug(session, LIBSSH2_DBG_KEX, "Server to Client HMAC Key calculated");
|
||||
#endif
|
||||
|
||||
clean_exit:
|
||||
_libssh2_bn_free(x);
|
||||
@@ -467,7 +481,7 @@ static int libssh2_kex_method_diffie_hellman_groupGP_sha1_key_exchange(LIBSSH2_S
|
||||
*/
|
||||
static int libssh2_kex_method_diffie_hellman_group1_sha1_key_exchange(LIBSSH2_SESSION *session)
|
||||
{
|
||||
unsigned char p_value[128] = {
|
||||
static const unsigned char p_value[128] = {
|
||||
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
|
||||
0xC9, 0x0F, 0xDA, 0xA2, 0x21, 0x68, 0xC2, 0x34,
|
||||
0xC4, 0xC6, 0x62, 0x8B, 0x80, 0xDC, 0x1C, 0xD1,
|
||||
@@ -493,9 +507,8 @@ static int libssh2_kex_method_diffie_hellman_group1_sha1_key_exchange(LIBSSH2_SE
|
||||
_libssh2_bn_set_word(g, 2);
|
||||
_libssh2_bn_from_bin(p, 128, p_value);
|
||||
|
||||
#ifdef LIBSSH2_DEBUG_KEX
|
||||
_libssh2_debug(session, LIBSSH2_DBG_KEX, "Initiating Diffie-Hellman Group1 Key Exchange");
|
||||
#endif
|
||||
|
||||
ret = libssh2_kex_method_diffie_hellman_groupGP_sha1_key_exchange(session, g, p, 128, SSH_MSG_KEXDH_INIT, SSH_MSG_KEXDH_REPLY, NULL, 0);
|
||||
|
||||
_libssh2_bn_free(p);
|
||||
@@ -510,7 +523,7 @@ static int libssh2_kex_method_diffie_hellman_group1_sha1_key_exchange(LIBSSH2_SE
|
||||
*/
|
||||
static int libssh2_kex_method_diffie_hellman_group14_sha1_key_exchange(LIBSSH2_SESSION *session)
|
||||
{
|
||||
unsigned char p_value[256] = {
|
||||
static const unsigned char p_value[256] = {
|
||||
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
|
||||
0xC9, 0x0F, 0xDA, 0xA2, 0x21, 0x68, 0xC2, 0x34,
|
||||
0xC4, 0xC6, 0x62, 0x8B, 0x80, 0xDC, 0x1C, 0xD1,
|
||||
@@ -552,9 +565,7 @@ static int libssh2_kex_method_diffie_hellman_group14_sha1_key_exchange(LIBSSH2_S
|
||||
_libssh2_bn_set_word(g, 2);
|
||||
_libssh2_bn_from_bin(p, 256, p_value);
|
||||
|
||||
#ifdef LIBSSH2_DEBUG_KEX
|
||||
_libssh2_debug(session, LIBSSH2_DBG_KEX, "Initiating Diffie-Hellman Group14 Key Exchange");
|
||||
#endif
|
||||
ret = libssh2_kex_method_diffie_hellman_groupGP_sha1_key_exchange(session, g, p, 256, SSH_MSG_KEXDH_INIT, SSH_MSG_KEXDH_REPLY, NULL, 0);
|
||||
|
||||
_libssh2_bn_free(p);
|
||||
@@ -583,16 +594,12 @@ static int libssh2_kex_method_diffie_hellman_group_exchange_sha1_key_exchange(LI
|
||||
libssh2_htonu32(request + 5, LIBSSH2_DH_GEX_OPTGROUP);
|
||||
libssh2_htonu32(request + 9, LIBSSH2_DH_GEX_MAXGROUP);
|
||||
request_len = 13;
|
||||
#ifdef LIBSSH2_DEBUG_KEX
|
||||
_libssh2_debug(session, LIBSSH2_DBG_KEX, "Initiating Diffie-Hellman Group-Exchange (New Method)");
|
||||
#endif
|
||||
#else
|
||||
request[0] = SSH_MSG_KEX_DH_GEX_REQUEST_OLD;
|
||||
libssh2_htonu32(request + 1, LIBSSH2_DH_GEX_OPTGROUP);
|
||||
request_len = 5;
|
||||
#ifdef LIBSSH2_DEBUG_KEX
|
||||
_libssh2_debug(session, LIBSSH2_DBG_KEX, "Initiating Diffie-Hellman Group-Exchange (Old Method)");
|
||||
#endif
|
||||
#endif
|
||||
|
||||
if (libssh2_packet_write(session, request, request_len)) {
|
||||
@@ -629,25 +636,25 @@ static int libssh2_kex_method_diffie_hellman_group_exchange_sha1_key_exchange(LI
|
||||
#define LIBSSH2_KEX_METHOD_FLAG_REQ_ENC_HOSTKEY 0x0001
|
||||
#define LIBSSH2_KEX_METHOD_FLAG_REQ_SIGN_HOSTKEY 0x0002
|
||||
|
||||
LIBSSH2_KEX_METHOD libssh2_kex_method_diffie_helman_group1_sha1 = {
|
||||
static const LIBSSH2_KEX_METHOD libssh2_kex_method_diffie_helman_group1_sha1 = {
|
||||
"diffie-hellman-group1-sha1",
|
||||
libssh2_kex_method_diffie_hellman_group1_sha1_key_exchange,
|
||||
LIBSSH2_KEX_METHOD_FLAG_REQ_SIGN_HOSTKEY,
|
||||
};
|
||||
|
||||
LIBSSH2_KEX_METHOD libssh2_kex_method_diffie_helman_group14_sha1 = {
|
||||
static const LIBSSH2_KEX_METHOD libssh2_kex_method_diffie_helman_group14_sha1 = {
|
||||
"diffie-hellman-group14-sha1",
|
||||
libssh2_kex_method_diffie_hellman_group14_sha1_key_exchange,
|
||||
LIBSSH2_KEX_METHOD_FLAG_REQ_SIGN_HOSTKEY,
|
||||
};
|
||||
|
||||
LIBSSH2_KEX_METHOD libssh2_kex_method_diffie_helman_group_exchange_sha1 = {
|
||||
static const LIBSSH2_KEX_METHOD libssh2_kex_method_diffie_helman_group_exchange_sha1 = {
|
||||
"diffie-hellman-group-exchange-sha1",
|
||||
libssh2_kex_method_diffie_hellman_group_exchange_sha1_key_exchange,
|
||||
LIBSSH2_KEX_METHOD_FLAG_REQ_SIGN_HOSTKEY,
|
||||
};
|
||||
|
||||
LIBSSH2_KEX_METHOD *libssh2_kex_methods[] = {
|
||||
static const LIBSSH2_KEX_METHOD *libssh2_kex_methods[] = {
|
||||
&libssh2_kex_method_diffie_helman_group14_sha1,
|
||||
&libssh2_kex_method_diffie_helman_group_exchange_sha1,
|
||||
&libssh2_kex_method_diffie_helman_group1_sha1,
|
||||
@@ -655,7 +662,7 @@ LIBSSH2_KEX_METHOD *libssh2_kex_methods[] = {
|
||||
};
|
||||
|
||||
typedef struct _LIBSSH2_COMMON_METHOD {
|
||||
char *name;
|
||||
const char *name;
|
||||
} LIBSSH2_COMMON_METHOD;
|
||||
|
||||
/* {{{ libssh2_kex_method_strlen
|
||||
@@ -781,10 +788,10 @@ static int libssh2_kexinit(LIBSSH2_SESSION *session)
|
||||
*(s++) = 0;
|
||||
*(s++) = 0;
|
||||
|
||||
#ifdef LIBSSH2_DEBUG_KEX
|
||||
#ifdef LIBSSH2DEBUG
|
||||
{
|
||||
/* Funnily enough, they'll all "appear" to be '\0' terminated */
|
||||
char *p = data + 21; /* type(1) + cookie(16) + len(4) */
|
||||
unsigned char *p = data + 21; /* type(1) + cookie(16) + len(4) */
|
||||
|
||||
_libssh2_debug(session, LIBSSH2_DBG_KEX, "Sent KEX: %s", p); p += kex_len + 4;
|
||||
_libssh2_debug(session, LIBSSH2_DBG_KEX, "Sent HOSTKEY: %s", p); p += hostkey_len + 4;
|
||||
@@ -797,7 +804,7 @@ static int libssh2_kexinit(LIBSSH2_SESSION *session)
|
||||
_libssh2_debug(session, LIBSSH2_DBG_KEX, "Sent LANG_CS: %s", p); p += lang_cs_len + 4;
|
||||
_libssh2_debug(session, LIBSSH2_DBG_KEX, "Sent LANG_SC: %s", p); p += lang_sc_len + 4;
|
||||
}
|
||||
#endif /* LIBSSH2_DEBUG_KEX */
|
||||
#endif /* LIBSSH2DEBUG */
|
||||
if (libssh2_packet_write(session, data, data_len)) {
|
||||
LIBSSH2_FREE(session, data);
|
||||
libssh2_error(session, LIBSSH2_ERROR_SOCKET_SEND, "Unable to send KEXINIT packet to remote host", 0);
|
||||
@@ -820,7 +827,7 @@ static int libssh2_kexinit(LIBSSH2_SESSION *session)
|
||||
* Needle must be preceed by BOL or ',', and followed by ',' or EOL
|
||||
*/
|
||||
static unsigned char *libssh2_kex_agree_instr(unsigned char *haystack, unsigned long haystack_len,
|
||||
unsigned char *needle, unsigned long needle_len)
|
||||
const unsigned char *needle, unsigned long needle_len)
|
||||
{
|
||||
unsigned char *s;
|
||||
|
||||
@@ -853,7 +860,7 @@ static unsigned char *libssh2_kex_agree_instr(unsigned char *haystack, unsigned
|
||||
|
||||
/* {{{ libssh2_get_method_by_name
|
||||
*/
|
||||
static LIBSSH2_COMMON_METHOD *libssh2_get_method_by_name(char *name, int name_len, LIBSSH2_COMMON_METHOD **methodlist)
|
||||
static const LIBSSH2_COMMON_METHOD *libssh2_get_method_by_name(const char *name, int name_len, const LIBSSH2_COMMON_METHOD **methodlist)
|
||||
{
|
||||
while (*methodlist) {
|
||||
if ((strlen((*methodlist)->name) == name_len) &&
|
||||
@@ -871,7 +878,7 @@ static LIBSSH2_COMMON_METHOD *libssh2_get_method_by_name(char *name, int name_le
|
||||
*/
|
||||
static int libssh2_kex_agree_hostkey(LIBSSH2_SESSION *session, unsigned long kex_flags, unsigned char *hostkey, unsigned long hostkey_len)
|
||||
{
|
||||
LIBSSH2_HOSTKEY_METHOD **hostkeyp = libssh2_hostkey_methods();
|
||||
const LIBSSH2_HOSTKEY_METHOD **hostkeyp = libssh2_hostkey_methods();
|
||||
unsigned char *s;
|
||||
|
||||
if (session->hostkey_prefs) {
|
||||
@@ -881,7 +888,7 @@ static int libssh2_kex_agree_hostkey(LIBSSH2_SESSION *session, unsigned long kex
|
||||
unsigned char *p = strchr(s, ',');
|
||||
int method_len = (p ? (p - s) : strlen(s));
|
||||
if (libssh2_kex_agree_instr(hostkey, hostkey_len, s, method_len)) {
|
||||
LIBSSH2_HOSTKEY_METHOD *method = (LIBSSH2_HOSTKEY_METHOD*)libssh2_get_method_by_name(s, method_len, (LIBSSH2_COMMON_METHOD**)hostkeyp);
|
||||
const LIBSSH2_HOSTKEY_METHOD *method = (const LIBSSH2_HOSTKEY_METHOD*)libssh2_get_method_by_name(s, method_len, (const LIBSSH2_COMMON_METHOD**)hostkeyp);
|
||||
|
||||
if (!method) {
|
||||
/* Invalid method -- Should never be reached */
|
||||
@@ -907,7 +914,9 @@ static int libssh2_kex_agree_hostkey(LIBSSH2_SESSION *session, unsigned long kex
|
||||
}
|
||||
|
||||
while (hostkeyp && (*hostkeyp)->name) {
|
||||
s = libssh2_kex_agree_instr(hostkey, hostkey_len, (*hostkeyp)->name, strlen((*hostkeyp)->name));
|
||||
s = libssh2_kex_agree_instr(hostkey, hostkey_len,
|
||||
(unsigned char *)(*hostkeyp)->name,
|
||||
strlen((*hostkeyp)->name));
|
||||
if (s) {
|
||||
/* So far so good, but does it suit our purposes? (Encrypting vs Signing) */
|
||||
if (((kex_flags & LIBSSH2_KEX_METHOD_FLAG_REQ_ENC_HOSTKEY) == 0) ||
|
||||
@@ -934,7 +943,7 @@ static int libssh2_kex_agree_hostkey(LIBSSH2_SESSION *session, unsigned long kex
|
||||
static int libssh2_kex_agree_kex_hostkey(LIBSSH2_SESSION *session, unsigned char *kex, unsigned long kex_len,
|
||||
unsigned char *hostkey, unsigned long hostkey_len)
|
||||
{
|
||||
LIBSSH2_KEX_METHOD **kexp = libssh2_kex_methods;
|
||||
const LIBSSH2_KEX_METHOD **kexp = libssh2_kex_methods;
|
||||
unsigned char *s;
|
||||
|
||||
if (session->kex_prefs) {
|
||||
@@ -944,7 +953,7 @@ static int libssh2_kex_agree_kex_hostkey(LIBSSH2_SESSION *session, unsigned char
|
||||
unsigned char *q, *p = strchr(s, ',');
|
||||
int method_len = (p ? (p - s) : strlen(s));
|
||||
if ((q = libssh2_kex_agree_instr(kex, kex_len, s, method_len))) {
|
||||
LIBSSH2_KEX_METHOD *method = (LIBSSH2_KEX_METHOD*)libssh2_get_method_by_name(s, method_len, (LIBSSH2_COMMON_METHOD**)kexp);
|
||||
const LIBSSH2_KEX_METHOD *method = (const LIBSSH2_KEX_METHOD*)libssh2_get_method_by_name(s, method_len, (const LIBSSH2_COMMON_METHOD**)kexp);
|
||||
|
||||
if (!method) {
|
||||
/* Invalid method -- Should never be reached */
|
||||
@@ -972,7 +981,9 @@ static int libssh2_kex_agree_kex_hostkey(LIBSSH2_SESSION *session, unsigned char
|
||||
}
|
||||
|
||||
while (*kexp && (*kexp)->name) {
|
||||
s = libssh2_kex_agree_instr(kex, kex_len, (*kexp)->name, strlen((*kexp)->name));
|
||||
s = libssh2_kex_agree_instr(kex, kex_len,
|
||||
(unsigned char *)(*kexp)->name,
|
||||
strlen((*kexp)->name));
|
||||
if (s) {
|
||||
/* We've agreed on a key exchange method,
|
||||
* Can we agree on a hostkey that works with this kex?
|
||||
@@ -1002,8 +1013,9 @@ static int libssh2_kex_agree_crypt(LIBSSH2_SESSION *session,
|
||||
unsigned char *crypt,
|
||||
unsigned long crypt_len)
|
||||
{
|
||||
LIBSSH2_CRYPT_METHOD **cryptp = libssh2_crypt_methods();
|
||||
const LIBSSH2_CRYPT_METHOD **cryptp = libssh2_crypt_methods();
|
||||
unsigned char *s;
|
||||
(void)session;
|
||||
|
||||
if (endpoint->crypt_prefs) {
|
||||
s = endpoint->crypt_prefs;
|
||||
@@ -1013,8 +1025,8 @@ static int libssh2_kex_agree_crypt(LIBSSH2_SESSION *session,
|
||||
int method_len = (p ? (p - s) : strlen(s));
|
||||
|
||||
if (libssh2_kex_agree_instr(crypt, crypt_len, s, method_len)) {
|
||||
LIBSSH2_CRYPT_METHOD *method =
|
||||
(LIBSSH2_CRYPT_METHOD*)libssh2_get_method_by_name(s, method_len, (LIBSSH2_COMMON_METHOD**)cryptp);
|
||||
const LIBSSH2_CRYPT_METHOD *method =
|
||||
(const LIBSSH2_CRYPT_METHOD*)libssh2_get_method_by_name((char *)s, method_len, (const LIBSSH2_COMMON_METHOD**)cryptp);
|
||||
|
||||
if (!method) {
|
||||
/* Invalid method -- Should never be reached */
|
||||
@@ -1031,7 +1043,9 @@ static int libssh2_kex_agree_crypt(LIBSSH2_SESSION *session,
|
||||
}
|
||||
|
||||
while (*cryptp && (*cryptp)->name) {
|
||||
s = libssh2_kex_agree_instr(crypt, crypt_len, (*cryptp)->name, strlen((*cryptp)->name));
|
||||
s = libssh2_kex_agree_instr(crypt, crypt_len,
|
||||
(unsigned char *)(*cryptp)->name,
|
||||
strlen((*cryptp)->name));
|
||||
if (s) {
|
||||
endpoint->crypt = *cryptp;
|
||||
return 0;
|
||||
@@ -1048,8 +1062,9 @@ static int libssh2_kex_agree_crypt(LIBSSH2_SESSION *session,
|
||||
*/
|
||||
static int libssh2_kex_agree_mac(LIBSSH2_SESSION *session, libssh2_endpoint_data *endpoint, unsigned char *mac, unsigned long mac_len)
|
||||
{
|
||||
LIBSSH2_MAC_METHOD **macp = libssh2_mac_methods();
|
||||
const LIBSSH2_MAC_METHOD **macp = libssh2_mac_methods();
|
||||
unsigned char *s;
|
||||
(void)session;
|
||||
|
||||
if (endpoint->mac_prefs) {
|
||||
s = endpoint->mac_prefs;
|
||||
@@ -1059,7 +1074,7 @@ static int libssh2_kex_agree_mac(LIBSSH2_SESSION *session, libssh2_endpoint_data
|
||||
int method_len = (p ? (p - s) : strlen(s));
|
||||
|
||||
if (libssh2_kex_agree_instr(mac, mac_len, s, method_len)) {
|
||||
LIBSSH2_MAC_METHOD *method = (LIBSSH2_MAC_METHOD*)libssh2_get_method_by_name(s, method_len, (LIBSSH2_COMMON_METHOD**)macp);
|
||||
const LIBSSH2_MAC_METHOD *method = (const LIBSSH2_MAC_METHOD*)libssh2_get_method_by_name(s, method_len, (const LIBSSH2_COMMON_METHOD**)macp);
|
||||
|
||||
if (!method) {
|
||||
/* Invalid method -- Should never be reached */
|
||||
@@ -1076,7 +1091,9 @@ static int libssh2_kex_agree_mac(LIBSSH2_SESSION *session, libssh2_endpoint_data
|
||||
}
|
||||
|
||||
while (*macp && (*macp)->name) {
|
||||
s = libssh2_kex_agree_instr(mac, mac_len, (*macp)->name, strlen((*macp)->name));
|
||||
s = libssh2_kex_agree_instr(mac, mac_len,
|
||||
(unsigned char *)(*macp)->name,
|
||||
strlen((*macp)->name));
|
||||
if (s) {
|
||||
endpoint->mac = *macp;
|
||||
return 0;
|
||||
@@ -1093,8 +1110,9 @@ static int libssh2_kex_agree_mac(LIBSSH2_SESSION *session, libssh2_endpoint_data
|
||||
*/
|
||||
static int libssh2_kex_agree_comp(LIBSSH2_SESSION *session, libssh2_endpoint_data *endpoint, unsigned char *comp, unsigned long comp_len)
|
||||
{
|
||||
LIBSSH2_COMP_METHOD **compp = libssh2_comp_methods();
|
||||
const LIBSSH2_COMP_METHOD **compp = libssh2_comp_methods();
|
||||
unsigned char *s;
|
||||
(void)session;
|
||||
|
||||
if (endpoint->comp_prefs) {
|
||||
s = endpoint->comp_prefs;
|
||||
@@ -1104,7 +1122,7 @@ static int libssh2_kex_agree_comp(LIBSSH2_SESSION *session, libssh2_endpoint_dat
|
||||
int method_len = (p ? (p - s) : strlen(s));
|
||||
|
||||
if (libssh2_kex_agree_instr(comp, comp_len, s, method_len)) {
|
||||
LIBSSH2_COMP_METHOD *method = (LIBSSH2_COMP_METHOD*)libssh2_get_method_by_name(s, method_len, (LIBSSH2_COMMON_METHOD**)compp);
|
||||
const LIBSSH2_COMP_METHOD *method = (const LIBSSH2_COMP_METHOD*)libssh2_get_method_by_name(s, method_len, (const LIBSSH2_COMMON_METHOD**)compp);
|
||||
|
||||
if (!method) {
|
||||
/* Invalid method -- Should never be reached */
|
||||
@@ -1121,7 +1139,9 @@ static int libssh2_kex_agree_comp(LIBSSH2_SESSION *session, libssh2_endpoint_dat
|
||||
}
|
||||
|
||||
while (*compp && (*compp)->name) {
|
||||
s = libssh2_kex_agree_instr(comp, comp_len, (*compp)->name, strlen((*compp)->name));
|
||||
s = libssh2_kex_agree_instr(comp, comp_len,
|
||||
(unsigned char *)(*compp)->name,
|
||||
strlen((*compp)->name));
|
||||
if (s) {
|
||||
endpoint->comp = *compp;
|
||||
return 0;
|
||||
@@ -1170,6 +1190,9 @@ static int libssh2_kex_agree_methods(LIBSSH2_SESSION *session, unsigned char *da
|
||||
session->burn_optimistic_kexinit = *(s++);
|
||||
/* Next uint32 in packet is all zeros (reserved) */
|
||||
|
||||
if (data_len < (unsigned)(s - data))
|
||||
return -1; /* short packet */
|
||||
|
||||
if (libssh2_kex_agree_kex_hostkey(session, kex, kex_len, hostkey, hostkey_len)) {
|
||||
return -1;
|
||||
}
|
||||
@@ -1194,7 +1217,6 @@ static int libssh2_kex_agree_methods(LIBSSH2_SESSION *session, unsigned char *da
|
||||
return -1;
|
||||
}
|
||||
|
||||
#ifdef LIBSSH2_DEBUG_KEX
|
||||
_libssh2_debug(session, LIBSSH2_DBG_KEX, "Agreed on KEX method: %s", session->kex->name);
|
||||
_libssh2_debug(session, LIBSSH2_DBG_KEX, "Agreed on HOSTKEY method: %s", session->hostkey->name);
|
||||
_libssh2_debug(session, LIBSSH2_DBG_KEX, "Agreed on CRYPT_CS method: %s", session->local.crypt->name);
|
||||
@@ -1205,7 +1227,6 @@ static int libssh2_kex_agree_methods(LIBSSH2_SESSION *session, unsigned char *da
|
||||
_libssh2_debug(session, LIBSSH2_DBG_KEX, "Agreed on COMP_SC method: %s", session->remote.comp->name);
|
||||
_libssh2_debug(session, LIBSSH2_DBG_KEX, "Agreed on LANG_CS method:"); /* None yet */
|
||||
_libssh2_debug(session, LIBSSH2_DBG_KEX, "Agreed on LANG_SC method:"); /* None yet */
|
||||
#endif
|
||||
|
||||
/* Initialize compression layer */
|
||||
if (session->local.comp && session->local.comp->init &&
|
||||
@@ -1230,6 +1251,7 @@ int libssh2_kex_exchange(LIBSSH2_SESSION *session, int reexchange) /* session->f
|
||||
{
|
||||
unsigned char *data;
|
||||
unsigned long data_len;
|
||||
int rc = 0;
|
||||
|
||||
/* Prevent loop in packet_add() */
|
||||
session->state |= LIBSSH2_STATE_EXCHANGING_KEYS;
|
||||
@@ -1261,7 +1283,7 @@ int libssh2_kex_exchange(LIBSSH2_SESSION *session, int reexchange) /* session->f
|
||||
}
|
||||
session->local.kexinit = oldlocal;
|
||||
session->local.kexinit_len = oldlocal_len;
|
||||
return -1;
|
||||
return -2;
|
||||
}
|
||||
|
||||
if (session->remote.kexinit) {
|
||||
@@ -1271,13 +1293,15 @@ int libssh2_kex_exchange(LIBSSH2_SESSION *session, int reexchange) /* session->f
|
||||
session->remote.kexinit_len = data_len;
|
||||
|
||||
if (libssh2_kex_agree_methods(session, data, data_len)) {
|
||||
return -1;
|
||||
rc = -3;
|
||||
}
|
||||
}
|
||||
|
||||
if (rc == 0) {
|
||||
if (session->kex->exchange_keys(session)) {
|
||||
libssh2_error(session, LIBSSH2_ERROR_KEY_EXCHANGE_FAILURE, "Unrecoverable error exchanging keys", 0);
|
||||
return -1;
|
||||
rc = -4;
|
||||
}
|
||||
}
|
||||
|
||||
/* Done with kexinit buffers */
|
||||
@@ -1292,7 +1316,7 @@ int libssh2_kex_exchange(LIBSSH2_SESSION *session, int reexchange) /* session->f
|
||||
|
||||
session->state &= ~LIBSSH2_STATE_EXCHANGING_KEYS;
|
||||
|
||||
return 0;
|
||||
return rc;
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
@@ -1303,40 +1327,40 @@ LIBSSH2_API int libssh2_session_method_pref(LIBSSH2_SESSION *session, int method
|
||||
{
|
||||
char **prefvar, *s, *newprefs;
|
||||
int prefs_len = strlen(prefs);
|
||||
LIBSSH2_COMMON_METHOD **mlist;
|
||||
const LIBSSH2_COMMON_METHOD **mlist;
|
||||
|
||||
switch (method_type) {
|
||||
case LIBSSH2_METHOD_KEX:
|
||||
prefvar = &session->kex_prefs;
|
||||
mlist = (LIBSSH2_COMMON_METHOD**)libssh2_kex_methods;
|
||||
mlist = (const LIBSSH2_COMMON_METHOD**)libssh2_kex_methods;
|
||||
break;
|
||||
case LIBSSH2_METHOD_HOSTKEY:
|
||||
prefvar = &session->hostkey_prefs;
|
||||
mlist = (LIBSSH2_COMMON_METHOD**)libssh2_hostkey_methods();
|
||||
mlist = (const LIBSSH2_COMMON_METHOD**)libssh2_hostkey_methods();
|
||||
break;
|
||||
case LIBSSH2_METHOD_CRYPT_CS:
|
||||
prefvar = &session->local.crypt_prefs;
|
||||
mlist = (LIBSSH2_COMMON_METHOD**)libssh2_crypt_methods();
|
||||
mlist = (const LIBSSH2_COMMON_METHOD**)libssh2_crypt_methods();
|
||||
break;
|
||||
case LIBSSH2_METHOD_CRYPT_SC:
|
||||
prefvar = &session->remote.crypt_prefs;
|
||||
mlist = (LIBSSH2_COMMON_METHOD**)libssh2_crypt_methods();
|
||||
mlist = (const LIBSSH2_COMMON_METHOD**)libssh2_crypt_methods();
|
||||
break;
|
||||
case LIBSSH2_METHOD_MAC_CS:
|
||||
prefvar = &session->local.mac_prefs;
|
||||
mlist = (LIBSSH2_COMMON_METHOD**)libssh2_mac_methods();
|
||||
mlist = (const LIBSSH2_COMMON_METHOD**)libssh2_mac_methods();
|
||||
break;
|
||||
case LIBSSH2_METHOD_MAC_SC:
|
||||
prefvar = &session->remote.mac_prefs;
|
||||
mlist = (LIBSSH2_COMMON_METHOD**)libssh2_mac_methods();
|
||||
mlist = (const LIBSSH2_COMMON_METHOD**)libssh2_mac_methods();
|
||||
break;
|
||||
case LIBSSH2_METHOD_COMP_CS:
|
||||
prefvar = &session->local.comp_prefs;
|
||||
mlist = (LIBSSH2_COMMON_METHOD**)libssh2_comp_methods();
|
||||
mlist = (const LIBSSH2_COMMON_METHOD**)libssh2_comp_methods();
|
||||
break;
|
||||
case LIBSSH2_METHOD_COMP_SC:
|
||||
prefvar = &session->remote.comp_prefs;
|
||||
mlist = (LIBSSH2_COMMON_METHOD**)libssh2_comp_methods();
|
||||
mlist = (const LIBSSH2_COMMON_METHOD**)libssh2_comp_methods();
|
||||
break;
|
||||
case LIBSSH2_METHOD_LANG_CS:
|
||||
prefvar = &session->local.lang_prefs;
|
||||
@@ -1360,7 +1384,7 @@ LIBSSH2_API int libssh2_session_method_pref(LIBSSH2_SESSION *session, int method
|
||||
|
||||
while (s && *s) {
|
||||
char *p = strchr(s, ',');
|
||||
int method_len = p ? (p - s) : strlen(s);
|
||||
int method_len = p ? (p - s) : (int) strlen(s);
|
||||
|
||||
if (!libssh2_get_method_by_name(s, method_len, mlist)) {
|
||||
/* Strip out unsupported method */
|
||||
|
@@ -40,13 +40,40 @@
|
||||
|
||||
#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>
|
||||
|
||||
#ifndef WIN32
|
||||
#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"
|
||||
@@ -54,6 +81,15 @@
|
||||
#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)
|
||||
@@ -156,14 +192,14 @@ typedef struct _libssh2_endpoint_data {
|
||||
unsigned char *kexinit;
|
||||
unsigned long kexinit_len;
|
||||
|
||||
LIBSSH2_CRYPT_METHOD *crypt;
|
||||
const LIBSSH2_CRYPT_METHOD *crypt;
|
||||
void *crypt_abstract;
|
||||
|
||||
LIBSSH2_MAC_METHOD *mac;
|
||||
const LIBSSH2_MAC_METHOD *mac;
|
||||
unsigned long seqno;
|
||||
void *mac_abstract;
|
||||
|
||||
LIBSSH2_COMP_METHOD *comp;
|
||||
const LIBSSH2_COMP_METHOD *comp;
|
||||
void *comp_abstract;
|
||||
|
||||
/* Method Preferences -- NULL yields "load order" */
|
||||
@@ -173,6 +209,43 @@ typedef struct _libssh2_endpoint_data {
|
||||
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;
|
||||
@@ -195,14 +268,14 @@ struct _LIBSSH2_SESSION {
|
||||
int flags;
|
||||
|
||||
/* Agreed Key Exchange Method */
|
||||
LIBSSH2_KEX_METHOD *kex;
|
||||
const LIBSSH2_KEX_METHOD *kex;
|
||||
int burn_optimistic_kexinit:1;
|
||||
|
||||
unsigned char *session_id;
|
||||
unsigned long session_id_len;
|
||||
|
||||
/* Server's public key */
|
||||
LIBSSH2_HOSTKEY_METHOD *hostkey;
|
||||
const LIBSSH2_HOSTKEY_METHOD *hostkey;
|
||||
void *server_hostkey_abstract;
|
||||
|
||||
/* Either set with libssh2_session_hostkey() (for server mode)
|
||||
@@ -240,6 +313,12 @@ struct _LIBSSH2_SESSION {
|
||||
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 */
|
||||
@@ -272,7 +351,7 @@ struct _LIBSSH2_HOSTKEY_METHOD {
|
||||
const char *name;
|
||||
unsigned long hash_len;
|
||||
|
||||
int (*init)(LIBSSH2_SESSION *session, unsigned char *hostkey_data, unsigned long hostkey_data_len, void **abstract);
|
||||
int (*init)(LIBSSH2_SESSION *session, const unsigned char *hostkey_data, unsigned long hostkey_data_len, void **abstract);
|
||||
int (*initPEM)(LIBSSH2_SESSION *session, const char *privkeyfile, unsigned const char *passphrase, void **abstract);
|
||||
int (*sig_verify)(LIBSSH2_SESSION *session, const unsigned char *sig, unsigned long sig_len, const unsigned char *m, unsigned long m_len, void **abstract);
|
||||
int (*signv)(LIBSSH2_SESSION *session, unsigned char **signature, unsigned long *signature_len, unsigned long veccount, const struct iovec datavec[], void **abstract);
|
||||
@@ -291,7 +370,7 @@ struct _LIBSSH2_CRYPT_METHOD {
|
||||
|
||||
long flags;
|
||||
|
||||
int (*init)(LIBSSH2_SESSION *session, LIBSSH2_CRYPT_METHOD *method, unsigned char *iv, int *free_iv, unsigned char *secret, int *free_secret, int encrypt, void **abstract);
|
||||
int (*init)(LIBSSH2_SESSION *session, const LIBSSH2_CRYPT_METHOD *method, unsigned char *iv, int *free_iv, unsigned char *secret, int *free_secret, int encrypt, void **abstract);
|
||||
int (*crypt)(LIBSSH2_SESSION *session, unsigned char *block, void **abstract);
|
||||
int (*dtor)(LIBSSH2_SESSION *session, void **abstract);
|
||||
|
||||
@@ -322,10 +401,6 @@ struct _LIBSSH2_MAC_METHOD {
|
||||
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
|
||||
@@ -334,32 +409,43 @@ struct _LIBSSH2_MAC_METHOD {
|
||||
#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
|
||||
|
||||
#endif /* LIBSSH2_DEBUG_ENABLED */
|
||||
|
||||
#ifdef LIBSSH2_DEBUG_ERRORS
|
||||
#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 = errmsg; \
|
||||
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 /* ! LIBSSH2_DEBUG_ERRORS */
|
||||
#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 = errmsg; \
|
||||
session->err_msg = (char *)errmsg; \
|
||||
session->err_msglen = strlen(errmsg); \
|
||||
session->err_should_free = should_free; \
|
||||
session->err_code = errcode; \
|
||||
@@ -440,30 +526,66 @@ 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);
|
||||
#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, unsigned char *packet_types, unsigned char **data, unsigned long *data_len, unsigned long match_ofs, const unsigned char *match_buf, unsigned long match_len, int poll_socket);
|
||||
int libssh2_packet_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, 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 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 */
|
||||
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);
|
||||
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
|
||||
|
16
src/mac.c
16
src/mac.c
@@ -113,7 +113,7 @@ static int libssh2_mac_method_hmac_sha1_hash(LIBSSH2_SESSION *session, unsigned
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
static LIBSSH2_MAC_METHOD libssh2_mac_method_hmac_sha1 = {
|
||||
static const LIBSSH2_MAC_METHOD libssh2_mac_method_hmac_sha1 = {
|
||||
"hmac-sha1",
|
||||
20,
|
||||
20,
|
||||
@@ -138,7 +138,7 @@ static int libssh2_mac_method_hmac_sha1_96_hash(LIBSSH2_SESSION *session, unsign
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
static LIBSSH2_MAC_METHOD libssh2_mac_method_hmac_sha1_96 = {
|
||||
static const LIBSSH2_MAC_METHOD libssh2_mac_method_hmac_sha1_96 = {
|
||||
"hmac-sha1-96",
|
||||
12,
|
||||
20,
|
||||
@@ -173,7 +173,7 @@ static int libssh2_mac_method_hmac_md5_hash(LIBSSH2_SESSION *session, unsigned c
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
static LIBSSH2_MAC_METHOD libssh2_mac_method_hmac_md5 = {
|
||||
static const LIBSSH2_MAC_METHOD libssh2_mac_method_hmac_md5 = {
|
||||
"hmac-md5",
|
||||
16,
|
||||
16,
|
||||
@@ -198,7 +198,7 @@ static int libssh2_mac_method_hmac_md5_96_hash(LIBSSH2_SESSION *session, unsigne
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
static LIBSSH2_MAC_METHOD libssh2_mac_method_hmac_md5_96 = {
|
||||
static const LIBSSH2_MAC_METHOD libssh2_mac_method_hmac_md5_96 = {
|
||||
"hmac-md5-96",
|
||||
12,
|
||||
16,
|
||||
@@ -234,7 +234,7 @@ static int libssh2_mac_method_hmac_ripemd160_hash(LIBSSH2_SESSION *session, unsi
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
static LIBSSH2_MAC_METHOD libssh2_mac_method_hmac_ripemd160 = {
|
||||
static const LIBSSH2_MAC_METHOD libssh2_mac_method_hmac_ripemd160 = {
|
||||
"hmac-ripemd160",
|
||||
20,
|
||||
20,
|
||||
@@ -243,7 +243,7 @@ static LIBSSH2_MAC_METHOD libssh2_mac_method_hmac_ripemd160 = {
|
||||
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",
|
||||
20,
|
||||
20,
|
||||
@@ -253,7 +253,7 @@ static LIBSSH2_MAC_METHOD libssh2_mac_method_hmac_ripemd160_openssh_com = {
|
||||
};
|
||||
#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_96,
|
||||
&libssh2_mac_method_hmac_md5,
|
||||
@@ -268,7 +268,7 @@ static LIBSSH2_MAC_METHOD *_libssh2_mac_methods[] = {
|
||||
NULL
|
||||
};
|
||||
|
||||
LIBSSH2_MAC_METHOD **libssh2_mac_methods(void) {
|
||||
const LIBSSH2_MAC_METHOD **libssh2_mac_methods(void) {
|
||||
return _libssh2_mac_methods;
|
||||
}
|
||||
|
||||
|
41
src/misc.c
41
src/misc.c
@@ -1,4 +1,4 @@
|
||||
/* Copyright (c) 2004-2006, Sara Golemon <sarag@libssh2.org>
|
||||
/* Copyright (c) 2004-2007, Sara Golemon <sarag@libssh2.org>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms,
|
||||
@@ -36,6 +36,9 @@
|
||||
*/
|
||||
|
||||
#include "libssh2_priv.h"
|
||||
#ifdef HAVE_UNISTD_H
|
||||
#include <unistd.h>
|
||||
#endif
|
||||
|
||||
/* {{{ libssh2_ntohu32
|
||||
*/
|
||||
@@ -127,7 +130,7 @@ static const short libssh2_base64_reverse_table[256] = {
|
||||
* Decode a base64 chunk and store it into a newly alloc'd buffer
|
||||
*/
|
||||
LIBSSH2_API int libssh2_base64_decode(LIBSSH2_SESSION *session, char **data, unsigned int *datalen,
|
||||
char *src, unsigned int src_len)
|
||||
const char *src, unsigned int src_len)
|
||||
{
|
||||
unsigned char *s, *d;
|
||||
short v;
|
||||
@@ -170,19 +173,23 @@ LIBSSH2_API int libssh2_base64_decode(LIBSSH2_SESSION *session, char **data, uns
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
#ifdef LIBSSH2_DEBUG_ENABLED
|
||||
/* {{{ _libssh2_debug
|
||||
* Internal debug logging facility
|
||||
* Just writes to stderr until a good reason comes up to support anything else
|
||||
*/
|
||||
void _libssh2_debug(LIBSSH2_SESSION *session, int context, const char *format, ...)
|
||||
#ifdef LIBSSH2DEBUG
|
||||
LIBSSH2_API int libssh2_trace(LIBSSH2_SESSION *session, int bitmask)
|
||||
{
|
||||
session->showmask = bitmask;
|
||||
return 0;
|
||||
}
|
||||
|
||||
void _libssh2_debug(LIBSSH2_SESSION *session, int context,
|
||||
const char *format, ...)
|
||||
{
|
||||
char buffer[1536];
|
||||
int len;
|
||||
va_list vargs;
|
||||
char *contexts[9] = { "Unknown",
|
||||
static const char * const contexts[9] = {
|
||||
"Unknown",
|
||||
"Transport",
|
||||
"Key Exhange",
|
||||
"Key Exchange",
|
||||
"Userauth",
|
||||
"Connection",
|
||||
"scp",
|
||||
@@ -194,6 +201,10 @@ void _libssh2_debug(LIBSSH2_SESSION *session, int context, const char *format, .
|
||||
if (context < 1 || context > 8) {
|
||||
context = 0;
|
||||
}
|
||||
if(!(session->showmask & (1<<context))) {
|
||||
/* no such output asked for */
|
||||
return;
|
||||
}
|
||||
|
||||
len = snprintf(buffer, 1535, "[libssh2] %s: ", contexts[context]);
|
||||
|
||||
@@ -202,6 +213,14 @@ void _libssh2_debug(LIBSSH2_SESSION *session, int context, const char *format, .
|
||||
buffer[len] = '\n';
|
||||
va_end(vargs);
|
||||
write(2, buffer, len + 1);
|
||||
|
||||
}
|
||||
|
||||
#else
|
||||
LIBSSH2_API int libssh2_trace(LIBSSH2_SESSION *session, int bitmask)
|
||||
{
|
||||
(void)session;
|
||||
(void)bitmask;
|
||||
return 0;
|
||||
}
|
||||
/* }}} */
|
||||
#endif
|
||||
|
@@ -39,6 +39,10 @@
|
||||
#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,
|
||||
@@ -65,8 +69,7 @@ int _libssh2_rsa_new(libssh2_rsa_ctx **rsa,
|
||||
(*rsa)->n = BN_new();
|
||||
BN_bin2bn(ndata, nlen, (*rsa)->n);
|
||||
|
||||
if (ddata)
|
||||
{
|
||||
if (ddata) {
|
||||
(*rsa)->d = BN_new();
|
||||
BN_bin2bn(ddata, dlen, (*rsa)->d);
|
||||
|
||||
@@ -153,6 +156,8 @@ int _libssh2_dsa_sha1_verify(libssh2_dsa_ctx *dsactx,
|
||||
|
||||
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;
|
||||
}
|
||||
|
755
src/packet.c
755
src/packet.c
File diff suppressed because it is too large
Load Diff
@@ -1,4 +1,4 @@
|
||||
/* Copyright (c) 2004-2006, Sara Golemon <sarag@libssh2.org>
|
||||
/* Copyright (c) 2004-2007, Sara Golemon <sarag@libssh2.org>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms,
|
||||
@@ -52,11 +52,11 @@ struct _LIBSSH2_PUBLICKEY {
|
||||
|
||||
typedef struct _LIBSSH2_PUBLICKEY_CODE_LIST {
|
||||
int code;
|
||||
char *name;
|
||||
const char *name;
|
||||
int name_len;
|
||||
} 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_VERSION, "version", sizeof("version") - 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
|
||||
|
||||
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_ACCESS_DENIED, "access denied", sizeof("access denied") - 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_MID "\" Server Resports: \""
|
||||
#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;
|
||||
char *m, *s;
|
||||
int m_len;
|
||||
@@ -147,7 +147,7 @@ static int libssh2_publickey_packet_receive(LIBSSH2_PUBLICKEY *pkey, unsigned ch
|
||||
unsigned long packet_len;
|
||||
unsigned char *packet;
|
||||
|
||||
if (libssh2_channel_read(channel, (char *)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);
|
||||
return -1;
|
||||
}
|
||||
@@ -159,7 +159,7 @@ static int libssh2_publickey_packet_receive(LIBSSH2_PUBLICKEY *pkey, unsigned ch
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (libssh2_channel_read(channel, (char *)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_FREE(session, packet);
|
||||
return -1;
|
||||
@@ -180,7 +180,7 @@ static int libssh2_publickey_response_id(unsigned char **pdata, int data_len)
|
||||
{
|
||||
unsigned long response_len;
|
||||
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) {
|
||||
/* Malformed response */
|
||||
@@ -289,9 +289,7 @@ LIBSSH2_API LIBSSH2_PUBLICKEY *libssh2_publickey_init(LIBSSH2_SESSION *session)
|
||||
unsigned long data_len;
|
||||
int response;
|
||||
|
||||
#ifdef LIBSSH2_DEBUG_PUBLICKEY
|
||||
_libssh2_debug(session, LIBSSH2_DBG_PUBLICKEY, "Initializing publickey subsystem");
|
||||
#endif
|
||||
|
||||
channel = libssh2_channel_open_session(session);
|
||||
if (!channel) {
|
||||
@@ -320,9 +318,7 @@ LIBSSH2_API LIBSSH2_PUBLICKEY *libssh2_publickey_init(LIBSSH2_SESSION *session)
|
||||
memcpy(s, "version", sizeof("version") - 1); s += sizeof("version") - 1;
|
||||
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);
|
||||
#endif
|
||||
if ((s - buffer) != libssh2_channel_write(channel, (char*)buffer, (s - buffer))) {
|
||||
libssh2_error(session, LIBSSH2_ERROR_SOCKET_SEND, "Unable to send publickey version packet", 0);
|
||||
goto err_exit;
|
||||
@@ -365,14 +361,10 @@ LIBSSH2_API LIBSSH2_PUBLICKEY *libssh2_publickey_init(LIBSSH2_SESSION *session)
|
||||
/* What we want */
|
||||
pkey->version = libssh2_ntohu32(s);
|
||||
if (pkey->version > LIBSSH2_PUBLICKEY_VERSION) {
|
||||
#ifdef LIBSSH2_DEBUG_PUBLICKEY
|
||||
_libssh2_debug(session, LIBSSH2_DBG_PUBLICKEY, "Truncating remote publickey version from %lu", pkey->version);
|
||||
#endif
|
||||
pkey->version = LIBSSH2_PUBLICKEY_VERSION;
|
||||
}
|
||||
#ifdef LIBSSH2_DEBUG_PUBLICKEY
|
||||
_libssh2_debug(session, LIBSSH2_DBG_PUBLICKEY, "Enabling publickey subsystem version %lu", pkey->version);
|
||||
#endif
|
||||
LIBSSH2_FREE(session, data);
|
||||
return pkey;
|
||||
default:
|
||||
@@ -403,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,
|
||||
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_SESSION *session = channel->session;
|
||||
@@ -419,9 +411,7 @@ LIBSSH2_API int libssh2_publickey_add_ex(LIBSSH2_PUBLICKEY *pkey, const unsigned
|
||||
blob_len(4) +
|
||||
{blob} */
|
||||
|
||||
#ifdef LIBSSH2_DEBUG_PUBLICKEY
|
||||
_libssh2_debug(session, LIBSSH2_DBG_PUBLICKEY, "Adding %s pubickey", name);
|
||||
#endif
|
||||
|
||||
if (pkey->version == 1) {
|
||||
for(i = 0; i < num_attrs; i++) {
|
||||
@@ -480,9 +470,9 @@ LIBSSH2_API int libssh2_publickey_add_ex(LIBSSH2_PUBLICKEY *pkey, const unsigned
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef LIBSSH2_DEBUG_PUBLICKEY
|
||||
_libssh2_debug(session, LIBSSH2_DBG_PUBLICKEY, "Sending publickey \"add\" packet: type=%s blob_len=%ld num_attrs=%ld", name, blob_len, num_attrs);
|
||||
#endif
|
||||
_libssh2_debug(session, LIBSSH2_DBG_PUBLICKEY,
|
||||
"Sending publickey \"add\" packet: type=%s blob_len=%ld num_attrs=%ld",
|
||||
name, blob_len, num_attrs);
|
||||
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_FREE(session, packet);
|
||||
@@ -528,9 +518,7 @@ LIBSSH2_API int libssh2_publickey_remove_ex(LIBSSH2_PUBLICKEY *pkey, const unsig
|
||||
libssh2_htonu32(s, blob_len); s += 4;
|
||||
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);
|
||||
#endif
|
||||
if ((s - packet) != libssh2_channel_write(channel, (char *)packet, (s - packet))) {
|
||||
libssh2_error(session, LIBSSH2_ERROR_SOCKET_SEND, "Unable to send publickey remove packet", 0);
|
||||
LIBSSH2_FREE(session, packet);
|
||||
@@ -563,9 +551,7 @@ LIBSSH2_API int libssh2_publickey_list_fetch(LIBSSH2_PUBLICKEY *pkey, unsigned l
|
||||
libssh2_htonu32(s, sizeof("list") - 1); s += 4;
|
||||
memcpy(s, "list", sizeof("list") - 1); s += sizeof("list") - 1;
|
||||
|
||||
#ifdef LIBSSH2_DEBUG_PUBLICKEY
|
||||
_libssh2_debug(session, LIBSSH2_DBG_PUBLICKEY, "Sending publickey \"list\" packet");
|
||||
#endif
|
||||
if ((s - buffer) != libssh2_channel_write(channel, (char *)buffer, (s - buffer))) {
|
||||
libssh2_error(session, LIBSSH2_ERROR_SOCKET_SEND, "Unable to send publickey list packet", 0);
|
||||
return -1;
|
||||
@@ -614,13 +600,15 @@ LIBSSH2_API int libssh2_publickey_list_fetch(LIBSSH2_PUBLICKEY *pkey, unsigned l
|
||||
case LIBSSH2_PUBLICKEY_RESPONSE_PUBLICKEY:
|
||||
/* What we want */
|
||||
if (keys >= max_keys) {
|
||||
libssh2_publickey_list *newlist;
|
||||
/* Grow the key list if necessary */
|
||||
max_keys += 8;
|
||||
list = LIBSSH2_REALLOC(session, list, (max_keys + 1) * sizeof(libssh2_publickey_list));
|
||||
if (!list) {
|
||||
newlist = LIBSSH2_REALLOC(session, list, (max_keys + 1) * sizeof(libssh2_publickey_list));
|
||||
if (!newlist) {
|
||||
libssh2_error(session, LIBSSH2_ERROR_ALLOC, "Unable to allocate memory for publickey list", 0);
|
||||
goto err_exit;
|
||||
}
|
||||
list = newlist;
|
||||
}
|
||||
if (pkey->version == 1) {
|
||||
unsigned long comment_len;
|
||||
|
35
src/scp.c
35
src/scp.c
@@ -1,4 +1,4 @@
|
||||
/* Copyright (c) 2004-2006, Sara Golemon <sarag@libssh2.org>
|
||||
/* Copyright (c) 2004-2007, Sara Golemon <sarag@libssh2.org>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms,
|
||||
@@ -42,9 +42,12 @@
|
||||
#define LIBSSH2_SCP_RESPONSE_BUFLEN 256
|
||||
|
||||
/* {{{ libssh2_scp_recv
|
||||
* [BLOCKING]
|
||||
* 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);
|
||||
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';
|
||||
|
||||
#ifdef LIBSSH2_DEBUG_SCP
|
||||
_libssh2_debug(session, LIBSSH2_DBG_SCP, "Opening channel for SCP receive");
|
||||
#endif
|
||||
/* Allocate a channel */
|
||||
if ((channel = libssh2_channel_open_session(session)) == NULL) {
|
||||
LIBSSH2_FREE(session, command);
|
||||
@@ -89,9 +90,7 @@ LIBSSH2_API LIBSSH2_CHANNEL *libssh2_scp_recv(LIBSSH2_SESSION *session, const ch
|
||||
}
|
||||
LIBSSH2_FREE(session, command);
|
||||
|
||||
#ifdef LIBSSH2_DEBUG_SCP
|
||||
_libssh2_debug(session, LIBSSH2_DBG_SCP, "Sending initial wakeup");
|
||||
#endif
|
||||
/* SCP ACK */
|
||||
response[0] = '\0';
|
||||
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;
|
||||
while (sb && (response_len < LIBSSH2_SCP_RESPONSE_BUFLEN)) {
|
||||
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 */
|
||||
libssh2_error(session, LIBSSH2_ERROR_SCP_PROTOCOL, "Timed out waiting for SCP response", 0);
|
||||
libssh2_channel_free(channel);
|
||||
@@ -203,9 +204,8 @@ LIBSSH2_API LIBSSH2_CHANNEL *libssh2_scp_recv(LIBSSH2_SESSION *session, const ch
|
||||
libssh2_channel_free(channel);
|
||||
return NULL;
|
||||
}
|
||||
#ifdef LIBSSH2_DEBUG_SCP
|
||||
|
||||
_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? */
|
||||
break;
|
||||
@@ -215,7 +215,7 @@ LIBSSH2_API LIBSSH2_CHANNEL *libssh2_scp_recv(LIBSSH2_SESSION *session, const ch
|
||||
while (response_len < LIBSSH2_SCP_RESPONSE_BUFLEN) {
|
||||
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 */
|
||||
libssh2_error(session, LIBSSH2_ERROR_SCP_PROTOCOL, "Timed out waiting for SCP response", 0);
|
||||
libssh2_channel_free(channel);
|
||||
@@ -304,9 +304,7 @@ LIBSSH2_API LIBSSH2_CHANNEL *libssh2_scp_recv(LIBSSH2_SESSION *session, const ch
|
||||
libssh2_channel_free(channel);
|
||||
return NULL;
|
||||
}
|
||||
#ifdef LIBSSH2_DEBUG_SCP
|
||||
_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? */
|
||||
break;
|
||||
@@ -357,9 +355,7 @@ LIBSSH2_API LIBSSH2_CHANNEL *libssh2_scp_send_ex(LIBSSH2_SESSION *session, const
|
||||
}
|
||||
command[command_len - 1] = '\0';
|
||||
|
||||
#ifdef LIBSSH2_DEBUG_SCP
|
||||
_libssh2_debug(session, LIBSSH2_DBG_SCP, "Opening channel for SCP send");
|
||||
#endif
|
||||
/* Allocate a channel */
|
||||
if ((channel = libssh2_channel_open_session(session)) == NULL) {
|
||||
/* 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);
|
||||
|
||||
/* 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_channel_free(channel);
|
||||
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 */
|
||||
if (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);
|
||||
#endif
|
||||
|
||||
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_channel_free(channel);
|
||||
return NULL;
|
||||
}
|
||||
/* 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_channel_free(channel);
|
||||
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);
|
||||
#ifdef LIBSSH2_DEBUG_SCP
|
||||
_libssh2_debug(session, LIBSSH2_DBG_SCP, "Sent %s", response);
|
||||
#endif
|
||||
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_channel_free(channel);
|
||||
return NULL;
|
||||
}
|
||||
/* 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_channel_free(channel);
|
||||
return NULL;
|
||||
|
166
src/session.c
166
src/session.c
@@ -1,4 +1,4 @@
|
||||
/* Copyright (c) 2004-2006, Sara Golemon <sarag@libssh2.org>
|
||||
/* Copyright (c) 2004-2007, Sara Golemon <sarag@libssh2.org>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms,
|
||||
@@ -37,35 +37,20 @@
|
||||
|
||||
#include "libssh2_priv.h"
|
||||
#include <errno.h>
|
||||
#ifndef WIN32
|
||||
#ifdef HAVE_UNISTD_H
|
||||
#include <unistd.h>
|
||||
#endif
|
||||
#include <stdlib.h>
|
||||
|
||||
#ifdef HAVE_GETTIMEOFDAY
|
||||
#include <sys/time.h>
|
||||
#include <math.h>
|
||||
#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
|
||||
*/
|
||||
static LIBSSH2_ALLOC_FUNC(libssh2_default_alloc)
|
||||
{
|
||||
(void)abstract;
|
||||
return malloc(count);
|
||||
}
|
||||
/* }}} */
|
||||
@@ -74,6 +59,7 @@ static LIBSSH2_ALLOC_FUNC(libssh2_default_alloc)
|
||||
*/
|
||||
static LIBSSH2_FREE_FUNC(libssh2_default_free)
|
||||
{
|
||||
(void)abstract;
|
||||
free(ptr);
|
||||
}
|
||||
/* }}} */
|
||||
@@ -82,6 +68,7 @@ static LIBSSH2_FREE_FUNC(libssh2_default_free)
|
||||
*/
|
||||
static LIBSSH2_REALLOC_FUNC(libssh2_default_realloc)
|
||||
{
|
||||
(void)abstract;
|
||||
return realloc(ptr, count);
|
||||
}
|
||||
/* }}} */
|
||||
@@ -96,7 +83,7 @@ static int libssh2_banner_receive(LIBSSH2_SESSION *session)
|
||||
char banner[256];
|
||||
int banner_len = 0;
|
||||
|
||||
while ((banner_len < sizeof(banner)) &&
|
||||
while ((banner_len < (int)sizeof(banner)) &&
|
||||
((banner_len == 0) || (banner[banner_len-1] != '\n'))) {
|
||||
char c = '\0';
|
||||
int ret;
|
||||
@@ -114,7 +101,7 @@ static int libssh2_banner_receive(LIBSSH2_SESSION *session)
|
||||
break;
|
||||
case WSAENOTCONN:
|
||||
case WSAECONNABORTED:
|
||||
errno = ENOTCONN;
|
||||
errno = WSAENOTCONN;
|
||||
break;
|
||||
case WSAEINTR:
|
||||
errno = EINTR;
|
||||
@@ -145,11 +132,13 @@ static int libssh2_banner_receive(LIBSSH2_SESSION *session)
|
||||
if (!banner_len) return 1;
|
||||
|
||||
session->remote.banner = LIBSSH2_ALLOC(session, banner_len + 1);
|
||||
if (!session->remote.banner) {
|
||||
libssh2_error(session, LIBSSH2_ERROR_ALLOC, "Error allocating space for remote banner", 0);
|
||||
return 1;
|
||||
}
|
||||
memcpy(session->remote.banner, banner, banner_len);
|
||||
session->remote.banner[banner_len] = '\0';
|
||||
#ifdef LIBSSH2_DEBUG_TRANSPORT
|
||||
_libssh2_debug(session, LIBSSH2_DBG_TRANS, "Received Banner: %s", session->remote.banner);
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
/* }}} */
|
||||
@@ -159,15 +148,15 @@ static int libssh2_banner_receive(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;
|
||||
|
||||
if (session->local.banner) {
|
||||
/* setopt_string will have given us our \r\n characters */
|
||||
banner_len = strlen(session->local.banner);
|
||||
banner = session->local.banner;
|
||||
banner_len = strlen((char *)session->local.banner);
|
||||
banner = (char *)session->local.banner;
|
||||
}
|
||||
#ifdef LIBSSH2_DEBUG_TRANSPORT
|
||||
#ifdef LIBSSH2DEBUG
|
||||
{
|
||||
/* Hack and slash to avoid sending CRLF in debug output */
|
||||
char banner_dup[256];
|
||||
@@ -206,15 +195,15 @@ LIBSSH2_API int libssh2_banner_set(LIBSSH2_SESSION *session, const char *banner)
|
||||
|
||||
session->local.banner = LIBSSH2_ALLOC(session, banner_len + 3);
|
||||
if (!session->local.banner) {
|
||||
libssh2_error(session, LIBSSH2_ERROR_ALLOC, "Unable to allocate memory for local banner", 0);
|
||||
libssh2_error(session, LIBSSH2_ERROR_ALLOC,
|
||||
"Unable to allocate memory for local banner", 0);
|
||||
return -1;
|
||||
}
|
||||
|
||||
memcpy(session->local.banner, banner, banner_len);
|
||||
#ifdef LIBSSH2_DEBUG_TRANSPORT
|
||||
session->local.banner[banner_len] = '\0';
|
||||
_libssh2_debug(session, LIBSSH2_DBG_TRANS, "Setting local Banner: %s", session->local.banner);
|
||||
#endif
|
||||
_libssh2_debug(session, LIBSSH2_DBG_TRANS,
|
||||
"Setting local Banner: %s", session->local.banner);
|
||||
session->local.banner[banner_len++] = '\r';
|
||||
session->local.banner[banner_len++] = '\n';
|
||||
session->local.banner[banner_len++] = '\0';
|
||||
@@ -240,22 +229,24 @@ LIBSSH2_API LIBSSH2_SESSION *libssh2_session_init_ex(
|
||||
LIBSSH2_REALLOC_FUNC((*local_realloc)) = libssh2_default_realloc;
|
||||
LIBSSH2_SESSION *session;
|
||||
|
||||
if (my_alloc) local_alloc = my_alloc;
|
||||
if (my_free) local_free = my_free;
|
||||
if (my_realloc) local_realloc = my_realloc;
|
||||
if (my_alloc)
|
||||
local_alloc = my_alloc;
|
||||
if (my_free)
|
||||
local_free = my_free;
|
||||
if (my_realloc)
|
||||
local_realloc = my_realloc;
|
||||
|
||||
session = local_alloc(sizeof(LIBSSH2_SESSION), abstract);
|
||||
if (session) {
|
||||
memset(session, 0, sizeof(LIBSSH2_SESSION));
|
||||
session->alloc = local_alloc;
|
||||
session->free = local_free;
|
||||
session->realloc = local_realloc;
|
||||
session->abstract = abstract;
|
||||
#ifdef LIBSSH2_DEBUG_TRANSPORT
|
||||
_libssh2_debug(session, LIBSSH2_DBG_TRANS, "New session resource allocated");
|
||||
#endif
|
||||
|
||||
_libssh2_debug(session, LIBSSH2_DBG_TRANS,
|
||||
"New session resource allocated");
|
||||
libssh2_crypto_init ();
|
||||
|
||||
}
|
||||
return session;
|
||||
}
|
||||
/* }}} */
|
||||
@@ -264,7 +255,9 @@ LIBSSH2_API LIBSSH2_SESSION *libssh2_session_init_ex(
|
||||
* Set (or reset) a callback function
|
||||
* 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;
|
||||
|
||||
@@ -273,31 +266,29 @@ LIBSSH2_API void* libssh2_session_callback_set(LIBSSH2_SESSION *session, int cbt
|
||||
oldcb = session->ssh_msg_ignore;
|
||||
session->ssh_msg_ignore = callback;
|
||||
return oldcb;
|
||||
break;
|
||||
|
||||
case LIBSSH2_CALLBACK_DEBUG:
|
||||
oldcb = session->ssh_msg_debug;
|
||||
session->ssh_msg_debug = callback;
|
||||
return oldcb;
|
||||
break;
|
||||
|
||||
case LIBSSH2_CALLBACK_DISCONNECT:
|
||||
oldcb = session->ssh_msg_disconnect;
|
||||
session->ssh_msg_disconnect = callback;
|
||||
return oldcb;
|
||||
break;
|
||||
|
||||
case LIBSSH2_CALLBACK_MACERROR:
|
||||
oldcb = session->macerror;
|
||||
session->macerror = callback;
|
||||
return oldcb;
|
||||
break;
|
||||
|
||||
case LIBSSH2_CALLBACK_X11:
|
||||
oldcb = session->x11;
|
||||
session->x11 = callback;
|
||||
return oldcb;
|
||||
break;
|
||||
|
||||
}
|
||||
#ifdef LIBSSH2_DEBUG_TRANSPORT
|
||||
_libssh2_debug(session, LIBSSH2_DBG_TRANS, "Setting Callback %d", cbtype);
|
||||
#endif
|
||||
|
||||
return NULL;
|
||||
}
|
||||
@@ -306,8 +297,9 @@ LIBSSH2_API void* libssh2_session_callback_set(LIBSSH2_SESSION *session, int cbt
|
||||
/* {{{ proto libssh2_session_startup
|
||||
* session: LIBSSH2_SESSION struct allocated and owned by the calling program
|
||||
* Returns: 0 on success, or non-zero on failure
|
||||
* Any memory allocated by libssh2 will use alloc/realloc/free callbacks in session
|
||||
* socket *must* be populated with an opened socket
|
||||
* Any memory allocated by libssh2 will use alloc/realloc/free
|
||||
* callbacks in session
|
||||
* socket *must* be populated with an opened and connected socket.
|
||||
*/
|
||||
LIBSSH2_API int libssh2_session_startup(LIBSSH2_SESSION *session, int socket)
|
||||
{
|
||||
@@ -315,13 +307,15 @@ LIBSSH2_API int libssh2_session_startup(LIBSSH2_SESSION *session, int socket)
|
||||
unsigned long data_len;
|
||||
unsigned char service[sizeof("ssh-userauth") + 5 - 1];
|
||||
unsigned long service_length;
|
||||
int rc;
|
||||
|
||||
#ifdef LIBSSH2_DEBUG_TRANSPORT
|
||||
_libssh2_debug(session, LIBSSH2_DBG_TRANS, "session_startup for socket %d", socket);
|
||||
#endif
|
||||
_libssh2_debug(session, LIBSSH2_DBG_TRANS,
|
||||
"session_startup for socket %d", socket);
|
||||
/* FIXME: on some platforms (like win32) sockets are unsigned */
|
||||
if (socket < 0) {
|
||||
/* Did we forget something? */
|
||||
libssh2_error(session, LIBSSH2_ERROR_SOCKET_NONE, "Bad socket provided", 0);
|
||||
libssh2_error(session, LIBSSH2_ERROR_SOCKET_NONE,
|
||||
"Bad socket provided", 0);
|
||||
return LIBSSH2_ERROR_SOCKET_NONE;
|
||||
}
|
||||
session->socket_fd = socket;
|
||||
@@ -329,42 +323,50 @@ LIBSSH2_API int libssh2_session_startup(LIBSSH2_SESSION *session, int socket)
|
||||
/* TODO: Liveness check */
|
||||
if (libssh2_banner_send(session)) {
|
||||
/* 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;
|
||||
}
|
||||
|
||||
if (libssh2_banner_receive(session)) {
|
||||
/* 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;
|
||||
}
|
||||
|
||||
if (libssh2_kex_exchange(session, 0)) {
|
||||
libssh2_error(session, LIBSSH2_ERROR_KEX_FAILURE, "Unable to exchange encryption keys", 0);
|
||||
rc = libssh2_kex_exchange(session, 0);
|
||||
if(rc) {
|
||||
libssh2_error(session, LIBSSH2_ERROR_KEX_FAILURE,
|
||||
"Unable to exchange encryption keys", 0);
|
||||
return LIBSSH2_ERROR_KEX_FAILURE;
|
||||
}
|
||||
|
||||
#ifdef LIBSSH2_DEBUG_TRANSPORT
|
||||
_libssh2_debug(session, LIBSSH2_DBG_TRANS, "Requesting userauth service");
|
||||
#endif
|
||||
_libssh2_debug(session, LIBSSH2_DBG_TRANS,
|
||||
"Requesting userauth service");
|
||||
/* Request the userauth service */
|
||||
service[0] = SSH_MSG_SERVICE_REQUEST;
|
||||
libssh2_htonu32(service + 1, sizeof("ssh-userauth") - 1);
|
||||
memcpy(service + 5, "ssh-userauth", sizeof("ssh-userauth") - 1);
|
||||
if (libssh2_packet_write(session, service, sizeof("ssh-userauth") + 5 - 1)) {
|
||||
libssh2_error(session, LIBSSH2_ERROR_SOCKET_SEND, "Unable to ask for ssh-userauth service", 0);
|
||||
if (libssh2_packet_write(session, service,
|
||||
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;
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
service_length = libssh2_ntohu32(data + 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_error(session, LIBSSH2_ERROR_PROTO, "Invalid response received from server", 0);
|
||||
libssh2_error(session, LIBSSH2_ERROR_PROTO,
|
||||
"Invalid response received from server", 0);
|
||||
return LIBSSH2_ERROR_PROTO;
|
||||
}
|
||||
LIBSSH2_FREE(session, data);
|
||||
@@ -379,9 +381,7 @@ LIBSSH2_API int libssh2_session_startup(LIBSSH2_SESSION *session, int socket)
|
||||
*/
|
||||
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);
|
||||
#endif
|
||||
while (session->channels.head) {
|
||||
LIBSSH2_CHANNEL *tmp = session->channels.head;
|
||||
|
||||
@@ -509,9 +509,7 @@ LIBSSH2_API int libssh2_session_disconnect_ex(LIBSSH2_SESSION *session, int reas
|
||||
unsigned char *s, *data;
|
||||
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);
|
||||
#endif
|
||||
if (description) {
|
||||
descr_len = strlen(description);
|
||||
}
|
||||
@@ -557,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)
|
||||
{
|
||||
/* All methods have char *name as their first element */
|
||||
LIBSSH2_KEX_METHOD *method = NULL;
|
||||
const LIBSSH2_KEX_METHOD *method = NULL;
|
||||
|
||||
switch(method_type) {
|
||||
case LIBSSH2_METHOD_KEX:
|
||||
@@ -619,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
|
||||
* 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 */
|
||||
if (!session->err_code) {
|
||||
@@ -630,7 +630,7 @@ LIBSSH2_API int libssh2_session_last_error(LIBSSH2_SESSION *session, char **errm
|
||||
**errmsg = 0;
|
||||
}
|
||||
} else {
|
||||
*errmsg = "";
|
||||
*errmsg = (char *)"";
|
||||
}
|
||||
}
|
||||
if (errmsg_len) {
|
||||
@@ -640,7 +640,8 @@ LIBSSH2_API int libssh2_session_last_error(LIBSSH2_SESSION *session, char **errm
|
||||
}
|
||||
|
||||
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;
|
||||
|
||||
if (want_buf) {
|
||||
@@ -711,7 +712,7 @@ LIBSSH2_API int libssh2_poll_channel_read(LIBSSH2_CHANNEL *channel, int extended
|
||||
* Returns 0 if writing to channel would block,
|
||||
* 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;
|
||||
}
|
||||
@@ -721,7 +722,7 @@ inline int libssh2_poll_channel_write(LIBSSH2_CHANNEL *channel)
|
||||
* Returns 0 if no connections are waiting to be accepted
|
||||
* 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;
|
||||
}
|
||||
@@ -730,13 +731,18 @@ inline int libssh2_poll_listener_queued(LIBSSH2_LISTENER *listener)
|
||||
/* {{{ libssh2_poll
|
||||
* Poll sockets, channels, and listeners for activity
|
||||
*/
|
||||
LIBSSH2_API int libssh2_poll(LIBSSH2_POLLFD *fds, unsigned int nfds, long timeout)
|
||||
LIBSSH2_API int libssh2_poll(LIBSSH2_POLLFD *fds, unsigned int nfds,
|
||||
long timeout)
|
||||
{
|
||||
long timeout_remaining;
|
||||
int i, active_fds;
|
||||
unsigned int i, active_fds;
|
||||
#ifdef HAVE_POLL
|
||||
LIBSSH2_SESSION *session = NULL;
|
||||
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 */
|
||||
for(i = 0; i < nfds; i++) {
|
||||
@@ -893,7 +899,7 @@ LIBSSH2_API int libssh2_poll(LIBSSH2_POLLFD *fds, unsigned int nfds, long timeou
|
||||
case LIBSSH2_POLLFD_CHANNEL:
|
||||
if (sockets[i].events & POLLIN) {
|
||||
/* Spin session until no data available */
|
||||
while (libssh2_packet_read(fds[i].fd.channel->session, 0) > 0);
|
||||
while (libssh2_packet_read(fds[i].fd.channel->session) > 0);
|
||||
}
|
||||
if (sockets[i].revents & POLLHUP) {
|
||||
fds[i].revents |= LIBSSH2_POLLFD_CHANNEL_CLOSED | LIBSSH2_POLLFD_SESSION_CLOSED;
|
||||
@@ -903,7 +909,7 @@ LIBSSH2_API int libssh2_poll(LIBSSH2_POLLFD *fds, unsigned int nfds, long timeou
|
||||
case LIBSSH2_POLLFD_LISTENER:
|
||||
if (sockets[i].events & POLLIN) {
|
||||
/* Spin session until no data available */
|
||||
while (libssh2_packet_read(fds[i].fd.listener->session, 0) > 0);
|
||||
while (libssh2_packet_read(fds[i].fd.listener->session) > 0);
|
||||
}
|
||||
if (sockets[i].revents & POLLHUP) {
|
||||
fds[i].revents |= LIBSSH2_POLLFD_LISTENER_CLOSED | LIBSSH2_POLLFD_SESSION_CLOSED;
|
||||
@@ -952,13 +958,13 @@ LIBSSH2_API int libssh2_poll(LIBSSH2_POLLFD *fds, unsigned int nfds, long timeou
|
||||
case LIBSSH2_POLLFD_CHANNEL:
|
||||
if (FD_ISSET(fds[i].fd.channel->session->socket_fd, &rfds)) {
|
||||
/* Spin session until no data available */
|
||||
while (libssh2_packet_read(fds[i].fd.channel->session, 0) > 0);
|
||||
while (libssh2_packet_read(fds[i].fd.channel->session) > 0);
|
||||
}
|
||||
break;
|
||||
case LIBSSH2_POLLFD_LISTENER:
|
||||
if (FD_ISSET(fds[i].fd.listener->session->socket_fd, &rfds)) {
|
||||
/* 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;
|
||||
}
|
||||
|
1008
src/sftp.c
1008
src/sftp.c
File diff suppressed because it is too large
Load Diff
725
src/transport.c
Normal file
725
src/transport.c
Normal 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
|
@@ -1,4 +1,4 @@
|
||||
/* Copyright (c) 2004-2006, Sara Golemon <sarag@libssh2.org>
|
||||
/* Copyright (c) 2004-2007, Sara Golemon <sarag@libssh2.org>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms,
|
||||
@@ -54,7 +54,7 @@
|
||||
*/
|
||||
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" +
|
||||
method_len(4) + method(4)"none" */
|
||||
unsigned long methods_len;
|
||||
@@ -99,10 +99,8 @@ LIBSSH2_API char *libssh2_userauth_list(LIBSSH2_SESSION *session, const char *us
|
||||
methods_len = libssh2_ntohu32(data + 1);
|
||||
memcpy(data, data + 5, methods_len);
|
||||
data[methods_len] = '\0';
|
||||
#ifdef LIBSSH2_DEBUG_USERAUTH
|
||||
_libssh2_debug(session, LIBSSH2_DBG_AUTH, "Permitted auth methods: %s", data);
|
||||
#endif
|
||||
return data;
|
||||
return (char *)data;
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
@@ -123,7 +121,8 @@ LIBSSH2_API int libssh2_userauth_password_ex(LIBSSH2_SESSION *session, const cha
|
||||
const char *password, unsigned int password_len,
|
||||
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" +
|
||||
method_len(4) + method(8)"password" + chgpwdbool(1) + password_len(4) */
|
||||
|
||||
@@ -148,9 +147,7 @@ LIBSSH2_API int libssh2_userauth_password_ex(LIBSSH2_SESSION *session, const cha
|
||||
libssh2_htonu32(s, password_len); s += 4;
|
||||
memcpy(s, password, password_len); s += password_len;
|
||||
|
||||
#ifdef LIBSSH2_DEBUG_USERAUTH
|
||||
_libssh2_debug(session, LIBSSH2_DBG_AUTH, "Attempting to login using password authentication");
|
||||
#endif
|
||||
if (libssh2_packet_write(session, data, data_len)) {
|
||||
libssh2_error(session, LIBSSH2_ERROR_SOCKET_SEND, "Unable to send userauth-password request", 0);
|
||||
LIBSSH2_FREE(session, data);
|
||||
@@ -164,9 +161,7 @@ LIBSSH2_API int libssh2_userauth_password_ex(LIBSSH2_SESSION *session, const cha
|
||||
}
|
||||
|
||||
if (data[0] == SSH_MSG_USERAUTH_SUCCESS) {
|
||||
#ifdef LIBSSH2_DEBUG_USERAUTH
|
||||
_libssh2_debug(session, LIBSSH2_DBG_AUTH, "Password authentication successful");
|
||||
#endif
|
||||
LIBSSH2_FREE(session, data);
|
||||
session->state |= LIBSSH2_STATE_AUTHENTICATED;
|
||||
return 0;
|
||||
@@ -176,9 +171,7 @@ LIBSSH2_API int libssh2_userauth_password_ex(LIBSSH2_SESSION *session, const cha
|
||||
char *newpw = NULL;
|
||||
int newpw_len = 0;
|
||||
|
||||
#ifdef LIBSSH2_DEBUG_USERAUTH
|
||||
_libssh2_debug(session, LIBSSH2_DBG_AUTH, "Password change required");
|
||||
#endif
|
||||
LIBSSH2_FREE(session, data);
|
||||
if (passwd_change_cb) {
|
||||
passwd_change_cb(session, &newpw, &newpw_len, &session->abstract);
|
||||
@@ -190,6 +183,7 @@ LIBSSH2_API int libssh2_userauth_password_ex(LIBSSH2_SESSION *session, const cha
|
||||
s = data = LIBSSH2_ALLOC(session, data_len);
|
||||
if (!data) {
|
||||
libssh2_error(session, LIBSSH2_ERROR_ALLOC, "Unable to allocate memory for userauth-password-change request", 0);
|
||||
LIBSSH2_FREE(session, newpw);
|
||||
return -1;
|
||||
}
|
||||
|
||||
@@ -214,6 +208,7 @@ LIBSSH2_API int libssh2_userauth_password_ex(LIBSSH2_SESSION *session, const cha
|
||||
if (libssh2_packet_write(session, data, data_len)) {
|
||||
libssh2_error(session, LIBSSH2_ERROR_SOCKET_SEND, "Unable to send userauth-password-change request", 0);
|
||||
LIBSSH2_FREE(session, data);
|
||||
LIBSSH2_FREE(session, newpw);
|
||||
return -1;
|
||||
}
|
||||
LIBSSH2_FREE(session, data);
|
||||
@@ -241,13 +236,12 @@ static int libssh2_file_read_publickey(LIBSSH2_SESSION *session, unsigned char *
|
||||
const char *pubkeyfile)
|
||||
{
|
||||
FILE *fd;
|
||||
char *pubkey = NULL, c, *sp1, *sp2, *tmp;
|
||||
char c;
|
||||
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);
|
||||
#endif
|
||||
/* Read Public Key */
|
||||
fd = fopen(pubkeyfile, "r");
|
||||
if (!fd) {
|
||||
@@ -309,7 +303,7 @@ static int libssh2_file_read_publickey(LIBSSH2_SESSION *session, unsigned char *
|
||||
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_FREE(session, pubkey);
|
||||
return -1;
|
||||
@@ -324,20 +318,18 @@ static int libssh2_file_read_publickey(LIBSSH2_SESSION *session, unsigned char *
|
||||
/* {{{ libssh2_file_read_privatekey
|
||||
* 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,
|
||||
const char *method, int method_len,
|
||||
static int libssh2_file_read_privatekey(LIBSSH2_SESSION *session, const LIBSSH2_HOSTKEY_METHOD **hostkey_method, void **hostkey_abstract,
|
||||
const unsigned char *method, int method_len,
|
||||
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);
|
||||
#endif
|
||||
*hostkey_method = NULL;
|
||||
*hostkey_abstract = NULL;
|
||||
while (*hostkey_methods_avail && (*hostkey_methods_avail)->name) {
|
||||
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;
|
||||
break;
|
||||
}
|
||||
@@ -366,11 +358,12 @@ LIBSSH2_API int libssh2_userauth_hostbased_fromfile_ex(LIBSSH2_SESSION *session,
|
||||
const char *hostname, unsigned int hostname_len,
|
||||
const char *local_username, unsigned int local_username_len)
|
||||
{
|
||||
LIBSSH2_HOSTKEY_METHOD *privkeyobj;
|
||||
const LIBSSH2_HOSTKEY_METHOD *privkeyobj;
|
||||
void *abstract;
|
||||
unsigned char buf[5];
|
||||
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;
|
||||
|
||||
if (libssh2_file_read_publickey(session, &method, &method_len, &pubkeydata, &pubkeydata_len, publickey)) {
|
||||
@@ -385,6 +378,10 @@ LIBSSH2_API int libssh2_userauth_hostbased_fromfile_ex(LIBSSH2_SESSION *session,
|
||||
/* 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 */
|
||||
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;
|
||||
libssh2_htonu32(s, username_len); s += 4;
|
||||
@@ -436,13 +433,17 @@ LIBSSH2_API int libssh2_userauth_hostbased_fromfile_ex(LIBSSH2_SESSION *session,
|
||||
}
|
||||
|
||||
if (sig_len > pubkeydata_len) {
|
||||
unsigned char *newpacket;
|
||||
/* 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 */
|
||||
if (!packet) {
|
||||
newpacket = LIBSSH2_REALLOC(session, packet, packet_len + 4 + (4 + method_len) + (4 + sig_len)); /* PK sigblob */
|
||||
if (!newpacket) {
|
||||
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);
|
||||
return -1;
|
||||
}
|
||||
packet = newpacket;
|
||||
}
|
||||
|
||||
s = packet + packet_len;
|
||||
@@ -457,9 +458,7 @@ LIBSSH2_API int libssh2_userauth_hostbased_fromfile_ex(LIBSSH2_SESSION *session,
|
||||
memcpy(s, sig, sig_len); s += sig_len;
|
||||
LIBSSH2_FREE(session, sig);
|
||||
|
||||
#ifdef LIBSSH2_DEBUG_USERAUTH
|
||||
_libssh2_debug(session, LIBSSH2_DBG_AUTH, "Attempting hostbased authentication");
|
||||
#endif
|
||||
if (libssh2_packet_write(session, packet, s - packet)) {
|
||||
libssh2_error(session, LIBSSH2_ERROR_SOCKET_SEND, "Unable to send userauth-hostbased request", 0);
|
||||
LIBSSH2_FREE(session, packet);
|
||||
@@ -472,9 +471,8 @@ LIBSSH2_API int libssh2_userauth_hostbased_fromfile_ex(LIBSSH2_SESSION *session,
|
||||
}
|
||||
|
||||
if (data[0] == SSH_MSG_USERAUTH_SUCCESS) {
|
||||
#ifdef LIBSSH2_DEBUG_USERAUTH
|
||||
_libssh2_debug(session, LIBSSH2_DBG_AUTH, "Hostbased authentication successful");
|
||||
#endif
|
||||
_libssh2_debug(session, LIBSSH2_DBG_AUTH,
|
||||
"Hostbased authentication successful");
|
||||
/* We are us and we've proved it. */
|
||||
LIBSSH2_FREE(session, data);
|
||||
session->state |= LIBSSH2_STATE_AUTHENTICATED;
|
||||
@@ -495,7 +493,7 @@ LIBSSH2_API int libssh2_userauth_publickey_fromfile_ex(LIBSSH2_SESSION *session,
|
||||
const char *publickey, const char *privatekey,
|
||||
const char *passphrase)
|
||||
{
|
||||
LIBSSH2_HOSTKEY_METHOD *privkeyobj;
|
||||
const LIBSSH2_HOSTKEY_METHOD *privkeyobj;
|
||||
void *abstract;
|
||||
unsigned char buf[5];
|
||||
struct iovec datavec[4];
|
||||
@@ -514,6 +512,11 @@ LIBSSH2_API int libssh2_userauth_publickey_fromfile_ex(LIBSSH2_SESSION *session,
|
||||
/* 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 */
|
||||
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;
|
||||
libssh2_htonu32(s, username_len); s += 4;
|
||||
@@ -533,34 +536,28 @@ LIBSSH2_API int libssh2_userauth_publickey_fromfile_ex(LIBSSH2_SESSION *session,
|
||||
|
||||
libssh2_htonu32(s, pubkeydata_len); s += 4;
|
||||
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");
|
||||
#endif
|
||||
if (libssh2_packet_write(session, packet, packet_len)) {
|
||||
libssh2_error(session, LIBSSH2_ERROR_SOCKET_SEND, "Unable to send userauth-publickey request", 0);
|
||||
LIBSSH2_FREE(session, packet);
|
||||
LIBSSH2_FREE(session, method);
|
||||
LIBSSH2_FREE(session, pubkeydata);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (libssh2_packet_requirev(session, reply_codes, &data, &data_len)) {
|
||||
LIBSSH2_FREE(session, packet);
|
||||
LIBSSH2_FREE(session, method);
|
||||
LIBSSH2_FREE(session, pubkeydata);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (data[0] == SSH_MSG_USERAUTH_SUCCESS) {
|
||||
#ifdef LIBSSH2_DEBUG_USERAUTH
|
||||
_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 */
|
||||
LIBSSH2_FREE(session, data);
|
||||
LIBSSH2_FREE(session, packet);
|
||||
LIBSSH2_FREE(session, method);
|
||||
LIBSSH2_FREE(session, pubkeydata);
|
||||
session->state |= LIBSSH2_STATE_AUTHENTICATED;
|
||||
return 0;
|
||||
}
|
||||
@@ -570,14 +567,12 @@ LIBSSH2_API int libssh2_userauth_publickey_fromfile_ex(LIBSSH2_SESSION *session,
|
||||
LIBSSH2_FREE(session, data);
|
||||
LIBSSH2_FREE(session, packet);
|
||||
LIBSSH2_FREE(session, method);
|
||||
LIBSSH2_FREE(session, pubkeydata);
|
||||
libssh2_error(session, LIBSSH2_ERROR_PUBLICKEY_UNRECOGNIZED, "Username/PublicKey combination invalid", 0);
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Semi-Success! */
|
||||
LIBSSH2_FREE(session, data);
|
||||
LIBSSH2_FREE(session, pubkeydata);
|
||||
|
||||
if (libssh2_file_read_privatekey(session, &privkeyobj, &abstract, method, method_len, privatekey, passphrase)) {
|
||||
LIBSSH2_FREE(session, method);
|
||||
@@ -609,13 +604,17 @@ LIBSSH2_API int libssh2_userauth_publickey_fromfile_ex(LIBSSH2_SESSION *session,
|
||||
}
|
||||
|
||||
if (sig_len > pubkeydata_len) {
|
||||
unsigned char *newpacket;
|
||||
/* 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 */
|
||||
if (!packet) {
|
||||
newpacket = LIBSSH2_REALLOC(session, packet, packet_len + 4 + (4 + method_len) + (4 + sig_len)); /* PK sigblob */
|
||||
if (!newpacket) {
|
||||
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);
|
||||
return -1;
|
||||
}
|
||||
packet = newpacket;
|
||||
}
|
||||
|
||||
s = packet + packet_len;
|
||||
@@ -630,9 +629,7 @@ LIBSSH2_API int libssh2_userauth_publickey_fromfile_ex(LIBSSH2_SESSION *session,
|
||||
memcpy(s, sig, sig_len); s += sig_len;
|
||||
LIBSSH2_FREE(session, sig);
|
||||
|
||||
#ifdef LIBSSH2_DEBUG_USERAUTH
|
||||
_libssh2_debug(session, LIBSSH2_DBG_AUTH, "Attempting publickey authentication -- phase 2");
|
||||
#endif
|
||||
if (libssh2_packet_write(session, packet, s - packet)) {
|
||||
libssh2_error(session, LIBSSH2_ERROR_SOCKET_SEND, "Unable to send userauth-publickey request", 0);
|
||||
LIBSSH2_FREE(session, packet);
|
||||
@@ -648,9 +645,7 @@ LIBSSH2_API int libssh2_userauth_publickey_fromfile_ex(LIBSSH2_SESSION *session,
|
||||
}
|
||||
|
||||
if (data[0] == SSH_MSG_USERAUTH_SUCCESS) {
|
||||
#ifdef LIBSSH2_DEBUG_USERAUTH
|
||||
_libssh2_debug(session, LIBSSH2_DBG_AUTH, "Publickey authentication successful");
|
||||
#endif
|
||||
/* We are us and we've proved it. */
|
||||
LIBSSH2_FREE(session, data);
|
||||
session->state |= LIBSSH2_STATE_AUTHENTICATED;
|
||||
@@ -706,9 +701,7 @@ LIBSSH2_API int libssh2_userauth_keyboard_interactive_ex(LIBSSH2_SESSION *sessio
|
||||
/* submethods */
|
||||
libssh2_htonu32(s, 0); s += 4;
|
||||
|
||||
#ifdef LIBSSH2_DEBUG_USERAUTH
|
||||
_libssh2_debug(session, LIBSSH2_DBG_AUTH, "Attempting keyboard-interactive authentication");
|
||||
#endif
|
||||
if (libssh2_packet_write(session, data, packet_len)) {
|
||||
libssh2_error(session, LIBSSH2_ERROR_SOCKET_SEND, "Unable to send keyboard-interactive request", 0);
|
||||
LIBSSH2_FREE(session, data);
|
||||
@@ -717,7 +710,7 @@ LIBSSH2_API int libssh2_userauth_keyboard_interactive_ex(LIBSSH2_SESSION *sessio
|
||||
LIBSSH2_FREE(session, data);
|
||||
|
||||
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;
|
||||
char* auth_name = NULL;
|
||||
unsigned auth_instruction_len;
|
||||
@@ -735,9 +728,7 @@ LIBSSH2_API int libssh2_userauth_keyboard_interactive_ex(LIBSSH2_SESSION *sessio
|
||||
}
|
||||
|
||||
if (data[0] == SSH_MSG_USERAUTH_SUCCESS) {
|
||||
#ifdef LIBSSH2_DEBUG_USERAUTH
|
||||
_libssh2_debug(session, LIBSSH2_DBG_AUTH, "Keyboard-interactive authentication successful");
|
||||
#endif
|
||||
LIBSSH2_FREE(session, data);
|
||||
session->state |= LIBSSH2_STATE_AUTHENTICATED;
|
||||
return 0;
|
||||
@@ -804,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);
|
||||
|
||||
#ifdef LIBSSH2_DEBUG_USERAUTH
|
||||
_libssh2_debug(session, LIBSSH2_DBG_AUTH, "Keyboard-interactive response callback function invoked");
|
||||
#endif
|
||||
|
||||
packet_len = 1 /* byte SSH_MSG_USERAUTH_INFO_RESPONSE */
|
||||
+ 4 /* int num-responses */
|
||||
|
152
ssh2_sample.c
152
ssh2_sample.c
@@ -1,152 +0,0 @@
|
||||
#include "libssh2.h"
|
||||
|
||||
#ifndef WIN32
|
||||
# include <netinet/in.h>
|
||||
# include <sys/socket.h>
|
||||
# include <unistd.h>
|
||||
#else
|
||||
# include <winsock2.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";
|
||||
#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);
|
||||
#ifndef WIN32
|
||||
fcntl(sock, F_SETFL, 0);
|
||||
#endif
|
||||
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 and start it up
|
||||
* This will trade welcome banners, exchange keys, and setup crypto, compression, and MAC layers
|
||||
*/
|
||||
session = libssh2_session_init();
|
||||
if (libssh2_session_startup(session, sock)) {
|
||||
fprintf(stderr, "Failure establishing SSH session\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* At this point we havn't authenticated,
|
||||
* The first thing to do is check the hostkey's fingerprint against our known hosts
|
||||
* Your app may have it hard coded, may go to a file, may present it to the user, that's your call
|
||||
*/
|
||||
fingerprint = libssh2_hostkey_hash(session, LIBSSH2_HOSTKEY_HASH_MD5);
|
||||
printf("Fingerprint: ");
|
||||
for(i = 0; i < 16; i++) {
|
||||
printf("%02X ", (unsigned char)fingerprint[i]);
|
||||
}
|
||||
printf("\n");
|
||||
|
||||
if(argc > 1) {
|
||||
username = argv[1];
|
||||
}
|
||||
if(argc > 2) {
|
||||
password = argv[2];
|
||||
}
|
||||
|
||||
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 shell */
|
||||
if (!(channel = libssh2_channel_open_session(session))) {
|
||||
fprintf(stderr, "Unable to open a session\n");
|
||||
goto shutdown;
|
||||
}
|
||||
|
||||
/* Some environment variables may be set,
|
||||
* It's up to the server which ones it'll allow though
|
||||
*/
|
||||
libssh2_channel_setenv(channel, (char *)"FOO", (char *)"bar");
|
||||
|
||||
/* Request a terminal with 'vanilla' terminal emulation
|
||||
* See /etc/termcap for more options
|
||||
*/
|
||||
if (libssh2_channel_request_pty(channel, (char *)"vanilla")) {
|
||||
fprintf(stderr, "Failed requesting pty\n");
|
||||
goto skip_shell;
|
||||
}
|
||||
|
||||
/* Open a SHELL on that pty */
|
||||
if (libssh2_channel_shell(channel)) {
|
||||
fprintf(stderr, "Unable to request shell on allocated pty\n");
|
||||
goto shutdown;
|
||||
}
|
||||
|
||||
/* At this point the shell can be interacted with using
|
||||
* libssh2_channel_read()
|
||||
* libssh2_channel_read_stderr()
|
||||
* libssh2_channel_write()
|
||||
* libssh2_channel_write_stderr()
|
||||
*
|
||||
* Blocking mode may be (en|dis)abled with: libssh2_channel_set_blocking()
|
||||
* If the server send EOF, libssh2_channel_eof() will return non-0
|
||||
* To send EOF to the server use: libssh2_channel_send_eof()
|
||||
* A channel can be closed with: libssh2_channel_close()
|
||||
* A channel can be freed with: libssh2_channel_free()
|
||||
*/
|
||||
|
||||
skip_shell:
|
||||
if (channel) {
|
||||
libssh2_channel_free(channel);
|
||||
channel = NULL;
|
||||
}
|
||||
|
||||
/* Other channel types are supported via:
|
||||
* libssh2_scp_send()
|
||||
* libssh2_scp_recv()
|
||||
* libssh2_channel_direct_tcpip()
|
||||
*/
|
||||
|
||||
shutdown:
|
||||
|
||||
libssh2_session_disconnect(session, "Normal Shutdown, Thank you for playing");
|
||||
libssh2_session_free(session);
|
||||
|
||||
#ifdef WIN32
|
||||
Sleep(1000);
|
||||
closesocket(sock);
|
||||
#else
|
||||
sleep(1);
|
||||
close(sock);
|
||||
#endif
|
||||
printf("all done\n");
|
||||
return 0;
|
||||
}
|
@@ -1,7 +1,6 @@
|
||||
AM_CPPFLAGS = -I$(top_srcdir)/include
|
||||
AM_LDFLAGS = -no-install
|
||||
LDADD = ../src/libssh2.la
|
||||
|
||||
ctests = simple$(EXEEXT)
|
||||
ctests = simple
|
||||
TESTS = $(ctests)
|
||||
check_PROGRAMS = $(ctests)
|
||||
|
2
win32/Makefile
Normal file
2
win32/Makefile
Normal file
@@ -0,0 +1,2 @@
|
||||
include Makefile.win32
|
||||
|
311
win32/Makefile.win32
Normal file
311
win32/Makefile.win32
Normal 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)
|
||||
|
||||
|
@@ -1,3 +1,6 @@
|
||||
#ifndef LIBSSH2_CONFIG_H
|
||||
#define LIBSSH2_CONFIG_H
|
||||
|
||||
#ifndef WIN32
|
||||
#define WIN32
|
||||
#endif
|
||||
@@ -5,6 +8,16 @@
|
||||
#include <mswsock.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 */
|
||||
struct iovec {
|
||||
u_long iov_len;
|
||||
@@ -36,3 +49,7 @@ static inline int usleep(int udelay)
|
||||
|
||||
/* Enable newer diffie-hellman-group-exchange-sha1 syntax */
|
||||
#define LIBSSH2_DH_GEX_NEW 1
|
||||
|
||||
#endif /* LIBSSH2_CONFIG_H */
|
||||
|
||||
|
||||
|
208
win32/test/Makefile.win32
Normal file
208
win32/test/Makefile.win32
Normal file
@@ -0,0 +1,208 @@
|
||||
#########################################################################
|
||||
#
|
||||
## Makefile for building libssh2 samples (Win32 version - gnu make)
|
||||
## Use: make -f Makefile.win32 [help]
|
||||
##
|
||||
## Comments to: Guenter Knauf <eflash@gmx.net>
|
||||
##
|
||||
## $Id: Makefile.win32,v 1.5 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 var below to enable static linking of libssh2 and libz
|
||||
LINK_STATIC = 1
|
||||
|
||||
# Edit the vars below to change target settings.
|
||||
TARGETS = scp.exe sftp.exe sftpdir.exe ssh2.exe
|
||||
VERSION = $(LIBSSH2_VERSION)
|
||||
COPYR = (c) 2004-2007 Sara Golemon <sarag@libssh2.org>
|
||||
WWWURL = http://www.libssh2.org/
|
||||
DESCR = libssh2 $(subst .def,,$(notdir $@)) $(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
|
||||
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
|
||||
CFLAGS += -DWINSOCK_VERSION=MAKEWORD(2,0)
|
||||
|
||||
ifeq ($(CC),mwcc)
|
||||
LD = mwld
|
||||
RC = mwwinrc
|
||||
LDFLAGS = -nostdlib
|
||||
AR = $(LD)
|
||||
ARFLAGS = -nostdlib -library -o
|
||||
LIBEXT = lib
|
||||
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
|
||||
AR = ar
|
||||
ARFLAGS = -cq
|
||||
LIBEXT = a
|
||||
#LDLIBS += -lwsock32
|
||||
LDLIBS += -lws2_32
|
||||
RCFLAGS = -O coff -i
|
||||
CFLAGS += -fno-strict-aliasing -Wall -Wno-unused # -pedantic
|
||||
endif
|
||||
|
||||
INCLUDES = -I. -I.. -I../../include
|
||||
INCLUDES += -I$(OPENSSL_PATH)/outinc -I$(OPENSSL_PATH)/outinc/openssl
|
||||
#LIBPATH += -L$(OPENSSL_PATH)/out
|
||||
LIBPATH += -L..
|
||||
|
||||
ifdef LINK_STATIC
|
||||
LDLIBS += -llibssh2
|
||||
#LDLIBS += $(OPENSSL_PATH)/out/libcrypto.$(LIBEXT) $(OPENSSL_PATH)/out/libssl.$(LIBEXT)
|
||||
else
|
||||
LDLIBS += -llibssh2dll
|
||||
#LDLIBS += $(OPENSSL_PATH)/out/libeay32.$(LIBEXT) $(OPENSSL_PATH)/out/libssl32.$(LIBEXT)
|
||||
endif
|
||||
|
||||
ifdef WITH_ZLIB
|
||||
INCLUDES += -I$(ZLIB_PATH)
|
||||
#LIBPATH = -L$(ZLIB_PATH)
|
||||
#ifdef LINK_STATIC
|
||||
# LDLIBS += $(ZLIB_PATH)/libz.$(LIBEXT)
|
||||
#else
|
||||
# LDLIBS += $(ZLIB_PATH)/libzdll.$(LIBEXT)
|
||||
#endif
|
||||
endif
|
||||
|
||||
CFLAGS += $(INCLUDES)
|
||||
|
||||
#ifeq ($(findstring linux,$(OSTYPE)),linux)
|
||||
ifdef __MSYS__
|
||||
DL = '
|
||||
DS = /
|
||||
else
|
||||
DS = \\
|
||||
endif
|
||||
|
||||
vpath %.c ../../example/simple
|
||||
|
||||
.PRECIOUS: $(OBJDIR)/%.o $(OBJDIR)/%.rc $(OBJDIR)/%.res
|
||||
|
||||
|
||||
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 $@
|
||||
|
||||
%.exe: $(OBJDIR)/%.o $(OBJDIR)/%.res
|
||||
@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=.exe))\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=.exe))\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
|
||||
|
||||
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)
|
||||
|
||||
|
Reference in New Issue
Block a user