Compare commits

..

96 Commits

Author SHA1 Message Date
Daniel Stenberg
c889058cb3 updated info for 1.2.4 2010-02-13 17:10:30 +01:00
Dan Fandrich
69c876e210 Allow compiling with OpenSSL when AES isn't available. 2010-02-10 14:49:17 -08:00
Dave McCaldon
10f5c70ac0 Fix Tru64 socklen_t compile issue with example/direct_tcpip.c
Building libssh2-1.2.3 on Tru64 fails at line 48 and 166 because socklen_t
isn't defined on Tru64 unless _POSIX_PII_SOCKET is defined.

This patch updates configure.ac to add -D_POSIX_PII_SOCKET when building
on Tru64 platform(s).
2010-02-09 11:45:40 +01:00
Dave McCaldon
ea914c8b72 Resolve compile issues on Solaris x64 and UltraSPARC
Solaris builds of libssh2-1.2.3 failed on both x64 and UltraSPARC
platforms because of two problems:

1) src/agent.c:145 sun is a reserved word when using the SUNWspro compiler
2) example/direct_tcpip.c:84 INADDR_NONE is not defined
2010-02-09 11:19:52 +01:00
Daniel Stenberg
64a6c255ec towards 1.2.4 now 2010-02-03 19:36:19 +01:00
Daniel Stenberg
e09d6ac653 Version 1.2.3 (February 3, 2010) 2010-02-03 19:23:28 +01:00
Daniel Stenberg
91841731af fix building out of source tree by proving better include path
when building out of source tree, we provide -I$(top_builddir)/example
since the libssh2_config.h gets generated in that dir
2010-02-03 19:21:12 +01:00
Sofian Brabez
a190437c4a Replace : in hexdump with " " (two spaces) 2010-02-01 16:30:47 +01:00
Peter Stuge
68a900d27a Detect when the forwarded connection is closed in example/direct_tcpip.c 2010-01-30 00:45:56 +01:00
Peter Stuge
e4b7baa885 Fix example/direct_tcpip.c to work also on WIN32
read() and write() are no good for WIN32 sockets, use recv() and send().
2010-01-30 00:35:05 +01:00
Peter Stuge
2622bbaf33 Ignore libssh2_config.h.in and stamp-h2 in example/ and remove .cvsignore 2010-01-30 00:25:46 +01:00
Peter Stuge
d3dbe4c81e Simplify WIN32 ifdefs in example/direct_tcpip.c to allow standalone compile 2010-01-30 00:01:51 +01:00
Peter Stuge
095ccbf825 Always #define INVALID_SOCKET -1 in libssh2_priv.h when not on win32
Fix broken builds since commit abd9bd0bbe
for all non-win32 platforms.
2010-01-29 23:51:38 +01:00
Peter Stuge
8eafded280 Include hmac-md5 and hmac-md5-96 only if crypto backend supports MD5 2010-01-29 23:22:56 +01:00
Peter Stuge
6df87e64b7 Use LIBSSH2_HOSTKEY_HASH_SHA1 instead of _MD5 in examples and tests
MD5 support is optional and may not always be available, while SHA1 is both
required and recommended.
2010-01-29 23:06:31 +01:00
Peter Stuge
3ddac8ac66 Update mailing list address in configure.ac to @cool.haxx.se 2010-01-29 22:31:40 +01:00
Peter Stuge
6c543545fe Make example/direct_tcpip.c compile for win32
One warning from FD_SET() remains, it is also in some other examples.
2010-01-29 20:35:24 +01:00
Peter Stuge
abd9bd0bbe Correctly check for an invalid socket in session_startup() 2010-01-29 20:29:01 +01:00
Peter Stuge
5dd4005ace Small documentation fix after Dave's _USERAUTH_FAILURE improvement 2010-01-29 09:16:39 +01:00
Dave McCaldon
8f102b8f56 Handle SSH_MSG_USERAUTH_FAILURE for password and kbd-int authentication
Neither libssh2_userauth_password_ex() nor
libssh2_userauth_keyboard_interactive_ex() would return a login failure
error if the server responded with a SSH_MSG_USERAUTH_FAILURE, instead
you would see whatever previous error had occurred, typically
LIBSSH2_ERROR_EAGAIN.

This patch changes error code -18 to LIBSSH2_ERROR_AUTHENTICATION_FAILED
and makes LIBSSH2_ERROR_PUBLICKEY_UNRECOGNIZED an alias for
LIBSSH2_ERROR_AUTHENTICATION_FAILED.  In addition, new logic in
userauth_password() properly handles SSH_MSG_USERAUTH_FAILURE and both
this function and userauth_keyboard_interactive() now properly return
LIBSSH2_ERROR_AUTHENTICATION_FAILED.
2010-01-29 09:14:11 +01:00
Simon Josefsson
7d71f92a9c Fix. 2010-01-28 15:06:40 +01:00
Simon Josefsson
f6fab0d9ea Also deal with GLOBAL_REQUEST keep-alives. 2010-01-28 15:03:24 +01:00
Simon Josefsson
cc7f90f1d4 Make OpenSSH-style keepalive work against libssh2 clients. 2010-01-28 14:30:25 +01:00
Daniel Stenberg
6d55714ab5 clarified 2010-01-27 14:57:12 +01:00
Dave McCaldon
6b23f640f8 Fix trace context lookup in libssh2_debug()
The trace context is actually a bitmask so that tracing output can be
controlled by setting a bitmask using libssh2_trace().  However, the logic
in libssh2_debug() that converted the context to a string was using the
context value as an array index.  Because the code used a bounds check on
the array, there was never a danger of a crash, but you would certainly
either get the wrong string, or "unknown".

This patch adds a lookup that iterates over the context strings and uses
it's index to check for the corresponding bit in the context.
2010-01-26 17:33:25 +01:00
Peter Stuge
2cb8866f0a Fix typo in RELEASE-NOTES 2010-01-21 20:55:53 +01:00
Daniel Stenberg
3b3e13366e updated for 1.2.3 with all the stuff I found in the log 2010-01-20 19:57:42 +01:00
Daniel Stenberg
9f4292433a ignore more generated files 2010-01-20 19:46:36 +01:00
Dave McCaldon
f077984394 Pass user context through libssh2_trace_sethandler() to callback
The libssh2_trace_sethandler() call allows the user to handle the output of libssh2 rather than having it written to stderr.  This patch updates libssh2_trace_sethandler() to allow a user-defined void* context value to be passed back to the output handler.
2010-01-20 19:42:09 +01:00
Dave McCaldon
44eba0c993 Add libssh2_trace_sethandler() to the API (even more) 2010-01-15 22:58:44 +01:00
Dave McCaldon
474e38119b Add libssh2_trace_sethandler() to the API 2010-01-15 22:57:20 +01:00
Daniel Stenberg
7f27b0822d cleanup includes
We now produce a local libssh2_config.h file in this dir for the
examples to use so I cleaned up the include path at the same time.
2010-01-13 22:21:09 +01:00
Daniel Stenberg
e3d8c1cfed generate a libssh2_config.h in the example dir
buildconf copies the template to example/ and configure makes sure
to generate a proper file from it and the direct_tcpip.c example
is the first one to use it - to make sure it builds fine on more
paltforms
2010-01-13 13:46:56 +01:00
Simon Josefsson
11a114ee7c Remove redundant #includes and reorder sys/types.h include. 2010-01-13 11:03:26 +01:00
Daniel Stenberg
e48907ee05 avoid a free(NULL) 2010-01-10 00:00:31 +01:00
Simon Josefsson
3f6bc287f9 Make it simpler to get more debug info. 2010-01-07 19:43:40 +01:00
Daiki Ueno
e84fe88526 Simplify the commit 63457dfa using type cast from size_t * to ulong *. 2010-01-01 17:51:42 +09:00
Alexander Lamaison
73e37b3b49 Fixed memory leak in userauth_publickey().
userauth_publickey_fromfile() reads the key from a
file using file_read_publickey() which returns two
allocated strings, the decoded key and the key
method (such as "ssh-dss").  The latter can be
derived from the former but returning both avoids a
later allocation while doing so.

Older versions of userauth_publickey_fromfile() used
this method string directly but when
userauth_publickey() was factored out of
userauth_publickey_fromfile() it derived the method
from the key itself.  This resulted in the method
being allocated twice.

This fix, which maintains the optimisation that
avoids an extra allocation, changes
userauth_publickey() so it doesn't allocate and
derive the method when userauth_pblc_method already
has a value.

Signed-off-by: Alexander Lamaison <awl03@doc.ic.ac.uk>
2009-12-30 04:18:36 +00:00
Daiki Ueno
7926c9cfaa Fix the return value description of libssh2_knownhost_free(). 2009-12-25 10:26:51 +09:00
Daiki Ueno
63457dfa6c Fix compiler warnings for size_t pointers on 32-bit Windows. 2009-12-25 10:21:15 +09:00
Daiki Ueno
d00e97a7f1 Define INVALID_SOCKET and use it instead of SOCKET_BAD.
Revert the part of previous commit that defines SOCKET_BAD library wide.
2009-12-25 10:04:34 +09:00
Daiki Ueno
8436e45ea6 Use libssh2_socket_t in the ssh-agent stuff.
Define a portability macro SOCKET_BAD which means "invalid socket".
2009-12-24 19:45:57 +09:00
Daiki Ueno
0b6e37872d Mark/unmark connection to Pageant is open/close. 2009-12-24 17:57:15 +09:00
Daiki Ueno
1b3b7b2214 Add test to check if the socket is connected. 2009-12-24 16:49:28 +09:00
Peter Stuge
6a249d7b6c Add libssh2.pc to top-level .gitignore 2009-12-24 02:18:40 +01:00
Peter Stuge
87e32272f9 Fix publickey authentication regression
Commit 70b199f476 introduced a parsing
bug in file_read_publickey() which made the algorithm name contain an
extra trailing space character, breaking all publickey authentication.
2009-12-24 02:18:40 +01:00
Peter Stuge
bd0505d6b9 Add a direct-tcpip example which shows local port forwarding 2009-12-24 02:18:39 +01:00
Peter Stuge
f70dbfa3e6 Add session parameter and LIBSSH2_TRACE_SOCKET to libssh2_trace(3) man page 2009-12-24 02:18:39 +01:00
Peter Stuge
a2452d7eee Add TODO: Expose error messages sent by the server 2009-12-24 02:18:39 +01:00
Daiki Ueno
bbb2f29037 Fix doc comments. 2009-12-23 09:12:31 +09:00
Daiki Ueno
3138b5891f Add man pages for ssh-agent API. 2009-12-23 09:12:02 +09:00
Daiki Ueno
c573af83de Don't request userauthlist after authentication. 2009-12-23 07:59:37 +09:00
Simon Josefsson
ea8babf6d1 Add. 2009-12-21 12:30:17 +01:00
Daiki Ueno
db26c4eace Add an example to use ssh-agent API.
Signed-off-by: Simon Josefsson <simon@josefsson.org>
2009-12-21 12:19:33 +01:00
Daiki Ueno
7b351eed36 Add ssh-agent API.
Signed-off-by: Simon Josefsson <simon@josefsson.org>
2009-12-21 12:19:20 +01:00
Daiki Ueno
58abc7e30b Add callback-based API for publickey auth.
Signed-off-by: Simon Josefsson <simon@josefsson.org>
2009-12-21 12:15:33 +01:00
Simon Josefsson
0a3b350012 Move examples from example/simple to example/. 2009-12-19 10:56:03 +01:00
Simon Josefsson
b5e358618b Move examples from example/simple to example/. 2009-12-19 10:54:45 +01:00
Daniel Stenberg
dd81bda112 _libssh2_list_insert() fixed to work
While this is code not currently in use, it is part of the generic linked
list code and since I found the error I thought I'd better fix it since we
might bring in this function into the code one day.
2009-12-17 11:35:54 +01:00
Simon Josefsson
12433b4511 Silence compiler warnings.
Based on patch by Kamil Dudka <kdudka@redhat.com> in
<http://www.mail-archive.com/libssh2-devel@cool.haxx.se/msg00796.html>.
2009-12-16 16:14:55 +01:00
Kamil Dudka
39cbd17e19 libgcrypt: simplify code of _libssh2_dsa_sha1_sign
Signed-off-by: Simon Josefsson <simon@josefsson.org>
2009-12-16 16:08:25 +01:00
Kamil Dudka
1f91ab049f libgcrypt: follow-up for ssh-dss padding fix
Signed-off-by: Simon Josefsson <simon@josefsson.org>
2009-12-16 16:08:21 +01:00
Dan Fandrich
f2e5b49904 Check for the right environment variable in the test app 2009-12-15 15:21:06 -08:00
Simon Josefsson
b4c0821332 Silence warning about unused function parameter.
Reported by Steven Van Ingelgem <steven@vaningelgem.be>.
2009-12-14 15:50:41 +01:00
Daniel Stenberg
70b199f476 avoid returning data to memory already freed
In case of failure we must make sure that the data we return
doesn't point to a memory area already freed. Reported anonymously
in the bug report #2910103.
2009-12-10 23:40:44 +01:00
Peter Stuge
d142f385da Use LIBSSH2_TRACE_* internally and remove redundant LIBSSH2_DBG_* 2009-12-08 08:52:03 +01:00
Peter Stuge
1a491c6f00 Add LIBSSH2_TRACE_SOCKET context for tracing send() and recv()
Helpful in debugging the -39 errors.
2009-12-08 08:40:30 +01:00
Peter Stuge
1256c61815 Another transport layer fix for bogus -39 (LIBSSH2_ERROR_BAD_USE) errors
Commit 683aa0f6b5 made send_existing() send
more than just the second part of a packet when the kernel did not accept
the full packet, but the function still overlooked the SSH protocol
overhead in each packet, often 48 bytes.

If only the last few bytes of a packet remained, then the packet would
erroneously be considered completely sent, and the next call to write
more data in the session would return a -39 error.
2009-12-08 07:33:05 +01:00
Daniel Stenberg
95f559a926 move local variable to be more localized 2009-12-06 19:14:36 +01:00
Daniel Stenberg
052a68db30 fixed some indent mistakes 2009-12-06 19:14:36 +01:00
Peter Stuge
1aba38cd7d Fix padding in ssh-dss signature blob encoding
DSA signatures consist of two 160-bit integers called r and s. In ssh-dss
signature blobs r and s are stored directly after each other in binary
representation, making up a 320-bit (40 byte) string. (See RFC4253 p14.)

The crypto wrappers in libssh2 would either pack r and s incorrectly, or
fail, when at least one integer was small enough to be stored in 19 bytes
or less.

The patch ensures that r and s are always stored as two 160 bit numbers.
2009-12-06 08:07:40 +01:00
Peter Stuge
7317edab61 Don't always clear write direction blocking flag
When libssh2_transport_write() is called to continue sending a
partially sent packet the write direction flag must not be cleared
until the previous packet has been completely sent, or the app would
hang if the packet still isn't sent completely, since select() gets
called by the internal blocking emulation layer in libssh2 but would
then not be watching the socket for writability.

Clear the flag only once processing of previous packet data is
complete and a new packet is about to be prepared.
2009-11-27 07:52:26 +01:00
Alexander Lamaison
e642e2c202 Detabify. 2009-11-24 14:54:10 +00:00
Daniel Stenberg
f07cf3afd3 Fixed memory leak in sftp_fstat(). 2009-11-24 14:45:46 +00:00
Simon Josefsson
1e350754f6 Mark date of 1.2.2 release. 2009-11-17 09:51:12 +01:00
Simon Josefsson
55031fa320 Merge branch 'master' of ssh://git.stuge.se/var/lib/git/libssh2 2009-11-17 09:50:12 +01:00
Daniel Stenberg
355fbf4d5b prepared for 1.2.2 2009-11-16 22:43:55 +01:00
Simon Josefsson
74c63852d7 Improve NEWS items. 2009-11-16 16:24:36 +01:00
Simon Josefsson
ebbd7c879b Support AES-Counter ciphers. 2009-11-16 16:04:00 +01:00
Simon Josefsson
b78f854d8b Silence compiler warning.
Reported by Steven Van Ingelgem <steven@vaningelgem.be>
in <http://thread.gmane.org/gmane.network.ssh.libssh2.devel/2566>.
2009-11-04 14:47:00 +01:00
Simon Josefsson
1f0d47fa92 Mention libssh2-style.el. 2009-10-29 10:39:15 +01:00
Simon Josefsson
463e09e55f Use memmove instead of memcpy on overlapping memory areas.
Reported by Bob Alexander <balexander@expressor-software.com> in
<http://thread.gmane.org/gmane.network.ssh.libssh2.devel/2530>.
2009-10-28 15:31:00 +01:00
Simon Josefsson
82bf39dbfa Add. 2009-10-28 15:29:36 +01:00
Simon Josefsson
e5f170bae2 Protect against crash on too small SSH_MSG_IGNORE packets.
Reported by Bob Alexander <balexander@expressor-software.com>
in <http://thread.gmane.org/gmane.network.ssh.libssh2.devel/2530>.
2009-10-28 15:27:11 +01:00
Simon Josefsson
fc60563840 add copyright line 2009-10-27 20:32:24 +01:00
Simon Josefsson
b38b4fb859 support arcfour128 cipher per RFC 4345 2009-10-27 20:03:30 +01:00
Cristian Rodríguez
3182045c2d add support for GCC visibility features 2009-10-21 17:02:12 +02:00
Simon Josefsson
60d73d5663 less hard coding of cipher mode in libgcrypt backend 2009-10-19 17:36:50 +02:00
Juzna
1e80194b97 libssh2_channel_forward_accept() and listening fixes
The forward accepting was not done right before, and the
packet_queue_listener function didn't assign a necessary
variable. All fixed by Juzna. I (Daniel) modified the
forward_accept() change somewhat.
2009-10-18 03:41:25 +02:00
Daniel Stenberg
0c13f7beda added man page for libssh2_knownhost_free 2009-10-18 03:03:55 +02:00
Daniel Stenberg
b859f4d9d2 more CVS => DEV conversions 2009-10-17 21:36:57 +02:00
Daniel Stenberg
13092c5a5e remove references to "CVS" 2009-10-17 21:36:05 +02:00
Daniel Stenberg
22b73235d3 we are on the 1.2.2 track nowadays 2009-10-17 21:34:49 +02:00
Peter Stuge
55034294e8 Ensure that win32/libssh2.dsp will be generated with CRLF line endings
First, win32/msvcproj.{head,foot} are now committed with CRLF line endings,
and .gitattributes specifies that these should not be changed on checkout or
commit. These are win32 files so it makes sense to store them with native
line endings.

Second, the rules for generating libssh2.dsp and libssh2.vcproj are changed
so that the full file contents passes through awk, which strips all CR and
then prints each line with one CRLF line ending. Stripping CR is important
to avoid CRCRLF in case the input already comes with CRLF.
2009-10-17 02:58:53 +02:00
Dan Fandrich
5e80055d22 Make sure permissions on the private host key file is tight enough that
sshd doesn't complain. Quote $srcdir to try to cope with embedded spaces.
2009-09-29 15:27:17 -07:00
Peter Stuge
11ca8d5583 Clarify the scp_write examples slightly and use an octal mask for the mode 2009-09-30 00:12:23 +02:00
77 changed files with 2885 additions and 690 deletions

2
.gitattribute Normal file
View File

@@ -0,0 +1,2 @@
win32/msvcproj.head -crlf
win32/msvcproj.foot -crlf

1
.gitignore vendored
View File

@@ -31,3 +31,4 @@ install-sh
*.la
mkinstalldirs
tags
libssh2.pc

View File

