Compare commits

..

96 Commits

Author SHA1 Message Date
Daniel Stenberg
291ac7d433 Version 1.2 (August 10, 2009) 2009-08-10 20:07:17 +02:00
Daniel Stenberg
cccaa868f5 revert parts of the b95fe985af commit
Alexander Lamaison tracked down that my previous commit broke SFTP
reads in some aspects. The reversion now gets back to always recv()
until EAGAIN is returned so that the code no longer treats a short
read as an indication that it is "enough for now".

The bad commit in particular had another independent change included,
which is to clear the direction-bits first in the transport read
and write functions, but this reversion does not revert that change.
Clearing those bits first is a good thing.
2009-08-07 11:33:59 +02:00
Daniel Stenberg
08b0183d8e Fix some nroff formatting
Patch by Sofian Brabez
2009-08-06 15:56:27 +02:00
Alexander Lamaison
231a97a95f Replaced calls to OpenSSL FILE-pointer functions.
Passing a FILE* argument across a DLL boundary causes problems on Windows.  Instead the keys are read into memory by libssh2 and passed to the OpenSSL functions as BIO* arguments.
2009-08-02 23:20:20 +01:00
Daniel Stenberg
6c46bb4719 Add missing names
I went over the NEWS and git log outputs and added all mentioned
contributors through the project's history. I want us to make an
effort to give credit to everyone who contributes, big or small.
2009-07-31 16:07:33 +02:00
Daniel Stenberg
8a0ba6f5f6 fix the C99 variadic macro use for _libssh2_debug()
George Neill pointed out that the C99 vararg marcro use was
wrong, and I edited his suggested patch slightly and unified
both prec99-GCC and C99 into the same macro.
2009-07-29 22:03:40 +02:00
Daniel Stenberg
143720e922 Include RELEASE-NOTES in the release package 2009-07-29 14:38:06 +02:00
Daniel Stenberg
0cad4c08e9 Release notes for the pending release
I hope to maintain this file during development so that we also add
changes and bugfixes to it when we change things. Makes the daily
snapshots better and makes less of a hurdle when the release day
comes.
2009-07-29 14:35:42 +02:00
Daniel Stenberg
dd38d0a929 bad debugdump() causes SIGSEGV, partial sends not done right
The anonymous bug report #2822910 pointed out that debugdump() was
stupidly called within the send_existing() function. At closer
inspection was the report not only right, but it also revealed
another problem to me: when the _libssh2_send() function returns
after sending only a part of the buffer, it would then misbehave.
This probably is very rare though, which must be the reason we
haven't seen a bigger problem with this.
2009-07-28 19:57:02 +02:00
Simon Josefsson
ba57d5ae3c Silcen compiler warnings. 2009-07-28 13:27:43 +02:00
Daniel Stenberg
5ac67d1268 added two new issues to fix: socket type and better windowing
* make sure the windowing code adapts better to slow situations so that it
  doesn't then use as much memory as today

* Introduce a 'libssh2_socket_t' type for sockets in internal code
2009-07-27 23:58:06 +02:00
Daniel Stenberg
6f4463e81f remove superfluous check for large packets
as we're already doing the correct check further down anyway there's no point
in doing the (wrong) check further up as well. Paul Veldkamp pointed this out.
2009-07-27 22:54:18 +02:00
Simon Josefsson
690c3d42db Fix make distcheck problems. 2009-07-22 23:34:31 +02:00
Daniel Stenberg
2b780fa02d parts of the previous VS project files commit 2009-07-18 00:35:38 +02:00
Daniel Stenberg
b363c84366 From: Neil Gierman <ngierman@roadrunn.com>
Makefile changes to generate MSVS project files

- I integrated the libssh2_lib.dsp and libssh2_dll.dsp into a single
libssh2.dsp with different targets for lib vs dll
- Since I run Visual Studio 2008 with VC++9 I did not do vcproj files since
I would have newer vc8proj.head|foot than what others will be running
- My patch only has changes to Makefile.am's. I noticed that Makefile.in's
are included in the daily snapshots but they should be generated from the
.am's
- The 3 new files are msvcproj.head and msvcproj.foot for the beginning and
ending of the dsp file, and a new Makefile.inc that will have the source and
header file names. NOTE: All new source files will need to be added to
Makefile.inc and NOT Makefile.am now.
- I moved the win32 dir before the include dir
- I modified the dsw file so it points to the new libssh2.dsp project file
2009-07-18 00:23:25 +02:00
Daniel Stenberg
35a9d4bc62 From: Alexander Lamaison <swish@lammy.co.uk>
Make the public headers includable on their own
2009-07-17 23:40:32 +02:00
Daniel Stenberg
686db51284 From: Steven Van Ingelgem <steven@vaningelgem.be>
check first for libtoolize, and then for glibtoolize

Mac OS X (and others?) needs this
2009-07-17 23:38:41 +02:00
Daniel Stenberg
2361f50e9a Fix knownhost checking of non-hashed hosts
From: Ben Kibbey <bjk@luxsci.net>
2009-07-12 07:05:00 +02:00
Daniel Stenberg
e5d76b5468 Fix the functionality again with hashed host names again.
The breakage came with commit 8b46528c04.
2009-07-12 00:03:37 +02:00
Peter Stuge
7eead1461b Update mailing list URL to new address 2009-07-10 20:11:29 +02:00
Daniel Stenberg
c0d032a45c const'ify two arguments to libssh2_knownhost_check() 2009-07-10 00:54:59 +02:00
Daniel Stenberg
0751067c2f Fix compiler warnings appearing with VS2008. Based on Steven Van Ingelgem's
patch in #2787839 with a bunch of additional edits by yours truly.
2009-07-07 13:44:17 +02:00
Daniel Stenberg
acbdbb8914 Applied Francois Dupoux's extra checks for weird packet or padding length in
incoming packets. We really need to bail out this way on weird input.
bug report #2814613
2009-07-07 13:26:42 +02:00
Daniel Stenberg
bea1beb4fd Mark McPherson posted bug report #2815836 pointing out that the custom memory
functions were not given the correct data as argument. This is now fixed even
if I personally don't quite grasp why abstract is passed as a pointer to
pointer all over libssh2...
2009-07-07 13:09:11 +02:00
Daniel Stenberg
5b599fbf40 Ben Kibbey added a type parameter to the libssh2_session_hostkey() function,
which hasn't yet been in a public release so changing the API is fine!
2009-07-07 00:25:17 +02:00
Daniel Stenberg
75bec57c94 Guenter Knauf fixed this example to build on win32 2009-07-02 11:46:51 +02:00
Daniel Stenberg
b9b5e5fea5 corrected (again) 2009-07-02 11:44:54 +02:00
Daniel Stenberg
91bca481b5 clarify 2009-07-02 00:11:33 +02:00
Daniel Stenberg
9a6ce012cc Neil Gierman pointed out in bug report #2809163 that these two files cannot
include the public libssh2.h header as it breaks the compile on window. I'll
adapt to this now, but in the long run I think we should rather fix the
includes so that we _can_ include the public headers properly.
2009-06-26 20:43:56 +02:00
Daniel Stenberg
a4c3f0d0a3 fixed the length check in knownhost_writeline() since <= is actually good
enough when the size includes the trailing zero
2009-06-14 14:29:15 +02:00
Daniel Stenberg
320450201a After a mention from Ben Kibbey we now let knownhost_writeline() return the
length of the actual data it returns, excluding the trailing zero. I also
updated the man page for libssh2_knownhost_writeline() accordingly.
2009-06-14 14:27:15 +02:00
Daniel Stenberg
9f5c1caa81 empty line removed 2009-06-14 14:26:27 +02:00
Daniel Stenberg
8b46528c04 Ben Kibbey fixed the hostline() when parsing lines using only one hostname 2009-06-10 20:46:11 +02:00
Daniel Stenberg
aeaf07576e Merge branch 'master' of ssh://bagder@git.stuge.se/var/lib/git/libssh2 2009-06-09 00:00:26 +02:00
Daniel Stenberg
c01e147a40 Provide a libssh2_scp_send() API for files larger than 4GB (32bit size) 2009-06-08 16:10:37 +02:00
Daniel Stenberg
32080def94 Olivier Hervieu provided this x11 forwarding example. This is the version
after my initial cleanup that I posted to the list on May 26th 2009. It still
has a few ugly spots that should be cleaned up, but until then it's will at
least be found in the repo. For this reason I don't add this to the makefile.
2009-06-05 09:04:24 +02:00
Daniel Stenberg
da1230b35b New man page for libssh2_session_hostkey(3). We probably need to improve this
to also return the type of the key.
2009-06-05 09:02:56 +02:00
Daniel Stenberg
d440995a80 Add check for and use of the _REENTRANT define for Solaris so that libssh2
is then properly thread-safe on that OS. These autuconf macros are straight
from the cURL project and were mostly written by Yang Tse. They were only
very slightly edited by me when imported to here.
2009-06-04 20:23:23 +02:00
Tor Arntsen
2a142a6524 Ignore generated files 2009-06-04 18:20:29 +02:00
Daniel Stenberg
afcf63b433 use the correct #if condition for strtoll(), pointed out in bug report 2009-06-04 00:36:34 +02:00
Daniel Stenberg
bc4c258842 define the HAVE_LIBSSH2_KNOWNHOST_API to the version number 1.1.1 to make apps
know that when this define exists, the API exists. And the version number can
be used for run-time checks. 1.1.1 is not likely to be the release version as
I think we'll go with 1.2 instead but 1.1.1 OR LATER should still work.
2009-05-29 23:04:52 +02:00
Daniel Stenberg
e52a1057fd libssh2_knownhost_add() got an additional argument: 'store' so that an
application can get a pointer back to the internal representation of the host
it just added. Useful for example when the app wants to add a host, and then
convert that exact same host to a line for storing in a known host file.
'store' can also be set to NULL to simple not care.
2009-05-29 18:40:29 +02:00
Daniel Stenberg
517909d37a Added a call to libssh2_knownhost_writefile()
Updated to the slightly modified libssh2_knownhost_check() proto
2009-05-29 14:10:54 +02:00
Daniel Stenberg
8cd76af353 "struct libssh2_knownhost" is now part of the internal struct for each known
host so we now only return pointers to structs instead of having the app
allocate a full struct

I moved the private struct definition into knownhosts.c instead of exposing it
wider in libssh2_priv.h

I thus modified the proto for two functions that previously used 'struct
libssh2_knownhost *' to receive data.
2009-05-29 14:08:24 +02:00
Daniel Stenberg
1d31dadc1e when a host is added, we must make sure the app also provides a key *type* even
though we don't use the type in this function
2009-05-29 13:58:04 +02:00
Daniel Stenberg
2e990194ab Added man pages for the two newest members of the knownhosts API family:
libssh2_knownhost_readline() and libssh2_knownhost_writeline()
2009-05-29 10:12:22 +02:00
Daniel Stenberg
1afbbf4507 introducing libssh2_knownhost_writeline() and some cleanups to use more
defined error codes instead of the simplified -1 previously used a little too
much here
2009-05-29 10:00:45 +02:00
Daniel Stenberg
82bdd12a8b I think *readline() makes a better name 2009-05-29 00:19:02 +02:00
Daniel Stenberg
4df48aef41 clarify that the key "string" needs to be zero terminated too 2009-05-29 00:14:41 +02:00
Daniel Stenberg
bc28d0146d introducing libssh2_knownhost_read() that makes libssh2 read a single given
line
const'ified a few args to libssh2_knownhost_add() as well
2009-05-29 00:08:00 +02:00
Daniel Stenberg
8b1ec197b2 fix a warning for a comparison mixing signed and unsigned types 2009-05-28 22:54:37 +02:00
Daniel Stenberg
2436a4de60 After review/feedback/discussions on the mailing list. Rename two functions:
s/libssh2_knownhost_parsefile/libssh2_knownhost_readfile
s/libssh2_knownhost_dumpfile/libssh2_knownhost_writefile
2009-05-28 19:57:54 +02:00
Daniel Stenberg
22014f074b define removed 2009-05-28 16:12:24 +02:00
Daniel Stenberg
f35dbff3c4 LIBSSH2_KNOWNHOST_TYPE_DEFAULT is not a good idea, scrap it 2009-05-28 14:36:16 +02:00
Daniel Stenberg
703fbd9d11 Added the initial man pages for the 7 new functions for known host handling 2009-05-28 14:35:13 +02:00
Daniel Stenberg
5207690edf first shot at implementing libssh2_knownhost_dumpfile() and some minor
cleanups
2009-05-28 13:14:32 +02:00
Daniel Stenberg
eaa95e0331 introducing libssh2_knownhost_get() to the public API 2009-05-27 16:00:52 +02:00
Daniel Stenberg
d965dda027 clarified a comment 2009-05-26 11:18:29 +02:00
Daniel Stenberg
bf884488ae slighty better behavior and comments 2009-05-26 11:18:00 +02:00
Daniel Stenberg
28b08e0b4d remove include since we don't use struct iovec in this file 2009-05-26 11:14:07 +02:00
Daniel Stenberg
1ffa2cb519 These examples no longer need to explictly set the socket to non-blocking state
as libssh2 itself will always do that by itself.
2009-05-26 09:41:13 +02:00
Daniel Stenberg
279d6dd82a add myself as copyright owner 2009-05-25 11:35:06 +02:00
Daniel Stenberg
49192598d2 mention conversion of code to the new linked list code 2009-05-25 11:29:39 +02:00
Daniel Stenberg
6b7c19ec26 remove #if 0'ed code 2009-05-25 11:23:06 +02:00
Daniel Stenberg
160e5aa763 clarify the fix, as it wasn't a leak 2009-05-25 11:03:24 +02:00
Daniel Stenberg
42e9f02025 spell fix a comment 2009-05-25 10:58:13 +02:00
Daniel Stenberg
5a162ad9f8 Added some clarifying comments on how the 'sftpInit_sftp' and
'sftpInit_channel' struct fields within the session struct are used. And made
sure to clear them both correctly when sftp_init() returns instead of at
shutdown time, as it must not touch them at shutdown time. This should make it
possible to properly make more than one SFTP handle.
2009-05-25 10:50:49 +02:00
Daniel Stenberg
6ff83eab1b no need for LIBSSH2_ERROR_MEMORY when LIBSSH2_ERROR_ALLOC already exist!
added my own copyright line too now
2009-05-25 10:41:07 +02:00
Daniel Stenberg
8df3222d91 use LIBSSH2_ERROR_ALLOC instead of introducing a new error code 2009-05-25 10:40:36 +02:00
Daniel Stenberg
0357ce6c48 clear session->sftpInit_sftp unconditionally 2009-05-24 23:51:59 +02:00
Daniel Stenberg
c5f335ad4f Fix my recent session->sftpInit_sftp fix which wasn't correct. The memory area
does not need to be freed (it already gets freed) but clearing the pointer is
a good idea. And it should be done _after_ the channel_free() call.
2009-05-24 23:44:52 +02:00
Daniel Stenberg
fdc043e7b1 add an assert to help debugging 2009-05-24 23:44:23 +02:00
Daniel Stenberg
fdaa5ad5b4 Without CVS we must not use cvs tools to generate the changelog. I'm not
confident enough with git to attempt to make one so I'll just make a dummy for
now.
2009-05-23 23:03:31 +02:00
Daniel Stenberg
f1f49c3cce - Anonymous bug report #2795816 revealed that libssh2_sftp_shutdown() did not
properly free/cleanup the SFTP handle so libssh2 leaked memory and caused
   an assert() on subsequent libssh2_sftp_init() calls on the same session.
2009-05-23 22:30:43 +02:00
Daniel Stenberg
ad13de92d4 Fix _libssh2_channel_write(): fixed the write loop to also read from the
transport layer better, to avoid draining the window size when sending large
packets. I also fixed the return code for it to return the number of bytes
handled in this single invoke (and not the cumulative amount).
2009-05-20 14:34:30 +02:00
Daniel Stenberg
b755f3eb10 First, only try to send max packet size *4 to channel write, as trying to send
much larger packages only cause internal problems and much larger allocations.

Also fix sftp_write() when _libssh2_channel_write() returns that a packet was
only partially sent as that is not an error.

Fixed a few error messages to more accurately point out the problem
2009-05-20 14:31:46 +02:00
Daniel Stenberg
b95fe985af If recv() returns something less than the full buffer we know we're done for
now, so skip looping and doing another read that then simply will cause an
EAGAIN as it may trick the user into believing things that aren't true.
2009-05-20 14:30:05 +02:00
daniel
035cb24fa0 remove the old style as it makes little sense to mention here anymore 2009-05-14 17:01:54 +02:00
Daniel Stenberg
18e03739be typo 2009-05-12 10:10:55 +00:00
Daniel Stenberg
e367e1ad4e comment typo and some indent fixes 2009-05-12 10:07:30 +00:00
Daniel Stenberg
f7149d1830 Partial fix based on the patch and discussions in #2788319 2009-05-12 09:33:22 +00:00
Daniel Stenberg
042b545247 clear the passed in struct when the entry has been removed to help prevent
mistakes due to re-use
2009-05-12 09:32:51 +00:00
Daniel Stenberg
4490c6b434 use a better example file name for the known_hosts file 2009-05-07 20:30:22 +00:00
Daniel Stenberg
d3542e6f7d split out the knownhost code from hostkey.c into its own separate source file
now: knownhost.c
2009-05-07 17:21:56 +00:00
Daniel Stenberg
0cee15dc0c this was never supposed to be added for real 2009-05-07 17:21:14 +00:00
Daniel Stenberg
4b991b232d My knownhost work as of right now. It works at least partly. More tests and
tweaks will come.
2009-05-07 13:09:48 +00:00
Daniel Stenberg
4bc1b8a1d7 get host, user, password and command from the command line 2009-05-05 12:30:19 +00:00
Daniel Stenberg
755e213ae6 Added ssh2_exec as a new example, showing how to run a command remotely with
libssh2
2009-05-05 12:27:02 +00:00
Daniel Stenberg
9412588373 bug #2785173 pointed out that we really must call _libssh2_transport_read()
in loops until it returns < 0 when we call it, as if we just call it once we
may drain the socket for data and then leave unused in-memory data that we
won't detect because the socket is back to idle...
2009-05-01 19:07:20 +00:00
Daniel Stenberg
9f104cd883 Markus posted a bug report about a bad 0-return from libssh2_channel_read:
http://libssh2.haxx.se/mail/libssh2-devel-archive-2009-04/0076.shtml

  And it was indeed a bad loop that terminated too early due to a receveived
  close packet.
2009-04-30 10:30:26 +00:00
Daniel Stenberg
6409bb53ba remove pointless sleeps 2009-04-28 10:35:30 +00:00
Daniel Stenberg
c306119dd6 edited 2009-04-14 21:43:39 +00:00
Daniel Stenberg
2b8038e175 libssh2_poll() and libssh2_poll_channel_read() are now considered and
documented deprecated and they will be removed at next soname bump. It also
  saves us from fixing some rather quirky bugs in libssh2_poll()...
2009-04-14 21:38:36 +00:00
Guenter Knauf
2a39b32b1a some minor Makefile tweaks; mainly for crosscompiling. 2009-04-09 03:13:51 +00:00
Daniel Stenberg
e63cbd907f Jussi Mononen pointed out we used an unsigned variable to store negative
values in, when a plain int is much better anyway since it matches the return
type.
2009-04-06 14:50:29 +00:00
Daniel Stenberg
cb66b7b94f and we're now on the 1.1.1 track 2009-04-02 09:35:02 +00:00
73 changed files with 3389 additions and 858 deletions

32
.gitignore vendored Normal file
View File

@@ -0,0 +1,32 @@
.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
*.o
*.lo
*.la
mkinstalldirs

51
AUTHORS
View File

@@ -1,15 +1,40 @@
* Sara Golemon: Author / Project Manager libssh2 is the result of many friendly people. This list is an attempt to
mention all contributors. If we've missed anyone, tell us!
* Daniel Stenberg: Co-maintainer This list of names is a-z sorted.
* James Housleys: Nonblocking conversion Adam Gobiowski
Alexander Holyapin
* Simon Josefsson: libgcrypt support Alexander Lamaison
Bjorn Stenborg
* Mikhail Gusarov: Keyboard Interactive Authentication Carlo Bramini
Dan Casey
* Wez Furlong & Edink Kadribasic: Windows Port Dan Fandrich
Daniel Stenberg
* Dan Fandrich: bug fixes, cleanups David J Sullivan
David Robins
* Guenter Knauf: win32 work and more Edink Kadribasic
Erik Brossler
Guenter Knauf
Heiner Steven
James Housleys
Jean-Louis Charton
Markus Moeller
Mike Protts
Mikhail Gusarov
Neil Gierman
Olivier Hervieu
Peter O'Gorman
Peter Stuge
Romain Bondue
Sara Golemon
Satish Mittal
Sean Peterson
Selcuk Gueney
Simon Hart
Simon Josefsson
Steven Ayre
Vincent Jaulin
Vlad Grachov
Wez Furlong
Yang Tse

View File

