1
0
mirror of https://github.com/nmap/nmap.git synced 2025-12-15 04:09:01 +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>
])
if test "$ac_cv_libmbedtls" = "yes"; then LDFLAGS="$libssh2_save_LDFLAGS"
AC_DEFINE(LIBSSH2_MBEDTLS, 1, [Use mbedtls])
LIBSREQUIRED= # mbedtls doesn't provide a .pc file if test "$ac_cv_lib$1" = "yes"; then :
LIBS="$LIBS -lmbedtls -lmbedcrypto" $4
found_crypto=libmbedtls else
CPPFLAGS="$libssh2_save_CPPFLAGS"
fi
])
AC_DEFUN([LIBSSH2_CHECK_CRYPTO], [
if test "$use_crypto" = "auto" && test "$found_crypto" = "none" || test "$use_crypto" = "$1"; then
m4_case([$1],
[openssl], [
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], [
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 [wincng], [
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>
])
AC_CHECK_DECLS([SecureZeroMemory], [], [], [
#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"
]) ])
],
)
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
]) ])

912
libssh2/config.guess vendored

File diff suppressed because it is too large Load Diff

416
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)
@@ -861,7 +895,7 @@ case $basic_machine in
basic_machine=v70-nec basic_machine=v70-nec
os=-sysv os=-sysv
;; ;;
next | m*-next ) next | m*-next)
basic_machine=m68k-next basic_machine=m68k-next
case $os in case $os in
-nextstep* ) -nextstep* )
@@ -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
;; ;;
@@ -1437,7 +1459,7 @@ case $os in
-nova*) -nova*)
os=-rtmk-nova os=-rtmk-nova
;; ;;
-ns2 ) -ns2)
os=-nextstep2 os=-nextstep2
;; ;;
-nsk*) -nsk*)
@@ -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
;; ;;
@@ -1631,7 +1662,7 @@ case $basic_machine in
m88k-omron*) m88k-omron*)
os=-luna os=-luna
;; ;;
*-next ) *-next)
os=-nextstep os=-nextstep
;; ;;
*-sequent) *-sequent)
@@ -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: "'"

