Compare commits

..

88 Commits

Author SHA1 Message Date
Daniel Stenberg
355fbf4d5b prepared for 1.2.2 2009-11-16 22:43:55 +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
Daniel Stenberg
9162fd7e61 1.2.1 preparations 2009-09-29 13:20:32 +02:00
Daniel Stenberg
7208e8d0d9 remove ChangeLog and win32/libssh2.dsp only at make distclean 2009-09-28 14:21:56 +02:00
Simon Josefsson
e1bb074287 Fix shell usage. 2009-09-23 09:39:47 +02:00
Daniel Stenberg
e887ffca4c clarify that the paths are the remote ones 2009-09-22 23:54:10 +02:00
Daniel Stenberg
65d1cb8107 let hpux systems build with _REENTRANT defined as well 2009-09-22 23:46:45 +02:00
Daniel Stenberg
4ed82f0e78 updated to match reality
I went over the commit log and added what I believe is all notable
changes and bugfixes since the 1.2 release
2009-09-20 20:14:23 +02:00
Peter Stuge
3cc2f143c1 Fix scp examples to loop correctly over libssh2_channel_write() 2009-09-20 01:35:19 +02:00
Peter Stuge
683aa0f6b5 Fix transport layer bug causing invalid -39 (LIBSSH2_ERROR_BAD_USE) errors
The channel layer sends packets using the transport layer, possibly
calling _libssh2_transport_write() many times for each packet.

The transport layer uses the send_existing() helper to send out any
remaining parts of previous packets before a new packet is started.

The bug made send_existing() consider the entire packet sent as soon as it
successfully sent the second part of a packet, even if the packet was not
completely done yet.
2009-09-20 00:30:42 +02:00
Neil Gierman
7a9d36903a Added gettimeofday() function for win32
Neil Gierman's patch adds a gettimeofday() function for win32
for the libssh2_trace() functionality. The code originates from
cygwin and was put in the public domain by the author
Danny Smith <dannysmith@users.sourceforge.net>
2009-09-19 22:39:50 +02:00
Daniel Stenberg
c2375dbfa4 libssh2_channel_read_ex() must return 0 when closed
If the channel is already at EOF or even closed at the end of the
libssh2_channel_read_ex() function and there's no data to return,
we need to signal that back. We may have gotten that info while
draining the incoming transport layer until EAGAIN so we must not
be fooled by that return code.
2009-09-16 23:46:30 +02:00
Dan Fandrich
906a7d8866 Ignore tags file 2009-09-16 07:49:32 -07:00
Dan Fandrich
1418993a0f Some platforms need sys/socket.h included before netinet/in.h.
Fixed an unused variable compiler warning.
2009-09-16 07:49:32 -07:00
Daniel Stenberg
c4b7f0394b libssh2_channel_wait_closed() could hang
libssh2_channel_wait_closed() had a bad loop waiting for the
channel to close, as it could easily miss the info and then if
the socket would be silent from that moment the funtion would
hang if in blocking-mode or just return EAGAIN wrongly to the
app. The drain-transport loop now correctly checks if the close
has arrived.
2009-09-16 13:49:04 +02:00
Daniel Stenberg
9e84b999a5 make libssh2_scp_send/recv do blocking mode correctly
Somehow I had completely missed to make the libssh2_scp_send/recv
functions support the blocking mode the correct way so when I
cleaned up things the other day blocking mode broke for them...
Fixed now.
2009-09-15 23:29:46 +02:00
Guenter Knauf
3fda91d725 changed NetWare test makefile static link order 2009-09-08 01:32:45 +02:00
Guenter Knauf
7c32c84d0e removed conditional sources from Makefile.inc
added ifdef blocks to libgcrypt.c, pem.c, openssl.c
2009-09-07 18:10:49 +02:00
Simon Josefsson
766127ad57 Fix compilation errors. 2009-09-07 14:14:10 +02:00
Guenter Knauf
a9e7f87e31 some more NetWare build fixes. 2009-09-06 06:57:55 +02:00
Guenter Knauf
a04a0b6c69 some more NetWare makefile fixes. 2009-09-06 06:31:59 +02:00
Guenter Knauf
1f8d58a4ce added sys/select.h include to samples for fd_set on NetWare. 2009-09-06 06:15:29 +02:00
Guenter Knauf
4b482eddbe accept CFLAGS from environment. 2009-09-06 04:36:51 +02:00
Guenter Knauf
05eb612f8e some more .cvsignore / .gitignore fixes. 2009-09-04 02:23:28 +02:00
Guenter Knauf
d48ee98ecf renamed .cvsignore to .gitignore. 2009-09-04 02:12:50 +02:00
Guenter Knauf
536443246e changed conditional into make language. 2009-09-04 01:24:38 +02:00
Guenter Knauf
b728b1018f changed NetWare and MingW32 makefile to use Makefile.inc. 2009-09-03 22:06:59 +02:00
Daniel Stenberg
3f5a6662d0 CVS leftovers removed 2009-09-02 22:41:47 +02:00
Daniel Stenberg
33f4e0f250 libssh2_version() exists since 1.1 2009-09-02 22:39:48 +02:00
Hacki
8dabb1c5eb added knownhost.c to makefiles. 2009-09-02 20:03:27 +02:00
Alexander Lamaison
0d6aaa1f56 Pass private-key to OpenSSL as a filename with BIO_new_file().
This keeps all FILE* handling on the OpenSSL side of the DLL boundary avoiding crashes on Windows while removing the need for libssh2 to read the private key file into memory.  This is now done by OpenSSL which is likely to do a better job of it.
2009-09-02 14:59:40 +01:00
Daniel Stenberg
00fac145ba generate and install libssh2.pc
oh these are necessary libssh2.pc changes too
2009-09-01 10:04:13 +02:00
Daniel Stenberg
f65f71a156 first take at producing and installing a pkg-config file 2009-09-01 09:55:25 +02:00
Daniel Stenberg
3142e8df7e renamed to .ac 2009-09-01 09:51:14 +02:00
Daniel Stenberg
bffefb12ea renamed to the modern name "configure.ac" 2009-09-01 09:48:14 +02:00
Daniel Stenberg
feadd5f321 always braces and else and brace on the same line removed
I don't follow those particular guidelines myself so I think I'd
rather remove them here and keep my style than the opposite. As
I am the most frequent writer of code for the moment.
2009-09-01 09:42:33 +02:00
Daniel Stenberg
7c139633a1 _libssh2_channel_write() only sends the 32K first bytes
In theory we could split larger buffers into several smaller
packets to pass to transport_write(), but for now we instead only
deal with the first 32K in this call and assume the app will call
this function again with the rest!  The 32K size is a
conservative limit based on the text in RFC4253 section 6.1.
2009-08-30 23:52:11 +02:00
Daniel Stenberg
692401633a document _libssh2_channel_write's return code 2009-08-30 19:46:42 +02:00
Daniel Stenberg
5bb1fb5cbc s/libssh2_channel_write_ex/_libssh2_channel_write internally 2009-08-30 19:31:07 +02:00
Daniel Stenberg
5e5ead00b4 call libssh2_error() when transport_write() returns EAGAIN
_libssh2_channel_write() should never return error without
libssh2_error() getting called
2009-08-30 19:28:43 +02:00
Daniel Stenberg
06278728e2 clarify that zero can be returned without meaning error 2009-08-30 17:07:50 +02:00
Daniel Stenberg
0357befa42 remove debug leftovers 2009-08-30 17:06:57 +02:00
Daniel Stenberg
85198c1cdb channel_read() was changed to _libssh2_channel_read() as lots of
internal code was changed to use that instead of wrongly using
libssh2_channel_read_ex(). Some files now need to include
channel.h to get this proto.

channel_read() calls libssh2_error() properly on transport_read()
failures

channel_read() was adjusted to not "invent" EAGAIN return code in
case the transport_read() didn't return it

channel_close() now returns 0 or error code, as
documented. Previously it would return number of bytes read in
the last read, which was confusing (and useless).
2009-08-30 17:00:49 +02:00
Daniel Stenberg
face4750ca changed all return EAGAIN to return the variable instead
I made this change just to easier grep for "return .*EAGAIN" cases
as they should be very rare or done wrongly. Already worked to find
a flaw, marked with "TODO FIXME THIS IS WRONG" in channel.c. I also
fixed a few cases to become more general returns now when we have
more unified return codes internally.
2009-08-25 00:54:47 +02:00
Daniel Stenberg
a1365916c7 _libssh2_channel_write() must not invent EAGAIN situations
it is important that only the transport layer can generate EAGAIN
error codes so that we limit where we need to set direction bits
and more. When the local window is too small to send data we simply
stop trying to send and (risk) returning zero in
_libssh2_channel_write()
2009-08-25 00:25:08 +02:00
Daniel Stenberg
f64a84a909 error code cleanup 2009-08-25 00:23:34 +02:00
Daniel Stenberg
fba3877ed8 remove all libssh2pack_t leftovers 2009-08-24 23:57:15 +02:00
Daniel Stenberg
f1e010f5d4 removed the libssh2pack_t type
and a minor _libssh2_transport_read() simplification
2009-08-24 23:50:53 +02:00
Daniel Stenberg
9e96acf86e fix return codes, shortened a very long function name 2009-08-24 23:49:58 +02:00
Daniel Stenberg
1a157d27cc remove use of libssh2_channel_receive_window_adjust
_libssh2_channel_receive_window_adjust is the new replacement that
is both the correct internal version instead of the external API one,
and it has the return code flaw fixed. I also fixed more return
codes to pass long the correct error found.
2009-08-24 23:24:35 +02:00
Daniel Stenberg
b3418bb1eb more proper return codes, added a missing libssh2_error() call 2009-08-24 23:23:46 +02:00
Daniel Stenberg
08be841b4d clear socket_block_directions bits before send/recv
These two places are the only places where send and recv are called
outside of transport.c so make sure they clear/set the bits correctly.
2009-08-24 23:22:39 +02:00
Daniel Stenberg
e39128df52 simplified fullpacket, clarified _libssh2_transport_write() comment 2009-08-24 23:13:14 +02:00
Daniel Stenberg
5c6b8166c7 cleaned up _libssh2_packet_add()
removed some code duplication, changed a few return -1 to return
error codes instead and added a missing libssh2_error() invoke
2009-08-24 23:03:08 +02:00
Daniel Stenberg
dcb9625473 convert return -1 instances to return [proper error code] 2009-08-24 22:50:46 +02:00
Daniel Stenberg
c1b687c9e4 simplify code by removing code duplication 2009-08-24 22:44:22 +02:00
Daniel Stenberg
13e920d4ef fix several return -1 to return a proper error code
On many places in the code there have been laziness return -1
statements lying around that should be fixed to return sensible
error codes. Here's a take at fixing a few offenders.
2009-08-24 22:28:27 +02:00
Daniel Stenberg
314e61e545 change transport to use unified error codes
I added three new public error codes, and then modified the return
codes we use in the transport layer to use the generic error codes
so that there won't be any risk of internal confusions due to
different error code sets.
2009-08-24 22:27:11 +02:00
Daniel Stenberg
13c16db3bc changes from int to libssh2_socket_t for sokcets
modified two functions to use libssh2_socket_t instead of int
when referring to a socket descriptor
2009-08-24 14:13:00 +02:00
Daniel Stenberg
82c3f0ba72 introducing libssh2_socket_t type and fixed iovec for windows
Steven Van Ingelgem introduces libssh2_socket_t as a generic socket
type to use internally to avoid compiler warnings and mistakes. Also,
the private struct iovec declaration for windows is now made to look
like the POSIX struct does.
2009-08-24 14:07:05 +02:00
Daniel Stenberg
9e099fb88a linked list changes and minor bug fixes 2009-08-20 01:03:40 +02:00
Daniel Stenberg
415efe10ac linked list code is now converted to new functions 2009-08-20 01:00:54 +02:00
Daniel Stenberg
4b1cb4e95e remove superfluous braces and re-indent somewhat 2009-08-20 00:59:23 +02:00
Daniel Stenberg
d8b6f3c7b8 move over lots of code to the _libssh2_list_* functions
and I fixed a few minor bugs at the same time
2009-08-20 00:56:54 +02:00
Daniel Stenberg
a871f0b214 converted listeners to the linked list functions 2009-08-20 00:56:54 +02:00
Daniel Stenberg
08cad8e14c moved the handling of SFTP handles to new linked list code
Each SFTP file handle is now handled by the "mother-struct"
using the generic linked list functions. The goal is to move
all custom linked list code to use this set of functions.

I also moved the list declarations to the misc.h where they
belong and made misc.h no longer include libssh2_priv.h itself
since now libssh2_priv.h needs misc.h...

In misc.c I added a #if 0'ed _libssh2_list_insert() function
because I ended up writing one, and I believe we may need it here
too once we move over more stuff to use the _libssh2_list* family.
2009-08-20 00:56:54 +02:00
Daniel Stenberg
46178378f2 correct the comment for _libssh2_list_add()
it adds the new node to the _end_ of the list
2009-08-20 00:56:54 +02:00
Steven Van Ingelgem
28b179ecf2 Suppress signed/unsigned comparison warning. 2009-08-16 23:14:20 +01:00
Daniel Stenberg
7b4d6b2868 added contributors from the 1.2 release notes 2009-08-11 10:11:11 +02:00
Simon Josefsson
fbe4737719 Need to use $(EXEEXT) on programs in TESTS to fix mingw cross-compiles. 2009-08-11 02:46:45 +02:00
Daniel Stenberg
ce4ad0d086 start working on 1.2.1 2009-08-10 22:58:15 +02:00
72 changed files with 1629 additions and 1462 deletions

View File

@@ -1,28 +0,0 @@
.deps
.libs
*.lib
*.pdb
*.dll
*.exe
*.obj
.*.swp
Debug
Release
*.exp
Makefile
Makefile.in
aclocal.m4
autom4te.cache
config.guess
config.log
config.status
config.sub
configure
depcomp
libtool
ltmain.sh
missing
ssh2_sample
libssh2-*.tar.gz
INSTALL
install-sh

View File

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

2
.gitattribute Normal file
View File

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

1
.gitignore vendored
View File

@@ -30,3 +30,4 @@ install-sh
*.lo
*.la
mkinstalldirs
tags

View File

@@ -6,6 +6,7 @@
Adam Gobiowski
Alexander Holyapin
Alexander Lamaison
Ben Kibbey
Bjorn Stenborg
Carlo Bramini
Dan Casey
@@ -15,15 +16,19 @@ David J Sullivan
David Robins
Edink Kadribasic
Erik Brossler
Francois Dupoux
Guenter Knauf
Heiner Steven
James Housleys
Jean-Louis Charton
Jussi Mononen
Mark McPherson
Markus Moeller
Mike Protts
Mikhail Gusarov
Neil Gierman
Olivier Hervieu
Paul Veldkamp
Peter O'Gorman
Peter Stuge
Romain Bondue
@@ -34,6 +39,8 @@ Selcuk Gueney
Simon Hart
Simon Josefsson
Steven Ayre
Steven Van Ingelgem
Tor Arntsen
Vincent Jaulin
Vlad Grachov
Wez Furlong

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,

11
HACKING
View File

@@ -9,14 +9,5 @@ libssh2 source code style guide:
go_nuts();
}
- write both braces on the else line:
if (banana) {
go_nuts();
} else {
stay_calm();
}
- use braces even for single-statement blocks
- keep source lines shorter than 80 columns
- See libssh2-style.el for how to achieve this within Emacs

View File

@@ -2,6 +2,9 @@ AUTOMAKE_OPTIONS = foreign nostdinc
SUBDIRS = src example tests docs
pkgconfigdir = $(libdir)/pkgconfig
pkgconfig_DATA = libssh2.pc
include_HEADERS = \
include/libssh2.h \
include/libssh2_publickey.h \
@@ -16,8 +19,7 @@ NETWAREFILES = nw/keepscreen.c \
DSP = win32/libssh2.dsp
VCPROJ = win32/libssh2.vcproj
#Need to include $(VCPROJ) to CLEANFILES and WIN32FILES when I get a proper vc8proj.head|foot
CLEANFILES = $(DSP)
DISTCLEANFILES = $(DSP)
WIN32FILES = win32/Makefile.win32 win32/libssh2.dsw \
win32/config.mk win32/Makefile win32/test/Makefile.win32 \
@@ -25,14 +27,14 @@ win32/libssh2_config.h win32/tests.dsp win32/rules.mk $(DSP) \
win32/msvcproj.head win32/msvcproj.foot
EXTRA_DIST = $(WIN32FILES) buildconf $(NETWAREFILES) get_ver.awk HACKING \
maketgz NMakefile TODO RELEASE-NOTES
maketgz NMakefile TODO RELEASE-NOTES libssh2.pc.in
ACLOCAL_AMFLAGS = -I m4
.PHONY: ChangeLog
ChangeLog:
echo "see NEWS" > ./ChangeLog
CLEANFILES += ChangeLog
DISTCLEANFILES += ChangeLog
dist-hook:
rm -rf $(top_builddir)/tests/log
@@ -73,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); \
@( (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" $(DSPOUT); \
echo "" $(DSPOUT); \
echo "SOURCE=..\\src\\"$$file $(DSPOUT); \
echo "# End Source File" $(DSPOUT); \
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); \
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" $(DSPOUT); \
echo "" $(DSPOUT); \
echo "# Begin Source File"; \
echo ""; \
if [ "$$file" == "libssh2_config.h" ]; \
then \
echo "SOURCE=.\\"$$file $(DSPOUT); \
echo "SOURCE=.\\"$$file; \
else \
echo "SOURCE=..\\src\\"$$file $(DSPOUT); \
echo "SOURCE=..\\src\\"$$file; \
fi; \
echo "# End Source File" $(DSPOUT); \
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); \
@( (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>" $(VCPROJOUT); \
echo "<File RelativePath=\""..\src\$$file"\"></File>"; \
done; \
echo "</Filter><Filter Name=\"Header Files\">" $(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>" $(VCPROJOUT); \
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,11 +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
if LIBGCRYPT
CSOURCES += libgcrypt.c pem.c
else
CSOURCES += openssl.c
endif
version.c knownhost.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

45
NEWS
View File

@@ -1,3 +1,48 @@
Version 1.2.2 (unreleased)
* 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.
Version 1.2.1 (September 28, 2009)
* This release includes the following changes:
o generate and install libssh2.pc
... and 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()
* (August 29 2009) Daniel Stenberg:
- I fixed all code to use the recently added dedicated linked list functions
instead of doing the same stuff spread out all over.
- I also fixed a few cases where local variables where used to keep memory
but was used to keep state for re-invokes due to non-blocking situations
which would lead to segfaults.
Version 1.2 (August 10, 2009)
-----------------------------

View File

@@ -1,40 +1,18 @@
libssh2 1.2
libssh2 1.2.2
This release includes the following changes:
o we've switched to using git for source code control
o we're offering an alternative web site at http://libssh2.haxx.se/
o the libssh2-devel mailing list moved to http://cool.haxx.se/
o libssh2_poll() and libssh2_poll_channel_read() are now deprecated
o a range of libssh2_knownhost_*() functions were added to the API to work
with OpenSSH style known_hosts files etc
o added libssh2_session_hostkey()
o added an X11 forwarding example
o the makefile now generate MSVS project files
o Support for the "aes128-ctr", "aes192-ctr", "aes256-ctr" ciphers
o Support for the "arcfour128" cipher
This release includes the following bugfixes:
o bad 0-return from libssh2_channel_read
o failure to "drain" the transport data caused badness
o memory leak in libssh2_sftp_shutdown()
o fixed stroll() #if condition
o build thread-safe on Solaris
o error when including libssh2.h in two files on Windows fixed
o custom memory function extra argument was wrong
o transport now checks for and bail out on packets claing to be zero sized
o fixed a number of compiler warnings
o buildconf runs on Mac OS X
o public headers includable on their own
o bad debugdump() caused SIGSEGV at times (when libssh2_trace() was used)
o possible data loss when send_existing() failed to send its buffer
o passing FILE*s across DLL boundaries (OpenSSL) caused crashes on Windows
o Fix crash when server sends an invalid SSH_MSG_IGNORE message
This release would not have looked like this without help, code, reports and
advice from friends like these:
Simon Josefsson, Neil Gierman, Alexander Lamaison, Peter Stuge,
Steven Van Ingelgem, Ben Kibbey, Francois Dupoux, Mark McPherson,
Guenter Knauf, Yang Tse, Tor Arntsen, Jussi Mononen, Olivier Hervieu,
Paul Veldkamp
Simon Josefsson, Bob Alexander
Thanks! (and sorry if I forgot to mention someone)

3
TODO
View File

@@ -8,9 +8,6 @@ Things TODO
* Provide a libssh2_scp_send() API for files larger than 4GB (32bit size)
* Convert the linked list code used all over to use the (new) generic linked
list code. See the _libssh2_list_*() functions in src/misc.c
* Add more info to the man pages.
* Decrease the number of mallocs. Everywhere.

View File

@@ -297,7 +297,7 @@ dnl Internal macro for CURL_CONFIGURE_REENTRANT.
AC_DEFUN([CURL_CHECK_NEED_REENTRANT_SYSTEM], [
case $host in
*-*-solaris*)
*-*-solaris* | *-*-hpux*)
tmp_need_reentrant="yes"
;;
*)

View File

@@ -162,6 +162,45 @@ 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])
@@ -214,5 +253,6 @@ AC_CONFIG_FILES([Makefile
tests/Makefile
example/Makefile
example/simple/Makefile
docs/Makefile])
docs/Makefile
libssh2.pc])
AC_OUTPUT

View File

View File

@@ -40,6 +40,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 \

View File

@@ -35,6 +35,9 @@ macros.
Actual number of bytes read 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.
Note that a return value of zero (0) can in fact be a legitimate value and
only signals that no payload data was read. It is not an error.
.SH ERRORS
\fILIBSSH2_ERROR_SOCKET_SEND\fP - Unable to send data on socket.

View File

@@ -0,0 +1,21 @@
.\"
.\" 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
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.
.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

@@ -13,7 +13,8 @@ libssh2_scp_recv(LIBSSH2_SESSION *session, const char *path, struct stat *sb);
\fIsession\fP - Session instance as returned by
.BR libssh2_session_init_ex(3)
\fIpath\fP - Full path and filename of file to transfer
\fIpath\fP - Full path and filename of file to transfer. That is the remote
file name.
\fIsb\fP - Populated with remote file's size, mode, mtime, and atime

View File

@@ -12,7 +12,8 @@ libssh2_scp_send_ex(LIBSSH2_SESSION *session, const char *path, int mode, size_t
\fIsession\fP - Session instance as returned by
.BR libssh2_session_init_ex(3)
\fIpath\fP - Full path and filename of file to transfer
\fIpath\fP - Full path and filename of file to transfer to. That is the remote
file name.
\fImode\fP - File access mode to create file with

View File

@@ -1,21 +0,0 @@
Makefile
Makefile.in
.deps
.libs
*.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

View File

@@ -10,12 +10,12 @@
#ifdef HAVE_WINSOCK2_H
# include <winsock2.h>
#endif
#ifdef HAVE_NETINET_IN_H
# include <netinet/in.h>
#endif
#ifdef HAVE_SYS_SOCKET_H
# include <sys/socket.h>
#endif
#ifdef HAVE_NETINET_IN_H
# include <netinet/in.h>
#endif
# ifdef HAVE_UNISTD_H
#include <unistd.h>
#endif

View File

@@ -15,11 +15,14 @@
#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_SYS_SOCKET_H
# include <sys/socket.h>
#ifdef HAVE_SYS_SELECT_H
# include <sys/select.h>
#endif
# ifdef HAVE_UNISTD_H
#include <unistd.h>

View File

@@ -10,12 +10,12 @@
#ifdef HAVE_WINSOCK2_H
# include <winsock2.h>
#endif
#ifdef HAVE_NETINET_IN_H
# include <netinet/in.h>
#endif
#ifdef HAVE_SYS_SOCKET_H
# include <sys/socket.h>
#endif
#ifdef HAVE_NETINET_IN_H
# include <netinet/in.h>
#endif
# ifdef HAVE_UNISTD_H
#include <unistd.h>
#endif
@@ -47,7 +47,7 @@ int main(int argc, char *argv[])
FILE *local;
int rc;
char mem[1024];
size_t nread;
size_t nread, sent;
char *ptr;
struct stat fileinfo;
@@ -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) {
@@ -159,13 +159,20 @@ int main(int argc, char *argv[])
break;
}
ptr = mem;
sent = 0;
do {
/* write data in a loop until we block */
/* write the same data over and over, until error or completion */
rc = libssh2_channel_write(channel, ptr, nread);
ptr += rc;
nread -= nread;
} while (rc > 0);
if (rc < 0) {
fprintf(stderr, "ERROR %d\n", rc);
} else {
/* rc indicates how many bytes were written this time */
sent += rc;
}
} while (rc > 0 && sent < nread);
ptr += sent;
nread -= sent;
} while (1);
fprintf(stderr, "Sending EOF\n");