@@ -1,5 +1,6 @@
/* 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
* All rights reserved. * All rights reserved.
* *
* Redistribution and use in source and binary forms, * Redistribution and use in source and binary forms,

10
HACKING
View File

@@ -20,13 +20,3 @@ libssh2 source code style guide:
- use braces even for single-statement blocks - use braces even for single-statement blocks
- keep source lines shorter than 80 columns - keep source lines shorter than 80 columns
------------
Older libssh2 code that still hasn't quite transitioned to the above
mentioned style, used a different style:
- indented with tabs (only)
- no line length limits

View File

@@ -1,3 +1,5 @@
AUTOMAKE_OPTIONS = foreign nostdinc
SUBDIRS = src example tests docs SUBDIRS = src example tests docs
include_HEADERS = \ include_HEADERS = \
@@ -11,20 +13,26 @@ NETWAREFILES = nw/keepscreen.c \
nw/nwlib.c \ nw/nwlib.c \
nw/test/Makefile.netware nw/test/Makefile.netware
WIN32FILES = win32/libssh2_dll.dsp win32/libssh2.dsw win32/Makefile.win32 \ DSP = win32/libssh2.dsp
win32/config.mk win32/Makefile win32/test/Makefile.win32 win32/libssh2_lib.dsp \ VCPROJ = win32/libssh2.vcproj
win32/libssh2_config.h win32/tests.dsp win32/rules.mk
#Need to include $(VCPROJ) to CLEANFILES and WIN32FILES when I get a proper vc8proj.head|foot
CLEANFILES = $(DSP)
WIN32FILES = win32/Makefile.win32 win32/libssh2.dsw \
win32/config.mk win32/Makefile win32/test/Makefile.win32 \
win32/libssh2_config.h win32/tests.dsp win32/rules.mk $(DSP) \
win32/msvcproj.head win32/msvcproj.foot
EXTRA_DIST = $(WIN32FILES) buildconf $(NETWAREFILES) get_ver.awk HACKING \ EXTRA_DIST = $(WIN32FILES) buildconf $(NETWAREFILES) get_ver.awk HACKING \
maketgz NMakefile TODO maketgz NMakefile TODO RELEASE-NOTES
ACLOCAL_AMFLAGS = -I m4 ACLOCAL_AMFLAGS = -I m4
.PHONY: ChangeLog .PHONY: ChangeLog
ChangeLog: ChangeLog:
if test -f .cvsusers; then \ echo "see NEWS" > ./ChangeLog
cvs2cl --utc --fsf --FSF --usermap .cvsusers -I ChangeLog -I .cvs; \ CLEANFILES += ChangeLog
fi
dist-hook: dist-hook:
rm -rf $(top_builddir)/tests/log rm -rf $(top_builddir)/tests/log
@@ -57,3 +65,63 @@ gen-coverage:
--title "$(PACKAGE_NAME)" --title "$(PACKAGE_NAME)"
coverage: init-coverage build-coverage gen-coverage coverage: init-coverage build-coverage gen-coverage
# DSP/VCPROJ generation adapted from libcurl
# Makefile.inc provides the CSOURCES and HHEADERS defines
include Makefile.inc
WIN32SOURCES = $(CSOURCES)
WIN32HEADERS = $(HHEADERS) libssh2_config.h
DSPOUT = | awk '{printf("%s\r\n", $$0)}' >> $(DSP)
VCPROJOUT = | awk '{printf("%s\r\n", $$0)}' >> $(VCPROJ)
$(DSP): win32/msvcproj.head win32/msvcproj.foot Makefile.am
echo "creating $(DSP)"
@(cp $(srcdir)/win32/msvcproj.head $(DSP); \
echo "# Begin Group \"Source Files\"" $(DSPOUT); \
echo "" $(DSPOUT); \
echo "# PROP Default_Filter \"cpp;c;cxx\"" $(DSPOUT); \
win32_srcs='$(WIN32SOURCES)'; \
sorted_srcs=`for file in $$win32_srcs; do echo $$file; done | sort`; \
for file in $$sorted_srcs; do \
echo "# Begin Source File" $(DSPOUT); \
echo "" $(DSPOUT); \
echo "SOURCE=..\\src\\"$$file $(DSPOUT); \
echo "# End Source File" $(DSPOUT); \
done; \
echo "# End Group" $(DSPOUT); \
echo "# Begin Group \"Header Files\"" $(DSPOUT); \
echo "" $(DSPOUT); \
echo "# PROP Default_Filter \"h;hpp;hxx\"" $(DSPOUT); \
win32_hdrs='$(WIN32HEADERS)'; \
sorted_hdrs=`for file in $$win32_hdrs; do echo $$file; done | sort`; \
for file in $$sorted_hdrs; do \
echo "# Begin Source File" $(DSPOUT); \
echo "" $(DSPOUT); \
if [ "$$file" == "libssh2_config.h" ]; \
then \
echo "SOURCE=.\\"$$file $(DSPOUT); \
else \
echo "SOURCE=..\\src\\"$$file $(DSPOUT); \
fi; \
echo "# End Source File" $(DSPOUT); \
done; \
echo "# End Group" $(DSPOUT); \
cat $(srcdir)/win32/msvcproj.foot $(DSPOUT) )
$(VCPROJ): win32/vc8proj.head win32/vc8proj.foot Makefile.am
echo "creating $(VCPROJ)"
@(cp $(srcdir)/vc8proj.head $(VCPROJ); \
win32_srcs='$(WIN32SOURCES)'; \
sorted_srcs=`for file in $$win32_srcs; do echo $$file; done | sort`; \
for file in $$sorted_srcs; do \
echo "<File RelativePath=\""..\src\$$file"\"></File>" $(VCPROJOUT); \
done; \
echo "</Filter><Filter Name=\"Header Files\">" $(VCPROJOUT); \
win32_hdrs='$(WIN32HEADERS)'; \
sorted_hdrs=`for file in $$win32_hdrs; do echo $$file; done | sort`; \
for file in $$sorted_hdrs; do \
echo "<File RelativePath=\""..\src\$$file"\"></File>" $(VCPROJOUT); \
done; \
cat $(srcdir)/vc8proj.foot $(VCPROJOUT) )

11
Makefile.inc Normal file
View File

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

74
NEWS
View File

@@ -1,3 +1,77 @@
Version 1.2 (August 10, 2009)
-----------------------------
* (August 02 2009) Alexander Lamaison:
- changed _libssh2_rsa_new_private and _libssh2_rsa_new_private so that they
no longer use the OpenSSL functions that take a FILE* argument. Passing
CRT-created objects across a DLL boundary causes crashes on Windows of the
DLL and the client aren't linked to the exact same verison of the CRT. Now
we pass the keys as strings to avoid this issue.
* (May 29 2009) Daniel Stenberg:
- Updated the knownhost API and there are now 9 functions, and all of them
have man pages. The libssh2.h now defines HAVE_LIBSSH2_KNOWNHOST_API to
ease things for applications to check for the correct release before trying
to use it.
* (May 23 2009) Daniel Stenberg:
- Anonymous bug report #2795816 revealed that doing subsequent
libssh2_sftp_init() calls on the same session failed.
* (May 20 2009) Daniel Stenberg:
- made libssh2_sftp_write() properly deal with huge/any sized input buffers.
- fixed libssh2_channel_write_ex() to return the correct return code, and
deal with sending off huge buffers better
* (May 7 2009) Daniel Stenberg:
- linked list code. I got a bit tired of the fact that we don't have any
generic linked-list functions within libssh2 so I wrote up the first embryo
for one that I use for this new functionality. The plan would then be to
move all existing code that uses linked lists to use this new set.
- base64 encode. I had to add a base64 encoding function which was missing
in the code base so it helps to "bloat" my patch.
- The knownhost API is currently:
_init() - init a bundle of known hosts
_add() - add a known host
_del() - delete a known host
_free() - free an entire bundle of known hosts
_check() - check if a host+key is present in the bundle
The convenience function:
_parsefile() - reads a ~/.ssh/known_hosts file and add all entries to the
given bundle
- there's no docs other than some comments in the code/headers yet
- the patch includes changes to example/simple/ssh2_exec.c that makes use of
a few of these functions. Using that I've verified that the functions in
fact can verify my localhost's key agains my ~/.ssh/known_hosts file
* (Apr 30 2009) Daniel Stenberg:
Markus posted a bug report about a bad 0-return from libssh2_channel_read:
http://libssh2.haxx.se/mail/libssh2-devel-archive-2009-04/0076.shtml
And it was indeed a bad loop that terminated too early due to a receveived
close packet.
* (Apr 14 2009) Daniel Stenberg:
libssh2_poll() and libssh2_poll_channel_read() are now considered and
documented deprecated and they will be removed at next soname bump. It also
saves us from fixing some rather quirky bugs in libssh2_poll()...
Version 1.1 (April 2, 2009) Version 1.1 (April 2, 2009)
--------------------------- ---------------------------

2
README
View File

@@ -6,7 +6,7 @@ the revised BSD license.
Web site: http://www.libssh2.org/ Web site: http://www.libssh2.org/
Mailing list: https://lists.sourceforge.net/lists/listinfo/libssh2-devel Mailing list: http://cool.haxx.se/mailman/listinfo/libssh2-devel
Generic installation instructions are in INSTALL. Some ./configure Generic installation instructions are in INSTALL. Some ./configure
options deserve additional comments: options deserve additional comments:

40
RELEASE-NOTES Normal file
View File

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

35
TODO
View File

@@ -1,19 +1,17 @@
Things TODO Things TODO
=========== ===========
* Add one of the missing man pages: * make sure the windowing code adapts better to slow situations so that it
doesn't then use as much memory as today
libssh2_channel_receive_window_adjust * Introduce a 'libssh2_socket_t' type for sockets in internal code
libssh2_channel_request_pty_size_ex
libssh2_channel_window_read_ex * Provide a libssh2_scp_send() API for files larger than 4GB (32bit size)
libssh2_channel_window_write_ex
libssh2_publickey_add_ex * Convert the linked list code used all over to use the (new) generic linked
libssh2_publickey_init list code. See the _libssh2_list_*() functions in src/misc.c
libssh2_publickey_list_fetch
libssh2_publickey_list_free * Add more info to the man pages.
libssh2_publickey_remove_ex
libssh2_publickey_shutdown
libssh2_userauth_hostbased_fromfile_ex
* Decrease the number of mallocs. Everywhere. * Decrease the number of mallocs. Everywhere.
@@ -21,8 +19,7 @@ Things TODO
* Extend the test suite to actually test lots of aspects of libssh2 * Extend the test suite to actually test lots of aspects of libssh2
* libssh2_channel_receive_window_adjust() can return EAGAIN while documented * Fix all compiler warnings (some can't be done without API changes)
to return the window as an "unsigned long".
At next SONAME bump At next SONAME bump
=================== ===================
@@ -30,9 +27,19 @@ At next SONAME bump
* stop using #defined macros as part of the official API. The macros should * stop using #defined macros as part of the official API. The macros should
either be turned into real functions or discarded from the API. either be turned into real functions or discarded from the API.
* fix the parts of the API where object pointers and function pointers are
mixed like libssh2_session_callback_set()
* remove the following functions from the API/ABI * remove the following functions from the API/ABI
libssh2_base64_decode() libssh2_base64_decode()
libssh2_session_flag() libssh2_session_flag()
libssh2_channel_handle_extended_data() libssh2_channel_handle_extended_data()
libssh2_channel_receive_window_adjust() libssh2_channel_receive_window_adjust()
libssh2_poll()
libssh2_poll_channel_read()
* Rename a few function:
libssh2_hostkey_hash => libssh2_session_hostkey_hash
libssh2_banner_set => libssh2_session_banner_set

View File

@@ -288,3 +288,97 @@ dnl end of non-blocking try-compile test
AC_MSG_WARN([non-block sockets disabled]) AC_MSG_WARN([non-block sockets disabled])
fi fi
]) ])
dnl CURL_CHECK_NEED_REENTRANT_SYSTEM
dnl -------------------------------------------------
dnl Checks if the preprocessor _REENTRANT definition
dnl must be unconditionally done for this platform.
dnl Internal macro for CURL_CONFIGURE_REENTRANT.
AC_DEFUN([CURL_CHECK_NEED_REENTRANT_SYSTEM], [
case $host in
*-*-solaris*)
tmp_need_reentrant="yes"
;;
*)
tmp_need_reentrant="no"
;;
esac
])
dnl CURL_CONFIGURE_FROM_NOW_ON_WITH_REENTRANT
dnl -------------------------------------------------
dnl This macro ensures that configuration tests done
dnl after this will execute with preprocessor symbol
dnl _REENTRANT defined. This macro also ensures that
dnl the generated config file defines NEED_REENTRANT
dnl and that in turn setup.h will define _REENTRANT.
dnl Internal macro for CURL_CONFIGURE_REENTRANT.
AC_DEFUN([CURL_CONFIGURE_FROM_NOW_ON_WITH_REENTRANT], [
AC_DEFINE(NEED_REENTRANT, 1,
[Define to 1 if _REENTRANT preprocessor symbol must be defined.])
cat >>confdefs.h <<_EOF
#ifndef _REENTRANT
# define _REENTRANT
#endif
_EOF
])
dnl CURL_CONFIGURE_REENTRANT
dnl -------------------------------------------------
dnl This first checks if the preprocessor _REENTRANT
dnl symbol is already defined. If it isn't currently
dnl defined a set of checks are performed to verify
dnl if its definition is required to make visible to
dnl the compiler a set of *_r functions. Finally, if
dnl _REENTRANT is already defined or needed it takes
dnl care of making adjustments necessary to ensure
dnl that it is defined equally for further configure
dnl tests and generated config file.
AC_DEFUN([CURL_CONFIGURE_REENTRANT], [
AC_PREREQ([2.50])dnl
#
AC_MSG_CHECKING([if _REENTRANT is already defined])
AC_COMPILE_IFELSE([
AC_LANG_PROGRAM([[
]],[[
#ifdef _REENTRANT
int dummy=1;
#else
force compilation error
#endif
]])
],[
AC_MSG_RESULT([yes])
tmp_reentrant_initially_defined="yes"
],[
AC_MSG_RESULT([no])
tmp_reentrant_initially_defined="no"
])
#
if test "$tmp_reentrant_initially_defined" = "no"; then
AC_MSG_CHECKING([if _REENTRANT is actually needed])
CURL_CHECK_NEED_REENTRANT_SYSTEM
if test "$tmp_need_reentrant" = "yes"; then
AC_MSG_RESULT([yes])
else
AC_MSG_RESULT([no])
fi
fi
#
AC_MSG_CHECKING([if _REENTRANT is onwards defined])
if test "$tmp_reentrant_initially_defined" = "yes" ||
test "$tmp_need_reentrant" = "yes"; then
CURL_CONFIGURE_FROM_NOW_ON_WITH_REENTRANT
AC_MSG_RESULT([yes])
else
AC_MSG_RESULT([no])
fi
#
])

View File

@@ -1,6 +1,22 @@
#!/bin/sh #!/bin/sh
${LIBTOOLIZE:-libtoolize} --copy --automake --force LIBTOOLIZE="libtoolize"
if [ "x`which $LIBTOOLIZE`" == "x" ];
then
LIBTOOLIZE="glibtoolize";
fi
if [ "x`which $LIBTOOLIZE`" == "x" ];
then
echo "Neither libtoolize nor glibtoolize could be found!";
exit 1
fi
${LIBTOOLIZE} --copy --automake --force
${ACLOCAL:-aclocal} -I m4 $ACLOCAL_FLAGS ${ACLOCAL:-aclocal} -I m4 $ACLOCAL_FLAGS
${AUTOHEADER:-autoheader} ${AUTOHEADER:-autoheader}
# copy the private libssh2_config.h.in to the examples dir so that # copy the private libssh2_config.h.in to the examples dir so that

View File

@@ -50,6 +50,10 @@ AC_CHECK_TYPE(long long,
[Define to 1 if the compiler supports the 'long long' data type.])] [Define to 1 if the compiler supports the 'long long' data type.])]
longlong="yes" longlong="yes"
) )
dnl Our configure and build reentrant settings
CURL_CONFIGURE_REENTRANT
# Some systems (Solaris?) have socket() in -lsocket. # Some systems (Solaris?) have socket() in -lsocket.
AC_SEARCH_LIBS(socket, socket) AC_SEARCH_LIBS(socket, socket)

View File

@@ -4,6 +4,7 @@ EXTRA_DIST = template.3
dist_man_MANS = \ dist_man_MANS = \
libssh2_banner_set.3 \ libssh2_banner_set.3 \
libssh2_base64_decode.3 \
libssh2_channel_close.3 \ libssh2_channel_close.3 \
libssh2_channel_direct_tcpip_ex.3 \ libssh2_channel_direct_tcpip_ex.3 \
libssh2_channel_eof.3 \ libssh2_channel_eof.3 \
@@ -21,23 +22,47 @@ dist_man_MANS = \
libssh2_channel_receive_window_adjust.3 \ libssh2_channel_receive_window_adjust.3 \
libssh2_channel_receive_window_adjust2.3 \ libssh2_channel_receive_window_adjust2.3 \
libssh2_channel_request_pty_ex.3 \ libssh2_channel_request_pty_ex.3 \
libssh2_channel_request_pty_size_ex.3 \
libssh2_channel_send_eof.3 \ libssh2_channel_send_eof.3 \
libssh2_channel_set_blocking.3 \ libssh2_channel_set_blocking.3 \
libssh2_channel_setenv_ex.3 \ libssh2_channel_setenv_ex.3 \
libssh2_channel_wait_eof.3 \
libssh2_channel_wait_closed.3 \ libssh2_channel_wait_closed.3 \
libssh2_channel_wait_eof.3 \
libssh2_channel_window_read_ex.3 \ libssh2_channel_window_read_ex.3 \
libssh2_channel_window_write_ex.3 \ libssh2_channel_window_write_ex.3 \
libssh2_channel_write_ex.3 \ libssh2_channel_write_ex.3 \
libssh2_channel_x11_req_ex.3 \ libssh2_channel_x11_req_ex.3 \
libssh2_free_host_entry.3 \
libssh2_host_entry_match.3 \
libssh2_hostkey_hash.3 \ libssh2_hostkey_hash.3 \
libssh2_knownhost_add.3 \
libssh2_knownhost_check.3 \
libssh2_knownhost_del.3 \
libssh2_knownhost_get.3 \
libssh2_knownhost_init.3 \
libssh2_knownhost_readfile.3 \
libssh2_knownhost_readline.3 \
libssh2_knownhost_writefile.3 \
libssh2_knownhost_writeline.3 \
libssh2_new_host_entry.3 \
libssh2_poll.3 \
libssh2_poll_channel_read.3 \
libssh2_publickey_add_ex.3 \
libssh2_publickey_init.3 \
libssh2_publickey_list_fetch.3 \
libssh2_publickey_list_free.3 \
libssh2_publickey_remove_ex.3 \
libssh2_publickey_shutdown.3 \
libssh2_scp_recv.3 \ libssh2_scp_recv.3 \
libssh2_scp_send_ex.3 \ libssh2_scp_send_ex.3 \
libssh2_session_abstract.3 \ libssh2_session_abstract.3 \
libssh2_session_block_directions.3 \ libssh2_session_block_directions.3 \
libssh2_session_callback_set.3 \ libssh2_session_callback_set.3 \
libssh2_session_free.3 \
libssh2_session_disconnect_ex.3 \ libssh2_session_disconnect_ex.3 \
libssh2_session_flag.3 \
libssh2_session_free.3 \
libssh2_session_get_blocking.3 \
libssh2_session_hostkey.3 \
libssh2_session_init_ex.3 \ libssh2_session_init_ex.3 \
libssh2_session_last_errno.3 \ libssh2_session_last_errno.3 \
libssh2_session_last_error.3 \ libssh2_session_last_error.3 \
@@ -45,14 +70,12 @@ dist_man_MANS = \
libssh2_session_methods.3 \ libssh2_session_methods.3 \
libssh2_session_set_blocking.3 \ libssh2_session_set_blocking.3 \
libssh2_session_startup.3 \ libssh2_session_startup.3 \
libssh2_poll.3 \
libssh2_poll_channel_read.3 \
libssh2_sftp_close_handle.3 \ libssh2_sftp_close_handle.3 \
libssh2_sftp_fstat_ex.3 \ libssh2_sftp_fstat_ex.3 \
libssh2_sftp_last_error.3 \
libssh2_sftp_init.3 \ libssh2_sftp_init.3 \
libssh2_sftp_open_ex.3 \ libssh2_sftp_last_error.3 \
libssh2_sftp_mkdir_ex.3 \ libssh2_sftp_mkdir_ex.3 \
libssh2_sftp_open_ex.3 \
libssh2_sftp_read.3 \ libssh2_sftp_read.3 \
libssh2_sftp_readdir_ex.3 \ libssh2_sftp_readdir_ex.3 \
libssh2_sftp_rename_ex.3 \ libssh2_sftp_rename_ex.3 \
@@ -65,24 +88,11 @@ dist_man_MANS = \
libssh2_sftp_tell64.3 \ libssh2_sftp_tell64.3 \
libssh2_sftp_unlink_ex.3 \ libssh2_sftp_unlink_ex.3 \
libssh2_sftp_write.3 \ libssh2_sftp_write.3 \
libssh2_trace.3 \
libssh2_userauth_authenticated.3 \ libssh2_userauth_authenticated.3 \
libssh2_userauth_hostbased_fromfile_ex.3 \
libssh2_userauth_keyboard_interactive_ex.3 \ libssh2_userauth_keyboard_interactive_ex.3 \
libssh2_userauth_list.3 \ libssh2_userauth_list.3 \
libssh2_userauth_password_ex.3 \ libssh2_userauth_password_ex.3 \
libssh2_userauth_publickey_fromfile_ex.3 \ libssh2_userauth_publickey_fromfile_ex.3 \
libssh2_base64_decode.3 \
libssh2_trace.3 \
libssh2_version.3 libssh2_version.3
libssh2_channel_request_pty_size_ex.3 \
libssh2_free_host_entry.3 \
libssh2_host_entry_match.3 \
libssh2_new_host_entry.3 \
libssh2_publickey_add_ex.3 \
libssh2_publickey_init.3 \
libssh2_publickey_list_fetch.3 \
libssh2_publickey_list_free.3 \
libssh2_publickey_remove_ex.3 \
libssh2_publickey_shutdown.3 \
libssh2_session_flag.3 \
libssh2_session_get_blocking.3 \
libssh2_userauth_hostbased_fromfile_ex.3

View File

@@ -13,16 +13,16 @@ LIBSSH2_CHANNEL *
libssh2_channel_direct_tcpip(LIBSSH2_SESSION *session, const char *host, int port); libssh2_channel_direct_tcpip(LIBSSH2_SESSION *session, const char *host, int port);
.SH DESCRIPTION .SH DESCRIPTION
/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)
/fIhost/fP - Third party host to connect to using the SSH host as a proxy. \fIhost\fP - Third party host to connect to using the SSH host as a proxy.
/fIport/fP - Port on third party host to connect to. \fIport\fP - Port on third party host to connect to.
/fIshost/fP - Host to tell the SSH server the connection originated on. \fIshost\fP - Host to tell the SSH server the connection originated on.
/fIsport/fP - Port to tell the SSH server the connection originated from. \fIsport\fP - Port to tell the SSH server the connection originated from.
Tunnel a TCP/IP connection through the SSH transport via the remote host to Tunnel a TCP/IP connection through the SSH transport via the remote host to
a third party. Communication from the client to the SSH server remains a third party. Communication from the client to the SSH server remains

View File

@@ -10,7 +10,7 @@ int
libssh2_channel_forward_cancel(LIBSSH2_LISTENER *listener); libssh2_channel_forward_cancel(LIBSSH2_LISTENER *listener);
.SH DESCRIPTION .SH DESCRIPTION
/fIlistener/fP - Forwarding listener instance as returned by \fIlistener\fP - Forwarding listener instance as returned by
.BR libssh2_channel_forward_listen_ex(3) .BR libssh2_channel_forward_listen_ex(3)
Instruct the remote host to stop listening for new connections on a previously requested host/port. Instruct the remote host to stop listening for new connections on a previously requested host/port.

View File

@@ -0,0 +1,58 @@
.\" Copyright (c) 2009 by Daniel Stenberg
.\"
.TH libssh2_knownhost_add 3 "28 May 2009" "libssh2 1.2" "libssh2 manual"
.SH NAME
libssh2_knownhost_add - add a known host
.SH SYNOPSIS
#include <libssh2.h>
int libssh2_knownhost_add(LIBSSH2_KNOWNHOSTS *hosts,
char *host, char *salt,
char *key, size_t keylen,
int typemask,
struct libssh2_knownhost **store);
.SH DESCRIPTION
Adds a known host to the collection of known hosts identified by the 'hosts'
handle.
\fIhost\fP is a pointer the host name in plain text or hashed. If hashed, it
must be provided base64 encoded. The host name can be the IP numerical address
of the host or the full name.
\fIsalt\P is a pointer to the salt used for the host hashing, if the host is
provided hashed. If the host is provided in plain text, salt has no meaning.
The salt has to be provided base64 encoded with a trailing zero byte.
\fIkey\fP is a pointer to the key for the given host.
\fIkeylen\fP is the total size in bytes of the key pointed to by the \fIkey\fP
argument
\fItypemask\fP is a bitmask that specifies format and info about the data
passed to this function. Specificly, it details what format the host name is,
what format the key is and what key type it is.
The host name is given as one of the following types:
LIBSSH2_KNOWNHOST_TYPE_PLAIN, LIBSSH2_KNOWNHOST_TYPE_SHA1 or
LIBSSH2_KNOWNHOST_TYPE_CUSTOM.
The key is encoded using one of the following encodings:
LIBSSH2_KNOWNHOST_KEYENC_RAW or LIBSSH2_KNOWNHOST_KEYENC_BASE64.
The key is using one of these algorithms:
LIBSSH2_KNOWNHOST_KEY_RSA1, LIBSSH2_KNOWNHOST_KEY_SSHRSA or
LIBSSH2_KNOWNHOST_KEY_SSHDSS.
\fIstore\fP should point to a pointer that gets filled in to point to the
known host data after the addition. NULL can be passed if you don't care about
this pointer.
.SH RETURN VALUE
Returns a regular libssh2 error code, where negative values are error codes
and 0 indicates success.
.SH AVAILABILITY
Added in libssh2 1.2
.SH SEE ALSO
.BR libssh2_knownhost_init(3)
.BR libssh2_knownhost_free(3)
.BR libssh2_knownhost_check(3)

View File

@@ -0,0 +1,57 @@
.\"
.\" Copyright (c) 2009 by Daniel Stenberg
.\"
.TH libssh2_knownhost_check 3 "28 May 2009" "libssh2 1.2" "libssh2 manual"
.SH NAME
libssh2_knownhost_check - check a host+key against the list of known hosts
.SH SYNOPSIS
#include <libssh2.h>
int libssh2_knownhost_check(LIBSSH2_KNOWNHOSTS *hosts,
char *host, char *key, size_t keylen,
int typemask,
struct libssh2_knownhost **knownhost);
.SH DESCRIPTION
Checks a host and its associated key against the collection of known hosts,
and returns info back about the (partially) matched entry.
\fIhost\fP is a pointer the host name in plain text. The host name can be the
IP numerical address of the host or the full name.
\fIkey\fP is a pointer to the key for the given host.
\fIkeylen\fP is the total size in bytes of the key pointed to by the \fIkey\fP
argument
\fItypemask\fP is a bitmask that specifies format and info about the data
passed to this function. Specificly, it details what format the host name is,
what format the key is and what key type it is.
The host name is given as one of the following types:
LIBSSH2_KNOWNHOST_TYPE_PLAIN or LIBSSH2_KNOWNHOST_TYPE_CUSTOM.
The key is encoded using one of the following encodings:
LIBSSH2_KNOWNHOST_KEYENC_RAW or LIBSSH2_KNOWNHOST_KEYENC_BASE64.
\fIknownhost\fP if set to non-NULL, it must be a pointer to a 'struct
libssh2_knownhost' pointer that gets filled in to point to info about a known
host that matches or partially matches.
.SH RETURN VALUE
\fIlibssh2_knownhost_check(3)\fP returns info about how well the provided
host + key pair matched one of the entries in the list of known hosts.
LIBSSH2_KNOWNHOST_CHECK_FAILURE - something prevented the check to be made
LIBSSH2_KNOWNHOST_CHECK_NOTFOUND - no host match was found
LIBSSH2_KNOWNHOST_CHECK_MATCH - hosts and keys match.
LIBSSH2_KNOWNHOST_CHECK_MISMATCH - host was found, but the keys didn't match!
.SH AVAILABILITY
Added in libssh2 1.2
.SH EXAMPLE
See the ssh2_exec.c example as provided in the tarball.
.SH SEE ALSO
.BR libssh2_knownhost_init(3)
.BR libssh2_knownhost_free(3)
.BR libssh2_knownhost_add(3)

View File

@@ -0,0 +1,26 @@
.\"
.\" Copyright (c) 2009 by Daniel Stenberg
.\"
.TH libssh2_knownhost_del 3 "28 May 2009" "libssh2 1.2" "libssh2 manual"
.SH NAME
libssh2_knownhost_del - delete a known host entry
.SH SYNOPSIS
#include <libssh2.h>
int libssh2_knownhost_del(LIBSSH2_KNOWNHOSTS *hosts,
struct libssh2_knownhost *entry);
.SH DESCRIPTION
Delete a known host entry from the collection of known hosts.
\fIentry\fP is a pointer to a struct that you can extract with
\fIlibssh2_knownhost_check(3)\fP or \fIlibssh2_knownhost_get(3)\fP.
.SH RETURN VALUE
Returns a regular libssh2 error code, where negative values are error codes
and 0 indicates success.
.SH AVAILABILITY
Added in libssh2 1.2
.SH SEE ALSO
.BR libssh2_knownhost_init(3)
.BR libssh2_knownhost_free(3)
.BR libssh2_knownhost_add(3)
.BR libssh2_knownhost_check(3)

View File

@@ -0,0 +1,35 @@
.\"
.\" Copyright (c) 2009 by Daniel Stenberg
.\"
.TH libssh2_knownhost_get 3 "28 May 2009" "libssh2 1.2" "libssh2 manual"
.SH NAME
libssh2_knownhost_get - get a known host off the collection of known hosts
.SH SYNOPSIS
#include <libssh2.h>
int libssh2_knownhost_get(LIBSSH2_KNOWNHOSTS *hosts,
struct libssh2_knownhost **store,
struct libssh2_knownhost *prev):
.SH DESCRIPTION
\fIlibssh2_knownhost_get(3)\fP allows an application to iterate over all known
hosts in the collection.
\fIstore\fP should point to a pointer that gets filled in to point to the
known host data.
\fIprev\fP is a pointer to a previous 'struct libssh2_knownhost' as returned
by a previous invoke of this function, or NULL to get the first entry in the
internal collection.
.SH RETURN VALUE
Returns 0 if everything is fine and information about a host was stored in
the \fIstore\fP struct.
Returns 1 if it reached the end of hosts.
Returns negative values for error
.SH AVAILABILITY
Added in libssh2 1.2
.SH SEE ALSO
.BR libssh2_knownhost_readfile(3)
.BR libssh2_knownhost_writefile(3)
.BR libssh2_knownhost_add(3)

View File

@@ -0,0 +1,22 @@
.\"
.\" Copyright (c) 2009 by Daniel Stenberg
.\"
.TH libssh2_knownhost_init 3 "28 May 2009" "libssh2 1.2" "libssh2 manual"
.SH NAME
libssh2_knownhost_init - init a collection of known hosts
.SH SYNOPSIS
#include <libssh2.h>
LIBSSH2_KNOWNHOSTS *libssh2_knownhost_init(LIBSSH2_SESSION *session);
.SH DESCRIPTION
Init a collection of known hosts for this session. Returns the handle to an
internal representation of a known host collection.
.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_free(3)
.BR libssh2_knownhost_add(3)
.BR libssh2_knownhost_check(3)

View File

@@ -0,0 +1,29 @@
.\"
.\" Copyright (c) 2009 by Daniel Stenberg
.\"
.TH libssh2_knownhost_readfile 3 "28 May 2009" "libssh2 1.2" "libssh2 manual"
.SH NAME
libssh2_knownhost_readfile - parse a file of known hosts
.SH SYNOPSIS
#include <libssh2.h>
int libssh2_knownhost_readfile(LIBSSH2_KNOWNHOSTS *hosts,
const char *filename, int type);
.SH DESCRIPTION
Reads a collection of known hosts from a specified file and adds them to the
collection of known hosts.
\fIfilename\fP specifies which file to read
\fItype\fP specifies what file type it is, and
\fILIBSSH2_KNOWNHOST_FILE_OPENSSH\fP is the only currently supported
format. This file is normally found named ~/.ssh/known_hosts
.SH RETURN VALUE
Returns a regular libssh2 error code, where negative values are error codes
and 0 indicates success.
.SH AVAILABILITY
Added in libssh2 1.2
.SH SEE ALSO
.BR libssh2_knownhost_init(3)
.BR libssh2_knownhost_free(3)
.BR libssh2_knownhost_check(3)

View File

@@ -0,0 +1,30 @@
.\"
.\" Copyright (c) 2009 by Daniel Stenberg
.\"
.TH libssh2_knownhost_readline 3 "28 May 2009" "libssh2 1.2" "libssh2 manual"
.SH NAME
libssh2_knownhost_readline - read a known host line
.SH SYNOPSIS
#include <libssh2.h>
int libssh2_knownhost_readline(LIBSSH2_KNOWNHOSTS *hosts,
const char *line, size_t len, int type):
.SH DESCRIPTION
Tell libssh2 to read a buffer as it if is a line from a known hosts file.
\fIline\fP points to the start of the line
\fIlen\fP is the length of the line in bytes
\fItype\fP specifies what file type it is, and
\fILIBSSH2_KNOWNHOST_FILE_OPENSSH\fP is the only currently supported
format. This file is normally found named ~/.ssh/known_hosts
.SH RETURN VALUE
Returns a regular libssh2 error code, where negative values are error codes
and 0 indicates success.
.SH AVAILABILITY
Added in libssh2 1.2
.SH SEE ALSO
.BR libssh2_knownhost_get(3)
.BR libssh2_knownhost_writeline(3)
.BR libssh2_knownhost_readfile(3)

View File

@@ -0,0 +1,29 @@
.\"
.\" Copyright (c) 2009 by Daniel Stenberg
.\"
.TH libssh2_knownhost_writefile 3 "28 May 2009" "libssh2 1.2" "libssh2 manual"
.SH NAME
libssh2_knownhost_writefile - write a collection of known hosts to a file
.SH SYNOPSIS
#include <libssh2.h>
int libssh2_knownhost_writefile(LIBSSH2_KNOWNHOSTS *hosts,
const char *filename, int type);
.SH DESCRIPTION
Writes all the known hosts to the specified file using the specified file
format.
\fIfilename\fP specifies what filename to create
\fItype\fP specifies what file type it is, and
\fILIBSSH2_KNOWNHOST_FILE_OPENSSH\fP is the only currently supported
format.
.SH RETURN VALUE
Returns a regular libssh2 error code, where negative values are error codes
and 0 indicates success.
.SH AVAILABILITY
Added in libssh2 1.2
.SH SEE ALSO
.BR libssh2_knownhost_readfile(3)
.BR libssh2_knownhost_add(3)

View File

@@ -0,0 +1,46 @@
.\"
.\" Copyright (c) 2009 by Daniel Stenberg
.\"
.TH libssh2_knownhost_writeline 3 "28 May 2009" "libssh2 1.2" "libssh2 manual"
.SH NAME
libssh2_knownhost_writeline - convert a known host to a line for storage
.SH SYNOPSIS
#include <libssh2.h>
libssh2_knownhost_writeline(LIBSSH2_KNOWNHOSTS *hosts,
struct libssh2_knownhost *known,
char *buffer, size_t buflen,
size_t *outlen,
int type);
.SH DESCRIPTION
Converts a single known host to a single line of output for storage, using
the 'type' output format.
\fIknown\fP identifies which particular known host
\fIbuffer\fP points to an allocated buffer
\fIbuflen\fP is the size of the \fIbuffer\fP. See RETURN VALUE about the size.
\fIoutlen\fP must be a pointer to a size_t variable that will get the output
length of the stored data chunk. The number does not included the trailing
zero!
\fItype\fP specifies what file type it is, and
\fILIBSSH2_KNOWNHOST_FILE_OPENSSH\fP is the only currently supported
format.
.SH RETURN VALUE
Returns a regular libssh2 error code, where negative values are error codes
and 0 indicates success.
If the provided buffer is deemed too small to fit the data libssh2 wants to
store in it, LIBSSH2_ERROR_BUFFER_TOO_SMALL will be returned. The application
is then adviced to call the function again with a larger buffer. The
\fIoutlen\fP size will then hold the requested size.
.SH AVAILABILITY
Added in libssh2 1.2
.SH SEE ALSO
.BR libssh2_knownhost_get(3)
.BR libssh2_knownhost_readline(3)
.BR libssh2_knownhost_writefile(3)

View File

@@ -1,4 +1,4 @@
.\" $Id: libssh2_poll.3,v 1.3 2007/06/13 12:51:11 jehousley Exp $ .\" $Id: libssh2_poll.3,v 1.4 2009/04/14 21:38:36 bagder Exp $
.\" .\"
.TH libssh2_poll 3 "14 Dec 2006" "libssh2 0.15" "libssh2 manual" .TH libssh2_poll 3 "14 Dec 2006" "libssh2 0.15" "libssh2 manual"
.SH NAME .SH NAME
@@ -8,6 +8,8 @@ libssh2_poll - poll for activity on a socket, channel or listener
int libssh2_poll(LIBSSH2_POLLFD *fds, unsigned int nfds, long timeout); int libssh2_poll(LIBSSH2_POLLFD *fds, unsigned int nfds, long timeout);
.SH DESCRIPTION .SH DESCRIPTION
This function is deprecated. Do note use.
Poll for activity on a socket, channel, listener, or any combination of these Poll for activity on a socket, channel, listener, or any combination of these
three types. The calling semantics for this function generally match three types. The calling semantics for this function generally match
\fIpoll(2)\fP however the structure of fds is somewhat more complex in order \fIpoll(2)\fP however the structure of fds is somewhat more complex in order

View File

@@ -1,4 +1,4 @@
.\" $Id: libssh2_poll_channel_read.3,v 1.2 2007/06/13 12:51:11 jehousley Exp $ .\" $Id: libssh2_poll_channel_read.3,v 1.3 2009/04/14 21:38:36 bagder Exp $
.\" .\"
.TH libssh2_poll_channel_read 3 "14 Dec 2006" "libssh2 0.15" "libssh2 manual" .TH libssh2_poll_channel_read 3 "14 Dec 2006" "libssh2 0.15" "libssh2 manual"
.SH NAME .SH NAME
@@ -8,6 +8,8 @@ libssh2_poll_channel_read - check if data is available
int libssh2_poll_channel_read(LIBSSH2_CHANNEL *channel, int extended); int libssh2_poll_channel_read(LIBSSH2_CHANNEL *channel, int extended);
.SH DESCRIPTION .SH DESCRIPTION
This function is deprecated. Do note use.
\fIlibssh2_poll_channel_read(3)\fP checks to see if data is available in the \fIlibssh2_poll_channel_read(3)\fP checks to see if data is available in the
\fIchannel\fP's read buffer. No attempt is made with this method to see if \fIchannel\fP's read buffer. No attempt is made with this method to see if
packets are available to be processed. For full polling support, use packets are available to be processed. For full polling support, use

View File

@@ -0,0 +1,23 @@
.\" $Id: session_hostkey.3,v 1.4 2007/06/13 16:41:33 jehousley Exp $
.\"
.TH libssh2_session_hostkey 3 "1 Jun 2007" "libssh2 0.15" "libssh2 manual"
.SH NAME
libssh2_session_hostkey - get the remote key
.SH SYNOPSIS
#include <libssh2.h>
const char *libssh2_session_hostkey(LIBSSH2_SESSION *session,
size_t *len, int *type);
.SH DESCRIPTION
Returns a pointer to the current host key, the value \fIlen\fP points to will
get the length of the key.
The value \fItype\fP points to the type of hostkey which is one of:
LIBSSH2_HOSTKEY_TYPE_RSA, LIBSSH2_HOSTKEY_TYPE_DSS, or
LIBSSH2_HOSTKEY_TYPE_UNKNOWN.
.SH RETURN VALUE
A pointer, or NULL if something went wrong.
.SH SEE ALSO
.BR libssh2_knownhost_check(3)
.BR libssh2_knownhost_add(3)

View File

@@ -20,14 +20,10 @@ libssh2_sftp_closedir(LIBSSH2_SFTP_HANDLE *handle);
\fIhandle\fP - SFTP File Handle as returned by \fBlibssh2_sftp_open_ex(3)\fP \fIhandle\fP - SFTP File Handle as returned by \fBlibssh2_sftp_open_ex(3)\fP
or \fBlibssh2_sftp_opendir(3)\fP (which is a macro). or \fBlibssh2_sftp_opendir(3)\fP (which is a macro).
Close an active LIBSSH2_SFTP_HANDLE. Because files and directories Close an active LIBSSH2_SFTP_HANDLE. Because files and directories share the
share the same underlying storage mechanism these methods may be used same underlying storage mechanism these methods may be used
interchangably. It is recommended that interchangably. \fBlibssh2_sftp_close(3)\fP and \fBlibssh2_sftp_closedir(3)\fP
.BR libssh2_sftp_closedir() are macros for \fBlibssh2_sftp_close_handle(3)\fP.
be used for files and that
.BR libssh2_sftp_closedir()
be used for directories so that future changes in the library may cause
minimal disruption. Both are macros for \fBlibssh2_sftp_close_handle\fP.
.SH RETURN VALUE .SH RETURN VALUE
Return 0 on success or negative on failure. It returns Return 0 on success or negative on failure. It returns

18
example/simple/.gitignore vendored Normal file
View File

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

View File

@@ -8,7 +8,7 @@ noinst_PROGRAMS = ssh2 \
sftp_write sftp_write_nonblock \ sftp_write sftp_write_nonblock \
sftp_mkdir sftp_mkdir_nonblock \ sftp_mkdir sftp_mkdir_nonblock \
sftp_RW_nonblock \ sftp_RW_nonblock \
sftpdir sftpdir_nonblock sftpdir sftpdir_nonblock ssh2_exec
# the examples need the $(top_builddir)/src since when building outside of the # the examples need the $(top_builddir)/src since when building outside of the
# source dir they still need to reach the libssh2_config.h header # source dir they still need to reach the libssh2_config.h header

View File

@@ -1,5 +1,5 @@
/* /*
* $Id: scp.c,v 1.11 2008/11/10 16:48:41 bagder Exp $ * $Id: scp.c,v 1.12 2009/04/28 10:35:30 bagder Exp $
* *
* Sample showing how to do a simple SCP transfer. * Sample showing how to do a simple SCP transfer.
*/ */
@@ -164,10 +164,8 @@ int main(int argc, char *argv[])
libssh2_session_free(session); libssh2_session_free(session);
#ifdef WIN32 #ifdef WIN32
Sleep(1000);
closesocket(sock); closesocket(sock);
#else #else
sleep(1);
close(sock); close(sock);
#endif #endif
fprintf(stderr, "all done\n"); fprintf(stderr, "all done\n");