3732
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
@@ -259,14 +270,14 @@ typedef off_t libssh2_struct_stat_size;
typedef struct _LIBSSH2_USERAUTH_KBDINT_PROMPT typedef struct _LIBSSH2_USERAUTH_KBDINT_PROMPT
{ {
char* text; char *text;
unsigned int length; unsigned int length;
unsigned char echo; unsigned char echo;
} LIBSSH2_USERAUTH_KBDINT_PROMPT; } LIBSSH2_USERAUTH_KBDINT_PROMPT;
typedef struct _LIBSSH2_USERAUTH_KBDINT_RESPONSE typedef struct _LIBSSH2_USERAUTH_KBDINT_RESPONSE
{ {
char* text; char *text;
unsigned int length; unsigned int length;
} LIBSSH2_USERAUTH_KBDINT_RESPONSE; } LIBSSH2_USERAUTH_KBDINT_RESPONSE;
@@ -277,10 +288,10 @@ typedef struct _LIBSSH2_USERAUTH_KBDINT_RESPONSE
/* 'keyboard-interactive' authentication callback */ /* 'keyboard-interactive' authentication callback */
#define LIBSSH2_USERAUTH_KBDINT_RESPONSE_FUNC(name_) \ #define LIBSSH2_USERAUTH_KBDINT_RESPONSE_FUNC(name_) \
void name_(const char* name, int name_len, const char* instruction, \ void name_(const char *name, int name_len, const char *instruction, \
int instruction_len, int num_prompts, \ int instruction_len, int num_prompts, \
const LIBSSH2_USERAUTH_KBDINT_PROMPT* prompts, \ const LIBSSH2_USERAUTH_KBDINT_PROMPT *prompts, \
LIBSSH2_USERAUTH_KBDINT_RESPONSE* responses, void **abstract) LIBSSH2_USERAUTH_KBDINT_RESPONSE *responses, void **abstract)
/* Callbacks for special SSH packets */ /* Callbacks for special SSH packets */
#define LIBSSH2_IGNORE_FUNC(name) \ #define LIBSSH2_IGNORE_FUNC(name) \
@@ -314,11 +325,13 @@ 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) \
const void *buffer, size_t length,\ ssize_t name(libssh2_socket_t socket, \
const void *buffer, size_t length, \
int flags, void **abstract) int flags, void **abstract)
/* libssh2_session_callback_set() constants */ /* libssh2_session_callback_set() constants */
@@ -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
@@ -531,7 +552,7 @@ LIBSSH2_API void libssh2_free(LIBSSH2_SESSION *session, void *ptr);
*/ */
LIBSSH2_API int libssh2_session_supported_algs(LIBSSH2_SESSION* session, LIBSSH2_API int libssh2_session_supported_algs(LIBSSH2_SESSION* session,
int method_type, int method_type,
const char*** algs); const char ***algs);
/* Session API */ /* Session API */
LIBSSH2_API LIBSSH2_SESSION * LIBSSH2_API LIBSSH2_SESSION *
@@ -579,7 +600,7 @@ LIBSSH2_API int libssh2_session_last_error(LIBSSH2_SESSION *session,
LIBSSH2_API int libssh2_session_last_errno(LIBSSH2_SESSION *session); LIBSSH2_API int libssh2_session_last_errno(LIBSSH2_SESSION *session);
LIBSSH2_API int libssh2_session_set_last_error(LIBSSH2_SESSION* session, LIBSSH2_API int libssh2_session_set_last_error(LIBSSH2_SESSION* session,
int errcode, int errcode,
const char* errmsg); const char *errmsg);
LIBSSH2_API int libssh2_session_block_directions(LIBSSH2_SESSION *session); LIBSSH2_API int libssh2_session_block_directions(LIBSSH2_SESSION *session);
LIBSSH2_API int libssh2_session_flag(LIBSSH2_SESSION *session, int flag, LIBSSH2_API int libssh2_session_flag(LIBSSH2_SESSION *session, int flag,
@@ -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,15 +772,17 @@ 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,
int width_px, int width_px,
int height_px); int height_px);
#define libssh2_channel_request_pty_size(channel, width, height) \ #define libssh2_channel_request_pty_size(channel, width, height) \
libssh2_channel_request_pty_size_ex( (channel), (width), (height), 0, 0) libssh2_channel_request_pty_size_ex((channel), (width), (height), 0, 0)
LIBSSH2_API int libssh2_channel_x11_req_ex(LIBSSH2_CHANNEL *channel, LIBSSH2_API int libssh2_channel_x11_req_ex(LIBSSH2_CHANNEL *channel,
int single_connection, int single_connection,
@@ -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,
@@ -855,7 +883,7 @@ LIBSSH2_API int libssh2_channel_handle_extended_data2(LIBSSH2_CHANNEL *channel,
libssh2_channel_handle_extended_data((channel), \ libssh2_channel_handle_extended_data((channel), \
(ignore) ? \ (ignore) ? \
LIBSSH2_CHANNEL_EXTENDED_DATA_IGNORE : \ LIBSSH2_CHANNEL_EXTENDED_DATA_IGNORE : \
LIBSSH2_CHANNEL_EXTENDED_DATA_NORMAL ) LIBSSH2_CHANNEL_EXTENDED_DATA_NORMAL)
#define LIBSSH2_CHANNEL_FLUSH_EXTENDED_DATA -1 #define LIBSSH2_CHANNEL_FLUSH_EXTENDED_DATA -1
#define LIBSSH2_CHANNEL_FLUSH_ALL -2 #define LIBSSH2_CHANNEL_FLUSH_ALL -2
@@ -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()
@@ -1247,7 +1297,7 @@ libssh2_agent_free(LIBSSH2_AGENT *agent);
* Note that non-blocking applications are responsible for sending the * Note that non-blocking applications are responsible for sending the
* keepalive messages using libssh2_keepalive_send(). * keepalive messages using libssh2_keepalive_send().
*/ */
LIBSSH2_API void libssh2_keepalive_config (LIBSSH2_SESSION *session, LIBSSH2_API void libssh2_keepalive_config(LIBSSH2_SESSION *session,
int want_reply, int want_reply,
unsigned interval); unsigned interval);
@@ -1259,7 +1309,7 @@ LIBSSH2_API void libssh2_keepalive_config (LIBSSH2_SESSION *session,
* it again. Returns 0 on success, or LIBSSH2_ERROR_SOCKET_SEND on * it again. Returns 0 on success, or LIBSSH2_ERROR_SOCKET_SEND on
* I/O errors. * I/O errors.
*/ */
LIBSSH2_API int libssh2_keepalive_send (LIBSSH2_SESSION *session, LIBSSH2_API int libssh2_keepalive_send(LIBSSH2_SESSION *session,
int *seconds_to_next); int *seconds_to_next);
/* NOTE NOTE NOTE /* NOTE NOTE NOTE
@@ -1278,11 +1328,11 @@ LIBSSH2_API int libssh2_trace(LIBSSH2_SESSION *session, int bitmask);
#define LIBSSH2_TRACE_SOCKET (1<<9) #define LIBSSH2_TRACE_SOCKET (1<<9)
typedef void (*libssh2_trace_handler_func)(LIBSSH2_SESSION*, typedef void (*libssh2_trace_handler_func)(LIBSSH2_SESSION*,
void*, void *,
const char *, const char *,
size_t); size_t);
LIBSSH2_API int libssh2_trace_sethandler(LIBSSH2_SESSION *session, LIBSSH2_API int libssh2_trace_sethandler(LIBSSH2_SESSION *session,
void* context, void *context,
libssh2_trace_handler_func callback); libssh2_trace_handler_func callback);
#ifdef __cplusplus #ifdef __cplusplus

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,108 +95,168 @@ In the 2nd and 3rd, copy all SRCFILES to DIRECTORY.
In the 4th, create DIRECTORIES. In the 4th, create DIRECTORIES.
Options: Options:
-c (ignored) --help display this help and exit.
-d create directories instead of installing files. --version display version info and exit.
-g GROUP $chgrpprog installed files to GROUP.
-m MODE $chmodprog installed files to MODE. -c (ignored)
-o USER $chownprog installed files to USER. -C install only if different (preserve the last data modification time)
-s $stripprog installed files. -d create directories instead of installing files.
-t DIRECTORY install into DIRECTORY. -g GROUP $chgrpprog installed files to GROUP.
-T report an error if DSTFILE is a directory. -m MODE $chmodprog installed files to MODE.
--help display this help and exit. -o USER $chownprog installed files to USER.
--version display version info and exit. -s $stripprog installed files.
-t DIRECTORY install into DIRECTORY.
-T report an error if DSTFILE is a directory.
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,22 +149,25 @@ 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)
return _libssh2_error(agent->session, LIBSSH2_ERROR_BAD_SOCKET, return _libssh2_error(agent->session, LIBSSH2_ERROR_BAD_SOCKET,
"failed creating socket"); "failed creating socket");
s_un.sun_family = AF_UNIX; s_un.sun_family = AF_UNIX;
strncpy (s_un.sun_path, path, sizeof s_un.sun_path); strncpy(s_un.sun_path, path, sizeof s_un.sun_path);
s_un.sun_path[sizeof(s_un.sun_path)-1]=0; /* make sure there's a trailing s_un.sun_path[sizeof(s_un.sun_path)-1] = 0; /* make sure there's a trailing
zero */ zero */
if (connect(agent->fd, (struct sockaddr*)(&s_un), sizeof s_un) != 0) { if(connect(agent->fd, (struct sockaddr*)(&s_un), sizeof s_un) != 0) {
close (agent->fd); close(agent->fd);
return _libssh2_error(agent->session, LIBSSH2_ERROR_AGENT_PROTOCOL, return _libssh2_error(agent->session, LIBSSH2_ERROR_AGENT_PROTOCOL,
"failed connecting with agent"); "failed connecting with agent");
} }
@@ -177,34 +182,34 @@ agent_transact_unix(LIBSSH2_AGENT *agent, agent_transaction_ctx_t transctx)
int rc; int rc;
/* Send the length of the request */ /* Send the length of the request */
if (transctx->state == agent_NB_state_request_created) { if(transctx->state == agent_NB_state_request_created) {
_libssh2_htonu32(buf, transctx->request_len); _libssh2_htonu32(buf, transctx->request_len);
rc = LIBSSH2_SEND_FD(agent->session, agent->fd, buf, sizeof buf, 0); rc = LIBSSH2_SEND_FD(agent->session, agent->fd, buf, sizeof buf, 0);
if (rc == -EAGAIN) if(rc == -EAGAIN)
return LIBSSH2_ERROR_EAGAIN; return LIBSSH2_ERROR_EAGAIN;
else if (rc < 0) else if(rc < 0)
return _libssh2_error(agent->session, LIBSSH2_ERROR_SOCKET_SEND, return _libssh2_error(agent->session, LIBSSH2_ERROR_SOCKET_SEND,
"agent send failed"); "agent send failed");
transctx->state = agent_NB_state_request_length_sent; transctx->state = agent_NB_state_request_length_sent;
} }
/* Send the request body */ /* Send the request body */
if (transctx->state == agent_NB_state_request_length_sent) { if(transctx->state == agent_NB_state_request_length_sent) {
rc = LIBSSH2_SEND_FD(agent->session, agent->fd, transctx->request, rc = LIBSSH2_SEND_FD(agent->session, agent->fd, transctx->request,
transctx->request_len, 0); transctx->request_len, 0);
if (rc == -EAGAIN) if(rc == -EAGAIN)
return LIBSSH2_ERROR_EAGAIN; return LIBSSH2_ERROR_EAGAIN;
else if (rc < 0) else if(rc < 0)
return _libssh2_error(agent->session, LIBSSH2_ERROR_SOCKET_SEND, return _libssh2_error(agent->session, LIBSSH2_ERROR_SOCKET_SEND,
"agent send failed"); "agent send failed");
transctx->state = agent_NB_state_request_sent; transctx->state = agent_NB_state_request_sent;
} }
/* Receive the length of a response */ /* Receive the length of a response */
if (transctx->state == agent_NB_state_request_sent) { if(transctx->state == agent_NB_state_request_sent) {
rc = LIBSSH2_RECV_FD(agent->session, agent->fd, buf, sizeof buf, 0); rc = LIBSSH2_RECV_FD(agent->session, agent->fd, buf, sizeof buf, 0);
if (rc < 0) { if(rc < 0) {
if (rc == -EAGAIN) if(rc == -EAGAIN)
return LIBSSH2_ERROR_EAGAIN; return LIBSSH2_ERROR_EAGAIN;
return _libssh2_error(agent->session, LIBSSH2_ERROR_SOCKET_RECV, return _libssh2_error(agent->session, LIBSSH2_ERROR_SOCKET_RECV,
"agent recv failed"); "agent recv failed");
@@ -212,18 +217,18 @@ agent_transact_unix(LIBSSH2_AGENT *agent, agent_transaction_ctx_t transctx)
transctx->response_len = _libssh2_ntohu32(buf); transctx->response_len = _libssh2_ntohu32(buf);
transctx->response = LIBSSH2_ALLOC(agent->session, transctx->response = LIBSSH2_ALLOC(agent->session,
transctx->response_len); transctx->response_len);
if (!transctx->response) if(!transctx->response)
return LIBSSH2_ERROR_ALLOC; return LIBSSH2_ERROR_ALLOC;
transctx->state = agent_NB_state_response_length_received; transctx->state = agent_NB_state_response_length_received;
} }
/* Receive the response body */ /* Receive the response body */
if (transctx->state == agent_NB_state_response_length_received) { if(transctx->state == agent_NB_state_response_length_received) {
rc = LIBSSH2_RECV_FD(agent->session, agent->fd, transctx->response, rc = LIBSSH2_RECV_FD(agent->session, agent->fd, transctx->response,
transctx->response_len, 0); transctx->response_len, 0);
if (rc < 0) { if(rc < 0) {
if (rc == -EAGAIN) if(rc == -EAGAIN)
return LIBSSH2_ERROR_EAGAIN; return LIBSSH2_ERROR_EAGAIN;
return _libssh2_error(agent->session, LIBSSH2_ERROR_SOCKET_SEND, return _libssh2_error(agent->session, LIBSSH2_ERROR_SOCKET_SEND,
"agent recv failed"); "agent recv failed");
@@ -270,7 +275,7 @@ agent_connect_pageant(LIBSSH2_AGENT *agent)
{ {
HWND hwnd; HWND hwnd;
hwnd = FindWindow("Pageant", "Pageant"); hwnd = FindWindow("Pageant", "Pageant");
if (!hwnd) if(!hwnd)
return _libssh2_error(agent->session, LIBSSH2_ERROR_AGENT_PROTOCOL, return _libssh2_error(agent->session, LIBSSH2_ERROR_AGENT_PROTOCOL,
"failed connecting agent"); "failed connecting agent");
agent->fd = 0; /* Mark as the connection has been established */ agent->fd = 0; /* Mark as the connection has been established */
@@ -288,25 +293,26 @@ agent_transact_pageant(LIBSSH2_AGENT *agent, agent_transaction_ctx_t transctx)
int id; int id;
COPYDATASTRUCT cds; COPYDATASTRUCT cds;
if (!transctx || 4 + transctx->request_len > PAGEANT_MAX_MSGLEN) if(!transctx || 4 + transctx->request_len > PAGEANT_MAX_MSGLEN)
return _libssh2_error(agent->session, LIBSSH2_ERROR_INVAL, return _libssh2_error(agent->session, LIBSSH2_ERROR_INVAL,
"illegal input"); "illegal input");
hwnd = FindWindow("Pageant", "Pageant"); hwnd = FindWindow("Pageant", "Pageant");
if (!hwnd) if(!hwnd)
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);
if (filemap == NULL || filemap == INVALID_HANDLE_VALUE) if(filemap == NULL || filemap == INVALID_HANDLE_VALUE)
return _libssh2_error(agent->session, LIBSSH2_ERROR_AGENT_PROTOCOL, return _libssh2_error(agent->session, LIBSSH2_ERROR_AGENT_PROTOCOL,
"failed setting up pageant filemap"); "failed setting up pageant filemap");
p2 = p = MapViewOfFile(filemap, FILE_MAP_WRITE, 0, 0, 0); p2 = p = MapViewOfFile(filemap, FILE_MAP_WRITE, 0, 0, 0);
if (p == NULL || p2 == NULL) { if(p == NULL || p2 == NULL) {
CloseHandle(filemap); CloseHandle(filemap);
return _libssh2_error(agent->session, LIBSSH2_ERROR_AGENT_PROTOCOL, return _libssh2_error(agent->session, LIBSSH2_ERROR_AGENT_PROTOCOL,
"failed to open pageant filemap for writing"); "failed to open pageant filemap for writing");
@@ -320,9 +326,9 @@ agent_transact_pageant(LIBSSH2_AGENT *agent, agent_transaction_ctx_t transctx)
cds.lpData = mapname; cds.lpData = mapname;
id = SendMessage(hwnd, WM_COPYDATA, (WPARAM) NULL, (LPARAM) &cds); id = SendMessage(hwnd, WM_COPYDATA, (WPARAM) NULL, (LPARAM) &cds);
if (id > 0) { if(id > 0) {
transctx->response_len = _libssh2_ntohu32(p); transctx->response_len = _libssh2_ntohu32(p);
if (transctx->response_len > PAGEANT_MAX_MSGLEN) { if(transctx->response_len > PAGEANT_MAX_MSGLEN) {
UnmapViewOfFile(p); UnmapViewOfFile(p);
CloseHandle(filemap); CloseHandle(filemap);
return _libssh2_error(agent->session, LIBSSH2_ERROR_AGENT_PROTOCOL, return _libssh2_error(agent->session, LIBSSH2_ERROR_AGENT_PROTOCOL,
@@ -330,7 +336,7 @@ agent_transact_pageant(LIBSSH2_AGENT *agent, agent_transaction_ctx_t transctx)
} }
transctx->response = LIBSSH2_ALLOC(agent->session, transctx->response = LIBSSH2_ALLOC(agent->session,
transctx->response_len); transctx->response_len);
if (!transctx->response) { if(!transctx->response) {
UnmapViewOfFile(p); UnmapViewOfFile(p);
CloseHandle(filemap); CloseHandle(filemap);
return _libssh2_error(agent->session, LIBSSH2_ERROR_ALLOC, return _libssh2_error(agent->session, LIBSSH2_ERROR_ALLOC,
@@ -384,9 +390,9 @@ agent_sign(LIBSSH2_SESSION *session, unsigned char **sig, size_t *sig_len,
int rc; int rc;
/* Create a request to sign the data */ /* Create a request to sign the data */
if (transctx->state == agent_NB_state_init) { if(transctx->state == agent_NB_state_init) {
s = transctx->request = LIBSSH2_ALLOC(session, len); s = transctx->request = LIBSSH2_ALLOC(session, len);
if (!transctx->request) if(!transctx->request)
return _libssh2_error(session, LIBSSH2_ERROR_ALLOC, return _libssh2_error(session, LIBSSH2_ERROR_ALLOC,
"out of memory"); "out of memory");
@@ -405,17 +411,17 @@ agent_sign(LIBSSH2_SESSION *session, unsigned char **sig, size_t *sig_len,
} }
/* Make sure to be re-called as a result of EAGAIN. */ /* Make sure to be re-called as a result of EAGAIN. */
if (*transctx->request != SSH2_AGENTC_SIGN_REQUEST) if(*transctx->request != SSH2_AGENTC_SIGN_REQUEST)
return _libssh2_error(session, LIBSSH2_ERROR_BAD_USE, return _libssh2_error(session, LIBSSH2_ERROR_BAD_USE,
"illegal request"); "illegal request");
if (!agent->ops) if(!agent->ops)
/* if no agent has been connected, bail out */ /* if no agent has been connected, bail out */
return _libssh2_error(session, LIBSSH2_ERROR_BAD_USE, return _libssh2_error(session, LIBSSH2_ERROR_BAD_USE,
"agent not connected"); "agent not connected");
rc = agent->ops->transact(agent, transctx); rc = agent->ops->transact(agent, transctx);
if (rc) { if(rc) {
goto error; goto error;
} }
LIBSSH2_FREE(session, transctx->request); LIBSSH2_FREE(session, transctx->request);
@@ -424,11 +430,11 @@ agent_sign(LIBSSH2_SESSION *session, unsigned char **sig, size_t *sig_len,
len = transctx->response_len; len = transctx->response_len;
s = transctx->response; s = transctx->response;
len--; len--;
if (len < 0) { if(len < 0) {
rc = LIBSSH2_ERROR_AGENT_PROTOCOL; rc = LIBSSH2_ERROR_AGENT_PROTOCOL;
goto error; goto error;
} }
if (*s != SSH2_AGENT_SIGN_RESPONSE) { if(*s != SSH2_AGENT_SIGN_RESPONSE) {
rc = LIBSSH2_ERROR_AGENT_PROTOCOL; rc = LIBSSH2_ERROR_AGENT_PROTOCOL;
goto error; goto error;
} }
@@ -436,7 +442,7 @@ agent_sign(LIBSSH2_SESSION *session, unsigned char **sig, size_t *sig_len,
/* Skip the entire length of the signature */ /* Skip the entire length of the signature */
len -= 4; len -= 4;
if (len < 0) { if(len < 0) {
rc = LIBSSH2_ERROR_AGENT_PROTOCOL; rc = LIBSSH2_ERROR_AGENT_PROTOCOL;
goto error; goto error;
} }
@@ -444,14 +450,14 @@ agent_sign(LIBSSH2_SESSION *session, unsigned char **sig, size_t *sig_len,
/* Skip signing method */ /* Skip signing method */
len -= 4; len -= 4;
if (len < 0) { if(len < 0) {
rc = LIBSSH2_ERROR_AGENT_PROTOCOL; rc = LIBSSH2_ERROR_AGENT_PROTOCOL;
goto error; goto error;
} }
method_len = _libssh2_ntohu32(s); method_len = _libssh2_ntohu32(s);
s += 4; s += 4;
len -= method_len; len -= method_len;
if (len < 0) { if(len < 0) {
rc = LIBSSH2_ERROR_AGENT_PROTOCOL; rc = LIBSSH2_ERROR_AGENT_PROTOCOL;
goto error; goto error;
} }
@@ -459,20 +465,20 @@ agent_sign(LIBSSH2_SESSION *session, unsigned char **sig, size_t *sig_len,
/* Read the signature */ /* Read the signature */
len -= 4; len -= 4;
if (len < 0) { if(len < 0) {
rc = LIBSSH2_ERROR_AGENT_PROTOCOL; rc = LIBSSH2_ERROR_AGENT_PROTOCOL;
goto error; goto error;
} }
*sig_len = _libssh2_ntohu32(s); *sig_len = _libssh2_ntohu32(s);
s += 4; s += 4;
len -= *sig_len; len -= *sig_len;
if (len < 0) { if(len < 0) {
rc = LIBSSH2_ERROR_AGENT_PROTOCOL; rc = LIBSSH2_ERROR_AGENT_PROTOCOL;
goto error; goto error;
} }
*sig = LIBSSH2_ALLOC(session, *sig_len); *sig = LIBSSH2_ALLOC(session, *sig_len);
if (!*sig) { if(!*sig) {
rc = LIBSSH2_ERROR_ALLOC; rc = LIBSSH2_ERROR_ALLOC;
goto error; goto error;
} }
@@ -498,24 +504,24 @@ agent_list_identities(LIBSSH2_AGENT *agent)
unsigned char c = SSH2_AGENTC_REQUEST_IDENTITIES; unsigned char c = SSH2_AGENTC_REQUEST_IDENTITIES;
/* Create a request to list identities */ /* Create a request to list identities */
if (transctx->state == agent_NB_state_init) { if(transctx->state == agent_NB_state_init) {
transctx->request = &c; transctx->request = &c;
transctx->request_len = 1; transctx->request_len = 1;
transctx->state = agent_NB_state_request_created; transctx->state = agent_NB_state_request_created;
} }
/* Make sure to be re-called as a result of EAGAIN. */ /* Make sure to be re-called as a result of EAGAIN. */
if (*transctx->request != SSH2_AGENTC_REQUEST_IDENTITIES) if(*transctx->request != SSH2_AGENTC_REQUEST_IDENTITIES)
return _libssh2_error(agent->session, LIBSSH2_ERROR_BAD_USE, return _libssh2_error(agent->session, LIBSSH2_ERROR_BAD_USE,
"illegal agent request"); "illegal agent request");
if (!agent->ops) if(!agent->ops)
/* if no agent has been connected, bail out */ /* if no agent has been connected, bail out */
return _libssh2_error(agent->session, LIBSSH2_ERROR_BAD_USE, return _libssh2_error(agent->session, LIBSSH2_ERROR_BAD_USE,
"agent not connected"); "agent not connected");
rc = agent->ops->transact(agent, transctx); rc = agent->ops->transact(agent, transctx);
if (rc) { if(rc) {
goto error; goto error;
} }
transctx->request = NULL; transctx->request = NULL;
@@ -523,11 +529,11 @@ agent_list_identities(LIBSSH2_AGENT *agent)
len = transctx->response_len; len = transctx->response_len;
s = transctx->response; s = transctx->response;
len--; len--;
if (len < 0) { if(len < 0) {
rc = LIBSSH2_ERROR_AGENT_PROTOCOL; rc = LIBSSH2_ERROR_AGENT_PROTOCOL;
goto error; goto error;
} }
if (*s != SSH2_AGENT_IDENTITIES_ANSWER) { if(*s != SSH2_AGENT_IDENTITIES_ANSWER) {
rc = LIBSSH2_ERROR_AGENT_PROTOCOL; rc = LIBSSH2_ERROR_AGENT_PROTOCOL;
goto error; goto error;
} }
@@ -535,25 +541,25 @@ agent_list_identities(LIBSSH2_AGENT *agent)
/* Read the length of identities */ /* Read the length of identities */
len -= 4; len -= 4;
if (len < 0) { if(len < 0) {
rc = LIBSSH2_ERROR_AGENT_PROTOCOL; rc = LIBSSH2_ERROR_AGENT_PROTOCOL;
goto error; goto error;
} }
num_identities = _libssh2_ntohu32(s); num_identities = _libssh2_ntohu32(s);
s += 4; s += 4;
while (num_identities--) { while(num_identities--) {
struct agent_publickey *identity; struct agent_publickey *identity;
ssize_t comment_len; ssize_t comment_len;
/* Read the length of the blob */ /* Read the length of the blob */
len -= 4; len -= 4;
if (len < 0) { if(len < 0) {
rc = LIBSSH2_ERROR_AGENT_PROTOCOL; rc = LIBSSH2_ERROR_AGENT_PROTOCOL;
goto error; goto error;
} }
identity = LIBSSH2_ALLOC(agent->session, sizeof *identity); identity = LIBSSH2_ALLOC(agent->session, sizeof *identity);
if (!identity) { if(!identity) {
rc = LIBSSH2_ERROR_ALLOC; rc = LIBSSH2_ERROR_ALLOC;
goto error; goto error;
} }
@@ -562,7 +568,7 @@ agent_list_identities(LIBSSH2_AGENT *agent)
/* Read the blob */ /* Read the blob */
len -= identity->external.blob_len; len -= identity->external.blob_len;
if (len < 0) { if(len < 0) {
rc = LIBSSH2_ERROR_AGENT_PROTOCOL; rc = LIBSSH2_ERROR_AGENT_PROTOCOL;
LIBSSH2_FREE(agent->session, identity); LIBSSH2_FREE(agent->session, identity);
goto error; goto error;
@@ -570,7 +576,7 @@ agent_list_identities(LIBSSH2_AGENT *agent)
identity->external.blob = LIBSSH2_ALLOC(agent->session, identity->external.blob = LIBSSH2_ALLOC(agent->session,
identity->external.blob_len); identity->external.blob_len);
if (!identity->external.blob) { if(!identity->external.blob) {
rc = LIBSSH2_ERROR_ALLOC; rc = LIBSSH2_ERROR_ALLOC;
LIBSSH2_FREE(agent->session, identity); LIBSSH2_FREE(agent->session, identity);
goto error; goto error;
@@ -580,7 +586,7 @@ agent_list_identities(LIBSSH2_AGENT *agent)
/* Read the length of the comment */ /* Read the length of the comment */
len -= 4; len -= 4;
if (len < 0) { if(len < 0) {
rc = LIBSSH2_ERROR_AGENT_PROTOCOL; rc = LIBSSH2_ERROR_AGENT_PROTOCOL;
LIBSSH2_FREE(agent->session, identity->external.blob); LIBSSH2_FREE(agent->session, identity->external.blob);
LIBSSH2_FREE(agent->session, identity); LIBSSH2_FREE(agent->session, identity);
@@ -591,7 +597,7 @@ agent_list_identities(LIBSSH2_AGENT *agent)
/* Read the comment */ /* Read the comment */
len -= comment_len; len -= comment_len;
if (len < 0) { if(len < 0) {
rc = LIBSSH2_ERROR_AGENT_PROTOCOL; rc = LIBSSH2_ERROR_AGENT_PROTOCOL;
LIBSSH2_FREE(agent->session, identity->external.blob); LIBSSH2_FREE(agent->session, identity->external.blob);
LIBSSH2_FREE(agent->session, identity); LIBSSH2_FREE(agent->session, identity);
@@ -600,7 +606,7 @@ agent_list_identities(LIBSSH2_AGENT *agent)
identity->external.comment = LIBSSH2_ALLOC(agent->session, identity->external.comment = LIBSSH2_ALLOC(agent->session,
comment_len + 1); comment_len + 1);
if (!identity->external.comment) { if(!identity->external.comment) {
rc = LIBSSH2_ERROR_ALLOC; rc = LIBSSH2_ERROR_ALLOC;
LIBSSH2_FREE(agent->session, identity->external.blob); LIBSSH2_FREE(agent->session, identity->external.blob);
LIBSSH2_FREE(agent->session, identity); LIBSSH2_FREE(agent->session, identity);
@@ -621,11 +627,12 @@ 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;
for (node = _libssh2_list_first(&agent->head); node; node = next) { for(node = _libssh2_list_first(&agent->head); node; node = next) {
next = _libssh2_list_next(&node->node); next = _libssh2_list_next(&node->node);
LIBSSH2_FREE(agent->session, node->external.blob); LIBSSH2_FREE(agent->session, node->external.blob);
LIBSSH2_FREE(agent->session, node->external.comment); LIBSSH2_FREE(agent->session, node->external.comment);
@@ -664,13 +671,14 @@ libssh2_agent_init(LIBSSH2_SESSION *session)
LIBSSH2_AGENT *agent; LIBSSH2_AGENT *agent;
agent = LIBSSH2_CALLOC(session, sizeof *agent); agent = LIBSSH2_CALLOC(session, sizeof *agent);
if (!agent) { if(!agent) {
_libssh2_error(session, LIBSSH2_ERROR_ALLOC, _libssh2_error(session, LIBSSH2_ERROR_ALLOC,
"Unable to allocate space for agent connection"); "Unable to allocate space for agent connection");
return NULL; return NULL;
} }
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;
@@ -687,10 +695,10 @@ LIBSSH2_API int
libssh2_agent_connect(LIBSSH2_AGENT *agent) libssh2_agent_connect(LIBSSH2_AGENT *agent)
{ {
int i, rc = -1; int i, rc = -1;
for (i = 0; supported_backends[i].name; i++) { for(i = 0; supported_backends[i].name; i++) {
agent->ops = supported_backends[i].ops; agent->ops = supported_backends[i].ops;
rc = (agent->ops->connect)(agent); rc = (agent->ops->connect)(agent);
if (!rc) if(!rc)
return 0; return 0;
} }
return rc; return rc;
@@ -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);
} }
@@ -730,7 +738,7 @@ libssh2_agent_get_identity(LIBSSH2_AGENT *agent,
struct libssh2_agent_publickey *oprev) struct libssh2_agent_publickey *oprev)
{ {
struct agent_publickey *node; struct agent_publickey *node;
if (oprev && oprev->node) { if(oprev && oprev->node) {
/* we have a starting point */ /* we have a starting point */
struct agent_publickey *prev = oprev->node; struct agent_publickey *prev = oprev->node;
@@ -740,7 +748,7 @@ libssh2_agent_get_identity(LIBSSH2_AGENT *agent,
else else
node = _libssh2_list_first(&agent->head); node = _libssh2_list_first(&agent->head);
if (!node) if(!node)
/* no (more) node */ /* no (more) node */
return 1; return 1;
@@ -764,7 +772,7 @@ libssh2_agent_userauth(LIBSSH2_AGENT *agent,
void *abstract = agent; void *abstract = agent;
int rc; int rc;
if (agent->session->userauth_pblc_state == libssh2_NB_state_idle) { if(agent->session->userauth_pblc_state == libssh2_NB_state_idle) {
memset(&agent->transctx, 0, sizeof agent->transctx); memset(&agent->transctx, 0, sizeof agent->transctx);
agent->identity = identity->node; agent->identity = identity->node;
} }
@@ -789,7 +797,7 @@ libssh2_agent_userauth(LIBSSH2_AGENT *agent,
LIBSSH2_API int LIBSSH2_API int
libssh2_agent_disconnect(LIBSSH2_AGENT *agent) libssh2_agent_disconnect(LIBSSH2_AGENT *agent)
{ {
if (agent->ops && agent->fd != LIBSSH2_INVALID_SOCKET) if(agent->ops && agent->fd != LIBSSH2_INVALID_SOCKET)
return agent->ops->disconnect(agent); return agent->ops->disconnect(agent);
return 0; return 0;
} }
@@ -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)) */

File diff suppressed because it is too large Load Diff

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.
* *
@@ -142,7 +142,7 @@ comp_method_zlib_init(LIBSSH2_SESSION * session, int compr,
int status; int status;
strm = LIBSSH2_CALLOC(session, sizeof(z_stream)); strm = LIBSSH2_CALLOC(session, sizeof(z_stream));
if (!strm) { if(!strm) {
return _libssh2_error(session, LIBSSH2_ERROR_ALLOC, return _libssh2_error(session, LIBSSH2_ERROR_ALLOC,
"Unable to allocate memory for " "Unable to allocate memory for "
"zlib compression/decompression"); "zlib compression/decompression");
@@ -151,15 +151,16 @@ comp_method_zlib_init(LIBSSH2_SESSION * session, int compr,
strm->opaque = (voidpf) session; strm->opaque = (voidpf) session;
strm->zalloc = (alloc_func) comp_method_zlib_alloc; strm->zalloc = (alloc_func) comp_method_zlib_alloc;
strm->zfree = (free_func) comp_method_zlib_free; strm->zfree = (free_func) comp_method_zlib_free;
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);
} }
if (status != Z_OK) { if(status != Z_OK) {
LIBSSH2_FREE(session, strm); LIBSSH2_FREE(session, strm);
_libssh2_debug(session, LIBSSH2_TRACE_TRANS, _libssh2_debug(session, LIBSSH2_TRACE_TRANS,
"unhandled zlib error %d", status); "unhandled zlib error %d", status);
@@ -197,13 +198,14 @@ comp_method_zlib_comp(LIBSSH2_SESSION *session,
status = deflate(strm, Z_PARTIAL_FLUSH); status = deflate(strm, Z_PARTIAL_FLUSH);
if ((status == Z_OK) && (strm->avail_out > 0)) { if((status == Z_OK) && (strm->avail_out > 0)) {
*dest_len = out_maxlen - strm->avail_out; *dest_len = out_maxlen - strm->avail_out;
return 0; return 0;
} }
_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");
} }
@@ -226,21 +228,21 @@ comp_method_zlib_decomp(LIBSSH2_SESSION * session,
char *out; char *out;
size_t out_maxlen = src_len; size_t out_maxlen = src_len;
if (src_len <= SIZE_MAX / 4) if(src_len <= SIZE_MAX / 4)
out_maxlen = src_len * 4; out_maxlen = src_len * 4;
else else
out_maxlen = payload_limit; out_maxlen = payload_limit;
/* If strm is null, then we have not yet been initialized. */ /* If strm is null, then we have not yet been initialized. */
if (strm == NULL) if(strm == NULL)
return _libssh2_error(session, LIBSSH2_ERROR_COMPRESS, return _libssh2_error(session, LIBSSH2_ERROR_COMPRESS,
"decompression uninitialized");; "decompression uninitialized");;
/* In practice they never come smaller than this */ /* In practice they never come smaller than this */
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;
@@ -248,26 +250,29 @@ comp_method_zlib_decomp(LIBSSH2_SESSION * session,
strm->next_out = (unsigned char *) LIBSSH2_ALLOC(session, out_maxlen); strm->next_out = (unsigned char *) LIBSSH2_ALLOC(session, out_maxlen);
out = (char *) strm->next_out; out = (char *) strm->next_out;
strm->avail_out = out_maxlen; strm->avail_out = out_maxlen;
if (!strm->next_out) if(!strm->next_out)
return _libssh2_error(session, LIBSSH2_ERROR_ALLOC, return _libssh2_error(session, LIBSSH2_ERROR_ALLOC,
"Unable to allocate decompression buffer"); "Unable to allocate decompression buffer");
/* Loop until it's all inflated or hit error */ /* Loop until it's all inflated or hit error */
for (;;) { for(;;) {
int status; int status;
size_t out_ofs; size_t out_ofs;
char *newout; char *newout;
status = inflate(strm, Z_PARTIAL_FLUSH); status = inflate(strm, Z_PARTIAL_FLUSH);
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");
@@ -286,7 +291,7 @@ comp_method_zlib_decomp(LIBSSH2_SESSION * session,
out_ofs = out_maxlen - strm->avail_out; out_ofs = out_maxlen - strm->avail_out;
out_maxlen *= 2; out_maxlen *= 2;
newout = LIBSSH2_REALLOC(session, out, out_maxlen); newout = LIBSSH2_REALLOC(session, out, out_maxlen);
if (!newout) { if(!newout) {
LIBSSH2_FREE(session, out); LIBSSH2_FREE(session, out);
return _libssh2_error(session, LIBSSH2_ERROR_ALLOC, return _libssh2_error(session, LIBSSH2_ERROR_ALLOC,
"Unable to expand decompression buffer"); "Unable to expand decompression buffer");
@@ -311,8 +316,8 @@ comp_method_zlib_dtor(LIBSSH2_SESSION *session, int compr, void **abstract)
{ {
z_stream *strm = *abstract; z_stream *strm = *abstract;
if (strm) { if(strm) {
if (compr) if(compr)
deflateEnd(strm); deflateEnd(strm);
else else
inflateEnd(strm); inflateEnd(strm);

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 */
@@ -79,12 +80,12 @@ crypt_init(LIBSSH2_SESSION * session,
{ {
struct crypt_ctx *ctx = LIBSSH2_ALLOC(session, struct crypt_ctx *ctx = LIBSSH2_ALLOC(session,
sizeof(struct crypt_ctx)); sizeof(struct crypt_ctx));
if (!ctx) if(!ctx)
return LIBSSH2_ERROR_ALLOC; return LIBSSH2_ERROR_ALLOC;
ctx->encrypt = encrypt; ctx->encrypt = encrypt;
ctx->algo = method->algo; ctx->algo = method->algo;
if (_libssh2_cipher_init(&ctx->h, ctx->algo, iv, secret, encrypt)) { if(_libssh2_cipher_init(&ctx->h, ctx->algo, iv, secret, encrypt)) {
LIBSSH2_FREE(session, ctx); LIBSSH2_FREE(session, ctx);
return -1; return -1;
} }
@@ -108,7 +109,7 @@ static int
crypt_dtor(LIBSSH2_SESSION * session, void **abstract) crypt_dtor(LIBSSH2_SESSION * session, void **abstract)
{ {
struct crypt_ctx **cctx = (struct crypt_ctx **) abstract; struct crypt_ctx **cctx = (struct crypt_ctx **) abstract;
if (cctx && *cctx) { if(cctx && *cctx) {
_libssh2_cipher_dtor(&(*cctx)->h); _libssh2_cipher_dtor(&(*cctx)->h);
LIBSSH2_FREE(session, *cctx); LIBSSH2_FREE(session, *cctx);
*abstract = NULL; *abstract = NULL;
@@ -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 */
@@ -242,13 +252,13 @@ crypt_init_arcfour128(LIBSSH2_SESSION * session,
{ {
int rc; int rc;
rc = crypt_init (session, method, iv, free_iv, secret, free_secret, rc = crypt_init(session, method, iv, free_iv, secret, free_secret,
encrypt, abstract); encrypt, abstract);
if (rc == 0) { if(rc == 0) {
struct crypt_ctx *cctx = *(struct crypt_ctx **) abstract; struct crypt_ctx *cctx = *(struct crypt_ctx **) abstract;
unsigned char block[8]; unsigned char block[8];
size_t discard = 1536; size_t discard = 1536;
for (; discard; discard -= 8) for(; discard; discard -= 8)
_libssh2_cipher_crypt(&cctx->h, cctx->algo, cctx->encrypt, block, _libssh2_cipher_crypt(&cctx->h, cctx->algo, cctx->encrypt, block,
method->blocksize); method->blocksize);
} }
@@ -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

@@ -44,9 +44,8 @@ static int _libssh2_init_flags = 0;
LIBSSH2_API int LIBSSH2_API int
libssh2_init(int flags) 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++;
@@ -58,12 +57,12 @@ libssh2_init(int flags)
LIBSSH2_API void LIBSSH2_API void
libssh2_exit(void) libssh2_exit(void)
{ {
if (_libssh2_initialized == 0) if(_libssh2_initialized == 0)
return; return;
_libssh2_initialized--; _libssh2_initialized--;
if (!(_libssh2_init_flags & LIBSSH2_INIT_NO_CRYPTO)) { if(!(_libssh2_init_flags & LIBSSH2_INIT_NO_CRYPTO)) {
libssh2_crypto_exit(); libssh2_crypto_exit();
} }
@@ -73,6 +72,6 @@ libssh2_exit(void)
void void
_libssh2_init_if_needed(void) _libssh2_init_if_needed(void)
{ {
if (_libssh2_initialized == 0) if(_libssh2_initialized == 0)
(void)libssh2_init (0); (void)libssh2_init (0);
} }

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;
} }
@@ -118,13 +116,13 @@ hostkey_method_ssh_rsa_initPEM(LIBSSH2_SESSION * session,
libssh2_rsa_ctx *rsactx; libssh2_rsa_ctx *rsactx;
int ret; int ret;
if (*abstract) { if(*abstract) {
hostkey_method_ssh_rsa_dtor(session, abstract); hostkey_method_ssh_rsa_dtor(session, abstract);
*abstract = NULL; *abstract = NULL;
} }
ret = _libssh2_rsa_new_private(&rsactx, session, privkeyfile, passphrase); ret = _libssh2_rsa_new_private(&rsactx, session, privkeyfile, passphrase);
if (ret) { if(ret) {
return -1; return -1;
} }
@@ -148,7 +146,7 @@ hostkey_method_ssh_rsa_initPEMFromMemory(LIBSSH2_SESSION * session,
libssh2_rsa_ctx *rsactx; libssh2_rsa_ctx *rsactx;
int ret; int ret;
if (*abstract) { if(*abstract) {
hostkey_method_ssh_rsa_dtor(session, abstract); hostkey_method_ssh_rsa_dtor(session, abstract);
*abstract = NULL; *abstract = NULL;
} }
@@ -156,7 +154,7 @@ hostkey_method_ssh_rsa_initPEMFromMemory(LIBSSH2_SESSION * session,
ret = _libssh2_rsa_new_private_frommemory(&rsactx, session, ret = _libssh2_rsa_new_private_frommemory(&rsactx, session,
privkeyfiledata, privkeyfiledata,
privkeyfiledata_len, passphrase); privkeyfiledata_len, passphrase);
if (ret) { if(ret) {
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);
@@ -218,7 +219,7 @@ hostkey_method_ssh_rsa_signv(LIBSSH2_SESSION * session,
ret = _libssh2_rsa_sha1_sign(session, rsactx, hash, SHA_DIGEST_LENGTH, ret = _libssh2_rsa_sha1_sign(session, rsactx, hash, SHA_DIGEST_LENGTH,
signature, signature_len); signature, signature_len);
if (ret) { if(ret) {
return -1; return -1;
} }
@@ -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;
} }
@@ -342,13 +340,13 @@ hostkey_method_ssh_dss_initPEM(LIBSSH2_SESSION * session,
libssh2_dsa_ctx *dsactx; libssh2_dsa_ctx *dsactx;
int ret; int ret;
if (*abstract) { if(*abstract) {
hostkey_method_ssh_dss_dtor(session, abstract); hostkey_method_ssh_dss_dtor(session, abstract);
*abstract = NULL; *abstract = NULL;
} }
ret = _libssh2_dsa_new_private(&dsactx, session, privkeyfile, passphrase); ret = _libssh2_dsa_new_private(&dsactx, session, privkeyfile, passphrase);
if (ret) { if(ret) {
return -1; return -1;
} }
@@ -372,7 +370,7 @@ hostkey_method_ssh_dss_initPEMFromMemory(LIBSSH2_SESSION * session,
libssh2_dsa_ctx *dsactx; libssh2_dsa_ctx *dsactx;
int ret; int ret;
if (*abstract) { if(*abstract) {
hostkey_method_ssh_dss_dtor(session, abstract); hostkey_method_ssh_dss_dtor(session, abstract);
*abstract = NULL; *abstract = NULL;
} }
@@ -380,7 +378,7 @@ hostkey_method_ssh_dss_initPEMFromMemory(LIBSSH2_SESSION * session,
ret = _libssh2_dsa_new_private_frommemory(&dsactx, session, ret = _libssh2_dsa_new_private_frommemory(&dsactx, session,
privkeyfiledata, privkeyfiledata,
privkeyfiledata_len, passphrase); privkeyfiledata_len, passphrase);
if (ret) { if(ret) {
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);
} }
@@ -432,7 +432,7 @@ hostkey_method_ssh_dss_signv(LIBSSH2_SESSION * session,
int i; int i;
*signature = LIBSSH2_CALLOC(session, 2 * SHA_DIGEST_LENGTH); *signature = LIBSSH2_CALLOC(session, 2 * SHA_DIGEST_LENGTH);
if (!*signature) { if(!*signature) {
return -1; return -1;
} }
@@ -444,7 +444,7 @@ hostkey_method_ssh_dss_signv(LIBSSH2_SESSION * session,
} }
libssh2_sha1_final(ctx, hash); libssh2_sha1_final(ctx, hash);
if (_libssh2_dsa_sha1_sign(dsactx, hash, SHA_DIGEST_LENGTH, *signature)) { if(_libssh2_dsa_sha1_sign(dsactx, hash, SHA_DIGEST_LENGTH, *signature)) {
LIBSSH2_FREE(session, *signature); LIBSSH2_FREE(session, *signature);
return -1; return -1;
} }
@@ -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,12 +1024,12 @@ 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)
{ {
switch (hash_type) { switch(hash_type) {
#if LIBSSH2_MD5 #if LIBSSH2_MD5
case LIBSSH2_HOSTKEY_HASH_MD5: case LIBSSH2_HOSTKEY_HASH_MD5:
return (session->server_hostkey_md5_valid) return (session->server_hostkey_md5_valid)
@@ -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,22 +1054,55 @@ 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;
if (!memcmp(rsa, hostkey, 11)) if(!memcmp(rsa, hostkey, 11))
return LIBSSH2_HOSTKEY_TYPE_RSA; return LIBSSH2_HOSTKEY_TYPE_RSA;
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;
} }
@@ -561,7 +1118,7 @@ libssh2_session_hostkey(LIBSSH2_SESSION *session, size_t *len, int *type)
if(session->server_hostkey_len) { if(session->server_hostkey_len) {
if(len) if(len)
*len = session->server_hostkey_len; *len = session->server_hostkey_len;
if (type) if(type)
*type = hostkey_type(session->server_hostkey, *type = hostkey_type(session->server_hostkey,
session->server_hostkey_len); session->server_hostkey_len);
return (char *) session->server_hostkey; return (char *) session->server_hostkey;
@@ -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

@@ -46,7 +46,7 @@ libssh2_keepalive_config (LIBSSH2_SESSION *session,
int want_reply, int want_reply,
unsigned interval) unsigned interval)
{ {
if (interval == 1) if(interval == 1)
session->keepalive_interval = 2; session->keepalive_interval = 2;
else else
session->keepalive_interval = interval; session->keepalive_interval = interval;
@@ -59,20 +59,20 @@ libssh2_keepalive_send (LIBSSH2_SESSION *session,
{ {
time_t now; time_t now;
if (!session->keepalive_interval) { if(!session->keepalive_interval) {
if (seconds_to_next) if(seconds_to_next)
*seconds_to_next = 0; *seconds_to_next = 0;
return 0; return 0;
} }
now = time (NULL); now = time(NULL);
if (session->keepalive_last_sent + session->keepalive_interval <= now) { if(session->keepalive_last_sent + session->keepalive_interval <= now) {
/* Format is /* Format is
"SSH_MSG_GLOBAL_REQUEST || 4-byte len || str || want-reply". */ "SSH_MSG_GLOBAL_REQUEST || 4-byte len || str || want-reply". */
unsigned char keepalive_data[] unsigned char keepalive_data[]
= "\x50\x00\x00\x00\x15keepalive@libssh2.orgW"; = "\x50\x00\x00\x00\x15keepalive@libssh2.orgW";
size_t len = sizeof (keepalive_data) - 1; size_t len = sizeof(keepalive_data) - 1;
int rc; int rc;
keepalive_data[len - 1] = keepalive_data[len - 1] =
@@ -81,16 +81,17 @@ libssh2_keepalive_send (LIBSSH2_SESSION *session,
rc = _libssh2_transport_send(session, keepalive_data, len, NULL, 0); rc = _libssh2_transport_send(session, keepalive_data, len, NULL, 0);
/* Silently ignore PACKET_EAGAIN here: if the write buffer is /* Silently ignore PACKET_EAGAIN here: if the write buffer is
already full, sending another keepalive is not useful. */ already full, sending another keepalive is not useful. */
if (rc && rc != LIBSSH2_ERROR_EAGAIN) { if(rc && rc != LIBSSH2_ERROR_EAGAIN) {
_libssh2_error(session, LIBSSH2_ERROR_SOCKET_SEND, _libssh2_error(session, LIBSSH2_ERROR_SOCKET_SEND,
"Unable to send keepalive message"); "Unable to send keepalive message");
return rc; return rc;
} }
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,
@@ -71,7 +71,7 @@ static void free_host(LIBSSH2_SESSION *session, struct known_host *entry)
if(entry) { if(entry) {
if(entry->comment) if(entry->comment)
LIBSSH2_FREE(session, entry->comment); LIBSSH2_FREE(session, entry->comment);
if (entry->key_type_name) if(entry->key_type_name)
LIBSSH2_FREE(session, entry->key_type_name); LIBSSH2_FREE(session, entry->key_type_name);
if(entry->key) if(entry->key)
LIBSSH2_FREE(session, entry->key); LIBSSH2_FREE(session, entry->key);
@@ -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");
@@ -159,13 +160,13 @@ knownhost_add(LIBSSH2_KNOWNHOSTS *hosts,
switch(entry->typemask & LIBSSH2_KNOWNHOST_TYPE_MASK) { switch(entry->typemask & LIBSSH2_KNOWNHOST_TYPE_MASK) {
case LIBSSH2_KNOWNHOST_TYPE_PLAIN: case LIBSSH2_KNOWNHOST_TYPE_PLAIN:
case LIBSSH2_KNOWNHOST_TYPE_CUSTOM: case LIBSSH2_KNOWNHOST_TYPE_CUSTOM:
entry->name = LIBSSH2_ALLOC(hosts->session, hostlen+1); entry->name = LIBSSH2_ALLOC(hosts->session, hostlen + 1);
if(!entry->name) { if(!entry->name) {
rc = _libssh2_error(hosts->session, LIBSSH2_ERROR_ALLOC, rc = _libssh2_error(hosts->session, LIBSSH2_ERROR_ALLOC,
"Unable to allocate memory for host name"); "Unable to allocate memory for host name");
goto error; goto error;
} }
memcpy(entry->name, host, hostlen+1); memcpy(entry->name, host, hostlen + 1);
entry->name_len = hostlen; entry->name_len = hostlen;
break; break;
case LIBSSH2_KNOWNHOST_TYPE_SHA1: case LIBSSH2_KNOWNHOST_TYPE_SHA1:
@@ -193,14 +194,14 @@ knownhost_add(LIBSSH2_KNOWNHOSTS *hosts,
/* the provided key is base64 encoded already */ /* the provided key is base64 encoded already */
if(!keylen) if(!keylen)
keylen = strlen(key); keylen = strlen(key);
entry->key = LIBSSH2_ALLOC(hosts->session, keylen+1); entry->key = LIBSSH2_ALLOC(hosts->session, keylen + 1);
if(!entry->key) { if(!entry->key) {
rc = _libssh2_error(hosts->session, LIBSSH2_ERROR_ALLOC, rc = _libssh2_error(hosts->session, LIBSSH2_ERROR_ALLOC,
"Unable to allocate memory for key"); "Unable to allocate memory for key");
goto error; goto error;
} }
memcpy(entry->key, key, keylen+1); memcpy(entry->key, key, keylen + 1);
entry->key[keylen]=0; /* force a terminating zero trailer */ entry->key[keylen] = 0; /* force a terminating zero trailer */
} }
else { else {
/* key is raw, we base64 encode it and store it as such */ /* key is raw, we base64 encode it and store it as such */
@@ -216,28 +217,28 @@ knownhost_add(LIBSSH2_KNOWNHOSTS *hosts,
entry->key = ptr; entry->key = ptr;
} }
if (key_type_name && ((typemask & LIBSSH2_KNOWNHOST_KEY_MASK) == if(key_type_name && ((typemask & LIBSSH2_KNOWNHOST_KEY_MASK) ==
LIBSSH2_KNOWNHOST_KEY_UNKNOWN)) { LIBSSH2_KNOWNHOST_KEY_UNKNOWN)) {
entry->key_type_name = LIBSSH2_ALLOC(hosts->session, key_type_len+1); entry->key_type_name = LIBSSH2_ALLOC(hosts->session, key_type_len + 1);
if (!entry->key_type_name) { if(!entry->key_type_name) {
rc = _libssh2_error(hosts->session, LIBSSH2_ERROR_ALLOC, rc = _libssh2_error(hosts->session, LIBSSH2_ERROR_ALLOC,
"Unable to allocate memory for key type"); "Unable to allocate memory for key type");
goto error; goto error;
} }
memcpy(entry->key_type_name, key_type_name, key_type_len); memcpy(entry->key_type_name, key_type_name, key_type_len);
entry->key_type_name[key_type_len]=0; entry->key_type_name[key_type_len] = 0;
entry->key_type_len = key_type_len; entry->key_type_len = key_type_len;
} }
if (comment) { if(comment) {
entry->comment = LIBSSH2_ALLOC(hosts->session, commentlen+1); entry->comment = LIBSSH2_ALLOC(hosts->session, commentlen + 1);
if(!entry->comment) { if(!entry->comment) {
rc = _libssh2_error(hosts->session, LIBSSH2_ERROR_ALLOC, rc = _libssh2_error(hosts->session, LIBSSH2_ERROR_ALLOC,
"Unable to allocate memory for comment"); "Unable to allocate memory for comment");
goto error; goto error;
} }
memcpy(entry->comment, comment, commentlen+1); memcpy(entry->comment, comment, commentlen + 1);
entry->comment[commentlen]=0; /* force a terminating zero trailer */ entry->comment[commentlen] = 0; /* force a terminating zero trailer */
entry->comment_len = commentlen; entry->comment_len = commentlen;
} }
else { else {
@@ -370,7 +371,7 @@ knownhost_check(LIBSSH2_KNOWNHOSTS *hosts,
plain 'host' */ plain 'host' */
if(port >= 0) { if(port >= 0) {
int len = snprintf(hostbuff, sizeof(hostbuff), "[%s]:%d", hostp, port); int len = snprintf(hostbuff, sizeof(hostbuff), "[%s]:%d", hostp, port);
if (len < 0 || len >= (int)sizeof(hostbuff)) { if(len < 0 || len >= (int)sizeof(hostbuff)) {
_libssh2_error(hosts->session, _libssh2_error(hosts->session,
LIBSSH2_ERROR_BUFFER_TOO_SMALL, LIBSSH2_ERROR_BUFFER_TOO_SMALL,
"Known-host write buffer too small"); "Known-host write buffer too small");
@@ -401,7 +402,7 @@ knownhost_check(LIBSSH2_KNOWNHOSTS *hosts,
do { do {
node = _libssh2_list_first(&hosts->head); node = _libssh2_list_first(&hosts->head);
while (node) { while(node) {
switch(node->typemask & LIBSSH2_KNOWNHOST_TYPE_MASK) { switch(node->typemask & LIBSSH2_KNOWNHOST_TYPE_MASK) {
case LIBSSH2_KNOWNHOST_TYPE_PLAIN: case LIBSSH2_KNOWNHOST_TYPE_PLAIN:
if(type == LIBSSH2_KNOWNHOST_TYPE_PLAIN) if(type == LIBSSH2_KNOWNHOST_TYPE_PLAIN)
@@ -450,13 +451,13 @@ 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! */
if (ext) if(ext)
*ext = knownhost_to_external(node); *ext = knownhost_to_external(node);
badkey = NULL; badkey = NULL;
rc = LIBSSH2_KNOWNHOST_CHECK_MATCH; rc = LIBSSH2_KNOWNHOST_CHECK_MATCH;
@@ -472,14 +473,14 @@ knownhost_check(LIBSSH2_KNOWNHOSTS *hosts,
} }
match = 0; /* don't count this as a match anymore */ match = 0; /* don't count this as a match anymore */
} }
node= _libssh2_list_next(&node->node); node = _libssh2_list_next(&node->node);
} }
host = hostp; host = hostp;
} while(!match && --numcheck); } while(!match && --numcheck);
if(badkey) { if(badkey) {
/* key mismatch */ /* key mismatch */
if (ext) if(ext)
*ext = knownhost_to_external(badkey); *ext = knownhost_to_external(badkey);
rc = LIBSSH2_KNOWNHOST_CHECK_MISMATCH; rc = LIBSSH2_KNOWNHOST_CHECK_MISMATCH;
} }
@@ -646,7 +647,7 @@ static int oldstyle_hostline(LIBSSH2_KNOWNHOSTS *hosts,
/* copy host name to the temp buffer and zero terminate */ /* copy host name to the temp buffer and zero terminate */
memcpy(hostbuf, name, namelen); memcpy(hostbuf, name, namelen);
hostbuf[namelen]=0; hostbuf[namelen] = 0;
rc = knownhost_add(hosts, hostbuf, NULL, rc = knownhost_add(hosts, hostbuf, NULL,
key_type_name, key_type_len, key_type_name, key_type_len,
@@ -685,7 +686,7 @@ static int hashed_hostline(LIBSSH2_KNOWNHOSTS *hosts,
for(p = salt; *p && (*p != '|'); p++) for(p = salt; *p && (*p != '|'); p++)
; ;
if(*p=='|') { if(*p == '|') {
const char *hash = NULL; const char *hash = NULL;
size_t saltlen = p - salt; size_t saltlen = p - salt;
if(saltlen >= (sizeof(saltbuf)-1)) /* weird length */ if(saltlen >= (sizeof(saltbuf)-1)) /* weird length */
@@ -698,11 +699,11 @@ static int hashed_hostline(LIBSSH2_KNOWNHOSTS *hosts,
saltbuf[saltlen] = 0; /* zero terminate */ saltbuf[saltlen] = 0; /* zero terminate */
salt = saltbuf; /* point to the stack based buffer */ salt = saltbuf; /* point to the stack based buffer */
hash = p+1; /* the host hash is after the separator */ hash = p + 1; /* the host hash is after the separator */
/* now make the host point to the hash */ /* now make the host point to the hash */
host = hash; host = hash;
hostlen -= saltlen+1; /* deduct the salt and separator */ hostlen -= saltlen + 1; /* deduct the salt and separator */
/* check that the lengths seem sensible */ /* check that the lengths seem sensible */
if(hostlen >= sizeof(hostbuf)-1) if(hostlen >= sizeof(hostbuf)-1)
@@ -712,7 +713,7 @@ static int hashed_hostline(LIBSSH2_KNOWNHOSTS *hosts,
"(unexpected length)"); "(unexpected length)");
memcpy(hostbuf, host, hostlen); memcpy(hostbuf, host, hostlen);
hostbuf[hostlen]=0; hostbuf[hostlen] = 0;
return knownhost_add(hosts, hostbuf, salt, return knownhost_add(hosts, hostbuf, salt,
key_type_name, key_type_len, key_type_name, key_type_len,
@@ -766,17 +767,25 @@ static int hostline(LIBSSH2_KNOWNHOSTS *hosts,
default: default:
key_type_name = key; key_type_name = key;
while (keylen && *key && while(keylen && *key &&
(*key != ' ') && (*key != '\t')) { (*key != ' ') && (*key != '\t')) {
key++; key++;
keylen--; keylen--;
} }
key_type_len = key - key_type_name; key_type_len = key - key_type_name;
if (!strncmp(key_type_name, "ssh-dss", key_type_len)) if(!strncmp(key_type_name, "ssh-dss", key_type_len))
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;
@@ -800,7 +809,7 @@ static int hostline(LIBSSH2_KNOWNHOSTS *hosts,
keylen -= commentlen; keylen -= commentlen;
/* Distinguish empty comment (a space) from no comment (no space) */ /* Distinguish empty comment (a space) from no comment (no space) */
if (commentlen == 0) if(commentlen == 0)
comment = NULL; comment = NULL;
/* skip whitespaces */ /* skip whitespaces */
@@ -879,7 +888,7 @@ libssh2_knownhost_readline(LIBSSH2_KNOWNHOSTS *hosts,
cp = line; cp = line;
/* skip leading whitespaces */ /* skip leading whitespaces */
while(len && ((*cp==' ') || (*cp == '\t'))) { while(len && ((*cp == ' ') || (*cp == '\t'))) {
cp++; cp++;
len--; len--;
} }
@@ -892,7 +901,7 @@ libssh2_knownhost_readline(LIBSSH2_KNOWNHOSTS *hosts,
hostp = cp; hostp = cp;
/* move over the host to the separator */ /* move over the host to the separator */
while(len && *cp && (*cp!=' ') && (*cp != '\t')) { while(len && *cp && (*cp != ' ') && (*cp != '\t')) {
cp++; cp++;
len--; len--;
} }
@@ -900,7 +909,7 @@ libssh2_knownhost_readline(LIBSSH2_KNOWNHOSTS *hosts,
hostlen = cp - hostp; hostlen = cp - hostp;
/* the key starts after the whitespaces */ /* the key starts after the whitespaces */
while(len && *cp && ((*cp==' ') || (*cp == '\t'))) { while(len && *cp && ((*cp == ' ') || (*cp == '\t'))) {
cp++; cp++;
len--; len--;
} }
@@ -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,13 +1025,30 @@ 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) {
key_type_len = node->key_type_len; key_type_len = node->key_type_len;
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,
@@ -1087,10 +1113,10 @@ knownhost_writeline(LIBSSH2_KNOWNHOSTS *hosts,
if(node->comment && key_type_len) if(node->comment && key_type_len)
snprintf(buf, buflen, "|1|%s|%s %s %s %s\n", saltalloc, snprintf(buf, buflen, "|1|%s|%s %s %s %s\n", saltalloc,
namealloc, key_type_name, node->key, node->comment); namealloc, key_type_name, node->key, node->comment);
else if (node->comment) else if(node->comment)
snprintf(buf, buflen, "|1|%s|%s %s %s\n", saltalloc, namealloc, snprintf(buf, buflen, "|1|%s|%s %s %s\n", saltalloc, namealloc,
node->key, node->comment); node->key, node->comment);
else if (key_type_len) else if(key_type_len)
snprintf(buf, buflen, "|1|%s|%s %s %s\n", saltalloc, namealloc, snprintf(buf, buflen, "|1|%s|%s %s %s\n", saltalloc, namealloc,
key_type_name, node->key); key_type_name, node->key);
else else
@@ -1109,10 +1135,10 @@ knownhost_writeline(LIBSSH2_KNOWNHOSTS *hosts,
if(node->comment && key_type_len) if(node->comment && key_type_len)
snprintf(buf, buflen, "%s %s %s %s\n", node->name, snprintf(buf, buflen, "%s %s %s %s\n", node->name,
key_type_name, node->key, node->comment); key_type_name, node->key, node->comment);
else if (node->comment) else if(node->comment)
snprintf(buf, buflen, "%s %s %s\n", node->name, node->key, snprintf(buf, buflen, "%s %s %s\n", node->name, node->key,
node->comment); node->comment);
else if (key_type_len) else if(key_type_len)
snprintf(buf, buflen, "%s %s %s\n", node->name, key_type_name, snprintf(buf, buflen, "%s %s %s\n", node->name, key_type_name,
node->key); node->key);
else else
@@ -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

@@ -66,17 +66,18 @@ _libssh2_rsa_new(libssh2_rsa_ctx ** rsa,
(void) e2data; (void) e2data;
(void) e2len; (void) e2len;
if (ddata) { if(ddata) {
rc = gcry_sexp_build rc = gcry_sexp_build
(rsa, NULL, (rsa, NULL,
"(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);
} }
if (rc) { if(rc) {
*rsa = NULL; *rsa = NULL;
return -1; return -1;
} }
@@ -99,12 +100,12 @@ _libssh2_rsa_sha1_verify(libssh2_rsa_ctx * rsa,
rc = gcry_sexp_build(&s_hash, NULL, rc = gcry_sexp_build(&s_hash, NULL,
"(data (flags pkcs1) (hash sha1 %b))", "(data (flags pkcs1) (hash sha1 %b))",
SHA_DIGEST_LENGTH, hash); SHA_DIGEST_LENGTH, hash);
if (rc != 0) { if(rc != 0) {
return -1; return -1;
} }
rc = gcry_sexp_build(&s_sig, NULL, "(sig-val(rsa(s %b)))", sig_len, sig); rc = gcry_sexp_build(&s_sig, NULL, "(sig-val(rsa(s %b)))", sig_len, sig);
if (rc != 0) { if(rc != 0) {
gcry_sexp_release(s_hash); gcry_sexp_release(s_hash);
return -1; return -1;
} }
@@ -130,18 +131,19 @@ _libssh2_dsa_new(libssh2_dsa_ctx ** dsactx,
{ {
int rc; int rc;
if (x_len) { if(x_len) {
rc = gcry_sexp_build rc = gcry_sexp_build
(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);
} }
if (rc) { if(rc) {
*dsactx = NULL; *dsactx = NULL;
return -1; return -1;
} }
@@ -172,84 +174,83 @@ _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);
if(!fp) {
fp = fopen(filename, "r");
if (!fp) {
return -1; return -1;
} }
ret = _libssh2_pem_parse(session, ret = _libssh2_pem_parse(session,
"-----BEGIN RSA PRIVATE KEY-----", "-----BEGIN RSA PRIVATE KEY-----",
"-----END RSA PRIVATE KEY-----", "-----END RSA PRIVATE KEY-----",
passphrase,
fp, &data, &datalen); fp, &data, &datalen);
fclose(fp); fclose(fp);
if (ret) { if(ret) {
return -1; return -1;
} }
save_data = data; save_data = data;
if (_libssh2_pem_decode_sequence(&data, &datalen)) { if(_libssh2_pem_decode_sequence(&data, &datalen)) {
ret = -1; ret = -1;
goto fail; goto fail;
} }
/* First read Version field (should be 0). */ /* First read Version field (should be 0). */
ret = _libssh2_pem_decode_integer(&data, &datalen, &n, &nlen); ret = _libssh2_pem_decode_integer(&data, &datalen, &n, &nlen);
if (ret != 0 || (nlen != 1 && *n != '\0')) { if(ret != 0 || (nlen != 1 && *n != '\0')) {
ret = -1; ret = -1;
goto fail; goto fail;
} }
ret = _libssh2_pem_decode_integer(&data, &datalen, &n, &nlen); ret = _libssh2_pem_decode_integer(&data, &datalen, &n, &nlen);
if (ret != 0) { if(ret != 0) {
ret = -1; ret = -1;
goto fail; goto fail;
} }
ret = _libssh2_pem_decode_integer(&data, &datalen, &e, &elen); ret = _libssh2_pem_decode_integer(&data, &datalen, &e, &elen);
if (ret != 0) { if(ret != 0) {
ret = -1; ret = -1;
goto fail; goto fail;
} }
ret = _libssh2_pem_decode_integer(&data, &datalen, &d, &dlen); ret = _libssh2_pem_decode_integer(&data, &datalen, &d, &dlen);
if (ret != 0) { if(ret != 0) {
ret = -1; ret = -1;
goto fail; goto fail;
} }
ret = _libssh2_pem_decode_integer(&data, &datalen, &p, &plen); ret = _libssh2_pem_decode_integer(&data, &datalen, &p, &plen);
if (ret != 0) { if(ret != 0) {
ret = -1; ret = -1;
goto fail; goto fail;
} }
ret = _libssh2_pem_decode_integer(&data, &datalen, &q, &qlen); ret = _libssh2_pem_decode_integer(&data, &datalen, &q, &qlen);
if (ret != 0) { if(ret != 0) {
ret = -1; ret = -1;
goto fail; goto fail;
} }
ret = _libssh2_pem_decode_integer(&data, &datalen, &e1, &e1len); ret = _libssh2_pem_decode_integer(&data, &datalen, &e1, &e1len);
if (ret != 0) { if(ret != 0) {
ret = -1; ret = -1;
goto fail; goto fail;
} }
ret = _libssh2_pem_decode_integer(&data, &datalen, &e2, &e2len); ret = _libssh2_pem_decode_integer(&data, &datalen, &e2, &e2len);
if (ret != 0) { if(ret != 0) {
ret = -1; ret = -1;
goto fail; goto fail;
} }
ret = _libssh2_pem_decode_integer(&data, &datalen, &coeff, &coefflen); ret = _libssh2_pem_decode_integer(&data, &datalen, &coeff, &coefflen);
if (ret != 0) { if(ret != 0) {
ret = -1; ret = -1;
goto fail; goto fail;
} }
if (_libssh2_rsa_new(rsa, e, elen, n, nlen, d, dlen, p, plen, if(_libssh2_rsa_new(rsa, e, elen, n, nlen, d, dlen, p, plen,
q, qlen, e1, e1len, e2, e2len, coeff, coefflen)) { q, qlen, e1, e1len, e2, e2len, coeff, coefflen)) {
ret = -1; ret = -1;
goto fail; goto fail;
@@ -285,72 +286,71 @@ _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);
if(!fp) {
fp = fopen(filename, "r");
if (!fp) {
return -1; return -1;
} }
ret = _libssh2_pem_parse(session, ret = _libssh2_pem_parse(session,
"-----BEGIN DSA PRIVATE KEY-----", "-----BEGIN DSA PRIVATE KEY-----",
"-----END DSA PRIVATE KEY-----", "-----END DSA PRIVATE KEY-----",
passphrase,
fp, &data, &datalen); fp, &data, &datalen);
fclose(fp); fclose(fp);
if (ret) { if(ret) {
return -1; return -1;
} }
save_data = data; save_data = data;
if (_libssh2_pem_decode_sequence(&data, &datalen)) { if(_libssh2_pem_decode_sequence(&data, &datalen)) {
ret = -1; ret = -1;
goto fail; goto fail;
} }
/* First read Version field (should be 0). */ /* First read Version field (should be 0). */
ret = _libssh2_pem_decode_integer(&data, &datalen, &p, &plen); ret = _libssh2_pem_decode_integer(&data, &datalen, &p, &plen);
if (ret != 0 || (plen != 1 && *p != '\0')) { if(ret != 0 || (plen != 1 && *p != '\0')) {
ret = -1; ret = -1;
goto fail; goto fail;
} }
ret = _libssh2_pem_decode_integer(&data, &datalen, &p, &plen); ret = _libssh2_pem_decode_integer(&data, &datalen, &p, &plen);
if (ret != 0) { if(ret != 0) {
ret = -1; ret = -1;
goto fail; goto fail;
} }
ret = _libssh2_pem_decode_integer(&data, &datalen, &q, &qlen); ret = _libssh2_pem_decode_integer(&data, &datalen, &q, &qlen);
if (ret != 0) { if(ret != 0) {
ret = -1; ret = -1;
goto fail; goto fail;
} }
ret = _libssh2_pem_decode_integer(&data, &datalen, &g, &glen); ret = _libssh2_pem_decode_integer(&data, &datalen, &g, &glen);
if (ret != 0) { if(ret != 0) {
ret = -1; ret = -1;
goto fail; goto fail;
} }
ret = _libssh2_pem_decode_integer(&data, &datalen, &y, &ylen); ret = _libssh2_pem_decode_integer(&data, &datalen, &y, &ylen);
if (ret != 0) { if(ret != 0) {
ret = -1; ret = -1;
goto fail; goto fail;
} }
ret = _libssh2_pem_decode_integer(&data, &datalen, &x, &xlen); ret = _libssh2_pem_decode_integer(&data, &datalen, &x, &xlen);
if (ret != 0) { if(ret != 0) {
ret = -1; ret = -1;
goto fail; goto fail;
} }
if (datalen != 0) { if(datalen != 0) {
ret = -1; ret = -1;
goto fail; goto fail;
} }
if (_libssh2_dsa_new(dsa, p, plen, q, qlen, g, glen, y, ylen, x, xlen)) { if(_libssh2_dsa_new(dsa, p, plen, q, qlen, g, glen, y, ylen, x, xlen)) {
ret = -1; ret = -1;
goto fail; goto fail;
} }
@@ -375,11 +375,11 @@ _libssh2_rsa_sha1_sign(LIBSSH2_SESSION * session,
const char *tmp; const char *tmp;
size_t size; size_t size;
if (hash_len != SHA_DIGEST_LENGTH) { if(hash_len != SHA_DIGEST_LENGTH) {
return -1; return -1;
} }
if (gcry_sexp_build(&data, NULL, if(gcry_sexp_build(&data, NULL,
"(data (flags pkcs1) (hash sha1 %b))", "(data (flags pkcs1) (hash sha1 %b))",
hash_len, hash)) { hash_len, hash)) {
return -1; return -1;
@@ -389,32 +389,36 @@ _libssh2_rsa_sha1_sign(LIBSSH2_SESSION * session,
gcry_sexp_release(data); gcry_sexp_release(data);
if (rc != 0) { if(rc != 0) {
return -1; return -1;
} }
data = gcry_sexp_find_token(sig_sexp, "s", 0); data = gcry_sexp_find_token(sig_sexp, "s", 0);
if (!data) { if(!data) {
return -1; return -1;
} }
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;
} }
if (tmp[0] == '\0') { if(tmp[0] == '\0') {
tmp++; tmp++;
size--; size--;
} }
*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;
} }
@@ -430,14 +434,15 @@ _libssh2_dsa_sha1_sign(libssh2_dsa_ctx * dsactx,
const char *tmp; const char *tmp;
size_t size; size_t size;
if (hash_len != SHA_DIGEST_LENGTH) { if(hash_len != SHA_DIGEST_LENGTH) {
return -1; return -1;
} }
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;
} }
@@ -445,7 +450,7 @@ _libssh2_dsa_sha1_sign(libssh2_dsa_ctx * dsactx,
gcry_sexp_release(data); gcry_sexp_release(data);
if (ret != 0) { if(ret != 0) {
return -1; return -1;
} }
@@ -454,19 +459,19 @@ _libssh2_dsa_sha1_sign(libssh2_dsa_ctx * dsactx,
/* Extract R. */ /* Extract R. */
data = gcry_sexp_find_token(sig_sexp, "r", 0); data = gcry_sexp_find_token(sig_sexp, "r", 0);
if (!data) if(!data)
goto err; goto err;
tmp = gcry_sexp_nth_data(data, 1, &size); tmp = gcry_sexp_nth_data(data, 1, &size);
if (!tmp) if(!tmp)
goto err; goto err;
if (tmp[0] == '\0') { if(tmp[0] == '\0') {
tmp++; tmp++;
size--; size--;
} }
if (size < 1 || size > 20) if(size < 1 || size > 20)
goto err; goto err;
memcpy(sig + (20 - size), tmp, size); memcpy(sig + (20 - size), tmp, size);
@@ -476,19 +481,19 @@ _libssh2_dsa_sha1_sign(libssh2_dsa_ctx * dsactx,
/* Extract S. */ /* Extract S. */
data = gcry_sexp_find_token(sig_sexp, "s", 0); data = gcry_sexp_find_token(sig_sexp, "s", 0);
if (!data) if(!data)
goto err; goto err;
tmp = gcry_sexp_nth_data(data, 1, &size); tmp = gcry_sexp_nth_data(data, 1, &size);
if (!tmp) if(!tmp)
goto err; goto err;
if (tmp[0] == '\0') { if(tmp[0] == '\0') {
tmp++; tmp++;
size--; size--;
} }
if (size < 1 || size > 20) if(size < 1 || size > 20)
goto err; goto err;
memcpy(sig + 20 + (20 - size), tmp, size); memcpy(sig + 20 + (20 - size), tmp, size);
@@ -498,10 +503,10 @@ _libssh2_dsa_sha1_sign(libssh2_dsa_ctx * dsactx,
ret = -1; ret = -1;
out: out:
if (sig_sexp) { if(sig_sexp) {
gcry_sexp_release(sig_sexp); gcry_sexp_release(sig_sexp);
} }
if (data) { if(data) {
gcry_sexp_release(data); gcry_sexp_release(data);
} }
return ret; return ret;
@@ -519,12 +524,12 @@ _libssh2_dsa_sha1_verify(libssh2_dsa_ctx * dsactx,
libssh2_sha1(m, m_len, hash + 1); libssh2_sha1(m, m_len, hash + 1);
hash[0] = 0; hash[0] = 0;
if (gcry_sexp_build(&s_hash, NULL, "(data(flags raw)(value %b))", if(gcry_sexp_build(&s_hash, NULL, "(data(flags raw)(value %b))",
SHA_DIGEST_LENGTH + 1, hash)) { SHA_DIGEST_LENGTH + 1, hash)) {
return -1; return -1;
} }
if (gcry_sexp_build(&s_sig, NULL, "(sig-val(dsa(r %b)(s %b)))", if(gcry_sexp_build(&s_sig, NULL, "(sig-val(dsa(r %b)(s %b)))",
20, sig, 20, sig + 20)) { 20, sig, 20, sig + 20)) {
gcry_sexp_release(s_hash); gcry_sexp_release(s_hash);
return -1; return -1;
@@ -543,30 +548,30 @@ _libssh2_cipher_init(_libssh2_cipher_ctx * h,
unsigned char *iv, unsigned char *secret, int encrypt) unsigned char *iv, unsigned char *secret, int encrypt)
{ {
int ret; int ret;
int cipher = _libssh2_gcry_cipher (algo); int cipher = _libssh2_gcry_cipher(algo);
int mode = _libssh2_gcry_mode (algo); int mode = _libssh2_gcry_mode(algo);
int keylen = gcry_cipher_get_algo_keylen(cipher); int keylen = gcry_cipher_get_algo_keylen(cipher);
(void) encrypt; (void) encrypt;
ret = gcry_cipher_open(h, cipher, mode, 0); ret = gcry_cipher_open(h, cipher, mode, 0);
if (ret) { if(ret) {
return -1; return -1;
} }
ret = gcry_cipher_setkey(*h, secret, keylen); ret = gcry_cipher_setkey(*h, secret, keylen);
if (ret) { if(ret) {
gcry_cipher_close(*h); gcry_cipher_close(*h);
return -1; return -1;
} }
if (mode != GCRY_CIPHER_MODE_STREAM) { if(mode != GCRY_CIPHER_MODE_STREAM) {
int blklen = gcry_cipher_get_algo_blklen(cipher); int blklen = gcry_cipher_get_algo_blklen(cipher);
if (mode == GCRY_CIPHER_MODE_CTR) if(mode == GCRY_CIPHER_MODE_CTR)
ret = gcry_cipher_setctr(*h, iv, blklen); ret = gcry_cipher_setctr(*h, iv, blklen);
else else
ret = gcry_cipher_setiv(*h, iv, blklen); ret = gcry_cipher_setiv(*h, iv, blklen);
if (ret) { if(ret) {
gcry_cipher_close(*h); gcry_cipher_close(*h);
return -1; return -1;
} }
@@ -580,12 +585,13 @@ _libssh2_cipher_crypt(_libssh2_cipher_ctx * ctx,
_libssh2_cipher_type(algo), _libssh2_cipher_type(algo),
int encrypt, unsigned char *block, size_t blklen) int encrypt, unsigned char *block, size_t blklen)
{ {
int cipher = _libssh2_gcry_cipher (algo); int cipher = _libssh2_gcry_cipher(algo);
int ret; int ret;
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)
@@ -68,60 +74,82 @@
/* returns 0 in case of failure */ /* returns 0 in case of failure */
#define libssh2_sha1_init(ctx) \ #define libssh2_sha1_init(ctx) \
(GPG_ERR_NO_ERROR == gcry_md_open (ctx, GCRY_MD_SHA1, 0)) (GPG_ERR_NO_ERROR == gcry_md_open(ctx, GCRY_MD_SHA1, 0))
#define libssh2_sha1_update(ctx, data, len) \ #define libssh2_sha1_update(ctx, data, len) \
gcry_md_write (ctx, (unsigned char *) data, len) gcry_md_write(ctx, (unsigned char *) data, len)
#define libssh2_sha1_final(ctx, out) \ #define libssh2_sha1_final(ctx, out) \
memcpy (out, gcry_md_read (ctx, 0), SHA_DIGEST_LENGTH), gcry_md_close (ctx) memcpy(out, gcry_md_read(ctx, 0), SHA_DIGEST_LENGTH), gcry_md_close(ctx)
#define libssh2_sha1(message, len, out) \ #define libssh2_sha1(message, len, out) \
gcry_md_hash_buffer (GCRY_MD_SHA1, out, message, len) gcry_md_hash_buffer(GCRY_MD_SHA1, out, message, len)
#define libssh2_sha256_ctx gcry_md_hd_t #define libssh2_sha256_ctx gcry_md_hd_t
#define libssh2_sha256_init(ctx) \ #define libssh2_sha256_init(ctx) \
(GPG_ERR_NO_ERROR == gcry_md_open (ctx, GCRY_MD_SHA256, 0)) (GPG_ERR_NO_ERROR == gcry_md_open(ctx, GCRY_MD_SHA256, 0))
#define libssh2_sha256_update(ctx, data, len) \ #define libssh2_sha256_update(ctx, data, len) \
gcry_md_write (ctx, (unsigned char *) data, len) gcry_md_write(ctx, (unsigned char *) data, len)
#define libssh2_sha256_final(ctx, out) \ #define libssh2_sha256_final(ctx, out) \
memcpy (out, gcry_md_read (ctx, 0), SHA256_DIGEST_LENGTH), gcry_md_close (ctx) memcpy(out, gcry_md_read(ctx, 0), SHA256_DIGEST_LENGTH), gcry_md_close(ctx)
#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 */
#define libssh2_md5_init(ctx) \ #define libssh2_md5_init(ctx) \
(GPG_ERR_NO_ERROR == gcry_md_open (ctx, GCRY_MD_MD5, 0)) (GPG_ERR_NO_ERROR == gcry_md_open(ctx, GCRY_MD_MD5, 0))
#define libssh2_md5_update(ctx, data, len) \ #define libssh2_md5_update(ctx, data, len) \
gcry_md_write (ctx, (unsigned char *) data, len) gcry_md_write(ctx, (unsigned char *) data, len)
#define libssh2_md5_final(ctx, out) \ #define libssh2_md5_final(ctx, out) \
memcpy (out, gcry_md_read (ctx, 0), MD5_DIGEST_LENGTH), gcry_md_close (ctx) memcpy(out, gcry_md_read(ctx, 0), MD5_DIGEST_LENGTH), gcry_md_close(ctx)
#define libssh2_md5(message, len, out) \ #define libssh2_md5(message, len, out) \
gcry_md_hash_buffer (GCRY_MD_MD5, out, message, len) gcry_md_hash_buffer(GCRY_MD_MD5, out, message, len)
#define libssh2_hmac_ctx gcry_md_hd_t #define libssh2_hmac_ctx gcry_md_hd_t
#define libssh2_hmac_ctx_init(ctx) #define libssh2_hmac_ctx_init(ctx)
#define libssh2_hmac_sha1_init(ctx, key, keylen) \ #define libssh2_hmac_sha1_init(ctx, key, keylen) \
gcry_md_open (ctx, GCRY_MD_SHA1, GCRY_MD_FLAG_HMAC), \ gcry_md_open(ctx, GCRY_MD_SHA1, GCRY_MD_FLAG_HMAC), \
gcry_md_setkey (*ctx, key, keylen) gcry_md_setkey(*ctx, key, keylen)
#define libssh2_hmac_md5_init(ctx, key, keylen) \ #define libssh2_hmac_md5_init(ctx, key, keylen) \
gcry_md_open (ctx, GCRY_MD_MD5, GCRY_MD_FLAG_HMAC), \ gcry_md_open(ctx, GCRY_MD_MD5, GCRY_MD_FLAG_HMAC), \
gcry_md_setkey (*ctx, key, keylen) gcry_md_setkey(*ctx, key, keylen)
#define libssh2_hmac_ripemd160_init(ctx, key, keylen) \ #define libssh2_hmac_ripemd160_init(ctx, key, keylen) \
gcry_md_open (ctx, GCRY_MD_RMD160, GCRY_MD_FLAG_HMAC), \ gcry_md_open(ctx, GCRY_MD_RMD160, GCRY_MD_FLAG_HMAC), \
gcry_md_setkey (*ctx, key, keylen) gcry_md_setkey(*ctx, key, keylen)
#define libssh2_hmac_sha256_init(ctx, key, keylen) \ #define libssh2_hmac_sha256_init(ctx, key, keylen) \
gcry_md_open (ctx, GCRY_MD_SHA256, GCRY_MD_FLAG_HMAC), \ gcry_md_open(ctx, GCRY_MD_SHA256, GCRY_MD_FLAG_HMAC), \
gcry_md_setkey (*ctx, key, keylen) gcry_md_setkey(*ctx, key, keylen)
#define libssh2_hmac_sha512_init(ctx, key, keylen) \ #define libssh2_hmac_sha512_init(ctx, key, keylen) \
gcry_md_open (ctx, GCRY_MD_SHA512, GCRY_MD_FLAG_HMAC), \ gcry_md_open(ctx, GCRY_MD_SHA512, GCRY_MD_FLAG_HMAC), \
gcry_md_setkey (*ctx, key, keylen) gcry_md_setkey(*ctx, key, keylen)
#define libssh2_hmac_update(ctx, data, datalen) \ #define libssh2_hmac_update(ctx, data, datalen) \
gcry_md_write (ctx, (unsigned char *) data, datalen) gcry_md_write(ctx, (unsigned char *) data, datalen)
#define libssh2_hmac_final(ctx, data) \ #define libssh2_hmac_final(ctx, data) \
memcpy (data, gcry_md_read (ctx, 0), \ memcpy(data, gcry_md_read(ctx, 0), \
gcry_md_get_algo_dlen (gcry_md_get_algo (ctx))) gcry_md_get_algo_dlen(gcry_md_get_algo(ctx)))
#define libssh2_hmac_cleanup(ctx) gcry_md_close (*ctx); #define libssh2_hmac_cleanup(ctx) gcry_md_close (*ctx);
#define libssh2_crypto_init() gcry_control (GCRYCTL_DISABLE_SECMEM) #define libssh2_crypto_init() gcry_control (GCRYCTL_DISABLE_SECMEM)
@@ -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
@@ -118,13 +115,13 @@
struct iovec { struct iovec {
size_t iov_len; size_t iov_len;
void * iov_base; void *iov_base;
}; };
static inline int writev(int sock, struct iovec *iov, int nvecs) static inline int writev(int sock, struct iovec *iov, int nvecs)
{ {
DWORD ret; DWORD ret;
if (WSASend(sock, (LPWSABUF)iov, nvecs, &ret, 0, NULL, NULL) == 0) { if(WSASend(sock, (LPWSABUF)iov, nvecs, &ret, 0, NULL, NULL) == 0) {
return ret; return ret;
} }
return -1; return -1;
@@ -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,8 +662,9 @@ 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
void* tracehandler_context; /* context for the trace handler */ messages */
void *tracehandler_context; /* context for the trace handler */
#endif #endif
/* State variables used in libssh2_banner_send() */ /* State variables used in libssh2_banner_send() */
@@ -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,31 +1069,75 @@ 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);
/* global.c */ /* global.c */
void _libssh2_init_if_needed (void); void _libssh2_init_if_needed(void);
#define ARRAY_SIZE(a) (sizeof ((a)) / sizeof ((a)[0])) #define ARRAY_SIZE(a) (sizeof ((a)) / sizeof ((a)[0]))
/* define to output the libssh2_int64_t type in a *printf() */ /* define to output the libssh2_int64_t type in a *printf() */
#if defined( __BORLANDC__ ) || defined( _MSC_VER ) || defined( __MINGW32__ ) #if defined(__BORLANDC__) || defined(_MSC_VER) || defined(__MINGW32__)
#define LIBSSH2_INT64_T_FORMAT "I64d" #define LIBSSH2_INT64_T_FORMAT "I64d"
#else #else
#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

@@ -86,7 +86,7 @@ mac_method_common_init(LIBSSH2_SESSION * session, unsigned char *key,
static int static int
mac_method_common_dtor(LIBSSH2_SESSION * session, void **abstract) mac_method_common_dtor(LIBSSH2_SESSION * session, void **abstract)
{ {
if (*abstract) { if(*abstract) {
LIBSSH2_FREE(session, *abstract); LIBSSH2_FREE(session, *abstract);
} }
*abstract = NULL; *abstract = NULL;
@@ -118,7 +118,7 @@ mac_method_hmac_sha2_512_hash(LIBSSH2_SESSION * session,
libssh2_hmac_sha512_init(&ctx, *abstract, 64); libssh2_hmac_sha512_init(&ctx, *abstract, 64);
libssh2_hmac_update(ctx, seqno_buf, 4); libssh2_hmac_update(ctx, seqno_buf, 4);
libssh2_hmac_update(ctx, packet, packet_len); libssh2_hmac_update(ctx, packet, packet_len);
if (addtl && addtl_len) { if(addtl && addtl_len) {
libssh2_hmac_update(ctx, addtl, addtl_len); libssh2_hmac_update(ctx, addtl, addtl_len);
} }
libssh2_hmac_final(ctx, buf); libssh2_hmac_final(ctx, buf);
@@ -163,7 +163,7 @@ mac_method_hmac_sha2_256_hash(LIBSSH2_SESSION * session,
libssh2_hmac_sha256_init(&ctx, *abstract, 32); libssh2_hmac_sha256_init(&ctx, *abstract, 32);
libssh2_hmac_update(ctx, seqno_buf, 4); libssh2_hmac_update(ctx, seqno_buf, 4);
libssh2_hmac_update(ctx, packet, packet_len); libssh2_hmac_update(ctx, packet, packet_len);
if (addtl && addtl_len) { if(addtl && addtl_len) {
libssh2_hmac_update(ctx, addtl, addtl_len); libssh2_hmac_update(ctx, addtl, addtl_len);
} }
libssh2_hmac_final(ctx, buf); libssh2_hmac_final(ctx, buf);
@@ -208,7 +208,7 @@ mac_method_hmac_sha1_hash(LIBSSH2_SESSION * session,
libssh2_hmac_sha1_init(&ctx, *abstract, 20); libssh2_hmac_sha1_init(&ctx, *abstract, 20);
libssh2_hmac_update(ctx, seqno_buf, 4); libssh2_hmac_update(ctx, seqno_buf, 4);
libssh2_hmac_update(ctx, packet, packet_len); libssh2_hmac_update(ctx, packet, packet_len);
if (addtl && addtl_len) { if(addtl && addtl_len) {
libssh2_hmac_update(ctx, addtl, addtl_len); libssh2_hmac_update(ctx, addtl, addtl_len);
} }
libssh2_hmac_final(ctx, buf); libssh2_hmac_final(ctx, buf);
@@ -281,7 +281,7 @@ mac_method_hmac_md5_hash(LIBSSH2_SESSION * session, unsigned char *buf,
libssh2_hmac_md5_init(&ctx, *abstract, 16); libssh2_hmac_md5_init(&ctx, *abstract, 16);
libssh2_hmac_update(ctx, seqno_buf, 4); libssh2_hmac_update(ctx, seqno_buf, 4);
libssh2_hmac_update(ctx, packet, packet_len); libssh2_hmac_update(ctx, packet, packet_len);
if (addtl && addtl_len) { if(addtl && addtl_len) {
libssh2_hmac_update(ctx, addtl, addtl_len); libssh2_hmac_update(ctx, addtl, addtl_len);
} }
libssh2_hmac_final(ctx, buf); libssh2_hmac_final(ctx, buf);
@@ -354,7 +354,7 @@ mac_method_hmac_ripemd160_hash(LIBSSH2_SESSION * session,
libssh2_hmac_ripemd160_init(&ctx, *abstract, 20); libssh2_hmac_ripemd160_init(&ctx, *abstract, 20);
libssh2_hmac_update(ctx, seqno_buf, 4); libssh2_hmac_update(ctx, seqno_buf, 4);
libssh2_hmac_update(ctx, packet, packet_len); libssh2_hmac_update(ctx, packet, packet_len);
if (addtl && addtl_len) { if(addtl && addtl_len) {
libssh2_hmac_update(ctx, addtl, addtl_len); libssh2_hmac_update(ctx, addtl, addtl_len);
} }
libssh2_hmac_final(ctx, buf); libssh2_hmac_final(ctx, buf);

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
@@ -18,7 +63,7 @@ _libssh2_mbedtls_init(void)
ret = mbedtls_ctr_drbg_seed(&_libssh2_mbedtls_ctr_drbg, ret = mbedtls_ctr_drbg_seed(&_libssh2_mbedtls_ctr_drbg,
mbedtls_entropy_func, mbedtls_entropy_func,
&_libssh2_mbedtls_entropy, NULL, 0); &_libssh2_mbedtls_entropy, NULL, 0);
if (ret != 0) if(ret != 0)
mbedtls_ctr_drbg_free(&_libssh2_mbedtls_ctr_drbg); mbedtls_ctr_drbg_free(&_libssh2_mbedtls_ctr_drbg);
} }
@@ -44,11 +89,11 @@ _libssh2_mbedtls_safe_free(void *buf, int len)
(void)len; (void)len;
#endif #endif
if (!buf) if(!buf)
return; return;
#ifdef LIBSSH2_CLEAR_MEMORY #ifdef LIBSSH2_CLEAR_MEMORY
if (len > 0) if(len > 0)
memset(buf, 0, len); memset(buf, 0, len);
#endif #endif
@@ -65,7 +110,7 @@ _libssh2_mbedtls_cipher_init(_libssh2_cipher_ctx *ctx,
const mbedtls_cipher_info_t *cipher_info; const mbedtls_cipher_info_t *cipher_info;
int ret, op; int ret, op;
if (!ctx) if(!ctx)
return -1; return -1;
op = encrypt == 0 ? MBEDTLS_ENCRYPT : MBEDTLS_DECRYPT; op = encrypt == 0 ? MBEDTLS_ENCRYPT : MBEDTLS_DECRYPT;
@@ -99,11 +144,10 @@ _libssh2_mbedtls_cipher_crypt(_libssh2_cipher_ctx *ctx,
(void) encrypt; (void) encrypt;
(void) algo; (void) algo;
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)
@@ -112,7 +156,7 @@ _libssh2_mbedtls_cipher_crypt(_libssh2_cipher_ctx *ctx,
if(!ret) if(!ret)
ret = mbedtls_cipher_finish(ctx, output + olen, &finish_olen); ret = mbedtls_cipher_finish(ctx, output + olen, &finish_olen);
if (!ret) { if(!ret) {
olen += finish_olen; olen += finish_olen;
memcpy(block, output, olen); memcpy(block, output, olen);
} }
@@ -148,8 +192,8 @@ _libssh2_mbedtls_hash_init(mbedtls_md_context_t *ctx,
mbedtls_md_init(ctx); mbedtls_md_init(ctx);
ret = mbedtls_md_setup(ctx, md_info, hmac); ret = mbedtls_md_setup(ctx, md_info, hmac);
if (!ret){ if(!ret) {
if (hmac) if(hmac)
ret = mbedtls_md_hmac_starts(ctx, key, keylen); ret = mbedtls_md_hmac_starts(ctx, key, keylen);
else else
ret = mbedtls_md_starts(ctx); ret = mbedtls_md_starts(ctx);
@@ -196,50 +240,61 @@ _libssh2_mbedtls_bignum_init(void)
_libssh2_bn *bignum; _libssh2_bn *bignum;
bignum = (_libssh2_bn *)mbedtls_calloc(1, sizeof(_libssh2_bn)); bignum = (_libssh2_bn *)mbedtls_calloc(1, sizeof(_libssh2_bn));
if (bignum) { if(bignum) {
mbedtls_mpi_init(bignum); mbedtls_mpi_init(bignum);
} }
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;
int err; int err;
int i; int i;
if (!bn || bits <= 0) if(!bn || bits <= 0)
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,
if (err) &_libssh2_mbedtls_ctr_drbg);
if(err)
return -1; return -1;
/* Zero unsued bits above the most significant bit*/ /* Zero unsued bits above the most significant bit*/
for(i=len*8-1;bits<=i;--i) { for(i = len*8 - 1; bits <= i; --i) {
err = mbedtls_mpi_set_bit(bn, i, 0); err = mbedtls_mpi_set_bit(bn, i, 0);
if (err) if(err)
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);
if (err) if(err)
return -1; return -1;
} }
/* make odd by setting first bit in least significant byte */ /* make odd by setting first bit in least significant byte */
if (bottom) { if(bottom) {
err = mbedtls_mpi_set_bit(bn, 0, 1); err = mbedtls_mpi_set_bit(bn, 0, 1);
if (err) if(err)
return -1; return -1;
} }
@@ -275,42 +330,40 @@ _libssh2_mbedtls_rsa_new(libssh2_rsa_ctx **rsa,
libssh2_rsa_ctx *ctx; libssh2_rsa_ctx *ctx;
ctx = (libssh2_rsa_ctx *) mbedtls_calloc(1, sizeof(libssh2_rsa_ctx)); ctx = (libssh2_rsa_ctx *) mbedtls_calloc(1, sizeof(libssh2_rsa_ctx));
if (ctx != NULL) { if(ctx != NULL) {
mbedtls_rsa_init(ctx, MBEDTLS_RSA_PKCS_V15, 0); mbedtls_rsa_init(ctx, MBEDTLS_RSA_PKCS_V15, 0);
} }
else else
return -1; return -1;
if( (ret = mbedtls_mpi_read_binary(&(ctx->E), edata, elen) ) != 0 || /* !checksrc! disable ASSIGNWITHINCONDITION 1 */
(ret = mbedtls_mpi_read_binary(&(ctx->N), ndata, nlen) ) != 0 ) if((ret = mbedtls_mpi_read_binary(&(ctx->E), edata, elen) ) != 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);
} }
if (ret && ctx) { if(ret && ctx) {
_libssh2_mbedtls_rsa_free(ctx); _libssh2_mbedtls_rsa_free(ctx);
ctx = NULL; ctx = NULL;
} }
@@ -326,17 +379,17 @@ _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)
return -1; return -1;
mbedtls_rsa_init(*rsa, MBEDTLS_RSA_PKCS_V15, 0); mbedtls_rsa_init(*rsa, MBEDTLS_RSA_PKCS_V15, 0);
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;
} }
@@ -421,14 +491,14 @@ _libssh2_mbedtls_rsa_sha1_sign(LIBSSH2_SESSION *session,
sig_len = rsa->len; sig_len = rsa->len;
sig = LIBSSH2_ALLOC(session, sig_len); sig = LIBSSH2_ALLOC(session, sig_len);
if (!sig) { if(!sig) {
return -1; return -1;
} }
ret = mbedtls_rsa_pkcs1_sign(rsa, NULL, NULL, MBEDTLS_RSA_PRIVATE, ret = mbedtls_rsa_pkcs1_sign(rsa, NULL, NULL, MBEDTLS_RSA_PRIVATE,
MBEDTLS_MD_SHA1, SHA_DIGEST_LENGTH, MBEDTLS_MD_SHA1, SHA_DIGEST_LENGTH,
hash, sig); hash, sig);
if (ret) { if(ret) {
LIBSSH2_FREE(session, sig); LIBSSH2_FREE(session, sig);
return -1; return -1;
} }
@@ -453,8 +523,8 @@ gen_publickey_from_rsa(LIBSSH2_SESSION *session,
{ {
int e_bytes, n_bytes; int e_bytes, n_bytes;
unsigned long len; unsigned long len;
unsigned char* key; unsigned char *key;
unsigned char* p; unsigned char *p;
e_bytes = mbedtls_mpi_size(&rsa->E); e_bytes = mbedtls_mpi_size(&rsa->E);
n_bytes = mbedtls_mpi_size(&rsa->N); n_bytes = mbedtls_mpi_size(&rsa->N);
@@ -463,7 +533,7 @@ gen_publickey_from_rsa(LIBSSH2_SESSION *session,
len = 4 + 7 + 4 + e_bytes + 4 + n_bytes; len = 4 + 7 + 4 + e_bytes + 4 + n_bytes;
key = LIBSSH2_ALLOC(session, len); key = LIBSSH2_ALLOC(session, len);
if (!key) { if(!key) {
return NULL; return NULL;
} }
@@ -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,21 +53,28 @@
#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);
session->err_code = errcode; session->err_code = errcode;
session->err_flags = 0; session->err_flags = 0;
if ((errmsg != NULL) && ((errflags & LIBSSH2_ERR_FLAG_DUP) != 0)) { if((errmsg != NULL) && ((errflags & LIBSSH2_ERR_FLAG_DUP) != 0)) {
size_t len = strlen(errmsg); size_t len = strlen(errmsg);
char *copy = LIBSSH2_ALLOC(session, len + 1); char *copy = LIBSSH2_ALLOC(session, len + 1);
if (copy) { if(copy) {
memcpy(copy, errmsg, len + 1); memcpy(copy, errmsg, len + 1);
session->err_flags = LIBSSH2_ERR_FLAG_DUP; session->err_flags = LIBSSH2_ERR_FLAG_DUP;
session->err_msg = copy; session->err_msg = copy;
@@ -86,7 +98,7 @@ int _libssh2_error_flags(LIBSSH2_SESSION* session, int errcode, const char* errm
return errcode; return errcode;
} }
int _libssh2_error(LIBSSH2_SESSION* session, int errcode, const char* errmsg) int _libssh2_error(LIBSSH2_SESSION* session, int errcode, const char *errmsg)
{ {
return _libssh2_error_flags(session, errcode, errmsg, 0); return _libssh2_error_flags(session, errcode, errmsg, 0);
} }
@@ -94,7 +106,7 @@ int _libssh2_error(LIBSSH2_SESSION* session, int errcode, const char* errmsg)
#ifdef WIN32 #ifdef WIN32
static int wsa2errno(void) static int wsa2errno(void)
{ {
switch (WSAGetLastError()) { switch(WSAGetLastError()) {
case WSAEWOULDBLOCK: case WSAEWOULDBLOCK:
return EAGAIN; return EAGAIN;
@@ -127,20 +139,20 @@ _libssh2_recv(libssh2_socket_t sock, void *buffer, size_t length,
rc = recv(sock, buffer, length, flags); rc = recv(sock, buffer, length, flags);
#ifdef WIN32 #ifdef WIN32
if (rc < 0 ) if(rc < 0)
return -wsa2errno(); return -wsa2errno();
#elif defined(__VMS) #elif defined(__VMS)
if (rc < 0 ){ if(rc < 0) {
if ( errno == EWOULDBLOCK ) if(errno == EWOULDBLOCK)
return -EAGAIN; return -EAGAIN;
else else
return -errno; return -errno;
} }
#else #else
if (rc < 0 ){ if(rc < 0) {
/* Sometimes the first recv() function call sets errno to ENOENT on /* Sometimes the first recv() function call sets errno to ENOENT on
Solaris and HP-UX */ Solaris and HP-UX */
if ( errno == ENOENT ) if(errno == ENOENT)
return -EAGAIN; return -EAGAIN;
else else
return -errno; return -errno;
@@ -163,17 +175,17 @@ _libssh2_send(libssh2_socket_t sock, const void *buffer, size_t length,
rc = send(sock, buffer, length, flags); rc = send(sock, buffer, length, flags);
#ifdef WIN32 #ifdef WIN32
if (rc < 0 ) if(rc < 0)
return -wsa2errno(); return -wsa2errno();
#elif defined(__VMS) #elif defined(__VMS)
if (rc < 0 ) { if(rc < 0) {
if ( errno == EWOULDBLOCK ) if(errno == EWOULDBLOCK)
return -EAGAIN; return -EAGAIN;
else else
return -errno; return -errno;
} }
#else #else
if (rc < 0 ) if(rc < 0)
return -errno; return -errno;
#endif #endif
return rc; return rc;
@@ -269,15 +281,16 @@ libssh2_base64_decode(LIBSSH2_SESSION *session, char **data,
*data = LIBSSH2_ALLOC(session, (3 * src_len / 4) + 1); *data = LIBSSH2_ALLOC(session, (3 * src_len / 4) + 1);
d = (unsigned char *) *data; d = (unsigned char *) *data;
if (!d) { if(!d) {
return _libssh2_error(session, LIBSSH2_ERROR_ALLOC, return _libssh2_error(session, LIBSSH2_ERROR_ALLOC,
"Unable to allocate memory for base64 decoding"); "Unable to allocate memory for base64 decoding");
} }
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:
d[len] = (unsigned char)(v << 2); d[len] = (unsigned char)(v << 2);
break; break;
@@ -295,10 +308,11 @@ libssh2_base64_decode(LIBSSH2_SESSION *session, char **data,
} }
i++; i++;
} }
if ((i % 4) == 1) { if((i % 4) == 1) {
/* 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,17 +343,18 @@ 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);
base64data = output = LIBSSH2_ALLOC(session, insize*4/3+4); base64data = output = LIBSSH2_ALLOC(session, insize * 4 / 3 + 4);
if(NULL == output) if(NULL == output)
return 0; return 0;
while(insize > 0) { while(insize > 0) {
for (i = inputparts = 0; i < 3; i++) { for(i = inputparts = 0; i < 3; i++) {
if(insize > 0) { if(insize > 0) {
inputparts++; inputparts++;
ibuf[i] = *indata; ibuf[i] = *indata;
@@ -374,12 +389,12 @@ size_t _libssh2_base64_encode(LIBSSH2_SESSION *session,
table64[obuf[0]], table64[obuf[0]],
table64[obuf[1]], table64[obuf[1]],
table64[obuf[2]], table64[obuf[2]],
table64[obuf[3]] ); table64[obuf[3]]);
break; break;
} }
output += 4; output += 4;
} }
*output=0; *output = 0;
*outptr = base64data; /* make it return the actual data memory */ *outptr = base64data; /* make it return the actual data memory */
return strlen(base64data); /* return the length of the new data */ return strlen(base64data); /* return the length of the new data */
@@ -403,7 +418,7 @@ libssh2_trace(LIBSSH2_SESSION * session, int bitmask)
} }
LIBSSH2_API int LIBSSH2_API int
libssh2_trace_sethandler(LIBSSH2_SESSION *session, void* handler_context, libssh2_trace_sethandler(LIBSSH2_SESSION *session, void *handler_context,
libssh2_trace_handler_func callback) libssh2_trace_handler_func callback)
{ {
session->tracehandler = callback; session->tracehandler = callback;
@@ -431,18 +446,18 @@ _libssh2_debug(LIBSSH2_SESSION * session, int context, const char *format, ...)
"Publickey", "Publickey",
"Socket", "Socket",
}; };
const char* contexttext = contexts[0]; const char *contexttext = contexts[0];
unsigned int contextindex; unsigned int contextindex;
if (!(session->showmask & context)) { if(!(session->showmask & context)) {
/* no such output asked for */ /* no such output asked for */
return; return;
} }
/* Find the first matching context string for this message */ /* Find the first matching context string for this message */
for (contextindex = 0; contextindex < ARRAY_SIZE(contexts); for(contextindex = 0; contextindex < ARRAY_SIZE(contexts);
contextindex++) { contextindex++) {
if ((context & (1 << contextindex)) != 0) { if((context & (1 << contextindex)) != 0) {
contexttext = contexts[contextindex]; contexttext = contexts[contextindex];
break; break;
} }
@@ -457,7 +472,7 @@ _libssh2_debug(LIBSSH2_SESSION * session, int context, const char *format, ...)
len = snprintf(buffer, buflen, "[libssh2] %d.%06d %s: ", len = snprintf(buffer, buflen, "[libssh2] %d.%06d %s: ",
(int)now.tv_sec, (int)now.tv_usec, contexttext); (int)now.tv_sec, (int)now.tv_usec, contexttext);
if (len >= buflen) if(len >= buflen)
msglen = buflen - 1; msglen = buflen - 1;
else { else {
buflen -= len; buflen -= len;
@@ -468,7 +483,7 @@ _libssh2_debug(LIBSSH2_SESSION * session, int context, const char *format, ...)
msglen += len < buflen ? len : buflen - 1; msglen += len < buflen ? len : buflen - 1;
} }
if (session->tracehandler) if(session->tracehandler)
(session->tracehandler)(session, session->tracehandler_context, buffer, (session->tracehandler)(session, session->tracehandler_context, buffer,
msglen); msglen);
else else
@@ -485,7 +500,7 @@ libssh2_trace(LIBSSH2_SESSION * session, int bitmask)
} }
LIBSSH2_API int LIBSSH2_API int
libssh2_trace_sethandler(LIBSSH2_SESSION *session, void* handler_context, libssh2_trace_sethandler(LIBSSH2_SESSION *session, void *handler_context,
libssh2_trace_handler_func callback) libssh2_trace_handler_func callback)
{ {
(void) session; (void) session;
@@ -615,17 +630,16 @@ void _libssh2_list_insert(struct list_node *after, /* insert before this */
#define _W32_FT_OFFSET (116444736000000000) #define _W32_FT_OFFSET (116444736000000000)
int __cdecl _libssh2_gettimeofday(struct timeval *tp, void *tzp) int __cdecl _libssh2_gettimeofday(struct timeval *tp, void *tzp)
{ {
union { union {
unsigned __int64 ns100; /*time since 1 Jan 1601 in 100ns units */ unsigned __int64 ns100; /*time since 1 Jan 1601 in 100ns units */
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);
} }
/* Always return 0 as per Open Group Base Specifications Issue 6. /* Always return 0 as per Open Group Base Specifications Issue 6.
Do not set errno on error. */ Do not set errno on error. */
@@ -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,8 +49,15 @@ 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 {
int _libssh2_error(LIBSSH2_SESSION* session, int errcode, const char* errmsg); 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);
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);
@@ -78,7 +85,22 @@ libssh2_uint64_t _libssh2_ntohu64(const unsigned char *buf);
void _libssh2_htonu32(unsigned char *buf, uint32_t val); 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

@@ -87,7 +87,7 @@ packet_queue_listener(LIBSSH2_SESSION * session, unsigned char *data,
(void) datalen; (void) datalen;
if (listen_state->state == libssh2_NB_state_idle) { if(listen_state->state == libssh2_NB_state_idle) {
unsigned char *s = data + (sizeof("forwarded-tcpip") - 1) + 5; unsigned char *s = data + (sizeof("forwarded-tcpip") - 1) + 5;
listen_state->sender_channel = _libssh2_ntohu32(s); listen_state->sender_channel = _libssh2_ntohu32(s);
s += 4; s += 4;
@@ -118,9 +118,9 @@ packet_queue_listener(LIBSSH2_SESSION * session, unsigned char *data,
listen_state->state = libssh2_NB_state_allocated; listen_state->state = libssh2_NB_state_allocated;
} }
if (listen_state->state != libssh2_NB_state_sent) { if(listen_state->state != libssh2_NB_state_sent) {
while (listn) { while(listn) {
if ((listn->port == (int) listen_state->port) && if((listn->port == (int) listen_state->port) &&
(strlen(listn->host) == listen_state->host_len) && (strlen(listn->host) == listen_state->host_len) &&
(memcmp (listn->host, listen_state->host, (memcmp (listn->host, listen_state->host,
listen_state->host_len) == 0)) { listen_state->host_len) == 0)) {
@@ -128,8 +128,8 @@ packet_queue_listener(LIBSSH2_SESSION * session, unsigned char *data,
LIBSSH2_CHANNEL *channel = NULL; LIBSSH2_CHANNEL *channel = NULL;
listen_state->channel = NULL; listen_state->channel = NULL;
if (listen_state->state == libssh2_NB_state_allocated) { if(listen_state->state == libssh2_NB_state_allocated) {
if (listn->queue_maxsize && if(listn->queue_maxsize &&
(listn->queue_maxsize <= listn->queue_size)) { (listn->queue_maxsize <= listn->queue_size)) {
/* Queue is full */ /* Queue is full */
failure_code = SSH_OPEN_RESOURCE_SHORTAGE; failure_code = SSH_OPEN_RESOURCE_SHORTAGE;
@@ -140,7 +140,7 @@ packet_queue_listener(LIBSSH2_SESSION * session, unsigned char *data,
} }
channel = LIBSSH2_CALLOC(session, sizeof(LIBSSH2_CHANNEL)); channel = LIBSSH2_CALLOC(session, sizeof(LIBSSH2_CHANNEL));
if (!channel) { if(!channel) {
_libssh2_error(session, LIBSSH2_ERROR_ALLOC, _libssh2_error(session, LIBSSH2_ERROR_ALLOC,
"Unable to allocate a channel for " "Unable to allocate a channel for "
"new connection"); "new connection");
@@ -156,7 +156,7 @@ packet_queue_listener(LIBSSH2_SESSION * session, unsigned char *data,
channel-> channel->
channel_type_len + channel_type_len +
1); 1);
if (!channel->channel_type) { if(!channel->channel_type) {
_libssh2_error(session, LIBSSH2_ERROR_ALLOC, _libssh2_error(session, LIBSSH2_ERROR_ALLOC,
"Unable to allocate a channel for new" "Unable to allocate a channel for new"
" connection"); " connection");
@@ -203,12 +203,12 @@ packet_queue_listener(LIBSSH2_SESSION * session, unsigned char *data,
listen_state->state = libssh2_NB_state_created; listen_state->state = libssh2_NB_state_created;
} }
if (listen_state->state == libssh2_NB_state_created) { if(listen_state->state == libssh2_NB_state_created) {
rc = _libssh2_transport_send(session, listen_state->packet, rc = _libssh2_transport_send(session, listen_state->packet,
17, NULL, 0); 17, 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, return _libssh2_error(session, rc,
"Unable to send channel " "Unable to send channel "
@@ -216,7 +216,7 @@ packet_queue_listener(LIBSSH2_SESSION * session, unsigned char *data,
} }
/* Link the channel into the end of the queue list */ /* Link the channel into the end of the queue list */
if (listen_state->channel) { if(listen_state->channel) {
_libssh2_list_add(&listn->queue, _libssh2_list_add(&listn->queue,
&listen_state->channel->node); &listen_state->channel->node);
listn->queue_size++; listn->queue_size++;
@@ -243,9 +243,10 @@ packet_queue_listener(LIBSSH2_SESSION * session, unsigned char *data,
rc = _libssh2_transport_send(session, listen_state->packet, rc = _libssh2_transport_send(session, listen_state->packet,
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");
@@ -273,7 +274,7 @@ packet_x11_open(LIBSSH2_SESSION * session, unsigned char *data,
(void) datalen; (void) datalen;
if (x11open_state->state == libssh2_NB_state_idle) { if(x11open_state->state == libssh2_NB_state_idle) {
unsigned char *s = data + (sizeof("x11") - 1) + 5; unsigned char *s = data + (sizeof("x11") - 1) + 5;
x11open_state->sender_channel = _libssh2_ntohu32(s); x11open_state->sender_channel = _libssh2_ntohu32(s);
s += 4; s += 4;
@@ -295,10 +296,10 @@ packet_x11_open(LIBSSH2_SESSION * session, unsigned char *data,
x11open_state->state = libssh2_NB_state_allocated; x11open_state->state = libssh2_NB_state_allocated;
} }
if (session->x11) { if(session->x11) {
if (x11open_state->state == libssh2_NB_state_allocated) { if(x11open_state->state == libssh2_NB_state_allocated) {
channel = LIBSSH2_CALLOC(session, sizeof(LIBSSH2_CHANNEL)); channel = LIBSSH2_CALLOC(session, sizeof(LIBSSH2_CHANNEL));
if (!channel) { if(!channel) {
_libssh2_error(session, LIBSSH2_ERROR_ALLOC, _libssh2_error(session, LIBSSH2_ERROR_ALLOC,
"allocate a channel for new connection"); "allocate a channel for new connection");
failure_code = SSH_OPEN_RESOURCE_SHORTAGE; failure_code = SSH_OPEN_RESOURCE_SHORTAGE;
@@ -310,7 +311,7 @@ packet_x11_open(LIBSSH2_SESSION * session, unsigned char *data,
channel->channel_type = LIBSSH2_ALLOC(session, channel->channel_type = LIBSSH2_ALLOC(session,
channel->channel_type_len + channel->channel_type_len +
1); 1);
if (!channel->channel_type) { if(!channel->channel_type) {
_libssh2_error(session, LIBSSH2_ERROR_ALLOC, _libssh2_error(session, LIBSSH2_ERROR_ALLOC,
"allocate a channel for new connection"); "allocate a channel for new connection");
LIBSSH2_FREE(session, channel); LIBSSH2_FREE(session, channel);
@@ -350,12 +351,13 @@ packet_x11_open(LIBSSH2_SESSION * session, unsigned char *data,
x11open_state->state = libssh2_NB_state_created; x11open_state->state = libssh2_NB_state_created;
} }
if (x11open_state->state == libssh2_NB_state_created) { if(x11open_state->state == libssh2_NB_state_created) {
rc = _libssh2_transport_send(session, x11open_state->packet, 17, rc = _libssh2_transport_send(session, x11open_state->packet, 17,
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 "
@@ -389,9 +391,10 @@ packet_x11_open(LIBSSH2_SESSION * session, unsigned char *data,
rc = _libssh2_transport_send(session, x11open_state->packet, packet_len, rc = _libssh2_transport_send(session, x11open_state->packet, packet_len,
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");
} }
@@ -416,10 +419,10 @@ _libssh2_packet_add(LIBSSH2_SESSION * session, unsigned char *data,
size_t datalen, int macstate) size_t datalen, int macstate)
{ {
int rc = 0; int rc = 0;
char *message=NULL; char *message = NULL;
char *language=NULL; char *language = NULL;
size_t message_len=0; size_t message_len = 0;
size_t language_len=0; size_t language_len = 0;
LIBSSH2_CHANNEL *channelp = NULL; LIBSSH2_CHANNEL *channelp = NULL;
size_t data_head = 0; size_t data_head = 0;
unsigned char msg = data[0]; unsigned char msg = data[0];
@@ -430,7 +433,7 @@ _libssh2_packet_add(LIBSSH2_SESSION * session, unsigned char *data,
"Packet type %d received, length=%d", "Packet type %d received, length=%d",
(int) msg, (int) datalen); (int) msg, (int) datalen);
if ((macstate == LIBSSH2_MAC_INVALID) && if((macstate == LIBSSH2_MAC_INVALID) &&
(!session->macerror || (!session->macerror ||
LIBSSH2_MACERROR(session, (char *) data, datalen))) { LIBSSH2_MACERROR(session, (char *) data, datalen))) {
/* Bad MAC input, but no callback set or non-zero return from the /* Bad MAC input, but no callback set or non-zero return from the
@@ -456,9 +459,9 @@ _libssh2_packet_add(LIBSSH2_SESSION * session, unsigned char *data,
break; break;
} }
if (session->packAdd_state == libssh2_NB_state_allocated) { if(session->packAdd_state == libssh2_NB_state_allocated) {
/* A couple exceptions to the packet adding rule: */ /* A couple exceptions to the packet adding rule: */
switch (msg) { switch(msg) {
/* /*
byte SSH_MSG_DISCONNECT byte SSH_MSG_DISCONNECT
@@ -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)) {
@@ -489,9 +493,9 @@ _libssh2_packet_add(LIBSSH2_SESSION * session, unsigned char *data,
} }
else else
/* bad size, clear it */ /* bad size, clear it */
message_len=0; message_len = 0;
} }
if (session->ssh_msg_disconnect) { if(session->ssh_msg_disconnect) {
LIBSSH2_DISCONNECT(session, reason, message, LIBSSH2_DISCONNECT(session, reason, message,
message_len, language, language_len); message_len, language, language_len);
} }
@@ -511,11 +515,12 @@ _libssh2_packet_add(LIBSSH2_SESSION * session, unsigned char *data,
*/ */
case SSH_MSG_IGNORE: case SSH_MSG_IGNORE:
if (datalen >= 2) { if(datalen >= 2) {
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);
@@ -531,7 +536,7 @@ _libssh2_packet_add(LIBSSH2_SESSION * session, unsigned char *data,
case SSH_MSG_DEBUG: case SSH_MSG_DEBUG:
if(datalen >= 2) { if(datalen >= 2) {
int always_display= data[1]; int always_display = data[1];
if(datalen >= 6) { if(datalen >= 6) {
message_len = _libssh2_ntohu32(data + 2); message_len = _libssh2_ntohu32(data + 2);
@@ -539,14 +544,15 @@ _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;
} }
} }
if (session->ssh_msg_debug) { if(session->ssh_msg_debug) {
LIBSSH2_DEBUG(session, always_display, message, LIBSSH2_DEBUG(session, always_display, message,
message_len, language, language_len); message_len, language, language_len);
} }
@@ -570,8 +576,8 @@ _libssh2_packet_add(LIBSSH2_SESSION * session, unsigned char *data,
case SSH_MSG_GLOBAL_REQUEST: case SSH_MSG_GLOBAL_REQUEST:
if(datalen >= 5) { if(datalen >= 5) {
uint32_t len =0; uint32_t len = 0;
unsigned char want_reply=0; unsigned char want_reply = 0;
len = _libssh2_ntohu32(data + 1); len = _libssh2_ntohu32(data + 1);
if(datalen >= (6 + len)) { if(datalen >= (6 + len)) {
want_reply = data[5 + len]; want_reply = data[5 + len];
@@ -582,13 +588,13 @@ _libssh2_packet_add(LIBSSH2_SESSION * session, unsigned char *data,
} }
if (want_reply) { if(want_reply) {
static const unsigned char packet = static const unsigned char packet =
SSH_MSG_REQUEST_FAILURE; SSH_MSG_REQUEST_FAILURE;
libssh2_packet_add_jump_point5: libssh2_packet_add_jump_point5:
session->packAdd_state = libssh2_NB_state_jump5; session->packAdd_state = libssh2_NB_state_jump5;
rc = _libssh2_transport_send(session, &packet, 1, NULL, 0); rc = _libssh2_transport_send(session, &packet, 1, NULL, 0);
if (rc == LIBSSH2_ERROR_EAGAIN) if(rc == LIBSSH2_ERROR_EAGAIN)
return rc; return rc;
} }
} }
@@ -624,7 +630,7 @@ _libssh2_packet_add(LIBSSH2_SESSION * session, unsigned char *data,
_libssh2_channel_locate(session, _libssh2_channel_locate(session,
_libssh2_ntohu32(data + 1)); _libssh2_ntohu32(data + 1));
if (!channelp) { if(!channelp) {
_libssh2_error(session, LIBSSH2_ERROR_CHANNEL_UNKNOWN, _libssh2_error(session, LIBSSH2_ERROR_CHANNEL_UNKNOWN,
"Packet received for unknown channel"); "Packet received for unknown channel");
LIBSSH2_FREE(session, data); LIBSSH2_FREE(session, data);
@@ -634,7 +640,7 @@ _libssh2_packet_add(LIBSSH2_SESSION * session, unsigned char *data,
#ifdef LIBSSH2DEBUG #ifdef LIBSSH2DEBUG
{ {
uint32_t stream_id = 0; uint32_t stream_id = 0;
if (msg == SSH_MSG_CHANNEL_EXTENDED_DATA) if(msg == SSH_MSG_CHANNEL_EXTENDED_DATA)
stream_id = _libssh2_ntohu32(data + 5); stream_id = _libssh2_ntohu32(data + 5);
_libssh2_debug(session, LIBSSH2_TRACE_CONN, _libssh2_debug(session, LIBSSH2_TRACE_CONN,
@@ -645,7 +651,7 @@ _libssh2_packet_add(LIBSSH2_SESSION * session, unsigned char *data,
stream_id); stream_id);
} }
#endif #endif
if ((channelp->remote.extended_data_ignore_mode == if((channelp->remote.extended_data_ignore_mode ==
LIBSSH2_CHANNEL_EXTENDED_DATA_IGNORE) && LIBSSH2_CHANNEL_EXTENDED_DATA_IGNORE) &&
(msg == SSH_MSG_CHANNEL_EXTENDED_DATA)) { (msg == SSH_MSG_CHANNEL_EXTENDED_DATA)) {
/* Pretend we didn't receive this */ /* Pretend we didn't receive this */
@@ -654,14 +660,15 @@ _libssh2_packet_add(LIBSSH2_SESSION * session, unsigned char *data,
_libssh2_debug(session, LIBSSH2_TRACE_CONN, _libssh2_debug(session, LIBSSH2_TRACE_CONN,
"Ignoring extended data and refunding %d bytes", "Ignoring extended data and refunding %d bytes",
(int) (datalen - 13)); (int) (datalen - 13));
if (channelp->read_avail + datalen - data_head >= if(channelp->read_avail + datalen - data_head >=
channelp->remote.window_size) channelp->remote.window_size)
datalen = channelp->remote.window_size - datalen = channelp->remote.window_size -
channelp->read_avail + data_head; channelp->read_avail + data_head;
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);
@@ -675,7 +682,7 @@ _libssh2_packet_add(LIBSSH2_SESSION * session, unsigned char *data,
packAdd_channelp, packAdd_channelp,
datalen - 13, datalen - 13,
1, NULL); 1, NULL);
if (rc == LIBSSH2_ERROR_EAGAIN) if(rc == LIBSSH2_ERROR_EAGAIN)
return rc; return rc;
session->packAdd_state = libssh2_NB_state_idle; session->packAdd_state = libssh2_NB_state_idle;
@@ -686,7 +693,7 @@ _libssh2_packet_add(LIBSSH2_SESSION * session, unsigned char *data,
* REMEMBER! remote means remote as source of data, * REMEMBER! remote means remote as source of data,
* NOT remote window! * NOT remote window!
*/ */
if (channelp->remote.packet_size < (datalen - data_head)) { if(channelp->remote.packet_size < (datalen - data_head)) {
/* /*
* Spec says we MAY ignore bytes sent beyond * Spec says we MAY ignore bytes sent beyond
* packet_size * packet_size
@@ -697,7 +704,7 @@ _libssh2_packet_add(LIBSSH2_SESSION * session, unsigned char *data,
" to receive, truncating"); " to receive, truncating");
datalen = channelp->remote.packet_size + data_head; datalen = channelp->remote.packet_size + data_head;
} }
if (channelp->remote.window_size <= channelp->read_avail) { if(channelp->remote.window_size <= channelp->read_avail) {
/* /*
* Spec says we MAY ignore bytes sent beyond * Spec says we MAY ignore bytes sent beyond
* window_size * window_size
@@ -713,7 +720,7 @@ _libssh2_packet_add(LIBSSH2_SESSION * session, unsigned char *data,
/* Reset EOF status */ /* Reset EOF status */
channelp->remote.eof = 0; channelp->remote.eof = 0;
if (channelp->read_avail + datalen - data_head > if(channelp->read_avail + datalen - data_head >
channelp->remote.window_size) { channelp->remote.window_size) {
_libssh2_error(session, _libssh2_error(session,
LIBSSH2_ERROR_CHANNEL_WINDOW_EXCEEDED, LIBSSH2_ERROR_CHANNEL_WINDOW_EXCEEDED,
@@ -746,7 +753,7 @@ _libssh2_packet_add(LIBSSH2_SESSION * session, unsigned char *data,
channelp = channelp =
_libssh2_channel_locate(session, _libssh2_channel_locate(session,
_libssh2_ntohu32(data + 1)); _libssh2_ntohu32(data + 1));
if (!channelp) if(!channelp)
/* We may have freed already, just quietly ignore this... */ /* We may have freed already, just quietly ignore this... */
; ;
else { else {
@@ -783,7 +790,7 @@ _libssh2_packet_add(LIBSSH2_SESSION * session, unsigned char *data,
"Channel %d received request type %.*s (wr %X)", "Channel %d received request type %.*s (wr %X)",
channel, len, data + 9, want_reply); channel, len, data + 9, want_reply);
if (len == sizeof("exit-status") - 1 if(len == sizeof("exit-status") - 1
&& (sizeof("exit-status") - 1 + 9) <= datalen && (sizeof("exit-status") - 1 + 9) <= datalen
&& !memcmp("exit-status", data + 9, && !memcmp("exit-status", data + 9,
sizeof("exit-status") - 1)) { sizeof("exit-status") - 1)) {
@@ -793,7 +800,7 @@ _libssh2_packet_add(LIBSSH2_SESSION * session, unsigned char *data,
channelp = channelp =
_libssh2_channel_locate(session, channel); _libssh2_channel_locate(session, channel);
if (channelp && (sizeof("exit-status") + 13) <= datalen) { if(channelp && (sizeof("exit-status") + 13) <= datalen) {
channelp->exit_status = channelp->exit_status =
_libssh2_ntohu32(data + 9 + sizeof("exit-status")); _libssh2_ntohu32(data + 9 + sizeof("exit-status"));
_libssh2_debug(session, LIBSSH2_TRACE_CONN, _libssh2_debug(session, LIBSSH2_TRACE_CONN,
@@ -805,7 +812,7 @@ _libssh2_packet_add(LIBSSH2_SESSION * session, unsigned char *data,
} }
} }
else if (len == sizeof("exit-signal") - 1 else if(len == sizeof("exit-signal") - 1
&& (sizeof("exit-signal") - 1 + 9) <= datalen && (sizeof("exit-signal") - 1 + 9) <= datalen
&& !memcmp("exit-signal", data + 9, && !memcmp("exit-signal", data + 9,
sizeof("exit-signal") - 1)) { sizeof("exit-signal") - 1)) {
@@ -813,7 +820,7 @@ _libssh2_packet_add(LIBSSH2_SESSION * session, unsigned char *data,
if(datalen >= 20) if(datalen >= 20)
channelp = _libssh2_channel_locate(session, channel); channelp = _libssh2_channel_locate(session, channel);
if (channelp && (sizeof("exit-signal") + 13) <= datalen) { if(channelp && (sizeof("exit-signal") + 13) <= datalen) {
/* set signal name (without SIG prefix) */ /* set signal name (without SIG prefix) */
uint32_t namelen = uint32_t namelen =
_libssh2_ntohu32(data + 9 + sizeof("exit-signal")); _libssh2_ntohu32(data + 9 + sizeof("exit-signal"));
@@ -826,10 +833,11 @@ _libssh2_packet_add(LIBSSH2_SESSION * session, unsigned char *data,
channelp->exit_signal = NULL; channelp->exit_signal = NULL;
} }
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';
@@ -845,14 +853,14 @@ _libssh2_packet_add(LIBSSH2_SESSION * session, unsigned char *data,
} }
if (want_reply) { if(want_reply) {
unsigned char packet[5]; unsigned char packet[5];
libssh2_packet_add_jump_point4: libssh2_packet_add_jump_point4:
session->packAdd_state = libssh2_NB_state_jump4; session->packAdd_state = libssh2_NB_state_jump4;
packet[0] = SSH_MSG_CHANNEL_FAILURE; packet[0] = SSH_MSG_CHANNEL_FAILURE;
memcpy(&packet[1], data+1, 4); memcpy(&packet[1], data + 1, 4);
rc = _libssh2_transport_send(session, packet, 5, NULL, 0); rc = _libssh2_transport_send(session, packet, 5, NULL, 0);
if (rc == LIBSSH2_ERROR_EAGAIN) if(rc == LIBSSH2_ERROR_EAGAIN)
return rc; return rc;
} }
} }
@@ -870,7 +878,7 @@ _libssh2_packet_add(LIBSSH2_SESSION * session, unsigned char *data,
channelp = channelp =
_libssh2_channel_locate(session, _libssh2_channel_locate(session,
_libssh2_ntohu32(data + 1)); _libssh2_ntohu32(data + 1));
if (!channelp) { if(!channelp) {
/* We may have freed already, just quietly ignore this... */ /* We may have freed already, just quietly ignore this... */
LIBSSH2_FREE(session, data); LIBSSH2_FREE(session, data);
session->packAdd_state = libssh2_NB_state_idle; session->packAdd_state = libssh2_NB_state_idle;
@@ -899,7 +907,7 @@ _libssh2_packet_add(LIBSSH2_SESSION * session, unsigned char *data,
case SSH_MSG_CHANNEL_OPEN: case SSH_MSG_CHANNEL_OPEN:
if(datalen < 17) if(datalen < 17)
; ;
else if ((datalen >= (sizeof("forwarded-tcpip") + 4)) && else if((datalen >= (sizeof("forwarded-tcpip") + 4)) &&
((sizeof("forwarded-tcpip") - 1) == ((sizeof("forwarded-tcpip") - 1) ==
_libssh2_ntohu32(data + 1)) _libssh2_ntohu32(data + 1))
&& &&
@@ -915,7 +923,7 @@ _libssh2_packet_add(LIBSSH2_SESSION * session, unsigned char *data,
rc = packet_queue_listener(session, data, datalen, rc = packet_queue_listener(session, data, datalen,
&session->packAdd_Qlstn_state); &session->packAdd_Qlstn_state);
} }
else if ((datalen >= (sizeof("x11") + 4)) && else if((datalen >= (sizeof("x11") + 4)) &&
((sizeof("x11") - 1) == _libssh2_ntohu32(data + 1)) && ((sizeof("x11") - 1) == _libssh2_ntohu32(data + 1)) &&
(memcmp(data + 5, "x11", sizeof("x11") - 1) == 0)) { (memcmp(data + 5, "x11", sizeof("x11") - 1) == 0)) {
@@ -928,7 +936,7 @@ _libssh2_packet_add(LIBSSH2_SESSION * session, unsigned char *data,
rc = packet_x11_open(session, data, datalen, rc = packet_x11_open(session, data, datalen,
&session->packAdd_x11open_state); &session->packAdd_x11open_state);
} }
if (rc == LIBSSH2_ERROR_EAGAIN) if(rc == LIBSSH2_ERROR_EAGAIN)
return rc; return rc;
LIBSSH2_FREE(session, data); LIBSSH2_FREE(session, data);
@@ -970,10 +978,10 @@ _libssh2_packet_add(LIBSSH2_SESSION * session, unsigned char *data,
session->packAdd_state = libssh2_NB_state_sent; session->packAdd_state = libssh2_NB_state_sent;
} }
if (session->packAdd_state == libssh2_NB_state_sent) { if(session->packAdd_state == libssh2_NB_state_sent) {
LIBSSH2_PACKET *packetp = LIBSSH2_PACKET *packetp =
LIBSSH2_ALLOC(session, sizeof(LIBSSH2_PACKET)); LIBSSH2_ALLOC(session, sizeof(LIBSSH2_PACKET));
if (!packetp) { if(!packetp) {
_libssh2_debug(session, LIBSSH2_ERROR_ALLOC, _libssh2_debug(session, LIBSSH2_ERROR_ALLOC,
"memory for packet"); "memory for packet");
LIBSSH2_FREE(session, data); LIBSSH2_FREE(session, data);
@@ -989,10 +997,10 @@ _libssh2_packet_add(LIBSSH2_SESSION * session, unsigned char *data,
session->packAdd_state = libssh2_NB_state_sent1; session->packAdd_state = libssh2_NB_state_sent1;
} }
if ((msg == SSH_MSG_KEXINIT && if((msg == SSH_MSG_KEXINIT &&
!(session->state & LIBSSH2_STATE_EXCHANGING_KEYS)) || !(session->state & LIBSSH2_STATE_EXCHANGING_KEYS)) ||
(session->packAdd_state == libssh2_NB_state_sent2)) { (session->packAdd_state == libssh2_NB_state_sent2)) {
if (session->packAdd_state == libssh2_NB_state_sent1) { if(session->packAdd_state == libssh2_NB_state_sent1) {
/* /*
* Remote wants new keys * Remote wants new keys
* Well, it's already in the brigade, * Well, it's already in the brigade,
@@ -1021,7 +1029,7 @@ _libssh2_packet_add(LIBSSH2_SESSION * session, unsigned char *data,
* send NEWKEYS yet, otherwise remote will drop us like a rock * send NEWKEYS yet, otherwise remote will drop us like a rock
*/ */
rc = _libssh2_kex_exchange(session, 1, &session->startup_key_state); rc = _libssh2_kex_exchange(session, 1, &session->startup_key_state);
if (rc == LIBSSH2_ERROR_EAGAIN) if(rc == LIBSSH2_ERROR_EAGAIN)
return rc; return rc;
} }
@@ -1046,8 +1054,8 @@ _libssh2_packet_ask(LIBSSH2_SESSION * session, unsigned char packet_type,
_libssh2_debug(session, LIBSSH2_TRACE_TRANS, _libssh2_debug(session, LIBSSH2_TRACE_TRANS,
"Looking for packet of type: %d", (int) packet_type); "Looking for packet of type: %d", (int) packet_type);
while (packet) { while(packet) {
if (packet->data[0] == packet_type if(packet->data[0] == packet_type
&& (packet->data_len >= (match_ofs + match_len)) && (packet->data_len >= (match_ofs + match_len))
&& (!match_buf || && (!match_buf ||
(memcmp(packet->data + match_ofs, match_buf, (memcmp(packet->data + match_ofs, match_buf,
@@ -1084,7 +1092,7 @@ _libssh2_packet_askv(LIBSSH2_SESSION * session,
int i, packet_types_len = strlen((char *) packet_types); int i, packet_types_len = strlen((char *) packet_types);
for(i = 0; i < packet_types_len; i++) { for(i = 0; i < packet_types_len; i++) {
if (0 == _libssh2_packet_ask(session, packet_types[i], data, if(0 == _libssh2_packet_ask(session, packet_types[i], data,
data_len, match_ofs, data_len, match_ofs,
match_buf, match_len)) { match_buf, match_len)) {
return 0; return 0;
@@ -1111,8 +1119,8 @@ _libssh2_packet_require(LIBSSH2_SESSION * session, unsigned char packet_type,
size_t match_len, size_t match_len,
packet_require_state_t *state) packet_require_state_t *state)
{ {
if (state->start == 0) { if(state->start == 0) {
if (_libssh2_packet_ask(session, packet_type, data, data_len, if(_libssh2_packet_ask(session, packet_type, data, data_len,
match_ofs, match_buf, match_ofs, match_buf,
match_len) == 0) { match_len) == 0) {
/* A packet was available in the packet brigade */ /* A packet was available in the packet brigade */
@@ -1122,26 +1130,28 @@ _libssh2_packet_require(LIBSSH2_SESSION * session, unsigned char packet_type,
state->start = time(NULL); state->start = time(NULL);
} }
while (session->socket_state == LIBSSH2_SOCKET_CONNECTED) { while(session->socket_state == LIBSSH2_SOCKET_CONNECTED) {
int ret = _libssh2_transport_read(session); int 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->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);
if (left <= 0) { if(left <= 0) {
state->start = 0; state->start = 0;
return LIBSSH2_ERROR_TIMEOUT; return LIBSSH2_ERROR_TIMEOUT;
} }
@@ -1169,13 +1179,13 @@ _libssh2_packet_burn(LIBSSH2_SESSION * session,
unsigned char i, all_packets[255]; unsigned char i, all_packets[255];
int ret; int ret;
if (*state == libssh2_NB_state_idle) { if(*state == libssh2_NB_state_idle) {
for(i = 1; i < 255; i++) { for(i = 1; i < 255; i++) {
all_packets[i - 1] = i; all_packets[i - 1] = i;
} }
all_packets[254] = 0; all_packets[254] = 0;
if (_libssh2_packet_askv(session, all_packets, &data, &data_len, 0, if(_libssh2_packet_askv(session, all_packets, &data, &data_len, 0,
NULL, 0) == 0) { NULL, 0) == 0) {
i = data[0]; i = data[0];
/* A packet was available in the packet brigade, burn it */ /* A packet was available in the packet brigade, burn it */
@@ -1188,20 +1198,22 @@ _libssh2_packet_burn(LIBSSH2_SESSION * session,
*state = libssh2_NB_state_created; *state = libssh2_NB_state_created;
} }
while (session->socket_state == LIBSSH2_SOCKET_CONNECTED) { while(session->socket_state == LIBSSH2_SOCKET_CONNECTED) {
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;
} }
/* Be lazy, let packet_ask pull it out of the brigade */ /* Be lazy, let packet_ask pull it out of the brigade */
if (0 == if(0 ==
_libssh2_packet_ask(session, (unsigned char)ret, _libssh2_packet_ask(session, (unsigned char)ret,
&data, &data_len, 0, NULL, 0)) { &data, &data_len, 0, NULL, 0)) {
/* Smoke 'em if you got 'em */ /* Smoke 'em if you got 'em */
@@ -1231,37 +1243,37 @@ _libssh2_packet_requirev(LIBSSH2_SESSION *session,
const unsigned char *match_buf, size_t match_len, const unsigned char *match_buf, size_t match_len,
packet_requirev_state_t * state) packet_requirev_state_t * state)
{ {
if (_libssh2_packet_askv(session, packet_types, data, data_len, match_ofs, if(_libssh2_packet_askv(session, packet_types, data, data_len, match_ofs,
match_buf, match_len) == 0) { match_buf, match_len) == 0) {
/* One of the packets listed was available in the packet brigade */ /* One of the packets listed was available in the packet brigade */
state->start = 0; state->start = 0;
return 0; return 0;
} }
if (state->start == 0) { if(state->start == 0) {
state->start = time(NULL); state->start = time(NULL);
} }
while (session->socket_state != LIBSSH2_SOCKET_DISCONNECTED) { while(session->socket_state != LIBSSH2_SOCKET_DISCONNECTED) {
int ret = _libssh2_transport_read(session); int ret = _libssh2_transport_read(session);
if ((ret < 0) && (ret != LIBSSH2_ERROR_EAGAIN)) { if((ret < 0) && (ret != LIBSSH2_ERROR_EAGAIN)) {
state->start = 0; state->start = 0;
return ret; return ret;
} }
if (ret <= 0) { if(ret <= 0) {
long left = LIBSSH2_READ_TIMEOUT - long left = LIBSSH2_READ_TIMEOUT -
(long)(time(NULL) - state->start); (long)(time(NULL) - state->start);
if (left <= 0) { if(left <= 0) {
state->start = 0; state->start = 0;
return LIBSSH2_ERROR_TIMEOUT; return LIBSSH2_ERROR_TIMEOUT;
} }
else if (ret == LIBSSH2_ERROR_EAGAIN) { else if(ret == LIBSSH2_ERROR_EAGAIN) {
return ret; return ret;
} }
} }
if (strchr((char *) packet_types, ret)) { if(strchr((char *) packet_types, ret)) {
/* Be lazy, let packet_ask pull it out of the brigade */ /* Be lazy, let packet_ask pull it out of the brigade */
return _libssh2_packet_askv(session, packet_types, data, return _libssh2_packet_askv(session, packet_types, data,
data_len, match_ofs, match_buf, data_len, match_ofs, match_buf,

View File

@@ -43,23 +43,23 @@ readline(char *line, int line_size, FILE * fp)
{ {
size_t len; size_t len;
if (!line) { if(!line) {
return -1; return -1;
} }
if (!fgets(line, line_size, fp)) { if(!fgets(line, line_size, fp)) {
return -1; return -1;
} }
if (*line) { if(*line) {
len = strlen(line); len = strlen(line);
if (len > 0 && line[len - 1] == '\n') { if(len > 0 && line[len - 1] == '\n') {
line[len - 1] = '\0'; line[len - 1] = '\0';
} }
} }
if (*line) { if(*line) {
len = strlen(line); len = strlen(line);
if (len > 0 && line[len - 1] == '\r') { if(len > 0 && line[len - 1] == '\r') {
line[len - 1] = '\0'; line[len - 1] = '\0';
} }
} }
@@ -76,14 +76,14 @@ 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;
} }
} }
if (len) { if(len) {
memcpy(line, filedata + off, len); memcpy(line, filedata + off, len);
*filedata_offset += len; *filedata_offset += len;
} }
@@ -96,36 +96,86 @@ 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';
if (readline(line, LINE_SIZE, fp)) { if(readline(line, LINE_SIZE, fp)) {
return -1; return -1;
} }
} }
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) {
char *tmp; char *tmp;
size_t linelen; size_t linelen;
linelen = strlen(line); linelen = strlen(line);
tmp = LIBSSH2_REALLOC(session, b64data, b64datalen + linelen); tmp = LIBSSH2_REALLOC(session, b64data, b64datalen + linelen);
if (!tmp) { if(!tmp) {
ret = -1; ret = -1;
goto out; goto out;
} }
@@ -136,25 +186,102 @@ _libssh2_pem_parse(LIBSSH2_SESSION * session,
*line = '\0'; *line = '\0';
if (readline(line, LINE_SIZE, fp)) { if(readline(line, LINE_SIZE, fp)) {
ret = -1; ret = -1;
goto out; goto out;
} }
} while (strcmp(line, headerend) != 0); } while(strcmp(line, headerend) != 0);
if (!b64data) { if(!b64data) {
return -1; return -1;
} }
if (libssh2_base64_decode(session, (char**) data, datalen, if(libssh2_base64_decode(session, (char **) data, datalen,
b64data, b64datalen)) { b64data, b64datalen)) {
ret = -1; ret = -1;
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;
@@ -176,22 +303,22 @@ _libssh2_pem_parse_memory(LIBSSH2_SESSION * session,
do { do {
*line = '\0'; *line = '\0';
if (readline_memory(line, LINE_SIZE, filedata, filedata_len, &off)) { if(readline_memory(line, LINE_SIZE, filedata, filedata_len, &off)) {
return -1; return -1;
} }
} }
while (strcmp(line, headerbegin) != 0); while(strcmp(line, headerbegin) != 0);
*line = '\0'; *line = '\0';
do { do {
if (*line) { if(*line) {
char *tmp; char *tmp;
size_t linelen; size_t linelen;
linelen = strlen(line); linelen = strlen(line);
tmp = LIBSSH2_REALLOC(session, b64data, b64datalen + linelen); tmp = LIBSSH2_REALLOC(session, b64data, b64datalen + linelen);
if (!tmp) { if(!tmp) {
ret = -1; ret = -1;
goto out; goto out;
} }
@@ -202,17 +329,17 @@ _libssh2_pem_parse_memory(LIBSSH2_SESSION * session,
*line = '\0'; *line = '\0';
if (readline_memory(line, LINE_SIZE, filedata, filedata_len, &off)) { if(readline_memory(line, LINE_SIZE, filedata, filedata_len, &off)) {
ret = -1; ret = -1;
goto out; goto out;
} }
} while (strcmp(line, headerend) != 0); } while(strcmp(line, headerend) != 0);
if (!b64data) { if(!b64data) {
return -1; return -1;
} }
if (libssh2_base64_decode(session, (char**) data, datalen, if(libssh2_base64_decode(session, (char **) data, datalen,
b64data, b64datalen)) { b64data, b64datalen)) {
ret = -1; ret = -1;
goto out; goto out;
@@ -220,12 +347,462 @@ _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)
@@ -233,27 +810,28 @@ read_asn1_length(const unsigned char *data,
unsigned int lenlen; unsigned int lenlen;
int nextpos; int nextpos;
if (datalen < 1) { if(datalen < 1) {
return -1; return -1;
} }
*len = data[0]; *len = data[0];
if (*len >= 0x80) { if(*len >= 0x80) {
lenlen = *len & 0x7F; lenlen = *len & 0x7F;
*len = data[1]; *len = data[1];
if (1 + lenlen > datalen) { if(1 + lenlen > datalen) {
return -1; return -1;
} }
if (lenlen > 1) { if(lenlen > 1) {
*len <<= 8; *len <<= 8;
*len |= data[2]; *len |= data[2];
} }
} else { }
else {
lenlen = 0; lenlen = 0;
} }
nextpos = 1 + lenlen; nextpos = 1 + lenlen;
if (lenlen > 2 || 1 + lenlen + *len > datalen) { if(lenlen > 2 || 1 + lenlen + *len > datalen) {
return -1; return -1;
} }
@@ -266,11 +844,11 @@ _libssh2_pem_decode_sequence(unsigned char **data, unsigned int *datalen)
unsigned int len; unsigned int len;
int lenlen; int lenlen;
if (*datalen < 1) { if(*datalen < 1) {
return -1; return -1;
} }
if ((*data)[0] != '\x30') { if((*data)[0] != '\x30') {
return -1; return -1;
} }
@@ -278,7 +856,7 @@ _libssh2_pem_decode_sequence(unsigned char **data, unsigned int *datalen)
(*datalen)--; (*datalen)--;
lenlen = read_asn1_length(*data, *datalen, &len); lenlen = read_asn1_length(*data, *datalen, &len);
if (lenlen < 0 || lenlen + len != *datalen) { if(lenlen < 0 || lenlen + len != *datalen) {
return -1; return -1;
} }
@@ -295,11 +873,11 @@ _libssh2_pem_decode_integer(unsigned char **data, unsigned int *datalen,
unsigned int len; unsigned int len;
int lenlen; int lenlen;
if (*datalen < 1) { if(*datalen < 1) {
return -1; return -1;
} }
if ((*data)[0] != '\x02') { if((*data)[0] != '\x02') {
return -1; return -1;
} }
@@ -307,7 +885,7 @@ _libssh2_pem_decode_integer(unsigned char **data, unsigned int *datalen,
(*datalen)--; (*datalen)--;
lenlen = read_asn1_length(*data, *datalen, &len); lenlen = read_asn1_length(*data, *datalen, &len);
if (lenlen < 0 || lenlen + len > *datalen) { if(lenlen < 0 || lenlen + len > *datalen) {
return -1; return -1;
} }

View File

@@ -60,7 +60,7 @@ static const LIBSSH2_PUBLICKEY_CODE_LIST publickey_response_codes[] =
{LIBSSH2_PUBLICKEY_RESPONSE_STATUS, "status", sizeof("status") - 1}, {LIBSSH2_PUBLICKEY_RESPONSE_STATUS, "status", sizeof("status") - 1},
{LIBSSH2_PUBLICKEY_RESPONSE_VERSION, "version", sizeof("version") - 1}, {LIBSSH2_PUBLICKEY_RESPONSE_VERSION, "version", sizeof("version") - 1},
{LIBSSH2_PUBLICKEY_RESPONSE_PUBLICKEY, "publickey", {LIBSSH2_PUBLICKEY_RESPONSE_PUBLICKEY, "publickey",
sizeof("publickey") - 1} , sizeof("publickey") - 1},
{0, NULL, 0} {0, NULL, 0}
}; };
@@ -78,13 +78,13 @@ static const LIBSSH2_PUBLICKEY_CODE_LIST publickey_response_codes[] =
#define LIBSSH2_PUBLICKEY_STATUS_CODE_MAX 8 #define LIBSSH2_PUBLICKEY_STATUS_CODE_MAX 8
static const LIBSSH2_PUBLICKEY_CODE_LIST publickey_status_codes[] = { static const LIBSSH2_PUBLICKEY_CODE_LIST publickey_status_codes[] = {
{LIBSSH2_PUBLICKEY_SUCCESS, "success", sizeof("success") - 1} , {LIBSSH2_PUBLICKEY_SUCCESS, "success", sizeof("success") - 1},
{LIBSSH2_PUBLICKEY_ACCESS_DENIED, "access denied", {LIBSSH2_PUBLICKEY_ACCESS_DENIED, "access denied",
sizeof("access denied") - 1}, sizeof("access denied") - 1},
{LIBSSH2_PUBLICKEY_STORAGE_EXCEEDED, "storage exceeded", {LIBSSH2_PUBLICKEY_STORAGE_EXCEEDED, "storage exceeded",
sizeof("storage exceeded") - 1} , sizeof("storage exceeded") - 1},
{LIBSSH2_PUBLICKEY_VERSION_NOT_SUPPORTED, "version not supported", {LIBSSH2_PUBLICKEY_VERSION_NOT_SUPPORTED, "version not supported",
sizeof("version not supported") - 1} , sizeof("version not supported") - 1},
{LIBSSH2_PUBLICKEY_KEY_NOT_FOUND, "key not found", {LIBSSH2_PUBLICKEY_KEY_NOT_FOUND, "key not found",
sizeof("key not found") - 1}, sizeof("key not found") - 1},
{LIBSSH2_PUBLICKEY_KEY_NOT_SUPPORTED, "key not supported", {LIBSSH2_PUBLICKEY_KEY_NOT_SUPPORTED, "key not supported",
@@ -110,13 +110,14 @@ publickey_status_error(const LIBSSH2_PUBLICKEY *pkey,
const char *msg; const char *msg;
/* GENERAL_FAILURE got remapped between version 1 and 2 */ /* GENERAL_FAILURE got remapped between version 1 and 2 */
if (status == 6 && pkey && pkey->version == 1) { if(status == 6 && pkey && pkey->version == 1) {
status = 7; status = 7;
} }
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;
} }
@@ -139,11 +140,12 @@ publickey_packet_receive(LIBSSH2_PUBLICKEY * pkey,
*data = NULL; /* default to nothing returned */ *data = NULL; /* default to nothing returned */
*data_len = 0; *data_len = 0;
if (pkey->receive_state == libssh2_NB_state_idle) { if(pkey->receive_state == libssh2_NB_state_idle) {
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");
} }
@@ -151,7 +153,7 @@ publickey_packet_receive(LIBSSH2_PUBLICKEY * pkey,
pkey->receive_packet_len = _libssh2_ntohu32(buffer); pkey->receive_packet_len = _libssh2_ntohu32(buffer);
pkey->receive_packet = pkey->receive_packet =
LIBSSH2_ALLOC(session, pkey->receive_packet_len); LIBSSH2_ALLOC(session, pkey->receive_packet_len);
if (!pkey->receive_packet) { if(!pkey->receive_packet) {
return _libssh2_error(session, LIBSSH2_ERROR_ALLOC, return _libssh2_error(session, LIBSSH2_ERROR_ALLOC,
"Unable to allocate publickey response " "Unable to allocate publickey response "
"buffer"); "buffer");
@@ -160,12 +162,13 @@ publickey_packet_receive(LIBSSH2_PUBLICKEY * pkey,
pkey->receive_state = libssh2_NB_state_sent; pkey->receive_state = libssh2_NB_state_sent;
} }
if (pkey->receive_state == libssh2_NB_state_sent) { if(pkey->receive_state == libssh2_NB_state_sent) {
rc = _libssh2_channel_read(channel, 0, (char *) pkey->receive_packet, rc = _libssh2_channel_read(channel, 0, (char *) pkey->receive_packet,
pkey->receive_packet_len); pkey->receive_packet_len);
if (rc == 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;
@@ -195,20 +198,20 @@ publickey_response_id(unsigned char **pdata, size_t data_len)
unsigned char *data = *pdata; unsigned char *data = *pdata;
const LIBSSH2_PUBLICKEY_CODE_LIST *codes = publickey_response_codes; const LIBSSH2_PUBLICKEY_CODE_LIST *codes = publickey_response_codes;
if (data_len < 4) { if(data_len < 4) {
/* Malformed response */ /* Malformed response */
return -1; return -1;
} }
response_len = _libssh2_ntohu32(data); response_len = _libssh2_ntohu32(data);
data += 4; data += 4;
data_len -= 4; data_len -= 4;
if (data_len < response_len) { if(data_len < response_len) {
/* Malformed response */ /* Malformed response */
return -1; return -1;
} }
while (codes->name) { while(codes->name) {
if ((unsigned long)codes->name_len == response_len && if((unsigned long)codes->name_len == response_len &&
strncmp(codes->name, (char *) data, response_len) == 0) { strncmp(codes->name, (char *) data, response_len) == 0) {
*pdata = data + response_len; *pdata = data + response_len;
return codes->code; return codes->code;
@@ -231,28 +234,41 @@ publickey_response_success(LIBSSH2_PUBLICKEY * pkey)
size_t data_len; size_t data_len;
int response; int response;
while (1) { while(1) {
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);
switch (response) { switch(response) {
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);
if (status == LIBSSH2_PUBLICKEY_SUCCESS) if(status == LIBSSH2_PUBLICKEY_SUCCESS)
return 0; return 0;
publickey_status_error(pkey, session, status); publickey_status_error(pkey, session, status);
@@ -260,7 +276,7 @@ publickey_response_success(LIBSSH2_PUBLICKEY * pkey)
} }
default: default:
LIBSSH2_FREE(session, data); LIBSSH2_FREE(session, data);
if (response < 0) { if(response < 0) {
return _libssh2_error(session, return _libssh2_error(session,
LIBSSH2_ERROR_PUBLICKEY_PROTOCOL, LIBSSH2_ERROR_PUBLICKEY_PROTOCOL,
"Invalid publickey subsystem response"); "Invalid publickey subsystem response");
@@ -289,7 +305,7 @@ static LIBSSH2_PUBLICKEY *publickey_init(LIBSSH2_SESSION *session)
int response; int response;
int rc; int rc;
if (session->pkeyInit_state == libssh2_NB_state_idle) { if(session->pkeyInit_state == libssh2_NB_state_idle) {
session->pkeyInit_data = NULL; session->pkeyInit_data = NULL;
session->pkeyInit_pkey = NULL; session->pkeyInit_pkey = NULL;
session->pkeyInit_channel = NULL; session->pkeyInit_channel = NULL;
@@ -300,7 +316,7 @@ static LIBSSH2_PUBLICKEY *publickey_init(LIBSSH2_SESSION *session)
session->pkeyInit_state = libssh2_NB_state_allocated; session->pkeyInit_state = libssh2_NB_state_allocated;
} }
if (session->pkeyInit_state == libssh2_NB_state_allocated) { if(session->pkeyInit_state == libssh2_NB_state_allocated) {
session->pkeyInit_channel = session->pkeyInit_channel =
_libssh2_channel_open(session, "session", _libssh2_channel_open(session, "session",
@@ -308,8 +324,8 @@ static LIBSSH2_PUBLICKEY *publickey_init(LIBSSH2_SESSION *session)
LIBSSH2_CHANNEL_WINDOW_DEFAULT, LIBSSH2_CHANNEL_WINDOW_DEFAULT,
LIBSSH2_CHANNEL_PACKET_DEFAULT, NULL, LIBSSH2_CHANNEL_PACKET_DEFAULT, NULL,
0); 0);
if (!session->pkeyInit_channel) { if(!session->pkeyInit_channel) {
if (libssh2_session_last_errno(session) == LIBSSH2_ERROR_EAGAIN) if(libssh2_session_last_errno(session) == LIBSSH2_ERROR_EAGAIN)
/* The error state is already set, so leave it */ /* The error state is already set, so leave it */
return NULL; return NULL;
_libssh2_error(session, LIBSSH2_ERROR_CHANNEL_FAILURE, _libssh2_error(session, LIBSSH2_ERROR_CHANNEL_FAILURE,
@@ -320,17 +336,18 @@ static LIBSSH2_PUBLICKEY *publickey_init(LIBSSH2_SESSION *session)
session->pkeyInit_state = libssh2_NB_state_sent; session->pkeyInit_state = libssh2_NB_state_sent;
} }
if (session->pkeyInit_state == libssh2_NB_state_sent) { if(session->pkeyInit_state == libssh2_NB_state_sent) {
rc = _libssh2_channel_process_startup(session->pkeyInit_channel, rc = _libssh2_channel_process_startup(session->pkeyInit_channel,
"subsystem", "subsystem",
sizeof("subsystem") - 1, sizeof("subsystem") - 1,
"publickey", "publickey",
sizeof("publickey") - 1); sizeof("publickey") - 1);
if (rc == LIBSSH2_ERROR_EAGAIN) { if(rc == LIBSSH2_ERROR_EAGAIN) {
_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;
@@ -339,11 +356,11 @@ static LIBSSH2_PUBLICKEY *publickey_init(LIBSSH2_SESSION *session)
session->pkeyInit_state = libssh2_NB_state_sent1; session->pkeyInit_state = libssh2_NB_state_sent1;
} }
if (session->pkeyInit_state == libssh2_NB_state_sent1) { if(session->pkeyInit_state == libssh2_NB_state_sent1) {
unsigned char *s; unsigned char *s;
rc = _libssh2_channel_extended_data(session->pkeyInit_channel, rc = _libssh2_channel_extended_data(session->pkeyInit_channel,
LIBSSH2_CHANNEL_EXTENDED_DATA_IGNORE); LIBSSH2_CHANNEL_EXTENDED_DATA_IGNORE);
if (rc == LIBSSH2_ERROR_EAGAIN) { if(rc == LIBSSH2_ERROR_EAGAIN) {
_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;
@@ -351,7 +368,7 @@ static LIBSSH2_PUBLICKEY *publickey_init(LIBSSH2_SESSION *session)
session->pkeyInit_pkey = session->pkeyInit_pkey =
LIBSSH2_CALLOC(session, sizeof(LIBSSH2_PUBLICKEY)); LIBSSH2_CALLOC(session, sizeof(LIBSSH2_PUBLICKEY));
if (!session->pkeyInit_pkey) { if(!session->pkeyInit_pkey) {
_libssh2_error(session, LIBSSH2_ERROR_ALLOC, _libssh2_error(session, LIBSSH2_ERROR_ALLOC,
"Unable to allocate a new publickey structure"); "Unable to allocate a new publickey structure");
goto err_exit; goto err_exit;
@@ -377,15 +394,16 @@ static LIBSSH2_PUBLICKEY *publickey_init(LIBSSH2_SESSION *session)
session->pkeyInit_state = libssh2_NB_state_sent2; session->pkeyInit_state = libssh2_NB_state_sent2;
} }
if (session->pkeyInit_state == libssh2_NB_state_sent2) { if(session->pkeyInit_state == libssh2_NB_state_sent2) {
rc = _libssh2_channel_write(session->pkeyInit_channel, 0, rc = _libssh2_channel_write(session->pkeyInit_channel, 0,
session->pkeyInit_buffer, session->pkeyInit_buffer,
19 - session->pkeyInit_buffer_sent); 19 - session->pkeyInit_buffer_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 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;
@@ -400,18 +418,19 @@ static LIBSSH2_PUBLICKEY *publickey_init(LIBSSH2_SESSION *session)
session->pkeyInit_state = libssh2_NB_state_sent3; session->pkeyInit_state = libssh2_NB_state_sent3;
} }
if (session->pkeyInit_state == libssh2_NB_state_sent3) { if(session->pkeyInit_state == libssh2_NB_state_sent3) {
while (1) { while(1) {
unsigned char *s; unsigned char *s;
rc = publickey_packet_receive(session->pkeyInit_pkey, rc = publickey_packet_receive(session->pkeyInit_pkey,
&session->pkeyInit_data, &session->pkeyInit_data,
&session->pkeyInit_data_len); &session->pkeyInit_data_len);
if (rc == LIBSSH2_ERROR_EAGAIN) { if(rc == LIBSSH2_ERROR_EAGAIN) {
_libssh2_error(session, LIBSSH2_ERROR_EAGAIN, _libssh2_error(session, LIBSSH2_ERROR_EAGAIN,
"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");
@@ -419,31 +438,62 @@ static LIBSSH2_PUBLICKEY *publickey_init(LIBSSH2_SESSION *session)
} }
s = session->pkeyInit_data; s = session->pkeyInit_data;
if ((response = if((response =
publickey_response_id(&s, session->pkeyInit_data_len)) < 0) { publickey_response_id(&s, session->pkeyInit_data_len)) < 0) {
_libssh2_error(session, LIBSSH2_ERROR_PUBLICKEY_PROTOCOL, _libssh2_error(session, LIBSSH2_ERROR_PUBLICKEY_PROTOCOL,
"Invalid publickey subsystem response code"); "Invalid publickey subsystem response code");
goto err_exit; goto err_exit;
} }
switch (response) { 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) {
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) {
_libssh2_error(session, _libssh2_error(session,
LIBSSH2_ERROR_PUBLICKEY_PROTOCOL, LIBSSH2_ERROR_PUBLICKEY_PROTOCOL,
@@ -459,10 +509,11 @@ static LIBSSH2_PUBLICKEY *publickey_init(LIBSSH2_SESSION *session)
case LIBSSH2_PUBLICKEY_RESPONSE_VERSION: case LIBSSH2_PUBLICKEY_RESPONSE_VERSION:
/* What we want */ /* What we want */
session->pkeyInit_pkey->version = _libssh2_ntohu32(s); session->pkeyInit_pkey->version = _libssh2_ntohu32(s);
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;
@@ -489,19 +540,19 @@ static LIBSSH2_PUBLICKEY *publickey_init(LIBSSH2_SESSION *session)
/* Never reached except by direct goto */ /* Never reached except by direct goto */
err_exit: err_exit:
session->pkeyInit_state = libssh2_NB_state_sent4; session->pkeyInit_state = libssh2_NB_state_sent4;
if (session->pkeyInit_channel) { if(session->pkeyInit_channel) {
rc = _libssh2_channel_close(session->pkeyInit_channel); rc = _libssh2_channel_close(session->pkeyInit_channel);
if (rc == LIBSSH2_ERROR_EAGAIN) { if(rc == LIBSSH2_ERROR_EAGAIN) {
_libssh2_error(session, LIBSSH2_ERROR_EAGAIN, _libssh2_error(session, LIBSSH2_ERROR_EAGAIN,
"Would block closing channel"); "Would block closing channel");
return NULL; return NULL;
} }
} }
if (session->pkeyInit_pkey) { if(session->pkeyInit_pkey) {
LIBSSH2_FREE(session, session->pkeyInit_pkey); LIBSSH2_FREE(session, session->pkeyInit_pkey);
session->pkeyInit_pkey = NULL; session->pkeyInit_pkey = NULL;
} }
if (session->pkeyInit_data) { if(session->pkeyInit_data) {
LIBSSH2_FREE(session, session->pkeyInit_data); LIBSSH2_FREE(session, session->pkeyInit_data);
session->pkeyInit_data = NULL; session->pkeyInit_data = NULL;
} }
@@ -553,16 +604,16 @@ libssh2_publickey_add_ex(LIBSSH2_PUBLICKEY *pkey, const unsigned char *name,
channel = pkey->channel; channel = pkey->channel;
session = channel->session; session = channel->session;
if (pkey->add_state == libssh2_NB_state_idle) { if(pkey->add_state == libssh2_NB_state_idle) {
pkey->add_packet = NULL; pkey->add_packet = NULL;
_libssh2_debug(session, LIBSSH2_TRACE_PUBLICKEY, "Adding %s publickey", _libssh2_debug(session, LIBSSH2_TRACE_PUBLICKEY, "Adding %s publickey",
name); name);
if (pkey->version == 1) { if(pkey->version == 1) {
for(i = 0; i < num_attrs; i++) { for(i = 0; i < num_attrs; i++) {
/* Search for a comment attribute */ /* Search for a comment attribute */
if (attrs[i].name_len == (sizeof("comment") - 1) && if(attrs[i].name_len == (sizeof("comment") - 1) &&
strncmp(attrs[i].name, "comment", strncmp(attrs[i].name, "comment",
sizeof("comment") - 1) == 0) { sizeof("comment") - 1) == 0) {
comment = (unsigned char *) attrs[i].value; comment = (unsigned char *) attrs[i].value;
@@ -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;
@@ -580,7 +632,7 @@ libssh2_publickey_add_ex(LIBSSH2_PUBLICKEY *pkey, const unsigned char *name,
} }
pkey->add_packet = LIBSSH2_ALLOC(session, packet_len); pkey->add_packet = LIBSSH2_ALLOC(session, packet_len);
if (!pkey->add_packet) { if(!pkey->add_packet) {
return _libssh2_error(session, LIBSSH2_ERROR_ALLOC, return _libssh2_error(session, LIBSSH2_ERROR_ALLOC,
"Unable to allocate memory for " "Unable to allocate memory for "
"publickey \"add\" packet"); "publickey \"add\" packet");
@@ -593,10 +645,10 @@ libssh2_publickey_add_ex(LIBSSH2_PUBLICKEY *pkey, const unsigned char *name,
pkey->add_s += 4; pkey->add_s += 4;
memcpy(pkey->add_s, "add", sizeof("add") - 1); memcpy(pkey->add_s, "add", sizeof("add") - 1);
pkey->add_s += sizeof("add") - 1; pkey->add_s += sizeof("add") - 1;
if (pkey->version == 1) { if(pkey->version == 1) {
_libssh2_htonu32(pkey->add_s, comment_len); _libssh2_htonu32(pkey->add_s, comment_len);
pkey->add_s += 4; pkey->add_s += 4;
if (comment) { if(comment) {
memcpy(pkey->add_s, comment, comment_len); memcpy(pkey->add_s, comment, comment_len);
pkey->add_s += comment_len; pkey->add_s += comment_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);
@@ -644,12 +697,13 @@ libssh2_publickey_add_ex(LIBSSH2_PUBLICKEY *pkey, const unsigned char *name,
pkey->add_state = libssh2_NB_state_created; pkey->add_state = libssh2_NB_state_created;
} }
if (pkey->add_state == libssh2_NB_state_created) { if(pkey->add_state == libssh2_NB_state_created) {
rc = _libssh2_channel_write(channel, 0, pkey->add_packet, rc = _libssh2_channel_write(channel, 0, pkey->add_packet,
(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,
@@ -662,7 +716,7 @@ libssh2_publickey_add_ex(LIBSSH2_PUBLICKEY *pkey, const unsigned char *name,
} }
rc = publickey_response_success(pkey); rc = publickey_response_success(pkey);
if (rc == LIBSSH2_ERROR_EAGAIN) { if(rc == LIBSSH2_ERROR_EAGAIN) {
return rc; return rc;
} }
@@ -693,11 +747,11 @@ libssh2_publickey_remove_ex(LIBSSH2_PUBLICKEY * pkey,
channel = pkey->channel; channel = pkey->channel;
session = channel->session; session = channel->session;
if (pkey->remove_state == libssh2_NB_state_idle) { if(pkey->remove_state == libssh2_NB_state_idle) {
pkey->remove_packet = NULL; pkey->remove_packet = NULL;
pkey->remove_packet = LIBSSH2_ALLOC(session, packet_len); pkey->remove_packet = LIBSSH2_ALLOC(session, packet_len);
if (!pkey->remove_packet) { if(!pkey->remove_packet) {
return _libssh2_error(session, LIBSSH2_ERROR_ALLOC, return _libssh2_error(session, LIBSSH2_ERROR_ALLOC,
"Unable to allocate memory for " "Unable to allocate memory for "
"publickey \"remove\" packet"); "publickey \"remove\" packet");
@@ -727,12 +781,13 @@ libssh2_publickey_remove_ex(LIBSSH2_PUBLICKEY * pkey,
pkey->remove_state = libssh2_NB_state_created; pkey->remove_state = libssh2_NB_state_created;
} }
if (pkey->remove_state == libssh2_NB_state_created) { if(pkey->remove_state == libssh2_NB_state_created) {
rc = _libssh2_channel_write(channel, 0, pkey->remove_packet, rc = _libssh2_channel_write(channel, 0, pkey->remove_packet,
(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;
@@ -746,7 +801,7 @@ libssh2_publickey_remove_ex(LIBSSH2_PUBLICKEY * pkey,
} }
rc = publickey_response_success(pkey); rc = publickey_response_success(pkey);
if (rc == LIBSSH2_ERROR_EAGAIN) { if(rc == LIBSSH2_ERROR_EAGAIN) {
return rc; return rc;
} }
@@ -776,7 +831,7 @@ libssh2_publickey_list_fetch(LIBSSH2_PUBLICKEY * pkey, unsigned long *num_keys,
channel = pkey->channel; channel = pkey->channel;
session = channel->session; session = channel->session;
if (pkey->listFetch_state == libssh2_NB_state_idle) { if(pkey->listFetch_state == libssh2_NB_state_idle) {
pkey->listFetch_data = NULL; pkey->listFetch_data = NULL;
pkey->listFetch_s = pkey->listFetch_buffer; pkey->listFetch_s = pkey->listFetch_buffer;
@@ -793,14 +848,15 @@ libssh2_publickey_list_fetch(LIBSSH2_PUBLICKEY * pkey, unsigned long *num_keys,
pkey->listFetch_state = libssh2_NB_state_created; pkey->listFetch_state = libssh2_NB_state_created;
} }
if (pkey->listFetch_state == libssh2_NB_state_created) { if(pkey->listFetch_state == libssh2_NB_state_created) {
rc = _libssh2_channel_write(channel, 0, rc = _libssh2_channel_write(channel, 0,
pkey->listFetch_buffer, pkey->listFetch_buffer,
(pkey->listFetch_s - (pkey->listFetch_s -
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");
@@ -809,12 +865,13 @@ libssh2_publickey_list_fetch(LIBSSH2_PUBLICKEY * pkey, unsigned long *num_keys,
pkey->listFetch_state = libssh2_NB_state_sent; pkey->listFetch_state = libssh2_NB_state_sent;
} }
while (1) { while(1) {
rc = publickey_packet_receive(pkey, &pkey->listFetch_data, rc = publickey_packet_receive(pkey, &pkey->listFetch_data,
&pkey->listFetch_data_len); &pkey->listFetch_data_len);
if (rc == 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");
@@ -822,7 +879,7 @@ libssh2_publickey_list_fetch(LIBSSH2_PUBLICKEY * pkey, unsigned long *num_keys,
} }
pkey->listFetch_s = pkey->listFetch_data; pkey->listFetch_s = pkey->listFetch_data;
if ((response = if((response =
publickey_response_id(&pkey->listFetch_s, publickey_response_id(&pkey->listFetch_s,
pkey->listFetch_data_len)) < 0) { pkey->listFetch_data_len)) < 0) {
_libssh2_error(session, LIBSSH2_ERROR_PUBLICKEY_PROTOCOL, _libssh2_error(session, LIBSSH2_ERROR_PUBLICKEY_PROTOCOL,
@@ -830,31 +887,57 @@ libssh2_publickey_list_fetch(LIBSSH2_PUBLICKEY * pkey, unsigned long *num_keys,
goto err_exit; goto err_exit;
} }
switch (response) { switch(response) {
case LIBSSH2_PUBLICKEY_RESPONSE_STATUS: case LIBSSH2_PUBLICKEY_RESPONSE_STATUS:
/* Error, or processing complete */ /* Error, or processing complete */
{ {
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) {
_libssh2_error(session, LIBSSH2_ERROR_PUBLICKEY_PROTOCOL, _libssh2_error(session, LIBSSH2_ERROR_PUBLICKEY_PROTOCOL,
"Malformed publickey subsystem packet"); "Malformed publickey subsystem packet");
goto err_exit; goto err_exit;
} }
if (status == LIBSSH2_PUBLICKEY_SUCCESS) { if(status == LIBSSH2_PUBLICKEY_SUCCESS) {
LIBSSH2_FREE(session, pkey->listFetch_data); LIBSSH2_FREE(session, pkey->listFetch_data);
pkey->listFetch_data = NULL; pkey->listFetch_data = NULL;
*pkey_list = list; *pkey_list = list;
@@ -868,7 +951,7 @@ libssh2_publickey_list_fetch(LIBSSH2_PUBLICKEY * pkey, unsigned long *num_keys,
} }
case LIBSSH2_PUBLICKEY_RESPONSE_PUBLICKEY: case LIBSSH2_PUBLICKEY_RESPONSE_PUBLICKEY:
/* What we want */ /* What we want */
if (keys >= max_keys) { if(keys >= max_keys) {
libssh2_publickey_list *newlist; libssh2_publickey_list *newlist;
/* Grow the key list if necessary */ /* Grow the key list if necessary */
max_keys += 8; max_keys += 8;
@@ -876,7 +959,7 @@ libssh2_publickey_list_fetch(LIBSSH2_PUBLICKEY * pkey, unsigned long *num_keys,
LIBSSH2_REALLOC(session, list, LIBSSH2_REALLOC(session, list,
(max_keys + (max_keys +
1) * sizeof(libssh2_publickey_list)); 1) * sizeof(libssh2_publickey_list));
if (!newlist) { if(!newlist) {
_libssh2_error(session, LIBSSH2_ERROR_ALLOC, _libssh2_error(session, LIBSSH2_ERROR_ALLOC,
"Unable to allocate memory for " "Unable to allocate memory for "
"publickey list"); "publickey list");
@@ -884,17 +967,26 @@ libssh2_publickey_list_fetch(LIBSSH2_PUBLICKEY * pkey, unsigned long *num_keys,
} }
list = newlist; list = newlist;
} }
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;
if (comment_len) { }
else {
_libssh2_error(session, LIBSSH2_ERROR_BUFFER_TOO_SMALL,
"ListFetch data too short");
goto err_exit;
}
if(comment_len) {
list[keys].num_attrs = 1; list[keys].num_attrs = 1;
list[keys].attrs = list[keys].attrs =
LIBSSH2_ALLOC(session, LIBSSH2_ALLOC(session,
sizeof(libssh2_publickey_attribute)); sizeof(libssh2_publickey_attribute));
if (!list[keys].attrs) { if(!list[keys].attrs) {
_libssh2_error(session, LIBSSH2_ERROR_ALLOC, _libssh2_error(session, LIBSSH2_ERROR_ALLOC,
"Unable to allocate memory for " "Unable to allocate memory for "
"publickey attributes"); "publickey attributes");
@@ -907,57 +999,184 @@ 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;
if (list[keys].num_attrs) { }
else {
_libssh2_error(session, LIBSSH2_ERROR_BUFFER_TOO_SMALL,
"ListFetch data too short");
goto err_exit;
}
if(list[keys].num_attrs) {
list[keys].attrs = list[keys].attrs =
LIBSSH2_ALLOC(session, LIBSSH2_ALLOC(session,
list[keys].num_attrs * list[keys].num_attrs *
sizeof(libssh2_publickey_attribute)); sizeof(libssh2_publickey_attribute));
if (!list[keys].attrs) { if(!list[keys].attrs) {
_libssh2_error(session, LIBSSH2_ERROR_ALLOC, _libssh2_error(session, LIBSSH2_ERROR_ALLOC,
"Unable to allocate memory for " "Unable to allocate memory for "
"publickey attributes"); "publickey attributes");
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;
} }
} }
@@ -979,11 +1198,11 @@ libssh2_publickey_list_fetch(LIBSSH2_PUBLICKEY * pkey, unsigned long *num_keys,
/* Only reached via explicit goto */ /* Only reached via explicit goto */
err_exit: err_exit:
if (pkey->listFetch_data) { if(pkey->listFetch_data) {
LIBSSH2_FREE(session, pkey->listFetch_data); LIBSSH2_FREE(session, pkey->listFetch_data);
pkey->listFetch_data = NULL; pkey->listFetch_data = NULL;
} }
if (list) { if(list) {
libssh2_publickey_list_free(pkey, list); libssh2_publickey_list_free(pkey, list);
} }
pkey->listFetch_state = libssh2_NB_state_idle; pkey->listFetch_state = libssh2_NB_state_idle;
@@ -1005,8 +1224,8 @@ libssh2_publickey_list_free(LIBSSH2_PUBLICKEY * pkey,
session = pkey->channel->session; session = pkey->channel->session;
while (p->packet) { while(p->packet) {
if (p->attrs) { if(p->attrs) {
LIBSSH2_FREE(session, p->attrs); LIBSSH2_FREE(session, p->attrs);
} }
LIBSSH2_FREE(session, p->packet); LIBSSH2_FREE(session, p->packet);
@@ -1033,25 +1252,25 @@ libssh2_publickey_shutdown(LIBSSH2_PUBLICKEY *pkey)
/* /*
* Make sure all memory used in the state variables are free * Make sure all memory used in the state variables are free
*/ */
if (pkey->receive_packet) { if(pkey->receive_packet) {
LIBSSH2_FREE(session, pkey->receive_packet); LIBSSH2_FREE(session, pkey->receive_packet);
pkey->receive_packet = NULL; pkey->receive_packet = NULL;
} }
if (pkey->add_packet) { if(pkey->add_packet) {
LIBSSH2_FREE(session, pkey->add_packet); LIBSSH2_FREE(session, pkey->add_packet);
pkey->add_packet = NULL; pkey->add_packet = NULL;
} }
if (pkey->remove_packet) { if(pkey->remove_packet) {
LIBSSH2_FREE(session, pkey->remove_packet); LIBSSH2_FREE(session, pkey->remove_packet);
pkey->remove_packet = NULL; pkey->remove_packet = NULL;
} }
if (pkey->listFetch_data) { if(pkey->listFetch_data) {
LIBSSH2_FREE(session, pkey->listFetch_data); LIBSSH2_FREE(session, pkey->listFetch_data);
pkey->listFetch_data = NULL; pkey->listFetch_data = NULL;
} }
rc = _libssh2_channel_free(pkey->channel); rc = _libssh2_channel_free(pkey->channel);
if (rc == LIBSSH2_ERROR_EAGAIN) if(rc == LIBSSH2_ERROR_EAGAIN)
return rc; return rc;
LIBSSH2_FREE(session, pkey); LIBSSH2_FREE(session, pkey);

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.
* *
@@ -141,9 +141,9 @@ shell_quotearg(const char *path, unsigned char *buf,
endp = &buf[bufsize]; endp = &buf[bufsize];
src = path; src = path;
dst = buf; dst = buf;
while (*src && dst < endp - 1) { while(*src && dst < endp - 1) {
switch (*src) { switch(*src) {
/* /*
* Special handling for apostrophe. * Special handling for apostrophe.
* An apostrophe is always written in quotation marks, e.g. * An apostrophe is always written in quotation marks, e.g.
@@ -151,16 +151,16 @@ shell_quotearg(const char *path, unsigned char *buf,
*/ */
case '\'': case '\'':
switch (state) { switch(state) {
case UQSTRING: /* Unquoted string */ case UQSTRING: /* Unquoted string */
if (dst+1 >= endp) if(dst + 1 >= endp)
return 0; return 0;
*dst++ = '"'; *dst++ = '"';
break; break;
case QSTRING: /* Continue quoted string */ case QSTRING: /* Continue quoted string */
break; break;
case SQSTRING: /* Close single quoted string */ case SQSTRING: /* Close single quoted string */
if (dst+2 >= endp) if(dst + 2 >= endp)
return 0; return 0;
*dst++ = '\''; *dst++ = '\'';
*dst++ = '"'; *dst++ = '"';
@@ -179,20 +179,20 @@ shell_quotearg(const char *path, unsigned char *buf,
*/ */
case '!': case '!':
switch (state) { switch(state) {
case UQSTRING: case UQSTRING:
if (dst+1 >= endp) if(dst + 1 >= endp)
return 0; return 0;
*dst++ = '\\'; *dst++ = '\\';
break; break;
case QSTRING: case QSTRING:
if (dst+2 >= endp) if(dst + 2 >= endp)
return 0; return 0;
*dst++ = '"'; /* Closing quotation mark */ *dst++ = '"'; /* Closing quotation mark */
*dst++ = '\\'; *dst++ = '\\';
break; break;
case SQSTRING: /* Close single quoted string */ case SQSTRING: /* Close single quoted string */
if (dst+2 >= endp) if(dst + 2 >= endp)
return 0; return 0;
*dst++ = '\''; *dst++ = '\'';
*dst++ = '\\'; *dst++ = '\\';
@@ -208,14 +208,14 @@ shell_quotearg(const char *path, unsigned char *buf,
*/ */
default: default:
switch (state) { switch(state) {
case UQSTRING: case UQSTRING:
if (dst+1 >= endp) if(dst + 1 >= endp)
return 0; return 0;
*dst++ = '\''; *dst++ = '\'';
break; break;
case QSTRING: case QSTRING:
if (dst+2 >= endp) if(dst + 2 >= endp)
return 0; return 0;
*dst++ = '"'; /* Closing quotation mark */ *dst++ = '"'; /* Closing quotation mark */
*dst++ = '\''; *dst++ = '\'';
@@ -229,21 +229,21 @@ shell_quotearg(const char *path, unsigned char *buf,
break; break;
} }
if (dst+1 >= endp) if(dst + 1 >= endp)
return 0; return 0;
*dst++ = *src++; *dst++ = *src++;
} }
switch (state) { switch(state) {
case UQSTRING: case UQSTRING:
break; break;
case QSTRING: /* Close quoted string */ case QSTRING: /* Close quoted string */
if (dst+1 >= endp) if(dst + 1 >= endp)
return 0; return 0;
*dst++ = '"'; *dst++ = '"';
break; break;
case SQSTRING: /* Close single quoted string */ case SQSTRING: /* Close single quoted string */
if (dst+1 >= endp) if(dst + 1 >= endp)
return 0; return 0;
*dst++ = '\''; *dst++ = '\'';
break; break;
@@ -251,7 +251,7 @@ shell_quotearg(const char *path, unsigned char *buf,
break; break;
} }
if (dst+1 >= endp) if(dst + 1 >= endp)
return 0; return 0;
*dst = '\0'; *dst = '\0';
@@ -275,7 +275,7 @@ scp_recv(LIBSSH2_SESSION * session, const char *path, libssh2_struct_stat * sb)
int tmp_err_code; int tmp_err_code;
const char *tmp_err_msg; const char *tmp_err_msg;
if (session->scpRecv_state == libssh2_NB_state_idle) { if(session->scpRecv_state == libssh2_NB_state_idle) {
session->scpRecv_mode = 0; session->scpRecv_mode = 0;
session->scpRecv_size = 0; session->scpRecv_size = 0;
session->scpRecv_mtime = 0; session->scpRecv_mtime = 0;
@@ -287,7 +287,7 @@ scp_recv(LIBSSH2_SESSION * session, const char *path, libssh2_struct_stat * sb)
session->scpRecv_command = session->scpRecv_command =
LIBSSH2_ALLOC(session, session->scpRecv_command_len); LIBSSH2_ALLOC(session, session->scpRecv_command_len);
if (!session->scpRecv_command) { if(!session->scpRecv_command) {
_libssh2_error(session, LIBSSH2_ERROR_ALLOC, _libssh2_error(session, LIBSSH2_ERROR_ALLOC,
"Unable to allocate a command buffer for " "Unable to allocate a command buffer for "
"SCP session"); "SCP session");
@@ -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");
@@ -312,7 +312,7 @@ scp_recv(LIBSSH2_SESSION * session, const char *path, libssh2_struct_stat * sb)
session->scpRecv_state = libssh2_NB_state_created; session->scpRecv_state = libssh2_NB_state_created;
} }
if (session->scpRecv_state == libssh2_NB_state_created) { if(session->scpRecv_state == libssh2_NB_state_created) {
/* Allocate a channel */ /* Allocate a channel */
session->scpRecv_channel = session->scpRecv_channel =
_libssh2_channel_open(session, "session", _libssh2_channel_open(session, "session",
@@ -320,8 +320,8 @@ scp_recv(LIBSSH2_SESSION * session, const char *path, libssh2_struct_stat * sb)
LIBSSH2_CHANNEL_WINDOW_DEFAULT, LIBSSH2_CHANNEL_WINDOW_DEFAULT,
LIBSSH2_CHANNEL_PACKET_DEFAULT, NULL, LIBSSH2_CHANNEL_PACKET_DEFAULT, NULL,
0); 0);
if (!session->scpRecv_channel) { if(!session->scpRecv_channel) {
if (libssh2_session_last_errno(session) != if(libssh2_session_last_errno(session) !=
LIBSSH2_ERROR_EAGAIN) { LIBSSH2_ERROR_EAGAIN) {
LIBSSH2_FREE(session, session->scpRecv_command); LIBSSH2_FREE(session, session->scpRecv_command);
session->scpRecv_command = NULL; session->scpRecv_command = NULL;
@@ -337,17 +337,18 @@ scp_recv(LIBSSH2_SESSION * session, const char *path, libssh2_struct_stat * sb)
session->scpRecv_state = libssh2_NB_state_sent; session->scpRecv_state = libssh2_NB_state_sent;
} }
if (session->scpRecv_state == libssh2_NB_state_sent) { if(session->scpRecv_state == libssh2_NB_state_sent) {
/* Request SCP for the desired file */ /* Request SCP for the desired file */
rc = _libssh2_channel_process_startup(session->scpRecv_channel, "exec", rc = _libssh2_channel_process_startup(session->scpRecv_channel, "exec",
sizeof("exec") - 1, sizeof("exec") - 1,
(char *) session->scpRecv_command, (char *)session->scpRecv_command,
session->scpRecv_command_len); session->scpRecv_command_len);
if (rc == LIBSSH2_ERROR_EAGAIN) { if(rc == LIBSSH2_ERROR_EAGAIN) {
_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;
@@ -362,14 +363,15 @@ scp_recv(LIBSSH2_SESSION * session, const char *path, libssh2_struct_stat * sb)
session->scpRecv_state = libssh2_NB_state_sent1; session->scpRecv_state = libssh2_NB_state_sent1;
} }
if (session->scpRecv_state == libssh2_NB_state_sent1) { if(session->scpRecv_state == libssh2_NB_state_sent1) {
rc = _libssh2_channel_write(session->scpRecv_channel, 0, rc = _libssh2_channel_write(session->scpRecv_channel, 0,
session->scpRecv_response, 1); session->scpRecv_response, 1);
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 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;
} }
@@ -379,23 +381,23 @@ scp_recv(LIBSSH2_SESSION * session, const char *path, libssh2_struct_stat * sb)
session->scpRecv_state = libssh2_NB_state_sent2; session->scpRecv_state = libssh2_NB_state_sent2;
} }
if ((session->scpRecv_state == libssh2_NB_state_sent2) if((session->scpRecv_state == libssh2_NB_state_sent2)
|| (session->scpRecv_state == libssh2_NB_state_sent3)) { || (session->scpRecv_state == libssh2_NB_state_sent3)) {
while (sb && (session->scpRecv_response_len < while(sb && (session->scpRecv_response_len <
LIBSSH2_SCP_RESPONSE_BUFLEN)) { LIBSSH2_SCP_RESPONSE_BUFLEN)) {
unsigned char *s, *p; unsigned char *s, *p;
if (session->scpRecv_state == libssh2_NB_state_sent2) { if(session->scpRecv_state == libssh2_NB_state_sent2) {
rc = _libssh2_channel_read(session->scpRecv_channel, 0, rc = _libssh2_channel_read(session->scpRecv_channel, 0,
(char *) session-> (char *) session->
scpRecv_response + scpRecv_response +
session->scpRecv_response_len, 1); session->scpRecv_response_len, 1);
if (rc == LIBSSH2_ERROR_EAGAIN) { if(rc == LIBSSH2_ERROR_EAGAIN) {
_libssh2_error(session, LIBSSH2_ERROR_EAGAIN, _libssh2_error(session, LIBSSH2_ERROR_EAGAIN,
"Would block waiting for SCP response"); "Would block waiting for SCP response");
return NULL; return NULL;
} }
else if (rc < 0) { else if(rc < 0) {
/* error, give up */ /* error, give up */
_libssh2_error(session, rc, "Failed reading SCP response"); _libssh2_error(session, rc, "Failed reading SCP response");
goto scp_recv_error; goto scp_recv_error;
@@ -405,7 +407,7 @@ scp_recv(LIBSSH2_SESSION * session, const char *path, libssh2_struct_stat * sb)
session->scpRecv_response_len++; session->scpRecv_response_len++;
if (session->scpRecv_response[0] != 'T') { if(session->scpRecv_response[0] != 'T') {
size_t err_len; size_t err_len;
char *err_msg; char *err_msg;
@@ -419,7 +421,7 @@ scp_recv(LIBSSH2_SESSION * session, const char *path, libssh2_struct_stat * sb)
_libssh2_channel_packet_data_len(session-> _libssh2_channel_packet_data_len(session->
scpRecv_channel, 0); scpRecv_channel, 0);
err_msg = LIBSSH2_ALLOC(session, err_len + 1); err_msg = LIBSSH2_ALLOC(session, err_len + 1);
if (!err_msg) { if(!err_msg) {
_libssh2_error(session, LIBSSH2_ERROR_ALLOC, _libssh2_error(session, LIBSSH2_ERROR_ALLOC,
"Failed to get memory "); "Failed to get memory ");
goto scp_recv_error; goto scp_recv_error;
@@ -431,7 +433,7 @@ scp_recv(LIBSSH2_SESSION * session, const char *path, libssh2_struct_stat * sb)
/* If it failed for any reason, we ignore it anyway. */ /* If it failed for any reason, we ignore it anyway. */
/* zero terminate the error */ /* zero terminate the error */
err_msg[err_len]=0; err_msg[err_len] = 0;
_libssh2_debug(session, LIBSSH2_TRACE_SCP, _libssh2_debug(session, LIBSSH2_TRACE_SCP,
"got %02x %s", session->scpRecv_response[0], "got %02x %s", session->scpRecv_response[0],
@@ -444,7 +446,7 @@ scp_recv(LIBSSH2_SESSION * session, const char *path, libssh2_struct_stat * sb)
goto scp_recv_error; goto scp_recv_error;
} }
if ((session->scpRecv_response_len > 1) && if((session->scpRecv_response_len > 1) &&
((session-> ((session->
scpRecv_response[session->scpRecv_response_len - 1] < scpRecv_response[session->scpRecv_response_len - 1] <
'0') '0')
@@ -465,15 +467,16 @@ scp_recv(LIBSSH2_SESSION * session, const char *path, libssh2_struct_stat * sb)
goto scp_recv_error; goto scp_recv_error;
} }
if ((session->scpRecv_response_len < 9) if((session->scpRecv_response_len < 9)
|| (session-> || (session->
scpRecv_response[session->scpRecv_response_len - 1] != scpRecv_response[session->scpRecv_response_len - 1] !=
'\n')) { '\n')) {
if (session->scpRecv_response_len == if(session->scpRecv_response_len ==
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,
@@ -483,7 +486,7 @@ scp_recv(LIBSSH2_SESSION * session, const char *path, libssh2_struct_stat * sb)
/* We're guaranteed not to go under response_len == 0 by the /* We're guaranteed not to go under response_len == 0 by the
logic above */ logic above */
while ((session-> while((session->
scpRecv_response[session->scpRecv_response_len - 1] == scpRecv_response[session->scpRecv_response_len - 1] ==
'\r') '\r')
|| (session-> || (session->
@@ -493,18 +496,18 @@ scp_recv(LIBSSH2_SESSION * session, const char *path, libssh2_struct_stat * sb)
session->scpRecv_response[session->scpRecv_response_len] = session->scpRecv_response[session->scpRecv_response_len] =
'\0'; '\0';
if (session->scpRecv_response_len < 8) { if(session->scpRecv_response_len < 8) {
/* 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, " "Invalid response from SCP server, "
"too short" ); "too short");
goto scp_recv_error; goto scp_recv_error;
} }
s = session->scpRecv_response + 1; s = session->scpRecv_response + 1;
p = (unsigned char *) strchr((char *) s, ' '); p = (unsigned char *) strchr((char *) s, ' ');
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, " "Invalid response from SCP server, "
@@ -517,20 +520,22 @@ scp_recv(LIBSSH2_SESSION * session, const char *path, libssh2_struct_stat * sb)
session->scpRecv_mtime = strtol((char *) s, NULL, 10); session->scpRecv_mtime = strtol((char *) s, NULL, 10);
s = (unsigned char *) strchr((char *) p, ' '); s = (unsigned char *) strchr((char *) p, ' ');
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;
} }
/* Ignore mtime.usec */ /* Ignore mtime.usec */
s++; s++;
p = (unsigned char *) strchr((char *) s, ' '); p = (unsigned char *) strchr((char *) s, ' ');
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;
} }
@@ -544,14 +549,15 @@ scp_recv(LIBSSH2_SESSION * session, const char *path, libssh2_struct_stat * sb)
session->scpRecv_state = libssh2_NB_state_sent3; session->scpRecv_state = libssh2_NB_state_sent3;
} }
if (session->scpRecv_state == libssh2_NB_state_sent3) { if(session->scpRecv_state == libssh2_NB_state_sent3) {
rc = _libssh2_channel_write(session->scpRecv_channel, 0, rc = _libssh2_channel_write(session->scpRecv_channel, 0,
session->scpRecv_response, 1); session->scpRecv_response, 1);
if (rc == LIBSSH2_ERROR_EAGAIN) { if(rc == LIBSSH2_ERROR_EAGAIN) {
_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;
} }
@@ -568,28 +574,28 @@ scp_recv(LIBSSH2_SESSION * session, const char *path, libssh2_struct_stat * sb)
session->scpRecv_state = libssh2_NB_state_sent4; session->scpRecv_state = libssh2_NB_state_sent4;
} }
if (session->scpRecv_state == libssh2_NB_state_sent4) { if(session->scpRecv_state == libssh2_NB_state_sent4) {
session->scpRecv_response_len = 0; session->scpRecv_response_len = 0;
session->scpRecv_state = libssh2_NB_state_sent5; session->scpRecv_state = libssh2_NB_state_sent5;
} }
if ((session->scpRecv_state == libssh2_NB_state_sent5) if((session->scpRecv_state == libssh2_NB_state_sent5)
|| (session->scpRecv_state == libssh2_NB_state_sent6)) { || (session->scpRecv_state == libssh2_NB_state_sent6)) {
while (session->scpRecv_response_len < LIBSSH2_SCP_RESPONSE_BUFLEN) { while(session->scpRecv_response_len < LIBSSH2_SCP_RESPONSE_BUFLEN) {
char *s, *p, *e = NULL; char *s, *p, *e = NULL;
if (session->scpRecv_state == libssh2_NB_state_sent5) { if(session->scpRecv_state == libssh2_NB_state_sent5) {
rc = _libssh2_channel_read(session->scpRecv_channel, 0, rc = _libssh2_channel_read(session->scpRecv_channel, 0,
(char *) session-> (char *) session->
scpRecv_response + scpRecv_response +
session->scpRecv_response_len, 1); session->scpRecv_response_len, 1);
if (rc == LIBSSH2_ERROR_EAGAIN) { if(rc == LIBSSH2_ERROR_EAGAIN) {
_libssh2_error(session, LIBSSH2_ERROR_EAGAIN, _libssh2_error(session, LIBSSH2_ERROR_EAGAIN,
"Would block waiting for SCP response"); "Would block waiting for SCP response");
return NULL; return NULL;
} }
else if (rc < 0) { else if(rc < 0) {
/* error, bail out*/ /* error, bail out*/
_libssh2_error(session, rc, "Failed reading SCP response"); _libssh2_error(session, rc, "Failed reading SCP response");
goto scp_recv_error; goto scp_recv_error;
@@ -599,13 +605,13 @@ scp_recv(LIBSSH2_SESSION * session, const char *path, libssh2_struct_stat * sb)
session->scpRecv_response_len++; session->scpRecv_response_len++;
if (session->scpRecv_response[0] != 'C') { if(session->scpRecv_response[0] != 'C') {
_libssh2_error(session, LIBSSH2_ERROR_SCP_PROTOCOL, _libssh2_error(session, LIBSSH2_ERROR_SCP_PROTOCOL,
"Invalid response from SCP server"); "Invalid response from SCP server");
goto scp_recv_error; goto scp_recv_error;
} }
if ((session->scpRecv_response_len > 1) && if((session->scpRecv_response_len > 1) &&
(session-> (session->
scpRecv_response[session->scpRecv_response_len - 1] != scpRecv_response[session->scpRecv_response_len - 1] !=
'\r') '\r')
@@ -621,15 +627,16 @@ scp_recv(LIBSSH2_SESSION * session, const char *path, libssh2_struct_stat * sb)
goto scp_recv_error; goto scp_recv_error;
} }
if ((session->scpRecv_response_len < 7) if((session->scpRecv_response_len < 7)
|| (session-> || (session->
scpRecv_response[session->scpRecv_response_len - 1] != scpRecv_response[session->scpRecv_response_len - 1] !=
'\n')) { '\n')) {
if (session->scpRecv_response_len == if(session->scpRecv_response_len ==
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,
@@ -639,7 +646,7 @@ scp_recv(LIBSSH2_SESSION * session, const char *path, libssh2_struct_stat * sb)
/* We're guaranteed not to go under response_len == 0 by the /* We're guaranteed not to go under response_len == 0 by the
logic above */ logic above */
while ((session-> while((session->
scpRecv_response[session->scpRecv_response_len - 1] == scpRecv_response[session->scpRecv_response_len - 1] ==
'\r') '\r')
|| (session-> || (session->
@@ -650,20 +657,22 @@ scp_recv(LIBSSH2_SESSION * session, const char *path, libssh2_struct_stat * sb)
session->scpRecv_response[session->scpRecv_response_len] = session->scpRecv_response[session->scpRecv_response_len] =
'\0'; '\0';
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;
} }
s = (char *) session->scpRecv_response + 1; s = (char *) session->scpRecv_response + 1;
p = strchr(s, ' '); p = strchr(s, ' ');
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;
} }
@@ -671,26 +680,29 @@ scp_recv(LIBSSH2_SESSION * session, const char *path, libssh2_struct_stat * sb)
/* Make sure we don't get fooled by leftover values */ /* Make sure we don't get fooled by leftover values */
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;
} }
s = strchr(p, ' '); s = strchr(p, ' ');
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;
} }
*s = '\0'; *s = '\0';
/* Make sure we don't get fooled by leftover values */ /* Make sure we don't get fooled by leftover values */
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;
} }
@@ -700,14 +712,15 @@ scp_recv(LIBSSH2_SESSION * session, const char *path, libssh2_struct_stat * sb)
session->scpRecv_state = libssh2_NB_state_sent6; session->scpRecv_state = libssh2_NB_state_sent6;
} }
if (session->scpRecv_state == libssh2_NB_state_sent6) { if(session->scpRecv_state == libssh2_NB_state_sent6) {
rc = _libssh2_channel_write(session->scpRecv_channel, 0, rc = _libssh2_channel_write(session->scpRecv_channel, 0,
session->scpRecv_response, 1); session->scpRecv_response, 1);
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 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,
@@ -723,7 +736,7 @@ scp_recv(LIBSSH2_SESSION * session, const char *path, libssh2_struct_stat * sb)
session->scpRecv_state = libssh2_NB_state_sent7; session->scpRecv_state = libssh2_NB_state_sent7;
} }
if (sb) { if(sb) {
memset(sb, 0, sizeof(libssh2_struct_stat)); memset(sb, 0, sizeof(libssh2_struct_stat));
sb->st_mtime = session->scpRecv_mtime; sb->st_mtime = session->scpRecv_mtime;
@@ -747,7 +760,7 @@ scp_recv(LIBSSH2_SESSION * session, const char *path, libssh2_struct_stat * sb)
scp_recv_error: scp_recv_error:
tmp_err_code = session->err_code; tmp_err_code = session->err_code;
tmp_err_msg = session->err_msg; tmp_err_msg = session->err_msg;
while (libssh2_channel_free(session->scpRecv_channel) == while(libssh2_channel_free(session->scpRecv_channel) ==
LIBSSH2_ERROR_EAGAIN); LIBSSH2_ERROR_EAGAIN);
session->err_code = tmp_err_code; session->err_code = tmp_err_code;
session->err_msg = tmp_err_msg; session->err_msg = tmp_err_msg;
@@ -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,15 +784,17 @@ 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));
/* ...and populate the caller's with as much info as fits. */ /* ...and populate the caller's with as much info as fits. */
if (sb) { if(sb) {
memset(sb, 0, sizeof(struct stat)); memset(sb, 0, sizeof(struct stat));
sb->st_mtime = sb_intl.st_mtime; sb->st_mtime = sb_intl.st_mtime;
@@ -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));
@@ -821,7 +837,7 @@ scp_send(LIBSSH2_SESSION * session, const char *path, int mode,
int tmp_err_code; int tmp_err_code;
const char *tmp_err_msg; const char *tmp_err_msg;
if (session->scpSend_state == libssh2_NB_state_idle) { if(session->scpSend_state == libssh2_NB_state_idle) {
session->scpSend_command_len = session->scpSend_command_len =
_libssh2_shell_quotedsize(path) + sizeof("scp -t ") + _libssh2_shell_quotedsize(path) + sizeof("scp -t ") +
((mtime || atime)?1:0); ((mtime || atime)?1:0);
@@ -829,7 +845,7 @@ scp_send(LIBSSH2_SESSION * session, const char *path, int mode,
session->scpSend_command = session->scpSend_command =
LIBSSH2_ALLOC(session, session->scpSend_command_len); LIBSSH2_ALLOC(session, session->scpSend_command_len);
if (!session->scpSend_command) { if(!session->scpSend_command) {
_libssh2_error(session, LIBSSH2_ERROR_ALLOC, _libssh2_error(session, LIBSSH2_ERROR_ALLOC,
"Unable to allocate a command buffer for " "Unable to allocate a command buffer for "
"SCP session"); "SCP session");
@@ -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");
@@ -855,13 +871,13 @@ scp_send(LIBSSH2_SESSION * session, const char *path, int mode,
session->scpSend_state = libssh2_NB_state_created; session->scpSend_state = libssh2_NB_state_created;
} }
if (session->scpSend_state == libssh2_NB_state_created) { if(session->scpSend_state == libssh2_NB_state_created) {
session->scpSend_channel = session->scpSend_channel =
_libssh2_channel_open(session, "session", sizeof("session") - 1, _libssh2_channel_open(session, "session", sizeof("session") - 1,
LIBSSH2_CHANNEL_WINDOW_DEFAULT, LIBSSH2_CHANNEL_WINDOW_DEFAULT,
LIBSSH2_CHANNEL_PACKET_DEFAULT, NULL, 0); LIBSSH2_CHANNEL_PACKET_DEFAULT, NULL, 0);
if (!session->scpSend_channel) { if(!session->scpSend_channel) {
if (libssh2_session_last_errno(session) != LIBSSH2_ERROR_EAGAIN) { if(libssh2_session_last_errno(session) != LIBSSH2_ERROR_EAGAIN) {
/* previous call set libssh2_session_last_error(), pass it /* previous call set libssh2_session_last_error(), pass it
through */ through */
LIBSSH2_FREE(session, session->scpSend_command); LIBSSH2_FREE(session, session->scpSend_command);
@@ -878,18 +894,18 @@ scp_send(LIBSSH2_SESSION * session, const char *path, int mode,
session->scpSend_state = libssh2_NB_state_sent; session->scpSend_state = libssh2_NB_state_sent;
} }
if (session->scpSend_state == libssh2_NB_state_sent) { if(session->scpSend_state == libssh2_NB_state_sent) {
/* Request SCP for the desired file */ /* Request SCP for the desired file */
rc = _libssh2_channel_process_startup(session->scpSend_channel, "exec", rc = _libssh2_channel_process_startup(session->scpSend_channel, "exec",
sizeof("exec") - 1, sizeof("exec") - 1,
(char *) session->scpSend_command, (char *)session->scpSend_command,
session->scpSend_command_len); session->scpSend_command_len);
if (rc == LIBSSH2_ERROR_EAGAIN) { if(rc == LIBSSH2_ERROR_EAGAIN) {
_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) {
/* previous call set libssh2_session_last_error(), pass it /* previous call set libssh2_session_last_error(), pass it
through */ through */
LIBSSH2_FREE(session, session->scpSend_command); LIBSSH2_FREE(session, session->scpSend_command);
@@ -904,28 +920,28 @@ scp_send(LIBSSH2_SESSION * session, const char *path, int mode,
session->scpSend_state = libssh2_NB_state_sent1; session->scpSend_state = libssh2_NB_state_sent1;
} }
if (session->scpSend_state == libssh2_NB_state_sent1) { if(session->scpSend_state == libssh2_NB_state_sent1) {
/* Wait for ACK */ /* Wait for ACK */
rc = _libssh2_channel_read(session->scpSend_channel, 0, rc = _libssh2_channel_read(session->scpSend_channel, 0,
(char *) session->scpSend_response, 1); (char *) session->scpSend_response, 1);
if (rc == LIBSSH2_ERROR_EAGAIN) { if(rc == LIBSSH2_ERROR_EAGAIN) {
_libssh2_error(session, LIBSSH2_ERROR_EAGAIN, _libssh2_error(session, LIBSSH2_ERROR_EAGAIN,
"Would block waiting for response from remote"); "Would block waiting for response from remote");
return NULL; return NULL;
} }
else if (rc < 0) { else if(rc < 0) {
_libssh2_error(session, rc, "SCP failure"); _libssh2_error(session, rc, "SCP failure");
goto scp_send_error; goto scp_send_error;
} }
else if(!rc) else if(!rc)
/* remain in the same state */ /* remain in the same state */
goto scp_send_empty_channel; goto scp_send_empty_channel;
else if (session->scpSend_response[0] != 0) { else if(session->scpSend_response[0] != 0) {
_libssh2_error(session, LIBSSH2_ERROR_SCP_PROTOCOL, _libssh2_error(session, LIBSSH2_ERROR_SCP_PROTOCOL,
"Invalid ACK response from remote"); "Invalid ACK response from remote");
goto scp_send_error; goto scp_send_error;
} }
if (mtime || atime) { if(mtime || atime) {
/* Send mtime and atime to be used for file */ /* Send mtime and atime to be used for file */
session->scpSend_response_len = session->scpSend_response_len =
snprintf((char *) session->scpSend_response, snprintf((char *) session->scpSend_response,
@@ -939,16 +955,17 @@ scp_send(LIBSSH2_SESSION * session, const char *path, int mode,
} }
/* Send mtime and atime to be used for file */ /* Send mtime and atime to be used for file */
if (mtime || atime) { if(mtime || atime) {
if (session->scpSend_state == libssh2_NB_state_sent2) { if(session->scpSend_state == libssh2_NB_state_sent2) {
rc = _libssh2_channel_write(session->scpSend_channel, 0, rc = _libssh2_channel_write(session->scpSend_channel, 0,
session->scpSend_response, session->scpSend_response,
session->scpSend_response_len); session->scpSend_response_len);
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 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;
@@ -957,23 +974,23 @@ scp_send(LIBSSH2_SESSION * session, const char *path, int mode,
session->scpSend_state = libssh2_NB_state_sent3; session->scpSend_state = libssh2_NB_state_sent3;
} }
if (session->scpSend_state == libssh2_NB_state_sent3) { if(session->scpSend_state == libssh2_NB_state_sent3) {
/* Wait for ACK */ /* Wait for ACK */
rc = _libssh2_channel_read(session->scpSend_channel, 0, rc = _libssh2_channel_read(session->scpSend_channel, 0,
(char *) session->scpSend_response, 1); (char *) session->scpSend_response, 1);
if (rc == LIBSSH2_ERROR_EAGAIN) { if(rc == LIBSSH2_ERROR_EAGAIN) {
_libssh2_error(session, LIBSSH2_ERROR_EAGAIN, _libssh2_error(session, LIBSSH2_ERROR_EAGAIN,
"Would block waiting for response"); "Would block waiting for response");
return NULL; return NULL;
} }
else if (rc < 0) { else if(rc < 0) {
_libssh2_error(session, rc, "SCP failure"); _libssh2_error(session, rc, "SCP failure");
goto scp_send_error; goto scp_send_error;
} }
else if(!rc) else if(!rc)
/* remain in the same state */ /* remain in the same state */
goto scp_send_empty_channel; goto scp_send_empty_channel;
else if (session->scpSend_response[0] != 0) { else if(session->scpSend_response[0] != 0) {
_libssh2_error(session, LIBSSH2_ERROR_SCP_PROTOCOL, _libssh2_error(session, LIBSSH2_ERROR_SCP_PROTOCOL,
"Invalid SCP ACK response"); "Invalid SCP ACK response");
goto scp_send_error; goto scp_send_error;
@@ -981,16 +998,17 @@ 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 { }
if (session->scpSend_state == libssh2_NB_state_sent2) { else {
if(session->scpSend_state == libssh2_NB_state_sent2) {
session->scpSend_state = libssh2_NB_state_sent4; session->scpSend_state = libssh2_NB_state_sent4;
} }
} }
if (session->scpSend_state == libssh2_NB_state_sent4) { if(session->scpSend_state == libssh2_NB_state_sent4) {
/* Send mode, size, and basename */ /* Send mode, size, and basename */
const char *base = strrchr(path, '/'); const char *base = strrchr(path, '/');
if (base) if(base)
base++; base++;
else else
base = path; base = path;
@@ -1006,15 +1024,16 @@ scp_send(LIBSSH2_SESSION * session, const char *path, int mode,
session->scpSend_state = libssh2_NB_state_sent5; session->scpSend_state = libssh2_NB_state_sent5;
} }
if (session->scpSend_state == libssh2_NB_state_sent5) { if(session->scpSend_state == libssh2_NB_state_sent5) {
rc = _libssh2_channel_write(session->scpSend_channel, 0, rc = _libssh2_channel_write(session->scpSend_channel, 0,
session->scpSend_response, session->scpSend_response,
session->scpSend_response_len); session->scpSend_response_len);
if (rc == LIBSSH2_ERROR_EAGAIN) { if(rc == LIBSSH2_ERROR_EAGAIN) {
_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;
@@ -1023,31 +1042,31 @@ scp_send(LIBSSH2_SESSION * session, const char *path, int mode,
session->scpSend_state = libssh2_NB_state_sent6; session->scpSend_state = libssh2_NB_state_sent6;
} }
if (session->scpSend_state == libssh2_NB_state_sent6) { if(session->scpSend_state == libssh2_NB_state_sent6) {
/* Wait for ACK */ /* Wait for ACK */
rc = _libssh2_channel_read(session->scpSend_channel, 0, rc = _libssh2_channel_read(session->scpSend_channel, 0,
(char *) session->scpSend_response, 1); (char *) session->scpSend_response, 1);
if (rc == LIBSSH2_ERROR_EAGAIN) { if(rc == LIBSSH2_ERROR_EAGAIN) {
_libssh2_error(session, LIBSSH2_ERROR_EAGAIN, _libssh2_error(session, LIBSSH2_ERROR_EAGAIN,
"Would block waiting for response"); "Would block waiting for response");
return NULL; return NULL;
} }
else if (rc < 0) { else if(rc < 0) {
_libssh2_error(session, LIBSSH2_ERROR_SCP_PROTOCOL, _libssh2_error(session, LIBSSH2_ERROR_SCP_PROTOCOL,
"Invalid ACK response from remote"); "Invalid ACK response from remote");
goto scp_send_error; goto scp_send_error;
} }
else if (rc == 0) else if(rc == 0)
goto scp_send_empty_channel; goto scp_send_empty_channel;
else if (session->scpSend_response[0] != 0) { else if(session->scpSend_response[0] != 0) {
size_t err_len; size_t err_len;
char *err_msg; char *err_msg;
err_len = err_len =
_libssh2_channel_packet_data_len(session->scpSend_channel, 0); _libssh2_channel_packet_data_len(session->scpSend_channel, 0);
err_msg = LIBSSH2_ALLOC(session, err_len + 1); err_msg = LIBSSH2_ALLOC(session, err_len + 1);
if (!err_msg) { if(!err_msg) {
_libssh2_error(session, LIBSSH2_ERROR_ALLOC, _libssh2_error(session, LIBSSH2_ERROR_ALLOC,
"failed to get memory"); "failed to get memory");
goto scp_send_error; goto scp_send_error;
@@ -1056,8 +1075,8 @@ scp_send(LIBSSH2_SESSION * session, const char *path, int mode,
/* Read the remote error message */ /* Read the remote error message */
rc = _libssh2_channel_read(session->scpSend_channel, 0, rc = _libssh2_channel_read(session->scpSend_channel, 0,
err_msg, err_len); err_msg, err_len);
if (rc > 0) { if(rc > 0) {
err_msg[err_len]=0; err_msg[err_len] = 0;
_libssh2_debug(session, LIBSSH2_TRACE_SCP, _libssh2_debug(session, LIBSSH2_TRACE_SCP,
"got %02x %s", session->scpSend_response[0], "got %02x %s", session->scpSend_response[0],
err_msg); err_msg);
@@ -1085,7 +1104,7 @@ scp_send(LIBSSH2_SESSION * session, const char *path, int mode,
scp_send_error: scp_send_error:
tmp_err_code = session->err_code; tmp_err_code = session->err_code;
tmp_err_msg = session->err_msg; tmp_err_msg = session->err_msg;
while (libssh2_channel_free(session->scpSend_channel) == while(libssh2_channel_free(session->scpSend_channel) ==
LIBSSH2_ERROR_EAGAIN); LIBSSH2_ERROR_EAGAIN);
session->err_code = tmp_err_code; session->err_code = tmp_err_code;
session->err_msg = tmp_err_msg; session->err_msg = tmp_err_msg;

File diff suppressed because it is too large Load Diff

View File

@@ -51,9 +51,9 @@
function. function.
*/ */
#define BLOCK_ADJUST(rc,sess,x) \ #define BLOCK_ADJUST(rc, sess, x) \
do { \ do { \
time_t entry_time = time (NULL); \ time_t entry_time = time(NULL); \
do { \ do { \
rc = x; \ rc = x; \
/* the order of the check below is important to properly deal with \ /* the order of the check below is important to properly deal with \
@@ -70,9 +70,9 @@
* immediately. If the API is blocking and we get a NULL we check the errno * immediately. If the API is blocking and we get a NULL we check the errno
* and *only* if that is EAGAIN we loop and wait for socket action. * and *only* if that is EAGAIN we loop and wait for socket action.
*/ */
#define BLOCK_ADJUST_ERRNO(ptr,sess,x) \ #define BLOCK_ADJUST_ERRNO(ptr, sess, x) \
do { \ do { \
time_t entry_time = time (NULL); \ time_t entry_time = time(NULL); \
int rc; \ int rc; \
do { \ do { \
ptr = x; \ ptr = x; \

File diff suppressed because it is too large Load Diff

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

@@ -65,16 +65,16 @@ debugdump(LIBSSH2_SESSION * session,
unsigned int width = 0x10; unsigned int width = 0x10;
char buffer[256]; /* Must be enough for width*4 + about 30 or so */ char buffer[256]; /* Must be enough for width*4 + about 30 or so */
size_t used; size_t used;
static const char* hex_chars = "0123456789ABCDEF"; static const char *hex_chars = "0123456789ABCDEF";
if (!(session->showmask & LIBSSH2_TRACE_TRANS)) { if(!(session->showmask & LIBSSH2_TRACE_TRANS)) {
/* not asked for, bail out */ /* not asked for, bail out */
return; return;
} }
used = snprintf(buffer, sizeof(buffer), "=> %s (%d bytes)\n", used = snprintf(buffer, sizeof(buffer), "=> %s (%d bytes)\n",
desc, (int) size); desc, (int) size);
if (session->tracehandler) if(session->tracehandler)
(session->tracehandler)(session, session->tracehandler_context, (session->tracehandler)(session, session->tracehandler_context,
buffer, used); buffer, used);
else else
@@ -86,9 +86,9 @@ debugdump(LIBSSH2_SESSION * session,
/* hex not disabled, show it */ /* hex not disabled, show it */
for(c = 0; c < width; c++) { for(c = 0; c < width; c++) {
if (i + c < size) { if(i + c < size) {
buffer[used++] = hex_chars[(ptr[i+c] >> 4) & 0xF]; buffer[used++] = hex_chars[(ptr[i + c] >> 4) & 0xF];
buffer[used++] = hex_chars[ptr[i+c] & 0xF]; buffer[used++] = hex_chars[ptr[i + c] & 0xF];
} }
else { else {
buffer[used++] = ' '; buffer[used++] = ' ';
@@ -96,7 +96,7 @@ debugdump(LIBSSH2_SESSION * session,
} }
buffer[used++] = ' '; buffer[used++] = ' ';
if ((width/2) - 1 == c) if((width/2) - 1 == c)
buffer[used++] = ' '; buffer[used++] = ' ';
} }
@@ -110,7 +110,7 @@ debugdump(LIBSSH2_SESSION * session,
buffer[used++] = '\n'; buffer[used++] = '\n';
buffer[used] = 0; buffer[used] = 0;
if (session->tracehandler) if(session->tracehandler)
(session->tracehandler)(session, session->tracehandler_context, (session->tracehandler)(session, session->tracehandler_context,
buffer, used); buffer, used);
else else
@@ -138,8 +138,8 @@ decrypt(LIBSSH2_SESSION * session, unsigned char *source,
we risk losing those extra bytes */ we risk losing those extra bytes */
assert((len % blocksize) == 0); assert((len % blocksize) == 0);
while (len >= blocksize) { while(len >= blocksize) {
if (session->remote.crypt->crypt(session, source, blocksize, if(session->remote.crypt->crypt(session, source, blocksize,
&session->remote.crypt_abstract)) { &session->remote.crypt_abstract)) {
LIBSSH2_FREE(session, p->payload); LIBSSH2_FREE(session, p->payload);
return LIBSSH2_ERROR_DECRYPT; return LIBSSH2_ERROR_DECRYPT;
@@ -169,11 +169,11 @@ fullpacket(LIBSSH2_SESSION * session, int encrypted /* 1 or 0 */ )
int rc; int rc;
int compressed; int compressed;
if (session->fullpacket_state == libssh2_NB_state_idle) { if(session->fullpacket_state == libssh2_NB_state_idle) {
session->fullpacket_macstate = LIBSSH2_MAC_CONFIRMED; session->fullpacket_macstate = LIBSSH2_MAC_CONFIRMED;
session->fullpacket_payload_len = p->packet_length - 1; session->fullpacket_payload_len = p->packet_length - 1;
if (encrypted) { if(encrypted) {
/* Calculate MAC hash */ /* Calculate MAC hash */
session->remote.mac->hash(session, macbuf, /* store hash here */ session->remote.mac->hash(session, macbuf, /* store hash here */
@@ -188,7 +188,7 @@ fullpacket(LIBSSH2_SESSION * session, int encrypted /* 1 or 0 */ )
* buffer. Note that 'payload_len' here is the packet_length * buffer. Note that 'payload_len' here is the packet_length
* field which includes the padding but not the MAC. * field which includes the padding but not the MAC.
*/ */
if (memcmp(macbuf, p->payload + session->fullpacket_payload_len, if(memcmp(macbuf, p->payload + session->fullpacket_payload_len,
session->remote.mac->mac_len)) { session->remote.mac->mac_len)) {
session->fullpacket_macstate = LIBSSH2_MAC_INVALID; session->fullpacket_macstate = LIBSSH2_MAC_INVALID;
} }
@@ -206,7 +206,7 @@ fullpacket(LIBSSH2_SESSION * session, int encrypted /* 1 or 0 */ )
((session->state & LIBSSH2_STATE_AUTHENTICATED) || ((session->state & LIBSSH2_STATE_AUTHENTICATED) ||
session->local.comp->use_in_auth); session->local.comp->use_in_auth);
if (compressed && session->remote.comp_abstract) { if(compressed && session->remote.comp_abstract) {
/* /*
* The buffer for the decompression (remote.comp_abstract) is * The buffer for the decompression (remote.comp_abstract) is
* initialised in time when it is needed so as long it is NULL we * initialised in time when it is needed so as long it is NULL we
@@ -237,13 +237,13 @@ fullpacket(LIBSSH2_SESSION * session, int encrypted /* 1 or 0 */ )
session->fullpacket_state = libssh2_NB_state_created; session->fullpacket_state = libssh2_NB_state_created;
} }
if (session->fullpacket_state == libssh2_NB_state_created) { if(session->fullpacket_state == libssh2_NB_state_created) {
rc = _libssh2_packet_add(session, p->payload, rc = _libssh2_packet_add(session, p->payload,
session->fullpacket_payload_len, session->fullpacket_payload_len,
session->fullpacket_macstate); session->fullpacket_macstate);
if (rc == LIBSSH2_ERROR_EAGAIN) if(rc == LIBSSH2_ERROR_EAGAIN)
return rc; return rc;
if (rc) { if(rc) {
session->fullpacket_state = libssh2_NB_state_idle; session->fullpacket_state = libssh2_NB_state_idle;
return rc; return rc;
} }
@@ -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;
@@ -298,7 +297,7 @@ int _libssh2_transport_read(LIBSSH2_SESSION * session)
* of packet_read, then don't redirect, as that would be an infinite loop! * of packet_read, then don't redirect, as that would be an infinite loop!
*/ */
if (session->state & LIBSSH2_STATE_EXCHANGING_KEYS && if(session->state & LIBSSH2_STATE_EXCHANGING_KEYS &&
!(session->state & LIBSSH2_STATE_KEX_ACTIVE)) { !(session->state & LIBSSH2_STATE_KEX_ACTIVE)) {
/* Whoever wants a packet won't get anything until the key re-exchange /* Whoever wants a packet won't get anything until the key re-exchange
@@ -307,7 +306,7 @@ int _libssh2_transport_read(LIBSSH2_SESSION * session)
_libssh2_debug(session, LIBSSH2_TRACE_TRANS, "Redirecting into the" _libssh2_debug(session, LIBSSH2_TRACE_TRANS, "Redirecting into the"
" key re-exchange from _libssh2_transport_read"); " key re-exchange from _libssh2_transport_read");
rc = _libssh2_kex_exchange(session, 1, &session->startup_key_state); rc = _libssh2_kex_exchange(session, 1, &session->startup_key_state);
if (rc) if(rc)
return rc; return rc;
} }
@@ -316,20 +315,21 @@ int _libssh2_transport_read(LIBSSH2_SESSION * session)
* I know this is very ugly and not a really good use of "goto", but * I know this is very ugly and not a really good use of "goto", but
* this case statement would be even uglier to do it any other way * this case statement would be even uglier to do it any other way
*/ */
if (session->readPack_state == libssh2_NB_state_jump1) { if(session->readPack_state == libssh2_NB_state_jump1) {
session->readPack_state = libssh2_NB_state_idle; session->readPack_state = libssh2_NB_state_idle;
encrypted = session->readPack_encrypted; encrypted = session->readPack_encrypted;
goto libssh2_transport_read_point1; goto libssh2_transport_read_point1;
} }
do { do {
if (session->socket_state == LIBSSH2_SOCKET_DISCONNECTED) { if(session->socket_state == LIBSSH2_SOCKET_DISCONNECTED) {
return LIBSSH2_ERROR_NONE; return LIBSSH2_ERROR_NONE;
} }
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 */
@@ -348,18 +348,19 @@ int _libssh2_transport_read(LIBSSH2_SESSION * session)
/* if remainbuf turns negative we have a bad internal error */ /* if remainbuf turns negative we have a bad internal error */
assert(remainbuf >= 0); assert(remainbuf >= 0);
if (remainbuf < blocksize) { if(remainbuf < blocksize) {
/* If we have less than a blocksize left, it is too /* If we have less than a blocksize left, it is too
little data to deal with, read more */ little data to deal with, read more */
ssize_t nread; ssize_t nread;
/* move any remainder to the start of the buffer so /* move any remainder to the start of the buffer so
that we can do a full refill */ that we can do a full refill */
if (remainbuf) { if(remainbuf) {
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;
} }
@@ -369,10 +370,10 @@ int _libssh2_transport_read(LIBSSH2_SESSION * session)
LIBSSH2_RECV(session, &p->buf[remainbuf], LIBSSH2_RECV(session, &p->buf[remainbuf],
PACKETBUFSIZE - remainbuf, PACKETBUFSIZE - remainbuf,
LIBSSH2_SOCKET_RECV_FLAGS(session)); LIBSSH2_SOCKET_RECV_FLAGS(session));
if (nread <= 0) { if(nread <= 0) {
/* check if this is due to EAGAIN and return the special /* check if this is due to EAGAIN and return the special
return code if so, error out normally otherwise */ return code if so, error out normally otherwise */
if ((nread < 0) && (nread == -EAGAIN)) { if((nread < 0) && (nread == -EAGAIN)) {
session->socket_block_directions |= session->socket_block_directions |=
LIBSSH2_SESSION_BLOCK_INBOUND; LIBSSH2_SESSION_BLOCK_INBOUND;
return LIBSSH2_ERROR_EAGAIN; return LIBSSH2_ERROR_EAGAIN;
@@ -398,12 +399,14 @@ int _libssh2_transport_read(LIBSSH2_SESSION * session)
/* how much data to deal with from the buffer */ /* how much data to deal with from the buffer */
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. */
if (numbytes < blocksize) { if(numbytes < blocksize) {
/* we can't act on anything less than blocksize, but this /* we can't act on anything less than blocksize, but this
check is only done for the initial block since once we have check is only done for the initial block since once we have
got the start of a block we can in fact deal with fractions got the start of a block we can in fact deal with fractions
@@ -413,15 +416,16 @@ int _libssh2_transport_read(LIBSSH2_SESSION * session)
return LIBSSH2_ERROR_EAGAIN; return LIBSSH2_ERROR_EAGAIN;
} }
if (encrypted) { if(encrypted) {
rc = decrypt(session, &p->buf[p->readidx], block, blocksize); rc = decrypt(session, &p->buf[p->readidx], block, blocksize);
if (rc != LIBSSH2_ERROR_NONE) { if(rc != LIBSSH2_ERROR_NONE) {
return rc; return rc;
} }
/* 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;
} }
@@ -463,28 +465,29 @@ int _libssh2_transport_read(LIBSSH2_SESSION * session)
* or less (including length, padding length, payload, * or less (including length, padding length, payload,
* padding, and MAC.)." * padding, and MAC.)."
*/ */
if (total_num > LIBSSH2_PACKET_MAXPAYLOAD) { if(total_num > LIBSSH2_PACKET_MAXPAYLOAD) {
return LIBSSH2_ERROR_OUT_OF_BOUNDARY; return LIBSSH2_ERROR_OUT_OF_BOUNDARY;
} }
/* Get a packet handle put data into. We get one to /* Get a packet handle put data into. We get one to
hold all data, including padding and MAC. */ hold all data, including padding and MAC. */
p->payload = LIBSSH2_ALLOC(session, total_num); p->payload = LIBSSH2_ALLOC(session, total_num);
if (!p->payload) { if(!p->payload) {
return LIBSSH2_ERROR_ALLOC; return LIBSSH2_ERROR_ALLOC;
} }
p->total_num = total_num; p->total_num = total_num;
/* init write pointer to start of payload buffer */ /* init write pointer to start of payload buffer */
p->wptr = p->payload; p->wptr = p->payload;
if (blocksize > 5) { if(blocksize > 5) {
/* 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;
} }
} }
@@ -501,13 +504,13 @@ int _libssh2_transport_read(LIBSSH2_SESSION * session)
package */ package */
remainpack = p->total_num - p->data_num; remainpack = p->total_num - p->data_num;
if (numbytes > remainpack) { if(numbytes > remainpack) {
/* if we have more data in the buffer than what is going into this /* if we have more data in the buffer than what is going into this
particular packet, we limit this round to this packet only */ particular packet, we limit this round to this packet only */
numbytes = remainpack; numbytes = remainpack;
} }
if (encrypted) { if(encrypted) {
/* At the end of the incoming stream, there is a MAC, /* At the end of the incoming stream, there is a MAC,
and we don't want to decrypt that since we need it and we don't want to decrypt that since we need it
"raw". We MUST however decrypt the padding data "raw". We MUST however decrypt the padding data
@@ -517,13 +520,14 @@ int _libssh2_transport_read(LIBSSH2_SESSION * session)
/* if what we have plus numbytes is bigger than the /* if what we have plus numbytes is bigger than the
total minus the skip margin, we should lower the total minus the skip margin, we should lower the
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;
if (frac) { if(frac) {
/* not an aligned amount of blocks, /* not an aligned amount of blocks,
align it */ align it */
numdecrypt -= frac; numdecrypt -= frac;
@@ -532,16 +536,17 @@ 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;
} }
/* if there are bytes to decrypt, do that */ /* if there are bytes to decrypt, do that */
if (numdecrypt > 0) { if(numdecrypt > 0) {
/* now decrypt the lot */ /* now decrypt the lot */
rc = decrypt(session, &p->buf[p->readidx], p->wptr, numdecrypt); rc = decrypt(session, &p->buf[p->readidx], p->wptr, numdecrypt);
if (rc != LIBSSH2_ERROR_NONE) { if(rc != LIBSSH2_ERROR_NONE) {
p->total_num = 0; /* no packet buffer available */ p->total_num = 0; /* no packet buffer available */
return rc; return rc;
} }
@@ -559,9 +564,9 @@ int _libssh2_transport_read(LIBSSH2_SESSION * session)
/* if there are bytes to copy that aren't decrypted, simply /* if there are bytes to copy that aren't decrypted, simply
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 {
@@ -580,21 +585,21 @@ int _libssh2_transport_read(LIBSSH2_SESSION * session)
current packet */ current packet */
remainpack = p->total_num - p->data_num; remainpack = p->total_num - p->data_num;
if (!remainpack) { if(!remainpack) {
/* we have a full packet */ /* we have a full packet */
libssh2_transport_read_point1: libssh2_transport_read_point1:
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;
@@ -607,7 +612,7 @@ int _libssh2_transport_read(LIBSSH2_SESSION * session)
return rc; return rc;
} }
} while (1); /* loop */ } while(1); /* loop */
return LIBSSH2_ERROR_SOCKET_RECV; /* we never reach this point */ return LIBSSH2_ERROR_SOCKET_RECV; /* we never reach this point */
} }
@@ -620,13 +625,13 @@ send_existing(LIBSSH2_SESSION *session, const unsigned char *data,
ssize_t length; ssize_t length;
struct transportpacket *p = &session->packet; struct transportpacket *p = &session->packet;
if (!p->olen) { if(!p->olen) {
*ret = 0; *ret = 0;
return LIBSSH2_ERROR_NONE; return LIBSSH2_ERROR_NONE;
} }
/* send as much as possible of the existing packet */ /* send as much as possible of the existing packet */
if ((data != p->odata) || (data_len != p->olen)) { if((data != p->odata) || (data_len != p->olen)) {
/* When we are about to complete the sending of a packet, it is vital /* When we are about to complete the sending of a packet, it is vital
that the caller doesn't try to send a new/different packet since that the caller doesn't try to send a new/different packet since
we don't add this one up until the previous one has been sent. To we don't add this one up until the previous one has been sent. To
@@ -642,7 +647,7 @@ send_existing(LIBSSH2_SESSION *session, const unsigned char *data,
rc = LIBSSH2_SEND(session, &p->outbuf[p->osent], length, rc = LIBSSH2_SEND(session, &p->outbuf[p->osent], length,
LIBSSH2_SOCKET_SEND_FLAGS(session)); LIBSSH2_SOCKET_SEND_FLAGS(session));
if (rc < 0) if(rc < 0)
_libssh2_debug(session, LIBSSH2_TRACE_SOCKET, _libssh2_debug(session, LIBSSH2_TRACE_SOCKET,
"Error sending %d bytes: %d", length, -rc); "Error sending %d bytes: %d", length, -rc);
else { else {
@@ -653,7 +658,7 @@ send_existing(LIBSSH2_SESSION *session, const unsigned char *data,
&p->outbuf[p->osent], rc); &p->outbuf[p->osent], rc);
} }
if (rc == length) { if(rc == length) {
/* the remainder of the package was sent */ /* the remainder of the package was sent */
p->ototal_num = 0; p->ototal_num = 0;
p->olen = 0; p->olen = 0;
@@ -663,9 +668,9 @@ send_existing(LIBSSH2_SESSION *session, const unsigned char *data,
return LIBSSH2_ERROR_NONE; return LIBSSH2_ERROR_NONE;
} }
else if (rc < 0) { else if(rc < 0) {
/* nothing was sent */ /* nothing was sent */
if (rc != -EAGAIN) if(rc != -EAGAIN)
/* send failure! */ /* send failure! */
return LIBSSH2_ERROR_SOCKET_SEND; return LIBSSH2_ERROR_SOCKET_SEND;
@@ -725,14 +730,14 @@ int _libssh2_transport_send(LIBSSH2_SESSION *session,
* *
* See the similar block in _libssh2_transport_read for more details. * See the similar block in _libssh2_transport_read for more details.
*/ */
if (session->state & LIBSSH2_STATE_EXCHANGING_KEYS && if(session->state & LIBSSH2_STATE_EXCHANGING_KEYS &&
!(session->state & LIBSSH2_STATE_KEX_ACTIVE)) { !(session->state & LIBSSH2_STATE_KEX_ACTIVE)) {
/* Don't write any new packets if we're still in the middle of a key /* Don't write any new packets if we're still in the middle of a key
* exchange. */ * exchange. */
_libssh2_debug(session, LIBSSH2_TRACE_TRANS, "Redirecting into the" _libssh2_debug(session, LIBSSH2_TRACE_TRANS, "Redirecting into the"
" key re-exchange from _libssh2_transport_send"); " key re-exchange from _libssh2_transport_send");
rc = _libssh2_kex_exchange(session, 1, &session->startup_key_state); rc = _libssh2_kex_exchange(session, 1, &session->startup_key_state);
if (rc) if(rc)
return rc; return rc;
} }
@@ -743,12 +748,12 @@ int _libssh2_transport_send(LIBSSH2_SESSION *session,
/* FIRST, check if we have a pending write to complete. send_existing /* FIRST, check if we have a pending write to complete. send_existing
only sanity-check data and data_len and not data2 and data2_len!! */ only sanity-check data and data_len and not data2 and data2_len!! */
rc = send_existing(session, data, data_len, &ret); rc = send_existing(session, data, data_len, &ret);
if (rc) if(rc)
return rc; return rc;
session->socket_block_directions &= ~LIBSSH2_SESSION_BLOCK_OUTBOUND; session->socket_block_directions &= ~LIBSSH2_SESSION_BLOCK_OUTBOUND;
if (ret) if(ret)
/* set by send_existing if data was sent */ /* set by send_existing if data was sent */
return rc; return rc;
@@ -760,7 +765,7 @@ int _libssh2_transport_send(LIBSSH2_SESSION *session,
((session->state & LIBSSH2_STATE_AUTHENTICATED) || ((session->state & LIBSSH2_STATE_AUTHENTICATED) ||
session->local.comp->use_in_auth); session->local.comp->use_in_auth);
if (encrypted && compressed) { if(encrypted && compressed) {
/* the idea here is that these function must fail if the output gets /* the idea here is that these function must fail if the output gets
larger than what fits in the assigned buffer so thus they don't larger than what fits in the assigned buffer so thus they don't
check the input size as we don't know how much it compresses */ check the input size as we don't know how much it compresses */
@@ -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);
} }
@@ -801,7 +807,7 @@ int _libssh2_transport_send(LIBSSH2_SESSION *session,
/* copy the payload data */ /* copy the payload data */
memcpy(&p->outbuf[5], data, data_len); memcpy(&p->outbuf[5], data, data_len);
if(data2 && data2_len) if(data2 && data2_len)
memcpy(&p->outbuf[5+data_len], data2, data2_len); memcpy(&p->outbuf[5 + data_len], data2, data2_len);
data_len += data2_len; /* use the combined length */ data_len += data2_len; /* use the combined length */
} }
@@ -825,7 +831,7 @@ int _libssh2_transport_send(LIBSSH2_SESSION *session,
/* if the padding becomes too small we add another blocksize worth /* if the padding becomes too small we add another blocksize worth
of it (taken from the original libssh2 where it didn't have any of it (taken from the original libssh2 where it didn't have any
real explanation) */ real explanation) */
if (padding_length < 4) { if(padding_length < 4) {
padding_length += blocksize; padding_length += blocksize;
} }
#ifdef RANDOM_PADDING #ifdef RANDOM_PADDING
@@ -854,7 +860,7 @@ int _libssh2_transport_send(LIBSSH2_SESSION *session,
/* fill the padding area with random junk */ /* fill the padding area with random junk */
_libssh2_random(p->outbuf + 5 + data_len, padding_length); _libssh2_random(p->outbuf + 5 + data_len, padding_length);
if (encrypted) { if(encrypted) {
size_t i; size_t i;
/* Calculate MAC hash. Put the output at index packet_length, /* Calculate MAC hash. Put the output at index packet_length,
@@ -870,7 +876,7 @@ int _libssh2_transport_send(LIBSSH2_SESSION *session,
The MAC field is not encrypted. */ The MAC field is not encrypted. */
for(i = 0; i < packet_length; i += session->local.crypt->blocksize) { for(i = 0; i < packet_length; i += session->local.crypt->blocksize) {
unsigned char *ptr = &p->outbuf[i]; unsigned char *ptr = &p->outbuf[i];
if (session->local.crypt->crypt(session, ptr, if(session->local.crypt->crypt(session, ptr,
session->local.crypt->blocksize, session->local.crypt->blocksize,
&session->local.crypt_abstract)) &session->local.crypt_abstract))
return LIBSSH2_ERROR_ENCRYPT; /* encryption failure */ return LIBSSH2_ERROR_ENCRYPT; /* encryption failure */
@@ -881,7 +887,7 @@ int _libssh2_transport_send(LIBSSH2_SESSION *session,
ret = LIBSSH2_SEND(session, p->outbuf, total_length, ret = LIBSSH2_SEND(session, p->outbuf, total_length,
LIBSSH2_SOCKET_SEND_FLAGS(session)); LIBSSH2_SOCKET_SEND_FLAGS(session));
if (ret < 0) if(ret < 0)
_libssh2_debug(session, LIBSSH2_TRACE_SOCKET, _libssh2_debug(session, LIBSSH2_TRACE_SOCKET,
"Error sending %d bytes: %d", total_length, -ret); "Error sending %d bytes: %d", total_length, -ret);
else { else {
@@ -890,8 +896,8 @@ int _libssh2_transport_send(LIBSSH2_SESSION *session,
debugdump(session, "libssh2_transport_write send()", p->outbuf, ret); debugdump(session, "libssh2_transport_write send()", p->outbuf, ret);
} }
if (ret != total_length) { if(ret != total_length) {
if (ret >= 0 || ret == -EAGAIN) { if(ret >= 0 || ret == -EAGAIN) {
/* the whole packet could not be sent, save the rest */ /* the whole packet could not be sent, save the rest */
session->socket_block_directions |= LIBSSH2_SESSION_BLOCK_OUTBOUND; session->socket_block_directions |= LIBSSH2_SESSION_BLOCK_OUTBOUND;
p->odata = orgdata; p->odata = orgdata;

File diff suppressed because it is too large Load Diff

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 */

File diff suppressed because it is too large Load Diff

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" />