mirror of
https://github.com/php-win-ext/libssh2.git
synced 2026-03-24 17:12:15 +01:00
Compare commits
1 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
60401ec4c2 |
@@ -98,6 +98,14 @@ if(BUILD_TESTING)
|
||||
add_subdirectory(tests)
|
||||
endif()
|
||||
|
||||
option(LINT "Check style while building" OFF)
|
||||
if(LINT)
|
||||
add_custom_target(lint ALL
|
||||
./ci/checksrc.sh
|
||||
WORKING_DIRECTORY ${libssh2_SOURCE_DIR})
|
||||
add_dependencies(libssh2 lint)
|
||||
endif()
|
||||
|
||||
add_subdirectory(docs)
|
||||
|
||||
feature_summary(WHAT ALL)
|
||||
|
||||
4
COPYING
4
COPYING
@@ -2,8 +2,10 @@
|
||||
* Copyright (c) 2005,2006 Mikhail Gusarov <dottedmag@dottedmag.net>
|
||||
* Copyright (c) 2006-2007 The Written Word, Inc.
|
||||
* Copyright (c) 2007 Eli Fant <elifantu@mail.ru>
|
||||
* Copyright (c) 2009-2014 Daniel Stenberg
|
||||
* Copyright (c) 2009-2021 Daniel Stenberg
|
||||
* Copyright (C) 2008, 2009 Simon Josefsson
|
||||
* Copyright (c) 2000 Markus Friedl
|
||||
* Copyright (c) 2015 Microsoft Corp.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms,
|
||||
|
||||
@@ -43,7 +43,7 @@ os400/libssh2rpg/libssh2_publickey.rpgle \
|
||||
os400/libssh2rpg/libssh2_sftp.rpgle \
|
||||
Makefile.os400qc3.inc
|
||||
|
||||
EXTRA_DIST = $(WIN32FILES) buildconf $(NETWAREFILES) get_ver.awk \
|
||||
EXTRA_DIST = $(WIN32FILES) $(NETWAREFILES) get_ver.awk \
|
||||
maketgz NMakefile RELEASE-NOTES libssh2.pc.in $(VMSFILES) config.rpath \
|
||||
CMakeLists.txt cmake $(OS400FILES)
|
||||
|
||||
@@ -119,7 +119,7 @@ $(DSP): win32/msvcproj.head win32/msvcproj.foot Makefile.am
|
||||
for file in $$sorted_hdrs; do \
|
||||
echo "# Begin Source File"; \
|
||||
echo ""; \
|
||||
if [ "$$file" == "libssh2_config.h" ]; \
|
||||
if [ "$$file" = "libssh2_config.h" ]; \
|
||||
then \
|
||||
echo "SOURCE=.\\"$$file; \
|
||||
else \
|
||||
@@ -149,4 +149,6 @@ $(VCPROJ): win32/vc8proj.head win32/vc8proj.foot Makefile.am
|
||||
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
|
||||
perl src/checksrc.pl -i4 -m79 -ASIZEOFNOPAREN -ASNPRINTF -ACOPYRIGHT \
|
||||
-AFOPENMODE -Wsrc/libssh2_config.h src/*.[ch] include/*.h example/*.c \
|
||||
tests/*.[ch]
|
||||
|
||||
44
Makefile.in
44
Makefile.in
@@ -1,7 +1,7 @@
|
||||
# Makefile.in generated by automake 1.16.1 from Makefile.am.
|
||||
# Makefile.in generated by automake 1.16.4 from Makefile.am.
|
||||
# @configure_input@
|
||||
|
||||
# Copyright (C) 1994-2018 Free Software Foundation, Inc.
|
||||
# Copyright (C) 1994-2021 Free Software Foundation, Inc.
|
||||
|
||||
# This Makefile.in is free software; the Free Software Foundation
|
||||
# gives unlimited permission to copy and/or distribute it,
|
||||
@@ -105,8 +105,7 @@ DIST_COMMON = $(srcdir)/Makefile.am $(top_srcdir)/configure \
|
||||
am__CONFIG_DISTCLEAN_FILES = config.status config.cache config.log \
|
||||
configure.lineno config.status.lineno
|
||||
mkinstalldirs = $(install_sh) -d
|
||||
CONFIG_HEADER = $(top_builddir)/src/libssh2_config.h \
|
||||
$(top_builddir)/example/libssh2_config.h
|
||||
CONFIG_HEADER = $(top_builddir)/src/libssh2_config.h
|
||||
CONFIG_CLEAN_FILES = libssh2.pc
|
||||
CONFIG_CLEAN_VPATH_FILES =
|
||||
AM_V_P = $(am__v_P_@AM_V@)
|
||||
@@ -192,9 +191,6 @@ am__define_uniq_tagged_files = \
|
||||
unique=`for i in $$list; do \
|
||||
if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
|
||||
done | $(am__uniquify_input)`
|
||||
ETAGS = etags
|
||||
CTAGS = ctags
|
||||
CSCOPE = cscope
|
||||
DIST_SUBDIRS = src tests docs example
|
||||
am__DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/Makefile.inc \
|
||||
$(srcdir)/libssh2.pc.in COPYING ChangeLog NEWS README compile \
|
||||
@@ -238,6 +234,8 @@ am__relativize = \
|
||||
DIST_ARCHIVES = $(distdir).tar.gz
|
||||
GZIP_ENV = --best
|
||||
DIST_TARGETS = dist-gzip
|
||||
# Exists only to be overridden by the user if desired.
|
||||
AM_DISTCHECK_DVI_TARGET = dvi
|
||||
distuninstallcheck_listfiles = find . -type f -print
|
||||
am__distuninstallcheck_listfiles = $(distuninstallcheck_listfiles) \
|
||||
| sed 's|^\./|$(prefix)/|' | grep -v '$(infodir)/dir$$'
|
||||
@@ -257,6 +255,12 @@ CCDEPMODE = @CCDEPMODE@
|
||||
CFLAGS = @CFLAGS@
|
||||
CPP = @CPP@
|
||||
CPPFLAGS = @CPPFLAGS@
|
||||
CSCOPE = @CSCOPE@
|
||||
CTAGS = @CTAGS@
|
||||
CXX = @CXX@
|
||||
CXXCPP = @CXXCPP@
|
||||
CXXDEPMODE = @CXXDEPMODE@
|
||||
CXXFLAGS = @CXXFLAGS@
|
||||
CYGPATH_W = @CYGPATH_W@
|
||||
DEFS = @DEFS@
|
||||
DEPDIR = @DEPDIR@
|
||||
@@ -267,6 +271,7 @@ ECHO_C = @ECHO_C@
|
||||
ECHO_N = @ECHO_N@
|
||||
ECHO_T = @ECHO_T@
|
||||
EGREP = @EGREP@
|
||||
ETAGS = @ETAGS@
|
||||
EXEEXT = @EXEEXT@
|
||||
FGREP = @FGREP@
|
||||
GREP = @GREP@
|
||||
@@ -300,6 +305,7 @@ LIBSSL_PREFIX = @LIBSSL_PREFIX@
|
||||
LIBTOOL = @LIBTOOL@
|
||||
LIBZ = @LIBZ@
|
||||
LIBZ_PREFIX = @LIBZ_PREFIX@
|
||||
LIB_FUZZING_ENGINE = @LIB_FUZZING_ENGINE@
|
||||
LIPO = @LIPO@
|
||||
LN_S = @LN_S@
|
||||
LTLIBBCRYPT = @LTLIBBCRYPT@
|
||||
@@ -341,6 +347,7 @@ abs_top_builddir = @abs_top_builddir@
|
||||
abs_top_srcdir = @abs_top_srcdir@
|
||||
ac_ct_AR = @ac_ct_AR@
|
||||
ac_ct_CC = @ac_ct_CC@
|
||||
ac_ct_CXX = @ac_ct_CXX@
|
||||
ac_ct_DUMPBIN = @ac_ct_DUMPBIN@
|
||||
am__include = @am__include@
|
||||
am__leading_dot = @am__leading_dot@
|
||||
@@ -425,7 +432,7 @@ os400/libssh2rpg/libssh2_publickey.rpgle \
|
||||
os400/libssh2rpg/libssh2_sftp.rpgle \
|
||||
Makefile.os400qc3.inc
|
||||
|
||||
EXTRA_DIST = $(WIN32FILES) buildconf $(NETWAREFILES) get_ver.awk \
|
||||
EXTRA_DIST = $(WIN32FILES) $(NETWAREFILES) get_ver.awk \
|
||||
maketgz NMakefile RELEASE-NOTES libssh2.pc.in $(VMSFILES) config.rpath \
|
||||
CMakeLists.txt cmake $(OS400FILES)
|
||||
|
||||
@@ -438,10 +445,10 @@ CRYPTO_HHEADERS = openssl.h wincng.h mbedtls.h
|
||||
CSOURCES = channel.c comp.c crypt.c hostkey.c kex.c mac.c misc.c \
|
||||
packet.c publickey.c scp.c session.c sftp.c userauth.c transport.c \
|
||||
version.c knownhost.c agent.c $(CRYPTO_CSOURCES) pem.c keepalive.c global.c \
|
||||
blowfish.c bcrypt_pbkdf.c
|
||||
blowfish.c bcrypt_pbkdf.c agent_win.c
|
||||
|
||||
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 blf.h
|
||||
mac.h misc.h packet.h userauth.h session.h sftp.h crypto.h blf.h agent.h
|
||||
|
||||
# Makefile.inc provides the CSOURCES and HHEADERS defines
|
||||
WIN32SOURCES = $(CSOURCES)
|
||||
@@ -642,7 +649,6 @@ cscopelist-am: $(am__tagged_files)
|
||||
distclean-tags:
|
||||
-rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
|
||||
-rm -f cscope.out cscope.in.out cscope.po.out cscope.files
|
||||
|
||||
distdir: $(BUILT_SOURCES)
|
||||
$(MAKE) $(AM_MAKEFLAGS) distdir-am
|
||||
|
||||
@@ -729,6 +735,10 @@ dist-xz: distdir
|
||||
tardir=$(distdir) && $(am__tar) | XZ_OPT=$${XZ_OPT--e} xz -c >$(distdir).tar.xz
|
||||
$(am__post_remove_distdir)
|
||||
|
||||
dist-zstd: distdir
|
||||
tardir=$(distdir) && $(am__tar) | zstd -c $${ZSTD_CLEVEL-$${ZSTD_OPT--19}} >$(distdir).tar.zst
|
||||
$(am__post_remove_distdir)
|
||||
|
||||
dist-tarZ: distdir
|
||||
@echo WARNING: "Support for distribution archives compressed with" \
|
||||
"legacy program 'compress' is deprecated." >&2
|
||||
@@ -771,6 +781,8 @@ distcheck: dist
|
||||
eval GZIP= gzip $(GZIP_ENV) -dc $(distdir).shar.gz | unshar ;;\
|
||||
*.zip*) \
|
||||
unzip $(distdir).zip ;;\
|
||||
*.tar.zst*) \
|
||||
zstd -dc $(distdir).tar.zst | $(am__untar) ;;\
|
||||
esac
|
||||
chmod -R a-w $(distdir)
|
||||
chmod u+w $(distdir)
|
||||
@@ -786,7 +798,7 @@ distcheck: dist
|
||||
$(DISTCHECK_CONFIGURE_FLAGS) \
|
||||
--srcdir=../.. --prefix="$$dc_install_base" \
|
||||
&& $(MAKE) $(AM_MAKEFLAGS) \
|
||||
&& $(MAKE) $(AM_MAKEFLAGS) dvi \
|
||||
&& $(MAKE) $(AM_MAKEFLAGS) $(AM_DISTCHECK_DVI_TARGET) \
|
||||
&& $(MAKE) $(AM_MAKEFLAGS) check \
|
||||
&& $(MAKE) $(AM_MAKEFLAGS) install \
|
||||
&& $(MAKE) $(AM_MAKEFLAGS) installcheck \
|
||||
@@ -952,7 +964,7 @@ uninstall-am: uninstall-includeHEADERS uninstall-pkgconfigDATA
|
||||
am--refresh check check-am clean clean-cscope clean-generic \
|
||||
clean-libtool cscope cscopelist-am ctags ctags-am dist \
|
||||
dist-all dist-bzip2 dist-gzip dist-hook dist-lzip dist-shar \
|
||||
dist-tarZ dist-xz dist-zip distcheck distclean \
|
||||
dist-tarZ dist-xz dist-zip dist-zstd distcheck distclean \
|
||||
distclean-generic distclean-libtool distclean-tags \
|
||||
distcleancheck distdir distuninstallcheck dvi dvi-am html \
|
||||
html-am info info-am install install-am install-data \
|
||||
@@ -1028,7 +1040,7 @@ $(DSP): win32/msvcproj.head win32/msvcproj.foot Makefile.am
|
||||
for file in $$sorted_hdrs; do \
|
||||
echo "# Begin Source File"; \
|
||||
echo ""; \
|
||||
if [ "$$file" == "libssh2_config.h" ]; \
|
||||
if [ "$$file" = "libssh2_config.h" ]; \
|
||||
then \
|
||||
echo "SOURCE=.\\"$$file; \
|
||||
else \
|
||||
@@ -1058,7 +1070,9 @@ $(VCPROJ): win32/vc8proj.head win32/vc8proj.foot Makefile.am
|
||||
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
|
||||
perl src/checksrc.pl -i4 -m79 -ASIZEOFNOPAREN -ASNPRINTF -ACOPYRIGHT \
|
||||
-AFOPENMODE -Wsrc/libssh2_config.h src/*.[ch] include/*.h example/*.c \
|
||||
tests/*.[ch]
|
||||
|
||||
# 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.
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
CSOURCES = channel.c comp.c crypt.c hostkey.c kex.c mac.c misc.c \
|
||||
packet.c publickey.c scp.c session.c sftp.c userauth.c transport.c \
|
||||
version.c knownhost.c agent.c $(CRYPTO_CSOURCES) pem.c keepalive.c global.c \
|
||||
blowfish.c bcrypt_pbkdf.c
|
||||
blowfish.c bcrypt_pbkdf.c agent_win.c
|
||||
|
||||
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 blf.h
|
||||
mac.h misc.h packet.h userauth.h session.h sftp.h crypto.h blf.h agent.h
|
||||
|
||||
14
README.md
14
README.md
@@ -1,14 +0,0 @@
|
||||
# libssh2
|
||||
|
||||
libssh2 is a client-side C library implementing the SSH2 protocol.
|
||||
|
||||
# Building for PHP
|
||||
|
||||
libssh2 depends on openssl and zlib. To build follow these steps:
|
||||
|
||||
* create a directory named "deps" at the level of the libssh2 source dir and put the dependencies there
|
||||
* build libssh2
|
||||
* use win32/libssh2.vcproj to build with VS2008
|
||||
* use win32/libssh2.vc11.sln to build with VS2012
|
||||
* use win32/libssh2.vc14.sln to build with VS2015
|
||||
* use win32/libssh2.vc15.sln to build with VS2017
|
||||
@@ -1,44 +1,62 @@
|
||||
libssh2 1.9.0
|
||||
libssh2 1.10
|
||||
|
||||
This release includes the following enhancements and bugfixes:
|
||||
|
||||
o adds ECDSA keys and host key support when using OpenSSL
|
||||
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 adds agent forwarding support
|
||||
o adds OpenSSH Agent support on Windows
|
||||
o adds ECDSA key support using the Mbed TLS backend
|
||||
o adds ECDSA cert authentication
|
||||
o adds diffie-hellman-group14-sha256, diffie-hellman-group16-sha512,
|
||||
diffie-hellman-group18-sha512 key exchanges
|
||||
o adds support for PKIX key reading when using ed25519 with OpenSSL
|
||||
o adds support for EWOULDBLOCK on VMS systems
|
||||
o adds support for building with OpenSSL 3
|
||||
o adds support for using FIPS mode in OpenSSL
|
||||
o adds debug symbols when building with MSVC
|
||||
o adds support for building on the 3DS
|
||||
o adds unicode build support on Windows
|
||||
o restores os400 building
|
||||
o increases min, max and opt Diffie Hellman group values
|
||||
o improves portiablity of the make file
|
||||
o improves timeout behavior with 2FA keyboard auth
|
||||
o various improvements to the Wincng backend
|
||||
o fixes reading parital packet replies when using an agent
|
||||
o fixes Diffie Hellman key exchange on Windows 1903+ builds
|
||||
o fixes building tests with older versions of OpenSSL
|
||||
o fixes possible multiple definition warnings
|
||||
o fixes potential cast issues _libssh2_ecdsa_key_get_curve_type()
|
||||
o fixes potential use after free if libssh2_init() is called twice
|
||||
o improved linking when using Mbed TLS
|
||||
o fixes call to libssh2_crypto_exit() if crypto hasn't been initialized
|
||||
o fixes crash when loading public keys with no id
|
||||
o fixes possible out of bounds read when exchanging keys
|
||||
o fixes possible out of bounds read when reading packets
|
||||
o fixes possible out of bounds read when opening an X11 connection
|
||||
o fixes possible out of bounds read when ecdh host keys
|
||||
o fixes possible hang when trying to read a disconnected socket
|
||||
o fixes a crash when using the delayed compression option
|
||||
o fixes read error with large known host entries
|
||||
o fixes various warnings
|
||||
o fixes various small memory leaks
|
||||
o improved error handling, various detailed errors will now be reported
|
||||
o builds are now using OSS-Fuzz
|
||||
o builds now use autoreconf instead of a custom build script
|
||||
o cmake now respects install directory
|
||||
o improved CI backend
|
||||
o updated HACKING-CRYPTO documentation
|
||||
o use markdown file extensions
|
||||
o improved unit tests
|
||||
|
||||
|
||||
This release would not have looked like this without help, code, reports and
|
||||
advice from friends like these:
|
||||
|
||||
Peter Surge, Will Cosgrove, Daniel Stenberg, Alex Arslan, Alex Crichton,
|
||||
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)
|
||||
katzer, Orgad Shaneh, mark-i-m, Zenju, axjowa, Thilo Schulz,
|
||||
Etienne Samson, hlefebvre, seba30, Panos, jethrogb, Fabrice Fontaine,
|
||||
Will Cosgrove, Daniel Stenberg, Michael Buckley, Wallace Souza Silva,
|
||||
Romain-Geissler-1A, meierha, Tseng Jun, Thomas Klausner, Brendan Shanks,
|
||||
Harry Sintonen, monnerat, Koutheir Attouchi, Marc Hörsken, yann-morin-1998,
|
||||
Wez Furlong, TDi-jonesds, David Benjamin, Max Dymond, Igor Klevanets,
|
||||
Viktor Szakats, Laurent Stacul, Mstrodl, Gabriel Smith, MarcT512,
|
||||
Paul Capron, teottin, Tor Erik Ottinsen, Brian Inglis
|
||||
|
||||
(40 contributors)
|
||||
|
||||
@@ -441,6 +441,7 @@ m4_case([$1],
|
||||
[mbedtls], [
|
||||
LIBSSH2_LIB_HAVE_LINKFLAGS([mbedcrypto], [], [#include <mbedtls/version.h>], [
|
||||
AC_DEFINE(LIBSSH2_MBEDTLS, 1, [Use $1])
|
||||
LIBS="$LIBS -lmbedcrypto"
|
||||
found_crypto="$1"
|
||||
support_clear_memory=yes
|
||||
])
|
||||
|
||||
77
aclocal.m4
vendored
77
aclocal.m4
vendored
@@ -1,6 +1,6 @@
|
||||
# generated automatically by aclocal 1.16.1 -*- Autoconf -*-
|
||||
# generated automatically by aclocal 1.16.4 -*- Autoconf -*-
|
||||
|
||||
# Copyright (C) 1996-2018 Free Software Foundation, Inc.
|
||||
# Copyright (C) 1996-2021 Free Software Foundation, Inc.
|
||||
|
||||
# This file is free software; the Free Software Foundation
|
||||
# gives unlimited permission to copy and/or distribute it,
|
||||
@@ -14,13 +14,13 @@
|
||||
m4_ifndef([AC_CONFIG_MACRO_DIRS], [m4_defun([_AM_CONFIG_MACRO_DIRS], [])m4_defun([AC_CONFIG_MACRO_DIRS], [_AM_CONFIG_MACRO_DIRS($@)])])
|
||||
m4_ifndef([AC_AUTOCONF_VERSION],
|
||||
[m4_copy([m4_PACKAGE_VERSION], [AC_AUTOCONF_VERSION])])dnl
|
||||
m4_if(m4_defn([AC_AUTOCONF_VERSION]), [2.69],,
|
||||
[m4_warning([this file was generated for autoconf 2.69.
|
||||
m4_if(m4_defn([AC_AUTOCONF_VERSION]), [2.71],,
|
||||
[m4_warning([this file was generated for autoconf 2.71.
|
||||
You have another version of autoconf. It may work, but is not guaranteed to.
|
||||
If you have problems, you may need to regenerate the build system entirely.
|
||||
To do so, use the procedure documented by the package, typically 'autoreconf'.])])
|
||||
|
||||
# Copyright (C) 2002-2018 Free Software Foundation, Inc.
|
||||
# Copyright (C) 2002-2021 Free Software Foundation, Inc.
|
||||
#
|
||||
# This file is free software; the Free Software Foundation
|
||||
# gives unlimited permission to copy and/or distribute it,
|
||||
@@ -35,7 +35,7 @@ AC_DEFUN([AM_AUTOMAKE_VERSION],
|
||||
[am__api_version='1.16'
|
||||
dnl Some users find AM_AUTOMAKE_VERSION and mistake it for a way to
|
||||
dnl require some minimum version. Point them to the right macro.
|
||||
m4_if([$1], [1.16.1], [],
|
||||
m4_if([$1], [1.16.4], [],
|
||||
[AC_FATAL([Do not call $0, use AM_INIT_AUTOMAKE([$1]).])])dnl
|
||||
])
|
||||
|
||||
@@ -51,14 +51,14 @@ m4_define([_AM_AUTOCONF_VERSION], [])
|
||||
# Call AM_AUTOMAKE_VERSION and AM_AUTOMAKE_VERSION so they can be traced.
|
||||
# This function is AC_REQUIREd by AM_INIT_AUTOMAKE.
|
||||
AC_DEFUN([AM_SET_CURRENT_AUTOMAKE_VERSION],
|
||||
[AM_AUTOMAKE_VERSION([1.16.1])dnl
|
||||
[AM_AUTOMAKE_VERSION([1.16.4])dnl
|
||||
m4_ifndef([AC_AUTOCONF_VERSION],
|
||||
[m4_copy([m4_PACKAGE_VERSION], [AC_AUTOCONF_VERSION])])dnl
|
||||
_AM_AUTOCONF_VERSION(m4_defn([AC_AUTOCONF_VERSION]))])
|
||||
|
||||
# AM_AUX_DIR_EXPAND -*- Autoconf -*-
|
||||
|
||||
# Copyright (C) 2001-2018 Free Software Foundation, Inc.
|
||||
# Copyright (C) 2001-2021 Free Software Foundation, Inc.
|
||||
#
|
||||
# This file is free software; the Free Software Foundation
|
||||
# gives unlimited permission to copy and/or distribute it,
|
||||
@@ -110,7 +110,7 @@ am_aux_dir=`cd "$ac_aux_dir" && pwd`
|
||||
|
||||
# AM_CONDITIONAL -*- Autoconf -*-
|
||||
|
||||
# Copyright (C) 1997-2018 Free Software Foundation, Inc.
|
||||
# Copyright (C) 1997-2021 Free Software Foundation, Inc.
|
||||
#
|
||||
# This file is free software; the Free Software Foundation
|
||||
# gives unlimited permission to copy and/or distribute it,
|
||||
@@ -141,7 +141,7 @@ AC_CONFIG_COMMANDS_PRE(
|
||||
Usually this means the macro was only invoked conditionally.]])
|
||||
fi])])
|
||||
|
||||
# Copyright (C) 1999-2018 Free Software Foundation, Inc.
|
||||
# Copyright (C) 1999-2021 Free Software Foundation, Inc.
|
||||
#
|
||||
# This file is free software; the Free Software Foundation
|
||||
# gives unlimited permission to copy and/or distribute it,
|
||||
@@ -332,7 +332,7 @@ _AM_SUBST_NOTMAKE([am__nodep])dnl
|
||||
|
||||
# Generate code to set up dependency tracking. -*- Autoconf -*-
|
||||
|
||||
# Copyright (C) 1999-2018 Free Software Foundation, Inc.
|
||||
# Copyright (C) 1999-2021 Free Software Foundation, Inc.
|
||||
#
|
||||
# This file is free software; the Free Software Foundation
|
||||
# gives unlimited permission to copy and/or distribute it,
|
||||
@@ -371,7 +371,9 @@ AC_DEFUN([_AM_OUTPUT_DEPENDENCY_COMMANDS],
|
||||
done
|
||||
if test $am_rc -ne 0; then
|
||||
AC_MSG_FAILURE([Something went wrong bootstrapping makefile fragments
|
||||
for automatic dependency tracking. Try re-running configure with the
|
||||
for automatic dependency tracking. If GNU make was not used, consider
|
||||
re-running the configure script with MAKE="gmake" (or whatever is
|
||||
necessary). You can also try re-running configure with the
|
||||
'--disable-dependency-tracking' option to at least be able to build
|
||||
the package (albeit without support for automatic dependency tracking).])
|
||||
fi
|
||||
@@ -398,7 +400,7 @@ AC_DEFUN([AM_OUTPUT_DEPENDENCY_COMMANDS],
|
||||
|
||||
# Do all the work for Automake. -*- Autoconf -*-
|
||||
|
||||
# Copyright (C) 1996-2018 Free Software Foundation, Inc.
|
||||
# Copyright (C) 1996-2021 Free Software Foundation, Inc.
|
||||
#
|
||||
# This file is free software; the Free Software Foundation
|
||||
# gives unlimited permission to copy and/or distribute it,
|
||||
@@ -462,7 +464,7 @@ m4_ifval([$3], [_AM_SET_OPTION([no-define])])dnl
|
||||
[_AM_SET_OPTIONS([$1])dnl
|
||||
dnl Diagnose old-style AC_INIT with new-style AM_AUTOMAKE_INIT.
|
||||
m4_if(
|
||||
m4_ifdef([AC_PACKAGE_NAME], [ok]):m4_ifdef([AC_PACKAGE_VERSION], [ok]),
|
||||
m4_ifset([AC_PACKAGE_NAME], [ok]):m4_ifset([AC_PACKAGE_VERSION], [ok]),
|
||||
[ok:ok],,
|
||||
[m4_fatal([AC_INIT should be called with package and version arguments])])dnl
|
||||
AC_SUBST([PACKAGE], ['AC_PACKAGE_TARNAME'])dnl
|
||||
@@ -514,6 +516,20 @@ AC_PROVIDE_IFELSE([AC_PROG_OBJCXX],
|
||||
[m4_define([AC_PROG_OBJCXX],
|
||||
m4_defn([AC_PROG_OBJCXX])[_AM_DEPENDENCIES([OBJCXX])])])dnl
|
||||
])
|
||||
# Variables for tags utilities; see am/tags.am
|
||||
if test -z "$CTAGS"; then
|
||||
CTAGS=ctags
|
||||
fi
|
||||
AC_SUBST([CTAGS])
|
||||
if test -z "$ETAGS"; then
|
||||
ETAGS=etags
|
||||
fi
|
||||
AC_SUBST([ETAGS])
|
||||
if test -z "$CSCOPE"; then
|
||||
CSCOPE=cscope
|
||||
fi
|
||||
AC_SUBST([CSCOPE])
|
||||
|
||||
AC_REQUIRE([AM_SILENT_RULES])dnl
|
||||
dnl The testsuite driver may need to know about EXEEXT, so add the
|
||||
dnl 'am__EXEEXT' conditional if _AM_COMPILER_EXEEXT was seen. This
|
||||
@@ -595,7 +611,7 @@ for _am_header in $config_headers :; do
|
||||
done
|
||||
echo "timestamp for $_am_arg" >`AS_DIRNAME(["$_am_arg"])`/stamp-h[]$_am_stamp_count])
|
||||
|
||||
# Copyright (C) 2001-2018 Free Software Foundation, Inc.
|
||||
# Copyright (C) 2001-2021 Free Software Foundation, Inc.
|
||||
#
|
||||
# This file is free software; the Free Software Foundation
|
||||
# gives unlimited permission to copy and/or distribute it,
|
||||
@@ -616,7 +632,7 @@ if test x"${install_sh+set}" != xset; then
|
||||
fi
|
||||
AC_SUBST([install_sh])])
|
||||
|
||||
# Copyright (C) 2003-2018 Free Software Foundation, Inc.
|
||||
# Copyright (C) 2003-2021 Free Software Foundation, Inc.
|
||||
#
|
||||
# This file is free software; the Free Software Foundation
|
||||
# gives unlimited permission to copy and/or distribute it,
|
||||
@@ -638,7 +654,7 @@ AC_SUBST([am__leading_dot])])
|
||||
# Add --enable-maintainer-mode option to configure. -*- Autoconf -*-
|
||||
# From Jim Meyering
|
||||
|
||||
# Copyright (C) 1996-2018 Free Software Foundation, Inc.
|
||||
# Copyright (C) 1996-2021 Free Software Foundation, Inc.
|
||||
#
|
||||
# This file is free software; the Free Software Foundation
|
||||
# gives unlimited permission to copy and/or distribute it,
|
||||
@@ -673,7 +689,7 @@ AC_MSG_CHECKING([whether to enable maintainer-specific portions of Makefiles])
|
||||
|
||||
# Check to see how 'make' treats includes. -*- Autoconf -*-
|
||||
|
||||
# Copyright (C) 2001-2018 Free Software Foundation, Inc.
|
||||
# Copyright (C) 2001-2021 Free Software Foundation, Inc.
|
||||
#
|
||||
# This file is free software; the Free Software Foundation
|
||||
# gives unlimited permission to copy and/or distribute it,
|
||||
@@ -716,7 +732,7 @@ AC_SUBST([am__quote])])
|
||||
|
||||
# Fake the existence of programs that GNU maintainers use. -*- Autoconf -*-
|
||||
|
||||
# Copyright (C) 1997-2018 Free Software Foundation, Inc.
|
||||
# Copyright (C) 1997-2021 Free Software Foundation, Inc.
|
||||
#
|
||||
# This file is free software; the Free Software Foundation
|
||||
# gives unlimited permission to copy and/or distribute it,
|
||||
@@ -737,12 +753,7 @@ AC_DEFUN([AM_MISSING_HAS_RUN],
|
||||
[AC_REQUIRE([AM_AUX_DIR_EXPAND])dnl
|
||||
AC_REQUIRE_AUX_FILE([missing])dnl
|
||||
if test x"${MISSING+set}" != xset; then
|
||||
case $am_aux_dir in
|
||||
*\ * | *\ *)
|
||||
MISSING="\${SHELL} \"$am_aux_dir/missing\"" ;;
|
||||
*)
|
||||
MISSING="\${SHELL} $am_aux_dir/missing" ;;
|
||||
esac
|
||||
MISSING="\${SHELL} '$am_aux_dir/missing'"
|
||||
fi
|
||||
# Use eval to expand $SHELL
|
||||
if eval "$MISSING --is-lightweight"; then
|
||||
@@ -755,7 +766,7 @@ fi
|
||||
|
||||
# Helper functions for option handling. -*- Autoconf -*-
|
||||
|
||||
# Copyright (C) 2001-2018 Free Software Foundation, Inc.
|
||||
# Copyright (C) 2001-2021 Free Software Foundation, Inc.
|
||||
#
|
||||
# This file is free software; the Free Software Foundation
|
||||
# gives unlimited permission to copy and/or distribute it,
|
||||
@@ -784,7 +795,7 @@ AC_DEFUN([_AM_SET_OPTIONS],
|
||||
AC_DEFUN([_AM_IF_OPTION],
|
||||
[m4_ifset(_AM_MANGLE_OPTION([$1]), [$2], [$3])])
|
||||
|
||||
# Copyright (C) 1999-2018 Free Software Foundation, Inc.
|
||||
# Copyright (C) 1999-2021 Free Software Foundation, Inc.
|
||||
#
|
||||
# This file is free software; the Free Software Foundation
|
||||
# gives unlimited permission to copy and/or distribute it,
|
||||
@@ -831,7 +842,7 @@ AC_LANG_POP([C])])
|
||||
# For backward compatibility.
|
||||
AC_DEFUN_ONCE([AM_PROG_CC_C_O], [AC_REQUIRE([AC_PROG_CC])])
|
||||
|
||||
# Copyright (C) 2001-2018 Free Software Foundation, Inc.
|
||||
# Copyright (C) 2001-2021 Free Software Foundation, Inc.
|
||||
#
|
||||
# This file is free software; the Free Software Foundation
|
||||
# gives unlimited permission to copy and/or distribute it,
|
||||
@@ -850,7 +861,7 @@ AC_DEFUN([AM_RUN_LOG],
|
||||
|
||||
# Check to make sure that the build environment is sane. -*- Autoconf -*-
|
||||
|
||||
# Copyright (C) 1996-2018 Free Software Foundation, Inc.
|
||||
# Copyright (C) 1996-2021 Free Software Foundation, Inc.
|
||||
#
|
||||
# This file is free software; the Free Software Foundation
|
||||
# gives unlimited permission to copy and/or distribute it,
|
||||
@@ -931,7 +942,7 @@ AC_CONFIG_COMMANDS_PRE(
|
||||
rm -f conftest.file
|
||||
])
|
||||
|
||||
# Copyright (C) 2009-2018 Free Software Foundation, Inc.
|
||||
# Copyright (C) 2009-2021 Free Software Foundation, Inc.
|
||||
#
|
||||
# This file is free software; the Free Software Foundation
|
||||
# gives unlimited permission to copy and/or distribute it,
|
||||
@@ -991,7 +1002,7 @@ AC_SUBST([AM_BACKSLASH])dnl
|
||||
_AM_SUBST_NOTMAKE([AM_BACKSLASH])dnl
|
||||
])
|
||||
|
||||
# Copyright (C) 2001-2018 Free Software Foundation, Inc.
|
||||
# Copyright (C) 2001-2021 Free Software Foundation, Inc.
|
||||
#
|
||||
# This file is free software; the Free Software Foundation
|
||||
# gives unlimited permission to copy and/or distribute it,
|
||||
@@ -1019,7 +1030,7 @@ fi
|
||||
INSTALL_STRIP_PROGRAM="\$(install_sh) -c -s"
|
||||
AC_SUBST([INSTALL_STRIP_PROGRAM])])
|
||||
|
||||
# Copyright (C) 2006-2018 Free Software Foundation, Inc.
|
||||
# Copyright (C) 2006-2021 Free Software Foundation, Inc.
|
||||
#
|
||||
# This file is free software; the Free Software Foundation
|
||||
# gives unlimited permission to copy and/or distribute it,
|
||||
@@ -1038,7 +1049,7 @@ AC_DEFUN([AM_SUBST_NOTMAKE], [_AM_SUBST_NOTMAKE($@)])
|
||||
|
||||
# Check how to create a tarball. -*- Autoconf -*-
|
||||
|
||||
# Copyright (C) 2004-2018 Free Software Foundation, Inc.
|
||||
# Copyright (C) 2004-2021 Free Software Foundation, Inc.
|
||||
#
|
||||
# This file is free software; the Free Software Foundation
|
||||
# gives unlimited permission to copy and/or distribute it,
|
||||
|
||||
22
buildconf
22
buildconf
@@ -1,22 +0,0 @@
|
||||
#!/bin/sh
|
||||
|
||||
LIBTOOLIZE="libtoolize"
|
||||
|
||||
if [ "x`which $LIBTOOLIZE`" = "x" ]; then
|
||||
LIBTOOLIZE="glibtoolize"
|
||||
fi
|
||||
|
||||
if [ "x`which $LIBTOOLIZE`" = "x" ]; then
|
||||
echo "Neither libtoolize nor glibtoolize could be found!"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
${LIBTOOLIZE} --copy --automake --force
|
||||
${ACLOCAL:-aclocal} -I m4 $ACLOCAL_FLAGS
|
||||
${AUTOHEADER:-autoheader}
|
||||
# copy the private libssh2_config.h.in to the examples dir so that
|
||||
# it can be included without pointing the include path to the private
|
||||
# source dir
|
||||
cp src/libssh2_config.h.in example/libssh2_config.h.in
|
||||
${AUTOCONF:-autoconf}
|
||||
${AUTOMAKE:-automake} --add-missing --copy
|
||||
6
compile
6
compile
@@ -3,7 +3,7 @@
|
||||
|
||||
scriptversion=2018-03-07.03; # UTC
|
||||
|
||||
# Copyright (C) 1999-2018 Free Software Foundation, Inc.
|
||||
# Copyright (C) 1999-2020 Free Software Foundation, Inc.
|
||||
# Written by Tom Tromey <tromey@cygnus.com>.
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or modify
|
||||
@@ -53,7 +53,7 @@ func_file_conv ()
|
||||
MINGW*)
|
||||
file_conv=mingw
|
||||
;;
|
||||
CYGWIN*)
|
||||
CYGWIN* | MSYS*)
|
||||
file_conv=cygwin
|
||||
;;
|
||||
*)
|
||||
@@ -67,7 +67,7 @@ func_file_conv ()
|
||||
mingw/*)
|
||||
file=`cmd //C echo "$file " | sed -e 's/"\(.*\) " *$/\1/'`
|
||||
;;
|
||||
cygwin/*)
|
||||
cygwin/* | msys/*)
|
||||
file=`cygpath -m "$file" || echo "$file"`
|
||||
;;
|
||||
wine/*)
|
||||
|
||||
28
configure.ac
28
configure.ac
@@ -2,7 +2,7 @@
|
||||
AC_INIT(libssh2, [-], libssh2-devel@cool.haxx.se)
|
||||
AC_CONFIG_MACRO_DIR([m4])
|
||||
AC_CONFIG_SRCDIR([src])
|
||||
AC_CONFIG_HEADERS([src/libssh2_config.h example/libssh2_config.h])
|
||||
AC_CONFIG_HEADERS([src/libssh2_config.h])
|
||||
AM_MAINTAINER_MODE
|
||||
m4_ifdef([AM_SILENT_RULES], [AM_SILENT_RULES([yes])])
|
||||
|
||||
@@ -36,12 +36,9 @@ case "$host" in
|
||||
CFLAGS="$CFLAGS -DLIBSSH2_WIN32"
|
||||
LIBS="$LIBS -lws2_32"
|
||||
;;
|
||||
*-cygwin)
|
||||
CFLAGS="$CFLAGS -DLIBSSH2_WIN32"
|
||||
*darwin*)
|
||||
CFLAGS="$CFLAGS -DLIBSSH2_DARWIN"
|
||||
;;
|
||||
*darwin*)
|
||||
CFLAGS="$CFLAGS -DLIBSSH2_DARWIN"
|
||||
;;
|
||||
*hpux*)
|
||||
;;
|
||||
*osf*)
|
||||
@@ -69,6 +66,7 @@ AC_SEARCH_LIBS(inet_addr, nsl)
|
||||
AC_SUBST(LIBS)
|
||||
|
||||
AC_PROG_CC
|
||||
AC_PROG_CXX
|
||||
AC_PROG_INSTALL
|
||||
AC_PROG_LN_S
|
||||
AC_PROG_MAKE_SET
|
||||
@@ -127,8 +125,6 @@ fi
|
||||
m4_set_foreach([crypto_backends], [backend],
|
||||
[AM_CONDITIONAL(m4_toupper(backend), test "$found_crypto" = "backend")]
|
||||
)
|
||||
m4_undefine([backend])
|
||||
|
||||
|
||||
# libz
|
||||
|
||||
@@ -284,6 +280,21 @@ esac], [build_examples='yes'])
|
||||
AC_MSG_RESULT($build_examples)
|
||||
AM_CONDITIONAL([BUILD_EXAMPLES], [test "x$build_examples" != "xno"])
|
||||
|
||||
|
||||
# Build OSS fuzzing targets?
|
||||
AC_ARG_ENABLE([ossfuzzers],
|
||||
[AS_HELP_STRING([--enable-ossfuzzers],
|
||||
[Whether to generate the fuzzers for OSS-Fuzz])],
|
||||
[have_ossfuzzers=yes], [have_ossfuzzers=no])
|
||||
AM_CONDITIONAL([USE_OSSFUZZERS], [test "x$have_ossfuzzers" = "xyes"])
|
||||
|
||||
|
||||
# Set the correct flags for the given fuzzing engine.
|
||||
AC_SUBST([LIB_FUZZING_ENGINE])
|
||||
AM_CONDITIONAL([USE_OSSFUZZ_FLAG], [test "x$LIB_FUZZING_ENGINE" = "x-fsanitize=fuzzer"])
|
||||
AM_CONDITIONAL([USE_OSSFUZZ_STATIC], [test -f "$LIB_FUZZING_ENGINE"])
|
||||
|
||||
|
||||
# Checks for header files.
|
||||
# AC_HEADER_STDC
|
||||
AC_CHECK_HEADERS([errno.h fcntl.h stdio.h stdlib.h unistd.h sys/uio.h])
|
||||
@@ -373,6 +384,7 @@ LIBSSH2_CHECK_OPTION_WERROR
|
||||
AC_CONFIG_FILES([Makefile
|
||||
src/Makefile
|
||||
tests/Makefile
|
||||
tests/ossfuzz/Makefile
|
||||
example/Makefile
|
||||
docs/Makefile
|
||||
libssh2.pc])
|
||||
|
||||
2
depcomp
2
depcomp
@@ -3,7 +3,7 @@
|
||||
|
||||
scriptversion=2018-03-07.03; # UTC
|
||||
|
||||
# Copyright (C) 1999-2018 Free Software Foundation, Inc.
|
||||
# Copyright (C) 1999-2020 Free Software Foundation, Inc.
|
||||
|
||||
# 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
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
Definitions needed to implement a specific crypto library
|
||||
Definitions needed to implement a specific crypto library
|
||||
|
||||
This document offers some hints about implementing a new crypto library
|
||||
interface.
|
||||
@@ -67,14 +67,14 @@ Note: if the ctx parameter is modified by the underlying code,
|
||||
this procedure must be implemented as a macro to map ctx --> &ctx.
|
||||
|
||||
void libssh2_hmac_update(libssh2_hmac_ctx ctx,
|
||||
const unsigned char *data,
|
||||
int datalen);
|
||||
const unsigned char *data,
|
||||
int datalen);
|
||||
Continue computation of an HMAC on datalen bytes at data using context ctx.
|
||||
Note: if the ctx parameter is modified by the underlying code,
|
||||
this procedure must be implemented as a macro to map ctx --> &ctx.
|
||||
|
||||
void libssh2_hmac_final(libssh2_hmac_ctx ctx,
|
||||
unsigned char output[]);
|
||||
unsigned char output[]);
|
||||
Get the computed HMAC from context ctx into the output buffer. The
|
||||
minimum data buffer size depends on the HMAC hash algorithm.
|
||||
Note: if the ctx parameter is modified by the underlying code,
|
||||
@@ -100,8 +100,8 @@ Initializes the SHA-1 computation context at x.
|
||||
Returns 1 for success and 0 for failure
|
||||
|
||||
void libssh2_sha1_update(libssh2_sha1_ctx ctx,
|
||||
const unsigned char *data,
|
||||
size_t len);
|
||||
const unsigned char *data,
|
||||
size_t len);
|
||||
Continue computation of SHA-1 on len bytes at data using context ctx.
|
||||
Note: if the ctx parameter is modified by the underlying code,
|
||||
this procedure must be implemented as a macro to map ctx --> &ctx.
|
||||
@@ -115,8 +115,8 @@ Note: if the ctx parameter is modified by the underlying code,
|
||||
this procedure must be implemented as a macro to map ctx --> &ctx.
|
||||
|
||||
void libssh2_hmac_sha1_init(libssh2_hmac_ctx *ctx,
|
||||
const void *key,
|
||||
int keylen);
|
||||
const void *key,
|
||||
int keylen);
|
||||
Setup the HMAC computation context ctx for an HMAC-SHA-1 computation using the
|
||||
keylen-byte key. Is invoked just after libssh2_hmac_ctx_init().
|
||||
|
||||
@@ -134,14 +134,14 @@ Initializes the SHA-256 computation context at x.
|
||||
Returns 1 for success and 0 for failure
|
||||
|
||||
void libssh2_sha256_update(libssh2_sha256_ctx ctx,
|
||||
const unsigned char *data,
|
||||
size_t len);
|
||||
const unsigned char *data,
|
||||
size_t len);
|
||||
Continue computation of SHA-256 on len bytes at data using context ctx.
|
||||
Note: if the ctx parameter is modified by the underlying code,
|
||||
this procedure must be implemented as a macro to map ctx --> &ctx.
|
||||
|
||||
void libssh2_sha256_final(libssh2_sha256_ctx ctx,
|
||||
unsigned char output[SHA256_DIGEST_LENGTH]);
|
||||
unsigned char output[SHA256_DIGEST_LENGTH]);
|
||||
Gets the computed SHA-256 signature from context ctx into the output buffer.
|
||||
Release the context.
|
||||
Note: if the ctx parameter is modified by the underlying code,
|
||||
@@ -160,26 +160,91 @@ LIBSSH2_HMAC_SHA256
|
||||
If defined as 0, the rest of this section can be omitted.
|
||||
|
||||
void libssh2_hmac_sha256_init(libssh2_hmac_ctx *ctx,
|
||||
const void *key,
|
||||
int keylen);
|
||||
const void *key,
|
||||
int keylen);
|
||||
Setup the HMAC computation context ctx for an HMAC-256 computation using the
|
||||
keylen-byte key. Is invoked just after libssh2_hmac_ctx_init().
|
||||
|
||||
3.3) SHA-512
|
||||
LIBSSH2_HMAC_SHA512
|
||||
#define as 1 if the crypto library supports HMAC-SHA-512, else 0.
|
||||
If defined as 0, the rest of this section can be omitted.
|
||||
3.3) SHA-384
|
||||
Mandatory if ECDSA is implemented. Can be omitted otherwise.
|
||||
|
||||
SHA384_DIGEST_LENGTH
|
||||
#define to 48, the SHA-384 digest length.
|
||||
|
||||
libssh2_sha384_ctx
|
||||
Type of an SHA-384 computation context. Generally a struct.
|
||||
|
||||
int libssh2_sha384_init(libssh2_sha384_ctx *x);
|
||||
Initializes the SHA-384 computation context at x.
|
||||
Returns 1 for success and 0 for failure
|
||||
|
||||
void libssh2_sha384_update(libssh2_sha384_ctx ctx,
|
||||
const unsigned char *data,
|
||||
size_t len);
|
||||
Continue computation of SHA-384 on len bytes at data using context ctx.
|
||||
Note: if the ctx parameter is modified by the underlying code,
|
||||
this procedure must be implemented as a macro to map ctx --> &ctx.
|
||||
|
||||
void libssh2_sha384_final(libssh2_sha384_ctx ctx,
|
||||
unsigned char output[SHA384_DIGEST_LENGTH]);
|
||||
Gets the computed SHA-384 signature from context ctx into the output buffer.
|
||||
Release the context.
|
||||
Note: if the ctx parameter is modified by the underlying code,
|
||||
this procedure must be implemented as a macro to map ctx --> &ctx.
|
||||
|
||||
int libssh2_sha384(const unsigned char *message,
|
||||
unsigned long len,
|
||||
unsigned char output[SHA384_DIGEST_LENGTH]);
|
||||
Computes the SHA-384 signature over the given message of length len and
|
||||
store the result into the output buffer.
|
||||
Return 1 if error, else 0.
|
||||
|
||||
3.4) SHA-512
|
||||
Must always be implemented.
|
||||
|
||||
SHA512_DIGEST_LENGTH
|
||||
#define to 64, the SHA-512 digest length.
|
||||
|
||||
libssh2_sha512_ctx
|
||||
Type of an SHA-512 computation context. Generally a struct.
|
||||
|
||||
int libssh2_sha512_init(libssh2_sha512_ctx *x);
|
||||
Initializes the SHA-512 computation context at x.
|
||||
Returns 1 for success and 0 for failure
|
||||
|
||||
void libssh2_sha512_update(libssh2_sha512_ctx ctx,
|
||||
const unsigned char *data,
|
||||
size_t len);
|
||||
Continue computation of SHA-512 on len bytes at data using context ctx.
|
||||
Note: if the ctx parameter is modified by the underlying code,
|
||||
this procedure must be implemented as a macro to map ctx --> &ctx.
|
||||
|
||||
void libssh2_sha512_final(libssh2_sha512_ctx ctx,
|
||||
unsigned char output[SHA512_DIGEST_LENGTH]);
|
||||
Gets the computed SHA-512 signature from context ctx into the output buffer.
|
||||
Release the context.
|
||||
Note: if the ctx parameter is modified by the underlying code,
|
||||
this procedure must be implemented as a macro to map ctx --> &ctx.
|
||||
|
||||
int libssh2_sha512(const unsigned char *message,
|
||||
unsigned long len,
|
||||
unsigned char output[SHA512_DIGEST_LENGTH]);
|
||||
Computes the SHA-512 signature over the given message of length len and
|
||||
store the result into the output buffer.
|
||||
Return 1 if error, else 0.
|
||||
Note: Seems unused in current code, but defined in each crypto library backend.
|
||||
|
||||
LIBSSH2_HMAC_SHA512
|
||||
#define as 1 if the crypto library supports HMAC-SHA-512, else 0.
|
||||
If defined as 0, the rest of this section can be omitted.
|
||||
|
||||
void libssh2_hmac_sha512_init(libssh2_hmac_ctx *ctx,
|
||||
const void *key,
|
||||
int keylen);
|
||||
const void *key,
|
||||
int keylen);
|
||||
Setup the HMAC computation context ctx for an HMAC-512 computation using the
|
||||
keylen-byte key. Is invoked just after libssh2_hmac_ctx_init().
|
||||
|
||||
3.4) MD5
|
||||
3.5) MD5
|
||||
LIBSSH2_MD5
|
||||
#define to 1 if the crypto library supports MD5, else 0.
|
||||
If defined as 0, the rest of this section can be omitted.
|
||||
@@ -195,34 +260,34 @@ Initializes the MD5 computation context at x.
|
||||
Returns 1 for success and 0 for failure
|
||||
|
||||
void libssh2_md5_update(libssh2_md5_ctx ctx,
|
||||
const unsigned char *data,
|
||||
size_t len);
|
||||
const unsigned char *data,
|
||||
size_t len);
|
||||
Continues computation of MD5 on len bytes at data using context ctx.
|
||||
Returns 1 for success and 0 for failure.
|
||||
Note: if the ctx parameter is modified by the underlying code,
|
||||
this procedure must be implemented as a macro to map ctx --> &ctx.
|
||||
|
||||
void libssh2_md5_final(libssh2_md5_ctx ctx,
|
||||
unsigned char output[MD5_DIGEST_LENGTH]);
|
||||
unsigned char output[MD5_DIGEST_LENGTH]);
|
||||
Gets the computed MD5 signature from context ctx into the output buffer.
|
||||
Release the context.
|
||||
Note: if the ctx parameter is modified by the underlying code,
|
||||
this procedure must be implemented as a macro to map ctx --> &ctx.
|
||||
|
||||
void libssh2_hmac_md5_init(libssh2_hmac_ctx *ctx,
|
||||
const void *key,
|
||||
int keylen);
|
||||
const void *key,
|
||||
int keylen);
|
||||
Setup the HMAC computation context ctx for an HMAC-MD5 computation using the
|
||||
keylen-byte key. Is invoked just after libssh2_hmac_ctx_init().
|
||||
|
||||
3.5) RIPEMD-160
|
||||
3.6) RIPEMD-160
|
||||
LIBSSH2_HMAC_RIPEMD
|
||||
#define as 1 if the crypto library supports HMAC-RIPEMD-160, else 0.
|
||||
If defined as 0, the rest of this section can be omitted.
|
||||
|
||||
void libssh2_hmac_ripemd160_init(libssh2_hmac_ctx *ctx,
|
||||
const void *key,
|
||||
int keylen);
|
||||
const void *key,
|
||||
int keylen);
|
||||
Setup the HMAC computation context ctx for an HMAC-RIPEMD-160 computation using
|
||||
the keylen-byte key. Is invoked just after libssh2_hmac_ctx_init().
|
||||
Returns 1 for success and 0 for failure.
|
||||
@@ -411,7 +476,7 @@ Sets the value of bn to val.
|
||||
Returns 1 on success, 0 otherwise.
|
||||
|
||||
_libssh2_bn * _libssh2_bn_from_bin(_libssh2_bn *bn, int len,
|
||||
const unsigned char *val);
|
||||
const unsigned char *val);
|
||||
Converts the positive integer in big-endian form of length len at val
|
||||
into a _libssh2_bn and place it in bn. If bn is NULL, a new _libssh2_bn is
|
||||
created.
|
||||
@@ -438,6 +503,17 @@ d) g, MSB first, with high order bit = 0.
|
||||
e) pub_key, MSB first, with high order bit = 0.
|
||||
Each item is preceded by its 32-bit byte length, MSB first.
|
||||
|
||||
Format of an ECDSA public key:
|
||||
a) "ecdsa-sha2-nistp256" or "ecdsa-sha2-nistp384" or "ecdsa-sha2-nistp521".
|
||||
b) domain: "nistp256", "nistp384" or "nistp521" matching a).
|
||||
c) raw public key ("octal").
|
||||
Each item is preceded by its 32-bit byte length, MSB first.
|
||||
|
||||
Format of an ED25519 public key:
|
||||
a) "ssh-ed25519".
|
||||
b) raw key (32 bytes).
|
||||
Each item is preceded by its 32-bit byte length, MSB first.
|
||||
|
||||
int _libssh2_pub_priv_keyfile(LIBSSH2_SESSION *session,
|
||||
unsigned char **method,
|
||||
size_t *method_len,
|
||||
@@ -467,6 +543,7 @@ Both buffers have to be allocated using LIBSSH2_ALLOC().
|
||||
Returns 0 if OK, else -1.
|
||||
This procedure is already prototyped in crypto.h.
|
||||
|
||||
|
||||
7.1) RSA
|
||||
LIBSSH2_RSA
|
||||
#define as 1 if the crypto library supports RSA, else 0.
|
||||
@@ -492,14 +569,14 @@ int _libssh2_rsa_new(libssh2_rsa_ctx **rsa,
|
||||
unsigned long e2len,
|
||||
const unsigned char *coeffdata, unsigned long coefflen);
|
||||
Creates a new context for RSA computations from key source values:
|
||||
pdata, plen Prime number p. Only used if private key known (ddata).
|
||||
qdata, qlen Prime number q. Only used if private key known (ddata).
|
||||
ndata, nlen Modulus n.
|
||||
edata, elen Exponent e.
|
||||
ddata, dlen e^-1 % phi(n) = private key. May be NULL if unknown.
|
||||
e1data, e1len dp = d % (p-1). Only used if private key known (dtata).
|
||||
e2data, e2len dq = d % (q-1). Only used if private key known (dtata).
|
||||
coeffdata, coefflen q^-1 % p. Only used if private key known.
|
||||
pdata, plen Prime number p. Only used if private key known (ddata).
|
||||
qdata, qlen Prime number q. Only used if private key known (ddata).
|
||||
ndata, nlen Modulus n.
|
||||
edata, elen Exponent e.
|
||||
ddata, dlen e^-1 % phi(n) = private key. May be NULL if unknown.
|
||||
e1data, e1len dp = d % (p-1). Only used if private key known (dtata).
|
||||
e2data, e2len dq = d % (q-1). Only used if private key known (dtata).
|
||||
coeffdata, coefflen q^-1 % p. Only used if private key known.
|
||||
Returns 0 if OK.
|
||||
This procedure is already prototyped in crypto.h.
|
||||
Note: the current generic code only calls this function with e and n (public
|
||||
@@ -518,7 +595,7 @@ This procedure is already prototyped in crypto.h.
|
||||
int _libssh2_rsa_new_private_frommemory(libssh2_rsa_ctx **rsa,
|
||||
LIBSSH2_SESSION *session,
|
||||
const char *data,
|
||||
size_t data_len,
|
||||
size_t data_len,
|
||||
unsigned const char *passphrase);
|
||||
Gets an RSA private key from data into a new RSA context.
|
||||
Must call _libssh2_init_if_needed().
|
||||
@@ -529,15 +606,15 @@ int _libssh2_rsa_sha1_verify(libssh2_rsa_ctx *rsa,
|
||||
const unsigned char *sig,
|
||||
unsigned long sig_len,
|
||||
const unsigned char *m, unsigned long m_len);
|
||||
Verify (sig, siglen) signature of (m, m_len) using an SHA-1 hash and the
|
||||
Verify (sig, sig_len) signature of (m, m_len) using an SHA-1 hash and the
|
||||
RSA context.
|
||||
Return 0 if OK, else -1.
|
||||
This procedure is already prototyped in crypto.h.
|
||||
|
||||
int _libssh2_rsa_sha1_signv(LIBSSH2_SESSION *session,
|
||||
unsigned char **sig, size_t *siglen,
|
||||
int count, const struct iovec vector[],
|
||||
libssh2_rsa_ctx *ctx);
|
||||
unsigned char **sig, size_t *siglen,
|
||||
int count, const struct iovec vector[],
|
||||
libssh2_rsa_ctx *ctx);
|
||||
RSA signs the SHA-1 hash computed over the count data chunks in vector.
|
||||
Signature is stored at (sig, siglen).
|
||||
Signature buffer must be allocated from the given session.
|
||||
@@ -581,11 +658,11 @@ int _libssh2_dsa_new(libssh2_dsa_ctx **dsa,
|
||||
unsigned long ylen,
|
||||
const unsigned char *x, unsigned long x_len);
|
||||
Creates a new context for DSA computations from source key values:
|
||||
pdata, plen Prime number p. Only used if private key known (ddata).
|
||||
qdata, qlen Prime number q. Only used if private key known (ddata).
|
||||
gdata, glen G number.
|
||||
ydata, ylen Public key.
|
||||
xdata, xlen Private key. Only taken if xlen non-zero.
|
||||
pdata, plen Prime number p. Only used if private key known (ddata).
|
||||
qdata, qlen Prime number q. Only used if private key known (ddata).
|
||||
gdata, glen G number.
|
||||
ydata, ylen Public key.
|
||||
xdata, xlen Private key. Only taken if xlen non-zero.
|
||||
Returns 0 if OK.
|
||||
This procedure is already prototyped in crypto.h.
|
||||
|
||||
@@ -601,7 +678,7 @@ This procedure is already prototyped in crypto.h.
|
||||
int _libssh2_dsa_new_private_frommemory(libssh2_dsa_ctx **dsa,
|
||||
LIBSSH2_SESSION *session,
|
||||
const char *data,
|
||||
size_t data_len,
|
||||
size_t data_len,
|
||||
unsigned const char *passphrase);
|
||||
Gets a DSA private key from the data_len-bytes data into a new DSA context.
|
||||
Must call _libssh2_init_if_needed().
|
||||
@@ -627,6 +704,191 @@ void _libssh2_dsa_free(libssh2_dsa_ctx *dsactx);
|
||||
Releases the DSA computation context at dsactx.
|
||||
|
||||
|
||||
7.3) ECDSA
|
||||
LIBSSH2_ECDSA
|
||||
#define as 1 if the crypto library supports ECDSA, else 0.
|
||||
If defined as 0, _libssh2_ec_key should be defined as void and the rest of
|
||||
this section can be omitted.
|
||||
|
||||
EC_MAX_POINT_LEN
|
||||
Maximum point length. Usually defined as ((528 * 2 / 8) + 1) (= 133).
|
||||
|
||||
libssh2_ecdsa_ctx
|
||||
Type of an ECDSA computation context. Generally a struct.
|
||||
|
||||
_libssh2_ec_key
|
||||
Type of an elliptic curve key.
|
||||
|
||||
libssh2_curve_type
|
||||
An enum type defining curve types. Current supported identifiers are:
|
||||
LIBSSH2_EC_CURVE_NISTP256
|
||||
LIBSSH2_EC_CURVE_NISTP384
|
||||
LIBSSH2_EC_CURVE_NISTP521
|
||||
|
||||
int _libssh2_ecdsa_create_key(_libssh2_ec_key **out_private_key,
|
||||
unsigned char **out_public_key_octal,
|
||||
size_t *out_public_key_octal_len,
|
||||
libssh2_curve_type curve_type);
|
||||
Create a new ECDSA private key of type curve_type and return it at
|
||||
out_private_key. If out_public_key_octal is not NULL, store an allocated
|
||||
pointer to the associated public key in "octal" form in it and its length
|
||||
at out_public_key_octal_len.
|
||||
Return 0 if OK, else -1.
|
||||
This procedure is already prototyped in crypto.h.
|
||||
|
||||
int _libssh2_ecdsa_new_private(libssh2_ecdsa_ctx **ec_ctx,
|
||||
LIBSSH2_SESSION * session,
|
||||
const char *filename,
|
||||
unsigned const char *passphrase);
|
||||
Reads an ECDSA private key from PEM file filename into a new ECDSA context.
|
||||
Must call _libssh2_init_if_needed().
|
||||
Return 0 if OK, else -1.
|
||||
This procedure is already prototyped in crypto.h.
|
||||
|
||||
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);
|
||||
Builds an ECDSA private key from PEM data at filedata of length filedata_len
|
||||
into a new ECDSA context stored at ec_ctx.
|
||||
Must call _libssh2_init_if_needed().
|
||||
Return 0 if OK, else -1.
|
||||
This procedure is already prototyped in crypto.h.
|
||||
|
||||
int _libssh2_ecdsa_curve_name_with_octal_new(libssh2_ecdsa_ctx **ecdsactx,
|
||||
const unsigned char *k,
|
||||
size_t k_len,
|
||||
libssh2_curve_type type);
|
||||
Stores at ecdsactx a new ECDSA context associated with the given curve type
|
||||
and with "octal" form public key (k, k_len).
|
||||
Return 0 if OK, else -1.
|
||||
This procedure is already prototyped in crypto.h.
|
||||
|
||||
int _libssh2_ecdsa_new_openssh_private(libssh2_ecdsa_ctx **ec_ctx,
|
||||
LIBSSH2_SESSION * session,
|
||||
const char *filename,
|
||||
unsigned const char *passphrase);
|
||||
Reads a PEM-encoded ECDSA private key from file filename encrypted with
|
||||
passphrase and stores at ec_ctx a new ECDSA context for it.
|
||||
Return 0 if OK, else -1.
|
||||
Currently used only from openssl backend (ought to be private).
|
||||
This procedure is already prototyped in crypto.h.
|
||||
|
||||
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);
|
||||
ECDSA signs the (hash, hashlen) hash bytes and stores the allocated
|
||||
signature at (signature, signature_len). Hash algorithm used should be
|
||||
SHA-256, SHA-384 or SHA-512 depending on type stored in ECDSA context at ec_ctx.
|
||||
Signature buffer must be allocated from the given session.
|
||||
Returns 0 if OK, else -1.
|
||||
This procedure is already prototyped in crypto.h.
|
||||
|
||||
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);
|
||||
Verify the ECDSA signature made of (r, r_len) and (s, s_len) of (m, m_len)
|
||||
using the hash algorithm configured in the ECDSA context ctx.
|
||||
Return 0 if OK, else -1.
|
||||
This procedure is already prototyped in crypto.h.
|
||||
|
||||
libssh2_curve_type _libssh2_ecdsa_get_curve_type(libssh2_ecdsa_ctx *ecdsactx);
|
||||
Returns the curve type associated with given context.
|
||||
This procedure is already prototyped in crypto.h.
|
||||
|
||||
int _libssh2_ecdsa_curve_type_from_name(const char *name,
|
||||
libssh2_curve_type *out_type);
|
||||
Stores in out_type the curve type matching string name of the form
|
||||
"ecdsa-sha2-nistpxxx".
|
||||
Return 0 if OK, else -1.
|
||||
Currently used only from openssl backend (ought to be private).
|
||||
This procedure is already prototyped in crypto.h.
|
||||
|
||||
void _libssh2_ecdsa_free(libssh2_ecdsa_ctx *ecdsactx);
|
||||
Releases the ECDSA computation context at ecdsactx.
|
||||
|
||||
|
||||
7.4) ED25519
|
||||
LIBSSH2_ED25519
|
||||
#define as 1 if the crypto library supports ED25519, else 0.
|
||||
If defined as 0, the rest of this section can be omitted.
|
||||
|
||||
|
||||
libssh2_ed25519_ctx
|
||||
Type of an ED25519 computation context. Generally a struct.
|
||||
|
||||
int _libssh2_curve25519_new(LIBSSH2_SESSION *session, libssh2_ed25519_ctx **ctx,
|
||||
uint8_t **out_public_key,
|
||||
uint8_t **out_private_key);
|
||||
Generates an ED25519 key pair, stores a pointer to them at out_private_key
|
||||
and out_public_key respectively and stores at ctx a new ED25519 context for
|
||||
this key.
|
||||
Argument ctx, out_private_key and out_public key may be NULL to disable storing
|
||||
the corresponding value.
|
||||
Length of each key is LIBSSH2_ED25519_KEY_LEN (32 bytes).
|
||||
Key buffers are allocated and should be released by caller after use.
|
||||
Returns 0 if OK, else -1.
|
||||
This procedure is already prototyped in crypto.h.
|
||||
|
||||
int _libssh2_ed25519_new_private(libssh2_ed25519_ctx **ed_ctx,
|
||||
LIBSSH2_SESSION *session,
|
||||
const char *filename,
|
||||
const uint8_t *passphrase);
|
||||
Reads an ED25519 private key from PEM file filename into a new ED25519 context.
|
||||
Must call _libssh2_init_if_needed().
|
||||
Return 0 if OK, else -1.
|
||||
This procedure is already prototyped in crypto.h.
|
||||
|
||||
int _libssh2_ed25519_new_public(libssh2_ed25519_ctx **ed_ctx,
|
||||
LIBSSH2_SESSION *session,
|
||||
const unsigned char *raw_pub_key,
|
||||
const uint8_t key_len);
|
||||
Stores at ed_ctx a new ED25519 key context for raw public key (raw_pub_key,
|
||||
key_len).
|
||||
Return 0 if OK, else -1.
|
||||
This procedure is already prototyped in crypto.h.
|
||||
|
||||
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);
|
||||
Builds an ED25519 private key from PEM data at filedata of length filedata_len
|
||||
into a new ED25519 context stored at ed_ctx.
|
||||
Must call _libssh2_init_if_needed().
|
||||
Return 0 if OK, else -1.
|
||||
This procedure is already prototyped in crypto.h.
|
||||
|
||||
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);
|
||||
ED25519 signs the (message, message_len) bytes and stores the allocated
|
||||
signature at (sig, sig_len).
|
||||
Signature buffer is allocated from the given session.
|
||||
Returns 0 if OK, else -1.
|
||||
This procedure is already prototyped in crypto.h.
|
||||
|
||||
int _libssh2_ed25519_verify(libssh2_ed25519_ctx *ctx, const uint8_t *s,
|
||||
size_t s_len, const uint8_t *m, size_t m_len);
|
||||
Verify (s, s_len) signature of (m, m_len) using the given ED25519 context.
|
||||
Return 0 if OK, else -1.
|
||||
This procedure is already prototyped in crypto.h.
|
||||
|
||||
int _libssh2_curve25519_gen_k(_libssh2_bn **k,
|
||||
uint8_t private_key[LIBSSH2_ED25519_KEY_LEN],
|
||||
uint8_t srvr_public_key[LIBSSH2_ED25519_KEY_LEN]);
|
||||
Computes a shared ED25519 secret key from the given raw server public key and
|
||||
raw client public key and stores it as a big number in *k. Big number should
|
||||
have been initialized before calling this function.
|
||||
Returns 0 if OK, else -1.
|
||||
This procedure is already prototyped in crypto.h.
|
||||
|
||||
void _libssh2_ed25519_free(libssh2_ed25519_ctx *ed25519ctx);
|
||||
Releases the ED25519 computation context at ed25519ctx.
|
||||
|
||||
|
||||
8) Miscellaneous
|
||||
|
||||
void libssh2_prepare_iovec(struct iovec *vector, unsigned int len);
|
||||
@@ -635,5 +897,6 @@ In example, this is needed to preset unused structure slacks on platforms
|
||||
requiring it.
|
||||
If this is not needed, it should be defined as an empty macro.
|
||||
|
||||
void _libssh2_random(unsigned char *buf, int len);
|
||||
int _libssh2_random(unsigned char *buf, int len);
|
||||
Store len random bytes at buf.
|
||||
Returns 0 if OK, else -1.
|
||||
@@ -14,9 +14,9 @@ If you want to build directly from the git repository, you must first
|
||||
generate the configure script and Makefile using autotools. There is
|
||||
a convenience script that calls all tools in the correct order. Make
|
||||
sure that autoconf, automake and libtool are installed on your system,
|
||||
then execute the following script:
|
||||
then execute:
|
||||
|
||||
./buildconf
|
||||
autoreconf -fi
|
||||
|
||||
After executing this script, you can build the project as usual:
|
||||
|
||||
|
||||
@@ -20,10 +20,12 @@ Getting started
|
||||
If you are happy with the default options, make a new build directory,
|
||||
change to it, configure the build environment and build the project:
|
||||
|
||||
```
|
||||
mkdir bin
|
||||
cd bin
|
||||
cmake ..
|
||||
cmake --build .
|
||||
```
|
||||
|
||||
libssh2 will be built as a static library and will use any
|
||||
cryptography library available. The library binary will be put in
|
||||
@@ -40,6 +42,11 @@ pass the options to CMake on the command line:
|
||||
|
||||
The following options are available:
|
||||
|
||||
* `LINT=ON`
|
||||
|
||||
Enables running the source code linter when building. Can be `ON` or `OFF`.
|
||||
|
||||
|
||||
* `BUILD_SHARED_LIBS=OFF`
|
||||
|
||||
Determines whether libssh2 is built as a static library or as a
|
||||
@@ -119,20 +126,27 @@ Tests
|
||||
To test the build, run the appropriate test target for your build
|
||||
system. For example:
|
||||
|
||||
```
|
||||
cmake --build . --target test
|
||||
```
|
||||
or
|
||||
```
|
||||
cmake --build . --target RUN_TESTS
|
||||
```
|
||||
|
||||
How do I use libssh2 in my project if my project doesn't use CMake?
|
||||
-------------------------------------------------------------------
|
||||
|
||||
If you are not using CMake for your own project, install libssh2
|
||||
|
||||
```
|
||||
cmake <libssh2 source location>
|
||||
cmake --build .
|
||||
cmake --build . --target install
|
||||
```
|
||||
or
|
||||
```
|
||||
cmake --build . --target INSTALL
|
||||
```
|
||||
|
||||
and then specify the install location to your project in the normal
|
||||
way for your build environment. If you don't like the default install
|
||||
@@ -1,7 +1,7 @@
|
||||
# $Id: Makefile.am,v 1.37 2009/03/26 15:41:15 bagder Exp $
|
||||
|
||||
EXTRA_DIST = template.3 BINDINGS INSTALL_AUTOTOOLS INSTALL_CMAKE HACKING TODO \
|
||||
AUTHORS CMakeLists.txt HACKING.CRYPTO SECURITY.md
|
||||
EXTRA_DIST = template.3 BINDINGS INSTALL_AUTOTOOLS INSTALL_CMAKE.md HACKING TODO \
|
||||
AUTHORS CMakeLists.txt HACKING-CRYPTO SECURITY.md
|
||||
|
||||
dist_man_MANS = \
|
||||
libssh2_agent_connect.3 \
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
# Makefile.in generated by automake 1.16.1 from Makefile.am.
|
||||
# Makefile.in generated by automake 1.16.4 from Makefile.am.
|
||||
# @configure_input@
|
||||
|
||||
# Copyright (C) 1994-2018 Free Software Foundation, Inc.
|
||||
# Copyright (C) 1994-2021 Free Software Foundation, Inc.
|
||||
|
||||
# This Makefile.in is free software; the Free Software Foundation
|
||||
# gives unlimited permission to copy and/or distribute it,
|
||||
@@ -101,8 +101,7 @@ am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
|
||||
$(ACLOCAL_M4)
|
||||
DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON)
|
||||
mkinstalldirs = $(install_sh) -d
|
||||
CONFIG_HEADER = $(top_builddir)/src/libssh2_config.h \
|
||||
$(top_builddir)/example/libssh2_config.h
|
||||
CONFIG_HEADER = $(top_builddir)/src/libssh2_config.h
|
||||
CONFIG_CLEAN_FILES =
|
||||
CONFIG_CLEAN_VPATH_FILES =
|
||||
AM_V_P = $(am__v_P_@AM_V@)
|
||||
@@ -173,6 +172,12 @@ CCDEPMODE = @CCDEPMODE@
|
||||
CFLAGS = @CFLAGS@
|
||||
CPP = @CPP@
|
||||
CPPFLAGS = @CPPFLAGS@
|
||||
CSCOPE = @CSCOPE@
|
||||
CTAGS = @CTAGS@
|
||||
CXX = @CXX@
|
||||
CXXCPP = @CXXCPP@
|
||||
CXXDEPMODE = @CXXDEPMODE@
|
||||
CXXFLAGS = @CXXFLAGS@
|
||||
CYGPATH_W = @CYGPATH_W@
|
||||
DEFS = @DEFS@
|
||||
DEPDIR = @DEPDIR@
|
||||
@@ -183,6 +188,7 @@ ECHO_C = @ECHO_C@
|
||||
ECHO_N = @ECHO_N@
|
||||
ECHO_T = @ECHO_T@
|
||||
EGREP = @EGREP@
|
||||
ETAGS = @ETAGS@
|
||||
EXEEXT = @EXEEXT@
|
||||
FGREP = @FGREP@
|
||||
GREP = @GREP@
|
||||
@@ -216,6 +222,7 @@ LIBSSL_PREFIX = @LIBSSL_PREFIX@
|
||||
LIBTOOL = @LIBTOOL@
|
||||
LIBZ = @LIBZ@
|
||||
LIBZ_PREFIX = @LIBZ_PREFIX@
|
||||
LIB_FUZZING_ENGINE = @LIB_FUZZING_ENGINE@
|
||||
LIPO = @LIPO@
|
||||
LN_S = @LN_S@
|
||||
LTLIBBCRYPT = @LTLIBBCRYPT@
|
||||
@@ -257,6 +264,7 @@ abs_top_builddir = @abs_top_builddir@
|
||||
abs_top_srcdir = @abs_top_srcdir@
|
||||
ac_ct_AR = @ac_ct_AR@
|
||||
ac_ct_CC = @ac_ct_CC@
|
||||
ac_ct_CXX = @ac_ct_CXX@
|
||||
ac_ct_DUMPBIN = @ac_ct_DUMPBIN@
|
||||
am__include = @am__include@
|
||||
am__leading_dot = @am__leading_dot@
|
||||
@@ -304,8 +312,8 @@ target_alias = @target_alias@
|
||||
top_build_prefix = @top_build_prefix@
|
||||
top_builddir = @top_builddir@
|
||||
top_srcdir = @top_srcdir@
|
||||
EXTRA_DIST = template.3 BINDINGS INSTALL_AUTOTOOLS INSTALL_CMAKE HACKING TODO \
|
||||
AUTHORS CMakeLists.txt HACKING.CRYPTO SECURITY.md
|
||||
EXTRA_DIST = template.3 BINDINGS INSTALL_AUTOTOOLS INSTALL_CMAKE.md HACKING TODO \
|
||||
AUTHORS CMakeLists.txt HACKING-CRYPTO SECURITY.md
|
||||
|
||||
dist_man_MANS = \
|
||||
libssh2_agent_connect.3 \
|
||||
@@ -567,7 +575,6 @@ ctags CTAGS:
|
||||
|
||||
cscope cscopelist:
|
||||
|
||||
|
||||
distdir: $(BUILT_SOURCES)
|
||||
$(MAKE) $(AM_MAKEFLAGS) distdir-am
|
||||
|
||||
|
||||
@@ -32,11 +32,43 @@ function returns 0, the packet will be accepted nonetheless.
|
||||
.IP LIBSSH2_CALLBACK_X11
|
||||
Called when an X11 connection has been accepted
|
||||
.IP LIBSSH2_CALLBACK_SEND
|
||||
Called when libssh2 wants to send some data on the connection.
|
||||
Can be set to a custom function to handle I/O your own way.
|
||||
Called when libssh2 wants to send data on the connection. Can be set to a
|
||||
custom function to handle I/O your own way.
|
||||
|
||||
The prototype of the callback:
|
||||
|
||||
.nf
|
||||
ssize_t sendcb(libssh2_socket_t sockfd, const void *buffer,
|
||||
size_t length, int flags, void **abstract);
|
||||
.fi
|
||||
|
||||
\fBsockfd\fP is the socket to write to, \fBbuffer\fP points to the data to
|
||||
send, \fBlength\fP is the size of the data, \fBflags\fP is the flags that
|
||||
would've been used to a \fIsend()\fP call and \fBabstract\fP is a pointer to
|
||||
the abstract pointer set in the \fIlibssh2_session_init_ex(3)\fP call.
|
||||
|
||||
The callback returns the number of bytes sent, or -1 for error. The special
|
||||
return code \fB-EAGAIN\fP can be returned to signal that the send was aborted
|
||||
to prevent getting blocked and it needs to be called again.
|
||||
.IP LIBSSH2_CALLBACK_RECV
|
||||
Called when libssh2 wants to receive some data from the connection.
|
||||
Can be set to a custom function to handle I/O your own way.
|
||||
Called when libssh2 wants to read data from the connection. Can be set to a
|
||||
custom function to handle I/O your own way.
|
||||
|
||||
The prototype of the callback:
|
||||
|
||||
.nf
|
||||
ssize_t recvcb(libssh2_socket_t sockfd, void *buffer,
|
||||
size_t length, int flags, void **abstract);
|
||||
.fi
|
||||
|
||||
\fBsockfd\fP is the socket to read from, \fBbuffer\fP where to store received
|
||||
data into, \fBlength\fP is the size of the buffer, \fBflags\fP is the flags
|
||||
that would've been used to a \fIrecv()\fP call and \fBabstract\fP is a pointer
|
||||
to the abstract pointer set in the \fIlibssh2_session_init_ex(3)\fP call.
|
||||
|
||||
The callback returns the number of bytes read, or -1 for error. The special
|
||||
return code \fB-EAGAIN\fP can be returned to signal that the read was aborted
|
||||
to prevent getting blocked and it needs to be called again.
|
||||
.SH RETURN VALUE
|
||||
Pointer to previous callback handler. Returns NULL if no prior callback
|
||||
handler was set or the callback type was unknown.
|
||||
|
||||
@@ -57,6 +57,7 @@ set(EXAMPLES
|
||||
sftpdir_nonblock
|
||||
ssh2_exec
|
||||
ssh2_agent
|
||||
ssh2_agent_forwarding
|
||||
ssh2_echo
|
||||
sftp_append
|
||||
subsystem_netconf
|
||||
|
||||
@@ -6,12 +6,12 @@ EXTRA_DIST = libssh2_config.h.in libssh2_config_cmake.h.in CMakeLists.txt
|
||||
noinst_PROGRAMS = direct_tcpip ssh2 scp scp_nonblock scp_write \
|
||||
scp_write_nonblock sftp sftp_nonblock sftp_write sftp_write_nonblock \
|
||||
sftp_mkdir sftp_mkdir_nonblock sftp_RW_nonblock sftp_write_sliding \
|
||||
sftpdir sftpdir_nonblock ssh2_exec ssh2_agent ssh2_echo sftp_append \
|
||||
subsystem_netconf tcpip-forward
|
||||
sftpdir sftpdir_nonblock ssh2_exec ssh2_agent ssh2_agent_forwarding \
|
||||
ssh2_echo sftp_append subsystem_netconf tcpip-forward
|
||||
|
||||
if HAVE_SYS_UN_H
|
||||
noinst_PROGRAMS += x11
|
||||
endif
|
||||
|
||||
AM_CPPFLAGS = -I$(top_srcdir)/include -I$(top_builddir)/example
|
||||
AM_CPPFLAGS = -I$(top_srcdir)/include -I$(top_builddir)/example -I../src
|
||||
LDADD = $(top_builddir)/src/libssh2.la
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
# Makefile.in generated by automake 1.16.1 from Makefile.am.
|
||||
# Makefile.in generated by automake 1.16.4 from Makefile.am.
|
||||
# @configure_input@
|
||||
|
||||
# Copyright (C) 1994-2018 Free Software Foundation, Inc.
|
||||
# Copyright (C) 1994-2021 Free Software Foundation, Inc.
|
||||
|
||||
# This Makefile.in is free software; the Free Software Foundation
|
||||
# gives unlimited permission to copy and/or distribute it,
|
||||
@@ -96,7 +96,8 @@ noinst_PROGRAMS = direct_tcpip$(EXEEXT) ssh2$(EXEEXT) scp$(EXEEXT) \
|
||||
sftp_mkdir_nonblock$(EXEEXT) sftp_RW_nonblock$(EXEEXT) \
|
||||
sftp_write_sliding$(EXEEXT) sftpdir$(EXEEXT) \
|
||||
sftpdir_nonblock$(EXEEXT) ssh2_exec$(EXEEXT) \
|
||||
ssh2_agent$(EXEEXT) ssh2_echo$(EXEEXT) sftp_append$(EXEEXT) \
|
||||
ssh2_agent$(EXEEXT) ssh2_agent_forwarding$(EXEEXT) \
|
||||
ssh2_echo$(EXEEXT) sftp_append$(EXEEXT) \
|
||||
subsystem_netconf$(EXEEXT) tcpip-forward$(EXEEXT) \
|
||||
$(am__EXEEXT_1)
|
||||
@HAVE_SYS_UN_H_TRUE@am__append_1 = x11
|
||||
@@ -112,7 +113,7 @@ am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
|
||||
$(ACLOCAL_M4)
|
||||
DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON)
|
||||
mkinstalldirs = $(install_sh) -d
|
||||
CONFIG_HEADER = $(top_builddir)/src/libssh2_config.h libssh2_config.h
|
||||
CONFIG_HEADER = $(top_builddir)/src/libssh2_config.h
|
||||
CONFIG_CLEAN_FILES =
|
||||
CONFIG_CLEAN_VPATH_FILES =
|
||||
@HAVE_SYS_UN_H_TRUE@am__EXEEXT_1 = x11$(EXEEXT)
|
||||
@@ -193,6 +194,10 @@ ssh2_agent_SOURCES = ssh2_agent.c
|
||||
ssh2_agent_OBJECTS = ssh2_agent.$(OBJEXT)
|
||||
ssh2_agent_LDADD = $(LDADD)
|
||||
ssh2_agent_DEPENDENCIES = $(top_builddir)/src/libssh2.la
|
||||
ssh2_agent_forwarding_SOURCES = ssh2_agent_forwarding.c
|
||||
ssh2_agent_forwarding_OBJECTS = ssh2_agent_forwarding.$(OBJEXT)
|
||||
ssh2_agent_forwarding_LDADD = $(LDADD)
|
||||
ssh2_agent_forwarding_DEPENDENCIES = $(top_builddir)/src/libssh2.la
|
||||
ssh2_echo_SOURCES = ssh2_echo.c
|
||||
ssh2_echo_OBJECTS = ssh2_echo.$(OBJEXT)
|
||||
ssh2_echo_LDADD = $(LDADD)
|
||||
@@ -237,9 +242,10 @@ am__depfiles_remade = ./$(DEPDIR)/direct_tcpip.Po ./$(DEPDIR)/scp.Po \
|
||||
./$(DEPDIR)/sftp_write_nonblock.Po \
|
||||
./$(DEPDIR)/sftp_write_sliding.Po ./$(DEPDIR)/sftpdir.Po \
|
||||
./$(DEPDIR)/sftpdir_nonblock.Po ./$(DEPDIR)/ssh2.Po \
|
||||
./$(DEPDIR)/ssh2_agent.Po ./$(DEPDIR)/ssh2_echo.Po \
|
||||
./$(DEPDIR)/ssh2_exec.Po ./$(DEPDIR)/subsystem_netconf.Po \
|
||||
./$(DEPDIR)/tcpip-forward.Po ./$(DEPDIR)/x11.Po
|
||||
./$(DEPDIR)/ssh2_agent.Po ./$(DEPDIR)/ssh2_agent_forwarding.Po \
|
||||
./$(DEPDIR)/ssh2_echo.Po ./$(DEPDIR)/ssh2_exec.Po \
|
||||
./$(DEPDIR)/subsystem_netconf.Po ./$(DEPDIR)/tcpip-forward.Po \
|
||||
./$(DEPDIR)/x11.Po
|
||||
am__mv = mv -f
|
||||
COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \
|
||||
$(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
|
||||
@@ -263,21 +269,22 @@ SOURCES = direct_tcpip.c scp.c scp_nonblock.c scp_write.c \
|
||||
scp_write_nonblock.c sftp.c sftp_RW_nonblock.c sftp_append.c \
|
||||
sftp_mkdir.c sftp_mkdir_nonblock.c sftp_nonblock.c \
|
||||
sftp_write.c sftp_write_nonblock.c sftp_write_sliding.c \
|
||||
sftpdir.c sftpdir_nonblock.c ssh2.c ssh2_agent.c ssh2_echo.c \
|
||||
ssh2_exec.c subsystem_netconf.c tcpip-forward.c x11.c
|
||||
sftpdir.c sftpdir_nonblock.c ssh2.c ssh2_agent.c \
|
||||
ssh2_agent_forwarding.c ssh2_echo.c ssh2_exec.c \
|
||||
subsystem_netconf.c tcpip-forward.c x11.c
|
||||
DIST_SOURCES = direct_tcpip.c scp.c scp_nonblock.c scp_write.c \
|
||||
scp_write_nonblock.c sftp.c sftp_RW_nonblock.c sftp_append.c \
|
||||
sftp_mkdir.c sftp_mkdir_nonblock.c sftp_nonblock.c \
|
||||
sftp_write.c sftp_write_nonblock.c sftp_write_sliding.c \
|
||||
sftpdir.c sftpdir_nonblock.c ssh2.c ssh2_agent.c ssh2_echo.c \
|
||||
ssh2_exec.c subsystem_netconf.c tcpip-forward.c x11.c
|
||||
sftpdir.c sftpdir_nonblock.c ssh2.c ssh2_agent.c \
|
||||
ssh2_agent_forwarding.c ssh2_echo.c ssh2_exec.c \
|
||||
subsystem_netconf.c tcpip-forward.c x11.c
|
||||
am__can_run_installinfo = \
|
||||
case $$AM_UPDATE_INFO_DIR in \
|
||||
n|no|NO) false;; \
|
||||
*) (install-info --version) >/dev/null 2>&1;; \
|
||||
esac
|
||||
am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) \
|
||||
$(LISP)libssh2_config.h.in
|
||||
am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP)
|
||||
# Read a list of newline-separated strings from the standard input,
|
||||
# and print each of them once, without duplicates. Input order is
|
||||
# *not* preserved.
|
||||
@@ -294,10 +301,7 @@ am__define_uniq_tagged_files = \
|
||||
unique=`for i in $$list; do \
|
||||
if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
|
||||
done | $(am__uniquify_input)`
|
||||
ETAGS = etags
|
||||
CTAGS = ctags
|
||||
am__DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/libssh2_config.h.in \
|
||||
$(top_srcdir)/depcomp
|
||||
am__DIST_COMMON = $(srcdir)/Makefile.in $(top_srcdir)/depcomp
|
||||
DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
|
||||
ACLOCAL = @ACLOCAL@
|
||||
ALLOCA = @ALLOCA@
|
||||
@@ -314,6 +318,12 @@ CCDEPMODE = @CCDEPMODE@
|
||||
CFLAGS = @CFLAGS@
|
||||
CPP = @CPP@
|
||||
CPPFLAGS = @CPPFLAGS@
|
||||
CSCOPE = @CSCOPE@
|
||||
CTAGS = @CTAGS@
|
||||
CXX = @CXX@
|
||||
CXXCPP = @CXXCPP@
|
||||
CXXDEPMODE = @CXXDEPMODE@
|
||||
CXXFLAGS = @CXXFLAGS@
|
||||
CYGPATH_W = @CYGPATH_W@
|
||||
DEFS = @DEFS@
|
||||
DEPDIR = @DEPDIR@
|
||||
@@ -324,6 +334,7 @@ ECHO_C = @ECHO_C@
|
||||
ECHO_N = @ECHO_N@
|
||||
ECHO_T = @ECHO_T@
|
||||
EGREP = @EGREP@
|
||||
ETAGS = @ETAGS@
|
||||
EXEEXT = @EXEEXT@
|
||||
FGREP = @FGREP@
|
||||
GREP = @GREP@
|
||||
@@ -357,6 +368,7 @@ LIBSSL_PREFIX = @LIBSSL_PREFIX@
|
||||
LIBTOOL = @LIBTOOL@
|
||||
LIBZ = @LIBZ@
|
||||
LIBZ_PREFIX = @LIBZ_PREFIX@
|
||||
LIB_FUZZING_ENGINE = @LIB_FUZZING_ENGINE@
|
||||
LIPO = @LIPO@
|
||||
LN_S = @LN_S@
|
||||
LTLIBBCRYPT = @LTLIBBCRYPT@
|
||||
@@ -398,6 +410,7 @@ abs_top_builddir = @abs_top_builddir@
|
||||
abs_top_srcdir = @abs_top_srcdir@
|
||||
ac_ct_AR = @ac_ct_AR@
|
||||
ac_ct_CC = @ac_ct_CC@
|
||||
ac_ct_CXX = @ac_ct_CXX@
|
||||
ac_ct_DUMPBIN = @ac_ct_DUMPBIN@
|
||||
am__include = @am__include@
|
||||
am__leading_dot = @am__leading_dot@
|
||||
@@ -447,10 +460,9 @@ top_builddir = @top_builddir@
|
||||
top_srcdir = @top_srcdir@
|
||||
AUTOMAKE_OPTIONS = foreign nostdinc
|
||||
EXTRA_DIST = libssh2_config.h.in libssh2_config_cmake.h.in CMakeLists.txt
|
||||
AM_CPPFLAGS = -I$(top_srcdir)/include -I$(top_builddir)/example
|
||||
AM_CPPFLAGS = -I$(top_srcdir)/include -I$(top_builddir)/example -I../src
|
||||
LDADD = $(top_builddir)/src/libssh2.la
|
||||
all: libssh2_config.h
|
||||
$(MAKE) $(AM_MAKEFLAGS) all-am
|
||||
all: all-am
|
||||
|
||||
.SUFFIXES:
|
||||
.SUFFIXES: .c .lo .o .obj
|
||||
@@ -484,17 +496,6 @@ $(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps)
|
||||
cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
|
||||
$(am__aclocal_m4_deps):
|
||||
|
||||
libssh2_config.h: stamp-h2
|
||||
@test -f $@ || rm -f stamp-h2
|
||||
@test -f $@ || $(MAKE) $(AM_MAKEFLAGS) stamp-h2
|
||||
|
||||
stamp-h2: $(srcdir)/libssh2_config.h.in $(top_builddir)/config.status
|
||||
@rm -f stamp-h2
|
||||
cd $(top_builddir) && $(SHELL) ./config.status example/libssh2_config.h
|
||||
|
||||
distclean-hdr:
|
||||
-rm -f libssh2_config.h stamp-h2
|
||||
|
||||
clean-noinstPROGRAMS:
|
||||
@list='$(noinst_PROGRAMS)'; test -n "$$list" || exit 0; \
|
||||
echo " rm -f" $$list; \
|
||||
@@ -576,6 +577,10 @@ ssh2_agent$(EXEEXT): $(ssh2_agent_OBJECTS) $(ssh2_agent_DEPENDENCIES) $(EXTRA_ss
|
||||
@rm -f ssh2_agent$(EXEEXT)
|
||||
$(AM_V_CCLD)$(LINK) $(ssh2_agent_OBJECTS) $(ssh2_agent_LDADD) $(LIBS)
|
||||
|
||||
ssh2_agent_forwarding$(EXEEXT): $(ssh2_agent_forwarding_OBJECTS) $(ssh2_agent_forwarding_DEPENDENCIES) $(EXTRA_ssh2_agent_forwarding_DEPENDENCIES)
|
||||
@rm -f ssh2_agent_forwarding$(EXEEXT)
|
||||
$(AM_V_CCLD)$(LINK) $(ssh2_agent_forwarding_OBJECTS) $(ssh2_agent_forwarding_LDADD) $(LIBS)
|
||||
|
||||
ssh2_echo$(EXEEXT): $(ssh2_echo_OBJECTS) $(ssh2_echo_DEPENDENCIES) $(EXTRA_ssh2_echo_DEPENDENCIES)
|
||||
@rm -f ssh2_echo$(EXEEXT)
|
||||
$(AM_V_CCLD)$(LINK) $(ssh2_echo_OBJECTS) $(ssh2_echo_LDADD) $(LIBS)
|
||||
@@ -620,6 +625,7 @@ distclean-compile:
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sftpdir_nonblock.Po@am__quote@ # am--include-marker
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ssh2.Po@am__quote@ # am--include-marker
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ssh2_agent.Po@am__quote@ # am--include-marker
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ssh2_agent_forwarding.Po@am__quote@ # am--include-marker
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ssh2_echo.Po@am__quote@ # am--include-marker
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ssh2_exec.Po@am__quote@ # am--include-marker
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/subsystem_netconf.Po@am__quote@ # am--include-marker
|
||||
@@ -710,7 +716,6 @@ cscopelist-am: $(am__tagged_files)
|
||||
|
||||
distclean-tags:
|
||||
-rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
|
||||
|
||||
distdir: $(BUILT_SOURCES)
|
||||
$(MAKE) $(AM_MAKEFLAGS) distdir-am
|
||||
|
||||
@@ -746,7 +751,7 @@ distdir-am: $(DISTFILES)
|
||||
done
|
||||
check-am: all-am
|
||||
check: check-am
|
||||
all-am: Makefile $(PROGRAMS) libssh2_config.h
|
||||
all-am: Makefile $(PROGRAMS)
|
||||
installdirs:
|
||||
install: install-am
|
||||
install-exec: install-exec-am
|
||||
@@ -802,6 +807,7 @@ distclean: distclean-am
|
||||
-rm -f ./$(DEPDIR)/sftpdir_nonblock.Po
|
||||
-rm -f ./$(DEPDIR)/ssh2.Po
|
||||
-rm -f ./$(DEPDIR)/ssh2_agent.Po
|
||||
-rm -f ./$(DEPDIR)/ssh2_agent_forwarding.Po
|
||||
-rm -f ./$(DEPDIR)/ssh2_echo.Po
|
||||
-rm -f ./$(DEPDIR)/ssh2_exec.Po
|
||||
-rm -f ./$(DEPDIR)/subsystem_netconf.Po
|
||||
@@ -809,7 +815,7 @@ distclean: distclean-am
|
||||
-rm -f ./$(DEPDIR)/x11.Po
|
||||
-rm -f Makefile
|
||||
distclean-am: clean-am distclean-compile distclean-generic \
|
||||
distclean-hdr distclean-tags
|
||||
distclean-tags
|
||||
|
||||
dvi: dvi-am
|
||||
|
||||
@@ -870,6 +876,7 @@ maintainer-clean: maintainer-clean-am
|
||||
-rm -f ./$(DEPDIR)/sftpdir_nonblock.Po
|
||||
-rm -f ./$(DEPDIR)/ssh2.Po
|
||||
-rm -f ./$(DEPDIR)/ssh2_agent.Po
|
||||
-rm -f ./$(DEPDIR)/ssh2_agent_forwarding.Po
|
||||
-rm -f ./$(DEPDIR)/ssh2_echo.Po
|
||||
-rm -f ./$(DEPDIR)/ssh2_exec.Po
|
||||
-rm -f ./$(DEPDIR)/subsystem_netconf.Po
|
||||
@@ -893,18 +900,18 @@ ps-am:
|
||||
|
||||
uninstall-am:
|
||||
|
||||
.MAKE: all install-am install-strip
|
||||
.MAKE: install-am install-strip
|
||||
|
||||
.PHONY: CTAGS GTAGS TAGS all all-am am--depfiles check check-am clean \
|
||||
clean-generic clean-libtool clean-noinstPROGRAMS cscopelist-am \
|
||||
ctags ctags-am distclean distclean-compile distclean-generic \
|
||||
distclean-hdr distclean-libtool distclean-tags distdir dvi \
|
||||
dvi-am html html-am info info-am install install-am \
|
||||
install-data install-data-am install-dvi install-dvi-am \
|
||||
install-exec install-exec-am install-html install-html-am \
|
||||
install-info install-info-am install-man install-pdf \
|
||||
install-pdf-am install-ps install-ps-am install-strip \
|
||||
installcheck installcheck-am installdirs maintainer-clean \
|
||||
distclean-libtool distclean-tags distdir dvi dvi-am html \
|
||||
html-am info info-am install install-am install-data \
|
||||
install-data-am install-dvi install-dvi-am install-exec \
|
||||
install-exec-am install-html install-html-am install-info \
|
||||
install-info-am install-man install-pdf install-pdf-am \
|
||||
install-ps install-ps-am install-strip installcheck \
|
||||
installcheck-am installdirs maintainer-clean \
|
||||
maintainer-clean-generic mostlyclean mostlyclean-compile \
|
||||
mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \
|
||||
tags tags-am uninstall uninstall-am
|
||||
|
||||
292
example/ssh2_agent_forwarding.c
Normal file
292
example/ssh2_agent_forwarding.c
Normal file
@@ -0,0 +1,292 @@
|
||||
/*
|
||||
* Sample showing how to use libssh2 to request agent forwarding
|
||||
* on the remote host. The command executed will run with agent forwarded
|
||||
* so you should be able to do things like clone out protected git
|
||||
* repos and such.
|
||||
*
|
||||
* The example uses agent authentication to ensure an agent to forward
|
||||
* is running.
|
||||
*
|
||||
* Run it like this:
|
||||
*
|
||||
* $ ./ssh2_agent_forwarding 127.0.0.1 user "uptime"
|
||||
*
|
||||
*/
|
||||
|
||||
#include "libssh2_config.h"
|
||||
#include <libssh2.h>
|
||||
|
||||
#ifdef HAVE_WINSOCK2_H
|
||||
# include <winsock2.h>
|
||||
#endif
|
||||
#ifdef HAVE_SYS_SOCKET_H
|
||||
# include <sys/socket.h>
|
||||
#endif
|
||||
#ifdef HAVE_NETINET_IN_H
|
||||
# include <netinet/in.h>
|
||||
#endif
|
||||
#ifdef HAVE_SYS_SELECT_H
|
||||
# include <sys/select.h>
|
||||
#endif
|
||||
# ifdef HAVE_UNISTD_H
|
||||
#include <unistd.h>
|
||||
#endif
|
||||
#ifdef HAVE_ARPA_INET_H
|
||||
# include <arpa/inet.h>
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_SYS_TIME_H
|
||||
# include <sys/time.h>
|
||||
#endif
|
||||
#include <sys/types.h>
|
||||
#include <stdlib.h>
|
||||
#include <fcntl.h>
|
||||
#include <errno.h>
|
||||
#include <stdio.h>
|
||||
#include <ctype.h>
|
||||
|
||||
static int waitsocket(int socket_fd, LIBSSH2_SESSION *session)
|
||||
{
|
||||
struct timeval timeout;
|
||||
int rc;
|
||||
fd_set fd;
|
||||
fd_set *writefd = NULL;
|
||||
fd_set *readfd = NULL;
|
||||
int dir;
|
||||
|
||||
timeout.tv_sec = 10;
|
||||
timeout.tv_usec = 0;
|
||||
|
||||
FD_ZERO(&fd);
|
||||
|
||||
FD_SET(socket_fd, &fd);
|
||||
|
||||
/* now make sure we wait in the correct direction */
|
||||
dir = libssh2_session_block_directions(session);
|
||||
|
||||
if(dir & LIBSSH2_SESSION_BLOCK_INBOUND)
|
||||
readfd = &fd;
|
||||
|
||||
if(dir & LIBSSH2_SESSION_BLOCK_OUTBOUND)
|
||||
writefd = &fd;
|
||||
|
||||
rc = select(socket_fd + 1, readfd, writefd, NULL, &timeout);
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
const char *hostname = "127.0.0.1";
|
||||
const char *commandline = "uptime";
|
||||
const char *username = NULL;
|
||||
unsigned long hostaddr;
|
||||
int sock;
|
||||
struct sockaddr_in sin;
|
||||
LIBSSH2_SESSION *session;
|
||||
LIBSSH2_CHANNEL *channel;
|
||||
LIBSSH2_AGENT *agent = NULL;
|
||||
struct libssh2_agent_publickey *identity, *prev_identity = NULL;
|
||||
int rc;
|
||||
int exitcode;
|
||||
char *exitsignal = (char *)"none";
|
||||
int bytecount = 0;
|
||||
|
||||
#ifdef WIN32
|
||||
WSADATA wsadata;
|
||||
WSAStartup(MAKEWORD(2, 0), &wsadata);
|
||||
#endif
|
||||
if(argc < 2) {
|
||||
fprintf(stderr, "At least IP and username arguments are required.\n");
|
||||
return 1;
|
||||
}
|
||||
/* must be ip address only */
|
||||
hostname = argv[1];
|
||||
username = argv[2];
|
||||
|
||||
if(argc > 3) {
|
||||
commandline = argv[3];
|
||||
}
|
||||
|
||||
rc = libssh2_init(0);
|
||||
if(rc != 0) {
|
||||
fprintf(stderr, "libssh2 initialization failed (%d)\n", rc);
|
||||
return 1;
|
||||
}
|
||||
|
||||
hostaddr = inet_addr(hostname);
|
||||
|
||||
/* Ultra basic "connect to port 22 on localhost"
|
||||
* Your code is responsible for creating the socket establishing the
|
||||
* connection
|
||||
*/
|
||||
sock = socket(AF_INET, SOCK_STREAM, 0);
|
||||
|
||||
sin.sin_family = AF_INET;
|
||||
sin.sin_port = htons(22);
|
||||
sin.sin_addr.s_addr = hostaddr;
|
||||
if(connect(sock, (struct sockaddr*)(&sin),
|
||||
sizeof(struct sockaddr_in)) != 0) {
|
||||
fprintf(stderr, "failed to connect!\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Create a session instance */
|
||||
session = libssh2_session_init();
|
||||
if(!session)
|
||||
return -1;
|
||||
|
||||
if(libssh2_session_handshake(session, sock) != 0) {
|
||||
fprintf(stderr, "Failure establishing SSH session: %d\n", rc);
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Connect to the ssh-agent */
|
||||
agent = libssh2_agent_init(session);
|
||||
if(!agent) {
|
||||
fprintf(stderr, "Failure initializing ssh-agent support\n");
|
||||
rc = 1;
|
||||
goto shutdown;
|
||||
}
|
||||
if(libssh2_agent_connect(agent)) {
|
||||
fprintf(stderr, "Failure connecting to ssh-agent\n");
|
||||
rc = 1;
|
||||
goto shutdown;
|
||||
}
|
||||
if(libssh2_agent_list_identities(agent)) {
|
||||
fprintf(stderr, "Failure requesting identities to ssh-agent\n");
|
||||
rc = 1;
|
||||
goto shutdown;
|
||||
}
|
||||
while(1) {
|
||||
rc = libssh2_agent_get_identity(agent, &identity, prev_identity);
|
||||
if(rc == 1)
|
||||
break;
|
||||
if(rc < 0) {
|
||||
fprintf(stderr,
|
||||
"Failure obtaining identity from ssh-agent support\n");
|
||||
rc = 1;
|
||||
goto shutdown;
|
||||
}
|
||||
if(libssh2_agent_userauth(agent, username, identity)) {
|
||||
fprintf(stderr, "\tAuthentication with username %s and "
|
||||
"public key %s failed!\n",
|
||||
username, identity->comment);
|
||||
}
|
||||
else {
|
||||
fprintf(stderr, "\tAuthentication with username %s and "
|
||||
"public key %s succeeded!\n",
|
||||
username, identity->comment);
|
||||
break;
|
||||
}
|
||||
prev_identity = identity;
|
||||
}
|
||||
if(rc) {
|
||||
fprintf(stderr, "Couldn't continue authentication\n");
|
||||
goto shutdown;
|
||||
}
|
||||
|
||||
#if 0
|
||||
libssh2_trace(session, ~0);
|
||||
#endif
|
||||
|
||||
/* Set session to non-blocking */
|
||||
libssh2_session_set_blocking(session, 0);
|
||||
|
||||
/* Exec non-blocking on the remove host */
|
||||
while((channel = libssh2_channel_open_session(session)) == NULL &&
|
||||
libssh2_session_last_error(session, NULL, NULL, 0) ==
|
||||
LIBSSH2_ERROR_EAGAIN) {
|
||||
waitsocket(sock, session);
|
||||
}
|
||||
if(channel == NULL) {
|
||||
fprintf(stderr, "Error\n");
|
||||
exit(1);
|
||||
}
|
||||
while((rc = libssh2_channel_request_auth_agent(channel)) ==
|
||||
LIBSSH2_ERROR_EAGAIN) {
|
||||
waitsocket(sock, session);
|
||||
}
|
||||
if(rc != 0) {
|
||||
fprintf(stderr, "Error, couldn't request auth agent, error code %d.\n",
|
||||
rc);
|
||||
exit(1);
|
||||
}
|
||||
else {
|
||||
fprintf(stdout, "\tAgent forwarding request succeeded!\n");
|
||||
}
|
||||
while((rc = libssh2_channel_exec(channel, commandline)) ==
|
||||
LIBSSH2_ERROR_EAGAIN) {
|
||||
waitsocket(sock, session);
|
||||
}
|
||||
if(rc != 0) {
|
||||
fprintf(stderr, "Error\n");
|
||||
exit(1);
|
||||
}
|
||||
for(;;) {
|
||||
/* loop until we block */
|
||||
int rc;
|
||||
do {
|
||||
char buffer[0x4000];
|
||||
rc = libssh2_channel_read(channel, buffer, sizeof(buffer) );
|
||||
if(rc > 0) {
|
||||
int i;
|
||||
bytecount += rc;
|
||||
fprintf(stderr, "We read:\n");
|
||||
for(i = 0; i < rc; ++i)
|
||||
fputc(buffer[i], stderr);
|
||||
fprintf(stderr, "\n");
|
||||
}
|
||||
else {
|
||||
if(rc != LIBSSH2_ERROR_EAGAIN)
|
||||
/* no need to output this for the EAGAIN case */
|
||||
fprintf(stderr, "libssh2_channel_read returned %d\n", rc);
|
||||
}
|
||||
}
|
||||
while(rc > 0);
|
||||
|
||||
/* this is due to blocking that would occur otherwise so we loop on
|
||||
this condition */
|
||||
if(rc == LIBSSH2_ERROR_EAGAIN) {
|
||||
waitsocket(sock, session);
|
||||
}
|
||||
else
|
||||
break;
|
||||
}
|
||||
exitcode = 127;
|
||||
while((rc = libssh2_channel_close(channel)) == LIBSSH2_ERROR_EAGAIN) {
|
||||
waitsocket(sock, session);
|
||||
}
|
||||
if(rc == 0) {
|
||||
exitcode = libssh2_channel_get_exit_status(channel);
|
||||
libssh2_channel_get_exit_signal(channel, &exitsignal,
|
||||
NULL, NULL, NULL, NULL, NULL);
|
||||
}
|
||||
|
||||
if(exitsignal) {
|
||||
printf("\nGot signal: %s\n", exitsignal);
|
||||
}
|
||||
else {
|
||||
printf("\nEXIT: %d bytecount: %d\n", exitcode, bytecount);
|
||||
}
|
||||
|
||||
libssh2_channel_free(channel);
|
||||
channel = NULL;
|
||||
|
||||
shutdown:
|
||||
|
||||
libssh2_session_disconnect(session,
|
||||
"Normal Shutdown, Thank you for playing");
|
||||
libssh2_session_free(session);
|
||||
|
||||
#ifdef WIN32
|
||||
closesocket(sock);
|
||||
#else
|
||||
close(sock);
|
||||
#endif
|
||||
fprintf(stderr, "all done\n");
|
||||
|
||||
libssh2_exit();
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -46,12 +46,12 @@
|
||||
to make the BANNER define (used by src/session.c) be a valid SSH
|
||||
banner. Release versions have no appended strings and may of course not
|
||||
have dashes either. */
|
||||
#define LIBSSH2_VERSION "1.9.0"
|
||||
#define LIBSSH2_VERSION "1.10.0"
|
||||
|
||||
/* The numeric version number is also available "in parts" by using these
|
||||
defines: */
|
||||
#define LIBSSH2_VERSION_MAJOR 1
|
||||
#define LIBSSH2_VERSION_MINOR 9
|
||||
#define LIBSSH2_VERSION_MINOR 10
|
||||
#define LIBSSH2_VERSION_PATCH 0
|
||||
|
||||
/* This is the numeric version of the libssh2 version number, meant for easier
|
||||
@@ -69,7 +69,7 @@
|
||||
and it is always a greater number in a more recent release. It makes
|
||||
comparisons with greater than and less than work.
|
||||
*/
|
||||
#define LIBSSH2_VERSION_NUM 0x010900
|
||||
#define LIBSSH2_VERSION_NUM 0x010a00
|
||||
|
||||
/*
|
||||
* 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"
|
||||
*/
|
||||
#define LIBSSH2_TIMESTAMP "Thu Jun 20 06:19:26 UTC 2019"
|
||||
#define LIBSSH2_TIMESTAMP "Sun 29 Aug 2021 08:37:50 PM UTC"
|
||||
|
||||
#ifndef RC_INVOKED
|
||||
|
||||
@@ -235,9 +235,11 @@ typedef off_t libssh2_struct_stat_size;
|
||||
|
||||
/* Default generate and safe prime sizes for
|
||||
diffie-hellman-group-exchange-sha1 */
|
||||
#define LIBSSH2_DH_GEX_MINGROUP 1024
|
||||
#define LIBSSH2_DH_GEX_OPTGROUP 1536
|
||||
#define LIBSSH2_DH_GEX_MAXGROUP 2048
|
||||
#define LIBSSH2_DH_GEX_MINGROUP 2048
|
||||
#define LIBSSH2_DH_GEX_OPTGROUP 4096
|
||||
#define LIBSSH2_DH_GEX_MAXGROUP 8192
|
||||
|
||||
#define LIBSSH2_DH_MAX_MODULUS_BITS 16384
|
||||
|
||||
/* Defaults for pty requests */
|
||||
#define LIBSSH2_TERM_WIDTH 80
|
||||
@@ -503,6 +505,7 @@ typedef struct _LIBSSH2_POLLFD {
|
||||
#define LIBSSH2_ERROR_KNOWN_HOSTS -46
|
||||
#define LIBSSH2_ERROR_CHANNEL_WINDOW_FULL -47
|
||||
#define LIBSSH2_ERROR_KEYFILE_AUTH_FAILED -48
|
||||
#define LIBSSH2_ERROR_RANDGEN -49
|
||||
|
||||
/* this is a define to provide the old (<= 1.2.7) name */
|
||||
#define LIBSSH2_ERROR_BANNER_NONE LIBSSH2_ERROR_BANNER_RECV
|
||||
@@ -545,7 +548,7 @@ LIBSSH2_API void libssh2_free(LIBSSH2_SESSION *session, void *ptr);
|
||||
*
|
||||
* Fills algs with a list of supported acryptographic algorithms. Returns a
|
||||
* non-negative number (number of supported algorithms) on success or a
|
||||
* negative number (an eror code) on failure.
|
||||
* negative number (an error code) on failure.
|
||||
*
|
||||
* NOTE: on success, algs must be deallocated (by calling libssh2_free) when
|
||||
* not needed anymore
|
||||
@@ -688,7 +691,7 @@ libssh2_userauth_publickey_frommemory(LIBSSH2_SESSION *session,
|
||||
* response_callback is provided with filled by library prompts array,
|
||||
* but client must allocate and fill individual responses. Responses
|
||||
* array is already allocated. Responses data will be freed by libssh2
|
||||
* after callback return, but before subsequent callback invokation.
|
||||
* after callback return, but before subsequent callback invocation.
|
||||
*/
|
||||
LIBSSH2_API int
|
||||
libssh2_userauth_keyboard_interactive_ex(LIBSSH2_SESSION* session,
|
||||
@@ -718,7 +721,7 @@ LIBSSH2_API int libssh2_poll(LIBSSH2_POLLFD *fds, unsigned int nfds,
|
||||
|
||||
#define SSH_EXTENDED_DATA_STDERR 1
|
||||
|
||||
/* Returned by any function that would block during a read/write opperation */
|
||||
/* Returned by any function that would block during a read/write operation */
|
||||
#define LIBSSH2CHANNEL_EAGAIN LIBSSH2_ERROR_EAGAIN
|
||||
|
||||
LIBSSH2_API LIBSSH2_CHANNEL *
|
||||
@@ -761,6 +764,8 @@ LIBSSH2_API int libssh2_channel_setenv_ex(LIBSSH2_CHANNEL *channel,
|
||||
(unsigned int)strlen(varname), (value), \
|
||||
(unsigned int)strlen(value))
|
||||
|
||||
LIBSSH2_API int libssh2_channel_request_auth_agent(LIBSSH2_CHANNEL *channel);
|
||||
|
||||
LIBSSH2_API int libssh2_channel_request_pty_ex(LIBSSH2_CHANNEL *channel,
|
||||
const char *term,
|
||||
unsigned int term_len,
|
||||
@@ -987,7 +992,7 @@ libssh2_knownhost_init(LIBSSH2_SESSION *session);
|
||||
#define LIBSSH2_KNOWNHOST_KEYENC_RAW (1<<16)
|
||||
#define LIBSSH2_KNOWNHOST_KEYENC_BASE64 (2<<16)
|
||||
|
||||
/* type of key (3 bits) */
|
||||
/* type of key (4 bits) */
|
||||
#define LIBSSH2_KNOWNHOST_KEY_MASK (15<<18)
|
||||
#define LIBSSH2_KNOWNHOST_KEY_SHIFT 18
|
||||
#define LIBSSH2_KNOWNHOST_KEY_RSA1 (1<<18)
|
||||
@@ -1165,7 +1170,7 @@ libssh2_knownhost_writefile(LIBSSH2_KNOWNHOSTS *hosts,
|
||||
* libssh2_knownhost_get()
|
||||
*
|
||||
* Traverse the internal list of known hosts. Pass NULL to 'prev' to get
|
||||
* the first one. Or pass a poiner to the previously returned one to get the
|
||||
* the first one. Or pass a pointer to the previously returned one to get the
|
||||
* next.
|
||||
*
|
||||
* Returns:
|
||||
@@ -1221,7 +1226,7 @@ libssh2_agent_list_identities(LIBSSH2_AGENT *agent);
|
||||
* libssh2_agent_get_identity()
|
||||
*
|
||||
* Traverse the internal list of public keys. Pass NULL to 'prev' to get
|
||||
* the first one. Or pass a poiner to the previously returned one to get the
|
||||
* the first one. Or pass a pointer to the previously returned one to get the
|
||||
* next.
|
||||
*
|
||||
* Returns:
|
||||
|
||||
@@ -189,32 +189,32 @@ struct _LIBSSH2_SFTP_STATVFS {
|
||||
#define LIBSSH2_FXF_EXCL 0x00000020
|
||||
|
||||
/* SFTP Status Codes (returned by libssh2_sftp_last_error() ) */
|
||||
#define LIBSSH2_FX_OK 0
|
||||
#define LIBSSH2_FX_EOF 1
|
||||
#define LIBSSH2_FX_NO_SUCH_FILE 2
|
||||
#define LIBSSH2_FX_PERMISSION_DENIED 3
|
||||
#define LIBSSH2_FX_FAILURE 4
|
||||
#define LIBSSH2_FX_BAD_MESSAGE 5
|
||||
#define LIBSSH2_FX_NO_CONNECTION 6
|
||||
#define LIBSSH2_FX_CONNECTION_LOST 7
|
||||
#define LIBSSH2_FX_OP_UNSUPPORTED 8
|
||||
#define LIBSSH2_FX_INVALID_HANDLE 9
|
||||
#define LIBSSH2_FX_NO_SUCH_PATH 10
|
||||
#define LIBSSH2_FX_FILE_ALREADY_EXISTS 11
|
||||
#define LIBSSH2_FX_WRITE_PROTECT 12
|
||||
#define LIBSSH2_FX_NO_MEDIA 13
|
||||
#define LIBSSH2_FX_NO_SPACE_ON_FILESYSTEM 14
|
||||
#define LIBSSH2_FX_QUOTA_EXCEEDED 15
|
||||
#define LIBSSH2_FX_UNKNOWN_PRINCIPLE 16 /* Initial mis-spelling */
|
||||
#define LIBSSH2_FX_UNKNOWN_PRINCIPAL 16
|
||||
#define LIBSSH2_FX_LOCK_CONFlICT 17 /* Initial mis-spelling */
|
||||
#define LIBSSH2_FX_LOCK_CONFLICT 17
|
||||
#define LIBSSH2_FX_DIR_NOT_EMPTY 18
|
||||
#define LIBSSH2_FX_NOT_A_DIRECTORY 19
|
||||
#define LIBSSH2_FX_INVALID_FILENAME 20
|
||||
#define LIBSSH2_FX_LINK_LOOP 21
|
||||
#define LIBSSH2_FX_OK 0UL
|
||||
#define LIBSSH2_FX_EOF 1UL
|
||||
#define LIBSSH2_FX_NO_SUCH_FILE 2UL
|
||||
#define LIBSSH2_FX_PERMISSION_DENIED 3UL
|
||||
#define LIBSSH2_FX_FAILURE 4UL
|
||||
#define LIBSSH2_FX_BAD_MESSAGE 5UL
|
||||
#define LIBSSH2_FX_NO_CONNECTION 6UL
|
||||
#define LIBSSH2_FX_CONNECTION_LOST 7UL
|
||||
#define LIBSSH2_FX_OP_UNSUPPORTED 8UL
|
||||
#define LIBSSH2_FX_INVALID_HANDLE 9UL
|
||||
#define LIBSSH2_FX_NO_SUCH_PATH 10UL
|
||||
#define LIBSSH2_FX_FILE_ALREADY_EXISTS 11UL
|
||||
#define LIBSSH2_FX_WRITE_PROTECT 12UL
|
||||
#define LIBSSH2_FX_NO_MEDIA 13UL
|
||||
#define LIBSSH2_FX_NO_SPACE_ON_FILESYSTEM 14UL
|
||||
#define LIBSSH2_FX_QUOTA_EXCEEDED 15UL
|
||||
#define LIBSSH2_FX_UNKNOWN_PRINCIPLE 16UL /* Initial mis-spelling */
|
||||
#define LIBSSH2_FX_UNKNOWN_PRINCIPAL 16UL
|
||||
#define LIBSSH2_FX_LOCK_CONFlICT 17UL /* Initial mis-spelling */
|
||||
#define LIBSSH2_FX_LOCK_CONFLICT 17UL
|
||||
#define LIBSSH2_FX_DIR_NOT_EMPTY 18UL
|
||||
#define LIBSSH2_FX_NOT_A_DIRECTORY 19UL
|
||||
#define LIBSSH2_FX_INVALID_FILENAME 20UL
|
||||
#define LIBSSH2_FX_LINK_LOOP 21UL
|
||||
|
||||
/* Returned by any function that would block during a read/write opperation */
|
||||
/* Returned by any function that would block during a read/write operation */
|
||||
#define LIBSSH2SFTP_EAGAIN LIBSSH2_ERROR_EAGAIN
|
||||
|
||||
/* SFTP API */
|
||||
|
||||
157
install-sh
157
install-sh
@@ -1,7 +1,7 @@
|
||||
#!/bin/sh
|
||||
# install - install a program, script, or datafile
|
||||
|
||||
scriptversion=2018-03-11.20; # UTC
|
||||
scriptversion=2020-11-14.01; # UTC
|
||||
|
||||
# This originates from X11R5 (mit/util/scripts/install.sh), which was
|
||||
# later released in X11R6 (xc/config/util/install.sh) with the
|
||||
@@ -69,6 +69,11 @@ posix_mkdir=
|
||||
# Desired mode of installed file.
|
||||
mode=0755
|
||||
|
||||
# Create dirs (including intermediate dirs) using mode 755.
|
||||
# This is like GNU 'install' as of coreutils 8.32 (2020).
|
||||
mkdir_umask=22
|
||||
|
||||
backupsuffix=
|
||||
chgrpcmd=
|
||||
chmodcmd=$chmodprog
|
||||
chowncmd=
|
||||
@@ -99,18 +104,28 @@ Options:
|
||||
--version display version info and exit.
|
||||
|
||||
-c (ignored)
|
||||
-C install only if different (preserve the last data modification time)
|
||||
-C install only if different (preserve data modification time)
|
||||
-d create directories instead of installing files.
|
||||
-g GROUP $chgrpprog installed files to GROUP.
|
||||
-m MODE $chmodprog installed files to MODE.
|
||||
-o USER $chownprog installed files to USER.
|
||||
-p pass -p to $cpprog.
|
||||
-s $stripprog installed files.
|
||||
-S SUFFIX attempt to back up existing files, with suffix SUFFIX.
|
||||
-t DIRECTORY install into DIRECTORY.
|
||||
-T report an error if DSTFILE is a directory.
|
||||
|
||||
Environment variables override the default commands:
|
||||
CHGRPPROG CHMODPROG CHOWNPROG CMPPROG CPPROG MKDIRPROG MVPROG
|
||||
RMPROG STRIPPROG
|
||||
|
||||
By default, rm is invoked with -f; when overridden with RMPROG,
|
||||
it's up to you to specify -f if you want it.
|
||||
|
||||
If -S is not specified, no backups are attempted.
|
||||
|
||||
Email bug reports to bug-automake@gnu.org.
|
||||
Automake home page: https://www.gnu.org/software/automake/
|
||||
"
|
||||
|
||||
while test $# -ne 0; do
|
||||
@@ -137,8 +152,13 @@ while test $# -ne 0; do
|
||||
-o) chowncmd="$chownprog $2"
|
||||
shift;;
|
||||
|
||||
-p) cpprog="$cpprog -p";;
|
||||
|
||||
-s) stripcmd=$stripprog;;
|
||||
|
||||
-S) backupsuffix="$2"
|
||||
shift;;
|
||||
|
||||
-t)
|
||||
is_target_a_directory=always
|
||||
dst_arg=$2
|
||||
@@ -255,6 +275,10 @@ do
|
||||
dstdir=$dst
|
||||
test -d "$dstdir"
|
||||
dstdir_status=$?
|
||||
# Don't chown directories that already exist.
|
||||
if test $dstdir_status = 0; then
|
||||
chowncmd=""
|
||||
fi
|
||||
else
|
||||
|
||||
# Waiting for this to be detected by the "$cpprog $src $dsttmp" command
|
||||
@@ -301,22 +325,6 @@ do
|
||||
if test $dstdir_status != 0; then
|
||||
case $posix_mkdir in
|
||||
'')
|
||||
# Create intermediate dirs using mode 755 as modified by the umask.
|
||||
# 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
|
||||
@@ -326,52 +334,49 @@ do
|
||||
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-$$
|
||||
# The $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
|
||||
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;;
|
||||
# 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'.
|
||||
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
|
||||
|
||||
if
|
||||
@@ -382,7 +387,7 @@ do
|
||||
then :
|
||||
else
|
||||
|
||||
# The umask is ridiculous, or mkdir does not conform to POSIX,
|
||||
# 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.
|
||||
|
||||
@@ -411,7 +416,7 @@ do
|
||||
prefixes=
|
||||
else
|
||||
if $posix_mkdir; then
|
||||
(umask=$mkdir_umask &&
|
||||
(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
|
||||
@@ -451,7 +456,18 @@ do
|
||||
trap 'ret=$?; rm -f "$dsttmp" "$rmtmp" && exit $ret' 0
|
||||
|
||||
# Copy the file name to the temp name.
|
||||
(umask $cp_umask && $doit_exec $cpprog "$src" "$dsttmp") &&
|
||||
(umask $cp_umask &&
|
||||
{ test -z "$stripcmd" || {
|
||||
# Create $dsttmp read-write so that cp doesn't create it read-only,
|
||||
# which would cause strip to fail.
|
||||
if test -z "$doit"; then
|
||||
: >"$dsttmp" # No need to fork-exec 'touch'.
|
||||
else
|
||||
$doit touch "$dsttmp"
|
||||
fi
|
||||
}
|
||||
} &&
|
||||
$doit_exec $cpprog "$src" "$dsttmp") &&
|
||||
|
||||
# and set any options; do chmod last to preserve setuid bits.
|
||||
#
|
||||
@@ -477,6 +493,13 @@ do
|
||||
then
|
||||
rm -f "$dsttmp"
|
||||
else
|
||||
# If $backupsuffix is set, and the file being installed
|
||||
# already exists, attempt a backup. Don't worry if it fails,
|
||||
# e.g., if mv doesn't support -f.
|
||||
if test -n "$backupsuffix" && test -f "$dst"; then
|
||||
$doit $mvcmd -f "$dst" "$dst$backupsuffix" 2>/dev/null
|
||||
fi
|
||||
|
||||
# Rename the file to the real destination.
|
||||
$doit $mvcmd -f "$dsttmp" "$dst" 2>/dev/null ||
|
||||
|
||||
@@ -491,9 +514,9 @@ do
|
||||
# file should still install successfully.
|
||||
{
|
||||
test ! -f "$dst" ||
|
||||
$doit $rmcmd -f "$dst" 2>/dev/null ||
|
||||
$doit $rmcmd "$dst" 2>/dev/null ||
|
||||
{ $doit $mvcmd -f "$dst" "$rmtmp" 2>/dev/null &&
|
||||
{ $doit $rmcmd -f "$rmtmp" 2>/dev/null; :; }
|
||||
{ $doit $rmcmd "$rmtmp" 2>/dev/null; :; }
|
||||
} ||
|
||||
{ echo "$0: cannot unlink or rename $dst" >&2
|
||||
(exit 1); exit 1
|
||||
|
||||
10
ltmain.sh
10
ltmain.sh
@@ -31,7 +31,7 @@
|
||||
|
||||
PROGRAM=libtool
|
||||
PACKAGE=libtool
|
||||
VERSION="2.4.6 Debian-2.4.6-10"
|
||||
VERSION="2.4.6 Debian-2.4.6-15"
|
||||
package_revision=2.4.6
|
||||
|
||||
|
||||
@@ -387,7 +387,7 @@ EXIT_SKIP=77 # $? = 77 is used to indicate a skipped test to automake.
|
||||
# putting '$debug_cmd' at the start of all your functions, you can get
|
||||
# bash to show function call trace with:
|
||||
#
|
||||
# debug_cmd='eval echo "${FUNCNAME[0]} $*" >&2' bash your-script-name
|
||||
# debug_cmd='echo "${FUNCNAME[0]} $*" >&2' bash your-script-name
|
||||
debug_cmd=${debug_cmd-":"}
|
||||
exit_cmd=:
|
||||
|
||||
@@ -2141,7 +2141,7 @@ include the following information:
|
||||
compiler: $LTCC
|
||||
compiler flags: $LTCFLAGS
|
||||
linker: $LD (gnu? $with_gnu_ld)
|
||||
version: $progname $scriptversion Debian-2.4.6-10
|
||||
version: $progname $scriptversion Debian-2.4.6-15
|
||||
automake: `($AUTOMAKE --version) 2>/dev/null |$SED 1q`
|
||||
autoconf: `($AUTOCONF --version) 2>/dev/null |$SED 1q`
|
||||
|
||||
@@ -7368,10 +7368,12 @@ func_mode_link ()
|
||||
# -stdlib=* select c++ std lib with clang
|
||||
# -fsanitize=* Clang/GCC memory and address sanitizer
|
||||
# -fuse-ld=* Linker select flags for GCC
|
||||
# -static-* direct GCC to link specific libraries statically
|
||||
# -fcilkplus Cilk Plus language extension features for C/C++
|
||||
-64|-mips[0-9]|-r[0-9][0-9]*|-xarch=*|-xtarget=*|+DA*|+DD*|-q*|-m*| \
|
||||
-t[45]*|-txscale*|-p|-pg|--coverage|-fprofile-*|-F*|@*|-tp=*|--sysroot=*| \
|
||||
-O*|-g*|-flto*|-fwhopr*|-fuse-linker-plugin|-fstack-protector*|-stdlib=*| \
|
||||
-specs=*|-fsanitize=*|-fuse-ld=*)
|
||||
-specs=*|-fsanitize=*|-fuse-ld=*|-static-*|-fcilkplus)
|
||||
func_quote_for_eval "$arg"
|
||||
arg=$func_quote_for_eval_result
|
||||
func_append compile_command " $arg"
|
||||
|
||||
10
m4/libtool.m4
vendored
10
m4/libtool.m4
vendored
@@ -1041,8 +1041,8 @@ int forced_loaded() { return 2;}
|
||||
_LT_EOF
|
||||
echo "$LTCC $LTCFLAGS -c -o conftest.o conftest.c" >&AS_MESSAGE_LOG_FD
|
||||
$LTCC $LTCFLAGS -c -o conftest.o conftest.c 2>&AS_MESSAGE_LOG_FD
|
||||
echo "$AR cru libconftest.a conftest.o" >&AS_MESSAGE_LOG_FD
|
||||
$AR cru libconftest.a conftest.o 2>&AS_MESSAGE_LOG_FD
|
||||
echo "$AR cr libconftest.a conftest.o" >&AS_MESSAGE_LOG_FD
|
||||
$AR cr libconftest.a conftest.o 2>&AS_MESSAGE_LOG_FD
|
||||
echo "$RANLIB libconftest.a" >&AS_MESSAGE_LOG_FD
|
||||
$RANLIB libconftest.a 2>&AS_MESSAGE_LOG_FD
|
||||
cat > conftest.c << _LT_EOF
|
||||
@@ -1071,11 +1071,11 @@ _LT_EOF
|
||||
# to the OS version, if on x86, and 10.4, the deployment
|
||||
# target defaults to 10.4. Don't you love it?
|
||||
case ${MACOSX_DEPLOYMENT_TARGET-10.0},$host in
|
||||
10.0,*86*-darwin8*|10.0,*-darwin[[91]]*)
|
||||
10.0,*86*-darwin8*|10.0,*-darwin[[912]]*)
|
||||
_lt_dar_allow_undefined='$wl-undefined ${wl}dynamic_lookup' ;;
|
||||
10.[[012]][[,.]]*)
|
||||
_lt_dar_allow_undefined='$wl-flat_namespace $wl-undefined ${wl}suppress' ;;
|
||||
10.*)
|
||||
10.*|11.*)
|
||||
_lt_dar_allow_undefined='$wl-undefined ${wl}dynamic_lookup' ;;
|
||||
esac
|
||||
;;
|
||||
@@ -1492,7 +1492,7 @@ need_locks=$enable_libtool_lock
|
||||
m4_defun([_LT_PROG_AR],
|
||||
[AC_CHECK_TOOLS(AR, [ar], false)
|
||||
: ${AR=ar}
|
||||
: ${AR_FLAGS=cru}
|
||||
: ${AR_FLAGS=cr}
|
||||
_LT_DECL([], [AR], [1], [The archiver])
|
||||
_LT_DECL([], [AR_FLAGS], [1], [Flags to create an archive])
|
||||
|
||||
|
||||
2
missing
2
missing
@@ -3,7 +3,7 @@
|
||||
|
||||
scriptversion=2018-03-07.03; # UTC
|
||||
|
||||
# Copyright (C) 1996-2018 Free Software Foundation, Inc.
|
||||
# Copyright (C) 1996-2020 Free Software Foundation, Inc.
|
||||
# Originally written by Fran,cois Pinard <pinard@iro.umontreal.ca>, 1996.
|
||||
|
||||
# This program is free software; you can redistribute it and/or modify
|
||||
|
||||
@@ -176,6 +176,7 @@ include(GNUInstallDirs)
|
||||
set(SOURCES
|
||||
${CRYPTO_SOURCES}
|
||||
agent.c
|
||||
agent_win.c
|
||||
blf.h
|
||||
bcrypt_pbkdf.c
|
||||
blowfish.c
|
||||
@@ -359,6 +360,11 @@ elseif(${CMAKE_SYSTEM_NAME} STREQUAL "Darwin")
|
||||
target_compile_definitions(libssh2 PRIVATE LIBSSH2_DARWIN)
|
||||
endif()
|
||||
|
||||
if(MSVC)
|
||||
set(CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG} /Zi /Od")
|
||||
set(CMAKE_SHARED_LINKER_FLAGS_DEBUG "${CMAKE_SHARED_LINKER_FLAGS_DEBUG} /DEBUG")
|
||||
endif()
|
||||
|
||||
if(CMAKE_VERSION VERSION_LESS "2.8.12")
|
||||
# Fall back to over-linking dependencies
|
||||
target_link_libraries(libssh2 ${LIBRARIES})
|
||||
@@ -392,7 +398,7 @@ set(RUNTIME_DEPENDENCIES ${_RUNTIME_DEPENDENCIES} CACHE INTERNAL
|
||||
## During package installation, install Libssh2Config.cmake
|
||||
install(EXPORT Libssh2Config
|
||||
NAMESPACE Libssh2::
|
||||
DESTINATION lib/cmake/libssh2)
|
||||
DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/libssh2)
|
||||
|
||||
## During build, register directly from build tree
|
||||
# create Libssh2Config.cmake
|
||||
@@ -424,4 +430,4 @@ write_basic_package_version_file(
|
||||
COMPATIBILITY SameMajorVersion)
|
||||
install(
|
||||
FILES ${CMAKE_CURRENT_BINARY_DIR}/Libssh2ConfigVersion.cmake
|
||||
DESTINATION lib/cmake/libssh2)
|
||||
DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/libssh2)
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
# Makefile.in generated by automake 1.16.1 from Makefile.am.
|
||||
# Makefile.in generated by automake 1.16.4 from Makefile.am.
|
||||
# @configure_input@
|
||||
|
||||
# Copyright (C) 1994-2018 Free Software Foundation, Inc.
|
||||
# Copyright (C) 1994-2021 Free Software Foundation, Inc.
|
||||
|
||||
# This Makefile.in is free software; the Free Software Foundation
|
||||
# gives unlimited permission to copy and/or distribute it,
|
||||
@@ -100,8 +100,7 @@ am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
|
||||
$(ACLOCAL_M4)
|
||||
DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON)
|
||||
mkinstalldirs = $(install_sh) -d
|
||||
CONFIG_HEADER = libssh2_config.h \
|
||||
$(top_builddir)/example/libssh2_config.h
|
||||
CONFIG_HEADER = libssh2_config.h
|
||||
CONFIG_CLEAN_FILES =
|
||||
CONFIG_CLEAN_VPATH_FILES =
|
||||
am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`;
|
||||
@@ -138,10 +137,10 @@ 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 \
|
||||
userauth.c transport.c version.c knownhost.c agent.c \
|
||||
libgcrypt.c mbedtls.c openssl.c wincng.c pem.c keepalive.c \
|
||||
global.c blowfish.c bcrypt_pbkdf.c libssh2_priv.h libgcrypt.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 \
|
||||
blf.h
|
||||
global.c blowfish.c bcrypt_pbkdf.c agent_win.c libssh2_priv.h \
|
||||
libgcrypt.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 blf.h agent.h
|
||||
@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@ openssl.lo
|
||||
@@ -151,7 +150,7 @@ 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 \
|
||||
userauth.lo transport.lo version.lo knownhost.lo agent.lo \
|
||||
$(am__objects_1) pem.lo keepalive.lo global.lo blowfish.lo \
|
||||
bcrypt_pbkdf.lo
|
||||
bcrypt_pbkdf.lo agent_win.lo
|
||||
am__objects_3 =
|
||||
am__objects_4 = $(am__objects_3)
|
||||
am_libssh2_la_OBJECTS = $(am__objects_2) $(am__objects_4)
|
||||
@@ -178,7 +177,7 @@ am__v_at_1 =
|
||||
DEFAULT_INCLUDES =
|
||||
depcomp = $(SHELL) $(top_srcdir)/depcomp
|
||||
am__maybe_remake_depfiles = depfiles
|
||||
am__depfiles_remade = ./$(DEPDIR)/agent.Plo \
|
||||
am__depfiles_remade = ./$(DEPDIR)/agent.Plo ./$(DEPDIR)/agent_win.Plo \
|
||||
./$(DEPDIR)/bcrypt_pbkdf.Plo ./$(DEPDIR)/blowfish.Plo \
|
||||
./$(DEPDIR)/channel.Plo ./$(DEPDIR)/comp.Plo \
|
||||
./$(DEPDIR)/crypt.Plo ./$(DEPDIR)/global.Plo \
|
||||
@@ -218,8 +217,8 @@ am__can_run_installinfo = \
|
||||
n|no|NO) false;; \
|
||||
*) (install-info --version) >/dev/null 2>&1;; \
|
||||
esac
|
||||
am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) \
|
||||
$(LISP)libssh2_config.h.in
|
||||
am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) \
|
||||
libssh2_config.h.in
|
||||
# Read a list of newline-separated strings from the standard input,
|
||||
# and print each of them once, without duplicates. Input order is
|
||||
# *not* preserved.
|
||||
@@ -236,8 +235,6 @@ am__define_uniq_tagged_files = \
|
||||
unique=`for i in $$list; do \
|
||||
if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
|
||||
done | $(am__uniquify_input)`
|
||||
ETAGS = etags
|
||||
CTAGS = ctags
|
||||
am__DIST_COMMON = $(srcdir)/../Makefile.OpenSSL.inc \
|
||||
$(srcdir)/../Makefile.WinCNG.inc $(srcdir)/../Makefile.inc \
|
||||
$(srcdir)/../Makefile.libgcrypt.inc \
|
||||
@@ -259,6 +256,12 @@ CCDEPMODE = @CCDEPMODE@
|
||||
CFLAGS = @CFLAGS@
|
||||
CPP = @CPP@
|
||||
CPPFLAGS = @CPPFLAGS@
|
||||
CSCOPE = @CSCOPE@
|
||||
CTAGS = @CTAGS@
|
||||
CXX = @CXX@
|
||||
CXXCPP = @CXXCPP@
|
||||
CXXDEPMODE = @CXXDEPMODE@
|
||||
CXXFLAGS = @CXXFLAGS@
|
||||
CYGPATH_W = @CYGPATH_W@
|
||||
DEFS = @DEFS@
|
||||
DEPDIR = @DEPDIR@
|
||||
@@ -269,6 +272,7 @@ ECHO_C = @ECHO_C@
|
||||
ECHO_N = @ECHO_N@
|
||||
ECHO_T = @ECHO_T@
|
||||
EGREP = @EGREP@
|
||||
ETAGS = @ETAGS@
|
||||
EXEEXT = @EXEEXT@
|
||||
FGREP = @FGREP@
|
||||
GREP = @GREP@
|
||||
@@ -302,6 +306,7 @@ LIBSSL_PREFIX = @LIBSSL_PREFIX@
|
||||
LIBTOOL = @LIBTOOL@
|
||||
LIBZ = @LIBZ@
|
||||
LIBZ_PREFIX = @LIBZ_PREFIX@
|
||||
LIB_FUZZING_ENGINE = @LIB_FUZZING_ENGINE@
|
||||
LIPO = @LIPO@
|
||||
LN_S = @LN_S@
|
||||
LTLIBBCRYPT = @LTLIBBCRYPT@
|
||||
@@ -343,6 +348,7 @@ abs_top_builddir = @abs_top_builddir@
|
||||
abs_top_srcdir = @abs_top_srcdir@
|
||||
ac_ct_AR = @ac_ct_AR@
|
||||
ac_ct_CC = @ac_ct_CC@
|
||||
ac_ct_CXX = @ac_ct_CXX@
|
||||
ac_ct_DUMPBIN = @ac_ct_DUMPBIN@
|
||||
am__include = @am__include@
|
||||
am__leading_dot = @am__leading_dot@
|
||||
@@ -408,10 +414,10 @@ AUTOMAKE_OPTIONS = foreign nostdinc
|
||||
CSOURCES = channel.c comp.c crypt.c hostkey.c kex.c mac.c misc.c \
|
||||
packet.c publickey.c scp.c session.c sftp.c userauth.c transport.c \
|
||||
version.c knownhost.c agent.c $(CRYPTO_CSOURCES) pem.c keepalive.c global.c \
|
||||
blowfish.c bcrypt_pbkdf.c
|
||||
blowfish.c bcrypt_pbkdf.c agent_win.c
|
||||
|
||||
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 blf.h
|
||||
mac.h misc.h packet.h userauth.h session.h sftp.h crypto.h blf.h agent.h
|
||||
|
||||
|
||||
# Get the CRYPTO_CSOURCES, CRYPTO_HHEADERS and CRYPTO_LTLIBS defines
|
||||
@@ -554,6 +560,7 @@ distclean-compile:
|
||||
-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_win.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
|
||||
@@ -664,7 +671,6 @@ cscopelist-am: $(am__tagged_files)
|
||||
|
||||
distclean-tags:
|
||||
-rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
|
||||
|
||||
distdir: $(BUILT_SOURCES)
|
||||
$(MAKE) $(AM_MAKEFLAGS) distdir-am
|
||||
|
||||
@@ -742,6 +748,7 @@ clean-am: clean-generic clean-libLTLIBRARIES clean-libtool \
|
||||
|
||||
distclean: distclean-am
|
||||
-rm -f ./$(DEPDIR)/agent.Plo
|
||||
-rm -f ./$(DEPDIR)/agent_win.Plo
|
||||
-rm -f ./$(DEPDIR)/bcrypt_pbkdf.Plo
|
||||
-rm -f ./$(DEPDIR)/blowfish.Plo
|
||||
-rm -f ./$(DEPDIR)/channel.Plo
|
||||
@@ -813,6 +820,7 @@ installcheck-am:
|
||||
|
||||
maintainer-clean: maintainer-clean-am
|
||||
-rm -f ./$(DEPDIR)/agent.Plo
|
||||
-rm -f ./$(DEPDIR)/agent_win.Plo
|
||||
-rm -f ./$(DEPDIR)/bcrypt_pbkdf.Plo
|
||||
-rm -f ./$(DEPDIR)/blowfish.Plo
|
||||
-rm -f ./$(DEPDIR)/channel.Plo
|
||||
|
||||
123
src/agent.c
123
src/agent.c
@@ -38,6 +38,7 @@
|
||||
*/
|
||||
|
||||
#include "libssh2_priv.h"
|
||||
#include "agent.h"
|
||||
#include "misc.h"
|
||||
#include <errno.h>
|
||||
#ifdef HAVE_SYS_UN_H
|
||||
@@ -50,6 +51,9 @@
|
||||
#endif
|
||||
#include "userauth.h"
|
||||
#include "session.h"
|
||||
#ifdef WIN32
|
||||
#include <stdlib.h>
|
||||
#endif
|
||||
|
||||
/* Requests from client to agent for protocol 1 key operations */
|
||||
#define SSH_AGENTC_REQUEST_RSA_IDENTITIES 1
|
||||
@@ -90,58 +94,6 @@
|
||||
#define SSH_AGENT_CONSTRAIN_LIFETIME 1
|
||||
#define SSH_AGENT_CONSTRAIN_CONFIRM 2
|
||||
|
||||
/* non-blocking mode on agent connection is not yet implemented, but
|
||||
for future use. */
|
||||
typedef enum {
|
||||
agent_NB_state_init = 0,
|
||||
agent_NB_state_request_created,
|
||||
agent_NB_state_request_length_sent,
|
||||
agent_NB_state_request_sent,
|
||||
agent_NB_state_response_length_received,
|
||||
agent_NB_state_response_received
|
||||
} agent_nonblocking_states;
|
||||
|
||||
typedef struct agent_transaction_ctx {
|
||||
unsigned char *request;
|
||||
size_t request_len;
|
||||
unsigned char *response;
|
||||
size_t response_len;
|
||||
agent_nonblocking_states state;
|
||||
} *agent_transaction_ctx_t;
|
||||
|
||||
typedef int (*agent_connect_func)(LIBSSH2_AGENT *agent);
|
||||
typedef int (*agent_transact_func)(LIBSSH2_AGENT *agent,
|
||||
agent_transaction_ctx_t transctx);
|
||||
typedef int (*agent_disconnect_func)(LIBSSH2_AGENT *agent);
|
||||
|
||||
struct agent_publickey {
|
||||
struct list_node node;
|
||||
|
||||
/* this is the struct we expose externally */
|
||||
struct libssh2_agent_publickey external;
|
||||
};
|
||||
|
||||
struct agent_ops {
|
||||
agent_connect_func connect;
|
||||
agent_transact_func transact;
|
||||
agent_disconnect_func disconnect;
|
||||
};
|
||||
|
||||
struct _LIBSSH2_AGENT
|
||||
{
|
||||
LIBSSH2_SESSION *session; /* the session this "belongs to" */
|
||||
|
||||
libssh2_socket_t fd;
|
||||
|
||||
struct agent_ops *ops;
|
||||
|
||||
struct agent_transaction_ctx transctx;
|
||||
struct agent_publickey *identity;
|
||||
struct list_head head; /* list of public keys */
|
||||
|
||||
char *identity_agent_path; /* Path to a custom identity agent socket */
|
||||
};
|
||||
|
||||
#ifdef PF_UNIX
|
||||
static int
|
||||
agent_connect_unix(LIBSSH2_AGENT *agent)
|
||||
@@ -175,6 +127,38 @@ agent_connect_unix(LIBSSH2_AGENT *agent)
|
||||
return LIBSSH2_ERROR_NONE;
|
||||
}
|
||||
|
||||
#define RECV_SEND_ALL(func, socket, buffer, length, flags, abstract) \
|
||||
int rc; \
|
||||
size_t finished = 0; \
|
||||
\
|
||||
while(finished < length) { \
|
||||
rc = func(socket, \
|
||||
(char *)buffer + finished, length - finished, \
|
||||
flags, abstract); \
|
||||
if(rc < 0) \
|
||||
return rc; \
|
||||
\
|
||||
finished += rc; \
|
||||
} \
|
||||
\
|
||||
return finished;
|
||||
|
||||
static ssize_t _send_all(LIBSSH2_SEND_FUNC(func), libssh2_socket_t socket,
|
||||
const void *buffer, size_t length,
|
||||
int flags, void **abstract)
|
||||
{
|
||||
RECV_SEND_ALL(func, socket, buffer, length, flags, abstract);
|
||||
}
|
||||
|
||||
static ssize_t _recv_all(LIBSSH2_RECV_FUNC(func), libssh2_socket_t socket,
|
||||
void *buffer, size_t length,
|
||||
int flags, void **abstract)
|
||||
{
|
||||
RECV_SEND_ALL(func, socket, buffer, length, flags, abstract);
|
||||
}
|
||||
|
||||
#undef RECV_SEND_ALL
|
||||
|
||||
static int
|
||||
agent_transact_unix(LIBSSH2_AGENT *agent, agent_transaction_ctx_t transctx)
|
||||
{
|
||||
@@ -184,7 +168,8 @@ agent_transact_unix(LIBSSH2_AGENT *agent, agent_transaction_ctx_t transctx)
|
||||
/* Send the length of the request */
|
||||
if(transctx->state == agent_NB_state_request_created) {
|
||||
_libssh2_htonu32(buf, transctx->request_len);
|
||||
rc = LIBSSH2_SEND_FD(agent->session, agent->fd, buf, sizeof buf, 0);
|
||||
rc = _send_all(agent->session->send, agent->fd,
|
||||
buf, sizeof buf, 0, &agent->session->abstract);
|
||||
if(rc == -EAGAIN)
|
||||
return LIBSSH2_ERROR_EAGAIN;
|
||||
else if(rc < 0)
|
||||
@@ -195,8 +180,8 @@ agent_transact_unix(LIBSSH2_AGENT *agent, agent_transaction_ctx_t transctx)
|
||||
|
||||
/* Send the request body */
|
||||
if(transctx->state == agent_NB_state_request_length_sent) {
|
||||
rc = LIBSSH2_SEND_FD(agent->session, agent->fd, transctx->request,
|
||||
transctx->request_len, 0);
|
||||
rc = _send_all(agent->session->send, agent->fd, transctx->request,
|
||||
transctx->request_len, 0, &agent->session->abstract);
|
||||
if(rc == -EAGAIN)
|
||||
return LIBSSH2_ERROR_EAGAIN;
|
||||
else if(rc < 0)
|
||||
@@ -207,7 +192,8 @@ agent_transact_unix(LIBSSH2_AGENT *agent, agent_transaction_ctx_t transctx)
|
||||
|
||||
/* Receive the length of a response */
|
||||
if(transctx->state == agent_NB_state_request_sent) {
|
||||
rc = LIBSSH2_RECV_FD(agent->session, agent->fd, buf, sizeof buf, 0);
|
||||
rc = _recv_all(agent->session->recv, agent->fd,
|
||||
buf, sizeof buf, 0, &agent->session->abstract);
|
||||
if(rc < 0) {
|
||||
if(rc == -EAGAIN)
|
||||
return LIBSSH2_ERROR_EAGAIN;
|
||||
@@ -225,8 +211,8 @@ agent_transact_unix(LIBSSH2_AGENT *agent, agent_transaction_ctx_t transctx)
|
||||
|
||||
/* Receive the response body */
|
||||
if(transctx->state == agent_NB_state_response_length_received) {
|
||||
rc = LIBSSH2_RECV_FD(agent->session, agent->fd, transctx->response,
|
||||
transctx->response_len, 0);
|
||||
rc = _recv_all(agent->session->recv, agent->fd, transctx->response,
|
||||
transctx->response_len, 0, &agent->session->abstract);
|
||||
if(rc < 0) {
|
||||
if(rc == -EAGAIN)
|
||||
return LIBSSH2_ERROR_EAGAIN;
|
||||
@@ -274,7 +260,7 @@ static int
|
||||
agent_connect_pageant(LIBSSH2_AGENT *agent)
|
||||
{
|
||||
HWND hwnd;
|
||||
hwnd = FindWindow("Pageant", "Pageant");
|
||||
hwnd = FindWindowA("Pageant", "Pageant");
|
||||
if(!hwnd)
|
||||
return _libssh2_error(agent->session, LIBSSH2_ERROR_AGENT_PROTOCOL,
|
||||
"failed connecting agent");
|
||||
@@ -297,15 +283,15 @@ agent_transact_pageant(LIBSSH2_AGENT *agent, agent_transaction_ctx_t transctx)
|
||||
return _libssh2_error(agent->session, LIBSSH2_ERROR_INVAL,
|
||||
"illegal input");
|
||||
|
||||
hwnd = FindWindow("Pageant", "Pageant");
|
||||
hwnd = FindWindowA("Pageant", "Pageant");
|
||||
if(!hwnd)
|
||||
return _libssh2_error(agent->session, LIBSSH2_ERROR_AGENT_PROTOCOL,
|
||||
"found no pageant");
|
||||
|
||||
snprintf(mapname, sizeof(mapname),
|
||||
"PageantRequest%08x%c", (unsigned)GetCurrentThreadId(), '\0');
|
||||
filemap = CreateFileMapping(INVALID_HANDLE_VALUE, NULL, PAGE_READWRITE,
|
||||
0, PAGEANT_MAX_MSGLEN, mapname);
|
||||
filemap = CreateFileMappingA(INVALID_HANDLE_VALUE, NULL, PAGE_READWRITE,
|
||||
0, PAGEANT_MAX_MSGLEN, mapname);
|
||||
|
||||
if(filemap == NULL || filemap == INVALID_HANDLE_VALUE)
|
||||
return _libssh2_error(agent->session, LIBSSH2_ERROR_AGENT_PROTOCOL,
|
||||
@@ -370,6 +356,7 @@ static struct {
|
||||
} supported_backends[] = {
|
||||
#ifdef WIN32
|
||||
{"Pageant", &agent_ops_pageant},
|
||||
{"OpenSSH", &agent_ops_openssh},
|
||||
#endif /* WIN32 */
|
||||
#ifdef PF_UNIX
|
||||
{"Unix", &agent_ops_unix},
|
||||
@@ -407,6 +394,7 @@ agent_sign(LIBSSH2_SESSION *session, unsigned char **sig, size_t *sig_len,
|
||||
_libssh2_store_u32(&s, 0);
|
||||
|
||||
transctx->request_len = s - transctx->request;
|
||||
transctx->send_recv_total = 0;
|
||||
transctx->state = agent_NB_state_request_created;
|
||||
}
|
||||
|
||||
@@ -507,6 +495,7 @@ agent_list_identities(LIBSSH2_AGENT *agent)
|
||||
if(transctx->state == agent_NB_state_init) {
|
||||
transctx->request = &c;
|
||||
transctx->request_len = 1;
|
||||
transctx->send_recv_total = 0;
|
||||
transctx->state = agent_NB_state_request_created;
|
||||
}
|
||||
|
||||
@@ -522,7 +511,9 @@ agent_list_identities(LIBSSH2_AGENT *agent)
|
||||
|
||||
rc = agent->ops->transact(agent, transctx);
|
||||
if(rc) {
|
||||
goto error;
|
||||
LIBSSH2_FREE(agent->session, transctx->response);
|
||||
transctx->response = NULL;
|
||||
return rc;
|
||||
}
|
||||
transctx->request = NULL;
|
||||
|
||||
@@ -681,6 +672,12 @@ libssh2_agent_init(LIBSSH2_SESSION *session)
|
||||
agent->identity_agent_path = NULL;
|
||||
_libssh2_list_init(&agent->head);
|
||||
|
||||
#ifdef WIN32
|
||||
agent->pipe = INVALID_HANDLE_VALUE;
|
||||
memset(&agent->overlapped, 0, sizeof(OVERLAPPED));
|
||||
agent->pending_io = FALSE;
|
||||
#endif
|
||||
|
||||
return agent;
|
||||
}
|
||||
|
||||
|
||||
112
src/agent.h
Normal file
112
src/agent.h
Normal file
@@ -0,0 +1,112 @@
|
||||
#ifndef __LIBSSH2_AGENT_H
|
||||
#define __LIBSSH2_AGENT_H
|
||||
/*
|
||||
* Copyright (c) 2009 by Daiki Ueno
|
||||
* Copyright (C) 2010-2014 by Daniel Stenberg
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms,
|
||||
* with or without modification, are permitted provided
|
||||
* that the following conditions are met:
|
||||
*
|
||||
* Redistributions of source code must retain the above
|
||||
* copyright notice, this list of conditions and the
|
||||
* following disclaimer.
|
||||
*
|
||||
* Redistributions in binary form must reproduce the above
|
||||
* copyright notice, this list of conditions and the following
|
||||
* disclaimer in the documentation and/or other materials
|
||||
* provided with the distribution.
|
||||
*
|
||||
* Neither the name of the copyright holder nor the names
|
||||
* of any other contributors may be used to endorse or
|
||||
* promote products derived from this software without
|
||||
* specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
|
||||
* CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
|
||||
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
|
||||
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
|
||||
* USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
|
||||
* OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include "libssh2_priv.h"
|
||||
#include "misc.h"
|
||||
#include "session.h"
|
||||
#ifdef WIN32
|
||||
#include <stdlib.h>
|
||||
#endif
|
||||
|
||||
/* non-blocking mode on agent connection is not yet implemented, but
|
||||
for future use. */
|
||||
typedef enum {
|
||||
agent_NB_state_init = 0,
|
||||
agent_NB_state_request_created,
|
||||
agent_NB_state_request_length_sent,
|
||||
agent_NB_state_request_sent,
|
||||
agent_NB_state_response_length_received,
|
||||
agent_NB_state_response_received
|
||||
} agent_nonblocking_states;
|
||||
|
||||
typedef struct agent_transaction_ctx {
|
||||
unsigned char *request;
|
||||
size_t request_len;
|
||||
unsigned char *response;
|
||||
size_t response_len;
|
||||
agent_nonblocking_states state;
|
||||
size_t send_recv_total;
|
||||
} *agent_transaction_ctx_t;
|
||||
|
||||
typedef int (*agent_connect_func)(LIBSSH2_AGENT *agent);
|
||||
typedef int (*agent_transact_func)(LIBSSH2_AGENT *agent,
|
||||
agent_transaction_ctx_t transctx);
|
||||
typedef int (*agent_disconnect_func)(LIBSSH2_AGENT *agent);
|
||||
|
||||
struct agent_publickey {
|
||||
struct list_node node;
|
||||
|
||||
/* this is the struct we expose externally */
|
||||
struct libssh2_agent_publickey external;
|
||||
};
|
||||
|
||||
struct agent_ops {
|
||||
agent_connect_func connect;
|
||||
agent_transact_func transact;
|
||||
agent_disconnect_func disconnect;
|
||||
};
|
||||
|
||||
struct _LIBSSH2_AGENT
|
||||
{
|
||||
LIBSSH2_SESSION *session; /* the session this "belongs to" */
|
||||
|
||||
libssh2_socket_t fd;
|
||||
|
||||
struct agent_ops *ops;
|
||||
|
||||
struct agent_transaction_ctx transctx;
|
||||
struct agent_publickey *identity;
|
||||
struct list_head head; /* list of public keys */
|
||||
|
||||
char *identity_agent_path; /* Path to a custom identity agent socket */
|
||||
|
||||
#ifdef WIN32
|
||||
OVERLAPPED overlapped;
|
||||
HANDLE pipe;
|
||||
BOOL pending_io;
|
||||
#endif
|
||||
};
|
||||
|
||||
#ifdef WIN32
|
||||
extern struct agent_ops agent_ops_openssh;
|
||||
#endif
|
||||
|
||||
#endif /* __LIBSSH2_AGENT_H */
|
||||
361
src/agent_win.c
Normal file
361
src/agent_win.c
Normal file
@@ -0,0 +1,361 @@
|
||||
/*
|
||||
* Copyright (c) 2009 by Daiki Ueno
|
||||
* Copyright (C) 2010-2014 by Daniel Stenberg
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms,
|
||||
* with or without modification, are permitted provided
|
||||
* that the following conditions are met:
|
||||
*
|
||||
* Redistributions of source code must retain the above
|
||||
* copyright notice, this list of conditions and the
|
||||
* following disclaimer.
|
||||
*
|
||||
* Redistributions in binary form must reproduce the above
|
||||
* copyright notice, this list of conditions and the following
|
||||
* disclaimer in the documentation and/or other materials
|
||||
* provided with the distribution.
|
||||
*
|
||||
* Neither the name of the copyright holder nor the names
|
||||
* of any other contributors may be used to endorse or
|
||||
* promote products derived from this software without
|
||||
* specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
|
||||
* CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
|
||||
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
|
||||
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
|
||||
* USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
|
||||
* OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include "libssh2_priv.h"
|
||||
#include "agent.h"
|
||||
#include "misc.h"
|
||||
#include <errno.h>
|
||||
#ifdef HAVE_SYS_UN_H
|
||||
#include <sys/un.h>
|
||||
#else
|
||||
/* Use the existence of sys/un.h as a test if Unix domain socket is
|
||||
supported. winsock*.h define PF_UNIX/AF_UNIX but do not actually
|
||||
support them. */
|
||||
#undef PF_UNIX
|
||||
#endif
|
||||
#include "userauth.h"
|
||||
#include "session.h"
|
||||
#ifdef WIN32
|
||||
#include <stdlib.h>
|
||||
#endif
|
||||
|
||||
#ifdef WIN32
|
||||
/* Code to talk to OpenSSH was taken and modified from the Win32 port of
|
||||
* Portable OpenSSH by the PowerShell team. Commit
|
||||
* 8ab565c53f3619d6a1f5ac229e212cad8a52852c of
|
||||
* https://github.com/PowerShell/openssh-portable.git was used as the base,
|
||||
* specificaly the following files:
|
||||
*
|
||||
* - contrib\win32\win32compat\fileio.c
|
||||
* - Structure of agent_connect_openssh from ssh_get_authentication_socket
|
||||
* - Structure of agent_transact_openssh from ssh_request_reply
|
||||
* - contrib\win32\win32compat\wmain_common.c
|
||||
* - Windows equivalent functions for common Unix functions, inlined into
|
||||
* this implementation
|
||||
* - fileio_connect replacing connect
|
||||
* - fileio_read replacing read
|
||||
* - fileio_write replacing write
|
||||
* - fileio_close replacing close
|
||||
*
|
||||
* Author: Tatu Ylonen <ylo@cs.hut.fi>
|
||||
* Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
|
||||
* All rights reserved
|
||||
* Functions for connecting the local authentication agent.
|
||||
*
|
||||
* As far as I am concerned, the code I have written for this software
|
||||
* can be used freely for any purpose. Any derived versions of this
|
||||
* software must be clearly marked as such, and if the derived work is
|
||||
* incompatible with the protocol description in the RFC file, it must be
|
||||
* called by a name other than "ssh" or "Secure Shell".
|
||||
*
|
||||
* SSH2 implementation,
|
||||
* Copyright (c) 2000 Markus Friedl. 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.
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
* Copyright (c) 2015 Microsoft Corp.
|
||||
* All rights reserved
|
||||
*
|
||||
* Microsoft openssh win32 port
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#define WIN32_OPENSSH_AGENT_SOCK "\\\\.\\pipe\\openssh-ssh-agent"
|
||||
|
||||
static int
|
||||
agent_connect_openssh(LIBSSH2_AGENT *agent)
|
||||
{
|
||||
int ret = LIBSSH2_ERROR_NONE;
|
||||
const char *path;
|
||||
HANDLE pipe = INVALID_HANDLE_VALUE;
|
||||
HANDLE event = NULL;
|
||||
|
||||
path = agent->identity_agent_path;
|
||||
if(!path) {
|
||||
path = getenv("SSH_AUTH_SOCK");
|
||||
if(!path)
|
||||
path = WIN32_OPENSSH_AGENT_SOCK;
|
||||
}
|
||||
|
||||
for(;;) {
|
||||
pipe = CreateFileA(
|
||||
path,
|
||||
GENERIC_READ | GENERIC_WRITE,
|
||||
0,
|
||||
NULL,
|
||||
OPEN_EXISTING,
|
||||
/* Non-blocking mode for agent connections is not implemented at
|
||||
* the point this was implemented. The code for Win32 OpenSSH
|
||||
* should support non-blocking IO, but the code calling it doesn't
|
||||
* support it as of yet.
|
||||
* When non-blocking IO is implemented for the surrounding code,
|
||||
* uncomment the following line to enable support within the Win32
|
||||
* OpenSSH code.
|
||||
*/
|
||||
/* FILE_FLAG_OVERLAPPED | */
|
||||
SECURITY_SQOS_PRESENT |
|
||||
SECURITY_IDENTIFICATION,
|
||||
NULL
|
||||
);
|
||||
|
||||
if(pipe != INVALID_HANDLE_VALUE)
|
||||
break;
|
||||
if(GetLastError() != ERROR_PIPE_BUSY)
|
||||
break;
|
||||
|
||||
/* Wait up to 1 second for a pipe instance to become available */
|
||||
if(!WaitNamedPipeA(path, 1000))
|
||||
break;
|
||||
}
|
||||
|
||||
if(pipe == INVALID_HANDLE_VALUE) {
|
||||
ret = _libssh2_error(agent->session, LIBSSH2_ERROR_AGENT_PROTOCOL,
|
||||
"unable to connect to agent pipe");
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
if(SetHandleInformation(pipe, HANDLE_FLAG_INHERIT, 0) == FALSE) {
|
||||
ret = _libssh2_error(agent->session, LIBSSH2_ERROR_AGENT_PROTOCOL,
|
||||
"unable to set handle information of agent pipe");
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
event = CreateEventA(NULL, TRUE, FALSE, NULL);
|
||||
if(event == NULL) {
|
||||
ret = _libssh2_error(agent->session, LIBSSH2_ERROR_AGENT_PROTOCOL,
|
||||
"unable to create async I/O event");
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
agent->pipe = pipe;
|
||||
pipe = INVALID_HANDLE_VALUE;
|
||||
agent->overlapped.hEvent = event;
|
||||
event = NULL;
|
||||
agent->fd = 0; /* Mark as the connection has been established */
|
||||
|
||||
cleanup:
|
||||
if(event != NULL)
|
||||
CloseHandle(event);
|
||||
if(pipe != INVALID_HANDLE_VALUE)
|
||||
CloseHandle(pipe);
|
||||
return ret;
|
||||
}
|
||||
|
||||
#define RECV_SEND_ALL(func, agent, buffer, length, total) \
|
||||
DWORD bytes_transfered; \
|
||||
BOOL ret; \
|
||||
DWORD err; \
|
||||
int rc; \
|
||||
\
|
||||
while(*total < length) { \
|
||||
if(!agent->pending_io) \
|
||||
ret = func(agent->pipe, (char *)buffer + *total, \
|
||||
(DWORD)(length - *total), &bytes_transfered, \
|
||||
&agent->overlapped); \
|
||||
else \
|
||||
ret = GetOverlappedResult(agent->pipe, &agent->overlapped, \
|
||||
&bytes_transfered, FALSE); \
|
||||
\
|
||||
*total += bytes_transfered; \
|
||||
if(!ret) { \
|
||||
err = GetLastError(); \
|
||||
if((!agent->pending_io && ERROR_IO_PENDING == err) \
|
||||
|| (agent->pending_io && ERROR_IO_INCOMPLETE == err)) { \
|
||||
agent->pending_io = TRUE; \
|
||||
return LIBSSH2_ERROR_EAGAIN; \
|
||||
} \
|
||||
\
|
||||
return LIBSSH2_ERROR_SOCKET_NONE; \
|
||||
} \
|
||||
agent->pending_io = FALSE; \
|
||||
} \
|
||||
\
|
||||
rc = (int)*total; \
|
||||
*total = 0; \
|
||||
return rc;
|
||||
|
||||
static int
|
||||
win32_openssh_send_all(LIBSSH2_AGENT *agent, void *buffer, size_t length,
|
||||
size_t *send_recv_total)
|
||||
{
|
||||
RECV_SEND_ALL(WriteFile, agent, buffer, length, send_recv_total)
|
||||
}
|
||||
|
||||
static int
|
||||
win32_openssh_recv_all(LIBSSH2_AGENT *agent, void *buffer, size_t length,
|
||||
size_t *send_recv_total)
|
||||
{
|
||||
RECV_SEND_ALL(ReadFile, agent, buffer, length, send_recv_total)
|
||||
}
|
||||
|
||||
#undef RECV_SEND_ALL
|
||||
|
||||
static int
|
||||
agent_transact_openssh(LIBSSH2_AGENT *agent, agent_transaction_ctx_t transctx)
|
||||
{
|
||||
unsigned char buf[4];
|
||||
int rc;
|
||||
|
||||
/* Send the length of the request */
|
||||
if(transctx->state == agent_NB_state_request_created) {
|
||||
_libssh2_htonu32(buf, (uint32_t)transctx->request_len);
|
||||
rc = win32_openssh_send_all(agent, buf, sizeof buf,
|
||||
&transctx->send_recv_total);
|
||||
if(rc == LIBSSH2_ERROR_EAGAIN)
|
||||
return LIBSSH2_ERROR_EAGAIN;
|
||||
else if(rc < 0)
|
||||
return _libssh2_error(agent->session, LIBSSH2_ERROR_SOCKET_SEND,
|
||||
"agent send failed");
|
||||
transctx->state = agent_NB_state_request_length_sent;
|
||||
}
|
||||
|
||||
/* Send the request body */
|
||||
if(transctx->state == agent_NB_state_request_length_sent) {
|
||||
rc = win32_openssh_send_all(agent, transctx->request,
|
||||
transctx->request_len,
|
||||
&transctx->send_recv_total);
|
||||
if(rc == LIBSSH2_ERROR_EAGAIN)
|
||||
return LIBSSH2_ERROR_EAGAIN;
|
||||
else if(rc < 0)
|
||||
return _libssh2_error(agent->session, LIBSSH2_ERROR_SOCKET_SEND,
|
||||
"agent send failed");
|
||||
transctx->state = agent_NB_state_request_sent;
|
||||
}
|
||||
|
||||
/* Receive the length of the body */
|
||||
if(transctx->state == agent_NB_state_request_sent) {
|
||||
rc = win32_openssh_recv_all(agent, buf, sizeof buf,
|
||||
&transctx->send_recv_total);
|
||||
if(rc == LIBSSH2_ERROR_EAGAIN)
|
||||
return LIBSSH2_ERROR_EAGAIN;
|
||||
else if(rc < 0)
|
||||
return _libssh2_error(agent->session, LIBSSH2_ERROR_SOCKET_RECV,
|
||||
"agent recv failed");
|
||||
|
||||
transctx->response_len = _libssh2_ntohu32(buf);
|
||||
transctx->response = LIBSSH2_ALLOC(agent->session,
|
||||
transctx->response_len);
|
||||
if(!transctx->response)
|
||||
return LIBSSH2_ERROR_ALLOC;
|
||||
|
||||
transctx->state = agent_NB_state_response_length_received;
|
||||
}
|
||||
|
||||
/* Receive the response body */
|
||||
if(transctx->state == agent_NB_state_response_length_received) {
|
||||
rc = win32_openssh_recv_all(agent, transctx->response,
|
||||
transctx->response_len,
|
||||
&transctx->send_recv_total);
|
||||
if(rc == LIBSSH2_ERROR_EAGAIN)
|
||||
return LIBSSH2_ERROR_EAGAIN;
|
||||
else if(rc < 0)
|
||||
return _libssh2_error(agent->session, LIBSSH2_ERROR_SOCKET_RECV,
|
||||
"agent recv failed");
|
||||
transctx->state = agent_NB_state_response_received;
|
||||
}
|
||||
|
||||
return LIBSSH2_ERROR_NONE;
|
||||
}
|
||||
|
||||
static int
|
||||
agent_disconnect_openssh(LIBSSH2_AGENT *agent)
|
||||
{
|
||||
if(!CancelIo(agent->pipe))
|
||||
return _libssh2_error(agent->session, LIBSSH2_ERROR_SOCKET_DISCONNECT,
|
||||
"failed to cancel pending IO of agent pipe");
|
||||
if(!CloseHandle(agent->overlapped.hEvent))
|
||||
return _libssh2_error(agent->session, LIBSSH2_ERROR_SOCKET_DISCONNECT,
|
||||
"failed to close handle to async I/O event");
|
||||
agent->overlapped.hEvent = NULL;
|
||||
/* let queued APCs (if any) drain */
|
||||
SleepEx(0, TRUE);
|
||||
if(!CloseHandle(agent->pipe))
|
||||
return _libssh2_error(agent->session, LIBSSH2_ERROR_SOCKET_DISCONNECT,
|
||||
"failed to close handle to agent pipe");
|
||||
|
||||
agent->pipe = INVALID_HANDLE_VALUE;
|
||||
agent->fd = LIBSSH2_INVALID_SOCKET;
|
||||
|
||||
return LIBSSH2_ERROR_NONE;
|
||||
}
|
||||
|
||||
struct agent_ops agent_ops_openssh = {
|
||||
agent_connect_openssh,
|
||||
agent_transact_openssh,
|
||||
agent_disconnect_openssh
|
||||
};
|
||||
#endif /* WIN32 */
|
||||
@@ -36,7 +36,7 @@
|
||||
* 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
|
||||
* 3. Subsequently the magic string to be encrypted is lengthened and modified
|
||||
* to "OxychromaticBlowfishSwatDynamite"
|
||||
* 4. The hash function is defined to perform 64 rounds of initial state
|
||||
* expansion. (More rounds are performed by iterating the hash.)
|
||||
@@ -81,7 +81,7 @@ bcrypt_hash(uint8_t *sha2pass, uint8_t *sha2salt, uint8_t *out)
|
||||
cdata[i] = Blowfish_stream2word(ciphertext, sizeof(ciphertext),
|
||||
&j);
|
||||
for(i = 0; i < 64; i++)
|
||||
blf_enc(&state, cdata, sizeof(cdata) / sizeof(uint64_t));
|
||||
blf_enc(&state, cdata, BCRYPT_BLOCKS / 2);
|
||||
|
||||
/* copy out */
|
||||
for(i = 0; i < BCRYPT_BLOCKS; i++) {
|
||||
@@ -158,7 +158,7 @@ bcrypt_pbkdf(const char *pass, size_t passlen, const uint8_t *salt,
|
||||
}
|
||||
|
||||
/*
|
||||
* pbkdf2 deviation: ouput the key material non-linearly.
|
||||
* pbkdf2 deviation: output the key material non-linearly.
|
||||
*/
|
||||
amt = MINIMUM(amt, keylen);
|
||||
for(i = 0; i < amt; i++) {
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
#ifndef __LIBSSH2_BLF_H
|
||||
#define __LIBSSH2_BLF_H
|
||||
/* $OpenBSD: blf.h,v 1.7 2007/03/14 17:59:41 grunk Exp $ */
|
||||
/*
|
||||
* Blowfish - a fast block cipher designed by Bruce Schneier
|
||||
@@ -31,9 +33,6 @@
|
||||
* 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.
|
||||
@@ -87,4 +86,4 @@ int bcrypt_pbkdf(const char *pass, size_t passlen, const uint8_t *salt,
|
||||
uint8_t *key, size_t keylen, unsigned int rounds);
|
||||
|
||||
#endif /* !defined(HAVE_BCRYPT_PBKDF) && !defined(HAVE_BLH_H) */
|
||||
#endif /* _BLF_H */
|
||||
#endif /* __LIBSSH2_BLF_H */
|
||||
|
||||
159
src/channel.c
159
src/channel.c
@@ -236,6 +236,7 @@ _libssh2_channel_open(LIBSSH2_SESSION * session, const char *channel_type,
|
||||
return NULL;
|
||||
}
|
||||
else if(rc) {
|
||||
_libssh2_error(session, rc, "Unexpected error");
|
||||
goto channel_error;
|
||||
}
|
||||
|
||||
@@ -1021,6 +1022,158 @@ static int channel_request_pty(LIBSSH2_CHANNEL *channel,
|
||||
"channel request-pty");
|
||||
}
|
||||
|
||||
/**
|
||||
* channel_request_auth_agent
|
||||
* The actual re-entrant method which requests an auth agent.
|
||||
* */
|
||||
static int channel_request_auth_agent(LIBSSH2_CHANNEL *channel,
|
||||
const char *request_str,
|
||||
int request_str_len)
|
||||
{
|
||||
LIBSSH2_SESSION *session = channel->session;
|
||||
unsigned char *s;
|
||||
static const unsigned char reply_codes[3] =
|
||||
{ SSH_MSG_CHANNEL_SUCCESS, SSH_MSG_CHANNEL_FAILURE, 0 };
|
||||
int rc;
|
||||
|
||||
if(channel->req_auth_agent_state == libssh2_NB_state_idle) {
|
||||
/* Only valid options are "auth-agent-req" and
|
||||
* "auth-agent-req_at_openssh.com" so we make sure it is not
|
||||
* actually longer than the longest possible. */
|
||||
if(request_str_len > 26) {
|
||||
return _libssh2_error(session, LIBSSH2_ERROR_INVAL,
|
||||
"request_str length too large");
|
||||
}
|
||||
|
||||
/*
|
||||
* Length: 24 or 36 = packet_type(1) + channel(4) + req_len(4) +
|
||||
* request_str (variable) + want_reply (1) */
|
||||
channel->req_auth_agent_packet_len = 10 + request_str_len;
|
||||
|
||||
/* Zero out the requireev state to reset */
|
||||
memset(&channel->req_auth_agent_requirev_state, 0,
|
||||
sizeof(channel->req_auth_agent_requirev_state));
|
||||
|
||||
_libssh2_debug(session, LIBSSH2_TRACE_CONN,
|
||||
"Requesting auth agent on channel %lu/%lu",
|
||||
channel->local.id, channel->remote.id);
|
||||
|
||||
/*
|
||||
* byte SSH_MSG_CHANNEL_REQUEST
|
||||
* uint32 recipient channel
|
||||
* string "auth-agent-req"
|
||||
* boolean want reply
|
||||
* */
|
||||
s = channel->req_auth_agent_packet;
|
||||
*(s++) = SSH_MSG_CHANNEL_REQUEST;
|
||||
_libssh2_store_u32(&s, channel->remote.id);
|
||||
_libssh2_store_str(&s, (char *)request_str, request_str_len);
|
||||
*(s++) = 0x01;
|
||||
|
||||
channel->req_auth_agent_state = libssh2_NB_state_created;
|
||||
}
|
||||
|
||||
if(channel->req_auth_agent_state == libssh2_NB_state_created) {
|
||||
/* Send the packet, we can use sizeof() on the packet because it
|
||||
* is always completely filled; there are no variable length fields. */
|
||||
rc = _libssh2_transport_send(session, channel->req_auth_agent_packet,
|
||||
channel->req_auth_agent_packet_len,
|
||||
NULL, 0);
|
||||
|
||||
if(rc == LIBSSH2_ERROR_EAGAIN) {
|
||||
_libssh2_error(session, rc,
|
||||
"Would block sending auth-agent request");
|
||||
}
|
||||
else if(rc) {
|
||||
channel->req_auth_agent_state = libssh2_NB_state_idle;
|
||||
return _libssh2_error(session, rc,
|
||||
"Unable to send auth-agent request");
|
||||
}
|
||||
_libssh2_htonu32(channel->req_auth_agent_local_channel,
|
||||
channel->local.id);
|
||||
channel->req_auth_agent_state = libssh2_NB_state_sent;
|
||||
}
|
||||
|
||||
if(channel->req_auth_agent_state == libssh2_NB_state_sent) {
|
||||
unsigned char *data;
|
||||
size_t data_len;
|
||||
unsigned char code;
|
||||
|
||||
rc = _libssh2_packet_requirev(
|
||||
session, reply_codes, &data, &data_len, 1,
|
||||
channel->req_auth_agent_local_channel,
|
||||
4, &channel->req_auth_agent_requirev_state);
|
||||
if(rc == LIBSSH2_ERROR_EAGAIN) {
|
||||
return rc;
|
||||
}
|
||||
else if(rc) {
|
||||
channel->req_auth_agent_state = libssh2_NB_state_idle;
|
||||
return _libssh2_error(session, LIBSSH2_ERROR_PROTO,
|
||||
"Failed to request auth-agent");
|
||||
}
|
||||
|
||||
code = data[0];
|
||||
|
||||
LIBSSH2_FREE(session, data);
|
||||
channel->req_auth_agent_state = libssh2_NB_state_idle;
|
||||
|
||||
if(code == SSH_MSG_CHANNEL_SUCCESS)
|
||||
return 0;
|
||||
}
|
||||
|
||||
return _libssh2_error(session, LIBSSH2_ERROR_CHANNEL_REQUEST_DENIED,
|
||||
"Unable to complete request for auth-agent");
|
||||
}
|
||||
|
||||
/**
|
||||
* libssh2_channel_request_auth_agent
|
||||
* Requests that agent forwarding be enabled for the session. The
|
||||
* request must be sent over a specific channel, which starts the agent
|
||||
* listener on the remote side. Once the channel is closed, the agent
|
||||
* listener continues to exist.
|
||||
* */
|
||||
LIBSSH2_API int
|
||||
libssh2_channel_request_auth_agent(LIBSSH2_CHANNEL *channel)
|
||||
{
|
||||
int rc;
|
||||
|
||||
if(!channel)
|
||||
return LIBSSH2_ERROR_BAD_USE;
|
||||
|
||||
/* The current RFC draft for agent forwarding says you're supposed to
|
||||
* send "auth-agent-req," but most SSH servers out there right now
|
||||
* actually expect "auth-agent-req@openssh.com", so we try that
|
||||
* first. */
|
||||
if(channel->req_auth_agent_try_state == libssh2_NB_state_idle) {
|
||||
BLOCK_ADJUST(rc, channel->session,
|
||||
channel_request_auth_agent(channel,
|
||||
"auth-agent-req@openssh.com",
|
||||
26));
|
||||
|
||||
/* If we failed (but not with EAGAIN), then we move onto
|
||||
* the next step to try another request type. */
|
||||
if(rc != 0 && rc != LIBSSH2_ERROR_EAGAIN)
|
||||
channel->req_auth_agent_try_state = libssh2_NB_state_sent;
|
||||
}
|
||||
|
||||
if(channel->req_auth_agent_try_state == libssh2_NB_state_sent) {
|
||||
BLOCK_ADJUST(rc, channel->session,
|
||||
channel_request_auth_agent(channel,
|
||||
"auth-agent-req", 14));
|
||||
|
||||
/* If we failed without an EAGAIN, then move on with this
|
||||
* state machine. */
|
||||
if(rc != 0 && rc != LIBSSH2_ERROR_EAGAIN)
|
||||
channel->req_auth_agent_try_state = libssh2_NB_state_sent1;
|
||||
}
|
||||
|
||||
/* If things are good, reset the try state. */
|
||||
if(rc == 0)
|
||||
channel->req_auth_agent_try_state = libssh2_NB_state_idle;
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
/*
|
||||
* libssh2_channel_request_pty_ex
|
||||
* Duh... Request a PTY
|
||||
@@ -1185,7 +1338,11 @@ channel_x11_req(LIBSSH2_CHANNEL *channel, int single_connection,
|
||||
border */
|
||||
unsigned char buffer[(LIBSSH2_X11_RANDOM_COOKIE_LEN / 2) + 1];
|
||||
|
||||
_libssh2_random(buffer, LIBSSH2_X11_RANDOM_COOKIE_LEN / 2);
|
||||
if(_libssh2_random(buffer, LIBSSH2_X11_RANDOM_COOKIE_LEN / 2)) {
|
||||
return _libssh2_error(session, LIBSSH2_ERROR_RANDGEN,
|
||||
"Unable to get random bytes "
|
||||
"for x11-req cookie");
|
||||
}
|
||||
for(i = 0; i < (LIBSSH2_X11_RANDOM_COOKIE_LEN / 2); i++) {
|
||||
snprintf((char *)&s[i*2], 3, "%02X", buffer[i]);
|
||||
}
|
||||
|
||||
@@ -38,7 +38,8 @@
|
||||
|
||||
#include "libssh2_priv.h"
|
||||
#ifdef LIBSSH2_HAVE_ZLIB
|
||||
# include <zlib.h>
|
||||
#include <zlib.h>
|
||||
#undef compress /* dodge name clash with ZLIB macro */
|
||||
#endif
|
||||
|
||||
#include "comp.h"
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
#ifndef __LIBSSH2_COMP_H
|
||||
#define __LIBSSH2_COMP_H
|
||||
|
||||
/* Copyright (C) 2009-2010 by Daniel Stenberg
|
||||
*
|
||||
* Redistribution and use in source and binary forms,
|
||||
|
||||
12
src/crypto.h
12
src/crypto.h
@@ -1,3 +1,5 @@
|
||||
#ifndef __LIBSSH2_CRYPTO_H
|
||||
#define __LIBSSH2_CRYPTO_H
|
||||
/* Copyright (C) 2009, 2010 Simon Josefsson
|
||||
* Copyright (C) 2006, 2007 The Written Word, Inc. All rights reserved.
|
||||
* Copyright (C) 2010-2019 Daniel Stenberg
|
||||
@@ -35,8 +37,6 @@
|
||||
* USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
|
||||
* OF SUCH DAMAGE.
|
||||
*/
|
||||
#ifndef LIBSSH2_CRYPTO_H
|
||||
#define LIBSSH2_CRYPTO_H
|
||||
|
||||
#ifdef LIBSSH2_OPENSSL
|
||||
#include "openssl.h"
|
||||
@@ -170,7 +170,7 @@ int _libssh2_ecdsa_new_private_frommemory(libssh2_ecdsa_ctx ** ec_ctx,
|
||||
unsigned const char *passphrase);
|
||||
|
||||
libssh2_curve_type
|
||||
_libssh2_ecdsa_key_get_curve_type(_libssh2_ec_key *key);
|
||||
_libssh2_ecdsa_get_curve_type(libssh2_ecdsa_ctx *ec_ctx);
|
||||
|
||||
int
|
||||
_libssh2_ecdsa_curve_type_from_name(const char *name,
|
||||
@@ -181,8 +181,8 @@ _libssh2_ecdsa_curve_type_from_name(const char *name,
|
||||
#if LIBSSH2_ED25519
|
||||
|
||||
int
|
||||
_libssh2_curve25519_new(LIBSSH2_SESSION *session, libssh2_ed25519_ctx **ctx,
|
||||
uint8_t **out_public_key, uint8_t **out_private_key);
|
||||
_libssh2_curve25519_new(LIBSSH2_SESSION *session, uint8_t **out_public_key,
|
||||
uint8_t **out_private_key);
|
||||
|
||||
int
|
||||
_libssh2_curve25519_gen_k(_libssh2_bn **k,
|
||||
@@ -245,4 +245,4 @@ int _libssh2_pub_priv_keyfilememory(LIBSSH2_SESSION *session,
|
||||
size_t privatekeydata_len,
|
||||
const char *passphrase);
|
||||
|
||||
#endif
|
||||
#endif /* __LIBSSH2_CRYPTO_H */
|
||||
|
||||
@@ -62,7 +62,8 @@ libssh2_exit(void)
|
||||
|
||||
_libssh2_initialized--;
|
||||
|
||||
if(!(_libssh2_init_flags & LIBSSH2_INIT_NO_CRYPTO)) {
|
||||
if(_libssh2_initialized == 0 &&
|
||||
!(_libssh2_init_flags & LIBSSH2_INIT_NO_CRYPTO)) {
|
||||
libssh2_crypto_exit();
|
||||
}
|
||||
|
||||
|
||||
@@ -647,7 +647,7 @@ hostkey_method_ssh_ecdsa_sig_verify(LIBSSH2_SESSION * session,
|
||||
{
|
||||
unsigned char *r, *s, *name;
|
||||
size_t r_len, s_len, name_len;
|
||||
unsigned int len;
|
||||
uint32_t len;
|
||||
struct string_buf buf;
|
||||
libssh2_ecdsa_ctx *ctx = (libssh2_ecdsa_ctx *) (*abstract);
|
||||
|
||||
@@ -709,7 +709,7 @@ hostkey_method_ssh_ecdsa_signv(LIBSSH2_SESSION * session,
|
||||
void **abstract)
|
||||
{
|
||||
libssh2_ecdsa_ctx *ec_ctx = (libssh2_ecdsa_ctx *) (*abstract);
|
||||
libssh2_curve_type type = _libssh2_ecdsa_key_get_curve_type(ec_ctx);
|
||||
libssh2_curve_type type = _libssh2_ecdsa_get_curve_type(ec_ctx);
|
||||
int ret = 0;
|
||||
|
||||
if(type == LIBSSH2_EC_CURVE_NISTP256) {
|
||||
@@ -783,6 +783,42 @@ static const LIBSSH2_HOSTKEY_METHOD hostkey_method_ecdsa_ssh_nistp521 = {
|
||||
hostkey_method_ssh_ecdsa_dtor,
|
||||
};
|
||||
|
||||
static const LIBSSH2_HOSTKEY_METHOD hostkey_method_ecdsa_ssh_nistp256_cert = {
|
||||
"ecdsa-sha2-nistp256-cert-v01@openssh.com",
|
||||
SHA256_DIGEST_LENGTH,
|
||||
NULL,
|
||||
hostkey_method_ssh_ecdsa_initPEM,
|
||||
hostkey_method_ssh_ecdsa_initPEMFromMemory,
|
||||
NULL,
|
||||
hostkey_method_ssh_ecdsa_signv,
|
||||
NULL, /* encrypt */
|
||||
hostkey_method_ssh_ecdsa_dtor,
|
||||
};
|
||||
|
||||
static const LIBSSH2_HOSTKEY_METHOD hostkey_method_ecdsa_ssh_nistp384_cert = {
|
||||
"ecdsa-sha2-nistp384-cert-v01@openssh.com",
|
||||
SHA384_DIGEST_LENGTH,
|
||||
NULL,
|
||||
hostkey_method_ssh_ecdsa_initPEM,
|
||||
hostkey_method_ssh_ecdsa_initPEMFromMemory,
|
||||
NULL,
|
||||
hostkey_method_ssh_ecdsa_signv,
|
||||
NULL, /* encrypt */
|
||||
hostkey_method_ssh_ecdsa_dtor,
|
||||
};
|
||||
|
||||
static const LIBSSH2_HOSTKEY_METHOD hostkey_method_ecdsa_ssh_nistp521_cert = {
|
||||
"ecdsa-sha2-nistp521-cert-v01@openssh.com",
|
||||
SHA512_DIGEST_LENGTH,
|
||||
NULL,
|
||||
hostkey_method_ssh_ecdsa_initPEM,
|
||||
hostkey_method_ssh_ecdsa_initPEMFromMemory,
|
||||
NULL,
|
||||
hostkey_method_ssh_ecdsa_signv,
|
||||
NULL, /* encrypt */
|
||||
hostkey_method_ssh_ecdsa_dtor,
|
||||
};
|
||||
|
||||
#endif /* LIBSSH2_ECDSA */
|
||||
|
||||
#if LIBSSH2_ED25519
|
||||
@@ -999,6 +1035,9 @@ static const LIBSSH2_HOSTKEY_METHOD *hostkey_methods[] = {
|
||||
&hostkey_method_ecdsa_ssh_nistp256,
|
||||
&hostkey_method_ecdsa_ssh_nistp384,
|
||||
&hostkey_method_ecdsa_ssh_nistp521,
|
||||
&hostkey_method_ecdsa_ssh_nistp256_cert,
|
||||
&hostkey_method_ecdsa_ssh_nistp384_cert,
|
||||
&hostkey_method_ecdsa_ssh_nistp521_cert,
|
||||
#endif
|
||||
#if LIBSSH2_ED25519
|
||||
&hostkey_method_ssh_ed25519,
|
||||
|
||||
@@ -955,7 +955,7 @@ libssh2_knownhost_readfile(LIBSSH2_KNOWNHOSTS *hosts,
|
||||
{
|
||||
FILE *file;
|
||||
int num = 0;
|
||||
char buf[2048];
|
||||
char buf[4092];
|
||||
|
||||
if(type != LIBSSH2_KNOWNHOST_FILE_OPENSSH)
|
||||
return _libssh2_error(hosts->session,
|
||||
@@ -1194,7 +1194,7 @@ libssh2_knownhost_writefile(LIBSSH2_KNOWNHOSTS *hosts,
|
||||
struct known_host *node;
|
||||
FILE *file;
|
||||
int rc = LIBSSH2_ERROR_NONE;
|
||||
char buffer[2048];
|
||||
char buffer[4092];
|
||||
|
||||
/* we only support this single file type for now, bail out on all other
|
||||
attempts */
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
#ifndef __LIBSSH2_LIBGCRYPT_H
|
||||
#define __LIBSSH2_LIBGCRYPT_H
|
||||
/*
|
||||
* Copyright (C) 2008, 2009, 2010 Simon Josefsson
|
||||
* Copyright (C) 2006, 2007, The Written Word, Inc.
|
||||
@@ -66,7 +68,7 @@
|
||||
#define EC_MAX_POINT_LEN ((528 * 2 / 8) + 1)
|
||||
|
||||
#define _libssh2_random(buf, len) \
|
||||
(gcry_randomize ((buf), (len), GCRY_STRONG_RANDOM), 1)
|
||||
(gcry_randomize ((buf), (len), GCRY_STRONG_RANDOM), 0)
|
||||
|
||||
#define libssh2_prepare_iovec(vec, len) /* Empty. */
|
||||
|
||||
@@ -232,3 +234,4 @@ 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);
|
||||
|
||||
#endif /* __LIBSSH2_LIBGCRYPT_H */
|
||||
|
||||
@@ -3,19 +3,13 @@
|
||||
/* Define if building universal (internal helper macro) */
|
||||
#undef AC_APPLE_UNIVERSAL_BUILD
|
||||
|
||||
/* Define to one of `_getb67', `GETB67', `getb67' for Cray-2 and Cray-YMP
|
||||
systems. This function is required for `alloca.c' support on those systems.
|
||||
*/
|
||||
#undef CRAY_STACKSEG_END
|
||||
|
||||
/* Define to 1 if using `alloca.c'. */
|
||||
/* Define to 1 if using 'alloca.c'. */
|
||||
#undef C_ALLOCA
|
||||
|
||||
/* Define to 1 if you have `alloca', as a function or macro. */
|
||||
/* Define to 1 if you have 'alloca', as a function or macro. */
|
||||
#undef HAVE_ALLOCA
|
||||
|
||||
/* Define to 1 if you have <alloca.h> and it should be used (not on Ultrix).
|
||||
*/
|
||||
/* Define to 1 if <alloca.h> works. */
|
||||
#undef HAVE_ALLOCA_H
|
||||
|
||||
/* Define to 1 if you have the <arpa/inet.h> header file. */
|
||||
@@ -76,9 +70,6 @@
|
||||
/* Define to 1 if the compiler supports the 'long long' data type. */
|
||||
#undef HAVE_LONGLONG
|
||||
|
||||
/* Define to 1 if you have the <memory.h> header file. */
|
||||
#undef HAVE_MEMORY_H
|
||||
|
||||
/* Define to 1 if you have the `memset_s' function. */
|
||||
#undef HAVE_MEMSET_S
|
||||
|
||||
@@ -222,7 +213,9 @@
|
||||
STACK_DIRECTION = 0 => direction of growth unknown */
|
||||
#undef STACK_DIRECTION
|
||||
|
||||
/* Define to 1 if you have the ANSI C header files. */
|
||||
/* Define to 1 if all of the C90 standard headers exist (not just the ones
|
||||
required in a freestanding environment). This macro is provided for
|
||||
backward compatibility; new code need not use it. */
|
||||
#undef STDC_HEADERS
|
||||
|
||||
/* Version number of package */
|
||||
@@ -240,11 +233,6 @@
|
||||
# endif
|
||||
#endif
|
||||
|
||||
/* Enable large inode numbers on Mac OS X 10.5. */
|
||||
#ifndef _DARWIN_USE_64_BIT_INODE
|
||||
# define _DARWIN_USE_64_BIT_INODE 1
|
||||
#endif
|
||||
|
||||
/* Number of bits in a file offset, on hosts where this is settable. */
|
||||
#undef _FILE_OFFSET_BITS
|
||||
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
#ifndef __LIBSSH2_PRIV_H
|
||||
#define __LIBSSH2_PRIV_H
|
||||
/* Copyright (c) 2004-2008, 2010, Sara Golemon <sarag@libssh2.org>
|
||||
* Copyright (c) 2009-2014 by Daniel Stenberg
|
||||
* Copyright (c) 2010 Simon Josefsson
|
||||
@@ -37,9 +39,6 @@
|
||||
* OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#ifndef LIBSSH2_PRIV_H
|
||||
#define LIBSSH2_PRIV_H 1
|
||||
|
||||
#define LIBSSH2_LIBRARY
|
||||
#include "libssh2_config.h"
|
||||
|
||||
@@ -110,14 +109,19 @@
|
||||
#define inline __inline
|
||||
#endif
|
||||
|
||||
/* Provide iovec / writev on WIN32 platform. */
|
||||
#ifdef WIN32
|
||||
/* 3DS doesn't seem to have iovec */
|
||||
#if defined(WIN32) || defined(_3DS)
|
||||
|
||||
struct iovec {
|
||||
size_t iov_len;
|
||||
void *iov_base;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
/* Provide iovec / writev on WIN32 platform. */
|
||||
#ifdef WIN32
|
||||
|
||||
static inline int writev(int sock, struct iovec *iov, int nvecs)
|
||||
{
|
||||
DWORD ret;
|
||||
@@ -452,6 +456,13 @@ struct _LIBSSH2_CHANNEL
|
||||
/* State variables used in libssh2_channel_handle_extended_data2() */
|
||||
libssh2_nonblocking_states extData2_state;
|
||||
|
||||
/* State variables used in libssh2_channel_request_auth_agent() */
|
||||
libssh2_nonblocking_states req_auth_agent_try_state;
|
||||
libssh2_nonblocking_states req_auth_agent_state;
|
||||
unsigned char req_auth_agent_packet[36];
|
||||
size_t req_auth_agent_packet_len;
|
||||
unsigned char req_auth_agent_local_channel[4];
|
||||
packet_requirev_state_t req_auth_agent_requirev_state;
|
||||
};
|
||||
|
||||
struct _LIBSSH2_LISTENER
|
||||
@@ -1140,4 +1151,4 @@ endings either CRLF or LF so 't' is appropriate.
|
||||
#define FOPEN_APPENDTEXT "a"
|
||||
#endif
|
||||
|
||||
#endif /* LIBSSH2_H */
|
||||
#endif /* __LIBSSH2_PRIV_H */
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
#ifndef __LIBSSH2_MAC_H
|
||||
#define __LIBSSH2_MAC_H
|
||||
|
||||
/* Copyright (C) 2009-2010 by Daniel Stenberg
|
||||
*
|
||||
* Redistribution and use in source and binary forms,
|
||||
|
||||
522
src/mbedtls.c
522
src/mbedtls.c
@@ -94,7 +94,7 @@ _libssh2_mbedtls_safe_free(void *buf, int len)
|
||||
|
||||
#ifdef LIBSSH2_CLEAR_MEMORY
|
||||
if(len > 0)
|
||||
memset(buf, 0, len);
|
||||
_libssh2_explicit_zero(buf, len);
|
||||
#endif
|
||||
|
||||
mbedtls_free(buf);
|
||||
@@ -272,7 +272,7 @@ _libssh2_mbedtls_bignum_random(_libssh2_bn *bn, int bits, int top, int bottom)
|
||||
if(err)
|
||||
return -1;
|
||||
|
||||
/* Zero unsued bits above the most significant bit*/
|
||||
/* Zero unused bits above the most significant bit*/
|
||||
for(i = len*8 - 1; bits <= i; --i) {
|
||||
err = mbedtls_mpi_set_bit(bn, i, 0);
|
||||
if(err)
|
||||
@@ -730,4 +730,522 @@ _libssh2_dh_dtor(_libssh2_dh_ctx *dhctx)
|
||||
*dhctx = NULL;
|
||||
}
|
||||
|
||||
#if LIBSSH2_ECDSA
|
||||
|
||||
/*******************************************************************/
|
||||
/*
|
||||
* mbedTLS backend: ECDSA functions
|
||||
*/
|
||||
|
||||
/*
|
||||
* _libssh2_ecdsa_create_key
|
||||
*
|
||||
* Creates a local private key based on input curve
|
||||
* and returns octal value and octal length
|
||||
*
|
||||
*/
|
||||
|
||||
int
|
||||
_libssh2_mbedtls_ecdsa_create_key(LIBSSH2_SESSION *session,
|
||||
_libssh2_ec_key **privkey,
|
||||
unsigned char **pubkey_oct,
|
||||
size_t *pubkey_oct_len,
|
||||
libssh2_curve_type curve)
|
||||
{
|
||||
size_t plen = 0;
|
||||
|
||||
*privkey = LIBSSH2_ALLOC(session, sizeof(mbedtls_ecp_keypair));
|
||||
|
||||
if(*privkey == NULL)
|
||||
goto failed;
|
||||
|
||||
mbedtls_ecdsa_init(*privkey);
|
||||
|
||||
if(mbedtls_ecdsa_genkey(*privkey, (mbedtls_ecp_group_id)curve,
|
||||
mbedtls_ctr_drbg_random,
|
||||
&_libssh2_mbedtls_ctr_drbg) != 0)
|
||||
goto failed;
|
||||
|
||||
plen = 2 * mbedtls_mpi_size(&(*privkey)->grp.P) + 1;
|
||||
*pubkey_oct = LIBSSH2_ALLOC(session, plen);
|
||||
|
||||
if(*pubkey_oct == NULL)
|
||||
goto failed;
|
||||
|
||||
if(mbedtls_ecp_point_write_binary(&(*privkey)->grp, &(*privkey)->Q,
|
||||
MBEDTLS_ECP_PF_UNCOMPRESSED,
|
||||
pubkey_oct_len, *pubkey_oct, plen) == 0)
|
||||
return 0;
|
||||
|
||||
failed:
|
||||
|
||||
_libssh2_mbedtls_ecdsa_free(*privkey);
|
||||
_libssh2_mbedtls_safe_free(*pubkey_oct, plen);
|
||||
*privkey = NULL;
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* _libssh2_ecdsa_curve_name_with_octal_new
|
||||
*
|
||||
* Creates a new public key given an octal string, length and type
|
||||
*
|
||||
*/
|
||||
|
||||
int
|
||||
_libssh2_mbedtls_ecdsa_curve_name_with_octal_new(libssh2_ecdsa_ctx **ctx,
|
||||
const unsigned char *k,
|
||||
size_t k_len,
|
||||
libssh2_curve_type curve)
|
||||
{
|
||||
*ctx = mbedtls_calloc(1, sizeof(mbedtls_ecp_keypair));
|
||||
|
||||
if(*ctx == NULL)
|
||||
goto failed;
|
||||
|
||||
mbedtls_ecdsa_init(*ctx);
|
||||
|
||||
if(mbedtls_ecp_group_load(&(*ctx)->grp, (mbedtls_ecp_group_id)curve) != 0)
|
||||
goto failed;
|
||||
|
||||
if(mbedtls_ecp_point_read_binary(&(*ctx)->grp, &(*ctx)->Q, k, k_len) != 0)
|
||||
goto failed;
|
||||
|
||||
if(mbedtls_ecp_check_pubkey(&(*ctx)->grp, &(*ctx)->Q) == 0)
|
||||
return 0;
|
||||
|
||||
failed:
|
||||
|
||||
_libssh2_mbedtls_ecdsa_free(*ctx);
|
||||
*ctx = NULL;
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* _libssh2_ecdh_gen_k
|
||||
*
|
||||
* Computes the shared secret K given a local private key,
|
||||
* remote public key and length
|
||||
*/
|
||||
|
||||
int
|
||||
_libssh2_mbedtls_ecdh_gen_k(_libssh2_bn **k,
|
||||
_libssh2_ec_key *privkey,
|
||||
const unsigned char *server_pubkey,
|
||||
size_t server_pubkey_len)
|
||||
{
|
||||
mbedtls_ecp_point pubkey;
|
||||
int rc = 0;
|
||||
|
||||
if(*k == NULL)
|
||||
return -1;
|
||||
|
||||
mbedtls_ecp_point_init(&pubkey);
|
||||
|
||||
if(mbedtls_ecp_point_read_binary(&privkey->grp, &pubkey,
|
||||
server_pubkey, server_pubkey_len) != 0) {
|
||||
rc = -1;
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
if(mbedtls_ecdh_compute_shared(&privkey->grp, *k,
|
||||
&pubkey, &privkey->d,
|
||||
mbedtls_ctr_drbg_random,
|
||||
&_libssh2_mbedtls_ctr_drbg) != 0) {
|
||||
rc = -1;
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
if(mbedtls_ecp_check_privkey(&privkey->grp, *k) != 0)
|
||||
rc = -1;
|
||||
|
||||
cleanup:
|
||||
|
||||
mbedtls_ecp_point_free(&pubkey);
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
#define LIBSSH2_MBEDTLS_ECDSA_VERIFY(digest_type) \
|
||||
{ \
|
||||
unsigned char hsh[SHA##digest_type##_DIGEST_LENGTH]; \
|
||||
\
|
||||
if(libssh2_sha##digest_type(m, m_len, hsh) == 0) { \
|
||||
rc = mbedtls_ecdsa_verify(&ctx->grp, hsh, \
|
||||
SHA##digest_type##_DIGEST_LENGTH, \
|
||||
&ctx->Q, &pr, &ps); \
|
||||
} \
|
||||
\
|
||||
}
|
||||
|
||||
/* _libssh2_ecdsa_sign
|
||||
*
|
||||
* Verifies the ECDSA signature of a hashed message
|
||||
*
|
||||
*/
|
||||
|
||||
int
|
||||
_libssh2_mbedtls_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)
|
||||
{
|
||||
mbedtls_mpi pr, ps;
|
||||
int rc = -1;
|
||||
|
||||
mbedtls_mpi_init(&pr);
|
||||
mbedtls_mpi_init(&ps);
|
||||
|
||||
if(mbedtls_mpi_read_binary(&pr, r, r_len) != 0)
|
||||
goto cleanup;
|
||||
|
||||
if(mbedtls_mpi_read_binary(&ps, s, s_len) != 0)
|
||||
goto cleanup;
|
||||
|
||||
switch(_libssh2_ecdsa_get_curve_type(ctx)) {
|
||||
case LIBSSH2_EC_CURVE_NISTP256:
|
||||
LIBSSH2_MBEDTLS_ECDSA_VERIFY(256);
|
||||
break;
|
||||
case LIBSSH2_EC_CURVE_NISTP384:
|
||||
LIBSSH2_MBEDTLS_ECDSA_VERIFY(384);
|
||||
break;
|
||||
case LIBSSH2_EC_CURVE_NISTP521:
|
||||
LIBSSH2_MBEDTLS_ECDSA_VERIFY(512);
|
||||
break;
|
||||
default:
|
||||
rc = -1;
|
||||
}
|
||||
|
||||
cleanup:
|
||||
|
||||
mbedtls_mpi_free(&pr);
|
||||
mbedtls_mpi_free(&ps);
|
||||
|
||||
return (rc == 0) ? 0 : -1;
|
||||
}
|
||||
|
||||
static int
|
||||
_libssh2_mbedtls_parse_eckey(libssh2_ecdsa_ctx **ctx,
|
||||
mbedtls_pk_context *pkey,
|
||||
LIBSSH2_SESSION *session,
|
||||
const unsigned char *data,
|
||||
size_t data_len,
|
||||
const unsigned char *pwd)
|
||||
{
|
||||
size_t pwd_len;
|
||||
|
||||
pwd_len = pwd ? strlen((const char *) pwd) : 0;
|
||||
|
||||
if(mbedtls_pk_parse_key(pkey, data, data_len, pwd, pwd_len) != 0)
|
||||
goto failed;
|
||||
|
||||
if(mbedtls_pk_get_type(pkey) != MBEDTLS_PK_ECKEY)
|
||||
goto failed;
|
||||
|
||||
*ctx = LIBSSH2_ALLOC(session, sizeof(libssh2_ecdsa_ctx));
|
||||
|
||||
if(*ctx == NULL)
|
||||
goto failed;
|
||||
|
||||
mbedtls_ecdsa_init(*ctx);
|
||||
|
||||
if(mbedtls_ecdsa_from_keypair(*ctx, mbedtls_pk_ec(*pkey)) == 0)
|
||||
return 0;
|
||||
|
||||
failed:
|
||||
|
||||
_libssh2_mbedtls_ecdsa_free(*ctx);
|
||||
*ctx = NULL;
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
static int
|
||||
_libssh2_mbedtls_parse_openssh_key(libssh2_ecdsa_ctx **ctx,
|
||||
LIBSSH2_SESSION *session,
|
||||
const unsigned char *data,
|
||||
size_t data_len,
|
||||
const unsigned char *pwd)
|
||||
{
|
||||
libssh2_curve_type type;
|
||||
unsigned char *name = NULL;
|
||||
struct string_buf *decrypted = NULL;
|
||||
size_t curvelen, exponentlen, pointlen;
|
||||
unsigned char *curve, *exponent, *point_buf;
|
||||
|
||||
if(_libssh2_openssh_pem_parse_memory(session, pwd,
|
||||
(const char *)data, data_len,
|
||||
&decrypted) != 0)
|
||||
goto failed;
|
||||
|
||||
if(_libssh2_get_string(decrypted, &name, NULL) != 0)
|
||||
goto failed;
|
||||
|
||||
if(_libssh2_mbedtls_ecdsa_curve_type_from_name((const char *)name,
|
||||
&type) != 0)
|
||||
goto failed;
|
||||
|
||||
if(_libssh2_get_string(decrypted, &curve, &curvelen) != 0)
|
||||
goto failed;
|
||||
|
||||
if(_libssh2_get_string(decrypted, &point_buf, &pointlen) != 0)
|
||||
goto failed;
|
||||
|
||||
if(_libssh2_get_bignum_bytes(decrypted, &exponent, &exponentlen) != 0)
|
||||
goto failed;
|
||||
|
||||
*ctx = LIBSSH2_ALLOC(session, sizeof(libssh2_ecdsa_ctx));
|
||||
|
||||
if(*ctx == NULL)
|
||||
goto failed;
|
||||
|
||||
mbedtls_ecdsa_init(*ctx);
|
||||
|
||||
if(mbedtls_ecp_group_load(&(*ctx)->grp, (mbedtls_ecp_group_id)type) != 0)
|
||||
goto failed;
|
||||
|
||||
if(mbedtls_mpi_read_binary(&(*ctx)->d, exponent, exponentlen) != 0)
|
||||
goto failed;
|
||||
|
||||
if(mbedtls_ecp_mul(&(*ctx)->grp, &(*ctx)->Q,
|
||||
&(*ctx)->d, &(*ctx)->grp.G,
|
||||
mbedtls_ctr_drbg_random,
|
||||
&_libssh2_mbedtls_ctr_drbg) != 0)
|
||||
goto failed;
|
||||
|
||||
if(mbedtls_ecp_check_privkey(&(*ctx)->grp, &(*ctx)->d) == 0)
|
||||
goto cleanup;
|
||||
|
||||
failed:
|
||||
|
||||
_libssh2_mbedtls_ecdsa_free(*ctx);
|
||||
*ctx = NULL;
|
||||
|
||||
cleanup:
|
||||
|
||||
if(decrypted) {
|
||||
_libssh2_string_buf_free(session, decrypted);
|
||||
}
|
||||
|
||||
return (*ctx == NULL) ? -1 : 0;
|
||||
}
|
||||
|
||||
/* _libssh2_ecdsa_new_private
|
||||
*
|
||||
* Creates a new private key given a file path and password
|
||||
*
|
||||
*/
|
||||
|
||||
int
|
||||
_libssh2_mbedtls_ecdsa_new_private(libssh2_ecdsa_ctx **ctx,
|
||||
LIBSSH2_SESSION *session,
|
||||
const char *filename,
|
||||
const unsigned char *pwd)
|
||||
{
|
||||
mbedtls_pk_context pkey;
|
||||
unsigned char *data;
|
||||
size_t data_len;
|
||||
|
||||
if(mbedtls_pk_load_file(filename, &data, &data_len) != 0)
|
||||
goto cleanup;
|
||||
|
||||
mbedtls_pk_init(&pkey);
|
||||
|
||||
if(_libssh2_mbedtls_parse_eckey(ctx, &pkey, session,
|
||||
data, data_len, pwd) == 0)
|
||||
goto cleanup;
|
||||
|
||||
_libssh2_mbedtls_parse_openssh_key(ctx, session, data, data_len, pwd);
|
||||
|
||||
cleanup:
|
||||
|
||||
mbedtls_pk_free(&pkey);
|
||||
|
||||
_libssh2_mbedtls_safe_free(data, data_len);
|
||||
|
||||
return (*ctx == NULL) ? -1 : 0;
|
||||
}
|
||||
|
||||
/* _libssh2_ecdsa_new_private
|
||||
*
|
||||
* Creates a new private key given a file data and password
|
||||
*
|
||||
*/
|
||||
|
||||
int
|
||||
_libssh2_mbedtls_ecdsa_new_private_frommemory(libssh2_ecdsa_ctx **ctx,
|
||||
LIBSSH2_SESSION *session,
|
||||
const char *data,
|
||||
size_t data_len,
|
||||
const unsigned char *pwd)
|
||||
{
|
||||
unsigned char *ntdata;
|
||||
mbedtls_pk_context pkey;
|
||||
|
||||
mbedtls_pk_init(&pkey);
|
||||
|
||||
ntdata = LIBSSH2_ALLOC(session, data_len + 1);
|
||||
|
||||
if(ntdata == NULL)
|
||||
goto cleanup;
|
||||
|
||||
memcpy(ntdata, data, data_len);
|
||||
|
||||
if(_libssh2_mbedtls_parse_eckey(ctx, &pkey, session,
|
||||
ntdata, data_len + 1, pwd) == 0)
|
||||
goto cleanup;
|
||||
|
||||
_libssh2_mbedtls_parse_openssh_key(ctx, session,
|
||||
ntdata, data_len + 1, pwd);
|
||||
|
||||
cleanup:
|
||||
|
||||
mbedtls_pk_free(&pkey);
|
||||
|
||||
_libssh2_mbedtls_safe_free(ntdata, data_len);
|
||||
|
||||
return (*ctx == NULL) ? -1 : 0;
|
||||
}
|
||||
|
||||
static unsigned char *
|
||||
_libssh2_mbedtls_mpi_write_binary(unsigned char *buf,
|
||||
const mbedtls_mpi *mpi,
|
||||
size_t bytes)
|
||||
{
|
||||
unsigned char *p = buf;
|
||||
|
||||
if(sizeof(&p) / sizeof(p[0]) < 4) {
|
||||
goto done;
|
||||
}
|
||||
|
||||
p += 4;
|
||||
*p = 0;
|
||||
|
||||
if(bytes > 0) {
|
||||
mbedtls_mpi_write_binary(mpi, p + 1, bytes - 1);
|
||||
}
|
||||
|
||||
if(bytes > 0 && !(*(p + 1) & 0x80)) {
|
||||
memmove(p, p + 1, --bytes);
|
||||
}
|
||||
|
||||
_libssh2_htonu32(p - 4, bytes);
|
||||
|
||||
done:
|
||||
|
||||
return p + bytes;
|
||||
}
|
||||
|
||||
/* _libssh2_ecdsa_sign
|
||||
*
|
||||
* Computes the ECDSA signature of a previously-hashed message
|
||||
*
|
||||
*/
|
||||
|
||||
int
|
||||
_libssh2_mbedtls_ecdsa_sign(LIBSSH2_SESSION *session,
|
||||
libssh2_ecdsa_ctx *ctx,
|
||||
const unsigned char *hash,
|
||||
unsigned long hash_len,
|
||||
unsigned char **sign,
|
||||
size_t *sign_len)
|
||||
{
|
||||
size_t r_len, s_len, tmp_sign_len = 0;
|
||||
unsigned char *sp, *tmp_sign = NULL;
|
||||
mbedtls_mpi pr, ps;
|
||||
|
||||
mbedtls_mpi_init(&pr);
|
||||
mbedtls_mpi_init(&ps);
|
||||
|
||||
if(mbedtls_ecdsa_sign(&ctx->grp, &pr, &ps, &ctx->d,
|
||||
hash, hash_len,
|
||||
mbedtls_ctr_drbg_random,
|
||||
&_libssh2_mbedtls_ctr_drbg) != 0)
|
||||
goto cleanup;
|
||||
|
||||
r_len = mbedtls_mpi_size(&pr) + 1;
|
||||
s_len = mbedtls_mpi_size(&ps) + 1;
|
||||
tmp_sign_len = r_len + s_len + 8;
|
||||
|
||||
tmp_sign = LIBSSH2_CALLOC(session, tmp_sign_len);
|
||||
|
||||
if(tmp_sign == NULL)
|
||||
goto cleanup;
|
||||
|
||||
sp = tmp_sign;
|
||||
sp = _libssh2_mbedtls_mpi_write_binary(sp, &pr, r_len);
|
||||
sp = _libssh2_mbedtls_mpi_write_binary(sp, &ps, s_len);
|
||||
|
||||
*sign_len = (size_t)(sp - tmp_sign);
|
||||
|
||||
*sign = LIBSSH2_CALLOC(session, *sign_len);
|
||||
|
||||
if(*sign == NULL)
|
||||
goto cleanup;
|
||||
|
||||
memcpy(*sign, tmp_sign, *sign_len);
|
||||
|
||||
cleanup:
|
||||
|
||||
mbedtls_mpi_free(&pr);
|
||||
mbedtls_mpi_free(&ps);
|
||||
|
||||
_libssh2_mbedtls_safe_free(tmp_sign, tmp_sign_len);
|
||||
|
||||
return (*sign == NULL) ? -1 : 0;
|
||||
}
|
||||
|
||||
/* _libssh2_ecdsa_get_curve_type
|
||||
*
|
||||
* returns key curve type that maps to libssh2_curve_type
|
||||
*
|
||||
*/
|
||||
|
||||
libssh2_curve_type
|
||||
_libssh2_mbedtls_ecdsa_get_curve_type(libssh2_ecdsa_ctx *ctx)
|
||||
{
|
||||
return (libssh2_curve_type) ctx->grp.id;
|
||||
}
|
||||
|
||||
/* _libssh2_ecdsa_curve_type_from_name
|
||||
*
|
||||
* returns 0 for success, key curve type that maps to libssh2_curve_type
|
||||
*
|
||||
*/
|
||||
|
||||
int
|
||||
_libssh2_mbedtls_ecdsa_curve_type_from_name(const char *name,
|
||||
libssh2_curve_type *out_type)
|
||||
{
|
||||
int ret = 0;
|
||||
libssh2_curve_type type;
|
||||
|
||||
if(name == NULL || strlen(name) != 19)
|
||||
return -1;
|
||||
|
||||
if(strcmp(name, "ecdsa-sha2-nistp256") == 0)
|
||||
type = LIBSSH2_EC_CURVE_NISTP256;
|
||||
else if(strcmp(name, "ecdsa-sha2-nistp384") == 0)
|
||||
type = LIBSSH2_EC_CURVE_NISTP384;
|
||||
else if(strcmp(name, "ecdsa-sha2-nistp521") == 0)
|
||||
type = LIBSSH2_EC_CURVE_NISTP521;
|
||||
else {
|
||||
ret = -1;
|
||||
}
|
||||
|
||||
if(ret == 0 && out_type) {
|
||||
*out_type = type;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
void
|
||||
_libssh2_mbedtls_ecdsa_free(libssh2_ecdsa_ctx *ctx)
|
||||
{
|
||||
mbedtls_ecdsa_free(ctx);
|
||||
mbedtls_free(ctx);
|
||||
}
|
||||
|
||||
#endif /* LIBSSH2_ECDSA */
|
||||
#endif /* LIBSSH2_MBEDTLS */
|
||||
|
||||
153
src/mbedtls.h
153
src/mbedtls.h
@@ -1,3 +1,5 @@
|
||||
#ifndef __LIBSSH2_MBEDTLS_H
|
||||
#define __LIBSSH2_MBEDTLS_H
|
||||
/* Copyright (c) 2016, Art <https://github.com/wildart>
|
||||
* All rights reserved.
|
||||
*
|
||||
@@ -43,6 +45,12 @@
|
||||
#include <mbedtls/rsa.h>
|
||||
#include <mbedtls/bignum.h>
|
||||
#include <mbedtls/cipher.h>
|
||||
#ifdef MBEDTLS_ECDH_C
|
||||
# include <mbedtls/ecdh.h>
|
||||
#endif
|
||||
#ifdef MBEDTLS_ECDSA_C
|
||||
# include <mbedtls/ecdsa.h>
|
||||
#endif
|
||||
#include <mbedtls/entropy.h>
|
||||
#include <mbedtls/ctr_drbg.h>
|
||||
#include <mbedtls/pk.h>
|
||||
@@ -64,7 +72,11 @@
|
||||
|
||||
#define LIBSSH2_RSA 1
|
||||
#define LIBSSH2_DSA 0
|
||||
#define LIBSSH2_ECDSA 0
|
||||
#ifdef MBEDTLS_ECDSA_C
|
||||
# define LIBSSH2_ECDSA 1
|
||||
#else
|
||||
# define LIBSSH2_ECDSA 0
|
||||
#endif
|
||||
#define LIBSSH2_ED25519 0
|
||||
|
||||
#define MD5_DIGEST_LENGTH 16
|
||||
@@ -75,10 +87,6 @@
|
||||
|
||||
#define EC_MAX_POINT_LEN ((528 * 2 / 8) + 1)
|
||||
|
||||
#if LIBSSH2_ECDSA
|
||||
#else
|
||||
#define _libssh2_ec_key void
|
||||
#endif
|
||||
|
||||
/*******************************************************************/
|
||||
/*
|
||||
@@ -208,9 +216,10 @@
|
||||
#define libssh2_md5(data, datalen, hash) \
|
||||
_libssh2_mbedtls_hash(data, datalen, MBEDTLS_MD_MD5, hash)
|
||||
|
||||
|
||||
/*******************************************************************/
|
||||
/*
|
||||
* mbedTLS backend: RSA structure
|
||||
* mbedTLS backend: RSA functions
|
||||
*/
|
||||
|
||||
#define libssh2_rsa_ctx mbedtls_rsa_context
|
||||
@@ -239,6 +248,82 @@
|
||||
#define _libssh2_rsa_free(rsactx) \
|
||||
_libssh2_mbedtls_rsa_free(rsactx)
|
||||
|
||||
|
||||
/*******************************************************************/
|
||||
/*
|
||||
* mbedTLS backend: ECDSA structures
|
||||
*/
|
||||
|
||||
#if LIBSSH2_ECDSA
|
||||
|
||||
typedef enum {
|
||||
#ifdef MBEDTLS_ECP_DP_SECP256R1_ENABLED
|
||||
LIBSSH2_EC_CURVE_NISTP256 = MBEDTLS_ECP_DP_SECP256R1,
|
||||
#else
|
||||
LIBSSH2_EC_CURVE_NISTP256 = MBEDTLS_ECP_DP_NONE,
|
||||
#endif
|
||||
#ifdef MBEDTLS_ECP_DP_SECP384R1_ENABLED
|
||||
LIBSSH2_EC_CURVE_NISTP384 = MBEDTLS_ECP_DP_SECP384R1,
|
||||
#else
|
||||
LIBSSH2_EC_CURVE_NISTP384 = MBEDTLS_ECP_DP_NONE,
|
||||
#endif
|
||||
#ifdef MBEDTLS_ECP_DP_SECP521R1_ENABLED
|
||||
LIBSSH2_EC_CURVE_NISTP521 = MBEDTLS_ECP_DP_SECP521R1
|
||||
#else
|
||||
LIBSSH2_EC_CURVE_NISTP521 = MBEDTLS_ECP_DP_NONE,
|
||||
#endif
|
||||
} libssh2_curve_type;
|
||||
|
||||
# define _libssh2_ec_key mbedtls_ecp_keypair
|
||||
#else
|
||||
# define _libssh2_ec_key void
|
||||
#endif /* LIBSSH2_ECDSA */
|
||||
|
||||
|
||||
/*******************************************************************/
|
||||
/*
|
||||
* mbedTLS backend: ECDSA functions
|
||||
*/
|
||||
|
||||
#if LIBSSH2_ECDSA
|
||||
|
||||
#define libssh2_ecdsa_ctx mbedtls_ecdsa_context
|
||||
|
||||
#define _libssh2_ecdsa_create_key(session, privkey, pubkey_octal, \
|
||||
pubkey_octal_len, curve) \
|
||||
_libssh2_mbedtls_ecdsa_create_key(session, privkey, pubkey_octal, \
|
||||
pubkey_octal_len, curve)
|
||||
|
||||
#define _libssh2_ecdsa_curve_name_with_octal_new(ctx, k, k_len, curve) \
|
||||
_libssh2_mbedtls_ecdsa_curve_name_with_octal_new(ctx, k, k_len, curve)
|
||||
|
||||
#define _libssh2_ecdh_gen_k(k, privkey, server_pubkey, server_pubkey_len) \
|
||||
_libssh2_mbedtls_ecdh_gen_k(k, privkey, server_pubkey, server_pubkey_len)
|
||||
|
||||
#define _libssh2_ecdsa_verify(ctx, r, r_len, s, s_len, m, m_len) \
|
||||
_libssh2_mbedtls_ecdsa_verify(ctx, r, r_len, s, s_len, m, m_len)
|
||||
|
||||
#define _libssh2_ecdsa_new_private(ctx, session, filename, passphrase) \
|
||||
_libssh2_mbedtls_ecdsa_new_private(ctx, session, filename, passphrase)
|
||||
|
||||
#define _libssh2_ecdsa_new_private_frommemory(ctx, session, filedata, \
|
||||
filedata_len, passphrase) \
|
||||
_libssh2_mbedtls_ecdsa_new_private_frommemory(ctx, session, filedata, \
|
||||
filedata_len, passphrase)
|
||||
|
||||
#define _libssh2_ecdsa_sign(session, ctx, hash, hash_len, sign, sign_len) \
|
||||
_libssh2_mbedtls_ecdsa_sign(session, ctx, hash, hash_len, sign, sign_len)
|
||||
|
||||
#define _libssh2_ecdsa_get_curve_type(ctx) \
|
||||
_libssh2_mbedtls_ecdsa_get_curve_type(ctx)
|
||||
|
||||
#define _libssh2_ecdsa_free(ctx) \
|
||||
_libssh2_mbedtls_ecdsa_free(ctx)
|
||||
|
||||
#endif /* LIBSSH2_ECDSA */
|
||||
|
||||
|
||||
/*******************************************************************/
|
||||
/*
|
||||
* mbedTLS backend: Key functions
|
||||
*/
|
||||
@@ -251,10 +336,11 @@
|
||||
pk, pk_len, pw)
|
||||
|
||||
|
||||
/*******************************************************************/
|
||||
/*******************************************************************/
|
||||
/*
|
||||
* mbedTLS backend: Cipher Context structure
|
||||
*/
|
||||
|
||||
#define _libssh2_cipher_ctx mbedtls_cipher_context_t
|
||||
|
||||
#define _libssh2_cipher_type(algo) mbedtls_cipher_type_t algo
|
||||
@@ -270,6 +356,8 @@
|
||||
#define _libssh2_cipher_cast5 MBEDTLS_CIPHER_NULL
|
||||
#define _libssh2_cipher_3des MBEDTLS_CIPHER_DES_EDE3_CBC
|
||||
|
||||
|
||||
/*******************************************************************/
|
||||
/*
|
||||
* mbedTLS backend: Cipher functions
|
||||
*/
|
||||
@@ -329,6 +417,7 @@
|
||||
/*
|
||||
* mbedTLS backend: forward declarations
|
||||
*/
|
||||
|
||||
void
|
||||
_libssh2_mbedtls_init(void);
|
||||
|
||||
@@ -434,6 +523,54 @@ _libssh2_mbedtls_pub_priv_keyfilememory(LIBSSH2_SESSION *session,
|
||||
const char *privatekeydata,
|
||||
size_t privatekeydata_len,
|
||||
const char *passphrase);
|
||||
#if LIBSSH2_ECDSA
|
||||
int
|
||||
_libssh2_mbedtls_ecdsa_create_key(LIBSSH2_SESSION *session,
|
||||
_libssh2_ec_key **privkey,
|
||||
unsigned char **pubkey_octal,
|
||||
size_t *pubkey_octal_len,
|
||||
libssh2_curve_type curve);
|
||||
int
|
||||
_libssh2_mbedtls_ecdsa_curve_name_with_octal_new(libssh2_ecdsa_ctx **ctx,
|
||||
const unsigned char *k,
|
||||
size_t k_len,
|
||||
libssh2_curve_type curve);
|
||||
int
|
||||
_libssh2_mbedtls_ecdh_gen_k(_libssh2_bn **k,
|
||||
_libssh2_ec_key *privkey,
|
||||
const unsigned char *server_pubkey,
|
||||
size_t server_pubkey_len);
|
||||
int
|
||||
_libssh2_mbedtls_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_mbedtls_ecdsa_new_private(libssh2_ecdsa_ctx **ctx,
|
||||
LIBSSH2_SESSION *session,
|
||||
const char *filename,
|
||||
const unsigned char *passphrase);
|
||||
int
|
||||
_libssh2_mbedtls_ecdsa_new_private_frommemory(libssh2_ecdsa_ctx **ctx,
|
||||
LIBSSH2_SESSION *session,
|
||||
const char *filedata,
|
||||
size_t filedata_len,
|
||||
const unsigned char *passphrase);
|
||||
int
|
||||
_libssh2_mbedtls_ecdsa_sign(LIBSSH2_SESSION *session,
|
||||
libssh2_ecdsa_ctx *ctx,
|
||||
const unsigned char *hash,
|
||||
unsigned long hash_len,
|
||||
unsigned char **signature,
|
||||
size_t *signature_len);
|
||||
libssh2_curve_type
|
||||
_libssh2_mbedtls_ecdsa_key_get_curve_type(libssh2_ecdsa_ctx *ctx);
|
||||
int
|
||||
_libssh2_mbedtls_ecdsa_curve_type_from_name(const char *name,
|
||||
libssh2_curve_type *type);
|
||||
void
|
||||
_libssh2_mbedtls_ecdsa_free(libssh2_ecdsa_ctx *ctx);
|
||||
#endif /* LIBSSH2_ECDSA */
|
||||
|
||||
extern void
|
||||
_libssh2_dh_init(_libssh2_dh_ctx *dhctx);
|
||||
@@ -445,3 +582,5 @@ _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);
|
||||
|
||||
#endif /* __LIBSSH2_MBEDTLS_H */
|
||||
|
||||
32
src/misc.c
32
src/misc.c
@@ -141,19 +141,16 @@ _libssh2_recv(libssh2_socket_t sock, void *buffer, size_t length,
|
||||
#ifdef WIN32
|
||||
if(rc < 0)
|
||||
return -wsa2errno();
|
||||
#elif defined(__VMS)
|
||||
if(rc < 0) {
|
||||
if(errno == EWOULDBLOCK)
|
||||
return -EAGAIN;
|
||||
else
|
||||
return -errno;
|
||||
}
|
||||
#else
|
||||
if(rc < 0) {
|
||||
/* Sometimes the first recv() function call sets errno to ENOENT on
|
||||
Solaris and HP-UX */
|
||||
if(errno == ENOENT)
|
||||
return -EAGAIN;
|
||||
#ifdef EWOULDBLOCK /* For VMS and other special unixes */
|
||||
else if(errno == EWOULDBLOCK)
|
||||
return -EAGAIN;
|
||||
#endif
|
||||
else
|
||||
return -errno;
|
||||
}
|
||||
@@ -177,16 +174,14 @@ _libssh2_send(libssh2_socket_t sock, const void *buffer, size_t length,
|
||||
#ifdef WIN32
|
||||
if(rc < 0)
|
||||
return -wsa2errno();
|
||||
#elif defined(__VMS)
|
||||
if(rc < 0) {
|
||||
if(errno == EWOULDBLOCK)
|
||||
return -EAGAIN;
|
||||
else
|
||||
return -errno;
|
||||
}
|
||||
#else
|
||||
if(rc < 0)
|
||||
return -errno;
|
||||
if(rc < 0) {
|
||||
#ifdef EWOULDBLOCK /* For VMS and other special unixes */
|
||||
if(errno == EWOULDBLOCK)
|
||||
return -EAGAIN;
|
||||
#endif
|
||||
return -errno;
|
||||
}
|
||||
#endif
|
||||
return rc;
|
||||
}
|
||||
@@ -196,7 +191,10 @@ _libssh2_send(libssh2_socket_t sock, const void *buffer, size_t length,
|
||||
unsigned int
|
||||
_libssh2_ntohu32(const unsigned char *buf)
|
||||
{
|
||||
return (buf[0] << 24) | (buf[1] << 16) | (buf[2] << 8) | buf[3];
|
||||
return (((unsigned int)buf[0] << 24)
|
||||
| ((unsigned int)buf[1] << 16)
|
||||
| ((unsigned int)buf[2] << 8)
|
||||
| ((unsigned int)buf[3]));
|
||||
}
|
||||
|
||||
|
||||
|
||||
420
src/openssl.c
420
src/openssl.c
@@ -259,16 +259,16 @@ _libssh2_dsa_sha1_verify(libssh2_dsa_ctx * dsactx,
|
||||
|
||||
#if LIBSSH2_ECDSA
|
||||
|
||||
/* _libssh2_ecdsa_key_get_curve_type
|
||||
/* _libssh2_ecdsa_get_curve_type
|
||||
*
|
||||
* returns key curve type that maps to libssh2_curve_type
|
||||
*
|
||||
*/
|
||||
|
||||
libssh2_curve_type
|
||||
_libssh2_ecdsa_key_get_curve_type(_libssh2_ec_key *key)
|
||||
_libssh2_ecdsa_get_curve_type(libssh2_ecdsa_ctx *ec_ctx)
|
||||
{
|
||||
const EC_GROUP *group = EC_KEY_get0_group(key);
|
||||
const EC_GROUP *group = EC_KEY_get0_group(ec_ctx);
|
||||
return EC_GROUP_get_curve_name(group);
|
||||
}
|
||||
|
||||
@@ -355,7 +355,7 @@ _libssh2_ecdsa_verify(libssh2_ecdsa_ctx * ctx,
|
||||
{
|
||||
int ret = 0;
|
||||
EC_KEY *ec_key = (EC_KEY*)ctx;
|
||||
libssh2_curve_type type = _libssh2_ecdsa_key_get_curve_type(ec_key);
|
||||
libssh2_curve_type type = _libssh2_ecdsa_get_curve_type(ec_key);
|
||||
|
||||
#ifdef HAVE_OPAQUE_STRUCTS
|
||||
ECDSA_SIG *ecdsa_sig = ECDSA_SIG_new();
|
||||
@@ -427,10 +427,19 @@ _libssh2_cipher_crypt(_libssh2_cipher_ctx * ctx,
|
||||
#else
|
||||
ret = EVP_Cipher(ctx, buf, block, blocksize);
|
||||
#endif
|
||||
#if defined(OPENSSL_VERSION_MAJOR) && OPENSSL_VERSION_MAJOR >= 3
|
||||
if(ret != -1) {
|
||||
#else
|
||||
if(ret == 1) {
|
||||
#endif
|
||||
memcpy(block, buf, blocksize);
|
||||
}
|
||||
|
||||
#if defined(OPENSSL_VERSION_MAJOR) && OPENSSL_VERSION_MAJOR >= 3
|
||||
return ret != -1 ? 0 : 1;
|
||||
#else
|
||||
return ret == 1 ? 0 : 1;
|
||||
#endif
|
||||
}
|
||||
|
||||
#if LIBSSH2_AES_CTR && !defined(HAVE_EVP_AES_128_CTR)
|
||||
@@ -445,6 +454,10 @@ typedef struct
|
||||
unsigned char ctr[AES_BLOCK_SIZE];
|
||||
} aes_ctr_ctx;
|
||||
|
||||
static EVP_CIPHER * aes_128_ctr_cipher = NULL;
|
||||
static EVP_CIPHER * aes_192_ctr_cipher = NULL;
|
||||
static EVP_CIPHER * aes_256_ctr_cipher = NULL;
|
||||
|
||||
static int
|
||||
aes_ctr_init(EVP_CIPHER_CTX *ctx, const unsigned char *key,
|
||||
const unsigned char *iv, int enc) /* init key */
|
||||
@@ -589,14 +602,16 @@ const EVP_CIPHER *
|
||||
_libssh2_EVP_aes_128_ctr(void)
|
||||
{
|
||||
#ifdef HAVE_OPAQUE_STRUCTS
|
||||
static EVP_CIPHER * aes_ctr_cipher;
|
||||
return !aes_ctr_cipher ?
|
||||
make_ctr_evp(16, &aes_ctr_cipher, NID_aes_128_ctr) : aes_ctr_cipher;
|
||||
return !aes_128_ctr_cipher ?
|
||||
make_ctr_evp(16, &aes_128_ctr_cipher, NID_aes_128_ctr) :
|
||||
aes_128_ctr_cipher;
|
||||
#else
|
||||
static EVP_CIPHER aes_ctr_cipher;
|
||||
static EVP_CIPHER * aes_ctr_cipher_ptr = &aes_ctr_cipher;
|
||||
return !aes_ctr_cipher.key_len ?
|
||||
make_ctr_evp(16, &aes_ctr_cipher_ptr, 0) : &aes_ctr_cipher;
|
||||
if(!aes_128_ctr_cipher) {
|
||||
aes_128_ctr_cipher = &aes_ctr_cipher;
|
||||
make_ctr_evp(16, &aes_128_ctr_cipher, 0);
|
||||
}
|
||||
return aes_128_ctr_cipher;
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -604,14 +619,16 @@ const EVP_CIPHER *
|
||||
_libssh2_EVP_aes_192_ctr(void)
|
||||
{
|
||||
#ifdef HAVE_OPAQUE_STRUCTS
|
||||
static EVP_CIPHER * aes_ctr_cipher;
|
||||
return !aes_ctr_cipher ?
|
||||
make_ctr_evp(24, &aes_ctr_cipher, NID_aes_192_ctr) : aes_ctr_cipher;
|
||||
return !aes_192_ctr_cipher ?
|
||||
make_ctr_evp(24, &aes_192_ctr_cipher, NID_aes_192_ctr) :
|
||||
aes_192_ctr_cipher;
|
||||
#else
|
||||
static EVP_CIPHER aes_ctr_cipher;
|
||||
static EVP_CIPHER * aes_ctr_cipher_ptr = &aes_ctr_cipher;
|
||||
return !aes_ctr_cipher.key_len ?
|
||||
make_ctr_evp(24, &aes_ctr_cipher_ptr, 0) : &aes_ctr_cipher;
|
||||
if(!aes_192_ctr_cipher) {
|
||||
aes_192_ctr_cipher = &aes_ctr_cipher;
|
||||
make_ctr_evp(24, &aes_192_ctr_cipher, 0);
|
||||
}
|
||||
return aes_192_ctr_cipher;
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -619,24 +636,20 @@ const EVP_CIPHER *
|
||||
_libssh2_EVP_aes_256_ctr(void)
|
||||
{
|
||||
#ifdef HAVE_OPAQUE_STRUCTS
|
||||
static EVP_CIPHER * aes_ctr_cipher;
|
||||
return !aes_ctr_cipher ?
|
||||
make_ctr_evp(32, &aes_ctr_cipher, NID_aes_256_ctr) : aes_ctr_cipher;
|
||||
return !aes_256_ctr_cipher ?
|
||||
make_ctr_evp(32, &aes_256_ctr_cipher, NID_aes_256_ctr) :
|
||||
aes_256_ctr_cipher;
|
||||
#else
|
||||
static EVP_CIPHER aes_ctr_cipher;
|
||||
static EVP_CIPHER * aes_ctr_cipher_ptr = &aes_ctr_cipher;
|
||||
return !aes_ctr_cipher.key_len ?
|
||||
make_ctr_evp(32, &aes_ctr_cipher_ptr, 0) : &aes_ctr_cipher;
|
||||
if(!aes_256_ctr_cipher) {
|
||||
aes_256_ctr_cipher = &aes_ctr_cipher;
|
||||
make_ctr_evp(32, &aes_256_ctr_cipher, 0);
|
||||
}
|
||||
return aes_256_ctr_cipher;
|
||||
#endif
|
||||
}
|
||||
|
||||
#endif /* LIBSSH2_AES_CTR */
|
||||
|
||||
#ifndef HAVE_EVP_AES_128_CTR
|
||||
static EVP_CIPHER * aes_128_ctr_cipher = NULL;
|
||||
static EVP_CIPHER * aes_192_ctr_cipher = NULL;
|
||||
static EVP_CIPHER * aes_256_ctr_cipher = NULL;
|
||||
#endif
|
||||
#endif /* LIBSSH2_AES_CTR && !defined(HAVE_EVP_AES_128_CTR) */
|
||||
|
||||
void _libssh2_openssl_crypto_init(void)
|
||||
{
|
||||
@@ -655,16 +668,16 @@ void _libssh2_openssl_crypto_init(void)
|
||||
ENGINE_register_all_complete();
|
||||
#endif
|
||||
#endif
|
||||
#ifndef HAVE_EVP_AES_128_CTR
|
||||
aes_128_ctr_cipher = (EVP_CIPHER *)_libssh2_EVP_aes_128_ctr();
|
||||
aes_192_ctr_cipher = (EVP_CIPHER *)_libssh2_EVP_aes_192_ctr();
|
||||
aes_256_ctr_cipher = (EVP_CIPHER *)_libssh2_EVP_aes_256_ctr();
|
||||
#if LIBSSH2_AES_CTR && !defined(HAVE_EVP_AES_128_CTR)
|
||||
aes_128_ctr_cipher = (EVP_CIPHER *) _libssh2_EVP_aes_128_ctr();
|
||||
aes_192_ctr_cipher = (EVP_CIPHER *) _libssh2_EVP_aes_192_ctr();
|
||||
aes_256_ctr_cipher = (EVP_CIPHER *) _libssh2_EVP_aes_256_ctr();
|
||||
#endif
|
||||
}
|
||||
|
||||
void _libssh2_openssl_crypto_exit(void)
|
||||
{
|
||||
#ifndef HAVE_EVP_AES_128_CTR
|
||||
#if LIBSSH2_AES_CTR && !defined(HAVE_EVP_AES_128_CTR)
|
||||
#ifdef HAVE_OPAQUE_STRUCTS
|
||||
if(aes_128_ctr_cipher) {
|
||||
EVP_CIPHER_meth_free(aes_128_ctr_cipher);
|
||||
@@ -762,7 +775,6 @@ _libssh2_rsa_new_private_frommemory(libssh2_rsa_ctx ** rsa,
|
||||
|
||||
pem_read_bio_func read_rsa =
|
||||
(pem_read_bio_func) &PEM_read_bio_RSAPrivateKey;
|
||||
(void) session;
|
||||
|
||||
_libssh2_init_if_needed();
|
||||
|
||||
@@ -834,7 +846,7 @@ gen_publickey_from_rsa_evp(LIBSSH2_SESSION *session,
|
||||
|
||||
_libssh2_debug(session,
|
||||
LIBSSH2_TRACE_AUTH,
|
||||
"Computing public key from RSA private key envelop");
|
||||
"Computing public key from RSA private key envelope");
|
||||
|
||||
rsa = EVP_PKEY_get1_RSA(pk);
|
||||
if(rsa == NULL) {
|
||||
@@ -1113,7 +1125,6 @@ _libssh2_rsa_new_private(libssh2_rsa_ctx ** rsa,
|
||||
|
||||
pem_read_bio_func read_rsa =
|
||||
(pem_read_bio_func) &PEM_read_bio_RSAPrivateKey;
|
||||
(void) session;
|
||||
|
||||
_libssh2_init_if_needed();
|
||||
|
||||
@@ -1139,7 +1150,6 @@ _libssh2_dsa_new_private_frommemory(libssh2_dsa_ctx ** dsa,
|
||||
|
||||
pem_read_bio_func read_dsa =
|
||||
(pem_read_bio_func) &PEM_read_bio_DSAPrivateKey;
|
||||
(void) session;
|
||||
|
||||
_libssh2_init_if_needed();
|
||||
|
||||
@@ -1225,7 +1235,7 @@ gen_publickey_from_dsa_evp(LIBSSH2_SESSION *session,
|
||||
|
||||
_libssh2_debug(session,
|
||||
LIBSSH2_TRACE_AUTH,
|
||||
"Computing public key from DSA private key envelop");
|
||||
"Computing public key from DSA private key envelope");
|
||||
|
||||
dsa = EVP_PKEY_get1_DSA(pk);
|
||||
if(dsa == NULL) {
|
||||
@@ -1415,7 +1425,6 @@ _libssh2_dsa_new_private(libssh2_dsa_ctx ** dsa,
|
||||
|
||||
pem_read_bio_func read_dsa =
|
||||
(pem_read_bio_func) &PEM_read_bio_DSAPrivateKey;
|
||||
(void) session;
|
||||
|
||||
_libssh2_init_if_needed();
|
||||
|
||||
@@ -1444,7 +1453,6 @@ _libssh2_ecdsa_new_private_frommemory(libssh2_ecdsa_ctx ** ec_ctx,
|
||||
|
||||
pem_read_bio_func read_ec =
|
||||
(pem_read_bio_func) &PEM_read_bio_ECPrivateKey;
|
||||
(void) session;
|
||||
|
||||
_libssh2_init_if_needed();
|
||||
|
||||
@@ -1466,89 +1474,53 @@ _libssh2_ecdsa_new_private_frommemory(libssh2_ecdsa_ctx ** ec_ctx,
|
||||
#if LIBSSH2_ED25519
|
||||
|
||||
int
|
||||
_libssh2_curve25519_new(LIBSSH2_SESSION *session, libssh2_x25519_ctx **out_ctx,
|
||||
_libssh2_curve25519_new(LIBSSH2_SESSION *session,
|
||||
unsigned char **out_public_key,
|
||||
unsigned char **out_private_key)
|
||||
{
|
||||
EVP_PKEY *key = NULL;
|
||||
EVP_PKEY_CTX *pctx = NULL;
|
||||
PKCS8_PRIV_KEY_INFO *info = NULL;
|
||||
ASN1_OCTET_STRING *oct = NULL;
|
||||
X509_PUBKEY *pubkey = NULL;
|
||||
libssh2_ed25519_ctx *ctx = NULL;
|
||||
const unsigned char *pkcs, *priv, *pub;
|
||||
int privLen, pubLen, pkcsLen;
|
||||
unsigned char *priv = NULL, *pub = NULL;
|
||||
size_t privLen, pubLen;
|
||||
int rc = -1;
|
||||
|
||||
pctx = EVP_PKEY_CTX_new_id(EVP_PKEY_X25519, NULL);
|
||||
if(pctx == NULL)
|
||||
return -1;
|
||||
|
||||
EVP_PKEY_keygen_init(pctx);
|
||||
EVP_PKEY_keygen(pctx, &key);
|
||||
info = EVP_PKEY2PKCS8(key);
|
||||
|
||||
if(info == NULL || !PKCS8_pkey_get0(NULL, &pkcs, &pkcsLen, NULL, info))
|
||||
goto cleanExit;
|
||||
|
||||
oct = d2i_ASN1_OCTET_STRING(NULL, &pkcs, pkcsLen);
|
||||
if(oct == NULL) {
|
||||
if(EVP_PKEY_keygen_init(pctx) != 1 ||
|
||||
EVP_PKEY_keygen(pctx, &key) != 1) {
|
||||
goto cleanExit;
|
||||
}
|
||||
|
||||
priv = ASN1_STRING_get0_data(oct);
|
||||
privLen = ASN1_STRING_length(oct);
|
||||
|
||||
if(privLen != LIBSSH2_ED25519_KEY_LEN)
|
||||
goto cleanExit;
|
||||
|
||||
pubkey = X509_PUBKEY_new();
|
||||
if(pubkey == NULL || !X509_PUBKEY_set(&pubkey, key))
|
||||
goto cleanExit;
|
||||
|
||||
if(!X509_PUBKEY_get0_param(NULL, &pub, &pubLen, NULL, pubkey))
|
||||
goto cleanExit;
|
||||
|
||||
if(pubLen != LIBSSH2_ED25519_KEY_LEN)
|
||||
goto cleanExit;
|
||||
|
||||
if(out_private_key != NULL) {
|
||||
*out_private_key = LIBSSH2_ALLOC(session, LIBSSH2_ED25519_KEY_LEN);
|
||||
if(*out_private_key == NULL)
|
||||
privLen = LIBSSH2_ED25519_KEY_LEN;
|
||||
priv = LIBSSH2_ALLOC(session, privLen);
|
||||
if(priv == NULL)
|
||||
goto cleanExit;
|
||||
|
||||
memcpy(*out_private_key, priv, LIBSSH2_ED25519_KEY_LEN);
|
||||
}
|
||||
|
||||
if(out_public_key != NULL) {
|
||||
*out_public_key = LIBSSH2_ALLOC(session, LIBSSH2_ED25519_KEY_LEN);
|
||||
if(*out_public_key == NULL)
|
||||
goto cleanExit;
|
||||
|
||||
memcpy(*out_public_key, pub, LIBSSH2_ED25519_KEY_LEN);
|
||||
}
|
||||
|
||||
if(out_ctx != NULL) {
|
||||
ctx = malloc(sizeof(libssh2_x25519_ctx));
|
||||
if(ctx == NULL)
|
||||
goto cleanExit;
|
||||
|
||||
ctx->private_key =
|
||||
EVP_PKEY_new_raw_private_key(EVP_PKEY_X25519, NULL,
|
||||
(const unsigned char *)priv,
|
||||
LIBSSH2_ED25519_KEY_LEN);
|
||||
|
||||
ctx->public_key =
|
||||
EVP_PKEY_new_raw_public_key(EVP_PKEY_X25519, NULL,
|
||||
(const unsigned char *)pub,
|
||||
LIBSSH2_ED25519_KEY_LEN);
|
||||
|
||||
if(ctx->public_key == NULL || ctx->private_key == NULL) {
|
||||
_libssh2_x25519_free(ctx);
|
||||
if(EVP_PKEY_get_raw_private_key(key, priv, &privLen) != 1 ||
|
||||
privLen != LIBSSH2_ED25519_KEY_LEN) {
|
||||
goto cleanExit;
|
||||
}
|
||||
|
||||
*out_ctx = ctx;
|
||||
*out_private_key = priv;
|
||||
priv = NULL;
|
||||
}
|
||||
|
||||
if(out_public_key != NULL) {
|
||||
pubLen = LIBSSH2_ED25519_KEY_LEN;
|
||||
pub = LIBSSH2_ALLOC(session, pubLen);
|
||||
if(pub == NULL)
|
||||
goto cleanExit;
|
||||
|
||||
if(EVP_PKEY_get_raw_public_key(key, pub, &pubLen) != 1 ||
|
||||
pubLen != LIBSSH2_ED25519_KEY_LEN) {
|
||||
goto cleanExit;
|
||||
}
|
||||
|
||||
*out_public_key = pub;
|
||||
pub = NULL;
|
||||
}
|
||||
|
||||
/* success */
|
||||
@@ -1556,20 +1528,84 @@ _libssh2_curve25519_new(LIBSSH2_SESSION *session, libssh2_x25519_ctx **out_ctx,
|
||||
|
||||
cleanExit:
|
||||
|
||||
if(info)
|
||||
PKCS8_PRIV_KEY_INFO_free(info);
|
||||
if(pctx)
|
||||
EVP_PKEY_CTX_free(pctx);
|
||||
if(oct)
|
||||
ASN1_OCTET_STRING_free(oct);
|
||||
if(pubkey)
|
||||
X509_PUBKEY_free(pubkey);
|
||||
if(key)
|
||||
EVP_PKEY_free(key);
|
||||
if(priv)
|
||||
LIBSSH2_FREE(session, priv);
|
||||
if(pub)
|
||||
LIBSSH2_FREE(session, pub);
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
|
||||
static int
|
||||
gen_publickey_from_ed_evp(LIBSSH2_SESSION *session,
|
||||
unsigned char **method,
|
||||
size_t *method_len,
|
||||
unsigned char **pubkeydata,
|
||||
size_t *pubkeydata_len,
|
||||
EVP_PKEY *pk)
|
||||
{
|
||||
const char methodName[] = "ssh-ed25519";
|
||||
unsigned char *methodBuf = NULL;
|
||||
size_t rawKeyLen = 0;
|
||||
unsigned char *keyBuf = NULL;
|
||||
size_t bufLen = 0;
|
||||
unsigned char *bufPos = NULL;
|
||||
|
||||
_libssh2_debug(session, LIBSSH2_TRACE_AUTH,
|
||||
"Computing public key from ED private key envelope");
|
||||
|
||||
methodBuf = LIBSSH2_ALLOC(session, sizeof(methodName) - 1);
|
||||
if(!methodBuf) {
|
||||
_libssh2_error(session, LIBSSH2_ERROR_ALLOC,
|
||||
"Unable to allocate memory for private key data");
|
||||
goto fail;
|
||||
}
|
||||
memcpy(methodBuf, methodName, sizeof(methodName) - 1);
|
||||
|
||||
if(EVP_PKEY_get_raw_public_key(pk, NULL, &rawKeyLen) != 1) {
|
||||
_libssh2_error(session, LIBSSH2_ERROR_PROTO,
|
||||
"EVP_PKEY_get_raw_public_key failed");
|
||||
goto fail;
|
||||
}
|
||||
|
||||
/* Key form is: type_len(4) + type(11) + pub_key_len(4) + pub_key(32). */
|
||||
bufLen = 4 + sizeof(methodName) - 1 + 4 + rawKeyLen;
|
||||
bufPos = keyBuf = LIBSSH2_ALLOC(session, bufLen);
|
||||
if(!keyBuf) {
|
||||
_libssh2_error(session, LIBSSH2_ERROR_ALLOC,
|
||||
"Unable to allocate memory for private key data");
|
||||
goto fail;
|
||||
}
|
||||
|
||||
_libssh2_store_str(&bufPos, methodName, sizeof(methodName) - 1);
|
||||
_libssh2_store_u32(&bufPos, rawKeyLen);
|
||||
|
||||
if(EVP_PKEY_get_raw_public_key(pk, bufPos, &rawKeyLen) != 1) {
|
||||
_libssh2_error(session, LIBSSH2_ERROR_PROTO,
|
||||
"EVP_PKEY_get_raw_public_key failed");
|
||||
goto fail;
|
||||
}
|
||||
|
||||
*method = methodBuf;
|
||||
*method_len = sizeof(methodName) - 1;
|
||||
*pubkeydata = keyBuf;
|
||||
*pubkeydata_len = bufLen;
|
||||
return 0;
|
||||
|
||||
fail:
|
||||
if(methodBuf)
|
||||
LIBSSH2_FREE(session, methodBuf);
|
||||
if(keyBuf)
|
||||
LIBSSH2_FREE(session, keyBuf);
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
static int
|
||||
gen_publickey_from_ed25519_openssh_priv_data(LIBSSH2_SESSION *session,
|
||||
struct string_buf *decrypted,
|
||||
@@ -1606,25 +1642,11 @@ gen_publickey_from_ed25519_openssh_priv_data(LIBSSH2_SESSION *session,
|
||||
goto clean_exit;
|
||||
}
|
||||
|
||||
ctx = _libssh2_ed25519_new_ctx();
|
||||
if(ctx == NULL) {
|
||||
_libssh2_error(session, LIBSSH2_ERROR_ALLOC,
|
||||
"Unable to allocate memory for ed25519 key");
|
||||
ret = -1;
|
||||
goto clean_exit;
|
||||
}
|
||||
|
||||
/* first 32 bytes of priv_key is the private key, the last 32 bytes are
|
||||
the public key */
|
||||
ctx->private_key =
|
||||
EVP_PKEY_new_raw_private_key(EVP_PKEY_ED25519, NULL,
|
||||
(const unsigned char *)priv_key,
|
||||
LIBSSH2_ED25519_KEY_LEN);
|
||||
|
||||
ctx->public_key =
|
||||
EVP_PKEY_new_raw_public_key(EVP_PKEY_ED25519, NULL,
|
||||
(const unsigned char *)pub_key,
|
||||
LIBSSH2_ED25519_KEY_LEN);
|
||||
ctx = EVP_PKEY_new_raw_private_key(EVP_PKEY_ED25519, NULL,
|
||||
(const unsigned char *)priv_key,
|
||||
LIBSSH2_ED25519_KEY_LEN);
|
||||
|
||||
/* comment */
|
||||
if(_libssh2_get_string(decrypted, &buf, &tmp_len)) {
|
||||
@@ -1664,10 +1686,12 @@ gen_publickey_from_ed25519_openssh_priv_data(LIBSSH2_SESSION *session,
|
||||
_libssh2_debug(session,
|
||||
LIBSSH2_TRACE_AUTH,
|
||||
"Computing public key from ED25519 "
|
||||
"private key envelop");
|
||||
"private key envelope");
|
||||
|
||||
method_buf = LIBSSH2_ALLOC(session, 11); /* ssh-ed25519. */
|
||||
if(method_buf == NULL) {
|
||||
_libssh2_error(session, LIBSSH2_ERROR_ALLOC,
|
||||
"Unable to allocate memory for ED25519 key");
|
||||
goto clean_exit;
|
||||
}
|
||||
|
||||
@@ -1676,6 +1700,8 @@ gen_publickey_from_ed25519_openssh_priv_data(LIBSSH2_SESSION *session,
|
||||
key_len = LIBSSH2_ED25519_KEY_LEN + 19;
|
||||
key = LIBSSH2_CALLOC(session, key_len);
|
||||
if(key == NULL) {
|
||||
_libssh2_error(session, LIBSSH2_ERROR_ALLOC,
|
||||
"Unable to allocate memory for ED25519 key");
|
||||
goto clean_exit;
|
||||
}
|
||||
|
||||
@@ -1798,6 +1824,24 @@ _libssh2_ed25519_new_private_frommemory(libssh2_ed25519_ctx ** ed_ctx,
|
||||
size_t filedata_len,
|
||||
unsigned const char *passphrase)
|
||||
{
|
||||
libssh2_ed25519_ctx *ctx = NULL;
|
||||
|
||||
_libssh2_init_if_needed();
|
||||
|
||||
if(read_private_key_from_memory((void **)&ctx,
|
||||
(pem_read_bio_func)
|
||||
&PEM_read_bio_PrivateKey,
|
||||
filedata, filedata_len, passphrase) == 0) {
|
||||
if(EVP_PKEY_id(ctx) != EVP_PKEY_ED25519) {
|
||||
_libssh2_ed25519_free(ctx);
|
||||
return _libssh2_error(session, LIBSSH2_ERROR_PROTO,
|
||||
"Private key is not an ED25519 key");
|
||||
}
|
||||
|
||||
*ed_ctx = ctx;
|
||||
return 0;
|
||||
}
|
||||
|
||||
return read_openssh_private_key_from_memory((void **)ed_ctx, session,
|
||||
"ssh-ed25519",
|
||||
filedata, filedata_len,
|
||||
@@ -1811,38 +1855,26 @@ _libssh2_ed25519_new_public(libssh2_ed25519_ctx ** ed_ctx,
|
||||
const uint8_t key_len)
|
||||
{
|
||||
libssh2_ed25519_ctx *ctx = NULL;
|
||||
EVP_PKEY *public_key = NULL;
|
||||
|
||||
if(ed_ctx == NULL)
|
||||
return -1;
|
||||
|
||||
public_key =
|
||||
EVP_PKEY_new_raw_public_key(EVP_PKEY_ED25519, NULL,
|
||||
(const unsigned char *)raw_pub_key,
|
||||
key_len);
|
||||
if(public_key == NULL) {
|
||||
ctx = EVP_PKEY_new_raw_public_key(EVP_PKEY_ED25519, NULL,
|
||||
raw_pub_key, key_len);
|
||||
if(!ctx)
|
||||
return _libssh2_error(session, LIBSSH2_ERROR_PROTO,
|
||||
"could not create ED25519 public key");
|
||||
}
|
||||
|
||||
ctx = _libssh2_ed25519_new_ctx();
|
||||
if(ctx == NULL) {
|
||||
return _libssh2_error(session, LIBSSH2_ERROR_ALLOC,
|
||||
"could not alloc public/private key");
|
||||
}
|
||||
|
||||
ctx->public_key = public_key;
|
||||
|
||||
if(ed_ctx != NULL)
|
||||
*ed_ctx = ctx;
|
||||
else if(ctx != NULL)
|
||||
else if(ctx)
|
||||
_libssh2_ed25519_free(ctx);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
#endif /* LIBSSH2_ED25519 */
|
||||
|
||||
|
||||
int
|
||||
_libssh2_rsa_sha1_sign(LIBSSH2_SESSION * session,
|
||||
libssh2_rsa_ctx * rsactx,
|
||||
@@ -2193,6 +2225,19 @@ _libssh2_sha512(const unsigned char *message, unsigned long len,
|
||||
int
|
||||
_libssh2_md5_init(libssh2_md5_ctx *ctx)
|
||||
{
|
||||
/* MD5 digest is not supported in OpenSSL FIPS mode
|
||||
* Trying to init it will result in a latent OpenSSL error:
|
||||
* "digital envelope routines:FIPS_DIGESTINIT:disabled for fips"
|
||||
* So, just return 0 in FIPS mode
|
||||
*/
|
||||
#if OPENSSL_VERSION_NUMBER >= 0x000907000L && \
|
||||
defined(OPENSSL_VERSION_MAJOR) && \
|
||||
OPENSSL_VERSION_MAJOR < 3 && \
|
||||
!defined(LIBRESSL_VERSION_NUMBER)
|
||||
if(FIPS_mode() != 0)
|
||||
return 0;
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_OPAQUE_STRUCTS
|
||||
*ctx = EVP_MD_CTX_new();
|
||||
|
||||
@@ -2237,7 +2282,7 @@ gen_publickey_from_ec_evp(LIBSSH2_SESSION *session,
|
||||
|
||||
_libssh2_debug(session,
|
||||
LIBSSH2_TRACE_AUTH,
|
||||
"Computing public key from EC private key envelop");
|
||||
"Computing public key from EC private key envelope");
|
||||
|
||||
bn_ctx = BN_CTX_new();
|
||||
if(bn_ctx == NULL)
|
||||
@@ -2251,7 +2296,7 @@ gen_publickey_from_ec_evp(LIBSSH2_SESSION *session,
|
||||
|
||||
public_key = EC_KEY_get0_public_key(ec);
|
||||
group = EC_KEY_get0_group(ec);
|
||||
type = _libssh2_ecdsa_key_get_curve_type(ec);
|
||||
type = _libssh2_ecdsa_get_curve_type(ec);
|
||||
|
||||
method_buf = LIBSSH2_ALLOC(session, 19);
|
||||
if(method_buf == NULL) {
|
||||
@@ -2383,6 +2428,7 @@ gen_publickey_from_ecdsa_openssh_priv_data(LIBSSH2_SESSION *session,
|
||||
|
||||
if((rc = _libssh2_ecdsa_curve_name_with_octal_new(&ec_key, point_buf,
|
||||
pointlen, curve_type)) != 0) {
|
||||
rc = -1;
|
||||
_libssh2_error(session, LIBSSH2_ERROR_PROTO,
|
||||
"ECDSA could not create key");
|
||||
goto fail;
|
||||
@@ -2391,6 +2437,8 @@ gen_publickey_from_ecdsa_openssh_priv_data(LIBSSH2_SESSION *session,
|
||||
bn_exponent = BN_new();
|
||||
if(bn_exponent == NULL) {
|
||||
rc = -1;
|
||||
_libssh2_error(session, LIBSSH2_ERROR_ALLOC,
|
||||
"Unable to allocate memory for private key data");
|
||||
goto fail;
|
||||
}
|
||||
|
||||
@@ -2417,15 +2465,10 @@ gen_publickey_from_ecdsa_openssh_priv_data(LIBSSH2_SESSION *session,
|
||||
return rc;
|
||||
|
||||
fail:
|
||||
|
||||
if(ec_key != NULL)
|
||||
EC_KEY_free(ec_key);
|
||||
|
||||
return _libssh2_error(session,
|
||||
LIBSSH2_ERROR_ALLOC,
|
||||
"Unable to allocate memory for private key data");
|
||||
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
static int
|
||||
@@ -2495,7 +2538,6 @@ _libssh2_ecdsa_new_private(libssh2_ecdsa_ctx ** ec_ctx,
|
||||
int rc;
|
||||
|
||||
pem_read_bio_func read_ec = (pem_read_bio_func) &PEM_read_bio_ECPrivateKey;
|
||||
(void) session;
|
||||
|
||||
_libssh2_init_if_needed();
|
||||
|
||||
@@ -2668,7 +2710,7 @@ _libssh2_ed25519_sign(libssh2_ed25519_ctx *ctx, LIBSSH2_SESSION *session,
|
||||
unsigned char *sig = NULL;
|
||||
|
||||
if(md_ctx != NULL) {
|
||||
if(EVP_DigestSignInit(md_ctx, NULL, NULL, NULL, ctx->private_key) != 1)
|
||||
if(EVP_DigestSignInit(md_ctx, NULL, NULL, NULL, ctx) != 1)
|
||||
goto clean_exit;
|
||||
if(EVP_DigestSign(md_ctx, NULL, &sig_len, message, message_len) != 1)
|
||||
goto clean_exit;
|
||||
@@ -2785,7 +2827,7 @@ _libssh2_ed25519_verify(libssh2_ed25519_ctx *ctx, const uint8_t *s,
|
||||
if(NULL == md_ctx)
|
||||
return -1;
|
||||
|
||||
ret = EVP_DigestVerifyInit(md_ctx, NULL, NULL, NULL, ctx->public_key);
|
||||
ret = EVP_DigestVerifyInit(md_ctx, NULL, NULL, NULL, ctx);
|
||||
if(ret != 1)
|
||||
goto clean_exit;
|
||||
|
||||
@@ -2962,6 +3004,12 @@ _libssh2_pub_priv_keyfile(LIBSSH2_SESSION *session,
|
||||
#endif
|
||||
|
||||
switch(pktype) {
|
||||
#if LIBSSH2_ED25519
|
||||
case EVP_PKEY_ED25519 :
|
||||
st = gen_publickey_from_ed_evp(
|
||||
session, method, method_len, pubkeydata, pubkeydata_len, pk);
|
||||
break;
|
||||
#endif /* LIBSSH2_ED25519 */
|
||||
case EVP_PKEY_RSA :
|
||||
st = gen_publickey_from_rsa_evp(
|
||||
session, method, method_len, pubkeydata, pubkeydata_len, pk);
|
||||
@@ -3013,17 +3061,13 @@ _libssh2_pub_priv_openssh_keyfilememory(LIBSSH2_SESSION *session,
|
||||
if(key_ctx != NULL)
|
||||
*key_ctx = NULL;
|
||||
|
||||
if(session == NULL) {
|
||||
_libssh2_error(session, LIBSSH2_ERROR_PROTO,
|
||||
"Session is required");
|
||||
return -1;
|
||||
}
|
||||
if(session == NULL)
|
||||
return _libssh2_error(session, LIBSSH2_ERROR_PROTO,
|
||||
"Session is required");
|
||||
|
||||
if(key_type != NULL && (strlen(key_type) > 11 || strlen(key_type) < 7)) {
|
||||
_libssh2_error(session, LIBSSH2_ERROR_PROTO,
|
||||
"type is invalid");
|
||||
return -1;
|
||||
}
|
||||
if(key_type != NULL && (strlen(key_type) > 11 || strlen(key_type) < 7))
|
||||
return _libssh2_error(session, LIBSSH2_ERROR_PROTO,
|
||||
"type is invalid");
|
||||
|
||||
_libssh2_init_if_needed();
|
||||
|
||||
@@ -3031,20 +3075,18 @@ _libssh2_pub_priv_openssh_keyfilememory(LIBSSH2_SESSION *session,
|
||||
privatekeydata,
|
||||
privatekeydata_len, &decrypted);
|
||||
|
||||
if(rc) {
|
||||
if(rc)
|
||||
return rc;
|
||||
}
|
||||
|
||||
/* We have a new key file, now try and parse it using supported types */
|
||||
rc = _libssh2_get_string(decrypted, &buf, NULL);
|
||||
|
||||
if(rc != 0 || buf == NULL) {
|
||||
_libssh2_error(session, LIBSSH2_ERROR_PROTO,
|
||||
"Public key type in decrypted key data not found");
|
||||
return -1;
|
||||
}
|
||||
if(rc != 0 || buf == NULL)
|
||||
return _libssh2_error(session, LIBSSH2_ERROR_PROTO,
|
||||
"Public key type in decrypted "
|
||||
"key data not found");
|
||||
|
||||
rc = -1;
|
||||
rc = LIBSSH2_ERROR_FILE;
|
||||
|
||||
#if LIBSSH2_ED25519
|
||||
if(strcmp("ssh-ed25519", (const char *)buf) == 0) {
|
||||
@@ -3098,6 +3140,11 @@ _libssh2_pub_priv_openssh_keyfilememory(LIBSSH2_SESSION *session,
|
||||
}
|
||||
#endif
|
||||
|
||||
if(rc == LIBSSH2_ERROR_FILE)
|
||||
rc = _libssh2_error(session, LIBSSH2_ERROR_FILE,
|
||||
"Unable to extract public key from private key file: "
|
||||
"invalid/unrecognized private key file format");
|
||||
|
||||
if(decrypted)
|
||||
_libssh2_string_buf_free(session, decrypted);
|
||||
|
||||
@@ -3137,10 +3184,10 @@ _libssh2_pub_priv_keyfilememory(LIBSSH2_SESSION *session,
|
||||
"Computing public key from private key.");
|
||||
|
||||
bp = BIO_new_mem_buf((char *)privatekeydata, privatekeydata_len);
|
||||
if(!bp) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
if(!bp)
|
||||
return _libssh2_error(session, LIBSSH2_ERROR_ALLOC,
|
||||
"Unable to allocate memory when"
|
||||
"computing public key");
|
||||
BIO_reset(bp);
|
||||
pk = PEM_read_bio_PrivateKey(bp, NULL, NULL, (void *)passphrase);
|
||||
BIO_free(bp);
|
||||
@@ -3155,15 +3202,8 @@ _libssh2_pub_priv_keyfilememory(LIBSSH2_SESSION *session,
|
||||
privatekeydata,
|
||||
privatekeydata_len,
|
||||
(unsigned const char *)passphrase);
|
||||
if(st != 0) {
|
||||
return _libssh2_error(session,
|
||||
LIBSSH2_ERROR_FILE,
|
||||
"Unable to extract public key "
|
||||
"from private key file: "
|
||||
"Wrong passphrase or invalid/unrecognized "
|
||||
"private key file format");
|
||||
}
|
||||
|
||||
if(st != 0)
|
||||
return st;
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -3174,6 +3214,12 @@ _libssh2_pub_priv_keyfilememory(LIBSSH2_SESSION *session,
|
||||
#endif
|
||||
|
||||
switch(pktype) {
|
||||
#if LIBSSH2_ED25519
|
||||
case EVP_PKEY_ED25519 :
|
||||
st = gen_publickey_from_ed_evp(
|
||||
session, method, method_len, pubkeydata, pubkeydata_len, pk);
|
||||
break;
|
||||
#endif /* LIBSSH2_ED25519 */
|
||||
case EVP_PKEY_RSA :
|
||||
st = gen_publickey_from_rsa_evp(session, method, method_len,
|
||||
pubkeydata, pubkeydata_len, pk);
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
#ifndef __LIBSSH2_OPENSSL_H
|
||||
#define __LIBSSH2_OPENSSL_H
|
||||
/* Copyright (C) 2009, 2010 Simon Josefsson
|
||||
* Copyright (C) 2006, 2007 The Written Word, Inc. All rights reserved.
|
||||
*
|
||||
@@ -135,7 +137,7 @@
|
||||
|
||||
#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)) == 1 ? 0 : -1)
|
||||
|
||||
#define libssh2_prepare_iovec(vec, len) /* Empty. */
|
||||
|
||||
@@ -306,7 +308,7 @@ extern void _libssh2_openssl_crypto_exit(void);
|
||||
|
||||
#define _libssh2_dsa_free(dsactx) DSA_free(dsactx)
|
||||
|
||||
#ifdef LIBSSH2_ECDSA
|
||||
#if LIBSSH2_ECDSA
|
||||
#define libssh2_ecdsa_ctx EC_KEY
|
||||
#define _libssh2_ecdsa_free(ecdsactx) EC_KEY_free(ecdsactx)
|
||||
#define _libssh2_ec_key EC_KEY
|
||||
@@ -321,27 +323,10 @@ libssh2_curve_type;
|
||||
#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)
|
||||
#if LIBSSH2_ED25519
|
||||
#define libssh2_ed25519_ctx EVP_PKEY
|
||||
|
||||
#define _libssh2_ed25519_free(ctx) EVP_PKEY_free(ctx)
|
||||
#endif /* ED25519 */
|
||||
|
||||
#define _libssh2_cipher_type(name) const EVP_CIPHER *(*name)(void)
|
||||
@@ -407,3 +392,5 @@ extern void _libssh2_dh_dtor(_libssh2_dh_ctx *dhctx);
|
||||
const EVP_CIPHER *_libssh2_EVP_aes_128_ctr(void);
|
||||
const EVP_CIPHER *_libssh2_EVP_aes_192_ctr(void);
|
||||
const EVP_CIPHER *_libssh2_EVP_aes_256_ctr(void);
|
||||
|
||||
#endif /* __LIBSSH2_OPENSSL_H */
|
||||
|
||||
196
src/packet.c
196
src/packet.c
@@ -85,30 +85,53 @@ packet_queue_listener(LIBSSH2_SESSION * session, unsigned char *data,
|
||||
char failure_code = SSH_OPEN_ADMINISTRATIVELY_PROHIBITED;
|
||||
int rc;
|
||||
|
||||
(void) datalen;
|
||||
|
||||
if(listen_state->state == libssh2_NB_state_idle) {
|
||||
unsigned char *s = data + (sizeof("forwarded-tcpip") - 1) + 5;
|
||||
listen_state->sender_channel = _libssh2_ntohu32(s);
|
||||
s += 4;
|
||||
unsigned long offset = (sizeof("forwarded-tcpip") - 1) + 5;
|
||||
size_t temp_len = 0;
|
||||
struct string_buf buf;
|
||||
buf.data = data;
|
||||
buf.dataptr = buf.data;
|
||||
buf.len = datalen;
|
||||
|
||||
listen_state->initial_window_size = _libssh2_ntohu32(s);
|
||||
s += 4;
|
||||
listen_state->packet_size = _libssh2_ntohu32(s);
|
||||
s += 4;
|
||||
if(datalen < offset) {
|
||||
return _libssh2_error(session, LIBSSH2_ERROR_OUT_OF_BOUNDARY,
|
||||
"Unexpected packet size");
|
||||
}
|
||||
|
||||
listen_state->host_len = _libssh2_ntohu32(s);
|
||||
s += 4;
|
||||
listen_state->host = s;
|
||||
s += listen_state->host_len;
|
||||
listen_state->port = _libssh2_ntohu32(s);
|
||||
s += 4;
|
||||
buf.dataptr += offset;
|
||||
|
||||
listen_state->shost_len = _libssh2_ntohu32(s);
|
||||
s += 4;
|
||||
listen_state->shost = s;
|
||||
s += listen_state->shost_len;
|
||||
listen_state->sport = _libssh2_ntohu32(s);
|
||||
if(_libssh2_get_u32(&buf, &(listen_state->sender_channel))) {
|
||||
return _libssh2_error(session, LIBSSH2_ERROR_BUFFER_TOO_SMALL,
|
||||
"Data too short extracting channel");
|
||||
}
|
||||
if(_libssh2_get_u32(&buf, &(listen_state->initial_window_size))) {
|
||||
return _libssh2_error(session, LIBSSH2_ERROR_BUFFER_TOO_SMALL,
|
||||
"Data too short extracting window size");
|
||||
}
|
||||
if(_libssh2_get_u32(&buf, &(listen_state->packet_size))) {
|
||||
return _libssh2_error(session, LIBSSH2_ERROR_BUFFER_TOO_SMALL,
|
||||
"Data too short extracting packet");
|
||||
}
|
||||
if(_libssh2_get_string(&buf, &(listen_state->host), &temp_len)) {
|
||||
return _libssh2_error(session, LIBSSH2_ERROR_BUFFER_TOO_SMALL,
|
||||
"Data too short extracting host");
|
||||
}
|
||||
listen_state->host_len = (uint32_t)temp_len;
|
||||
|
||||
if(_libssh2_get_u32(&buf, &(listen_state->port))) {
|
||||
return _libssh2_error(session, LIBSSH2_ERROR_BUFFER_TOO_SMALL,
|
||||
"Data too short extracting port");
|
||||
}
|
||||
if(_libssh2_get_string(&buf, &(listen_state->shost), &temp_len)) {
|
||||
return _libssh2_error(session, LIBSSH2_ERROR_BUFFER_TOO_SMALL,
|
||||
"Data too short extracting shost");
|
||||
}
|
||||
listen_state->shost_len = (uint32_t)temp_len;
|
||||
|
||||
if(_libssh2_get_u32(&buf, &(listen_state->sport))) {
|
||||
return _libssh2_error(session, LIBSSH2_ERROR_BUFFER_TOO_SMALL,
|
||||
"Data too short extracting sport");
|
||||
}
|
||||
|
||||
_libssh2_debug(session, LIBSSH2_TRACE_CONN,
|
||||
"Remote received connection from %s:%ld to %s:%ld",
|
||||
@@ -272,21 +295,56 @@ packet_x11_open(LIBSSH2_SESSION * session, unsigned char *data,
|
||||
LIBSSH2_CHANNEL *channel = x11open_state->channel;
|
||||
int rc;
|
||||
|
||||
(void) datalen;
|
||||
|
||||
if(x11open_state->state == libssh2_NB_state_idle) {
|
||||
unsigned char *s = data + (sizeof("x11") - 1) + 5;
|
||||
x11open_state->sender_channel = _libssh2_ntohu32(s);
|
||||
s += 4;
|
||||
x11open_state->initial_window_size = _libssh2_ntohu32(s);
|
||||
s += 4;
|
||||
x11open_state->packet_size = _libssh2_ntohu32(s);
|
||||
s += 4;
|
||||
x11open_state->shost_len = _libssh2_ntohu32(s);
|
||||
s += 4;
|
||||
x11open_state->shost = s;
|
||||
s += x11open_state->shost_len;
|
||||
x11open_state->sport = _libssh2_ntohu32(s);
|
||||
|
||||
unsigned long offset = (sizeof("x11") - 1) + 5;
|
||||
size_t temp_len = 0;
|
||||
struct string_buf buf;
|
||||
buf.data = data;
|
||||
buf.dataptr = buf.data;
|
||||
buf.len = datalen;
|
||||
|
||||
if(datalen < offset) {
|
||||
_libssh2_error(session, LIBSSH2_ERROR_INVAL,
|
||||
"unexpected data length");
|
||||
failure_code = SSH_OPEN_CONNECT_FAILED;
|
||||
goto x11_exit;
|
||||
}
|
||||
|
||||
buf.dataptr += offset;
|
||||
|
||||
if(_libssh2_get_u32(&buf, &(x11open_state->sender_channel))) {
|
||||
_libssh2_error(session, LIBSSH2_ERROR_INVAL,
|
||||
"unexpected sender channel size");
|
||||
failure_code = SSH_OPEN_CONNECT_FAILED;
|
||||
goto x11_exit;
|
||||
}
|
||||
if(_libssh2_get_u32(&buf, &(x11open_state->initial_window_size))) {
|
||||
_libssh2_error(session, LIBSSH2_ERROR_INVAL,
|
||||
"unexpected window size");
|
||||
failure_code = SSH_OPEN_CONNECT_FAILED;
|
||||
goto x11_exit;
|
||||
}
|
||||
if(_libssh2_get_u32(&buf, &(x11open_state->packet_size))) {
|
||||
_libssh2_error(session, LIBSSH2_ERROR_INVAL,
|
||||
"unexpected window size");
|
||||
failure_code = SSH_OPEN_CONNECT_FAILED;
|
||||
goto x11_exit;
|
||||
}
|
||||
if(_libssh2_get_string(&buf, &(x11open_state->shost), &temp_len)) {
|
||||
_libssh2_error(session, LIBSSH2_ERROR_INVAL,
|
||||
"unexpected host size");
|
||||
failure_code = SSH_OPEN_CONNECT_FAILED;
|
||||
goto x11_exit;
|
||||
}
|
||||
x11open_state->shost_len = (uint32_t)temp_len;
|
||||
|
||||
if(_libssh2_get_u32(&buf, &(x11open_state->sport))) {
|
||||
_libssh2_error(session, LIBSSH2_ERROR_INVAL,
|
||||
"unexpected port size");
|
||||
failure_code = SSH_OPEN_CONNECT_FAILED;
|
||||
goto x11_exit;
|
||||
}
|
||||
|
||||
_libssh2_debug(session, LIBSSH2_TRACE_CONN,
|
||||
"X11 Connection Received from %s:%ld on channel %lu",
|
||||
@@ -419,8 +477,8 @@ _libssh2_packet_add(LIBSSH2_SESSION * session, unsigned char *data,
|
||||
size_t datalen, int macstate)
|
||||
{
|
||||
int rc = 0;
|
||||
char *message = NULL;
|
||||
char *language = NULL;
|
||||
unsigned char *message = NULL;
|
||||
unsigned char *language = NULL;
|
||||
size_t message_len = 0;
|
||||
size_t language_len = 0;
|
||||
LIBSSH2_CHANNEL *channelp = NULL;
|
||||
@@ -472,33 +530,23 @@ _libssh2_packet_add(LIBSSH2_SESSION * session, unsigned char *data,
|
||||
|
||||
case SSH_MSG_DISCONNECT:
|
||||
if(datalen >= 5) {
|
||||
size_t reason = _libssh2_ntohu32(data + 1);
|
||||
uint32_t reason = 0;
|
||||
struct string_buf buf;
|
||||
buf.data = (unsigned char *)data;
|
||||
buf.dataptr = buf.data;
|
||||
buf.len = datalen;
|
||||
buf.dataptr++; /* advance past type */
|
||||
|
||||
if(datalen >= 9) {
|
||||
message_len = _libssh2_ntohu32(data + 5);
|
||||
_libssh2_get_u32(&buf, &reason);
|
||||
_libssh2_get_string(&buf, &message, &message_len);
|
||||
_libssh2_get_string(&buf, &language, &language_len);
|
||||
|
||||
if(message_len < datalen-13) {
|
||||
/* 9 = packet_type(1) + reason(4) + message_len(4) */
|
||||
message = (char *) data + 9;
|
||||
|
||||
language_len =
|
||||
_libssh2_ntohu32(data + 9 + message_len);
|
||||
language = (char *) data + 9 + message_len + 4;
|
||||
|
||||
if(language_len > (datalen-13-message_len)) {
|
||||
/* bad input, clear info */
|
||||
language = message = NULL;
|
||||
language_len = message_len = 0;
|
||||
}
|
||||
}
|
||||
else
|
||||
/* bad size, clear it */
|
||||
message_len = 0;
|
||||
}
|
||||
if(session->ssh_msg_disconnect) {
|
||||
LIBSSH2_DISCONNECT(session, reason, message,
|
||||
message_len, language, language_len);
|
||||
LIBSSH2_DISCONNECT(session, reason, (const char *)message,
|
||||
message_len, (const char *)language,
|
||||
language_len);
|
||||
}
|
||||
|
||||
_libssh2_debug(session, LIBSSH2_TRACE_TRANS,
|
||||
"Disconnect(%d): %s(%s)", reason,
|
||||
message, language);
|
||||
@@ -539,24 +587,24 @@ _libssh2_packet_add(LIBSSH2_SESSION * session, unsigned char *data,
|
||||
int always_display = data[1];
|
||||
|
||||
if(datalen >= 6) {
|
||||
message_len = _libssh2_ntohu32(data + 2);
|
||||
struct string_buf buf;
|
||||
buf.data = (unsigned char *)data;
|
||||
buf.dataptr = buf.data;
|
||||
buf.len = datalen;
|
||||
buf.dataptr += 2; /* advance past type & always display */
|
||||
|
||||
if(message_len <= (datalen - 10)) {
|
||||
/* 6 = packet_type(1) + display(1) + message_len(4) */
|
||||
message = (char *) data + 6;
|
||||
language_len = _libssh2_ntohu32(data + 6 +
|
||||
message_len);
|
||||
|
||||
if(language_len <= (datalen - 10 - message_len))
|
||||
language = (char *) data + 10 + message_len;
|
||||
}
|
||||
_libssh2_get_string(&buf, &message, &message_len);
|
||||
_libssh2_get_string(&buf, &language, &language_len);
|
||||
}
|
||||
|
||||
if(session->ssh_msg_debug) {
|
||||
LIBSSH2_DEBUG(session, always_display, message,
|
||||
message_len, language, language_len);
|
||||
LIBSSH2_DEBUG(session, always_display,
|
||||
(const char *)message,
|
||||
message_len, (const char *)language,
|
||||
language_len);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* _libssh2_debug will actually truncate this for us so
|
||||
* that it's not an inordinate about of data
|
||||
@@ -579,7 +627,7 @@ _libssh2_packet_add(LIBSSH2_SESSION * session, unsigned char *data,
|
||||
uint32_t len = 0;
|
||||
unsigned char want_reply = 0;
|
||||
len = _libssh2_ntohu32(data + 1);
|
||||
if(datalen >= (6 + len)) {
|
||||
if((len <= (UINT_MAX - 6)) && (datalen >= (6 + len))) {
|
||||
want_reply = data[5 + len];
|
||||
_libssh2_debug(session,
|
||||
LIBSSH2_TRACE_CONN,
|
||||
@@ -1275,9 +1323,11 @@ _libssh2_packet_requirev(LIBSSH2_SESSION *session,
|
||||
|
||||
if(strchr((char *) packet_types, ret)) {
|
||||
/* Be lazy, let packet_ask pull it out of the brigade */
|
||||
return _libssh2_packet_askv(session, packet_types, data,
|
||||
int ret = _libssh2_packet_askv(session, packet_types, data,
|
||||
data_len, match_ofs, match_buf,
|
||||
match_len);
|
||||
state->start = 0;
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
#ifndef LIBSSH2_PACKET_H
|
||||
#define LIBSSH2_PACKET_H
|
||||
#ifndef __LIBSSH2_PACKET_H
|
||||
#define __LIBSSH2_PACKET_H
|
||||
/*
|
||||
* Copyright (C) 2010 by Daniel Stenberg
|
||||
* Author: Daniel Stenberg <daniel@haxx.se>
|
||||
@@ -73,4 +73,4 @@ int _libssh2_packet_write(LIBSSH2_SESSION * session, unsigned char *data,
|
||||
int _libssh2_packet_add(LIBSSH2_SESSION * session, unsigned char *data,
|
||||
size_t datalen, int macstate);
|
||||
|
||||
#endif /* LIBSSH2_PACKET_H */
|
||||
#endif /* __LIBSSH2_PACKET_H */
|
||||
|
||||
31
src/pem.c
31
src/pem.c
@@ -176,6 +176,8 @@ _libssh2_pem_parse(LIBSSH2_SESSION * session,
|
||||
linelen = strlen(line);
|
||||
tmp = LIBSSH2_REALLOC(session, b64data, b64datalen + linelen);
|
||||
if(!tmp) {
|
||||
_libssh2_error(session, LIBSSH2_ERROR_ALLOC,
|
||||
"Unable to allocate memory for PEM parsing");
|
||||
ret = -1;
|
||||
goto out;
|
||||
}
|
||||
@@ -319,6 +321,8 @@ _libssh2_pem_parse_memory(LIBSSH2_SESSION * session,
|
||||
linelen = strlen(line);
|
||||
tmp = LIBSSH2_REALLOC(session, b64data, b64datalen + linelen);
|
||||
if(!tmp) {
|
||||
_libssh2_error(session, LIBSSH2_ERROR_ALLOC,
|
||||
"Unable to allocate memory for PEM parsing");
|
||||
ret = -1;
|
||||
goto out;
|
||||
}
|
||||
@@ -690,6 +694,8 @@ _libssh2_openssh_pem_parse(LIBSSH2_SESSION * session,
|
||||
linelen = strlen(line);
|
||||
tmp = LIBSSH2_REALLOC(session, b64data, b64datalen + linelen);
|
||||
if(!tmp) {
|
||||
_libssh2_error(session, LIBSSH2_ERROR_ALLOC,
|
||||
"Unable to allocate memory for PEM parsing");
|
||||
ret = -1;
|
||||
goto out;
|
||||
}
|
||||
@@ -738,17 +744,17 @@ _libssh2_openssh_pem_parse_memory(LIBSSH2_SESSION * session,
|
||||
size_t off = 0;
|
||||
int ret;
|
||||
|
||||
if(filedata == NULL || filedata_len <= 0) {
|
||||
return -1;
|
||||
}
|
||||
if(filedata == NULL || filedata_len <= 0)
|
||||
return _libssh2_error(session, LIBSSH2_ERROR_PROTO,
|
||||
"Error parsing PEM: filedata missing");
|
||||
|
||||
do {
|
||||
|
||||
*line = '\0';
|
||||
|
||||
if(off >= filedata_len) {
|
||||
return -1;
|
||||
}
|
||||
if(off >= filedata_len)
|
||||
return _libssh2_error(session, LIBSSH2_ERROR_PROTO,
|
||||
"Error parsing PEM: offset out of bounds");
|
||||
|
||||
if(readline_memory(line, LINE_SIZE, filedata, filedata_len, &off)) {
|
||||
return -1;
|
||||
@@ -766,7 +772,9 @@ _libssh2_openssh_pem_parse_memory(LIBSSH2_SESSION * session,
|
||||
linelen = strlen(line);
|
||||
tmp = LIBSSH2_REALLOC(session, b64data, b64datalen + linelen);
|
||||
if(!tmp) {
|
||||
ret = -1;
|
||||
ret = _libssh2_error(session, LIBSSH2_ERROR_ALLOC,
|
||||
"Unable to allocate memory for "
|
||||
"PEM parsing");
|
||||
goto out;
|
||||
}
|
||||
memcpy(tmp + b64datalen, line, linelen);
|
||||
@@ -777,7 +785,8 @@ _libssh2_openssh_pem_parse_memory(LIBSSH2_SESSION * session,
|
||||
*line = '\0';
|
||||
|
||||
if(off >= filedata_len) {
|
||||
ret = -1;
|
||||
ret = _libssh2_error(session, LIBSSH2_ERROR_PROTO,
|
||||
"Error parsing PEM: offset out of bounds");
|
||||
goto out;
|
||||
}
|
||||
|
||||
@@ -787,9 +796,9 @@ _libssh2_openssh_pem_parse_memory(LIBSSH2_SESSION * session,
|
||||
}
|
||||
} while(strcmp(line, OPENSSH_HEADER_END) != 0);
|
||||
|
||||
if(!b64data) {
|
||||
return -1;
|
||||
}
|
||||
if(!b64data)
|
||||
return _libssh2_error(session, LIBSSH2_ERROR_PROTO,
|
||||
"Error parsing PEM: base 64 data missing");
|
||||
|
||||
ret = _libssh2_openssh_pem_parse_data(session, passphrase, b64data,
|
||||
b64datalen, decrypted_buf);
|
||||
|
||||
@@ -65,13 +65,13 @@
|
||||
current argument word, add the apostrophe in quotation marks "",
|
||||
and open a new argument word instead (_ indicate the input
|
||||
string characters):
|
||||
_____ _ _
|
||||
_____ _ _
|
||||
'doesn' "'" 't'
|
||||
|
||||
Sequences of apostrophes are combined in one pair of quotation marks:
|
||||
a'''b
|
||||
becomes
|
||||
_ ___ _
|
||||
_ ___ _
|
||||
'a'"'''"'b'
|
||||
|
||||
o If the string contains an exclamation mark (!), the C-Shell
|
||||
@@ -84,7 +84,7 @@
|
||||
a!b
|
||||
|
||||
become
|
||||
_ _ _
|
||||
_ _ _
|
||||
'a'\!'b'
|
||||
|
||||
The result buffer must be large enough for the expanded result. A
|
||||
|
||||
@@ -219,7 +219,7 @@ banner_send(LIBSSH2_SESSION * session)
|
||||
}
|
||||
else {
|
||||
memcpy(banner_dup, banner, 255);
|
||||
banner[255] = '\0';
|
||||
banner_dup[255] = '\0';
|
||||
}
|
||||
|
||||
_libssh2_debug(session, LIBSSH2_TRACE_TRANS, "Sending Banner: %s",
|
||||
@@ -589,7 +589,7 @@ int _libssh2_wait_socket(LIBSSH2_SESSION *session, time_t start_time)
|
||||
session->err_code = LIBSSH2_ERROR_NONE;
|
||||
|
||||
rc = libssh2_keepalive_send(session, &seconds_to_next);
|
||||
if(rc < 0)
|
||||
if(rc)
|
||||
return rc;
|
||||
|
||||
ms_to_next = seconds_to_next * 1000;
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
#ifndef LIBSSH2_SESSION_H
|
||||
#define LIBSSH2_SESSION_H
|
||||
#ifndef __LIBSSH2_SESSION_H
|
||||
#define __LIBSSH2_SESSION_H
|
||||
/* Copyright (c) 2004-2007 Sara Golemon <sarag@libssh2.org>
|
||||
* Copyright (c) 2009-2010 by Daniel Stenberg
|
||||
* Copyright (c) 2010 Simon Josefsson <simon@josefsson.org>
|
||||
@@ -90,4 +90,4 @@ int _libssh2_wait_socket(LIBSSH2_SESSION *session, time_t entry_time);
|
||||
/* this is the lib-internal set blocking function */
|
||||
int _libssh2_session_set_blocking(LIBSSH2_SESSION * session, int blocking);
|
||||
|
||||
#endif /* LIBSSH2_SESSION_H */
|
||||
#endif /* __LIBSSH2_SESSION_H */
|
||||
|
||||
@@ -1428,7 +1428,7 @@ static ssize_t sftp_read(LIBSSH2_SFTP_HANDLE * handle, char *buffer,
|
||||
|
||||
/* 'count' is how much more data to ask for, and 'already' is how
|
||||
much data that already has been asked for but not yet returned.
|
||||
Specificly, 'count' means how much data that have or will be
|
||||
Specifically, 'count' means how much data that have or will be
|
||||
asked for by the nodes that are already added to the linked
|
||||
list. Some of those read requests may not actually have been
|
||||
sent off successfully yet.
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
#ifndef _LIBSSH2_SFTP_H
|
||||
#define _LIBSSH2_SFTP_H
|
||||
#ifndef __LIBSSH2_SFTP_H
|
||||
#define __LIBSSH2_SFTP_H
|
||||
/*
|
||||
* Copyright (C) 2010 - 2012 by Daniel Stenberg
|
||||
* Author: Daniel Stenberg <daniel@haxx.se>
|
||||
@@ -235,4 +235,4 @@ struct _LIBSSH2_SFTP
|
||||
uint32_t symlink_request_id;
|
||||
};
|
||||
|
||||
#endif
|
||||
#endif /* __LIBSSH2_SFTP_H */
|
||||
|
||||
@@ -323,7 +323,7 @@ int _libssh2_transport_read(LIBSSH2_SESSION * session)
|
||||
|
||||
do {
|
||||
if(session->socket_state == LIBSSH2_SOCKET_DISCONNECTED) {
|
||||
return LIBSSH2_ERROR_NONE;
|
||||
return LIBSSH2_ERROR_SOCKET_DISCONNECT;
|
||||
}
|
||||
|
||||
if(session->state & LIBSSH2_STATE_NEWKEYS) {
|
||||
@@ -465,7 +465,7 @@ int _libssh2_transport_read(LIBSSH2_SESSION * session)
|
||||
* or less (including length, padding length, payload,
|
||||
* padding, and MAC.)."
|
||||
*/
|
||||
if(total_num > LIBSSH2_PACKET_MAXPAYLOAD) {
|
||||
if(total_num > LIBSSH2_PACKET_MAXPAYLOAD || total_num == 0) {
|
||||
return LIBSSH2_ERROR_OUT_OF_BOUNDARY;
|
||||
}
|
||||
|
||||
@@ -488,6 +488,8 @@ int _libssh2_transport_read(LIBSSH2_SESSION * session)
|
||||
p->wptr += blocksize - 5; /* advance write pointer */
|
||||
}
|
||||
else {
|
||||
if(p->payload)
|
||||
LIBSSH2_FREE(session, p->payload);
|
||||
return LIBSSH2_ERROR_OUT_OF_BOUNDARY;
|
||||
}
|
||||
}
|
||||
@@ -570,6 +572,8 @@ int _libssh2_transport_read(LIBSSH2_SESSION * session)
|
||||
memcpy(p->wptr, &p->buf[p->readidx], numbytes);
|
||||
}
|
||||
else {
|
||||
if(p->payload)
|
||||
LIBSSH2_FREE(session, p->payload);
|
||||
return LIBSSH2_ERROR_OUT_OF_BOUNDARY;
|
||||
}
|
||||
|
||||
@@ -765,7 +769,7 @@ int _libssh2_transport_send(LIBSSH2_SESSION *session,
|
||||
((session->state & LIBSSH2_STATE_AUTHENTICATED) ||
|
||||
session->local.comp->use_in_auth);
|
||||
|
||||
if(encrypted && compressed) {
|
||||
if(encrypted && compressed && session->local.comp_abstract) {
|
||||
/* 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
|
||||
check the input size as we don't know how much it compresses */
|
||||
@@ -858,7 +862,10 @@ int _libssh2_transport_send(LIBSSH2_SESSION *session,
|
||||
p->outbuf[4] = (unsigned char)padding_length;
|
||||
|
||||
/* fill the padding area with random junk */
|
||||
_libssh2_random(p->outbuf + 5 + data_len, padding_length);
|
||||
if(_libssh2_random(p->outbuf + 5 + data_len, padding_length)) {
|
||||
return _libssh2_error(session, LIBSSH2_ERROR_RANDGEN,
|
||||
"Unable to get random bytes for packet padding");
|
||||
}
|
||||
|
||||
if(encrypted) {
|
||||
size_t i;
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
#ifndef __LIBSSH2_TRANSPORT_H
|
||||
#define __LIBSSH2_TRANSPORT_H
|
||||
|
||||
/* Copyright (C) 2007 The Written Word, Inc. All rights reserved.
|
||||
* Copyright (C) 2009-2010 by Daniel Stenberg
|
||||
* Author: Daniel Stenberg <daniel@haxx.se>
|
||||
|
||||
@@ -629,7 +629,7 @@ file_read_publickey(LIBSSH2_SESSION * session, unsigned char **method,
|
||||
|
||||
sp1++;
|
||||
|
||||
sp_len = sp1 > pubkey ? (sp1 - pubkey) - 1 : 0;
|
||||
sp_len = sp1 > pubkey ? (sp1 - pubkey) : 0;
|
||||
sp2 = memchr(sp1, ' ', pubkey_len - sp_len);
|
||||
if(sp2 == NULL) {
|
||||
/* Assume that the id string is missing, but that it's okay */
|
||||
@@ -828,11 +828,6 @@ userauth_hostbased_fromfile(LIBSSH2_SESSION *session,
|
||||
{
|
||||
int rc;
|
||||
|
||||
#if !LIBSSH2_RSA
|
||||
return _libssh2_error(session, LIBSSH2_ERROR_METHOD_NOT_SUPPORTED,
|
||||
"RSA is not supported by crypto backend");
|
||||
#endif
|
||||
|
||||
if(session->userauth_host_state == libssh2_NB_state_idle) {
|
||||
const LIBSSH2_HOSTKEY_METHOD *privkeyobj;
|
||||
unsigned char *pubkeydata = NULL;
|
||||
@@ -1075,7 +1070,21 @@ libssh2_userauth_hostbased_fromfile_ex(LIBSSH2_SESSION *session,
|
||||
return rc;
|
||||
}
|
||||
|
||||
|
||||
static int plain_method_len(const char *method, size_t method_len)
|
||||
{
|
||||
if(!strncmp("ecdsa-sha2-nistp256-cert-v01@openssh.com",
|
||||
method,
|
||||
method_len) ||
|
||||
!strncmp("ecdsa-sha2-nistp384-cert-v01@openssh.com",
|
||||
method,
|
||||
method_len) ||
|
||||
!strncmp("ecdsa-sha2-nistp521-cert-v01@openssh.com",
|
||||
method,
|
||||
method_len)) {
|
||||
return 19;
|
||||
}
|
||||
return method_len;
|
||||
}
|
||||
|
||||
int
|
||||
_libssh2_userauth_publickey(LIBSSH2_SESSION *session,
|
||||
@@ -1340,6 +1349,10 @@ _libssh2_userauth_publickey(LIBSSH2_SESSION *session,
|
||||
s = session->userauth_pblc_packet + session->userauth_pblc_packet_len;
|
||||
session->userauth_pblc_b = NULL;
|
||||
|
||||
session->userauth_pblc_method_len =
|
||||
plain_method_len((const char *)session->userauth_pblc_method,
|
||||
session->userauth_pblc_method_len);
|
||||
|
||||
_libssh2_store_u32(&s,
|
||||
4 + session->userauth_pblc_method_len + 4 +
|
||||
sig_len);
|
||||
@@ -1438,11 +1451,6 @@ userauth_publickey_frommemory(LIBSSH2_SESSION *session,
|
||||
void *abstract = &privkey_file;
|
||||
int rc;
|
||||
|
||||
#if !LIBSSH2_RSA
|
||||
return _libssh2_error(session, LIBSSH2_ERROR_METHOD_NOT_SUPPORTED,
|
||||
"RSA is not supported by crypto backend");
|
||||
#endif
|
||||
|
||||
privkey_file.filename = privatekeydata;
|
||||
privkey_file.passphrase = passphrase;
|
||||
|
||||
@@ -1457,15 +1465,14 @@ userauth_publickey_frommemory(LIBSSH2_SESSION *session,
|
||||
}
|
||||
else if(privatekeydata_len && privatekeydata) {
|
||||
/* Compute public key from private key. */
|
||||
if(_libssh2_pub_priv_keyfilememory(session,
|
||||
rc = _libssh2_pub_priv_keyfilememory(session,
|
||||
&session->userauth_pblc_method,
|
||||
&session->userauth_pblc_method_len,
|
||||
&pubkeydata, &pubkeydata_len,
|
||||
privatekeydata, privatekeydata_len,
|
||||
passphrase))
|
||||
return _libssh2_error(session, LIBSSH2_ERROR_FILE,
|
||||
"Unable to extract public key "
|
||||
"from private key.");
|
||||
passphrase);
|
||||
if(rc)
|
||||
return rc;
|
||||
}
|
||||
else {
|
||||
return _libssh2_error(session, LIBSSH2_ERROR_FILE,
|
||||
@@ -1500,11 +1507,6 @@ userauth_publickey_fromfile(LIBSSH2_SESSION *session,
|
||||
void *abstract = &privkey_file;
|
||||
int rc;
|
||||
|
||||
#if !LIBSSH2_RSA
|
||||
return _libssh2_error(session, LIBSSH2_ERROR_METHOD_NOT_SUPPORTED,
|
||||
"RSA is not supported by crypto backend");
|
||||
#endif
|
||||
|
||||
privkey_file.filename = privatekey;
|
||||
privkey_file.passphrase = passphrase;
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
#ifndef LIBSSH2_USERAUTH_H
|
||||
#define LIBSSH2_USERAUTH_H
|
||||
#ifndef __LIBSSH2_USERAUTH_H
|
||||
#define __LIBSSH2_USERAUTH_H
|
||||
/* Copyright (c) 2004-2007, Sara Golemon <sarag@libssh2.org>
|
||||
* Copyright (c) 2009-2010 by Daniel Stenberg
|
||||
* All rights reserved.
|
||||
@@ -48,4 +48,4 @@ _libssh2_userauth_publickey(LIBSSH2_SESSION *session,
|
||||
((*sign_callback)),
|
||||
void *abstract);
|
||||
|
||||
#endif /* LIBSSH2_USERAUTH_H */
|
||||
#endif /* __LIBSSH2_USERAUTH_H */
|
||||
|
||||
569
src/wincng.c
569
src/wincng.c
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (C) 2013-2015 Marc Hoersken <info@marc-hoersken.de>
|
||||
* Copyright (C) 2013-2020 Marc Hoersken <info@marc-hoersken.de>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms,
|
||||
@@ -58,6 +58,7 @@
|
||||
|
||||
#include <windows.h>
|
||||
#include <bcrypt.h>
|
||||
#include <ntstatus.h>
|
||||
#include <math.h>
|
||||
#include "misc.h"
|
||||
|
||||
@@ -98,6 +99,10 @@
|
||||
#define BCRYPT_SHA256_ALGORITHM L"SHA256"
|
||||
#endif
|
||||
|
||||
#ifndef BCRYPT_SHA384_ALGORITHM
|
||||
#define BCRYPT_SHA384_ALGORITHM L"SHA384"
|
||||
#endif
|
||||
|
||||
#ifndef BCRYPT_SHA512_ALGORITHM
|
||||
#define BCRYPT_SHA512_ALGORITHM L"SHA512"
|
||||
#endif
|
||||
@@ -122,6 +127,15 @@
|
||||
#define BCRYPT_3DES_ALGORITHM L"3DES"
|
||||
#endif
|
||||
|
||||
#ifndef BCRYPT_DH_ALGORITHM
|
||||
#define BCRYPT_DH_ALGORITHM L"DH"
|
||||
#endif
|
||||
|
||||
/* BCRYPT_KDF_RAW_SECRET is available from Windows 8.1 and onwards */
|
||||
#ifndef BCRYPT_KDF_RAW_SECRET
|
||||
#define BCRYPT_KDF_RAW_SECRET L"TRUNCATE"
|
||||
#endif
|
||||
|
||||
#ifndef BCRYPT_ALG_HANDLE_HMAC_FLAG
|
||||
#define BCRYPT_ALG_HANDLE_HMAC_FLAG 0x00000008
|
||||
#endif
|
||||
@@ -208,40 +222,88 @@
|
||||
* Windows CNG backend: Generic functions
|
||||
*/
|
||||
|
||||
struct _libssh2_wincng_ctx _libssh2_wincng;
|
||||
|
||||
void
|
||||
_libssh2_wincng_init(void)
|
||||
{
|
||||
int ret;
|
||||
|
||||
(void)BCryptOpenAlgorithmProvider(&_libssh2_wincng.hAlgRNG,
|
||||
memset(&_libssh2_wincng, 0, sizeof(_libssh2_wincng));
|
||||
|
||||
ret = BCryptOpenAlgorithmProvider(&_libssh2_wincng.hAlgRNG,
|
||||
BCRYPT_RNG_ALGORITHM, NULL, 0);
|
||||
if(!BCRYPT_SUCCESS(ret)) {
|
||||
_libssh2_wincng.hAlgRNG = NULL;
|
||||
}
|
||||
|
||||
(void)BCryptOpenAlgorithmProvider(&_libssh2_wincng.hAlgHashMD5,
|
||||
ret = BCryptOpenAlgorithmProvider(&_libssh2_wincng.hAlgHashMD5,
|
||||
BCRYPT_MD5_ALGORITHM, NULL, 0);
|
||||
(void)BCryptOpenAlgorithmProvider(&_libssh2_wincng.hAlgHashSHA1,
|
||||
if(!BCRYPT_SUCCESS(ret)) {
|
||||
_libssh2_wincng.hAlgHashMD5 = NULL;
|
||||
}
|
||||
ret = BCryptOpenAlgorithmProvider(&_libssh2_wincng.hAlgHashSHA1,
|
||||
BCRYPT_SHA1_ALGORITHM, NULL, 0);
|
||||
(void)BCryptOpenAlgorithmProvider(&_libssh2_wincng.hAlgHashSHA256,
|
||||
if(!BCRYPT_SUCCESS(ret)) {
|
||||
_libssh2_wincng.hAlgHashSHA1 = NULL;
|
||||
}
|
||||
ret = BCryptOpenAlgorithmProvider(&_libssh2_wincng.hAlgHashSHA256,
|
||||
BCRYPT_SHA256_ALGORITHM, NULL, 0);
|
||||
(void)BCryptOpenAlgorithmProvider(&_libssh2_wincng.hAlgHashSHA512,
|
||||
if(!BCRYPT_SUCCESS(ret)) {
|
||||
_libssh2_wincng.hAlgHashSHA256 = NULL;
|
||||
}
|
||||
ret = BCryptOpenAlgorithmProvider(&_libssh2_wincng.hAlgHashSHA384,
|
||||
BCRYPT_SHA384_ALGORITHM, NULL, 0);
|
||||
if(!BCRYPT_SUCCESS(ret)) {
|
||||
_libssh2_wincng.hAlgHashSHA384 = NULL;
|
||||
}
|
||||
ret = BCryptOpenAlgorithmProvider(&_libssh2_wincng.hAlgHashSHA512,
|
||||
BCRYPT_SHA512_ALGORITHM, NULL, 0);
|
||||
if(!BCRYPT_SUCCESS(ret)) {
|
||||
_libssh2_wincng.hAlgHashSHA512 = NULL;
|
||||
}
|
||||
|
||||
(void)BCryptOpenAlgorithmProvider(&_libssh2_wincng.hAlgHmacMD5,
|
||||
ret = BCryptOpenAlgorithmProvider(&_libssh2_wincng.hAlgHmacMD5,
|
||||
BCRYPT_MD5_ALGORITHM, NULL,
|
||||
BCRYPT_ALG_HANDLE_HMAC_FLAG);
|
||||
(void)BCryptOpenAlgorithmProvider(&_libssh2_wincng.hAlgHmacSHA1,
|
||||
if(!BCRYPT_SUCCESS(ret)) {
|
||||
_libssh2_wincng.hAlgHmacMD5 = NULL;
|
||||
}
|
||||
ret = BCryptOpenAlgorithmProvider(&_libssh2_wincng.hAlgHmacSHA1,
|
||||
BCRYPT_SHA1_ALGORITHM, NULL,
|
||||
BCRYPT_ALG_HANDLE_HMAC_FLAG);
|
||||
(void)BCryptOpenAlgorithmProvider(&_libssh2_wincng.hAlgHmacSHA256,
|
||||
if(!BCRYPT_SUCCESS(ret)) {
|
||||
_libssh2_wincng.hAlgHmacSHA1 = NULL;
|
||||
}
|
||||
ret = BCryptOpenAlgorithmProvider(&_libssh2_wincng.hAlgHmacSHA256,
|
||||
BCRYPT_SHA256_ALGORITHM, NULL,
|
||||
BCRYPT_ALG_HANDLE_HMAC_FLAG);
|
||||
(void)BCryptOpenAlgorithmProvider(&_libssh2_wincng.hAlgHmacSHA512,
|
||||
if(!BCRYPT_SUCCESS(ret)) {
|
||||
_libssh2_wincng.hAlgHmacSHA256 = NULL;
|
||||
}
|
||||
ret = BCryptOpenAlgorithmProvider(&_libssh2_wincng.hAlgHmacSHA384,
|
||||
BCRYPT_SHA384_ALGORITHM, NULL,
|
||||
BCRYPT_ALG_HANDLE_HMAC_FLAG);
|
||||
if(!BCRYPT_SUCCESS(ret)) {
|
||||
_libssh2_wincng.hAlgHmacSHA384 = NULL;
|
||||
}
|
||||
ret = BCryptOpenAlgorithmProvider(&_libssh2_wincng.hAlgHmacSHA512,
|
||||
BCRYPT_SHA512_ALGORITHM, NULL,
|
||||
BCRYPT_ALG_HANDLE_HMAC_FLAG);
|
||||
if(!BCRYPT_SUCCESS(ret)) {
|
||||
_libssh2_wincng.hAlgHmacSHA512 = NULL;
|
||||
}
|
||||
|
||||
(void)BCryptOpenAlgorithmProvider(&_libssh2_wincng.hAlgRSA,
|
||||
ret = BCryptOpenAlgorithmProvider(&_libssh2_wincng.hAlgRSA,
|
||||
BCRYPT_RSA_ALGORITHM, NULL, 0);
|
||||
(void)BCryptOpenAlgorithmProvider(&_libssh2_wincng.hAlgDSA,
|
||||
if(!BCRYPT_SUCCESS(ret)) {
|
||||
_libssh2_wincng.hAlgRSA = NULL;
|
||||
}
|
||||
ret = BCryptOpenAlgorithmProvider(&_libssh2_wincng.hAlgDSA,
|
||||
BCRYPT_DSA_ALGORITHM, NULL, 0);
|
||||
if(!BCRYPT_SUCCESS(ret)) {
|
||||
_libssh2_wincng.hAlgDSA = NULL;
|
||||
}
|
||||
|
||||
ret = BCryptOpenAlgorithmProvider(&_libssh2_wincng.hAlgAES_CBC,
|
||||
BCRYPT_AES_ALGORITHM, NULL, 0);
|
||||
@@ -251,7 +313,10 @@ _libssh2_wincng_init(void)
|
||||
(PBYTE)BCRYPT_CHAIN_MODE_CBC,
|
||||
sizeof(BCRYPT_CHAIN_MODE_CBC), 0);
|
||||
if(!BCRYPT_SUCCESS(ret)) {
|
||||
(void)BCryptCloseAlgorithmProvider(_libssh2_wincng.hAlgAES_CBC, 0);
|
||||
ret = BCryptCloseAlgorithmProvider(_libssh2_wincng.hAlgAES_CBC, 0);
|
||||
if(BCRYPT_SUCCESS(ret)) {
|
||||
_libssh2_wincng.hAlgAES_CBC = NULL;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -263,7 +328,10 @@ _libssh2_wincng_init(void)
|
||||
(PBYTE)BCRYPT_CHAIN_MODE_ECB,
|
||||
sizeof(BCRYPT_CHAIN_MODE_ECB), 0);
|
||||
if(!BCRYPT_SUCCESS(ret)) {
|
||||
(void)BCryptCloseAlgorithmProvider(_libssh2_wincng.hAlgAES_ECB, 0);
|
||||
ret = BCryptCloseAlgorithmProvider(_libssh2_wincng.hAlgAES_ECB, 0);
|
||||
if(BCRYPT_SUCCESS(ret)) {
|
||||
_libssh2_wincng.hAlgAES_ECB = NULL;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -275,7 +343,10 @@ _libssh2_wincng_init(void)
|
||||
(PBYTE)BCRYPT_CHAIN_MODE_NA,
|
||||
sizeof(BCRYPT_CHAIN_MODE_NA), 0);
|
||||
if(!BCRYPT_SUCCESS(ret)) {
|
||||
(void)BCryptCloseAlgorithmProvider(_libssh2_wincng.hAlgRC4_NA, 0);
|
||||
ret = BCryptCloseAlgorithmProvider(_libssh2_wincng.hAlgRC4_NA, 0);
|
||||
if(BCRYPT_SUCCESS(ret)) {
|
||||
_libssh2_wincng.hAlgRC4_NA = NULL;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -287,29 +358,58 @@ _libssh2_wincng_init(void)
|
||||
(PBYTE)BCRYPT_CHAIN_MODE_CBC,
|
||||
sizeof(BCRYPT_CHAIN_MODE_CBC), 0);
|
||||
if(!BCRYPT_SUCCESS(ret)) {
|
||||
(void)BCryptCloseAlgorithmProvider(_libssh2_wincng.hAlg3DES_CBC,
|
||||
ret = BCryptCloseAlgorithmProvider(_libssh2_wincng.hAlg3DES_CBC,
|
||||
0);
|
||||
if(BCRYPT_SUCCESS(ret)) {
|
||||
_libssh2_wincng.hAlg3DES_CBC = NULL;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ret = BCryptOpenAlgorithmProvider(&_libssh2_wincng.hAlgDH,
|
||||
BCRYPT_DH_ALGORITHM, NULL, 0);
|
||||
if(!BCRYPT_SUCCESS(ret)) {
|
||||
_libssh2_wincng.hAlgDH = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
_libssh2_wincng_free(void)
|
||||
{
|
||||
(void)BCryptCloseAlgorithmProvider(_libssh2_wincng.hAlgRNG, 0);
|
||||
(void)BCryptCloseAlgorithmProvider(_libssh2_wincng.hAlgHashMD5, 0);
|
||||
(void)BCryptCloseAlgorithmProvider(_libssh2_wincng.hAlgHashSHA1, 0);
|
||||
(void)BCryptCloseAlgorithmProvider(_libssh2_wincng.hAlgHashSHA256, 0);
|
||||
(void)BCryptCloseAlgorithmProvider(_libssh2_wincng.hAlgHashSHA512, 0);
|
||||
(void)BCryptCloseAlgorithmProvider(_libssh2_wincng.hAlgHmacMD5, 0);
|
||||
(void)BCryptCloseAlgorithmProvider(_libssh2_wincng.hAlgHmacSHA1, 0);
|
||||
(void)BCryptCloseAlgorithmProvider(_libssh2_wincng.hAlgHmacSHA256, 0);
|
||||
(void)BCryptCloseAlgorithmProvider(_libssh2_wincng.hAlgHmacSHA512, 0);
|
||||
(void)BCryptCloseAlgorithmProvider(_libssh2_wincng.hAlgRSA, 0);
|
||||
(void)BCryptCloseAlgorithmProvider(_libssh2_wincng.hAlgDSA, 0);
|
||||
(void)BCryptCloseAlgorithmProvider(_libssh2_wincng.hAlgAES_CBC, 0);
|
||||
(void)BCryptCloseAlgorithmProvider(_libssh2_wincng.hAlgRC4_NA, 0);
|
||||
(void)BCryptCloseAlgorithmProvider(_libssh2_wincng.hAlg3DES_CBC, 0);
|
||||
if(_libssh2_wincng.hAlgRNG)
|
||||
(void)BCryptCloseAlgorithmProvider(_libssh2_wincng.hAlgRNG, 0);
|
||||
if(_libssh2_wincng.hAlgHashMD5)
|
||||
(void)BCryptCloseAlgorithmProvider(_libssh2_wincng.hAlgHashMD5, 0);
|
||||
if(_libssh2_wincng.hAlgHashSHA1)
|
||||
(void)BCryptCloseAlgorithmProvider(_libssh2_wincng.hAlgHashSHA1, 0);
|
||||
if(_libssh2_wincng.hAlgHashSHA256)
|
||||
(void)BCryptCloseAlgorithmProvider(_libssh2_wincng.hAlgHashSHA256, 0);
|
||||
if(_libssh2_wincng.hAlgHashSHA384)
|
||||
(void)BCryptCloseAlgorithmProvider(_libssh2_wincng.hAlgHashSHA384, 0);
|
||||
if(_libssh2_wincng.hAlgHashSHA512)
|
||||
(void)BCryptCloseAlgorithmProvider(_libssh2_wincng.hAlgHashSHA512, 0);
|
||||
if(_libssh2_wincng.hAlgHmacMD5)
|
||||
(void)BCryptCloseAlgorithmProvider(_libssh2_wincng.hAlgHmacMD5, 0);
|
||||
if(_libssh2_wincng.hAlgHmacSHA1)
|
||||
(void)BCryptCloseAlgorithmProvider(_libssh2_wincng.hAlgHmacSHA1, 0);
|
||||
if(_libssh2_wincng.hAlgHmacSHA256)
|
||||
(void)BCryptCloseAlgorithmProvider(_libssh2_wincng.hAlgHmacSHA256, 0);
|
||||
if(_libssh2_wincng.hAlgHmacSHA384)
|
||||
(void)BCryptCloseAlgorithmProvider(_libssh2_wincng.hAlgHmacSHA384, 0);
|
||||
if(_libssh2_wincng.hAlgHmacSHA512)
|
||||
(void)BCryptCloseAlgorithmProvider(_libssh2_wincng.hAlgHmacSHA512, 0);
|
||||
if(_libssh2_wincng.hAlgRSA)
|
||||
(void)BCryptCloseAlgorithmProvider(_libssh2_wincng.hAlgRSA, 0);
|
||||
if(_libssh2_wincng.hAlgDSA)
|
||||
(void)BCryptCloseAlgorithmProvider(_libssh2_wincng.hAlgDSA, 0);
|
||||
if(_libssh2_wincng.hAlgAES_CBC)
|
||||
(void)BCryptCloseAlgorithmProvider(_libssh2_wincng.hAlgAES_CBC, 0);
|
||||
if(_libssh2_wincng.hAlgRC4_NA)
|
||||
(void)BCryptCloseAlgorithmProvider(_libssh2_wincng.hAlgRC4_NA, 0);
|
||||
if(_libssh2_wincng.hAlg3DES_CBC)
|
||||
(void)BCryptCloseAlgorithmProvider(_libssh2_wincng.hAlg3DES_CBC, 0);
|
||||
if(_libssh2_wincng.hAlgDH)
|
||||
(void)BCryptCloseAlgorithmProvider(_libssh2_wincng.hAlgDH, 0);
|
||||
|
||||
memset(&_libssh2_wincng, 0, sizeof(_libssh2_wincng));
|
||||
}
|
||||
@@ -342,6 +442,24 @@ _libssh2_wincng_safe_free(void *buf, int len)
|
||||
free(buf);
|
||||
}
|
||||
|
||||
/* Copy a big endian set of bits from src to dest.
|
||||
* if the size of src is smaller than dest then pad the "left" (MSB)
|
||||
* end with zeroes and copy the bits into the "right" (LSB) end. */
|
||||
static void
|
||||
memcpy_with_be_padding(unsigned char *dest, unsigned long dest_len,
|
||||
unsigned char *src, unsigned long src_len)
|
||||
{
|
||||
if(dest_len > src_len) {
|
||||
memset(dest, 0, dest_len - src_len);
|
||||
}
|
||||
memcpy((dest + dest_len) - src_len, src, src_len);
|
||||
}
|
||||
|
||||
static int
|
||||
round_down(int number, int multiple)
|
||||
{
|
||||
return (number / multiple) * multiple;
|
||||
}
|
||||
|
||||
/*******************************************************************/
|
||||
/*
|
||||
@@ -1914,7 +2032,8 @@ _libssh2_wincng_bignum_rand(_libssh2_bn *rnd, int bits, int top, int bottom)
|
||||
if(!rnd)
|
||||
return -1;
|
||||
|
||||
length = (unsigned long)(ceil((float)bits / 8) * sizeof(unsigned char));
|
||||
length = (unsigned long) (ceil(((double)bits) / 8.0) *
|
||||
sizeof(unsigned char));
|
||||
if(_libssh2_wincng_bignum_resize(rnd, length))
|
||||
return -1;
|
||||
|
||||
@@ -1925,15 +2044,17 @@ _libssh2_wincng_bignum_rand(_libssh2_bn *rnd, int bits, int top, int bottom)
|
||||
|
||||
/* calculate significant bits in most significant byte */
|
||||
bits %= 8;
|
||||
if(bits == 0)
|
||||
bits = 8;
|
||||
|
||||
/* fill most significant byte with zero padding */
|
||||
bignum[0] &= (1 << (8 - bits)) - 1;
|
||||
bignum[0] &= ((1 << bits) - 1);
|
||||
|
||||
/* set some special last bits in most significant byte */
|
||||
/* set most significant bits in most significant byte */
|
||||
if(top == 0)
|
||||
bignum[0] |= (1 << (7 - bits));
|
||||
bignum[0] |= (1 << (bits - 1));
|
||||
else if(top == 1)
|
||||
bignum[0] |= (3 << (6 - bits));
|
||||
bignum[0] |= (3 << (bits - 2));
|
||||
|
||||
/* make odd by setting first bit in least significant byte */
|
||||
if(bottom)
|
||||
@@ -1978,11 +2099,10 @@ _libssh2_wincng_bignum_mod_exp(_libssh2_bn *r,
|
||||
offset += p->length;
|
||||
|
||||
memcpy(key + offset, m->bignum, m->length);
|
||||
offset = 0;
|
||||
|
||||
ret = BCryptImportKeyPair(_libssh2_wincng.hAlgRSA, NULL,
|
||||
BCRYPT_RSAPUBLIC_BLOB, &hKey, key, keylen,
|
||||
BCRYPT_NO_KEY_VALIDATION);
|
||||
|
||||
BCRYPT_RSAPUBLIC_BLOB, &hKey, key, keylen, 0);
|
||||
if(BCRYPT_SUCCESS(ret)) {
|
||||
ret = BCryptEncrypt(hKey, a->bignum, a->length, NULL, NULL, 0,
|
||||
NULL, 0, &length, BCRYPT_PAD_NONE);
|
||||
@@ -1991,9 +2111,8 @@ _libssh2_wincng_bignum_mod_exp(_libssh2_bn *r,
|
||||
length = max(a->length, length);
|
||||
bignum = malloc(length);
|
||||
if(bignum) {
|
||||
offset = length - a->length;
|
||||
memset(bignum, 0, offset);
|
||||
memcpy(bignum + offset, a->bignum, a->length);
|
||||
memcpy_with_be_padding(bignum, length,
|
||||
a->bignum, a->length);
|
||||
|
||||
ret = BCryptEncrypt(hKey, bignum, length, NULL, NULL, 0,
|
||||
r->bignum, r->length, &offset,
|
||||
@@ -2032,8 +2151,9 @@ _libssh2_wincng_bignum_set_word(_libssh2_bn *bn, unsigned long word)
|
||||
number = word;
|
||||
while(number >>= 1)
|
||||
bits++;
|
||||
bits++;
|
||||
|
||||
length = (unsigned long) (ceil(((double)(bits + 1)) / 8.0) *
|
||||
length = (unsigned long) (ceil(((double)bits) / 8.0) *
|
||||
sizeof(unsigned char));
|
||||
if(_libssh2_wincng_bignum_resize(bn, length))
|
||||
return -1;
|
||||
@@ -2050,21 +2170,18 @@ _libssh2_wincng_bignum_bits(const _libssh2_bn *bn)
|
||||
unsigned char number;
|
||||
unsigned long offset, length, bits;
|
||||
|
||||
if(!bn)
|
||||
if(!bn || !bn->bignum || !bn->length)
|
||||
return 0;
|
||||
|
||||
length = bn->length - 1;
|
||||
|
||||
offset = 0;
|
||||
while(!(*(bn->bignum + offset)) && (offset < length))
|
||||
length = bn->length - 1;
|
||||
while(!bn->bignum[offset] && offset < length)
|
||||
offset++;
|
||||
|
||||
bits = (length - offset) * 8;
|
||||
number = bn->bignum[offset];
|
||||
|
||||
while(number >>= 1)
|
||||
bits++;
|
||||
|
||||
bits++;
|
||||
|
||||
return bits;
|
||||
@@ -2127,6 +2244,7 @@ _libssh2_wincng_bignum_free(_libssh2_bn *bn)
|
||||
}
|
||||
|
||||
|
||||
/*******************************************************************/
|
||||
/*
|
||||
* Windows CNG backend: Diffie-Hellman support.
|
||||
*/
|
||||
@@ -2134,35 +2252,342 @@ _libssh2_wincng_bignum_free(_libssh2_bn *bn)
|
||||
void
|
||||
_libssh2_dh_init(_libssh2_dh_ctx *dhctx)
|
||||
{
|
||||
*dhctx = _libssh2_wincng_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 */
|
||||
if(_libssh2_wincng_bignum_rand(*dhctx, group_order * 8 - 1, 0, -1))
|
||||
return -1;
|
||||
if(_libssh2_wincng_bignum_mod_exp(public, g, *dhctx, p))
|
||||
return -1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
_libssh2_dh_secret(_libssh2_dh_ctx *dhctx, _libssh2_bn *secret,
|
||||
_libssh2_bn *f, _libssh2_bn *p)
|
||||
{
|
||||
/* Compute the shared secret */
|
||||
_libssh2_wincng_bignum_mod_exp(secret, f, *dhctx, p);
|
||||
return 0;
|
||||
/* Random from client */
|
||||
dhctx->bn = NULL;
|
||||
dhctx->dh_handle = NULL;
|
||||
dhctx->dh_params = NULL;
|
||||
}
|
||||
|
||||
void
|
||||
_libssh2_dh_dtor(_libssh2_dh_ctx *dhctx)
|
||||
{
|
||||
_libssh2_wincng_bignum_free(*dhctx);
|
||||
*dhctx = NULL;
|
||||
if(dhctx->dh_handle) {
|
||||
BCryptDestroyKey(dhctx->dh_handle);
|
||||
dhctx->dh_handle = NULL;
|
||||
}
|
||||
if(dhctx->dh_params) {
|
||||
/* Since public dh_params are shared in clear text,
|
||||
* we don't need to securely zero them out here */
|
||||
free(dhctx->dh_params);
|
||||
dhctx->dh_params = NULL;
|
||||
}
|
||||
if(dhctx->bn) {
|
||||
_libssh2_wincng_bignum_free(dhctx->bn);
|
||||
dhctx->bn = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
/* Generates a Diffie-Hellman key pair using base `g', prime `p' and the given
|
||||
* `group_order'. Can use the given big number context `bnctx' if needed. The
|
||||
* private key is stored as opaque in the Diffie-Hellman context `*dhctx' and
|
||||
* the public key is returned in `public'. 0 is returned upon success, else
|
||||
* -1. */
|
||||
int
|
||||
_libssh2_dh_key_pair(_libssh2_dh_ctx *dhctx, _libssh2_bn *public,
|
||||
_libssh2_bn *g, _libssh2_bn *p, int group_order)
|
||||
{
|
||||
const int hasAlgDHwithKDF = _libssh2_wincng.hasAlgDHwithKDF;
|
||||
while(_libssh2_wincng.hAlgDH && hasAlgDHwithKDF != -1) {
|
||||
BCRYPT_DH_PARAMETER_HEADER *dh_params = NULL;
|
||||
unsigned long dh_params_len;
|
||||
unsigned char *blob = NULL;
|
||||
int status;
|
||||
/* Note that the DH provider requires that keys be multiples of 64 bits
|
||||
* in length. At the time of writing a practical observed group_order
|
||||
* value is 257, so we need to round down to 8 bytes of length (64/8)
|
||||
* in order for kex to succeed */
|
||||
DWORD key_length_bytes = max(round_down(group_order, 8),
|
||||
max(g->length, p->length));
|
||||
BCRYPT_DH_KEY_BLOB *dh_key_blob;
|
||||
LPCWSTR key_type;
|
||||
|
||||
/* Prepare a key pair; pass the in the bit length of the key,
|
||||
* but the key is not ready for consumption until it is finalized. */
|
||||
status = BCryptGenerateKeyPair(_libssh2_wincng.hAlgDH,
|
||||
&dhctx->dh_handle,
|
||||
key_length_bytes * 8, 0);
|
||||
if(!BCRYPT_SUCCESS(status)) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
dh_params_len = sizeof(*dh_params) + 2 * key_length_bytes;
|
||||
blob = malloc(dh_params_len);
|
||||
if(!blob) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Populate DH parameters blob; after the header follows the `p`
|
||||
* value and the `g` value. */
|
||||
dh_params = (BCRYPT_DH_PARAMETER_HEADER*)blob;
|
||||
dh_params->cbLength = dh_params_len;
|
||||
dh_params->dwMagic = BCRYPT_DH_PARAMETERS_MAGIC;
|
||||
dh_params->cbKeyLength = key_length_bytes;
|
||||
memcpy_with_be_padding(blob + sizeof(*dh_params), key_length_bytes,
|
||||
p->bignum, p->length);
|
||||
memcpy_with_be_padding(blob + sizeof(*dh_params) + key_length_bytes,
|
||||
key_length_bytes, g->bignum, g->length);
|
||||
|
||||
status = BCryptSetProperty(dhctx->dh_handle, BCRYPT_DH_PARAMETERS,
|
||||
blob, dh_params_len, 0);
|
||||
if(hasAlgDHwithKDF == -1) {
|
||||
/* We know that the raw KDF is not supported, so discard this. */
|
||||
free(blob);
|
||||
}
|
||||
else {
|
||||
/* Pass ownership to dhctx; these parameters will be freed when
|
||||
* the context is destroyed. We need to keep the parameters more
|
||||
* easily available so that we have access to the `g` value when
|
||||
* _libssh2_dh_secret is called later. */
|
||||
dhctx->dh_params = dh_params;
|
||||
}
|
||||
dh_params = NULL;
|
||||
blob = NULL;
|
||||
|
||||
if(!BCRYPT_SUCCESS(status)) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
status = BCryptFinalizeKeyPair(dhctx->dh_handle, 0);
|
||||
if(!BCRYPT_SUCCESS(status)) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
key_length_bytes = 0;
|
||||
if(hasAlgDHwithKDF == 1) {
|
||||
/* Now we need to extract the public portion of the key so that we
|
||||
* set it in the `public` bignum to satisfy our caller.
|
||||
* First measure up the size of the required buffer. */
|
||||
key_type = BCRYPT_DH_PUBLIC_BLOB;
|
||||
}
|
||||
else {
|
||||
/* We also need to extract the private portion of the key to
|
||||
* set it in the `*dhctx' bignum if the raw KDF is not supported.
|
||||
* First measure up the size of the required buffer. */
|
||||
key_type = BCRYPT_DH_PRIVATE_BLOB;
|
||||
}
|
||||
status = BCryptExportKey(dhctx->dh_handle, NULL, key_type,
|
||||
NULL, 0, &key_length_bytes, 0);
|
||||
if(!BCRYPT_SUCCESS(status)) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
blob = malloc(key_length_bytes);
|
||||
if(!blob) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
status = BCryptExportKey(dhctx->dh_handle, NULL, key_type,
|
||||
blob, key_length_bytes,
|
||||
&key_length_bytes, 0);
|
||||
if(!BCRYPT_SUCCESS(status)) {
|
||||
if(hasAlgDHwithKDF == 1) {
|
||||
/* We have no private data, because raw KDF is supported */
|
||||
free(blob);
|
||||
}
|
||||
else { /* we may have potentially private data, use secure free */
|
||||
_libssh2_wincng_safe_free(blob, key_length_bytes);
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
if(hasAlgDHwithKDF == -1) {
|
||||
/* We know that the raw KDF is not supported, so discard this */
|
||||
BCryptDestroyKey(dhctx->dh_handle);
|
||||
dhctx->dh_handle = NULL;
|
||||
}
|
||||
|
||||
/* BCRYPT_DH_PUBLIC_BLOB corresponds to a BCRYPT_DH_KEY_BLOB header
|
||||
* followed by the Modulus, Generator and Public data. Those components
|
||||
* each have equal size, specified by dh_key_blob->cbKey. */
|
||||
dh_key_blob = (BCRYPT_DH_KEY_BLOB*)blob;
|
||||
if(_libssh2_wincng_bignum_resize(public, dh_key_blob->cbKey)) {
|
||||
if(hasAlgDHwithKDF == 1) {
|
||||
/* We have no private data, because raw KDF is supported */
|
||||
free(blob);
|
||||
}
|
||||
else { /* we may have potentially private data, use secure free */
|
||||
_libssh2_wincng_safe_free(blob, key_length_bytes);
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Copy the public key data into the public bignum data buffer */
|
||||
memcpy(public->bignum,
|
||||
blob + sizeof(*dh_key_blob) + 2 * dh_key_blob->cbKey,
|
||||
dh_key_blob->cbKey);
|
||||
|
||||
if(dh_key_blob->dwMagic == BCRYPT_DH_PRIVATE_MAGIC) {
|
||||
/* BCRYPT_DH_PRIVATE_BLOB additionally contains the Private data */
|
||||
dhctx->bn = _libssh2_wincng_bignum_init();
|
||||
if(!dhctx->bn) {
|
||||
_libssh2_wincng_safe_free(blob, key_length_bytes);
|
||||
return -1;
|
||||
}
|
||||
if(_libssh2_wincng_bignum_resize(dhctx->bn, dh_key_blob->cbKey)) {
|
||||
_libssh2_wincng_safe_free(blob, key_length_bytes);
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Copy the private key data into the dhctx bignum data buffer */
|
||||
memcpy(dhctx->bn->bignum,
|
||||
blob + sizeof(*dh_key_blob) + 3 * dh_key_blob->cbKey,
|
||||
dh_key_blob->cbKey);
|
||||
|
||||
/* Make sure the private key is an odd number, because only
|
||||
* odd primes can be used with the RSA-based fallback while
|
||||
* DH itself does not seem to care about it being odd or not. */
|
||||
if(!(dhctx->bn->bignum[dhctx->bn->length-1] % 2)) {
|
||||
_libssh2_wincng_safe_free(blob, key_length_bytes);
|
||||
/* discard everything first, then try again */
|
||||
_libssh2_dh_dtor(dhctx);
|
||||
_libssh2_dh_init(dhctx);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Generate x and e */
|
||||
dhctx->bn = _libssh2_wincng_bignum_init();
|
||||
if(!dhctx->bn)
|
||||
return -1;
|
||||
if(_libssh2_wincng_bignum_rand(dhctx->bn, group_order * 8 - 1, 0, -1))
|
||||
return -1;
|
||||
if(_libssh2_wincng_bignum_mod_exp(public, g, dhctx->bn, p))
|
||||
return -1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Computes the Diffie-Hellman secret from the previously created context
|
||||
* `*dhctx', the public key `f' from the other party and the same prime `p'
|
||||
* used at context creation. The result is stored in `secret'. 0 is returned
|
||||
* upon success, else -1. */
|
||||
int
|
||||
_libssh2_dh_secret(_libssh2_dh_ctx *dhctx, _libssh2_bn *secret,
|
||||
_libssh2_bn *f, _libssh2_bn *p)
|
||||
{
|
||||
if(_libssh2_wincng.hAlgDH && _libssh2_wincng.hasAlgDHwithKDF != -1 &&
|
||||
dhctx->dh_handle && dhctx->dh_params && f) {
|
||||
BCRYPT_KEY_HANDLE peer_public = NULL;
|
||||
BCRYPT_SECRET_HANDLE agreement = NULL;
|
||||
ULONG secret_len_bytes = 0;
|
||||
unsigned char *blob;
|
||||
int status;
|
||||
unsigned char *start, *end;
|
||||
BCRYPT_DH_KEY_BLOB *public_blob = NULL;
|
||||
DWORD key_length_bytes = max(f->length, dhctx->dh_params->cbKeyLength);
|
||||
DWORD public_blob_len = sizeof(*public_blob) + 3 * key_length_bytes;
|
||||
|
||||
{
|
||||
/* Populate a BCRYPT_DH_KEY_BLOB; after the header follows the
|
||||
* Modulus, Generator and Public data. Those components must have
|
||||
* equal size in this representation. */
|
||||
unsigned char *dest;
|
||||
unsigned char *src;
|
||||
|
||||
blob = malloc(public_blob_len);
|
||||
if(!blob) {
|
||||
return -1;
|
||||
}
|
||||
public_blob = (BCRYPT_DH_KEY_BLOB*)blob;
|
||||
public_blob->dwMagic = BCRYPT_DH_PUBLIC_MAGIC;
|
||||
public_blob->cbKey = key_length_bytes;
|
||||
|
||||
dest = (unsigned char *)(public_blob + 1);
|
||||
src = (unsigned char *)(dhctx->dh_params + 1);
|
||||
|
||||
/* Modulus (the p-value from the first call) */
|
||||
memcpy_with_be_padding(dest, key_length_bytes, src,
|
||||
dhctx->dh_params->cbKeyLength);
|
||||
/* Generator (the g-value from the first call) */
|
||||
memcpy_with_be_padding(dest + key_length_bytes, key_length_bytes,
|
||||
src + dhctx->dh_params->cbKeyLength,
|
||||
dhctx->dh_params->cbKeyLength);
|
||||
/* Public from the peer */
|
||||
memcpy_with_be_padding(dest + 2*key_length_bytes, key_length_bytes,
|
||||
f->bignum, f->length);
|
||||
}
|
||||
|
||||
/* Import the peer public key information */
|
||||
status = BCryptImportKeyPair(_libssh2_wincng.hAlgDH, NULL,
|
||||
BCRYPT_DH_PUBLIC_BLOB, &peer_public, blob,
|
||||
public_blob_len, 0);
|
||||
if(!BCRYPT_SUCCESS(status)) {
|
||||
goto out;
|
||||
}
|
||||
|
||||
/* Set up a handle that we can use to establish the shared secret
|
||||
* between ourselves (our saved dh_handle) and the peer. */
|
||||
status = BCryptSecretAgreement(dhctx->dh_handle, peer_public,
|
||||
&agreement, 0);
|
||||
if(!BCRYPT_SUCCESS(status)) {
|
||||
goto out;
|
||||
}
|
||||
|
||||
/* Compute the size of the buffer that is needed to hold the derived
|
||||
* shared secret. */
|
||||
status = BCryptDeriveKey(agreement, BCRYPT_KDF_RAW_SECRET, NULL, NULL,
|
||||
0, &secret_len_bytes, 0);
|
||||
if(!BCRYPT_SUCCESS(status)) {
|
||||
if(status == STATUS_NOT_SUPPORTED) {
|
||||
_libssh2_wincng.hasAlgDHwithKDF = -1;
|
||||
}
|
||||
goto out;
|
||||
}
|
||||
|
||||
/* Expand the secret bignum to be ready to receive the derived secret
|
||||
* */
|
||||
if(_libssh2_wincng_bignum_resize(secret, secret_len_bytes)) {
|
||||
status = STATUS_NO_MEMORY;
|
||||
goto out;
|
||||
}
|
||||
|
||||
/* And populate the secret bignum */
|
||||
status = BCryptDeriveKey(agreement, BCRYPT_KDF_RAW_SECRET, NULL,
|
||||
secret->bignum, secret_len_bytes,
|
||||
&secret_len_bytes, 0);
|
||||
if(!BCRYPT_SUCCESS(status)) {
|
||||
if(status == STATUS_NOT_SUPPORTED) {
|
||||
_libssh2_wincng.hasAlgDHwithKDF = -1;
|
||||
}
|
||||
goto out;
|
||||
}
|
||||
|
||||
/* Counter to all the other data in the BCrypt APIs, the raw secret is
|
||||
* returned to us in host byte order, so we need to swap it to big
|
||||
* endian order. */
|
||||
start = secret->bignum;
|
||||
end = secret->bignum + secret->length - 1;
|
||||
while(start < end) {
|
||||
unsigned char tmp = *end;
|
||||
*end = *start;
|
||||
*start = tmp;
|
||||
start++;
|
||||
end--;
|
||||
}
|
||||
|
||||
status = 0;
|
||||
_libssh2_wincng.hasAlgDHwithKDF = 1;
|
||||
|
||||
out:
|
||||
if(peer_public) {
|
||||
BCryptDestroyKey(peer_public);
|
||||
}
|
||||
if(agreement) {
|
||||
BCryptDestroySecret(agreement);
|
||||
}
|
||||
if(status == STATUS_NOT_SUPPORTED &&
|
||||
_libssh2_wincng.hasAlgDHwithKDF == -1) {
|
||||
goto fb; /* fallback to RSA-based implementation */
|
||||
}
|
||||
return BCRYPT_SUCCESS(status) ? 0 : -1;
|
||||
}
|
||||
|
||||
fb:
|
||||
/* Compute the shared secret */
|
||||
return _libssh2_wincng_bignum_mod_exp(secret, f, dhctx->bn, p);
|
||||
}
|
||||
|
||||
#endif /* LIBSSH2_WINCNG */
|
||||
|
||||
38
src/wincng.h
38
src/wincng.h
@@ -1,5 +1,7 @@
|
||||
#ifndef __LIBSSH2_WINCNG_H
|
||||
#define __LIBSSH2_WINCNG_H
|
||||
/*
|
||||
* Copyright (C) 2013-2015 Marc Hoersken <info@marc-hoersken.de>
|
||||
* Copyright (C) 2013-2020 Marc Hoersken <info@marc-hoersken.de>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms,
|
||||
@@ -47,7 +49,6 @@
|
||||
#include <windows.h>
|
||||
#include <bcrypt.h>
|
||||
|
||||
|
||||
#define LIBSSH2_MD5 1
|
||||
|
||||
#define LIBSSH2_HMAC_RIPEMD 0
|
||||
@@ -69,6 +70,7 @@
|
||||
#define MD5_DIGEST_LENGTH 16
|
||||
#define SHA_DIGEST_LENGTH 20
|
||||
#define SHA256_DIGEST_LENGTH 32
|
||||
#define SHA384_DIGEST_LENGTH 48
|
||||
#define SHA512_DIGEST_LENGTH 64
|
||||
|
||||
#define EC_MAX_POINT_LEN ((528 * 2 / 8) + 1)
|
||||
@@ -88,10 +90,12 @@ struct _libssh2_wincng_ctx {
|
||||
BCRYPT_ALG_HANDLE hAlgHashMD5;
|
||||
BCRYPT_ALG_HANDLE hAlgHashSHA1;
|
||||
BCRYPT_ALG_HANDLE hAlgHashSHA256;
|
||||
BCRYPT_ALG_HANDLE hAlgHashSHA384;
|
||||
BCRYPT_ALG_HANDLE hAlgHashSHA512;
|
||||
BCRYPT_ALG_HANDLE hAlgHmacMD5;
|
||||
BCRYPT_ALG_HANDLE hAlgHmacSHA1;
|
||||
BCRYPT_ALG_HANDLE hAlgHmacSHA256;
|
||||
BCRYPT_ALG_HANDLE hAlgHmacSHA384;
|
||||
BCRYPT_ALG_HANDLE hAlgHmacSHA512;
|
||||
BCRYPT_ALG_HANDLE hAlgRSA;
|
||||
BCRYPT_ALG_HANDLE hAlgDSA;
|
||||
@@ -99,9 +103,11 @@ struct _libssh2_wincng_ctx {
|
||||
BCRYPT_ALG_HANDLE hAlgAES_ECB;
|
||||
BCRYPT_ALG_HANDLE hAlgRC4_NA;
|
||||
BCRYPT_ALG_HANDLE hAlg3DES_CBC;
|
||||
BCRYPT_ALG_HANDLE hAlgDH;
|
||||
volatile int hasAlgDHwithKDF; /* -1=no, 0=maybe, 1=yes */
|
||||
};
|
||||
|
||||
struct _libssh2_wincng_ctx _libssh2_wincng;
|
||||
extern struct _libssh2_wincng_ctx _libssh2_wincng;
|
||||
|
||||
|
||||
/*******************************************************************/
|
||||
@@ -162,7 +168,17 @@ typedef struct __libssh2_wincng_hash_ctx {
|
||||
#define libssh2_sha256(data, datalen, hash) \
|
||||
_libssh2_wincng_hash(data, datalen, _libssh2_wincng.hAlgHashSHA256, \
|
||||
hash, SHA256_DIGEST_LENGTH)
|
||||
|
||||
#define libssh2_sha384_ctx _libssh2_wincng_hash_ctx
|
||||
#define libssh2_sha384_init(ctx) \
|
||||
(_libssh2_wincng_hash_init(ctx, _libssh2_wincng.hAlgHashSHA384, \
|
||||
SHA384_DIGEST_LENGTH, NULL, 0) == 0)
|
||||
#define libssh2_sha384_update(ctx, data, datalen) \
|
||||
_libssh2_wincng_hash_update(&ctx, (unsigned char *) data, datalen)
|
||||
#define libssh2_sha384_final(ctx, hash) \
|
||||
_libssh2_wincng_hash_final(&ctx, hash)
|
||||
#define libssh2_sha384(data, datalen, hash) \
|
||||
_libssh2_wincng_hash(data, datalen, _libssh2_wincng.hAlgHashSHA384, \
|
||||
hash, SHA384_DIGEST_LENGTH)
|
||||
#define libssh2_sha512_ctx _libssh2_wincng_hash_ctx
|
||||
#define libssh2_sha512_init(ctx) \
|
||||
(_libssh2_wincng_hash_init(ctx, _libssh2_wincng.hAlgHashSHA512, \
|
||||
@@ -385,7 +401,17 @@ _libssh2_bn *_libssh2_wincng_bignum_init(void);
|
||||
* Windows CNG backend: Diffie-Hellman support
|
||||
*/
|
||||
|
||||
#define _libssh2_dh_ctx struct _libssh2_wincng_bignum *
|
||||
typedef struct {
|
||||
/* holds our private and public key components */
|
||||
BCRYPT_KEY_HANDLE dh_handle;
|
||||
/* records the parsed out modulus and generator
|
||||
* parameters that are shared with the peer */
|
||||
BCRYPT_DH_PARAMETER_HEADER *dh_params;
|
||||
/* records the parsed out private key component for
|
||||
* fallback if the DH API raw KDF is not supported */
|
||||
struct _libssh2_wincng_bignum *bn;
|
||||
} _libssh2_dh_ctx;
|
||||
|
||||
#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)
|
||||
@@ -569,3 +595,5 @@ _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);
|
||||
|
||||
#endif /* __LIBSSH2_WINCNG_H */
|
||||
|
||||
10
test-driver
10
test-driver
@@ -3,7 +3,7 @@
|
||||
|
||||
scriptversion=2018-03-07.03; # UTC
|
||||
|
||||
# Copyright (C) 2011-2018 Free Software Foundation, Inc.
|
||||
# Copyright (C) 2011-2020 Free Software Foundation, Inc.
|
||||
#
|
||||
# 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
|
||||
@@ -42,11 +42,13 @@ print_usage ()
|
||||
{
|
||||
cat <<END
|
||||
Usage:
|
||||
test-driver --test-name=NAME --log-file=PATH --trs-file=PATH
|
||||
[--expect-failure={yes|no}] [--color-tests={yes|no}]
|
||||
[--enable-hard-errors={yes|no}] [--]
|
||||
test-driver --test-name NAME --log-file PATH --trs-file PATH
|
||||
[--expect-failure {yes|no}] [--color-tests {yes|no}]
|
||||
[--enable-hard-errors {yes|no}] [--]
|
||||
TEST-SCRIPT [TEST-SCRIPT-ARGUMENTS]
|
||||
|
||||
The '--test-name', '--log-file' and '--trs-file' options are mandatory.
|
||||
See the GNU Automake documentation for information.
|
||||
END
|
||||
}
|
||||
|
||||
|
||||
@@ -118,6 +118,7 @@ set(TESTS
|
||||
public_key_auth_succeeds_with_correct_encrypted_rsa_key
|
||||
keyboard_interactive_auth_fails_with_wrong_response
|
||||
keyboard_interactive_auth_succeeds_with_correct_response
|
||||
agent_forward_succeeds
|
||||
)
|
||||
|
||||
if(CRYPTO_BACKEND STREQUAL "OpenSSL")
|
||||
@@ -129,7 +130,9 @@ if(CRYPTO_BACKEND STREQUAL "OpenSSL")
|
||||
public_key_auth_succeeds_with_correct_ed25519_key
|
||||
public_key_auth_succeeds_with_correct_encrypted_ed25519_key
|
||||
public_key_auth_succeeds_with_correct_ed25519_key_from_mem
|
||||
)
|
||||
public_key_auth_succeeds_with_correct_ecdsa_key
|
||||
public_key_auth_succeeds_with_correct_signed_ecdsa_key
|
||||
)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
SUBDIRS = ossfuzz
|
||||
|
||||
AM_CPPFLAGS = -I$(top_srcdir)/src -I$(top_srcdir)/include -I$(top_builddir)/src
|
||||
LDADD = ../src/libssh2.la
|
||||
|
||||
@@ -16,26 +18,61 @@ check_PROGRAMS = $(ctests)
|
||||
TESTS_ENVIRONMENT = SSHD=$(SSHD) EXEEXT=$(EXEEXT)
|
||||
TESTS_ENVIRONMENT += srcdir=$(top_srcdir)/tests builddir=$(top_builddir)/tests
|
||||
|
||||
EXTRA_DIST = ssh2.sh mansyntax.sh
|
||||
EXTRA_DIST += etc/host etc/host.pub etc/user etc/user.pub
|
||||
EXTRA_DIST += CMakeLists.txt libssh2_config_cmake.h.in sshd_fixture.sh.in
|
||||
EXTRA_DIST += key_dsa key_dsa.pub key_dsa_wrong key_dsa_wrong.pub key_rsa key_rsa.pub
|
||||
EXTRA_DIST += openssh_server/authorized_keys openssh_server/Dockerfile openssh_server/ssh_host_rsa_key
|
||||
EXTRA_DIST += openssh_fixture.c openssh_fixture.h runner.c session_fixture.c session_fixture.h
|
||||
EXTRA_DIST += test_hostkey.c test_hostkey_hash.c
|
||||
EXTRA_DIST += test_keyboard_interactive_auth_fails_with_wrong_response.c
|
||||
EXTRA_DIST += test_keyboard_interactive_auth_succeeds_with_correct_response.c
|
||||
EXTRA_DIST += test_password_auth_fails_with_wrong_password.c
|
||||
EXTRA_DIST += test_password_auth_fails_with_wrong_username.c
|
||||
EXTRA_DIST += test_password_auth_succeeds_with_correct_credentials.c
|
||||
EXTRA_DIST += test_public_key_auth_fails_with_wrong_key.c
|
||||
EXTRA_DIST += test_public_key_auth_succeeds_with_correct_dsa_key.c
|
||||
EXTRA_DIST += test_public_key_auth_succeeds_with_correct_rsa_key.c
|
||||
EXTRA_DIST += test_public_key_auth_succeeds_with_correct_encrypted_rsa_key.c
|
||||
if OPENSSL
|
||||
# TODO: need to add a test for specific openssl version some how
|
||||
# EXTRA_DIST += test_public_key_auth_succeeds_with_correct_ed25519_key.c
|
||||
# EXTRA_DIST += test_public_key_auth_succeeds_with_correct_encrypted_ed25519_key.c
|
||||
# EXTRA_DIST += test_public_key_auth_succeeds_with_correct_ed25519_key_from_mem.c
|
||||
EXTRA_DIST += test_public_key_auth_succeeds_with_correct_rsa_openssh_key.c
|
||||
endif
|
||||
EXTRA_DIST = \
|
||||
CMakeLists.txt \
|
||||
etc/host \
|
||||
etc/host.pub \
|
||||
etc/user \
|
||||
etc/user.pub \
|
||||
key_dsa \
|
||||
key_dsa.pub \
|
||||
key_dsa_wrong \
|
||||
key_dsa_wrong.pub \
|
||||
key_ecdsa \
|
||||
key_ecdsa.pub \
|
||||
key_ed25519 \
|
||||
key_ed25519.pub \
|
||||
key_ed25519_encrypted \
|
||||
key_ed25519_encrypted.pub \
|
||||
key_rsa \
|
||||
key_rsa.pub \
|
||||
key_rsa_encrypted \
|
||||
key_rsa_encrypted.pub \
|
||||
key_rsa_openssh \
|
||||
key_rsa_openssh.pub \
|
||||
libssh2_config_cmake.h.in \
|
||||
mansyntax.sh \
|
||||
openssh_fixture.c \
|
||||
openssh_fixture.h \
|
||||
openssh_server/Dockerfile \
|
||||
openssh_server/authorized_keys \
|
||||
openssh_server/ca_ecdsa \
|
||||
openssh_server/ca_ecdsa.pub \
|
||||
openssh_server/ssh_host_ecdsa_key \
|
||||
openssh_server/ssh_host_ed25519_key \
|
||||
openssh_server/ssh_host_rsa_key \
|
||||
runner.c \
|
||||
session_fixture.c \
|
||||
session_fixture.h \
|
||||
simple.c \
|
||||
ssh2.c \
|
||||
ssh2.sh \
|
||||
sshd_fixture.sh.in \
|
||||
test_agent_forward_succeeds.c \
|
||||
test_hostkey.c \
|
||||
test_hostkey_hash.c \
|
||||
test_keyboard_interactive_auth_fails_with_wrong_response.c \
|
||||
test_keyboard_interactive_auth_succeeds_with_correct_response.c \
|
||||
test_password_auth_fails_with_wrong_password.c \
|
||||
test_password_auth_fails_with_wrong_username.c \
|
||||
test_password_auth_succeeds_with_correct_credentials.c \
|
||||
test_public_key_auth_fails_with_wrong_key.c \
|
||||
test_public_key_auth_succeeds_with_correct_dsa_key.c \
|
||||
test_public_key_auth_succeeds_with_correct_ed25519_key.c \
|
||||
test_public_key_auth_succeeds_with_correct_ed25519_key_from_mem.c \
|
||||
test_public_key_auth_succeeds_with_correct_ecdsa_key.c \
|
||||
test_public_key_auth_succeeds_with_correct_signed_ecdsa_key.c \
|
||||
test_public_key_auth_succeeds_with_correct_encrypted_ed25519_key.c \
|
||||
test_public_key_auth_succeeds_with_correct_encrypted_rsa_key.c \
|
||||
test_public_key_auth_succeeds_with_correct_rsa_key.c \
|
||||
test_public_key_auth_succeeds_with_correct_rsa_openssh_key.c
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
# Makefile.in generated by automake 1.16.1 from Makefile.am.
|
||||
# Makefile.in generated by automake 1.16.4 from Makefile.am.
|
||||
# @configure_input@
|
||||
|
||||
# Copyright (C) 1994-2018 Free Software Foundation, Inc.
|
||||
# Copyright (C) 1994-2021 Free Software Foundation, Inc.
|
||||
|
||||
# This Makefile.in is free software; the Free Software Foundation
|
||||
# gives unlimited permission to copy and/or distribute it,
|
||||
@@ -90,11 +90,6 @@ build_triplet = @build@
|
||||
host_triplet = @host@
|
||||
@SSHD_TRUE@noinst_PROGRAMS = ssh2$(EXEEXT)
|
||||
@SSHD_TRUE@am__append_1 = ssh2.sh
|
||||
# TODO: need to add a test for specific openssl version some how
|
||||
# EXTRA_DIST += test_public_key_auth_succeeds_with_correct_ed25519_key.c
|
||||
# EXTRA_DIST += test_public_key_auth_succeeds_with_correct_encrypted_ed25519_key.c
|
||||
# EXTRA_DIST += test_public_key_auth_succeeds_with_correct_ed25519_key_from_mem.c
|
||||
@OPENSSL_TRUE@am__append_2 = test_public_key_auth_succeeds_with_correct_rsa_openssh_key.c
|
||||
subdir = tests
|
||||
ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
|
||||
am__aclocal_m4_deps = $(top_srcdir)/m4/autobuild.m4 \
|
||||
@@ -107,8 +102,7 @@ am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
|
||||
$(ACLOCAL_M4)
|
||||
DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON)
|
||||
mkinstalldirs = $(install_sh) -d
|
||||
CONFIG_HEADER = $(top_builddir)/src/libssh2_config.h \
|
||||
$(top_builddir)/example/libssh2_config.h
|
||||
CONFIG_HEADER = $(top_builddir)/src/libssh2_config.h
|
||||
CONFIG_CLEAN_FILES =
|
||||
CONFIG_CLEAN_VPATH_FILES =
|
||||
PROGRAMS = $(noinst_PROGRAMS)
|
||||
@@ -137,7 +131,7 @@ AM_V_at = $(am__v_at_@AM_V@)
|
||||
am__v_at_ = $(am__v_at_@AM_DEFAULT_V@)
|
||||
am__v_at_0 = @
|
||||
am__v_at_1 =
|
||||
DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir)/src -I$(top_builddir)/example
|
||||
DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir)/src
|
||||
depcomp = $(SHELL) $(top_srcdir)/depcomp
|
||||
am__maybe_remake_depfiles = depfiles
|
||||
am__depfiles_remade = ./$(DEPDIR)/simple.Po ./$(DEPDIR)/ssh2.Po
|
||||
@@ -162,11 +156,27 @@ am__v_CCLD_0 = @echo " CCLD " $@;
|
||||
am__v_CCLD_1 =
|
||||
SOURCES = simple.c $(ssh2_SOURCES)
|
||||
DIST_SOURCES = simple.c $(am__ssh2_SOURCES_DIST)
|
||||
RECURSIVE_TARGETS = all-recursive check-recursive cscopelist-recursive \
|
||||
ctags-recursive dvi-recursive html-recursive info-recursive \
|
||||
install-data-recursive install-dvi-recursive \
|
||||
install-exec-recursive install-html-recursive \
|
||||
install-info-recursive install-pdf-recursive \
|
||||
install-ps-recursive install-recursive installcheck-recursive \
|
||||
installdirs-recursive pdf-recursive ps-recursive \
|
||||
tags-recursive uninstall-recursive
|
||||
am__can_run_installinfo = \
|
||||
case $$AM_UPDATE_INFO_DIR in \
|
||||
n|no|NO) false;; \
|
||||
*) (install-info --version) >/dev/null 2>&1;; \
|
||||
esac
|
||||
RECURSIVE_CLEAN_TARGETS = mostlyclean-recursive clean-recursive \
|
||||
distclean-recursive maintainer-clean-recursive
|
||||
am__recursive_targets = \
|
||||
$(RECURSIVE_TARGETS) \
|
||||
$(RECURSIVE_CLEAN_TARGETS) \
|
||||
$(am__extra_recursive_targets)
|
||||
AM_RECURSIVE_TARGETS = $(am__recursive_targets:-recursive=) TAGS CTAGS \
|
||||
check recheck distdir distdir-am
|
||||
am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP)
|
||||
# Read a list of newline-separated strings from the standard input,
|
||||
# and print each of them once, without duplicates. Input order is
|
||||
@@ -184,8 +194,6 @@ am__define_uniq_tagged_files = \
|
||||
unique=`for i in $$list; do \
|
||||
if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
|
||||
done | $(am__uniquify_input)`
|
||||
ETAGS = etags
|
||||
CTAGS = ctags
|
||||
am__tty_colors_dummy = \
|
||||
mgn= red= grn= lgn= blu= brg= std=; \
|
||||
am__color_tests=no
|
||||
@@ -368,8 +376,8 @@ am__set_TESTS_bases = \
|
||||
bases='$(TEST_LOGS)'; \
|
||||
bases=`for i in $$bases; do echo $$i; done | sed 's/\.log$$//'`; \
|
||||
bases=`echo $$bases`
|
||||
AM_TESTSUITE_SUMMARY_HEADER = ' for $(PACKAGE_STRING)'
|
||||
RECHECK_LOGS = $(TEST_LOGS)
|
||||
AM_RECURSIVE_TARGETS = check recheck
|
||||
TEST_SUITE_LOG = test-suite.log
|
||||
TEST_EXTENSIONS = @EXEEXT@ .test
|
||||
LOG_DRIVER = $(SHELL) $(top_srcdir)/test-driver
|
||||
@@ -390,9 +398,35 @@ TEST_LOGS = $(am__test_logs2:.test.log=.log)
|
||||
TEST_LOG_DRIVER = $(SHELL) $(top_srcdir)/test-driver
|
||||
TEST_LOG_COMPILE = $(TEST_LOG_COMPILER) $(AM_TEST_LOG_FLAGS) \
|
||||
$(TEST_LOG_FLAGS)
|
||||
DIST_SUBDIRS = $(SUBDIRS)
|
||||
am__DIST_COMMON = $(srcdir)/Makefile.in $(top_srcdir)/depcomp \
|
||||
$(top_srcdir)/test-driver
|
||||
DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
|
||||
am__relativize = \
|
||||
dir0=`pwd`; \
|
||||
sed_first='s,^\([^/]*\)/.*$$,\1,'; \
|
||||
sed_rest='s,^[^/]*/*,,'; \
|
||||
sed_last='s,^.*/\([^/]*\)$$,\1,'; \
|
||||
sed_butlast='s,/*[^/]*$$,,'; \
|
||||
while test -n "$$dir1"; do \
|
||||
first=`echo "$$dir1" | sed -e "$$sed_first"`; \
|
||||
if test "$$first" != "."; then \
|
||||
if test "$$first" = ".."; then \
|
||||
dir2=`echo "$$dir0" | sed -e "$$sed_last"`/"$$dir2"; \
|
||||
dir0=`echo "$$dir0" | sed -e "$$sed_butlast"`; \
|
||||
else \
|
||||
first2=`echo "$$dir2" | sed -e "$$sed_first"`; \
|
||||
if test "$$first2" = "$$first"; then \
|
||||
dir2=`echo "$$dir2" | sed -e "$$sed_rest"`; \
|
||||
else \
|
||||
dir2="../$$dir2"; \
|
||||
fi; \
|
||||
dir0="$$dir0"/"$$first"; \
|
||||
fi; \
|
||||
fi; \
|
||||
dir1=`echo "$$dir1" | sed -e "$$sed_rest"`; \
|
||||
done; \
|
||||
reldir="$$dir2"
|
||||
ACLOCAL = @ACLOCAL@
|
||||
ALLOCA = @ALLOCA@
|
||||
AMTAR = @AMTAR@
|
||||
@@ -408,6 +442,12 @@ CCDEPMODE = @CCDEPMODE@
|
||||
CFLAGS = @CFLAGS@
|
||||
CPP = @CPP@
|
||||
CPPFLAGS = @CPPFLAGS@
|
||||
CSCOPE = @CSCOPE@
|
||||
CTAGS = @CTAGS@
|
||||
CXX = @CXX@
|
||||
CXXCPP = @CXXCPP@
|
||||
CXXDEPMODE = @CXXDEPMODE@
|
||||
CXXFLAGS = @CXXFLAGS@
|
||||
CYGPATH_W = @CYGPATH_W@
|
||||
DEFS = @DEFS@
|
||||
DEPDIR = @DEPDIR@
|
||||
@@ -418,6 +458,7 @@ ECHO_C = @ECHO_C@
|
||||
ECHO_N = @ECHO_N@
|
||||
ECHO_T = @ECHO_T@
|
||||
EGREP = @EGREP@
|
||||
ETAGS = @ETAGS@
|
||||
EXEEXT = @EXEEXT@
|
||||
FGREP = @FGREP@
|
||||
GREP = @GREP@
|
||||
@@ -451,6 +492,7 @@ LIBSSL_PREFIX = @LIBSSL_PREFIX@
|
||||
LIBTOOL = @LIBTOOL@
|
||||
LIBZ = @LIBZ@
|
||||
LIBZ_PREFIX = @LIBZ_PREFIX@
|
||||
LIB_FUZZING_ENGINE = @LIB_FUZZING_ENGINE@
|
||||
LIPO = @LIPO@
|
||||
LN_S = @LN_S@
|
||||
LTLIBBCRYPT = @LTLIBBCRYPT@
|
||||
@@ -492,6 +534,7 @@ abs_top_builddir = @abs_top_builddir@
|
||||
abs_top_srcdir = @abs_top_srcdir@
|
||||
ac_ct_AR = @ac_ct_AR@
|
||||
ac_ct_CC = @ac_ct_CC@
|
||||
ac_ct_CXX = @ac_ct_CXX@
|
||||
ac_ct_DUMPBIN = @ac_ct_DUMPBIN@
|
||||
am__include = @am__include@
|
||||
am__leading_dot = @am__leading_dot@
|
||||
@@ -539,6 +582,7 @@ target_alias = @target_alias@
|
||||
top_build_prefix = @top_build_prefix@
|
||||
top_builddir = @top_builddir@
|
||||
top_srcdir = @top_srcdir@
|
||||
SUBDIRS = ossfuzz
|
||||
AM_CPPFLAGS = -I$(top_srcdir)/src -I$(top_srcdir)/include -I$(top_builddir)/src
|
||||
LDADD = ../src/libssh2.la
|
||||
@SSHD_TRUE@ssh2_SOURCES = ssh2.c
|
||||
@@ -547,25 +591,66 @@ TESTS = $(ctests) mansyntax.sh $(am__append_1)
|
||||
check_PROGRAMS = $(ctests)
|
||||
TESTS_ENVIRONMENT = SSHD=$(SSHD) EXEEXT=$(EXEEXT) \
|
||||
srcdir=$(top_srcdir)/tests builddir=$(top_builddir)/tests
|
||||
EXTRA_DIST = ssh2.sh mansyntax.sh etc/host etc/host.pub etc/user \
|
||||
etc/user.pub CMakeLists.txt libssh2_config_cmake.h.in \
|
||||
sshd_fixture.sh.in key_dsa key_dsa.pub key_dsa_wrong \
|
||||
key_dsa_wrong.pub key_rsa key_rsa.pub \
|
||||
openssh_server/authorized_keys openssh_server/Dockerfile \
|
||||
openssh_server/ssh_host_rsa_key openssh_fixture.c \
|
||||
openssh_fixture.h runner.c session_fixture.c session_fixture.h \
|
||||
test_hostkey.c test_hostkey_hash.c \
|
||||
test_keyboard_interactive_auth_fails_with_wrong_response.c \
|
||||
test_keyboard_interactive_auth_succeeds_with_correct_response.c \
|
||||
test_password_auth_fails_with_wrong_password.c \
|
||||
test_password_auth_fails_with_wrong_username.c \
|
||||
test_password_auth_succeeds_with_correct_credentials.c \
|
||||
test_public_key_auth_fails_with_wrong_key.c \
|
||||
test_public_key_auth_succeeds_with_correct_dsa_key.c \
|
||||
test_public_key_auth_succeeds_with_correct_rsa_key.c \
|
||||
test_public_key_auth_succeeds_with_correct_encrypted_rsa_key.c \
|
||||
$(am__append_2)
|
||||
all: all-am
|
||||
EXTRA_DIST = \
|
||||
CMakeLists.txt \
|
||||
etc/host \
|
||||
etc/host.pub \
|
||||
etc/user \
|
||||
etc/user.pub \
|
||||
key_dsa \
|
||||
key_dsa.pub \
|
||||
key_dsa_wrong \
|
||||
key_dsa_wrong.pub \
|
||||
key_ecdsa \
|
||||
key_ecdsa.pub \
|
||||
key_ed25519 \
|
||||
key_ed25519.pub \
|
||||
key_ed25519_encrypted \
|
||||
key_ed25519_encrypted.pub \
|
||||
key_rsa \
|
||||
key_rsa.pub \
|
||||
key_rsa_encrypted \
|
||||
key_rsa_encrypted.pub \
|
||||
key_rsa_openssh \
|
||||
key_rsa_openssh.pub \
|
||||
libssh2_config_cmake.h.in \
|
||||
mansyntax.sh \
|
||||
openssh_fixture.c \
|
||||
openssh_fixture.h \
|
||||
openssh_server/Dockerfile \
|
||||
openssh_server/authorized_keys \
|
||||
openssh_server/ca_ecdsa \
|
||||
openssh_server/ca_ecdsa.pub \
|
||||
openssh_server/ssh_host_ecdsa_key \
|
||||
openssh_server/ssh_host_ed25519_key \
|
||||
openssh_server/ssh_host_rsa_key \
|
||||
runner.c \
|
||||
session_fixture.c \
|
||||
session_fixture.h \
|
||||
simple.c \
|
||||
ssh2.c \
|
||||
ssh2.sh \
|
||||
sshd_fixture.sh.in \
|
||||
test_agent_forward_succeeds.c \
|
||||
test_hostkey.c \
|
||||
test_hostkey_hash.c \
|
||||
test_keyboard_interactive_auth_fails_with_wrong_response.c \
|
||||
test_keyboard_interactive_auth_succeeds_with_correct_response.c \
|
||||
test_password_auth_fails_with_wrong_password.c \
|
||||
test_password_auth_fails_with_wrong_username.c \
|
||||
test_password_auth_succeeds_with_correct_credentials.c \
|
||||
test_public_key_auth_fails_with_wrong_key.c \
|
||||
test_public_key_auth_succeeds_with_correct_dsa_key.c \
|
||||
test_public_key_auth_succeeds_with_correct_ed25519_key.c \
|
||||
test_public_key_auth_succeeds_with_correct_ed25519_key_from_mem.c \
|
||||
test_public_key_auth_succeeds_with_correct_ecdsa_key.c \
|
||||
test_public_key_auth_succeeds_with_correct_signed_ecdsa_key.c \
|
||||
test_public_key_auth_succeeds_with_correct_encrypted_ed25519_key.c \
|
||||
test_public_key_auth_succeeds_with_correct_encrypted_rsa_key.c \
|
||||
test_public_key_auth_succeeds_with_correct_rsa_key.c \
|
||||
test_public_key_auth_succeeds_with_correct_rsa_openssh_key.c
|
||||
|
||||
all: all-recursive
|
||||
|
||||
.SUFFIXES:
|
||||
.SUFFIXES: .c .lo .log .o .obj .test .test$(EXEEXT) .trs
|
||||
@@ -667,14 +752,61 @@ mostlyclean-libtool:
|
||||
clean-libtool:
|
||||
-rm -rf .libs _libs
|
||||
|
||||
# This directory's subdirectories are mostly independent; you can cd
|
||||
# into them and run 'make' without going through this Makefile.
|
||||
# To change the values of 'make' variables: instead of editing Makefiles,
|
||||
# (1) if the variable is set in 'config.status', edit 'config.status'
|
||||
# (which will cause the Makefiles to be regenerated when you run 'make');
|
||||
# (2) otherwise, pass the desired values on the 'make' command line.
|
||||
$(am__recursive_targets):
|
||||
@fail=; \
|
||||
if $(am__make_keepgoing); then \
|
||||
failcom='fail=yes'; \
|
||||
else \
|
||||
failcom='exit 1'; \
|
||||
fi; \
|
||||
dot_seen=no; \
|
||||
target=`echo $@ | sed s/-recursive//`; \
|
||||
case "$@" in \
|
||||
distclean-* | maintainer-clean-*) list='$(DIST_SUBDIRS)' ;; \
|
||||
*) list='$(SUBDIRS)' ;; \
|
||||
esac; \
|
||||
for subdir in $$list; do \
|
||||
echo "Making $$target in $$subdir"; \
|
||||
if test "$$subdir" = "."; then \
|
||||
dot_seen=yes; \
|
||||
local_target="$$target-am"; \
|
||||
else \
|
||||
local_target="$$target"; \
|
||||
fi; \
|
||||
($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \
|
||||
|| eval $$failcom; \
|
||||
done; \
|
||||
if test "$$dot_seen" = "no"; then \
|
||||
$(MAKE) $(AM_MAKEFLAGS) "$$target-am" || exit 1; \
|
||||
fi; test -z "$$fail"
|
||||
|
||||
ID: $(am__tagged_files)
|
||||
$(am__define_uniq_tagged_files); mkid -fID $$unique
|
||||
tags: tags-am
|
||||
tags: tags-recursive
|
||||
TAGS: tags
|
||||
|
||||
tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files)
|
||||
set x; \
|
||||
here=`pwd`; \
|
||||
if ($(ETAGS) --etags-include --version) >/dev/null 2>&1; then \
|
||||
include_option=--etags-include; \
|
||||
empty_fix=.; \
|
||||
else \
|
||||
include_option=--include; \
|
||||
empty_fix=; \
|
||||
fi; \
|
||||
list='$(SUBDIRS)'; for subdir in $$list; do \
|
||||
if test "$$subdir" = .; then :; else \
|
||||
test ! -f $$subdir/TAGS || \
|
||||
set "$$@" "$$include_option=$$here/$$subdir/TAGS"; \
|
||||
fi; \
|
||||
done; \
|
||||
$(am__define_uniq_tagged_files); \
|
||||
shift; \
|
||||
if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \
|
||||
@@ -687,7 +819,7 @@ tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files)
|
||||
$$unique; \
|
||||
fi; \
|
||||
fi
|
||||
ctags: ctags-am
|
||||
ctags: ctags-recursive
|
||||
|
||||
CTAGS: ctags
|
||||
ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files)
|
||||
@@ -700,7 +832,7 @@ GTAGS:
|
||||
here=`$(am__cd) $(top_builddir) && pwd` \
|
||||
&& $(am__cd) $(top_srcdir) \
|
||||
&& gtags -i $(GTAGS_ARGS) "$$here"
|
||||
cscopelist: cscopelist-am
|
||||
cscopelist: cscopelist-recursive
|
||||
|
||||
cscopelist-am: $(am__tagged_files)
|
||||
list='$(am__tagged_files)'; \
|
||||
@@ -826,7 +958,7 @@ $(TEST_SUITE_LOG): $(TEST_LOGS)
|
||||
test x"$$VERBOSE" = x || cat $(TEST_SUITE_LOG); \
|
||||
fi; \
|
||||
echo "$${col}$$br$${std}"; \
|
||||
echo "$${col}Testsuite summary for $(PACKAGE_STRING)$${std}"; \
|
||||
echo "$${col}Testsuite summary"$(AM_TESTSUITE_SUMMARY_HEADER)"$${std}"; \
|
||||
echo "$${col}$$br$${std}"; \
|
||||
create_testsuite_report --maybe-color; \
|
||||
echo "$$col$$br$$std"; \
|
||||
@@ -895,7 +1027,6 @@ ssh2.sh.log: ssh2.sh
|
||||
@am__EXEEXT_TRUE@ --log-file $$b.log --trs-file $$b.trs \
|
||||
@am__EXEEXT_TRUE@ $(am__common_driver_flags) $(AM_TEST_LOG_DRIVER_FLAGS) $(TEST_LOG_DRIVER_FLAGS) -- $(TEST_LOG_COMPILE) \
|
||||
@am__EXEEXT_TRUE@ "$$tst" $(AM_TESTS_FD_REDIRECT)
|
||||
|
||||
distdir: $(BUILT_SOURCES)
|
||||
$(MAKE) $(AM_MAKEFLAGS) distdir-am
|
||||
|
||||
@@ -929,21 +1060,47 @@ distdir-am: $(DISTFILES)
|
||||
|| exit 1; \
|
||||
fi; \
|
||||
done
|
||||
@list='$(DIST_SUBDIRS)'; for subdir in $$list; do \
|
||||
if test "$$subdir" = .; then :; else \
|
||||
$(am__make_dryrun) \
|
||||
|| test -d "$(distdir)/$$subdir" \
|
||||
|| $(MKDIR_P) "$(distdir)/$$subdir" \
|
||||
|| exit 1; \
|
||||
dir1=$$subdir; dir2="$(distdir)/$$subdir"; \
|
||||
$(am__relativize); \
|
||||
new_distdir=$$reldir; \
|
||||
dir1=$$subdir; dir2="$(top_distdir)"; \
|
||||
$(am__relativize); \
|
||||
new_top_distdir=$$reldir; \
|
||||
echo " (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) top_distdir="$$new_top_distdir" distdir="$$new_distdir" \\"; \
|
||||
echo " am__remove_distdir=: am__skip_length_check=: am__skip_mode_fix=: distdir)"; \
|
||||
($(am__cd) $$subdir && \
|
||||
$(MAKE) $(AM_MAKEFLAGS) \
|
||||
top_distdir="$$new_top_distdir" \
|
||||
distdir="$$new_distdir" \
|
||||
am__remove_distdir=: \
|
||||
am__skip_length_check=: \
|
||||
am__skip_mode_fix=: \
|
||||
distdir) \
|
||||
|| exit 1; \
|
||||
fi; \
|
||||
done
|
||||
check-am: all-am
|
||||
$(MAKE) $(AM_MAKEFLAGS) $(check_PROGRAMS)
|
||||
$(MAKE) $(AM_MAKEFLAGS) check-TESTS
|
||||
check: check-am
|
||||
check: check-recursive
|
||||
all-am: Makefile $(PROGRAMS)
|
||||
installdirs:
|
||||
install: install-am
|
||||
install-exec: install-exec-am
|
||||
install-data: install-data-am
|
||||
uninstall: uninstall-am
|
||||
installdirs: installdirs-recursive
|
||||
installdirs-am:
|
||||
install: install-recursive
|
||||
install-exec: install-exec-recursive
|
||||
install-data: install-data-recursive
|
||||
uninstall: uninstall-recursive
|
||||
|
||||
install-am: all-am
|
||||
@$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
|
||||
|
||||
installcheck: installcheck-am
|
||||
installcheck: installcheck-recursive
|
||||
install-strip:
|
||||
if test -z '$(STRIP)'; then \
|
||||
$(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
|
||||
@@ -968,83 +1125,84 @@ distclean-generic:
|
||||
maintainer-clean-generic:
|
||||
@echo "This command is intended for maintainers to use"
|
||||
@echo "it deletes files that may require special tools to rebuild."
|
||||
clean: clean-am
|
||||
clean: clean-recursive
|
||||
|
||||
clean-am: clean-checkPROGRAMS clean-generic clean-libtool \
|
||||
clean-noinstPROGRAMS mostlyclean-am
|
||||
|
||||
distclean: distclean-am
|
||||
distclean: distclean-recursive
|
||||
-rm -f ./$(DEPDIR)/simple.Po
|
||||
-rm -f ./$(DEPDIR)/ssh2.Po
|
||||
-rm -f Makefile
|
||||
distclean-am: clean-am distclean-compile distclean-generic \
|
||||
distclean-tags
|
||||
|
||||
dvi: dvi-am
|
||||
dvi: dvi-recursive
|
||||
|
||||
dvi-am:
|
||||
|
||||
html: html-am
|
||||
html: html-recursive
|
||||
|
||||
html-am:
|
||||
|
||||
info: info-am
|
||||
info: info-recursive
|
||||
|
||||
info-am:
|
||||
|
||||
install-data-am:
|
||||
|
||||
install-dvi: install-dvi-am
|
||||
install-dvi: install-dvi-recursive
|
||||
|
||||
install-dvi-am:
|
||||
|
||||
install-exec-am:
|
||||
|
||||
install-html: install-html-am
|
||||
install-html: install-html-recursive
|
||||
|
||||
install-html-am:
|
||||
|
||||
install-info: install-info-am
|
||||
install-info: install-info-recursive
|
||||
|
||||
install-info-am:
|
||||
|
||||
install-man:
|
||||
|
||||
install-pdf: install-pdf-am
|
||||
install-pdf: install-pdf-recursive
|
||||
|
||||
install-pdf-am:
|
||||
|
||||
install-ps: install-ps-am
|
||||
install-ps: install-ps-recursive
|
||||
|
||||
install-ps-am:
|
||||
|
||||
installcheck-am:
|
||||
|
||||
maintainer-clean: maintainer-clean-am
|
||||
maintainer-clean: maintainer-clean-recursive
|
||||
-rm -f ./$(DEPDIR)/simple.Po
|
||||
-rm -f ./$(DEPDIR)/ssh2.Po
|
||||
-rm -f Makefile
|
||||
maintainer-clean-am: distclean-am maintainer-clean-generic
|
||||
|
||||
mostlyclean: mostlyclean-am
|
||||
mostlyclean: mostlyclean-recursive
|
||||
|
||||
mostlyclean-am: mostlyclean-compile mostlyclean-generic \
|
||||
mostlyclean-libtool
|
||||
|
||||
pdf: pdf-am
|
||||
pdf: pdf-recursive
|
||||
|
||||
pdf-am:
|
||||
|
||||
ps: ps-am
|
||||
ps: ps-recursive
|
||||
|
||||
ps-am:
|
||||
|
||||
uninstall-am:
|
||||
|
||||
.MAKE: check-am install-am install-strip
|
||||
.MAKE: $(am__recursive_targets) check-am install-am install-strip
|
||||
|
||||
.PHONY: CTAGS GTAGS TAGS all all-am am--depfiles check check-TESTS \
|
||||
check-am clean clean-checkPROGRAMS clean-generic clean-libtool \
|
||||
.PHONY: $(am__recursive_targets) CTAGS GTAGS TAGS all all-am \
|
||||
am--depfiles check check-TESTS check-am clean \
|
||||
clean-checkPROGRAMS clean-generic clean-libtool \
|
||||
clean-noinstPROGRAMS cscopelist-am ctags ctags-am distclean \
|
||||
distclean-compile distclean-generic distclean-libtool \
|
||||
distclean-tags distdir dvi dvi-am html html-am info info-am \
|
||||
@@ -1053,10 +1211,10 @@ uninstall-am:
|
||||
install-html-am install-info install-info-am install-man \
|
||||
install-pdf install-pdf-am install-ps install-ps-am \
|
||||
install-strip installcheck installcheck-am installdirs \
|
||||
maintainer-clean maintainer-clean-generic mostlyclean \
|
||||
mostlyclean-compile mostlyclean-generic mostlyclean-libtool \
|
||||
pdf pdf-am ps ps-am recheck tags tags-am uninstall \
|
||||
uninstall-am
|
||||
installdirs-am maintainer-clean maintainer-clean-generic \
|
||||
mostlyclean mostlyclean-compile mostlyclean-generic \
|
||||
mostlyclean-libtool pdf pdf-am ps ps-am recheck tags tags-am \
|
||||
uninstall uninstall-am
|
||||
|
||||
.PRECIOUS: Makefile
|
||||
|
||||
|
||||
10
tests/key_ecdsa
Normal file
10
tests/key_ecdsa
Normal file
@@ -0,0 +1,10 @@
|
||||
-----BEGIN OPENSSH PRIVATE KEY-----
|
||||
b3BlbnNzaC1rZXktdjEAAAAABG5vbmUAAAAEbm9uZQAAAAAAAAABAAAAiAAAABNlY2RzYS
|
||||
1zaGEyLW5pc3RwMzg0AAAACG5pc3RwMzg0AAAAYQTosiScH/oRSazpIpPSEFcY4YVZyNby
|
||||
peARi49N3qy78OE118KGc5T8eifd+n1PSb7z8PnfDwOL4jBHxW5nWx0RCocIt7tb2a349J
|
||||
gfEl8PegHGcF/DwC+eesIKJvv0MfkAAADIKLgw6yi4MOsAAAATZWNkc2Etc2hhMi1uaXN0
|
||||
cDM4NAAAAAhuaXN0cDM4NAAAAGEE6LIknB/6EUms6SKT0hBXGOGFWcjW8qXgEYuPTd6su/
|
||||
DhNdfChnOU/Hon3fp9T0m+8/D53w8Di+IwR8VuZ1sdEQqHCLe7W9mt+PSYHxJfD3oBxnBf
|
||||
w8AvnnrCCib79DH5AAAAMGYdHu+u2/L8zC/0S9bao9y6vKiLSuTEfZpCIsyE5jWj/vrS0n
|
||||
r1lzv9kKj+5A86aQAAAAA=
|
||||
-----END OPENSSH PRIVATE KEY-----
|
||||
1
tests/key_ecdsa.pub
Normal file
1
tests/key_ecdsa.pub
Normal file
@@ -0,0 +1 @@
|
||||
ecdsa-sha2-nistp384 AAAAE2VjZHNhLXNoYTItbmlzdHAzODQAAAAIbmlzdHAzODQAAABhBOiyJJwf+hFJrOkik9IQVxjhhVnI1vKl4BGLj03erLvw4TXXwoZzlPx6J936fU9JvvPw+d8PA4viMEfFbmdbHREKhwi3u1vZrfj0mB8SXw96AcZwX8PAL556wgom+/Qx+Q==
|
||||
7
tests/key_ed25519
Normal file
7
tests/key_ed25519
Normal file
@@ -0,0 +1,7 @@
|
||||
-----BEGIN OPENSSH PRIVATE KEY-----
|
||||
b3BlbnNzaC1rZXktdjEAAAAABG5vbmUAAAAEbm9uZQAAAAAAAAABAAAAMwAAAAtzc2gtZW
|
||||
QyNTUxOQAAACCMbXcoNmUVxO9FMMj1VB91MnwwVfBl+XDxet+j+oY6JgAAAJg8nvUxPJ71
|
||||
MQAAAAtzc2gtZWQyNTUxOQAAACCMbXcoNmUVxO9FMMj1VB91MnwwVfBl+XDxet+j+oY6Jg
|
||||
AAAECnhCuTDYdz3kUn48BXkaCXXdbKdH7wSIQ/CUx1cbnR0Ixtdyg2ZRXE70UwyPVUH3Uy
|
||||
fDBV8GX5cPF636P6hjomAAAAEHdpbGxAaUN1YmUubG9jYWwBAgMEBQ==
|
||||
-----END OPENSSH PRIVATE KEY-----
|
||||
1
tests/key_ed25519.pub
Normal file
1
tests/key_ed25519.pub
Normal file
@@ -0,0 +1 @@
|
||||
ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIIxtdyg2ZRXE70UwyPVUH3UyfDBV8GX5cPF636P6hjom
|
||||
8
tests/key_ed25519_encrypted
Normal file
8
tests/key_ed25519_encrypted
Normal file
@@ -0,0 +1,8 @@
|
||||
-----BEGIN OPENSSH PRIVATE KEY-----
|
||||
b3BlbnNzaC1rZXktdjEAAAAACmFlczI1Ni1jdHIAAAAGYmNyeXB0AAAAGAAAABD4qdu8J/
|
||||
EAqXFQERrvzMerAAAAEAAAAAEAAAAzAAAAC3NzaC1lZDI1NTE5AAAAICHxEyUTOVHXvdMF
|
||||
ARedFQ+H9DW/n8Zy3daKKRqnTDMqAAAAoO05oxXUkLz8cMQcMeeRSc4UvsaWnCvfN4Qm15
|
||||
NaVwSjb/09AcGGVeF1xxwPEIjwsIRftAjjgLuauI6XpXzyeDOlr2HnwzgpZtmeaHzbB7lS
|
||||
NjpSENP+fXipXinSfgZqGOItPbbismEVWX4sQn/Zla6/f/JAcDV60TK2ZhVEZ5072t0NcA
|
||||
eZQeSzBnpoRhlB7IDO7/7pmu1kNysUzH94Bw8=
|
||||
-----END OPENSSH PRIVATE KEY-----
|
||||
1
tests/key_ed25519_encrypted.pub
Normal file
1
tests/key_ed25519_encrypted.pub
Normal file
@@ -0,0 +1 @@
|
||||
ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAICHxEyUTOVHXvdMFARedFQ+H9DW/n8Zy3daKKRqnTDMq
|
||||
30
tests/key_rsa_encrypted
Normal file
30
tests/key_rsa_encrypted
Normal file
@@ -0,0 +1,30 @@
|
||||
-----BEGIN RSA PRIVATE KEY-----
|
||||
Proc-Type: 4,ENCRYPTED
|
||||
DEK-Info: AES-128-CBC,E030CC29AE4C20669EE41DF3DE4C0886
|
||||
|
||||
gLMMWawVUpqtAtpSVnr7HcH+P0gHKFU00hUhNY18TNJRfFIhPqc9R9xsLHgBac7k
|
||||
vHtD2nzUuWLVMIKQoS3+1IF/KO6Xj1zSqnyk49hyKWxFiD3U1YdZAiZNgJ/s6olg
|
||||
J/h4mNNsz8Nh6Swp3HwP2jtLHWHV8fOzsaE3dvnVYZ5gPnec7XAYcQycbOV0t2Wd
|
||||
NGlP09ooAQRWWuf1TaBewjj7Jm40l8OQat5EKZKzydUZZQYAqfJQ7fIw7jI/lQYF
|
||||
KJj9tq0ceFdxvk8LYMr5a+ixnDwirxgg4L0X3fjLocfLVt42qDKkfOGXGg9VI8CO
|
||||
gjTu/MbodGCWKe/5eeCSSLrKo486S/5B6RzN0Ax4QBb1iYAN5IECsV91Ekk0socY
|
||||
DBZmDMEGHppHJhNhbBzfMYeKssWbOQf9z0y+gDPesImV2gXNoMgTcmZrCLOJWj6L
|
||||
ifQAtTKc8P5fV+TLhg3dKmxCt1UMlCHpWWl7tPTsO3WaaXi50f9ypRfpbpH0hket
|
||||
SO//bZqF0lF+Ci8uC6ndXBniIfinFoMWPsY01bxyHvmEMwCTVApZEkrZtGlHnavy
|
||||
d2oYJ0Oc+eeSjnx2BccQ9GdoI3292CVJVgPiibr42updecFwTry+j//IY8H3d62m
|
||||
UYUXJQgIL04o2/1UIT0mPWwPigF3sJSZOwT5arn4MgUyBCC18p6OTmGmvIyrz3YB
|
||||
imbhndok/30sMwtJocgXKTdyreMUp0s8Hpw/2z4LQ0qlOstKwa8KnDcFAqaSFNGD
|
||||
8tGTobAcGRhqq93PRrn3aRibk1T3KDpMF/oqRaajgBmXFVYOk1yuLy6meB+wAJFD
|
||||
VVIokZaygYs13SMX+hau0Gd6PmVh8QF0RmvG69ga7k4dfJMbe2uU59wf9uABmyvd
|
||||
+Ju+uXGiF0wYfcyv6HJarPIqA3630TPKR/z8dDWC3rJ83xx7hIpoEAA+b7RA3Vtx
|
||||
Gv0EoDK6zeq4UJK0tqxMZJuy+FHBDZhv+gAeB/PmIGPIbF+jV+flmCrUgHg2Ka8I
|
||||
Iaap+lQKMj5lzOv/1bbcZ6cpj717MGvo3XOwOD4x5b3wRX6DWphB0+oRWiVU3Vrd
|
||||
PiZ0gtlX31Rj+h+QB4DrMKZWMu++qEDF6NPLz2ktNcjOYBT29VVqX8ALKKFO+jOK
|
||||
ZASnUXXE3XnwbccwU9VIQ+3mom3K+GjJRGxsWNZsrPy364eQHckomcOptgk5ldI1
|
||||
eF7t5w0xQ4hx6jrJBcKJL29SQAcmUO+vu+6Vg6synBpnlqM9mSe8Xlo3SQ9bROJ9
|
||||
1unhrml0Jr1tJZfbM/kX7xhFUVc2kQHqYz6pwYl3fYceHk5dVj9IWaJj82Sfi1QQ
|
||||
il3DQb9t3y4oJcYQxR9OzyjiKPiCAkIDakYshZP/bb/ZfDy1szIIL0e3mKLUcdFc
|
||||
3sqAvcBsPt+SngnTtodkAK1ddTuxjHUN3+XpIAUoNtqv02g47JCmvSQ0NGsPyXIz
|
||||
2krWQoMlmYaG3N74ybMajTXW3Y8+wbe5moJ+Yt4bPUo61d8rMOVI/+3lU7YIyUj1
|
||||
TqbwgHCvZRvaiXJQbC9lP7mbQipQhtwQgGMw9TdQB/oHldmDNETF4eNX11LC73+G
|
||||
-----END RSA PRIVATE KEY-----
|
||||
1
tests/key_rsa_encrypted.pub
Normal file
1
tests/key_rsa_encrypted.pub
Normal file
@@ -0,0 +1 @@
|
||||
ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQC92YlGoc4PJy6DzX916JJZhxkvmkWBLGJdWOL7R9B6iaYEKebBxzTE3P1RcnxnuI06kklVq/KcDP9sLlgawTZcDg7ifM7HncPOi18OON8vvVVzodikHzuupjhpI5YTT9wwV2fDVi2URsBjvX4AFiZ5WM3/NwqdKpYABzWieBikXGJ58Tsnw+zQw2qMmKKESBuzSN538loTAj5iEH/GAKYDbbH9t2a17qhNCNEw4vrtURT9JqwO1cOg7N1OKpmqCPEbK0wuSTljNC230VJ06X/8UqahWWSH6MreGy6gwpPi6i9wFiFLur301R0dTPiKVhz6bguhcC1EAlhSgjfelFJt awl03@bounty
|
||||
27
tests/key_rsa_openssh
Normal file
27
tests/key_rsa_openssh
Normal file
@@ -0,0 +1,27 @@
|
||||
-----BEGIN OPENSSH PRIVATE KEY-----
|
||||
b3BlbnNzaC1rZXktdjEAAAAABG5vbmUAAAAEbm9uZQAAAAAAAAABAAABFwAAAAdzc2gtcn
|
||||
NhAAAAAwEAAQAAAQEA03tZTdi/8nrdDGtSc15EH97dX/qWrgC3nNhbBmcvOykSVtQDsXE0
|
||||
4nj45RcD9cn0itZVl0Prn9G+tYJCqqkedhQ5MtuByVrmJX15REDJ9nfzzQzVQw2zuE1ysj
|
||||
ccVBxSeqmDDXeJFozh/uq5mKFirFlft5g0Wx2oG1TxGC/MHqfDk6ijqq7lS1T82cmGZAbZ
|
||||
+FzhYulBPFioklXStQJtTuVMb5Q/ebd9nmHIesEPWs4DKo2urKXvy+VCYD/N0GRZJ1Qt8D
|
||||
2VpI6qJlRapdBaWkHJRDcMmPzmTMa9HE/3+2wi+rOAP9V6W7BpgtMWpOP0xx2zp/tC3SHo
|
||||
9pxlfCRaEQAAA8gL9Cg6C/QoOgAAAAdzc2gtcnNhAAABAQDTe1lN2L/yet0Ma1JzXkQf3t
|
||||
1f+pauALec2FsGZy87KRJW1AOxcTTiePjlFwP1yfSK1lWXQ+uf0b61gkKqqR52FDky24HJ
|
||||
WuYlfXlEQMn2d/PNDNVDDbO4TXKyNxxUHFJ6qYMNd4kWjOH+6rmYoWKsWV+3mDRbHagbVP
|
||||
EYL8wep8OTqKOqruVLVPzZyYZkBtn4XOFi6UE8WKiSVdK1Am1O5UxvlD95t32eYch6wQ9a
|
||||
zgMqja6spe/L5UJgP83QZFknVC3wPZWkjqomVFql0FpaQclENwyY/OZMxr0cT/f7bCL6s4
|
||||
A/1XpbsGmC0xak4/THHbOn+0LdIej2nGV8JFoRAAAAAwEAAQAAAQAykM27lVXf7oyoCYk/
|
||||
WIzFag5YgpxAop9Ee17YWxep95oQ9MSlSsIwXGh2rlgeDtnP0IvKjUzre8UztR+nmqRT62
|
||||
X5yQ5xTLC2yheSwEMKEYhTwPvE+qO8L5h7ED5Pxi3acmmJcMlwgOMQhqM14XCscPo39cae
|
||||
+qpVTqwO8m7F7Tu/GCQWKTDE6FekoX13/bYbnsgd7FZGTyc37rQ2kuergYeIRewrdTD3JB
|
||||
ne6LmRVbMEuGh9WbXfXFLr+5p79xgnTPs+whdoyQTY8+O3052D8yMV7UcU+T9A0zHFyU9E
|
||||
VT/SvTgMTF7icThTtVR6Vn095ahe77wh363N0JEe1rwBAAAAgQCSqhkKVowJSPw+Ho6PNk
|
||||
lKcXWCutA8sVg+x+MaIdnzTe9TbxItm/XW4zj1Ax1rJeEgAaCKQVwH5oJDeC3awNZZ5ZY9
|
||||
GK6h4ueyolzVP5wwalR9HeY/S+wdRgaIvYmIpHewLAj/o5ykE2Ijzgf3+HdaNlRxwWXz1i
|
||||
8ArMV1AwB8WwAAAIEA75OHcAo8RUM7EoU165FZp7nqBphKuGMb8Os/p2xbNC8MYz5CyDXy
|
||||
fzYZC3i67uGXyTTVLtl54+kzuciuZ/qLHJT49JY/AtOm+rmpXKACNQIZeEnCML8AewLDEg
|
||||
ugXuFCMIFR4/fupCjGv/tTVHvsh6LJ/td3+DQmisVG3uDnGDEAAACBAOH6xeQ5Z/VPFV1b
|
||||
+ZxutTMjFghLce50L6fSHpBbIN00vS+9I4TmXYI1XFvaFjHShYUrFifWiMFGBNjuoqRY+c
|
||||
9/8UDvptdiXLqqLkw3SNB/UqUQRtZkD384Eazxud+FMfMguFBrgmkWYwAh9EVAzXrbzxQd
|
||||
U9To5SerEitsWsfhAAAAEHdpbGxAaUN1YmUubG9jYWwBAg==
|
||||
-----END OPENSSH PRIVATE KEY-----
|
||||
1
tests/key_rsa_openssh.pub
Normal file
1
tests/key_rsa_openssh.pub
Normal file
@@ -0,0 +1 @@
|
||||
ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQDTe1lN2L/yet0Ma1JzXkQf3t1f+pauALec2FsGZy87KRJW1AOxcTTiePjlFwP1yfSK1lWXQ+uf0b61gkKqqR52FDky24HJWuYlfXlEQMn2d/PNDNVDDbO4TXKyNxxUHFJ6qYMNd4kWjOH+6rmYoWKsWV+3mDRbHagbVPEYL8wep8OTqKOqruVLVPzZyYZkBtn4XOFi6UE8WKiSVdK1Am1O5UxvlD95t32eYch6wQ9azgMqja6spe/L5UJgP83QZFknVC3wPZWkjqomVFql0FpaQclENwyY/OZMxr0cT/f7bCL6s4A/1XpbsGmC0xak4/THHbOn+0LdIej2nGV8JFoR will@iCube.local
|
||||
@@ -62,10 +62,12 @@
|
||||
static int run_command_varg(char **output, const char *command, va_list args)
|
||||
{
|
||||
FILE *pipe;
|
||||
char redirect_stderr[] = "%s 2>&1";
|
||||
char command_buf[BUFSIZ];
|
||||
char buf[BUFSIZ];
|
||||
char *p;
|
||||
int ret;
|
||||
size_t buf_len;
|
||||
|
||||
if(output) {
|
||||
*output = NULL;
|
||||
}
|
||||
@@ -78,26 +80,33 @@ static int run_command_varg(char **output, const char *command, va_list args)
|
||||
}
|
||||
|
||||
/* Rewrite the command to redirect stderr to stdout to we can output it */
|
||||
if(strlen(command_buf) + 6 >= sizeof(command_buf)) {
|
||||
if(strlen(command_buf) + strlen(redirect_stderr) >= sizeof(buf)) {
|
||||
fprintf(stderr, "Unable to rewrite command (%s)\n", command);
|
||||
return -1;
|
||||
}
|
||||
|
||||
strncat(command_buf, " 2>&1", 6);
|
||||
ret = snprintf(buf, sizeof(buf), redirect_stderr, command_buf);
|
||||
if(ret < 0 || ret >= BUFSIZ) {
|
||||
fprintf(stderr, "Unable to rewrite command (%s)\n", command);
|
||||
return -1;
|
||||
}
|
||||
|
||||
fprintf(stdout, "Command: %s\n", command);
|
||||
#ifdef WIN32
|
||||
pipe = _popen(command_buf, "r");
|
||||
pipe = _popen(buf, "r");
|
||||
#else
|
||||
pipe = popen(command_buf, "r");
|
||||
pipe = popen(buf, "r");
|
||||
#endif
|
||||
if(!pipe) {
|
||||
fprintf(stderr, "Unable to execute command '%s'\n", command);
|
||||
return -1;
|
||||
}
|
||||
p = buf;
|
||||
while(fgets(p, sizeof(buf) - (p - buf), pipe) != NULL)
|
||||
;
|
||||
buf[0] = 0;
|
||||
buf_len = 0;
|
||||
while(buf_len < (sizeof(buf) - 1) &&
|
||||
fgets(&buf[buf_len], sizeof(buf) - buf_len, pipe) != NULL) {
|
||||
buf_len = strlen(buf);
|
||||
}
|
||||
|
||||
#ifdef WIN32
|
||||
ret = _pclose(pipe);
|
||||
@@ -112,9 +121,9 @@ static int run_command_varg(char **output, const char *command, va_list args)
|
||||
if(output) {
|
||||
/* command output may contain a trailing newline, so we trim
|
||||
* whitespace here */
|
||||
size_t end = strlen(buf) - 1;
|
||||
while(end > 0 && isspace(buf[end])) {
|
||||
buf[end] = '\0';
|
||||
size_t end = strlen(buf);
|
||||
while(end > 0 && isspace(buf[end - 1])) {
|
||||
buf[end - 1] = '\0';
|
||||
}
|
||||
|
||||
*output = strdup(buf);
|
||||
@@ -134,16 +143,31 @@ static int run_command(char **output, const char *command, ...)
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int build_openssh_server_docker_image()
|
||||
static int build_openssh_server_docker_image(void)
|
||||
{
|
||||
return run_command(NULL, "docker build -t libssh2/openssh_server openssh_server");
|
||||
return run_command(NULL, "docker build -t libssh2/openssh_server "
|
||||
"openssh_server");
|
||||
}
|
||||
|
||||
static const char *openssh_server_port(void)
|
||||
{
|
||||
return getenv("OPENSSH_SERVER_PORT");
|
||||
}
|
||||
|
||||
static int start_openssh_server(char **container_id_out)
|
||||
{
|
||||
return run_command(container_id_out,
|
||||
"docker run --detach -P libssh2/openssh_server"
|
||||
);
|
||||
const char *container_host_port = openssh_server_port();
|
||||
if(container_host_port != NULL) {
|
||||
return run_command(container_id_out,
|
||||
"docker run --rm -d -p %s:22 "
|
||||
"libssh2/openssh_server",
|
||||
container_host_port);
|
||||
}
|
||||
else {
|
||||
return run_command(container_id_out,
|
||||
"docker run --rm -d -p 22 "
|
||||
"libssh2/openssh_server");
|
||||
}
|
||||
}
|
||||
|
||||
static int stop_openssh_server(char *container_id)
|
||||
@@ -151,11 +175,48 @@ static int stop_openssh_server(char *container_id)
|
||||
return run_command(NULL, "docker stop %s", container_id);
|
||||
}
|
||||
|
||||
static const char *docker_machine_name()
|
||||
static const char *docker_machine_name(void)
|
||||
{
|
||||
return getenv("DOCKER_MACHINE_NAME");
|
||||
}
|
||||
|
||||
static int is_running_inside_a_container()
|
||||
{
|
||||
#ifdef WIN32
|
||||
return 0;
|
||||
#else
|
||||
const char *cgroup_filename = "/proc/self/cgroup";
|
||||
FILE *f = NULL;
|
||||
char *line = NULL;
|
||||
size_t len = 0;
|
||||
ssize_t read = 0;
|
||||
int found = 0;
|
||||
f = fopen(cgroup_filename, "r");
|
||||
if(f == NULL) {
|
||||
/* Don't go further, we are not in a container */
|
||||
return 0;
|
||||
}
|
||||
while((read = getline(&line, &len, f)) != -1) {
|
||||
if(strstr(line, "docker") != NULL) {
|
||||
found = 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
fclose(f);
|
||||
free(line);
|
||||
return found;
|
||||
#endif
|
||||
}
|
||||
|
||||
static unsigned int portable_sleep(unsigned int seconds)
|
||||
{
|
||||
#ifdef WIN32
|
||||
Sleep(seconds);
|
||||
#else
|
||||
sleep(seconds);
|
||||
#endif
|
||||
}
|
||||
|
||||
static int ip_address_from_container(char *container_id, char **ip_address_out)
|
||||
{
|
||||
const char *active_docker_machine = docker_machine_name();
|
||||
@@ -167,9 +228,12 @@ static int ip_address_from_container(char *container_id, char **ip_address_out)
|
||||
int attempt_no = 0;
|
||||
int wait_time = 500;
|
||||
for(;;) {
|
||||
return run_command(ip_address_out, "docker-machine ip %s", active_docker_machine);
|
||||
|
||||
if(attempt_no > 5) {
|
||||
int ret = run_command(ip_address_out, "docker-machine ip %s",
|
||||
active_docker_machine);
|
||||
if(ret == 0) {
|
||||
return 0;
|
||||
}
|
||||
else if(attempt_no > 5) {
|
||||
fprintf(
|
||||
stderr,
|
||||
"Unable to get IP from docker-machine after %d attempts\n",
|
||||
@@ -177,35 +241,44 @@ static int ip_address_from_container(char *container_id, char **ip_address_out)
|
||||
return -1;
|
||||
}
|
||||
else {
|
||||
#ifdef WIN32
|
||||
#pragma warning(push)
|
||||
#pragma warning(disable : 4996)
|
||||
_sleep(wait_time);
|
||||
#pragma warning(pop)
|
||||
#else
|
||||
sleep(wait_time);
|
||||
#endif
|
||||
portable_sleep(wait_time);
|
||||
++attempt_no;
|
||||
wait_time *= 2;
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
return run_command(ip_address_out,
|
||||
"docker inspect --format "
|
||||
"\"{{ index (index (index .NetworkSettings.Ports "
|
||||
"\\\"22/tcp\\\") 0) \\\"HostIp\\\" }}\" %s",
|
||||
container_id);
|
||||
if(is_running_inside_a_container()) {
|
||||
return run_command(ip_address_out,
|
||||
"docker inspect --format "
|
||||
"\"{{ .NetworkSettings.IPAddress }}\""
|
||||
" %s",
|
||||
container_id);
|
||||
}
|
||||
else {
|
||||
return run_command(ip_address_out,
|
||||
"docker inspect --format "
|
||||
"\"{{ index (index (index "
|
||||
".NetworkSettings.Ports "
|
||||
"\\\"22/tcp\\\") 0) \\\"HostIp\\\" }}\" %s",
|
||||
container_id);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static int port_from_container(char *container_id, char **port_out)
|
||||
{
|
||||
return run_command(port_out,
|
||||
"docker inspect --format "
|
||||
"\"{{ index (index (index .NetworkSettings.Ports "
|
||||
"\\\"22/tcp\\\") 0) \\\"HostPort\\\" }}\" %s",
|
||||
container_id);
|
||||
if(is_running_inside_a_container()) {
|
||||
*port_out = strdup("22");
|
||||
return 0;
|
||||
}
|
||||
else {
|
||||
return run_command(port_out,
|
||||
"docker inspect --format "
|
||||
"\"{{ index (index (index .NetworkSettings.Ports "
|
||||
"\\\"22/tcp\\\") 0) \\\"HostPort\\\" }}\" %s",
|
||||
container_id);
|
||||
}
|
||||
}
|
||||
|
||||
static int open_socket_to_container(char *container_id)
|
||||
@@ -215,20 +288,31 @@ static int open_socket_to_container(char *container_id)
|
||||
unsigned long hostaddr;
|
||||
int sock;
|
||||
struct sockaddr_in sin;
|
||||
int counter = 0;
|
||||
|
||||
int ret = ip_address_from_container(container_id, &ip_address);
|
||||
if(ret != 0) {
|
||||
fprintf(stderr, "Failed to get IP address for container %s\n", container_id);
|
||||
fprintf(stderr, "Failed to get IP address for container %s\n",
|
||||
container_id);
|
||||
ret = -1;
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
ret = port_from_container(container_id, &port_string);
|
||||
if(ret != 0) {
|
||||
fprintf(stderr, "Failed to get port for container %s\n", container_id);
|
||||
fprintf(stderr, "Failed to get port for container %s\n",
|
||||
container_id);
|
||||
ret = -1;
|
||||
}
|
||||
|
||||
/* 0.0.0.0 is returned by Docker for Windows, because the container
|
||||
is reachable from anywhere. But we cannot connect to 0.0.0.0,
|
||||
instead we assume localhost and try to connect to 127.0.0.1. */
|
||||
if(ip_address && strcmp(ip_address, "0.0.0.0") == 0) {
|
||||
free(ip_address);
|
||||
ip_address = strdup("127.0.0.1");
|
||||
}
|
||||
|
||||
hostaddr = inet_addr(ip_address);
|
||||
if(hostaddr == (unsigned long)(-1)) {
|
||||
fprintf(stderr, "Failed to convert %s host address\n", ip_address);
|
||||
@@ -247,15 +331,26 @@ static int open_socket_to_container(char *container_id)
|
||||
sin.sin_port = htons((short)strtol(port_string, NULL, 0));
|
||||
sin.sin_addr.s_addr = hostaddr;
|
||||
|
||||
if(connect(sock, (struct sockaddr *)(&sin),
|
||||
sizeof(struct sockaddr_in)) != 0) {
|
||||
fprintf(stderr, "Failed to connect to %s:%s\n", ip_address, port_string);
|
||||
ret = -1;
|
||||
for(counter = 0; counter < 3; ++counter) {
|
||||
if(connect(sock, (struct sockaddr *)(&sin),
|
||||
sizeof(struct sockaddr_in)) != 0) {
|
||||
ret = -1;
|
||||
fprintf(stderr,
|
||||
"Connection to %s:%s attempt #%d failed: retrying...\n",
|
||||
ip_address, port_string, counter);
|
||||
portable_sleep(1 + 2*counter);
|
||||
}
|
||||
else {
|
||||
ret = sock;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if(ret == -1) {
|
||||
fprintf(stderr, "Failed to connect to %s:%s\n",
|
||||
ip_address, port_string);
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
ret = sock;
|
||||
|
||||
cleanup:
|
||||
free(ip_address);
|
||||
free(port_string);
|
||||
|
||||
@@ -58,10 +58,19 @@ COPY ssh_host_ed25519_key /tmp/etc/ssh/ssh_host_ed25519_key
|
||||
RUN mv /tmp/etc/ssh/ssh_host_ed25519_key /etc/ssh/ssh_host_ed25519_key
|
||||
RUN chmod 600 /etc/ssh/ssh_host_ed25519_key
|
||||
|
||||
COPY ca_ecdsa.pub /tmp/etc/ssh/ca_ecdsa.pub
|
||||
RUN mv /tmp/etc/ssh/ca_ecdsa.pub /etc/ssh/ca_ecdsa.pub
|
||||
RUN chmod 600 /etc/ssh/ca_ecdsa.pub
|
||||
|
||||
COPY ca_ecdsa /tmp/etc/ssh/ca_ecdsa
|
||||
RUN mv /tmp/etc/ssh/ca_ecdsa /etc/ssh/ca_ecdsa
|
||||
RUN chmod 600 /etc/ssh/ca_ecdsa
|
||||
|
||||
RUN adduser --disabled-password --gecos 'Test user for libssh2 integration tests' libssh2
|
||||
RUN echo 'libssh2:my test password' | chpasswd
|
||||
|
||||
RUN sed -i 's/ChallengeResponseAuthentication no/ChallengeResponseAuthentication yes/' /etc/ssh/sshd_config
|
||||
RUN echo "TrustedUserCAKeys /etc/ssh/ca_ecdsa.pub" >> /etc/ssh/sshd_config
|
||||
|
||||
# SSH login fix. Otherwise user is kicked off after login
|
||||
RUN sed 's@session\s*required\s*pam_loginuid.so@session optional pam_loginuid.so@g' -i /etc/pam.d/sshd
|
||||
|
||||
@@ -4,3 +4,4 @@ ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQC92YlGoc4PJy6DzX916JJZhxkvmkWBLGJdWOL7R9B6
|
||||
ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQDTe1lN2L/yet0Ma1JzXkQf3t1f+pauALec2FsGZy87KRJW1AOxcTTiePjlFwP1yfSK1lWXQ+uf0b61gkKqqR52FDky24HJWuYlfXlEQMn2d/PNDNVDDbO4TXKyNxxUHFJ6qYMNd4kWjOH+6rmYoWKsWV+3mDRbHagbVPEYL8wep8OTqKOqruVLVPzZyYZkBtn4XOFi6UE8WKiSVdK1Am1O5UxvlD95t32eYch6wQ9azgMqja6spe/L5UJgP83QZFknVC3wPZWkjqomVFql0FpaQclENwyY/OZMxr0cT/f7bCL6s4A/1XpbsGmC0xak4/THHbOn+0LdIej2nGV8JFoR
|
||||
ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIIxtdyg2ZRXE70UwyPVUH3UyfDBV8GX5cPF636P6hjom
|
||||
ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAICHxEyUTOVHXvdMFARedFQ+H9DW/n8Zy3daKKRqnTDMq
|
||||
ecdsa-sha2-nistp384 AAAAE2VjZHNhLXNoYTItbmlzdHAzODQAAAAIbmlzdHAzODQAAABhBOiyJJwf+hFJrOkik9IQVxjhhVnI1vKl4BGLj03erLvw4TXXwoZzlPx6J936fU9JvvPw+d8PA4viMEfFbmdbHREKhwi3u1vZrfj0mB8SXw96AcZwX8PAL556wgom+/Qx+Q==
|
||||
|
||||
12
tests/openssh_server/ca_ecdsa
Normal file
12
tests/openssh_server/ca_ecdsa
Normal file
@@ -0,0 +1,12 @@
|
||||
-----BEGIN OPENSSH PRIVATE KEY-----
|
||||
b3BlbnNzaC1rZXktdjEAAAAABG5vbmUAAAAEbm9uZQAAAAAAAAABAAAArAAAABNlY2RzYS
|
||||
1zaGEyLW5pc3RwNTIxAAAACG5pc3RwNTIxAAAAhQQAfv15s+G2xg56J+audKAM4G9qOTFr
|
||||
bZRo0CTwvkb/oHrf9/2RSWqYsx/0m5mYCZVlecnZqwRHAOolXbc/Yb4cGjsALUj3UDirsn
|
||||
YR7Ve+SwnunkpvW/H3a98sA3sS+HCpd5RbpfWClSBOI9JEAlPtS1CrEQ7EmO7hmlFOH2cL
|
||||
0qfHCyYAAAEA763VSe+t1UkAAAATZWNkc2Etc2hhMi1uaXN0cDUyMQAAAAhuaXN0cDUyMQ
|
||||
AAAIUEAH79ebPhtsYOeifmrnSgDOBvajkxa22UaNAk8L5G/6B63/f9kUlqmLMf9JuZmAmV
|
||||
ZXnJ2asERwDqJV23P2G+HBo7AC1I91A4q7J2Ee1XvksJ7p5Kb1vx92vfLAN7EvhwqXeUW6
|
||||
X1gpUgTiPSRAJT7UtQqxEOxJju4ZpRTh9nC9KnxwsmAAAAQgD8VJwi9RHYN13CAfhvdmjW
|
||||
xVjH55J5jDjPlENU2Z+cnm01SQ+9mPFEY4wDSvfiovD1VstNJX/P97WbHw+e5XL+HwAAAA
|
||||
JDQQ==
|
||||
-----END OPENSSH PRIVATE KEY-----
|
||||
1
tests/openssh_server/ca_ecdsa.pub
Normal file
1
tests/openssh_server/ca_ecdsa.pub
Normal file
@@ -0,0 +1 @@
|
||||
ecdsa-sha2-nistp521 AAAAE2VjZHNhLXNoYTItbmlzdHA1MjEAAAAIbmlzdHA1MjEAAACFBAB+/Xmz4bbGDnon5q50oAzgb2o5MWttlGjQJPC+Rv+get/3/ZFJapizH/SbmZgJlWV5ydmrBEcA6iVdtz9hvhwaOwAtSPdQOKuydhHtV75LCe6eSm9b8fdr3ywDexL4cKl3lFul9YKVIE4j0kQCU+1LUKsRDsSY7uGaUU4fZwvSp8cLJg== CA
|
||||
5
tests/openssh_server/ssh_host_ecdsa_key
Normal file
5
tests/openssh_server/ssh_host_ecdsa_key
Normal file
@@ -0,0 +1,5 @@
|
||||
-----BEGIN EC PRIVATE KEY-----
|
||||
MHcCAQEEIKdqGrp+52U1ehslMI4fX0cmvgHFmKSkMzQGmj6B07ecoAoGCCqGSM49
|
||||
AwEHoUQDQgAEL7+zLJ4okP10LZkf1DuIkZF5HhgzetQIyxLKeTJeiN19IKUYIxjs
|
||||
m9aW3fQRKNi/GhN9JEbHpa9qpgr+8+hhDg==
|
||||
-----END EC PRIVATE KEY-----
|
||||
7
tests/openssh_server/ssh_host_ed25519_key
Normal file
7
tests/openssh_server/ssh_host_ed25519_key
Normal file
@@ -0,0 +1,7 @@
|
||||
-----BEGIN OPENSSH PRIVATE KEY-----
|
||||
b3BlbnNzaC1rZXktdjEAAAAABG5vbmUAAAAEbm9uZQAAAAAAAAABAAAAMwAAAAtzc2gtZW
|
||||
QyNTUxOQAAACCMbXcoNmUVxO9FMMj1VB91MnwwVfBl+XDxet+j+oY6JgAAAJg8nvUxPJ71
|
||||
MQAAAAtzc2gtZWQyNTUxOQAAACCMbXcoNmUVxO9FMMj1VB91MnwwVfBl+XDxet+j+oY6Jg
|
||||
AAAECnhCuTDYdz3kUn48BXkaCXXdbKdH7wSIQ/CUx1cbnR0Ixtdyg2ZRXE70UwyPVUH3Uy
|
||||
fDBV8GX5cPF636P6hjomAAAAEHdpbGxAaUN1YmUubG9jYWwBAgMEBQ==
|
||||
-----END OPENSSH PRIVATE KEY-----
|
||||
32
tests/ossfuzz/Makefile.am
Normal file
32
tests/ossfuzz/Makefile.am
Normal file
@@ -0,0 +1,32 @@
|
||||
AM_CPPFLAGS = -I$(top_builddir)/include
|
||||
LDADD = $(top_builddir)/src/libssh2.la
|
||||
|
||||
if USE_OSSFUZZ_FLAG
|
||||
FUZZ_FLAG = $(LIB_FUZZING_ENGINE)
|
||||
else
|
||||
if USE_OSSFUZZ_STATIC
|
||||
LDADD += $(LIB_FUZZING_ENGINE)
|
||||
FUZZ_FLAG =
|
||||
else
|
||||
LDADD += libstandaloneengine.a
|
||||
FUZZ_FLAG =
|
||||
endif
|
||||
endif
|
||||
|
||||
noinst_PROGRAMS =
|
||||
noinst_LIBRARIES =
|
||||
|
||||
if USE_OSSFUZZERS
|
||||
noinst_PROGRAMS += \
|
||||
ssh2_client_fuzzer
|
||||
|
||||
noinst_LIBRARIES += \
|
||||
libstandaloneengine.a
|
||||
endif
|
||||
|
||||
ssh2_client_fuzzer_SOURCES = ssh2_client_fuzzer.cc testinput.h
|
||||
ssh2_client_fuzzer_CXXFLAGS = $(AM_CXXFLAGS) $(FUZZ_FLAG)
|
||||
ssh2_client_fuzzer_LDFLAGS = $(AM_LDFLAGS) -static
|
||||
|
||||
libstandaloneengine_a_SOURCES = standaloneengine.cc
|
||||
libstandaloneengine_a_CXXFLAGS = $(AM_CXXFLAGS)
|
||||
731
tests/ossfuzz/Makefile.in
Normal file
731
tests/ossfuzz/Makefile.in
Normal file
@@ -0,0 +1,731 @@
|
||||
# Makefile.in generated by automake 1.16.4 from Makefile.am.
|
||||
# @configure_input@
|
||||
|
||||
# Copyright (C) 1994-2021 Free Software Foundation, Inc.
|
||||
|
||||
# This Makefile.in is free software; the Free Software Foundation
|
||||
# gives unlimited permission to copy and/or distribute it,
|
||||
# with or without modifications, as long as this notice is preserved.
|
||||
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
|
||||
# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
|
||||
# PARTICULAR PURPOSE.
|
||||
|
||||
@SET_MAKE@
|
||||
|
||||
|
||||
VPATH = @srcdir@
|
||||
am__is_gnu_make = { \
|
||||
if test -z '$(MAKELEVEL)'; then \
|
||||
false; \
|
||||
elif test -n '$(MAKE_HOST)'; then \
|
||||
true; \
|
||||
elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \
|
||||
true; \
|
||||
else \
|
||||
false; \
|
||||
fi; \
|
||||
}
|
||||
am__make_running_with_option = \
|
||||
case $${target_option-} in \
|
||||
?) ;; \
|
||||
*) echo "am__make_running_with_option: internal error: invalid" \
|
||||
"target option '$${target_option-}' specified" >&2; \
|
||||
exit 1;; \
|
||||
esac; \
|
||||
has_opt=no; \
|
||||
sane_makeflags=$$MAKEFLAGS; \
|
||||
if $(am__is_gnu_make); then \
|
||||
sane_makeflags=$$MFLAGS; \
|
||||
else \
|
||||
case $$MAKEFLAGS in \
|
||||
*\\[\ \ ]*) \
|
||||
bs=\\; \
|
||||
sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \
|
||||
| sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \
|
||||
esac; \
|
||||
fi; \
|
||||
skip_next=no; \
|
||||
strip_trailopt () \
|
||||
{ \
|
||||
flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \
|
||||
}; \
|
||||
for flg in $$sane_makeflags; do \
|
||||
test $$skip_next = yes && { skip_next=no; continue; }; \
|
||||
case $$flg in \
|
||||
*=*|--*) continue;; \
|
||||
-*I) strip_trailopt 'I'; skip_next=yes;; \
|
||||
-*I?*) strip_trailopt 'I';; \
|
||||
-*O) strip_trailopt 'O'; skip_next=yes;; \
|
||||
-*O?*) strip_trailopt 'O';; \
|
||||
-*l) strip_trailopt 'l'; skip_next=yes;; \
|
||||
-*l?*) strip_trailopt 'l';; \
|
||||
-[dEDm]) skip_next=yes;; \
|
||||
-[JT]) skip_next=yes;; \
|
||||
esac; \
|
||||
case $$flg in \
|
||||
*$$target_option*) has_opt=yes; break;; \
|
||||
esac; \
|
||||
done; \
|
||||
test $$has_opt = yes
|
||||
am__make_dryrun = (target_option=n; $(am__make_running_with_option))
|
||||
am__make_keepgoing = (target_option=k; $(am__make_running_with_option))
|
||||
pkgdatadir = $(datadir)/@PACKAGE@
|
||||
pkgincludedir = $(includedir)/@PACKAGE@
|
||||
pkglibdir = $(libdir)/@PACKAGE@
|
||||
pkglibexecdir = $(libexecdir)/@PACKAGE@
|
||||
am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
|
||||
install_sh_DATA = $(install_sh) -c -m 644
|
||||
install_sh_PROGRAM = $(install_sh) -c
|
||||
install_sh_SCRIPT = $(install_sh) -c
|
||||
INSTALL_HEADER = $(INSTALL_DATA)
|
||||
transform = $(program_transform_name)
|
||||
NORMAL_INSTALL = :
|
||||
PRE_INSTALL = :
|
||||
POST_INSTALL = :
|
||||
NORMAL_UNINSTALL = :
|
||||
PRE_UNINSTALL = :
|
||||
POST_UNINSTALL = :
|
||||
build_triplet = @build@
|
||||
host_triplet = @host@
|
||||
@USE_OSSFUZZ_FLAG_FALSE@@USE_OSSFUZZ_STATIC_TRUE@am__append_1 = $(LIB_FUZZING_ENGINE)
|
||||
@USE_OSSFUZZ_FLAG_FALSE@@USE_OSSFUZZ_STATIC_FALSE@am__append_2 = libstandaloneengine.a
|
||||
noinst_PROGRAMS = $(am__EXEEXT_1)
|
||||
@USE_OSSFUZZERS_TRUE@am__append_3 = \
|
||||
@USE_OSSFUZZERS_TRUE@ ssh2_client_fuzzer
|
||||
|
||||
@USE_OSSFUZZERS_TRUE@am__append_4 = \
|
||||
@USE_OSSFUZZERS_TRUE@ libstandaloneengine.a
|
||||
|
||||
subdir = tests/ossfuzz
|
||||
ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
|
||||
am__aclocal_m4_deps = $(top_srcdir)/m4/autobuild.m4 \
|
||||
$(top_srcdir)/m4/lib-ld.m4 $(top_srcdir)/m4/lib-link.m4 \
|
||||
$(top_srcdir)/m4/lib-prefix.m4 $(top_srcdir)/m4/libtool.m4 \
|
||||
$(top_srcdir)/m4/ltoptions.m4 $(top_srcdir)/m4/ltsugar.m4 \
|
||||
$(top_srcdir)/m4/ltversion.m4 $(top_srcdir)/m4/lt~obsolete.m4 \
|
||||
$(top_srcdir)/acinclude.m4 $(top_srcdir)/configure.ac
|
||||
am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
|
||||
$(ACLOCAL_M4)
|
||||
DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON)
|
||||
mkinstalldirs = $(install_sh) -d
|
||||
CONFIG_HEADER = $(top_builddir)/src/libssh2_config.h
|
||||
CONFIG_CLEAN_FILES =
|
||||
CONFIG_CLEAN_VPATH_FILES =
|
||||
@USE_OSSFUZZERS_TRUE@am__EXEEXT_1 = ssh2_client_fuzzer$(EXEEXT)
|
||||
PROGRAMS = $(noinst_PROGRAMS)
|
||||
LIBRARIES = $(noinst_LIBRARIES)
|
||||
ARFLAGS = cru
|
||||
AM_V_AR = $(am__v_AR_@AM_V@)
|
||||
am__v_AR_ = $(am__v_AR_@AM_DEFAULT_V@)
|
||||
am__v_AR_0 = @echo " AR " $@;
|
||||
am__v_AR_1 =
|
||||
libstandaloneengine_a_AR = $(AR) $(ARFLAGS)
|
||||
libstandaloneengine_a_LIBADD =
|
||||
am_libstandaloneengine_a_OBJECTS = \
|
||||
libstandaloneengine_a-standaloneengine.$(OBJEXT)
|
||||
libstandaloneengine_a_OBJECTS = $(am_libstandaloneengine_a_OBJECTS)
|
||||
am_ssh2_client_fuzzer_OBJECTS = \
|
||||
ssh2_client_fuzzer-ssh2_client_fuzzer.$(OBJEXT)
|
||||
ssh2_client_fuzzer_OBJECTS = $(am_ssh2_client_fuzzer_OBJECTS)
|
||||
ssh2_client_fuzzer_LDADD = $(LDADD)
|
||||
am__DEPENDENCIES_1 =
|
||||
@USE_OSSFUZZ_FLAG_FALSE@@USE_OSSFUZZ_STATIC_TRUE@am__DEPENDENCIES_2 = $(am__DEPENDENCIES_1)
|
||||
ssh2_client_fuzzer_DEPENDENCIES = $(top_builddir)/src/libssh2.la \
|
||||
$(am__DEPENDENCIES_2) $(am__append_2)
|
||||
AM_V_lt = $(am__v_lt_@AM_V@)
|
||||
am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@)
|
||||
am__v_lt_0 = --silent
|
||||
am__v_lt_1 =
|
||||
ssh2_client_fuzzer_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CXX \
|
||||
$(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CXXLD) \
|
||||
$(ssh2_client_fuzzer_CXXFLAGS) $(CXXFLAGS) \
|
||||
$(ssh2_client_fuzzer_LDFLAGS) $(LDFLAGS) -o $@
|
||||
AM_V_P = $(am__v_P_@AM_V@)
|
||||
am__v_P_ = $(am__v_P_@AM_DEFAULT_V@)
|
||||
am__v_P_0 = false
|
||||
am__v_P_1 = :
|
||||
AM_V_GEN = $(am__v_GEN_@AM_V@)
|
||||
am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@)
|
||||
am__v_GEN_0 = @echo " GEN " $@;
|
||||
am__v_GEN_1 =
|
||||
AM_V_at = $(am__v_at_@AM_V@)
|
||||
am__v_at_ = $(am__v_at_@AM_DEFAULT_V@)
|
||||
am__v_at_0 = @
|
||||
am__v_at_1 =
|
||||
DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir)/src
|
||||
depcomp = $(SHELL) $(top_srcdir)/depcomp
|
||||
am__maybe_remake_depfiles = depfiles
|
||||
am__depfiles_remade = \
|
||||
./$(DEPDIR)/libstandaloneengine_a-standaloneengine.Po \
|
||||
./$(DEPDIR)/ssh2_client_fuzzer-ssh2_client_fuzzer.Po
|
||||
am__mv = mv -f
|
||||
CXXCOMPILE = $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \
|
||||
$(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS)
|
||||
LTCXXCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) \
|
||||
$(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) \
|
||||
$(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \
|
||||
$(AM_CXXFLAGS) $(CXXFLAGS)
|
||||
AM_V_CXX = $(am__v_CXX_@AM_V@)
|
||||
am__v_CXX_ = $(am__v_CXX_@AM_DEFAULT_V@)
|
||||
am__v_CXX_0 = @echo " CXX " $@;
|
||||
am__v_CXX_1 =
|
||||
CXXLD = $(CXX)
|
||||
CXXLINK = $(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) \
|
||||
$(LIBTOOLFLAGS) --mode=link $(CXXLD) $(AM_CXXFLAGS) \
|
||||
$(CXXFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@
|
||||
AM_V_CXXLD = $(am__v_CXXLD_@AM_V@)
|
||||
am__v_CXXLD_ = $(am__v_CXXLD_@AM_DEFAULT_V@)
|
||||
am__v_CXXLD_0 = @echo " CXXLD " $@;
|
||||
am__v_CXXLD_1 =
|
||||
COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \
|
||||
$(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
|
||||
LTCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \
|
||||
$(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) \
|
||||
$(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \
|
||||
$(AM_CFLAGS) $(CFLAGS)
|
||||
AM_V_CC = $(am__v_CC_@AM_V@)
|
||||
am__v_CC_ = $(am__v_CC_@AM_DEFAULT_V@)
|
||||
am__v_CC_0 = @echo " CC " $@;
|
||||
am__v_CC_1 =
|
||||
CCLD = $(CC)
|
||||
LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \
|
||||
$(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \
|
||||
$(AM_LDFLAGS) $(LDFLAGS) -o $@
|
||||
AM_V_CCLD = $(am__v_CCLD_@AM_V@)
|
||||
am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@)
|
||||
am__v_CCLD_0 = @echo " CCLD " $@;
|
||||
am__v_CCLD_1 =
|
||||
SOURCES = $(libstandaloneengine_a_SOURCES) \
|
||||
$(ssh2_client_fuzzer_SOURCES)
|
||||
DIST_SOURCES = $(libstandaloneengine_a_SOURCES) \
|
||||
$(ssh2_client_fuzzer_SOURCES)
|
||||
am__can_run_installinfo = \
|
||||
case $$AM_UPDATE_INFO_DIR in \
|
||||
n|no|NO) false;; \
|
||||
*) (install-info --version) >/dev/null 2>&1;; \
|
||||
esac
|
||||
am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP)
|
||||
# Read a list of newline-separated strings from the standard input,
|
||||
# and print each of them once, without duplicates. Input order is
|
||||
# *not* preserved.
|
||||
am__uniquify_input = $(AWK) '\
|
||||
BEGIN { nonempty = 0; } \
|
||||
{ items[$$0] = 1; nonempty = 1; } \
|
||||
END { if (nonempty) { for (i in items) print i; }; } \
|
||||
'
|
||||
# Make sure the list of sources is unique. This is necessary because,
|
||||
# e.g., the same source file might be shared among _SOURCES variables
|
||||
# for different programs/libraries.
|
||||
am__define_uniq_tagged_files = \
|
||||
list='$(am__tagged_files)'; \
|
||||
unique=`for i in $$list; do \
|
||||
if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
|
||||
done | $(am__uniquify_input)`
|
||||
am__DIST_COMMON = $(srcdir)/Makefile.in $(top_srcdir)/depcomp
|
||||
DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
|
||||
ACLOCAL = @ACLOCAL@
|
||||
ALLOCA = @ALLOCA@
|
||||
AMTAR = @AMTAR@
|
||||
AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@
|
||||
AR = @AR@
|
||||
AS = @AS@
|
||||
AUTOCONF = @AUTOCONF@
|
||||
AUTOHEADER = @AUTOHEADER@
|
||||
AUTOMAKE = @AUTOMAKE@
|
||||
AWK = @AWK@
|
||||
CC = @CC@
|
||||
CCDEPMODE = @CCDEPMODE@
|
||||
CFLAGS = @CFLAGS@
|
||||
CPP = @CPP@
|
||||
CPPFLAGS = @CPPFLAGS@
|
||||
CSCOPE = @CSCOPE@
|
||||
CTAGS = @CTAGS@
|
||||
CXX = @CXX@
|
||||
CXXCPP = @CXXCPP@
|
||||
CXXDEPMODE = @CXXDEPMODE@
|
||||
CXXFLAGS = @CXXFLAGS@
|
||||
CYGPATH_W = @CYGPATH_W@
|
||||
DEFS = @DEFS@
|
||||
DEPDIR = @DEPDIR@
|
||||
DLLTOOL = @DLLTOOL@
|
||||
DSYMUTIL = @DSYMUTIL@
|
||||
DUMPBIN = @DUMPBIN@
|
||||
ECHO_C = @ECHO_C@
|
||||
ECHO_N = @ECHO_N@
|
||||
ECHO_T = @ECHO_T@
|
||||
EGREP = @EGREP@
|
||||
ETAGS = @ETAGS@
|
||||
EXEEXT = @EXEEXT@
|
||||
FGREP = @FGREP@
|
||||
GREP = @GREP@
|
||||
HAVE_LIBBCRYPT = @HAVE_LIBBCRYPT@
|
||||
HAVE_LIBCRYPT32 = @HAVE_LIBCRYPT32@
|
||||
HAVE_LIBGCRYPT = @HAVE_LIBGCRYPT@
|
||||
HAVE_LIBMBEDCRYPTO = @HAVE_LIBMBEDCRYPTO@
|
||||
HAVE_LIBSSL = @HAVE_LIBSSL@
|
||||
HAVE_LIBZ = @HAVE_LIBZ@
|
||||
INSTALL = @INSTALL@
|
||||
INSTALL_DATA = @INSTALL_DATA@
|
||||
INSTALL_PROGRAM = @INSTALL_PROGRAM@
|
||||
INSTALL_SCRIPT = @INSTALL_SCRIPT@
|
||||
INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
|
||||
LD = @LD@
|
||||
LDFLAGS = @LDFLAGS@
|
||||
LIBBCRYPT = @LIBBCRYPT@
|
||||
LIBBCRYPT_PREFIX = @LIBBCRYPT_PREFIX@
|
||||
LIBCRYPT32 = @LIBCRYPT32@
|
||||
LIBCRYPT32_PREFIX = @LIBCRYPT32_PREFIX@
|
||||
LIBGCRYPT = @LIBGCRYPT@
|
||||
LIBGCRYPT_PREFIX = @LIBGCRYPT_PREFIX@
|
||||
LIBMBEDCRYPTO = @LIBMBEDCRYPTO@
|
||||
LIBMBEDCRYPTO_PREFIX = @LIBMBEDCRYPTO_PREFIX@
|
||||
LIBOBJS = @LIBOBJS@
|
||||
LIBS = @LIBS@
|
||||
LIBSREQUIRED = @LIBSREQUIRED@
|
||||
LIBSSH2VER = @LIBSSH2VER@
|
||||
LIBSSL = @LIBSSL@
|
||||
LIBSSL_PREFIX = @LIBSSL_PREFIX@
|
||||
LIBTOOL = @LIBTOOL@
|
||||
LIBZ = @LIBZ@
|
||||
LIBZ_PREFIX = @LIBZ_PREFIX@
|
||||
LIB_FUZZING_ENGINE = @LIB_FUZZING_ENGINE@
|
||||
LIPO = @LIPO@
|
||||
LN_S = @LN_S@
|
||||
LTLIBBCRYPT = @LTLIBBCRYPT@
|
||||
LTLIBCRYPT32 = @LTLIBCRYPT32@
|
||||
LTLIBGCRYPT = @LTLIBGCRYPT@
|
||||
LTLIBMBEDCRYPTO = @LTLIBMBEDCRYPTO@
|
||||
LTLIBOBJS = @LTLIBOBJS@
|
||||
LTLIBSSL = @LTLIBSSL@
|
||||
LTLIBZ = @LTLIBZ@
|
||||
LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@
|
||||
MAINT = @MAINT@
|
||||
MAKEINFO = @MAKEINFO@
|
||||
MANIFEST_TOOL = @MANIFEST_TOOL@
|
||||
MKDIR_P = @MKDIR_P@
|
||||
NM = @NM@
|
||||
NMEDIT = @NMEDIT@
|
||||
OBJDUMP = @OBJDUMP@
|
||||
OBJEXT = @OBJEXT@
|
||||
OTOOL = @OTOOL@
|
||||
OTOOL64 = @OTOOL64@
|
||||
PACKAGE = @PACKAGE@
|
||||
PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
|
||||
PACKAGE_NAME = @PACKAGE_NAME@
|
||||
PACKAGE_STRING = @PACKAGE_STRING@
|
||||
PACKAGE_TARNAME = @PACKAGE_TARNAME@
|
||||
PACKAGE_URL = @PACKAGE_URL@
|
||||
PACKAGE_VERSION = @PACKAGE_VERSION@
|
||||
PATH_SEPARATOR = @PATH_SEPARATOR@
|
||||
RANLIB = @RANLIB@
|
||||
SED = @SED@
|
||||
SET_MAKE = @SET_MAKE@
|
||||
SHELL = @SHELL@
|
||||
SSHD = @SSHD@
|
||||
STRIP = @STRIP@
|
||||
VERSION = @VERSION@
|
||||
abs_builddir = @abs_builddir@
|
||||
abs_srcdir = @abs_srcdir@
|
||||
abs_top_builddir = @abs_top_builddir@
|
||||
abs_top_srcdir = @abs_top_srcdir@
|
||||
ac_ct_AR = @ac_ct_AR@
|
||||
ac_ct_CC = @ac_ct_CC@
|
||||
ac_ct_CXX = @ac_ct_CXX@
|
||||
ac_ct_DUMPBIN = @ac_ct_DUMPBIN@
|
||||
am__include = @am__include@
|
||||
am__leading_dot = @am__leading_dot@
|
||||
am__quote = @am__quote@
|
||||
am__tar = @am__tar@
|
||||
am__untar = @am__untar@
|
||||
bindir = @bindir@
|
||||
build = @build@
|
||||
build_alias = @build_alias@
|
||||
build_cpu = @build_cpu@
|
||||
build_os = @build_os@
|
||||
build_vendor = @build_vendor@
|
||||
builddir = @builddir@
|
||||
datadir = @datadir@
|
||||
datarootdir = @datarootdir@
|
||||
docdir = @docdir@
|
||||
dvidir = @dvidir@
|
||||
exec_prefix = @exec_prefix@
|
||||
host = @host@
|
||||
host_alias = @host_alias@
|
||||
host_cpu = @host_cpu@
|
||||
host_os = @host_os@
|
||||
host_vendor = @host_vendor@
|
||||
htmldir = @htmldir@
|
||||
includedir = @includedir@
|
||||
infodir = @infodir@
|
||||
install_sh = @install_sh@
|
||||
libdir = @libdir@
|
||||
libexecdir = @libexecdir@
|
||||
localedir = @localedir@
|
||||
localstatedir = @localstatedir@
|
||||
mandir = @mandir@
|
||||
mkdir_p = @mkdir_p@
|
||||
oldincludedir = @oldincludedir@
|
||||
pdfdir = @pdfdir@
|
||||
prefix = @prefix@
|
||||
program_transform_name = @program_transform_name@
|
||||
psdir = @psdir@
|
||||
runstatedir = @runstatedir@
|
||||
sbindir = @sbindir@
|
||||
sharedstatedir = @sharedstatedir@
|
||||
srcdir = @srcdir@
|
||||
sysconfdir = @sysconfdir@
|
||||
target_alias = @target_alias@
|
||||
top_build_prefix = @top_build_prefix@
|
||||
top_builddir = @top_builddir@
|
||||
top_srcdir = @top_srcdir@
|
||||
AM_CPPFLAGS = -I$(top_builddir)/include
|
||||
LDADD = $(top_builddir)/src/libssh2.la $(am__append_1) $(am__append_2)
|
||||
@USE_OSSFUZZ_FLAG_FALSE@@USE_OSSFUZZ_STATIC_FALSE@FUZZ_FLAG =
|
||||
@USE_OSSFUZZ_FLAG_FALSE@@USE_OSSFUZZ_STATIC_TRUE@FUZZ_FLAG =
|
||||
@USE_OSSFUZZ_FLAG_TRUE@FUZZ_FLAG = $(LIB_FUZZING_ENGINE)
|
||||
noinst_LIBRARIES = $(am__append_4)
|
||||
ssh2_client_fuzzer_SOURCES = ssh2_client_fuzzer.cc testinput.h
|
||||
ssh2_client_fuzzer_CXXFLAGS = $(AM_CXXFLAGS) $(FUZZ_FLAG)
|
||||
ssh2_client_fuzzer_LDFLAGS = $(AM_LDFLAGS) -static
|
||||
libstandaloneengine_a_SOURCES = standaloneengine.cc
|
||||
libstandaloneengine_a_CXXFLAGS = $(AM_CXXFLAGS)
|
||||
all: all-am
|
||||
|
||||
.SUFFIXES:
|
||||
.SUFFIXES: .cc .lo .o .obj
|
||||
$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(am__configure_deps)
|
||||
@for dep in $?; do \
|
||||
case '$(am__configure_deps)' in \
|
||||
*$$dep*) \
|
||||
( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \
|
||||
&& { if test -f $@; then exit 0; else break; fi; }; \
|
||||
exit 1;; \
|
||||
esac; \
|
||||
done; \
|
||||
echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign tests/ossfuzz/Makefile'; \
|
||||
$(am__cd) $(top_srcdir) && \
|
||||
$(AUTOMAKE) --foreign tests/ossfuzz/Makefile
|
||||
Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
|
||||
@case '$?' in \
|
||||
*config.status*) \
|
||||
cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \
|
||||
*) \
|
||||
echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles)'; \
|
||||
cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles);; \
|
||||
esac;
|
||||
|
||||
$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
|
||||
cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
|
||||
|
||||
$(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps)
|
||||
cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
|
||||
$(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps)
|
||||
cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
|
||||
$(am__aclocal_m4_deps):
|
||||
|
||||
clean-noinstPROGRAMS:
|
||||
@list='$(noinst_PROGRAMS)'; test -n "$$list" || exit 0; \
|
||||
echo " rm -f" $$list; \
|
||||
rm -f $$list || exit $$?; \
|
||||
test -n "$(EXEEXT)" || exit 0; \
|
||||
list=`for p in $$list; do echo "$$p"; done | sed 's/$(EXEEXT)$$//'`; \
|
||||
echo " rm -f" $$list; \
|
||||
rm -f $$list
|
||||
|
||||
clean-noinstLIBRARIES:
|
||||
-test -z "$(noinst_LIBRARIES)" || rm -f $(noinst_LIBRARIES)
|
||||
|
||||
libstandaloneengine.a: $(libstandaloneengine_a_OBJECTS) $(libstandaloneengine_a_DEPENDENCIES) $(EXTRA_libstandaloneengine_a_DEPENDENCIES)
|
||||
$(AM_V_at)-rm -f libstandaloneengine.a
|
||||
$(AM_V_AR)$(libstandaloneengine_a_AR) libstandaloneengine.a $(libstandaloneengine_a_OBJECTS) $(libstandaloneengine_a_LIBADD)
|
||||
$(AM_V_at)$(RANLIB) libstandaloneengine.a
|
||||
|
||||
ssh2_client_fuzzer$(EXEEXT): $(ssh2_client_fuzzer_OBJECTS) $(ssh2_client_fuzzer_DEPENDENCIES) $(EXTRA_ssh2_client_fuzzer_DEPENDENCIES)
|
||||
@rm -f ssh2_client_fuzzer$(EXEEXT)
|
||||
$(AM_V_CXXLD)$(ssh2_client_fuzzer_LINK) $(ssh2_client_fuzzer_OBJECTS) $(ssh2_client_fuzzer_LDADD) $(LIBS)
|
||||
|
||||
mostlyclean-compile:
|
||||
-rm -f *.$(OBJEXT)
|
||||
|
||||
distclean-compile:
|
||||
-rm -f *.tab.c
|
||||
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libstandaloneengine_a-standaloneengine.Po@am__quote@ # am--include-marker
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ssh2_client_fuzzer-ssh2_client_fuzzer.Po@am__quote@ # am--include-marker
|
||||
|
||||
$(am__depfiles_remade):
|
||||
@$(MKDIR_P) $(@D)
|
||||
@echo '# dummy' >$@-t && $(am__mv) $@-t $@
|
||||
|
||||
am--depfiles: $(am__depfiles_remade)
|
||||
|
||||
.cc.o:
|
||||
@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXXCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
|
||||
@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
|
||||
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
|
||||
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
|
||||
@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXXCOMPILE) -c -o $@ $<
|
||||
|
||||
.cc.obj:
|
||||
@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXXCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'`
|
||||
@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
|
||||
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
|
||||
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
|
||||
@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXXCOMPILE) -c -o $@ `$(CYGPATH_W) '$<'`
|
||||
|
||||
.cc.lo:
|
||||
@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(LTCXXCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
|
||||
@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo
|
||||
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@
|
||||
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
|
||||
@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(LTCXXCOMPILE) -c -o $@ $<
|
||||
|
||||
libstandaloneengine_a-standaloneengine.o: standaloneengine.cc
|
||||
@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libstandaloneengine_a_CXXFLAGS) $(CXXFLAGS) -MT libstandaloneengine_a-standaloneengine.o -MD -MP -MF $(DEPDIR)/libstandaloneengine_a-standaloneengine.Tpo -c -o libstandaloneengine_a-standaloneengine.o `test -f 'standaloneengine.cc' || echo '$(srcdir)/'`standaloneengine.cc
|
||||
@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libstandaloneengine_a-standaloneengine.Tpo $(DEPDIR)/libstandaloneengine_a-standaloneengine.Po
|
||||
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='standaloneengine.cc' object='libstandaloneengine_a-standaloneengine.o' libtool=no @AMDEPBACKSLASH@
|
||||
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
|
||||
@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libstandaloneengine_a_CXXFLAGS) $(CXXFLAGS) -c -o libstandaloneengine_a-standaloneengine.o `test -f 'standaloneengine.cc' || echo '$(srcdir)/'`standaloneengine.cc
|
||||
|
||||
libstandaloneengine_a-standaloneengine.obj: standaloneengine.cc
|
||||
@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libstandaloneengine_a_CXXFLAGS) $(CXXFLAGS) -MT libstandaloneengine_a-standaloneengine.obj -MD -MP -MF $(DEPDIR)/libstandaloneengine_a-standaloneengine.Tpo -c -o libstandaloneengine_a-standaloneengine.obj `if test -f 'standaloneengine.cc'; then $(CYGPATH_W) 'standaloneengine.cc'; else $(CYGPATH_W) '$(srcdir)/standaloneengine.cc'; fi`
|
||||
@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libstandaloneengine_a-standaloneengine.Tpo $(DEPDIR)/libstandaloneengine_a-standaloneengine.Po
|
||||
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='standaloneengine.cc' object='libstandaloneengine_a-standaloneengine.obj' libtool=no @AMDEPBACKSLASH@
|
||||
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
|
||||
@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libstandaloneengine_a_CXXFLAGS) $(CXXFLAGS) -c -o libstandaloneengine_a-standaloneengine.obj `if test -f 'standaloneengine.cc'; then $(CYGPATH_W) 'standaloneengine.cc'; else $(CYGPATH_W) '$(srcdir)/standaloneengine.cc'; fi`
|
||||
|
||||
ssh2_client_fuzzer-ssh2_client_fuzzer.o: ssh2_client_fuzzer.cc
|
||||
@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ssh2_client_fuzzer_CXXFLAGS) $(CXXFLAGS) -MT ssh2_client_fuzzer-ssh2_client_fuzzer.o -MD -MP -MF $(DEPDIR)/ssh2_client_fuzzer-ssh2_client_fuzzer.Tpo -c -o ssh2_client_fuzzer-ssh2_client_fuzzer.o `test -f 'ssh2_client_fuzzer.cc' || echo '$(srcdir)/'`ssh2_client_fuzzer.cc
|
||||
@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/ssh2_client_fuzzer-ssh2_client_fuzzer.Tpo $(DEPDIR)/ssh2_client_fuzzer-ssh2_client_fuzzer.Po
|
||||
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='ssh2_client_fuzzer.cc' object='ssh2_client_fuzzer-ssh2_client_fuzzer.o' libtool=no @AMDEPBACKSLASH@
|
||||
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
|
||||
@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ssh2_client_fuzzer_CXXFLAGS) $(CXXFLAGS) -c -o ssh2_client_fuzzer-ssh2_client_fuzzer.o `test -f 'ssh2_client_fuzzer.cc' || echo '$(srcdir)/'`ssh2_client_fuzzer.cc
|
||||
|
||||
ssh2_client_fuzzer-ssh2_client_fuzzer.obj: ssh2_client_fuzzer.cc
|
||||
@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ssh2_client_fuzzer_CXXFLAGS) $(CXXFLAGS) -MT ssh2_client_fuzzer-ssh2_client_fuzzer.obj -MD -MP -MF $(DEPDIR)/ssh2_client_fuzzer-ssh2_client_fuzzer.Tpo -c -o ssh2_client_fuzzer-ssh2_client_fuzzer.obj `if test -f 'ssh2_client_fuzzer.cc'; then $(CYGPATH_W) 'ssh2_client_fuzzer.cc'; else $(CYGPATH_W) '$(srcdir)/ssh2_client_fuzzer.cc'; fi`
|
||||
@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/ssh2_client_fuzzer-ssh2_client_fuzzer.Tpo $(DEPDIR)/ssh2_client_fuzzer-ssh2_client_fuzzer.Po
|
||||
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='ssh2_client_fuzzer.cc' object='ssh2_client_fuzzer-ssh2_client_fuzzer.obj' libtool=no @AMDEPBACKSLASH@
|
||||
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
|
||||
@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ssh2_client_fuzzer_CXXFLAGS) $(CXXFLAGS) -c -o ssh2_client_fuzzer-ssh2_client_fuzzer.obj `if test -f 'ssh2_client_fuzzer.cc'; then $(CYGPATH_W) 'ssh2_client_fuzzer.cc'; else $(CYGPATH_W) '$(srcdir)/ssh2_client_fuzzer.cc'; fi`
|
||||
|
||||
mostlyclean-libtool:
|
||||
-rm -f *.lo
|
||||
|
||||
clean-libtool:
|
||||
-rm -rf .libs _libs
|
||||
|
||||
ID: $(am__tagged_files)
|
||||
$(am__define_uniq_tagged_files); mkid -fID $$unique
|
||||
tags: tags-am
|
||||
TAGS: tags
|
||||
|
||||
tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files)
|
||||
set x; \
|
||||
here=`pwd`; \
|
||||
$(am__define_uniq_tagged_files); \
|
||||
shift; \
|
||||
if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \
|
||||
test -n "$$unique" || unique=$$empty_fix; \
|
||||
if test $$# -gt 0; then \
|
||||
$(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
|
||||
"$$@" $$unique; \
|
||||
else \
|
||||
$(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
|
||||
$$unique; \
|
||||
fi; \
|
||||
fi
|
||||
ctags: ctags-am
|
||||
|
||||
CTAGS: ctags
|
||||
ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files)
|
||||
$(am__define_uniq_tagged_files); \
|
||||
test -z "$(CTAGS_ARGS)$$unique" \
|
||||
|| $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \
|
||||
$$unique
|
||||
|
||||
GTAGS:
|
||||
here=`$(am__cd) $(top_builddir) && pwd` \
|
||||
&& $(am__cd) $(top_srcdir) \
|
||||
&& gtags -i $(GTAGS_ARGS) "$$here"
|
||||
cscopelist: cscopelist-am
|
||||
|
||||
cscopelist-am: $(am__tagged_files)
|
||||
list='$(am__tagged_files)'; \
|
||||
case "$(srcdir)" in \
|
||||
[\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \
|
||||
*) sdir=$(subdir)/$(srcdir) ;; \
|
||||
esac; \
|
||||
for i in $$list; do \
|
||||
if test -f "$$i"; then \
|
||||
echo "$(subdir)/$$i"; \
|
||||
else \
|
||||
echo "$$sdir/$$i"; \
|
||||
fi; \
|
||||
done >> $(top_builddir)/cscope.files
|
||||
|
||||
distclean-tags:
|
||||
-rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
|
||||
distdir: $(BUILT_SOURCES)
|
||||
$(MAKE) $(AM_MAKEFLAGS) distdir-am
|
||||
|
||||
distdir-am: $(DISTFILES)
|
||||
@srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
|
||||
topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
|
||||
list='$(DISTFILES)'; \
|
||||
dist_files=`for file in $$list; do echo $$file; done | \
|
||||
sed -e "s|^$$srcdirstrip/||;t" \
|
||||
-e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \
|
||||
case $$dist_files in \
|
||||
*/*) $(MKDIR_P) `echo "$$dist_files" | \
|
||||
sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \
|
||||
sort -u` ;; \
|
||||
esac; \
|
||||
for file in $$dist_files; do \
|
||||
if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
|
||||
if test -d $$d/$$file; then \
|
||||
dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \
|
||||
if test -d "$(distdir)/$$file"; then \
|
||||
find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
|
||||
fi; \
|
||||
if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
|
||||
cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \
|
||||
find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
|
||||
fi; \
|
||||
cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \
|
||||
else \
|
||||
test -f "$(distdir)/$$file" \
|
||||
|| cp -p $$d/$$file "$(distdir)/$$file" \
|
||||
|| exit 1; \
|
||||
fi; \
|
||||
done
|
||||
check-am: all-am
|
||||
check: check-am
|
||||
all-am: Makefile $(PROGRAMS) $(LIBRARIES)
|
||||
installdirs:
|
||||
install: install-am
|
||||
install-exec: install-exec-am
|
||||
install-data: install-data-am
|
||||
uninstall: uninstall-am
|
||||
|
||||
install-am: all-am
|
||||
@$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
|
||||
|
||||
installcheck: installcheck-am
|
||||
install-strip:
|
||||
if test -z '$(STRIP)'; then \
|
||||
$(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
|
||||
install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
|
||||
install; \
|
||||
else \
|
||||
$(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
|
||||
install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
|
||||
"INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \
|
||||
fi
|
||||
mostlyclean-generic:
|
||||
|
||||
clean-generic:
|
||||
|
||||
distclean-generic:
|
||||
-test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
|
||||
-test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES)
|
||||
|
||||
maintainer-clean-generic:
|
||||
@echo "This command is intended for maintainers to use"
|
||||
@echo "it deletes files that may require special tools to rebuild."
|
||||
clean: clean-am
|
||||
|
||||
clean-am: clean-generic clean-libtool clean-noinstLIBRARIES \
|
||||
clean-noinstPROGRAMS mostlyclean-am
|
||||
|
||||
distclean: distclean-am
|
||||
-rm -f ./$(DEPDIR)/libstandaloneengine_a-standaloneengine.Po
|
||||
-rm -f ./$(DEPDIR)/ssh2_client_fuzzer-ssh2_client_fuzzer.Po
|
||||
-rm -f Makefile
|
||||
distclean-am: clean-am distclean-compile distclean-generic \
|
||||
distclean-tags
|
||||
|
||||
dvi: dvi-am
|
||||
|
||||
dvi-am:
|
||||
|
||||
html: html-am
|
||||
|
||||
html-am:
|
||||
|
||||
info: info-am
|
||||
|
||||
info-am:
|
||||
|
||||
install-data-am:
|
||||
|
||||
install-dvi: install-dvi-am
|
||||
|
||||
install-dvi-am:
|
||||
|
||||
install-exec-am:
|
||||
|
||||
install-html: install-html-am
|
||||
|
||||
install-html-am:
|
||||
|
||||
install-info: install-info-am
|
||||
|
||||
install-info-am:
|
||||
|
||||
install-man:
|
||||
|
||||
install-pdf: install-pdf-am
|
||||
|
||||
install-pdf-am:
|
||||
|
||||
install-ps: install-ps-am
|
||||
|
||||
install-ps-am:
|
||||
|
||||
installcheck-am:
|
||||
|
||||
maintainer-clean: maintainer-clean-am
|
||||
-rm -f ./$(DEPDIR)/libstandaloneengine_a-standaloneengine.Po
|
||||
-rm -f ./$(DEPDIR)/ssh2_client_fuzzer-ssh2_client_fuzzer.Po
|
||||
-rm -f Makefile
|
||||
maintainer-clean-am: distclean-am maintainer-clean-generic
|
||||
|
||||
mostlyclean: mostlyclean-am
|
||||
|
||||
mostlyclean-am: mostlyclean-compile mostlyclean-generic \
|
||||
mostlyclean-libtool
|
||||
|
||||
pdf: pdf-am
|
||||
|
||||
pdf-am:
|
||||
|
||||
ps: ps-am
|
||||
|
||||
ps-am:
|
||||
|
||||
uninstall-am:
|
||||
|
||||
.MAKE: install-am install-strip
|
||||
|
||||
.PHONY: CTAGS GTAGS TAGS all all-am am--depfiles check check-am clean \
|
||||
clean-generic clean-libtool clean-noinstLIBRARIES \
|
||||
clean-noinstPROGRAMS cscopelist-am ctags ctags-am distclean \
|
||||
distclean-compile distclean-generic distclean-libtool \
|
||||
distclean-tags distdir dvi dvi-am html html-am info info-am \
|
||||
install install-am install-data install-data-am install-dvi \
|
||||
install-dvi-am install-exec install-exec-am install-html \
|
||||
install-html-am install-info install-info-am install-man \
|
||||
install-pdf install-pdf-am install-ps install-ps-am \
|
||||
install-strip installcheck installcheck-am installdirs \
|
||||
maintainer-clean maintainer-clean-generic mostlyclean \
|
||||
mostlyclean-compile mostlyclean-generic mostlyclean-libtool \
|
||||
pdf pdf-am ps ps-am tags tags-am uninstall uninstall-am
|
||||
|
||||
.PRECIOUS: Makefile
|
||||
|
||||
|
||||
# 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.
|
||||
.NOEXPORT:
|
||||
90
tests/ossfuzz/ssh2_client_fuzzer.cc
Normal file
90
tests/ossfuzz/ssh2_client_fuzzer.cc
Normal file
@@ -0,0 +1,90 @@
|
||||
#include <assert.h>
|
||||
#include <errno.h>
|
||||
#include <stdbool.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <sys/socket.h>
|
||||
#include <unistd.h>
|
||||
#include <libssh2.h>
|
||||
#include "testinput.h"
|
||||
|
||||
#define FUZZ_ASSERT(COND) \
|
||||
if(!(COND)) \
|
||||
{ \
|
||||
fprintf(stderr, "Assertion failed: " #COND "\n%s", \
|
||||
strerror(errno)); \
|
||||
assert((COND)); \
|
||||
}
|
||||
|
||||
extern "C" int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size)
|
||||
{
|
||||
int socket_fds[2] = {-1, -1};
|
||||
ssize_t written;
|
||||
int rc;
|
||||
LIBSSH2_SESSION *session = NULL;
|
||||
int handshake_completed = 0;
|
||||
|
||||
rc = libssh2_init(0);
|
||||
|
||||
if(rc != 0) {
|
||||
fprintf(stderr, "libssh2 initialization failed (%d)\n", rc);
|
||||
goto EXIT_LABEL;
|
||||
}
|
||||
|
||||
// Create a socket pair so data can be sent in.
|
||||
rc = socketpair(AF_UNIX, SOCK_STREAM, 0, socket_fds);
|
||||
FUZZ_ASSERT(rc == 0);
|
||||
|
||||
written = send(socket_fds[1], data, size, 0);
|
||||
|
||||
if (written != size)
|
||||
{
|
||||
// Handle whatever error case we're in.
|
||||
fprintf(stderr, "send() of %zu bytes returned %zu (%d)\n",
|
||||
size,
|
||||
written,
|
||||
errno);
|
||||
goto EXIT_LABEL;
|
||||
}
|
||||
|
||||
rc = shutdown(socket_fds[1], SHUT_WR);
|
||||
if (rc != 0)
|
||||
{
|
||||
fprintf(stderr, "socket shutdown failed (%d)\n", rc);
|
||||
goto EXIT_LABEL;
|
||||
}
|
||||
|
||||
// Create a session and start the handshake using the fuzz data passed in.
|
||||
session = libssh2_session_init();
|
||||
if(session) {
|
||||
libssh2_session_set_blocking(session, 1);
|
||||
}
|
||||
|
||||
if(libssh2_session_handshake(session, socket_fds[0])) {
|
||||
goto EXIT_LABEL;
|
||||
}
|
||||
|
||||
// If we get here the handshake actually completed.
|
||||
handshake_completed = 1;
|
||||
|
||||
EXIT_LABEL:
|
||||
|
||||
if (session != NULL)
|
||||
{
|
||||
if (handshake_completed)
|
||||
{
|
||||
libssh2_session_disconnect(session,
|
||||
"Normal Shutdown, Thank you for playing");
|
||||
}
|
||||
|
||||
libssh2_session_free(session);
|
||||
}
|
||||
|
||||
libssh2_exit();
|
||||
|
||||
close(socket_fds[0]);
|
||||
close(socket_fds[1]);
|
||||
|
||||
return 0;
|
||||
}
|
||||
74
tests/ossfuzz/standaloneengine.cc
Normal file
74
tests/ossfuzz/standaloneengine.cc
Normal file
@@ -0,0 +1,74 @@
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "testinput.h"
|
||||
|
||||
/**
|
||||
* Main procedure for standalone fuzzing engine.
|
||||
*
|
||||
* Reads filenames from the argument array. For each filename, read the file
|
||||
* into memory and then call the fuzzing interface with the data.
|
||||
*/
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
int ii;
|
||||
for(ii = 1; ii < argc; ii++)
|
||||
{
|
||||
FILE *infile;
|
||||
printf("[%s] ", argv[ii]);
|
||||
|
||||
/* Try and open the file. */
|
||||
infile = fopen(argv[ii], "rb");
|
||||
if(infile)
|
||||
{
|
||||
uint8_t *buffer = NULL;
|
||||
size_t buffer_len;
|
||||
|
||||
printf("Opened.. ");
|
||||
|
||||
/* Get the length of the file. */
|
||||
fseek(infile, 0L, SEEK_END);
|
||||
buffer_len = ftell(infile);
|
||||
|
||||
/* Reset the file indicator to the beginning of the file. */
|
||||
fseek(infile, 0L, SEEK_SET);
|
||||
|
||||
/* Allocate a buffer for the file contents. */
|
||||
buffer = (uint8_t *)calloc(buffer_len, sizeof(uint8_t));
|
||||
if(buffer)
|
||||
{
|
||||
/* Read all the text from the file into the buffer. */
|
||||
fread(buffer, sizeof(uint8_t), buffer_len, infile);
|
||||
printf("Read %zu bytes, fuzzing.. ", buffer_len);
|
||||
|
||||
/* Call the fuzzer with the data. */
|
||||
LLVMFuzzerTestOneInput(buffer, buffer_len);
|
||||
|
||||
printf("complete !!");
|
||||
|
||||
/* Free the buffer as it's no longer needed. */
|
||||
free(buffer);
|
||||
buffer = NULL;
|
||||
}
|
||||
else
|
||||
{
|
||||
fprintf(stderr,
|
||||
"[%s] Failed to allocate %zu bytes \n",
|
||||
argv[ii],
|
||||
buffer_len);
|
||||
}
|
||||
|
||||
/* Close the file as it's no longer needed. */
|
||||
fclose(infile);
|
||||
infile = NULL;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Failed to open the file. Maybe wrong name or wrong permissions? */
|
||||
fprintf(stderr, "[%s] Open failed. \n", argv[ii]);
|
||||
}
|
||||
|
||||
printf("\n");
|
||||
}
|
||||
}
|
||||
3
tests/ossfuzz/testinput.h
Normal file
3
tests/ossfuzz/testinput.h
Normal file
@@ -0,0 +1,3 @@
|
||||
#include <inttypes.h>
|
||||
|
||||
extern "C" int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size);
|
||||
14
tests/ssh2.c
14
tests/ssh2.c
@@ -84,7 +84,8 @@ int main(int argc, char *argv[])
|
||||
}
|
||||
|
||||
/* Create a session instance and start it up
|
||||
* This will trade welcome banners, exchange keys, and setup crypto, compression, and MAC layers
|
||||
* This will trade welcome banners, exchange keys,
|
||||
* and setup crypto, compression, and MAC layers
|
||||
*/
|
||||
session = libssh2_session_init();
|
||||
if(libssh2_session_startup(session, sock)) {
|
||||
@@ -92,9 +93,11 @@ int main(int argc, char *argv[])
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* At this point we havn't authenticated,
|
||||
* The first thing to do is check the hostkey's fingerprint against our known hosts
|
||||
* Your app may have it hard coded, may go to a file, may present it to the user, that's your call
|
||||
/* At this point we haven't authenticated,
|
||||
* The first thing to do is check the hostkey's
|
||||
* fingerprint against our known hosts
|
||||
* Your app may have it hard coded, may go to a file,
|
||||
* may present it to the user, that's your call
|
||||
*/
|
||||
fingerprint = libssh2_hostkey_hash(session, LIBSSH2_HOSTKEY_HASH_SHA1);
|
||||
printf("Fingerprint: ");
|
||||
@@ -118,7 +121,8 @@ int main(int argc, char *argv[])
|
||||
|
||||
if(auth_pw & 4) {
|
||||
/* Authenticate by public key */
|
||||
if(libssh2_userauth_publickey_fromfile(session, username, pubkeyfile, privkeyfile, password)) {
|
||||
if(libssh2_userauth_publickey_fromfile(session, username, pubkeyfile,
|
||||
privkeyfile, password)) {
|
||||
printf("\tAuthentication by public key failed!\n");
|
||||
goto shutdown;
|
||||
}
|
||||
|
||||
51
tests/test_agent_forward_succeeds.c
Normal file
51
tests/test_agent_forward_succeeds.c
Normal file
@@ -0,0 +1,51 @@
|
||||
#include "session_fixture.h"
|
||||
|
||||
#include <libssh2.h>
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
const char *USERNAME = "libssh2"; /* set in Dockerfile */
|
||||
const char *KEY_FILE_PRIVATE = "key_rsa";
|
||||
const char *KEY_FILE_PUBLIC = "key_rsa.pub"; /* set in Dockerfile */
|
||||
|
||||
int test(LIBSSH2_SESSION *session)
|
||||
{
|
||||
int rc;
|
||||
LIBSSH2_CHANNEL *channel;
|
||||
|
||||
const char *userauth_list =
|
||||
libssh2_userauth_list(session, USERNAME, strlen(USERNAME));
|
||||
if(userauth_list == NULL) {
|
||||
print_last_session_error("libssh2_userauth_list");
|
||||
return 1;
|
||||
}
|
||||
|
||||
if(strstr(userauth_list, "publickey") == NULL) {
|
||||
fprintf(stderr, "'publickey' was expected in userauth list: %s\n",
|
||||
userauth_list);
|
||||
return 1;
|
||||
}
|
||||
|
||||
rc = libssh2_userauth_publickey_fromfile_ex(
|
||||
session, USERNAME, strlen(USERNAME), KEY_FILE_PUBLIC, KEY_FILE_PRIVATE,
|
||||
NULL);
|
||||
if(rc != 0) {
|
||||
print_last_session_error("libssh2_userauth_publickey_fromfile_ex");
|
||||
return 1;
|
||||
}
|
||||
|
||||
channel = libssh2_channel_open_session(session);
|
||||
/* if(channel == NULL) { */
|
||||
/* printf("Error opening channel\n"); */
|
||||
/* return 1; */
|
||||
/* } */
|
||||
|
||||
rc = libssh2_channel_request_auth_agent(channel);
|
||||
if(rc != 0) {
|
||||
fprintf(stderr, "Auth agent request for agent forwarding failed, "
|
||||
"error code %d\n", rc);
|
||||
return 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -32,11 +32,13 @@ int test(LIBSSH2_SESSION *session)
|
||||
|
||||
if(type == LIBSSH2_HOSTKEY_TYPE_ECDSA_256) {
|
||||
rc = libssh2_base64_decode(session, &expected_hostkey, &expected_len,
|
||||
EXPECTED_ECDSA_HOSTKEY, strlen(EXPECTED_ECDSA_HOSTKEY));
|
||||
EXPECTED_ECDSA_HOSTKEY,
|
||||
strlen(EXPECTED_ECDSA_HOSTKEY));
|
||||
}
|
||||
else if(type == LIBSSH2_HOSTKEY_TYPE_RSA) {
|
||||
rc = libssh2_base64_decode(session, &expected_hostkey, &expected_len,
|
||||
EXPECTED_RSA_HOSTKEY, strlen(EXPECTED_RSA_HOSTKEY));
|
||||
EXPECTED_RSA_HOSTKEY,
|
||||
strlen(EXPECTED_RSA_HOSTKEY));
|
||||
}
|
||||
else {
|
||||
fprintf(stderr, "Unexpected type of hostkey: %i\n", type);
|
||||
@@ -49,7 +51,7 @@ int test(LIBSSH2_SESSION *session)
|
||||
}
|
||||
|
||||
if(len != expected_len) {
|
||||
fprintf(stderr, "Hostkey does not have the expected length %ld != %d\n",
|
||||
fprintf(stderr, "Hostkey does not have the expected length %ld!=%d\n",
|
||||
(unsigned long)len, expected_len);
|
||||
return 1;
|
||||
}
|
||||
|
||||
@@ -17,19 +17,23 @@ static const char *EXPECTED_ECDSA_HOSTKEY =
|
||||
"AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBC+/syyeKJD9dC2ZH"
|
||||
"9Q7iJGReR4YM3rUCMsSynkyXojdfSClGCMY7JvWlt30ESjYvxoTfSRGx6WvaqYK/vPoYQ4=";
|
||||
|
||||
static const char *EXPECTED_RSA_MD5_HASH_DIGEST = "0C0ED1A5BB10275F76924CE187CE5C5E";
|
||||
static const char *EXPECTED_RSA_MD5_HASH_DIGEST =
|
||||
"0C0ED1A5BB10275F76924CE187CE5C5E";
|
||||
|
||||
static const char *EXPECTED_RSA_SHA1_HASH_DIGEST =
|
||||
"F3CD59E2913F4422B80F7B0A82B2B89EAE449387";
|
||||
|
||||
static const char *EXPECTED_RSA_SHA256_HASH_DIGEST = "92E3DA49DF3C7F99A828F505ED8239397A5D1F62914459760F878F7510F563A3";
|
||||
static const char *EXPECTED_RSA_SHA256_HASH_DIGEST =
|
||||
"92E3DA49DF3C7F99A828F505ED8239397A5D1F62914459760F878F7510F563A3";
|
||||
|
||||
static const char *EXPECTED_ECDSA_MD5_HASH_DIGEST = "0402E4D897580BBC911379CBD88BCD3D";
|
||||
static const char *EXPECTED_ECDSA_MD5_HASH_DIGEST =
|
||||
"0402E4D897580BBC911379CBD88BCD3D";
|
||||
|
||||
static const char *EXPECTED_ECDSA_SHA1_HASH_DIGEST =
|
||||
"12FDAD1E3B31B10BABB00F2A8D1B9A62C326BD2F";
|
||||
|
||||
static const char *EXPECTED_ECDSA_SHA256_HASH_DIGEST = "56FCD975B166C3F0342D0036E44C311A86C0EAE40713B53FC776369BAE7F5264";
|
||||
static const char *EXPECTED_ECDSA_SHA256_HASH_DIGEST =
|
||||
"56FCD975B166C3F0342D0036E44C311A86C0EAE40713B53FC776369BAE7F5264";
|
||||
|
||||
static const int MD5_HASH_SIZE = 16;
|
||||
static const int SHA1_HASH_SIZE = 20;
|
||||
@@ -51,6 +55,7 @@ int test(LIBSSH2_SESSION *session)
|
||||
{
|
||||
char buf[BUFSIZ];
|
||||
|
||||
const char *hostkey;
|
||||
const char *md5_hash;
|
||||
const char *sha1_hash;
|
||||
const char *sha256_hash;
|
||||
@@ -61,7 +66,7 @@ int test(LIBSSH2_SESSION *session)
|
||||
(void)EXPECTED_RSA_HOSTKEY;
|
||||
(void)EXPECTED_ECDSA_HOSTKEY;
|
||||
|
||||
const char *hostkey = libssh2_session_hostkey(session, &len, &type);
|
||||
hostkey = libssh2_session_hostkey(session, &len, &type);
|
||||
if(hostkey == NULL) {
|
||||
print_last_session_error("libssh2_session_hostkey");
|
||||
return 1;
|
||||
@@ -79,8 +84,9 @@ int test(LIBSSH2_SESSION *session)
|
||||
calculate_digest(md5_hash, MD5_HASH_SIZE, buf, BUFSIZ);
|
||||
|
||||
if(strcmp(buf, EXPECTED_ECDSA_MD5_HASH_DIGEST) != 0) {
|
||||
fprintf(stderr, "ECDSA MD5 hash not as expected - digest %s != %s\n", buf,
|
||||
EXPECTED_ECDSA_MD5_HASH_DIGEST);
|
||||
fprintf(stderr,
|
||||
"ECDSA MD5 hash not as expected - digest %s != %s\n",
|
||||
buf, EXPECTED_ECDSA_MD5_HASH_DIGEST);
|
||||
return 1;
|
||||
}
|
||||
|
||||
@@ -94,12 +100,14 @@ int test(LIBSSH2_SESSION *session)
|
||||
calculate_digest(sha1_hash, SHA1_HASH_SIZE, buf, BUFSIZ);
|
||||
|
||||
if(strcmp(buf, EXPECTED_ECDSA_SHA1_HASH_DIGEST) != 0) {
|
||||
fprintf(stderr, "ECDSA SHA1 hash not as expected - digest %s != %s\n", buf,
|
||||
EXPECTED_ECDSA_SHA1_HASH_DIGEST);
|
||||
fprintf(stderr,
|
||||
"ECDSA SHA1 hash not as expected - digest %s != %s\n",
|
||||
buf, EXPECTED_ECDSA_SHA1_HASH_DIGEST);
|
||||
return 1;
|
||||
}
|
||||
|
||||
sha256_hash = libssh2_hostkey_hash(session, LIBSSH2_HOSTKEY_HASH_SHA256);
|
||||
sha256_hash = libssh2_hostkey_hash(session,
|
||||
LIBSSH2_HOSTKEY_HASH_SHA256);
|
||||
if(sha256_hash == NULL) {
|
||||
print_last_session_error(
|
||||
"libssh2_hostkey_hash(LIBSSH2_HOSTKEY_HASH_SHA256)");
|
||||
@@ -109,8 +117,9 @@ int test(LIBSSH2_SESSION *session)
|
||||
calculate_digest(sha256_hash, SHA256_HASH_SIZE, buf, BUFSIZ);
|
||||
|
||||
if(strcmp(buf, EXPECTED_ECDSA_SHA256_HASH_DIGEST) != 0) {
|
||||
fprintf(stderr, "ECDSA SHA256 hash not as expected - digest %s != %s\n", buf,
|
||||
EXPECTED_ECDSA_SHA256_HASH_DIGEST);
|
||||
fprintf(stderr,
|
||||
"ECDSA SHA256 hash not as expected - digest %s != %s\n",
|
||||
buf, EXPECTED_ECDSA_SHA256_HASH_DIGEST);
|
||||
return 1;
|
||||
}
|
||||
|
||||
@@ -127,8 +136,9 @@ int test(LIBSSH2_SESSION *session)
|
||||
calculate_digest(md5_hash, MD5_HASH_SIZE, buf, BUFSIZ);
|
||||
|
||||
if(strcmp(buf, EXPECTED_RSA_MD5_HASH_DIGEST) != 0) {
|
||||
fprintf(stderr, "MD5 hash not as expected - digest %s != %s\n", buf,
|
||||
EXPECTED_RSA_MD5_HASH_DIGEST);
|
||||
fprintf(stderr,
|
||||
"MD5 hash not as expected - digest %s != %s\n",
|
||||
buf, EXPECTED_RSA_MD5_HASH_DIGEST);
|
||||
return 1;
|
||||
}
|
||||
|
||||
@@ -142,12 +152,14 @@ int test(LIBSSH2_SESSION *session)
|
||||
calculate_digest(sha1_hash, SHA1_HASH_SIZE, buf, BUFSIZ);
|
||||
|
||||
if(strcmp(buf, EXPECTED_RSA_SHA1_HASH_DIGEST) != 0) {
|
||||
fprintf(stderr, "SHA1 hash not as expected - digest %s != %s\n", buf,
|
||||
EXPECTED_RSA_SHA1_HASH_DIGEST);
|
||||
fprintf(stderr,
|
||||
"SHA1 hash not as expected - digest %s != %s\n",
|
||||
buf, EXPECTED_RSA_SHA1_HASH_DIGEST);
|
||||
return 1;
|
||||
}
|
||||
|
||||
sha256_hash = libssh2_hostkey_hash(session, LIBSSH2_HOSTKEY_HASH_SHA256);
|
||||
sha256_hash = libssh2_hostkey_hash(session,
|
||||
LIBSSH2_HOSTKEY_HASH_SHA256);
|
||||
if(sha256_hash == NULL) {
|
||||
print_last_session_error(
|
||||
"libssh2_hostkey_hash(LIBSSH2_HOSTKEY_HASH_SHA256)");
|
||||
@@ -157,8 +169,9 @@ int test(LIBSSH2_SESSION *session)
|
||||
calculate_digest(sha256_hash, SHA256_HASH_SIZE, buf, BUFSIZ);
|
||||
|
||||
if(strcmp(buf, EXPECTED_RSA_SHA256_HASH_DIGEST) != 0) {
|
||||
fprintf(stderr, "SHA256 hash not as expected - digest %s != %s\n", buf,
|
||||
EXPECTED_RSA_SHA256_HASH_DIGEST);
|
||||
fprintf(stderr,
|
||||
"SHA256 hash not as expected - digest %s != %s\n",
|
||||
buf, EXPECTED_RSA_SHA256_HASH_DIGEST);
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4,11 +4,11 @@
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
static const char *USERNAME = "libssh2"; /* configured in Dockerfile */
|
||||
static const char *USERNAME = "libssh2"; /* set in Dockerfile */
|
||||
static const char *WRONG_PASSWORD = "i'm not the password";
|
||||
|
||||
static void kbd_callback(const char *name, int name_len,
|
||||
const char *instruction, int instruction_len,
|
||||
const char *instruct, int instruct_len,
|
||||
int num_prompts,
|
||||
const LIBSSH2_USERAUTH_KBDINT_PROMPT *prompts,
|
||||
LIBSSH2_USERAUTH_KBDINT_RESPONSE *responses,
|
||||
@@ -17,7 +17,7 @@ static void kbd_callback(const char *name, int name_len,
|
||||
int i;
|
||||
(void)abstract;
|
||||
fprintf(stdout, "Kb-int name: %.*s\n", name_len, name);
|
||||
fprintf(stdout, "Kb-int instruction: %.*s\n", instruction_len, instruction);
|
||||
fprintf(stdout, "Kb-int instruction: %.*s\n", instruct_len, instruct);
|
||||
for(i = 0; i < num_prompts; ++i) {
|
||||
fprintf(stdout, "Kb-int prompt %d: %.*s\n", i, prompts[i].length,
|
||||
prompts[i].text);
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user