View File

@@ -1,5 +1,5 @@
/* /*
* $Id: scp_nonblock.c,v 1.15 2009/03/25 22:52:32 bagder Exp $ * $Id: scp_nonblock.c,v 1.16 2009/04/28 10:35:30 bagder Exp $
* *
* Sample showing how to do SCP transfers in a non-blocking manner. * Sample showing how to do SCP transfers in a non-blocking manner.
* *
@@ -132,23 +132,6 @@ int main(int argc, char *argv[])
return -1; return -1;
} }
/* We set the socket non-blocking. We do it after the connect just to
simplify the example code. */
#ifdef F_SETFL
/* FIXME: this can/should be done in a more portable manner */
rc = fcntl(sock, F_GETFL, 0);
fcntl(sock, F_SETFL, rc | O_NONBLOCK);
#elif defined(HAVE_IOCTLSOCKET)
ioctlsocket(sock, FIONBIO, &flag);
#else
#ifdef WIN32
u_long mode = 1;
ioctlsocket (sock, FIONBIO, &mode);
#else
#error "add support for setting the socket non-blocking here"
#endif
#endif
/* Create a session instance */ /* Create a session instance */
session = libssh2_session_init(); session = libssh2_session_init();
if (!session) if (!session)
@@ -276,10 +259,8 @@ shutdown:
libssh2_session_free(session); libssh2_session_free(session);
#ifdef WIN32 #ifdef WIN32
Sleep(1000);
closesocket(sock); closesocket(sock);
#else #else
sleep(1);
close(sock); close(sock);
#endif #endif
fprintf(stderr, "all done\n"); fprintf(stderr, "all done\n");

View File

@@ -1,5 +1,5 @@
/* /*
* $Id: scp_write.c,v 1.6 2008/11/10 16:48:41 bagder Exp $ * $Id: scp_write.c,v 1.7 2009/04/28 10:35:30 bagder Exp $
* *
* Sample showing how to do a simple SCP transfer. * Sample showing how to do a simple SCP transfer.
*/ */
@@ -186,10 +186,8 @@ int main(int argc, char *argv[])
libssh2_session_free(session); libssh2_session_free(session);
#ifdef WIN32 #ifdef WIN32
Sleep(1000);
closesocket(sock); closesocket(sock);
#else #else
sleep(1);
close(sock); close(sock);
#endif #endif
fprintf(stderr, "all done\n"); fprintf(stderr, "all done\n");

View File

@@ -1,5 +1,5 @@
/* /*
* $Id: scp_write_nonblock.c,v 1.9 2008/11/10 16:48:41 bagder Exp $ * $Id: scp_write_nonblock.c,v 1.10 2009/04/28 10:35:30 bagder Exp $
* *
* Sample showing how to do a simple SCP transfer. * Sample showing how to do a simple SCP transfer.
*/ */
@@ -102,23 +102,6 @@ int main(int argc, char *argv[])
return -1; return -1;
} }
/* We set the socket non-blocking. We do it after the connect just to
simplify the example code. */
#ifdef F_SETFL
/* FIXME: this can/should be done in a more portable manner */
rc = fcntl(sock, F_GETFL, 0);
fcntl(sock, F_SETFL, rc | O_NONBLOCK);
#elif defined(HAVE_IOCTLSOCKET)
ioctlsocket(sock, FIONBIO, &flag);
#else
#ifdef WIN32
u_long mode = 1;
ioctlsocket (sock, FIONBIO, &mode);
#else
#error "add support for setting the socket non-blocking here"
#endif
#endif
/* Create a session instance /* Create a session instance
*/ */
session = libssh2_session_init(); session = libssh2_session_init();
@@ -225,10 +208,8 @@ int main(int argc, char *argv[])
libssh2_session_free(session); libssh2_session_free(session);
#ifdef WIN32 #ifdef WIN32
Sleep(1000);
closesocket(sock); closesocket(sock);
#else #else
sleep(1);
close(sock); close(sock);
#endif #endif
fprintf(stderr, "all done\n"); fprintf(stderr, "all done\n");

View File

@@ -1,5 +1,5 @@
/* /*
* $Id: sftp.c,v 1.16 2009/03/31 12:20:36 bagder Exp $ * $Id: sftp.c,v 1.17 2009/04/28 10:35:30 bagder Exp $
* *
* Sample showing how to do SFTP transfers. * Sample showing how to do SFTP transfers.
* *
@@ -236,10 +236,8 @@ int main(int argc, char *argv[])
libssh2_session_free(session); libssh2_session_free(session);
#ifdef WIN32 #ifdef WIN32
Sleep(1000);
closesocket(sock); closesocket(sock);
#else #else
sleep(1);
close(sock); close(sock);
#endif #endif
fprintf(stderr, "all done\n"); fprintf(stderr, "all done\n");

View File

@@ -1,5 +1,5 @@
/* /*
* $Id: sftp_RW_nonblock.c,v 1.12 2008/11/10 16:48:41 bagder Exp $ * $Id: sftp_RW_nonblock.c,v 1.13 2009/04/28 10:35:30 bagder Exp $
* *
* Sample showing how to do SFTP transfers in a non-blocking manner. * Sample showing how to do SFTP transfers in a non-blocking manner.
* *
@@ -84,23 +84,6 @@ int main(int argc, char *argv[])
return -1; return -1;
} }
/* We set the socket non-blocking. We do it after the connect just to
simplify the example code. */
#ifdef F_SETFL
/* FIXME: this can/should be done in a more portable manner */
rc = fcntl(sock, F_GETFL, 0);
fcntl(sock, F_SETFL, rc | O_NONBLOCK);
#elif defined(HAVE_IOCTLSOCKET)
ioctlsocket(sock, FIONBIO, &flag);
#else
#ifdef WIN32
u_long mode = 1;
ioctlsocket (sock, FIONBIO, &mode);
#else
#error "add support for setting the socket non-blocking here"
#endif
#endif
/* Create a session instance /* Create a session instance
*/ */
session = libssh2_session_init(); session = libssh2_session_init();
@@ -293,10 +276,8 @@ int main(int argc, char *argv[])
libssh2_session_free(session); libssh2_session_free(session);
#ifdef WIN32 #ifdef WIN32
Sleep(1000);
closesocket(sock); closesocket(sock);
#else #else
sleep(1);
close(sock); close(sock);
#endif #endif
printf("all done\n"); printf("all done\n");

View File

@@ -1,5 +1,5 @@
/* /*
* $Id: sftp_mkdir.c,v 1.8 2008/11/10 16:48:41 bagder Exp $ * $Id: sftp_mkdir.c,v 1.9 2009/04/28 10:35:30 bagder Exp $
* *
* Sample showing how to do SFTP mkdir * Sample showing how to do SFTP mkdir
* *
@@ -155,10 +155,8 @@ int main(int argc, char *argv[])
libssh2_session_free(session); libssh2_session_free(session);
#ifdef WIN32 #ifdef WIN32
Sleep(1000);
closesocket(sock); closesocket(sock);
#else #else
sleep(1);
close(sock); close(sock);
#endif #endif
printf("all done\n"); printf("all done\n");

View File

@@ -1,5 +1,5 @@
/* /*
* $Id: sftp_mkdir_nonblock.c,v 1.11 2008/11/10 16:48:41 bagder Exp $ * $Id: sftp_mkdir_nonblock.c,v 1.12 2009/04/28 10:35:30 bagder Exp $
* *
* Sample showing how to do SFTP non-blocking mkdir. * Sample showing how to do SFTP non-blocking mkdir.
* *
@@ -88,23 +88,6 @@ int main(int argc, char *argv[])
return -1; return -1;
} }
/* We set the socket non-blocking. We do it after the connect just to
simplify the example code. */
#ifdef F_SETFL
/* FIXME: this can/should be done in a more portable manner */
rc = fcntl(sock, F_GETFL, 0);
fcntl(sock, F_SETFL, rc | O_NONBLOCK);
#elif defined(HAVE_IOCTLSOCKET)
ioctlsocket(sock, FIONBIO, &flag);
#else
#ifdef WIN32
u_long mode = 1;
ioctlsocket (sock, FIONBIO, &mode);
#else
#error "add support for setting the socket non-blocking here"
#endif
#endif
/* Create a session instance /* Create a session instance
*/ */
session = libssh2_session_init(); session = libssh2_session_init();
@@ -178,10 +161,8 @@ int main(int argc, char *argv[])
libssh2_session_free(session); libssh2_session_free(session);
#ifdef WIN32 #ifdef WIN32
Sleep(1000);
closesocket(sock); closesocket(sock);
#else #else
sleep(1);
close(sock); close(sock);
#endif #endif
printf("all done\n"); printf("all done\n");

View File

@@ -1,5 +1,5 @@
/* /*
* $Id: sftp_nonblock.c,v 1.17 2009/03/13 22:14:47 bagder Exp $ * $Id: sftp_nonblock.c,v 1.18 2009/04/28 10:35:30 bagder Exp $
* *
* Sample showing how to do SFTP non-blocking transfers. * Sample showing how to do SFTP non-blocking transfers.
* *
@@ -133,23 +133,6 @@ int main(int argc, char *argv[])
return -1; return -1;
} }
/* We set the socket non-blocking. We do it after the connect just to
simplify the example code. */
#ifdef F_SETFL
/* FIXME: this can/should be done in a more portable manner */
rc = fcntl(sock, F_GETFL, 0);
fcntl(sock, F_SETFL, rc | O_NONBLOCK);
#elif defined(HAVE_IOCTLSOCKET)
ioctlsocket(sock, FIONBIO, &flag);
#else
#ifdef WIN32
u_long mode = 1;
ioctlsocket (sock, FIONBIO, &mode);
#else
#error "add support for setting the socket non-blocking here"
#endif
#endif
/* Create a session instance */ /* Create a session instance */
session = libssh2_session_init(); session = libssh2_session_init();
if (!session) if (!session)
@@ -278,10 +261,8 @@ shutdown:
libssh2_session_free(session); libssh2_session_free(session);
#ifdef WIN32 #ifdef WIN32
Sleep(1000);
closesocket(sock); closesocket(sock);
#else #else
sleep(1);
close(sock); close(sock);
#endif #endif
fprintf(stderr, "all done\n"); fprintf(stderr, "all done\n");

View File

@@ -1,5 +1,5 @@
/* /*
* $Id: sftp_write.c,v 1.10 2009/03/31 12:20:36 bagder Exp $ * $Id: sftp_write.c,v 1.11 2009/04/28 10:35:30 bagder Exp $
* *
* Sample showing how to do SFTP write transfers. * Sample showing how to do SFTP write transfers.
* *
@@ -195,10 +195,8 @@ int main(int argc, char *argv[])
libssh2_session_free(session); libssh2_session_free(session);
#ifdef WIN32 #ifdef WIN32
Sleep(1000);
closesocket(sock); closesocket(sock);
#else #else
sleep(1);
close(sock); close(sock);
#endif #endif
printf("all done\n"); printf("all done\n");

View File

@@ -1,5 +1,5 @@
/* /*
* $Id: sftp_write_nonblock.c,v 1.13 2009/03/31 12:20:36 bagder Exp $ * $Id: sftp_write_nonblock.c,v 1.14 2009/04/28 10:35:30 bagder Exp $
* *
* Sample showing how to do SFTP non-blocking write transfers. * Sample showing how to do SFTP non-blocking write transfers.
* *
@@ -103,23 +103,6 @@ int main(int argc, char *argv[])
return -1; return -1;
} }
/* We set the socket non-blocking. We do it after the connect just to
simplify the example code. */
#ifdef F_SETFL
/* FIXME: this can/should be done in a more portable manner */
rc = fcntl(sock, F_GETFL, 0);
fcntl(sock, F_SETFL, rc | O_NONBLOCK);
#elif defined(HAVE_IOCTLSOCKET)
ioctlsocket(sock, FIONBIO, &flag);
#else
#ifdef WIN32
u_long mode = 1;
ioctlsocket (sock, FIONBIO, &mode);
#else
#error "add support for setting the socket non-blocking here"
#endif
#endif
/* Create a session instance /* Create a session instance
*/ */
session = libssh2_session_init(); session = libssh2_session_init();
@@ -139,10 +122,10 @@ int main(int argc, char *argv[])
return -1; return -1;
} }
/* At this point we havn't yet authenticated. The first thing to do /* At this point we havn't yet authenticated. The first thing to do is
* is check the hostkey's fingerprint against our known hosts Your app * check the hostkey's fingerprint against our known hosts Your app may
* may have it hard coded, may go to a file, may present it to the * have it hard coded, may go to a file, may present it to the user,
* user, that's your call * that's your call
*/ */
fingerprint = libssh2_hostkey_hash(session, LIBSSH2_HOSTKEY_HASH_MD5); fingerprint = libssh2_hostkey_hash(session, LIBSSH2_HOSTKEY_HASH_MD5);
printf("Fingerprint: "); printf("Fingerprint: ");
@@ -224,10 +207,8 @@ shutdown:
libssh2_session_free(session); libssh2_session_free(session);
#ifdef WIN32 #ifdef WIN32
Sleep(1000);
closesocket(sock); closesocket(sock);
#else #else
sleep(1);
close(sock); close(sock);
#endif #endif
printf("all done\n"); printf("all done\n");