View File

@@ -11,12 +11,12 @@
#ifdef HAVE_WINSOCK2_H
# include <winsock2.h>
#endif
#ifdef HAVE_NETINET_IN_H
# include <netinet/in.h>
#endif
#ifdef HAVE_SYS_SOCKET_H
# include <sys/socket.h>
#endif
#ifdef HAVE_NETINET_IN_H
# include <netinet/in.h>
#endif
# ifdef HAVE_UNISTD_H
#include <unistd.h>
#endif
@@ -51,7 +51,7 @@ int main(int argc, char *argv[])
long flag = 1;
#endif
char mem[1024];
size_t nread;
size_t nread, sent;
char *ptr;
struct stat fileinfo;
@@ -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) !=
@@ -176,17 +176,22 @@ int main(int argc, char *argv[])
break;
}
ptr = mem;
sent = 0;
do {
/* write data in a loop until we block */
while ((rc = libssh2_channel_write(channel, ptr, nread)) ==
LIBSSH2_ERROR_EAGAIN);
if (rc < 0) {
/* write the same data over and over, until error or completion */
rc = libssh2_channel_write(channel, ptr, nread);
if (LIBSSH2_ERROR_EAGAIN == rc) { /* must loop around */
continue;
} else if (rc < 0) {
fprintf(stderr, "ERROR %d\n", rc);
} else {
/* rc indicates how many bytes were written this time */
sent += rc;
}
ptr += rc;
nread -= rc;
} while (nread > 0);
} while (rc > 0 && sent < nread);
ptr += sent;
nread -= sent;
} while (1);
fprintf(stderr, "Sending EOF\n");

View File

@@ -16,12 +16,12 @@
#ifdef HAVE_WINSOCK2_H
# include <winsock2.h>
#endif
#ifdef HAVE_NETINET_IN_H
# include <netinet/in.h>
#endif
#ifdef HAVE_SYS_SOCKET_H
# include <sys/socket.h>
#endif
#ifdef HAVE_NETINET_IN_H
# include <netinet/in.h>
#endif
# ifdef HAVE_UNISTD_H
#include <unistd.h>
#endif

View File

@@ -16,11 +16,14 @@
#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_SYS_SOCKET_H
# include <sys/socket.h>
#ifdef HAVE_SYS_SELECT_H
# include <sys/select.h>
#endif
# ifdef HAVE_UNISTD_H
#include <unistd.h>

View File

@@ -16,12 +16,12 @@
#ifdef HAVE_WINSOCK2_H
# include <winsock2.h>
#endif
#ifdef HAVE_NETINET_IN_H
# include <netinet/in.h>
#endif
#ifdef HAVE_SYS_SOCKET_H
# include <sys/socket.h>
#endif
#ifdef HAVE_NETINET_IN_H
# include <netinet/in.h>
#endif
# ifdef HAVE_UNISTD_H
#include <unistd.h>
#endif

View File

@@ -16,12 +16,12 @@
#ifdef HAVE_WINSOCK2_H
# include <winsock2.h>
#endif
#ifdef HAVE_NETINET_IN_H
# include <netinet/in.h>
#endif
#ifdef HAVE_SYS_SOCKET_H
# include <sys/socket.h>
#endif
#ifdef HAVE_NETINET_IN_H
# include <netinet/in.h>
#endif
# ifdef HAVE_UNISTD_H
#include <unistd.h>
#endif

View File

@@ -16,11 +16,14 @@
#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_SYS_SOCKET_H
# include <sys/socket.h>
#ifdef HAVE_SYS_SELECT_H
# include <sys/select.h>
#endif
# ifdef HAVE_UNISTD_H
#include <unistd.h>

View File

@@ -16,12 +16,12 @@
#ifdef HAVE_WINSOCK2_H
# include <winsock2.h>
#endif
#ifdef HAVE_NETINET_IN_H
# include <netinet/in.h>
#endif
#ifdef HAVE_SYS_SOCKET_H
# include <sys/socket.h>
#endif
#ifdef HAVE_NETINET_IN_H
# include <netinet/in.h>
#endif
# ifdef HAVE_UNISTD_H
#include <unistd.h>
#endif

View File

@@ -16,12 +16,12 @@
#ifdef HAVE_WINSOCK2_H
# include <winsock2.h>
#endif
#ifdef HAVE_NETINET_IN_H
# include <netinet/in.h>
#endif
#ifdef HAVE_SYS_SOCKET_H
# include <sys/socket.h>
#endif
#ifdef HAVE_NETINET_IN_H
# include <netinet/in.h>
#endif
# ifdef HAVE_UNISTD_H
#include <unistd.h>
#endif

View File

@@ -16,12 +16,12 @@
#ifdef HAVE_WINSOCK2_H
# include <winsock2.h>
#endif
#ifdef HAVE_NETINET_IN_H
# include <netinet/in.h>
#endif
#ifdef HAVE_SYS_SOCKET_H
# include <sys/socket.h>
#endif
#ifdef HAVE_NETINET_IN_H
# include <netinet/in.h>
#endif
# ifdef HAVE_UNISTD_H
#include <unistd.h>
#endif

View File

@@ -16,12 +16,12 @@
#ifdef HAVE_WINSOCK2_H
# include <winsock2.h>
#endif
#ifdef HAVE_NETINET_IN_H
# include <netinet/in.h>
#endif
#ifdef HAVE_SYS_SOCKET_H
# include <sys/socket.h>
#endif
#ifdef HAVE_NETINET_IN_H
# include <netinet/in.h>
#endif
# ifdef HAVE_UNISTD_H
#include <unistd.h>
#endif

View File

@@ -19,12 +19,12 @@
#ifdef HAVE_WINSOCK2_H
# include <winsock2.h>
#endif
#ifdef HAVE_NETINET_IN_H
# include <netinet/in.h>
#endif
#ifdef HAVE_SYS_SOCKET_H
# include <sys/socket.h>
#endif
#ifdef HAVE_NETINET_IN_H
# include <netinet/in.h>
#endif
# ifdef HAVE_UNISTD_H
#include <unistd.h>
#endif

View File

