Compare commits

..

113 Commits

Author SHA1 Message Date
Daniel Stenberg
6e40af7bea NEWS: add the 1.2.6 release details 2010-06-10 10:19:31 +02:00
Daniel Stenberg
5e46c864dc RELEASE-NOTES: 1.2.6 details added 2010-06-10 10:15:46 +02:00
Guenter Knauf
a4fdf0de01 fixed libssh2.dsw to use the generated libssh2.dsp; removed old *.dsp files. 2010-06-10 02:43:49 +02:00
Guenter Knauf
2c1c751ad1 moved MSVC strdup define to libssh2_config.h which we include already. 2010-06-10 02:31:48 +02:00
Guenter Knauf
f682684fdd added missing source files to src/NMakefile. 2010-06-10 02:28:47 +02:00
Daniel Stenberg
0ad1a52a09 libssh2_poll: refer to poll(3) and select(3) instead 2010-06-08 08:37:37 +02:00
Daniel Stenberg
4e10882e06 example: fix strdup() for MSVC compiles
MSVC has a _strdup() that we better use. This was reported in bug
2010-06-07 13:36:12 +02:00
Daniel Stenberg
eeeebd02e7 SFTP: fail init SFTP if session isn't authenticated
Alexander Lamaison filed bug #172
(http://trac.libssh2.org/ticket/172), and pointed out that SFTP
init would do bad if the session isn't yet authenticated at the
time of the call, so we now check for this situation and returns
an error if detected. Calling sftp_init() at this point is bad
usage to start with.
2010-06-07 13:10:51 +02:00
Daniel Stenberg
f285438022 direct_tcpip: bring back inclusion of libssh2_config.h
In order to increase portability of this example, I'm bringing
the inclusion of libssh2_config.h back, and I also added an
require that header for this example to compile.

I also made all code lines fit within 80 columns.
2010-06-03 13:55:54 +02:00
Guenter Knauf
81912f67e7 cast away a warning. 2010-06-03 05:21:02 +02:00
Guenter Knauf
2996e02482 moved CRT_SECURE_NO_DEPRECATE define up so its defined before the winsock headers are included. 2010-06-03 03:12:20 +02:00
Guenter Knauf
2683fddcca fixed platform detection for MingW32 test makefile. 2010-06-01 21:19:14 +02:00
Guenter Knauf
fa5d6c705d MingW32 has gettimeofday() implemented, so proper ifdef this function here. 2010-06-01 21:09:08 +02:00
Guenter Knauf
b6c6470e7e removed MSVC ifdef since seems we can use __int64 still with latest headers. 2010-06-01 20:24:05 +02:00
Guenter Knauf
dceb3d1452 changed copyright notice for MinW32 and NetWare binaries. 2010-06-01 20:17:05 +02:00
Guenter Knauf
86c935317c cleaned up MSVC ifdefs which where spreaded over 3 places. 2010-06-01 19:32:11 +02:00
Guenter Knauf
aad74b7fa6 added uint8_t typedef for NetWare CLIB platform. 2010-06-01 19:08:19 +02:00
Guenter Knauf
0b593c8a9d if the function declaration gets changed the header should be changed too. 2010-06-01 17:28:46 +02:00
Guenter Knauf
8ff3f62786 this is MSVC specific and doesnt apply for all Win32 compilers;
the uint8_t typedef clashes with MingW32 headers.
2010-06-01 17:15:46 +02:00
Guenter Knauf
4d7b2950d9 updated MingW32 makefiles for latest dependency lib versions. 2010-06-01 16:58:40 +02:00
Guenter Knauf
18569d76de updated NetWare makefiles for latest dependency lib versions. 2010-06-01 16:44:17 +02:00
Dan Fandrich
7a088a8ab7 Fixed compiling with libgcrypt
A change of parameter types from unsigned long to size_t was
missed in the prototype in libgcrypt.h
2010-05-30 22:53:53 -07:00
Daniel Stenberg
d15663477b statvfs: use libssh2_sftp_statvfs only, no "_ex"
As the long-term goal is to get rid of the extensive set of
macros from the API we can just as well start small by not adding
new macros when we add new functions. Therefore we let the
function be libssh2_sftp_statvfs() plainly without using an _ex
suffix.

I also made it use size_t instead of unsigned int for the string
length as that too is a long-term goal for the API.
2010-05-28 17:25:42 +02:00
Grubsky Grigory
8145f9e79c DSP: output lib name typo 2010-05-25 23:28:01 +02:00
Grubsky Grigory
dc747fb221 win32: provide a uint8_t typedef for better building on windows 2010-05-25 23:22:39 +02:00
Daniel Stenberg
76fd96e63e agent: win32: fix bad _libssh2_store_str call
As pointed out by Grubsky Grigory <g.grubsky@securitycode.ru>, I
made a mistake when I added the _libssh2_store_str() call before
and I made a slightly different patch than what he suggested.
Based purely on taste.
2010-05-25 23:19:46 +02:00
Joey Degges
ed526a0e24 Add libssh2_sftp_statvfs() and libssh2_sftp_fstatvfs()
These can be used to get file system statistics from servers that
support the statvfs@openssh.com and fstatvfs@openssh.com extensions.
2010-05-24 07:05:23 +02:00
Jose Baars
667f4acda6 VMS specific: make sure final release can be installed over daily build 2010-05-22 11:06:08 +01:00
Jose Baars
f3208b99ca VMS: small improvement to the man2help utilities 2010-05-22 11:05:29 +01:00
Joey Degges
b702441242 libssh2_exit and libssh2_sftp_readdir man page fixes 2010-05-22 08:30:42 +02:00
Daniel Stenberg
396dcedc56 spelling: s/sue/use 2010-05-21 23:37:43 +02:00
Alexander Lamaison
798a808a2b Change magic port number for generic knownhost check.
libssh2_knownhost_checkp took 0 as a magic port number that indicated
a 'generic' check should be performed.  However, 0 is a valid port
number in its own right so this commit changes the magic value to any
negative int.
2010-05-21 00:01:57 +01:00
Mikhail Gusarov
c8df661129 Add re-discovered copyright holders to COPYING 2010-05-05 15:45:17 +07:00
Mikhail Gusarov
b3ed8e064a Restoring copyright statements from pre-git era
Eli Fant has contributed fragmenting SFTP requests
2010-05-05 15:44:15 +07:00
Mikhail Gusarov
ffb55aa2a3 Restoring my copyright statements from pre-git era
keyboard_interactive, 'exit-status' information packet, non-atomic read/write
under FreeBSD, multi-channel operation bugfixes.
2010-05-05 15:41:19 +07:00
Daniel Stenberg
9251642ef3 pedantic: make the code C90 clean 2010-05-03 22:16:01 +02:00
Peter Stuge
79b97c67c7 Do proper keyboard-interactive user dialog in the sftp.c example 2010-05-03 15:36:16 +02:00
Daniel Stenberg
b23ae2bf22 added to tarball: libssh2_knownhost_checkp.3 2010-05-03 09:45:53 +02:00
Daniel Stenberg
a3f3347c12 knownhost: support [host]:port in knownhost file
OpenSSH has ways to add hosts to the knownhosts file that include
a specific port number which makes the key associated with only
that specific host+port pair. libssh2 previously did not support
this, and I was forced to add a new function to the API to
properly expose this ability to applications:
libssh2_knownhost_checkp()

To *add* such hosts to the knownhosts file, you make sure to pass
on the host name in that manner to the libssh2_knownhost_addc()
function.
2010-05-02 16:56:31 +02:00
Daniel Stenberg
5184aec461 init/exit: mention these were added in 1.2.5 2010-05-01 23:49:45 +02:00
Daniel Stenberg
358aa3e24b libssh2_knownhost_check docs: correct the prototype 2010-05-01 23:35:16 +02:00
Daniel Stenberg
7bbefe0660 examples: avoid use of uninitialized variable 'sock' 2010-04-30 12:30:24 +02:00
Daniel Stenberg
204100e636 KEX: stop pretending we negotiate language
There was some stub-like parts of an implementation for
implementing kex language negotiation that caused clang-analyzer
to warn and as it did nothing I've now removed the dead code.
2010-04-29 23:57:47 +02:00
Daniel Stenberg
6c85370428 Uninitialized argument 2010-04-29 22:01:32 +02:00
Daniel Stenberg
23f02aad11 sftpdir: removed dead assignment 2010-04-29 22:00:05 +02:00
Daniel Stenberg
eb7581e72e Makefile.am: include the VMS-specific config header as well 2010-04-29 20:28:56 +02:00
Jose Baars
a16d67e250 Add VMS specific libssh2_config.h 2010-04-29 20:28:02 +02:00
Daniel Stenberg
ab81b75a8e fix Value stored to 's' is never read warning
and moved variable declaration of s to be more local
2010-04-28 23:28:26 +02:00
Daniel Stenberg
0c918ef72a kexinit: simplify the code and avoid scan-build warning
Previously it would say "Value stored to 's' is never read" due
fourth increment of 's'.
2010-04-28 23:28:26 +02:00
Alexander Lamaison
6c3f2ec815 Removed unecessary brackets. 2010-04-28 17:41:17 +01:00
Alexander Lamaison
f1df0b7fbc Changed sftp_attrsize macro to a static function. 2010-04-28 17:38:00 +01:00
Daniel Stenberg
6f895e3298 release: include the VMS-specific files 2010-04-28 13:28:54 +02:00
Daniel Stenberg
45210d8376 sftp_attrsize: protect the macro argument with proper parentheses 2010-04-28 10:23:40 +02:00
Daniel Stenberg
6a44eff0b5 ssh2_agent: avoid using 'session' uninitialized on failures 2010-04-28 09:13:22 +02:00
Daniel Stenberg
0862a1a39a examples: remove assignments of variable rc that's never used 2010-04-28 09:05:19 +02:00
Daniel Stenberg
514f4d9305 publickey_init: remove useless variable increment 2010-04-28 08:59:17 +02:00
Daniel Stenberg
d5d80d296a hostkey_method_ssh_rsa_init: remove useless variable increment 2010-04-28 08:57:56 +02:00
Daniel Stenberg
568060d266 packet_x11_open: removed useless variable increment
and made the declaration of a variable more local
2010-04-28 08:48:50 +02:00
Daniel Stenberg
6e2a0e603a packet_queue_listener: removed useless variable increment
and made the declaration of a variable more local
2010-04-28 08:47:30 +02:00
Daniel Stenberg
d811478071 sftp_read: move a read_responses array to where its used
I find that this increases readability since the array is used
only in the function call just immediately below and nowhere
else.
2010-04-28 00:39:23 +02:00
Daniel Stenberg
b979af1eee sftp_readdir: turn a small array static const and move it 2010-04-28 00:38:22 +02:00
Daniel Stenberg
37624b61e3 sftp_attrsize: converted function to a macro
This way, the macro can evaluate a static number at compile time
for two out of four uses, and it probably runs faster for the
other two cases too.
2010-04-28 00:23:09 +02:00
Daniel Stenberg
4c26a46362 sftp_open: deal with short channel_write calls
This was an old TODO that just wasn't done before. If
channel_write returns short, that is not an error.
2010-04-28 00:12:47 +02:00
Daniel Stenberg
77efca961d sftp_open: clean up, better check of input data
The clang-analyzer report made it look into this function and
I've went through it to remove a potential use of an
uninitialized variable and I also added some validation of input
data received from the server.

In general, lots of more code in this file need to validate the
input before assuming it is correct: there are servers out there
that have bugs or just have another idea of how to do the SFTP
protocol.
2010-04-27 23:59:55 +02:00
Daniel Stenberg
c28fa65424 bugfix: avoid using the socket if it failed to create one 2010-04-27 15:18:40 +02:00
Daniel Stenberg
03815483be bugfix: potential use of NULL pointer 2010-04-27 15:10:48 +02:00
Daniel Stenberg
67de62d650 libssh2_userauth_password_ex: clarify errors somewhat
The errors mentioned in this man page are possible return codes
but not necessarily the only return codes that this can return.

Also reformatted the typ prototypes somewhat.
2010-04-26 22:28:36 +02:00
Daniel Stenberg
cb42be1a9c examples: fixed and made them more similar
The channel read/write functions can return 0 in legitimate cases
without it being an error, and we need to loop properly if they
return short.
2010-04-26 16:49:30 +02:00
Jose Baars
c511177d39 VMS port of libssh2; changes in the libssh2 common code 2010-04-25 19:57:45 +02:00
Daniel Stenberg
d4edb0b9c3 Makefile: added the two news headers userauth.h and session.h 2010-04-25 19:52:36 +02:00
Daniel Stenberg
71fb9cc93e cleanup: prefer the internal functions
To get the blocking vs non-blocking to work as smooth as possible
and behave better internally, we avoid using the external
interfaces when calling functions internally.

Renamed a few internal functions to use _libssh2 prefix when not
being private within a file, and removed the libssh2_ for one
that was private within the file.
2010-04-25 19:35:43 +02:00
Daniel Stenberg
5163e4ecb8 session_free: remove dead code 2010-04-25 19:35:43 +02:00
Daniel Stenberg
000b0f73d0 libssh2_publickey_init: fixed to work better non-blocking
This was triggered by a clang-analyzer complaint that turned out
to be valid, and it made me dig deeper and fix some generic non-
blocking problems I disovered in the code.

While cleaning this up, I moved session-specific stuff over to a
new session.h header from the libssh2_priv.h header.
2010-04-25 19:35:43 +02:00
Daniel Stenberg
c5602fac58 channel: reduce duplicated free and returns
Simplified the code by trying to free data and return on a single
spot.
2010-04-25 19:35:43 +02:00
Daniel Stenberg
046ff03c3f channel: make variables more local
By making 'data' and 'data_len' more local in several places in
this file it will be easier to spot how they are used and we'll
get less risks to accidentally do bad things with them.
2010-04-25 19:35:43 +02:00
Mikhail Gusarov
d06f983c9c Fix typos in manpages, catched by Lintian 2010-04-24 23:43:07 +07:00
Daniel Stenberg
8620cc03f8 channel_request_pty: simplify the code
clang-analyzer pointed out how 'data' could be accessed as a NULL
pointer if the wrong state was set, and while I don't see that
happen in real-life the code flow is easier to read and follow by
moving the LIBSSH2_FREE() call into the block that is supposed to
deal with the data pointer anyway.
2010-04-24 13:14:12 +02:00
Daniel Stenberg
21f55d0006 libssh2_channel_process_startup: simplify the code
clang-analyzer pointed out how 'data' could be accessed as a NULL
pointer if the wrong state was set, and while I don't see that
happen in real-life the code flow is easier to read and follow by
moving the LIBSSH2_FREE() call into the block that is supposed to
deal with the data pointer anyway.
2010-04-24 13:11:05 +02:00
Daniel Stenberg
88ac2dd43c sftp_close_handle: add precation to not access NULL pointer
clang-analyzer pointed this out as a "Pass-by-value argument in
function call is undefined" but while I can't see exactly how
this can ever happen in reality I think a little check for safety
isn't such a bad thing here.
2010-04-24 13:03:27 +02:00
Daniel Stenberg
26d1698320 scp_write_nonblock: Value stored to 'nread' is never read 2010-04-24 12:58:34 +02:00
Daniel Stenberg
7dfeadef97 scp_write: Value stored to 'ptr' is never read 2010-04-24 12:57:32 +02:00
Daniel Stenberg
5804444936 scp_write_nonblock: Value stored to 'ptr' is never read 2010-04-24 12:56:53 +02:00
Daniel Stenberg
ee5dd3561d sftp_mkdir: less silly output but show failures 2010-04-24 12:56:13 +02:00
Jose Baars
ad1ec1c9e4 VMS port of libssh2 including VMS specific build procedures 2010-04-24 10:11:27 +02:00
Daniel Stenberg
28ef62be20 two variable types changes, made lines less than 80 columns
The two variable type changes are only to match type variable
fields actually read from the binary protocol.
2010-04-20 22:49:32 +02:00
Daniel Stenberg
1acca6e3ee remove check for negative padding_length
It was silly, since it is read as an unsigned char...
2010-04-20 22:48:40 +02:00
Daniel Stenberg
d3a0f2932b hostkey_method_ssh_dss_init: Value stored to 's' is never read 2010-04-18 15:31:46 +02:00
Daniel Stenberg
7adc23a628 libssh2_banner_set: avoid unnecessary increment and explain code 2010-04-18 15:30:03 +02:00
Daniel Stenberg
fca949ea55 agent_transact_unix: remove unused variable 2010-04-18 15:27:47 +02:00
Daniel Stenberg
f8b42cab86 remove two unnecessary increments 2010-04-18 15:26:41 +02:00
Daniel Stenberg
fea133f8d6 more code converted to use _libssh2_store_*() 2010-04-18 15:24:13 +02:00
Daniel Stenberg
9ba30d888e libssh2_publickey_list_fetch: removed unused variables 2010-04-18 15:20:29 +02:00
Daniel Stenberg
5d37cd44aa libssh2_publickey_init: remove unused variables 2010-04-18 15:18:18 +02:00
Daniel Stenberg
be9ee7095e libssh2_scp_send64: added to API to provide large file transfers
The previously existing libssh2_scp_send_ex() function has no way
to send files that are larger than 'size_t' which on 32bit
systems mean 4GB. This new API uses a libssh2_int64_t type and
should thus on most modern systems be able to send enormous
files.
2010-04-17 19:47:50 +02:00
Daniel Stenberg
9209309bc3 sftp_init: remove unused variables and assignments 2010-04-17 19:05:53 +02:00
Daniel Stenberg
2a069503be libssh2_knownhost_check: Value stored to 'keylen' is never read 2010-04-17 19:02:44 +02:00
Daniel Stenberg
182108ac91 hostkey: fix compiler warning 2010-04-17 13:38:20 +02:00
Daniel Stenberg
21a01c96f8 remove unused variable 2010-04-17 13:38:07 +02:00
Daniel Stenberg
100059989f data types: convert more to use size_t and uint32_t 2010-04-17 13:34:44 +02:00
Daniel Stenberg
13caffa00e channel: variable type cleanups 2010-04-17 13:27:17 +02:00
Daniel Stenberg
c3bcdd88a4 cleanups: better binary packet gen, size_t fixes and PACKET_* removal
I'll introduce a new internal function set named

 _libssh2_store_u32
 _libssh2_store_u64
 _libssh2_store_str

That can be used all through the library to build binary outgoing
packets.  Using these instead of the current approach removes
hundreds of lines from the library while at the same time greatly
enhances readability. I've not yet fully converted everything to
use these functions.

I've converted LOTS of 'unsigned long' to 'size_t' where
data/string lengths are dealt with internally. This is The Right
Thing and it will help us make the transition to our
size_t-polished API later on as well.

I'm removing the PACKET_* error codes. They were originally
introduced as a set of separate error codes from the transport
layer, but having its own set of errors turned out to be very
awkward and they were then converted into a set of #defines that
simply maps them to the global libssh2 error codes instead. Now,
I'l take the next logical step and simply replace the PACKET_*
defines with the actual LIBSSH2_ERROR_* defines. It will increase
readability and decrease confusion.

I also separated packet stuff into its own packet.h header file.
2010-04-17 13:18:15 +02:00
Daniel Stenberg
81e63b3657 clarified the return code 2010-04-17 09:55:24 +02:00
Daniel Stenberg
1adcb5234f rename libssh2_error to the correct _libssh2_error
We reserve ^libssh2_ for public symbols and we use _libssh2 as
prefix for internal ones. I fixed the intendation of all these
edits with emacs afterwards, which then changed it slightly more
than just _libssh2_error() expressions but I didn't see any
obvious problems.
2010-04-16 00:18:51 +02:00
Daniel Stenberg
9cc824e27b data type cleanup: made lots of code use size_t etc
A lot of code used 'unsigned long' and the likes when it should
rather just use plain 'int' or use size_t for data lengths.
2010-04-15 20:37:46 +02:00
Daniel Stenberg
2f9c105ec2 wait_socket: make c89 compliant and use two fd_sets for select() 2010-04-15 11:02:41 +02:00
Daniel Stenberg
8ab009c0b0 sftp_readdir: always zero terminate, detail the return code
I also added a description for the 'longentry' field which was
previously undocumented!
2010-04-15 01:16:02 +02:00
Daniel Stenberg
e22cdcea77 sftp_readdir: simplified and bugfixed
This function no longer has any special purpose code for the
single entry case, as it was pointless.

The previous code would overflow the buffers with an off-by-one
in case the file name or longentry data fields received from the
server were exactly as long as the buffer provided to
libssh2_sftp_readdir_ex.

We now make sure that libssh2_sftp_readdir_ex() ALWAYS zero
terminate the buffers it fills in.

The function no longer calls the libssh2_* function again, but
properly uses the internal sftp_* instead.
2010-04-15 01:15:35 +02:00
Daniel Stenberg
7f740368f4 channel/transport: we now drain the outgoing send buffer when we ignore EAGAIN
When we ignore the EAGAIN from the transport layer within channel_write, we
now drain the outgoing transport layer buffer so that remainders in that
won't cause any problems in the next invoke of _libssh2_transport_write()
2010-04-15 01:12:22 +02:00
Daniel Stenberg
8b63dc9e59 channel_write: if data has been sent, don't return EAGAIN
When sending data in a loop, we must not return EAGAIN if we
managed to send data in an earlier round. This was reported in
bug #126 => http://libssh2.stuge.se/ticket/126
2010-04-14 23:35:40 +02:00
Simon Josefsson
77fa740674 Fix OpenSSL AES-128-CTR detection.
Patch from Paul Howarth <paul@city-fan.org>.
2010-04-14 14:04:45 +02:00
Daniel Stenberg
32cf14b512 version in header file now says 1.2.6-DEV 2010-04-13 23:39:39 +02:00
Daniel Stenberg
44cd934fa2 1.2.6: clean the RELEASE-NOTES for next release round 2010-04-13 23:38:21 +02:00
Daniel Stenberg
339ad5ccd3 NEWS: add the stuff from the version 1.2.5 RELEASE-NOTES 2010-04-13 23:37:47 +02:00
85 changed files with 5216 additions and 3263 deletions

View File

@@ -1,5 +1,7 @@
/* Copyright (c) 2004-2007 Sara Golemon <sarag@libssh2.org>
* Copyright (c) 2005,2006 Mikhail Gusarov <dottedmag@dottedmag.net>
* Copyright (c) 2006-2007 The Written Word, Inc.
* Copyright (c) 2007 Eli Fant <elifantu@mail.ru>
* Copyright (c) 2009 Daniel Stenberg
* Copyright (C) 2008, 2009 Simon Josefsson
* All rights reserved.

View File

@@ -21,13 +21,18 @@ VCPROJ = win32/libssh2.vcproj
DISTCLEANFILES = $(DSP)
VMSFILES = vms/libssh2_make_example.dcl vms/libssh2_make_help.dcl \
vms/libssh2_make_kit.dcl vms/libssh2_make_lib.dcl vms/man2help.c \
vms/readme.vms vms/libssh2_config.h
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 \
maketgz NMakefile TODO RELEASE-NOTES libssh2.pc.in
maketgz NMakefile TODO RELEASE-NOTES libssh2.pc.in $(VMSFILES)
ACLOCAL_AMFLAGS = -I m4

View File

@@ -4,4 +4,4 @@ CSOURCES = channel.c comp.c crypt.c hostkey.c kex.c mac.c misc.c \
global.c
HHEADERS = libssh2_priv.h openssl.h libgcrypt.h transport.h channel.h \
comp.h mac.h misc.h
comp.h mac.h misc.h packet.h userauth.h session.h

50
NEWS
View File

@@ -1,3 +1,53 @@
libssh2 1.2.6 (June 10, 2010)
This release includes the following changes:
o Added libssh2_sftp_statvfs() and libssh2_sftp_fstatvfs()
o Added libssh2_knownhost_checkp()
o Added libssh2_scp_send64()
This release includes the following bugfixes:
o wait_socket: make c89 compliant and use two fd_sets for select()
o OpenSSL AES-128-CTR detection
o proper keyboard-interactive user dialog in the sftp.c example
o build procedure for VMS
o fixed libssh2.dsw to use the generated libssh2.dsp
o several Windows-related build fixes
o fail to init SFTP if session isn't already authenticated
o many tiny fixes that address clang-analyzer warnings
o sftp_open: deal with short channel_write calls
o libssh2_publickey_init: fixed to work better non-blocking
o sftp_close_handle: add precation to not access NULL pointer
o sftp_readdir: simplified and bugfixed
o channel_write: if data has been sent, don't return EAGAIN
Version 1.2.5 (April 13, 2010)
This release includes the following changes:
o Added Add keep-alive support: libssh2_keepalive_config() and
libssh2_keepalive_send()
o Added libssh2_knownhost_addc(), libssh2_init() and libssh2_exit()
o Added LIBSSH2_SFTP_S_IS***() macros
This release includes the following bugfixes:
o fix memory leak in libssh2_session_startup()
o added missing error codes - shown as hangs in blocking mode
o fix memory leak in userauth_keyboard_interactive()
o libssh2_knownhost_del: fix write to freed memory
o Send and receive channel EOF before sending SSH_MSG_CHANNEL_CLOSE
o Use AES-CTR from OpenSSL when available
o Fixed gettimeofday to compile with Visual C++ 6
o NULL dereference when window adjusting a non-existing channel
o avoid using poll on interix and mac os x systems
o fix scp memory leak
o Correctly clear blocking flag after sending multipart packet
o Reduce used window sizes by factor 10
o libssh2_userauth_publickey_fromfile_ex() handles a NULL password
o sftp_init() deal with _libssh2_channel_write() short returns
o Use poll instead of select when available. By Paul Querna.
o Add APIs to have libssh2 automatically send keep-alive requests.

View File

@@ -1,33 +1,32 @@
libssh2 1.2.5
libssh2 1.2.6
This release includes the following changes:
o Added Add keep-alive support: libssh2_keepalive_config() and
libssh2_keepalive_send()
o Added libssh2_knownhost_addc(), libssh2_init() and libssh2_exit()
o Added LIBSSH2_SFTP_S_IS***() macros
o Added libssh2_sftp_statvfs() and libssh2_sftp_fstatvfs()
o Added libssh2_knownhost_checkp()
o Added libssh2_scp_send64()
This release includes the following bugfixes:
o fix memory leak in libssh2_session_startup()
o added missing error codes - shown as hangs in blocking mode
o fix memory leak in userauth_keyboard_interactive()
o libssh2_knownhost_del: fix write to freed memory
o Send and receive channel EOF before sending SSH_MSG_CHANNEL_CLOSE
o Use AES-CTR from OpenSSL when available
o Fixed gettimeofday to compile with Visual C++ 6
o NULL dereference when window adjusting a non-existing channel
o avoid using poll on interix and mac os x systems
o fix scp memory leak
o Correctly clear blocking flag after sending multipart packet
o Reduce used window sizes by factor 10
o libssh2_userauth_publickey_fromfile_ex() handles a NULL password
o sftp_init() deal with _libssh2_channel_write() short returns
o wait_socket: make c89 compliant and use two fd_sets for select()
o OpenSSL AES-128-CTR detection
o proper keyboard-interactive user dialog in the sftp.c example
o build procedure for VMS
o fixed libssh2.dsw to use the generated libssh2.dsp
o several Windows-related build fixes
o fail to init SFTP if session isn't already authenticated
o many tiny fixes that address clang-analyzer warnings
o sftp_open: deal with short channel_write calls
o libssh2_publickey_init: fixed to work better non-blocking
o sftp_close_handle: add precation to not access NULL pointer
o sftp_readdir: simplified and bugfixed
o channel_write: if data has been sent, don't return EAGAIN
This release would not have looked like this without help, code, reports and
advice from friends like these:
Peter Stuge, Simon Josefsson, Alexander Lamaison, Paul Querna, Suyog Jadhav,
Lars Nordin
Alexander Lamaison, Guenter Knauf, Dan Fandrich, Grubsky Grigory,
Joey Degges, Jose Baars, Mikhail Gusarov, Peter Stuge, Simon Josefsson,
Daniel Stenberg
Thanks! (and sorry if I forgot to mention someone)

8
TODO
View File

@@ -9,8 +9,6 @@ Things TODO
lib, like when libssh2_session_last_error() is asked to return the string
with 'want_buf' set to non-zero.
* Provide a libssh2_scp_send() API for files larger than 4GB (32bit size)
* Add more info to the man pages.
* Decrease the number of mallocs. Everywhere.
@@ -54,3 +52,9 @@ At next SONAME bump
* remove the existing libssh2_knownhost_add() function and rename
libssh2_knownhost_addc to become the new libssh2_knownhost_add instead
* remove the existing libssh2_scp_send_ex() function and rename
libssh2_scp_send64 to become the new libssh2_scp_send instead.
* remove the existing libssh2_knownhost_check() functin and rename
libssh2_knownhost_checkp() to become the new libssh2_knownhost_check instead

View File

@@ -115,7 +115,7 @@ AM_CONDITIONAL(LIBGCRYPT, test "$ac_cv_libgcrypt" = "yes")
if test "$ac_cv_libssl" = "yes"; then
save_LDFLAGS="$LDFLAGS"
LDFLAGS="$LDFLAGS $LIBSSL"
AC_CHECK_FUNCS(EVP_aes128_ctr)
AC_CHECK_FUNCS(EVP_aes_128_ctr)
LDFLAGS="$save_LDFLAGS"
fi
@@ -295,7 +295,7 @@ AC_MSG_NOTICE([summary of build options:
Compiler: ${CC}
Compiler flags: ${CFLAGS}
Library types: Shared=${enable_shared}, Static=${enable_static}
Crypto library: openssl: ${ac_cv_libssl:-no} (AES-CTR: ${ac_cv_func_EVP_aes128_ctr:-N/A}) libgcrypt: ${ac_cv_libgcrypt:-no}
Crypto library: openssl: ${ac_cv_libssl:-no} (AES-CTR: ${ac_cv_func_EVP_aes_128_ctr:-N/A}) libgcrypt: ${ac_cv_libgcrypt:-no}
Debug build: $enable_debug
Path to sshd: $ac_cv_path_SSHD (only for self-tests)
libz compression: $ac_cv_libz

View File

@@ -66,6 +66,7 @@ dist_man_MANS = \
libssh2_knownhost_add.3 \
libssh2_knownhost_addc.3 \
libssh2_knownhost_check.3 \
libssh2_knownhost_checkp.3 \
libssh2_knownhost_del.3 \
libssh2_knownhost_free.3 \
libssh2_knownhost_get.3 \
@@ -88,6 +89,7 @@ dist_man_MANS = \
libssh2_scp_recv.3 \
libssh2_scp_send.3 \
libssh2_scp_send_ex.3 \
libssh2_scp_send64.3 \
libssh2_session_abstract.3 \
libssh2_session_block_directions.3 \
libssh2_session_callback_set.3 \
@@ -111,6 +113,7 @@ dist_man_MANS = \
libssh2_sftp_fsetstat.3 \
libssh2_sftp_fstat.3 \
libssh2_sftp_fstat_ex.3 \
libssh2_sftp_fstatvfs.3 \
libssh2_sftp_init.3 \
libssh2_sftp_last_error.3 \
libssh2_sftp_lstat.3 \
@@ -134,6 +137,7 @@ dist_man_MANS = \
libssh2_sftp_shutdown.3 \
libssh2_sftp_stat.3 \
libssh2_sftp_stat_ex.3 \
libssh2_sftp_statvfs.3 \
libssh2_sftp_symlink.3 \
libssh2_sftp_symlink_ex.3 \
libssh2_sftp_tell.3 \

View File

@@ -4,11 +4,11 @@ libssh2_exit - global library deinitialization
.SH SYNOPSIS
#include <libssh2.h>
int
void
libssh2_exit(void);
.SH DESCRIPTION
Exit the libssh2 functions and free's all memory used internal.
.SH AVAILABILITY
Added in libssh2 1.2.5
.SH SEE ALSO
.BR libssh2_init(3)

View File

@@ -8,14 +8,13 @@ libssh2_init - global library initialization
int
libssh2_init(int flags);
.SH DESCRIPTION
Initialize the libssh2 functions. This typically initialize the
crypto library. It uses a global state, and is not thread safe -- you
must make sure this function is not called concurrently.
.SH RETURN VALUE
Returns 0 if succeeded, or a negative value for error.
.SH AVAILABILITY
Added in libssh2 1.2.5
.SH SEE ALSO
.BR libssh2_exit(3)

View File

@@ -1,10 +1,11 @@
.\" Copyright (c) 2009 by Daniel Stenberg
.\" Copyright (c) 2009, 2010 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
.nf
#include <libssh2.h>
int libssh2_knownhost_add(LIBSSH2_KNOWNHOSTS *hosts,
@@ -14,7 +15,7 @@ int libssh2_knownhost_add(LIBSSH2_KNOWNHOSTS *hosts,
struct libssh2_knownhost **store);
.SH DESCRIPTION
We discourage use of this function as of libssh2 1.2.5. Instead we strongly
urge users to sue \fIlibssh2_knownhost_addc(3)\fP instead, which as a more
urge users to use \fIlibssh2_knownhost_addc(3)\fP instead, which as a more
complete API. \fIlibssh2_knownhost_add(3)\fP is subject for removal in a
future release.

View File

@@ -7,12 +7,12 @@ 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,
const char *comment, size_t commentlen,
int typemask,
struct libssh2_knownhost **store);
int libssh2_knownhost_addc(LIBSSH2_KNOWNHOSTS *hosts,
char *host, char *salt,
char *key, size_t keylen,
const char *comment, size_t commentlen,
int typemask,
struct libssh2_knownhost **store);
.SH DESCRIPTION
Adds a known host to the collection of known hosts identified by the 'hosts'
handle.
@@ -21,7 +21,12 @@ handle.
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
If you want to add a key for a specific port number for the given host, you
must provide the host name like '[host]:port' with the actual characters '['
and ']' enclosing the host name and a colon separating the host part from the
port number. For example: \&"[host.example.com]:222".
\fIsalt\fP 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.

View File

@@ -8,7 +8,8 @@ libssh2_knownhost_check - check a host+key against the list of known hosts
#include <libssh2.h>
int libssh2_knownhost_check(LIBSSH2_KNOWNHOSTS *hosts,
char *host, char *key, size_t keylen,
const char *host,
const char *key, size_t keylen,
int typemask,
struct libssh2_knownhost **knownhost);
.SH DESCRIPTION

View File

@@ -0,0 +1,63 @@
.\"
.\" Copyright (c) 2009-2010 by Daniel Stenberg
.\"
.TH libssh2_knownhost_check 3 "1 May 2010" "libssh2 1.2.6" "libssh2 manual"
.SH NAME
libssh2_knownhost_checkp - check a host+key against the list of known hosts
.SH SYNOPSIS
#include <libssh2.h>
int libssh2_knownhost_checkp(LIBSSH2_KNOWNHOSTS *hosts,
const char *host, int port,
const 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.
\fIport\fP is the port number used by the host (or a negative number
to check the generic host). If the port number is given, libssh2 will
check the key for the specific host + port number combination in
addition to the plain host name only check.
\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.6
.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

@@ -35,7 +35,7 @@ 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
is then advised 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

View File

@@ -8,7 +8,9 @@ libssh2_poll - poll for activity on a socket, channel or listener
int libssh2_poll(LIBSSH2_POLLFD *fds, unsigned int nfds, long timeout);
.SH DESCRIPTION
This function is deprecated. Do note use.
This function is deprecated. Do note use. We encourage users to instead use
the \fIpoll(3)\fP or \fIselect(3)\fP functions to check for socket activity or
when specific sockets are ready to get recevied from or send to.
Poll for activity on a socket, channel, listener, or any combination of these
three types. The calling semantics for this function generally match

49
docs/libssh2_scp_send64.3 Normal file
View File

@@ -0,0 +1,49 @@
.\" $Id: libssh2_scp_send_ex.3,v 1.3 2009/03/17 10:34:27 bagder Exp $
.\"
.TH libssh2_scp_send64 3 "17 Apr 2010" "libssh2 1.2.6" "libssh2 manual"
.SH NAME
libssh2_scp_send64 - Send a file via SCP
.SH SYNOPSIS
.nf
#include <libssh2.h>
LIBSSH2_CHANNEL *
libssh2_scp_send64(LIBSSH2_SESSION *session, const char *path, int mode,
libssh2_uint64_t size, time_t mtime, time_t atime);
.SH DESCRIPTION
\fIsession\fP - Session instance as returned by
.BR libssh2_session_init_ex(3)
\fIpath\fP - Full path and filename of file to transfer to. That is the remote
file name.
\fImode\fP - File access mode to create file with
\fIsize\fP - Size of file being transmitted (Must be known ahead of
time). Note that this needs to be passed on as variable type
libssh2_uint64_t. This type is 64 bit on modern operating systems and
compilers.
\fImtime\fP - mtime to assign to file being created
\fIatime\fP - atime to assign to file being created (Set this and
mtime to zero to instruct remote host to use current time).
Send a file to the remote host via SCP.
.SH RETURN VALUE
Pointer to a newly allocated LIBSSH2_CHANNEL instance, or NULL on errors.
.SH ERRORS
\fILIBSSH2_ERROR_ALLOC\fP - An internal memory allocation call failed.
\fILIBSSH2_ERROR_SOCKET_SEND\fP - Unable to send data on socket.
\fILIBSSH2_ERROR_SCP_PROTOCOL\fP -
\fILIBSSH2_ERROR_EAGAIN\fP - Marked for non-blocking I/O but the call would
block.
.SH AVAILABILITY
This function was added in libssh2 1.2.6 and is meant to replace the former
\fIlibssh2_scp_send_ex(3)\fP function.
.SH SEE ALSO
.BR libssh2_channel_open_ex(3)

View File

@@ -4,11 +4,16 @@
.SH NAME
libssh2_scp_send_ex - Send a file via SCP
.SH SYNOPSIS
.nf
#include <libssh2.h>
LIBSSH2_CHANNEL *
libssh2_scp_send_ex(LIBSSH2_SESSION *session, const char *path, int mode, size_t size, long mtime, long atime);
libssh2_scp_send_ex(LIBSSH2_SESSION *session, const char *path, int mode,
size_t size, long mtime, long atime);
.SH DESCRIPTION
This function has been deemed deprecated since libssh2 1.2.6. See
\fIlibssh2_scp_send64(3)\fP.
\fIsession\fP - Session instance as returned by
.BR libssh2_session_init_ex(3)
@@ -38,6 +43,8 @@ Pointer to a newly allocated LIBSSH2_CHANNEL instance, or NULL on errors.
\fILIBSSH2_ERROR_EAGAIN\fP - Marked for non-blocking I/O but the call would
block.
.SH AVAILABILITY
This function was marked deprecated in libssh2 1.2.6 as
\fIlibssh2_scp_send64(3)\fP has been introduced to replace this function.
.SH SEE ALSO
.BR libssh2_channel_open_ex(3)

View File

@@ -60,7 +60,7 @@ You will find a full set of defines and macros to identify flags and
permissions on the \fBlibssh2_sftp.h\fP header file, but some of the
most common ones are:
To check for specific user permissons, the set of defines are in the
To check for specific user permissions, the set of defines are in the
pattern LIBSSH2_SFTP_S_I<action><who> where <action> is R, W or X for
read, write and excutable and <who> is USR, GRP and OTH for user,
group and other. So, you check for a user readable file, use the bit

View File

@@ -0,0 +1 @@
.so man3/libssh2_sftp_statvfs.3

View File

@@ -17,7 +17,7 @@ libssh2_sftp_last_error(LIBSSH2_SFTP *sftp);
Returns the last error code produced by the SFTP layer. Note that this only
returns a sensible error code if libssh2 returned LIBSSH2_ERROR_SFTP_PROTOCOL
in a previous call. Using \fBlibssh2_sftp_last_error(3)\fP without a
preceeding SFTP protocol error, it will return an unspecified value.
preceding SFTP protocol error, it will return an unspecified value.
.SH RETURN VALUE
Current error code state of the SFTP instance.

View File

@@ -2,7 +2,7 @@
.\"
.TH libssh2_sftp_readdir 3 "20 Feb 2010" "libssh2 1.2.4" "libssh2 manual"
.SH NAME
libssh2_sftp_readdir - convenience macro for \fIlibssh2_sftp_readdir_exa(3)\fP calls
libssh2_sftp_readdir - convenience macro for \fIlibssh2_sftp_readdir_ex(3)\fP calls
.SH SYNOPSIS
#include <libssh2.h>
@@ -10,10 +10,10 @@ libssh2_sftp_readdir(arguments)
.SH DESCRIPTION
This is a macro defined in a public libssh2 header file that is using the
underlying function \fIlibssh2_sftp_readdir_exa(3)\fP.
underlying function \fIlibssh2_sftp_readdir_ex(3)\fP.
.SH RETURN VALUE
See \fIlibssh2_sftp_readdir_exa(3)\fP
See \fIlibssh2_sftp_readdir_ex(3)\fP
.SH ERRORS
See \fIlibssh2_sftp_readdir_exa(3)\fP
See \fIlibssh2_sftp_readdir_ex(3)\fP
.SH SEE ALSO
.BR \fIlibssh2_sftp_readdir_exa(3)\fP
.BR \fIlibssh2_sftp_readdir_ex(3)\fP

View File

@@ -4,16 +4,22 @@
.SH NAME
libssh2_sftp_readdir_ex - read directory data from an SFTP handle
.SH SYNOPSIS
.nf
#include <libssh2.h>
#include <libssh2_sftp.h>
int
libssh2_sftp_readdir_ex(LIBSSH2_SFTP_HANDLE *handle, char *buffer, size_t buffer_maxlen, char *longentry, size_t longentry_maxlen, LIBSSH2_SFTP_ATTRIBUTES *attrs);
int
libssh2_sftp_readdir(LIBSSH2_SFTP_HANDLE *handle, char *buffer, size_t buffer_maxlen, LIBSSH2_SFTP_ATTRIBUTES *attrs);
libssh2_sftp_readdir_ex(LIBSSH2_SFTP_HANDLE *handle,
char *buffer, size_t buffer_maxlen,
char *longentry, size_t longentry_maxlen,
LIBSSH2_SFTP_ATTRIBUTES *attrs);
#define libssh2_sftp_readdir(h, b, bl, a) \\
libssh2_sftp_readdir_ex((h), (b), (bl), NULL, 0, (a))
.SH DESCRIPTION
Reads a block of data from a LIBSSH2_SFTP_HANDLE and returns file entry
information for the next entry, if any.
\fIhandle\fP - is the SFTP File Handle as returned by
.BR libssh2_sftp_open_ex(3)
@@ -25,25 +31,22 @@ filename is longer than the space provided by buffer_maxlen it will be
truncated to fit.
\fIlongentry\fP - is a pointer to a pre-allocated buffer of at least
\fIlongentry_maxlen\fP bytes to read data into.
\fIlongentry_maxlen\fP bytes to read data into. The format of the `longname'
field is unspecified by SFTP protocol. It MUST be suitable for use in the
output of a directory listing command (in fact, the recommended operation for
a directory listing command is to simply display this data).
\fIlongentry_maxlen\fP - is the length of longentry in bytes. If the length
of the full directory entry is longer than the space provided by
longentry_maxlen it will be truncated to fit.
\fIlongentry_maxlen\fP - is the length of longentry in bytes. If the length of
the full directory entry is longer than the space provided by
\fIlongentry_maxlen\fP it will be truncated to fit.
\fIattrs\fP - is a pointer to LIBSSH2_SFTP_ATTRIBUTES storage to populate
statbuf style data into.
Read a block of data from a LIBSSH2_SFTP_HANDLE. This method is modeled
after the POSIX
.BR readdir(2)
however, it uses a variable sized directory entry (filename) buffer and
returns statbuf type data in the same call.
.SH RETURN VALUE
Number of bytes actually populated into buffer, or negative on failure. It
returns LIBSSH2_ERROR_EAGAIN when it would otherwise block. While
LIBSSH2_ERROR_EAGAIN is a negative number, it isn't really a failure per se.
Number of bytes actually populated into buffer (not counting the terminating
zero), or negative on failure. It returns LIBSSH2_ERROR_EAGAIN when it would
otherwise block. While LIBSSH2_ERROR_EAGAIN is a negative number, it isn't
really a failure per se.
.SH ERRORS
\fILIBSSH2_ERROR_ALLOC\fP - An internal memory allocation call failed.

View File

@@ -25,7 +25,7 @@ libssh2_sftp_setstat(LIBSSH2_SFTP *sftp, const char *path, LIBSSH2_SFTP_ATTRIBUT
\fIpath\fP - Remote filesystem object to stat/lstat/setstat.
\fIpath_len\fP - Lenght of the name of the remote filesystem object
\fIpath_len\fP - Length of the name of the remote filesystem object
to stat/lstat/setstat.
\fIstat_type\fP - One of the three constants specifying the type of

View File

@@ -0,0 +1,79 @@
.TH libssh2_sftp_statvfs 3 "22 May 2010" "libssh2 1.2.6" "libssh2 manual"
.SH NAME
libssh2_sftp_statvfs, libssh2_sftp_fstatvfs - get file system statistics
.SH SYNOPSIS
.nf
#include <libssh2.h>
#include <libssh2_sftp.h>
int
libssh2_sftp_statvfs(LIBSSH2_SFTP *sftp, const char *path,
size_t path_len, LIBSSH2_SFTP_STATVFS *st);
int
libssh2_sftp_fstatvfs(LIBSSH2_SFTP_HANDLE *handle,
LIBSSH2_SFTP_STATVFS *st)
.fi
.SH DESCRIPTION
These functions provide statvfs(2)-like operations and require
statvfs@openssh.com and fstatvfs@openssh.com extension support on the server.
\fIsftp\fP - SFTP instance as returned by
.BR libssh2_sftp_init(3)
\fIhandle\fP - SFTP File Handle as returned by
.BR libssh2_sftp_open_ex(3)
\fIpath\fP - full path of any file within the mounted file system.
\fIpath_len\fP - length of the full path.
\fIst\fP - Pointer to a LIBSSH2_SFTP_STATVFS structure to place file system
statistics into.
.SH DATA TYPES
LIBSSH2_SFTP_STATVFS is a typedefed struct that is defined as below
.nf
struct _LIBSSH2_SFTP_STATVFS {
libssh2_uint64_t f_bsize; /* file system block size */
libssh2_uint64_t f_frsize; /* fragment size */
libssh2_uint64_t f_blocks; /* size of fs in f_frsize units */
libssh2_uint64_t f_bfree; /* # free blocks */
libssh2_uint64_t f_bavail; /* # free blocks for non-root */
libssh2_uint64_t f_files; /* # inodes */
libssh2_uint64_t f_ffree; /* # free inodes */
libssh2_uint64_t f_favail; /* # free inodes for non-root */
libssh2_uint64_t f_fsid; /* file system ID */
libssh2_uint64_t f_flag; /* mount flags */
libssh2_uint64_t f_namemax; /* maximum filename length */
};
.fi
It is unspecified whether all members of the returned struct have meaningful
values on all file systems.
The field \fIf_flag\fP is a bit mask. Bits are defined as follows:
.IP LIBSSH2_SFTP_ST_RDONLY
Read-only file system.
.IP LIBSSH2_SFTP_ST_NOSUID
Set-user-ID/set-group-ID bits are ignored by \fBexec\fP(3).
.SH RETURN VALUE
Returns 0 on success or negative on failure. If used in non-blocking mode, it
returns LIBSSH2_ERROR_EAGAIN when it would otherwise block. While
LIBSSH2_ERROR_EAGAIN is a negative number, it isn't really a failure per se.
.SH ERRORS
\fILIBSSH2_ERROR_ALLOC\fP - An internal memory allocation call failed.
\fILIBSSH2_ERROR_SOCKET_SEND\fP - Unable to send data on socket.
\fILIBSSH2_ERROR_SOCKET_TIMEOUT\fP -
\fILIBSSH2_ERROR_SFTP_PROTOCOL\fP - An invalid SFTP protocol response was
received on the socket, or an SFTP operation caused an errorcode to be returned
by the server.
.SH AVAILABILITY
Added in libssh2 1.2.6
.SH SEE ALSO
.BR libssh2_sftp_open_ex(3)

View File

@@ -4,22 +4,28 @@
.SH NAME
libssh2_sftp_symlink_ex - read or set a symbolic link
.SH SYNOPSIS
.nf
#include <libssh2.h>
#include <libssh2_sftp.h>
int
libssh2_sftp_symlink_ex(LIBSSH2_SFTP *sftp, const char *path, unsigned int path_len, char *target, unsigned int target_len, int link_type);
libssh2_sftp_symlink_ex(LIBSSH2_SFTP *sftp, const char *path,
unsigned int path_len, char *target,
unsigned int target_len, int link_type);
int
libssh2_sftp_symlink(LIBSSH2_SFTP *sftp, const char *path, char *target);
int
libssh2_sftp_readlink(LIBSSH2_SFTP *sftp, const char *path, char *target, unsigned int target_len);
libssh2_sftp_readlink(LIBSSH2_SFTP *sftp, const char *path, char *target,
unsigned int target_len);
int
libssh2_sftp_realpath(LIBSSH2_SFTP *sftp, const char *path, char *target, unsigned int target_len);
libssh2_sftp_realpath(LIBSSH2_SFTP *sftp, const char *path, char *target,
unsigned int target_len);
.SH DESCRIPTION
Create a symlink or read out symlink information from the remote side.
\fIsftp\fP - SFTP instance as returned by
.BR libssh2_sftp_init(3)
@@ -28,19 +34,24 @@ libssh2_sftp_realpath(LIBSSH2_SFTP *sftp, const char *path, char *target, unsign
\fIpath_len\fP - Length of the name of the remote filesystem object to
create a symlink from or resolve.
\fItarget\fP -
\fItarget\fP - a pointer to a buffer. The buffer has different uses depending
what the \fIlink_type\fP argument is set to.
.br
\fBLIBSSH2_SFTP_SYMLINK\fP: Remote filesystem object to link to.
.br
\fBLIBSSH2_SFTP_READLINK\fP: Pre-allocated buffer to resolve symlink target into.
\fBLIBSSH2_SFTP_READLINK\fP: Pre-allocated buffer to resolve symlink target
into.
.br
\fBLIBSSH2_SFTP_REALPATH\fP: Pre-allocated buffer to resolve realpath target into.
\fBLIBSSH2_SFTP_REALPATH\fP: Pre-allocated buffer to resolve realpath target
into.
\fItarget_len\fP - Length of the name of the remote filesystem target object.
\fIlink_type\fP - One of the three previously mentioned constants which
determines the resulting behavior of this function.
These are convenience macros:
.BR libssh2_sftp_symlink(3)
: Create a symbolic link between two filesystem objects.
.br
@@ -49,12 +60,16 @@ determines the resulting behavior of this function.
.br
.BR libssh2_sftp_realpath(3)
: Resolve a complex, relative, or symlinked filepath to its effective target.
.SH RETURN VALUE
Return 0 on success or negative on failure. It returns
LIBSSH2_ERROR_EAGAIN when it would otherwise block. While
LIBSSH2_ERROR_EAGAIN is a negative number, it isn't really a failure per se.
When using LIBSSH2_SFTP_SYMLINK, this funtion returns 0 on success or negative
on failure.
When using LIBSSH2_SFTP_READLINK or LIBSSH2_SFTP_REALPATH, it returns the
number of bytes it copied to the target buffer (not including the terminating
zero) or negative on failure.
It returns LIBSSH2_ERROR_EAGAIN when it would otherwise block. While
LIBSSH2_ERROR_EAGAIN is a negative number, it isn't really a failure per se.
.SH ERRORS
\fILIBSSH2_ERROR_ALLOC\fP - An internal memory allocation call failed.

View File

@@ -5,13 +5,18 @@
libssh2_userauth_password_ex - authenticate a session with username and password
.SH SYNOPSIS
#include <libssh2.h>
.nf
int libssh2_userauth_password_ex(LIBSSH2_SESSION *session,
const char *username,
unsigned int username_len,
const char *password,
unsigned int password_len,
LIBSSH2_PASSWD_CHANGEREQ_FUNC((*passwd_change_cb)));
int
libssh2_userauth_password_ex(LIBSSH2_SESSION *session, const char *username, unsigned int username_len, const char *password, unsigned int password_len, LIBSSH2_PASSWD_CHANGEREQ_FUNC((*passwd_change_cb)));
int
libssh2_userauth_password(LIBSSH2_SESSION *session, const char *username, const char *password);
#define libssh2_userauth_password(session, username, password) \\
libssh2_userauth_password_ex((session), (username), \\
strlen(username), \\
(password), strlen(password), NULL)
.SH DESCRIPTION
\fIsession\fP - Session instance as returned by
.BR libssh2_session_init_ex(3)
@@ -40,13 +45,15 @@ LIBSSH2_ERROR_EAGAIN when it would otherwise block. While
LIBSSH2_ERROR_EAGAIN is a negative number, it isn't really a failure per se.
.SH ERRORS
Some of the errors this function may return include:
\fILIBSSH2_ERROR_ALLOC\fP - An internal memory allocation call failed.
\fILIBSSH2_ERROR_SOCKET_SEND\fP - Unable to send data on socket.
\fILIBSSH2_ERROR_PASSWORD_EXPIRED\fP -
\fLIBSSH2_ERROR_AUTHENTICATION_FAILED\fP - failed, invalid username/password or public/private key.
\fLIBSSH2_ERROR_AUTHENTICATION_FAILED\fP - failed, invalid username/password
or public/private key.
.SH SEE ALSO
.BR libssh2_session_init_ex(3)

View File

@@ -1,3 +1,4 @@
#include "libssh2_config.h"
#include <libssh2.h>
#ifdef WIN32
@@ -18,6 +19,10 @@
#include <unistd.h>
#include <sys/types.h>
#ifdef HAVE_SYS_SELECT_H
#include <sys/select.h>
#endif
#ifndef INADDR_NONE
#define INADDR_NONE (in_addr_t)-1
#endif
@@ -150,7 +155,8 @@ int main(int argc, char *argv[])
goto shutdown;
}
} else if (auth & AUTH_PUBLICKEY) {
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");
goto shutdown;
}
@@ -197,8 +203,9 @@ int main(int argc, char *argv[])
channel = libssh2_channel_direct_tcpip_ex(session, remote_desthost,
remote_destport, shost, sport);
if (!channel) {
fprintf(stderr, "Could not open the direct-tcpip channel!\n");
fprintf(stderr, "(Note that this can be a problem at the server! Please review the server logs.)\n");
fprintf(stderr, "Could not open the direct-tcpip channel!\n"
"(Note that this can be a problem at the server!"
" Please review the server logs.)\n");
goto shutdown;
}

View File

@@ -47,7 +47,7 @@ int main(int argc, char *argv[])
FILE *local;
int rc;
char mem[1024];
size_t nread, sent;
size_t nread;
char *ptr;
struct stat fileinfo;
@@ -84,7 +84,7 @@ int main(int argc, char *argv[])
local = fopen(loclfile, "rb");
if (!local) {
fprintf(stderr, "Can't open local file %s\n", loclfile);
goto shutdown;
return -1;
}
stat(loclfile, &fileinfo);
@@ -94,6 +94,10 @@ int main(int argc, char *argv[])
* connection
*/
sock = socket(AF_INET, SOCK_STREAM, 0);
if(-1 == sock) {
fprintf(stderr, "failed to create socket!\n");
return -1;
}
sin.sin_family = AF_INET;
sin.sin_port = htons(22);
@@ -168,20 +172,21 @@ int main(int argc, char *argv[])
break;
}
ptr = mem;
sent = 0;
do {
/* write the same data over and over, until error or completion */
rc = libssh2_channel_write(channel, ptr, nread);
if (rc < 0) {
fprintf(stderr, "ERROR %d\n", rc);
} else {
/* rc indicates how many bytes were written this time */
sent += rc;
break;
}
} while (rc > 0 && sent < nread);
ptr += sent;
nread -= sent;
else {
/* rc indicates how many bytes were written this time */
ptr += rc;
nread -= rc;
}
} while (nread);
} while (1);
fprintf(stderr, "Sending EOF\n");

View File

@@ -39,7 +39,7 @@ int main(int argc, char *argv[])
int sock, i, auth_pw = 1;
struct sockaddr_in sin;
const char *fingerprint;
LIBSSH2_SESSION *session;
LIBSSH2_SESSION *session = NULL;
LIBSSH2_CHANNEL *channel;
const char *username="username";
const char *password="password";
@@ -51,7 +51,7 @@ int main(int argc, char *argv[])
long flag = 1;
#endif
char mem[1024];
size_t nread, sent;
size_t nread;
char *ptr;
struct stat fileinfo;
@@ -88,7 +88,7 @@ int main(int argc, char *argv[])
local = fopen(loclfile, "rb");
if (!local) {
fprintf(stderr, "Can't local file %s\n", loclfile);
goto shutdown;
return -1;
}
stat(loclfile, &fileinfo);
@@ -182,7 +182,6 @@ int main(int argc, char *argv[])
break;
}
ptr = mem;
sent = 0;
do {
/* write the same data over and over, until error or completion */
@@ -191,14 +190,14 @@ int main(int argc, char *argv[])
continue;
} else if (rc < 0) {
fprintf(stderr, "ERROR %d\n", rc);
break;
} else {
/* rc indicates how many bytes were written this time */
sent += rc;
nread -= rc;
ptr += rc;
}
} while (rc > 0 && sent < nread);
ptr += sent;
nread -= sent;
} while (1);
} while (nread);
} while (!nread); /* only continue if nread was drained */
fprintf(stderr, "Sending EOF\n");
while (libssh2_channel_send_eof(channel) == LIBSSH2_ERROR_EAGAIN);
@@ -214,8 +213,9 @@ int main(int argc, char *argv[])
shutdown:
while ((rc = libssh2_session_disconnect(session,
"Normal Shutdown, Thank you for playing")) == LIBSSH2_ERROR_EAGAIN);
while (libssh2_session_disconnect(session,
"Normal Shutdown, Thank you for playing") ==
LIBSSH2_ERROR_EAGAIN);
libssh2_session_free(session);
#ifdef WIN32

View File

@@ -52,17 +52,45 @@ static void kbd_callback(const char *name, int name_len,
LIBSSH2_USERAUTH_KBDINT_RESPONSE *responses,
void **abstract)
{
(void)name;
(void)name_len;
(void)instruction;
(void)instruction_len;
if (num_prompts == 1) {
responses[0].text = strdup(password);
responses[0].length = strlen(password);
}
(void)prompts;
int i;
size_t n;
char buf[1024];
(void)abstract;
} /* kbd_callback */
printf("Performing keyboard-interactive authentication.\n");
printf("Authentication name: '");
fwrite(name, 1, name_len, stdout);
printf("'\n");
printf("Authentication instruction: '");
fwrite(instruction, 1, instruction_len, stdout);
printf("'\n");
printf("Number of prompts: %d\n\n", num_prompts);
for (i = 0; i < num_prompts; i++) {
printf("Prompt %d from server: '", i);
fwrite(prompts[i].text, 1, prompts[i].length, stdout);
printf("'\n");
printf("Please type response: ");
fgets(buf, sizeof(buf), stdin);
n = strlen(buf);
while (n > 0 && strchr("\r\n", buf[n - 1]))
n--;
buf[n] = 0;
responses[i].text = strdup(buf);
responses[i].length = n;
printf("Response %d from user is '", i);
fwrite(responses[i].text, 1, responses[i].length, stdout);
printf("'\n\n");
}
printf("Done. Sending keyboard-interactive responses to server now.\n");
}
int main(int argc, char *argv[])

View File

@@ -246,7 +246,7 @@ int main(int argc, char *argv[])
nread);
ptr += rc;
nread -= nread;
} while (rc > 0);
} while (rc >= 0);
if(rc != LIBSSH2_ERROR_EAGAIN) {
/* error or end of file */

View File

@@ -135,7 +135,6 @@ int main(int argc, char *argv[])
}
}
fprintf(stderr, "libssh2_sftp_init()!\n");
sftp_session = libssh2_sftp_init(session);
if (!sftp_session) {
@@ -146,13 +145,15 @@ int main(int argc, char *argv[])
/* Since we have not set non-blocking, tell libssh2 we are blocking */
libssh2_session_set_blocking(session, 1);
fprintf(stderr, "libssh2_sftp_mkdir()!\n");
/* Make a directory via SFTP */
rc = libssh2_sftp_mkdir(sftp_session, sftppath,
LIBSSH2_SFTP_S_IRWXU|
LIBSSH2_SFTP_S_IRGRP|LIBSSH2_SFTP_S_IXGRP|
LIBSSH2_SFTP_S_IROTH|LIBSSH2_SFTP_S_IXOTH);
if(rc)
fprintf(stderr, "libssh2_sftp_mkdir failed: %d\n", rc);
libssh2_sftp_shutdown(sftp_session);
shutdown:

View File

@@ -151,13 +151,11 @@ int main(int argc, char *argv[])
fprintf(stderr, "libssh2_sftp_mkdirnb()!\n");
/* Make a directory via SFTP */
while ((rc = libssh2_sftp_mkdir(sftp_session, sftppath,
LIBSSH2_SFTP_S_IRWXU|
LIBSSH2_SFTP_S_IRGRP|LIBSSH2_SFTP_S_IXGRP|
LIBSSH2_SFTP_S_IROTH|LIBSSH2_SFTP_S_IXOTH))
== LIBSSH2_ERROR_EAGAIN) {
;
}
while (libssh2_sftp_mkdir(sftp_session, sftppath,
LIBSSH2_SFTP_S_IRWXU|
LIBSSH2_SFTP_S_IRGRP|LIBSSH2_SFTP_S_IXGRP|
LIBSSH2_SFTP_S_IROTH|LIBSSH2_SFTP_S_IXOTH)
== LIBSSH2_ERROR_EAGAIN);
libssh2_sftp_shutdown(sftp_session);

View File

@@ -265,8 +265,8 @@ int main(int argc, char *argv[])
shutdown:
printf("libssh2_session_disconnect\n");
while ((rc = libssh2_session_disconnect(session,
"Normal Shutdown, Thank you")) ==
while (libssh2_session_disconnect(session,
"Normal Shutdown, Thank you") ==
LIBSSH2_ERROR_EAGAIN);
libssh2_session_free(session);

View File

@@ -88,7 +88,7 @@ int main(int argc, char *argv[])
local = fopen(loclfile, "rb");
if (!local) {
printf("Can't local file %s\n", loclfile);
goto shutdown;
return -1;
}
/*
@@ -185,10 +185,13 @@ int main(int argc, char *argv[])
do {
/* write data in a loop until we block */
rc = libssh2_sftp_write(sftp_handle, ptr, nread);
if(rc < 0)
break;
ptr += rc;
nread -= nread;
} while (rc > 0);
} while (1);
nread -= rc;
} while (nread);
} while (rc > 0);
libssh2_sftp_close(sftp_handle);
libssh2_sftp_shutdown(sftp_session);

View File

@@ -91,7 +91,7 @@ int main(int argc, char *argv[])
local = fopen(loclfile, "rb");
if (!local) {
printf("Can't local file %s\n", loclfile);
goto shutdown;
return -1;
}
/*
@@ -199,9 +199,9 @@ int main(int argc, char *argv[])
;
}
ptr += rc;
nread -= nread;
} while (rc > 0);
} while (1);
nread -= rc;
} while (nread);
} while (rc > 0);
fclose(local);
libssh2_sftp_close(sftp_handle);
@@ -209,7 +209,8 @@ int main(int argc, char *argv[])
shutdown:
while ((rc = libssh2_session_disconnect(session, "Normal Shutdown, Thank you for playing")) == LIBSSH2_ERROR_EAGAIN);
while (libssh2_session_disconnect(session, "Normal Shutdown, Thank you for playing")
== LIBSSH2_ERROR_EAGAIN);
libssh2_session_free(session);
#ifdef WIN32

View File

@@ -121,7 +121,7 @@ int main(int argc, char *argv[])
if (auth_pw) {
/* We could authenticate via password */
if ((i = libssh2_userauth_password(session, username, password))) {
if (libssh2_userauth_password(session, username, password)) {
printf("Authentication by password failed.\n");
goto shutdown;
}

View File

@@ -41,11 +41,11 @@ const char *username="username";
int main(int argc, char *argv[])
{
unsigned long hostaddr;
int sock = -1, i, j, rc;
int sock = -1, i, rc;
struct sockaddr_in sin;
const char *fingerprint;
char *userauthlist;
LIBSSH2_SESSION *session;
LIBSSH2_SESSION *session = NULL;
LIBSSH2_CHANNEL *channel;
LIBSSH2_AGENT *agent = NULL;
struct libssh2_agent_publickey *identity, *prev_identity = NULL;
@@ -218,9 +218,11 @@ int main(int argc, char *argv[])
libssh2_agent_disconnect(agent);
libssh2_agent_free(agent);
libssh2_session_disconnect(session,
"Normal Shutdown, Thank you for playing");
libssh2_session_free(session);
if(session) {
libssh2_session_disconnect(session,
"Normal Shutdown, Thank you for playing");
libssh2_session_free(session);
}
if (sock != -1) {
#ifdef WIN32

View File

@@ -167,12 +167,21 @@ int main(int argc, char *argv[])
fingerprint = libssh2_session_hostkey(session, &len, &type);
if(fingerprint) {
struct libssh2_knownhost *host;
int check = libssh2_knownhost_check(nh, (char *)hostname,
(char *)fingerprint, len,
#if LIBSSH2_VERSION_NUM >= 0x010206
/* introduced in 1.2.6 */
int check = libssh2_knownhost_checkp(nh, hostname, 22,
fingerprint, len,
LIBSSH2_KNOWNHOST_TYPE_PLAIN|
LIBSSH2_KNOWNHOST_KEYENC_RAW,
&host);
#else
/* 1.2.5 or older */
int check = libssh2_knownhost_check(nh, hostname,
fingerprint, len,
LIBSSH2_KNOWNHOST_TYPE_PLAIN|
LIBSSH2_KNOWNHOST_KEYENC_RAW,
&host);
#endif
fprintf(stderr, "Host check: %d, key: %s\n", check,
(check <= LIBSSH2_KNOWNHOST_CHECK_MISMATCH)?
host->key:"<none>");

View File

@@ -69,16 +69,18 @@ extern "C" {
#if (defined(NETWARE) && !defined(__NOVELL_LIBC__))
# include <sys/bsdskt.h>
typedef unsigned char uint8_t;
typedef unsigned int uint32_t;
#endif
#if defined(LIBSSH2_WIN32) && defined(_MSC_VER) && (_MSC_VER <= 1400)
#if defined(LIBSSH2_WIN32) && defined(_MSC_VER)
typedef unsigned char uint8_t;
typedef unsigned int uint32_t;
typedef unsigned __int64 libssh2_uint64_t;
typedef __int64 libssh2_int64_t;
typedef unsigned int uint32_t;
#ifndef _SSIZE_T_DEFINED
# ifndef _SSIZE_T_DEFINED
typedef int ssize_t;
#define _SSIZE_T_DEFINED
# define _SSIZE_T_DEFINED
#endif
#else
typedef unsigned long long libssh2_uint64_t;
@@ -89,13 +91,13 @@ typedef long long libssh2_int64_t;
to make the BANNER define (used by src/session.c) be a valid SSH
banner. Release versions have no appended strings and may of course not
have dashes either. */
#define LIBSSH2_VERSION "1.2.5_DEV"
#define LIBSSH2_VERSION "1.2.6_DEV"
/* The numeric version number is also available "in parts" by using these
defines: */
#define LIBSSH2_VERSION_MAJOR 1
#define LIBSSH2_VERSION_MINOR 2
#define LIBSSH2_VERSION_PATCH 5
#define LIBSSH2_VERSION_PATCH 6
/* This is the numeric version of the libssh2 version number, meant for easier
parsing and comparions by programs. The LIBSSH2_VERSION_NUM define will
@@ -112,7 +114,7 @@ typedef long long libssh2_int64_t;
and it is always a greater number in a more recent release. It makes
comparisons with greater than and less than work.
*/
#define LIBSSH2_VERSION_NUM 0x010205
#define LIBSSH2_VERSION_NUM 0x010206
/*
* This is the date and time when the full source package was created. The
@@ -710,6 +712,10 @@ LIBSSH2_API LIBSSH2_CHANNEL *libssh2_scp_send_ex(LIBSSH2_SESSION *session,
const char *path, int mode,
size_t size, long mtime,
long atime);
LIBSSH2_API LIBSSH2_CHANNEL *
libssh2_scp_send64(LIBSSH2_SESSION *session, const char *path, int mode,
libssh2_int64_t size, time_t mtime, time_t atime);
#define libssh2_scp_send(session, path, mode, size) \
libssh2_scp_send_ex((session), (path), (mode), (size), 0, 0)
@@ -852,6 +858,15 @@ libssh2_knownhost_check(LIBSSH2_KNOWNHOSTS *hosts,
int typemask,
struct libssh2_knownhost **knownhost);
/* this function is identital to the above one, but also takes a port
argument that allows libssh2 to do a better check */
LIBSSH2_API int
libssh2_knownhost_checkp(LIBSSH2_KNOWNHOSTS *hosts,
const char *host, int port,
const char *key, size_t keylen,
int typemask,
struct libssh2_knownhost **knownhost);
/*
* libssh2_knownhost_del
*

View File

@@ -59,6 +59,7 @@ extern "C" {
typedef struct _LIBSSH2_SFTP LIBSSH2_SFTP;
typedef struct _LIBSSH2_SFTP_HANDLE LIBSSH2_SFTP_HANDLE;
typedef struct _LIBSSH2_SFTP_ATTRIBUTES LIBSSH2_SFTP_ATTRIBUTES;
typedef struct _LIBSSH2_SFTP_STATVFS LIBSSH2_SFTP_STATVFS;
/* Flags for open_ex() */
#define LIBSSH2_SFTP_OPENFILE 0
@@ -86,6 +87,10 @@ typedef struct _LIBSSH2_SFTP_ATTRIBUTES LIBSSH2_SFTP_ATTRIBUTES;
#define LIBSSH2_SFTP_ATTR_ACMODTIME 0x00000008
#define LIBSSH2_SFTP_ATTR_EXTENDED 0x80000000
/* SFTP statvfs flag bits */
#define LIBSSH2_SFTP_ST_RDONLY 0x00000001
#define LIBSSH2_SFTP_ST_NOSUID 0x00000002
struct _LIBSSH2_SFTP_ATTRIBUTES {
/* If flags & ATTR_* bit is set, then the value in this struct will be
* meaningful Otherwise it should be ignored
@@ -98,6 +103,20 @@ struct _LIBSSH2_SFTP_ATTRIBUTES {
unsigned long atime, mtime;
};
struct _LIBSSH2_SFTP_STATVFS {
libssh2_uint64_t f_bsize; /* file system block size */
libssh2_uint64_t f_frsize; /* fragment size */
libssh2_uint64_t f_blocks; /* size of fs in f_frsize units */
libssh2_uint64_t f_bfree; /* # free blocks */
libssh2_uint64_t f_bavail; /* # free blocks for non-root */
libssh2_uint64_t f_files; /* # inodes */
libssh2_uint64_t f_ffree; /* # free inodes */
libssh2_uint64_t f_favail; /* # free inodes for non-root */
libssh2_uint64_t f_fsid; /* file system ID */
libssh2_uint64_t f_flag; /* mount flags */
libssh2_uint64_t f_namemax; /* maximum filename length */
};
/* SFTP filetypes */
#define LIBSSH2_SFTP_TYPE_REGULAR 1
#define LIBSSH2_SFTP_TYPE_DIRECTORY 2
@@ -269,6 +288,14 @@ LIBSSH2_API int libssh2_sftp_unlink_ex(LIBSSH2_SFTP *sftp,
#define libssh2_sftp_unlink(sftp, filename) \
libssh2_sftp_unlink_ex((sftp), (filename), strlen(filename))
LIBSSH2_API int libssh2_sftp_fstatvfs(LIBSSH2_SFTP_HANDLE *handle,
LIBSSH2_SFTP_STATVFS *st);
LIBSSH2_API int libssh2_sftp_statvfs(LIBSSH2_SFTP *sftp,
const char *path,
size_t path_len,
LIBSSH2_SFTP_STATVFS *st);
LIBSSH2_API int libssh2_sftp_mkdir_ex(LIBSSH2_SFTP *sftp,
const char *path,
unsigned int path_len, long mode);

View File

@@ -16,12 +16,12 @@ endif
# Edit the path below to point to the base of your Zlib sources.
ifndef ZLIB_PATH
ZLIB_PATH = ../../zlib-1.2.3
ZLIB_PATH = ../../zlib-1.2.5
endif
# Edit the path below to point to the base of your OpenSSL package.
ifndef OPENSSL_PATH
OPENSSL_PATH = ../../openssl-0.9.8k
OPENSSL_PATH = ../../openssl-0.9.8n
endif
# Edit the path below to point to your Distribution folder.
@@ -39,7 +39,7 @@ DEVLARC = $(DEVLDIR).zip
# Edit the vars below to change NLM target settings.
TARGET = libssh2
VERSION = $(LIBSSH2_VERSION)
COPYR = Copyright (c) 2004-2009 Sara Golemon <sarag@libssh2.org>
COPYR = Copyright (c) 2004-2010 The libssh2 project and its contributors.
WWWURL = http://www.libssh2.org/
DESCR = libssh2 $(LIBSSH2_VERSION_STR) ($(LIBARCH)) - $(WWWURL)
MTSAFE = YES

View File

@@ -16,12 +16,12 @@ endif
# Edit the path below to point to the base of your Zlib sources.
ifndef ZLIB_PATH
ZLIB_PATH = ../../../zlib-1.2.3
ZLIB_PATH = ../../../zlib-1.2.5
endif
# Edit the path below to point to the base of your OpenSSL package.
ifndef OPENSSL_PATH
OPENSSL_PATH = ../../../openssl-0.9.8k
OPENSSL_PATH = ../../../openssl-0.9.8n
endif
# Edit the var below to enable static linking of libssh2 and libz
@@ -31,7 +31,7 @@ LINK_STATIC = 1
SAMPLES = ../../example
TARGETS := $(filter-out x11.nlm,$(patsubst $(SAMPLES)/%.c,%.nlm,$(strip $(wildcard $(SAMPLES)/*.c))))
VERSION = $(LIBSSH2_VERSION)
COPYR = Copyright (c) 2004-2009, Sara Golemon <sarag@libssh2.org>
COPYR = Copyright (c) 2004-2010 The libssh2 project and its contributors.
WWWURL = http://www.libssh2.org/
DESCR = libssh2 $(notdir $(@:.def=)) $(LIBSSH2_VERSION_STR) ($(LIBARCH)) - $(WWWURL)
MTSAFE = YES

View File

@@ -6,7 +6,9 @@ OBJECTS = \
$(INTDIR)\channel.obj \
$(INTDIR)\comp.obj \
$(INTDIR)\crypt.obj \
$(INTDIR)\global.obj \
$(INTDIR)\hostkey.obj \
$(INTDIR)\keepalive.obj \
$(INTDIR)\kex.obj \
$(INTDIR)\mac.obj \
$(INTDIR)\misc.obj \

View File

@@ -47,6 +47,7 @@
support them. */
#undef PF_UNIX
#endif
#include "userauth.h"
/* Requests from client to agent for protocol 1 key operations */
#define SSH_AGENTC_REQUEST_RSA_IDENTITIES 1
@@ -167,7 +168,7 @@ agent_connect_unix(LIBSSH2_AGENT *agent)
static int
agent_transact_unix(LIBSSH2_AGENT *agent, agent_transaction_ctx_t transctx)
{
unsigned char buf[4], *s;
unsigned char buf[4];
int rc;
/* Send the length of the request */
@@ -203,8 +204,8 @@ agent_transact_unix(LIBSSH2_AGENT *agent, agent_transaction_ctx_t transctx)
return -1;
}
transctx->response_len = _libssh2_ntohu32(buf);
s = transctx->response = LIBSSH2_ALLOC(agent->session,
transctx->response_len);
transctx->response = LIBSSH2_ALLOC(agent->session,
transctx->response_len);
if (!transctx->response) {
return LIBSSH2_ERROR_ALLOC;
}
@@ -267,6 +268,7 @@ agent_transact_pageant(LIBSSH2_AGENT *agent, agent_transaction_ctx_t transctx)
char mapname[23];
HANDLE filemap;
unsigned char *p;
unsigned char *p2;
int id;
COPYDATASTRUCT cds;
@@ -283,9 +285,9 @@ agent_transact_pageant(LIBSSH2_AGENT *agent, agent_transaction_ctx_t transctx)
if (filemap == NULL || filemap == INVALID_HANDLE_VALUE) {
return -1;
}
p = MapViewOfFile(filemap, FILE_MAP_WRITE, 0, 0, 0);
_libssh2_htonu32(p, transctx->request_len);
memcpy(p + 4, transctx->request, transctx->request_len);
p2 = p = MapViewOfFile(filemap, FILE_MAP_WRITE, 0, 0, 0);
_libssh2_store_str(&p2, transctx->request, transctx->request_len);
cds.dwData = PAGEANT_COPYDATA_ID;
cds.cbData = 1 + strlen(mapname);
cds.lpData = mapname;
@@ -361,18 +363,14 @@ agent_sign(LIBSSH2_SESSION *session, unsigned char **sig, size_t *sig_len,
*s++ = SSH2_AGENTC_SIGN_REQUEST;
/* key blob */
_libssh2_htonu32(s, identity->external.blob_len);
s += 4;
memcpy(s, identity->external.blob, identity->external.blob_len);
s += identity->external.blob_len;
_libssh2_store_str(&s, (const char *)identity->external.blob,
identity->external.blob_len);
/* data */
_libssh2_htonu32(s, data_len);
s += 4;
memcpy(s, data, data_len);
s += data_len;
_libssh2_store_str(&s, (const char *)data, data_len);
/* flags */
_libssh2_htonu32(s, 0);
s += 4;
_libssh2_store_u32(&s, 0);
transctx->request_len = s - transctx->request;
transctx->state = agent_NB_state_request_created;
}
@@ -618,8 +616,8 @@ libssh2_agent_init(LIBSSH2_SESSION *session)
agent = LIBSSH2_ALLOC(session, sizeof *agent);
if (!agent) {
libssh2_error(session, LIBSSH2_ERROR_ALLOC,
"Unable to allocate space for agent connection");
_libssh2_error(session, LIBSSH2_ERROR_ALLOC,
"Unable to allocate space for agent connection");
return NULL;
}
memset(agent, 0, sizeof *agent);
@@ -720,11 +718,12 @@ libssh2_agent_userauth(LIBSSH2_AGENT *agent,
memset(&agent->transctx, 0, sizeof agent->transctx);
agent->identity = identity->node;
}
return libssh2_userauth_publickey(agent->session, username,
identity->blob,
identity->blob_len,
agent_sign,
&abstract);
return _libssh2_userauth_publickey(agent->session, username,
strlen(username),
identity->blob,
identity->blob_len,
agent_sign,
&abstract);
}
/*

File diff suppressed because it is too large Load Diff

View File

@@ -1,6 +1,6 @@
#ifndef __LIBSSH2_CHANNEL_H
#define __LIBSSH2_CHANNEL_H
/* Copyright (c) 2008-2009 by Daniel Stenberg
/* Copyright (c) 2008-2010 by Daniel Stenberg
*
* All rights reserved.
*
@@ -89,8 +89,9 @@ _libssh2_channel_write(LIBSSH2_CHANNEL *channel, int stream_id,
*/
LIBSSH2_CHANNEL *
_libssh2_channel_open(LIBSSH2_SESSION * session, const char *channel_type,
unsigned int channel_type_len,
unsigned int window_size, unsigned int packet_size,
uint32_t channel_type_len,
uint32_t window_size,
uint32_t packet_size,
const char *message, unsigned int message_len);
@@ -116,5 +117,26 @@ _libssh2_channel_process_startup(LIBSSH2_CHANNEL *channel,
*/
ssize_t _libssh2_channel_read(LIBSSH2_CHANNEL *channel, int stream_id,
char *buf, size_t buflen);
uint32_t _libssh2_channel_nextid(LIBSSH2_SESSION * session);
LIBSSH2_CHANNEL *_libssh2_channel_locate(LIBSSH2_SESSION * session,
uint32_t channel_id);
size_t _libssh2_channel_packet_data_len(LIBSSH2_CHANNEL * channel,
int stream_id);
int _libssh2_channel_close(LIBSSH2_CHANNEL * channel);
/*
* _libssh2_channel_forward_cancel
*
* Stop listening on a remote port and free the listener
* Toss out any pending (un-accept()ed) connections
*
* Return 0 on success, LIBSSH2_ERROR_EAGAIN if would block, -1 on error
*/
int _libssh2_channel_forward_cancel(LIBSSH2_LISTENER *listener);
#endif /* __LIBSSH2_CHANNEL_H */

View File

@@ -43,8 +43,8 @@
#include "comp.h"
/* ********
* none *
******** */
* none *
******** */
/*
* comp_method_none_comp
@@ -55,11 +55,11 @@ static int
comp_method_none_comp(LIBSSH2_SESSION * session,
int compress,
unsigned char **dest,
unsigned long *dest_len,
unsigned long payload_limit,
size_t *dest_len,
size_t payload_limit,
int *free_dest,
const unsigned char *src,
unsigned long src_len, void **abstract)
size_t src_len, void **abstract)
{
(void) session;
(void) compress;
@@ -84,8 +84,8 @@ static const LIBSSH2_COMP_METHOD comp_method_none = {
#ifdef LIBSSH2_HAVE_ZLIB
/* ********
* zlib *
******** */
* zlib *
******** */
/* Memory management wrappers
* Yes, I realize we're doing a callback to a callback,
@@ -122,9 +122,9 @@ comp_method_zlib_init(LIBSSH2_SESSION * session, int compress,
strm = LIBSSH2_ALLOC(session, sizeof(z_stream));
if (!strm) {
return libssh2_error(session, LIBSSH2_ERROR_ALLOC,
"Unable to allocate memory for "
"zlib compression/decompression");
return _libssh2_error(session, LIBSSH2_ERROR_ALLOC,
"Unable to allocate memory for "
"zlib compression/decompression");
}
memset(strm, 0, sizeof(z_stream));
@@ -157,11 +157,11 @@ static int
comp_method_zlib_comp(LIBSSH2_SESSION * session,
int compress,
unsigned char **dest,
unsigned long *dest_len,
unsigned long payload_limit,
size_t *dest_len,
size_t payload_limit,
int *free_dest,
const unsigned char *src,
unsigned long src_len, void **abstract)
size_t src_len, void **abstract)
{
z_stream *strm = *abstract;
/* A short-term alloc of a full data chunk is better than a series of
@@ -185,9 +185,9 @@ comp_method_zlib_comp(LIBSSH2_SESSION * session,
out = (char *) strm->next_out;
strm->avail_out = out_maxlen;
if (!strm->next_out) {
return libssh2_error(session, LIBSSH2_ERROR_ALLOC,
"Unable to allocate compression/decompression "
"buffer");
return _libssh2_error(session, LIBSSH2_ERROR_ALLOC,
"Unable to allocate compression/decompression "
"buffer");
}
while (strm->avail_in) {
int status;
@@ -199,11 +199,11 @@ comp_method_zlib_comp(LIBSSH2_SESSION * session,
}
if (status != Z_OK) {
LIBSSH2_FREE(session, out);
return libssh2_error(session, LIBSSH2_ERROR_ZLIB,
"compress/decompression failure");
return _libssh2_error(session, LIBSSH2_ERROR_ZLIB,
"compress/decompression failure");
}
if (strm->avail_in) {
unsigned long out_ofs = out_maxlen - strm->avail_out;
size_t out_ofs = out_maxlen - strm->avail_out;
char *newout;
out_maxlen +=
@@ -211,16 +211,16 @@ comp_method_zlib_comp(LIBSSH2_SESSION * session,
if ((out_maxlen > (int) payload_limit) && !compress && limiter++) {
LIBSSH2_FREE(session, out);
return libssh2_error(session, LIBSSH2_ERROR_ZLIB,
"Excessive growth in decompression phase");
return _libssh2_error(session, LIBSSH2_ERROR_ZLIB,
"Excessive growth in decompression phase");
}
newout = LIBSSH2_REALLOC(session, out, out_maxlen);
if (!newout) {
LIBSSH2_FREE(session, out);
return libssh2_error(session, LIBSSH2_ERROR_ALLOC,
"Unable to expand compress/"
"decompression buffer");
return _libssh2_error(session, LIBSSH2_ERROR_ALLOC,
"Unable to expand compress/"
"decompression buffer");
}
out = newout;
strm->next_out = (unsigned char *) out + out_ofs;
@@ -237,9 +237,9 @@ comp_method_zlib_comp(LIBSSH2_SESSION * session,
if (out_maxlen >= (int) payload_limit) {
LIBSSH2_FREE(session, out);
return libssh2_error(session, LIBSSH2_ERROR_ZLIB,
"Excessive growth in decompression "
"phase");
return _libssh2_error(session, LIBSSH2_ERROR_ZLIB,
"Excessive growth in decompression "
"phase");
}
if (grow_size > (int) (payload_limit - out_maxlen)) {
@@ -252,9 +252,9 @@ comp_method_zlib_comp(LIBSSH2_SESSION * session,
newout = LIBSSH2_REALLOC(session, out, out_maxlen);
if (!newout) {
LIBSSH2_FREE(session, out);
return libssh2_error(session, LIBSSH2_ERROR_ALLOC,
"Unable to expand final compress/"
"decompress buffer");
return _libssh2_error(session, LIBSSH2_ERROR_ALLOC,
"Unable to expand final compress/"
"decompress buffer");
}
out = newout;
strm->next_out = (unsigned char *) out + out_maxlen -
@@ -267,8 +267,8 @@ comp_method_zlib_comp(LIBSSH2_SESSION * session,
}
if (status != Z_OK) {
LIBSSH2_FREE(session, out);
return libssh2_error(session, LIBSSH2_ERROR_ZLIB,
"compress/decompression failure");
return _libssh2_error(session, LIBSSH2_ERROR_ZLIB,
"compress/decompression failure");
}
}
}
@@ -316,8 +316,8 @@ static const LIBSSH2_COMP_METHOD comp_method_zlib = {
#endif /* LIBSSH2_HAVE_ZLIB */
/* ***********************
* Compression Methods *
*********************** */
* Compression Methods *
*********************** */
static const LIBSSH2_COMP_METHOD *comp_methods[] = {
&comp_method_none,

View File

@@ -46,8 +46,8 @@
#if LIBSSH2_RSA
/* ***********
* ssh-rsa *
*********** */
* ssh-rsa *
*********** */
static int hostkey_method_ssh_rsa_dtor(LIBSSH2_SESSION * session,
void **abstract);
@@ -60,7 +60,7 @@ static int hostkey_method_ssh_rsa_dtor(LIBSSH2_SESSION * session,
static int
hostkey_method_ssh_rsa_init(LIBSSH2_SESSION * session,
const unsigned char *hostkey_data,
unsigned long hostkey_data_len,
size_t hostkey_data_len,
void **abstract)
{
libssh2_rsa_ctx *rsactx;
@@ -91,7 +91,6 @@ hostkey_method_ssh_rsa_init(LIBSSH2_SESSION * session,
n_len = _libssh2_ntohu32(s);
s += 4;
n = s;
s += n_len;
if (_libssh2_rsa_new(&rsactx, e, e_len, n, n_len, NULL, 0,
NULL, 0, NULL, 0, NULL, 0, NULL, 0, NULL, 0))
@@ -139,9 +138,9 @@ hostkey_method_ssh_rsa_initPEM(LIBSSH2_SESSION * session,
static int
hostkey_method_ssh_rsa_sig_verify(LIBSSH2_SESSION * session,
const unsigned char *sig,
unsigned long sig_len,
size_t sig_len,
const unsigned char *m,
unsigned long m_len, void **abstract)
size_t m_len, void **abstract)
{
libssh2_rsa_ctx *rsactx = (libssh2_rsa_ctx *) (*abstract);
(void) session;
@@ -160,14 +159,14 @@ hostkey_method_ssh_rsa_sig_verify(LIBSSH2_SESSION * session,
static int
hostkey_method_ssh_rsa_signv(LIBSSH2_SESSION * session,
unsigned char **signature,
unsigned long *signature_len,
unsigned long veccount,
size_t *signature_len,
int veccount,
const struct iovec datavec[],
void **abstract)
{
libssh2_rsa_ctx *rsactx = (libssh2_rsa_ctx *) (*abstract);
int ret;
unsigned int i;
int i;
unsigned char hash[SHA_DIGEST_LENGTH];
libssh2_sha1_ctx ctx;
@@ -218,8 +217,8 @@ static const LIBSSH2_HOSTKEY_METHOD hostkey_method_ssh_rsa = {
#if LIBSSH2_DSA
/* ***********
* ssh-dss *
*********** */
* ssh-dss *
*********** */
static int hostkey_method_ssh_dss_dtor(LIBSSH2_SESSION * session,
void **abstract);
@@ -232,7 +231,7 @@ static int hostkey_method_ssh_dss_dtor(LIBSSH2_SESSION * session,
static int
hostkey_method_ssh_dss_init(LIBSSH2_SESSION * session,
const unsigned char *hostkey_data,
unsigned long hostkey_data_len,
size_t hostkey_data_len,
void **abstract)
{
libssh2_dsa_ctx *dsactx;
@@ -268,7 +267,7 @@ hostkey_method_ssh_dss_init(LIBSSH2_SESSION * session,
y_len = _libssh2_ntohu32(s);
s += 4;
y = s;
s += y_len;
/* s += y_len; */
_libssh2_dsa_new(&dsactx, p, p_len, q, q_len, g, g_len, y, y_len, NULL, 0);
@@ -314,9 +313,9 @@ hostkey_method_ssh_dss_initPEM(LIBSSH2_SESSION * session,
static int
hostkey_method_ssh_dss_sig_verify(LIBSSH2_SESSION * session,
const unsigned char *sig,
unsigned long sig_len,
size_t sig_len,
const unsigned char *m,
unsigned long m_len, void **abstract)
size_t m_len, void **abstract)
{
libssh2_dsa_ctx *dsactx = (libssh2_dsa_ctx *) (*abstract);
@@ -324,8 +323,8 @@ hostkey_method_ssh_dss_sig_verify(LIBSSH2_SESSION * session,
sig += 15;
sig_len -= 15;
if (sig_len != 40) {
return libssh2_error(session, LIBSSH2_ERROR_PROTO,
"Invalid DSS signature length");
return _libssh2_error(session, LIBSSH2_ERROR_PROTO,
"Invalid DSS signature length");
}
return _libssh2_dsa_sha1_verify(dsactx, sig, m, m_len);
}
@@ -338,15 +337,15 @@ hostkey_method_ssh_dss_sig_verify(LIBSSH2_SESSION * session,
static int
hostkey_method_ssh_dss_signv(LIBSSH2_SESSION * session,
unsigned char **signature,
unsigned long *signature_len,
unsigned long veccount,
size_t *signature_len,
int veccount,
const struct iovec datavec[],
void **abstract)
{
libssh2_dsa_ctx *dsactx = (libssh2_dsa_ctx *) (*abstract);
unsigned char hash[SHA_DIGEST_LENGTH];
libssh2_sha1_ctx ctx;
unsigned int i;
int i;
*signature = LIBSSH2_ALLOC(session, 2 * SHA_DIGEST_LENGTH);
if (!*signature) {

View File

@@ -79,9 +79,9 @@ libssh2_keepalive_send (LIBSSH2_SESSION *session,
rc = _libssh2_transport_write(session, keepalive_data, len);
/* Silently ignore PACKET_EAGAIN here: if the write buffer is
already full, sending another keepalive is not useful. */
if (rc && rc != PACKET_EAGAIN) {
libssh2_error(session, LIBSSH2_ERROR_SOCKET_SEND,
"Unable to send keepalive message");
if (rc && rc != LIBSSH2_ERROR_EAGAIN) {
_libssh2_error(session, LIBSSH2_ERROR_SOCKET_SEND,
"Unable to send keepalive message");
return rc;
}
@@ -89,7 +89,7 @@ libssh2_keepalive_send (LIBSSH2_SESSION *session,
if (seconds_to_next)
*seconds_to_next = session->keepalive_interval;
} else if (seconds_to_next) {
*seconds_to_next = session->keepalive_last_sent
*seconds_to_next = (int) session->keepalive_last_sent
+ session->keepalive_interval - now;
}

214
src/kex.c
View File

@@ -44,30 +44,30 @@
/* TODO: Switch this to an inline and handle alloc() failures */
/* Helper macro called from kex_method_diffie_hellman_group1_sha1_key_exchange */
#define LIBSSH2_KEX_METHOD_DIFFIE_HELLMAN_SHA1_HASH(value, reqlen, version) \
{ \
libssh2_sha1_ctx hash; \
unsigned long len = 0; \
if (!(value)) { \
value = LIBSSH2_ALLOC(session, reqlen + SHA_DIGEST_LENGTH); \
} \
if (value) \
while (len < (unsigned long)reqlen) { \
libssh2_sha1_init(&hash); \
libssh2_sha1_update(hash, exchange_state->k_value, \
exchange_state->k_value_len); \
libssh2_sha1_update(hash, exchange_state->h_sig_comp, \
SHA_DIGEST_LENGTH); \
if (len > 0) { \
libssh2_sha1_update(hash, value, len); \
} else { \
libssh2_sha1_update(hash, (version), 1); \
libssh2_sha1_update(hash, session->session_id, \
session->session_id_len); \
} \
libssh2_sha1_final(hash, (value) + len); \
len += SHA_DIGEST_LENGTH; \
} \
}
{ \
libssh2_sha1_ctx hash; \
unsigned long len = 0; \
if (!(value)) { \
value = LIBSSH2_ALLOC(session, reqlen + SHA_DIGEST_LENGTH); \
} \
if (value) \
while (len < (unsigned long)reqlen) { \
libssh2_sha1_init(&hash); \
libssh2_sha1_update(hash, exchange_state->k_value, \
exchange_state->k_value_len); \
libssh2_sha1_update(hash, exchange_state->h_sig_comp, \
SHA_DIGEST_LENGTH); \
if (len > 0) { \
libssh2_sha1_update(hash, value, len); \
} else { \
libssh2_sha1_update(hash, (version), 1); \
libssh2_sha1_update(hash, session->session_id, \
session->session_id_len); \
} \
libssh2_sha1_final(hash, (value) + len); \
len += SHA_DIGEST_LENGTH; \
} \
}
/*
* diffie_hellman_sha1
@@ -118,13 +118,13 @@ static int diffie_hellman_sha1(LIBSSH2_SESSION *session,
exchange_state->e_packet =
LIBSSH2_ALLOC(session, exchange_state->e_packet_len);
if (!exchange_state->e_packet) {
ret = libssh2_error(session, LIBSSH2_ERROR_ALLOC,
"Out of memory error");
ret = _libssh2_error(session, LIBSSH2_ERROR_ALLOC,
"Out of memory error");
goto clean_exit;
}
exchange_state->e_packet[0] = packet_type_init;
_libssh2_htonu32(exchange_state->e_packet + 1,
exchange_state->e_packet_len - 5);
exchange_state->e_packet_len - 5);
if (_libssh2_bn_bits(exchange_state->e) % 8) {
_libssh2_bn_to_bin(exchange_state->e,
exchange_state->e_packet + 5);
@@ -142,11 +142,11 @@ static int diffie_hellman_sha1(LIBSSH2_SESSION *session,
if (exchange_state->state == libssh2_NB_state_created) {
rc = _libssh2_transport_write(session, exchange_state->e_packet,
exchange_state->e_packet_len);
if (rc == PACKET_EAGAIN) {
if (rc == LIBSSH2_ERROR_EAGAIN) {
return rc;
} else if (rc) {
ret = libssh2_error(session, rc,
"Unable to send KEX init message");
ret = _libssh2_error(session, rc,
"Unable to send KEX init message");
goto clean_exit;
}
exchange_state->state = libssh2_NB_state_sent;
@@ -163,7 +163,7 @@ static int diffie_hellman_sha1(LIBSSH2_SESSION *session,
"Waiting for badly guessed KEX packet (to be ignored)");
burn_type =
_libssh2_packet_burn(session, &exchange_state->burn_state);
if (burn_type == PACKET_EAGAIN) {
if (burn_type == LIBSSH2_ERROR_EAGAIN) {
return burn_type;
} else if (burn_type <= 0) {
/* Failed to receive a packet */
@@ -186,12 +186,12 @@ static int diffie_hellman_sha1(LIBSSH2_SESSION *session,
&exchange_state->s_packet,
&exchange_state->s_packet_len, 0, NULL,
0, &exchange_state->req_state);
if (rc == PACKET_EAGAIN) {
if (rc == LIBSSH2_ERROR_EAGAIN) {
return rc;
}
if (rc) {
ret = libssh2_error(session, LIBSSH2_ERROR_TIMEOUT,
"Timed out waiting for KEX reply");
ret = _libssh2_error(session, LIBSSH2_ERROR_TIMEOUT,
"Timed out waiting for KEX reply");
goto clean_exit;
}
@@ -203,9 +203,9 @@ static int diffie_hellman_sha1(LIBSSH2_SESSION *session,
session->server_hostkey =
LIBSSH2_ALLOC(session, session->server_hostkey_len);
if (!session->server_hostkey) {
ret = libssh2_error(session, LIBSSH2_ERROR_ALLOC,
"Unable to allocate memory for a copy "
"of the host key");
ret = _libssh2_error(session, LIBSSH2_ERROR_ALLOC,
"Unable to allocate memory for a copy "
"of the host key");
goto clean_exit;
}
memcpy(session->server_hostkey, exchange_state->s,
@@ -260,8 +260,8 @@ static int diffie_hellman_sha1(LIBSSH2_SESSION *session,
if (session->hostkey->init(session, session->server_hostkey,
session->server_hostkey_len,
&session->server_hostkey_abstract)) {
ret = libssh2_error(session, LIBSSH2_ERROR_HOSTKEY_INIT,
"Unable to initialize hostkey importer");
ret = _libssh2_error(session, LIBSSH2_ERROR_HOSTKEY_INIT,
"Unable to initialize hostkey importer");
goto clean_exit;
}
@@ -287,12 +287,12 @@ static int diffie_hellman_sha1(LIBSSH2_SESSION *session,
exchange_state->k_value =
LIBSSH2_ALLOC(session, exchange_state->k_value_len);
if (!exchange_state->k_value) {
ret = libssh2_error(session, LIBSSH2_ERROR_ALLOC,
"Unable to allocate buffer for K");
ret = _libssh2_error(session, LIBSSH2_ERROR_ALLOC,
"Unable to allocate buffer for K");
goto clean_exit;
}
_libssh2_htonu32(exchange_state->k_value,
exchange_state->k_value_len - 4);
exchange_state->k_value_len - 4);
if (_libssh2_bn_bits(exchange_state->k) % 8) {
_libssh2_bn_to_bin(exchange_state->k, exchange_state->k_value + 4);
} else {
@@ -303,7 +303,7 @@ static int diffie_hellman_sha1(LIBSSH2_SESSION *session,
libssh2_sha1_init(&exchange_state->exchange_hash);
if (session->local.banner) {
_libssh2_htonu32(exchange_state->h_sig_comp,
strlen((char *) session->local.banner) - 2);
strlen((char *) session->local.banner) - 2);
libssh2_sha1_update(exchange_state->exchange_hash,
exchange_state->h_sig_comp, 4);
libssh2_sha1_update(exchange_state->exchange_hash,
@@ -311,7 +311,7 @@ static int diffie_hellman_sha1(LIBSSH2_SESSION *session,
strlen((char *) session->local.banner) - 2);
} else {
_libssh2_htonu32(exchange_state->h_sig_comp,
sizeof(LIBSSH2_SSH_DEFAULT_BANNER) - 1);
sizeof(LIBSSH2_SSH_DEFAULT_BANNER) - 1);
libssh2_sha1_update(exchange_state->exchange_hash,
exchange_state->h_sig_comp, 4);
libssh2_sha1_update(exchange_state->exchange_hash,
@@ -320,7 +320,7 @@ static int diffie_hellman_sha1(LIBSSH2_SESSION *session,
}
_libssh2_htonu32(exchange_state->h_sig_comp,
strlen((char *) session->remote.banner));
strlen((char *) session->remote.banner));
libssh2_sha1_update(exchange_state->exchange_hash,
exchange_state->h_sig_comp, 4);
libssh2_sha1_update(exchange_state->exchange_hash,
@@ -328,7 +328,7 @@ static int diffie_hellman_sha1(LIBSSH2_SESSION *session,
strlen((char *) session->remote.banner));
_libssh2_htonu32(exchange_state->h_sig_comp,
session->local.kexinit_len);
session->local.kexinit_len);
libssh2_sha1_update(exchange_state->exchange_hash,
exchange_state->h_sig_comp, 4);
libssh2_sha1_update(exchange_state->exchange_hash,
@@ -336,7 +336,7 @@ static int diffie_hellman_sha1(LIBSSH2_SESSION *session,
session->local.kexinit_len);
_libssh2_htonu32(exchange_state->h_sig_comp,
session->remote.kexinit_len);
session->remote.kexinit_len);
libssh2_sha1_update(exchange_state->exchange_hash,
exchange_state->h_sig_comp, 4);
libssh2_sha1_update(exchange_state->exchange_hash,
@@ -344,7 +344,7 @@ static int diffie_hellman_sha1(LIBSSH2_SESSION *session,
session->remote.kexinit_len);
_libssh2_htonu32(exchange_state->h_sig_comp,
session->server_hostkey_len);
session->server_hostkey_len);
libssh2_sha1_update(exchange_state->exchange_hash,
exchange_state->h_sig_comp, 4);
libssh2_sha1_update(exchange_state->exchange_hash,
@@ -355,16 +355,16 @@ static int diffie_hellman_sha1(LIBSSH2_SESSION *session,
/* diffie-hellman-group-exchange hashes additional fields */
#ifdef LIBSSH2_DH_GEX_NEW
_libssh2_htonu32(exchange_state->h_sig_comp,
LIBSSH2_DH_GEX_MINGROUP);
LIBSSH2_DH_GEX_MINGROUP);
_libssh2_htonu32(exchange_state->h_sig_comp + 4,
LIBSSH2_DH_GEX_OPTGROUP);
LIBSSH2_DH_GEX_OPTGROUP);
_libssh2_htonu32(exchange_state->h_sig_comp + 8,
LIBSSH2_DH_GEX_MAXGROUP);
LIBSSH2_DH_GEX_MAXGROUP);
libssh2_sha1_update(exchange_state->exchange_hash,
exchange_state->h_sig_comp, 12);
#else
_libssh2_htonu32(exchange_state->h_sig_comp,
LIBSSH2_DH_GEX_OPTGROUP);
LIBSSH2_DH_GEX_OPTGROUP);
libssh2_sha1_update(exchange_state->exchange_hash,
exchange_state->h_sig_comp, 4);
#endif
@@ -380,7 +380,7 @@ static int diffie_hellman_sha1(LIBSSH2_SESSION *session,
exchange_state->e_packet_len - 1);
_libssh2_htonu32(exchange_state->h_sig_comp,
exchange_state->f_value_len);
exchange_state->f_value_len);
libssh2_sha1_update(exchange_state->exchange_hash,
exchange_state->h_sig_comp, 4);
libssh2_sha1_update(exchange_state->exchange_hash,
@@ -398,8 +398,8 @@ static int diffie_hellman_sha1(LIBSSH2_SESSION *session,
sig_verify(session, exchange_state->h_sig,
exchange_state->h_sig_len, exchange_state->h_sig_comp,
20, &session->server_hostkey_abstract)) {
ret = libssh2_error(session, LIBSSH2_ERROR_HOSTKEY_SIGN,
"Unable to verify hostkey signature");
ret = _libssh2_error(session, LIBSSH2_ERROR_HOSTKEY_SIGN,
"Unable to verify hostkey signature");
goto clean_exit;
}
@@ -411,10 +411,10 @@ static int diffie_hellman_sha1(LIBSSH2_SESSION *session,
if (exchange_state->state == libssh2_NB_state_sent2) {
rc = _libssh2_transport_write(session, &exchange_state->c, 1);
if (rc == PACKET_EAGAIN) {
if (rc == LIBSSH2_ERROR_EAGAIN) {
return rc;
} else if (rc) {
ret = libssh2_error(session, rc, "Unable to send NEWKEYS message");
ret = _libssh2_error(session, rc, "Unable to send NEWKEYS message");
goto clean_exit;
}
@@ -426,10 +426,10 @@ static int diffie_hellman_sha1(LIBSSH2_SESSION *session,
&exchange_state->tmp,
&exchange_state->tmp_len, 0, NULL, 0,
&exchange_state->req_state);
if (rc == PACKET_EAGAIN) {
if (rc == LIBSSH2_ERROR_EAGAIN) {
return rc;
} else if (rc) {
ret = libssh2_error(session, rc, "Timed out waiting for NEWKEYS");
ret = _libssh2_error(session, rc, "Timed out waiting for NEWKEYS");
goto clean_exit;
}
/* The first key exchange has been performed,
@@ -444,8 +444,8 @@ static int diffie_hellman_sha1(LIBSSH2_SESSION *session,
if (!session->session_id) {
session->session_id = LIBSSH2_ALLOC(session, SHA_DIGEST_LENGTH);
if (!session->session_id) {
ret = libssh2_error(session, LIBSSH2_ERROR_ALLOC,
"Unable to allocate buffer for SHA digest");
ret = _libssh2_error(session, LIBSSH2_ERROR_ALLOC,
"Unable to allocate buffer for SHA digest");
goto clean_exit;
}
memcpy(session->session_id, exchange_state->h_sig_comp,
@@ -682,7 +682,7 @@ kex_method_diffie_hellman_group1_sha1_key_exchange(LIBSSH2_SESSION *session,
ret = diffie_hellman_sha1(session, key_state->g, key_state->p, 128,
SSH_MSG_KEXDH_INIT, SSH_MSG_KEXDH_REPLY,
NULL, 0, &key_state->exchange_state);
if (ret == PACKET_EAGAIN) {
if (ret == LIBSSH2_ERROR_EAGAIN) {
return ret;
}
@@ -758,7 +758,7 @@ kex_method_diffie_hellman_group14_sha1_key_exchange(LIBSSH2_SESSION *session,
ret = diffie_hellman_sha1(session, key_state->g, key_state->p,
256, SSH_MSG_KEXDH_INIT, SSH_MSG_KEXDH_REPLY,
NULL, 0, &key_state->exchange_state);
if (ret == PACKET_EAGAIN) {
if (ret == LIBSSH2_ERROR_EAGAIN) {
return ret;
}
@@ -781,7 +781,6 @@ static int
kex_method_diffie_hellman_group_exchange_sha1_key_exchange
(LIBSSH2_SESSION * session, key_exchange_state_low_t * key_state)
{
unsigned char *s;
unsigned long p_len, g_len;
int ret = 0;
int rc;
@@ -811,12 +810,12 @@ kex_method_diffie_hellman_group_exchange_sha1_key_exchange
if (key_state->state == libssh2_NB_state_created) {
rc = _libssh2_transport_write(session, key_state->request,
key_state->request_len);
if (rc == PACKET_EAGAIN) {
key_state->request_len);
if (rc == LIBSSH2_ERROR_EAGAIN) {
return rc;
} else if (rc) {
ret = libssh2_error(session, rc,
"Unable to send Group Exchange Request");
ret = _libssh2_error(session, rc,
"Unable to send Group Exchange Request");
goto dh_gex_clean_exit;
}
@@ -827,11 +826,11 @@ kex_method_diffie_hellman_group_exchange_sha1_key_exchange
rc = _libssh2_packet_require(session, SSH_MSG_KEX_DH_GEX_GROUP,
&key_state->data, &key_state->data_len,
0, NULL, 0, &key_state->req_state);
if (rc == PACKET_EAGAIN) {
if (rc == LIBSSH2_ERROR_EAGAIN) {
return rc;
} else if (rc) {
ret = libssh2_error(session, rc,
"Timeout waiting for GEX_GROUP reply");
ret = _libssh2_error(session, rc,
"Timeout waiting for GEX_GROUP reply");
goto dh_gex_clean_exit;
}
@@ -839,7 +838,7 @@ kex_method_diffie_hellman_group_exchange_sha1_key_exchange
}
if (key_state->state == libssh2_NB_state_sent1) {
s = key_state->data + 1;
unsigned char *s = key_state->data + 1;
p_len = _libssh2_ntohu32(s);
s += 4;
_libssh2_bn_from_bin(key_state->p, p_len, s);
@@ -848,7 +847,6 @@ kex_method_diffie_hellman_group_exchange_sha1_key_exchange
g_len = _libssh2_ntohu32(s);
s += 4;
_libssh2_bn_from_bin(key_state->g, g_len, s);
s += g_len;
ret = diffie_hellman_sha1(session, key_state->g, key_state->p, p_len,
SSH_MSG_KEX_DH_GEX_INIT,
@@ -856,7 +854,7 @@ kex_method_diffie_hellman_group_exchange_sha1_key_exchange
key_state->data + 1,
key_state->data_len - 1,
&key_state->exchange_state);
if (ret == PACKET_EAGAIN) {
if (ret == LIBSSH2_ERROR_EAGAIN) {
return ret;
}
@@ -891,7 +889,7 @@ static const LIBSSH2_KEX_METHOD kex_method_diffie_helman_group14_sha1 = {
};
static const LIBSSH2_KEX_METHOD
kex_method_diffie_helman_group_exchange_sha1 = {
kex_method_diffie_helman_group_exchange_sha1 = {
"diffie-hellman-group-exchange-sha1",
kex_method_diffie_hellman_group_exchange_sha1_key_exchange,
LIBSSH2_KEX_METHOD_FLAG_REQ_SIGN_HOSTKEY,
@@ -960,13 +958,13 @@ kex_method_list(unsigned char *buf, size_t list_strlen,
#define LIBSSH2_METHOD_PREFS_LEN(prefvar, defaultvar) \
((prefvar) ? strlen(prefvar) : \
#define LIBSSH2_METHOD_PREFS_LEN(prefvar, defaultvar) \
((prefvar) ? strlen(prefvar) : \
kex_method_strlen((LIBSSH2_COMMON_METHOD**)(defaultvar)))
#define LIBSSH2_METHOD_PREFS_STR(buf, prefvarlen, prefvar, defaultvar) \
if (prefvar) { \
_libssh2_htonu32((buf), (prefvarlen)); \
_libssh2_htonu32((buf), (prefvarlen)); \
buf += 4; \
memcpy((buf), (prefvar), (prefvarlen)); \
buf += (prefvarlen); \
@@ -1026,13 +1024,13 @@ static int kexinit(LIBSSH2_SESSION * session)
s = data = LIBSSH2_ALLOC(session, data_len);
if (!data) {
return libssh2_error(session, LIBSSH2_ERROR_ALLOC,
"Unable to allocate memory");
return _libssh2_error(session, LIBSSH2_ERROR_ALLOC,
"Unable to allocate memory");
}
*(s++) = SSH_MSG_KEXINIT;
libssh2_random(s, 16);
_libssh2_random(s, 16);
s += 16;
/* Ennumerating through these lists twice is probably (certainly?)
@@ -1067,10 +1065,7 @@ static int kexinit(LIBSSH2_SESSION * session)
*(s++) = 0;
/* Reserved == 0 */
*(s++) = 0;
*(s++) = 0;
*(s++) = 0;
*(s++) = 0;
_libssh2_htonu32(s, 0);
#ifdef LIBSSH2DEBUG
{
@@ -1107,7 +1102,7 @@ static int kexinit(LIBSSH2_SESSION * session)
}
rc = _libssh2_transport_write(session, data, data_len);
if (rc == PACKET_EAGAIN) {
if (rc == LIBSSH2_ERROR_EAGAIN) {
session->kexinit_data = data;
session->kexinit_data_len = data_len;
return rc;
@@ -1115,8 +1110,8 @@ static int kexinit(LIBSSH2_SESSION * session)
else if (rc) {
LIBSSH2_FREE(session, data);
session->kexinit_state = libssh2_NB_state_idle;
return libssh2_error(session, rc,
"Unable to send KEXINIT packet to remote host");
return _libssh2_error(session, rc,
"Unable to send KEXINIT packet to remote host");
}
@@ -1176,7 +1171,7 @@ kex_agree_instr(unsigned char *haystack, unsigned long haystack_len,
*/
static const LIBSSH2_COMMON_METHOD *
kex_get_method_by_name(const char *name, size_t name_len,
const LIBSSH2_COMMON_METHOD ** methodlist)
const LIBSSH2_COMMON_METHOD ** methodlist)
{
while (*methodlist) {
if ((strlen((*methodlist)->name) == name_len) &&
@@ -1517,9 +1512,9 @@ static int kex_agree_methods(LIBSSH2_SESSION * session, unsigned char *data,
unsigned data_len)
{
unsigned char *kex, *hostkey, *crypt_cs, *crypt_sc, *comp_cs, *comp_sc,
*mac_cs, *mac_sc, *lang_cs, *lang_sc;
*mac_cs, *mac_sc;
size_t kex_len, hostkey_len, crypt_cs_len, crypt_sc_len, comp_cs_len;
size_t comp_sc_len, mac_cs_len, mac_sc_len, lang_cs_len, lang_sc_len;
size_t comp_sc_len, mac_cs_len, mac_sc_len;
unsigned char *s = data;
/* Skip packet_type, we know it already */
@@ -1552,6 +1547,7 @@ static int kex_agree_methods(LIBSSH2_SESSION * session, unsigned char *data,
s += 4 + comp_cs_len;
comp_sc_len = _libssh2_ntohu32(s);
comp_sc = s + 4;
#if 0
s += 4 + comp_sc_len;
lang_cs_len = _libssh2_ntohu32(s);
lang_cs = s + 4;
@@ -1559,7 +1555,7 @@ static int kex_agree_methods(LIBSSH2_SESSION * session, unsigned char *data,
lang_sc_len = _libssh2_ntohu32(s);
lang_sc = s + 4;
s += 4 + lang_sc_len;
#endif
/* If the server sent an optimistic packet, assume that it guessed wrong.
* If the guess is determined to be right (by kex_agree_kex_hostkey)
* This flag will be reset to zero so that it's not ignored */
@@ -1588,11 +1584,13 @@ static int kex_agree_methods(LIBSSH2_SESSION * session, unsigned char *data,
return -1;
}
#if 0
if (libssh2_kex_agree_lang(session, &session->local, lang_cs, lang_cs_len)
|| libssh2_kex_agree_lang(session, &session->remote, lang_sc,
lang_sc_len)) {
return -1;
}
#endif
_libssh2_debug(session, LIBSSH2_TRACE_KEX, "Agreed on KEX method: %s",
session->kex->name);
@@ -1610,8 +1608,6 @@ static int kex_agree_methods(LIBSSH2_SESSION * session, unsigned char *data,
session->local.comp->name);
_libssh2_debug(session, LIBSSH2_TRACE_KEX, "Agreed on COMP_SC method: %s",
session->remote.comp->name);
_libssh2_debug(session, LIBSSH2_TRACE_KEX, "Agreed on LANG_CS method:"); /* None yet */
_libssh2_debug(session, LIBSSH2_TRACE_KEX, "Agreed on LANG_SC method:"); /* None yet */
/* Initialize compression layer */
if (session->local.comp && session->local.comp->init &&
@@ -1630,14 +1626,14 @@ static int kex_agree_methods(LIBSSH2_SESSION * session, unsigned char *data,
/* libssh2_kex_exchange
/* _libssh2_kex_exchange
* Exchange keys
* Returns 0 on success, non-zero on failure
*
* Returns some errors without libssh2_error()
* Returns some errors without _libssh2_error()
*/
int
libssh2_kex_exchange(LIBSSH2_SESSION * session, int reexchange,
_libssh2_kex_exchange(LIBSSH2_SESSION * session, int reexchange,
key_exchange_state_t * key_state)
{
int rc = 0;
@@ -1675,7 +1671,7 @@ libssh2_kex_exchange(LIBSSH2_SESSION * session, int reexchange,
if (key_state->state == libssh2_NB_state_sent) {
retcode = kexinit(session);
if (retcode == PACKET_EAGAIN) {
if (retcode == LIBSSH2_ERROR_EAGAIN) {
session->state &= ~LIBSSH2_STATE_KEX_ACTIVE;
return retcode;
} else if (retcode) {
@@ -1696,7 +1692,7 @@ libssh2_kex_exchange(LIBSSH2_SESSION * session, int reexchange,
&key_state->data,
&key_state->data_len, 0, NULL, 0,
&key_state->req_state);
if (retcode == PACKET_EAGAIN) {
if (retcode == LIBSSH2_ERROR_EAGAIN) {
session->state &= ~LIBSSH2_STATE_KEX_ACTIVE;
return retcode;
}
@@ -1732,12 +1728,12 @@ libssh2_kex_exchange(LIBSSH2_SESSION * session, int reexchange,
if (key_state->state == libssh2_NB_state_sent2) {
retcode = session->kex->exchange_keys(session,
&key_state->key_state_low);
if (retcode == PACKET_EAGAIN) {
if (retcode == LIBSSH2_ERROR_EAGAIN) {
session->state &= ~LIBSSH2_STATE_KEX_ACTIVE;
return retcode;
} else if (retcode) {
rc = libssh2_error(session, LIBSSH2_ERROR_KEY_EXCHANGE_FAILURE,
"Unrecoverable error exchanging keys");
rc = _libssh2_error(session, LIBSSH2_ERROR_KEY_EXCHANGE_FAILURE,
"Unrecoverable error exchanging keys");
}
}
}
@@ -1825,14 +1821,14 @@ libssh2_session_method_pref(LIBSSH2_SESSION * session, int method_type,
break;
default:
return libssh2_error(session, LIBSSH2_ERROR_INVAL,
"Invalid parameter specified for method_type");
return _libssh2_error(session, LIBSSH2_ERROR_INVAL,
"Invalid parameter specified for method_type");
}
s = newprefs = LIBSSH2_ALLOC(session, prefs_len + 1);
if (!newprefs) {
return libssh2_error(session, LIBSSH2_ERROR_ALLOC,
"Error allocated space for method preferences");
return _libssh2_error(session, LIBSSH2_ERROR_ALLOC,
"Error allocated space for method preferences");
}
memcpy(s, prefs, prefs_len + 1);
@@ -1858,9 +1854,9 @@ libssh2_session_method_pref(LIBSSH2_SESSION * session, int method_type,
if (strlen(newprefs) == 0) {
LIBSSH2_FREE(session, newprefs);
return libssh2_error(session, LIBSSH2_ERROR_METHOD_NOT_SUPPORTED,
"The requested method(s) are not currently "
"supported");
return _libssh2_error(session, LIBSSH2_ERROR_METHOD_NOT_SUPPORTED,
"The requested method(s) are not currently "
"supported");
}
if (*prefvar) {

View File

@@ -1,5 +1,5 @@
/*
* Copyright (c) 2009 by Daniel Stenberg
* Copyright (c) 2009, 2010 by Daniel Stenberg
* All rights reserved.
*
* Redistribution and use in source and binary forms,
@@ -43,6 +43,8 @@ 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 port; /* if non-zero, a specific port this key is for on this
host */
int typemask; /* plain, sha1, custom, ... */
char *salt; /* points to binary salt (allocated) */
size_t salt_len; /* size of salt */
@@ -88,9 +90,9 @@ libssh2_knownhost_init(LIBSSH2_SESSION *session)
LIBSSH2_ALLOC(session, sizeof(struct _LIBSSH2_KNOWNHOSTS));
if(!knh) {
libssh2_error(session, LIBSSH2_ERROR_ALLOC,
"Unable to allocate memory for known-hosts "
"collection");
_libssh2_error(session, LIBSSH2_ERROR_ALLOC,
"Unable to allocate memory for known-hosts "
"collection");
return NULL;
}
@@ -137,14 +139,14 @@ knownhost_add(LIBSSH2_KNOWNHOSTS *hosts,
unsigned int ptrlen;
if(!entry)
return libssh2_error(hosts->session, LIBSSH2_ERROR_ALLOC,
"Unable to allocate memory for known host "
"entry");
return _libssh2_error(hosts->session, LIBSSH2_ERROR_ALLOC,
"Unable to allocate memory for known host "
"entry");
/* make sure we have a key type set */
if(!(typemask & LIBSSH2_KNOWNHOST_KEY_MASK)) {
rc = libssh2_error(hosts->session, LIBSSH2_ERROR_INVAL,
"No key type set");
rc = _libssh2_error(hosts->session, LIBSSH2_ERROR_INVAL,
"No key type set");
goto error;
}
@@ -157,8 +159,8 @@ knownhost_add(LIBSSH2_KNOWNHOSTS *hosts,
case LIBSSH2_KNOWNHOST_TYPE_CUSTOM:
entry->name = LIBSSH2_ALLOC(hosts->session, hostlen+1);
if(!entry->name) {
rc = libssh2_error(hosts->session, LIBSSH2_ERROR_ALLOC,
"Unable to allocate memory for host name");
rc = _libssh2_error(hosts->session, LIBSSH2_ERROR_ALLOC,
"Unable to allocate memory for host name");
goto error;
}
memcpy(entry->name, host, hostlen+1);
@@ -179,8 +181,8 @@ knownhost_add(LIBSSH2_KNOWNHOSTS *hosts,
entry->salt_len = ptrlen;
break;
default:
rc = libssh2_error(hosts->session, LIBSSH2_ERROR_METHOD_NOT_SUPPORTED,
"Unknown host name type");
rc = _libssh2_error(hosts->session, LIBSSH2_ERROR_METHOD_NOT_SUPPORTED,
"Unknown host name type");
goto error;
}
@@ -190,8 +192,8 @@ knownhost_add(LIBSSH2_KNOWNHOSTS *hosts,
keylen = strlen(key);
entry->key = LIBSSH2_ALLOC(hosts->session, keylen+1);
if(!entry->key) {
rc = libssh2_error(hosts->session, LIBSSH2_ERROR_ALLOC,
"Unable to allocate memory for key");
rc = _libssh2_error(hosts->session, LIBSSH2_ERROR_ALLOC,
"Unable to allocate memory for key");
goto error;
}
memcpy(entry->key, key, keylen+1);
@@ -202,9 +204,9 @@ knownhost_add(LIBSSH2_KNOWNHOSTS *hosts,
size_t nlen = _libssh2_base64_encode(hosts->session, key, keylen,
&ptr);
if(!nlen) {
rc = libssh2_error(hosts->session, LIBSSH2_ERROR_ALLOC,
"Unable to allocate memory for "
"base64-encoded key");
rc = _libssh2_error(hosts->session, LIBSSH2_ERROR_ALLOC,
"Unable to allocate memory for "
"base64-encoded key");
goto error;
}
@@ -214,8 +216,8 @@ knownhost_add(LIBSSH2_KNOWNHOSTS *hosts,
if (comment) {
entry->comment = LIBSSH2_ALLOC(hosts->session, commentlen+1);
if(!entry->comment) {
rc = libssh2_error(hosts->session, LIBSSH2_ERROR_ALLOC,
"Unable to allocate memory for comment");
rc = _libssh2_error(hosts->session, LIBSSH2_ERROR_ALLOC,
"Unable to allocate memory for comment");
goto error;
}
memcpy(entry->comment, comment, commentlen+1);
@@ -308,6 +310,147 @@ libssh2_knownhost_addc(LIBSSH2_KNOWNHOSTS *hosts,
typemask, store);
}
/*
* 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
*/
static int
knownhost_check(LIBSSH2_KNOWNHOSTS *hosts,
const char *hostp, int port,
const char *key, size_t keylen,
int typemask,
struct libssh2_knownhost **ext)
{
struct known_host *node;
struct known_host *badkey = NULL;
int type = typemask & LIBSSH2_KNOWNHOST_TYPE_MASK;
char *keyalloc = NULL;
int rc = LIBSSH2_KNOWNHOST_CHECK_NOTFOUND;
char hostbuff[270]; /* most host names can't be longer than like 256 */
const char *host;
int numcheck; /* number of host combos to check */
int match = 0;
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) {
_libssh2_error(hosts->session, LIBSSH2_ERROR_ALLOC,
"Unable to allocate memory for base64-encoded "
"key");
return LIBSSH2_KNOWNHOST_CHECK_FAILURE;
}
/* make the key point to this */
key = keyalloc;
}
/* if a port number is given, check for a '[host]:port' first before the
plain 'host' */
if(port >= 0) {
snprintf(hostbuff, sizeof(hostbuff), "[%s]:%d", hostp, port);
host = hostbuff;
numcheck = 2; /* check both combos, start with this */
}
else {
host = hostp;
numcheck = 1; /* only check this host version */
}
do {
node = _libssh2_list_first(&hosts->head);
while (node) {
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;
match = 0; /* don't count this as a match anymore */
}
}
node= _libssh2_list_next(&node->node);
}
host = hostp;
} while(!match && --numcheck);
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_check
*
@@ -328,104 +471,49 @@ libssh2_knownhost_addc(LIBSSH2_KNOWNHOSTS *hosts,
*/
LIBSSH2_API int
libssh2_knownhost_check(LIBSSH2_KNOWNHOSTS *hosts,
const char *host, const char *key, size_t keylen,
const char *hostp, 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) {
libssh2_error(hosts->session, LIBSSH2_ERROR_ALLOC,
"Unable to allocate memory for base64-encoded "
"key");
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;
return knownhost_check(hosts, hostp, -1, key, keylen,
typemask, ext);
}
/*
* libssh2_knownhost_checkp
*
* Check a host+port and its associated key against the collection of known
* hosts.
*
* Note that if 'port' is specified as greater than zero, the check function
* will be able to check for a dedicated key for this particular host+port
* combo, and if 'port' is negative it only checks for the generic host key.
*
* 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_checkp(LIBSSH2_KNOWNHOSTS *hosts,
const char *hostp, int port,
const char *key, size_t keylen,
int typemask,
struct libssh2_knownhost **ext)
{
return knownhost_check(hosts, hostp, port, key, keylen,
typemask, ext);
}
/*
* libssh2_knownhost_del
*
@@ -440,8 +528,8 @@ libssh2_knownhost_del(LIBSSH2_KNOWNHOSTS *hosts,
/* check that this was retrieved the right way or get out */
if(!entry || (entry->magic != KNOWNHOST_MAGIC))
return libssh2_error(hosts->session, LIBSSH2_ERROR_INVAL,
"Invalid host information");
return _libssh2_error(hosts->session, LIBSSH2_ERROR_INVAL,
"Invalid host information");
/* get the internal node pointer */
node = entry->node;
@@ -510,7 +598,7 @@ static int hostline(LIBSSH2_KNOWNHOSTS *hosts,
for the sake of simplicity, we add them as two hosts with the same
key
*/
*/
size_t scan = hostlen;
while(scan && (*host != ',')) {
@@ -542,10 +630,10 @@ static int hostline(LIBSSH2_KNOWNHOSTS *hosts,
const char *hash = NULL;
size_t saltlen = p - salt;
if(saltlen >= (sizeof(saltbuf)-1)) /* weird length */
return libssh2_error(hosts->session,
LIBSSH2_ERROR_METHOD_NOT_SUPPORTED,
"Failed to parse known_hosts line "
"(unexpectedly long salt)");
return _libssh2_error(hosts->session,
LIBSSH2_ERROR_METHOD_NOT_SUPPORTED,
"Failed to parse known_hosts line "
"(unexpectedly long salt)");
memcpy(saltbuf, salt, saltlen);
saltbuf[saltlen] = 0; /* zero terminate */
@@ -565,10 +653,10 @@ static int hostline(LIBSSH2_KNOWNHOSTS *hosts,
if((keylen < 20) ||
(seplen >= sizeof(hostbuf)-1) ||
(hostlen >= sizeof(hostbuf)-1))
return libssh2_error(hosts->session,
LIBSSH2_ERROR_METHOD_NOT_SUPPORTED,
"Failed to parse known_hosts line "
"(unexpected length)");
return _libssh2_error(hosts->session,
LIBSSH2_ERROR_METHOD_NOT_SUPPORTED,
"Failed to parse known_hosts line "
"(unexpected length)");
switch(key[0]) {
case '0': case '1': case '2': case '3': case '4':
@@ -589,9 +677,9 @@ static int hostline(LIBSSH2_KNOWNHOSTS *hosts,
type |= LIBSSH2_KNOWNHOST_KEY_SSHRSA;
else
/* unknown key type */
return libssh2_error(hosts->session,
LIBSSH2_ERROR_METHOD_NOT_SUPPORTED,
"Unknown key type");
return _libssh2_error(hosts->session,
LIBSSH2_ERROR_METHOD_NOT_SUPPORTED,
"Unknown key type");
key += 7;
keylen -= 7;
@@ -628,9 +716,9 @@ static int hostline(LIBSSH2_KNOWNHOSTS *hosts,
break;
default: /* unknown key format */
return libssh2_error(hosts->session,
LIBSSH2_ERROR_METHOD_NOT_SUPPORTED,
"Unknown key format");
return _libssh2_error(hosts->session,
LIBSSH2_ERROR_METHOD_NOT_SUPPORTED,
"Unknown key format");
}
if(sep) {
@@ -639,10 +727,10 @@ static int hostline(LIBSSH2_KNOWNHOSTS *hosts,
memcpy(hostbuf, sep, seplen);
hostbuf[seplen]=0;
rc = libssh2_knownhost_addc(hosts, hostbuf, salt, key, keylen,
comment, commentlen,
type | LIBSSH2_KNOWNHOST_KEYENC_BASE64,
NULL);
rc = knownhost_add(hosts, hostbuf, salt, key, keylen,
comment, commentlen,
type | LIBSSH2_KNOWNHOST_KEYENC_BASE64,
NULL);
if(rc)
return rc;
}
@@ -652,10 +740,10 @@ static int hostline(LIBSSH2_KNOWNHOSTS *hosts,
memcpy(hostbuf, host, hostlen);
hostbuf[hostlen]=0;
rc = libssh2_knownhost_addc(hosts, hostbuf, salt, key, keylen, comment,
commentlen,
type | LIBSSH2_KNOWNHOST_KEYENC_BASE64,
NULL);
rc = knownhost_add(hosts, hostbuf, salt, key, keylen, comment,
commentlen,
type | LIBSSH2_KNOWNHOST_KEYENC_BASE64,
NULL);
return rc;
}
@@ -699,10 +787,10 @@ libssh2_knownhost_readline(LIBSSH2_KNOWNHOSTS *hosts,
int rc;
if(type != LIBSSH2_KNOWNHOST_FILE_OPENSSH)
return libssh2_error(hosts->session,
LIBSSH2_ERROR_METHOD_NOT_SUPPORTED,
"Unsupported type of known-host information "
"store");
return _libssh2_error(hosts->session,
LIBSSH2_ERROR_METHOD_NOT_SUPPORTED,
"Unsupported type of known-host information "
"store");
cp = line;
@@ -734,9 +822,9 @@ libssh2_knownhost_readline(LIBSSH2_KNOWNHOSTS *hosts,
}
if(!*cp || !len) /* illegal line */
return libssh2_error(hosts->session,
LIBSSH2_ERROR_METHOD_NOT_SUPPORTED,
"Failed to parse known_hosts line");
return _libssh2_error(hosts->session,
LIBSSH2_ERROR_METHOD_NOT_SUPPORTED,
"Failed to parse known_hosts line");
keyp = cp; /* the key starts here */
keylen = len;
@@ -777,10 +865,10 @@ libssh2_knownhost_readfile(LIBSSH2_KNOWNHOSTS *hosts,
char buf[2048];
if(type != LIBSSH2_KNOWNHOST_FILE_OPENSSH)
return libssh2_error(hosts->session,
LIBSSH2_ERROR_METHOD_NOT_SUPPORTED,
"Unsupported type of known-host information "
"store");
return _libssh2_error(hosts->session,
LIBSSH2_ERROR_METHOD_NOT_SUPPORTED,
"Unsupported type of known-host information "
"store");
file = fopen(filename, "r");
if(file) {
@@ -792,8 +880,8 @@ libssh2_knownhost_readfile(LIBSSH2_KNOWNHOSTS *hosts,
fclose(file);
}
else
return libssh2_error(hosts->session, LIBSSH2_ERROR_FILE,
"Failed to open file");
return _libssh2_error(hosts->session, LIBSSH2_ERROR_FILE,
"Failed to open file");
return num;
}
@@ -830,10 +918,10 @@ knownhost_writeline(LIBSSH2_KNOWNHOSTS *hosts,
/* we only support this single file type for now, bail out on all other
attempts */
if(type != LIBSSH2_KNOWNHOST_FILE_OPENSSH)
return libssh2_error(hosts->session,
LIBSSH2_ERROR_METHOD_NOT_SUPPORTED,
"Unsupported type of known-host information "
"store");
return _libssh2_error(hosts->session,
LIBSSH2_ERROR_METHOD_NOT_SUPPORTED,
"Unsupported type of known-host information "
"store");
tindex = (node->typemask & LIBSSH2_KNOWNHOST_KEY_MASK) >>
LIBSSH2_KNOWNHOST_KEY_SHIFT;
@@ -852,18 +940,18 @@ knownhost_writeline(LIBSSH2_KNOWNHOSTS *hosts,
nlen = _libssh2_base64_encode(hosts->session, node->name,
node->name_len, &namealloc);
if(!nlen)
return libssh2_error(hosts->session, LIBSSH2_ERROR_ALLOC,
"Unable to allocate memory for "
"base64-encoded host name");
return _libssh2_error(hosts->session, LIBSSH2_ERROR_ALLOC,
"Unable to allocate memory for "
"base64-encoded host name");
nlen = _libssh2_base64_encode(hosts->session,
node->salt, node->salt_len,
&saltalloc);
if(!nlen) {
free(namealloc);
return libssh2_error(hosts->session, LIBSSH2_ERROR_ALLOC,
"Unable to allocate memory for "
"base64-encoded salt");
return _libssh2_error(hosts->session, LIBSSH2_ERROR_ALLOC,
"Unable to allocate memory for "
"base64-encoded salt");
}
nlen = strlen(saltalloc) + strlen(namealloc) + strlen(keytype) +
@@ -878,8 +966,8 @@ knownhost_writeline(LIBSSH2_KNOWNHOSTS *hosts,
sprintf(buf, "|1|%s|%s%s %s\n", saltalloc, namealloc,
keytype, node->key);
else
rc = libssh2_error(hosts->session, LIBSSH2_ERROR_BUFFER_TOO_SMALL,
"Known-host write buffer too small");
rc = _libssh2_error(hosts->session, LIBSSH2_ERROR_BUFFER_TOO_SMALL,
"Known-host write buffer too small");
free(namealloc);
free(saltalloc);
@@ -896,8 +984,8 @@ knownhost_writeline(LIBSSH2_KNOWNHOSTS *hosts,
else
sprintf(buf, "%s%s %s\n", node->name, keytype, node->key);
else
rc = libssh2_error(hosts->session, LIBSSH2_ERROR_BUFFER_TOO_SMALL,
"Known-host write buffer too small");
rc = _libssh2_error(hosts->session, LIBSSH2_ERROR_BUFFER_TOO_SMALL,
"Known-host write buffer too small");
}
/* we report the full length of the data with the trailing zero excluded */
@@ -924,8 +1012,8 @@ libssh2_knownhost_writeline(LIBSSH2_KNOWNHOSTS *hosts,
struct known_host *node;
if(known->magic != KNOWNHOST_MAGIC)
return libssh2_error(hosts->session, LIBSSH2_ERROR_INVAL,
"Invalid host information");
return _libssh2_error(hosts->session, LIBSSH2_ERROR_INVAL,
"Invalid host information");
node = known->node;
@@ -939,7 +1027,7 @@ libssh2_knownhost_writeline(LIBSSH2_KNOWNHOSTS *hosts,
*/
LIBSSH2_API int
libssh2_knownhost_writefile(LIBSSH2_KNOWNHOSTS *hosts,
const char *filename, int type)
const char *filename, int type)
{
struct known_host *node;
FILE *file;
@@ -949,15 +1037,15 @@ libssh2_knownhost_writefile(LIBSSH2_KNOWNHOSTS *hosts,
/* we only support this single file type for now, bail out on all other
attempts */
if(type != LIBSSH2_KNOWNHOST_FILE_OPENSSH)
return libssh2_error(hosts->session,
LIBSSH2_ERROR_METHOD_NOT_SUPPORTED,
"Unsupported type of known-host information "
"store");
return _libssh2_error(hosts->session,
LIBSSH2_ERROR_METHOD_NOT_SUPPORTED,
"Unsupported type of known-host information "
"store");
file = fopen(filename, "w");
if(!file)
return libssh2_error(hosts->session, LIBSSH2_ERROR_FILE,
"Failed to open file");
return _libssh2_error(hosts->session, LIBSSH2_ERROR_FILE,
"Failed to open file");
for(node = _libssh2_list_first(&hosts->head);
node;
@@ -972,8 +1060,8 @@ libssh2_knownhost_writefile(LIBSSH2_KNOWNHOSTS *hosts,
nwrote = fwrite(buffer, 1, wrote, file);
if(nwrote != wrote) {
/* failed to write the whole thing, bail out */
rc = libssh2_error(hosts->session, LIBSSH2_ERROR_FILE,
"Write failed");
rc = _libssh2_error(hosts->session, LIBSSH2_ERROR_FILE,
"Write failed");
break;
}
}

View File

@@ -344,8 +344,8 @@ int
_libssh2_rsa_sha1_sign(LIBSSH2_SESSION * session,
libssh2_dsa_ctx * rsactx,
const unsigned char *hash,
unsigned long hash_len,
unsigned char **signature, unsigned long *signature_len)
size_t hash_len,
unsigned char **signature, size_t *signature_len)
{
gcry_sexp_t sig_sexp;
gcry_sexp_t data;

View File

@@ -56,7 +56,7 @@
#define MD5_DIGEST_LENGTH 16
#define SHA_DIGEST_LENGTH 20
#define libssh2_random(buf, len) \
#define _libssh2_random(buf, len) \
(gcry_randomize ((buf), (len), GCRY_STRONG_RANDOM), 1)
#define libssh2_sha1_ctx gcry_md_hd_t
@@ -124,9 +124,9 @@ int _libssh2_rsa_sha1_verify(libssh2_rsa_ctx * rsa,
int _libssh2_rsa_sha1_sign(LIBSSH2_SESSION * session,
libssh2_rsa_ctx * rsactx,
const unsigned char *hash,
unsigned long hash_len,
size_t hash_len,
unsigned char **signature,
unsigned long *signature_len);
size_t *signature_len);
#define _libssh2_rsa_free(rsactx) gcry_sexp_release (rsactx)

View File

@@ -40,12 +40,6 @@
#ifndef LIBSSH2_PRIV_H
#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
#include "libssh2_config.h"
@@ -83,6 +77,21 @@
# endif
#endif
/* Needed for struct iovec on some platforms */
#ifdef HAVE_SYS_UIO_H
#include <sys/uio.h>
#endif
#ifdef HAVE_SYS_SOCKET_H
# include <sys/socket.h>
#endif
#ifdef HAVE_SYS_IOCTL_H
# include <sys/ioctl.h>
#endif
#ifdef HAVE_INTTYPES_H
#include <inttypes.h>
#endif
#include "libssh2.h"
#include "libssh2_publickey.h"
#include "libssh2_sftp.h"
@@ -116,20 +125,6 @@ static inline int writev(int sock, struct iovec *iov, int nvecs)
#endif /* WIN32 */
/* Needed for struct iovec on some platforms */
#ifdef HAVE_SYS_UIO_H
#include <sys/uio.h>
#endif
#ifdef HAVE_SYS_SOCKET_H
# include <sys/socket.h>
#endif
#ifdef HAVE_SYS_IOCTL_H
# include <sys/ioctl.h>
#endif
#ifdef HAVE_INTTYPES_H
#include <inttypes.h>
#endif
#ifdef LIBSSH2_LIBGCRYPT
#include "libgcrypt.h"
@@ -235,9 +230,9 @@ typedef struct kmdhgGPsha1kex_state_t
unsigned char *tmp;
unsigned char h_sig_comp[SHA_DIGEST_LENGTH];
unsigned char c;
unsigned long e_packet_len;
unsigned long s_packet_len;
unsigned long tmp_len;
size_t e_packet_len;
size_t s_packet_len;
size_t tmp_len;
_libssh2_bn_ctx *ctx;
_libssh2_bn *x;
_libssh2_bn *e;
@@ -247,9 +242,9 @@ typedef struct kmdhgGPsha1kex_state_t
unsigned char *f_value;
unsigned char *k_value;
unsigned char *h_sig;
unsigned long f_value_len;
unsigned long k_value_len;
unsigned long h_sig_len;
size_t f_value_len;
size_t k_value_len;
size_t h_sig_len;
libssh2_sha1_ctx exchange_hash;
packet_require_state_t req_state;
libssh2_nonblocking_states burn_state;
@@ -264,8 +259,8 @@ typedef struct key_exchange_state_low_t
_libssh2_bn *g; /* SSH2 defined value (2) */
unsigned char request[13];
unsigned char *data;
unsigned long request_len;
unsigned long data_len;
size_t request_len;
size_t data_len;
} key_exchange_state_low_t;
typedef struct key_exchange_state_t
@@ -274,9 +269,9 @@ typedef struct key_exchange_state_t
packet_require_state_t req_state;
key_exchange_state_low_t key_state_low;
unsigned char *data;
unsigned long data_len;
size_t data_len;
unsigned char *oldlocal;
unsigned long oldlocal_len;
size_t oldlocal_len;
} key_exchange_state_t;
#define FwdNotReq "Forward not requested"
@@ -320,7 +315,7 @@ struct _LIBSSH2_PACKET
/* Unencrypted Payload (no type byte, no padding, just the facts ma'am) */
unsigned char *data;
unsigned long data_len;
size_t data_len;
/* Where to start reading data from,
* used for channel data that's been partially consumed */
@@ -333,7 +328,7 @@ struct _LIBSSH2_PACKET
typedef struct _libssh2_channel_data
{
/* Identifier */
unsigned long id;
uint32_t id;
/* Limits and restrictions */
unsigned long window_size_initial, window_size, packet_size;
@@ -364,35 +359,35 @@ struct _LIBSSH2_CHANNEL
/* State variables used in libssh2_channel_setenv_ex() */
libssh2_nonblocking_states setenv_state;
unsigned char *setenv_packet;
unsigned long setenv_packet_len;
size_t setenv_packet_len;
unsigned char setenv_local_channel[4];
packet_requirev_state_t setenv_packet_requirev_state;
/* State variables used in libssh2_channel_request_pty_ex() */
libssh2_nonblocking_states reqPTY_state;
unsigned char *reqPTY_packet;
unsigned long reqPTY_packet_len;
size_t reqPTY_packet_len;
unsigned char reqPTY_local_channel[4];
packet_requirev_state_t reqPTY_packet_requirev_state;
/* State variables used in libssh2_channel_x11_req_ex() */
libssh2_nonblocking_states reqX11_state;
unsigned char *reqX11_packet;
unsigned long reqX11_packet_len;
size_t reqX11_packet_len;
unsigned char reqX11_local_channel[4];
packet_requirev_state_t reqX11_packet_requirev_state;
/* State variables used in libssh2_channel_process_startup() */
libssh2_nonblocking_states process_state;
unsigned char *process_packet;
unsigned long process_packet_len;
size_t process_packet_len;
unsigned char process_local_channel[4];
packet_requirev_state_t process_packet_requirev_state;
/* State variables used in libssh2_channel_flush_ex() */
libssh2_nonblocking_states flush_state;
unsigned long flush_refund_bytes;
unsigned long flush_flush_bytes;
size_t flush_refund_bytes;
size_t flush_flush_bytes;
/* State variables used in libssh2_channel_receive_window_adjust() */
libssh2_nonblocking_states adjust_state;
@@ -407,8 +402,8 @@ struct _LIBSSH2_CHANNEL
libssh2_nonblocking_states write_state;
unsigned char *write_packet;
unsigned char *write_s;
unsigned long write_packet_len;
unsigned long write_bufwrote;
size_t write_packet_len;
size_t write_bufwrote;
size_t write_bufwrite;
/* State variables used in libssh2_channel_close() */
@@ -454,7 +449,7 @@ typedef struct _libssh2_endpoint_data
unsigned char *banner;
unsigned char *kexinit;
unsigned long kexinit_len;
size_t kexinit_len;
const LIBSSH2_CRYPT_METHOD *crypt;
void *crypt_abstract;
@@ -479,36 +474,36 @@ struct transportpacket
{
/* ------------- for incoming data --------------- */
unsigned char buf[PACKETBUFSIZE];
unsigned char init[5]; /* first 5 bytes of the incoming data stream,
still encrypted */
int writeidx; /* at what array index we do the next write into
the buffer */
int readidx; /* at what array index we do the next read from
the buffer */
int packet_length; /* the most recent packet_length as read from the
network data */
int padding_length; /* the most recent padding_length as read from the
network data */
int data_num; /* How much of the total package that has been read
so far. */
int total_num; /* How much a total package is supposed to be, in
number of bytes. A full package is
packet_length + padding_length + 4 +
mac_length. */
unsigned char *payload; /* this is a pointer to a LIBSSH2_ALLOC()
area to which we write decrypted data */
unsigned char *wptr; /* write pointer into the payload to where we
are currently writing decrypted data */
unsigned char init[5]; /* first 5 bytes of the incoming data stream,
still encrypted */
int writeidx; /* at what array index we do the next write into
the buffer */
int readidx; /* at what array index we do the next read from
the buffer */
uint32_t packet_length; /* the most recent packet_length as read from the
network data */
uint8_t padding_length; /* the most recent padding_length as read from the
network data */
int data_num; /* How much of the total package that has been read
so far. */
int total_num; /* How much a total package is supposed to be, in
number of bytes. A full package is
packet_length + padding_length + 4 +
mac_length. */
unsigned char *payload; /* this is a pointer to a LIBSSH2_ALLOC()
area to which we write decrypted data */
unsigned char *wptr; /* write pointer into the payload to where we
are currently writing decrypted data */
/* ------------- for outgoing data --------------- */
unsigned char *outbuf; /* pointer to a LIBSSH2_ALLOC() area for the
outgoing data */
int ototal_num; /* size of outbuf in number of bytes */
unsigned char *odata; /* original pointer to the data we stored in
outbuf */
unsigned long olen; /* original size of the data we stored in
outbuf */
unsigned long osent; /* number of bytes already sent */
unsigned char *outbuf; /* pointer to a LIBSSH2_ALLOC() area for the
outgoing data */
int ototal_num; /* size of outbuf in number of bytes */
unsigned char *odata; /* original pointer to the data we stored in
outbuf */
size_t olen; /* original size of the data we stored in
outbuf */
size_t osent; /* number of bytes already sent */
};
struct _LIBSSH2_PUBLICKEY
@@ -519,7 +514,7 @@ struct _LIBSSH2_PUBLICKEY
/* State variables used in libssh2_publickey_packet_receive() */
libssh2_nonblocking_states receive_state;
unsigned char *receive_packet;
unsigned long receive_packet_len;
size_t receive_packet_len;
/* State variables used in libssh2_publickey_add_ex() */
libssh2_nonblocking_states add_state;
@@ -536,7 +531,7 @@ struct _LIBSSH2_PUBLICKEY
unsigned char *listFetch_s;
unsigned char listFetch_buffer[12];
unsigned char *listFetch_data;
unsigned long listFetch_data_len;
size_t listFetch_data_len;
};
#define SFTP_HANDLE_MAXLEN 256 /* according to spec! */
@@ -553,7 +548,7 @@ struct _LIBSSH2_SFTP_HANDLE
unsigned char request_packet[SFTP_HANDLE_MAXLEN + 25];
char handle[SFTP_HANDLE_MAXLEN];
int handle_len;
size_t handle_len;
char handle_type;
@@ -592,8 +587,8 @@ struct _LIBSSH2_SFTP
/* Holder for partial packet, use in libssh2_sftp_packet_read() */
unsigned char *partial_packet; /* The data */
unsigned long partial_len; /* Desired number of bytes */
unsigned long partial_received; /* Bytes received so far */
size_t partial_len; /* Desired number of bytes */
size_t partial_received; /* Bytes received so far */
/* Time that libssh2_sftp_packet_requirev() started reading */
time_t requirev_start;
@@ -601,60 +596,71 @@ struct _LIBSSH2_SFTP
/* State variables used in libssh2_sftp_open_ex() */
libssh2_nonblocking_states open_state;
unsigned char *open_packet;
ssize_t open_packet_len;
unsigned long open_request_id;
size_t open_packet_len;
size_t open_packet_sent;
uint32_t open_request_id;
/* State variables used in libssh2_sftp_read() */
libssh2_nonblocking_states read_state;
unsigned char *read_packet;
unsigned long read_request_id;
uint32_t read_request_id;
size_t read_total_read;
/* State variables used in libssh2_sftp_readdir() */
libssh2_nonblocking_states readdir_state;
unsigned char *readdir_packet;
unsigned long readdir_request_id;
uint32_t readdir_request_id;
/* State variables used in libssh2_sftp_write() */
libssh2_nonblocking_states write_state;
unsigned char *write_packet;
unsigned long write_request_id;
uint32_t write_request_id;
/* State variables used in libssh2_sftp_fstat_ex() */
libssh2_nonblocking_states fstat_state;
unsigned char *fstat_packet;
unsigned long fstat_request_id;
uint32_t fstat_request_id;
/* State variables used in libssh2_sftp_unlink_ex() */
libssh2_nonblocking_states unlink_state;
unsigned char *unlink_packet;
unsigned long unlink_request_id;
uint32_t unlink_request_id;
/* State variables used in libssh2_sftp_rename_ex() */
libssh2_nonblocking_states rename_state;
unsigned char *rename_packet;
unsigned char *rename_s;
unsigned long rename_request_id;
uint32_t rename_request_id;
/* State variables used in libssh2_sftp_fstatvfs() */
libssh2_nonblocking_states fstatvfs_state;
unsigned char *fstatvfs_packet;
uint32_t fstatvfs_request_id;
/* State variables used in libssh2_sftp_statvfs() */
libssh2_nonblocking_states statvfs_state;
unsigned char *statvfs_packet;
uint32_t statvfs_request_id;
/* State variables used in libssh2_sftp_mkdir() */
libssh2_nonblocking_states mkdir_state;
unsigned char *mkdir_packet;
unsigned long mkdir_request_id;
uint32_t mkdir_request_id;
/* State variables used in libssh2_sftp_rmdir() */
libssh2_nonblocking_states rmdir_state;
unsigned char *rmdir_packet;
unsigned long rmdir_request_id;
uint32_t rmdir_request_id;
/* State variables used in libssh2_sftp_stat() */
libssh2_nonblocking_states stat_state;
unsigned char *stat_packet;
unsigned long stat_request_id;
uint32_t stat_request_id;
/* State variables used in libssh2_sftp_symlink() */
libssh2_nonblocking_states symlink_state;
unsigned char *symlink_packet;
unsigned long symlink_request_id;
uint32_t symlink_request_id;
};
#define LIBSSH2_SCP_RESPONSE_BUFLEN 256
@@ -754,9 +760,9 @@ struct _LIBSSH2_SESSION
/* State variables used in libssh2_session_startup() */
libssh2_nonblocking_states startup_state;
unsigned char *startup_data;
unsigned long startup_data_len;
size_t startup_data_len;
unsigned char startup_service[sizeof("ssh-userauth") + 5 - 1];
unsigned long startup_service_length;
size_t startup_service_length;
packet_require_state_t startup_req_state;
key_exchange_state_t startup_key_state;
@@ -766,7 +772,7 @@ struct _LIBSSH2_SESSION
/* State variables used in libssh2_session_disconnect_ex() */
libssh2_nonblocking_states disconnect_state;
unsigned char *disconnect_data;
unsigned long disconnect_data_len;
size_t disconnect_data_len;
/* State variables used in libssh2_packet_read() */
libssh2_nonblocking_states readPack_state;
@@ -775,14 +781,14 @@ struct _LIBSSH2_SESSION
/* State variables used in libssh2_userauth_list() */
libssh2_nonblocking_states userauth_list_state;
unsigned char *userauth_list_data;
unsigned long userauth_list_data_len;
size_t userauth_list_data_len;
packet_requirev_state_t userauth_list_packet_requirev_state;
/* State variables used in libssh2_userauth_password_ex() */
libssh2_nonblocking_states userauth_pswd_state;
unsigned char *userauth_pswd_data;
unsigned char userauth_pswd_data0;
unsigned long userauth_pswd_data_len;
size_t userauth_pswd_data_len;
char *userauth_pswd_newpw;
int userauth_pswd_newpw_len;
packet_requirev_state_t userauth_pswd_packet_requirev_state;
@@ -790,22 +796,22 @@ struct _LIBSSH2_SESSION
/* State variables used in libssh2_userauth_hostbased_fromfile_ex() */
libssh2_nonblocking_states userauth_host_state;
unsigned char *userauth_host_data;
unsigned long userauth_host_data_len;
size_t userauth_host_data_len;
unsigned char *userauth_host_packet;
unsigned long userauth_host_packet_len;
size_t userauth_host_packet_len;
unsigned char *userauth_host_method;
unsigned long userauth_host_method_len;
size_t userauth_host_method_len;
unsigned char *userauth_host_s;
packet_requirev_state_t userauth_host_packet_requirev_state;
/* State variables used in libssh2_userauth_publickey_fromfile_ex() */
libssh2_nonblocking_states userauth_pblc_state;
unsigned char *userauth_pblc_data;
unsigned long userauth_pblc_data_len;
size_t userauth_pblc_data_len;
unsigned char *userauth_pblc_packet;
unsigned long userauth_pblc_packet_len;
size_t userauth_pblc_packet_len;
unsigned char *userauth_pblc_method;
unsigned long userauth_pblc_method_len;
size_t userauth_pblc_method_len;
unsigned char *userauth_pblc_s;
unsigned char *userauth_pblc_b;
packet_requirev_state_t userauth_pblc_packet_requirev_state;
@@ -813,9 +819,9 @@ struct _LIBSSH2_SESSION
/* State variables used in libssh2_userauth_keyboard_interactive_ex() */
libssh2_nonblocking_states userauth_kybd_state;
unsigned char *userauth_kybd_data;
unsigned long userauth_kybd_data_len;
size_t userauth_kybd_data_len;
unsigned char *userauth_kybd_packet;
unsigned long userauth_kybd_packet_len;
size_t userauth_kybd_packet_len;
unsigned int userauth_kybd_auth_name_len;
char *userauth_kybd_auth_name;
unsigned userauth_kybd_auth_instruction_len;
@@ -831,17 +837,17 @@ struct _LIBSSH2_SESSION
packet_requirev_state_t open_packet_requirev_state;
LIBSSH2_CHANNEL *open_channel;
unsigned char *open_packet;
unsigned long open_packet_len;
size_t open_packet_len;
unsigned char *open_data;
unsigned long open_data_len;
unsigned long open_local_channel;
size_t open_data_len;
uint32_t open_local_channel;
/* State variables used in libssh2_channel_direct_tcpip_ex() */
libssh2_nonblocking_states direct_state;
unsigned char *direct_message;
unsigned long direct_host_len;
unsigned long direct_shost_len;
unsigned long direct_message_len;
size_t direct_host_len;
size_t direct_shost_len;
size_t direct_message_len;
/* State variables used in libssh2_channel_forward_listen_ex() */
libssh2_nonblocking_states fwdLstn_state;
@@ -855,7 +861,10 @@ struct _LIBSSH2_SESSION
LIBSSH2_PUBLICKEY *pkeyInit_pkey;
LIBSSH2_CHANNEL *pkeyInit_channel;
unsigned char *pkeyInit_data;
unsigned long pkeyInit_data_len;
size_t pkeyInit_data_len;
/* 19 = packet_len(4) + version_len(4) + "version"(7) + version_num(4) */
unsigned char pkeyInit_buffer[19];
size_t pkeyInit_buffer_sent; /* how much of buffer that has been sent */
/* State variables used in libssh2_packet_add() */
libssh2_nonblocking_states packAdd_state;
@@ -955,18 +964,18 @@ struct _LIBSSH2_HOSTKEY_METHOD
unsigned long hash_len;
int (*init) (LIBSSH2_SESSION * session, const unsigned char *hostkey_data,
unsigned long hostkey_data_len, void **abstract);
size_t hostkey_data_len, void **abstract);
int (*initPEM) (LIBSSH2_SESSION * session, const char *privkeyfile,
unsigned const char *passphrase, void **abstract);
int (*sig_verify) (LIBSSH2_SESSION * session, const unsigned char *sig,
unsigned long sig_len, const unsigned char *m,
unsigned long m_len, void **abstract);
size_t sig_len, const unsigned char *m,
size_t m_len, void **abstract);
int (*signv) (LIBSSH2_SESSION * session, unsigned char **signature,
unsigned long *signature_len, unsigned long veccount,
size_t *signature_len, int veccount,
const struct iovec datavec[], void **abstract);
int (*encrypt) (LIBSSH2_SESSION * session, unsigned char **dst,
unsigned long *dst_len, const unsigned char *src,
unsigned long src_len, void **abstract);
size_t *dst_len, const unsigned char *src,
size_t src_len, void **abstract);
int (*dtor) (LIBSSH2_SESSION * session, void **abstract);
};
@@ -999,9 +1008,9 @@ struct _LIBSSH2_COMP_METHOD
int (*init) (LIBSSH2_SESSION * session, int compress, void **abstract);
int (*comp) (LIBSSH2_SESSION * session, int compress, unsigned char **dest,
unsigned long *dest_len, unsigned long payload_limit,
size_t *dest_len, size_t payload_limit,
int *free_dest, const unsigned char *src,
unsigned long src_len, void **abstract);
size_t src_len, void **abstract);
int (*dtor) (LIBSSH2_SESSION * session, int compress, void **abstract);
};
@@ -1041,8 +1050,6 @@ _libssh2_debug(LIBSSH2_SESSION * session, int context, const char *format, ...)
#endif
#endif
int libssh2_error(LIBSSH2_SESSION* session, int errcode, const char* errmsg);
#define LIBSSH2_SOCKET_UNKNOWN 1
#define LIBSSH2_SOCKET_CONNECTED 0
#define LIBSSH2_SOCKET_DISCONNECTED -1
@@ -1108,13 +1115,7 @@ int libssh2_error(LIBSSH2_SESSION* session, int errcode, const char* errmsg);
#define SSH_MSG_CHANNEL_SUCCESS 99
#define SSH_MSG_CHANNEL_FAILURE 100
void _libssh2_session_shutdown(LIBSSH2_SESSION * session);
unsigned int _libssh2_ntohu32(const unsigned char *buf);
libssh2_uint64_t _libssh2_ntohu64(const unsigned char *buf);
void _libssh2_htonu32(unsigned char *buf, unsigned int val);
#ifdef WIN32
#if defined( WIN32 ) || defined( __VMS )
ssize_t _libssh2_recv(libssh2_socket_t socket, void *buffer, size_t length, int flags);
ssize_t _libssh2_send(libssh2_socket_t socket, const void *buffer, size_t length, int flags);
#else
@@ -1125,74 +1126,14 @@ ssize_t _libssh2_send(libssh2_socket_t socket, const void *buffer, size_t length
#define LIBSSH2_READ_TIMEOUT 60 /* generic timeout in seconds used when
waiting for more data to arrive */
int _libssh2_wait_socket(LIBSSH2_SESSION *session);
/* These started out as private return codes for the transport layer, but was
converted to using the library-wide return codes to easy propagation of the
error reasons all over etc without risking mixups. The PACKET_* names are
left only to reduce the impact of changing the code all over.*/
#define PACKET_TIMEOUT LIBSSH2_ERROR_TIMEOUT
#define PACKET_BADUSE LIBSSH2_ERROR_BAD_USE
#define PACKET_COMPRESS LIBSSH2_ERROR_COMPRESS
#define PACKET_TOOBIG LIBSSH2_ERROR_OUT_OF_BOUNDARY
#define PACKET_ENOMEM LIBSSH2_ERROR_ALLOC
#define PACKET_EAGAIN LIBSSH2_ERROR_EAGAIN
#define PACKET_FAIL LIBSSH2_ERROR_SOCKET_NONE
#define PACKET_NONE LIBSSH2_ERROR_NONE
int _libssh2_packet_read(LIBSSH2_SESSION * session);
int _libssh2_packet_ask(LIBSSH2_SESSION * session, unsigned char packet_type,
unsigned char **data, unsigned long *data_len,
unsigned long match_ofs,
const unsigned char *match_buf,
unsigned long match_len);
int _libssh2_packet_askv(LIBSSH2_SESSION * session,
const unsigned char *packet_types,
unsigned char **data, unsigned long *data_len,
unsigned long match_ofs,
const unsigned char *match_buf,
unsigned long match_len);
int _libssh2_packet_require(LIBSSH2_SESSION * session,
unsigned char packet_type, unsigned char **data,
unsigned long *data_len, unsigned long match_ofs,
const unsigned char *match_buf,
unsigned long match_len,
packet_require_state_t * state);
int _libssh2_packet_requirev(LIBSSH2_SESSION * session,
const unsigned char *packet_types,
unsigned char **data, unsigned long *data_len,
unsigned long match_ofs,
const unsigned char *match_buf,
unsigned long match_len,
packet_requirev_state_t * state);
int _libssh2_packet_burn(LIBSSH2_SESSION * session,
libssh2_nonblocking_states * state);
int _libssh2_packet_write(LIBSSH2_SESSION * session, unsigned char *data,
unsigned long data_len);
int _libssh2_packet_add(LIBSSH2_SESSION * session, unsigned char *data,
size_t datalen, int macstate);
int libssh2_kex_exchange(LIBSSH2_SESSION * session, int reexchange,
key_exchange_state_t * state);
unsigned long _libssh2_channel_nextid(LIBSSH2_SESSION * session);
LIBSSH2_CHANNEL *_libssh2_channel_locate(LIBSSH2_SESSION * session,
unsigned long channel_id);
unsigned long _libssh2_channel_packet_data_len(LIBSSH2_CHANNEL * channel,
int stream_id);
/* this is the lib-internal set blocking function */
int _libssh2_session_set_blocking(LIBSSH2_SESSION * session, int blocking);
int _libssh2_kex_exchange(LIBSSH2_SESSION * session, int reexchange,
key_exchange_state_t * state);
/* Let crypt.c/hostkey.c expose their method structs */
const LIBSSH2_CRYPT_METHOD **libssh2_crypt_methods(void);
const LIBSSH2_HOSTKEY_METHOD **libssh2_hostkey_methods(void);
/* Language API doesn't exist yet. Just act like we've agreed on a language */
#define libssh2_kex_agree_lang(session, endpoint, str, str_len) 0
/* pem.c */
int _libssh2_pem_parse(LIBSSH2_SESSION * session,
const char *headerbegin,
@@ -1205,49 +1146,6 @@ int _libssh2_pem_decode_integer(unsigned char **data, unsigned int *datalen,
/* global.c */
void _libssh2_init_if_needed (void);
/* Conveniance-macros to allow code like this;
int rc = BLOCK_ADJUST(rc, session, session_startup(session, sock) );
int rc = BLOCK_ADJUST_ERRNO(ptr, session, session_startup(session, sock) );
The point of course being to make sure that while in non-blocking mode
these always return no matter what the return code is, but in blocking mode
it blocks if EAGAIN is the reason for the return from the underlying
function.
*/
#define BLOCK_ADJUST(rc,sess,x) \
do { \
rc = x; \
/* the order of the check below is important to properly deal with the
case when the 'sess' is freed */ \
if((rc != LIBSSH2_ERROR_EAGAIN) || !sess->api_block_mode) \
break; \
rc = _libssh2_wait_socket(sess); \
if(rc) \
break; \
} while(1)
/*
* For functions that returns a pointer, we need to check if the API is
* non-blocking and return immediately. If the pointer is non-NULL we return
* immediately. If the API is blocking and we get a NULL we check the errno
* and *only* if that is EAGAIN we loop and wait for socket action.
*/
#define BLOCK_ADJUST_ERRNO(ptr,sess,x) \
do { \
int rc; \
ptr = x; \
if(!sess->api_block_mode || \
(ptr != NULL) || \
(libssh2_session_last_errno(sess) != LIBSSH2_ERROR_EAGAIN) ) \
break; \
rc = _libssh2_wait_socket(sess); \
if(rc) \
break; \
} while(1)
#define ARRAY_SIZE(a) (sizeof ((a)) / sizeof ((a)[0]))

View File

@@ -49,7 +49,7 @@
#include <errno.h>
int libssh2_error(LIBSSH2_SESSION* session, int errcode, const char* errmsg)
int _libssh2_error(LIBSSH2_SESSION* session, int errcode, const char* errmsg)
{
session->err_msg = errmsg;
session->err_code = errcode;
@@ -96,6 +96,11 @@ _libssh2_recv(libssh2_socket_t socket, void *buffer, size_t length, int flags)
#ifdef WIN32
if (rc < 0 )
errno = wsa2errno();
#endif
#ifdef __VMS
if (rc < 0 ){
if ( errno == EWOULDBLOCK ) errno = EAGAIN;
}
#endif
return rc;
}
@@ -115,6 +120,11 @@ _libssh2_send(libssh2_socket_t socket, const void *buffer, size_t length, int fl
#ifdef WIN32
if (rc < 0 )
errno = wsa2errno();
#endif
#ifdef VMS
if (rc < 0 ){
if ( errno == EWOULDBLOCK ) errno = EAGAIN;
}
#endif
return rc;
}
@@ -145,7 +155,7 @@ _libssh2_ntohu64(const unsigned char *buf)
/* _libssh2_htonu32
*/
void
_libssh2_htonu32(unsigned char *buf, unsigned int value)
_libssh2_htonu32(unsigned char *buf, uint32_t value)
{
buf[0] = (value >> 24) & 0xFF;
buf[1] = (value >> 16) & 0xFF;
@@ -153,6 +163,25 @@ _libssh2_htonu32(unsigned char *buf, unsigned int value)
buf[3] = value & 0xFF;
}
/* _libssh2_store_u32
*/
void _libssh2_store_u32(unsigned char **buf, uint32_t value)
{
_libssh2_htonu32(*buf, value);
*buf += sizeof(uint32_t);
}
/* _libssh2_store_str
*/
void _libssh2_store_str(unsigned char **buf, const char *str, size_t len)
{
_libssh2_store_u32(buf, (uint32_t)len);
if(len) {
memcpy(*buf, str, len);
*buf += len;
}
}
/* Base64 Conversion */
static const char base64_table[] =
@@ -201,8 +230,8 @@ libssh2_base64_decode(LIBSSH2_SESSION *session, char **data,
*data = LIBSSH2_ALLOC(session, (3 * src_len / 4) + 1);
d = (unsigned char *) *data;
if (!d) {
return libssh2_error(session, LIBSSH2_ERROR_ALLOC,
"Unable to allocate memory for base64 decoding");
return _libssh2_error(session, LIBSSH2_ERROR_ALLOC,
"Unable to allocate memory for base64 decoding");
}
for(s = (unsigned char *) src; ((char *) s) < (src + src_len); s++) {
@@ -230,8 +259,8 @@ libssh2_base64_decode(LIBSSH2_SESSION *session, char **data,
/* Invalid -- We have a byte which belongs exclusively to a partial
octet */
LIBSSH2_FREE(session, *data);
return libssh2_error(session, LIBSSH2_ERROR_INVAL,
"Invalid data (byte belonging to partial octet)");
return _libssh2_error(session, LIBSSH2_ERROR_INVAL,
"Invalid data (byte belonging to partial octet)");
}
*datalen = len;
@@ -504,7 +533,7 @@ void _libssh2_list_insert(struct list_node *after, /* insert before this */
#ifdef WIN32
#if defined(LIBSSH2_WIN32) && !defined(__MINGW32__)
/*
* gettimeofday
* Implementation according to:

View File

@@ -1,6 +1,6 @@
#ifndef __LIBSSH2_MISC_H
#define __LIBSSH2_MISC_H
/* Copyright (c) 2009 by Daniel Stenberg
/* Copyright (c) 2009-2010 by Daniel Stenberg
*
* All rights reserved.
*
@@ -49,6 +49,8 @@ struct list_node {
struct list_head *head;
};
int _libssh2_error(LIBSSH2_SESSION* session, int errcode, const char* errmsg);
void _libssh2_list_init(struct list_head *head);
/* add a node last in the list */
@@ -69,4 +71,11 @@ void _libssh2_list_remove(struct list_node *entry);
size_t _libssh2_base64_encode(struct _LIBSSH2_SESSION *session,
const char *inp, size_t insize, char **outptr);
unsigned int _libssh2_ntohu32(const unsigned char *buf);
libssh2_uint64_t _libssh2_ntohu64(const unsigned char *buf);
void _libssh2_htonu32(unsigned char *buf, uint32_t val);
void _libssh2_store_u32(unsigned char **buf, uint32_t value);
void _libssh2_store_str(unsigned char **buf, const char *str, size_t len);
#endif /* _LIBSSH2_MISC_H */

View File

@@ -201,7 +201,7 @@ _libssh2_cipher_crypt(_libssh2_cipher_ctx * ctx,
return ret == 1 ? 0 : 1;
}
#if LIBSSH2_AES_CTR && !defined(HAVE_EVP_AES128_CTR)
#if LIBSSH2_AES_CTR && !defined(HAVE_EVP_AES_128_CTR)
#include <openssl/aes.h>
@@ -385,8 +385,8 @@ int
_libssh2_rsa_sha1_sign(LIBSSH2_SESSION * session,
libssh2_rsa_ctx * rsactx,
const unsigned char *hash,
unsigned long hash_len,
unsigned char **signature, unsigned long *signature_len)
size_t hash_len,
unsigned char **signature, size_t *signature_len)
{
int ret;
unsigned char *sig;

View File

@@ -104,7 +104,7 @@
# define LIBSSH2_3DES 1
#endif
#define libssh2_random(buf, len) RAND_bytes ((buf), (len))
#define _libssh2_random(buf, len) RAND_bytes ((buf), (len))
#define libssh2_sha1_ctx EVP_MD_CTX
#define libssh2_sha1_init(ctx) EVP_DigestInit(ctx, EVP_get_digestbyname("sha1"))
@@ -162,9 +162,9 @@ int _libssh2_rsa_sha1_verify(libssh2_rsa_ctx * rsa,
int _libssh2_rsa_sha1_sign(LIBSSH2_SESSION * session,
libssh2_rsa_ctx * rsactx,
const unsigned char *hash,
unsigned long hash_len,
size_t hash_len,
unsigned char **signature,
unsigned long *signature_len);
size_t *signature_len);
#define _libssh2_rsa_free(rsactx) RSA_free(rsactx)
@@ -199,7 +199,7 @@ int _libssh2_dsa_sha1_sign(libssh2_dsa_ctx * dsactx,
#define _libssh2_cipher_aes256 EVP_aes_256_cbc
#define _libssh2_cipher_aes192 EVP_aes_192_cbc
#define _libssh2_cipher_aes128 EVP_aes_128_cbc
#ifdef HAVE_EVP_AES128_CTR
#ifdef HAVE_EVP_AES_128_CTR
#define _libssh2_cipher_aes128ctr EVP_aes_128_ctr
#define _libssh2_cipher_aes192ctr EVP_aes_192_ctr
#define _libssh2_cipher_aes256ctr EVP_aes_256_ctr

View File

@@ -1,4 +1,5 @@
/* Copyright (c) 2004-2007, Sara Golemon <sarag@libssh2.org>
* Copyright (c) 2005,2006 Mikhail Gusarov
* Copyright (c) 2009 by Daniel Stenberg
* Copyright (c) 2010 Simon Josefsson
* All rights reserved.
@@ -62,6 +63,7 @@
#include "transport.h"
#include "channel.h"
#include "packet.h"
/*
* libssh2_packet_queue_listener
@@ -76,7 +78,6 @@ packet_queue_listener(LIBSSH2_SESSION * session, unsigned char *data,
/*
* Look for a matching listener
*/
unsigned char *s = data + (sizeof("forwarded-tcpip") - 1) + 5;
/* 17 = packet_type(1) + channel(4) + reason(4) + descr(4) + lang(4) */
unsigned long packet_len = 17 + (sizeof(FwdNotReq) - 1);
unsigned char *p;
@@ -87,6 +88,7 @@ packet_queue_listener(LIBSSH2_SESSION * session, unsigned char *data,
(void) datalen;
if (listen_state->state == libssh2_NB_state_idle) {
unsigned char *s = data + (sizeof("forwarded-tcpip") - 1) + 5;
listen_state->sender_channel = _libssh2_ntohu32(s);
s += 4;
@@ -107,7 +109,6 @@ packet_queue_listener(LIBSSH2_SESSION * session, unsigned char *data,
listen_state->shost = s;
s += listen_state->shost_len;
listen_state->sport = _libssh2_ntohu32(s);
s += 4;
_libssh2_debug(session, LIBSSH2_TRACE_CONN,
"Remote received connection from %s:%ld to %s:%ld",
@@ -140,9 +141,9 @@ packet_queue_listener(LIBSSH2_SESSION * session, unsigned char *data,
channel = LIBSSH2_ALLOC(session, sizeof(LIBSSH2_CHANNEL));
if (!channel) {
libssh2_error(session, LIBSSH2_ERROR_ALLOC,
"Unable to allocate a channel for "
"new connection");
_libssh2_error(session, LIBSSH2_ERROR_ALLOC,
"Unable to allocate a channel for "
"new connection");
failure_code = 4; /* SSH_OPEN_RESOURCE_SHORTAGE */
listen_state->state = libssh2_NB_state_sent;
break;
@@ -158,9 +159,9 @@ packet_queue_listener(LIBSSH2_SESSION * session, unsigned char *data,
channel_type_len +
1);
if (!channel->channel_type) {
libssh2_error(session, LIBSSH2_ERROR_ALLOC,
"Unable to allocate a channel for new"
" connection");
_libssh2_error(session, LIBSSH2_ERROR_ALLOC,
"Unable to allocate a channel for new"
" connection");
LIBSSH2_FREE(session, channel);
failure_code = 4; /* SSH_OPEN_RESOURCE_SHORTAGE */
listen_state->state = libssh2_NB_state_sent;
@@ -194,14 +195,10 @@ packet_queue_listener(LIBSSH2_SESSION * session, unsigned char *data,
p = listen_state->packet;
*(p++) = SSH_MSG_CHANNEL_OPEN_CONFIRMATION;
_libssh2_htonu32(p, channel->remote.id);
p += 4;
_libssh2_htonu32(p, channel->local.id);
p += 4;
_libssh2_htonu32(p, channel->remote.window_size_initial);
p += 4;
_libssh2_htonu32(p, channel->remote.packet_size);
p += 4;
_libssh2_store_u32(&p, channel->remote.id);
_libssh2_store_u32(&p, channel->local.id);
_libssh2_store_u32(&p, channel->remote.window_size_initial);
_libssh2_store_u32(&p, channel->remote.packet_size);
listen_state->state = libssh2_NB_state_created;
}
@@ -209,13 +206,13 @@ packet_queue_listener(LIBSSH2_SESSION * session, unsigned char *data,
if (listen_state->state == libssh2_NB_state_created) {
rc = _libssh2_transport_write(session, listen_state->packet,
17);
if (rc == PACKET_EAGAIN)
if (rc == LIBSSH2_ERROR_EAGAIN)
return rc;
else if (rc) {
listen_state->state = libssh2_NB_state_idle;
return libssh2_error(session, rc,
"Unable to send channel "
"open confirmation");
return _libssh2_error(session, rc,
"Unable to send channel "
"open confirmation");
}
/* Link the channel into the end of the queue list */
@@ -237,23 +234,18 @@ packet_queue_listener(LIBSSH2_SESSION * session, unsigned char *data,
/* We're not listening to you */
p = listen_state->packet;
*(p++) = SSH_MSG_CHANNEL_OPEN_FAILURE;
_libssh2_htonu32(p, listen_state->sender_channel);
p += 4;
_libssh2_htonu32(p, failure_code);
p += 4;
_libssh2_htonu32(p, sizeof(FwdNotReq) - 1);
p += 4;
memcpy(s, FwdNotReq, sizeof(FwdNotReq) - 1);
p += sizeof(FwdNotReq) - 1;
_libssh2_store_u32(&p, listen_state->sender_channel);
_libssh2_store_u32(&p, failure_code);
_libssh2_store_str(&p, FwdNotReq, sizeof(FwdNotReq) - 1);
_libssh2_htonu32(p, 0);
rc = _libssh2_transport_write(session, listen_state->packet,
packet_len);
if (rc == PACKET_EAGAIN) {
if (rc == LIBSSH2_ERROR_EAGAIN) {
return rc;
} else if (rc) {
listen_state->state = libssh2_NB_state_idle;
return libssh2_error(session, rc, "Unable to send open failure");
return _libssh2_error(session, rc, "Unable to send open failure");
}
listen_state->state = libssh2_NB_state_idle;
@@ -271,7 +263,6 @@ packet_x11_open(LIBSSH2_SESSION * session, unsigned char *data,
packet_x11_open_state_t *x11open_state)
{
int failure_code = 2; /* SSH_OPEN_CONNECT_FAILED */
unsigned char *s = data + (sizeof("x11") - 1) + 5;
/* 17 = packet_type(1) + channel(4) + reason(4) + descr(4) + lang(4) */
unsigned long packet_len = 17 + (sizeof(X11FwdUnAvil) - 1);
unsigned char *p;
@@ -281,6 +272,7 @@ packet_x11_open(LIBSSH2_SESSION * session, unsigned char *data,
(void) datalen;
if (x11open_state->state == libssh2_NB_state_idle) {
unsigned char *s = data + (sizeof("x11") - 1) + 5;
x11open_state->sender_channel = _libssh2_ntohu32(s);
s += 4;
x11open_state->initial_window_size = _libssh2_ntohu32(s);
@@ -292,7 +284,6 @@ packet_x11_open(LIBSSH2_SESSION * session, unsigned char *data,
x11open_state->shost = s;
s += x11open_state->shost_len;
x11open_state->sport = _libssh2_ntohu32(s);
s += 4;
_libssh2_debug(session, LIBSSH2_TRACE_CONN,
"X11 Connection Received from %s:%ld on channel %lu",
@@ -306,8 +297,8 @@ packet_x11_open(LIBSSH2_SESSION * session, unsigned char *data,
if (x11open_state->state == libssh2_NB_state_allocated) {
channel = LIBSSH2_ALLOC(session, sizeof(LIBSSH2_CHANNEL));
if (!channel) {
libssh2_error(session, LIBSSH2_ERROR_ALLOC,
"Unable to allocate a channel for new connection");
_libssh2_error(session, LIBSSH2_ERROR_ALLOC,
"Unable to allocate a channel for new connection");
failure_code = 4; /* SSH_OPEN_RESOURCE_SHORTAGE */
goto x11_exit;
}
@@ -319,8 +310,8 @@ packet_x11_open(LIBSSH2_SESSION * session, unsigned char *data,
channel->channel_type_len +
1);
if (!channel->channel_type) {
libssh2_error(session, LIBSSH2_ERROR_ALLOC,
"Unable to allocate a channel for new connection");
_libssh2_error(session, LIBSSH2_ERROR_ALLOC,
"Unable to allocate a channel for new connection");
LIBSSH2_FREE(session, channel);
failure_code = 4; /* SSH_OPEN_RESOURCE_SHORTAGE */
goto x11_exit;
@@ -349,27 +340,23 @@ packet_x11_open(LIBSSH2_SESSION * session, unsigned char *data,
channel->remote.packet_size);
p = x11open_state->packet;
*(p++) = SSH_MSG_CHANNEL_OPEN_CONFIRMATION;
_libssh2_htonu32(p, channel->remote.id);
p += 4;
_libssh2_htonu32(p, channel->local.id);
p += 4;
_libssh2_htonu32(p, channel->remote.window_size_initial);
p += 4;
_libssh2_htonu32(p, channel->remote.packet_size);
p += 4;
_libssh2_store_u32(&p, channel->remote.id);
_libssh2_store_u32(&p, channel->local.id);
_libssh2_store_u32(&p, channel->remote.window_size_initial);
_libssh2_store_u32(&p, channel->remote.packet_size);
x11open_state->state = libssh2_NB_state_created;
}
if (x11open_state->state == libssh2_NB_state_created) {
rc = _libssh2_transport_write(session, x11open_state->packet, 17);
if (rc == PACKET_EAGAIN) {
if (rc == LIBSSH2_ERROR_EAGAIN) {
return rc;
} else if (rc) {
x11open_state->state = libssh2_NB_state_idle;
return libssh2_error(session, LIBSSH2_ERROR_SOCKET_SEND,
"Unable to send channel open "
"confirmation");
return _libssh2_error(session, LIBSSH2_ERROR_SOCKET_SEND,
"Unable to send channel open "
"confirmation");
}
/* Link the channel into the session */
@@ -392,22 +379,17 @@ packet_x11_open(LIBSSH2_SESSION * session, unsigned char *data,
x11_exit:
p = x11open_state->packet;
*(p++) = SSH_MSG_CHANNEL_OPEN_FAILURE;
_libssh2_htonu32(p, x11open_state->sender_channel);
p += 4;
_libssh2_htonu32(p, failure_code);
p += 4;
_libssh2_htonu32(p, sizeof(X11FwdUnAvil) - 1);
p += 4;
memcpy(s, X11FwdUnAvil, sizeof(X11FwdUnAvil) - 1);
p += sizeof(X11FwdUnAvil) - 1;
_libssh2_store_u32(&p, x11open_state->sender_channel);
_libssh2_store_u32(&p, failure_code);
_libssh2_store_str(&p, X11FwdUnAvil, sizeof(X11FwdUnAvil) - 1);
_libssh2_htonu32(p, 0);
rc = _libssh2_transport_write(session, x11open_state->packet, packet_len);
if (rc == PACKET_EAGAIN) {
if (rc == LIBSSH2_ERROR_EAGAIN) {
return rc;
} else if (rc) {
x11open_state->state = libssh2_NB_state_idle;
return libssh2_error(session, rc, "Unable to send open failure");
return _libssh2_error(session, rc, "Unable to send open failure");
}
x11open_state->state = libssh2_NB_state_idle;
return 0;
@@ -459,8 +441,8 @@ _libssh2_packet_add(LIBSSH2_SESSION * session, unsigned char *data,
"", 0);
}
LIBSSH2_FREE(session, data);
return libssh2_error(session, LIBSSH2_ERROR_INVALID_MAC,
"Invalid MAC received");
return _libssh2_error(session, LIBSSH2_ERROR_INVALID_MAC,
"Invalid MAC received");
}
}
@@ -492,47 +474,47 @@ _libssh2_packet_add(LIBSSH2_SESSION * session, unsigned char *data,
/* A couple exceptions to the packet adding rule: */
switch (data[0]) {
case SSH_MSG_DISCONNECT:
{
char *message, *language;
int reason, message_len, language_len;
{
char *message, *language;
int reason, message_len, language_len;
reason = _libssh2_ntohu32(data + 1);
message_len = _libssh2_ntohu32(data + 5);
/* 9 = packet_type(1) + reason(4) + message_len(4) */
message = (char *) data + 9;
language_len = _libssh2_ntohu32(data + 9 + message_len);
/*
* This is where we hack on the data a little,
* Use the MSB of language_len to to a terminating NULL
* (In all liklihood it is already)
* Shift the language tag back a byte (In all likelihood
* it's zero length anyway)
* Store a NULL in the last byte of the packet to terminate
* the language string
* With the lengths passed this isn't *REALLY* necessary,
* but it's "kind"
*/
message[message_len] = '\0';
language = (char *) data + 9 + message_len + 3;
if (language_len) {
memmove(language, language + 1, language_len);
}
language[language_len] = '\0';
if (session->ssh_msg_disconnect) {
LIBSSH2_DISCONNECT(session, reason, message,
message_len, language, language_len);
}
_libssh2_debug(session, LIBSSH2_TRACE_TRANS,
"Disconnect(%d): %s(%s)", reason,
message, language);
LIBSSH2_FREE(session, data);
session->socket_state = LIBSSH2_SOCKET_DISCONNECTED;
session->packAdd_state = libssh2_NB_state_idle;
return libssh2_error(session, LIBSSH2_ERROR_SOCKET_DISCONNECT,
"socket disconnect");
reason = _libssh2_ntohu32(data + 1);
message_len = _libssh2_ntohu32(data + 5);
/* 9 = packet_type(1) + reason(4) + message_len(4) */
message = (char *) data + 9;
language_len = _libssh2_ntohu32(data + 9 + message_len);
/*
* This is where we hack on the data a little,
* Use the MSB of language_len to to a terminating NULL
* (In all liklihood it is already)
* Shift the language tag back a byte (In all likelihood
* it's zero length anyway)
* Store a NULL in the last byte of the packet to terminate
* the language string
* With the lengths passed this isn't *REALLY* necessary,
* but it's "kind"
*/
message[message_len] = '\0';
language = (char *) data + 9 + message_len + 3;
if (language_len) {
memmove(language, language + 1, language_len);
}
break;
language[language_len] = '\0';
if (session->ssh_msg_disconnect) {
LIBSSH2_DISCONNECT(session, reason, message,
message_len, language, language_len);
}
_libssh2_debug(session, LIBSSH2_TRACE_TRANS,
"Disconnect(%d): %s(%s)", reason,
message, language);
LIBSSH2_FREE(session, data);
session->socket_state = LIBSSH2_SOCKET_DISCONNECTED;
session->packAdd_state = libssh2_NB_state_idle;
return _libssh2_error(session, LIBSSH2_ERROR_SOCKET_DISCONNECT,
"socket disconnect");
}
break;
case SSH_MSG_IGNORE:
if (datalen >= 5) {
@@ -550,48 +532,48 @@ _libssh2_packet_add(LIBSSH2_SESSION * session, unsigned char *data,
return 0;
case SSH_MSG_DEBUG:
{
int always_display = data[0];
char *message, *language;
int message_len, language_len;
{
int always_display = data[0];
char *message, *language;
int message_len, language_len;
message_len = _libssh2_ntohu32(data + 2);
/* 6 = packet_type(1) + display(1) + message_len(4) */
message = (char *) data + 6;
language_len = _libssh2_ntohu32(data + 6 + message_len);
/*
* This is where we hack on the data a little,
* Use the MSB of language_len to to a terminating NULL
* (In all liklihood it is already)
* Shift the language tag back a byte (In all likelihood
* it's zero length anyway)
* Store a NULL in the last byte of the packet to terminate
* the language string
* With the lengths passed this isn't *REALLY* necessary,
* but it's "kind"
*/
message[message_len] = '\0';
language = (char *) data + 6 + message_len + 3;
if (language_len) {
memmove(language, language + 1, language_len);
}
language[language_len] = '\0';
if (session->ssh_msg_debug) {
LIBSSH2_DEBUG(session, always_display, message,
message_len, language, language_len);
}
/*
* _libssh2_debug will actually truncate this for us so
* that it's not an inordinate about of data
*/
_libssh2_debug(session, LIBSSH2_TRACE_TRANS,
"Debug Packet: %s", message);
LIBSSH2_FREE(session, data);
session->packAdd_state = libssh2_NB_state_idle;
return 0;
message_len = _libssh2_ntohu32(data + 2);
/* 6 = packet_type(1) + display(1) + message_len(4) */
message = (char *) data + 6;
language_len = _libssh2_ntohu32(data + 6 + message_len);
/*
* This is where we hack on the data a little,
* Use the MSB of language_len to to a terminating NULL
* (In all liklihood it is already)
* Shift the language tag back a byte (In all likelihood
* it's zero length anyway)
* Store a NULL in the last byte of the packet to terminate
* the language string
* With the lengths passed this isn't *REALLY* necessary,
* but it's "kind"
*/
message[message_len] = '\0';
language = (char *) data + 6 + message_len + 3;
if (language_len) {
memmove(language, language + 1, language_len);
}
break;
language[language_len] = '\0';
if (session->ssh_msg_debug) {
LIBSSH2_DEBUG(session, always_display, message,
message_len, language, language_len);
}
/*
* _libssh2_debug will actually truncate this for us so
* that it's not an inordinate about of data
*/
_libssh2_debug(session, LIBSSH2_TRACE_TRANS,
"Debug Packet: %s", message);
LIBSSH2_FREE(session, data);
session->packAdd_state = libssh2_NB_state_idle;
return 0;
}
break;
case SSH_MSG_GLOBAL_REQUEST:
{
@@ -608,7 +590,7 @@ _libssh2_packet_add(LIBSSH2_SESSION * session, unsigned char *data,
session->packAdd_state = libssh2_NB_state_jump5;
data[0] = SSH_MSG_REQUEST_FAILURE;
rc = _libssh2_transport_write(session, data, 1);
if (rc == PACKET_EAGAIN)
if (rc == LIBSSH2_ERROR_EAGAIN)
return rc;
LIBSSH2_FREE(session, data);
session->packAdd_state = libssh2_NB_state_idle;
@@ -628,8 +610,8 @@ _libssh2_packet_add(LIBSSH2_SESSION * session, unsigned char *data,
_libssh2_channel_locate(session, _libssh2_ntohu32(data + 1));
if (!session->packAdd_channel) {
libssh2_error(session, LIBSSH2_ERROR_CHANNEL_UNKNOWN,
"Packet received for unknown channel, ignoring");
_libssh2_error(session, LIBSSH2_ERROR_CHANNEL_UNKNOWN,
"Packet received for unknown channel, ignoring");
LIBSSH2_FREE(session, data);
session->packAdd_state = libssh2_NB_state_idle;
return 0;
@@ -665,7 +647,7 @@ _libssh2_packet_add(LIBSSH2_SESSION * session, unsigned char *data,
packAdd_channel,
datalen - 13,
0, NULL);
if (rc == PACKET_EAGAIN)
if (rc == LIBSSH2_ERROR_EAGAIN)
return rc;
session->packAdd_state = libssh2_NB_state_idle;
@@ -682,10 +664,10 @@ _libssh2_packet_add(LIBSSH2_SESSION * session, unsigned char *data,
* Spec says we MAY ignore bytes sent beyond
* packet_size
*/
libssh2_error(session,
LIBSSH2_ERROR_CHANNEL_PACKET_EXCEEDED,
"Packet contains more data than we offered"
" to receive, truncating");
_libssh2_error(session,
LIBSSH2_ERROR_CHANNEL_PACKET_EXCEEDED,
"Packet contains more data than we offered"
" to receive, truncating");
datalen =
session->packAdd_channel->remote.packet_size +
session->packAdd_data_head;
@@ -695,10 +677,10 @@ _libssh2_packet_add(LIBSSH2_SESSION * session, unsigned char *data,
* Spec says we MAY ignore bytes sent beyond
* window_size
*/
libssh2_error(session,
LIBSSH2_ERROR_CHANNEL_WINDOW_EXCEEDED,
"The current receive window is full,"
" data ignored");
_libssh2_error(session,
LIBSSH2_ERROR_CHANNEL_WINDOW_EXCEEDED,
"The current receive window is full,"
" data ignored");
LIBSSH2_FREE(session, data);
session->packAdd_state = libssh2_NB_state_idle;
return 0;
@@ -708,10 +690,10 @@ _libssh2_packet_add(LIBSSH2_SESSION * session, unsigned char *data,
if ((datalen - session->packAdd_data_head) >
session->packAdd_channel->remote.window_size) {
libssh2_error(session,
LIBSSH2_ERROR_CHANNEL_WINDOW_EXCEEDED,
"Remote sent more data than current "
"window allows, truncating");
_libssh2_error(session,
LIBSSH2_ERROR_CHANNEL_WINDOW_EXCEEDED,
"Remote sent more data than current "
"window allows, truncating");
datalen =
session->packAdd_channel->remote.window_size +
session->packAdd_data_head;
@@ -785,14 +767,14 @@ _libssh2_packet_add(LIBSSH2_SESSION * session, unsigned char *data,
session->packAdd_state = libssh2_NB_state_jump4;
data[0] = SSH_MSG_CHANNEL_FAILURE;
rc = _libssh2_transport_write(session, data, 5);
if (rc == PACKET_EAGAIN)
if (rc == LIBSSH2_ERROR_EAGAIN)
return rc;
LIBSSH2_FREE(session, data);
session->packAdd_state = libssh2_NB_state_idle;
return 0;
}
break;
}
}
case SSH_MSG_CHANNEL_CLOSE:
session->packAdd_channel =
@@ -827,7 +809,7 @@ _libssh2_packet_add(LIBSSH2_SESSION * session, unsigned char *data,
session->packAdd_state = libssh2_NB_state_jump2;
rc = packet_queue_listener(session, data, datalen,
&session->packAdd_Qlstn_state);
if (rc == PACKET_EAGAIN)
if (rc == LIBSSH2_ERROR_EAGAIN)
return rc;
LIBSSH2_FREE(session, data);
@@ -842,7 +824,7 @@ _libssh2_packet_add(LIBSSH2_SESSION * session, unsigned char *data,
session->packAdd_state = libssh2_NB_state_jump3;
rc = packet_x11_open(session, data, datalen,
&session->packAdd_x11open_state);
if (rc == PACKET_EAGAIN)
if (rc == LIBSSH2_ERROR_EAGAIN)
return rc;
LIBSSH2_FREE(session, data);
@@ -852,31 +834,31 @@ _libssh2_packet_add(LIBSSH2_SESSION * session, unsigned char *data,
break;
case SSH_MSG_CHANNEL_WINDOW_ADJUST:
{
unsigned long bytestoadd = _libssh2_ntohu32(data + 5);
session->packAdd_channel =
_libssh2_channel_locate(session,
_libssh2_ntohu32(data + 1));
{
unsigned long bytestoadd = _libssh2_ntohu32(data + 5);
session->packAdd_channel =
_libssh2_channel_locate(session,
_libssh2_ntohu32(data + 1));
if (session->packAdd_channel && bytestoadd) {
session->packAdd_channel->local.window_size += bytestoadd;
}
if(session->packAdd_channel)
_libssh2_debug(session, LIBSSH2_TRACE_CONN,
"Window adjust received for channel %lu/%lu, adding %lu bytes, new window_size=%lu",
session->packAdd_channel->local.id,
session->packAdd_channel->remote.id,
bytestoadd,
session->packAdd_channel->local.window_size);
else
_libssh2_debug(session, LIBSSH2_TRACE_CONN,
"Window adjust for non-existing channel!");
LIBSSH2_FREE(session, data);
session->packAdd_state = libssh2_NB_state_idle;
return 0;
if (session->packAdd_channel && bytestoadd) {
session->packAdd_channel->local.window_size += bytestoadd;
}
break;
if(session->packAdd_channel)
_libssh2_debug(session, LIBSSH2_TRACE_CONN,
"Window adjust received for channel %lu/%lu, adding %lu bytes, new window_size=%lu",
session->packAdd_channel->local.id,
session->packAdd_channel->remote.id,
bytestoadd,
session->packAdd_channel->local.window_size);
else
_libssh2_debug(session, LIBSSH2_TRACE_CONN,
"Window adjust for non-existing channel!");
LIBSSH2_FREE(session, data);
session->packAdd_state = libssh2_NB_state_idle;
return 0;
}
break;
}
session->packAdd_state = libssh2_NB_state_sent;
@@ -885,7 +867,7 @@ _libssh2_packet_add(LIBSSH2_SESSION * session, unsigned char *data,
if (session->packAdd_state == libssh2_NB_state_sent) {
LIBSSH2_PACKET *packAdd_packet;
packAdd_packet =
LIBSSH2_ALLOC(session, sizeof(LIBSSH2_PACKET));
LIBSSH2_ALLOC(session, sizeof(LIBSSH2_PACKET));
if (!packAdd_packet) {
_libssh2_debug(session, LIBSSH2_ERROR_ALLOC,
"Unable to allocate memory for LIBSSH2_PACKET");
@@ -920,7 +902,7 @@ _libssh2_packet_add(LIBSSH2_SESSION * session, unsigned char *data,
/*
* The KEXINIT message has been added to the queue. The packAdd and
* readPack states need to be reset because libssh2_kex_exchange
* readPack states need to be reset because _libssh2_kex_exchange
* (eventually) calls upon _libssh2_transport_read to read the rest of
* the key exchange conversation.
*/
@@ -940,10 +922,9 @@ _libssh2_packet_add(LIBSSH2_SESSION * session, unsigned char *data,
* If there was a key reexchange failure, let's just hope we didn't
* send NEWKEYS yet, otherwise remote will drop us like a rock
*/
rc = libssh2_kex_exchange(session, 1, &session->startup_key_state);
if (rc == PACKET_EAGAIN) {
rc = _libssh2_kex_exchange(session, 1, &session->startup_key_state);
if (rc == LIBSSH2_ERROR_EAGAIN)
return rc;
}
}
session->packAdd_state = libssh2_NB_state_idle;
@@ -958,9 +939,9 @@ _libssh2_packet_add(LIBSSH2_SESSION * session, unsigned char *data,
*/
int
_libssh2_packet_ask(LIBSSH2_SESSION * session, unsigned char packet_type,
unsigned char **data, unsigned long *data_len,
unsigned long match_ofs, const unsigned char *match_buf,
unsigned long match_len)
unsigned char **data, size_t *data_len,
int match_ofs, const unsigned char *match_buf,
size_t match_len)
{
LIBSSH2_PACKET *packet = _libssh2_list_first(&session->packets);
@@ -997,10 +978,10 @@ _libssh2_packet_ask(LIBSSH2_SESSION * session, unsigned char packet_type,
int
_libssh2_packet_askv(LIBSSH2_SESSION * session,
const unsigned char *packet_types,
unsigned char **data, unsigned long *data_len,
unsigned long match_ofs,
unsigned char **data, size_t *data_len,
int match_ofs,
const unsigned char *match_buf,
unsigned long match_len)
size_t match_len)
{
int i, packet_types_len = strlen((char *) packet_types);
@@ -1026,16 +1007,16 @@ _libssh2_packet_askv(LIBSSH2_SESSION * session,
*/
int
_libssh2_packet_require(LIBSSH2_SESSION * session, unsigned char packet_type,
unsigned char **data, unsigned long *data_len,
unsigned long match_ofs,
unsigned char **data, size_t *data_len,
int match_ofs,
const unsigned char *match_buf,
unsigned long match_len,
size_t match_len,
packet_require_state_t *state)
{
if (state->start == 0) {
if (_libssh2_packet_ask(session, packet_type, data, data_len,
match_ofs, match_buf,
match_len) == 0) {
match_ofs, match_buf,
match_len) == 0) {
/* A packet was available in the packet brigade */
return 0;
}
@@ -1045,7 +1026,7 @@ _libssh2_packet_require(LIBSSH2_SESSION * session, unsigned char packet_type,
while (session->socket_state == LIBSSH2_SOCKET_CONNECTED) {
int ret = _libssh2_transport_read(session);
if (ret == PACKET_EAGAIN)
if (ret == LIBSSH2_ERROR_EAGAIN)
return ret;
else if (ret < 0) {
state->start = 0;
@@ -1054,7 +1035,7 @@ _libssh2_packet_require(LIBSSH2_SESSION * session, unsigned char packet_type,
} else if (ret == packet_type) {
/* Be lazy, let packet_ask pull it out of the brigade */
ret = _libssh2_packet_ask(session, packet_type, data, data_len,
match_ofs, match_buf, match_len);
match_ofs, match_buf, match_len);
state->start = 0;
return ret;
} else if (ret == 0) {
@@ -1063,7 +1044,7 @@ _libssh2_packet_require(LIBSSH2_SESSION * session, unsigned char packet_type,
if (left <= 0) {
state->start = 0;
return PACKET_TIMEOUT;
return LIBSSH2_ERROR_TIMEOUT;
}
return -1; /* no packet available yet */
}
@@ -1085,7 +1066,7 @@ _libssh2_packet_burn(LIBSSH2_SESSION * session,
libssh2_nonblocking_states * state)
{
unsigned char *data;
unsigned long data_len;
size_t data_len;
unsigned char all_packets[255];
int i;
int ret;
@@ -1110,7 +1091,7 @@ _libssh2_packet_burn(LIBSSH2_SESSION * session,
while (session->socket_state == LIBSSH2_SOCKET_CONNECTED) {
ret = _libssh2_transport_read(session);
if (ret == PACKET_EAGAIN) {
if (ret == LIBSSH2_ERROR_EAGAIN) {
return ret;
} else if (ret < 0) {
*state = libssh2_NB_state_idle;
@@ -1143,12 +1124,11 @@ _libssh2_packet_burn(LIBSSH2_SESSION * session,
*/
int
_libssh2_packet_requirev(LIBSSH2_SESSION * session,
_libssh2_packet_requirev(LIBSSH2_SESSION *session,
const unsigned char *packet_types,
unsigned char **data, unsigned long *data_len,
unsigned long match_ofs,
const unsigned char *match_buf,
unsigned long match_len,
unsigned char **data, size_t *data_len,
int match_ofs,
const unsigned char *match_buf, size_t match_len,
packet_requirev_state_t * state)
{
if (_libssh2_packet_askv(session, packet_types, data, data_len, match_ofs,
@@ -1164,7 +1144,7 @@ _libssh2_packet_requirev(LIBSSH2_SESSION * session,
while (session->socket_state != LIBSSH2_SOCKET_DISCONNECTED) {
int ret = _libssh2_transport_read(session);
if ((ret < 0) && (ret != PACKET_EAGAIN)) {
if ((ret < 0) && (ret != LIBSSH2_ERROR_EAGAIN)) {
state->start = 0;
return ret;
}
@@ -1174,9 +1154,9 @@ _libssh2_packet_requirev(LIBSSH2_SESSION * session,
if (left <= 0) {
state->start = 0;
return PACKET_TIMEOUT;
return LIBSSH2_ERROR_TIMEOUT;
}
else if (ret == PACKET_EAGAIN) {
else if (ret == LIBSSH2_ERROR_EAGAIN) {
return ret;
}
}

76
src/packet.h Normal file
View File

@@ -0,0 +1,76 @@
#ifndef LIBSSH2_PACKET_H
#define LIBSSH2_PACKET_H
/*
* Copyright (C) 2010 by Daniel Stenberg
* Author: Daniel Stenberg <daniel@haxx.se>
*
* Redistribution and use in source and binary forms,
* with or without modification, are permitted provided
* that the following conditions are met:
*
* Redistributions of source code must retain the above
* copyright notice, this list of conditions and the
* following disclaimer.
*
* Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following
* disclaimer in the documentation and/or other materials
* provided with the distribution.
*
* Neither the name of the copyright holder nor the names
* of any other contributors may be used to endorse or
* promote products derived from this software without
* specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
* CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
* USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
* OF SUCH DAMAGE.
*
*/
int _libssh2_packet_read(LIBSSH2_SESSION * session);
int _libssh2_packet_ask(LIBSSH2_SESSION * session, unsigned char packet_type,
unsigned char **data, size_t *data_len,
int match_ofs,
const unsigned char *match_buf,
size_t match_len);
int _libssh2_packet_askv(LIBSSH2_SESSION * session,
const unsigned char *packet_types,
unsigned char **data, size_t *data_len,
int match_ofs,
const unsigned char *match_buf,
size_t match_len);
int _libssh2_packet_require(LIBSSH2_SESSION * session,
unsigned char packet_type, unsigned char **data,
size_t *data_len, int match_ofs,
const unsigned char *match_buf,
size_t match_len,
packet_require_state_t * state);
int _libssh2_packet_requirev(LIBSSH2_SESSION *session,
const unsigned char *packet_types,
unsigned char **data, size_t *data_len,
int match_ofs,
const unsigned char *match_buf,
size_t match_len,
packet_requirev_state_t * state);
int _libssh2_packet_burn(LIBSSH2_SESSION * session,
libssh2_nonblocking_states * state);
int _libssh2_packet_write(LIBSSH2_SESSION * session, unsigned char *data,
unsigned long data_len);
int _libssh2_packet_add(LIBSSH2_SESSION * session, unsigned char *data,
size_t datalen, int macstate);
#endif /* LIBSSH2_PACKET_H */

View File

@@ -1,4 +1,5 @@
/* Copyright (c) 2004-2007, Sara Golemon <sarag@libssh2.org>
* Copyright (c) 2010 by Daniel Stenberg
* All rights reserved.
*
* Redistribution and use in source and binary forms,
@@ -38,6 +39,7 @@
#include "libssh2_priv.h"
#include "libssh2_publickey.h"
#include "channel.h"
#include "session.h"
#define LIBSSH2_PUBLICKEY_VERSION 2
@@ -118,7 +120,7 @@ publickey_status_error(const LIBSSH2_PUBLICKEY *pkey,
msg = publickey_status_codes[status].name;
}
libssh2_error(session, LIBSSH2_ERROR_PUBLICKEY_PROTOCOL, msg);
_libssh2_error(session, LIBSSH2_ERROR_PUBLICKEY_PROTOCOL, msg);
}
/*
@@ -128,7 +130,7 @@ publickey_status_error(const LIBSSH2_PUBLICKEY *pkey,
*/
static int
publickey_packet_receive(LIBSSH2_PUBLICKEY * pkey,
unsigned char **data, unsigned long *data_len)
unsigned char **data, size_t *data_len)
{
LIBSSH2_CHANNEL *channel = pkey->channel;
LIBSSH2_SESSION *session = channel->session;
@@ -137,20 +139,20 @@ publickey_packet_receive(LIBSSH2_PUBLICKEY * pkey,
if (pkey->receive_state == libssh2_NB_state_idle) {
rc = _libssh2_channel_read(channel, 0, (char *) buffer, 4);
if (rc == PACKET_EAGAIN) {
if (rc == LIBSSH2_ERROR_EAGAIN) {
return rc;
} else if (rc != 4) {
return libssh2_error(session, LIBSSH2_ERROR_PUBLICKEY_PROTOCOL,
"Invalid response from publickey subsystem");
return _libssh2_error(session, LIBSSH2_ERROR_PUBLICKEY_PROTOCOL,
"Invalid response from publickey subsystem");
}
pkey->receive_packet_len = _libssh2_ntohu32(buffer);
pkey->receive_packet =
LIBSSH2_ALLOC(session, pkey->receive_packet_len);
if (!pkey->receive_packet) {
return libssh2_error(session, LIBSSH2_ERROR_ALLOC,
"Unable to allocate publickey response "
"buffer");
return _libssh2_error(session, LIBSSH2_ERROR_ALLOC,
"Unable to allocate publickey response "
"buffer");
}
pkey->receive_state = libssh2_NB_state_sent;
@@ -159,15 +161,15 @@ publickey_packet_receive(LIBSSH2_PUBLICKEY * pkey,
if (pkey->receive_state == libssh2_NB_state_sent) {
rc = _libssh2_channel_read(channel, 0, (char *) pkey->receive_packet,
pkey->receive_packet_len);
if (rc == PACKET_EAGAIN) {
if (rc == LIBSSH2_ERROR_EAGAIN) {
return rc;
} else if (rc != (int)pkey->receive_packet_len) {
LIBSSH2_FREE(session, pkey->receive_packet);
pkey->receive_packet = NULL;
pkey->receive_state = libssh2_NB_state_idle;
return libssh2_error(session, LIBSSH2_ERROR_SOCKET_TIMEOUT,
"Timeout waiting for publickey subsystem "
"response packet");
return _libssh2_error(session, LIBSSH2_ERROR_SOCKET_TIMEOUT,
"Timeout waiting for publickey subsystem "
"response packet");
}
*data = pkey->receive_packet;
@@ -185,9 +187,9 @@ publickey_packet_receive(LIBSSH2_PUBLICKEY * pkey,
* Data will be incremented by 4 + response_len on success only
*/
static int
publickey_response_id(unsigned char **pdata, int data_len)
publickey_response_id(unsigned char **pdata, size_t data_len)
{
unsigned long response_len;
size_t response_len;
unsigned char *data = *pdata;
const LIBSSH2_PUBLICKEY_CODE_LIST *codes = publickey_response_codes;
@@ -198,7 +200,7 @@ publickey_response_id(unsigned char **pdata, int data_len)
response_len = _libssh2_ntohu32(data);
data += 4;
data_len -= 4;
if (data_len < (int)response_len) {
if (data_len < response_len) {
/* Malformed response */
return -1;
}
@@ -215,7 +217,7 @@ publickey_response_id(unsigned char **pdata, int data_len)
return -1;
}
/* libssh2_publickey_response_success
/* publickey_response_success
*
* Generic helper routine to wait for success response and nothing else
*/
@@ -224,46 +226,45 @@ publickey_response_success(LIBSSH2_PUBLICKEY * pkey)
{
LIBSSH2_SESSION *session = pkey->channel->session;
unsigned char *data, *s;
unsigned long data_len;
size_t data_len;
int response;
int rc;
while (1) {
rc = publickey_packet_receive(pkey, &data, &data_len);
if (rc == PACKET_EAGAIN) {
int rc = publickey_packet_receive(pkey, &data, &data_len);
if (rc == LIBSSH2_ERROR_EAGAIN) {
return rc;
} else if (rc) {
return libssh2_error(session, LIBSSH2_ERROR_SOCKET_TIMEOUT,
"Timeout waiting for response from "
"publickey subsystem");
return _libssh2_error(session, LIBSSH2_ERROR_SOCKET_TIMEOUT,
"Timeout waiting for response from "
"publickey subsystem");
}
s = data;
if ((response = publickey_response_id(&s, data_len)) < 0) {
LIBSSH2_FREE(session, data);
return libssh2_error(session, LIBSSH2_ERROR_PUBLICKEY_PROTOCOL,
"Invalid publickey subsystem response code");
}
response = publickey_response_id(&s, data_len);
switch (response) {
case LIBSSH2_PUBLICKEY_RESPONSE_STATUS:
/* Error, or processing complete */
{
unsigned long status = _libssh2_ntohu32(s);
{
unsigned long status = _libssh2_ntohu32(s);
LIBSSH2_FREE(session, data);
if (status == LIBSSH2_PUBLICKEY_SUCCESS)
return 0;
publickey_status_error(pkey, session, status);
return -1;
}
default:
/* Unknown/Unexpected */
libssh2_error(session, LIBSSH2_ERROR_PUBLICKEY_PROTOCOL,
"Unexpected publickey subsystem response, ignoring");
LIBSSH2_FREE(session, data);
if (status == LIBSSH2_PUBLICKEY_SUCCESS)
return 0;
publickey_status_error(pkey, session, status);
return -1;
}
default:
LIBSSH2_FREE(session, data);
if (response < 0) {
return _libssh2_error(session, LIBSSH2_ERROR_PUBLICKEY_PROTOCOL,
"Invalid publickey subsystem response code");
}
/* Unknown/Unexpected */
_libssh2_error(session, LIBSSH2_ERROR_PUBLICKEY_PROTOCOL,
"Unexpected publickey subsystem response, ignoring");
data = NULL;
}
}
@@ -272,20 +273,16 @@ publickey_response_success(LIBSSH2_PUBLICKEY * pkey)
}
/* *****************
* Publickey API *
***************** */
* Publickey API *
***************** */
/*
* libssh2_publickey_init
* publickey_init
*
* Startup the publickey subsystem
*/
LIBSSH2_API LIBSSH2_PUBLICKEY *
libssh2_publickey_init(LIBSSH2_SESSION * session)
static LIBSSH2_PUBLICKEY *publickey_init(LIBSSH2_SESSION *session)
{
/* 19 = packet_len(4) + version_len(4) + "version"(7) + version_num(4) */
unsigned char buffer[19];
unsigned char *s;
int response;
int rc;
@@ -301,44 +298,37 @@ libssh2_publickey_init(LIBSSH2_SESSION * session)
}
if (session->pkeyInit_state == libssh2_NB_state_allocated) {
do {
session->pkeyInit_channel =
libssh2_channel_open_ex(session, "session",
sizeof("session") - 1,
LIBSSH2_CHANNEL_WINDOW_DEFAULT,
LIBSSH2_CHANNEL_PACKET_DEFAULT, NULL,
0);
if (!session->pkeyInit_channel
&& (libssh2_session_last_errno(session) ==
LIBSSH2_ERROR_EAGAIN)) {
session->pkeyInit_channel =
_libssh2_channel_open(session, "session",
sizeof("session") - 1,
LIBSSH2_CHANNEL_WINDOW_DEFAULT,
LIBSSH2_CHANNEL_PACKET_DEFAULT, NULL,
0);
if (!session->pkeyInit_channel) {
if (libssh2_session_last_errno(session) == LIBSSH2_ERROR_EAGAIN)
/* The error state is already set, so leave it */
libssh2_error(session, LIBSSH2_ERROR_EAGAIN,
"Would block to startup channel");
return NULL;
} else if (!session->pkeyInit_channel
&& (libssh2_session_last_errno(session) !=
LIBSSH2_ERROR_EAGAIN)) {
libssh2_error(session, LIBSSH2_ERROR_CHANNEL_FAILURE,
"Unable to startup channel");
goto err_exit;
}
} while (!session->pkeyInit_channel);
_libssh2_error(session, LIBSSH2_ERROR_CHANNEL_FAILURE,
"Unable to startup channel");
goto err_exit;
}
session->pkeyInit_state = libssh2_NB_state_sent;
}
if (session->pkeyInit_state == libssh2_NB_state_sent) {
rc = libssh2_channel_process_startup(session->pkeyInit_channel,
"subsystem",
sizeof("subsystem") - 1,
"publickey", strlen("publickey"));
if (rc == PACKET_EAGAIN) {
libssh2_error(session, LIBSSH2_ERROR_EAGAIN,
"Would block starting publickey subsystem");
rc = _libssh2_channel_process_startup(session->pkeyInit_channel,
"subsystem",
sizeof("subsystem") - 1,
"publickey", strlen("publickey"));
if (rc == LIBSSH2_ERROR_EAGAIN) {
_libssh2_error(session, LIBSSH2_ERROR_EAGAIN,
"Would block starting publickey subsystem");
return NULL;
} else if (rc) {
libssh2_error(session, LIBSSH2_ERROR_CHANNEL_FAILURE,
"Unable to request publickey subsystem");
_libssh2_error(session, LIBSSH2_ERROR_CHANNEL_FAILURE,
"Unable to request publickey subsystem");
goto err_exit;
}
@@ -346,26 +336,27 @@ libssh2_publickey_init(LIBSSH2_SESSION * session)
}
if (session->pkeyInit_state == libssh2_NB_state_sent1) {
rc = libssh2_channel_handle_extended_data2(session->pkeyInit_channel,
LIBSSH2_CHANNEL_EXTENDED_DATA_IGNORE);
if (rc == PACKET_EAGAIN) {
libssh2_error(session, LIBSSH2_ERROR_EAGAIN,
"Would block starting publickey subsystem");
unsigned char *s;
rc = _libssh2_channel_extended_data(session->pkeyInit_channel,
LIBSSH2_CHANNEL_EXTENDED_DATA_IGNORE);
if (rc == LIBSSH2_ERROR_EAGAIN) {
_libssh2_error(session, LIBSSH2_ERROR_EAGAIN,
"Would block starting publickey subsystem");
return NULL;
}
session->pkeyInit_pkey =
LIBSSH2_ALLOC(session, sizeof(LIBSSH2_PUBLICKEY));
if (!session->pkeyInit_pkey) {
libssh2_error(session, LIBSSH2_ERROR_ALLOC,
"Unable to allocate a new publickey structure");
_libssh2_error(session, LIBSSH2_ERROR_ALLOC,
"Unable to allocate a new publickey structure");
goto err_exit;
}
memset(session->pkeyInit_pkey, 0, sizeof(LIBSSH2_PUBLICKEY));
session->pkeyInit_pkey->channel = session->pkeyInit_channel;
session->pkeyInit_pkey->version = 0;
s = buffer;
s = session->pkeyInit_buffer;
_libssh2_htonu32(s, 4 + (sizeof("version") - 1) + 4);
s += 4;
_libssh2_htonu32(s, sizeof("version") - 1);
@@ -373,7 +364,8 @@ libssh2_publickey_init(LIBSSH2_SESSION * session)
memcpy(s, "version", sizeof("version") - 1);
s += sizeof("version") - 1;
_libssh2_htonu32(s, LIBSSH2_PUBLICKEY_VERSION);
s += 4;
session->pkeyInit_buffer_sent = 0;
_libssh2_debug(session, LIBSSH2_TRACE_PUBLICKEY,
"Sending publickey version packet advertising version %d support",
@@ -384,76 +376,83 @@ libssh2_publickey_init(LIBSSH2_SESSION * session)
if (session->pkeyInit_state == libssh2_NB_state_sent2) {
rc = _libssh2_channel_write(session->pkeyInit_channel, 0,
(char *) buffer, (s - buffer));
if (rc == PACKET_EAGAIN) {
libssh2_error(session, LIBSSH2_ERROR_EAGAIN,
"Would block sending publickey version packet");
(char *)session->pkeyInit_buffer,
19 - session->pkeyInit_buffer_sent);
if (rc == LIBSSH2_ERROR_EAGAIN) {
_libssh2_error(session, LIBSSH2_ERROR_EAGAIN,
"Would block sending publickey version packet");
return NULL;
} else if ((s - buffer) != rc) {
libssh2_error(session, LIBSSH2_ERROR_SOCKET_SEND,
"Unable to send publickey version packet");
} else if (rc) {
_libssh2_error(session, rc,
"Unable to send publickey version packet");
goto err_exit;
}
session->pkeyInit_buffer_sent += rc;
if(session->pkeyInit_buffer_sent < 19) {
_libssh2_error(session, LIBSSH2_ERROR_EAGAIN,
"Need to be called again to complete this");
return NULL;
}
session->pkeyInit_state = libssh2_NB_state_sent3;
}
if (session->pkeyInit_state == libssh2_NB_state_sent3) {
while (1) {
unsigned char *s;
rc = publickey_packet_receive(session->pkeyInit_pkey,
&session->pkeyInit_data,
&session->pkeyInit_data_len);
if (rc == PACKET_EAGAIN) {
libssh2_error(session, LIBSSH2_ERROR_EAGAIN,
"Would block waiting for response from "
"publickey subsystem");
if (rc == LIBSSH2_ERROR_EAGAIN) {
_libssh2_error(session, LIBSSH2_ERROR_EAGAIN,
"Would block waiting for response from "
"publickey subsystem");
return NULL;
} else if (rc) {
libssh2_error(session, LIBSSH2_ERROR_SOCKET_TIMEOUT,
"Timeout waiting for response from "
"publickey subsystem");
_libssh2_error(session, LIBSSH2_ERROR_SOCKET_TIMEOUT,
"Timeout waiting for response from "
"publickey subsystem");
goto err_exit;
}
s = session->pkeyInit_data;
if ((response =
publickey_response_id(&s, session->pkeyInit_data_len)) < 0) {
libssh2_error(session, LIBSSH2_ERROR_PUBLICKEY_PROTOCOL,
"Invalid publickey subsystem response code");
_libssh2_error(session, LIBSSH2_ERROR_PUBLICKEY_PROTOCOL,
"Invalid publickey subsystem response code");
goto err_exit;
}
switch (response) {
case LIBSSH2_PUBLICKEY_RESPONSE_STATUS:
/* Error */
{
unsigned long status, descr_len, lang_len;
unsigned char *descr, *lang;
{
unsigned long status, descr_len, lang_len;
status = _libssh2_ntohu32(s);
s += 4;
descr_len = _libssh2_ntohu32(s);
s += 4;
descr = s;
s += descr_len;
lang_len = _libssh2_ntohu32(s);
s += 4;
lang = s;
s += lang_len;
if (s >
session->pkeyInit_data + session->pkeyInit_data_len) {
libssh2_error(session,
LIBSSH2_ERROR_PUBLICKEY_PROTOCOL,
"Malformed publickey subsystem packet");
goto err_exit;
}
publickey_status_error(NULL, session, status);
status = _libssh2_ntohu32(s);
s += 4;
descr_len = _libssh2_ntohu32(s);
s += 4;
/* description starts here */
s += descr_len;
lang_len = _libssh2_ntohu32(s);
s += 4;
/* lang starts here */
s += lang_len;
if (s >
session->pkeyInit_data + session->pkeyInit_data_len) {
_libssh2_error(session,
LIBSSH2_ERROR_PUBLICKEY_PROTOCOL,
"Malformed publickey subsystem packet");
goto err_exit;
}
publickey_status_error(NULL, session, status);
goto err_exit;
}
case LIBSSH2_PUBLICKEY_RESPONSE_VERSION:
/* What we want */
session->pkeyInit_pkey->version = _libssh2_ntohu32(s);
@@ -475,9 +474,9 @@ libssh2_publickey_init(LIBSSH2_SESSION * session)
default:
/* Unknown/Unexpected */
libssh2_error(session, LIBSSH2_ERROR_PUBLICKEY_PROTOCOL,
"Unexpected publickey subsystem response, "
"ignoring");
_libssh2_error(session, LIBSSH2_ERROR_PUBLICKEY_PROTOCOL,
"Unexpected publickey subsystem response, "
"ignoring");
LIBSSH2_FREE(session, session->pkeyInit_data);
session->pkeyInit_data = NULL;
}
@@ -488,10 +487,10 @@ libssh2_publickey_init(LIBSSH2_SESSION * session)
err_exit:
session->pkeyInit_state = libssh2_NB_state_sent4;
if (session->pkeyInit_channel) {
rc = libssh2_channel_close(session->pkeyInit_channel);
if (rc == PACKET_EAGAIN) {
libssh2_error(session, LIBSSH2_ERROR_EAGAIN,
"Would block closing channel");
rc = _libssh2_channel_close(session->pkeyInit_channel);
if (rc == LIBSSH2_ERROR_EAGAIN) {
_libssh2_error(session, LIBSSH2_ERROR_EAGAIN,
"Would block closing channel");
return NULL;
}
}
@@ -507,6 +506,23 @@ libssh2_publickey_init(LIBSSH2_SESSION * session)
return NULL;
}
/*
* libssh2_publickey_init
*
* Startup the publickey subsystem
*/
LIBSSH2_API LIBSSH2_PUBLICKEY *
libssh2_publickey_init(LIBSSH2_SESSION *session)
{
LIBSSH2_PUBLICKEY *ptr;
BLOCK_ADJUST_ERRNO(ptr, session,
publickey_init(session));
return ptr;
}
/*
* libssh2_publickey_add_ex
*
@@ -555,9 +571,9 @@ libssh2_publickey_add_ex(LIBSSH2_PUBLICKEY * pkey, const unsigned char *name,
pkey->add_packet = LIBSSH2_ALLOC(session, packet_len);
if (!pkey->add_packet) {
return libssh2_error(session, LIBSSH2_ERROR_ALLOC,
"Unable to allocate memory for "
"publickey \"add\" packet");
return _libssh2_error(session, LIBSSH2_ERROR_ALLOC,
"Unable to allocate memory for "
"publickey \"add\" packet");
}
pkey->add_s = pkey->add_packet;
@@ -620,13 +636,13 @@ libssh2_publickey_add_ex(LIBSSH2_PUBLICKEY * pkey, const unsigned char *name,
if (pkey->add_state == libssh2_NB_state_created) {
rc = _libssh2_channel_write(channel, 0, (char *) pkey->add_packet,
(pkey->add_s - pkey->add_packet));
if (rc == PACKET_EAGAIN) {
if (rc == LIBSSH2_ERROR_EAGAIN) {
return rc;
} else if ((pkey->add_s - pkey->add_packet) != rc) {
LIBSSH2_FREE(session, pkey->add_packet);
pkey->add_packet = NULL;
return libssh2_error(session, LIBSSH2_ERROR_SOCKET_SEND,
"Unable to send publickey add packet");
return _libssh2_error(session, LIBSSH2_ERROR_SOCKET_SEND,
"Unable to send publickey add packet");
}
LIBSSH2_FREE(session, pkey->add_packet);
pkey->add_packet = NULL;
@@ -635,7 +651,7 @@ libssh2_publickey_add_ex(LIBSSH2_PUBLICKEY * pkey, const unsigned char *name,
}
rc = publickey_response_success(pkey);
if (rc == PACKET_EAGAIN) {
if (rc == LIBSSH2_ERROR_EAGAIN) {
return rc;
}
@@ -663,9 +679,9 @@ libssh2_publickey_remove_ex(LIBSSH2_PUBLICKEY * pkey,
pkey->remove_packet = LIBSSH2_ALLOC(session, packet_len);
if (!pkey->remove_packet) {
return libssh2_error(session, LIBSSH2_ERROR_ALLOC,
"Unable to allocate memory for "
"publickey \"remove\" packet");
return _libssh2_error(session, LIBSSH2_ERROR_ALLOC,
"Unable to allocate memory for "
"publickey \"remove\" packet");
}
pkey->remove_s = pkey->remove_packet;
@@ -694,14 +710,14 @@ libssh2_publickey_remove_ex(LIBSSH2_PUBLICKEY * pkey,
if (pkey->remove_state == libssh2_NB_state_created) {
rc = _libssh2_channel_write(channel, 0, (char *) pkey->remove_packet,
(pkey->remove_s - pkey->remove_packet));
if (rc == PACKET_EAGAIN) {
if (rc == LIBSSH2_ERROR_EAGAIN) {
return rc;
} else if ((pkey->remove_s - pkey->remove_packet) != rc) {
LIBSSH2_FREE(session, pkey->remove_packet);
pkey->remove_packet = NULL;
pkey->remove_state = libssh2_NB_state_idle;
return libssh2_error(session, LIBSSH2_ERROR_SOCKET_SEND,
"Unable to send publickey remove packet");
return _libssh2_error(session, LIBSSH2_ERROR_SOCKET_SEND,
"Unable to send publickey remove packet");
}
LIBSSH2_FREE(session, pkey->remove_packet);
pkey->remove_packet = NULL;
@@ -710,7 +726,7 @@ libssh2_publickey_remove_ex(LIBSSH2_PUBLICKEY * pkey,
}
rc = publickey_response_success(pkey);
if (rc == PACKET_EAGAIN) {
if (rc == LIBSSH2_ERROR_EAGAIN) {
return rc;
}
@@ -756,12 +772,12 @@ libssh2_publickey_list_fetch(LIBSSH2_PUBLICKEY * pkey, unsigned long *num_keys,
(char *) pkey->listFetch_buffer,
(pkey->listFetch_s -
pkey->listFetch_buffer));
if (rc == PACKET_EAGAIN) {
if (rc == LIBSSH2_ERROR_EAGAIN) {
return rc;
} else if ((pkey->listFetch_s - pkey->listFetch_buffer) != rc) {
pkey->listFetch_state = libssh2_NB_state_idle;
return libssh2_error(session, LIBSSH2_ERROR_SOCKET_SEND,
"Unable to send publickey list packet");
return _libssh2_error(session, LIBSSH2_ERROR_SOCKET_SEND,
"Unable to send publickey list packet");
}
pkey->listFetch_state = libssh2_NB_state_sent;
@@ -770,12 +786,12 @@ libssh2_publickey_list_fetch(LIBSSH2_PUBLICKEY * pkey, unsigned long *num_keys,
while (1) {
rc = publickey_packet_receive(pkey, &pkey->listFetch_data,
&pkey->listFetch_data_len);
if (rc == PACKET_EAGAIN) {
if (rc == LIBSSH2_ERROR_EAGAIN) {
return rc;
} else if (rc) {
libssh2_error(session, LIBSSH2_ERROR_SOCKET_TIMEOUT,
"Timeout waiting for response from "
"publickey subsystem");
_libssh2_error(session, LIBSSH2_ERROR_SOCKET_TIMEOUT,
"Timeout waiting for response from "
"publickey subsystem");
goto err_exit;
}
@@ -783,48 +799,47 @@ libssh2_publickey_list_fetch(LIBSSH2_PUBLICKEY * pkey, unsigned long *num_keys,
if ((response =
publickey_response_id(&pkey->listFetch_s,
pkey->listFetch_data_len)) < 0) {
libssh2_error(session, LIBSSH2_ERROR_PUBLICKEY_PROTOCOL,
"Invalid publickey subsystem response code");
_libssh2_error(session, LIBSSH2_ERROR_PUBLICKEY_PROTOCOL,
"Invalid publickey subsystem response code");
goto err_exit;
}
switch (response) {
case LIBSSH2_PUBLICKEY_RESPONSE_STATUS:
/* Error, or processing complete */
{
unsigned long status, descr_len, lang_len;
unsigned char *descr, *lang;
{
unsigned long status, descr_len, lang_len;
status = _libssh2_ntohu32(pkey->listFetch_s);
pkey->listFetch_s += 4;
descr_len = _libssh2_ntohu32(pkey->listFetch_s);
pkey->listFetch_s += 4;
descr = pkey->listFetch_s;
pkey->listFetch_s += descr_len;
lang_len = _libssh2_ntohu32(pkey->listFetch_s);
pkey->listFetch_s += 4;
lang = pkey->listFetch_s;
pkey->listFetch_s += lang_len;
status = _libssh2_ntohu32(pkey->listFetch_s);
pkey->listFetch_s += 4;
descr_len = _libssh2_ntohu32(pkey->listFetch_s);
pkey->listFetch_s += 4;
/* description starts at pkey->listFetch_s */
pkey->listFetch_s += descr_len;
lang_len = _libssh2_ntohu32(pkey->listFetch_s);
pkey->listFetch_s += 4;
/* lang starts at pkey->listFetch_s */
pkey->listFetch_s += lang_len;
if (pkey->listFetch_s >
pkey->listFetch_data + pkey->listFetch_data_len) {
libssh2_error(session, LIBSSH2_ERROR_PUBLICKEY_PROTOCOL,
"Malformed publickey subsystem packet");
goto err_exit;
}
if (status == LIBSSH2_PUBLICKEY_SUCCESS) {
LIBSSH2_FREE(session, pkey->listFetch_data);
pkey->listFetch_data = NULL;
*pkey_list = list;
*num_keys = keys;
pkey->listFetch_state = libssh2_NB_state_idle;
return 0;
}
publickey_status_error(pkey, session, status);
if (pkey->listFetch_s >
pkey->listFetch_data + pkey->listFetch_data_len) {
_libssh2_error(session, LIBSSH2_ERROR_PUBLICKEY_PROTOCOL,
"Malformed publickey subsystem packet");
goto err_exit;
}
if (status == LIBSSH2_PUBLICKEY_SUCCESS) {
LIBSSH2_FREE(session, pkey->listFetch_data);
pkey->listFetch_data = NULL;
*pkey_list = list;
*num_keys = keys;
pkey->listFetch_state = libssh2_NB_state_idle;
return 0;
}
publickey_status_error(pkey, session, status);
goto err_exit;
}
case LIBSSH2_PUBLICKEY_RESPONSE_PUBLICKEY:
/* What we want */
if (keys >= max_keys) {
@@ -836,9 +851,9 @@ libssh2_publickey_list_fetch(LIBSSH2_PUBLICKEY * pkey, unsigned long *num_keys,
(max_keys +
1) * sizeof(libssh2_publickey_list));
if (!newlist) {
libssh2_error(session, LIBSSH2_ERROR_ALLOC,
"Unable to allocate memory for "
"publickey list");
_libssh2_error(session, LIBSSH2_ERROR_ALLOC,
"Unable to allocate memory for "
"publickey list");
goto err_exit;
}
list = newlist;
@@ -854,9 +869,9 @@ libssh2_publickey_list_fetch(LIBSSH2_PUBLICKEY * pkey, unsigned long *num_keys,
LIBSSH2_ALLOC(session,
sizeof(libssh2_publickey_attribute));
if (!list[keys].attrs) {
libssh2_error(session, LIBSSH2_ERROR_ALLOC,
"Unable to allocate memory for "
"publickey attributes");
_libssh2_error(session, LIBSSH2_ERROR_ALLOC,
"Unable to allocate memory for "
"publickey attributes");
goto err_exit;
}
list[keys].attrs[0].name = "comment";
@@ -896,9 +911,9 @@ libssh2_publickey_list_fetch(LIBSSH2_PUBLICKEY * pkey, unsigned long *num_keys,
list[keys].num_attrs *
sizeof(libssh2_publickey_attribute));
if (!list[keys].attrs) {
libssh2_error(session, LIBSSH2_ERROR_ALLOC,
"Unable to allocate memory for "
"publickey attributes");
_libssh2_error(session, LIBSSH2_ERROR_ALLOC,
"Unable to allocate memory for "
"publickey attributes");
goto err_exit;
}
for(i = 0; i < list[keys].num_attrs; i++) {
@@ -926,8 +941,8 @@ libssh2_publickey_list_fetch(LIBSSH2_PUBLICKEY * pkey, unsigned long *num_keys,
break;
default:
/* Unknown/Unexpected */
libssh2_error(session, LIBSSH2_ERROR_PUBLICKEY_PROTOCOL,
"Unexpected publickey subsystem response, ignoring");
_libssh2_error(session, LIBSSH2_ERROR_PUBLICKEY_PROTOCOL,
"Unexpected publickey subsystem response, ignoring");
LIBSSH2_FREE(session, pkey->listFetch_data);
pkey->listFetch_data = NULL;
}
@@ -996,8 +1011,8 @@ libssh2_publickey_shutdown(LIBSSH2_PUBLICKEY * pkey)
pkey->listFetch_data = NULL;
}
rc = libssh2_channel_free(pkey->channel);
if (rc == PACKET_EAGAIN)
rc = _libssh2_channel_free(pkey->channel);
if (rc == LIBSSH2_ERROR_EAGAIN)
return rc;
LIBSSH2_FREE(session, pkey);

459
src/scp.c
View File

@@ -1,4 +1,4 @@
/* Copyright (c) 2009 by Daniel Stenberg
/* Copyright (c) 2009-2010 by Daniel Stenberg
* Copyright (c) 2004-2008, Sara Golemon <sarag@libssh2.org>
* All rights reserved.
*
@@ -41,89 +41,90 @@
#include <stdlib.h>
#include "channel.h"
#include "session.h"
/* Max. length of a quoted string after libssh2_shell_quotearg() processing */
#define libssh2_shell_quotedsize(s) (3 * strlen(s) + 2)
#define _libssh2_shell_quotedsize(s) (3 * strlen(s) + 2)
/*
This function quotes a string in a way suitable to be used with a
shell, e.g. the file name
one two
becomes
'one two'
This function quotes a string in a way suitable to be used with a
shell, e.g. the file name
one two
becomes
'one two'
The resulting output string is crafted in a way that makes it usable
with the two most common shell types: Bourne Shell derived shells
(sh, ksh, ksh93, bash, zsh) and C-Shell derivates (csh, tcsh).
The resulting output string is crafted in a way that makes it usable
with the two most common shell types: Bourne Shell derived shells
(sh, ksh, ksh93, bash, zsh) and C-Shell derivates (csh, tcsh).
The following special cases are handled:
o If the string contains an apostrophy itself, the apostrophy
character is written in quotation marks, e.g. "'".
The shell cannot handle the syntax 'doesn\'t', so we close the
current argument word, add the apostrophe in quotation marks "",
and open a new argument word instead (_ indicate the input
string characters):
_____ _ _
'doesn' "'" 't'
The following special cases are handled:
o If the string contains an apostrophy itself, the apostrophy
character is written in quotation marks, e.g. "'".
The shell cannot handle the syntax 'doesn\'t', so we close the
current argument word, add the apostrophe in quotation marks "",
and open a new argument word instead (_ indicate the input
string characters):
_____ _ _
'doesn' "'" 't'
Sequences of apostrophes are combined in one pair of quotation marks:
a'''b
becomes
_ ___ _
'a'"'''"'b'
Sequences of apostrophes are combined in one pair of quotation marks:
a'''b
becomes
_ ___ _
'a'"'''"'b'
o If the string contains an exclamation mark (!), the C-Shell
interprets it as an event number. Using \! (not within quotation
marks or single quotation marks) is a mechanism understood by
both Bourne Shell and C-Shell.
o If the string contains an exclamation mark (!), the C-Shell
interprets it as an event number. Using \! (not within quotation
marks or single quotation marks) is a mechanism understood by
both Bourne Shell and C-Shell.
If a quotation was already started, the argument word is closed
first:
a!b
If a quotation was already started, the argument word is closed
first:
a!b
become
_ _ _
'a'\!'b'
become
_ _ _
'a'\!'b'
The result buffer must be large enough for the expanded result. A
bad case regarding expansion is alternating characters and
apostrophes:
The result buffer must be large enough for the expanded result. A
bad case regarding expansion is alternating characters and
apostrophes:
a'b'c'd' (length 8) gets converted to
'a'"'"'b'"'"'c'"'"'d'"'" (length 24)
a'b'c'd' (length 8) gets converted to
'a'"'"'b'"'"'c'"'"'d'"'" (length 24)
This is the worst case.
This is the worst case.
Maximum length of the result:
1 + 6 * (length(input) + 1) / 2) + 1
Maximum length of the result:
1 + 6 * (length(input) + 1) / 2) + 1
=> 3 * length(input) + 2
=> 3 * length(input) + 2
Explanation:
o leading apostrophe
o one character / apostrophe pair (two characters) can get
represented as 6 characters: a' -> a'"'"'
o String terminator (+1)
Explanation:
o leading apostrophe
o one character / apostrophe pair (two characters) can get
represented as 6 characters: a' -> a'"'"'
o String terminator (+1)
A result buffer three times the size of the input buffer + 2
characters should be safe.
A result buffer three times the size of the input buffer + 2
characters should be safe.
References:
o csh-compatible quotation (special handling for '!' etc.), see
http://www.grymoire.com/Unix/Csh.html#toc-uh-10
References:
o csh-compatible quotation (special handling for '!' etc.), see
http://www.grymoire.com/Unix/Csh.html#toc-uh-10
Return value:
Length of the resulting string (not counting the terminating '\0'),
or 0 in case of errors, e.g. result buffer too small
Return value:
Length of the resulting string (not counting the terminating '\0'),
or 0 in case of errors, e.g. result buffer too small
Note: this function could possible be used elsewhere within libssh2, but
until then it is kept static and in this source file.
Note: this function could possible be used elsewhere within libssh2, but
until then it is kept static and in this source file.
*/
static unsigned
libssh2_shell_quotearg(const char *path, unsigned char *buf,
unsigned bufsize)
shell_quotearg(const char *path, unsigned char *buf,
unsigned bufsize)
{
const char *src;
unsigned char *dst, *endp;
@@ -234,20 +235,20 @@ libssh2_shell_quotearg(const char *path, unsigned char *buf,
}
switch (state) {
case UQSTRING:
break;
case QSTRING: /* Close quoted string */
if (dst+1 >= endp)
return 0;
*dst++ = '"';
break;
case SQSTRING: /* Close single quoted string */
if (dst+1 >= endp)
return 0;
*dst++ = '\'';
break;
default:
break;
case UQSTRING:
break;
case QSTRING: /* Close quoted string */
if (dst+1 >= endp)
return 0;
*dst++ = '"';
break;
case SQSTRING: /* Close single quoted string */
if (dst+1 >= endp)
return 0;
*dst++ = '\'';
break;
default:
break;
}
if (dst+1 >= endp)
@@ -279,15 +280,15 @@ scp_recv(LIBSSH2_SESSION * session, const char *path, struct stat * sb)
session->scpRecv_atime = 0;
session->scpRecv_command_len =
libssh2_shell_quotedsize(path) + sizeof("scp -f ") + (sb?1:0);
_libssh2_shell_quotedsize(path) + sizeof("scp -f ") + (sb?1:0);
session->scpRecv_command =
LIBSSH2_ALLOC(session, session->scpRecv_command_len);
if (!session->scpRecv_command) {
libssh2_error(session, LIBSSH2_ERROR_ALLOC,
"Unable to allocate a command buffer for "
"SCP session");
_libssh2_error(session, LIBSSH2_ERROR_ALLOC,
"Unable to allocate a command buffer for "
"SCP session");
return NULL;
}
@@ -296,9 +297,9 @@ scp_recv(LIBSSH2_SESSION * session, const char *path, struct stat * sb)
cmd_len = strlen((char *)session->scpRecv_command);
(void) libssh2_shell_quotearg(path,
&session->scpRecv_command[cmd_len],
session->scpRecv_command_len - cmd_len);
(void) shell_quotearg(path,
&session->scpRecv_command[cmd_len],
session->scpRecv_command_len - cmd_len);
_libssh2_debug(session, LIBSSH2_TRACE_SCP,
@@ -310,11 +311,11 @@ scp_recv(LIBSSH2_SESSION * session, const char *path, struct stat * sb)
if (session->scpRecv_state == libssh2_NB_state_created) {
/* Allocate a channel */
session->scpRecv_channel =
libssh2_channel_open_ex(session, "session",
sizeof("session") - 1,
LIBSSH2_CHANNEL_WINDOW_DEFAULT,
LIBSSH2_CHANNEL_PACKET_DEFAULT, NULL,
0);
_libssh2_channel_open(session, "session",
sizeof("session") - 1,
LIBSSH2_CHANNEL_WINDOW_DEFAULT,
LIBSSH2_CHANNEL_PACKET_DEFAULT, NULL,
0);
if (!session->scpRecv_channel) {
if (libssh2_session_last_errno(session) !=
LIBSSH2_ERROR_EAGAIN) {
@@ -323,8 +324,8 @@ scp_recv(LIBSSH2_SESSION * session, const char *path, struct stat * sb)
session->scpRecv_state = libssh2_NB_state_idle;
}
else {
libssh2_error(session, LIBSSH2_ERROR_EAGAIN,
"Would block starting up channel");
_libssh2_error(session, LIBSSH2_ERROR_EAGAIN,
"Would block starting up channel");
}
return NULL;
}
@@ -334,13 +335,13 @@ scp_recv(LIBSSH2_SESSION * session, const char *path, struct stat * sb)
if (session->scpRecv_state == libssh2_NB_state_sent) {
/* Request SCP for the desired file */
rc = libssh2_channel_process_startup(session->scpRecv_channel, "exec",
sizeof("exec") - 1,
(char *) session->scpRecv_command,
session->scpRecv_command_len);
if (rc == PACKET_EAGAIN) {
libssh2_error(session, LIBSSH2_ERROR_EAGAIN,
"Would block requesting SCP startup");
rc = _libssh2_channel_process_startup(session->scpRecv_channel, "exec",
sizeof("exec") - 1,
(char *) session->scpRecv_command,
session->scpRecv_command_len);
if (rc == LIBSSH2_ERROR_EAGAIN) {
_libssh2_error(session, LIBSSH2_ERROR_EAGAIN,
"Would block requesting SCP startup");
return NULL;
} else if (rc) {
LIBSSH2_FREE(session, session->scpRecv_command);
@@ -360,9 +361,9 @@ scp_recv(LIBSSH2_SESSION * session, const char *path, struct stat * sb)
if (session->scpRecv_state == libssh2_NB_state_sent1) {
rc = _libssh2_channel_write(session->scpRecv_channel, 0,
(char *) session->scpRecv_response, 1);
if (rc == PACKET_EAGAIN) {
libssh2_error(session, LIBSSH2_ERROR_EAGAIN,
"Would block sending initial wakeup");
if (rc == LIBSSH2_ERROR_EAGAIN) {
_libssh2_error(session, LIBSSH2_ERROR_EAGAIN,
"Would block sending initial wakeup");
return NULL;
} else if (rc != 1) {
goto scp_recv_error;
@@ -385,14 +386,14 @@ scp_recv(LIBSSH2_SESSION * session, const char *path, struct stat * sb)
(char *) session->
scpRecv_response +
session->scpRecv_response_len, 1);
if (rc == PACKET_EAGAIN) {
libssh2_error(session, LIBSSH2_ERROR_EAGAIN,
"Would block waiting for SCP response");
if (rc == LIBSSH2_ERROR_EAGAIN) {
_libssh2_error(session, LIBSSH2_ERROR_EAGAIN,
"Would block waiting for SCP response");
return NULL;
} else if (rc <= 0) {
/* Timeout, give up */
libssh2_error(session, LIBSSH2_ERROR_SCP_PROTOCOL,
"Timed out waiting for SCP response");
_libssh2_error(session, LIBSSH2_ERROR_SCP_PROTOCOL,
"Timed out waiting for SCP response");
goto scp_recv_error;
}
session->scpRecv_response_len++;
@@ -402,8 +403,8 @@ scp_recv(LIBSSH2_SESSION * session, const char *path, struct stat * sb)
* Set this as the default error for here, if
* we are successful it will be replaced
*/
libssh2_error(session, LIBSSH2_ERROR_SCP_PROTOCOL,
"Invalid data in SCP response, missing Time data");
_libssh2_error(session, LIBSSH2_ERROR_SCP_PROTOCOL,
"Invalid data in SCP response, missing Time data");
session->scpRecv_err_len =
_libssh2_channel_packet_data_len(session->
@@ -424,14 +425,14 @@ scp_recv(LIBSSH2_SESSION * session, const char *path, struct stat * sb)
/*
* Since we have alread started reading this packet,
* it is already in the systems so it can't return
* PACKET_EAGAIN
* LIBSSH2_ERROR_EAGAIN
*/
libssh2_error(session, LIBSSH2_ERROR_SCP_PROTOCOL,
"Unknown error" );
_libssh2_error(session, LIBSSH2_ERROR_SCP_PROTOCOL,
"Unknown error" );
}
else
libssh2_error(session, LIBSSH2_ERROR_SCP_PROTOCOL,
"SCP protocol error");
_libssh2_error(session, LIBSSH2_ERROR_SCP_PROTOCOL,
"SCP protocol error");
/* TODO: for debugging purposes, the
session->scpRecv_err_msg should be displayed here
@@ -458,8 +459,8 @@ scp_recv(LIBSSH2_SESSION * session, const char *path, struct stat * sb)
&& (session->
scpRecv_response[session->scpRecv_response_len - 1] !=
'\n')) {
libssh2_error(session, LIBSSH2_ERROR_SCP_PROTOCOL,
"Invalid data in SCP response");
_libssh2_error(session, LIBSSH2_ERROR_SCP_PROTOCOL,
"Invalid data in SCP response");
goto scp_recv_error;
}
@@ -470,8 +471,8 @@ scp_recv(LIBSSH2_SESSION * session, const char *path, struct stat * sb)
if (session->scpRecv_response_len ==
LIBSSH2_SCP_RESPONSE_BUFLEN) {
/* You had your chance */
libssh2_error(session, LIBSSH2_ERROR_SCP_PROTOCOL,
"Unterminated response from SCP server");
_libssh2_error(session, LIBSSH2_ERROR_SCP_PROTOCOL,
"Unterminated response from SCP server");
goto scp_recv_error;
}
/* Way too short to be an SCP response, or not done yet,
@@ -493,9 +494,9 @@ scp_recv(LIBSSH2_SESSION * session, const char *path, struct stat * sb)
if (session->scpRecv_response_len < 8) {
/* EOL came too soon */
libssh2_error(session, LIBSSH2_ERROR_SCP_PROTOCOL,
"Invalid response from SCP server, "
"too short" );
_libssh2_error(session, LIBSSH2_ERROR_SCP_PROTOCOL,
"Invalid response from SCP server, "
"too short" );
goto scp_recv_error;
}
@@ -504,9 +505,9 @@ scp_recv(LIBSSH2_SESSION * session, const char *path, struct stat * sb)
p = (unsigned char *) strchr((char *) s, ' ');
if (!p || ((p - s) <= 0)) {
/* No spaces or space in the wrong spot */
libssh2_error(session, LIBSSH2_ERROR_SCP_PROTOCOL,
"Invalid response from SCP server, "
"malformed mtime");
_libssh2_error(session, LIBSSH2_ERROR_SCP_PROTOCOL,
"Invalid response from SCP server, "
"malformed mtime");
goto scp_recv_error;
}
@@ -515,15 +516,15 @@ scp_recv(LIBSSH2_SESSION * session, const char *path, struct stat * sb)
errno = 0;
session->scpRecv_mtime = strtol((char *) s, NULL, 10);
if (errno) {
libssh2_error(session, LIBSSH2_ERROR_SCP_PROTOCOL,
"Invalid response from SCP server, invalid mtime");
_libssh2_error(session, LIBSSH2_ERROR_SCP_PROTOCOL,
"Invalid response from SCP server, invalid mtime");
goto scp_recv_error;
}
s = (unsigned char *) strchr((char *) p, ' ');
if (!s || ((s - p) <= 0)) {
/* No spaces or space in the wrong spot */
libssh2_error(session, LIBSSH2_ERROR_SCP_PROTOCOL,
"Invalid response from SCP server, malformed mtime.usec");
_libssh2_error(session, LIBSSH2_ERROR_SCP_PROTOCOL,
"Invalid response from SCP server, malformed mtime.usec");
goto scp_recv_error;
}
@@ -532,18 +533,18 @@ scp_recv(LIBSSH2_SESSION * session, const char *path, struct stat * sb)
p = (unsigned char *) strchr((char *) s, ' ');
if (!p || ((p - s) <= 0)) {
/* No spaces or space in the wrong spot */
libssh2_error(session, LIBSSH2_ERROR_SCP_PROTOCOL,
"Invalid response from SCP server, too short or malformed");
_libssh2_error(session, LIBSSH2_ERROR_SCP_PROTOCOL,
"Invalid response from SCP server, too short or malformed");
goto scp_recv_error;
}
*(p++) = '\0';
*p = '\0';
/* Make sure we don't get fooled by leftover values */
errno = 0;
session->scpRecv_atime = strtol((char *) s, NULL, 10);
if (errno) {
libssh2_error(session, LIBSSH2_ERROR_SCP_PROTOCOL,
"Invalid response from SCP server, invalid atime");
_libssh2_error(session, LIBSSH2_ERROR_SCP_PROTOCOL,
"Invalid response from SCP server, invalid atime");
goto scp_recv_error;
}
@@ -557,9 +558,9 @@ scp_recv(LIBSSH2_SESSION * session, const char *path, struct stat * sb)
rc = _libssh2_channel_write(session->scpRecv_channel, 0,
(char *) session->
scpRecv_response, 1);
if (rc == PACKET_EAGAIN) {
libssh2_error(session, LIBSSH2_ERROR_EAGAIN,
"Would block waiting to send SCP ACK");
if (rc == LIBSSH2_ERROR_EAGAIN) {
_libssh2_error(session, LIBSSH2_ERROR_EAGAIN,
"Would block waiting to send SCP ACK");
return NULL;
} else if (rc != 1) {
goto scp_recv_error;
@@ -594,21 +595,21 @@ scp_recv(LIBSSH2_SESSION * session, const char *path, struct stat * sb)
(char *) session->
scpRecv_response +
session->scpRecv_response_len, 1);
if (rc == PACKET_EAGAIN) {
libssh2_error(session, LIBSSH2_ERROR_EAGAIN,
"Would block waiting for SCP response");
if (rc == LIBSSH2_ERROR_EAGAIN) {
_libssh2_error(session, LIBSSH2_ERROR_EAGAIN,
"Would block waiting for SCP response");
return NULL;
} else if (rc <= 0) {
/* Timeout, give up */
libssh2_error(session, LIBSSH2_ERROR_SCP_PROTOCOL,
"Timed out waiting for SCP response");
_libssh2_error(session, LIBSSH2_ERROR_SCP_PROTOCOL,
"Timed out waiting for SCP response");
goto scp_recv_error;
}
session->scpRecv_response_len++;
if (session->scpRecv_response[0] != 'C') {
libssh2_error(session, LIBSSH2_ERROR_SCP_PROTOCOL,
"Invalid response from SCP server");
_libssh2_error(session, LIBSSH2_ERROR_SCP_PROTOCOL,
"Invalid response from SCP server");
goto scp_recv_error;
}
@@ -625,8 +626,8 @@ scp_recv(LIBSSH2_SESSION * session, const char *path, struct stat * sb)
|| (session->
scpRecv_response[session->scpRecv_response_len - 1] >
126))) {
libssh2_error(session, LIBSSH2_ERROR_SCP_PROTOCOL,
"Invalid data in SCP response");
_libssh2_error(session, LIBSSH2_ERROR_SCP_PROTOCOL,
"Invalid data in SCP response");
goto scp_recv_error;
}
@@ -637,8 +638,8 @@ scp_recv(LIBSSH2_SESSION * session, const char *path, struct stat * sb)
if (session->scpRecv_response_len ==
LIBSSH2_SCP_RESPONSE_BUFLEN) {
/* You had your chance */
libssh2_error(session, LIBSSH2_ERROR_SCP_PROTOCOL,
"Unterminated response from SCP server");
_libssh2_error(session, LIBSSH2_ERROR_SCP_PROTOCOL,
"Unterminated response from SCP server");
goto scp_recv_error;
}
/* Way too short to be an SCP response, or not done yet,
@@ -661,8 +662,8 @@ scp_recv(LIBSSH2_SESSION * session, const char *path, struct stat * sb)
if (session->scpRecv_response_len < 6) {
/* EOL came too soon */
libssh2_error(session, LIBSSH2_ERROR_SCP_PROTOCOL,
"Invalid response from SCP server, too short");
_libssh2_error(session, LIBSSH2_ERROR_SCP_PROTOCOL,
"Invalid response from SCP server, too short");
goto scp_recv_error;
}
@@ -671,8 +672,8 @@ scp_recv(LIBSSH2_SESSION * session, const char *path, struct stat * sb)
p = strchr(s, ' ');
if (!p || ((p - s) <= 0)) {
/* No spaces or space in the wrong spot */
libssh2_error(session, LIBSSH2_ERROR_SCP_PROTOCOL,
"Invalid response from SCP server, malformed mode");
_libssh2_error(session, LIBSSH2_ERROR_SCP_PROTOCOL,
"Invalid response from SCP server, malformed mode");
goto scp_recv_error;
}
@@ -681,26 +682,26 @@ scp_recv(LIBSSH2_SESSION * session, const char *path, struct stat * sb)
errno = 0;
session->scpRecv_mode = strtol(s, &e, 8);
if ((e && *e) || errno) {
libssh2_error(session, LIBSSH2_ERROR_SCP_PROTOCOL,
"Invalid response from SCP server, invalid mode");
_libssh2_error(session, LIBSSH2_ERROR_SCP_PROTOCOL,
"Invalid response from SCP server, invalid mode");
goto scp_recv_error;
}
s = strchr(p, ' ');
if (!s || ((s - p) <= 0)) {
/* No spaces or space in the wrong spot */
libssh2_error(session, LIBSSH2_ERROR_SCP_PROTOCOL,
"Invalid response from SCP server, too short or malformed");
_libssh2_error(session, LIBSSH2_ERROR_SCP_PROTOCOL,
"Invalid response from SCP server, too short or malformed");
goto scp_recv_error;
}
*(s++) = '\0';
*s = '\0';
/* Make sure we don't get fooled by leftover values */
errno = 0;
session->scpRecv_size = scpsize_strtol(p, &e, 10);
if ((e && *e) || errno) {
libssh2_error(session, LIBSSH2_ERROR_SCP_PROTOCOL,
"Invalid response from SCP server, invalid size");
_libssh2_error(session, LIBSSH2_ERROR_SCP_PROTOCOL,
"Invalid response from SCP server, invalid size");
goto scp_recv_error;
}
@@ -714,9 +715,9 @@ scp_recv(LIBSSH2_SESSION * session, const char *path, struct stat * sb)
rc = _libssh2_channel_write(session->scpRecv_channel, 0,
(char *) session->
scpRecv_response, 1);
if (rc == PACKET_EAGAIN) {
libssh2_error(session, LIBSSH2_ERROR_EAGAIN,
"Would block sending SCP ACK");
if (rc == LIBSSH2_ERROR_EAGAIN) {
_libssh2_error(session, LIBSSH2_ERROR_EAGAIN,
"Would block sending SCP ACK");
return NULL;
} else if (rc != 1) {
goto scp_recv_error;
@@ -747,7 +748,7 @@ scp_recv(LIBSSH2_SESSION * session, const char *path, struct stat * sb)
return session->scpRecv_channel;
scp_recv_error:
while (libssh2_channel_free(session->scpRecv_channel) == PACKET_EAGAIN);
while (libssh2_channel_free(session->scpRecv_channel) == LIBSSH2_ERROR_EAGAIN);
session->scpRecv_channel = NULL;
session->scpRecv_state = libssh2_NB_state_idle;
return NULL;
@@ -775,22 +776,21 @@ libssh2_scp_recv(LIBSSH2_SESSION *session, const char *path, struct stat * sb)
*/
static LIBSSH2_CHANNEL *
scp_send(LIBSSH2_SESSION * session, const char *path, int mode,
size_t size, long mtime, long atime)
libssh2_int64_t size, time_t mtime, time_t atime)
{
int cmd_len;
unsigned const char *base;
int rc;
if (session->scpSend_state == libssh2_NB_state_idle) {
session->scpSend_command_len =
libssh2_shell_quotedsize(path) + sizeof("scp -t ") +
_libssh2_shell_quotedsize(path) + sizeof("scp -t ") +
((mtime || atime)?1:0);
session->scpSend_command =
LIBSSH2_ALLOC(session, session->scpSend_command_len);
if (!session->scpSend_command) {
libssh2_error(session, LIBSSH2_ERROR_ALLOC,
"Unable to allocate a command buffer for scp session");
_libssh2_error(session, LIBSSH2_ERROR_ALLOC,
"Unable to allocate a command buffer for scp session");
return NULL;
}
@@ -799,9 +799,9 @@ scp_send(LIBSSH2_SESSION * session, const char *path, int mode,
cmd_len = strlen((char *)session->scpSend_command);
(void)libssh2_shell_quotearg(path,
&session->scpSend_command[cmd_len],
session->scpSend_command_len - cmd_len);
(void)shell_quotearg(path,
&session->scpSend_command[cmd_len],
session->scpSend_command_len - cmd_len);
session->scpSend_command[session->scpSend_command_len - 1] = '\0';
@@ -814,9 +814,9 @@ scp_send(LIBSSH2_SESSION * session, const char *path, int mode,
if (session->scpSend_state == libssh2_NB_state_created) {
session->scpSend_channel =
libssh2_channel_open_ex(session, "session", sizeof("session") - 1,
LIBSSH2_CHANNEL_WINDOW_DEFAULT,
LIBSSH2_CHANNEL_PACKET_DEFAULT, NULL, 0);
_libssh2_channel_open(session, "session", sizeof("session") - 1,
LIBSSH2_CHANNEL_WINDOW_DEFAULT,
LIBSSH2_CHANNEL_PACKET_DEFAULT, NULL, 0);
if (!session->scpSend_channel) {
if (libssh2_session_last_errno(session) != LIBSSH2_ERROR_EAGAIN) {
/* previous call set libssh2_session_last_error(), pass it
@@ -826,8 +826,8 @@ scp_send(LIBSSH2_SESSION * session, const char *path, int mode,
session->scpSend_state = libssh2_NB_state_idle;
}
else {
libssh2_error(session, LIBSSH2_ERROR_EAGAIN,
"Would block starting up channel");
_libssh2_error(session, LIBSSH2_ERROR_EAGAIN,
"Would block starting up channel");
}
return NULL;
}
@@ -837,13 +837,13 @@ scp_send(LIBSSH2_SESSION * session, const char *path, int mode,
if (session->scpSend_state == libssh2_NB_state_sent) {
/* Request SCP for the desired file */
rc = libssh2_channel_process_startup(session->scpSend_channel, "exec",
sizeof("exec") - 1,
(char *) session->scpSend_command,
session->scpSend_command_len);
if (rc == PACKET_EAGAIN) {
libssh2_error(session, LIBSSH2_ERROR_EAGAIN,
"Would block requesting SCP startup");
rc = _libssh2_channel_process_startup(session->scpSend_channel, "exec",
sizeof("exec") - 1,
(char *) session->scpSend_command,
session->scpSend_command_len);
if (rc == LIBSSH2_ERROR_EAGAIN) {
_libssh2_error(session, LIBSSH2_ERROR_EAGAIN,
"Would block requesting SCP startup");
return NULL;
}
else if (rc) {
@@ -851,8 +851,8 @@ scp_send(LIBSSH2_SESSION * session, const char *path, int mode,
through */
LIBSSH2_FREE(session, session->scpSend_command);
session->scpSend_command = NULL;
libssh2_error(session, LIBSSH2_ERROR_SCP_PROTOCOL,
"Unknown error while getting error string");
_libssh2_error(session, LIBSSH2_ERROR_SCP_PROTOCOL,
"Unknown error while getting error string");
goto scp_send_error;
}
LIBSSH2_FREE(session, session->scpSend_command);
@@ -865,13 +865,13 @@ scp_send(LIBSSH2_SESSION * session, const char *path, int mode,
/* Wait for ACK */
rc = _libssh2_channel_read(session->scpSend_channel, 0,
(char *) session->scpSend_response, 1);
if (rc == PACKET_EAGAIN) {
libssh2_error(session, LIBSSH2_ERROR_EAGAIN,
"Would block waiting for response from remote");
if (rc == LIBSSH2_ERROR_EAGAIN) {
_libssh2_error(session, LIBSSH2_ERROR_EAGAIN,
"Would block waiting for response from remote");
return NULL;
} else if ((rc <= 0) || (session->scpSend_response[0] != 0)) {
libssh2_error(session, LIBSSH2_ERROR_SCP_PROTOCOL,
"Invalid ACK response from remote");
_libssh2_error(session, LIBSSH2_ERROR_SCP_PROTOCOL,
"Invalid ACK response from remote");
goto scp_send_error;
}
@@ -879,8 +879,8 @@ scp_send(LIBSSH2_SESSION * session, const char *path, int mode,
/* Send mtime and atime to be used for file */
session->scpSend_response_len =
snprintf((char *) session->scpSend_response,
LIBSSH2_SCP_RESPONSE_BUFLEN, "T%ld 0 %ld 0\n", mtime,
atime);
LIBSSH2_SCP_RESPONSE_BUFLEN, "T%ld 0 %ld 0\n",
mtime, atime);
_libssh2_debug(session, LIBSSH2_TRACE_SCP, "Sent %s",
session->scpSend_response);
}
@@ -894,13 +894,13 @@ scp_send(LIBSSH2_SESSION * session, const char *path, int mode,
rc = _libssh2_channel_write(session->scpSend_channel, 0,
(char *) session->scpSend_response,
session->scpSend_response_len);
if (rc == PACKET_EAGAIN) {
libssh2_error(session, LIBSSH2_ERROR_EAGAIN,
"Would block sending time data for SCP file");
if (rc == LIBSSH2_ERROR_EAGAIN) {
_libssh2_error(session, LIBSSH2_ERROR_EAGAIN,
"Would block sending time data for SCP file");
return NULL;
} else if (rc != (int)session->scpSend_response_len) {
libssh2_error(session, LIBSSH2_ERROR_SOCKET_SEND,
"Unable to send time data for SCP file");
_libssh2_error(session, LIBSSH2_ERROR_SOCKET_SEND,
"Unable to send time data for SCP file");
goto scp_send_error;
}
@@ -911,13 +911,13 @@ scp_send(LIBSSH2_SESSION * session, const char *path, int mode,
/* Wait for ACK */
rc = _libssh2_channel_read(session->scpSend_channel, 0,
(char *) session->scpSend_response, 1);
if (rc == PACKET_EAGAIN) {
libssh2_error(session, LIBSSH2_ERROR_EAGAIN,
"Would block waiting for response");
if (rc == LIBSSH2_ERROR_EAGAIN) {
_libssh2_error(session, LIBSSH2_ERROR_EAGAIN,
"Would block waiting for response");
return NULL;
} else if ((rc <= 0) || (session->scpSend_response[0] != 0)) {
libssh2_error(session, LIBSSH2_ERROR_SCP_PROTOCOL,
"Invalid ACK response from remote");
_libssh2_error(session, LIBSSH2_ERROR_SCP_PROTOCOL,
"Invalid ACK response from remote");
goto scp_send_error;
}
@@ -931,17 +931,16 @@ scp_send(LIBSSH2_SESSION * session, const char *path, int mode,
if (session->scpSend_state == libssh2_NB_state_sent4) {
/* Send mode, size, and basename */
base = (unsigned char *) strrchr(path, '/');
if (base) {
const char *base = strrchr(path, '/');
if (base)
base++;
} else {
base = (unsigned char *) path;
}
else
base = path;
session->scpSend_response_len =
snprintf((char *) session->scpSend_response,
LIBSSH2_SCP_RESPONSE_BUFLEN, "C0%o %lu %s\n", mode,
(unsigned long) size, base);
LIBSSH2_SCP_RESPONSE_BUFLEN, "C0%o %llu %s\n", mode,
size, base);
_libssh2_debug(session, LIBSSH2_TRACE_SCP, "Sent %s",
session->scpSend_response);
@@ -952,13 +951,13 @@ scp_send(LIBSSH2_SESSION * session, const char *path, int mode,
rc = _libssh2_channel_write(session->scpSend_channel, 0,
(char *) session->scpSend_response,
session->scpSend_response_len);
if (rc == PACKET_EAGAIN) {
libssh2_error(session, LIBSSH2_ERROR_EAGAIN,
"Would block send core file data for SCP file");
if (rc == LIBSSH2_ERROR_EAGAIN) {
_libssh2_error(session, LIBSSH2_ERROR_EAGAIN,
"Would block send core file data for SCP file");
return NULL;
} else if (rc != (int)session->scpSend_response_len) {
libssh2_error(session, LIBSSH2_ERROR_SOCKET_SEND,
"Unable to send core file data for SCP file");
_libssh2_error(session, LIBSSH2_ERROR_SOCKET_SEND,
"Unable to send core file data for SCP file");
goto scp_send_error;
}
@@ -969,21 +968,21 @@ scp_send(LIBSSH2_SESSION * session, const char *path, int mode,
/* Wait for ACK */
rc = _libssh2_channel_read(session->scpSend_channel, 0,
(char *) session->scpSend_response, 1);
if (rc == PACKET_EAGAIN) {
libssh2_error(session, LIBSSH2_ERROR_EAGAIN,
"Would block waiting for response");
if (rc == LIBSSH2_ERROR_EAGAIN) {
_libssh2_error(session, LIBSSH2_ERROR_EAGAIN,
"Would block waiting for response");
return NULL;
} else if (rc <= 0) {
libssh2_error(session, LIBSSH2_ERROR_SCP_PROTOCOL,
"Invalid ACK response from remote");
_libssh2_error(session, LIBSSH2_ERROR_SCP_PROTOCOL,
"Invalid ACK response from remote");
goto scp_send_error;
} else if (session->scpSend_response[0] != 0) {
/*
* Set this as the default error for here, if
* we are successful it will be replaced
*/
libssh2_error(session, LIBSSH2_ERROR_SCP_PROTOCOL,
"Invalid ACK response from remote");
_libssh2_error(session, LIBSSH2_ERROR_SCP_PROTOCOL,
"Invalid ACK response from remote");
session->scpSend_err_len =
_libssh2_channel_packet_data_len(session->scpSend_channel, 0);
@@ -1001,14 +1000,15 @@ scp_send(LIBSSH2_SESSION * session, const char *path, int mode,
if (rc <= 0) {
/*
* Since we have alread started reading this packet, it is
* already in the systems so it can't return PACKET_EAGAIN
* already in the systems so it can't return
* LIBSSH2_ERROR_EAGAIN
*/
LIBSSH2_FREE(session, session->scpSend_err_msg);
session->scpSend_err_msg = NULL;
}
else
libssh2_error(session, LIBSSH2_ERROR_SCP_PROTOCOL,
"failed waiting for ACK");
_libssh2_error(session, LIBSSH2_ERROR_SCP_PROTOCOL,
"failed waiting for ACK");
goto scp_send_error;
}
}
@@ -1018,7 +1018,8 @@ scp_send(LIBSSH2_SESSION * session, const char *path, int mode,
return session->scpSend_channel;
scp_send_error:
while (libssh2_channel_free(session->scpSend_channel) == PACKET_EAGAIN);
while (libssh2_channel_free(session->scpSend_channel) ==
LIBSSH2_ERROR_EAGAIN);
session->scpSend_channel = NULL;
session->scpSend_state = libssh2_NB_state_idle;
return NULL;
@@ -1027,11 +1028,27 @@ scp_send(LIBSSH2_SESSION * session, const char *path, int mode,
/*
* libssh2_scp_send_ex
*
* Send a file using SCP
* Send a file using SCP. Old API.
*/
LIBSSH2_API LIBSSH2_CHANNEL *
libssh2_scp_send_ex(LIBSSH2_SESSION *session, const char *path, int mode,
size_t size, long mtime, long atime)
{
LIBSSH2_CHANNEL *ptr;
BLOCK_ADJUST_ERRNO(ptr, session,
scp_send(session, path, mode, size,
(time_t)mtime, (time_t)atime));
return ptr;
}
/*
* libssh2_scp_send64
*
* Send a file using SCP
*/
LIBSSH2_API LIBSSH2_CHANNEL *
libssh2_scp_send64(LIBSSH2_SESSION *session, const char *path, int mode,
libssh2_int64_t size, time_t mtime, time_t atime)
{
LIBSSH2_CHANNEL *ptr;
BLOCK_ADJUST_ERRNO(ptr, session,

View File

@@ -1,5 +1,5 @@
/* Copyright (c) 2004-2007 Sara Golemon <sarag@libssh2.org>
* Copyright (c) 2009 by Daniel Stenberg
* Copyright (c) 2009-2010 by Daniel Stenberg
* Copyright (c) 2010 Simon Josefsson <simon@josefsson.org>
* All rights reserved.
*
@@ -53,6 +53,8 @@
#endif
#include "transport.h"
#include "session.h"
#include "channel.h"
/* libssh2_default_alloc
*/
@@ -86,7 +88,7 @@ LIBSSH2_REALLOC_FUNC(libssh2_default_realloc)
*
* Wait for a hello from the remote host
* Allocate a buffer and store the banner in session->remote.banner
* Returns: 0 on success, PACKET_EAGAIN if read would block, negative on failure
* Returns: 0 on success, LIBSSH2_ERROR_EAGAIN if read would block, negative on failure
*/
static int
banner_receive(LIBSSH2_SESSION * session)
@@ -124,7 +126,7 @@ banner_receive(LIBSSH2_SESSION * session)
session->socket_block_directions =
LIBSSH2_SESSION_BLOCK_INBOUND;
session->banner_TxRx_total_send = banner_len;
return PACKET_EAGAIN;
return LIBSSH2_ERROR_EAGAIN;
}
/* Some kinda error */
@@ -135,7 +137,7 @@ banner_receive(LIBSSH2_SESSION * session)
if (ret == 0) {
session->socket_state = LIBSSH2_SOCKET_DISCONNECTED;
return PACKET_FAIL;
return LIBSSH2_ERROR_SOCKET_NONE;
}
if (c == '\0') {
@@ -163,8 +165,8 @@ banner_receive(LIBSSH2_SESSION * session)
session->remote.banner = LIBSSH2_ALLOC(session, banner_len + 1);
if (!session->remote.banner) {
return libssh2_error(session, LIBSSH2_ERROR_ALLOC,
"Error allocating space for remote banner");
return _libssh2_error(session, LIBSSH2_ERROR_ALLOC,
"Error allocating space for remote banner");
}
memcpy(session->remote.banner, session->banner_TxRx_banner, banner_len);
session->remote.banner[banner_len] = '\0';
@@ -178,7 +180,7 @@ banner_receive(LIBSSH2_SESSION * session)
*
* Send the default banner, or the one set via libssh2_setopt_string
*
* Returns PACKET_EAGAIN if it would block - and if it does so, you should
* Returns LIBSSH2_ERROR_EAGAIN if it would block - and if it does so, you should
* call this function again as soon as it is likely that more data can be
* sent, and this function should then be called with the same argument set
* (same data pointer and same data_len) until zero or failure is returned.
@@ -239,11 +241,11 @@ banner_send(LIBSSH2_SESSION * session)
session->socket_block_directions =
LIBSSH2_SESSION_BLOCK_OUTBOUND;
session->banner_TxRx_total_send += ret;
return PACKET_EAGAIN;
return LIBSSH2_ERROR_EAGAIN;
}
session->banner_TxRx_state = libssh2_NB_state_idle;
session->banner_TxRx_total_send = 0;
return PACKET_FAIL;
return LIBSSH2_ERROR_SOCKET_NONE;
}
/* Set the state back to idle */
@@ -278,7 +280,7 @@ session_nonblock(libssh2_socket_t sockfd, /* operate on this */
#endif
#if defined(HAVE_FIONBIO) && (SETBLOCK == 0)
/* older unix versions */
/* older unix versions and VMS*/
int flags;
flags = nonblock;
@@ -373,10 +375,28 @@ get_socket_nonblocking(int sockfd)
#define GETBLOCK 5
#endif
#if defined(SO_STATE) && defined( __VMS ) && (GETBLOCK == 0)
/* VMS TCP/IP Services */
size_t sockstat = 0;
int callstat = 0;
size_t size = sizeof( int );
callstat = getsockopt(sockfd, SOL_SOCKET, SO_STATE,
(char *)&sockstat, &size);
if ( callstat == -1 ) return(0);
if ( (sockstat&SS_NBIO) )return(1);
return(0);
#undef GETBLOCK
#define GETBLOCK 6
#endif
#ifdef HAVE_DISABLED_NONBLOCKING
return 1; /* returns blocking */
#undef GETBLOCK
#define GETBLOCK 6
#define GETBLOCK 7
#endif
#if (GETBLOCK == 0)
@@ -403,17 +423,19 @@ libssh2_banner_set(LIBSSH2_SESSION * session, const char *banner)
session->local.banner = LIBSSH2_ALLOC(session, banner_len + 3);
if (!session->local.banner) {
return libssh2_error(session, LIBSSH2_ERROR_ALLOC,
"Unable to allocate memory for local banner");
return _libssh2_error(session, LIBSSH2_ERROR_ALLOC,
"Unable to allocate memory for local banner");
}
memcpy(session->local.banner, banner, banner_len);
/* first zero terminate like this so that the debug output is nice */
session->local.banner[banner_len] = '\0';
_libssh2_debug(session, LIBSSH2_TRACE_TRANS, "Setting local Banner: %s",
session->local.banner);
session->local.banner[banner_len++] = '\r';
session->local.banner[banner_len++] = '\n';
session->local.banner[banner_len++] = '\0';
session->local.banner[banner_len] = '\0';
return 0;
}
@@ -518,8 +540,8 @@ libssh2_session_callback_set(LIBSSH2_SESSION * session,
int _libssh2_wait_socket(LIBSSH2_SESSION *session)
{
int rc;
int dir;
int seconds_to_next;
int dir;
rc = libssh2_keepalive_send (session, &seconds_to_next);
if (rc < 0)
@@ -528,43 +550,49 @@ int _libssh2_wait_socket(LIBSSH2_SESSION *session)
/* figure out what to wait for */
dir = libssh2_session_block_directions(session);
{
#ifdef HAVE_POLL
struct pollfd sockets[1];
struct pollfd sockets[1];
sockets[0].fd = session->socket_fd;
sockets[0].events = 0;
sockets[0].revents = 0;
sockets[0].fd = session->socket_fd;
sockets[0].events = 0;
sockets[0].revents = 0;
if(dir & LIBSSH2_SESSION_BLOCK_INBOUND)
sockets[0].events |= POLLIN;
if(dir & LIBSSH2_SESSION_BLOCK_INBOUND)
sockets[0].events |= POLLIN;
if(dir & LIBSSH2_SESSION_BLOCK_OUTBOUND)
sockets[0].events |= POLLOUT;
if(dir & LIBSSH2_SESSION_BLOCK_OUTBOUND)
sockets[0].events |= POLLOUT;
rc = poll(sockets, 1, seconds_to_next ? seconds_to_next / 1000 : -1);
rc = poll(sockets, 1, seconds_to_next ? seconds_to_next / 1000 : -1);
#else
fd_set fd;
fd_set *writefd = NULL;
fd_set *readfd = NULL;
struct timeval tv;
fd_set rfd;
fd_set wfd;
fd_set *writefd = NULL;
fd_set *readfd = NULL;
struct timeval tv;
tv.tv_sec = seconds_to_next;
tv.tv_usec = 0;
tv.tv_sec = seconds_to_next;
tv.tv_usec = 0;
FD_ZERO(&fd);
FD_SET(session->socket_fd, &fd);
if(dir & LIBSSH2_SESSION_BLOCK_INBOUND) {
FD_ZERO(&rfd);
FD_SET(session->socket_fd, &rfd);
readfd = &rfd;
}
if(dir & LIBSSH2_SESSION_BLOCK_INBOUND)
readfd = &fd;
if(dir & LIBSSH2_SESSION_BLOCK_OUTBOUND) {
FD_ZERO(&wfd);
FD_SET(session->socket_fd, &wfd);
writefd = &wfd;
}
if(dir & LIBSSH2_SESSION_BLOCK_OUTBOUND)
writefd = &fd;
/* Note that this COULD be made to use a timeout that perhaps could be
customizable by the app or something... */
rc = select(session->socket_fd + 1, readfd, writefd, NULL,
seconds_to_next ? &tv : NULL);
/* Note that this COULD be made to use a timeout that perhaps
could be customizable by the app or something... */
rc = select(session->socket_fd + 1, readfd, writefd, NULL,
seconds_to_next ? &tv : NULL);
#endif
}
}
if(rc <= 0) {
@@ -586,8 +614,8 @@ session_startup(LIBSSH2_SESSION *session, libssh2_socket_t sock)
"session_startup for socket %d", sock);
if (INVALID_SOCKET == sock) {
/* Did we forget something? */
return libssh2_error(session, LIBSSH2_ERROR_SOCKET_NONE,
"Bad socket provided");
return _libssh2_error(session, LIBSSH2_ERROR_SOCKET_NONE,
"Bad socket provided");
}
session->socket_fd = sock;
@@ -605,8 +633,8 @@ session_startup(LIBSSH2_SESSION *session, libssh2_socket_t sock)
if (session->startup_state == libssh2_NB_state_created) {
rc = banner_send(session);
if (rc) {
return libssh2_error(session, rc,
"Failed sending banner");
return _libssh2_error(session, rc,
"Failed sending banner");
}
session->startup_state = libssh2_NB_state_sent;
}
@@ -614,19 +642,18 @@ session_startup(LIBSSH2_SESSION *session, libssh2_socket_t sock)
if (session->startup_state == libssh2_NB_state_sent) {
rc = banner_receive(session);
if (rc) {
return libssh2_error(session, rc,
"Failed getting banner");
return _libssh2_error(session, rc,
"Failed getting banner");
}
session->startup_state = libssh2_NB_state_sent1;
}
if (session->startup_state == libssh2_NB_state_sent1) {
rc = libssh2_kex_exchange(session, 0, &session->startup_key_state);
if (rc) {
return libssh2_error(session, rc,
"Unable to exchange encryption keys");
}
rc = _libssh2_kex_exchange(session, 0, &session->startup_key_state);
if (rc)
return _libssh2_error(session, rc,
"Unable to exchange encryption keys");
session->startup_state = libssh2_NB_state_sent2;
}
@@ -638,7 +665,7 @@ session_startup(LIBSSH2_SESSION *session, libssh2_socket_t sock)
/* Request the userauth service */
session->startup_service[0] = SSH_MSG_SERVICE_REQUEST;
_libssh2_htonu32(session->startup_service + 1,
sizeof("ssh-userauth") - 1);
sizeof("ssh-userauth") - 1);
memcpy(session->startup_service + 5, "ssh-userauth",
sizeof("ssh-userauth") - 1);
@@ -649,8 +676,8 @@ session_startup(LIBSSH2_SESSION *session, libssh2_socket_t sock)
rc = _libssh2_transport_write(session, session->startup_service,
sizeof("ssh-userauth") + 5 - 1);
if (rc) {
return libssh2_error(session, rc,
"Unable to ask for ssh-userauth service");
return _libssh2_error(session, rc,
"Unable to ask for ssh-userauth service");
}
session->startup_state = libssh2_NB_state_sent4;
@@ -672,8 +699,8 @@ session_startup(LIBSSH2_SESSION *session, libssh2_socket_t sock)
session->startup_service_length)) {
LIBSSH2_FREE(session, session->startup_data);
session->startup_data = NULL;
return libssh2_error(session, LIBSSH2_ERROR_PROTO,
"Invalid response received from server");
return _libssh2_error(session, LIBSSH2_ERROR_PROTO,
"Invalid response received from server");
}
LIBSSH2_FREE(session, session->startup_data);
session->startup_data = NULL;
@@ -731,27 +758,9 @@ session_free(LIBSSH2_SESSION *session)
if (session->free_state == libssh2_NB_state_created) {
while ((ch = _libssh2_list_first(&session->channels))) {
rc = libssh2_channel_free(ch);
if (rc == PACKET_EAGAIN)
rc = _libssh2_channel_free(ch);
if (rc == LIBSSH2_ERROR_EAGAIN)
return rc;
#if 0
/* Daniel's note: I'm leaving this code here right now since it
looks so weird I'm stumped. Why would libssh2_channel_free()
fail and forces this to be done? */
if (tmp == session->channels.head) {
/* channel_free couldn't do it's job, perform a messy cleanup */
tmp = session->channels.head;
/* unlink */
session->channels.head = tmp->next;
/* free */
LIBSSH2_FREE(session, tmp);
/* reverse linking isn't important here, we're killing the
* structure */
}
#endif
}
session->state = libssh2_NB_state_sent;
@@ -759,8 +768,8 @@ session_free(LIBSSH2_SESSION *session)
if (session->state == libssh2_NB_state_sent) {
while ((l = _libssh2_list_first(&session->listeners))) {
rc = libssh2_channel_forward_cancel(l);
if (rc == PACKET_EAGAIN)
rc = _libssh2_channel_forward_cancel(l);
if (rc == LIBSSH2_ERROR_EAGAIN)
return rc;
}
@@ -998,35 +1007,22 @@ session_disconnect(LIBSSH2_SESSION *session, int reason,
LIBSSH2_ALLOC(session, session->disconnect_data_len);
if (!session->disconnect_data) {
session->disconnect_state = libssh2_NB_state_idle;
return libssh2_error(session, LIBSSH2_ERROR_ALLOC,
"Unable to allocate memory for "
"disconnect packet");
return _libssh2_error(session, LIBSSH2_ERROR_ALLOC,
"Unable to allocate memory for "
"disconnect packet");
}
*(s++) = SSH_MSG_DISCONNECT;
_libssh2_htonu32(s, reason);
s += 4;
_libssh2_htonu32(s, descr_len);
s += 4;
if (description) {
memcpy(s, description, descr_len);
s += descr_len;
}
_libssh2_htonu32(s, lang_len);
s += 4;
if (lang) {
memcpy(s, lang, lang_len);
s += lang_len;
}
_libssh2_store_u32(&s, reason);
_libssh2_store_str(&s, description, descr_len);
_libssh2_store_str(&s, lang, lang_len);
session->disconnect_state = libssh2_NB_state_created;
}
rc = _libssh2_transport_write(session, session->disconnect_data,
session->disconnect_data_len);
if (rc == PACKET_EAGAIN) {
if (rc == LIBSSH2_ERROR_EAGAIN) {
return rc;
}
@@ -1105,14 +1101,14 @@ libssh2_session_methods(LIBSSH2_SESSION * session, int method_type)
return "";
default:
libssh2_error(session, LIBSSH2_ERROR_INVAL,
"Invalid parameter specified for method_type");
_libssh2_error(session, LIBSSH2_ERROR_INVAL,
"Invalid parameter specified for method_type");
return NULL;
}
if (!method) {
libssh2_error(session, LIBSSH2_ERROR_METHOD_NONE,
"No method negotiated");
_libssh2_error(session, LIBSSH2_ERROR_METHOD_NONE,
"No method negotiated");
return NULL;
}
@@ -1352,8 +1348,8 @@ libssh2_poll(LIBSSH2_POLLFD * fds, unsigned int nfds, long timeout)
default:
if (session)
libssh2_error(session, LIBSSH2_ERROR_INVALID_POLL_TYPE,
"Invalid descriptor passed to libssh2_poll()");
_libssh2_error(session, LIBSSH2_ERROR_INVALID_POLL_TYPE,
"Invalid descriptor passed to libssh2_poll()");
return -1;
}
}
@@ -1399,8 +1395,8 @@ libssh2_poll(LIBSSH2_POLLFD * fds, unsigned int nfds, long timeout)
default:
if (session)
libssh2_error(session, LIBSSH2_ERROR_INVALID_POLL_TYPE,
"Invalid descriptor passed to libssh2_poll()");
_libssh2_error(session, LIBSSH2_ERROR_INVALID_POLL_TYPE,
"Invalid descriptor passed to libssh2_poll()");
return -1;
}
}

91
src/session.h Normal file
View File

@@ -0,0 +1,91 @@
#ifndef LIBSSH2_SESSION_H
#define LIBSSH2_SESSION_H
/* Copyright (c) 2004-2007 Sara Golemon <sarag@libssh2.org>
* Copyright (c) 2009-2010 by Daniel Stenberg
* Copyright (c) 2010 Simon Josefsson <simon@josefsson.org>
* 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.
*/
/* Conveniance-macros to allow code like this;
int rc = BLOCK_ADJUST(rc, session, session_startup(session, sock) );
int rc = BLOCK_ADJUST_ERRNO(ptr, session, session_startup(session, sock) );
The point of course being to make sure that while in non-blocking mode
these always return no matter what the return code is, but in blocking mode
it blocks if EAGAIN is the reason for the return from the underlying
function.
*/
#define BLOCK_ADJUST(rc,sess,x) \
do { \
rc = x; \
/* the order of the check below is important to properly deal with the
case when the 'sess' is freed */ \
if((rc != LIBSSH2_ERROR_EAGAIN) || !sess->api_block_mode) \
break; \
rc = _libssh2_wait_socket(sess); \
if(rc) \
break; \
} while(1)
/*
* For functions that returns a pointer, we need to check if the API is
* non-blocking and return immediately. If the pointer is non-NULL we return
* immediately. If the API is blocking and we get a NULL we check the errno
* and *only* if that is EAGAIN we loop and wait for socket action.
*/
#define BLOCK_ADJUST_ERRNO(ptr,sess,x) \
do { \
int rc; \
ptr = x; \
if(!sess->api_block_mode || \
(ptr != NULL) || \
(libssh2_session_last_errno(sess) != LIBSSH2_ERROR_EAGAIN) ) \
break; \
rc = _libssh2_wait_socket(sess); \
if(rc) \
break; \
} while(1)
int _libssh2_wait_socket(LIBSSH2_SESSION *session);
/* this is the lib-internal set blocking function */
int _libssh2_session_set_blocking(LIBSSH2_SESSION * session, int blocking);
#endif /* LIBSSH2_SESSION_H */

1246
src/sftp.c

File diff suppressed because it is too large Load Diff

View File

@@ -1,5 +1,5 @@
/* Copyright (C) 2007 The Written Word, Inc. All rights reserved.
* Copyright (C) 2009 by Daniel Stenberg
* Copyright (C) 2009-2010 by Daniel Stenberg
* Author: Daniel Stenberg <daniel@haxx.se>
*
* Redistribution and use in source and binary forms,
@@ -47,14 +47,14 @@
#include "transport.h"
#define MAX_BLOCKSIZE 32 /* MUST fit biggest crypto block size we use/get */
#define MAX_BLOCKSIZE 32 /* MUST fit biggest crypto block size we use/get */
#define MAX_MACSIZE 20 /* MUST fit biggest MAC length we support */
#ifdef LIBSSH2DEBUG
#define UNPRINTABLE_CHAR '.'
static void
debugdump(LIBSSH2_SESSION * session,
const char *desc, unsigned char *ptr, unsigned long size)
const char *desc, unsigned char *ptr, size_t size)
{
size_t i;
size_t c;
@@ -71,7 +71,8 @@ debugdump(LIBSSH2_SESSION * session,
used = snprintf(buffer, sizeof(buffer), "=> %s (%d bytes)\n",
desc, (int) size);
if (session->tracehandler)
(session->tracehandler)(session, session->tracehandler_context, buffer, used);
(session->tracehandler)(session, session->tracehandler_context,
buffer, used);
else
write(2 /* stderr */, buffer, used);
@@ -106,7 +107,8 @@ debugdump(LIBSSH2_SESSION * session,
buffer[used] = 0;
if (session->tracehandler)
(session->tracehandler)(session, session->tracehandler_context, buffer, used);
(session->tracehandler)(session, session->tracehandler_context,
buffer, used);
else
write(2, buffer, used);
}
@@ -136,7 +138,7 @@ decrypt(LIBSSH2_SESSION * session, unsigned char *source,
if (session->remote.crypt->crypt(session, source,
&session->remote.crypt_abstract)) {
LIBSSH2_FREE(session, p->payload);
return PACKET_FAIL;
return LIBSSH2_ERROR_SOCKET_NONE;
}
/* if the crypt() function would write to a given address it
@@ -148,7 +150,7 @@ decrypt(LIBSSH2_SESSION * session, unsigned char *source,
dest += blocksize; /* advance write pointer */
source += blocksize; /* advance read pointer */
}
return PACKET_NONE; /* all is fine */
return LIBSSH2_ERROR_NONE; /* all is fine */
}
/*
@@ -196,7 +198,7 @@ fullpacket(LIBSSH2_SESSION * session, int encrypted /* 1 or 0 */ )
if (session->remote.comp &&
strcmp(session->remote.comp->name, "none")) {
unsigned char *data;
unsigned long data_len;
size_t data_len;
int free_payload = 1;
if (session->remote.comp->comp(session, 0,
@@ -207,7 +209,7 @@ fullpacket(LIBSSH2_SESSION * session, int encrypted /* 1 or 0 */ )
session->fullpacket_payload_len,
&session->remote.comp_abstract)) {
LIBSSH2_FREE(session, p->payload);
return PACKET_FAIL;
return LIBSSH2_ERROR_SOCKET_NONE;
}
if (free_payload) {
@@ -231,7 +233,7 @@ fullpacket(LIBSSH2_SESSION * session, int encrypted /* 1 or 0 */ )
* brigade won't know what to do with it */
p->payload = LIBSSH2_ALLOC(session, data_len);
if (!p->payload)
return PACKET_ENOMEM;
return LIBSSH2_ERROR_ALLOC;
memcpy(p->payload, data, data_len);
session->fullpacket_payload_len = data_len;
@@ -274,7 +276,7 @@ fullpacket(LIBSSH2_SESSION * session, int encrypted /* 1 or 0 */ )
* This function reads the binary stream as specified in chapter 6 of RFC4253
* "The Secure Shell (SSH) Transport Layer Protocol"
*
* DOES NOT call libssh2_error() for ANY error case.
* DOES NOT call _libssh2_error() for ANY error case.
*/
int _libssh2_transport_read(LIBSSH2_SESSION * session)
{
@@ -311,7 +313,7 @@ int _libssh2_transport_read(LIBSSH2_SESSION * session)
*/
_libssh2_debug(session, LIBSSH2_TRACE_TRANS, "Redirecting into the"
" key re-exchange");
rc = libssh2_kex_exchange(session, 1, &session->startup_key_state);
rc = _libssh2_kex_exchange(session, 1, &session->startup_key_state);
if (rc)
return rc;
}
@@ -329,7 +331,7 @@ int _libssh2_transport_read(LIBSSH2_SESSION * session)
do {
if (session->socket_state == LIBSSH2_SOCKET_DISCONNECTED) {
return PACKET_NONE;
return LIBSSH2_ERROR_NONE;
}
if (session->state & LIBSSH2_STATE_NEWKEYS) {
@@ -389,9 +391,9 @@ int _libssh2_transport_read(LIBSSH2_SESSION * session)
if ((nread < 0) && (errno == EAGAIN)) {
session->socket_block_directions |=
LIBSSH2_SESSION_BLOCK_INBOUND;
return PACKET_EAGAIN;
return LIBSSH2_ERROR_EAGAIN;
}
return PACKET_FAIL;
return LIBSSH2_ERROR_SOCKET_NONE;
}
debugdump(session, "libssh2_transport_read() raw",
@@ -418,12 +420,12 @@ int _libssh2_transport_read(LIBSSH2_SESSION * session)
*/
session->socket_block_directions |=
LIBSSH2_SESSION_BLOCK_INBOUND;
return PACKET_EAGAIN;
return LIBSSH2_ERROR_EAGAIN;
}
if (encrypted) {
rc = decrypt(session, &p->buf[p->readidx], block, blocksize);
if (rc != PACKET_NONE) {
if (rc != LIBSSH2_ERROR_NONE) {
return rc;
}
/* save the first 5 bytes of the decrypted package, to be
@@ -443,11 +445,9 @@ int _libssh2_transport_read(LIBSSH2_SESSION * session)
*/
p->packet_length = _libssh2_ntohu32(block);
if (p->packet_length < 1)
return PACKET_FAIL;
return LIBSSH2_ERROR_SOCKET_NONE;
p->padding_length = block[4];
if (p->padding_length < 0)
return PACKET_FAIL;
/* total_num is the number of bytes following the initial
(5 bytes) packet length and padding length fields */
@@ -464,14 +464,14 @@ int _libssh2_transport_read(LIBSSH2_SESSION * session)
* padding, and MAC.)."
*/
if (p->total_num > LIBSSH2_PACKET_MAXPAYLOAD) {
return PACKET_TOOBIG;
return LIBSSH2_ERROR_OUT_OF_BOUNDARY;
}
/* Get a packet handle put data into. We get one to
hold all data, including padding and MAC. */
p->payload = LIBSSH2_ALLOC(session, p->total_num);
if (!p->payload) {
return PACKET_ENOMEM;
return LIBSSH2_ERROR_ALLOC;
}
/* init write pointer to start of payload buffer */
p->wptr = p->payload;
@@ -536,7 +536,7 @@ int _libssh2_transport_read(LIBSSH2_SESSION * session)
if (numdecrypt > 0) {
/* now decrypt the lot */
rc = decrypt(session, &p->buf[p->readidx], p->wptr, numdecrypt);
if (rc != PACKET_NONE) {
if (rc != LIBSSH2_ERROR_NONE) {
return rc;
}
@@ -572,13 +572,13 @@ int _libssh2_transport_read(LIBSSH2_SESSION * session)
/* we have a full packet */
libssh2_transport_read_point1:
rc = fullpacket(session, encrypted);
if (rc == PACKET_EAGAIN) {
if (rc == LIBSSH2_ERROR_EAGAIN) {
if (session->packAdd_state != libssh2_NB_state_idle)
{
/* fullpacket only returns PACKET_EAGAIN if
* libssh2_packet_add returns PACKET_EAGAIN. If that
* returns PACKET_EAGAIN but the packAdd_state is idle,
/* fullpacket only returns LIBSSH2_ERROR_EAGAIN if
* libssh2_packet_add returns LIBSSH2_ERROR_EAGAIN. If that
* returns LIBSSH2_ERROR_EAGAIN but the packAdd_state is idle,
* then the packet has been added to the brigade, but some
* immediate action that was taken based on the packet
* type (such as key re-exchange) is not yet complete.
@@ -597,12 +597,26 @@ int _libssh2_transport_read(LIBSSH2_SESSION * session)
}
} while (1); /* loop */
return PACKET_FAIL; /* we never reach this point */
return LIBSSH2_ERROR_SOCKET_NONE; /* we never reach this point */
}
/*
* _libssh2_transport_drain() empties the outgoing send buffer if there
* is any.
*/
void _libssh2_transport_drain(LIBSSH2_SESSION * session)
{
struct transportpacket *p = &session->packet;
if(p->outbuf) {
LIBSSH2_FREE(session, p->outbuf);
p->outbuf = NULL;
p->ototal_num = 0;
}
}
static int
send_existing(LIBSSH2_SESSION * session, unsigned char *data,
unsigned long data_len, ssize_t * ret)
size_t data_len, ssize_t * ret)
{
ssize_t rc;
ssize_t length;
@@ -610,7 +624,7 @@ send_existing(LIBSSH2_SESSION * session, unsigned char *data,
if (!p->outbuf) {
*ret = 0;
return PACKET_NONE;
return LIBSSH2_ERROR_NONE;
}
/* send as much as possible of the existing packet */
@@ -620,7 +634,7 @@ send_existing(LIBSSH2_SESSION * session, unsigned char *data,
we don't add this one up until the previous one has been sent. To
make the caller really notice his/hers flaw, we return error for
this case */
return PACKET_BADUSE;
return LIBSSH2_ERROR_BAD_USE;
}
*ret = 1; /* set to make our parent return */
@@ -653,15 +667,15 @@ send_existing(LIBSSH2_SESSION * session, unsigned char *data,
/* nothing was sent */
if (errno != EAGAIN) {
/* send failure! */
return PACKET_FAIL;
return LIBSSH2_ERROR_SOCKET_NONE;
}
session->socket_block_directions |= LIBSSH2_SESSION_BLOCK_OUTBOUND;
return PACKET_EAGAIN;
return LIBSSH2_ERROR_EAGAIN;
}
p->osent += rc; /* we sent away this much data */
return rc < length ? PACKET_EAGAIN : PACKET_NONE;
return rc < length ? LIBSSH2_ERROR_EAGAIN : LIBSSH2_ERROR_NONE;
}
/*
@@ -670,7 +684,7 @@ send_existing(LIBSSH2_SESSION * session, unsigned char *data,
* Send a packet, encrypting it and adding a MAC code if necessary
* Returns 0 on success, non-zero on failure.
*
* Returns PACKET_EAGAIN if it would block - and if it does so, you should
* Returns LIBSSH2_ERROR_EAGAIN if it would block - and if it does so, you should
* call this function again as soon as it is likely that more data can be
* sent, and this function should then be called with the same argument set
* (same data pointer and same data_len) until zero or failure is returned.
@@ -679,11 +693,11 @@ send_existing(LIBSSH2_SESSION * session, unsigned char *data,
* which is what all implementations should support at least as packet size.
* (RFC4253 section 6.1)
*
* This function DOES not call libssh2_error() on any errors.
* This function DOES not call _libssh2_error() on any errors.
*/
int
_libssh2_transport_write(LIBSSH2_SESSION * session, unsigned char *data,
unsigned long data_len)
size_t data_len)
{
int blocksize =
(session->state & LIBSSH2_STATE_NEWKEYS) ? session->local.crypt->
@@ -702,7 +716,7 @@ _libssh2_transport_write(LIBSSH2_SESSION * session, unsigned char *data,
ssize_t ret;
int rc;
unsigned char *orgdata = data;
unsigned long orgdata_len = data_len;
size_t orgdata_len = data_len;
debugdump(session, "libssh2_transport_write plain", data, data_len);
@@ -724,7 +738,7 @@ _libssh2_transport_write(LIBSSH2_SESSION * session, unsigned char *data,
LIBSSH2_PACKET_MAXCOMP,
&free_data, data, data_len,
&session->local.comp_abstract)) {
return PACKET_COMPRESS; /* compression failure */
return LIBSSH2_ERROR_COMPRESS; /* compression failure */
}
}
@@ -772,7 +786,7 @@ _libssh2_transport_write(LIBSSH2_SESSION * session, unsigned char *data,
returns. */
p->outbuf = LIBSSH2_ALLOC(session, total_length);
if (!p->outbuf) {
return PACKET_ENOMEM;
return LIBSSH2_ERROR_ALLOC;
}
/* store packet_length, which is the size of the whole packet except
@@ -783,7 +797,7 @@ _libssh2_transport_write(LIBSSH2_SESSION * session, unsigned char *data,
/* copy the payload data */
memcpy(p->outbuf + 5, data, data_len);
/* fill the padding area with random junk */
libssh2_random(p->outbuf + 5 + data_len, padding_length);
_libssh2_random(p->outbuf + 5 + data_len, padding_length);
if (free_data) {
LIBSSH2_FREE(session, data);
}
@@ -804,7 +818,7 @@ _libssh2_transport_write(LIBSSH2_SESSION * session, unsigned char *data,
unsigned char *ptr = &p->outbuf[i];
if (session->local.crypt->crypt(session, ptr,
&session->local.crypt_abstract))
return PACKET_FAIL; /* encryption failure */
return LIBSSH2_ERROR_SOCKET_NONE; /* encryption failure */
}
}
@@ -830,9 +844,9 @@ _libssh2_transport_write(LIBSSH2_SESSION * session, unsigned char *data,
p->olen = orgdata_len;
p->osent = (ret == -1) ? 0 : ret;
p->ototal_num = total_length;
return PACKET_EAGAIN;
return LIBSSH2_ERROR_EAGAIN;
}
return PACKET_FAIL;
return LIBSSH2_ERROR_SOCKET_NONE;
}
/* the whole thing got sent away */
@@ -841,5 +855,5 @@ _libssh2_transport_write(LIBSSH2_SESSION * session, unsigned char *data,
LIBSSH2_FREE(session, p->outbuf);
p->outbuf = NULL;
return PACKET_NONE; /* all is good */
return LIBSSH2_ERROR_NONE; /* all is good */
}

View File

@@ -2,7 +2,7 @@
#define __LIBSSH2_TRANSPORT_H
/* Copyright (C) 2007 The Written Word, Inc. All rights reserved.
* Copyright (C) 2009 by Daniel Stenberg
* Copyright (C) 2009-2010 by Daniel Stenberg
* Author: Daniel Stenberg <daniel@haxx.se>
*
* Redistribution and use in source and binary forms,
@@ -42,6 +42,7 @@
*/
#include "libssh2_priv.h"
#include "packet.h"
/*
* libssh2_transport_write
@@ -59,7 +60,7 @@
* (RFC4253 section 6.1)
*/
int _libssh2_transport_write(LIBSSH2_SESSION * session, unsigned char *data,
unsigned long data_len);
size_t data_len);
/*
* _libssh2_transport_read
*
@@ -77,4 +78,10 @@ int _libssh2_transport_write(LIBSSH2_SESSION * session, unsigned char *data,
*/
int _libssh2_transport_read(LIBSSH2_SESSION * session);
/*
* _libssh2_transport_drain() empties the outgoing send buffer if there
* is any.
*/
void _libssh2_transport_drain(LIBSSH2_SESSION *session);
#endif /* __LIBSSH2_TRANSPORT_H */

File diff suppressed because it is too large Load Diff

50
src/userauth.h Normal file
View File

@@ -0,0 +1,50 @@
#ifndef LIBSSH2_USERAUTH_H
#define LIBSSH2_USERAUTH_H
/* Copyright (c) 2004-2007, Sara Golemon <sarag@libssh2.org>
* Copyright (c) 2009-2010 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.
*/
int
_libssh2_userauth_publickey(LIBSSH2_SESSION *session,
const char *username,
unsigned int username_len,
const unsigned char *pubkeydata,
unsigned long pubkeydata_len,
LIBSSH2_USERAUTH_PUBLICKEY_SIGN_FUNC((*sign_callback)),
void *abstract);
#endif /* LIBSSH2_USERAUTH_H */

82
vms/libssh2_config.h Normal file
View File

@@ -0,0 +1,82 @@
#ifndef LIBSSH2_CONFIG_H
#ifdef __VMS
#define LIBSSH2_CONFIG_H
/* VMS specific libssh2_config.h
*/
#define ssize_t SSIZE_T
typedef unsigned int uint32_t ;
typedef unsigned int socklen_t; /* missing in headers on VMS */
/* Have's */
#define HAVE_UNISTD_H
#define HAVE_INTTYPES_H
#define HAVE_SYS_TIME_H
#define HAVE_SELECT
#define HAVE_UIO
#define HAVE_SYS_SOCKET.H
#define HAVE_NETINET_IN_H
#define HAVE_ARPA_INET_H
#define POSIX_C_SOURCE
/* Enable the possibility of using tracing */
#define LIBSSH2DEBUG 1
/* For selection of proper block/unblock function in session.c */
#define HAVE_FIONBIO
#include <stropts.h>
/* In VMS TCP/IP Services and some BSD variants SO_STATE retrieves
* a bitmask revealing amongst others the blocking state of the
* socket. On VMS the bits are undocumented, but SS_NBIO
* works, I did not test the other bits. Below bitdefs are
* from Berkely source socketvar.h at
* http://ftp.fibranet.cat/UnixArchive/PDP-11/Trees/2.11BSD/sys/h/socketvar.h
* Socket state bits.
* #define SS_NOFDREF 0x001 no file table ref any more
* #define SS_ISCONNECTED 0x002 socket connected to a peer
* #define SS_ISCONNECTING 0x004 in process of connecting to peer
* #define SS_ISDISCONNECTING 0x008 in process of disconnecting
* #define SS_CANTSENDMORE 0x010 can't send more data to peer
* #define SS_CANTRCVMORE 0x020 can't receive more data from peer
* #define SS_RCVATMARK 0x040 at mark on input
* #define SS_PRIV 0x080 privileged for broadcast, raw...
* #define SS_NBIO 0x100 non-blocking ops
* #define SS_ASYNC 0x200 async i/o notify
*
*/
#ifdef SO_STATE
/* SO_STATE is defined in stropts.h by DECC
* When running on Multinet, SO_STATE renders a protocol
* not started error. Functionally this has no impact,
* apart from libssh2 not being able to restore the socket
* to the proper blocking/non-blocking state.
*/
#define SS_NBIO 0x100
#endif
/* Compile in zlib support. We link against gnv$libzshr, as available
* on encompasserve.com.
*/
#define LIBSSH2_HAVE_ZLIB
/* Enable newer diffie-hellman-group-exchange-sha1 syntax */
#define LIBSSH2_DH_GEX_NEW 1
#endif /* __VMS */
#endif /* LIBSSH2_CONFIG_H */

View File

@@ -0,0 +1,124 @@
$!
$!
$ olddir = f$environment("default")
$ on control_y then goto YExit
$!
$ gosub Init
$ if .not. init_status then goto YExit
$!
$ if what .eqs. "ALL"
$ then
$ call MakeAll
$ else
$ call Make
$endif
$!
$YExit:
$ set noon
$! deassign exadir
$! deassign objdir
$ delete 'link_opts';*
$ set default 'olddir'
$exit
$MakeAll: subroutine
$!
$ set noon
$Loop:
$ this = f$search("exadir:*.c;0")
$ if this .eqs. "" then goto EndLoop
$!
$ what = f$parse( this,,,"name")
$ call Make
$!
$ goto Loop
$EndLoop:
$!
$exit
$endsubroutine
$Make: subroutine
$!
$ set noon
$!
$ cc 'cc_include' 'cc_flags'/object=objdir:'what' exadir:'what'
$ sev = $severity
$ if sev .and. 2
$ then
$ say "Error compiling ''what', not linked."
$ else
$ if .not. (sev .and. 1)
$ then
$ say "Compile warnings in ''what'"
$ endif
$ link/exe='what'.exe objdir:'what'.obj, 'link_opts'/opt
$ endif
$!
$!
$End:
$ delete objdir:'what'.obj;*
$exit
$endsubroutine
$Init:
$!
$!
$ init_status = 1
$ thisid = f$integer( %x'f$getjpi(0,"pid")') + "''f$cvtime(,,"second")'"
$ mdir = f$environment("procedure")
$ mdir = mdir - f$parse(mdir,,,"name") - f$parse(mdir,,,"type") - f$parse(mdir,,,"version")
$ set default 'mdir'
$!
$ objdir = "[.example_objects]"
$ exadir = "[-.example]"
$!
$ objdirfile = objdir - "[." - "]" + ".dir"
$ if f$search( objdirfile ) .eqs. ""
$ then
$ create/directory 'objdir'
$ endif
$!
$ define objdir 'objdir'
$ define exadir 'exadir'
$!
$ cc_include = "/include=([],[-.include])"
$ cc_flags = "/name=shortened/show=all"
$ link_opts = "objdir:libssh2_''thisid'.opt"
$!
$!
$ what = "''p1'"
$ if what .eqs. "" .or. f$edit(p1,"trim,collapse,upcase") .eqs. "ALL"
$ then
$ what = "ALL"
$ else
$ what = f$parse(what,,,"name")
$ if f$search("exadir:''what'.c") .eqs. ""
$ then
$ write sys$output "Can't make ''what'"
$ init_status = 0
$ endif
$ endif
$!
$ currentlib = f$search("libssh2*.exe")
$!
$ define libssh2 'currentlib'
$!
$ how = "''p2'"
$ if how .eqs. "" .or. f$edit(p2,"trim,collapse,upcase") .eqs. "STATIC"
$ then
$ open/write lout 'link_opts'
$ write lout "libssh2.olb/lib"
$ write lout "sys$share:ssl$libcrypto_shr32.exe/share"
$ write lout "sys$share:ssl$libssl_shr32.exe/share"
$ write lout "gnv$libzshr/share"
$ close lout
$ else
$ how = "SHARED"
$ open/write lout 'link_opts'
$ write lout "libssh2/share"
$ close lout
$ endif
$!
$return

91
vms/libssh2_make_help.dcl Normal file
View File

@@ -0,0 +1,91 @@
$!
$!
$!
$ olddir = f$environment( "default" )
$ on control_y then goto End
$ on error then goto End
$!
$ gosub Init
$!
$ man2help sys$input: libssh2.hlp -b 1
LIBSSH2
OpenVMS port of the public domain libssh2 library, which
provides an API to implement client SSH communciation.
License information is available at the copying subtopic.
$!
$ open/append mh libssh2.hlp
$ write mh helpversion
$ close mh
$!
$ man2help -a [-]readme.; libssh2.hlp -b 2
$ man2help -a [-]authors.; libssh2.hlp -b 2
$ man2help -a [-]copying.; libssh2.hlp -b 2
$ man2help -a [-]news.; libssh2.hlp -b 2
$ man2help -a [-]release-notes.; libssh2.hlp -b 2
$ man2help -a [-]hacking.; libssh2.hlp -b 2
$ man2help -a [-]todo.; libssh2.hlp -b 2
$!
$ man2help -a sys$input: libssh2.hlp -b 2
API_Reference
Reference of all implemented API calls in
libssh2.
$!
$ man2help -a [-.docs]*.3 libssh2.hlp -b 3 -p
$!
$ library/help/create libssh2.hlb libssh2.hlp
$!
$End:
$ set default 'olddir'
$exit
$!
$!-------------------------------------------------------
$!
$Init:
$!
$ thisdir = f$environment( "procedure" )
$ thisdir = f$parse(thisdir,,,"device") + f$parse(thisdir,,,"directory")
$ set default 'thisdir'
$!
$ say = "write sys$output"
$!
$ pipe search [-.include]*.h libssh2_version_major/nohead | (read sys$input l ; l = f$element(2," ",f$edit(l,"trim,compress")) ; -
define/job majorv &l )
$ pipe search [-.include]*.h libssh2_version_minor/nohead | (read sys$input l ; l = f$element(2," ",f$edit(l,"trim,compress")) ; -
define/job minorv &l )
$ pipe search [-.include]*.h libssh2_version_patch/nohead | (read sys$input l ; l = f$element(2," ",f$edit(l,"trim,compress")) ; -
define/job patchv &l )
$!
$ majorv = f$trnlnm("majorv")
$ minorv = f$integer(f$trnlnm("minorv"))
$ patchv = f$integer( f$trnlnm("patchv"))
$!
$ helpversion = "This help library is based on build version ''majorv'.''minorv'.''patchv' of libssh2."
$!
$ deassign/job majorv
$ deassign/job minorv
$ deassign/job patchv
$!
$ if f$search( "man2help.exe" ) .eqs. ""
$ then
$ cc man2help
$ link man2help
$ endif
$!
$ man2help := $'thisdir'man2help.exe
$!
$ if f$search("libssh2.hlp") .nes. ""
$ then
$ delete libssh2.hlp;*
$ endif
$ if f$search("libssh2.hlb") .nes. ""
$ then
$ delete libssh2.hlb;*
$ endif
$return

222
vms/libssh2_make_kit.dcl Normal file
View File

@@ -0,0 +1,222 @@
$!
$ olddir = f$environment("default")
$ on error then goto End
$!
$ gosub Init
$!
$ call WriteProductDescriptionFile
$ call WriteProductTextFile
$!
$! backup tree
$!
$ backup [-...]*.*;0/excl=([]*.exe,*.obj,*.opt,*.hlp,*.hlb,*.bck,*.com,*.pcsi*) -
libssh2-'versionname''datename'_src.bck/save
$ purge libssh2-'versionname''datename'_src.bck
$!
$! backup examples
$!
$ backup [-.example]*.c;0 libssh2_examples-'versionname''datename'.bck/save
$ dire libssh2_examples-'versionname''datename'.bck
$ purge libssh2_examples-'versionname''datename'.bck
$!
$ set default [-]
$!
$ defdir = f$environment( "default" )
$ thisdev = f$parse(defdir,,,"device","no_conceal")
$ thisdir = f$parse(defdir,,,"directory","no_conceal") - "][" - "][" - "][" - "]["
$!
$ libssh2_kf = thisdev + thisdir
$ libssh2_kf = libssh2_kf - "]" + ".]"
$!
$ set default 'mdir'
$!
$ define/translation_attributes=concealed libssh2_kf 'libssh2_kf'
$!
$ product package libssh2 -
/base='arch' -
/producer=jcb -
/source=[] - ! where to find PDF and PTF
/destination=[] - ! where to put .PCSI file
/material=libssh2_kf:[000000...] - ! where to find product material
/version="''vms_majorv'.''minorv'-''patchv'''datename'" -
/format=sequential
$!
$End:
$!
$ set noon
$ if f$search("*.pcsi$desc;*") .nes. "" then delete *.pcsi$desc;*
$ if f$search("*.pcsi$text;*") .nes. "" then delete *.pcsi$text;*
$ if f$search("libssh2-''versionname'''datename'_src.bck;*") .nes. "" then delete libssh2-'versionname''datename'_src.bck;*
$ if f$search("libssh2_examples-''versionname'''datename'.bck;*") .nes. "" then delete libssh2_examples-'versionname''datename'.bck;*
$!
$ if f$trnlnm("libssh2_kf") .nes. "" then deassign libssh2_kf
$ set default 'olddir'
$!
$exit
$!
$!--------------------------------------------------------------------------------
$!
$Init:
$ set process/parse=extended
$!
$ say = "write sys$output"
$!
$ mdir = f$environment("procedure")
$ mdir = mdir - f$parse(mdir,,,"name") - f$parse(mdir,,,"type") - f$parse(mdir,,,"version")
$!
$ set default 'mdir'
$!
$ pipe search [-.include]*.h libssh2_version_major/nohead | (read sys$input l ; l = f$element(2," ",f$edit(l,"trim,compress")) ; -
define/job majorv &l )
$ pipe search [-.include]*.h libssh2_version_minor/nohead | (read sys$input l ; l = f$element(2," ",f$edit(l,"trim,compress")) ; -
define/job minorv &l )
$ pipe search [-.include]*.h libssh2_version_patch/nohead | (read sys$input l ; l = f$element(2," ",f$edit(l,"trim,compress")) ; -
define/job patchv &l )
$!
$ majorv = f$trnlnm("majorv")
$ minorv = f$integer(f$trnlnm("minorv"))
$ patchv = f$integer( f$trnlnm("patchv"))
$!
$ deassign/job majorv
$ deassign/job minorv
$ deassign/job patchv
$!
$ vms_majorv = f$trnlnm("vms_majorv")
$ if vms_majorv .eqs. "" then vms_majorv = majorv
$!
$ arch = "UNKNOWN"
$ if f$getsyi("arch_type") .eq. 2 then arch = "AXPVMS"
$ if f$getsyi("arch_type") .eq. 3 then arch = "I64VMS"
$!
$ if arch .eqs. "UNKNOWN"
$ then
$ say "Unsupported or unknown architecture, only works on Alpha and Itanium"
$ exit 2
$ endif
$!
$! is this a proper release or a daily snapshot?
$! crummy, but should work.
$!
$ daily = "TRUE"
$ firstdash = f$locate("-",mdir)
$ restdir = f$extract( firstdash + 1, 80, mdir)
$ seconddash = f$locate("-", restdir)
$ if seconddash .ge. f$length( restdir )
$ then
$ daily = "FALSE"
$ datename = "Final"
$ else
$ datename = "D" + f$extract(seconddash+1,8,restdir)
$ endif
$!
$ if daily
$ then
$ productname = "JCB ''arch' LIBSSH2 V''vms_majorv'.''minorv'-''patchv'''datename'"
$ else
$ productname = "JCB ''arch' LIBSSH2 V''vms_majorv'.''minorv'-''patchv'''datename'"
$ endif
$!
$ productfilename = "JCB-''arch'-LIBSSH2-" + f$fao("V!2ZL!2ZL-!2ZL!AS-1", f$integer(vms_majorv),minorv,patchv,datename)
$!
$ versionname = "''vms_majorv'_''minorv'_''patchv'"
$!
$return
$!
$!--------------------------------------------------------------------------------
$!
$WriteProductDescriptionFile: subroutine
$!
$ open/write pd 'productfilename'.PCSI$DESC
$!
$ write pd "product ''productname' full ;"
$ write pd " software DEC ''arch' VMS ;"
$ write pd " if (not <software DEC ''arch' VMS version minimum V8.3>) ;
$ write pd " error NEED_VMS83 ;"
$ write pd " end if ;"
$ write pd " software HP ''arch' SSL version minimum V1.3;"
$ write pd " if (not <software HP ''arch' SSL version minimum V1.3>) ;
$ write pd " error NEED_SSL ;"
$ write pd " end if ;"
$ write pd " execute preconfigure (""set process/parse_type=extended"");"
$ write pd " execute postinstall (""set process/parse_type=extended"","
$ write pd " ""rename pcsi$destination:[gnv]usr.dir usr.DIR"","
$ write pd " ""rename pcsi$destination:[gnv.usr]include.dir include.DIR"","
$ write pd " ""rename pcsi$destination:[gnv.usr.include]libssh2.dir libssh2.DIR"","
$ write pd " ""rename pcsi$destination:[gnv.usr.include.libssh2]libssh2.h libssh2.h"","
$ write pd " ""rename pcsi$destination:[gnv.usr.include.libssh2]libssh2_publickey.h libssh2_publickey.h"","
$ write pd " ""rename pcsi$destination:[gnv.usr.include.libssh2]libssh2_sftp.h libssh2_sftp.h"","
$ write pd " ""rename pcsi$destination:[gnv.usr.include.libssh2]libssh2_config.h libssh2_config.h"","
$ write pd " ""rename pcsi$destination:[gnv.usr]lib.dir lib.DIR"","
$ write pd " ""rename pcsi$destination:[gnv.usr.lib]gnv$libssh2_''versionname'.exe gnv$libssh2_''versionname'.exe"","
$ write pd " ""rename pcsi$destination:[gnv.usr.share.doc.libssh2]libssh2.hlb libssh2.hlb"");"
$ write pd " information RELEASE_NOTES phase after ;"
$ write pd " option EXAMPLE default 0 ;"
$ write pd " directory ""[gnv.usr.share.doc.libssh2.examples]"" ;"
$ write pd " file ""[gnv.usr.share.doc.libssh2.examples]libssh2_examples-''versionname'''datename'.bck"";"
$ write pd " end option ;"
$ write pd " option SOURCE default 0 ;"
$ write pd " directory ""[gnv.common_src]"" ;"
$ write pd " file ""[gnv.common_src]libssh2-''versionname'''datename'_src.bck"";"
$ write pd " end option ;"
$ write pd " directory ""[gnv]"" ;"
$ write pd " directory ""[gnv.usr]"" ;"
$ write pd " directory ""[gnv.usr.lib]"" ;"
$ write pd " directory ""[gnv.usr.include]"" ;"
$ write pd " directory ""[gnv.usr.include.libssh2]"" ;"
$ write pd " directory ""[gnv.usr.share]"" ;"
$ write pd " directory ""[gnv.usr.share.doc]"" ;"
$ write pd " directory ""[gnv.usr.share.doc.libssh2]"" ;"
$ write pd " file ""[gnv.usr.include.libssh2]libssh2.h"" source ""[include]libssh2.h"";"
$ write pd " file ""[gnv.usr.include.libssh2]libssh2_publickey.h"" source ""[include]libssh2_publickey.h"";"
$ write pd " file ""[gnv.usr.include.libssh2]libssh2_sftp.h"" source ""[include]libssh2_sftp.h"";"
$ write pd " file ""[gnv.usr.include.libssh2]libssh2_config.h"" source ""[vms]libssh2_config.h"";"
$ write pd " file ""[gnv.usr.share.doc.libssh2]libssh2.hlb"" source ""[vms]libssh2.hlb"";"
$ write pd " file ""[gnv.usr.share.doc.libssh2]libssh2-''versionname'.news"" source ""[000000]NEWS."";"
$ write pd " file ""[gnv.usr.share.doc.libssh2]libssh2-''versionname'.release_notes"" source ""[vms]readme.vms"";"
$ write pd " file ""[gnv.usr.lib]gnv$libssh2_''versionname'.exe"" source ""[vms]libssh2_''versionname'.exe"";"
$ write pd "end product ;"
$ close pd
$exit
$endsubroutine
$!
$!--------------------------------------------------------------------------------
$!
$WriteProductTextFile: subroutine
$!
$ open/write pt 'productfilename'.PCSI$TEXT
$ write pt "=PRODUCT ''productname' Full"
$ write pt "1 'PRODUCER"
$ write pt "=prompt libssh2 is an open source product ported to VMS by Jose Baars"
$ write pt "This software product is provided with no warranty."
$ write pt "For license information see the LIBSSH2 help library."
$ write pt "1 'PRODUCT"
$ write pt "=prompt JCB LIBSSH2 for OpenVMS"
$ write pt ""
$ write pt "libssh2 is an open source client side library that aims to implement"
$ write pt "the SSH protocol. This is the OpenVMS port of that library."
$ write pt "Further information at http://www.libssh2.org."
$ write pt ""
$ write pt "1 NEED_VMS83"
$ write pt "=prompt OpenVMS 8.3 or later is not installed on your system."
$ write pt "This product requires OpenVMS 8.3 or later to function."
$ write pt ""
$ write pt "1 NEED_SSL"
$ write pt "=prompt HP SSL 1.3 or later is not installed on your system."
$ write pt "This product requires HP SSL 1.3 or later to function."
$ write pt ""
$ write pt "1 RELEASE_NOTES"
$ write pt "=prompt Release notes and the libssh2 help library are available in [gnv.usr.share.doc.libssh2] directory."
$ write pt ""
$ write pt "1 EXAMPLE"
$ write pt "=prompt Do you want the libssh2 C programming examples ? "
$ write pt "The libssh2 coding examples will be available in backup saveset "
$ write pt "[gnv.usr.share.doc.libssh2.examples]libssh2_examples_''versionname'.bck"
$ write pt ""
$ write pt "1 SOURCE"
$ write pt "=prompt Do you want the complete libssh2 source tree ? "
$ write pt "The libssh2 source tree will be available in backup saveset "
$ write pt "[gnv.common_src]libssh2_''versionname'''datename'_src.bck"
$close pt
$exit
$ endsubroutine

344
vms/libssh2_make_lib.dcl Normal file
View File

@@ -0,0 +1,344 @@
$!
$!
$ olddir = f$environment("default")
$ on control_y then goto YExit
$!
$ gosub Init
$ if .not. init_status then goto YExit
$!
$ call CompileAll
$ call BuildTransferVectors
$ call LinkShared
$!
$ call Cleanup
$!
$YExit:
$ set noon
$!
$ deassign srcdir
$ if f$search("objdir:*.*;*") .nes. "" then delete objdir:*.*;*
$ deassign objdir
$ delete library_objects.dir;*
$!
$ set default 'olddir'
$exit
$!
$!---------------------------------------------------------------------
$!
$Init:
$!
$!
$ init_status = 1
$ thisid = f$integer( %x'f$getjpi(0,"pid")')
$ mdir = f$environment("procedure")
$ mdir = mdir - f$parse(mdir,,,"name") - f$parse(mdir,,,"type") - f$parse(mdir,,,"version")
$ set default 'mdir'
$!
$ objdir = "[.library_objects]"
$ srcdir = "[-.src]"
$!
$ objdirfile = objdir - "[." - "]" + ".dir"
$ if f$search( objdirfile ) .eqs. ""
$ then
$ create/directory 'objdir'
$ endif
$!
$ define objdir 'objdir'
$ define srcdir 'srcdir'
$!
$ cc_include = "/include=([],[-.include])"
$ link_opts = "objdir:libssh2_''thisid'.opt"
$!
$ pipe search [-.include]libssh2.h libssh2_version_major/nohead | (read sys$input l ; l = f$element(2," ",f$edit(l,"trim,compress")) ; -
define/job majorv &l )
$ pipe search [-.include]libssh2.h libssh2_version_minor/nohead | (read sys$input l ; l = f$element(2," ",f$edit(l,"trim,compress")) ; -
define/job minorv &l )
$ pipe search [-.include]libssh2.h libssh2_version_patch/nohead | (read sys$input l ; l = f$element(2," ",f$edit(l,"trim,compress")) ; -
define/job patchv &l )
$!
$ majorv = f$trnlnm("majorv")
$ minorv = f$integer(f$trnlnm("minorv"))
$ patchv = f$integer( f$trnlnm("patchv"))
$!
$ OLBONLY = "FALSE"
$ if p1 .eqs. "OLBONLY"
$ then
$ OLBONLY = "TRUE"
$ endif
$!
$ deassign/job majorv
$ deassign/job minorv
$ deassign/job patchv
$!
$return
$!
$!---------------------------------------------------------------------
$!
$Cleanup: subroutine
$!
$ set noon
$ purge *.opt
$ purge *.olb
$ purge *.exe
$!
$exit 1
$endsubroutine
$!
$!---------------------------------------------------------------------
$!
$LinkShared: subroutine
$!
$!
$!
$ cversion = f$fao("!3ZL",minorv) + f$fao("!3ZL",patchv)
$!
$! General linking options in link_libssh2_version...opt
$! Vectors in link_libssh2_vectors...opt
$!
$ open/write uitv link_libssh2_version_'majorv'_'minorv'_'patchv'.opt
$ write uitv "GSMATCH=LEQUAL,''majorv',''cversion'"
$ write uitv "IDENTIFICATION=""LIBSSH2 ''majorv'.''minorv'.''patchv'"""
$ write uitv "sys$share:ssl$libcrypto_shr32.exe/share"
$ write uitv "sys$share:ssl$libssl_shr32.exe/share"
$ write uitv "gnv$libzshr/share"
$ close uitv
$!
$ link/shared/exe=libssh2_'majorv'_'minorv'_'patchv'.exe -
libssh2.olb/lib, -
link_libssh2_version_'majorv'_'minorv'_'patchv'.opt/opt, -
link_libssh2_vectors_'majorv'_'minorv'_'patchv'.opt/opt
$!
$exit
$endsubroutine
$!
$!---------------------------------------------------------------------
$!
$CompileAll: subroutine
$!
$ set noon
$!
$ if f$search("objdir:*.obj;*") .nes ""
$ then
$ delete objdir:*.obj;*
$ endif
$ if f$search("[.cxx_repository]cxx$demangler_db.;") .nes ""
$ then
$ delete [.cxx_repository]cxx$demangler_db.;*
$ endif
$!
$! Compile all .c files in [-.src], first as_is
$! and then as default all uppercase names
$! and add the resulting object to object libraries
$! libssh2_up.olb and libssh2_as_is.olb.
$!
$ case = 0
$ if OLBONLY then case = 1
$CaseLoop:
$!
$ if case .eq. 0
$ then!camel case names
$ cc_flags = "/names=(shortened,as_is)"
$ objlib = "libssh2_asis.olb"
$ endif
$!
$ if case .eq. 1
$ then!uppercase names
$ if f$search("[.cxx_repository]cxx$demangler_db.;") .nes ""
$ then
$ rename [.cxx_repository]cxx$demangler_db.; *.lowercase
$ purge [.cxx_repository]cxx$demangler_db.lowercase
$ endif
$!
$ cc_flags = "/names=(shortened)"
$ objlib = "libssh2_up.olb"
$ endif
$!
$ if f$search("''objlib';*") .nes. "" then delete 'objlib';*
$ library/create 'objlib'
$!
$Loop:
$ this = f$search("srcdir:*.c;0")
$ if this .eqs. "" then goto EndLoop
$!
$ what = f$parse( this,,,"name")
$!
$ call CompileAndAdd
$!
$ goto Loop
$EndLoop:
$ case = case + 1
$ delete objdir:*.obj;*
$ if case .lt 2 then goto CaseLoop
$!
$ rename libssh2_up.olb libssh2.olb
$ if f$search("[.cxx_repository]cxx$demangler_db.;") .nes ""
$ then
$ rename [.cxx_repository]cxx$demangler_db.; *.uppercase
$ purge [.cxx_repository]cxx$demangler_db.uppercase
$ endif
$!
$ if OLBONLY then exit 4
$!
$! For each function that is too long, create a global symbol
$! low$'shortened-uppercase-name' with as value lowercase shortened
$! name in it, so we can add the proper lower or mixed case
$! shortened name later when building the transfer vectors
$! for the shared image.
$! This is to prevent two very long similar function names
$! that are shortened getting mixed up when sorted alphabetically.
$!
$ inputfile = "[.cxx_repository]cxx$demangler_db.lowercase"
$ gosub GetShortened
$!
$ inputfile = "[.cxx_repository]cxx$demangler_db.uppercase"
$ gosub GetShortened
$!
$exit
$!
$GetShortened:
$!
$ open/read s 'inputfile'
$ namecount = 0
$ReadLoop:
$!
$ read/end=endreadloop s regel
$!
$ shortname = f$element(0,"$",regel) + "$"
$ longname = f$element(1,"$",regel)
$!
$ symvalue = ""
$!
$ if shortname .eqs. f$edit(shortname,"upcase")
$ then
$! this is an uppercase shortname, add it
$ symname = "u$''longname'"
$ symvalue = "''shortname'"
$ low$'shortname' == l$'longname'
$!
$ delete/symbol l$'longname'
$!
$ else
$! this is an lowercase shortname
$ symname = "l$''longname'"
$ symvalue = "''shortname'"
$ 'symname' = "''symvalue'"
$ endif
$!
$ namecount = namecount + 1
$!
$ goto ReadLoop
$EndReadLoop:
$!
$close s
$return
$!
$endsubroutine
$!
$!---------------------------------------------------------------------
$!
$CompileAndAdd: subroutine
$!
$ on error then goto End
$!
$ cc /warn=disable=longextern/lis=objdir:/show=all 'cc_include' 'cc_flags'/object=objdir:'what'.obj srcdir:'what'.c
$ library/insert 'objlib' objdir:'what'.obj
$!
$End:
$exit
$endsubroutine
$!
$!---------------------------------------------------------------------
$!
$BuildTransferVectors: subroutine
$!
$! Do a balanced read of the uppercase library names
$! and the mixed case library names, and build the
$! transfer vectors with uppercase entry points
$! with an alternative in mixed case.
$! For shortened names, use the low$* symbols
$! to avoid being fooled by the sort.
$!
$ thislib = "libssh2.olb"
$ library/lis=libu.'thisid'/names libssh2.olb
$ library/lis=lib_asisu.'thisid'/names libssh2_asis.olb
$!
$! case blind sort of all modules in both the uppercase
$! as the case sensitive object library.
$!
$ sort libu.'thisid' lib.'thisid'/spec=sys$input
/COLLATING_SEQUENCE=(SEQUENCE= ("A" - "Z","0"-"9","_"), FOLD)
$ sort lib_asisu.'thisid' lib_asis.'thisid'/spec=sys$input
/COLLATING_SEQUENCE=(SEQUENCE= ("A" - "Z","0"-"9","_"), FOLD)
$!
$ open/read in lib.'thisid'
$ open/read inasis lib_asis.'thisid'
$ open/write uit link_libssh2_vectors_'majorv'_'minorv'_'patchv'.opt
$!
$ write uit "CASE_SENSITIVE=YES"
$ write uit "SYMBOL_VECTOR= ( -"
$!
$ mode = 0
$ uitregel = ""
$!
$ReadLoop:
$!
$ read/end=ReadAsis in regel
$ReadAsis:
$ read/end=EndReadLoop inasis asisregel
$!
$ regel = f$edit( regel, "trim,compress" )
$ asisregel = f$edit( asisregel, "trim,compress" )
$!
$ if f$element(0," ",regel) .eqs. "Module" .or. -
f$extract(0,1,regel) .eqs. "_" .or. -
f$element(1," ",regel) .nes. " " .or. -
regel .eqs. ""
$ then
$ goto ReadLoop
$ endif
$!
$ if uitregel .nes. "" .and. mode .eq. 1
$ then
$ write uit "''uitregel'=PROCEDURE, -"
$ write uit "''uitasis'/''uitregel'=PROCEDURE, -"
$!
$ uitregel = ""
$ uitasis = ""
$ endif
$!
$ uitregel = regel
$ if f$type( low$'uitregel' ) .nes. ""
$ then
$ uitasis = low$'uitregel'
$ delete/symbol/global low$'uitregel'
$ else
$ uitasis = asisregel
$ endif
$!
$ mode = 1
$!
$ goto ReadLoop
$EndreadLoop:
$!
$! To get the closing brace after the last procedure
$! keyword.
$!
$ if uitregel .nes. ""
$ then
$ write uit "''uitregel'=PROCEDURE, -"
$ write uit "''uitasis'/''uitregel'=PROCEDURE)"
$ endif
$!
$ write uit "CASE_SENSITIVE=NO"
$!
$ close in
$ close inasis
$ close uit
$!
$ delete lib*.'thisid';*
$!
$exit
$endsubroutine
$!
$!---------------------------------------------------------------------
$!

516
vms/man2help.c Normal file
View File

@@ -0,0 +1,516 @@
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include <errno.h>
#include <starlet.h>
#include <lib$routines.h>
#include <ssdef.h>
#include <descrip.h>
#include <rms.h>
typedef struct manl{
struct manl *next;
char *filename;
}man, *manPtr;
typedef struct pf_fabnam{
struct FAB dfab;
struct RAB drab;
struct namldef dnam;
char expanded_filename[NAM$C_MAXRSS + 1];
} pfn, *pfnPtr;
/*----------------------------------------------------------*/
fpcopy( char *output, char *input, int len )
{
char *is, *os;
int i;
if ( len ){
for ( is = input, os = output, i = 0; i < len ; ++i, ++is, ++os){
*os = *is;
}
*os = 0;
}else{
output[0] = 0;
}
}
/*----------------------------------------------------------*/
/* give part of ilename in partname. See code for proper
value of i ( 0 = node, 1 = dev, 2 = dir,3 = name etc.
*/
int fnamepart( char *inputfile, char *part, int whatpart )
{
pfnPtr pf;
int status;
char ipart[6][256], *i, *p;
pf = calloc( 1, sizeof( pfn ) );
pf->dfab = cc$rms_fab;
pf->drab = cc$rms_rab;
pf->dnam = cc$rms_naml;
pf->dfab.fab$l_naml = &pf->dnam;
pf->dfab.fab$l_fna = (char *) -1;
pf->dfab.fab$l_dna = (char *) -1;
pf->dfab.fab$b_fns = 0;
pf->dfab.fab$w_ifi = 0;
pf->dnam.naml$l_long_defname = NULL; //inputfile;
pf->dnam.naml$l_long_defname_size = 0;//strlen( inputfile );
pf->dnam.naml$l_long_filename = inputfile;
pf->dnam.naml$l_long_filename_size = strlen( inputfile);
pf->dnam.naml$l_long_expand = pf->expanded_filename;
pf->dnam.naml$l_long_expand_alloc = NAM$C_MAXRSS ;
pf->dnam.naml$b_nop |= NAML$M_SYNCHK | NAML$M_PWD;
status = sys$parse( &pf->dfab, 0,0);
if ( !(status&1) ){
free( pf );
return( status );
}
fpcopy ( ipart[0], pf->dnam.naml$l_long_node , pf->dnam.naml$l_long_node_size);
fpcopy ( ipart[1], pf->dnam.naml$l_long_dev , pf->dnam.naml$l_long_dev_size);
fpcopy ( ipart[2], pf->dnam.naml$l_long_dir , pf->dnam.naml$l_long_dir_size);
fpcopy ( ipart[3], pf->dnam.naml$l_long_name , pf->dnam.naml$l_long_name_size);
fpcopy ( ipart[4], pf->dnam.naml$l_long_type , pf->dnam.naml$l_long_type_size);
fpcopy ( ipart[5], pf->dnam.naml$l_long_ver , pf->dnam.naml$l_long_ver_size);
for( i = ipart[ whatpart ], p = part; *i; ++i, ++p){
if ( p == part ){
*p = toupper( *i );
}else{
*p = tolower( *i );
}
}
*p = 0;
free( pf );
return(1);
}
/*----------------------------------------------------------*/
int find_file(char *filename,char *gevonden,int *findex)
{
int status;
struct dsc$descriptor gevondend;
struct dsc$descriptor filespec;
char gevonden_file[NAM$C_MAXRSS + 1];
filespec.dsc$w_length = strlen(filename);
filespec.dsc$b_dtype = DSC$K_DTYPE_T;
filespec.dsc$b_class = DSC$K_CLASS_S;
filespec.dsc$a_pointer = filename;
gevondend.dsc$w_length = NAM$C_MAXRSS;
gevondend.dsc$b_dtype = DSC$K_DTYPE_T;
gevondend.dsc$b_class = DSC$K_CLASS_S;
gevondend.dsc$a_pointer = gevonden_file;
status=lib$find_file(&filespec,&gevondend,findex,0,0,0,0);
if ( (status & 1) == 1 ){
strcpy(gevonden,strtok(gevonden_file," "));
}else{
gevonden[0] = 0;
}
return(status);
}
/*--------------------------------------------*/
manPtr addman( manPtr *manroot,char *filename )
{
manPtr m,f;
m = calloc( 1, sizeof( man) );
if ( !m ) return( NULL );
m->filename = strdup( filename );
if ( *manroot == NULL ){
*manroot = m;
}else{
for( f = *manroot; f->next ; f = f->next );
f->next = m;
}
return(m);
}
/*--------------------------------------------*/
void freeman( manPtr *manroot )
{
manPtr m,n;
for( m = *manroot; m ; m = n ){
free( m->filename );
n = m->next;
free ( m );
}
*manroot = NULL;
}
/*--------------------------------------------*/
int listofmans( char *filespec, manPtr *manroot )
{
manPtr r;
int status;
int ffindex=0;
char gevonden[NAM$C_MAXRSS + 1];
while(1){
status = find_file( filespec, gevonden, &ffindex );
if ( (status&1) ){
r = addman( manroot, gevonden );
if ( r == NULL ) return(2);
}else{
if ( !( status&1)) break;
}
}
lib$find_file_end( &ffindex);
if ( status == RMS$_NMF) status = 1;
return( status );
}
/*--------------------------------------------*/
int convertman ( char *filespec, FILE *hlp , int base_level, int add_parentheses )
{
FILE *man;
char *in, *uit;
char *m,*h;
size_t len, thislen, maxlen= 50000;
int bol,mode, return_status=1;
char subjectname[ NAM$C_MAXRSS + 1 ];
in = calloc( 1, maxlen + 1 );
uit = calloc( 1, maxlen + 1 );
if ( in == NULL || uit == NULL ) return(2);
man = fopen( filespec, "r");
if ( man == NULL ) return(vaxc$errno);
for( len = 0; !feof( man ) && len < maxlen ; len += thislen ){
thislen = fread( in + len, 1, maxlen - len, man );
}
fclose (man);
m = in;
h = uit;
*(m + len ) = 0;
for ( mode = 0, bol = 1 ; *m; ++m ){
switch ( mode ){
case 0:
switch(*m){
case '.':
if ( bol ){
mode = 1;
}else{
*h = *m;
++h;
}
break;
case '\\':
if ( bol ){
*h = ' ';++h;
*h = ' ';++h;
}
mode = 2;
break;
default:
if ( bol ){
*h = ' ';++h;
*h = ' ';++h;
}
*h = *m;
++h;
break;
}
break;
case 1: /* after . at bol */
switch(*m){
case '\\':
while( *m != '\n' && *m != '\r' && *m )++m;
mode = 0;
break;
case 'B':
++m;
*h = ' ';++h;
mode = 0;
break;
case 'I':
/* remove preceding eol */
if ( *(m+1) != 'P' ){
--h;
while ( (*h == '\n' || *h == '\r') && h > uit )--h;
++h;
}
/* skip .Ix */
for(;*m != ' ' && *m != '\n' && *m != '\r'; ++m);
/* copy line up to EOL */
for(;*m != '\n' && *m != '\r' && *m; ++m, ++h)*h = *m;
/* if line ends in ., this is an EOL */
if ( *(h-1) == '.'){
--h;
--m;
}else{
/* if line does not end in ., skip EOL in source */
if ( *(m+1) == '\n' || *(m+1) == '\r')++m;
}
mode = 0;
break;
case 'S':
if ( *(m+1) == 'H' ){
*h = '\n';++h;
if ( strncmp( m+3 ,"NAME",4) == 0 ||
strncmp( m+3 ,"SYNOPSIS",8) == 0 ||
strncmp( m+3 ,"DESCRIPTION",11) == 0 ){
while( *m != '\n' && *m != '\r')++m;
mode = 0;
}else{
++m;
/* write help level, and flag it */
*h = '0' + base_level + 1;++h;
return_status |= 2;
*h = ' ';++h;
/* skip H (or whatever after S) and blank */
++m;++m;
for(;*m != '\n' && *m != '\r' && *m; ++m, ++h){
/* write help label in lowercase, skip quotes */
/* fill blanks with underscores */
if ( *m != '\"' ){
*h = tolower( *m );
if (*h == ' ') *h = '_';
}else{
--h;
}
}
/* Add a linefeed or two */
*h = *m;++h;
*h = *m;++h;
mode = 0;
}
}
break;
case 'T':
if ( *(m+1) == 'H' ){
*h = '0' + base_level; ++h;
return_status |= 2;
*h = ' ';++h;
for ( m = m + 3; *m != ' ' && *m ; ++m, ++h ){
*h = *m;
}
if ( add_parentheses ){
*h = '(';++h;
*h = ')';++h;
}
while( *m != '\n' && *m != '\r' && *m )++m;
mode = 0;
}
break;
default:
++m;
mode = 0;
break;
}
break;
case 2: /* after \ skip two characters or print the backslash */
switch(*m){
case '\\':
*h = *m;
++h;
mode = 0;
break;
default:
++m;
mode = 0;
break;
}
break;
} /*end switch mode */
bol = 0;
if ( *m == '\n' || *m == '\r') bol = 1;
}/* end for mode */
*h = 0;
if ( (return_status&2) ){
fprintf( hlp, "%s\n\n", uit);
}else{
fnamepart( filespec, subjectname,3);
if ( *subjectname ){
fprintf( hlp, "%d %s\n\n%s\n\n", base_level, subjectname, uit);
}else{
/* No filename (as is the case with a logical), use first word as subject name */
char *n,*s;
for(n = in; isspace( *n );++n);
for(s = subjectname; !(isspace( *n )); ++n,++s)*s = *n;
*s = 0;
fprintf( hlp, "%d %s\n\n%s\n\n", base_level, subjectname, uit);
}
}
/*
printf( "read %d from %s, written %d to helpfile, return_status = %d\n",
len, filespec, strlen(uit), return_status );
*/
free( m );
free( h );
return ( 1);
}
/*--------------------------------------------*/
int convertmans( char *filespec, char *hlpfilename, int base_level, int append, int add_parentheses )
{
int status=1;
manPtr manroot=NULL, m;
FILE *hlp;
if ( append ){
hlp = fopen( hlpfilename,"a+");
}else{
hlp = fopen( hlpfilename,"w");
}
if ( hlp == NULL ) return( vaxc$errno );
status = listofmans( filespec, &manroot );
if ( !(status&1) ) return( status );
for ( m = manroot ; m ; m = m->next ){
status = convertman( m->filename, hlp , base_level, add_parentheses );
if ( !(status&1) ){
fprintf(stderr,"Convertman of %s went wrong\n", m->filename);
break;
}
}
freeman( &manroot );
return( status );
}
/*--------------------------------------------*/
void print_help()
{
fprintf( stderr, "Usage: [-a] [-b x] convertman <manfilespec> <helptextfile>\n" );
fprintf( stderr, " -a append <manfilespec> to <helptextfile>\n" );
fprintf( stderr, " -b <baselevel> if no headers found create one with level <baselevel>\n" );
fprintf( stderr, " and the filename as title.\n" );
fprintf( stderr, " -p add parentheses() to baselevel help items.\n" );
}
/*--------------------------------------------*/
main ( int argc, char **argv )
{
int status;
int i,j;
int append, base_level, basechange, add_parentheses;
char *manfile=NULL;
char *helpfile=NULL;
if ( argc < 3 ){
print_help();
return( 1 ) ;
}
append = 0;
base_level = 1;
basechange = 0;
add_parentheses = 0;
for ( i = 1; i < argc; ++i){
if ( argv[i][0] == '-' ){
for( j = 1; argv[i][j] ; ++j ){
switch( argv[i][j] ){
case 'a':
append = 1;
break;
case 'b':
if ( (i+1) < argc ){
base_level = atoi( argv[ i + 1 ] );
basechange = 1;
}
break;
case 'p':
add_parentheses = 1;
break;
}
}
if ( basechange){
basechange = 0;
i = i + 1;
}
}else{
if ( manfile == NULL ){
manfile = strdup( argv[i]);
} else if ( helpfile == NULL ){
helpfile = strdup( argv[i]);
} else {
fprintf( stderr, "Unrecognized parameter : %s\n", argv[i]);
}
}
}
/* fprintf( stderr,"manfile: %s, helpfile: %s, append: %d, base_level : %d\n",
manfile, helpfile, append, base_level);
*/
status = convertmans( manfile, helpfile, base_level, append, add_parentheses );
free( manfile );
free( helpfile );
return( status );
}

319
vms/readme.vms Normal file
View File

@@ -0,0 +1,319 @@
*These are the porting notes to OpenVMS, as of 7 April 2010
by Jose Baars. This file will be installed as
libssh2*.release_notes by the product install kit.
LIBSSH2
-------
LIBSSH2 is a client-side library written in C that aims to
implement the SSH2 protocol. It is an open source project,
to be found at http://libssh2.org.
GNV
---
The library uses the GNV prefix, on advise of the kind supporter
of the GNV project, John Malmberg.
Installing the PCSI kit
=======================
Prerequisites
-------------
- VMS version 8.3 minimal.
See the remarks at prerequisites for building the kit
- TCP/IP stack, both TCP/IP services and Multinet should work.
See the remarks at prerequisites for building the kit
- HP OPENSSL V1.3 minimal.
See the remarks at prerequisites for building the kit
- JEM ZLIB V1.2-3E1 minimal.
See the remarks at prerequisites for building the kit
The first three dependencies are tested at installation time, and
installation will fail if any these products are not installed.
The ZLIB dependency is not tested by the product installation
procedure, as libssh2 will probably be installed as part of
multiple libraries including zlib.
Install
-------
The kit will install gnv$libssh2.exe in a directory tree that might
already be available on your system if you have installed other gnv*
libraries or utilities.
The directory tree for gnv$libssh2.exe will be like this:
[gnv] -- [usr] -- [include] -- [libssh2] include files for libssh2
[lib] gnv$libssh2_x_y_z.exe
[share] -- [doc] -- [libssh2] libssh2.hlb,
release notes (this file),
libssh2 release notes
optional:
[example] libssh2_examples-x_y_z.bck
[common_src] libssh2-x_y_z_src.bck
By default, it will install the shared image and include files to
SYS$COMMON:[GNV...].
You can override this destination by specifying the destination
directory after /DESTINATION= on the product install command line.
This is particularly of use when installing the library on a cluster
without a common system disk.
Please ignore the following warnings, as the kit is not signed :
%PCSI-I-CANNOTVAL, cannot validate dev:[dir]JCB-AXPVMS-LIBSSH2-V0102-05D20100402-1.PCSI
-PCSI-I-NOTSIGNED, product kit is not signed and therefore has no manifest file
Optionally, you can install a backup saveset with some programming examples,
or a backupo saveset with the complete libssh2 source tree.
you will need to answer 'NO' to the question
'Do you want the default for all options'.
and 'YES' to either or both the following questions:
Do you want the libssh2 C programming examples ? [NO]
Do you want the complete libssh2 source tree ? [NO]
Post installation tasks
-----------------------
Although we will try to maintain upward compatibility of libssh2,
this can not be guaranteed by the libssh2 project itself for OpenVMS,
nor eternally by us.
To use libssh2 effectively, you will have to define a system logical
to point to the shared image. If you are willing to take the gamble,
define this logical in your systartup like so:
$ define/system/executive gnv$libssh2 dev:[dir..]gnv$libssh2_x_y_z.exe
Optionally, you can install the executbale like so:
$ mc sysgen install dev:[dir..]gnv$libssh2_x_y_z.exe/open/share/header
Link your programs against gnv$libssh2, and when upgrading libssh2
test thoroughly.
If you want to be extra cautious define a system logical like this:
$ define/system/executive gnv$libssh2_x_y_z dev:[dir..]gnv$libssh2_x_y_z.exe
Link programs against gnv$libssh2_x_y_z, and when upgrading libssh2
link against new versions.
It is probably more convenient in the last case to link against the object
library provided in the source backup saveset. Both an uppercase and a
mixed case object library, called libssh2.olb and libssh2_asis.olb
are provided.
Compiling and linking against libssh2
-------------------------------------
The shared image library has a vector table with both uppercase and
mixed case entry points, allowing to link directly against the shared
image wether you need the /NAMES=AS_IS or not.
To link successfully, you MUST use /NAMES=shortened, as some function
names in libssh2 are longer than the VMS maximum of 32 characters.
If you chose to install the examples, you can unpack the backup
saveset by
backup/sel=*.c device:[gnv.usr.share.doc.libssh2.examples]libssh2_examples-x_y_z.bck -
[]
They can by compiled and linked by these commands ( provided you have defined
the gnv$libssh2 logical) :
$ cc/include=dev:[gnv.usr.include.libssh2] xxx.c/names=shortened
$ link/opt=sys$input: xxx.obj
gnv$libssh2/share
Building gnv$libssh2
====================
You can build gnv$libssh2 yourself, which may have advantages, as the library is
in full development, very regularly new features are added.
For production use, it is probably advisable to use a stable version, and
link against that. To check out new features, statically linking against
the object library is probably more practical, to avoid compatibility
issues.
Prerequisites
-------------
You will need to have the following available:
- An Alpha or Itanium VMS system. Due to dependencies on zlib, ssl and ODS-5,
support on VAXen would be cumbersome at least.
- VMS version 8.3 minimal. This is a requirement of gnv$zlibshr.exe against
which shared image library libssh2 is linked. If you use another zlib
to link against, you can make it work under lower versions of VMS.
I have made it work on VMS 7.3-2 with not a lot of difficulty.
Also, if you are not interested in compression, you can choose not
to link against zlib at all; in that case comment out the
#define LIBSSH2_HAVE_ZLIB in libssh2_config.h.
- TCP/IP services or Multinet for OpenVMS.
TCPWare has not been tested.
- The HP OpenSSL product. Of course, with tweaking, you can probably link
it against the OpenSSL library, but that is not what I have used.
- A C compiler. I don't know any other working C compilers than
the DEC/Compac/HP-C compiler on VMS.
- An ODS-5 disk. With tweaking you'll get it to work on an ODS-2
disk, but it is unpractical to do so.
- A version of VMSTAR that understands ODS-5 disks and extended
filenames. Look here:
http://ftp.process.com/ftp/vms-freeware/fileserv/vmstar.zip
- gunzip, available for instance at Steven M Schweda's website:
http://antinode.info/ftp/gzip/gzip-1_3_12b_vms/gzip-1_3_12b_vms.zip
Optional:
- curl, to be found at http://curl.haxx.se
You might want to use curl to download the libssh2 kit directly
to you VMS machine. Interestingly, sftp in curl is implemented using
libssh2, soon to be expected on VMS as well, hopefully.
Downloading libssh2
-------------------
At the website of libssh2, you can find stable and daily gzipped
tarballs. if you have a computer connected to internet you can
download a daily build yourself by a procedure that looks a lot like
this ( fill out your own proxy user/password, set up right symbols to
gunzip, vmstar and curl and set up the libssh2 build version):
$ libssh2_version = "1.2.6"
$!
$ proxy_line = " ""-U"" ""''proxy_userpass'"" ""-x"" ""''proxy_hostport'"" "
$!
$ currentday = f$cvtime(,,"date") - "-" - "-"
$!
$ set def mydev:[mydir.libssh2]
$!
$ if f$search("libssh2-''libssh2_version'-''currentday'.tar.gz") .nes. ""
$ then
$ delete libssh2-'libssh2_version'-'currentday'.tar.gz;*
$ endif
$!
$ curl 'proxy_line' "http://libssh2.org/snapshots/libssh2-''libssh2_version'-''currentday'.tar.gz" -
-o libssh2-'libssh2_version'-'currentday'.tar.gz
$!
$!
$ if f$search("libssh2-''libssh2_version'-''currentday'.tar.;") .nes. ""
$ then
$ delete libssh2-'libssh2_version'-'currentday'.tar.;*
$ endif
$!
$ gunzip libssh2-'libssh2_version'-'currentday'.tar.gz
$!
$ tarfile = f$search("libssh2-''libssh2_version'-''currentday'.tar.;")
$ vmstar xf 'tarfile'
Downloading a stable build will need you to get rid of the currentday.
After the download, you should have a directory tree with a toplevel
directory called [libssh2-x.y.z-yyyymmdd].
One of the subdirectories is called vms.
Getting the libssh2 sources from the source backup in the binary kit
--------------------------------------------------------------------
During installation of the binary kit, you are given the option
of installing the sources. If chosen, a backup saveset with
the complete libssh2 directory is made available in
[gnv.common_src].
By restoring this backup saveset, you end up with the same
set of files as by the direct download from libssh2.org.
Building the library
--------------------
To avoid all kinds of misunderstandings caused by firewalls thinking that
a .com file must be an MS-DOS executable, all command procedures are called
.dcl.
Go to the vms subdirectory in the download tree, and issue the following
command:
@libssh2_make_lib.dcl
This should produce libssh2_x_y_z.exe in this same vms directory.
Building the examples
---------------------
A number of examples are also part of the full libssh2 delivery.
You can compile and link them either against the object library
produced when building the shared image, or against the shared image
produced in the step before.
You can compile only one of the examples by giving only the
name part of the filename of the example as p1 to the
build procedure:
@libssh2_make_example.dcl
or for instance
@libssh2_make_example.dcl sftp
By default, libssh2_make_example.dcl links to the object libraries
produced by the libssh2_make_lib.dcl procedure. If you want to link
against the shared image library made in the same procedure, invoke
the procedure like so:
@libssh2_make_example.dcl sftp "SHARED"
The procdure defines a process logical gnv$libssh2 pointing to the shared
image library in the directory, which obviously will not survive a logout.
Building the help library
-------------------------
The man pages can be converted to a VMS help library by issuing
this command :
@libssh2_make_help.dcl
It uses a simple but fairly effective c program man2help.c
to achieve this.
Building a PCSI kit
-------------------
When you have built the shared library and the help library,
you can build a PCSI kit by issueing this command:
@libssh2_make_kit.dcl

View File

@@ -11,14 +11,14 @@
# Edit the path below to point to the base of your Zlib sources.
ifndef ZLIB_PATH
ZLIB_PATH = ../../zlib-1.2.3
ZLIB_PATH = ../../zlib-1.2.5
endif
# since currently always enabled in libssh2_config.h set here too!
WITH_ZLIB = 1
# Edit the path below to point to the base of your OpenSSL package.
ifndef OPENSSL_PATH
OPENSSL_PATH = ../../openssl-0.9.8k
OPENSSL_PATH = ../../openssl-0.9.8n
endif
# Edit the path below to point to your Distribution folder.
@@ -36,7 +36,7 @@ DEVLARC = $(DEVLDIR).zip
# Edit the vars below to change target settings.
TARGET = libssh2
VERSION = $(LIBSSH2_VERSION)
COPYR = (c) 2004-2009 Sara Golemon <sarag@libssh2.org>
COPYR = (c) 2004-2010 The libssh2 project and its contributors.
WWWURL = http://www.libssh2.org/
DESCR = libssh2 $(LIBSSH2_VERSION_STR)
#STACK = 64000

View File

@@ -3,19 +3,7 @@ Microsoft Developer Studio Workspace File, Format Version 6.00
###############################################################################
Project: "libssh2_dll"=".\libssh2_dll.dsp" - Package Owner=<4>
Package=<5>
{{{
}}}
Package=<4>
{{{
}}}
###############################################################################
Project: "libssh2_lib"=".\libssh2_lib.dsp" - Package Owner=<4>
Project: "libssh2"=".\libssh2.dsp" - Package Owner=<4>
Package=<5>
{{{

View File

@@ -4,6 +4,9 @@
#ifndef WIN32
#define WIN32
#endif
#ifndef _CRT_SECURE_NO_DEPRECATE
#define _CRT_SECURE_NO_DEPRECATE 1
#endif /* _CRT_SECURE_NO_DEPRECATE */
#include <winsock2.h>
#include <mswsock.h>
#include <ws2tcpip.h>
@@ -22,10 +25,8 @@
#define snprintf _snprintf
#if _MSC_VER < 1500
#define vsnprintf _vsnprintf
#else
#define ssize_t SSIZE_T
#define uint32_t UINT32
#endif
#define strdup _strdup
#define strncasecmp _strnicmp
#define strcasecmp _stricmp
#else
@@ -41,4 +42,3 @@
#endif /* LIBSSH2_CONFIG_H */

View File

@@ -1,184 +0,0 @@
# Microsoft Developer Studio Project File - Name="libssh2_dll" - Package Owner=<4>
# Microsoft Developer Studio Generated Build File, Format Version 6.00
# ** DO NOT EDIT **
# TARGTYPE "Win32 (x86) Dynamic-Link Library" 0x0102
CFG=libssh2_dll - 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_dll.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_dll.mak" CFG="libssh2_dll - Win32 Debug"
!MESSAGE
!MESSAGE Possible choices for configuration are:
!MESSAGE
!MESSAGE "libssh2_dll - Win32 Release" (based on "Win32 (x86) Dynamic-Link Library")
!MESSAGE "libssh2_dll - Win32 Debug" (based on "Win32 (x86) Dynamic-Link 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_dll - Win32 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 "..\include" /I "..\win32" /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_dll - Win32 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 "..\include" /I "..\win32" /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
!ENDIF
# Begin Target
# Name "libssh2_dll - Win32 Release"
# Name "libssh2_dll - Win32 Debug"
# Begin Group "Source Files"
# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat"
# Begin Source File
SOURCE=..\src\channel.c
# End Source File
# Begin Source File
SOURCE=..\src\comp.c
# End Source File
# Begin Source File
SOURCE=..\src\crypt.c
# End Source File
# Begin Source File
SOURCE=..\src\hostkey.c
# End Source File
# Begin Source File
SOURCE=..\src\kex.c
# End Source File
# Begin Source File
SOURCE=..\src\mac.c
# End Source File
# Begin Source File
SOURCE=..\src\misc.c
# End Source File
# Begin Source File
SOURCE=..\src\openssl.c
# End Source File
# Begin Source File
SOURCE=..\src\packet.c
# End Source File
# Begin Source File
SOURCE=..\src\pem.c
# End Source File
# Begin Source File
SOURCE=..\src\publickey.c
# End Source File
# Begin Source File
SOURCE=..\src\scp.c
# End Source File
# Begin Source File
SOURCE=..\src\session.c
# End Source File
# Begin Source File
SOURCE=..\src\sftp.c
# End Source File
# Begin Source File
SOURCE=..\src\transport.c
# End Source File
# Begin Source File
SOURCE=..\src\userauth.c
# End Source File
# End Group
# Begin Group "Header Files"
# PROP Default_Filter "h;hpp;hxx;hm;inl"
# Begin Source File
SOURCE=..\include\libssh2.h
# End Source File
# Begin Source File
SOURCE=.\libssh2_config.h
# End Source File
# Begin Source File
SOURCE=..\include\libssh2_priv.h
# End Source File
# Begin Source File
SOURCE=..\include\libssh2_sftp.h
# End Source File
# End Group
# End Target
# End Project

View File

@@ -1,175 +0,0 @@
# Microsoft Developer Studio Project File - Name="libssh2_lib" - Package Owner=<4>
# Microsoft Developer Studio Generated Build File, Format Version 6.00
# ** DO NOT EDIT **
# TARGTYPE "Win32 (x86) Static Library" 0x0104
CFG=libssh2_lib - 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_lib.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_lib.mak" CFG="libssh2_lib - Win32 Debug"
!MESSAGE
!MESSAGE Possible choices for configuration are:
!MESSAGE
!MESSAGE "libssh2_lib - Win32 Release" (based on "Win32 (x86) Static Library")
!MESSAGE "libssh2_lib - Win32 Debug" (based on "Win32 (x86) Static Library")
!MESSAGE
# Begin Project
# PROP AllowPerConfigDependencies 0
# PROP Scc_ProjName ""
# PROP Scc_LocalPath ""
CPP=cl.exe
RSC=rc.exe
!IF "$(CFG)" == "libssh2_lib - Win32 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 "..\include" /I "..\win32" /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_lib - Win32 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 "..\include" /I "..\win32" /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_lib - Win32 Release"
# Name "libssh2_lib - Win32 Debug"
# Begin Group "Source Files"
# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat"
# Begin Source File
SOURCE=..\src\channel.c
# End Source File
# Begin Source File
SOURCE=..\src\comp.c
# End Source File
# Begin Source File
SOURCE=..\src\crypt.c
# End Source File
# Begin Source File
SOURCE=..\src\hostkey.c
# End Source File
# Begin Source File
SOURCE=..\src\kex.c
# End Source File
# Begin Source File
SOURCE=..\src\mac.c
# End Source File
# Begin Source File
SOURCE=..\src\misc.c
# End Source File
# Begin Source File
SOURCE=..\src\openssl.c
# End Source File
# Begin Source File
SOURCE=..\src\packet.c
# End Source File
# Begin Source File
SOURCE=..\src\pem.c
# End Source File
# Begin Source File
SOURCE=..\src\publickey.c
# End Source File
# Begin Source File
SOURCE=..\src\scp.c
# End Source File
# Begin Source File
SOURCE=..\src\session.c
# End Source File
# Begin Source File
SOURCE=..\src\sftp.c
# End Source File
# Begin Source File
SOURCE=..\src\transport.c
# End Source File
# Begin Source File
SOURCE=..\src\userauth.c
# End Source File
# End Group
# Begin Group "Header Files"
# PROP Default_Filter "h;hpp;hxx;hm;inl"
# Begin Source File
SOURCE=..\include\libssh2.h
# End Source File
# Begin Source File
SOURCE=.\libssh2_config.h
# End Source File
# Begin Source File
SOURCE=..\include\libssh2_priv.h
# End Source File
# Begin Source File
SOURCE=..\include\libssh2_sftp.h
# End Source File
# End Group
# End Target
# End Project

View File

@@ -109,7 +109,7 @@ BSC32=bscmake.exe
LIB32=link.exe -lib
# ADD BASE LIB32 /nologo
# ADD LIB32 /nologo
# ADD LIB32 /nologo /out:"Release_lib\libssh.lib"
# ADD LIB32 /nologo /out:"Release_lib\libssh2.lib"
!ELSEIF "$(CFG)" == "libssh2 - Win32 LIB Debug"

View File

@@ -11,12 +11,12 @@
# Edit the path below to point to the base of your Zlib sources.
ifndef ZLIB_PATH
ZLIB_PATH = ../../../zlib-1.2.3
ZLIB_PATH = ../../../zlib-1.2.5
endif
# Edit the path below to point to the base of your OpenSSL package.
ifndef OPENSSL_PATH
OPENSSL_PATH = ../../../openssl-0.9.8k
OPENSSL_PATH = ../../../openssl-0.9.8n
endif
# Edit the var below to enable static linking of libssh2 and libz
@@ -25,7 +25,7 @@ LINK_STATIC = 1
# Edit the vars below to change target settings.
TARGETS = scp.exe sftp.exe sftpdir.exe ssh2.exe
VERSION = $(LIBSSH2_VERSION)
COPYR = (c) 2004-2009 Sara Golemon <sarag@libssh2.org>
COPYR = (c) 2004-2010 The libssh2 project and its contributors.
WWWURL = http://www.libssh2.org/
DESCR = libssh2 $(subst .def,,$(notdir $@)) $(LIBSSH2_VERSION_STR)
#STACK = 64000
@@ -117,8 +117,7 @@ endif
CFLAGS += $(INCLUDES)
#ifeq ($(findstring linux,$(OSTYPE)),linux)
ifdef __MSYS__
ifeq ($(findstring /sh,$(SHELL)),/sh)
DL = '
DS = /
else