View File

@@ -1,5 +1,5 @@
/* /*
* $Id: sftpdir.c,v 1.10 2008/11/10 16:48:41 bagder Exp $ * $Id: sftpdir.c,v 1.11 2009/04/28 10:35:30 bagder Exp $
* *
* Sample doing an SFTP directory listing. * Sample doing an SFTP directory listing.
* *
@@ -207,10 +207,8 @@ int main(int argc, char *argv[])
libssh2_session_free(session); libssh2_session_free(session);
#ifdef WIN32 #ifdef WIN32
Sleep(1000);
closesocket(sock); closesocket(sock);
#else #else
sleep(1);
close(sock); close(sock);
#endif #endif
printf("all done\n"); printf("all done\n");

View File

@@ -1,5 +1,5 @@
/* /*
* $Id: sftpdir_nonblock.c,v 1.12 2008/11/10 16:48:41 bagder Exp $ * $Id: sftpdir_nonblock.c,v 1.13 2009/04/28 10:35:30 bagder Exp $
* *
* Sample doing an SFTP directory listing. * Sample doing an SFTP directory listing.
* *
@@ -88,23 +88,6 @@ int main(int argc, char *argv[])
return -1; return -1;
} }
/* We set the socket non-blocking. We do it after the connect just to
simplify the example code. */
#ifdef F_SETFL
/* FIXME: this can/should be done in a more portable manner */
rc = fcntl(sock, F_GETFL, 0);
fcntl(sock, F_SETFL, rc | O_NONBLOCK);
#elif defined(HAVE_IOCTLSOCKET)
ioctlsocket(sock, FIONBIO, &flag);
#else
#ifdef WIN32
u_long mode = 1;
ioctlsocket (sock, FIONBIO, &mode);
#else
#error "add support for setting the socket non-blocking here"
#endif
#endif
/* Create a session instance /* Create a session instance
*/ */
session = libssh2_session_init(); session = libssh2_session_init();
@@ -236,10 +219,8 @@ int main(int argc, char *argv[])
libssh2_session_free(session); libssh2_session_free(session);
#ifdef WIN32 #ifdef WIN32
Sleep(1000);
closesocket(sock); closesocket(sock);
#else #else
sleep(1);
close(sock); close(sock);
#endif #endif
printf("all done\n"); printf("all done\n");

View File

