Compare commits
88 Commits
libssh2-1.
...
libssh2-1.
Author | SHA1 | Date | |
---|---|---|---|
![]() |
355fbf4d5b | ||
![]() |
ebbd7c879b | ||
![]() |
b78f854d8b | ||
![]() |
1f0d47fa92 | ||
![]() |
463e09e55f | ||
![]() |
82bf39dbfa | ||
![]() |
e5f170bae2 | ||
![]() |
fc60563840 | ||
![]() |
b38b4fb859 | ||
![]() |
3182045c2d | ||
![]() |
60d73d5663 | ||
![]() |
1e80194b97 | ||
![]() |
0c13f7beda | ||
![]() |
b859f4d9d2 | ||
![]() |
13092c5a5e | ||
![]() |
22b73235d3 | ||
![]() |
55034294e8 | ||
![]() |
5e80055d22 | ||
![]() |
11ca8d5583 | ||
![]() |
9162fd7e61 | ||
![]() |
7208e8d0d9 | ||
![]() |
e1bb074287 | ||
![]() |
e887ffca4c | ||
![]() |
65d1cb8107 | ||
![]() |
4ed82f0e78 | ||
![]() |
3cc2f143c1 | ||
![]() |
683aa0f6b5 | ||
![]() |
7a9d36903a | ||
![]() |
c2375dbfa4 | ||
![]() |
906a7d8866 | ||
![]() |
1418993a0f | ||
![]() |
c4b7f0394b | ||
![]() |
9e84b999a5 | ||
![]() |
3fda91d725 | ||
![]() |
7c32c84d0e | ||
![]() |
766127ad57 | ||
![]() |
a9e7f87e31 | ||
![]() |
a04a0b6c69 | ||
![]() |
1f8d58a4ce | ||
![]() |
4b482eddbe | ||
![]() |
05eb612f8e | ||
![]() |
d48ee98ecf | ||
![]() |
536443246e | ||
![]() |
b728b1018f | ||
![]() |
3f5a6662d0 | ||
![]() |
33f4e0f250 | ||
![]() |
8dabb1c5eb | ||
![]() |
0d6aaa1f56 | ||
![]() |
00fac145ba | ||
![]() |
f65f71a156 | ||
![]() |
3142e8df7e | ||
![]() |
bffefb12ea | ||
![]() |
feadd5f321 | ||
![]() |
7c139633a1 | ||
![]() |
692401633a | ||
![]() |
5bb1fb5cbc | ||
![]() |
5e5ead00b4 | ||
![]() |
06278728e2 | ||
![]() |
0357befa42 | ||
![]() |
85198c1cdb | ||
![]() |
face4750ca | ||
![]() |
a1365916c7 | ||
![]() |
f64a84a909 | ||
![]() |
fba3877ed8 | ||
![]() |
f1e010f5d4 | ||
![]() |
9e96acf86e | ||
![]() |
1a157d27cc | ||
![]() |
b3418bb1eb | ||
![]() |
08be841b4d | ||
![]() |
e39128df52 | ||
![]() |
5c6b8166c7 | ||
![]() |
dcb9625473 | ||
![]() |
c1b687c9e4 | ||
![]() |
13e920d4ef | ||
![]() |
314e61e545 | ||
![]() |
13c16db3bc | ||
![]() |
82c3f0ba72 | ||
![]() |
9e099fb88a | ||
![]() |
415efe10ac | ||
![]() |
4b1cb4e95e | ||
![]() |
d8b6f3c7b8 | ||
![]() |
a871f0b214 | ||
![]() |
08cad8e14c | ||
![]() |
46178378f2 | ||
![]() |
28b179ecf2 | ||
![]() |
7b4d6b2868 | ||
![]() |
fbe4737719 | ||
![]() |
ce4ad0d086 |
28
.cvsignore
28
.cvsignore
@@ -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
|
|
11
.cvsusers
11
.cvsusers
@@ -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
2
.gitattribute
Normal file
@@ -0,0 +1,2 @@
|
|||||||
|
win32/msvcproj.head -crlf
|
||||||
|
win32/msvcproj.foot -crlf
|
1
.gitignore
vendored
1
.gitignore
vendored
@@ -30,3 +30,4 @@ install-sh
|
|||||||
*.lo
|
*.lo
|
||||||
*.la
|
*.la
|
||||||
mkinstalldirs
|
mkinstalldirs
|
||||||
|
tags
|
||||||
|
7
AUTHORS
7
AUTHORS
@@ -6,6 +6,7 @@
|
|||||||
Adam Gobiowski
|
Adam Gobiowski
|
||||||
Alexander Holyapin
|
Alexander Holyapin
|
||||||
Alexander Lamaison
|
Alexander Lamaison
|
||||||
|
Ben Kibbey
|
||||||
Bjorn Stenborg
|
Bjorn Stenborg
|
||||||
Carlo Bramini
|
Carlo Bramini
|
||||||
Dan Casey
|
Dan Casey
|
||||||
@@ -15,15 +16,19 @@ David J Sullivan
|
|||||||
David Robins
|
David Robins
|
||||||
Edink Kadribasic
|
Edink Kadribasic
|
||||||
Erik Brossler
|
Erik Brossler
|
||||||
|
Francois Dupoux
|
||||||
Guenter Knauf
|
Guenter Knauf
|
||||||
Heiner Steven
|
Heiner Steven
|
||||||
James Housleys
|
James Housleys
|
||||||
Jean-Louis Charton
|
Jean-Louis Charton
|
||||||
|
Jussi Mononen
|
||||||
|
Mark McPherson
|
||||||
Markus Moeller
|
Markus Moeller
|
||||||
Mike Protts
|
Mike Protts
|
||||||
Mikhail Gusarov
|
Mikhail Gusarov
|
||||||
Neil Gierman
|
Neil Gierman
|
||||||
Olivier Hervieu
|
Olivier Hervieu
|
||||||
|
Paul Veldkamp
|
||||||
Peter O'Gorman
|
Peter O'Gorman
|
||||||
Peter Stuge
|
Peter Stuge
|
||||||
Romain Bondue
|
Romain Bondue
|
||||||
@@ -34,6 +39,8 @@ Selcuk Gueney
|
|||||||
Simon Hart
|
Simon Hart
|
||||||
Simon Josefsson
|
Simon Josefsson
|
||||||
Steven Ayre
|
Steven Ayre
|
||||||
|
Steven Van Ingelgem
|
||||||
|
Tor Arntsen
|
||||||
Vincent Jaulin
|
Vincent Jaulin
|
||||||
Vlad Grachov
|
Vlad Grachov
|
||||||
Wez Furlong
|
Wez Furlong
|
||||||
|
1
COPYING
1
COPYING
@@ -1,6 +1,7 @@
|
|||||||
/* Copyright (c) 2004-2007 Sara Golemon <sarag@libssh2.org>
|
/* Copyright (c) 2004-2007 Sara Golemon <sarag@libssh2.org>
|
||||||
* Copyright (c) 2006-2007 The Written Word, Inc.
|
* Copyright (c) 2006-2007 The Written Word, Inc.
|
||||||
* Copyright (c) 2009 Daniel Stenberg
|
* Copyright (c) 2009 Daniel Stenberg
|
||||||
|
* Copyright (C) 2008, 2009 Simon Josefsson
|
||||||
* All rights reserved.
|
* All rights reserved.
|
||||||
*
|
*
|
||||||
* Redistribution and use in source and binary forms,
|
* Redistribution and use in source and binary forms,
|
||||||
|
11
HACKING
11
HACKING
@@ -9,14 +9,5 @@ libssh2 source code style guide:
|
|||||||
go_nuts();
|
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
|
- keep source lines shorter than 80 columns
|
||||||
|
- See libssh2-style.el for how to achieve this within Emacs
|
||||||
|
95
Makefile.am
95
Makefile.am
@@ -2,6 +2,9 @@ AUTOMAKE_OPTIONS = foreign nostdinc
|
|||||||
|
|
||||||
SUBDIRS = src example tests docs
|
SUBDIRS = src example tests docs
|
||||||
|
|
||||||
|
pkgconfigdir = $(libdir)/pkgconfig
|
||||||
|
pkgconfig_DATA = libssh2.pc
|
||||||
|
|
||||||
include_HEADERS = \
|
include_HEADERS = \
|
||||||
include/libssh2.h \
|
include/libssh2.h \
|
||||||
include/libssh2_publickey.h \
|
include/libssh2_publickey.h \
|
||||||
@@ -16,8 +19,7 @@ NETWAREFILES = nw/keepscreen.c \
|
|||||||
DSP = win32/libssh2.dsp
|
DSP = win32/libssh2.dsp
|
||||||
VCPROJ = win32/libssh2.vcproj
|
VCPROJ = win32/libssh2.vcproj
|
||||||
|
|
||||||
#Need to include $(VCPROJ) to CLEANFILES and WIN32FILES when I get a proper vc8proj.head|foot
|
DISTCLEANFILES = $(DSP)
|
||||||
CLEANFILES = $(DSP)
|
|
||||||
|
|
||||||
WIN32FILES = win32/Makefile.win32 win32/libssh2.dsw \
|
WIN32FILES = win32/Makefile.win32 win32/libssh2.dsw \
|
||||||
win32/config.mk win32/Makefile win32/test/Makefile.win32 \
|
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
|
win32/msvcproj.head win32/msvcproj.foot
|
||||||
|
|
||||||
EXTRA_DIST = $(WIN32FILES) buildconf $(NETWAREFILES) get_ver.awk HACKING \
|
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
|
ACLOCAL_AMFLAGS = -I m4
|
||||||
|
|
||||||
.PHONY: ChangeLog
|
.PHONY: ChangeLog
|
||||||
ChangeLog:
|
ChangeLog:
|
||||||
echo "see NEWS" > ./ChangeLog
|
echo "see NEWS" > ./ChangeLog
|
||||||
CLEANFILES += ChangeLog
|
DISTCLEANFILES += ChangeLog
|
||||||
|
|
||||||
dist-hook:
|
dist-hook:
|
||||||
rm -rf $(top_builddir)/tests/log
|
rm -rf $(top_builddir)/tests/log
|
||||||
@@ -73,55 +75,54 @@ include Makefile.inc
|
|||||||
WIN32SOURCES = $(CSOURCES)
|
WIN32SOURCES = $(CSOURCES)
|
||||||
WIN32HEADERS = $(HHEADERS) libssh2_config.h
|
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
|
$(DSP): win32/msvcproj.head win32/msvcproj.foot Makefile.am
|
||||||
echo "creating $(DSP)"
|
echo "creating $(DSP)"
|
||||||
@(cp $(srcdir)/win32/msvcproj.head $(DSP); \
|
@( (cat $(srcdir)/win32/msvcproj.head; \
|
||||||
echo "# Begin Group \"Source Files\"" $(DSPOUT); \
|
echo "# Begin Group \"Source Files\""; \
|
||||||
echo "" $(DSPOUT); \
|
echo ""; \
|
||||||
echo "# PROP Default_Filter \"cpp;c;cxx\"" $(DSPOUT); \
|
echo "# PROP Default_Filter \"cpp;c;cxx\""; \
|
||||||
win32_srcs='$(WIN32SOURCES)'; \
|
win32_srcs='$(WIN32SOURCES)'; \
|
||||||
sorted_srcs=`for file in $$win32_srcs; do echo $$file; done | sort`; \
|
sorted_srcs=`for file in $$win32_srcs; do echo $$file; done | sort`; \
|
||||||
for file in $$sorted_srcs; do \
|
for file in $$sorted_srcs; do \
|
||||||
echo "# Begin Source File" $(DSPOUT); \
|
echo "# Begin Source File"; \
|
||||||
echo "" $(DSPOUT); \
|
echo ""; \
|
||||||
echo "SOURCE=..\\src\\"$$file $(DSPOUT); \
|
echo "SOURCE=..\\src\\"$$file; \
|
||||||
echo "# End Source File" $(DSPOUT); \
|
echo "# End Source File"; \
|
||||||
done; \
|
done; \
|
||||||
echo "# End Group" $(DSPOUT); \
|
echo "# End Group"; \
|
||||||
echo "# Begin Group \"Header Files\"" $(DSPOUT); \
|
echo "# Begin Group \"Header Files\""; \
|
||||||
echo "" $(DSPOUT); \
|
echo ""; \
|
||||||
echo "# PROP Default_Filter \"h;hpp;hxx\"" $(DSPOUT); \
|
echo "# PROP Default_Filter \"h;hpp;hxx\""; \
|
||||||
win32_hdrs='$(WIN32HEADERS)'; \
|
win32_hdrs='$(WIN32HEADERS)'; \
|
||||||
sorted_hdrs=`for file in $$win32_hdrs; do echo $$file; done | sort`; \
|
sorted_hdrs=`for file in $$win32_hdrs; do echo $$file; done | sort`; \
|
||||||
for file in $$sorted_hdrs; do \
|
for file in $$sorted_hdrs; do \
|
||||||
echo "# Begin Source File" $(DSPOUT); \
|
echo "# Begin Source File"; \
|
||||||
echo "" $(DSPOUT); \
|
echo ""; \
|
||||||
if [ "$$file" == "libssh2_config.h" ]; \
|
if [ "$$file" == "libssh2_config.h" ]; \
|
||||||
then \
|
then \
|
||||||
echo "SOURCE=.\\"$$file $(DSPOUT); \
|
echo "SOURCE=.\\"$$file; \
|
||||||
else \
|
else \
|
||||||
echo "SOURCE=..\\src\\"$$file $(DSPOUT); \
|
echo "SOURCE=..\\src\\"$$file; \
|
||||||
fi; \
|
fi; \
|
||||||
echo "# End Source File" $(DSPOUT); \
|
echo "# End Source File"; \
|
||||||
done; \
|
done; \
|
||||||
echo "# End Group" $(DSPOUT); \
|
echo "# End Group"; \
|
||||||
cat $(srcdir)/win32/msvcproj.foot $(DSPOUT) )
|
cat $(srcdir)/win32/msvcproj.foot) | \
|
||||||
|
awk '{printf("%s\r\n", gensub("\r", "", "g"))}' > $@ )
|
||||||
|
|
||||||
$(VCPROJ): win32/vc8proj.head win32/vc8proj.foot Makefile.am
|
$(VCPROJ): win32/vc8proj.head win32/vc8proj.foot Makefile.am
|
||||||
echo "creating $(VCPROJ)"
|
echo "creating $(VCPROJ)"
|
||||||
@(cp $(srcdir)/vc8proj.head $(VCPROJ); \
|
@( (cat $(srcdir)/vc8proj.head; \
|
||||||
win32_srcs='$(WIN32SOURCES)'; \
|
win32_srcs='$(WIN32SOURCES)'; \
|
||||||
sorted_srcs=`for file in $$win32_srcs; do echo $$file; done | sort`; \
|
sorted_srcs=`for file in $$win32_srcs; do echo $$file; done | sort`; \
|
||||||
for file in $$sorted_srcs; do \
|
for file in $$sorted_srcs; do \
|
||||||
echo "<File RelativePath=\""..\src\$$file"\"></File>" $(VCPROJOUT); \
|
echo "<File RelativePath=\""..\src\$$file"\"></File>"; \
|
||||||
done; \
|
done; \
|
||||||
echo "</Filter><Filter Name=\"Header Files\">" $(VCPROJOUT); \
|
echo "</Filter><Filter Name=\"Header Files\">"; \
|
||||||
win32_hdrs='$(WIN32HEADERS)'; \
|
win32_hdrs='$(WIN32HEADERS)'; \
|
||||||
sorted_hdrs=`for file in $$win32_hdrs; do echo $$file; done | sort`; \
|
sorted_hdrs=`for file in $$win32_hdrs; do echo $$file; done | sort`; \
|
||||||
for file in $$sorted_hdrs; do \
|
for file in $$sorted_hdrs; do \
|
||||||
echo "<File RelativePath=\""..\src\$$file"\"></File>" $(VCPROJOUT); \
|
echo "<File RelativePath=\""..\src\$$file"\"></File>"; \
|
||||||
done; \
|
done; \
|
||||||
cat $(srcdir)/vc8proj.foot $(VCPROJOUT) )
|
cat $(srcdir)/vc8proj.foot) | \
|
||||||
|
awk '{printf("%s\r\n", gensub("\r", "", "g"))}' > $@ )
|
||||||
|
10
Makefile.inc
10
Makefile.inc
@@ -1,11 +1,5 @@
|
|||||||
CSOURCES = channel.c comp.c crypt.c hostkey.c kex.c mac.c misc.c \
|
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 \
|
packet.c publickey.c scp.c session.c sftp.c userauth.c transport.c \
|
||||||
version.c knownhost.c
|
version.c knownhost.c openssl.c libgcrypt.c pem.c
|
||||||
|
|
||||||
if LIBGCRYPT
|
HHEADERS = libssh2_priv.h openssl.h libgcrypt.h transport.h channel.h comp.h mac.h misc.h
|
||||||
CSOURCES += libgcrypt.c pem.c
|
|
||||||
else
|
|
||||||
CSOURCES += openssl.c
|
|
||||||
endif
|
|
||||||
|
|
||||||
HHEADERS = libssh2_priv.h openssl.h libgcrypt.h transport.h channel.h comp.h mac.h misc.h
|
|
||||||
|
45
NEWS
45
NEWS
@@ -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)
|
Version 1.2 (August 10, 2009)
|
||||||
-----------------------------
|
-----------------------------
|
||||||
|
|
||||||
|
@@ -1,40 +1,18 @@
|
|||||||
libssh2 1.2
|
libssh2 1.2.2
|
||||||
|
|
||||||
This release includes the following changes:
|
This release includes the following changes:
|
||||||
|
|
||||||
o we've switched to using git for source code control
|
o Support for the "aes128-ctr", "aes192-ctr", "aes256-ctr" ciphers
|
||||||
o we're offering an alternative web site at http://libssh2.haxx.se/
|
o Support for the "arcfour128" cipher
|
||||||
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
|
|
||||||
|
|
||||||
This release includes the following bugfixes:
|
This release includes the following bugfixes:
|
||||||
|
|
||||||
o bad 0-return from libssh2_channel_read
|
o Fix crash when server sends an invalid SSH_MSG_IGNORE message
|
||||||
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
|
|
||||||
|
|
||||||
This release would not have looked like this without help, code, reports and
|
This release would not have looked like this without help, code, reports and
|
||||||
advice from friends like these:
|
advice from friends like these:
|
||||||
|
|
||||||
Simon Josefsson, Neil Gierman, Alexander Lamaison, Peter Stuge,
|
Simon Josefsson, Bob Alexander
|
||||||
Steven Van Ingelgem, Ben Kibbey, Francois Dupoux, Mark McPherson,
|
|
||||||
Guenter Knauf, Yang Tse, Tor Arntsen, Jussi Mononen, Olivier Hervieu,
|
|
||||||
Paul Veldkamp
|
|
||||||
|
|
||||||
Thanks! (and sorry if I forgot to mention someone)
|
Thanks! (and sorry if I forgot to mention someone)
|
||||||
|
3
TODO
3
TODO
@@ -8,9 +8,6 @@ Things TODO
|
|||||||
|
|
||||||
* Provide a libssh2_scp_send() API for files larger than 4GB (32bit size)
|
* 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.
|
* Add more info to the man pages.
|
||||||
|
|
||||||
* Decrease the number of mallocs. Everywhere.
|
* Decrease the number of mallocs. Everywhere.
|
||||||
|
@@ -297,7 +297,7 @@ dnl Internal macro for CURL_CONFIGURE_REENTRANT.
|
|||||||
|
|
||||||
AC_DEFUN([CURL_CHECK_NEED_REENTRANT_SYSTEM], [
|
AC_DEFUN([CURL_CHECK_NEED_REENTRANT_SYSTEM], [
|
||||||
case $host in
|
case $host in
|
||||||
*-*-solaris*)
|
*-*-solaris* | *-*-hpux*)
|
||||||
tmp_need_reentrant="yes"
|
tmp_need_reentrant="yes"
|
||||||
;;
|
;;
|
||||||
*)
|
*)
|
||||||
|
@@ -162,6 +162,45 @@ AC_HELP_STRING([--disable-debug],[Disable debug options]),
|
|||||||
AC_MSG_RESULT(no)
|
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.
|
# Checks for header files.
|
||||||
# AC_HEADER_STDC
|
# AC_HEADER_STDC
|
||||||
AC_CHECK_HEADERS([errno.h fcntl.h stdio.h stdlib.h unistd.h sys/uio.h])
|
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
|
tests/Makefile
|
||||||
example/Makefile
|
example/Makefile
|
||||||
example/simple/Makefile
|
example/simple/Makefile
|
||||||
docs/Makefile])
|
docs/Makefile
|
||||||
|
libssh2.pc])
|
||||||
AC_OUTPUT
|
AC_OUTPUT
|
0
docs/.cvsignore → docs/.gitignore
vendored
0
docs/.cvsignore → docs/.gitignore
vendored
@@ -40,6 +40,7 @@ dist_man_MANS = \
|
|||||||
libssh2_knownhost_del.3 \
|
libssh2_knownhost_del.3 \
|
||||||
libssh2_knownhost_get.3 \
|
libssh2_knownhost_get.3 \
|
||||||
libssh2_knownhost_init.3 \
|
libssh2_knownhost_init.3 \
|
||||||
|
libssh2_knownhost_free.3 \
|
||||||
libssh2_knownhost_readfile.3 \
|
libssh2_knownhost_readfile.3 \
|
||||||
libssh2_knownhost_readline.3 \
|
libssh2_knownhost_readline.3 \
|
||||||
libssh2_knownhost_writefile.3 \
|
libssh2_knownhost_writefile.3 \
|
||||||
|
@@ -35,6 +35,9 @@ macros.
|
|||||||
Actual number of bytes read or negative on failure. It returns
|
Actual number of bytes read or negative on failure. It returns
|
||||||
LIBSSH2_ERROR_EAGAIN when it would otherwise block. While
|
LIBSSH2_ERROR_EAGAIN when it would otherwise block. While
|
||||||
LIBSSH2_ERROR_EAGAIN is a negative number, it isn't really a failure per se.
|
LIBSSH2_ERROR_EAGAIN is a negative number, it isn't really a failure per se.
|
||||||
|
|
||||||
|
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
|
.SH ERRORS
|
||||||
\fILIBSSH2_ERROR_SOCKET_SEND\fP - Unable to send data on socket.
|
\fILIBSSH2_ERROR_SOCKET_SEND\fP - Unable to send data on socket.
|
||||||
|
|
||||||
|
21
docs/libssh2_knownhost_free.3
Normal file
21
docs/libssh2_knownhost_free.3
Normal 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)
|
@@ -11,6 +11,9 @@ LIBSSH2_KNOWNHOSTS *libssh2_knownhost_init(LIBSSH2_SESSION *session);
|
|||||||
.SH DESCRIPTION
|
.SH DESCRIPTION
|
||||||
Init a collection of known hosts for this session. Returns the handle to an
|
Init a collection of known hosts for this session. Returns the handle to an
|
||||||
internal representation of a known host collection.
|
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
|
.SH RETURN VALUE
|
||||||
Returns a handle pointer or NULL if something went wrong. The returned handle
|
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.
|
is used as input to all other known host related functions libssh2 provides.
|
||||||
|
@@ -13,7 +13,8 @@ libssh2_scp_recv(LIBSSH2_SESSION *session, const char *path, struct stat *sb);
|
|||||||
\fIsession\fP - Session instance as returned by
|
\fIsession\fP - Session instance as returned by
|
||||||
.BR libssh2_session_init_ex(3)
|
.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
|
\fIsb\fP - Populated with remote file's size, mode, mtime, and atime
|
||||||
|
|
||||||
|
@@ -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
|
\fIsession\fP - Session instance as returned by
|
||||||
.BR libssh2_session_init_ex(3)
|
.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
|
\fImode\fP - File access mode to create file with
|
||||||
|
|
||||||
|
0
example/.cvsignore → example/.gitignore
vendored
0
example/.cvsignore → example/.gitignore
vendored
@@ -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
|
|
||||||
|
|
@@ -10,12 +10,12 @@
|
|||||||
#ifdef HAVE_WINSOCK2_H
|
#ifdef HAVE_WINSOCK2_H
|
||||||
# include <winsock2.h>
|
# include <winsock2.h>
|
||||||
#endif
|
#endif
|
||||||
#ifdef HAVE_NETINET_IN_H
|
|
||||||
# include <netinet/in.h>
|
|
||||||
#endif
|
|
||||||
#ifdef HAVE_SYS_SOCKET_H
|
#ifdef HAVE_SYS_SOCKET_H
|
||||||
# include <sys/socket.h>
|
# include <sys/socket.h>
|
||||||
#endif
|
#endif
|
||||||
|
#ifdef HAVE_NETINET_IN_H
|
||||||
|
# include <netinet/in.h>
|
||||||
|
#endif
|
||||||
# ifdef HAVE_UNISTD_H
|
# ifdef HAVE_UNISTD_H
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
#endif
|
#endif
|
||||||
|
@@ -15,11 +15,14 @@
|
|||||||
#ifdef HAVE_WINSOCK2_H
|
#ifdef HAVE_WINSOCK2_H
|
||||||
# include <winsock2.h>
|
# include <winsock2.h>
|
||||||
#endif
|
#endif
|
||||||
|
#ifdef HAVE_SYS_SOCKET_H
|
||||||
|
# include <sys/socket.h>
|
||||||
|
#endif
|
||||||
#ifdef HAVE_NETINET_IN_H
|
#ifdef HAVE_NETINET_IN_H
|
||||||
# include <netinet/in.h>
|
# include <netinet/in.h>
|
||||||
#endif
|
#endif
|
||||||
#ifdef HAVE_SYS_SOCKET_H
|
#ifdef HAVE_SYS_SELECT_H
|
||||||
# include <sys/socket.h>
|
# include <sys/select.h>
|
||||||
#endif
|
#endif
|
||||||
# ifdef HAVE_UNISTD_H
|
# ifdef HAVE_UNISTD_H
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
|
@@ -10,12 +10,12 @@
|
|||||||
#ifdef HAVE_WINSOCK2_H
|
#ifdef HAVE_WINSOCK2_H
|
||||||
# include <winsock2.h>
|
# include <winsock2.h>
|
||||||
#endif
|
#endif
|
||||||
#ifdef HAVE_NETINET_IN_H
|
|
||||||
# include <netinet/in.h>
|
|
||||||
#endif
|
|
||||||
#ifdef HAVE_SYS_SOCKET_H
|
#ifdef HAVE_SYS_SOCKET_H
|
||||||
# include <sys/socket.h>
|
# include <sys/socket.h>
|
||||||
#endif
|
#endif
|
||||||
|
#ifdef HAVE_NETINET_IN_H
|
||||||
|
# include <netinet/in.h>
|
||||||
|
#endif
|
||||||
# ifdef HAVE_UNISTD_H
|
# ifdef HAVE_UNISTD_H
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
#endif
|
#endif
|
||||||
@@ -47,7 +47,7 @@ int main(int argc, char *argv[])
|
|||||||
FILE *local;
|
FILE *local;
|
||||||
int rc;
|
int rc;
|
||||||
char mem[1024];
|
char mem[1024];
|
||||||
size_t nread;
|
size_t nread, sent;
|
||||||
char *ptr;
|
char *ptr;
|
||||||
struct stat fileinfo;
|
struct stat fileinfo;
|
||||||
|
|
||||||
@@ -142,8 +142,8 @@ int main(int argc, char *argv[])
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Request a file via SCP */
|
/* Send a file via scp. The mode parameter must only have permissions! */
|
||||||
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);
|
(unsigned long)fileinfo.st_size);
|
||||||
|
|
||||||
if (!channel) {
|
if (!channel) {
|
||||||
@@ -159,13 +159,20 @@ int main(int argc, char *argv[])
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
ptr = mem;
|
ptr = mem;
|
||||||
|
sent = 0;
|
||||||
|
|
||||||
do {
|
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);
|
rc = libssh2_channel_write(channel, ptr, nread);
|
||||||
ptr += rc;
|
if (rc < 0) {
|
||||||
nread -= nread;
|
fprintf(stderr, "ERROR %d\n", rc);
|
||||||
} while (rc > 0);
|
} else {
|
||||||
|
/* rc indicates how many bytes were written this time */
|
||||||
|
sent += rc;
|
||||||
|
}
|
||||||
|
} while (rc > 0 && sent < nread);
|
||||||
|
ptr += sent;
|
||||||
|
nread -= sent;
|
||||||
} while (1);
|
} while (1);
|
||||||
|
|
||||||
fprintf(stderr, "Sending EOF\n");
|
fprintf(stderr, "Sending EOF\n");
|
||||||
|
@@ -11,12 +11,12 @@
|
|||||||
#ifdef HAVE_WINSOCK2_H
|
#ifdef HAVE_WINSOCK2_H
|
||||||
# include <winsock2.h>
|
# include <winsock2.h>
|
||||||
#endif
|
#endif
|
||||||
#ifdef HAVE_NETINET_IN_H
|
|
||||||
# include <netinet/in.h>
|
|
||||||
#endif
|
|
||||||
#ifdef HAVE_SYS_SOCKET_H
|
#ifdef HAVE_SYS_SOCKET_H
|
||||||
# include <sys/socket.h>
|
# include <sys/socket.h>
|
||||||
#endif
|
#endif
|
||||||
|
#ifdef HAVE_NETINET_IN_H
|
||||||
|
# include <netinet/in.h>
|
||||||
|
#endif
|
||||||
# ifdef HAVE_UNISTD_H
|
# ifdef HAVE_UNISTD_H
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
#endif
|
#endif
|
||||||
@@ -51,7 +51,7 @@ int main(int argc, char *argv[])
|
|||||||
long flag = 1;
|
long flag = 1;
|
||||||
#endif
|
#endif
|
||||||
char mem[1024];
|
char mem[1024];
|
||||||
size_t nread;
|
size_t nread, sent;
|
||||||
char *ptr;
|
char *ptr;
|
||||||
struct stat fileinfo;
|
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 {
|
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);
|
(unsigned long)fileinfo.st_size);
|
||||||
|
|
||||||
if ((!channel) && (libssh2_session_last_errno(session) !=
|
if ((!channel) && (libssh2_session_last_errno(session) !=
|
||||||
@@ -176,17 +176,22 @@ int main(int argc, char *argv[])
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
ptr = mem;
|
ptr = mem;
|
||||||
|
sent = 0;
|
||||||
|
|
||||||
do {
|
do {
|
||||||
/* write data in a loop until we block */
|
/* write the same data over and over, until error or completion */
|
||||||
while ((rc = libssh2_channel_write(channel, ptr, nread)) ==
|
rc = libssh2_channel_write(channel, ptr, nread);
|
||||||
LIBSSH2_ERROR_EAGAIN);
|
if (LIBSSH2_ERROR_EAGAIN == rc) { /* must loop around */
|
||||||
if (rc < 0) {
|
continue;
|
||||||
|
} else if (rc < 0) {
|
||||||
fprintf(stderr, "ERROR %d\n", rc);
|
fprintf(stderr, "ERROR %d\n", rc);
|
||||||
|
} else {
|
||||||
|
/* rc indicates how many bytes were written this time */
|
||||||
|
sent += rc;
|
||||||
}
|
}
|
||||||
ptr += rc;
|
} while (rc > 0 && sent < nread);
|
||||||
nread -= rc;
|
ptr += sent;
|
||||||
} while (nread > 0);
|
nread -= sent;
|
||||||
} while (1);
|
} while (1);
|
||||||
|
|
||||||
fprintf(stderr, "Sending EOF\n");
|
fprintf(stderr, "Sending EOF\n");
|
||||||
|
@@ -16,12 +16,12 @@
|
|||||||
#ifdef HAVE_WINSOCK2_H
|
#ifdef HAVE_WINSOCK2_H
|
||||||
# include <winsock2.h>
|
# include <winsock2.h>
|
||||||
#endif
|
#endif
|
||||||
#ifdef HAVE_NETINET_IN_H
|
|
||||||
# include <netinet/in.h>
|
|
||||||
#endif
|
|
||||||
#ifdef HAVE_SYS_SOCKET_H
|
#ifdef HAVE_SYS_SOCKET_H
|
||||||
# include <sys/socket.h>
|
# include <sys/socket.h>
|
||||||
#endif
|
#endif
|
||||||
|
#ifdef HAVE_NETINET_IN_H
|
||||||
|
# include <netinet/in.h>
|
||||||
|
#endif
|
||||||
# ifdef HAVE_UNISTD_H
|
# ifdef HAVE_UNISTD_H
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
#endif
|
#endif
|
||||||
|
@@ -16,11 +16,14 @@
|
|||||||
#ifdef HAVE_WINSOCK2_H
|
#ifdef HAVE_WINSOCK2_H
|
||||||
# include <winsock2.h>
|
# include <winsock2.h>
|
||||||
#endif
|
#endif
|
||||||
|
#ifdef HAVE_SYS_SOCKET_H
|
||||||
|
# include <sys/socket.h>
|
||||||
|
#endif
|
||||||
#ifdef HAVE_NETINET_IN_H
|
#ifdef HAVE_NETINET_IN_H
|
||||||
# include <netinet/in.h>
|
# include <netinet/in.h>
|
||||||
#endif
|
#endif
|
||||||
#ifdef HAVE_SYS_SOCKET_H
|
#ifdef HAVE_SYS_SELECT_H
|
||||||
# include <sys/socket.h>
|
# include <sys/select.h>
|
||||||
#endif
|
#endif
|
||||||
# ifdef HAVE_UNISTD_H
|
# ifdef HAVE_UNISTD_H
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
|
@@ -16,12 +16,12 @@
|
|||||||
#ifdef HAVE_WINSOCK2_H
|
#ifdef HAVE_WINSOCK2_H
|
||||||
# include <winsock2.h>
|
# include <winsock2.h>
|
||||||
#endif
|
#endif
|
||||||
#ifdef HAVE_NETINET_IN_H
|
|
||||||
# include <netinet/in.h>
|
|
||||||
#endif
|
|
||||||
#ifdef HAVE_SYS_SOCKET_H
|
#ifdef HAVE_SYS_SOCKET_H
|
||||||
# include <sys/socket.h>
|
# include <sys/socket.h>
|
||||||
#endif
|
#endif
|
||||||
|
#ifdef HAVE_NETINET_IN_H
|
||||||
|
# include <netinet/in.h>
|
||||||
|
#endif
|
||||||
# ifdef HAVE_UNISTD_H
|
# ifdef HAVE_UNISTD_H
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
#endif
|
#endif
|
||||||
|
@@ -16,12 +16,12 @@
|
|||||||
#ifdef HAVE_WINSOCK2_H
|
#ifdef HAVE_WINSOCK2_H
|
||||||
# include <winsock2.h>
|
# include <winsock2.h>
|
||||||
#endif
|
#endif
|
||||||
#ifdef HAVE_NETINET_IN_H
|
|
||||||
# include <netinet/in.h>
|
|
||||||
#endif
|
|
||||||
#ifdef HAVE_SYS_SOCKET_H
|
#ifdef HAVE_SYS_SOCKET_H
|
||||||
# include <sys/socket.h>
|
# include <sys/socket.h>
|
||||||
#endif
|
#endif
|
||||||
|
#ifdef HAVE_NETINET_IN_H
|
||||||
|
# include <netinet/in.h>
|
||||||
|
#endif
|
||||||
# ifdef HAVE_UNISTD_H
|
# ifdef HAVE_UNISTD_H
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
#endif
|
#endif
|
||||||
|
@@ -16,11 +16,14 @@
|
|||||||
#ifdef HAVE_WINSOCK2_H
|
#ifdef HAVE_WINSOCK2_H
|
||||||
# include <winsock2.h>
|
# include <winsock2.h>
|
||||||
#endif
|
#endif
|
||||||
|
#ifdef HAVE_SYS_SOCKET_H
|
||||||
|
# include <sys/socket.h>
|
||||||
|
#endif
|
||||||
#ifdef HAVE_NETINET_IN_H
|
#ifdef HAVE_NETINET_IN_H
|
||||||
# include <netinet/in.h>
|
# include <netinet/in.h>
|
||||||
#endif
|
#endif
|
||||||
#ifdef HAVE_SYS_SOCKET_H
|
#ifdef HAVE_SYS_SELECT_H
|
||||||
# include <sys/socket.h>
|
# include <sys/select.h>
|
||||||
#endif
|
#endif
|
||||||
# ifdef HAVE_UNISTD_H
|
# ifdef HAVE_UNISTD_H
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
|
@@ -16,12 +16,12 @@
|
|||||||
#ifdef HAVE_WINSOCK2_H
|
#ifdef HAVE_WINSOCK2_H
|
||||||
# include <winsock2.h>
|
# include <winsock2.h>
|
||||||
#endif
|
#endif
|
||||||
#ifdef HAVE_NETINET_IN_H
|
|
||||||
# include <netinet/in.h>
|
|
||||||
#endif
|
|
||||||
#ifdef HAVE_SYS_SOCKET_H
|
#ifdef HAVE_SYS_SOCKET_H
|
||||||
# include <sys/socket.h>
|
# include <sys/socket.h>
|
||||||
#endif
|
#endif
|
||||||
|
#ifdef HAVE_NETINET_IN_H
|
||||||
|
# include <netinet/in.h>
|
||||||
|
#endif
|
||||||
# ifdef HAVE_UNISTD_H
|
# ifdef HAVE_UNISTD_H
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
#endif
|
#endif
|
||||||
|
@@ -16,12 +16,12 @@
|
|||||||
#ifdef HAVE_WINSOCK2_H
|
#ifdef HAVE_WINSOCK2_H
|
||||||
# include <winsock2.h>
|
# include <winsock2.h>
|
||||||
#endif
|
#endif
|
||||||
#ifdef HAVE_NETINET_IN_H
|
|
||||||
# include <netinet/in.h>
|
|
||||||
#endif
|
|
||||||
#ifdef HAVE_SYS_SOCKET_H
|
#ifdef HAVE_SYS_SOCKET_H
|
||||||
# include <sys/socket.h>
|
# include <sys/socket.h>
|
||||||
#endif
|
#endif
|
||||||
|
#ifdef HAVE_NETINET_IN_H
|
||||||
|
# include <netinet/in.h>
|
||||||
|
#endif
|
||||||
# ifdef HAVE_UNISTD_H
|
# ifdef HAVE_UNISTD_H
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
#endif
|
#endif
|
||||||
|
@@ -16,12 +16,12 @@
|
|||||||
#ifdef HAVE_WINSOCK2_H
|
#ifdef HAVE_WINSOCK2_H
|
||||||
# include <winsock2.h>
|
# include <winsock2.h>
|
||||||
#endif
|
#endif
|
||||||
#ifdef HAVE_NETINET_IN_H
|
|
||||||
# include <netinet/in.h>
|
|
||||||
#endif
|
|
||||||
#ifdef HAVE_SYS_SOCKET_H
|
#ifdef HAVE_SYS_SOCKET_H
|
||||||
# include <sys/socket.h>
|
# include <sys/socket.h>
|
||||||
#endif
|
#endif
|
||||||
|
#ifdef HAVE_NETINET_IN_H
|
||||||
|
# include <netinet/in.h>
|
||||||
|
#endif
|
||||||
# ifdef HAVE_UNISTD_H
|
# ifdef HAVE_UNISTD_H
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
#endif
|
#endif
|
||||||
|
@@ -16,12 +16,12 @@
|
|||||||
#ifdef HAVE_WINSOCK2_H
|
#ifdef HAVE_WINSOCK2_H
|
||||||
# include <winsock2.h>
|
# include <winsock2.h>
|
||||||
#endif
|
#endif
|
||||||
#ifdef HAVE_NETINET_IN_H
|
|
||||||
# include <netinet/in.h>
|
|
||||||
#endif
|
|
||||||
#ifdef HAVE_SYS_SOCKET_H
|
#ifdef HAVE_SYS_SOCKET_H
|
||||||
# include <sys/socket.h>
|
# include <sys/socket.h>
|
||||||
#endif
|
#endif
|
||||||
|
#ifdef HAVE_NETINET_IN_H
|
||||||
|
# include <netinet/in.h>
|
||||||
|
#endif
|
||||||
# ifdef HAVE_UNISTD_H
|
# ifdef HAVE_UNISTD_H
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
#endif
|
#endif
|
||||||
|
@@ -19,12 +19,12 @@
|
|||||||
#ifdef HAVE_WINSOCK2_H
|
#ifdef HAVE_WINSOCK2_H
|
||||||
# include <winsock2.h>
|
# include <winsock2.h>
|
||||||
#endif
|
#endif
|
||||||
#ifdef HAVE_NETINET_IN_H
|
|
||||||
# include <netinet/in.h>
|
|
||||||
#endif
|
|
||||||
#ifdef HAVE_SYS_SOCKET_H
|
#ifdef HAVE_SYS_SOCKET_H
|
||||||
# include <sys/socket.h>
|
# include <sys/socket.h>
|
||||||
#endif
|
#endif
|
||||||
|
#ifdef HAVE_NETINET_IN_H
|
||||||
|
# include <netinet/in.h>
|
||||||
|
#endif
|
||||||
# ifdef HAVE_UNISTD_H
|
# ifdef HAVE_UNISTD_H
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
#endif
|
#endif
|
||||||
|
@@ -18,11 +18,14 @@
|
|||||||
#ifdef HAVE_WINSOCK2_H
|
#ifdef HAVE_WINSOCK2_H
|
||||||
# include <winsock2.h>
|
# include <winsock2.h>
|
||||||
#endif
|
#endif
|
||||||
|
#ifdef HAVE_SYS_SOCKET_H
|
||||||
|
# include <sys/socket.h>
|
||||||
|
#endif
|
||||||
#ifdef HAVE_NETINET_IN_H
|
#ifdef HAVE_NETINET_IN_H
|
||||||
# include <netinet/in.h>
|
# include <netinet/in.h>
|
||||||
#endif
|
#endif
|
||||||
#ifdef HAVE_SYS_SOCKET_H
|
#ifdef HAVE_SYS_SELECT_H
|
||||||
# include <sys/socket.h>
|
# include <sys/select.h>
|
||||||
#endif
|
#endif
|
||||||
# ifdef HAVE_UNISTD_H
|
# ifdef HAVE_UNISTD_H
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
|
@@ -84,17 +84,17 @@ typedef unsigned long long libssh2_uint64_t;
|
|||||||
typedef long long libssh2_int64_t;
|
typedef long long libssh2_int64_t;
|
||||||
#endif
|
#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
|
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
|
banner. Release versions have no appended strings and may of course not
|
||||||
have dashes either. */
|
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
|
/* The numeric version number is also available "in parts" by using these
|
||||||
defines: */
|
defines: */
|
||||||
#define LIBSSH2_VERSION_MAJOR 1
|
#define LIBSSH2_VERSION_MAJOR 1
|
||||||
#define LIBSSH2_VERSION_MINOR 1
|
#define LIBSSH2_VERSION_MINOR 2
|
||||||
#define LIBSSH2_VERSION_PATCH 1
|
#define LIBSSH2_VERSION_PATCH 2
|
||||||
|
|
||||||
/* This is the numeric version of the libssh2 version number, meant for easier
|
/* This is the numeric version of the libssh2 version number, meant for easier
|
||||||
parsing and comparions by programs. The LIBSSH2_VERSION_NUM define will
|
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
|
and it is always a greater number in a more recent release. It makes
|
||||||
comparisons with greater than and less than work.
|
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
|
* 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
|
* timestamp is not stored in the source code repo, as the timestamp is
|
||||||
* tarballs by the maketgz script.
|
* properly set in the tarballs by the maketgz script.
|
||||||
*
|
*
|
||||||
* The format of the date should follow this template:
|
* The format of the date should follow this template:
|
||||||
*
|
*
|
||||||
* "Mon Feb 12 11:35:33 UTC 2007"
|
* "Mon Feb 12 11:35:33 UTC 2007"
|
||||||
*/
|
*/
|
||||||
#define LIBSSH2_TIMESTAMP "CVS"
|
#define LIBSSH2_TIMESTAMP "DEV"
|
||||||
|
|
||||||
/* Part of every banner, user specified or not */
|
/* Part of every banner, user specified or not */
|
||||||
#define LIBSSH2_SSH_BANNER "SSH-2.0-libssh2_" LIBSSH2_VERSION
|
#define LIBSSH2_SSH_BANNER "SSH-2.0-libssh2_" LIBSSH2_VERSION
|
||||||
@@ -356,6 +356,9 @@ typedef struct _LIBSSH2_POLLFD {
|
|||||||
#define LIBSSH2_ERROR_PUBLICKEY_PROTOCOL -36
|
#define LIBSSH2_ERROR_PUBLICKEY_PROTOCOL -36
|
||||||
#define LIBSSH2_ERROR_EAGAIN -37
|
#define LIBSSH2_ERROR_EAGAIN -37
|
||||||
#define LIBSSH2_ERROR_BUFFER_TOO_SMALL -38
|
#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 */
|
/* Session API */
|
||||||
LIBSSH2_API LIBSSH2_SESSION *
|
LIBSSH2_API LIBSSH2_SESSION *
|
||||||
@@ -675,6 +678,7 @@ LIBSSH2_API
|
|||||||
const char *libssh2_version(int req_version_num);
|
const char *libssh2_version(int req_version_num);
|
||||||
|
|
||||||
#define HAVE_LIBSSH2_KNOWNHOST_API 0x010101 /* since 1.1.1 */
|
#define HAVE_LIBSSH2_KNOWNHOST_API 0x010101 /* since 1.1.1 */
|
||||||
|
#define HAVE_LIBSSH2_VERSION_API 0x010100 /* libssh2_version since 1.1 */
|
||||||
|
|
||||||
struct libssh2_knownhost {
|
struct libssh2_knownhost {
|
||||||
unsigned int magic; /* magic stored by the library */
|
unsigned int magic; /* magic stored by the library */
|
||||||
|
16
libssh2.pc.in
Normal file
16
libssh2.pc.in
Normal 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}
|
@@ -96,7 +96,7 @@ LIBARCH_L = $(shell $(AWK) 'BEGIN {print tolower(ARGV[1])}' $(LIBARCH))
|
|||||||
-include $(OBJDIR)/version.inc
|
-include $(OBJDIR)/version.inc
|
||||||
|
|
||||||
# Global flags for all compilers
|
# Global flags for all compilers
|
||||||
CFLAGS = $(OPT) -D$(DB) -DNETWARE -nostdinc
|
CFLAGS += $(OPT) -D$(DB) -DNETWARE -nostdinc
|
||||||
#CFLAGS += -DHAVE_CONFIG_H
|
#CFLAGS += -DHAVE_CONFIG_H
|
||||||
|
|
||||||
ifeq ($(CC),mwccnlm)
|
ifeq ($(CC),mwccnlm)
|
||||||
@@ -184,8 +184,7 @@ ifdef XDCOPT
|
|||||||
XDCDATA = $(OBJDIR)/$(TARGET).xdc
|
XDCDATA = $(OBJDIR)/$(TARGET).xdc
|
||||||
endif
|
endif
|
||||||
|
|
||||||
ifeq ($(findstring linux,$(OSTYPE)),linux)
|
ifeq ($(findstring /sh,$(SHELL)),/sh)
|
||||||
#-include $(NDKBASE)/nlmconv/ncpfs.inc
|
|
||||||
DL = '
|
DL = '
|
||||||
DS = /
|
DS = /
|
||||||
else
|
else
|
||||||
@@ -194,24 +193,10 @@ endif
|
|||||||
|
|
||||||
vpath %.c . ../src
|
vpath %.c . ../src
|
||||||
|
|
||||||
OBJECTS = \
|
# include Makefile.inc to get CSOURCES define
|
||||||
channel.o \
|
include ../Makefile.inc
|
||||||
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
|
|
||||||
|
|
||||||
|
OBJECTS := $(patsubst %.c,%.o,$(CSOURCES))
|
||||||
ifeq ($(LIBARCH),CLIB)
|
ifeq ($(LIBARCH),CLIB)
|
||||||
# CLIB lacks of snprint() function - here's a replacement:
|
# CLIB lacks of snprint() function - here's a replacement:
|
||||||
# http://www.ijs.si/software/snprintf/
|
# http://www.ijs.si/software/snprintf/
|
||||||
@@ -220,7 +205,6 @@ vpath %.c $(SNPRINTF)
|
|||||||
endif
|
endif
|
||||||
|
|
||||||
OBJS := $(addprefix $(OBJDIR)/,$(OBJECTS))
|
OBJS := $(addprefix $(OBJDIR)/,$(OBJECTS))
|
||||||
|
|
||||||
OBJL = $(OBJS) $(OBJDIR)/nwlib.o $(LDLIBS)
|
OBJL = $(OBJS) $(OBJDIR)/nwlib.o $(LDLIBS)
|
||||||
|
|
||||||
all: lib nlm
|
all: lib nlm
|
||||||
@@ -382,6 +366,8 @@ ifeq ($(LIBARCH),CLIB)
|
|||||||
@echo $(DL)#define HAVE_STRICMP 1$(DL) >> $@
|
@echo $(DL)#define HAVE_STRICMP 1$(DL) >> $@
|
||||||
@echo $(DL)#define socklen_t int$(DL) >> $@
|
@echo $(DL)#define socklen_t int$(DL) >> $@
|
||||||
@echo $(DL)#define sleep(s) delay(1000 * s)$(DL) >> $@
|
@echo $(DL)#define sleep(s) delay(1000 * s)$(DL) >> $@
|
||||||
|
@echo $(DL)#define strcasecmp stricmp$(DL) >> $@
|
||||||
|
@echo $(DL)#define strncasecmp strnicmp$(DL) >> $@
|
||||||
else
|
else
|
||||||
@echo $(DL)#define OS "i586-pc-libc-NetWare"$(DL) >> $@
|
@echo $(DL)#define OS "i586-pc-libc-NetWare"$(DL) >> $@
|
||||||
@echo $(DL)#define HAVE_DLFCN_H 1$(DL) >> $@
|
@echo $(DL)#define HAVE_DLFCN_H 1$(DL) >> $@
|
||||||
@@ -508,6 +494,7 @@ endif
|
|||||||
@echo $(DL) libssh2_channel_eof,$(DL) >> $@
|
@echo $(DL) libssh2_channel_eof,$(DL) >> $@
|
||||||
@echo $(DL) libssh2_channel_flush_ex,$(DL) >> $@
|
@echo $(DL) libssh2_channel_flush_ex,$(DL) >> $@
|
||||||
@echo $(DL) libssh2_channel_free,$(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_open_ex,$(DL) >> $@
|
||||||
@echo $(DL) libssh2_channel_process_startup,$(DL) >> $@
|
@echo $(DL) libssh2_channel_process_startup,$(DL) >> $@
|
||||||
@echo $(DL) libssh2_channel_read_ex,$(DL) >> $@
|
@echo $(DL) libssh2_channel_read_ex,$(DL) >> $@
|
||||||
@@ -521,11 +508,18 @@ endif
|
|||||||
@echo $(DL) libssh2_hostkey_hash,$(DL) >> $@
|
@echo $(DL) libssh2_hostkey_hash,$(DL) >> $@
|
||||||
@echo $(DL) libssh2_scp_recv,$(DL) >> $@
|
@echo $(DL) libssh2_scp_recv,$(DL) >> $@
|
||||||
@echo $(DL) libssh2_scp_send_ex,$(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_abstract,$(DL) >> $@
|
||||||
@echo $(DL) libssh2_session_block_directions,$(DL) >> $@
|
@echo $(DL) libssh2_session_block_directions,$(DL) >> $@
|
||||||
@echo $(DL) libssh2_session_callback_set,$(DL) >> $@
|
@echo $(DL) libssh2_session_callback_set,$(DL) >> $@
|
||||||
@echo $(DL) libssh2_session_disconnect_ex,$(DL) >> $@
|
@echo $(DL) libssh2_session_disconnect_ex,$(DL) >> $@
|
||||||
@echo $(DL) libssh2_session_free,$(DL) >> $@
|
@echo $(DL) libssh2_session_free,$(DL) >> $@
|
||||||
|
@echo $(DL) libssh2_session_hostkey,$(DL) >> $@
|
||||||
@echo $(DL) libssh2_session_init_ex,$(DL) >> $@
|
@echo $(DL) libssh2_session_init_ex,$(DL) >> $@
|
||||||
@echo $(DL) libssh2_session_last_errno,$(DL) >> $@
|
@echo $(DL) libssh2_session_last_errno,$(DL) >> $@
|
||||||
@echo $(DL) libssh2_session_last_error,$(DL) >> $@
|
@echo $(DL) libssh2_session_last_error,$(DL) >> $@
|
||||||
|
@@ -29,7 +29,7 @@ LINK_STATIC = 1
|
|||||||
|
|
||||||
# Edit the vars below to change NLM target settings.
|
# Edit the vars below to change NLM target settings.
|
||||||
SAMPLES = ../../example/simple
|
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)
|
VERSION = $(LIBSSH2_VERSION)
|
||||||
COPYR = Copyright (c) 2004-2009, Sara Golemon <sarag@libssh2.org>
|
COPYR = Copyright (c) 2004-2009, Sara Golemon <sarag@libssh2.org>
|
||||||
WWWURL = http://www.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
|
-include $(OBJDIR)/version.inc
|
||||||
|
|
||||||
# Global flags for all compilers
|
# Global flags for all compilers
|
||||||
CFLAGS = $(OPT) -D$(DB) -DNETWARE -nostdinc
|
CFLAGS += $(OPT) -D$(DB) -DNETWARE -nostdinc
|
||||||
|
|
||||||
ifeq ($(CC),mwccnlm)
|
ifeq ($(CC),mwccnlm)
|
||||||
LD = mwldnlm
|
LD = mwldnlm
|
||||||
@@ -116,12 +116,15 @@ LDFLAGS = -T
|
|||||||
AR = ar
|
AR = ar
|
||||||
ARFLAGS = -cq
|
ARFLAGS = -cq
|
||||||
LIBEXT = a
|
LIBEXT = a
|
||||||
CFLAGS += -fno-builtin -fpack-struct -fpcc-struct-return -fno-strict-aliasing
|
CFLAGS += -fno-builtin -fpcc-struct-return -fno-strict-aliasing
|
||||||
CFLAGS += -Wall,no-unused # -pedantic
|
CFLAGS += -Wall # -pedantic
|
||||||
ifeq ($(LIBARCH),LIBC)
|
ifeq ($(LIBARCH),LIBC)
|
||||||
PRELUDE = $(SDK_LIBC)/imports/libcpre.gcc.o
|
PRELUDE = $(SDK_LIBC)/imports/libcpre.gcc.o
|
||||||
else
|
else
|
||||||
PRELUDE = $(SDK_CLIB)/imports/clibpre.gcc.o
|
# PRELUDE = $(SDK_CLIB)/imports/clibpre.gcc.o
|
||||||
|
# to avoid the __init_* / __deinit_* whoes dont use prelude from NDK
|
||||||
|
# http://www.gknw.net/development/mk_nlm/gcc_pre.zip
|
||||||
|
PRELUDE = $(NDK_ROOT)/pre/prelude.o
|
||||||
CFLAGS += -include $(NDKBASE)/nlmconv/genlm.h
|
CFLAGS += -include $(NDKBASE)/nlmconv/genlm.h
|
||||||
endif
|
endif
|
||||||
endif
|
endif
|
||||||
@@ -135,6 +138,13 @@ INCLUDES = -I.. -I../../include
|
|||||||
|
|
||||||
LDLIBS =
|
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
|
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)/ssl.$(LIBEXT)
|
||||||
LDLIBS += $(OPENSSL_PATH)/out_nw_$(LIBARCH_L)/crypto.$(LIBEXT)
|
LDLIBS += $(OPENSSL_PATH)/out_nw_$(LIBARCH_L)/crypto.$(LIBEXT)
|
||||||
@@ -150,13 +160,6 @@ else
|
|||||||
endif
|
endif
|
||||||
endif
|
endif
|
||||||
|
|
||||||
ifdef LINK_STATIC
|
|
||||||
LDLIBS += ../libssh2.$(LIBEXT)
|
|
||||||
else
|
|
||||||
IMPORTS += @../libssh2.imp
|
|
||||||
MODULES += libssh2.nlm
|
|
||||||
endif
|
|
||||||
|
|
||||||
ifeq ($(LIBARCH),LIBC)
|
ifeq ($(LIBARCH),LIBC)
|
||||||
INCLUDES += -I$(SDK_LIBC)/include
|
INCLUDES += -I$(SDK_LIBC)/include
|
||||||
# INCLUDES += -I$(SDK_LIBC)/include/nks
|
# INCLUDES += -I$(SDK_LIBC)/include/nks
|
||||||
@@ -177,8 +180,11 @@ ifeq ($(MTSAFE),NO)
|
|||||||
XDCOPT = -u
|
XDCOPT = -u
|
||||||
endif
|
endif
|
||||||
|
|
||||||
ifeq ($(findstring linux,$(OSTYPE)),linux)
|
ifeq ($(findstring /sh,$(SHELL)),/sh)
|
||||||
DL = '
|
DL = '
|
||||||
|
DS = /
|
||||||
|
else
|
||||||
|
DS = \\
|
||||||
endif
|
endif
|
||||||
|
|
||||||
vpath %.c $(SAMPLES)
|
vpath %.c $(SAMPLES)
|
||||||
@@ -188,7 +194,7 @@ vpath %.c $(SAMPLES)
|
|||||||
|
|
||||||
all: prebuild $(TARGETS)
|
all: prebuild $(TARGETS)
|
||||||
|
|
||||||
prebuild: $(OBJDIR) $(OBJDIR)/version.inc config.h
|
prebuild: $(OBJDIR) $(OBJDIR)/version.inc
|
||||||
|
|
||||||
$(OBJDIR)/%.o: %.c
|
$(OBJDIR)/%.o: %.c
|
||||||
# @echo Compiling $<
|
# @echo Compiling $<
|
||||||
@@ -276,7 +282,7 @@ ifdef IMPORTS
|
|||||||
@echo $(DL)import $(IMPORTS)$(DL) >> $@
|
@echo $(DL)import $(IMPORTS)$(DL) >> $@
|
||||||
endif
|
endif
|
||||||
ifeq ($(LD),nlmconv)
|
ifeq ($(LD),nlmconv)
|
||||||
@echo $(DL)input $(<:.def=.o)$(DL) >> $@
|
@echo $(DL)input $(@:.def=.o)$(DL) >> $@
|
||||||
@echo $(DL)input $(PRELUDE)$(DL) >> $@
|
@echo $(DL)input $(PRELUDE)$(DL) >> $@
|
||||||
ifdef LDLIBS
|
ifdef LDLIBS
|
||||||
@echo $(DL)input $(LDLIBS)$(DL) >> $@
|
@echo $(DL)input $(LDLIBS)$(DL) >> $@
|
||||||
@@ -284,7 +290,7 @@ endif
|
|||||||
@echo $(DL)output $(notdir $(@:.def=.nlm))$(DL) >> $@
|
@echo $(DL)output $(notdir $(@:.def=.nlm))$(DL) >> $@
|
||||||
endif
|
endif
|
||||||
|
|
||||||
config.h: Makefile.netware
|
ssh2_config.h: Makefile.netware
|
||||||
@echo Creating $@
|
@echo Creating $@
|
||||||
@echo $(DL)/* $@ for NetWare target.$(DL) > $@
|
@echo $(DL)/* $@ for NetWare target.$(DL) > $@
|
||||||
@echo $(DL)** Do not edit this file - it is created by make!$(DL) >> $@
|
@echo $(DL)** Do not edit this file - it is created by make!$(DL) >> $@
|
||||||
|
431
src/channel.c
431
src/channel.c
@@ -61,13 +61,13 @@ _libssh2_channel_nextid(LIBSSH2_SESSION * session)
|
|||||||
unsigned long id = session->next_channel;
|
unsigned long id = session->next_channel;
|
||||||
LIBSSH2_CHANNEL *channel;
|
LIBSSH2_CHANNEL *channel;
|
||||||
|
|
||||||
channel = session->channels.head;
|
channel = _libssh2_list_first(&session->channels);
|
||||||
|
|
||||||
while (channel) {
|
while (channel) {
|
||||||
if (channel->local.id > id) {
|
if (channel->local.id > id) {
|
||||||
id = channel->local.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
|
/* 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_locate(LIBSSH2_SESSION *session, unsigned long channel_id)
|
||||||
{
|
{
|
||||||
LIBSSH2_CHANNEL *channel;
|
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)
|
if (channel->local.id == channel_id)
|
||||||
return channel;
|
return channel;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* We didn't find the channel in the session, let's then check its
|
/* We didn't find the channel in the session, let's then check its
|
||||||
listeners... */
|
listeners since each listener may have its own set of pending channels
|
||||||
for(listener = session->listeners; listener; listener = listener->next) {
|
*/
|
||||||
for(channel = listener->queue; channel; channel = channel->next) {
|
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)
|
if (channel->local.id == channel_id)
|
||||||
return channel;
|
return channel;
|
||||||
}
|
}
|
||||||
@@ -111,20 +117,6 @@ _libssh2_channel_locate(LIBSSH2_SESSION *session, unsigned long channel_id)
|
|||||||
return NULL;
|
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
|
* _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 = window_size;
|
||||||
session->open_channel->remote.window_size_initial = window_size;
|
session->open_channel->remote.window_size_initial = window_size;
|
||||||
session->open_channel->remote.packet_size = packet_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 =
|
s = session->open_packet =
|
||||||
LIBSSH2_ALLOC(session, session->open_packet_len);
|
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];
|
unsigned char channel_id[4];
|
||||||
LIBSSH2_FREE(session, session->open_channel->channel_type);
|
LIBSSH2_FREE(session, session->open_channel->channel_type);
|
||||||
|
|
||||||
if (session->open_channel->next) {
|
_libssh2_list_remove(&session->open_channel->node);
|
||||||
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;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Clear out packets meant for this channel */
|
/* Clear out packets meant for this channel */
|
||||||
_libssh2_htonu32(channel_id, session->open_channel->local.id);
|
_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... */
|
/* by default we set (keep?) idle state... */
|
||||||
session->direct_state = libssh2_NB_state_idle;
|
session->direct_state = libssh2_NB_state_idle;
|
||||||
|
|
||||||
if (!channel) {
|
if (!channel &&
|
||||||
if (libssh2_session_last_errno(session) == LIBSSH2_ERROR_EAGAIN) {
|
libssh2_session_last_errno(session) == LIBSSH2_ERROR_EAGAIN) {
|
||||||
/* The error code is still set to LIBSSH2_ERROR_EAGAIN,
|
/* The error code is still set to LIBSSH2_ERROR_EAGAIN, set our state
|
||||||
set our state to created to avoid re-creating the package
|
to created to avoid re-creating the package on next invoke */
|
||||||
on next invoke */
|
session->direct_state = libssh2_NB_state_created;
|
||||||
session->direct_state = libssh2_NB_state_created;
|
return NULL;
|
||||||
return NULL;
|
|
||||||
} else {
|
|
||||||
LIBSSH2_FREE(session, session->direct_message);
|
|
||||||
session->direct_message = NULL;
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
LIBSSH2_FREE(session, session->direct_message);
|
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_size = 0;
|
||||||
listener->queue_maxsize = queue_maxsize;
|
listener->queue_maxsize = queue_maxsize;
|
||||||
|
|
||||||
listener->next = session->listeners;
|
/* append this to the parent's list of listeners */
|
||||||
listener->prev = NULL;
|
_libssh2_list_add(&session->listeners, &listener->node);
|
||||||
if (session->listeners) {
|
|
||||||
session->listeners->prev = listener;
|
|
||||||
}
|
|
||||||
session->listeners = listener;
|
|
||||||
|
|
||||||
if (bound_port) {
|
if (bound_port) {
|
||||||
*bound_port = listener->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)
|
static int channel_forward_cancel(LIBSSH2_LISTENER *listener)
|
||||||
{
|
{
|
||||||
LIBSSH2_SESSION *session = listener->session;
|
LIBSSH2_SESSION *session = listener->session;
|
||||||
LIBSSH2_CHANNEL *queued = listener->queue;
|
LIBSSH2_CHANNEL *queued;
|
||||||
unsigned char *packet, *s;
|
unsigned char *packet, *s;
|
||||||
unsigned long host_len = strlen(listener->host);
|
unsigned long host_len = strlen(listener->host);
|
||||||
/* 14 = packet_type(1) + request_len(4) + want_replay(1) + host_len(4) +
|
/* 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) {
|
if (!packet) {
|
||||||
libssh2_error(session, LIBSSH2_ERROR_ALLOC,
|
libssh2_error(session, LIBSSH2_ERROR_ALLOC,
|
||||||
"Unable to allocate memeory for setenv packet", 0);
|
"Unable to allocate memeory for setenv packet", 0);
|
||||||
return -1;
|
return LIBSSH2_ERROR_ALLOC;
|
||||||
}
|
}
|
||||||
|
|
||||||
*(s++) = SSH_MSG_GLOBAL_REQUEST;
|
*(s++) = SSH_MSG_GLOBAL_REQUEST;
|
||||||
@@ -695,32 +668,27 @@ static int channel_forward_cancel(LIBSSH2_LISTENER *listener)
|
|||||||
0);
|
0);
|
||||||
LIBSSH2_FREE(session, packet);
|
LIBSSH2_FREE(session, packet);
|
||||||
listener->chanFwdCncl_state = libssh2_NB_state_idle;
|
listener->chanFwdCncl_state = libssh2_NB_state_idle;
|
||||||
return -1;
|
return LIBSSH2_ERROR_SOCKET_SEND;
|
||||||
}
|
}
|
||||||
LIBSSH2_FREE(session, packet);
|
LIBSSH2_FREE(session, packet);
|
||||||
|
|
||||||
listener->chanFwdCncl_state = libssh2_NB_state_sent;
|
listener->chanFwdCncl_state = libssh2_NB_state_sent;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
queued = _libssh2_list_first(&listener->queue);
|
||||||
while (queued) {
|
while (queued) {
|
||||||
LIBSSH2_CHANNEL *next = queued->next;
|
LIBSSH2_CHANNEL *next = _libssh2_list_next(&queued->node);
|
||||||
|
|
||||||
rc = libssh2_channel_free(queued);
|
rc = libssh2_channel_free(queued);
|
||||||
if (rc == PACKET_EAGAIN) {
|
if (rc == PACKET_EAGAIN) {
|
||||||
return PACKET_EAGAIN;
|
return rc;
|
||||||
}
|
}
|
||||||
queued = next;
|
queued = next;
|
||||||
}
|
}
|
||||||
LIBSSH2_FREE(session, listener->host);
|
LIBSSH2_FREE(session, listener->host);
|
||||||
|
|
||||||
if (listener->next) {
|
/* remove this entry from the parent's list of listeners */
|
||||||
listener->next->prev = listener->prev;
|
_libssh2_list_remove(&listener->node);
|
||||||
}
|
|
||||||
if (listener->prev) {
|
|
||||||
listener->prev->next = listener->next;
|
|
||||||
} else {
|
|
||||||
session->listeners = listener->next;
|
|
||||||
}
|
|
||||||
|
|
||||||
LIBSSH2_FREE(session, listener);
|
LIBSSH2_FREE(session, listener);
|
||||||
|
|
||||||
@@ -753,44 +721,33 @@ libssh2_channel_forward_cancel(LIBSSH2_LISTENER *listener)
|
|||||||
static LIBSSH2_CHANNEL *
|
static LIBSSH2_CHANNEL *
|
||||||
channel_forward_accept(LIBSSH2_LISTENER *listener)
|
channel_forward_accept(LIBSSH2_LISTENER *listener)
|
||||||
{
|
{
|
||||||
libssh2pack_t rc;
|
int rc;
|
||||||
|
|
||||||
do {
|
do {
|
||||||
rc = _libssh2_transport_read(listener->session);
|
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);
|
} while (rc > 0);
|
||||||
|
|
||||||
if (listener->queue) {
|
if (_libssh2_list_first(&listener->queue)) {
|
||||||
LIBSSH2_SESSION *session = listener->session;
|
LIBSSH2_CHANNEL *channel = _libssh2_list_first(&listener->queue);
|
||||||
LIBSSH2_CHANNEL *channel;
|
|
||||||
|
|
||||||
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--;
|
listener->queue_size--;
|
||||||
|
|
||||||
|
/* add channel to session's channel list */
|
||||||
|
_libssh2_list_add(&channel->session->channels, &channel->node);
|
||||||
|
|
||||||
return channel;
|
return channel;
|
||||||
}
|
}
|
||||||
|
|
||||||
libssh2_error(listener->session, LIBSSH2_ERROR_CHANNEL_UNKNOWN,
|
if (rc == PACKET_EAGAIN) {
|
||||||
"Channel not found", 0);
|
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;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -844,7 +801,7 @@ static int channel_setenv(LIBSSH2_CHANNEL *channel,
|
|||||||
if (!channel->setenv_packet) {
|
if (!channel->setenv_packet) {
|
||||||
libssh2_error(session, LIBSSH2_ERROR_ALLOC,
|
libssh2_error(session, LIBSSH2_ERROR_ALLOC,
|
||||||
"Unable to allocate memeory for setenv packet", 0);
|
"Unable to allocate memeory for setenv packet", 0);
|
||||||
return -1;
|
return LIBSSH2_ERROR_ALLOC;
|
||||||
}
|
}
|
||||||
|
|
||||||
*(s++) = SSH_MSG_CHANNEL_REQUEST;
|
*(s++) = SSH_MSG_CHANNEL_REQUEST;
|
||||||
@@ -874,7 +831,7 @@ static int channel_setenv(LIBSSH2_CHANNEL *channel,
|
|||||||
rc = _libssh2_transport_write(session, channel->setenv_packet,
|
rc = _libssh2_transport_write(session, channel->setenv_packet,
|
||||||
channel->setenv_packet_len);
|
channel->setenv_packet_len);
|
||||||
if (rc == PACKET_EAGAIN) {
|
if (rc == PACKET_EAGAIN) {
|
||||||
return PACKET_EAGAIN;
|
return rc;
|
||||||
} else if (rc) {
|
} else if (rc) {
|
||||||
libssh2_error(session, LIBSSH2_ERROR_SOCKET_SEND,
|
libssh2_error(session, LIBSSH2_ERROR_SOCKET_SEND,
|
||||||
"Unable to send channel-request packet for "
|
"Unable to send channel-request packet for "
|
||||||
@@ -883,7 +840,7 @@ static int channel_setenv(LIBSSH2_CHANNEL *channel,
|
|||||||
LIBSSH2_FREE(session, channel->setenv_packet);
|
LIBSSH2_FREE(session, channel->setenv_packet);
|
||||||
channel->setenv_packet = NULL;
|
channel->setenv_packet = NULL;
|
||||||
channel->setenv_state = libssh2_NB_state_idle;
|
channel->setenv_state = libssh2_NB_state_idle;
|
||||||
return -1;
|
return LIBSSH2_ERROR_SOCKET_SEND;
|
||||||
}
|
}
|
||||||
LIBSSH2_FREE(session, channel->setenv_packet);
|
LIBSSH2_FREE(session, channel->setenv_packet);
|
||||||
channel->setenv_packet = NULL;
|
channel->setenv_packet = NULL;
|
||||||
@@ -899,11 +856,11 @@ static int channel_setenv(LIBSSH2_CHANNEL *channel,
|
|||||||
&channel->
|
&channel->
|
||||||
setenv_packet_requirev_state);
|
setenv_packet_requirev_state);
|
||||||
if (rc == PACKET_EAGAIN) {
|
if (rc == PACKET_EAGAIN) {
|
||||||
return PACKET_EAGAIN;
|
return rc;
|
||||||
}
|
}
|
||||||
if (rc) {
|
if (rc) {
|
||||||
channel->setenv_state = libssh2_NB_state_idle;
|
channel->setenv_state = libssh2_NB_state_idle;
|
||||||
return -1;
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (data[0] == SSH_MSG_CHANNEL_SUCCESS) {
|
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,
|
libssh2_error(session, LIBSSH2_ERROR_CHANNEL_REQUEST_DENIED,
|
||||||
"Unable to complete request for channel-setenv", 0);
|
"Unable to complete request for channel-setenv", 0);
|
||||||
channel->setenv_state = libssh2_NB_state_idle;
|
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,
|
rc = _libssh2_transport_write(session, channel->reqPTY_packet,
|
||||||
channel->reqPTY_packet_len);
|
channel->reqPTY_packet_len);
|
||||||
if (rc == PACKET_EAGAIN) {
|
if (rc == PACKET_EAGAIN) {
|
||||||
return PACKET_EAGAIN;
|
return rc;
|
||||||
} else if (rc) {
|
} else if (rc) {
|
||||||
libssh2_error(session, LIBSSH2_ERROR_SOCKET_SEND,
|
libssh2_error(session, rc,
|
||||||
"Unable to send pty-request packet", 0);
|
"Unable to send pty-request packet", 0);
|
||||||
LIBSSH2_FREE(session, channel->reqPTY_packet);
|
LIBSSH2_FREE(session, channel->reqPTY_packet);
|
||||||
channel->reqPTY_packet = NULL;
|
channel->reqPTY_packet = NULL;
|
||||||
channel->reqPTY_state = libssh2_NB_state_idle;
|
channel->reqPTY_state = libssh2_NB_state_idle;
|
||||||
return -1;
|
return rc;
|
||||||
}
|
}
|
||||||
LIBSSH2_FREE(session, channel->reqPTY_packet);
|
LIBSSH2_FREE(session, channel->reqPTY_packet);
|
||||||
channel->reqPTY_packet = NULL;
|
channel->reqPTY_packet = NULL;
|
||||||
@@ -1039,7 +996,7 @@ static int channel_request_pty(LIBSSH2_CHANNEL *channel,
|
|||||||
1, channel->reqPTY_local_channel, 4,
|
1, channel->reqPTY_local_channel, 4,
|
||||||
&channel->reqPTY_packet_requirev_state);
|
&channel->reqPTY_packet_requirev_state);
|
||||||
if (rc == PACKET_EAGAIN) {
|
if (rc == PACKET_EAGAIN) {
|
||||||
return PACKET_EAGAIN;
|
return rc;
|
||||||
} else if (rc) {
|
} else if (rc) {
|
||||||
channel->reqPTY_state = libssh2_NB_state_idle;
|
channel->reqPTY_state = libssh2_NB_state_idle;
|
||||||
return -1;
|
return -1;
|
||||||
@@ -1056,7 +1013,7 @@ static int channel_request_pty(LIBSSH2_CHANNEL *channel,
|
|||||||
libssh2_error(session, LIBSSH2_ERROR_CHANNEL_REQUEST_DENIED,
|
libssh2_error(session, LIBSSH2_ERROR_CHANNEL_REQUEST_DENIED,
|
||||||
"Unable to complete request for channel request-pty", 0);
|
"Unable to complete request for channel request-pty", 0);
|
||||||
channel->reqPTY_state = libssh2_NB_state_idle;
|
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,
|
rc = _libssh2_transport_write(session, channel->reqPTY_packet,
|
||||||
channel->reqPTY_packet_len);
|
channel->reqPTY_packet_len);
|
||||||
if (rc == PACKET_EAGAIN) {
|
if (rc == PACKET_EAGAIN) {
|
||||||
return PACKET_EAGAIN;
|
return rc;
|
||||||
} else if (rc) {
|
} else if (rc) {
|
||||||
libssh2_error(session, LIBSSH2_ERROR_SOCKET_SEND,
|
libssh2_error(session, rc,
|
||||||
"Unable to send window-change packet", 0);
|
"Unable to send window-change packet", 0);
|
||||||
LIBSSH2_FREE(session, channel->reqPTY_packet);
|
LIBSSH2_FREE(session, channel->reqPTY_packet);
|
||||||
channel->reqPTY_packet = NULL;
|
channel->reqPTY_packet = NULL;
|
||||||
channel->reqPTY_state = libssh2_NB_state_idle;
|
channel->reqPTY_state = libssh2_NB_state_idle;
|
||||||
return -1;
|
return rc;
|
||||||
}
|
}
|
||||||
LIBSSH2_FREE(session, channel->reqPTY_packet);
|
LIBSSH2_FREE(session, channel->reqPTY_packet);
|
||||||
channel->reqPTY_packet = NULL;
|
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,
|
rc = _libssh2_transport_write(session, channel->reqX11_packet,
|
||||||
channel->reqX11_packet_len);
|
channel->reqX11_packet_len);
|
||||||
if (rc == PACKET_EAGAIN) {
|
if (rc == PACKET_EAGAIN) {
|
||||||
return PACKET_EAGAIN;
|
return rc;
|
||||||
}
|
}
|
||||||
if (rc) {
|
if (rc) {
|
||||||
libssh2_error(session, LIBSSH2_ERROR_SOCKET_SEND,
|
libssh2_error(session, rc,
|
||||||
"Unable to send x11-req packet", 0);
|
"Unable to send x11-req packet", 0);
|
||||||
LIBSSH2_FREE(session, channel->reqX11_packet);
|
LIBSSH2_FREE(session, channel->reqX11_packet);
|
||||||
channel->reqX11_packet = NULL;
|
channel->reqX11_packet = NULL;
|
||||||
channel->reqX11_state = libssh2_NB_state_idle;
|
channel->reqX11_state = libssh2_NB_state_idle;
|
||||||
return -1;
|
return rc;
|
||||||
}
|
}
|
||||||
LIBSSH2_FREE(session, channel->reqX11_packet);
|
LIBSSH2_FREE(session, channel->reqX11_packet);
|
||||||
channel->reqX11_packet = NULL;
|
channel->reqX11_packet = NULL;
|
||||||
@@ -1280,10 +1237,11 @@ channel_x11_req(LIBSSH2_CHANNEL *channel, int single_connection,
|
|||||||
1, channel->reqX11_local_channel, 4,
|
1, channel->reqX11_local_channel, 4,
|
||||||
&channel->reqX11_packet_requirev_state);
|
&channel->reqX11_packet_requirev_state);
|
||||||
if (rc == PACKET_EAGAIN) {
|
if (rc == PACKET_EAGAIN) {
|
||||||
return PACKET_EAGAIN;
|
return rc;
|
||||||
} else if (rc) {
|
} else if (rc) {
|
||||||
|
/* TODO: call libssh2_error() here! */
|
||||||
channel->reqX11_state = libssh2_NB_state_idle;
|
channel->reqX11_state = libssh2_NB_state_idle;
|
||||||
return -1;
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (data[0] == SSH_MSG_CHANNEL_SUCCESS) {
|
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] =
|
static const unsigned char reply_codes[3] =
|
||||||
{ SSH_MSG_CHANNEL_SUCCESS, SSH_MSG_CHANNEL_FAILURE, 0 };
|
{ SSH_MSG_CHANNEL_SUCCESS, SSH_MSG_CHANNEL_FAILURE, 0 };
|
||||||
unsigned long data_len;
|
unsigned long data_len;
|
||||||
libssh2pack_t rc;
|
int rc;
|
||||||
|
|
||||||
if (channel->process_state == libssh2_NB_state_idle) {
|
if (channel->process_state == libssh2_NB_state_idle) {
|
||||||
/* 10 = packet_type(1) + channel(4) + request_len(4) + want_reply(1) */
|
/* 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,
|
libssh2_error(session, LIBSSH2_ERROR_ALLOC,
|
||||||
"Unable to allocate memory for channel-process request",
|
"Unable to allocate memory for channel-process request",
|
||||||
0);
|
0);
|
||||||
return -1;
|
return LIBSSH2_ERROR_ALLOC;
|
||||||
}
|
}
|
||||||
|
|
||||||
*(s++) = SSH_MSG_CHANNEL_REQUEST;
|
*(s++) = SSH_MSG_CHANNEL_REQUEST;
|
||||||
@@ -1382,15 +1340,15 @@ _libssh2_channel_process_startup(LIBSSH2_CHANNEL *channel,
|
|||||||
rc = _libssh2_transport_write(session, channel->process_packet,
|
rc = _libssh2_transport_write(session, channel->process_packet,
|
||||||
channel->process_packet_len);
|
channel->process_packet_len);
|
||||||
if (rc == PACKET_EAGAIN) {
|
if (rc == PACKET_EAGAIN) {
|
||||||
return PACKET_EAGAIN;
|
return rc;
|
||||||
}
|
}
|
||||||
else if (rc) {
|
else if (rc) {
|
||||||
libssh2_error(session, LIBSSH2_ERROR_SOCKET_SEND,
|
libssh2_error(session, rc,
|
||||||
"Unable to send channel request", 0);
|
"Unable to send channel request", 0);
|
||||||
LIBSSH2_FREE(session, channel->process_packet);
|
LIBSSH2_FREE(session, channel->process_packet);
|
||||||
channel->process_packet = NULL;
|
channel->process_packet = NULL;
|
||||||
channel->process_state = libssh2_NB_state_idle;
|
channel->process_state = libssh2_NB_state_idle;
|
||||||
return -1;
|
return rc;
|
||||||
}
|
}
|
||||||
LIBSSH2_FREE(session, channel->process_packet);
|
LIBSSH2_FREE(session, channel->process_packet);
|
||||||
channel->process_packet = NULL;
|
channel->process_packet = NULL;
|
||||||
@@ -1405,10 +1363,12 @@ _libssh2_channel_process_startup(LIBSSH2_CHANNEL *channel,
|
|||||||
1, channel->process_local_channel, 4,
|
1, channel->process_local_channel, 4,
|
||||||
&channel->process_packet_requirev_state);
|
&channel->process_packet_requirev_state);
|
||||||
if (rc == PACKET_EAGAIN) {
|
if (rc == PACKET_EAGAIN) {
|
||||||
return PACKET_EAGAIN;
|
return rc;
|
||||||
} else if (rc) {
|
} else if (rc) {
|
||||||
channel->process_state = libssh2_NB_state_idle;
|
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) {
|
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,
|
libssh2_error(session, LIBSSH2_ERROR_CHANNEL_REQUEST_DENIED,
|
||||||
"Unable to complete request for channel-process-startup", 0);
|
"Unable to complete request for channel-process-startup", 0);
|
||||||
channel->process_state = libssh2_NB_state_idle;
|
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
|
int
|
||||||
_libssh2_channel_flush(LIBSSH2_CHANNEL *channel, int streamid)
|
_libssh2_channel_flush(LIBSSH2_CHANNEL *channel, int streamid)
|
||||||
{
|
{
|
||||||
LIBSSH2_PACKET *packet = channel->session->packets.head;
|
|
||||||
|
|
||||||
if (channel->flush_state == libssh2_NB_state_idle) {
|
if (channel->flush_state == libssh2_NB_state_idle) {
|
||||||
|
LIBSSH2_PACKET *packet =
|
||||||
|
_libssh2_list_first(&channel->session->packets);
|
||||||
channel->flush_refund_bytes = 0;
|
channel->flush_refund_bytes = 0;
|
||||||
channel->flush_flush_bytes = 0;
|
channel->flush_flush_bytes = 0;
|
||||||
|
|
||||||
while (packet) {
|
while (packet) {
|
||||||
LIBSSH2_PACKET *next = packet->next;
|
LIBSSH2_PACKET *next = _libssh2_list_next(&packet->node);
|
||||||
unsigned char packet_type = packet->data[0];
|
unsigned char packet_type = packet->data[0];
|
||||||
|
|
||||||
if (((packet_type == SSH_MSG_CHANNEL_DATA)
|
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)) {
|
&& (_libssh2_ntohu32(packet->data + 1) == channel->local.id)) {
|
||||||
/* It's our channel at least */
|
/* It's our channel at least */
|
||||||
long packet_stream_id =
|
long packet_stream_id =
|
||||||
(packet_type ==
|
(packet_type == SSH_MSG_CHANNEL_DATA) ? 0 :
|
||||||
SSH_MSG_CHANNEL_DATA) ? 0 : _libssh2_ntohu32(packet->data +
|
_libssh2_ntohu32(packet->data + 5);
|
||||||
5);
|
|
||||||
if ((streamid == LIBSSH2_CHANNEL_FLUSH_ALL)
|
if ((streamid == LIBSSH2_CHANNEL_FLUSH_ALL)
|
||||||
|| ((packet_type == SSH_MSG_CHANNEL_EXTENDED_DATA)
|
|| ((packet_type == SSH_MSG_CHANNEL_EXTENDED_DATA)
|
||||||
&& ((streamid == LIBSSH2_CHANNEL_FLUSH_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;
|
channel->flush_flush_bytes += bytes_to_flush;
|
||||||
|
|
||||||
LIBSSH2_FREE(channel->session, packet->data);
|
LIBSSH2_FREE(channel->session, packet->data);
|
||||||
if (packet->prev) {
|
|
||||||
packet->prev->next = packet->next;
|
/* remove this packet from the parent's list */
|
||||||
} else {
|
_libssh2_list_remove(&packet->node);
|
||||||
channel->session->packets.head = packet->next;
|
|
||||||
}
|
|
||||||
if (packet->next) {
|
|
||||||
packet->next->prev = packet->prev;
|
|
||||||
} else {
|
|
||||||
channel->session->packets.tail = packet->prev;
|
|
||||||
}
|
|
||||||
LIBSSH2_FREE(channel->session, packet);
|
LIBSSH2_FREE(channel->session, packet);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1526,9 +1478,8 @@ _libssh2_channel_flush(LIBSSH2_CHANNEL *channel, int streamid)
|
|||||||
rc = _libssh2_channel_receive_window_adjust(channel,
|
rc = _libssh2_channel_receive_window_adjust(channel,
|
||||||
channel->flush_refund_bytes,
|
channel->flush_refund_bytes,
|
||||||
0, NULL);
|
0, NULL);
|
||||||
if (rc == PACKET_EAGAIN) {
|
if (rc == PACKET_EAGAIN)
|
||||||
return PACKET_EAGAIN;
|
return rc;
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
channel->flush_state = libssh2_NB_state_idle;
|
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);
|
rc = _libssh2_transport_write(channel->session, channel->adjust_adjust, 9);
|
||||||
if (rc == PACKET_EAGAIN) {
|
if (rc == PACKET_EAGAIN) {
|
||||||
return PACKET_EAGAIN;
|
return rc;
|
||||||
}
|
}
|
||||||
else if (rc) {
|
else if (rc) {
|
||||||
libssh2_error(channel->session, LIBSSH2_ERROR_SOCKET_SEND,
|
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
|
* libssh2_channel_receive_window_adjust
|
||||||
*
|
*
|
||||||
|
* DEPRECATED
|
||||||
|
*
|
||||||
* Adjust the receive window for a channel by adjustment bytes. If the amount
|
* 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
|
* to be adjusted is less than LIBSSH2_CHANNEL_MINADJUST and force is 0 the
|
||||||
* adjustment amount will be queued for a later packet.
|
* 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 (channel->extData2_state == libssh2_NB_state_idle) {
|
||||||
if (ignore_mode == LIBSSH2_CHANNEL_EXTENDED_DATA_IGNORE) {
|
if (ignore_mode == LIBSSH2_CHANNEL_EXTENDED_DATA_IGNORE) {
|
||||||
if (_libssh2_channel_flush(channel,
|
int rc =
|
||||||
LIBSSH2_CHANNEL_FLUSH_EXTENDED_DATA) ==
|
_libssh2_channel_flush(channel,
|
||||||
PACKET_EAGAIN) {
|
LIBSSH2_CHANNEL_FLUSH_EXTENDED_DATA);
|
||||||
return PACKET_EAGAIN;
|
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
|
* 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
|
* 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.
|
* 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)
|
char *buf, size_t buflen)
|
||||||
{
|
{
|
||||||
LIBSSH2_SESSION *session = channel->session;
|
LIBSSH2_SESSION *session = channel->session;
|
||||||
libssh2pack_t rc;
|
int rc;
|
||||||
int bytes_read = 0;
|
int bytes_read = 0;
|
||||||
int bytes_want;
|
int bytes_want;
|
||||||
int unlink_packet;
|
int unlink_packet;
|
||||||
|
LIBSSH2_PACKET *read_packet;
|
||||||
|
LIBSSH2_PACKET *read_next;
|
||||||
|
|
||||||
if (channel->read_state == libssh2_NB_state_idle) {
|
if (channel->read_state == libssh2_NB_state_idle) {
|
||||||
_libssh2_debug(session, LIBSSH2_DBG_CONN,
|
_libssh2_debug(session, LIBSSH2_DBG_CONN,
|
||||||
@@ -1780,8 +1735,10 @@ static ssize_t channel_read(LIBSSH2_CHANNEL *channel, int stream_id,
|
|||||||
while (rc > 0)
|
while (rc > 0)
|
||||||
rc = _libssh2_transport_read(session);
|
rc = _libssh2_transport_read(session);
|
||||||
|
|
||||||
if ((rc < 0) && (rc != PACKET_EAGAIN))
|
if ((rc < 0) && (rc != PACKET_EAGAIN)) {
|
||||||
return -1;
|
libssh2_error(session, rc, "tranport read", 0);
|
||||||
|
return rc;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* =============================== NOTE ===============================
|
* =============================== NOTE ===============================
|
||||||
@@ -1792,11 +1749,8 @@ static ssize_t channel_read(LIBSSH2_CHANNEL *channel, int stream_id,
|
|||||||
goto channel_read_ex_point1;
|
goto channel_read_ex_point1;
|
||||||
}
|
}
|
||||||
|
|
||||||
rc = 0;
|
read_packet = _libssh2_list_first(&session->packets);
|
||||||
|
while (read_packet && (bytes_read < (int) buflen)) {
|
||||||
channel->read_packet = session->packets.head;
|
|
||||||
while (channel->read_packet &&
|
|
||||||
(bytes_read < (int) buflen)) {
|
|
||||||
/* previously this loop condition also checked for
|
/* previously this loop condition also checked for
|
||||||
!channel->remote.close but we cannot let it do this:
|
!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.
|
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 */
|
/* In case packet gets destroyed during this iteration */
|
||||||
channel->read_next = readpkt->next;
|
read_next = _libssh2_list_next(&readpkt->node);
|
||||||
|
|
||||||
channel->read_local_id =
|
channel->read_local_id =
|
||||||
_libssh2_ntohu32(readpkt->data + 1);
|
_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 drained, remove from list */
|
||||||
if (unlink_packet) {
|
if (unlink_packet) {
|
||||||
if (readpkt->prev) {
|
/* detach readpkt from session->packets list */
|
||||||
readpkt->prev->next = readpkt->next;
|
_libssh2_list_remove(&readpkt->node);
|
||||||
} else {
|
|
||||||
session->packets.head = readpkt->next;
|
|
||||||
}
|
|
||||||
if (readpkt->next) {
|
|
||||||
readpkt->next->prev = readpkt->prev;
|
|
||||||
} else {
|
|
||||||
session->packets.tail = readpkt->prev;
|
|
||||||
}
|
|
||||||
LIBSSH2_FREE(session, readpkt->data);
|
LIBSSH2_FREE(session, readpkt->data);
|
||||||
LIBSSH2_FREE(session, readpkt);
|
LIBSSH2_FREE(session, readpkt);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* check the next struct in the chain */
|
/* 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;
|
channel->read_state = libssh2_NB_state_idle;
|
||||||
if (channel->remote.close) {
|
|
||||||
libssh2_error(session, LIBSSH2_ERROR_CHANNEL_CLOSED,
|
/* If the channel is already at EOF or even closed, we need to signal
|
||||||
"Remote end has closed this channel", 0);
|
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;
|
return 0;
|
||||||
}
|
else
|
||||||
else {
|
/* if the transport layer said EAGAIN then we say so as well */
|
||||||
/*
|
return (rc == PACKET_EAGAIN)?rc:0;
|
||||||
* 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
|
else
|
||||||
/* make sure we remain in the created state to focus on emptying the
|
/* 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 */
|
this special state here */
|
||||||
rc = _libssh2_channel_receive_window_adjust(channel,
|
rc = _libssh2_channel_receive_window_adjust(channel,
|
||||||
(LIBSSH2_CHANNEL_WINDOW_DEFAULT*600), 0, NULL);
|
(LIBSSH2_CHANNEL_WINDOW_DEFAULT*600), 0, NULL);
|
||||||
if (rc == PACKET_EAGAIN) {
|
if (rc == PACKET_EAGAIN)
|
||||||
return PACKET_EAGAIN;
|
return rc;
|
||||||
}
|
|
||||||
_libssh2_debug(session, LIBSSH2_DBG_CONN,
|
_libssh2_debug(session, LIBSSH2_DBG_CONN,
|
||||||
"channel_read() filled %d adjusted %d",
|
"channel_read() filled %d adjusted %d",
|
||||||
bytes_read, buflen);
|
bytes_read, buflen);
|
||||||
@@ -1940,8 +1882,8 @@ libssh2_channel_read_ex(LIBSSH2_CHANNEL *channel, int stream_id, char *buf,
|
|||||||
size_t buflen)
|
size_t buflen)
|
||||||
{
|
{
|
||||||
int rc;
|
int rc;
|
||||||
BLOCK_ADJUST(rc, channel->session, channel_read(channel, stream_id,
|
BLOCK_ADJUST(rc, channel->session,
|
||||||
buf, buflen));
|
_libssh2_channel_read(channel, stream_id, buf, buflen));
|
||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1958,9 +1900,9 @@ _libssh2_channel_packet_data_len(LIBSSH2_CHANNEL * channel, int stream_id)
|
|||||||
LIBSSH2_PACKET *read_packet;
|
LIBSSH2_PACKET *read_packet;
|
||||||
uint32_t read_local_id;
|
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;
|
return 0;
|
||||||
}
|
|
||||||
|
|
||||||
while (read_packet) {
|
while (read_packet) {
|
||||||
read_local_id = _libssh2_ntohu32(read_packet->data + 1);
|
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);
|
return (read_packet->data_len - read_packet->data_head);
|
||||||
}
|
}
|
||||||
read_packet = read_packet->next;
|
read_packet = _libssh2_list_next(&read_packet->node);
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
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 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
|
* send the entire packet, the caller must call this function again with the
|
||||||
* SAME input arguments.
|
* SAME input arguments.
|
||||||
|
*
|
||||||
|
* Returns: number of bytes sent, or if it returns a negative number, that is
|
||||||
|
* the error code!
|
||||||
*/
|
*/
|
||||||
ssize_t
|
ssize_t
|
||||||
_libssh2_channel_write(LIBSSH2_CHANNEL *channel, int stream_id,
|
_libssh2_channel_write(LIBSSH2_CHANNEL *channel, int stream_id,
|
||||||
const char *buf, size_t buflen)
|
const char *buf, size_t buflen)
|
||||||
{
|
{
|
||||||
LIBSSH2_SESSION *session = channel->session;
|
LIBSSH2_SESSION *session = channel->session;
|
||||||
libssh2pack_t rc;
|
int rc;
|
||||||
ssize_t wrote = 0; /* counter for this specific this call */
|
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) {
|
if (channel->write_state == libssh2_NB_state_idle) {
|
||||||
channel->write_bufwrote = 0;
|
channel->write_bufwrote = 0;
|
||||||
|
|
||||||
@@ -2021,7 +1974,7 @@ _libssh2_channel_write(LIBSSH2_CHANNEL *channel, int stream_id,
|
|||||||
if (channel->local.close) {
|
if (channel->local.close) {
|
||||||
libssh2_error(session, LIBSSH2_ERROR_CHANNEL_CLOSED,
|
libssh2_error(session, LIBSSH2_ERROR_CHANNEL_CLOSED,
|
||||||
"We've already closed this channel", 0);
|
"We've already closed this channel", 0);
|
||||||
return -1;
|
return LIBSSH2_ERROR_CHANNEL_CLOSED;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (channel->local.eof) {
|
if (channel->local.eof) {
|
||||||
@@ -2039,7 +1992,7 @@ _libssh2_channel_write(LIBSSH2_CHANNEL *channel, int stream_id,
|
|||||||
libssh2_error(session, LIBSSH2_ERROR_ALLOC,
|
libssh2_error(session, LIBSSH2_ERROR_ALLOC,
|
||||||
"Unable to allocte space for data transmission packet",
|
"Unable to allocte space for data transmission packet",
|
||||||
0);
|
0);
|
||||||
return -1;
|
return LIBSSH2_ERROR_ALLOC;
|
||||||
}
|
}
|
||||||
|
|
||||||
channel->write_state = libssh2_NB_state_allocated;
|
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) {
|
if(channel->local.window_size <= 0) {
|
||||||
/* there's no more room for data so we stop sending now */
|
/* 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;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -2112,20 +2060,20 @@ _libssh2_channel_write(LIBSSH2_CHANNEL *channel, int stream_id,
|
|||||||
|
|
||||||
if (channel->write_state == libssh2_NB_state_created) {
|
if (channel->write_state == libssh2_NB_state_created) {
|
||||||
rc = _libssh2_transport_write(session, channel->write_packet,
|
rc = _libssh2_transport_write(session, channel->write_packet,
|
||||||
channel->write_s -
|
channel->write_s -
|
||||||
channel->write_packet);
|
channel->write_packet);
|
||||||
if (rc == PACKET_EAGAIN) {
|
if (rc == PACKET_EAGAIN) {
|
||||||
_libssh2_debug(session, LIBSSH2_DBG_CONN,
|
libssh2_error(session, rc,
|
||||||
"libssh2_transport_write returned EAGAIN");
|
"Unable to send channel data", 0);
|
||||||
return PACKET_EAGAIN;
|
return rc;
|
||||||
}
|
}
|
||||||
else if (rc) {
|
else if (rc) {
|
||||||
libssh2_error(session, LIBSSH2_ERROR_SOCKET_SEND,
|
libssh2_error(session, rc,
|
||||||
"Unable to send channel data", 0);
|
"Unable to send channel data", 0);
|
||||||
LIBSSH2_FREE(session, channel->write_packet);
|
LIBSSH2_FREE(session, channel->write_packet);
|
||||||
channel->write_packet = NULL;
|
channel->write_packet = NULL;
|
||||||
channel->write_state = libssh2_NB_state_idle;
|
channel->write_state = libssh2_NB_state_idle;
|
||||||
return -1;
|
return rc;
|
||||||
}
|
}
|
||||||
/* Shrink local window size */
|
/* Shrink local window size */
|
||||||
channel->local.window_size -= channel->write_bufwrite;
|
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);
|
_libssh2_htonu32(packet + 1, channel->remote.id);
|
||||||
rc = _libssh2_transport_write(session, packet, 5);
|
rc = _libssh2_transport_write(session, packet, 5);
|
||||||
if (rc == PACKET_EAGAIN) {
|
if (rc == PACKET_EAGAIN) {
|
||||||
return PACKET_EAGAIN;
|
return rc;
|
||||||
}
|
}
|
||||||
else if (rc) {
|
else if (rc) {
|
||||||
libssh2_error(session, LIBSSH2_ERROR_SOCKET_SEND,
|
libssh2_error(session, LIBSSH2_ERROR_SOCKET_SEND,
|
||||||
"Unable to send EOF on channel", 0);
|
"Unable to send EOF on channel", 0);
|
||||||
return -1;
|
return LIBSSH2_ERROR_SOCKET_SEND;
|
||||||
}
|
}
|
||||||
channel->local.eof = 1;
|
channel->local.eof = 1;
|
||||||
|
|
||||||
@@ -2214,7 +2162,7 @@ LIBSSH2_API int
|
|||||||
libssh2_channel_eof(LIBSSH2_CHANNEL * channel)
|
libssh2_channel_eof(LIBSSH2_CHANNEL * channel)
|
||||||
{
|
{
|
||||||
LIBSSH2_SESSION *session = channel->session;
|
LIBSSH2_SESSION *session = channel->session;
|
||||||
LIBSSH2_PACKET *packet = session->packets.head;
|
LIBSSH2_PACKET *packet = _libssh2_list_first(&session->packets);
|
||||||
|
|
||||||
while (packet) {
|
while (packet) {
|
||||||
if (((packet->data[0] == SSH_MSG_CHANNEL_DATA)
|
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 */
|
/* There's data waiting to be read yet, mask the EOF status */
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
packet = packet->next;
|
packet = _libssh2_list_next(&packet->node);
|
||||||
}
|
}
|
||||||
|
|
||||||
return channel->remote.eof;
|
return channel->remote.eof;
|
||||||
@@ -2257,7 +2205,7 @@ static int channel_wait_eof(LIBSSH2_CHANNEL *channel)
|
|||||||
}
|
}
|
||||||
rc = _libssh2_transport_read(session);
|
rc = _libssh2_transport_read(session);
|
||||||
if (rc == PACKET_EAGAIN) {
|
if (rc == PACKET_EAGAIN) {
|
||||||
return PACKET_EAGAIN;
|
return rc;
|
||||||
}
|
}
|
||||||
else if (rc < 0) {
|
else if (rc < 0) {
|
||||||
channel->wait_eof_state = libssh2_NB_state_idle;
|
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) {
|
if (channel->close_state == libssh2_NB_state_created) {
|
||||||
retcode = _libssh2_transport_write(session, channel->close_packet, 5);
|
retcode = _libssh2_transport_write(session, channel->close_packet, 5);
|
||||||
if (retcode == PACKET_EAGAIN) {
|
if (retcode == PACKET_EAGAIN) {
|
||||||
return PACKET_EAGAIN;
|
return retcode;
|
||||||
} else if (retcode) {
|
} else if (retcode) {
|
||||||
libssh2_error(session, LIBSSH2_ERROR_SOCKET_SEND,
|
libssh2_error(session, retcode,
|
||||||
"Unable to send close-channel request", 0);
|
"Unable to send close-channel request", 0);
|
||||||
channel->close_state = libssh2_NB_state_idle;
|
channel->close_state = libssh2_NB_state_idle;
|
||||||
return -1;
|
return retcode;
|
||||||
}
|
}
|
||||||
|
|
||||||
channel->close_state = libssh2_NB_state_sent;
|
channel->close_state = libssh2_NB_state_sent;
|
||||||
@@ -2326,29 +2274,25 @@ channel_close(LIBSSH2_CHANNEL * channel)
|
|||||||
|
|
||||||
while (!channel->remote.close && !rc) {
|
while (!channel->remote.close && !rc) {
|
||||||
rc = _libssh2_transport_read(session);
|
rc = _libssh2_transport_read(session);
|
||||||
if (rc == PACKET_EAGAIN) {
|
|
||||||
return PACKET_EAGAIN;
|
|
||||||
}
|
|
||||||
else if (rc < 0)
|
|
||||||
rc = -1;
|
|
||||||
else
|
|
||||||
rc = 0;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* set the local close state first when we're perfectly confirmed to not
|
if(rc != LIBSSH2_ERROR_EAGAIN) {
|
||||||
do any more EAGAINs */
|
/* set the local close state first when we're perfectly confirmed to not
|
||||||
channel->local.close = 1;
|
do any more EAGAINs */
|
||||||
|
channel->local.close = 1;
|
||||||
|
|
||||||
/* We call the callback last in this function to make it keep the local
|
/* We call the callback last in this function to make it keep the local
|
||||||
data as long as EAGAIN is returned. */
|
data as long as EAGAIN is returned. */
|
||||||
if (channel->close_cb) {
|
if (channel->close_cb) {
|
||||||
LIBSSH2_CHANNEL_CLOSE(session, channel);
|
LIBSSH2_CHANNEL_CLOSE(session, channel);
|
||||||
|
}
|
||||||
|
|
||||||
|
channel->close_state = libssh2_NB_state_idle;
|
||||||
}
|
}
|
||||||
|
|
||||||
channel->close_state = libssh2_NB_state_idle;
|
/* return 0 or an error */
|
||||||
|
return rc>=0?0:rc;
|
||||||
return rc;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -2397,6 +2341,9 @@ static int channel_wait_closed(LIBSSH2_CHANNEL *channel)
|
|||||||
if (!channel->remote.close) {
|
if (!channel->remote.close) {
|
||||||
do {
|
do {
|
||||||
rc = _libssh2_transport_read(session);
|
rc = _libssh2_transport_read(session);
|
||||||
|
if (channel->remote.close)
|
||||||
|
/* it is now closed, move on! */
|
||||||
|
break;
|
||||||
} while (rc > 0);
|
} while (rc > 0);
|
||||||
if(rc < 0)
|
if(rc < 0)
|
||||||
return rc;
|
return rc;
|
||||||
@@ -2450,12 +2397,12 @@ int _libssh2_channel_free(LIBSSH2_CHANNEL *channel)
|
|||||||
if (!channel->local.close
|
if (!channel->local.close
|
||||||
&& (session->socket_state == LIBSSH2_SOCKET_CONNECTED)) {
|
&& (session->socket_state == LIBSSH2_SOCKET_CONNECTED)) {
|
||||||
rc = channel_close(channel);
|
rc = channel_close(channel);
|
||||||
|
|
||||||
if(rc == PACKET_EAGAIN)
|
if(rc == PACKET_EAGAIN)
|
||||||
return rc;
|
return rc;
|
||||||
|
else if (rc < 0) {
|
||||||
if (rc) {
|
|
||||||
channel->free_state = libssh2_NB_state_idle;
|
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);
|
LIBSSH2_FREE(session, channel->channel_type);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Unlink from channel brigade */
|
/* Unlink from channel list */
|
||||||
if (channel->prev) {
|
_libssh2_list_remove(&channel->node);
|
||||||
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;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Make sure all memory used in the state variables are free
|
* 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) {
|
if (read_avail) {
|
||||||
unsigned long bytes_queued = 0;
|
unsigned long bytes_queued = 0;
|
||||||
LIBSSH2_PACKET *packet = channel->session->packets.head;
|
LIBSSH2_PACKET *packet =
|
||||||
|
_libssh2_list_first(&channel->session->packets);
|
||||||
|
|
||||||
while (packet) {
|
while (packet) {
|
||||||
unsigned char packet_type = packet->data[0];
|
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;
|
bytes_queued += packet->data_len - packet->data_head;
|
||||||
}
|
}
|
||||||
|
|
||||||
packet = packet->next;
|
packet = _libssh2_list_next(&packet->node);
|
||||||
}
|
}
|
||||||
|
|
||||||
*read_avail = bytes_queued;
|
*read_avail = bytes_queued;
|
||||||
|
@@ -104,5 +104,17 @@ _libssh2_channel_process_startup(LIBSSH2_CHANNEL *channel,
|
|||||||
const char *request, unsigned int request_len,
|
const char *request, unsigned int request_len,
|
||||||
const char *message, unsigned int message_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 */
|
#endif /* __LIBSSH2_CHANNEL_H */
|
||||||
|
|
||||||
|
81
src/crypt.c
81
src/crypt.c
@@ -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.
|
* All rights reserved.
|
||||||
*
|
*
|
||||||
* Redistribution and use in source and binary forms,
|
* Redistribution and use in source and binary forms,
|
||||||
@@ -114,6 +115,44 @@ crypt_dtor(LIBSSH2_SESSION * session, void **abstract)
|
|||||||
return 0;
|
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
|
#if LIBSSH2_AES
|
||||||
static const LIBSSH2_CRYPT_METHOD libssh2_crypt_method_aes128_cbc = {
|
static const LIBSSH2_CRYPT_METHOD libssh2_crypt_method_aes128_cbc = {
|
||||||
"aes128-cbc",
|
"aes128-cbc",
|
||||||
@@ -192,6 +231,40 @@ static const LIBSSH2_CRYPT_METHOD libssh2_crypt_method_arcfour = {
|
|||||||
&crypt_dtor,
|
&crypt_dtor,
|
||||||
_libssh2_cipher_arcfour
|
_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 */
|
#endif /* LIBSSH2_RC4 */
|
||||||
|
|
||||||
#if LIBSSH2_CAST
|
#if LIBSSH2_CAST
|
||||||
@@ -223,6 +296,11 @@ static const LIBSSH2_CRYPT_METHOD libssh2_crypt_method_3des_cbc = {
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
static const LIBSSH2_CRYPT_METHOD *_libssh2_crypt_methods[] = {
|
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
|
#if LIBSSH2_AES
|
||||||
&libssh2_crypt_method_aes256_cbc,
|
&libssh2_crypt_method_aes256_cbc,
|
||||||
&libssh2_crypt_method_rijndael_cbc_lysator_liu_se, /* == aes256-cbc */
|
&libssh2_crypt_method_rijndael_cbc_lysator_liu_se, /* == aes256-cbc */
|
||||||
@@ -233,6 +311,7 @@ static const LIBSSH2_CRYPT_METHOD *_libssh2_crypt_methods[] = {
|
|||||||
&libssh2_crypt_method_blowfish_cbc,
|
&libssh2_crypt_method_blowfish_cbc,
|
||||||
#endif /* LIBSSH2_BLOWFISH */
|
#endif /* LIBSSH2_BLOWFISH */
|
||||||
#if LIBSSH2_RC4
|
#if LIBSSH2_RC4
|
||||||
|
&libssh2_crypt_method_arcfour128,
|
||||||
&libssh2_crypt_method_arcfour,
|
&libssh2_crypt_method_arcfour,
|
||||||
#endif /* LIBSSH2_RC4 */
|
#endif /* LIBSSH2_RC4 */
|
||||||
#if LIBSSH2_CAST
|
#if LIBSSH2_CAST
|
||||||
|
@@ -114,7 +114,6 @@ hostkey_method_ssh_rsa_initPEM(LIBSSH2_SESSION * session,
|
|||||||
void **abstract)
|
void **abstract)
|
||||||
{
|
{
|
||||||
libssh2_rsa_ctx *rsactx;
|
libssh2_rsa_ctx *rsactx;
|
||||||
FILE *fp;
|
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
if (*abstract) {
|
if (*abstract) {
|
||||||
@@ -122,13 +121,7 @@ hostkey_method_ssh_rsa_initPEM(LIBSSH2_SESSION * session,
|
|||||||
*abstract = NULL;
|
*abstract = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
fp = fopen(privkeyfile, "r");
|
ret = _libssh2_rsa_new_private(&rsactx, session, privkeyfile, passphrase);
|
||||||
if (!fp) {
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
ret = _libssh2_rsa_new_private(&rsactx, session, fp, passphrase);
|
|
||||||
fclose(fp);
|
|
||||||
if (ret) {
|
if (ret) {
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
@@ -296,7 +289,6 @@ hostkey_method_ssh_dss_initPEM(LIBSSH2_SESSION * session,
|
|||||||
void **abstract)
|
void **abstract)
|
||||||
{
|
{
|
||||||
libssh2_dsa_ctx *dsactx;
|
libssh2_dsa_ctx *dsactx;
|
||||||
FILE *fp;
|
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
if (*abstract) {
|
if (*abstract) {
|
||||||
@@ -304,13 +296,7 @@ hostkey_method_ssh_dss_initPEM(LIBSSH2_SESSION * session,
|
|||||||
*abstract = NULL;
|
*abstract = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
fp = fopen(privkeyfile, "r");
|
ret = _libssh2_dsa_new_private(&dsactx, session, privkeyfile, passphrase);
|
||||||
if (!fp) {
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
ret = _libssh2_dsa_new_private(&dsactx, session, fp, passphrase);
|
|
||||||
fclose(fp);
|
|
||||||
if (ret) {
|
if (ret) {
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
170
src/kex.c
170
src/kex.c
@@ -69,22 +69,20 @@
|
|||||||
} \
|
} \
|
||||||
}
|
}
|
||||||
|
|
||||||
/* kex_method_diffie_hellman_groupGP_sha1_key_exchange
|
/*
|
||||||
|
* diffie_hellman_sha1
|
||||||
|
*
|
||||||
* Diffie Hellman Key Exchange, Group Agnostic
|
* Diffie Hellman Key Exchange, Group Agnostic
|
||||||
*/
|
*/
|
||||||
static int
|
static int diffie_hellman_sha1(LIBSSH2_SESSION *session,
|
||||||
kex_method_diffie_hellman_groupGP_sha1_key_exchange(LIBSSH2_SESSION *session,
|
_libssh2_bn *g,
|
||||||
_libssh2_bn * g,
|
_libssh2_bn *p,
|
||||||
_libssh2_bn * p,
|
int group_order,
|
||||||
int group_order,
|
unsigned char packet_type_init,
|
||||||
unsigned char
|
unsigned char packet_type_reply,
|
||||||
packet_type_init,
|
unsigned char *midhash,
|
||||||
unsigned char
|
unsigned long midhash_len,
|
||||||
packet_type_reply,
|
kmdhgGPsha1kex_state_t *exchange_state)
|
||||||
unsigned char *midhash,
|
|
||||||
unsigned long midhash_len,
|
|
||||||
kmdhgGPsha1kex_state_t
|
|
||||||
* exchange_state)
|
|
||||||
{
|
{
|
||||||
int ret = 0;
|
int ret = 0;
|
||||||
int rc;
|
int rc;
|
||||||
@@ -122,7 +120,7 @@ kex_method_diffie_hellman_groupGP_sha1_key_exchange(LIBSSH2_SESSION *session,
|
|||||||
if (!exchange_state->e_packet) {
|
if (!exchange_state->e_packet) {
|
||||||
libssh2_error(session, LIBSSH2_ERROR_ALLOC, "Out of memory error",
|
libssh2_error(session, LIBSSH2_ERROR_ALLOC, "Out of memory error",
|
||||||
0);
|
0);
|
||||||
ret = -1;
|
ret = LIBSSH2_ERROR_ALLOC;
|
||||||
goto clean_exit;
|
goto clean_exit;
|
||||||
}
|
}
|
||||||
exchange_state->e_packet[0] = packet_type_init;
|
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,
|
rc = _libssh2_transport_write(session, exchange_state->e_packet,
|
||||||
exchange_state->e_packet_len);
|
exchange_state->e_packet_len);
|
||||||
if (rc == PACKET_EAGAIN) {
|
if (rc == PACKET_EAGAIN) {
|
||||||
return PACKET_EAGAIN;
|
return rc;
|
||||||
} else if (rc) {
|
} else if (rc) {
|
||||||
libssh2_error(session, LIBSSH2_ERROR_SOCKET_SEND,
|
libssh2_error(session, rc,
|
||||||
"Unable to send KEX init message", 0);
|
"Unable to send KEX init message", 0);
|
||||||
ret = -1;
|
ret = rc;
|
||||||
goto clean_exit;
|
goto clean_exit;
|
||||||
}
|
}
|
||||||
exchange_state->state = libssh2_NB_state_sent;
|
exchange_state->state = libssh2_NB_state_sent;
|
||||||
@@ -168,10 +166,10 @@ kex_method_diffie_hellman_groupGP_sha1_key_exchange(LIBSSH2_SESSION *session,
|
|||||||
burn_type =
|
burn_type =
|
||||||
_libssh2_packet_burn(session, &exchange_state->burn_state);
|
_libssh2_packet_burn(session, &exchange_state->burn_state);
|
||||||
if (burn_type == PACKET_EAGAIN) {
|
if (burn_type == PACKET_EAGAIN) {
|
||||||
return PACKET_EAGAIN;
|
return burn_type;
|
||||||
} else if (burn_type <= 0) {
|
} else if (burn_type <= 0) {
|
||||||
/* Failed to receive a packet */
|
/* Failed to receive a packet */
|
||||||
ret = -1;
|
ret = burn_type;
|
||||||
goto clean_exit;
|
goto clean_exit;
|
||||||
}
|
}
|
||||||
session->burn_optimistic_kexinit = 0;
|
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,
|
&exchange_state->s_packet_len, 0, NULL,
|
||||||
0, &exchange_state->req_state);
|
0, &exchange_state->req_state);
|
||||||
if (rc == PACKET_EAGAIN) {
|
if (rc == PACKET_EAGAIN) {
|
||||||
return PACKET_EAGAIN;
|
return rc;
|
||||||
}
|
}
|
||||||
if (rc) {
|
if (rc) {
|
||||||
libssh2_error(session, LIBSSH2_ERROR_TIMEOUT,
|
libssh2_error(session, LIBSSH2_ERROR_TIMEOUT,
|
||||||
"Timed out waiting for KEX reply", 0);
|
"Timed out waiting for KEX reply", 0);
|
||||||
ret = -1;
|
ret = rc;
|
||||||
goto clean_exit;
|
goto clean_exit;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -211,7 +209,7 @@ kex_method_diffie_hellman_groupGP_sha1_key_exchange(LIBSSH2_SESSION *session,
|
|||||||
libssh2_error(session, LIBSSH2_ERROR_ALLOC,
|
libssh2_error(session, LIBSSH2_ERROR_ALLOC,
|
||||||
"Unable to allocate memory for a copy of the host key",
|
"Unable to allocate memory for a copy of the host key",
|
||||||
0);
|
0);
|
||||||
ret = -1;
|
ret = LIBSSH2_ERROR_ALLOC;
|
||||||
goto clean_exit;
|
goto clean_exit;
|
||||||
}
|
}
|
||||||
memcpy(session->server_hostkey, exchange_state->s,
|
memcpy(session->server_hostkey, exchange_state->s,
|
||||||
@@ -263,12 +261,12 @@ kex_method_diffie_hellman_groupGP_sha1_key_exchange(LIBSSH2_SESSION *session,
|
|||||||
}
|
}
|
||||||
#endif /* LIBSSH2DEBUG */
|
#endif /* LIBSSH2DEBUG */
|
||||||
|
|
||||||
if (session->hostkey->
|
if (session->hostkey->init(session, session->server_hostkey,
|
||||||
init(session, session->server_hostkey, session->server_hostkey_len,
|
session->server_hostkey_len,
|
||||||
&session->server_hostkey_abstract)) {
|
&session->server_hostkey_abstract)) {
|
||||||
libssh2_error(session, LIBSSH2_ERROR_HOSTKEY_INIT,
|
libssh2_error(session, LIBSSH2_ERROR_HOSTKEY_INIT,
|
||||||
"Unable to initialize hostkey importer", 0);
|
"Unable to initialize hostkey importer", 0);
|
||||||
ret = -1;
|
ret = LIBSSH2_ERROR_HOSTKEY_INIT;
|
||||||
goto clean_exit;
|
goto clean_exit;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -296,7 +294,7 @@ kex_method_diffie_hellman_groupGP_sha1_key_exchange(LIBSSH2_SESSION *session,
|
|||||||
if (!exchange_state->k_value) {
|
if (!exchange_state->k_value) {
|
||||||
libssh2_error(session, LIBSSH2_ERROR_ALLOC,
|
libssh2_error(session, LIBSSH2_ERROR_ALLOC,
|
||||||
"Unable to allocate buffer for K", 0);
|
"Unable to allocate buffer for K", 0);
|
||||||
ret = -1;
|
ret = LIBSSH2_ERROR_ALLOC;
|
||||||
goto clean_exit;
|
goto clean_exit;
|
||||||
}
|
}
|
||||||
_libssh2_htonu32(exchange_state->k_value,
|
_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) {
|
if (exchange_state->state == libssh2_NB_state_sent2) {
|
||||||
rc = _libssh2_transport_write(session, &exchange_state->c, 1);
|
rc = _libssh2_transport_write(session, &exchange_state->c, 1);
|
||||||
if (rc == PACKET_EAGAIN) {
|
if (rc == PACKET_EAGAIN) {
|
||||||
return PACKET_EAGAIN;
|
return rc;
|
||||||
} else if (rc) {
|
} else if (rc) {
|
||||||
libssh2_error(session, LIBSSH2_ERROR_SOCKET_SEND,
|
libssh2_error(session, rc, "Unable to send NEWKEYS message", 0);
|
||||||
"Unable to send NEWKEYS message", 0);
|
ret = rc;
|
||||||
ret = -1;
|
|
||||||
goto clean_exit;
|
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->tmp_len, 0, NULL, 0,
|
||||||
&exchange_state->req_state);
|
&exchange_state->req_state);
|
||||||
if (rc == PACKET_EAGAIN) {
|
if (rc == PACKET_EAGAIN) {
|
||||||
return PACKET_EAGAIN;
|
return rc;
|
||||||
} else if (rc) {
|
} else if (rc) {
|
||||||
libssh2_error(session, LIBSSH2_ERROR_TIMEOUT,
|
libssh2_error(session, rc, "Timed out waiting for NEWKEYS", 0);
|
||||||
"Timed out waiting for NEWKEYS", 0);
|
ret = rc;
|
||||||
ret = -1;
|
|
||||||
goto clean_exit;
|
goto clean_exit;
|
||||||
}
|
}
|
||||||
/* The first key exchange has been performed,
|
/* 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) {
|
if (!session->session_id) {
|
||||||
session->session_id = LIBSSH2_ALLOC(session, SHA_DIGEST_LENGTH);
|
session->session_id = LIBSSH2_ALLOC(session, SHA_DIGEST_LENGTH);
|
||||||
if (!session->session_id) {
|
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;
|
goto clean_exit;
|
||||||
}
|
}
|
||||||
memcpy(session->session_id, exchange_state->h_sig_comp,
|
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");
|
secret_len, "C");
|
||||||
if (!secret) {
|
if (!secret) {
|
||||||
LIBSSH2_FREE(session, iv);
|
LIBSSH2_FREE(session, iv);
|
||||||
ret = -1;
|
ret = LIBSSH2_ERROR_KEX_FAILURE;
|
||||||
goto clean_exit;
|
goto clean_exit;
|
||||||
}
|
}
|
||||||
if (session->local.crypt->
|
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)) {
|
&free_secret, 1, &session->local.crypt_abstract)) {
|
||||||
LIBSSH2_FREE(session, iv);
|
LIBSSH2_FREE(session, iv);
|
||||||
LIBSSH2_FREE(session, secret);
|
LIBSSH2_FREE(session, secret);
|
||||||
ret = -1;
|
ret = LIBSSH2_ERROR_KEX_FAILURE;
|
||||||
goto clean_exit;
|
goto clean_exit;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -528,7 +526,7 @@ kex_method_diffie_hellman_groupGP_sha1_key_exchange(LIBSSH2_SESSION *session,
|
|||||||
session->remote.crypt->
|
session->remote.crypt->
|
||||||
iv_len, "B");
|
iv_len, "B");
|
||||||
if (!iv) {
|
if (!iv) {
|
||||||
ret = -1;
|
ret = LIBSSH2_ERROR_KEX_FAILURE;
|
||||||
goto clean_exit;
|
goto clean_exit;
|
||||||
}
|
}
|
||||||
LIBSSH2_KEX_METHOD_DIFFIE_HELLMAN_SHA1_HASH(secret,
|
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");
|
secret_len, "D");
|
||||||
if (!secret) {
|
if (!secret) {
|
||||||
LIBSSH2_FREE(session, iv);
|
LIBSSH2_FREE(session, iv);
|
||||||
ret = -1;
|
ret = LIBSSH2_ERROR_KEX_FAILURE;
|
||||||
goto clean_exit;
|
goto clean_exit;
|
||||||
}
|
}
|
||||||
if (session->remote.crypt->
|
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)) {
|
&free_secret, 0, &session->remote.crypt_abstract)) {
|
||||||
LIBSSH2_FREE(session, iv);
|
LIBSSH2_FREE(session, iv);
|
||||||
LIBSSH2_FREE(session, secret);
|
LIBSSH2_FREE(session, secret);
|
||||||
ret = -1;
|
ret = LIBSSH2_ERROR_KEX_FAILURE;
|
||||||
goto clean_exit;
|
goto clean_exit;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -573,7 +571,7 @@ kex_method_diffie_hellman_groupGP_sha1_key_exchange(LIBSSH2_SESSION *session,
|
|||||||
session->local.mac->
|
session->local.mac->
|
||||||
key_len, "E");
|
key_len, "E");
|
||||||
if (!key) {
|
if (!key) {
|
||||||
ret = -1;
|
ret = LIBSSH2_ERROR_KEX_FAILURE;
|
||||||
goto clean_exit;
|
goto clean_exit;
|
||||||
}
|
}
|
||||||
session->local.mac->init(session, key, &free_key,
|
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->
|
session->remote.mac->
|
||||||
key_len, "F");
|
key_len, "F");
|
||||||
if (!key) {
|
if (!key) {
|
||||||
ret = -1;
|
ret = LIBSSH2_ERROR_KEX_FAILURE;
|
||||||
goto clean_exit;
|
goto clean_exit;
|
||||||
}
|
}
|
||||||
session->remote.mac->init(session, key, &free_key,
|
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;
|
key_state->state = libssh2_NB_state_created;
|
||||||
}
|
}
|
||||||
|
ret = diffie_hellman_sha1(session, key_state->g, key_state->p, 128,
|
||||||
ret =
|
SSH_MSG_KEXDH_INIT, SSH_MSG_KEXDH_REPLY,
|
||||||
kex_method_diffie_hellman_groupGP_sha1_key_exchange(session,
|
NULL, 0, &key_state->exchange_state);
|
||||||
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) {
|
if (ret == PACKET_EAGAIN) {
|
||||||
return PACKET_EAGAIN;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
_libssh2_bn_free(key_state->p);
|
_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;
|
key_state->state = libssh2_NB_state_created;
|
||||||
}
|
}
|
||||||
ret =
|
ret = diffie_hellman_sha1(session, key_state->g, key_state->p,
|
||||||
kex_method_diffie_hellman_groupGP_sha1_key_exchange(session,
|
256, SSH_MSG_KEXDH_INIT, SSH_MSG_KEXDH_REPLY,
|
||||||
key_state->g,
|
NULL, 0, &key_state->exchange_state);
|
||||||
key_state->p,
|
|
||||||
256,
|
|
||||||
SSH_MSG_KEXDH_INIT,
|
|
||||||
SSH_MSG_KEXDH_REPLY,
|
|
||||||
NULL, 0,
|
|
||||||
&key_state->
|
|
||||||
exchange_state);
|
|
||||||
if (ret == PACKET_EAGAIN) {
|
if (ret == PACKET_EAGAIN) {
|
||||||
return PACKET_EAGAIN;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
key_state->state = libssh2_NB_state_idle;
|
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,
|
rc = _libssh2_transport_write(session, key_state->request,
|
||||||
key_state->request_len);
|
key_state->request_len);
|
||||||
if (rc == PACKET_EAGAIN) {
|
if (rc == PACKET_EAGAIN) {
|
||||||
return PACKET_EAGAIN;
|
return rc;
|
||||||
} else if (rc) {
|
} else if (rc) {
|
||||||
libssh2_error(session, LIBSSH2_ERROR_SOCKET_SEND,
|
libssh2_error(session, rc,
|
||||||
"Unable to send Group Exchange Request", 0);
|
"Unable to send Group Exchange Request", 0);
|
||||||
ret = -1;
|
ret = rc;
|
||||||
goto dh_gex_clean_exit;
|
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,
|
&key_state->data, &key_state->data_len,
|
||||||
0, NULL, 0, &key_state->req_state);
|
0, NULL, 0, &key_state->req_state);
|
||||||
if (rc == PACKET_EAGAIN) {
|
if (rc == PACKET_EAGAIN) {
|
||||||
return PACKET_EAGAIN;
|
return rc;
|
||||||
} else if (rc) {
|
} else if (rc) {
|
||||||
libssh2_error(session, LIBSSH2_ERROR_TIMEOUT,
|
libssh2_error(session, rc,
|
||||||
"Timeout waiting for GEX_GROUP reply", 0);
|
"Timeout waiting for GEX_GROUP reply", 0);
|
||||||
ret = -1;
|
ret = rc;
|
||||||
goto dh_gex_clean_exit;
|
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);
|
_libssh2_bn_from_bin(key_state->g, g_len, s);
|
||||||
s += g_len;
|
s += g_len;
|
||||||
|
|
||||||
ret =
|
ret = diffie_hellman_sha1(session, key_state->g, key_state->p, p_len,
|
||||||
kex_method_diffie_hellman_groupGP_sha1_key_exchange
|
SSH_MSG_KEX_DH_GEX_INIT,
|
||||||
(session, key_state->g, key_state->p, p_len,
|
SSH_MSG_KEX_DH_GEX_REPLY,
|
||||||
SSH_MSG_KEX_DH_GEX_INIT, SSH_MSG_KEX_DH_GEX_REPLY,
|
key_state->data + 1,
|
||||||
key_state->data + 1, key_state->data_len - 1,
|
key_state->data_len - 1,
|
||||||
&key_state->exchange_state);
|
&key_state->exchange_state);
|
||||||
if (ret == PACKET_EAGAIN) {
|
if (ret == PACKET_EAGAIN) {
|
||||||
return PACKET_EAGAIN;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
LIBSSH2_FREE(session, key_state->data);
|
LIBSSH2_FREE(session, key_state->data);
|
||||||
@@ -1056,7 +1040,7 @@ static int kexinit(LIBSSH2_SESSION * session)
|
|||||||
if (!data) {
|
if (!data) {
|
||||||
libssh2_error(session, LIBSSH2_ERROR_ALLOC,
|
libssh2_error(session, LIBSSH2_ERROR_ALLOC,
|
||||||
"Unable to allocate memory", 0);
|
"Unable to allocate memory", 0);
|
||||||
return -1;
|
return LIBSSH2_ERROR_ALLOC;
|
||||||
}
|
}
|
||||||
|
|
||||||
*(s++) = SSH_MSG_KEXINIT;
|
*(s++) = SSH_MSG_KEXINIT;
|
||||||
@@ -1139,14 +1123,14 @@ static int kexinit(LIBSSH2_SESSION * session)
|
|||||||
if (rc == PACKET_EAGAIN) {
|
if (rc == PACKET_EAGAIN) {
|
||||||
session->kexinit_data = data;
|
session->kexinit_data = data;
|
||||||
session->kexinit_data_len = data_len;
|
session->kexinit_data_len = data_len;
|
||||||
return PACKET_EAGAIN;
|
return rc;
|
||||||
}
|
}
|
||||||
else if (rc) {
|
else if (rc) {
|
||||||
LIBSSH2_FREE(session, data);
|
LIBSSH2_FREE(session, data);
|
||||||
libssh2_error(session, LIBSSH2_ERROR_SOCKET_SEND,
|
libssh2_error(session, rc,
|
||||||
"Unable to send KEXINIT packet to remote host", 0);
|
"Unable to send KEXINIT packet to remote host", 0);
|
||||||
session->kexinit_state = libssh2_NB_state_idle;
|
session->kexinit_state = libssh2_NB_state_idle;
|
||||||
return -1;
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (session->local.kexinit) {
|
if (session->local.kexinit) {
|
||||||
@@ -1662,6 +1646,8 @@ static int kex_agree_methods(LIBSSH2_SESSION * session, unsigned char *data,
|
|||||||
/* libssh2_kex_exchange
|
/* libssh2_kex_exchange
|
||||||
* Exchange keys
|
* Exchange keys
|
||||||
* Returns 0 on success, non-zero on failure
|
* Returns 0 on success, non-zero on failure
|
||||||
|
*
|
||||||
|
* Returns some errors without libssh2_error()
|
||||||
*/
|
*/
|
||||||
int
|
int
|
||||||
libssh2_kex_exchange(LIBSSH2_SESSION * session, int reexchange,
|
libssh2_kex_exchange(LIBSSH2_SESSION * session, int reexchange,
|
||||||
@@ -1704,7 +1690,7 @@ libssh2_kex_exchange(LIBSSH2_SESSION * session, int reexchange,
|
|||||||
retcode = kexinit(session);
|
retcode = kexinit(session);
|
||||||
if (retcode == PACKET_EAGAIN) {
|
if (retcode == PACKET_EAGAIN) {
|
||||||
session->state &= ~LIBSSH2_STATE_KEX_ACTIVE;
|
session->state &= ~LIBSSH2_STATE_KEX_ACTIVE;
|
||||||
return PACKET_EAGAIN;
|
return retcode;
|
||||||
} else if (retcode) {
|
} else if (retcode) {
|
||||||
session->local.kexinit = key_state->oldlocal;
|
session->local.kexinit = key_state->oldlocal;
|
||||||
session->local.kexinit_len = key_state->oldlocal_len;
|
session->local.kexinit_len = key_state->oldlocal_len;
|
||||||
@@ -1725,7 +1711,7 @@ libssh2_kex_exchange(LIBSSH2_SESSION * session, int reexchange,
|
|||||||
&key_state->req_state);
|
&key_state->req_state);
|
||||||
if (retcode == PACKET_EAGAIN) {
|
if (retcode == PACKET_EAGAIN) {
|
||||||
session->state &= ~LIBSSH2_STATE_KEX_ACTIVE;
|
session->state &= ~LIBSSH2_STATE_KEX_ACTIVE;
|
||||||
return PACKET_EAGAIN;
|
return retcode;
|
||||||
}
|
}
|
||||||
else if (retcode) {
|
else if (retcode) {
|
||||||
if (session->local.kexinit) {
|
if (session->local.kexinit) {
|
||||||
@@ -1746,9 +1732,8 @@ libssh2_kex_exchange(LIBSSH2_SESSION * session, int reexchange,
|
|||||||
session->remote.kexinit_len = key_state->data_len;
|
session->remote.kexinit_len = key_state->data_len;
|
||||||
|
|
||||||
if (kex_agree_methods(session, key_state->data,
|
if (kex_agree_methods(session, key_state->data,
|
||||||
key_state->data_len)) {
|
key_state->data_len))
|
||||||
rc = -1;
|
rc = LIBSSH2_ERROR_KEX_FAILURE;
|
||||||
}
|
|
||||||
|
|
||||||
key_state->state = libssh2_NB_state_sent2;
|
key_state->state = libssh2_NB_state_sent2;
|
||||||
}
|
}
|
||||||
@@ -1758,16 +1743,15 @@ libssh2_kex_exchange(LIBSSH2_SESSION * session, int reexchange,
|
|||||||
|
|
||||||
if (rc == 0) {
|
if (rc == 0) {
|
||||||
if (key_state->state == libssh2_NB_state_sent2) {
|
if (key_state->state == libssh2_NB_state_sent2) {
|
||||||
retcode =
|
retcode = session->kex->exchange_keys(session,
|
||||||
session->kex->exchange_keys(session,
|
&key_state->key_state_low);
|
||||||
&key_state->key_state_low);
|
|
||||||
if (retcode == PACKET_EAGAIN) {
|
if (retcode == PACKET_EAGAIN) {
|
||||||
session->state &= ~LIBSSH2_STATE_KEX_ACTIVE;
|
session->state &= ~LIBSSH2_STATE_KEX_ACTIVE;
|
||||||
return PACKET_EAGAIN;
|
return retcode;
|
||||||
} else if (retcode) {
|
} else if (retcode) {
|
||||||
libssh2_error(session, LIBSSH2_ERROR_KEY_EXCHANGE_FAILURE,
|
libssh2_error(session, LIBSSH2_ERROR_KEY_EXCHANGE_FAILURE,
|
||||||
"Unrecoverable error exchanging keys", 0);
|
"Unrecoverable error exchanging keys", 0);
|
||||||
rc = -1;
|
rc = retcode;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -1,5 +1,5 @@
|
|||||||
/* Copyright (C) 2006, 2007, The Written Word, Inc.
|
/* Copyright (C) 2008, 2009, Simon Josefsson
|
||||||
* Copyright (C) 2008, Simon Josefsson
|
* Copyright (C) 2006, 2007, The Written Word, Inc.
|
||||||
* All rights reserved.
|
* All rights reserved.
|
||||||
*
|
*
|
||||||
* Redistribution and use in source and binary forms,
|
* Redistribution and use in source and binary forms,
|
||||||
@@ -37,6 +37,9 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#include "libssh2_priv.h"
|
#include "libssh2_priv.h"
|
||||||
|
|
||||||
|
#ifdef LIBSSH2_LIBGCRYPT /* compile only if we build with libgcrypt */
|
||||||
|
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
int
|
int
|
||||||
@@ -149,8 +152,9 @@ _libssh2_dsa_new(libssh2_dsa_ctx ** dsactx,
|
|||||||
int
|
int
|
||||||
_libssh2_rsa_new_private(libssh2_rsa_ctx ** rsa,
|
_libssh2_rsa_new_private(libssh2_rsa_ctx ** rsa,
|
||||||
LIBSSH2_SESSION * session,
|
LIBSSH2_SESSION * session,
|
||||||
FILE * fp, unsigned const char *passphrase)
|
const char *filename, unsigned const char *passphrase)
|
||||||
{
|
{
|
||||||
|
FILE *fp;
|
||||||
unsigned char *data, *save_data;
|
unsigned char *data, *save_data;
|
||||||
unsigned int datalen;
|
unsigned int datalen;
|
||||||
int ret;
|
int ret;
|
||||||
@@ -159,10 +163,16 @@ _libssh2_rsa_new_private(libssh2_rsa_ctx ** rsa,
|
|||||||
|
|
||||||
(void) passphrase;
|
(void) passphrase;
|
||||||
|
|
||||||
|
fp = fopen(filename, "r");
|
||||||
|
if (!fp) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
ret = _libssh2_pem_parse(session,
|
ret = _libssh2_pem_parse(session,
|
||||||
"-----BEGIN RSA PRIVATE KEY-----",
|
"-----BEGIN RSA PRIVATE KEY-----",
|
||||||
"-----END RSA PRIVATE KEY-----",
|
"-----END RSA PRIVATE KEY-----",
|
||||||
fp, &data, &datalen);
|
fp, &data, &datalen);
|
||||||
|
fclose(fp);
|
||||||
if (ret) {
|
if (ret) {
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
@@ -244,8 +254,9 @@ _libssh2_rsa_new_private(libssh2_rsa_ctx ** rsa,
|
|||||||
int
|
int
|
||||||
_libssh2_dsa_new_private(libssh2_dsa_ctx ** dsa,
|
_libssh2_dsa_new_private(libssh2_dsa_ctx ** dsa,
|
||||||
LIBSSH2_SESSION * session,
|
LIBSSH2_SESSION * session,
|
||||||
FILE * fp, unsigned const char *passphrase)
|
const char *filename, unsigned const char *passphrase)
|
||||||
{
|
{
|
||||||
|
FILE *fp;
|
||||||
unsigned char *data, *save_data;
|
unsigned char *data, *save_data;
|
||||||
unsigned int datalen;
|
unsigned int datalen;
|
||||||
int ret;
|
int ret;
|
||||||
@@ -254,10 +265,16 @@ _libssh2_dsa_new_private(libssh2_dsa_ctx ** dsa,
|
|||||||
|
|
||||||
(void) passphrase;
|
(void) passphrase;
|
||||||
|
|
||||||
|
fp = fopen(filename, "r");
|
||||||
|
if (!fp) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
ret = _libssh2_pem_parse(session,
|
ret = _libssh2_pem_parse(session,
|
||||||
"-----BEGIN DSA PRIVATE KEY-----",
|
"-----BEGIN DSA PRIVATE KEY-----",
|
||||||
"-----END DSA PRIVATE KEY-----",
|
"-----END DSA PRIVATE KEY-----",
|
||||||
fp, &data, &datalen);
|
fp, &data, &datalen);
|
||||||
|
fclose(fp);
|
||||||
if (ret) {
|
if (ret) {
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
@@ -507,16 +524,14 @@ _libssh2_cipher_init(_libssh2_cipher_ctx * h,
|
|||||||
_libssh2_cipher_type(algo),
|
_libssh2_cipher_type(algo),
|
||||||
unsigned char *iv, unsigned char *secret, int encrypt)
|
unsigned char *iv, unsigned char *secret, int encrypt)
|
||||||
{
|
{
|
||||||
int mode = 0, ret;
|
int ret;
|
||||||
int keylen = gcry_cipher_get_algo_keylen(algo);
|
int cipher = _libssh2_gcry_cipher (algo);
|
||||||
|
int mode = _libssh2_gcry_mode (algo);
|
||||||
|
int keylen = gcry_cipher_get_algo_keylen(cipher);
|
||||||
|
|
||||||
(void) encrypt;
|
(void) encrypt;
|
||||||
|
|
||||||
if (algo != GCRY_CIPHER_ARCFOUR) {
|
ret = gcry_cipher_open(h, cipher, mode, 0);
|
||||||
mode = GCRY_CIPHER_MODE_CBC;
|
|
||||||
}
|
|
||||||
|
|
||||||
ret = gcry_cipher_open(h, algo, mode, 0);
|
|
||||||
if (ret) {
|
if (ret) {
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
@@ -527,10 +542,13 @@ _libssh2_cipher_init(_libssh2_cipher_ctx * h,
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (algo != GCRY_CIPHER_ARCFOUR) {
|
if (mode != GCRY_CIPHER_MODE_STREAM) {
|
||||||
int blklen = gcry_cipher_get_algo_blklen(algo);
|
int blklen = gcry_cipher_get_algo_blklen(cipher);
|
||||||
ret = gcry_cipher_setiv(*h, iv, blklen);
|
if (mode == GCRY_CIPHER_MODE_CTR)
|
||||||
if (ret) {
|
ret = gcry_cipher_setctr(*h, iv, blklen);
|
||||||
|
else
|
||||||
|
ret = gcry_cipher_setiv(*h, iv, blklen);
|
||||||
|
if (ret) {
|
||||||
gcry_cipher_close(*h);
|
gcry_cipher_close(*h);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
@@ -544,8 +562,10 @@ _libssh2_cipher_crypt(_libssh2_cipher_ctx * ctx,
|
|||||||
_libssh2_cipher_type(algo),
|
_libssh2_cipher_type(algo),
|
||||||
int encrypt, unsigned char *block)
|
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;
|
int ret;
|
||||||
|
|
||||||
if (blklen == 1) {
|
if (blklen == 1) {
|
||||||
/* Hack for arcfour. */
|
/* Hack for arcfour. */
|
||||||
blklen = 8;
|
blklen = 8;
|
||||||
@@ -558,3 +578,5 @@ _libssh2_cipher_crypt(_libssh2_cipher_ctx * ctx,
|
|||||||
}
|
}
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#endif /* LIBSSH2_LIBGCRYPT */
|
||||||
|
@@ -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.
|
* All rights reserved.
|
||||||
*
|
*
|
||||||
* Redistribution and use in source and binary forms,
|
* Redistribution and use in source and binary forms,
|
||||||
@@ -43,6 +44,7 @@
|
|||||||
#define LIBSSH2_HMAC_RIPEMD 1
|
#define LIBSSH2_HMAC_RIPEMD 1
|
||||||
|
|
||||||
#define LIBSSH2_AES 1
|
#define LIBSSH2_AES 1
|
||||||
|
#define LIBSSH2_AES_CTR 1
|
||||||
#define LIBSSH2_BLOWFISH 1
|
#define LIBSSH2_BLOWFISH 1
|
||||||
#define LIBSSH2_RC4 1
|
#define LIBSSH2_RC4 1
|
||||||
#define LIBSSH2_CAST 1
|
#define LIBSSH2_CAST 1
|
||||||
@@ -112,7 +114,8 @@ int _libssh2_rsa_new(libssh2_rsa_ctx ** rsa,
|
|||||||
const unsigned char *coeffdata, unsigned long coefflen);
|
const unsigned char *coeffdata, unsigned long coefflen);
|
||||||
int _libssh2_rsa_new_private(libssh2_rsa_ctx ** rsa,
|
int _libssh2_rsa_new_private(libssh2_rsa_ctx ** rsa,
|
||||||
LIBSSH2_SESSION * session,
|
LIBSSH2_SESSION * session,
|
||||||
FILE * fp, unsigned const char *passphrase);
|
const char *filename,
|
||||||
|
unsigned const char *passphrase);
|
||||||
int _libssh2_rsa_sha1_verify(libssh2_rsa_ctx * rsa,
|
int _libssh2_rsa_sha1_verify(libssh2_rsa_ctx * rsa,
|
||||||
const unsigned char *sig,
|
const unsigned char *sig,
|
||||||
unsigned long sig_len,
|
unsigned long sig_len,
|
||||||
@@ -140,7 +143,8 @@ int _libssh2_dsa_new(libssh2_dsa_ctx ** dsa,
|
|||||||
const unsigned char *x, unsigned long x_len);
|
const unsigned char *x, unsigned long x_len);
|
||||||
int _libssh2_dsa_new_private(libssh2_dsa_ctx ** dsa,
|
int _libssh2_dsa_new_private(libssh2_dsa_ctx ** dsa,
|
||||||
LIBSSH2_SESSION * session,
|
LIBSSH2_SESSION * session,
|
||||||
FILE * fp, unsigned const char *passphrase);
|
const char *filename,
|
||||||
|
unsigned const char *passphrase);
|
||||||
int _libssh2_dsa_sha1_verify(libssh2_dsa_ctx * dsa,
|
int _libssh2_dsa_sha1_verify(libssh2_dsa_ctx * dsa,
|
||||||
const unsigned char *sig,
|
const unsigned char *sig,
|
||||||
const unsigned char *m, unsigned long m_len);
|
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_type(name) int name
|
||||||
#define _libssh2_cipher_ctx gcry_cipher_hd_t
|
#define _libssh2_cipher_ctx gcry_cipher_hd_t
|
||||||
|
|
||||||
#define _libssh2_cipher_aes256 GCRY_CIPHER_AES256
|
#define _libssh2_gcry_ciphermode(c,m) ((c << 8) | m)
|
||||||
#define _libssh2_cipher_aes192 GCRY_CIPHER_AES192
|
#define _libssh2_gcry_cipher(c) (c >> 8)
|
||||||
#define _libssh2_cipher_aes128 GCRY_CIPHER_AES128
|
#define _libssh2_gcry_mode(m) (m & 0xFF)
|
||||||
#define _libssh2_cipher_blowfish GCRY_CIPHER_BLOWFISH
|
|
||||||
#define _libssh2_cipher_arcfour GCRY_CIPHER_ARCFOUR
|
#define _libssh2_cipher_aes256ctr \
|
||||||
#define _libssh2_cipher_cast5 GCRY_CIPHER_CAST5
|
_libssh2_gcry_ciphermode(GCRY_CIPHER_AES256, GCRY_CIPHER_MODE_CTR)
|
||||||
#define _libssh2_cipher_3des GCRY_CIPHER_3DES
|
#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,
|
int _libssh2_cipher_init(_libssh2_cipher_ctx * h,
|
||||||
_libssh2_cipher_type(algo),
|
_libssh2_cipher_type(algo),
|
||||||
|
@@ -85,6 +85,7 @@
|
|||||||
#include "libssh2.h"
|
#include "libssh2.h"
|
||||||
#include "libssh2_publickey.h"
|
#include "libssh2_publickey.h"
|
||||||
#include "libssh2_sftp.h"
|
#include "libssh2_sftp.h"
|
||||||
|
#include "misc.h" /* for the linked list stuff */
|
||||||
|
|
||||||
#ifndef FALSE
|
#ifndef FALSE
|
||||||
#define FALSE 0
|
#define FALSE 0
|
||||||
@@ -96,10 +97,9 @@
|
|||||||
/* Provide iovec / writev on WIN32 platform. */
|
/* Provide iovec / writev on WIN32 platform. */
|
||||||
#ifdef WIN32
|
#ifdef WIN32
|
||||||
|
|
||||||
/* same as WSABUF */
|
|
||||||
struct iovec {
|
struct iovec {
|
||||||
u_long iov_len;
|
size_t iov_len;
|
||||||
char *iov_base;
|
void * iov_base;
|
||||||
};
|
};
|
||||||
|
|
||||||
#define inline __inline
|
#define inline __inline
|
||||||
@@ -149,6 +149,12 @@ static inline int writev(int sock, struct iovec *iov, int nvecs)
|
|||||||
|
|
||||||
#endif
|
#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:
|
/* RFC4253 section 6.1 Maximum Packet Length says:
|
||||||
*
|
*
|
||||||
* "All implementations MUST be able to process packets with
|
* "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_COMP_METHOD LIBSSH2_COMP_METHOD;
|
||||||
|
|
||||||
typedef struct _LIBSSH2_PACKET LIBSSH2_PACKET;
|
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
|
typedef enum
|
||||||
{
|
{
|
||||||
@@ -288,6 +290,7 @@ typedef struct packet_queue_listener_state_t
|
|||||||
uint32_t sport;
|
uint32_t sport;
|
||||||
uint32_t host_len;
|
uint32_t host_len;
|
||||||
uint32_t shost_len;
|
uint32_t shost_len;
|
||||||
|
LIBSSH2_CHANNEL *channel;
|
||||||
} packet_queue_listener_state_t;
|
} packet_queue_listener_state_t;
|
||||||
|
|
||||||
#define X11FwdUnAvil "X11 Forward Unavailable"
|
#define X11FwdUnAvil "X11 Forward Unavailable"
|
||||||
@@ -302,10 +305,13 @@ typedef struct packet_x11_open_state_t
|
|||||||
uint32_t packet_size;
|
uint32_t packet_size;
|
||||||
uint32_t sport;
|
uint32_t sport;
|
||||||
uint32_t shost_len;
|
uint32_t shost_len;
|
||||||
|
LIBSSH2_CHANNEL *channel;
|
||||||
} packet_x11_open_state_t;
|
} packet_x11_open_state_t;
|
||||||
|
|
||||||
struct _LIBSSH2_PACKET
|
struct _LIBSSH2_PACKET
|
||||||
{
|
{
|
||||||
|
struct list_node node; /* linked list header */
|
||||||
|
|
||||||
unsigned char type;
|
unsigned char type;
|
||||||
|
|
||||||
/* Unencrypted Payload (no type byte, no padding, just the facts ma'am) */
|
/* Unencrypted Payload (no type byte, no padding, just the facts ma'am) */
|
||||||
@@ -318,15 +324,6 @@ struct _LIBSSH2_PACKET
|
|||||||
|
|
||||||
/* Can the message be confirmed? */
|
/* Can the message be confirmed? */
|
||||||
int mac;
|
int mac;
|
||||||
|
|
||||||
LIBSSH2_PACKET_BRIGADE *brigade;
|
|
||||||
|
|
||||||
LIBSSH2_PACKET *next, *prev;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct _LIBSSH2_PACKET_BRIGADE
|
|
||||||
{
|
|
||||||
LIBSSH2_PACKET *head, *tail;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef struct _libssh2_channel_data
|
typedef struct _libssh2_channel_data
|
||||||
@@ -343,6 +340,8 @@ typedef struct _libssh2_channel_data
|
|||||||
|
|
||||||
struct _LIBSSH2_CHANNEL
|
struct _LIBSSH2_CHANNEL
|
||||||
{
|
{
|
||||||
|
struct list_node node;
|
||||||
|
|
||||||
unsigned char *channel_type;
|
unsigned char *channel_type;
|
||||||
unsigned channel_type_len;
|
unsigned channel_type_len;
|
||||||
|
|
||||||
@@ -355,8 +354,6 @@ struct _LIBSSH2_CHANNEL
|
|||||||
|
|
||||||
LIBSSH2_SESSION *session;
|
LIBSSH2_SESSION *session;
|
||||||
|
|
||||||
LIBSSH2_CHANNEL *next, *prev;
|
|
||||||
|
|
||||||
void *abstract;
|
void *abstract;
|
||||||
LIBSSH2_CHANNEL_CLOSE_FUNC((*close_cb));
|
LIBSSH2_CHANNEL_CLOSE_FUNC((*close_cb));
|
||||||
|
|
||||||
@@ -399,8 +396,6 @@ struct _LIBSSH2_CHANNEL
|
|||||||
|
|
||||||
/* State variables used in libssh2_channel_read_ex() */
|
/* State variables used in libssh2_channel_read_ex() */
|
||||||
libssh2_nonblocking_states read_state;
|
libssh2_nonblocking_states read_state;
|
||||||
LIBSSH2_PACKET *read_packet;
|
|
||||||
LIBSSH2_PACKET *read_next;
|
|
||||||
|
|
||||||
uint32_t read_local_id;
|
uint32_t read_local_id;
|
||||||
|
|
||||||
@@ -429,24 +424,21 @@ struct _LIBSSH2_CHANNEL
|
|||||||
libssh2_nonblocking_states extData2_state;
|
libssh2_nonblocking_states extData2_state;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct _LIBSSH2_CHANNEL_BRIGADE
|
|
||||||
{
|
|
||||||
LIBSSH2_CHANNEL *head, *tail;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct _LIBSSH2_LISTENER
|
struct _LIBSSH2_LISTENER
|
||||||
{
|
{
|
||||||
|
struct list_node node; /* linked list header */
|
||||||
|
|
||||||
LIBSSH2_SESSION *session;
|
LIBSSH2_SESSION *session;
|
||||||
|
|
||||||
char *host;
|
char *host;
|
||||||
int port;
|
int port;
|
||||||
|
|
||||||
LIBSSH2_CHANNEL *queue;
|
/* a list of CHANNELs for this listener */
|
||||||
|
struct list_head queue;
|
||||||
|
|
||||||
int queue_size;
|
int queue_size;
|
||||||
int queue_maxsize;
|
int queue_maxsize;
|
||||||
|
|
||||||
LIBSSH2_LISTENER *prev, *next;
|
|
||||||
|
|
||||||
/* State variables used in libssh2_channel_forward_cancel() */
|
/* State variables used in libssh2_channel_forward_cancel() */
|
||||||
libssh2_nonblocking_states chanFwdCncl_state;
|
libssh2_nonblocking_states chanFwdCncl_state;
|
||||||
unsigned char *chanFwdCncl_data;
|
unsigned char *chanFwdCncl_data;
|
||||||
@@ -547,8 +539,9 @@ struct _LIBSSH2_PUBLICKEY
|
|||||||
|
|
||||||
struct _LIBSSH2_SFTP_HANDLE
|
struct _LIBSSH2_SFTP_HANDLE
|
||||||
{
|
{
|
||||||
|
struct list_node node;
|
||||||
|
|
||||||
LIBSSH2_SFTP *sftp;
|
LIBSSH2_SFTP *sftp;
|
||||||
LIBSSH2_SFTP_HANDLE *prev, *next;
|
|
||||||
|
|
||||||
/* This is a pre-allocated buffer used for sending SFTP requests as the
|
/* 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,
|
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;
|
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;
|
unsigned long last_errno;
|
||||||
|
|
||||||
@@ -713,18 +707,19 @@ struct _LIBSSH2_SESSION
|
|||||||
/* (local as source of data -- packet_write ) */
|
/* (local as source of data -- packet_write ) */
|
||||||
libssh2_endpoint_data local;
|
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 */
|
packet we're ready for */
|
||||||
LIBSSH2_PACKET_BRIGADE packets;
|
struct list_head packets;
|
||||||
|
|
||||||
/* Active connection channels */
|
/* Active connection channels */
|
||||||
LIBSSH2_CHANNEL_BRIGADE channels;
|
struct list_head channels;
|
||||||
|
|
||||||
unsigned long next_channel;
|
unsigned long next_channel;
|
||||||
|
|
||||||
LIBSSH2_LISTENER *listeners;
|
struct list_head listeners; /* list of LIBSSH2_LISTENER structs */
|
||||||
|
|
||||||
/* Actual I/O socket */
|
/* Actual I/O socket */
|
||||||
int socket_fd;
|
libssh2_socket_t socket_fd;
|
||||||
int socket_state;
|
int socket_state;
|
||||||
int socket_block_directions;
|
int socket_block_directions;
|
||||||
int socket_prev_blockstate; /* stores the state of the socket blockiness
|
int socket_prev_blockstate; /* stores the state of the socket blockiness
|
||||||
@@ -811,7 +806,7 @@ struct _LIBSSH2_SESSION
|
|||||||
unsigned char *userauth_pblc_b;
|
unsigned char *userauth_pblc_b;
|
||||||
packet_requirev_state_t userauth_pblc_packet_requirev_state;
|
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;
|
libssh2_nonblocking_states userauth_kybd_state;
|
||||||
unsigned char *userauth_kybd_data;
|
unsigned char *userauth_kybd_data;
|
||||||
unsigned long userauth_kybd_data_len;
|
unsigned long userauth_kybd_data_len;
|
||||||
@@ -860,7 +855,6 @@ struct _LIBSSH2_SESSION
|
|||||||
|
|
||||||
/* State variables used in libssh2_packet_add() */
|
/* State variables used in libssh2_packet_add() */
|
||||||
libssh2_nonblocking_states packAdd_state;
|
libssh2_nonblocking_states packAdd_state;
|
||||||
LIBSSH2_PACKET *packAdd_packet;
|
|
||||||
LIBSSH2_CHANNEL *packAdd_channel;
|
LIBSSH2_CHANNEL *packAdd_channel;
|
||||||
unsigned long packAdd_data_head;
|
unsigned long packAdd_data_head;
|
||||||
key_exchange_state_t packAdd_key_state;
|
key_exchange_state_t packAdd_key_state;
|
||||||
@@ -871,7 +865,7 @@ struct _LIBSSH2_SESSION
|
|||||||
libssh2_nonblocking_states fullpacket_state;
|
libssh2_nonblocking_states fullpacket_state;
|
||||||
int fullpacket_macstate;
|
int fullpacket_macstate;
|
||||||
int fullpacket_payload_len;
|
int fullpacket_payload_len;
|
||||||
libssh2pack_t fullpacket_packet_type;
|
int fullpacket_packet_type;
|
||||||
|
|
||||||
/* State variables used in libssh2_sftp_init() */
|
/* State variables used in libssh2_sftp_init() */
|
||||||
libssh2_nonblocking_states sftpInit_state;
|
libssh2_nonblocking_states sftpInit_state;
|
||||||
@@ -928,22 +922,6 @@ struct _LIBSSH2_SESSION
|
|||||||
#define LIBSSH2_SOCKET_RECV_FLAGS(session) 0
|
#define LIBSSH2_SOCKET_RECV_FLAGS(session) 0
|
||||||
#endif
|
#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
|
/* 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);
|
void _libssh2_htonu32(unsigned char *buf, unsigned int val);
|
||||||
|
|
||||||
#ifdef WIN32
|
#ifdef WIN32
|
||||||
ssize_t _libssh2_recv(int socket, 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(int socket, const void *buffer, size_t length, int flags);
|
ssize_t _libssh2_send(libssh2_socket_t socket, const void *buffer, size_t length, int flags);
|
||||||
#else
|
#else
|
||||||
#define _libssh2_recv(a,b,c,d) recv(a,b,c,d)
|
#define _libssh2_recv(a,b,c,d) recv(a,b,c,d)
|
||||||
#define _libssh2_send(a,b,c,d) send(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);
|
int _libssh2_wait_socket(LIBSSH2_SESSION *session);
|
||||||
|
|
||||||
|
|
||||||
/* CAUTION: some of these error codes are returned in the public API and is
|
/* These started out as private return codes for the transport layer, but was
|
||||||
there known with other #defined names from the public header file. They
|
converted to using the library-wide return codes to easy propagation of the
|
||||||
should not be changed. */
|
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_TIMEOUT LIBSSH2_ERROR_TIMEOUT
|
||||||
#define PACKET_BADUSE -6
|
#define PACKET_BADUSE LIBSSH2_ERROR_BAD_USE
|
||||||
#define PACKET_COMPRESS -5
|
#define PACKET_COMPRESS LIBSSH2_ERROR_COMPRESS
|
||||||
#define PACKET_TOOBIG -4
|
#define PACKET_TOOBIG LIBSSH2_ERROR_OUT_OF_BOUNDARY
|
||||||
#define PACKET_ENOMEM -3
|
#define PACKET_ENOMEM LIBSSH2_ERROR_ALLOC
|
||||||
#define PACKET_EAGAIN LIBSSH2_ERROR_EAGAIN
|
#define PACKET_EAGAIN LIBSSH2_ERROR_EAGAIN
|
||||||
#define PACKET_FAIL -1
|
#define PACKET_FAIL LIBSSH2_ERROR_SOCKET_NONE
|
||||||
#define PACKET_NONE 0
|
#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,
|
int _libssh2_packet_ask(LIBSSH2_SESSION * session, unsigned char packet_type,
|
||||||
unsigned char **data, unsigned long *data_len,
|
unsigned char **data, unsigned long *data_len,
|
||||||
|
82
src/misc.c
82
src/misc.c
@@ -78,7 +78,7 @@ static int wsa2errno(void)
|
|||||||
* to set errno
|
* to set errno
|
||||||
*/
|
*/
|
||||||
ssize_t
|
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);
|
ssize_t rc = recv(socket, buffer, length, flags);
|
||||||
#ifdef WIN32
|
#ifdef WIN32
|
||||||
@@ -97,7 +97,7 @@ _libssh2_recv(int socket, void *buffer, size_t length, int flags)
|
|||||||
* to set errno
|
* to set errno
|
||||||
*/
|
*/
|
||||||
ssize_t
|
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);
|
ssize_t rc = send(socket, buffer, length, flags);
|
||||||
#ifdef WIN32
|
#ifdef WIN32
|
||||||
@@ -426,3 +426,81 @@ void _libssh2_list_remove(struct list_node *entry)
|
|||||||
else
|
else
|
||||||
entry->head->last = entry->prev;
|
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
|
||||||
|
15
src/misc.h
15
src/misc.h
@@ -38,11 +38,20 @@
|
|||||||
* OF SUCH DAMAGE.
|
* 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);
|
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,
|
void _libssh2_list_add(struct list_head *head,
|
||||||
struct list_node *entry);
|
struct list_node *entry);
|
||||||
|
|
||||||
@@ -58,6 +67,6 @@ void *_libssh2_list_prev(struct list_node *node);
|
|||||||
/* remove this node from the list */
|
/* remove this node from the list */
|
||||||
void _libssh2_list_remove(struct list_node *entry);
|
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);
|
const char *inp, size_t insize, char **outptr);
|
||||||
#endif /* _LIBSSH2_MISC_H */
|
#endif /* _LIBSSH2_MISC_H */
|
||||||
|
174
src/openssl.c
174
src/openssl.c
@@ -1,7 +1,9 @@
|
|||||||
/* Copyright (C) 2006, 2007 The Written Word, Inc. All rights reserved.
|
/* Copyright (C) 2009 Simon Josefsson
|
||||||
* Author: Simon Josefsson
|
* Copyright (C) 2006, 2007 The Written Word, Inc. All rights reserved.
|
||||||
* Copyright (c) 2004-2006, Sara Golemon <sarag@libssh2.org>
|
* Copyright (c) 2004-2006, Sara Golemon <sarag@libssh2.org>
|
||||||
*
|
*
|
||||||
|
* Author: Simon Josefsson
|
||||||
|
*
|
||||||
* Redistribution and use in source and binary forms,
|
* Redistribution and use in source and binary forms,
|
||||||
* with or without modification, are permitted provided
|
* with or without modification, are permitted provided
|
||||||
* that the following conditions are met:
|
* that the following conditions are met:
|
||||||
@@ -37,15 +39,15 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#include "libssh2_priv.h"
|
#include "libssh2_priv.h"
|
||||||
|
|
||||||
|
#ifndef LIBSSH2_LIBGCRYPT /* compile only if we build with OpenSSL */
|
||||||
|
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
#ifndef EVP_MAX_BLOCK_LENGTH
|
#ifndef EVP_MAX_BLOCK_LENGTH
|
||||||
#define EVP_MAX_BLOCK_LENGTH 32
|
#define EVP_MAX_BLOCK_LENGTH 32
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* Ridiculously large key-file size cap (512KB) */
|
|
||||||
#define MAX_KEY_FILE_LENGTH 524288
|
|
||||||
|
|
||||||
int
|
int
|
||||||
_libssh2_rsa_new(libssh2_rsa_ctx ** rsa,
|
_libssh2_rsa_new(libssh2_rsa_ctx ** rsa,
|
||||||
const unsigned char *edata,
|
const unsigned char *edata,
|
||||||
@@ -197,6 +199,106 @@ _libssh2_cipher_crypt(_libssh2_cipher_ctx * ctx,
|
|||||||
return ret == 1 ? 0 : 1;
|
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
|
/* TODO: Optionally call a passphrase callback specified by the
|
||||||
* calling program
|
* calling program
|
||||||
*/
|
*/
|
||||||
@@ -215,61 +317,21 @@ passphrase_cb(char *buf, int size, int rwflag, char *passphrase)
|
|||||||
return passphrase_len;
|
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 *,
|
typedef void * (*pem_read_bio_func)(BIO *, void **, pem_password_cb *,
|
||||||
void * u);
|
void * u);
|
||||||
|
|
||||||
static int
|
static int
|
||||||
read_private_key_from_file(void ** key_ctx, LIBSSH2_SESSION * session,
|
read_private_key_from_file(void ** key_ctx, LIBSSH2_SESSION * session,
|
||||||
pem_read_bio_func read_private_key,
|
pem_read_bio_func read_private_key,
|
||||||
FILE * fp, unsigned const char *passphrase)
|
const char * filename,
|
||||||
|
unsigned const char *passphrase)
|
||||||
{
|
{
|
||||||
char * key;
|
|
||||||
BIO * bp;
|
BIO * bp;
|
||||||
|
|
||||||
*key_ctx = NULL;
|
*key_ctx = NULL;
|
||||||
|
|
||||||
if(read_file_into_string(&key, session, fp)) {
|
bp = BIO_new_file(filename, "r");
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
bp = BIO_new_mem_buf(key, -1);
|
|
||||||
if (!bp) {
|
if (!bp) {
|
||||||
LIBSSH2_FREE(session, key);
|
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -277,17 +339,17 @@ read_private_key_from_file(void ** key_ctx, LIBSSH2_SESSION * session,
|
|||||||
(void *) passphrase);
|
(void *) passphrase);
|
||||||
|
|
||||||
BIO_free(bp);
|
BIO_free(bp);
|
||||||
LIBSSH2_FREE(session, key);
|
|
||||||
return (*key_ctx) ? 0 : -1;
|
return (*key_ctx) ? 0 : -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
_libssh2_rsa_new_private(libssh2_rsa_ctx ** rsa,
|
_libssh2_rsa_new_private(libssh2_rsa_ctx ** rsa,
|
||||||
LIBSSH2_SESSION * session,
|
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 read_rsa =
|
||||||
(pem_read_bio_func) &PEM_read_bio_RSAPrivateKey;
|
(pem_read_bio_func) &PEM_read_bio_RSAPrivateKey;
|
||||||
|
(void) session;
|
||||||
|
|
||||||
if (!EVP_get_cipherbyname("des")) {
|
if (!EVP_get_cipherbyname("des")) {
|
||||||
/* If this cipher isn't loaded it's a pretty good indication that none are.
|
/* If this cipher isn't loaded it's a pretty good indication that none are.
|
||||||
@@ -297,14 +359,14 @@ _libssh2_rsa_new_private(libssh2_rsa_ctx ** rsa,
|
|||||||
OpenSSL_add_all_ciphers();
|
OpenSSL_add_all_ciphers();
|
||||||
}
|
}
|
||||||
|
|
||||||
return read_private_key_from_file((void **) rsa, session, read_rsa, fp,
|
return read_private_key_from_file((void **) rsa, session, read_rsa,
|
||||||
passphrase);
|
filename, passphrase);
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
_libssh2_dsa_new_private(libssh2_dsa_ctx ** dsa,
|
_libssh2_dsa_new_private(libssh2_dsa_ctx ** dsa,
|
||||||
LIBSSH2_SESSION * session,
|
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 read_dsa =
|
||||||
(pem_read_bio_func) &PEM_read_bio_DSAPrivateKey;
|
(pem_read_bio_func) &PEM_read_bio_DSAPrivateKey;
|
||||||
@@ -317,8 +379,8 @@ _libssh2_dsa_new_private(libssh2_dsa_ctx ** dsa,
|
|||||||
OpenSSL_add_all_ciphers();
|
OpenSSL_add_all_ciphers();
|
||||||
}
|
}
|
||||||
|
|
||||||
return read_private_key_from_file((void **) dsa, session, read_dsa, fp,
|
return read_private_key_from_file((void **) dsa, session, read_dsa,
|
||||||
passphrase);
|
filename, passphrase);
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
@@ -381,3 +443,5 @@ _libssh2_dsa_sha1_sign(libssh2_dsa_ctx * dsactx,
|
|||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#endif /* !LIBSSH2_LIBGCRYPT */
|
||||||
|
@@ -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
|
* Author: Simon Josefsson
|
||||||
*
|
*
|
||||||
* Redistribution and use in source and binary forms,
|
* Redistribution and use in source and binary forms,
|
||||||
@@ -71,6 +73,7 @@
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if OPENSSL_VERSION_NUMBER >= 0x00907000L && !defined(OPENSSL_NO_AES)
|
#if OPENSSL_VERSION_NUMBER >= 0x00907000L && !defined(OPENSSL_NO_AES)
|
||||||
|
# define LIBSSH2_AES_CTR 1
|
||||||
# define LIBSSH2_AES 1
|
# define LIBSSH2_AES 1
|
||||||
#else
|
#else
|
||||||
# define LIBSSH2_AES 0
|
# define LIBSSH2_AES 0
|
||||||
@@ -148,7 +151,8 @@ int _libssh2_rsa_new(libssh2_rsa_ctx ** rsa,
|
|||||||
const unsigned char *coeffdata, unsigned long coefflen);
|
const unsigned char *coeffdata, unsigned long coefflen);
|
||||||
int _libssh2_rsa_new_private(libssh2_rsa_ctx ** rsa,
|
int _libssh2_rsa_new_private(libssh2_rsa_ctx ** rsa,
|
||||||
LIBSSH2_SESSION * session,
|
LIBSSH2_SESSION * session,
|
||||||
FILE * fp, unsigned const char *passphrase);
|
const char *filename,
|
||||||
|
unsigned const char *passphrase);
|
||||||
int _libssh2_rsa_sha1_verify(libssh2_rsa_ctx * rsa,
|
int _libssh2_rsa_sha1_verify(libssh2_rsa_ctx * rsa,
|
||||||
const unsigned char *sig,
|
const unsigned char *sig,
|
||||||
unsigned long sig_len,
|
unsigned long sig_len,
|
||||||
@@ -176,7 +180,8 @@ int _libssh2_dsa_new(libssh2_dsa_ctx ** dsa,
|
|||||||
const unsigned char *x, unsigned long x_len);
|
const unsigned char *x, unsigned long x_len);
|
||||||
int _libssh2_dsa_new_private(libssh2_dsa_ctx ** dsa,
|
int _libssh2_dsa_new_private(libssh2_dsa_ctx ** dsa,
|
||||||
LIBSSH2_SESSION * session,
|
LIBSSH2_SESSION * session,
|
||||||
FILE * fp, unsigned const char *passphrase);
|
const char *filename,
|
||||||
|
unsigned const char *passphrase);
|
||||||
int _libssh2_dsa_sha1_verify(libssh2_dsa_ctx * dsactx,
|
int _libssh2_dsa_sha1_verify(libssh2_dsa_ctx * dsactx,
|
||||||
const unsigned char *sig,
|
const unsigned char *sig,
|
||||||
const unsigned char *m, unsigned long m_len);
|
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_aes256 EVP_aes_256_cbc
|
||||||
#define _libssh2_cipher_aes192 EVP_aes_192_cbc
|
#define _libssh2_cipher_aes192 EVP_aes_192_cbc
|
||||||
#define _libssh2_cipher_aes128 EVP_aes_128_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_blowfish EVP_bf_cbc
|
||||||
#define _libssh2_cipher_arcfour EVP_rc4
|
#define _libssh2_cipher_arcfour EVP_rc4
|
||||||
#define _libssh2_cipher_cast5 EVP_cast5_cbc
|
#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_bytes(bn) BN_num_bytes(bn)
|
||||||
#define _libssh2_bn_bits(bn) BN_num_bits(bn)
|
#define _libssh2_bn_bits(bn) BN_num_bits(bn)
|
||||||
#define _libssh2_bn_free(bn) BN_clear_free(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);
|
||||||
|
382
src/packet.c
382
src/packet.c
@@ -60,6 +60,7 @@
|
|||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
|
|
||||||
#include "transport.h"
|
#include "transport.h"
|
||||||
|
#include "channel.h"
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* libssh2_packet_queue_listener
|
* libssh2_packet_queue_listener
|
||||||
@@ -69,7 +70,7 @@
|
|||||||
static inline int
|
static inline int
|
||||||
packet_queue_listener(LIBSSH2_SESSION * session, unsigned char *data,
|
packet_queue_listener(LIBSSH2_SESSION * session, unsigned char *data,
|
||||||
unsigned long datalen,
|
unsigned long datalen,
|
||||||
packet_queue_listener_state_t * listen_state)
|
packet_queue_listener_state_t *listen_state)
|
||||||
{
|
{
|
||||||
/*
|
/*
|
||||||
* Look for a matching listener
|
* 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) */
|
/* 17 = packet_type(1) + channel(4) + reason(4) + descr(4) + lang(4) */
|
||||||
unsigned long packet_len = 17 + (sizeof(FwdNotReq) - 1);
|
unsigned long packet_len = 17 + (sizeof(FwdNotReq) - 1);
|
||||||
unsigned char *p;
|
unsigned char *p;
|
||||||
LIBSSH2_LISTENER *listen = session->listeners;
|
LIBSSH2_LISTENER *listen = _libssh2_list_first(&session->listeners);
|
||||||
char failure_code = 1; /* SSH_OPEN_ADMINISTRATIVELY_PROHIBITED */
|
char failure_code = 1; /* SSH_OPEN_ADMINISTRATIVELY_PROHIBITED */
|
||||||
int rc;
|
int rc;
|
||||||
|
|
||||||
@@ -119,13 +120,12 @@ packet_queue_listener(LIBSSH2_SESSION * session, unsigned char *data,
|
|||||||
while (listen) {
|
while (listen) {
|
||||||
if ((listen->port == (int) listen_state->port) &&
|
if ((listen->port == (int) listen_state->port) &&
|
||||||
(strlen(listen->host) == listen_state->host_len) &&
|
(strlen(listen->host) == listen_state->host_len) &&
|
||||||
(memcmp
|
(memcmp (listen->host, listen_state->host,
|
||||||
(listen->host, listen_state->host,
|
listen_state->host_len) == 0)) {
|
||||||
listen_state->host_len) == 0)) {
|
|
||||||
/* This is our listener */
|
/* 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_state->state == libssh2_NB_state_allocated) {
|
||||||
if (listen->queue_maxsize &&
|
if (listen->queue_maxsize &&
|
||||||
(listen->queue_maxsize <= listen->queue_size)) {
|
(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;
|
listen_state->state = libssh2_NB_state_sent;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
listen_state->channel = channel;
|
||||||
|
|
||||||
memset(channel, 0, sizeof(LIBSSH2_CHANNEL));
|
memset(channel, 0, sizeof(LIBSSH2_CHANNEL));
|
||||||
|
|
||||||
channel->session = session;
|
channel->session = session;
|
||||||
@@ -206,31 +208,19 @@ packet_queue_listener(LIBSSH2_SESSION * session, unsigned char *data,
|
|||||||
if (listen_state->state == libssh2_NB_state_created) {
|
if (listen_state->state == libssh2_NB_state_created) {
|
||||||
rc = _libssh2_transport_write(session, listen_state->packet,
|
rc = _libssh2_transport_write(session, listen_state->packet,
|
||||||
17);
|
17);
|
||||||
if (rc == PACKET_EAGAIN) {
|
if (rc == PACKET_EAGAIN)
|
||||||
return PACKET_EAGAIN;
|
return rc;
|
||||||
} else if (rc) {
|
else if (rc) {
|
||||||
libssh2_error(session, LIBSSH2_ERROR_SOCKET_SEND,
|
libssh2_error(session, rc,
|
||||||
"Unable to send channel open confirmation",
|
"Unable to send channel "
|
||||||
0);
|
"open confirmation", 0);
|
||||||
listen_state->state = libssh2_NB_state_idle;
|
listen_state->state = libssh2_NB_state_idle;
|
||||||
return -1;
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Link the channel into the end of the queue list */
|
/* Link the channel into the end of the queue list */
|
||||||
|
_libssh2_list_add(&listen->queue,
|
||||||
if (!last_queued) {
|
&listen_state->channel->node);
|
||||||
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;
|
|
||||||
|
|
||||||
listen->queue_size++;
|
listen->queue_size++;
|
||||||
|
|
||||||
listen_state->state = libssh2_NB_state_idle;
|
listen_state->state = libssh2_NB_state_idle;
|
||||||
@@ -238,39 +228,36 @@ 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;
|
listen_state->state = libssh2_NB_state_sent;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* We're not listening to you */
|
/* We're not listening to you */
|
||||||
{
|
p = listen_state->packet;
|
||||||
p = listen_state->packet;
|
*(p++) = SSH_MSG_CHANNEL_OPEN_FAILURE;
|
||||||
*(p++) = SSH_MSG_CHANNEL_OPEN_FAILURE;
|
_libssh2_htonu32(p, listen_state->sender_channel);
|
||||||
_libssh2_htonu32(p, listen_state->sender_channel);
|
p += 4;
|
||||||
p += 4;
|
_libssh2_htonu32(p, failure_code);
|
||||||
_libssh2_htonu32(p, failure_code);
|
p += 4;
|
||||||
p += 4;
|
_libssh2_htonu32(p, sizeof(FwdNotReq) - 1);
|
||||||
_libssh2_htonu32(p, sizeof(FwdNotReq) - 1);
|
p += 4;
|
||||||
p += 4;
|
memcpy(s, FwdNotReq, sizeof(FwdNotReq) - 1);
|
||||||
memcpy(s, FwdNotReq, sizeof(FwdNotReq) - 1);
|
p += sizeof(FwdNotReq) - 1;
|
||||||
p += sizeof(FwdNotReq) - 1;
|
_libssh2_htonu32(p, 0);
|
||||||
_libssh2_htonu32(p, 0);
|
|
||||||
|
|
||||||
rc = _libssh2_transport_write(session, listen_state->packet,
|
rc = _libssh2_transport_write(session, listen_state->packet,
|
||||||
packet_len);
|
packet_len);
|
||||||
if (rc == PACKET_EAGAIN) {
|
if (rc == PACKET_EAGAIN) {
|
||||||
return PACKET_EAGAIN;
|
return rc;
|
||||||
} else if (rc) {
|
} else if (rc) {
|
||||||
libssh2_error(session, LIBSSH2_ERROR_SOCKET_SEND,
|
libssh2_error(session, rc, "Unable to send open failure", 0);
|
||||||
"Unable to send open failure", 0);
|
|
||||||
listen_state->state = libssh2_NB_state_idle;
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
listen_state->state = libssh2_NB_state_idle;
|
listen_state->state = libssh2_NB_state_idle;
|
||||||
return 0;
|
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
|
static inline int
|
||||||
packet_x11_open(LIBSSH2_SESSION * session, unsigned char *data,
|
packet_x11_open(LIBSSH2_SESSION * session, unsigned char *data,
|
||||||
unsigned long datalen,
|
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 */
|
int failure_code = 2; /* SSH_OPEN_CONNECT_FAILED */
|
||||||
unsigned char *s = data + (sizeof("x11") - 1) + 5;
|
unsigned char *s = data + (sizeof("x11") - 1) + 5;
|
||||||
/* 17 = packet_type(1) + channel(4) + reason(4) + descr(4) + lang(4) */
|
/* 17 = packet_type(1) + channel(4) + reason(4) + descr(4) + lang(4) */
|
||||||
unsigned long packet_len = 17 + (sizeof(X11FwdUnAvil) - 1);
|
unsigned long packet_len = 17 + (sizeof(X11FwdUnAvil) - 1);
|
||||||
unsigned char *p;
|
unsigned char *p;
|
||||||
LIBSSH2_CHANNEL *channel = NULL;
|
LIBSSH2_CHANNEL *channel = x11open_state->channel;
|
||||||
int rc;
|
int rc;
|
||||||
|
|
||||||
(void) datalen;
|
(void) datalen;
|
||||||
@@ -379,7 +366,7 @@ packet_x11_open(LIBSSH2_SESSION * session, unsigned char *data,
|
|||||||
if (x11open_state->state == libssh2_NB_state_created) {
|
if (x11open_state->state == libssh2_NB_state_created) {
|
||||||
rc = _libssh2_transport_write(session, x11open_state->packet, 17);
|
rc = _libssh2_transport_write(session, x11open_state->packet, 17);
|
||||||
if (rc == PACKET_EAGAIN) {
|
if (rc == PACKET_EAGAIN) {
|
||||||
return PACKET_EAGAIN;
|
return rc;
|
||||||
} else if (rc) {
|
} else if (rc) {
|
||||||
libssh2_error(session, LIBSSH2_ERROR_SOCKET_SEND,
|
libssh2_error(session, LIBSSH2_ERROR_SOCKET_SEND,
|
||||||
"Unable to send channel open confirmation", 0);
|
"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 */
|
/* Link the channel into the session */
|
||||||
if (session->channels.tail) {
|
_libssh2_list_add(&session->channels, &channel->node);
|
||||||
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;
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Pass control to the callback, they may turn right around and
|
* Pass control to the callback, they may turn right around and
|
||||||
* free the channel, or actually use it
|
* 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->sport);
|
||||||
|
|
||||||
x11open_state->state = libssh2_NB_state_idle;
|
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);
|
rc = _libssh2_transport_write(session, x11open_state->packet, packet_len);
|
||||||
if (rc == PACKET_EAGAIN) {
|
if (rc == PACKET_EAGAIN) {
|
||||||
return PACKET_EAGAIN;
|
return rc;
|
||||||
} else if (rc) {
|
} else if (rc) {
|
||||||
libssh2_error(session, LIBSSH2_ERROR_SOCKET_SEND,
|
libssh2_error(session, rc, "Unable to send open failure", 0);
|
||||||
"Unable to send open failure", 0);
|
|
||||||
x11open_state->state = libssh2_NB_state_idle;
|
x11open_state->state = libssh2_NB_state_idle;
|
||||||
return -1;
|
return rc;
|
||||||
}
|
}
|
||||||
x11open_state->state = libssh2_NB_state_idle;
|
x11open_state->state = libssh2_NB_state_idle;
|
||||||
return 0;
|
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
|
* Create a new packet and attach it to the brigade. Called from the transport
|
||||||
* layer when it as received a packet.
|
* 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
|
int
|
||||||
_libssh2_packet_add(LIBSSH2_SESSION * session, unsigned char *data,
|
_libssh2_packet_add(LIBSSH2_SESSION * session, unsigned char *data,
|
||||||
@@ -469,23 +450,10 @@ _libssh2_packet_add(LIBSSH2_SESSION * session, unsigned char *data,
|
|||||||
"Packet type %d received, length=%d",
|
"Packet type %d received, length=%d",
|
||||||
(int) data[0], (int) datalen);
|
(int) data[0], (int) datalen);
|
||||||
if (macstate == LIBSSH2_MAC_INVALID) {
|
if (macstate == LIBSSH2_MAC_INVALID) {
|
||||||
if (session->macerror) {
|
if (session->macerror &&
|
||||||
if (LIBSSH2_MACERROR(session, (char *) data, datalen) == 0) {
|
LIBSSH2_MACERROR(session, (char *) data, datalen) == 0) {
|
||||||
/* Calling app has given the OK, Process it anyway */
|
/* Calling app has given the OK, Process it anyway */
|
||||||
macstate = LIBSSH2_MAC_CONFIRMED;
|
macstate = LIBSSH2_MAC_CONFIRMED;
|
||||||
} 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;
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
libssh2_error(session, LIBSSH2_ERROR_INVALID_MAC,
|
libssh2_error(session, LIBSSH2_ERROR_INVALID_MAC,
|
||||||
"Invalid Message Authentication Code received",
|
"Invalid Message Authentication Code received",
|
||||||
@@ -497,7 +465,7 @@ _libssh2_packet_add(LIBSSH2_SESSION * session, unsigned char *data,
|
|||||||
"", 0);
|
"", 0);
|
||||||
}
|
}
|
||||||
LIBSSH2_FREE(session, data);
|
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';
|
message[message_len] = '\0';
|
||||||
language = (char *) data + 9 + message_len + 3;
|
language = (char *) data + 9 + message_len + 3;
|
||||||
if (language_len) {
|
if (language_len) {
|
||||||
memcpy(language, language + 1, language_len);
|
memmove(language, language + 1, language_len);
|
||||||
}
|
}
|
||||||
language[language_len] = '\0';
|
language[language_len] = '\0';
|
||||||
|
|
||||||
@@ -558,21 +526,26 @@ _libssh2_packet_add(LIBSSH2_SESSION * session, unsigned char *data,
|
|||||||
LIBSSH2_FREE(session, data);
|
LIBSSH2_FREE(session, data);
|
||||||
session->socket_state = LIBSSH2_SOCKET_DISCONNECTED;
|
session->socket_state = LIBSSH2_SOCKET_DISCONNECTED;
|
||||||
session->packAdd_state = libssh2_NB_state_idle;
|
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;
|
break;
|
||||||
|
|
||||||
case SSH_MSG_IGNORE:
|
case SSH_MSG_IGNORE:
|
||||||
/* As with disconnect, back it up one and add a trailing NULL */
|
if (datalen >= 5) {
|
||||||
memcpy(data + 4, data + 5, datalen - 5);
|
/* Back it up one and add a trailing NULL */
|
||||||
data[datalen] = '\0';
|
memmove(data, data + 1, datalen - 1);
|
||||||
if (session->ssh_msg_ignore) {
|
data[datalen] = '\0';
|
||||||
LIBSSH2_IGNORE(session, (char *) data + 4, datalen - 5);
|
if (session->ssh_msg_ignore) {
|
||||||
|
LIBSSH2_IGNORE(session, (char *) data + 4, datalen - 1);
|
||||||
|
}
|
||||||
|
} else if (session->ssh_msg_ignore) {
|
||||||
|
LIBSSH2_IGNORE(session, "", 0);
|
||||||
}
|
}
|
||||||
LIBSSH2_FREE(session, data);
|
LIBSSH2_FREE(session, data);
|
||||||
session->packAdd_state = libssh2_NB_state_idle;
|
session->packAdd_state = libssh2_NB_state_idle;
|
||||||
return 0;
|
return 0;
|
||||||
break;
|
|
||||||
|
|
||||||
case SSH_MSG_DEBUG:
|
case SSH_MSG_DEBUG:
|
||||||
{
|
{
|
||||||
@@ -598,7 +571,7 @@ _libssh2_packet_add(LIBSSH2_SESSION * session, unsigned char *data,
|
|||||||
message[message_len] = '\0';
|
message[message_len] = '\0';
|
||||||
language = (char *) data + 6 + message_len + 3;
|
language = (char *) data + 6 + message_len + 3;
|
||||||
if (language_len) {
|
if (language_len) {
|
||||||
memcpy(language, language + 1, language_len);
|
memmove(language, language + 1, language_len);
|
||||||
}
|
}
|
||||||
language[language_len] = '\0';
|
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 */
|
/* Adjust the window based on the block we just freed */
|
||||||
libssh2_packet_add_jump_point1:
|
libssh2_packet_add_jump_point1:
|
||||||
session->packAdd_state = libssh2_NB_state_jump1;
|
session->packAdd_state = libssh2_NB_state_jump1;
|
||||||
rc = libssh2_channel_receive_window_adjust(session->
|
rc = _libssh2_channel_receive_window_adjust(session->
|
||||||
packAdd_channel,
|
packAdd_channel,
|
||||||
datalen - 13,
|
datalen - 13,
|
||||||
0);
|
0, NULL);
|
||||||
if (rc == PACKET_EAGAIN) {
|
if (rc == PACKET_EAGAIN)
|
||||||
session->socket_block_directions =
|
return rc;
|
||||||
LIBSSH2_SESSION_BLOCK_OUTBOUND;
|
|
||||||
return PACKET_EAGAIN;
|
|
||||||
}
|
|
||||||
session->packAdd_state = libssh2_NB_state_idle;
|
session->packAdd_state = libssh2_NB_state_idle;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@@ -731,101 +702,88 @@ _libssh2_packet_add(LIBSSH2_SESSION * session, unsigned char *data,
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case SSH_MSG_CHANNEL_EOF:
|
case SSH_MSG_CHANNEL_EOF:
|
||||||
{
|
session->packAdd_channel =
|
||||||
session->packAdd_channel =
|
_libssh2_channel_locate(session, _libssh2_ntohu32(data + 1));
|
||||||
_libssh2_channel_locate(session, _libssh2_ntohu32(data + 1));
|
|
||||||
|
|
||||||
if (!session->packAdd_channel) {
|
|
||||||
/* We may have freed already, just quietly ignore this... */
|
|
||||||
LIBSSH2_FREE(session, data);
|
|
||||||
session->packAdd_state = libssh2_NB_state_idle;
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
_libssh2_debug(session,
|
|
||||||
LIBSSH2_DBG_CONN,
|
|
||||||
"EOF received for channel %lu/%lu",
|
|
||||||
session->packAdd_channel->local.id,
|
|
||||||
session->packAdd_channel->remote.id);
|
|
||||||
session->packAdd_channel->remote.eof = 1;
|
|
||||||
|
|
||||||
|
if (!session->packAdd_channel) {
|
||||||
|
/* We may have freed already, just quietly ignore this... */
|
||||||
LIBSSH2_FREE(session, data);
|
LIBSSH2_FREE(session, data);
|
||||||
session->packAdd_state = libssh2_NB_state_idle;
|
session->packAdd_state = libssh2_NB_state_idle;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
break;
|
|
||||||
|
_libssh2_debug(session,
|
||||||
|
LIBSSH2_DBG_CONN,
|
||||||
|
"EOF received for channel %lu/%lu",
|
||||||
|
session->packAdd_channel->local.id,
|
||||||
|
session->packAdd_channel->remote.id);
|
||||||
|
session->packAdd_channel->remote.eof = 1;
|
||||||
|
|
||||||
|
LIBSSH2_FREE(session, data);
|
||||||
|
session->packAdd_state = libssh2_NB_state_idle;
|
||||||
|
return 0;
|
||||||
|
|
||||||
case SSH_MSG_CHANNEL_REQUEST:
|
case SSH_MSG_CHANNEL_REQUEST:
|
||||||
{
|
if (_libssh2_ntohu32(data + 5) == sizeof("exit-status") - 1
|
||||||
if (_libssh2_ntohu32(data + 5) == sizeof("exit-status") - 1
|
&& !memcmp("exit-status", data + 9,
|
||||||
&& !memcmp("exit-status", data + 9,
|
sizeof("exit-status") - 1)) {
|
||||||
sizeof("exit-status") - 1)) {
|
|
||||||
|
|
||||||
/* we've got "exit-status" packet. Set the session value */
|
/* we've got "exit-status" packet. Set the session value */
|
||||||
session->packAdd_channel =
|
session->packAdd_channel =
|
||||||
_libssh2_channel_locate(session,
|
_libssh2_channel_locate(session,
|
||||||
_libssh2_ntohu32(data + 1));
|
_libssh2_ntohu32(data + 1));
|
||||||
|
|
||||||
if (session->packAdd_channel) {
|
if (session->packAdd_channel) {
|
||||||
session->packAdd_channel->exit_status =
|
session->packAdd_channel->exit_status =
|
||||||
_libssh2_ntohu32(data + 9 + sizeof("exit-status"));
|
_libssh2_ntohu32(data + 9 + sizeof("exit-status"));
|
||||||
_libssh2_debug(session, LIBSSH2_DBG_CONN,
|
_libssh2_debug(session, LIBSSH2_DBG_CONN,
|
||||||
"Exit status %lu received for channel %lu/%lu",
|
"Exit status %lu received for channel %lu/%lu",
|
||||||
session->packAdd_channel->exit_status,
|
session->packAdd_channel->exit_status,
|
||||||
session->packAdd_channel->local.id,
|
session->packAdd_channel->local.id,
|
||||||
session->packAdd_channel->remote.id);
|
session->packAdd_channel->remote.id);
|
||||||
}
|
|
||||||
|
|
||||||
LIBSSH2_FREE(session, data);
|
|
||||||
session->packAdd_state = libssh2_NB_state_idle;
|
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
LIBSSH2_FREE(session, data);
|
||||||
|
session->packAdd_state = libssh2_NB_state_idle;
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case SSH_MSG_CHANNEL_CLOSE:
|
case SSH_MSG_CHANNEL_CLOSE:
|
||||||
{
|
session->packAdd_channel =
|
||||||
session->packAdd_channel =
|
_libssh2_channel_locate(session, _libssh2_ntohu32(data + 1));
|
||||||
_libssh2_channel_locate(session, _libssh2_ntohu32(data + 1));
|
|
||||||
|
|
||||||
if (!session->packAdd_channel) {
|
|
||||||
/* We may have freed already, just quietly ignore this... */
|
|
||||||
LIBSSH2_FREE(session, data);
|
|
||||||
session->packAdd_state = libssh2_NB_state_idle;
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
_libssh2_debug(session, LIBSSH2_DBG_CONN,
|
|
||||||
"Close received for channel %lu/%lu",
|
|
||||||
session->packAdd_channel->local.id,
|
|
||||||
session->packAdd_channel->remote.id);
|
|
||||||
|
|
||||||
session->packAdd_channel->remote.close = 1;
|
|
||||||
session->packAdd_channel->remote.eof = 1;
|
|
||||||
/* TODO: Add a callback for this */
|
|
||||||
|
|
||||||
|
if (!session->packAdd_channel) {
|
||||||
|
/* We may have freed already, just quietly ignore this... */
|
||||||
LIBSSH2_FREE(session, data);
|
LIBSSH2_FREE(session, data);
|
||||||
session->packAdd_state = libssh2_NB_state_idle;
|
session->packAdd_state = libssh2_NB_state_idle;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
break;
|
_libssh2_debug(session, LIBSSH2_DBG_CONN,
|
||||||
|
"Close received for channel %lu/%lu",
|
||||||
|
session->packAdd_channel->local.id,
|
||||||
|
session->packAdd_channel->remote.id);
|
||||||
|
|
||||||
|
session->packAdd_channel->remote.close = 1;
|
||||||
|
session->packAdd_channel->remote.eof = 1;
|
||||||
|
|
||||||
|
LIBSSH2_FREE(session, data);
|
||||||
|
session->packAdd_state = libssh2_NB_state_idle;
|
||||||
|
return 0;
|
||||||
|
|
||||||
case SSH_MSG_CHANNEL_OPEN:
|
case SSH_MSG_CHANNEL_OPEN:
|
||||||
if ((datalen >= (sizeof("forwarded-tcpip") + 4)) &&
|
if ((datalen >= (sizeof("forwarded-tcpip") + 4)) &&
|
||||||
((sizeof("forwarded-tcpip") - 1) == _libssh2_ntohu32(data + 1))
|
((sizeof("forwarded-tcpip") - 1) == _libssh2_ntohu32(data + 1))
|
||||||
&&
|
&&
|
||||||
(memcmp
|
(memcmp(data + 5, "forwarded-tcpip",
|
||||||
(data + 5, "forwarded-tcpip",
|
sizeof("forwarded-tcpip") - 1) == 0)) {
|
||||||
sizeof("forwarded-tcpip") - 1) == 0)) {
|
|
||||||
|
|
||||||
libssh2_packet_add_jump_point2:
|
libssh2_packet_add_jump_point2:
|
||||||
session->packAdd_state = libssh2_NB_state_jump2;
|
session->packAdd_state = libssh2_NB_state_jump2;
|
||||||
rc = packet_queue_listener(session, data, datalen,
|
rc = packet_queue_listener(session, data, datalen,
|
||||||
&session->packAdd_Qlstn_state);
|
&session->packAdd_Qlstn_state);
|
||||||
if (rc == PACKET_EAGAIN) {
|
if (rc == PACKET_EAGAIN)
|
||||||
session->socket_block_directions =
|
return rc;
|
||||||
LIBSSH2_SESSION_BLOCK_OUTBOUND;
|
|
||||||
return PACKET_EAGAIN;
|
|
||||||
}
|
|
||||||
|
|
||||||
LIBSSH2_FREE(session, data);
|
LIBSSH2_FREE(session, data);
|
||||||
session->packAdd_state = libssh2_NB_state_idle;
|
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;
|
session->packAdd_state = libssh2_NB_state_jump3;
|
||||||
rc = packet_x11_open(session, data, datalen,
|
rc = packet_x11_open(session, data, datalen,
|
||||||
&session->packAdd_x11open_state);
|
&session->packAdd_x11open_state);
|
||||||
if (rc == PACKET_EAGAIN) {
|
if (rc == PACKET_EAGAIN)
|
||||||
session->socket_block_directions =
|
return rc;
|
||||||
LIBSSH2_SESSION_BLOCK_OUTBOUND;
|
|
||||||
return PACKET_EAGAIN;
|
|
||||||
}
|
|
||||||
|
|
||||||
LIBSSH2_FREE(session, data);
|
LIBSSH2_FREE(session, data);
|
||||||
session->packAdd_state = libssh2_NB_state_idle;
|
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) {
|
if (session->packAdd_state == libssh2_NB_state_sent) {
|
||||||
session->packAdd_packet =
|
LIBSSH2_PACKET *packAdd_packet;
|
||||||
LIBSSH2_ALLOC(session, sizeof(LIBSSH2_PACKET));
|
packAdd_packet =
|
||||||
if (!session->packAdd_packet) {
|
LIBSSH2_ALLOC(session, sizeof(LIBSSH2_PACKET));
|
||||||
|
if (!packAdd_packet) {
|
||||||
_libssh2_debug(session, LIBSSH2_ERROR_ALLOC,
|
_libssh2_debug(session, LIBSSH2_ERROR_ALLOC,
|
||||||
"Unable to allocate memory for LIBSSH2_PACKET");
|
"Unable to allocate memory for LIBSSH2_PACKET");
|
||||||
LIBSSH2_FREE(session, data);
|
|
||||||
session->packAdd_state = libssh2_NB_state_idle;
|
session->packAdd_state = libssh2_NB_state_idle;
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
memset(session->packAdd_packet, 0, sizeof(LIBSSH2_PACKET));
|
memset(packAdd_packet, 0, sizeof(LIBSSH2_PACKET));
|
||||||
|
|
||||||
session->packAdd_packet->data = data;
|
packAdd_packet->data = data;
|
||||||
session->packAdd_packet->data_len = datalen;
|
packAdd_packet->data_len = datalen;
|
||||||
session->packAdd_packet->data_head = session->packAdd_data_head;
|
packAdd_packet->data_head = session->packAdd_data_head;
|
||||||
session->packAdd_packet->mac = macstate;
|
packAdd_packet->mac = macstate;
|
||||||
session->packAdd_packet->brigade = &session->packets;
|
|
||||||
session->packAdd_packet->next = NULL;
|
|
||||||
|
|
||||||
if (session->packets.tail) {
|
_libssh2_list_add(&session->packets, &packAdd_packet->node);
|
||||||
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;
|
|
||||||
}
|
|
||||||
|
|
||||||
session->packAdd_state = libssh2_NB_state_sent1;
|
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);
|
rc = libssh2_kex_exchange(session, 1, &session->startup_key_state);
|
||||||
if (rc == PACKET_EAGAIN) {
|
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_ofs, const unsigned char *match_buf,
|
||||||
unsigned long match_len)
|
unsigned long match_len)
|
||||||
{
|
{
|
||||||
LIBSSH2_PACKET *packet = session->packets.head;
|
LIBSSH2_PACKET *packet = _libssh2_list_first(&session->packets);
|
||||||
|
|
||||||
_libssh2_debug(session, LIBSSH2_DBG_TRANS,
|
_libssh2_debug(session, LIBSSH2_DBG_TRANS,
|
||||||
"Looking for packet of type: %d", (int) packet_type);
|
"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 = packet->data;
|
||||||
*data_len = packet->data_len;
|
*data_len = packet->data_len;
|
||||||
|
|
||||||
/* unlink struct */
|
/* unlink struct from session->packets */
|
||||||
if (packet->prev) {
|
_libssh2_list_remove(&packet->node);
|
||||||
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;
|
|
||||||
}
|
|
||||||
|
|
||||||
LIBSSH2_FREE(session, packet);
|
LIBSSH2_FREE(session, packet);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
packet = packet->next;
|
packet = _libssh2_list_next(&packet->node);
|
||||||
}
|
}
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
@@ -1060,13 +995,10 @@ _libssh2_packet_require(LIBSSH2_SESSION * session, unsigned char packet_type,
|
|||||||
}
|
}
|
||||||
|
|
||||||
while (session->socket_state == LIBSSH2_SOCKET_CONNECTED) {
|
while (session->socket_state == LIBSSH2_SOCKET_CONNECTED) {
|
||||||
libssh2pack_t ret = _libssh2_transport_read(session);
|
int ret = _libssh2_transport_read(session);
|
||||||
if (ret == PACKET_EAGAIN) {
|
if (ret == PACKET_EAGAIN)
|
||||||
return PACKET_EAGAIN;
|
return ret;
|
||||||
} else if (ret == 0) {
|
else if (ret < 0) {
|
||||||
/* There is no data, return that. TODO: is this really correct? */
|
|
||||||
return PACKET_EAGAIN;
|
|
||||||
} else if (ret < 0) {
|
|
||||||
state->start = 0;
|
state->start = 0;
|
||||||
/* an error which is not just because of blocking */
|
/* an error which is not just because of blocking */
|
||||||
return ret;
|
return ret;
|
||||||
@@ -1084,11 +1016,12 @@ _libssh2_packet_require(LIBSSH2_SESSION * session, unsigned char packet_type,
|
|||||||
state->start = 0;
|
state->start = 0;
|
||||||
return PACKET_TIMEOUT;
|
return PACKET_TIMEOUT;
|
||||||
}
|
}
|
||||||
|
return -1; /* no packet available yet */
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Only reached if the socket died */
|
/* 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) {
|
while (session->socket_state == LIBSSH2_SOCKET_CONNECTED) {
|
||||||
if ((ret = _libssh2_transport_read(session)) == PACKET_EAGAIN) {
|
ret = _libssh2_transport_read(session);
|
||||||
return PACKET_EAGAIN;
|
if (ret == PACKET_EAGAIN) {
|
||||||
|
return ret;
|
||||||
} else if (ret < 0) {
|
} else if (ret < 0) {
|
||||||
*state = libssh2_NB_state_idle;
|
*state = libssh2_NB_state_idle;
|
||||||
return ret;
|
return ret;
|
||||||
@@ -1148,7 +1082,7 @@ _libssh2_packet_burn(LIBSSH2_SESSION * session,
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Only reached if the socket died */
|
/* 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;
|
return PACKET_TIMEOUT;
|
||||||
}
|
}
|
||||||
else if (ret == PACKET_EAGAIN) {
|
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 */
|
/* Only reached if the socket died */
|
||||||
state->start = 0;
|
state->start = 0;
|
||||||
return -1;
|
return LIBSSH2_ERROR_SOCKET_DISCONNECT;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -38,6 +38,8 @@
|
|||||||
|
|
||||||
#include "libssh2_priv.h"
|
#include "libssh2_priv.h"
|
||||||
|
|
||||||
|
#ifdef LIBSSH2_LIBGCRYPT /* compile only if we build with libgcrypt */
|
||||||
|
|
||||||
static int
|
static int
|
||||||
readline(char *line, int line_size, FILE * fp)
|
readline(char *line, int line_size, FILE * fp)
|
||||||
{
|
{
|
||||||
@@ -207,3 +209,5 @@ _libssh2_pem_decode_integer(unsigned char **data, unsigned int *datalen,
|
|||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#endif /* LIBSSH2_LIBGCRYPT */
|
||||||
|
@@ -37,6 +37,7 @@
|
|||||||
|
|
||||||
#include "libssh2_priv.h"
|
#include "libssh2_priv.h"
|
||||||
#include "libssh2_publickey.h"
|
#include "libssh2_publickey.h"
|
||||||
|
#include "channel.h"
|
||||||
|
|
||||||
#define LIBSSH2_PUBLICKEY_VERSION 2
|
#define LIBSSH2_PUBLICKEY_VERSION 2
|
||||||
|
|
||||||
@@ -168,9 +169,9 @@ publickey_packet_receive(LIBSSH2_PUBLICKEY * pkey,
|
|||||||
int rc;
|
int rc;
|
||||||
|
|
||||||
if (pkey->receive_state == libssh2_NB_state_idle) {
|
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) {
|
if (rc == PACKET_EAGAIN) {
|
||||||
return PACKET_EAGAIN;
|
return rc;
|
||||||
} else if (rc != 4) {
|
} else if (rc != 4) {
|
||||||
libssh2_error(session, LIBSSH2_ERROR_PUBLICKEY_PROTOCOL,
|
libssh2_error(session, LIBSSH2_ERROR_PUBLICKEY_PROTOCOL,
|
||||||
"Invalid response from publickey subsystem", 0);
|
"Invalid response from publickey subsystem", 0);
|
||||||
@@ -190,10 +191,10 @@ publickey_packet_receive(LIBSSH2_PUBLICKEY * pkey,
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (pkey->receive_state == libssh2_NB_state_sent) {
|
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);
|
pkey->receive_packet_len);
|
||||||
if (rc == PACKET_EAGAIN) {
|
if (rc == PACKET_EAGAIN) {
|
||||||
return PACKET_EAGAIN;
|
return rc;
|
||||||
} else if (rc != (int)pkey->receive_packet_len) {
|
} else if (rc != (int)pkey->receive_packet_len) {
|
||||||
libssh2_error(session, LIBSSH2_ERROR_SOCKET_TIMEOUT,
|
libssh2_error(session, LIBSSH2_ERROR_SOCKET_TIMEOUT,
|
||||||
"Timeout waiting for publickey subsystem response packet",
|
"Timeout waiting for publickey subsystem response packet",
|
||||||
@@ -265,7 +266,7 @@ publickey_response_success(LIBSSH2_PUBLICKEY * pkey)
|
|||||||
while (1) {
|
while (1) {
|
||||||
rc = publickey_packet_receive(pkey, &data, &data_len);
|
rc = publickey_packet_receive(pkey, &data, &data_len);
|
||||||
if (rc == PACKET_EAGAIN) {
|
if (rc == PACKET_EAGAIN) {
|
||||||
return PACKET_EAGAIN;
|
return rc;
|
||||||
} else if (rc) {
|
} else if (rc) {
|
||||||
libssh2_error(session, LIBSSH2_ERROR_SOCKET_TIMEOUT,
|
libssh2_error(session, LIBSSH2_ERROR_SOCKET_TIMEOUT,
|
||||||
"Timeout waiting for response from publickey subsystem",
|
"Timeout waiting for response from publickey subsystem",
|
||||||
@@ -441,8 +442,8 @@ libssh2_publickey_init(LIBSSH2_SESSION * session)
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (session->pkeyInit_state == libssh2_NB_state_sent2) {
|
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));
|
(char *) buffer, (s - buffer));
|
||||||
if (rc == PACKET_EAGAIN) {
|
if (rc == PACKET_EAGAIN) {
|
||||||
libssh2_error(session, LIBSSH2_ERROR_EAGAIN,
|
libssh2_error(session, LIBSSH2_ERROR_EAGAIN,
|
||||||
"Would block sending publickey version packet", 0);
|
"Would block sending publickey version packet", 0);
|
||||||
@@ -678,10 +679,10 @@ libssh2_publickey_add_ex(LIBSSH2_PUBLICKEY * pkey, const unsigned char *name,
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (pkey->add_state == libssh2_NB_state_created) {
|
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));
|
(pkey->add_s - pkey->add_packet));
|
||||||
if (rc == PACKET_EAGAIN) {
|
if (rc == PACKET_EAGAIN) {
|
||||||
return PACKET_EAGAIN;
|
return rc;
|
||||||
} else if ((pkey->add_s - pkey->add_packet) != rc) {
|
} else if ((pkey->add_s - pkey->add_packet) != rc) {
|
||||||
libssh2_error(session, LIBSSH2_ERROR_SOCKET_SEND,
|
libssh2_error(session, LIBSSH2_ERROR_SOCKET_SEND,
|
||||||
"Unable to send publickey add packet", 0);
|
"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);
|
rc = publickey_response_success(pkey);
|
||||||
if (rc == PACKET_EAGAIN) {
|
if (rc == PACKET_EAGAIN) {
|
||||||
return PACKET_EAGAIN;
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
pkey->add_state = libssh2_NB_state_idle;
|
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) {
|
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));
|
(pkey->remove_s - pkey->remove_packet));
|
||||||
if (rc == PACKET_EAGAIN) {
|
if (rc == PACKET_EAGAIN) {
|
||||||
return PACKET_EAGAIN;
|
return rc;
|
||||||
} else if ((pkey->remove_s - pkey->remove_packet) != rc) {
|
} else if ((pkey->remove_s - pkey->remove_packet) != rc) {
|
||||||
libssh2_error(session, LIBSSH2_ERROR_SOCKET_SEND,
|
libssh2_error(session, LIBSSH2_ERROR_SOCKET_SEND,
|
||||||
"Unable to send publickey remove packet", 0);
|
"Unable to send publickey remove packet", 0);
|
||||||
@@ -774,7 +775,7 @@ libssh2_publickey_remove_ex(LIBSSH2_PUBLICKEY * pkey,
|
|||||||
|
|
||||||
rc = publickey_response_success(pkey);
|
rc = publickey_response_success(pkey);
|
||||||
if (rc == PACKET_EAGAIN) {
|
if (rc == PACKET_EAGAIN) {
|
||||||
return PACKET_EAGAIN;
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
pkey->remove_state = libssh2_NB_state_idle;
|
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) {
|
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,
|
(char *) pkey->listFetch_buffer,
|
||||||
(pkey->listFetch_s -
|
(pkey->listFetch_s -
|
||||||
pkey->listFetch_buffer));
|
pkey->listFetch_buffer));
|
||||||
if (rc == PACKET_EAGAIN) {
|
if (rc == PACKET_EAGAIN) {
|
||||||
return PACKET_EAGAIN;
|
return rc;
|
||||||
} else if ((pkey->listFetch_s - pkey->listFetch_buffer) != rc) {
|
} else if ((pkey->listFetch_s - pkey->listFetch_buffer) != rc) {
|
||||||
libssh2_error(session, LIBSSH2_ERROR_SOCKET_SEND,
|
libssh2_error(session, LIBSSH2_ERROR_SOCKET_SEND,
|
||||||
"Unable to send publickey list packet", 0);
|
"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,
|
rc = publickey_packet_receive(pkey, &pkey->listFetch_data,
|
||||||
&pkey->listFetch_data_len);
|
&pkey->listFetch_data_len);
|
||||||
if (rc == PACKET_EAGAIN) {
|
if (rc == PACKET_EAGAIN) {
|
||||||
return PACKET_EAGAIN;
|
return rc;
|
||||||
} else if (rc) {
|
} else if (rc) {
|
||||||
libssh2_error(session, LIBSSH2_ERROR_SOCKET_TIMEOUT,
|
libssh2_error(session, LIBSSH2_ERROR_SOCKET_TIMEOUT,
|
||||||
"Timeout waiting for response from publickey subsystem",
|
"Timeout waiting for response from publickey subsystem",
|
||||||
@@ -1040,6 +1041,7 @@ LIBSSH2_API int
|
|||||||
libssh2_publickey_shutdown(LIBSSH2_PUBLICKEY * pkey)
|
libssh2_publickey_shutdown(LIBSSH2_PUBLICKEY * pkey)
|
||||||
{
|
{
|
||||||
LIBSSH2_SESSION *session = pkey->channel->session;
|
LIBSSH2_SESSION *session = pkey->channel->session;
|
||||||
|
int rc;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Make sure all memory used in the state variables are free
|
* 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;
|
pkey->listFetch_data = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (libssh2_channel_free(pkey->channel) == PACKET_EAGAIN) {
|
rc = libssh2_channel_free(pkey->channel);
|
||||||
return PACKET_EAGAIN;
|
if (rc == PACKET_EAGAIN)
|
||||||
}
|
return rc;
|
||||||
|
|
||||||
LIBSSH2_FREE(session, pkey);
|
LIBSSH2_FREE(session, pkey);
|
||||||
return 0;
|
return 0;
|
||||||
|
116
src/scp.c
116
src/scp.c
@@ -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.
|
* All rights reserved.
|
||||||
*
|
*
|
||||||
* Redistribution and use in source and binary forms,
|
* Redistribution and use in source and binary forms,
|
||||||
@@ -39,6 +40,8 @@
|
|||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
|
||||||
|
#include "channel.h"
|
||||||
|
|
||||||
|
|
||||||
/* Max. length of a quoted string after libssh2_shell_quotearg() processing */
|
/* Max. length of a quoted string after libssh2_shell_quotearg() processing */
|
||||||
#define libssh2_shell_quotedsize(s) (3 * strlen(s) + 2)
|
#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
|
* Open a channel and request a remote file via SCP
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
LIBSSH2_API LIBSSH2_CHANNEL *
|
static LIBSSH2_CHANNEL *
|
||||||
libssh2_scp_recv(LIBSSH2_SESSION * session, const char *path, struct stat * sb)
|
scp_recv(LIBSSH2_SESSION * session, const char *path, struct stat * sb)
|
||||||
{
|
{
|
||||||
int cmd_len;
|
int cmd_len;
|
||||||
int rc;
|
int rc;
|
||||||
@@ -355,8 +358,8 @@ libssh2_scp_recv(LIBSSH2_SESSION * session, const char *path, struct stat * sb)
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (session->scpRecv_state == libssh2_NB_state_sent1) {
|
if (session->scpRecv_state == libssh2_NB_state_sent1) {
|
||||||
rc = libssh2_channel_write_ex(session->scpRecv_channel, 0,
|
rc = _libssh2_channel_write(session->scpRecv_channel, 0,
|
||||||
(char *) session->scpRecv_response, 1);
|
(char *) session->scpRecv_response, 1);
|
||||||
if (rc == PACKET_EAGAIN) {
|
if (rc == PACKET_EAGAIN) {
|
||||||
libssh2_error(session, LIBSSH2_ERROR_EAGAIN,
|
libssh2_error(session, LIBSSH2_ERROR_EAGAIN,
|
||||||
"Would block sending initial wakeup", 0);
|
"Would block sending initial wakeup", 0);
|
||||||
@@ -378,10 +381,10 @@ libssh2_scp_recv(LIBSSH2_SESSION * session, const char *path, struct stat * sb)
|
|||||||
unsigned char *s, *p;
|
unsigned char *s, *p;
|
||||||
|
|
||||||
if (session->scpRecv_state == libssh2_NB_state_sent2) {
|
if (session->scpRecv_state == libssh2_NB_state_sent2) {
|
||||||
rc = libssh2_channel_read_ex(session->scpRecv_channel, 0,
|
rc = _libssh2_channel_read(session->scpRecv_channel, 0,
|
||||||
(char *) session->
|
(char *) session->
|
||||||
scpRecv_response +
|
scpRecv_response +
|
||||||
session->scpRecv_response_len, 1);
|
session->scpRecv_response_len, 1);
|
||||||
if (rc == PACKET_EAGAIN) {
|
if (rc == PACKET_EAGAIN) {
|
||||||
libssh2_error(session, LIBSSH2_ERROR_EAGAIN,
|
libssh2_error(session, LIBSSH2_ERROR_EAGAIN,
|
||||||
"Would block waiting for SCP response", 0);
|
"Would block waiting for SCP response", 0);
|
||||||
@@ -415,9 +418,9 @@ libssh2_scp_recv(LIBSSH2_SESSION * session, const char *path, struct stat * sb)
|
|||||||
session->scpRecv_err_len + 1);
|
session->scpRecv_err_len + 1);
|
||||||
|
|
||||||
/* Read the remote error message */
|
/* 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_msg,
|
||||||
session->scpRecv_err_len);
|
session->scpRecv_err_len);
|
||||||
if (rc <= 0) {
|
if (rc <= 0) {
|
||||||
/*
|
/*
|
||||||
* Since we have alread started reading this packet,
|
* Since we have alread started reading this packet,
|
||||||
@@ -555,9 +558,9 @@ libssh2_scp_recv(LIBSSH2_SESSION * session, const char *path, struct stat * sb)
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (session->scpRecv_state == libssh2_NB_state_sent3) {
|
if (session->scpRecv_state == libssh2_NB_state_sent3) {
|
||||||
rc = libssh2_channel_write_ex(session->scpRecv_channel, 0,
|
rc = _libssh2_channel_write(session->scpRecv_channel, 0,
|
||||||
(char *) session->
|
(char *) session->
|
||||||
scpRecv_response, 1);
|
scpRecv_response, 1);
|
||||||
if (rc == PACKET_EAGAIN) {
|
if (rc == PACKET_EAGAIN) {
|
||||||
libssh2_error(session, LIBSSH2_ERROR_EAGAIN,
|
libssh2_error(session, LIBSSH2_ERROR_EAGAIN,
|
||||||
"Would block waiting to send SCP ACK", 0);
|
"Would block waiting to send SCP ACK", 0);
|
||||||
@@ -591,10 +594,10 @@ libssh2_scp_recv(LIBSSH2_SESSION * session, const char *path, struct stat * sb)
|
|||||||
char *s, *p, *e = NULL;
|
char *s, *p, *e = NULL;
|
||||||
|
|
||||||
if (session->scpRecv_state == libssh2_NB_state_sent5) {
|
if (session->scpRecv_state == libssh2_NB_state_sent5) {
|
||||||
rc = libssh2_channel_read_ex(session->scpRecv_channel, 0,
|
rc = _libssh2_channel_read(session->scpRecv_channel, 0,
|
||||||
(char *) session->
|
(char *) session->
|
||||||
scpRecv_response +
|
scpRecv_response +
|
||||||
session->scpRecv_response_len, 1);
|
session->scpRecv_response_len, 1);
|
||||||
if (rc == PACKET_EAGAIN) {
|
if (rc == PACKET_EAGAIN) {
|
||||||
libssh2_error(session, LIBSSH2_ERROR_EAGAIN,
|
libssh2_error(session, LIBSSH2_ERROR_EAGAIN,
|
||||||
"Would block waiting for SCP response", 0);
|
"Would block waiting for SCP response", 0);
|
||||||
@@ -718,9 +721,9 @@ libssh2_scp_recv(LIBSSH2_SESSION * session, const char *path, struct stat * sb)
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (session->scpRecv_state == libssh2_NB_state_sent6) {
|
if (session->scpRecv_state == libssh2_NB_state_sent6) {
|
||||||
rc = libssh2_channel_write_ex(session->scpRecv_channel, 0,
|
rc = _libssh2_channel_write(session->scpRecv_channel, 0,
|
||||||
(char *) session->
|
(char *) session->
|
||||||
scpRecv_response, 1);
|
scpRecv_response, 1);
|
||||||
if (rc == PACKET_EAGAIN) {
|
if (rc == PACKET_EAGAIN) {
|
||||||
libssh2_error(session, LIBSSH2_ERROR_EAGAIN,
|
libssh2_error(session, LIBSSH2_ERROR_EAGAIN,
|
||||||
"Would block sending SCP ACK", 0);
|
"Would block sending SCP ACK", 0);
|
||||||
@@ -761,14 +764,28 @@ 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
|
* Send a file using SCP
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
LIBSSH2_API LIBSSH2_CHANNEL *
|
static LIBSSH2_CHANNEL *
|
||||||
libssh2_scp_send_ex(LIBSSH2_SESSION * session, const char *path, int mode,
|
scp_send(LIBSSH2_SESSION * session, const char *path, int mode,
|
||||||
size_t size, long mtime, long atime)
|
size_t size, long mtime, long atime)
|
||||||
{
|
{
|
||||||
int cmd_len;
|
int cmd_len;
|
||||||
unsigned const char *base;
|
unsigned const char *base;
|
||||||
@@ -857,8 +874,8 @@ libssh2_scp_send_ex(LIBSSH2_SESSION * session, const char *path, int mode,
|
|||||||
|
|
||||||
if (session->scpSend_state == libssh2_NB_state_sent1) {
|
if (session->scpSend_state == libssh2_NB_state_sent1) {
|
||||||
/* Wait for ACK */
|
/* Wait for ACK */
|
||||||
rc = libssh2_channel_read_ex(session->scpSend_channel, 0,
|
rc = _libssh2_channel_read(session->scpSend_channel, 0,
|
||||||
(char *) session->scpSend_response, 1);
|
(char *) session->scpSend_response, 1);
|
||||||
if (rc == PACKET_EAGAIN) {
|
if (rc == PACKET_EAGAIN) {
|
||||||
libssh2_error(session, LIBSSH2_ERROR_EAGAIN,
|
libssh2_error(session, LIBSSH2_ERROR_EAGAIN,
|
||||||
"Would block waiting for response from remote", 0);
|
"Would block waiting for response from remote", 0);
|
||||||
@@ -885,9 +902,9 @@ libssh2_scp_send_ex(LIBSSH2_SESSION * session, const char *path, int mode,
|
|||||||
/* Send mtime and atime to be used for file */
|
/* Send mtime and atime to be used for file */
|
||||||
if (mtime || atime) {
|
if (mtime || atime) {
|
||||||
if (session->scpSend_state == libssh2_NB_state_sent2) {
|
if (session->scpSend_state == libssh2_NB_state_sent2) {
|
||||||
rc = libssh2_channel_write_ex(session->scpSend_channel, 0,
|
rc = _libssh2_channel_write(session->scpSend_channel, 0,
|
||||||
(char *) session->scpSend_response,
|
(char *) session->scpSend_response,
|
||||||
session->scpSend_response_len);
|
session->scpSend_response_len);
|
||||||
if (rc == PACKET_EAGAIN) {
|
if (rc == PACKET_EAGAIN) {
|
||||||
libssh2_error(session, LIBSSH2_ERROR_EAGAIN,
|
libssh2_error(session, LIBSSH2_ERROR_EAGAIN,
|
||||||
"Would block sending time data for SCP file", 0);
|
"Would block sending time data for SCP file", 0);
|
||||||
@@ -903,9 +920,8 @@ libssh2_scp_send_ex(LIBSSH2_SESSION * session, const char *path, int mode,
|
|||||||
|
|
||||||
if (session->scpSend_state == libssh2_NB_state_sent3) {
|
if (session->scpSend_state == libssh2_NB_state_sent3) {
|
||||||
/* Wait for ACK */
|
/* Wait for ACK */
|
||||||
rc = libssh2_channel_read_ex(session->scpSend_channel, 0,
|
rc = _libssh2_channel_read(session->scpSend_channel, 0,
|
||||||
(char *) session->scpSend_response,
|
(char *) session->scpSend_response, 1);
|
||||||
1);
|
|
||||||
if (rc == PACKET_EAGAIN) {
|
if (rc == PACKET_EAGAIN) {
|
||||||
libssh2_error(session, LIBSSH2_ERROR_EAGAIN,
|
libssh2_error(session, LIBSSH2_ERROR_EAGAIN,
|
||||||
"Would block waiting for response", 0);
|
"Would block waiting for response", 0);
|
||||||
@@ -944,9 +960,9 @@ libssh2_scp_send_ex(LIBSSH2_SESSION * session, const char *path, int mode,
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (session->scpSend_state == libssh2_NB_state_sent5) {
|
if (session->scpSend_state == libssh2_NB_state_sent5) {
|
||||||
rc = libssh2_channel_write_ex(session->scpSend_channel, 0,
|
rc = _libssh2_channel_write(session->scpSend_channel, 0,
|
||||||
(char *) session->scpSend_response,
|
(char *) session->scpSend_response,
|
||||||
session->scpSend_response_len);
|
session->scpSend_response_len);
|
||||||
if (rc == PACKET_EAGAIN) {
|
if (rc == PACKET_EAGAIN) {
|
||||||
libssh2_error(session, LIBSSH2_ERROR_EAGAIN,
|
libssh2_error(session, LIBSSH2_ERROR_EAGAIN,
|
||||||
"Would block send core file data for SCP file", 0);
|
"Would block send core file data for SCP file", 0);
|
||||||
@@ -962,8 +978,8 @@ libssh2_scp_send_ex(LIBSSH2_SESSION * session, const char *path, int mode,
|
|||||||
|
|
||||||
if (session->scpSend_state == libssh2_NB_state_sent6) {
|
if (session->scpSend_state == libssh2_NB_state_sent6) {
|
||||||
/* Wait for ACK */
|
/* 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);
|
(char *) session->scpSend_response, 1);
|
||||||
if (rc == PACKET_EAGAIN) {
|
if (rc == PACKET_EAGAIN) {
|
||||||
libssh2_error(session, LIBSSH2_ERROR_EAGAIN,
|
libssh2_error(session, LIBSSH2_ERROR_EAGAIN,
|
||||||
"Would block waiting for response", 0);
|
"Would block waiting for response", 0);
|
||||||
@@ -990,9 +1006,9 @@ libssh2_scp_send_ex(LIBSSH2_SESSION * session, const char *path, int mode,
|
|||||||
memset(session->scpSend_err_msg, 0, session->scpSend_err_len + 1);
|
memset(session->scpSend_err_msg, 0, session->scpSend_err_len + 1);
|
||||||
|
|
||||||
/* Read the remote error message */
|
/* 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_msg,
|
||||||
session->scpSend_err_len);
|
session->scpSend_err_len);
|
||||||
if (rc <= 0) {
|
if (rc <= 0) {
|
||||||
/*
|
/*
|
||||||
* Since we have alread started reading this packet, it is
|
* Since we have alread started reading this packet, it is
|
||||||
@@ -1021,3 +1037,17 @@ libssh2_scp_send_ex(LIBSSH2_SESSION * session, const char *path, int mode,
|
|||||||
return NULL;
|
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;
|
||||||
|
}
|
||||||
|
122
src/session.c
122
src/session.c
@@ -106,6 +106,9 @@ banner_receive(LIBSSH2_SESSION * session)
|
|||||||
|| (session->banner_TxRx_banner[banner_len - 1] != '\n'))) {
|
|| (session->banner_TxRx_banner[banner_len - 1] != '\n'))) {
|
||||||
char c = '\0';
|
char c = '\0';
|
||||||
|
|
||||||
|
/* no incoming block yet! */
|
||||||
|
session->socket_block_directions &= ~LIBSSH2_SESSION_BLOCK_INBOUND;
|
||||||
|
|
||||||
ret = _libssh2_recv(session->socket_fd, &c, 1,
|
ret = _libssh2_recv(session->socket_fd, &c, 1,
|
||||||
LIBSSH2_SOCKET_RECV_FLAGS(session));
|
LIBSSH2_SOCKET_RECV_FLAGS(session));
|
||||||
|
|
||||||
@@ -207,6 +210,9 @@ banner_send(LIBSSH2_SESSION * session)
|
|||||||
session->banner_TxRx_state = libssh2_NB_state_created;
|
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,
|
ret = _libssh2_send(session->socket_fd,
|
||||||
banner + session->banner_TxRx_total_send,
|
banner + session->banner_TxRx_total_send,
|
||||||
banner_len - 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.
|
* is copied from the libcurl sources with permission.
|
||||||
*/
|
*/
|
||||||
static int
|
static int
|
||||||
session_nonblock(int sockfd, /* operate on this */
|
session_nonblock(libssh2_socket_t sockfd, /* operate on this */
|
||||||
int nonblock /* TRUE or FALSE */ )
|
int nonblock /* TRUE or FALSE */ )
|
||||||
{
|
{
|
||||||
#undef SETBLOCK
|
#undef SETBLOCK
|
||||||
@@ -529,7 +535,7 @@ int _libssh2_wait_socket(LIBSSH2_SESSION *session)
|
|||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
session_startup(LIBSSH2_SESSION *session, int sock)
|
session_startup(LIBSSH2_SESSION *session, libssh2_socket_t sock)
|
||||||
{
|
{
|
||||||
int rc;
|
int rc;
|
||||||
|
|
||||||
@@ -556,35 +562,22 @@ session_startup(LIBSSH2_SESSION *session, int sock)
|
|||||||
session->startup_state = libssh2_NB_state_created;
|
session->startup_state = libssh2_NB_state_created;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* TODO: Liveness check */
|
|
||||||
|
|
||||||
if (session->startup_state == libssh2_NB_state_created) {
|
if (session->startup_state == libssh2_NB_state_created) {
|
||||||
rc = banner_send(session);
|
rc = banner_send(session);
|
||||||
if (rc == PACKET_EAGAIN) {
|
if (rc) {
|
||||||
libssh2_error(session, LIBSSH2_ERROR_EAGAIN,
|
libssh2_error(session, rc,
|
||||||
"Would block sending banner to remote host", 0);
|
"Failed sending banner", 0);
|
||||||
return LIBSSH2_ERROR_EAGAIN;
|
return rc;
|
||||||
} 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;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
session->startup_state = libssh2_NB_state_sent;
|
session->startup_state = libssh2_NB_state_sent;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (session->startup_state == libssh2_NB_state_sent) {
|
if (session->startup_state == libssh2_NB_state_sent) {
|
||||||
rc = banner_receive(session);
|
rc = banner_receive(session);
|
||||||
if (rc == PACKET_EAGAIN) {
|
if (rc) {
|
||||||
libssh2_error(session, LIBSSH2_ERROR_EAGAIN,
|
libssh2_error(session, rc,
|
||||||
"Would block waiting for banner", 0);
|
"Failed getting banner", 0);
|
||||||
return LIBSSH2_ERROR_EAGAIN;
|
return rc;
|
||||||
} 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;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
session->startup_state = libssh2_NB_state_sent1;
|
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) {
|
if (session->startup_state == libssh2_NB_state_sent1) {
|
||||||
rc = libssh2_kex_exchange(session, 0, &session->startup_key_state);
|
rc = libssh2_kex_exchange(session, 0, &session->startup_key_state);
|
||||||
if (rc == PACKET_EAGAIN) {
|
if (rc) {
|
||||||
libssh2_error(session, LIBSSH2_ERROR_EAGAIN,
|
libssh2_error(session, rc,
|
||||||
"Would block exchanging encryption keys", 0);
|
|
||||||
return LIBSSH2_ERROR_EAGAIN;
|
|
||||||
} else if (rc) {
|
|
||||||
libssh2_error(session, LIBSSH2_ERROR_KEX_FAILURE,
|
|
||||||
"Unable to exchange encryption keys", 0);
|
"Unable to exchange encryption keys", 0);
|
||||||
return LIBSSH2_ERROR_KEX_FAILURE;
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
session->startup_state = libssh2_NB_state_sent2;
|
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) {
|
if (session->startup_state == libssh2_NB_state_sent3) {
|
||||||
rc = _libssh2_transport_write(session, session->startup_service,
|
rc = _libssh2_transport_write(session, session->startup_service,
|
||||||
sizeof("ssh-userauth") + 5 - 1);
|
sizeof("ssh-userauth") + 5 - 1);
|
||||||
if (rc == PACKET_EAGAIN) {
|
if (rc) {
|
||||||
libssh2_error(session, LIBSSH2_ERROR_EAGAIN,
|
libssh2_error(session, rc,
|
||||||
"Would block asking for ssh-userauth service", 0);
|
|
||||||
return LIBSSH2_ERROR_EAGAIN;
|
|
||||||
}
|
|
||||||
else if (rc) {
|
|
||||||
libssh2_error(session, LIBSSH2_ERROR_SOCKET_SEND,
|
|
||||||
"Unable to ask for ssh-userauth service", 0);
|
"Unable to ask for ssh-userauth service", 0);
|
||||||
return LIBSSH2_ERROR_SOCKET_SEND;
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
session->startup_state = libssh2_NB_state_sent4;
|
session->startup_state = libssh2_NB_state_sent4;
|
||||||
@@ -641,11 +625,9 @@ session_startup(LIBSSH2_SESSION *session, int sock)
|
|||||||
&session->startup_data,
|
&session->startup_data,
|
||||||
&session->startup_data_len, 0, NULL, 0,
|
&session->startup_data_len, 0, NULL, 0,
|
||||||
&session->startup_req_state);
|
&session->startup_req_state);
|
||||||
if (rc == PACKET_EAGAIN) {
|
if (rc)
|
||||||
return LIBSSH2_ERROR_EAGAIN;
|
return rc;
|
||||||
} else if (rc) {
|
|
||||||
return LIBSSH2_ERROR_SOCKET_DISCONNECT;
|
|
||||||
}
|
|
||||||
session->startup_service_length =
|
session->startup_service_length =
|
||||||
_libssh2_ntohu32(session->startup_data + 1);
|
_libssh2_ntohu32(session->startup_data + 1);
|
||||||
|
|
||||||
@@ -699,6 +681,9 @@ static int
|
|||||||
session_free(LIBSSH2_SESSION *session)
|
session_free(LIBSSH2_SESSION *session)
|
||||||
{
|
{
|
||||||
int rc;
|
int rc;
|
||||||
|
LIBSSH2_PACKET *pkg;
|
||||||
|
LIBSSH2_CHANNEL *ch;
|
||||||
|
LIBSSH2_LISTENER *l;
|
||||||
|
|
||||||
if (session->free_state == libssh2_NB_state_idle) {
|
if (session->free_state == libssh2_NB_state_idle) {
|
||||||
_libssh2_debug(session, LIBSSH2_DBG_TRANS, "Freeing session resource",
|
_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) {
|
if (session->free_state == libssh2_NB_state_created) {
|
||||||
while (session->channels.head) {
|
while ((ch = _libssh2_list_first(&session->channels))) {
|
||||||
LIBSSH2_CHANNEL *tmp = session->channels.head;
|
|
||||||
|
|
||||||
rc = libssh2_channel_free(session->channels.head);
|
rc = libssh2_channel_free(ch);
|
||||||
if (rc == PACKET_EAGAIN) {
|
if (rc == PACKET_EAGAIN)
|
||||||
return 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) {
|
if (tmp == session->channels.head) {
|
||||||
/* channel_free couldn't do it's job, perform a messy cleanup */
|
/* channel_free couldn't do it's job, perform a messy cleanup */
|
||||||
tmp = session->channels.head;
|
tmp = session->channels.head;
|
||||||
@@ -728,17 +715,17 @@ session_free(LIBSSH2_SESSION *session)
|
|||||||
/* reverse linking isn't important here, we're killing the
|
/* reverse linking isn't important here, we're killing the
|
||||||
* structure */
|
* structure */
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
session->state = libssh2_NB_state_sent;
|
session->state = libssh2_NB_state_sent;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (session->state == libssh2_NB_state_sent) {
|
if (session->state == libssh2_NB_state_sent) {
|
||||||
while (session->listeners) {
|
while ((l = _libssh2_list_first(&session->listeners))) {
|
||||||
rc = libssh2_channel_forward_cancel(session->listeners);
|
rc = libssh2_channel_forward_cancel(l);
|
||||||
if (rc == PACKET_EAGAIN) {
|
if (rc == PACKET_EAGAIN)
|
||||||
return PACKET_EAGAIN;
|
return rc;
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
session->state = libssh2_NB_state_sent1;
|
session->state = libssh2_NB_state_sent1;
|
||||||
@@ -908,16 +895,14 @@ session_free(LIBSSH2_SESSION *session)
|
|||||||
LIBSSH2_FREE(session, session->err_msg);
|
LIBSSH2_FREE(session, session->err_msg);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Cleanup any remaining packets */
|
/* Cleanup all remaining packets */
|
||||||
while (session->packets.head) {
|
while ((pkg = _libssh2_list_first(&session->packets))) {
|
||||||
LIBSSH2_PACKET *tmp = session->packets.head;
|
/* unlink the node */
|
||||||
|
_libssh2_list_remove(&pkg->node);
|
||||||
/* unlink */
|
|
||||||
session->packets.head = tmp->next;
|
|
||||||
|
|
||||||
/* free */
|
/* free */
|
||||||
LIBSSH2_FREE(session, tmp->data);
|
LIBSSH2_FREE(session, pkg->data);
|
||||||
LIBSSH2_FREE(session, tmp);
|
LIBSSH2_FREE(session, pkg);
|
||||||
}
|
}
|
||||||
|
|
||||||
if(session->socket_prev_blockstate)
|
if(session->socket_prev_blockstate)
|
||||||
@@ -1007,7 +992,7 @@ session_disconnect(LIBSSH2_SESSION *session, int reason,
|
|||||||
rc = _libssh2_transport_write(session, session->disconnect_data,
|
rc = _libssh2_transport_write(session, session->disconnect_data,
|
||||||
session->disconnect_data_len);
|
session->disconnect_data_len);
|
||||||
if (rc == PACKET_EAGAIN) {
|
if (rc == PACKET_EAGAIN) {
|
||||||
return PACKET_EAGAIN;
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
LIBSSH2_FREE(session, session->disconnect_data);
|
LIBSSH2_FREE(session, session->disconnect_data);
|
||||||
@@ -1245,7 +1230,7 @@ LIBSSH2_API int
|
|||||||
libssh2_poll_channel_read(LIBSSH2_CHANNEL * channel, int extended)
|
libssh2_poll_channel_read(LIBSSH2_CHANNEL * channel, int extended)
|
||||||
{
|
{
|
||||||
LIBSSH2_SESSION *session = channel->session;
|
LIBSSH2_SESSION *session = channel->session;
|
||||||
LIBSSH2_PACKET *packet = session->packets.head;
|
LIBSSH2_PACKET *packet = _libssh2_list_first(&session->packets);
|
||||||
|
|
||||||
while (packet) {
|
while (packet) {
|
||||||
if ( channel->local.id == _libssh2_ntohu32(packet->data + 1)) {
|
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 */
|
/* else - no data of any type is ready to be read */
|
||||||
}
|
}
|
||||||
packet = packet->next;
|
packet = _libssh2_list_next(&packet->node);
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
@@ -1285,7 +1270,7 @@ poll_channel_write(LIBSSH2_CHANNEL * channel)
|
|||||||
static inline int
|
static inline int
|
||||||
poll_listener_queued(LIBSSH2_LISTENER * listener)
|
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)
|
#elif defined(HAVE_SELECT)
|
||||||
LIBSSH2_SESSION *session = NULL;
|
LIBSSH2_SESSION *session = NULL;
|
||||||
int maxfd = 0;
|
libssh2_socket_t maxfd = 0;
|
||||||
fd_set rfds, wfds;
|
fd_set rfds, wfds;
|
||||||
struct timeval tv;
|
struct timeval tv;
|
||||||
|
|
||||||
@@ -1456,8 +1441,7 @@ libssh2_poll(LIBSSH2_POLLFD * fds, unsigned int nfds, long timeout)
|
|||||||
((fds[i].revents & LIBSSH2_POLLFD_POLLIN) == 0)) {
|
((fds[i].revents & LIBSSH2_POLLFD_POLLIN) == 0)) {
|
||||||
/* No connections known of yet */
|
/* No connections known of yet */
|
||||||
fds[i].revents |=
|
fds[i].revents |=
|
||||||
poll_listener_queued(fds[i].fd.
|
poll_listener_queued(fds[i].fd. listener) ?
|
||||||
listener) ?
|
|
||||||
LIBSSH2_POLLFD_POLLIN : 0;
|
LIBSSH2_POLLFD_POLLIN : 0;
|
||||||
}
|
}
|
||||||
if (fds[i].fd.listener->session->socket_state ==
|
if (fds[i].fd.listener->session->socket_state ==
|
||||||
|
169
src/sftp.c
169
src/sftp.c
@@ -124,22 +124,15 @@ sftp_packet_add(LIBSSH2_SFTP *sftp, unsigned char *data,
|
|||||||
if (!packet) {
|
if (!packet) {
|
||||||
libssh2_error(session, LIBSSH2_ERROR_ALLOC,
|
libssh2_error(session, LIBSSH2_ERROR_ALLOC,
|
||||||
"Unable to allocate datablock for SFTP packet", 0);
|
"Unable to allocate datablock for SFTP packet", 0);
|
||||||
return -1;
|
return LIBSSH2_ERROR_ALLOC;
|
||||||
}
|
}
|
||||||
memset(packet, 0, sizeof(LIBSSH2_PACKET));
|
memset(packet, 0, sizeof(LIBSSH2_PACKET));
|
||||||
|
|
||||||
packet->data = data;
|
packet->data = data;
|
||||||
packet->data_len = data_len;
|
packet->data_len = data_len;
|
||||||
packet->data_head = 5;
|
packet->data_head = 5;
|
||||||
packet->brigade = &sftp->packets;
|
|
||||||
packet->next = NULL;
|
_libssh2_list_add(&sftp->packets, &packet->node);
|
||||||
packet->prev = sftp->packets.tail;
|
|
||||||
if (packet->prev) {
|
|
||||||
packet->prev->next = packet;
|
|
||||||
} else {
|
|
||||||
sftp->packets.head = packet;
|
|
||||||
}
|
|
||||||
sftp->packets.tail = packet;
|
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@@ -174,17 +167,17 @@ sftp_packet_read(LIBSSH2_SFTP *sftp)
|
|||||||
"partial read cont, len: %lu", packet_len);
|
"partial read cont, len: %lu", packet_len);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
rc = libssh2_channel_read_ex(channel, 0, (char *) buffer, 4);
|
rc = _libssh2_channel_read(channel, 0, (char *) buffer, 4);
|
||||||
if (rc == PACKET_EAGAIN) {
|
if (rc == PACKET_EAGAIN) {
|
||||||
return PACKET_EAGAIN;
|
return rc;
|
||||||
}
|
}
|
||||||
else if (4 != rc) {
|
else if (4 != rc) {
|
||||||
/* TODO: this is stupid since we can in fact get 1-3 bytes in a
|
/* 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
|
legitimate working case as well if the connection happens to be
|
||||||
super slow or something */
|
super slow or something */
|
||||||
libssh2_error(session, LIBSSH2_ERROR_SOCKET_TIMEOUT,
|
libssh2_error(session, LIBSSH2_ERROR_CHANNEL_FAILURE,
|
||||||
"Timeout waiting for FXP packet", 0);
|
"Read part of packet", 0);
|
||||||
return -1;
|
return LIBSSH2_ERROR_CHANNEL_FAILURE;
|
||||||
}
|
}
|
||||||
|
|
||||||
packet_len = _libssh2_ntohu32(buffer);
|
packet_len = _libssh2_ntohu32(buffer);
|
||||||
@@ -193,14 +186,14 @@ sftp_packet_read(LIBSSH2_SFTP *sftp)
|
|||||||
if (packet_len > LIBSSH2_SFTP_PACKET_MAXLEN) {
|
if (packet_len > LIBSSH2_SFTP_PACKET_MAXLEN) {
|
||||||
libssh2_error(session, LIBSSH2_ERROR_CHANNEL_PACKET_EXCEEDED,
|
libssh2_error(session, LIBSSH2_ERROR_CHANNEL_PACKET_EXCEEDED,
|
||||||
"SFTP packet too large", 0);
|
"SFTP packet too large", 0);
|
||||||
return -1;
|
return LIBSSH2_ERROR_CHANNEL_PACKET_EXCEEDED;
|
||||||
}
|
}
|
||||||
|
|
||||||
packet = LIBSSH2_ALLOC(session, packet_len);
|
packet = LIBSSH2_ALLOC(session, packet_len);
|
||||||
if (!packet) {
|
if (!packet) {
|
||||||
libssh2_error(session, LIBSSH2_ERROR_ALLOC,
|
libssh2_error(session, LIBSSH2_ERROR_ALLOC,
|
||||||
"Unable to allocate SFTP packet", 0);
|
"Unable to allocate SFTP packet", 0);
|
||||||
return -1;
|
return LIBSSH2_ERROR_ALLOC;
|
||||||
}
|
}
|
||||||
|
|
||||||
packet_received = 0;
|
packet_received = 0;
|
||||||
@@ -209,9 +202,9 @@ sftp_packet_read(LIBSSH2_SFTP *sftp)
|
|||||||
/* Read as much of the packet as we can */
|
/* Read as much of the packet as we can */
|
||||||
while (packet_len > packet_received) {
|
while (packet_len > packet_received) {
|
||||||
bytes_received =
|
bytes_received =
|
||||||
libssh2_channel_read_ex(channel, 0,
|
_libssh2_channel_read(channel, 0,
|
||||||
(char *) packet + packet_received,
|
(char *) packet + packet_received,
|
||||||
packet_len - packet_received);
|
packet_len - packet_received);
|
||||||
|
|
||||||
if (bytes_received == PACKET_EAGAIN) {
|
if (bytes_received == PACKET_EAGAIN) {
|
||||||
/*
|
/*
|
||||||
@@ -223,20 +216,21 @@ sftp_packet_read(LIBSSH2_SFTP *sftp)
|
|||||||
sftp->partial_received = packet_received;
|
sftp->partial_received = packet_received;
|
||||||
packet = NULL;
|
packet = NULL;
|
||||||
|
|
||||||
return PACKET_EAGAIN;
|
return bytes_received;
|
||||||
}
|
}
|
||||||
else if (bytes_received < 0) {
|
else if (bytes_received < 0) {
|
||||||
libssh2_error(session, LIBSSH2_ERROR_SOCKET_TIMEOUT,
|
libssh2_error(session, LIBSSH2_ERROR_SOCKET_TIMEOUT,
|
||||||
"Receive error waiting for SFTP packet", 0);
|
"Receive error waiting for SFTP packet", 0);
|
||||||
LIBSSH2_FREE(session, packet);
|
LIBSSH2_FREE(session, packet);
|
||||||
return -1;
|
return bytes_received;
|
||||||
}
|
}
|
||||||
packet_received += 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);
|
LIBSSH2_FREE(session, packet);
|
||||||
return -1;
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
return packet[0];
|
return packet[0];
|
||||||
@@ -253,7 +247,7 @@ sftp_packet_ask(LIBSSH2_SFTP *sftp, unsigned char packet_type,
|
|||||||
unsigned long *data_len)
|
unsigned long *data_len)
|
||||||
{
|
{
|
||||||
LIBSSH2_SESSION *session = sftp->channel->session;
|
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];
|
unsigned char match_buf[5];
|
||||||
int match_len;
|
int match_len;
|
||||||
|
|
||||||
@@ -277,24 +271,13 @@ sftp_packet_ask(LIBSSH2_SFTP *sftp, unsigned char packet_type,
|
|||||||
*data_len = packet->data_len;
|
*data_len = packet->data_len;
|
||||||
|
|
||||||
/* unlink and free this struct */
|
/* unlink and free this struct */
|
||||||
if (packet->prev) {
|
_libssh2_list_remove(&packet->node);
|
||||||
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_FREE(session, packet);
|
LIBSSH2_FREE(session, packet);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
/* check next struct in the list */
|
/* check next struct in the list */
|
||||||
packet = packet->next;
|
packet = _libssh2_list_next(&packet->node);
|
||||||
}
|
}
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
@@ -323,7 +306,7 @@ sftp_packet_require(LIBSSH2_SFTP *sftp, unsigned char packet_type,
|
|||||||
while (session->socket_state == LIBSSH2_SOCKET_CONNECTED) {
|
while (session->socket_state == LIBSSH2_SOCKET_CONNECTED) {
|
||||||
ret = sftp_packet_read(sftp);
|
ret = sftp_packet_read(sftp);
|
||||||
if (ret == PACKET_EAGAIN) {
|
if (ret == PACKET_EAGAIN) {
|
||||||
return PACKET_EAGAIN;
|
return ret;
|
||||||
} else if (ret <= 0) {
|
} else if (ret <= 0) {
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
@@ -338,7 +321,7 @@ sftp_packet_require(LIBSSH2_SFTP *sftp, unsigned char packet_type,
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Only reached if the socket died */
|
/* Only reached if the socket died */
|
||||||
return -1;
|
return LIBSSH2_ERROR_SOCKET_DISCONNECT;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* sftp_packet_requirev
|
/* sftp_packet_requirev
|
||||||
@@ -385,7 +368,7 @@ sftp_packet_requirev(LIBSSH2_SFTP *sftp, int num_valid_responses,
|
|||||||
return PACKET_TIMEOUT;
|
return PACKET_TIMEOUT;
|
||||||
}
|
}
|
||||||
else if (ret == PACKET_EAGAIN) {
|
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
|
* 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.
|
* 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
|
* Note that you MUST NOT try to call libssh2_sftp_init() again to get
|
||||||
* another handle until the previous one has finished and either
|
* another handle until the previous call has finished and either
|
||||||
* succesffully made a handle or failed and returned error (not
|
* succesffully made a handle or failed and returned error (not
|
||||||
* including *EAGAIN).
|
* including *EAGAIN).
|
||||||
*/
|
*/
|
||||||
@@ -715,6 +698,8 @@ static LIBSSH2_SFTP *sftp_init(LIBSSH2_SESSION *session)
|
|||||||
session->sftpInit_sftp = NULL;
|
session->sftpInit_sftp = NULL;
|
||||||
session->sftpInit_channel = NULL;
|
session->sftpInit_channel = NULL;
|
||||||
|
|
||||||
|
_libssh2_list_init(&sftp_handle->sftp_handles);
|
||||||
|
|
||||||
return sftp_handle;
|
return sftp_handle;
|
||||||
|
|
||||||
sftp_init_error:
|
sftp_init_error:
|
||||||
@@ -798,6 +783,9 @@ sftp_shutdown(LIBSSH2_SFTP *sftp)
|
|||||||
sftp->symlink_packet = NULL;
|
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);
|
rc = _libssh2_channel_free(sftp->channel);
|
||||||
|
|
||||||
return rc;
|
return rc;
|
||||||
@@ -810,8 +798,7 @@ LIBSSH2_API int
|
|||||||
libssh2_sftp_shutdown(LIBSSH2_SFTP *sftp)
|
libssh2_sftp_shutdown(LIBSSH2_SFTP *sftp)
|
||||||
{
|
{
|
||||||
int rc;
|
int rc;
|
||||||
BLOCK_ADJUST(rc, sftp->channel->session,
|
BLOCK_ADJUST(rc, sftp->channel->session, sftp_shutdown(sftp));
|
||||||
sftp_shutdown(sftp));
|
|
||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -920,7 +907,7 @@ sftp_open(LIBSSH2_SFTP *sftp, const char *filename,
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
else if (rc) {
|
else if (rc) {
|
||||||
libssh2_error(session, LIBSSH2_ERROR_SOCKET_TIMEOUT,
|
libssh2_error(session, rc,
|
||||||
"Timeout waiting for status message", 0);
|
"Timeout waiting for status message", 0);
|
||||||
sftp->open_state = libssh2_NB_state_idle;
|
sftp->open_state = libssh2_NB_state_idle;
|
||||||
return NULL;
|
return NULL;
|
||||||
@@ -985,12 +972,10 @@ sftp_open(LIBSSH2_SFTP *sftp, const char *filename,
|
|||||||
memcpy(fp->handle, data + 9, fp->handle_len);
|
memcpy(fp->handle, data + 9, fp->handle_len);
|
||||||
LIBSSH2_FREE(session, data);
|
LIBSSH2_FREE(session, data);
|
||||||
|
|
||||||
/* Link the file and the sftp session together */
|
/* add this file handle to the list kept in the sftp session */
|
||||||
fp->next = sftp->handles;
|
_libssh2_list_add(&sftp->sftp_handles, &fp->node);
|
||||||
if (fp->next) {
|
|
||||||
fp->next->prev = fp;
|
fp->sftp = sftp; /* point to the parent struct */
|
||||||
}
|
|
||||||
fp->sftp = sftp;
|
|
||||||
|
|
||||||
fp->u.file.offset = 0;
|
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_packet = packet;
|
||||||
sftp->read_request_id = request_id;
|
sftp->read_request_id = request_id;
|
||||||
sftp->read_total_read = total_read;
|
sftp->read_total_read = total_read;
|
||||||
return PACKET_EAGAIN;
|
return retcode;
|
||||||
} else if (packet_len != retcode) {
|
} else if (packet_len != retcode) {
|
||||||
/* TODO: a partial write is not a critical error when in
|
/* TODO: a partial write is not a critical error when in
|
||||||
non-blocking mode! */
|
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,
|
sftp_packet_requirev(sftp, 2, read_responses,
|
||||||
request_id, &data, &data_len);
|
request_id, &data, &data_len);
|
||||||
if (retcode == PACKET_EAGAIN) {
|
if (retcode == PACKET_EAGAIN) {
|
||||||
return PACKET_EAGAIN;
|
libssh2_error(session, retcode,
|
||||||
|
"Would block waiting for status message", 0);
|
||||||
|
return retcode;
|
||||||
} else if (retcode) {
|
} else if (retcode) {
|
||||||
libssh2_error(session, LIBSSH2_ERROR_SOCKET_TIMEOUT,
|
libssh2_error(session, retcode,
|
||||||
"Timeout waiting for status message", 0);
|
"Timeout waiting for status message", 0);
|
||||||
sftp->read_packet = NULL;
|
sftp->read_packet = NULL;
|
||||||
sftp->read_state = libssh2_NB_state_idle;
|
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,
|
(char *) sftp->readdir_packet,
|
||||||
packet_len);
|
packet_len);
|
||||||
if (retcode == PACKET_EAGAIN) {
|
if (retcode == PACKET_EAGAIN) {
|
||||||
return PACKET_EAGAIN;
|
return retcode;
|
||||||
}
|
}
|
||||||
else if (packet_len != retcode) {
|
else if (packet_len != retcode) {
|
||||||
libssh2_error(session, LIBSSH2_ERROR_SOCKET_SEND,
|
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,
|
sftp->readdir_request_id, &data,
|
||||||
&data_len);
|
&data_len);
|
||||||
if (retcode == PACKET_EAGAIN) {
|
if (retcode == PACKET_EAGAIN) {
|
||||||
return PACKET_EAGAIN;
|
return retcode;
|
||||||
} else if (retcode) {
|
} else if (retcode) {
|
||||||
libssh2_error(session, LIBSSH2_ERROR_SOCKET_TIMEOUT,
|
libssh2_error(session, LIBSSH2_ERROR_SOCKET_TIMEOUT,
|
||||||
"Timeout waiting for status message", 0);
|
"Timeout waiting for status message", 0);
|
||||||
@@ -1418,7 +1405,8 @@ libssh2_sftp_readdir_ex(LIBSSH2_SFTP_HANDLE *hnd, char *buffer,
|
|||||||
/*
|
/*
|
||||||
* sftp_write
|
* 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,
|
static ssize_t sftp_write(LIBSSH2_SFTP_HANDLE *handle, const char *buffer,
|
||||||
size_t count)
|
size_t count)
|
||||||
@@ -1449,7 +1437,7 @@ static ssize_t sftp_write(LIBSSH2_SFTP_HANDLE *handle, const char *buffer,
|
|||||||
if (!sftp->write_packet) {
|
if (!sftp->write_packet) {
|
||||||
libssh2_error(session, LIBSSH2_ERROR_ALLOC,
|
libssh2_error(session, LIBSSH2_ERROR_ALLOC,
|
||||||
"Unable to allocate memory for FXP_WRITE", 0);
|
"Unable to allocate memory for FXP_WRITE", 0);
|
||||||
return -1;
|
return LIBSSH2_ERROR_ALLOC;
|
||||||
}
|
}
|
||||||
_libssh2_htonu32(s, packet_len - 4);
|
_libssh2_htonu32(s, packet_len - 4);
|
||||||
s += 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) {
|
if (sftp->write_state == libssh2_NB_state_created) {
|
||||||
rc = _libssh2_channel_write(channel, 0, (char *)sftp->write_packet,
|
rc = _libssh2_channel_write(channel, 0, (char *)sftp->write_packet,
|
||||||
packet_len);
|
packet_len);
|
||||||
if (rc == PACKET_EAGAIN) {
|
if(rc < 0) {
|
||||||
return PACKET_EAGAIN;
|
/* error */
|
||||||
}
|
|
||||||
else if(rc < 0) {
|
|
||||||
/* an actual error */
|
|
||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
else if(0 == rc) {
|
else if(0 == rc) {
|
||||||
/* an actual error */
|
/* nothing sent is an error */
|
||||||
fprintf(stderr, "WEIRDNESS\n");
|
return LIBSSH2_ERROR_SOCKET_SEND;
|
||||||
return -1;
|
|
||||||
}
|
}
|
||||||
else if (packet_len != rc) {
|
else if (packet_len != rc) {
|
||||||
return 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,
|
rc = sftp_packet_require(sftp, SSH_FXP_STATUS,
|
||||||
sftp->write_request_id, &data, &data_len);
|
sftp->write_request_id, &data, &data_len);
|
||||||
if (rc == PACKET_EAGAIN) {
|
if (rc == PACKET_EAGAIN) {
|
||||||
return PACKET_EAGAIN;
|
return rc;
|
||||||
} else if (rc) {
|
}
|
||||||
libssh2_error(session, LIBSSH2_ERROR_SOCKET_TIMEOUT,
|
else if (rc) {
|
||||||
|
libssh2_error(session, rc,
|
||||||
"Timeout waiting for status message", 0);
|
"Timeout waiting for status message", 0);
|
||||||
sftp->write_state = libssh2_NB_state_idle;
|
sftp->write_state = libssh2_NB_state_idle;
|
||||||
return -1;
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
sftp->write_state = libssh2_NB_state_idle;
|
sftp->write_state = libssh2_NB_state_idle;
|
||||||
@@ -1518,7 +1503,7 @@ static ssize_t sftp_write(LIBSSH2_SFTP_HANDLE *handle, const char *buffer,
|
|||||||
0);
|
0);
|
||||||
sftp->last_errno = retcode;
|
sftp->last_errno = retcode;
|
||||||
|
|
||||||
return -1;
|
return LIBSSH2_ERROR_SFTP_PROTOCOL;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* libssh2_sftp_write
|
/* 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,
|
rc = _libssh2_channel_write(channel, 0, (char *) sftp->fstat_packet,
|
||||||
packet_len);
|
packet_len);
|
||||||
if (rc == PACKET_EAGAIN) {
|
if (rc == PACKET_EAGAIN) {
|
||||||
return PACKET_EAGAIN;
|
return rc;
|
||||||
} else if (packet_len != rc) {
|
} else if (packet_len != rc) {
|
||||||
libssh2_error(session, LIBSSH2_ERROR_SOCKET_SEND,
|
libssh2_error(session, LIBSSH2_ERROR_SOCKET_SEND,
|
||||||
(setstat ? "Unable to send FXP_FSETSTAT"
|
(setstat ? "Unable to send FXP_FSETSTAT"
|
||||||
@@ -1607,7 +1592,7 @@ static int sftp_fstat(LIBSSH2_SFTP_HANDLE *handle,
|
|||||||
sftp->fstat_request_id, &data,
|
sftp->fstat_request_id, &data,
|
||||||
&data_len);
|
&data_len);
|
||||||
if (rc == PACKET_EAGAIN) {
|
if (rc == PACKET_EAGAIN) {
|
||||||
return PACKET_EAGAIN;
|
return rc;
|
||||||
} else if (rc) {
|
} else if (rc) {
|
||||||
libssh2_error(session, LIBSSH2_ERROR_SOCKET_TIMEOUT,
|
libssh2_error(session, LIBSSH2_ERROR_SOCKET_TIMEOUT,
|
||||||
"Timeout waiting for status message", 0);
|
"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,
|
rc = _libssh2_channel_write(channel, 0, (char *) handle->close_packet,
|
||||||
packet_len);
|
packet_len);
|
||||||
if (rc == PACKET_EAGAIN) {
|
if (rc == PACKET_EAGAIN) {
|
||||||
return PACKET_EAGAIN;
|
return rc;
|
||||||
} else if (packet_len != rc) {
|
} else if (packet_len != rc) {
|
||||||
libssh2_error(session, LIBSSH2_ERROR_SOCKET_SEND,
|
libssh2_error(session, LIBSSH2_ERROR_SOCKET_SEND,
|
||||||
"Unable to send FXP_CLOSE command", 0);
|
"Unable to send FXP_CLOSE command", 0);
|
||||||
@@ -1753,7 +1738,7 @@ sftp_close_handle(LIBSSH2_SFTP_HANDLE *handle)
|
|||||||
handle->close_request_id, &data,
|
handle->close_request_id, &data,
|
||||||
&data_len);
|
&data_len);
|
||||||
if (rc == PACKET_EAGAIN) {
|
if (rc == PACKET_EAGAIN) {
|
||||||
return PACKET_EAGAIN;
|
return rc;
|
||||||
} else if (rc) {
|
} else if (rc) {
|
||||||
libssh2_error(session, LIBSSH2_ERROR_SOCKET_TIMEOUT,
|
libssh2_error(session, LIBSSH2_ERROR_SOCKET_TIMEOUT,
|
||||||
"Timeout waiting for status message", 0);
|
"Timeout waiting for status message", 0);
|
||||||
@@ -1775,12 +1760,8 @@ sftp_close_handle(LIBSSH2_SFTP_HANDLE *handle)
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (handle == sftp->handles) {
|
/* remove this handle from the parent's list */
|
||||||
sftp->handles = handle->next;
|
_libssh2_list_remove(&handle->node);
|
||||||
}
|
|
||||||
if (handle->next) {
|
|
||||||
handle->next->prev = NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
if ((handle->handle_type == LIBSSH2_SFTP_HANDLE_DIR)
|
if ((handle->handle_type == LIBSSH2_SFTP_HANDLE_DIR)
|
||||||
&& handle->u.dir.names_left) {
|
&& 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,
|
rc = _libssh2_channel_write(channel, 0, (char *) sftp->unlink_packet,
|
||||||
packet_len);
|
packet_len);
|
||||||
if (rc == PACKET_EAGAIN) {
|
if (rc == PACKET_EAGAIN) {
|
||||||
return PACKET_EAGAIN;
|
return rc;
|
||||||
} else if (packet_len != rc) {
|
} else if (packet_len != rc) {
|
||||||
libssh2_error(session, LIBSSH2_ERROR_SOCKET_SEND,
|
libssh2_error(session, LIBSSH2_ERROR_SOCKET_SEND,
|
||||||
"Unable to send FXP_REMOVE command", 0);
|
"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,
|
sftp->unlink_request_id, &data,
|
||||||
&data_len);
|
&data_len);
|
||||||
if (rc == PACKET_EAGAIN) {
|
if (rc == PACKET_EAGAIN) {
|
||||||
return PACKET_EAGAIN;
|
return rc;
|
||||||
}
|
}
|
||||||
else if (rc) {
|
else if (rc) {
|
||||||
libssh2_error(session, LIBSSH2_ERROR_SOCKET_TIMEOUT,
|
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,
|
rc = _libssh2_channel_write(channel, 0, (char *) sftp->rename_packet,
|
||||||
sftp->rename_s - sftp->rename_packet);
|
sftp->rename_s - sftp->rename_packet);
|
||||||
if (rc == PACKET_EAGAIN) {
|
if (rc == PACKET_EAGAIN) {
|
||||||
return PACKET_EAGAIN;
|
return rc;
|
||||||
} else if (packet_len != rc) {
|
} else if (packet_len != rc) {
|
||||||
libssh2_error(session, LIBSSH2_ERROR_SOCKET_SEND,
|
libssh2_error(session, LIBSSH2_ERROR_SOCKET_SEND,
|
||||||
"Unable to send FXP_RENAME command", 0);
|
"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,
|
sftp->rename_request_id, &data,
|
||||||
&data_len);
|
&data_len);
|
||||||
if (rc == PACKET_EAGAIN) {
|
if (rc == PACKET_EAGAIN) {
|
||||||
return PACKET_EAGAIN;
|
return rc;
|
||||||
} else if (rc) {
|
} else if (rc) {
|
||||||
libssh2_error(session, LIBSSH2_ERROR_SOCKET_TIMEOUT,
|
libssh2_error(session, LIBSSH2_ERROR_SOCKET_TIMEOUT,
|
||||||
"Timeout waiting for status message", 0);
|
"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);
|
rc = _libssh2_channel_write(channel, 0, (char *) packet, packet_len);
|
||||||
if (rc == PACKET_EAGAIN) {
|
if (rc == PACKET_EAGAIN) {
|
||||||
sftp->mkdir_packet = packet;
|
sftp->mkdir_packet = packet;
|
||||||
return PACKET_EAGAIN;
|
return rc;
|
||||||
}
|
}
|
||||||
if (packet_len != rc) {
|
if (packet_len != rc) {
|
||||||
libssh2_error(session, LIBSSH2_ERROR_SOCKET_SEND,
|
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,
|
rc = sftp_packet_require(sftp, SSH_FXP_STATUS, sftp->mkdir_request_id,
|
||||||
&data, &data_len);
|
&data, &data_len);
|
||||||
if (rc == PACKET_EAGAIN) {
|
if (rc == PACKET_EAGAIN) {
|
||||||
return PACKET_EAGAIN;
|
return rc;
|
||||||
} else if (rc) {
|
} else if (rc) {
|
||||||
libssh2_error(session, LIBSSH2_ERROR_SOCKET_TIMEOUT,
|
libssh2_error(session, LIBSSH2_ERROR_SOCKET_TIMEOUT,
|
||||||
"Timeout waiting for status message", 0);
|
"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,
|
rc = _libssh2_channel_write(channel, 0, (char *) sftp->rmdir_packet,
|
||||||
packet_len);
|
packet_len);
|
||||||
if (rc == PACKET_EAGAIN) {
|
if (rc == PACKET_EAGAIN) {
|
||||||
return PACKET_EAGAIN;
|
return rc;
|
||||||
} else if (packet_len != rc) {
|
} else if (packet_len != rc) {
|
||||||
libssh2_error(session, LIBSSH2_ERROR_SOCKET_SEND,
|
libssh2_error(session, LIBSSH2_ERROR_SOCKET_SEND,
|
||||||
"Unable to send FXP_RMDIR command", 0);
|
"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,
|
rc = sftp_packet_require(sftp, SSH_FXP_STATUS,
|
||||||
sftp->rmdir_request_id, &data, &data_len);
|
sftp->rmdir_request_id, &data, &data_len);
|
||||||
if (rc == PACKET_EAGAIN) {
|
if (rc == PACKET_EAGAIN) {
|
||||||
return PACKET_EAGAIN;
|
return rc;
|
||||||
} else if (rc) {
|
} else if (rc) {
|
||||||
libssh2_error(session, LIBSSH2_ERROR_SOCKET_TIMEOUT,
|
libssh2_error(session, LIBSSH2_ERROR_SOCKET_TIMEOUT,
|
||||||
"Timeout waiting for status message", 0);
|
"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,
|
rc = _libssh2_channel_write(channel, 0, (char *) sftp->stat_packet,
|
||||||
packet_len);
|
packet_len);
|
||||||
if (rc == PACKET_EAGAIN) {
|
if (rc == PACKET_EAGAIN) {
|
||||||
return PACKET_EAGAIN;
|
return rc;
|
||||||
} else if (packet_len != rc) {
|
} else if (packet_len != rc) {
|
||||||
libssh2_error(session, LIBSSH2_ERROR_SOCKET_SEND,
|
libssh2_error(session, LIBSSH2_ERROR_SOCKET_SEND,
|
||||||
"Unable to send STAT/LSTAT/SETSTAT command", 0);
|
"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,
|
rc = sftp_packet_requirev(sftp, 2, stat_responses,
|
||||||
sftp->stat_request_id, &data, &data_len);
|
sftp->stat_request_id, &data, &data_len);
|
||||||
if (rc == PACKET_EAGAIN) {
|
if (rc == PACKET_EAGAIN) {
|
||||||
return PACKET_EAGAIN;
|
return rc;
|
||||||
} else if (rc) {
|
} else if (rc) {
|
||||||
libssh2_error(session, LIBSSH2_ERROR_SOCKET_TIMEOUT,
|
libssh2_error(session, LIBSSH2_ERROR_SOCKET_TIMEOUT,
|
||||||
"Timeout waiting for status message", 0);
|
"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,
|
rc = _libssh2_channel_write(channel, 0, (char *) sftp->symlink_packet,
|
||||||
packet_len);
|
packet_len);
|
||||||
if (rc == PACKET_EAGAIN) {
|
if (rc == PACKET_EAGAIN) {
|
||||||
return PACKET_EAGAIN;
|
return rc;
|
||||||
} else if (packet_len != rc) {
|
} else if (packet_len != rc) {
|
||||||
libssh2_error(session, LIBSSH2_ERROR_SOCKET_SEND,
|
libssh2_error(session, LIBSSH2_ERROR_SOCKET_SEND,
|
||||||
"Unable to send SYMLINK/READLINK command", 0);
|
"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,
|
sftp->symlink_request_id, &data,
|
||||||
&data_len);
|
&data_len);
|
||||||
if (rc == PACKET_EAGAIN) {
|
if (rc == PACKET_EAGAIN) {
|
||||||
return PACKET_EAGAIN;
|
return rc;
|
||||||
}
|
}
|
||||||
else if (rc) {
|
else if (rc) {
|
||||||
libssh2_error(session, LIBSSH2_ERROR_SOCKET_TIMEOUT,
|
libssh2_error(session, LIBSSH2_ERROR_SOCKET_TIMEOUT,
|
||||||
|
@@ -95,10 +95,10 @@ debugdump(LIBSSH2_SESSION * session,
|
|||||||
|
|
||||||
/* decrypt() decrypts 'len' bytes from 'source' to 'dest'.
|
/* 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,
|
decrypt(LIBSSH2_SESSION * session, unsigned char *source,
|
||||||
unsigned char *dest, int len)
|
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
|
* fullpacket() gets called when a full packet has been received and properly
|
||||||
* collected.
|
* collected.
|
||||||
*/
|
*/
|
||||||
static libssh2pack_t
|
static int
|
||||||
fullpacket(LIBSSH2_SESSION * session, int encrypted /* 1 or 0 */ )
|
fullpacket(LIBSSH2_SESSION * session, int encrypted /* 1 or 0 */ )
|
||||||
{
|
{
|
||||||
unsigned char macbuf[MAX_MACSIZE];
|
unsigned char macbuf[MAX_MACSIZE];
|
||||||
@@ -232,11 +232,8 @@ fullpacket(LIBSSH2_SESSION * session, int encrypted /* 1 or 0 */ )
|
|||||||
rc = _libssh2_packet_add(session, p->payload,
|
rc = _libssh2_packet_add(session, p->payload,
|
||||||
session->fullpacket_payload_len,
|
session->fullpacket_payload_len,
|
||||||
session->fullpacket_macstate);
|
session->fullpacket_macstate);
|
||||||
if (rc == PACKET_EAGAIN) {
|
if (rc)
|
||||||
return PACKET_EAGAIN;
|
return rc;
|
||||||
} else if (rc < 0) {
|
|
||||||
return PACKET_FAIL;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
session->fullpacket_state = libssh2_NB_state_idle;
|
session->fullpacket_state = libssh2_NB_state_idle;
|
||||||
@@ -248,22 +245,21 @@ fullpacket(LIBSSH2_SESSION * session, int encrypted /* 1 or 0 */ )
|
|||||||
/*
|
/*
|
||||||
* _libssh2_transport_read
|
* _libssh2_transport_read
|
||||||
*
|
*
|
||||||
* Collect a packet into the input brigade block only controls whether or not
|
* Collect a packet into the input queue.
|
||||||
* to wait for a packet to start.
|
|
||||||
*
|
*
|
||||||
* Returns packet type added to input brigade (PACKET_NONE if nothing added),
|
* Returns packet type added to input queue (0 if nothing added), or a
|
||||||
* or PACKET_FAIL on failure and PACKET_EAGAIN if it couldn't process a full
|
* negative error number.
|
||||||
* packet.
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* This function reads the binary stream as specified in chapter 6 of RFC4253
|
* This function reads the binary stream as specified in chapter 6 of RFC4253
|
||||||
* "The Secure Shell (SSH) Transport Layer Protocol"
|
* "The Secure Shell (SSH) Transport Layer Protocol"
|
||||||
|
*
|
||||||
|
* DOES NOT call libssh2_error() for ANY error case.
|
||||||
*/
|
*/
|
||||||
libssh2pack_t
|
int _libssh2_transport_read(LIBSSH2_SESSION * session)
|
||||||
_libssh2_transport_read(LIBSSH2_SESSION * session)
|
|
||||||
{
|
{
|
||||||
libssh2pack_t rc = -1;
|
int rc = LIBSSH2_ERROR_SOCKET_NONE;
|
||||||
struct transportpacket *p = &session->packet;
|
struct transportpacket *p = &session->packet;
|
||||||
int remainbuf;
|
int remainbuf;
|
||||||
int remainpack;
|
int remainpack;
|
||||||
@@ -272,7 +268,6 @@ _libssh2_transport_read(LIBSSH2_SESSION * session)
|
|||||||
unsigned char block[MAX_BLOCKSIZE];
|
unsigned char block[MAX_BLOCKSIZE];
|
||||||
int blocksize;
|
int blocksize;
|
||||||
int encrypted = 1;
|
int encrypted = 1;
|
||||||
int status;
|
|
||||||
|
|
||||||
/* default clear the bit */
|
/* default clear the bit */
|
||||||
session->socket_block_directions &= ~LIBSSH2_SESSION_BLOCK_INBOUND;
|
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"
|
_libssh2_debug(session, LIBSSH2_DBG_TRANS, "Redirecting into the"
|
||||||
" key re-exchange");
|
" key re-exchange");
|
||||||
status = libssh2_kex_exchange(session, 1, &session->startup_key_state);
|
rc = libssh2_kex_exchange(session, 1, &session->startup_key_state);
|
||||||
if (status == PACKET_EAGAIN) {
|
if (rc)
|
||||||
libssh2_error(session, LIBSSH2_ERROR_EAGAIN,
|
return rc;
|
||||||
"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;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -371,7 +359,7 @@ _libssh2_transport_read(LIBSSH2_SESSION * session)
|
|||||||
/* check if this is due to EAGAIN and return the special
|
/* check if this is due to EAGAIN and return the special
|
||||||
return code if so, error out normally otherwise */
|
return code if so, error out normally otherwise */
|
||||||
if ((nread < 0) && (errno == EAGAIN)) {
|
if ((nread < 0) && (errno == EAGAIN)) {
|
||||||
session->socket_block_directions =
|
session->socket_block_directions |=
|
||||||
LIBSSH2_SESSION_BLOCK_INBOUND;
|
LIBSSH2_SESSION_BLOCK_INBOUND;
|
||||||
return PACKET_EAGAIN;
|
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
|
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
|
got the start of a block we can in fact deal with fractions
|
||||||
*/
|
*/
|
||||||
|
session->socket_block_directions |=
|
||||||
|
LIBSSH2_SESSION_BLOCK_INBOUND;
|
||||||
return PACKET_EAGAIN;
|
return PACKET_EAGAIN;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -570,7 +560,7 @@ _libssh2_transport_read(LIBSSH2_SESSION * session)
|
|||||||
session->readPack_state = libssh2_NB_state_jump1;
|
session->readPack_state = libssh2_NB_state_jump1;
|
||||||
}
|
}
|
||||||
|
|
||||||
return PACKET_EAGAIN;
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
p->total_num = 0; /* no packet buffer available */
|
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 */
|
return PACKET_FAIL; /* we never reach this point */
|
||||||
}
|
}
|
||||||
|
|
||||||
static libssh2pack_t
|
static int
|
||||||
send_existing(LIBSSH2_SESSION * session, unsigned char *data,
|
send_existing(LIBSSH2_SESSION * session, unsigned char *data,
|
||||||
unsigned long data_len, ssize_t * ret)
|
unsigned long data_len, ssize_t * ret)
|
||||||
{
|
{
|
||||||
@@ -630,13 +620,13 @@ send_existing(LIBSSH2_SESSION * session, unsigned char *data,
|
|||||||
/* send failure! */
|
/* send failure! */
|
||||||
return PACKET_FAIL;
|
return PACKET_FAIL;
|
||||||
}
|
}
|
||||||
session->socket_block_directions = LIBSSH2_SESSION_BLOCK_OUTBOUND;
|
session->socket_block_directions |= LIBSSH2_SESSION_BLOCK_OUTBOUND;
|
||||||
return PACKET_EAGAIN;
|
return PACKET_EAGAIN;
|
||||||
}
|
}
|
||||||
|
|
||||||
p->osent += rc; /* we sent away this much data */
|
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
|
* 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.
|
* which is what all implementations should support at least as packet size.
|
||||||
* (RFC4253 section 6.1)
|
* (RFC4253 section 6.1)
|
||||||
|
*
|
||||||
|
* This function DOES not call libssh2_error() on any errors.
|
||||||
*/
|
*/
|
||||||
int
|
int
|
||||||
_libssh2_transport_write(LIBSSH2_SESSION * session, unsigned char *data,
|
_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 encrypted;
|
||||||
int i;
|
int i;
|
||||||
ssize_t ret;
|
ssize_t ret;
|
||||||
libssh2pack_t rc;
|
int rc;
|
||||||
unsigned char *orgdata = data;
|
unsigned char *orgdata = data;
|
||||||
unsigned long orgdata_len = data_len;
|
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 != total_length) {
|
||||||
if ((ret > 0) || ((ret == -1) && (errno == EAGAIN))) {
|
if ((ret > 0) || ((ret == -1) && (errno == EAGAIN))) {
|
||||||
/* the whole packet could not be sent, save the rest */
|
/* the whole packet could not be sent, save the rest */
|
||||||
session->socket_block_directions = LIBSSH2_SESSION_BLOCK_OUTBOUND;
|
session->socket_block_directions |= LIBSSH2_SESSION_BLOCK_OUTBOUND;
|
||||||
p->odata = orgdata;
|
p->odata = orgdata;
|
||||||
p->olen = orgdata_len;
|
p->olen = orgdata_len;
|
||||||
p->osent = (ret == -1) ? 0 : ret;
|
p->osent = (ret == -1) ? 0 : ret;
|
||||||
|
@@ -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
|
* This function reads the binary stream as specified in chapter 6 of RFC4253
|
||||||
* "The Secure Shell (SSH) Transport Layer Protocol"
|
* "The Secure Shell (SSH) Transport Layer Protocol"
|
||||||
*/
|
*/
|
||||||
libssh2pack_t _libssh2_transport_read(LIBSSH2_SESSION * session);
|
int _libssh2_transport_read(LIBSSH2_SESSION * session);
|
||||||
|
|
||||||
#endif /* __LIBSSH2_TRANSPORT_H */
|
#endif /* __LIBSSH2_TRANSPORT_H */
|
||||||
|
@@ -266,7 +266,7 @@ userauth_password(LIBSSH2_SESSION *session, const char *username,
|
|||||||
rc = _libssh2_transport_write(session, session->userauth_pswd_data,
|
rc = _libssh2_transport_write(session, session->userauth_pswd_data,
|
||||||
session->userauth_pswd_data_len);
|
session->userauth_pswd_data_len);
|
||||||
if (rc == PACKET_EAGAIN) {
|
if (rc == PACKET_EAGAIN) {
|
||||||
return PACKET_EAGAIN;
|
return rc;
|
||||||
} else if (rc) {
|
} else if (rc) {
|
||||||
libssh2_error(session, LIBSSH2_ERROR_SOCKET_SEND,
|
libssh2_error(session, LIBSSH2_ERROR_SOCKET_SEND,
|
||||||
"Unable to send userauth-password request", 0);
|
"Unable to send userauth-password request", 0);
|
||||||
@@ -294,7 +294,7 @@ userauth_password(LIBSSH2_SESSION *session, const char *username,
|
|||||||
&session->
|
&session->
|
||||||
userauth_pswd_packet_requirev_state);
|
userauth_pswd_packet_requirev_state);
|
||||||
if (rc == PACKET_EAGAIN) {
|
if (rc == PACKET_EAGAIN) {
|
||||||
return PACKET_EAGAIN;
|
return rc;
|
||||||
} else if (rc) {
|
} else if (rc) {
|
||||||
session->userauth_pswd_state = libssh2_NB_state_idle;
|
session->userauth_pswd_state = libssh2_NB_state_idle;
|
||||||
return -1;
|
return -1;
|
||||||
@@ -402,7 +402,7 @@ userauth_password(LIBSSH2_SESSION *session, const char *username,
|
|||||||
session->
|
session->
|
||||||
userauth_pswd_data_len);
|
userauth_pswd_data_len);
|
||||||
if (rc == PACKET_EAGAIN) {
|
if (rc == PACKET_EAGAIN) {
|
||||||
return PACKET_EAGAIN;
|
return rc;
|
||||||
} else if (rc) {
|
} else if (rc) {
|
||||||
libssh2_error(session, LIBSSH2_ERROR_SOCKET_SEND,
|
libssh2_error(session, LIBSSH2_ERROR_SOCKET_SEND,
|
||||||
"Unable to send userauth-password-change request",
|
"Unable to send userauth-password-change request",
|
||||||
@@ -808,7 +808,7 @@ userauth_hostbased_fromfile(LIBSSH2_SESSION *session,
|
|||||||
session->userauth_host_s -
|
session->userauth_host_s -
|
||||||
session->userauth_host_packet);
|
session->userauth_host_packet);
|
||||||
if (rc == PACKET_EAGAIN) {
|
if (rc == PACKET_EAGAIN) {
|
||||||
return PACKET_EAGAIN;
|
return rc;
|
||||||
} else if (rc) {
|
} else if (rc) {
|
||||||
libssh2_error(session, LIBSSH2_ERROR_SOCKET_SEND,
|
libssh2_error(session, LIBSSH2_ERROR_SOCKET_SEND,
|
||||||
"Unable to send userauth-hostbased request", 0);
|
"Unable to send userauth-hostbased request", 0);
|
||||||
@@ -831,7 +831,7 @@ userauth_hostbased_fromfile(LIBSSH2_SESSION *session,
|
|||||||
&session->
|
&session->
|
||||||
userauth_host_packet_requirev_state);
|
userauth_host_packet_requirev_state);
|
||||||
if (rc == PACKET_EAGAIN) {
|
if (rc == PACKET_EAGAIN) {
|
||||||
return PACKET_EAGAIN;
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
session->userauth_host_state = libssh2_NB_state_idle;
|
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,
|
rc = _libssh2_transport_write(session, session->userauth_pblc_packet,
|
||||||
session->userauth_pblc_packet_len);
|
session->userauth_pblc_packet_len);
|
||||||
if (rc == PACKET_EAGAIN) {
|
if (rc == PACKET_EAGAIN) {
|
||||||
return PACKET_EAGAIN;
|
return rc;
|
||||||
} else if (rc) {
|
} else if (rc) {
|
||||||
libssh2_error(session, LIBSSH2_ERROR_SOCKET_SEND,
|
libssh2_error(session, LIBSSH2_ERROR_SOCKET_SEND,
|
||||||
"Unable to send userauth-publickey request", 0);
|
"Unable to send userauth-publickey request", 0);
|
||||||
@@ -1017,7 +1017,7 @@ userauth_publickey_fromfile(LIBSSH2_SESSION *session,
|
|||||||
&session->
|
&session->
|
||||||
userauth_pblc_packet_requirev_state);
|
userauth_pblc_packet_requirev_state);
|
||||||
if (rc == PACKET_EAGAIN) {
|
if (rc == PACKET_EAGAIN) {
|
||||||
return PACKET_EAGAIN;
|
return rc;
|
||||||
} else if (rc) {
|
} else if (rc) {
|
||||||
LIBSSH2_FREE(session, session->userauth_pblc_packet);
|
LIBSSH2_FREE(session, session->userauth_pblc_packet);
|
||||||
session->userauth_pblc_packet = NULL;
|
session->userauth_pblc_packet = NULL;
|
||||||
@@ -1163,7 +1163,7 @@ userauth_publickey_fromfile(LIBSSH2_SESSION *session,
|
|||||||
session->userauth_pblc_s -
|
session->userauth_pblc_s -
|
||||||
session->userauth_pblc_packet);
|
session->userauth_pblc_packet);
|
||||||
if (rc == PACKET_EAGAIN) {
|
if (rc == PACKET_EAGAIN) {
|
||||||
return PACKET_EAGAIN;
|
return rc;
|
||||||
} else if (rc) {
|
} else if (rc) {
|
||||||
libssh2_error(session, LIBSSH2_ERROR_SOCKET_SEND,
|
libssh2_error(session, LIBSSH2_ERROR_SOCKET_SEND,
|
||||||
"Unable to send userauth-publickey request", 0);
|
"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_data_len, 0, NULL, 0,
|
||||||
&session->userauth_pblc_packet_requirev_state);
|
&session->userauth_pblc_packet_requirev_state);
|
||||||
if (rc == PACKET_EAGAIN) {
|
if (rc == PACKET_EAGAIN) {
|
||||||
return PACKET_EAGAIN;
|
return rc;
|
||||||
} else if (rc) {
|
} else if (rc) {
|
||||||
session->userauth_pblc_state = libssh2_NB_state_idle;
|
session->userauth_pblc_state = libssh2_NB_state_idle;
|
||||||
return -1;
|
return -1;
|
||||||
@@ -1326,7 +1326,7 @@ userauth_keyboard_interactive(LIBSSH2_SESSION * session,
|
|||||||
rc = _libssh2_transport_write(session, session->userauth_kybd_data,
|
rc = _libssh2_transport_write(session, session->userauth_kybd_data,
|
||||||
session->userauth_kybd_packet_len);
|
session->userauth_kybd_packet_len);
|
||||||
if (rc == PACKET_EAGAIN) {
|
if (rc == PACKET_EAGAIN) {
|
||||||
return PACKET_EAGAIN;
|
return rc;
|
||||||
} else if (rc) {
|
} else if (rc) {
|
||||||
libssh2_error(session, LIBSSH2_ERROR_SOCKET_SEND,
|
libssh2_error(session, LIBSSH2_ERROR_SOCKET_SEND,
|
||||||
"Unable to send keyboard-interactive request", 0);
|
"Unable to send keyboard-interactive request", 0);
|
||||||
@@ -1350,7 +1350,7 @@ userauth_keyboard_interactive(LIBSSH2_SESSION * session,
|
|||||||
&session->
|
&session->
|
||||||
userauth_kybd_packet_requirev_state);
|
userauth_kybd_packet_requirev_state);
|
||||||
if (rc == PACKET_EAGAIN) {
|
if (rc == PACKET_EAGAIN) {
|
||||||
return PACKET_EAGAIN;
|
return rc;
|
||||||
} else if (rc) {
|
} else if (rc) {
|
||||||
session->userauth_kybd_state = libssh2_NB_state_idle;
|
session->userauth_kybd_state = libssh2_NB_state_idle;
|
||||||
return -1;
|
return -1;
|
||||||
@@ -1527,7 +1527,7 @@ userauth_keyboard_interactive(LIBSSH2_SESSION * session,
|
|||||||
rc = _libssh2_transport_write(session, session->userauth_kybd_data,
|
rc = _libssh2_transport_write(session, session->userauth_kybd_data,
|
||||||
session->userauth_kybd_packet_len);
|
session->userauth_kybd_packet_len);
|
||||||
if (rc == PACKET_EAGAIN) {
|
if (rc == PACKET_EAGAIN) {
|
||||||
return PACKET_EAGAIN;
|
return rc;
|
||||||
}
|
}
|
||||||
if (rc) {
|
if (rc) {
|
||||||
libssh2_error(session, LIBSSH2_ERROR_SOCKET_SEND,
|
libssh2_error(session, LIBSSH2_ERROR_SOCKET_SEND,
|
||||||
|
@@ -1,8 +0,0 @@
|
|||||||
.deps
|
|
||||||
.libs
|
|
||||||
*.gcno
|
|
||||||
*.gcda
|
|
||||||
Makefile
|
|
||||||
Makefile.in
|
|
||||||
simple
|
|
||||||
ssh2
|
|
7
tests/.gitignore
vendored
7
tests/.gitignore
vendored
@@ -1 +1,8 @@
|
|||||||
|
.deps
|
||||||
|
.libs
|
||||||
|
*.gcno
|
||||||
|
*.gcda
|
||||||
|
Makefile
|
||||||
|
Makefile.in
|
||||||
|
simple
|
||||||
ssh2
|
ssh2
|
||||||
|
@@ -6,7 +6,7 @@ noinst_PROGRAMS = ssh2
|
|||||||
ssh2_SOURCES = ssh2.c
|
ssh2_SOURCES = ssh2.c
|
||||||
endif
|
endif
|
||||||
|
|
||||||
ctests = simple
|
ctests = simple$(EXEEXT)
|
||||||
TESTS = $(ctests)
|
TESTS = $(ctests)
|
||||||
if SSHD
|
if SSHD
|
||||||
TESTS += ssh2.sh
|
TESTS += ssh2.sh
|
||||||
|
@@ -10,12 +10,12 @@
|
|||||||
#ifdef HAVE_WINSOCK2_H
|
#ifdef HAVE_WINSOCK2_H
|
||||||
# include <winsock2.h>
|
# include <winsock2.h>
|
||||||
#endif
|
#endif
|
||||||
#ifdef HAVE_NETINET_IN_H
|
|
||||||
# include <netinet/in.h>
|
|
||||||
#endif
|
|
||||||
#ifdef HAVE_SYS_SOCKET_H
|
#ifdef HAVE_SYS_SOCKET_H
|
||||||
# include <sys/socket.h>
|
# include <sys/socket.h>
|
||||||
#endif
|
#endif
|
||||||
|
#ifdef HAVE_NETINET_IN_H
|
||||||
|
# include <netinet/in.h>
|
||||||
|
#endif
|
||||||
# ifdef HAVE_UNISTD_H
|
# ifdef HAVE_UNISTD_H
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
#endif
|
#endif
|
||||||
|
@@ -9,15 +9,15 @@ srcdir=${srcdir:-$PWD}
|
|||||||
SSHD=${SSHD:-/usr/sbin/sshd}
|
SSHD=${SSHD:-/usr/sbin/sshd}
|
||||||
|
|
||||||
cmd="./ssh2${EXEEXT}"
|
cmd="./ssh2${EXEEXT}"
|
||||||
srcdir=`cd $srcdir; pwd`
|
srcdir=`cd "$srcdir"; pwd`
|
||||||
|
|
||||||
PRIVKEY=$srcdir/etc/user
|
PRIVKEY=$srcdir/etc/user
|
||||||
export PRIVKEY
|
export PRIVKEY
|
||||||
PUBKEY=$srcdir/etc/user.pub
|
PUBKEY=$srcdir/etc/user.pub
|
||||||
export PUBKEY
|
export PUBKEY
|
||||||
|
|
||||||
chmod go-r $srcdir/etc/host*
|
chmod go-rwx "$srcdir"/etc/host*
|
||||||
$SSHD -f /dev/null -h $srcdir/etc/host \
|
$SSHD -f /dev/null -h "$srcdir"/etc/host \
|
||||||
-o 'Port 4711' \
|
-o 'Port 4711' \
|
||||||
-o 'Protocol 2' \
|
-o 'Protocol 2' \
|
||||||
-o "AuthorizedKeysFile $srcdir/etc/user.pub" \
|
-o "AuthorizedKeysFile $srcdir/etc/user.pub" \
|
||||||
|
0
win32/.cvsignore → win32/.gitignore
vendored
0
win32/.cvsignore → win32/.gitignore
vendored
@@ -121,8 +121,7 @@ endif
|
|||||||
|
|
||||||
CFLAGS += $(INCLUDES)
|
CFLAGS += $(INCLUDES)
|
||||||
|
|
||||||
#ifeq ($(findstring msys,$(OSTYPE)),msys)
|
ifeq ($(findstring /sh,$(SHELL)),/sh)
|
||||||
ifdef __MSYS__
|
|
||||||
DL = '
|
DL = '
|
||||||
DS = /
|
DS = /
|
||||||
else
|
else
|
||||||
@@ -131,24 +130,10 @@ endif
|
|||||||
|
|
||||||
vpath %.c . ../src
|
vpath %.c . ../src
|
||||||
|
|
||||||
OBJECTS = \
|
# include Makefile.inc to get CSOURCES define
|
||||||
channel.o \
|
include ../Makefile.inc
|
||||||
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
|
|
||||||
|
|
||||||
|
OBJECTS := $(patsubst %.c,%.o,$(CSOURCES))
|
||||||
OBJS := $(addprefix $(OBJDIR)/,$(OBJECTS))
|
OBJS := $(addprefix $(OBJDIR)/,$(OBJECTS))
|
||||||
OBJL = $(OBJS) $(OBJDIR)/$(TARGET).res
|
OBJL = $(OBJS) $(OBJDIR)/$(TARGET).res
|
||||||
|
|
||||||
|
@@ -1,3 +1,3 @@
|
|||||||
# End Target
|
# End Target
|
||||||
# End Project
|
# End Project
|
||||||
|
|
||||||
|
@@ -1,145 +1,145 @@
|
|||||||
# Microsoft Developer Studio Project File - Name="libssh2" - Package Owner=<4>
|
# Microsoft Developer Studio Project File - Name="libssh2" - Package Owner=<4>
|
||||||
# Microsoft Developer Studio Generated Build File, Format Version 6.00
|
# Microsoft Developer Studio Generated Build File, Format Version 6.00
|
||||||
# ** DO NOT EDIT **
|
# ** DO NOT EDIT **
|
||||||
|
|
||||||
# TARGTYPE "Win32 (x86) Dynamic-Link Library" 0x0102
|
# TARGTYPE "Win32 (x86) Dynamic-Link Library" 0x0102
|
||||||
# TARGTYPE "Win32 (x86) Static Library" 0x0104
|
# TARGTYPE "Win32 (x86) Static Library" 0x0104
|
||||||
|
|
||||||
CFG=libssh2 - Win32 Debug
|
CFG=libssh2 - Win32 Debug
|
||||||
!MESSAGE This is not a valid makefile. To build this project using NMAKE,
|
!MESSAGE This is not a valid makefile. To build this project using NMAKE,
|
||||||
!MESSAGE use the Export Makefile command and run
|
!MESSAGE use the Export Makefile command and run
|
||||||
!MESSAGE
|
!MESSAGE
|
||||||
!MESSAGE NMAKE /f "libssh2.mak".
|
!MESSAGE NMAKE /f "libssh2.mak".
|
||||||
!MESSAGE
|
!MESSAGE
|
||||||
!MESSAGE You can specify a configuration when running NMAKE
|
!MESSAGE You can specify a configuration when running NMAKE
|
||||||
!MESSAGE by defining the macro CFG on the command line. For example:
|
!MESSAGE by defining the macro CFG on the command line. For example:
|
||||||
!MESSAGE
|
!MESSAGE
|
||||||
!MESSAGE NMAKE /f "libssh2.mak" CFG="libssh2 - Win32 DLL Debug"
|
!MESSAGE NMAKE /f "libssh2.mak" CFG="libssh2 - Win32 DLL Debug"
|
||||||
!MESSAGE
|
!MESSAGE
|
||||||
!MESSAGE Possible choices for configuration are:
|
!MESSAGE Possible choices for configuration are:
|
||||||
!MESSAGE
|
!MESSAGE
|
||||||
!MESSAGE "libssh2 - Win32 DLL Release" (based on "Win32 (x86) Dynamic-Link Library")
|
!MESSAGE "libssh2 - Win32 DLL Release" (based on "Win32 (x86) Dynamic-Link Library")
|
||||||
!MESSAGE "libssh2 - Win32 DLL Debug" (based on "Win32 (x86) Dynamic-Link Library")
|
!MESSAGE "libssh2 - Win32 DLL Debug" (based on "Win32 (x86) Dynamic-Link Library")
|
||||||
!MESSAGE "libssh2 - Win32 LIB Release" (based on "Win32 (x86) Static Library")
|
!MESSAGE "libssh2 - Win32 LIB Release" (based on "Win32 (x86) Static Library")
|
||||||
!MESSAGE "libssh2 - Win32 LIB Debug" (based on "Win32 (x86) Static Library")
|
!MESSAGE "libssh2 - Win32 LIB Debug" (based on "Win32 (x86) Static Library")
|
||||||
!MESSAGE
|
!MESSAGE
|
||||||
|
|
||||||
# Begin Project
|
# Begin Project
|
||||||
# PROP AllowPerConfigDependencies 0
|
# PROP AllowPerConfigDependencies 0
|
||||||
# PROP Scc_ProjName ""
|
# PROP Scc_ProjName ""
|
||||||
# PROP Scc_LocalPath ""
|
# PROP Scc_LocalPath ""
|
||||||
CPP=cl.exe
|
CPP=cl.exe
|
||||||
MTL=midl.exe
|
MTL=midl.exe
|
||||||
RSC=rc.exe
|
RSC=rc.exe
|
||||||
|
|
||||||
!IF "$(CFG)" == "libssh2 - Win32 DLL Release"
|
!IF "$(CFG)" == "libssh2 - Win32 DLL Release"
|
||||||
|
|
||||||
# PROP BASE Use_MFC 0
|
# PROP BASE Use_MFC 0
|
||||||
# PROP BASE Use_Debug_Libraries 0
|
# PROP BASE Use_Debug_Libraries 0
|
||||||
# PROP BASE Output_Dir "Release_dll"
|
# PROP BASE Output_Dir "Release_dll"
|
||||||
# PROP BASE Intermediate_Dir "Release_dll"
|
# PROP BASE Intermediate_Dir "Release_dll"
|
||||||
# PROP BASE Target_Dir ""
|
# PROP BASE Target_Dir ""
|
||||||
# PROP Use_MFC 0
|
# PROP Use_MFC 0
|
||||||
# PROP Use_Debug_Libraries 0
|
# PROP Use_Debug_Libraries 0
|
||||||
# PROP Output_Dir "Release_dll"
|
# PROP Output_Dir "Release_dll"
|
||||||
# PROP Intermediate_Dir "Release_dll"
|
# PROP Intermediate_Dir "Release_dll"
|
||||||
# PROP Ignore_Export_Lib 0
|
# PROP Ignore_Export_Lib 0
|
||||||
# PROP Target_Dir ""
|
# PROP Target_Dir ""
|
||||||
# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "LIBSSH2_WIN32" /D "_MBCS" /D "_LIB" /YX /FD /c
|
# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "LIBSSH2_WIN32" /D "_MBCS" /D "_LIB" /YX /FD /c
|
||||||
# ADD CPP /nologo /MD /W3 /GX /O2 /I "..\win32" /I "..\include" /D "WIN32" /D "NDEBUG" /D "LIBSSH2_WIN32" /D "_MBCS" /D "_LIB" /YX /FD /c
|
# ADD CPP /nologo /MD /W3 /GX /O2 /I "..\win32" /I "..\include" /D "WIN32" /D "NDEBUG" /D "LIBSSH2_WIN32" /D "_MBCS" /D "_LIB" /YX /FD /c
|
||||||
# SUBTRACT CPP /YX
|
# SUBTRACT CPP /YX
|
||||||
# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32
|
# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32
|
||||||
# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32
|
# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32
|
||||||
# ADD BASE RSC /l 0x409 /d "NDEBUG"
|
# ADD BASE RSC /l 0x409 /d "NDEBUG"
|
||||||
# ADD RSC /l 0x409 /d "NDEBUG"
|
# ADD RSC /l 0x409 /d "NDEBUG"
|
||||||
BSC32=bscmake.exe
|
BSC32=bscmake.exe
|
||||||
# ADD BASE BSC32 /nologo
|
# ADD BASE BSC32 /nologo
|
||||||
# ADD BSC32 /nologo
|
# ADD BSC32 /nologo
|
||||||
LINK32=link.exe
|
LINK32=link.exe
|
||||||
# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /machine:I386
|
# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /machine:I386
|
||||||
# ADD LINK32 kernel32.lib ws2_32.lib libeay32.lib ssleay32.lib zlib.lib /nologo /dll /map /debug /machine:I386 /out:"Release_dll/libssh2.dll"
|
# ADD LINK32 kernel32.lib ws2_32.lib libeay32.lib ssleay32.lib zlib.lib /nologo /dll /map /debug /machine:I386 /out:"Release_dll/libssh2.dll"
|
||||||
|
|
||||||
!ELSEIF "$(CFG)" == "libssh2 - Win32 DLL Debug"
|
!ELSEIF "$(CFG)" == "libssh2 - Win32 DLL Debug"
|
||||||
|
|
||||||
# PROP BASE Use_MFC 0
|
# PROP BASE Use_MFC 0
|
||||||
# PROP BASE Use_Debug_Libraries 1
|
# PROP BASE Use_Debug_Libraries 1
|
||||||
# PROP BASE Output_Dir "Debug_dll"
|
# PROP BASE Output_Dir "Debug_dll"
|
||||||
# PROP BASE Intermediate_Dir "Debug_dll"
|
# PROP BASE Intermediate_Dir "Debug_dll"
|
||||||
# PROP BASE Target_Dir ""
|
# PROP BASE Target_Dir ""
|
||||||
# PROP Use_MFC 0
|
# PROP Use_MFC 0
|
||||||
# PROP Use_Debug_Libraries 1
|
# PROP Use_Debug_Libraries 1
|
||||||
# PROP Output_Dir "Debug_dll"
|
# PROP Output_Dir "Debug_dll"
|
||||||
# PROP Intermediate_Dir "Debug_dll"
|
# PROP Intermediate_Dir "Debug_dll"
|
||||||
# PROP Ignore_Export_Lib 0
|
# PROP Ignore_Export_Lib 0
|
||||||
# PROP Target_Dir ""
|
# PROP Target_Dir ""
|
||||||
# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "LIBSSH2_WIN32" /D "_MBCS" /D "_LIB" /YX /FD /GZ /c
|
# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "LIBSSH2_WIN32" /D "_MBCS" /D "_LIB" /YX /FD /GZ /c
|
||||||
# ADD CPP /nologo /MDd /W3 /Gm /GX /ZI /Od /I "..\win32" /I "..\include" /D "WIN32" /D "_DEBUG" /D "LIBSSH2_WIN32" /D "_MBCS" /D "_LIB" /YX /FD /GZ /c
|
# ADD CPP /nologo /MDd /W3 /Gm /GX /ZI /Od /I "..\win32" /I "..\include" /D "WIN32" /D "_DEBUG" /D "LIBSSH2_WIN32" /D "_MBCS" /D "_LIB" /YX /FD /GZ /c
|
||||||
# SUBTRACT CPP /WX /YX
|
# SUBTRACT CPP /WX /YX
|
||||||
# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32
|
# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32
|
||||||
# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32
|
# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32
|
||||||
# ADD BASE RSC /l 0x409 /d "_DEBUG"
|
# ADD BASE RSC /l 0x409 /d "_DEBUG"
|
||||||
# ADD RSC /l 0x409 /d "_DEBUG"
|
# ADD RSC /l 0x409 /d "_DEBUG"
|
||||||
BSC32=bscmake.exe
|
BSC32=bscmake.exe
|
||||||
# ADD BASE BSC32 /nologo
|
# ADD BASE BSC32 /nologo
|
||||||
# ADD BSC32 /nologo
|
# ADD BSC32 /nologo
|
||||||
LINK32=link.exe
|
LINK32=link.exe
|
||||||
# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /debug /machine:I386 /pdbtype:sept
|
# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /debug /machine:I386 /pdbtype:sept
|
||||||
# ADD LINK32 kernel32.lib ws2_32.lib libeay32.lib ssleay32.lib zlib.lib /nologo /dll /incremental:no /map /debug /machine:I386 /out:"Debug_dll/libssh2.dll" /pdbtype:sept
|
# ADD LINK32 kernel32.lib ws2_32.lib libeay32.lib ssleay32.lib zlib.lib /nologo /dll /incremental:no /map /debug /machine:I386 /out:"Debug_dll/libssh2.dll" /pdbtype:sept
|
||||||
# SUBTRACT LINK32 /nodefaultlib
|
# SUBTRACT LINK32 /nodefaultlib
|
||||||
|
|
||||||
!ELSEIF "$(CFG)" == "libssh2 - Win32 LIB Release"
|
!ELSEIF "$(CFG)" == "libssh2 - Win32 LIB Release"
|
||||||
|
|
||||||
# PROP BASE Use_MFC 0
|
# PROP BASE Use_MFC 0
|
||||||
# PROP BASE Use_Debug_Libraries 0
|
# PROP BASE Use_Debug_Libraries 0
|
||||||
# PROP BASE Output_Dir "Release_lib"
|
# PROP BASE Output_Dir "Release_lib"
|
||||||
# PROP BASE Intermediate_Dir "Release_lib"
|
# PROP BASE Intermediate_Dir "Release_lib"
|
||||||
# PROP BASE Target_Dir ""
|
# PROP BASE Target_Dir ""
|
||||||
# PROP Use_MFC 0
|
# PROP Use_MFC 0
|
||||||
# PROP Use_Debug_Libraries 0
|
# PROP Use_Debug_Libraries 0
|
||||||
# PROP Output_Dir "Release_lib"
|
# PROP Output_Dir "Release_lib"
|
||||||
# PROP Intermediate_Dir "Release_lib"
|
# PROP Intermediate_Dir "Release_lib"
|
||||||
# PROP Target_Dir ""
|
# PROP Target_Dir ""
|
||||||
# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "LIBSSH2_WIN32" /D "_MBCS" /D "_LIB" /YX /FD /c
|
# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "LIBSSH2_WIN32" /D "_MBCS" /D "_LIB" /YX /FD /c
|
||||||
# ADD CPP /nologo /MD /W3 /GX /O2 /I "..\win32" /I "..\include" /D "WIN32" /D "NDEBUG" /D "LIBSSH2_WIN32" /D "_MBCS" /D "_LIB" /YX /FD /c
|
# ADD CPP /nologo /MD /W3 /GX /O2 /I "..\win32" /I "..\include" /D "WIN32" /D "NDEBUG" /D "LIBSSH2_WIN32" /D "_MBCS" /D "_LIB" /YX /FD /c
|
||||||
# ADD BASE RSC /l 0x409 /d "NDEBUG"
|
# ADD BASE RSC /l 0x409 /d "NDEBUG"
|
||||||
# ADD RSC /l 0x409 /d "NDEBUG"
|
# ADD RSC /l 0x409 /d "NDEBUG"
|
||||||
BSC32=bscmake.exe
|
BSC32=bscmake.exe
|
||||||
# ADD BASE BSC32 /nologo
|
# ADD BASE BSC32 /nologo
|
||||||
# ADD BSC32 /nologo
|
# ADD BSC32 /nologo
|
||||||
LIB32=link.exe -lib
|
LIB32=link.exe -lib
|
||||||
# ADD BASE LIB32 /nologo
|
# ADD BASE LIB32 /nologo
|
||||||
# ADD LIB32 /nologo
|
# ADD LIB32 /nologo
|
||||||
# ADD LIB32 /nologo /out:"Release_lib\libssh.lib"
|
# ADD LIB32 /nologo /out:"Release_lib\libssh.lib"
|
||||||
|
|
||||||
!ELSEIF "$(CFG)" == "libssh2 - Win32 LIB Debug"
|
!ELSEIF "$(CFG)" == "libssh2 - Win32 LIB Debug"
|
||||||
|
|
||||||
# PROP BASE Use_MFC 0
|
# PROP BASE Use_MFC 0
|
||||||
# PROP BASE Use_Debug_Libraries 1
|
# PROP BASE Use_Debug_Libraries 1
|
||||||
# PROP BASE Output_Dir "Debug_lib"
|
# PROP BASE Output_Dir "Debug_lib"
|
||||||
# PROP BASE Intermediate_Dir "Debug_lib"
|
# PROP BASE Intermediate_Dir "Debug_lib"
|
||||||
# PROP BASE Target_Dir ""
|
# PROP BASE Target_Dir ""
|
||||||
# PROP Use_MFC 0
|
# PROP Use_MFC 0
|
||||||
# PROP Use_Debug_Libraries 1
|
# PROP Use_Debug_Libraries 1
|
||||||
# PROP Output_Dir "Debug_lib"
|
# PROP Output_Dir "Debug_lib"
|
||||||
# PROP Intermediate_Dir "Debug_lib"
|
# PROP Intermediate_Dir "Debug_lib"
|
||||||
# PROP Target_Dir ""
|
# PROP Target_Dir ""
|
||||||
# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "LIBSSH2_WIN32" /D "_MBCS" /D "_LIB" /YX /FD /GZ /c
|
# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "LIBSSH2_WIN32" /D "_MBCS" /D "_LIB" /YX /FD /GZ /c
|
||||||
# ADD CPP /nologo /MDd /W3 /Gm /GX /ZI /Od /I "..\win32" /I "..\include" /D "WIN32" /D "_DEBUG" /D "LIBSSH2_WIN32" /D "_MBCS" /D "_LIB" /YX /FD /GZ /c
|
# ADD CPP /nologo /MDd /W3 /Gm /GX /ZI /Od /I "..\win32" /I "..\include" /D "WIN32" /D "_DEBUG" /D "LIBSSH2_WIN32" /D "_MBCS" /D "_LIB" /YX /FD /GZ /c
|
||||||
# ADD BASE RSC /l 0x409 /d "_DEBUG"
|
# ADD BASE RSC /l 0x409 /d "_DEBUG"
|
||||||
# ADD RSC /l 0x409 /d "_DEBUG"
|
# ADD RSC /l 0x409 /d "_DEBUG"
|
||||||
BSC32=bscmake.exe
|
BSC32=bscmake.exe
|
||||||
# ADD BASE BSC32 /nologo
|
# ADD BASE BSC32 /nologo
|
||||||
# ADD BSC32 /nologo
|
# ADD BSC32 /nologo
|
||||||
LIB32=link.exe -lib
|
LIB32=link.exe -lib
|
||||||
# ADD BASE LIB32 /nologo
|
# ADD BASE LIB32 /nologo
|
||||||
# ADD LIB32 /nologo /out:"Debug_lib\libssh2d.lib"
|
# ADD LIB32 /nologo /out:"Debug_lib\libssh2d.lib"
|
||||||
|
|
||||||
!ENDIF
|
!ENDIF
|
||||||
|
|
||||||
# Begin Target
|
# Begin Target
|
||||||
|
|
||||||
# Name "libssh2 - Win32 DLL Release"
|
# Name "libssh2 - Win32 DLL Release"
|
||||||
# Name "libssh2 - Win32 DLL Debug"
|
# Name "libssh2 - Win32 DLL Debug"
|
||||||
# Name "libssh2 - Win32 LIB Release"
|
# Name "libssh2 - Win32 LIB Release"
|
||||||
# Name "libssh2 - Win32 LIB Debug"
|
# Name "libssh2 - Win32 LIB Debug"
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user