@@ -1,6 +1,7 @@
/* Copyright (c) 2004-2007 Sara Golemon <sarag@libssh2.org>
* Copyright (c) 2006-2007 The Written Word, Inc.
* Copyright (c) 2009 Daniel Stenberg
* Copyright (C) 2008, 2009 Simon Josefsson
* All rights reserved.
*
* Redistribution and use in source and binary forms,

View File

@@ -10,3 +10,4 @@ libssh2 source code style guide:
}
- keep source lines shorter than 80 columns
- See libssh2-style.el for how to achieve this within Emacs

View File

@@ -75,55 +75,54 @@ include Makefile.inc
WIN32SOURCES = $(CSOURCES)
WIN32HEADERS = $(HHEADERS) libssh2_config.h
DSPOUT = | awk '{printf("%s\r\n", $$0)}' >> $(DSP)
VCPROJOUT = | awk '{printf("%s\r\n", $$0)}' >> $(VCPROJ)
$(DSP): win32/msvcproj.head win32/msvcproj.foot Makefile.am
echo "creating $(DSP)"
@(cp $(srcdir)/win32/msvcproj.head $(DSP); \
echo "# Begin Group \"Source Files\"" $(DSPOUT); \
echo "" $(DSPOUT); \
echo "# PROP Default_Filter \"cpp;c;cxx\"" $(DSPOUT); \
win32_srcs='$(WIN32SOURCES)'; \
sorted_srcs=`for file in $$win32_srcs; do echo $$file; done | sort`; \
for file in $$sorted_srcs; do \
echo "# Begin Source File" $(DSPOUT); \
echo "" $(DSPOUT); \
echo "SOURCE=..\\src\\"$$file $(DSPOUT); \
echo "# End Source File" $(DSPOUT); \
@( (cat $(srcdir)/win32/msvcproj.head; \
echo "# Begin Group \"Source Files\""; \
echo ""; \
echo "# PROP Default_Filter \"cpp;c;cxx\""; \
win32_srcs='$(WIN32SOURCES)'; \
sorted_srcs=`for file in $$win32_srcs; do echo $$file; done | sort`; \
for file in $$sorted_srcs; do \
echo "# Begin Source File"; \
echo ""; \
echo "SOURCE=..\\src\\"$$file; \
echo "# End Source File"; \
done; \
echo "# End Group" $(DSPOUT); \
echo "# Begin Group \"Header Files\"" $(DSPOUT); \
echo "" $(DSPOUT); \
echo "# PROP Default_Filter \"h;hpp;hxx\"" $(DSPOUT); \
win32_hdrs='$(WIN32HEADERS)'; \
sorted_hdrs=`for file in $$win32_hdrs; do echo $$file; done | sort`; \
for file in $$sorted_hdrs; do \
echo "# Begin Source File" $(DSPOUT); \
echo "" $(DSPOUT); \
if [ "$$file" == "libssh2_config.h" ]; \
then \
echo "SOURCE=.\\"$$file $(DSPOUT); \
else \
echo "SOURCE=..\\src\\"$$file $(DSPOUT); \
fi; \
echo "# End Source File" $(DSPOUT); \
echo "# End Group"; \
echo "# Begin Group \"Header Files\""; \
echo ""; \
echo "# PROP Default_Filter \"h;hpp;hxx\""; \
win32_hdrs='$(WIN32HEADERS)'; \
sorted_hdrs=`for file in $$win32_hdrs; do echo $$file; done | sort`; \
for file in $$sorted_hdrs; do \
echo "# Begin Source File"; \
echo ""; \
if [ "$$file" == "libssh2_config.h" ]; \
then \
echo "SOURCE=.\\"$$file; \
else \
echo "SOURCE=..\\src\\"$$file; \
fi; \
echo "# End Source File"; \
done; \
echo "# End Group" $(DSPOUT); \
cat $(srcdir)/win32/msvcproj.foot $(DSPOUT) )
echo "# End Group"; \
cat $(srcdir)/win32/msvcproj.foot) | \
awk '{printf("%s\r\n", gensub("\r", "", "g"))}' > $@ )
$(VCPROJ): win32/vc8proj.head win32/vc8proj.foot Makefile.am
echo "creating $(VCPROJ)"
@(cp $(srcdir)/vc8proj.head $(VCPROJ); \
win32_srcs='$(WIN32SOURCES)'; \
sorted_srcs=`for file in $$win32_srcs; do echo $$file; done | sort`; \
for file in $$sorted_srcs; do \
echo "<File RelativePath=\""..\src\$$file"\"></File>" $(VCPROJOUT); \
@( (cat $(srcdir)/vc8proj.head; \
win32_srcs='$(WIN32SOURCES)'; \
sorted_srcs=`for file in $$win32_srcs; do echo $$file; done | sort`; \
for file in $$sorted_srcs; do \
echo "<File RelativePath=\""..\src\$$file"\"></File>"; \
done; \
echo "</Filter><Filter Name=\"Header Files\">" $(VCPROJOUT); \
win32_hdrs='$(WIN32HEADERS)'; \
sorted_hdrs=`for file in $$win32_hdrs; do echo $$file; done | sort`; \
for file in $$sorted_hdrs; do \
echo "<File RelativePath=\""..\src\$$file"\"></File>" $(VCPROJOUT); \
echo "</Filter><Filter Name=\"Header Files\">"; \
win32_hdrs='$(WIN32HEADERS)'; \
sorted_hdrs=`for file in $$win32_hdrs; do echo $$file; done | sort`; \
for file in $$sorted_hdrs; do \
echo "<File RelativePath=\""..\src\$$file"\"></File>"; \
done; \
cat $(srcdir)/vc8proj.foot $(VCPROJOUT) )
cat $(srcdir)/vc8proj.foot) | \
awk '{printf("%s\r\n", gensub("\r", "", "g"))}' > $@ )

View File

@@ -1,5 +1,5 @@
CSOURCES = channel.c comp.c crypt.c hostkey.c kex.c mac.c misc.c \
packet.c publickey.c scp.c session.c sftp.c userauth.c transport.c \
version.c knownhost.c openssl.c libgcrypt.c pem.c
version.c knownhost.c agent.c openssl.c libgcrypt.c pem.c
HHEADERS = libssh2_priv.h openssl.h libgcrypt.h transport.h channel.h comp.h mac.h misc.h

52
NEWS
View File

@@ -1,3 +1,55 @@
Version 1.2.4 (February 13, 2010)
o Resolve compile issues on Solaris x64 and UltraSPARC
o Allow compiling with OpenSSL when AES isn't available
o Fix Tru64 socklen_t compile issue with example/direct_tcpip.c
Version 1.2.3 (February 3, 2010)
o Added libssh2_trace_sethandler()
o Added the direct_tcpip.c example
o Fixed memory leak in userauth_publickey
o Added support for authentication via SSH-Agent. By Daiki Ueno.
o Respond to unknown SSH_MSG_GLOBAL_REQUEST/SSH_MSG_CHANNEL_REQUEST
with SSH_MSG_REQUEST_FAILURE/SSH_MSG_CHANNEL_FAILURE in order to
make (at least) OpenSSH server keepalive work. Before OpenSSH
servers (configured with a positive ClientAliveInterval) would
terminate connections against libssh2 clients because libssh2 did
not respond properly to the request. By Simon Josefsson.
Version 1.2.2 (November 16, 2009)
* This release includes the following changes:
o Fix crash when server sends an invalid SSH_MSG_IGNORE message.
Reported by Bob Alexander <balexander@expressor-software.com> in
<http://thread.gmane.org/gmane.network.ssh.libssh2.devel/2530>.
By Simon Josefsson.
o Support for the "aes128-ctr", "aes192-ctr", "aes256-ctr" ciphers
as per RFC 4344 for libgcrypt and OpenSSL. They are now the
preferred ciphers. By Simon Josefsson.
o Support for the "arcfour128" cipher as per RFC 4345 for libgcrypt
and OpenSSL. It is preferred over the normal "arcfour" cipher
which is somewhat broken. By Simon Josefsson.
o Add support for GCC visibility features. By Cristian Rodr<64>guez.
o Fix libssh2_channel_forward_accept. By Juzna.
o Generate Win32 files correctly. By Peter Stuge.
o Fix permission issue in ssh2 self test. By Dan Fandrich.
o Use memmove instead of memcpy in one place which copies
overlapping memory areas.
o Cleanup hard coding of cipher modes in libgcrypt backend. By Simon.
o Added man page for libssh2_knownhost_free. By Daniel.
Version 1.2.1 (September 28, 2009)
* This release includes the following changes:

View File

@@ -1,6 +1,6 @@
!include "win32/config.mk"
# SUBDIRS=src example\simple
# SUBDIRS=src example
SUBDIRS=src
all-sub:

View File

@@ -1,27 +1,18 @@
libssh2 1.2.1
libssh2 1.2.4
This release includes the following changes:
o generate and install libssh2.pc
o
This release includes the following bugfixes:
o proper return codes returned from several functions
o return EAGAIN internal cleanup
o added knownhost.c to windows makefiles
o pass private-key to OpenSSL as a filename with BIO_new_file().
o make libssh2_scp_send/recv do blocking mode correctly
o libssh2_channel_wait_closed() could hang
o libssh2_channel_read_ex() must return 0 when closed
o added gettimeofday() function for win32 for the debug trace outputs
o transport layer bug causing invalid -39 (LIBSSH2_ERROR_BAD_USE) errors
o scp examples now loop correctly over libssh2_channel_write()
o Resolve compile issues on Solaris x64 and UltraSPARC
o Allow compiling with OpenSSL when AES isn't available
o Fix Tru64 socklen_t compile issue with example/direct_tcpip.c
This release would not have looked like this without help, code, reports and
advice from friends like these:
Peter Stuge, Neil Gierman, Steven Van Ingelgem, Alexander Lamaison,
Guenter Knauf, Simon Josefsson
Dan Fandrich, Dave McCaldon, Peter Stuge
Thanks! (and sorry if I forgot to mention someone)

2
TODO
View File

@@ -18,6 +18,8 @@ Things TODO
* Fix all compiler warnings (some can't be done without API changes)
* Expose error messages sent by the server
At next SONAME bump
===================

View File

@@ -22,6 +22,6 @@ ${AUTOHEADER:-autoheader}
# copy the private libssh2_config.h.in to the examples dir so that
# it can be included without pointing the include path to the private
# source dir
cp src/libssh2_config.h.in example/simple/config.h.in
cp src/libssh2_config.h.in example/libssh2_config.h.in
${AUTOCONF:-autoconf}
${AUTOMAKE:-automake} --add-missing --copy

View File

@@ -1,8 +1,8 @@
# AC_PREREQ(2.57)
AC_INIT(libssh2, [-], libssh2-devel@lists.sourceforge.net)
AC_INIT(libssh2, [-], libssh2-devel@cool.haxx.se)
AC_CONFIG_MACRO_DIR([m4])
AC_CONFIG_SRCDIR([src])
AC_CONFIG_HEADER([src/libssh2_config.h])
AM_CONFIG_HEADER([src/libssh2_config.h example/libssh2_config.h])
AM_MAINTAINER_MODE
dnl SED is needed by some of the tools
@@ -41,6 +41,9 @@ case "$host" in
;;
*hpux*)
;;
*osf*)
CFLAGS="$CFLAGS -D_POSIX_PII_SOCKET"
;;
*)
;;
esac
@@ -162,11 +165,51 @@ AC_HELP_STRING([--disable-debug],[Disable debug options]),
AC_MSG_RESULT(no)
)
dnl ************************************************************
dnl Enable hiding of internal symbols in library to reduce its size and
dnl speed dynamic linking of applications. This currently is only supported
dnl on gcc >= 4.0 and SunPro C.
dnl
AC_MSG_CHECKING([whether to enable hidden symbols in the library])
AC_ARG_ENABLE(hidden-symbols,
AC_HELP_STRING([--enable-hidden-symbols],[Hide internal symbols in library])
AC_HELP_STRING([--disable-hidden-symbols],[Leave all symbols with default visibility in library]),
[ case "$enableval" in
no)
AC_MSG_RESULT(no)
;;
*)
AC_MSG_CHECKING([whether $CC supports it])
if test "$GCC" = yes ; then
if $CC --help --verbose 2>&1 | grep fvisibility= > /dev/null ; then
AC_MSG_RESULT(yes)
AC_DEFINE(LIBSSH2_API, [__attribute__ ((visibility ("default")))], [to make a symbol visible])
CFLAGS="$CFLAGS -fvisibility=hidden"
else
AC_MSG_RESULT(no)
fi
else
dnl Test for SunPro cc
if $CC 2>&1 | grep flags >/dev/null && $CC -flags | grep xldscope= >/dev/null ; then
AC_MSG_RESULT(yes)
AC_DEFINE(LIBSSH2_API, [__global], [to make a symbol visible])
CFLAGS="$CFLAGS -xldscope=hidden"
else
AC_MSG_RESULT(no)
fi
fi
;;
esac ],
AC_MSG_RESULT(no)
)
# Checks for header files.
# AC_HEADER_STDC
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_HEADERS([sys/un.h])
case $host in
*-*-cygwin* | *-*-cegcc*)
@@ -213,7 +256,6 @@ AC_CONFIG_FILES([Makefile
src/Makefile
tests/Makefile
example/Makefile
example/simple/Makefile
docs/Makefile
libssh2.pc])
AC_OUTPUT

View File

@@ -3,6 +3,13 @@
EXTRA_DIST = template.3
dist_man_MANS = \
libssh2_agent_connect.3 \
libssh2_agent_disconnect.3 \
libssh2_agent_free.3 \
libssh2_agent_get_identity.3 \
libssh2_agent_init.3 \
libssh2_agent_list_identities.3 \
libssh2_agent_userauth.3 \
libssh2_banner_set.3 \
libssh2_base64_decode.3 \
libssh2_channel_close.3 \
@@ -40,6 +47,7 @@ dist_man_MANS = \
libssh2_knownhost_del.3 \
libssh2_knownhost_get.3 \
libssh2_knownhost_init.3 \
libssh2_knownhost_free.3 \
libssh2_knownhost_readfile.3 \
libssh2_knownhost_readline.3 \
libssh2_knownhost_writefile.3 \
@@ -89,6 +97,7 @@ dist_man_MANS = \
libssh2_sftp_unlink_ex.3 \
libssh2_sftp_write.3 \
libssh2_trace.3 \
libssh2_trace_sethandler.3 \
libssh2_userauth_authenticated.3 \
libssh2_userauth_hostbased_fromfile_ex.3 \
libssh2_userauth_keyboard_interactive_ex.3 \

View File

@@ -0,0 +1,23 @@
.\"
.\" Copyright (c) 2009 by Daiki Ueno
.\"
.TH libssh2_agent_connect 3 "23 Dec 2009" "libssh2 1.2" "libssh2 manual"
.SH NAME
libssh2_agent_connect - connect to an ssh-agent
.SH SYNOPSIS
#include <libssh2.h>
int libssh2_agent_connect(LIBSSH2_AGENT *agent);
.SH DESCRIPTION
Connect to an ssh-agent running on the system.
Call \fBlibssh2_agent_disconnect(3)\fP to close the connection after
you're doing using it.
.SH RETURN VALUE
Returns 0 if succeeded, or a negative value for error.
.SH AVAILABILITY
Added in libssh2 1.2
.SH SEE ALSO
.BR libssh2_agent_init(3)
.BR libssh2_agent_disconnect(3)

View File

@@ -0,0 +1,20 @@
.\"
.\" Copyright (c) 2009 by Daiki Ueno
.\"
.TH libssh2_agent_disconnect 3 "23 Dec 2009" "libssh2 1.2" "libssh2 manual"
.SH NAME
libssh2_agent_disconnect - close a connection to an ssh-agent
.SH SYNOPSIS
#include <libssh2.h>
int libssh2_agent_disconnect(LIBSSH2_AGENT *agent);
.SH DESCRIPTION
Close a connection to an ssh-agent.
.SH RETURN VALUE
Returns 0 if succeeded, or a negative value for error.
.SH AVAILABILITY
Added in libssh2 1.2
.SH SEE ALSO
.BR libssh2_agent_connect(3)
.BR libssh2_agent_free(3)

20
docs/libssh2_agent_free.3 Normal file
View File

@@ -0,0 +1,20 @@
.\"
.\" Copyright (c) 2009 by Daiki Ueno
.\"
.TH libssh2_agent_free 3 "28 May 2009" "libssh2 1.2" "libssh2 manual"
.SH NAME
libssh2_agent_free - free an ssh-agent handle
.SH SYNOPSIS
#include <libssh2.h>
void libssh2_agent_free(LIBSSH2_AGENT *agent);
.SH DESCRIPTION
Free an ssh-agent handle. This function also frees the internal
collection of public keys.
.SH RETURN VALUE
None.
.SH AVAILABILITY
Added in libssh2 1.2
.SH SEE ALSO
.BR libssh2_agent_init(3)
.BR libssh2_agent_disconnect(3)

View File

@@ -0,0 +1,34 @@
.\"
.\" Copyright (c) 2009 by Daiki Ueno
.\"
.TH libssh2_agent_get_identity 3 "23 Dec 2009" "libssh2 1.2" "libssh2 manual"
.SH NAME
libssh2_agent_get_identity - get a public key off the collection of public keys managed by ssh-agent
.SH SYNOPSIS
#include <libssh2.h>
int libssh2_agent_get_identity(LIBSSH2_AGENT *agent,
struct libssh2_agent_publickey **store,
struct libssh2_agent_publickey *prev);
.SH DESCRIPTION
\fIlibssh2_agent_get_identity(3)\fP allows an application to iterate
over all public keys in the collection managed by ssh-agent.
\fIstore\fP should point to a pointer that gets filled in to point to the
public key data.
\fIprev\fP is a pointer to a previous 'struct libssh2_agent_publickey'
as returned by a previous invoke of this function, or NULL to get the
first entry in the internal collection.
.SH RETURN VALUE
Returns 0 if everything is fine and information about a host was stored in
the \fIstore\fP struct.
Returns 1 if it reached the end of public keys.
Returns negative values for error
.SH AVAILABILITY
Added in libssh2 1.2
.SH SEE ALSO
.BR libssh2_agent_list_identities(3)
.BR libssh2_agent_userauth(3)

26
docs/libssh2_agent_init.3 Normal file
View File

@@ -0,0 +1,26 @@
.\"
.\" Copyright (c) 2009 by Daiki Ueno
.\"
.TH libssh2_agent_init 3 "23 Dec 2009" "libssh2 1.2" "libssh2 manual"
.SH NAME
libssh2_agent_init - init an ssh-agent handle
.SH SYNOPSIS
#include <libssh2.h>
LIBSSH2_AGENT *libssh2_agent_init(LIBSSH2_SESSION *session);
.SH DESCRIPTION
Init an ssh-agent handle. Returns the handle to an internal
representation of an ssh-agent connection. After the successful
initialization, an application can call \fBlibssh2_agent_connect(3)\fP
to connect to a running ssh-agent.
Call \fBlibssh2_agent_free(3)\fP to free the handle again after you're
doing using it.
.SH RETURN VALUE
Returns a handle pointer or NULL if something went wrong. The returned handle
is used as input to all other ssh-agent related functions libssh2 provides.
.SH AVAILABILITY
Added in libssh2 1.2
.SH SEE ALSO
.BR libssh2_agent_connect(3)
.BR libssh2_agent_free(3)

View File

@@ -0,0 +1,24 @@
.\"
.\" Copyright (c) 2009 by Daiki Ueno
.\"
.TH libssh2_agent_list_identities 3 "23 Dec 2009" "libssh2 1.2" "libssh2 manual"
.SH NAME
libssh2_agent_list_identities - request an ssh-agent to list of public keys.
.SH SYNOPSIS
#include <libssh2.h>
int libssh2_agent_list_identities(LIBSSH2_AGENT *agent);
.SH DESCRIPTION
Request an ssh-agent to list of public keys, and stores them in the
internal collection of the handle. Call
\fIlibssh2_agent_get_identity(3)\fP to get a public key off the
collection.
.SH RETURN VALUE
Returns 0 if succeeded, or a negative value for error.
.SH AVAILABILITY
Added in libssh2 1.2
.SH SEE ALSO
.BR libssh2_agent_connect(3)
.BR libssh2_agent_get_identity(3)

View File

@@ -0,0 +1,29 @@
.\"
.\" Copyright (c) 2009 by Daiki Ueno
.\"
.TH libssh2_agent_userauth 3 "23 Dec 2009" "libssh2 1.2" "libssh2 manual"
.SH NAME
libssh2_agent_userauth - authenticate a session with a public key, with the help of ssh-agent
.SH SYNOPSIS
#include <libssh2.h>
int libssh2_agent_userauth(LIBSSH2_AGENT *agent,
const char *username,
struct libssh2_agent_publickey *identity);
.SH DESCRIPTION
\fIagent\fP - ssh-agent handle as returned by
.BR libssh2_agent_init(3)
\fIusername\fP - Remote user name to authenticate as.
\fIidentity\fP - Public key to authenticate with, as returned by
.BR libssh2_agent_get_identity(3)
Attempt public key authentication with the help of ssh-agent.
.SH RETURN VALUE
Returns 0 if succeeded, or a negative value for error.
.SH AVAILABILITY
Added in libssh2 1.2
.SH SEE ALSO
.BR libssh2_agent_init(3)
.BR libssh2_agent_get_identity(3)

View File

@@ -0,0 +1,20 @@
.\"
.\" Copyright (c) 2009 by Daniel Stenberg
.\"
.TH libssh2_knownhost_free 3 "28 May 2009" "libssh2 1.2" "libssh2 manual"
.SH NAME
libssh2_knownhost_free - free a collection of known hosts
.SH SYNOPSIS
#include <libssh2.h>
void libssh2_knownhost_free(LIBSSH2_KNOWNHOSTS *hosts);
.SH DESCRIPTION
Free a collection of known hosts.
.SH RETURN VALUE
None.
.SH AVAILABILITY
Added in libssh2 1.2
.SH SEE ALSO
.BR libssh2_knownhost_init(3)
.BR libssh2_knownhost_add(3)
.BR libssh2_knownhost_check(3)

View File

@@ -11,6 +11,9 @@ LIBSSH2_KNOWNHOSTS *libssh2_knownhost_init(LIBSSH2_SESSION *session);
.SH DESCRIPTION
Init a collection of known hosts for this session. Returns the handle to an
internal representation of a known host collection.
Call \fBlibssh2_knownhost_free(3)\fP to free the collection again after you're
doing using it.
.SH RETURN VALUE
Returns a handle pointer or NULL if something went wrong. The returned handle
is used as input to all other known host related functions libssh2 provides.

View File

@@ -11,21 +11,26 @@ ssize_t
libssh2_sftp_write(LIBSSH2_SFTP_HANDLE *handle, const char *buffer, size_t count);
.SH DESCRIPTION
\fIhandle\fP - SFTP File Handle as returned by
.BR libssh2_sftp_open_ex(3)
\fIhandle\fP - SFTP file handle as returned by \fIlibssh2_sftp_open_ex(3)\fP.
\fIbuffer\fP - Pre-initialized data buffer to write to the LIBSSH2_SFTP_HANDLE.
\fIbuffer\fP - points to the data to send off
\fIcount\fP - Number of bytes from buffer to write. Note that it may not
be possible to write all bytes as requested.
Write a block of data to a LIBSSH2_SFTP_HANDLE. This method is modeled after the POSIX write() function and uses the same calling semantics.
\fIcount\fP - Number of bytes from 'buffer' to write. Note that it may not be
possible to write all bytes as requested.
\fBlibssh2_sftp_write(3)\fP writes a block of data to the SFTP server. This
method is modeled after the POSIX write() function and uses the same calling
semantics.
.SH RETURN VALUE
Actual number of bytes written or negative on failure. It returns
LIBSSH2_ERROR_EAGAIN when it would otherwise block. While
LIBSSH2_ERROR_EAGAIN is a negative number, it isn't really a failure per se.
Actual number of bytes written or negative on failure.
If used in non-blocking mode, it returns LIBSSH2_ERROR_EAGAIN when it would
otherwise block. While LIBSSH2_ERROR_EAGAIN is a negative number, it isn't
really a failure per se.
If this function returns 0 (zero) it should not be considered an error, but
simply that there was no error but yet no payload data got sent to the other
end.
.SH ERRORS
\fILIBSSH2_ERROR_ALLOC\fP - An internal memory allocation call failed.
@@ -36,6 +41,5 @@ LIBSSH2_ERROR_EAGAIN is a negative number, it isn't really a failure per se.
\fILIBSSH2_ERROR_SFTP_PROTOCOL\fP - An invalid SFTP protocol response was
received on the socket, or an SFTP operation caused an errorcode to
be returned by the server.
.SH SEE ALSO
.BR libssh2_sftp_open_ex(3)

View File

@@ -6,16 +6,18 @@ libssh2_trace - enable debug info from inside libssh2
.SH SYNOPSIS
#include <libssh2.h>
void libssh2_trace(int bitmask);
void libssh2_trace(LIBSSH2_SESSION *session, int bitmask);
.SH DESCRIPTION
This is a function present in the library that can be used to get debug info
from within libssh2 when it is running. Helpful when trying to trace or debug
behaviors. This function has no effect unless libssh2 was built to support
this option, and a typical "release build" might not.
behaviors. Note that this function has no effect unless libssh2 was built to
support tracing! It is usually disabled in release builds.
\fBbitmask\fP can be set to none, one or more of these bits:
\fBbitmask\fP can be set to the logical OR of none, one or more of these:
.RS
.IP LIBSSH2_TRACE_SOCKET
Socket low-level debugging
.IP LIBSSH2_TRACE_TRANS
Transport layer debugging
.IP LIBSSH2_TRACE_KEX

View File

@@ -0,0 +1,30 @@
.\" $Id: libssh2_trace_sethandler.3,v 1.1 2008/12/26 07:46:45 bagder Exp $
.\"
.TH libssh2_trace_sethandler 3 "15 Jan 2010" "libssh2 1.2.3" "libssh2 manual"
.SH NAME
libssh2_trace_sethandler - set a trace output handler
.SH SYNOPSIS
.nf
#include <libssh2.h>
typedef void (*libssh2_trace_handler_func)(LIBSSH2_SESSION *session,
void* context,
const char *data,
size_t length);
int libssh2_trace_sethandler(LIBSSH2_SESSION *session,
void* context,
libssh2_trace_handler_func callback);
.SH DESCRIPTION
libssh2_trace_sethandler installs a trace output handler for your application.
By default, when tracing has been switched on via a call to libssh2_trace(),
all output is written to stderr. By calling this method and passing a
function pointer that matches the libssh2_trace_handler_func prototype,
libssh2 will call back as it generates trace output. This can be used to
capture the trace output and put it into a log file or diagnostic window.
This function has no effect unless libssh2 was built to support this option,
and a typical "release build" might not.
\fBcontext\fP can be used to pass arbitrary user defined data back into the callback when invoked.
.SH AVAILABILITY
Added in libssh2 version 1.2.3

View File

@@ -39,5 +39,7 @@ LIBSSH2_ERROR_EAGAIN is a negative number, it isn't really a failure per se.
\fILIBSSH2_ERROR_SOCKET_SEND\fP - Unable to send data on socket.
\fLIBSSH2_ERROR_AUTHENTICATION_FAILED\fP - failed, invalid username/password or public/private key.
.SH SEE ALSO
.BR libssh2_session_init_ex(3)

View File

@@ -46,5 +46,7 @@ LIBSSH2_ERROR_EAGAIN is a negative number, it isn't really a failure per se.
\fILIBSSH2_ERROR_PASSWORD_EXPIRED\fP -
\fLIBSSH2_ERROR_AUTHENTICATION_FAILED\fP - failed, invalid username/password or public/private key.
.SH SEE ALSO
.BR libssh2_session_init_ex(3)

View File

@@ -40,12 +40,11 @@ LIBSSH2_ERROR_EAGAIN is a negative number, it isn't really a failure per se.
\fILIBSSH2_ERROR_SOCKET_TIMEOUT\fP -
\fILIBSSH2_ERROR_PUBLICKEY_UNRECOGNIZED\fP - >The username/public key
\fILIBSSH2_ERROR_PUBLICKEY_UNVERIFIED\fP - The username/public key
combination was invalid.
\fILIBSSH2_ERROR_PUBLICKEY_UNVERIFIED\fP - The username/public key
combination was invalid, or the signature for the supplied public
key was invalid.
\fILIBSSH2_ERROR_AUTHENTICATION_FAILED\fP - Authentication using the supplied
public key was not accepted.
.SH SEE ALSO
.BR libssh2_session_init_ex(3)

23
example/.gitignore vendored
View File

@@ -1,2 +1,25 @@
Makefile
Makefile.in
*.gcno
*.gcda
direct_tcpip
scp
scp_nonblock
scp_write
scp_write_nonblock
sftp
sftp_nonblock
sftpdir
sftpdir_nonblock
ssh2
sftp_RW_nonblock
sftp_mkdir
sftp_mkdir_nonblock
sftp_write
sftp_write_nonblock
config.h.in
ssh2_exec
ssh2_agent
libssh2_config.h
libssh2_config.h.in
stamp-h2

View File

@@ -1,2 +1,16 @@
AUTOMAKE_OPTIONS = foreign nostdinc
SUBDIRS = simple
EXTRA_DIST = libssh2_config.h.in
# samples
noinst_PROGRAMS = direct_tcpip ssh2 \
scp scp_nonblock \
scp_write scp_write_nonblock \
sftp sftp_nonblock \
sftp_write sftp_write_nonblock \
sftp_mkdir sftp_mkdir_nonblock \
sftp_RW_nonblock \
sftpdir sftpdir_nonblock ssh2_exec ssh2_agent
AM_CPPFLAGS = -I$(top_srcdir)/include -I$(top_builddir)/example
LDADD = $(top_builddir)/src/libssh2.la

275
example/direct_tcpip.c Normal file
View File

@@ -0,0 +1,275 @@
#include <libssh2.h>
#ifdef WIN32
#include <windows.h>
#include <winsock2.h>
#include <ws2tcpip.h>
#else
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <sys/time.h>
#endif
#include <fcntl.h>
#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#ifndef INADDR_NONE
#define INADDR_NONE (in_addr_t)-1
#endif
const char *keyfile1 = "/home/username/.ssh/id_rsa.pub";
const char *keyfile2 = "/home/username/.ssh/id_rsa";
const char *username = "username";
const char *password = "";
const char *server_ip = "127.0.0.1";
const char *local_listenip = "127.0.0.1";
unsigned int local_listenport = 2222;
const char *remote_desthost = "localhost"; /* resolved by the server */
unsigned int remote_destport = 22;
enum {
AUTH_NONE = 0,
AUTH_PASSWORD,
AUTH_PUBLICKEY
};
int main(int argc, char *argv[])
{
int rc, sock = -1, listensock = -1, forwardsock = -1, i, auth = AUTH_NONE;
struct sockaddr_in sin;
socklen_t sinlen;
const char *fingerprint;
char *userauthlist;
LIBSSH2_SESSION *session;
LIBSSH2_CHANNEL *channel = NULL;
const char *shost;
unsigned int sport;
fd_set fds;
struct timeval tv;
ssize_t len, wr;
char buf[16384];
#ifdef WIN32
char sockopt;
WSADATA wsadata;
WSAStartup(MAKEWORD(2,0), &wsadata);
#else
int sockopt;
#endif
if (argc > 1)
server_ip = argv[1];
if (argc > 2)
username = argv[2];
if (argc > 3)
password = argv[3];
if (argc > 4)
local_listenip = argv[4];
if (argc > 5)
local_listenport = atoi(argv[5]);
if (argc > 6)
remote_desthost = argv[6];
if (argc > 7)
remote_destport = atoi(argv[7]);
/* Connect to SSH server */
sock = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP);
sin.sin_family = AF_INET;
if (INADDR_NONE == (sin.sin_addr.s_addr = inet_addr(server_ip))) {
perror("inet_addr");
return -1;
}
sin.sin_port = htons(22);
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) {
fprintf(stderr, "Could not initialize SSH session!\n");
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, "Error when starting up 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_SHA1);
fprintf(stderr, "Fingerprint: ");
for(i = 0; i < 20; i++)
fprintf(stderr, "%02X ", (unsigned char)fingerprint[i]);
fprintf(stderr, "\n");
/* check what authentication methods are available */
userauthlist = libssh2_userauth_list(session, username, strlen(username));
printf("Authentication methods: %s\n", userauthlist);
if (strstr(userauthlist, "password"))
auth |= AUTH_PASSWORD;
if (strstr(userauthlist, "publickey"))
auth |= AUTH_PUBLICKEY;
/* check for options */
if(argc > 8) {
if ((auth & AUTH_PASSWORD) && !strcasecmp(argv[8], "-p"))
auth = AUTH_PASSWORD;
if ((auth & AUTH_PUBLICKEY) && !strcasecmp(argv[8], "-k"))
auth = AUTH_PUBLICKEY;
}
if (auth & AUTH_PASSWORD) {
if (libssh2_userauth_password(session, username, password)) {
fprintf(stderr, "Authentication by password failed.\n");
goto shutdown;
}
} else if (auth & AUTH_PUBLICKEY) {
if (libssh2_userauth_publickey_fromfile(session, username, keyfile1, keyfile2, password)) {
printf("\tAuthentication by public key failed!\n");
goto shutdown;
}
printf("\tAuthentication by public key succeeded.\n");
} else {
printf("No supported authentication methods found!\n");
goto shutdown;
}
listensock = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP);
sin.sin_family = AF_INET;
sin.sin_port = htons(local_listenport);
if (INADDR_NONE == (sin.sin_addr.s_addr = inet_addr(local_listenip))) {
perror("inet_addr");
goto shutdown;
}
sockopt = 1;
setsockopt(listensock, SOL_SOCKET, SO_REUSEADDR, &sockopt, sizeof(sockopt));
sinlen=sizeof(sin);
if (-1 == bind(listensock, (struct sockaddr *)&sin, sinlen)) {
perror("bind");
goto shutdown;
}
if (-1 == listen(listensock, 2)) {
perror("listen");
goto shutdown;
}
printf("Waiting for TCP connection on %s:%d...\n",
inet_ntoa(sin.sin_addr), ntohs(sin.sin_port));
forwardsock = accept(listensock, (struct sockaddr *)&sin, &sinlen);
if (-1 == forwardsock) {
perror("accept");
goto shutdown;
}
shost = inet_ntoa(sin.sin_addr);
sport = ntohs(sin.sin_port);
printf("Forwarding connection from %s:%d here to remote %s:%d\n", shost,
sport, remote_desthost, remote_destport);
channel = libssh2_channel_direct_tcpip_ex(session, remote_desthost,
remote_destport, shost, sport);
if (!channel) {
fprintf(stderr, "Could not open the direct-tcpip channel!\n");
fprintf(stderr, "(Note that this can be a problem at the server! Please review the server logs.)\n");
goto shutdown;
}
/* Must use non-blocking IO hereafter due to the current libssh2 API */
libssh2_session_set_blocking(session, 0);
while (1) {
FD_ZERO(&fds);
FD_SET(forwardsock, &fds);
tv.tv_sec = 0;
tv.tv_usec = 100000;
rc = select(forwardsock + 1, &fds, NULL, NULL, &tv);
if (-1 == rc) {
perror("select");
goto shutdown;
}
if (rc && FD_ISSET(forwardsock, &fds)) {
len = recv(forwardsock, buf, sizeof(buf), 0);
if (len < 0) {
perror("read");
goto shutdown;
} else if (0 == len) {
printf("The client at %s:%d disconnected!\n", shost, sport);
goto shutdown;
}
wr = 0;
do {
i = libssh2_channel_write(channel, buf, len);
if (i < 0) {
fprintf(stderr, "libssh2_channel_write: %d\n", i);
goto shutdown;
}
wr += i;
} while(i > 0 && wr < len);
}
while (1) {
len = libssh2_channel_read(channel, buf, sizeof(buf));
if (LIBSSH2_ERROR_EAGAIN == len)
break;
else if (len < 0) {
fprintf(stderr, "libssh2_channel_read: %d", (int)len);
goto shutdown;
}
wr = 0;
while (wr < len) {
i = send(forwardsock, buf + wr, len - wr, 0);
if (i <= 0) {
perror("write");
goto shutdown;
}
wr += i;
}
if (libssh2_channel_eof(channel)) {
printf("The server at %s:%d disconnected!\n",
remote_desthost, remote_destport);
goto shutdown;
}
}
}
shutdown:
#ifdef WIN32
closesocket(forwardsock);
closesocket(listensock);
#else
close(forwardsock);
close(listensock);
#endif
if (channel)
libssh2_channel_free(channel);
libssh2_session_disconnect(session, "Client disconnecting normally");
libssh2_session_free(session);
#ifdef WIN32
closesocket(sock);
#else
close(sock);
#endif
return 0;
}

View File