@@ -1,5 +1,5 @@
/* /*
* $Id: ssh2.c,v 1.18 2008/11/10 16:48:41 bagder Exp $ * $Id: ssh2.c,v 1.19 2009/04/28 10:35:30 bagder Exp $
* *
* Sample showing how to do SSH2 connect. * Sample showing how to do SSH2 connect.
* *
@@ -46,7 +46,8 @@ const char *password="password";
static void kbd_callback(const char *name, int name_len, static void kbd_callback(const char *name, int name_len,
const char *instruction, int instruction_len, int num_prompts, const char *instruction, int instruction_len,
int num_prompts,
const LIBSSH2_USERAUTH_KBDINT_PROMPT *prompts, const LIBSSH2_USERAUTH_KBDINT_PROMPT *prompts,
LIBSSH2_USERAUTH_KBDINT_RESPONSE *responses, LIBSSH2_USERAUTH_KBDINT_RESPONSE *responses,
void **abstract) void **abstract)
@@ -92,13 +93,11 @@ int main(int argc, char *argv[])
password = argv[3]; password = argv[3];
} }
/* Ultra basic "connect to port 22 on localhost" /* Ultra basic "connect to port 22 on localhost". Your code is
* Your code is responsible for creating the socket establishing the connection * responsible for creating the socket establishing the connection
*/ */
sock = socket(AF_INET, SOCK_STREAM, 0); sock = socket(AF_INET, SOCK_STREAM, 0);
#ifndef WIN32
fcntl(sock, F_SETFL, 0);
#endif
sin.sin_family = AF_INET; sin.sin_family = AF_INET;
sin.sin_port = htons(22); sin.sin_port = htons(22);
sin.sin_addr.s_addr = hostaddr; sin.sin_addr.s_addr = hostaddr;
@@ -108,8 +107,8 @@ int main(int argc, char *argv[])
return -1; return -1;
} }
/* Create a session instance and start it up /* Create a session instance and start it up. This will trade welcome
* This will trade welcome banners, exchange keys, and setup crypto, compression, and MAC layers * banners, exchange keys, and setup crypto, compression, and MAC layers
*/ */
session = libssh2_session_init(); session = libssh2_session_init();
if (libssh2_session_startup(session, sock)) { if (libssh2_session_startup(session, sock)) {
@@ -117,9 +116,10 @@ int main(int argc, char *argv[])
return -1; return -1;
} }
/* At this point we havn't authenticated, /* At this point we havn't authenticated. The first thing to do is check
* The first thing to do is check the hostkey's fingerprint against our known hosts * the hostkey's fingerprint against our known hosts Your app may have it
* Your app may have it hard coded, may go to a file, may present it to the user, that's your call * hard coded, may go to a file, may present it to the user, that's your
* call
*/ */
fingerprint = libssh2_hostkey_hash(session, LIBSSH2_HOSTKEY_HASH_MD5); fingerprint = libssh2_hostkey_hash(session, LIBSSH2_HOSTKEY_HASH_MD5);
printf("Fingerprint: "); printf("Fingerprint: ");
@@ -164,7 +164,8 @@ int main(int argc, char *argv[])
} }
} else if (auth_pw & 2) { } else if (auth_pw & 2) {
/* Or via keyboard-interactive */ /* Or via keyboard-interactive */
if (libssh2_userauth_keyboard_interactive(session, username, &kbd_callback) ) { if (libssh2_userauth_keyboard_interactive(session, username,
&kbd_callback) ) {
printf("\tAuthentication by keyboard-interactive failed!\n"); printf("\tAuthentication by keyboard-interactive failed!\n");
goto shutdown; goto shutdown;
} else { } else {
@@ -172,7 +173,8 @@ int main(int argc, char *argv[])
} }
} else if (auth_pw & 4) { } else if (auth_pw & 4) {
/* Or by public key */ /* Or by public key */
if (libssh2_userauth_publickey_fromfile(session, username, keyfile1, keyfile2, password)) { if (libssh2_userauth_publickey_fromfile(session, username, keyfile1,
keyfile2, password)) {
printf("\tAuthentication by public key failed!\n"); printf("\tAuthentication by public key failed!\n");
goto shutdown; goto shutdown;
} else { } else {
@@ -235,14 +237,13 @@ int main(int argc, char *argv[])
shutdown: shutdown:
libssh2_session_disconnect(session, "Normal Shutdown, Thank you for playing"); libssh2_session_disconnect(session,
"Normal Shutdown, Thank you for playing");
libssh2_session_free(session); libssh2_session_free(session);
#ifdef WIN32 #ifdef WIN32
Sleep(1000);
closesocket(sock); closesocket(sock);
#else #else
sleep(1);
close(sock); close(sock);
#endif #endif
printf("all done!\n"); printf("all done!\n");

291
example/simple/ssh2_exec.c Normal file
View File

@@ -0,0 +1,291 @@
/*
* $Id: ssh2_exec.c,v 1.4 2009/05/07 20:30:22 bagder Exp $
*
* Sample showing how to use libssh2 to execute a command remotely.
*
* The sample code has fixed values for host name, user name, password
* and command to run.
*
* Run it like this:
*
* $ ./ssh2_exec 127.0.0.1 user password "uptime"
*
*/
#include "libssh2_config.h"
#include <libssh2.h>
#ifdef HAVE_WINSOCK2_H
# include <winsock2.h>
#endif
#ifdef HAVE_NETINET_IN_H
# include <netinet/in.h>
#endif
#ifdef HAVE_SYS_SOCKET_H
# include <sys/socket.h>
#endif
# ifdef HAVE_UNISTD_H
#include <unistd.h>
#endif
#ifdef HAVE_ARPA_INET_H
# include <arpa/inet.h>
#endif
#include <sys/time.h>
#include <sys/types.h>
#include <stdlib.h>
#include <fcntl.h>
#include <errno.h>
#include <stdio.h>
#include <ctype.h>
static int waitsocket(int socket_fd, LIBSSH2_SESSION *session)
{
struct timeval timeout;
int rc;
fd_set fd;
fd_set *writefd = NULL;
fd_set *readfd = NULL;
int dir;
timeout.tv_sec = 10;
timeout.tv_usec = 0;
FD_ZERO(&fd);
FD_SET(socket_fd, &fd);
/* now make sure we wait in the correct direction */
dir = libssh2_session_block_directions(session);
if(dir & LIBSSH2_SESSION_BLOCK_INBOUND)
readfd = &fd;
if(dir & LIBSSH2_SESSION_BLOCK_OUTBOUND)
writefd = &fd;
rc = select(socket_fd + 1, readfd, writefd, NULL, &timeout);
return rc;
}
int main(int argc, char *argv[])
{
const char *hostname = "127.0.0.1";
const char *commandline = "uptime";
const char *username = "user";
const char *password = "password";
unsigned long hostaddr;
int sock;
struct sockaddr_in sin;
const char *fingerprint;
LIBSSH2_SESSION *session;
LIBSSH2_CHANNEL *channel;
int rc;
int exitcode;
int bytecount = 0;
size_t len;
LIBSSH2_KNOWNHOSTS *nh;
int type;
#ifdef WIN32
WSADATA wsadata;
WSAStartup(MAKEWORD(2,0), &wsadata);
#endif
if (argc > 1)
/* must be ip address only */
hostname = argv[1];
if (argc > 2) {
username = argv[2];
}
if (argc > 3) {
password = argv[3];
}
if (argc > 4) {
commandline = argv[4];
}
hostaddr = inet_addr(hostname);
/* Ultra basic "connect to port 22 on localhost"
* Your code is responsible for creating the socket establishing the
* connection
*/
sock = socket(AF_INET, SOCK_STREAM, 0);
sin.sin_family = AF_INET;
sin.sin_port = htons(22);
sin.sin_addr.s_addr = hostaddr;
if (connect(sock, (struct sockaddr*)(&sin),
sizeof(struct sockaddr_in)) != 0) {
fprintf(stderr, "failed to connect!\n");
return -1;
}
/* Create a session instance */
session = libssh2_session_init();
if (!session)
return -1;
/* tell libssh2 we want it all done non-blocking */
libssh2_session_set_blocking(session, 0);
/* ... start it up. This will trade welcome banners, exchange keys,
* and setup crypto, compression, and MAC layers
*/
while ((rc = libssh2_session_startup(session, sock)) ==
LIBSSH2_ERROR_EAGAIN);
if (rc) {
fprintf(stderr, "Failure establishing SSH session: %d\n", rc);
return -1;
}
nh = libssh2_knownhost_init(session);
if(!nh) {
/* eeek, do cleanup here */
return 2;
}
/* read all hosts from here */
libssh2_knownhost_readfile(nh, "known_hosts",
LIBSSH2_KNOWNHOST_FILE_OPENSSH);
/* store all known hosts to here */
libssh2_knownhost_writefile(nh, "dumpfile",
LIBSSH2_KNOWNHOST_FILE_OPENSSH);
fingerprint = libssh2_session_hostkey(session, &len, &type);
if(fingerprint) {
struct libssh2_knownhost *host;
int check = libssh2_knownhost_check(nh, (char *)hostname,
(char *)fingerprint, len,
LIBSSH2_KNOWNHOST_TYPE_PLAIN|
LIBSSH2_KNOWNHOST_KEYENC_RAW,
&host);
fprintf(stderr, "Host check: %d, key: %s\n", check,
(check <= LIBSSH2_KNOWNHOST_CHECK_MISMATCH)?
host->key:"<none>");
/*****
* At this point, we could verify that 'check' tells us the key is
* fine or bail out.
*****/
}
else {
/* eeek, do cleanup here */
return 3;
}
libssh2_knownhost_free(nh);
if ( strlen(password) != 0 ) {
/* We could authenticate via password */
while ((rc = libssh2_userauth_password(session, username, password)) ==
LIBSSH2_ERROR_EAGAIN);
if (rc) {
fprintf(stderr, "Authentication by password failed.\n");
goto shutdown;
}
}
else {
/* Or by public key */
while ((rc = libssh2_userauth_publickey_fromfile(session, username,
"/home/user/"
".ssh/id_rsa.pub",
"/home/user/"
".ssh/id_rsa",
password)) ==
LIBSSH2_ERROR_EAGAIN);
if (rc) {
fprintf(stderr, "\tAuthentication by public key failed\n");
goto shutdown;
}
}
#if 0
libssh2_trace(session, ~0 );
#endif
/* Exec non-blocking on the remove host */
while( (channel = libssh2_channel_open_session(session)) == NULL &&
libssh2_session_last_error(session,NULL,NULL,0) ==
LIBSSH2_ERROR_EAGAIN )
{
waitsocket(sock, session);
}
if( channel == NULL )
{
fprintf(stderr,"Error\n");
exit( 1 );
}
while( (rc = libssh2_channel_exec(channel, commandline)) ==
LIBSSH2_ERROR_EAGAIN )
{
waitsocket(sock, session);
}
if( rc != 0 )
{
fprintf(stderr,"Error\n");
exit( 1 );
}
for( ;; )
{
/* loop until we block */
int rc;
do
{
char buffer[0x4000];
rc = libssh2_channel_read( channel, buffer, sizeof(buffer) );
if( rc > 0 )
{
int i;
bytecount += rc;
fprintf(stderr, "We read:\n");
for( i=0; i < rc; ++i )
fputc( buffer[i], stderr);
fprintf(stderr, "\n");
}
else {
fprintf(stderr, "libssh2_channel_read returned %d\n", rc);
}
}
while( rc > 0 );
/* this is due to blocking that would occur otherwise so we loop on
this condition */
if( rc == LIBSSH2_ERROR_EAGAIN )
{
waitsocket(sock, session);
}
else
break;
}
exitcode = 127;
while( (rc = libssh2_channel_close(channel)) == LIBSSH2_ERROR_EAGAIN )
waitsocket(sock, session);
if( rc == 0 )
{
exitcode = libssh2_channel_get_exit_status( channel );
}
printf("\nEXIT: %d bytecount: %d\n", exitcode, bytecount);
libssh2_channel_free(channel);
channel = NULL;
shutdown:
libssh2_session_disconnect(session,
"Normal Shutdown, Thank you for playing");
libssh2_session_free(session);
#ifdef WIN32
closesocket(sock);
#else
close(sock);
#endif
fprintf(stderr, "all done\n");
return 0;
}

433
example/simple/x11.c Normal file
View File

@@ -0,0 +1,433 @@
/*
*
* Sample showing how to makes SSH2 with X11 Forwarding works.
*
* Usage :
* "ssh2 host user password [DEBUG]"
*/
#include <string.h>
#include <sys/ioctl.h>
#include <netinet/in.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/un.h>
#include <fcntl.h>
#include <errno.h>
#include <stdio.h>
#include <ctype.h>
#include <stdlib.h>
#include <termios.h>
#include <libssh2.h>
#define _PATH_UNIX_X "/tmp/.X11-unix/X%d"
/*
* Chained list that contains channels and associated X11 socket for each X11
* connections
*/
struct chan_X11_list {
LIBSSH2_CHANNEL *chan;
int sock;
struct chan_X11_list *next;
};
struct chan_X11_list * gp_x11_chan = NULL;
struct termios _saved_tio;
/*
* Utility function to remove a Node of the chained list
*/
static void remove_node(struct chan_X11_list *elem)
{
struct chan_X11_list *current_node = NULL;
current_node = gp_x11_chan;
if (gp_x11_chan == elem) {
/* Removing the only one element in the list */
free(gp_x11_chan);
gp_x11_chan = NULL;
}
while( current_node->next != NULL) {
if (current_node->next ==elem) {
current_node->next = current_node->next->next;
current_node = current_node->next;
free(current_node);
break;
}
}
}
static void session_shutdown(LIBSSH2_SESSION *session)
{
libssh2_session_disconnect(session,
"Session Shutdown, Thank you for playing");
libssh2_session_free(session);
}
static int _raw_mode(void)
{
int rc;
struct termios tio;
rc = tcgetattr(fileno(stdin), &tio);
if (rc != -1) {
_saved_tio = tio;
cfmakeraw(&tio);
rc = tcsetattr(fileno(stdin), TCSADRAIN, &tio);
}
return rc;
}
static int _normal_mode(void)
{
int rc;
rc = tcsetattr(fileno(stdin), TCSADRAIN, &_saved_tio);
return rc;
}
/*
* CallBack to initialize the forwarding.
* Save the channel to loop on it, save the X11 forwarded socket to send
* and receive info from our X server.
*/
static void x11_callback(LIBSSH2_SESSION *session, LIBSSH2_CHANNEL *channel,
char *shost, int sport, void **abstract)
{
const char * display = NULL;
char * ptr = NULL;
char * temp_buff = NULL;
int display_port = 0;
int sock = 0;
int rc = 0;
struct sockaddr_un addr;
struct chan_X11_list *new;
struct chan_X11_list *chan_iter;
/*
* Connect to the display
* Inspired by x11_connect_display in openssh
*/
display = getenv("DISPLAY");
if ( display != NULL) {
if (strncmp( display, "unix:", 5) == 0 ||
display[0] == ':') {
/* Connect to the local unix domain */
ptr = strrchr(display, ':');
temp_buff = (char *) calloc(strlen(ptr+1), sizeof(char));
memcpy(temp_buff, ptr+1, strlen(ptr+1));
display_port = atoi(temp_buff);
sock = socket(AF_UNIX,SOCK_STREAM, 0);
if (sock <0)
return;
memset(&addr, 0, sizeof(addr));
addr.sun_family = AF_UNIX;
snprintf(addr.sun_path, sizeof(addr.sun_path),
_PATH_UNIX_X, display_port);
rc = connect(sock, (struct sockaddr *) &addr, sizeof(addr));
if (rc != -1){
/* Connection Successfull */
if (gp_x11_chan == NULL) {
/* Calloc ensure that gp_X11_chan is full of 0 */
gp_x11_chan = (struct chan_X11_list *)
calloc(1, sizeof(struct chan_X11_list));
gp_x11_chan->sock = sock;
gp_x11_chan->chan = channel;
gp_x11_chan->next = NULL;
}
else {
chan_iter = gp_x11_chan;
while (chan_iter->next != NULL)
chan_iter = chan_iter->next;
/* Create the new Node */
new = (struct chan_X11_list *)
malloc(sizeof(struct chan_X11_list));
new->sock = sock;
new->chan = channel;
new->next = NULL;
chan_iter->next = new;
}
}
else
close(sock);
}
}
return;
}
/*
* Send and receive Data for the X11 channel.
* If the connection is closed, returns -1, 0 either.
*/
static int x11_send_receive(LIBSSH2_CHANNEL *channel, int sock)
{
char * buf = NULL;
int bufsize = 8192;
int rc = 0;
int nfds = 1;
LIBSSH2_POLLFD *fds = NULL;
fd_set set;
struct timeval timeval_out;
timeval_out.tv_sec = 0;
timeval_out.tv_usec = 0;
FD_ZERO(&set);
FD_SET(sock,&set);
if ((buf = calloc (bufsize, sizeof(char))) == NULL)
return 0;
if ((fds = malloc (sizeof (LIBSSH2_POLLFD))) == NULL) {
free(buf);
return 0;
}
fds[0].type = LIBSSH2_POLLFD_CHANNEL;
fds[0].fd.channel = channel;
fds[0].events = LIBSSH2_POLLFD_POLLIN;
fds[0].revents = LIBSSH2_POLLFD_POLLIN;
rc = libssh2_poll(fds, nfds, 0);
if (rc >0) {
rc = libssh2_channel_read(channel, buf,sizeof(buf));
rc = write(sock, buf, rc);
}
rc = select(sock+1,&set,NULL,NULL,&timeval_out);
if (rc > 0) {
memset((void *)buf,0,bufsize);
/* Data in sock*/
rc = read(sock, buf,sizeof(buf));
if (rc > 0)
rc = libssh2_channel_write(channel,buf, rc);
else
return -1;
}
free(fds);
free(buf);
if (libssh2_channel_eof (channel) == 1) {
return -1;
}
return 0;
}
/*
* Main, more than inspired by ssh2.c by Bagder
*/
int
main (int argc, char *argv[])
{
unsigned long hostaddr = 0;
int sock = 0;
int rc = 0;
struct sockaddr_in sin;
LIBSSH2_SESSION *session;
LIBSSH2_CHANNEL *channel;
char *username = NULL;
char *password = NULL;
size_t bufsiz = 8193;
char *buf = NULL;
int set_debug_on = 0;
int nfds = 1;
LIBSSH2_POLLFD *fds = NULL;
/* Chan List struct */
struct chan_X11_list *current_node = NULL;
/* Struct winsize for term size */
struct winsize w_size;
struct winsize w_size_bck;
/* For select on stdin */
fd_set set;
struct timeval timeval_out;
timeval_out.tv_sec = 0;
timeval_out.tv_usec = 10;
if (argc > 3) {
hostaddr = inet_addr(argv[1]);
username = argv[2];
password = argv[3];
}
else {
fprintf(stderr, "Usage: %s destination username password",
argv[0]);
return -1;
}
if (argc > 4) {
set_debug_on = 1;
fprintf (stderr, "DEBUG is ON: %d\n", set_debug_on);
}
sock = socket (AF_INET, SOCK_STREAM, 0);
sin.sin_family = AF_INET;
sin.sin_port = htons (22);
sin.sin_addr.s_addr = hostaddr;
rc = connect(sock, (struct sockaddr *) &sin,
sizeof(struct sockaddr_in));
if (rc != 0) {
fprintf (stderr, "Failed to established connection!\n");
return -1;
}
/* Open a session */
session = libssh2_session_init ();
rc = libssh2_session_startup (session, sock);
if (rc != 0) {
fprintf(stderr, "Failed Start the SSH session\n");
return -1;
}
if (set_debug_on == 1)
libssh2_trace(session, LIBSSH2_TRACE_CONN);
/* Set X11 Callback */
libssh2_session_callback_set(session, LIBSSH2_CALLBACK_X11,
(void *)x11_callback);
/* Authenticate via password */
rc = libssh2_userauth_password(session, username, password);
if (rc != 0) {
fprintf(stderr, "Failed to authenticate\n");
session_shutdown(session);
close(sock);
return -1;
}
/* Open a channel */
channel = libssh2_channel_open_session(session);
if ( channel == NULL ) {
fprintf(stderr, "Failed to open a new channel\n");
session_shutdown(session);
close(sock);
return -1;
}
/* Request a PTY */
rc = libssh2_channel_request_pty( channel, "xterm");
if (rc != 0) {
fprintf(stderr, "Failed to request a pty\n");
session_shutdown(session);
close(sock);
return -1;
}
/* Request X11 */
rc = libssh2_channel_x11_req(channel,0);
if(rc!=0) {
fprintf(stderr, "Failed to request X11 forwarding\n");
session_shutdown(session);
close(sock);
return -1;
}
/* Request a shell */
rc = libssh2_channel_shell(channel);
if (rc!=0) {
fprintf(stderr, "Failed to open a shell\n");
session_shutdown(session);
close(sock);
return -1;
}
rc = _raw_mode();
if (rc != 0) {
fprintf(stderr, "Failed to entered in raw mode\n");
session_shutdown(session);
close(sock);
return -1;
}
while (1) {
FD_ZERO(&set);
FD_SET(fileno(stdin),&set);
/* Search if a resize pty has to be send */
ioctl(fileno(stdin), TIOCGWINSZ, &w_size);
if ((w_size.ws_row != w_size_bck.ws_row) ||
(w_size.ws_col != w_size_bck.ws_col)) {
w_size_bck = w_size;
libssh2_channel_request_pty_size(channel,
w_size.ws_col,
w_size.ws_row);
}
if ((buf = calloc (bufsiz, sizeof(char))) == NULL)
break;
if ((fds = malloc (sizeof (LIBSSH2_POLLFD))) == NULL) {
free(buf);
break;
}
fds[0].type = LIBSSH2_POLLFD_CHANNEL;
fds[0].fd.channel = channel;
fds[0].events = LIBSSH2_POLLFD_POLLIN;
fds[0].revents = LIBSSH2_POLLFD_POLLIN;
rc = libssh2_poll(fds, nfds, 0);
if (rc >0) {
rc = libssh2_channel_read(channel, buf,sizeof(buf));
fprintf(stdout, "%s", buf);
fflush(stdout);
}
/* Looping on X clients */
if (gp_x11_chan != NULL) {
current_node = gp_x11_chan;
}
else
current_node = NULL;
while (current_node != NULL) {
rc = x11_send_receive(current_node->chan, current_node->sock);
if (rc == -1){
shutdown(current_node->sock,SHUT_RDWR);
close(current_node->sock);
remove_node(current_node);
}
current_node = current_node->next;
}
rc = select(fileno(stdin)+1,&set,NULL,NULL,&timeval_out);
if (rc > 0) {
/* Data in stdin*/
rc = read(fileno(stdin), buf,1);
if (rc > 0)
libssh2_channel_write(channel,buf, sizeof(buf));
}
free (fds);
free (buf);
if (libssh2_channel_eof (channel) == 1) {
break;
}
}
if (channel) {
libssh2_channel_free (channel);
channel = NULL;
}
_normal_mode();
return 0;
}

View File

@@ -1,4 +1,5 @@
/* Copyright (c) 2004-2008, Sara Golemon <sarag@libssh2.org> /* Copyright (c) 2004-2009, Sara Golemon <sarag@libssh2.org>
* Copyright (c) 2009 by Daniel Stenberg
* All rights reserved. * All rights reserved.
* *
* Redistribution and use in source and binary forms, * Redistribution and use in source and binary forms,
@@ -87,13 +88,13 @@ typedef long long libssh2_int64_t;
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_CVS" #define LIBSSH2_VERSION "1.1.1_CVS"
/* 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 1
#define LIBSSH2_VERSION_PATCH 0 #define LIBSSH2_VERSION_PATCH 1
/* 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
@@ -110,7 +111,7 @@ 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 0x010100 #define LIBSSH2_VERSION_NUM 0x010101
/* /*
* 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
@@ -240,6 +241,7 @@ typedef struct _LIBSSH2_USERAUTH_KBDINT_RESPONSE
typedef struct _LIBSSH2_SESSION LIBSSH2_SESSION; typedef struct _LIBSSH2_SESSION LIBSSH2_SESSION;
typedef struct _LIBSSH2_CHANNEL LIBSSH2_CHANNEL; typedef struct _LIBSSH2_CHANNEL LIBSSH2_CHANNEL;
typedef struct _LIBSSH2_LISTENER LIBSSH2_LISTENER; typedef struct _LIBSSH2_LISTENER LIBSSH2_LISTENER;
typedef struct _LIBSSH2_KNOWNHOSTS LIBSSH2_KNOWNHOSTS;
typedef struct _LIBSSH2_POLLFD { typedef struct _LIBSSH2_POLLFD {
unsigned char type; /* LIBSSH2_POLLFD_* below */ unsigned char type; /* LIBSSH2_POLLFD_* below */
@@ -292,6 +294,11 @@ typedef struct _LIBSSH2_POLLFD {
#define LIBSSH2_HOSTKEY_HASH_MD5 1 #define LIBSSH2_HOSTKEY_HASH_MD5 1
#define LIBSSH2_HOSTKEY_HASH_SHA1 2 #define LIBSSH2_HOSTKEY_HASH_SHA1 2
/* Hostkey Types */
#define LIBSSH2_HOSTKEY_TYPE_UNKNOWN 0
#define LIBSSH2_HOSTKEY_TYPE_RSA 1
#define LIBSSH2_HOSTKEY_TYPE_DSS 2
/* Disconnect Codes (defined by SSH protocol) */ /* Disconnect Codes (defined by SSH protocol) */
#define SSH_DISCONNECT_HOST_NOT_ALLOWED_TO_CONNECT 1 #define SSH_DISCONNECT_HOST_NOT_ALLOWED_TO_CONNECT 1
#define SSH_DISCONNECT_PROTOCOL_ERROR 2 #define SSH_DISCONNECT_PROTOCOL_ERROR 2
@@ -348,6 +355,7 @@ typedef struct _LIBSSH2_POLLFD {
#define LIBSSH2_ERROR_INVALID_POLL_TYPE -35 #define LIBSSH2_ERROR_INVALID_POLL_TYPE -35
#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
/* Session API */ /* Session API */
LIBSSH2_API LIBSSH2_SESSION * LIBSSH2_API LIBSSH2_SESSION *
@@ -377,6 +385,9 @@ LIBSSH2_API int libssh2_session_free(LIBSSH2_SESSION *session);
LIBSSH2_API const char *libssh2_hostkey_hash(LIBSSH2_SESSION *session, LIBSSH2_API const char *libssh2_hostkey_hash(LIBSSH2_SESSION *session,
int hash_type); int hash_type);
LIBSSH2_API const char *libssh2_session_hostkey(LIBSSH2_SESSION *session,
size_t *len, int *type);
LIBSSH2_API int libssh2_session_method_pref(LIBSSH2_SESSION *session, LIBSSH2_API int libssh2_session_method_pref(LIBSSH2_SESSION *session,
int method_type, int method_type,
const char *prefs); const char *prefs);
@@ -663,6 +674,197 @@ LIBSSH2_API int libssh2_base64_decode(LIBSSH2_SESSION *session, char **dest,
LIBSSH2_API 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 */
struct libssh2_knownhost {
unsigned int magic; /* magic stored by the library */
void *node; /* handle to the internal representation of this host */
char *name; /* this is NULL if no plain text host name exists */
char *key; /* key in base64/printable format */
int typemask;
};
/*
* libssh2_knownhost_init
*
* Init a collection of known hosts. Returns the pointer to a collection.
*
*/
LIBSSH2_API LIBSSH2_KNOWNHOSTS *
libssh2_knownhost_init(LIBSSH2_SESSION *session);
/*
* libssh2_knownhost_add
*
* Add a host and its associated key to the collection of known hosts.
*
* The 'type' argument specifies on what format the given host is:
*
* plain - ascii "hostname.domain.tld"
* sha1 - SHA1(<salt> <host>) base64-encoded!
* custom - another hash
*
* If 'sha1' is selected as type, the salt must be provided to the salt
* argument. This too base64 encoded.
*
* The SHA-1 hash is what OpenSSH can be told to use in known_hosts files. If
* a custom type is used, salt is ignored and you must provide the host
* pre-hashed when checking for it in the libssh2_knownhost_check() function.
*
*/
/* host format (2 bits) */
#define LIBSSH2_KNOWNHOST_TYPE_MASK 0xffff
#define LIBSSH2_KNOWNHOST_TYPE_PLAIN 1
#define LIBSSH2_KNOWNHOST_TYPE_SHA1 2 /* always base64 encoded */
#define LIBSSH2_KNOWNHOST_TYPE_CUSTOM 3
/* key format (2 bits) */
#define LIBSSH2_KNOWNHOST_KEYENC_MASK (3<<16)
#define LIBSSH2_KNOWNHOST_KEYENC_RAW (1<<16)
#define LIBSSH2_KNOWNHOST_KEYENC_BASE64 (2<<16)
/* type of key (2 bits) */
#define LIBSSH2_KNOWNHOST_KEY_MASK (3<<18)
#define LIBSSH2_KNOWNHOST_KEY_SHIFT 18
#define LIBSSH2_KNOWNHOST_KEY_RSA1 (1<<18)
#define LIBSSH2_KNOWNHOST_KEY_SSHRSA (2<<18)
#define LIBSSH2_KNOWNHOST_KEY_SSHDSS (3<<18)
LIBSSH2_API int
libssh2_knownhost_add(LIBSSH2_KNOWNHOSTS *hosts,
const char *host,
const char *salt,
const char *key, size_t keylen, int typemask,
struct libssh2_knownhost **store);
/*
* libssh2_knownhost_check
*
* Check a host and its associated key against the collection of known hosts.
*
* The type is the type/format of the given host name.
*
* plain - ascii "hostname.domain.tld"
* custom - prehashed base64 encoded. Note that this cannot use any salts.
*
*
* 'knownhost' may be set to NULL if you don't care about that info.
*
* Returns:
*
* LIBSSH2_KNOWNHOST_CHECK_* values, see below
*
*/
#define LIBSSH2_KNOWNHOST_CHECK_MATCH 0
#define LIBSSH2_KNOWNHOST_CHECK_MISMATCH 1
#define LIBSSH2_KNOWNHOST_CHECK_NOTFOUND 2
#define LIBSSH2_KNOWNHOST_CHECK_FAILURE 3
LIBSSH2_API int
libssh2_knownhost_check(LIBSSH2_KNOWNHOSTS *hosts,
const char *host, const char *key, size_t keylen,
int typemask,
struct libssh2_knownhost **knownhost);
/*
* libssh2_knownhost_del
*
* Remove a host from the collection of known hosts. The 'entry' struct is
* retrieved by a call to libssh2_knownhost_check().
*
*/
LIBSSH2_API int
libssh2_knownhost_del(LIBSSH2_KNOWNHOSTS *hosts,
struct libssh2_knownhost *entry);
/*
* libssh2_knownhost_free
*
* Free an entire collection of known hosts.
*
*/
LIBSSH2_API void
libssh2_knownhost_free(LIBSSH2_KNOWNHOSTS *hosts);
/*
* libssh2_knownhost_readline()
*
* Pass in a line of a file of 'type'. It makes libssh2 read this line.
*
* LIBSSH2_KNOWNHOST_FILE_OPENSSH is the only supported type.
*
*/
LIBSSH2_API int
libssh2_knownhost_readline(LIBSSH2_KNOWNHOSTS *hosts,
const char *line, size_t len, int type);
/*
* libssh2_knownhost_readfile
*
* Add hosts+key pairs from a given file.
*
* Returns a negative value for error or number of successfully added hosts.
*
* This implementation currently only knows one 'type' (openssh), all others
* are reserved for future use.
*/
#define LIBSSH2_KNOWNHOST_FILE_OPENSSH 1
LIBSSH2_API int
libssh2_knownhost_readfile(LIBSSH2_KNOWNHOSTS *hosts,
const char *filename, int type);
/*
* libssh2_knownhost_writeline()
*
* Ask libssh2 to convert a known host to an output line for storage.
*
* Note that this function returns LIBSSH2_ERROR_BUFFER_TOO_SMALL if the given
* output buffer is too small to hold the desired output.
*
* This implementation currently only knows one 'type' (openssh), all others
* are reserved for future use.
*
*/
LIBSSH2_API int
libssh2_knownhost_writeline(LIBSSH2_KNOWNHOSTS *hosts,
struct libssh2_knownhost *known,
char *buffer, size_t buflen,
size_t *outlen, /* the amount of written data */
int type);
/*
* libssh2_knownhost_writefile
*
* Write hosts+key pairs to a given file.
*
* This implementation currently only knows one 'type' (openssh), all others
* are reserved for future use.
*/
LIBSSH2_API int
libssh2_knownhost_writefile(LIBSSH2_KNOWNHOSTS *hosts,
const char *filename, int type);
/*
* libssh2_knownhost_get()
*
* Traverse the internal list of known hosts. Pass NULL to 'prev' to get
* the first one. Or pass a poiner to the previously returned one to get the
* next.
*
* Returns:
* 0 if a fine host was stored in 'store'
* 1 if end of hosts
* [negative] on errors
*/
LIBSSH2_API int
libssh2_knownhost_get(LIBSSH2_KNOWNHOSTS *hosts,
struct libssh2_knownhost **store,
struct libssh2_knownhost *prev);
/* NOTE NOTE NOTE /* NOTE NOTE NOTE
libssh2_trace() has no function in builds that aren't built with debug libssh2_trace() has no function in builds that aren't built with debug

View File

@@ -46,6 +46,8 @@
#ifndef LIBSSH2_PUBLICKEY_H #ifndef LIBSSH2_PUBLICKEY_H
#define LIBSSH2_PUBLICKEY_H 1 #define LIBSSH2_PUBLICKEY_H 1
#include "libssh2.h"
typedef struct _LIBSSH2_PUBLICKEY LIBSSH2_PUBLICKEY; typedef struct _LIBSSH2_PUBLICKEY LIBSSH2_PUBLICKEY;
typedef struct _libssh2_publickey_attribute { typedef struct _libssh2_publickey_attribute {

View File

@@ -38,6 +38,8 @@
#ifndef LIBSSH2_SFTP_H #ifndef LIBSSH2_SFTP_H
#define LIBSSH2_SFTP_H 1 #define LIBSSH2_SFTP_H 1
#include "libssh2.h"
#ifndef WIN32 #ifndef WIN32
#include <unistd.h> #include <unistd.h>
#endif #endif

5
m4/.gitignore vendored Normal file
View File

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

View File

@@ -5,7 +5,7 @@
## ##
## Comments to: Guenter Knauf <eflash@gmx.net> ## Comments to: Guenter Knauf <eflash@gmx.net>
## ##
## $Id: Makefile.netware,v 1.13 2009/03/06 07:25:37 gknauf Exp $ ## $Id: Makefile.netware,v 1.14 2009/04/09 03:13:51 gknauf Exp $
# #
######################################################################### #########################################################################
@@ -21,7 +21,7 @@ endif
# Edit the path below to point to the base of your OpenSSL package. # Edit the path below to point to the base of your OpenSSL package.
ifndef OPENSSL_PATH ifndef OPENSSL_PATH
OPENSSL_PATH = ../../openssl-0.9.8j OPENSSL_PATH = ../../openssl-0.9.8k
endif endif
# Edit the path below to point to your Distribution folder. # Edit the path below to point to your Distribution folder.
@@ -76,7 +76,7 @@ ifdef METROWERKS
MWCW_PATH = $(subst \,/,$(METROWERKS))/Novell Support/Metrowerks Support MWCW_PATH = $(subst \,/,$(METROWERKS))/Novell Support/Metrowerks Support
CC = mwccnlm CC = mwccnlm
else else
CC = gcc CC = $(CROSSPREFIX)gcc
endif endif
CP = cp -afv CP = cp -afv
# RM = rm -f # RM = rm -f
@@ -119,12 +119,12 @@ else
CFLAGS += -align 1 CFLAGS += -align 1
endif endif
else else
LD = nlmconv LD = $(CROSSPREFIX)nlmconv
LDFLAGS = -T LDFLAGS = -T
AR = ar AR = $(CROSSPREFIX)ar
ARFLAGS = -cq ARFLAGS = -cq
LIBEXT = a LIBEXT = a
RANLIB = ranlib RANLIB = $(CROSSPREFIX)ranlib
CFLAGS += -fno-builtin -fpcc-struct-return -fno-strict-aliasing CFLAGS += -fno-builtin -fpcc-struct-return -fno-strict-aliasing
CFLAGS += -Wall # -pedantic CFLAGS += -Wall # -pedantic
#CFLAGS += -Wno-pointer-sign #CFLAGS += -Wno-pointer-sign

View File

@@ -5,7 +5,7 @@
## ##
## Comments to: Guenter Knauf <eflash@gmx.net> ## Comments to: Guenter Knauf <eflash@gmx.net>
## ##
## $Id: Makefile.netware,v 1.9 2009/03/06 07:25:37 gknauf Exp $ ## $Id: Makefile.netware,v 1.10 2009/04/09 03:13:52 gknauf Exp $
# #
######################################################################### #########################################################################
@@ -21,7 +21,7 @@ endif
# Edit the path below to point to the base of your OpenSSL package. # Edit the path below to point to the base of your OpenSSL package.
ifndef OPENSSL_PATH ifndef OPENSSL_PATH
OPENSSL_PATH = ../../../openssl-0.9.8j OPENSSL_PATH = ../../../openssl-0.9.8k
endif endif
# Edit the var below to enable static linking of libssh2 and libz # Edit the var below to enable static linking of libssh2 and libz
@@ -70,7 +70,7 @@ ifdef METROWERKS
MWCW_PATH = $(subst \,/,$(METROWERKS))/Novell Support/Metrowerks Support MWCW_PATH = $(subst \,/,$(METROWERKS))/Novell Support/Metrowerks Support
CC = mwccnlm CC = mwccnlm
else else
CC = gcc CC = $(CROSSPREFIX)gcc
endif endif
CP = cp -afv CP = cp -afv
# RM = rm -f # RM = rm -f
@@ -131,7 +131,7 @@ SDK_CLIB = $(NDK_ROOT)/nwsdk
SDK_LIBC = $(NDK_ROOT)/libc SDK_LIBC = $(NDK_ROOT)/libc
SNPRINTF = $(NDKBASE)/snprintf SNPRINTF = $(NDKBASE)/snprintf
INCLUDES = -I. -I../../include INCLUDES = -I.. -I../../include
LDLIBS = LDLIBS =

3
src/.gitignore vendored Normal file
View File

@@ -0,0 +1,3 @@
libssh2_config.h
libssh2_config.h.in
stamp-h1

View File

@@ -1,15 +1,10 @@
# $Id: Makefile.am,v 1.19 2009/03/26 22:25:23 bagder Exp $ # $Id: Makefile.am,v 1.21 2009/05/07 17:21:56 bagder Exp $
AUTOMAKE_OPTIONS = foreign nostdinc AUTOMAKE_OPTIONS = foreign nostdinc
libssh2_la_SOURCES = channel.c comp.c crypt.c hostkey.c kex.c mac.c misc.c \ # Makefile.inc provides the CSOURCES and HHEADERS defines
packet.c publickey.c scp.c session.c sftp.c userauth.c libssh2_priv.h \ include ../Makefile.inc
openssl.h libgcrypt.h transport.c version.c transport.h channel.h comp.h mac.h
if LIBGCRYPT libssh2_la_SOURCES = $(CSOURCES) $(HHEADERS)
libssh2_la_SOURCES += libgcrypt.c pem.c
else
libssh2_la_SOURCES += openssl.c
endif
EXTRA_DIST = libssh2_config.h.in NMakefile EXTRA_DIST = libssh2_config.h.in NMakefile

View File

@@ -45,6 +45,7 @@
#ifdef HAVE_INTTYPES_H #ifdef HAVE_INTTYPES_H
#include <inttypes.h> #include <inttypes.h>
#endif #endif
#include <assert.h>
#include "channel.h" #include "channel.h"
#include "transport.h" #include "transport.h"
@@ -90,12 +91,21 @@ _libssh2_channel_nextid(LIBSSH2_SESSION * session)
LIBSSH2_CHANNEL * 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 = session->channels.head; LIBSSH2_CHANNEL *channel;
while (channel) { LIBSSH2_LISTENER *listener;
if (channel->local.id == channel_id) {
for(channel = session->channels.head; channel; channel = channel->next) {
if (channel->local.id == channel_id)
return channel;
}
/* We didn't find the channel in the session, let's then check its
listeners... */
for(listener = session->listeners; listener; listener = listener->next) {
for(channel = listener->queue; channel; channel = channel->next) {
if (channel->local.id == channel_id)
return channel; return channel;
} }
channel = channel->next;
} }
return NULL; return NULL;
@@ -779,6 +789,8 @@ channel_forward_accept(LIBSSH2_LISTENER *listener)
return channel; return channel;
} }
libssh2_error(listener->session, LIBSSH2_ERROR_CHANNEL_UNKNOWN,
"Channel not found", 0);
return NULL; return NULL;
} }
@@ -1758,29 +1770,19 @@ static ssize_t channel_read(LIBSSH2_CHANNEL *channel, int stream_id,
"stream #%d", "stream #%d",
(int) buflen, channel->local.id, channel->remote.id, (int) buflen, channel->local.id, channel->remote.id,
stream_id); stream_id);
channel->read_state = libssh2_NB_state_created;
}
rc = 1; /* set to >0 to let the while loop start */ rc = 1; /* set to >0 to let the while loop start */
/* process all pending incoming packets */ /* Process all pending incoming packets in all states in order to "even
out" the network readings. Tests prove that this way produces faster
transfers. */
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; return -1;
channel->read_state = libssh2_NB_state_created;
}
else {
/* We're not in the idle state, but in order to "even out" the network
readings we do a single shot read here as well. Tests prove that
this way produces faster transfers. */
rc = _libssh2_transport_read(session);
/* ignore PACKET_EAGAIN but return failure for the rest */
if ((rc < 0) && (rc != PACKET_EAGAIN))
return -1;
}
/* /*
* =============================== NOTE =============================== * =============================== NOTE ===============================
* I know this is very ugly and not a really good use of "goto", but * I know this is very ugly and not a really good use of "goto", but
@@ -1794,8 +1796,15 @@ static ssize_t channel_read(LIBSSH2_CHANNEL *channel, int stream_id,
channel->read_packet = session->packets.head; channel->read_packet = session->packets.head;
while (channel->read_packet && while (channel->read_packet &&
!channel->remote.close &&
(bytes_read < (int) buflen)) { (bytes_read < (int) buflen)) {
/* previously this loop condition also checked for
!channel->remote.close but we cannot let it do this:
We may have a series of packets to read that are still pending even
if a close has been received. Acknowledging the close too early
makes us flush buffers prematurely and loose data.
*/
LIBSSH2_PACKET *readpkt = channel->read_packet; LIBSSH2_PACKET *readpkt = channel->read_packet;
/* In case packet gets destroyed during this iteration */ /* In case packet gets destroyed during this iteration */
@@ -1989,7 +1998,9 @@ _libssh2_channel_packet_data_len(LIBSSH2_CHANNEL * channel, int stream_id)
/* /*
* _libssh2_channel_write * _libssh2_channel_write
* *
* Send data to a channel * Send data to a channel. Note that if this returns EAGAIN or simply didn't
* send the entire packet, the caller must call this function again with the
* SAME input arguments.
*/ */
ssize_t ssize_t
_libssh2_channel_write(LIBSSH2_CHANNEL *channel, int stream_id, _libssh2_channel_write(LIBSSH2_CHANNEL *channel, int stream_id,
@@ -1997,6 +2008,7 @@ _libssh2_channel_write(LIBSSH2_CHANNEL *channel, int stream_id,
{ {
LIBSSH2_SESSION *session = channel->session; LIBSSH2_SESSION *session = channel->session;
libssh2pack_t rc; libssh2pack_t rc;
ssize_t wrote = 0; /* counter for this specific this call */
if (channel->write_state == libssh2_NB_state_idle) { if (channel->write_state == libssh2_NB_state_idle) {
channel->write_bufwrote = 0; channel->write_bufwrote = 0;
@@ -2052,29 +2064,19 @@ _libssh2_channel_write(LIBSSH2_CHANNEL *channel, int stream_id,
channel->write_s += 4; channel->write_s += 4;
} }
/* twiddle our thumbs until there's window space available */ /* drain the incoming flow first */
while (channel->local.window_size <= 0) { do
/* Don't worry -- This is never hit unless it's a
blocking channel anyway */
rc = _libssh2_transport_read(session); rc = _libssh2_transport_read(session);
while (rc > 0);
if (rc < 0) { if(channel->local.window_size <= 0) {
/* Error or EAGAIN occurred, disconnect? */ /* there's no more room for data so we stop sending now */
if (rc != PACKET_EAGAIN) { if(!wrote) {
LIBSSH2_FREE(session, channel->write_packet); /* if nothing has been written at this point we're at an
channel->write_state = libssh2_NB_state_idle; EAGAIN point */
}
return rc;
}
if (rc == 0) {
/*
* if rc == 0, then fake EAGAIN to prevent busyloops until
* data arriaves on the network which seemed like a very
* bad idea
*/
return PACKET_EAGAIN; return PACKET_EAGAIN;
} }
break;
} }
/* Don't exceed the remote end's limits */ /* Don't exceed the remote end's limits */
@@ -2132,15 +2134,9 @@ _libssh2_channel_write(LIBSSH2_CHANNEL *channel, int stream_id,
buflen -= channel->write_bufwrite; buflen -= channel->write_bufwrite;
buf += channel->write_bufwrite; buf += channel->write_bufwrite;
channel->write_bufwrote += channel->write_bufwrite; channel->write_bufwrote += channel->write_bufwrite;
wrote += channel->write_bufwrite;
channel->write_state = libssh2_NB_state_allocated; channel->write_state = libssh2_NB_state_allocated;
/*
* Not sure this is still wanted
if (!channel->session->socket_block) {
break;
}
*/
} }
} }
@@ -2149,7 +2145,7 @@ _libssh2_channel_write(LIBSSH2_CHANNEL *channel, int stream_id,
channel->write_state = libssh2_NB_state_idle; channel->write_state = libssh2_NB_state_idle;
return channel->write_bufwrote; return wrote;
} }
/* /*
@@ -2440,6 +2436,8 @@ int _libssh2_channel_free(LIBSSH2_CHANNEL *channel)
unsigned long data_len; unsigned long data_len;
int rc; int rc;
assert(session);
if (channel->free_state == libssh2_NB_state_idle) { if (channel->free_state == libssh2_NB_state_idle) {
_libssh2_debug(session, LIBSSH2_DBG_CONN, _libssh2_debug(session, LIBSSH2_DBG_CONN,
"Freeing channel %lu/%lu resources", channel->local.id, "Freeing channel %lu/%lu resources", channel->local.id,

View File

@@ -1,4 +1,5 @@
/* Copyright (c) 2004-2006, Sara Golemon <sarag@libssh2.org> /* Copyright (c) 2004-2006, Sara Golemon <sarag@libssh2.org>
* Copyright (c) 2009 by Daniel Stenberg
* All rights reserved. * All rights reserved.
* *
* Redistribution and use in source and binary forms, * Redistribution and use in source and binary forms,
@@ -36,6 +37,7 @@
*/ */
#include "libssh2_priv.h" #include "libssh2_priv.h"
#include "misc.h"
/* Needed for struct iovec on some platforms */ /* Needed for struct iovec on some platforms */
#ifdef HAVE_SYS_UIO_H #ifdef HAVE_SYS_UIO_H
@@ -453,3 +455,47 @@ libssh2_hostkey_hash(LIBSSH2_SESSION * session, int hash_type)
return NULL; return NULL;
} }
} }
static int hostkey_type(const unsigned char *hostkey, size_t len)
{
const unsigned char rsa[] = {
0, 0, 0, 0x07, 's', 's', 'h', '-', 'r', 's', 'a'
};
const unsigned char dss[] = {
0, 0, 0, 0x07, 's', 's', 'h', '-', 'd', 's', 's'
};
if (len < 11)
return LIBSSH2_HOSTKEY_TYPE_UNKNOWN;
if (!memcmp(rsa, hostkey, 11))
return LIBSSH2_HOSTKEY_TYPE_RSA;
if (!memcmp(dss, hostkey, 11))
return LIBSSH2_HOSTKEY_TYPE_DSS;
return LIBSSH2_HOSTKEY_TYPE_UNKNOWN;
}
/*
* libssh2_session_hostkey()
*
* Returns the server key and length.
*
*/
LIBSSH2_API const char *
libssh2_session_hostkey(LIBSSH2_SESSION *session, size_t *len, int *type)
{
if(session->server_hostkey_len) {
if(len)
*len = session->server_hostkey_len;
if (type)
*type = hostkey_type(session->server_hostkey,
session->server_hostkey_len);
return (char *) session->server_hostkey;
}
if(len)
*len = 0;
return NULL;
}

