1
0
mirror of https://github.com/nmap/nmap.git synced 2025-12-15 12:19:02 +00:00

Upgrade libssh2 to 1.9.0

This commit is contained in:
dmiller
2019-09-25 04:42:40 +00:00
parent 41b05333c6
commit 1ae88d2620
67 changed files with 15385 additions and 9976 deletions

1
.gitignore vendored
View File

@@ -44,6 +44,7 @@ libpcap/pcap-savefile.manfile
libpcap/pcap-tstamp.manmisc libpcap/pcap-tstamp.manmisc
libpcap/pcap_version.h libpcap/pcap_version.h
libssh2/src/libssh2_config.h libssh2/src/libssh2_config.h
libssh2/lib/
libpcre/pcre-config libpcre/pcre-config
ndiff/INSTALLED_FILES ndiff/INSTALLED_FILES
libz/contrib/vstudio/vc11/Debug_lib/ libz/contrib/vstudio/vc11/Debug_lib/

View File

@@ -1,5 +1,7 @@
#Nmap Changelog ($Id$); -*-text-*- #Nmap Changelog ($Id$); -*-text-*-
o Upgrade libssh2 to 1.9.0, fixing compilation with OpenSSL 1.1.0 API.
o [GH#1717][GH#1718] Processing of IP address CIDR blocks was not working o [GH#1717][GH#1718] Processing of IP address CIDR blocks was not working
correctly on ppc64, ppc64le, and s390x architectures. [rfrohl, nnposter] correctly on ppc64, ppc64le, and s390x architectures. [rfrohl, nnposter]

View File

@@ -1,2 +1,3 @@
CRYPTO_CSOURCES = openssl.c CRYPTO_CSOURCES = openssl.c
CRYPTO_HHEADERS = openssl.h CRYPTO_HHEADERS = openssl.h
CRYPTO_LTLIBS = $(LTLIBSSL)

View File

@@ -1,2 +1,3 @@
CRYPTO_CSOURCES = wincng.c CRYPTO_CSOURCES = wincng.c
CRYPTO_HHEADERS = wincng.h CRYPTO_HHEADERS = wincng.h
CRYPTO_LTLIBS = $(LTLIBBCRYPT) $(LTLIBCRYPT32)

View File

@@ -1,10 +1,9 @@
AUTOMAKE_OPTIONS = foreign nostdinc AUTOMAKE_OPTIONS = foreign nostdinc
SUBDIRS = src SUBDIRS = src tests docs
#SUBDIRS = src tests docs if BUILD_EXAMPLES
#if BUILD_EXAMPLES SUBDIRS += example
#SUBDIRS += example endif
#endif
pkgconfigdir = $(libdir)/pkgconfig pkgconfigdir = $(libdir)/pkgconfig
pkgconfig_DATA = libssh2.pc pkgconfig_DATA = libssh2.pc
@@ -148,3 +147,6 @@ $(VCPROJ): win32/vc8proj.head win32/vc8proj.foot Makefile.am
done; \ done; \
cat $(srcdir)/vc8proj.foot) | \ cat $(srcdir)/vc8proj.foot) | \
awk '{printf("%s\r\n", gensub("\r", "", "g"))}' > $@ ) awk '{printf("%s\r\n", gensub("\r", "", "g"))}' > $@ )
checksrc:
perl src/checksrc.pl -i4 -m79 -ASIZEOFNOPAREN -ASNPRINTF -ACOPYRIGHT -AFOPENMODE -Wsrc/libssh2_config.h src/*.[ch] include/*.h example/*.c

View File

@@ -1,7 +1,7 @@
# Makefile.in generated by automake 1.15 from Makefile.am. # Makefile.in generated by automake 1.16.1 from Makefile.am.
# @configure_input@ # @configure_input@
# Copyright (C) 1994-2014 Free Software Foundation, Inc. # Copyright (C) 1994-2018 Free Software Foundation, Inc.
# This Makefile.in is free software; the Free Software Foundation # This Makefile.in is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it, # gives unlimited permission to copy and/or distribute it,
@@ -89,6 +89,7 @@ PRE_UNINSTALL = :
POST_UNINSTALL = : POST_UNINSTALL = :
build_triplet = @build@ build_triplet = @build@
host_triplet = @host@ host_triplet = @host@
@BUILD_EXAMPLES_TRUE@am__append_1 = example
subdir = . subdir = .
ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
am__aclocal_m4_deps = $(top_srcdir)/m4/autobuild.m4 \ am__aclocal_m4_deps = $(top_srcdir)/m4/autobuild.m4 \
@@ -173,7 +174,7 @@ am__recursive_targets = \
$(RECURSIVE_CLEAN_TARGETS) \ $(RECURSIVE_CLEAN_TARGETS) \
$(am__extra_recursive_targets) $(am__extra_recursive_targets)
AM_RECURSIVE_TARGETS = $(am__recursive_targets:-recursive=) TAGS CTAGS \ AM_RECURSIVE_TARGETS = $(am__recursive_targets:-recursive=) TAGS CTAGS \
cscope distdir dist dist-all distcheck cscope distdir distdir-am dist dist-all distcheck
am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP)
# Read a list of newline-separated strings from the standard input, # Read a list of newline-separated strings from the standard input,
# and print each of them once, without duplicates. Input order is # and print each of them once, without duplicates. Input order is
@@ -194,7 +195,7 @@ am__define_uniq_tagged_files = \
ETAGS = etags ETAGS = etags
CTAGS = ctags CTAGS = ctags
CSCOPE = cscope CSCOPE = cscope
DIST_SUBDIRS = $(SUBDIRS) DIST_SUBDIRS = src tests docs example
am__DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/Makefile.inc \ am__DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/Makefile.inc \
$(srcdir)/libssh2.pc.in COPYING ChangeLog NEWS README compile \ $(srcdir)/libssh2.pc.in COPYING ChangeLog NEWS README compile \
config.guess config.rpath config.sub depcomp install-sh \ config.guess config.rpath config.sub depcomp install-sh \
@@ -272,7 +273,7 @@ GREP = @GREP@
HAVE_LIBBCRYPT = @HAVE_LIBBCRYPT@ HAVE_LIBBCRYPT = @HAVE_LIBBCRYPT@
HAVE_LIBCRYPT32 = @HAVE_LIBCRYPT32@ HAVE_LIBCRYPT32 = @HAVE_LIBCRYPT32@
HAVE_LIBGCRYPT = @HAVE_LIBGCRYPT@ HAVE_LIBGCRYPT = @HAVE_LIBGCRYPT@
HAVE_LIBMBEDTLS = @HAVE_LIBMBEDTLS@ HAVE_LIBMBEDCRYPTO = @HAVE_LIBMBEDCRYPTO@
HAVE_LIBSSL = @HAVE_LIBSSL@ HAVE_LIBSSL = @HAVE_LIBSSL@
HAVE_LIBZ = @HAVE_LIBZ@ HAVE_LIBZ = @HAVE_LIBZ@
INSTALL = @INSTALL@ INSTALL = @INSTALL@
@@ -288,8 +289,8 @@ LIBCRYPT32 = @LIBCRYPT32@
LIBCRYPT32_PREFIX = @LIBCRYPT32_PREFIX@ LIBCRYPT32_PREFIX = @LIBCRYPT32_PREFIX@
LIBGCRYPT = @LIBGCRYPT@ LIBGCRYPT = @LIBGCRYPT@
LIBGCRYPT_PREFIX = @LIBGCRYPT_PREFIX@ LIBGCRYPT_PREFIX = @LIBGCRYPT_PREFIX@
LIBMBEDTLS = @LIBMBEDTLS@ LIBMBEDCRYPTO = @LIBMBEDCRYPTO@
LIBMBEDTLS_PREFIX = @LIBMBEDTLS_PREFIX@ LIBMBEDCRYPTO_PREFIX = @LIBMBEDCRYPTO_PREFIX@
LIBOBJS = @LIBOBJS@ LIBOBJS = @LIBOBJS@
LIBS = @LIBS@ LIBS = @LIBS@
LIBSREQUIRED = @LIBSREQUIRED@ LIBSREQUIRED = @LIBSREQUIRED@
@@ -304,7 +305,7 @@ LN_S = @LN_S@
LTLIBBCRYPT = @LTLIBBCRYPT@ LTLIBBCRYPT = @LTLIBBCRYPT@
LTLIBCRYPT32 = @LTLIBCRYPT32@ LTLIBCRYPT32 = @LTLIBCRYPT32@
LTLIBGCRYPT = @LTLIBGCRYPT@ LTLIBGCRYPT = @LTLIBGCRYPT@
LTLIBMBEDTLS = @LTLIBMBEDTLS@ LTLIBMBEDCRYPTO = @LTLIBMBEDCRYPTO@
LTLIBOBJS = @LTLIBOBJS@ LTLIBOBJS = @LTLIBOBJS@
LTLIBSSL = @LTLIBSSL@ LTLIBSSL = @LTLIBSSL@
LTLIBZ = @LTLIBZ@ LTLIBZ = @LTLIBZ@
@@ -388,7 +389,7 @@ top_build_prefix = @top_build_prefix@
top_builddir = @top_builddir@ top_builddir = @top_builddir@
top_srcdir = @top_srcdir@ top_srcdir = @top_srcdir@
AUTOMAKE_OPTIONS = foreign nostdinc AUTOMAKE_OPTIONS = foreign nostdinc
SUBDIRS = src SUBDIRS = src tests docs $(am__append_1)
pkgconfigdir = $(libdir)/pkgconfig pkgconfigdir = $(libdir)/pkgconfig
pkgconfig_DATA = libssh2.pc pkgconfig_DATA = libssh2.pc
include_HEADERS = \ include_HEADERS = \
@@ -436,10 +437,11 @@ CRYPTO_CSOURCES = openssl.c wincng.c mbedtls.c
CRYPTO_HHEADERS = openssl.h wincng.h mbedtls.h CRYPTO_HHEADERS = openssl.h wincng.h mbedtls.h
CSOURCES = channel.c comp.c crypt.c hostkey.c kex.c mac.c misc.c \ CSOURCES = channel.c comp.c crypt.c hostkey.c kex.c mac.c misc.c \
packet.c publickey.c scp.c session.c sftp.c userauth.c transport.c \ packet.c publickey.c scp.c session.c sftp.c userauth.c transport.c \
version.c knownhost.c agent.c $(CRYPTO_CSOURCES) pem.c keepalive.c global.c version.c knownhost.c agent.c $(CRYPTO_CSOURCES) pem.c keepalive.c global.c \
blowfish.c bcrypt_pbkdf.c
HHEADERS = libssh2_priv.h $(CRYPTO_HHEADERS) transport.h channel.h comp.h \ HHEADERS = libssh2_priv.h $(CRYPTO_HHEADERS) transport.h channel.h comp.h \
mac.h misc.h packet.h userauth.h session.h sftp.h crypto.h mac.h misc.h packet.h userauth.h session.h sftp.h crypto.h blf.h
# Makefile.inc provides the CSOURCES and HHEADERS defines # Makefile.inc provides the CSOURCES and HHEADERS defines
WIN32SOURCES = $(CSOURCES) WIN32SOURCES = $(CSOURCES)
@@ -468,8 +470,8 @@ Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
echo ' $(SHELL) ./config.status'; \ echo ' $(SHELL) ./config.status'; \
$(SHELL) ./config.status;; \ $(SHELL) ./config.status;; \
*) \ *) \
echo ' cd $(top_builddir) && $(SHELL) ./config.status $@ $(am__depfiles_maybe)'; \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $@ $(am__maybe_remake_depfiles)'; \
cd $(top_builddir) && $(SHELL) ./config.status $@ $(am__depfiles_maybe);; \ cd $(top_builddir) && $(SHELL) ./config.status $@ $(am__maybe_remake_depfiles);; \
esac; esac;
$(srcdir)/Makefile.inc $(am__empty): $(srcdir)/Makefile.inc $(am__empty):
@@ -641,7 +643,10 @@ distclean-tags:
-rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
-rm -f cscope.out cscope.in.out cscope.po.out cscope.files -rm -f cscope.out cscope.in.out cscope.po.out cscope.files
distdir: $(DISTFILES) distdir: $(BUILT_SOURCES)
$(MAKE) $(AM_MAKEFLAGS) distdir-am
distdir-am: $(DISTFILES)
$(am__remove_distdir) $(am__remove_distdir)
test -d "$(distdir)" || mkdir "$(distdir)" test -d "$(distdir)" || mkdir "$(distdir)"
@srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
@@ -709,7 +714,7 @@ distdir: $(DISTFILES)
! -type d ! -perm -444 -exec $(install_sh) -c -m a+r {} {} \; \ ! -type d ! -perm -444 -exec $(install_sh) -c -m a+r {} {} \; \
|| chmod -R a+r "$(distdir)" || chmod -R a+r "$(distdir)"
dist-gzip: distdir dist-gzip: distdir
tardir=$(distdir) && $(am__tar) | GZIP=$(GZIP_ENV) gzip -c >$(distdir).tar.gz tardir=$(distdir) && $(am__tar) | eval GZIP= gzip $(GZIP_ENV) -c >$(distdir).tar.gz
$(am__post_remove_distdir) $(am__post_remove_distdir)
dist-bzip2: distdir dist-bzip2: distdir
@@ -735,7 +740,7 @@ dist-shar: distdir
@echo WARNING: "Support for shar distribution archives is" \ @echo WARNING: "Support for shar distribution archives is" \
"deprecated." >&2 "deprecated." >&2
@echo WARNING: "It will be removed altogether in Automake 2.0" >&2 @echo WARNING: "It will be removed altogether in Automake 2.0" >&2
shar $(distdir) | GZIP=$(GZIP_ENV) gzip -c >$(distdir).shar.gz shar $(distdir) | eval GZIP= gzip $(GZIP_ENV) -c >$(distdir).shar.gz
$(am__post_remove_distdir) $(am__post_remove_distdir)
dist-zip: distdir dist-zip: distdir
@@ -753,7 +758,7 @@ dist dist-all:
distcheck: dist distcheck: dist
case '$(DIST_ARCHIVES)' in \ case '$(DIST_ARCHIVES)' in \
*.tar.gz*) \ *.tar.gz*) \
GZIP=$(GZIP_ENV) gzip -dc $(distdir).tar.gz | $(am__untar) ;;\ eval GZIP= gzip $(GZIP_ENV) -dc $(distdir).tar.gz | $(am__untar) ;;\
*.tar.bz2*) \ *.tar.bz2*) \
bzip2 -dc $(distdir).tar.bz2 | $(am__untar) ;;\ bzip2 -dc $(distdir).tar.bz2 | $(am__untar) ;;\
*.tar.lz*) \ *.tar.lz*) \
@@ -763,7 +768,7 @@ distcheck: dist
*.tar.Z*) \ *.tar.Z*) \
uncompress -c $(distdir).tar.Z | $(am__untar) ;;\ uncompress -c $(distdir).tar.Z | $(am__untar) ;;\
*.shar.gz*) \ *.shar.gz*) \
GZIP=$(GZIP_ENV) gzip -dc $(distdir).shar.gz | unshar ;;\ eval GZIP= gzip $(GZIP_ENV) -dc $(distdir).shar.gz | unshar ;;\
*.zip*) \ *.zip*) \
unzip $(distdir).zip ;;\ unzip $(distdir).zip ;;\
esac esac
@@ -1052,6 +1057,9 @@ $(VCPROJ): win32/vc8proj.head win32/vc8proj.foot Makefile.am
cat $(srcdir)/vc8proj.foot) | \ cat $(srcdir)/vc8proj.foot) | \
awk '{printf("%s\r\n", gensub("\r", "", "g"))}' > $@ ) awk '{printf("%s\r\n", gensub("\r", "", "g"))}' > $@ )
checksrc:
perl src/checksrc.pl -i4 -m79 -ASIZEOFNOPAREN -ASNPRINTF -ACOPYRIGHT -AFOPENMODE -Wsrc/libssh2_config.h src/*.[ch] include/*.h example/*.c
# Tell versions [3.59,3.63) of GNU make to not export all variables. # Tell versions [3.59,3.63) of GNU make to not export all variables.
# Otherwise a system limit (for SysV at least) may be exceeded. # Otherwise a system limit (for SysV at least) may be exceeded.
.NOEXPORT: .NOEXPORT:

View File

@@ -1,6 +1,7 @@
CSOURCES = channel.c comp.c crypt.c hostkey.c kex.c mac.c misc.c \ CSOURCES = channel.c comp.c crypt.c hostkey.c kex.c mac.c misc.c \
packet.c publickey.c scp.c session.c sftp.c userauth.c transport.c \ packet.c publickey.c scp.c session.c sftp.c userauth.c transport.c \
version.c knownhost.c agent.c $(CRYPTO_CSOURCES) pem.c keepalive.c global.c version.c knownhost.c agent.c $(CRYPTO_CSOURCES) pem.c keepalive.c global.c \
blowfish.c bcrypt_pbkdf.c
HHEADERS = libssh2_priv.h $(CRYPTO_HHEADERS) transport.h channel.h comp.h \ HHEADERS = libssh2_priv.h $(CRYPTO_HHEADERS) transport.h channel.h comp.h \
mac.h misc.h packet.h userauth.h session.h sftp.h crypto.h mac.h misc.h packet.h userauth.h session.h sftp.h crypto.h blf.h

View File

@@ -1,2 +1,3 @@
CRYPTO_CSOURCES = libgcrypt.c CRYPTO_CSOURCES = libgcrypt.c
CRYPTO_HHEADERS = libgcrypt.h CRYPTO_HHEADERS = libgcrypt.h
CRYPTO_LTLIBS = $(LTLIBGCRYPT)

View File

@@ -1,2 +1,3 @@
CRYPTO_CSOURCES = mbedtls.c CRYPTO_CSOURCES = mbedtls.c
CRYPTO_HHEADERS = mbedtls.h CRYPTO_HHEADERS = mbedtls.h
CRYPTO_LTLIBS = $(LTLIBMBEDCRYPTO)

File diff suppressed because it is too large Load Diff

View File

@@ -1,12 +1,44 @@
libssh2 1.8.2 libssh2 1.9.0
This release includes the following bugfixes: This release includes the following enhancements and bugfixes:
o Fixed the misapplied userauth patch that broke 1.8.1 o adds ECDSA keys and host key support when using OpenSSL
o moved the MAX size declarations from the public header o adds ED25519 key and host key support when using OpenSSL 1.1.1
o adds OpenSSH style key file reading
o adds AES CTR mode support when using WinCNG
o adds PEM passphrase protected file support for Libgcrypt and WinCNG
o adds SHA256 hostkey fingerprint
o adds libssh2_agent_get_identity_path() and libssh2_agent_set_identity_path()
o adds explicit zeroing of sensitive data in memory
o adds additional bounds checks to network buffer reads
o adds the ability to use the server default permissions when creating sftp directories
o adds support for building with OpenSSL no engine flag
o adds support for building with LibreSSL
o increased sftp packet size to 256k
o fixed oversized packet handling in sftp
o fixed building with OpenSSL 1.1
o fixed a possible crash if sftp stat gets an unexpected response
o fixed incorrect parsing of the KEX preference string value
o fixed conditional RSA and AES-CTR support
o fixed a small memory leak during the key exchange process
o fixed a possible memory leak of the ssh banner string
o fixed various small memory leaks in the backends
o fixed possible out of bounds read when parsing public keys from the server
o fixed possible out of bounds read when parsing invalid PEM files
o no longer null terminates the scp remote exec command
o now handle errors when diffie hellman key pair generation fails
o fixed compiling on Windows with the flag STDCALL=ON
o improved building instructions
o improved unit tests
This release would not have looked like this without help, code, reports and This release would not have looked like this without help, code, reports and
advice from friends like these: advice from friends like these:
Will Cosgrove Peter Surge, Will Cosgrove, Daniel Stenberg, Alex Arslan, Alex Crichton,
(1 contributors) Thomas Bleeker, Keno Fischer, Marc Hörsken, Marcel Raad, Viktor Szakats,
Kamil Dudka, Panos, Etienne Samson, Tseng Jun, Brendan Shanks, doublex,
Erik B, Jakob Egger, Thomas Lochmatter, alex-weaver, Adrian Moran, Zenju,
gartens, Matthew D. Fuller, Ryan Kelley, Zhen-Huan HWANG, Orivej Desh,
Alexander Curtiss
(29 contributors)

View File

@@ -382,86 +382,130 @@ AC_DEFUN([CURL_CONFIGURE_REENTRANT], [
# #
]) ])
AC_DEFUN([LIBSSH2_CHECKFOR_MBEDTLS], [ dnl LIBSSH2_LIB_HAVE_LINKFLAGS
dnl --------------------------
dnl Wrapper around AC_LIB_HAVE_LINKFLAGS to also check $prefix/lib, if set.
dnl
dnl autoconf only checks $prefix/lib64 if gcc -print-search-dirs output
dnl includes a directory named lib64. So, to find libraries in $prefix/lib
dnl we append -L$prefix/lib to LDFLAGS before checking.
dnl
dnl For conveniece, $4 is expanded if [lib]$1 is found.
old_LDFLAGS=$LDFLAGS AC_DEFUN([LIBSSH2_LIB_HAVE_LINKFLAGS], [
old_CFLAGS=$CFLAGS libssh2_save_CPPFLAGS="$CPPFLAGS"
if test -n "$use_mbedtls" && test "$use_mbedtls" != "no"; then libssh2_save_LDFLAGS="$LDFLAGS"
LDFLAGS="$LDFLAGS -L$use_mbedtls/lib"
CFLAGS="$CFLAGS -I$use_mbedtls/include" if test "${with_lib$1_prefix+set}" = set; then
CPPFLAGS="$CPPFLAGS${CPPFLAGS:+ }-I${with_lib$1_prefix}/include"
LDFLAGS="$LDFLAGS${LDFLAGS:+ }-L${with_lib$1_prefix}/lib"
fi fi
AC_LIB_HAVE_LINKFLAGS([mbedtls], [], [ AC_LIB_HAVE_LINKFLAGS([$1], [$2], [$3])
#include <mbedtls/version.h>
LDFLAGS="$libssh2_save_LDFLAGS"
if test "$ac_cv_lib$1" = "yes"; then :
$4
else
CPPFLAGS="$libssh2_save_CPPFLAGS"
fi
]) ])
if test "$ac_cv_libmbedtls" = "yes"; then AC_DEFUN([LIBSSH2_CHECK_CRYPTO], [
AC_DEFINE(LIBSSH2_MBEDTLS, 1, [Use mbedtls]) if test "$use_crypto" = "auto" && test "$found_crypto" = "none" || test "$use_crypto" = "$1"; then
LIBSREQUIRED= # mbedtls doesn't provide a .pc file m4_case([$1],
LIBS="$LIBS -lmbedtls -lmbedcrypto" [openssl], [
found_crypto=libmbedtls LIBSSH2_LIB_HAVE_LINKFLAGS([ssl], [crypto], [#include <openssl/ssl.h>], [
AC_DEFINE(LIBSSH2_OPENSSL, 1, [Use $1])
LIBSREQUIRED="$LIBSREQUIRED${LIBSREQUIRED:+ }libssl libcrypto"
# Not all OpenSSL have AES-CTR functions.
libssh2_save_LIBS="$LIBS"
LIBS="$LIBS $LIBSSL"
AC_CHECK_FUNCS(EVP_aes_128_ctr)
LIBS="$libssh2_save_LIBS"
found_crypto="$1"
found_crypto_str="OpenSSL (AES-CTR: ${ac_cv_func_EVP_aes_128_ctr:-N/A})"
])
],
[libgcrypt], [
LIBSSH2_LIB_HAVE_LINKFLAGS([gcrypt], [], [#include <gcrypt.h>], [
AC_DEFINE(LIBSSH2_LIBGCRYPT, 1, [Use $1])
found_crypto="$1"
])
],
[mbedtls], [
LIBSSH2_LIB_HAVE_LINKFLAGS([mbedcrypto], [], [#include <mbedtls/version.h>], [
AC_DEFINE(LIBSSH2_MBEDTLS, 1, [Use $1])
found_crypto="$1"
support_clear_memory=yes support_clear_memory=yes
else
# restore
LDFLAGS=$old_LDFLAGS
CFLAGS=$old_CFLAGS
fi
]) ])
],
AC_DEFUN([LIBSSH2_CHECKFOR_GCRYPT], [ [wincng], [
old_LDFLAGS=$LDFLAGS
old_CFLAGS=$CFLAGS
if test -n "$use_libgcrypt" && test "$use_libgcrypt" != "no"; then
LDFLAGS="$LDFLAGS -L$use_libgcrypt/lib"
CFLAGS="$CFLAGS -I$use_libgcrypt/include"
fi
AC_LIB_HAVE_LINKFLAGS([gcrypt], [], [
#include <gcrypt.h>
])
if test "$ac_cv_libgcrypt" = "yes"; then
AC_DEFINE(LIBSSH2_LIBGCRYPT, 1, [Use libgcrypt])
LIBSREQUIRED= # libgcrypt doesn't provide a .pc file. sad face.
LIBS="$LIBS -lgcrypt"
found_crypto=libgcrypt
else
# restore
LDFLAGS=$old_LDFLAGS
CFLAGS=$old_CFLAGS
fi
])
AC_DEFUN([LIBSSH2_CHECKFOR_WINCNG], [
# Look for Windows Cryptography API: Next Generation # Look for Windows Cryptography API: Next Generation
AC_LIB_HAVE_LINKFLAGS([bcrypt], [], [ AC_CHECK_HEADERS([ntdef.h ntstatus.h], [], [], [#include <windows.h>])
#include <windows.h> AC_CHECK_DECLS([SecureZeroMemory], [], [], [#include <windows.h>])
#include <bcrypt.h>
]) LIBSSH2_LIB_HAVE_LINKFLAGS([crypt32], [], [
AC_LIB_HAVE_LINKFLAGS([crypt32], [], [
#include <windows.h> #include <windows.h>
#include <wincrypt.h> #include <wincrypt.h>
]) ])
AC_CHECK_HEADERS([ntdef.h ntstatus.h], [], [], [ LIBSSH2_LIB_HAVE_LINKFLAGS([bcrypt], [], [
#include <windows.h> #include <windows.h>
#include <bcrypt.h>
], [
AC_DEFINE(LIBSSH2_WINCNG, 1, [Use $1])
found_crypto="$1"
found_crypto_str="Windows Cryptography API: Next Generation"
support_clear_memory="$ac_cv_have_decl_SecureZeroMemory"
]) ])
AC_CHECK_DECLS([SecureZeroMemory], [], [], [ ],
#include <windows.h> )
test "$found_crypto" = "none" &&
crypto_errors="${crypto_errors}No $1 crypto library found!
"
fi
]) ])
if test "$ac_cv_libbcrypt" = "yes"; then
AC_DEFINE(LIBSSH2_WINCNG, 1, [Use Windows CNG]) dnl LIBSSH2_CHECK_OPTION_WERROR
LIBSREQUIRED= # wincng doesn't provide a .pc file. sad face. dnl -------------------------------------------------
LIBS="$LIBS -lbcrypt" dnl Verify if configure has been invoked with option
if test "$ac_cv_libcrypt32" = "yes"; then dnl --enable-werror or --disable-werror, and set
LIBS="$LIBS -lcrypt32" dnl shell variable want_werror as appropriate.
fi
found_crypto="Windows Cryptography API: Next Generation" AC_DEFUN([LIBSSH2_CHECK_OPTION_WERROR], [
if test "$ac_cv_have_decl_SecureZeroMemory" = "yes"; then AC_BEFORE([$0],[LIBSSH2_CHECK_COMPILER])dnl
support_clear_memory=yes AC_MSG_CHECKING([whether to enable compiler warnings as errors])
fi OPT_COMPILER_WERROR="default"
AC_ARG_ENABLE(werror,
AC_HELP_STRING([--enable-werror],[Enable compiler warnings as errors])
AC_HELP_STRING([--disable-werror],[Disable compiler warnings as errors]),
OPT_COMPILER_WERROR=$enableval)
case "$OPT_COMPILER_WERROR" in
no)
dnl --disable-werror option used
want_werror="no"
;;
default)
dnl configure option not specified
want_werror="no"
;;
*)
dnl --enable-werror option used
want_werror="yes"
;;
esac
AC_MSG_RESULT([$want_werror])
if test X"$want_werror" = Xyes; then
CFLAGS="$CFLAGS -Werror"
fi fi
]) ])

902
libssh2/config.guess vendored

File diff suppressed because it is too large Load Diff

410
libssh2/config.sub vendored
View File

@@ -1,36 +1,31 @@
#! /bin/sh #! /bin/sh
# Configuration validation subroutine script. # Configuration validation subroutine script.
# Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, # Copyright 1992-2018 Free Software Foundation, Inc.
# 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010,
# 2011, 2012 Free Software Foundation, Inc.
timestamp='2012-02-10' timestamp='2018-02-22'
# This file is (in principle) common to ALL GNU software. # This file is free software; you can redistribute it and/or modify it
# The presence of a machine in this file suggests that SOME GNU software # under the terms of the GNU General Public License as published by
# can handle that machine. It does not imply ALL GNU software can. # the Free Software Foundation; either version 3 of the License, or
#
# This file is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version. # (at your option) any later version.
# #
# This program is distributed in the hope that it will be useful, # This program is distributed in the hope that it will be useful, but
# but WITHOUT ANY WARRANTY; without even the implied warranty of # WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
# GNU General Public License for more details. # General Public License for more details.
# #
# You should have received a copy of the GNU General Public License # You should have received a copy of the GNU General Public License
# along with this program; if not, see <http://www.gnu.org/licenses/>. # along with this program; if not, see <https://www.gnu.org/licenses/>.
# #
# As a special exception to the GNU General Public License, if you # As a special exception to the GNU General Public License, if you
# distribute this file as part of a program that contains a # distribute this file as part of a program that contains a
# configuration script generated by Autoconf, you may include it under # configuration script generated by Autoconf, you may include it under
# the same distribution terms that you use for the rest of that program. # the same distribution terms that you use for the rest of that
# program. This Exception is an additional permission under section 7
# of the GNU General Public License, version 3 ("GPLv3").
# Please send patches to <config-patches@gnu.org>. Submit a context # Please send patches to <config-patches@gnu.org>.
# diff and a properly formatted GNU ChangeLog entry.
# #
# Configuration subroutine to validate and canonicalize a configuration type. # Configuration subroutine to validate and canonicalize a configuration type.
# Supply the specified configuration type as an argument. # Supply the specified configuration type as an argument.
@@ -38,7 +33,7 @@ timestamp='2012-02-10'
# Otherwise, we print the canonical config type on stdout and succeed. # Otherwise, we print the canonical config type on stdout and succeed.
# You can get the latest version of this script from: # You can get the latest version of this script from:
# http://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.sub;hb=HEAD # https://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.sub
# This file is supposed to be the same for all GNU packages # This file is supposed to be the same for all GNU packages
# and recognize all the CPU types, system types and aliases # and recognize all the CPU types, system types and aliases
@@ -58,12 +53,11 @@ timestamp='2012-02-10'
me=`echo "$0" | sed -e 's,.*/,,'` me=`echo "$0" | sed -e 's,.*/,,'`
usage="\ usage="\
Usage: $0 [OPTION] CPU-MFR-OPSYS Usage: $0 [OPTION] CPU-MFR-OPSYS or ALIAS
$0 [OPTION] ALIAS
Canonicalize a configuration name. Canonicalize a configuration name.
Operation modes: Options:
-h, --help print this help, then exit -h, --help print this help, then exit
-t, --time-stamp print date of last modification, then exit -t, --time-stamp print date of last modification, then exit
-v, --version print version number, then exit -v, --version print version number, then exit
@@ -73,9 +67,7 @@ Report bugs and patches to <config-patches@gnu.org>."
version="\ version="\
GNU config.sub ($timestamp) GNU config.sub ($timestamp)
Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, Copyright 1992-2018 Free Software Foundation, Inc.
2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012
Free Software Foundation, Inc.
This is free software; see the source for copying conditions. There is NO This is free software; see the source for copying conditions. There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE." warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE."
@@ -102,7 +94,7 @@ while test $# -gt 0 ; do
*local*) *local*)
# First pass through any local machine types. # First pass through any local machine types.
echo $1 echo "$1"
exit ;; exit ;;
* ) * )
@@ -120,24 +112,24 @@ esac
# Separate what the user gave into CPU-COMPANY and OS or KERNEL-OS (if any). # Separate what the user gave into CPU-COMPANY and OS or KERNEL-OS (if any).
# Here we must recognize all the valid KERNEL-OS combinations. # Here we must recognize all the valid KERNEL-OS combinations.
maybe_os=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\2/'` maybe_os=`echo "$1" | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\2/'`
case $maybe_os in case $maybe_os in
nto-qnx* | linux-gnu* | linux-android* | linux-dietlibc | linux-newlib* | \ nto-qnx* | linux-gnu* | linux-android* | linux-dietlibc | linux-newlib* | \
linux-uclibc* | uclinux-uclibc* | uclinux-gnu* | kfreebsd*-gnu* | \ linux-musl* | linux-uclibc* | uclinux-uclibc* | uclinux-gnu* | kfreebsd*-gnu* | \
knetbsd*-gnu* | netbsd*-gnu* | \ knetbsd*-gnu* | netbsd*-gnu* | netbsd*-eabi* | \
kopensolaris*-gnu* | \ kopensolaris*-gnu* | cloudabi*-eabi* | \
storm-chaos* | os2-emx* | rtmk-nova*) storm-chaos* | os2-emx* | rtmk-nova*)
os=-$maybe_os os=-$maybe_os
basic_machine=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\1/'` basic_machine=`echo "$1" | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\1/'`
;; ;;
android-linux) android-linux)
os=-linux-android os=-linux-android
basic_machine=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\1/'`-unknown basic_machine=`echo "$1" | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\1/'`-unknown
;; ;;
*) *)
basic_machine=`echo $1 | sed 's/-[^-]*$//'` basic_machine=`echo "$1" | sed 's/-[^-]*$//'`
if [ $basic_machine != $1 ] if [ "$basic_machine" != "$1" ]
then os=`echo $1 | sed 's/.*-/-/'` then os=`echo "$1" | sed 's/.*-/-/'`
else os=; fi else os=; fi
;; ;;
esac esac
@@ -156,7 +148,7 @@ case $os in
-convergent* | -ncr* | -news | -32* | -3600* | -3100* | -hitachi* |\ -convergent* | -ncr* | -news | -32* | -3600* | -3100* | -hitachi* |\
-c[123]* | -convex* | -sun | -crds | -omron* | -dg | -ultra | -tti* | \ -c[123]* | -convex* | -sun | -crds | -omron* | -dg | -ultra | -tti* | \
-harris | -dolphin | -highlevel | -gould | -cbm | -ns | -masscomp | \ -harris | -dolphin | -highlevel | -gould | -cbm | -ns | -masscomp | \
-apple | -axis | -knuth | -cray | -microblaze) -apple | -axis | -knuth | -cray | -microblaze*)
os= os=
basic_machine=$1 basic_machine=$1
;; ;;
@@ -186,53 +178,56 @@ case $os in
;; ;;
-sco6) -sco6)
os=-sco5v6 os=-sco5v6
basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` basic_machine=`echo "$1" | sed -e 's/86-.*/86-pc/'`
;; ;;
-sco5) -sco5)
os=-sco3.2v5 os=-sco3.2v5
basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` basic_machine=`echo "$1" | sed -e 's/86-.*/86-pc/'`
;; ;;
-sco4) -sco4)
os=-sco3.2v4 os=-sco3.2v4
basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` basic_machine=`echo "$1" | sed -e 's/86-.*/86-pc/'`
;; ;;
-sco3.2.[4-9]*) -sco3.2.[4-9]*)
os=`echo $os | sed -e 's/sco3.2./sco3.2v/'` os=`echo $os | sed -e 's/sco3.2./sco3.2v/'`
basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` basic_machine=`echo "$1" | sed -e 's/86-.*/86-pc/'`
;; ;;
-sco3.2v[4-9]*) -sco3.2v[4-9]*)
# Don't forget version if it is 3.2v4 or newer. # Don't forget version if it is 3.2v4 or newer.
basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` basic_machine=`echo "$1" | sed -e 's/86-.*/86-pc/'`
;; ;;
-sco5v6*) -sco5v6*)
# Don't forget version if it is 3.2v4 or newer. # Don't forget version if it is 3.2v4 or newer.
basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` basic_machine=`echo "$1" | sed -e 's/86-.*/86-pc/'`
;; ;;
-sco*) -sco*)
os=-sco3.2v2 os=-sco3.2v2
basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` basic_machine=`echo "$1" | sed -e 's/86-.*/86-pc/'`
;; ;;
-udk*) -udk*)
basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` basic_machine=`echo "$1" | sed -e 's/86-.*/86-pc/'`
;; ;;
-isc) -isc)
os=-isc2.2 os=-isc2.2
basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` basic_machine=`echo "$1" | sed -e 's/86-.*/86-pc/'`
;; ;;
-clix*) -clix*)
basic_machine=clipper-intergraph basic_machine=clipper-intergraph
;; ;;
-isc*) -isc*)
basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` basic_machine=`echo "$1" | sed -e 's/86-.*/86-pc/'`
;;
-lynx*178)
os=-lynxos178
;;
-lynx*5)
os=-lynxos5
;; ;;
-lynx*) -lynx*)
os=-lynxos os=-lynxos
;; ;;
-ptx*) -ptx*)
basic_machine=`echo $1 | sed -e 's/86-.*/86-sequent/'` basic_machine=`echo "$1" | sed -e 's/86-.*/86-sequent/'`
;;
-windowsnt*)
os=`echo $os | sed -e 's/windowsnt/winnt/'`
;; ;;
-psos*) -psos*)
os=-psos os=-psos
@@ -253,21 +248,25 @@ case $basic_machine in
| alpha | alphaev[4-8] | alphaev56 | alphaev6[78] | alphapca5[67] \ | alpha | alphaev[4-8] | alphaev56 | alphaev6[78] | alphapca5[67] \
| alpha64 | alpha64ev[4-8] | alpha64ev56 | alpha64ev6[78] | alpha64pca5[67] \ | alpha64 | alpha64ev[4-8] | alpha64ev56 | alpha64ev6[78] | alpha64pca5[67] \
| am33_2.0 \ | am33_2.0 \
| arc | arm | arm[bl]e | arme[lb] | armv[2345] | armv[345][lb] | avr | avr32 \ | arc | arceb \
| arm | arm[bl]e | arme[lb] | armv[2-8] | armv[3-8][lb] | armv7[arm] \
| avr | avr32 \
| ba \
| be32 | be64 \ | be32 | be64 \
| bfin \ | bfin \
| c4x | clipper \ | c4x | c8051 | clipper \
| d10v | d30v | dlx | dsp16xx \ | d10v | d30v | dlx | dsp16xx \
| epiphany \ | e2k | epiphany \
| fido | fr30 | frv \ | fido | fr30 | frv | ft32 \
| h8300 | h8500 | hppa | hppa1.[01] | hppa2.0 | hppa2.0[nw] | hppa64 \ | h8300 | h8500 | hppa | hppa1.[01] | hppa2.0 | hppa2.0[nw] | hppa64 \
| hexagon \ | hexagon \
| i370 | i860 | i960 | ia64 \ | i370 | i860 | i960 | ia16 | ia64 \
| ip2k | iq2000 \ | ip2k | iq2000 \
| k1om \
| le32 | le64 \ | le32 | le64 \
| lm32 \ | lm32 \
| m32c | m32r | m32rle | m68000 | m68k | m88k \ | m32c | m32r | m32rle | m68000 | m68k | m88k \
| maxq | mb | microblaze | mcore | mep | metag \ | maxq | mb | microblaze | microblazeel | mcore | mep | metag \
| mips | mipsbe | mipseb | mipsel | mipsle \ | mips | mipsbe | mipseb | mipsel | mipsle \
| mips16 \ | mips16 \
| mips64 | mips64el \ | mips64 | mips64el \
@@ -281,26 +280,30 @@ case $basic_machine in
| mips64vr5900 | mips64vr5900el \ | mips64vr5900 | mips64vr5900el \
| mipsisa32 | mipsisa32el \ | mipsisa32 | mipsisa32el \
| mipsisa32r2 | mipsisa32r2el \ | mipsisa32r2 | mipsisa32r2el \
| mipsisa32r6 | mipsisa32r6el \
| mipsisa64 | mipsisa64el \ | mipsisa64 | mipsisa64el \
| mipsisa64r2 | mipsisa64r2el \ | mipsisa64r2 | mipsisa64r2el \
| mipsisa64r6 | mipsisa64r6el \
| mipsisa64sb1 | mipsisa64sb1el \ | mipsisa64sb1 | mipsisa64sb1el \
| mipsisa64sr71k | mipsisa64sr71kel \ | mipsisa64sr71k | mipsisa64sr71kel \
| mipsr5900 | mipsr5900el \
| mipstx39 | mipstx39el \ | mipstx39 | mipstx39el \
| mn10200 | mn10300 \ | mn10200 | mn10300 \
| moxie \ | moxie \
| mt \ | mt \
| msp430 \ | msp430 \
| nds32 | nds32le | nds32be \ | nds32 | nds32le | nds32be \
| nios | nios2 \ | nios | nios2 | nios2eb | nios2el \
| ns16k | ns32k \ | ns16k | ns32k \
| open8 \ | open8 | or1k | or1knd | or32 \
| or32 \ | pdp10 | pj | pjl \
| pdp10 | pdp11 | pj | pjl \
| powerpc | powerpc64 | powerpc64le | powerpcle \ | powerpc | powerpc64 | powerpc64le | powerpcle \
| pru \
| pyramid \ | pyramid \
| riscv32 | riscv64 \
| rl78 | rx \ | rl78 | rx \
| score \ | score \
| sh | sh[1234] | sh[24]a | sh[24]aeb | sh[23]e | sh[34]eb | sheb | shbe | shle | sh[1234]le | sh3ele \ | sh | sh[1234] | sh[24]a | sh[24]aeb | sh[23]e | sh[234]eb | sheb | shbe | shle | sh[1234]le | sh3ele \
| sh64 | sh64le \ | sh64 | sh64le \
| sparc | sparc64 | sparc64b | sparc64v | sparc86x | sparclet | sparclite \ | sparc | sparc64 | sparc64b | sparc64v | sparc86x | sparclet | sparclite \
| sparcv8 | sparcv9 | sparcv9b | sparcv9v \ | sparcv8 | sparcv9 | sparcv9b | sparcv9v \
@@ -308,7 +311,8 @@ case $basic_machine in
| tahoe | tic4x | tic54x | tic55x | tic6x | tic80 | tron \ | tahoe | tic4x | tic54x | tic55x | tic6x | tic80 | tron \
| ubicom32 \ | ubicom32 \
| v850 | v850e | v850e1 | v850e2 | v850es | v850e2v3 \ | v850 | v850e | v850e1 | v850e2 | v850es | v850e2v3 \
| we32k \ | visium \
| wasm32 \
| x86 | xc16x | xstormy16 | xtensa \ | x86 | xc16x | xstormy16 | xtensa \
| z8k | z80) | z8k | z80)
basic_machine=$basic_machine-unknown basic_machine=$basic_machine-unknown
@@ -322,11 +326,14 @@ case $basic_machine in
c6x) c6x)
basic_machine=tic6x-unknown basic_machine=tic6x-unknown
;; ;;
m6811 | m68hc11 | m6812 | m68hc12 | m68hcs12x | picochip) leon|leon[3-9])
basic_machine=sparc-$basic_machine
;;
m6811 | m68hc11 | m6812 | m68hc12 | m68hcs12x | nvptx | picochip)
basic_machine=$basic_machine-unknown basic_machine=$basic_machine-unknown
os=-none os=-none
;; ;;
m88110 | m680[12346]0 | m683?2 | m68360 | m5200 | v70 | w65 | z8k) m88110 | m680[12346]0 | m683?2 | m68360 | m5200 | v70 | w65)
;; ;;
ms1) ms1)
basic_machine=mt-unknown basic_machine=mt-unknown
@@ -355,7 +362,7 @@ case $basic_machine in
;; ;;
# Object if more than one company name word. # Object if more than one company name word.
*-*-*) *-*-*)
echo Invalid configuration \`$1\': machine \`$basic_machine\' not recognized 1>&2 echo Invalid configuration \`"$1"\': machine \`"$basic_machine"\' not recognized 1>&2
exit 1 exit 1
;; ;;
# Recognize the basic CPU types with company name. # Recognize the basic CPU types with company name.
@@ -364,26 +371,29 @@ case $basic_machine in
| aarch64-* | aarch64_be-* \ | aarch64-* | aarch64_be-* \
| alpha-* | alphaev[4-8]-* | alphaev56-* | alphaev6[78]-* \ | alpha-* | alphaev[4-8]-* | alphaev56-* | alphaev6[78]-* \
| alpha64-* | alpha64ev[4-8]-* | alpha64ev56-* | alpha64ev6[78]-* \ | alpha64-* | alpha64ev[4-8]-* | alpha64ev56-* | alpha64ev6[78]-* \
| alphapca5[67]-* | alpha64pca5[67]-* | arc-* \ | alphapca5[67]-* | alpha64pca5[67]-* | arc-* | arceb-* \
| arm-* | armbe-* | armle-* | armeb-* | armv*-* \ | arm-* | armbe-* | armle-* | armeb-* | armv*-* \
| avr-* | avr32-* \ | avr-* | avr32-* \
| ba-* \
| be32-* | be64-* \ | be32-* | be64-* \
| bfin-* | bs2000-* \ | bfin-* | bs2000-* \
| c[123]* | c30-* | [cjt]90-* | c4x-* \ | c[123]* | c30-* | [cjt]90-* | c4x-* \
| clipper-* | craynv-* | cydra-* \ | c8051-* | clipper-* | craynv-* | cydra-* \
| d10v-* | d30v-* | dlx-* \ | d10v-* | d30v-* | dlx-* \
| elxsi-* \ | e2k-* | elxsi-* \
| f30[01]-* | f700-* | fido-* | fr30-* | frv-* | fx80-* \ | f30[01]-* | f700-* | fido-* | fr30-* | frv-* | fx80-* \
| h8300-* | h8500-* \ | h8300-* | h8500-* \
| hppa-* | hppa1.[01]-* | hppa2.0-* | hppa2.0[nw]-* | hppa64-* \ | hppa-* | hppa1.[01]-* | hppa2.0-* | hppa2.0[nw]-* | hppa64-* \
| hexagon-* \ | hexagon-* \
| i*86-* | i860-* | i960-* | ia64-* \ | i*86-* | i860-* | i960-* | ia16-* | ia64-* \
| ip2k-* | iq2000-* \ | ip2k-* | iq2000-* \
| k1om-* \
| le32-* | le64-* \ | le32-* | le64-* \
| lm32-* \ | lm32-* \
| m32c-* | m32r-* | m32rle-* \ | m32c-* | m32r-* | m32rle-* \
| m68000-* | m680[012346]0-* | m68360-* | m683?2-* | m68k-* \ | m68000-* | m680[012346]0-* | m68360-* | m683?2-* | m68k-* \
| m88110-* | m88k-* | maxq-* | mcore-* | metag-* | microblaze-* \ | m88110-* | m88k-* | maxq-* | mcore-* | metag-* \
| microblaze-* | microblazeel-* \
| mips-* | mipsbe-* | mipseb-* | mipsel-* | mipsle-* \ | mips-* | mipsbe-* | mipseb-* | mipsel-* | mipsle-* \
| mips16-* \ | mips16-* \
| mips64-* | mips64el-* \ | mips64-* | mips64el-* \
@@ -397,28 +407,34 @@ case $basic_machine in
| mips64vr5900-* | mips64vr5900el-* \ | mips64vr5900-* | mips64vr5900el-* \
| mipsisa32-* | mipsisa32el-* \ | mipsisa32-* | mipsisa32el-* \
| mipsisa32r2-* | mipsisa32r2el-* \ | mipsisa32r2-* | mipsisa32r2el-* \
| mipsisa32r6-* | mipsisa32r6el-* \
| mipsisa64-* | mipsisa64el-* \ | mipsisa64-* | mipsisa64el-* \
| mipsisa64r2-* | mipsisa64r2el-* \ | mipsisa64r2-* | mipsisa64r2el-* \
| mipsisa64r6-* | mipsisa64r6el-* \
| mipsisa64sb1-* | mipsisa64sb1el-* \ | mipsisa64sb1-* | mipsisa64sb1el-* \
| mipsisa64sr71k-* | mipsisa64sr71kel-* \ | mipsisa64sr71k-* | mipsisa64sr71kel-* \
| mipsr5900-* | mipsr5900el-* \
| mipstx39-* | mipstx39el-* \ | mipstx39-* | mipstx39el-* \
| mmix-* \ | mmix-* \
| mt-* \ | mt-* \
| msp430-* \ | msp430-* \
| nds32-* | nds32le-* | nds32be-* \ | nds32-* | nds32le-* | nds32be-* \
| nios-* | nios2-* \ | nios-* | nios2-* | nios2eb-* | nios2el-* \
| none-* | np1-* | ns16k-* | ns32k-* \ | none-* | np1-* | ns16k-* | ns32k-* \
| open8-* \ | open8-* \
| or1k*-* \
| orion-* \ | orion-* \
| pdp10-* | pdp11-* | pj-* | pjl-* | pn-* | power-* \ | pdp10-* | pdp11-* | pj-* | pjl-* | pn-* | power-* \
| powerpc-* | powerpc64-* | powerpc64le-* | powerpcle-* \ | powerpc-* | powerpc64-* | powerpc64le-* | powerpcle-* \
| pru-* \
| pyramid-* \ | pyramid-* \
| riscv32-* | riscv64-* \
| rl78-* | romp-* | rs6000-* | rx-* \ | rl78-* | romp-* | rs6000-* | rx-* \
| sh-* | sh[1234]-* | sh[24]a-* | sh[24]aeb-* | sh[23]e-* | sh[34]eb-* | sheb-* | shbe-* \ | sh-* | sh[1234]-* | sh[24]a-* | sh[24]aeb-* | sh[23]e-* | sh[34]eb-* | sheb-* | shbe-* \
| shle-* | sh[1234]le-* | sh3ele-* | sh64-* | sh64le-* \ | shle-* | sh[1234]le-* | sh3ele-* | sh64-* | sh64le-* \
| sparc-* | sparc64-* | sparc64b-* | sparc64v-* | sparc86x-* | sparclet-* \ | sparc-* | sparc64-* | sparc64b-* | sparc64v-* | sparc86x-* | sparclet-* \
| sparclite-* \ | sparclite-* \
| sparcv8-* | sparcv9-* | sparcv9b-* | sparcv9v-* | sv1-* | sx?-* \ | sparcv8-* | sparcv9-* | sparcv9b-* | sparcv9v-* | sv1-* | sx*-* \
| tahoe-* \ | tahoe-* \
| tic30-* | tic4x-* | tic54x-* | tic55x-* | tic6x-* | tic80-* \ | tic30-* | tic4x-* | tic54x-* | tic55x-* | tic6x-* | tic80-* \
| tile*-* \ | tile*-* \
@@ -426,6 +442,8 @@ case $basic_machine in
| ubicom32-* \ | ubicom32-* \
| v850-* | v850e-* | v850e1-* | v850es-* | v850e2-* | v850e2v3-* \ | v850-* | v850e-* | v850e1-* | v850es-* | v850e2-* | v850e2v3-* \
| vax-* \ | vax-* \
| visium-* \
| wasm32-* \
| we32k-* \ | we32k-* \
| x86-* | x86_64-* | xc16x-* | xps100-* \ | x86-* | x86_64-* | xc16x-* | xps100-* \
| xstormy16-* | xtensa*-* \ | xstormy16-* | xtensa*-* \
@@ -439,7 +457,7 @@ case $basic_machine in
# Recognize the various machine names and aliases which stand # Recognize the various machine names and aliases which stand
# for a CPU type and a company and sometimes even an OS. # for a CPU type and a company and sometimes even an OS.
386bsd) 386bsd)
basic_machine=i386-unknown basic_machine=i386-pc
os=-bsd os=-bsd
;; ;;
3b1 | 7300 | 7300-att | att-7300 | pc7300 | safari | unixpc) 3b1 | 7300 | 7300-att | att-7300 | pc7300 | safari | unixpc)
@@ -473,7 +491,7 @@ case $basic_machine in
basic_machine=x86_64-pc basic_machine=x86_64-pc
;; ;;
amd64-*) amd64-*)
basic_machine=x86_64-`echo $basic_machine | sed 's/^[^-]*-//'` basic_machine=x86_64-`echo "$basic_machine" | sed 's/^[^-]*-//'`
;; ;;
amdahl) amdahl)
basic_machine=580-amdahl basic_machine=580-amdahl
@@ -502,6 +520,9 @@ case $basic_machine in
basic_machine=i386-pc basic_machine=i386-pc
os=-aros os=-aros
;; ;;
asmjs)
basic_machine=asmjs-unknown
;;
aux) aux)
basic_machine=m68k-apple basic_machine=m68k-apple
os=-aux os=-aux
@@ -515,7 +536,7 @@ case $basic_machine in
os=-linux os=-linux
;; ;;
blackfin-*) blackfin-*)
basic_machine=bfin-`echo $basic_machine | sed 's/^[^-]*-//'` basic_machine=bfin-`echo "$basic_machine" | sed 's/^[^-]*-//'`
os=-linux os=-linux
;; ;;
bluegene*) bluegene*)
@@ -523,13 +544,13 @@ case $basic_machine in
os=-cnk os=-cnk
;; ;;
c54x-*) c54x-*)
basic_machine=tic54x-`echo $basic_machine | sed 's/^[^-]*-//'` basic_machine=tic54x-`echo "$basic_machine" | sed 's/^[^-]*-//'`
;; ;;
c55x-*) c55x-*)
basic_machine=tic55x-`echo $basic_machine | sed 's/^[^-]*-//'` basic_machine=tic55x-`echo "$basic_machine" | sed 's/^[^-]*-//'`
;; ;;
c6x-*) c6x-*)
basic_machine=tic6x-`echo $basic_machine | sed 's/^[^-]*-//'` basic_machine=tic6x-`echo "$basic_machine" | sed 's/^[^-]*-//'`
;; ;;
c90) c90)
basic_machine=c90-cray basic_machine=c90-cray
@@ -618,10 +639,18 @@ case $basic_machine in
basic_machine=rs6000-bull basic_machine=rs6000-bull
os=-bosx os=-bosx
;; ;;
dpx2* | dpx2*-bull) dpx2*)
basic_machine=m68k-bull basic_machine=m68k-bull
os=-sysv3 os=-sysv3
;; ;;
e500v[12])
basic_machine=powerpc-unknown
os=$os"spe"
;;
e500v[12]-*)
basic_machine=powerpc-`echo "$basic_machine" | sed 's/^[^-]*-//'`
os=$os"spe"
;;
ebmon29k) ebmon29k)
basic_machine=a29k-amd basic_machine=a29k-amd
os=-ebmon os=-ebmon
@@ -711,9 +740,6 @@ case $basic_machine in
hp9k8[0-9][0-9] | hp8[0-9][0-9]) hp9k8[0-9][0-9] | hp8[0-9][0-9])
basic_machine=hppa1.0-hp basic_machine=hppa1.0-hp
;; ;;
hppa-next)
os=-nextstep3
;;
hppaosf) hppaosf)
basic_machine=hppa1.1-hp basic_machine=hppa1.1-hp
os=-osf os=-osf
@@ -726,26 +752,26 @@ case $basic_machine in
basic_machine=i370-ibm basic_machine=i370-ibm
;; ;;
i*86v32) i*86v32)
basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` basic_machine=`echo "$1" | sed -e 's/86.*/86-pc/'`
os=-sysv32 os=-sysv32
;; ;;
i*86v4*) i*86v4*)
basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` basic_machine=`echo "$1" | sed -e 's/86.*/86-pc/'`
os=-sysv4 os=-sysv4
;; ;;
i*86v) i*86v)
basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` basic_machine=`echo "$1" | sed -e 's/86.*/86-pc/'`
os=-sysv os=-sysv
;; ;;
i*86sol2) i*86sol2)
basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` basic_machine=`echo "$1" | sed -e 's/86.*/86-pc/'`
os=-solaris2 os=-solaris2
;; ;;
i386mach) i386mach)
basic_machine=i386-mach basic_machine=i386-mach
os=-mach os=-mach
;; ;;
i386-vsta | vsta) vsta)
basic_machine=i386-unknown basic_machine=i386-unknown
os=-vsta os=-vsta
;; ;;
@@ -763,17 +789,17 @@ case $basic_machine in
basic_machine=m68k-isi basic_machine=m68k-isi
os=-sysv os=-sysv
;; ;;
leon-*|leon[3-9]-*)
basic_machine=sparc-`echo "$basic_machine" | sed 's/-.*//'`
;;
m68knommu) m68knommu)
basic_machine=m68k-unknown basic_machine=m68k-unknown
os=-linux os=-linux
;; ;;
m68knommu-*) m68knommu-*)
basic_machine=m68k-`echo $basic_machine | sed 's/^[^-]*-//'` basic_machine=m68k-`echo "$basic_machine" | sed 's/^[^-]*-//'`
os=-linux os=-linux
;; ;;
m88k-omron*)
basic_machine=m88k-omron
;;
magnum | m3230) magnum | m3230)
basic_machine=mips-mips basic_machine=mips-mips
os=-sysv os=-sysv
@@ -782,11 +808,15 @@ case $basic_machine in
basic_machine=ns32k-utek basic_machine=ns32k-utek
os=-sysv os=-sysv
;; ;;
microblaze) microblaze*)
basic_machine=microblaze-xilinx basic_machine=microblaze-xilinx
;; ;;
mingw64)
basic_machine=x86_64-pc
os=-mingw64
;;
mingw32) mingw32)
basic_machine=i386-pc basic_machine=i686-pc
os=-mingw32 os=-mingw32
;; ;;
mingw32ce) mingw32ce)
@@ -801,10 +831,10 @@ case $basic_machine in
os=-mint os=-mint
;; ;;
mips3*-*) mips3*-*)
basic_machine=`echo $basic_machine | sed -e 's/mips3/mips64/'` basic_machine=`echo "$basic_machine" | sed -e 's/mips3/mips64/'`
;; ;;
mips3*) mips3*)
basic_machine=`echo $basic_machine | sed -e 's/mips3/mips64/'`-unknown basic_machine=`echo "$basic_machine" | sed -e 's/mips3/mips64/'`-unknown
;; ;;
monitor) monitor)
basic_machine=m68k-rom68k basic_machine=m68k-rom68k
@@ -814,15 +844,19 @@ case $basic_machine in
basic_machine=powerpc-unknown basic_machine=powerpc-unknown
os=-morphos os=-morphos
;; ;;
moxiebox)
basic_machine=moxie-unknown
os=-moxiebox
;;
msdos) msdos)
basic_machine=i386-pc basic_machine=i386-pc
os=-msdos os=-msdos
;; ;;
ms1-*) ms1-*)
basic_machine=`echo $basic_machine | sed -e 's/ms1-/mt-/'` basic_machine=`echo "$basic_machine" | sed -e 's/ms1-/mt-/'`
;; ;;
msys) msys)
basic_machine=i386-pc basic_machine=i686-pc
os=-msys os=-msys
;; ;;
mvs) mvs)
@@ -906,6 +940,12 @@ case $basic_machine in
nsr-tandem) nsr-tandem)
basic_machine=nsr-tandem basic_machine=nsr-tandem
;; ;;
nsv-tandem)
basic_machine=nsv-tandem
;;
nsx-tandem)
basic_machine=nsx-tandem
;;
op50n-* | op60c-*) op50n-* | op60c-*)
basic_machine=hppa1.1-oki basic_machine=hppa1.1-oki
os=-proelf os=-proelf
@@ -938,7 +978,7 @@ case $basic_machine in
os=-linux os=-linux
;; ;;
parisc-*) parisc-*)
basic_machine=hppa-`echo $basic_machine | sed 's/^[^-]*-//'` basic_machine=hppa-`echo "$basic_machine" | sed 's/^[^-]*-//'`
os=-linux os=-linux
;; ;;
pbd) pbd)
@@ -954,7 +994,7 @@ case $basic_machine in
basic_machine=i386-pc basic_machine=i386-pc
;; ;;
pc98-*) pc98-*)
basic_machine=i386-`echo $basic_machine | sed 's/^[^-]*-//'` basic_machine=i386-`echo "$basic_machine" | sed 's/^[^-]*-//'`
;; ;;
pentium | p5 | k5 | k6 | nexgen | viac3) pentium | p5 | k5 | k6 | nexgen | viac3)
basic_machine=i586-pc basic_machine=i586-pc
@@ -969,16 +1009,16 @@ case $basic_machine in
basic_machine=i786-pc basic_machine=i786-pc
;; ;;
pentium-* | p5-* | k5-* | k6-* | nexgen-* | viac3-*) pentium-* | p5-* | k5-* | k6-* | nexgen-* | viac3-*)
basic_machine=i586-`echo $basic_machine | sed 's/^[^-]*-//'` basic_machine=i586-`echo "$basic_machine" | sed 's/^[^-]*-//'`
;; ;;
pentiumpro-* | p6-* | 6x86-* | athlon-*) pentiumpro-* | p6-* | 6x86-* | athlon-*)
basic_machine=i686-`echo $basic_machine | sed 's/^[^-]*-//'` basic_machine=i686-`echo "$basic_machine" | sed 's/^[^-]*-//'`
;; ;;
pentiumii-* | pentium2-* | pentiumiii-* | pentium3-*) pentiumii-* | pentium2-* | pentiumiii-* | pentium3-*)
basic_machine=i686-`echo $basic_machine | sed 's/^[^-]*-//'` basic_machine=i686-`echo "$basic_machine" | sed 's/^[^-]*-//'`
;; ;;
pentium4-*) pentium4-*)
basic_machine=i786-`echo $basic_machine | sed 's/^[^-]*-//'` basic_machine=i786-`echo "$basic_machine" | sed 's/^[^-]*-//'`
;; ;;
pn) pn)
basic_machine=pn-gould basic_machine=pn-gould
@@ -988,23 +1028,23 @@ case $basic_machine in
ppc | ppcbe) basic_machine=powerpc-unknown ppc | ppcbe) basic_machine=powerpc-unknown
;; ;;
ppc-* | ppcbe-*) ppc-* | ppcbe-*)
basic_machine=powerpc-`echo $basic_machine | sed 's/^[^-]*-//'` basic_machine=powerpc-`echo "$basic_machine" | sed 's/^[^-]*-//'`
;; ;;
ppcle | powerpclittle | ppc-le | powerpc-little) ppcle | powerpclittle)
basic_machine=powerpcle-unknown basic_machine=powerpcle-unknown
;; ;;
ppcle-* | powerpclittle-*) ppcle-* | powerpclittle-*)
basic_machine=powerpcle-`echo $basic_machine | sed 's/^[^-]*-//'` basic_machine=powerpcle-`echo "$basic_machine" | sed 's/^[^-]*-//'`
;; ;;
ppc64) basic_machine=powerpc64-unknown ppc64) basic_machine=powerpc64-unknown
;; ;;
ppc64-*) basic_machine=powerpc64-`echo $basic_machine | sed 's/^[^-]*-//'` ppc64-*) basic_machine=powerpc64-`echo "$basic_machine" | sed 's/^[^-]*-//'`
;; ;;
ppc64le | powerpc64little | ppc64-le | powerpc64-little) ppc64le | powerpc64little)
basic_machine=powerpc64le-unknown basic_machine=powerpc64le-unknown
;; ;;
ppc64le-* | powerpc64little-*) ppc64le-* | powerpc64little-*)
basic_machine=powerpc64le-`echo $basic_machine | sed 's/^[^-]*-//'` basic_machine=powerpc64le-`echo "$basic_machine" | sed 's/^[^-]*-//'`
;; ;;
ps2) ps2)
basic_machine=i386-ibm basic_machine=i386-ibm
@@ -1013,7 +1053,11 @@ case $basic_machine in
basic_machine=i586-unknown basic_machine=i586-unknown
os=-pw32 os=-pw32
;; ;;
rdos) rdos | rdos64)
basic_machine=x86_64-pc
os=-rdos
;;
rdos32)
basic_machine=i386-pc basic_machine=i386-pc
os=-rdos os=-rdos
;; ;;
@@ -1054,17 +1098,10 @@ case $basic_machine in
sequent) sequent)
basic_machine=i386-sequent basic_machine=i386-sequent
;; ;;
sh)
basic_machine=sh-hitachi
os=-hms
;;
sh5el) sh5el)
basic_machine=sh5le-unknown basic_machine=sh5le-unknown
;; ;;
sh64) simso-wrs)
basic_machine=sh64-unknown
;;
sparclite-wrs | simso-wrs)
basic_machine=sparclite-wrs basic_machine=sparclite-wrs
os=-vxworks os=-vxworks
;; ;;
@@ -1083,7 +1120,7 @@ case $basic_machine in
os=-sysv4 os=-sysv4
;; ;;
strongarm-* | thumb-*) strongarm-* | thumb-*)
basic_machine=arm-`echo $basic_machine | sed 's/^[^-]*-//'` basic_machine=arm-`echo "$basic_machine" | sed 's/^[^-]*-//'`
;; ;;
sun2) sun2)
basic_machine=m68000-sun basic_machine=m68000-sun
@@ -1205,6 +1242,9 @@ case $basic_machine in
basic_machine=hppa1.1-winbond basic_machine=hppa1.1-winbond
os=-proelf os=-proelf
;; ;;
x64)
basic_machine=x86_64-pc
;;
xbox) xbox)
basic_machine=i686-pc basic_machine=i686-pc
os=-mingw32 os=-mingw32
@@ -1213,20 +1253,12 @@ case $basic_machine in
basic_machine=xps100-honeywell basic_machine=xps100-honeywell
;; ;;
xscale-* | xscalee[bl]-*) xscale-* | xscalee[bl]-*)
basic_machine=`echo $basic_machine | sed 's/^xscale/arm/'` basic_machine=`echo "$basic_machine" | sed 's/^xscale/arm/'`
;; ;;
ymp) ymp)
basic_machine=ymp-cray basic_machine=ymp-cray
os=-unicos os=-unicos
;; ;;
z8k-*-coff)
basic_machine=z8k-unknown
os=-sim
;;
z80-*-coff)
basic_machine=z80-unknown
os=-sim
;;
none) none)
basic_machine=none-none basic_machine=none-none
os=-none os=-none
@@ -1255,10 +1287,6 @@ case $basic_machine in
vax) vax)
basic_machine=vax-dec basic_machine=vax-dec
;; ;;
pdp10)
# there are many clones, so DEC is not a safe bet
basic_machine=pdp10-unknown
;;
pdp11) pdp11)
basic_machine=pdp11-dec basic_machine=pdp11-dec
;; ;;
@@ -1268,9 +1296,6 @@ case $basic_machine in
sh[1234] | sh[24]a | sh[24]aeb | sh[34]eb | sh[1234]le | sh[23]ele) sh[1234] | sh[24]a | sh[24]aeb | sh[34]eb | sh[1234]le | sh[23]ele)
basic_machine=sh-unknown basic_machine=sh-unknown
;; ;;
sparc | sparcv8 | sparcv9 | sparcv9b | sparcv9v)
basic_machine=sparc-sun
;;
cydra) cydra)
basic_machine=cydra-cydrome basic_machine=cydra-cydrome
;; ;;
@@ -1290,7 +1315,7 @@ case $basic_machine in
# Make sure to match an already-canonicalized machine name. # Make sure to match an already-canonicalized machine name.
;; ;;
*) *)
echo Invalid configuration \`$1\': machine \`$basic_machine\' not recognized 1>&2 echo Invalid configuration \`"$1"\': machine \`"$basic_machine"\' not recognized 1>&2
exit 1 exit 1
;; ;;
esac esac
@@ -1298,10 +1323,10 @@ esac
# Here we canonicalize certain aliases for manufacturers. # Here we canonicalize certain aliases for manufacturers.
case $basic_machine in case $basic_machine in
*-digital*) *-digital*)
basic_machine=`echo $basic_machine | sed 's/digital.*/dec/'` basic_machine=`echo "$basic_machine" | sed 's/digital.*/dec/'`
;; ;;
*-commodore*) *-commodore*)
basic_machine=`echo $basic_machine | sed 's/commodore.*/cbm/'` basic_machine=`echo "$basic_machine" | sed 's/commodore.*/cbm/'`
;; ;;
*) *)
;; ;;
@@ -1312,8 +1337,8 @@ esac
if [ x"$os" != x"" ] if [ x"$os" != x"" ]
then then
case $os in case $os in
# First match some system type aliases # First match some system type aliases that might get confused
# that might get confused with valid system types. # with valid system types.
# -solaris* is a basic system type, with this one exception. # -solaris* is a basic system type, with this one exception.
-auroraux) -auroraux)
os=-auroraux os=-auroraux
@@ -1324,45 +1349,48 @@ case $os in
-solaris) -solaris)
os=-solaris2 os=-solaris2
;; ;;
-svr4*)
os=-sysv4
;;
-unixware*) -unixware*)
os=-sysv4.2uw os=-sysv4.2uw
;; ;;
-gnu/linux*) -gnu/linux*)
os=`echo $os | sed -e 's|gnu/linux|linux-gnu|'` os=`echo $os | sed -e 's|gnu/linux|linux-gnu|'`
;; ;;
# First accept the basic system types. # es1800 is here to avoid being matched by es* (a different OS)
-es1800*)
os=-ose
;;
# Now accept the basic system types.
# The portable systems comes first. # The portable systems comes first.
# Each alternative MUST END IN A *, to match a version number. # Each alternative MUST end in a * to match a version number.
# -sysv* is not here because it comes later, after sysvr4. # -sysv* is not here because it comes later, after sysvr4.
-gnu* | -bsd* | -mach* | -minix* | -genix* | -ultrix* | -irix* \ -gnu* | -bsd* | -mach* | -minix* | -genix* | -ultrix* | -irix* \
| -*vms* | -sco* | -esix* | -isc* | -aix* | -cnk* | -sunos | -sunos[34]*\ | -*vms* | -sco* | -esix* | -isc* | -aix* | -cnk* | -sunos | -sunos[34]*\
| -hpux* | -unos* | -osf* | -luna* | -dgux* | -auroraux* | -solaris* \ | -hpux* | -unos* | -osf* | -luna* | -dgux* | -auroraux* | -solaris* \
| -sym* | -kopensolaris* \ | -sym* | -kopensolaris* | -plan9* \
| -amigaos* | -amigados* | -msdos* | -newsos* | -unicos* | -aof* \ | -amigaos* | -amigados* | -msdos* | -newsos* | -unicos* | -aof* \
| -aos* | -aros* \ | -aos* | -aros* | -cloudabi* | -sortix* \
| -nindy* | -vxsim* | -vxworks* | -ebmon* | -hms* | -mvs* \ | -nindy* | -vxsim* | -vxworks* | -ebmon* | -hms* | -mvs* \
| -clix* | -riscos* | -uniplus* | -iris* | -rtu* | -xenix* \ | -clix* | -riscos* | -uniplus* | -iris* | -rtu* | -xenix* \
| -hiux* | -386bsd* | -knetbsd* | -mirbsd* | -netbsd* \ | -hiux* | -knetbsd* | -mirbsd* | -netbsd* \
| -openbsd* | -solidbsd* \ | -bitrig* | -openbsd* | -solidbsd* | -libertybsd* \
| -ekkobsd* | -kfreebsd* | -freebsd* | -riscix* | -lynxos* \ | -ekkobsd* | -kfreebsd* | -freebsd* | -riscix* | -lynxos* \
| -bosx* | -nextstep* | -cxux* | -aout* | -elf* | -oabi* \ | -bosx* | -nextstep* | -cxux* | -aout* | -elf* | -oabi* \
| -ptx* | -coff* | -ecoff* | -winnt* | -domain* | -vsta* \ | -ptx* | -coff* | -ecoff* | -winnt* | -domain* | -vsta* \
| -udi* | -eabi* | -lites* | -ieee* | -go32* | -aux* \ | -udi* | -eabi* | -lites* | -ieee* | -go32* | -aux* \
| -chorusos* | -chorusrdb* | -cegcc* \ | -chorusos* | -chorusrdb* | -cegcc* | -glidix* \
| -cygwin* | -msys* | -pe* | -psos* | -moss* | -proelf* | -rtems* \ | -cygwin* | -msys* | -pe* | -psos* | -moss* | -proelf* | -rtems* \
| -mingw32* | -linux-gnu* | -linux-android* \ | -midipix* | -mingw32* | -mingw64* | -linux-gnu* | -linux-android* \
| -linux-newlib* | -linux-uclibc* \ | -linux-newlib* | -linux-musl* | -linux-uclibc* \
| -uxpv* | -beos* | -mpeix* | -udk* \ | -uxpv* | -beos* | -mpeix* | -udk* | -moxiebox* \
| -interix* | -uwin* | -mks* | -rhapsody* | -darwin* | -opened* \ | -interix* | -uwin* | -mks* | -rhapsody* | -darwin* \
| -openstep* | -oskit* | -conix* | -pw32* | -nonstopux* \ | -openstep* | -oskit* | -conix* | -pw32* | -nonstopux* \
| -storm-chaos* | -tops10* | -tenex* | -tops20* | -its* \ | -storm-chaos* | -tops10* | -tenex* | -tops20* | -its* \
| -os2* | -vos* | -palmos* | -uclinux* | -nucleus* \ | -os2* | -vos* | -palmos* | -uclinux* | -nucleus* \
| -morphos* | -superux* | -rtmk* | -rtmk-nova* | -windiss* \ | -morphos* | -superux* | -rtmk* | -windiss* \
| -powermax* | -dnix* | -nx6 | -nx7 | -sei* | -dragonfly* \ | -powermax* | -dnix* | -nx6 | -nx7 | -sei* | -dragonfly* \
| -skyos* | -haiku* | -rdos* | -toppers* | -drops* | -es*) | -skyos* | -haiku* | -rdos* | -toppers* | -drops* | -es* \
| -onefs* | -tirtos* | -phoenix* | -fuchsia* | -redox* | -bme* \
| -midnightbsd*)
# Remember, each alternative MUST END IN *, to match a version number. # Remember, each alternative MUST END IN *, to match a version number.
;; ;;
-qnx*) -qnx*)
@@ -1379,12 +1407,12 @@ case $os in
-nto*) -nto*)
os=`echo $os | sed -e 's|nto|nto-qnx|'` os=`echo $os | sed -e 's|nto|nto-qnx|'`
;; ;;
-sim | -es1800* | -hms* | -xray | -os68k* | -none* | -v88r* \ -sim | -xray | -os68k* | -v88r* \
| -windows* | -osx | -abug | -netware* | -os9* | -beos* | -haiku* \ | -windows* | -osx | -abug | -netware* | -os9* \
| -macos* | -mpw* | -magic* | -mmixware* | -mon960* | -lnews*) | -macos* | -mpw* | -magic* | -mmixware* | -mon960* | -lnews*)
;; ;;
-mac*) -mac*)
os=`echo $os | sed -e 's|mac|macos|'` os=`echo "$os" | sed -e 's|mac|macos|'`
;; ;;
-linux-dietlibc) -linux-dietlibc)
os=-linux-dietlibc os=-linux-dietlibc
@@ -1393,10 +1421,10 @@ case $os in
os=`echo $os | sed -e 's|linux|linux-gnu|'` os=`echo $os | sed -e 's|linux|linux-gnu|'`
;; ;;
-sunos5*) -sunos5*)
os=`echo $os | sed -e 's|sunos5|solaris2|'` os=`echo "$os" | sed -e 's|sunos5|solaris2|'`
;; ;;
-sunos6*) -sunos6*)
os=`echo $os | sed -e 's|sunos6|solaris3|'` os=`echo "$os" | sed -e 's|sunos6|solaris3|'`
;; ;;
-opened*) -opened*)
os=-openedition os=-openedition
@@ -1407,12 +1435,6 @@ case $os in
-wince*) -wince*)
os=-wince os=-wince
;; ;;
-osfrose*)
os=-osfrose
;;
-osf*)
os=-osf
;;
-utek*) -utek*)
os=-bsd os=-bsd
;; ;;
@@ -1459,7 +1481,7 @@ case $os in
-oss*) -oss*)
os=-sysv3 os=-sysv3
;; ;;
-svr4) -svr4*)
os=-sysv4 os=-sysv4
;; ;;
-svr3) -svr3)
@@ -1474,35 +1496,38 @@ case $os in
-ose*) -ose*)
os=-ose os=-ose
;; ;;
-es1800*)
os=-ose
;;
-xenix)
os=-xenix
;;
-*mint | -mint[0-9]* | -*MiNT | -MiNT[0-9]*) -*mint | -mint[0-9]* | -*MiNT | -MiNT[0-9]*)
os=-mint os=-mint
;; ;;
-aros*)
os=-aros
;;
-kaos*)
os=-kaos
;;
-zvmoe) -zvmoe)
os=-zvmoe os=-zvmoe
;; ;;
-dicos*) -dicos*)
os=-dicos os=-dicos
;; ;;
-pikeos*)
# Until real need of OS specific support for
# particular features comes up, bare metal
# configurations are quite functional.
case $basic_machine in
arm*)
os=-eabi
;;
*)
os=-elf
;;
esac
;;
-nacl*) -nacl*)
;; ;;
-ios)
;;
-none) -none)
;; ;;
*) *)
# Get rid of the `-' at the beginning of $os. # Get rid of the `-' at the beginning of $os.
os=`echo $os | sed 's/[^-]*-//'` os=`echo $os | sed 's/[^-]*-//'`
echo Invalid configuration \`$1\': system \`$os\' not recognized 1>&2 echo Invalid configuration \`"$1"\': system \`"$os"\' not recognized 1>&2
exit 1 exit 1
;; ;;
esac esac
@@ -1537,6 +1562,12 @@ case $basic_machine in
c4x-* | tic4x-*) c4x-* | tic4x-*)
os=-coff os=-coff
;; ;;
c8051-*)
os=-elf
;;
hexagon-*)
os=-elf
;;
tic54x-*) tic54x-*)
os=-coff os=-coff
;; ;;
@@ -1586,12 +1617,12 @@ case $basic_machine in
sparc-* | *-sun) sparc-* | *-sun)
os=-sunos4.1.1 os=-sunos4.1.1
;; ;;
pru-*)
os=-elf
;;
*-be) *-be)
os=-beos os=-beos
;; ;;
*-haiku)
os=-haiku
;;
*-ibm) *-ibm)
os=-aix os=-aix
;; ;;
@@ -1646,9 +1677,6 @@ case $basic_machine in
i370-*) i370-*)
os=-mvs os=-mvs
;; ;;
*-next)
os=-nextstep3
;;
*-gould) *-gould)
os=-sysv os=-sysv
;; ;;
@@ -1758,15 +1786,15 @@ case $basic_machine in
vendor=stratus vendor=stratus
;; ;;
esac esac
basic_machine=`echo $basic_machine | sed "s/unknown/$vendor/"` basic_machine=`echo "$basic_machine" | sed "s/unknown/$vendor/"`
;; ;;
esac esac
echo $basic_machine$os echo "$basic_machine$os"
exit exit
# Local variables: # Local variables:
# eval: (add-hook 'write-file-hooks 'time-stamp) # eval: (add-hook 'write-file-functions 'time-stamp)
# time-stamp-start: "timestamp='" # time-stamp-start: "timestamp='"
# time-stamp-format: "%:y-%02m-%02d" # time-stamp-format: "%:y-%02m-%02d"
# time-stamp-end: "'" # time-stamp-end: "'"

3708
libssh2/configure vendored

File diff suppressed because it is too large Load Diff

View File

@@ -83,79 +83,78 @@ AC_C_BIGENDIAN
dnl check for how to do large files dnl check for how to do large files
AC_SYS_LARGEFILE AC_SYS_LARGEFILE
# Crypto backends
found_crypto=none found_crypto=none
found_crypto_str=""
# Configure parameters
AC_ARG_WITH(openssl,
AC_HELP_STRING([--with-openssl],[Use OpenSSL for crypto]),
use_openssl=$withval,use_openssl=auto)
AC_ARG_WITH(libgcrypt,
AC_HELP_STRING([--with-libgcrypt],[Use libgcrypt for crypto]),
[ use_libgcrypt=$withval
LIBSSH2_CHECKFOR_GCRYPT
], use_libgcrypt=auto)
AC_ARG_WITH(wincng,
AC_HELP_STRING([--with-wincng],[Use Windows CNG for crypto]),
[ use_wincng=$withval
LIBSSH2_CHECKFOR_WINCNG
] ,use_wincng=auto)
AC_ARG_WITH([mbedtls],
AC_HELP_STRING([--with-mbedtls],[Use mbedTLS for crypto]),
[ use_mbedtls=$withval
LIBSSH2_CHECKFOR_MBEDTLS
], use_mbedtls=auto
)
AC_ARG_WITH(libz,
AC_HELP_STRING([--with-libz],[Use zlib for compression]),
use_libz=$withval,use_libz=auto)
support_clear_memory=no support_clear_memory=no
crypto_errors=""
# Look for OpenSSL m4_set_add([crypto_backends], [openssl])
if test "$found_crypto" = "none" && test "$use_openssl" != "no"; then m4_set_add([crypto_backends], [libgcrypt])
AC_LIB_HAVE_LINKFLAGS([ssl], [crypto], [#include <openssl/ssl.h>]) m4_set_add([crypto_backends], [mbedtls])
fi m4_set_add([crypto_backends], [wincng])
if test "$ac_cv_libssl" = "yes"; then
AC_DEFINE(LIBSSH2_OPENSSL, 1, [Use OpenSSL])
LIBSREQUIRED=libssl,libcrypto
# Not all OpenSSL have AES-CTR functions. AC_ARG_WITH([crypto],
save_LIBS="$LIBS" AC_HELP_STRING([--with-crypto=auto|]m4_set_contents([crypto_backends], [|]),
LIBS="$LIBS $LIBSSL" [Select crypto backend (default: auto)]),
AC_CHECK_FUNCS(EVP_aes_128_ctr) use_crypto=$withval,
LIBS="$save_LIBS" use_crypto=auto
)
found_crypto="OpenSSL (AES-CTR: ${ac_cv_func_EVP_aes_128_ctr:-N/A})" case "${use_crypto}" in
fi auto|m4_set_contents([crypto_backends], [|]))
m4_set_map([crypto_backends], [LIBSSH2_CHECK_CRYPTO])
;;
yes|"")
crypto_errors="No crypto backend specified!"
;;
*)
crypto_errors="Unknown crypto backend '${use_crypto}' specified!"
;;
esac
AM_CONDITIONAL(OPENSSL, test "$ac_cv_libssl" = "yes")
AM_CONDITIONAL(WINCNG, test "$ac_cv_libbcrypt" = "yes")
AM_CONDITIONAL(LIBGCRYPT, test "$ac_cv_libgcrypt" = "yes")
AM_CONDITIONAL(MBEDTLS, test "$ac_cv_libmbedtls" = "yes")
AM_CONDITIONAL(OS400QC3, false)
# Check if crypto library was found
if test "$found_crypto" = "none"; then if test "$found_crypto" = "none"; then
AC_MSG_ERROR([No crypto library found! crypto_errors="${crypto_errors}
Try --with-libssl-prefix=PATH Specify --with-crypto=\$backend and/or the neccessary library search prefix.
or --with-libgcrypt-prefix=PATH
or --with-libmbedtls-prefix=PATH Known crypto backends: auto, m4_set_contents([crypto_backends], [, ])"
or --with-wincng on Windows\ AS_MESSAGE([ERROR: ${crypto_errors}])
]) else
test "$found_crypto_str" = "" && found_crypto_str="$found_crypto"
fi fi
# Look for Libz m4_set_foreach([crypto_backends], [backend],
if test "$use_libz" != "no"; then [AM_CONDITIONAL(m4_toupper(backend), test "$found_crypto" = "backend")]
)
m4_undefine([backend])
# libz
AC_ARG_WITH([libz],
AC_HELP_STRING([--with-libz],[Use libz for compression]),
use_libz=$withval,
use_libz=auto)
found_libz=no
libz_errors=""
if test "$use_libz" != no; then
AC_LIB_HAVE_LINKFLAGS([z], [], [#include <zlib.h>]) AC_LIB_HAVE_LINKFLAGS([z], [], [#include <zlib.h>])
if test "$ac_cv_libz" != yes; then if test "$ac_cv_libz" != yes; then
AC_MSG_NOTICE([Cannot find zlib, disabling compression]) if test "$use_libz" = auto; then
AC_MSG_NOTICE([Try --with-libz-prefix=PATH if you know you have it]) AC_MSG_NOTICE([Cannot find libz, disabling compression])
found_libz="disabled; no libz found"
else
libz_errors="No libz found!
Try --with-libz-prefix=PATH if you know that you have it."
AS_MESSAGE([ERROR: $libz_errors])
fi
else else
AC_DEFINE(LIBSSH2_HAVE_ZLIB, 1, [Compile in zlib support]) AC_DEFINE(LIBSSH2_HAVE_ZLIB, 1, [Compile in zlib support])
if test "${LIBSREQUIRED}" != ""; then LIBSREQUIRED="$LIBSREQUIRED${LIBSREQUIRED:+ }zlib"
LIBSREQUIRED="${LIBSREQUIRED}," found_libz="yes"
fi
LIBSREQUIRED="${LIBSREQUIRED}zlib"
fi fi
fi fi
@@ -213,6 +212,7 @@ AC_HELP_STRING([--disable-debug],[Disable debug options]),
[ case "$enable_debug" in [ case "$enable_debug" in
no) no)
AC_MSG_RESULT(no) AC_MSG_RESULT(no)
CPPFLAGS="$CPPFLAGS -DNDEBUG"
;; ;;
*) AC_MSG_RESULT(yes) *) AC_MSG_RESULT(yes)
enable_debug=yes enable_debug=yes
@@ -268,22 +268,6 @@ AC_HELP_STRING([--disable-hidden-symbols],[Leave all symbols with default visibi
AC_MSG_RESULT(no) AC_MSG_RESULT(no)
) )
# Build example applications?
AC_MSG_CHECKING([whether to build example applications])
AC_ARG_ENABLE([examples-build],
AC_HELP_STRING([--enable-examples-build], [Build example applications (this is the default)])
AC_HELP_STRING([--disable-examples-build], [Do not build example applications]),
[case "$enableval" in
no | false)
build_examples='no'
;;
*)
build_examples='yes'
;;
esac], [build_examples='yes'])
AC_MSG_RESULT($build_examples)
AM_CONDITIONAL([BUILD_EXAMPLES], [test "x$build_examples" != "xno"])
# Checks for header files. # Checks for header files.
# AC_HEADER_STDC # AC_HEADER_STDC
AC_CHECK_HEADERS([errno.h fcntl.h stdio.h stdlib.h unistd.h sys/uio.h]) AC_CHECK_HEADERS([errno.h fcntl.h stdio.h stdlib.h unistd.h sys/uio.h])
@@ -319,7 +303,7 @@ case $host in
;; ;;
esac esac
AC_CHECK_FUNCS(gettimeofday select strtoll) AC_CHECK_FUNCS(gettimeofday select strtoll memset_s)
dnl Check for select() into ws2_32 for Msys/Mingw dnl Check for select() into ws2_32 for Msys/Mingw
if test "$ac_cv_func_select" != "yes"; then if test "$ac_cv_func_select" != "yes"; then
@@ -351,6 +335,25 @@ AC_C_INLINE
CURL_CHECK_NONBLOCKING_SOCKET CURL_CHECK_NONBLOCKING_SOCKET
missing_required_deps=0
if test "${libz_errors}" != ""; then
AS_MESSAGE([ERROR: ${libz_errors}])
missing_required_deps=1
fi
if test "$found_crypto" = "none"; then
AS_MESSAGE([ERROR: ${crypto_errors}])
missing_required_deps=1
fi
if test $missing_required_deps = 1; then
AC_MSG_ERROR([Required dependencies are missing!])
fi
# Configure parameters
LIBSSH2_CHECK_OPTION_WERROR
AC_CONFIG_FILES([Makefile AC_CONFIG_FILES([Makefile
src/Makefile src/Makefile
libssh2.pc]) libssh2.pc])
@@ -364,10 +367,9 @@ AC_MSG_NOTICE([summary of build options:
Compiler: ${CC} Compiler: ${CC}
Compiler flags: ${CFLAGS} Compiler flags: ${CFLAGS}
Library types: Shared=${enable_shared}, Static=${enable_static} Library types: Shared=${enable_shared}, Static=${enable_static}
Crypto library: ${found_crypto} Crypto library: ${found_crypto_str}
Clear memory: $enable_clear_memory Clear memory: $enable_clear_memory
Debug build: $enable_debug Debug build: $enable_debug
Build examples: $build_examples
Path to sshd: $ac_cv_path_SSHD (only for self-tests) Path to sshd: $ac_cv_path_SSHD (only for self-tests)
zlib compression: $ac_cv_libz zlib compression: ${found_libz}
]) ])

View File

@@ -40,19 +40,19 @@
#ifndef LIBSSH2_H #ifndef LIBSSH2_H
#define LIBSSH2_H 1 #define LIBSSH2_H 1
#define LIBSSH2_COPYRIGHT "2004-2016 The libssh2 project and its contributors." #define LIBSSH2_COPYRIGHT "2004-2019 The libssh2 project and its contributors."
/* We use underscore instead of dash when appending DEV in dev versions just /* We use underscore instead of dash when appending DEV in dev versions just
to make the BANNER define (used by src/session.c) be a valid SSH to make the BANNER define (used by src/session.c) be a valid SSH
banner. Release versions have no appended strings and may of course not banner. Release versions have no appended strings and may of course not
have dashes either. */ have dashes either. */
#define LIBSSH2_VERSION "1.8.2" #define LIBSSH2_VERSION "1.9.0"
/* The numeric version number is also available "in parts" by using these /* The numeric version number is also available "in parts" by using these
defines: */ defines: */
#define LIBSSH2_VERSION_MAJOR 1 #define LIBSSH2_VERSION_MAJOR 1
#define LIBSSH2_VERSION_MINOR 8 #define LIBSSH2_VERSION_MINOR 9
#define LIBSSH2_VERSION_PATCH 2 #define LIBSSH2_VERSION_PATCH 0
/* This is the numeric version of the libssh2 version number, meant for easier /* This is the numeric version of the libssh2 version number, meant for easier
parsing and comparions by programs. The LIBSSH2_VERSION_NUM define will parsing and comparions by programs. The LIBSSH2_VERSION_NUM define will
@@ -69,7 +69,7 @@
and it is always a greater number in a more recent release. It makes and it is always a greater number in a more recent release. It makes
comparisons with greater than and less than work. comparisons with greater than and less than work.
*/ */
#define LIBSSH2_VERSION_NUM 0x010802 #define LIBSSH2_VERSION_NUM 0x010900
/* /*
* This is the date and time when the full source package was created. The * This is the date and time when the full source package was created. The
@@ -80,7 +80,7 @@
* *
* "Mon Feb 12 11:35:33 UTC 2007" * "Mon Feb 12 11:35:33 UTC 2007"
*/ */
#define LIBSSH2_TIMESTAMP "Mon Mar 25 19:29:57 UTC 2019" #define LIBSSH2_TIMESTAMP "Thu Jun 20 06:19:26 UTC 2019"
#ifndef RC_INVOKED #ifndef RC_INVOKED
@@ -121,18 +121,28 @@ extern "C" {
#if (defined(NETWARE) && !defined(__NOVELL_LIBC__)) #if (defined(NETWARE) && !defined(__NOVELL_LIBC__))
# include <sys/bsdskt.h> # include <sys/bsdskt.h>
typedef unsigned char uint8_t; typedef unsigned char uint8_t;
typedef unsigned short int uint16_t;
typedef unsigned int uint32_t; typedef unsigned int uint32_t;
typedef int int32_t;
typedef unsigned long long uint64_t;
typedef long long int64_t;
#endif #endif
#ifdef _MSC_VER #ifdef _MSC_VER
typedef unsigned char uint8_t; typedef unsigned char uint8_t;
typedef unsigned short int uint16_t;
typedef unsigned int uint32_t; typedef unsigned int uint32_t;
typedef __int32 int32_t;
typedef __int64 int64_t;
typedef unsigned __int64 uint64_t;
typedef unsigned __int64 libssh2_uint64_t; typedef unsigned __int64 libssh2_uint64_t;
typedef __int64 libssh2_int64_t; typedef __int64 libssh2_int64_t;
#ifndef ssize_t #if (!defined(HAVE_SSIZE_T) && !defined(ssize_t))
typedef SSIZE_T ssize_t; typedef SSIZE_T ssize_t;
#define HAVE_SSIZE_T
#endif #endif
#else #else
#include <stdint.h>
typedef unsigned long long libssh2_uint64_t; typedef unsigned long long libssh2_uint64_t;
typedef long long libssh2_int64_t; typedef long long libssh2_int64_t;
#endif #endif
@@ -203,7 +213,8 @@ typedef off_t libssh2_struct_stat_size;
#ifndef LIBSSH2_STRUCT_STAT_SIZE_FORMAT #ifndef LIBSSH2_STRUCT_STAT_SIZE_FORMAT
# ifdef __VMS # ifdef __VMS
/* We have to roll our own format here because %z is a C99-ism we don't have. */ /* We have to roll our own format here because %z is a C99-ism we don't
have. */
# if __USE_OFF64_T || __USING_STD_STAT # if __USE_OFF64_T || __USING_STD_STAT
# define LIBSSH2_STRUCT_STAT_SIZE_FORMAT "%Ld" # define LIBSSH2_STRUCT_STAT_SIZE_FORMAT "%Ld"
# else # else
@@ -219,11 +230,11 @@ typedef off_t libssh2_struct_stat_size;
/* Part of every banner, user specified or not */ /* Part of every banner, user specified or not */
#define LIBSSH2_SSH_BANNER "SSH-2.0-libssh2_" LIBSSH2_VERSION #define LIBSSH2_SSH_BANNER "SSH-2.0-libssh2_" LIBSSH2_VERSION
/* We *could* add a comment here if we so chose */
#define LIBSSH2_SSH_DEFAULT_BANNER LIBSSH2_SSH_BANNER #define LIBSSH2_SSH_DEFAULT_BANNER LIBSSH2_SSH_BANNER
#define LIBSSH2_SSH_DEFAULT_BANNER_WITH_CRLF LIBSSH2_SSH_DEFAULT_BANNER "\r\n" #define LIBSSH2_SSH_DEFAULT_BANNER_WITH_CRLF LIBSSH2_SSH_DEFAULT_BANNER "\r\n"
/* Default generate and safe prime sizes for diffie-hellman-group-exchange-sha1 */ /* Default generate and safe prime sizes for
diffie-hellman-group-exchange-sha1 */
#define LIBSSH2_DH_GEX_MINGROUP 1024 #define LIBSSH2_DH_GEX_MINGROUP 1024
#define LIBSSH2_DH_GEX_OPTGROUP 1536 #define LIBSSH2_DH_GEX_OPTGROUP 1536
#define LIBSSH2_DH_GEX_MAXGROUP 2048 #define LIBSSH2_DH_GEX_MAXGROUP 2048
@@ -314,10 +325,12 @@ typedef struct _LIBSSH2_USERAUTH_KBDINT_RESPONSE
LIBSSH2_CHANNEL *channel, void **channel_abstract) LIBSSH2_CHANNEL *channel, void **channel_abstract)
/* I/O callbacks */ /* I/O callbacks */
#define LIBSSH2_RECV_FUNC(name) ssize_t name(libssh2_socket_t socket, \ #define LIBSSH2_RECV_FUNC(name) \
ssize_t name(libssh2_socket_t socket, \
void *buffer, size_t length, \ void *buffer, size_t length, \
int flags, void **abstract) int flags, void **abstract)
#define LIBSSH2_SEND_FUNC(name) ssize_t name(libssh2_socket_t socket, \ #define LIBSSH2_SEND_FUNC(name) \
ssize_t name(libssh2_socket_t socket, \
const void *buffer, size_t length, \ const void *buffer, size_t length, \
int flags, void **abstract) int flags, void **abstract)
@@ -403,11 +416,16 @@ typedef struct _LIBSSH2_POLLFD {
/* Hash Types */ /* Hash Types */
#define LIBSSH2_HOSTKEY_HASH_MD5 1 #define LIBSSH2_HOSTKEY_HASH_MD5 1
#define LIBSSH2_HOSTKEY_HASH_SHA1 2 #define LIBSSH2_HOSTKEY_HASH_SHA1 2
#define LIBSSH2_HOSTKEY_HASH_SHA256 3
/* Hostkey Types */ /* Hostkey Types */
#define LIBSSH2_HOSTKEY_TYPE_UNKNOWN 0 #define LIBSSH2_HOSTKEY_TYPE_UNKNOWN 0
#define LIBSSH2_HOSTKEY_TYPE_RSA 1 #define LIBSSH2_HOSTKEY_TYPE_RSA 1
#define LIBSSH2_HOSTKEY_TYPE_DSS 2 #define LIBSSH2_HOSTKEY_TYPE_DSS 2
#define LIBSSH2_HOSTKEY_TYPE_ECDSA_256 3
#define LIBSSH2_HOSTKEY_TYPE_ECDSA_384 4
#define LIBSSH2_HOSTKEY_TYPE_ECDSA_521 5
#define LIBSSH2_HOSTKEY_TYPE_ED25519 6
/* Disconnect Codes (defined by SSH protocol) */ /* Disconnect Codes (defined by SSH protocol) */
#define SSH_DISCONNECT_HOST_NOT_ALLOWED_TO_CONNECT 1 #define SSH_DISCONNECT_HOST_NOT_ALLOWED_TO_CONNECT 1
@@ -453,7 +471,8 @@ typedef struct _LIBSSH2_POLLFD {
#define LIBSSH2_ERROR_FILE -16 #define LIBSSH2_ERROR_FILE -16
#define LIBSSH2_ERROR_METHOD_NONE -17 #define LIBSSH2_ERROR_METHOD_NONE -17
#define LIBSSH2_ERROR_AUTHENTICATION_FAILED -18 #define LIBSSH2_ERROR_AUTHENTICATION_FAILED -18
#define LIBSSH2_ERROR_PUBLICKEY_UNRECOGNIZED LIBSSH2_ERROR_AUTHENTICATION_FAILED #define LIBSSH2_ERROR_PUBLICKEY_UNRECOGNIZED \
LIBSSH2_ERROR_AUTHENTICATION_FAILED
#define LIBSSH2_ERROR_PUBLICKEY_UNVERIFIED -19 #define LIBSSH2_ERROR_PUBLICKEY_UNVERIFIED -19
#define LIBSSH2_ERROR_CHANNEL_OUTOFORDER -20 #define LIBSSH2_ERROR_CHANNEL_OUTOFORDER -20
#define LIBSSH2_ERROR_CHANNEL_FAILURE -21 #define LIBSSH2_ERROR_CHANNEL_FAILURE -21
@@ -482,6 +501,8 @@ typedef struct _LIBSSH2_POLLFD {
#define LIBSSH2_ERROR_ENCRYPT -44 #define LIBSSH2_ERROR_ENCRYPT -44
#define LIBSSH2_ERROR_BAD_SOCKET -45 #define LIBSSH2_ERROR_BAD_SOCKET -45
#define LIBSSH2_ERROR_KNOWN_HOSTS -46 #define LIBSSH2_ERROR_KNOWN_HOSTS -46
#define LIBSSH2_ERROR_CHANNEL_WINDOW_FULL -47
#define LIBSSH2_ERROR_KEYFILE_AUTH_FAILED -48
/* this is a define to provide the old (<= 1.2.7) name */ /* this is a define to provide the old (<= 1.2.7) name */
#define LIBSSH2_ERROR_BANNER_NONE LIBSSH2_ERROR_BANNER_RECV #define LIBSSH2_ERROR_BANNER_NONE LIBSSH2_ERROR_BANNER_RECV
@@ -592,12 +613,14 @@ LIBSSH2_API char *libssh2_userauth_list(LIBSSH2_SESSION *session,
unsigned int username_len); unsigned int username_len);
LIBSSH2_API int libssh2_userauth_authenticated(LIBSSH2_SESSION *session); LIBSSH2_API int libssh2_userauth_authenticated(LIBSSH2_SESSION *session);
LIBSSH2_API int libssh2_userauth_password_ex(LIBSSH2_SESSION *session, LIBSSH2_API int
libssh2_userauth_password_ex(LIBSSH2_SESSION *session,
const char *username, const char *username,
unsigned int username_len, unsigned int username_len,
const char *password, const char *password,
unsigned int password_len, unsigned int password_len,
LIBSSH2_PASSWD_CHANGEREQ_FUNC((*passwd_change_cb))); LIBSSH2_PASSWD_CHANGEREQ_FUNC
((*passwd_change_cb)));
#define libssh2_userauth_password(session, username, password) \ #define libssh2_userauth_password(session, username, password) \
libssh2_userauth_password_ex((session), (username), \ libssh2_userauth_password_ex((session), (username), \
@@ -624,7 +647,8 @@ libssh2_userauth_publickey(LIBSSH2_SESSION *session,
const char *username, const char *username,
const unsigned char *pubkeydata, const unsigned char *pubkeydata,
size_t pubkeydata_len, size_t pubkeydata_len,
LIBSSH2_USERAUTH_PUBLICKEY_SIGN_FUNC((*sign_callback)), LIBSSH2_USERAUTH_PUBLICKEY_SIGN_FUNC
((*sign_callback)),
void **abstract); void **abstract);
LIBSSH2_API int LIBSSH2_API int
@@ -716,7 +740,8 @@ libssh2_channel_direct_tcpip_ex(LIBSSH2_SESSION *session, const char *host,
LIBSSH2_API LIBSSH2_LISTENER * LIBSSH2_API LIBSSH2_LISTENER *
libssh2_channel_forward_listen_ex(LIBSSH2_SESSION *session, const char *host, libssh2_channel_forward_listen_ex(LIBSSH2_SESSION *session, const char *host,
int port, int *bound_port, int queue_maxsize); int port, int *bound_port,
int queue_maxsize);
#define libssh2_channel_forward_listen(session, port) \ #define libssh2_channel_forward_listen(session, port) \
libssh2_channel_forward_listen_ex((session), NULL, (port), NULL, 16) libssh2_channel_forward_listen_ex((session), NULL, (port), NULL, 16)
@@ -747,8 +772,10 @@ LIBSSH2_API int libssh2_channel_request_pty_ex(LIBSSH2_CHANNEL *channel,
libssh2_channel_request_pty_ex((channel), (term), \ libssh2_channel_request_pty_ex((channel), (term), \
(unsigned int)strlen(term), \ (unsigned int)strlen(term), \
NULL, 0, \ NULL, 0, \
LIBSSH2_TERM_WIDTH, LIBSSH2_TERM_HEIGHT, \ LIBSSH2_TERM_WIDTH, \
LIBSSH2_TERM_WIDTH_PX, LIBSSH2_TERM_HEIGHT_PX) LIBSSH2_TERM_HEIGHT, \
LIBSSH2_TERM_WIDTH_PX, \
LIBSSH2_TERM_HEIGHT_PX)
LIBSSH2_API int libssh2_channel_request_pty_size_ex(LIBSSH2_CHANNEL *channel, LIBSSH2_API int libssh2_channel_request_pty_size_ex(LIBSSH2_CHANNEL *channel,
int width, int height, int width, int height,
@@ -818,7 +845,8 @@ LIBSSH2_API ssize_t libssh2_channel_write_ex(LIBSSH2_CHANNEL *channel,
#define libssh2_channel_write(channel, buf, buflen) \ #define libssh2_channel_write(channel, buf, buflen) \
libssh2_channel_write_ex((channel), 0, (buf), (buflen)) libssh2_channel_write_ex((channel), 0, (buf), (buflen))
#define libssh2_channel_write_stderr(channel, buf, buflen) \ #define libssh2_channel_write_stderr(channel, buf, buflen) \
libssh2_channel_write_ex((channel), SSH_EXTENDED_DATA_STDERR, (buf), (buflen)) libssh2_channel_write_ex((channel), SSH_EXTENDED_DATA_STDERR, \
(buf), (buflen))
LIBSSH2_API unsigned long LIBSSH2_API unsigned long
libssh2_channel_window_write_ex(LIBSSH2_CHANNEL *channel, libssh2_channel_window_write_ex(LIBSSH2_CHANNEL *channel,
@@ -959,13 +987,17 @@ libssh2_knownhost_init(LIBSSH2_SESSION *session);
#define LIBSSH2_KNOWNHOST_KEYENC_RAW (1<<16) #define LIBSSH2_KNOWNHOST_KEYENC_RAW (1<<16)
#define LIBSSH2_KNOWNHOST_KEYENC_BASE64 (2<<16) #define LIBSSH2_KNOWNHOST_KEYENC_BASE64 (2<<16)
/* type of key (2 bits) */ /* type of key (3 bits) */
#define LIBSSH2_KNOWNHOST_KEY_MASK (7<<18) #define LIBSSH2_KNOWNHOST_KEY_MASK (15<<18)
#define LIBSSH2_KNOWNHOST_KEY_SHIFT 18 #define LIBSSH2_KNOWNHOST_KEY_SHIFT 18
#define LIBSSH2_KNOWNHOST_KEY_RSA1 (1<<18) #define LIBSSH2_KNOWNHOST_KEY_RSA1 (1<<18)
#define LIBSSH2_KNOWNHOST_KEY_SSHRSA (2<<18) #define LIBSSH2_KNOWNHOST_KEY_SSHRSA (2<<18)
#define LIBSSH2_KNOWNHOST_KEY_SSHDSS (3<<18) #define LIBSSH2_KNOWNHOST_KEY_SSHDSS (3<<18)
#define LIBSSH2_KNOWNHOST_KEY_UNKNOWN (7<<18) #define LIBSSH2_KNOWNHOST_KEY_ECDSA_256 (4<<18)
#define LIBSSH2_KNOWNHOST_KEY_ECDSA_384 (5<<18)
#define LIBSSH2_KNOWNHOST_KEY_ECDSA_521 (6<<18)
#define LIBSSH2_KNOWNHOST_KEY_ED25519 (7<<18)
#define LIBSSH2_KNOWNHOST_KEY_UNKNOWN (15<<18)
LIBSSH2_API int LIBSSH2_API int
libssh2_knownhost_add(LIBSSH2_KNOWNHOSTS *hosts, libssh2_knownhost_add(LIBSSH2_KNOWNHOSTS *hosts,
@@ -1233,6 +1265,24 @@ libssh2_agent_disconnect(LIBSSH2_AGENT *agent);
LIBSSH2_API void LIBSSH2_API void
libssh2_agent_free(LIBSSH2_AGENT *agent); libssh2_agent_free(LIBSSH2_AGENT *agent);
/*
* libssh2_agent_set_identity_path()
*
* Allows a custom agent identity socket path beyond SSH_AUTH_SOCK env
*
*/
LIBSSH2_API void
libssh2_agent_set_identity_path(LIBSSH2_AGENT *agent,
const char *path);
/*
* libssh2_agent_get_identity_path()
*
* Returns the custom agent identity socket path if set
*
*/
LIBSSH2_API const char *
libssh2_agent_get_identity_path(LIBSSH2_AGENT *agent);
/* /*
* libssh2_keepalive_config() * libssh2_keepalive_config()

View File

@@ -81,9 +81,11 @@ extern "C" {
#endif #endif
/* Publickey Subsystem */ /* Publickey Subsystem */
LIBSSH2_API LIBSSH2_PUBLICKEY *libssh2_publickey_init(LIBSSH2_SESSION *session); LIBSSH2_API LIBSSH2_PUBLICKEY *
libssh2_publickey_init(LIBSSH2_SESSION *session);
LIBSSH2_API int libssh2_publickey_add_ex(LIBSSH2_PUBLICKEY *pkey, LIBSSH2_API int
libssh2_publickey_add_ex(LIBSSH2_PUBLICKEY *pkey,
const unsigned char *name, const unsigned char *name,
unsigned long name_len, unsigned long name_len,
const unsigned char *blob, const unsigned char *blob,
@@ -107,7 +109,8 @@ LIBSSH2_API int
libssh2_publickey_list_fetch(LIBSSH2_PUBLICKEY *pkey, libssh2_publickey_list_fetch(LIBSSH2_PUBLICKEY *pkey,
unsigned long *num_keys, unsigned long *num_keys,
libssh2_publickey_list **pkey_list); libssh2_publickey_list **pkey_list);
LIBSSH2_API void libssh2_publickey_list_free(LIBSSH2_PUBLICKEY *pkey, LIBSSH2_API void
libssh2_publickey_list_free(LIBSSH2_PUBLICKEY *pkey,
libssh2_publickey_list *pkey_list); libssh2_publickey_list *pkey_list);
LIBSSH2_API int libssh2_publickey_shutdown(LIBSSH2_PUBLICKEY *pkey); LIBSSH2_API int libssh2_publickey_shutdown(LIBSSH2_PUBLICKEY *pkey);

View File

@@ -79,6 +79,9 @@ typedef struct _LIBSSH2_SFTP_STATVFS LIBSSH2_SFTP_STATVFS;
#define LIBSSH2_SFTP_READLINK 1 #define LIBSSH2_SFTP_READLINK 1
#define LIBSSH2_SFTP_REALPATH 2 #define LIBSSH2_SFTP_REALPATH 2
/* Flags for sftp_mkdir() */
#define LIBSSH2_SFTP_DEFAULT_MODE -1
/* SFTP attribute flag bits */ /* SFTP attribute flag bits */
#define LIBSSH2_SFTP_ATTR_SIZE 0x00000001 #define LIBSSH2_SFTP_ATTR_SIZE 0x00000001
#define LIBSSH2_SFTP_ATTR_UIDGID 0x00000002 #define LIBSSH2_SFTP_ATTR_UIDGID 0x00000002
@@ -221,7 +224,8 @@ LIBSSH2_API unsigned long libssh2_sftp_last_error(LIBSSH2_SFTP *sftp);
LIBSSH2_API LIBSSH2_CHANNEL *libssh2_sftp_get_channel(LIBSSH2_SFTP *sftp); LIBSSH2_API LIBSSH2_CHANNEL *libssh2_sftp_get_channel(LIBSSH2_SFTP *sftp);
/* File / Directory Ops */ /* File / Directory Ops */
LIBSSH2_API LIBSSH2_SFTP_HANDLE *libssh2_sftp_open_ex(LIBSSH2_SFTP *sftp, LIBSSH2_API LIBSSH2_SFTP_HANDLE *
libssh2_sftp_open_ex(LIBSSH2_SFTP *sftp,
const char *filename, const char *filename,
unsigned int filename_len, unsigned int filename_len,
unsigned long flags, unsigned long flags,
@@ -328,7 +332,8 @@ LIBSSH2_API int libssh2_sftp_symlink_ex(LIBSSH2_SFTP *sftp,
const char *path, const char *path,
unsigned int path_len, unsigned int path_len,
char *target, char *target,
unsigned int target_len, int link_type); unsigned int target_len,
int link_type);
#define libssh2_sftp_symlink(sftp, orig, linkpath) \ #define libssh2_sftp_symlink(sftp, orig, linkpath) \
libssh2_sftp_symlink_ex((sftp), (orig), strlen(orig), (linkpath), \ libssh2_sftp_symlink_ex((sftp), (orig), strlen(orig), (linkpath), \
strlen(linkpath), LIBSSH2_SFTP_SYMLINK) strlen(linkpath), LIBSSH2_SFTP_SYMLINK)

View File

@@ -1,7 +1,7 @@
#!/bin/sh #!/bin/sh
# install - install a program, script, or datafile # install - install a program, script, or datafile
scriptversion=2005-05-14.22 scriptversion=2018-03-11.20; # UTC
# This originates from X11R5 (mit/util/scripts/install.sh), which was # This originates from X11R5 (mit/util/scripts/install.sh), which was
# later released in X11R6 (xc/config/util/install.sh) with the # later released in X11R6 (xc/config/util/install.sh) with the
@@ -35,42 +35,57 @@ scriptversion=2005-05-14.22
# FSF changes to this file are in the public domain. # FSF changes to this file are in the public domain.
# #
# Calling this script install-sh is preferred over install.sh, to prevent # Calling this script install-sh is preferred over install.sh, to prevent
# `make' implicit rules from creating a file called install from it # 'make' implicit rules from creating a file called install from it
# when there is no Makefile. # when there is no Makefile.
# #
# This script is compatible with the BSD install script, but was written # This script is compatible with the BSD install script, but was written
# from scratch. It can only install one file at a time, a restriction # from scratch.
# shared with many OS's install programs.
# set DOITPROG to echo to test this script tab=' '
nl='
'
IFS=" $tab$nl"
# Don't use :- since 4.3BSD and earlier shells don't like it. # Set DOITPROG to "echo" to test this script.
doit="${DOITPROG-}"
# put in absolute paths if you don't have them in your path; or use env. vars. doit=${DOITPROG-}
doit_exec=${doit:-exec}
mvprog="${MVPROG-mv}" # Put in absolute file names if you don't have them in your path;
cpprog="${CPPROG-cp}" # or use environment vars.
chmodprog="${CHMODPROG-chmod}"
chownprog="${CHOWNPROG-chown}" chgrpprog=${CHGRPPROG-chgrp}
chgrpprog="${CHGRPPROG-chgrp}" chmodprog=${CHMODPROG-chmod}
stripprog="${STRIPPROG-strip}" chownprog=${CHOWNPROG-chown}
rmprog="${RMPROG-rm}" cmpprog=${CMPPROG-cmp}
mkdirprog="${MKDIRPROG-mkdir}" cpprog=${CPPROG-cp}
mkdirprog=${MKDIRPROG-mkdir}
mvprog=${MVPROG-mv}
rmprog=${RMPROG-rm}
stripprog=${STRIPPROG-strip}
posix_mkdir=
# Desired mode of installed file.
mode=0755
chmodcmd="$chmodprog 0755"
chowncmd=
chgrpcmd= chgrpcmd=
stripcmd= chmodcmd=$chmodprog
chowncmd=
mvcmd=$mvprog
rmcmd="$rmprog -f" rmcmd="$rmprog -f"
mvcmd="$mvprog" stripcmd=
src= src=
dst= dst=
dir_arg= dir_arg=
dstarg= dst_arg=
no_target_directory=
usage="Usage: $0 [OPTION]... [-T] SRCFILE DSTFILE copy_on_change=false
is_target_a_directory=possibly
usage="\
Usage: $0 [OPTION]... [-T] SRCFILE DSTFILE
or: $0 [OPTION]... SRCFILES... DIRECTORY or: $0 [OPTION]... SRCFILES... DIRECTORY
or: $0 [OPTION]... -t DIRECTORY SRCFILES... or: $0 [OPTION]... -t DIRECTORY SRCFILES...
or: $0 [OPTION]... -d DIRECTORIES... or: $0 [OPTION]... -d DIRECTORIES...
@@ -80,7 +95,11 @@ In the 2nd and 3rd, copy all SRCFILES to DIRECTORY.
In the 4th, create DIRECTORIES. In the 4th, create DIRECTORIES.
Options: Options:
--help display this help and exit.
--version display version info and exit.
-c (ignored) -c (ignored)
-C install only if different (preserve the last data modification time)
-d create directories instead of installing files. -d create directories instead of installing files.
-g GROUP $chgrpprog installed files to GROUP. -g GROUP $chgrpprog installed files to GROUP.
-m MODE $chmodprog installed files to MODE. -m MODE $chmodprog installed files to MODE.
@@ -88,100 +107,156 @@ Options:
-s $stripprog installed files. -s $stripprog installed files.
-t DIRECTORY install into DIRECTORY. -t DIRECTORY install into DIRECTORY.
-T report an error if DSTFILE is a directory. -T report an error if DSTFILE is a directory.
--help display this help and exit.
--version display version info and exit.
Environment variables override the default commands: Environment variables override the default commands:
CHGRPPROG CHMODPROG CHOWNPROG CPPROG MKDIRPROG MVPROG RMPROG STRIPPROG CHGRPPROG CHMODPROG CHOWNPROG CMPPROG CPPROG MKDIRPROG MVPROG
RMPROG STRIPPROG
" "
while test -n "$1"; do while test $# -ne 0; do
case $1 in case $1 in
-c) shift -c) ;;
continue;;
-d) dir_arg=true -C) copy_on_change=true;;
shift
continue;; -d) dir_arg=true;;
-g) chgrpcmd="$chgrpprog $2" -g) chgrpcmd="$chgrpprog $2"
shift shift;;
shift
continue;;
--help) echo "$usage"; exit $?;; --help) echo "$usage"; exit $?;;
-m) chmodcmd="$chmodprog $2" -m) mode=$2
shift case $mode in
shift *' '* | *"$tab"* | *"$nl"* | *'*'* | *'?'* | *'['*)
continue;; echo "$0: invalid mode: $mode" >&2
exit 1;;
esac
shift;;
-o) chowncmd="$chownprog $2" -o) chowncmd="$chownprog $2"
shift shift;;
shift
continue;;
-s) stripcmd=$stripprog -s) stripcmd=$stripprog;;
shift
continue;;
-t) dstarg=$2 -t)
shift is_target_a_directory=always
shift dst_arg=$2
continue;; # Protect names problematic for 'test' and other utilities.
case $dst_arg in
-* | [=\(\)!]) dst_arg=./$dst_arg;;
esac
shift;;
-T) no_target_directory=true -T) is_target_a_directory=never;;
shift
continue;;
--version) echo "$0 $scriptversion"; exit $?;; --version) echo "$0 $scriptversion"; exit $?;;
*) # When -d is used, all remaining arguments are directories to create. --) shift
break;;
-*) echo "$0: invalid option: $1" >&2
exit 1;;
*) break;;
esac
shift
done
# We allow the use of options -d and -T together, by making -d
# take the precedence; this is for compatibility with GNU install.
if test -n "$dir_arg"; then
if test -n "$dst_arg"; then
echo "$0: target directory not allowed when installing a directory." >&2
exit 1
fi
fi
if test $# -ne 0 && test -z "$dir_arg$dst_arg"; then
# When -d is used, all remaining arguments are directories to create.
# When -t is used, the destination is already specified. # When -t is used, the destination is already specified.
test -n "$dir_arg$dstarg" && break
# Otherwise, the last argument is the destination. Remove it from $@. # Otherwise, the last argument is the destination. Remove it from $@.
for arg for arg
do do
if test -n "$dstarg"; then if test -n "$dst_arg"; then
# $@ is not empty: it contains at least $arg. # $@ is not empty: it contains at least $arg.
set fnord "$@" "$dstarg" set fnord "$@" "$dst_arg"
shift # fnord shift # fnord
fi fi
shift # arg shift # arg
dstarg=$arg dst_arg=$arg
done # Protect names problematic for 'test' and other utilities.
break;; case $dst_arg in
-* | [=\(\)!]) dst_arg=./$dst_arg;;
esac esac
done done
fi
if test -z "$1"; then if test $# -eq 0; then
if test -z "$dir_arg"; then if test -z "$dir_arg"; then
echo "$0: no input file specified." >&2 echo "$0: no input file specified." >&2
exit 1 exit 1
fi fi
# It's OK to call `install-sh -d' without argument. # It's OK to call 'install-sh -d' without argument.
# This can happen when creating conditional directories. # This can happen when creating conditional directories.
exit 0 exit 0
fi fi
if test -z "$dir_arg"; then
if test $# -gt 1 || test "$is_target_a_directory" = always; then
if test ! -d "$dst_arg"; then
echo "$0: $dst_arg: Is not a directory." >&2
exit 1
fi
fi
fi
if test -z "$dir_arg"; then
do_exit='(exit $ret); exit $ret'
trap "ret=129; $do_exit" 1
trap "ret=130; $do_exit" 2
trap "ret=141; $do_exit" 13
trap "ret=143; $do_exit" 15
# Set umask so as not to create temps with too-generous modes.
# However, 'strip' requires both read and write access to temps.
case $mode in
# Optimize common cases.
*644) cp_umask=133;;
*755) cp_umask=22;;
*[0-7])
if test -z "$stripcmd"; then
u_plus_rw=
else
u_plus_rw='% 200'
fi
cp_umask=`expr '(' 777 - $mode % 1000 ')' $u_plus_rw`;;
*)
if test -z "$stripcmd"; then
u_plus_rw=
else
u_plus_rw=,u+rw
fi
cp_umask=$mode$u_plus_rw;;
esac
fi
for src for src
do do
# Protect names starting with `-'. # Protect names problematic for 'test' and other utilities.
case $src in case $src in
-*) src=./$src ;; -* | [=\(\)!]) src=./$src;;
esac esac
if test -n "$dir_arg"; then if test -n "$dir_arg"; then
dst=$src dst=$src
src= dstdir=$dst
test -d "$dstdir"
dstdir_status=$?
else
if test -d "$dst"; then
mkdircmd=:
chmodcmd=
else
mkdircmd=$mkdirprog
fi
else
# Waiting for this to be detected by the "$cpprog $src $dsttmp" command # Waiting for this to be detected by the "$cpprog $src $dsttmp" command
# might cause directories to be created, which would be especially bad # might cause directories to be created, which would be especially bad
# if $src (and thus $dsttmp) contains '*'. # if $src (and thus $dsttmp) contains '*'.
@@ -190,82 +265,193 @@ do
exit 1 exit 1
fi fi
if test -z "$dstarg"; then if test -z "$dst_arg"; then
echo "$0: no destination specified." >&2 echo "$0: no destination specified." >&2
exit 1 exit 1
fi fi
dst=$dst_arg
dst=$dstarg # If destination is a directory, append the input filename.
# Protect names starting with `-'.
case $dst in
-*) dst=./$dst ;;
esac
# If destination is a directory, append the input filename; won't work
# if double slashes aren't ignored.
if test -d "$dst"; then if test -d "$dst"; then
if test -n "$no_target_directory"; then if test "$is_target_a_directory" = never; then
echo "$0: $dstarg: Is a directory" >&2 echo "$0: $dst_arg: Is a directory" >&2
exit 1 exit 1
fi fi
dst=$dst/`basename "$src"` dstdir=$dst
dstbase=`basename "$src"`
case $dst in
*/) dst=$dst$dstbase;;
*) dst=$dst/$dstbase;;
esac
dstdir_status=0
else
dstdir=`dirname "$dst"`
test -d "$dstdir"
dstdir_status=$?
fi fi
fi fi
# This sed command emulates the dirname command. case $dstdir in
dstdir=`echo "$dst" | sed -e 's,/*$,,;s,[^/]*$,,;s,/*$,,;s,^$,.,'` */) dstdirslash=$dstdir;;
*) dstdirslash=$dstdir/;;
esac
# Make sure that the destination directory exists. obsolete_mkdir_used=false
# Skip lots of stat calls in the usual case. if test $dstdir_status != 0; then
if test ! -d "$dstdir"; then case $posix_mkdir in
defaultIFS=' '')
' # Create intermediate dirs using mode 755 as modified by the umask.
IFS="${IFS-$defaultIFS}" # This is like FreeBSD 'install' as of 1997-10-28.
umask=`umask`
case $stripcmd.$umask in
# Optimize common cases.
*[2367][2367]) mkdir_umask=$umask;;
.*0[02][02] | .[02][02] | .[02]) mkdir_umask=22;;
*[0-7])
mkdir_umask=`expr $umask + 22 \
- $umask % 100 % 40 + $umask % 20 \
- $umask % 10 % 4 + $umask % 2
`;;
*) mkdir_umask=$umask,go-w;;
esac
# With -d, create the new directory with the user-specified mode.
# Otherwise, rely on $mkdir_umask.
if test -n "$dir_arg"; then
mkdir_mode=-m$mode
else
mkdir_mode=
fi
posix_mkdir=false
case $umask in
*[123567][0-7][0-7])
# POSIX mkdir -p sets u+wx bits regardless of umask, which
# is incompatible with FreeBSD 'install' when (umask & 300) != 0.
;;
*)
# Note that $RANDOM variable is not portable (e.g. dash); Use it
# here however when possible just to lower collision chance.
tmpdir=${TMPDIR-/tmp}/ins$RANDOM-$$
trap 'ret=$?; rmdir "$tmpdir/a/b" "$tmpdir/a" "$tmpdir" 2>/dev/null; exit $ret' 0
# Because "mkdir -p" follows existing symlinks and we likely work
# directly in world-writeable /tmp, make sure that the '$tmpdir'
# directory is successfully created first before we actually test
# 'mkdir -p' feature.
if (umask $mkdir_umask &&
$mkdirprog $mkdir_mode "$tmpdir" &&
exec $mkdirprog $mkdir_mode -p -- "$tmpdir/a/b") >/dev/null 2>&1
then
if test -z "$dir_arg" || {
# Check for POSIX incompatibilities with -m.
# HP-UX 11.23 and IRIX 6.5 mkdir -m -p sets group- or
# other-writable bit of parent directory when it shouldn't.
# FreeBSD 6.1 mkdir -m -p sets mode of existing directory.
test_tmpdir="$tmpdir/a"
ls_ld_tmpdir=`ls -ld "$test_tmpdir"`
case $ls_ld_tmpdir in
d????-?r-*) different_mode=700;;
d????-?--*) different_mode=755;;
*) false;;
esac &&
$mkdirprog -m$different_mode -p -- "$test_tmpdir" && {
ls_ld_tmpdir_1=`ls -ld "$test_tmpdir"`
test "$ls_ld_tmpdir" = "$ls_ld_tmpdir_1"
}
}
then posix_mkdir=:
fi
rmdir "$tmpdir/a/b" "$tmpdir/a" "$tmpdir"
else
# Remove any dirs left behind by ancient mkdir implementations.
rmdir ./$mkdir_mode ./-p ./-- "$tmpdir" 2>/dev/null
fi
trap '' 0;;
esac;;
esac
if
$posix_mkdir && (
umask $mkdir_umask &&
$doit_exec $mkdirprog $mkdir_mode -p -- "$dstdir"
)
then :
else
# The umask is ridiculous, or mkdir does not conform to POSIX,
# or it failed possibly due to a race condition. Create the
# directory the slow way, step by step, checking for races as we go.
case $dstdir in
/*) prefix='/';;
[-=\(\)!]*) prefix='./';;
*) prefix='';;
esac
oIFS=$IFS oIFS=$IFS
# Some sh's can't handle IFS=/ for some reason. IFS=/
IFS='%' set -f
set x `echo "$dstdir" | sed -e 's@/@%@g' -e 's@^%@/@'` set fnord $dstdir
shift shift
set +f
IFS=$oIFS IFS=$oIFS
pathcomp= prefixes=
while test $# -ne 0 ; do for d
pathcomp=$pathcomp$1 do
shift test X"$d" = X && continue
if test ! -d "$pathcomp"; then
$mkdirprog "$pathcomp" prefix=$prefix$d
# mkdir can fail with a `File exist' error in case several if test -d "$prefix"; then
# install-sh are creating the directory concurrently. This prefixes=
# is OK. else
test -d "$pathcomp" || exit if $posix_mkdir; then
(umask=$mkdir_umask &&
$doit_exec $mkdirprog $mkdir_mode -p -- "$dstdir") && break
# Don't fail if two instances are running concurrently.
test -d "$prefix" || exit 1
else
case $prefix in
*\'*) qprefix=`echo "$prefix" | sed "s/'/'\\\\\\\\''/g"`;;
*) qprefix=$prefix;;
esac
prefixes="$prefixes '$qprefix'"
fi fi
pathcomp=$pathcomp/ fi
prefix=$prefix/
done done
if test -n "$prefixes"; then
# Don't fail if two instances are running concurrently.
(umask $mkdir_umask &&
eval "\$doit_exec \$mkdirprog $prefixes") ||
test -d "$dstdir" || exit 1
obsolete_mkdir_used=true
fi
fi
fi fi
if test -n "$dir_arg"; then if test -n "$dir_arg"; then
$doit $mkdircmd "$dst" \ { test -z "$chowncmd" || $doit $chowncmd "$dst"; } &&
&& { test -z "$chowncmd" || $doit $chowncmd "$dst"; } \ { test -z "$chgrpcmd" || $doit $chgrpcmd "$dst"; } &&
&& { test -z "$chgrpcmd" || $doit $chgrpcmd "$dst"; } \ { test "$obsolete_mkdir_used$chowncmd$chgrpcmd" = false ||
&& { test -z "$stripcmd" || $doit $stripcmd "$dst"; } \ test -z "$chmodcmd" || $doit $chmodcmd $mode "$dst"; } || exit 1
&& { test -z "$chmodcmd" || $doit $chmodcmd "$dst"; }
else else
dstfile=`basename "$dst"`
# Make a couple of temp file names in the proper directory. # Make a couple of temp file names in the proper directory.
dsttmp=$dstdir/_inst.$$_ dsttmp=${dstdirslash}_inst.$$_
rmtmp=$dstdir/_rm.$$_ rmtmp=${dstdirslash}_rm.$$_
# Trap to clean up those temp files at exit. # Trap to clean up those temp files at exit.
trap 'ret=$?; rm -f "$dsttmp" "$rmtmp" && exit $ret' 0 trap 'ret=$?; rm -f "$dsttmp" "$rmtmp" && exit $ret' 0
trap '(exit $?); exit' 1 2 13 15
# Copy the file name to the temp name. # Copy the file name to the temp name.
$doit $cpprog "$src" "$dsttmp" && (umask $cp_umask && $doit_exec $cpprog "$src" "$dsttmp") &&
# and set any options; do chmod last to preserve setuid bits. # and set any options; do chmod last to preserve setuid bits.
# #
@@ -273,51 +459,60 @@ do
# ignore errors from any of these, just make sure not to ignore # ignore errors from any of these, just make sure not to ignore
# errors from the above "$doit $cpprog $src $dsttmp" command. # errors from the above "$doit $cpprog $src $dsttmp" command.
# #
{ test -z "$chowncmd" || $doit $chowncmd "$dsttmp"; } \ { test -z "$chowncmd" || $doit $chowncmd "$dsttmp"; } &&
&& { test -z "$chgrpcmd" || $doit $chgrpcmd "$dsttmp"; } \ { test -z "$chgrpcmd" || $doit $chgrpcmd "$dsttmp"; } &&
&& { test -z "$stripcmd" || $doit $stripcmd "$dsttmp"; } \ { test -z "$stripcmd" || $doit $stripcmd "$dsttmp"; } &&
&& { test -z "$chmodcmd" || $doit $chmodcmd "$dsttmp"; } && { test -z "$chmodcmd" || $doit $chmodcmd $mode "$dsttmp"; } &&
# If -C, don't bother to copy if it wouldn't change the file.
if $copy_on_change &&
old=`LC_ALL=C ls -dlL "$dst" 2>/dev/null` &&
new=`LC_ALL=C ls -dlL "$dsttmp" 2>/dev/null` &&
set -f &&
set X $old && old=:$2:$4:$5:$6 &&
set X $new && new=:$2:$4:$5:$6 &&
set +f &&
test "$old" = "$new" &&
$cmpprog "$dst" "$dsttmp" >/dev/null 2>&1
then
rm -f "$dsttmp"
else
# Rename the file to the real destination.
$doit $mvcmd -f "$dsttmp" "$dst" 2>/dev/null ||
# Now rename the file to the real destination.
{ $doit $mvcmd -f "$dsttmp" "$dstdir/$dstfile" 2>/dev/null \
|| {
# The rename failed, perhaps because mv can't rename something else # The rename failed, perhaps because mv can't rename something else
# to itself, or perhaps because mv is so ancient that it does not # to itself, or perhaps because mv is so ancient that it does not
# support -f. # support -f.
{
# Now remove or move aside any old file at destination location. # Now remove or move aside any old file at destination location.
# We try this two ways since rm can't unlink itself on some # We try this two ways since rm can't unlink itself on some
# systems and the destination file might be busy for other # systems and the destination file might be busy for other
# reasons. In this case, the final cleanup might fail but the new # reasons. In this case, the final cleanup might fail but the new
# file should still install successfully. # file should still install successfully.
{ {
if test -f "$dstdir/$dstfile"; then test ! -f "$dst" ||
$doit $rmcmd -f "$dstdir/$dstfile" 2>/dev/null \ $doit $rmcmd -f "$dst" 2>/dev/null ||
|| $doit $mvcmd -f "$dstdir/$dstfile" "$rmtmp" 2>/dev/null \ { $doit $mvcmd -f "$dst" "$rmtmp" 2>/dev/null &&
|| { { $doit $rmcmd -f "$rmtmp" 2>/dev/null; :; }
echo "$0: cannot unlink or rename $dstdir/$dstfile" >&2 } ||
{ echo "$0: cannot unlink or rename $dst" >&2
(exit 1); exit 1 (exit 1); exit 1
} }
else
:
fi
} && } &&
# Now rename the file to the real destination. # Now rename the file to the real destination.
$doit $mvcmd "$dsttmp" "$dstdir/$dstfile" $doit $mvcmd "$dsttmp" "$dst"
} }
} fi || exit 1
fi || { (exit 1); exit 1; }
trap '' 0
fi
done done
# The final little trick to "correctly" pass the exit status to the exit trap.
{
(exit 0); exit 0
}
# Local variables: # Local variables:
# eval: (add-hook 'write-file-hooks 'time-stamp) # eval: (add-hook 'before-save-hook 'time-stamp)
# time-stamp-start: "scriptversion=" # time-stamp-start: "scriptversion="
# time-stamp-format: "%:y-%02m-%02d.%02H" # time-stamp-format: "%:y-%02m-%02d.%02H"
# time-stamp-end: "$" # time-stamp-time-zone: "UTC0"
# time-stamp-end: "; # UTC"
# End: # End:

View File

@@ -49,7 +49,7 @@ setenv TGTCCSID '500' # Target CCSID of objects.
setenv DEBUG '*ALL' # Debug level. setenv DEBUG '*ALL' # Debug level.
setenv OPTIMIZE '10' # Optimisation level setenv OPTIMIZE '10' # Optimisation level
setenv OUTPUT '*NONE' # Compilation output option. setenv OUTPUT '*NONE' # Compilation output option.
setenv TGTRLS 'V5R3M0' # Target OS release. setenv TGTRLS 'V6R1M0' # Target OS release.
setenv IFSDIR '/libssh2' # Installation IFS directory. setenv IFSDIR '/libssh2' # Installation IFS directory.
# Define ZLIB availability and locations. # Define ZLIB availability and locations.
@@ -180,7 +180,7 @@ make_module()
CMD="CRTCMOD MODULE(${TARGETLIB}/${1}) SRCSTMF('__tmpsrcf.c')" CMD="CRTCMOD MODULE(${TARGETLIB}/${1}) SRCSTMF('__tmpsrcf.c')"
# CMD="${CMD} SYSIFCOPT(*IFS64IO) OPTION(*INCDIRFIRST *SHOWINC *SHOWSYS)" # CMD="${CMD} SYSIFCOPT(*IFS64IO) OPTION(*INCDIRFIRST *SHOWINC *SHOWSYS)"
CMD="${CMD} SYSIFCOPT(*IFS64IO) OPTION(*INCDIRFIRST)" CMD="${CMD} SYSIFCOPT(*IFS64IO) OPTION(*INCDIRFIRST)"
CMD="${CMD} LOCALETYPE(*LOCALE)" CMD="${CMD} LOCALETYPE(*LOCALE) FLAG(10)"
CMD="${CMD} INCDIR('${TOPDIR}/os400/include'" CMD="${CMD} INCDIR('${TOPDIR}/os400/include'"
CMD="${CMD} '/QIBM/ProdData/qadrt/include' '${TOPDIR}/include'" CMD="${CMD} '/QIBM/ProdData/qadrt/include' '${TOPDIR}/include'"
CMD="${CMD} '${TOPDIR}/os400' '${SRCDIR}'" CMD="${CMD} '${TOPDIR}/os400' '${SRCDIR}'"

View File

@@ -77,21 +77,21 @@ if(CRYPTO_BACKEND STREQUAL "OpenSSL" OR NOT CRYPTO_BACKEND)
list(APPEND PC_LIBS -lcrypt32) list(APPEND PC_LIBS -lcrypt32)
find_file(DLL_LIBEAY32 find_file(DLL_LIBEAY32
NAMES libeay32.dll crypto.dll NAMES libeay32.dll crypto.dll libcrypto-1_1.dll libcrypto-1_1-x64.dll
HINTS ${_OPENSSL_ROOT_HINTS} PATHS ${_OPENSSL_ROOT_PATHS} HINTS ${_OPENSSL_ROOT_HINTS} PATHS ${_OPENSSL_ROOT_PATHS}
PATH_SUFFIXES bin) PATH_SUFFIXES bin)
if (NOT DLL_LIBEAY32) if (NOT DLL_LIBEAY32)
message(WARNING message(WARNING
"Unable to find OpenSSL libeay32 DLL, executables may not run") "Unable to find OpenSSL crypto (aka libeay32) DLL, executables may not run")
endif() endif()
find_file(DLL_SSLEAY32 find_file(DLL_SSLEAY32
NAMES ssleay32.dll ssl.dll NAMES ssleay32.dll ssl.dll libssl-1_1.dll libssl-1_1-x64.dll
HINTS ${_OPENSSL_ROOT_HINTS} PATHS ${_OPENSSL_ROOT_PATHS} HINTS ${_OPENSSL_ROOT_HINTS} PATHS ${_OPENSSL_ROOT_PATHS}
PATH_SUFFIXES bin) PATH_SUFFIXES bin)
if (NOT DLL_SSLEAY32) if (NOT DLL_SSLEAY32)
message(WARNING message(WARNING
"Unable to find OpenSSL ssleay32 DLL, executables may not run") "Unable to find OpenSSL ssl (aka ssleay32) DLL, executables may not run")
endif() endif()
if(DLL_LIBEAY32 AND DLL_SSLEAY32) if(DLL_LIBEAY32 AND DLL_SSLEAY32)
@@ -176,6 +176,9 @@ include(GNUInstallDirs)
set(SOURCES set(SOURCES
${CRYPTO_SOURCES} ${CRYPTO_SOURCES}
agent.c agent.c
blf.h
bcrypt_pbkdf.c
blowfish.c
channel.c channel.c
channel.h channel.h
comp.c comp.c
@@ -217,7 +220,7 @@ set_target_properties(libssh2 PROPERTIES PREFIX "")
target_compile_definitions(libssh2 PRIVATE ${PRIVATE_COMPILE_DEFINITIONS}) target_compile_definitions(libssh2 PRIVATE ${PRIVATE_COMPILE_DEFINITIONS})
target_include_directories(libssh2 target_include_directories(libssh2
PRIVATE ${PRIVATE_INCLUDE_DIRECTORIES} PRIVATE "${PROJECT_SOURCE_DIR}/include/" ${PRIVATE_INCLUDE_DIRECTORIES}
PUBLIC PUBLIC
$<BUILD_INTERFACE:${PROJECT_SOURCE_DIR}/include> $<BUILD_INTERFACE:${PROJECT_SOURCE_DIR}/include>
$<INSTALL_INTERFACE:$<INSTALL_PREFIX>/${CMAKE_INSTALL_INCLUDEDIR}>) $<INSTALL_INTERFACE:$<INSTALL_PREFIX>/${CMAKE_INSTALL_INCLUDEDIR}>)
@@ -312,6 +315,7 @@ if (NOT HAVE_STRTOLL)
check_symbol_exists(_strtoi64 stdlib.h HAVE_STRTOI64) check_symbol_exists(_strtoi64 stdlib.h HAVE_STRTOI64)
endif() endif()
check_symbol_exists(snprintf stdio.h HAVE_SNPRINTF) check_symbol_exists(snprintf stdio.h HAVE_SNPRINTF)
check_symbol_exists(memset_s string.h HAVE_MEMSET_S)
if(${CMAKE_SYSTEM_NAME} STREQUAL "Darwin" OR if(${CMAKE_SYSTEM_NAME} STREQUAL "Darwin" OR
${CMAKE_SYSTEM_NAME} STREQUAL "Interix") ${CMAKE_SYSTEM_NAME} STREQUAL "Interix")
@@ -322,7 +326,7 @@ if(${CMAKE_SYSTEM_NAME} STREQUAL "Darwin" OR
# filesystem here" # filesystem here"
# #
# Mac OS X's poll has funny behaviors, like: # Mac OS X's poll has funny behaviors, like:
# not being able to do poll on no fildescriptors (10.3?) # not being able to do poll on no filedescriptors (10.3?)
# not being able to poll on some files (like anything in /dev) # not being able to poll on some files (like anything in /dev)
# not having reliable timeout support # not having reliable timeout support
# inconsistent return of POLLHUP where other implementations give POLLIN # inconsistent return of POLLHUP where other implementations give POLLIN
@@ -333,7 +337,7 @@ endif()
append_needed_socket_libraries(LIBRARIES) append_needed_socket_libraries(LIBRARIES)
# Non-blocking socket support tests. Must be after after library tests to # Non-blocking socket support tests. Must be after library tests to
# link correctly # link correctly
set(SAVE_CMAKE_REQUIRED_LIBRARIES ${CMAKE_REQUIRED_LIBRARIES}) set(SAVE_CMAKE_REQUIRED_LIBRARIES ${CMAKE_REQUIRED_LIBRARIES})
set(CMAKE_REQUIRED_LIBRARIES ${LIBRARIES}) set(CMAKE_REQUIRED_LIBRARIES ${LIBRARIES})

View File

@@ -1,7 +1,7 @@
# $Id: Makefile.am,v 1.21 2009/05/07 17:21:56 bagder Exp $ # $Id: Makefile.am,v 1.21 2009/05/07 17:21:56 bagder Exp $
AUTOMAKE_OPTIONS = foreign nostdinc AUTOMAKE_OPTIONS = foreign nostdinc
# Get the CRYPTO_CSOURCES and CRYPTO_HHEADERS defines # Get the CRYPTO_CSOURCES, CRYPTO_HHEADERS and CRYPTO_LTLIBS defines
if OPENSSL if OPENSSL
include ../Makefile.OpenSSL.inc include ../Makefile.OpenSSL.inc
endif endif
@@ -11,9 +11,6 @@ endif
if WINCNG if WINCNG
include ../Makefile.WinCNG.inc include ../Makefile.WinCNG.inc
endif endif
if OS400QC3
include ../Makefile.os400qc3.inc
endif
if MBEDTLS if MBEDTLS
include ../Makefile.mbedTLS.inc include ../Makefile.mbedTLS.inc
endif endif
@@ -65,4 +62,4 @@ VERSION=-version-info 1:1:0
libssh2_la_LDFLAGS = $(VERSION) -no-undefined \ libssh2_la_LDFLAGS = $(VERSION) -no-undefined \
-export-symbols-regex '^libssh2_.*' \ -export-symbols-regex '^libssh2_.*' \
$(LTLIBGCRYPT) $(LTLIBSSL) $(LTLIBZ) $(CRYPTO_LTLIBS) $(LTLIBZ)

View File

@@ -137,12 +137,12 @@ libssh2_la_LIBADD =
am__libssh2_la_SOURCES_DIST = channel.c comp.c crypt.c hostkey.c kex.c \ am__libssh2_la_SOURCES_DIST = channel.c comp.c crypt.c hostkey.c kex.c \
mac.c misc.c packet.c publickey.c scp.c session.c sftp.c \ mac.c misc.c packet.c publickey.c scp.c session.c sftp.c \
userauth.c transport.c version.c knownhost.c agent.c \ userauth.c transport.c version.c knownhost.c agent.c \
libgcrypt.c mbedtls.c openssl.c os400qc3.c wincng.c pem.c \ libgcrypt.c mbedtls.c openssl.c wincng.c pem.c keepalive.c \
keepalive.c global.c libssh2_priv.h libgcrypt.h mbedtls.h \ global.c blowfish.c bcrypt_pbkdf.c libssh2_priv.h libgcrypt.h \
openssl.h os400qc3.h wincng.h transport.h channel.h comp.h \ mbedtls.h openssl.h wincng.h transport.h channel.h comp.h \
mac.h misc.h packet.h userauth.h session.h sftp.h crypto.h mac.h misc.h packet.h userauth.h session.h sftp.h crypto.h \
@LIBGCRYPT_FALSE@@MBEDTLS_FALSE@@OPENSSL_FALSE@@OS400QC3_FALSE@@WINCNG_TRUE@am__objects_1 = wincng.lo blf.h
@LIBGCRYPT_FALSE@@MBEDTLS_FALSE@@OPENSSL_FALSE@@OS400QC3_TRUE@am__objects_1 = os400qc3.lo @LIBGCRYPT_FALSE@@MBEDTLS_FALSE@@OPENSSL_FALSE@@WINCNG_TRUE@am__objects_1 = wincng.lo
@LIBGCRYPT_FALSE@@MBEDTLS_FALSE@@OPENSSL_TRUE@am__objects_1 = \ @LIBGCRYPT_FALSE@@MBEDTLS_FALSE@@OPENSSL_TRUE@am__objects_1 = \
@LIBGCRYPT_FALSE@@MBEDTLS_FALSE@@OPENSSL_TRUE@ openssl.lo @LIBGCRYPT_FALSE@@MBEDTLS_FALSE@@OPENSSL_TRUE@ openssl.lo
@LIBGCRYPT_FALSE@@MBEDTLS_TRUE@am__objects_1 = mbedtls.lo @LIBGCRYPT_FALSE@@MBEDTLS_TRUE@am__objects_1 = mbedtls.lo
@@ -150,7 +150,8 @@ am__libssh2_la_SOURCES_DIST = channel.c comp.c crypt.c hostkey.c kex.c \
am__objects_2 = channel.lo comp.lo crypt.lo hostkey.lo kex.lo mac.lo \ am__objects_2 = channel.lo comp.lo crypt.lo hostkey.lo kex.lo mac.lo \
misc.lo packet.lo publickey.lo scp.lo session.lo sftp.lo \ misc.lo packet.lo publickey.lo scp.lo session.lo sftp.lo \
userauth.lo transport.lo version.lo knownhost.lo agent.lo \ userauth.lo transport.lo version.lo knownhost.lo agent.lo \
$(am__objects_1) pem.lo keepalive.lo global.lo $(am__objects_1) pem.lo keepalive.lo global.lo blowfish.lo \
bcrypt_pbkdf.lo
am__objects_3 = am__objects_3 =
am__objects_4 = $(am__objects_3) am__objects_4 = $(am__objects_3)
am_libssh2_la_OBJECTS = $(am__objects_2) $(am__objects_4) am_libssh2_la_OBJECTS = $(am__objects_2) $(am__objects_4)
@@ -177,14 +178,15 @@ am__v_at_1 =
DEFAULT_INCLUDES = DEFAULT_INCLUDES =
depcomp = $(SHELL) $(top_srcdir)/depcomp depcomp = $(SHELL) $(top_srcdir)/depcomp
am__maybe_remake_depfiles = depfiles am__maybe_remake_depfiles = depfiles
am__depfiles_remade = ./$(DEPDIR)/agent.Plo ./$(DEPDIR)/channel.Plo \ am__depfiles_remade = ./$(DEPDIR)/agent.Plo \
./$(DEPDIR)/comp.Plo ./$(DEPDIR)/crypt.Plo \ ./$(DEPDIR)/bcrypt_pbkdf.Plo ./$(DEPDIR)/blowfish.Plo \
./$(DEPDIR)/global.Plo ./$(DEPDIR)/hostkey.Plo \ ./$(DEPDIR)/channel.Plo ./$(DEPDIR)/comp.Plo \
./$(DEPDIR)/keepalive.Plo ./$(DEPDIR)/kex.Plo \ ./$(DEPDIR)/crypt.Plo ./$(DEPDIR)/global.Plo \
./$(DEPDIR)/knownhost.Plo ./$(DEPDIR)/libgcrypt.Plo \ ./$(DEPDIR)/hostkey.Plo ./$(DEPDIR)/keepalive.Plo \
./$(DEPDIR)/mac.Plo ./$(DEPDIR)/mbedtls.Plo \ ./$(DEPDIR)/kex.Plo ./$(DEPDIR)/knownhost.Plo \
./$(DEPDIR)/misc.Plo ./$(DEPDIR)/openssl.Plo \ ./$(DEPDIR)/libgcrypt.Plo ./$(DEPDIR)/mac.Plo \
./$(DEPDIR)/os400qc3.Plo ./$(DEPDIR)/packet.Plo \ ./$(DEPDIR)/mbedtls.Plo ./$(DEPDIR)/misc.Plo \
./$(DEPDIR)/openssl.Plo ./$(DEPDIR)/packet.Plo \
./$(DEPDIR)/pem.Plo ./$(DEPDIR)/publickey.Plo \ ./$(DEPDIR)/pem.Plo ./$(DEPDIR)/publickey.Plo \
./$(DEPDIR)/scp.Plo ./$(DEPDIR)/session.Plo \ ./$(DEPDIR)/scp.Plo ./$(DEPDIR)/session.Plo \
./$(DEPDIR)/sftp.Plo ./$(DEPDIR)/transport.Plo \ ./$(DEPDIR)/sftp.Plo ./$(DEPDIR)/transport.Plo \
@@ -239,8 +241,7 @@ CTAGS = ctags
am__DIST_COMMON = $(srcdir)/../Makefile.OpenSSL.inc \ am__DIST_COMMON = $(srcdir)/../Makefile.OpenSSL.inc \
$(srcdir)/../Makefile.WinCNG.inc $(srcdir)/../Makefile.inc \ $(srcdir)/../Makefile.WinCNG.inc $(srcdir)/../Makefile.inc \
$(srcdir)/../Makefile.libgcrypt.inc \ $(srcdir)/../Makefile.libgcrypt.inc \
$(srcdir)/../Makefile.mbedTLS.inc \ $(srcdir)/../Makefile.mbedTLS.inc $(srcdir)/Makefile.in \
$(srcdir)/../Makefile.os400qc3.inc $(srcdir)/Makefile.in \
$(srcdir)/libssh2_config.h.in $(top_srcdir)/depcomp $(srcdir)/libssh2_config.h.in $(top_srcdir)/depcomp
DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
ACLOCAL = @ACLOCAL@ ACLOCAL = @ACLOCAL@
@@ -274,7 +275,7 @@ GREP = @GREP@
HAVE_LIBBCRYPT = @HAVE_LIBBCRYPT@ HAVE_LIBBCRYPT = @HAVE_LIBBCRYPT@
HAVE_LIBCRYPT32 = @HAVE_LIBCRYPT32@ HAVE_LIBCRYPT32 = @HAVE_LIBCRYPT32@
HAVE_LIBGCRYPT = @HAVE_LIBGCRYPT@ HAVE_LIBGCRYPT = @HAVE_LIBGCRYPT@
HAVE_LIBMBEDTLS = @HAVE_LIBMBEDTLS@ HAVE_LIBMBEDCRYPTO = @HAVE_LIBMBEDCRYPTO@
HAVE_LIBSSL = @HAVE_LIBSSL@ HAVE_LIBSSL = @HAVE_LIBSSL@
HAVE_LIBZ = @HAVE_LIBZ@ HAVE_LIBZ = @HAVE_LIBZ@
INSTALL = @INSTALL@ INSTALL = @INSTALL@
@@ -290,8 +291,8 @@ LIBCRYPT32 = @LIBCRYPT32@
LIBCRYPT32_PREFIX = @LIBCRYPT32_PREFIX@ LIBCRYPT32_PREFIX = @LIBCRYPT32_PREFIX@
LIBGCRYPT = @LIBGCRYPT@ LIBGCRYPT = @LIBGCRYPT@
LIBGCRYPT_PREFIX = @LIBGCRYPT_PREFIX@ LIBGCRYPT_PREFIX = @LIBGCRYPT_PREFIX@
LIBMBEDTLS = @LIBMBEDTLS@ LIBMBEDCRYPTO = @LIBMBEDCRYPTO@
LIBMBEDTLS_PREFIX = @LIBMBEDTLS_PREFIX@ LIBMBEDCRYPTO_PREFIX = @LIBMBEDCRYPTO_PREFIX@
LIBOBJS = @LIBOBJS@ LIBOBJS = @LIBOBJS@
LIBS = @LIBS@ LIBS = @LIBS@
LIBSREQUIRED = @LIBSREQUIRED@ LIBSREQUIRED = @LIBSREQUIRED@
@@ -306,7 +307,7 @@ LN_S = @LN_S@
LTLIBBCRYPT = @LTLIBBCRYPT@ LTLIBBCRYPT = @LTLIBBCRYPT@
LTLIBCRYPT32 = @LTLIBCRYPT32@ LTLIBCRYPT32 = @LTLIBCRYPT32@
LTLIBGCRYPT = @LTLIBGCRYPT@ LTLIBGCRYPT = @LTLIBGCRYPT@
LTLIBMBEDTLS = @LTLIBMBEDTLS@ LTLIBMBEDCRYPTO = @LTLIBMBEDCRYPTO@
LTLIBOBJS = @LTLIBOBJS@ LTLIBOBJS = @LTLIBOBJS@
LTLIBSSL = @LTLIBSSL@ LTLIBSSL = @LTLIBSSL@
LTLIBZ = @LTLIBZ@ LTLIBZ = @LTLIBZ@
@@ -395,22 +396,25 @@ AUTOMAKE_OPTIONS = foreign nostdinc
@LIBGCRYPT_TRUE@CRYPTO_CSOURCES = libgcrypt.c @LIBGCRYPT_TRUE@CRYPTO_CSOURCES = libgcrypt.c
@MBEDTLS_TRUE@CRYPTO_CSOURCES = mbedtls.c @MBEDTLS_TRUE@CRYPTO_CSOURCES = mbedtls.c
@OPENSSL_TRUE@CRYPTO_CSOURCES = openssl.c @OPENSSL_TRUE@CRYPTO_CSOURCES = openssl.c
@OS400QC3_TRUE@CRYPTO_CSOURCES = os400qc3.c
@WINCNG_TRUE@CRYPTO_CSOURCES = wincng.c @WINCNG_TRUE@CRYPTO_CSOURCES = wincng.c
@LIBGCRYPT_TRUE@CRYPTO_HHEADERS = libgcrypt.h @LIBGCRYPT_TRUE@CRYPTO_HHEADERS = libgcrypt.h
@MBEDTLS_TRUE@CRYPTO_HHEADERS = mbedtls.h @MBEDTLS_TRUE@CRYPTO_HHEADERS = mbedtls.h
@OPENSSL_TRUE@CRYPTO_HHEADERS = openssl.h @OPENSSL_TRUE@CRYPTO_HHEADERS = openssl.h
@OS400QC3_TRUE@CRYPTO_HHEADERS = os400qc3.h
@WINCNG_TRUE@CRYPTO_HHEADERS = wincng.h @WINCNG_TRUE@CRYPTO_HHEADERS = wincng.h
@LIBGCRYPT_TRUE@CRYPTO_LTLIBS = $(LTLIBGCRYPT)
@MBEDTLS_TRUE@CRYPTO_LTLIBS = $(LTLIBMBEDCRYPTO)
@OPENSSL_TRUE@CRYPTO_LTLIBS = $(LTLIBSSL)
@WINCNG_TRUE@CRYPTO_LTLIBS = $(LTLIBBCRYPT) $(LTLIBCRYPT32)
CSOURCES = channel.c comp.c crypt.c hostkey.c kex.c mac.c misc.c \ CSOURCES = channel.c comp.c crypt.c hostkey.c kex.c mac.c misc.c \
packet.c publickey.c scp.c session.c sftp.c userauth.c transport.c \ packet.c publickey.c scp.c session.c sftp.c userauth.c transport.c \
version.c knownhost.c agent.c $(CRYPTO_CSOURCES) pem.c keepalive.c global.c version.c knownhost.c agent.c $(CRYPTO_CSOURCES) pem.c keepalive.c global.c \
blowfish.c bcrypt_pbkdf.c
HHEADERS = libssh2_priv.h $(CRYPTO_HHEADERS) transport.h channel.h comp.h \ HHEADERS = libssh2_priv.h $(CRYPTO_HHEADERS) transport.h channel.h comp.h \
mac.h misc.h packet.h userauth.h session.h sftp.h crypto.h mac.h misc.h packet.h userauth.h session.h sftp.h crypto.h blf.h
# Get the CRYPTO_CSOURCES and CRYPTO_HHEADERS defines # Get the CRYPTO_CSOURCES, CRYPTO_HHEADERS and CRYPTO_LTLIBS defines
# Makefile.inc provides the CSOURCES and HHEADERS defines # Makefile.inc provides the CSOURCES and HHEADERS defines
libssh2_la_SOURCES = $(CSOURCES) $(HHEADERS) libssh2_la_SOURCES = $(CSOURCES) $(HHEADERS)
@@ -452,14 +456,14 @@ AM_CPPFLAGS = -I$(top_srcdir)/include -I$(top_builddir)/src
# #
libssh2_la_LDFLAGS = $(VERSION) -no-undefined \ libssh2_la_LDFLAGS = $(VERSION) -no-undefined \
-export-symbols-regex '^libssh2_.*' \ -export-symbols-regex '^libssh2_.*' \
$(LTLIBGCRYPT) $(LTLIBSSL) $(LTLIBZ) $(CRYPTO_LTLIBS) $(LTLIBZ)
all: libssh2_config.h all: libssh2_config.h
$(MAKE) $(AM_MAKEFLAGS) all-am $(MAKE) $(AM_MAKEFLAGS) all-am
.SUFFIXES: .SUFFIXES:
.SUFFIXES: .c .lo .o .obj .SUFFIXES: .c .lo .o .obj
$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(srcdir)/../Makefile.OpenSSL.inc $(srcdir)/../Makefile.libgcrypt.inc $(srcdir)/../Makefile.WinCNG.inc $(srcdir)/../Makefile.os400qc3.inc $(srcdir)/../Makefile.mbedTLS.inc $(srcdir)/../Makefile.inc $(am__configure_deps) $(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(srcdir)/../Makefile.OpenSSL.inc $(srcdir)/../Makefile.libgcrypt.inc $(srcdir)/../Makefile.WinCNG.inc $(srcdir)/../Makefile.mbedTLS.inc $(srcdir)/../Makefile.inc $(am__configure_deps)
@for dep in $?; do \ @for dep in $?; do \
case '$(am__configure_deps)' in \ case '$(am__configure_deps)' in \
*$$dep*) \ *$$dep*) \
@@ -479,7 +483,7 @@ Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles)'; \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles)'; \
cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles);; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles);; \
esac; esac;
$(srcdir)/../Makefile.OpenSSL.inc $(srcdir)/../Makefile.libgcrypt.inc $(srcdir)/../Makefile.WinCNG.inc $(srcdir)/../Makefile.os400qc3.inc $(srcdir)/../Makefile.mbedTLS.inc $(srcdir)/../Makefile.inc $(am__empty): $(srcdir)/../Makefile.OpenSSL.inc $(srcdir)/../Makefile.libgcrypt.inc $(srcdir)/../Makefile.WinCNG.inc $(srcdir)/../Makefile.mbedTLS.inc $(srcdir)/../Makefile.inc $(am__empty):
$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
@@ -550,6 +554,8 @@ distclean-compile:
-rm -f *.tab.c -rm -f *.tab.c
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/agent.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/agent.Plo@am__quote@ # am--include-marker
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/bcrypt_pbkdf.Plo@am__quote@ # am--include-marker
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/blowfish.Plo@am__quote@ # am--include-marker
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/channel.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/channel.Plo@am__quote@ # am--include-marker
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/comp.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/comp.Plo@am__quote@ # am--include-marker
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/crypt.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/crypt.Plo@am__quote@ # am--include-marker
@@ -563,7 +569,6 @@ distclean-compile:
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/mbedtls.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/mbedtls.Plo@am__quote@ # am--include-marker
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/misc.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/misc.Plo@am__quote@ # am--include-marker
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/openssl.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/openssl.Plo@am__quote@ # am--include-marker
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/os400qc3.Plo@am__quote@ # am--include-marker
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/packet.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/packet.Plo@am__quote@ # am--include-marker
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pem.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pem.Plo@am__quote@ # am--include-marker
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/publickey.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/publickey.Plo@am__quote@ # am--include-marker
@@ -737,6 +742,8 @@ clean-am: clean-generic clean-libLTLIBRARIES clean-libtool \
distclean: distclean-am distclean: distclean-am
-rm -f ./$(DEPDIR)/agent.Plo -rm -f ./$(DEPDIR)/agent.Plo
-rm -f ./$(DEPDIR)/bcrypt_pbkdf.Plo
-rm -f ./$(DEPDIR)/blowfish.Plo
-rm -f ./$(DEPDIR)/channel.Plo -rm -f ./$(DEPDIR)/channel.Plo
-rm -f ./$(DEPDIR)/comp.Plo -rm -f ./$(DEPDIR)/comp.Plo
-rm -f ./$(DEPDIR)/crypt.Plo -rm -f ./$(DEPDIR)/crypt.Plo
@@ -750,7 +757,6 @@ distclean: distclean-am
-rm -f ./$(DEPDIR)/mbedtls.Plo -rm -f ./$(DEPDIR)/mbedtls.Plo
-rm -f ./$(DEPDIR)/misc.Plo -rm -f ./$(DEPDIR)/misc.Plo
-rm -f ./$(DEPDIR)/openssl.Plo -rm -f ./$(DEPDIR)/openssl.Plo
-rm -f ./$(DEPDIR)/os400qc3.Plo
-rm -f ./$(DEPDIR)/packet.Plo -rm -f ./$(DEPDIR)/packet.Plo
-rm -f ./$(DEPDIR)/pem.Plo -rm -f ./$(DEPDIR)/pem.Plo
-rm -f ./$(DEPDIR)/publickey.Plo -rm -f ./$(DEPDIR)/publickey.Plo
@@ -807,6 +813,8 @@ installcheck-am:
maintainer-clean: maintainer-clean-am maintainer-clean: maintainer-clean-am
-rm -f ./$(DEPDIR)/agent.Plo -rm -f ./$(DEPDIR)/agent.Plo
-rm -f ./$(DEPDIR)/bcrypt_pbkdf.Plo
-rm -f ./$(DEPDIR)/blowfish.Plo
-rm -f ./$(DEPDIR)/channel.Plo -rm -f ./$(DEPDIR)/channel.Plo
-rm -f ./$(DEPDIR)/comp.Plo -rm -f ./$(DEPDIR)/comp.Plo
-rm -f ./$(DEPDIR)/crypt.Plo -rm -f ./$(DEPDIR)/crypt.Plo
@@ -820,7 +828,6 @@ maintainer-clean: maintainer-clean-am
-rm -f ./$(DEPDIR)/mbedtls.Plo -rm -f ./$(DEPDIR)/mbedtls.Plo
-rm -f ./$(DEPDIR)/misc.Plo -rm -f ./$(DEPDIR)/misc.Plo
-rm -f ./$(DEPDIR)/openssl.Plo -rm -f ./$(DEPDIR)/openssl.Plo
-rm -f ./$(DEPDIR)/os400qc3.Plo
-rm -f ./$(DEPDIR)/packet.Plo -rm -f ./$(DEPDIR)/packet.Plo
-rm -f ./$(DEPDIR)/pem.Plo -rm -f ./$(DEPDIR)/pem.Plo
-rm -f ./$(DEPDIR)/publickey.Plo -rm -f ./$(DEPDIR)/publickey.Plo

View File

@@ -138,6 +138,8 @@ struct _LIBSSH2_AGENT
struct agent_transaction_ctx transctx; struct agent_transaction_ctx transctx;
struct agent_publickey *identity; struct agent_publickey *identity;
struct list_head head; /* list of public keys */ struct list_head head; /* list of public keys */
char *identity_agent_path; /* Path to a custom identity agent socket */
}; };
#ifdef PF_UNIX #ifdef PF_UNIX
@@ -147,10 +149,13 @@ agent_connect_unix(LIBSSH2_AGENT *agent)
const char *path; const char *path;
struct sockaddr_un s_un; struct sockaddr_un s_un;
path = agent->identity_agent_path;
if(!path) {
path = getenv("SSH_AUTH_SOCK"); path = getenv("SSH_AUTH_SOCK");
if(!path) if(!path)
return _libssh2_error(agent->session, LIBSSH2_ERROR_BAD_USE, return _libssh2_error(agent->session, LIBSSH2_ERROR_BAD_USE,
"no auth sock variable"); "no auth sock variable");
}
agent->fd = socket(PF_UNIX, SOCK_STREAM, 0); agent->fd = socket(PF_UNIX, SOCK_STREAM, 0);
if(agent->fd < 0) if(agent->fd < 0)
@@ -297,7 +302,8 @@ agent_transact_pageant(LIBSSH2_AGENT *agent, agent_transaction_ctx_t transctx)
return _libssh2_error(agent->session, LIBSSH2_ERROR_AGENT_PROTOCOL, return _libssh2_error(agent->session, LIBSSH2_ERROR_AGENT_PROTOCOL,
"found no pageant"); "found no pageant");
sprintf(mapname, "PageantRequest%08x", (unsigned)GetCurrentThreadId()); snprintf(mapname, sizeof(mapname),
"PageantRequest%08x%c", (unsigned)GetCurrentThreadId(), '\0');
filemap = CreateFileMapping(INVALID_HANDLE_VALUE, NULL, PAGE_READWRITE, filemap = CreateFileMapping(INVALID_HANDLE_VALUE, NULL, PAGE_READWRITE,
0, PAGEANT_MAX_MSGLEN, mapname); 0, PAGEANT_MAX_MSGLEN, mapname);
@@ -621,7 +627,8 @@ agent_list_identities(LIBSSH2_AGENT *agent)
} }
static void static void
agent_free_identities(LIBSSH2_AGENT *agent) { agent_free_identities(LIBSSH2_AGENT *agent)
{
struct agent_publickey *node; struct agent_publickey *node;
struct agent_publickey *next; struct agent_publickey *next;
@@ -671,6 +678,7 @@ libssh2_agent_init(LIBSSH2_SESSION *session)
} }
agent->fd = LIBSSH2_INVALID_SOCKET; agent->fd = LIBSSH2_INVALID_SOCKET;
agent->session = session; agent->session = session;
agent->identity_agent_path = NULL;
_libssh2_list_init(&agent->head); _libssh2_list_init(&agent->head);
return agent; return agent;
@@ -707,7 +715,7 @@ LIBSSH2_API int
libssh2_agent_list_identities(LIBSSH2_AGENT *agent) libssh2_agent_list_identities(LIBSSH2_AGENT *agent)
{ {
memset(&agent->transctx, 0, sizeof agent->transctx); memset(&agent->transctx, 0, sizeof agent->transctx);
/* Abondon the last fetched identities */ /* Abandon the last fetched identities */
agent_free_identities(agent); agent_free_identities(agent);
return agent_list_identities(agent); return agent_list_identities(agent);
} }
@@ -801,11 +809,52 @@ libssh2_agent_disconnect(LIBSSH2_AGENT *agent)
* collection of public keys. * collection of public keys.
*/ */
LIBSSH2_API void LIBSSH2_API void
libssh2_agent_free(LIBSSH2_AGENT *agent) { libssh2_agent_free(LIBSSH2_AGENT *agent)
{
/* Allow connection freeing when the socket has lost its connection */ /* Allow connection freeing when the socket has lost its connection */
if(agent->fd != LIBSSH2_INVALID_SOCKET) { if(agent->fd != LIBSSH2_INVALID_SOCKET) {
libssh2_agent_disconnect(agent); libssh2_agent_disconnect(agent);
} }
if(agent->identity_agent_path != NULL)
LIBSSH2_FREE(agent->session, agent->identity_agent_path);
agent_free_identities(agent); agent_free_identities(agent);
LIBSSH2_FREE(agent->session, agent); LIBSSH2_FREE(agent->session, agent);
} }
/*
* libssh2_agent_set_identity_path()
*
* Allows a custom agent socket path beyond SSH_AUTH_SOCK env
*
*/
LIBSSH2_API void
libssh2_agent_set_identity_path(LIBSSH2_AGENT *agent, const char *path)
{
if(agent->identity_agent_path) {
LIBSSH2_FREE(agent->session, agent->identity_agent_path);
agent->identity_agent_path = NULL;
}
if(path) {
size_t path_len = strlen(path);
if(path_len < SIZE_MAX - 1) {
char *path_buf = LIBSSH2_ALLOC(agent->session, path_len + 1);
memcpy(path_buf, path, path_len);
path_buf[path_len] = '\0';
agent->identity_agent_path = path_buf;
}
}
}
/*
* libssh2_agent_get_identity_path()
*
* Returns the custom agent socket path if set
*
*/
LIBSSH2_API const char *libssh2_agent_get_identity_path(LIBSSH2_AGENT *agent)
{
return agent->identity_agent_path;
}

180
libssh2/src/bcrypt_pbkdf.c Normal file
View File

@@ -0,0 +1,180 @@
/* $OpenBSD: bcrypt_pbkdf.c,v 1.4 2013/07/29 00:55:53 tedu Exp $ */
/*
* Copyright (c) 2013 Ted Unangst <tedu@openbsd.org>
*
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
#ifndef HAVE_BCRYPT_PBKDF
#include "libssh2_priv.h"
#include <stdlib.h>
#include <sys/types.h>
#ifdef HAVE_SYS_PARAM_H
#include <sys/param.h>
#endif
#include "blf.h"
#define MINIMUM(a,b) (((a) < (b)) ? (a) : (b))
/*
* pkcs #5 pbkdf2 implementation using the "bcrypt" hash
*
* The bcrypt hash function is derived from the bcrypt password hashing
* function with the following modifications:
* 1. The input password and salt are preprocessed with SHA512.
* 2. The output length is expanded to 256 bits.
* 3. Subsequently the magic string to be encrypted is lengthened and modifed
* to "OxychromaticBlowfishSwatDynamite"
* 4. The hash function is defined to perform 64 rounds of initial state
* expansion. (More rounds are performed by iterating the hash.)
*
* Note that this implementation pulls the SHA512 operations into the caller
* as a performance optimization.
*
* One modification from official pbkdf2. Instead of outputting key material
* linearly, we mix it. pbkdf2 has a known weakness where if one uses it to
* generate (i.e.) 512 bits of key material for use as two 256 bit keys, an
* attacker can merely run once through the outer loop below, but the user
* always runs it twice. Shuffling output bytes requires computing the
* entirety of the key material to assemble any subkey. This is something a
* wise caller could do; we just do it for you.
*/
#define BCRYPT_BLOCKS 8
#define BCRYPT_HASHSIZE (BCRYPT_BLOCKS * 4)
static void
bcrypt_hash(uint8_t *sha2pass, uint8_t *sha2salt, uint8_t *out)
{
blf_ctx state;
uint8_t ciphertext[BCRYPT_HASHSIZE] =
"OxychromaticBlowfishSwatDynamite";
uint32_t cdata[BCRYPT_BLOCKS];
int i;
uint16_t j;
size_t shalen = SHA512_DIGEST_LENGTH;
/* key expansion */
Blowfish_initstate(&state);
Blowfish_expandstate(&state, sha2salt, shalen, sha2pass, shalen);
for(i = 0; i < 64; i++) {
Blowfish_expand0state(&state, sha2salt, shalen);
Blowfish_expand0state(&state, sha2pass, shalen);
}
/* encryption */
j = 0;
for(i = 0; i < BCRYPT_BLOCKS; i++)
cdata[i] = Blowfish_stream2word(ciphertext, sizeof(ciphertext),
&j);
for(i = 0; i < 64; i++)
blf_enc(&state, cdata, sizeof(cdata) / sizeof(uint64_t));
/* copy out */
for(i = 0; i < BCRYPT_BLOCKS; i++) {
out[4 * i + 3] = (cdata[i] >> 24) & 0xff;
out[4 * i + 2] = (cdata[i] >> 16) & 0xff;
out[4 * i + 1] = (cdata[i] >> 8) & 0xff;
out[4 * i + 0] = cdata[i] & 0xff;
}
/* zap */
_libssh2_explicit_zero(ciphertext, sizeof(ciphertext));
_libssh2_explicit_zero(cdata, sizeof(cdata));
_libssh2_explicit_zero(&state, sizeof(state));
}
int
bcrypt_pbkdf(const char *pass, size_t passlen, const uint8_t *salt,
size_t saltlen,
uint8_t *key, size_t keylen, unsigned int rounds)
{
uint8_t sha2pass[SHA512_DIGEST_LENGTH];
uint8_t sha2salt[SHA512_DIGEST_LENGTH];
uint8_t out[BCRYPT_HASHSIZE];
uint8_t tmpout[BCRYPT_HASHSIZE];
uint8_t *countsalt;
size_t i, j, amt, stride;
uint32_t count;
size_t origkeylen = keylen;
libssh2_sha512_ctx ctx;
/* nothing crazy */
if(rounds < 1)
return -1;
if(passlen == 0 || saltlen == 0 || keylen == 0 ||
keylen > sizeof(out) * sizeof(out) || saltlen > 1<<20)
return -1;
countsalt = calloc(1, saltlen + 4);
if(countsalt == NULL)
return -1;
stride = (keylen + sizeof(out) - 1) / sizeof(out);
amt = (keylen + stride - 1) / stride;
memcpy(countsalt, salt, saltlen);
/* collapse password */
libssh2_sha512_init(&ctx);
libssh2_sha512_update(ctx, pass, passlen);
libssh2_sha512_final(ctx, sha2pass);
/* generate key, sizeof(out) at a time */
for(count = 1; keylen > 0; count++) {
countsalt[saltlen + 0] = (count >> 24) & 0xff;
countsalt[saltlen + 1] = (count >> 16) & 0xff;
countsalt[saltlen + 2] = (count >> 8) & 0xff;
countsalt[saltlen + 3] = count & 0xff;
/* first round, salt is salt */
libssh2_sha512_init(&ctx);
libssh2_sha512_update(ctx, countsalt, saltlen + 4);
libssh2_sha512_final(ctx, sha2salt);
bcrypt_hash(sha2pass, sha2salt, tmpout);
memcpy(out, tmpout, sizeof(out));
for(i = 1; i < rounds; i++) {
/* subsequent rounds, salt is previous output */
libssh2_sha512_init(&ctx);
libssh2_sha512_update(ctx, tmpout, sizeof(tmpout));
libssh2_sha512_final(ctx, sha2salt);
bcrypt_hash(sha2pass, sha2salt, tmpout);
for(j = 0; j < sizeof(out); j++)
out[j] ^= tmpout[j];
}
/*
* pbkdf2 deviation: ouput the key material non-linearly.
*/
amt = MINIMUM(amt, keylen);
for(i = 0; i < amt; i++) {
size_t dest = i * stride + (count - 1);
if(dest >= origkeylen) {
break;
}
key[dest] = out[i];
}
keylen -= i;
}
/* zap */
_libssh2_explicit_zero(out, sizeof(out));
free(countsalt);
return 0;
}
#endif /* HAVE_BCRYPT_PBKDF */

90
libssh2/src/blf.h Normal file
View File

@@ -0,0 +1,90 @@
/* $OpenBSD: blf.h,v 1.7 2007/03/14 17:59:41 grunk Exp $ */
/*
* Blowfish - a fast block cipher designed by Bruce Schneier
*
* Copyright 1997 Niels Provos <provos@physnet.uni-hamburg.de>
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. 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.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by Niels Provos.
* 4. The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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.
*/
#ifndef _BLF_H_
#define _BLF_H_
#if !defined(HAVE_BCRYPT_PBKDF) && !defined(HAVE_BLH_H)
/* Schneier specifies a maximum key length of 56 bytes.
* This ensures that every key bit affects every cipher
* bit. However, the subkeys can hold up to 72 bytes.
* Warning: For normal blowfish encryption only 56 bytes
* of the key affect all cipherbits.
*/
#define BLF_N 16 /* Number of Subkeys */
#define BLF_MAXKEYLEN ((BLF_N-2)*4) /* 448 bits */
#define BLF_MAXUTILIZED ((BLF_N + 2)*4) /* 576 bits */
/* Blowfish context */
typedef struct BlowfishContext {
uint32_t S[4][256]; /* S-Boxes */
uint32_t P[BLF_N + 2]; /* Subkeys */
} blf_ctx;
/* Raw access to customized Blowfish
* blf_key is just:
* Blowfish_initstate( state )
* Blowfish_expand0state( state, key, keylen )
*/
void Blowfish_encipher(blf_ctx *, uint32_t *, uint32_t *);
void Blowfish_decipher(blf_ctx *, uint32_t *, uint32_t *);
void Blowfish_initstate(blf_ctx *);
void Blowfish_expand0state(blf_ctx *, const uint8_t *, uint16_t);
void Blowfish_expandstate
(blf_ctx *, const uint8_t *, uint16_t, const uint8_t *, uint16_t);
/* Standard Blowfish */
void blf_key(blf_ctx *, const uint8_t *, uint16_t);
void blf_enc(blf_ctx *, uint32_t *, uint16_t);
void blf_dec(blf_ctx *, uint32_t *, uint16_t);
void blf_ecb_encrypt(blf_ctx *, uint8_t *, uint32_t);
void blf_ecb_decrypt(blf_ctx *, uint8_t *, uint32_t);
void blf_cbc_encrypt(blf_ctx *, uint8_t *, uint8_t *, uint32_t);
void blf_cbc_decrypt(blf_ctx *, uint8_t *, uint8_t *, uint32_t);
/* Converts uint8_t to uint32_t */
uint32_t Blowfish_stream2word(const uint8_t *, uint16_t, uint16_t *);
/* bcrypt with pbkd */
int bcrypt_pbkdf(const char *pass, size_t passlen, const uint8_t *salt,
size_t saltlen,
uint8_t *key, size_t keylen, unsigned int rounds);
#endif /* !defined(HAVE_BCRYPT_PBKDF) && !defined(HAVE_BLH_H) */
#endif /* _BLF_H */

697
libssh2/src/blowfish.c Normal file
View File

@@ -0,0 +1,697 @@
/* $OpenBSD: blowfish.c,v 1.18 2004/11/02 17:23:26 hshoexer Exp $ */
/*
* Blowfish block cipher for OpenBSD
* Copyright 1997 Niels Provos <provos@physnet.uni-hamburg.de>
* All rights reserved.
*
* Implementation advice by David Mazieres <dm@lcs.mit.edu>.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. 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.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by Niels Provos.
* 4. The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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.
*/
/*
* This code is derived from section 14.3 and the given source
* in section V of Applied Cryptography, second edition.
* Blowfish is an unpatented fast block cipher designed by
* Bruce Schneier.
*/
#if !defined(HAVE_BCRYPT_PBKDF) && (!defined(HAVE_BLOWFISH_INITSTATE) || \
!defined(HAVE_BLOWFISH_EXPAND0STATE) || \
!defined(HAVE_BLF_ENC))
#if 0
#include <stdio.h> /* used for debugging */
#include <string.h>
#endif
#include <sys/types.h>
#include "libssh2.h"
#include "blf.h"
#undef inline
#ifdef __GNUC__
#define inline __inline
#else /* !__GNUC__ */
#define inline
#endif /* !__GNUC__ */
/* Function for Feistel Networks */
#define F(s, x) ((((s)[ (((x)>>24)&0xFF)] \
+ (s)[0x100 + (((x)>>16)&0xFF)]) \
^ (s)[0x200 + (((x)>> 8)&0xFF)]) \
+ (s)[0x300 + ( (x) &0xFF)])
#define BLFRND(s,p,i,j,n) (i ^= F(s,j) ^ (p)[n])
void
Blowfish_encipher(blf_ctx *c, uint32_t *xl, uint32_t *xr)
{
uint32_t Xl;
uint32_t Xr;
uint32_t *s = c->S[0];
uint32_t *p = c->P;
Xl = *xl;
Xr = *xr;
Xl ^= p[0];
BLFRND(s, p, Xr, Xl, 1); BLFRND(s, p, Xl, Xr, 2);
BLFRND(s, p, Xr, Xl, 3); BLFRND(s, p, Xl, Xr, 4);
BLFRND(s, p, Xr, Xl, 5); BLFRND(s, p, Xl, Xr, 6);
BLFRND(s, p, Xr, Xl, 7); BLFRND(s, p, Xl, Xr, 8);
BLFRND(s, p, Xr, Xl, 9); BLFRND(s, p, Xl, Xr, 10);
BLFRND(s, p, Xr, Xl, 11); BLFRND(s, p, Xl, Xr, 12);
BLFRND(s, p, Xr, Xl, 13); BLFRND(s, p, Xl, Xr, 14);
BLFRND(s, p, Xr, Xl, 15); BLFRND(s, p, Xl, Xr, 16);
*xl = Xr ^ p[17];
*xr = Xl;
}
void
Blowfish_decipher(blf_ctx *c, uint32_t *xl, uint32_t *xr)
{
uint32_t Xl;
uint32_t Xr;
uint32_t *s = c->S[0];
uint32_t *p = c->P;
Xl = *xl;
Xr = *xr;
Xl ^= p[17];
BLFRND(s, p, Xr, Xl, 16); BLFRND(s, p, Xl, Xr, 15);
BLFRND(s, p, Xr, Xl, 14); BLFRND(s, p, Xl, Xr, 13);
BLFRND(s, p, Xr, Xl, 12); BLFRND(s, p, Xl, Xr, 11);
BLFRND(s, p, Xr, Xl, 10); BLFRND(s, p, Xl, Xr, 9);
BLFRND(s, p, Xr, Xl, 8); BLFRND(s, p, Xl, Xr, 7);
BLFRND(s, p, Xr, Xl, 6); BLFRND(s, p, Xl, Xr, 5);
BLFRND(s, p, Xr, Xl, 4); BLFRND(s, p, Xl, Xr, 3);
BLFRND(s, p, Xr, Xl, 2); BLFRND(s, p, Xl, Xr, 1);
*xl = Xr ^ p[0];
*xr = Xl;
}
void
Blowfish_initstate(blf_ctx *c)
{
/* P-box and S-box tables initialized with digits of Pi */
static const blf_ctx initstate =
{ {
{
0xd1310ba6, 0x98dfb5ac, 0x2ffd72db, 0xd01adfb7,
0xb8e1afed, 0x6a267e96, 0xba7c9045, 0xf12c7f99,
0x24a19947, 0xb3916cf7, 0x0801f2e2, 0x858efc16,
0x636920d8, 0x71574e69, 0xa458fea3, 0xf4933d7e,
0x0d95748f, 0x728eb658, 0x718bcd58, 0x82154aee,
0x7b54a41d, 0xc25a59b5, 0x9c30d539, 0x2af26013,
0xc5d1b023, 0x286085f0, 0xca417918, 0xb8db38ef,
0x8e79dcb0, 0x603a180e, 0x6c9e0e8b, 0xb01e8a3e,
0xd71577c1, 0xbd314b27, 0x78af2fda, 0x55605c60,
0xe65525f3, 0xaa55ab94, 0x57489862, 0x63e81440,
0x55ca396a, 0x2aab10b6, 0xb4cc5c34, 0x1141e8ce,
0xa15486af, 0x7c72e993, 0xb3ee1411, 0x636fbc2a,
0x2ba9c55d, 0x741831f6, 0xce5c3e16, 0x9b87931e,
0xafd6ba33, 0x6c24cf5c, 0x7a325381, 0x28958677,
0x3b8f4898, 0x6b4bb9af, 0xc4bfe81b, 0x66282193,
0x61d809cc, 0xfb21a991, 0x487cac60, 0x5dec8032,
0xef845d5d, 0xe98575b1, 0xdc262302, 0xeb651b88,
0x23893e81, 0xd396acc5, 0x0f6d6ff3, 0x83f44239,
0x2e0b4482, 0xa4842004, 0x69c8f04a, 0x9e1f9b5e,
0x21c66842, 0xf6e96c9a, 0x670c9c61, 0xabd388f0,
0x6a51a0d2, 0xd8542f68, 0x960fa728, 0xab5133a3,
0x6eef0b6c, 0x137a3be4, 0xba3bf050, 0x7efb2a98,
0xa1f1651d, 0x39af0176, 0x66ca593e, 0x82430e88,
0x8cee8619, 0x456f9fb4, 0x7d84a5c3, 0x3b8b5ebe,
0xe06f75d8, 0x85c12073, 0x401a449f, 0x56c16aa6,
0x4ed3aa62, 0x363f7706, 0x1bfedf72, 0x429b023d,
0x37d0d724, 0xd00a1248, 0xdb0fead3, 0x49f1c09b,
0x075372c9, 0x80991b7b, 0x25d479d8, 0xf6e8def7,
0xe3fe501a, 0xb6794c3b, 0x976ce0bd, 0x04c006ba,
0xc1a94fb6, 0x409f60c4, 0x5e5c9ec2, 0x196a2463,
0x68fb6faf, 0x3e6c53b5, 0x1339b2eb, 0x3b52ec6f,
0x6dfc511f, 0x9b30952c, 0xcc814544, 0xaf5ebd09,
0xbee3d004, 0xde334afd, 0x660f2807, 0x192e4bb3,
0xc0cba857, 0x45c8740f, 0xd20b5f39, 0xb9d3fbdb,
0x5579c0bd, 0x1a60320a, 0xd6a100c6, 0x402c7279,
0x679f25fe, 0xfb1fa3cc, 0x8ea5e9f8, 0xdb3222f8,
0x3c7516df, 0xfd616b15, 0x2f501ec8, 0xad0552ab,
0x323db5fa, 0xfd238760, 0x53317b48, 0x3e00df82,
0x9e5c57bb, 0xca6f8ca0, 0x1a87562e, 0xdf1769db,
0xd542a8f6, 0x287effc3, 0xac6732c6, 0x8c4f5573,
0x695b27b0, 0xbbca58c8, 0xe1ffa35d, 0xb8f011a0,
0x10fa3d98, 0xfd2183b8, 0x4afcb56c, 0x2dd1d35b,
0x9a53e479, 0xb6f84565, 0xd28e49bc, 0x4bfb9790,
0xe1ddf2da, 0xa4cb7e33, 0x62fb1341, 0xcee4c6e8,
0xef20cada, 0x36774c01, 0xd07e9efe, 0x2bf11fb4,
0x95dbda4d, 0xae909198, 0xeaad8e71, 0x6b93d5a0,
0xd08ed1d0, 0xafc725e0, 0x8e3c5b2f, 0x8e7594b7,
0x8ff6e2fb, 0xf2122b64, 0x8888b812, 0x900df01c,
0x4fad5ea0, 0x688fc31c, 0xd1cff191, 0xb3a8c1ad,
0x2f2f2218, 0xbe0e1777, 0xea752dfe, 0x8b021fa1,
0xe5a0cc0f, 0xb56f74e8, 0x18acf3d6, 0xce89e299,
0xb4a84fe0, 0xfd13e0b7, 0x7cc43b81, 0xd2ada8d9,
0x165fa266, 0x80957705, 0x93cc7314, 0x211a1477,
0xe6ad2065, 0x77b5fa86, 0xc75442f5, 0xfb9d35cf,
0xebcdaf0c, 0x7b3e89a0, 0xd6411bd3, 0xae1e7e49,
0x00250e2d, 0x2071b35e, 0x226800bb, 0x57b8e0af,
0x2464369b, 0xf009b91e, 0x5563911d, 0x59dfa6aa,
0x78c14389, 0xd95a537f, 0x207d5ba2, 0x02e5b9c5,
0x83260376, 0x6295cfa9, 0x11c81968, 0x4e734a41,
0xb3472dca, 0x7b14a94a, 0x1b510052, 0x9a532915,
0xd60f573f, 0xbc9bc6e4, 0x2b60a476, 0x81e67400,
0x08ba6fb5, 0x571be91f, 0xf296ec6b, 0x2a0dd915,
0xb6636521, 0xe7b9f9b6, 0xff34052e, 0xc5855664,
0x53b02d5d, 0xa99f8fa1, 0x08ba4799, 0x6e85076a},
{
0x4b7a70e9, 0xb5b32944, 0xdb75092e, 0xc4192623,
0xad6ea6b0, 0x49a7df7d, 0x9cee60b8, 0x8fedb266,
0xecaa8c71, 0x699a17ff, 0x5664526c, 0xc2b19ee1,
0x193602a5, 0x75094c29, 0xa0591340, 0xe4183a3e,
0x3f54989a, 0x5b429d65, 0x6b8fe4d6, 0x99f73fd6,
0xa1d29c07, 0xefe830f5, 0x4d2d38e6, 0xf0255dc1,
0x4cdd2086, 0x8470eb26, 0x6382e9c6, 0x021ecc5e,
0x09686b3f, 0x3ebaefc9, 0x3c971814, 0x6b6a70a1,
0x687f3584, 0x52a0e286, 0xb79c5305, 0xaa500737,
0x3e07841c, 0x7fdeae5c, 0x8e7d44ec, 0x5716f2b8,
0xb03ada37, 0xf0500c0d, 0xf01c1f04, 0x0200b3ff,
0xae0cf51a, 0x3cb574b2, 0x25837a58, 0xdc0921bd,
0xd19113f9, 0x7ca92ff6, 0x94324773, 0x22f54701,
0x3ae5e581, 0x37c2dadc, 0xc8b57634, 0x9af3dda7,
0xa9446146, 0x0fd0030e, 0xecc8c73e, 0xa4751e41,
0xe238cd99, 0x3bea0e2f, 0x3280bba1, 0x183eb331,
0x4e548b38, 0x4f6db908, 0x6f420d03, 0xf60a04bf,
0x2cb81290, 0x24977c79, 0x5679b072, 0xbcaf89af,
0xde9a771f, 0xd9930810, 0xb38bae12, 0xdccf3f2e,
0x5512721f, 0x2e6b7124, 0x501adde6, 0x9f84cd87,
0x7a584718, 0x7408da17, 0xbc9f9abc, 0xe94b7d8c,
0xec7aec3a, 0xdb851dfa, 0x63094366, 0xc464c3d2,
0xef1c1847, 0x3215d908, 0xdd433b37, 0x24c2ba16,
0x12a14d43, 0x2a65c451, 0x50940002, 0x133ae4dd,
0x71dff89e, 0x10314e55, 0x81ac77d6, 0x5f11199b,
0x043556f1, 0xd7a3c76b, 0x3c11183b, 0x5924a509,
0xf28fe6ed, 0x97f1fbfa, 0x9ebabf2c, 0x1e153c6e,
0x86e34570, 0xeae96fb1, 0x860e5e0a, 0x5a3e2ab3,
0x771fe71c, 0x4e3d06fa, 0x2965dcb9, 0x99e71d0f,
0x803e89d6, 0x5266c825, 0x2e4cc978, 0x9c10b36a,
0xc6150eba, 0x94e2ea78, 0xa5fc3c53, 0x1e0a2df4,
0xf2f74ea7, 0x361d2b3d, 0x1939260f, 0x19c27960,
0x5223a708, 0xf71312b6, 0xebadfe6e, 0xeac31f66,
0xe3bc4595, 0xa67bc883, 0xb17f37d1, 0x018cff28,
0xc332ddef, 0xbe6c5aa5, 0x65582185, 0x68ab9802,
0xeecea50f, 0xdb2f953b, 0x2aef7dad, 0x5b6e2f84,
0x1521b628, 0x29076170, 0xecdd4775, 0x619f1510,
0x13cca830, 0xeb61bd96, 0x0334fe1e, 0xaa0363cf,
0xb5735c90, 0x4c70a239, 0xd59e9e0b, 0xcbaade14,
0xeecc86bc, 0x60622ca7, 0x9cab5cab, 0xb2f3846e,
0x648b1eaf, 0x19bdf0ca, 0xa02369b9, 0x655abb50,
0x40685a32, 0x3c2ab4b3, 0x319ee9d5, 0xc021b8f7,
0x9b540b19, 0x875fa099, 0x95f7997e, 0x623d7da8,
0xf837889a, 0x97e32d77, 0x11ed935f, 0x16681281,
0x0e358829, 0xc7e61fd6, 0x96dedfa1, 0x7858ba99,
0x57f584a5, 0x1b227263, 0x9b83c3ff, 0x1ac24696,
0xcdb30aeb, 0x532e3054, 0x8fd948e4, 0x6dbc3128,
0x58ebf2ef, 0x34c6ffea, 0xfe28ed61, 0xee7c3c73,
0x5d4a14d9, 0xe864b7e3, 0x42105d14, 0x203e13e0,
0x45eee2b6, 0xa3aaabea, 0xdb6c4f15, 0xfacb4fd0,
0xc742f442, 0xef6abbb5, 0x654f3b1d, 0x41cd2105,
0xd81e799e, 0x86854dc7, 0xe44b476a, 0x3d816250,
0xcf62a1f2, 0x5b8d2646, 0xfc8883a0, 0xc1c7b6a3,
0x7f1524c3, 0x69cb7492, 0x47848a0b, 0x5692b285,
0x095bbf00, 0xad19489d, 0x1462b174, 0x23820e00,
0x58428d2a, 0x0c55f5ea, 0x1dadf43e, 0x233f7061,
0x3372f092, 0x8d937e41, 0xd65fecf1, 0x6c223bdb,
0x7cde3759, 0xcbee7460, 0x4085f2a7, 0xce77326e,
0xa6078084, 0x19f8509e, 0xe8efd855, 0x61d99735,
0xa969a7aa, 0xc50c06c2, 0x5a04abfc, 0x800bcadc,
0x9e447a2e, 0xc3453484, 0xfdd56705, 0x0e1e9ec9,
0xdb73dbd3, 0x105588cd, 0x675fda79, 0xe3674340,
0xc5c43465, 0x713e38d8, 0x3d28f89e, 0xf16dff20,
0x153e21e7, 0x8fb03d4a, 0xe6e39f2b, 0xdb83adf7},
{
0xe93d5a68, 0x948140f7, 0xf64c261c, 0x94692934,
0x411520f7, 0x7602d4f7, 0xbcf46b2e, 0xd4a20068,
0xd4082471, 0x3320f46a, 0x43b7d4b7, 0x500061af,
0x1e39f62e, 0x97244546, 0x14214f74, 0xbf8b8840,
0x4d95fc1d, 0x96b591af, 0x70f4ddd3, 0x66a02f45,
0xbfbc09ec, 0x03bd9785, 0x7fac6dd0, 0x31cb8504,
0x96eb27b3, 0x55fd3941, 0xda2547e6, 0xabca0a9a,
0x28507825, 0x530429f4, 0x0a2c86da, 0xe9b66dfb,
0x68dc1462, 0xd7486900, 0x680ec0a4, 0x27a18dee,
0x4f3ffea2, 0xe887ad8c, 0xb58ce006, 0x7af4d6b6,
0xaace1e7c, 0xd3375fec, 0xce78a399, 0x406b2a42,
0x20fe9e35, 0xd9f385b9, 0xee39d7ab, 0x3b124e8b,
0x1dc9faf7, 0x4b6d1856, 0x26a36631, 0xeae397b2,
0x3a6efa74, 0xdd5b4332, 0x6841e7f7, 0xca7820fb,
0xfb0af54e, 0xd8feb397, 0x454056ac, 0xba489527,
0x55533a3a, 0x20838d87, 0xfe6ba9b7, 0xd096954b,
0x55a867bc, 0xa1159a58, 0xcca92963, 0x99e1db33,
0xa62a4a56, 0x3f3125f9, 0x5ef47e1c, 0x9029317c,
0xfdf8e802, 0x04272f70, 0x80bb155c, 0x05282ce3,
0x95c11548, 0xe4c66d22, 0x48c1133f, 0xc70f86dc,
0x07f9c9ee, 0x41041f0f, 0x404779a4, 0x5d886e17,
0x325f51eb, 0xd59bc0d1, 0xf2bcc18f, 0x41113564,
0x257b7834, 0x602a9c60, 0xdff8e8a3, 0x1f636c1b,
0x0e12b4c2, 0x02e1329e, 0xaf664fd1, 0xcad18115,
0x6b2395e0, 0x333e92e1, 0x3b240b62, 0xeebeb922,
0x85b2a20e, 0xe6ba0d99, 0xde720c8c, 0x2da2f728,
0xd0127845, 0x95b794fd, 0x647d0862, 0xe7ccf5f0,
0x5449a36f, 0x877d48fa, 0xc39dfd27, 0xf33e8d1e,
0x0a476341, 0x992eff74, 0x3a6f6eab, 0xf4f8fd37,
0xa812dc60, 0xa1ebddf8, 0x991be14c, 0xdb6e6b0d,
0xc67b5510, 0x6d672c37, 0x2765d43b, 0xdcd0e804,
0xf1290dc7, 0xcc00ffa3, 0xb5390f92, 0x690fed0b,
0x667b9ffb, 0xcedb7d9c, 0xa091cf0b, 0xd9155ea3,
0xbb132f88, 0x515bad24, 0x7b9479bf, 0x763bd6eb,
0x37392eb3, 0xcc115979, 0x8026e297, 0xf42e312d,
0x6842ada7, 0xc66a2b3b, 0x12754ccc, 0x782ef11c,
0x6a124237, 0xb79251e7, 0x06a1bbe6, 0x4bfb6350,
0x1a6b1018, 0x11caedfa, 0x3d25bdd8, 0xe2e1c3c9,
0x44421659, 0x0a121386, 0xd90cec6e, 0xd5abea2a,
0x64af674e, 0xda86a85f, 0xbebfe988, 0x64e4c3fe,
0x9dbc8057, 0xf0f7c086, 0x60787bf8, 0x6003604d,
0xd1fd8346, 0xf6381fb0, 0x7745ae04, 0xd736fccc,
0x83426b33, 0xf01eab71, 0xb0804187, 0x3c005e5f,
0x77a057be, 0xbde8ae24, 0x55464299, 0xbf582e61,
0x4e58f48f, 0xf2ddfda2, 0xf474ef38, 0x8789bdc2,
0x5366f9c3, 0xc8b38e74, 0xb475f255, 0x46fcd9b9,
0x7aeb2661, 0x8b1ddf84, 0x846a0e79, 0x915f95e2,
0x466e598e, 0x20b45770, 0x8cd55591, 0xc902de4c,
0xb90bace1, 0xbb8205d0, 0x11a86248, 0x7574a99e,
0xb77f19b6, 0xe0a9dc09, 0x662d09a1, 0xc4324633,
0xe85a1f02, 0x09f0be8c, 0x4a99a025, 0x1d6efe10,
0x1ab93d1d, 0x0ba5a4df, 0xa186f20f, 0x2868f169,
0xdcb7da83, 0x573906fe, 0xa1e2ce9b, 0x4fcd7f52,
0x50115e01, 0xa70683fa, 0xa002b5c4, 0x0de6d027,
0x9af88c27, 0x773f8641, 0xc3604c06, 0x61a806b5,
0xf0177a28, 0xc0f586e0, 0x006058aa, 0x30dc7d62,
0x11e69ed7, 0x2338ea63, 0x53c2dd94, 0xc2c21634,
0xbbcbee56, 0x90bcb6de, 0xebfc7da1, 0xce591d76,
0x6f05e409, 0x4b7c0188, 0x39720a3d, 0x7c927c24,
0x86e3725f, 0x724d9db9, 0x1ac15bb4, 0xd39eb8fc,
0xed545578, 0x08fca5b5, 0xd83d7cd3, 0x4dad0fc4,
0x1e50ef5e, 0xb161e6f8, 0xa28514d9, 0x6c51133c,
0x6fd5c7e7, 0x56e14ec4, 0x362abfce, 0xddc6c837,
0xd79a3234, 0x92638212, 0x670efa8e, 0x406000e0},
{
0x3a39ce37, 0xd3faf5cf, 0xabc27737, 0x5ac52d1b,
0x5cb0679e, 0x4fa33742, 0xd3822740, 0x99bc9bbe,
0xd5118e9d, 0xbf0f7315, 0xd62d1c7e, 0xc700c47b,
0xb78c1b6b, 0x21a19045, 0xb26eb1be, 0x6a366eb4,
0x5748ab2f, 0xbc946e79, 0xc6a376d2, 0x6549c2c8,
0x530ff8ee, 0x468dde7d, 0xd5730a1d, 0x4cd04dc6,
0x2939bbdb, 0xa9ba4650, 0xac9526e8, 0xbe5ee304,
0xa1fad5f0, 0x6a2d519a, 0x63ef8ce2, 0x9a86ee22,
0xc089c2b8, 0x43242ef6, 0xa51e03aa, 0x9cf2d0a4,
0x83c061ba, 0x9be96a4d, 0x8fe51550, 0xba645bd6,
0x2826a2f9, 0xa73a3ae1, 0x4ba99586, 0xef5562e9,
0xc72fefd3, 0xf752f7da, 0x3f046f69, 0x77fa0a59,
0x80e4a915, 0x87b08601, 0x9b09e6ad, 0x3b3ee593,
0xe990fd5a, 0x9e34d797, 0x2cf0b7d9, 0x022b8b51,
0x96d5ac3a, 0x017da67d, 0xd1cf3ed6, 0x7c7d2d28,
0x1f9f25cf, 0xadf2b89b, 0x5ad6b472, 0x5a88f54c,
0xe029ac71, 0xe019a5e6, 0x47b0acfd, 0xed93fa9b,
0xe8d3c48d, 0x283b57cc, 0xf8d56629, 0x79132e28,
0x785f0191, 0xed756055, 0xf7960e44, 0xe3d35e8c,
0x15056dd4, 0x88f46dba, 0x03a16125, 0x0564f0bd,
0xc3eb9e15, 0x3c9057a2, 0x97271aec, 0xa93a072a,
0x1b3f6d9b, 0x1e6321f5, 0xf59c66fb, 0x26dcf319,
0x7533d928, 0xb155fdf5, 0x03563482, 0x8aba3cbb,
0x28517711, 0xc20ad9f8, 0xabcc5167, 0xccad925f,
0x4de81751, 0x3830dc8e, 0x379d5862, 0x9320f991,
0xea7a90c2, 0xfb3e7bce, 0x5121ce64, 0x774fbe32,
0xa8b6e37e, 0xc3293d46, 0x48de5369, 0x6413e680,
0xa2ae0810, 0xdd6db224, 0x69852dfd, 0x09072166,
0xb39a460a, 0x6445c0dd, 0x586cdecf, 0x1c20c8ae,
0x5bbef7dd, 0x1b588d40, 0xccd2017f, 0x6bb4e3bb,
0xdda26a7e, 0x3a59ff45, 0x3e350a44, 0xbcb4cdd5,
0x72eacea8, 0xfa6484bb, 0x8d6612ae, 0xbf3c6f47,
0xd29be463, 0x542f5d9e, 0xaec2771b, 0xf64e6370,
0x740e0d8d, 0xe75b1357, 0xf8721671, 0xaf537d5d,
0x4040cb08, 0x4eb4e2cc, 0x34d2466a, 0x0115af84,
0xe1b00428, 0x95983a1d, 0x06b89fb4, 0xce6ea048,
0x6f3f3b82, 0x3520ab82, 0x011a1d4b, 0x277227f8,
0x611560b1, 0xe7933fdc, 0xbb3a792b, 0x344525bd,
0xa08839e1, 0x51ce794b, 0x2f32c9b7, 0xa01fbac9,
0xe01cc87e, 0xbcc7d1f6, 0xcf0111c3, 0xa1e8aac7,
0x1a908749, 0xd44fbd9a, 0xd0dadecb, 0xd50ada38,
0x0339c32a, 0xc6913667, 0x8df9317c, 0xe0b12b4f,
0xf79e59b7, 0x43f5bb3a, 0xf2d519ff, 0x27d9459c,
0xbf97222c, 0x15e6fc2a, 0x0f91fc71, 0x9b941525,
0xfae59361, 0xceb69ceb, 0xc2a86459, 0x12baa8d1,
0xb6c1075e, 0xe3056a0c, 0x10d25065, 0xcb03a442,
0xe0ec6e0e, 0x1698db3b, 0x4c98a0be, 0x3278e964,
0x9f1f9532, 0xe0d392df, 0xd3a0342b, 0x8971f21e,
0x1b0a7441, 0x4ba3348c, 0xc5be7120, 0xc37632d8,
0xdf359f8d, 0x9b992f2e, 0xe60b6f47, 0x0fe3f11d,
0xe54cda54, 0x1edad891, 0xce6279cf, 0xcd3e7e6f,
0x1618b166, 0xfd2c1d05, 0x848fd2c5, 0xf6fb2299,
0xf523f357, 0xa6327623, 0x93a83531, 0x56cccd02,
0xacf08162, 0x5a75ebb5, 0x6e163697, 0x88d273cc,
0xde966292, 0x81b949d0, 0x4c50901b, 0x71c65614,
0xe6c6c7bd, 0x327a140a, 0x45e1d006, 0xc3f27b9a,
0xc9aa53fd, 0x62a80f00, 0xbb25bfe2, 0x35bdd2f6,
0x71126905, 0xb2040222, 0xb6cbcf7c, 0xcd769c2b,
0x53113ec0, 0x1640e3d3, 0x38abbd60, 0x2547adf0,
0xba38209c, 0xf746ce76, 0x77afa1c5, 0x20756060,
0x85cbfe4e, 0x8ae88dd8, 0x7aaaf9b0, 0x4cf9aa7e,
0x1948c25c, 0x02fb8a8c, 0x01c36ae4, 0xd6ebe1f9,
0x90d4f869, 0xa65cdea0, 0x3f09252d, 0xc208e69f,
0xb74e6132, 0xce77e25b, 0x578fdfe3, 0x3ac372e6}
},
{
0x243f6a88, 0x85a308d3, 0x13198a2e, 0x03707344,
0xa4093822, 0x299f31d0, 0x082efa98, 0xec4e6c89,
0x452821e6, 0x38d01377, 0xbe5466cf, 0x34e90c6c,
0xc0ac29b7, 0xc97c50dd, 0x3f84d5b5, 0xb5470917,
0x9216d5d9, 0x8979fb1b
} };
*c = initstate;
}
uint32_t
Blowfish_stream2word(const uint8_t *data, uint16_t databytes,
uint16_t *current)
{
uint8_t i;
uint16_t j;
uint32_t temp;
temp = 0x00000000;
j = *current;
for(i = 0; i < 4; i++, j++) {
if(j >= databytes)
j = 0;
temp = (temp << 8) | data[j];
}
*current = j;
return temp;
}
void
Blowfish_expand0state(blf_ctx *c, const uint8_t *key, uint16_t keybytes)
{
uint16_t i;
uint16_t j;
uint16_t k;
uint32_t temp;
uint32_t datal;
uint32_t datar;
j = 0;
for(i = 0; i < BLF_N + 2; i++) {
/* Extract 4 int8 to 1 int32 from keystream */
temp = Blowfish_stream2word(key, keybytes, &j);
c->P[i] = c->P[i] ^ temp;
}
j = 0;
datal = 0x00000000;
datar = 0x00000000;
for(i = 0; i < BLF_N + 2; i += 2) {
Blowfish_encipher(c, &datal, &datar);
c->P[i] = datal;
c->P[i + 1] = datar;
}
for(i = 0; i < 4; i++) {
for(k = 0; k < 256; k += 2) {
Blowfish_encipher(c, &datal, &datar);
c->S[i][k] = datal;
c->S[i][k + 1] = datar;
}
}
}
void
Blowfish_expandstate(blf_ctx *c, const uint8_t *data, uint16_t databytes,
const uint8_t *key, uint16_t keybytes)
{
uint16_t i;
uint16_t j;
uint16_t k;
uint32_t temp;
uint32_t datal;
uint32_t datar;
j = 0;
for(i = 0; i < BLF_N + 2; i++) {
/* Extract 4 int8 to 1 int32 from keystream */
temp = Blowfish_stream2word(key, keybytes, &j);
c->P[i] = c->P[i] ^ temp;
}
j = 0;
datal = 0x00000000;
datar = 0x00000000;
for(i = 0; i < BLF_N + 2; i += 2) {
datal ^= Blowfish_stream2word(data, databytes, &j);
datar ^= Blowfish_stream2word(data, databytes, &j);
Blowfish_encipher(c, &datal, &datar);
c->P[i] = datal;
c->P[i + 1] = datar;
}
for(i = 0; i < 4; i++) {
for(k = 0; k < 256; k += 2) {
datal ^= Blowfish_stream2word(data, databytes, &j);
datar ^= Blowfish_stream2word(data, databytes, &j);
Blowfish_encipher(c, &datal, &datar);
c->S[i][k] = datal;
c->S[i][k + 1] = datar;
}
}
}
void
blf_key(blf_ctx *c, const uint8_t *k, uint16_t len)
{
/* Initialize S-boxes and subkeys with Pi */
Blowfish_initstate(c);
/* Transform S-boxes and subkeys with key */
Blowfish_expand0state(c, k, len);
}
void
blf_enc(blf_ctx *c, uint32_t *data, uint16_t blocks)
{
uint32_t *d;
uint16_t i;
d = data;
for(i = 0; i < blocks; i++) {
Blowfish_encipher(c, d, d + 1);
d += 2;
}
}
void
blf_dec(blf_ctx *c, uint32_t *data, uint16_t blocks)
{
uint32_t *d;
uint16_t i;
d = data;
for(i = 0; i < blocks; i++) {
Blowfish_decipher(c, d, d + 1);
d += 2;
}
}
void
blf_ecb_encrypt(blf_ctx *c, uint8_t *data, uint32_t len)
{
uint32_t l, r;
uint32_t i;
for(i = 0; i < len; i += 8) {
l = data[0] << 24 | data[1] << 16 | data[2] << 8 | data[3];
r = data[4] << 24 | data[5] << 16 | data[6] << 8 | data[7];
Blowfish_encipher(c, &l, &r);
data[0] = l >> 24 & 0xff;
data[1] = l >> 16 & 0xff;
data[2] = l >> 8 & 0xff;
data[3] = l & 0xff;
data[4] = r >> 24 & 0xff;
data[5] = r >> 16 & 0xff;
data[6] = r >> 8 & 0xff;
data[7] = r & 0xff;
data += 8;
}
}
void
blf_ecb_decrypt(blf_ctx *c, uint8_t *data, uint32_t len)
{
uint32_t l, r;
uint32_t i;
for(i = 0; i < len; i += 8) {
l = data[0] << 24 | data[1] << 16 | data[2] << 8 | data[3];
r = data[4] << 24 | data[5] << 16 | data[6] << 8 | data[7];
Blowfish_decipher(c, &l, &r);
data[0] = l >> 24 & 0xff;
data[1] = l >> 16 & 0xff;
data[2] = l >> 8 & 0xff;
data[3] = l & 0xff;
data[4] = r >> 24 & 0xff;
data[5] = r >> 16 & 0xff;
data[6] = r >> 8 & 0xff;
data[7] = r & 0xff;
data += 8;
}
}
void
blf_cbc_encrypt(blf_ctx *c, uint8_t *iv, uint8_t *data, uint32_t len)
{
uint32_t l, r;
uint32_t i, j;
for(i = 0; i < len; i += 8) {
for(j = 0; j < 8; j++)
data[j] ^= iv[j];
l = data[0] << 24 | data[1] << 16 | data[2] << 8 | data[3];
r = data[4] << 24 | data[5] << 16 | data[6] << 8 | data[7];
Blowfish_encipher(c, &l, &r);
data[0] = l >> 24 & 0xff;
data[1] = l >> 16 & 0xff;
data[2] = l >> 8 & 0xff;
data[3] = l & 0xff;
data[4] = r >> 24 & 0xff;
data[5] = r >> 16 & 0xff;
data[6] = r >> 8 & 0xff;
data[7] = r & 0xff;
iv = data;
data += 8;
}
}
void
blf_cbc_decrypt(blf_ctx *c, uint8_t *iva, uint8_t *data, uint32_t len)
{
uint32_t l, r;
uint8_t *iv;
uint32_t i, j;
iv = data + len - 16;
data = data + len - 8;
for(i = len - 8; i >= 8; i -= 8) {
l = data[0] << 24 | data[1] << 16 | data[2] << 8 | data[3];
r = data[4] << 24 | data[5] << 16 | data[6] << 8 | data[7];
Blowfish_decipher(c, &l, &r);
data[0] = l >> 24 & 0xff;
data[1] = l >> 16 & 0xff;
data[2] = l >> 8 & 0xff;
data[3] = l & 0xff;
data[4] = r >> 24 & 0xff;
data[5] = r >> 16 & 0xff;
data[6] = r >> 8 & 0xff;
data[7] = r & 0xff;
for(j = 0; j < 8; j++)
data[j] ^= iv[j];
iv -= 8;
data -= 8;
}
l = data[0] << 24 | data[1] << 16 | data[2] << 8 | data[3];
r = data[4] << 24 | data[5] << 16 | data[6] << 8 | data[7];
Blowfish_decipher(c, &l, &r);
data[0] = l >> 24 & 0xff;
data[1] = l >> 16 & 0xff;
data[2] = l >> 8 & 0xff;
data[3] = l & 0xff;
data[4] = r >> 24 & 0xff;
data[5] = r >> 16 & 0xff;
data[6] = r >> 8 & 0xff;
data[7] = r & 0xff;
for(j = 0; j < 8; j++)
data[j] ^= iva[j];
}
#if 0
void
report(uint32_t data[], uint16_t len)
{
uint16_t i;
for(i = 0; i < len; i += 2)
printf("Block %0hd: %08lx %08lx.\n",
i / 2, data[i], data[i + 1]);
}
void
main(void)
{
blf_ctx c;
char key[] = "AAAAA";
char key2[] = "abcdefghijklmnopqrstuvwxyz";
uint32_t data[10];
uint32_t data2[] =
{0x424c4f57l, 0x46495348l};
uint16_t i;
/* First test */
for(i = 0; i < 10; i++)
data[i] = i;
blf_key(&c, (uint8_t *) key, 5);
blf_enc(&c, data, 5);
blf_dec(&c, data, 1);
blf_dec(&c, data + 2, 4);
printf("Should read as 0 - 9.\n");
report(data, 10);
/* Second test */
blf_key(&c, (uint8_t *) key2, strlen(key2));
blf_enc(&c, data2, 1);
printf("\nShould read as: 0x324ed0fe 0xf413a203.\n");
report(data2, 2);
blf_dec(&c, data2, 1);
report(data2, 2);
}
#endif
#endif /* !defined(HAVE_BCRYPT_PBKDF) && \
(!defined(HAVE_BLOWFISH_INITSTATE) || \
!defined(HAVE_BLOWFISH_EXPAND0STATE) || \
'!defined(HAVE_BLF_ENC)) */

View File

@@ -1,6 +1,6 @@
/* Copyright (c) 2004-2007 Sara Golemon <sarag@libssh2.org> /* Copyright (c) 2004-2007 Sara Golemon <sarag@libssh2.org>
* Copyright (c) 2005 Mikhail Gusarov <dottedmag@dottedmag.net> * Copyright (c) 2005 Mikhail Gusarov <dottedmag@dottedmag.net>
* Copyright (c) 2008-2014 by Daniel Stenberg * Copyright (c) 2008-2019 by Daniel Stenberg
* *
* All rights reserved. * All rights reserved.
* *
@@ -234,7 +234,8 @@ _libssh2_channel_open(LIBSSH2_SESSION * session, const char *channel_type,
if(rc == LIBSSH2_ERROR_EAGAIN) { if(rc == LIBSSH2_ERROR_EAGAIN) {
_libssh2_error(session, LIBSSH2_ERROR_EAGAIN, "Would block"); _libssh2_error(session, LIBSSH2_ERROR_EAGAIN, "Would block");
return NULL; return NULL;
} else if (rc) { }
else if(rc) {
goto channel_error; goto channel_error;
} }
@@ -279,11 +280,13 @@ _libssh2_channel_open(LIBSSH2_SESSION * session, const char *channel_type,
} }
if(session->open_data[0] == SSH_MSG_CHANNEL_OPEN_FAILURE) { if(session->open_data[0] == SSH_MSG_CHANNEL_OPEN_FAILURE) {
unsigned int reason_code = _libssh2_ntohu32(session->open_data + 5); unsigned int reason_code =
_libssh2_ntohu32(session->open_data + 5);
switch(reason_code) { switch(reason_code) {
case SSH_OPEN_ADMINISTRATIVELY_PROHIBITED: case SSH_OPEN_ADMINISTRATIVELY_PROHIBITED:
_libssh2_error(session, LIBSSH2_ERROR_CHANNEL_FAILURE, _libssh2_error(session, LIBSSH2_ERROR_CHANNEL_FAILURE,
"Channel open failure (administratively prohibited)"); "Channel open failure "
"(administratively prohibited)");
break; break;
case SSH_OPEN_CONNECT_FAILED: case SSH_OPEN_CONNECT_FAILED:
_libssh2_error(session, LIBSSH2_ERROR_CHANNEL_FAILURE, _libssh2_error(session, LIBSSH2_ERROR_CHANNEL_FAILURE,
@@ -387,14 +390,15 @@ channel_direct_tcpip(LIBSSH2_SESSION * session, const char *host,
session->direct_host_len + session->direct_shost_len + 16; session->direct_host_len + session->direct_shost_len + 16;
_libssh2_debug(session, LIBSSH2_TRACE_CONN, _libssh2_debug(session, LIBSSH2_TRACE_CONN,
"Requesting direct-tcpip session to from %s:%d to %s:%d", "Requesting direct-tcpip session from %s:%d to %s:%d",
shost, sport, host, port); shost, sport, host, port);
s = session->direct_message = s = session->direct_message =
LIBSSH2_ALLOC(session, session->direct_message_len); LIBSSH2_ALLOC(session, session->direct_message_len);
if(!session->direct_message) { if(!session->direct_message) {
_libssh2_error(session, LIBSSH2_ERROR_ALLOC, _libssh2_error(session, LIBSSH2_ERROR_ALLOC,
"Unable to allocate memory for direct-tcpip connection"); "Unable to allocate memory for "
"direct-tcpip connection");
return NULL; return NULL;
} }
_libssh2_store_str(&s, host, session->direct_host_len); _libssh2_store_str(&s, host, session->direct_host_len);
@@ -442,7 +446,8 @@ libssh2_channel_direct_tcpip_ex(LIBSSH2_SESSION *session, const char *host,
return NULL; return NULL;
BLOCK_ADJUST_ERRNO(ptr, session, BLOCK_ADJUST_ERRNO(ptr, session,
channel_direct_tcpip(session, host, port, shost, sport)); channel_direct_tcpip(session, host, port,
shost, sport));
return ptr; return ptr;
} }
@@ -531,7 +536,8 @@ channel_forward_listen(LIBSSH2_SESSION * session, const char *host,
if(rc == LIBSSH2_ERROR_EAGAIN) { if(rc == LIBSSH2_ERROR_EAGAIN) {
_libssh2_error(session, LIBSSH2_ERROR_EAGAIN, "Would block"); _libssh2_error(session, LIBSSH2_ERROR_EAGAIN, "Would block");
return NULL; return NULL;
} else if (rc || data_len < 1) { }
else if(rc || (data_len < 1)) {
_libssh2_error(session, LIBSSH2_ERROR_PROTO, "Unknown"); _libssh2_error(session, LIBSSH2_ERROR_PROTO, "Unknown");
session->fwdLstn_state = libssh2_NB_state_idle; session->fwdLstn_state = libssh2_NB_state_idle;
return NULL; return NULL;
@@ -549,7 +555,8 @@ channel_forward_listen(LIBSSH2_SESSION * session, const char *host,
LIBSSH2_ALLOC(session, session->fwdLstn_host_len + 1); LIBSSH2_ALLOC(session, session->fwdLstn_host_len + 1);
if(!listener->host) { if(!listener->host) {
_libssh2_error(session, LIBSSH2_ERROR_ALLOC, _libssh2_error(session, LIBSSH2_ERROR_ALLOC,
"Unable to allocate memory for listener queue"); "Unable to allocate memory "
"for listener queue");
LIBSSH2_FREE(session, listener); LIBSSH2_FREE(session, listener);
listener = NULL; listener = NULL;
} }
@@ -560,7 +567,8 @@ channel_forward_listen(LIBSSH2_SESSION * session, const char *host,
if(data_len >= 5 && !port) { if(data_len >= 5 && !port) {
listener->port = _libssh2_ntohu32(data + 1); listener->port = _libssh2_ntohu32(data + 1);
_libssh2_debug(session, LIBSSH2_TRACE_CONN, _libssh2_debug(session, LIBSSH2_TRACE_CONN,
"Dynamic tcpip-forward port allocated: %d", "Dynamic tcpip-forward port "
"allocated: %d",
listener->port); listener->port);
} }
else else
@@ -658,7 +666,8 @@ int _libssh2_channel_forward_cancel(LIBSSH2_LISTENER *listener)
_libssh2_store_u32(&s, listener->port); _libssh2_store_u32(&s, listener->port);
listener->chanFwdCncl_state = libssh2_NB_state_created; listener->chanFwdCncl_state = libssh2_NB_state_created;
} else { }
else {
packet = listener->chanFwdCncl_data; packet = listener->chanFwdCncl_data;
} }
@@ -840,7 +849,8 @@ static int channel_setenv(LIBSSH2_CHANNEL *channel,
_libssh2_error(session, rc, _libssh2_error(session, rc,
"Would block sending setenv request"); "Would block sending setenv request");
return rc; return rc;
} else if (rc) { }
else if(rc) {
LIBSSH2_FREE(session, channel->setenv_packet); LIBSSH2_FREE(session, channel->setenv_packet);
channel->setenv_packet = NULL; channel->setenv_packet = NULL;
channel->setenv_state = libssh2_NB_state_idle; channel->setenv_state = libssh2_NB_state_idle;
@@ -970,7 +980,8 @@ static int channel_request_pty(LIBSSH2_CHANNEL *channel,
_libssh2_error(session, rc, _libssh2_error(session, rc,
"Would block sending pty request"); "Would block sending pty request");
return rc; return rc;
} else if (rc) { }
else if(rc) {
channel->reqPTY_state = libssh2_NB_state_idle; channel->reqPTY_state = libssh2_NB_state_idle;
return _libssh2_error(session, rc, return _libssh2_error(session, rc,
"Unable to send pty-request packet"); "Unable to send pty-request packet");
@@ -989,7 +1000,8 @@ static int channel_request_pty(LIBSSH2_CHANNEL *channel,
&channel->reqPTY_packet_requirev_state); &channel->reqPTY_packet_requirev_state);
if(rc == LIBSSH2_ERROR_EAGAIN) { if(rc == LIBSSH2_ERROR_EAGAIN) {
return rc; return rc;
} else if (rc || data_len < 1) { }
else if(rc || data_len < 1) {
channel->reqPTY_state = libssh2_NB_state_idle; channel->reqPTY_state = libssh2_NB_state_idle;
return _libssh2_error(session, LIBSSH2_ERROR_PROTO, return _libssh2_error(session, LIBSSH2_ERROR_PROTO,
"Failed to require the PTY package"); "Failed to require the PTY package");
@@ -1005,7 +1017,8 @@ static int channel_request_pty(LIBSSH2_CHANNEL *channel,
} }
return _libssh2_error(session, LIBSSH2_ERROR_CHANNEL_REQUEST_DENIED, return _libssh2_error(session, LIBSSH2_ERROR_CHANNEL_REQUEST_DENIED,
"Unable to complete request for channel request-pty"); "Unable to complete request for "
"channel request-pty");
} }
/* /*
@@ -1074,7 +1087,8 @@ channel_request_pty_size(LIBSSH2_CHANNEL * channel, int width,
_libssh2_error(session, rc, _libssh2_error(session, rc,
"Would block sending window-change request"); "Would block sending window-change request");
return rc; return rc;
} else if (rc) { }
else if(rc) {
channel->reqPTY_state = libssh2_NB_state_idle; channel->reqPTY_state = libssh2_NB_state_idle;
return _libssh2_error(session, rc, return _libssh2_error(session, rc,
"Unable to send window-change packet"); "Unable to send window-change packet");
@@ -1162,7 +1176,8 @@ channel_x11_req(LIBSSH2_CHANNEL *channel, int single_connection,
_libssh2_store_u32(&s, cookie_len); _libssh2_store_u32(&s, cookie_len);
if(auth_cookie) { if(auth_cookie) {
memcpy(s, auth_cookie, cookie_len); memcpy(s, auth_cookie, cookie_len);
} else { }
else {
int i; int i;
/* note: the extra +1 below is necessary since the sprintf() /* note: the extra +1 below is necessary since the sprintf()
loop will always write 3 bytes so the last one will write loop will always write 3 bytes so the last one will write
@@ -1172,7 +1187,7 @@ channel_x11_req(LIBSSH2_CHANNEL *channel, int single_connection,
_libssh2_random(buffer, LIBSSH2_X11_RANDOM_COOKIE_LEN / 2); _libssh2_random(buffer, LIBSSH2_X11_RANDOM_COOKIE_LEN / 2);
for(i = 0; i < (LIBSSH2_X11_RANDOM_COOKIE_LEN / 2); i++) { for(i = 0; i < (LIBSSH2_X11_RANDOM_COOKIE_LEN / 2); i++) {
sprintf((char *)&s[i*2], "%02X", buffer[i]); snprintf((char *)&s[i*2], 3, "%02X", buffer[i]);
} }
} }
s += cookie_len; s += cookie_len;
@@ -1215,7 +1230,8 @@ channel_x11_req(LIBSSH2_CHANNEL *channel, int single_connection,
&channel->reqX11_packet_requirev_state); &channel->reqX11_packet_requirev_state);
if(rc == LIBSSH2_ERROR_EAGAIN) { if(rc == LIBSSH2_ERROR_EAGAIN) {
return rc; return rc;
} else if (rc || data_len < 1) { }
else if(rc || data_len < 1) {
channel->reqX11_state = libssh2_NB_state_idle; channel->reqX11_state = libssh2_NB_state_idle;
return _libssh2_error(session, rc, return _libssh2_error(session, rc,
"waiting for x11-req response packet"); "waiting for x11-req response packet");
@@ -1342,7 +1358,8 @@ _libssh2_channel_process_startup(LIBSSH2_CHANNEL *channel,
&channel->process_packet_requirev_state); &channel->process_packet_requirev_state);
if(rc == LIBSSH2_ERROR_EAGAIN) { if(rc == LIBSSH2_ERROR_EAGAIN) {
return rc; return rc;
} else if (rc || data_len < 1) { }
else if(rc || data_len < 1) {
channel->process_state = libssh2_NB_state_end; channel->process_state = libssh2_NB_state_end;
return _libssh2_error(session, rc, return _libssh2_error(session, rc,
"Failed waiting for channel success"); "Failed waiting for channel success");
@@ -1412,23 +1429,47 @@ _libssh2_channel_flush(LIBSSH2_CHANNEL *channel, int streamid)
channel->flush_flush_bytes = 0; channel->flush_flush_bytes = 0;
while(packet) { while(packet) {
unsigned char packet_type;
LIBSSH2_PACKET *next = _libssh2_list_next(&packet->node); LIBSSH2_PACKET *next = _libssh2_list_next(&packet->node);
unsigned char packet_type = packet->data[0];
if(packet->data_len < 1) {
packet = next;
_libssh2_debug(channel->session, LIBSSH2_TRACE_ERROR,
"Unexpected packet length");
continue;
}
packet_type = packet->data[0];
if(((packet_type == SSH_MSG_CHANNEL_DATA) if(((packet_type == SSH_MSG_CHANNEL_DATA)
|| (packet_type == SSH_MSG_CHANNEL_EXTENDED_DATA)) || (packet_type == SSH_MSG_CHANNEL_EXTENDED_DATA))
&& (_libssh2_ntohu32(packet->data + 1) == channel->local.id)) { && ((packet->data_len >= 5)
&& (_libssh2_ntohu32(packet->data + 1)
== channel->local.id))) {
/* It's our channel at least */ /* It's our channel at least */
long packet_stream_id = int packet_stream_id;
(packet_type == SSH_MSG_CHANNEL_DATA) ? 0 :
_libssh2_ntohu32(packet->data + 5); if(packet_type == SSH_MSG_CHANNEL_DATA) {
packet_stream_id = 0;
}
else if(packet->data_len >= 9) {
packet_stream_id = _libssh2_ntohu32(packet->data + 5);
}
else {
channel->flush_state = libssh2_NB_state_idle;
return _libssh2_error(channel->session,
LIBSSH2_ERROR_PROTO,
"Unexpected packet length");
}
if((streamid == LIBSSH2_CHANNEL_FLUSH_ALL) if((streamid == LIBSSH2_CHANNEL_FLUSH_ALL)
|| ((packet_type == SSH_MSG_CHANNEL_EXTENDED_DATA) || ((packet_type == SSH_MSG_CHANNEL_EXTENDED_DATA)
&& ((streamid == LIBSSH2_CHANNEL_FLUSH_EXTENDED_DATA) && ((streamid == LIBSSH2_CHANNEL_FLUSH_EXTENDED_DATA)
|| (streamid == packet_stream_id))) || (streamid == packet_stream_id)))
|| ((packet_type == SSH_MSG_CHANNEL_DATA) || ((packet_type == SSH_MSG_CHANNEL_DATA)
&& (streamid == 0))) { && (streamid == 0))) {
int bytes_to_flush = packet->data_len - packet->data_head; size_t bytes_to_flush = packet->data_len -
packet->data_head;
_libssh2_debug(channel->session, LIBSSH2_TRACE_CONN, _libssh2_debug(channel->session, LIBSSH2_TRACE_CONN,
"Flushing %d bytes of data from stream " "Flushing %d bytes of data from stream "
@@ -1457,9 +1498,8 @@ _libssh2_channel_flush(LIBSSH2_CHANNEL *channel, int streamid)
channel->remote.window_size -= channel->flush_flush_bytes; channel->remote.window_size -= channel->flush_flush_bytes;
if(channel->flush_refund_bytes) { if(channel->flush_refund_bytes) {
int rc; int rc =
_libssh2_channel_receive_window_adjust(channel,
rc = _libssh2_channel_receive_window_adjust(channel,
channel->flush_refund_bytes, channel->flush_refund_bytes,
1, NULL); 1, NULL);
if(rc == LIBSSH2_ERROR_EAGAIN) if(rc == LIBSSH2_ERROR_EAGAIN)
@@ -1544,7 +1584,8 @@ libssh2_channel_get_exit_signal(LIBSSH2_CHANNEL *channel,
} }
if(exitsignal_len) if(exitsignal_len)
*exitsignal_len = namelen; *exitsignal_len = namelen;
} else { }
else {
if(exitsignal) if(exitsignal)
*exitsignal = NULL; *exitsignal = NULL;
if(exitsignal_len) if(exitsignal_len)
@@ -1784,8 +1825,8 @@ ssize_t _libssh2_channel_read(LIBSSH2_CHANNEL *channel, int stream_id,
{ {
LIBSSH2_SESSION *session = channel->session; LIBSSH2_SESSION *session = channel->session;
int rc; int rc;
int bytes_read = 0; size_t bytes_read = 0;
int bytes_want; size_t bytes_want;
int unlink_packet; int unlink_packet;
LIBSSH2_PACKET *read_packet; LIBSSH2_PACKET *read_packet;
LIBSSH2_PACKET *read_next; LIBSSH2_PACKET *read_next;
@@ -1798,9 +1839,11 @@ ssize_t _libssh2_channel_read(LIBSSH2_CHANNEL *channel, int stream_id,
/* expand the receiving window first if it has become too narrow */ /* expand the receiving window first if it has become too narrow */
if((channel->read_state == libssh2_NB_state_jump1) || if((channel->read_state == libssh2_NB_state_jump1) ||
(channel->remote.window_size < channel->remote.window_size_initial / 4 * 3 + buflen) ) { (channel->remote.window_size <
channel->remote.window_size_initial / 4 * 3 + buflen) ) {
uint32_t adjustment = channel->remote.window_size_initial + buflen - channel->remote.window_size; uint32_t adjustment = channel->remote.window_size_initial + buflen -
channel->remote.window_size;
if(adjustment < LIBSSH2_CHANNEL_MINADJUST) if(adjustment < LIBSSH2_CHANNEL_MINADJUST)
adjustment = LIBSSH2_CHANNEL_MINADJUST; adjustment = LIBSSH2_CHANNEL_MINADJUST;
@@ -1825,7 +1868,7 @@ ssize_t _libssh2_channel_read(LIBSSH2_CHANNEL *channel, int stream_id,
return _libssh2_error(session, rc, "transport read"); return _libssh2_error(session, rc, "transport read");
read_packet = _libssh2_list_first(&session->packets); read_packet = _libssh2_list_first(&session->packets);
while (read_packet && (bytes_read < (int) buflen)) { while(read_packet && (bytes_read < buflen)) {
/* previously this loop condition also checked for /* previously this loop condition also checked for
!channel->remote.close but we cannot let it do this: !channel->remote.close but we cannot let it do this:
@@ -1839,6 +1882,13 @@ ssize_t _libssh2_channel_read(LIBSSH2_CHANNEL *channel, int stream_id,
/* In case packet gets destroyed during this iteration */ /* In case packet gets destroyed during this iteration */
read_next = _libssh2_list_next(&readpkt->node); read_next = _libssh2_list_next(&readpkt->node);
if(readpkt->data_len < 5) {
read_packet = read_next;
_libssh2_debug(channel->session, LIBSSH2_TRACE_ERROR,
"Unexpected packet length");
continue;
}
channel->read_local_id = channel->read_local_id =
_libssh2_ntohu32(readpkt->data + 1); _libssh2_ntohu32(readpkt->data + 1);
@@ -1852,6 +1902,7 @@ ssize_t _libssh2_channel_read(LIBSSH2_CHANNEL *channel, int stream_id,
if((stream_id if((stream_id
&& (readpkt->data[0] == SSH_MSG_CHANNEL_EXTENDED_DATA) && (readpkt->data[0] == SSH_MSG_CHANNEL_EXTENDED_DATA)
&& (channel->local.id == channel->read_local_id) && (channel->local.id == channel->read_local_id)
&& (readpkt->data_len >= 9)
&& (stream_id == (int) _libssh2_ntohu32(readpkt->data + 5))) && (stream_id == (int) _libssh2_ntohu32(readpkt->data + 5)))
|| (!stream_id && (readpkt->data[0] == SSH_MSG_CHANNEL_DATA) || (!stream_id && (readpkt->data[0] == SSH_MSG_CHANNEL_DATA)
&& (channel->local.id == channel->read_local_id)) && (channel->local.id == channel->read_local_id))
@@ -1865,7 +1916,7 @@ ssize_t _libssh2_channel_read(LIBSSH2_CHANNEL *channel, int stream_id,
bytes_want = buflen - bytes_read; bytes_want = buflen - bytes_read;
unlink_packet = FALSE; unlink_packet = FALSE;
if (bytes_want >= (int) (readpkt->data_len - readpkt->data_head)) { if(bytes_want >= (readpkt->data_len - readpkt->data_head)) {
/* we want more than this node keeps, so adjust the number and /* we want more than this node keeps, so adjust the number and
delete this node after the copy */ delete this node after the copy */
bytes_want = readpkt->data_len - readpkt->data_head; bytes_want = readpkt->data_len - readpkt->data_head;
@@ -1968,6 +2019,7 @@ _libssh2_channel_packet_data_len(LIBSSH2_CHANNEL * channel, int stream_id)
{ {
LIBSSH2_SESSION *session = channel->session; LIBSSH2_SESSION *session = channel->session;
LIBSSH2_PACKET *read_packet; LIBSSH2_PACKET *read_packet;
LIBSSH2_PACKET *next_packet;
uint32_t read_local_id; uint32_t read_local_id;
read_packet = _libssh2_list_first(&session->packets); read_packet = _libssh2_list_first(&session->packets);
@@ -1975,6 +2027,16 @@ _libssh2_channel_packet_data_len(LIBSSH2_CHANNEL * channel, int stream_id)
return 0; return 0;
while(read_packet) { while(read_packet) {
next_packet = _libssh2_list_next(&read_packet->node);
if(read_packet->data_len < 5) {
read_packet = next_packet;
_libssh2_debug(channel->session, LIBSSH2_TRACE_ERROR,
"Unexpected packet length");
continue;
}
read_local_id = _libssh2_ntohu32(read_packet->data + 1); read_local_id = _libssh2_ntohu32(read_packet->data + 1);
/* /*
@@ -1987,6 +2049,7 @@ _libssh2_channel_packet_data_len(LIBSSH2_CHANNEL * channel, int stream_id)
if((stream_id if((stream_id
&& (read_packet->data[0] == SSH_MSG_CHANNEL_EXTENDED_DATA) && (read_packet->data[0] == SSH_MSG_CHANNEL_EXTENDED_DATA)
&& (channel->local.id == read_local_id) && (channel->local.id == read_local_id)
&& (read_packet->data_len >= 9)
&& (stream_id == (int) _libssh2_ntohu32(read_packet->data + 5))) && (stream_id == (int) _libssh2_ntohu32(read_packet->data + 5)))
|| ||
(!stream_id (!stream_id
@@ -1997,11 +2060,11 @@ _libssh2_channel_packet_data_len(LIBSSH2_CHANNEL * channel, int stream_id)
&& (read_packet->data[0] == SSH_MSG_CHANNEL_EXTENDED_DATA) && (read_packet->data[0] == SSH_MSG_CHANNEL_EXTENDED_DATA)
&& (channel->local.id == read_local_id) && (channel->local.id == read_local_id)
&& (channel->remote.extended_data_ignore_mode && (channel->remote.extended_data_ignore_mode
== LIBSSH2_CHANNEL_EXTENDED_DATA_MERGE))) == LIBSSH2_CHANNEL_EXTENDED_DATA_MERGE))) {
{
return (read_packet->data_len - read_packet->data_head); return (read_packet->data_len - read_packet->data_head);
} }
read_packet = _libssh2_list_next(&read_packet->node);
read_packet = next_packet;
} }
return 0; return 0;
@@ -2182,7 +2245,8 @@ static int channel_send_eof(LIBSSH2_CHANNEL *channel)
unsigned char packet[5]; /* packet_type(1) + channelno(4) */ unsigned char packet[5]; /* packet_type(1) + channelno(4) */
int rc; int rc;
_libssh2_debug(session, LIBSSH2_TRACE_CONN, "Sending EOF on channel %lu/%lu", _libssh2_debug(session, LIBSSH2_TRACE_CONN,
"Sending EOF on channel %lu/%lu",
channel->local.id, channel->remote.id); channel->local.id, channel->remote.id);
packet[0] = SSH_MSG_CHANNEL_EOF; packet[0] = SSH_MSG_CHANNEL_EOF;
_libssh2_htonu32(packet + 1, channel->remote.id); _libssh2_htonu32(packet + 1, channel->remote.id);
@@ -2228,6 +2292,7 @@ libssh2_channel_eof(LIBSSH2_CHANNEL * channel)
{ {
LIBSSH2_SESSION *session; LIBSSH2_SESSION *session;
LIBSSH2_PACKET *packet; LIBSSH2_PACKET *packet;
LIBSSH2_PACKET *next_packet;
if(!channel) if(!channel)
return LIBSSH2_ERROR_BAD_USE; return LIBSSH2_ERROR_BAD_USE;
@@ -2236,13 +2301,24 @@ libssh2_channel_eof(LIBSSH2_CHANNEL * channel)
packet = _libssh2_list_first(&session->packets); packet = _libssh2_list_first(&session->packets);
while(packet) { while(packet) {
next_packet = _libssh2_list_next(&packet->node);
if(packet->data_len < 1) {
packet = next_packet;
_libssh2_debug(channel->session, LIBSSH2_TRACE_ERROR,
"Unexpected packet length");
continue;
}
if(((packet->data[0] == SSH_MSG_CHANNEL_DATA) if(((packet->data[0] == SSH_MSG_CHANNEL_DATA)
|| (packet->data[0] == SSH_MSG_CHANNEL_EXTENDED_DATA)) || (packet->data[0] == SSH_MSG_CHANNEL_EXTENDED_DATA))
&& (channel->local.id == _libssh2_ntohu32(packet->data + 1))) { && ((packet->data_len >= 5)
&& (channel->local.id == _libssh2_ntohu32(packet->data + 1)))) {
/* There's data waiting to be read yet, mask the EOF status */ /* There's data waiting to be read yet, mask the EOF status */
return 0; return 0;
} }
packet = _libssh2_list_next(&packet->node); packet = next_packet;
} }
return channel->remote.eof; return channel->remote.eof;
@@ -2260,7 +2336,7 @@ static int channel_wait_eof(LIBSSH2_CHANNEL *channel)
if(channel->wait_eof_state == libssh2_NB_state_idle) { if(channel->wait_eof_state == libssh2_NB_state_idle) {
_libssh2_debug(session, LIBSSH2_TRACE_CONN, _libssh2_debug(session, LIBSSH2_TRACE_CONN,
"Awaiting close of channel %lu/%lu", channel->local.id, "Awaiting EOF for channel %lu/%lu", channel->local.id,
channel->remote.id); channel->remote.id);
channel->wait_eof_state = libssh2_NB_state_created; channel->wait_eof_state = libssh2_NB_state_created;
@@ -2274,6 +2350,13 @@ static int channel_wait_eof(LIBSSH2_CHANNEL *channel)
if(channel->remote.eof) { if(channel->remote.eof) {
break; break;
} }
if((channel->remote.window_size == channel->read_avail) &&
session->api_block_mode)
return _libssh2_error(session, LIBSSH2_ERROR_CHANNEL_WINDOW_FULL,
"Receiving channel window "
"has been exhausted");
rc = _libssh2_transport_read(session); rc = _libssh2_transport_read(session);
if(rc == LIBSSH2_ERROR_EAGAIN) { if(rc == LIBSSH2_ERROR_EAGAIN) {
return rc; return rc;
@@ -2320,7 +2403,8 @@ int _libssh2_channel_close(LIBSSH2_CHANNEL * channel)
} }
if(!channel->local.eof) { if(!channel->local.eof) {
if ((rc = channel_send_eof(channel))) { rc = channel_send_eof(channel);
if(rc) {
if(rc == LIBSSH2_ERROR_EAGAIN) { if(rc == LIBSSH2_ERROR_EAGAIN) {
return rc; return rc;
} }
@@ -2350,14 +2434,16 @@ int _libssh2_channel_close(LIBSSH2_CHANNEL * channel)
"Would block sending close-channel"); "Would block sending close-channel");
return rc; return rc;
} else if (rc) { }
else if(rc) {
_libssh2_error(session, rc, _libssh2_error(session, rc,
"Unable to send close-channel request, " "Unable to send close-channel request, "
"but closing anyway"); "but closing anyway");
/* skip waiting for the response and fall through to /* skip waiting for the response and fall through to
LIBSSH2_CHANNEL_CLOSE below */ LIBSSH2_CHANNEL_CLOSE below */
} else }
else
channel->close_state = libssh2_NB_state_sent; channel->close_state = libssh2_NB_state_sent;
} }
@@ -2370,8 +2456,8 @@ int _libssh2_channel_close(LIBSSH2_CHANNEL * channel)
} }
if(rc != LIBSSH2_ERROR_EAGAIN) { if(rc != LIBSSH2_ERROR_EAGAIN) {
/* set the local close state first when we're perfectly confirmed to not /* set the local close state first when we're perfectly confirmed to
do any more EAGAINs */ not do any more EAGAINs */
channel->local.close = 1; channel->local.close = 1;
/* We call the callback last in this function to make it keep the local /* We call the callback last in this function to make it keep the local
@@ -2414,7 +2500,7 @@ static int channel_wait_closed(LIBSSH2_CHANNEL *channel)
LIBSSH2_SESSION *session = channel->session; LIBSSH2_SESSION *session = channel->session;
int rc; int rc;
if (!libssh2_channel_eof(channel)) { if(!channel->remote.eof) {
return _libssh2_error(session, LIBSSH2_ERROR_INVAL, return _libssh2_error(session, LIBSSH2_ERROR_INVAL,
"libssh2_channel_wait_closed() invoked when " "libssh2_channel_wait_closed() invoked when "
"channel is not in EOF state"); "channel is not in EOF state");
@@ -2593,19 +2679,32 @@ libssh2_channel_window_read_ex(LIBSSH2_CHANNEL *channel,
if(read_avail) { if(read_avail) {
size_t bytes_queued = 0; size_t bytes_queued = 0;
LIBSSH2_PACKET *next_packet;
LIBSSH2_PACKET *packet = LIBSSH2_PACKET *packet =
_libssh2_list_first(&channel->session->packets); _libssh2_list_first(&channel->session->packets);
while(packet) { while(packet) {
unsigned char packet_type = packet->data[0]; unsigned char packet_type;
next_packet = _libssh2_list_next(&packet->node);
if(packet->data_len < 1) {
packet = next_packet;
_libssh2_debug(channel->session, LIBSSH2_TRACE_ERROR,
"Unexpected packet length");
continue;
}
packet_type = packet->data[0];
if(((packet_type == SSH_MSG_CHANNEL_DATA) if(((packet_type == SSH_MSG_CHANNEL_DATA)
|| (packet_type == SSH_MSG_CHANNEL_EXTENDED_DATA)) || (packet_type == SSH_MSG_CHANNEL_EXTENDED_DATA))
&& (_libssh2_ntohu32(packet->data + 1) == channel->local.id)) { && ((packet->data_len >= 5)
&& (_libssh2_ntohu32(packet->data + 1) ==
channel->local.id))) {
bytes_queued += packet->data_len - packet->data_head; bytes_queued += packet->data_len - packet->data_head;
} }
packet = _libssh2_list_next(&packet->node); packet = next_packet;
} }
*read_avail = bytes_queued; *read_avail = bytes_queued;

View File

@@ -1,4 +1,4 @@
/* Copyright (c) 2004-2007, Sara Golemon <sarag@libssh2.org> /* Copyright (c) 2004-2007, 2019, Sara Golemon <sarag@libssh2.org>
* Copyright (c) 2010-2014, Daniel Stenberg <daniel@haxx.se> * Copyright (c) 2010-2014, Daniel Stenberg <daniel@haxx.se>
* All rights reserved. * All rights reserved.
* *
@@ -154,7 +154,8 @@ comp_method_zlib_init(LIBSSH2_SESSION * session, int compr,
if(compr) { if(compr) {
/* deflate */ /* deflate */
status = deflateInit(strm, Z_DEFAULT_COMPRESSION); status = deflateInit(strm, Z_DEFAULT_COMPRESSION);
} else { }
else {
/* inflate */ /* inflate */
status = inflateInit(strm); status = inflateInit(strm);
} }
@@ -203,7 +204,8 @@ comp_method_zlib_comp(LIBSSH2_SESSION *session,
} }
_libssh2_debug(session, LIBSSH2_TRACE_TRANS, _libssh2_debug(session, LIBSSH2_TRACE_TRANS,
"unhandled zlib compression error %d, avail_out", status, strm->avail_out); "unhandled zlib compression error %d, avail_out",
status, strm->avail_out);
return _libssh2_error(session, LIBSSH2_ERROR_ZLIB, "compression failure"); return _libssh2_error(session, LIBSSH2_ERROR_ZLIB, "compression failure");
} }
@@ -240,7 +242,7 @@ comp_method_zlib_decomp(LIBSSH2_SESSION * session,
if(out_maxlen < 25) if(out_maxlen < 25)
out_maxlen = 25; out_maxlen = 25;
if (out_maxlen > (int) payload_limit) if(out_maxlen > payload_limit)
out_maxlen = payload_limit; out_maxlen = payload_limit;
strm->next_in = (unsigned char *) src; strm->next_in = (unsigned char *) src;
@@ -262,12 +264,15 @@ comp_method_zlib_decomp(LIBSSH2_SESSION * session,
if(status == Z_OK) { if(status == Z_OK) {
if(strm->avail_out > 0) if(strm->avail_out > 0)
/* status is OK and the output buffer has not been exhausted so we're done */ /* status is OK and the output buffer has not been exhausted
so we're done */
break; break;
} else if (status == Z_BUF_ERROR) { }
else if(status == Z_BUF_ERROR) {
/* the input data has been exhausted so we are done */ /* the input data has been exhausted so we are done */
break; break;
} else { }
else {
/* error state */ /* error state */
LIBSSH2_FREE(session, out); LIBSSH2_FREE(session, out);
_libssh2_debug(session, LIBSSH2_TRACE_TRANS, _libssh2_debug(session, LIBSSH2_TRACE_TRANS,
@@ -276,7 +281,7 @@ comp_method_zlib_decomp(LIBSSH2_SESSION * session,
"decompression failure"); "decompression failure");
} }
if (out_maxlen > (int) payload_limit || out_maxlen > SIZE_MAX / 2) { if(out_maxlen > payload_limit || out_maxlen > SIZE_MAX / 2) {
LIBSSH2_FREE(session, out); LIBSSH2_FREE(session, out);
return _libssh2_error(session, LIBSSH2_ERROR_ZLIB, return _libssh2_error(session, LIBSSH2_ERROR_ZLIB,
"Excessive growth in decompression phase"); "Excessive growth in decompression phase");

View File

@@ -53,6 +53,7 @@ crypt_none_crypt(LIBSSH2_SESSION * session, unsigned char *buf,
static const LIBSSH2_CRYPT_METHOD libssh2_crypt_method_none = { static const LIBSSH2_CRYPT_METHOD libssh2_crypt_method_none = {
"none", "none",
"DEK-Info: NONE",
8, /* blocksize (SSH2 defines minimum blocksize as 8) */ 8, /* blocksize (SSH2 defines minimum blocksize as 8) */
0, /* iv_len */ 0, /* iv_len */
0, /* secret_len */ 0, /* secret_len */
@@ -119,6 +120,7 @@ crypt_dtor(LIBSSH2_SESSION * session, void **abstract)
#if LIBSSH2_AES_CTR #if LIBSSH2_AES_CTR
static const LIBSSH2_CRYPT_METHOD libssh2_crypt_method_aes128_ctr = { static const LIBSSH2_CRYPT_METHOD libssh2_crypt_method_aes128_ctr = {
"aes128-ctr", "aes128-ctr",
"",
16, /* blocksize */ 16, /* blocksize */
16, /* initial value length */ 16, /* initial value length */
16, /* secret length -- 16*8 == 128bit */ 16, /* secret length -- 16*8 == 128bit */
@@ -131,6 +133,7 @@ static const LIBSSH2_CRYPT_METHOD libssh2_crypt_method_aes128_ctr = {
static const LIBSSH2_CRYPT_METHOD libssh2_crypt_method_aes192_ctr = { static const LIBSSH2_CRYPT_METHOD libssh2_crypt_method_aes192_ctr = {
"aes192-ctr", "aes192-ctr",
"",
16, /* blocksize */ 16, /* blocksize */
16, /* initial value length */ 16, /* initial value length */
24, /* secret length -- 24*8 == 192bit */ 24, /* secret length -- 24*8 == 192bit */
@@ -143,6 +146,7 @@ static const LIBSSH2_CRYPT_METHOD libssh2_crypt_method_aes192_ctr = {
static const LIBSSH2_CRYPT_METHOD libssh2_crypt_method_aes256_ctr = { static const LIBSSH2_CRYPT_METHOD libssh2_crypt_method_aes256_ctr = {
"aes256-ctr", "aes256-ctr",
"",
16, /* blocksize */ 16, /* blocksize */
16, /* initial value length */ 16, /* initial value length */
32, /* secret length -- 32*8 == 256bit */ 32, /* secret length -- 32*8 == 256bit */
@@ -157,6 +161,7 @@ static const LIBSSH2_CRYPT_METHOD libssh2_crypt_method_aes256_ctr = {
#if LIBSSH2_AES #if LIBSSH2_AES
static const LIBSSH2_CRYPT_METHOD libssh2_crypt_method_aes128_cbc = { static const LIBSSH2_CRYPT_METHOD libssh2_crypt_method_aes128_cbc = {
"aes128-cbc", "aes128-cbc",
"DEK-Info: AES-128-CBC",
16, /* blocksize */ 16, /* blocksize */
16, /* initial value length */ 16, /* initial value length */
16, /* secret length -- 16*8 == 128bit */ 16, /* secret length -- 16*8 == 128bit */
@@ -169,6 +174,7 @@ static const LIBSSH2_CRYPT_METHOD libssh2_crypt_method_aes128_cbc = {
static const LIBSSH2_CRYPT_METHOD libssh2_crypt_method_aes192_cbc = { static const LIBSSH2_CRYPT_METHOD libssh2_crypt_method_aes192_cbc = {
"aes192-cbc", "aes192-cbc",
"DEK-Info: AES-192-CBC",
16, /* blocksize */ 16, /* blocksize */
16, /* initial value length */ 16, /* initial value length */
24, /* secret length -- 24*8 == 192bit */ 24, /* secret length -- 24*8 == 192bit */
@@ -181,6 +187,7 @@ static const LIBSSH2_CRYPT_METHOD libssh2_crypt_method_aes192_cbc = {
static const LIBSSH2_CRYPT_METHOD libssh2_crypt_method_aes256_cbc = { static const LIBSSH2_CRYPT_METHOD libssh2_crypt_method_aes256_cbc = {
"aes256-cbc", "aes256-cbc",
"DEK-Info: AES-256-CBC",
16, /* blocksize */ 16, /* blocksize */
16, /* initial value length */ 16, /* initial value length */
32, /* secret length -- 32*8 == 256bit */ 32, /* secret length -- 32*8 == 256bit */
@@ -195,6 +202,7 @@ static const LIBSSH2_CRYPT_METHOD libssh2_crypt_method_aes256_cbc = {
static const LIBSSH2_CRYPT_METHOD static const LIBSSH2_CRYPT_METHOD
libssh2_crypt_method_rijndael_cbc_lysator_liu_se = { libssh2_crypt_method_rijndael_cbc_lysator_liu_se = {
"rijndael-cbc@lysator.liu.se", "rijndael-cbc@lysator.liu.se",
"DEK-Info: AES-256-CBC",
16, /* blocksize */ 16, /* blocksize */
16, /* initial value length */ 16, /* initial value length */
32, /* secret length -- 32*8 == 256bit */ 32, /* secret length -- 32*8 == 256bit */
@@ -209,6 +217,7 @@ static const LIBSSH2_CRYPT_METHOD
#if LIBSSH2_BLOWFISH #if LIBSSH2_BLOWFISH
static const LIBSSH2_CRYPT_METHOD libssh2_crypt_method_blowfish_cbc = { static const LIBSSH2_CRYPT_METHOD libssh2_crypt_method_blowfish_cbc = {
"blowfish-cbc", "blowfish-cbc",
"",
8, /* blocksize */ 8, /* blocksize */
8, /* initial value length */ 8, /* initial value length */
16, /* secret length */ 16, /* secret length */
@@ -223,6 +232,7 @@ static const LIBSSH2_CRYPT_METHOD libssh2_crypt_method_blowfish_cbc = {
#if LIBSSH2_RC4 #if LIBSSH2_RC4
static const LIBSSH2_CRYPT_METHOD libssh2_crypt_method_arcfour = { static const LIBSSH2_CRYPT_METHOD libssh2_crypt_method_arcfour = {
"arcfour", "arcfour",
"DEK-Info: RC4",
8, /* blocksize */ 8, /* blocksize */
8, /* initial value length */ 8, /* initial value length */
16, /* secret length */ 16, /* secret length */
@@ -258,6 +268,7 @@ crypt_init_arcfour128(LIBSSH2_SESSION * session,
static const LIBSSH2_CRYPT_METHOD libssh2_crypt_method_arcfour128 = { static const LIBSSH2_CRYPT_METHOD libssh2_crypt_method_arcfour128 = {
"arcfour128", "arcfour128",
"",
8, /* blocksize */ 8, /* blocksize */
8, /* initial value length */ 8, /* initial value length */
16, /* secret length */ 16, /* secret length */
@@ -272,6 +283,7 @@ static const LIBSSH2_CRYPT_METHOD libssh2_crypt_method_arcfour128 = {
#if LIBSSH2_CAST #if LIBSSH2_CAST
static const LIBSSH2_CRYPT_METHOD libssh2_crypt_method_cast128_cbc = { static const LIBSSH2_CRYPT_METHOD libssh2_crypt_method_cast128_cbc = {
"cast128-cbc", "cast128-cbc",
"",
8, /* blocksize */ 8, /* blocksize */
8, /* initial value length */ 8, /* initial value length */
16, /* secret length */ 16, /* secret length */
@@ -286,6 +298,7 @@ static const LIBSSH2_CRYPT_METHOD libssh2_crypt_method_cast128_cbc = {
#if LIBSSH2_3DES #if LIBSSH2_3DES
static const LIBSSH2_CRYPT_METHOD libssh2_crypt_method_3des_cbc = { static const LIBSSH2_CRYPT_METHOD libssh2_crypt_method_3des_cbc = {
"3des-cbc", "3des-cbc",
"DEK-Info: DES-EDE3-CBC",
8, /* blocksize */ 8, /* blocksize */
8, /* initial value length */ 8, /* initial value length */
24, /* secret length */ 24, /* secret length */

View File

@@ -1,6 +1,6 @@
/* Copyright (C) 2009, 2010 Simon Josefsson /* Copyright (C) 2009, 2010 Simon Josefsson
* Copyright (C) 2006, 2007 The Written Word, Inc. All rights reserved. * Copyright (C) 2006, 2007 The Written Word, Inc. All rights reserved.
* Copyright (C) 2010 Daniel Stenberg * Copyright (C) 2010-2019 Daniel Stenberg
* *
* Redistribution and use in source and binary forms, * Redistribution and use in source and binary forms,
* with or without modification, are permitted provided * with or without modification, are permitted provided
@@ -58,6 +58,11 @@
#include "mbedtls.h" #include "mbedtls.h"
#endif #endif
#define LIBSSH2_ED25519_KEY_LEN 32
#define LIBSSH2_ED25519_PRIVATE_KEY_LEN 64
#define LIBSSH2_ED25519_SIG_LEN 64
#if LIBSSH2_RSA
int _libssh2_rsa_new(libssh2_rsa_ctx ** rsa, int _libssh2_rsa_new(libssh2_rsa_ctx ** rsa,
const unsigned char *edata, const unsigned char *edata,
unsigned long elen, unsigned long elen,
@@ -90,8 +95,10 @@ int _libssh2_rsa_sha1_sign(LIBSSH2_SESSION * session,
size_t *signature_len); size_t *signature_len);
int _libssh2_rsa_new_private_frommemory(libssh2_rsa_ctx ** rsa, int _libssh2_rsa_new_private_frommemory(libssh2_rsa_ctx ** rsa,
LIBSSH2_SESSION * session, LIBSSH2_SESSION * session,
const char *filedata, size_t filedata_len, const char *filedata,
size_t filedata_len,
unsigned const char *passphrase); unsigned const char *passphrase);
#endif
#if LIBSSH2_DSA #if LIBSSH2_DSA
int _libssh2_dsa_new(libssh2_dsa_ctx ** dsa, int _libssh2_dsa_new(libssh2_dsa_ctx ** dsa,
@@ -116,10 +123,102 @@ int _libssh2_dsa_sha1_sign(libssh2_dsa_ctx * dsactx,
unsigned long hash_len, unsigned char *sig); unsigned long hash_len, unsigned char *sig);
int _libssh2_dsa_new_private_frommemory(libssh2_dsa_ctx ** dsa, int _libssh2_dsa_new_private_frommemory(libssh2_dsa_ctx ** dsa,
LIBSSH2_SESSION * session, LIBSSH2_SESSION * session,
const char *filedata, size_t filedata_len, const char *filedata,
size_t filedata_len,
unsigned const char *passphrase); unsigned const char *passphrase);
#endif #endif
#if LIBSSH2_ECDSA
int
_libssh2_ecdsa_curve_name_with_octal_new(libssh2_ecdsa_ctx ** ecdsactx,
const unsigned char *k,
size_t k_len,
libssh2_curve_type type);
int
_libssh2_ecdsa_new_private(libssh2_ecdsa_ctx ** ec_ctx,
LIBSSH2_SESSION * session,
const char *filename,
unsigned const char *passphrase);
int
_libssh2_ecdsa_verify(libssh2_ecdsa_ctx * ctx,
const unsigned char *r, size_t r_len,
const unsigned char *s, size_t s_len,
const unsigned char *m, size_t m_len);
int
_libssh2_ecdsa_create_key(LIBSSH2_SESSION *session,
_libssh2_ec_key **out_private_key,
unsigned char **out_public_key_octal,
size_t *out_public_key_octal_len,
libssh2_curve_type curve_type);
int
_libssh2_ecdh_gen_k(_libssh2_bn **k, _libssh2_ec_key *private_key,
const unsigned char *server_public_key,
size_t server_public_key_len);
int
_libssh2_ecdsa_sign(LIBSSH2_SESSION *session, libssh2_ecdsa_ctx *ec_ctx,
const unsigned char *hash, unsigned long hash_len,
unsigned char **signature, size_t *signature_len);
int _libssh2_ecdsa_new_private_frommemory(libssh2_ecdsa_ctx ** ec_ctx,
LIBSSH2_SESSION * session,
const char *filedata,
size_t filedata_len,
unsigned const char *passphrase);
libssh2_curve_type
_libssh2_ecdsa_key_get_curve_type(_libssh2_ec_key *key);
int
_libssh2_ecdsa_curve_type_from_name(const char *name,
libssh2_curve_type *out_type);
#endif /* LIBSSH2_ECDSA */
#if LIBSSH2_ED25519
int
_libssh2_curve25519_new(LIBSSH2_SESSION *session, libssh2_ed25519_ctx **ctx,
uint8_t **out_public_key, uint8_t **out_private_key);
int
_libssh2_curve25519_gen_k(_libssh2_bn **k,
uint8_t private_key[LIBSSH2_ED25519_KEY_LEN],
uint8_t server_public_key[LIBSSH2_ED25519_KEY_LEN]);
int
_libssh2_ed25519_verify(libssh2_ed25519_ctx *ctx, const uint8_t *s,
size_t s_len, const uint8_t *m, size_t m_len);
int
_libssh2_ed25519_new_private(libssh2_ed25519_ctx **ed_ctx,
LIBSSH2_SESSION *session,
const char *filename, const uint8_t *passphrase);
int
_libssh2_ed25519_new_public(libssh2_ed25519_ctx **ed_ctx,
LIBSSH2_SESSION *session,
const unsigned char *raw_pub_key,
const uint8_t key_len);
int
_libssh2_ed25519_sign(libssh2_ed25519_ctx *ctx, LIBSSH2_SESSION *session,
uint8_t **out_sig, size_t *out_sig_len,
const uint8_t *message, size_t message_len);
int
_libssh2_ed25519_new_private_frommemory(libssh2_ed25519_ctx **ed_ctx,
LIBSSH2_SESSION *session,
const char *filedata,
size_t filedata_len,
unsigned const char *passphrase);
#endif /* LIBSSH2_ED25519 */
int _libssh2_cipher_init(_libssh2_cipher_ctx * h, int _libssh2_cipher_init(_libssh2_cipher_ctx * h,
_libssh2_cipher_type(algo), _libssh2_cipher_type(algo),
unsigned char *iv, unsigned char *iv,
@@ -136,6 +235,7 @@ int _libssh2_pub_priv_keyfile(LIBSSH2_SESSION *session,
size_t *pubkeydata_len, size_t *pubkeydata_len,
const char *privatekey, const char *privatekey,
const char *passphrase); const char *passphrase);
int _libssh2_pub_priv_keyfilememory(LIBSSH2_SESSION *session, int _libssh2_pub_priv_keyfilememory(LIBSSH2_SESSION *session,
unsigned char **method, unsigned char **method,
size_t *method_len, size_t *method_len,
@@ -145,6 +245,4 @@ int _libssh2_pub_priv_keyfilememory(LIBSSH2_SESSION *session,
size_t privatekeydata_len, size_t privatekeydata_len,
const char *passphrase); const char *passphrase);
void _libssh2_init_aes_ctr(void);
#endif #endif

View File

@@ -46,7 +46,6 @@ libssh2_init(int flags)
{ {
if(_libssh2_initialized == 0 && !(flags & LIBSSH2_INIT_NO_CRYPTO)) { if(_libssh2_initialized == 0 && !(flags & LIBSSH2_INIT_NO_CRYPTO)) {
libssh2_crypto_init(); libssh2_crypto_init();
_libssh2_init_aes_ctr();
} }
_libssh2_initialized++; _libssh2_initialized++;

View File

@@ -1,5 +1,5 @@
/* Copyright (c) 2004-2006, Sara Golemon <sarag@libssh2.org> /* Copyright (c) 2004-2006, Sara Golemon <sarag@libssh2.org>
* Copyright (c) 2009-2014 by Daniel Stenberg * Copyright (c) 2009-2019 by Daniel Stenberg
* All rights reserved. * All rights reserved.
* *
* Redistribution and use in source and binary forms, * Redistribution and use in source and binary forms,
@@ -64,38 +64,36 @@ hostkey_method_ssh_rsa_init(LIBSSH2_SESSION * session,
void **abstract) void **abstract)
{ {
libssh2_rsa_ctx *rsactx; libssh2_rsa_ctx *rsactx;
const unsigned char *s, *e, *n; unsigned char *e, *n;
unsigned long len, e_len, n_len; size_t e_len, n_len;
int ret; struct string_buf buf;
(void) hostkey_data_len;
if(*abstract) { if(*abstract) {
hostkey_method_ssh_rsa_dtor(session, abstract); hostkey_method_ssh_rsa_dtor(session, abstract);
*abstract = NULL; *abstract = NULL;
} }
s = hostkey_data; if(hostkey_data_len < 19) {
len = _libssh2_ntohu32(s); _libssh2_debug(session, LIBSSH2_TRACE_ERROR,
s += 4; "host key length too short");
if (len != 7 || strncmp((char *) s, "ssh-rsa", 7) != 0) {
return -1; return -1;
} }
s += 7;
e_len = _libssh2_ntohu32(s); buf.data = (unsigned char *)hostkey_data;
s += 4; buf.dataptr = buf.data;
buf.len = hostkey_data_len;
e = s; if(_libssh2_match_string(&buf, "ssh-rsa"))
s += e_len; return -1;
n_len = _libssh2_ntohu32(s);
s += 4;
n = s;
ret = _libssh2_rsa_new(&rsactx, e, e_len, n, n_len, NULL, 0, if(_libssh2_get_string(&buf, &e, &e_len))
NULL, 0, NULL, 0, NULL, 0, NULL, 0, NULL, 0); return -1;
if (ret) {
if(_libssh2_get_string(&buf, &n, &n_len))
return -1;
if(_libssh2_rsa_new(&rsactx, e, e_len, n, n_len, NULL, 0,
NULL, 0, NULL, 0, NULL, 0, NULL, 0, NULL, 0)) {
return -1; return -1;
} }
@@ -181,6 +179,9 @@ hostkey_method_ssh_rsa_sig_verify(LIBSSH2_SESSION * session,
(void) session; (void) session;
/* Skip past keyname_len(4) + keyname(7){"ssh-rsa"} + signature_len(4) */ /* Skip past keyname_len(4) + keyname(7){"ssh-rsa"} + signature_len(4) */
if(sig_len < 15)
return -1;
sig += 15; sig += 15;
sig_len -= 15; sig_len -= 15;
return _libssh2_rsa_sha1_verify(rsactx, sig, sig_len, m, m_len); return _libssh2_rsa_sha1_verify(rsactx, sig, sig_len, m, m_len);
@@ -281,45 +282,42 @@ hostkey_method_ssh_dss_init(LIBSSH2_SESSION * session,
void **abstract) void **abstract)
{ {
libssh2_dsa_ctx *dsactx; libssh2_dsa_ctx *dsactx;
const unsigned char *p, *q, *g, *y, *s; unsigned char *p, *q, *g, *y;
unsigned long p_len, q_len, g_len, y_len, len; size_t p_len, q_len, g_len, y_len;
int ret; struct string_buf buf;
(void) hostkey_data_len;
if(*abstract) { if(*abstract) {
hostkey_method_ssh_dss_dtor(session, abstract); hostkey_method_ssh_dss_dtor(session, abstract);
*abstract = NULL; *abstract = NULL;
} }
s = hostkey_data; if(hostkey_data_len < 27) {
len = _libssh2_ntohu32(s); _libssh2_debug(session, LIBSSH2_TRACE_ERROR,
s += 4; "host key length too short");
if (len != 7 || strncmp((char *) s, "ssh-dss", 7) != 0) {
return -1; return -1;
} }
s += 7;
p_len = _libssh2_ntohu32(s); buf.data = (unsigned char *)hostkey_data;
s += 4; buf.dataptr = buf.data;
p = s; buf.len = hostkey_data_len;
s += p_len;
q_len = _libssh2_ntohu32(s);
s += 4;
q = s;
s += q_len;
g_len = _libssh2_ntohu32(s);
s += 4;
g = s;
s += g_len;
y_len = _libssh2_ntohu32(s);
s += 4;
y = s;
/* s += y_len; */
ret = _libssh2_dsa_new(&dsactx, p, p_len, q, q_len, if(_libssh2_match_string(&buf, "ssh-dss"))
g, g_len, y, y_len, NULL, 0); return -1;
if (ret) {
if(_libssh2_get_string(&buf, &p, &p_len))
return -1;
if(_libssh2_get_string(&buf, &q, &q_len))
return -1;
if(_libssh2_get_string(&buf, &g, &g_len))
return -1;
if(_libssh2_get_string(&buf, &y, &y_len))
return -1;
if(_libssh2_dsa_new(&dsactx, p, p_len, q, q_len,
g, g_len, y, y_len, NULL, 0)) {
return -1; return -1;
} }
@@ -404,12 +402,14 @@ hostkey_method_ssh_dss_sig_verify(LIBSSH2_SESSION * session,
libssh2_dsa_ctx *dsactx = (libssh2_dsa_ctx *) (*abstract); libssh2_dsa_ctx *dsactx = (libssh2_dsa_ctx *) (*abstract);
/* Skip past keyname_len(4) + keyname(7){"ssh-dss"} + signature_len(4) */ /* Skip past keyname_len(4) + keyname(7){"ssh-dss"} + signature_len(4) */
sig += 15; if(sig_len != 55) {
sig_len -= 15;
if (sig_len != 40) {
return _libssh2_error(session, LIBSSH2_ERROR_PROTO, return _libssh2_error(session, LIBSSH2_ERROR_PROTO,
"Invalid DSS signature length"); "Invalid DSS signature length");
} }
sig += 15;
sig_len -= 15;
return _libssh2_dsa_sha1_verify(dsactx, sig, m, m_len); return _libssh2_dsa_sha1_verify(dsactx, sig, m, m_len);
} }
@@ -483,7 +483,526 @@ static const LIBSSH2_HOSTKEY_METHOD hostkey_method_ssh_dss = {
}; };
#endif /* LIBSSH2_DSA */ #endif /* LIBSSH2_DSA */
#if LIBSSH2_ECDSA
/* ***********
* ecdsa-sha2-nistp256/384/521 *
*********** */
static int
hostkey_method_ssh_ecdsa_dtor(LIBSSH2_SESSION * session,
void **abstract);
/*
* hostkey_method_ssh_ecdsa_init
*
* Initialize the server hostkey working area with e/n pair
*/
static int
hostkey_method_ssh_ecdsa_init(LIBSSH2_SESSION * session,
const unsigned char *hostkey_data,
size_t hostkey_data_len,
void **abstract)
{
libssh2_ecdsa_ctx *ecdsactx = NULL;
unsigned char *type_str, *domain, *public_key;
size_t key_len, len;
libssh2_curve_type type;
struct string_buf buf;
if(abstract != NULL && *abstract) {
hostkey_method_ssh_ecdsa_dtor(session, abstract);
*abstract = NULL;
}
if(hostkey_data_len < 39) {
_libssh2_debug(session, LIBSSH2_TRACE_ERROR,
"host key length too short");
return -1;
}
buf.data = (unsigned char *)hostkey_data;
buf.dataptr = buf.data;
buf.len = hostkey_data_len;
if(_libssh2_get_string(&buf, &type_str, &len) || len != 19)
return -1;
if(strncmp((char *) type_str, "ecdsa-sha2-nistp256", 19) == 0) {
type = LIBSSH2_EC_CURVE_NISTP256;
}
else if(strncmp((char *) type_str, "ecdsa-sha2-nistp384", 19) == 0) {
type = LIBSSH2_EC_CURVE_NISTP384;
}
else if(strncmp((char *) type_str, "ecdsa-sha2-nistp521", 19) == 0) {
type = LIBSSH2_EC_CURVE_NISTP521;
}
else {
return -1;
}
if(_libssh2_get_string(&buf, &domain, &len) || len != 8)
return -1;
if(type == LIBSSH2_EC_CURVE_NISTP256 &&
strncmp((char *)domain, "nistp256", 8) != 0) {
return -1;
}
else if(type == LIBSSH2_EC_CURVE_NISTP384 &&
strncmp((char *)domain, "nistp384", 8) != 0) {
return -1;
}
else if(type == LIBSSH2_EC_CURVE_NISTP521 &&
strncmp((char *)domain, "nistp521", 8) != 0) {
return -1;
}
/* public key */
if(_libssh2_get_string(&buf, &public_key, &key_len))
return -1;
if(_libssh2_ecdsa_curve_name_with_octal_new(&ecdsactx, public_key,
key_len, type))
return -1;
if(abstract != NULL)
*abstract = ecdsactx;
return 0;
}
/*
* hostkey_method_ssh_ecdsa_initPEM
*
* Load a Private Key from a PEM file
*/
static int
hostkey_method_ssh_ecdsa_initPEM(LIBSSH2_SESSION * session,
const char *privkeyfile,
unsigned const char *passphrase,
void **abstract)
{
libssh2_ecdsa_ctx *ec_ctx = NULL;
int ret;
if(abstract != NULL && *abstract) {
hostkey_method_ssh_ecdsa_dtor(session, abstract);
*abstract = NULL;
}
ret = _libssh2_ecdsa_new_private(&ec_ctx, session,
privkeyfile, passphrase);
if(abstract != NULL)
*abstract = ec_ctx;
return ret;
}
/*
* hostkey_method_ssh_ecdsa_initPEMFromMemory
*
* Load a Private Key from memory
*/
static int
hostkey_method_ssh_ecdsa_initPEMFromMemory(LIBSSH2_SESSION * session,
const char *privkeyfiledata,
size_t privkeyfiledata_len,
unsigned const char *passphrase,
void **abstract)
{
libssh2_ecdsa_ctx *ec_ctx = NULL;
int ret;
if(abstract != NULL && *abstract) {
hostkey_method_ssh_ecdsa_dtor(session, abstract);
*abstract = NULL;
}
ret = _libssh2_ecdsa_new_private_frommemory(&ec_ctx, session,
privkeyfiledata,
privkeyfiledata_len,
passphrase);
if(ret) {
return -1;
}
if(abstract != NULL)
*abstract = ec_ctx;
return 0;
}
/*
* hostkey_method_ecdsa_sig_verify
*
* Verify signature created by remote
*/
static int
hostkey_method_ssh_ecdsa_sig_verify(LIBSSH2_SESSION * session,
const unsigned char *sig,
size_t sig_len,
const unsigned char *m,
size_t m_len, void **abstract)
{
unsigned char *r, *s, *name;
size_t r_len, s_len, name_len;
unsigned int len;
struct string_buf buf;
libssh2_ecdsa_ctx *ctx = (libssh2_ecdsa_ctx *) (*abstract);
(void) session;
if(sig_len < 35)
return -1;
/* keyname_len(4) + keyname(19){"ecdsa-sha2-nistp256"} +
signature_len(4) */
buf.data = (unsigned char *)sig;
buf.dataptr = buf.data;
buf.len = sig_len;
if(_libssh2_get_string(&buf, &name, &name_len) || name_len != 19)
return -1;
if(_libssh2_get_u32(&buf, &len) != 0 || len < 8)
return -1;
if(_libssh2_get_string(&buf, &r, &r_len))
return -1;
if(_libssh2_get_string(&buf, &s, &s_len))
return -1;
return _libssh2_ecdsa_verify(ctx, r, r_len, s, s_len, m, m_len);
}
#define LIBSSH2_HOSTKEY_METHOD_EC_SIGNV_HASH(digest_type) \
{ \
unsigned char hash[SHA##digest_type##_DIGEST_LENGTH]; \
libssh2_sha##digest_type##_ctx ctx; \
int i; \
libssh2_sha##digest_type##_init(&ctx); \
for(i = 0; i < veccount; i++) { \
libssh2_sha##digest_type##_update(ctx, datavec[i].iov_base, \
datavec[i].iov_len); \
} \
libssh2_sha##digest_type##_final(ctx, hash); \
ret = _libssh2_ecdsa_sign(session, ec_ctx, hash, \
SHA##digest_type##_DIGEST_LENGTH, \
signature, signature_len); \
}
/*
* hostkey_method_ecdsa_signv
*
* Construct a signature from an array of vectors
*/
static int
hostkey_method_ssh_ecdsa_signv(LIBSSH2_SESSION * session,
unsigned char **signature,
size_t *signature_len,
int veccount,
const struct iovec datavec[],
void **abstract)
{
libssh2_ecdsa_ctx *ec_ctx = (libssh2_ecdsa_ctx *) (*abstract);
libssh2_curve_type type = _libssh2_ecdsa_key_get_curve_type(ec_ctx);
int ret = 0;
if(type == LIBSSH2_EC_CURVE_NISTP256) {
LIBSSH2_HOSTKEY_METHOD_EC_SIGNV_HASH(256);
}
else if(type == LIBSSH2_EC_CURVE_NISTP384) {
LIBSSH2_HOSTKEY_METHOD_EC_SIGNV_HASH(384);
}
else if(type == LIBSSH2_EC_CURVE_NISTP521) {
LIBSSH2_HOSTKEY_METHOD_EC_SIGNV_HASH(512);
}
else {
return -1;
}
return ret;
}
/*
* hostkey_method_ssh_ecdsa_dtor
*
* Shutdown the hostkey by freeing EC_KEY context
*/
static int
hostkey_method_ssh_ecdsa_dtor(LIBSSH2_SESSION * session, void **abstract)
{
libssh2_ecdsa_ctx *keyctx = (libssh2_ecdsa_ctx *) (*abstract);
(void) session;
if(keyctx != NULL)
_libssh2_ecdsa_free(keyctx);
*abstract = NULL;
return 0;
}
static const LIBSSH2_HOSTKEY_METHOD hostkey_method_ecdsa_ssh_nistp256 = {
"ecdsa-sha2-nistp256",
SHA256_DIGEST_LENGTH,
hostkey_method_ssh_ecdsa_init,
hostkey_method_ssh_ecdsa_initPEM,
hostkey_method_ssh_ecdsa_initPEMFromMemory,
hostkey_method_ssh_ecdsa_sig_verify,
hostkey_method_ssh_ecdsa_signv,
NULL, /* encrypt */
hostkey_method_ssh_ecdsa_dtor,
};
static const LIBSSH2_HOSTKEY_METHOD hostkey_method_ecdsa_ssh_nistp384 = {
"ecdsa-sha2-nistp384",
SHA384_DIGEST_LENGTH,
hostkey_method_ssh_ecdsa_init,
hostkey_method_ssh_ecdsa_initPEM,
hostkey_method_ssh_ecdsa_initPEMFromMemory,
hostkey_method_ssh_ecdsa_sig_verify,
hostkey_method_ssh_ecdsa_signv,
NULL, /* encrypt */
hostkey_method_ssh_ecdsa_dtor,
};
static const LIBSSH2_HOSTKEY_METHOD hostkey_method_ecdsa_ssh_nistp521 = {
"ecdsa-sha2-nistp521",
SHA512_DIGEST_LENGTH,
hostkey_method_ssh_ecdsa_init,
hostkey_method_ssh_ecdsa_initPEM,
hostkey_method_ssh_ecdsa_initPEMFromMemory,
hostkey_method_ssh_ecdsa_sig_verify,
hostkey_method_ssh_ecdsa_signv,
NULL, /* encrypt */
hostkey_method_ssh_ecdsa_dtor,
};
#endif /* LIBSSH2_ECDSA */
#if LIBSSH2_ED25519
/* ***********
* ed25519 *
*********** */
static int hostkey_method_ssh_ed25519_dtor(LIBSSH2_SESSION * session,
void **abstract);
/*
* hostkey_method_ssh_ed25519_init
*
* Initialize the server hostkey working area with e/n pair
*/
static int
hostkey_method_ssh_ed25519_init(LIBSSH2_SESSION * session,
const unsigned char *hostkey_data,
size_t hostkey_data_len,
void **abstract)
{
const unsigned char *s;
unsigned long len, key_len;
libssh2_ed25519_ctx *ctx = NULL;
if(*abstract) {
hostkey_method_ssh_ed25519_dtor(session, abstract);
*abstract = NULL;
}
if(hostkey_data_len < 19) {
_libssh2_debug(session, LIBSSH2_TRACE_ERROR,
"host key length too short");
return -1;
}
s = hostkey_data;
len = _libssh2_ntohu32(s);
s += 4;
if(len != 11 || strncmp((char *) s, "ssh-ed25519", 11) != 0) {
return -1;
}
s += 11;
/* public key */
key_len = _libssh2_ntohu32(s);
s += 4;
if(_libssh2_ed25519_new_public(&ctx, session, s, key_len) != 0) {
return -1;
}
*abstract = ctx;
return 0;
}
/*
* hostkey_method_ssh_ed25519_initPEM
*
* Load a Private Key from a PEM file
*/
static int
hostkey_method_ssh_ed25519_initPEM(LIBSSH2_SESSION * session,
const char *privkeyfile,
unsigned const char *passphrase,
void **abstract)
{
libssh2_ed25519_ctx *ec_ctx = NULL;
int ret;
if(*abstract) {
hostkey_method_ssh_ed25519_dtor(session, abstract);
*abstract = NULL;
}
ret = _libssh2_ed25519_new_private(&ec_ctx, session,
privkeyfile, passphrase);
if(ret) {
return -1;
}
*abstract = ec_ctx;
return ret;
}
/*
* hostkey_method_ssh_ed25519_initPEMFromMemory
*
* Load a Private Key from memory
*/
static int
hostkey_method_ssh_ed25519_initPEMFromMemory(LIBSSH2_SESSION * session,
const char *privkeyfiledata,
size_t privkeyfiledata_len,
unsigned const char *passphrase,
void **abstract)
{
libssh2_ed25519_ctx *ed_ctx = NULL;
int ret;
if(abstract != NULL && *abstract) {
hostkey_method_ssh_ed25519_dtor(session, abstract);
*abstract = NULL;
}
ret = _libssh2_ed25519_new_private_frommemory(&ed_ctx, session,
privkeyfiledata,
privkeyfiledata_len,
passphrase);
if(ret) {
return -1;
}
if(abstract != NULL)
*abstract = ed_ctx;
return 0;
}
/*
* hostkey_method_ssh_ed25519_sig_verify
*
* Verify signature created by remote
*/
static int
hostkey_method_ssh_ed25519_sig_verify(LIBSSH2_SESSION * session,
const unsigned char *sig,
size_t sig_len,
const unsigned char *m,
size_t m_len, void **abstract)
{
libssh2_ed25519_ctx *ctx = (libssh2_ed25519_ctx *) (*abstract);
(void) session;
if(sig_len < 19)
return -1;
/* Skip past keyname_len(4) + keyname(11){"ssh-ed25519"} +
signature_len(4) */
sig += 19;
sig_len -= 19;
if(sig_len != LIBSSH2_ED25519_SIG_LEN)
return -1;
return _libssh2_ed25519_verify(ctx, sig, sig_len, m, m_len);
}
/*
* hostkey_method_ssh_ed25519_signv
*
* Construct a signature from an array of vectors
*/
static int
hostkey_method_ssh_ed25519_signv(LIBSSH2_SESSION * session,
unsigned char **signature,
size_t *signature_len,
int veccount,
const struct iovec datavec[],
void **abstract)
{
libssh2_ed25519_ctx *ctx = (libssh2_ed25519_ctx *) (*abstract);
if(veccount != 1) {
return -1;
}
return _libssh2_ed25519_sign(ctx, session, signature, signature_len,
datavec[0].iov_base, datavec[0].iov_len);
}
/*
* hostkey_method_ssh_ed25519_dtor
*
* Shutdown the hostkey by freeing key context
*/
static int
hostkey_method_ssh_ed25519_dtor(LIBSSH2_SESSION * session, void **abstract)
{
libssh2_ed25519_ctx *keyctx = (libssh2_ed25519_ctx*) (*abstract);
(void) session;
if(keyctx)
_libssh2_ed25519_free(keyctx);
*abstract = NULL;
return 0;
}
static const LIBSSH2_HOSTKEY_METHOD hostkey_method_ssh_ed25519 = {
"ssh-ed25519",
SHA256_DIGEST_LENGTH,
hostkey_method_ssh_ed25519_init,
hostkey_method_ssh_ed25519_initPEM,
hostkey_method_ssh_ed25519_initPEMFromMemory,
hostkey_method_ssh_ed25519_sig_verify,
hostkey_method_ssh_ed25519_signv,
NULL, /* encrypt */
hostkey_method_ssh_ed25519_dtor,
};
#endif /*LIBSSH2_ED25519*/
static const LIBSSH2_HOSTKEY_METHOD *hostkey_methods[] = { static const LIBSSH2_HOSTKEY_METHOD *hostkey_methods[] = {
#if LIBSSH2_ECDSA
&hostkey_method_ecdsa_ssh_nistp256,
&hostkey_method_ecdsa_ssh_nistp384,
&hostkey_method_ecdsa_ssh_nistp521,
#endif
#if LIBSSH2_ED25519
&hostkey_method_ssh_ed25519,
#endif
#if LIBSSH2_RSA #if LIBSSH2_RSA
&hostkey_method_ssh_rsa, &hostkey_method_ssh_rsa,
#endif /* LIBSSH2_RSA */ #endif /* LIBSSH2_RSA */
@@ -505,7 +1024,7 @@ libssh2_hostkey_methods(void)
* Returns hash signature * Returns hash signature
* Returned buffer should NOT be freed * Returned buffer should NOT be freed
* Length of buffer is determined by hash type * Length of buffer is determined by hash type
* i.e. MD5 == 16, SHA1 == 20 * i.e. MD5 == 16, SHA1 == 20, SHA256 == 32
*/ */
LIBSSH2_API const char * LIBSSH2_API const char *
libssh2_hostkey_hash(LIBSSH2_SESSION * session, int hash_type) libssh2_hostkey_hash(LIBSSH2_SESSION * session, int hash_type)
@@ -523,6 +1042,11 @@ libssh2_hostkey_hash(LIBSSH2_SESSION * session, int hash_type)
? (char *) session->server_hostkey_sha1 ? (char *) session->server_hostkey_sha1
: NULL; : NULL;
break; break;
case LIBSSH2_HOSTKEY_HASH_SHA256:
return (session->server_hostkey_sha256_valid)
? (char *) session->server_hostkey_sha256
: NULL;
break;
default: default:
return NULL; return NULL;
} }
@@ -530,12 +1054,27 @@ libssh2_hostkey_hash(LIBSSH2_SESSION * session, int hash_type)
static int hostkey_type(const unsigned char *hostkey, size_t len) static int hostkey_type(const unsigned char *hostkey, size_t len)
{ {
const unsigned char rsa[] = { static const unsigned char rsa[] = {
0, 0, 0, 0x07, 's', 's', 'h', '-', 'r', 's', 'a' 0, 0, 0, 0x07, 's', 's', 'h', '-', 'r', 's', 'a'
}; };
const unsigned char dss[] = { static const unsigned char dss[] = {
0, 0, 0, 0x07, 's', 's', 'h', '-', 'd', 's', 's' 0, 0, 0, 0x07, 's', 's', 'h', '-', 'd', 's', 's'
}; };
static const unsigned char ecdsa_256[] = {
0, 0, 0, 0x13, 'e', 'c', 'd', 's', 'a', '-', 's', 'h', 'a', '2', '-',
'n', 'i', 's', 't', 'p', '2', '5', '6'
};
static const unsigned char ecdsa_384[] = {
0, 0, 0, 0x13, 'e', 'c', 'd', 's', 'a', '-', 's', 'h', 'a', '2', '-',
'n', 'i', 's', 't', 'p', '3', '8', '4'
};
static const unsigned char ecdsa_521[] = {
0, 0, 0, 0x13, 'e', 'c', 'd', 's', 'a', '-', 's', 'h', 'a', '2', '-',
'n', 'i', 's', 't', 'p', '5', '2', '1'
};
static const unsigned char ed25519[] = {
0, 0, 0, 0x0b, 's', 's', 'h', '-', 'e', 'd', '2', '5', '5', '1', '9'
};
if(len < 11) if(len < 11)
return LIBSSH2_HOSTKEY_TYPE_UNKNOWN; return LIBSSH2_HOSTKEY_TYPE_UNKNOWN;
@@ -546,6 +1085,24 @@ static int hostkey_type(const unsigned char *hostkey, size_t len)
if(!memcmp(dss, hostkey, 11)) if(!memcmp(dss, hostkey, 11))
return LIBSSH2_HOSTKEY_TYPE_DSS; return LIBSSH2_HOSTKEY_TYPE_DSS;
if(len < 15)
return LIBSSH2_HOSTKEY_TYPE_UNKNOWN;
if(!memcmp(ed25519, hostkey, 15))
return LIBSSH2_HOSTKEY_TYPE_ED25519;
if(len < 23)
return LIBSSH2_HOSTKEY_TYPE_UNKNOWN;
if(!memcmp(ecdsa_256, hostkey, 23))
return LIBSSH2_HOSTKEY_TYPE_ECDSA_256;
if(!memcmp(ecdsa_384, hostkey, 23))
return LIBSSH2_HOSTKEY_TYPE_ECDSA_384;
if(!memcmp(ecdsa_521, hostkey, 23))
return LIBSSH2_HOSTKEY_TYPE_ECDSA_521;
return LIBSSH2_HOSTKEY_TYPE_UNKNOWN; return LIBSSH2_HOSTKEY_TYPE_UNKNOWN;
} }
@@ -570,4 +1127,3 @@ libssh2_session_hostkey(LIBSSH2_SESSION *session, size_t *len, int *type)
*len = 0; *len = 0;
return NULL; return NULL;
} }

View File

@@ -90,7 +90,8 @@ libssh2_keepalive_send (LIBSSH2_SESSION *session,
session->keepalive_last_sent = now; session->keepalive_last_sent = now;
if(seconds_to_next) if(seconds_to_next)
*seconds_to_next = session->keepalive_interval; *seconds_to_next = session->keepalive_interval;
} else if (seconds_to_next) { }
else if(seconds_to_next) {
*seconds_to_next = (int) (session->keepalive_last_sent - now) *seconds_to_next = (int) (session->keepalive_last_sent - now)
+ session->keepalive_interval; + session->keepalive_interval;
} }

File diff suppressed because it is too large Load Diff

View File

@@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2009-2014 by Daniel Stenberg * Copyright (c) 2009-2019 by Daniel Stenberg
* All rights reserved. * All rights reserved.
* *
* Redistribution and use in source and binary forms, * Redistribution and use in source and binary forms,
@@ -149,7 +149,8 @@ knownhost_add(LIBSSH2_KNOWNHOSTS *hosts,
return _libssh2_error(hosts->session, LIBSSH2_ERROR_INVAL, return _libssh2_error(hosts->session, LIBSSH2_ERROR_INVAL,
"No key type set"); "No key type set");
if(!(entry = LIBSSH2_CALLOC(hosts->session, sizeof(struct known_host)))) entry = LIBSSH2_CALLOC(hosts->session, sizeof(struct known_host));
if(!entry)
return _libssh2_error(hosts->session, LIBSSH2_ERROR_ALLOC, return _libssh2_error(hosts->session, LIBSSH2_ERROR_ALLOC,
"Unable to allocate memory for known host " "Unable to allocate memory for known host "
"entry"); "entry");
@@ -450,9 +451,9 @@ knownhost_check(LIBSSH2_KNOWNHOSTS *hosts,
- if key_type is set to zero, ignore it an match always - if key_type is set to zero, ignore it an match always
- otherwise match when both key types are equal - otherwise match when both key types are equal
*/ */
if ( (host_key_type != LIBSSH2_KNOWNHOST_KEY_UNKNOWN ) && if(host_key_type != LIBSSH2_KNOWNHOST_KEY_UNKNOWN &&
( (host_key_type == 0) || (host_key_type == 0 ||
(host_key_type == known_key_type) ) ) { host_key_type == known_key_type)) {
/* host name and key type match, now compare the keys */ /* host name and key type match, now compare the keys */
if(!strcmp(key, node->key)) { if(!strcmp(key, node->key)) {
/* they match! */ /* they match! */
@@ -777,6 +778,14 @@ static int hostline(LIBSSH2_KNOWNHOSTS *hosts,
key_type = LIBSSH2_KNOWNHOST_KEY_SSHDSS; key_type = LIBSSH2_KNOWNHOST_KEY_SSHDSS;
else if(!strncmp(key_type_name, "ssh-rsa", key_type_len)) else if(!strncmp(key_type_name, "ssh-rsa", key_type_len))
key_type = LIBSSH2_KNOWNHOST_KEY_SSHRSA; key_type = LIBSSH2_KNOWNHOST_KEY_SSHRSA;
else if(!strncmp(key_type_name, "ecdsa-sha2-nistp256", key_type_len))
key_type = LIBSSH2_KNOWNHOST_KEY_ECDSA_256;
else if(!strncmp(key_type_name, "ecdsa-sha2-nistp384", key_type_len))
key_type = LIBSSH2_KNOWNHOST_KEY_ECDSA_384;
else if(!strncmp(key_type_name, "ecdsa-sha2-nistp521", key_type_len))
key_type = LIBSSH2_KNOWNHOST_KEY_ECDSA_521;
else if(!strncmp(key_type_name, "ssh-ed25519", key_type_len))
key_type = LIBSSH2_KNOWNHOST_KEY_ED25519;
else else
key_type = LIBSSH2_KNOWNHOST_KEY_UNKNOWN; key_type = LIBSSH2_KNOWNHOST_KEY_UNKNOWN;
@@ -954,7 +963,7 @@ libssh2_knownhost_readfile(LIBSSH2_KNOWNHOSTS *hosts,
"Unsupported type of known-host information " "Unsupported type of known-host information "
"store"); "store");
file = fopen(filename, "r"); file = fopen(filename, FOPEN_READTEXT);
if(file) { if(file) {
while(fgets(buf, sizeof(buf), file)) { while(fgets(buf, sizeof(buf), file)) {
if(libssh2_knownhost_readline(hosts, buf, strlen(buf), type)) { if(libssh2_knownhost_readline(hosts, buf, strlen(buf), type)) {
@@ -1016,6 +1025,22 @@ knownhost_writeline(LIBSSH2_KNOWNHOSTS *hosts,
key_type_name = "ssh-dss"; key_type_name = "ssh-dss";
key_type_len = 7; key_type_len = 7;
break; break;
case LIBSSH2_KNOWNHOST_KEY_ECDSA_256:
key_type_name = "ecdsa-sha2-nistp256";
key_type_len = 19;
break;
case LIBSSH2_KNOWNHOST_KEY_ECDSA_384:
key_type_name = "ecdsa-sha2-nistp384";
key_type_len = 19;
break;
case LIBSSH2_KNOWNHOST_KEY_ECDSA_521:
key_type_name = "ecdsa-sha2-nistp521";
key_type_len = 19;
break;
case LIBSSH2_KNOWNHOST_KEY_ED25519:
key_type_name = "ssh-ed25519";
key_type_len = 11;
break;
case LIBSSH2_KNOWNHOST_KEY_UNKNOWN: case LIBSSH2_KNOWNHOST_KEY_UNKNOWN:
key_type_name = node->key_type_name; key_type_name = node->key_type_name;
if(key_type_name) { if(key_type_name) {
@@ -1023,6 +1048,7 @@ knownhost_writeline(LIBSSH2_KNOWNHOSTS *hosts,
break; break;
} }
/* otherwise fallback to default and error */ /* otherwise fallback to default and error */
/* FALL-THROUGH */
default: default:
return _libssh2_error(hosts->session, return _libssh2_error(hosts->session,
LIBSSH2_ERROR_METHOD_NOT_SUPPORTED, LIBSSH2_ERROR_METHOD_NOT_SUPPORTED,
@@ -1178,7 +1204,7 @@ libssh2_knownhost_writefile(LIBSSH2_KNOWNHOSTS *hosts,
"Unsupported type of known-host information " "Unsupported type of known-host information "
"store"); "store");
file = fopen(filename, "w"); file = fopen(filename, FOPEN_WRITETEXT);
if(!file) if(!file)
return _libssh2_error(hosts->session, LIBSSH2_ERROR_FILE, return _libssh2_error(hosts->session, LIBSSH2_ERROR_FILE,
"Failed to open file"); "Failed to open file");

View File

@@ -72,7 +72,8 @@ _libssh2_rsa_new(libssh2_rsa_ctx ** rsa,
"(private-key(rsa(n%b)(e%b)(d%b)(q%b)(p%b)(u%b)))", "(private-key(rsa(n%b)(e%b)(d%b)(q%b)(p%b)(u%b)))",
nlen, ndata, elen, edata, dlen, ddata, plen, pdata, nlen, ndata, elen, edata, dlen, ddata, plen, pdata,
qlen, qdata, coefflen, coeffdata); qlen, qdata, coefflen, coeffdata);
} else { }
else {
rc = gcry_sexp_build(rsa, NULL, "(public-key(rsa(n%b)(e%b)))", rc = gcry_sexp_build(rsa, NULL, "(public-key(rsa(n%b)(e%b)))",
nlen, ndata, elen, edata); nlen, ndata, elen, edata);
} }
@@ -135,7 +136,8 @@ _libssh2_dsa_new(libssh2_dsa_ctx ** dsactx,
(dsactx, NULL, (dsactx, NULL,
"(private-key(dsa(p%b)(q%b)(g%b)(y%b)(x%b)))", "(private-key(dsa(p%b)(q%b)(g%b)(y%b)(x%b)))",
p_len, p, q_len, q, g_len, g, y_len, y, x_len, x); p_len, p, q_len, q, g_len, g, y_len, y, x_len, x);
} else { }
else {
rc = gcry_sexp_build(dsactx, NULL, rc = gcry_sexp_build(dsactx, NULL,
"(public-key(dsa(p%b)(q%b)(g%b)(y%b)))", "(public-key(dsa(p%b)(q%b)(g%b)(y%b)))",
p_len, p, q_len, q, g_len, g, y_len, y); p_len, p, q_len, q, g_len, g, y_len, y);
@@ -172,9 +174,7 @@ _libssh2_rsa_new_private(libssh2_rsa_ctx ** rsa,
unsigned char *n, *e, *d, *p, *q, *e1, *e2, *coeff; unsigned char *n, *e, *d, *p, *q, *e1, *e2, *coeff;
unsigned int nlen, elen, dlen, plen, qlen, e1len, e2len, coefflen; unsigned int nlen, elen, dlen, plen, qlen, e1len, e2len, coefflen;
(void) passphrase; fp = fopen(filename, FOPEN_READTEXT);
fp = fopen(filename, "r");
if(!fp) { if(!fp) {
return -1; return -1;
} }
@@ -182,6 +182,7 @@ _libssh2_rsa_new_private(libssh2_rsa_ctx ** rsa,
ret = _libssh2_pem_parse(session, ret = _libssh2_pem_parse(session,
"-----BEGIN RSA PRIVATE KEY-----", "-----BEGIN RSA PRIVATE KEY-----",
"-----END RSA PRIVATE KEY-----", "-----END RSA PRIVATE KEY-----",
passphrase,
fp, &data, &datalen); fp, &data, &datalen);
fclose(fp); fclose(fp);
if(ret) { if(ret) {
@@ -285,9 +286,7 @@ _libssh2_dsa_new_private(libssh2_dsa_ctx ** dsa,
unsigned char *p, *q, *g, *y, *x; unsigned char *p, *q, *g, *y, *x;
unsigned int plen, qlen, glen, ylen, xlen; unsigned int plen, qlen, glen, ylen, xlen;
(void) passphrase; fp = fopen(filename, FOPEN_READTEXT);
fp = fopen(filename, "r");
if(!fp) { if(!fp) {
return -1; return -1;
} }
@@ -295,6 +294,7 @@ _libssh2_dsa_new_private(libssh2_dsa_ctx ** dsa,
ret = _libssh2_pem_parse(session, ret = _libssh2_pem_parse(session,
"-----BEGIN DSA PRIVATE KEY-----", "-----BEGIN DSA PRIVATE KEY-----",
"-----END DSA PRIVATE KEY-----", "-----END DSA PRIVATE KEY-----",
passphrase,
fp, &data, &datalen); fp, &data, &datalen);
fclose(fp); fclose(fp);
if(ret) { if(ret) {
@@ -400,6 +400,7 @@ _libssh2_rsa_sha1_sign(LIBSSH2_SESSION * session,
tmp = gcry_sexp_nth_data(data, 1, &size); tmp = gcry_sexp_nth_data(data, 1, &size);
if(!tmp) { if(!tmp) {
gcry_sexp_release(data);
return -1; return -1;
} }
@@ -410,11 +411,14 @@ _libssh2_rsa_sha1_sign(LIBSSH2_SESSION * session,
*signature = LIBSSH2_ALLOC(session, size); *signature = LIBSSH2_ALLOC(session, size);
if(!*signature) { if(!*signature) {
gcry_sexp_release(data);
return -1; return -1;
} }
memcpy(*signature, tmp, size); memcpy(*signature, tmp, size);
*signature_len = size; *signature_len = size;
gcry_sexp_release(data);
return rc; return rc;
} }
@@ -437,7 +441,8 @@ _libssh2_dsa_sha1_sign(libssh2_dsa_ctx * dsactx,
memcpy(zhash + 1, hash, hash_len); memcpy(zhash + 1, hash, hash_len);
zhash[0] = 0; zhash[0] = 0;
if (gcry_sexp_build(&data, NULL, "(data (value %b))", hash_len + 1, zhash)) { if(gcry_sexp_build(&data, NULL, "(data (value %b))",
hash_len + 1, zhash)) {
return -1; return -1;
} }
@@ -585,7 +590,8 @@ _libssh2_cipher_crypt(_libssh2_cipher_ctx * ctx,
if(encrypt) { if(encrypt) {
ret = gcry_cipher_encrypt(*ctx, block, blklen, block, blklen); ret = gcry_cipher_encrypt(*ctx, block, blklen, block, blklen);
} else { }
else {
ret = gcry_cipher_decrypt(*ctx, block, blklen, block, blklen); ret = gcry_cipher_decrypt(*ctx, block, blklen, block, blklen);
} }
return ret; return ret;
@@ -602,7 +608,8 @@ _libssh2_pub_priv_keyfilememory(LIBSSH2_SESSION *session,
const char *passphrase) const char *passphrase)
{ {
return _libssh2_error(session, LIBSSH2_ERROR_METHOD_NOT_SUPPORTED, return _libssh2_error(session, LIBSSH2_ERROR_METHOD_NOT_SUPPORTED,
"Unable to extract public key from private key in memory: " "Unable to extract public key from private "
"key in memory: "
"Method unimplemented in libgcrypt backend"); "Method unimplemented in libgcrypt backend");
} }
@@ -624,4 +631,37 @@ void _libssh2_init_aes_ctr(void)
{ {
/* no implementation */ /* no implementation */
} }
void
_libssh2_dh_init(_libssh2_dh_ctx *dhctx)
{
*dhctx = gcry_mpi_new(0); /* Random from client */
}
int
_libssh2_dh_key_pair(_libssh2_dh_ctx *dhctx, _libssh2_bn *public,
_libssh2_bn *g, _libssh2_bn *p, int group_order)
{
/* Generate x and e */
gcry_mpi_randomize(*dhctx, group_order * 8 - 1, GCRY_WEAK_RANDOM);
gcry_mpi_powm(public, g, *dhctx, p);
return 0;
}
int
_libssh2_dh_secret(_libssh2_dh_ctx *dhctx, _libssh2_bn *secret,
_libssh2_bn *f, _libssh2_bn *p)
{
/* Compute the shared secret */
gcry_mpi_powm(secret, f, *dhctx, p);
return 0;
}
void
_libssh2_dh_dtor(_libssh2_dh_ctx *dhctx)
{
gcry_mpi_release(*dhctx);
*dhctx = NULL;
}
#endif /* LIBSSH2_LIBGCRYPT */ #endif /* LIBSSH2_LIBGCRYPT */

View File

@@ -54,10 +54,16 @@
#define LIBSSH2_RSA 1 #define LIBSSH2_RSA 1
#define LIBSSH2_DSA 1 #define LIBSSH2_DSA 1
#define LIBSSH2_ECDSA 0
#define LIBSSH2_ED25519 0
#define MD5_DIGEST_LENGTH 16 #define MD5_DIGEST_LENGTH 16
#define SHA_DIGEST_LENGTH 20 #define SHA_DIGEST_LENGTH 20
#define SHA256_DIGEST_LENGTH 32 #define SHA256_DIGEST_LENGTH 32
#define SHA384_DIGEST_LENGTH 48
#define SHA512_DIGEST_LENGTH 64
#define EC_MAX_POINT_LEN ((528 * 2 / 8) + 1)
#define _libssh2_random(buf, len) \ #define _libssh2_random(buf, len) \
(gcry_randomize ((buf), (len), GCRY_STRONG_RANDOM), 1) (gcry_randomize ((buf), (len), GCRY_STRONG_RANDOM), 1)
@@ -87,6 +93,28 @@
#define libssh2_sha256(message, len, out) \ #define libssh2_sha256(message, len, out) \
gcry_md_hash_buffer(GCRY_MD_SHA256, out, message, len) gcry_md_hash_buffer(GCRY_MD_SHA256, out, message, len)
#define libssh2_sha384_ctx gcry_md_hd_t
#define libssh2_sha384_init(ctx) \
(GPG_ERR_NO_ERROR == gcry_md_open(ctx, GCRY_MD_SHA384, 0))
#define libssh2_sha384_update(ctx, data, len) \
gcry_md_write(ctx, (unsigned char *) data, len)
#define libssh2_sha384_final(ctx, out) \
memcpy(out, gcry_md_read(ctx, 0), SHA384_DIGEST_LENGTH), gcry_md_close(ctx)
#define libssh2_sha384(message, len, out) \
gcry_md_hash_buffer(GCRY_MD_SHA384, out, message, len)
#define libssh2_sha512_ctx gcry_md_hd_t
#define libssh2_sha512_init(ctx) \
(GPG_ERR_NO_ERROR == gcry_md_open(ctx, GCRY_MD_SHA512, 0))
#define libssh2_sha512_update(ctx, data, len) \
gcry_md_write(ctx, (unsigned char *) data, len)
#define libssh2_sha512_final(ctx, out) \
memcpy(out, gcry_md_read(ctx, 0), SHA512_DIGEST_LENGTH), gcry_md_close(ctx)
#define libssh2_sha512(message, len, out) \
gcry_md_hash_buffer(GCRY_MD_SHA512, out, message, len)
#define libssh2_md5_ctx gcry_md_hd_t #define libssh2_md5_ctx gcry_md_hd_t
/* returns 0 in case of failure */ /* returns 0 in case of failure */
@@ -135,6 +163,11 @@
#define _libssh2_dsa_free(dsactx) gcry_sexp_release (dsactx) #define _libssh2_dsa_free(dsactx) gcry_sexp_release (dsactx)
#if LIBSSH2_ECDSA
#else
#define _libssh2_ec_key void
#endif
#define _libssh2_cipher_type(name) int name #define _libssh2_cipher_type(name) int name
#define _libssh2_cipher_ctx gcry_cipher_hd_t #define _libssh2_cipher_ctx gcry_cipher_hd_t
@@ -171,13 +204,31 @@
#define _libssh2_bn_ctx_new() 0 #define _libssh2_bn_ctx_new() 0
#define _libssh2_bn_ctx_free(bnctx) ((void)0) #define _libssh2_bn_ctx_free(bnctx) ((void)0)
#define _libssh2_bn_init() gcry_mpi_new(0) #define _libssh2_bn_init() gcry_mpi_new(0)
#define _libssh2_bn_init_from_bin() NULL /* because gcry_mpi_scan() creates a new bignum */ #define _libssh2_bn_init_from_bin() NULL /* because gcry_mpi_scan() creates a
#define _libssh2_bn_rand(bn, bits, top, bottom) gcry_mpi_randomize (bn, bits, GCRY_WEAK_RANDOM) new bignum */
#define _libssh2_bn_mod_exp(r, a, p, m, ctx) gcry_mpi_powm (r, a, p, m)
#define _libssh2_bn_set_word(bn, val) gcry_mpi_set_ui(bn, val) #define _libssh2_bn_set_word(bn, val) gcry_mpi_set_ui(bn, val)
#define _libssh2_bn_from_bin(bn, len, val) gcry_mpi_scan(&((bn)), GCRYMPI_FMT_USG, val, len, NULL) #define _libssh2_bn_from_bin(bn, len, val) \
#define _libssh2_bn_to_bin(bn, val) gcry_mpi_print (GCRYMPI_FMT_USG, val, _libssh2_bn_bytes(bn), NULL, bn) gcry_mpi_scan(&((bn)), GCRYMPI_FMT_USG, val, len, NULL)
#define _libssh2_bn_bytes(bn) (gcry_mpi_get_nbits (bn) / 8 + ((gcry_mpi_get_nbits (bn) % 8 == 0) ? 0 : 1)) #define _libssh2_bn_to_bin(bn, val) \
gcry_mpi_print(GCRYMPI_FMT_USG, val, _libssh2_bn_bytes(bn), NULL, bn)
#define _libssh2_bn_bytes(bn) \
(gcry_mpi_get_nbits (bn) / 8 + \
((gcry_mpi_get_nbits (bn) % 8 == 0) ? 0 : 1))
#define _libssh2_bn_bits(bn) gcry_mpi_get_nbits (bn) #define _libssh2_bn_bits(bn) gcry_mpi_get_nbits (bn)
#define _libssh2_bn_free(bn) gcry_mpi_release(bn) #define _libssh2_bn_free(bn) gcry_mpi_release(bn)
#define _libssh2_dh_ctx struct gcry_mpi *
#define libssh2_dh_init(dhctx) _libssh2_dh_init(dhctx)
#define libssh2_dh_key_pair(dhctx, public, g, p, group_order, bnctx) \
_libssh2_dh_key_pair(dhctx, public, g, p, group_order)
#define libssh2_dh_secret(dhctx, secret, f, p, bnctx) \
_libssh2_dh_secret(dhctx, secret, f, p)
#define libssh2_dh_dtor(dhctx) _libssh2_dh_dtor(dhctx)
extern void _libssh2_dh_init(_libssh2_dh_ctx *dhctx);
extern int _libssh2_dh_key_pair(_libssh2_dh_ctx *dhctx, _libssh2_bn *public,
_libssh2_bn *g, _libssh2_bn *p,
int group_order);
extern int _libssh2_dh_secret(_libssh2_dh_ctx *dhctx, _libssh2_bn *secret,
_libssh2_bn *f, _libssh2_bn *p);
extern void _libssh2_dh_dtor(_libssh2_dh_ctx *dhctx);

View File

@@ -64,8 +64,8 @@
/* Define if you have the gcrypt library. */ /* Define if you have the gcrypt library. */
#undef HAVE_LIBGCRYPT #undef HAVE_LIBGCRYPT
/* Define if you have the mbedtls library. */ /* Define if you have the mbedcrypto library. */
#undef HAVE_LIBMBEDTLS #undef HAVE_LIBMBEDCRYPTO
/* Define if you have the ssl library. */ /* Define if you have the ssl library. */
#undef HAVE_LIBSSL #undef HAVE_LIBSSL
@@ -79,6 +79,9 @@
/* Define to 1 if you have the <memory.h> header file. */ /* Define to 1 if you have the <memory.h> header file. */
#undef HAVE_MEMORY_H #undef HAVE_MEMORY_H
/* Define to 1 if you have the `memset_s' function. */
#undef HAVE_MEMSET_S
/* Define to 1 if you have the <netinet/in.h> header file. */ /* Define to 1 if you have the <netinet/in.h> header file. */
#undef HAVE_NETINET_IN_H #undef HAVE_NETINET_IN_H
@@ -178,10 +181,10 @@
/* Use mbedtls */ /* Use mbedtls */
#undef LIBSSH2_MBEDTLS #undef LIBSSH2_MBEDTLS
/* Use OpenSSL */ /* Use openssl */
#undef LIBSSH2_OPENSSL #undef LIBSSH2_OPENSSL
/* Use Windows CNG */ /* Use wincng */
#undef LIBSSH2_WINCNG #undef LIBSSH2_WINCNG
/* Define to the sub-directory where libtool stores uninstalled libraries. */ /* Define to the sub-directory where libtool stores uninstalled libraries. */

View File

@@ -58,18 +58,15 @@
#include <stdio.h> #include <stdio.h>
#include <time.h> #include <time.h>
/* The following CPP block should really only be in session.c and /* The following CPP block should really only be in session.c and packet.c.
packet.c. However, AIX have #define's for 'events' and 'revents' However, AIX have #define's for 'events' and 'revents' and we are using
and we are using those names in libssh2.h, so we need to include those names in libssh2.h, so we need to include the AIX headers first, to
the AIX headers first, to make sure all code is compiled with make sure all code is compiled with consistent names of these fields.
consistent names of these fields. While arguable the best would to While arguable the best would to change libssh2.h to use other names, that
change libssh2.h to use other names, that would break backwards would break backwards compatibility.
compatibility. For more information, see:
https://www.mail-archive.com/libssh2-devel%40lists.sourceforge.net/msg00003.html
https://www.mail-archive.com/libssh2-devel%40lists.sourceforge.net/msg00224.html
*/ */
#ifdef HAVE_POLL #ifdef HAVE_POLL
# include <sys/poll.h> # include <poll.h>
#else #else
# if defined(HAVE_SELECT) && !defined(WIN32) # if defined(HAVE_SELECT) && !defined(WIN32)
# ifdef HAVE_SYS_SELECT_H # ifdef HAVE_SYS_SELECT_H
@@ -166,7 +163,7 @@ static inline int writev(int sock, struct iovec *iov, int nvecs)
* padding length, payload, padding, and MAC.)." * padding length, payload, padding, and MAC.)."
*/ */
#define MAX_SSH_PACKET_LEN 35000 #define MAX_SSH_PACKET_LEN 35000
#define MAX_SHA_DIGEST_LEN SHA256_DIGEST_LENGTH #define MAX_SHA_DIGEST_LEN SHA512_DIGEST_LENGTH
#define LIBSSH2_ALLOC(session, count) \ #define LIBSSH2_ALLOC(session, count) \
session->alloc((count), &(session)->abstract) session->alloc((count), &(session)->abstract)
@@ -260,11 +257,10 @@ typedef struct kmdhgGPshakex_state_t
size_t s_packet_len; size_t s_packet_len;
size_t tmp_len; size_t tmp_len;
_libssh2_bn_ctx *ctx; _libssh2_bn_ctx *ctx;
_libssh2_bn *x; _libssh2_dh_ctx x;
_libssh2_bn *e; _libssh2_bn *e;
_libssh2_bn *f; _libssh2_bn *f;
_libssh2_bn *k; _libssh2_bn *k;
unsigned char *s;
unsigned char *f_value; unsigned char *f_value;
unsigned char *k_value; unsigned char *k_value;
unsigned char *h_sig; unsigned char *h_sig;
@@ -283,10 +279,18 @@ typedef struct key_exchange_state_low_t
kmdhgGPshakex_state_t exchange_state; kmdhgGPshakex_state_t exchange_state;
_libssh2_bn *p; /* SSH2 defined value (p_value) */ _libssh2_bn *p; /* SSH2 defined value (p_value) */
_libssh2_bn *g; /* SSH2 defined value (2) */ _libssh2_bn *g; /* SSH2 defined value (2) */
unsigned char request[13]; unsigned char request[256]; /* Must fit EC_MAX_POINT_LEN + data */
unsigned char *data; unsigned char *data;
size_t request_len; size_t request_len;
size_t data_len; size_t data_len;
_libssh2_ec_key *private_key; /* SSH2 ecdh private key */
unsigned char *public_key_oct; /* SSH2 ecdh public key octal value */
size_t public_key_oct_len; /* SSH2 ecdh public key octal value
length */
unsigned char *curve25519_public_key; /* curve25519 public key, 32
bytes */
unsigned char *curve25519_private_key; /* curve25519 private key, 32
bytes */
} key_exchange_state_low_t; } key_exchange_state_low_t;
typedef struct key_exchange_state_t typedef struct key_exchange_state_t
@@ -418,7 +422,8 @@ struct _LIBSSH2_CHANNEL
/* State variables used in libssh2_channel_receive_window_adjust() */ /* State variables used in libssh2_channel_receive_window_adjust() */
libssh2_nonblocking_states adjust_state; libssh2_nonblocking_states adjust_state;
unsigned char adjust_adjust[9]; /* packet_type(1) + channel(4) + adjustment(4) */ unsigned char adjust_adjust[9]; /* packet_type(1) + channel(4) +
adjustment(4) */
/* State variables used in libssh2_channel_read_ex() */ /* State variables used in libssh2_channel_read_ex() */
libssh2_nonblocking_states read_state; libssh2_nonblocking_states read_state;
@@ -621,6 +626,9 @@ struct _LIBSSH2_SESSION
unsigned char server_hostkey_sha1[SHA_DIGEST_LENGTH]; unsigned char server_hostkey_sha1[SHA_DIGEST_LENGTH];
int server_hostkey_sha1_valid; int server_hostkey_sha1_valid;
unsigned char server_hostkey_sha256[SHA256_DIGEST_LENGTH];
int server_hostkey_sha256_valid;
/* (remote as source of data -- packet_read ) */ /* (remote as source of data -- packet_read ) */
libssh2_endpoint_data remote; libssh2_endpoint_data remote;
@@ -654,7 +662,8 @@ struct _LIBSSH2_SESSION
struct transportpacket packet; struct transportpacket packet;
#ifdef LIBSSH2DEBUG #ifdef LIBSSH2DEBUG
int showmask; /* what debug/trace messages to display */ int showmask; /* what debug/trace messages to display */
libssh2_trace_handler_func tracehandler; /* callback to display trace messages */ libssh2_trace_handler_func tracehandler; /* callback to display trace
messages */
void *tracehandler_context; /* context for the trace handler */ void *tracehandler_context; /* context for the trace handler */
#endif #endif
@@ -862,7 +871,8 @@ struct _LIBSSH2_KEX_METHOD
{ {
const char *name; const char *name;
/* Key exchange, populates session->* and returns 0 on success, non-0 on error */ /* Key exchange, populates session->* and returns 0 on success, non-0 on
error */
int (*exchange_keys) (LIBSSH2_SESSION * session, int (*exchange_keys) (LIBSSH2_SESSION * session,
key_exchange_state_low_t * key_state); key_exchange_state_low_t * key_state);
@@ -879,8 +889,10 @@ struct _LIBSSH2_HOSTKEY_METHOD
int (*initPEM) (LIBSSH2_SESSION * session, const char *privkeyfile, int (*initPEM) (LIBSSH2_SESSION * session, const char *privkeyfile,
unsigned const char *passphrase, void **abstract); unsigned const char *passphrase, void **abstract);
int (*initPEMFromMemory) (LIBSSH2_SESSION * session, int (*initPEMFromMemory) (LIBSSH2_SESSION * session,
const char *privkeyfiledata, size_t privkeyfiledata_len, const char *privkeyfiledata,
unsigned const char *passphrase, void **abstract); size_t privkeyfiledata_len,
unsigned const char *passphrase,
void **abstract);
int (*sig_verify) (LIBSSH2_SESSION * session, const unsigned char *sig, int (*sig_verify) (LIBSSH2_SESSION * session, const unsigned char *sig,
size_t sig_len, const unsigned char *m, size_t sig_len, const unsigned char *m,
size_t m_len, void **abstract); size_t m_len, void **abstract);
@@ -896,6 +908,7 @@ struct _LIBSSH2_HOSTKEY_METHOD
struct _LIBSSH2_CRYPT_METHOD struct _LIBSSH2_CRYPT_METHOD
{ {
const char *name; const char *name;
const char *pem_annotation;
int blocksize; int blocksize;
@@ -942,7 +955,8 @@ struct _LIBSSH2_COMP_METHOD
void _libssh2_debug(LIBSSH2_SESSION * session, int context, const char *format, void _libssh2_debug(LIBSSH2_SESSION * session, int context, const char *format,
...); ...);
#else #else
#if (defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L)) || defined(__GNUC__) #if (defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L)) || \
defined(__GNUC__)
/* C99 supported and also by older GCC */ /* C99 supported and also by older GCC */
#define _libssh2_debug(x,y,z,...) do {} while (0) #define _libssh2_debug(x,y,z,...) do {} while (0)
#else #else
@@ -963,7 +977,8 @@ _libssh2_debug(LIBSSH2_SESSION * session, int context, const char *format, ...)
/* Initial packet state, prior to MAC check */ /* Initial packet state, prior to MAC check */
#define LIBSSH2_MAC_UNCONFIRMED 1 #define LIBSSH2_MAC_UNCONFIRMED 1
/* When MAC type is "none" (proto initiation phase) all packets are deemed "confirmed" */ /* When MAC type is "none" (proto initiation phase) all packets are deemed
"confirmed" */
#define LIBSSH2_MAC_CONFIRMED 0 #define LIBSSH2_MAC_CONFIRMED 0
/* Something very bad is going on */ /* Something very bad is going on */
#define LIBSSH2_MAC_INVALID -1 #define LIBSSH2_MAC_INVALID -1
@@ -988,13 +1003,18 @@ _libssh2_debug(LIBSSH2_SESSION * session, int context, const char *format, ...)
#define SSH_MSG_KEXDH_INIT 30 #define SSH_MSG_KEXDH_INIT 30
#define SSH_MSG_KEXDH_REPLY 31 #define SSH_MSG_KEXDH_REPLY 31
/* diffie-hellman-group-exchange-sha1 and diffie-hellman-group-exchange-sha256 */ /* diffie-hellman-group-exchange-sha1 and
diffie-hellman-group-exchange-sha256 */
#define SSH_MSG_KEX_DH_GEX_REQUEST_OLD 30 #define SSH_MSG_KEX_DH_GEX_REQUEST_OLD 30
#define SSH_MSG_KEX_DH_GEX_REQUEST 34 #define SSH_MSG_KEX_DH_GEX_REQUEST 34
#define SSH_MSG_KEX_DH_GEX_GROUP 31 #define SSH_MSG_KEX_DH_GEX_GROUP 31
#define SSH_MSG_KEX_DH_GEX_INIT 32 #define SSH_MSG_KEX_DH_GEX_INIT 32
#define SSH_MSG_KEX_DH_GEX_REPLY 33 #define SSH_MSG_KEX_DH_GEX_REPLY 33
/* ecdh */
#define SSH2_MSG_KEX_ECDH_INIT 30
#define SSH2_MSG_KEX_ECDH_REPLY 31
/* User Authentication */ /* User Authentication */
#define SSH_MSG_USERAUTH_REQUEST 50 #define SSH_MSG_USERAUTH_REQUEST 50
#define SSH_MSG_USERAUTH_FAILURE 51 #define SSH_MSG_USERAUTH_FAILURE 51
@@ -1049,16 +1069,37 @@ int _libssh2_kex_exchange(LIBSSH2_SESSION * session, int reexchange,
const LIBSSH2_CRYPT_METHOD **libssh2_crypt_methods(void); const LIBSSH2_CRYPT_METHOD **libssh2_crypt_methods(void);
const LIBSSH2_HOSTKEY_METHOD **libssh2_hostkey_methods(void); const LIBSSH2_HOSTKEY_METHOD **libssh2_hostkey_methods(void);
/* misc.c */
int _libssh2_bcrypt_pbkdf(const char *pass,
size_t passlen,
const uint8_t *salt,
size_t saltlen,
uint8_t *key,
size_t keylen,
unsigned int rounds);
/* pem.c */ /* pem.c */
int _libssh2_pem_parse(LIBSSH2_SESSION * session, int _libssh2_pem_parse(LIBSSH2_SESSION * session,
const char *headerbegin, const char *headerbegin,
const char *headerend, const char *headerend,
const unsigned char *passphrase,
FILE * fp, unsigned char **data, unsigned int *datalen); FILE * fp, unsigned char **data, unsigned int *datalen);
int _libssh2_pem_parse_memory(LIBSSH2_SESSION * session, int _libssh2_pem_parse_memory(LIBSSH2_SESSION * session,
const char *headerbegin, const char *headerbegin,
const char *headerend, const char *headerend,
const char *filedata, size_t filedata_len, const char *filedata, size_t filedata_len,
unsigned char **data, unsigned int *datalen); unsigned char **data, unsigned int *datalen);
/* OpenSSL keys */
int
_libssh2_openssh_pem_parse(LIBSSH2_SESSION * session,
const unsigned char *passphrase,
FILE * fp, struct string_buf **decrypted_buf);
int
_libssh2_openssh_pem_parse_memory(LIBSSH2_SESSION * session,
const unsigned char *passphrase,
const char *filedata, size_t filedata_len,
struct string_buf **decrypted_buf);
int _libssh2_pem_decode_sequence(unsigned char **data, unsigned int *datalen); int _libssh2_pem_decode_sequence(unsigned char **data, unsigned int *datalen);
int _libssh2_pem_decode_integer(unsigned char **data, unsigned int *datalen, int _libssh2_pem_decode_integer(unsigned char **data, unsigned int *datalen,
unsigned char **i, unsigned int *ilen); unsigned char **i, unsigned int *ilen);
@@ -1076,4 +1117,27 @@ void _libssh2_init_if_needed (void);
#define LIBSSH2_INT64_T_FORMAT "lld" #define LIBSSH2_INT64_T_FORMAT "lld"
#endif #endif
/* In Windows the default file mode is text but an application can override it.
Therefore we specify it explicitly. https://github.com/curl/curl/pull/258
*/
#if defined(WIN32) || defined(MSDOS)
#define FOPEN_READTEXT "rt"
#define FOPEN_WRITETEXT "wt"
#define FOPEN_APPENDTEXT "at"
#elif defined(__CYGWIN__)
/* Cygwin has specific behavior we need to address when WIN32 is not defined.
https://cygwin.com/cygwin-ug-net/using-textbinary.html
For write we want our output to have line endings of LF and be compatible with
other Cygwin utilities. For read we want to handle input that may have line
endings either CRLF or LF so 't' is appropriate.
*/
#define FOPEN_READTEXT "rt"
#define FOPEN_WRITETEXT "w"
#define FOPEN_APPENDTEXT "a"
#else
#define FOPEN_READTEXT "r"
#define FOPEN_WRITETEXT "w"
#define FOPEN_APPENDTEXT "a"
#endif
#endif /* LIBSSH2_H */ #endif /* LIBSSH2_H */

View File

@@ -1,7 +1,52 @@
/* Copyright (c) 2016, Art <https://github.com/wildart>
* All rights reserved.
*
* Redistribution and use in source and binary forms,
* with or without modification, are permitted provided
* that the following conditions are met:
*
* Redistributions of source code must retain the above
* copyright notice, this list of conditions and the
* following disclaimer.
*
* Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following
* disclaimer in the documentation and/or other materials
* provided with the distribution.
*
* Neither the name of the copyright holder nor the names
* of any other contributors may be used to endorse or
* promote products derived from this software without
* specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
* CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
* USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
* OF SUCH DAMAGE.
*/
#include "libssh2_priv.h" #include "libssh2_priv.h"
#ifdef LIBSSH2_MBEDTLS /* compile only if we build with mbedtls */ #ifdef LIBSSH2_MBEDTLS /* compile only if we build with mbedtls */
/*******************************************************************/
/*
* mbedTLS backend: Global context handles
*/
static mbedtls_entropy_context _libssh2_mbedtls_entropy;
static mbedtls_ctr_drbg_context _libssh2_mbedtls_ctr_drbg;
/*******************************************************************/ /*******************************************************************/
/* /*
* mbedTLS backend: Generic functions * mbedTLS backend: Generic functions
@@ -102,8 +147,7 @@ _libssh2_mbedtls_cipher_crypt(_libssh2_cipher_ctx *ctx,
osize = blocklen + mbedtls_cipher_get_block_size(ctx); osize = blocklen + mbedtls_cipher_get_block_size(ctx);
output = (unsigned char *)mbedtls_calloc(osize, sizeof(char)); output = (unsigned char *)mbedtls_calloc(osize, sizeof(char));
if(output) if(output) {
{
ret = mbedtls_cipher_reset(ctx); ret = mbedtls_cipher_reset(ctx);
if(!ret) if(!ret)
@@ -203,7 +247,16 @@ _libssh2_mbedtls_bignum_init(void)
return bignum; return bignum;
} }
int void
_libssh2_mbedtls_bignum_free(_libssh2_bn *bn)
{
if(bn) {
mbedtls_mpi_free(bn);
mbedtls_free(bn);
}
}
static int
_libssh2_mbedtls_bignum_random(_libssh2_bn *bn, int bits, int top, int bottom) _libssh2_mbedtls_bignum_random(_libssh2_bn *bn, int bits, int top, int bottom)
{ {
size_t len; size_t len;
@@ -214,7 +267,8 @@ _libssh2_mbedtls_bignum_random(_libssh2_bn *bn, int bits, int top, int bottom)
return -1; return -1;
len = (bits + 7) >> 3; len = (bits + 7) >> 3;
err = mbedtls_mpi_fill_random(bn, len, mbedtls_ctr_drbg_random, &_libssh2_mbedtls_ctr_drbg); err = mbedtls_mpi_fill_random(bn, len, mbedtls_ctr_drbg_random,
&_libssh2_mbedtls_ctr_drbg);
if(err) if(err)
return -1; return -1;
@@ -225,10 +279,11 @@ _libssh2_mbedtls_bignum_random(_libssh2_bn *bn, int bits, int top, int bottom)
return -1; return -1;
} }
/* If `top` is -1, the most significant bit of the random number can be zero. /* If `top` is -1, the most significant bit of the random number can be
If top is 0, the most significant bit of the random number is set to 1, zero. If top is 0, the most significant bit of the random number is
and if top is 1, the two most significant bits of the number will be set set to 1, and if top is 1, the two most significant bits of the number
to 1, so that the product of two such random numbers will always have 2*bits length. will be set to 1, so that the product of two such random numbers will
always have 2*bits length.
*/ */
for(i = 0; i <= top; ++i) { for(i = 0; i <= top; ++i) {
err = mbedtls_mpi_set_bit(bn, bits-i-1, 1); err = mbedtls_mpi_set_bit(bn, bits-i-1, 1);
@@ -281,32 +336,30 @@ _libssh2_mbedtls_rsa_new(libssh2_rsa_ctx **rsa,
else else
return -1; return -1;
/* !checksrc! disable ASSIGNWITHINCONDITION 1 */
if((ret = mbedtls_mpi_read_binary(&(ctx->E), edata, elen) ) != 0 || if((ret = mbedtls_mpi_read_binary(&(ctx->E), edata, elen) ) != 0 ||
(ret = mbedtls_mpi_read_binary(&(ctx->N), ndata, nlen) ) != 0 ) (ret = mbedtls_mpi_read_binary(&(ctx->N), ndata, nlen) ) != 0) {
{
ret = -1; ret = -1;
} }
if (!ret) if(!ret) {
{
ctx->len = mbedtls_mpi_size(&(ctx->N)); ctx->len = mbedtls_mpi_size(&(ctx->N));
} }
if (!ret && ddata) if(!ret && ddata) {
{ /* !checksrc! disable ASSIGNWITHINCONDITION 1 */
if((ret = mbedtls_mpi_read_binary(&(ctx->D), ddata, dlen) ) != 0 || if((ret = mbedtls_mpi_read_binary(&(ctx->D), ddata, dlen) ) != 0 ||
(ret = mbedtls_mpi_read_binary(&(ctx->P), pdata, plen) ) != 0 || (ret = mbedtls_mpi_read_binary(&(ctx->P), pdata, plen) ) != 0 ||
(ret = mbedtls_mpi_read_binary(&(ctx->Q), qdata, qlen) ) != 0 || (ret = mbedtls_mpi_read_binary(&(ctx->Q), qdata, qlen) ) != 0 ||
(ret = mbedtls_mpi_read_binary(&(ctx->DP), e1data, e1len) ) != 0 || (ret = mbedtls_mpi_read_binary(&(ctx->DP), e1data, e1len) ) != 0 ||
(ret = mbedtls_mpi_read_binary(&(ctx->DQ), e2data, e2len) ) != 0 || (ret = mbedtls_mpi_read_binary(&(ctx->DQ), e2data, e2len) ) != 0 ||
(ret = mbedtls_mpi_read_binary(&(ctx->QP), coeffdata, coefflen) ) != 0 ) (ret = mbedtls_mpi_read_binary(&(ctx->QP), coeffdata, coefflen) )
{ != 0) {
ret = -1; ret = -1;
} }
ret = mbedtls_rsa_check_privkey(ctx); ret = mbedtls_rsa_check_privkey(ctx);
} }
else if (!ret) else if(!ret) {
{
ret = mbedtls_rsa_check_pubkey(ctx); ret = mbedtls_rsa_check_pubkey(ctx);
} }
@@ -326,6 +379,7 @@ _libssh2_mbedtls_rsa_new_private(libssh2_rsa_ctx **rsa,
{ {
int ret; int ret;
mbedtls_pk_context pkey; mbedtls_pk_context pkey;
mbedtls_rsa_context *pk_rsa;
*rsa = (libssh2_rsa_ctx *) LIBSSH2_ALLOC(session, sizeof(libssh2_rsa_ctx)); *rsa = (libssh2_rsa_ctx *) LIBSSH2_ALLOC(session, sizeof(libssh2_rsa_ctx));
if(*rsa == NULL) if(*rsa == NULL)
@@ -335,8 +389,7 @@ _libssh2_mbedtls_rsa_new_private(libssh2_rsa_ctx **rsa,
mbedtls_pk_init(&pkey); mbedtls_pk_init(&pkey);
ret = mbedtls_pk_parse_keyfile(&pkey, filename, (char *)passphrase); ret = mbedtls_pk_parse_keyfile(&pkey, filename, (char *)passphrase);
if( ret != 0 || mbedtls_pk_get_type(&pkey) != MBEDTLS_PK_RSA) if(ret != 0 || mbedtls_pk_get_type(&pkey) != MBEDTLS_PK_RSA) {
{
mbedtls_pk_free(&pkey); mbedtls_pk_free(&pkey);
mbedtls_rsa_free(*rsa); mbedtls_rsa_free(*rsa);
LIBSSH2_FREE(session, *rsa); LIBSSH2_FREE(session, *rsa);
@@ -344,7 +397,7 @@ _libssh2_mbedtls_rsa_new_private(libssh2_rsa_ctx **rsa,
return -1; return -1;
} }
mbedtls_rsa_context *pk_rsa = mbedtls_pk_rsa(pkey); pk_rsa = mbedtls_pk_rsa(pkey);
mbedtls_rsa_copy(*rsa, pk_rsa); mbedtls_rsa_copy(*rsa, pk_rsa);
mbedtls_pk_free(&pkey); mbedtls_pk_free(&pkey);
@@ -360,17 +413,33 @@ _libssh2_mbedtls_rsa_new_private_frommemory(libssh2_rsa_ctx **rsa,
{ {
int ret; int ret;
mbedtls_pk_context pkey; mbedtls_pk_context pkey;
mbedtls_rsa_context *pk_rsa;
void *filedata_nullterm;
size_t pwd_len;
*rsa = (libssh2_rsa_ctx *) mbedtls_calloc(1, sizeof(libssh2_rsa_ctx)); *rsa = (libssh2_rsa_ctx *) mbedtls_calloc(1, sizeof(libssh2_rsa_ctx));
if(*rsa == NULL) if(*rsa == NULL)
return -1; return -1;
/*
mbedtls checks in "mbedtls/pkparse.c:1184" if "key[keylen - 1] != '\0'"
private-key from memory will fail if the last byte is not a null byte
*/
filedata_nullterm = mbedtls_calloc(filedata_len + 1, 1);
if(filedata_nullterm == NULL) {
return -1;
}
memcpy(filedata_nullterm, filedata, filedata_len);
mbedtls_pk_init(&pkey); mbedtls_pk_init(&pkey);
ret = mbedtls_pk_parse_key(&pkey, (unsigned char *)filedata, pwd_len = passphrase != NULL ? strlen((const char *)passphrase) : 0;
filedata_len, NULL, 0); ret = mbedtls_pk_parse_key(&pkey, (unsigned char *)filedata_nullterm,
if( ret != 0 || mbedtls_pk_get_type(&pkey) != MBEDTLS_PK_RSA) filedata_len + 1,
{ passphrase, pwd_len);
_libssh2_mbedtls_safe_free(filedata_nullterm, filedata_len);
if(ret != 0 || mbedtls_pk_get_type(&pkey) != MBEDTLS_PK_RSA) {
mbedtls_pk_free(&pkey); mbedtls_pk_free(&pkey);
mbedtls_rsa_free(*rsa); mbedtls_rsa_free(*rsa);
LIBSSH2_FREE(session, *rsa); LIBSSH2_FREE(session, *rsa);
@@ -378,7 +447,7 @@ _libssh2_mbedtls_rsa_new_private_frommemory(libssh2_rsa_ctx **rsa,
return -1; return -1;
} }
mbedtls_rsa_context *pk_rsa = mbedtls_pk_rsa(pkey); pk_rsa = mbedtls_pk_rsa(pkey);
mbedtls_rsa_copy(*rsa, pk_rsa); mbedtls_rsa_copy(*rsa, pk_rsa);
mbedtls_pk_free(&pkey); mbedtls_pk_free(&pkey);
@@ -400,7 +469,8 @@ _libssh2_mbedtls_rsa_sha1_verify(libssh2_rsa_ctx *rsa,
return -1; /* failure */ return -1; /* failure */
ret = mbedtls_rsa_pkcs1_verify(rsa, NULL, NULL, MBEDTLS_RSA_PUBLIC, ret = mbedtls_rsa_pkcs1_verify(rsa, NULL, NULL, MBEDTLS_RSA_PUBLIC,
MBEDTLS_MD_SHA1, SHA_DIGEST_LENGTH, hash, sig); MBEDTLS_MD_SHA1, SHA_DIGEST_LENGTH,
hash, sig);
return (ret == 0) ? 0 : -1; return (ret == 0) ? 0 : -1;
} }
@@ -498,36 +568,38 @@ _libssh2_mbedtls_pub_priv_key(LIBSSH2_SESSION *session,
unsigned char *key = NULL, *mth = NULL; unsigned char *key = NULL, *mth = NULL;
size_t keylen = 0, mthlen = 0; size_t keylen = 0, mthlen = 0;
int ret; int ret;
mbedtls_rsa_context *rsa;
if( mbedtls_pk_get_type(pkey) != MBEDTLS_PK_RSA ) if(mbedtls_pk_get_type(pkey) != MBEDTLS_PK_RSA) {
{
mbedtls_pk_free(pkey); mbedtls_pk_free(pkey);
return _libssh2_error(session, LIBSSH2_ERROR_FILE, return _libssh2_error(session, LIBSSH2_ERROR_FILE,
"Key type not supported"); "Key type not supported");
} }
// write method /* write method */
mthlen = 7; mthlen = 7;
mth = LIBSSH2_ALLOC(session, mthlen); mth = LIBSSH2_ALLOC(session, mthlen);
if(mth) { if(mth) {
memcpy(mth, "ssh-rsa", mthlen); memcpy(mth, "ssh-rsa", mthlen);
} else { }
else {
ret = -1; ret = -1;
} }
mbedtls_rsa_context *rsa = mbedtls_pk_rsa(*pkey); rsa = mbedtls_pk_rsa(*pkey);
key = gen_publickey_from_rsa(session, rsa, &keylen); key = gen_publickey_from_rsa(session, rsa, &keylen);
if(key == NULL) { if(key == NULL) {
ret = -1; ret = -1;
} }
// write output /* write output */
if(ret) { if(ret) {
if(mth) if(mth)
LIBSSH2_FREE(session, mth); LIBSSH2_FREE(session, mth);
if(key) if(key)
LIBSSH2_FREE(session, key); LIBSSH2_FREE(session, key);
} else { }
else {
*method = mth; *method = mth;
*method_len = mthlen; *method_len = mthlen;
*pubkeydata = key; *pubkeydata = key;
@@ -552,8 +624,7 @@ _libssh2_mbedtls_pub_priv_keyfile(LIBSSH2_SESSION *session,
mbedtls_pk_init(&pkey); mbedtls_pk_init(&pkey);
ret = mbedtls_pk_parse_keyfile(&pkey, privatekey, passphrase); ret = mbedtls_pk_parse_keyfile(&pkey, privatekey, passphrase);
if( ret != 0 ) if(ret != 0) {
{
mbedtls_strerror(ret, (char *)buf, sizeof(buf)); mbedtls_strerror(ret, (char *)buf, sizeof(buf));
mbedtls_pk_free(&pkey); mbedtls_pk_free(&pkey);
return _libssh2_error(session, LIBSSH2_ERROR_FILE, buf); return _libssh2_error(session, LIBSSH2_ERROR_FILE, buf);
@@ -580,12 +651,29 @@ _libssh2_mbedtls_pub_priv_keyfilememory(LIBSSH2_SESSION *session,
mbedtls_pk_context pkey; mbedtls_pk_context pkey;
char buf[1024]; char buf[1024];
int ret; int ret;
void *privatekeydata_nullterm;
size_t pwd_len;
/*
mbedtls checks in "mbedtls/pkparse.c:1184" if "key[keylen - 1] != '\0'"
private-key from memory will fail if the last byte is not a null byte
*/
privatekeydata_nullterm = mbedtls_calloc(privatekeydata_len + 1, 1);
if(privatekeydata_nullterm == NULL) {
return -1;
}
memcpy(privatekeydata_nullterm, privatekeydata, privatekeydata_len);
mbedtls_pk_init(&pkey); mbedtls_pk_init(&pkey);
ret = mbedtls_pk_parse_key(&pkey, (unsigned char *)privatekeydata,
privatekeydata_len, NULL, 0); pwd_len = passphrase != NULL ? strlen((const char *)passphrase) : 0;
if( ret != 0 ) ret = mbedtls_pk_parse_key(&pkey,
{ (unsigned char *)privatekeydata_nullterm,
privatekeydata_len + 1,
(const unsigned char *)passphrase, pwd_len);
_libssh2_mbedtls_safe_free(privatekeydata_nullterm, privatekeydata_len);
if(ret != 0) {
mbedtls_strerror(ret, (char *)buf, sizeof(buf)); mbedtls_strerror(ret, (char *)buf, sizeof(buf));
mbedtls_pk_free(&pkey); mbedtls_pk_free(&pkey);
return _libssh2_error(session, LIBSSH2_ERROR_FILE, buf); return _libssh2_error(session, LIBSSH2_ERROR_FILE, buf);
@@ -603,4 +691,43 @@ void _libssh2_init_aes_ctr(void)
{ {
/* no implementation */ /* no implementation */
} }
/*******************************************************************/
/*
* mbedTLS backend: Diffie-Hellman functions
*/
void
_libssh2_dh_init(_libssh2_dh_ctx *dhctx)
{
*dhctx = _libssh2_mbedtls_bignum_init(); /* Random from client */
}
int
_libssh2_dh_key_pair(_libssh2_dh_ctx *dhctx, _libssh2_bn *public,
_libssh2_bn *g, _libssh2_bn *p, int group_order)
{
/* Generate x and e */
_libssh2_mbedtls_bignum_random(*dhctx, group_order * 8 - 1, 0, -1);
mbedtls_mpi_exp_mod(public, g, *dhctx, p, NULL);
return 0;
}
int
_libssh2_dh_secret(_libssh2_dh_ctx *dhctx, _libssh2_bn *secret,
_libssh2_bn *f, _libssh2_bn *p)
{
/* Compute the shared secret */
mbedtls_mpi_exp_mod(secret, f, *dhctx, p, NULL);
return 0;
}
void
_libssh2_dh_dtor(_libssh2_dh_ctx *dhctx)
{
_libssh2_mbedtls_bignum_free(*dhctx);
*dhctx = NULL;
}
#endif /* LIBSSH2_MBEDTLS */ #endif /* LIBSSH2_MBEDTLS */

View File

@@ -1,3 +1,40 @@
/* Copyright (c) 2016, Art <https://github.com/wildart>
* All rights reserved.
*
* Redistribution and use in source and binary forms,
* with or without modification, are permitted provided
* that the following conditions are met:
*
* Redistributions of source code must retain the above
* copyright notice, this list of conditions and the
* following disclaimer.
*
* Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following
* disclaimer in the documentation and/or other materials
* provided with the distribution.
*
* Neither the name of the copyright holder nor the names
* of any other contributors may be used to endorse or
* promote products derived from this software without
* specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
* CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
* USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
* OF SUCH DAMAGE.
*/
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <string.h>
@@ -27,19 +64,21 @@
#define LIBSSH2_RSA 1 #define LIBSSH2_RSA 1
#define LIBSSH2_DSA 0 #define LIBSSH2_DSA 0
#define LIBSSH2_ECDSA 0
#define LIBSSH2_ED25519 0
#define MD5_DIGEST_LENGTH 16 #define MD5_DIGEST_LENGTH 16
#define SHA_DIGEST_LENGTH 20 #define SHA_DIGEST_LENGTH 20
#define SHA256_DIGEST_LENGTH 32 #define SHA256_DIGEST_LENGTH 32
#define SHA384_DIGEST_LENGTH 48
#define SHA512_DIGEST_LENGTH 64 #define SHA512_DIGEST_LENGTH 64
/*******************************************************************/ #define EC_MAX_POINT_LEN ((528 * 2 / 8) + 1)
/*
* mbedTLS backend: Global context handles
*/
mbedtls_entropy_context _libssh2_mbedtls_entropy; #if LIBSSH2_ECDSA
mbedtls_ctr_drbg_context _libssh2_mbedtls_ctr_drbg; #else
#define _libssh2_ec_key void
#endif
/*******************************************************************/ /*******************************************************************/
/* /*
@@ -80,6 +119,8 @@ mbedtls_ctr_drbg_context _libssh2_mbedtls_ctr_drbg;
_libssh2_mbedtls_hash_init(pctx, MBEDTLS_MD_RIPEMD160, key, keylen) _libssh2_mbedtls_hash_init(pctx, MBEDTLS_MD_RIPEMD160, key, keylen)
#define libssh2_hmac_sha256_init(pctx, key, keylen) \ #define libssh2_hmac_sha256_init(pctx, key, keylen) \
_libssh2_mbedtls_hash_init(pctx, MBEDTLS_MD_SHA256, key, keylen) _libssh2_mbedtls_hash_init(pctx, MBEDTLS_MD_SHA256, key, keylen)
#define libssh2_hmac_sha384_init(pctx, key, keylen) \
_libssh2_mbedtls_hash_init(pctx, MBEDTLS_MD_SHA384, key, keylen)
#define libssh2_hmac_sha512_init(pctx, key, keylen) \ #define libssh2_hmac_sha512_init(pctx, key, keylen) \
_libssh2_mbedtls_hash_init(pctx, MBEDTLS_MD_SHA512, key, keylen) _libssh2_mbedtls_hash_init(pctx, MBEDTLS_MD_SHA512, key, keylen)
@@ -117,6 +158,23 @@ mbedtls_ctr_drbg_context _libssh2_mbedtls_ctr_drbg;
_libssh2_mbedtls_hash(data, datalen, MBEDTLS_MD_SHA256, hash) _libssh2_mbedtls_hash(data, datalen, MBEDTLS_MD_SHA256, hash)
/*******************************************************************/
/*
* mbedTLS backend: SHA384 functions
*/
#define libssh2_sha384_ctx mbedtls_md_context_t
#define libssh2_sha384_init(pctx) \
_libssh2_mbedtls_hash_init(pctx, MBEDTLS_MD_SHA384, NULL, 0)
#define libssh2_sha384_update(ctx, data, datalen) \
mbedtls_md_update(&ctx, (unsigned char *) data, datalen)
#define libssh2_sha384_final(ctx, hash) \
_libssh2_mbedtls_hash_final(&ctx, hash)
#define libssh2_sha384(data, datalen, hash) \
_libssh2_mbedtls_hash(data, datalen, MBEDTLS_MD_SHA384, hash)
/*******************************************************************/ /*******************************************************************/
/* /*
* mbedTLS backend: SHA512 functions * mbedTLS backend: SHA512 functions
@@ -239,10 +297,6 @@ mbedtls_ctr_drbg_context _libssh2_mbedtls_ctr_drbg;
_libssh2_mbedtls_bignum_init() _libssh2_mbedtls_bignum_init()
#define _libssh2_bn_init_from_bin() \ #define _libssh2_bn_init_from_bin() \
_libssh2_mbedtls_bignum_init() _libssh2_mbedtls_bignum_init()
#define _libssh2_bn_rand(bn, bits, top, bottom) \
_libssh2_mbedtls_bignum_random(bn, bits, top, bottom)
#define _libssh2_bn_mod_exp(r, a, p, m, ctx) \
mbedtls_mpi_exp_mod(r, a, p, m, NULL)
#define _libssh2_bn_set_word(bn, word) \ #define _libssh2_bn_set_word(bn, word) \
mbedtls_mpi_lset(bn, word) mbedtls_mpi_lset(bn, word)
#define _libssh2_bn_from_bin(bn, len, bin) \ #define _libssh2_bn_from_bin(bn, len, bin) \
@@ -254,7 +308,21 @@ mbedtls_ctr_drbg_context _libssh2_mbedtls_ctr_drbg;
#define _libssh2_bn_bits(bn) \ #define _libssh2_bn_bits(bn) \
mbedtls_mpi_bitlen(bn) mbedtls_mpi_bitlen(bn)
#define _libssh2_bn_free(bn) \ #define _libssh2_bn_free(bn) \
mbedtls_mpi_free(bn) _libssh2_mbedtls_bignum_free(bn)
/*******************************************************************/
/*
* mbedTLS backend: Diffie-Hellman support.
*/
#define _libssh2_dh_ctx mbedtls_mpi *
#define libssh2_dh_init(dhctx) _libssh2_dh_init(dhctx)
#define libssh2_dh_key_pair(dhctx, public, g, p, group_order, bnctx) \
_libssh2_dh_key_pair(dhctx, public, g, p, group_order)
#define libssh2_dh_secret(dhctx, secret, f, p, bnctx) \
_libssh2_dh_secret(dhctx, secret, f, p)
#define libssh2_dh_dtor(dhctx) _libssh2_dh_dtor(dhctx)
/*******************************************************************/ /*******************************************************************/
@@ -302,9 +370,6 @@ _libssh2_mbedtls_bignum_init(void);
void void
_libssh2_mbedtls_bignum_free(_libssh2_bn *bn); _libssh2_mbedtls_bignum_free(_libssh2_bn *bn);
int
_libssh2_mbedtls_bignum_random(_libssh2_bn *bn, int bits, int top, int bottom);
int int
_libssh2_mbedtls_rsa_new(libssh2_rsa_ctx **rsa, _libssh2_mbedtls_rsa_new(libssh2_rsa_ctx **rsa,
const unsigned char *edata, const unsigned char *edata,
@@ -369,3 +434,14 @@ _libssh2_mbedtls_pub_priv_keyfilememory(LIBSSH2_SESSION *session,
const char *privatekeydata, const char *privatekeydata,
size_t privatekeydata_len, size_t privatekeydata_len,
const char *passphrase); const char *passphrase);
extern void
_libssh2_dh_init(_libssh2_dh_ctx *dhctx);
extern int
_libssh2_dh_key_pair(_libssh2_dh_ctx *dhctx, _libssh2_bn *public,
_libssh2_bn *g, _libssh2_bn *p, int group_order);
extern int
_libssh2_dh_secret(_libssh2_dh_ctx *dhctx, _libssh2_bn *secret,
_libssh2_bn *f, _libssh2_bn *p);
extern void
_libssh2_dh_dtor(_libssh2_dh_ctx *dhctx);

View File

@@ -1,5 +1,5 @@
/* Copyright (c) 2004-2007 Sara Golemon <sarag@libssh2.org> /* Copyright (c) 2004-2007 Sara Golemon <sarag@libssh2.org>
* Copyright (c) 2009-2014 by Daniel Stenberg * Copyright (c) 2009-2019 by Daniel Stenberg
* Copyright (c) 2010 Simon Josefsson * Copyright (c) 2010 Simon Josefsson
* All rights reserved. * All rights reserved.
* *
@@ -39,6 +39,11 @@
#include "libssh2_priv.h" #include "libssh2_priv.h"
#include "misc.h" #include "misc.h"
#include "blf.h"
#ifdef HAVE_STDLIB_H
#include <stdlib.h>
#endif
#ifdef HAVE_UNISTD_H #ifdef HAVE_UNISTD_H
#include <unistd.h> #include <unistd.h>
@@ -48,10 +53,17 @@
#include <sys/time.h> #include <sys/time.h>
#endif #endif
#if defined(HAVE_DECL_SECUREZEROMEMORY) && HAVE_DECL_SECUREZEROMEMORY
#ifdef HAVE_WINDOWS_H
#include <windows.h>
#endif
#endif
#include <stdio.h> #include <stdio.h>
#include <errno.h> #include <errno.h>
int _libssh2_error_flags(LIBSSH2_SESSION* session, int errcode, const char* errmsg, int errflags) int _libssh2_error_flags(LIBSSH2_SESSION* session, int errcode,
const char *errmsg, int errflags)
{ {
if(session->err_flags & LIBSSH2_ERR_FLAG_DUP) if(session->err_flags & LIBSSH2_ERR_FLAG_DUP)
LIBSSH2_FREE(session, (char *)session->err_msg); LIBSSH2_FREE(session, (char *)session->err_msg);
@@ -275,7 +287,8 @@ libssh2_base64_decode(LIBSSH2_SESSION *session, char **data,
} }
for(s = (unsigned char *) src; ((char *) s) < (src + src_len); s++) { for(s = (unsigned char *) src; ((char *) s) < (src + src_len); s++) {
if ((v = base64_reverse_table[*s]) < 0) v = base64_reverse_table[*s];
if(v < 0)
continue; continue;
switch(i % 4) { switch(i % 4) {
case 0: case 0:
@@ -299,6 +312,7 @@ libssh2_base64_decode(LIBSSH2_SESSION *session, char **data,
/* Invalid -- We have a byte which belongs exclusively to a partial /* Invalid -- We have a byte which belongs exclusively to a partial
octet */ octet */
LIBSSH2_FREE(session, *data); LIBSSH2_FREE(session, *data);
*data = NULL;
return _libssh2_error(session, LIBSSH2_ERROR_INVAL, "Invalid base64"); return _libssh2_error(session, LIBSSH2_ERROR_INVAL, "Invalid base64");
} }
@@ -329,7 +343,8 @@ size_t _libssh2_base64_encode(LIBSSH2_SESSION *session,
char *base64data; char *base64data;
const char *indata = inp; const char *indata = inp;
*outptr = NULL; /* set to NULL in case of failure before we reach the end */ *outptr = NULL; /* set to NULL in case of failure before we reach the
end */
if(0 == insize) if(0 == insize)
insize = strlen(indata); insize = strlen(indata);
@@ -621,8 +636,7 @@ int __cdecl _libssh2_gettimeofday(struct timeval *tp, void *tzp)
FILETIME ft; FILETIME ft;
} _now; } _now;
(void)tzp; (void)tzp;
if(tp) if(tp) {
{
GetSystemTimeAsFileTime(&_now.ft); GetSystemTimeAsFileTime(&_now.ft);
tp->tv_usec = (long)((_now.ns100 / 10) % 1000000); tp->tv_usec = (long)((_now.ns100 / 10) % 1000000);
tp->tv_sec = (long)((_now.ns100 - _W32_FT_OFFSET) / 10000000); tp->tv_sec = (long)((_now.ns100 - _W32_FT_OFFSET) / 10000000);
@@ -643,3 +657,218 @@ void *_libssh2_calloc(LIBSSH2_SESSION* session, size_t size)
} }
return p; return p;
} }
/* XOR operation on buffers input1 and input2, result in output.
It is safe to use an input buffer as the output buffer. */
void _libssh2_xor_data(unsigned char *output,
const unsigned char *input1,
const unsigned char *input2,
size_t length)
{
size_t i;
for(i = 0; i < length; i++)
*output++ = *input1++ ^ *input2++;
}
/* Increments an AES CTR buffer to prepare it for use with the
next AES block. */
void _libssh2_aes_ctr_increment(unsigned char *ctr,
size_t length)
{
unsigned char *pc;
unsigned int val, carry;
pc = ctr + length - 1;
carry = 1;
while(pc >= ctr) {
val = (unsigned int)*pc + carry;
*pc-- = val & 0xFF;
carry = val >> 8;
}
}
#ifdef WIN32
static void * (__cdecl * const volatile memset_libssh)(void *, int, size_t) =
memset;
#else
static void * (* const volatile memset_libssh)(void *, int, size_t) = memset;
#endif
void _libssh2_explicit_zero(void *buf, size_t size)
{
#if defined(HAVE_DECL_SECUREZEROMEMORY) && HAVE_DECL_SECUREZEROMEMORY
SecureZeroMemory(buf, size);
(void)memset_libssh; /* Silence unused variable warning */
#elif defined(HAVE_MEMSET_S)
(void)memset_s(buf, size, 0, size);
(void)memset_libssh; /* Silence unused variable warning */
#else
memset_libssh(buf, 0, size);
#endif
}
/* String buffer */
struct string_buf* _libssh2_string_buf_new(LIBSSH2_SESSION *session)
{
struct string_buf *ret;
ret = _libssh2_calloc(session, sizeof(*ret));
if(ret == NULL)
return NULL;
return ret;
}
void _libssh2_string_buf_free(LIBSSH2_SESSION *session, struct string_buf *buf)
{
if(buf == NULL)
return;
if(buf->data != NULL)
LIBSSH2_FREE(session, buf->data);
LIBSSH2_FREE(session, buf);
buf = NULL;
}
int _libssh2_get_u32(struct string_buf *buf, uint32_t *out)
{
if(!_libssh2_check_length(buf, 4)) {
return -1;
}
*out = _libssh2_ntohu32(buf->dataptr);
buf->dataptr += 4;
return 0;
}
int _libssh2_get_u64(struct string_buf *buf, libssh2_uint64_t *out)
{
if(!_libssh2_check_length(buf, 8)) {
return -1;
}
*out = _libssh2_ntohu64(buf->dataptr);
buf->dataptr += 8;
return 0;
}
int _libssh2_match_string(struct string_buf *buf, const char *match)
{
unsigned char *out;
size_t len = 0;
if(_libssh2_get_string(buf, &out, &len) || len != strlen(match) ||
strncmp((char *)out, match, strlen(match)) != 0) {
return -1;
}
return 0;
}
int _libssh2_get_string(struct string_buf *buf, unsigned char **outbuf,
size_t *outlen)
{
uint32_t data_len;
if(_libssh2_get_u32(buf, &data_len) != 0) {
return -1;
}
if(!_libssh2_check_length(buf, data_len)) {
return -1;
}
*outbuf = buf->dataptr;
buf->dataptr += data_len;
if(outlen)
*outlen = (size_t)data_len;
return 0;
}
int _libssh2_copy_string(LIBSSH2_SESSION *session, struct string_buf *buf,
unsigned char **outbuf, size_t *outlen)
{
size_t str_len;
unsigned char *str;
if(_libssh2_get_string(buf, &str, &str_len)) {
return -1;
}
*outbuf = LIBSSH2_ALLOC(session, str_len);
if(*outbuf) {
memcpy(*outbuf, str, str_len);
}
else {
return -1;
}
if(outlen)
*outlen = str_len;
return 0;
}
int _libssh2_get_bignum_bytes(struct string_buf *buf, unsigned char **outbuf,
size_t *outlen)
{
uint32_t data_len;
uint32_t bn_len;
unsigned char *bnptr;
if(_libssh2_get_u32(buf, &data_len)) {
return -1;
}
if(!_libssh2_check_length(buf, data_len)) {
return -1;
}
bn_len = data_len;
bnptr = buf->dataptr;
/* trim leading zeros */
while(bn_len > 0 && *bnptr == 0x00) {
bn_len--;
bnptr++;
}
*outbuf = bnptr;
buf->dataptr += data_len;
if(outlen)
*outlen = (size_t)bn_len;
return 0;
}
/* Given the current location in buf, _libssh2_check_length ensures
callers can read the next len number of bytes out of the buffer
before reading the buffer content */
int _libssh2_check_length(struct string_buf *buf, size_t len)
{
unsigned char *endp = &buf->data[buf->len];
size_t left = endp - buf->dataptr;
return ((len <= left) && (left <= buf->len));
}
/* Wrappers */
int _libssh2_bcrypt_pbkdf(const char *pass,
size_t passlen,
const uint8_t *salt,
size_t saltlen,
uint8_t *key,
size_t keylen,
unsigned int rounds)
{
/* defined in bcrypt_pbkdf.c */
return bcrypt_pbkdf(pass,
passlen,
salt,
saltlen,
key,
keylen,
rounds);
}

View File

@@ -1,6 +1,6 @@
#ifndef __LIBSSH2_MISC_H #ifndef __LIBSSH2_MISC_H
#define __LIBSSH2_MISC_H #define __LIBSSH2_MISC_H
/* Copyright (c) 2009-2014 by Daniel Stenberg /* Copyright (c) 2009-2019 by Daniel Stenberg
* *
* All rights reserved. * All rights reserved.
* *
@@ -49,7 +49,14 @@ struct list_node {
struct list_head *head; struct list_head *head;
}; };
int _libssh2_error_flags(LIBSSH2_SESSION* session, int errcode, const char* errmsg, int errflags); struct string_buf {
unsigned char *data;
unsigned char *dataptr;
size_t len;
};
int _libssh2_error_flags(LIBSSH2_SESSION* session, int errcode,
const char *errmsg, int errflags);
int _libssh2_error(LIBSSH2_SESSION* session, int errcode, const char *errmsg); int _libssh2_error(LIBSSH2_SESSION* session, int errcode, const char *errmsg);
void _libssh2_list_init(struct list_head *head); void _libssh2_list_init(struct list_head *head);
@@ -70,7 +77,7 @@ void *_libssh2_list_prev(struct list_node *node);
/* remove this node from the list */ /* remove this node from the list */
void _libssh2_list_remove(struct list_node *entry); void _libssh2_list_remove(struct list_node *entry);
size_t _libssh2_base64_encode(struct _LIBSSH2_SESSION *session, size_t _libssh2_base64_encode(LIBSSH2_SESSION *session,
const char *inp, size_t insize, char **outptr); const char *inp, size_t insize, char **outptr);
unsigned int _libssh2_ntohu32(const unsigned char *buf); unsigned int _libssh2_ntohu32(const unsigned char *buf);
@@ -79,6 +86,21 @@ void _libssh2_htonu32(unsigned char *buf, uint32_t val);
void _libssh2_store_u32(unsigned char **buf, uint32_t value); void _libssh2_store_u32(unsigned char **buf, uint32_t value);
void _libssh2_store_str(unsigned char **buf, const char *str, size_t len); void _libssh2_store_str(unsigned char **buf, const char *str, size_t len);
void *_libssh2_calloc(LIBSSH2_SESSION *session, size_t size); void *_libssh2_calloc(LIBSSH2_SESSION *session, size_t size);
void _libssh2_explicit_zero(void *buf, size_t size);
struct string_buf* _libssh2_string_buf_new(LIBSSH2_SESSION *session);
void _libssh2_string_buf_free(LIBSSH2_SESSION *session,
struct string_buf *buf);
int _libssh2_get_u32(struct string_buf *buf, uint32_t *out);
int _libssh2_get_u64(struct string_buf *buf, libssh2_uint64_t *out);
int _libssh2_match_string(struct string_buf *buf, const char *match);
int _libssh2_get_string(struct string_buf *buf, unsigned char **outbuf,
size_t *outlen);
int _libssh2_copy_string(LIBSSH2_SESSION* session, struct string_buf *buf,
unsigned char **outbuf, size_t *outlen);
int _libssh2_get_bignum_bytes(struct string_buf *buf, unsigned char **outbuf,
size_t *outlen);
int _libssh2_check_length(struct string_buf *buf, size_t requested_len);
#if defined(LIBSSH2_WIN32) && !defined(__MINGW32__) && !defined(__CYGWIN__) #if defined(LIBSSH2_WIN32) && !defined(__MINGW32__) && !defined(__CYGWIN__)
/* provide a private one */ /* provide a private one */
@@ -93,4 +115,11 @@ int __cdecl _libssh2_gettimeofday(struct timeval *tp, void *tzp);
#endif #endif
#endif #endif
void _libssh2_xor_data(unsigned char *output,
const unsigned char *input1,
const unsigned char *input2,
size_t length);
void _libssh2_aes_ctr_increment(unsigned char *ctr, size_t length);
#endif /* _LIBSSH2_MISC_H */ #endif /* _LIBSSH2_MISC_H */

File diff suppressed because it is too large Load Diff

View File

@@ -40,7 +40,9 @@
#include <openssl/opensslconf.h> #include <openssl/opensslconf.h>
#include <openssl/sha.h> #include <openssl/sha.h>
#include <openssl/rsa.h> #include <openssl/rsa.h>
#ifndef OPENSSL_NO_ENGINE
#include <openssl/engine.h> #include <openssl/engine.h>
#endif
#ifndef OPENSSL_NO_DSA #ifndef OPENSSL_NO_DSA
#include <openssl/dsa.h> #include <openssl/dsa.h>
#endif #endif
@@ -70,6 +72,20 @@
# define LIBSSH2_DSA 1 # define LIBSSH2_DSA 1
#endif #endif
#ifdef OPENSSL_NO_ECDSA
# define LIBSSH2_ECDSA 0
#else
# define LIBSSH2_ECDSA 1
#endif
#if OPENSSL_VERSION_NUMBER >= 0x10101000L && \
!defined(LIBRESSL_VERSION_NUMBER)
# define LIBSSH2_ED25519 1
#else
# define LIBSSH2_ED25519 0
#endif
#ifdef OPENSSL_NO_MD5 #ifdef OPENSSL_NO_MD5
# define LIBSSH2_MD5 0 # define LIBSSH2_MD5 0
#else #else
@@ -117,6 +133,8 @@
# define LIBSSH2_3DES 1 # define LIBSSH2_3DES 1
#endif #endif
#define EC_MAX_POINT_LEN ((528 * 2 / 8) + 1)
#define _libssh2_random(buf, len) RAND_bytes ((buf), (len)) #define _libssh2_random(buf, len) RAND_bytes ((buf), (len))
#define libssh2_prepare_iovec(vec, len) /* Empty. */ #define libssh2_prepare_iovec(vec, len) /* Empty. */
@@ -160,13 +178,62 @@ int _libssh2_sha256_init(libssh2_sha256_ctx *ctx);
EVP_MD_CTX_free(ctx); \ EVP_MD_CTX_free(ctx); \
} while(0) } while(0)
#else #else
#define libssh2_sha256_update(ctx, data, len) EVP_DigestUpdate(&(ctx), data, len) #define libssh2_sha256_update(ctx, data, len) \
EVP_DigestUpdate(&(ctx), data, len)
#define libssh2_sha256_final(ctx, out) EVP_DigestFinal(&(ctx), out, NULL) #define libssh2_sha256_final(ctx, out) EVP_DigestFinal(&(ctx), out, NULL)
#endif #endif
int _libssh2_sha256(const unsigned char *message, unsigned long len, int _libssh2_sha256(const unsigned char *message, unsigned long len,
unsigned char *out); unsigned char *out);
#define libssh2_sha256(x,y,z) _libssh2_sha256(x,y,z) #define libssh2_sha256(x,y,z) _libssh2_sha256(x,y,z)
#ifdef HAVE_OPAQUE_STRUCTS
#define libssh2_sha384_ctx EVP_MD_CTX *
#else
#define libssh2_sha384_ctx EVP_MD_CTX
#endif
/* returns 0 in case of failure */
int _libssh2_sha384_init(libssh2_sha384_ctx *ctx);
#define libssh2_sha384_init(x) _libssh2_sha384_init(x)
#ifdef HAVE_OPAQUE_STRUCTS
#define libssh2_sha384_update(ctx, data, len) EVP_DigestUpdate(ctx, data, len)
#define libssh2_sha384_final(ctx, out) do { \
EVP_DigestFinal(ctx, out, NULL); \
EVP_MD_CTX_free(ctx); \
} while(0)
#else
#define libssh2_sha384_update(ctx, data, len) \
EVP_DigestUpdate(&(ctx), data, len)
#define libssh2_sha384_final(ctx, out) EVP_DigestFinal(&(ctx), out, NULL)
#endif
int _libssh2_sha384(const unsigned char *message, unsigned long len,
unsigned char *out);
#define libssh2_sha384(x,y,z) _libssh2_sha384(x,y,z)
#ifdef HAVE_OPAQUE_STRUCTS
#define libssh2_sha512_ctx EVP_MD_CTX *
#else
#define libssh2_sha512_ctx EVP_MD_CTX
#endif
/* returns 0 in case of failure */
int _libssh2_sha512_init(libssh2_sha512_ctx *ctx);
#define libssh2_sha512_init(x) _libssh2_sha512_init(x)
#ifdef HAVE_OPAQUE_STRUCTS
#define libssh2_sha512_update(ctx, data, len) EVP_DigestUpdate(ctx, data, len)
#define libssh2_sha512_final(ctx, out) do { \
EVP_DigestFinal(ctx, out, NULL); \
EVP_MD_CTX_free(ctx); \
} while(0)
#else
#define libssh2_sha512_update(ctx, data, len) \
EVP_DigestUpdate(&(ctx), data, len)
#define libssh2_sha512_final(ctx, out) EVP_DigestFinal(&(ctx), out, NULL)
#endif
int _libssh2_sha512(const unsigned char *message, unsigned long len,
unsigned char *out);
#define libssh2_sha512(x,y,z) _libssh2_sha512(x,y,z)
#ifdef HAVE_OPAQUE_STRUCTS #ifdef HAVE_OPAQUE_STRUCTS
#define libssh2_md5_ctx EVP_MD_CTX * #define libssh2_md5_ctx EVP_MD_CTX *
#else #else
@@ -226,12 +293,10 @@ int _libssh2_md5_init(libssh2_md5_ctx *ctx);
#define libssh2_hmac_cleanup(ctx) HMAC_cleanup(ctx) #define libssh2_hmac_cleanup(ctx) HMAC_cleanup(ctx)
#endif #endif
#define libssh2_crypto_init() \ extern void _libssh2_openssl_crypto_init(void);
OpenSSL_add_all_algorithms(); \ extern void _libssh2_openssl_crypto_exit(void);
ENGINE_load_builtin_engines(); \ #define libssh2_crypto_init() _libssh2_openssl_crypto_init()
ENGINE_register_all_complete() #define libssh2_crypto_exit() _libssh2_openssl_crypto_exit()
#define libssh2_crypto_exit()
#define libssh2_rsa_ctx RSA #define libssh2_rsa_ctx RSA
@@ -239,9 +304,46 @@ int _libssh2_md5_init(libssh2_md5_ctx *ctx);
#define libssh2_dsa_ctx DSA #define libssh2_dsa_ctx DSA
#define _libssh2_dsa_free(dsactx) DSA_free(dsactx) #define _libssh2_dsa_free(dsactx) DSA_free(dsactx)
#ifdef LIBSSH2_ECDSA
#define libssh2_ecdsa_ctx EC_KEY
#define _libssh2_ecdsa_free(ecdsactx) EC_KEY_free(ecdsactx)
#define _libssh2_ec_key EC_KEY
typedef enum {
LIBSSH2_EC_CURVE_NISTP256 = NID_X9_62_prime256v1,
LIBSSH2_EC_CURVE_NISTP384 = NID_secp384r1,
LIBSSH2_EC_CURVE_NISTP521 = NID_secp521r1
}
libssh2_curve_type;
#else
#define _libssh2_ec_key void
#endif /* LIBSSH2_ECDSA */
#ifdef LIBSSH2_ED25519
typedef struct {
EVP_PKEY *public_key;
EVP_PKEY *private_key;
} libssh2_curve25519_keys;
#define libssh2_ed25519_ctx libssh2_curve25519_keys
#define libssh2_x25519_ctx libssh2_curve25519_keys
#define _libssh2_ed25519_new_ctx() calloc(1, sizeof(libssh2_ed25519_ctx))
#define _libssh2_ed25519_free(ctx) do { \
if(ctx) { \
if(ctx->public_key) EVP_PKEY_free(ctx->public_key); \
if(ctx->private_key) EVP_PKEY_free(ctx->private_key); \
free(ctx); \
} \
} while(0)
#define _libssh2_x25519_free(ctx) _libssh2_ed25519_free(ctx)
#endif /* ED25519 */
#define _libssh2_cipher_type(name) const EVP_CIPHER *(*name)(void) #define _libssh2_cipher_type(name) const EVP_CIPHER *(*name)(void)
#ifdef HAVE_OPAQUE_STRUCTS #ifdef HAVE_OPAQUE_STRUCTS
#define _libssh2_cipher_ctx EVP_CIPHER_CTX * #define _libssh2_cipher_ctx EVP_CIPHER_CTX *
@@ -267,7 +369,7 @@ int _libssh2_md5_init(libssh2_md5_ctx *ctx);
#define _libssh2_cipher_3des EVP_des_ede3_cbc #define _libssh2_cipher_3des EVP_des_ede3_cbc
#ifdef HAVE_OPAQUE_STRUCTS #ifdef HAVE_OPAQUE_STRUCTS
#define _libssh2_cipher_dtor(ctx) EVP_CIPHER_CTX_reset(*(ctx)) #define _libssh2_cipher_dtor(ctx) EVP_CIPHER_CTX_free(*(ctx))
#else #else
#define _libssh2_cipher_dtor(ctx) EVP_CIPHER_CTX_cleanup(ctx) #define _libssh2_cipher_dtor(ctx) EVP_CIPHER_CTX_cleanup(ctx)
#endif #endif
@@ -278,8 +380,6 @@ int _libssh2_md5_init(libssh2_md5_ctx *ctx);
#define _libssh2_bn_ctx_free(bnctx) BN_CTX_free(bnctx) #define _libssh2_bn_ctx_free(bnctx) BN_CTX_free(bnctx)
#define _libssh2_bn_init() BN_new() #define _libssh2_bn_init() BN_new()
#define _libssh2_bn_init_from_bin() _libssh2_bn_init() #define _libssh2_bn_init_from_bin() _libssh2_bn_init()
#define _libssh2_bn_rand(bn, bits, top, bottom) BN_rand(bn, bits, top, bottom)
#define _libssh2_bn_mod_exp(r, a, p, m, ctx) BN_mod_exp(r, a, p, m, ctx)
#define _libssh2_bn_set_word(bn, val) BN_set_word(bn, val) #define _libssh2_bn_set_word(bn, val) BN_set_word(bn, val)
#define _libssh2_bn_from_bin(bn, len, val) BN_bin2bn(val, len, bn) #define _libssh2_bn_from_bin(bn, len, val) BN_bin2bn(val, len, bn)
#define _libssh2_bn_to_bin(bn, val) BN_bn2bin(bn, val) #define _libssh2_bn_to_bin(bn, val) BN_bn2bin(bn, val)
@@ -287,7 +387,23 @@ int _libssh2_md5_init(libssh2_md5_ctx *ctx);
#define _libssh2_bn_bits(bn) BN_num_bits(bn) #define _libssh2_bn_bits(bn) BN_num_bits(bn)
#define _libssh2_bn_free(bn) BN_clear_free(bn) #define _libssh2_bn_free(bn) BN_clear_free(bn)
#define _libssh2_dh_ctx BIGNUM *
#define libssh2_dh_init(dhctx) _libssh2_dh_init(dhctx)
#define libssh2_dh_key_pair(dhctx, public, g, p, group_order, bnctx) \
_libssh2_dh_key_pair(dhctx, public, g, p, group_order, bnctx)
#define libssh2_dh_secret(dhctx, secret, f, p, bnctx) \
_libssh2_dh_secret(dhctx, secret, f, p, bnctx)
#define libssh2_dh_dtor(dhctx) _libssh2_dh_dtor(dhctx)
extern void _libssh2_dh_init(_libssh2_dh_ctx *dhctx);
extern int _libssh2_dh_key_pair(_libssh2_dh_ctx *dhctx, _libssh2_bn *public,
_libssh2_bn *g, _libssh2_bn *p,
int group_order,
_libssh2_bn_ctx *bnctx);
extern int _libssh2_dh_secret(_libssh2_dh_ctx *dhctx, _libssh2_bn *secret,
_libssh2_bn *f, _libssh2_bn *p,
_libssh2_bn_ctx *bnctx);
extern void _libssh2_dh_dtor(_libssh2_dh_ctx *dhctx);
const EVP_CIPHER *_libssh2_EVP_aes_128_ctr(void); const EVP_CIPHER *_libssh2_EVP_aes_128_ctr(void);
const EVP_CIPHER *_libssh2_EVP_aes_192_ctr(void); const EVP_CIPHER *_libssh2_EVP_aes_192_ctr(void);
const EVP_CIPHER *_libssh2_EVP_aes_256_ctr(void); const EVP_CIPHER *_libssh2_EVP_aes_256_ctr(void);

File diff suppressed because it is too large Load Diff

View File

@@ -1,358 +0,0 @@
/*
* Copyright (C) 2015 Patrick Monnerat, D+H <patrick.monnerat@dh.com>
* 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.
*/
#ifndef LIBSSH2_OS400QC3_H
#define LIBSSH2_OS400QC3_H
#include <stdlib.h>
#include <string.h>
#include <qc3cci.h>
/* Redefine character/string literals as always EBCDIC. */
#undef Qc3_Alg_Token
#define Qc3_Alg_Token "\xC1\xD3\xC7\xC4\xF0\xF1\xF0\xF0" /* ALGD0100 */
#undef Qc3_Alg_Block_Cipher
#define Qc3_Alg_Block_Cipher "\xC1\xD3\xC7\xC4\xF0\xF2\xF0\xF0" /* ALGD0200 */
#undef Qc3_Alg_Block_CipherAuth
#define Qc3_Alg_Block_CipherAuth \
"\xC1\xD3\xC7\xC4\xF0\xF2\xF1\xF0" /* ALGD0210 */
#undef Qc3_Alg_Stream_Cipher
#define Qc3_Alg_Stream_Cipher \
"\xC1\xD3\xC7\xC4\xF0\xF3\xF0\xF0" /* ALGD0300 */
#undef Qc3_Alg_Public_Key
#define Qc3_Alg_Public_Key "\xC1\xD3\xC7\xC4\xF0\xF4\xF0\xF0" /* ALGD0400 */
#undef Qc3_Alg_Hash
#define Qc3_Alg_Hash "\xC1\xD3\xC7\xC4\xF0\xF5\xF0\xF0" /* ALGD0500 */
#undef Qc3_Data
#define Qc3_Data "\xC4\xC1\xE3\xC1\xF0\xF1\xF0\xF0" /* DATA0100 */
#undef Qc3_Array
#define Qc3_Array "\xC4\xC1\xE3\xC1\xF0\xF2\xF0\xF0" /* DATA0200 */
#undef Qc3_Key_Token
#define Qc3_Key_Token "\xD2\xC5\xE8\xC4\xF0\xF1\xF0\xF0" /* KEYD0100 */
#undef Qc3_Key_Parms
#define Qc3_Key_Parms "\xD2\xC5\xE8\xC4\xF0\xF2\xF0\xF0" /* KEYD0200 */
#undef Qc3_Key_KSLabel
#define Qc3_Key_KSLabel "\xD2\xC5\xE8\xC4\xF0\xF4\xF0\xF0" /* KEYD0400 */
#undef Qc3_Key_PKCS5
#define Qc3_Key_PKCS5 "\xD2\xC5\xE8\xC4\xF0\xF5\xF0\xF0" /* KEYD0500 */
#undef Qc3_Key_PEMCert
#define Qc3_Key_PEMCert "\xD2\xC5\xE8\xC4\xF0\xF6\xF0\xF0" /* KEYD0600 */
#undef Qc3_Key_CSLabel
#define Qc3_Key_CSLabel "\xD2\xC5\xE8\xC4\xF0\xF7\xF0\xF0" /* KEYD0700 */
#undef Qc3_Key_CSDN
#define Qc3_Key_CSDN "\xD2\xC5\xE8\xC4\xF0\xF8\xF0\xF0" /* KEYD0800 */
#undef Qc3_Key_AppID
#define Qc3_Key_AppID "\xD2\xC5\xE8\xC4\xF0\xF9\xF0\xF0" /* KEYD0900 */
#undef Qc3_ECB
#define Qc3_ECB '\xF0' /* '0' */
#undef Qc3_CBC
#define Qc3_CBC '\xF1' /* '1' */
#undef Qc3_OFB
#define Qc3_OFB '\xF2' /* '2' */
#undef Qc3_CFB1Bit
#define Qc3_CFB1Bit '\xF3' /* '3' */
#undef Qc3_CFB8Bit
#define Qc3_CFB8Bit '\xF4' /* '4' */
#undef Qc3_CFB64Bit
#define Qc3_CFB64Bit '\xF5' /* '5' */
#undef Qc3_CUSP
#define Qc3_CUSP '\xF6' /* '6' */
#undef Qc3_CTR
#define Qc3_CTR '\xF7' /* '7' */
#undef Qc3_CCM
#define Qc3_CCM '\xF8' /* '8' */
#undef Qc3_No_Pad
#define Qc3_No_Pad '\xF0' /* '0' */
#undef Qc3_Pad_Char
#define Qc3_Pad_Char '\xF1' /* '1' */
#undef Qc3_Pad_Counter
#define Qc3_Pad_Counter '\xF2' /* '2' */
#undef Qc3_PKCS1_00
#define Qc3_PKCS1_00 '\xF0' /* '0' */
#undef Qc3_PKCS1_01
#define Qc3_PKCS1_01 '\xF1' /* '1' */
#undef Qc3_PKCS1_02
#define Qc3_PKCS1_02 '\xF2' /* '2' */
#undef Qc3_ISO9796
#define Qc3_ISO9796 '\xF3' /* '3' */
#undef Qc3_Zero_Pad
#define Qc3_Zero_Pad '\xF4' /* '4' */
#undef Qc3_ANSI_X931
#define Qc3_ANSI_X931 '\xF5' /* '5' */
#undef Qc3_OAEP
#define Qc3_OAEP '\xF6' /* '6' */
#undef Qc3_Bin_String
#define Qc3_Bin_String '\xF0' /* '0' */
#undef Qc3_BER_String
#define Qc3_BER_String '\xF1' /* '1' */
#undef Qc3_MK_Struct
#define Qc3_MK_Struct '\xF3' /* '3' */
#undef Qc3_KSLabel_Struct
#define Qc3_KSLabel_Struct '\xF4' /* '4' */
#undef Qc3_PKCS5_Struct
#define Qc3_PKCS5_Struct '\xF5' /* '5' */
#undef Qc3_PEMCert_String
#define Qc3_PEMCert_String '\xF6' /* '6' */
#undef Qc3_CSLabel_String
#define Qc3_CSLabel_String '\xF7' /* '7' */
#undef Qc3_CSDN_String
#define Qc3_CSDN_String '\xF8' /* '8' */
#undef Qc3_Clear
#define Qc3_Clear '\xF0' /* '0' */
#undef Qc3_Encrypted
#define Qc3_Encrypted '\xF1' /* '1' */
#undef Qc3_MK_Encrypted
#define Qc3_MK_Encrypted '\xF2' /* '2' */
#undef Qc3_Any_CSP
#define Qc3_Any_CSP '\xF0' /* '0' */
#undef Qc3_Sfw_CSP
#define Qc3_Sfw_CSP '\xF1' /* '1' */
#undef Qc3_Hdw_CSP
#define Qc3_Hdw_CSP '\xF2' /* '2' */
#undef Qc3_Continue
#define Qc3_Continue '\xF0' /* '0' */
#undef Qc3_Final
#define Qc3_Final '\xF1' /* '1' */
#undef Qc3_MK_New
#define Qc3_MK_New '\xF0' /* '0' */
#undef Qc3_MK_Current
#define Qc3_MK_Current '\xF1' /* '1' */
#undef Qc3_MK_Old
#define Qc3_MK_Old '\xF2' /* '2' */
#undef Qc3_MK_Pending
#define Qc3_MK_Pending '\xF3' /* '3' */
/* Define which features are supported. */
#define LIBSSH2_MD5 1
#define LIBSSH2_HMAC_RIPEMD 0
#define LIBSSH2_HMAC_SHA256 1
#define LIBSSH2_HMAC_SHA512 1
#define LIBSSH2_AES 1
#define LIBSSH2_AES_CTR 1
#define LIBSSH2_BLOWFISH 0
#define LIBSSH2_RC4 1
#define LIBSSH2_CAST 0
#define LIBSSH2_3DES 1
#define LIBSSH2_RSA 1
#define LIBSSH2_DSA 0
#define MD5_DIGEST_LENGTH 16
#define SHA_DIGEST_LENGTH 20
#define SHA256_DIGEST_LENGTH 32
#define SHA512_DIGEST_LENGTH 64
/*******************************************************************
*
* OS/400 QC3 crypto-library backend: global handles structures.
*
*******************************************************************/
/* HMAC & private key algorithms support structure. */
typedef struct _libssh2_os400qc3_crypto_ctx _libssh2_os400qc3_crypto_ctx;
struct _libssh2_os400qc3_crypto_ctx {
Qc3_Format_ALGD0100_T hash; /* Hash algorithm. */
Qc3_Format_KEYD0100_T key; /* Key. */
_libssh2_os400qc3_crypto_ctx * kek; /* Key encryption. */
};
typedef struct { /* Big number. */
unsigned char * bignum; /* Number bits, little-endian. */
unsigned int length; /* Length of bignum (# bytes). */
} _libssh2_bn;
typedef struct { /* Algorithm description. */
char * fmt; /* Format of Qc3 structure. */
int algo; /* Algorithm identifier. */
unsigned char size; /* Block length. */
unsigned char mode; /* Block mode. */
int keylen; /* Key length. */
} _libssh2_os400qc3_cipher_t;
/*******************************************************************
*
* OS/400 QC3 crypto-library backend: Define global types/codes.
*
*******************************************************************/
#define libssh2_crypto_init()
#define libssh2_crypto_exit()
#define libssh2_sha1_ctx Qc3_Format_ALGD0100_T
#define libssh2_sha256_ctx Qc3_Format_ALGD0100_T
#define libssh2_md5_ctx Qc3_Format_ALGD0100_T
#define libssh2_hmac_ctx _libssh2_os400qc3_crypto_ctx
#define _libssh2_cipher_ctx _libssh2_os400qc3_crypto_ctx
#define libssh2_sha1_init(x) libssh2_os400qc3_hash_init(x, Qc3_SHA1)
#define libssh2_sha1_update(ctx, data, len) \
libssh2_os400qc3_hash_update(&(ctx), data, len)
#define libssh2_sha1_final(ctx, out) \
libssh2_os400qc3_hash_final(&(ctx), out)
#define libssh2_sha256_init(x) libssh2_os400qc3_hash_init(x, Qc3_SHA256)
#define libssh2_sha256_update(ctx, data, len) \
libssh2_os400qc3_hash_update(&(ctx), data, len)
#define libssh2_sha256_final(ctx, out) \
libssh2_os400qc3_hash_final(&(ctx), out)
#define libssh2_sha256(message, len, out) \
libssh2_os400qc3_hash(message, len, out, \
Qc3_SHA256)
#define libssh2_md5_init(x) libssh2_os400qc3_hash_init(x, Qc3_MD5)
#define libssh2_md5_update(ctx, data, len) \
libssh2_os400qc3_hash_update(&(ctx), data, len)
#define libssh2_md5_final(ctx, out) \
libssh2_os400qc3_hash_final(&(ctx), out)
#define libssh2_hmac_ctx_init(ctx) \
memset((char *) &(ctx), 0, \
sizeof(libssh2_hmac_ctx))
#define libssh2_hmac_md5_init(ctx, key, keylen) \
libssh2_os400qc3_hmac_init(ctx, Qc3_MD5, \
MD5_DIGEST_LENGTH, \
key, keylen)
#define libssh2_hmac_sha1_init(ctx, key, keylen) \
libssh2_os400qc3_hmac_init(ctx, Qc3_SHA1, \
SHA_DIGEST_LENGTH, \
key, keylen)
#define libssh2_hmac_sha256_init(ctx, key, keylen) \
libssh2_os400qc3_hmac_init(ctx, Qc3_SHA256, \
SHA256_DIGEST_LENGTH, \
key, keylen)
#define libssh2_hmac_sha512_init(ctx, key, keylen) \
libssh2_os400qc3_hmac_init(ctx, Qc3_SHA512, \
SHA512_DIGEST_LENGTH, \
key, keylen)
#define libssh2_hmac_update(ctx, data, datalen) \
libssh2_os400qc3_hmac_update(&(ctx), \
data, datalen)
#define libssh2_hmac_final(ctx, data) \
libssh2_os400qc3_hmac_final(&(ctx), data)
#define libssh2_hmac_cleanup(ctx) \
_libssh2_os400qc3_crypto_dtor(ctx)
#define _libssh2_bn_ctx int /* Not used. */
#define _libssh2_bn_ctx_new() 0
#define _libssh2_bn_ctx_free(bnctx) ((void) 0)
#define _libssh2_bn_init_from_bin() _libssh2_bn_init()
#define _libssh2_bn_mod_exp(r, a, p, m, ctx) \
_libssh2_os400qc3_bn_mod_exp(r, a, p, m)
#define _libssh2_bn_bytes(bn) ((bn)->length)
#define _libssh2_cipher_type(name) _libssh2_os400qc3_cipher_t name
#define _libssh2_cipher_aes128 {Qc3_Alg_Block_Cipher, Qc3_AES, 16, \
Qc3_CBC, 16}
#define _libssh2_cipher_aes192 {Qc3_Alg_Block_Cipher, Qc3_AES, 24, \
Qc3_CBC, 24}
#define _libssh2_cipher_aes256 {Qc3_Alg_Block_Cipher, Qc3_AES, 32, \
Qc3_CBC, 32}
#define _libssh2_cipher_aes128ctr {Qc3_Alg_Block_Cipher, Qc3_AES, 16, \
Qc3_CTR, 16}
#define _libssh2_cipher_aes192ctr {Qc3_Alg_Block_Cipher, Qc3_AES, 24, \
Qc3_CTR, 24}
#define _libssh2_cipher_aes256ctr {Qc3_Alg_Block_Cipher, Qc3_AES, 32, \
Qc3_CTR, 32}
#define _libssh2_cipher_3des {Qc3_Alg_Block_Cipher, Qc3_TDES, 0, \
Qc3_CBC, 24}
#define _libssh2_cipher_arcfour {Qc3_Alg_Stream_Cipher, Qc3_RC4, 0, 0, 16}
#define _libssh2_cipher_dtor(ctx) _libssh2_os400qc3_crypto_dtor(ctx)
#define libssh2_rsa_ctx _libssh2_os400qc3_crypto_ctx
#define _libssh2_rsa_free(ctx) (_libssh2_os400qc3_crypto_dtor(ctx), \
free((char *) ctx))
#define libssh2_prepare_iovec(vec, len) memset((char *) (vec), 0, \
(len) * sizeof(struct iovec))
#define _libssh2_rsa_sha1_signv(session, sig, siglen, count, vector, ctx) \
_libssh2_os400qc3_rsa_sha1_signv(session, sig, siglen, \
count, vector, ctx)
/*******************************************************************
*
* OS/400 QC3 crypto-library backend: Support procedure prototypes.
*
*******************************************************************/
extern _libssh2_bn * _libssh2_bn_init(void);
extern void _libssh2_bn_free(_libssh2_bn *bn);
extern unsigned long _libssh2_bn_bits(_libssh2_bn *bn);
extern int _libssh2_bn_from_bin(_libssh2_bn *bn, int len,
const unsigned char *v);
extern int _libssh2_bn_set_word(_libssh2_bn *bn, unsigned long val);
extern int _libssh2_bn_to_bin(_libssh2_bn *bn, unsigned char *val);
extern void _libssh2_random(unsigned char *buf, int len);
extern int _libssh2_bn_rand(_libssh2_bn *bn, int bits,
int top, int bottom);
extern int _libssh2_os400qc3_bn_mod_exp(_libssh2_bn *r, _libssh2_bn *a,
_libssh2_bn *p, _libssh2_bn *m);
extern void _libssh2_os400qc3_crypto_dtor(_libssh2_os400qc3_crypto_ctx *x);
extern int libssh2_os400qc3_hash_init(Qc3_Format_ALGD0100_T *x,
unsigned int algo);
extern void libssh2_os400qc3_hash_update(Qc3_Format_ALGD0100_T *ctx,
unsigned char *data, int len);
extern void libssh2_os400qc3_hash_final(Qc3_Format_ALGD0100_T *ctx,
unsigned char *out);
extern int libssh2_os400qc3_hash(const unsigned char *message,
unsigned long len, unsigned char *out,
unsigned int algo);
extern void libssh2_os400qc3_hmac_init(_libssh2_os400qc3_crypto_ctx *x,
int algo, size_t minkeylen,
void *key, int keylen);
extern void libssh2_os400qc3_hmac_update(_libssh2_os400qc3_crypto_ctx *ctx,
const unsigned char *data,
int len);
extern void libssh2_os400qc3_hmac_final(_libssh2_os400qc3_crypto_ctx *ctx,
unsigned char *out);
extern int _libssh2_os400qc3_rsa_sha1_signv(LIBSSH2_SESSION *session,
unsigned char **signature,
size_t *signature_len,
int veccount,
const struct iovec vector[],
libssh2_rsa_ctx *ctx);
#endif
/* vim: set expandtab ts=4 sw=4: */

View File

@@ -245,7 +245,8 @@ packet_queue_listener(LIBSSH2_SESSION * session, unsigned char *data,
packet_len, NULL, 0); packet_len, NULL, 0);
if(rc == LIBSSH2_ERROR_EAGAIN) { if(rc == LIBSSH2_ERROR_EAGAIN) {
return rc; return rc;
} else if (rc) { }
else if(rc) {
listen_state->state = libssh2_NB_state_idle; 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");
@@ -355,7 +356,8 @@ packet_x11_open(LIBSSH2_SESSION * session, unsigned char *data,
NULL, 0); NULL, 0);
if(rc == LIBSSH2_ERROR_EAGAIN) { if(rc == LIBSSH2_ERROR_EAGAIN) {
return rc; return rc;
} else if (rc) { }
else if(rc) {
x11open_state->state = libssh2_NB_state_idle; x11open_state->state = libssh2_NB_state_idle;
return _libssh2_error(session, LIBSSH2_ERROR_SOCKET_SEND, return _libssh2_error(session, LIBSSH2_ERROR_SOCKET_SEND,
"Unable to send channel open " "Unable to send channel open "
@@ -391,7 +393,8 @@ packet_x11_open(LIBSSH2_SESSION * session, unsigned char *data,
NULL, 0); NULL, 0);
if(rc == LIBSSH2_ERROR_EAGAIN) { if(rc == LIBSSH2_ERROR_EAGAIN) {
return rc; return rc;
} else if (rc) { }
else if(rc) {
x11open_state->state = libssh2_NB_state_idle; 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");
} }
@@ -478,7 +481,8 @@ _libssh2_packet_add(LIBSSH2_SESSION * session, unsigned char *data,
/* 9 = packet_type(1) + reason(4) + message_len(4) */ /* 9 = packet_type(1) + reason(4) + message_len(4) */
message = (char *) data + 9; message = (char *) data + 9;
language_len = _libssh2_ntohu32(data + 9 + message_len); language_len =
_libssh2_ntohu32(data + 9 + message_len);
language = (char *) data + 9 + message_len + 4; language = (char *) data + 9 + message_len + 4;
if(language_len > (datalen-13-message_len)) { if(language_len > (datalen-13-message_len)) {
@@ -515,7 +519,8 @@ _libssh2_packet_add(LIBSSH2_SESSION * session, unsigned char *data,
if(session->ssh_msg_ignore) { if(session->ssh_msg_ignore) {
LIBSSH2_IGNORE(session, (char *) data + 1, datalen - 1); LIBSSH2_IGNORE(session, (char *) data + 1, datalen - 1);
} }
} else if (session->ssh_msg_ignore) { }
else if(session->ssh_msg_ignore) {
LIBSSH2_IGNORE(session, "", 0); LIBSSH2_IGNORE(session, "", 0);
} }
LIBSSH2_FREE(session, data); LIBSSH2_FREE(session, data);
@@ -539,7 +544,8 @@ _libssh2_packet_add(LIBSSH2_SESSION * session, unsigned char *data,
if(message_len <= (datalen - 10)) { if(message_len <= (datalen - 10)) {
/* 6 = packet_type(1) + display(1) + message_len(4) */ /* 6 = packet_type(1) + display(1) + message_len(4) */
message = (char *) data + 6; message = (char *) data + 6;
language_len = _libssh2_ntohu32(data + 6 + message_len); language_len = _libssh2_ntohu32(data + 6 +
message_len);
if(language_len <= (datalen - 10 - message_len)) if(language_len <= (datalen - 10 - message_len))
language = (char *) data + 10 + message_len; language = (char *) data + 10 + message_len;
@@ -661,7 +667,8 @@ _libssh2_packet_add(LIBSSH2_SESSION * session, unsigned char *data,
channelp->remote.window_size -= datalen - data_head; channelp->remote.window_size -= datalen - data_head;
_libssh2_debug(session, LIBSSH2_TRACE_CONN, _libssh2_debug(session, LIBSSH2_TRACE_CONN,
"shrinking window size by %lu bytes to %lu, read_avail %lu", "shrinking window size by %lu bytes to %lu, "
"read_avail %lu",
datalen - data_head, datalen - data_head,
channelp->remote.window_size, channelp->remote.window_size,
channelp->read_avail); channelp->read_avail);
@@ -829,7 +836,8 @@ _libssh2_packet_add(LIBSSH2_SESSION * session, unsigned char *data,
if(!channelp->exit_signal) if(!channelp->exit_signal)
rc = _libssh2_error(session, LIBSSH2_ERROR_ALLOC, rc = _libssh2_error(session, LIBSSH2_ERROR_ALLOC,
"memory for signal name"); "memory for signal name");
else if ((sizeof("exit-signal") + 13 + namelen <= datalen)) { else if((sizeof("exit-signal") + 13 + namelen <=
datalen)) {
memcpy(channelp->exit_signal, memcpy(channelp->exit_signal,
data + 13 + sizeof("exit-signal"), namelen); data + 13 + sizeof("exit-signal"), namelen);
channelp->exit_signal[namelen] = '\0'; channelp->exit_signal[namelen] = '\0';
@@ -1130,13 +1138,15 @@ _libssh2_packet_require(LIBSSH2_SESSION * session, unsigned char packet_type,
state->start = 0; state->start = 0;
/* an error which is not just because of blocking */ /* an error which is not just because of blocking */
return ret; return ret;
} else if (ret == packet_type) { }
else if(ret == packet_type) {
/* Be lazy, let packet_ask pull it out of the brigade */ /* Be lazy, let packet_ask pull it out of the brigade */
ret = _libssh2_packet_ask(session, packet_type, data, data_len, 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; state->start = 0;
return ret; return ret;
} else if (ret == 0) { }
else if(ret == 0) {
/* nothing available, wait until data arrives or we time out */ /* nothing available, wait until data arrives or we time out */
long left = LIBSSH2_READ_TIMEOUT - (long)(time(NULL) - long left = LIBSSH2_READ_TIMEOUT - (long)(time(NULL) -
state->start); state->start);
@@ -1192,10 +1202,12 @@ _libssh2_packet_burn(LIBSSH2_SESSION * session,
ret = _libssh2_transport_read(session); ret = _libssh2_transport_read(session);
if(ret == LIBSSH2_ERROR_EAGAIN) { if(ret == LIBSSH2_ERROR_EAGAIN) {
return ret; return ret;
} else if (ret < 0) { }
else if(ret < 0) {
*state = libssh2_NB_state_idle; *state = libssh2_NB_state_idle;
return ret; return ret;
} else if (ret == 0) { }
else if(ret == 0) {
/* FIXME: this might busyloop */ /* FIXME: this might busyloop */
continue; continue;
} }

View File

@@ -76,7 +76,7 @@ readline_memory(char *line, size_t line_size,
off = *filedata_offset; off = *filedata_offset;
for (len = 0; off + len < filedata_len && len < line_size; len++) { for(len = 0; off + len < filedata_len && len < line_size - 1; len++) {
if(filedata[off + len] == '\n' || if(filedata[off + len] == '\n' ||
filedata[off + len] == '\r') { filedata[off + len] == '\r') {
break; break;
@@ -96,16 +96,26 @@ readline_memory(char *line, size_t line_size,
#define LINE_SIZE 128 #define LINE_SIZE 128
static const char *crypt_annotation = "Proc-Type: 4,ENCRYPTED";
static unsigned char hex_decode(char digit)
{
return (digit >= 'A') ? 0xA + (digit - 'A') : (digit - '0');
}
int int
_libssh2_pem_parse(LIBSSH2_SESSION * session, _libssh2_pem_parse(LIBSSH2_SESSION * session,
const char *headerbegin, const char *headerbegin,
const char *headerend, const char *headerend,
const unsigned char *passphrase,
FILE * fp, unsigned char **data, unsigned int *datalen) FILE * fp, unsigned char **data, unsigned int *datalen)
{ {
char line[LINE_SIZE]; char line[LINE_SIZE];
unsigned char iv[LINE_SIZE];
char *b64data = NULL; char *b64data = NULL;
unsigned int b64datalen = 0; unsigned int b64datalen = 0;
int ret; int ret;
const LIBSSH2_CRYPT_METHOD *method = NULL;
do { do {
*line = '\0'; *line = '\0';
@@ -116,7 +126,47 @@ _libssh2_pem_parse(LIBSSH2_SESSION * session,
} }
while(strcmp(line, headerbegin) != 0); while(strcmp(line, headerbegin) != 0);
*line = '\0'; if(readline(line, LINE_SIZE, fp)) {
return -1;
}
if(passphrase &&
memcmp(line, crypt_annotation, strlen(crypt_annotation)) == 0) {
const LIBSSH2_CRYPT_METHOD **all_methods, *cur_method;
int i;
if(readline(line, LINE_SIZE, fp)) {
ret = -1;
goto out;
}
all_methods = libssh2_crypt_methods();
while((cur_method = *all_methods++)) {
if(*cur_method->pem_annotation &&
memcmp(line, cur_method->pem_annotation,
strlen(cur_method->pem_annotation)) == 0) {
method = cur_method;
memcpy(iv, line + strlen(method->pem_annotation) + 1,
2*method->iv_len);
}
}
/* None of the available crypt methods were able to decrypt the key */
if(method == NULL)
return -1;
/* Decode IV from hex */
for(i = 0; i < method->iv_len; ++i) {
iv[i] = hex_decode(iv[2*i]) << 4;
iv[i] |= hex_decode(iv[2*i + 1]);
}
/* skip to the next line */
if(readline(line, LINE_SIZE, fp)) {
ret = -1;
goto out;
}
}
do { do {
if(*line) { if(*line) {
@@ -152,9 +202,86 @@ _libssh2_pem_parse(LIBSSH2_SESSION * session,
goto out; goto out;
} }
if(method) {
/* Set up decryption */
int free_iv = 0, free_secret = 0, len_decrypted = 0, padding = 0;
int blocksize = method->blocksize;
void *abstract;
unsigned char secret[2*MD5_DIGEST_LENGTH];
libssh2_md5_ctx fingerprint_ctx;
/* Perform key derivation (PBKDF1/MD5) */
if(!libssh2_md5_init(&fingerprint_ctx)) {
ret = -1;
goto out;
}
libssh2_md5_update(fingerprint_ctx, passphrase,
strlen((char *)passphrase));
libssh2_md5_update(fingerprint_ctx, iv, 8);
libssh2_md5_final(fingerprint_ctx, secret);
if(method->secret_len > MD5_DIGEST_LENGTH) {
if(!libssh2_md5_init(&fingerprint_ctx)) {
ret = -1;
goto out;
}
libssh2_md5_update(fingerprint_ctx, secret, MD5_DIGEST_LENGTH);
libssh2_md5_update(fingerprint_ctx, passphrase,
strlen((char *)passphrase));
libssh2_md5_update(fingerprint_ctx, iv, 8);
libssh2_md5_final(fingerprint_ctx, secret + MD5_DIGEST_LENGTH);
}
/* Initialize the decryption */
if(method->init(session, method, iv, &free_iv, secret,
&free_secret, 0, &abstract)) {
_libssh2_explicit_zero((char *)secret, sizeof(secret));
LIBSSH2_FREE(session, data);
ret = -1;
goto out;
}
if(free_secret) {
_libssh2_explicit_zero((char *)secret, sizeof(secret));
}
/* Do the actual decryption */
if((*datalen % blocksize) != 0) {
_libssh2_explicit_zero((char *)secret, sizeof(secret));
method->dtor(session, &abstract);
_libssh2_explicit_zero(*data, *datalen);
LIBSSH2_FREE(session, *data);
ret = -1;
goto out;
}
while(len_decrypted <= (int)*datalen - blocksize) {
if(method->crypt(session, *data + len_decrypted, blocksize,
&abstract)) {
ret = LIBSSH2_ERROR_DECRYPT;
_libssh2_explicit_zero((char *)secret, sizeof(secret));
method->dtor(session, &abstract);
_libssh2_explicit_zero(*data, *datalen);
LIBSSH2_FREE(session, *data);
goto out;
}
len_decrypted += blocksize;
}
/* Account for padding */
padding = (*data)[*datalen - 1];
memset(&(*data)[*datalen-padding], 0, padding);
*datalen -= padding;
/* Clean up */
_libssh2_explicit_zero((char *)secret, sizeof(secret));
method->dtor(session, &abstract);
}
ret = 0; ret = 0;
out: out:
if(b64data) { if(b64data) {
_libssh2_explicit_zero(b64data, b64datalen);
LIBSSH2_FREE(session, b64data); LIBSSH2_FREE(session, b64data);
} }
return ret; return ret;
@@ -221,11 +348,461 @@ _libssh2_pem_parse_memory(LIBSSH2_SESSION * session,
ret = 0; ret = 0;
out: out:
if(b64data) { if(b64data) {
_libssh2_explicit_zero(b64data, b64datalen);
LIBSSH2_FREE(session, b64data); LIBSSH2_FREE(session, b64data);
} }
return ret; return ret;
} }
/* OpenSSH formatted keys */
#define AUTH_MAGIC "openssh-key-v1"
#define OPENSSH_HEADER_BEGIN "-----BEGIN OPENSSH PRIVATE KEY-----"
#define OPENSSH_HEADER_END "-----END OPENSSH PRIVATE KEY-----"
static int
_libssh2_openssh_pem_parse_data(LIBSSH2_SESSION * session,
const unsigned char *passphrase,
const char *b64data, size_t b64datalen,
struct string_buf **decrypted_buf)
{
const LIBSSH2_CRYPT_METHOD *method = NULL;
struct string_buf decoded, decrypted, kdf_buf;
unsigned char *ciphername = NULL;
unsigned char *kdfname = NULL;
unsigned char *kdf = NULL;
unsigned char *buf = NULL;
unsigned char *salt = NULL;
uint32_t nkeys, check1, check2;
uint32_t rounds = 0;
unsigned char *key = NULL;
unsigned char *key_part = NULL;
unsigned char *iv_part = NULL;
unsigned char *f = NULL;
unsigned int f_len = 0;
int ret = 0, keylen = 0, ivlen = 0, total_len = 0;
size_t kdf_len = 0, tmp_len = 0, salt_len = 0;
if(decrypted_buf)
*decrypted_buf = NULL;
/* decode file */
if(libssh2_base64_decode(session, (char **)&f, &f_len,
b64data, b64datalen)) {
ret = -1;
goto out;
}
/* Parse the file */
decoded.data = (unsigned char *)f;
decoded.dataptr = (unsigned char *)f;
decoded.len = f_len;
if(decoded.len < strlen(AUTH_MAGIC)) {
ret = _libssh2_error(session, LIBSSH2_ERROR_PROTO, "key too short");
goto out;
}
if(strncmp((char *) decoded.dataptr, AUTH_MAGIC,
strlen(AUTH_MAGIC)) != 0) {
ret = _libssh2_error(session, LIBSSH2_ERROR_PROTO,
"key auth magic mismatch");
goto out;
}
decoded.dataptr += strlen(AUTH_MAGIC) + 1;
if(_libssh2_get_string(&decoded, &ciphername, &tmp_len) ||
tmp_len == 0) {
ret = _libssh2_error(session, LIBSSH2_ERROR_PROTO,
"ciphername is missing");
goto out;
}
if(_libssh2_get_string(&decoded, &kdfname, &tmp_len) ||
tmp_len == 0) {
ret = _libssh2_error(session, LIBSSH2_ERROR_PROTO,
"kdfname is missing");
goto out;
}
if(_libssh2_get_string(&decoded, &kdf, &kdf_len)) {
ret = _libssh2_error(session, LIBSSH2_ERROR_PROTO,
"kdf is missing");
goto out;
}
else {
kdf_buf.data = kdf;
kdf_buf.dataptr = kdf;
kdf_buf.len = kdf_len;
}
if((passphrase == NULL || strlen((const char *)passphrase) == 0) &&
strcmp((const char *)ciphername, "none") != 0) {
/* passphrase required */
ret = LIBSSH2_ERROR_KEYFILE_AUTH_FAILED;
goto out;
}
if(strcmp((const char *)kdfname, "none") != 0 &&
strcmp((const char *)kdfname, "bcrypt") != 0) {
ret = _libssh2_error(session, LIBSSH2_ERROR_PROTO,
"unknown cipher");
goto out;
}
if(!strcmp((const char *)kdfname, "none") &&
strcmp((const char *)ciphername, "none") != 0) {
ret =_libssh2_error(session, LIBSSH2_ERROR_PROTO,
"invalid format");
goto out;
}
if(_libssh2_get_u32(&decoded, &nkeys) != 0 || nkeys != 1) {
ret = _libssh2_error(session, LIBSSH2_ERROR_PROTO,
"Multiple keys are unsupported");
goto out;
}
/* unencrypted public key */
if(_libssh2_get_string(&decoded, &buf, &tmp_len) || tmp_len == 0) {
ret = _libssh2_error(session, LIBSSH2_ERROR_PROTO,
"Invalid private key; "
"expect embedded public key");
goto out;
}
if(_libssh2_get_string(&decoded, &buf, &tmp_len) || tmp_len == 0) {
ret = _libssh2_error(session, LIBSSH2_ERROR_PROTO,
"Private key data not found");
goto out;
}
/* decode encrypted private key */
decrypted.data = decrypted.dataptr = buf;
decrypted.len = tmp_len;
if(ciphername && strcmp((const char *)ciphername, "none") != 0) {
const LIBSSH2_CRYPT_METHOD **all_methods, *cur_method;
all_methods = libssh2_crypt_methods();
while((cur_method = *all_methods++)) {
if(*cur_method->name &&
memcmp(ciphername, cur_method->name,
strlen(cur_method->name)) == 0) {
method = cur_method;
}
}
/* None of the available crypt methods were able to decrypt the key */
if(method == NULL) {
ret = _libssh2_error(session, LIBSSH2_ERROR_PROTO,
"No supported cipher found");
goto out;
}
}
if(method) {
int free_iv = 0, free_secret = 0, len_decrypted = 0;
int blocksize;
void *abstract = NULL;
keylen = method->secret_len;
ivlen = method->iv_len;
total_len = keylen + ivlen;
key = LIBSSH2_CALLOC(session, total_len);
if(key == NULL) {
ret = _libssh2_error(session, LIBSSH2_ERROR_PROTO,
"Could not alloc key");
goto out;
}
if(strcmp((const char *)kdfname, "bcrypt") == 0 &&
passphrase != NULL) {
if((_libssh2_get_string(&kdf_buf, &salt, &salt_len)) ||
(_libssh2_get_u32(&kdf_buf, &rounds) != 0) ) {
ret = _libssh2_error(session, LIBSSH2_ERROR_PROTO,
"kdf contains unexpected values");
LIBSSH2_FREE(session, key);
goto out;
}
if(_libssh2_bcrypt_pbkdf((const char *)passphrase,
strlen((const char *)passphrase),
salt, salt_len, key,
keylen + ivlen, rounds) < 0) {
ret = _libssh2_error(session, LIBSSH2_ERROR_DECRYPT,
"invalid format");
LIBSSH2_FREE(session, key);
goto out;
}
}
else {
ret = _libssh2_error(session, LIBSSH2_ERROR_KEYFILE_AUTH_FAILED,
"bcrypted without passphrase");
LIBSSH2_FREE(session, key);
goto out;
}
/* Set up decryption */
blocksize = method->blocksize;
key_part = LIBSSH2_CALLOC(session, keylen);
if(key_part == NULL) {
ret = _libssh2_error(session, LIBSSH2_ERROR_PROTO,
"Could not alloc key part");
goto out;
}
iv_part = LIBSSH2_CALLOC(session, ivlen);
if(iv_part == NULL) {
ret = _libssh2_error(session, LIBSSH2_ERROR_PROTO,
"Could not alloc iv part");
goto out;
}
memcpy(key_part, key, keylen);
memcpy(iv_part, key + keylen, ivlen);
/* Initialize the decryption */
if(method->init(session, method, iv_part, &free_iv, key_part,
&free_secret, 0, &abstract)) {
ret = LIBSSH2_ERROR_DECRYPT;
goto out;
}
/* Do the actual decryption */
if((decrypted.len % blocksize) != 0) {
method->dtor(session, &abstract);
ret = LIBSSH2_ERROR_DECRYPT;
goto out;
}
while((size_t)len_decrypted <= decrypted.len - blocksize) {
if(method->crypt(session, decrypted.data + len_decrypted,
blocksize,
&abstract)) {
ret = LIBSSH2_ERROR_DECRYPT;
method->dtor(session, &abstract);
goto out;
}
len_decrypted += blocksize;
}
/* No padding */
method->dtor(session, &abstract);
}
/* Check random bytes match */
if(_libssh2_get_u32(&decrypted, &check1) != 0 ||
_libssh2_get_u32(&decrypted, &check2) != 0 ||
check1 != check2) {
_libssh2_error(session, LIBSSH2_ERROR_PROTO,
"Private key unpack failed (correct password?)");
ret = LIBSSH2_ERROR_KEYFILE_AUTH_FAILED;
goto out;
}
if(decrypted_buf != NULL) {
/* copy data to out-going buffer */
struct string_buf *out_buf = _libssh2_string_buf_new(session);
if(!out_buf) {
ret = _libssh2_error(session, LIBSSH2_ERROR_ALLOC,
"Unable to allocate memory for "
"decrypted struct");
goto out;
}
out_buf->data = LIBSSH2_CALLOC(session, decrypted.len);
if(out_buf->data == NULL) {
ret = _libssh2_error(session, LIBSSH2_ERROR_ALLOC,
"Unable to allocate memory for "
"decrypted struct");
_libssh2_string_buf_free(session, out_buf);
goto out;
}
memcpy(out_buf->data, decrypted.data, decrypted.len);
out_buf->dataptr = out_buf->data +
(decrypted.dataptr - decrypted.data);
out_buf->len = decrypted.len;
*decrypted_buf = out_buf;
}
out:
/* Clean up */
if(key) {
_libssh2_explicit_zero(key, total_len);
LIBSSH2_FREE(session, key);
}
if(key_part) {
_libssh2_explicit_zero(key_part, keylen);
LIBSSH2_FREE(session, key_part);
}
if(iv_part) {
_libssh2_explicit_zero(iv_part, ivlen);
LIBSSH2_FREE(session, iv_part);
}
if(f) {
_libssh2_explicit_zero(f, f_len);
LIBSSH2_FREE(session, f);
}
return ret;
}
int
_libssh2_openssh_pem_parse(LIBSSH2_SESSION * session,
const unsigned char *passphrase,
FILE * fp, struct string_buf **decrypted_buf)
{
char line[LINE_SIZE];
char *b64data = NULL;
unsigned int b64datalen = 0;
int ret = 0;
/* read file */
do {
*line = '\0';
if(readline(line, LINE_SIZE, fp)) {
return -1;
}
}
while(strcmp(line, OPENSSH_HEADER_BEGIN) != 0);
if(readline(line, LINE_SIZE, fp)) {
return -1;
}
do {
if(*line) {
char *tmp;
size_t linelen;
linelen = strlen(line);
tmp = LIBSSH2_REALLOC(session, b64data, b64datalen + linelen);
if(!tmp) {
ret = -1;
goto out;
}
memcpy(tmp + b64datalen, line, linelen);
b64data = tmp;
b64datalen += linelen;
}
*line = '\0';
if(readline(line, LINE_SIZE, fp)) {
ret = -1;
goto out;
}
} while(strcmp(line, OPENSSH_HEADER_END) != 0);
if(!b64data) {
return -1;
}
ret = _libssh2_openssh_pem_parse_data(session,
passphrase,
(const char *)b64data,
(size_t)b64datalen,
decrypted_buf);
if(b64data) {
_libssh2_explicit_zero(b64data, b64datalen);
LIBSSH2_FREE(session, b64data);
}
out:
return ret;
}
int
_libssh2_openssh_pem_parse_memory(LIBSSH2_SESSION * session,
const unsigned char *passphrase,
const char *filedata, size_t filedata_len,
struct string_buf **decrypted_buf)
{
char line[LINE_SIZE];
char *b64data = NULL;
unsigned int b64datalen = 0;
size_t off = 0;
int ret;
if(filedata == NULL || filedata_len <= 0) {
return -1;
}
do {
*line = '\0';
if(off >= filedata_len) {
return -1;
}
if(readline_memory(line, LINE_SIZE, filedata, filedata_len, &off)) {
return -1;
}
}
while(strcmp(line, OPENSSH_HEADER_BEGIN) != 0);
*line = '\0';
do {
if (*line) {
char *tmp;
size_t linelen;
linelen = strlen(line);
tmp = LIBSSH2_REALLOC(session, b64data, b64datalen + linelen);
if(!tmp) {
ret = -1;
goto out;
}
memcpy(tmp + b64datalen, line, linelen);
b64data = tmp;
b64datalen += linelen;
}
*line = '\0';
if(off >= filedata_len) {
ret = -1;
goto out;
}
if(readline_memory(line, LINE_SIZE, filedata, filedata_len, &off)) {
ret = -1;
goto out;
}
} while(strcmp(line, OPENSSH_HEADER_END) != 0);
if(!b64data) {
return -1;
}
ret = _libssh2_openssh_pem_parse_data(session, passphrase, b64data,
b64datalen, decrypted_buf);
out:
if(b64data) {
_libssh2_explicit_zero(b64data, b64datalen);
LIBSSH2_FREE(session, b64data);
}
return ret;
}
static int static int
read_asn1_length(const unsigned char *data, read_asn1_length(const unsigned char *data,
unsigned int datalen, unsigned int *len) unsigned int datalen, unsigned int *len)
@@ -248,7 +825,8 @@ read_asn1_length(const unsigned char *data,
*len <<= 8; *len <<= 8;
*len |= data[2]; *len |= data[2];
} }
} else { }
else {
lenlen = 0; lenlen = 0;
} }

View File

@@ -116,7 +116,8 @@ publickey_status_error(const LIBSSH2_PUBLICKEY *pkey,
if(status < 0 || status > LIBSSH2_PUBLICKEY_STATUS_CODE_MAX) { if(status < 0 || status > LIBSSH2_PUBLICKEY_STATUS_CODE_MAX) {
msg = "unknown"; msg = "unknown";
} else { }
else {
msg = publickey_status_codes[status].name; msg = publickey_status_codes[status].name;
} }
@@ -143,7 +144,8 @@ publickey_packet_receive(LIBSSH2_PUBLICKEY * pkey,
rc = _libssh2_channel_read(channel, 0, (char *) buffer, 4); rc = _libssh2_channel_read(channel, 0, (char *) buffer, 4);
if(rc == LIBSSH2_ERROR_EAGAIN) { if(rc == LIBSSH2_ERROR_EAGAIN) {
return rc; return rc;
} else if (rc != 4) { }
else if(rc != 4) {
return _libssh2_error(session, LIBSSH2_ERROR_PUBLICKEY_PROTOCOL, return _libssh2_error(session, LIBSSH2_ERROR_PUBLICKEY_PROTOCOL,
"Invalid response from publickey subsystem"); "Invalid response from publickey subsystem");
} }
@@ -165,7 +167,8 @@ publickey_packet_receive(LIBSSH2_PUBLICKEY * pkey,
pkey->receive_packet_len); pkey->receive_packet_len);
if(rc == LIBSSH2_ERROR_EAGAIN) { if(rc == LIBSSH2_ERROR_EAGAIN) {
return rc; return rc;
} else if (rc != (int)pkey->receive_packet_len) { }
else if(rc != (int)pkey->receive_packet_len) {
LIBSSH2_FREE(session, pkey->receive_packet); LIBSSH2_FREE(session, pkey->receive_packet);
pkey->receive_packet = NULL; pkey->receive_packet = NULL;
pkey->receive_state = libssh2_NB_state_idle; pkey->receive_state = libssh2_NB_state_idle;
@@ -235,12 +238,18 @@ publickey_response_success(LIBSSH2_PUBLICKEY * pkey)
int rc = publickey_packet_receive(pkey, &data, &data_len); int rc = publickey_packet_receive(pkey, &data, &data_len);
if(rc == LIBSSH2_ERROR_EAGAIN) { if(rc == LIBSSH2_ERROR_EAGAIN) {
return rc; return rc;
} else if (rc) { }
else if(rc) {
return _libssh2_error(session, LIBSSH2_ERROR_SOCKET_TIMEOUT, return _libssh2_error(session, LIBSSH2_ERROR_SOCKET_TIMEOUT,
"Timeout waiting for response from " "Timeout waiting for response from "
"publickey subsystem"); "publickey subsystem");
} }
if(data_len < 4) {
return _libssh2_error(session, LIBSSH2_ERROR_BUFFER_TOO_SMALL,
"Publickey response too small");
}
s = data; s = data;
response = publickey_response_id(&s, data_len); response = publickey_response_id(&s, data_len);
@@ -248,7 +257,14 @@ publickey_response_success(LIBSSH2_PUBLICKEY * pkey)
case LIBSSH2_PUBLICKEY_RESPONSE_STATUS: case LIBSSH2_PUBLICKEY_RESPONSE_STATUS:
/* Error, or processing complete */ /* Error, or processing complete */
{ {
unsigned long status = _libssh2_ntohu32(s); unsigned long status = 0;
if(data_len < 8) {
return _libssh2_error(session, LIBSSH2_ERROR_BUFFER_TOO_SMALL,
"Publickey response too small");
}
status = _libssh2_ntohu32(s);
LIBSSH2_FREE(session, data); LIBSSH2_FREE(session, data);
@@ -330,7 +346,8 @@ static LIBSSH2_PUBLICKEY *publickey_init(LIBSSH2_SESSION *session)
_libssh2_error(session, LIBSSH2_ERROR_EAGAIN, _libssh2_error(session, LIBSSH2_ERROR_EAGAIN,
"Would block starting publickey subsystem"); "Would block starting publickey subsystem");
return NULL; return NULL;
} else if (rc) { }
else if(rc) {
_libssh2_error(session, LIBSSH2_ERROR_CHANNEL_FAILURE, _libssh2_error(session, LIBSSH2_ERROR_CHANNEL_FAILURE,
"Unable to request publickey subsystem"); "Unable to request publickey subsystem");
goto err_exit; goto err_exit;
@@ -385,7 +402,8 @@ static LIBSSH2_PUBLICKEY *publickey_init(LIBSSH2_SESSION *session)
_libssh2_error(session, LIBSSH2_ERROR_EAGAIN, _libssh2_error(session, LIBSSH2_ERROR_EAGAIN,
"Would block sending publickey version packet"); "Would block sending publickey version packet");
return NULL; return NULL;
} else if (rc < 0) { }
else if(rc < 0) {
_libssh2_error(session, rc, _libssh2_error(session, rc,
"Unable to send publickey version packet"); "Unable to send publickey version packet");
goto err_exit; goto err_exit;
@@ -411,7 +429,8 @@ static LIBSSH2_PUBLICKEY *publickey_init(LIBSSH2_SESSION *session)
"Would block waiting for response from " "Would block waiting for response from "
"publickey subsystem"); "publickey subsystem");
return NULL; return NULL;
} else if (rc) { }
else if(rc) {
_libssh2_error(session, LIBSSH2_ERROR_SOCKET_TIMEOUT, _libssh2_error(session, LIBSSH2_ERROR_SOCKET_TIMEOUT,
"Timeout waiting for response from " "Timeout waiting for response from "
"publickey subsystem"); "publickey subsystem");
@@ -426,22 +445,53 @@ static LIBSSH2_PUBLICKEY *publickey_init(LIBSSH2_SESSION *session)
goto err_exit; goto err_exit;
} }
if(session->pkeyInit_data_len < 4) {
_libssh2_error(session, LIBSSH2_ERROR_BUFFER_TOO_SMALL,
"Public key init data too small");
goto err_exit;
}
switch(response) { switch(response) {
case LIBSSH2_PUBLICKEY_RESPONSE_STATUS: case LIBSSH2_PUBLICKEY_RESPONSE_STATUS:
/* Error */ /* Error */
{ {
unsigned long status, descr_len, lang_len; unsigned long status, descr_len, lang_len;
if(session->pkeyInit_data_len >= 8) {
status = _libssh2_ntohu32(s); status = _libssh2_ntohu32(s);
s += 4; s += 4;
descr_len = _libssh2_ntohu32(s); descr_len = _libssh2_ntohu32(s);
s += 4; s += 4;
}
else {
_libssh2_error(session, LIBSSH2_ERROR_BUFFER_TOO_SMALL,
"Public key init data too small");
goto err_exit;
}
if(s + descr_len + 4 <=
session->pkeyInit_data + session->pkeyInit_data_len) {
/* description starts here */ /* description starts here */
s += descr_len; s += descr_len;
lang_len = _libssh2_ntohu32(s); lang_len = _libssh2_ntohu32(s);
s += 4; s += 4;
}
else {
_libssh2_error(session, LIBSSH2_ERROR_BUFFER_TOO_SMALL,
"Public key init data too small");
goto err_exit;
}
if(s + lang_len <=
session->pkeyInit_data + session->pkeyInit_data_len) {
/* lang starts here */ /* lang starts here */
s += lang_len; s += lang_len;
}
else {
_libssh2_error(session, LIBSSH2_ERROR_BUFFER_TOO_SMALL,
"Public key init data too small");
goto err_exit;
}
if(s > if(s >
session->pkeyInit_data + session->pkeyInit_data_len) { session->pkeyInit_data + session->pkeyInit_data_len) {
@@ -462,7 +512,8 @@ static LIBSSH2_PUBLICKEY *publickey_init(LIBSSH2_SESSION *session)
if(session->pkeyInit_pkey->version > if(session->pkeyInit_pkey->version >
LIBSSH2_PUBLICKEY_VERSION) { LIBSSH2_PUBLICKEY_VERSION) {
_libssh2_debug(session, LIBSSH2_TRACE_PUBLICKEY, _libssh2_debug(session, LIBSSH2_TRACE_PUBLICKEY,
"Truncate remote publickey version from %lu", "Truncate remote publickey version "
"from %lu",
session->pkeyInit_pkey->version); session->pkeyInit_pkey->version);
session->pkeyInit_pkey->version = session->pkeyInit_pkey->version =
LIBSSH2_PUBLICKEY_VERSION; LIBSSH2_PUBLICKEY_VERSION;
@@ -571,7 +622,8 @@ libssh2_publickey_add_ex(LIBSSH2_PUBLICKEY *pkey, const unsigned char *name,
} }
} }
packet_len += 4 + comment_len; packet_len += 4 + comment_len;
} else { }
else {
packet_len += 5; /* overwrite(1) + attribute_count(4) */ packet_len += 5; /* overwrite(1) + attribute_count(4) */
for(i = 0; i < num_attrs; i++) { for(i = 0; i < num_attrs; i++) {
packet_len += 9 + attrs[i].name_len + attrs[i].value_len; packet_len += 9 + attrs[i].name_len + attrs[i].value_len;
@@ -609,7 +661,8 @@ libssh2_publickey_add_ex(LIBSSH2_PUBLICKEY *pkey, const unsigned char *name,
pkey->add_s += 4; pkey->add_s += 4;
memcpy(pkey->add_s, blob, blob_len); memcpy(pkey->add_s, blob, blob_len);
pkey->add_s += blob_len; pkey->add_s += blob_len;
} else { }
else {
/* Version == 2 */ /* Version == 2 */
_libssh2_htonu32(pkey->add_s, name_len); _libssh2_htonu32(pkey->add_s, name_len);
@@ -649,7 +702,8 @@ libssh2_publickey_add_ex(LIBSSH2_PUBLICKEY *pkey, const unsigned char *name,
(pkey->add_s - pkey->add_packet)); (pkey->add_s - pkey->add_packet));
if(rc == LIBSSH2_ERROR_EAGAIN) { if(rc == LIBSSH2_ERROR_EAGAIN) {
return rc; return rc;
} else if ((pkey->add_s - pkey->add_packet) != rc) { }
else if((pkey->add_s - pkey->add_packet) != rc) {
LIBSSH2_FREE(session, pkey->add_packet); LIBSSH2_FREE(session, pkey->add_packet);
pkey->add_packet = NULL; pkey->add_packet = NULL;
return _libssh2_error(session, LIBSSH2_ERROR_SOCKET_SEND, return _libssh2_error(session, LIBSSH2_ERROR_SOCKET_SEND,
@@ -732,7 +786,8 @@ libssh2_publickey_remove_ex(LIBSSH2_PUBLICKEY * pkey,
(pkey->remove_s - pkey->remove_packet)); (pkey->remove_s - pkey->remove_packet));
if(rc == LIBSSH2_ERROR_EAGAIN) { if(rc == LIBSSH2_ERROR_EAGAIN) {
return rc; return rc;
} else if ((pkey->remove_s - pkey->remove_packet) != rc) { }
else if((pkey->remove_s - pkey->remove_packet) != rc) {
LIBSSH2_FREE(session, pkey->remove_packet); LIBSSH2_FREE(session, pkey->remove_packet);
pkey->remove_packet = NULL; pkey->remove_packet = NULL;
pkey->remove_state = libssh2_NB_state_idle; pkey->remove_state = libssh2_NB_state_idle;
@@ -800,7 +855,8 @@ libssh2_publickey_list_fetch(LIBSSH2_PUBLICKEY * pkey, unsigned long *num_keys,
pkey->listFetch_buffer)); pkey->listFetch_buffer));
if(rc == LIBSSH2_ERROR_EAGAIN) { if(rc == LIBSSH2_ERROR_EAGAIN) {
return rc; return rc;
} else if ((pkey->listFetch_s - pkey->listFetch_buffer) != rc) { }
else if((pkey->listFetch_s - pkey->listFetch_buffer) != rc) {
pkey->listFetch_state = libssh2_NB_state_idle; pkey->listFetch_state = libssh2_NB_state_idle;
return _libssh2_error(session, LIBSSH2_ERROR_SOCKET_SEND, return _libssh2_error(session, LIBSSH2_ERROR_SOCKET_SEND,
"Unable to send publickey list packet"); "Unable to send publickey list packet");
@@ -814,7 +870,8 @@ libssh2_publickey_list_fetch(LIBSSH2_PUBLICKEY * pkey, unsigned long *num_keys,
&pkey->listFetch_data_len); &pkey->listFetch_data_len);
if(rc == LIBSSH2_ERROR_EAGAIN) { if(rc == LIBSSH2_ERROR_EAGAIN) {
return rc; return rc;
} else if (rc) { }
else if(rc) {
_libssh2_error(session, LIBSSH2_ERROR_SOCKET_TIMEOUT, _libssh2_error(session, LIBSSH2_ERROR_SOCKET_TIMEOUT,
"Timeout waiting for response from " "Timeout waiting for response from "
"publickey subsystem"); "publickey subsystem");
@@ -836,16 +893,42 @@ libssh2_publickey_list_fetch(LIBSSH2_PUBLICKEY * pkey, unsigned long *num_keys,
{ {
unsigned long status, descr_len, lang_len; unsigned long status, descr_len, lang_len;
if(pkey->listFetch_s + 8 <=
pkey->listFetch_data + pkey->listFetch_data_len) {
status = _libssh2_ntohu32(pkey->listFetch_s); status = _libssh2_ntohu32(pkey->listFetch_s);
pkey->listFetch_s += 4; pkey->listFetch_s += 4;
descr_len = _libssh2_ntohu32(pkey->listFetch_s); descr_len = _libssh2_ntohu32(pkey->listFetch_s);
pkey->listFetch_s += 4; pkey->listFetch_s += 4;
}
else {
_libssh2_error(session, LIBSSH2_ERROR_BUFFER_TOO_SMALL,
"ListFetch data too short");
goto err_exit;
}
if(pkey->listFetch_s + descr_len + 4 <=
pkey->listFetch_data + pkey->listFetch_data_len) {
/* description starts at pkey->listFetch_s */ /* description starts at pkey->listFetch_s */
pkey->listFetch_s += descr_len; pkey->listFetch_s += descr_len;
lang_len = _libssh2_ntohu32(pkey->listFetch_s); lang_len = _libssh2_ntohu32(pkey->listFetch_s);
pkey->listFetch_s += 4; pkey->listFetch_s += 4;
}
else {
_libssh2_error(session, LIBSSH2_ERROR_BUFFER_TOO_SMALL,
"ListFetch data too short");
goto err_exit;
}
if(pkey->listFetch_s + lang_len <=
pkey->listFetch_data + pkey->listFetch_data_len) {
/* lang starts at pkey->listFetch_s */ /* lang starts at pkey->listFetch_s */
pkey->listFetch_s += lang_len; pkey->listFetch_s += lang_len;
}
else {
_libssh2_error(session, LIBSSH2_ERROR_BUFFER_TOO_SMALL,
"ListFetch data too short");
goto err_exit;
}
if(pkey->listFetch_s > if(pkey->listFetch_s >
pkey->listFetch_data + pkey->listFetch_data_len) { pkey->listFetch_data + pkey->listFetch_data_len) {
@@ -887,8 +970,17 @@ libssh2_publickey_list_fetch(LIBSSH2_PUBLICKEY * pkey, unsigned long *num_keys,
if(pkey->version == 1) { if(pkey->version == 1) {
unsigned long comment_len; unsigned long comment_len;
if(pkey->listFetch_s + 4 <=
pkey->listFetch_data + pkey->listFetch_data_len) {
comment_len = _libssh2_ntohu32(pkey->listFetch_s); comment_len = _libssh2_ntohu32(pkey->listFetch_s);
pkey->listFetch_s += 4; pkey->listFetch_s += 4;
}
else {
_libssh2_error(session, LIBSSH2_ERROR_BUFFER_TOO_SMALL,
"ListFetch data too short");
goto err_exit;
}
if(comment_len) { if(comment_len) {
list[keys].num_attrs = 1; list[keys].num_attrs = 1;
list[keys].attrs = list[keys].attrs =
@@ -907,30 +999,114 @@ libssh2_publickey_list_fetch(LIBSSH2_PUBLICKEY * pkey, unsigned long *num_keys,
list[keys].attrs[0].mandatory = 0; list[keys].attrs[0].mandatory = 0;
pkey->listFetch_s += comment_len; pkey->listFetch_s += comment_len;
} else { }
else {
list[keys].num_attrs = 0; list[keys].num_attrs = 0;
list[keys].attrs = NULL; list[keys].attrs = NULL;
} }
if(pkey->listFetch_s + 4 <=
pkey->listFetch_data + pkey->listFetch_data_len) {
list[keys].name_len = _libssh2_ntohu32(pkey->listFetch_s); list[keys].name_len = _libssh2_ntohu32(pkey->listFetch_s);
pkey->listFetch_s += 4; pkey->listFetch_s += 4;
}
else {
_libssh2_error(session, LIBSSH2_ERROR_BUFFER_TOO_SMALL,
"ListFetch data too short");
goto err_exit;
}
if(pkey->listFetch_s + list[keys].name_len <=
pkey->listFetch_data + pkey->listFetch_data_len) {
list[keys].name = pkey->listFetch_s; list[keys].name = pkey->listFetch_s;
pkey->listFetch_s += list[keys].name_len; pkey->listFetch_s += list[keys].name_len;
}
else {
_libssh2_error(session, LIBSSH2_ERROR_BUFFER_TOO_SMALL,
"ListFetch data too short");
goto err_exit;
}
if(pkey->listFetch_s + 4 <=
pkey->listFetch_data + pkey->listFetch_data_len) {
list[keys].blob_len = _libssh2_ntohu32(pkey->listFetch_s); list[keys].blob_len = _libssh2_ntohu32(pkey->listFetch_s);
pkey->listFetch_s += 4; pkey->listFetch_s += 4;
}
else {
_libssh2_error(session, LIBSSH2_ERROR_BUFFER_TOO_SMALL,
"ListFetch data too short");
goto err_exit;
}
if(pkey->listFetch_s + list[keys].blob_len <=
pkey->listFetch_data + pkey->listFetch_data_len) {
list[keys].blob = pkey->listFetch_s; list[keys].blob = pkey->listFetch_s;
pkey->listFetch_s += list[keys].blob_len; pkey->listFetch_s += list[keys].blob_len;
} else { }
else {
_libssh2_error(session, LIBSSH2_ERROR_BUFFER_TOO_SMALL,
"ListFetch data too short");
goto err_exit;
}
}
else {
/* Version == 2 */ /* Version == 2 */
if(pkey->listFetch_s + 4 <=
pkey->listFetch_data + pkey->listFetch_data_len) {
list[keys].name_len = _libssh2_ntohu32(pkey->listFetch_s); list[keys].name_len = _libssh2_ntohu32(pkey->listFetch_s);
pkey->listFetch_s += 4; pkey->listFetch_s += 4;
}
else {
_libssh2_error(session, LIBSSH2_ERROR_BUFFER_TOO_SMALL,
"ListFetch data too short");
goto err_exit;
}
if(pkey->listFetch_s + list[keys].name_len <=
pkey->listFetch_data + pkey->listFetch_data_len) {
list[keys].name = pkey->listFetch_s; list[keys].name = pkey->listFetch_s;
pkey->listFetch_s += list[keys].name_len; pkey->listFetch_s += list[keys].name_len;
}
else {
_libssh2_error(session, LIBSSH2_ERROR_BUFFER_TOO_SMALL,
"ListFetch data too short");
goto err_exit;
}
if(pkey->listFetch_s + 4 <=
pkey->listFetch_data + pkey->listFetch_data_len) {
list[keys].blob_len = _libssh2_ntohu32(pkey->listFetch_s); list[keys].blob_len = _libssh2_ntohu32(pkey->listFetch_s);
pkey->listFetch_s += 4; pkey->listFetch_s += 4;
}
else {
_libssh2_error(session, LIBSSH2_ERROR_BUFFER_TOO_SMALL,
"ListFetch data too short");
goto err_exit;
}
if(pkey->listFetch_s + list[keys].blob_len <=
pkey->listFetch_data + pkey->listFetch_data_len) {
list[keys].blob = pkey->listFetch_s; list[keys].blob = pkey->listFetch_s;
pkey->listFetch_s += list[keys].blob_len; pkey->listFetch_s += list[keys].blob_len;
}
else {
_libssh2_error(session, LIBSSH2_ERROR_BUFFER_TOO_SMALL,
"ListFetch data too short");
goto err_exit;
}
if(pkey->listFetch_s + 4 <=
pkey->listFetch_data + pkey->listFetch_data_len) {
list[keys].num_attrs = _libssh2_ntohu32(pkey->listFetch_s); list[keys].num_attrs = _libssh2_ntohu32(pkey->listFetch_s);
pkey->listFetch_s += 4; pkey->listFetch_s += 4;
}
else {
_libssh2_error(session, LIBSSH2_ERROR_BUFFER_TOO_SMALL,
"ListFetch data too short");
goto err_exit;
}
if(list[keys].num_attrs) { if(list[keys].num_attrs) {
list[keys].attrs = list[keys].attrs =
LIBSSH2_ALLOC(session, LIBSSH2_ALLOC(session,
@@ -943,21 +1119,64 @@ libssh2_publickey_list_fetch(LIBSSH2_PUBLICKEY * pkey, unsigned long *num_keys,
goto err_exit; goto err_exit;
} }
for(i = 0; i < list[keys].num_attrs; i++) { for(i = 0; i < list[keys].num_attrs; i++) {
if(pkey->listFetch_s + 4 <=
pkey->listFetch_data + pkey->listFetch_data_len) {
list[keys].attrs[i].name_len = list[keys].attrs[i].name_len =
_libssh2_ntohu32(pkey->listFetch_s); _libssh2_ntohu32(pkey->listFetch_s);
pkey->listFetch_s += 4; pkey->listFetch_s += 4;
list[keys].attrs[i].name = (char *) pkey->listFetch_s; }
else {
_libssh2_error(session,
LIBSSH2_ERROR_BUFFER_TOO_SMALL,
"ListFetch data too short");
goto err_exit;
}
if(pkey->listFetch_s + list[keys].attrs[i].name_len <=
pkey->listFetch_data + pkey->listFetch_data_len) {
list[keys].attrs[i].name =
(char *) pkey->listFetch_s;
pkey->listFetch_s += list[keys].attrs[i].name_len; pkey->listFetch_s += list[keys].attrs[i].name_len;
}
else {
_libssh2_error(session,
LIBSSH2_ERROR_BUFFER_TOO_SMALL,
"ListFetch data too short");
goto err_exit;
}
if(pkey->listFetch_s + 4 <=
pkey->listFetch_data + pkey->listFetch_data_len) {
list[keys].attrs[i].value_len = list[keys].attrs[i].value_len =
_libssh2_ntohu32(pkey->listFetch_s); _libssh2_ntohu32(pkey->listFetch_s);
pkey->listFetch_s += 4; pkey->listFetch_s += 4;
list[keys].attrs[i].value = (char *) pkey->listFetch_s; }
else {
_libssh2_error(session,
LIBSSH2_ERROR_BUFFER_TOO_SMALL,
"ListFetch data too short");
goto err_exit;
}
if(pkey->listFetch_s +
list[keys].attrs[i].value_len <=
pkey->listFetch_data + pkey->listFetch_data_len) {
list[keys].attrs[i].value =
(char *) pkey->listFetch_s;
pkey->listFetch_s += list[keys].attrs[i].value_len; pkey->listFetch_s += list[keys].attrs[i].value_len;
}
else {
_libssh2_error(session,
LIBSSH2_ERROR_BUFFER_TOO_SMALL,
"ListFetch data too short");
goto err_exit;
}
/* actually an ignored value */ /* actually an ignored value */
list[keys].attrs[i].mandatory = 0; list[keys].attrs[i].mandatory = 0;
} }
} else { }
else {
list[keys].attrs = NULL; list[keys].attrs = NULL;
} }
} }

View File

@@ -1,4 +1,4 @@
/* Copyright (c) 2009-2010 by Daniel Stenberg /* Copyright (c) 2009-2019 by Daniel Stenberg
* Copyright (c) 2004-2008, Sara Golemon <sarag@libssh2.org> * Copyright (c) 2004-2008, Sara Golemon <sarag@libssh2.org>
* All rights reserved. * All rights reserved.
* *
@@ -303,8 +303,8 @@ scp_recv(LIBSSH2_SESSION * session, const char *path, libssh2_struct_stat * sb)
&session->scpRecv_command[cmd_len], &session->scpRecv_command[cmd_len],
session->scpRecv_command_len - cmd_len); session->scpRecv_command_len - cmd_len);
session->scpRecv_command[cmd_len] = '\0'; /* the command to exec should _not_ be NUL-terminated */
session->scpRecv_command_len = cmd_len + 1; session->scpRecv_command_len = cmd_len;
_libssh2_debug(session, LIBSSH2_TRACE_SCP, _libssh2_debug(session, LIBSSH2_TRACE_SCP,
"Opening channel for SCP receive"); "Opening channel for SCP receive");
@@ -347,7 +347,8 @@ scp_recv(LIBSSH2_SESSION * session, const char *path, libssh2_struct_stat * sb)
_libssh2_error(session, LIBSSH2_ERROR_EAGAIN, _libssh2_error(session, LIBSSH2_ERROR_EAGAIN,
"Would block requesting SCP startup"); "Would block requesting SCP startup");
return NULL; return NULL;
} else if (rc) { }
else if(rc) {
LIBSSH2_FREE(session, session->scpRecv_command); LIBSSH2_FREE(session, session->scpRecv_command);
session->scpRecv_command = NULL; session->scpRecv_command = NULL;
goto scp_recv_error; goto scp_recv_error;
@@ -369,7 +370,8 @@ scp_recv(LIBSSH2_SESSION * session, const char *path, libssh2_struct_stat * sb)
_libssh2_error(session, LIBSSH2_ERROR_EAGAIN, _libssh2_error(session, LIBSSH2_ERROR_EAGAIN,
"Would block sending initial wakeup"); "Would block sending initial wakeup");
return NULL; return NULL;
} else if (rc != 1) { }
else if(rc != 1) {
goto scp_recv_error; goto scp_recv_error;
} }
@@ -473,7 +475,8 @@ scp_recv(LIBSSH2_SESSION * session, const char *path, libssh2_struct_stat * sb)
LIBSSH2_SCP_RESPONSE_BUFLEN) { LIBSSH2_SCP_RESPONSE_BUFLEN) {
/* You had your chance */ /* You had your chance */
_libssh2_error(session, LIBSSH2_ERROR_SCP_PROTOCOL, _libssh2_error(session, LIBSSH2_ERROR_SCP_PROTOCOL,
"Unterminated response from SCP server"); "Unterminated response from "
"SCP server");
goto scp_recv_error; goto scp_recv_error;
} }
/* Way too short to be an SCP response, or not done yet, /* Way too short to be an SCP response, or not done yet,
@@ -520,7 +523,8 @@ scp_recv(LIBSSH2_SESSION * session, const char *path, libssh2_struct_stat * sb)
if(!s || ((s - p) <= 0)) { if(!s || ((s - p) <= 0)) {
/* No spaces or space in the wrong spot */ /* No spaces or space in the wrong spot */
_libssh2_error(session, LIBSSH2_ERROR_SCP_PROTOCOL, _libssh2_error(session, LIBSSH2_ERROR_SCP_PROTOCOL,
"Invalid response from SCP server, malformed mtime.usec"); "Invalid response from SCP server, "
"malformed mtime.usec");
goto scp_recv_error; goto scp_recv_error;
} }
@@ -530,7 +534,8 @@ scp_recv(LIBSSH2_SESSION * session, const char *path, libssh2_struct_stat * sb)
if(!p || ((p - s) <= 0)) { if(!p || ((p - s) <= 0)) {
/* No spaces or space in the wrong spot */ /* No spaces or space in the wrong spot */
_libssh2_error(session, LIBSSH2_ERROR_SCP_PROTOCOL, _libssh2_error(session, LIBSSH2_ERROR_SCP_PROTOCOL,
"Invalid response from SCP server, too short or malformed"); "Invalid response from SCP server, "
"too short or malformed");
goto scp_recv_error; goto scp_recv_error;
} }
@@ -551,7 +556,8 @@ scp_recv(LIBSSH2_SESSION * session, const char *path, libssh2_struct_stat * sb)
_libssh2_error(session, LIBSSH2_ERROR_EAGAIN, _libssh2_error(session, LIBSSH2_ERROR_EAGAIN,
"Would block waiting to send SCP ACK"); "Would block waiting to send SCP ACK");
return NULL; return NULL;
} else if (rc != 1) { }
else if(rc != 1) {
goto scp_recv_error; goto scp_recv_error;
} }
@@ -629,7 +635,8 @@ scp_recv(LIBSSH2_SESSION * session, const char *path, libssh2_struct_stat * sb)
LIBSSH2_SCP_RESPONSE_BUFLEN) { LIBSSH2_SCP_RESPONSE_BUFLEN) {
/* You had your chance */ /* You had your chance */
_libssh2_error(session, LIBSSH2_ERROR_SCP_PROTOCOL, _libssh2_error(session, LIBSSH2_ERROR_SCP_PROTOCOL,
"Unterminated response from SCP server"); "Unterminated response "
"from SCP server");
goto scp_recv_error; goto scp_recv_error;
} }
/* Way too short to be an SCP response, or not done yet, /* Way too short to be an SCP response, or not done yet,
@@ -653,7 +660,8 @@ scp_recv(LIBSSH2_SESSION * session, const char *path, libssh2_struct_stat * sb)
if(session->scpRecv_response_len < 6) { if(session->scpRecv_response_len < 6) {
/* EOL came too soon */ /* EOL came too soon */
_libssh2_error(session, LIBSSH2_ERROR_SCP_PROTOCOL, _libssh2_error(session, LIBSSH2_ERROR_SCP_PROTOCOL,
"Invalid response from SCP server, too short"); "Invalid response from SCP server, "
"too short");
goto scp_recv_error; goto scp_recv_error;
} }
@@ -663,7 +671,8 @@ scp_recv(LIBSSH2_SESSION * session, const char *path, libssh2_struct_stat * sb)
if(!p || ((p - s) <= 0)) { if(!p || ((p - s) <= 0)) {
/* No spaces or space in the wrong spot */ /* No spaces or space in the wrong spot */
_libssh2_error(session, LIBSSH2_ERROR_SCP_PROTOCOL, _libssh2_error(session, LIBSSH2_ERROR_SCP_PROTOCOL,
"Invalid response from SCP server, malformed mode"); "Invalid response from SCP server, "
"malformed mode");
goto scp_recv_error; goto scp_recv_error;
} }
@@ -673,7 +682,8 @@ scp_recv(LIBSSH2_SESSION * session, const char *path, libssh2_struct_stat * sb)
session->scpRecv_mode = strtol(s, &e, 8); session->scpRecv_mode = strtol(s, &e, 8);
if(e && *e) { if(e && *e) {
_libssh2_error(session, LIBSSH2_ERROR_SCP_PROTOCOL, _libssh2_error(session, LIBSSH2_ERROR_SCP_PROTOCOL,
"Invalid response from SCP server, invalid mode"); "Invalid response from SCP server, "
"invalid mode");
goto scp_recv_error; goto scp_recv_error;
} }
@@ -681,7 +691,8 @@ scp_recv(LIBSSH2_SESSION * session, const char *path, libssh2_struct_stat * sb)
if(!s || ((s - p) <= 0)) { if(!s || ((s - p) <= 0)) {
/* No spaces or space in the wrong spot */ /* No spaces or space in the wrong spot */
_libssh2_error(session, LIBSSH2_ERROR_SCP_PROTOCOL, _libssh2_error(session, LIBSSH2_ERROR_SCP_PROTOCOL,
"Invalid response from SCP server, too short or malformed"); "Invalid response from SCP server, "
"too short or malformed");
goto scp_recv_error; goto scp_recv_error;
} }
@@ -690,7 +701,8 @@ scp_recv(LIBSSH2_SESSION * session, const char *path, libssh2_struct_stat * sb)
session->scpRecv_size = scpsize_strtol(p, &e, 10); session->scpRecv_size = scpsize_strtol(p, &e, 10);
if(e && *e) { if(e && *e) {
_libssh2_error(session, LIBSSH2_ERROR_SCP_PROTOCOL, _libssh2_error(session, LIBSSH2_ERROR_SCP_PROTOCOL,
"Invalid response from SCP server, invalid size"); "Invalid response from SCP server, "
"invalid size");
goto scp_recv_error; goto scp_recv_error;
} }
@@ -707,7 +719,8 @@ scp_recv(LIBSSH2_SESSION * session, const char *path, libssh2_struct_stat * sb)
_libssh2_error(session, LIBSSH2_ERROR_EAGAIN, _libssh2_error(session, LIBSSH2_ERROR_EAGAIN,
"Would block sending SCP ACK"); "Would block sending SCP ACK");
return NULL; return NULL;
} else if (rc != 1) { }
else if(rc != 1) {
goto scp_recv_error; goto scp_recv_error;
} }
_libssh2_debug(session, LIBSSH2_TRACE_SCP, _libssh2_debug(session, LIBSSH2_TRACE_SCP,
@@ -761,9 +774,9 @@ scp_recv(LIBSSH2_SESSION * session, const char *path, libssh2_struct_stat * sb)
* *
* DEPRECATED * DEPRECATED
* *
* Open a channel and request a remote file via SCP. This receives files larger * Open a channel and request a remote file via SCP. This receives files
* than 2 GB, but is unable to report the proper size on platforms where the * larger than 2 GB, but is unable to report the proper size on platforms
* st_size member of struct stat is limited to 2 GB (e.g. windows). * where the st_size member of struct stat is limited to 2 GB (e.g. windows).
* *
*/ */
LIBSSH2_API LIBSSH2_CHANNEL * LIBSSH2_API LIBSSH2_CHANNEL *
@@ -771,9 +784,11 @@ libssh2_scp_recv(LIBSSH2_SESSION *session, const char *path, struct stat * sb)
{ {
LIBSSH2_CHANNEL *ptr; LIBSSH2_CHANNEL *ptr;
/* scp_recv uses libssh2_struct_stat, so pass one if the caller gave us a struct to populate... */ /* scp_recv uses libssh2_struct_stat, so pass one if the caller gave us a
struct to populate... */
libssh2_struct_stat sb_intl; libssh2_struct_stat sb_intl;
libssh2_struct_stat *sb_ptr; libssh2_struct_stat *sb_ptr;
memset(&sb_intl, 0, sizeof(sb_intl));
sb_ptr = sb ? &sb_intl : NULL; sb_ptr = sb ? &sb_intl : NULL;
BLOCK_ADJUST_ERRNO(ptr, session, scp_recv(session, path, sb_ptr)); BLOCK_ADJUST_ERRNO(ptr, session, scp_recv(session, path, sb_ptr));
@@ -799,7 +814,8 @@ libssh2_scp_recv(LIBSSH2_SESSION *session, const char *path, struct stat * sb)
* *
*/ */
LIBSSH2_API LIBSSH2_CHANNEL * LIBSSH2_API LIBSSH2_CHANNEL *
libssh2_scp_recv2(LIBSSH2_SESSION *session, const char *path, libssh2_struct_stat * sb) libssh2_scp_recv2(LIBSSH2_SESSION *session, const char *path,
libssh2_struct_stat *sb)
{ {
LIBSSH2_CHANNEL *ptr; LIBSSH2_CHANNEL *ptr;
BLOCK_ADJUST_ERRNO(ptr, session, scp_recv(session, path, sb)); BLOCK_ADJUST_ERRNO(ptr, session, scp_recv(session, path, sb));
@@ -845,8 +861,8 @@ scp_send(LIBSSH2_SESSION * session, const char *path, int mode,
&session->scpSend_command[cmd_len], &session->scpSend_command[cmd_len],
session->scpSend_command_len - cmd_len); session->scpSend_command_len - cmd_len);
session->scpSend_command[cmd_len] = '\0'; /* the command to exec should _not_ be NUL-terminated */
session->scpSend_command_len = cmd_len + 1; session->scpSend_command_len = cmd_len;
_libssh2_debug(session, LIBSSH2_TRACE_SCP, _libssh2_debug(session, LIBSSH2_TRACE_SCP,
"Opening channel for SCP send"); "Opening channel for SCP send");
@@ -948,7 +964,8 @@ scp_send(LIBSSH2_SESSION * session, const char *path, int mode,
_libssh2_error(session, LIBSSH2_ERROR_EAGAIN, _libssh2_error(session, LIBSSH2_ERROR_EAGAIN,
"Would block sending time data for SCP file"); "Would block sending time data for SCP file");
return NULL; return NULL;
} else if (rc != (int)session->scpSend_response_len) { }
else if(rc != (int)session->scpSend_response_len) {
_libssh2_error(session, LIBSSH2_ERROR_SOCKET_SEND, _libssh2_error(session, LIBSSH2_ERROR_SOCKET_SEND,
"Unable to send time data for SCP file"); "Unable to send time data for SCP file");
goto scp_send_error; goto scp_send_error;
@@ -981,7 +998,8 @@ scp_send(LIBSSH2_SESSION * session, const char *path, int mode,
session->scpSend_state = libssh2_NB_state_sent4; session->scpSend_state = libssh2_NB_state_sent4;
} }
} else { }
else {
if(session->scpSend_state == libssh2_NB_state_sent2) { if(session->scpSend_state == libssh2_NB_state_sent2) {
session->scpSend_state = libssh2_NB_state_sent4; session->scpSend_state = libssh2_NB_state_sent4;
} }
@@ -1014,7 +1032,8 @@ scp_send(LIBSSH2_SESSION * session, const char *path, int mode,
_libssh2_error(session, LIBSSH2_ERROR_EAGAIN, _libssh2_error(session, LIBSSH2_ERROR_EAGAIN,
"Would block send core file data for SCP file"); "Would block send core file data for SCP file");
return NULL; return NULL;
} else if (rc != (int)session->scpSend_response_len) { }
else if(rc != (int)session->scpSend_response_len) {
_libssh2_error(session, LIBSSH2_ERROR_SOCKET_SEND, _libssh2_error(session, LIBSSH2_ERROR_SOCKET_SEND,
"Unable to send core file data for SCP file"); "Unable to send core file data for SCP file");
goto scp_send_error; goto scp_send_error;

View File

@@ -103,7 +103,8 @@ banner_receive(LIBSSH2_SESSION * session)
banner_len = 0; banner_len = 0;
session->banner_TxRx_state = libssh2_NB_state_created; session->banner_TxRx_state = libssh2_NB_state_created;
} else { }
else {
banner_len = session->banner_TxRx_total_send; banner_len = session->banner_TxRx_total_send;
} }
@@ -169,6 +170,9 @@ banner_receive(LIBSSH2_SESSION * session)
if(!banner_len) if(!banner_len)
return LIBSSH2_ERROR_BANNER_RECV; return LIBSSH2_ERROR_BANNER_RECV;
if(session->remote.banner)
LIBSSH2_FREE(session, session->remote.banner);
session->remote.banner = LIBSSH2_ALLOC(session, banner_len + 1); session->remote.banner = LIBSSH2_ALLOC(session, banner_len + 1);
if(!session->remote.banner) { if(!session->remote.banner) {
return _libssh2_error(session, LIBSSH2_ERROR_ALLOC, return _libssh2_error(session, LIBSSH2_ERROR_ALLOC,
@@ -212,7 +216,8 @@ banner_send(LIBSSH2_SESSION * session)
if(banner_len < 256) { if(banner_len < 256) {
memcpy(banner_dup, banner, banner_len - 2); memcpy(banner_dup, banner, banner_len - 2);
banner_dup[banner_len - 2] = '\0'; banner_dup[banner_len - 2] = '\0';
} else { }
else {
memcpy(banner_dup, banner, 255); memcpy(banner_dup, banner, 255);
banner[255] = '\0'; banner[255] = '\0';
} }
@@ -344,9 +349,9 @@ get_socket_nonblocking(int sockfd)
#define GETBLOCK 0 #define GETBLOCK 0
#ifdef HAVE_O_NONBLOCK #ifdef HAVE_O_NONBLOCK
/* most recent unix versions */ /* most recent unix versions */
int flags; int flags = fcntl(sockfd, F_GETFL, 0);
if ((flags = fcntl(sockfd, F_GETFL, 0)) == -1) { if(flags == -1) {
/* Assume blocking on error */ /* Assume blocking on error */
return 1; return 1;
} }
@@ -392,9 +397,9 @@ get_socket_nonblocking(int sockfd)
callstat = getsockopt(sockfd, SOL_SOCKET, SO_STATE, callstat = getsockopt(sockfd, SOL_SOCKET, SO_STATE,
(char *)&sockstat, &size); (char *)&sockstat, &size);
if ( callstat == -1 ) return(0); if(callstat == -1) return 0;
if ( (sockstat&SS_NBIO) )return(1); if((sockstat&SS_NBIO) != 0) return 1;
return(0); return 0;
#undef GETBLOCK #undef GETBLOCK
#define GETBLOCK 6 #define GETBLOCK 6
@@ -508,9 +513,11 @@ libssh2_session_init_ex(LIBSSH2_ALLOC_FUNC((*my_alloc)),
* Set (or reset) a callback function * Set (or reset) a callback function
* Returns the prior address * Returns the prior address
* *
* FIXME: this function relies on that we can typecast function pointers * ALERT: this function relies on that we can typecast function pointers
* to void pointers, which isn't allowed in ISO C! * to void pointers, which isn't allowed in ISO C!
*/ */
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wpedantic"
LIBSSH2_API void * LIBSSH2_API void *
libssh2_session_callback_set(LIBSSH2_SESSION * session, libssh2_session_callback_set(LIBSSH2_SESSION * session,
int cbtype, void *callback) int cbtype, void *callback)
@@ -553,10 +560,12 @@ libssh2_session_callback_set(LIBSSH2_SESSION * session,
session->recv = callback; session->recv = callback;
return oldcb; return oldcb;
} }
_libssh2_debug(session, LIBSSH2_TRACE_TRANS, "Setting Callback %d", cbtype); _libssh2_debug(session, LIBSSH2_TRACE_TRANS, "Setting Callback %d",
cbtype);
return NULL; return NULL;
} }
#pragma GCC diagnostic pop
/* /*
* _libssh2_wait_socket() * _libssh2_wait_socket()
@@ -703,7 +712,9 @@ session_startup(LIBSSH2_SESSION *session, libssh2_socket_t sock)
if(session->startup_state == libssh2_NB_state_created) { if(session->startup_state == libssh2_NB_state_created) {
rc = banner_send(session); rc = banner_send(session);
if (rc) { if(rc == LIBSSH2_ERROR_EAGAIN)
return rc;
else if(rc) {
return _libssh2_error(session, rc, return _libssh2_error(session, rc,
"Failed sending banner"); "Failed sending banner");
} }
@@ -714,7 +725,9 @@ session_startup(LIBSSH2_SESSION *session, libssh2_socket_t sock)
if(session->startup_state == libssh2_NB_state_sent) { if(session->startup_state == libssh2_NB_state_sent) {
do { do {
rc = banner_receive(session); rc = banner_receive(session);
if (rc) if(rc == LIBSSH2_ERROR_EAGAIN)
return rc;
else if(rc)
return _libssh2_error(session, rc, return _libssh2_error(session, rc,
"Failed getting banner"); "Failed getting banner");
} while(strncmp("SSH-", (char *)session->remote.banner, 4)); } while(strncmp("SSH-", (char *)session->remote.banner, 4));
@@ -724,7 +737,9 @@ session_startup(LIBSSH2_SESSION *session, libssh2_socket_t sock)
if(session->startup_state == libssh2_NB_state_sent1) { if(session->startup_state == libssh2_NB_state_sent1) {
rc = _libssh2_kex_exchange(session, 0, &session->startup_key_state); rc = _libssh2_kex_exchange(session, 0, &session->startup_key_state);
if (rc) if(rc == LIBSSH2_ERROR_EAGAIN)
return rc;
else if(rc)
return _libssh2_error(session, rc, return _libssh2_error(session, rc,
"Unable to exchange encryption keys"); "Unable to exchange encryption keys");
@@ -749,7 +764,9 @@ session_startup(LIBSSH2_SESSION *session, libssh2_socket_t sock)
rc = _libssh2_transport_send(session, session->startup_service, rc = _libssh2_transport_send(session, session->startup_service,
sizeof("ssh-userauth") + 5 - 1, sizeof("ssh-userauth") + 5 - 1,
NULL, 0); NULL, 0);
if (rc) { if(rc == LIBSSH2_ERROR_EAGAIN)
return rc;
else if(rc) {
return _libssh2_error(session, rc, return _libssh2_error(session, rc,
"Unable to ask for ssh-userauth service"); "Unable to ask for ssh-userauth service");
} }
@@ -773,6 +790,7 @@ session_startup(LIBSSH2_SESSION *session, libssh2_socket_t sock)
session->startup_service_length = session->startup_service_length =
_libssh2_ntohu32(session->startup_data + 1); _libssh2_ntohu32(session->startup_data + 1);
if((session->startup_service_length != (sizeof("ssh-userauth") - 1)) if((session->startup_service_length != (sizeof("ssh-userauth") - 1))
|| strncmp("ssh-userauth", (char *) session->startup_data + 5, || strncmp("ssh-userauth", (char *) session->startup_data + 5,
session->startup_service_length)) { session->startup_service_length)) {
@@ -844,7 +862,8 @@ session_free(LIBSSH2_SESSION *session)
int packets_left = 0; int packets_left = 0;
if(session->free_state == libssh2_NB_state_idle) { if(session->free_state == libssh2_NB_state_idle) {
_libssh2_debug(session, LIBSSH2_TRACE_TRANS, "Freeing session resource", _libssh2_debug(session, LIBSSH2_TRACE_TRANS,
"Freeing session resource",
session->remote.banner); session->remote.banner);
session->free_state = libssh2_NB_state_created; session->free_state = libssh2_NB_state_created;
@@ -1067,7 +1086,8 @@ session_free(LIBSSH2_SESSION *session)
} }
/* error string */ /* error string */
if (session->err_msg && ((session->err_flags & LIBSSH2_ERR_FLAG_DUP) != 0)) { if(session->err_msg &&
((session->err_flags & LIBSSH2_ERR_FLAG_DUP) != 0)) {
LIBSSH2_FREE(session, (char *)session->err_msg); LIBSSH2_FREE(session, (char *)session->err_msg);
} }
@@ -1151,7 +1171,7 @@ libssh2_session_disconnect_ex(LIBSSH2_SESSION *session, int reason,
const char *desc, const char *lang) const char *desc, const char *lang)
{ {
int rc; int rc;
session->state &= ~LIBSSH2_STATE_EXCHANGING_KEYS;
BLOCK_ADJUST(rc, session, BLOCK_ADJUST(rc, session,
session_disconnect(session, reason, desc, lang)); session_disconnect(session, reason, desc, lang));
@@ -1254,7 +1274,8 @@ libssh2_session_last_error(LIBSSH2_SESSION * session, char **errmsg,
if(*errmsg) { if(*errmsg) {
**errmsg = 0; **errmsg = 0;
} }
} else { }
else {
*errmsg = (char *) ""; *errmsg = (char *) "";
} }
} }
@@ -1418,12 +1439,18 @@ libssh2_poll_channel_read(LIBSSH2_CHANNEL *channel, int extended)
packet = _libssh2_list_first(&session->packets); packet = _libssh2_list_first(&session->packets);
while(packet) { while(packet) {
if(packet->data_len < 5) {
return _libssh2_error(session, LIBSSH2_ERROR_BUFFER_TOO_SMALL,
"Packet too small");
}
if(channel->local.id == _libssh2_ntohu32(packet->data + 1)) { if(channel->local.id == _libssh2_ntohu32(packet->data + 1)) {
if(extended == 1 && if(extended == 1 &&
(packet->data[0] == SSH_MSG_CHANNEL_EXTENDED_DATA (packet->data[0] == SSH_MSG_CHANNEL_EXTENDED_DATA
|| packet->data[0] == SSH_MSG_CHANNEL_DATA)) { || packet->data[0] == SSH_MSG_CHANNEL_DATA)) {
return 1; return 1;
} else if ( extended == 0 && }
else if(extended == 0 &&
packet->data[0] == SSH_MSG_CHANNEL_DATA) { packet->data[0] == SSH_MSG_CHANNEL_DATA) {
return 1; return 1;
} }
@@ -1671,7 +1698,8 @@ libssh2_poll(LIBSSH2_POLLFD * fds, unsigned int nfds, long timeout)
switch(fds[i].type) { switch(fds[i].type) {
case LIBSSH2_POLLFD_SOCKET: case LIBSSH2_POLLFD_SOCKET:
fds[i].revents = sockets[i].revents; fds[i].revents = sockets[i].revents;
sockets[i].revents = 0; /* In case we loop again, be nice */ sockets[i].revents = 0; /* In case we loop again, be
nice */
if(fds[i].revents) { if(fds[i].revents) {
active_fds++; active_fds++;
} }
@@ -1679,7 +1707,8 @@ libssh2_poll(LIBSSH2_POLLFD * fds, unsigned int nfds, long timeout)
case LIBSSH2_POLLFD_CHANNEL: case LIBSSH2_POLLFD_CHANNEL:
if(sockets[i].events & POLLIN) { if(sockets[i].events & POLLIN) {
/* Spin session until no data available */ /* Spin session until no data available */
while (_libssh2_transport_read(fds[i].fd.channel->session) while(_libssh2_transport_read(fds[i].fd.
channel->session)
> 0); > 0);
} }
if(sockets[i].revents & POLLHUP) { if(sockets[i].revents & POLLHUP) {
@@ -1692,7 +1721,8 @@ libssh2_poll(LIBSSH2_POLLFD * fds, unsigned int nfds, long timeout)
case LIBSSH2_POLLFD_LISTENER: case LIBSSH2_POLLFD_LISTENER:
if(sockets[i].events & POLLIN) { if(sockets[i].events & POLLIN) {
/* Spin session until no data available */ /* Spin session until no data available */
while (_libssh2_transport_read(fds[i].fd.listener->session) while(_libssh2_transport_read(fds[i].fd.
listener->session)
> 0); > 0);
} }
if(sockets[i].revents & POLLHUP) { if(sockets[i].revents & POLLHUP) {
@@ -1743,9 +1773,11 @@ libssh2_poll(LIBSSH2_POLLFD * fds, unsigned int nfds, long timeout)
break; break;
case LIBSSH2_POLLFD_CHANNEL: case LIBSSH2_POLLFD_CHANNEL:
if (FD_ISSET(fds[i].fd.channel->session->socket_fd, &rfds)) { if(FD_ISSET(fds[i].fd.channel->session->socket_fd,
&rfds)) {
/* Spin session until no data available */ /* Spin session until no data available */
while (_libssh2_transport_read(fds[i].fd.channel->session) while(_libssh2_transport_read(fds[i].fd.
channel->session)
> 0); > 0);
} }
break; break;
@@ -1754,7 +1786,8 @@ libssh2_poll(LIBSSH2_POLLFD * fds, unsigned int nfds, long timeout)
if(FD_ISSET if(FD_ISSET
(fds[i].fd.listener->session->socket_fd, &rfds)) { (fds[i].fd.listener->session->socket_fd, &rfds)) {
/* Spin session until no data available */ /* Spin session until no data available */
while (_libssh2_transport_read(fds[i].fd.listener->session) while(_libssh2_transport_read(fds[i].fd.
listener->session)
> 0); > 0);
} }
break; break;

View File

@@ -1,6 +1,6 @@
/* Copyright (c) 2004-2008, Sara Golemon <sarag@libssh2.org> /* Copyright (c) 2004-2008, Sara Golemon <sarag@libssh2.org>
* Copyright (c) 2007 Eli Fant <elifantu@mail.ru> * Copyright (c) 2007 Eli Fant <elifantu@mail.ru>
* Copyright (c) 2009-2014 by Daniel Stenberg * Copyright (c) 2009-2019 by Daniel Stenberg
* All rights reserved. * All rights reserved.
* *
* Redistribution and use in source and binary forms, * Redistribution and use in source and binary forms,
@@ -91,7 +91,7 @@
/* This is the maximum packet length to accept, as larger than this indicate /* This is the maximum packet length to accept, as larger than this indicate
some kind of server problem. */ some kind of server problem. */
#define LIBSSH2_SFTP_PACKET_MAXLEN 80000 #define LIBSSH2_SFTP_PACKET_MAXLEN (256 * 1024)
static int sftp_packet_ask(LIBSSH2_SFTP *sftp, unsigned char packet_type, static int sftp_packet_ask(LIBSSH2_SFTP *sftp, unsigned char packet_type,
uint32_t request_id, unsigned char **data, uint32_t request_id, unsigned char **data,
@@ -161,7 +161,8 @@ remove_zombie_request(LIBSSH2_SFTP *sftp, uint32_t request_id)
request_id); request_id);
if(zombie) { if(zombie) {
_libssh2_debug(session, LIBSSH2_TRACE_SFTP, _libssh2_debug(session, LIBSSH2_TRACE_SFTP,
"Removing request ID %ld from the list of zombie requests", "Removing request ID %ld from the list of "
"zombie requests",
request_id); request_id);
_libssh2_list_remove(&zombie->node); _libssh2_list_remove(&zombie->node);
@@ -345,10 +346,14 @@ sftp_packet_read(LIBSSH2_SFTP *sftp)
sftp->partial_len = _libssh2_ntohu32(sftp->partial_size); sftp->partial_len = _libssh2_ntohu32(sftp->partial_size);
/* make sure we don't proceed if the packet size is unreasonably /* make sure we don't proceed if the packet size is unreasonably
large */ large */
if (sftp->partial_len > LIBSSH2_SFTP_PACKET_MAXLEN) if(sftp->partial_len > LIBSSH2_SFTP_PACKET_MAXLEN) {
libssh2_channel_flush(channel);
sftp->partial_size_len = 0;
return _libssh2_error(session, return _libssh2_error(session,
LIBSSH2_ERROR_CHANNEL_PACKET_EXCEEDED, LIBSSH2_ERROR_CHANNEL_PACKET_EXCEEDED,
"SFTP packet too large"); "SFTP packet too large");
}
if(sftp->partial_len == 0) if(sftp->partial_len == 0)
return _libssh2_error(session, return _libssh2_error(session,
LIBSSH2_ERROR_ALLOC, LIBSSH2_ERROR_ALLOC,
@@ -372,7 +377,8 @@ sftp_packet_read(LIBSSH2_SFTP *sftp)
if(sftp->partial_len > recv_window) { if(sftp->partial_len > recv_window) {
/* ask for twice the data amount we need at once */ /* ask for twice the data amount we need at once */
rc = _libssh2_channel_receive_window_adjust(channel, rc = _libssh2_channel_receive_window_adjust(channel,
sftp->partial_len*2, sftp->partial_len
* 2,
1, NULL); 1, NULL);
/* store the state so that we continue with the correct /* store the state so that we continue with the correct
operation at next invoke */ operation at next invoke */
@@ -530,7 +536,7 @@ sftp_packet_require(LIBSSH2_SFTP *sftp, unsigned char packet_type,
(int) packet_type); (int) packet_type);
if (*data_len < required_size) { if (*data_len < required_size) {
return LIBSSH2_ERROR_OUT_OF_BOUNDARY; return LIBSSH2_ERROR_BUFFER_TOO_SMALL;
} }
return LIBSSH2_ERROR_NONE; return LIBSSH2_ERROR_NONE;
@@ -548,7 +554,7 @@ sftp_packet_require(LIBSSH2_SFTP *sftp, unsigned char packet_type,
(int) packet_type); (int) packet_type);
if (*data_len < required_size) { if (*data_len < required_size) {
return LIBSSH2_ERROR_OUT_OF_BOUNDARY; return LIBSSH2_ERROR_BUFFER_TOO_SMALL;
} }
return LIBSSH2_ERROR_NONE; return LIBSSH2_ERROR_NONE;
@@ -590,7 +596,7 @@ sftp_packet_requirev(LIBSSH2_SFTP *sftp, int num_valid_responses,
sftp->requirev_start = 0; sftp->requirev_start = 0;
if (*data_len < required_size) { if (*data_len < required_size) {
return LIBSSH2_ERROR_OUT_OF_BOUNDARY; return LIBSSH2_ERROR_BUFFER_TOO_SMALL;
} }
return LIBSSH2_ERROR_NONE; return LIBSSH2_ERROR_NONE;
@@ -601,10 +607,12 @@ sftp_packet_requirev(LIBSSH2_SFTP *sftp, int num_valid_responses,
if((rc < 0) && (rc != LIBSSH2_ERROR_EAGAIN)) { if((rc < 0) && (rc != LIBSSH2_ERROR_EAGAIN)) {
sftp->requirev_start = 0; sftp->requirev_start = 0;
return rc; return rc;
} else if (rc <= 0) { }
else if(rc <= 0) {
/* prevent busy-looping */ /* prevent busy-looping */
long left = long left =
LIBSSH2_READ_TIMEOUT - (long)(time(NULL) - sftp->requirev_start); LIBSSH2_READ_TIMEOUT -
(long)(time(NULL) - sftp->requirev_start);
if(left <= 0) { if(left <= 0) {
sftp->requirev_start = 0; sftp->requirev_start = 0;
@@ -667,68 +675,57 @@ sftp_attr2bin(unsigned char *p, const LIBSSH2_SFTP_ATTRIBUTES * attrs)
/* sftp_bin2attr /* sftp_bin2attr
*/ */
static int static int
sftp_bin2attr(LIBSSH2_SFTP_ATTRIBUTES * attrs, const unsigned char *p, size_t data_len) sftp_bin2attr(LIBSSH2_SFTP_ATTRIBUTES *attrs, const unsigned char *p,
size_t data_len)
{ {
const unsigned char *s = p; struct string_buf buf;
uint32_t flags = 0;
buf.data = (unsigned char *)p;
buf.dataptr = buf.data;
buf.len = data_len;
if (data_len >= 4) { if(_libssh2_get_u32(&buf, &flags) != 0) {
memset(attrs, 0, sizeof(LIBSSH2_SFTP_ATTRIBUTES)); return LIBSSH2_ERROR_BUFFER_TOO_SMALL;
attrs->flags = _libssh2_ntohu32(s);
s += 4;
data_len -= 4;
}
else {
return LIBSSH2_ERROR_OUT_OF_BOUNDARY;
} }
attrs->flags = flags;
if(attrs->flags & LIBSSH2_SFTP_ATTR_SIZE) { if(attrs->flags & LIBSSH2_SFTP_ATTR_SIZE) {
if (data_len >= 8) { if(_libssh2_get_u64(&buf, &(attrs->filesize)) != 0) {
attrs->filesize = _libssh2_ntohu64(s); return LIBSSH2_ERROR_BUFFER_TOO_SMALL;
s += 8;
data_len -= 8;
}
else {
return LIBSSH2_ERROR_OUT_OF_BOUNDARY;
} }
} }
if(attrs->flags & LIBSSH2_SFTP_ATTR_UIDGID) { if(attrs->flags & LIBSSH2_SFTP_ATTR_UIDGID) {
if (data_len >= 8) { uint32_t uid = 0;
attrs->uid = _libssh2_ntohu32(s); uint32_t gid = 0;
s += 4; if(_libssh2_get_u32(&buf, &uid) != 0 ||
attrs->gid = _libssh2_ntohu32(s); _libssh2_get_u32(&buf, &gid) != 0) {
s += 4; return LIBSSH2_ERROR_BUFFER_TOO_SMALL;
data_len -= 8;
}
else {
return LIBSSH2_ERROR_OUT_OF_BOUNDARY;
} }
attrs->uid = uid;
attrs->gid = gid;
} }
if(attrs->flags & LIBSSH2_SFTP_ATTR_PERMISSIONS) { if(attrs->flags & LIBSSH2_SFTP_ATTR_PERMISSIONS) {
if (data_len >= 4) { uint32_t permissions;
attrs->permissions = _libssh2_ntohu32(s); if(_libssh2_get_u32(&buf, &permissions) != 0) {
s += 4; return LIBSSH2_ERROR_BUFFER_TOO_SMALL;
data_len -= 4;
}
else {
return LIBSSH2_ERROR_OUT_OF_BOUNDARY;
} }
attrs->permissions = permissions;
} }
if(attrs->flags & LIBSSH2_SFTP_ATTR_ACMODTIME) { if(attrs->flags & LIBSSH2_SFTP_ATTR_ACMODTIME) {
if (data_len >= 8) { uint32_t atime;
attrs->atime = _libssh2_ntohu32(s); uint32_t mtime;
s += 4; if(_libssh2_get_u32(&buf, &atime) != 0 ||
attrs->mtime = _libssh2_ntohu32(s); _libssh2_get_u32(&buf, &mtime) != 0) {
s += 4; return LIBSSH2_ERROR_BUFFER_TOO_SMALL;
}
else {
return LIBSSH2_ERROR_OUT_OF_BOUNDARY;
} }
attrs->atime = atime;
attrs->mtime = mtime;
} }
return (s - p); return (buf.dataptr - buf.data);
} }
/* ************ /* ************
@@ -767,10 +764,12 @@ LIBSSH2_CHANNEL_CLOSE_FUNC(libssh2_sftp_dtor)
*/ */
static LIBSSH2_SFTP *sftp_init(LIBSSH2_SESSION *session) static LIBSSH2_SFTP *sftp_init(LIBSSH2_SESSION *session)
{ {
unsigned char *data, *s; unsigned char *data;
size_t data_len; size_t data_len;
ssize_t rc; ssize_t rc;
LIBSSH2_SFTP *sftp_handle; LIBSSH2_SFTP *sftp_handle;
struct string_buf buf;
unsigned char *endp;
if(session->sftpInit_state == libssh2_NB_state_idle) { if(session->sftpInit_state == libssh2_NB_state_idle) {
_libssh2_debug(session, LIBSSH2_TRACE_SFTP, _libssh2_debug(session, LIBSSH2_TRACE_SFTP,
@@ -819,13 +818,15 @@ static LIBSSH2_SFTP *sftp_init(LIBSSH2_SESSION *session)
if(session->sftpInit_state == libssh2_NB_state_sent) { if(session->sftpInit_state == libssh2_NB_state_sent) {
int ret = _libssh2_channel_process_startup(session->sftpInit_channel, int ret = _libssh2_channel_process_startup(session->sftpInit_channel,
"subsystem", "subsystem",
sizeof("subsystem") - 1, "sftp", sizeof("subsystem") - 1,
"sftp",
strlen("sftp")); strlen("sftp"));
if(ret == LIBSSH2_ERROR_EAGAIN) { if(ret == LIBSSH2_ERROR_EAGAIN) {
_libssh2_error(session, LIBSSH2_ERROR_EAGAIN, _libssh2_error(session, LIBSSH2_ERROR_EAGAIN,
"Would block to request SFTP subsystem"); "Would block to request SFTP subsystem");
return NULL; return NULL;
} else if (ret) { }
else if(ret) {
_libssh2_error(session, LIBSSH2_ERROR_CHANNEL_FAILURE, _libssh2_error(session, LIBSSH2_ERROR_CHANNEL_FAILURE,
"Unable to request SFTP subsystem"); "Unable to request SFTP subsystem");
goto sftp_init_error; goto sftp_init_error;
@@ -860,7 +861,8 @@ static LIBSSH2_SFTP *sftp_init(LIBSSH2_SESSION *session)
session->sftpInit_sent = 0; /* nothing's sent yet */ session->sftpInit_sent = 0; /* nothing's sent yet */
_libssh2_debug(session, LIBSSH2_TRACE_SFTP, _libssh2_debug(session, LIBSSH2_TRACE_SFTP,
"Sending FXP_INIT packet advertising version %d support", "Sending FXP_INIT packet advertising "
"version %d support",
(int) LIBSSH2_SFTP_VERSION); (int) LIBSSH2_SFTP_VERSION);
session->sftpInit_state = libssh2_NB_state_sent2; session->sftpInit_state = libssh2_NB_state_sent2;
@@ -901,7 +903,7 @@ static LIBSSH2_SFTP *sftp_init(LIBSSH2_SESSION *session)
"Would block receiving SSH_FXP_VERSION"); "Would block receiving SSH_FXP_VERSION");
return NULL; return NULL;
} }
else if (rc == LIBSSH2_ERROR_OUT_OF_BOUNDARY) { else if(rc == LIBSSH2_ERROR_BUFFER_TOO_SMALL) {
if(data_len > 0) { if(data_len > 0) {
LIBSSH2_FREE(session, data); LIBSSH2_FREE(session, data);
} }
@@ -915,9 +917,17 @@ static LIBSSH2_SFTP *sftp_init(LIBSSH2_SESSION *session)
goto sftp_init_error; goto sftp_init_error;
} }
s = data + 1; buf.data = data;
sftp_handle->version = _libssh2_ntohu32(s); buf.dataptr = buf.data + 1;
s += 4; buf.len = data_len;
endp = &buf.data[data_len];
if(_libssh2_get_u32(&buf, &(sftp_handle->version)) != 0) {
LIBSSH2_FREE(session, data);
rc = LIBSSH2_ERROR_BUFFER_TOO_SMALL;
goto sftp_init_error;
}
if(sftp_handle->version > LIBSSH2_SFTP_VERSION) { if(sftp_handle->version > LIBSSH2_SFTP_VERSION) {
_libssh2_debug(session, LIBSSH2_TRACE_SFTP, _libssh2_debug(session, LIBSSH2_TRACE_SFTP,
"Truncating remote SFTP version from %lu", "Truncating remote SFTP version from %lu",
@@ -927,20 +937,22 @@ static LIBSSH2_SFTP *sftp_init(LIBSSH2_SESSION *session)
_libssh2_debug(session, LIBSSH2_TRACE_SFTP, _libssh2_debug(session, LIBSSH2_TRACE_SFTP,
"Enabling SFTP version %lu compatibility", "Enabling SFTP version %lu compatibility",
sftp_handle->version); sftp_handle->version);
while (s < (data + data_len)) { while(buf.dataptr < endp) {
size_t extname_len, extdata_len; unsigned char *extname, *extdata;
extname_len = _libssh2_ntohu32(s); if(_libssh2_get_string(&buf, &extname, NULL)) {
s += 4; LIBSSH2_FREE(session, data);
/* the extension name starts here */ _libssh2_error(session, LIBSSH2_ERROR_BUFFER_TOO_SMALL,
s += extname_len; "Data too short when extracting extname");
goto sftp_init_error;
extdata_len = _libssh2_ntohu32(s); }
s += 4;
/* TODO: Actually process extensions */
s += extdata_len;
if(_libssh2_get_string(&buf, &extdata, NULL)) {
LIBSSH2_FREE(session, data);
_libssh2_error(session, LIBSSH2_ERROR_BUFFER_TOO_SMALL,
"Data too short when extracting extdata");
goto sftp_init_error;
}
} }
LIBSSH2_FREE(session, data); LIBSSH2_FREE(session, data);
@@ -1107,7 +1119,8 @@ sftp_open(LIBSSH2_SFTP *sftp, const char *filename,
/* packet_len(4) + packet_type(1) + request_id(4) + filename_len(4) + /* packet_len(4) + packet_type(1) + request_id(4) + filename_len(4) +
flags(4) */ flags(4) */
sftp->open_packet_len = filename_len + 13 + sftp->open_packet_len = filename_len + 13 +
(open_file? (4 + sftp_attrsize(LIBSSH2_SFTP_ATTR_PERMISSIONS)) : 0); (open_file? (4 +
sftp_attrsize(LIBSSH2_SFTP_ATTR_PERMISSIONS)) : 0);
/* surprise! this starts out with nothing sent */ /* surprise! this starts out with nothing sent */
sftp->open_packet_sent = 0; sftp->open_packet_sent = 0;
@@ -1147,7 +1160,8 @@ sftp_open(LIBSSH2_SFTP *sftp, const char *filename,
sftp->open_packet_sent); sftp->open_packet_sent);
if(rc == LIBSSH2_ERROR_EAGAIN) { if(rc == LIBSSH2_ERROR_EAGAIN) {
_libssh2_error(session, LIBSSH2_ERROR_EAGAIN, _libssh2_error(session, LIBSSH2_ERROR_EAGAIN,
"Would block sending FXP_OPEN or FXP_OPENDIR command"); "Would block sending FXP_OPEN or "
"FXP_OPENDIR command");
return NULL; return NULL;
} }
else if(rc < 0) { else if(rc < 0) {
@@ -1183,7 +1197,7 @@ sftp_open(LIBSSH2_SFTP *sftp, const char *filename,
"Would block waiting for status message"); "Would block waiting for status message");
return NULL; return NULL;
} }
else if (rc == LIBSSH2_ERROR_OUT_OF_BOUNDARY) { else if(rc == LIBSSH2_ERROR_BUFFER_TOO_SMALL) {
if(data_len > 0) { if(data_len > 0) {
LIBSSH2_FREE(session, data); LIBSSH2_FREE(session, data);
} }
@@ -1214,7 +1228,8 @@ sftp_open(LIBSSH2_SFTP *sftp, const char *filename,
sftp->last_errno = _libssh2_ntohu32(data + 5); sftp->last_errno = _libssh2_ntohu32(data + 5);
if(LIBSSH2_FX_OK == sftp->last_errno) { if(LIBSSH2_FX_OK == sftp->last_errno) {
_libssh2_debug(session, LIBSSH2_TRACE_SFTP, "got HANDLE FXOK!"); _libssh2_debug(session, LIBSSH2_TRACE_SFTP,
"got HANDLE FXOK!");
LIBSSH2_FREE(session, data); LIBSSH2_FREE(session, data);
@@ -1227,7 +1242,7 @@ sftp_open(LIBSSH2_SFTP *sftp, const char *filename,
sftp->open_state = libssh2_NB_state_sent; sftp->open_state = libssh2_NB_state_sent;
return NULL; return NULL;
} }
else if (rc == LIBSSH2_ERROR_OUT_OF_BOUNDARY) { else if(rc == LIBSSH2_ERROR_BUFFER_TOO_SMALL) {
if(data_len > 0) { if(data_len > 0) {
LIBSSH2_FREE(session, data); LIBSSH2_FREE(session, data);
} }
@@ -1243,7 +1258,8 @@ sftp_open(LIBSSH2_SFTP *sftp, const char *filename,
if(badness) { if(badness) {
_libssh2_error(session, LIBSSH2_ERROR_SFTP_PROTOCOL, _libssh2_error(session, LIBSSH2_ERROR_SFTP_PROTOCOL,
"Failed opening remote file"); "Failed opening remote file");
_libssh2_debug(session, LIBSSH2_TRACE_SFTP, "got FXP_STATUS %d", _libssh2_debug(session, LIBSSH2_TRACE_SFTP,
"got FXP_STATUS %d",
sftp->last_errno); sftp->last_errno);
LIBSSH2_FREE(session, data); LIBSSH2_FREE(session, data);
return NULL; return NULL;
@@ -1390,7 +1406,8 @@ static ssize_t sftp_read(LIBSSH2_SFTP_HANDLE * handle, char *buffer,
if(filep->eof) { if(filep->eof) {
return 0; return 0;
} else { }
else {
/* We allow a number of bytes being requested at any given time /* We allow a number of bytes being requested at any given time
without having been acked - until we reach EOF. */ without having been acked - until we reach EOF. */
@@ -1491,7 +1508,7 @@ static ssize_t sftp_read(LIBSSH2_SFTP_HANDLE * handle, char *buffer,
"read request id %d sent (offset: %d, size: %d)", "read request id %d sent (offset: %d, size: %d)",
request_id, (int)chunk->offset, (int)chunk->len); request_id, (int)chunk->offset, (int)chunk->len);
} }
/* FALL-THROUGH */
case libssh2_NB_state_sent: case libssh2_NB_state_sent:
sftp->read_state = libssh2_NB_state_idle; sftp->read_state = libssh2_NB_state_idle;
@@ -1521,7 +1538,8 @@ static ssize_t sftp_read(LIBSSH2_SFTP_HANDLE * handle, char *buffer,
* we can get out of this loop and start reading. */ * we can get out of this loop and start reading. */
if(chunk != _libssh2_list_first(&handle->packet_list)) { if(chunk != _libssh2_list_first(&handle->packet_list)) {
break; break;
} else { }
else {
continue; continue;
} }
} }
@@ -1530,6 +1548,7 @@ static ssize_t sftp_read(LIBSSH2_SFTP_HANDLE * handle, char *buffer,
/* move on to the next chunk with data to send */ /* move on to the next chunk with data to send */
chunk = _libssh2_list_next(&chunk->node); chunk = _libssh2_list_next(&chunk->node);
} }
/* FALL-THROUGH */
case libssh2_NB_state_sent2: case libssh2_NB_state_sent2:
@@ -1553,7 +1572,8 @@ static ssize_t sftp_read(LIBSSH2_SFTP_HANDLE * handle, char *buffer,
for an ACK for it just yet */ for an ACK for it just yet */
if(bytes_in_buffer > 0) { if(bytes_in_buffer > 0) {
return bytes_in_buffer; return bytes_in_buffer;
} else { }
else {
/* we should never reach this point */ /* we should never reach this point */
return _libssh2_error(session, LIBSSH2_ERROR_SFTP_PROTOCOL, return _libssh2_error(session, LIBSSH2_ERROR_SFTP_PROTOCOL,
"sftp_read() internal error"); "sftp_read() internal error");
@@ -1568,7 +1588,7 @@ static ssize_t sftp_read(LIBSSH2_SFTP_HANDLE * handle, char *buffer,
return bytes_in_buffer; return bytes_in_buffer;
} }
if (rc == LIBSSH2_ERROR_OUT_OF_BOUNDARY) { if(rc == LIBSSH2_ERROR_BUFFER_TOO_SMALL) {
if(data_len > 0) { if(data_len > 0) {
LIBSSH2_FREE(session, data); LIBSSH2_FREE(session, data);
} }
@@ -1678,7 +1698,8 @@ static ssize_t sftp_read(LIBSSH2_SFTP_HANDLE * handle, char *buffer,
*/ */
if(bytes_in_buffer < buffer_size) { if(bytes_in_buffer < buffer_size) {
chunk = next; chunk = next;
} else { }
else {
chunk = NULL; chunk = NULL;
} }
@@ -1750,11 +1771,19 @@ static ssize_t sftp_readdir(LIBSSH2_SFTP_HANDLE *handle, char *buffer,
size_t real_filename_len; size_t real_filename_len;
size_t filename_len; size_t filename_len;
size_t longentry_len; size_t longentry_len;
size_t names_packet_len = handle->u.dir.names_packet_len;
int attr_len = 0;
if(names_packet_len >= 4) {
s = (unsigned char *) handle->u.dir.next_name; s = (unsigned char *) handle->u.dir.next_name;
real_filename_len = _libssh2_ntohu32(s); real_filename_len = _libssh2_ntohu32(s);
s += 4; s += 4;
names_packet_len -= 4;
}
else {
filename_len = (size_t)LIBSSH2_ERROR_BUFFER_TOO_SMALL;
goto end;
}
filename_len = real_filename_len; filename_len = real_filename_len;
if(filename_len >= buffer_maxlen) { if(filename_len >= buffer_maxlen) {
@@ -1762,17 +1791,33 @@ static ssize_t sftp_readdir(LIBSSH2_SFTP_HANDLE *handle, char *buffer,
goto end; goto end;
} }
if(buffer_maxlen >= filename_len && names_packet_len >=
filename_len) {
memcpy(buffer, s, filename_len); memcpy(buffer, s, filename_len);
buffer[filename_len] = '\0'; /* zero terminate */ buffer[filename_len] = '\0'; /* zero terminate */
s += real_filename_len; s += real_filename_len;
names_packet_len -= real_filename_len;
}
else {
filename_len = (size_t)LIBSSH2_ERROR_BUFFER_TOO_SMALL;
goto end;
}
if(names_packet_len >= 4) {
real_longentry_len = _libssh2_ntohu32(s); real_longentry_len = _libssh2_ntohu32(s);
s += 4; s += 4;
names_packet_len -= 4;
}
else {
filename_len = (size_t)LIBSSH2_ERROR_BUFFER_TOO_SMALL;
goto end;
}
if(longentry && (longentry_maxlen>1)) { if(longentry && (longentry_maxlen>1)) {
longentry_len = real_longentry_len; longentry_len = real_longentry_len;
if (longentry_len >= longentry_maxlen) { if(longentry_len >= longentry_maxlen ||
longentry_len > names_packet_len) {
filename_len = (size_t)LIBSSH2_ERROR_BUFFER_TOO_SMALL; filename_len = (size_t)LIBSSH2_ERROR_BUFFER_TOO_SMALL;
goto end; goto end;
} }
@@ -1780,14 +1825,33 @@ static ssize_t sftp_readdir(LIBSSH2_SFTP_HANDLE *handle, char *buffer,
memcpy(longentry, s, longentry_len); memcpy(longentry, s, longentry_len);
longentry[longentry_len] = '\0'; /* zero terminate */ longentry[longentry_len] = '\0'; /* zero terminate */
} }
if(real_longentry_len <= names_packet_len) {
s += real_longentry_len; s += real_longentry_len;
names_packet_len -= real_longentry_len;
}
else {
filename_len = (size_t)LIBSSH2_ERROR_BUFFER_TOO_SMALL;
goto end;
}
if(attrs) if(attrs)
memset(attrs, 0, sizeof(LIBSSH2_SFTP_ATTRIBUTES)); memset(attrs, 0, sizeof(LIBSSH2_SFTP_ATTRIBUTES));
s += sftp_bin2attr(attrs ? attrs : &attrs_dummy, s, 32); attr_len = sftp_bin2attr(attrs ? attrs : &attrs_dummy, s,
names_packet_len);
if(attr_len >= 0) {
s += attr_len;
names_packet_len -= attr_len;
}
else {
filename_len = (size_t)LIBSSH2_ERROR_BUFFER_TOO_SMALL;
goto end;
}
handle->u.dir.next_name = (char *) s; handle->u.dir.next_name = (char *) s;
handle->u.dir.names_packet_len = names_packet_len;
end: end:
if((--handle->u.dir.names_left) == 0) if((--handle->u.dir.names_left) == 0)
@@ -1843,7 +1907,7 @@ static ssize_t sftp_readdir(LIBSSH2_SFTP_HANDLE *handle, char *buffer,
&data_len, 9); &data_len, 9);
if(retcode == LIBSSH2_ERROR_EAGAIN) if(retcode == LIBSSH2_ERROR_EAGAIN)
return retcode; return retcode;
else if (retcode == LIBSSH2_ERROR_OUT_OF_BOUNDARY) { else if(retcode == LIBSSH2_ERROR_BUFFER_TOO_SMALL) {
if(data_len > 0) { if(data_len > 0) {
LIBSSH2_FREE(session, data); LIBSSH2_FREE(session, data);
} }
@@ -1884,6 +1948,7 @@ static ssize_t sftp_readdir(LIBSSH2_SFTP_HANDLE *handle, char *buffer,
handle->u.dir.names_left = num_names; handle->u.dir.names_left = num_names;
handle->u.dir.names_packet = data; handle->u.dir.names_packet = data;
handle->u.dir.next_name = (char *) data + 9; handle->u.dir.next_name = (char *) data + 9;
handle->u.dir.names_packet_len = data_len - 9;
/* use the name popping mechanism from the start of the function */ /* use the name popping mechanism from the start of the function */
return sftp_readdir(handle, buffer, buffer_maxlen, longentry, return sftp_readdir(handle, buffer, buffer_maxlen, longentry,
@@ -1967,14 +2032,15 @@ static ssize_t sftp_write(LIBSSH2_SFTP_HANDLE *handle, const char *buffer,
default: default:
case libssh2_NB_state_idle: case libssh2_NB_state_idle:
/* Number of bytes sent off that haven't been acked and therefor we /* Number of bytes sent off that haven't been acked and therefore we
will get passed in here again. will get passed in here again.
Also, add up the number of bytes that actually already have been Also, add up the number of bytes that actually already have been
acked but we haven't been able to return as such yet, so we will acked but we haven't been able to return as such yet, so we will
get that data as well passed in here again. get that data as well passed in here again.
*/ */
already = (size_t) (handle->u.file.offset_sent - handle->u.file.offset)+ already = (size_t) (handle->u.file.offset_sent -
handle->u.file.offset)+
handle->u.file.acked; handle->u.file.acked;
if(count >= already) { if(count >= already) {
@@ -2027,8 +2093,8 @@ static ssize_t sftp_write(LIBSSH2_SFTP_HANDLE *handle, const char *buffer,
to create more packets */ to create more packets */
} }
/* move through the WRITE packets that haven't been sent and send as many /* move through the WRITE packets that haven't been sent and send as
as possible - remember that we don't block */ many as possible - remember that we don't block */
chunk = _libssh2_list_first(&handle->packet_list); chunk = _libssh2_list_first(&handle->packet_list);
while(chunk) { while(chunk) {
@@ -2076,7 +2142,7 @@ static ssize_t sftp_write(LIBSSH2_SFTP_HANDLE *handle, const char *buffer,
/* we check the packets in order */ /* we check the packets in order */
rc = sftp_packet_require(sftp, SSH_FXP_STATUS, rc = sftp_packet_require(sftp, SSH_FXP_STATUS,
chunk->request_id, &data, &data_len, 9); chunk->request_id, &data, &data_len, 9);
if (rc == LIBSSH2_ERROR_OUT_OF_BOUNDARY) { if(rc == LIBSSH2_ERROR_BUFFER_TOO_SMALL) {
if(data_len > 0) { if(data_len > 0) {
LIBSSH2_FREE(session, data); LIBSSH2_FREE(session, data);
} }
@@ -2113,7 +2179,8 @@ static ssize_t sftp_write(LIBSSH2_SFTP_HANDLE *handle, const char *buffer,
/* since we return error now, the application will not get any /* since we return error now, the application will not get any
outstanding data acked, so we need to rewind the offset to outstanding data acked, so we need to rewind the offset to
where the application knows it has reached with acked data */ where the application knows it has reached with acked
data */
handle->u.file.offset -= handle->u.file.acked; handle->u.file.offset -= handle->u.file.acked;
/* then reset the offset_sent to be the same as the offset */ /* then reset the offset_sent to be the same as the offset */
@@ -2123,8 +2190,8 @@ static ssize_t sftp_write(LIBSSH2_SFTP_HANDLE *handle, const char *buffer,
ack after an error */ ack after an error */
handle->u.file.acked = 0; handle->u.file.acked = 0;
/* the server returned an error for that written chunk, propagate /* the server returned an error for that written chunk,
this back to our parent function */ propagate this back to our parent function */
return _libssh2_error(session, LIBSSH2_ERROR_SFTP_PROTOCOL, return _libssh2_error(session, LIBSSH2_ERROR_SFTP_PROTOCOL,
"FXP write failed"); "FXP write failed");
} }
@@ -2201,7 +2268,8 @@ static int sftp_fsync(LIBSSH2_SFTP_HANDLE *handle)
_libssh2_store_str(&s, handle->handle, handle->handle_len); _libssh2_store_str(&s, handle->handle, handle->handle_len);
sftp->fsync_state = libssh2_NB_state_created; sftp->fsync_state = libssh2_NB_state_created;
} else { }
else {
packet = sftp->fsync_packet; packet = sftp->fsync_packet;
} }
@@ -2229,7 +2297,7 @@ static int sftp_fsync(LIBSSH2_SFTP_HANDLE *handle)
if(rc == LIBSSH2_ERROR_EAGAIN) { if(rc == LIBSSH2_ERROR_EAGAIN) {
return rc; return rc;
} }
else if (rc == LIBSSH2_ERROR_OUT_OF_BOUNDARY) { else if(rc == LIBSSH2_ERROR_BUFFER_TOO_SMALL) {
if(data_len > 0) { if(data_len > 0) {
LIBSSH2_FREE(session, data); LIBSSH2_FREE(session, data);
} }
@@ -2339,7 +2407,7 @@ static int sftp_fstat(LIBSSH2_SFTP_HANDLE *handle,
&data_len, 9); &data_len, 9);
if(rc == LIBSSH2_ERROR_EAGAIN) if(rc == LIBSSH2_ERROR_EAGAIN)
return rc; return rc;
else if (rc == LIBSSH2_ERROR_OUT_OF_BOUNDARY) { else if(rc == LIBSSH2_ERROR_BUFFER_TOO_SMALL) {
if(data_len > 0) { if(data_len > 0) {
LIBSSH2_FREE(session, data); LIBSSH2_FREE(session, data);
} }
@@ -2361,7 +2429,8 @@ static int sftp_fstat(LIBSSH2_SFTP_HANDLE *handle,
LIBSSH2_FREE(session, data); LIBSSH2_FREE(session, data);
if(retcode == LIBSSH2_FX_OK) { if(retcode == LIBSSH2_FX_OK) {
return 0; return 0;
} else { }
else {
sftp->last_errno = retcode; sftp->last_errno = retcode;
return _libssh2_error(session, LIBSSH2_ERROR_SFTP_PROTOCOL, return _libssh2_error(session, LIBSSH2_ERROR_SFTP_PROTOCOL,
"SFTP Protocol Error"); "SFTP Protocol Error");
@@ -2520,7 +2589,8 @@ sftp_close_handle(LIBSSH2_SFTP_HANDLE *handle)
rc = _libssh2_error(session, LIBSSH2_ERROR_ALLOC, rc = _libssh2_error(session, LIBSSH2_ERROR_ALLOC,
"Unable to allocate memory for FXP_CLOSE " "Unable to allocate memory for FXP_CLOSE "
"packet"); "packet");
} else { }
else {
_libssh2_store_u32(&s, packet_len - 4); _libssh2_store_u32(&s, packet_len - 4);
*(s++) = SSH_FXP_CLOSE; *(s++) = SSH_FXP_CLOSE;
@@ -2536,11 +2606,13 @@ sftp_close_handle(LIBSSH2_SFTP_HANDLE *handle)
packet_len); packet_len);
if(rc == LIBSSH2_ERROR_EAGAIN) { if(rc == LIBSSH2_ERROR_EAGAIN) {
return rc; return rc;
} else if ((ssize_t)packet_len != rc) { }
else if((ssize_t)packet_len != rc) {
handle->close_state = libssh2_NB_state_idle; handle->close_state = libssh2_NB_state_idle;
rc = _libssh2_error(session, LIBSSH2_ERROR_SOCKET_SEND, rc = _libssh2_error(session, LIBSSH2_ERROR_SOCKET_SEND,
"Unable to send FXP_CLOSE command"); "Unable to send FXP_CLOSE command");
} else }
else
handle->close_state = libssh2_NB_state_sent; handle->close_state = libssh2_NB_state_sent;
LIBSSH2_FREE(session, handle->close_packet); LIBSSH2_FREE(session, handle->close_packet);
@@ -2554,7 +2626,7 @@ sftp_close_handle(LIBSSH2_SFTP_HANDLE *handle)
if(rc == LIBSSH2_ERROR_EAGAIN) { if(rc == LIBSSH2_ERROR_EAGAIN) {
return rc; return rc;
} }
else if (rc == LIBSSH2_ERROR_OUT_OF_BOUNDARY) { else if(rc == LIBSSH2_ERROR_BUFFER_TOO_SMALL) {
if(data_len > 0) { if(data_len > 0) {
LIBSSH2_FREE(session, data); LIBSSH2_FREE(session, data);
} }
@@ -2575,7 +2647,8 @@ sftp_close_handle(LIBSSH2_SFTP_HANDLE *handle)
happened for which we should have set an error code */ happened for which we should have set an error code */
assert(rc); assert(rc);
} else { }
else {
int retcode = _libssh2_ntohu32(data + 5); int retcode = _libssh2_ntohu32(data + 5);
LIBSSH2_FREE(session, data); LIBSSH2_FREE(session, data);
@@ -2590,11 +2663,11 @@ sftp_close_handle(LIBSSH2_SFTP_HANDLE *handle)
/* remove this handle from the parent's list */ /* remove this handle from the parent's list */
_libssh2_list_remove(&handle->node); _libssh2_list_remove(&handle->node);
if ((handle->handle_type == LIBSSH2_SFTP_HANDLE_DIR) if(handle->handle_type == LIBSSH2_SFTP_HANDLE_DIR) {
&& handle->u.dir.names_left) { if(handle->u.dir.names_left)
LIBSSH2_FREE(session, handle->u.dir.names_packet); LIBSSH2_FREE(session, handle->u.dir.names_packet);
} }
else { else if(handle->handle_type == LIBSSH2_SFTP_HANDLE_FILE) {
if(handle->u.file.data) if(handle->u.file.data)
LIBSSH2_FREE(session, handle->u.file.data); LIBSSH2_FREE(session, handle->u.file.data);
} }
@@ -2661,7 +2734,8 @@ static int sftp_unlink(LIBSSH2_SFTP *sftp, const char *filename,
packet_len); packet_len);
if(rc == LIBSSH2_ERROR_EAGAIN) { if(rc == LIBSSH2_ERROR_EAGAIN) {
return rc; return rc;
} else if ((ssize_t)packet_len != rc) { }
else if((ssize_t)packet_len != rc) {
LIBSSH2_FREE(session, sftp->unlink_packet); LIBSSH2_FREE(session, sftp->unlink_packet);
sftp->unlink_packet = NULL; sftp->unlink_packet = NULL;
sftp->unlink_state = libssh2_NB_state_idle; sftp->unlink_state = libssh2_NB_state_idle;
@@ -2680,7 +2754,7 @@ static int sftp_unlink(LIBSSH2_SFTP *sftp, const char *filename,
if(rc == LIBSSH2_ERROR_EAGAIN) { if(rc == LIBSSH2_ERROR_EAGAIN) {
return rc; return rc;
} }
else if (rc == LIBSSH2_ERROR_OUT_OF_BOUNDARY) { else if(rc == LIBSSH2_ERROR_BUFFER_TOO_SMALL) {
if(data_len > 0) { if(data_len > 0) {
LIBSSH2_FREE(session, data); LIBSSH2_FREE(session, data);
} }
@@ -2700,7 +2774,8 @@ static int sftp_unlink(LIBSSH2_SFTP *sftp, const char *filename,
if(retcode == LIBSSH2_FX_OK) { if(retcode == LIBSSH2_FX_OK) {
return 0; return 0;
} else { }
else {
sftp->last_errno = retcode; sftp->last_errno = retcode;
return _libssh2_error(session, LIBSSH2_ERROR_SFTP_PROTOCOL, return _libssh2_error(session, LIBSSH2_ERROR_SFTP_PROTOCOL,
"SFTP Protocol Error"); "SFTP Protocol Error");
@@ -2779,7 +2854,8 @@ static int sftp_rename(LIBSSH2_SFTP *sftp, const char *source_filename,
sftp->rename_s - sftp->rename_packet); sftp->rename_s - sftp->rename_packet);
if(rc == LIBSSH2_ERROR_EAGAIN) { if(rc == LIBSSH2_ERROR_EAGAIN) {
return rc; return rc;
} else if ((ssize_t)packet_len != rc) { }
else if((ssize_t)packet_len != rc) {
LIBSSH2_FREE(session, sftp->rename_packet); LIBSSH2_FREE(session, sftp->rename_packet);
sftp->rename_packet = NULL; sftp->rename_packet = NULL;
sftp->rename_state = libssh2_NB_state_idle; sftp->rename_state = libssh2_NB_state_idle;
@@ -2798,7 +2874,7 @@ static int sftp_rename(LIBSSH2_SFTP *sftp, const char *source_filename,
if(rc == LIBSSH2_ERROR_EAGAIN) { if(rc == LIBSSH2_ERROR_EAGAIN) {
return rc; return rc;
} }
else if (rc == LIBSSH2_ERROR_OUT_OF_BOUNDARY) { else if(rc == LIBSSH2_ERROR_BUFFER_TOO_SMALL) {
if(data_len > 0) { if(data_len > 0) {
LIBSSH2_FREE(session, data); LIBSSH2_FREE(session, data);
} }
@@ -2932,7 +3008,7 @@ static int sftp_fstatvfs(LIBSSH2_SFTP_HANDLE *handle, LIBSSH2_SFTP_STATVFS *st)
if(rc == LIBSSH2_ERROR_EAGAIN) { if(rc == LIBSSH2_ERROR_EAGAIN) {
return rc; return rc;
} }
else if (rc == LIBSSH2_ERROR_OUT_OF_BOUNDARY) { else if(rc == LIBSSH2_ERROR_BUFFER_TOO_SMALL) {
if(data_len > 0) { if(data_len > 0) {
LIBSSH2_FREE(session, data); LIBSSH2_FREE(session, data);
} }
@@ -2994,7 +3070,8 @@ libssh2_sftp_fstatvfs(LIBSSH2_SFTP_HANDLE *handle, LIBSSH2_SFTP_STATVFS *st)
int rc; int rc;
if(!handle || !st) if(!handle || !st)
return LIBSSH2_ERROR_BAD_USE; return LIBSSH2_ERROR_BAD_USE;
BLOCK_ADJUST(rc, handle->sftp->channel->session, sftp_fstatvfs(handle, st)); BLOCK_ADJUST(rc, handle->sftp->channel->session,
sftp_fstatvfs(handle, st));
return rc; return rc;
} }
@@ -3066,7 +3143,7 @@ static int sftp_statvfs(LIBSSH2_SFTP *sftp, const char *path,
if(rc == LIBSSH2_ERROR_EAGAIN) { if(rc == LIBSSH2_ERROR_EAGAIN) {
return rc; return rc;
} }
else if (rc == LIBSSH2_ERROR_OUT_OF_BOUNDARY) { else if(rc == LIBSSH2_ERROR_BUFFER_TOO_SMALL) {
if(data_len > 0) { if(data_len > 0) {
LIBSSH2_FREE(session, data); LIBSSH2_FREE(session, data);
} }
@@ -3146,16 +3223,23 @@ static int sftp_mkdir(LIBSSH2_SFTP *sftp, const char *path,
LIBSSH2_CHANNEL *channel = sftp->channel; LIBSSH2_CHANNEL *channel = sftp->channel;
LIBSSH2_SESSION *session = channel->session; LIBSSH2_SESSION *session = channel->session;
LIBSSH2_SFTP_ATTRIBUTES attrs = { LIBSSH2_SFTP_ATTRIBUTES attrs = {
LIBSSH2_SFTP_ATTR_PERMISSIONS, 0, 0, 0, 0, 0, 0 0, 0, 0, 0, 0, 0, 0
}; };
size_t data_len; size_t data_len;
int retcode; int retcode;
/* 13 = packet_len(4) + packet_type(1) + request_id(4) + path_len(4) */ ssize_t packet_len;
ssize_t packet_len = path_len + 13 +
sftp_attrsize(LIBSSH2_SFTP_ATTR_PERMISSIONS);
unsigned char *packet, *s, *data; unsigned char *packet, *s, *data;
int rc; int rc;
if(mode != LIBSSH2_SFTP_DEFAULT_MODE) {
/* Filetype in SFTP 3 and earlier */
attrs.flags = LIBSSH2_SFTP_ATTR_PERMISSIONS;
attrs.permissions = mode | LIBSSH2_SFTP_ATTR_PFILETYPE_DIR;
}
/* 13 = packet_len(4) + packet_type(1) + request_id(4) + path_len(4) */
packet_len = path_len + 13 + sftp_attrsize(attrs.flags);
if(sftp->mkdir_state == libssh2_NB_state_idle) { if(sftp->mkdir_state == libssh2_NB_state_idle) {
_libssh2_debug(session, LIBSSH2_TRACE_SFTP, _libssh2_debug(session, LIBSSH2_TRACE_SFTP,
"Creating directory %s with mode 0%lo", path, mode); "Creating directory %s with mode 0%lo", path, mode);
@@ -3165,8 +3249,6 @@ static int sftp_mkdir(LIBSSH2_SFTP *sftp, const char *path,
"Unable to allocate memory for FXP_MKDIR " "Unable to allocate memory for FXP_MKDIR "
"packet"); "packet");
} }
/* Filetype in SFTP 3 and earlier */
attrs.permissions = mode | LIBSSH2_SFTP_ATTR_PFILETYPE_DIR;
_libssh2_store_u32(&s, packet_len - 4); _libssh2_store_u32(&s, packet_len - 4);
*(s++) = SSH_FXP_MKDIR; *(s++) = SSH_FXP_MKDIR;
@@ -3204,7 +3286,7 @@ static int sftp_mkdir(LIBSSH2_SFTP *sftp, const char *path,
if(rc == LIBSSH2_ERROR_EAGAIN) { if(rc == LIBSSH2_ERROR_EAGAIN) {
return rc; return rc;
} }
else if (rc == LIBSSH2_ERROR_OUT_OF_BOUNDARY) { else if(rc == LIBSSH2_ERROR_BUFFER_TOO_SMALL) {
if(data_len > 0) { if(data_len > 0) {
LIBSSH2_FREE(session, data); LIBSSH2_FREE(session, data);
} }
@@ -3225,7 +3307,8 @@ static int sftp_mkdir(LIBSSH2_SFTP *sftp, const char *path,
if(retcode == LIBSSH2_FX_OK) { if(retcode == LIBSSH2_FX_OK) {
_libssh2_debug(session, LIBSSH2_TRACE_SFTP, "OK!"); _libssh2_debug(session, LIBSSH2_TRACE_SFTP, "OK!");
return 0; return 0;
} else { }
else {
sftp->last_errno = retcode; sftp->last_errno = retcode;
return _libssh2_error(session, LIBSSH2_ERROR_SFTP_PROTOCOL, return _libssh2_error(session, LIBSSH2_ERROR_SFTP_PROTOCOL,
"SFTP Protocol Error"); "SFTP Protocol Error");
@@ -3288,7 +3371,8 @@ static int sftp_rmdir(LIBSSH2_SFTP *sftp, const char *path,
packet_len); packet_len);
if(rc == LIBSSH2_ERROR_EAGAIN) { if(rc == LIBSSH2_ERROR_EAGAIN) {
return rc; return rc;
} else if (packet_len != rc) { }
else if(packet_len != rc) {
LIBSSH2_FREE(session, sftp->rmdir_packet); LIBSSH2_FREE(session, sftp->rmdir_packet);
sftp->rmdir_packet = NULL; sftp->rmdir_packet = NULL;
sftp->rmdir_state = libssh2_NB_state_idle; sftp->rmdir_state = libssh2_NB_state_idle;
@@ -3306,7 +3390,7 @@ static int sftp_rmdir(LIBSSH2_SFTP *sftp, const char *path,
if(rc == LIBSSH2_ERROR_EAGAIN) { if(rc == LIBSSH2_ERROR_EAGAIN) {
return rc; return rc;
} }
else if (rc == LIBSSH2_ERROR_OUT_OF_BOUNDARY) { else if(rc == LIBSSH2_ERROR_BUFFER_TOO_SMALL) {
if(data_len > 0) { if(data_len > 0) {
LIBSSH2_FREE(session, data); LIBSSH2_FREE(session, data);
} }
@@ -3326,7 +3410,8 @@ static int sftp_rmdir(LIBSSH2_SFTP *sftp, const char *path,
if(retcode == LIBSSH2_FX_OK) { if(retcode == LIBSSH2_FX_OK) {
return 0; return 0;
} else { }
else {
sftp->last_errno = retcode; sftp->last_errno = retcode;
return _libssh2_error(session, LIBSSH2_ERROR_SFTP_PROTOCOL, return _libssh2_error(session, LIBSSH2_ERROR_SFTP_PROTOCOL,
"SFTP Protocol Error"); "SFTP Protocol Error");
@@ -3409,7 +3494,8 @@ static int sftp_stat(LIBSSH2_SFTP *sftp, const char *path,
rc = _libssh2_channel_write(channel, 0, sftp->stat_packet, packet_len); rc = _libssh2_channel_write(channel, 0, sftp->stat_packet, packet_len);
if(rc == LIBSSH2_ERROR_EAGAIN) { if(rc == LIBSSH2_ERROR_EAGAIN) {
return rc; return rc;
} else if (packet_len != rc) { }
else if(packet_len != rc) {
LIBSSH2_FREE(session, sftp->stat_packet); LIBSSH2_FREE(session, sftp->stat_packet);
sftp->stat_packet = NULL; sftp->stat_packet = NULL;
sftp->stat_state = libssh2_NB_state_idle; sftp->stat_state = libssh2_NB_state_idle;
@@ -3426,7 +3512,7 @@ static int sftp_stat(LIBSSH2_SFTP *sftp, const char *path,
sftp->stat_request_id, &data, &data_len, 9); sftp->stat_request_id, &data, &data_len, 9);
if(rc == LIBSSH2_ERROR_EAGAIN) if(rc == LIBSSH2_ERROR_EAGAIN)
return rc; return rc;
else if (rc == LIBSSH2_ERROR_OUT_OF_BOUNDARY) { else if(rc == LIBSSH2_ERROR_BUFFER_TOO_SMALL) {
if(data_len > 0) { if(data_len > 0) {
LIBSSH2_FREE(session, data); LIBSSH2_FREE(session, data);
} }
@@ -3447,8 +3533,10 @@ static int sftp_stat(LIBSSH2_SFTP *sftp, const char *path,
retcode = _libssh2_ntohu32(data + 5); retcode = _libssh2_ntohu32(data + 5);
LIBSSH2_FREE(session, data); LIBSSH2_FREE(session, data);
if(retcode == LIBSSH2_FX_OK) { if(retcode == LIBSSH2_FX_OK) {
memset(attrs, 0, sizeof(LIBSSH2_SFTP_ATTRIBUTES));
return 0; return 0;
} else { }
else {
sftp->last_errno = retcode; sftp->last_errno = retcode;
return _libssh2_error(session, LIBSSH2_ERROR_SFTP_PROTOCOL, return _libssh2_error(session, LIBSSH2_ERROR_SFTP_PROTOCOL,
"SFTP Protocol Error"); "SFTP Protocol Error");
@@ -3569,7 +3657,7 @@ static int sftp_symlink(LIBSSH2_SFTP *sftp, const char *path,
&data_len, 9); &data_len, 9);
if(retcode == LIBSSH2_ERROR_EAGAIN) if(retcode == LIBSSH2_ERROR_EAGAIN)
return retcode; return retcode;
else if (retcode == LIBSSH2_ERROR_OUT_OF_BOUNDARY) { else if(retcode == LIBSSH2_ERROR_BUFFER_TOO_SMALL) {
if(data_len > 0) { if(data_len > 0) {
LIBSSH2_FREE(session, data); LIBSSH2_FREE(session, data);
} }
@@ -3585,8 +3673,6 @@ static int sftp_symlink(LIBSSH2_SFTP *sftp, const char *path,
sftp->symlink_state = libssh2_NB_state_idle; sftp->symlink_state = libssh2_NB_state_idle;
if(data[0] == SSH_FXP_STATUS) { if(data[0] == SSH_FXP_STATUS) {
int retcode;
retcode = _libssh2_ntohu32(data + 5); retcode = _libssh2_ntohu32(data + 5);
LIBSSH2_FREE(session, data); LIBSSH2_FREE(session, data);
if(retcode == LIBSSH2_FX_OK) if(retcode == LIBSSH2_FX_OK)

View File

@@ -122,6 +122,7 @@ struct _LIBSSH2_SFTP_HANDLE
uint32_t names_left; uint32_t names_left;
void *names_packet; void *names_packet;
char *next_name; char *next_name;
size_t names_packet_len;
} dir; } dir;
} u; } u;

View File

@@ -281,7 +281,6 @@ int _libssh2_transport_read(LIBSSH2_SESSION * session)
unsigned char block[MAX_BLOCKSIZE]; unsigned char block[MAX_BLOCKSIZE];
int blocksize; int blocksize;
int encrypted = 1; int encrypted = 1;
size_t total_num;
/* default clear the bit */ /* default clear the bit */
session->socket_block_directions &= ~LIBSSH2_SESSION_BLOCK_INBOUND; session->socket_block_directions &= ~LIBSSH2_SESSION_BLOCK_INBOUND;
@@ -329,7 +328,8 @@ int _libssh2_transport_read(LIBSSH2_SESSION * session)
if(session->state & LIBSSH2_STATE_NEWKEYS) { if(session->state & LIBSSH2_STATE_NEWKEYS) {
blocksize = session->remote.crypt->blocksize; blocksize = session->remote.crypt->blocksize;
} else { }
else {
encrypted = 0; /* not encrypted */ encrypted = 0; /* not encrypted */
blocksize = 5; /* not strictly true, but we can use 5 here to blocksize = 5; /* not strictly true, but we can use 5 here to
make the checks below work fine still */ make the checks below work fine still */
@@ -359,7 +359,8 @@ int _libssh2_transport_read(LIBSSH2_SESSION * session)
memmove(p->buf, &p->buf[p->readidx], remainbuf); memmove(p->buf, &p->buf[p->readidx], remainbuf);
p->readidx = 0; p->readidx = 0;
p->writeidx = remainbuf; p->writeidx = remainbuf;
} else { }
else {
/* nothing to move, just zero the indexes */ /* nothing to move, just zero the indexes */
p->readidx = p->writeidx = 0; p->readidx = p->writeidx = 0;
} }
@@ -399,6 +400,8 @@ int _libssh2_transport_read(LIBSSH2_SESSION * session)
numbytes = remainbuf; numbytes = remainbuf;
if(!p->total_num) { if(!p->total_num) {
size_t total_num;
/* No payload package area allocated yet. To know the /* No payload package area allocated yet. To know the
size of this payload, we need to decrypt the first size of this payload, we need to decrypt the first
blocksize data. */ blocksize data. */
@@ -420,8 +423,9 @@ int _libssh2_transport_read(LIBSSH2_SESSION * session)
} }
/* save the first 5 bytes of the decrypted package, to be /* save the first 5 bytes of the decrypted package, to be
used in the hash calculation later down. */ used in the hash calculation later down. */
memcpy(p->init, &p->buf[p->readidx], 5); memcpy(p->init, block, 5);
} else { }
else {
/* the data is plain, just copy it verbatim to /* the data is plain, just copy it verbatim to
the working block buffer */ the working block buffer */
memcpy(block, &p->buf[p->readidx], blocksize); memcpy(block, &p->buf[p->readidx], blocksize);
@@ -434,17 +438,15 @@ int _libssh2_transport_read(LIBSSH2_SESSION * session)
* and we can extract packet and padding length from it * and we can extract packet and padding length from it
*/ */
p->packet_length = _libssh2_ntohu32(block); p->packet_length = _libssh2_ntohu32(block);
if (p->packet_length < 1)
return LIBSSH2_ERROR_DECRYPT;
p->padding_length = block[4];
if(p->packet_length < 1) { if(p->packet_length < 1) {
return LIBSSH2_ERROR_DECRYPT; return LIBSSH2_ERROR_DECRYPT;
} }
else if(p->packet_length > LIBSSH2_PACKET_MAXPAYLOAD) { else if(p->packet_length > LIBSSH2_PACKET_MAXPAYLOAD) {
return LIBSSH2_ERROR_OUT_OF_BOUNDARY; return LIBSSH2_ERROR_OUT_OF_BOUNDARY;
} }
else if ( p->padding_length > p->packet_length - 1 ) {
p->padding_length = block[4];
if(p->padding_length > p->packet_length - 1) {
return LIBSSH2_ERROR_DECRYPT; return LIBSSH2_ERROR_DECRYPT;
} }
@@ -481,10 +483,11 @@ int _libssh2_transport_read(LIBSSH2_SESSION * session)
/* copy the data from index 5 to the end of /* copy the data from index 5 to the end of
the blocksize from the temporary buffer to the blocksize from the temporary buffer to
the start of the decrypted buffer */ the start of the decrypted buffer */
if (blocksize - 5 <= total_num) { if(blocksize - 5 <= (int) total_num) {
memcpy(p->wptr, &block[5], blocksize - 5); memcpy(p->wptr, &block[5], blocksize - 5);
p->wptr += blocksize - 5; /* advance write pointer */ p->wptr += blocksize - 5; /* advance write pointer */
} else { }
else {
return LIBSSH2_ERROR_OUT_OF_BOUNDARY; return LIBSSH2_ERROR_OUT_OF_BOUNDARY;
} }
} }
@@ -519,7 +522,8 @@ int _libssh2_transport_read(LIBSSH2_SESSION * session)
amount to decrypt even more */ amount to decrypt even more */
if((p->data_num + numbytes) > (p->total_num - skip)) { if((p->data_num + numbytes) > (p->total_num - skip)) {
numdecrypt = (p->total_num - skip) - p->data_num; numdecrypt = (p->total_num - skip) - p->data_num;
} else { }
else {
int frac; int frac;
numdecrypt = numbytes; numdecrypt = numbytes;
frac = numdecrypt % blocksize; frac = numdecrypt % blocksize;
@@ -532,7 +536,8 @@ int _libssh2_transport_read(LIBSSH2_SESSION * session)
numbytes = 0; numbytes = 0;
} }
} }
} else { }
else {
/* unencrypted data should not be decrypted at all */ /* unencrypted data should not be decrypted at all */
numdecrypt = 0; numdecrypt = 0;
} }
@@ -561,7 +566,7 @@ int _libssh2_transport_read(LIBSSH2_SESSION * session)
copy them as-is to the target buffer */ copy them as-is to the target buffer */
if(numbytes > 0) { if(numbytes > 0) {
if (numbytes <= total_num - (p->wptr - p->payload)) { if(numbytes <= (int)(p->total_num - (p->wptr - p->payload))) {
memcpy(p->wptr, &p->buf[p->readidx], numbytes); memcpy(p->wptr, &p->buf[p->readidx], numbytes);
} }
else { else {
@@ -586,15 +591,15 @@ int _libssh2_transport_read(LIBSSH2_SESSION * session)
rc = fullpacket(session, encrypted); rc = fullpacket(session, encrypted);
if(rc == LIBSSH2_ERROR_EAGAIN) { if(rc == LIBSSH2_ERROR_EAGAIN) {
if (session->packAdd_state != libssh2_NB_state_idle) if(session->packAdd_state != libssh2_NB_state_idle) {
{
/* fullpacket only returns LIBSSH2_ERROR_EAGAIN if /* fullpacket only returns LIBSSH2_ERROR_EAGAIN if
* libssh2_packet_add returns LIBSSH2_ERROR_EAGAIN. If that * libssh2_packet_add returns LIBSSH2_ERROR_EAGAIN. If
* returns LIBSSH2_ERROR_EAGAIN but the packAdd_state is idle, * that returns LIBSSH2_ERROR_EAGAIN but the packAdd_state
* then the packet has been added to the brigade, but some * is idle, then the packet has been added to the brigade,
* immediate action that was taken based on the packet * but some immediate action that was taken based on the
* type (such as key re-exchange) is not yet complete. * packet type (such as key re-exchange) is not yet
* Clear the way for a new packet to be read in. * complete. Clear the way for a new packet to be read
* in.
*/ */
session->readPack_encrypted = encrypted; session->readPack_encrypted = encrypted;
session->readPack_state = libssh2_NB_state_jump1; session->readPack_state = libssh2_NB_state_jump1;
@@ -781,7 +786,8 @@ int _libssh2_transport_send(LIBSSH2_SESSION *session,
dest2_len -= dest_len; dest2_len -= dest_len;
rc = session->local.comp->comp(session, rc = session->local.comp->comp(session,
&p->outbuf[5+dest_len], &dest2_len, &p->outbuf[5 + dest_len],
&dest2_len,
data2, data2_len, data2, data2_len,
&session->local.comp_abstract); &session->local.comp_abstract);
} }

View File

@@ -127,7 +127,8 @@ static char *userauth_list(LIBSSH2_SESSION *session, const char *username,
_libssh2_error(session, LIBSSH2_ERROR_EAGAIN, _libssh2_error(session, LIBSSH2_ERROR_EAGAIN,
"Would block requesting userauth list"); "Would block requesting userauth list");
return NULL; return NULL;
} else if (rc || (session->userauth_list_data_len < 1)) { }
else if(rc || (session->userauth_list_data_len < 1)) {
_libssh2_error(session, rc, "Failed getting response"); _libssh2_error(session, rc, "Failed getting response");
session->userauth_list_state = libssh2_NB_state_idle; session->userauth_list_state = libssh2_NB_state_idle;
return NULL; return NULL;
@@ -157,6 +158,7 @@ static char *userauth_list(LIBSSH2_SESSION *session, const char *username,
"Unexpected userauth list size"); "Unexpected userauth list size");
return NULL; return NULL;
} }
/* Do note that the memory areas overlap! */ /* Do note that the memory areas overlap! */
memmove(session->userauth_list_data, session->userauth_list_data + 5, memmove(session->userauth_list_data, session->userauth_list_data + 5,
methods_len); methods_len);
@@ -311,7 +313,9 @@ userauth_password(LIBSSH2_SESSION *session,
session->state |= LIBSSH2_STATE_AUTHENTICATED; session->state |= LIBSSH2_STATE_AUTHENTICATED;
session->userauth_pswd_state = libssh2_NB_state_idle; session->userauth_pswd_state = libssh2_NB_state_idle;
return 0; return 0;
} else if (session->userauth_pswd_data[0] == SSH_MSG_USERAUTH_FAILURE) { }
else if(session->userauth_pswd_data[0] ==
SSH_MSG_USERAUTH_FAILURE) {
_libssh2_debug(session, LIBSSH2_TRACE_AUTH, _libssh2_debug(session, LIBSSH2_TRACE_AUTH,
"Password authentication failed"); "Password authentication failed");
LIBSSH2_FREE(session, session->userauth_pswd_data); LIBSSH2_FREE(session, session->userauth_pswd_data);
@@ -350,7 +354,8 @@ userauth_password(LIBSSH2_SESSION *session,
session->userauth_pswd_data = NULL; session->userauth_pswd_data = NULL;
} }
if(passwd_change_cb) { if(passwd_change_cb) {
if (session->userauth_pswd_state == libssh2_NB_state_sent1) { if(session->userauth_pswd_state ==
libssh2_NB_state_sent1) {
passwd_change_cb(session, passwd_change_cb(session,
&session->userauth_pswd_newpw, &session->userauth_pswd_newpw,
&session->userauth_pswd_newpw_len, &session->userauth_pswd_newpw_len,
@@ -363,12 +368,18 @@ userauth_password(LIBSSH2_SESSION *session,
} }
/* basic data_len + newpw_len(4) */ /* basic data_len + newpw_len(4) */
if(username_len + password_len + 44 <= UINT_MAX) {
session->userauth_pswd_data_len = session->userauth_pswd_data_len =
username_len + password_len + 44; username_len + password_len + 44;
s = session->userauth_pswd_data = s = session->userauth_pswd_data =
LIBSSH2_ALLOC(session, LIBSSH2_ALLOC(session,
session->userauth_pswd_data_len); session->userauth_pswd_data_len);
}
else {
s = session->userauth_pswd_data = NULL;
session->userauth_pswd_data_len = 0;
}
if(!session->userauth_pswd_data) { if(!session->userauth_pswd_data) {
LIBSSH2_FREE(session, LIBSSH2_FREE(session,
session->userauth_pswd_newpw); session->userauth_pswd_newpw);
@@ -394,7 +405,8 @@ userauth_password(LIBSSH2_SESSION *session,
session->userauth_pswd_state = libssh2_NB_state_sent2; session->userauth_pswd_state = libssh2_NB_state_sent2;
} }
if (session->userauth_pswd_state == libssh2_NB_state_sent2) { if(session->userauth_pswd_state ==
libssh2_NB_state_sent2) {
rc = _libssh2_transport_send(session, rc = _libssh2_transport_send(session,
session->userauth_pswd_data, session->userauth_pswd_data,
session->userauth_pswd_data_len, session->userauth_pswd_data_len,
@@ -402,7 +414,8 @@ userauth_password(LIBSSH2_SESSION *session,
session->userauth_pswd_newpw, session->userauth_pswd_newpw,
session->userauth_pswd_newpw_len); session->userauth_pswd_newpw_len);
if(rc == LIBSSH2_ERROR_EAGAIN) { if(rc == LIBSSH2_ERROR_EAGAIN) {
return _libssh2_error(session, LIBSSH2_ERROR_EAGAIN, return _libssh2_error(session,
LIBSSH2_ERROR_EAGAIN,
"Would block waiting"); "Would block waiting");
} }
@@ -427,7 +440,8 @@ userauth_password(LIBSSH2_SESSION *session,
goto password_response; goto password_response;
} }
} }
} else { }
else {
session->userauth_pswd_state = libssh2_NB_state_idle; session->userauth_pswd_state = libssh2_NB_state_idle;
return _libssh2_error(session, LIBSSH2_ERROR_PASSWORD_EXPIRED, return _libssh2_error(session, LIBSSH2_ERROR_PASSWORD_EXPIRED,
"Password Expired, and no callback " "Password Expired, and no callback "
@@ -455,7 +469,8 @@ LIBSSH2_API int
libssh2_userauth_password_ex(LIBSSH2_SESSION *session, const char *username, libssh2_userauth_password_ex(LIBSSH2_SESSION *session, const char *username,
unsigned int username_len, const char *password, unsigned int username_len, const char *password,
unsigned int password_len, unsigned int password_len,
LIBSSH2_PASSWD_CHANGEREQ_FUNC((*passwd_change_cb))) LIBSSH2_PASSWD_CHANGEREQ_FUNC
((*passwd_change_cb)))
{ {
int rc; int rc;
BLOCK_ADJUST(rc, session, BLOCK_ADJUST(rc, session,
@@ -502,7 +517,8 @@ memory_read_publickey(LIBSSH2_SESSION * session, unsigned char **method,
"Missing public key data"); "Missing public key data");
} }
if ((sp1 = memchr(pubkey, ' ', pubkey_len)) == NULL) { sp1 = memchr(pubkey, ' ', pubkey_len);
if(sp1 == NULL) {
LIBSSH2_FREE(session, pubkey); LIBSSH2_FREE(session, pubkey);
return _libssh2_error(session, LIBSSH2_ERROR_FILE, return _libssh2_error(session, LIBSSH2_ERROR_FILE,
"Invalid public key data"); "Invalid public key data");
@@ -510,7 +526,8 @@ memory_read_publickey(LIBSSH2_SESSION * session, unsigned char **method,
sp1++; sp1++;
if ((sp2 = memchr(sp1, ' ', pubkey_len - (sp1 - pubkey - 1))) == NULL) { sp2 = memchr(sp1, ' ', pubkey_len - (sp1 - pubkey));
if(sp2 == NULL) {
/* Assume that the id string is missing, but that it's okay */ /* Assume that the id string is missing, but that it's okay */
sp2 = pubkey + pubkey_len; sp2 = pubkey + pubkey_len;
} }
@@ -561,7 +578,7 @@ file_read_publickey(LIBSSH2_SESSION * session, unsigned char **method,
_libssh2_debug(session, LIBSSH2_TRACE_AUTH, "Loading public key file: %s", _libssh2_debug(session, LIBSSH2_TRACE_AUTH, "Loading public key file: %s",
pubkeyfile); pubkeyfile);
/* Read Public Key */ /* Read Public Key */
fd = fopen(pubkeyfile, "r"); fd = fopen(pubkeyfile, FOPEN_READTEXT);
if(!fd) { if(!fd) {
return _libssh2_error(session, LIBSSH2_ERROR_FILE, return _libssh2_error(session, LIBSSH2_ERROR_FILE,
"Unable to open public key file"); "Unable to open public key file");
@@ -603,7 +620,8 @@ file_read_publickey(LIBSSH2_SESSION * session, unsigned char **method,
"Missing public key data"); "Missing public key data");
} }
if ((sp1 = memchr(pubkey, ' ', pubkey_len)) == NULL) { sp1 = memchr(pubkey, ' ', pubkey_len);
if(sp1 == NULL) {
LIBSSH2_FREE(session, pubkey); LIBSSH2_FREE(session, pubkey);
return _libssh2_error(session, LIBSSH2_ERROR_FILE, return _libssh2_error(session, LIBSSH2_ERROR_FILE,
"Invalid public key data"); "Invalid public key data");
@@ -612,7 +630,8 @@ file_read_publickey(LIBSSH2_SESSION * session, unsigned char **method,
sp1++; sp1++;
sp_len = sp1 > pubkey ? (sp1 - pubkey) - 1 : 0; sp_len = sp1 > pubkey ? (sp1 - pubkey) - 1 : 0;
if ((sp2 = memchr(sp1, ' ', pubkey_len - sp_len)) == NULL) { sp2 = memchr(sp1, ' ', pubkey_len - sp_len);
if(sp2 == NULL) {
/* Assume that the id string is missing, but that it's okay */ /* Assume that the id string is missing, but that it's okay */
sp2 = pubkey + pubkey_len; sp2 = pubkey + pubkey_len;
} }
@@ -746,7 +765,7 @@ sign_frommemory(LIBSSH2_SESSION *session, unsigned char **sig, size_t *sig_len,
if(privkeyobj->signv(session, sig, sig_len, 1, &datavec, if(privkeyobj->signv(session, sig, sig_len, 1, &datavec,
&hostkey_abstract)) { &hostkey_abstract)) {
if(privkeyobj->dtor) { if(privkeyobj->dtor) {
privkeyobj->dtor(session, abstract); privkeyobj->dtor(session, &hostkey_abstract);
} }
return -1; return -1;
} }
@@ -809,9 +828,15 @@ userauth_hostbased_fromfile(LIBSSH2_SESSION *session,
{ {
int rc; int rc;
#if !LIBSSH2_RSA
return _libssh2_error(session, LIBSSH2_ERROR_METHOD_NOT_SUPPORTED,
"RSA is not supported by crypto backend");
#endif
if(session->userauth_host_state == libssh2_NB_state_idle) { if(session->userauth_host_state == libssh2_NB_state_idle) {
const LIBSSH2_HOSTKEY_METHOD *privkeyobj; const LIBSSH2_HOSTKEY_METHOD *privkeyobj;
unsigned char *pubkeydata, *sig = NULL; unsigned char *pubkeydata = NULL;
unsigned char *sig = NULL;
size_t pubkeydata_len = 0; size_t pubkeydata_len = 0;
size_t sig_len = 0; size_t sig_len = 0;
void *abstract; void *abstract;
@@ -947,7 +972,8 @@ userauth_hostbased_fromfile(LIBSSH2_SESSION *session,
session->userauth_host_packet + session->userauth_host_packet_len; session->userauth_host_packet + session->userauth_host_packet_len;
_libssh2_store_u32(&session->userauth_host_s, _libssh2_store_u32(&session->userauth_host_s,
4 + session->userauth_host_method_len + 4 + sig_len); 4 + session->userauth_host_method_len +
4 + sig_len);
_libssh2_store_str(&session->userauth_host_s, _libssh2_store_str(&session->userauth_host_s,
(const char *)session->userauth_host_method, (const char *)session->userauth_host_method,
session->userauth_host_method_len); session->userauth_host_method_len);
@@ -970,7 +996,8 @@ userauth_hostbased_fromfile(LIBSSH2_SESSION *session,
session->userauth_host_packet, session->userauth_host_packet,
NULL, 0); NULL, 0);
if(rc == LIBSSH2_ERROR_EAGAIN) { if(rc == LIBSSH2_ERROR_EAGAIN) {
return _libssh2_error(session, LIBSSH2_ERROR_EAGAIN, "Would block"); return _libssh2_error(session, LIBSSH2_ERROR_EAGAIN,
"Would block");
} }
else if(rc) { else if(rc) {
LIBSSH2_FREE(session, session->userauth_host_packet); LIBSSH2_FREE(session, session->userauth_host_packet);
@@ -995,7 +1022,8 @@ userauth_hostbased_fromfile(LIBSSH2_SESSION *session,
&session-> &session->
userauth_host_packet_requirev_state); userauth_host_packet_requirev_state);
if(rc == LIBSSH2_ERROR_EAGAIN) { if(rc == LIBSSH2_ERROR_EAGAIN) {
return _libssh2_error(session, LIBSSH2_ERROR_EAGAIN, "Would block"); return _libssh2_error(session, LIBSSH2_ERROR_EAGAIN,
"Would block");
} }
session->userauth_host_state = libssh2_NB_state_idle; session->userauth_host_state = libssh2_NB_state_idle;
@@ -1055,7 +1083,8 @@ _libssh2_userauth_publickey(LIBSSH2_SESSION *session,
unsigned int username_len, unsigned int username_len,
const unsigned char *pubkeydata, const unsigned char *pubkeydata,
unsigned long pubkeydata_len, unsigned long pubkeydata_len,
LIBSSH2_USERAUTH_PUBLICKEY_SIGN_FUNC((*sign_callback)), LIBSSH2_USERAUTH_PUBLICKEY_SIGN_FUNC
((*sign_callback)),
void *abstract) void *abstract)
{ {
unsigned char reply_codes[4] = unsigned char reply_codes[4] =
@@ -1088,7 +1117,7 @@ _libssh2_userauth_publickey(LIBSSH2_SESSION *session,
if(!session->userauth_pblc_method) { if(!session->userauth_pblc_method) {
session->userauth_pblc_method_len = _libssh2_ntohu32(pubkeydata); session->userauth_pblc_method_len = _libssh2_ntohu32(pubkeydata);
if(session->userauth_pblc_method_len > pubkeydata_len) if(session->userauth_pblc_method_len > pubkeydata_len - 4)
/* the method length simply cannot be longer than the entire /* the method length simply cannot be longer than the entire
passed in data, so we use this to detect crazy input passed in data, so we use this to detect crazy input
data */ data */
@@ -1100,8 +1129,8 @@ _libssh2_userauth_publickey(LIBSSH2_SESSION *session,
LIBSSH2_ALLOC(session, session->userauth_pblc_method_len); LIBSSH2_ALLOC(session, session->userauth_pblc_method_len);
if(!session->userauth_pblc_method) { if(!session->userauth_pblc_method) {
return _libssh2_error(session, LIBSSH2_ERROR_ALLOC, return _libssh2_error(session, LIBSSH2_ERROR_ALLOC,
"Unable to allocate memory for public key " "Unable to allocate memory "
"data"); "for public key data");
} }
memcpy(session->userauth_pblc_method, pubkeydata + 4, memcpy(session->userauth_pblc_method, pubkeydata + 4,
session->userauth_pblc_method_len); session->userauth_pblc_method_len);
@@ -1171,7 +1200,8 @@ _libssh2_userauth_publickey(LIBSSH2_SESSION *session,
session->userauth_pblc_packet_len, session->userauth_pblc_packet_len,
NULL, 0); NULL, 0);
if(rc == LIBSSH2_ERROR_EAGAIN) if(rc == LIBSSH2_ERROR_EAGAIN)
return _libssh2_error(session, LIBSSH2_ERROR_EAGAIN, "Would block"); return _libssh2_error(session, LIBSSH2_ERROR_EAGAIN,
"Would block");
else if(rc) { else if(rc) {
LIBSSH2_FREE(session, session->userauth_pblc_packet); LIBSSH2_FREE(session, session->userauth_pblc_packet);
session->userauth_pblc_packet = NULL; session->userauth_pblc_packet = NULL;
@@ -1193,7 +1223,8 @@ _libssh2_userauth_publickey(LIBSSH2_SESSION *session,
&session-> &session->
userauth_pblc_packet_requirev_state); userauth_pblc_packet_requirev_state);
if(rc == LIBSSH2_ERROR_EAGAIN) { if(rc == LIBSSH2_ERROR_EAGAIN) {
return _libssh2_error(session, LIBSSH2_ERROR_EAGAIN, "Would block"); return _libssh2_error(session, LIBSSH2_ERROR_EAGAIN,
"Would block");
} }
else if(rc || (session->userauth_pblc_data_len < 1)) { else if(rc || (session->userauth_pblc_data_len < 1)) {
LIBSSH2_FREE(session, session->userauth_pblc_packet); LIBSSH2_FREE(session, session->userauth_pblc_packet);
@@ -1267,8 +1298,10 @@ _libssh2_userauth_publickey(LIBSSH2_SESSION *session,
rc = sign_callback(session, &sig, &sig_len, buf, s - buf, abstract); rc = sign_callback(session, &sig, &sig_len, buf, s - buf, abstract);
LIBSSH2_FREE(session, buf); LIBSSH2_FREE(session, buf);
if(rc == LIBSSH2_ERROR_EAGAIN) { if(rc == LIBSSH2_ERROR_EAGAIN) {
return _libssh2_error(session, LIBSSH2_ERROR_EAGAIN, "Would block"); return _libssh2_error(session, LIBSSH2_ERROR_EAGAIN,
} else if (rc) { "Would block");
}
else if(rc) {
LIBSSH2_FREE(session, session->userauth_pblc_method); LIBSSH2_FREE(session, session->userauth_pblc_method);
session->userauth_pblc_method = NULL; session->userauth_pblc_method = NULL;
LIBSSH2_FREE(session, session->userauth_pblc_packet); LIBSSH2_FREE(session, session->userauth_pblc_packet);
@@ -1308,7 +1341,8 @@ _libssh2_userauth_publickey(LIBSSH2_SESSION *session,
session->userauth_pblc_b = NULL; session->userauth_pblc_b = NULL;
_libssh2_store_u32(&s, _libssh2_store_u32(&s,
4 + session->userauth_pblc_method_len + 4 + sig_len); 4 + session->userauth_pblc_method_len + 4 +
sig_len);
_libssh2_store_str(&s, (const char *)session->userauth_pblc_method, _libssh2_store_str(&s, (const char *)session->userauth_pblc_method,
session->userauth_pblc_method_len); session->userauth_pblc_method_len);
@@ -1331,8 +1365,10 @@ _libssh2_userauth_publickey(LIBSSH2_SESSION *session,
session->userauth_pblc_packet, session->userauth_pblc_packet,
NULL, 0); NULL, 0);
if(rc == LIBSSH2_ERROR_EAGAIN) { if(rc == LIBSSH2_ERROR_EAGAIN) {
return _libssh2_error(session, LIBSSH2_ERROR_EAGAIN, "Would block"); return _libssh2_error(session, LIBSSH2_ERROR_EAGAIN,
} else if (rc) { "Would block");
}
else if(rc) {
LIBSSH2_FREE(session, session->userauth_pblc_packet); LIBSSH2_FREE(session, session->userauth_pblc_packet);
session->userauth_pblc_packet = NULL; session->userauth_pblc_packet = NULL;
session->userauth_pblc_state = libssh2_NB_state_idle; session->userauth_pblc_state = libssh2_NB_state_idle;
@@ -1355,7 +1391,8 @@ _libssh2_userauth_publickey(LIBSSH2_SESSION *session,
if(rc == LIBSSH2_ERROR_EAGAIN) { if(rc == LIBSSH2_ERROR_EAGAIN) {
return _libssh2_error(session, LIBSSH2_ERROR_EAGAIN, return _libssh2_error(session, LIBSSH2_ERROR_EAGAIN,
"Would block requesting userauth list"); "Would block requesting userauth list");
} else if (rc || session->userauth_pblc_data_len < 1) { }
else if(rc || session->userauth_pblc_data_len < 1) {
session->userauth_pblc_state = libssh2_NB_state_idle; session->userauth_pblc_state = libssh2_NB_state_idle;
return _libssh2_error(session, LIBSSH2_ERROR_PUBLICKEY_UNVERIFIED, return _libssh2_error(session, LIBSSH2_ERROR_PUBLICKEY_UNVERIFIED,
"Waiting for publickey USERAUTH response"); "Waiting for publickey USERAUTH response");
@@ -1401,6 +1438,11 @@ userauth_publickey_frommemory(LIBSSH2_SESSION *session,
void *abstract = &privkey_file; void *abstract = &privkey_file;
int rc; int rc;
#if !LIBSSH2_RSA
return _libssh2_error(session, LIBSSH2_ERROR_METHOD_NOT_SUPPORTED,
"RSA is not supported by crypto backend");
#endif
privkey_file.filename = privatekeydata; privkey_file.filename = privatekeydata;
privkey_file.passphrase = passphrase; privkey_file.passphrase = passphrase;
@@ -1458,6 +1500,11 @@ userauth_publickey_fromfile(LIBSSH2_SESSION *session,
void *abstract = &privkey_file; void *abstract = &privkey_file;
int rc; int rc;
#if !LIBSSH2_RSA
return _libssh2_error(session, LIBSSH2_ERROR_METHOD_NOT_SUPPORTED,
"RSA is not supported by crypto backend");
#endif
privkey_file.filename = privatekey; privkey_file.filename = privatekey;
privkey_file.passphrase = passphrase; privkey_file.passphrase = passphrase;
@@ -1555,7 +1602,8 @@ libssh2_userauth_publickey(LIBSSH2_SESSION *session,
const char *user, const char *user,
const unsigned char *pubkeydata, const unsigned char *pubkeydata,
size_t pubkeydata_len, size_t pubkeydata_len,
LIBSSH2_USERAUTH_PUBLICKEY_SIGN_FUNC((*sign_callback)), LIBSSH2_USERAUTH_PUBLICKEY_SIGN_FUNC
((*sign_callback)),
void **abstract) void **abstract)
{ {
int rc; int rc;
@@ -1581,7 +1629,8 @@ static int
userauth_keyboard_interactive(LIBSSH2_SESSION * session, userauth_keyboard_interactive(LIBSSH2_SESSION * session,
const char *username, const char *username,
unsigned int username_len, unsigned int username_len,
LIBSSH2_USERAUTH_KBDINT_RESPONSE_FUNC((*response_callback))) LIBSSH2_USERAUTH_KBDINT_RESPONSE_FUNC
((*response_callback)))
{ {
unsigned char *s; unsigned char *s;
int rc; int rc;
@@ -1652,13 +1701,16 @@ userauth_keyboard_interactive(LIBSSH2_SESSION * session,
session->userauth_kybd_packet_len, session->userauth_kybd_packet_len,
NULL, 0); NULL, 0);
if(rc == LIBSSH2_ERROR_EAGAIN) { if(rc == LIBSSH2_ERROR_EAGAIN) {
return _libssh2_error(session, LIBSSH2_ERROR_EAGAIN, "Would block"); return _libssh2_error(session, LIBSSH2_ERROR_EAGAIN,
} else if (rc) { "Would block");
}
else if(rc) {
LIBSSH2_FREE(session, session->userauth_kybd_data); LIBSSH2_FREE(session, session->userauth_kybd_data);
session->userauth_kybd_data = NULL; session->userauth_kybd_data = NULL;
session->userauth_kybd_state = libssh2_NB_state_idle; session->userauth_kybd_state = libssh2_NB_state_idle;
return _libssh2_error(session, LIBSSH2_ERROR_SOCKET_SEND, return _libssh2_error(session, LIBSSH2_ERROR_SOCKET_SEND,
"Unable to send keyboard-interactive request"); "Unable to send keyboard-interactive"
" request");
} }
LIBSSH2_FREE(session, session->userauth_kybd_data); LIBSSH2_FREE(session, session->userauth_kybd_data);
session->userauth_kybd_data = NULL; session->userauth_kybd_data = NULL;
@@ -1677,16 +1729,19 @@ userauth_keyboard_interactive(LIBSSH2_SESSION * session,
if(rc == LIBSSH2_ERROR_EAGAIN) { if(rc == LIBSSH2_ERROR_EAGAIN) {
return _libssh2_error(session, LIBSSH2_ERROR_EAGAIN, return _libssh2_error(session, LIBSSH2_ERROR_EAGAIN,
"Would block"); "Would block");
} else if (rc || session->userauth_kybd_data_len < 1) { }
else if(rc || session->userauth_kybd_data_len < 1) {
session->userauth_kybd_state = libssh2_NB_state_idle; session->userauth_kybd_state = libssh2_NB_state_idle;
return _libssh2_error(session, return _libssh2_error(session,
LIBSSH2_ERROR_AUTHENTICATION_FAILED, LIBSSH2_ERROR_AUTHENTICATION_FAILED,
"Waiting for keyboard USERAUTH response"); "Waiting for keyboard "
"USERAUTH response");
} }
if(session->userauth_kybd_data[0] == SSH_MSG_USERAUTH_SUCCESS) { if(session->userauth_kybd_data[0] == SSH_MSG_USERAUTH_SUCCESS) {
_libssh2_debug(session, LIBSSH2_TRACE_AUTH, _libssh2_debug(session, LIBSSH2_TRACE_AUTH,
"Keyboard-interactive authentication successful"); "Keyboard-interactive "
"authentication successful");
LIBSSH2_FREE(session, session->userauth_kybd_data); LIBSSH2_FREE(session, session->userauth_kybd_data);
session->userauth_kybd_data = NULL; session->userauth_kybd_data = NULL;
session->state |= LIBSSH2_STATE_AUTHENTICATED; session->state |= LIBSSH2_STATE_AUTHENTICATED;
@@ -1709,9 +1764,18 @@ userauth_keyboard_interactive(LIBSSH2_SESSION * session,
/* server requested PAM-like conversation */ /* server requested PAM-like conversation */
s = session->userauth_kybd_data + 1; s = session->userauth_kybd_data + 1;
if(session->userauth_kybd_data_len >= 5) {
/* string name (ISO-10646 UTF-8) */ /* string name (ISO-10646 UTF-8) */
session->userauth_kybd_auth_name_len = _libssh2_ntohu32(s); session->userauth_kybd_auth_name_len = _libssh2_ntohu32(s);
s += 4; s += 4;
}
else {
_libssh2_error(session, LIBSSH2_ERROR_BUFFER_TOO_SMALL,
"userauth keyboard data buffer too small"
"to get length");
goto cleanup;
}
if(session->userauth_kybd_auth_name_len) { if(session->userauth_kybd_auth_name_len) {
session->userauth_kybd_auth_name = session->userauth_kybd_auth_name =
LIBSSH2_ALLOC(session, LIBSSH2_ALLOC(session,
@@ -1723,14 +1787,35 @@ userauth_keyboard_interactive(LIBSSH2_SESSION * session,
"request field"); "request field");
goto cleanup; goto cleanup;
} }
if(s + session->userauth_list_data_len <=
session->userauth_kybd_data +
session->userauth_kybd_data_len) {
memcpy(session->userauth_kybd_auth_name, s, memcpy(session->userauth_kybd_auth_name, s,
session->userauth_kybd_auth_name_len); session->userauth_kybd_auth_name_len);
s += session->userauth_kybd_auth_name_len; s += session->userauth_kybd_auth_name_len;
} }
else {
_libssh2_error(session, LIBSSH2_ERROR_BUFFER_TOO_SMALL,
"userauth keyboard data buffer too small"
"for auth name");
goto cleanup;
}
}
if(s + 4 <= session->userauth_kybd_data +
session->userauth_kybd_data_len) {
/* string instruction (ISO-10646 UTF-8) */ /* string instruction (ISO-10646 UTF-8) */
session->userauth_kybd_auth_instruction_len = _libssh2_ntohu32(s); session->userauth_kybd_auth_instruction_len =
_libssh2_ntohu32(s);
s += 4; s += 4;
}
else {
_libssh2_error(session, LIBSSH2_ERROR_BUFFER_TOO_SMALL,
"userauth keyboard data buffer too small"
"for auth instruction length");
goto cleanup;
}
if(session->userauth_kybd_auth_instruction_len) { if(session->userauth_kybd_auth_instruction_len) {
session->userauth_kybd_auth_instruction = session->userauth_kybd_auth_instruction =
LIBSSH2_ALLOC(session, LIBSSH2_ALLOC(session,
@@ -1742,23 +1827,60 @@ userauth_keyboard_interactive(LIBSSH2_SESSION * session,
"request field"); "request field");
goto cleanup; goto cleanup;
} }
if(s + session->userauth_kybd_auth_instruction_len <=
session->userauth_kybd_data +
session->userauth_kybd_data_len) {
memcpy(session->userauth_kybd_auth_instruction, s, memcpy(session->userauth_kybd_auth_instruction, s,
session->userauth_kybd_auth_instruction_len); session->userauth_kybd_auth_instruction_len);
s += session->userauth_kybd_auth_instruction_len; s += session->userauth_kybd_auth_instruction_len;
} }
else {
_libssh2_error(session, LIBSSH2_ERROR_BUFFER_TOO_SMALL,
"userauth keyboard data buffer too small"
"for auth instruction");
goto cleanup;
}
}
if(s + 4 <= session->userauth_kybd_data +
session->userauth_kybd_data_len) {
/* string language tag (as defined in [RFC-3066]) */ /* string language tag (as defined in [RFC-3066]) */
language_tag_len = _libssh2_ntohu32(s); language_tag_len = _libssh2_ntohu32(s);
s += 4; s += 4;
}
else {
_libssh2_error(session, LIBSSH2_ERROR_BUFFER_TOO_SMALL,
"userauth keyboard data buffer too small"
"for auth language tag length");
goto cleanup;
}
if(s + language_tag_len <= session->userauth_kybd_data +
session->userauth_kybd_data_len) {
/* ignoring this field as deprecated */ /* ignoring this field as deprecated */
s += language_tag_len; s += language_tag_len;
}
else {
_libssh2_error(session, LIBSSH2_ERROR_BUFFER_TOO_SMALL,
"userauth keyboard data buffer too small"
"for auth language tag");
goto cleanup;
}
if(s + 4 <= session->userauth_kybd_data +
session->userauth_kybd_data_len) {
/* int num-prompts */ /* int num-prompts */
session->userauth_kybd_num_prompts = _libssh2_ntohu32(s); session->userauth_kybd_num_prompts = _libssh2_ntohu32(s);
s += 4; s += 4;
if(session->userauth_kybd_num_prompts && }
session->userauth_kybd_num_prompts > 100) { else {
_libssh2_error(session, LIBSSH2_ERROR_BUFFER_TOO_SMALL,
"userauth keyboard data buffer too small"
"for auth num keyboard prompts");
goto cleanup;
}
if(session->userauth_kybd_num_prompts > 100) {
_libssh2_error(session, LIBSSH2_ERROR_OUT_OF_BOUNDARY, _libssh2_error(session, LIBSSH2_ERROR_OUT_OF_BOUNDARY,
"Too many replies for " "Too many replies for "
"keyboard-interactive prompts"); "keyboard-interactive prompts");
@@ -1789,26 +1911,57 @@ userauth_keyboard_interactive(LIBSSH2_SESSION * session,
} }
for(i = 0; i < session->userauth_kybd_num_prompts; i++) { for(i = 0; i < session->userauth_kybd_num_prompts; i++) {
if(s + 4 <= session->userauth_kybd_data +
session->userauth_kybd_data_len) {
/* string prompt[1] (ISO-10646 UTF-8) */ /* string prompt[1] (ISO-10646 UTF-8) */
session->userauth_kybd_prompts[i].length = session->userauth_kybd_prompts[i].length =
_libssh2_ntohu32(s); _libssh2_ntohu32(s);
s += 4; s += 4;
}
else {
_libssh2_error(session, LIBSSH2_ERROR_BUFFER_TOO_SMALL,
"userauth keyboard data buffer too "
"small for auth keyboard "
"prompt length");
goto cleanup;
}
session->userauth_kybd_prompts[i].text = session->userauth_kybd_prompts[i].text =
LIBSSH2_CALLOC(session, LIBSSH2_CALLOC(session,
session->userauth_kybd_prompts[i].length); session->userauth_kybd_prompts[i].
length);
if(!session->userauth_kybd_prompts[i].text) { if(!session->userauth_kybd_prompts[i].text) {
_libssh2_error(session, LIBSSH2_ERROR_ALLOC, _libssh2_error(session, LIBSSH2_ERROR_ALLOC,
"Unable to allocate memory for " "Unable to allocate memory for "
"keyboard-interactive prompt message"); "keyboard-interactive prompt message");
goto cleanup; goto cleanup;
} }
if(s + session->userauth_kybd_prompts[i].length <=
session->userauth_kybd_data +
session->userauth_kybd_data_len) {
memcpy(session->userauth_kybd_prompts[i].text, s, memcpy(session->userauth_kybd_prompts[i].text, s,
session->userauth_kybd_prompts[i].length); session->userauth_kybd_prompts[i].length);
s += session->userauth_kybd_prompts[i].length; s += session->userauth_kybd_prompts[i].length;
}
else {
_libssh2_error(session, LIBSSH2_ERROR_BUFFER_TOO_SMALL,
"userauth keyboard data buffer too "
"small for auth keyboard prompt");
goto cleanup;
}
if(s < session->userauth_kybd_data +
session->userauth_kybd_data_len) {
/* boolean echo[1] */ /* boolean echo[1] */
session->userauth_kybd_prompts[i].echo = *s++; session->userauth_kybd_prompts[i].echo = *s++;
} }
else {
_libssh2_error(session, LIBSSH2_ERROR_BUFFER_TOO_SMALL,
"userauth keyboard data buffer too "
"small for auth keyboard prompt echo");
goto cleanup;
}
}
} }
response_callback(session->userauth_kybd_auth_name, response_callback(session->userauth_kybd_auth_name,
@@ -1946,7 +2099,8 @@ LIBSSH2_API int
libssh2_userauth_keyboard_interactive_ex(LIBSSH2_SESSION *session, libssh2_userauth_keyboard_interactive_ex(LIBSSH2_SESSION *session,
const char *user, const char *user,
unsigned int user_len, unsigned int user_len,
LIBSSH2_USERAUTH_KBDINT_RESPONSE_FUNC((*response_callback))) LIBSSH2_USERAUTH_KBDINT_RESPONSE_FUNC
((*response_callback)))
{ {
int rc; int rc;
BLOCK_ADJUST(rc, session, BLOCK_ADJUST(rc, session,

View File

@@ -44,7 +44,8 @@ _libssh2_userauth_publickey(LIBSSH2_SESSION *session,
unsigned int username_len, unsigned int username_len,
const unsigned char *pubkeydata, const unsigned char *pubkeydata,
unsigned long pubkeydata_len, unsigned long pubkeydata_len,
LIBSSH2_USERAUTH_PUBLICKEY_SIGN_FUNC((*sign_callback)), LIBSSH2_USERAUTH_PUBLICKEY_SIGN_FUNC
((*sign_callback)),
void *abstract); void *abstract);
#endif /* LIBSSH2_USERAUTH_H */ #endif /* LIBSSH2_USERAUTH_H */

View File

@@ -59,6 +59,7 @@
#include <windows.h> #include <windows.h>
#include <bcrypt.h> #include <bcrypt.h>
#include <math.h> #include <math.h>
#include "misc.h"
#ifdef HAVE_STDLIB_H #ifdef HAVE_STDLIB_H
#include <stdlib.h> #include <stdlib.h>
@@ -245,7 +246,8 @@ _libssh2_wincng_init(void)
ret = BCryptOpenAlgorithmProvider(&_libssh2_wincng.hAlgAES_CBC, ret = BCryptOpenAlgorithmProvider(&_libssh2_wincng.hAlgAES_CBC,
BCRYPT_AES_ALGORITHM, NULL, 0); BCRYPT_AES_ALGORITHM, NULL, 0);
if(BCRYPT_SUCCESS(ret)) { if(BCRYPT_SUCCESS(ret)) {
ret = BCryptSetProperty(_libssh2_wincng.hAlgAES_CBC, BCRYPT_CHAINING_MODE, ret = BCryptSetProperty(_libssh2_wincng.hAlgAES_CBC,
BCRYPT_CHAINING_MODE,
(PBYTE)BCRYPT_CHAIN_MODE_CBC, (PBYTE)BCRYPT_CHAIN_MODE_CBC,
sizeof(BCRYPT_CHAIN_MODE_CBC), 0); sizeof(BCRYPT_CHAIN_MODE_CBC), 0);
if(!BCRYPT_SUCCESS(ret)) { if(!BCRYPT_SUCCESS(ret)) {
@@ -253,10 +255,23 @@ _libssh2_wincng_init(void)
} }
} }
ret = BCryptOpenAlgorithmProvider(&_libssh2_wincng.hAlgAES_ECB,
BCRYPT_AES_ALGORITHM, NULL, 0);
if(BCRYPT_SUCCESS(ret)) {
ret = BCryptSetProperty(_libssh2_wincng.hAlgAES_ECB,
BCRYPT_CHAINING_MODE,
(PBYTE)BCRYPT_CHAIN_MODE_ECB,
sizeof(BCRYPT_CHAIN_MODE_ECB), 0);
if(!BCRYPT_SUCCESS(ret)) {
(void)BCryptCloseAlgorithmProvider(_libssh2_wincng.hAlgAES_ECB, 0);
}
}
ret = BCryptOpenAlgorithmProvider(&_libssh2_wincng.hAlgRC4_NA, ret = BCryptOpenAlgorithmProvider(&_libssh2_wincng.hAlgRC4_NA,
BCRYPT_RC4_ALGORITHM, NULL, 0); BCRYPT_RC4_ALGORITHM, NULL, 0);
if(BCRYPT_SUCCESS(ret)) { if(BCRYPT_SUCCESS(ret)) {
ret = BCryptSetProperty(_libssh2_wincng.hAlgRC4_NA, BCRYPT_CHAINING_MODE, ret = BCryptSetProperty(_libssh2_wincng.hAlgRC4_NA,
BCRYPT_CHAINING_MODE,
(PBYTE)BCRYPT_CHAIN_MODE_NA, (PBYTE)BCRYPT_CHAIN_MODE_NA,
sizeof(BCRYPT_CHAIN_MODE_NA), 0); sizeof(BCRYPT_CHAIN_MODE_NA), 0);
if(!BCRYPT_SUCCESS(ret)) { if(!BCRYPT_SUCCESS(ret)) {
@@ -267,11 +282,13 @@ _libssh2_wincng_init(void)
ret = BCryptOpenAlgorithmProvider(&_libssh2_wincng.hAlg3DES_CBC, ret = BCryptOpenAlgorithmProvider(&_libssh2_wincng.hAlg3DES_CBC,
BCRYPT_3DES_ALGORITHM, NULL, 0); BCRYPT_3DES_ALGORITHM, NULL, 0);
if(BCRYPT_SUCCESS(ret)) { if(BCRYPT_SUCCESS(ret)) {
ret = BCryptSetProperty(_libssh2_wincng.hAlg3DES_CBC, BCRYPT_CHAINING_MODE, ret = BCryptSetProperty(_libssh2_wincng.hAlg3DES_CBC,
BCRYPT_CHAINING_MODE,
(PBYTE)BCRYPT_CHAIN_MODE_CBC, (PBYTE)BCRYPT_CHAIN_MODE_CBC,
sizeof(BCRYPT_CHAIN_MODE_CBC), 0); sizeof(BCRYPT_CHAIN_MODE_CBC), 0);
if(!BCRYPT_SUCCESS(ret)) { if(!BCRYPT_SUCCESS(ret)) {
(void)BCryptCloseAlgorithmProvider(_libssh2_wincng.hAlg3DES_CBC, 0); (void)BCryptCloseAlgorithmProvider(_libssh2_wincng.hAlg3DES_CBC,
0);
} }
} }
} }
@@ -510,7 +527,8 @@ _libssh2_wincng_key_sha1_verify(_libssh2_wincng_key_ctx *ctx,
if(flags & BCRYPT_PAD_PKCS1) { if(flags & BCRYPT_PAD_PKCS1) {
paddingInfoPKCS1.pszAlgId = BCRYPT_SHA1_ALGORITHM; paddingInfoPKCS1.pszAlgId = BCRYPT_SHA1_ALGORITHM;
pPaddingInfo = &paddingInfoPKCS1; pPaddingInfo = &paddingInfoPKCS1;
} else }
else
pPaddingInfo = NULL; pPaddingInfo = NULL;
memcpy(data, sig, datalen); memcpy(data, sig, datalen);
@@ -537,14 +555,13 @@ _libssh2_wincng_load_pem(LIBSSH2_SESSION *session,
FILE *fp; FILE *fp;
int ret; int ret;
(void)passphrase; fp = fopen(filename, FOPEN_READTEXT);
fp = fopen(filename, "r");
if(!fp) { if(!fp) {
return -1; return -1;
} }
ret = _libssh2_pem_parse(session, headerbegin, headerend, ret = _libssh2_pem_parse(session, headerbegin, headerend,
passphrase,
fp, data, datalen); fp, data, datalen);
fclose(fp); fclose(fp);
@@ -764,7 +781,8 @@ _libssh2_wincng_asn_decode_bns(unsigned char *pbEncoded,
*prpbDecoded = rpbDecoded; *prpbDecoded = rpbDecoded;
*prcbDecoded = rcbDecoded; *prcbDecoded = rcbDecoded;
*pcbCount = length; *pcbCount = length;
} else { }
else {
for(length = 0; length < index; length++) { for(length = 0; length < index; length++) {
_libssh2_wincng_safe_free(rpbDecoded[length], _libssh2_wincng_safe_free(rpbDecoded[length],
rcbDecoded[length]); rcbDecoded[length]);
@@ -774,11 +792,13 @@ _libssh2_wincng_asn_decode_bns(unsigned char *pbEncoded,
free(rpbDecoded); free(rpbDecoded);
free(rcbDecoded); free(rcbDecoded);
} }
} else { }
else {
free(rpbDecoded); free(rpbDecoded);
ret = -1; ret = -1;
} }
} else { }
else {
ret = -1; ret = -1;
} }
@@ -917,7 +937,8 @@ _libssh2_wincng_rsa_new(libssh2_rsa_ctx **rsa,
rsakey->Magic = BCRYPT_RSAFULLPRIVATE_MAGIC; rsakey->Magic = BCRYPT_RSAFULLPRIVATE_MAGIC;
rsakey->cbPrime1 = p1len; rsakey->cbPrime1 = p1len;
rsakey->cbPrime2 = p2len; rsakey->cbPrime2 = p2len;
} else { }
else {
lpszBlobType = BCRYPT_RSAPUBLIC_BLOB; lpszBlobType = BCRYPT_RSAPUBLIC_BLOB;
rsakey->Magic = BCRYPT_RSAPUBLIC_MAGIC; rsakey->Magic = BCRYPT_RSAPUBLIC_MAGIC;
rsakey->cbPrime1 = 0; rsakey->cbPrime1 = 0;
@@ -1111,10 +1132,12 @@ _libssh2_wincng_rsa_sha1_sign(LIBSSH2_SESSION *session,
if(BCRYPT_SUCCESS(ret)) { if(BCRYPT_SUCCESS(ret)) {
*signature_len = siglen; *signature_len = siglen;
*signature = sig; *signature = sig;
} else { }
else {
LIBSSH2_FREE(session, sig); LIBSSH2_FREE(session, sig);
} }
} else }
else
ret = STATUS_NO_MEMORY; ret = STATUS_NO_MEMORY;
} }
@@ -1218,7 +1241,8 @@ _libssh2_wincng_dsa_new(libssh2_dsa_ctx **dsa,
lpszBlobType = BCRYPT_DSA_PRIVATE_BLOB; lpszBlobType = BCRYPT_DSA_PRIVATE_BLOB;
dsakey->dwMagic = BCRYPT_DSA_PRIVATE_MAGIC; dsakey->dwMagic = BCRYPT_DSA_PRIVATE_MAGIC;
} else { }
else {
lpszBlobType = BCRYPT_DSA_PUBLIC_BLOB; lpszBlobType = BCRYPT_DSA_PUBLIC_BLOB;
dsakey->dwMagic = BCRYPT_DSA_PUBLIC_MAGIC; dsakey->dwMagic = BCRYPT_DSA_PUBLIC_MAGIC;
} }
@@ -1276,7 +1300,8 @@ _libssh2_wincng_dsa_new_private_parse(libssh2_dsa_ctx **dsa,
rpbDecoded[3], rcbDecoded[3], rpbDecoded[3], rcbDecoded[3],
rpbDecoded[4], rcbDecoded[4], rpbDecoded[4], rcbDecoded[4],
rpbDecoded[5], rcbDecoded[5]); rpbDecoded[5], rcbDecoded[5]);
} else { }
else {
ret = -1; ret = -1;
} }
@@ -1398,9 +1423,11 @@ _libssh2_wincng_dsa_sha1_sign(libssh2_dsa_ctx *dsa,
} }
_libssh2_wincng_safe_free(sig, siglen); _libssh2_wincng_safe_free(sig, siglen);
} else }
else
ret = STATUS_NO_MEMORY; ret = STATUS_NO_MEMORY;
} else }
else
ret = STATUS_NO_MEMORY; ret = STATUS_NO_MEMORY;
} }
@@ -1476,7 +1503,8 @@ _libssh2_wincng_pub_priv_keyfile_parse(LIBSSH2_SESSION *session,
mth = LIBSSH2_ALLOC(session, mthlen); mth = LIBSSH2_ALLOC(session, mthlen);
if(mth) { if(mth) {
memcpy(mth, "ssh-rsa", mthlen); memcpy(mth, "ssh-rsa", mthlen);
} else { }
else {
ret = -1; ret = -1;
} }
@@ -1493,16 +1521,19 @@ _libssh2_wincng_pub_priv_keyfile_parse(LIBSSH2_SESSION *session,
_libssh2_wincng_pub_priv_write(key, offset, _libssh2_wincng_pub_priv_write(key, offset,
rpbDecoded[1], rpbDecoded[1],
rcbDecoded[1]); rcbDecoded[1]);
} else { }
else {
ret = -1; ret = -1;
} }
} else if (length == 6) { /* private DSA key */ }
else if(length == 6) { /* private DSA key */
mthlen = 7; mthlen = 7;
mth = LIBSSH2_ALLOC(session, mthlen); mth = LIBSSH2_ALLOC(session, mthlen);
if(mth) { if(mth) {
memcpy(mth, "ssh-dss", mthlen); memcpy(mth, "ssh-dss", mthlen);
} else { }
else {
ret = -1; ret = -1;
} }
@@ -1527,11 +1558,13 @@ _libssh2_wincng_pub_priv_keyfile_parse(LIBSSH2_SESSION *session,
_libssh2_wincng_pub_priv_write(key, offset, _libssh2_wincng_pub_priv_write(key, offset,
rpbDecoded[4], rpbDecoded[4],
rcbDecoded[4]); rcbDecoded[4]);
} else { }
else {
ret = -1; ret = -1;
} }
} else { }
else {
ret = -1; ret = -1;
} }
@@ -1551,7 +1584,8 @@ _libssh2_wincng_pub_priv_keyfile_parse(LIBSSH2_SESSION *session,
LIBSSH2_FREE(session, mth); LIBSSH2_FREE(session, mth);
if(key) if(key)
LIBSSH2_FREE(session, key); LIBSSH2_FREE(session, key);
} else { }
else {
*method = mth; *method = mth;
*method_len = mthlen; *method_len = mthlen;
*pubkeydata = key; *pubkeydata = key;
@@ -1653,8 +1687,9 @@ _libssh2_wincng_cipher_init(_libssh2_cipher_ctx *ctx,
{ {
BCRYPT_KEY_HANDLE hKey; BCRYPT_KEY_HANDLE hKey;
BCRYPT_KEY_DATA_BLOB_HEADER *header; BCRYPT_KEY_DATA_BLOB_HEADER *header;
unsigned char *pbKeyObject, *pbIV, *key; unsigned char *pbKeyObject, *pbIV, *key, *pbCtr, *pbIVCopy;
unsigned long dwKeyObject, dwIV, dwBlockLength, cbData, keylen; unsigned long dwKeyObject, dwIV, dwCtrLength, dwBlockLength,
cbData, keylen;
int ret; int ret;
(void)encrypt; (void)encrypt;
@@ -1707,31 +1742,41 @@ _libssh2_wincng_cipher_init(_libssh2_cipher_ctx *ctx,
return -1; return -1;
} }
if (type.dwUseIV) { pbIV = NULL;
pbIV = malloc(dwBlockLength); pbCtr = NULL;
if (!pbIV) { dwIV = 0;
dwCtrLength = 0;
if(type.useIV || type.ctrMode) {
pbIVCopy = malloc(dwBlockLength);
if(!pbIVCopy) {
BCryptDestroyKey(hKey); BCryptDestroyKey(hKey);
_libssh2_wincng_safe_free(pbKeyObject, dwKeyObject); _libssh2_wincng_safe_free(pbKeyObject, dwKeyObject);
return -1; return -1;
} }
dwIV = dwBlockLength; memcpy(pbIVCopy, iv, dwBlockLength);
memcpy(pbIV, iv, dwIV);
} else {
pbIV = NULL;
dwIV = 0;
}
if(type.ctrMode) {
pbCtr = pbIVCopy;
dwCtrLength = dwBlockLength;
}
else if(type.useIV) {
pbIV = pbIVCopy;
dwIV = dwBlockLength;
}
}
ctx->hKey = hKey; ctx->hKey = hKey;
ctx->pbKeyObject = pbKeyObject; ctx->pbKeyObject = pbKeyObject;
ctx->pbIV = pbIV; ctx->pbIV = pbIV;
ctx->pbCtr = pbCtr;
ctx->dwKeyObject = dwKeyObject; ctx->dwKeyObject = dwKeyObject;
ctx->dwIV = dwIV; ctx->dwIV = dwIV;
ctx->dwBlockLength = dwBlockLength; ctx->dwBlockLength = dwBlockLength;
ctx->dwCtrLength = dwCtrLength;
return 0; return 0;
} }
int int
_libssh2_wincng_cipher_crypt(_libssh2_cipher_ctx *ctx, _libssh2_wincng_cipher_crypt(_libssh2_cipher_ctx *ctx,
_libssh2_cipher_type(type), _libssh2_cipher_type(type),
@@ -1739,7 +1784,7 @@ _libssh2_wincng_cipher_crypt(_libssh2_cipher_ctx *ctx,
unsigned char *block, unsigned char *block,
size_t blocklen) size_t blocklen)
{ {
unsigned char *pbOutput; unsigned char *pbOutput, *pbInput;
unsigned long cbOutput, cbInput; unsigned long cbOutput, cbInput;
int ret; int ret;
@@ -1747,31 +1792,47 @@ _libssh2_wincng_cipher_crypt(_libssh2_cipher_ctx *ctx,
cbInput = (unsigned long)blocklen; cbInput = (unsigned long)blocklen;
if (encrypt) { if(type.ctrMode) {
ret = BCryptEncrypt(ctx->hKey, block, cbInput, NULL, pbInput = ctx->pbCtr;
}
else {
pbInput = block;
}
if(encrypt || type.ctrMode) {
ret = BCryptEncrypt(ctx->hKey, pbInput, cbInput, NULL,
ctx->pbIV, ctx->dwIV, NULL, 0, &cbOutput, 0); ctx->pbIV, ctx->dwIV, NULL, 0, &cbOutput, 0);
} else { }
ret = BCryptDecrypt(ctx->hKey, block, cbInput, NULL, else {
ret = BCryptDecrypt(ctx->hKey, pbInput, cbInput, NULL,
ctx->pbIV, ctx->dwIV, NULL, 0, &cbOutput, 0); ctx->pbIV, ctx->dwIV, NULL, 0, &cbOutput, 0);
} }
if(BCRYPT_SUCCESS(ret)) { if(BCRYPT_SUCCESS(ret)) {
pbOutput = malloc(cbOutput); pbOutput = malloc(cbOutput);
if(pbOutput) { if(pbOutput) {
if (encrypt) { if(encrypt || type.ctrMode) {
ret = BCryptEncrypt(ctx->hKey, block, cbInput, NULL, ret = BCryptEncrypt(ctx->hKey, pbInput, cbInput, NULL,
ctx->pbIV, ctx->dwIV, ctx->pbIV, ctx->dwIV,
pbOutput, cbOutput, &cbOutput, 0); pbOutput, cbOutput, &cbOutput, 0);
} else { }
ret = BCryptDecrypt(ctx->hKey, block, cbInput, NULL, else {
ret = BCryptDecrypt(ctx->hKey, pbInput, cbInput, NULL,
ctx->pbIV, ctx->dwIV, ctx->pbIV, ctx->dwIV,
pbOutput, cbOutput, &cbOutput, 0); pbOutput, cbOutput, &cbOutput, 0);
} }
if(BCRYPT_SUCCESS(ret)) { if(BCRYPT_SUCCESS(ret)) {
if(type.ctrMode) {
_libssh2_xor_data(block, block, pbOutput, blocklen);
_libssh2_aes_ctr_increment(ctx->pbCtr, ctx->dwCtrLength);
}
else {
memcpy(block, pbOutput, cbOutput); memcpy(block, pbOutput, cbOutput);
} }
}
_libssh2_wincng_safe_free(pbOutput, cbOutput); _libssh2_wincng_safe_free(pbOutput, cbOutput);
} else }
else
ret = STATUS_NO_MEMORY; ret = STATUS_NO_MEMORY;
} }
@@ -1791,6 +1852,10 @@ _libssh2_wincng_cipher_dtor(_libssh2_cipher_ctx *ctx)
_libssh2_wincng_safe_free(ctx->pbIV, ctx->dwBlockLength); _libssh2_wincng_safe_free(ctx->pbIV, ctx->dwBlockLength);
ctx->pbIV = NULL; ctx->pbIV = NULL;
ctx->dwBlockLength = 0; ctx->dwBlockLength = 0;
_libssh2_wincng_safe_free(ctx->pbCtr, ctx->dwCtrLength);
ctx->pbCtr = NULL;
ctx->dwCtrLength = 0;
} }
@@ -1840,7 +1905,7 @@ _libssh2_wincng_bignum_resize(_libssh2_bn *bn, unsigned long length)
return 0; return 0;
} }
int static int
_libssh2_wincng_bignum_rand(_libssh2_bn *rnd, int bits, int top, int bottom) _libssh2_wincng_bignum_rand(_libssh2_bn *rnd, int bits, int top, int bottom)
{ {
unsigned char *bignum; unsigned char *bignum;
@@ -1877,12 +1942,11 @@ _libssh2_wincng_bignum_rand(_libssh2_bn *rnd, int bits, int top, int bottom)
return 0; return 0;
} }
int static int
_libssh2_wincng_bignum_mod_exp(_libssh2_bn *r, _libssh2_wincng_bignum_mod_exp(_libssh2_bn *r,
_libssh2_bn *a, _libssh2_bn *a,
_libssh2_bn *p, _libssh2_bn *p,
_libssh2_bn *m, _libssh2_bn *m)
_libssh2_bn_ctx *bnctx)
{ {
BCRYPT_KEY_HANDLE hKey; BCRYPT_KEY_HANDLE hKey;
BCRYPT_RSAKEY_BLOB *rsakey; BCRYPT_RSAKEY_BLOB *rsakey;
@@ -1890,8 +1954,6 @@ _libssh2_wincng_bignum_mod_exp(_libssh2_bn *r,
unsigned long keylen, offset, length; unsigned long keylen, offset, length;
int ret; int ret;
(void)bnctx;
if(!r || !a || !p || !m) if(!r || !a || !p || !m)
return -1; return -1;
@@ -1942,9 +2004,11 @@ _libssh2_wincng_bignum_mod_exp(_libssh2_bn *r,
if(BCRYPT_SUCCESS(ret)) { if(BCRYPT_SUCCESS(ret)) {
_libssh2_wincng_bignum_resize(r, offset); _libssh2_wincng_bignum_resize(r, offset);
} }
} else }
else
ret = STATUS_NO_MEMORY; ret = STATUS_NO_MEMORY;
} else }
else
ret = STATUS_NO_MEMORY; ret = STATUS_NO_MEMORY;
} }
@@ -2064,13 +2128,41 @@ _libssh2_wincng_bignum_free(_libssh2_bn *bn)
/* /*
* Windows CNG backend: other functions * Windows CNG backend: Diffie-Hellman support.
*/ */
void _libssh2_init_aes_ctr(void) void
_libssh2_dh_init(_libssh2_dh_ctx *dhctx)
{ {
/* no implementation */ *dhctx = _libssh2_wincng_bignum_init(); /* Random from client */
(void)0; }
int
_libssh2_dh_key_pair(_libssh2_dh_ctx *dhctx, _libssh2_bn *public,
_libssh2_bn *g, _libssh2_bn *p, int group_order)
{
/* Generate x and e */
if(_libssh2_wincng_bignum_rand(*dhctx, group_order * 8 - 1, 0, -1))
return -1;
if(_libssh2_wincng_bignum_mod_exp(public, g, *dhctx, p))
return -1;
return 0;
}
int
_libssh2_dh_secret(_libssh2_dh_ctx *dhctx, _libssh2_bn *secret,
_libssh2_bn *f, _libssh2_bn *p)
{
/* Compute the shared secret */
_libssh2_wincng_bignum_mod_exp(secret, f, *dhctx, p);
return 0;
}
void
_libssh2_dh_dtor(_libssh2_dh_ctx *dhctx)
{
_libssh2_wincng_bignum_free(*dhctx);
*dhctx = NULL;
} }
#endif /* LIBSSH2_WINCNG */ #endif /* LIBSSH2_WINCNG */

View File

@@ -55,7 +55,7 @@
#define LIBSSH2_HMAC_SHA512 1 #define LIBSSH2_HMAC_SHA512 1
#define LIBSSH2_AES 1 #define LIBSSH2_AES 1
#define LIBSSH2_AES_CTR 0 #define LIBSSH2_AES_CTR 1
#define LIBSSH2_BLOWFISH 0 #define LIBSSH2_BLOWFISH 0
#define LIBSSH2_RC4 1 #define LIBSSH2_RC4 1
#define LIBSSH2_CAST 0 #define LIBSSH2_CAST 0
@@ -63,12 +63,20 @@
#define LIBSSH2_RSA 1 #define LIBSSH2_RSA 1
#define LIBSSH2_DSA 1 #define LIBSSH2_DSA 1
#define LIBSSH2_ECDSA 0
#define LIBSSH2_ED25519 0
#define MD5_DIGEST_LENGTH 16 #define MD5_DIGEST_LENGTH 16
#define SHA_DIGEST_LENGTH 20 #define SHA_DIGEST_LENGTH 20
#define SHA256_DIGEST_LENGTH 32 #define SHA256_DIGEST_LENGTH 32
#define SHA512_DIGEST_LENGTH 64 #define SHA512_DIGEST_LENGTH 64
#define EC_MAX_POINT_LEN ((528 * 2 / 8) + 1)
#if LIBSSH2_ECDSA
#else
#define _libssh2_ec_key void
#endif
/*******************************************************************/ /*******************************************************************/
/* /*
@@ -88,6 +96,7 @@ struct _libssh2_wincng_ctx {
BCRYPT_ALG_HANDLE hAlgRSA; BCRYPT_ALG_HANDLE hAlgRSA;
BCRYPT_ALG_HANDLE hAlgDSA; BCRYPT_ALG_HANDLE hAlgDSA;
BCRYPT_ALG_HANDLE hAlgAES_CBC; BCRYPT_ALG_HANDLE hAlgAES_CBC;
BCRYPT_ALG_HANDLE hAlgAES_ECB;
BCRYPT_ALG_HANDLE hAlgRC4_NA; BCRYPT_ALG_HANDLE hAlgRC4_NA;
BCRYPT_ALG_HANDLE hAlg3DES_CBC; BCRYPT_ALG_HANDLE hAlg3DES_CBC;
}; };
@@ -285,9 +294,11 @@ struct _libssh2_wincng_cipher_ctx {
BCRYPT_KEY_HANDLE hKey; BCRYPT_KEY_HANDLE hKey;
unsigned char *pbKeyObject; unsigned char *pbKeyObject;
unsigned char *pbIV; unsigned char *pbIV;
unsigned char *pbCtr;
unsigned long dwKeyObject; unsigned long dwKeyObject;
unsigned long dwIV; unsigned long dwIV;
unsigned long dwBlockLength; unsigned long dwBlockLength;
unsigned long dwCtrLength;
}; };
#define _libssh2_cipher_ctx struct _libssh2_wincng_cipher_ctx #define _libssh2_cipher_ctx struct _libssh2_wincng_cipher_ctx
@@ -299,21 +310,21 @@ struct _libssh2_wincng_cipher_ctx {
struct _libssh2_wincng_cipher_type { struct _libssh2_wincng_cipher_type {
BCRYPT_ALG_HANDLE *phAlg; BCRYPT_ALG_HANDLE *phAlg;
unsigned long dwKeyLength; unsigned long dwKeyLength;
unsigned long dwUseIV; int useIV; /* TODO: Convert to bool when a C89 compatible bool type
is defined */
int ctrMode;
}; };
#define _libssh2_cipher_type(type) struct _libssh2_wincng_cipher_type type #define _libssh2_cipher_type(type) struct _libssh2_wincng_cipher_type type
#define _libssh2_cipher_aes256ctr { NULL, 32, 1 } /* not supported */ #define _libssh2_cipher_aes256ctr { &_libssh2_wincng.hAlgAES_ECB, 32, 0, 1 }
#define _libssh2_cipher_aes192ctr { NULL, 24, 1 } /* not supported */ #define _libssh2_cipher_aes192ctr { &_libssh2_wincng.hAlgAES_ECB, 24, 0, 1 }
#define _libssh2_cipher_aes128ctr { NULL, 16, 1 } /* not supported */ #define _libssh2_cipher_aes128ctr { &_libssh2_wincng.hAlgAES_ECB, 16, 0, 1 }
#define _libssh2_cipher_aes256 { &_libssh2_wincng.hAlgAES_CBC, 32, 1 } #define _libssh2_cipher_aes256 { &_libssh2_wincng.hAlgAES_CBC, 32, 1, 0 }
#define _libssh2_cipher_aes192 { &_libssh2_wincng.hAlgAES_CBC, 24, 1 } #define _libssh2_cipher_aes192 { &_libssh2_wincng.hAlgAES_CBC, 24, 1, 0 }
#define _libssh2_cipher_aes128 { &_libssh2_wincng.hAlgAES_CBC, 16, 1 } #define _libssh2_cipher_aes128 { &_libssh2_wincng.hAlgAES_CBC, 16, 1, 0 }
#define _libssh2_cipher_blowfish { NULL, 16, 0 } /* not supported */ #define _libssh2_cipher_arcfour { &_libssh2_wincng.hAlgRC4_NA, 16, 0, 0 }
#define _libssh2_cipher_arcfour { &_libssh2_wincng.hAlgRC4_NA, 16, 0 } #define _libssh2_cipher_3des { &_libssh2_wincng.hAlg3DES_CBC, 24, 1, 0 }
#define _libssh2_cipher_cast5 { NULL, 16, 0 } /* not supported */
#define _libssh2_cipher_3des { &_libssh2_wincng.hAlg3DES_CBC, 24, 1 }
/* /*
* Windows CNG backend: Cipher functions * Windows CNG backend: Cipher functions
@@ -358,10 +369,6 @@ _libssh2_bn *_libssh2_wincng_bignum_init(void);
_libssh2_wincng_bignum_init() _libssh2_wincng_bignum_init()
#define _libssh2_bn_init_from_bin() \ #define _libssh2_bn_init_from_bin() \
_libssh2_bn_init() _libssh2_bn_init()
#define _libssh2_bn_rand(bn, bits, top, bottom) \
_libssh2_wincng_bignum_rand(bn, bits, top, bottom)
#define _libssh2_bn_mod_exp(r, a, p, m, ctx) \
_libssh2_wincng_bignum_mod_exp(r, a, p, m, ctx)
#define _libssh2_bn_set_word(bn, word) \ #define _libssh2_bn_set_word(bn, word) \
_libssh2_wincng_bignum_set_word(bn, word) _libssh2_wincng_bignum_set_word(bn, word)
#define _libssh2_bn_from_bin(bn, len, bin) \ #define _libssh2_bn_from_bin(bn, len, bin) \
@@ -374,6 +381,18 @@ _libssh2_bn *_libssh2_wincng_bignum_init(void);
#define _libssh2_bn_free(bn) \ #define _libssh2_bn_free(bn) \
_libssh2_wincng_bignum_free(bn) _libssh2_wincng_bignum_free(bn)
/*
* Windows CNG backend: Diffie-Hellman support
*/
#define _libssh2_dh_ctx struct _libssh2_wincng_bignum *
#define libssh2_dh_init(dhctx) _libssh2_dh_init(dhctx)
#define libssh2_dh_key_pair(dhctx, public, g, p, group_order, bnctx) \
_libssh2_dh_key_pair(dhctx, public, g, p, group_order)
#define libssh2_dh_secret(dhctx, secret, f, p, bnctx) \
_libssh2_dh_secret(dhctx, secret, f, p)
#define libssh2_dh_dtor(dhctx) _libssh2_dh_dtor(dhctx)
/*******************************************************************/ /*******************************************************************/
/* /*
* Windows CNG backend: forward declarations * Windows CNG backend: forward declarations
@@ -381,7 +400,6 @@ _libssh2_bn *_libssh2_wincng_bignum_init(void);
void _libssh2_wincng_init(void); void _libssh2_wincng_init(void);
void _libssh2_wincng_free(void); void _libssh2_wincng_free(void);
int _libssh2_wincng_random(void *buf, int len); int _libssh2_wincng_random(void *buf, int len);
void _libssh2_init_aes_ctr(void);
int int
_libssh2_wincng_hash_init(_libssh2_wincng_hash_ctx *ctx, _libssh2_wincng_hash_init(_libssh2_wincng_hash_ctx *ctx,
@@ -531,14 +549,6 @@ _libssh2_wincng_cipher_dtor(_libssh2_cipher_ctx *ctx);
_libssh2_bn * _libssh2_bn *
_libssh2_wincng_bignum_init(void); _libssh2_wincng_bignum_init(void);
int int
_libssh2_wincng_bignum_rand(_libssh2_bn *rnd, int bits, int top, int bottom);
int
_libssh2_wincng_bignum_mod_exp(_libssh2_bn *r,
_libssh2_bn *a,
_libssh2_bn *p,
_libssh2_bn *m,
_libssh2_bn_ctx *bnctx);
int
_libssh2_wincng_bignum_set_word(_libssh2_bn *bn, unsigned long word); _libssh2_wincng_bignum_set_word(_libssh2_bn *bn, unsigned long word);
unsigned long unsigned long
_libssh2_wincng_bignum_bits(const _libssh2_bn *bn); _libssh2_wincng_bignum_bits(const _libssh2_bn *bn);
@@ -549,3 +559,13 @@ void
_libssh2_wincng_bignum_to_bin(const _libssh2_bn *bn, unsigned char *bin); _libssh2_wincng_bignum_to_bin(const _libssh2_bn *bn, unsigned char *bin);
void void
_libssh2_wincng_bignum_free(_libssh2_bn *bn); _libssh2_wincng_bignum_free(_libssh2_bn *bn);
extern void
_libssh2_dh_init(_libssh2_dh_ctx *dhctx);
extern int
_libssh2_dh_key_pair(_libssh2_dh_ctx *dhctx, _libssh2_bn *public,
_libssh2_bn *g, _libssh2_bn *p, int group_order);
extern int
_libssh2_dh_secret(_libssh2_dh_ctx *dhctx, _libssh2_bn *secret,
_libssh2_bn *f, _libssh2_bn *p);
extern void
_libssh2_dh_dtor(_libssh2_dh_ctx *dhctx);

View File

@@ -1,9 +1,9 @@
#! /bin/sh #! /bin/sh
# test-driver - basic testsuite driver script. # test-driver - basic testsuite driver script.
scriptversion=2012-06-27.10; # UTC scriptversion=2018-03-07.03; # UTC
# Copyright (C) 2011-2013 Free Software Foundation, Inc. # Copyright (C) 2011-2018 Free Software Foundation, Inc.
# #
# This program is free software; you can redistribute it and/or modify # This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by # it under the terms of the GNU General Public License as published by
@@ -16,7 +16,7 @@ scriptversion=2012-06-27.10; # UTC
# GNU General Public License for more details. # GNU General Public License for more details.
# #
# You should have received a copy of the GNU General Public License # You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>. # along with this program. If not, see <https://www.gnu.org/licenses/>.
# As a special exception to the GNU General Public License, if you # As a special exception to the GNU General Public License, if you
# distribute this file as part of a program that contains a # distribute this file as part of a program that contains a
@@ -44,13 +44,12 @@ print_usage ()
Usage: Usage:
test-driver --test-name=NAME --log-file=PATH --trs-file=PATH test-driver --test-name=NAME --log-file=PATH --trs-file=PATH
[--expect-failure={yes|no}] [--color-tests={yes|no}] [--expect-failure={yes|no}] [--color-tests={yes|no}]
[--enable-hard-errors={yes|no}] [--] TEST-SCRIPT [--enable-hard-errors={yes|no}] [--]
TEST-SCRIPT [TEST-SCRIPT-ARGUMENTS]
The '--test-name', '--log-file' and '--trs-file' options are mandatory. The '--test-name', '--log-file' and '--trs-file' options are mandatory.
END END
} }
# TODO: better error handling in option parsing (in particular, ensure
# TODO: $log_file, $trs_file and $test_name are defined).
test_name= # Used for reporting. test_name= # Used for reporting.
log_file= # Where to save the output of the test script. log_file= # Where to save the output of the test script.
trs_file= # Where to save the metadata of the test run. trs_file= # Where to save the metadata of the test run.
@@ -69,10 +68,23 @@ while test $# -gt 0; do
--enable-hard-errors) enable_hard_errors=$2; shift;; --enable-hard-errors) enable_hard_errors=$2; shift;;
--) shift; break;; --) shift; break;;
-*) usage_error "invalid option: '$1'";; -*) usage_error "invalid option: '$1'";;
*) break;;
esac esac
shift shift
done done
missing_opts=
test x"$test_name" = x && missing_opts="$missing_opts --test-name"
test x"$log_file" = x && missing_opts="$missing_opts --log-file"
test x"$trs_file" = x && missing_opts="$missing_opts --trs-file"
if test x"$missing_opts" != x; then
usage_error "the following mandatory options are missing:$missing_opts"
fi
if test $# -eq 0; then
usage_error "missing argument"
fi
if test $color_tests = yes; then if test $color_tests = yes; then
# Keep this in sync with 'lib/am/check.am:$(am__tty_colors)'. # Keep this in sync with 'lib/am/check.am:$(am__tty_colors)'.
red='' # Red. red='' # Red.
@@ -94,11 +106,14 @@ trap "st=143; $do_exit" 15
# Test script is run here. # Test script is run here.
"$@" >$log_file 2>&1 "$@" >$log_file 2>&1
estatus=$? estatus=$?
if test $enable_hard_errors = no && test $estatus -eq 99; then if test $enable_hard_errors = no && test $estatus -eq 99; then
estatus=1 tweaked_estatus=1
else
tweaked_estatus=$estatus
fi fi
case $estatus:$expect_failure in case $tweaked_estatus:$expect_failure in
0:yes) col=$red res=XPASS recheck=yes gcopy=yes;; 0:yes) col=$red res=XPASS recheck=yes gcopy=yes;;
0:*) col=$grn res=PASS recheck=no gcopy=no;; 0:*) col=$grn res=PASS recheck=no gcopy=no;;
77:*) col=$blu res=SKIP recheck=no gcopy=yes;; 77:*) col=$blu res=SKIP recheck=no gcopy=yes;;
@@ -107,6 +122,12 @@ case $estatus:$expect_failure in
*:*) col=$red res=FAIL recheck=yes gcopy=yes;; *:*) col=$red res=FAIL recheck=yes gcopy=yes;;
esac esac
# Report the test outcome and exit status in the logs, so that one can
# know whether the test passed or failed simply by looking at the '.log'
# file, without the need of also peaking into the corresponding '.trs'
# file (automake bug#11814).
echo "$res $test_name (exit status: $estatus)" >>$log_file
# Report outcome to console. # Report outcome to console.
echo "${col}${res}${std}: $test_name" echo "${col}${res}${std}: $test_name"
@@ -119,9 +140,9 @@ echo ":copy-in-global-log: $gcopy" >> $trs_file
# Local Variables: # Local Variables:
# mode: shell-script # mode: shell-script
# sh-indentation: 2 # sh-indentation: 2
# eval: (add-hook 'write-file-hooks 'time-stamp) # eval: (add-hook 'before-save-hook 'time-stamp)
# time-stamp-start: "scriptversion=" # time-stamp-start: "scriptversion="
# time-stamp-format: "%:y-%02m-%02d.%02H" # time-stamp-format: "%:y-%02m-%02d.%02H"
# time-stamp-time-zone: "UTC" # time-stamp-time-zone: "UTC0"
# time-stamp-end: "; # UTC" # time-stamp-end: "; # UTC"
# End: # End:

View File

@@ -86,11 +86,26 @@ CAT = type
ECHONL = $(ComSpec) /c echo. ECHONL = $(ComSpec) /c echo.
endif endif
ifeq ($(LIBSSH2_CC),)
LIBSSH2_CC := $(CROSSPREFIX)gcc
endif
ifeq ($(LIBSSH2_AR),)
LIBSSH2_AR := $(CROSSPREFIX)ar
endif
ifeq ($(LIBSSH2_RANLIB),)
LIBSSH2_RANLIB := $(CROSSPREFIX)ranlib
endif
ifeq ($(LIBSSH2_DLL_A_SUFFIX),)
LIBSSH2_DLL_A_SUFFIX := dll
endif
libssh2_dll_LIBRARY = $(TARGET)$(LIBSSH2_DLL_SUFFIX).dll
# The following line defines your compiler. # The following line defines your compiler.
ifdef METROWERKS ifdef METROWERKS
CC = mwcc CC = mwcc
else else
CC = $(CROSSPREFIX)gcc CC = $(LIBSSH2_CC)
endif endif
# Set environment var ARCH to your architecture to override autodetection. # Set environment var ARCH to your architecture to override autodetection.
@@ -110,7 +125,7 @@ endif
-include $(OBJDIR)/version.inc -include $(OBJDIR)/version.inc
# Global flags for all compilers # Global flags for all compilers
CFLAGS = $(LIBSSH2_CFLAG_EXTRAS) $(OPT) -D$(DB) -DLIBSSH2_WIN32 # -DHAVE_CONFIG_H CFLAGS = $(LIBSSH2_CFLAG_EXTRAS) $(OPT) -D$(DB) -DLIBSSH2_WIN32 -DHAVE_WINDOWS_H # -DHAVE_CONFIG_H
LDFLAGS = $(LIBSSH2_LDFLAG_EXTRAS) LDFLAGS = $(LIBSSH2_LDFLAG_EXTRAS)
ifeq ($(CC),mwcc) ifeq ($(CC),mwcc)
@@ -128,13 +143,13 @@ CFLAGS += -nostdinc -gccinc -msgstyle gcc -inline off -opt nointrinsics -proc 58
CFLAGS += -ir "$(METROWERKS)/MSL" -ir "$(METROWERKS)/Win32-x86 Support" CFLAGS += -ir "$(METROWERKS)/MSL" -ir "$(METROWERKS)/Win32-x86 Support"
CFLAGS += -w on,nounused,nounusedexpr # -ansi strict CFLAGS += -w on,nounused,nounusedexpr # -ansi strict
else else
LD = $(CROSSPREFIX)gcc
RC = $(CROSSPREFIX)windres
LDFLAGS += -s -shared -Wl,--output-def,$(TARGET).def,--out-implib,$(TARGET)dll.a
AR = $(CROSSPREFIX)ar
ARFLAGS = -cq
LIBEXT = a LIBEXT = a
RANLIB = $(CROSSPREFIX)ranlib LD = $(LIBSSH2_CC)
RC = $(CROSSPREFIX)windres
LDFLAGS += -s -shared -Wl,--output-def,$(libssh2_dll_LIBRARY:.dll=.def),--out-implib,$(TARGET)$(LIBSSH2_DLL_A_SUFFIX).$(LIBEXT)
AR = $(LIBSSH2_AR)
ARFLAGS = cru
RANLIB = $(LIBSSH2_RANLIB)
RCFLAGS = -I $(PROOT)/include -O coff RCFLAGS = -I $(PROOT)/include -O coff
CFLAGS += -fno-builtin CFLAGS += -fno-builtin
CFLAGS += -fno-strict-aliasing CFLAGS += -fno-strict-aliasing
@@ -223,7 +238,7 @@ OBJL = $(OBJS) $(OBJDIR)/$(TARGET).res
all: lib dll all: lib dll
dll: prebuild $(TARGET).dll dll: prebuild $(libssh2_dll_LIBRARY)
lib: prebuild $(TARGET).$(LIBEXT) lib: prebuild $(TARGET).$(LIBEXT)
@@ -248,7 +263,7 @@ dist: all $(DISTDIR) $(DISTDIR)/readme.txt
@$(call COPY, $(PROOT)/INSTALL, $(DISTDIR)) @$(call COPY, $(PROOT)/INSTALL, $(DISTDIR))
@$(call COPY, $(PROOT)/README, $(DISTDIR)) @$(call COPY, $(PROOT)/README, $(DISTDIR))
@$(call COPY, $(PROOT)/RELEASE-NOTES, $(DISTDIR)) @$(call COPY, $(PROOT)/RELEASE-NOTES, $(DISTDIR))
@$(call COPY, $(TARGET).dll, $(DISTDIR)/bin) @$(call COPY, $(libssh2_dll_LIBRARY), $(DISTDIR)/bin)
@echo Creating $(DISTARC) @echo Creating $(DISTARC)
@$(ZIP) $(DISTARC) $(DISTDIR)/* < $(DISTDIR)/readme.txt @$(ZIP) $(DISTARC) $(DISTDIR)/* < $(DISTDIR)/readme.txt
@@ -261,7 +276,7 @@ dev: all $(DEVLDIR) $(DEVLDIR)/readme.txt
@$(call COPY, $(PROOT)/INSTALL, $(DEVLDIR)) @$(call COPY, $(PROOT)/INSTALL, $(DEVLDIR))
@$(call COPY, $(PROOT)/README, $(DEVLDIR)) @$(call COPY, $(PROOT)/README, $(DEVLDIR))
@$(call COPY, $(PROOT)/RELEASE-NOTES, $(DEVLDIR)) @$(call COPY, $(PROOT)/RELEASE-NOTES, $(DEVLDIR))
@$(call COPY, $(TARGET).dll, $(DEVLDIR)/bin) @$(call COPY, $(libssh2_dll_LIBRARY), $(DEVLDIR)/bin)
@$(call COPY, $(PROOT)/include/*.h, $(DEVLDIR)/include) @$(call COPY, $(PROOT)/include/*.h, $(DEVLDIR)/include)
@$(call COPY, libssh2_config.h, $(DEVLDIR)/include) @$(call COPY, libssh2_config.h, $(DEVLDIR)/include)
@$(call COPY, *.$(LIBEXT), $(DEVLDIR)/win32) @$(call COPY, *.$(LIBEXT), $(DEVLDIR)/win32)
@@ -284,7 +299,7 @@ testclean: clean
clean: clean:
# $(call DEL, libssh2_config.h) # $(call DEL, libssh2_config.h)
$(call DEL, $(TARGET).dll $(TARGET).def $(TARGET).$(LIBEXT) $(TARGET)dll.$(LIBEXT)) $(call DEL, $(libssh2_dll_LIBRARY) $(libssh2_dll_LIBRARY:.dll=.def) $(TARGET).$(LIBEXT) $(TARGET)$(LIBSSH2_DLL_A_SUFFIX).$(LIBEXT))
$(call RMDIR, $(OBJDIR)) $(call RMDIR, $(OBJDIR))
$(OBJDIR): $(OBJDIR):
@@ -304,7 +319,7 @@ ifdef RANLIB
@$(RANLIB) $@ @$(RANLIB) $@
endif endif
$(TARGET).dll $(TARGET)dll.a: $(OBJL) $(libssh2_dll_LIBRARY) $(TARGET)$(LIBSSH2_DLL_A_SUFFIX).$(LIBEXT): $(OBJL)
@echo Linking $@ @echo Linking $@
@$(call DEL, $@) @$(call DEL, $@)
@$(LD) $(LDFLAGS) $^ -o $@ $(LIBPATH) $(LDLIBS) @$(LD) $(LDFLAGS) $^ -o $@ $(LIBPATH) $(LDLIBS)

View File

@@ -263,6 +263,14 @@ SOURCE=..\src\agent.c
# End Source File # End Source File
# Begin Source File # Begin Source File
SOURCE=..\src\bcrypt_pbkdf.c
# End Source File
# Begin Source File
SOURCE=..\src\blowfish.c
# End Source File
# Begin Source File
SOURCE=..\src\channel.c SOURCE=..\src\channel.c
# End Source File # End Source File
# Begin Source File # Begin Source File
@@ -355,6 +363,10 @@ SOURCE=..\src\wincng.c
# PROP Default_Filter "h;hpp;hxx" # PROP Default_Filter "h;hpp;hxx"
# Begin Source File # Begin Source File
SOURCE=..\src\blf.h
# End Source File
# Begin Source File
SOURCE=..\src\channel.h SOURCE=..\src\channel.h
# End Source File # End Source File
# Begin Source File # Begin Source File

View File

@@ -140,6 +140,8 @@
</ItemDefinitionGroup> </ItemDefinitionGroup>
<ItemGroup> <ItemGroup>
<ClCompile Include="..\src\agent.c" /> <ClCompile Include="..\src\agent.c" />
<ClCompile Include="..\src\bcrypt_pbkdf.c" />
<ClCompile Include="..\src\blowfish.c" />
<ClCompile Include="..\src\channel.c" /> <ClCompile Include="..\src\channel.c" />
<ClCompile Include="..\src\comp.c" /> <ClCompile Include="..\src\comp.c" />
<ClCompile Include="..\src\crypt.c" /> <ClCompile Include="..\src\crypt.c" />
@@ -163,6 +165,7 @@
<ClCompile Include="..\src\wincng.c" /> <ClCompile Include="..\src\wincng.c" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<ClInclude Include="..\src\blf.h" />
<ClInclude Include="..\src\channel.h" /> <ClInclude Include="..\src\channel.h" />
<ClInclude Include="..\src\comp.h" /> <ClInclude Include="..\src\comp.h" />
<ClInclude Include="..\src\crypto.h" /> <ClInclude Include="..\src\crypto.h" />