@@ -18,11 +18,14 @@
#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_SYS_SOCKET_H
# include <sys/socket.h>
#ifdef HAVE_SYS_SELECT_H
# include <sys/select.h>
#endif
# ifdef HAVE_UNISTD_H
#include <unistd.h>

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.1.1_CVS"
#define LIBSSH2_VERSION "1.2.2_DEV"
/* The numeric version number is also available "in parts" by using these
defines: */
#define LIBSSH2_VERSION_MAJOR 1
#define LIBSSH2_VERSION_MINOR 1
#define LIBSSH2_VERSION_PATCH 1
#define LIBSSH2_VERSION_MINOR 2
#define LIBSSH2_VERSION_PATCH 2
/* 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 0x010101
#define LIBSSH2_VERSION_NUM 0x010202
/*
* 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
@@ -356,6 +356,9 @@ typedef struct _LIBSSH2_POLLFD {
#define LIBSSH2_ERROR_PUBLICKEY_PROTOCOL -36
#define LIBSSH2_ERROR_EAGAIN -37
#define LIBSSH2_ERROR_BUFFER_TOO_SMALL -38
#define LIBSSH2_ERROR_BAD_USE -39
#define LIBSSH2_ERROR_COMPRESS -40
#define LIBSSH2_ERROR_OUT_OF_BOUNDARY -41
/* Session API */
LIBSSH2_API LIBSSH2_SESSION *
@@ -675,6 +678,7 @@ LIBSSH2_API
const char *libssh2_version(int req_version_num);
#define HAVE_LIBSSH2_KNOWNHOST_API 0x010101 /* since 1.1.1 */
#define HAVE_LIBSSH2_VERSION_API 0x010100 /* libssh2_version since 1.1 */
struct libssh2_knownhost {
unsigned int magic; /* magic stored by the library */

16
libssh2.pc.in Normal file
View File

@@ -0,0 +1,16 @@
###########################################################################
# libssh2 installation details
###########################################################################
prefix=@prefix@
exec_prefix=@exec_prefix@
libdir=@libdir@
includedir=@includedir@
Name: libssh2
URL: http://www.libssh2.org/
Description: Library for SSH based connunication
Version: @VERSION@
Libs: -L${libdir} -lssh2 @LDFLAGS@ @LIBS@
Libs.private: @LIBS@
Cflags: -I${includedir}

View File

@@ -96,7 +96,7 @@ LIBARCH_L = $(shell $(AWK) 'BEGIN {print tolower(ARGV[1])}' $(LIBARCH))
-include $(OBJDIR)/version.inc
# Global flags for all compilers
CFLAGS = $(OPT) -D$(DB) -DNETWARE -nostdinc
CFLAGS += $(OPT) -D$(DB) -DNETWARE -nostdinc
#CFLAGS += -DHAVE_CONFIG_H
ifeq ($(CC),mwccnlm)
@@ -184,8 +184,7 @@ ifdef XDCOPT
XDCDATA = $(OBJDIR)/$(TARGET).xdc
endif
ifeq ($(findstring linux,$(OSTYPE)),linux)
#-include $(NDKBASE)/nlmconv/ncpfs.inc
ifeq ($(findstring /sh,$(SHELL)),/sh)
DL = '
DS = /
else
@@ -194,24 +193,10 @@ endif
vpath %.c . ../src
OBJECTS = \
channel.o \
comp.o \
crypt.o \
hostkey.o \
kex.o \
mac.o \
misc.o \
openssl.o \
packet.o \
pem.o \
publickey.o \
scp.o \
session.o \
sftp.o \
transport.o \
userauth.o
# include Makefile.inc to get CSOURCES define
include ../Makefile.inc
OBJECTS := $(patsubst %.c,%.o,$(CSOURCES))
ifeq ($(LIBARCH),CLIB)
# CLIB lacks of snprint() function - here's a replacement:
# http://www.ijs.si/software/snprintf/
@@ -220,7 +205,6 @@ vpath %.c $(SNPRINTF)
endif
OBJS := $(addprefix $(OBJDIR)/,$(OBJECTS))
OBJL = $(OBJS) $(OBJDIR)/nwlib.o $(LDLIBS)
all: lib nlm
@@ -382,6 +366,8 @@ ifeq ($(LIBARCH),CLIB)
@echo $(DL)#define HAVE_STRICMP 1$(DL) >> $@
@echo $(DL)#define socklen_t int$(DL) >> $@
@echo $(DL)#define sleep(s) delay(1000 * s)$(DL) >> $@
@echo $(DL)#define strcasecmp stricmp$(DL) >> $@
@echo $(DL)#define strncasecmp strnicmp$(DL) >> $@
else
@echo $(DL)#define OS "i586-pc-libc-NetWare"$(DL) >> $@
@echo $(DL)#define HAVE_DLFCN_H 1$(DL) >> $@
@@ -508,6 +494,7 @@ endif
@echo $(DL) libssh2_channel_eof,$(DL) >> $@
@echo $(DL) libssh2_channel_flush_ex,$(DL) >> $@
@echo $(DL) libssh2_channel_free,$(DL) >> $@
@echo $(DL) libssh2_channel_get_exit_status,$(DL) >> $@
@echo $(DL) libssh2_channel_open_ex,$(DL) >> $@
@echo $(DL) libssh2_channel_process_startup,$(DL) >> $@
@echo $(DL) libssh2_channel_read_ex,$(DL) >> $@
@@ -521,11 +508,18 @@ endif
@echo $(DL) libssh2_hostkey_hash,$(DL) >> $@
@echo $(DL) libssh2_scp_recv,$(DL) >> $@
@echo $(DL) libssh2_scp_send_ex,$(DL) >> $@
@echo $(DL) libssh2_knownhost_add,$(DL) >> $@
@echo $(DL) libssh2_knownhost_check,$(DL) >> $@
@echo $(DL) libssh2_knownhost_free,$(DL) >> $@
@echo $(DL) libssh2_knownhost_init,$(DL) >> $@
@echo $(DL) libssh2_knownhost_readfile,$(DL) >> $@
@echo $(DL) libssh2_knownhost_writefile,$(DL) >> $@
@echo $(DL) libssh2_session_abstract,$(DL) >> $@
@echo $(DL) libssh2_session_block_directions,$(DL) >> $@
@echo $(DL) libssh2_session_callback_set,$(DL) >> $@
@echo $(DL) libssh2_session_disconnect_ex,$(DL) >> $@
@echo $(DL) libssh2_session_free,$(DL) >> $@
@echo $(DL) libssh2_session_hostkey,$(DL) >> $@
@echo $(DL) libssh2_session_init_ex,$(DL) >> $@
@echo $(DL) libssh2_session_last_errno,$(DL) >> $@
@echo $(DL) libssh2_session_last_error,$(DL) >> $@

View File

@@ -29,7 +29,7 @@ LINK_STATIC = 1
# Edit the vars below to change NLM target settings.
SAMPLES = ../../example/simple
TARGETS := $(patsubst $(SAMPLES)/%.c,%.nlm,$(strip $(wildcard $(SAMPLES)/*.c)))
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>
WWWURL = http://www.libssh2.org/
@@ -89,7 +89,7 @@ LIBARCH_L = $(shell $(AWK) 'BEGIN {print tolower(ARGV[1])}' $(LIBARCH))
-include $(OBJDIR)/version.inc
# Global flags for all compilers
CFLAGS = $(OPT) -D$(DB) -DNETWARE -nostdinc
CFLAGS += $(OPT) -D$(DB) -DNETWARE -nostdinc
ifeq ($(CC),mwccnlm)
LD = mwldnlm
@@ -116,12 +116,15 @@ LDFLAGS = -T
AR = ar
ARFLAGS = -cq
LIBEXT = a
CFLAGS += -fno-builtin -fpack-struct -fpcc-struct-return -fno-strict-aliasing
CFLAGS += -Wall,no-unused # -pedantic
CFLAGS += -fno-builtin -fpcc-struct-return -fno-strict-aliasing
CFLAGS += -Wall # -pedantic
ifeq ($(LIBARCH),LIBC)
PRELUDE = $(SDK_LIBC)/imports/libcpre.gcc.o
else
PRELUDE = $(SDK_CLIB)/imports/clibpre.gcc.o
# PRELUDE = $(SDK_CLIB)/imports/clibpre.gcc.o
# to avoid the __init_* / __deinit_* whoes dont use prelude from NDK
# http://www.gknw.net/development/mk_nlm/gcc_pre.zip
PRELUDE = $(NDK_ROOT)/pre/prelude.o
CFLAGS += -include $(NDKBASE)/nlmconv/genlm.h
endif
endif
@@ -135,6 +138,13 @@ INCLUDES = -I.. -I../../include
LDLIBS =
ifdef LINK_STATIC
LDLIBS += ../libssh2.$(LIBEXT)
else
IMPORTS += @../libssh2.imp
MODULES += libssh2.nlm
endif
INCLUDES += -I$(OPENSSL_PATH)/outinc_nw_$(LIBARCH_L) -I$(OPENSSL_PATH)/outinc_nw_$(LIBARCH_L)/openssl
LDLIBS += $(OPENSSL_PATH)/out_nw_$(LIBARCH_L)/ssl.$(LIBEXT)
LDLIBS += $(OPENSSL_PATH)/out_nw_$(LIBARCH_L)/crypto.$(LIBEXT)
@@ -150,13 +160,6 @@ else
endif
endif
ifdef LINK_STATIC
LDLIBS += ../libssh2.$(LIBEXT)
else
IMPORTS += @../libssh2.imp
MODULES += libssh2.nlm
endif
ifeq ($(LIBARCH),LIBC)
INCLUDES += -I$(SDK_LIBC)/include
# INCLUDES += -I$(SDK_LIBC)/include/nks
@@ -177,8 +180,11 @@ ifeq ($(MTSAFE),NO)
XDCOPT = -u
endif
ifeq ($(findstring linux,$(OSTYPE)),linux)
ifeq ($(findstring /sh,$(SHELL)),/sh)
DL = '
DS = /
else
DS = \\
endif
vpath %.c $(SAMPLES)
@@ -188,7 +194,7 @@ vpath %.c $(SAMPLES)
all: prebuild $(TARGETS)
prebuild: $(OBJDIR) $(OBJDIR)/version.inc config.h
prebuild: $(OBJDIR) $(OBJDIR)/version.inc
$(OBJDIR)/%.o: %.c
# @echo Compiling $<
@@ -276,7 +282,7 @@ ifdef IMPORTS
@echo $(DL)import $(IMPORTS)$(DL) >> $@
endif
ifeq ($(LD),nlmconv)
@echo $(DL)input $(<:.def=.o)$(DL) >> $@
@echo $(DL)input $(@:.def=.o)$(DL) >> $@
@echo $(DL)input $(PRELUDE)$(DL) >> $@
ifdef LDLIBS
@echo $(DL)input $(LDLIBS)$(DL) >> $@
@@ -284,7 +290,7 @@ endif
@echo $(DL)output $(notdir $(@:.def=.nlm))$(DL) >> $@
endif
config.h: Makefile.netware
ssh2_config.h: Makefile.netware
@echo Creating $@
@echo $(DL)/* $@ for NetWare target.$(DL) > $@
@echo $(DL)** Do not edit this file - it is created by make!$(DL) >> $@

View File

@@ -61,13 +61,13 @@ _libssh2_channel_nextid(LIBSSH2_SESSION * session)
unsigned long id = session->next_channel;
LIBSSH2_CHANNEL *channel;
channel = session->channels.head;
channel = _libssh2_list_first(&session->channels);
while (channel) {
if (channel->local.id > id) {
id = channel->local.id;
}
channel = channel->next;
channel = _libssh2_list_next(&channel->node);
}
/* This is a shortcut to avoid waiting for close packets on channels we've
@@ -92,17 +92,23 @@ LIBSSH2_CHANNEL *
_libssh2_channel_locate(LIBSSH2_SESSION *session, unsigned long channel_id)
{
LIBSSH2_CHANNEL *channel;
LIBSSH2_LISTENER *listener;
LIBSSH2_LISTENER *l;
for(channel = session->channels.head; channel; channel = channel->next) {
for(channel = _libssh2_list_first(&session->channels);
channel;
channel = _libssh2_list_next(&channel->node)) {
if (channel->local.id == channel_id)
return channel;
}
/* We didn't find the channel in the session, let's then check its
listeners... */
for(listener = session->listeners; listener; listener = listener->next) {
for(channel = listener->queue; channel; channel = channel->next) {
listeners since each listener may have its own set of pending channels
*/
for(l = _libssh2_list_first(&session->listeners); l;
l = _libssh2_list_next(&l->node)) {
for(channel = _libssh2_list_first(&l->queue);
channel;
channel = _libssh2_list_next(&channel->node)) {
if (channel->local.id == channel_id)
return channel;
}
@@ -111,20 +117,6 @@ _libssh2_channel_locate(LIBSSH2_SESSION *session, unsigned long channel_id)
return NULL;
}
#define CHANNEL_ADD(session, channel) \
{ \
if ((session)->channels.tail) { \
(session)->channels.tail->next = (channel); \
(channel)->prev = (session)->channels.tail; \
} else { \
(session)->channels.head = (channel); \
(channel)->prev = NULL; \
} \
(channel)->next = NULL; \
(session)->channels.tail = (channel); \
(channel)->session = (session); \
}
/*
* _libssh2_channel_open
*
@@ -187,8 +179,10 @@ _libssh2_channel_open(LIBSSH2_SESSION * session, const char *channel_type,
session->open_channel->remote.window_size = window_size;
session->open_channel->remote.window_size_initial = window_size;
session->open_channel->remote.packet_size = packet_size;
session->open_channel->session = session;
CHANNEL_ADD(session, session->open_channel);
_libssh2_list_add(&session->channels,
&session->open_channel->node);
s = session->open_packet =
LIBSSH2_ALLOC(session, session->open_packet_len);
@@ -298,18 +292,7 @@ _libssh2_channel_open(LIBSSH2_SESSION * session, const char *channel_type,
unsigned char channel_id[4];
LIBSSH2_FREE(session, session->open_channel->channel_type);
if (session->open_channel->next) {
session->open_channel->next->prev = session->open_channel->prev;
}
if (session->open_channel->prev) {
session->open_channel->prev->next = session->open_channel->next;
}
if (session->channels.head == session->open_channel) {
session->channels.head = session->open_channel->next;
}
if (session->channels.tail == session->open_channel) {
session->channels.tail = session->open_channel->prev;
}
_libssh2_list_remove(&session->open_channel->node);
/* Clear out packets meant for this channel */
_libssh2_htonu32(channel_id, session->open_channel->local.id);
@@ -416,18 +399,12 @@ channel_direct_tcpip(LIBSSH2_SESSION * session, const char *host,
/* by default we set (keep?) idle state... */
session->direct_state = libssh2_NB_state_idle;
if (!channel) {
if (libssh2_session_last_errno(session) == LIBSSH2_ERROR_EAGAIN) {
/* The error code is still set to LIBSSH2_ERROR_EAGAIN,
set our state to created to avoid re-creating the package
on next invoke */
if (!channel &&
libssh2_session_last_errno(session) == LIBSSH2_ERROR_EAGAIN) {
/* The error code is still set to LIBSSH2_ERROR_EAGAIN, set our state
to created to avoid re-creating the package on next invoke */
session->direct_state = libssh2_NB_state_created;
return NULL;
} else {
LIBSSH2_FREE(session, session->direct_message);
session->direct_message = NULL;
return NULL;
}
}
LIBSSH2_FREE(session, session->direct_message);
@@ -585,12 +562,8 @@ channel_forward_listen(LIBSSH2_SESSION * session, const char *host,
listener->queue_size = 0;
listener->queue_maxsize = queue_maxsize;
listener->next = session->listeners;
listener->prev = NULL;
if (session->listeners) {
session->listeners->prev = listener;
}
session->listeners = listener;
/* append this to the parent's list of listeners */
_libssh2_list_add(&session->listeners, &listener->node);
if (bound_port) {
*bound_port = listener->port;
@@ -642,7 +615,7 @@ libssh2_channel_forward_listen_ex(LIBSSH2_SESSION *session, const char *host,
static int channel_forward_cancel(LIBSSH2_LISTENER *listener)
{
LIBSSH2_SESSION *session = listener->session;
LIBSSH2_CHANNEL *queued = listener->queue;
LIBSSH2_CHANNEL *queued;
unsigned char *packet, *s;
unsigned long host_len = strlen(listener->host);
/* 14 = packet_type(1) + request_len(4) + want_replay(1) + host_len(4) +
@@ -660,7 +633,7 @@ static int channel_forward_cancel(LIBSSH2_LISTENER *listener)
if (!packet) {
libssh2_error(session, LIBSSH2_ERROR_ALLOC,
"Unable to allocate memeory for setenv packet", 0);
return -1;
return LIBSSH2_ERROR_ALLOC;
}
*(s++) = SSH_MSG_GLOBAL_REQUEST;
@@ -695,32 +668,27 @@ static int channel_forward_cancel(LIBSSH2_LISTENER *listener)
0);
LIBSSH2_FREE(session, packet);
listener->chanFwdCncl_state = libssh2_NB_state_idle;
return -1;
return LIBSSH2_ERROR_SOCKET_SEND;
}
LIBSSH2_FREE(session, packet);
listener->chanFwdCncl_state = libssh2_NB_state_sent;
}
queued = _libssh2_list_first(&listener->queue);
while (queued) {
LIBSSH2_CHANNEL *next = queued->next;
LIBSSH2_CHANNEL *next = _libssh2_list_next(&queued->node);
rc = libssh2_channel_free(queued);
if (rc == PACKET_EAGAIN) {
return PACKET_EAGAIN;
return rc;
}
queued = next;
}
LIBSSH2_FREE(session, listener->host);
if (listener->next) {
listener->next->prev = listener->prev;
}
if (listener->prev) {
listener->prev->next = listener->next;
} else {
session->listeners = listener->next;
}
/* remove this entry from the parent's list of listeners */
_libssh2_list_remove(&listener->node);
LIBSSH2_FREE(session, listener);
@@ -753,42 +721,31 @@ libssh2_channel_forward_cancel(LIBSSH2_LISTENER *listener)
static LIBSSH2_CHANNEL *
channel_forward_accept(LIBSSH2_LISTENER *listener)
{
libssh2pack_t rc;
int rc;
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 (listener->queue) {
LIBSSH2_SESSION *session = listener->session;
LIBSSH2_CHANNEL *channel;
if (_libssh2_list_first(&listener->queue)) {
LIBSSH2_CHANNEL *channel = _libssh2_list_first(&listener->queue);
channel = listener->queue;
/* detach channel from listener's queue */
_libssh2_list_remove(&channel->node);
listener->queue = listener->queue->next;
if (listener->queue) {
listener->queue->prev = NULL;
}
channel->prev = NULL;
channel->next = session->channels.head;
session->channels.head = channel;
if (channel->next) {
channel->next->prev = channel;
} else {
session->channels.tail = channel;
}
listener->queue_size--;
/* add channel to session's channel list */
_libssh2_list_add(&channel->session->channels, &channel->node);
return channel;
}
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;
@@ -844,7 +801,7 @@ static int channel_setenv(LIBSSH2_CHANNEL *channel,
if (!channel->setenv_packet) {
libssh2_error(session, LIBSSH2_ERROR_ALLOC,
"Unable to allocate memeory for setenv packet", 0);
return -1;
return LIBSSH2_ERROR_ALLOC;
}
*(s++) = SSH_MSG_CHANNEL_REQUEST;
@@ -874,7 +831,7 @@ static int channel_setenv(LIBSSH2_CHANNEL *channel,
rc = _libssh2_transport_write(session, channel->setenv_packet,
channel->setenv_packet_len);
if (rc == PACKET_EAGAIN) {
return PACKET_EAGAIN;
return rc;
} else if (rc) {
libssh2_error(session, LIBSSH2_ERROR_SOCKET_SEND,
"Unable to send channel-request packet for "
@@ -883,7 +840,7 @@ static int channel_setenv(LIBSSH2_CHANNEL *channel,
LIBSSH2_FREE(session, channel->setenv_packet);
channel->setenv_packet = NULL;
channel->setenv_state = libssh2_NB_state_idle;
return -1;
return LIBSSH2_ERROR_SOCKET_SEND;
}
LIBSSH2_FREE(session, channel->setenv_packet);
channel->setenv_packet = NULL;
@@ -899,11 +856,11 @@ static int channel_setenv(LIBSSH2_CHANNEL *channel,
&channel->
setenv_packet_requirev_state);
if (rc == PACKET_EAGAIN) {
return PACKET_EAGAIN;
return rc;
}
if (rc) {
channel->setenv_state = libssh2_NB_state_idle;
return -1;
return rc;
}
if (data[0] == SSH_MSG_CHANNEL_SUCCESS) {
@@ -918,7 +875,7 @@ static int channel_setenv(LIBSSH2_CHANNEL *channel,
libssh2_error(session, LIBSSH2_ERROR_CHANNEL_REQUEST_DENIED,
"Unable to complete request for channel-setenv", 0);
channel->setenv_state = libssh2_NB_state_idle;
return -1;
return LIBSSH2_ERROR_CHANNEL_REQUEST_DENIED;
}
/*
@@ -1017,14 +974,14 @@ static int channel_request_pty(LIBSSH2_CHANNEL *channel,
rc = _libssh2_transport_write(session, channel->reqPTY_packet,
channel->reqPTY_packet_len);
if (rc == PACKET_EAGAIN) {
return PACKET_EAGAIN;
return rc;
} else if (rc) {
libssh2_error(session, LIBSSH2_ERROR_SOCKET_SEND,
libssh2_error(session, rc,
"Unable to send pty-request packet", 0);
LIBSSH2_FREE(session, channel->reqPTY_packet);
channel->reqPTY_packet = NULL;
channel->reqPTY_state = libssh2_NB_state_idle;
return -1;
return rc;
}
LIBSSH2_FREE(session, channel->reqPTY_packet);
channel->reqPTY_packet = NULL;
@@ -1039,7 +996,7 @@ static int channel_request_pty(LIBSSH2_CHANNEL *channel,
1, channel->reqPTY_local_channel, 4,
&channel->reqPTY_packet_requirev_state);
if (rc == PACKET_EAGAIN) {
return PACKET_EAGAIN;
return rc;
} else if (rc) {
channel->reqPTY_state = libssh2_NB_state_idle;
return -1;
@@ -1056,7 +1013,7 @@ static int channel_request_pty(LIBSSH2_CHANNEL *channel,
libssh2_error(session, LIBSSH2_ERROR_CHANNEL_REQUEST_DENIED,
"Unable to complete request for channel request-pty", 0);
channel->reqPTY_state = libssh2_NB_state_idle;
return -1;
return LIBSSH2_ERROR_CHANNEL_REQUEST_DENIED;
}
/*
@@ -1131,14 +1088,14 @@ channel_request_pty_size(LIBSSH2_CHANNEL * channel, int width,
rc = _libssh2_transport_write(session, channel->reqPTY_packet,
channel->reqPTY_packet_len);
if (rc == PACKET_EAGAIN) {
return PACKET_EAGAIN;
return rc;
} else if (rc) {
libssh2_error(session, LIBSSH2_ERROR_SOCKET_SEND,
libssh2_error(session, rc,
"Unable to send window-change packet", 0);
LIBSSH2_FREE(session, channel->reqPTY_packet);
channel->reqPTY_packet = NULL;
channel->reqPTY_state = libssh2_NB_state_idle;
return -1;
return rc;
}
LIBSSH2_FREE(session, channel->reqPTY_packet);
channel->reqPTY_packet = NULL;
@@ -1257,15 +1214,15 @@ channel_x11_req(LIBSSH2_CHANNEL *channel, int single_connection,
rc = _libssh2_transport_write(session, channel->reqX11_packet,
channel->reqX11_packet_len);
if (rc == PACKET_EAGAIN) {
return PACKET_EAGAIN;
return rc;
}
if (rc) {
libssh2_error(session, LIBSSH2_ERROR_SOCKET_SEND,
libssh2_error(session, rc,
"Unable to send x11-req packet", 0);
LIBSSH2_FREE(session, channel->reqX11_packet);
channel->reqX11_packet = NULL;
channel->reqX11_state = libssh2_NB_state_idle;
return -1;
return rc;
}
LIBSSH2_FREE(session, channel->reqX11_packet);
channel->reqX11_packet = NULL;
@@ -1280,10 +1237,11 @@ channel_x11_req(LIBSSH2_CHANNEL *channel, int single_connection,
1, channel->reqX11_local_channel, 4,
&channel->reqX11_packet_requirev_state);
if (rc == PACKET_EAGAIN) {
return PACKET_EAGAIN;
return rc;
} else if (rc) {
/* TODO: call libssh2_error() here! */
channel->reqX11_state = libssh2_NB_state_idle;
return -1;
return rc;
}
if (data[0] == SSH_MSG_CHANNEL_SUCCESS) {
@@ -1331,7 +1289,7 @@ _libssh2_channel_process_startup(LIBSSH2_CHANNEL *channel,
static const unsigned char reply_codes[3] =
{ SSH_MSG_CHANNEL_SUCCESS, SSH_MSG_CHANNEL_FAILURE, 0 };
unsigned long data_len;
libssh2pack_t rc;
int rc;
if (channel->process_state == libssh2_NB_state_idle) {
/* 10 = packet_type(1) + channel(4) + request_len(4) + want_reply(1) */
@@ -1355,7 +1313,7 @@ _libssh2_channel_process_startup(LIBSSH2_CHANNEL *channel,
libssh2_error(session, LIBSSH2_ERROR_ALLOC,
"Unable to allocate memory for channel-process request",
0);
return -1;
return LIBSSH2_ERROR_ALLOC;
}
*(s++) = SSH_MSG_CHANNEL_REQUEST;
@@ -1382,15 +1340,15 @@ _libssh2_channel_process_startup(LIBSSH2_CHANNEL *channel,
rc = _libssh2_transport_write(session, channel->process_packet,
channel->process_packet_len);
if (rc == PACKET_EAGAIN) {
return PACKET_EAGAIN;
return rc;
}
else if (rc) {
libssh2_error(session, LIBSSH2_ERROR_SOCKET_SEND,
libssh2_error(session, rc,
"Unable to send channel request", 0);
LIBSSH2_FREE(session, channel->process_packet);
channel->process_packet = NULL;
channel->process_state = libssh2_NB_state_idle;
return -1;
return rc;
}
LIBSSH2_FREE(session, channel->process_packet);
channel->process_packet = NULL;
@@ -1405,10 +1363,12 @@ _libssh2_channel_process_startup(LIBSSH2_CHANNEL *channel,
1, channel->process_local_channel, 4,
&channel->process_packet_requirev_state);
if (rc == PACKET_EAGAIN) {
return PACKET_EAGAIN;
return rc;
} else if (rc) {
channel->process_state = libssh2_NB_state_idle;
return -1;
libssh2_error(session, rc,
"Failed waiting for channel success", 0);
return rc;
}
if (data[0] == SSH_MSG_CHANNEL_SUCCESS) {
@@ -1422,7 +1382,7 @@ _libssh2_channel_process_startup(LIBSSH2_CHANNEL *channel,
libssh2_error(session, LIBSSH2_ERROR_CHANNEL_REQUEST_DENIED,
"Unable to complete request for channel-process-startup", 0);
channel->process_state = libssh2_NB_state_idle;
return -1;
return LIBSSH2_ERROR_CHANNEL_REQUEST_DENIED;
}
/*
@@ -1464,14 +1424,14 @@ libssh2_channel_set_blocking(LIBSSH2_CHANNEL * channel, int blocking)
int
_libssh2_channel_flush(LIBSSH2_CHANNEL *channel, int streamid)
{
LIBSSH2_PACKET *packet = channel->session->packets.head;
if (channel->flush_state == libssh2_NB_state_idle) {
LIBSSH2_PACKET *packet =
_libssh2_list_first(&channel->session->packets);
channel->flush_refund_bytes = 0;
channel->flush_flush_bytes = 0;
while (packet) {
LIBSSH2_PACKET *next = packet->next;
LIBSSH2_PACKET *next = _libssh2_list_next(&packet->node);
unsigned char packet_type = packet->data[0];
if (((packet_type == SSH_MSG_CHANNEL_DATA)
@@ -1479,9 +1439,8 @@ _libssh2_channel_flush(LIBSSH2_CHANNEL *channel, int streamid)
&& (_libssh2_ntohu32(packet->data + 1) == channel->local.id)) {
/* It's our channel at least */
long packet_stream_id =
(packet_type ==
SSH_MSG_CHANNEL_DATA) ? 0 : _libssh2_ntohu32(packet->data +
5);
(packet_type == SSH_MSG_CHANNEL_DATA) ? 0 :
_libssh2_ntohu32(packet->data + 5);
if ((streamid == LIBSSH2_CHANNEL_FLUSH_ALL)
|| ((packet_type == SSH_MSG_CHANNEL_EXTENDED_DATA)
&& ((streamid == LIBSSH2_CHANNEL_FLUSH_EXTENDED_DATA)
@@ -1501,16 +1460,9 @@ _libssh2_channel_flush(LIBSSH2_CHANNEL *channel, int streamid)
channel->flush_flush_bytes += bytes_to_flush;
LIBSSH2_FREE(channel->session, packet->data);
if (packet->prev) {
packet->prev->next = packet->next;
} else {
channel->session->packets.head = packet->next;
}
if (packet->next) {
packet->next->prev = packet->prev;
} else {
channel->session->packets.tail = packet->prev;
}
/* remove this packet from the parent's list */
_libssh2_list_remove(&packet->node);
LIBSSH2_FREE(channel->session, packet);
}
}
@@ -1526,9 +1478,8 @@ _libssh2_channel_flush(LIBSSH2_CHANNEL *channel, int streamid)
rc = _libssh2_channel_receive_window_adjust(channel,
channel->flush_refund_bytes,
0, NULL);
if (rc == PACKET_EAGAIN) {
return PACKET_EAGAIN;
}
if (rc == PACKET_EAGAIN)
return rc;
}
channel->flush_state = libssh2_NB_state_idle;
@@ -1615,7 +1566,7 @@ _libssh2_channel_receive_window_adjust(LIBSSH2_CHANNEL * channel,
rc = _libssh2_transport_write(channel->session, channel->adjust_adjust, 9);
if (rc == PACKET_EAGAIN) {
return PACKET_EAGAIN;
return rc;
}
else if (rc) {
libssh2_error(channel->session, LIBSSH2_ERROR_SOCKET_SEND,
@@ -1638,6 +1589,8 @@ _libssh2_channel_receive_window_adjust(LIBSSH2_CHANNEL * channel,
/*
* libssh2_channel_receive_window_adjust
*
* DEPRECATED
*
* Adjust the receive window for a channel by adjustment bytes. If the amount
* to be adjusted is less than LIBSSH2_CHANNEL_MINADJUST and force is 0 the
* adjustment amount will be queued for a later packet.
@@ -1701,11 +1654,11 @@ _libssh2_channel_extended_data(LIBSSH2_CHANNEL *channel, int ignore_mode)
if (channel->extData2_state == libssh2_NB_state_idle) {
if (ignore_mode == LIBSSH2_CHANNEL_EXTENDED_DATA_IGNORE) {
if (_libssh2_channel_flush(channel,
LIBSSH2_CHANNEL_FLUSH_EXTENDED_DATA) ==
PACKET_EAGAIN) {
return PACKET_EAGAIN;
}
int rc =
_libssh2_channel_flush(channel,
LIBSSH2_CHANNEL_FLUSH_EXTENDED_DATA);
if(PACKET_EAGAIN == rc)
return rc;
}
}
@@ -1747,7 +1700,7 @@ libssh2_channel_handle_extended_data(LIBSSH2_CHANNEL *channel,
/*
* channel_read
* _libssh2_channel_read
*
* Read data from a channel
*
@@ -1755,14 +1708,16 @@ libssh2_channel_handle_extended_data(LIBSSH2_CHANNEL *channel,
* complete. If we read stuff from the wire but it was no payload data to fill
* in the buffer with, we MUST make sure to return PACKET_EAGAIN.
*/
static ssize_t channel_read(LIBSSH2_CHANNEL *channel, int stream_id,
ssize_t _libssh2_channel_read(LIBSSH2_CHANNEL *channel, int stream_id,
char *buf, size_t buflen)
{
LIBSSH2_SESSION *session = channel->session;
libssh2pack_t rc;
int rc;
int bytes_read = 0;
int bytes_want;
int unlink_packet;
LIBSSH2_PACKET *read_packet;
LIBSSH2_PACKET *read_next;
if (channel->read_state == libssh2_NB_state_idle) {
_libssh2_debug(session, LIBSSH2_DBG_CONN,
@@ -1780,8 +1735,10 @@ static ssize_t channel_read(LIBSSH2_CHANNEL *channel, int stream_id,
while (rc > 0)
rc = _libssh2_transport_read(session);
if ((rc < 0) && (rc != PACKET_EAGAIN))
return -1;
if ((rc < 0) && (rc != PACKET_EAGAIN)) {
libssh2_error(session, rc, "tranport read", 0);
return rc;
}
/*
* =============================== NOTE ===============================
@@ -1792,11 +1749,8 @@ static ssize_t channel_read(LIBSSH2_CHANNEL *channel, int stream_id,
goto channel_read_ex_point1;
}
rc = 0;
channel->read_packet = session->packets.head;
while (channel->read_packet &&
(bytes_read < (int) buflen)) {
read_packet = _libssh2_list_first(&session->packets);
while (read_packet && (bytes_read < (int) buflen)) {
/* previously this loop condition also checked for
!channel->remote.close but we cannot let it do this:
@@ -1805,10 +1759,10 @@ static ssize_t channel_read(LIBSSH2_CHANNEL *channel, int stream_id,
makes us flush buffers prematurely and loose data.
*/
LIBSSH2_PACKET *readpkt = channel->read_packet;
LIBSSH2_PACKET *readpkt = read_packet;
/* In case packet gets destroyed during this iteration */
channel->read_next = readpkt->next;
read_next = _libssh2_list_next(&readpkt->node);
channel->read_local_id =
_libssh2_ntohu32(readpkt->data + 1);
@@ -1859,42 +1813,30 @@ static ssize_t channel_read(LIBSSH2_CHANNEL *channel, int stream_id,
/* if drained, remove from list */
if (unlink_packet) {
if (readpkt->prev) {
readpkt->prev->next = readpkt->next;
} else {
session->packets.head = readpkt->next;
}
if (readpkt->next) {
readpkt->next->prev = readpkt->prev;
} else {
session->packets.tail = readpkt->prev;
}
/* detach readpkt from session->packets list */
_libssh2_list_remove(&readpkt->node);
LIBSSH2_FREE(session, readpkt->data);
LIBSSH2_FREE(session, readpkt);
}
}
/* check the next struct in the chain */
channel->read_packet = channel->read_next;
read_packet = read_next;
}
if (bytes_read == 0) {
if (!bytes_read) {
channel->read_state = libssh2_NB_state_idle;
if (channel->remote.close) {
libssh2_error(session, LIBSSH2_ERROR_CHANNEL_CLOSED,
"Remote end has closed this channel", 0);
/* If the channel is already at EOF or even closed, we need to signal
that back. We may have gotten that info while draining the incoming
transport layer until EAGAIN so we must not be fooled by that
return code. */
if(channel->remote.eof || channel->remote.close)
return 0;
}
else {
/*
* when non-blocking, we must return PACKET_EAGAIN if we haven't
* completed reading the channel
*/
if (!libssh2_channel_eof(channel)) {
return PACKET_EAGAIN;
}
return 0;
}
else
/* if the transport layer said EAGAIN then we say so as well */
return (rc == PACKET_EAGAIN)?rc:0;
}
else
/* make sure we remain in the created state to focus on emptying the
@@ -1911,9 +1853,9 @@ static ssize_t channel_read(LIBSSH2_CHANNEL *channel, int stream_id,
this special state here */
rc = _libssh2_channel_receive_window_adjust(channel,
(LIBSSH2_CHANNEL_WINDOW_DEFAULT*600), 0, NULL);
if (rc == PACKET_EAGAIN) {
return PACKET_EAGAIN;
}
if (rc == PACKET_EAGAIN)
return rc;
_libssh2_debug(session, LIBSSH2_DBG_CONN,
"channel_read() filled %d adjusted %d",
bytes_read, buflen);
@@ -1940,8 +1882,8 @@ libssh2_channel_read_ex(LIBSSH2_CHANNEL *channel, int stream_id, char *buf,
size_t buflen)
{
int rc;
BLOCK_ADJUST(rc, channel->session, channel_read(channel, stream_id,
buf, buflen));
BLOCK_ADJUST(rc, channel->session,
_libssh2_channel_read(channel, stream_id, buf, buflen));
return rc;
}
@@ -1958,9 +1900,9 @@ _libssh2_channel_packet_data_len(LIBSSH2_CHANNEL * channel, int stream_id)
LIBSSH2_PACKET *read_packet;
uint32_t read_local_id;
if ((read_packet = session->packets.head) == NULL) {
read_packet = _libssh2_list_first(&session->packets);
if (read_packet == NULL)
return 0;
}
while (read_packet) {
read_local_id = _libssh2_ntohu32(read_packet->data + 1);
@@ -1989,7 +1931,7 @@ _libssh2_channel_packet_data_len(LIBSSH2_CHANNEL * channel, int stream_id)
{
return (read_packet->data_len - read_packet->data_head);
}
read_packet = read_packet->next;
read_packet = _libssh2_list_next(&read_packet->node);
}
return 0;
@@ -2001,15 +1943,26 @@ _libssh2_channel_packet_data_len(LIBSSH2_CHANNEL * channel, int stream_id)
* Send data to a channel. Note that if this returns EAGAIN or simply didn't
* send the entire packet, the caller must call this function again with the
* SAME input arguments.
*
* Returns: number of bytes sent, or if it returns a negative number, that is
* the error code!
*/
ssize_t
_libssh2_channel_write(LIBSSH2_CHANNEL *channel, int stream_id,
const char *buf, size_t buflen)
{
LIBSSH2_SESSION *session = channel->session;
libssh2pack_t rc;
int rc;
ssize_t wrote = 0; /* counter for this specific this call */
/* In theory we could split larger buffers into several smaller packets,
* but for now we instead only deal with the first 32K in this call and
* assume the app will call it again with the rest! The 32K is a
* conservative limit based on the text in RFC4253 section 6.1.
*/
if(buflen > 32768)
buflen = 32768;
if (channel->write_state == libssh2_NB_state_idle) {
channel->write_bufwrote = 0;
@@ -2021,7 +1974,7 @@ _libssh2_channel_write(LIBSSH2_CHANNEL *channel, int stream_id,
if (channel->local.close) {
libssh2_error(session, LIBSSH2_ERROR_CHANNEL_CLOSED,
"We've already closed this channel", 0);
return -1;
return LIBSSH2_ERROR_CHANNEL_CLOSED;
}
if (channel->local.eof) {
@@ -2039,7 +1992,7 @@ _libssh2_channel_write(LIBSSH2_CHANNEL *channel, int stream_id,
libssh2_error(session, LIBSSH2_ERROR_ALLOC,
"Unable to allocte space for data transmission packet",
0);
return -1;
return LIBSSH2_ERROR_ALLOC;
}
channel->write_state = libssh2_NB_state_allocated;
@@ -2071,11 +2024,6 @@ _libssh2_channel_write(LIBSSH2_CHANNEL *channel, int stream_id,
if(channel->local.window_size <= 0) {
/* there's no more room for data so we stop sending now */
if(!wrote) {
/* if nothing has been written at this point we're at an
EAGAIN point */
return PACKET_EAGAIN;
}
break;
}
@@ -2115,17 +2063,17 @@ _libssh2_channel_write(LIBSSH2_CHANNEL *channel, int stream_id,
channel->write_s -
channel->write_packet);
if (rc == PACKET_EAGAIN) {
_libssh2_debug(session, LIBSSH2_DBG_CONN,
"libssh2_transport_write returned EAGAIN");
return PACKET_EAGAIN;
libssh2_error(session, rc,
"Unable to send channel data", 0);
return rc;
}
else if (rc) {
libssh2_error(session, LIBSSH2_ERROR_SOCKET_SEND,
libssh2_error(session, rc,
"Unable to send channel data", 0);
LIBSSH2_FREE(session, channel->write_packet);
channel->write_packet = NULL;
channel->write_state = libssh2_NB_state_idle;
return -1;
return rc;
}
/* Shrink local window size */
channel->local.window_size -= channel->write_bufwrite;
@@ -2180,12 +2128,12 @@ static int channel_send_eof(LIBSSH2_CHANNEL *channel)
_libssh2_htonu32(packet + 1, channel->remote.id);
rc = _libssh2_transport_write(session, packet, 5);
if (rc == PACKET_EAGAIN) {
return PACKET_EAGAIN;
return rc;
}
else if (rc) {
libssh2_error(session, LIBSSH2_ERROR_SOCKET_SEND,
"Unable to send EOF on channel", 0);
return -1;
return LIBSSH2_ERROR_SOCKET_SEND;
}
channel->local.eof = 1;
@@ -2214,7 +2162,7 @@ LIBSSH2_API int
libssh2_channel_eof(LIBSSH2_CHANNEL * channel)
{
LIBSSH2_SESSION *session = channel->session;
LIBSSH2_PACKET *packet = session->packets.head;
LIBSSH2_PACKET *packet = _libssh2_list_first(&session->packets);
while (packet) {
if (((packet->data[0] == SSH_MSG_CHANNEL_DATA)
@@ -2223,7 +2171,7 @@ libssh2_channel_eof(LIBSSH2_CHANNEL * channel)
/* There's data waiting to be read yet, mask the EOF status */
return 0;
}
packet = packet->next;
packet = _libssh2_list_next(&packet->node);
}
return channel->remote.eof;
@@ -2257,7 +2205,7 @@ static int channel_wait_eof(LIBSSH2_CHANNEL *channel)
}
rc = _libssh2_transport_read(session);
if (rc == PACKET_EAGAIN) {
return PACKET_EAGAIN;
return rc;
}
else if (rc < 0) {
channel->wait_eof_state = libssh2_NB_state_idle;
@@ -2310,12 +2258,12 @@ channel_close(LIBSSH2_CHANNEL * channel)
if (channel->close_state == libssh2_NB_state_created) {
retcode = _libssh2_transport_write(session, channel->close_packet, 5);
if (retcode == PACKET_EAGAIN) {
return PACKET_EAGAIN;
return retcode;
} else if (retcode) {
libssh2_error(session, LIBSSH2_ERROR_SOCKET_SEND,
libssh2_error(session, retcode,
"Unable to send close-channel request", 0);
channel->close_state = libssh2_NB_state_idle;
return -1;
return retcode;
}
channel->close_state = libssh2_NB_state_sent;
@@ -2326,16 +2274,10 @@ channel_close(LIBSSH2_CHANNEL * channel)
while (!channel->remote.close && !rc) {
rc = _libssh2_transport_read(session);
if (rc == PACKET_EAGAIN) {
return PACKET_EAGAIN;
}
else if (rc < 0)
rc = -1;
else
rc = 0;
}
}
if(rc != LIBSSH2_ERROR_EAGAIN) {
/* set the local close state first when we're perfectly confirmed to not
do any more EAGAINs */
channel->local.close = 1;
@@ -2347,8 +2289,10 @@ channel_close(LIBSSH2_CHANNEL * channel)
}
channel->close_state = libssh2_NB_state_idle;
}
return rc;
/* return 0 or an error */
return rc>=0?0:rc;
}
/*
@@ -2397,6 +2341,9 @@ static int channel_wait_closed(LIBSSH2_CHANNEL *channel)
if (!channel->remote.close) {
do {
rc = _libssh2_transport_read(session);
if (channel->remote.close)
/* it is now closed, move on! */
break;
} while (rc > 0);
if(rc < 0)
return rc;
@@ -2450,12 +2397,12 @@ int _libssh2_channel_free(LIBSSH2_CHANNEL *channel)
if (!channel->local.close
&& (session->socket_state == LIBSSH2_SOCKET_CONNECTED)) {
rc = channel_close(channel);
if(rc == PACKET_EAGAIN)
return rc;
if (rc) {
else if (rc < 0) {
channel->free_state = libssh2_NB_state_idle;
return -1;
return rc;
}
}
@@ -2482,17 +2429,8 @@ int _libssh2_channel_free(LIBSSH2_CHANNEL *channel)
LIBSSH2_FREE(session, channel->channel_type);
}
/* Unlink from channel brigade */
if (channel->prev) {
channel->prev->next = channel->next;
} else {
session->channels.head = channel->next;
}
if (channel->next) {
channel->next->prev = channel->prev;
} else {
session->channels.tail = channel->prev;
}
/* Unlink from channel list */
_libssh2_list_remove(&channel->node);
/*
* Make sure all memory used in the state variables are free
@@ -2553,7 +2491,8 @@ libssh2_channel_window_read_ex(LIBSSH2_CHANNEL * channel,
if (read_avail) {
unsigned long bytes_queued = 0;
LIBSSH2_PACKET *packet = channel->session->packets.head;
LIBSSH2_PACKET *packet =
_libssh2_list_first(&channel->session->packets);
while (packet) {
unsigned char packet_type = packet->data[0];
@@ -2564,7 +2503,7 @@ libssh2_channel_window_read_ex(LIBSSH2_CHANNEL * channel,
bytes_queued += packet->data_len - packet->data_head;
}
packet = packet->next;
packet = _libssh2_list_next(&packet->node);
}
*read_avail = bytes_queued;

View File

@@ -104,5 +104,17 @@ _libssh2_channel_process_startup(LIBSSH2_CHANNEL *channel,
const char *request, unsigned int request_len,
const char *message, unsigned int message_len);
/*
* _libssh2_channel_read
*
* Read data from a channel
*
* It is important to not return 0 until the currently read channel is
* complete. If we read stuff from the wire but it was no payload data to fill
* in the buffer with, we MUST make sure to return PACKET_EAGAIN.
*/
ssize_t _libssh2_channel_read(LIBSSH2_CHANNEL *channel, int stream_id,
char *buf, size_t buflen);
#endif /* __LIBSSH2_CHANNEL_H */

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

@@ -114,7 +114,6 @@ hostkey_method_ssh_rsa_initPEM(LIBSSH2_SESSION * session,
void **abstract)
{
libssh2_rsa_ctx *rsactx;
FILE *fp;
int ret;
if (*abstract) {
@@ -122,13 +121,7 @@ hostkey_method_ssh_rsa_initPEM(LIBSSH2_SESSION * session,
*abstract = NULL;
}
fp = fopen(privkeyfile, "r");
if (!fp) {
return -1;
}
ret = _libssh2_rsa_new_private(&rsactx, session, fp, passphrase);
fclose(fp);
ret = _libssh2_rsa_new_private(&rsactx, session, privkeyfile, passphrase);
if (ret) {
return -1;
}
@@ -296,7 +289,6 @@ hostkey_method_ssh_dss_initPEM(LIBSSH2_SESSION * session,
void **abstract)
{
libssh2_dsa_ctx *dsactx;
FILE *fp;
int ret;
if (*abstract) {
@@ -304,13 +296,7 @@ hostkey_method_ssh_dss_initPEM(LIBSSH2_SESSION * session,
*abstract = NULL;
}
fp = fopen(privkeyfile, "r");
if (!fp) {
return -1;
}
ret = _libssh2_dsa_new_private(&dsactx, session, fp, passphrase);
fclose(fp);
ret = _libssh2_dsa_new_private(&dsactx, session, privkeyfile, passphrase);
if (ret) {
return -1;
}

158
src/kex.c
View File

@@ -69,22 +69,20 @@
} \
}
/* kex_method_diffie_hellman_groupGP_sha1_key_exchange
/*
* diffie_hellman_sha1
*
* Diffie Hellman Key Exchange, Group Agnostic
*/
static int
kex_method_diffie_hellman_groupGP_sha1_key_exchange(LIBSSH2_SESSION *session,
_libssh2_bn * g,
_libssh2_bn * p,
static int diffie_hellman_sha1(LIBSSH2_SESSION *session,
_libssh2_bn *g,
_libssh2_bn *p,
int group_order,
unsigned char
packet_type_init,
unsigned char
packet_type_reply,
unsigned char packet_type_init,
unsigned char packet_type_reply,
unsigned char *midhash,
unsigned long midhash_len,
kmdhgGPsha1kex_state_t
* exchange_state)
kmdhgGPsha1kex_state_t *exchange_state)
{
int ret = 0;
int rc;
@@ -122,7 +120,7 @@ kex_method_diffie_hellman_groupGP_sha1_key_exchange(LIBSSH2_SESSION *session,
if (!exchange_state->e_packet) {
libssh2_error(session, LIBSSH2_ERROR_ALLOC, "Out of memory error",
0);
ret = -1;
ret = LIBSSH2_ERROR_ALLOC;
goto clean_exit;
}
exchange_state->e_packet[0] = packet_type_init;
@@ -146,11 +144,11 @@ kex_method_diffie_hellman_groupGP_sha1_key_exchange(LIBSSH2_SESSION *session,
rc = _libssh2_transport_write(session, exchange_state->e_packet,
exchange_state->e_packet_len);
if (rc == PACKET_EAGAIN) {
return PACKET_EAGAIN;
return rc;
} else if (rc) {
libssh2_error(session, LIBSSH2_ERROR_SOCKET_SEND,
libssh2_error(session, rc,
"Unable to send KEX init message", 0);
ret = -1;
ret = rc;
goto clean_exit;
}
exchange_state->state = libssh2_NB_state_sent;
@@ -168,10 +166,10 @@ kex_method_diffie_hellman_groupGP_sha1_key_exchange(LIBSSH2_SESSION *session,
burn_type =
_libssh2_packet_burn(session, &exchange_state->burn_state);
if (burn_type == PACKET_EAGAIN) {
return PACKET_EAGAIN;
return burn_type;
} else if (burn_type <= 0) {
/* Failed to receive a packet */
ret = -1;
ret = burn_type;
goto clean_exit;
}
session->burn_optimistic_kexinit = 0;
@@ -191,12 +189,12 @@ kex_method_diffie_hellman_groupGP_sha1_key_exchange(LIBSSH2_SESSION *session,
&exchange_state->s_packet_len, 0, NULL,
0, &exchange_state->req_state);
if (rc == PACKET_EAGAIN) {
return PACKET_EAGAIN;
return rc;
}
if (rc) {
libssh2_error(session, LIBSSH2_ERROR_TIMEOUT,
"Timed out waiting for KEX reply", 0);
ret = -1;
ret = rc;
goto clean_exit;
}
@@ -211,7 +209,7 @@ kex_method_diffie_hellman_groupGP_sha1_key_exchange(LIBSSH2_SESSION *session,
libssh2_error(session, LIBSSH2_ERROR_ALLOC,
"Unable to allocate memory for a copy of the host key",
0);
ret = -1;
ret = LIBSSH2_ERROR_ALLOC;
goto clean_exit;
}
memcpy(session->server_hostkey, exchange_state->s,
@@ -263,12 +261,12 @@ kex_method_diffie_hellman_groupGP_sha1_key_exchange(LIBSSH2_SESSION *session,
}
#endif /* LIBSSH2DEBUG */
if (session->hostkey->
init(session, session->server_hostkey, session->server_hostkey_len,
if (session->hostkey->init(session, session->server_hostkey,
session->server_hostkey_len,
&session->server_hostkey_abstract)) {
libssh2_error(session, LIBSSH2_ERROR_HOSTKEY_INIT,
"Unable to initialize hostkey importer", 0);
ret = -1;
ret = LIBSSH2_ERROR_HOSTKEY_INIT;
goto clean_exit;
}
@@ -296,7 +294,7 @@ kex_method_diffie_hellman_groupGP_sha1_key_exchange(LIBSSH2_SESSION *session,
if (!exchange_state->k_value) {
libssh2_error(session, LIBSSH2_ERROR_ALLOC,
"Unable to allocate buffer for K", 0);
ret = -1;
ret = LIBSSH2_ERROR_ALLOC;
goto clean_exit;
}
_libssh2_htonu32(exchange_state->k_value,
@@ -421,11 +419,10 @@ kex_method_diffie_hellman_groupGP_sha1_key_exchange(LIBSSH2_SESSION *session,
if (exchange_state->state == libssh2_NB_state_sent2) {
rc = _libssh2_transport_write(session, &exchange_state->c, 1);
if (rc == PACKET_EAGAIN) {
return PACKET_EAGAIN;
return rc;
} else if (rc) {
libssh2_error(session, LIBSSH2_ERROR_SOCKET_SEND,
"Unable to send NEWKEYS message", 0);
ret = -1;
libssh2_error(session, rc, "Unable to send NEWKEYS message", 0);
ret = rc;
goto clean_exit;
}
@@ -438,11 +435,10 @@ kex_method_diffie_hellman_groupGP_sha1_key_exchange(LIBSSH2_SESSION *session,
&exchange_state->tmp_len, 0, NULL, 0,
&exchange_state->req_state);
if (rc == PACKET_EAGAIN) {
return PACKET_EAGAIN;
return rc;
} else if (rc) {
libssh2_error(session, LIBSSH2_ERROR_TIMEOUT,
"Timed out waiting for NEWKEYS", 0);
ret = -1;
libssh2_error(session, rc, "Timed out waiting for NEWKEYS", 0);
ret = rc;
goto clean_exit;
}
/* The first key exchange has been performed,
@@ -457,7 +453,9 @@ kex_method_diffie_hellman_groupGP_sha1_key_exchange(LIBSSH2_SESSION *session,
if (!session->session_id) {
session->session_id = LIBSSH2_ALLOC(session, SHA_DIGEST_LENGTH);
if (!session->session_id) {
ret = -1;
libssh2_error(session, LIBSSH2_ERROR_ALLOC,
"Unable to allocate buffer for SHA digest", 0);
ret = LIBSSH2_ERROR_ALLOC;
goto clean_exit;
}
memcpy(session->session_id, exchange_state->h_sig_comp,
@@ -489,7 +487,7 @@ kex_method_diffie_hellman_groupGP_sha1_key_exchange(LIBSSH2_SESSION *session,
secret_len, "C");
if (!secret) {
LIBSSH2_FREE(session, iv);
ret = -1;
ret = LIBSSH2_ERROR_KEX_FAILURE;
goto clean_exit;
}
if (session->local.crypt->
@@ -497,7 +495,7 @@ kex_method_diffie_hellman_groupGP_sha1_key_exchange(LIBSSH2_SESSION *session,
&free_secret, 1, &session->local.crypt_abstract)) {
LIBSSH2_FREE(session, iv);
LIBSSH2_FREE(session, secret);
ret = -1;
ret = LIBSSH2_ERROR_KEX_FAILURE;
goto clean_exit;
}
@@ -528,7 +526,7 @@ kex_method_diffie_hellman_groupGP_sha1_key_exchange(LIBSSH2_SESSION *session,
session->remote.crypt->
iv_len, "B");
if (!iv) {
ret = -1;
ret = LIBSSH2_ERROR_KEX_FAILURE;
goto clean_exit;
}
LIBSSH2_KEX_METHOD_DIFFIE_HELLMAN_SHA1_HASH(secret,
@@ -536,7 +534,7 @@ kex_method_diffie_hellman_groupGP_sha1_key_exchange(LIBSSH2_SESSION *session,
secret_len, "D");
if (!secret) {
LIBSSH2_FREE(session, iv);
ret = -1;
ret = LIBSSH2_ERROR_KEX_FAILURE;
goto clean_exit;
}
if (session->remote.crypt->
@@ -544,7 +542,7 @@ kex_method_diffie_hellman_groupGP_sha1_key_exchange(LIBSSH2_SESSION *session,
&free_secret, 0, &session->remote.crypt_abstract)) {
LIBSSH2_FREE(session, iv);
LIBSSH2_FREE(session, secret);
ret = -1;
ret = LIBSSH2_ERROR_KEX_FAILURE;
goto clean_exit;
}
@@ -573,7 +571,7 @@ kex_method_diffie_hellman_groupGP_sha1_key_exchange(LIBSSH2_SESSION *session,
session->local.mac->
key_len, "E");
if (!key) {
ret = -1;
ret = LIBSSH2_ERROR_KEX_FAILURE;
goto clean_exit;
}
session->local.mac->init(session, key, &free_key,
@@ -599,7 +597,7 @@ kex_method_diffie_hellman_groupGP_sha1_key_exchange(LIBSSH2_SESSION *session,
session->remote.mac->
key_len, "F");
if (!key) {
ret = -1;
ret = LIBSSH2_ERROR_KEX_FAILURE;
goto clean_exit;
}
session->remote.mac->init(session, key, &free_key,
@@ -691,18 +689,11 @@ kex_method_diffie_hellman_group1_sha1_key_exchange(LIBSSH2_SESSION *session,
key_state->state = libssh2_NB_state_created;
}
ret =
kex_method_diffie_hellman_groupGP_sha1_key_exchange(session,
key_state->g,
key_state->p, 128,
SSH_MSG_KEXDH_INIT,
SSH_MSG_KEXDH_REPLY,
NULL, 0,
&key_state->
exchange_state);
ret = diffie_hellman_sha1(session, key_state->g, key_state->p, 128,
SSH_MSG_KEXDH_INIT, SSH_MSG_KEXDH_REPLY,
NULL, 0, &key_state->exchange_state);
if (ret == PACKET_EAGAIN) {
return PACKET_EAGAIN;
return ret;
}
_libssh2_bn_free(key_state->p);
@@ -774,18 +765,11 @@ kex_method_diffie_hellman_group14_sha1_key_exchange(LIBSSH2_SESSION *session,
key_state->state = libssh2_NB_state_created;
}
ret =
kex_method_diffie_hellman_groupGP_sha1_key_exchange(session,
key_state->g,
key_state->p,
256,
SSH_MSG_KEXDH_INIT,
SSH_MSG_KEXDH_REPLY,
NULL, 0,
&key_state->
exchange_state);
ret = diffie_hellman_sha1(session, key_state->g, key_state->p,
256, SSH_MSG_KEXDH_INIT, SSH_MSG_KEXDH_REPLY,
NULL, 0, &key_state->exchange_state);
if (ret == PACKET_EAGAIN) {
return PACKET_EAGAIN;
return ret;
}
key_state->state = libssh2_NB_state_idle;
@@ -839,11 +823,11 @@ kex_method_diffie_hellman_group_exchange_sha1_key_exchange
rc = _libssh2_transport_write(session, key_state->request,
key_state->request_len);
if (rc == PACKET_EAGAIN) {
return PACKET_EAGAIN;
return rc;
} else if (rc) {
libssh2_error(session, LIBSSH2_ERROR_SOCKET_SEND,
libssh2_error(session, rc,
"Unable to send Group Exchange Request", 0);
ret = -1;
ret = rc;
goto dh_gex_clean_exit;
}
@@ -855,11 +839,11 @@ kex_method_diffie_hellman_group_exchange_sha1_key_exchange
&key_state->data, &key_state->data_len,
0, NULL, 0, &key_state->req_state);
if (rc == PACKET_EAGAIN) {
return PACKET_EAGAIN;
return rc;
} else if (rc) {
libssh2_error(session, LIBSSH2_ERROR_TIMEOUT,
libssh2_error(session, rc,
"Timeout waiting for GEX_GROUP reply", 0);
ret = -1;
ret = rc;
goto dh_gex_clean_exit;
}
@@ -878,14 +862,14 @@ kex_method_diffie_hellman_group_exchange_sha1_key_exchange
_libssh2_bn_from_bin(key_state->g, g_len, s);
s += g_len;
ret =
kex_method_diffie_hellman_groupGP_sha1_key_exchange
(session, key_state->g, key_state->p, p_len,
SSH_MSG_KEX_DH_GEX_INIT, SSH_MSG_KEX_DH_GEX_REPLY,
key_state->data + 1, key_state->data_len - 1,
ret = diffie_hellman_sha1(session, key_state->g, key_state->p, p_len,
SSH_MSG_KEX_DH_GEX_INIT,
SSH_MSG_KEX_DH_GEX_REPLY,
key_state->data + 1,
key_state->data_len - 1,
&key_state->exchange_state);
if (ret == PACKET_EAGAIN) {
return PACKET_EAGAIN;
return ret;
}
LIBSSH2_FREE(session, key_state->data);
@@ -1056,7 +1040,7 @@ static int kexinit(LIBSSH2_SESSION * session)
if (!data) {
libssh2_error(session, LIBSSH2_ERROR_ALLOC,
"Unable to allocate memory", 0);
return -1;
return LIBSSH2_ERROR_ALLOC;
}
*(s++) = SSH_MSG_KEXINIT;
@@ -1139,14 +1123,14 @@ static int kexinit(LIBSSH2_SESSION * session)
if (rc == PACKET_EAGAIN) {
session->kexinit_data = data;
session->kexinit_data_len = data_len;
return PACKET_EAGAIN;
return rc;
}
else if (rc) {
LIBSSH2_FREE(session, data);
libssh2_error(session, LIBSSH2_ERROR_SOCKET_SEND,
libssh2_error(session, rc,
"Unable to send KEXINIT packet to remote host", 0);
session->kexinit_state = libssh2_NB_state_idle;
return -1;
return rc;
}
if (session->local.kexinit) {
@@ -1662,6 +1646,8 @@ static int kex_agree_methods(LIBSSH2_SESSION * session, unsigned char *data,
/* libssh2_kex_exchange
* Exchange keys
* Returns 0 on success, non-zero on failure
*
* Returns some errors without libssh2_error()
*/
int
libssh2_kex_exchange(LIBSSH2_SESSION * session, int reexchange,
@@ -1704,7 +1690,7 @@ libssh2_kex_exchange(LIBSSH2_SESSION * session, int reexchange,
retcode = kexinit(session);
if (retcode == PACKET_EAGAIN) {
session->state &= ~LIBSSH2_STATE_KEX_ACTIVE;
return PACKET_EAGAIN;
return retcode;
} else if (retcode) {
session->local.kexinit = key_state->oldlocal;
session->local.kexinit_len = key_state->oldlocal_len;
@@ -1725,7 +1711,7 @@ libssh2_kex_exchange(LIBSSH2_SESSION * session, int reexchange,
&key_state->req_state);
if (retcode == PACKET_EAGAIN) {
session->state &= ~LIBSSH2_STATE_KEX_ACTIVE;
return PACKET_EAGAIN;
return retcode;
}
else if (retcode) {
if (session->local.kexinit) {
@@ -1746,9 +1732,8 @@ libssh2_kex_exchange(LIBSSH2_SESSION * session, int reexchange,
session->remote.kexinit_len = key_state->data_len;
if (kex_agree_methods(session, key_state->data,
key_state->data_len)) {
rc = -1;
}
key_state->data_len))
rc = LIBSSH2_ERROR_KEX_FAILURE;
key_state->state = libssh2_NB_state_sent2;
}
@@ -1758,16 +1743,15 @@ libssh2_kex_exchange(LIBSSH2_SESSION * session, int reexchange,
if (rc == 0) {
if (key_state->state == libssh2_NB_state_sent2) {
retcode =
session->kex->exchange_keys(session,
retcode = session->kex->exchange_keys(session,
&key_state->key_state_low);
if (retcode == PACKET_EAGAIN) {
session->state &= ~LIBSSH2_STATE_KEX_ACTIVE;
return PACKET_EAGAIN;
return retcode;
} else if (retcode) {
libssh2_error(session, LIBSSH2_ERROR_KEY_EXCHANGE_FAILURE,
"Unrecoverable error exchanging keys", 0);
rc = -1;
rc = retcode;
}
}
}

View File

@@ -1,5 +1,5 @@
/* 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,
@@ -37,6 +37,9 @@
*/
#include "libssh2_priv.h"
#ifdef LIBSSH2_LIBGCRYPT /* compile only if we build with libgcrypt */
#include <string.h>
int
@@ -149,8 +152,9 @@ _libssh2_dsa_new(libssh2_dsa_ctx ** dsactx,
int
_libssh2_rsa_new_private(libssh2_rsa_ctx ** rsa,
LIBSSH2_SESSION * session,
FILE * fp, unsigned const char *passphrase)
const char *filename, unsigned const char *passphrase)
{
FILE *fp;
unsigned char *data, *save_data;
unsigned int datalen;
int ret;
@@ -159,10 +163,16 @@ _libssh2_rsa_new_private(libssh2_rsa_ctx ** rsa,
(void) passphrase;
fp = fopen(filename, "r");
if (!fp) {
return -1;
}
ret = _libssh2_pem_parse(session,
"-----BEGIN RSA PRIVATE KEY-----",
"-----END RSA PRIVATE KEY-----",
fp, &data, &datalen);
fclose(fp);
if (ret) {
return -1;
}
@@ -244,8 +254,9 @@ _libssh2_rsa_new_private(libssh2_rsa_ctx ** rsa,
int
_libssh2_dsa_new_private(libssh2_dsa_ctx ** dsa,
LIBSSH2_SESSION * session,
FILE * fp, unsigned const char *passphrase)
const char *filename, unsigned const char *passphrase)
{
FILE *fp;
unsigned char *data, *save_data;
unsigned int datalen;
int ret;
@@ -254,10 +265,16 @@ _libssh2_dsa_new_private(libssh2_dsa_ctx ** dsa,
(void) passphrase;
fp = fopen(filename, "r");
if (!fp) {
return -1;
}
ret = _libssh2_pem_parse(session,
"-----BEGIN DSA PRIVATE KEY-----",
"-----END DSA PRIVATE KEY-----",
fp, &data, &datalen);
fclose(fp);
if (ret) {
return -1;
}
@@ -507,16 +524,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;
}
@@ -527,8 +542,11 @@ _libssh2_cipher_init(_libssh2_cipher_ctx * h,
return -1;
}
if (algo != GCRY_CIPHER_ARCFOUR) {
int blklen = gcry_cipher_get_algo_blklen(algo);
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);
@@ -544,8 +562,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;
@@ -558,3 +578,5 @@ _libssh2_cipher_crypt(_libssh2_cipher_ctx * ctx,
}
return ret;
}
#endif /* LIBSSH2_LIBGCRYPT */

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
@@ -112,7 +114,8 @@ int _libssh2_rsa_new(libssh2_rsa_ctx ** rsa,
const unsigned char *coeffdata, unsigned long coefflen);
int _libssh2_rsa_new_private(libssh2_rsa_ctx ** rsa,
LIBSSH2_SESSION * session,
FILE * fp, unsigned const char *passphrase);
const char *filename,
unsigned const char *passphrase);
int _libssh2_rsa_sha1_verify(libssh2_rsa_ctx * rsa,
const unsigned char *sig,
unsigned long sig_len,
@@ -140,7 +143,8 @@ int _libssh2_dsa_new(libssh2_dsa_ctx ** dsa,
const unsigned char *x, unsigned long x_len);
int _libssh2_dsa_new_private(libssh2_dsa_ctx ** dsa,
LIBSSH2_SESSION * session,
FILE * fp, unsigned const char *passphrase);
const char *filename,
unsigned const char *passphrase);
int _libssh2_dsa_sha1_verify(libssh2_dsa_ctx * dsa,
const unsigned char *sig,
const unsigned char *m, unsigned long m_len);
@@ -153,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

@@ -85,6 +85,7 @@
#include "libssh2.h"
#include "libssh2_publickey.h"
#include "libssh2_sftp.h"
#include "misc.h" /* for the linked list stuff */
#ifndef FALSE
#define FALSE 0
@@ -96,10 +97,9 @@
/* Provide iovec / writev on WIN32 platform. */
#ifdef WIN32
/* same as WSABUF */
struct iovec {
u_long iov_len;
char *iov_base;
size_t iov_len;
void * iov_base;
};
#define inline __inline
@@ -149,6 +149,12 @@ static inline int writev(int sock, struct iovec *iov, int nvecs)
#endif
#ifdef WIN32
typedef SOCKET libssh2_socket_t;
#else /* !WIN32 */
typedef int libssh2_socket_t;
#endif /* WIN32 */
/* RFC4253 section 6.1 Maximum Packet Length says:
*
* "All implementations MUST be able to process packets with
@@ -187,10 +193,6 @@ typedef struct _LIBSSH2_CRYPT_METHOD LIBSSH2_CRYPT_METHOD;
typedef struct _LIBSSH2_COMP_METHOD LIBSSH2_COMP_METHOD;
typedef struct _LIBSSH2_PACKET LIBSSH2_PACKET;
typedef struct _LIBSSH2_PACKET_BRIGADE LIBSSH2_PACKET_BRIGADE;
typedef struct _LIBSSH2_CHANNEL_BRIGADE LIBSSH2_CHANNEL_BRIGADE;
typedef int libssh2pack_t;
typedef enum
{
@@ -288,6 +290,7 @@ typedef struct packet_queue_listener_state_t
uint32_t sport;
uint32_t host_len;
uint32_t shost_len;
LIBSSH2_CHANNEL *channel;
} packet_queue_listener_state_t;
#define X11FwdUnAvil "X11 Forward Unavailable"
@@ -302,10 +305,13 @@ typedef struct packet_x11_open_state_t
uint32_t packet_size;
uint32_t sport;
uint32_t shost_len;
LIBSSH2_CHANNEL *channel;
} packet_x11_open_state_t;
struct _LIBSSH2_PACKET
{
struct list_node node; /* linked list header */
unsigned char type;
/* Unencrypted Payload (no type byte, no padding, just the facts ma'am) */
@@ -318,15 +324,6 @@ struct _LIBSSH2_PACKET
/* Can the message be confirmed? */
int mac;
LIBSSH2_PACKET_BRIGADE *brigade;
LIBSSH2_PACKET *next, *prev;
};
struct _LIBSSH2_PACKET_BRIGADE
{
LIBSSH2_PACKET *head, *tail;
};
typedef struct _libssh2_channel_data
@@ -343,6 +340,8 @@ typedef struct _libssh2_channel_data
struct _LIBSSH2_CHANNEL
{
struct list_node node;
unsigned char *channel_type;
unsigned channel_type_len;
@@ -355,8 +354,6 @@ struct _LIBSSH2_CHANNEL
LIBSSH2_SESSION *session;
LIBSSH2_CHANNEL *next, *prev;
void *abstract;
LIBSSH2_CHANNEL_CLOSE_FUNC((*close_cb));
@@ -399,8 +396,6 @@ struct _LIBSSH2_CHANNEL
/* State variables used in libssh2_channel_read_ex() */
libssh2_nonblocking_states read_state;
LIBSSH2_PACKET *read_packet;
LIBSSH2_PACKET *read_next;
uint32_t read_local_id;
@@ -429,24 +424,21 @@ struct _LIBSSH2_CHANNEL
libssh2_nonblocking_states extData2_state;
};
struct _LIBSSH2_CHANNEL_BRIGADE
{
LIBSSH2_CHANNEL *head, *tail;
};
struct _LIBSSH2_LISTENER
{
struct list_node node; /* linked list header */
LIBSSH2_SESSION *session;
char *host;
int port;
LIBSSH2_CHANNEL *queue;
/* a list of CHANNELs for this listener */
struct list_head queue;
int queue_size;
int queue_maxsize;
LIBSSH2_LISTENER *prev, *next;
/* State variables used in libssh2_channel_forward_cancel() */
libssh2_nonblocking_states chanFwdCncl_state;
unsigned char *chanFwdCncl_data;
@@ -547,8 +539,9 @@ struct _LIBSSH2_PUBLICKEY
struct _LIBSSH2_SFTP_HANDLE
{
struct list_node node;
LIBSSH2_SFTP *sftp;
LIBSSH2_SFTP_HANDLE *prev, *next;
/* This is a pre-allocated buffer used for sending SFTP requests as the
whole thing might not get sent in one go. This buffer is used for read,
@@ -586,9 +579,10 @@ struct _LIBSSH2_SFTP
unsigned long request_id, version;
LIBSSH2_PACKET_BRIGADE packets;
struct list_head packets;
LIBSSH2_SFTP_HANDLE *handles;
/* a list of _LIBSSH2_SFTP_HANDLE structs */
struct list_head sftp_handles;
unsigned long last_errno;
@@ -713,18 +707,19 @@ struct _LIBSSH2_SESSION
/* (local as source of data -- packet_write ) */
libssh2_endpoint_data local;
/* Inbound Data buffer -- Sometimes the packet that comes in isn't the
/* Inbound Data linked list -- Sometimes the packet that comes in isn't the
packet we're ready for */
LIBSSH2_PACKET_BRIGADE packets;
struct list_head packets;
/* Active connection channels */
LIBSSH2_CHANNEL_BRIGADE channels;
struct list_head channels;
unsigned long next_channel;
LIBSSH2_LISTENER *listeners;
struct list_head listeners; /* list of LIBSSH2_LISTENER structs */
/* Actual I/O socket */
int socket_fd;
libssh2_socket_t socket_fd;
int socket_state;
int socket_block_directions;
int socket_prev_blockstate; /* stores the state of the socket blockiness
@@ -811,7 +806,7 @@ struct _LIBSSH2_SESSION
unsigned char *userauth_pblc_b;
packet_requirev_state_t userauth_pblc_packet_requirev_state;
/* State variables used in llibssh2_userauth_keyboard_interactive_ex() */
/* State variables used in libssh2_userauth_keyboard_interactive_ex() */
libssh2_nonblocking_states userauth_kybd_state;
unsigned char *userauth_kybd_data;
unsigned long userauth_kybd_data_len;
@@ -860,7 +855,6 @@ struct _LIBSSH2_SESSION
/* State variables used in libssh2_packet_add() */
libssh2_nonblocking_states packAdd_state;
LIBSSH2_PACKET *packAdd_packet;
LIBSSH2_CHANNEL *packAdd_channel;
unsigned long packAdd_data_head;
key_exchange_state_t packAdd_key_state;
@@ -871,7 +865,7 @@ struct _LIBSSH2_SESSION
libssh2_nonblocking_states fullpacket_state;
int fullpacket_macstate;
int fullpacket_payload_len;
libssh2pack_t fullpacket_packet_type;
int fullpacket_packet_type;
/* State variables used in libssh2_sftp_init() */
libssh2_nonblocking_states sftpInit_state;
@@ -928,22 +922,6 @@ struct _LIBSSH2_SESSION
#define LIBSSH2_SOCKET_RECV_FLAGS(session) 0
#endif
/* -------- */
/* First take towards a generic linked list handling code for libssh2
internals */
struct list_head {
struct list_node *last;
struct list_node *first;
};
struct list_node {
struct list_node *next;
struct list_node *prev;
struct list_head *head;
};
/* --------- */
/* libssh2 extensible ssh api, ultimately I'd like to allow loading additional
@@ -1161,8 +1139,8 @@ libssh2_uint64_t _libssh2_ntohu64(const unsigned char *buf);
void _libssh2_htonu32(unsigned char *buf, unsigned int val);
#ifdef WIN32
ssize_t _libssh2_recv(int socket, void *buffer, size_t length, int flags);
ssize_t _libssh2_send(int socket, const void *buffer, size_t length, int flags);
ssize_t _libssh2_recv(libssh2_socket_t socket, void *buffer, size_t length, int flags);
ssize_t _libssh2_send(libssh2_socket_t socket, const void *buffer, size_t length, int flags);
#else
#define _libssh2_recv(a,b,c,d) recv(a,b,c,d)
#define _libssh2_send(a,b,c,d) send(a,b,c,d)
@@ -1174,20 +1152,21 @@ ssize_t _libssh2_send(int socket, const void *buffer, size_t length, int flags);
int _libssh2_wait_socket(LIBSSH2_SESSION *session);
/* CAUTION: some of these error codes are returned in the public API and is
there known with other #defined names from the public header file. They
should not be changed. */
/* These started out as private return codes for the transport layer, but was
converted to using the library-wide return codes to easy propagation of the
error reasons all over etc without risking mixups. The PACKET_* names are
left only to reduce the impact of changing the code all over.*/
#define PACKET_TIMEOUT -7
#define PACKET_BADUSE -6
#define PACKET_COMPRESS -5
#define PACKET_TOOBIG -4
#define PACKET_ENOMEM -3
#define PACKET_TIMEOUT LIBSSH2_ERROR_TIMEOUT
#define PACKET_BADUSE LIBSSH2_ERROR_BAD_USE
#define PACKET_COMPRESS LIBSSH2_ERROR_COMPRESS
#define PACKET_TOOBIG LIBSSH2_ERROR_OUT_OF_BOUNDARY
#define PACKET_ENOMEM LIBSSH2_ERROR_ALLOC
#define PACKET_EAGAIN LIBSSH2_ERROR_EAGAIN
#define PACKET_FAIL -1
#define PACKET_NONE 0
#define PACKET_FAIL LIBSSH2_ERROR_SOCKET_NONE
#define PACKET_NONE LIBSSH2_ERROR_NONE
libssh2pack_t _libssh2_packet_read(LIBSSH2_SESSION * session);
int _libssh2_packet_read(LIBSSH2_SESSION * session);
int _libssh2_packet_ask(LIBSSH2_SESSION * session, unsigned char packet_type,
unsigned char **data, unsigned long *data_len,

View File

@@ -78,7 +78,7 @@ static int wsa2errno(void)
* to set errno
*/
ssize_t
_libssh2_recv(int socket, void *buffer, size_t length, int flags)
_libssh2_recv(libssh2_socket_t socket, void *buffer, size_t length, int flags)
{
ssize_t rc = recv(socket, buffer, length, flags);
#ifdef WIN32
@@ -97,7 +97,7 @@ _libssh2_recv(int socket, void *buffer, size_t length, int flags)
* to set errno
*/
ssize_t
_libssh2_send(int socket, const void *buffer, size_t length, int flags)
_libssh2_send(libssh2_socket_t socket, const void *buffer, size_t length, int flags)
{
ssize_t rc = send(socket, buffer, length, flags);
#ifdef WIN32
@@ -426,3 +426,81 @@ void _libssh2_list_remove(struct list_node *entry)
else
entry->head->last = entry->prev;
}
#if 0
/* insert a node before the given 'after' entry */
void _libssh2_list_insert(struct list_node *after, /* insert before this */
struct list_node *entry)
{
/* 'after' is next to 'entry' */
bentry->next = after;
/* entry's prev is then made to be the prev after current has */
entry->prev = after->prev;
/* the node that is now before 'entry' was previously before 'after'
and must be made to point to 'entry' correctly */
if(entry->prev)
entry->prev->next = entry;
/* after's prev entry points back to entry */
after->prev = entry;
/* after's next entry is still the same as before */
/* entry's head is the same as after's */
entry->head = after->head;
}
#endif
#ifdef WIN32
/*
* gettimeofday
* Implementation according to:
* The Open Group Base Specifications Issue 6
* IEEE Std 1003.1, 2004 Edition
*/
/*
* THIS SOFTWARE IS NOT COPYRIGHTED
*
* This source code is offered for use in the public domain. You may
* use, modify or distribute it freely.
*
* This code is distributed in the hope that it will be useful but
* WITHOUT ANY WARRANTY. ALL WARRANTIES, EXPRESS OR IMPLIED ARE HEREBY
* DISCLAIMED. This includes but is not limited to warranties of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
*
* Contributed by:
* Danny Smith <dannysmith@users.sourceforge.net>
*/
/* Offset between 1/1/1601 and 1/1/1970 in 100 nanosec units */
#define _W32_FT_OFFSET (116444736000000000ULL)
int __cdecl gettimeofday(struct timeval *tp,
void *tzp)
{
union {
unsigned long long ns100; /*time since 1 Jan 1601 in 100ns units */
FILETIME ft;
} _now;
if(tp)
{
GetSystemTimeAsFileTime (&_now.ft);
tp->tv_usec=(long)((_now.ns100 / 10ULL) % 1000000ULL );
tp->tv_sec= (long)((_now.ns100 - _W32_FT_OFFSET) / 10000000ULL);
}
/* Always return 0 as per Open Group Base Specifications Issue 6.
Do not set errno on error. */
return 0;
}
#endif

View File

@@ -38,11 +38,20 @@
* OF SUCH DAMAGE.
*/
#include "libssh2_priv.h"
struct list_head {
struct list_node *last;
struct list_node *first;
};
struct list_node {
struct list_node *next;
struct list_node *prev;
struct list_head *head;
};
void _libssh2_list_init(struct list_head *head);
/* add a node first in the list */
/* add a node last in the list */
void _libssh2_list_add(struct list_head *head,
struct list_node *entry);
@@ -58,6 +67,6 @@ void *_libssh2_list_prev(struct list_node *node);
/* remove this node from the list */
void _libssh2_list_remove(struct list_node *entry);
size_t _libssh2_base64_encode(LIBSSH2_SESSION *session,
size_t _libssh2_base64_encode(struct _LIBSSH2_SESSION *session,
const char *inp, size_t insize, char **outptr);
#endif /* _LIBSSH2_MISC_H */

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:
@@ -37,15 +39,15 @@
*/
#include "libssh2_priv.h"
#ifndef LIBSSH2_LIBGCRYPT /* compile only if we build with OpenSSL */
#include <string.h>
#ifndef EVP_MAX_BLOCK_LENGTH
#define EVP_MAX_BLOCK_LENGTH 32
#endif
/* Ridiculously large key-file size cap (512KB) */
#define MAX_KEY_FILE_LENGTH 524288
int
_libssh2_rsa_new(libssh2_rsa_ctx ** rsa,
const unsigned char *edata,
@@ -197,6 +199,106 @@ _libssh2_cipher_crypt(_libssh2_cipher_ctx * ctx,
return ret == 1 ? 0 : 1;
}
#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));
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);
}
/* TODO: Optionally call a passphrase callback specified by the
* calling program
*/
@@ -215,61 +317,21 @@ passphrase_cb(char *buf, int size, int rwflag, char *passphrase)
return passphrase_len;
}
static int
read_file_into_string(char ** key, LIBSSH2_SESSION * session, FILE * fp)
{
long size;
size_t read;
*key = NULL;
fseek(fp, 0, SEEK_END);
size = ftell(fp);
if (size < 0) {
return -1;
}
fseek(fp, 0, SEEK_SET);
size *= sizeof(char);
if (size > MAX_KEY_FILE_LENGTH) {
return -1;
}
*key = LIBSSH2_ALLOC(session, size + 1);
if (!*key) {
return -1;
}
read = fread(*key, 1, size, fp);
if (read != size) {
LIBSSH2_FREE(session, *key);
return -1;
}
(*key)[size] = '\0';
return 0;
}
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,
pem_read_bio_func read_private_key,
FILE * fp, unsigned const char *passphrase)
const char * filename,
unsigned const char *passphrase)
{
char * key;
BIO * bp;
*key_ctx = NULL;
if(read_file_into_string(&key, session, fp)) {
return -1;
}
bp = BIO_new_mem_buf(key, -1);
bp = BIO_new_file(filename, "r");
if (!bp) {
LIBSSH2_FREE(session, key);
return -1;
}
@@ -277,17 +339,17 @@ read_private_key_from_file(void ** key_ctx, LIBSSH2_SESSION * session,
(void *) passphrase);
BIO_free(bp);
LIBSSH2_FREE(session, key);
return (*key_ctx) ? 0 : -1;
}
int
_libssh2_rsa_new_private(libssh2_rsa_ctx ** rsa,
LIBSSH2_SESSION * session,
FILE * fp, unsigned const char *passphrase)
const char *filename, unsigned const char *passphrase)
{
pem_read_bio_func read_rsa =
(pem_read_bio_func) &PEM_read_bio_RSAPrivateKey;
(void) session;
if (!EVP_get_cipherbyname("des")) {
/* If this cipher isn't loaded it's a pretty good indication that none are.
@@ -297,14 +359,14 @@ _libssh2_rsa_new_private(libssh2_rsa_ctx ** rsa,
OpenSSL_add_all_ciphers();
}
return read_private_key_from_file((void **) rsa, session, read_rsa, fp,
passphrase);
return read_private_key_from_file((void **) rsa, session, read_rsa,
filename, passphrase);
}
int
_libssh2_dsa_new_private(libssh2_dsa_ctx ** dsa,
LIBSSH2_SESSION * session,
FILE * fp, unsigned const char *passphrase)
const char *filename, unsigned const char *passphrase)
{
pem_read_bio_func read_dsa =
(pem_read_bio_func) &PEM_read_bio_DSAPrivateKey;
@@ -317,8 +379,8 @@ _libssh2_dsa_new_private(libssh2_dsa_ctx ** dsa,
OpenSSL_add_all_ciphers();
}
return read_private_key_from_file((void **) dsa, session, read_dsa, fp,
passphrase);
return read_private_key_from_file((void **) dsa, session, read_dsa,
filename, passphrase);
}
int
@@ -381,3 +443,5 @@ _libssh2_dsa_sha1_sign(libssh2_dsa_ctx * dsactx,
return 0;
}
#endif /* !LIBSSH2_LIBGCRYPT */

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
@@ -148,7 +151,8 @@ int _libssh2_rsa_new(libssh2_rsa_ctx ** rsa,
const unsigned char *coeffdata, unsigned long coefflen);
int _libssh2_rsa_new_private(libssh2_rsa_ctx ** rsa,
LIBSSH2_SESSION * session,
FILE * fp, unsigned const char *passphrase);
const char *filename,
unsigned const char *passphrase);
int _libssh2_rsa_sha1_verify(libssh2_rsa_ctx * rsa,
const unsigned char *sig,
unsigned long sig_len,
@@ -176,7 +180,8 @@ int _libssh2_dsa_new(libssh2_dsa_ctx ** dsa,
const unsigned char *x, unsigned long x_len);
int _libssh2_dsa_new_private(libssh2_dsa_ctx ** dsa,
LIBSSH2_SESSION * session,
FILE * fp, unsigned const char *passphrase);
const char *filename,
unsigned const char *passphrase);
int _libssh2_dsa_sha1_verify(libssh2_dsa_ctx * dsactx,
const unsigned char *sig,
const unsigned char *m, unsigned long m_len);
@@ -192,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
@@ -221,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

@@ -60,6 +60,7 @@
#include <sys/types.h>
#include "transport.h"
#include "channel.h"
/*
* libssh2_packet_queue_listener
@@ -69,7 +70,7 @@
static inline int
packet_queue_listener(LIBSSH2_SESSION * session, unsigned char *data,
unsigned long datalen,
packet_queue_listener_state_t * listen_state)
packet_queue_listener_state_t *listen_state)
{
/*
* Look for a matching listener
@@ -78,7 +79,7 @@ packet_queue_listener(LIBSSH2_SESSION * session, unsigned char *data,
/* 17 = packet_type(1) + channel(4) + reason(4) + descr(4) + lang(4) */
unsigned long packet_len = 17 + (sizeof(FwdNotReq) - 1);
unsigned char *p;
LIBSSH2_LISTENER *listen = session->listeners;
LIBSSH2_LISTENER *listen = _libssh2_list_first(&session->listeners);
char failure_code = 1; /* SSH_OPEN_ADMINISTRATIVELY_PROHIBITED */
int rc;
@@ -119,13 +120,12 @@ packet_queue_listener(LIBSSH2_SESSION * session, unsigned char *data,
while (listen) {
if ((listen->port == (int) listen_state->port) &&
(strlen(listen->host) == listen_state->host_len) &&
(memcmp
(listen->host, listen_state->host,
(memcmp (listen->host, listen_state->host,
listen_state->host_len) == 0)) {
/* This is our listener */
LIBSSH2_CHANNEL *channel = NULL, *last_queued = listen->queue;
LIBSSH2_CHANNEL *channel = NULL;
listen_state->channel = NULL;
last_queued = listen->queue;
if (listen_state->state == libssh2_NB_state_allocated) {
if (listen->queue_maxsize &&
(listen->queue_maxsize <= listen->queue_size)) {
@@ -146,6 +146,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;
@@ -206,31 +208,19 @@ packet_queue_listener(LIBSSH2_SESSION * session, unsigned char *data,
if (listen_state->state == libssh2_NB_state_created) {
rc = _libssh2_transport_write(session, listen_state->packet,
17);
if (rc == PACKET_EAGAIN) {
return PACKET_EAGAIN;
} else if (rc) {
libssh2_error(session, LIBSSH2_ERROR_SOCKET_SEND,
"Unable to send channel open confirmation",
0);
if (rc == PACKET_EAGAIN)
return rc;
else if (rc) {
libssh2_error(session, rc,
"Unable to send channel "
"open confirmation", 0);
listen_state->state = libssh2_NB_state_idle;
return -1;
return rc;
}
/* Link the channel into the end of the queue list */
if (!last_queued) {
listen->queue = channel;
listen_state->state = libssh2_NB_state_idle;
return 0;
}
while (last_queued->next) {
last_queued = last_queued->next;
}
last_queued->next = channel;
channel->prev = last_queued;
_libssh2_list_add(&listen->queue,
&listen_state->channel->node);
listen->queue_size++;
listen_state->state = libssh2_NB_state_idle;
@@ -238,14 +228,13 @@ packet_queue_listener(LIBSSH2_SESSION * session, unsigned char *data,
}
}
listen = listen->next;
listen = _libssh2_list_next(&listen->node);
}
listen_state->state = libssh2_NB_state_sent;
}
/* We're not listening to you */
{
p = listen_state->packet;
*(p++) = SSH_MSG_CHANNEL_OPEN_FAILURE;
_libssh2_htonu32(p, listen_state->sender_channel);
@@ -261,16 +250,14 @@ packet_queue_listener(LIBSSH2_SESSION * session, unsigned char *data,
rc = _libssh2_transport_write(session, listen_state->packet,
packet_len);
if (rc == PACKET_EAGAIN) {
return PACKET_EAGAIN;
return rc;
} else if (rc) {
libssh2_error(session, LIBSSH2_ERROR_SOCKET_SEND,
"Unable to send open failure", 0);
libssh2_error(session, rc, "Unable to send open failure", 0);
listen_state->state = libssh2_NB_state_idle;
return -1;
return rc;
}
listen_state->state = libssh2_NB_state_idle;
return 0;
}
}
/*
@@ -281,14 +268,14 @@ packet_queue_listener(LIBSSH2_SESSION * session, unsigned char *data,
static inline int
packet_x11_open(LIBSSH2_SESSION * session, unsigned char *data,
unsigned long datalen,
packet_x11_open_state_t * x11open_state)
packet_x11_open_state_t *x11open_state)
{
int failure_code = 2; /* SSH_OPEN_CONNECT_FAILED */
unsigned char *s = data + (sizeof("x11") - 1) + 5;
/* 17 = packet_type(1) + channel(4) + reason(4) + descr(4) + lang(4) */
unsigned long packet_len = 17 + (sizeof(X11FwdUnAvil) - 1);
unsigned char *p;
LIBSSH2_CHANNEL *channel = NULL;
LIBSSH2_CHANNEL *channel = x11open_state->channel;
int rc;
(void) datalen;
@@ -379,7 +366,7 @@ packet_x11_open(LIBSSH2_SESSION * session, unsigned char *data,
if (x11open_state->state == libssh2_NB_state_created) {
rc = _libssh2_transport_write(session, x11open_state->packet, 17);
if (rc == PACKET_EAGAIN) {
return PACKET_EAGAIN;
return rc;
} else if (rc) {
libssh2_error(session, LIBSSH2_ERROR_SOCKET_SEND,
"Unable to send channel open confirmation", 0);
@@ -388,21 +375,13 @@ packet_x11_open(LIBSSH2_SESSION * session, unsigned char *data,
}
/* Link the channel into the session */
if (session->channels.tail) {
session->channels.tail->next = channel;
channel->prev = session->channels.tail;
} else {
session->channels.head = channel;
channel->prev = NULL;
}
channel->next = NULL;
session->channels.tail = channel;
_libssh2_list_add(&session->channels, &channel->node);
/*
* Pass control to the callback, they may turn right around and
* free the channel, or actually use it
*/
LIBSSH2_X11_OPEN(channel, (char *) x11open_state->shost,
LIBSSH2_X11_OPEN(channel, (char *)x11open_state->shost,
x11open_state->sport);
x11open_state->state = libssh2_NB_state_idle;
@@ -427,12 +406,11 @@ packet_x11_open(LIBSSH2_SESSION * session, unsigned char *data,
rc = _libssh2_transport_write(session, x11open_state->packet, packet_len);
if (rc == PACKET_EAGAIN) {
return PACKET_EAGAIN;
return rc;
} else if (rc) {
libssh2_error(session, LIBSSH2_ERROR_SOCKET_SEND,
"Unable to send open failure", 0);
libssh2_error(session, rc, "Unable to send open failure", 0);
x11open_state->state = libssh2_NB_state_idle;
return -1;
return rc;
}
x11open_state->state = libssh2_NB_state_idle;
return 0;
@@ -443,6 +421,9 @@ packet_x11_open(LIBSSH2_SESSION * session, unsigned char *data,
*
* Create a new packet and attach it to the brigade. Called from the transport
* layer when it as 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.
*/
int
_libssh2_packet_add(LIBSSH2_SESSION * session, unsigned char *data,
@@ -469,8 +450,8 @@ _libssh2_packet_add(LIBSSH2_SESSION * session, unsigned char *data,
"Packet type %d received, length=%d",
(int) data[0], (int) datalen);
if (macstate == LIBSSH2_MAC_INVALID) {
if (session->macerror) {
if (LIBSSH2_MACERROR(session, (char *) data, datalen) == 0) {
if (session->macerror &&
LIBSSH2_MACERROR(session, (char *) data, datalen) == 0) {
/* Calling app has given the OK, Process it anyway */
macstate = LIBSSH2_MAC_CONFIRMED;
} else {
@@ -484,20 +465,7 @@ _libssh2_packet_add(LIBSSH2_SESSION * session, unsigned char *data,
"", 0);
}
LIBSSH2_FREE(session, data);
return -1;
}
} else {
libssh2_error(session, LIBSSH2_ERROR_INVALID_MAC,
"Invalid Message Authentication Code received",
0);
if (session->ssh_msg_disconnect) {
LIBSSH2_DISCONNECT(session, SSH_DISCONNECT_MAC_ERROR,
"Invalid MAC received",
sizeof("Invalid MAC received") - 1,
"", 0);
}
LIBSSH2_FREE(session, data);
return -1;
return LIBSSH2_ERROR_INVALID_MAC;
}
}
@@ -544,7 +512,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';
@@ -558,21 +526,26 @@ _libssh2_packet_add(LIBSSH2_SESSION * session, unsigned char *data,
LIBSSH2_FREE(session, data);
session->socket_state = LIBSSH2_SOCKET_DISCONNECTED;
session->packAdd_state = libssh2_NB_state_idle;
return -1;
libssh2_error(session, LIBSSH2_ERROR_SOCKET_DISCONNECT,
"socket disconnect", 0);
return LIBSSH2_ERROR_SOCKET_DISCONNECT;
}
break;
case SSH_MSG_IGNORE:
/* As with disconnect, back it up one and add a trailing NULL */
memcpy(data + 4, data + 5, 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 - 5);
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;
return 0;
break;
case SSH_MSG_DEBUG:
{
@@ -598,7 +571,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';
@@ -663,15 +636,13 @@ _libssh2_packet_add(LIBSSH2_SESSION * session, unsigned char *data,
/* Adjust the window based on the block we just freed */
libssh2_packet_add_jump_point1:
session->packAdd_state = libssh2_NB_state_jump1;
rc = libssh2_channel_receive_window_adjust(session->
rc = _libssh2_channel_receive_window_adjust(session->
packAdd_channel,
datalen - 13,
0);
if (rc == PACKET_EAGAIN) {
session->socket_block_directions =
LIBSSH2_SESSION_BLOCK_OUTBOUND;
return PACKET_EAGAIN;
}
0, NULL);
if (rc == PACKET_EAGAIN)
return rc;
session->packAdd_state = libssh2_NB_state_idle;
return 0;
}
@@ -731,7 +702,6 @@ _libssh2_packet_add(LIBSSH2_SESSION * session, unsigned char *data,
break;
case SSH_MSG_CHANNEL_EOF:
{
session->packAdd_channel =
_libssh2_channel_locate(session, _libssh2_ntohu32(data + 1));
@@ -752,11 +722,8 @@ _libssh2_packet_add(LIBSSH2_SESSION * session, unsigned char *data,
LIBSSH2_FREE(session, data);
session->packAdd_state = libssh2_NB_state_idle;
return 0;
}
break;
case SSH_MSG_CHANNEL_REQUEST:
{
if (_libssh2_ntohu32(data + 5) == sizeof("exit-status") - 1
&& !memcmp("exit-status", data + 9,
sizeof("exit-status") - 1)) {
@@ -780,11 +747,9 @@ _libssh2_packet_add(LIBSSH2_SESSION * session, unsigned char *data,
session->packAdd_state = libssh2_NB_state_idle;
return 0;
}
}
break;
case SSH_MSG_CHANNEL_CLOSE:
{
session->packAdd_channel =
_libssh2_channel_locate(session, _libssh2_ntohu32(data + 1));
@@ -801,31 +766,24 @@ _libssh2_packet_add(LIBSSH2_SESSION * session, unsigned char *data,
session->packAdd_channel->remote.close = 1;
session->packAdd_channel->remote.eof = 1;
/* TODO: Add a callback for this */
LIBSSH2_FREE(session, data);
session->packAdd_state = libssh2_NB_state_idle;
return 0;
}
break;
case SSH_MSG_CHANNEL_OPEN:
if ((datalen >= (sizeof("forwarded-tcpip") + 4)) &&
((sizeof("forwarded-tcpip") - 1) == _libssh2_ntohu32(data + 1))
&&
(memcmp
(data + 5, "forwarded-tcpip",
(memcmp(data + 5, "forwarded-tcpip",
sizeof("forwarded-tcpip") - 1) == 0)) {
libssh2_packet_add_jump_point2:
session->packAdd_state = libssh2_NB_state_jump2;
rc = packet_queue_listener(session, data, datalen,
&session->packAdd_Qlstn_state);
if (rc == PACKET_EAGAIN) {
session->socket_block_directions =
LIBSSH2_SESSION_BLOCK_OUTBOUND;
return PACKET_EAGAIN;
}
if (rc == PACKET_EAGAIN)
return rc;
LIBSSH2_FREE(session, data);
session->packAdd_state = libssh2_NB_state_idle;
@@ -839,11 +797,8 @@ _libssh2_packet_add(LIBSSH2_SESSION * session, unsigned char *data,
session->packAdd_state = libssh2_NB_state_jump3;
rc = packet_x11_open(session, data, datalen,
&session->packAdd_x11open_state);
if (rc == PACKET_EAGAIN) {
session->socket_block_directions =
LIBSSH2_SESSION_BLOCK_OUTBOUND;
return PACKET_EAGAIN;
}
if (rc == PACKET_EAGAIN)
return rc;
LIBSSH2_FREE(session, data);
session->packAdd_state = libssh2_NB_state_idle;
@@ -879,33 +834,23 @@ _libssh2_packet_add(LIBSSH2_SESSION * session, unsigned char *data,
}
if (session->packAdd_state == libssh2_NB_state_sent) {
session->packAdd_packet =
LIBSSH2_PACKET *packAdd_packet;
packAdd_packet =
LIBSSH2_ALLOC(session, sizeof(LIBSSH2_PACKET));
if (!session->packAdd_packet) {
if (!packAdd_packet) {
_libssh2_debug(session, LIBSSH2_ERROR_ALLOC,
"Unable to allocate memory for LIBSSH2_PACKET");
LIBSSH2_FREE(session, data);
session->packAdd_state = libssh2_NB_state_idle;
return -1;
}
memset(session->packAdd_packet, 0, sizeof(LIBSSH2_PACKET));
memset(packAdd_packet, 0, sizeof(LIBSSH2_PACKET));
session->packAdd_packet->data = data;
session->packAdd_packet->data_len = datalen;
session->packAdd_packet->data_head = session->packAdd_data_head;
session->packAdd_packet->mac = macstate;
session->packAdd_packet->brigade = &session->packets;
session->packAdd_packet->next = NULL;
packAdd_packet->data = data;
packAdd_packet->data_len = datalen;
packAdd_packet->data_head = session->packAdd_data_head;
packAdd_packet->mac = macstate;
if (session->packets.tail) {
session->packAdd_packet->prev = session->packets.tail;
session->packAdd_packet->prev->next = session->packAdd_packet;
session->packets.tail = session->packAdd_packet;
} else {
session->packets.head = session->packAdd_packet;
session->packets.tail = session->packAdd_packet;
session->packAdd_packet->prev = NULL;
}
_libssh2_list_add(&session->packets, &packAdd_packet->node);
session->packAdd_state = libssh2_NB_state_sent1;
}
@@ -948,7 +893,7 @@ _libssh2_packet_add(LIBSSH2_SESSION * session, unsigned char *data,
*/
rc = libssh2_kex_exchange(session, 1, &session->startup_key_state);
if (rc == PACKET_EAGAIN) {
return PACKET_EAGAIN;
return rc;
}
}
@@ -968,7 +913,7 @@ _libssh2_packet_ask(LIBSSH2_SESSION * session, unsigned char packet_type,
unsigned long match_ofs, const unsigned char *match_buf,
unsigned long match_len)
{
LIBSSH2_PACKET *packet = session->packets.head;
LIBSSH2_PACKET *packet = _libssh2_list_first(&session->packets);
_libssh2_debug(session, LIBSSH2_DBG_TRANS,
"Looking for packet of type: %d", (int) packet_type);
@@ -982,24 +927,14 @@ _libssh2_packet_ask(LIBSSH2_SESSION * session, unsigned char packet_type,
*data = packet->data;
*data_len = packet->data_len;
/* unlink struct */
if (packet->prev) {
packet->prev->next = packet->next;
} else {
session->packets.head = packet->next;
}
if (packet->next) {
packet->next->prev = packet->prev;
} else {
session->packets.tail = packet->prev;
}
/* unlink struct from session->packets */
_libssh2_list_remove(&packet->node);
LIBSSH2_FREE(session, packet);
return 0;
}
packet = packet->next;
packet = _libssh2_list_next(&packet->node);
}
return -1;
}
@@ -1060,13 +995,10 @@ _libssh2_packet_require(LIBSSH2_SESSION * session, unsigned char packet_type,
}
while (session->socket_state == LIBSSH2_SOCKET_CONNECTED) {
libssh2pack_t ret = _libssh2_transport_read(session);
if (ret == PACKET_EAGAIN) {
return PACKET_EAGAIN;
} else if (ret == 0) {
/* There is no data, return that. TODO: is this really correct? */
return PACKET_EAGAIN;
} else if (ret < 0) {
int ret = _libssh2_transport_read(session);
if (ret == PACKET_EAGAIN)
return ret;
else if (ret < 0) {
state->start = 0;
/* an error which is not just because of blocking */
return ret;
@@ -1084,11 +1016,12 @@ _libssh2_packet_require(LIBSSH2_SESSION * session, unsigned char packet_type,
state->start = 0;
return PACKET_TIMEOUT;
}
return -1; /* no packet available yet */
}
}
/* Only reached if the socket died */
return -1;
return LIBSSH2_ERROR_SOCKET_DISCONNECT;
}
/*
@@ -1127,8 +1060,9 @@ _libssh2_packet_burn(LIBSSH2_SESSION * session,
}
while (session->socket_state == LIBSSH2_SOCKET_CONNECTED) {
if ((ret = _libssh2_transport_read(session)) == PACKET_EAGAIN) {
return PACKET_EAGAIN;
ret = _libssh2_transport_read(session);
if (ret == PACKET_EAGAIN) {
return ret;
} else if (ret < 0) {
*state = libssh2_NB_state_idle;
return ret;
@@ -1148,7 +1082,7 @@ _libssh2_packet_burn(LIBSSH2_SESSION * session,
}
/* Only reached if the socket died */
return -1;
return LIBSSH2_ERROR_SOCKET_DISCONNECT;
}
/*
@@ -1194,7 +1128,7 @@ _libssh2_packet_requirev(LIBSSH2_SESSION * session,
return PACKET_TIMEOUT;
}
else if (ret == PACKET_EAGAIN) {
return PACKET_EAGAIN;
return ret;
}
}
@@ -1208,6 +1142,6 @@ _libssh2_packet_requirev(LIBSSH2_SESSION * session,
/* Only reached if the socket died */
state->start = 0;
return -1;
return LIBSSH2_ERROR_SOCKET_DISCONNECT;
}

View File

@@ -38,6 +38,8 @@
#include "libssh2_priv.h"
#ifdef LIBSSH2_LIBGCRYPT /* compile only if we build with libgcrypt */
static int
readline(char *line, int line_size, FILE * fp)
{
@@ -207,3 +209,5 @@ _libssh2_pem_decode_integer(unsigned char **data, unsigned int *datalen,
return 0;
}
#endif /* LIBSSH2_LIBGCRYPT */

View File

@@ -37,6 +37,7 @@
#include "libssh2_priv.h"
#include "libssh2_publickey.h"
#include "channel.h"
#define LIBSSH2_PUBLICKEY_VERSION 2
@@ -168,9 +169,9 @@ publickey_packet_receive(LIBSSH2_PUBLICKEY * pkey,
int rc;
if (pkey->receive_state == libssh2_NB_state_idle) {
rc = libssh2_channel_read_ex(channel, 0, (char *) buffer, 4);
rc = _libssh2_channel_read(channel, 0, (char *) buffer, 4);
if (rc == PACKET_EAGAIN) {
return PACKET_EAGAIN;
return rc;
} else if (rc != 4) {
libssh2_error(session, LIBSSH2_ERROR_PUBLICKEY_PROTOCOL,
"Invalid response from publickey subsystem", 0);
@@ -190,10 +191,10 @@ publickey_packet_receive(LIBSSH2_PUBLICKEY * pkey,
}
if (pkey->receive_state == libssh2_NB_state_sent) {
rc = libssh2_channel_read_ex(channel, 0, (char *) pkey->receive_packet,
rc = _libssh2_channel_read(channel, 0, (char *) pkey->receive_packet,
pkey->receive_packet_len);
if (rc == PACKET_EAGAIN) {
return PACKET_EAGAIN;
return rc;
} else if (rc != (int)pkey->receive_packet_len) {
libssh2_error(session, LIBSSH2_ERROR_SOCKET_TIMEOUT,
"Timeout waiting for publickey subsystem response packet",
@@ -265,7 +266,7 @@ publickey_response_success(LIBSSH2_PUBLICKEY * pkey)
while (1) {
rc = publickey_packet_receive(pkey, &data, &data_len);
if (rc == PACKET_EAGAIN) {
return PACKET_EAGAIN;
return rc;
} else if (rc) {
libssh2_error(session, LIBSSH2_ERROR_SOCKET_TIMEOUT,
"Timeout waiting for response from publickey subsystem",
@@ -441,7 +442,7 @@ libssh2_publickey_init(LIBSSH2_SESSION * session)
}
if (session->pkeyInit_state == libssh2_NB_state_sent2) {
rc = libssh2_channel_write_ex(session->pkeyInit_channel, 0,
rc = _libssh2_channel_write(session->pkeyInit_channel, 0,
(char *) buffer, (s - buffer));
if (rc == PACKET_EAGAIN) {
libssh2_error(session, LIBSSH2_ERROR_EAGAIN,
@@ -678,10 +679,10 @@ libssh2_publickey_add_ex(LIBSSH2_PUBLICKEY * pkey, const unsigned char *name,
}
if (pkey->add_state == libssh2_NB_state_created) {
rc = libssh2_channel_write_ex(channel, 0, (char *) pkey->add_packet,
rc = _libssh2_channel_write(channel, 0, (char *) pkey->add_packet,
(pkey->add_s - pkey->add_packet));
if (rc == PACKET_EAGAIN) {
return PACKET_EAGAIN;
return rc;
} else if ((pkey->add_s - pkey->add_packet) != rc) {
libssh2_error(session, LIBSSH2_ERROR_SOCKET_SEND,
"Unable to send publickey add packet", 0);
@@ -697,7 +698,7 @@ libssh2_publickey_add_ex(LIBSSH2_PUBLICKEY * pkey, const unsigned char *name,
rc = publickey_response_success(pkey);
if (rc == PACKET_EAGAIN) {
return PACKET_EAGAIN;
return rc;
}
pkey->add_state = libssh2_NB_state_idle;
@@ -754,10 +755,10 @@ libssh2_publickey_remove_ex(LIBSSH2_PUBLICKEY * pkey,
}
if (pkey->remove_state == libssh2_NB_state_created) {
rc = libssh2_channel_write_ex(channel, 0, (char *) pkey->remove_packet,
rc = _libssh2_channel_write(channel, 0, (char *) pkey->remove_packet,
(pkey->remove_s - pkey->remove_packet));
if (rc == PACKET_EAGAIN) {
return PACKET_EAGAIN;
return rc;
} else if ((pkey->remove_s - pkey->remove_packet) != rc) {
libssh2_error(session, LIBSSH2_ERROR_SOCKET_SEND,
"Unable to send publickey remove packet", 0);
@@ -774,7 +775,7 @@ libssh2_publickey_remove_ex(LIBSSH2_PUBLICKEY * pkey,
rc = publickey_response_success(pkey);
if (rc == PACKET_EAGAIN) {
return PACKET_EAGAIN;
return rc;
}
pkey->remove_state = libssh2_NB_state_idle;
@@ -815,12 +816,12 @@ libssh2_publickey_list_fetch(LIBSSH2_PUBLICKEY * pkey, unsigned long *num_keys,
}
if (pkey->listFetch_state == libssh2_NB_state_created) {
rc = libssh2_channel_write_ex(channel, 0,
rc = _libssh2_channel_write(channel, 0,
(char *) pkey->listFetch_buffer,
(pkey->listFetch_s -
pkey->listFetch_buffer));
if (rc == PACKET_EAGAIN) {
return PACKET_EAGAIN;
return rc;
} else if ((pkey->listFetch_s - pkey->listFetch_buffer) != rc) {
libssh2_error(session, LIBSSH2_ERROR_SOCKET_SEND,
"Unable to send publickey list packet", 0);
@@ -835,7 +836,7 @@ libssh2_publickey_list_fetch(LIBSSH2_PUBLICKEY * pkey, unsigned long *num_keys,
rc = publickey_packet_receive(pkey, &pkey->listFetch_data,
&pkey->listFetch_data_len);
if (rc == PACKET_EAGAIN) {
return PACKET_EAGAIN;
return rc;
} else if (rc) {
libssh2_error(session, LIBSSH2_ERROR_SOCKET_TIMEOUT,
"Timeout waiting for response from publickey subsystem",
@@ -1040,6 +1041,7 @@ LIBSSH2_API int
libssh2_publickey_shutdown(LIBSSH2_PUBLICKEY * pkey)
{
LIBSSH2_SESSION *session = pkey->channel->session;
int rc;
/*
* Make sure all memory used in the state variables are free
@@ -1061,9 +1063,9 @@ libssh2_publickey_shutdown(LIBSSH2_PUBLICKEY * pkey)
pkey->listFetch_data = NULL;
}
if (libssh2_channel_free(pkey->channel) == PACKET_EAGAIN) {
return PACKET_EAGAIN;
}
rc = libssh2_channel_free(pkey->channel);
if (rc == PACKET_EAGAIN)
return rc;
LIBSSH2_FREE(session, pkey);
return 0;

View File

@@ -1,4 +1,5 @@
/* Copyright (c) 2004-2008, Sara Golemon <sarag@libssh2.org>
/* Copyright (c) 2009 by Daniel Stenberg
* Copyright (c) 2004-2008, Sara Golemon <sarag@libssh2.org>
* All rights reserved.
*
* Redistribution and use in source and binary forms,
@@ -39,6 +40,8 @@
#include <errno.h>
#include <stdlib.h>
#include "channel.h"
/* Max. length of a quoted string after libssh2_shell_quotearg() processing */
#define libssh2_shell_quotedsize(s) (3 * strlen(s) + 2)
@@ -258,13 +261,13 @@ libssh2_shell_quotearg(const char *path, unsigned char *buf,
}
/*
* libssh2_scp_recv
* scp_recv
*
* Open a channel and request a remote file via SCP
*
*/
LIBSSH2_API LIBSSH2_CHANNEL *
libssh2_scp_recv(LIBSSH2_SESSION * session, const char *path, struct stat * sb)
static LIBSSH2_CHANNEL *
scp_recv(LIBSSH2_SESSION * session, const char *path, struct stat * sb)
{
int cmd_len;
int rc;
@@ -355,7 +358,7 @@ libssh2_scp_recv(LIBSSH2_SESSION * session, const char *path, struct stat * sb)
}
if (session->scpRecv_state == libssh2_NB_state_sent1) {
rc = libssh2_channel_write_ex(session->scpRecv_channel, 0,
rc = _libssh2_channel_write(session->scpRecv_channel, 0,
(char *) session->scpRecv_response, 1);
if (rc == PACKET_EAGAIN) {
libssh2_error(session, LIBSSH2_ERROR_EAGAIN,
@@ -378,7 +381,7 @@ libssh2_scp_recv(LIBSSH2_SESSION * session, const char *path, struct stat * sb)
unsigned char *s, *p;
if (session->scpRecv_state == libssh2_NB_state_sent2) {
rc = libssh2_channel_read_ex(session->scpRecv_channel, 0,
rc = _libssh2_channel_read(session->scpRecv_channel, 0,
(char *) session->
scpRecv_response +
session->scpRecv_response_len, 1);
@@ -415,7 +418,7 @@ libssh2_scp_recv(LIBSSH2_SESSION * session, const char *path, struct stat * sb)
session->scpRecv_err_len + 1);
/* Read the remote error message */
rc = libssh2_channel_read_ex(session->scpRecv_channel, 0,
rc = _libssh2_channel_read(session->scpRecv_channel, 0,
session->scpRecv_err_msg,
session->scpRecv_err_len);
if (rc <= 0) {
@@ -555,7 +558,7 @@ libssh2_scp_recv(LIBSSH2_SESSION * session, const char *path, struct stat * sb)
}
if (session->scpRecv_state == libssh2_NB_state_sent3) {
rc = libssh2_channel_write_ex(session->scpRecv_channel, 0,
rc = _libssh2_channel_write(session->scpRecv_channel, 0,
(char *) session->
scpRecv_response, 1);
if (rc == PACKET_EAGAIN) {
@@ -591,7 +594,7 @@ libssh2_scp_recv(LIBSSH2_SESSION * session, const char *path, struct stat * sb)
char *s, *p, *e = NULL;
if (session->scpRecv_state == libssh2_NB_state_sent5) {
rc = libssh2_channel_read_ex(session->scpRecv_channel, 0,
rc = _libssh2_channel_read(session->scpRecv_channel, 0,
(char *) session->
scpRecv_response +
session->scpRecv_response_len, 1);
@@ -718,7 +721,7 @@ libssh2_scp_recv(LIBSSH2_SESSION * session, const char *path, struct stat * sb)
}
if (session->scpRecv_state == libssh2_NB_state_sent6) {
rc = libssh2_channel_write_ex(session->scpRecv_channel, 0,
rc = _libssh2_channel_write(session->scpRecv_channel, 0,
(char *) session->
scpRecv_response, 1);
if (rc == PACKET_EAGAIN) {
@@ -761,13 +764,27 @@ libssh2_scp_recv(LIBSSH2_SESSION * session, const char *path, struct stat * sb)
}
/*
* libssh2_scp_send_ex
* libssh2_scp_recv
*
* Open a channel and request a remote file via SCP
*
*/
LIBSSH2_API LIBSSH2_CHANNEL *
libssh2_scp_recv(LIBSSH2_SESSION *session, const char *path, struct stat * sb)
{
LIBSSH2_CHANNEL *ptr;
BLOCK_ADJUST_ERRNO(ptr, session, scp_recv(session, path, sb));
return ptr;
}
/*
* scp_send()
*
* Send a file using SCP
*
*/
LIBSSH2_API LIBSSH2_CHANNEL *
libssh2_scp_send_ex(LIBSSH2_SESSION * session, const char *path, int mode,
static LIBSSH2_CHANNEL *
scp_send(LIBSSH2_SESSION * session, const char *path, int mode,
size_t size, long mtime, long atime)
{
int cmd_len;
@@ -857,7 +874,7 @@ libssh2_scp_send_ex(LIBSSH2_SESSION * session, const char *path, int mode,
if (session->scpSend_state == libssh2_NB_state_sent1) {
/* Wait for ACK */
rc = libssh2_channel_read_ex(session->scpSend_channel, 0,
rc = _libssh2_channel_read(session->scpSend_channel, 0,
(char *) session->scpSend_response, 1);
if (rc == PACKET_EAGAIN) {
libssh2_error(session, LIBSSH2_ERROR_EAGAIN,
@@ -885,7 +902,7 @@ libssh2_scp_send_ex(LIBSSH2_SESSION * session, const char *path, int mode,
/* Send mtime and atime to be used for file */
if (mtime || atime) {
if (session->scpSend_state == libssh2_NB_state_sent2) {
rc = libssh2_channel_write_ex(session->scpSend_channel, 0,
rc = _libssh2_channel_write(session->scpSend_channel, 0,
(char *) session->scpSend_response,
session->scpSend_response_len);
if (rc == PACKET_EAGAIN) {
@@ -903,9 +920,8 @@ libssh2_scp_send_ex(LIBSSH2_SESSION * session, const char *path, int mode,
if (session->scpSend_state == libssh2_NB_state_sent3) {
/* Wait for ACK */
rc = libssh2_channel_read_ex(session->scpSend_channel, 0,
(char *) session->scpSend_response,
1);
rc = _libssh2_channel_read(session->scpSend_channel, 0,
(char *) session->scpSend_response, 1);
if (rc == PACKET_EAGAIN) {
libssh2_error(session, LIBSSH2_ERROR_EAGAIN,
"Would block waiting for response", 0);
@@ -944,7 +960,7 @@ libssh2_scp_send_ex(LIBSSH2_SESSION * session, const char *path, int mode,
}
if (session->scpSend_state == libssh2_NB_state_sent5) {
rc = libssh2_channel_write_ex(session->scpSend_channel, 0,
rc = _libssh2_channel_write(session->scpSend_channel, 0,
(char *) session->scpSend_response,
session->scpSend_response_len);
if (rc == PACKET_EAGAIN) {
@@ -962,7 +978,7 @@ libssh2_scp_send_ex(LIBSSH2_SESSION * session, const char *path, int mode,
if (session->scpSend_state == libssh2_NB_state_sent6) {
/* Wait for ACK */
rc = libssh2_channel_read_ex(session->scpSend_channel, 0,
rc = _libssh2_channel_read(session->scpSend_channel, 0,
(char *) session->scpSend_response, 1);
if (rc == PACKET_EAGAIN) {
libssh2_error(session, LIBSSH2_ERROR_EAGAIN,
@@ -990,7 +1006,7 @@ libssh2_scp_send_ex(LIBSSH2_SESSION * session, const char *path, int mode,
memset(session->scpSend_err_msg, 0, session->scpSend_err_len + 1);
/* Read the remote error message */
rc = libssh2_channel_read_ex(session->scpSend_channel, 0,
rc = _libssh2_channel_read(session->scpSend_channel, 0,
session->scpSend_err_msg,
session->scpSend_err_len);
if (rc <= 0) {
@@ -1021,3 +1037,17 @@ libssh2_scp_send_ex(LIBSSH2_SESSION * session, const char *path, int mode,
return NULL;
}
/*
* libssh2_scp_send_ex
*
* Send a file using SCP
*/
LIBSSH2_API LIBSSH2_CHANNEL *
libssh2_scp_send_ex(LIBSSH2_SESSION *session, const char *path, int mode,
size_t size, long mtime, long atime)
{
LIBSSH2_CHANNEL *ptr;
BLOCK_ADJUST_ERRNO(ptr, session,
scp_send(session, path, mode, size, mtime, atime));
return ptr;
}

View File

@@ -106,6 +106,9 @@ banner_receive(LIBSSH2_SESSION * session)
|| (session->banner_TxRx_banner[banner_len - 1] != '\n'))) {
char c = '\0';
/* no incoming block yet! */
session->socket_block_directions &= ~LIBSSH2_SESSION_BLOCK_INBOUND;
ret = _libssh2_recv(session->socket_fd, &c, 1,
LIBSSH2_SOCKET_RECV_FLAGS(session));
@@ -207,6 +210,9 @@ banner_send(LIBSSH2_SESSION * session)
session->banner_TxRx_state = libssh2_NB_state_created;
}
/* no outgoing block yet! */
session->socket_block_directions &= ~LIBSSH2_SESSION_BLOCK_OUTBOUND;
ret = _libssh2_send(session->socket_fd,
banner + session->banner_TxRx_total_send,
banner_len - session->banner_TxRx_total_send,
@@ -238,7 +244,7 @@ banner_send(LIBSSH2_SESSION * session)
* is copied from the libcurl sources with permission.
*/
static int
session_nonblock(int sockfd, /* operate on this */
session_nonblock(libssh2_socket_t sockfd, /* operate on this */
int nonblock /* TRUE or FALSE */ )
{
#undef SETBLOCK
@@ -529,7 +535,7 @@ int _libssh2_wait_socket(LIBSSH2_SESSION *session)
}
static int
session_startup(LIBSSH2_SESSION *session, int sock)
session_startup(LIBSSH2_SESSION *session, libssh2_socket_t sock)
{
int rc;
@@ -556,35 +562,22 @@ session_startup(LIBSSH2_SESSION *session, int sock)
session->startup_state = libssh2_NB_state_created;
}
/* TODO: Liveness check */
if (session->startup_state == libssh2_NB_state_created) {
rc = banner_send(session);
if (rc == PACKET_EAGAIN) {
libssh2_error(session, LIBSSH2_ERROR_EAGAIN,
"Would block sending banner to remote host", 0);
return LIBSSH2_ERROR_EAGAIN;
} else if (rc) {
/* Unable to send banner? */
libssh2_error(session, LIBSSH2_ERROR_BANNER_SEND,
"Error sending banner to remote host", 0);
return LIBSSH2_ERROR_BANNER_SEND;
if (rc) {
libssh2_error(session, rc,
"Failed sending banner", 0);
return rc;
}
session->startup_state = libssh2_NB_state_sent;
}
if (session->startup_state == libssh2_NB_state_sent) {
rc = banner_receive(session);
if (rc == PACKET_EAGAIN) {
libssh2_error(session, LIBSSH2_ERROR_EAGAIN,
"Would block waiting for banner", 0);
return LIBSSH2_ERROR_EAGAIN;
} else if (rc) {
/* Unable to receive banner from remote */
libssh2_error(session, LIBSSH2_ERROR_BANNER_NONE,
"Timeout waiting for banner", 0);
return LIBSSH2_ERROR_BANNER_NONE;
if (rc) {
libssh2_error(session, rc,
"Failed getting banner", 0);
return rc;
}
session->startup_state = libssh2_NB_state_sent1;
@@ -592,14 +585,10 @@ session_startup(LIBSSH2_SESSION *session, int sock)
if (session->startup_state == libssh2_NB_state_sent1) {
rc = libssh2_kex_exchange(session, 0, &session->startup_key_state);
if (rc == PACKET_EAGAIN) {
libssh2_error(session, LIBSSH2_ERROR_EAGAIN,
"Would block exchanging encryption keys", 0);
return LIBSSH2_ERROR_EAGAIN;
} else if (rc) {
libssh2_error(session, LIBSSH2_ERROR_KEX_FAILURE,
if (rc) {
libssh2_error(session, rc,
"Unable to exchange encryption keys", 0);
return LIBSSH2_ERROR_KEX_FAILURE;
return rc;
}
session->startup_state = libssh2_NB_state_sent2;
@@ -622,15 +611,10 @@ session_startup(LIBSSH2_SESSION *session, int sock)
if (session->startup_state == libssh2_NB_state_sent3) {
rc = _libssh2_transport_write(session, session->startup_service,
sizeof("ssh-userauth") + 5 - 1);
if (rc == PACKET_EAGAIN) {
libssh2_error(session, LIBSSH2_ERROR_EAGAIN,
"Would block asking for ssh-userauth service", 0);
return LIBSSH2_ERROR_EAGAIN;
}
else if (rc) {
libssh2_error(session, LIBSSH2_ERROR_SOCKET_SEND,
if (rc) {
libssh2_error(session, rc,
"Unable to ask for ssh-userauth service", 0);
return LIBSSH2_ERROR_SOCKET_SEND;
return rc;
}
session->startup_state = libssh2_NB_state_sent4;
@@ -641,11 +625,9 @@ session_startup(LIBSSH2_SESSION *session, int sock)
&session->startup_data,
&session->startup_data_len, 0, NULL, 0,
&session->startup_req_state);
if (rc == PACKET_EAGAIN) {
return LIBSSH2_ERROR_EAGAIN;
} else if (rc) {
return LIBSSH2_ERROR_SOCKET_DISCONNECT;
}
if (rc)
return rc;
session->startup_service_length =
_libssh2_ntohu32(session->startup_data + 1);
@@ -699,6 +681,9 @@ static int
session_free(LIBSSH2_SESSION *session)
{
int rc;
LIBSSH2_PACKET *pkg;
LIBSSH2_CHANNEL *ch;
LIBSSH2_LISTENER *l;
if (session->free_state == libssh2_NB_state_idle) {
_libssh2_debug(session, LIBSSH2_DBG_TRANS, "Freeing session resource",
@@ -708,13 +693,15 @@ session_free(LIBSSH2_SESSION *session)
}
if (session->free_state == libssh2_NB_state_created) {
while (session->channels.head) {
LIBSSH2_CHANNEL *tmp = session->channels.head;
while ((ch = _libssh2_list_first(&session->channels))) {
rc = libssh2_channel_free(session->channels.head);
if (rc == PACKET_EAGAIN) {
return PACKET_EAGAIN;
}
rc = libssh2_channel_free(ch);
if (rc == PACKET_EAGAIN)
return rc;
#if 0
/* Daniel's note: I'm leaving this code here right now since it
looks so weird I'm stumped. Why would libssh2_channel_free()
fail and forces this to be done? */
if (tmp == session->channels.head) {
/* channel_free couldn't do it's job, perform a messy cleanup */
tmp = session->channels.head;
@@ -728,17 +715,17 @@ session_free(LIBSSH2_SESSION *session)
/* reverse linking isn't important here, we're killing the
* structure */
}
#endif
}
session->state = libssh2_NB_state_sent;
}
if (session->state == libssh2_NB_state_sent) {
while (session->listeners) {
rc = libssh2_channel_forward_cancel(session->listeners);
if (rc == PACKET_EAGAIN) {
return PACKET_EAGAIN;
}
while ((l = _libssh2_list_first(&session->listeners))) {
rc = libssh2_channel_forward_cancel(l);
if (rc == PACKET_EAGAIN)
return rc;
}
session->state = libssh2_NB_state_sent1;
@@ -908,16 +895,14 @@ session_free(LIBSSH2_SESSION *session)
LIBSSH2_FREE(session, session->err_msg);
}
/* Cleanup any remaining packets */
while (session->packets.head) {
LIBSSH2_PACKET *tmp = session->packets.head;
/* unlink */
session->packets.head = tmp->next;
/* Cleanup all remaining packets */
while ((pkg = _libssh2_list_first(&session->packets))) {
/* unlink the node */
_libssh2_list_remove(&pkg->node);
/* free */
LIBSSH2_FREE(session, tmp->data);
LIBSSH2_FREE(session, tmp);
LIBSSH2_FREE(session, pkg->data);
LIBSSH2_FREE(session, pkg);
}
if(session->socket_prev_blockstate)
@@ -1007,7 +992,7 @@ session_disconnect(LIBSSH2_SESSION *session, int reason,
rc = _libssh2_transport_write(session, session->disconnect_data,
session->disconnect_data_len);
if (rc == PACKET_EAGAIN) {
return PACKET_EAGAIN;
return rc;
}
LIBSSH2_FREE(session, session->disconnect_data);
@@ -1245,7 +1230,7 @@ LIBSSH2_API int
libssh2_poll_channel_read(LIBSSH2_CHANNEL * channel, int extended)
{
LIBSSH2_SESSION *session = channel->session;
LIBSSH2_PACKET *packet = session->packets.head;
LIBSSH2_PACKET *packet = _libssh2_list_first(&session->packets);
while (packet) {
if ( channel->local.id == _libssh2_ntohu32(packet->data + 1)) {
@@ -1259,7 +1244,7 @@ libssh2_poll_channel_read(LIBSSH2_CHANNEL * channel, int extended)
}
/* else - no data of any type is ready to be read */
}
packet = packet->next;
packet = _libssh2_list_next(&packet->node);
}
return 0;
@@ -1285,7 +1270,7 @@ poll_channel_write(LIBSSH2_CHANNEL * channel)
static inline int
poll_listener_queued(LIBSSH2_LISTENER * listener)
{
return listener->queue ? 1 : 0;
return _libssh2_list_first(&listener->queue) ? 1 : 0;
}
/*
@@ -1346,7 +1331,7 @@ libssh2_poll(LIBSSH2_POLLFD * fds, unsigned int nfds, long timeout)
}
#elif defined(HAVE_SELECT)
LIBSSH2_SESSION *session = NULL;
int maxfd = 0;
libssh2_socket_t maxfd = 0;
fd_set rfds, wfds;
struct timeval tv;
@@ -1456,8 +1441,7 @@ libssh2_poll(LIBSSH2_POLLFD * fds, unsigned int nfds, long timeout)
((fds[i].revents & LIBSSH2_POLLFD_POLLIN) == 0)) {
/* No connections known of yet */
fds[i].revents |=
poll_listener_queued(fds[i].fd.
listener) ?
poll_listener_queued(fds[i].fd. listener) ?
LIBSSH2_POLLFD_POLLIN : 0;
}
if (fds[i].fd.listener->session->socket_state ==

View File

@@ -124,22 +124,15 @@ sftp_packet_add(LIBSSH2_SFTP *sftp, unsigned char *data,
if (!packet) {
libssh2_error(session, LIBSSH2_ERROR_ALLOC,
"Unable to allocate datablock for SFTP packet", 0);
return -1;
return LIBSSH2_ERROR_ALLOC;
}
memset(packet, 0, sizeof(LIBSSH2_PACKET));
packet->data = data;
packet->data_len = data_len;
packet->data_head = 5;
packet->brigade = &sftp->packets;
packet->next = NULL;
packet->prev = sftp->packets.tail;
if (packet->prev) {
packet->prev->next = packet;
} else {
sftp->packets.head = packet;
}
sftp->packets.tail = packet;
_libssh2_list_add(&sftp->packets, &packet->node);
return 0;
}
@@ -174,17 +167,17 @@ sftp_packet_read(LIBSSH2_SFTP *sftp)
"partial read cont, len: %lu", packet_len);
}
else {
rc = libssh2_channel_read_ex(channel, 0, (char *) buffer, 4);
rc = _libssh2_channel_read(channel, 0, (char *) buffer, 4);
if (rc == PACKET_EAGAIN) {
return PACKET_EAGAIN;
return rc;
}
else if (4 != rc) {
/* TODO: this is stupid since we can in fact get 1-3 bytes in a
legitimate working case as well if the connection happens to be
super slow or something */
libssh2_error(session, LIBSSH2_ERROR_SOCKET_TIMEOUT,
"Timeout waiting for FXP packet", 0);
return -1;
libssh2_error(session, LIBSSH2_ERROR_CHANNEL_FAILURE,
"Read part of packet", 0);
return LIBSSH2_ERROR_CHANNEL_FAILURE;
}
packet_len = _libssh2_ntohu32(buffer);
@@ -193,14 +186,14 @@ sftp_packet_read(LIBSSH2_SFTP *sftp)
if (packet_len > LIBSSH2_SFTP_PACKET_MAXLEN) {
libssh2_error(session, LIBSSH2_ERROR_CHANNEL_PACKET_EXCEEDED,
"SFTP packet too large", 0);
return -1;
return LIBSSH2_ERROR_CHANNEL_PACKET_EXCEEDED;
}
packet = LIBSSH2_ALLOC(session, packet_len);
if (!packet) {
libssh2_error(session, LIBSSH2_ERROR_ALLOC,
"Unable to allocate SFTP packet", 0);
return -1;
return LIBSSH2_ERROR_ALLOC;
}
packet_received = 0;
@@ -209,7 +202,7 @@ sftp_packet_read(LIBSSH2_SFTP *sftp)
/* Read as much of the packet as we can */
while (packet_len > packet_received) {
bytes_received =
libssh2_channel_read_ex(channel, 0,
_libssh2_channel_read(channel, 0,
(char *) packet + packet_received,
packet_len - packet_received);
@@ -223,20 +216,21 @@ sftp_packet_read(LIBSSH2_SFTP *sftp)
sftp->partial_received = packet_received;
packet = NULL;
return PACKET_EAGAIN;
return bytes_received;
}
else if (bytes_received < 0) {
libssh2_error(session, LIBSSH2_ERROR_SOCKET_TIMEOUT,
"Receive error waiting for SFTP packet", 0);
LIBSSH2_FREE(session, packet);
return -1;
return bytes_received;
}
packet_received += bytes_received;
}
if (sftp_packet_add(sftp, packet, packet_len)) {
rc = sftp_packet_add(sftp, packet, packet_len);
if (rc) {
LIBSSH2_FREE(session, packet);
return -1;
return rc;
}
return packet[0];
@@ -253,7 +247,7 @@ sftp_packet_ask(LIBSSH2_SFTP *sftp, unsigned char packet_type,
unsigned long *data_len)
{
LIBSSH2_SESSION *session = sftp->channel->session;
LIBSSH2_PACKET *packet = sftp->packets.head;
LIBSSH2_PACKET *packet = _libssh2_list_first(&sftp->packets);
unsigned char match_buf[5];
int match_len;
@@ -277,24 +271,13 @@ sftp_packet_ask(LIBSSH2_SFTP *sftp, unsigned char packet_type,
*data_len = packet->data_len;
/* unlink and free this struct */
if (packet->prev) {
packet->prev->next = packet->next;
} else {
sftp->packets.head = packet->next;
}
if (packet->next) {
packet->next->prev = packet->prev;
} else {
sftp->packets.tail = packet->prev;
}
_libssh2_list_remove(&packet->node);
LIBSSH2_FREE(session, packet);
return 0;
}
/* check next struct in the list */
packet = packet->next;
packet = _libssh2_list_next(&packet->node);
}
return -1;
}
@@ -323,7 +306,7 @@ sftp_packet_require(LIBSSH2_SFTP *sftp, unsigned char packet_type,
while (session->socket_state == LIBSSH2_SOCKET_CONNECTED) {
ret = sftp_packet_read(sftp);
if (ret == PACKET_EAGAIN) {
return PACKET_EAGAIN;
return ret;
} else if (ret <= 0) {
return -1;
}
@@ -338,7 +321,7 @@ sftp_packet_require(LIBSSH2_SFTP *sftp, unsigned char packet_type,
}
/* Only reached if the socket died */
return -1;
return LIBSSH2_ERROR_SOCKET_DISCONNECT;
}
/* sftp_packet_requirev
@@ -385,7 +368,7 @@ sftp_packet_requirev(LIBSSH2_SFTP *sftp, int num_valid_responses,
return PACKET_TIMEOUT;
}
else if (ret == PACKET_EAGAIN) {
return PACKET_EAGAIN;
return ret;
}
}
}
@@ -556,8 +539,8 @@ static LIBSSH2_SFTP *sftp_init(LIBSSH2_SESSION *session)
* as the SFTP session is created they are cleared and can thus be
* re-used again to allow any amount of SFTP handles per sessions.
*
* Note that you MUST NOT try to call libssh2_sftp_init() to get
* another handle until the previous one has finished and either
* Note that you MUST NOT try to call libssh2_sftp_init() again to get
* another handle until the previous call has finished and either
* succesffully made a handle or failed and returned error (not
* including *EAGAIN).
*/
@@ -715,6 +698,8 @@ static LIBSSH2_SFTP *sftp_init(LIBSSH2_SESSION *session)
session->sftpInit_sftp = NULL;
session->sftpInit_channel = NULL;
_libssh2_list_init(&sftp_handle->sftp_handles);
return sftp_handle;
sftp_init_error:
@@ -798,6 +783,9 @@ sftp_shutdown(LIBSSH2_SFTP *sftp)
sftp->symlink_packet = NULL;
}
/* TODO: We should consider walking over the sftp_handles list and kill
* any remaining sftp handles ... */
rc = _libssh2_channel_free(sftp->channel);
return rc;
@@ -810,8 +798,7 @@ LIBSSH2_API int
libssh2_sftp_shutdown(LIBSSH2_SFTP *sftp)
{
int rc;
BLOCK_ADJUST(rc, sftp->channel->session,
sftp_shutdown(sftp));
BLOCK_ADJUST(rc, sftp->channel->session, sftp_shutdown(sftp));
return rc;
}
@@ -920,7 +907,7 @@ sftp_open(LIBSSH2_SFTP *sftp, const char *filename,
return NULL;
}
else if (rc) {
libssh2_error(session, LIBSSH2_ERROR_SOCKET_TIMEOUT,
libssh2_error(session, rc,
"Timeout waiting for status message", 0);
sftp->open_state = libssh2_NB_state_idle;
return NULL;
@@ -985,12 +972,10 @@ sftp_open(LIBSSH2_SFTP *sftp, const char *filename,
memcpy(fp->handle, data + 9, fp->handle_len);
LIBSSH2_FREE(session, data);
/* Link the file and the sftp session together */
fp->next = sftp->handles;
if (fp->next) {
fp->next->prev = fp;
}
fp->sftp = sftp;
/* add this file handle to the list kept in the sftp session */
_libssh2_list_add(&sftp->sftp_handles, &fp->node);
fp->sftp = sftp; /* point to the parent struct */
fp->u.file.offset = 0;
@@ -1106,7 +1091,7 @@ static ssize_t sftp_read(LIBSSH2_SFTP_HANDLE * handle, char *buffer,
sftp->read_packet = packet;
sftp->read_request_id = request_id;
sftp->read_total_read = total_read;
return PACKET_EAGAIN;
return retcode;
} else if (packet_len != retcode) {
/* TODO: a partial write is not a critical error when in
non-blocking mode! */
@@ -1127,9 +1112,11 @@ static ssize_t sftp_read(LIBSSH2_SFTP_HANDLE * handle, char *buffer,
sftp_packet_requirev(sftp, 2, read_responses,
request_id, &data, &data_len);
if (retcode == PACKET_EAGAIN) {
return PACKET_EAGAIN;
libssh2_error(session, retcode,
"Would block waiting for status message", 0);
return retcode;
} else if (retcode) {
libssh2_error(session, LIBSSH2_ERROR_SOCKET_TIMEOUT,
libssh2_error(session, retcode,
"Timeout waiting for status message", 0);
sftp->read_packet = NULL;
sftp->read_state = libssh2_NB_state_idle;
@@ -1307,7 +1294,7 @@ static int sftp_readdir(LIBSSH2_SFTP_HANDLE *handle, char *buffer,
(char *) sftp->readdir_packet,
packet_len);
if (retcode == PACKET_EAGAIN) {
return PACKET_EAGAIN;
return retcode;
}
else if (packet_len != retcode) {
libssh2_error(session, LIBSSH2_ERROR_SOCKET_SEND,
@@ -1329,7 +1316,7 @@ static int sftp_readdir(LIBSSH2_SFTP_HANDLE *handle, char *buffer,
sftp->readdir_request_id, &data,
&data_len);
if (retcode == PACKET_EAGAIN) {
return PACKET_EAGAIN;
return retcode;
} else if (retcode) {
libssh2_error(session, LIBSSH2_ERROR_SOCKET_TIMEOUT,
"Timeout waiting for status message", 0);
@@ -1418,7 +1405,8 @@ libssh2_sftp_readdir_ex(LIBSSH2_SFTP_HANDLE *hnd, char *buffer,
/*
* sftp_write
*
* Write data to an SFTP handle
* Write data to an SFTP handle. Returns the number of bytes written, or
* a negative error code.
*/
static ssize_t sftp_write(LIBSSH2_SFTP_HANDLE *handle, const char *buffer,
size_t count)
@@ -1449,7 +1437,7 @@ static ssize_t sftp_write(LIBSSH2_SFTP_HANDLE *handle, const char *buffer,
if (!sftp->write_packet) {
libssh2_error(session, LIBSSH2_ERROR_ALLOC,
"Unable to allocate memory for FXP_WRITE", 0);
return -1;
return LIBSSH2_ERROR_ALLOC;
}
_libssh2_htonu32(s, packet_len - 4);
s += 4;
@@ -1474,17 +1462,13 @@ static ssize_t sftp_write(LIBSSH2_SFTP_HANDLE *handle, const char *buffer,
if (sftp->write_state == libssh2_NB_state_created) {
rc = _libssh2_channel_write(channel, 0, (char *)sftp->write_packet,
packet_len);
if (rc == PACKET_EAGAIN) {
return PACKET_EAGAIN;
}
else if(rc < 0) {
/* an actual error */
if(rc < 0) {
/* error */
return rc;
}
else if(0 == rc) {
/* an actual error */
fprintf(stderr, "WEIRDNESS\n");
return -1;
/* nothing sent is an error */
return LIBSSH2_ERROR_SOCKET_SEND;
}
else if (packet_len != rc) {
return rc;
@@ -1497,12 +1481,13 @@ static ssize_t sftp_write(LIBSSH2_SFTP_HANDLE *handle, const char *buffer,
rc = sftp_packet_require(sftp, SSH_FXP_STATUS,
sftp->write_request_id, &data, &data_len);
if (rc == PACKET_EAGAIN) {
return PACKET_EAGAIN;
} else if (rc) {
libssh2_error(session, LIBSSH2_ERROR_SOCKET_TIMEOUT,
return rc;
}
else if (rc) {
libssh2_error(session, rc,
"Timeout waiting for status message", 0);
sftp->write_state = libssh2_NB_state_idle;
return -1;
return rc;
}
sftp->write_state = libssh2_NB_state_idle;
@@ -1518,7 +1503,7 @@ static ssize_t sftp_write(LIBSSH2_SFTP_HANDLE *handle, const char *buffer,
0);
sftp->last_errno = retcode;
return -1;
return LIBSSH2_ERROR_SFTP_PROTOCOL;
}
/* libssh2_sftp_write
@@ -1587,7 +1572,7 @@ static int sftp_fstat(LIBSSH2_SFTP_HANDLE *handle,
rc = _libssh2_channel_write(channel, 0, (char *) sftp->fstat_packet,
packet_len);
if (rc == PACKET_EAGAIN) {
return PACKET_EAGAIN;
return rc;
} else if (packet_len != rc) {
libssh2_error(session, LIBSSH2_ERROR_SOCKET_SEND,
(setstat ? "Unable to send FXP_FSETSTAT"
@@ -1607,7 +1592,7 @@ static int sftp_fstat(LIBSSH2_SFTP_HANDLE *handle,
sftp->fstat_request_id, &data,
&data_len);
if (rc == PACKET_EAGAIN) {
return PACKET_EAGAIN;
return rc;
} else if (rc) {
libssh2_error(session, LIBSSH2_ERROR_SOCKET_TIMEOUT,
"Timeout waiting for status message", 0);
@@ -1733,7 +1718,7 @@ sftp_close_handle(LIBSSH2_SFTP_HANDLE *handle)
rc = _libssh2_channel_write(channel, 0, (char *) handle->close_packet,
packet_len);
if (rc == PACKET_EAGAIN) {
return PACKET_EAGAIN;
return rc;
} else if (packet_len != rc) {
libssh2_error(session, LIBSSH2_ERROR_SOCKET_SEND,
"Unable to send FXP_CLOSE command", 0);
@@ -1753,7 +1738,7 @@ sftp_close_handle(LIBSSH2_SFTP_HANDLE *handle)
handle->close_request_id, &data,
&data_len);
if (rc == PACKET_EAGAIN) {
return PACKET_EAGAIN;
return rc;
} else if (rc) {
libssh2_error(session, LIBSSH2_ERROR_SOCKET_TIMEOUT,
"Timeout waiting for status message", 0);
@@ -1775,12 +1760,8 @@ sftp_close_handle(LIBSSH2_SFTP_HANDLE *handle)
return -1;
}
if (handle == sftp->handles) {
sftp->handles = handle->next;
}
if (handle->next) {
handle->next->prev = NULL;
}
/* remove this handle from the parent's list */
_libssh2_list_remove(&handle->node);
if ((handle->handle_type == LIBSSH2_SFTP_HANDLE_DIR)
&& handle->u.dir.names_left) {
@@ -1849,7 +1830,7 @@ static int sftp_unlink(LIBSSH2_SFTP *sftp, const char *filename,
rc = _libssh2_channel_write(channel, 0, (char *) sftp->unlink_packet,
packet_len);
if (rc == PACKET_EAGAIN) {
return PACKET_EAGAIN;
return rc;
} else if (packet_len != rc) {
libssh2_error(session, LIBSSH2_ERROR_SOCKET_SEND,
"Unable to send FXP_REMOVE command", 0);
@@ -1868,7 +1849,7 @@ static int sftp_unlink(LIBSSH2_SFTP *sftp, const char *filename,
sftp->unlink_request_id, &data,
&data_len);
if (rc == PACKET_EAGAIN) {
return PACKET_EAGAIN;
return rc;
}
else if (rc) {
libssh2_error(session, LIBSSH2_ERROR_SOCKET_TIMEOUT,
@@ -1972,7 +1953,7 @@ static int sftp_rename(LIBSSH2_SFTP *sftp, const char *source_filename,
rc = _libssh2_channel_write(channel, 0, (char *) sftp->rename_packet,
sftp->rename_s - sftp->rename_packet);
if (rc == PACKET_EAGAIN) {
return PACKET_EAGAIN;
return rc;
} else if (packet_len != rc) {
libssh2_error(session, LIBSSH2_ERROR_SOCKET_SEND,
"Unable to send FXP_RENAME command", 0);
@@ -1991,7 +1972,7 @@ static int sftp_rename(LIBSSH2_SFTP *sftp, const char *source_filename,
sftp->rename_request_id, &data,
&data_len);
if (rc == PACKET_EAGAIN) {
return PACKET_EAGAIN;
return rc;
} else if (rc) {
libssh2_error(session, LIBSSH2_ERROR_SOCKET_TIMEOUT,
"Timeout waiting for status message", 0);
@@ -2103,7 +2084,7 @@ static int sftp_mkdir(LIBSSH2_SFTP *sftp, const char *path,
rc = _libssh2_channel_write(channel, 0, (char *) packet, packet_len);
if (rc == PACKET_EAGAIN) {
sftp->mkdir_packet = packet;
return PACKET_EAGAIN;
return rc;
}
if (packet_len != rc) {
libssh2_error(session, LIBSSH2_ERROR_SOCKET_SEND,
@@ -2120,7 +2101,7 @@ static int sftp_mkdir(LIBSSH2_SFTP *sftp, const char *path,
rc = sftp_packet_require(sftp, SSH_FXP_STATUS, sftp->mkdir_request_id,
&data, &data_len);
if (rc == PACKET_EAGAIN) {
return PACKET_EAGAIN;
return rc;
} else if (rc) {
libssh2_error(session, LIBSSH2_ERROR_SOCKET_TIMEOUT,
"Timeout waiting for status message", 0);
@@ -2201,7 +2182,7 @@ static int sftp_rmdir(LIBSSH2_SFTP *sftp, const char *path,
rc = _libssh2_channel_write(channel, 0, (char *) sftp->rmdir_packet,
packet_len);
if (rc == PACKET_EAGAIN) {
return PACKET_EAGAIN;
return rc;
} else if (packet_len != rc) {
libssh2_error(session, LIBSSH2_ERROR_SOCKET_SEND,
"Unable to send FXP_RMDIR command", 0);
@@ -2219,7 +2200,7 @@ static int sftp_rmdir(LIBSSH2_SFTP *sftp, const char *path,
rc = sftp_packet_require(sftp, SSH_FXP_STATUS,
sftp->rmdir_request_id, &data, &data_len);
if (rc == PACKET_EAGAIN) {
return PACKET_EAGAIN;
return rc;
} else if (rc) {
libssh2_error(session, LIBSSH2_ERROR_SOCKET_TIMEOUT,
"Timeout waiting for status message", 0);
@@ -2320,7 +2301,7 @@ static int sftp_stat(LIBSSH2_SFTP *sftp, const char *path,
rc = _libssh2_channel_write(channel, 0, (char *) sftp->stat_packet,
packet_len);
if (rc == PACKET_EAGAIN) {
return PACKET_EAGAIN;
return rc;
} else if (packet_len != rc) {
libssh2_error(session, LIBSSH2_ERROR_SOCKET_SEND,
"Unable to send STAT/LSTAT/SETSTAT command", 0);
@@ -2338,7 +2319,7 @@ static int sftp_stat(LIBSSH2_SFTP *sftp, const char *path,
rc = sftp_packet_requirev(sftp, 2, stat_responses,
sftp->stat_request_id, &data, &data_len);
if (rc == PACKET_EAGAIN) {
return PACKET_EAGAIN;
return rc;
} else if (rc) {
libssh2_error(session, LIBSSH2_ERROR_SOCKET_TIMEOUT,
"Timeout waiting for status message", 0);
@@ -2460,7 +2441,7 @@ static int sftp_symlink(LIBSSH2_SFTP *sftp, const char *path,
rc = _libssh2_channel_write(channel, 0, (char *) sftp->symlink_packet,
packet_len);
if (rc == PACKET_EAGAIN) {
return PACKET_EAGAIN;
return rc;
} else if (packet_len != rc) {
libssh2_error(session, LIBSSH2_ERROR_SOCKET_SEND,
"Unable to send SYMLINK/READLINK command", 0);
@@ -2479,7 +2460,7 @@ static int sftp_symlink(LIBSSH2_SFTP *sftp, const char *path,
sftp->symlink_request_id, &data,
&data_len);
if (rc == PACKET_EAGAIN) {
return PACKET_EAGAIN;
return rc;
}
else if (rc) {
libssh2_error(session, LIBSSH2_ERROR_SOCKET_TIMEOUT,

View File

@@ -95,10 +95,10 @@ debugdump(LIBSSH2_SESSION * session,
/* decrypt() decrypts 'len' bytes from 'source' to 'dest'.
*
* returns PACKET_NONE on success and PACKET_FAIL on failure
* returns 0 on success and negative on failure
*/
static libssh2pack_t
static int
decrypt(LIBSSH2_SESSION * session, unsigned char *source,
unsigned char *dest, int len)
{
@@ -134,7 +134,7 @@ decrypt(LIBSSH2_SESSION * session, unsigned char *source,
* fullpacket() gets called when a full packet has been received and properly
* collected.
*/
static libssh2pack_t
static int
fullpacket(LIBSSH2_SESSION * session, int encrypted /* 1 or 0 */ )
{
unsigned char macbuf[MAX_MACSIZE];
@@ -232,11 +232,8 @@ fullpacket(LIBSSH2_SESSION * session, int encrypted /* 1 or 0 */ )
rc = _libssh2_packet_add(session, p->payload,
session->fullpacket_payload_len,
session->fullpacket_macstate);
if (rc == PACKET_EAGAIN) {
return PACKET_EAGAIN;
} else if (rc < 0) {
return PACKET_FAIL;
}
if (rc)
return rc;
}
session->fullpacket_state = libssh2_NB_state_idle;
@@ -248,22 +245,21 @@ fullpacket(LIBSSH2_SESSION * session, int encrypted /* 1 or 0 */ )
/*
* _libssh2_transport_read
*
* Collect a packet into the input brigade block only controls whether or not
* to wait for a packet to start.
* Collect a packet into the input queue.
*
* Returns packet type added to input brigade (PACKET_NONE if nothing added),
* or PACKET_FAIL on failure and PACKET_EAGAIN if it couldn't process a full
* packet.
* Returns packet type added to input queue (0 if nothing added), or a
* negative error number.
*/
/*
* This function reads the binary stream as specified in chapter 6 of RFC4253
* "The Secure Shell (SSH) Transport Layer Protocol"
*
* DOES NOT call libssh2_error() for ANY error case.
*/
libssh2pack_t
_libssh2_transport_read(LIBSSH2_SESSION * session)
int _libssh2_transport_read(LIBSSH2_SESSION * session)
{
libssh2pack_t rc = -1;
int rc = LIBSSH2_ERROR_SOCKET_NONE;
struct transportpacket *p = &session->packet;
int remainbuf;
int remainpack;
@@ -272,7 +268,6 @@ _libssh2_transport_read(LIBSSH2_SESSION * session)
unsigned char block[MAX_BLOCKSIZE];
int blocksize;
int encrypted = 1;
int status;
/* default clear the bit */
session->socket_block_directions &= ~LIBSSH2_SESSION_BLOCK_INBOUND;
@@ -297,16 +292,9 @@ _libssh2_transport_read(LIBSSH2_SESSION * session)
*/
_libssh2_debug(session, LIBSSH2_DBG_TRANS, "Redirecting into the"
" key re-exchange");
status = libssh2_kex_exchange(session, 1, &session->startup_key_state);
if (status == PACKET_EAGAIN) {
libssh2_error(session, LIBSSH2_ERROR_EAGAIN,
"Would block exchanging encryption keys", 0);
return PACKET_EAGAIN;
} else if (status) {
libssh2_error(session, LIBSSH2_ERROR_KEX_FAILURE,
"Unable to exchange encryption keys",0);
return LIBSSH2_ERROR_KEX_FAILURE;
}
rc = libssh2_kex_exchange(session, 1, &session->startup_key_state);
if (rc)
return rc;
}
/*
@@ -371,7 +359,7 @@ _libssh2_transport_read(LIBSSH2_SESSION * session)
/* check if this is due to EAGAIN and return the special
return code if so, error out normally otherwise */
if ((nread < 0) && (errno == EAGAIN)) {
session->socket_block_directions =
session->socket_block_directions |=
LIBSSH2_SESSION_BLOCK_INBOUND;
return PACKET_EAGAIN;
}
@@ -400,6 +388,8 @@ _libssh2_transport_read(LIBSSH2_SESSION * session)
check is only done for the initial block since once we have
got the start of a block we can in fact deal with fractions
*/
session->socket_block_directions |=
LIBSSH2_SESSION_BLOCK_INBOUND;
return PACKET_EAGAIN;
}
@@ -570,7 +560,7 @@ _libssh2_transport_read(LIBSSH2_SESSION * session)
session->readPack_state = libssh2_NB_state_jump1;
}
return PACKET_EAGAIN;
return rc;
}
p->total_num = 0; /* no packet buffer available */
@@ -582,7 +572,7 @@ _libssh2_transport_read(LIBSSH2_SESSION * session)
return PACKET_FAIL; /* we never reach this point */
}
static libssh2pack_t
static int
send_existing(LIBSSH2_SESSION * session, unsigned char *data,
unsigned long data_len, ssize_t * ret)
{
@@ -630,13 +620,13 @@ send_existing(LIBSSH2_SESSION * session, unsigned char *data,
/* send failure! */
return PACKET_FAIL;
}
session->socket_block_directions = LIBSSH2_SESSION_BLOCK_OUTBOUND;
session->socket_block_directions |= LIBSSH2_SESSION_BLOCK_OUTBOUND;
return PACKET_EAGAIN;
}
p->osent += rc; /* we sent away this much data */
return PACKET_NONE;
return p->osent < data_len ? PACKET_EAGAIN : PACKET_NONE;
}
/*
@@ -653,6 +643,8 @@ send_existing(LIBSSH2_SESSION * session, unsigned char *data,
* NOTE: this function does not verify that 'data_len' is less than ~35000
* which is what all implementations should support at least as packet size.
* (RFC4253 section 6.1)
*
* This function DOES not call libssh2_error() on any errors.
*/
int
_libssh2_transport_write(LIBSSH2_SESSION * session, unsigned char *data,
@@ -673,7 +665,7 @@ _libssh2_transport_write(LIBSSH2_SESSION * session, unsigned char *data,
int encrypted;
int i;
ssize_t ret;
libssh2pack_t rc;
int rc;
unsigned char *orgdata = data;
unsigned long orgdata_len = data_len;
@@ -791,7 +783,7 @@ _libssh2_transport_write(LIBSSH2_SESSION * session, unsigned char *data,
if (ret != total_length) {
if ((ret > 0) || ((ret == -1) && (errno == EAGAIN))) {
/* the whole packet could not be sent, save the rest */
session->socket_block_directions = LIBSSH2_SESSION_BLOCK_OUTBOUND;
session->socket_block_directions |= LIBSSH2_SESSION_BLOCK_OUTBOUND;
p->odata = orgdata;
p->olen = orgdata_len;
p->osent = (ret == -1) ? 0 : ret;

View File

@@ -75,6 +75,6 @@ int _libssh2_transport_write(LIBSSH2_SESSION * session, unsigned char *data,
* This function reads the binary stream as specified in chapter 6 of RFC4253
* "The Secure Shell (SSH) Transport Layer Protocol"
*/
libssh2pack_t _libssh2_transport_read(LIBSSH2_SESSION * session);
int _libssh2_transport_read(LIBSSH2_SESSION * session);
#endif /* __LIBSSH2_TRANSPORT_H */

View File

@@ -266,7 +266,7 @@ userauth_password(LIBSSH2_SESSION *session, const char *username,
rc = _libssh2_transport_write(session, session->userauth_pswd_data,
session->userauth_pswd_data_len);
if (rc == PACKET_EAGAIN) {
return PACKET_EAGAIN;
return rc;
} else if (rc) {
libssh2_error(session, LIBSSH2_ERROR_SOCKET_SEND,
"Unable to send userauth-password request", 0);
@@ -294,7 +294,7 @@ userauth_password(LIBSSH2_SESSION *session, const char *username,
&session->
userauth_pswd_packet_requirev_state);
if (rc == PACKET_EAGAIN) {
return PACKET_EAGAIN;
return rc;
} else if (rc) {
session->userauth_pswd_state = libssh2_NB_state_idle;
return -1;
@@ -402,7 +402,7 @@ userauth_password(LIBSSH2_SESSION *session, const char *username,
session->
userauth_pswd_data_len);
if (rc == PACKET_EAGAIN) {
return PACKET_EAGAIN;
return rc;
} else if (rc) {
libssh2_error(session, LIBSSH2_ERROR_SOCKET_SEND,
"Unable to send userauth-password-change request",
@@ -808,7 +808,7 @@ userauth_hostbased_fromfile(LIBSSH2_SESSION *session,
session->userauth_host_s -
session->userauth_host_packet);
if (rc == PACKET_EAGAIN) {
return PACKET_EAGAIN;
return rc;
} else if (rc) {
libssh2_error(session, LIBSSH2_ERROR_SOCKET_SEND,
"Unable to send userauth-hostbased request", 0);
@@ -831,7 +831,7 @@ userauth_hostbased_fromfile(LIBSSH2_SESSION *session,
&session->
userauth_host_packet_requirev_state);
if (rc == PACKET_EAGAIN) {
return PACKET_EAGAIN;
return rc;
}
session->userauth_host_state = libssh2_NB_state_idle;
@@ -987,7 +987,7 @@ userauth_publickey_fromfile(LIBSSH2_SESSION *session,
rc = _libssh2_transport_write(session, session->userauth_pblc_packet,
session->userauth_pblc_packet_len);
if (rc == PACKET_EAGAIN) {
return PACKET_EAGAIN;
return rc;
} else if (rc) {
libssh2_error(session, LIBSSH2_ERROR_SOCKET_SEND,
"Unable to send userauth-publickey request", 0);
@@ -1017,7 +1017,7 @@ userauth_publickey_fromfile(LIBSSH2_SESSION *session,
&session->
userauth_pblc_packet_requirev_state);
if (rc == PACKET_EAGAIN) {
return PACKET_EAGAIN;
return rc;
} else if (rc) {
LIBSSH2_FREE(session, session->userauth_pblc_packet);
session->userauth_pblc_packet = NULL;
@@ -1163,7 +1163,7 @@ userauth_publickey_fromfile(LIBSSH2_SESSION *session,
session->userauth_pblc_s -
session->userauth_pblc_packet);
if (rc == PACKET_EAGAIN) {
return PACKET_EAGAIN;
return rc;
} else if (rc) {
libssh2_error(session, LIBSSH2_ERROR_SOCKET_SEND,
"Unable to send userauth-publickey request", 0);
@@ -1186,7 +1186,7 @@ userauth_publickey_fromfile(LIBSSH2_SESSION *session,
&session->userauth_pblc_data_len, 0, NULL, 0,
&session->userauth_pblc_packet_requirev_state);
if (rc == PACKET_EAGAIN) {
return PACKET_EAGAIN;
return rc;
} else if (rc) {
session->userauth_pblc_state = libssh2_NB_state_idle;
return -1;
@@ -1326,7 +1326,7 @@ userauth_keyboard_interactive(LIBSSH2_SESSION * session,
rc = _libssh2_transport_write(session, session->userauth_kybd_data,
session->userauth_kybd_packet_len);
if (rc == PACKET_EAGAIN) {
return PACKET_EAGAIN;
return rc;
} else if (rc) {
libssh2_error(session, LIBSSH2_ERROR_SOCKET_SEND,
"Unable to send keyboard-interactive request", 0);
@@ -1350,7 +1350,7 @@ userauth_keyboard_interactive(LIBSSH2_SESSION * session,
&session->
userauth_kybd_packet_requirev_state);
if (rc == PACKET_EAGAIN) {
return PACKET_EAGAIN;
return rc;
} else if (rc) {
session->userauth_kybd_state = libssh2_NB_state_idle;
return -1;
@@ -1527,7 +1527,7 @@ userauth_keyboard_interactive(LIBSSH2_SESSION * session,
rc = _libssh2_transport_write(session, session->userauth_kybd_data,
session->userauth_kybd_packet_len);
if (rc == PACKET_EAGAIN) {
return PACKET_EAGAIN;
return rc;
}
if (rc) {
libssh2_error(session, LIBSSH2_ERROR_SOCKET_SEND,

View File

@@ -1,8 +0,0 @@
.deps
.libs
*.gcno
*.gcda
Makefile
Makefile.in
simple
ssh2

7
tests/.gitignore vendored
View File

@@ -1 +1,8 @@
.deps
.libs
*.gcno
*.gcda
Makefile
Makefile.in
simple
ssh2

View File

@@ -6,7 +6,7 @@ noinst_PROGRAMS = ssh2
ssh2_SOURCES = ssh2.c
endif
ctests = simple
ctests = simple$(EXEEXT)
TESTS = $(ctests)
if SSHD
TESTS += ssh2.sh

View File

@@ -10,12 +10,12 @@
#ifdef HAVE_WINSOCK2_H
# include <winsock2.h>
#endif
#ifdef HAVE_NETINET_IN_H
# include <netinet/in.h>
#endif
#ifdef HAVE_SYS_SOCKET_H
# include <sys/socket.h>
#endif
#ifdef HAVE_NETINET_IN_H
# include <netinet/in.h>
#endif
# ifdef HAVE_UNISTD_H
#include <unistd.h>
#endif

View File

@@ -9,15 +9,15 @@ 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 \
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" \

View File

@@ -121,8 +121,7 @@ endif
CFLAGS += $(INCLUDES)
#ifeq ($(findstring msys,$(OSTYPE)),msys)
ifdef __MSYS__
ifeq ($(findstring /sh,$(SHELL)),/sh)
DL = '
DS = /
else
@@ -131,24 +130,10 @@ endif
vpath %.c . ../src
OBJECTS = \
channel.o \
comp.o \
crypt.o \
hostkey.o \
kex.o \
mac.o \
misc.o \
openssl.o \
packet.o \
pem.o \
publickey.o \
scp.o \
session.o \
sftp.o \
transport.o \
userauth.o
# include Makefile.inc to get CSOURCES define
include ../Makefile.inc
OBJECTS := $(patsubst %.c,%.o,$(CSOURCES))
OBJS := $(addprefix $(OBJDIR)/,$(OBJECTS))
OBJL = $(OBJS) $(OBJDIR)/$(TARGET).res