View File

@@ -641,11 +641,6 @@ kex_method_diffie_hellman_groupGP_sha1_key_exchange(LIBSSH2_SESSION *session,
exchange_state->k_value = NULL; exchange_state->k_value = NULL;
} }
if (session->server_hostkey) {
LIBSSH2_FREE(session, session->server_hostkey);
session->server_hostkey = NULL;
}
exchange_state->state = libssh2_NB_state_idle; exchange_state->state = libssh2_NB_state_idle;
return ret; return ret;

843
src/knownhost.c Normal file
View File

@@ -0,0 +1,843 @@
/*
* Copyright (c) 2009 by Daniel Stenberg
* All rights reserved.
*
* Redistribution and use in source and binary forms,
* with or without modification, are permitted provided
* that the following conditions are met:
*
* Redistributions of source code must retain the above
* copyright notice, this list of conditions and the
* following disclaimer.
*
* Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following
* disclaimer in the documentation and/or other materials
* provided with the distribution.
*
* Neither the name of the copyright holder nor the names
* of any other contributors may be used to endorse or
* promote products derived from this software without
* specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
* CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
* USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
* OF SUCH DAMAGE.
*/
#include "libssh2_priv.h"
#include "misc.h"
struct known_host {
struct list_node node;
char *name; /* points to the name or the hash (allocated) */
size_t name_len; /* needed for hashed data */
int typemask; /* plain, sha1, custom, ... */
char *salt; /* points to binary salt (allocated) */
size_t salt_len; /* size of salt */
char *key; /* the (allocated) associated key. This is kept base64
encoded in memory. */
/* this is the struct we expose externally */
struct libssh2_knownhost external;
};
struct _LIBSSH2_KNOWNHOSTS
{
LIBSSH2_SESSION *session; /* the session this "belongs to" */
struct list_head head;
};
static void free_host(LIBSSH2_SESSION *session, struct known_host *entry)
{
if(entry) {
if(entry->key)
LIBSSH2_FREE(session, entry->key);
if(entry->salt)
LIBSSH2_FREE(session, entry->salt);
if(entry->name)
LIBSSH2_FREE(session, entry->name);
LIBSSH2_FREE(session, entry);
}
}
/*
* libssh2_knownhost_init
*
* Init a collection of known hosts. Returns the pointer to a collection.
*
*/
LIBSSH2_API LIBSSH2_KNOWNHOSTS *
libssh2_knownhost_init(LIBSSH2_SESSION *session)
{
LIBSSH2_KNOWNHOSTS *knh =
LIBSSH2_ALLOC(session, sizeof(struct _LIBSSH2_KNOWNHOSTS));
if(!knh)
return NULL;
knh->session = session;
_libssh2_list_init(&knh->head);
return knh;
}
#define KNOWNHOST_MAGIC 0xdeadcafe
/*
* knownhost_to_external()
*
* Copies data from the internal to the external representation struct.
*
*/
static struct libssh2_knownhost *knownhost_to_external(struct known_host *node)
{
struct libssh2_knownhost *ext = &node->external;
ext->magic = KNOWNHOST_MAGIC;
ext->node = node;
ext->name = ((node->typemask & LIBSSH2_KNOWNHOST_TYPE_MASK) ==
LIBSSH2_KNOWNHOST_TYPE_PLAIN)? node->name:NULL;
ext->key = node->key;
ext->typemask = node->typemask;
return ext;
}
/*
* libssh2_knownhost_add
*
* Add a host and its associated key to the collection of known hosts.
*
* The 'type' argument specifies on what format the given host and keys are:
*
* plain - ascii "hostname.domain.tld"
* sha1 - SHA1(<salt> <host>) base64-encoded!
* custom - another hash
*
* If 'sha1' is selected as type, the salt must be provided to the salt
* argument. This too base64 encoded.
*
* The SHA-1 hash is what OpenSSH can be told to use in known_hosts files. If
* a custom type is used, salt is ignored and you must provide the host
* pre-hashed when checking for it in the libssh2_knownhost_check() function.
*
*/
LIBSSH2_API int
libssh2_knownhost_add(LIBSSH2_KNOWNHOSTS *hosts,
const char *host, const char *salt,
const char *key, size_t keylen,
int typemask, struct libssh2_knownhost **store)
{
struct known_host *entry =
LIBSSH2_ALLOC(hosts->session, sizeof(struct known_host));
size_t hostlen = strlen(host);
int rc = LIBSSH2_ERROR_ALLOC;
char *ptr;
unsigned int ptrlen;
if(!entry)
return rc;
if(!(typemask & LIBSSH2_KNOWNHOST_KEY_MASK))
/* make sure we have a key type set */
return LIBSSH2_ERROR_INVAL;
memset(entry, 0, sizeof(struct known_host));
entry->typemask = typemask;
switch(entry->typemask & LIBSSH2_KNOWNHOST_TYPE_MASK) {
case LIBSSH2_KNOWNHOST_TYPE_PLAIN:
case LIBSSH2_KNOWNHOST_TYPE_CUSTOM:
entry->name = LIBSSH2_ALLOC(hosts->session, hostlen+1);
if(!entry)
goto error;
memcpy(entry->name, host, hostlen+1);
break;
case LIBSSH2_KNOWNHOST_TYPE_SHA1:
rc = libssh2_base64_decode(hosts->session, &ptr, &ptrlen,
host, hostlen);
if(rc)
goto error;
entry->name = ptr;
entry->name_len = ptrlen;
rc = libssh2_base64_decode(hosts->session, &ptr, &ptrlen,
salt, strlen(salt));
if(rc)
goto error;
entry->salt = ptr;
entry->salt_len = ptrlen;
break;
default:
rc = LIBSSH2_ERROR_METHOD_NOT_SUPPORTED;
goto error;
}
if(typemask & LIBSSH2_KNOWNHOST_KEYENC_BASE64) {
/* the provided key is base64 encoded already */
if(!keylen)
keylen = strlen(key);
entry->key = LIBSSH2_ALLOC(hosts->session, keylen+1);
if(!entry)
goto error;
memcpy(entry->key, key, keylen+1);
entry->key[keylen]=0; /* force a terminating zero trailer */
}
else {
/* key is raw, we base64 encode it and store it as such */
size_t nlen = _libssh2_base64_encode(hosts->session, key, keylen,
&ptr);
if(!nlen)
goto error;
entry->key = ptr;
}
/* add this new host to the big list of known hosts */
_libssh2_list_add(&hosts->head, &entry->node);
if(store)
*store = knownhost_to_external(entry);
return LIBSSH2_ERROR_NONE;
error:
free_host(hosts->session, entry);
return rc;
}
/*
* libssh2_knownhost_check
*
* Check a host and its associated key against the collection of known hosts.
*
* The typemask is the type/format of the given host name and key
*
* plain - ascii "hostname.domain.tld"
* sha1 - NOT SUPPORTED AS INPUT
* custom - prehashed base64 encoded. Note that this cannot use any salts.
*
* Returns:
*
* LIBSSH2_KNOWNHOST_CHECK_FAILURE
* LIBSSH2_KNOWNHOST_CHECK_NOTFOUND
* LIBSSH2_KNOWNHOST_CHECK_MATCH
* LIBSSH2_KNOWNHOST_CHECK_MISMATCH
*/
LIBSSH2_API int
libssh2_knownhost_check(LIBSSH2_KNOWNHOSTS *hosts,
const char *host, const char *key, size_t keylen,
int typemask,
struct libssh2_knownhost **ext)
{
struct known_host *node = _libssh2_list_first(&hosts->head);
struct known_host *badkey = NULL;
int type = typemask & LIBSSH2_KNOWNHOST_TYPE_MASK;
char *keyalloc = NULL;
int rc = LIBSSH2_KNOWNHOST_CHECK_NOTFOUND;
if(type == LIBSSH2_KNOWNHOST_TYPE_SHA1)
/* we can't work with a sha1 as given input */
return LIBSSH2_KNOWNHOST_CHECK_MISMATCH;
if(!(typemask & LIBSSH2_KNOWNHOST_KEYENC_BASE64)) {
/* we got a raw key input, convert it to base64 for the checks below */
size_t nlen = _libssh2_base64_encode(hosts->session, key, keylen,
&keyalloc);
if(!nlen)
return LIBSSH2_KNOWNHOST_CHECK_FAILURE;
/* make the key point to this */
key = keyalloc;
keylen = nlen;
}
while (node) {
int match = 0;
switch(node->typemask & LIBSSH2_KNOWNHOST_TYPE_MASK) {
case LIBSSH2_KNOWNHOST_TYPE_PLAIN:
if(type == LIBSSH2_KNOWNHOST_TYPE_PLAIN)
match = !strcmp(host, node->name);
break;
case LIBSSH2_KNOWNHOST_TYPE_CUSTOM:
if(type == LIBSSH2_KNOWNHOST_TYPE_CUSTOM)
match = !strcmp(host, node->name);
break;
case LIBSSH2_KNOWNHOST_TYPE_SHA1:
if(type == LIBSSH2_KNOWNHOST_TYPE_PLAIN) {
/* when we have the sha1 version stored, we can use a plain
input to produce a hash to compare with the stored hash.
*/
libssh2_hmac_ctx ctx;
unsigned char hash[SHA_DIGEST_LENGTH];
if(SHA_DIGEST_LENGTH != node->name_len) {
/* the name hash length must be the sha1 size or
we can't match it */
break;
}
libssh2_hmac_sha1_init(&ctx, node->salt, node->salt_len);
libssh2_hmac_update(ctx, (unsigned char *)host, strlen(host));
libssh2_hmac_final(ctx, hash);
libssh2_hmac_cleanup(&ctx);
if(!memcmp(hash, node->name, SHA_DIGEST_LENGTH))
/* this is a node we're interested in */
match = 1;
}
break;
default: /* unsupported type */
break;
}
if(match) {
/* host name match, now compare the keys */
if(!strcmp(key, node->key)) {
/* they match! */
*ext = knownhost_to_external(node);
badkey = NULL;
rc = LIBSSH2_KNOWNHOST_CHECK_MATCH;
break;
}
else {
/* remember the first node that had a host match but a failed
key match since we continue our search from here */
if(!badkey)
badkey = node;
}
}
node= _libssh2_list_next(&node->node);
}
if(badkey) {
/* key mismatch */
*ext = knownhost_to_external(badkey);
rc = LIBSSH2_KNOWNHOST_CHECK_MISMATCH;
}
if(keyalloc)
LIBSSH2_FREE(hosts->session, keyalloc);
return rc;
}
/*
* libssh2_knownhost_del
*
* Remove a host from the collection of known hosts.
*
*/
LIBSSH2_API int
libssh2_knownhost_del(LIBSSH2_KNOWNHOSTS *hosts,
struct libssh2_knownhost *entry)
{
struct known_host *node;
if(!entry || (entry->magic != KNOWNHOST_MAGIC))
/* check that this was retrieved the right way or get out */
return LIBSSH2_ERROR_INVAL;
/* get the internal node pointer */
node = entry->node;
/* unlink from the list of all hosts */
_libssh2_list_remove(&node->node);
/* free all resources */
free_host(hosts->session, node);
/* clear the struct now since this host entry has been removed! */
memset(entry, 0, sizeof(struct libssh2_knownhost));
return 0;
}
/*
* libssh2_knownhost_free
*
* Free an entire collection of known hosts.
*
*/
LIBSSH2_API void
libssh2_knownhost_free(LIBSSH2_KNOWNHOSTS *hosts)
{
struct known_host *node;
struct known_host *next;
for(node = _libssh2_list_first(&hosts->head); node; node = next) {
next = _libssh2_list_next(&node->node);
free_host(hosts->session, node);
}
LIBSSH2_FREE(hosts->session, hosts);
}
/*
* hostline()
*
* Parse a single known_host line pre-split into host and key.
*
*/
static int hostline(LIBSSH2_KNOWNHOSTS *hosts,
const char *host, size_t hostlen,
const char *key, size_t keylen)
{
const char *p;
const char *orig = host;
const char *salt = NULL;
int rc;
int type = LIBSSH2_KNOWNHOST_TYPE_PLAIN;
const char *sep = NULL;
size_t seplen = 0;
char saltbuf[32];
char hostbuf[256];
/* Figure out host format */
if((hostlen >2) && memcmp(host, "|1|", 3)) {
/* old style plain text: [name][,][ip-address]
for the sake of simplicity, we add them as two hosts with the same
key
*/
size_t scan = hostlen;
while(scan && (*host != ',')) {
host++;
scan--;
}
if(scan) {
sep = host+1;
seplen = scan-1;
hostlen -= scan; /* deduct what's left to scan from the first
host name */
}
else
host = orig;
}
else {
/* |1|[salt]|[hash] */
type = LIBSSH2_KNOWNHOST_TYPE_SHA1;
salt = &host[3]; /* skip the magic marker */
hostlen -= 3; /* deduct the marker */
/* this is where the salt starts, find the end of it */
for(p = salt; *p && (*p != '|'); p++)
;
if(*p=='|') {
const char *hash = NULL;
size_t saltlen = p - salt;
if(saltlen >= (sizeof(saltbuf)-1))
return LIBSSH2_ERROR_METHOD_NOT_SUPPORTED; /* weird length */
memcpy(saltbuf, salt, saltlen);
saltbuf[saltlen] = 0; /* zero terminate */
salt = saltbuf; /* point to the stack based buffer */
hash = p+1; /* the host hash is after the separator */
/* now make the host point to the hash */
host = hash;
hostlen -= saltlen+1; /* deduct the salt and separator */
}
else
return 0;
}
/* make some checks that the lenghts seem sensible */
if((keylen < 20) ||
(seplen >= sizeof(hostbuf)-1) ||
(hostlen >= sizeof(hostbuf)-1))
return LIBSSH2_ERROR_METHOD_NOT_SUPPORTED;
switch(key[0]) {
case '0': case '1': case '2': case '3': case '4':
case '5': case '6': case '7': case '8': case '9':
type |= LIBSSH2_KNOWNHOST_KEY_RSA1;
/* Note that the old-style keys (RSA1) aren't truly base64, but we
* claim it is for now since we can get away with strcmp()ing the
* entire anything anyway! We need to check and fix these to make them
* work properly.
*/
break;
case 's': /* ssh-dss or ssh-rsa */
if(!strncmp(key, "ssh-dss", 7))
type |= LIBSSH2_KNOWNHOST_KEY_SSHDSS;
else if(!strncmp(key, "ssh-rsa", 7))
type |= LIBSSH2_KNOWNHOST_KEY_SSHRSA;
else
return LIBSSH2_ERROR_METHOD_NOT_SUPPORTED; /* unknown key type */
key += 7;
keylen -= 7;
/* skip whitespaces */
while((*key ==' ') || (*key == '\t')) {
key++;
keylen--;
}
break;
default: /* unknown key format */
return LIBSSH2_ERROR_METHOD_NOT_SUPPORTED;
}
if(sep) {
/* The second host after the comma, add this first. Copy it to the
temp buffer and zero terminate */
memcpy(hostbuf, sep, seplen);
hostbuf[seplen]=0;
rc = libssh2_knownhost_add(hosts, hostbuf, salt, key, keylen,
type | LIBSSH2_KNOWNHOST_KEYENC_BASE64,
NULL);
if(rc)
return rc;
}
if (!salt)
host = orig;
memcpy(hostbuf, host, hostlen);
hostbuf[hostlen]=0;
rc = libssh2_knownhost_add(hosts, hostbuf, salt, key, keylen,
type | LIBSSH2_KNOWNHOST_KEYENC_BASE64,
NULL);
return rc;
}
/*
* libssh2_knownhost_readline()
*
* Pass in a line of a file of 'type'.
*
* LIBSSH2_KNOWNHOST_FILE_OPENSSH is the only supported type.
*
* OpenSSH line format:
*
* <host> <key>
*
* Where the two parts can be created like:
*
* <host> can be either
* <name> or <hash>
*
* <name> consists of
* [name,address] or just [name] or just [address]
*
* <hash> consists of
* |1|<salt>|hash
*
* <key> can be one of:
* [RSA bits] [e] [n as a decimal number]
* 'ssh-dss' [base64-encoded-key]
* 'ssh-rsa' [base64-encoded-key]
*
*/
LIBSSH2_API int
libssh2_knownhost_readline(LIBSSH2_KNOWNHOSTS *hosts,
const char *line, size_t len, int type)
{
const char *cp;
const char *hostp;
const char *keyp;
size_t hostlen;
size_t keylen;
int rc;
if(type != LIBSSH2_KNOWNHOST_FILE_OPENSSH)
return LIBSSH2_ERROR_METHOD_NOT_SUPPORTED;
cp = line;
/* skip leading whitespaces */
while(len && ((*cp==' ') || (*cp == '\t'))) {
cp++;
len--;
}
if(!len || !*cp || (*cp == '#') || (*cp == '\n'))
/* comment or empty line */
return LIBSSH2_ERROR_NONE;
/* the host part starts here */
hostp = cp;
/* move over the host to the separator */
while(len && *cp && (*cp!=' ') && (*cp != '\t')) {
cp++;
len--;
}
hostlen = cp - hostp;
/* the key starts after the whitespaces */
while(len && *cp && ((*cp==' ') || (*cp == '\t'))) {
cp++;
len--;
}
if(!*cp || !len)
/* illegal line */
return LIBSSH2_ERROR_METHOD_NOT_SUPPORTED;
keyp = cp; /* the key starts here */
keylen = len;
/* check if the line (key) ends with a newline and if so kill it */
while(len && *cp && (*cp != '\n')) {
cp++;
len--;
}
/* zero terminate where the newline is */
if(*cp == '\n')
keylen--; /* don't include this in the count */
/* deal with this one host+key line */
rc = hostline(hosts, hostp, hostlen, keyp, keylen);
if(rc)
return rc; /* failed */
return LIBSSH2_ERROR_NONE; /* success */
}
/*
* libssh2_knownhost_readfile
*
* Read hosts+key pairs from a given file.
*
* Returns a negative value for error or number of successfully added hosts.
*
*/
LIBSSH2_API int
libssh2_knownhost_readfile(LIBSSH2_KNOWNHOSTS *hosts,
const char *filename, int type)
{
FILE *file;
int num = 0;
char buf[2048];
if(type != LIBSSH2_KNOWNHOST_FILE_OPENSSH)
return LIBSSH2_ERROR_METHOD_NOT_SUPPORTED;
file = fopen(filename, "r");
if(file) {
while(fgets(buf, sizeof(buf), file)) {
if(libssh2_knownhost_readline(hosts, buf, strlen(buf), type))
break;
num++;
}
fclose(file);
}
else
return LIBSSH2_ERROR_FILE;
return num;
}
/*
* knownhost_writeline()
*
* Ask libssh2 to convert a known host to an output line for storage.
*
* Note that this function returns LIBSSH2_ERROR_BUFFER_TOO_SMALL if the given
* output buffer is too small to hold the desired output. The 'outlen' field
* will then contain the size libssh2 wanted to store, which then is the
* smallest sufficient buffer it would require.
*
*/
static int
knownhost_writeline(LIBSSH2_KNOWNHOSTS *hosts,
struct known_host *node,
char *buf, size_t buflen,
size_t *outlen, int type)
{
int rc = LIBSSH2_ERROR_NONE;
int tindex;
const char *keytypes[4]={
"", /* not used */
"", /* this type has no name in the file */
" ssh-rsa",
" ssh-dss"
};
const char *keytype;
size_t nlen;
/* we only support this single file type for now, bail out on all other
attempts */
if(type != LIBSSH2_KNOWNHOST_FILE_OPENSSH)
return LIBSSH2_ERROR_METHOD_NOT_SUPPORTED;
tindex = (node->typemask & LIBSSH2_KNOWNHOST_KEY_MASK) >>
LIBSSH2_KNOWNHOST_KEY_SHIFT;
/* set the string used in the file */
keytype = keytypes[tindex];
if((node->typemask & LIBSSH2_KNOWNHOST_TYPE_MASK) ==
LIBSSH2_KNOWNHOST_TYPE_SHA1) {
char *namealloc;
char *saltalloc;
nlen = _libssh2_base64_encode(hosts->session, node->name,
node->name_len, &namealloc);
if(!nlen)
return LIBSSH2_ERROR_ALLOC;
nlen = _libssh2_base64_encode(hosts->session,
node->salt, node->salt_len,
&saltalloc);
if(!nlen) {
free(namealloc);
return LIBSSH2_ERROR_ALLOC;
}
nlen = strlen(saltalloc) + strlen(namealloc) + strlen(keytype) +
strlen(node->key) + 7; /* |1| + | + ' ' + \n + \0 = 7 */
if(nlen <= buflen)
sprintf(buf, "|1|%s|%s%s %s\n", saltalloc, namealloc, keytype,
node->key);
else
rc = LIBSSH2_ERROR_BUFFER_TOO_SMALL;
free(namealloc);
free(saltalloc);
}
else {
nlen = strlen(node->name) + strlen(keytype) + strlen(node->key) + 3;
/* ' ' + '\n' + \0 = 3 */
if(nlen <= buflen)
/* these types have the plain name */
sprintf(buf, "%s%s %s\n", node->name, keytype, node->key);
else
rc = LIBSSH2_ERROR_BUFFER_TOO_SMALL;
}
/* we report the full length of the data with the trailing zero excluded */
*outlen = nlen-1;
return rc;
}
/*
* libssh2_knownhost_writeline()
*
* Ask libssh2 to convert a known host to an output line for storage.
*
* Note that this function returns LIBSSH2_ERROR_BUFFER_TOO_SMALL if the given
* output buffer is too small to hold the desired output.
*/
LIBSSH2_API int
libssh2_knownhost_writeline(LIBSSH2_KNOWNHOSTS *hosts,
struct libssh2_knownhost *known,
char *buffer, size_t buflen,
size_t *outlen, /* the amount of written data */
int type)
{
struct known_host *node;
if(known->magic != KNOWNHOST_MAGIC)
return LIBSSH2_ERROR_INVAL;
node = known->node;
return knownhost_writeline(hosts, node, buffer, buflen, outlen, type);
}
/*
* libssh2_knownhost_writefile()
*
* Write hosts+key pairs to the given file.
*/
LIBSSH2_API int
libssh2_knownhost_writefile(LIBSSH2_KNOWNHOSTS *hosts,
const char *filename, int type)
{
struct known_host *node;
FILE *file;
int rc = LIBSSH2_ERROR_NONE;
char buffer[2048];
/* we only support this single file type for now, bail out on all other
attempts */
if(type != LIBSSH2_KNOWNHOST_FILE_OPENSSH)
return LIBSSH2_ERROR_METHOD_NOT_SUPPORTED;
file = fopen(filename, "w");
if(!file)
return LIBSSH2_ERROR_FILE;
for(node = _libssh2_list_first(&hosts->head);
node;
node= _libssh2_list_next(&node->node) ) {
size_t wrote;
size_t nwrote;
rc = knownhost_writeline(hosts, node, buffer, sizeof(buffer), &wrote,
type);
if(rc)
break;
nwrote = fwrite(buffer, 1, wrote, file);
if(nwrote != wrote) {
/* failed to write the whole thing, bail out */
rc = LIBSSH2_ERROR_FILE;
break;
}
}
fclose(file);
return rc;
}
/*
* libssh2_knownhost_get()
*
* Traverse the internal list of known hosts. Pass NULL to 'prev' to get
* the first one.
*
* Returns:
* 0 if a fine host was stored in 'store'
* 1 if end of hosts
* [negative] on errors
*/
LIBSSH2_API int
libssh2_knownhost_get(LIBSSH2_KNOWNHOSTS *hosts,
struct libssh2_knownhost **ext,
struct libssh2_knownhost *oprev)
{
struct known_host *node;
if(oprev && oprev->node) {
/* we have a starting point */
struct known_host *prev = oprev->node;
/* get the next node in the list */
node = _libssh2_list_next(&prev->node);
}
else
node = _libssh2_list_first(&hosts->head);
if(!node)
/* no (more) node */
return 1;
*ext = knownhost_to_external(node);
return 0;
}

View File

