Compare commits
160 Commits
libssh2-1.
...
libssh2-1.
Author | SHA1 | Date | |
---|---|---|---|
![]() |
8d9d3e0d7a | ||
![]() |
c46abb2663 | ||
![]() |
0a34fa79f0 | ||
![]() |
43001570d6 | ||
![]() |
4b878e7cf8 | ||
![]() |
ac709e0d4f | ||
![]() |
56d0877f07 | ||
![]() |
51a8335486 | ||
![]() |
2bd9418ac7 | ||
![]() |
4b8013a8a7 | ||
![]() |
697b4e8ed7 | ||
![]() |
2afa5b2dc2 | ||
![]() |
992aff7aca | ||
![]() |
ef4c8718c2 | ||
![]() |
c375e5e5ad | ||
![]() |
46be03f92b | ||
![]() |
1d83b520b4 | ||
![]() |
f9c0a4a95a | ||
![]() |
7861ae8e4e | ||
![]() |
0f0652a309 | ||
![]() |
2cc4a629ac | ||
![]() |
04f90b2265 | ||
![]() |
7dc2bfac94 | ||
![]() |
35cf08e130 | ||
![]() |
32bd0df992 | ||
![]() |
38940f45d2 | ||
![]() |
537a00ee4b | ||
![]() |
6ddcc493e8 | ||
![]() |
3496e1c2a2 | ||
![]() |
49ddf447ff | ||
![]() |
04d4bbb66b | ||
![]() |
897f8463d8 | ||
![]() |
2fd044fdf5 | ||
![]() |
20e969d2e0 | ||
![]() |
33e2bc8785 | ||
![]() |
d7e6f9cf27 | ||
![]() |
be7cee1b3e | ||
![]() |
518d25eba1 | ||
![]() |
1785d0d6f3 | ||
![]() |
31d71a94f2 | ||
![]() |
22a2de7347 | ||
![]() |
4cf935abab | ||
![]() |
cce6ebbee7 | ||
![]() |
18605cb81f | ||
![]() |
3490b3fe10 | ||
![]() |
c87a48ae4c | ||
![]() |
ab8ee8abf3 | ||
![]() |
6e40af7bea | ||
![]() |
5e46c864dc | ||
![]() |
a4fdf0de01 | ||
![]() |
2c1c751ad1 | ||
![]() |
f682684fdd | ||
![]() |
0ad1a52a09 | ||
![]() |
4e10882e06 | ||
![]() |
eeeebd02e7 | ||
![]() |
f285438022 | ||
![]() |
81912f67e7 | ||
![]() |
2996e02482 | ||
![]() |
2683fddcca | ||
![]() |
fa5d6c705d | ||
![]() |
b6c6470e7e | ||
![]() |
dceb3d1452 | ||
![]() |
86c935317c | ||
![]() |
aad74b7fa6 | ||
![]() |
0b593c8a9d | ||
![]() |
8ff3f62786 | ||
![]() |
4d7b2950d9 | ||
![]() |
18569d76de | ||
![]() |
7a088a8ab7 | ||
![]() |
d15663477b | ||
![]() |
8145f9e79c | ||
![]() |
dc747fb221 | ||
![]() |
76fd96e63e | ||
![]() |
ed526a0e24 | ||
![]() |
667f4acda6 | ||
![]() |
f3208b99ca | ||
![]() |
b702441242 | ||
![]() |
396dcedc56 | ||
![]() |
798a808a2b | ||
![]() |
c8df661129 | ||
![]() |
b3ed8e064a | ||
![]() |
ffb55aa2a3 | ||
![]() |
9251642ef3 | ||
![]() |
79b97c67c7 | ||
![]() |
b23ae2bf22 | ||
![]() |
a3f3347c12 | ||
![]() |
5184aec461 | ||
![]() |
358aa3e24b | ||
![]() |
7bbefe0660 | ||
![]() |
204100e636 | ||
![]() |
6c85370428 | ||
![]() |
23f02aad11 | ||
![]() |
eb7581e72e | ||
![]() |
a16d67e250 | ||
![]() |
ab81b75a8e | ||
![]() |
0c918ef72a | ||
![]() |
6c3f2ec815 | ||
![]() |
f1df0b7fbc | ||
![]() |
6f895e3298 | ||
![]() |
45210d8376 | ||
![]() |
6a44eff0b5 | ||
![]() |
0862a1a39a | ||
![]() |
514f4d9305 | ||
![]() |
d5d80d296a | ||
![]() |
568060d266 | ||
![]() |
6e2a0e603a | ||
![]() |
d811478071 | ||
![]() |
b979af1eee | ||
![]() |
37624b61e3 | ||
![]() |
4c26a46362 | ||
![]() |
77efca961d | ||
![]() |
c28fa65424 | ||
![]() |
03815483be | ||
![]() |
67de62d650 | ||
![]() |
cb42be1a9c | ||
![]() |
c511177d39 | ||
![]() |
d4edb0b9c3 | ||
![]() |
71fb9cc93e | ||
![]() |
5163e4ecb8 | ||
![]() |
000b0f73d0 | ||
![]() |
c5602fac58 | ||
![]() |
046ff03c3f | ||
![]() |
d06f983c9c | ||
![]() |
8620cc03f8 | ||
![]() |
21f55d0006 | ||
![]() |
88ac2dd43c | ||
![]() |
26d1698320 | ||
![]() |
7dfeadef97 | ||
![]() |
5804444936 | ||
![]() |
ee5dd3561d | ||
![]() |
ad1ec1c9e4 | ||
![]() |
28ef62be20 | ||
![]() |
1acca6e3ee | ||
![]() |
d3a0f2932b | ||
![]() |
7adc23a628 | ||
![]() |
fca949ea55 | ||
![]() |
f8b42cab86 | ||
![]() |
fea133f8d6 | ||
![]() |
9ba30d888e | ||
![]() |
5d37cd44aa | ||
![]() |
be9ee7095e | ||
![]() |
9209309bc3 | ||
![]() |
2a069503be | ||
![]() |
182108ac91 | ||
![]() |
21a01c96f8 | ||
![]() |
100059989f | ||
![]() |
13caffa00e | ||
![]() |
c3bcdd88a4 | ||
![]() |
81e63b3657 | ||
![]() |
1adcb5234f | ||
![]() |
9cc824e27b | ||
![]() |
2f9c105ec2 | ||
![]() |
8ab009c0b0 | ||
![]() |
e22cdcea77 | ||
![]() |
7f740368f4 | ||
![]() |
8b63dc9e59 | ||
![]() |
77fa740674 | ||
![]() |
32cf14b512 | ||
![]() |
44cd934fa2 | ||
![]() |
339ad5ccd3 |
2
COPYING
2
COPYING
@@ -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.
|
||||
|
@@ -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
|
||||
|
||||
|
@@ -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
|
||||
|
77
NEWS
77
NEWS
@@ -1,3 +1,80 @@
|
||||
libssh2 1.2.7 (August 17, 2010)
|
||||
|
||||
This release includes the following changes:
|
||||
|
||||
o Added Watcom makefile
|
||||
|
||||
This release includes the following bugfixes:
|
||||
|
||||
o Better handling of invalid key files
|
||||
o inputchecks: make lots of API functions check for NULL pointers
|
||||
o libssh2_session_callback_set: extended the man page
|
||||
o SFTP: limit write() to not produce overly large packets
|
||||
o agent: make libssh2_agent_userauth() work blocking properly
|
||||
o _libssh2_userauth_publickey: reject method names longer than the data
|
||||
o channel_free: ignore problems with channel_close()
|
||||
o typedef: make ssize_t get typedef without LIBSSH2_WIN32
|
||||
o _libssh2_wait_socket: poll needs milliseconds
|
||||
o libssh2_wait_socket: reset error code to "leak" EAGAIN less
|
||||
o Added include for sys/select.h to get fd.set on some platforms
|
||||
o session_free: free more data to avoid memory leaks
|
||||
o openssl: make use of the EVP interface
|
||||
o Fix underscore typo for 64-bit printf format specifiers on Windows
|
||||
o Make libssh2_debug() create a correctly terminated string
|
||||
o userauth_hostbased_fromfile: packet length too short
|
||||
o handshake: Compression enabled at the wrong time
|
||||
o Don't overflow MD5 server hostkey
|
||||
|
||||
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.
|
||||
|
@@ -1,33 +1,34 @@
|
||||
libssh2 1.2.5
|
||||
libssh2 1.2.7
|
||||
|
||||
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 Watcom makefile
|
||||
|
||||
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 Better handling of invalid key files
|
||||
o inputchecks: make lots of API functions check for NULL pointers
|
||||
o libssh2_session_callback_set: extended the man page
|
||||
o SFTP: limit write() to not produce overly large packets
|
||||
o agent: make libssh2_agent_userauth() work blocking properly
|
||||
o _libssh2_userauth_publickey: reject method names longer than the data
|
||||
o channel_free: ignore problems with channel_close()
|
||||
o typedef: make ssize_t get typedef without LIBSSH2_WIN32
|
||||
o _libssh2_wait_socket: poll needs milliseconds
|
||||
o libssh2_wait_socket: reset error code to "leak" EAGAIN less
|
||||
o Added include for sys/select.h to get fd.set on some platforms
|
||||
o session_free: free more data to avoid memory leaks
|
||||
o openssl: make use of the EVP interface
|
||||
o Fix underscore typo for 64-bit printf format specifiers on Windows
|
||||
o Make libssh2_debug() create a correctly terminated string
|
||||
o userauth_hostbased_fromfile: packet length too short
|
||||
o handshake: Compression enabled at the wrong time
|
||||
o Don't overflow MD5 server hostkey
|
||||
|
||||
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, Peter Stuge, Simon Josefsson, Lars Nordin,
|
||||
John Little, Daniel Stenberg, TJ Saunders, Tor Arntsen
|
||||
|
||||
Thanks! (and sorry if I forgot to mention someone)
|
||||
|
8
TODO
8
TODO
@@ -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
|
||||
|
@@ -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
|
||||
|
@@ -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 \
|
||||
|
@@ -13,6 +13,7 @@ libssh2_channel_eof(LIBSSH2_CHANNEL *channel);
|
||||
|
||||
Check if the remote host has sent an EOF status for the selected stream.
|
||||
.SH RETURN VALUE
|
||||
Returns 1 if the remote host has sent EOF, otherwise 0.
|
||||
Returns 1 if the remote host has sent EOF, otherwise 0. Negative on
|
||||
failure.
|
||||
.SH SEE ALSO
|
||||
.BR libssh2_channel_close(3)
|
||||
|
@@ -2,12 +2,13 @@
|
||||
.\"
|
||||
.TH libssh2_channel_write 3 "20 Feb 2010" "libssh2 1.2.4" "libssh2 manual"
|
||||
.SH NAME
|
||||
libssh2_channel_write - convenience macro for \fIlibssh2_channel_write_ex(3)\fP calls
|
||||
libssh2_channel_write - convenience macro for \fIlibssh2_channel_write_ex(3)\fP
|
||||
.SH SYNOPSIS
|
||||
.nf
|
||||
#include <libssh2.h>
|
||||
|
||||
libssh2_channel_write(arguments)
|
||||
|
||||
#define libssh2_channel_write(channel, buf, buflen) \\
|
||||
libssh2_channel_write_ex((channel), 0, (buf), (buflen))
|
||||
.SH DESCRIPTION
|
||||
This is a macro defined in a public libssh2 header file that is using the
|
||||
underlying function \fIlibssh2_channel_write_ex(3)\fP.
|
||||
|
@@ -4,16 +4,12 @@
|
||||
.SH NAME
|
||||
libssh2_channel_write_ex - write data to a channel stream blocking
|
||||
.SH SYNOPSIS
|
||||
.nf
|
||||
#include <libssh2.h>
|
||||
|
||||
ssize_t
|
||||
libssh2_channel_write_ex(LIBSSH2_CHANNEL *channel, int stream_id, char *buf, size_t buflen);
|
||||
|
||||
ssize_t
|
||||
libssh2_channel_write(LIBSSH2_CHANNEL *channel, char *buf, size_t buflen);
|
||||
|
||||
ssize_t
|
||||
libssh2_channel_write_stderr(LIBSSH2_CHANNEL *channel, char *buf, size_t buflen);
|
||||
ssize_t libssh2_channel_write_ex(LIBSSH2_CHANNEL *channel,
|
||||
int stream_id, char *buf,
|
||||
size_t buflen);
|
||||
.SH DESCRIPTION
|
||||
Write data to a channel stream. All channel streams have one standard I/O
|
||||
substream (stream_id == 0), and may have up to 2^32 extended data streams as
|
||||
@@ -29,7 +25,12 @@ defines a stream ID of 1 to be the stderr substream.
|
||||
\fIbuflen\fP - size of the data to write
|
||||
|
||||
\fIlibssh2_channel_write(3)\fP and \fIlibssh2_channel_write_stderr(3)\fP are
|
||||
macros.
|
||||
convenience macros for this function.
|
||||
|
||||
\fIlibssh2_channel_write_ex(3)\fP will use as much as possible of the buffer
|
||||
and put it into a single SSH protocol packet. This means that to get maximum
|
||||
performance when sending larger files, you should try to always pass in at
|
||||
least 32K of data to this function.
|
||||
.SH RETURN VALUE
|
||||
Actual number of bytes written or negative on failure.
|
||||
LIBSSH2_ERROR_EAGAIN when it would otherwise block. While
|
||||
|
@@ -2,12 +2,13 @@
|
||||
.\"
|
||||
.TH libssh2_channel_write_stderr 3 "20 Feb 2010" "libssh2 1.2.4" "libssh2 manual"
|
||||
.SH NAME
|
||||
libssh2_channel_write_stderr - convenience macro for \fIlibssh2_channel_write_ex(3)\fP calls
|
||||
libssh2_channel_write_stderr - convenience macro for \fIlibssh2_channel_write_ex(3)\fP
|
||||
.SH SYNOPSIS
|
||||
.nf
|
||||
#include <libssh2.h>
|
||||
|
||||
libssh2_channel_write_stderr(arguments)
|
||||
|
||||
#define libssh2_channel_write_stderr(channel, buf, buflen) \\
|
||||
libssh2_channel_write_ex((channel), SSH_EXTENDED_DATA_STDERR, (buf), (buflen))
|
||||
.SH DESCRIPTION
|
||||
This is a macro defined in a public libssh2 header file that is using the
|
||||
underlying function \fIlibssh2_channel_write_ex(3)\fP.
|
||||
|
@@ -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)
|
||||
|
@@ -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)
|
||||
|
@@ -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.
|
||||
|
||||
|
@@ -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.
|
||||
|
||||
|
@@ -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
|
||||
|
63
docs/libssh2_knownhost_checkp.3
Normal file
63
docs/libssh2_knownhost_checkp.3
Normal 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)
|
@@ -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
|
||||
|
@@ -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
49
docs/libssh2_scp_send64.3
Normal 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)
|
@@ -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)
|
||||
|
@@ -4,12 +4,16 @@
|
||||
.SH NAME
|
||||
libssh2_session_callback_set - set a callback function
|
||||
.SH SYNOPSIS
|
||||
.nf
|
||||
#include <libssh2.h>
|
||||
|
||||
void *
|
||||
libssh2_session_callback_set(LIBSSH2_SESSION *session, int cbtype, void *callback);
|
||||
|
||||
void *libssh2_session_callback_set(LIBSSH2_SESSION *session,
|
||||
int cbtype, void *callback);
|
||||
.SH DESCRIPTION
|
||||
Sets a custom callback handler for a previously initialized session
|
||||
object. Callbacks are triggered by the receipt of special packets at the
|
||||
Transport layer. To disable a callback, set it to NULL.
|
||||
|
||||
\fIsession\fP - Session instance as returned by
|
||||
.BR libssh2_session_init_ex(3)
|
||||
|
||||
@@ -17,14 +21,19 @@ libssh2_session_callback_set(LIBSSH2_SESSION *session, int cbtype, void *callbac
|
||||
|
||||
\fIcallback\fP - Pointer to custom callback function. The prototype for
|
||||
this function must match the associated callback declaration macro.
|
||||
|
||||
Sets a custom callback handler for a previously initialized session
|
||||
object. Callbacks are triggered by the receipt of special packets at
|
||||
the Transport layer. To disable a callback, set it to NULL.
|
||||
|
||||
.SH CALLBACK TYPES
|
||||
.IP LIBSSH2_CALLBACK_IGNORE
|
||||
Called when a SSH_MSG_IGNORE message is received
|
||||
.IP LIBSSH2_CALLBACK_DEBUG
|
||||
Called when a SSH_MSG_DEBUG message is received
|
||||
.IP LIBSSH2_CALLBACK_DISCONNECT
|
||||
Called when a SSH_MSG_DISCONNECT message is received
|
||||
.IP LIBSSH2_CALLBACK_MACERROR
|
||||
Called when a mismatched MAC has been detected in the transport layer
|
||||
.IP LIBSSH2_CALLBACK_X11
|
||||
Called when an X11 connection has been accepted
|
||||
.SH RETURN VALUE
|
||||
Pointer to previous callback handler. Returns NULL if no
|
||||
prior callback handler was set.
|
||||
|
||||
Pointer to previous callback handler. Returns NULL if no prior callback
|
||||
handler was set or the callback type was unknown.
|
||||
.SH SEE ALSO
|
||||
.BR libssh2_session_init_ex(3)
|
||||
|
@@ -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
|
||||
|
1
docs/libssh2_sftp_fstatvfs.3
Normal file
1
docs/libssh2_sftp_fstatvfs.3
Normal file
@@ -0,0 +1 @@
|
||||
.so man3/libssh2_sftp_statvfs.3
|
@@ -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.
|
||||
|
@@ -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
|
||||
|
@@ -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.
|
||||
|
||||
|
@@ -2,12 +2,14 @@
|
||||
.\"
|
||||
.TH libssh2_sftp_readlink 3 "20 Feb 2010" "libssh2 1.2.4" "libssh2 manual"
|
||||
.SH NAME
|
||||
libssh2_sftp_readlink - convenience macro for \fIlibssh2_sftp_symlink_ex(3)\fP calls
|
||||
libssh2_sftp_readlink - convenience macro for \fIlibssh2_sftp_symlink_ex(3)\fP
|
||||
.SH SYNOPSIS
|
||||
.nf
|
||||
#include <libssh2.h>
|
||||
|
||||
libssh2_sftp_readlink(arguments)
|
||||
|
||||
#define libssh2_sftp_readlink(sftp, path, target, maxlen) \\
|
||||
libssh2_sftp_symlink_ex((sftp), (path), strlen(path), (target), (maxlen), \\
|
||||
LIBSSH2_SFTP_READLINK)
|
||||
.SH DESCRIPTION
|
||||
This is a macro defined in a public libssh2 header file that is using the
|
||||
underlying function \fIlibssh2_sftp_symlink_ex(3)\fP.
|
||||
|
@@ -2,12 +2,14 @@
|
||||
.\"
|
||||
.TH libssh2_sftp_realpath 3 "20 Feb 2010" "libssh2 1.2.4" "libssh2 manual"
|
||||
.SH NAME
|
||||
libssh2_sftp_realpath - convenience macro for \fIlibssh2_sftp_symlink_ex(3)\fP calls
|
||||
libssh2_sftp_realpath - convenience macro for \fIlibssh2_sftp_symlink_ex(3)\fP
|
||||
.SH SYNOPSIS
|
||||
.nf
|
||||
#include <libssh2.h>
|
||||
|
||||
libssh2_sftp_realpath(arguments)
|
||||
|
||||
#define libssh2_sftp_realpath(sftp, path, target, maxlen) \\
|
||||
libssh2_sftp_symlink_ex((sftp), (path), strlen(path), (target), (maxlen), \\
|
||||
LIBSSH2_SFTP_REALPATH)
|
||||
.SH DESCRIPTION
|
||||
This is a macro defined in a public libssh2 header file that is using the
|
||||
underlying function \fIlibssh2_sftp_symlink_ex(3)\fP.
|
||||
|
@@ -2,12 +2,13 @@
|
||||
.\"
|
||||
.TH libssh2_sftp_rmdir 3 "20 Feb 2010" "libssh2 1.2.4" "libssh2 manual"
|
||||
.SH NAME
|
||||
libssh2_sftp_rmdir - convenience macro for \fIlibssh2_sftp_rmdir_ex(3)\fP calls
|
||||
libssh2_sftp_rmdir - convenience macro for \fIlibssh2_sftp_rmdir_ex(3)\fP
|
||||
.SH SYNOPSIS
|
||||
.nf
|
||||
#include <libssh2.h>
|
||||
|
||||
libssh2_sftp_rmdir(arguments)
|
||||
|
||||
#define libssh2_sftp_rmdir(sftp, path) \\
|
||||
libssh2_sftp_rmdir_ex((sftp), (path), strlen(path))
|
||||
.SH DESCRIPTION
|
||||
This is a macro defined in a public libssh2 header file that is using the
|
||||
underlying function \fIlibssh2_sftp_rmdir_ex(3)\fP.
|
||||
|
@@ -4,30 +4,26 @@
|
||||
.SH NAME
|
||||
libssh2_sftp_rmdir_ex - remove an SFTP directory
|
||||
.SH SYNOPSIS
|
||||
.nf
|
||||
#include <libssh2.h>
|
||||
#include <libssh2_sftp.h>
|
||||
|
||||
int
|
||||
libssh2_sftp_rmdir_ex(LIBSSH2_SFTP *sftp, const char *path, unsigned int path_len);
|
||||
|
||||
int
|
||||
libssh2_sftp_rmdir_ex(LIBSSH2_SFTP *sftp, const char *path);
|
||||
|
||||
int libssh2_sftp_rmdir_ex(LIBSSH2_SFTP *sftp, const char *path,
|
||||
unsigned int path_len);
|
||||
.SH DESCRIPTION
|
||||
Remove a directory from the remote file system.
|
||||
|
||||
\fIsftp\fP - SFTP instance as returned by
|
||||
.BR libssh2_sftp_init(3)
|
||||
|
||||
\fIsourcefile\fP - Full path of the existing directory to remove.
|
||||
|
||||
\fIsourcefile_len\fP - Length of the full path of the existing directory to remove.
|
||||
|
||||
Remove a directory from the remote file system.
|
||||
|
||||
\fIsourcefile_len\fP - Length of the full path of the existing directory to
|
||||
remove.
|
||||
.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.
|
||||
|
||||
.SH ERRORS
|
||||
\fILIBSSH2_ERROR_ALLOC\fP - An internal memory allocation call failed.
|
||||
|
||||
@@ -38,6 +34,5 @@ LIBSSH2_ERROR_EAGAIN is a negative number, it isn't really a failure per se.
|
||||
\fILIBSSH2_ERROR_SFTP_PROTOCOL\fP - An invalid SFTP protocol response was
|
||||
received on the socket, or an SFTP operation caused an errorcode to
|
||||
be returned by the server.
|
||||
|
||||
.SH SEE ALSO
|
||||
.BR libssh2_sftp_init(3)
|
||||
|
@@ -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
|
||||
|
79
docs/libssh2_sftp_statvfs.3
Normal file
79
docs/libssh2_sftp_statvfs.3
Normal 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)
|
@@ -2,12 +2,14 @@
|
||||
.\"
|
||||
.TH libssh2_sftp_symlink 3 "20 Feb 2010" "libssh2 1.2.4" "libssh2 manual"
|
||||
.SH NAME
|
||||
libssh2_sftp_symlink - convenience macro for \fIlibssh2_sftp_symlink_ex(3)\fP calls
|
||||
libssh2_sftp_symlink - convenience macro for \fIlibssh2_sftp_symlink_ex(3)\fP
|
||||
.SH SYNOPSIS
|
||||
.nf
|
||||
#include <libssh2.h>
|
||||
|
||||
libssh2_sftp_symlink(arguments)
|
||||
|
||||
#define libssh2_sftp_symlink(sftp, orig, linkpath) \\
|
||||
libssh2_sftp_symlink_ex((sftp), (orig), strlen(orig), (linkpath), \\
|
||||
strlen(linkpath), LIBSSH2_SFTP_SYMLINK)
|
||||
.SH DESCRIPTION
|
||||
This is a macro defined in a public libssh2 header file that is using the
|
||||
underlying function \fIlibssh2_sftp_symlink_ex(3)\fP.
|
||||
|
@@ -4,22 +4,20 @@
|
||||
.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);
|
||||
|
||||
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 +26,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 +52,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.
|
||||
|
||||
|
@@ -4,23 +4,29 @@
|
||||
.SH NAME
|
||||
libssh2_sftp_write - write SFTP data
|
||||
.SH SYNOPSIS
|
||||
.nf
|
||||
#include <libssh2.h>
|
||||
#include <libssh2_sftp.h>
|
||||
|
||||
ssize_t
|
||||
libssh2_sftp_write(LIBSSH2_SFTP_HANDLE *handle, const char *buffer, size_t count);
|
||||
|
||||
ssize_t libssh2_sftp_write(LIBSSH2_SFTP_HANDLE *handle,
|
||||
const char *buffer,
|
||||
size_t count);
|
||||
.SH DESCRIPTION
|
||||
\fBlibssh2_sftp_write(3)\fP writes a block of data to the SFTP server. This
|
||||
method is modeled after the POSIX write() function and uses the same calling
|
||||
semantics.
|
||||
|
||||
\fIhandle\fP - SFTP file handle as returned by \fIlibssh2_sftp_open_ex(3)\fP.
|
||||
|
||||
\fIbuffer\fP - points to the data to send off
|
||||
\fIbuffer\fP - points to the data to send off.
|
||||
|
||||
\fIcount\fP - Number of bytes from 'buffer' to write. Note that it may not be
|
||||
possible to write all bytes as requested.
|
||||
|
||||
\fBlibssh2_sftp_write(3)\fP writes a block of data to the SFTP server. This
|
||||
method is modeled after the POSIX write() function and uses the same calling
|
||||
semantics.
|
||||
\fIlibssh2_sftp_handle(3)\fP will use as much as possible of the buffer and
|
||||
put it into a single SFTP protocol packet. This means that to get maximum
|
||||
performance when sending larger files, you should try to always pass in at
|
||||
least 32K of data to this function.
|
||||
.SH RETURN VALUE
|
||||
Actual number of bytes written or negative on failure.
|
||||
|
||||
|
@@ -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)
|
||||
|
@@ -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;
|
||||
}
|
||||
|
||||
|
@@ -151,10 +151,10 @@ int main(int argc, char *argv[])
|
||||
}
|
||||
|
||||
rc = libssh2_channel_read(channel, mem, amount);
|
||||
if(rc == amount) {
|
||||
if(rc > 0) {
|
||||
write(1, mem, rc);
|
||||
}
|
||||
else {
|
||||
else if(rc < 0) {
|
||||
fprintf(stderr, "libssh2_channel_read() failed: %d\n", rc);
|
||||
break;
|
||||
}
|
||||
|
@@ -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");
|
||||
|
@@ -32,6 +32,7 @@
|
||||
#include <errno.h>
|
||||
#include <stdio.h>
|
||||
#include <ctype.h>
|
||||
#include <time.h>
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
@@ -39,7 +40,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";
|
||||
@@ -50,10 +51,13 @@ int main(int argc, char *argv[])
|
||||
#if defined(HAVE_IOCTLSOCKET)
|
||||
long flag = 1;
|
||||
#endif
|
||||
char mem[1024];
|
||||
size_t nread, sent;
|
||||
char mem[1024*100];
|
||||
size_t nread;
|
||||
char *ptr;
|
||||
struct stat fileinfo;
|
||||
time_t start;
|
||||
long total = 0;
|
||||
int duration;
|
||||
|
||||
#ifdef WIN32
|
||||
WSADATA wsadata;
|
||||
@@ -88,7 +92,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);
|
||||
@@ -175,6 +179,7 @@ int main(int argc, char *argv[])
|
||||
} while (!channel);
|
||||
|
||||
fprintf(stderr, "SCP session waiting to send file\n");
|
||||
start = time(NULL);
|
||||
do {
|
||||
nread = fread(mem, 1, sizeof(mem), local);
|
||||
if (nread <= 0) {
|
||||
@@ -182,7 +187,8 @@ int main(int argc, char *argv[])
|
||||
break;
|
||||
}
|
||||
ptr = mem;
|
||||
sent = 0;
|
||||
|
||||
total += nread;
|
||||
|
||||
do {
|
||||
/* write the same data over and over, until error or completion */
|
||||
@@ -191,14 +197,19 @@ 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 */
|
||||
|
||||
duration = (int)(time(NULL)-start);
|
||||
|
||||
printf("%ld bytes in %d seconds makes %.1f bytes/sec\n",
|
||||
total, duration, total/(double)duration);
|
||||
|
||||
fprintf(stderr, "Sending EOF\n");
|
||||
while (libssh2_channel_send_eof(channel) == LIBSSH2_ERROR_EAGAIN);
|
||||
@@ -214,8 +225,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
|
||||
|
@@ -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[])
|
||||
|
@@ -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 */
|
||||
|
@@ -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:
|
||||
|
@@ -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);
|
||||
|
||||
|
@@ -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);
|
||||
|
||||
|
@@ -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);
|
||||
|
@@ -22,6 +22,9 @@
|
||||
#ifdef HAVE_NETINET_IN_H
|
||||
# include <netinet/in.h>
|
||||
#endif
|
||||
#ifdef HAVE_SYS_SELECT_H
|
||||
# include <sys/select.h>
|
||||
#endif
|
||||
# ifdef HAVE_UNISTD_H
|
||||
#include <unistd.h>
|
||||
#endif
|
||||
@@ -34,6 +37,37 @@
|
||||
#include <errno.h>
|
||||
#include <stdio.h>
|
||||
#include <ctype.h>
|
||||
#include <time.h>
|
||||
|
||||
static int waitsocket(int socket_fd, LIBSSH2_SESSION *session)
|
||||
{
|
||||
struct timeval timeout;
|
||||
int rc;
|
||||
fd_set fd;
|
||||
fd_set *writefd = NULL;
|
||||
fd_set *readfd = NULL;
|
||||
int dir;
|
||||
|
||||
timeout.tv_sec = 10;
|
||||
timeout.tv_usec = 0;
|
||||
|
||||
FD_ZERO(&fd);
|
||||
|
||||
FD_SET(socket_fd, &fd);
|
||||
|
||||
/* now make sure we wait in the correct direction */
|
||||
dir = libssh2_session_block_directions(session);
|
||||
|
||||
if(dir & LIBSSH2_SESSION_BLOCK_INBOUND)
|
||||
readfd = &fd;
|
||||
|
||||
if(dir & LIBSSH2_SESSION_BLOCK_OUTBOUND)
|
||||
writefd = &fd;
|
||||
|
||||
rc = select(socket_fd + 1, readfd, writefd, NULL, &timeout);
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
@@ -53,9 +87,12 @@ int main(int argc, char *argv[])
|
||||
FILE *local;
|
||||
LIBSSH2_SFTP *sftp_session;
|
||||
LIBSSH2_SFTP_HANDLE *sftp_handle;
|
||||
char mem[1024];
|
||||
char mem[1024 * 100];
|
||||
size_t nread;
|
||||
char *ptr;
|
||||
time_t start;
|
||||
long total = 0;
|
||||
int duration;
|
||||
|
||||
#ifdef WIN32
|
||||
WSADATA wsadata;
|
||||
@@ -91,7 +128,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;
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -142,17 +179,19 @@ int main(int argc, char *argv[])
|
||||
|
||||
if (auth_pw) {
|
||||
/* We could authenticate via password */
|
||||
while ((rc = libssh2_userauth_password(session, username, password)) == LIBSSH2_ERROR_EAGAIN);
|
||||
if (rc) {
|
||||
while ((rc = libssh2_userauth_password(session, username, password)) ==
|
||||
LIBSSH2_ERROR_EAGAIN);
|
||||
if (rc) {
|
||||
printf("Authentication by password failed.\n");
|
||||
goto shutdown;
|
||||
}
|
||||
} else {
|
||||
/* Or by public key */
|
||||
while ((rc = libssh2_userauth_publickey_fromfile(session, username,
|
||||
"/home/username/.ssh/id_rsa.pub",
|
||||
"/home/username/.ssh/id_rsa",
|
||||
password)) == LIBSSH2_ERROR_EAGAIN);
|
||||
"/home/username/.ssh/id_rsa.pub",
|
||||
"/home/username/.ssh/id_rsa",
|
||||
password)) ==
|
||||
LIBSSH2_ERROR_EAGAIN);
|
||||
if (rc) {
|
||||
printf("\tAuthentication by public key failed\n");
|
||||
goto shutdown;
|
||||
@@ -163,7 +202,8 @@ int main(int argc, char *argv[])
|
||||
do {
|
||||
sftp_session = libssh2_sftp_init(session);
|
||||
|
||||
if ((!sftp_session) && (libssh2_session_last_errno(session) != LIBSSH2_ERROR_EAGAIN)) {
|
||||
if (!sftp_session &&
|
||||
(libssh2_session_last_errno(session) != LIBSSH2_ERROR_EAGAIN)) {
|
||||
fprintf(stderr, "Unable to init SFTP session\n");
|
||||
goto shutdown;
|
||||
}
|
||||
@@ -178,13 +218,17 @@ int main(int argc, char *argv[])
|
||||
LIBSSH2_SFTP_S_IRUSR|LIBSSH2_SFTP_S_IWUSR|
|
||||
LIBSSH2_SFTP_S_IRGRP|LIBSSH2_SFTP_S_IROTH);
|
||||
|
||||
if ((!sftp_handle) && (libssh2_session_last_errno(session) != LIBSSH2_ERROR_EAGAIN)) {
|
||||
if (!sftp_handle &&
|
||||
(libssh2_session_last_errno(session) != LIBSSH2_ERROR_EAGAIN)) {
|
||||
fprintf(stderr, "Unable to open file with SFTP\n");
|
||||
goto shutdown;
|
||||
}
|
||||
} while (!sftp_handle);
|
||||
|
||||
fprintf(stderr, "libssh2_sftp_open() is done, now send data!\n");
|
||||
|
||||
start = time(NULL);
|
||||
|
||||
do {
|
||||
nread = fread(mem, 1, sizeof(mem), local);
|
||||
if (nread <= 0) {
|
||||
@@ -193,15 +237,27 @@ int main(int argc, char *argv[])
|
||||
}
|
||||
ptr = mem;
|
||||
|
||||
total += nread;
|
||||
|
||||
do {
|
||||
/* write data in a loop until we block */
|
||||
while ((rc = libssh2_sftp_write(sftp_handle, ptr, nread)) == LIBSSH2_ERROR_EAGAIN) {
|
||||
;
|
||||
while ((rc = libssh2_sftp_write(sftp_handle, ptr, nread)) ==
|
||||
LIBSSH2_ERROR_EAGAIN) {
|
||||
waitsocket(sock, session);
|
||||
}
|
||||
if(rc < 0)
|
||||
break;
|
||||
ptr += rc;
|
||||
nread -= nread;
|
||||
} while (rc > 0);
|
||||
} while (1);
|
||||
nread -= rc;
|
||||
|
||||
} while (nread);
|
||||
} while (rc > 0);
|
||||
|
||||
duration = (int)(time(NULL)-start);
|
||||
|
||||
printf("%ld bytes in %d seconds makes %.1f bytes/sec\n",
|
||||
total, duration, total/(double)duration);
|
||||
|
||||
|
||||
fclose(local);
|
||||
libssh2_sftp_close(sftp_handle);
|
||||
@@ -209,7 +265,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
|
||||
|
@@ -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;
|
||||
}
|
||||
|
@@ -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
|
||||
|
@@ -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>");
|
||||
|
@@ -1,7 +1,10 @@
|
||||
# fetch libssh2 version number from input file and write them to STDOUT
|
||||
BEGIN {
|
||||
while ((getline < ARGV[1]) > 0) {
|
||||
if (match ($0, /^#define LIBSSH2_VERSION[ |\t]+"[^"]+"/)) {
|
||||
if (match ($0, /^#define LIBSSH2_COPYRIGHT "[^"]+"$/)) {
|
||||
my_copyright_str = substr($0, 28, length($0)-28);
|
||||
}
|
||||
else if (match ($0, /^#define LIBSSH2_VERSION[ |\t]+"[^"]+"/)) {
|
||||
my_ver_str = substr($3, 2, length($3) - 2);
|
||||
split(my_ver_str, v, ".");
|
||||
if (v[3])
|
||||
@@ -17,4 +20,5 @@ BEGIN {
|
||||
}
|
||||
print "LIBSSH2_VERSION = " my_ver "";
|
||||
print "LIBSSH2_VERSION_STR = " my_ver_str "";
|
||||
print "LIBSSH2_COPYRIGHT_STR = " my_copyright_str "";
|
||||
}
|
||||
|
@@ -40,6 +40,50 @@
|
||||
#ifndef LIBSSH2_H
|
||||
#define LIBSSH2_H 1
|
||||
|
||||
#define LIBSSH2_COPYRIGHT "2004-2010 The libssh2 project and its contributors."
|
||||
|
||||
/* We use underscore instead of dash when appending DEV in dev versions just
|
||||
to make the BANNER define (used by src/session.c) be a valid SSH
|
||||
banner. Release versions have no appended strings and may of course not
|
||||
have dashes either. */
|
||||
#define LIBSSH2_VERSION "1.2.7_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 7
|
||||
|
||||
/* This is the numeric version of the libssh2 version number, meant for easier
|
||||
parsing and comparions by programs. The LIBSSH2_VERSION_NUM define will
|
||||
always follow this syntax:
|
||||
|
||||
0xXXYYZZ
|
||||
|
||||
Where XX, YY and ZZ are the main version, release and patch numbers in
|
||||
hexadecimal (using 8 bits each). All three numbers are always represented
|
||||
using two digits. 1.2 would appear as "0x010200" while version 9.11.7
|
||||
appears as "0x090b07".
|
||||
|
||||
This 6-digit (24 bits) hexadecimal number does not show pre-release number,
|
||||
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 0x010207
|
||||
|
||||
/*
|
||||
* This is the date and time when the full source package was created. The
|
||||
* timestamp is not stored in the source code repo, as the timestamp is
|
||||
* properly set in the tarballs by the maketgz script.
|
||||
*
|
||||
* The format of the date should follow this template:
|
||||
*
|
||||
* "Mon Feb 12 11:35:33 UTC 2007"
|
||||
*/
|
||||
#define LIBSSH2_TIMESTAMP "DEV"
|
||||
|
||||
#ifndef LIBSSH2_VERSION_ONLY
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
@@ -69,62 +113,24 @@ 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)
|
||||
#ifdef _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;
|
||||
typedef long long libssh2_int64_t;
|
||||
#endif
|
||||
|
||||
/* We use underscore instead of dash when appending DEV in dev versions just
|
||||
to make the BANNER define (used by src/session.c) be a valid SSH
|
||||
banner. Release versions have no appended strings and may of course not
|
||||
have dashes either. */
|
||||
#define LIBSSH2_VERSION "1.2.5_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
|
||||
|
||||
/* This is the numeric version of the libssh2 version number, meant for easier
|
||||
parsing and comparions by programs. The LIBSSH2_VERSION_NUM define will
|
||||
always follow this syntax:
|
||||
|
||||
0xXXYYZZ
|
||||
|
||||
Where XX, YY and ZZ are the main version, release and patch numbers in
|
||||
hexadecimal (using 8 bits each). All three numbers are always represented
|
||||
using two digits. 1.2 would appear as "0x010200" while version 9.11.7
|
||||
appears as "0x090b07".
|
||||
|
||||
This 6-digit (24 bits) hexadecimal number does not show pre-release number,
|
||||
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
|
||||
|
||||
/*
|
||||
* This is the date and time when the full source package was created. The
|
||||
* timestamp is not stored in the source code repo, as the timestamp is
|
||||
* properly set in the tarballs by the maketgz script.
|
||||
*
|
||||
* The format of the date should follow this template:
|
||||
*
|
||||
* "Mon Feb 12 11:35:33 UTC 2007"
|
||||
*/
|
||||
#define LIBSSH2_TIMESTAMP "DEV"
|
||||
|
||||
/* Part of every banner, user specified or not */
|
||||
#define LIBSSH2_SSH_BANNER "SSH-2.0-libssh2_" LIBSSH2_VERSION
|
||||
|
||||
@@ -710,6 +716,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 +862,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
|
||||
*
|
||||
@@ -1093,4 +1112,6 @@ LIBSSH2_API int libssh2_trace_sethandler(LIBSSH2_SESSION *session,
|
||||
} /* extern "C" */
|
||||
#endif
|
||||
|
||||
#endif /* LIBSSH2_VERSION_ONLY */
|
||||
|
||||
#endif /* LIBSSH2_H */
|
||||
|
@@ -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);
|
||||
|
@@ -3,9 +3,7 @@
|
||||
## Makefile for building libssh2 (NetWare version - gnu make)
|
||||
## Use: make -f Makefile.netware [help|all|clean|dev|devclean|dist|distclean|lib|nlm|objclean]
|
||||
##
|
||||
## Comments to: Guenter Knauf <eflash@gmx.net>
|
||||
##
|
||||
## $Id: Makefile.netware,v 1.14 2009/04/09 03:13:51 gknauf Exp $
|
||||
## Comments to: Guenter Knauf http://www.gknw.net/phpbb
|
||||
#
|
||||
#########################################################################
|
||||
|
||||
@@ -16,12 +14,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.8o
|
||||
endif
|
||||
|
||||
# Edit the path below to point to your Distribution folder.
|
||||
@@ -39,7 +37,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) $(LIBSSH2_COPYRIGHT_STR)
|
||||
WWWURL = http://www.libssh2.org/
|
||||
DESCR = libssh2 $(LIBSSH2_VERSION_STR) ($(LIBARCH)) - $(WWWURL)
|
||||
MTSAFE = YES
|
||||
@@ -81,9 +79,9 @@ endif
|
||||
CP = cp -afv
|
||||
# RM = rm -f
|
||||
# Here you can find a native Win32 binary of the original awk:
|
||||
# http://www.gknw.net/development/prgtools/awk.zip
|
||||
# http://www.gknw.net/development/prgtools/awk-20070501.zip
|
||||
AWK = awk
|
||||
# if you want to mark the target as MTSAFE you will need a tool for
|
||||
# If you want to mark the target as MTSAFE you will need a tool for
|
||||
# generating the xdc data for the linker; here's a minimal tool:
|
||||
# http://www.gknw.net/development/prgtools/mkxdc.zip
|
||||
MPKXDC = mkxdc
|
||||
@@ -507,6 +505,7 @@ endif
|
||||
@echo $(DL) libssh2_channel_write_ex,$(DL) >> $@
|
||||
@echo $(DL) libssh2_hostkey_hash,$(DL) >> $@
|
||||
@echo $(DL) libssh2_scp_recv,$(DL) >> $@
|
||||
@echo $(DL) libssh2_scp_send64,$(DL) >> $@
|
||||
@echo $(DL) libssh2_scp_send_ex,$(DL) >> $@
|
||||
@echo $(DL) libssh2_knownhost_add,$(DL) >> $@
|
||||
@echo $(DL) libssh2_knownhost_check,$(DL) >> $@
|
||||
|
@@ -3,9 +3,7 @@
|
||||
## Makefile for building libssh2 (NetWare version - gnu make)
|
||||
## Use: make -f Makefile.netware
|
||||
##
|
||||
## Comments to: Guenter Knauf <eflash@gmx.net>
|
||||
##
|
||||
## $Id: Makefile.netware,v 1.10 2009/04/09 03:13:52 gknauf Exp $
|
||||
## Comments to: Guenter Knauf http://www.gknw.net/phpbb
|
||||
#
|
||||
#########################################################################
|
||||
|
||||
@@ -16,12 +14,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.8o
|
||||
endif
|
||||
|
||||
# Edit the var below to enable static linking of libssh2 and libz
|
||||
@@ -31,7 +29,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
|
||||
@@ -75,9 +73,9 @@ endif
|
||||
CP = cp -afv
|
||||
# RM = rm -f
|
||||
# Here you can find a native Win32 binary of the original awk:
|
||||
# http://www.gknw.net/development/prgtools/awk.zip
|
||||
# http://www.gknw.net/development/prgtools/awk-20070501.zip
|
||||
AWK = awk
|
||||
# if you want to mark the target as MTSAFE you will need a tool for
|
||||
# If you want to mark the target as MTSAFE you will need a tool for
|
||||
# generating the xdc data for the linker; here's a minimal tool:
|
||||
# http://www.gknw.net/development/prgtools/mkxdc.zip
|
||||
MPKXDC = mkxdc
|
||||
|
@@ -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 \
|
||||
|
158
src/agent.c
158
src/agent.c
@@ -47,6 +47,8 @@
|
||||
support them. */
|
||||
#undef PF_UNIX
|
||||
#endif
|
||||
#include "userauth.h"
|
||||
#include "session.h"
|
||||
|
||||
/* Requests from client to agent for protocol 1 key operations */
|
||||
#define SSH_AGENTC_REQUEST_RSA_IDENTITIES 1
|
||||
@@ -145,29 +147,30 @@ agent_connect_unix(LIBSSH2_AGENT *agent)
|
||||
struct sockaddr_un s_un;
|
||||
|
||||
path = getenv("SSH_AUTH_SOCK");
|
||||
if (!path) {
|
||||
return -1;
|
||||
}
|
||||
if (!path)
|
||||
return _libssh2_error(agent->session, LIBSSH2_ERROR_BAD_USE,
|
||||
"no auth sock variable");
|
||||
|
||||
agent->fd = socket(PF_UNIX, SOCK_STREAM, 0);
|
||||
if (agent->fd < 0) {
|
||||
return -1;
|
||||
}
|
||||
if (agent->fd < 0)
|
||||
return _libssh2_error(agent->session, LIBSSH2_ERROR_SOCKET_NONE,
|
||||
"failed creating socket");
|
||||
|
||||
s_un.sun_family = AF_UNIX;
|
||||
strncpy (s_un.sun_path, path, sizeof s_un.sun_path);
|
||||
if (connect(agent->fd, (struct sockaddr*)(&s_un), sizeof s_un) != 0) {
|
||||
close (agent->fd);
|
||||
return -1;
|
||||
return _libssh2_error(agent->session, LIBSSH2_ERROR_SOCKET_NONE,
|
||||
"failed connecting");
|
||||
}
|
||||
|
||||
return 0;
|
||||
return LIBSSH2_ERROR_NONE;
|
||||
}
|
||||
|
||||
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 */
|
||||
@@ -177,7 +180,8 @@ agent_transact_unix(LIBSSH2_AGENT *agent, agent_transaction_ctx_t transctx)
|
||||
if (rc < 0) {
|
||||
if (errno == EAGAIN)
|
||||
return LIBSSH2_ERROR_EAGAIN;
|
||||
return -1;
|
||||
return _libssh2_error(agent->session, LIBSSH2_ERROR_SOCKET_SEND,
|
||||
"agent send failed");
|
||||
}
|
||||
transctx->state = agent_NB_state_request_length_sent;
|
||||
}
|
||||
@@ -189,7 +193,8 @@ agent_transact_unix(LIBSSH2_AGENT *agent, agent_transaction_ctx_t transctx)
|
||||
if (rc < 0) {
|
||||
if (errno == EAGAIN)
|
||||
return LIBSSH2_ERROR_EAGAIN;
|
||||
return -1;
|
||||
return _libssh2_error(agent->session, LIBSSH2_ERROR_SOCKET_SEND,
|
||||
"agent send failed");
|
||||
}
|
||||
transctx->state = agent_NB_state_request_sent;
|
||||
}
|
||||
@@ -200,14 +205,15 @@ agent_transact_unix(LIBSSH2_AGENT *agent, agent_transaction_ctx_t transctx)
|
||||
if (rc < 0) {
|
||||
if (errno == EAGAIN)
|
||||
return LIBSSH2_ERROR_EAGAIN;
|
||||
return -1;
|
||||
return _libssh2_error(agent->session, LIBSSH2_ERROR_SOCKET_NONE,
|
||||
"agent recv failed");
|
||||
}
|
||||
transctx->response_len = _libssh2_ntohu32(buf);
|
||||
s = transctx->response = LIBSSH2_ALLOC(agent->session,
|
||||
transctx->response_len);
|
||||
if (!transctx->response) {
|
||||
transctx->response = LIBSSH2_ALLOC(agent->session,
|
||||
transctx->response_len);
|
||||
if (!transctx->response)
|
||||
return LIBSSH2_ERROR_ALLOC;
|
||||
}
|
||||
|
||||
transctx->state = agent_NB_state_response_length_received;
|
||||
}
|
||||
|
||||
@@ -217,7 +223,8 @@ agent_transact_unix(LIBSSH2_AGENT *agent, agent_transaction_ctx_t transctx)
|
||||
if (rc < 0) {
|
||||
if (errno == EAGAIN)
|
||||
return LIBSSH2_ERROR_EAGAIN;
|
||||
return -1;
|
||||
return _libssh2_error(agent->session, LIBSSH2_ERROR_SOCKET_SEND,
|
||||
"agent recv failed");
|
||||
}
|
||||
transctx->state = agent_NB_state_response_received;
|
||||
}
|
||||
@@ -228,7 +235,13 @@ agent_transact_unix(LIBSSH2_AGENT *agent, agent_transaction_ctx_t transctx)
|
||||
static int
|
||||
agent_disconnect_unix(LIBSSH2_AGENT *agent)
|
||||
{
|
||||
return close(agent->fd);
|
||||
int ret;
|
||||
ret = close(agent->fd);
|
||||
|
||||
if(ret == -1)
|
||||
return _libssh2_error(agent->session, LIBSSH2_ERROR_SOCKET_DISCONNECT,
|
||||
"failed closing the agent socket");
|
||||
return LIBSSH2_ERROR_NONE;
|
||||
}
|
||||
|
||||
struct agent_ops agent_ops_unix = {
|
||||
@@ -255,9 +268,10 @@ agent_connect_pageant(LIBSSH2_AGENT *agent)
|
||||
HWND hwnd;
|
||||
hwnd = FindWindow("Pageant", "Pageant");
|
||||
if (!hwnd)
|
||||
return -1;
|
||||
return _libssh2_error(agent->session, LIBSSH2_ERROR_SOCKET_NONE,
|
||||
"failed connecting agent");
|
||||
agent->fd = 0; /* Mark as the connection has been established */
|
||||
return 0;
|
||||
return LIBSSH2_ERROR_NONE;
|
||||
}
|
||||
|
||||
static int
|
||||
@@ -267,25 +281,31 @@ 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;
|
||||
|
||||
if (!transctx || 4 + transctx->request_len > PAGEANT_MAX_MSGLEN) {
|
||||
return LIBSSH2_ERROR_INVAL;
|
||||
}
|
||||
if (!transctx || 4 + transctx->request_len > PAGEANT_MAX_MSGLEN)
|
||||
return _libssh2_error(agent->session, LIBSSH2_ERROR_INVAL,
|
||||
"illegal input");
|
||||
|
||||
hwnd = FindWindow("Pageant", "Pageant");
|
||||
if (!hwnd) {
|
||||
return -1;
|
||||
}
|
||||
if (!hwnd)
|
||||
return _libssh2_error(agent->session, LIBSSH2_ERROR_AGENT_PROTOCOL,
|
||||
"found no pageant");
|
||||
|
||||
sprintf(mapname, "PageantRequest%08x", (unsigned)GetCurrentThreadId());
|
||||
filemap = CreateFileMapping(INVALID_HANDLE_VALUE, NULL, PAGE_READWRITE,
|
||||
0, PAGEANT_MAX_MSGLEN, mapname);
|
||||
if (filemap == NULL || filemap == INVALID_HANDLE_VALUE) {
|
||||
return -1;
|
||||
}
|
||||
p = MapViewOfFile(filemap, FILE_MAP_WRITE, 0, 0, 0);
|
||||
_libssh2_htonu32(p, transctx->request_len);
|
||||
memcpy(p + 4, transctx->request, transctx->request_len);
|
||||
|
||||
if (filemap == NULL || filemap == INVALID_HANDLE_VALUE)
|
||||
return _libssh2_error(agent->session, LIBSSH2_ERROR_AGENT_PROTOCOL,
|
||||
"failed setting up pageant filemap");
|
||||
|
||||
p2 = p = MapViewOfFile(filemap, FILE_MAP_WRITE, 0, 0, 0);
|
||||
_libssh2_store_str(&p2, (const char *)transctx->request,
|
||||
transctx->request_len);
|
||||
|
||||
cds.dwData = PAGEANT_COPYDATA_ID;
|
||||
cds.cbData = 1 + strlen(mapname);
|
||||
cds.lpData = mapname;
|
||||
@@ -296,14 +316,16 @@ agent_transact_pageant(LIBSSH2_AGENT *agent, agent_transaction_ctx_t transctx)
|
||||
if (transctx->response_len > PAGEANT_MAX_MSGLEN) {
|
||||
UnmapViewOfFile(p);
|
||||
CloseHandle(filemap);
|
||||
return LIBSSH2_ERROR_AGENT_PROTOCOL;
|
||||
return _libssh2_error(agent->session, LIBSSH2_ERROR_AGENT_PROTOCOL,
|
||||
"agent setup fail");
|
||||
}
|
||||
transctx->response = LIBSSH2_ALLOC(agent->session,
|
||||
transctx->response_len);
|
||||
if (!transctx->response) {
|
||||
UnmapViewOfFile(p);
|
||||
CloseHandle(filemap);
|
||||
return LIBSSH2_ERROR_ALLOC;
|
||||
return _libssh2_error(agent->session, LIBSSH2_ERROR_ALLOC,
|
||||
"agent malloc");
|
||||
}
|
||||
memcpy(transctx->response, p + 4, transctx->response_len);
|
||||
}
|
||||
@@ -355,32 +377,33 @@ agent_sign(LIBSSH2_SESSION *session, unsigned char **sig, size_t *sig_len,
|
||||
/* Create a request to sign the data */
|
||||
if (transctx->state == agent_NB_state_init) {
|
||||
s = transctx->request = LIBSSH2_ALLOC(session, len);
|
||||
if (!transctx->request) {
|
||||
return LIBSSH2_ERROR_ALLOC;
|
||||
}
|
||||
if (!transctx->request)
|
||||
return _libssh2_error(session, LIBSSH2_ERROR_ALLOC,
|
||||
"out of memory");
|
||||
|
||||
*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;
|
||||
}
|
||||
|
||||
/* Make sure to be re-called as a result of EAGAIN. */
|
||||
if (*transctx->request != SSH2_AGENTC_SIGN_REQUEST) {
|
||||
return LIBSSH2_ERROR_BAD_USE;
|
||||
}
|
||||
if (*transctx->request != SSH2_AGENTC_SIGN_REQUEST)
|
||||
return _libssh2_error(session, LIBSSH2_ERROR_BAD_USE,
|
||||
"illegal request");
|
||||
|
||||
if (!agent->ops)
|
||||
/* if no agent has been connected, bail out */
|
||||
return _libssh2_error(session, LIBSSH2_ERROR_BAD_USE,
|
||||
"agent not connected");
|
||||
|
||||
rc = agent->ops->transact(agent, transctx);
|
||||
if (rc) {
|
||||
@@ -453,7 +476,7 @@ agent_sign(LIBSSH2_SESSION *session, unsigned char **sig, size_t *sig_len,
|
||||
LIBSSH2_FREE(session, transctx->response);
|
||||
transctx->response = NULL;
|
||||
|
||||
return rc;
|
||||
return _libssh2_error(session, rc, "agent sign failure");
|
||||
}
|
||||
|
||||
static int
|
||||
@@ -473,9 +496,14 @@ agent_list_identities(LIBSSH2_AGENT *agent)
|
||||
}
|
||||
|
||||
/* Make sure to be re-called as a result of EAGAIN. */
|
||||
if (*transctx->request != SSH2_AGENTC_REQUEST_IDENTITIES) {
|
||||
return LIBSSH2_ERROR_BAD_USE;
|
||||
}
|
||||
if (*transctx->request != SSH2_AGENTC_REQUEST_IDENTITIES)
|
||||
return _libssh2_error(agent->session, LIBSSH2_ERROR_BAD_USE,
|
||||
"illegal agent request");
|
||||
|
||||
if (!agent->ops)
|
||||
/* if no agent has been connected, bail out */
|
||||
return _libssh2_error(agent->session, LIBSSH2_ERROR_BAD_USE,
|
||||
"agent not connected");
|
||||
|
||||
rc = agent->ops->transact(agent, transctx);
|
||||
if (rc) {
|
||||
@@ -570,7 +598,8 @@ agent_list_identities(LIBSSH2_AGENT *agent)
|
||||
LIBSSH2_FREE(agent->session, transctx->response);
|
||||
transctx->response = NULL;
|
||||
|
||||
return rc;
|
||||
return _libssh2_error(agent->session, rc,
|
||||
"agent list id failed");
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -618,8 +647,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);
|
||||
@@ -715,16 +744,21 @@ libssh2_agent_userauth(LIBSSH2_AGENT *agent,
|
||||
struct libssh2_agent_publickey *identity)
|
||||
{
|
||||
void *abstract = agent;
|
||||
int rc;
|
||||
|
||||
if (agent->session->userauth_pblc_state == libssh2_NB_state_idle) {
|
||||
memset(&agent->transctx, 0, sizeof agent->transctx);
|
||||
agent->identity = identity->node;
|
||||
}
|
||||
return libssh2_userauth_publickey(agent->session, username,
|
||||
identity->blob,
|
||||
identity->blob_len,
|
||||
agent_sign,
|
||||
&abstract);
|
||||
|
||||
BLOCK_ADJUST(rc, agent->session,
|
||||
_libssh2_userauth_publickey(agent->session, username,
|
||||
strlen(username),
|
||||
identity->blob,
|
||||
identity->blob_len,
|
||||
agent_sign,
|
||||
&abstract));
|
||||
return rc;
|
||||
}
|
||||
|
||||
/*
|
||||
|
802
src/channel.c
802
src/channel.c
File diff suppressed because it is too large
Load Diff
@@ -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 */
|
||||
|
||||
|
77
src/comp.c
77
src/comp.c
@@ -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
|
||||
@@ -170,6 +170,15 @@ comp_method_zlib_comp(LIBSSH2_SESSION * session,
|
||||
int out_maxlen = compress ? (src_len + 4) : (2 * src_len);
|
||||
int limiter = 0;
|
||||
|
||||
/* If strm is null, then we have not yet been initialized. */
|
||||
if (strm == NULL) {
|
||||
*dest = (unsigned char *) src;
|
||||
*dest_len = src_len;
|
||||
|
||||
*free_dest = 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* In practice they never come smaller than this */
|
||||
if (out_maxlen < 25) {
|
||||
out_maxlen = 25;
|
||||
@@ -185,9 +194,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 +208,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 +220,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 +246,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 +261,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 +276,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 +325,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,
|
||||
|
@@ -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) {
|
||||
|
@@ -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;
|
||||
}
|
||||
|
||||
|
263
src/kex.c
263
src/kex.c
@@ -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,
|
||||
@@ -600,6 +600,40 @@ static int diffie_hellman_sha1(LIBSSH2_SESSION *session,
|
||||
}
|
||||
_libssh2_debug(session, LIBSSH2_TRACE_KEX,
|
||||
"Server to Client HMAC Key calculated");
|
||||
|
||||
/* Initialize compression for each direction */
|
||||
|
||||
/* Cleanup any existing compression */
|
||||
if (session->local.comp && session->local.comp->dtor) {
|
||||
session->local.comp->dtor(session, 1,
|
||||
&session->local.comp_abstract);
|
||||
}
|
||||
|
||||
if (session->local.comp && session->local.comp->init) {
|
||||
if (session->local.comp->init(session, 1,
|
||||
&session->local.comp_abstract)) {
|
||||
ret = LIBSSH2_ERROR_KEX_FAILURE;
|
||||
goto clean_exit;
|
||||
}
|
||||
}
|
||||
_libssh2_debug(session, LIBSSH2_TRACE_KEX,
|
||||
"Client to Server compression initialized");
|
||||
|
||||
if (session->remote.comp && session->remote.comp->dtor) {
|
||||
session->remote.comp->dtor(session, 0,
|
||||
&session->remote.comp_abstract);
|
||||
}
|
||||
|
||||
if (session->remote.comp && session->remote.comp->init) {
|
||||
if (session->remote.comp->init(session, 0,
|
||||
&session->remote.comp_abstract)) {
|
||||
ret = LIBSSH2_ERROR_KEX_FAILURE;
|
||||
goto clean_exit;
|
||||
}
|
||||
}
|
||||
_libssh2_debug(session, LIBSSH2_TRACE_KEX,
|
||||
"Server to Client compression initialized");
|
||||
|
||||
}
|
||||
|
||||
clean_exit:
|
||||
@@ -682,7 +716,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 +792,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 +815,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 +844,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 +860,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 +872,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 +881,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 +888,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 +923,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 +992,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 +1058,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 +1099,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
|
||||
{
|
||||
@@ -1104,10 +1133,13 @@ static int kexinit(LIBSSH2_SESSION * session)
|
||||
} else {
|
||||
data = session->kexinit_data;
|
||||
data_len = session->kexinit_data_len;
|
||||
/* zap the variables to ensure there is NOT a double free later */
|
||||
session->kexinit_data = NULL;
|
||||
session->kexinit_data_len = 0;
|
||||
}
|
||||
|
||||
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 +1147,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 +1208,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 +1549,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 +1584,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 +1592,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 +1621,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,34 +1645,20 @@ 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 &&
|
||||
session->local.comp->init(session, 1, &session->local.comp_abstract)) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (session->remote.comp && session->remote.comp->init &&
|
||||
session->remote.comp->init(session, 0,
|
||||
&session->remote.comp_abstract)) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* 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 +1696,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 +1717,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 +1753,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 +1846,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 +1879,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) {
|
||||
|
440
src/knownhost.c
440
src/knownhost.c
@@ -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;
|
||||
}
|
||||
}
|
||||
|
@@ -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;
|
||||
|
@@ -56,14 +56,14 @@
|
||||
#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
|
||||
#define libssh2_sha1_init(ctx) gcry_md_open (ctx, GCRY_MD_SHA1, 0);
|
||||
#define libssh2_sha1_update(ctx, data, len) gcry_md_write (ctx, data, len)
|
||||
#define libssh2_sha1_final(ctx, out) \
|
||||
memcpy (out, gcry_md_read (ctx, 0), 20), gcry_md_close (ctx)
|
||||
memcpy (out, gcry_md_read (ctx, 0), SHA_DIGEST_LENGTH), gcry_md_close (ctx)
|
||||
#define libssh2_sha1(message, len, out) \
|
||||
gcry_md_hash_buffer (GCRY_MD_SHA1, out, message, len)
|
||||
|
||||
@@ -71,7 +71,7 @@
|
||||
#define libssh2_md5_init(ctx) gcry_md_open (ctx, GCRY_MD_MD5, 0);
|
||||
#define libssh2_md5_update(ctx, data, len) gcry_md_write (ctx, data, len)
|
||||
#define libssh2_md5_final(ctx, out) \
|
||||
memcpy (out, gcry_md_read (ctx, 0), 20), gcry_md_close (ctx)
|
||||
memcpy (out, gcry_md_read (ctx, 0), MD5_DIGEST_LENGTH), gcry_md_close (ctx)
|
||||
#define libssh2_md5(message, len, out) \
|
||||
gcry_md_hash_buffer (GCRY_MD_MD5, out, message, len)
|
||||
|
||||
@@ -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)
|
||||
|
||||
|
@@ -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"
|
||||
@@ -177,9 +172,9 @@ typedef int libssh2_socket_t;
|
||||
session->ssh_msg_ignore((session), (data), (datalen), &(session)->abstract)
|
||||
#define LIBSSH2_DEBUG(session, always_display, message, message_len, \
|
||||
language, language_len) \
|
||||
session->ssh_msg_disconnect((session), (always_display), (message), \
|
||||
(message_len), (language), (language_len), \
|
||||
&(session)->abstract)
|
||||
session->ssh_msg_debug((session), (always_display), (message), \
|
||||
(message_len), (language), (language_len), \
|
||||
&(session)->abstract)
|
||||
#define LIBSSH2_DISCONNECT(session, reason, message, message_len, language, language_len) \
|
||||
session->ssh_msg_disconnect((session), (reason), (message), (message_len), (language), (language_len), &(session)->abstract)
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -588,12 +583,12 @@ struct _LIBSSH2_SFTP
|
||||
/* a list of _LIBSSH2_SFTP_HANDLE structs */
|
||||
struct list_head sftp_handles;
|
||||
|
||||
unsigned long last_errno;
|
||||
uint32_t last_errno;
|
||||
|
||||
/* 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,50 +1146,14 @@ 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]))
|
||||
|
||||
/* define to output the libssh2_int64_t type in a *printf() */
|
||||
#if defined( __BORLANDC__ ) || defined( _MSC_VER ) || defined( __MINGW32__ )
|
||||
#define LIBSSH2_INT64_T_FORMAT "I64"
|
||||
#else
|
||||
#define LIBSSH2_INT64_T_FORMAT "ll"
|
||||
#endif
|
||||
|
||||
#endif /* LIBSSH2_H */
|
||||
|
83
src/misc.c
83
src/misc.c
@@ -47,9 +47,10 @@
|
||||
#include <sys/time.h>
|
||||
#endif
|
||||
|
||||
#include <stdio.h>
|
||||
#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 +97,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;
|
||||
}
|
||||
@@ -109,12 +115,18 @@ _libssh2_recv(libssh2_socket_t socket, void *buffer, size_t length, int flags)
|
||||
* to set errno
|
||||
*/
|
||||
ssize_t
|
||||
_libssh2_send(libssh2_socket_t socket, const void *buffer, size_t length, int flags)
|
||||
_libssh2_send(libssh2_socket_t socket, const void *buffer, size_t length,
|
||||
int flags)
|
||||
{
|
||||
ssize_t rc = send(socket, buffer, length, flags);
|
||||
#ifdef WIN32
|
||||
if (rc < 0 )
|
||||
errno = wsa2errno();
|
||||
#endif
|
||||
#ifdef VMS
|
||||
if (rc < 0 ){
|
||||
if ( errno == EWOULDBLOCK ) errno = EAGAIN;
|
||||
}
|
||||
#endif
|
||||
return rc;
|
||||
}
|
||||
@@ -145,7 +157,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 +165,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 +232,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 +261,7 @@ 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 base64");
|
||||
}
|
||||
|
||||
*datalen = len;
|
||||
@@ -327,7 +357,8 @@ libssh2_trace(LIBSSH2_SESSION * session, int bitmask)
|
||||
}
|
||||
|
||||
LIBSSH2_API int
|
||||
libssh2_trace_sethandler(LIBSSH2_SESSION *session, void* handler_context, libssh2_trace_handler_func callback)
|
||||
libssh2_trace_sethandler(LIBSSH2_SESSION *session, void* handler_context,
|
||||
libssh2_trace_handler_func callback)
|
||||
{
|
||||
session->tracehandler = callback;
|
||||
session->tracehandler_context = handler_context;
|
||||
@@ -338,7 +369,7 @@ void
|
||||
_libssh2_debug(LIBSSH2_SESSION * session, int context, const char *format, ...)
|
||||
{
|
||||
char buffer[1536];
|
||||
int len;
|
||||
int len, msglen, buflen = sizeof(buffer);
|
||||
va_list vargs;
|
||||
struct timeval now;
|
||||
static int firstsec;
|
||||
@@ -363,7 +394,8 @@ _libssh2_debug(LIBSSH2_SESSION * session, int context, const char *format, ...)
|
||||
}
|
||||
|
||||
/* Find the first matching context string for this message */
|
||||
for (contextindex = 0; contextindex < ARRAY_SIZE(contexts); contextindex++) {
|
||||
for (contextindex = 0; contextindex < ARRAY_SIZE(contexts);
|
||||
contextindex++) {
|
||||
if ((context & (1 << contextindex)) != 0) {
|
||||
contexttext = contexts[contextindex];
|
||||
break;
|
||||
@@ -376,19 +408,25 @@ _libssh2_debug(LIBSSH2_SESSION * session, int context, const char *format, ...)
|
||||
}
|
||||
now.tv_sec -= firstsec;
|
||||
|
||||
len = snprintf(buffer, sizeof(buffer), "[libssh2] %d.%06d %s: ",
|
||||
len = snprintf(buffer, buflen, "[libssh2] %d.%06d %s: ",
|
||||
(int)now.tv_sec, (int)now.tv_usec, contexttext);
|
||||
|
||||
va_start(vargs, format);
|
||||
len += vsnprintf(buffer + len, 1535 - len, format, vargs);
|
||||
buffer[len] = '\n';
|
||||
va_end(vargs);
|
||||
|
||||
if (session->tracehandler) {
|
||||
(session->tracehandler)(session, session->tracehandler_context, buffer, len + 1);
|
||||
} else {
|
||||
write(2, buffer, len + 1);
|
||||
if (len >= buflen)
|
||||
msglen = buflen - 1;
|
||||
else {
|
||||
buflen -= len;
|
||||
msglen = len;
|
||||
va_start(vargs, format);
|
||||
len = vsnprintf(buffer + msglen, buflen, format, vargs);
|
||||
va_end(vargs);
|
||||
msglen += len < buflen ? len : buflen - 1;
|
||||
}
|
||||
|
||||
if (session->tracehandler)
|
||||
(session->tracehandler)(session, session->tracehandler_context, buffer,
|
||||
msglen);
|
||||
else
|
||||
fprintf(stderr, "%s\n", buffer);
|
||||
}
|
||||
|
||||
#else
|
||||
@@ -401,7 +439,8 @@ libssh2_trace(LIBSSH2_SESSION * session, int bitmask)
|
||||
}
|
||||
|
||||
LIBSSH2_API int
|
||||
libssh2_trace_sethandler(LIBSSH2_SESSION *session, void* handler_context, libssh2_trace_handler_func callback)
|
||||
libssh2_trace_sethandler(LIBSSH2_SESSION *session, void* handler_context,
|
||||
libssh2_trace_handler_func callback)
|
||||
{
|
||||
(void) session;
|
||||
(void) handler_context;
|
||||
@@ -504,7 +543,7 @@ void _libssh2_list_insert(struct list_node *after, /* insert before this */
|
||||
|
||||
|
||||
|
||||
#ifdef WIN32
|
||||
#if defined(LIBSSH2_WIN32) && !defined(__MINGW32__)
|
||||
/*
|
||||
* gettimeofday
|
||||
* Implementation according to:
|
||||
|
11
src/misc.h
11
src/misc.h
@@ -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 */
|
||||
|
@@ -201,13 +201,15 @@ _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>
|
||||
#include <openssl/evp.h>
|
||||
|
||||
typedef struct
|
||||
{
|
||||
AES_KEY key;
|
||||
EVP_CIPHER_CTX *aes_ctx;
|
||||
unsigned char ctr[AES_BLOCK_SIZE];
|
||||
} aes_ctr_ctx;
|
||||
|
||||
@@ -216,12 +218,35 @@ aes_ctr_init(EVP_CIPHER_CTX *ctx, const unsigned char *key,
|
||||
const unsigned char *iv, int enc) /* init key */
|
||||
{
|
||||
aes_ctr_ctx *c = malloc(sizeof(*c));
|
||||
const EVP_CIPHER *aes_cipher;
|
||||
(void) enc;
|
||||
|
||||
if (c == NULL)
|
||||
return 0;
|
||||
|
||||
AES_set_encrypt_key(key, 8 * ctx->key_len, &c->key);
|
||||
switch (ctx->key_len) {
|
||||
case 16:
|
||||
aes_cipher = EVP_aes_128_ecb();
|
||||
break;
|
||||
case 24:
|
||||
aes_cipher = EVP_aes_192_ecb();
|
||||
break;
|
||||
case 32:
|
||||
aes_cipher = EVP_aes_256_ecb();
|
||||
break;
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
c->aes_ctx = malloc(sizeof(EVP_CIPHER_CTX));
|
||||
if (c->aes_ctx == NULL)
|
||||
return 0;
|
||||
|
||||
if (EVP_EncryptInit(c->aes_ctx, aes_cipher, key, NULL) != 1) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
EVP_CIPHER_CTX_set_padding(c->aes_ctx, 0);
|
||||
|
||||
memcpy(c->ctr, iv, AES_BLOCK_SIZE);
|
||||
|
||||
EVP_CIPHER_CTX_set_app_data(ctx, c);
|
||||
@@ -236,11 +261,16 @@ aes_ctr_do_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
|
||||
{
|
||||
aes_ctr_ctx *c = EVP_CIPHER_CTX_get_app_data(ctx);
|
||||
unsigned char b1[AES_BLOCK_SIZE];
|
||||
size_t i;
|
||||
size_t i = 0;
|
||||
int outlen = 0;
|
||||
|
||||
if (inl != 16) /* libssh2 only ever encrypt one block */
|
||||
return 0;
|
||||
|
||||
if (c == NULL) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
To encrypt a packet P=P1||P2||...||Pn (where P1, P2, ..., Pn are each
|
||||
blocks of length L), the encryptor first encrypts <X> with <cipher>
|
||||
@@ -248,7 +278,9 @@ aes_ctr_do_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
|
||||
the ciphertext block C1. The counter X is then incremented
|
||||
*/
|
||||
|
||||
AES_encrypt(c->ctr, b1, &c->key);
|
||||
if (EVP_EncryptUpdate(c->aes_ctx, b1, &outlen, c->ctr, AES_BLOCK_SIZE) != 1) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
for (i = 0; i < 16; i++)
|
||||
*out++ = *in++ ^ b1[i];
|
||||
@@ -266,7 +298,18 @@ aes_ctr_do_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
|
||||
static int
|
||||
aes_ctr_cleanup(EVP_CIPHER_CTX *ctx) /* cleanup ctx */
|
||||
{
|
||||
free(EVP_CIPHER_CTX_get_app_data(ctx));
|
||||
aes_ctr_ctx *c = EVP_CIPHER_CTX_get_app_data(ctx);
|
||||
|
||||
if (c == NULL) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (c->aes_ctx != NULL) {
|
||||
free(c->aes_ctx);
|
||||
}
|
||||
|
||||
free(c);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
@@ -385,8 +428,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;
|
||||
|
@@ -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
|
||||
|
402
src/packet.c
402
src/packet.c
@@ -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
76
src/packet.h
Normal 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 */
|
493
src/publickey.c
493
src/publickey.c
@@ -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,10 +39,11 @@
|
||||
#include "libssh2_priv.h"
|
||||
#include "libssh2_publickey.h"
|
||||
#include "channel.h"
|
||||
#include "session.h"
|
||||
|
||||
#define LIBSSH2_PUBLICKEY_VERSION 2
|
||||
|
||||
/* Numericised response codes -- Not IETF standard, just a local representation */
|
||||
/* Numericised response codes -- Not IETF, just local representation */
|
||||
#define LIBSSH2_PUBLICKEY_RESPONSE_STATUS 0
|
||||
#define LIBSSH2_PUBLICKEY_RESPONSE_VERSION 1
|
||||
#define LIBSSH2_PUBLICKEY_RESPONSE_PUBLICKEY 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,46 @@ 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");
|
||||
}
|
||||
/* Unknown/Unexpected */
|
||||
_libssh2_error(session, LIBSSH2_ERROR_PUBLICKEY_PROTOCOL,
|
||||
"Unexpected publickey subsystem response");
|
||||
data = NULL;
|
||||
}
|
||||
}
|
||||
@@ -272,20 +274,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 +299,38 @@ 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",
|
||||
sizeof("publickey") - 1);
|
||||
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 +338,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,10 +366,11 @@ 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",
|
||||
"Sending publickey advertising version %d support",
|
||||
(int) LIBSSH2_PUBLICKEY_VERSION);
|
||||
|
||||
session->pkeyInit_state = libssh2_NB_state_sent2;
|
||||
@@ -384,83 +378,90 @@ 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);
|
||||
if (session->pkeyInit_pkey->version >
|
||||
LIBSSH2_PUBLICKEY_VERSION) {
|
||||
_libssh2_debug(session, LIBSSH2_TRACE_PUBLICKEY,
|
||||
"Truncating remote publickey version from %lu",
|
||||
"Truncate remote publickey version from %lu",
|
||||
session->pkeyInit_pkey->version);
|
||||
session->pkeyInit_pkey->version =
|
||||
LIBSSH2_PUBLICKEY_VERSION;
|
||||
@@ -475,9 +476,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 +489,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,26 +508,50 @@ 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
|
||||
*
|
||||
* Add a new public key entry
|
||||
*/
|
||||
LIBSSH2_API int
|
||||
libssh2_publickey_add_ex(LIBSSH2_PUBLICKEY * pkey, const unsigned char *name,
|
||||
libssh2_publickey_add_ex(LIBSSH2_PUBLICKEY *pkey, const unsigned char *name,
|
||||
unsigned long name_len, const unsigned char *blob,
|
||||
unsigned long blob_len, char overwrite,
|
||||
unsigned long num_attrs,
|
||||
const libssh2_publickey_attribute attrs[])
|
||||
{
|
||||
LIBSSH2_CHANNEL *channel = pkey->channel;
|
||||
LIBSSH2_SESSION *session = channel->session;
|
||||
/* 19 = packet_len(4) + add_len(4) + "add"(3) + name_len(4) + {name} blob_len(4) + {blob} */
|
||||
LIBSSH2_CHANNEL *channel;
|
||||
LIBSSH2_SESSION *session;
|
||||
/* 19 = packet_len(4) + add_len(4) + "add"(3) + name_len(4) + {name}
|
||||
blob_len(4) + {blob} */
|
||||
unsigned long i, packet_len = 19 + name_len + blob_len;
|
||||
unsigned char *comment = NULL;
|
||||
unsigned long comment_len = 0;
|
||||
int rc;
|
||||
|
||||
if(!pkey)
|
||||
return LIBSSH2_ERROR_BAD_USE;
|
||||
|
||||
channel = pkey->channel;
|
||||
session = channel->session;
|
||||
|
||||
if (pkey->add_state == libssh2_NB_state_idle) {
|
||||
pkey->add_packet = NULL;
|
||||
|
||||
@@ -555,9 +580,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;
|
||||
@@ -611,7 +636,8 @@ libssh2_publickey_add_ex(LIBSSH2_PUBLICKEY * pkey, const unsigned char *name,
|
||||
}
|
||||
|
||||
_libssh2_debug(session, LIBSSH2_TRACE_PUBLICKEY,
|
||||
"Sending publickey \"add\" packet: type=%s blob_len=%ld num_attrs=%ld",
|
||||
"Sending publickey \"add\" packet: "
|
||||
"type=%s blob_len=%ld num_attrs=%ld",
|
||||
name, blob_len, num_attrs);
|
||||
|
||||
pkey->add_state = libssh2_NB_state_created;
|
||||
@@ -620,13 +646,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 +661,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;
|
||||
}
|
||||
|
||||
@@ -645,27 +671,35 @@ libssh2_publickey_add_ex(LIBSSH2_PUBLICKEY * pkey, const unsigned char *name,
|
||||
}
|
||||
|
||||
/* libssh2_publickey_remove_ex
|
||||
* Remove an existing publickey so that authentication can no longer be performed using it
|
||||
* Remove an existing publickey so that authentication can no longer be
|
||||
* performed using it
|
||||
*/
|
||||
LIBSSH2_API int
|
||||
libssh2_publickey_remove_ex(LIBSSH2_PUBLICKEY * pkey,
|
||||
const unsigned char *name, unsigned long name_len,
|
||||
const unsigned char *blob, unsigned long blob_len)
|
||||
{
|
||||
LIBSSH2_CHANNEL *channel = pkey->channel;
|
||||
LIBSSH2_SESSION *session = channel->session;
|
||||
/* 22 = packet_len(4) + remove_len(4) + "remove"(6) + name_len(4) + {name} + blob_len(4) + {blob} */
|
||||
LIBSSH2_CHANNEL *channel;
|
||||
LIBSSH2_SESSION *session;
|
||||
/* 22 = packet_len(4) + remove_len(4) + "remove"(6) + name_len(4) + {name}
|
||||
+ blob_len(4) + {blob} */
|
||||
unsigned long packet_len = 22 + name_len + blob_len;
|
||||
int rc;
|
||||
|
||||
if(!pkey)
|
||||
return LIBSSH2_ERROR_BAD_USE;
|
||||
|
||||
channel = pkey->channel;
|
||||
session = channel->session;
|
||||
|
||||
if (pkey->remove_state == libssh2_NB_state_idle) {
|
||||
pkey->remove_packet = NULL;
|
||||
|
||||
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;
|
||||
@@ -685,7 +719,8 @@ libssh2_publickey_remove_ex(LIBSSH2_PUBLICKEY * pkey,
|
||||
pkey->remove_s += blob_len;
|
||||
|
||||
_libssh2_debug(session, LIBSSH2_TRACE_PUBLICKEY,
|
||||
"Sending publickey \"remove\" packet: type=%s blob_len=%ld",
|
||||
"Sending publickey \"remove\" packet: "
|
||||
"type=%s blob_len=%ld",
|
||||
name, blob_len);
|
||||
|
||||
pkey->remove_state = libssh2_NB_state_created;
|
||||
@@ -694,14 +729,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 +745,7 @@ libssh2_publickey_remove_ex(LIBSSH2_PUBLICKEY * pkey,
|
||||
}
|
||||
|
||||
rc = publickey_response_success(pkey);
|
||||
if (rc == PACKET_EAGAIN) {
|
||||
if (rc == LIBSSH2_ERROR_EAGAIN) {
|
||||
return rc;
|
||||
}
|
||||
|
||||
@@ -726,14 +761,20 @@ LIBSSH2_API int
|
||||
libssh2_publickey_list_fetch(LIBSSH2_PUBLICKEY * pkey, unsigned long *num_keys,
|
||||
libssh2_publickey_list ** pkey_list)
|
||||
{
|
||||
LIBSSH2_CHANNEL *channel = pkey->channel;
|
||||
LIBSSH2_SESSION *session = channel->session;
|
||||
LIBSSH2_CHANNEL *channel;
|
||||
LIBSSH2_SESSION *session;
|
||||
libssh2_publickey_list *list = NULL;
|
||||
unsigned long buffer_len = 12, keys = 0, max_keys = 0, i;
|
||||
/* 12 = packet_len(4) + list_len(4) + "list"(4) */
|
||||
int response;
|
||||
int rc;
|
||||
|
||||
if(!pkey)
|
||||
return LIBSSH2_ERROR_BAD_USE;
|
||||
|
||||
channel = pkey->channel;
|
||||
session = channel->session;
|
||||
|
||||
if (pkey->listFetch_state == libssh2_NB_state_idle) {
|
||||
pkey->listFetch_data = NULL;
|
||||
|
||||
@@ -756,12 +797,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 +811,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 +824,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 +876,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 +894,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 +936,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++) {
|
||||
@@ -912,13 +952,16 @@ libssh2_publickey_list_fetch(LIBSSH2_PUBLICKEY * pkey, unsigned long *num_keys,
|
||||
pkey->listFetch_s += 4;
|
||||
list[keys].attrs[i].value = (char *) pkey->listFetch_s;
|
||||
pkey->listFetch_s += list[keys].attrs[i].value_len;
|
||||
list[keys].attrs[i].mandatory = 0; /* actually an ignored value */
|
||||
|
||||
/* actually an ignored value */
|
||||
list[keys].attrs[i].mandatory = 0;
|
||||
}
|
||||
} else {
|
||||
list[keys].attrs = NULL;
|
||||
}
|
||||
}
|
||||
list[keys].packet = pkey->listFetch_data; /* To be FREEd in libssh2_publickey_list_free() */
|
||||
/* To be FREEd in libssh2_publickey_list_free() */
|
||||
list[keys].packet = pkey->listFetch_data;
|
||||
keys++;
|
||||
|
||||
list[keys].packet = NULL; /* Terminate the list */
|
||||
@@ -926,8 +969,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");
|
||||
LIBSSH2_FREE(session, pkey->listFetch_data);
|
||||
pkey->listFetch_data = NULL;
|
||||
}
|
||||
@@ -953,9 +996,14 @@ LIBSSH2_API void
|
||||
libssh2_publickey_list_free(LIBSSH2_PUBLICKEY * pkey,
|
||||
libssh2_publickey_list * pkey_list)
|
||||
{
|
||||
LIBSSH2_SESSION *session = pkey->channel->session;
|
||||
LIBSSH2_SESSION *session;
|
||||
libssh2_publickey_list *p = pkey_list;
|
||||
|
||||
if(!pkey || !p)
|
||||
return;
|
||||
|
||||
session = pkey->channel->session;
|
||||
|
||||
while (p->packet) {
|
||||
if (p->attrs) {
|
||||
LIBSSH2_FREE(session, p->attrs);
|
||||
@@ -971,11 +1019,16 @@ libssh2_publickey_list_free(LIBSSH2_PUBLICKEY * pkey,
|
||||
* Shutdown the publickey subsystem
|
||||
*/
|
||||
LIBSSH2_API int
|
||||
libssh2_publickey_shutdown(LIBSSH2_PUBLICKEY * pkey)
|
||||
libssh2_publickey_shutdown(LIBSSH2_PUBLICKEY *pkey)
|
||||
{
|
||||
LIBSSH2_SESSION *session = pkey->channel->session;
|
||||
LIBSSH2_SESSION *session;
|
||||
int rc;
|
||||
|
||||
if(!pkey)
|
||||
return LIBSSH2_ERROR_BAD_USE;
|
||||
|
||||
session = pkey->channel->session;
|
||||
|
||||
/*
|
||||
* Make sure all memory used in the state variables are free
|
||||
*/
|
||||
@@ -996,8 +1049,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);
|
||||
|
460
src/scp.c
460
src/scp.c
@@ -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,17 @@ 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 %"
|
||||
LIBSSH2_INT64_T_FORMAT "u %s\n", mode,
|
||||
size, base);
|
||||
_libssh2_debug(session, LIBSSH2_TRACE_SCP, "Sent %s",
|
||||
session->scpSend_response);
|
||||
|
||||
@@ -952,13 +952,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 +969,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 +1001,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 +1019,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 +1029,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,
|
||||
|
238
src/session.c
238
src/session.c
@@ -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,14 @@ libssh2_session_callback_set(LIBSSH2_SESSION * session,
|
||||
int _libssh2_wait_socket(LIBSSH2_SESSION *session)
|
||||
{
|
||||
int rc;
|
||||
int dir;
|
||||
int seconds_to_next;
|
||||
int dir;
|
||||
|
||||
/* since libssh2 often sets EAGAIN internally before this function is
|
||||
called, we can decrease some amount of confusion in user programs by
|
||||
resetting the error code in this function to reduce the risk of EAGAIN
|
||||
being stored as error when a blocking function has returned */
|
||||
session->err_code = LIBSSH2_ERROR_NONE;
|
||||
|
||||
rc = libssh2_keepalive_send (session, &seconds_to_next);
|
||||
if (rc < 0)
|
||||
@@ -528,43 +556,50 @@ 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 +621,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 +640,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 +649,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 +672,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 +683,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 +706,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 +765,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 +775,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;
|
||||
}
|
||||
|
||||
@@ -827,6 +843,9 @@ session_free(LIBSSH2_SESSION *session)
|
||||
LIBSSH2_FREE(session, session->hostkey_prefs);
|
||||
}
|
||||
|
||||
if (session->local.kexinit) {
|
||||
LIBSSH2_FREE(session, session->local.kexinit);
|
||||
}
|
||||
if (session->local.crypt_prefs) {
|
||||
LIBSSH2_FREE(session, session->local.crypt_prefs);
|
||||
}
|
||||
@@ -840,6 +859,9 @@ session_free(LIBSSH2_SESSION *session)
|
||||
LIBSSH2_FREE(session, session->local.lang_prefs);
|
||||
}
|
||||
|
||||
if (session->remote.kexinit) {
|
||||
LIBSSH2_FREE(session, session->remote.kexinit);
|
||||
}
|
||||
if (session->remote.crypt_prefs) {
|
||||
LIBSSH2_FREE(session, session->remote.crypt_prefs);
|
||||
}
|
||||
@@ -856,6 +878,9 @@ session_free(LIBSSH2_SESSION *session)
|
||||
/*
|
||||
* Make sure all memory used in the state variables are free
|
||||
*/
|
||||
if (session->kexinit_data) {
|
||||
LIBSSH2_FREE(session, session->kexinit_data);
|
||||
}
|
||||
if (session->startup_data) {
|
||||
LIBSSH2_FREE(session, session->startup_data);
|
||||
}
|
||||
@@ -998,35 +1023,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 +1117,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;
|
||||
}
|
||||
|
||||
@@ -1256,10 +1268,16 @@ libssh2_session_get_blocking(LIBSSH2_SESSION * session)
|
||||
* non-0 if data is available
|
||||
*/
|
||||
LIBSSH2_API int
|
||||
libssh2_poll_channel_read(LIBSSH2_CHANNEL * channel, int extended)
|
||||
libssh2_poll_channel_read(LIBSSH2_CHANNEL *channel, int extended)
|
||||
{
|
||||
LIBSSH2_SESSION *session = channel->session;
|
||||
LIBSSH2_PACKET *packet = _libssh2_list_first(&session->packets);
|
||||
LIBSSH2_SESSION *session;
|
||||
LIBSSH2_PACKET *packet;
|
||||
|
||||
if(!channel)
|
||||
return LIBSSH2_ERROR_BAD_USE;
|
||||
|
||||
session = channel->session;
|
||||
packet = _libssh2_list_first(&session->packets);
|
||||
|
||||
while (packet) {
|
||||
if ( channel->local.id == _libssh2_ntohu32(packet->data + 1)) {
|
||||
@@ -1352,8 +1370,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 +1417,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
91
src/session.h
Normal 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 */
|
1316
src/sftp.c
1316
src/sftp.c
File diff suppressed because it is too large
Load Diff
104
src/transport.c
104
src/transport.c
@@ -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 */
|
||||
}
|
||||
|
@@ -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 */
|
||||
|
692
src/userauth.c
692
src/userauth.c
File diff suppressed because it is too large
Load Diff
50
src/userauth.h
Normal file
50
src/userauth.h
Normal 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
82
vms/libssh2_config.h
Normal 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 */
|
124
vms/libssh2_make_example.dcl
Normal file
124
vms/libssh2_make_example.dcl
Normal 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
91
vms/libssh2_make_help.dcl
Normal 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
222
vms/libssh2_make_kit.dcl
Normal 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
344
vms/libssh2_make_lib.dcl
Normal 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
516
vms/man2help.c
Normal 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
319
vms/readme.vms
Normal 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
|
||||
|
||||
|
||||
|
||||
|
||||
|
179
win32/Makefile.Watcom
Normal file
179
win32/Makefile.Watcom
Normal file
@@ -0,0 +1,179 @@
|
||||
#
|
||||
# Watcom / OpenWatcom Win32 makefile for libssh2.
|
||||
#
|
||||
# Comments to: Guenter Knauf http://www.gknw.net/phpbb
|
||||
#
|
||||
|
||||
!ifndef %watcom
|
||||
!error WATCOM environment variable not set!
|
||||
!else
|
||||
SYS_INCL = -I$(%watcom)\h\nt -I$(%watcom)\h
|
||||
SYS_LIBS = $(%watcom)\lib386\nt;$(%watcom)\lib386
|
||||
!endif
|
||||
|
||||
!ifdef %libname
|
||||
LIBNAME = $(%libname)
|
||||
!else
|
||||
LIBNAME = libssh2
|
||||
!endif
|
||||
TARGETS = $(LIBNAME).dll $(LIBNAME)_imp.lib $(LIBNAME).lib
|
||||
|
||||
CC = wcc386
|
||||
LD = wlink
|
||||
AR = wlib
|
||||
RC = wrc
|
||||
|
||||
!ifdef __LOADDLL__
|
||||
! loaddll wcc386 wccd386
|
||||
! loaddll wpp386 wppd386
|
||||
! loaddll wlib wlibd
|
||||
! if $(__VERSION__) > 1270
|
||||
! loaddll wlink wlinkd
|
||||
! else
|
||||
! loaddll wlink wlink
|
||||
! endif
|
||||
!endif
|
||||
|
||||
!if $(__VERSION__) < 1250
|
||||
RM = del /q /f >NUL 2>&1
|
||||
!else
|
||||
RM = rm -f
|
||||
!endif
|
||||
MD = mkdir
|
||||
RD = rmdir /q /s >NUL 2>&1
|
||||
CP = copy
|
||||
|
||||
CFLAGS = -3r -mf -hc -zff -zgf -zq -zm -zc -s -fr=nul -w2 -fpi -oilrtfm &
|
||||
-wcd=201 -bt=nt -d+ -dWIN32 -DLIBSSH2_WIN32 &
|
||||
-I. -I..\include $(SYS_INCL)
|
||||
|
||||
!ifdef %debug
|
||||
DEBUG = -dDEBUG=1 -dDEBUGBUILD
|
||||
CFLAGS += -d3 $(DEBUG)
|
||||
!else
|
||||
CFLAGS += -d0
|
||||
!endif
|
||||
|
||||
!ifdef %use_ipv6
|
||||
CFLAGS += -d_WIN32_WINNT=0x0501 -dENABLE_IPV6
|
||||
!endif
|
||||
|
||||
#
|
||||
# Change to suite.
|
||||
#
|
||||
!ifdef %zlib_root
|
||||
ZLIB_ROOT = $(%zlib_root)
|
||||
!else
|
||||
ZLIB_ROOT = ..\..\zlib-1.2.5
|
||||
!endif
|
||||
|
||||
!ifdef %openssl_root
|
||||
OPENSSL_ROOT = $(%openssl_root)
|
||||
!else
|
||||
OPENSSL_ROOT = ..\..\openssl-0.9.8o
|
||||
!endif
|
||||
|
||||
#!ifdef %use_zlib
|
||||
CFLAGS += -dHAVE_ZLIB_H -dHAVE_LIBZ -I$(ZLIB_ROOT)
|
||||
#!endif
|
||||
|
||||
#!ifdef %use_ssl
|
||||
CFLAGS += -wcd=138 -dUSE_OPENSSL -dUSE_SSLEAY -I$(OPENSSL_ROOT)\inc32
|
||||
#!endif
|
||||
|
||||
!ifdef %use_watt32
|
||||
CFLAGS += -dUSE_WATT32 -I$(%watt_root)\inc
|
||||
!endif
|
||||
|
||||
OBJ_BASE = WC_Win32.obj
|
||||
LINK_ARG = $(OBJ_BASE)\dyn\wlink.arg
|
||||
LIB_ARG = $(OBJ_BASE)\stat\wlib.arg
|
||||
|
||||
# In order to process Makefile.inc wmake must be called with -u switch!
|
||||
!ifndef %MAKEFLAGS
|
||||
!error You MUST call wmake with the -u switch!
|
||||
!else
|
||||
!include ..\Makefile.inc
|
||||
!endif
|
||||
|
||||
OBJS = $(CSOURCES:.c=.obj)
|
||||
OBJS = $OBJ_DIR\$(OBJS: = $OBJ_DIR\)
|
||||
|
||||
#
|
||||
# Use $(OBJS) as a template to generate $(OBJS_STAT) and $(OBJS_DYN).
|
||||
#
|
||||
OBJ_DIR = $(OBJ_BASE)\stat
|
||||
OBJS_STAT = $+ $(OBJS) $-
|
||||
|
||||
OBJ_DIR = $(OBJ_BASE)\dyn
|
||||
OBJS_DYN = $+ $(OBJS) $-
|
||||
|
||||
RESOURCE = $(OBJ_BASE)\dyn\libssh2.res
|
||||
|
||||
.c: ..\src
|
||||
|
||||
|
||||
all: $(OBJ_BASE) $(TARGETS) .SYMBOLIC
|
||||
@echo Welcome to libssh2
|
||||
|
||||
clean: .SYMBOLIC
|
||||
-$(RM) $(OBJS_STAT)
|
||||
-$(RM) $(OBJS_DYN)
|
||||
-$(RM) $(RESOURCE) $(LINK_ARG) $(LIB_ARG)
|
||||
|
||||
vclean realclean: clean .SYMBOLIC
|
||||
-$(RM) $(TARGETS) $(LIBNAME).map $(LIBNAME).sym
|
||||
-$(RD) $(OBJ_BASE)\stat
|
||||
-$(RD) $(OBJ_BASE)\dyn
|
||||
-$(RD) $(OBJ_BASE)
|
||||
|
||||
$(OBJ_BASE):
|
||||
-$(MD) $^@
|
||||
-$(MD) $^@\stat
|
||||
-$(MD) $^@\dyn
|
||||
|
||||
$(LIBNAME).dll: $(OBJS_DYN) $(RESOURCE) $(LINK_ARG)
|
||||
$(LD) name $^@ @$]@
|
||||
|
||||
$(LIBNAME).lib: $(OBJS_STAT) $(LIB_ARG)
|
||||
$(AR) -q -b -c $^@ @$]@
|
||||
|
||||
.ERASE
|
||||
$(RESOURCE): libssh2.rc
|
||||
$(RC) $(DEBUG) -q -r -zm -DLIBSSH2_VERSION_ONLY -I..\include $(SYS_INCL) $[@ -fo=$^@
|
||||
|
||||
.ERASE
|
||||
.c{$(OBJ_BASE)\dyn}.obj:
|
||||
$(CC) $(CFLAGS) -bd -br $[@ -fo=$^@
|
||||
|
||||
.ERASE
|
||||
.c{$(OBJ_BASE)\stat}.obj:
|
||||
$(CC) $(CFLAGS) $[@ -fo=$^@
|
||||
|
||||
$(LINK_ARG): $(__MAKEFILES__)
|
||||
%create $^@
|
||||
@%append $^@ system nt dll
|
||||
@%append $^@ file { $(OBJS_DYN) }
|
||||
!ifdef %debug
|
||||
@%append $^@ debug all
|
||||
@%append $^@ option symfile
|
||||
!endif
|
||||
@%append $^@ option quiet, map, caseexact, eliminate, implib=$(LIBNAME)_imp.lib,
|
||||
@%append $^@ res=$(RESOURCE) libpath $(SYS_LIBS)
|
||||
!ifdef %use_watt32
|
||||
@%append $^@ library $(%watt_root)\lib\wattcpw_imp.lib
|
||||
!else
|
||||
@%append $^@ library ws2_32.lib
|
||||
!endif
|
||||
#!ifdef %use_zlib
|
||||
@%append $^@ library $(ZLIB_ROOT)\zlib.lib
|
||||
#!endif
|
||||
#!ifdef %use_ssl
|
||||
@%append $^@ library $(OPENSSL_ROOT)\out32\libeay32.lib, $(OPENSSL_ROOT)\out32\ssleay32.lib
|
||||
#!endif
|
||||
|
||||
$(LIB_ARG): $(__MAKEFILES__)
|
||||
%create $^@
|
||||
@for %f in ($(OBJS_STAT)) do @%append $^@ +- %f
|
||||
|
||||
|
@@ -3,22 +3,20 @@
|
||||
## Makefile for building libssh2 (Win32 version - gnu make)
|
||||
## Use: make -f Makefile.win32 [help|all|clean|dev|devclean|dist|distclean|dll|objclean]
|
||||
##
|
||||
## Comments to: Guenter Knauf <eflash@gmx.net>
|
||||
##
|
||||
## $Id: Makefile.win32,v 1.11 2009/04/09 03:13:52 gknauf Exp $
|
||||
## Comments to: Guenter Knauf http://www.gknw.net/phpbb
|
||||
#
|
||||
#########################################################################
|
||||
|
||||
# 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.8o
|
||||
endif
|
||||
|
||||
# Edit the path below to point to your Distribution folder.
|
||||
@@ -36,7 +34,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) $(LIBSSH2_COPYRIGHT_STR)
|
||||
WWWURL = http://www.libssh2.org/
|
||||
DESCR = libssh2 $(LIBSSH2_VERSION_STR)
|
||||
#STACK = 64000
|
||||
@@ -68,7 +66,7 @@ endif
|
||||
CP = cp -afv
|
||||
# RM = rm -f
|
||||
# Here you can find a native Win32 binary of the original awk:
|
||||
# http://www.gknw.net/development/prgtools/awk.zip
|
||||
# http://www.gknw.net/development/prgtools/awk-20070501.zip
|
||||
AWK = awk
|
||||
ZIP = zip -qzr9
|
||||
|
||||
@@ -222,46 +220,10 @@ $(TARGET).dll $(TARGET)dll.a: $(OBJL)
|
||||
@$(LD) $(LDFLAGS) $^ -o $@ $(LIBPATH) $(LDLIBS)
|
||||
|
||||
|
||||
$(OBJDIR)/%.res: $(OBJDIR)/%.rc
|
||||
$(OBJDIR)/%.res: %.rc
|
||||
@echo Creating $@
|
||||
@$(RC) $(RCFLAGS) $< -o $@
|
||||
@$(RC) $(RCFLAGS) -DLIBSSH2_VERSION_ONLY -I. -I ../include $< -o $@
|
||||
|
||||
$(OBJDIR)/%.rc: Makefile.win32 $(OBJDIR)/version.inc
|
||||
@echo $(DL)1 VERSIONINFO$(DL) > $@
|
||||
@echo $(DL) FILEVERSION $(LIBSSH2_VERSION),0$(DL) >> $@
|
||||
@echo $(DL) PRODUCTVERSION $(LIBSSH2_VERSION),0$(DL) >> $@
|
||||
@echo $(DL) FILEFLAGSMASK 0x3fL$(DL) >> $@
|
||||
@echo $(DL) FILEOS 0x40004L$(DL) >> $@
|
||||
@echo $(DL) FILEFLAGS 0x0L$(DL) >> $@
|
||||
@echo $(DL) FILETYPE 0x1L$(DL) >> $@
|
||||
@echo $(DL) FILESUBTYPE 0x0L$(DL) >> $@
|
||||
@echo $(DL)BEGIN$(DL) >> $@
|
||||
@echo $(DL) BLOCK "StringFileInfo"$(DL) >> $@
|
||||
@echo $(DL) BEGIN$(DL) >> $@
|
||||
@echo $(DL) BLOCK "040904E4"$(DL) >> $@
|
||||
@echo $(DL) BEGIN$(DL) >> $@
|
||||
@echo $(DL) VALUE "LegalCopyright","$(COPYR)\0"$(DL) >> $@
|
||||
ifdef COMPANY
|
||||
@echo $(DL) VALUE "CompanyName","$(COMPANY)\0"$(DL) >> $@
|
||||
endif
|
||||
@echo $(DL) VALUE "ProductName","$(notdir $(@:.rc=.dll))\0"$(DL) >> $@
|
||||
@echo $(DL) VALUE "ProductVersion","$(LIBSSH2_VERSION_STR)\0"$(DL) >> $@
|
||||
@echo $(DL) VALUE "License","Released under the Modified BSD license.\0"$(DL) >> $@
|
||||
@echo $(DL) VALUE "FileDescription","$(DESCR)\0"$(DL) >> $@
|
||||
@echo $(DL) VALUE "FileVersion","$(LIBSSH2_VERSION_STR)\0"$(DL) >> $@
|
||||
@echo $(DL) VALUE "InternalName","$(notdir $(@:.rc=))\0"$(DL) >> $@
|
||||
@echo $(DL) VALUE "OriginalFilename","$(notdir $(@:.rc=.dll))\0"$(DL) >> $@
|
||||
@echo $(DL) VALUE "WWW","$(WWWURL)\0"$(DL) >> $@
|
||||
@echo $(DL) END$(DL) >> $@
|
||||
@echo $(DL) END$(DL) >> $@
|
||||
@echo $(DL) BLOCK "VarFileInfo"$(DL) >> $@
|
||||
@echo $(DL) BEGIN$(DL) >> $@
|
||||
@echo $(DL) VALUE "Translation", 0x409, 1252$(DL) >> $@
|
||||
@echo $(DL) END$(DL) >> $@
|
||||
@echo $(DL)END$(DL) >> $@
|
||||
ifdef ICON
|
||||
@echo $(DL)10 ICON DISCARDABLE "$(ICON)"$(DL) >> $@
|
||||
endif
|
||||
|
||||
$(DISTDIR)/readme.txt: Makefile.win32
|
||||
@echo Creating $@
|
||||
|
@@ -1,10 +1,10 @@
|
||||
|
||||
# Tweak these for your system
|
||||
OPENSSLINC=..\openssl-0.9.8e\inc32
|
||||
OPENSSLLIB=..\openssl-0.9.8e\out32dll
|
||||
OPENSSLINC=..\openssl-0.9.8o\inc32
|
||||
OPENSSLLIB=..\openssl-0.9.8o\out32dll
|
||||
|
||||
ZLIBINC=-DLIBSSH2_HAVE_ZLIB=1 /I..\zlib-1.2.3
|
||||
ZLIBLIB=..\zlib-1.2.3
|
||||
ZLIBINC=-DLIBSSH2_HAVE_ZLIB=1 /I..\zlib-1.2.5
|
||||
ZLIBLIB=..\zlib-1.2.5
|
||||
|
||||
!if "$(TARGET)" == ""
|
||||
TARGET=Release
|
||||
|
@@ -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>
|
||||
{{{
|
||||
|
45
win32/libssh2.rc
Normal file
45
win32/libssh2.rc
Normal file
@@ -0,0 +1,45 @@
|
||||
/***************************************************************************
|
||||
* libssh2 Win32 resource file *
|
||||
***************************************************************************/
|
||||
#include <winver.h>
|
||||
#include "../include/libssh2.h"
|
||||
|
||||
LANGUAGE 0x09,0x01
|
||||
|
||||
#define RC_VERSION LIBSSH2_VERSION_MAJOR, LIBSSH2_VERSION_MINOR, LIBSSH2_VERSION_PATCH, 0
|
||||
|
||||
VS_VERSION_INFO VERSIONINFO
|
||||
FILEVERSION RC_VERSION
|
||||
PRODUCTVERSION RC_VERSION
|
||||
FILEFLAGSMASK 0x3fL
|
||||
#if defined(DEBUGBUILD) || defined(_DEBUG)
|
||||
FILEFLAGS 1
|
||||
#else
|
||||
FILEFLAGS 0
|
||||
#endif
|
||||
FILEOS VOS__WINDOWS32
|
||||
FILETYPE VFT_DLL
|
||||
FILESUBTYPE 0x0L
|
||||
|
||||
BEGIN
|
||||
BLOCK "StringFileInfo"
|
||||
BEGIN
|
||||
BLOCK "040904b0"
|
||||
BEGIN
|
||||
VALUE "CompanyName", "The libssh2 library, http://www.libssh2.org/\0"
|
||||
VALUE "FileDescription", "libssh2 Shared Library\0"
|
||||
VALUE "FileVersion", LIBSSH2_VERSION "\0"
|
||||
VALUE "InternalName", "libssh2\0"
|
||||
VALUE "OriginalFilename", "libssh2.dll\0"
|
||||
VALUE "ProductName", "The libssh2 library\0"
|
||||
VALUE "ProductVersion", LIBSSH2_VERSION "\0"
|
||||
VALUE "LegalCopyright", "<22> " LIBSSH2_COPYRIGHT "\0"
|
||||
VALUE "License", "http://www.libssh2.org/license.html\0"
|
||||
END
|
||||
END
|
||||
|
||||
BLOCK "VarFileInfo"
|
||||
BEGIN
|
||||
VALUE "Translation", 0x409, 1200
|
||||
END
|
||||
END
|
@@ -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 */
|
||||
|
||||
|
||||
|
@@ -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
|
||||
|
||||
|
@@ -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
|
||||
|
||||
|
@@ -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"
|
||||
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user