@@ -103,9 +103,9 @@ int main(int argc, char *argv[])
* may have it hard coded, may go to a file, may present it to the
* user, that's your call
*/
fingerprint = libssh2_hostkey_hash(session, LIBSSH2_HOSTKEY_HASH_MD5);
fingerprint = libssh2_hostkey_hash(session, LIBSSH2_HOSTKEY_HASH_SHA1);
fprintf(stderr, "Fingerprint: ");
for(i = 0; i < 16; i++) {
for(i = 0; i < 20; i++) {
fprintf(stderr, "%02X ", (unsigned char)fingerprint[i]);
}
fprintf(stderr, "\n");

View File

@@ -160,9 +160,9 @@ int main(int argc, char *argv[])
* may have it hard coded, may go to a file, may present it to the
* user, that's your call
*/
fingerprint = libssh2_hostkey_hash(session, LIBSSH2_HOSTKEY_HASH_MD5);
fingerprint = libssh2_hostkey_hash(session, LIBSSH2_HOSTKEY_HASH_SHA1);
fprintf(stderr, "Fingerprint: ");
for(i = 0; i < 16; i++) {
for(i = 0; i < 20; i++) {
fprintf(stderr, "%02X ", (unsigned char)fingerprint[i]);
}
fprintf(stderr, "\n");

View File

@@ -118,9 +118,9 @@ int main(int argc, char *argv[])
* may have it hard coded, may go to a file, may present it to the
* user, that's your call
*/
fingerprint = libssh2_hostkey_hash(session, LIBSSH2_HOSTKEY_HASH_MD5);
fingerprint = libssh2_hostkey_hash(session, LIBSSH2_HOSTKEY_HASH_SHA1);
fprintf(stderr, "Fingerprint: ");
for(i = 0; i < 16; i++) {
for(i = 0; i < 20; i++) {
fprintf(stderr, "%02X ", (unsigned char)fingerprint[i]);
}
fprintf(stderr, "\n");
@@ -142,8 +142,8 @@ int main(int argc, char *argv[])
}
}
/* Request a file via SCP */
channel = libssh2_scp_send(session, scppath, 0x1FF & fileinfo.st_mode,
/* Send a file via scp. The mode parameter must only have permissions! */
channel = libssh2_scp_send(session, scppath, fileinfo.st_mode & 0777,
(unsigned long)fileinfo.st_size);
if (!channel) {

View File

@@ -126,9 +126,9 @@ int main(int argc, char *argv[])
* may have it hard coded, may go to a file, may present it to the
* user, that's your call
*/
fingerprint = libssh2_hostkey_hash(session, LIBSSH2_HOSTKEY_HASH_MD5);
fingerprint = libssh2_hostkey_hash(session, LIBSSH2_HOSTKEY_HASH_SHA1);
fprintf(stderr, "Fingerprint: ");
for(i = 0; i < 16; i++) {
for(i = 0; i < 20; i++) {
fprintf(stderr, "%02X ", (unsigned char)fingerprint[i]);
}
fprintf(stderr, "\n");
@@ -153,9 +153,9 @@ int main(int argc, char *argv[])
}
}
/* Request a file via SCP */
/* Send a file via scp. The mode parameter must only have permissions! */
do {
channel = libssh2_scp_send(session, scppath, 0x1FF & fileinfo.st_mode,
channel = libssh2_scp_send(session, scppath, fileinfo.st_mode & 0777,
(unsigned long)fileinfo.st_size);
if ((!channel) && (libssh2_session_last_errno(session) !=

View File

@@ -136,9 +136,9 @@ int main(int argc, char *argv[])
* may have it hard coded, may go to a file, may present it to the
* user, that's your call
*/
fingerprint = libssh2_hostkey_hash(session, LIBSSH2_HOSTKEY_HASH_MD5);
fingerprint = libssh2_hostkey_hash(session, LIBSSH2_HOSTKEY_HASH_SHA1);
fprintf(stderr, "Fingerprint: ");
for(i = 0; i < 16; i++) {
for(i = 0; i < 20; i++) {
fprintf(stderr, "%02X ", (unsigned char)fingerprint[i]);
}
fprintf(stderr, "\n");

View File

@@ -109,9 +109,9 @@ int main(int argc, char *argv[])
* may have it hard coded, may go to a file, may present it to the
* user, that's your call
*/
fingerprint = libssh2_hostkey_hash(session, LIBSSH2_HOSTKEY_HASH_MD5);
fingerprint = libssh2_hostkey_hash(session, LIBSSH2_HOSTKEY_HASH_SHA1);
printf("Fingerprint: ");
for(i = 0; i < 16; i++) {
for(i = 0; i < 20; i++) {
printf("%02X ", (unsigned char)fingerprint[i]);
}
printf("\n");

View File

@@ -105,9 +105,9 @@ int main(int argc, char *argv[])
* may have it hard coded, may go to a file, may present it to the
* user, that's your call
*/
fingerprint = libssh2_hostkey_hash(session, LIBSSH2_HOSTKEY_HASH_MD5);
fingerprint = libssh2_hostkey_hash(session, LIBSSH2_HOSTKEY_HASH_SHA1);
printf("Fingerprint: ");
for(i = 0; i < 16; i++) {
for(i = 0; i < 20; i++) {
printf("%02X ", (unsigned char)fingerprint[i]);
}
printf("\n");

View File

@@ -108,9 +108,9 @@ int main(int argc, char *argv[])
* may have it hard coded, may go to a file, may present it to the
* user, that's your call
*/
fingerprint = libssh2_hostkey_hash(session, LIBSSH2_HOSTKEY_HASH_MD5);
fingerprint = libssh2_hostkey_hash(session, LIBSSH2_HOSTKEY_HASH_SHA1);
printf("Fingerprint: ");
for(i = 0; i < 16; i++) {
for(i = 0; i < 20; i++) {
printf("%02X ", (unsigned char)fingerprint[i]);
}
printf("\n");

View File

@@ -161,9 +161,9 @@ int main(int argc, char *argv[])
* may have it hard coded, may go to a file, may present it to the
* user, that's your call
*/
fingerprint = libssh2_hostkey_hash(session, LIBSSH2_HOSTKEY_HASH_MD5);
fingerprint = libssh2_hostkey_hash(session, LIBSSH2_HOSTKEY_HASH_SHA1);
fprintf(stderr, "Fingerprint: ");
for(i = 0; i < 16; i++) {
for(i = 0; i < 20; i++) {
fprintf(stderr, "%02X ", (unsigned char)fingerprint[i]);
}
fprintf(stderr, "\n");

View File

@@ -123,9 +123,9 @@ int main(int argc, char *argv[])
* may have it hard coded, may go to a file, may present it to the
* user, that's your call
*/
fingerprint = libssh2_hostkey_hash(session, LIBSSH2_HOSTKEY_HASH_MD5);
fingerprint = libssh2_hostkey_hash(session, LIBSSH2_HOSTKEY_HASH_SHA1);
printf("Fingerprint: ");
for(i = 0; i < 16; i++) {
for(i = 0; i < 20; i++) {
printf("%02X ", (unsigned char)fingerprint[i]);
}
printf("\n");

View File

@@ -127,9 +127,9 @@ int main(int argc, char *argv[])
* have it hard coded, may go to a file, may present it to the user,
* that's your call
*/
fingerprint = libssh2_hostkey_hash(session, LIBSSH2_HOSTKEY_HASH_MD5);
fingerprint = libssh2_hostkey_hash(session, LIBSSH2_HOSTKEY_HASH_SHA1);
printf("Fingerprint: ");
for(i = 0; i < 16; i++) {
for(i = 0; i < 20; i++) {
printf("%02X ", (unsigned char)fingerprint[i]);
}
printf("\n");

View File

@@ -105,9 +105,9 @@ int main(int argc, char *argv[])
* may have it hard coded, may go to a file, may present it to the
* user, that's your call
*/
fingerprint = libssh2_hostkey_hash(session, LIBSSH2_HOSTKEY_HASH_MD5);
fingerprint = libssh2_hostkey_hash(session, LIBSSH2_HOSTKEY_HASH_SHA1);
printf("Fingerprint: ");
for(i = 0; i < 16; i++) {
for(i = 0; i < 20; i++) {
printf("%02X ", (unsigned char)fingerprint[i]);
}
printf("\n");

View File

@@ -111,9 +111,9 @@ int main(int argc, char *argv[])
* may have it hard coded, may go to a file, may present it to the
* user, that's your call
*/
fingerprint = libssh2_hostkey_hash(session, LIBSSH2_HOSTKEY_HASH_MD5);
fingerprint = libssh2_hostkey_hash(session, LIBSSH2_HOSTKEY_HASH_SHA1);
printf("Fingerprint: ");
for(i = 0; i < 16; i++) {
for(i = 0; i < 20; i++) {
printf("%02X ", (unsigned char)fingerprint[i]);
}
printf("\n");

View File

@@ -1,18 +0,0 @@
*.gcno
*.gcda
scp
scp_nonblock
scp_write
scp_write_nonblock
sftp
sftp_nonblock
sftpdir
sftpdir_nonblock
ssh2
sftp_RW_nonblock
sftp_mkdir
sftp_mkdir_nonblock
sftp_write
sftp_write_nonblock
config.h.in
ssh2_exec

View File

@@ -1,16 +0,0 @@
AUTOMAKE_OPTIONS = foreign nostdinc
# samples
noinst_PROGRAMS = ssh2 \
scp scp_nonblock \
scp_write scp_write_nonblock \
sftp sftp_nonblock \
sftp_write sftp_write_nonblock \
sftp_mkdir sftp_mkdir_nonblock \
sftp_RW_nonblock \
sftpdir sftpdir_nonblock ssh2_exec
# the examples need the $(top_builddir)/src since when building outside of the
# source dir they still need to reach the libssh2_config.h header
AM_CPPFLAGS = -I$(top_srcdir)/src -I$(top_srcdir)/include -I$(top_builddir)/src
LDADD = $(top_builddir)/src/libssh2.la

View File

@@ -121,9 +121,9 @@ int main(int argc, char *argv[])
* hard coded, may go to a file, may present it to the user, that's your
* call
*/
fingerprint = libssh2_hostkey_hash(session, LIBSSH2_HOSTKEY_HASH_MD5);
fingerprint = libssh2_hostkey_hash(session, LIBSSH2_HOSTKEY_HASH_SHA1);
printf("Fingerprint: ");
for(i = 0; i < 16; i++) {
for(i = 0; i < 20; i++) {
printf("%02X ", (unsigned char)fingerprint[i]);
}
printf("\n");

229
example/ssh2_agent.c Normal file
View File

@@ -0,0 +1,229 @@
/*
* Sample showing how to do SSH2 connect using ssh-agent.
*
* The sample code has default values for host name, user name:
*
* "ssh2_agent host user"
*/
#include "libssh2_config.h"
#include <libssh2.h>
#include <libssh2_sftp.h>
#ifdef HAVE_WINDOWS_H
# include <windows.h>
#endif
#ifdef HAVE_WINSOCK2_H
# include <winsock2.h>
#endif
#ifdef HAVE_SYS_SOCKET_H
# include <sys/socket.h>
#endif
#ifdef HAVE_NETINET_IN_H
# include <netinet/in.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>
#include <stdlib.h>
const char *username="username";
int main(int argc, char *argv[])
{
unsigned long hostaddr;
int sock = -1, i, j, rc;
struct sockaddr_in sin;
const char *fingerprint;
char *userauthlist;
LIBSSH2_SESSION *session;
LIBSSH2_CHANNEL *channel;
LIBSSH2_AGENT *agent = NULL;
struct libssh2_agent_publickey *identity, *prev_identity = NULL;
#ifdef WIN32
WSADATA wsadata;
WSAStartup(MAKEWORD(2,0), &wsadata);
#endif
if (argc > 1) {
hostaddr = inet_addr(argv[1]);
} else {
hostaddr = htonl(0x7F000001);
}
if(argc > 2) {
username = argv[2];
}
/* 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);
if (sock == -1) {
fprintf(stderr, "failed to create socket!\n");
rc = 1;
goto shutdown;
}
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");
goto shutdown;
}
/* 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;
}
/* check what authentication methods are available */
userauthlist = libssh2_userauth_list(session, username, strlen(username));
printf("Authentication methods: %s\n", userauthlist);
if (strstr(userauthlist, "publickey") == NULL) {
fprintf(stderr, "\"publickey\" authentication is not supported\n");
goto shutdown;
}
/* Connect to the ssh-agent */
agent = libssh2_agent_init(session);
if (!agent) {
fprintf(stderr, "Failure initializing ssh-agent support\n");
rc = 1;
goto shutdown;
}
if (libssh2_agent_connect(agent)) {
fprintf(stderr, "Failure connecting to ssh-agent\n");
rc = 1;
goto shutdown;
}
if (libssh2_agent_list_identities(agent)) {
fprintf(stderr, "Failure requesting identities to ssh-agent\n");
rc = 1;
goto shutdown;
}
while (1) {
rc = libssh2_agent_get_identity(agent, &identity, prev_identity);
if (rc == 1)
break;
if (rc < 0) {
fprintf(stderr,
"Failure obtaining identity from ssh-agent support\n");
rc = 1;
goto shutdown;
}
if (libssh2_agent_userauth(agent, username, identity)) {
printf("\tAuthentication with username %s and "
"public key %s failed!\n",
username, identity->comment);
} else {
printf("\tAuthentication with username %s and "
"public key %s succeeded!\n",
username, identity->comment);
break;
}
prev_identity = identity;
}
if (rc) {
fprintf(stderr, "Couldn't continue authentication\n");
goto shutdown;
}
/* 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_SHA1);
printf("Fingerprint: ");
for(i = 0; i < 20; i++) {
printf("%02X ", (unsigned char)fingerprint[i]);
}
printf("\n");
/* Request a shell */
if (!(channel = libssh2_channel_open_session(session))) {
fprintf(stderr, "Unable to open a session\n");
goto shutdown;
}
/* Some environment variables may be set,
* It's up to the server which ones it'll allow though
*/
libssh2_channel_setenv(channel, "FOO", "bar");
/* Request a terminal with 'vanilla' terminal emulation
* See /etc/termcap for more options
*/
if (libssh2_channel_request_pty(channel, "vanilla")) {
fprintf(stderr, "Failed requesting pty\n");
goto skip_shell;
}
/* Open a SHELL on that pty */
if (libssh2_channel_shell(channel)) {
fprintf(stderr, "Unable to request shell on allocated pty\n");
goto shutdown;
}
/* 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_agent_disconnect(agent);
libssh2_agent_free(agent);
libssh2_session_disconnect(session,
"Normal Shutdown, Thank you for playing");
libssh2_session_free(session);
if (sock != -1) {
#ifdef WIN32
closesocket(sock);
#else
close(sock);
#endif
}
printf("all done!\n");
return rc;
}

View File

@@ -84,17 +84,17 @@ typedef unsigned long long libssh2_uint64_t;
typedef long long libssh2_int64_t;
#endif
/* We use underscore instead of dash when appending CVS in dev versions just
/* We use underscore instead of dash when appending DEV in dev versions just
to make the BANNER define (used by src/session.c) be a valid SSH
banner. Release versions have no appended strings and may of course not
have dashes either. */
#define LIBSSH2_VERSION "1.2.1_CVS"
#define LIBSSH2_VERSION "1.2.4_DEV"
/* The numeric version number is also available "in parts" by using these
defines: */
#define LIBSSH2_VERSION_MAJOR 1
#define LIBSSH2_VERSION_MINOR 2
#define LIBSSH2_VERSION_PATCH 1
#define LIBSSH2_VERSION_PATCH 4
/* This is the numeric version of the libssh2 version number, meant for easier
parsing and comparions by programs. The LIBSSH2_VERSION_NUM define will
@@ -111,18 +111,18 @@ typedef long long libssh2_int64_t;
and it is always a greater number in a more recent release. It makes
comparisons with greater than and less than work.
*/
#define LIBSSH2_VERSION_NUM 0x010201
#define LIBSSH2_VERSION_NUM 0x010204
/*
* This is the date and time when the full source package was created. The
* timestamp is not stored in CVS, as the timestamp is properly set in the
* tarballs by the maketgz script.
* timestamp is not stored in the source code repo, as the timestamp is
* properly set in the tarballs by the maketgz script.
*
* The format of the date should follow this template:
*
* "Mon Feb 12 11:35:33 UTC 2007"
*/
#define LIBSSH2_TIMESTAMP "CVS"
#define LIBSSH2_TIMESTAMP "DEV"
/* Part of every banner, user specified or not */
#define LIBSSH2_SSH_BANNER "SSH-2.0-libssh2_" LIBSSH2_VERSION
@@ -178,6 +178,11 @@ typedef struct _LIBSSH2_USERAUTH_KBDINT_RESPONSE
unsigned int length;
} LIBSSH2_USERAUTH_KBDINT_RESPONSE;
/* 'publickey' authentication callback */
#define LIBSSH2_USERAUTH_PUBLICKEY_SIGN_FUNC(name) \
int name(LIBSSH2_SESSION *session, unsigned char **sig, size_t *sig_len, \
const unsigned char *data, size_t data_len, void **abstract)
/* 'keyboard-interactive' authentication callback */
#define LIBSSH2_USERAUTH_KBDINT_RESPONSE_FUNC(name_) \
void name_(const char* name, int name_len, const char* instruction, \
@@ -242,6 +247,7 @@ typedef struct _LIBSSH2_SESSION LIBSSH2_SESSION;
typedef struct _LIBSSH2_CHANNEL LIBSSH2_CHANNEL;
typedef struct _LIBSSH2_LISTENER LIBSSH2_LISTENER;
typedef struct _LIBSSH2_KNOWNHOSTS LIBSSH2_KNOWNHOSTS;
typedef struct _LIBSSH2_AGENT LIBSSH2_AGENT;
typedef struct _LIBSSH2_POLLFD {
unsigned char type; /* LIBSSH2_POLLFD_* below */
@@ -335,7 +341,8 @@ typedef struct _LIBSSH2_POLLFD {
#define LIBSSH2_ERROR_PASSWORD_EXPIRED -15
#define LIBSSH2_ERROR_FILE -16
#define LIBSSH2_ERROR_METHOD_NONE -17
#define LIBSSH2_ERROR_PUBLICKEY_UNRECOGNIZED -18
#define LIBSSH2_ERROR_AUTHENTICATION_FAILED -18
#define LIBSSH2_ERROR_PUBLICKEY_UNRECOGNIZED LIBSSH2_ERROR_AUTHENTICATION_FAILED
#define LIBSSH2_ERROR_PUBLICKEY_UNVERIFIED -19
#define LIBSSH2_ERROR_CHANNEL_OUTOFORDER -20
#define LIBSSH2_ERROR_CHANNEL_FAILURE -21
@@ -359,6 +366,7 @@ typedef struct _LIBSSH2_POLLFD {
#define LIBSSH2_ERROR_BAD_USE -39
#define LIBSSH2_ERROR_COMPRESS -40
#define LIBSSH2_ERROR_OUT_OF_BOUNDARY -41
#define LIBSSH2_ERROR_AGENT_PROTOCOL -42
/* Session API */
LIBSSH2_API LIBSSH2_SESSION *
@@ -436,6 +444,14 @@ libssh2_userauth_publickey_fromfile_ex(LIBSSH2_SESSION *session,
strlen(username), (publickey), \
(privatekey), (passphrase))
LIBSSH2_API int
libssh2_userauth_publickey(LIBSSH2_SESSION *session,
const char *username,
const unsigned char *pubkeydata,
size_t pubkeydata_len,
LIBSSH2_USERAUTH_PUBLICKEY_SIGN_FUNC((*sign_callback)),
void **abstract);
LIBSSH2_API int
libssh2_userauth_hostbased_fromfile_ex(LIBSSH2_SESSION *session,
const char *username,
@@ -870,6 +886,93 @@ libssh2_knownhost_get(LIBSSH2_KNOWNHOSTS *hosts,
struct libssh2_knownhost **store,
struct libssh2_knownhost *prev);
#define HAVE_LIBSSH2_AGENT_API 0x010202 /* since 1.2.2 */
struct libssh2_agent_publickey {
unsigned int magic; /* magic stored by the library */
void *node; /* handle to the internal representation of key */
unsigned char *blob; /* public key blob */
size_t blob_len; /* length of the public key blob */
char *comment; /* comment in printable format */
};
/*
* libssh2_agent_init
*
* Init an ssh-agent handle. Returns the pointer to the handle.
*
*/
LIBSSH2_API LIBSSH2_AGENT *
libssh2_agent_init(LIBSSH2_SESSION *session);
/*
* libssh2_agent_connect()
*
* Connect to an ssh-agent.
*
* Returns 0 if succeeded, or a negative value for error.
*/
LIBSSH2_API int
libssh2_agent_connect(LIBSSH2_AGENT *agent);
/*
* libssh2_agent_list_identities()
*
* Request an ssh-agent to list identities.
*
* Returns 0 if succeeded, or a negative value for error.
*/
LIBSSH2_API int
libssh2_agent_list_identities(LIBSSH2_AGENT *agent);
/*
* libssh2_agent_get_identity()
*
* Traverse the internal list of public keys. Pass NULL to 'prev' to get
* the first one. Or pass a poiner to the previously returned one to get the
* next.
*
* Returns:
* 0 if a fine public key was stored in 'store'
* 1 if end of public keys
* [negative] on errors
*/
LIBSSH2_API int
libssh2_agent_get_identity(LIBSSH2_AGENT *agent,
struct libssh2_agent_publickey **store,
struct libssh2_agent_publickey *prev);
/*
* libssh2_agent_userauth()
*
* Do publickey user authentication with the help of ssh-agent.
*
* Returns 0 if succeeded, or a negative value for error.
*/
LIBSSH2_API int
libssh2_agent_userauth(LIBSSH2_AGENT *agent,
const char *username,
struct libssh2_agent_publickey *identity);
/*
* libssh2_agent_disconnect()
*
* Close a connection to an ssh-agent.
*
* Returns 0 if succeeded, or a negative value for error.
*/
LIBSSH2_API int
libssh2_agent_disconnect(LIBSSH2_AGENT *agent);
/*
* libssh2_agent_free()
*
* Free an ssh-agent handle. This function also frees the internal
* collection of public keys.
*/
LIBSSH2_API void
libssh2_agent_free(LIBSSH2_AGENT *agent);
/* NOTE NOTE NOTE
libssh2_trace() has no function in builds that aren't built with debug
enabled
@@ -883,6 +986,15 @@ LIBSSH2_API int libssh2_trace(LIBSSH2_SESSION *session, int bitmask);
#define LIBSSH2_TRACE_SFTP (1<<6)
#define LIBSSH2_TRACE_ERROR (1<<7)
#define LIBSSH2_TRACE_PUBLICKEY (1<<8)
#define LIBSSH2_TRACE_SOCKET (1<<9)
typedef void (*libssh2_trace_handler_func)(LIBSSH2_SESSION*,
void*,
const char *,
size_t);
LIBSSH2_API int libssh2_trace_sethandler(LIBSSH2_SESSION *session,
void* context,
libssh2_trace_handler_func callback);
#ifdef __cplusplus
} /* extern "C" */

View File

@@ -1,5 +0,0 @@
libtool.m4
ltoptions.m4
ltsugar.m4
ltversion.m4
lt~obsolete.m4

View File

@@ -28,7 +28,7 @@ endif
LINK_STATIC = 1
# Edit the vars below to change NLM target settings.
SAMPLES = ../../example/simple
SAMPLES = ../../example
TARGETS := $(filter-out x11.nlm,$(patsubst $(SAMPLES)/%.c,%.nlm,$(strip $(wildcard $(SAMPLES)/*.c))))
VERSION = $(LIBSSH2_VERSION)
COPYR = Copyright (c) 2004-2009, Sara Golemon <sarag@libssh2.org>

View File

@@ -1,20 +0,0 @@
.deps
.libs
*.lib
*.pdb
*.dll
*.exe
*.obj
*.gcno
*.gcda
.*.swp
Debug
Release
*.exp
Makefile
Makefile.in
*.lo
libssh2.la
libssh2_config.h
libssh2_config.h.in
stamp-h1

759
src/agent.c Normal file
View File

@@ -0,0 +1,759 @@
/*
* Copyright (c) 2009 by Daiki Ueno
* All rights reserved.
*
* Redistribution and use in source and binary forms,
* with or without modification, are permitted provided
* that the following conditions are met:
*
* Redistributions of source code must retain the above
* copyright notice, this list of conditions and the
* following disclaimer.
*
* Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following
* disclaimer in the documentation and/or other materials
* provided with the distribution.
*
* Neither the name of the copyright holder nor the names
* of any other contributors may be used to endorse or
* promote products derived from this software without
* specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
* CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
* USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
* OF SUCH DAMAGE.
*/
#include "libssh2_priv.h"
#include "misc.h"
#include <errno.h>
#ifdef HAVE_SYS_UN_H
#include <sys/un.h>
#else
/* Use the existence of sys/un.h as a test if Unix domain socket is
supported. winsock*.h define PF_UNIX/AF_UNIX but do not actually
support them. */
#undef PF_UNIX
#endif
/* Requests from client to agent for protocol 1 key operations */
#define SSH_AGENTC_REQUEST_RSA_IDENTITIES 1
#define SSH_AGENTC_RSA_CHALLENGE 3
#define SSH_AGENTC_ADD_RSA_IDENTITY 7
#define SSH_AGENTC_REMOVE_RSA_IDENTITY 8
#define SSH_AGENTC_REMOVE_ALL_RSA_IDENTITIES 9
#define SSH_AGENTC_ADD_RSA_ID_CONSTRAINED 24
/* Requests from client to agent for protocol 2 key operations */
#define SSH2_AGENTC_REQUEST_IDENTITIES 11
#define SSH2_AGENTC_SIGN_REQUEST 13
#define SSH2_AGENTC_ADD_IDENTITY 17
#define SSH2_AGENTC_REMOVE_IDENTITY 18
#define SSH2_AGENTC_REMOVE_ALL_IDENTITIES 19
#define SSH2_AGENTC_ADD_ID_CONSTRAINED 25
/* Key-type independent requests from client to agent */
#define SSH_AGENTC_ADD_SMARTCARD_KEY 20
#define SSH_AGENTC_REMOVE_SMARTCARD_KEY 21
#define SSH_AGENTC_LOCK 22
#define SSH_AGENTC_UNLOCK 23
#define SSH_AGENTC_ADD_SMARTCARD_KEY_CONSTRAINED 26
/* Generic replies from agent to client */
#define SSH_AGENT_FAILURE 5
#define SSH_AGENT_SUCCESS 6
/* Replies from agent to client for protocol 1 key operations */
#define SSH_AGENT_RSA_IDENTITIES_ANSWER 2
#define SSH_AGENT_RSA_RESPONSE 4
/* Replies from agent to client for protocol 2 key operations */
#define SSH2_AGENT_IDENTITIES_ANSWER 12
#define SSH2_AGENT_SIGN_RESPONSE 14
/* Key constraint identifiers */
#define SSH_AGENT_CONSTRAIN_LIFETIME 1
#define SSH_AGENT_CONSTRAIN_CONFIRM 2
/* non-blocking mode on agent connection is not yet implemented, but
for future use. */
typedef enum {
agent_NB_state_init = 0,
agent_NB_state_request_created,
agent_NB_state_request_length_sent,
agent_NB_state_request_sent,
agent_NB_state_response_length_received,
agent_NB_state_response_received
} agent_nonblocking_states;
typedef struct agent_transaction_ctx {
unsigned char *request;
size_t request_len;
unsigned char *response;
size_t response_len;
agent_nonblocking_states state;
} *agent_transaction_ctx_t;
typedef int (*agent_connect_func)(LIBSSH2_AGENT *agent);
typedef int (*agent_transact_func)(LIBSSH2_AGENT *agent,
agent_transaction_ctx_t transctx);
typedef int (*agent_disconnect_func)(LIBSSH2_AGENT *agent);
struct agent_publickey {
struct list_node node;
/* this is the struct we expose externally */
struct libssh2_agent_publickey external;
};
struct agent_ops {
agent_connect_func connect;
agent_transact_func transact;
agent_disconnect_func disconnect;
};
struct _LIBSSH2_AGENT
{
LIBSSH2_SESSION *session; /* the session this "belongs to" */
libssh2_socket_t fd;
struct agent_ops *ops;
struct agent_transaction_ctx transctx;
struct agent_publickey *identity;
struct list_head head; /* list of public keys */
};
#ifdef PF_UNIX
static int
agent_connect_unix(LIBSSH2_AGENT *agent)
{
const char *path;
struct sockaddr_un s_un;
path = getenv("SSH_AUTH_SOCK");
if (!path) {
return -1;
}
agent->fd = socket(PF_UNIX, SOCK_STREAM, 0);
if (agent->fd < 0) {
return -1;
}
s_un.sun_family = AF_UNIX;
strncpy (s_un.sun_path, path, sizeof s_un.sun_path);
if (connect(agent->fd, (struct sockaddr*)(&s_un), sizeof s_un) != 0) {
close (agent->fd);
return -1;
}
return 0;
}
static int
agent_transact_unix(LIBSSH2_AGENT *agent, agent_transaction_ctx_t transctx)
{
unsigned char buf[4], *s;
int rc;
/* Send the length of the request */
if (transctx->state == agent_NB_state_request_created) {
_libssh2_htonu32(buf, transctx->request_len);
rc = send(agent->fd, buf, sizeof buf, 0);
if (rc < 0) {
if (errno == EAGAIN)
return LIBSSH2_ERROR_EAGAIN;
return -1;
}
transctx->state = agent_NB_state_request_length_sent;
}
/* Send the request body */
if (transctx->state == agent_NB_state_request_length_sent) {
rc = send(agent->fd, transctx->request,
transctx->request_len, 0);
if (rc < 0) {
if (errno == EAGAIN)
return LIBSSH2_ERROR_EAGAIN;
return -1;
}
transctx->state = agent_NB_state_request_sent;
}
/* Receive the length of a response */
if (transctx->state == agent_NB_state_request_sent) {
rc = recv(agent->fd, buf, sizeof buf, 0);
if (rc < 0) {
if (errno == EAGAIN)
return LIBSSH2_ERROR_EAGAIN;
return -1;
}
transctx->response_len = _libssh2_ntohu32(buf);
s = transctx->response = LIBSSH2_ALLOC(agent->session,
transctx->response_len);
if (!transctx->response) {
return LIBSSH2_ERROR_ALLOC;
}
transctx->state = agent_NB_state_response_length_received;
}
/* Receive the response body */
if (transctx->state == agent_NB_state_response_length_received) {
rc = recv(agent->fd, transctx->response, transctx->response_len, 0);
if (rc < 0) {
if (errno == EAGAIN)
return LIBSSH2_ERROR_EAGAIN;
return -1;
}
transctx->state = agent_NB_state_response_received;
}
return 0;
}
static int
agent_disconnect_unix(LIBSSH2_AGENT *agent)
{
return close(agent->fd);
}
struct agent_ops agent_ops_unix = {
agent_connect_unix,
agent_transact_unix,
agent_disconnect_unix
};
#endif /* PF_UNIX */
#ifdef WIN32
/* Code to talk to Pageant was taken from PuTTY.
*
* Portions copyright Robert de Bath, Joris van Rantwijk, Delian
* Delchev, Andreas Schultz, Jeroen Massar, Wez Furlong, Nicolas
* Barry, Justin Bradford, Ben Harris, Malcolm Smith, Ahmad Khalifa,
* Markus Kuhn, Colin Watson, and CORE SDI S.A.
*/
#define PAGEANT_COPYDATA_ID 0x804e50ba /* random goop */
#define PAGEANT_MAX_MSGLEN 8192
static int
agent_connect_pageant(LIBSSH2_AGENT *agent)
{
HWND hwnd;
hwnd = FindWindow("Pageant", "Pageant");
if (!hwnd)
return -1;
agent->fd = 0; /* Mark as the connection has been established */
return 0;
}
static int
agent_transact_pageant(LIBSSH2_AGENT *agent, agent_transaction_ctx_t transctx)
{
HWND hwnd;
char mapname[23];
HANDLE filemap;
unsigned char *p;
int id;
COPYDATASTRUCT cds;
if (!transctx || 4 + transctx->request_len > PAGEANT_MAX_MSGLEN) {
return LIBSSH2_ERROR_INVAL;
}
hwnd = FindWindow("Pageant", "Pageant");
if (!hwnd) {
return -1;
}
sprintf(mapname, "PageantRequest%08x", (unsigned)GetCurrentThreadId());
filemap = CreateFileMapping(INVALID_HANDLE_VALUE, NULL, PAGE_READWRITE,
0, PAGEANT_MAX_MSGLEN, mapname);
if (filemap == NULL || filemap == INVALID_HANDLE_VALUE) {
return -1;
}
p = MapViewOfFile(filemap, FILE_MAP_WRITE, 0, 0, 0);
_libssh2_htonu32(p, transctx->request_len);
memcpy(p + 4, transctx->request, transctx->request_len);
cds.dwData = PAGEANT_COPYDATA_ID;
cds.cbData = 1 + strlen(mapname);
cds.lpData = mapname;
id = SendMessage(hwnd, WM_COPYDATA, (WPARAM) NULL, (LPARAM) &cds);
if (id > 0) {
transctx->response_len = _libssh2_ntohu32(p);
if (transctx->response_len > PAGEANT_MAX_MSGLEN) {
UnmapViewOfFile(p);
CloseHandle(filemap);
return LIBSSH2_ERROR_AGENT_PROTOCOL;
}
transctx->response = LIBSSH2_ALLOC(agent->session,
transctx->response_len);
if (!transctx->response) {
UnmapViewOfFile(p);
CloseHandle(filemap);
return LIBSSH2_ERROR_ALLOC;
}
memcpy(transctx->response, p + 4, transctx->response_len);
}
UnmapViewOfFile(p);
CloseHandle(filemap);
return 0;
}
static int
agent_disconnect_pageant(LIBSSH2_AGENT *agent)
{
agent->fd = INVALID_SOCKET;
return 0;
}
struct agent_ops agent_ops_pageant = {
agent_connect_pageant,
agent_transact_pageant,
agent_disconnect_pageant
};
#endif /* WIN32 */
static struct {
const char *name;
struct agent_ops *ops;
} supported_backends[] = {
#ifdef WIN32
{"Pageant", &agent_ops_pageant},
#endif /* WIN32 */
#ifdef PF_UNIX
{"Unix", &agent_ops_unix},
#endif /* PF_UNIX */
{NULL}
};
static int
agent_sign(LIBSSH2_SESSION *session, unsigned char **sig, size_t *sig_len,
const unsigned char *data, size_t data_len, void **abstract)
{
LIBSSH2_AGENT *agent = (LIBSSH2_AGENT *) (*abstract);
agent_transaction_ctx_t transctx = &agent->transctx;
struct agent_publickey *identity = agent->identity;
ssize_t len = 1 + 4 + identity->external.blob_len + 4 + data_len + 4;
ssize_t method_len;
unsigned char *s;
int rc;
/* Create a request to sign the data */
if (transctx->state == agent_NB_state_init) {
s = transctx->request = LIBSSH2_ALLOC(session, len);
if (!transctx->request) {
return LIBSSH2_ERROR_ALLOC;
}
*s++ = SSH2_AGENTC_SIGN_REQUEST;
/* key blob */
_libssh2_htonu32(s, identity->external.blob_len);
s += 4;
memcpy(s, identity->external.blob, identity->external.blob_len);
s += identity->external.blob_len;
/* data */
_libssh2_htonu32(s, data_len);
s += 4;
memcpy(s, data, data_len);
s += data_len;
/* flags */
_libssh2_htonu32(s, 0);
s += 4;
transctx->request_len = s - transctx->request;
transctx->state = agent_NB_state_request_created;
}
/* Make sure to be re-called as a result of EAGAIN. */
if (*transctx->request != SSH2_AGENTC_SIGN_REQUEST) {
return LIBSSH2_ERROR_BAD_USE;
}
rc = agent->ops->transact(agent, transctx);
if (rc) {
goto error;
}
LIBSSH2_FREE(session, transctx->request);
transctx->request = NULL;
len = transctx->response_len;
s = transctx->response;
len--;
if (len < 0) {
rc = LIBSSH2_ERROR_AGENT_PROTOCOL;
goto error;
}
if (*s != SSH2_AGENT_SIGN_RESPONSE) {
rc = LIBSSH2_ERROR_AGENT_PROTOCOL;
goto error;
}
s++;
/* Skip the entire length of the signature */
len -= 4;
if (len < 0) {
rc = LIBSSH2_ERROR_AGENT_PROTOCOL;
goto error;
}
s += 4;
/* Skip signing method */
len -= 4;
if (len < 0) {
rc = LIBSSH2_ERROR_AGENT_PROTOCOL;
goto error;
}
method_len = _libssh2_ntohu32(s);
s += 4;
len -= method_len;
if (len < 0) {
rc = LIBSSH2_ERROR_AGENT_PROTOCOL;
goto error;
}
s += method_len;
/* Read the signature */
len -= 4;
if (len < 0) {
rc = LIBSSH2_ERROR_AGENT_PROTOCOL;
goto error;
}
*sig_len = _libssh2_ntohu32(s);
s += 4;
len -= *sig_len;
if (len < 0) {
rc = LIBSSH2_ERROR_AGENT_PROTOCOL;
goto error;
}
*sig = LIBSSH2_ALLOC(session, *sig_len);
if (!*sig) {
rc = LIBSSH2_ERROR_ALLOC;
goto error;
}
memcpy(*sig, s, *sig_len);
error:
LIBSSH2_FREE(session, transctx->request);
transctx->request = NULL;
LIBSSH2_FREE(session, transctx->response);
transctx->response = NULL;
return rc;
}
static int
agent_list_identities(LIBSSH2_AGENT *agent)
{
agent_transaction_ctx_t transctx = &agent->transctx;
ssize_t len, num_identities;
unsigned char *s;
int rc;
/* Create a request to list identities */
if (transctx->state == agent_NB_state_init) {
unsigned char c = SSH2_AGENTC_REQUEST_IDENTITIES;
transctx->request = &c;
transctx->request_len = 1;
transctx->state = agent_NB_state_request_created;
}
/* Make sure to be re-called as a result of EAGAIN. */
if (*transctx->request != SSH2_AGENTC_REQUEST_IDENTITIES) {
return LIBSSH2_ERROR_BAD_USE;
}
rc = agent->ops->transact(agent, transctx);
if (rc) {
goto error;
}
transctx->request = NULL;
len = transctx->response_len;
s = transctx->response;
len--;
if (len < 0) {
rc = LIBSSH2_ERROR_AGENT_PROTOCOL;
goto error;
}
if (*s != SSH2_AGENT_IDENTITIES_ANSWER) {
rc = LIBSSH2_ERROR_AGENT_PROTOCOL;
goto error;
}
s++;
/* Read the length of identities */
len -= 4;
if (len < 0) {
rc = LIBSSH2_ERROR_AGENT_PROTOCOL;
goto error;
}
num_identities = _libssh2_ntohu32(s);
s += 4;
while (num_identities--) {
struct agent_publickey *identity;
ssize_t comment_len;
identity = LIBSSH2_ALLOC(agent->session, sizeof *identity);
if (!identity) {
rc = LIBSSH2_ERROR_ALLOC;
goto error;
}
/* Read the length of the blob */
len -= 4;
if (len < 0) {
rc = LIBSSH2_ERROR_AGENT_PROTOCOL;
goto error;
}
identity->external.blob_len = _libssh2_ntohu32(s);
s += 4;
/* Read the blob */
len -= identity->external.blob_len;
if (len < 0) {
rc = LIBSSH2_ERROR_AGENT_PROTOCOL;
goto error;
}
identity->external.blob = LIBSSH2_ALLOC(agent->session,
identity->external.blob_len);
if (!identity->external.blob) {
rc = LIBSSH2_ERROR_ALLOC;
goto error;
}
memcpy(identity->external.blob, s, identity->external.blob_len);
s += identity->external.blob_len;
/* Read the length of the comment */
len -= 4;
if (len < 0) {
rc = LIBSSH2_ERROR_AGENT_PROTOCOL;
goto error;
}
comment_len = _libssh2_ntohu32(s);
s += 4;
/* Read the comment */
len -= comment_len;
if (len < 0) {
rc = LIBSSH2_ERROR_AGENT_PROTOCOL;
goto error;
}
identity->external.comment = LIBSSH2_ALLOC(agent->session,
comment_len + 1);
if (!identity->external.comment) {
rc = LIBSSH2_ERROR_ALLOC;
goto error;
}
identity->external.comment[comment_len] = '\0';
memcpy(identity->external.comment, s, comment_len);
s += comment_len;
_libssh2_list_add(&agent->head, &identity->node);
}
error:
LIBSSH2_FREE(agent->session, transctx->response);
transctx->response = NULL;
return rc;
}
static void
agent_free_identities(LIBSSH2_AGENT *agent) {
struct agent_publickey *node;
struct agent_publickey *next;
for (node = _libssh2_list_first(&agent->head); node; node = next) {
next = _libssh2_list_next(&node->node);
LIBSSH2_FREE(agent->session, node->external.blob);
LIBSSH2_FREE(agent->session, node->external.comment);
LIBSSH2_FREE(agent->session, node);
}
_libssh2_list_init(&agent->head);
}
#define AGENT_PUBLICKEY_MAGIC 0x3bdefed2
/*
* agent_publickey_to_external()
*
* Copies data from the internal to the external representation struct.
*
*/
static struct libssh2_agent_publickey *
agent_publickey_to_external(struct agent_publickey *node)
{
struct libssh2_agent_publickey *ext = &node->external;
ext->magic = AGENT_PUBLICKEY_MAGIC;
ext->node = node;
return ext;
}
/*
* libssh2_agent_init
*
* Init an ssh-agent handle. Returns the pointer to the handle.
*
*/
LIBSSH2_API LIBSSH2_AGENT *
libssh2_agent_init(LIBSSH2_SESSION *session)
{
LIBSSH2_AGENT *agent;
agent = LIBSSH2_ALLOC(session, sizeof *agent);
if (!agent) {
libssh2_error(session, LIBSSH2_ERROR_ALLOC,
"Unable to allocate space for agent connection", 0);
return NULL;
}
memset(agent, 0, sizeof *agent);
agent->session = session;
_libssh2_list_init(&agent->head);
return agent;
}
/*
* libssh2_agent_connect()
*
* Connect to an ssh-agent.
*
* Returns 0 if succeeded, or a negative value for error.
*/
LIBSSH2_API int
libssh2_agent_connect(LIBSSH2_AGENT *agent)
{
int i, rc = -1;
for (i = 0; supported_backends[i].name; i++) {
agent->ops = supported_backends[i].ops;
rc = agent->ops->connect(agent);
if (!rc)
return 0;
}
return rc;
}
/*
* libssh2_agent_list_identities()
*
* Request ssh-agent to list identities.
*
* Returns 0 if succeeded, or a negative value for error.
*/
LIBSSH2_API int
libssh2_agent_list_identities(LIBSSH2_AGENT *agent)
{
memset(&agent->transctx, 0, sizeof agent->transctx);
/* Abondon the last fetched identities */
agent_free_identities(agent);
return agent_list_identities(agent);
}
/*
* libssh2_agent_get_identity()
*
* Traverse the internal list of public keys. Pass NULL to 'prev' to get
* the first one. Or pass a poiner to the previously returned one to get the
* next.
*
* Returns:
* 0 if a fine public key was stored in 'store'
* 1 if end of public keys
* [negative] on errors
*/
LIBSSH2_API int
libssh2_agent_get_identity(LIBSSH2_AGENT *agent,
struct libssh2_agent_publickey **ext,
struct libssh2_agent_publickey *oprev)
{
struct agent_publickey *node;
if (oprev && oprev->node) {
/* we have a starting point */
struct agent_publickey *prev = oprev->node;
/* get the next node in the list */
node = _libssh2_list_next(&prev->node);
}
else
node = _libssh2_list_first(&agent->head);
if (!node)
/* no (more) node */
return 1;
*ext = agent_publickey_to_external(node);
return 0;
}
/*
* libssh2_agent_userauth()
*
* Do publickey user authentication with the help of ssh-agent.
*
* Returns 0 if succeeded, or a negative value for error.
*/
LIBSSH2_API int
libssh2_agent_userauth(LIBSSH2_AGENT *agent,
const char *username,
struct libssh2_agent_publickey *identity)
{
void *abstract = agent;
if (agent->session->userauth_pblc_state == libssh2_NB_state_idle) {
memset(&agent->transctx, 0, sizeof agent->transctx);
agent->identity = identity->node;
}
return libssh2_userauth_publickey(agent->session, username,
identity->blob,
identity->blob_len,
agent_sign,
&abstract);
}
/*
* libssh2_agent_disconnect()
*
* Close a connection to an ssh-agent.
*
* Returns 0 if succeeded, or a negative value for error.
*/
LIBSSH2_API int
libssh2_agent_disconnect(LIBSSH2_AGENT *agent)
{
if (agent->ops && agent->fd != INVALID_SOCKET)
return agent->ops->disconnect(agent);
return 0;
}
/*
* libssh2_agent_free()
*
* Free an ssh-agent handle. This function also frees the internal
* collection of public keys.
*/
LIBSSH2_API void
libssh2_agent_free(LIBSSH2_AGENT *agent) {
/* Allow connection freeing when the socket has lost its connection */
if (agent->fd != INVALID_SOCKET) {
libssh2_agent_disconnect(agent);
}
agent_free_identities(agent);
LIBSSH2_FREE(agent->session, agent);
}

View File

@@ -78,7 +78,7 @@ _libssh2_channel_nextid(LIBSSH2_SESSION * session)
* told...
*/
session->next_channel = id + 1;
_libssh2_debug(session, LIBSSH2_DBG_CONN, "Allocated new channel ID#%lu",
_libssh2_debug(session, LIBSSH2_TRACE_CONN, "Allocated new channel ID#%lu",
id);
return id;
}
@@ -149,7 +149,7 @@ _libssh2_channel_open(LIBSSH2_SESSION * session, const char *channel_type,
memset(&session->open_packet_requirev_state, 0,
sizeof(session->open_packet_requirev_state));
_libssh2_debug(session, LIBSSH2_DBG_CONN,
_libssh2_debug(session, LIBSSH2_TRACE_CONN,
"Opening Channel - win %d pack %d", window_size,
packet_size);
session->open_channel =
@@ -254,7 +254,7 @@ _libssh2_channel_open(LIBSSH2_SESSION * session, const char *channel_type,
_libssh2_ntohu32(session->open_data + 9);
session->open_channel->local.packet_size =
_libssh2_ntohu32(session->open_data + 13);
_libssh2_debug(session, LIBSSH2_DBG_CONN,
_libssh2_debug(session, LIBSSH2_TRACE_CONN,
"Connection Established - ID: %lu/%lu win: %lu/%lu"
" pack: %lu/%lu",
session->open_channel->local.id,
@@ -361,7 +361,7 @@ channel_direct_tcpip(LIBSSH2_SESSION * session, const char *host,
session->direct_message_len =
session->direct_host_len + session->direct_shost_len + 16;
_libssh2_debug(session, LIBSSH2_DBG_CONN,
_libssh2_debug(session, LIBSSH2_TRACE_CONN,
"Requesting direct-tcpip session to from %s:%d to %s:%d",
shost, sport, host, port);
@@ -455,7 +455,7 @@ channel_forward_listen(LIBSSH2_SESSION * session, const char *host,
memset(&session->fwdLstn_packet_requirev_state, 0,
sizeof(session->fwdLstn_packet_requirev_state));
_libssh2_debug(session, LIBSSH2_DBG_CONN,
_libssh2_debug(session, LIBSSH2_TRACE_CONN,
"Requesting tcpip-forward session for %s:%d", host,
port);
@@ -552,7 +552,7 @@ channel_forward_listen(LIBSSH2_SESSION * session, const char *host,
listener->host[session->fwdLstn_host_len] = 0;
if (data_len >= 5 && !port) {
listener->port = _libssh2_ntohu32(data + 1);
_libssh2_debug(session, LIBSSH2_DBG_CONN,
_libssh2_debug(session, LIBSSH2_TRACE_CONN,
"Dynamic tcpip-forward port allocated: %d",
listener->port);
} else {
@@ -625,7 +625,7 @@ static int channel_forward_cancel(LIBSSH2_LISTENER *listener)
int rc;
if (listener->chanFwdCncl_state == libssh2_NB_state_idle) {
_libssh2_debug(session, LIBSSH2_DBG_CONN,
_libssh2_debug(session, LIBSSH2_TRACE_CONN,
"Cancelling tcpip-forward session for %s:%d",
listener->host, listener->port);
@@ -725,11 +725,6 @@ channel_forward_accept(LIBSSH2_LISTENER *listener)
do {
rc = _libssh2_transport_read(listener->session);
if (rc == PACKET_EAGAIN) {
libssh2_error(listener->session, LIBSSH2_ERROR_EAGAIN,
"Would block waiting for packet", 0);
return NULL;
}
} while (rc > 0);
if (_libssh2_list_first(&listener->queue)) {
@@ -746,8 +741,13 @@ channel_forward_accept(LIBSSH2_LISTENER *listener)
return channel;
}
libssh2_error(listener->session, LIBSSH2_ERROR_CHANNEL_UNKNOWN,
"Channel not found", 0);
if (rc == PACKET_EAGAIN) {
libssh2_error(listener->session, LIBSSH2_ERROR_EAGAIN,
"Would block waiting for packet", 0);
}
else
libssh2_error(listener->session, LIBSSH2_ERROR_CHANNEL_UNKNOWN,
"Channel not found", 0);
return NULL;
}
@@ -791,7 +791,7 @@ static int channel_setenv(LIBSSH2_CHANNEL *channel,
memset(&channel->setenv_packet_requirev_state, 0,
sizeof(channel->setenv_packet_requirev_state));
_libssh2_debug(session, LIBSSH2_DBG_CONN,
_libssh2_debug(session, LIBSSH2_TRACE_CONN,
"Setting remote environment variable: %s=%s on "
"channel %lu/%lu",
varname, value, channel->local.id, channel->remote.id);
@@ -922,7 +922,7 @@ static int channel_request_pty(LIBSSH2_CHANNEL *channel,
memset(&channel->reqPTY_packet_requirev_state, 0,
sizeof(channel->reqPTY_packet_requirev_state));
_libssh2_debug(session, LIBSSH2_DBG_CONN,
_libssh2_debug(session, LIBSSH2_TRACE_CONN,
"Allocating tty on channel %lu/%lu", channel->local.id,
channel->remote.id);
@@ -1049,7 +1049,7 @@ channel_request_pty_size(LIBSSH2_CHANNEL * channel, int width,
memset(&channel->reqPTY_packet_requirev_state, 0,
sizeof(channel->reqPTY_packet_requirev_state));
_libssh2_debug(session, LIBSSH2_DBG_CONN,
_libssh2_debug(session, LIBSSH2_TRACE_CONN,
"changing tty size on channel %lu/%lu",
channel->local.id,
channel->remote.id);
@@ -1153,7 +1153,7 @@ channel_x11_req(LIBSSH2_CHANNEL *channel, int single_connection,
memset(&channel->reqX11_packet_requirev_state, 0,
sizeof(channel->reqX11_packet_requirev_state));
_libssh2_debug(session, LIBSSH2_DBG_CONN,
_libssh2_debug(session, LIBSSH2_TRACE_CONN,
"Requesting x11-req for channel %lu/%lu: single=%d "
"proto=%s cookie=%s screen=%d",
channel->local.id, channel->remote.id,
@@ -1303,7 +1303,7 @@ _libssh2_channel_process_startup(LIBSSH2_CHANNEL *channel,
channel->process_packet_len += message_len + 4;
}
_libssh2_debug(session, LIBSSH2_DBG_CONN,
_libssh2_debug(session, LIBSSH2_TRACE_CONN,
"starting request(%s) on channel %lu/%lu, message=%s",
request, channel->local.id, channel->remote.id,
message);
@@ -1449,7 +1449,7 @@ _libssh2_channel_flush(LIBSSH2_CHANNEL *channel, int streamid)
&& (streamid == 0))) {
int bytes_to_flush = packet->data_len - packet->data_head;
_libssh2_debug(channel->session, LIBSSH2_DBG_CONN,
_libssh2_debug(channel->session, LIBSSH2_TRACE_CONN,
"Flushing %d bytes of data from stream "
"%lu on channel %lu/%lu",
bytes_to_flush, packet_stream_id,
@@ -1533,7 +1533,7 @@ _libssh2_channel_receive_window_adjust(LIBSSH2_CHANNEL * channel,
if (!force
&& (adjustment + channel->adjust_queue <
LIBSSH2_CHANNEL_MINADJUST)) {
_libssh2_debug(channel->session, LIBSSH2_DBG_CONN,
_libssh2_debug(channel->session, LIBSSH2_TRACE_CONN,
"Queueing %lu bytes for receive window adjustment "
"for channel %lu/%lu",
adjustment, channel->local.id, channel->remote.id);
@@ -1556,7 +1556,7 @@ _libssh2_channel_receive_window_adjust(LIBSSH2_CHANNEL * channel,
channel->adjust_adjust[0] = SSH_MSG_CHANNEL_WINDOW_ADJUST;
_libssh2_htonu32(&channel->adjust_adjust[1], channel->remote.id);
_libssh2_htonu32(&channel->adjust_adjust[5], adjustment);
_libssh2_debug(channel->session, LIBSSH2_DBG_CONN,
_libssh2_debug(channel->session, LIBSSH2_TRACE_CONN,
"Adjusting window %lu bytes for data on "
"channel %lu/%lu",
adjustment, channel->local.id, channel->remote.id);
@@ -1643,7 +1643,7 @@ int
_libssh2_channel_extended_data(LIBSSH2_CHANNEL *channel, int ignore_mode)
{
if (channel->extData2_state == libssh2_NB_state_idle) {
_libssh2_debug(channel->session, LIBSSH2_DBG_CONN,
_libssh2_debug(channel->session, LIBSSH2_TRACE_CONN,
"Setting channel %lu/%lu handle_extended_data"
" mode to %d",
channel->local.id, channel->remote.id, ignore_mode);
@@ -1720,7 +1720,7 @@ ssize_t _libssh2_channel_read(LIBSSH2_CHANNEL *channel, int stream_id,
LIBSSH2_PACKET *read_next;
if (channel->read_state == libssh2_NB_state_idle) {
_libssh2_debug(session, LIBSSH2_DBG_CONN,
_libssh2_debug(session, LIBSSH2_TRACE_CONN,
"channel_read() wants %d bytes from channel %lu/%lu "
"stream #%d",
(int) buflen, channel->local.id, channel->remote.id,
@@ -1797,7 +1797,7 @@ ssize_t _libssh2_channel_read(LIBSSH2_CHANNEL *channel, int stream_id,
unlink_packet = TRUE;
}
_libssh2_debug(session, LIBSSH2_DBG_CONN,
_libssh2_debug(session, LIBSSH2_TRACE_CONN,
"channel_read() got %d of data from %lu/%lu/%d%s",
bytes_want, channel->local.id,
channel->remote.id, stream_id,
@@ -1856,7 +1856,7 @@ ssize_t _libssh2_channel_read(LIBSSH2_CHANNEL *channel, int stream_id,
if (rc == PACKET_EAGAIN)
return rc;
_libssh2_debug(session, LIBSSH2_DBG_CONN,
_libssh2_debug(session, LIBSSH2_TRACE_CONN,
"channel_read() filled %d adjusted %d",
bytes_read, buflen);
/* continue in 'created' state to drain the already read packages
@@ -1966,7 +1966,7 @@ _libssh2_channel_write(LIBSSH2_CHANNEL *channel, int stream_id,
if (channel->write_state == libssh2_NB_state_idle) {
channel->write_bufwrote = 0;
_libssh2_debug(session, LIBSSH2_DBG_CONN,
_libssh2_debug(session, LIBSSH2_TRACE_CONN,
"Writing %d bytes on channel %lu/%lu, stream #%d",
(int) buflen, channel->local.id, channel->remote.id,
stream_id);
@@ -2030,7 +2030,7 @@ _libssh2_channel_write(LIBSSH2_CHANNEL *channel, int stream_id,
/* Don't exceed the remote end's limits */
/* REMEMBER local means local as the SOURCE of the data */
if (channel->write_bufwrite > channel->local.window_size) {
_libssh2_debug(session, LIBSSH2_DBG_CONN,
_libssh2_debug(session, LIBSSH2_TRACE_CONN,
"Splitting write block due to %lu byte "
"window_size on %lu/%lu/%d",
channel->local.window_size, channel->local.id,
@@ -2038,7 +2038,7 @@ _libssh2_channel_write(LIBSSH2_CHANNEL *channel, int stream_id,
channel->write_bufwrite = channel->local.window_size;
}
if (channel->write_bufwrite > channel->local.packet_size) {
_libssh2_debug(session, LIBSSH2_DBG_CONN,
_libssh2_debug(session, LIBSSH2_TRACE_CONN,
"Splitting write block due to %lu byte "
"packet_size on %lu/%lu/%d",
channel->local.packet_size, channel->local.id,
@@ -2050,7 +2050,7 @@ _libssh2_channel_write(LIBSSH2_CHANNEL *channel, int stream_id,
memcpy(channel->write_s, buf, channel->write_bufwrite);
channel->write_s += channel->write_bufwrite;
_libssh2_debug(session, LIBSSH2_DBG_CONN,
_libssh2_debug(session, LIBSSH2_TRACE_CONN,
"Sending %d bytes on channel %lu/%lu, stream_id=%d",
(int) channel->write_bufwrite, channel->local.id,
channel->remote.id, stream_id);
@@ -2122,7 +2122,7 @@ static int channel_send_eof(LIBSSH2_CHANNEL *channel)
unsigned char packet[5]; /* packet_type(1) + channelno(4) */
int rc;
_libssh2_debug(session, LIBSSH2_DBG_CONN, "Sending EOF on channel %lu/%lu",
_libssh2_debug(session, LIBSSH2_TRACE_CONN, "Sending EOF on channel %lu/%lu",
channel->local.id, channel->remote.id);
packet[0] = SSH_MSG_CHANNEL_EOF;
_libssh2_htonu32(packet + 1, channel->remote.id);
@@ -2188,7 +2188,7 @@ static int channel_wait_eof(LIBSSH2_CHANNEL *channel)
int rc;
if (channel->wait_eof_state == libssh2_NB_state_idle) {
_libssh2_debug(session, LIBSSH2_DBG_CONN,
_libssh2_debug(session, LIBSSH2_TRACE_CONN,
"Awaiting close of channel %lu/%lu", channel->local.id,
channel->remote.id);
@@ -2246,7 +2246,7 @@ channel_close(LIBSSH2_CHANNEL * channel)
}
if (channel->close_state == libssh2_NB_state_idle) {
_libssh2_debug(session, LIBSSH2_DBG_CONN, "Closing channel %lu/%lu",
_libssh2_debug(session, LIBSSH2_TRACE_CONN, "Closing channel %lu/%lu",
channel->local.id, channel->remote.id);
channel->close_packet[0] = SSH_MSG_CHANNEL_CLOSE;
@@ -2327,7 +2327,7 @@ static int channel_wait_closed(LIBSSH2_CHANNEL *channel)
}
if (channel->wait_closed_state == libssh2_NB_state_idle) {
_libssh2_debug(session, LIBSSH2_DBG_CONN,
_libssh2_debug(session, LIBSSH2_TRACE_CONN,
"Awaiting close of channel %lu/%lu", channel->local.id,
channel->remote.id);
@@ -2386,7 +2386,7 @@ int _libssh2_channel_free(LIBSSH2_CHANNEL *channel)
assert(session);
if (channel->free_state == libssh2_NB_state_idle) {
_libssh2_debug(session, LIBSSH2_DBG_CONN,
_libssh2_debug(session, LIBSSH2_TRACE_CONN,
"Freeing channel %lu/%lu resources", channel->local.id,
channel->remote.id);

View File

@@ -1,4 +1,5 @@
/* Copyright (c) 2004-2007, Sara Golemon <sarag@libssh2.org>
/* Copyright (c) 2009 Simon Josefsson <simon@josefsson.org>
* Copyright (c) 2004-2007, Sara Golemon <sarag@libssh2.org>
* All rights reserved.
*
* Redistribution and use in source and binary forms,
@@ -114,6 +115,44 @@ crypt_dtor(LIBSSH2_SESSION * session, void **abstract)
return 0;
}
#if LIBSSH2_AES_CTR
static const LIBSSH2_CRYPT_METHOD libssh2_crypt_method_aes128_ctr = {
"aes128-ctr",
16, /* blocksize */
16, /* initial value length */
16, /* secret length -- 16*8 == 128bit */
0, /* flags */
&crypt_init,
&crypt_encrypt,
&crypt_dtor,
_libssh2_cipher_aes128ctr
};
static const LIBSSH2_CRYPT_METHOD libssh2_crypt_method_aes192_ctr = {
"aes192-ctr",
16, /* blocksize */
16, /* initial value length */
24, /* secret length -- 24*8 == 192bit */
0, /* flags */
&crypt_init,
&crypt_encrypt,
&crypt_dtor,
_libssh2_cipher_aes192ctr
};
static const LIBSSH2_CRYPT_METHOD libssh2_crypt_method_aes256_ctr = {
"aes256-ctr",
16, /* blocksize */
16, /* initial value length */
32, /* secret length -- 32*8 == 256bit */
0, /* flags */
&crypt_init,
&crypt_encrypt,
&crypt_dtor,
_libssh2_cipher_aes256ctr
};
#endif
#if LIBSSH2_AES
static const LIBSSH2_CRYPT_METHOD libssh2_crypt_method_aes128_cbc = {
"aes128-cbc",
@@ -192,6 +231,40 @@ static const LIBSSH2_CRYPT_METHOD libssh2_crypt_method_arcfour = {
&crypt_dtor,
_libssh2_cipher_arcfour
};
static int
crypt_init_arcfour128(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 rc;
rc = crypt_init (session, method, iv, free_iv, secret, free_secret,
encrypt, abstract);
if (rc == 0) {
struct crypt_ctx *cctx = *(struct crypt_ctx **) abstract;
unsigned char block[8];
size_t discard = 1536;
for (; discard; discard -= 8)
_libssh2_cipher_crypt(&cctx->h, cctx->algo, cctx->encrypt, block);
}
return rc;
}
static const LIBSSH2_CRYPT_METHOD libssh2_crypt_method_arcfour128 = {
"arcfour128",
8, /* blocksize */
8, /* initial value length */
16, /* secret length */
0, /* flags */
&crypt_init_arcfour128,
&crypt_encrypt,
&crypt_dtor,
_libssh2_cipher_arcfour
};
#endif /* LIBSSH2_RC4 */
#if LIBSSH2_CAST
@@ -223,6 +296,11 @@ static const LIBSSH2_CRYPT_METHOD libssh2_crypt_method_3des_cbc = {
#endif
static const LIBSSH2_CRYPT_METHOD *_libssh2_crypt_methods[] = {
#if LIBSSH2_AES_CTR
&libssh2_crypt_method_aes128_ctr,
&libssh2_crypt_method_aes192_ctr,
&libssh2_crypt_method_aes256_ctr,
#endif /* LIBSSH2_AES */
#if LIBSSH2_AES
&libssh2_crypt_method_aes256_cbc,
&libssh2_crypt_method_rijndael_cbc_lysator_liu_se, /* == aes256-cbc */
@@ -233,6 +311,7 @@ static const LIBSSH2_CRYPT_METHOD *_libssh2_crypt_methods[] = {
&libssh2_crypt_method_blowfish_cbc,
#endif /* LIBSSH2_BLOWFISH */
#if LIBSSH2_RC4
&libssh2_crypt_method_arcfour128,
&libssh2_crypt_method_arcfour,
#endif /* LIBSSH2_RC4 */
#if LIBSSH2_CAST

View File

@@ -135,7 +135,7 @@ static int diffie_hellman_sha1(LIBSSH2_SESSION *session,
exchange_state->e_packet + 6);
}
_libssh2_debug(session, LIBSSH2_DBG_KEX, "Sending KEX packet %d",
_libssh2_debug(session, LIBSSH2_TRACE_KEX, "Sending KEX packet %d",
(int) packet_type_init);
exchange_state->state = libssh2_NB_state_created;
}
@@ -161,7 +161,7 @@ static int diffie_hellman_sha1(LIBSSH2_SESSION *session,
* need to silently ignore it */
int burn_type;
_libssh2_debug(session, LIBSSH2_DBG_KEX,
_libssh2_debug(session, LIBSSH2_TRACE_KEX,
"Waiting for badly guessed KEX packet (to be ignored)");
burn_type =
_libssh2_packet_burn(session, &exchange_state->burn_state);
@@ -174,7 +174,7 @@ static int diffie_hellman_sha1(LIBSSH2_SESSION *session,
}
session->burn_optimistic_kexinit = 0;
_libssh2_debug(session, LIBSSH2_DBG_KEX,
_libssh2_debug(session, LIBSSH2_TRACE_KEX,
"Burnt packet of type: %02x",
(unsigned int) burn_type);
}
@@ -233,7 +233,7 @@ static int diffie_hellman_sha1(LIBSSH2_SESSION *session,
snprintf(fprint, 4, "%02x:", session->server_hostkey_md5[i]);
}
*(--fprint) = '\0';
_libssh2_debug(session, LIBSSH2_DBG_KEX,
_libssh2_debug(session, LIBSSH2_TRACE_KEX,
"Server's MD5 Fingerprint: %s", fingerprint);
}
#endif /* LIBSSH2DEBUG */
@@ -256,7 +256,7 @@ static int diffie_hellman_sha1(LIBSSH2_SESSION *session,
snprintf(fprint, 4, "%02x:", session->server_hostkey_sha1[i]);
}
*(--fprint) = '\0';
_libssh2_debug(session, LIBSSH2_DBG_KEX,
_libssh2_debug(session, LIBSSH2_TRACE_KEX,
"Server's SHA1 Fingerprint: %s", fingerprint);
}
#endif /* LIBSSH2DEBUG */
@@ -410,7 +410,7 @@ static int diffie_hellman_sha1(LIBSSH2_SESSION *session,
goto clean_exit;
}
_libssh2_debug(session, LIBSSH2_DBG_KEX, "Sending NEWKEYS message");
_libssh2_debug(session, LIBSSH2_TRACE_KEX, "Sending NEWKEYS message");
exchange_state->c = SSH_MSG_NEWKEYS;
exchange_state->state = libssh2_NB_state_sent2;
@@ -444,7 +444,7 @@ static int diffie_hellman_sha1(LIBSSH2_SESSION *session,
/* The first key exchange has been performed,
switch to active crypt/comp/mac mode */
session->state |= LIBSSH2_STATE_NEWKEYS;
_libssh2_debug(session, LIBSSH2_DBG_KEX, "Received NEWKEYS message");
_libssh2_debug(session, LIBSSH2_TRACE_KEX, "Received NEWKEYS message");
/* This will actually end up being just packet_type(1)
for this packet type anyway */
@@ -461,7 +461,7 @@ static int diffie_hellman_sha1(LIBSSH2_SESSION *session,
memcpy(session->session_id, exchange_state->h_sig_comp,
SHA_DIGEST_LENGTH);
session->session_id_len = SHA_DIGEST_LENGTH;
_libssh2_debug(session, LIBSSH2_DBG_KEX, "session_id calculated");
_libssh2_debug(session, LIBSSH2_TRACE_KEX, "session_id calculated");
}
/* Cleanup any existing cipher */
@@ -509,7 +509,7 @@ static int diffie_hellman_sha1(LIBSSH2_SESSION *session,
LIBSSH2_FREE(session, secret);
}
}
_libssh2_debug(session, LIBSSH2_DBG_KEX,
_libssh2_debug(session, LIBSSH2_TRACE_KEX,
"Client to Server IV and Key calculated");
if (session->remote.crypt->dtor) {
@@ -556,7 +556,7 @@ static int diffie_hellman_sha1(LIBSSH2_SESSION *session,
LIBSSH2_FREE(session, secret);
}
}
_libssh2_debug(session, LIBSSH2_DBG_KEX,
_libssh2_debug(session, LIBSSH2_TRACE_KEX,
"Server to Client IV and Key calculated");
if (session->local.mac->dtor) {
@@ -582,7 +582,7 @@ static int diffie_hellman_sha1(LIBSSH2_SESSION *session,
LIBSSH2_FREE(session, key);
}
}
_libssh2_debug(session, LIBSSH2_DBG_KEX,
_libssh2_debug(session, LIBSSH2_TRACE_KEX,
"Client to Server HMAC Key calculated");
if (session->remote.mac->dtor) {
@@ -608,7 +608,7 @@ static int diffie_hellman_sha1(LIBSSH2_SESSION *session,
LIBSSH2_FREE(session, key);
}
}
_libssh2_debug(session, LIBSSH2_DBG_KEX,
_libssh2_debug(session, LIBSSH2_TRACE_KEX,
"Server to Client HMAC Key calculated");
}
@@ -684,7 +684,7 @@ kex_method_diffie_hellman_group1_sha1_key_exchange(LIBSSH2_SESSION *session,
_libssh2_bn_set_word(key_state->g, 2);
_libssh2_bn_from_bin(key_state->p, 128, p_value);
_libssh2_debug(session, LIBSSH2_DBG_KEX,
_libssh2_debug(session, LIBSSH2_TRACE_KEX,
"Initiating Diffie-Hellman Group1 Key Exchange");
key_state->state = libssh2_NB_state_created;
@@ -760,7 +760,7 @@ kex_method_diffie_hellman_group14_sha1_key_exchange(LIBSSH2_SESSION *session,
_libssh2_bn_set_word(key_state->g, 2);
_libssh2_bn_from_bin(key_state->p, 256, p_value);
_libssh2_debug(session, LIBSSH2_DBG_KEX,
_libssh2_debug(session, LIBSSH2_TRACE_KEX,
"Initiating Diffie-Hellman Group14 Key Exchange");
key_state->state = libssh2_NB_state_created;
@@ -806,13 +806,13 @@ kex_method_diffie_hellman_group_exchange_sha1_key_exchange
_libssh2_htonu32(key_state->request + 5, LIBSSH2_DH_GEX_OPTGROUP);
_libssh2_htonu32(key_state->request + 9, LIBSSH2_DH_GEX_MAXGROUP);
key_state->request_len = 13;
_libssh2_debug(session, LIBSSH2_DBG_KEX,
_libssh2_debug(session, LIBSSH2_TRACE_KEX,
"Initiating Diffie-Hellman Group-Exchange (New Method)");
#else
key_state->request[0] = SSH_MSG_KEX_DH_GEX_REQUEST_OLD;
_libssh2_htonu32(key_state->request + 1, LIBSSH2_DH_GEX_OPTGROUP);
key_state->request_len = 5;
_libssh2_debug(session, LIBSSH2_DBG_KEX,
_libssh2_debug(session, LIBSSH2_TRACE_KEX,
"Initiating Diffie-Hellman Group-Exchange (Old Method)");
#endif
@@ -1090,25 +1090,25 @@ static int kexinit(LIBSSH2_SESSION * session)
/* Funnily enough, they'll all "appear" to be '\0' terminated */
unsigned char *p = data + 21; /* type(1) + cookie(16) + len(4) */
_libssh2_debug(session, LIBSSH2_DBG_KEX, "Sent KEX: %s", p);
_libssh2_debug(session, LIBSSH2_TRACE_KEX, "Sent KEX: %s", p);
p += kex_len + 4;
_libssh2_debug(session, LIBSSH2_DBG_KEX, "Sent HOSTKEY: %s", p);
_libssh2_debug(session, LIBSSH2_TRACE_KEX, "Sent HOSTKEY: %s", p);
p += hostkey_len + 4;
_libssh2_debug(session, LIBSSH2_DBG_KEX, "Sent CRYPT_CS: %s", p);
_libssh2_debug(session, LIBSSH2_TRACE_KEX, "Sent CRYPT_CS: %s", p);
p += crypt_cs_len + 4;
_libssh2_debug(session, LIBSSH2_DBG_KEX, "Sent CRYPT_SC: %s", p);
_libssh2_debug(session, LIBSSH2_TRACE_KEX, "Sent CRYPT_SC: %s", p);
p += crypt_sc_len + 4;
_libssh2_debug(session, LIBSSH2_DBG_KEX, "Sent MAC_CS: %s", p);
_libssh2_debug(session, LIBSSH2_TRACE_KEX, "Sent MAC_CS: %s", p);
p += mac_cs_len + 4;
_libssh2_debug(session, LIBSSH2_DBG_KEX, "Sent MAC_SC: %s", p);
_libssh2_debug(session, LIBSSH2_TRACE_KEX, "Sent MAC_SC: %s", p);
p += mac_sc_len + 4;
_libssh2_debug(session, LIBSSH2_DBG_KEX, "Sent COMP_CS: %s", p);
_libssh2_debug(session, LIBSSH2_TRACE_KEX, "Sent COMP_CS: %s", p);
p += comp_cs_len + 4;
_libssh2_debug(session, LIBSSH2_DBG_KEX, "Sent COMP_SC: %s", p);
_libssh2_debug(session, LIBSSH2_TRACE_KEX, "Sent COMP_SC: %s", p);
p += comp_sc_len + 4;
_libssh2_debug(session, LIBSSH2_DBG_KEX, "Sent LANG_CS: %s", p);
_libssh2_debug(session, LIBSSH2_TRACE_KEX, "Sent LANG_CS: %s", p);
p += lang_cs_len + 4;
_libssh2_debug(session, LIBSSH2_DBG_KEX, "Sent LANG_SC: %s", p);
_libssh2_debug(session, LIBSSH2_TRACE_KEX, "Sent LANG_SC: %s", p);
p += lang_sc_len + 4;
}
#endif /* LIBSSH2DEBUG */
@@ -1607,24 +1607,24 @@ static int kex_agree_methods(LIBSSH2_SESSION * session, unsigned char *data,
return -1;
}
_libssh2_debug(session, LIBSSH2_DBG_KEX, "Agreed on KEX method: %s",
_libssh2_debug(session, LIBSSH2_TRACE_KEX, "Agreed on KEX method: %s",
session->kex->name);
_libssh2_debug(session, LIBSSH2_DBG_KEX, "Agreed on HOSTKEY method: %s",
_libssh2_debug(session, LIBSSH2_TRACE_KEX, "Agreed on HOSTKEY method: %s",
session->hostkey->name);
_libssh2_debug(session, LIBSSH2_DBG_KEX, "Agreed on CRYPT_CS method: %s",
_libssh2_debug(session, LIBSSH2_TRACE_KEX, "Agreed on CRYPT_CS method: %s",
session->local.crypt->name);
_libssh2_debug(session, LIBSSH2_DBG_KEX, "Agreed on CRYPT_SC method: %s",
_libssh2_debug(session, LIBSSH2_TRACE_KEX, "Agreed on CRYPT_SC method: %s",
session->remote.crypt->name);
_libssh2_debug(session, LIBSSH2_DBG_KEX, "Agreed on MAC_CS method: %s",
_libssh2_debug(session, LIBSSH2_TRACE_KEX, "Agreed on MAC_CS method: %s",
session->local.mac->name);
_libssh2_debug(session, LIBSSH2_DBG_KEX, "Agreed on MAC_SC method: %s",
_libssh2_debug(session, LIBSSH2_TRACE_KEX, "Agreed on MAC_SC method: %s",
session->remote.mac->name);
_libssh2_debug(session, LIBSSH2_DBG_KEX, "Agreed on COMP_CS method: %s",
_libssh2_debug(session, LIBSSH2_TRACE_KEX, "Agreed on COMP_CS method: %s",
session->local.comp->name);
_libssh2_debug(session, LIBSSH2_DBG_KEX, "Agreed on COMP_SC method: %s",
_libssh2_debug(session, LIBSSH2_TRACE_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 */
_libssh2_debug(session, LIBSSH2_TRACE_KEX, "Agreed on LANG_CS method:"); /* None yet */
_libssh2_debug(session, LIBSSH2_TRACE_KEX, "Agreed on LANG_SC method:"); /* None yet */
/* Initialize compression layer */
if (session->local.comp && session->local.comp->init &&

View File

@@ -424,61 +424,54 @@ _libssh2_dsa_sha1_sign(libssh2_dsa_ctx * dsactx,
return -1;
}
memset(sig, 0, 40);
/* Extract R. */
data = gcry_sexp_find_token(sig_sexp, "r", 0);
if (!data) {
ret = -1;
goto out;
}
if (!data)
goto err;
tmp = gcry_sexp_nth_data(data, 1, &size);
if (!tmp) {
ret = -1;
goto out;
}
if (!tmp)
goto err;
if (tmp[0] == '\0') {
tmp++;
size--;
}
if (size != 20) {
ret = -1;
goto out;
}
if (size < 1 || size > 20)
goto err;
memcpy(sig, tmp, 20);
memcpy(sig + (20 - size), tmp, size);
gcry_sexp_release(data);
/* Extract S. */
data = gcry_sexp_find_token(sig_sexp, "s", 0);
if (!data) {
ret = -1;
goto out;
}
if (!data)
goto err;
tmp = gcry_sexp_nth_data(data, 1, &size);
if (!tmp) {
ret = -1;
goto out;
}
if (!tmp)
goto err;
if (tmp[0] == '\0') {
tmp++;
size--;
}
if (size != 20) {
ret = -1;
goto out;
}
if (size < 1 || size > 20)
goto err;
memcpy(sig + 20, tmp, 20);
memcpy(sig + 20 + (20 - size), tmp, size);
goto out;
err:
ret = -1;
ret = 0;
out:
if (sig_sexp) {
gcry_sexp_release(sig_sexp);
@@ -524,16 +517,14 @@ _libssh2_cipher_init(_libssh2_cipher_ctx * h,
_libssh2_cipher_type(algo),
unsigned char *iv, unsigned char *secret, int encrypt)
{
int mode = 0, ret;
int keylen = gcry_cipher_get_algo_keylen(algo);
int ret;
int cipher = _libssh2_gcry_cipher (algo);
int mode = _libssh2_gcry_mode (algo);
int keylen = gcry_cipher_get_algo_keylen(cipher);
(void) encrypt;
if (algo != GCRY_CIPHER_ARCFOUR) {
mode = GCRY_CIPHER_MODE_CBC;
}
ret = gcry_cipher_open(h, algo, mode, 0);
ret = gcry_cipher_open(h, cipher, mode, 0);
if (ret) {
return -1;
}
@@ -544,10 +535,13 @@ _libssh2_cipher_init(_libssh2_cipher_ctx * h,
return -1;
}
if (algo != GCRY_CIPHER_ARCFOUR) {
int blklen = gcry_cipher_get_algo_blklen(algo);
ret = gcry_cipher_setiv(*h, iv, blklen);
if (ret) {
if (mode != GCRY_CIPHER_MODE_STREAM) {
int blklen = gcry_cipher_get_algo_blklen(cipher);
if (mode == GCRY_CIPHER_MODE_CTR)
ret = gcry_cipher_setctr(*h, iv, blklen);
else
ret = gcry_cipher_setiv(*h, iv, blklen);
if (ret) {
gcry_cipher_close(*h);
return -1;
}
@@ -561,8 +555,10 @@ _libssh2_cipher_crypt(_libssh2_cipher_ctx * ctx,
_libssh2_cipher_type(algo),
int encrypt, unsigned char *block)
{
size_t blklen = gcry_cipher_get_algo_blklen(algo);
int cipher = _libssh2_gcry_cipher (algo);
size_t blklen = gcry_cipher_get_algo_blklen(cipher);
int ret;
if (blklen == 1) {
/* Hack for arcfour. */
blklen = 8;

View File

@@ -1,5 +1,6 @@
/* Copyright (C) 2006, 2007, The Written Word, Inc.
* Copyright (C) 2008, Simon Josefsson
/*
* Copyright (C) 2008, 2009 Simon Josefsson
* Copyright (C) 2006, 2007, The Written Word, Inc.
* All rights reserved.
*
* Redistribution and use in source and binary forms,
@@ -43,6 +44,7 @@
#define LIBSSH2_HMAC_RIPEMD 1
#define LIBSSH2_AES 1
#define LIBSSH2_AES_CTR 1
#define LIBSSH2_BLOWFISH 1
#define LIBSSH2_RC4 1
#define LIBSSH2_CAST 1
@@ -155,13 +157,30 @@ int _libssh2_dsa_sha1_sign(libssh2_dsa_ctx * dsactx,
#define _libssh2_cipher_type(name) int name
#define _libssh2_cipher_ctx gcry_cipher_hd_t
#define _libssh2_cipher_aes256 GCRY_CIPHER_AES256
#define _libssh2_cipher_aes192 GCRY_CIPHER_AES192
#define _libssh2_cipher_aes128 GCRY_CIPHER_AES128
#define _libssh2_cipher_blowfish GCRY_CIPHER_BLOWFISH
#define _libssh2_cipher_arcfour GCRY_CIPHER_ARCFOUR
#define _libssh2_cipher_cast5 GCRY_CIPHER_CAST5
#define _libssh2_cipher_3des GCRY_CIPHER_3DES
#define _libssh2_gcry_ciphermode(c,m) ((c << 8) | m)
#define _libssh2_gcry_cipher(c) (c >> 8)
#define _libssh2_gcry_mode(m) (m & 0xFF)
#define _libssh2_cipher_aes256ctr \
_libssh2_gcry_ciphermode(GCRY_CIPHER_AES256, GCRY_CIPHER_MODE_CTR)
#define _libssh2_cipher_aes192ctr \
_libssh2_gcry_ciphermode(GCRY_CIPHER_AES192, GCRY_CIPHER_MODE_CTR)
#define _libssh2_cipher_aes128ctr \
_libssh2_gcry_ciphermode(GCRY_CIPHER_AES128, GCRY_CIPHER_MODE_CTR)
#define _libssh2_cipher_aes256 \
_libssh2_gcry_ciphermode(GCRY_CIPHER_AES256, GCRY_CIPHER_MODE_CBC)
#define _libssh2_cipher_aes192 \
_libssh2_gcry_ciphermode(GCRY_CIPHER_AES192, GCRY_CIPHER_MODE_CBC)
#define _libssh2_cipher_aes128 \
_libssh2_gcry_ciphermode(GCRY_CIPHER_AES128, GCRY_CIPHER_MODE_CBC)
#define _libssh2_cipher_blowfish \
_libssh2_gcry_ciphermode(GCRY_CIPHER_BLOWFISH, GCRY_CIPHER_MODE_CBC)
#define _libssh2_cipher_arcfour \
_libssh2_gcry_ciphermode(GCRY_CIPHER_ARCFOUR, GCRY_CIPHER_MODE_STREAM)
#define _libssh2_cipher_cast5 \
_libssh2_gcry_ciphermode(GCRY_CIPHER_CAST5, GCRY_CIPHER_MODE_CBC)
#define _libssh2_cipher_3des \
_libssh2_gcry_ciphermode(GCRY_CIPHER_3DES, GCRY_CIPHER_MODE_CBC)
int _libssh2_cipher_init(_libssh2_cipher_ctx * h,
_libssh2_cipher_type(algo),

View File

@@ -1,5 +1,6 @@
/* Copyright (c) 2004-2008, Sara Golemon <sarag@libssh2.org>
* Copyright (c) 2009 by Daniel Stenberg
* Copyright (c) 2010 Simon Josefsson
* All rights reserved.
*
* Redistribution and use in source and binary forms,
@@ -153,6 +154,7 @@ static inline int writev(int sock, struct iovec *iov, int nvecs)
typedef SOCKET libssh2_socket_t;
#else /* !WIN32 */
typedef int libssh2_socket_t;
#define INVALID_SOCKET -1
#endif /* WIN32 */
/* RFC4253 section 6.1 Maximum Packet Length says:
@@ -209,7 +211,9 @@ typedef enum
libssh2_NB_state_sent7,
libssh2_NB_state_jump1,
libssh2_NB_state_jump2,
libssh2_NB_state_jump3
libssh2_NB_state_jump3,
libssh2_NB_state_jump4,
libssh2_NB_state_jump5
} libssh2_nonblocking_states;
typedef struct packet_require_state_t
@@ -735,6 +739,8 @@ struct _LIBSSH2_SESSION
struct transportpacket packet;
#ifdef LIBSSH2DEBUG
int showmask; /* what debug/trace messages to display */
libssh2_trace_handler_func tracehandler; /* callback to display trace messages */
void* tracehandler_context; /* context for the trace handler */
#endif
/* State variables used in libssh2_banner_send() */
@@ -1014,14 +1020,6 @@ struct _LIBSSH2_MAC_METHOD
int (*dtor) (LIBSSH2_SESSION * session, void **abstract);
};
#define LIBSSH2_DBG_TRANS 1
#define LIBSSH2_DBG_KEX 2
#define LIBSSH2_DBG_AUTH 3
#define LIBSSH2_DBG_CONN 4
#define LIBSSH2_DBG_SCP 5
#define LIBSSH2_DBG_SFTP 6
#define LIBSSH2_DBG_ERROR 7
#define LIBSSH2_DBG_PUBLICKEY 8
#ifdef LIBSSH2DEBUG
void _libssh2_debug(LIBSSH2_SESSION * session, int context, const char *format,
...);
@@ -1048,7 +1046,7 @@ _libssh2_debug(LIBSSH2_SESSION * session, int context, const char *format, ...)
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); \
_libssh2_debug(session, LIBSSH2_TRACE_ERROR, "%d - %s", session->err_code, session->err_msg); \
}
#else /* ! LIBSSH2DEBUG */
@@ -1271,4 +1269,7 @@ int _libssh2_pem_decode_integer(unsigned char **data, unsigned int *datalen,
} while(1)
#define ARRAY_SIZE(a) (sizeof ((a)) / sizeof ((a)[0]))
#endif /* LIBSSH2_H */

View File

@@ -167,6 +167,7 @@ static const LIBSSH2_MAC_METHOD mac_method_hmac_sha1_96 = {
mac_method_common_dtor,
};
#if LIBSSH2_MD5
/* mac_method_hmac_md5_hash
* Calculate hash using full md5 value
*/
@@ -235,6 +236,7 @@ static const LIBSSH2_MAC_METHOD mac_method_hmac_md5_96 = {
mac_method_hmac_md5_96_hash,
mac_method_common_dtor,
};
#endif /* LIBSSH2_MD5 */
#if LIBSSH2_HMAC_RIPEMD
/* mac_method_hmac_ripemd160_hash
@@ -291,8 +293,10 @@ static const LIBSSH2_MAC_METHOD mac_method_hmac_ripemd160_openssh_com = {
static const LIBSSH2_MAC_METHOD *mac_methods[] = {
&mac_method_hmac_sha1,
&mac_method_hmac_sha1_96,
#if LIBSSH2_MD5
&mac_method_hmac_md5,
&mac_method_hmac_md5_96,
#endif
#if LIBSSH2_HMAC_RIPEMD
&mac_method_hmac_ripemd160,
&mac_method_hmac_ripemd160_openssh_com,

View File

@@ -312,6 +312,14 @@ libssh2_trace(LIBSSH2_SESSION * session, int bitmask)
return 0;
}
LIBSSH2_API int
libssh2_trace_sethandler(LIBSSH2_SESSION *session, void* handler_context, libssh2_trace_handler_func callback)
{
session->tracehandler = callback;
session->tracehandler_context = handler_context;
return 0;
}
void
_libssh2_debug(LIBSSH2_SESSION * session, int context, const char *format, ...)
{
@@ -320,7 +328,7 @@ _libssh2_debug(LIBSSH2_SESSION * session, int context, const char *format, ...)
va_list vargs;
struct timeval now;
static int firstsec;
static const char *const contexts[9] = {
static const char *const contexts[] = {
"Unknown",
"Transport",
"Key Ex",
@@ -330,15 +338,24 @@ _libssh2_debug(LIBSSH2_SESSION * session, int context, const char *format, ...)
"SFTP",
"Failure Event",
"Publickey",
"Socket",
};
const char* contexttext = contexts[0];
unsigned int contextindex;
if (context < 1 || context > 8) {
context = 0;
}
if (!(session->showmask & (1 << context))) {
if (!(session->showmask & context)) {
/* no such output asked for */
return;
}
/* Find the first matching context string for this message */
for (contextindex = 0; contextindex < ARRAY_SIZE(contexts); contextindex++) {
if ((context & (1 << contextindex)) != 0) {
contexttext = contexts[contextindex];
break;
}
}
gettimeofday(&now, NULL);
if(!firstsec) {
firstsec = now.tv_sec;
@@ -346,14 +363,18 @@ _libssh2_debug(LIBSSH2_SESSION * session, int context, const char *format, ...)
now.tv_sec -= firstsec;
len = snprintf(buffer, sizeof(buffer), "[libssh2] %d.%06d %s: ",
(int)now.tv_sec, (int)now.tv_usec, contexts[context]);
(int)now.tv_sec, (int)now.tv_usec, contexttext);
va_start(vargs, format);
len += vsnprintf(buffer + len, 1535 - len, format, vargs);
buffer[len] = '\n';
va_end(vargs);
write(2, buffer, len + 1);
if (session->tracehandler) {
(session->tracehandler)(session, session->tracehandler_context, buffer, len + 1);
} else {
write(2, buffer, len + 1);
}
}
#else
@@ -364,6 +385,15 @@ libssh2_trace(LIBSSH2_SESSION * session, int bitmask)
(void) bitmask;
return 0;
}
LIBSSH2_API int
libssh2_trace_sethandler(LIBSSH2_SESSION *session, void* handler_context, libssh2_trace_handler_func callback)
{
(void) session;
(void) handler_context;
(void) callback;
return 0;
}
#endif
/* init the list head */
@@ -442,6 +472,10 @@ void _libssh2_list_insert(struct list_node *after, /* insert before this */
and must be made to point to 'entry' correctly */
if(entry->prev)
entry->prev->next = entry;
else
/* there was no node before this, so we make sure we point the head
pointer to this node */
after->head->first = entry;
/* after's prev entry points back to entry */
after->prev = entry;

View File

@@ -1,7 +1,9 @@
/* Copyright (C) 2006, 2007 The Written Word, Inc. All rights reserved.
* Author: Simon Josefsson
/* Copyright (C) 2009 Simon Josefsson
* Copyright (C) 2006, 2007 The Written Word, Inc. All rights reserved.
* Copyright (c) 2004-2006, Sara Golemon <sarag@libssh2.org>
*
* Author: Simon Josefsson
*
* Redistribution and use in source and binary forms,
* with or without modification, are permitted provided
* that the following conditions are met:
@@ -197,6 +199,110 @@ _libssh2_cipher_crypt(_libssh2_cipher_ctx * ctx,
return ret == 1 ? 0 : 1;
}
#if LIBSSH2_AES_CTR
#include <openssl/aes.h>
typedef struct
{
AES_KEY key;
unsigned char ctr[AES_BLOCK_SIZE];
} aes_ctr_ctx;
static int
aes_ctr_init(EVP_CIPHER_CTX *ctx, const unsigned char *key,
const unsigned char *iv, int enc) /* init key */
{
aes_ctr_ctx *c = malloc(sizeof(*c));
(void) enc;
if (c == NULL)
return 0;
AES_set_encrypt_key(key, 8 * ctx->key_len, &c->key);
memcpy(c->ctr, iv, AES_BLOCK_SIZE);
EVP_CIPHER_CTX_set_app_data(ctx, c);
return 1;
}
static int
aes_ctr_do_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
const unsigned char *in,
unsigned int inl) /* encrypt/decrypt data */
{
aes_ctr_ctx *c = EVP_CIPHER_CTX_get_app_data(ctx);
unsigned char b1[AES_BLOCK_SIZE];
size_t i;
if (inl != 16) /* libssh2 only ever encrypt one block */
return 0;
/*
To encrypt a packet P=P1||P2||...||Pn (where P1, P2, ..., Pn are each
blocks of length L), the encryptor first encrypts <X> with <cipher>
to obtain a block B1. The block B1 is then XORed with P1 to generate
the ciphertext block C1. The counter X is then incremented
*/
AES_encrypt(c->ctr, b1, &c->key);
for (i = 0; i < 16; i++)
*out++ = *in++ ^ b1[i];
i = 15;
while (c->ctr[i]++ == 0xFF) {
if (i == 0)
break;
i--;
}
return 1;
}
static int
aes_ctr_cleanup(EVP_CIPHER_CTX *ctx) /* cleanup ctx */
{
free(EVP_CIPHER_CTX_get_app_data(ctx));
return 1;
}
static const EVP_CIPHER *
make_ctr_evp (size_t keylen)
{
static EVP_CIPHER aes_ctr_cipher;
memset(&aes_ctr_cipher, 0, sizeof(aes_ctr_cipher));
aes_ctr_cipher.block_size = 16;
aes_ctr_cipher.key_len = keylen;
aes_ctr_cipher.iv_len = 16;
aes_ctr_cipher.init = aes_ctr_init;
aes_ctr_cipher.do_cipher = aes_ctr_do_cipher;
aes_ctr_cipher.cleanup = aes_ctr_cleanup;
return &aes_ctr_cipher;
}
const EVP_CIPHER *
_libssh2_EVP_aes_128_ctr(void)
{
return make_ctr_evp (16);
}
const EVP_CIPHER *
_libssh2_EVP_aes_192_ctr(void)
{
return make_ctr_evp (24);
}
const EVP_CIPHER *
_libssh2_EVP_aes_256_ctr(void)
{
return make_ctr_evp (32);
}
#endif /* LIBSSH2_AES_CTR */
/* TODO: Optionally call a passphrase callback specified by the
* calling program
*/
@@ -219,7 +325,7 @@ typedef void * (*pem_read_bio_func)(BIO *, void **, pem_password_cb *,
void * u);
static int
read_private_key_from_file(void ** key_ctx, LIBSSH2_SESSION * session,
read_private_key_from_file(void ** key_ctx,
pem_read_bio_func read_private_key,
const char * filename,
unsigned const char *passphrase)
@@ -233,7 +339,7 @@ read_private_key_from_file(void ** key_ctx, LIBSSH2_SESSION * session,
return -1;
}
*key_ctx = read_private_key(bp, NULL, (void *) passphrase_cb,
*key_ctx = read_private_key(bp, NULL, (pem_password_cb *) passphrase_cb,
(void *) passphrase);
BIO_free(bp);
@@ -257,7 +363,7 @@ _libssh2_rsa_new_private(libssh2_rsa_ctx ** rsa,
OpenSSL_add_all_ciphers();
}
return read_private_key_from_file((void **) rsa, session, read_rsa,
return read_private_key_from_file((void **) rsa, read_rsa,
filename, passphrase);
}
@@ -268,6 +374,7 @@ _libssh2_dsa_new_private(libssh2_dsa_ctx ** dsa,
{
pem_read_bio_func read_dsa =
(pem_read_bio_func) &PEM_read_bio_DSAPrivateKey;
(void) session;
if (!EVP_get_cipherbyname("des")) {
/* If this cipher isn't loaded it's a pretty good indication that none are.
@@ -277,7 +384,7 @@ _libssh2_dsa_new_private(libssh2_dsa_ctx ** dsa,
OpenSSL_add_all_ciphers();
}
return read_private_key_from_file((void **) dsa, session, read_dsa,
return read_private_key_from_file((void **) dsa, read_dsa,
filename, passphrase);
}
@@ -318,7 +425,7 @@ _libssh2_dsa_sha1_sign(libssh2_dsa_ctx * dsactx,
unsigned long hash_len, unsigned char *signature)
{
DSA_SIG *sig;
int r_len, s_len, rs_pad;
int r_len, s_len;
(void) hash_len;
sig = DSA_do_sign(hash, SHA_DIGEST_LENGTH, dsactx);
@@ -327,15 +434,20 @@ _libssh2_dsa_sha1_sign(libssh2_dsa_ctx * dsactx,
}
r_len = BN_num_bytes(sig->r);
if (r_len < 1 || r_len > 20) {
DSA_SIG_free(sig);
return -1;
}
s_len = BN_num_bytes(sig->s);
rs_pad = (2 * SHA_DIGEST_LENGTH) - (r_len + s_len);
if (rs_pad < 0) {
if (s_len < 1 || s_len > 20) {
DSA_SIG_free(sig);
return -1;
}
BN_bn2bin(sig->r, signature + rs_pad);
BN_bn2bin(sig->s, signature + rs_pad + r_len);
memset(signature, 0, 40);
BN_bn2bin(sig->r, signature + (20 - r_len));
BN_bn2bin(sig->s, signature + 20 + (20 - s_len));
DSA_SIG_free(sig);

View File

@@ -1,4 +1,6 @@
/* Copyright (C) 2006, 2007 The Written Word, Inc. All rights reserved.
/* Copyright (C) 2009 Simon Josefsson
* Copyright (C) 2006, 2007 The Written Word, Inc. All rights reserved.
*
* Author: Simon Josefsson
*
* Redistribution and use in source and binary forms,
@@ -71,6 +73,7 @@
#endif
#if OPENSSL_VERSION_NUMBER >= 0x00907000L && !defined(OPENSSL_NO_AES)
# define LIBSSH2_AES_CTR 1
# define LIBSSH2_AES 1
#else
# define LIBSSH2_AES 0
@@ -194,6 +197,9 @@ int _libssh2_dsa_sha1_sign(libssh2_dsa_ctx * dsactx,
#define _libssh2_cipher_aes256 EVP_aes_256_cbc
#define _libssh2_cipher_aes192 EVP_aes_192_cbc
#define _libssh2_cipher_aes128 EVP_aes_128_cbc
#define _libssh2_cipher_aes128ctr _libssh2_EVP_aes_128_ctr
#define _libssh2_cipher_aes192ctr _libssh2_EVP_aes_192_ctr
#define _libssh2_cipher_aes256ctr _libssh2_EVP_aes_256_ctr
#define _libssh2_cipher_blowfish EVP_bf_cbc
#define _libssh2_cipher_arcfour EVP_rc4
#define _libssh2_cipher_cast5 EVP_cast5_cbc
@@ -223,3 +229,7 @@ int _libssh2_cipher_crypt(_libssh2_cipher_ctx * ctx,
#define _libssh2_bn_bytes(bn) BN_num_bytes(bn)
#define _libssh2_bn_bits(bn) BN_num_bits(bn)
#define _libssh2_bn_free(bn) BN_clear_free(bn)
const EVP_CIPHER *_libssh2_EVP_aes_128_ctr(void);
const EVP_CIPHER *_libssh2_EVP_aes_192_ctr(void);
const EVP_CIPHER *_libssh2_EVP_aes_256_ctr(void);

View File

@@ -1,5 +1,6 @@
/* Copyright (c) 2004-2007, Sara Golemon <sarag@libssh2.org>
* Copyright (c) 2009 by Daniel Stenberg
* Copyright (c) 2010 Simon Josefsson
* All rights reserved.
*
* Redistribution and use in source and binary forms,
@@ -108,7 +109,7 @@ packet_queue_listener(LIBSSH2_SESSION * session, unsigned char *data,
listen_state->sport = _libssh2_ntohu32(s);
s += 4;
_libssh2_debug(session, LIBSSH2_DBG_CONN,
_libssh2_debug(session, LIBSSH2_TRACE_CONN,
"Remote received connection from %s:%ld to %s:%ld",
listen_state->shost, listen_state->sport,
listen_state->host, listen_state->port);
@@ -131,7 +132,7 @@ packet_queue_listener(LIBSSH2_SESSION * session, unsigned char *data,
(listen->queue_maxsize <= listen->queue_size)) {
/* Queue is full */
failure_code = 4; /* SSH_OPEN_RESOURCE_SHORTAGE */
_libssh2_debug(session, LIBSSH2_DBG_CONN,
_libssh2_debug(session, LIBSSH2_TRACE_CONN,
"Listener queue full, ignoring");
listen_state->state = libssh2_NB_state_sent;
break;
@@ -146,6 +147,8 @@ packet_queue_listener(LIBSSH2_SESSION * session, unsigned char *data,
listen_state->state = libssh2_NB_state_sent;
break;
}
listen_state->channel = channel;
memset(channel, 0, sizeof(LIBSSH2_CHANNEL));
channel->session = session;
@@ -181,7 +184,7 @@ packet_queue_listener(LIBSSH2_SESSION * session, unsigned char *data,
listen_state->initial_window_size;
channel->local.packet_size = listen_state->packet_size;
_libssh2_debug(session, LIBSSH2_DBG_CONN,
_libssh2_debug(session, LIBSSH2_TRACE_CONN,
"Connection queued: channel %lu/%lu win %lu/%lu packet %lu/%lu",
channel->local.id, channel->remote.id,
channel->local.window_size,
@@ -292,7 +295,7 @@ packet_x11_open(LIBSSH2_SESSION * session, unsigned char *data,
x11open_state->sport = _libssh2_ntohu32(s);
s += 4;
_libssh2_debug(session, LIBSSH2_DBG_CONN,
_libssh2_debug(session, LIBSSH2_TRACE_CONN,
"X11 Connection Received from %s:%ld on channel %lu",
x11open_state->shost, x11open_state->sport,
x11open_state->sender_channel);
@@ -340,7 +343,7 @@ packet_x11_open(LIBSSH2_SESSION * session, unsigned char *data,
channel->local.window_size = x11open_state->initial_window_size;
channel->local.packet_size = x11open_state->packet_size;
_libssh2_debug(session, LIBSSH2_DBG_CONN,
_libssh2_debug(session, LIBSSH2_TRACE_CONN,
"X11 Connection established: channel %lu/%lu win %lu/%lu packet %lu/%lu",
channel->local.id, channel->remote.id,
channel->local.window_size,
@@ -418,7 +421,7 @@ packet_x11_open(LIBSSH2_SESSION * session, unsigned char *data,
* _libssh2_packet_add
*
* Create a new packet and attach it to the brigade. Called from the transport
* layer when it as received a packet.
* layer when it has received a packet.
*
* The input pointer 'data' is pointing to allocated data that this function
* is asked to deal with so on failure OR success, it must be freed fine.
@@ -444,7 +447,7 @@ _libssh2_packet_add(LIBSSH2_SESSION * session, unsigned char *data,
memset(&session->packAdd_x11open_state, 0,
sizeof(session->packAdd_x11open_state));
_libssh2_debug(session, LIBSSH2_DBG_TRANS,
_libssh2_debug(session, LIBSSH2_TRACE_TRANS,
"Packet type %d received, length=%d",
(int) data[0], (int) datalen);
if (macstate == LIBSSH2_MAC_INVALID) {
@@ -481,8 +484,16 @@ _libssh2_packet_add(LIBSSH2_SESSION * session, unsigned char *data,
goto libssh2_packet_add_jump_point2;
} else if (session->packAdd_state == libssh2_NB_state_jump3) {
goto libssh2_packet_add_jump_point3;
} else if (session->packAdd_state == libssh2_NB_state_jump4) {
goto libssh2_packet_add_jump_point4;
} else if (session->packAdd_state == libssh2_NB_state_jump5) {
goto libssh2_packet_add_jump_point5;
}
/* FIXME: I've noticed that DATA is accessed without proper
* out-of-bounds checking (i.e., DATALEN) in many places
* below. --simon */
if (session->packAdd_state == libssh2_NB_state_allocated) {
/* A couple exceptions to the packet adding rule: */
switch (data[0]) {
@@ -510,7 +521,7 @@ _libssh2_packet_add(LIBSSH2_SESSION * session, unsigned char *data,
message[message_len] = '\0';
language = (char *) data + 9 + message_len + 3;
if (language_len) {
memcpy(language, language + 1, language_len);
memmove(language, language + 1, language_len);
}
language[language_len] = '\0';
@@ -518,7 +529,7 @@ _libssh2_packet_add(LIBSSH2_SESSION * session, unsigned char *data,
LIBSSH2_DISCONNECT(session, reason, message,
message_len, language, language_len);
}
_libssh2_debug(session, LIBSSH2_DBG_TRANS,
_libssh2_debug(session, LIBSSH2_TRACE_TRANS,
"Disconnect(%d): %s(%s)", reason,
message, language);
LIBSSH2_FREE(session, data);
@@ -531,11 +542,15 @@ _libssh2_packet_add(LIBSSH2_SESSION * session, unsigned char *data,
break;
case SSH_MSG_IGNORE:
/* As with disconnect, back it up one and add a trailing NULL */
memcpy(data + 4, data + 5, datalen - 5);
data[datalen] = '\0';
if (session->ssh_msg_ignore) {
LIBSSH2_IGNORE(session, (char *) data + 4, datalen - 5);
if (datalen >= 5) {
/* Back it up one and add a trailing NULL */
memmove(data, data + 1, datalen - 1);
data[datalen] = '\0';
if (session->ssh_msg_ignore) {
LIBSSH2_IGNORE(session, (char *) data + 4, datalen - 1);
}
} else if (session->ssh_msg_ignore) {
LIBSSH2_IGNORE(session, "", 0);
}
LIBSSH2_FREE(session, data);
session->packAdd_state = libssh2_NB_state_idle;
@@ -565,7 +580,7 @@ _libssh2_packet_add(LIBSSH2_SESSION * session, unsigned char *data,
message[message_len] = '\0';
language = (char *) data + 6 + message_len + 3;
if (language_len) {
memcpy(language, language + 1, language_len);
memmove(language, language + 1, language_len);
}
language[language_len] = '\0';
@@ -577,7 +592,7 @@ _libssh2_packet_add(LIBSSH2_SESSION * session, unsigned char *data,
* _libssh2_debug will actually truncate this for us so
* that it's not an inordinate about of data
*/
_libssh2_debug(session, LIBSSH2_DBG_TRANS,
_libssh2_debug(session, LIBSSH2_TRACE_TRANS,
"Debug Packet: %s", message);
LIBSSH2_FREE(session, data);
session->packAdd_state = libssh2_NB_state_idle;
@@ -585,6 +600,30 @@ _libssh2_packet_add(LIBSSH2_SESSION * session, unsigned char *data,
}
break;
case SSH_MSG_GLOBAL_REQUEST:
{
uint32_t strlen = _libssh2_ntohu32(data + 1);
unsigned char want_reply = data[5 + strlen];
_libssh2_debug(session,
LIBSSH2_TRACE_CONN,
"Received global request type %.*s (wr %X)",
strlen, data + 5, want_reply);
if (want_reply) {
libssh2_packet_add_jump_point5:
session->packAdd_state = libssh2_NB_state_jump5;
data[0] = SSH_MSG_REQUEST_FAILURE;
rc = _libssh2_transport_write(session, data, 1);
if (rc == PACKET_EAGAIN)
return rc;
LIBSSH2_FREE(session, data);
session->packAdd_state = libssh2_NB_state_idle;
return 0;
}
}
break;
case SSH_MSG_CHANNEL_EXTENDED_DATA:
/* streamid(4) */
session->packAdd_data_head += 4;
@@ -610,7 +649,7 @@ _libssh2_packet_add(LIBSSH2_SESSION * session, unsigned char *data,
stream_id = _libssh2_ntohu32(data + 5);
}
_libssh2_debug(session, LIBSSH2_DBG_CONN,
_libssh2_debug(session, LIBSSH2_TRACE_CONN,
"%d bytes packet_add() for %lu/%lu/%lu",
(int) (datalen - session->packAdd_data_head),
session->packAdd_channel->local.id,
@@ -624,7 +663,7 @@ _libssh2_packet_add(LIBSSH2_SESSION * session, unsigned char *data,
/* Pretend we didn't receive this */
LIBSSH2_FREE(session, data);
_libssh2_debug(session, LIBSSH2_DBG_CONN,
_libssh2_debug(session, LIBSSH2_TRACE_CONN,
"Ignoring extended data and refunding %d bytes",
(int) (datalen - 13));
/* Adjust the window based on the block we just freed */
@@ -707,7 +746,7 @@ _libssh2_packet_add(LIBSSH2_SESSION * session, unsigned char *data,
}
_libssh2_debug(session,
LIBSSH2_DBG_CONN,
LIBSSH2_TRACE_CONN,
"EOF received for channel %lu/%lu",
session->packAdd_channel->local.id,
session->packAdd_channel->remote.id);
@@ -718,19 +757,28 @@ _libssh2_packet_add(LIBSSH2_SESSION * session, unsigned char *data,
return 0;
case SSH_MSG_CHANNEL_REQUEST:
if (_libssh2_ntohu32(data + 5) == sizeof("exit-status") - 1
{
uint32_t channel = _libssh2_ntohu32(data + 1);
uint32_t strlen = _libssh2_ntohu32(data + 5);
unsigned char want_reply = data[9 + strlen];
_libssh2_debug(session,
LIBSSH2_TRACE_CONN,
"Channel %d received request type %.*s (wr %X)",
channel, strlen, data + 9, want_reply);
if (strlen == sizeof("exit-status") - 1
&& !memcmp("exit-status", data + 9,
sizeof("exit-status") - 1)) {
/* we've got "exit-status" packet. Set the session value */
session->packAdd_channel =
_libssh2_channel_locate(session,
_libssh2_ntohu32(data + 1));
_libssh2_channel_locate(session, channel);
if (session->packAdd_channel) {
session->packAdd_channel->exit_status =
_libssh2_ntohu32(data + 9 + sizeof("exit-status"));
_libssh2_debug(session, LIBSSH2_DBG_CONN,
_libssh2_debug(session, LIBSSH2_TRACE_CONN,
"Exit status %lu received for channel %lu/%lu",
session->packAdd_channel->exit_status,
session->packAdd_channel->local.id,
@@ -741,7 +789,20 @@ _libssh2_packet_add(LIBSSH2_SESSION * session, unsigned char *data,
session->packAdd_state = libssh2_NB_state_idle;
return 0;
}
if (want_reply) {
libssh2_packet_add_jump_point4:
session->packAdd_state = libssh2_NB_state_jump4;
data[0] = SSH_MSG_CHANNEL_FAILURE;
rc = _libssh2_transport_write(session, data, 5);
if (rc == PACKET_EAGAIN)
return rc;
LIBSSH2_FREE(session, data);
session->packAdd_state = libssh2_NB_state_idle;
return 0;
}
break;
}
case SSH_MSG_CHANNEL_CLOSE:
session->packAdd_channel =
@@ -753,7 +814,7 @@ _libssh2_packet_add(LIBSSH2_SESSION * session, unsigned char *data,
session->packAdd_state = libssh2_NB_state_idle;
return 0;
}
_libssh2_debug(session, LIBSSH2_DBG_CONN,
_libssh2_debug(session, LIBSSH2_TRACE_CONN,
"Close received for channel %lu/%lu",
session->packAdd_channel->local.id,
session->packAdd_channel->remote.id);
@@ -810,7 +871,7 @@ _libssh2_packet_add(LIBSSH2_SESSION * session, unsigned char *data,
if (session->packAdd_channel && bytestoadd) {
session->packAdd_channel->local.window_size += bytestoadd;
}
_libssh2_debug(session, LIBSSH2_DBG_CONN,
_libssh2_debug(session, LIBSSH2_TRACE_CONN,
"Window adjust received for channel %lu/%lu, adding %lu bytes, new window_size=%lu",
session->packAdd_channel->local.id,
session->packAdd_channel->remote.id,
@@ -858,7 +919,7 @@ _libssh2_packet_add(LIBSSH2_SESSION * session, unsigned char *data,
* Well, it's already in the brigade,
* let's just call back into ourselves
*/
_libssh2_debug(session, LIBSSH2_DBG_TRANS, "Renegotiating Keys");
_libssh2_debug(session, LIBSSH2_TRACE_TRANS, "Renegotiating Keys");
session->packAdd_state = libssh2_NB_state_sent2;
}
@@ -909,7 +970,7 @@ _libssh2_packet_ask(LIBSSH2_SESSION * session, unsigned char packet_type,
{
LIBSSH2_PACKET *packet = _libssh2_list_first(&session->packets);
_libssh2_debug(session, LIBSSH2_DBG_TRANS,
_libssh2_debug(session, LIBSSH2_TRACE_TRANS,
"Looking for packet of type: %d", (int) packet_type);
while (packet) {
@@ -1048,7 +1109,7 @@ _libssh2_packet_burn(LIBSSH2_SESSION * session,
return i;
}
_libssh2_debug(session, LIBSSH2_DBG_TRANS,
_libssh2_debug(session, LIBSSH2_TRACE_TRANS,
"Blocking until packet becomes available to burn");
*state = libssh2_NB_state_created;
}

View File

@@ -353,7 +353,7 @@ libssh2_publickey_init(LIBSSH2_SESSION * session)
session->pkeyInit_pkey = NULL;
session->pkeyInit_channel = NULL;
_libssh2_debug(session, LIBSSH2_DBG_PUBLICKEY,
_libssh2_debug(session, LIBSSH2_TRACE_PUBLICKEY,
"Initializing publickey subsystem");
session->pkeyInit_state = libssh2_NB_state_allocated;
@@ -434,7 +434,7 @@ libssh2_publickey_init(LIBSSH2_SESSION * session)
_libssh2_htonu32(s, LIBSSH2_PUBLICKEY_VERSION);
s += 4;
_libssh2_debug(session, LIBSSH2_DBG_PUBLICKEY,
_libssh2_debug(session, LIBSSH2_TRACE_PUBLICKEY,
"Sending publickey version packet advertising version %d support",
(int) LIBSSH2_PUBLICKEY_VERSION);
@@ -519,13 +519,13 @@ libssh2_publickey_init(LIBSSH2_SESSION * session)
session->pkeyInit_pkey->version = _libssh2_ntohu32(s);
if (session->pkeyInit_pkey->version >
LIBSSH2_PUBLICKEY_VERSION) {
_libssh2_debug(session, LIBSSH2_DBG_PUBLICKEY,
_libssh2_debug(session, LIBSSH2_TRACE_PUBLICKEY,
"Truncating remote publickey version from %lu",
session->pkeyInit_pkey->version);
session->pkeyInit_pkey->version =
LIBSSH2_PUBLICKEY_VERSION;
}
_libssh2_debug(session, LIBSSH2_DBG_PUBLICKEY,
_libssh2_debug(session, LIBSSH2_TRACE_PUBLICKEY,
"Enabling publickey subsystem version %lu",
session->pkeyInit_pkey->version);
LIBSSH2_FREE(session, session->pkeyInit_data);
@@ -590,7 +590,7 @@ libssh2_publickey_add_ex(LIBSSH2_PUBLICKEY * pkey, const unsigned char *name,
if (pkey->add_state == libssh2_NB_state_idle) {
pkey->add_packet = NULL;
_libssh2_debug(session, LIBSSH2_DBG_PUBLICKEY, "Adding %s publickey",
_libssh2_debug(session, LIBSSH2_TRACE_PUBLICKEY, "Adding %s publickey",
name);
if (pkey->version == 1) {
@@ -671,7 +671,7 @@ libssh2_publickey_add_ex(LIBSSH2_PUBLICKEY * pkey, const unsigned char *name,
}
}
_libssh2_debug(session, LIBSSH2_DBG_PUBLICKEY,
_libssh2_debug(session, LIBSSH2_TRACE_PUBLICKEY,
"Sending publickey \"add\" packet: type=%s blob_len=%ld num_attrs=%ld",
name, blob_len, num_attrs);
@@ -747,7 +747,7 @@ libssh2_publickey_remove_ex(LIBSSH2_PUBLICKEY * pkey,
memcpy(pkey->remove_s, blob, blob_len);
pkey->remove_s += blob_len;
_libssh2_debug(session, LIBSSH2_DBG_PUBLICKEY,
_libssh2_debug(session, LIBSSH2_TRACE_PUBLICKEY,
"Sending publickey \"remove\" packet: type=%s blob_len=%ld",
name, blob_len);
@@ -809,7 +809,7 @@ libssh2_publickey_list_fetch(LIBSSH2_PUBLICKEY * pkey, unsigned long *num_keys,
memcpy(pkey->listFetch_s, "list", sizeof("list") - 1);
pkey->listFetch_s += sizeof("list") - 1;
_libssh2_debug(session, LIBSSH2_DBG_PUBLICKEY,
_libssh2_debug(session, LIBSSH2_TRACE_PUBLICKEY,
"Sending publickey \"list\" packet");
pkey->listFetch_state = libssh2_NB_state_created;

View File

@@ -301,7 +301,7 @@ scp_recv(LIBSSH2_SESSION * session, const char *path, struct stat * sb)
session->scpRecv_command_len - cmd_len);
_libssh2_debug(session, LIBSSH2_DBG_SCP,
_libssh2_debug(session, LIBSSH2_TRACE_SCP,
"Opening channel for SCP receive");
session->scpRecv_state = libssh2_NB_state_created;
@@ -350,7 +350,7 @@ scp_recv(LIBSSH2_SESSION * session, const char *path, struct stat * sb)
LIBSSH2_FREE(session, session->scpRecv_command);
session->scpRecv_command = NULL;
_libssh2_debug(session, LIBSSH2_DBG_SCP, "Sending initial wakeup");
_libssh2_debug(session, LIBSSH2_TRACE_SCP, "Sending initial wakeup");
/* SCP ACK */
session->scpRecv_response[0] = '\0';
@@ -569,7 +569,7 @@ scp_recv(LIBSSH2_SESSION * session, const char *path, struct stat * sb)
goto scp_recv_error;
}
_libssh2_debug(session, LIBSSH2_DBG_SCP,
_libssh2_debug(session, LIBSSH2_TRACE_SCP,
"mtime = %ld, atime = %ld",
session->scpRecv_mtime, session->scpRecv_atime);
@@ -731,7 +731,7 @@ scp_recv(LIBSSH2_SESSION * session, const char *path, struct stat * sb)
} else if (rc != 1) {
goto scp_recv_error;
}
_libssh2_debug(session, LIBSSH2_DBG_SCP,
_libssh2_debug(session, LIBSSH2_TRACE_SCP,
"mode = 0%lo size = %ld", session->scpRecv_mode,
session->scpRecv_size);
@@ -816,7 +816,7 @@ scp_send(LIBSSH2_SESSION * session, const char *path, int mode,
session->scpSend_command[session->scpSend_command_len - 1] = '\0';
_libssh2_debug(session, LIBSSH2_DBG_SCP,
_libssh2_debug(session, LIBSSH2_TRACE_SCP,
"Opening channel for SCP send");
/* Allocate a channel */
@@ -892,7 +892,7 @@ scp_send(LIBSSH2_SESSION * session, const char *path, int mode,
snprintf((char *) session->scpSend_response,
LIBSSH2_SCP_RESPONSE_BUFLEN, "T%ld 0 %ld 0\n", mtime,
atime);
_libssh2_debug(session, LIBSSH2_DBG_SCP, "Sent %s",
_libssh2_debug(session, LIBSSH2_TRACE_SCP, "Sent %s",
session->scpSend_response);
}
@@ -953,7 +953,7 @@ scp_send(LIBSSH2_SESSION * session, const char *path, int mode,
snprintf((char *) session->scpSend_response,
LIBSSH2_SCP_RESPONSE_BUFLEN, "C0%o %lu %s\n", mode,
(unsigned long) size, base);
_libssh2_debug(session, LIBSSH2_DBG_SCP, "Sent %s",
_libssh2_debug(session, LIBSSH2_TRACE_SCP, "Sent %s",
session->scpSend_response);
session->scpSend_state = libssh2_NB_state_sent5;

View File

@@ -111,6 +111,12 @@ banner_receive(LIBSSH2_SESSION * session)
ret = _libssh2_recv(session->socket_fd, &c, 1,
LIBSSH2_SOCKET_RECV_FLAGS(session));
if (ret < 0)
_libssh2_debug(session, LIBSSH2_TRACE_SOCKET,
"Error recving %d bytes to %p: %d", 1, &c, errno);
else
_libssh2_debug(session, LIBSSH2_TRACE_SOCKET,
"Recved %d bytes to %p", ret, &c);
if (ret < 0) {
if (errno == EAGAIN) {
@@ -162,7 +168,7 @@ banner_receive(LIBSSH2_SESSION * session)
}
memcpy(session->remote.banner, session->banner_TxRx_banner, banner_len);
session->remote.banner[banner_len] = '\0';
_libssh2_debug(session, LIBSSH2_DBG_TRANS, "Received Banner: %s",
_libssh2_debug(session, LIBSSH2_TRACE_TRANS, "Received Banner: %s",
session->remote.banner);
return 0;
}
@@ -203,7 +209,7 @@ banner_send(LIBSSH2_SESSION * session)
banner[255] = '\0';
}
_libssh2_debug(session, LIBSSH2_DBG_TRANS, "Sending Banner: %s",
_libssh2_debug(session, LIBSSH2_TRACE_TRANS, "Sending Banner: %s",
banner_dup);
#endif
@@ -217,6 +223,15 @@ banner_send(LIBSSH2_SESSION * session)
banner + session->banner_TxRx_total_send,
banner_len - session->banner_TxRx_total_send,
LIBSSH2_SOCKET_SEND_FLAGS(session));
if (ret < 0)
_libssh2_debug(session, LIBSSH2_TRACE_SOCKET,
"Error sending %d bytes: %d",
banner_len - session->banner_TxRx_total_send, errno);
else
_libssh2_debug(session, LIBSSH2_TRACE_SOCKET,
"Sent %d/%d bytes at %p+%d", ret,
banner_len - session->banner_TxRx_total_send,
banner, session->banner_TxRx_total_send);
if (ret != (banner_len - session->banner_TxRx_total_send)) {
if ((ret > 0) || ((ret == -1) && (errno == EAGAIN))) {
@@ -395,7 +410,7 @@ libssh2_banner_set(LIBSSH2_SESSION * session, const char *banner)
memcpy(session->local.banner, banner, banner_len);
session->local.banner[banner_len] = '\0';
_libssh2_debug(session, LIBSSH2_DBG_TRANS, "Setting local Banner: %s",
_libssh2_debug(session, LIBSSH2_TRACE_TRANS, "Setting local Banner: %s",
session->local.banner);
session->local.banner[banner_len++] = '\r';
session->local.banner[banner_len++] = '\n';
@@ -441,7 +456,7 @@ libssh2_session_init_ex(LIBSSH2_ALLOC_FUNC((*my_alloc)),
session->realloc = local_realloc;
session->abstract = abstract;
session->api_block_mode = 1; /* blocking API by default */
_libssh2_debug(session, LIBSSH2_DBG_TRANS,
_libssh2_debug(session, LIBSSH2_TRACE_TRANS,
"New session resource allocated");
libssh2_crypto_init();
}
@@ -490,7 +505,7 @@ libssh2_session_callback_set(LIBSSH2_SESSION * session,
return oldcb;
}
_libssh2_debug(session, LIBSSH2_DBG_TRANS, "Setting Callback %d", cbtype);
_libssh2_debug(session, LIBSSH2_TRACE_TRANS, "Setting Callback %d", cbtype);
return NULL;
}
@@ -540,10 +555,9 @@ session_startup(LIBSSH2_SESSION *session, libssh2_socket_t sock)
int rc;
if (session->startup_state == libssh2_NB_state_idle) {
_libssh2_debug(session, LIBSSH2_DBG_TRANS,
_libssh2_debug(session, LIBSSH2_TRACE_TRANS,
"session_startup for socket %d", sock);
/* FIXME: on some platforms (like win32) sockets are unsigned */
if (sock < 0) {
if (INVALID_SOCKET == sock) {
/* Did we forget something? */
libssh2_error(session, LIBSSH2_ERROR_SOCKET_NONE,
"Bad socket provided", 0);
@@ -595,7 +609,7 @@ session_startup(LIBSSH2_SESSION *session, libssh2_socket_t sock)
}
if (session->startup_state == libssh2_NB_state_sent2) {
_libssh2_debug(session, LIBSSH2_DBG_TRANS,
_libssh2_debug(session, LIBSSH2_TRACE_TRANS,
"Requesting userauth service");
/* Request the userauth service */
@@ -686,7 +700,7 @@ session_free(LIBSSH2_SESSION *session)
LIBSSH2_LISTENER *l;
if (session->free_state == libssh2_NB_state_idle) {
_libssh2_debug(session, LIBSSH2_DBG_TRANS, "Freeing session resource",
_libssh2_debug(session, LIBSSH2_TRACE_TRANS, "Freeing session resource",
session->remote.banner);
session->state = libssh2_NB_state_created;
@@ -946,7 +960,7 @@ session_disconnect(LIBSSH2_SESSION *session, int reason,
int rc;
if (session->disconnect_state == libssh2_NB_state_idle) {
_libssh2_debug(session, LIBSSH2_DBG_TRANS,
_libssh2_debug(session, LIBSSH2_TRACE_TRANS,
"Disconnecting: reason=%d, desc=%s, lang=%s", reason,
description, lang);
if (description) {
@@ -1192,7 +1206,7 @@ int
_libssh2_session_set_blocking(LIBSSH2_SESSION *session, int blocking)
{
int bl = session->api_block_mode;
_libssh2_debug(session, LIBSSH2_DBG_CONN,
_libssh2_debug(session, LIBSSH2_TRACE_CONN,
"Setting blocking mode %s", blocking?"ON":"OFF");
session->api_block_mode = blocking;

View File

@@ -118,7 +118,7 @@ sftp_packet_add(LIBSSH2_SFTP *sftp, unsigned char *data,
LIBSSH2_SESSION *session = sftp->channel->session;
LIBSSH2_PACKET *packet;
_libssh2_debug(session, LIBSSH2_DBG_SFTP, "Received packet %d (len %d)",
_libssh2_debug(session, LIBSSH2_TRACE_SFTP, "Received packet %d (len %d)",
(int) data[0], data_len);
packet = LIBSSH2_ALLOC(session, sizeof(LIBSSH2_PACKET));
if (!packet) {
@@ -153,7 +153,7 @@ sftp_packet_read(LIBSSH2_SFTP *sftp)
ssize_t bytes_received;
int rc;
_libssh2_debug(session, LIBSSH2_DBG_SFTP, "recv packet");
_libssh2_debug(session, LIBSSH2_TRACE_SFTP, "recv packet");
/* If there was a previous partial, start using it */
if (sftp->partial_packet) {
@@ -163,7 +163,7 @@ sftp_packet_read(LIBSSH2_SFTP *sftp)
packet_received = sftp->partial_received;
sftp->partial_packet = NULL;
_libssh2_debug(session, LIBSSH2_DBG_SFTP,
_libssh2_debug(session, LIBSSH2_TRACE_SFTP,
"partial read cont, len: %lu", packet_len);
}
else {
@@ -181,7 +181,7 @@ sftp_packet_read(LIBSSH2_SFTP *sftp)
}
packet_len = _libssh2_ntohu32(buffer);
_libssh2_debug(session, LIBSSH2_DBG_SFTP,
_libssh2_debug(session, LIBSSH2_TRACE_SFTP,
"Data begin - Packet Length: %lu", packet_len);
if (packet_len > LIBSSH2_SFTP_PACKET_MAXLEN) {
libssh2_error(session, LIBSSH2_ERROR_CHANNEL_PACKET_EXCEEDED,
@@ -251,7 +251,7 @@ sftp_packet_ask(LIBSSH2_SFTP *sftp, unsigned char packet_type,
unsigned char match_buf[5];
int match_len;
_libssh2_debug(session, LIBSSH2_DBG_SFTP, "Asking for %d packet",
_libssh2_debug(session, LIBSSH2_TRACE_SFTP, "Asking for %d packet",
(int) packet_type);
match_buf[0] = packet_type;
@@ -293,12 +293,12 @@ sftp_packet_require(LIBSSH2_SFTP *sftp, unsigned char packet_type,
LIBSSH2_SESSION *session = sftp->channel->session;
int ret;
_libssh2_debug(session, LIBSSH2_DBG_SFTP, "Requiring packet %d id %ld",
_libssh2_debug(session, LIBSSH2_TRACE_SFTP, "Requiring packet %d id %ld",
(int) packet_type, request_id);
if (sftp_packet_ask(sftp, packet_type, request_id, data, data_len) == 0) {
/* The right packet was available in the packet brigade */
_libssh2_debug(session, LIBSSH2_DBG_SFTP, "Got %d",
_libssh2_debug(session, LIBSSH2_TRACE_SFTP, "Got %d",
(int) packet_type);
return 0;
}
@@ -314,7 +314,7 @@ sftp_packet_require(LIBSSH2_SFTP *sftp, unsigned char packet_type,
/* data was read, check the queue again */
if (!sftp_packet_ask(sftp, packet_type, request_id, data, data_len)) {
/* The right packet was available in the packet brigade */
_libssh2_debug(session, LIBSSH2_DBG_SFTP, "Got %d",
_libssh2_debug(session, LIBSSH2_TRACE_SFTP, "Got %d",
(int) packet_type);
return 0;
}
@@ -530,7 +530,7 @@ static LIBSSH2_SFTP *sftp_init(LIBSSH2_SESSION *session)
LIBSSH2_SFTP *sftp_handle;
if (session->sftpInit_state == libssh2_NB_state_idle) {
_libssh2_debug(session, LIBSSH2_DBG_SFTP,
_libssh2_debug(session, LIBSSH2_TRACE_SFTP,
"Initializing SFTP subsystem");
/*
@@ -616,7 +616,7 @@ static LIBSSH2_SFTP *sftp_init(LIBSSH2_SESSION *session)
session->sftpInit_buffer[4] = SSH_FXP_INIT;
_libssh2_htonu32(session->sftpInit_buffer + 5, LIBSSH2_SFTP_VERSION);
_libssh2_debug(session, LIBSSH2_DBG_SFTP,
_libssh2_debug(session, LIBSSH2_TRACE_SFTP,
"Sending FXP_INIT packet advertising version %d support",
(int) LIBSSH2_SFTP_VERSION);
@@ -661,12 +661,12 @@ static LIBSSH2_SFTP *sftp_init(LIBSSH2_SESSION *session)
sftp_handle->version = _libssh2_ntohu32(s);
s += 4;
if (sftp_handle->version > LIBSSH2_SFTP_VERSION) {
_libssh2_debug(session, LIBSSH2_DBG_SFTP,
_libssh2_debug(session, LIBSSH2_TRACE_SFTP,
"Truncating remote SFTP version from %lu",
sftp_handle->version);
sftp_handle->version = LIBSSH2_SFTP_VERSION;
}
_libssh2_debug(session, LIBSSH2_DBG_SFTP,
_libssh2_debug(session, LIBSSH2_TRACE_SFTP,
"Enabling SFTP version %lu compatability",
sftp_handle->version);
while (s < (data + data_len)) {
@@ -864,7 +864,7 @@ sftp_open(LIBSSH2_SFTP *sftp, const char *filename,
s += sftp_attr2bin(s, &attrs);
}
_libssh2_debug(session, LIBSSH2_DBG_SFTP, "Sending %s open request",
_libssh2_debug(session, LIBSSH2_TRACE_SFTP, "Sending %s open request",
(open_type ==
LIBSSH2_SFTP_OPENFILE) ? "file" : "directory");
@@ -925,7 +925,7 @@ sftp_open(LIBSSH2_SFTP *sftp, const char *filename,
sftp->last_errno = _libssh2_ntohu32(data + 5);
if(LIBSSH2_FX_OK == sftp->last_errno) {
_libssh2_debug(session, LIBSSH2_DBG_SFTP, "got HANDLE FXOK!");
_libssh2_debug(session, LIBSSH2_TRACE_SFTP, "got HANDLE FXOK!");
/* silly situation, but check for a HANDLE */
rc = sftp_packet_require(sftp, SSH_FXP_HANDLE,
@@ -943,7 +943,7 @@ sftp_open(LIBSSH2_SFTP *sftp, const char *filename,
if(badness) {
libssh2_error(session, LIBSSH2_ERROR_SFTP_PROTOCOL,
"Failed opening remote file", 0);
_libssh2_debug(session, LIBSSH2_DBG_SFTP, "got FXP_STATUS %d",
_libssh2_debug(session, LIBSSH2_TRACE_SFTP, "got FXP_STATUS %d",
sftp->last_errno);
LIBSSH2_FREE(session, data);
return NULL;
@@ -979,7 +979,7 @@ sftp_open(LIBSSH2_SFTP *sftp, const char *filename,
fp->u.file.offset = 0;
_libssh2_debug(session, LIBSSH2_DBG_SFTP, "Open command successful");
_libssh2_debug(session, LIBSSH2_TRACE_SFTP, "Open command successful");
return fp;
}
@@ -1019,7 +1019,7 @@ static ssize_t sftp_read(LIBSSH2_SFTP_HANDLE * handle, char *buffer,
int retcode;
if (sftp->read_state == libssh2_NB_state_idle) {
_libssh2_debug(session, LIBSSH2_DBG_SFTP,
_libssh2_debug(session, LIBSSH2_TRACE_SFTP,
"Reading %lu bytes from SFTP handle",
(unsigned long) buffer_maxlen);
packet = handle->request_packet;
@@ -1057,7 +1057,7 @@ static ssize_t sftp_read(LIBSSH2_SFTP_HANDLE * handle, char *buffer,
bytes_requested = LIBSSH2_SFTP_PACKET_MAXLEN - 13;
}
#ifdef LIBSSH2_DEBUG_SFTP
_libssh2_debug(session, LIBSSH2_DBG_SFTP,
_libssh2_debug(session, LIBSSH2_TRACE_SFTP,
"Requesting %lu bytes from SFTP handle",
(unsigned long) bytes_requested);
#endif
@@ -1153,7 +1153,7 @@ static ssize_t sftp_read(LIBSSH2_SFTP_HANDLE * handle, char *buffer,
return -1;
}
#ifdef LIBSSH2_DEBUG_SFTP
_libssh2_debug(session, LIBSSH2_DBG_SFTP, "%lu bytes returned",
_libssh2_debug(session, LIBSSH2_TRACE_SFTP, "%lu bytes returned",
(unsigned long) bytes_read);
#endif
memcpy(buffer + total_read, data + 9, bytes_read);
@@ -1257,7 +1257,7 @@ static int sftp_readdir(LIBSSH2_SFTP_HANDLE *handle, char *buffer,
LIBSSH2_FREE(session, handle->u.dir.names_packet);
}
_libssh2_debug(session, LIBSSH2_DBG_SFTP,
_libssh2_debug(session, LIBSSH2_TRACE_SFTP,
"libssh2_sftp_readdir_ex() return %d",
filename_len);
return filename_len;
@@ -1288,7 +1288,7 @@ static int sftp_readdir(LIBSSH2_SFTP_HANDLE *handle, char *buffer,
}
if (sftp->readdir_state == libssh2_NB_state_created) {
_libssh2_debug(session, LIBSSH2_DBG_SFTP,
_libssh2_debug(session, LIBSSH2_TRACE_SFTP,
"Reading entries from directory handle");
retcode = _libssh2_channel_write(channel, 0,
(char *) sftp->readdir_packet,
@@ -1340,7 +1340,7 @@ static int sftp_readdir(LIBSSH2_SFTP_HANDLE *handle, char *buffer,
}
num_names = _libssh2_ntohu32(data + 5);
_libssh2_debug(session, LIBSSH2_DBG_SFTP, "%lu entries returned",
_libssh2_debug(session, LIBSSH2_TRACE_SFTP, "%lu entries returned",
num_names);
if (num_names <= 0) {
LIBSSH2_FREE(session, data);
@@ -1431,7 +1431,7 @@ static ssize_t sftp_write(LIBSSH2_SFTP_HANDLE *handle, const char *buffer,
packet_len = handle->handle_len + count + 25;
if (sftp->write_state == libssh2_NB_state_idle) {
_libssh2_debug(session, LIBSSH2_DBG_SFTP, "Writing %lu bytes",
_libssh2_debug(session, LIBSSH2_TRACE_SFTP, "Writing %lu bytes",
(unsigned long) count);
s = sftp->write_packet = LIBSSH2_ALLOC(session, packet_len);
if (!sftp->write_packet) {
@@ -1541,7 +1541,7 @@ static int sftp_fstat(LIBSSH2_SFTP_HANDLE *handle,
int rc;
if (sftp->fstat_state == libssh2_NB_state_idle) {
_libssh2_debug(session, LIBSSH2_DBG_SFTP, "Issuing %s command",
_libssh2_debug(session, LIBSSH2_TRACE_SFTP, "Issuing %s command",
setstat ? "set-stat" : "stat");
s = sftp->fstat_packet = LIBSSH2_ALLOC(session, packet_len);
if (!sftp->fstat_packet) {
@@ -1618,6 +1618,7 @@ static int sftp_fstat(LIBSSH2_SFTP_HANDLE *handle,
}
sftp_bin2attr(attrs, data + 5);
LIBSSH2_FREE(session, data);
return 0;
}
@@ -1692,7 +1693,7 @@ sftp_close_handle(LIBSSH2_SFTP_HANDLE *handle)
int rc;
if (handle->close_state == libssh2_NB_state_idle) {
_libssh2_debug(session, LIBSSH2_DBG_SFTP, "Closing handle");
_libssh2_debug(session, LIBSSH2_TRACE_SFTP, "Closing handle");
s = handle->close_packet = LIBSSH2_ALLOC(session, packet_len);
if (!handle->close_packet) {
libssh2_error(session, LIBSSH2_ERROR_ALLOC,
@@ -1803,7 +1804,7 @@ static int sftp_unlink(LIBSSH2_SFTP *sftp, const char *filename,
int rc;
if (sftp->unlink_state == libssh2_NB_state_idle) {
_libssh2_debug(session, LIBSSH2_DBG_SFTP, "Unlinking %s", filename);
_libssh2_debug(session, LIBSSH2_TRACE_SFTP, "Unlinking %s", filename);
s = sftp->unlink_packet = LIBSSH2_ALLOC(session, packet_len);
if (!sftp->unlink_packet) {
libssh2_error(session, LIBSSH2_ERROR_ALLOC,
@@ -1915,7 +1916,7 @@ static int sftp_rename(LIBSSH2_SFTP *sftp, const char *source_filename,
}
if (sftp->rename_state == libssh2_NB_state_idle) {
_libssh2_debug(session, LIBSSH2_DBG_SFTP, "Renaming %s to %s",
_libssh2_debug(session, LIBSSH2_TRACE_SFTP, "Renaming %s to %s",
source_filename, dest_filename);
sftp->rename_s = sftp->rename_packet =
LIBSSH2_ALLOC(session, packet_len);
@@ -2051,7 +2052,7 @@ static int sftp_mkdir(LIBSSH2_SFTP *sftp, const char *path,
int rc;
if (sftp->mkdir_state == libssh2_NB_state_idle) {
_libssh2_debug(session, LIBSSH2_DBG_SFTP,
_libssh2_debug(session, LIBSSH2_TRACE_SFTP,
"Creating directory %s with mode 0%lo", path, mode);
s = packet = LIBSSH2_ALLOC(session, packet_len);
if (!packet) {
@@ -2115,7 +2116,7 @@ static int sftp_mkdir(LIBSSH2_SFTP *sftp, const char *path,
LIBSSH2_FREE(session, data);
if (retcode == LIBSSH2_FX_OK) {
_libssh2_debug(session, LIBSSH2_DBG_SFTP, "OK!");
_libssh2_debug(session, LIBSSH2_TRACE_SFTP, "OK!");
return 0;
} else {
libssh2_error(session, LIBSSH2_ERROR_SFTP_PROTOCOL,
@@ -2155,7 +2156,7 @@ static int sftp_rmdir(LIBSSH2_SFTP *sftp, const char *path,
int rc;
if (sftp->rmdir_state == libssh2_NB_state_idle) {
_libssh2_debug(session, LIBSSH2_DBG_SFTP, "Removing directory: %s",
_libssh2_debug(session, LIBSSH2_TRACE_SFTP, "Removing directory: %s",
path);
s = sftp->rmdir_packet = LIBSSH2_ALLOC(session, packet_len);
if (!sftp->rmdir_packet) {
@@ -2257,7 +2258,7 @@ static int sftp_stat(LIBSSH2_SFTP *sftp, const char *path,
int rc;
if (sftp->stat_state == libssh2_NB_state_idle) {
_libssh2_debug(session, LIBSSH2_DBG_SFTP, "%s %s",
_libssh2_debug(session, LIBSSH2_TRACE_SFTP, "%s %s",
(stat_type == LIBSSH2_SFTP_SETSTAT) ? "Set-statting" :
(stat_type ==
LIBSSH2_SFTP_LSTAT ? "LStatting" : "Statting"), path);
@@ -2399,7 +2400,7 @@ static int sftp_symlink(LIBSSH2_SFTP *sftp, const char *path,
return -1;
}
_libssh2_debug(session, LIBSSH2_DBG_SFTP, "%s %s on %s",
_libssh2_debug(session, LIBSSH2_TRACE_SFTP, "%s %s on %s",
(link_type ==
LIBSSH2_SFTP_SYMLINK) ? "Creating" : "Reading",
(link_type ==

View File

@@ -41,6 +41,7 @@
#include "libssh2_priv.h"
#include <errno.h>
#include <fcntl.h>
#include <ctype.h>
#include <assert.h>
@@ -57,36 +58,58 @@ debugdump(LIBSSH2_SESSION * session,
{
size_t i;
size_t c;
FILE *stream = stderr;
unsigned int width = 0x10;
char buffer[256]; /* Must be enough for width*4 + about 30 or so */
size_t used;
static const char* hex_chars = "0123456789ABCDEF";
if (!(session->showmask & (1 << LIBSSH2_DBG_TRANS))) {
if (!(session->showmask & LIBSSH2_TRACE_TRANS)) {
/* not asked for, bail out */
return;
}
fprintf(stream, "=> %s (%d bytes)\n", desc, (int) size);
used = snprintf(buffer, sizeof(buffer), "=> %s (%d bytes)\n",
desc, (int) size);
if (session->tracehandler)
(session->tracehandler)(session, session->tracehandler_context, buffer, used);
else
write(2 /* stderr */, buffer, used);
for(i = 0; i < size; i += width) {
fprintf(stream, "%04lx: ", (long)i);
used = snprintf(buffer, sizeof(buffer), "%04lx: ", (long)i);
/* hex not disabled, show it */
for(c = 0; c < width; c++) {
if (i + c < size)
fprintf(stream, "%02x ", ptr[i + c]);
else
fputs(" ", stream);
if (i + c < size) {
buffer[used++] = hex_chars[(ptr[i+c] >> 4) & 0xF];
buffer[used++] = hex_chars[ptr[i+c] & 0xF];
}
else {
buffer[used++] = ' ';
buffer[used++] = ' ';
}
buffer[used++] = ' ';
if ((width/2) - 1 == c)
buffer[used++] = ' ';
}
buffer[used++] = ':';
buffer[used++] = ' ';
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);
buffer[used++] = isprint(ptr[i + c]) ?
ptr[i + c] : UNPRINTABLE_CHAR;
}
fputc('\n', stream); /* newline */
buffer[used++] = '\n';
buffer[used] = 0;
if (session->tracehandler)
(session->tracehandler)(session, session->tracehandler_context, buffer, used);
else
write(2, buffer, used);
}
fflush(stream);
}
#else
#define debugdump(a,x,y,z)
@@ -290,7 +313,7 @@ int _libssh2_transport_read(LIBSSH2_SESSION * session)
/* Whoever wants a packet won't get anything until the key re-exchange
* is done!
*/
_libssh2_debug(session, LIBSSH2_DBG_TRANS, "Redirecting into the"
_libssh2_debug(session, LIBSSH2_TRACE_TRANS, "Redirecting into the"
" key re-exchange");
rc = libssh2_kex_exchange(session, 1, &session->startup_key_state);
if (rc)
@@ -355,6 +378,15 @@ int _libssh2_transport_read(LIBSSH2_SESSION * session)
_libssh2_recv(session->socket_fd, &p->buf[remainbuf],
PACKETBUFSIZE - remainbuf,
LIBSSH2_SOCKET_RECV_FLAGS(session));
if (nread < 0)
_libssh2_debug(session, LIBSSH2_TRACE_SOCKET,
"Error recving %d bytes to %p+%d: %d",
PACKETBUFSIZE - remainbuf, p->buf, remainbuf,
errno);
else
_libssh2_debug(session, LIBSSH2_TRACE_SOCKET,
"Recved %d/%d bytes to %p+%d", nread,
PACKETBUFSIZE - remainbuf, p->buf, remainbuf);
if (nread <= 0) {
/* check if this is due to EAGAIN and return the special
return code if so, error out normally otherwise */
@@ -602,6 +634,13 @@ send_existing(LIBSSH2_SESSION * session, unsigned char *data,
rc = _libssh2_send(session->socket_fd, &p->outbuf[p->osent], length,
LIBSSH2_SOCKET_SEND_FLAGS(session));
if (rc < 0)
_libssh2_debug(session, LIBSSH2_TRACE_SOCKET,
"Error sending %d bytes: %d", length, errno);
else
_libssh2_debug(session, LIBSSH2_TRACE_SOCKET,
"Sent %d/%d bytes at %p+%d", rc, length, p->outbuf,
p->osent);
if(rc > 0) {
debugdump(session, "libssh2_transport_write send()",
@@ -626,7 +665,7 @@ send_existing(LIBSSH2_SESSION * session, unsigned char *data,
p->osent += rc; /* we sent away this much data */
return p->osent < data_len ? PACKET_EAGAIN : PACKET_NONE;
return rc < length ? PACKET_EAGAIN : PACKET_NONE;
}
/*
@@ -671,15 +710,15 @@ _libssh2_transport_write(LIBSSH2_SESSION * session, unsigned char *data,
debugdump(session, "libssh2_transport_write plain", data, data_len);
/* default clear the bit */
session->socket_block_directions &= ~LIBSSH2_SESSION_BLOCK_OUTBOUND;
/* FIRST, check if we have a pending write to complete */
rc = send_existing(session, data, data_len, &ret);
if (rc || ret) {
return rc;
}
/* default clear the bit */
session->socket_block_directions &= ~LIBSSH2_SESSION_BLOCK_OUTBOUND;
encrypted = (session->state & LIBSSH2_STATE_NEWKEYS) ? 1 : 0;
/* check if we should compress */
@@ -776,6 +815,12 @@ _libssh2_transport_write(LIBSSH2_SESSION * session, unsigned char *data,
ret = _libssh2_send(session->socket_fd, p->outbuf, total_length,
LIBSSH2_SOCKET_SEND_FLAGS(session));
if (ret < 0)
_libssh2_debug(session, LIBSSH2_TRACE_SOCKET,
"Error sending %d bytes: %d", total_length, errno);
else
_libssh2_debug(session, LIBSSH2_TRACE_SOCKET, "Sent %d/%d bytes at %p",
ret, total_length, p->outbuf);
if (ret != -1) {
debugdump(session, "libssh2_transport_write send()", p->outbuf, ret);

View File

@@ -41,6 +41,8 @@
#include <ctype.h>
#include <stdio.h>
#include <assert.h>
/* Needed for struct iovec on some platforms */
#ifdef HAVE_SYS_UIO_H
#include <sys/uio.h>
@@ -104,7 +106,7 @@ static char *userauth_list(LIBSSH2_SESSION *session, const char *username,
if (session->userauth_list_state == libssh2_NB_state_created) {
rc = _libssh2_transport_write(session, session->userauth_list_data,
session->userauth_list_data_len);
session->userauth_list_data_len);
if (rc == PACKET_EAGAIN) {
libssh2_error(session, LIBSSH2_ERROR_EAGAIN,
"Would block requesting userauth list", 0);
@@ -155,7 +157,7 @@ static char *userauth_list(LIBSSH2_SESSION *session, const char *username,
memmove(session->userauth_list_data, session->userauth_list_data + 5,
methods_len);
session->userauth_list_data[methods_len] = '\0';
_libssh2_debug(session, LIBSSH2_DBG_AUTH, "Permitted auth methods: %s",
_libssh2_debug(session, LIBSSH2_TRACE_AUTH, "Permitted auth methods: %s",
session->userauth_list_data);
}
@@ -206,8 +208,8 @@ userauth_password(LIBSSH2_SESSION *session, const char *username,
unsigned char *s;
static const unsigned char reply_codes[4] =
{ SSH_MSG_USERAUTH_SUCCESS, SSH_MSG_USERAUTH_FAILURE,
SSH_MSG_USERAUTH_PASSWD_CHANGEREQ, 0
};
SSH_MSG_USERAUTH_PASSWD_CHANGEREQ, 0
};
int rc;
if (session->userauth_pswd_state == libssh2_NB_state_idle) {
@@ -256,7 +258,7 @@ userauth_password(LIBSSH2_SESSION *session, const char *username,
memcpy(s, password, password_len);
s += password_len;
_libssh2_debug(session, LIBSSH2_DBG_AUTH,
_libssh2_debug(session, LIBSSH2_TRACE_AUTH,
"Attempting to login using password authentication");
session->userauth_pswd_state = libssh2_NB_state_created;
@@ -264,7 +266,7 @@ userauth_password(LIBSSH2_SESSION *session, const char *username,
if (session->userauth_pswd_state == libssh2_NB_state_created) {
rc = _libssh2_transport_write(session, session->userauth_pswd_data,
session->userauth_pswd_data_len);
session->userauth_pswd_data_len);
if (rc == PACKET_EAGAIN) {
return rc;
} else if (rc) {
@@ -301,13 +303,24 @@ userauth_password(LIBSSH2_SESSION *session, const char *username,
}
if (session->userauth_pswd_data[0] == SSH_MSG_USERAUTH_SUCCESS) {
_libssh2_debug(session, LIBSSH2_DBG_AUTH,
_libssh2_debug(session, LIBSSH2_TRACE_AUTH,
"Password authentication successful");
LIBSSH2_FREE(session, session->userauth_pswd_data);
session->userauth_pswd_data = NULL;
session->state |= LIBSSH2_STATE_AUTHENTICATED;
session->userauth_pswd_state = libssh2_NB_state_idle;
return 0;
} else if (session->userauth_pswd_data[0] == SSH_MSG_USERAUTH_FAILURE) {
_libssh2_debug(session, LIBSSH2_TRACE_AUTH,
"Password authentication failed");
LIBSSH2_FREE(session, session->userauth_pswd_data);
session->userauth_pswd_data = NULL;
session->userauth_pswd_state = libssh2_NB_state_idle;
libssh2_error(session,
LIBSSH2_ERROR_AUTHENTICATION_FAILED,
"Authentication failed (username/password)",
0);
return -1;
}
session->userauth_pswd_newpw = NULL;
@@ -325,7 +338,7 @@ userauth_password(LIBSSH2_SESSION *session, const char *username,
if ((session->userauth_pswd_state == libssh2_NB_state_sent1) ||
(session->userauth_pswd_state == libssh2_NB_state_sent2)) {
if (session->userauth_pswd_state == libssh2_NB_state_sent1) {
_libssh2_debug(session, LIBSSH2_DBG_AUTH,
_libssh2_debug(session, LIBSSH2_TRACE_AUTH,
"Password change required");
LIBSSH2_FREE(session, session->userauth_pswd_data);
session->userauth_pswd_data = NULL;
@@ -398,9 +411,9 @@ userauth_password(LIBSSH2_SESSION *session, const char *username,
if (session->userauth_pswd_state == libssh2_NB_state_sent2) {
rc = _libssh2_transport_write(session,
session->userauth_pswd_data,
session->
userauth_pswd_data_len);
session->userauth_pswd_data,
session->
userauth_pswd_data_len);
if (rc == PACKET_EAGAIN) {
return rc;
} else if (rc) {
@@ -469,7 +482,10 @@ libssh2_userauth_password_ex(LIBSSH2_SESSION *session, const char *username,
*
* Read a public key from an id_???.pub style file
*
* Returns an allocated string in *pubkeydata on success.
* Returns an allocated string containing the decoded key in *pubkeydata
* on success.
* Returns an allocated string containing the key method (e.g. "ssh-dss")
* in method on success.
*/
static int
file_read_publickey(LIBSSH2_SESSION * session, unsigned char **method,
@@ -484,7 +500,7 @@ file_read_publickey(LIBSSH2_SESSION * session, unsigned char **method,
size_t pubkey_len = 0;
unsigned int tmp_len;
_libssh2_debug(session, LIBSSH2_DBG_AUTH, "Loading public key file: %s",
_libssh2_debug(session, LIBSSH2_TRACE_AUTH, "Loading public key file: %s",
pubkeyfile);
/* Read Public Key */
fd = fopen(pubkeyfile, "r");
@@ -542,15 +558,10 @@ file_read_publickey(LIBSSH2_SESSION * session, unsigned char **method,
LIBSSH2_FREE(session, pubkey);
return -1;
}
/* Wasting some bytes here (okay, more than some),
* but since it's likely to be freed soon anyway,
* we'll just avoid the extra free/alloc and call it a wash */
*method = pubkey;
*method_len = sp1 - pubkey;
sp1++;
if ((sp2 = memchr(sp1, ' ', pubkey_len - *method_len)) == NULL) {
if ((sp2 = memchr(sp1, ' ', pubkey_len - (sp1 - pubkey - 1))) == NULL) {
/* Assume that the id string is missing, but that it's okay */
sp2 = pubkey + pubkey_len;
}
@@ -562,6 +573,13 @@ file_read_publickey(LIBSSH2_SESSION * session, unsigned char **method,
LIBSSH2_FREE(session, pubkey);
return -1;
}
/* Wasting some bytes here (okay, more than some), but since it's likely
* to be freed soon anyway, we'll just avoid the extra free/alloc and call
* it a wash */
*method = pubkey;
*method_len = sp1 - pubkey - 1;
*pubkeydata = tmp;
*pubkeydata_len = tmp_len;
@@ -583,7 +601,7 @@ file_read_privatekey(LIBSSH2_SESSION * session,
const LIBSSH2_HOSTKEY_METHOD **hostkey_methods_avail =
libssh2_hostkey_methods();
_libssh2_debug(session, LIBSSH2_DBG_AUTH, "Loading private key file: %s",
_libssh2_debug(session, LIBSSH2_TRACE_AUTH, "Loading private key file: %s",
privkeyfile);
*hostkey_method = NULL;
*hostkey_abstract = NULL;
@@ -613,6 +631,45 @@ file_read_privatekey(LIBSSH2_SESSION * session,
return 0;
}
struct privkey_file {
const char *filename;
const char *passphrase;
};
static int
sign_fromfile(LIBSSH2_SESSION *session, unsigned char **sig, size_t *sig_len,
const unsigned char *data, size_t data_len, void **abstract)
{
struct privkey_file *privkey_file = (struct privkey_file *) (*abstract);
const LIBSSH2_HOSTKEY_METHOD *privkeyobj;
void *hostkey_abstract;
struct iovec datavec;
if (file_read_privatekey(session, &privkeyobj, &hostkey_abstract,
session->userauth_pblc_method,
session->userauth_pblc_method_len,
privkey_file->filename,
privkey_file->passphrase)) {
return -1;
}
datavec.iov_base = (unsigned char *)data;
datavec.iov_len = data_len;
if (privkeyobj->signv(session, sig, (unsigned long *)sig_len, 1, &datavec,
&hostkey_abstract)) {
if (privkeyobj->dtor) {
privkeyobj->dtor(session, abstract);
}
return -1;
}
if (privkeyobj->dtor) {
privkeyobj->dtor(session, &hostkey_abstract);
}
return 0;
}
/* userauth_hostbased_fromfile
@@ -627,8 +684,6 @@ userauth_hostbased_fromfile(LIBSSH2_SESSION *session,
const char *local_username,
unsigned int local_username_len)
{
static const unsigned char reply_codes[3] =
{ SSH_MSG_USERAUTH_SUCCESS, SSH_MSG_USERAUTH_FAILURE, 0 };
int rc;
if (session->userauth_host_state == libssh2_NB_state_idle) {
@@ -797,7 +852,7 @@ userauth_hostbased_fromfile(LIBSSH2_SESSION *session,
session->userauth_host_s += sig_len;
LIBSSH2_FREE(session, sig);
_libssh2_debug(session, LIBSSH2_DBG_AUTH,
_libssh2_debug(session, LIBSSH2_TRACE_AUTH,
"Attempting hostbased authentication");
session->userauth_host_state = libssh2_NB_state_created;
@@ -824,6 +879,8 @@ userauth_hostbased_fromfile(LIBSSH2_SESSION *session,
}
if (session->userauth_host_state == libssh2_NB_state_sent) {
static const unsigned char reply_codes[3] =
{ SSH_MSG_USERAUTH_SUCCESS, SSH_MSG_USERAUTH_FAILURE, 0 };
unsigned long data_len;
rc = _libssh2_packet_requirev(session, reply_codes,
&session->userauth_host_data,
@@ -839,7 +896,7 @@ userauth_hostbased_fromfile(LIBSSH2_SESSION *session,
return -1;
if (session->userauth_host_data[0] == SSH_MSG_USERAUTH_SUCCESS) {
_libssh2_debug(session, LIBSSH2_DBG_AUTH,
_libssh2_debug(session, LIBSSH2_TRACE_AUTH,
"Hostbased authentication successful");
/* We are us and we've proved it. */
LIBSSH2_FREE(session, session->userauth_host_data);
@@ -885,37 +942,47 @@ libssh2_userauth_hostbased_fromfile_ex(LIBSSH2_SESSION *session,
/*
* userauth_publickey_fromfile
* Authenticate using a keypair found in the named files
*/
static int
userauth_publickey_fromfile(LIBSSH2_SESSION *session,
const char *username,
unsigned int username_len,
const char *publickey,
const char *privatekey,
const char *passphrase)
userauth_publickey(LIBSSH2_SESSION *session,
const char *username,
unsigned int username_len,
const unsigned char *pubkeydata,
unsigned long pubkeydata_len,
LIBSSH2_USERAUTH_PUBLICKEY_SIGN_FUNC((*sign_callback)),
void *abstract)
{
unsigned long pubkeydata_len = 0;
unsigned char reply_codes[4] =
{ SSH_MSG_USERAUTH_SUCCESS, SSH_MSG_USERAUTH_FAILURE,
SSH_MSG_USERAUTH_PK_OK, 0
};
SSH_MSG_USERAUTH_PK_OK, 0
};
int rc;
if (session->userauth_pblc_state == libssh2_NB_state_idle) {
unsigned char *pubkeydata;
/* Zero the whole thing out */
memset(&session->userauth_pblc_packet_requirev_state, 0,
sizeof(session->userauth_pblc_packet_requirev_state));
if (file_read_publickey(session, &session->userauth_pblc_method,
&session->userauth_pblc_method_len,
&pubkeydata, &pubkeydata_len,publickey)) {
return -1;
/*
* As an optimisation, userauth_publickey_fromfile reuses a
* previously allocated copy of the method name to avoid an extra
* allocation/free.
* For other uses, we allocate and populate it here.
*/
if (!session->userauth_pblc_method) {
session->userauth_pblc_method_len = _libssh2_ntohu32(pubkeydata);
session->userauth_pblc_method =
LIBSSH2_ALLOC(session, session->userauth_pblc_method_len);
if (!session->userauth_pblc_method) {
libssh2_error(session, LIBSSH2_ERROR_ALLOC,
"Unable to allocate memory for public key "
"data", 0);
return -1;
}
memcpy(session->userauth_pblc_method, pubkeydata + 4,
session->userauth_pblc_method_len);
}
assert( /* preallocated method len should match what we expect */
session->userauth_pblc_method_len == _libssh2_ntohu32(pubkeydata));
/*
* 45 = packet_type(1) + username_len(4) + servicename_len(4) +
@@ -940,7 +1007,6 @@ userauth_publickey_fromfile(LIBSSH2_SESSION *session,
if (!session->userauth_pblc_packet) {
LIBSSH2_FREE(session, session->userauth_pblc_method);
session->userauth_pblc_method = NULL;
LIBSSH2_FREE(session, pubkeydata);
return -1;
}
@@ -965,7 +1031,7 @@ userauth_publickey_fromfile(LIBSSH2_SESSION *session,
*(session->userauth_pblc_s++) = 0;
_libssh2_htonu32(session->userauth_pblc_s,
session->userauth_pblc_method_len);
session->userauth_pblc_method_len);
session->userauth_pblc_s += 4;
memcpy(session->userauth_pblc_s, session->userauth_pblc_method,
session->userauth_pblc_method_len);
@@ -975,9 +1041,8 @@ userauth_publickey_fromfile(LIBSSH2_SESSION *session,
session->userauth_pblc_s += 4;
memcpy(session->userauth_pblc_s, pubkeydata, pubkeydata_len);
session->userauth_pblc_s += pubkeydata_len;
LIBSSH2_FREE(session, pubkeydata);
_libssh2_debug(session, LIBSSH2_DBG_AUTH,
_libssh2_debug(session, LIBSSH2_TRACE_AUTH,
"Attempting publickey authentication");
session->userauth_pblc_state = libssh2_NB_state_created;
@@ -985,7 +1050,7 @@ userauth_publickey_fromfile(LIBSSH2_SESSION *session,
if (session->userauth_pblc_state == libssh2_NB_state_created) {
rc = _libssh2_transport_write(session, session->userauth_pblc_packet,
session->userauth_pblc_packet_len);
session->userauth_pblc_packet_len);
if (rc == PACKET_EAGAIN) {
return rc;
} else if (rc) {
@@ -1003,13 +1068,6 @@ userauth_publickey_fromfile(LIBSSH2_SESSION *session,
}
if (session->userauth_pblc_state == libssh2_NB_state_sent) {
const LIBSSH2_HOSTKEY_METHOD *privkeyobj;
void *abstract;
unsigned char buf[5];
struct iovec datavec[4];
unsigned char *sig;
unsigned long sig_len;
rc = _libssh2_packet_requirev(session, reply_codes,
&session->userauth_pblc_data,
&session->userauth_pblc_data_len, 0,
@@ -1028,7 +1086,7 @@ userauth_publickey_fromfile(LIBSSH2_SESSION *session,
}
if (session->userauth_pblc_data[0] == SSH_MSG_USERAUTH_SUCCESS) {
_libssh2_debug(session, LIBSSH2_DBG_AUTH,
_libssh2_debug(session, LIBSSH2_TRACE_AUTH,
"Pubkey authentication prematurely successful");
/*
* God help any SSH server that allows an UNVERIFIED
@@ -1053,7 +1111,7 @@ userauth_publickey_fromfile(LIBSSH2_SESSION *session,
session->userauth_pblc_packet = NULL;
LIBSSH2_FREE(session, session->userauth_pblc_method);
session->userauth_pblc_method = NULL;
libssh2_error(session, LIBSSH2_ERROR_PUBLICKEY_UNRECOGNIZED,
libssh2_error(session, LIBSSH2_ERROR_AUTHENTICATION_FAILED,
"Username/PublicKey combination invalid", 0);
session->userauth_pblc_state = libssh2_NB_state_idle;
return -1;
@@ -1063,44 +1121,45 @@ userauth_publickey_fromfile(LIBSSH2_SESSION *session,
LIBSSH2_FREE(session, session->userauth_pblc_data);
session->userauth_pblc_data = NULL;
if (file_read_privatekey(session, &privkeyobj, &abstract,
session->userauth_pblc_method,
session->userauth_pblc_method_len,
privatekey, passphrase)) {
LIBSSH2_FREE(session, session->userauth_pblc_method);
session->userauth_pblc_method = NULL;
LIBSSH2_FREE(session, session->userauth_pblc_packet);
session->userauth_pblc_packet = NULL;
session->userauth_pblc_state = libssh2_NB_state_idle;
return -1;
}
*session->userauth_pblc_b = 0x01;
session->userauth_pblc_state = libssh2_NB_state_sent1;
}
_libssh2_htonu32(buf, session->session_id_len);
datavec[0].iov_base = buf;
datavec[0].iov_len = 4;
datavec[1].iov_base = session->session_id;
datavec[1].iov_len = session->session_id_len;
datavec[2].iov_base = session->userauth_pblc_packet;
datavec[2].iov_len = session->userauth_pblc_packet_len;
if (session->userauth_pblc_state == libssh2_NB_state_sent1) {
unsigned char *buf, *s;
unsigned char *sig;
size_t sig_len;
if (privkeyobj->signv(session, &sig, &sig_len, 3, datavec, &abstract)) {
s = buf = LIBSSH2_ALLOC(session, 4 + session->session_id_len
+ session->userauth_pblc_packet_len);
if (!buf) {
libssh2_error(session, LIBSSH2_ERROR_ALLOC,
"Unable to allocate memory for userauth-publickey "
"signed data", 0);
return -1;
}
_libssh2_htonu32(s, session->session_id_len);
s += 4;
memcpy (s, session->session_id, session->session_id_len);
s += session->session_id_len;
memcpy (s, session->userauth_pblc_packet,
session->userauth_pblc_packet_len);
s += session->userauth_pblc_packet_len;
rc = sign_callback(session, &sig, &sig_len, buf, s - buf, abstract);
LIBSSH2_FREE(session, buf);
if (rc == PACKET_EAGAIN) {
return rc;
} else if (rc) {
LIBSSH2_FREE(session, session->userauth_pblc_method);
session->userauth_pblc_method = NULL;
LIBSSH2_FREE(session, session->userauth_pblc_packet);
session->userauth_pblc_packet = NULL;
if (privkeyobj->dtor) {
privkeyobj->dtor(session, &abstract);
}
session->userauth_pblc_state = libssh2_NB_state_idle;
return -1;
}
if (privkeyobj->dtor) {
privkeyobj->dtor(session, &abstract);
}
/*
* If this function was restarted, pubkeydata_len might still be 0
* which will cause an unnecessary but harmless realloc here.
@@ -1152,13 +1211,13 @@ userauth_publickey_fromfile(LIBSSH2_SESSION *session,
session->userauth_pblc_s += sig_len;
LIBSSH2_FREE(session, sig);
_libssh2_debug(session, LIBSSH2_DBG_AUTH,
_libssh2_debug(session, LIBSSH2_TRACE_AUTH,
"Attempting publickey authentication -- phase 2");
session->userauth_pblc_state = libssh2_NB_state_sent1;
session->userauth_pblc_state = libssh2_NB_state_sent2;
}
if (session->userauth_pblc_state == libssh2_NB_state_sent1) {
if (session->userauth_pblc_state == libssh2_NB_state_sent2) {
rc = _libssh2_transport_write(session, session->userauth_pblc_packet,
session->userauth_pblc_s -
session->userauth_pblc_packet);
@@ -1175,7 +1234,7 @@ userauth_publickey_fromfile(LIBSSH2_SESSION *session,
LIBSSH2_FREE(session, session->userauth_pblc_packet);
session->userauth_pblc_packet = NULL;
session->userauth_pblc_state = libssh2_NB_state_sent2;
session->userauth_pblc_state = libssh2_NB_state_sent3;
}
/* PK_OK is no longer valid */
@@ -1193,7 +1252,7 @@ userauth_publickey_fromfile(LIBSSH2_SESSION *session,
}
if (session->userauth_pblc_data[0] == SSH_MSG_USERAUTH_SUCCESS) {
_libssh2_debug(session, LIBSSH2_DBG_AUTH,
_libssh2_debug(session, LIBSSH2_TRACE_AUTH,
"Publickey authentication successful");
/* We are us and we've proved it. */
LIBSSH2_FREE(session, session->userauth_pblc_data);
@@ -1214,6 +1273,44 @@ userauth_publickey_fromfile(LIBSSH2_SESSION *session,
return -1;
}
/*
* userauth_publickey_fromfile
* Authenticate using a keypair found in the named files
*/
static int
userauth_publickey_fromfile(LIBSSH2_SESSION *session,
const char *username,
unsigned int username_len,
const char *publickey,
const char *privatekey,
const char *passphrase)
{
unsigned char *pubkeydata = NULL;
unsigned long pubkeydata_len = 0;
struct privkey_file privkey_file;
void *abstract = &privkey_file;
int rc;
privkey_file.filename = privatekey;
privkey_file.passphrase = passphrase;
if (session->userauth_pblc_state == libssh2_NB_state_idle) {
if (file_read_publickey(session, &session->userauth_pblc_method,
&session->userauth_pblc_method_len,
&pubkeydata, &pubkeydata_len, publickey)) {
return -1;
}
}
rc = userauth_publickey(session, username, username_len,
pubkeydata, pubkeydata_len,
sign_fromfile, &abstract);
if(pubkeydata)
LIBSSH2_FREE(session, pubkeydata);
return rc;
}
/* libssh2_userauth_publickey_fromfile_ex
* Authenticate using a keypair found in the named files
*/
@@ -1233,6 +1330,25 @@ libssh2_userauth_publickey_fromfile_ex(LIBSSH2_SESSION *session,
return rc;
}
/* libssh2_userauth_publickey_ex
* Authenticate using an external callback function
*/
LIBSSH2_API int
libssh2_userauth_publickey(LIBSSH2_SESSION *session,
const char *user,
const unsigned char *pubkeydata,
size_t pubkeydata_len,
LIBSSH2_USERAUTH_PUBLICKEY_SIGN_FUNC((*sign_callback)),
void **abstract)
{
int rc;
BLOCK_ADJUST(rc, session,
userauth_publickey(session, user, strlen(user),
pubkeydata, pubkeydata_len,
sign_callback, abstract));
return rc;
}
/*
@@ -1249,7 +1365,8 @@ userauth_keyboard_interactive(LIBSSH2_SESSION * session,
unsigned char *s;
int rc;
static const unsigned char reply_codes[4] = { SSH_MSG_USERAUTH_SUCCESS,
static const unsigned char reply_codes[4] = {
SSH_MSG_USERAUTH_SUCCESS,
SSH_MSG_USERAUTH_FAILURE, SSH_MSG_USERAUTH_INFO_REQUEST, 0
};
unsigned int language_tag_len;
@@ -1316,7 +1433,7 @@ userauth_keyboard_interactive(LIBSSH2_SESSION * session,
_libssh2_htonu32(s, 0);
s += 4;
_libssh2_debug(session, LIBSSH2_DBG_AUTH,
_libssh2_debug(session, LIBSSH2_TRACE_AUTH,
"Attempting keyboard-interactive authentication");
session->userauth_kybd_state = libssh2_NB_state_created;
@@ -1324,7 +1441,7 @@ userauth_keyboard_interactive(LIBSSH2_SESSION * session,
if (session->userauth_kybd_state == libssh2_NB_state_created) {
rc = _libssh2_transport_write(session, session->userauth_kybd_data,
session->userauth_kybd_packet_len);
session->userauth_kybd_packet_len);
if (rc == PACKET_EAGAIN) {
return rc;
} else if (rc) {
@@ -1357,7 +1474,7 @@ userauth_keyboard_interactive(LIBSSH2_SESSION * session,
}
if (session->userauth_kybd_data[0] == SSH_MSG_USERAUTH_SUCCESS) {
_libssh2_debug(session, LIBSSH2_DBG_AUTH,
_libssh2_debug(session, LIBSSH2_TRACE_AUTH,
"Keyboard-interactive authentication successful");
LIBSSH2_FREE(session, session->userauth_kybd_data);
session->userauth_kybd_data = NULL;
@@ -1367,9 +1484,15 @@ userauth_keyboard_interactive(LIBSSH2_SESSION * session,
}
if (session->userauth_kybd_data[0] == SSH_MSG_USERAUTH_FAILURE) {
_libssh2_debug(session, LIBSSH2_TRACE_AUTH,
"Keyboard-interactive authentication failed");
LIBSSH2_FREE(session, session->userauth_kybd_data);
session->userauth_kybd_data = NULL;
session->userauth_kybd_state = libssh2_NB_state_idle;
libssh2_error(session,
LIBSSH2_ERROR_AUTHENTICATION_FAILED,
"Authentication failed (keyboard-interactive)",
0);
return -1;
}
@@ -1482,7 +1605,7 @@ userauth_keyboard_interactive(LIBSSH2_SESSION * session,
session->userauth_kybd_responses,
&session->abstract);
_libssh2_debug(session, LIBSSH2_DBG_AUTH,
_libssh2_debug(session, LIBSSH2_TRACE_AUTH,
"Keyboard-interactive response callback function"
" invoked");
@@ -1525,7 +1648,7 @@ userauth_keyboard_interactive(LIBSSH2_SESSION * session,
if (session->userauth_kybd_state == libssh2_NB_state_sent1) {
rc = _libssh2_transport_write(session, session->userauth_kybd_data,
session->userauth_kybd_packet_len);
session->userauth_kybd_packet_len);
if (rc == PACKET_EAGAIN) {
return rc;
}

View File

@@ -1,4 +1,4 @@
/* Self test, based on examples/simple/ssh2.c. */
/* Self test, based on examples/ssh2.c. */
#include "libssh2_config.h"
#include <libssh2.h>
@@ -59,7 +59,7 @@ int main(int argc, char *argv[])
if (getenv ("PRIVKEY"))
privkeyfile = getenv ("PRIVKEY");
if (getenv ("PRIVKEY"))
if (getenv ("PUBKEY"))
pubkeyfile = getenv ("PUBKEY");
hostaddr = htonl(0x7F000001);
@@ -90,9 +90,9 @@ int main(int argc, char *argv[])
* 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);
fingerprint = libssh2_hostkey_hash(session, LIBSSH2_HOSTKEY_HASH_SHA1);
printf("Fingerprint: ");
for(i = 0; i < 16; i++) {
for(i = 0; i < 20; i++) {
printf("%02X ", (unsigned char)fingerprint[i]);
}
printf("\n");

View File

@@ -9,21 +9,26 @@ srcdir=${srcdir:-$PWD}
SSHD=${SSHD:-/usr/sbin/sshd}
cmd="./ssh2${EXEEXT}"
srcdir=`cd $srcdir; pwd`
srcdir=`cd "$srcdir"; pwd`
PRIVKEY=$srcdir/etc/user
export PRIVKEY
PUBKEY=$srcdir/etc/user.pub
export PUBKEY
chmod go-r $srcdir/etc/host*
$SSHD -f /dev/null -h $srcdir/etc/host \
if test -n "$DEBUG"; then
libssh2_sshd_params="-d -d"
fi
chmod go-rwx "$srcdir"/etc/host*
$SSHD -f /dev/null -h "$srcdir"/etc/host \
-o 'Port 4711' \
-o 'Protocol 2' \
-o "AuthorizedKeysFile $srcdir/etc/user.pub" \
-o 'UsePrivilegeSeparation no' \
-o 'StrictModes no' \
-D &
-D \
$libssh2_sshd_params &
sshdpid=$!
trap "kill ${sshdpid}; echo signal killing sshd; exit 1;" EXIT

View File

@@ -1,3 +1,3 @@
# End Target
# End Project
# End Target
# End Project

View File

@@ -1,145 +1,145 @@
# Microsoft Developer Studio Project File - Name="libssh2" - Package Owner=<4>
# Microsoft Developer Studio Generated Build File, Format Version 6.00
# ** DO NOT EDIT **
# TARGTYPE "Win32 (x86) Dynamic-Link Library" 0x0102
# TARGTYPE "Win32 (x86) Static Library" 0x0104
CFG=libssh2 - Win32 Debug
!MESSAGE This is not a valid makefile. To build this project using NMAKE,
!MESSAGE use the Export Makefile command and run
!MESSAGE
!MESSAGE NMAKE /f "libssh2.mak".
!MESSAGE
!MESSAGE You can specify a configuration when running NMAKE
!MESSAGE by defining the macro CFG on the command line. For example:
!MESSAGE
!MESSAGE NMAKE /f "libssh2.mak" CFG="libssh2 - Win32 DLL Debug"
!MESSAGE
!MESSAGE Possible choices for configuration are:
!MESSAGE
!MESSAGE "libssh2 - Win32 DLL Release" (based on "Win32 (x86) Dynamic-Link Library")
!MESSAGE "libssh2 - Win32 DLL Debug" (based on "Win32 (x86) Dynamic-Link Library")
!MESSAGE "libssh2 - Win32 LIB Release" (based on "Win32 (x86) Static Library")
!MESSAGE "libssh2 - Win32 LIB Debug" (based on "Win32 (x86) Static Library")
!MESSAGE
# Begin Project
# PROP AllowPerConfigDependencies 0
# PROP Scc_ProjName ""
# PROP Scc_LocalPath ""
CPP=cl.exe
MTL=midl.exe
RSC=rc.exe
!IF "$(CFG)" == "libssh2 - Win32 DLL Release"
# PROP BASE Use_MFC 0
# PROP BASE Use_Debug_Libraries 0
# PROP BASE Output_Dir "Release_dll"
# PROP BASE Intermediate_Dir "Release_dll"
# PROP BASE Target_Dir ""
# PROP Use_MFC 0
# PROP Use_Debug_Libraries 0
# PROP Output_Dir "Release_dll"
# PROP Intermediate_Dir "Release_dll"
# PROP Ignore_Export_Lib 0
# PROP Target_Dir ""
# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "LIBSSH2_WIN32" /D "_MBCS" /D "_LIB" /YX /FD /c
# ADD CPP /nologo /MD /W3 /GX /O2 /I "..\win32" /I "..\include" /D "WIN32" /D "NDEBUG" /D "LIBSSH2_WIN32" /D "_MBCS" /D "_LIB" /YX /FD /c
# SUBTRACT CPP /YX
# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32
# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32
# ADD BASE RSC /l 0x409 /d "NDEBUG"
# ADD RSC /l 0x409 /d "NDEBUG"
BSC32=bscmake.exe
# ADD BASE BSC32 /nologo
# ADD BSC32 /nologo
LINK32=link.exe
# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /machine:I386
# ADD LINK32 kernel32.lib ws2_32.lib libeay32.lib ssleay32.lib zlib.lib /nologo /dll /map /debug /machine:I386 /out:"Release_dll/libssh2.dll"
!ELSEIF "$(CFG)" == "libssh2 - Win32 DLL Debug"
# PROP BASE Use_MFC 0
# PROP BASE Use_Debug_Libraries 1
# PROP BASE Output_Dir "Debug_dll"
# PROP BASE Intermediate_Dir "Debug_dll"
# PROP BASE Target_Dir ""
# PROP Use_MFC 0
# PROP Use_Debug_Libraries 1
# PROP Output_Dir "Debug_dll"
# PROP Intermediate_Dir "Debug_dll"
# PROP Ignore_Export_Lib 0
# PROP Target_Dir ""
# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "LIBSSH2_WIN32" /D "_MBCS" /D "_LIB" /YX /FD /GZ /c
# ADD CPP /nologo /MDd /W3 /Gm /GX /ZI /Od /I "..\win32" /I "..\include" /D "WIN32" /D "_DEBUG" /D "LIBSSH2_WIN32" /D "_MBCS" /D "_LIB" /YX /FD /GZ /c
# SUBTRACT CPP /WX /YX
# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32
# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32
# ADD BASE RSC /l 0x409 /d "_DEBUG"
# ADD RSC /l 0x409 /d "_DEBUG"
BSC32=bscmake.exe
# ADD BASE BSC32 /nologo
# ADD BSC32 /nologo
LINK32=link.exe
# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /debug /machine:I386 /pdbtype:sept
# ADD LINK32 kernel32.lib ws2_32.lib libeay32.lib ssleay32.lib zlib.lib /nologo /dll /incremental:no /map /debug /machine:I386 /out:"Debug_dll/libssh2.dll" /pdbtype:sept
# SUBTRACT LINK32 /nodefaultlib
!ELSEIF "$(CFG)" == "libssh2 - Win32 LIB Release"
# PROP BASE Use_MFC 0
# PROP BASE Use_Debug_Libraries 0
# PROP BASE Output_Dir "Release_lib"
# PROP BASE Intermediate_Dir "Release_lib"
# PROP BASE Target_Dir ""
# PROP Use_MFC 0
# PROP Use_Debug_Libraries 0
# PROP Output_Dir "Release_lib"
# PROP Intermediate_Dir "Release_lib"
# PROP Target_Dir ""
# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "LIBSSH2_WIN32" /D "_MBCS" /D "_LIB" /YX /FD /c
# ADD CPP /nologo /MD /W3 /GX /O2 /I "..\win32" /I "..\include" /D "WIN32" /D "NDEBUG" /D "LIBSSH2_WIN32" /D "_MBCS" /D "_LIB" /YX /FD /c
# ADD BASE RSC /l 0x409 /d "NDEBUG"
# ADD RSC /l 0x409 /d "NDEBUG"
BSC32=bscmake.exe
# ADD BASE BSC32 /nologo
# ADD BSC32 /nologo
LIB32=link.exe -lib
# ADD BASE LIB32 /nologo
# ADD LIB32 /nologo
# ADD LIB32 /nologo /out:"Release_lib\libssh.lib"
!ELSEIF "$(CFG)" == "libssh2 - Win32 LIB Debug"
# PROP BASE Use_MFC 0
# PROP BASE Use_Debug_Libraries 1
# PROP BASE Output_Dir "Debug_lib"
# PROP BASE Intermediate_Dir "Debug_lib"
# PROP BASE Target_Dir ""
# PROP Use_MFC 0
# PROP Use_Debug_Libraries 1
# PROP Output_Dir "Debug_lib"
# PROP Intermediate_Dir "Debug_lib"
# PROP Target_Dir ""
# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "LIBSSH2_WIN32" /D "_MBCS" /D "_LIB" /YX /FD /GZ /c
# ADD CPP /nologo /MDd /W3 /Gm /GX /ZI /Od /I "..\win32" /I "..\include" /D "WIN32" /D "_DEBUG" /D "LIBSSH2_WIN32" /D "_MBCS" /D "_LIB" /YX /FD /GZ /c
# ADD BASE RSC /l 0x409 /d "_DEBUG"
# ADD RSC /l 0x409 /d "_DEBUG"
BSC32=bscmake.exe
# ADD BASE BSC32 /nologo
# ADD BSC32 /nologo
LIB32=link.exe -lib
# ADD BASE LIB32 /nologo
# ADD LIB32 /nologo /out:"Debug_lib\libssh2d.lib"
!ENDIF
# Begin Target
# Name "libssh2 - Win32 DLL Release"
# Name "libssh2 - Win32 DLL Debug"
# Name "libssh2 - Win32 LIB Release"
# Name "libssh2 - Win32 LIB Debug"
# Microsoft Developer Studio Project File - Name="libssh2" - Package Owner=<4>
# Microsoft Developer Studio Generated Build File, Format Version 6.00
# ** DO NOT EDIT **
# TARGTYPE "Win32 (x86) Dynamic-Link Library" 0x0102
# TARGTYPE "Win32 (x86) Static Library" 0x0104
CFG=libssh2 - Win32 Debug
!MESSAGE This is not a valid makefile. To build this project using NMAKE,
!MESSAGE use the Export Makefile command and run
!MESSAGE
!MESSAGE NMAKE /f "libssh2.mak".
!MESSAGE
!MESSAGE You can specify a configuration when running NMAKE
!MESSAGE by defining the macro CFG on the command line. For example:
!MESSAGE
!MESSAGE NMAKE /f "libssh2.mak" CFG="libssh2 - Win32 DLL Debug"
!MESSAGE
!MESSAGE Possible choices for configuration are:
!MESSAGE
!MESSAGE "libssh2 - Win32 DLL Release" (based on "Win32 (x86) Dynamic-Link Library")
!MESSAGE "libssh2 - Win32 DLL Debug" (based on "Win32 (x86) Dynamic-Link Library")
!MESSAGE "libssh2 - Win32 LIB Release" (based on "Win32 (x86) Static Library")
!MESSAGE "libssh2 - Win32 LIB Debug" (based on "Win32 (x86) Static Library")
!MESSAGE
# Begin Project
# PROP AllowPerConfigDependencies 0
# PROP Scc_ProjName ""
# PROP Scc_LocalPath ""
CPP=cl.exe
MTL=midl.exe
RSC=rc.exe
!IF "$(CFG)" == "libssh2 - Win32 DLL Release"
# PROP BASE Use_MFC 0
# PROP BASE Use_Debug_Libraries 0
# PROP BASE Output_Dir "Release_dll"
# PROP BASE Intermediate_Dir "Release_dll"
# PROP BASE Target_Dir ""
# PROP Use_MFC 0
# PROP Use_Debug_Libraries 0
# PROP Output_Dir "Release_dll"
# PROP Intermediate_Dir "Release_dll"
# PROP Ignore_Export_Lib 0
# PROP Target_Dir ""
# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "LIBSSH2_WIN32" /D "_MBCS" /D "_LIB" /YX /FD /c
# ADD CPP /nologo /MD /W3 /GX /O2 /I "..\win32" /I "..\include" /D "WIN32" /D "NDEBUG" /D "LIBSSH2_WIN32" /D "_MBCS" /D "_LIB" /YX /FD /c
# SUBTRACT CPP /YX
# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32
# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32
# ADD BASE RSC /l 0x409 /d "NDEBUG"
# ADD RSC /l 0x409 /d "NDEBUG"
BSC32=bscmake.exe
# ADD BASE BSC32 /nologo
# ADD BSC32 /nologo
LINK32=link.exe
# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /machine:I386
# ADD LINK32 kernel32.lib ws2_32.lib libeay32.lib ssleay32.lib zlib.lib /nologo /dll /map /debug /machine:I386 /out:"Release_dll/libssh2.dll"
!ELSEIF "$(CFG)" == "libssh2 - Win32 DLL Debug"
# PROP BASE Use_MFC 0
# PROP BASE Use_Debug_Libraries 1
# PROP BASE Output_Dir "Debug_dll"
# PROP BASE Intermediate_Dir "Debug_dll"
# PROP BASE Target_Dir ""
# PROP Use_MFC 0
# PROP Use_Debug_Libraries 1
# PROP Output_Dir "Debug_dll"
# PROP Intermediate_Dir "Debug_dll"
# PROP Ignore_Export_Lib 0
# PROP Target_Dir ""
# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "LIBSSH2_WIN32" /D "_MBCS" /D "_LIB" /YX /FD /GZ /c
# ADD CPP /nologo /MDd /W3 /Gm /GX /ZI /Od /I "..\win32" /I "..\include" /D "WIN32" /D "_DEBUG" /D "LIBSSH2_WIN32" /D "_MBCS" /D "_LIB" /YX /FD /GZ /c
# SUBTRACT CPP /WX /YX
# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32
# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32
# ADD BASE RSC /l 0x409 /d "_DEBUG"
# ADD RSC /l 0x409 /d "_DEBUG"
BSC32=bscmake.exe
# ADD BASE BSC32 /nologo
# ADD BSC32 /nologo
LINK32=link.exe
# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /debug /machine:I386 /pdbtype:sept
# ADD LINK32 kernel32.lib ws2_32.lib libeay32.lib ssleay32.lib zlib.lib /nologo /dll /incremental:no /map /debug /machine:I386 /out:"Debug_dll/libssh2.dll" /pdbtype:sept
# SUBTRACT LINK32 /nodefaultlib
!ELSEIF "$(CFG)" == "libssh2 - Win32 LIB Release"
# PROP BASE Use_MFC 0
# PROP BASE Use_Debug_Libraries 0
# PROP BASE Output_Dir "Release_lib"
# PROP BASE Intermediate_Dir "Release_lib"
# PROP BASE Target_Dir ""
# PROP Use_MFC 0
# PROP Use_Debug_Libraries 0
# PROP Output_Dir "Release_lib"
# PROP Intermediate_Dir "Release_lib"
# PROP Target_Dir ""
# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "LIBSSH2_WIN32" /D "_MBCS" /D "_LIB" /YX /FD /c
# ADD CPP /nologo /MD /W3 /GX /O2 /I "..\win32" /I "..\include" /D "WIN32" /D "NDEBUG" /D "LIBSSH2_WIN32" /D "_MBCS" /D "_LIB" /YX /FD /c
# ADD BASE RSC /l 0x409 /d "NDEBUG"
# ADD RSC /l 0x409 /d "NDEBUG"
BSC32=bscmake.exe
# ADD BASE BSC32 /nologo
# ADD BSC32 /nologo
LIB32=link.exe -lib
# ADD BASE LIB32 /nologo
# ADD LIB32 /nologo
# ADD LIB32 /nologo /out:"Release_lib\libssh.lib"
!ELSEIF "$(CFG)" == "libssh2 - Win32 LIB Debug"
# PROP BASE Use_MFC 0
# PROP BASE Use_Debug_Libraries 1
# PROP BASE Output_Dir "Debug_lib"
# PROP BASE Intermediate_Dir "Debug_lib"
# PROP BASE Target_Dir ""
# PROP Use_MFC 0
# PROP Use_Debug_Libraries 1
# PROP Output_Dir "Debug_lib"
# PROP Intermediate_Dir "Debug_lib"
# PROP Target_Dir ""
# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "LIBSSH2_WIN32" /D "_MBCS" /D "_LIB" /YX /FD /GZ /c
# ADD CPP /nologo /MDd /W3 /Gm /GX /ZI /Od /I "..\win32" /I "..\include" /D "WIN32" /D "_DEBUG" /D "LIBSSH2_WIN32" /D "_MBCS" /D "_LIB" /YX /FD /GZ /c
# ADD BASE RSC /l 0x409 /d "_DEBUG"
# ADD RSC /l 0x409 /d "_DEBUG"
BSC32=bscmake.exe
# ADD BASE BSC32 /nologo
# ADD BSC32 /nologo
LIB32=link.exe -lib
# ADD BASE LIB32 /nologo
# ADD LIB32 /nologo /out:"Debug_lib\libssh2d.lib"
!ENDIF
# Begin Target
# Name "libssh2 - Win32 DLL Release"
# Name "libssh2 - Win32 DLL Debug"
# Name "libssh2 - Win32 LIB Release"
# Name "libssh2 - Win32 LIB Debug"

View File

@@ -125,7 +125,7 @@ else
DS = \\
endif
vpath %.c ../../example/simple
vpath %.c ../../example
.PRECIOUS: $(OBJDIR)/%.o $(OBJDIR)/%.rc $(OBJDIR)/%.res