@@ -39,6 +39,12 @@
#ifndef LIBSSH2_PRIV_H #ifndef LIBSSH2_PRIV_H
#define LIBSSH2_PRIV_H 1 #define LIBSSH2_PRIV_H 1
#ifdef _WIN32
#ifndef _CRT_SECURE_NO_DEPRECATE
#define _CRT_SECURE_NO_DEPRECATE 1
#endif /* _CRT_SECURE_NO_DEPRECATE */
#endif /* WIN32 */
#define LIBSSH2_LIBRARY #define LIBSSH2_LIBRARY
#include "libssh2_config.h" #include "libssh2_config.h"
@@ -881,7 +887,7 @@ struct _LIBSSH2_SESSION
unsigned char scpRecv_response[LIBSSH2_SCP_RESPONSE_BUFLEN]; unsigned char scpRecv_response[LIBSSH2_SCP_RESPONSE_BUFLEN];
unsigned long scpRecv_response_len; unsigned long scpRecv_response_len;
long scpRecv_mode; long scpRecv_mode;
#if defined(HAVE_LONGLONG) && defined(strtoll) #if defined(HAVE_LONGLONG) && defined(HAVE_STRTOLL)
/* we have the type and we can parse such numbers */ /* we have the type and we can parse such numbers */
long long scpRecv_size; long long scpRecv_size;
#define scpsize_strtol strtoll #define scpsize_strtol strtoll
@@ -922,7 +928,26 @@ struct _LIBSSH2_SESSION
#define LIBSSH2_SOCKET_RECV_FLAGS(session) 0 #define LIBSSH2_SOCKET_RECV_FLAGS(session) 0
#endif #endif
/* libssh2 extensible ssh api, ultimately I'd like to allow loading additional methods via .so/.dll */ /* -------- */
/* 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
methods via .so/.dll */
struct _LIBSSH2_KEX_METHOD struct _LIBSSH2_KEX_METHOD
{ {
@@ -1023,11 +1048,8 @@ struct _LIBSSH2_MAC_METHOD
void _libssh2_debug(LIBSSH2_SESSION * session, int context, const char *format, void _libssh2_debug(LIBSSH2_SESSION * session, int context, const char *format,
...); ...);
#else #else
#if defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L) #if (defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L)) || defined(__GNUC__)
/* C99 style */ /* C99 supported and also by older GCC */
#define _libssh2_debug(x,y,z, __VA_ARGS__) do {} while (0)
#elif defined(__GNUC__)
/* GNU style */
#define _libssh2_debug(x,y,z,...) do {} while (0) #define _libssh2_debug(x,y,z,...) do {} while (0)
#else #else
/* no gcc and not C99, do static and hopefully inline */ /* no gcc and not C99, do static and hopefully inline */

View File

@@ -37,6 +37,8 @@
*/ */
#include "libssh2_priv.h" #include "libssh2_priv.h"
#include "misc.h"
#ifdef HAVE_UNISTD_H #ifdef HAVE_UNISTD_H
#include <unistd.h> #include <unistd.h>
#endif #endif
@@ -222,6 +224,86 @@ libssh2_base64_decode(LIBSSH2_SESSION * session, char **data,
return 0; return 0;
} }
/* ---- Base64 Encoding/Decoding Table --- */
static const char table64[]=
"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
/*
* _libssh2_base64_encode()
*
* Returns the length of the newly created base64 string. The third argument
* is a pointer to an allocated area holding the base64 data. If something
* went wrong, 0 is returned.
*
*/
size_t _libssh2_base64_encode(LIBSSH2_SESSION *session,
const char *inp, size_t insize, char **outptr)
{
unsigned char ibuf[3];
unsigned char obuf[4];
int i;
int inputparts;
char *output;
char *base64data;
const char *indata = inp;
*outptr = NULL; /* set to NULL in case of failure before we reach the end */
if(0 == insize)
insize = strlen(indata);
base64data = output = LIBSSH2_ALLOC(session, insize*4/3+4);
if(NULL == output)
return 0;
while(insize > 0) {
for (i = inputparts = 0; i < 3; i++) {
if(insize > 0) {
inputparts++;
ibuf[i] = *indata;
indata++;
insize--;
}
else
ibuf[i] = 0;
}
obuf[0] = (unsigned char) ((ibuf[0] & 0xFC) >> 2);
obuf[1] = (unsigned char) (((ibuf[0] & 0x03) << 4) | \
((ibuf[1] & 0xF0) >> 4));
obuf[2] = (unsigned char) (((ibuf[1] & 0x0F) << 2) | \
((ibuf[2] & 0xC0) >> 6));
obuf[3] = (unsigned char) (ibuf[2] & 0x3F);
switch(inputparts) {
case 1: /* only one byte read */
snprintf(output, 5, "%c%c==",
table64[obuf[0]],
table64[obuf[1]]);
break;
case 2: /* two bytes read */
snprintf(output, 5, "%c%c%c=",
table64[obuf[0]],
table64[obuf[1]],
table64[obuf[2]]);
break;
default:
snprintf(output, 5, "%c%c%c%c",
table64[obuf[0]],
table64[obuf[1]],
table64[obuf[2]],
table64[obuf[3]] );
break;
}
output += 4;
}
*output=0;
*outptr = base64data; /* make it return the actual data memory */
return strlen(base64data); /* return the length of the new data */
}
/* ---- End of Base64 Encoding ---- */
#ifdef LIBSSH2DEBUG #ifdef LIBSSH2DEBUG
LIBSSH2_API int LIBSSH2_API int
libssh2_trace(LIBSSH2_SESSION * session, int bitmask) libssh2_trace(LIBSSH2_SESSION * session, int bitmask)
@@ -283,3 +365,64 @@ libssh2_trace(LIBSSH2_SESSION * session, int bitmask)
return 0; return 0;
} }
#endif #endif
/* init the list head */
void _libssh2_list_init(struct list_head *head)
{
head->first = head->last = NULL;
}
/* add a node to the list */
void _libssh2_list_add(struct list_head *head,
struct list_node *entry)
{
/* store a pointer to the head */
entry->head = head;
/* we add this entry at the "top" so it has no next */
entry->next = NULL;
/* make our prev point to what the head thinks is last */
entry->prev = head->last;
/* and make head's last be us now */
head->last = entry;
/* make sure our 'prev' node points to us next */
if(entry->prev)
entry->prev->next = entry;
else
head->first = entry;
}
/* return the "first" node in the list this head points to */
void *_libssh2_list_first(struct list_head *head)
{
return head->first;
}
/* return the next node in the list */
void *_libssh2_list_next(struct list_node *node)
{
return node->next;
}
/* return the prev node in the list */
void *_libssh2_list_prev(struct list_node *node)
{
return node->prev;
}
/* remove this node from the list */
void _libssh2_list_remove(struct list_node *entry)
{
if(entry->prev)
entry->prev->next = entry->next;
else
entry->head->first = entry->next;
if(entry->next)
entry->next->prev = entry->prev;
else
entry->head->last = entry->prev;
}

63
src/misc.h Normal file
View File

@@ -0,0 +1,63 @@
#ifndef __LIBSSH2_MISC_H
#define __LIBSSH2_MISC_H
/* Copyright (c) 2009 by Daniel Stenberg
*
* All rights reserved.
*
* Redistribution and use in source and binary forms,
* with or without modification, are permitted provided
* that the following conditions are met:
*
* Redistributions of source code must retain the above
* copyright notice, this list of conditions and the
* following disclaimer.
*
* Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following
* disclaimer in the documentation and/or other materials
* provided with the distribution.
*
* Neither the name of the copyright holder nor the names
* of any other contributors may be used to endorse or
* promote products derived from this software without
* specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
* CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
* USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
* OF SUCH DAMAGE.
*/
#include "libssh2_priv.h"
void _libssh2_list_init(struct list_head *head);
/* add a node first in the list */
void _libssh2_list_add(struct list_head *head,
struct list_node *entry);
/* return the "first" node in the list this head points to */
void *_libssh2_list_first(struct list_head *head);
/* return the next node in the list */
void *_libssh2_list_next(struct list_node *node);
/* return the prev node in the list */
void *_libssh2_list_prev(struct list_node *node);
/* remove this node from the list */
void _libssh2_list_remove(struct list_node *entry);
size_t _libssh2_base64_encode(LIBSSH2_SESSION *session,
const char *inp, size_t insize, char **outptr);
#endif /* _LIBSSH2_MISC_H */

View File

@@ -43,6 +43,9 @@
#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,
@@ -212,12 +215,80 @@ 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 *,
void * u);
static int
read_private_key_from_file(void ** key_ctx, LIBSSH2_SESSION * session,
pem_read_bio_func read_private_key,
FILE * fp, unsigned const char *passphrase)
{
char * key;
BIO * bp;
*key_ctx = NULL;
if(read_file_into_string(&key, session, fp)) {
return -1;
}
bp = BIO_new_mem_buf(key, -1);
if (!bp) {
LIBSSH2_FREE(session, key);
return -1;
}
*key_ctx = read_private_key(bp, NULL, (void *) passphrase_cb,
(void *) passphrase);
BIO_free(bp);
LIBSSH2_FREE(session, key);
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) FILE * fp, unsigned const char *passphrase)
{ {
(void) session; pem_read_bio_func read_rsa =
(pem_read_bio_func) &PEM_read_bio_RSAPrivateKey;
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.
* I have *NO DOUBT* that there's a better way to deal with this ($#&%#$(%$#( * I have *NO DOUBT* that there's a better way to deal with this ($#&%#$(%$#(
@@ -225,12 +296,9 @@ _libssh2_rsa_new_private(libssh2_rsa_ctx ** rsa,
*/ */
OpenSSL_add_all_ciphers(); OpenSSL_add_all_ciphers();
} }
*rsa = PEM_read_RSAPrivateKey(fp, NULL, (void *) passphrase_cb,
(void *) passphrase); return read_private_key_from_file((void **) rsa, session, read_rsa, fp,
if (!*rsa) { passphrase);
return -1;
}
return 0;
} }
int int
@@ -238,7 +306,9 @@ _libssh2_dsa_new_private(libssh2_dsa_ctx ** dsa,
LIBSSH2_SESSION * session, LIBSSH2_SESSION * session,
FILE * fp, unsigned const char *passphrase) FILE * fp, unsigned const char *passphrase)
{ {
(void) session; pem_read_bio_func read_dsa =
(pem_read_bio_func) &PEM_read_bio_DSAPrivateKey;
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.
* I have *NO DOUBT* that there's a better way to deal with this ($#&%#$(%$#( * I have *NO DOUBT* that there's a better way to deal with this ($#&%#$(%$#(
@@ -246,12 +316,9 @@ _libssh2_dsa_new_private(libssh2_dsa_ctx ** dsa,
*/ */
OpenSSL_add_all_ciphers(); OpenSSL_add_all_ciphers();
} }
*dsa = PEM_read_DSAPrivateKey(fp, NULL, (void *) passphrase_cb,
(void *) passphrase); return read_private_key_from_file((void **) dsa, session, read_dsa, fp,
if (!*dsa) { passphrase);
return -1;
}
return 0;
} }
int int

View File

@@ -123,7 +123,7 @@ packet_queue_listener(LIBSSH2_SESSION * session, unsigned char *data,
(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, *last_queued = listen->queue; LIBSSH2_CHANNEL *channel = NULL, *last_queued = listen->queue;
last_queued = listen->queue; last_queued = listen->queue;
if (listen_state->state == libssh2_NB_state_allocated) { if (listen_state->state == libssh2_NB_state_allocated) {
@@ -288,7 +288,7 @@ packet_x11_open(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(X11FwdUnAvil) - 1); unsigned long packet_len = 17 + (sizeof(X11FwdUnAvil) - 1);
unsigned char *p; unsigned char *p;
LIBSSH2_CHANNEL *channel; LIBSSH2_CHANNEL *channel = NULL;
int rc; int rc;
(void) datalen; (void) datalen;
@@ -1078,7 +1078,7 @@ _libssh2_packet_require(LIBSSH2_SESSION * session, unsigned char packet_type,
return ret; return ret;
} else if (ret == 0) { } else if (ret == 0) {
/* nothing available, wait until data arrives or we time out */ /* nothing available, wait until data arrives or we time out */
long left = LIBSSH2_READ_TIMEOUT - (time(NULL) - state->start); long left = LIBSSH2_READ_TIMEOUT - (long)(time(NULL) - state->start);
if (left <= 0) { if (left <= 0) {
state->start = 0; state->start = 0;
@@ -1187,7 +1187,7 @@ _libssh2_packet_requirev(LIBSSH2_SESSION * session,
return ret; return ret;
} }
if (ret <= 0) { if (ret <= 0) {
long left = LIBSSH2_READ_TIMEOUT - (time(NULL) - state->start); long left = LIBSSH2_READ_TIMEOUT - (long)(time(NULL) - state->start);
if (left <= 0) { if (left <= 0) {
state->start = 0; state->start = 0;

View File

@@ -427,7 +427,7 @@ libssh2_session_init_ex(LIBSSH2_ALLOC_FUNC((*my_alloc)),
local_realloc = my_realloc; local_realloc = my_realloc;
} }
session = local_alloc(sizeof(LIBSSH2_SESSION), abstract); session = local_alloc(sizeof(LIBSSH2_SESSION), &abstract);
if (session) { if (session) {
memset(session, 0, sizeof(LIBSSH2_SESSION)); memset(session, 0, sizeof(LIBSSH2_SESSION));
session->alloc = local_alloc; session->alloc = local_alloc;
@@ -924,6 +924,10 @@ session_free(LIBSSH2_SESSION *session)
/* if the socket was previously blocking, put it back so */ /* if the socket was previously blocking, put it back so */
session_nonblock(session->socket_fd, 0); session_nonblock(session->socket_fd, 0);
if (session->server_hostkey) {
LIBSSH2_FREE(session, session->server_hostkey);
}
LIBSSH2_FREE(session, session); LIBSSH2_FREE(session, session);
return 0; return 0;
@@ -1164,7 +1168,8 @@ libssh2_session_last_error(LIBSSH2_SESSION * session, char **errmsg,
return session->err_code; return session->err_code;
} }
/* libssh2_session_last_error /* libssh2_session_last_errno
*
* Returns error code * Returns error code
*/ */
LIBSSH2_API int LIBSSH2_API int
@@ -1174,8 +1179,11 @@ libssh2_session_last_errno(LIBSSH2_SESSION * session)
} }
/* libssh2_session_flag /* libssh2_session_flag
*
* Set/Get session flags * Set/Get session flags
* Passing flag==0 will avoid changing session->flags while still returning its current value *
* Passing flag==0 will avoid changing session->flags while still returning
* its current value
*/ */
LIBSSH2_API int LIBSSH2_API int
libssh2_session_flag(LIBSSH2_SESSION * session, int flag, int value) libssh2_session_flag(LIBSSH2_SESSION * session, int flag, int value)
@@ -1594,7 +1602,7 @@ libssh2_poll(LIBSSH2_POLLFD * fds, unsigned int nfds, long timeout)
} }
/* /*
* libssh2_session_block_direction * libssh2_session_block_directions
* *
* Get blocked direction when a function returns LIBSSH2_ERROR_EAGAIN * Get blocked direction when a function returns LIBSSH2_ERROR_EAGAIN
* Returns LIBSSH2_SOCKET_BLOCK_INBOUND if recv() blocked * Returns LIBSSH2_SOCKET_BLOCK_INBOUND if recv() blocked

View File

@@ -93,17 +93,17 @@ static int sftp_close_handle(LIBSSH2_SFTP_HANDLE *handle);
static void static void
_libssh2_htonu64(unsigned char *buf, libssh2_uint64_t value) _libssh2_htonu64(unsigned char *buf, libssh2_uint64_t value)
{ {
unsigned long msl = ((libssh2_uint64_t)value >> 32); unsigned long msl = (unsigned long)(value >> 32);
buf[0] = (msl >> 24) & 0xFF; buf[0] = (unsigned char)((msl >> 24) & 0xFF);
buf[1] = (msl >> 16) & 0xFF; buf[1] = (unsigned char)((msl >> 16) & 0xFF);
buf[2] = (msl >> 8) & 0xFF; buf[2] = (unsigned char)((msl >> 8) & 0xFF);
buf[3] = msl & 0xFF; buf[3] = (unsigned char)( msl & 0xFF);
buf[4] = (value >> 24) & 0xFF; buf[4] = (unsigned char)((value >> 24) & 0xFF);
buf[5] = (value >> 16) & 0xFF; buf[5] = (unsigned char)((value >> 16) & 0xFF);
buf[6] = (value >> 8) & 0xFF; buf[6] = (unsigned char)((value >> 8) & 0xFF);
buf[7] = value & 0xFF; buf[7] = (unsigned char)( value & 0xFF);
} }
/* /*
@@ -378,7 +378,7 @@ sftp_packet_requirev(LIBSSH2_SFTP *sftp, int num_valid_responses,
} else if (ret <= 0) { } else if (ret <= 0) {
/* prevent busy-looping */ /* prevent busy-looping */
long left = long left =
LIBSSH2_READ_TIMEOUT - (time(NULL) - sftp->requirev_start); LIBSSH2_READ_TIMEOUT - (long)(time(NULL) - sftp->requirev_start);
if (left <= 0) { if (left <= 0) {
sftp->requirev_start = 0; sftp->requirev_start = 0;
@@ -521,20 +521,6 @@ LIBSSH2_CHANNEL_CLOSE_FUNC(libssh2_sftp_dtor)
(void) session_abstract; (void) session_abstract;
(void) channel; (void) channel;
#if 0
/* EEEK! While it might sound like a neat idea to make this code loop over
all the outstanding handles and close them, that is going to cause
EAGAIN to get returned and this callback system is not designed to
handle this very nicely so thus we now DEMAND that the app closes its
handles instead!
*/
/* Loop through handles closing them */
while (sftp->handles) {
sftp_close_handle(sftp->handles);
}
#endif
/* Free the partial packet storage for sftp_packet_read */ /* Free the partial packet storage for sftp_packet_read */
if (sftp->partial_packet) { if (sftp->partial_packet) {
LIBSSH2_FREE(session, sftp->partial_packet); LIBSSH2_FREE(session, sftp->partial_packet);
@@ -558,18 +544,31 @@ static LIBSSH2_SFTP *sftp_init(LIBSSH2_SESSION *session)
unsigned char *data, *s; unsigned char *data, *s;
unsigned long data_len; unsigned long data_len;
int rc; int rc;
LIBSSH2_SFTP *sftp_handle;
if (session->sftpInit_state == libssh2_NB_state_idle) { if (session->sftpInit_state == libssh2_NB_state_idle) {
_libssh2_debug(session, LIBSSH2_DBG_SFTP, _libssh2_debug(session, LIBSSH2_DBG_SFTP,
"Initializing SFTP subsystem"); "Initializing SFTP subsystem");
/*
* The 'sftpInit_sftp' and 'sftpInit_channel' struct fields within the
* session struct are only to be used during the setup phase. As soon
* as the SFTP session is created they are cleared and can thus be
* re-used again to allow any amount of SFTP handles per sessions.
*
* Note that you MUST NOT try to call libssh2_sftp_init() to get
* another handle until the previous one has finished and either
* succesffully made a handle or failed and returned error (not
* including *EAGAIN).
*/
assert(session->sftpInit_sftp == NULL); assert(session->sftpInit_sftp == NULL);
session->sftpInit_sftp = NULL; session->sftpInit_sftp = NULL;
session->sftpInit_state = libssh2_NB_state_created; session->sftpInit_state = libssh2_NB_state_created;
} }
sftp_handle = session->sftpInit_sftp;
if (session->sftpInit_state == libssh2_NB_state_created) { if (session->sftpInit_state == libssh2_NB_state_created) {
session->sftpInit_channel = session->sftpInit_channel =
_libssh2_channel_open(session, "session", sizeof("session") - 1, _libssh2_channel_open(session, "session", sizeof("session") - 1,
@@ -618,15 +617,17 @@ static LIBSSH2_SFTP *sftp_init(LIBSSH2_SESSION *session)
return NULL; return NULL;
} }
session->sftpInit_sftp = LIBSSH2_ALLOC(session, sizeof(LIBSSH2_SFTP)); sftp_handle =
if (!session->sftpInit_sftp) { session->sftpInit_sftp =
LIBSSH2_ALLOC(session, sizeof(LIBSSH2_SFTP));
if (!sftp_handle) {
libssh2_error(session, LIBSSH2_ERROR_ALLOC, libssh2_error(session, LIBSSH2_ERROR_ALLOC,
"Unable to allocate a new SFTP structure", 0); "Unable to allocate a new SFTP structure", 0);
goto sftp_init_error; goto sftp_init_error;
} }
memset(session->sftpInit_sftp, 0, sizeof(LIBSSH2_SFTP)); memset(sftp_handle, 0, sizeof(LIBSSH2_SFTP));
session->sftpInit_sftp->channel = session->sftpInit_channel; sftp_handle->channel = session->sftpInit_channel;
session->sftpInit_sftp->request_id = 0; sftp_handle->request_id = 0;
_libssh2_htonu32(session->sftpInit_buffer, 5); _libssh2_htonu32(session->sftpInit_buffer, 5);
session->sftpInit_buffer[4] = SSH_FXP_INIT; session->sftpInit_buffer[4] = SSH_FXP_INIT;
@@ -655,7 +656,7 @@ static LIBSSH2_SFTP *sftp_init(LIBSSH2_SESSION *session)
session->sftpInit_state = libssh2_NB_state_sent3; session->sftpInit_state = libssh2_NB_state_sent3;
} }
rc = sftp_packet_require(session->sftpInit_sftp, SSH_FXP_VERSION, rc = sftp_packet_require(sftp_handle, SSH_FXP_VERSION,
0, &data, &data_len); 0, &data, &data_len);
if (rc == PACKET_EAGAIN) { if (rc == PACKET_EAGAIN) {
libssh2_error(session, LIBSSH2_ERROR_EAGAIN, libssh2_error(session, LIBSSH2_ERROR_EAGAIN,
@@ -674,17 +675,17 @@ static LIBSSH2_SFTP *sftp_init(LIBSSH2_SESSION *session)
} }
s = data + 1; s = data + 1;
session->sftpInit_sftp->version = _libssh2_ntohu32(s); sftp_handle->version = _libssh2_ntohu32(s);
s += 4; s += 4;
if (session->sftpInit_sftp->version > LIBSSH2_SFTP_VERSION) { if (sftp_handle->version > LIBSSH2_SFTP_VERSION) {
_libssh2_debug(session, LIBSSH2_DBG_SFTP, _libssh2_debug(session, LIBSSH2_DBG_SFTP,
"Truncating remote SFTP version from %lu", "Truncating remote SFTP version from %lu",
session->sftpInit_sftp->version); sftp_handle->version);
session->sftpInit_sftp->version = LIBSSH2_SFTP_VERSION; sftp_handle->version = LIBSSH2_SFTP_VERSION;
} }
_libssh2_debug(session, LIBSSH2_DBG_SFTP, _libssh2_debug(session, LIBSSH2_DBG_SFTP,
"Enabling SFTP version %lu compatability", "Enabling SFTP version %lu compatability",
session->sftpInit_sftp->version); sftp_handle->version);
while (s < (data + data_len)) { while (s < (data + data_len)) {
unsigned char *extension_name, *extension_data; unsigned char *extension_name, *extension_data;
unsigned long extname_len, extdata_len; unsigned long extname_len, extdata_len;
@@ -705,11 +706,16 @@ static LIBSSH2_SFTP *sftp_init(LIBSSH2_SESSION *session)
/* Make sure that when the channel gets closed, the SFTP service is shut /* Make sure that when the channel gets closed, the SFTP service is shut
down too */ down too */
session->sftpInit_sftp->channel->abstract = session->sftpInit_sftp; sftp_handle->channel->abstract = sftp_handle;
session->sftpInit_sftp->channel->close_cb = libssh2_sftp_dtor; sftp_handle->channel->close_cb = libssh2_sftp_dtor;
session->sftpInit_state = libssh2_NB_state_idle; session->sftpInit_state = libssh2_NB_state_idle;
return session->sftpInit_sftp;
/* clear the sftp and channel pointers in this session struct now */
session->sftpInit_sftp = NULL;
session->sftpInit_channel = NULL;
return sftp_handle;
sftp_init_error: sftp_init_error:
while (_libssh2_channel_free(session->sftpInit_channel) == PACKET_EAGAIN); while (_libssh2_channel_free(session->sftpInit_channel) == PACKET_EAGAIN);
@@ -1105,7 +1111,7 @@ static ssize_t sftp_read(LIBSSH2_SFTP_HANDLE * handle, char *buffer,
/* 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! */
libssh2_error(session, LIBSSH2_ERROR_SOCKET_SEND, libssh2_error(session, LIBSSH2_ERROR_SOCKET_SEND,
"Unable to send FXP_READ command", 0); "_libssh2_channel_write() failed", 0);
sftp->read_packet = NULL; sftp->read_packet = NULL;
sftp->read_state = libssh2_NB_state_idle; sftp->read_state = libssh2_NB_state_idle;
return -1; return -1;
@@ -1305,7 +1311,7 @@ static int sftp_readdir(LIBSSH2_SFTP_HANDLE *handle, char *buffer,
} }
else if (packet_len != retcode) { else if (packet_len != retcode) {
libssh2_error(session, LIBSSH2_ERROR_SOCKET_SEND, libssh2_error(session, LIBSSH2_ERROR_SOCKET_SEND,
"Unable to send FXP_READ command", 0); "_libssh2_channel_write() failed", 0);
LIBSSH2_FREE(session, sftp->readdir_packet); LIBSSH2_FREE(session, sftp->readdir_packet);
sftp->readdir_packet = NULL; sftp->readdir_packet = NULL;
sftp->readdir_state = libssh2_NB_state_idle; sftp->readdir_state = libssh2_NB_state_idle;
@@ -1409,8 +1415,10 @@ libssh2_sftp_readdir_ex(LIBSSH2_SFTP_HANDLE *hnd, char *buffer,
return rc; return rc;
} }
/* sftp_write /*
* Write data to a file handle * sftp_write
*
* Write data to an SFTP handle
*/ */
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)
@@ -1421,20 +1429,28 @@ static ssize_t sftp_write(LIBSSH2_SFTP_HANDLE * handle, const char *buffer,
unsigned long data_len, retcode; unsigned long data_len, retcode;
/* 25 = packet_len(4) + packet_type(1) + request_id(4) + handle_len(4) + /* 25 = packet_len(4) + packet_type(1) + request_id(4) + handle_len(4) +
offset(8) + count(4) */ offset(8) + count(4) */
ssize_t packet_len = handle->handle_len + count + 25; ssize_t packet_len;
unsigned char *s, *data; unsigned char *s, *data;
int rc; int rc;
/* There's no point in us accepting a VERY large packet here since we
cannot send it anyway. We just accept 4 times the big size to fill up
the queue somewhat. */
if(count > (MAX_SSH_PACKET_LEN*4))
count = MAX_SSH_PACKET_LEN*4;
packet_len = handle->handle_len + count + 25;
if (sftp->write_state == libssh2_NB_state_idle) { if (sftp->write_state == libssh2_NB_state_idle) {
_libssh2_debug(session, LIBSSH2_DBG_SFTP, "Writing %lu bytes", _libssh2_debug(session, LIBSSH2_DBG_SFTP, "Writing %lu bytes",
(unsigned long) count); (unsigned long) count);
s = sftp->write_packet = LIBSSH2_ALLOC(session, packet_len); s = sftp->write_packet = LIBSSH2_ALLOC(session, packet_len);
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 packet", 0); "Unable to allocate memory for FXP_WRITE", 0);
return -1; return -1;
} }
_libssh2_htonu32(s, packet_len - 4); _libssh2_htonu32(s, packet_len - 4);
s += 4; s += 4;
*(s++) = SSH_FXP_WRITE; *(s++) = SSH_FXP_WRITE;
@@ -1461,14 +1477,18 @@ static ssize_t sftp_write(LIBSSH2_SFTP_HANDLE * handle, const char *buffer,
if (rc == PACKET_EAGAIN) { if (rc == PACKET_EAGAIN) {
return PACKET_EAGAIN; return PACKET_EAGAIN;
} }
if (packet_len != rc) { else if(rc < 0) {
libssh2_error(session, LIBSSH2_ERROR_SOCKET_SEND, /* an actual error */
"Unable to send FXP_READ command", 0); return rc;
LIBSSH2_FREE(session, sftp->write_packet); }
sftp->write_packet = NULL; else if(0 == rc) {
sftp->write_state = libssh2_NB_state_idle; /* an actual error */
fprintf(stderr, "WEIRDNESS\n");
return -1; return -1;
} }
else if (packet_len != rc) {
return rc;
}
LIBSSH2_FREE(session, sftp->write_packet); LIBSSH2_FREE(session, sftp->write_packet);
sftp->write_packet = NULL; sftp->write_packet = NULL;
sftp->write_state = libssh2_NB_state_sent; sftp->write_state = libssh2_NB_state_sent;
@@ -1654,7 +1674,10 @@ libssh2_sftp_seek64(LIBSSH2_SFTP_HANDLE * handle, libssh2_uint64_t offset)
LIBSSH2_API size_t LIBSSH2_API size_t
libssh2_sftp_tell(LIBSSH2_SFTP_HANDLE * handle) libssh2_sftp_tell(LIBSSH2_SFTP_HANDLE * handle)
{ {
return handle->u.file.offset; /* NOTE: this may very well truncate the size if it is larger than what
size_t can hold, so libssh2_sftp_tell64() is really the function you
should use */
return (size_t)(handle->u.file.offset);
} }
/* libssh2_sftp_tell64 /* libssh2_sftp_tell64
@@ -1894,7 +1917,8 @@ static int sftp_rename(LIBSSH2_SFTP *sftp, const char *source_filename,
{ {
LIBSSH2_CHANNEL *channel = sftp->channel; LIBSSH2_CHANNEL *channel = sftp->channel;
LIBSSH2_SESSION *session = channel->session; LIBSSH2_SESSION *session = channel->session;
unsigned long data_len, retcode; unsigned long data_len;
int retcode;
ssize_t packet_len = ssize_t packet_len =
source_filename_len + dest_filename_len + 17 + (sftp->version >= source_filename_len + dest_filename_len + 17 + (sftp->version >=
5 ? 4 : 0); 5 ? 4 : 0);
@@ -2083,7 +2107,7 @@ static int sftp_mkdir(LIBSSH2_SFTP *sftp, const char *path,
} }
if (packet_len != rc) { if (packet_len != rc) {
libssh2_error(session, LIBSSH2_ERROR_SOCKET_SEND, libssh2_error(session, LIBSSH2_ERROR_SOCKET_SEND,
"Unable to send FXP_READ command", 0); "_libssh2_channel_write() failed", 0);
LIBSSH2_FREE(session, packet); LIBSSH2_FREE(session, packet);
sftp->mkdir_state = libssh2_NB_state_idle; sftp->mkdir_state = libssh2_NB_state_idle;
return -1; return -1;

View File

@@ -1,374 +0,0 @@
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include "libssh2_priv.h"
static int
ssh_host_parse_hostnames (LIBSSH2_SESSION * session,
LIBSSH2_KNOWNHOSTS * s,
char *line,
char *end
);
static int
ssh_host_parse_key (LIBSSH2_SESSION * session,
LIBSSH2_KNOWNHOSTS * s,
char *line,
int is_base64_encoded
);
/* Returns zero if successful, > zero for malformed data, < 0 not supported. */
LIBSSH2_API int
libssh2_new_host_entry(LIBSSH2_SESSION * session,
LIBSSH2_KNOWNHOSTS ** s,
char *line)
{
char *tmp = NULL;
LIBSSH2_KNOWNHOSTS *t = NULL;
int i;
if (line == NULL || *line == 0)
return 1;
if (s == NULL)
return 2;
tmp = strchr (line, ' ');
if (tmp == NULL)
return 3;
t = (LIBSSH2_KNOWNHOSTS *)
LIBSSH2_ALLOC(session, sizeof(LIBSSH2_KNOWNHOSTS));
t->hostname_line = NULL;
t->hostnames = NULL;
t->hostnames_size = t->bits = t->exponent = -1;
t->modulus = NULL;
t->modulus_length = -1;
t->ssh_version = -1;
t->md5 = NULL;
i = ssh_host_parse_hostnames (session, t, line, tmp);
if (i != 0) {
libssh2_free_host_entry (session, t);
return ((i > 0) ? 4 : -1);
}
line = tmp + 1;
tmp = strchr (line, ' ');
if (tmp != NULL)
tmp = strchr (tmp + 1, ' ');
i = ssh_host_parse_key (session, t, line, tmp == NULL ? 1 : 0);
if (i != 0) {
libssh2_free_host_entry (session, t);
return ((i > 0) ? 5 : -2);
}
*s = t;
return 0;
}
static int
ssh_host_parse_hostnames(LIBSSH2_SESSION * session,
LIBSSH2_KNOWNHOSTS * s,
char *line,
char *end)
{
char *start;
char *comma = NULL;
int i;
/* TODO: we don't handle the hashed name format because the hashing
* mechanism isnt defined (at least based on the man page)
*/
if (*line == '|')
return -1;
if (line == end || *line == ' ')
return 1;
s->hostname_line = (char *) LIBSSH2_ALLOC (session, (end - line) + 1);
strncpy (s->hostname_line, line, (end - line) + 1);
start = end = s->hostname_line + (end - line);
*end = 0;
s->hostnames_size = 1;
comma = s->hostname_line;
while ((comma = strchr (comma, ',')) != NULL) {
comma++;
if (*comma == ',' || *comma == 0) {
LIBSSH2_FREE (session, s->hostname_line);
s->hostname_line = NULL;
return 2;
}
s->hostnames_size++;
}
s->hostnames = (char **) LIBSSH2_ALLOC
(session, sizeof (char *) * s->hostnames_size);
start = comma = s->hostname_line;
i = 0;
while ((comma = strchr (comma, ',')) != NULL) {
*comma = 0;
s->hostnames[i] = start;
comma++;
start = comma;
i++;
}
s->hostnames[i] = start;
return 0;
}
/** Returns the number of bytes read or -1. */
static int
ssh_proto_str_read(LIBSSH2_SESSION * session,
char *line,
char **val,
char *end
)
{
unsigned int len;
if (line + 4 > end)
return -1;
len = (line[0] << 24) + (line[1] << 16) + (line[2] << 8) + line[3];
if (line + 4 + len > end)
return -1;
*val = LIBSSH2_ALLOC (session, len);
memcpy (*val, line + 4, len);
return len + 4;
}
static int
ssh_host_parse_key(LIBSSH2_SESSION * session,
LIBSSH2_KNOWNHOSTS * s,
char *line,
int is_base64_encoded)
{
int i, j;
char *tmp, *tmp2;
/* workaround for the MD5 stuff */
libssh2_md5_ctx ctx;
/* the bits, exponent, modulus format */
if (is_base64_encoded == 0) {
s->ssh_version = 1;
s->key_type = 0;
if (!isdigit (*line))
return -1;
if (sscanf (line, "%hu %hu ", &(s->bits), &(s->exponent)) != 2)
return -2;
/* TODO:
* There's probably an acceptable range...
*/
if (s->bits <= 0 || s->exponent <= 0)
return 1;
line = strchr (line, ' ');
if (line == NULL)
return -3;
line++;
line = strchr (line, ' ');
if (line == NULL)
return -4;
line++;
/* TODO:
* figure out what format modulus is in since its not clear
* from the man page
*/
return -5;
}
else {
s->ssh_version = 2;
/* we only handle the rsa type */
if (strstr (line, "ssh-rsa") != line)
return -6;
s->key_type = 0;
line += 7;
if (*line != ' ')
return 2;
line++;
i = 0;
while (*line) {
if ((line[i] >= 0x30 && line[i] <= 0x39) ||
(line[i] >= 0x41 && line[i] <= 0x5a) ||
(line[i] >= 0x61 && line[i] <= 0x7a) ||
(line[i] == '+') || (line[i] == '/') || (line[i] == '='))
i++;
else
break;
}
if (i == 0)
return 3;
tmp = LIBSSH2_ALLOC (session, sizeof (char) * (i + 5));
strncpy (tmp, line, i);
/* this should hopefully avoid any issues with reading
* past the array if its malformed */
tmp[i] = tmp[i + 1] = tmp[i + 2] = tmp[i + 3] = tmp[i + 4] = 0;
{
/* TODO: rework the api interface instead of making a local
instance */
i = libssh2_base64_decode(session, &tmp2, (unsigned int *)&j,
tmp, strlen(tmp));
LIBSSH2_FREE(session, tmp);
if (i != 0)
return 4;
}
/* printf("Decode Size: %d\n", i); */
/* free (tmp); */
#if LIBSSH2_MD5
s->md5 = LIBSSH2_ALLOC (session, 16);
libssh2_md5_init (&ctx);
libssh2_md5_update (ctx, tmp2, j);
libssh2_md5_final (ctx, s->md5);
#endif
line = tmp2;
i = ssh_proto_str_read (session, line, &tmp, tmp2 + j);
if (i < 0) {
LIBSSH2_FREE (session, tmp2);
return 5;
}
/* TODO: verify that its ssh-rsa -- its the only one
* supported
*/
if (!(i == 11 && tmp[0] == 's' && tmp[1] == 's' &&
tmp[2] == 'h' && tmp[3] == '-' && tmp[4] == 'r' &&
tmp[5] == 's' && tmp[6] == 'a')) {
free (tmp);
free (tmp2);
return 8;
}
LIBSSH2_FREE (session, tmp);
line += i;
i = ssh_proto_str_read (session, line, &tmp, tmp2 + j);
if (i < 0) {
LIBSSH2_FREE (session, tmp2);
return 6;
}
/* TODO: verify that the exponent is valid */
if (i == 5)
s->exponent = (unsigned short) ((unsigned char) *tmp);
else {
LIBSSH2_FREE (session, tmp);
LIBSSH2_FREE (session, tmp2);
return 9;
}
LIBSSH2_FREE (session, tmp);
line += i;
i = ssh_proto_str_read (session, line, &tmp, tmp2 + j);
if (i < 0) {
LIBSSH2_FREE (session, tmp2);
return 7;
}
/* TODO: the modulus may need to be converted to
* big integer format
*/
s->modulus_length = i - 4;
s->modulus = tmp;
s->bits = (s->modulus_length - 1) * 8;
LIBSSH2_FREE (session, tmp2);
return 0;
}
}
LIBSSH2_API void
libssh2_free_host_entry(LIBSSH2_SESSION * session, LIBSSH2_KNOWNHOSTS * s)
{
/* int i; */
if (s == NULL)
return;
if (s->hostname_line != NULL) {
LIBSSH2_FREE (session, s->hostname_line);
s->hostname_line = NULL;
}
if (s->hostnames != NULL && s->hostnames_size > 0) {
LIBSSH2_FREE (session, s->hostnames);
s->hostnames = NULL;
}
s->hostnames_size = s->bits = s->exponent = -1;
if (s->modulus != NULL) {
LIBSSH2_FREE (session, s->modulus);
s->modulus = NULL;
}
s->modulus_length = -1;
s->ssh_version = -1;
if (s->md5 != NULL) {
LIBSSH2_FREE (session, s->md5);
s->md5 = NULL;
}
LIBSSH2_FREE (session, s);
}
#ifdef SSH_HOSTNAME_TESTS
int
ssh_unit_tests (int argc, char **argv)
{
char *l[] = {
"closenet,...,192.0.2.53 1024 37 159...93 closenet.example.net",
"cvs.example.net,192.0.2.10 ssh-rsa AAAA1234.....=",
" cvs.example.net,192.0.2.10 ssh-rsa AAAA1234.....=",
"",
",",
"f, ",
"cvs.example.net ssh-rsa AAAA1234.....=",
"192.168.30.118 ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAQEAwWVqxKm2Biwilakq9Ex8/tzHVQjRrzEkwlrWTDneptodVgqAzXUFQSa6Oj9AwzdDPhKe71vTv7RhXYg0ZvB1a5dIkzgCdoF/mIuTb80LvK7f0NxCaAHWODuHbwlJeMmjHV0WFsjsdOf690fPqeinD/8jfBQB950M1K3Qesib9H75gsnawF06MzZ52nC1HHi8mG2tGy2PMyP+mJs7KN1v4T+nobZ10ePe1dMqYXMdro/PB0JQmuGL7bBR5GRDEkK6nFcp2HsvuzXSeWZJcmWDdo+1n0cNg2th5VEIxrrFG5iy0CA2AXVPMqkf3VrAXGXV66dJTGtBqZ5GoxJCxDgW6w==",
"|1|JfKTdBh7rNbXkVAQCRp4OQoPfmI=|USECr3SWf1JUPsms5AqfD5QfxkM= ssh-rsaAAAA1234.....="
};
int s;
int cases = sizeof (l) / sizeof (char *);
if (argc == 2) {
s = atoi (argv[1]);
if (s >= 0 && s < cases) {
LIBSSH2_KNOWNHOSTS *x = NULL;
printf ("%d\n", s = new_ssh_host_entry (&x, l[s]));
libssh2_free_host_entry (x);
return s;
}
}
}
#endif
/** Returns 0 for a match, non-zero otherwise. */
LIBSSH2_API int
libssh2_host_entry_match(LIBSSH2_KNOWNHOSTS * x, char *host)
{
/* TODO: Add pattern matching and/or DNS matching against
* to entries found in x
*/
int i;
if (host == NULL || x == NULL)
return -1;
/* FIXME: this should use a case-insensitive compare as dns hostnames
* are generally case insensitive anyways
*/
for (i = 0; i < x->hostnames_size; i++)
if (!strcmp (x->hostnames[i], host))
return 0;
return 1;
}

View File

@@ -263,7 +263,7 @@ fullpacket(LIBSSH2_SESSION * session, int encrypted /* 1 or 0 */ )
libssh2pack_t libssh2pack_t
_libssh2_transport_read(LIBSSH2_SESSION * session) _libssh2_transport_read(LIBSSH2_SESSION * session)
{ {
libssh2pack_t rc; libssh2pack_t rc = -1;
struct transportpacket *p = &session->packet; struct transportpacket *p = &session->packet;
int remainbuf; int remainbuf;
int remainpack; int remainpack;
@@ -272,9 +272,11 @@ _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; int status;
/* default clear the bit */
session->socket_block_directions &= ~LIBSSH2_SESSION_BLOCK_INBOUND;
/* /*
* All channels, systems, subsystems, etc eventually make it down here * All channels, systems, subsystems, etc eventually make it down here
* when looking for more incoming data. If a key exchange is going on * when looking for more incoming data. If a key exchange is going on
@@ -375,6 +377,7 @@ _libssh2_transport_read(LIBSSH2_SESSION * session)
} }
return PACKET_FAIL; return PACKET_FAIL;
} }
debugdump(session, "libssh2_transport_read() raw", debugdump(session, "libssh2_transport_read() raw",
&p->buf[remainbuf], nread); &p->buf[remainbuf], nread);
/* advance write pointer */ /* advance write pointer */
@@ -421,7 +424,12 @@ _libssh2_transport_read(LIBSSH2_SESSION * session)
* and we can extract packet and padding length from it * and we can extract packet and padding length from it
*/ */
p->packet_length = _libssh2_ntohu32(block); p->packet_length = _libssh2_ntohu32(block);
if (p->packet_length < 1)
return PACKET_FAIL;
p->padding_length = block[4]; p->padding_length = block[4];
if (p->padding_length < 0)
return PACKET_FAIL;
/* total_num is the number of bytes following the initial /* total_num is the number of bytes following the initial
(5 bytes) packet length and padding length fields */ (5 bytes) packet length and padding length fields */
@@ -605,12 +613,18 @@ send_existing(LIBSSH2_SESSION * session, unsigned char *data,
rc = _libssh2_send(session->socket_fd, &p->outbuf[p->osent], length, rc = _libssh2_send(session->socket_fd, &p->outbuf[p->osent], length,
LIBSSH2_SOCKET_SEND_FLAGS(session)); LIBSSH2_SOCKET_SEND_FLAGS(session));
if(rc > 0) {
debugdump(session, "libssh2_transport_write send()",
&p->outbuf[p->osent], rc);
}
if (rc == length) { if (rc == length) {
/* the remainder of the package was sent */ /* the remainder of the package was sent */
LIBSSH2_FREE(session, p->outbuf); LIBSSH2_FREE(session, p->outbuf);
p->outbuf = NULL; p->outbuf = NULL;
p->ototal_num = 0; p->ototal_num = 0;
} else if (rc < 0) { }
else if (rc < 0) {
/* nothing was sent */ /* nothing was sent */
if (errno != EAGAIN) { if (errno != EAGAIN) {
/* send failure! */ /* send failure! */
@@ -620,9 +634,7 @@ send_existing(LIBSSH2_SESSION * session, unsigned char *data,
return PACKET_EAGAIN; return PACKET_EAGAIN;
} }
debugdump(session, "libssh2_transport_write send()", &p->outbuf[p->osent], p->osent += rc; /* we sent away this much data */
length);
p->osent += length; /* we sent away this much data */
return PACKET_NONE; return PACKET_NONE;
} }
@@ -667,6 +679,9 @@ _libssh2_transport_write(LIBSSH2_SESSION * session, unsigned char *data,
debugdump(session, "libssh2_transport_write plain", data, data_len); debugdump(session, "libssh2_transport_write plain", data, data_len);
/* default clear the bit */
session->socket_block_directions &= ~LIBSSH2_SESSION_BLOCK_OUTBOUND;
/* FIRST, check if we have a pending write to complete */ /* FIRST, check if we have a pending write to complete */
rc = send_existing(session, data, data_len, &ret); rc = send_existing(session, data, data_len, &ret);
if (rc || ret) { if (rc || ret) {
@@ -794,6 +809,3 @@ _libssh2_transport_write(LIBSSH2_SESSION * session, unsigned char *data,
return PACKET_NONE; /* all is good */ return PACKET_NONE; /* all is good */
} }

1
tests/.gitignore vendored Normal file
View File

@@ -0,0 +1 @@
ssh2

View File

@@ -5,7 +5,7 @@
## ##
## Comments to: Guenter Knauf <eflash@gmx.net> ## Comments to: Guenter Knauf <eflash@gmx.net>
## ##
## $Id: Makefile.win32,v 1.10 2009/03/06 07:25:37 gknauf Exp $ ## $Id: Makefile.win32,v 1.11 2009/04/09 03:13:52 gknauf Exp $
# #
######################################################################### #########################################################################
@@ -18,7 +18,7 @@ WITH_ZLIB = 1
# Edit the path below to point to the base of your OpenSSL package. # Edit the path below to point to the base of your OpenSSL package.
ifndef OPENSSL_PATH ifndef OPENSSL_PATH
OPENSSL_PATH = ../../openssl-0.9.8j OPENSSL_PATH = ../../openssl-0.9.8k
endif endif
# Edit the path below to point to your Distribution folder. # Edit the path below to point to your Distribution folder.
@@ -63,7 +63,7 @@ endif
ifdef METROWERKS ifdef METROWERKS
CC = mwcc CC = mwcc
else else
CC = $(CRPREFIX)gcc CC = $(CROSSPREFIX)gcc
endif endif
CP = cp -afv CP = cp -afv
# RM = rm -f # RM = rm -f
@@ -91,13 +91,13 @@ CFLAGS += -nostdinc -gccinc -msgstyle gcc -inline off -opt nointrinsics -proc 58
CFLAGS += -ir "$(METROWERKS)/MSL" -ir "$(METROWERKS)/Win32-x86 Support" CFLAGS += -ir "$(METROWERKS)/MSL" -ir "$(METROWERKS)/Win32-x86 Support"
CFLAGS += -w on,nounused,nounusedexpr # -ansi strict CFLAGS += -w on,nounused,nounusedexpr # -ansi strict
else else
LD = $(CRPREFIX)gcc LD = $(CROSSPREFIX)gcc
RC = $(CRPREFIX)windres RC = $(CROSSPREFIX)windres
LDFLAGS = -s -shared -Wl,--out-implib,$(TARGET)dll.a LDFLAGS = -s -shared -Wl,--out-implib,$(TARGET)dll.a
AR = $(CRPREFIX)ar AR = $(CROSSPREFIX)ar
ARFLAGS = -cq ARFLAGS = -cq
LIBEXT = a LIBEXT = a
RANLIB = $(CRPREFIX)ranlib RANLIB = $(CROSSPREFIX)ranlib
#LDLIBS += -lwsock32 #LDLIBS += -lwsock32
LDLIBS += -lws2_32 LDLIBS += -lws2_32
RCFLAGS = -O coff -i RCFLAGS = -O coff -i

3
win32/msvcproj.foot Normal file
View File

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

145
win32/msvcproj.head Normal file
View File

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

View File

@@ -5,7 +5,7 @@
## ##
## Comments to: Guenter Knauf <eflash@gmx.net> ## Comments to: Guenter Knauf <eflash@gmx.net>
## ##
## $Id: Makefile.win32,v 1.7 2009/03/06 07:25:49 gknauf Exp $ ## $Id: Makefile.win32,v 1.8 2009/04/09 03:14:05 gknauf Exp $
# #
######################################################################### #########################################################################
@@ -16,7 +16,7 @@ endif
# Edit the path below to point to the base of your OpenSSL package. # Edit the path below to point to the base of your OpenSSL package.
ifndef OPENSSL_PATH ifndef OPENSSL_PATH
OPENSSL_PATH = ../../../openssl-0.9.8j OPENSSL_PATH = ../../../openssl-0.9.8k
endif endif
# Edit the var below to enable static linking of libssh2 and libz # Edit the var below to enable static linking of libssh2 and libz
@@ -51,7 +51,7 @@ endif
ifdef METROWERKS ifdef METROWERKS
CC = mwcc CC = mwcc
else else
CC = gcc CC = $(CROSSPREFIX)gcc
endif endif
CP = cp -afv CP = cp -afv
# RM = rm -f # RM = rm -f
@@ -79,19 +79,20 @@ CFLAGS += -nostdinc -gccinc -msgstyle gcc -inline off -opt nointrinsics -proc 58
CFLAGS += -ir "$(METROWERKS)/MSL" -ir "$(METROWERKS)/Win32-x86 Support" CFLAGS += -ir "$(METROWERKS)/MSL" -ir "$(METROWERKS)/Win32-x86 Support"
CFLAGS += -w on,nounused,nounusedexpr # -ansi strict CFLAGS += -w on,nounused,nounusedexpr # -ansi strict
else else
LD = gcc LD = $(CROSSPREFIX)gcc
RC = windres RC = $(CROSSPREFIX)windres
LDFLAGS = -s LDFLAGS = -s
AR = ar AR = $(CROSSPREFIX)ar
ARFLAGS = -cq ARFLAGS = -cq
LIBEXT = a LIBEXT = a
#LDLIBS += -lwsock32 #LDLIBS += -lwsock32
LDLIBS += -lws2_32 LDLIBS += -lws2_32
RCFLAGS = -O coff -i RCFLAGS = -O coff -i
CFLAGS += -fno-strict-aliasing -Wall -Wno-unused # -pedantic CFLAGS += -fno-strict-aliasing
CFLAGS += -Wall #-Wno-unused #-pedantic
endif endif
INCLUDES = -I. -I.. -I../../include INCLUDES = -I.. -I../../include
INCLUDES += -I$(OPENSSL_PATH)/outinc -I$(OPENSSL_PATH)/outinc/openssl INCLUDES += -I$(OPENSSL_PATH)/outinc -I$(OPENSSL_PATH)/outinc/openssl
#LIBPATH += -L$(OPENSSL_PATH)/out #LIBPATH += -L$(OPENSSL_PATH)/out
LIBPATH += -L.. LIBPATH += -L..