This commit is contained in:
Mirek Fidler 2025-01-31 14:01:21 +01:00
commit 82cf50e36d
82 changed files with 26279 additions and 10965 deletions

View file

@ -1,6 +1,6 @@
SSH package for Ultimate++
SSH package for U++
Copyright (c) 2016, 2022, İsmail Yılmaz
Copyright (c) 2016, 2024, İsmail Yılmaz
All rights reserved.
Redistribution and use in source and binary forms, with or without modification, are permitted

View file

@ -204,7 +204,7 @@ bool SFtp::CopyData(Stream& dest, Stream& src, int64 maxsize)
if(n > 0) {
dest.Put(chunk, n);
if(dest.IsError()) {
LLOG("Stream write error. " + src.GetErrorText());
LLOG("Stream write error. " + dest.GetErrorText());
return false;
}
count += n;

View file

@ -58,7 +58,8 @@ bool SFtpStream::Open(SFtp& sftp_, const char *filename, dword mode, int acm)
if(handle) {
SFtpAttrs attrs;
if(!sftp->GetAttrs(handle, attrs)) {
Zero(attrs);
if(iomode != CREATE && !sftp->GetAttrs(handle, attrs)) {
sftp->Close(handle);
handle = nullptr;
return false;

View file

@ -10,6 +10,8 @@
#include <sys/un.h>
#endif
#include "libssh2/libssh2_setup.h"
#include "libssh2/libssh2.h"
#include "libssh2/libssh2_sftp.h"
#include "libssh2/libssh2_publickey.h"

View file

@ -42,9 +42,9 @@ file
Hosts.h,
Hosts.cpp,
"Library Files" readonly separator,
libssh2upp.c,
libssh2\libssh2_config.h,
libssh2/Copying,
libssh2/libssh2_config.h,
libssh2upp.ext,
libssh2/COPYING,
Docs readonly separator,
src.tpp,
Info readonly separator,

View file

@ -247,36 +247,43 @@ bool SshSession::Connect(const String& host, int port, const String& user, const
? &sChangePasswordCallback
: nullptr);
break;
case PUBLICKEY:
case PUBLICKEY: {
// Allow computation of public key from private key.
const char *pubkey = !IsNull(session->pubkey) ? ~session->pubkey : nullptr;
rc = session->keyfile
? libssh2_userauth_publickey_fromfile(
ssh->session,
ssh->session,
~user,
~session->pubkey,
pubkey,
~session->prikey,
~session->phrase)
: libssh2_userauth_publickey_frommemory(
ssh->session,
ssh->session,
~user,
user.GetLength(),
~session->pubkey,
session->pubkey.GetLength(),
pubkey,
~session->pubkey.GetLength(),
~session->prikey,
session->prikey.GetLength(),
~session->phrase);
break;
case HOSTBASED:
}
case HOSTBASED: {
if(!session->keyfile)
ThrowError(-1, "Keys cannot be loaded from memory.");
else
else {
// Allow computation of public key from private key.
const char *pubkey = !IsNull(session->pubkey) ? ~session->pubkey : nullptr;
rc = libssh2_userauth_hostbased_fromfile(
ssh->session,
ssh->session,
~user,
~session->pubkey,
pubkey,
~session->prikey,
~session->phrase,
~host);
}
break;
}
case KEYBOARD:
rc = libssh2_userauth_keyboard_interactive(
ssh->session,
@ -302,7 +309,7 @@ bool SshSession::Connect(const String& host, int port, const String& user, const
Finalize:
#ifdef PLATFORM_POSIX
libssh2_session_callback_set(ssh->session, LIBSSH2_CALLBACK_X11, (void*) sX11RequestCallback);
libssh2_session_callback_set2(ssh->session, LIBSSH2_CALLBACK_X11, (libssh2_cb_generic*) sX11RequestCallback);
LLOG("X11 dispatcher is set.");
#endif
return true;

View file

@ -47,13 +47,6 @@ public:
TcpSocket& GetSocket() { return session->socket; }
ValueMap GetMethods() const;
SFtp CreateSFtp();
SshChannel CreateChannel();
SshExec CreateExec();
Scp CreateScp();
SshTunnel CreateTunnel();
SshShell CreateShell();
bool Connect(const String& url);
bool Connect(const String& host, int port, const String& user, const String& password);
void Disconnect();
@ -72,6 +65,14 @@ public:
SshSession(SshSession&&) = default;
// Deprecations.
[[deprecated("This method is deprecated and will be removed in U++ 2025.1. Use the class constructor instead.")]] SFtp CreateSFtp();
[[deprecated("This method is deprecated and will be removed in U++ 2025.1. Use the class constructor instead.")]] SshChannel CreateChannel();
[[deprecated("This method is deprecated and will be removed in U++ 2025.1. Use the class constructor instead.")]] SshExec CreateExec();
[[deprecated("This method is deprecated and will be removed in U++ 2025.1. Use the class constructor instead.")]] Scp CreateScp();
[[deprecated("This method is deprecated and will be removed in U++ 2025.1. Use the class constructor instead.")]] SshTunnel CreateTunnel();
[[deprecated("This method is deprecated and will be removed in U++ 2025.1. Use the class constructor instead.")]] SshShell CreateShell();
private:
void Exit() override;
String GetHostKeyHash(int type, int length) const;

View file

@ -1,11 +1,11 @@
/* Copyright (c) 2004-2007 Sara Golemon <sarag@libssh2.org>
* Copyright (c) 2005,2006 Mikhail Gusarov <dottedmag@dottedmag.net>
* Copyright (c) 2006-2007 The Written Word, Inc.
* Copyright (c) 2007 Eli Fant <elifantu@mail.ru>
* Copyright (c) 2009-2021 Daniel Stenberg
/* Copyright (C) 2004-2007 Sara Golemon <sarag@libssh2.org>
* Copyright (C) 2005,2006 Mikhail Gusarov <dottedmag@dottedmag.net>
* Copyright (C) 2006-2007 The Written Word, Inc.
* Copyright (C) 2007 Eli Fant <elifantu@mail.ru>
* Copyright (C) 2009-2023 Daniel Stenberg
* Copyright (C) 2008, 2009 Simon Josefsson
* Copyright (c) 2000 Markus Friedl
* Copyright (c) 2015 Microsoft Corp.
* Copyright (C) 2000 Markus Friedl
* Copyright (C) 2015 Microsoft Corp.
* All rights reserved.
*
* Redistribution and use in source and binary forms,
@ -41,4 +41,3 @@
* USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
* OF SUCH DAMAGE.
*/

View file

@ -1 +0,0 @@
see NEWS

File diff suppressed because it is too large Load diff

View file

@ -1,30 +0,0 @@
!include "win32/config.mk"
!include "win32/objects.mk"
CFLAGS=$(CFLAGS)
AR = lib
ARFLAGS = -nologo /LTCG
RESOURCE=$(INTDIR)\libssh2.res
DLL=libssh2$(SUFFIX).dll
STATICLIB=$(INTDIR)\libssh2.lib
!if "$(BUILD_STATIC_LIB)" == ""
all: $(DLL)
!else
all: $(STATICLIB)
!endif
$(DLL): $(OBJECTS) $(RESOURCE)
$(CC) -o $(DLL) $(DLLFLAGS) $(OBJECTS) $(RESOURCE) $(LIBS)
$(STATICLIB): $(OBJECTS)
$(AR) $(ARFLAGS) -out:$@ $(OBJECTS)
$(RESOURCE): win32\libssh2.rc
$(RC) $(RCFLAGS) /Fo"$@" $?
!include "win32/rules.mk"

View file

@ -4,9 +4,9 @@ libssh2 - SSH2 library
libssh2 is a library implementing the SSH2 protocol, available under
the revised BSD license.
Web site: https://www.libssh2.org/
Web site: https://libssh2.org/
Mailing list: https://cool.haxx.se/mailman/listinfo/libssh2-devel
Mailing list: https://lists.haxx.se/listinfo/libssh2-devel
License: see COPYING

View file

@ -1,62 +1,325 @@
libssh2 1.10
libssh2 1.11.1
Deprecation notices:
- Starting October 2024, the following algos go deprecated and will be
disabled in default builds (with an option to enable them):
- DSA: `ssh-dss` hostkeys.
You can enable it now with `-DLIBSSH2_DSA_ENABLE`.
Disabled by default in OpenSSH 7.0 (2015-08-11).
Support to be removed by early 2025 from OpenSSH.
- MD5-based MACs and hashes: `hmac-md5`, `hmac-md5-96`,
`LIBSSH2_HOSTKEY_HASH_MD5`
You can disable it now with `-DLIBSSH2_NO_MD5`.
Disabled by default since OpenSSH 7.2 (2016-02-29).
- 3DES cipher: `3des-cbc`
You can disable it now with `-DLIBSSH2_NO_3DES`.
Disabled by default since OpenSSH 7.4 (2016-12-19).
- RIPEMD-160 MACs: `hmac-ripemd160`, `hmac-ripemd160@openssh.com`
You can disable it now with `-DLIBSSH2_NO_HMAC_RIPEMD`.
Removed in OpenSSH 7.6 (2017-10-03).
- Blowfish cipher: `blowfish-cbc`
You can disable it now with `-DLIBSSH2_NO_BLOWFISH`.
Removed in OpenSSH 7.6 (2017-10-03).
- RC4 ciphers: `arcfour`, `arcfour128`
You can disable it now with `-DLIBSSH2_NO_RC4`.
Removed in OpenSSH 7.6 (2017-10-03).
- CAST cipher: `cast128-cbc`
You can disable it now with `-DLIBSSH2_NO_CAST`.
Removed in OpenSSH 7.6 (2017-10-03).
- Starting April 2025, above options will be deleted from the
libssh2 codebase.
- Default builds will also disable support for old-style, MD5-based
encrypted private keys.
You can disable it now with `-DLIBSSH2_NO_MD5_PEM`.
This release includes the following enhancements and bugfixes:
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
- autotools: fix to update `LDFLAGS` for each detected dependency (d19b6190 #1384 #1381 #1377)
- autotools: delete `--disable-tests` option, fix CI tests (e051ae34 #1271 #715 revert: 7483edfa)
- autotools: show the default for `hidden-symbols` option (a3f5594a #1269)
- autotools: enable `-Wunused-macros` with gcc (ecdf5199 #1262 #1227 #1224)
- autotools: fix dotless gcc and Apple clang version detections (89ccc83c #1232 #1187)
- autotools: show more clang/gcc version details (fb580161 #1230)
- autotools: avoid warnings in libtool stub code (96682bd5 #1227 #1224)
- autotools: sync warning enabler code with curl (5996fefe #1223)
- autotools: rename variable (ce5f208a #1222)
- autotools: picky warning options tidy-up (cdca8cff #1221)
- autotools: fix `cp` to preserve attributes and timestamp in `Makefile.am` (f64e6318)
- autotools: fix selecting WinCNG in cross-builds (and more) (00a3b88c #1187 #1186)
- autotools: use comma separator in `Requires.private` of `libssh2.pc` (7f83de14 #1124)
- autotools: remove `AB_INIT` from `configure.ac` (f4f52ccc)
- autotools: improve libz position (c89174a7 #1077 #941 #1075 #1013 regr: 4f0f4bff)
- autotools: skip tests requiring static lib if `--disable-static` (572c57c9 #1072 #663 #1056 regr: 83853f8a)
- build: stop detecting `sys/param.h` header (2677d3b0 #1418 #1415)
- build: silence warnings inside `FD_SET()`/`FD_ISSET()` macros (323a14b2 #1379)
- build: drop `-Wformat-nonliteral` warning suppressions (c452c5cc #1342)
- build: enable `-pedantic-errors` (3ec53f3e #1286)
- build: add mingw-w64 support to `LIBSSH2_PRINTF()` attribute (f8c45794 #1287)
- build: add `LIBSSH2_NO_DEPRECATED` option (b1414503 #1267 #1266 #1260 #1259)
- build: enable missing OpenSSF-recommended warnings, with fixes (afa6b865 #1257)
- build: enable more compiler warnings and fix them (7ecc309c #1224)
- build: picky warning updates (328a96b3 #1219)
- build: revert: respect autotools `DLL_EXPORT` in `libssh2.h` (481be044 #1141 #917 revert: fb1195cf)
- build: stop requiring libssl from openssl (c84745e3 #1128)
- build: tidy-up `libssh2.pc.in` variable names (5720dd9f #1125)
- build: add/fix `Requires.private` packages in `libssh2.pc` (ef538069 #1123)
- buildconf: drop (814a850c #1441 follow: fc5d7788)
- checksrc: update, check all sources, fix fallouts (1117b677 #1457)
- checksrc: sync with curl (8cd473c9 #1272)
- checksrc: fix spelling in comment (a95d401f)
- checksrc: modernise Perl file open (3d309f9b)
- checksrc: switch to dot file (d67a91aa #1052)
- ci: use Ninja with cmake (20ad047d #1458)
- ci: disable dependency tracking in autotools builds (e44f0418 #1396)
- ci: fix mbedtls runners on macOS (84411539 #1381)
- ci: enable Unity mode for most CMake builds (1bfae57b #1367 #1034)
- ci: add shellcheck job and script (d88b9bcd)
- ci: verify build and install from tarball (a86e27e8 #1362)
- ci: add reproducibility test for `maketgz` (2d765e45 #1360)
- ci: use Linux runner for BSDs, add arm64 FreeBSD 14 job (6f86b196 #1343)
- ci: do not parallelize `distcheck` job (5e65dd87 #1339)
- ci: add FreeBSD 14 job, fix issues (46333adf #1277)
- ci: add OmniOS job, fix issues (5e0ec991)
- ci: show compiler in cross/cygwin job names (c9124088)
- ci: add OpenBSD (v7.4) job + fix build error in example (0c9a8e35 #1250)
- ci: add NetBSD (v9.3) job (65c7a7a5)
- ci: update and speed up FreeBSD job (eee4e805)
- ci: use absolute path in `CMAKE_INSTALL_PREFIX` (74948816 #1247)
- ci: boost mbedTLS build speed (236e79a1 #1245)
- ci: add BoringSSL job (cmake, gcc, amd64) (c9dd3566 #1233)
- ci: fixup FreeBSD version, bump mbedTLS (fea6664e #1217)
- ci: add FreeBSD 13.2 job (a7d2a573 #1215)
- ci: mbedTLS 3.5.0 (5e190442 #1202)
- ci: update actions, use shallow clones with appveyor (d468a33f #1199)
- ci: replace `mv` + `chmod` with `install` in `Dockerfile` (5754fed6 #1175)
- ci: set file mode early in `appveyor_docker.yml` (633db55f)
- ci: add spellcheck (codespell) (a79218d3)
- ci: add MSYS builds (autotools and cmake) (d43b8d9b #1162)
- ci: add Cygwin builds (autotools and cmake) (f1e96e73 #1161)
- ci: add mingw-w64 UWP build (1215aa5f #1155 #1147)
- ci: add missing timeout to 'autotools distcheck' step (6265ffdb)
- ci: add non-static autotools i386 build, ignore GHA updates on AppVeyor (c6e137f7 #1074 #1072)
- ci: prefer `=` operator in shell snippets (e5c03043 #1073)
- ci: drop redundant/unused vars, sync var names (ab8e95bc #1059)
- ci: add i386 Linux build (with mbedTLS) (abdf40c7 #1057 #1053)
- ci/appveyor: reduce test runs (workaround for infrastructure permafails) (b5e68bdc #1461)
- ci/appveyor: increase wait for SSH server on GHA (bf3af90b)
- ci/appveyor: bump to OpenSSL 3.2.1 (53d9c1a6 #1363 #1348)
- ci/appveyor: re-enable parallel mode (e190e5b2 #1294 #884 #867)
- ci/appveyor: delete UWP job broken since Visual Studio upgrade (d0a7f1da #1275)
- ci/appveyor: YAML/PowerShell formatting, shorten variable name (06fd721f #1200)
- ci/appveyor: move to pure PowerShell (8a081fd9 #1197)
- ci/GHA: revert concurrency and improve permissions (e4c042f6)
- ci/GHA: FreeBSD 14.1, actions bump (ae04b1b9 #1424)
- ci/GHA: fix wolfSSL-from-source AES-GCM tests (1c0b07a7 #1409 #1408)
- ci/GHA: add Linux job with latest wolfSSL built from source (d4cea53f #1408 #1299 #1020)
- ci/GHA: tidy up build-from-source steps (2c633033)
- ci/GHA: show configure logs on failure and other tidy-ups (dab48398 #1403)
- ci/GHA: bump parallel jobs to nproc+1 (6f3d3bc8 #1402)
- ci/GHA: show test logs on failure (b8ffa7a5 #1401)
- ci/GHA: fix `Dockerfile` failing after Ubuntu package update (839bb84e #1400)
- ci/GHA: use ubuntu-latest with OmniOS job (50143d58)
- ci/GHA: shell syntax tidy-up (3b23e039 #1390)
- ci/GHA: bump NetBSD/OpenBSD, add NetBSD arm64 job (e980af72 #1388)
- ci/GHA: tidy up wolfSSL autotools config on macOS (5953c1f1 #1383)
- ci/GHA: shorter mbedTLS autotools workaround (736e3d7d #1382 #1381)
- ci/GHA: fix gcrypt with autotools/macOS/Homebrew/ARM64 (ae2770de #1377)
- ci/GHA: fix verbose option for autotools jobs (499b27ae #1376)
- ci/GHA: dump `config.log` on failure for macOS autotools jobs (4fa69214 #1375)
- ci/GHA: fix `autoreconf` failure on macOS/Homebrew (0b64b30b #1374)
- ci/GHA: fixup Homebrew location (for ARM runners) (6128aee0 #1373)
- ci/GHA: review/fixup auto-cancel settings (b08cfbc9 #1292)
- ci/GHA: restore curly braces in `if` (36748270 #1145)
- ci/GHA: simplify `if` strings (cab3db58 #1140)
- cmake: sync and improve Find modules, add `pkg-config` native detection (45064137 #1445 #1420)
- cmake: generate `LIBSSH2_PC_LIBS_PRIVATE` dynamically (c87f1296 #1466)
- cmake: add comment about `ibssh2.pc.in` variables (14b1b9d0)
- cmake: support absolute `CMAKE_INSTALL_INCLUDEDIR`/`CMAKE_INSTALL_LIBDIR` (d70cee36 #1465)
- cmake: rename two variables and initialize them (0fce9dcc #1464)
- cmake: prefer `find_dependency()` in `libssh2-config.cmake` (d9c2e550 #1460)
- cmake: tidy up syntax, minor improvements (9d9ee780 #1446)
- cmake: rename mbedTLS and wolfSSL Find modules (570de0f2)
- cmake: fixup version detection in mbedTLS Find module (8e3c40b2 #1444)
- cmake: mbedTLS detection tidy-ups (6d1d13c2 #1438)
- cmake: add quotes, delete ending dirseps (2bb46d44 #1437 #1166)
- cmake: sync formatting in `cmake/Find*` modules (a0310699)
- cmake: tidy up function name casing in `CopyRuntimeDependencies.cmake` (03547cb8)
- cmake: use the imported target of FindOpenSSL module (82b09f9b #1322)
- cmake: rename picky warnings script (64d6789f #1225)
- cmake: fix multiple include of libssh2 package (932d6a32 #1216)
- cmake: show crypto backend in feature summary (20387285 #1211)
- cmake: simplify showing CMake version (fc00bdd7 #1203)
- cmake: cleanup mbedTLS version detection more (4c241d5c #1196 #1192)
- cmake: delete duplicate `include()` (30eef0a6)
- cmake: improve/fix mbedTLS detection (41594675 #1192 #1191)
- cmake: tidy-up `foreach()` syntax (4a64ca14 #1180)
- cmake: verify `libssh2_VERSION` in integration tests (a20572e9)
- cmake: show cmake versions in ci (87f5769b)
- cmake: quote more strings (e9c7d3af #1173)
- cmake: add `ExternalProject` integration test (aeaefaf6 #1171)
- cmake: add integration tests (8715c3d5 #1170)
- cmake: (re-)add aliases for `add_subdirectory()` builds (4ff64ae3 #1169)
- cmake: style tidy-up (3fa5282d #1166)
- cmake: add `LIB_NAME` variable (5453fc80 #1159)
- cmake: tidy-up concatenation in `CMAKE_MODULE_PATH` (ae7d5108 #1157)
- cmake: replace `libssh2` literals with `PROJECT_NAME` variable (72fd2595 #1152)
- cmake: fix `STREQUAL` check in error branch (42d3bf13 #1151)
- cmake: cache more config values on Windows (11a03690 #1142)
- cmake: streamline invocation (f58f77b5 #1138)
- cmake: merge `set_target_properties()` calls (a9091007 #1132)
- cmake: (re-)add zlib to `Libs.private` in `libssh2.pc` (64643018 #1131)
- cmake: use `wolfssl/options.h` for detection, like autotools (c5ec6c49 #1130)
- cmake: add openssl libs to `Libs.private` in `libssh2.pc` (5cfa59d3 #1127)
- cmake: bump minimum CMake version to v3.7.0 (9cd18f45 #1126)
- cmake: CMAKE_SOURCE_DIR -> PROJECT_SOURCE_DIR (0f396aa9 #1121)
- cmake: tidy-ups (2fc36790 #1122)
- cmake: re-add `Libssh2:libssh2` for compatibility + lowercase namespace (2da13c13 #1104 #731 #1103)
- copyright: remove years from copyright headers (187d89bb #1082)
- disable DSA by default (b7ab0faa #1435 #1433)
- docs: update `INSTALL_AUTOTOOLS` (2f0efde3 #1316)
- docs: replace SHA1 with SHA256 in CMake example (766bde9f)
- example: restore `sys/time.h` for AIX (24503cb9 #1340 #1335 #1334 #1001 regr: e53aae0e)
- example: use `libssh2_socket_t` in X11 example (3f60ccb7)
- example: replace remaining libssh2_scp_recv with libssh2_scp_recv2 in output messages (8d69e63d #1258 follow: 6c84a426)
- example: fix regression in `ssh2_exec.c` (279a2e57 #1106 #861 #846 #1105 regr: b13936bd)
- example, tests: call `WSACleanup()` for each `WSAStartup()` (94b6bad3 #1283)
- example, tests: fix/silence `-Wformat-truncation=2` gcc warnings (744e059f)
- hostkey: do not advertise ssh-rsa when SHA1 is disabled (82d1b8ff #1093 #1092)
- kex: prevent possible double free of hostkey (b3465418 #1452)
- kex: always check for null pointers before calling _libssh2_bn_set_word (9f23a3bb #1423)
- kex: fix a memory leak in key exchange (19101843 #1412 #1404)
- kex: always add extension indicators to kex_algorithms (00e2a07e #1327 #1326)
- libssh2.h: add deprecated function warnings (9839ebe5 #1289 #1260)
- libssh2.h: add portable `LIBSSH2_SOCKET_CLOSE()` macro (28dbf016 #1278)
- libssh2.h: use `_WIN32` for Windows detection instead of rolling our own (631e7734 #1238)
- libssh2.pc: reference mbedcrypto pkgconfig (c149a127 #1405)
- libssh2.pc: re-add & extend support for static-only libssh2 builds (624abe27 #1119 #1114)
- libssh2.pc: don't put `@LIBS@` in pc file (1209c16d)
- mac: add empty hash functions for `mac_method_hmac_aesgcm` to not crash when e.g. setting `LIBSSH2_METHOD_CRYPT_CS` (b2738391 #1321)
- mac: handle low-level errors (f64885b6 #1297)
- Makefile.mk: delete Windows-focused raw GNU Make build (43485579 #1204)
- maketgz: reproducible tarballs/zip, display tarball hashes (d52fe1b4 #1357 #1359)
- maketgz: `set -eu`, reproducibility, improve zip, add CI test (cba7f975 #1353)
- man: improve `libssh2_userauth_publickey_from*` manpages (581b72aa #1347 #1308 #652)
- man: fix double spaces and dash escaping (a3ffc422 #1210)
- man: add description to `libssh2_session_get_blocking.3` (67e39091 #1185)
- mbedtls: always init ECDSA mbedtls_pk_context (a50d7deb #1430)
- mbedtls: correctly initialize values (ECDSA) (1701d5c0 #1428 #1421)
- mbedtls: expose `mbedtls_pk_load_file()` for our use (1628f6ca #1421 #1393 #1349 follow: e973493f)
- mbedtls: add workaround + FIXME to build with 3.6.0 (2e4c5ec4 #1349)
- mbedtls: improve disabling `-Wredundant-decls` (ecec68a2 #1226 #1224)
- mbedtls: include `version.h` for `MBEDTLS_VERSION_NUMBER` (9d7bc253 #1095 #1094)
- mbedtls: use more `size_t` to sync up with `crypto.h` (1153ebde #1054 #879 #846 #1053)
- md5: allow disabling old-style encrypted private keys at build-time (eb9f9de2 #1181)
- mingw: fix printf mask for 64-bit integers (36c1e1d1 #1091 #876 #846 #1090)
- misc: flatten `_libssh2_explicit_zero` if tree (74e74288 #1149)
- NMakefile: delete (c515eed3 #1134 #1129)
- openssl: free allocated resources when using openssl3 (b942bad1 #1459)
- openssl: fix memory leaks in `_libssh2_ecdsa_curve_name_with_octal_new` and `_libssh2_ecdsa_verify` (8d3bc19b #1449)
- openssl: fix calculating DSA public key with OpenSSL 3 (8b3c6e9d #1380)
- openssl: initialize BIGNUMs to NULL in `gen_publickey_from_dsa` for OpenSSL 3 (f1133c75 #1320)
- openssl: fix cppcheck found NULL dereferences (f2945905 #1304)
- openssl: delete internal `read_openssh_private_key_from_memory()` (34aff5ff #1306)
- openssl: use OpenSSL 3 HMAC API, add `no-deprecated` CI job (363dcbf4 #1243 #1235 #1207)
- openssl: make a function static, add `#ifdef` comments (efee9133 #1246 #248 follow: 03092292)
- openssl: fix DSA code to use OpenSSL 3 API (82581941 #1244 #1207)
- openssl: fix `EC_KEY` reference with OpenSSL 3 `no-deprecated` build (487152f4 #1236 #1235 #1207)
- openssl: use non-deprecated APIs with OpenSSL 3.x (b0ab005f #1207)
- openssl: silence `-Wunused-value` warnings (bf285500 #1205)
- openssl: use automatic initialization with LibreSSL 2.7.0+ (d79047c9 #1146 #302)
- openssl: add missing check for `LIBRESSL_VERSION_NUMBER` before use (4a42f42e #1117 #1115)
- os400: drop vsprintf() use (40e817ff #1462 #1457)
- os400: Add two recent files to the distribution (e4c65e5b #1364)
- os400: fix shellcheck warnings in scripts (fixups) (81341e1e #1366 #1364 #1358)
- os400: fix shellcheck warnings in scripts (c6625707 #1358)
- os400: maintain up to date (8457c37a #1309)
- packet: properly bounds check packet_authagent_open() (88a960a8 #1179)
- pem: fix private keys encrypted with AES-GCM methods (e87bdefa #1133)
- reuse: upgrade to `REUSE.toml` (70b8bf31 #1419)
- reuse: fix duplicate copyright warning (b9a4ed83)
- reuse: comply with 3.1 spec and 2.0.0 checker (fe6239a1 #1102 #1101 #1098)
- reuse: provide SPDX identifiers (f6aa31f4 #1084)
- scp: fix missing cast for targets without large file support (c317e06f #1060 #1057 #1002 regr: 5db836b2)
- session: support server banners up to 8192 bytes (was: 256) (1a9e8811 #1443 #1442)
- session: add `libssh2_session_callback_set2()` (c0f69548 #1285)
- session: handle EINTR from send/recv/poll/select to try again as the error is not fatal (798ed4a7 #1058 #955)
- sftp: increase SFTP_HANDLE_MAXLEN back to 4092 (75de6a37 #1422)
- sftp: implement posix-rename@openssh.com (fb652746 #1386)
- src: implement chacha20-poly1305@openssh.com (492bc543 #1426 #584)
- src: use `UINT32_MAX` (dc206408 #1413)
- src: fix type warning in `libssh2_sftp_unlink` macro (ac2e8c73 #1406)
- src: check the return value from `_libssh2_bn_*()` functions (95c824d5 #1354)
- src: support RSA-SHA2 cert-based authentication (rsa-sha2-512_cert and rsa-sha2-256_cert) (3a6ab70d #1314)
- src: check hash update/final success (4718ede4 #1303 #1301)
- src: check hash init success (2ed9eb92 #1301)
- src: add 'strict KEX' to fix CVE-2023-48795 "Terrapin Attack" (d34d9258 #1291 #1290)
- src: disable `-Wsign-conversion` warnings, add option to re-enable (6e451669 #1284 #1257)
- src: fix gcc 13 `-Wconversion` warning on Darwin (8cca7b77 #1209 follow: 08354e0a)
- src: drop a redundant `#include` (1f0174d0 #1153)
- src: improve MSVC C4701 warning fix (8b924999 #1086 #876 #1083)
- src: bump `hash_len` to `size_t` in `LIBSSH2_HOSTKEY_METHOD` (8b917d76 #1076)
- src: bump DSA and ECDSA sign `hash_len` to `size_t` (7b8e0225 #1055)
- tests: avoid using `MAXPATHLEN`, for portability (12427f4f #1415 #198 #1414)
- tests: fix excluding AES-GCM tests (fbd9d192 #1410)
- tests: drop default cygpath option `-u` (38e50aa0)
- tests: fix shellcheck issues in `test_sshd.test` (a2ac8c55)
- tests: sync port number type with the rest of codebase (eb996af8)
- tests: fall back to `$LOGNAME` for username (5326a5ce #1241 #1240)
- tests: show cmake version used in integration tests (2cd2f40e #1201)
- tests: formatting and tidy-ups (e61987a3)
- tests: replace FIXME with comments (1a99a86a)
- tests: add aes256-gcm encrypted key test (802336cf #1135 #1133)
- tests: trap signals in scripts (b2916b28 #1098)
- tests: cast to avoid `-Wchar-subscripts` with Cygwin (43df6a46 #1081 #1080)
- test_read: make it run without Docker (57e9d18e #1139)
- test_sshd.test: show sshd and test connect logs on harness failure (299c2040 #1097)
- test_sshd.test: set a safe PID directory (e8cabdcf #1089)
- test_sshd.test: minor cleanups (d29eea1d)
- tidy-up: link updates (c905bfd2 #1434)
- tidy-up: typo in comment (792e1b6f)
- tidy-up: fix typo found by codespell (706ec36d)
- tidy-up: bump casts from int to long for large C99 types in printfs (2e5a8719 #1264 #1257)
- tidy-up: `unsigned` -> `unsigned int` (b136c379)
- tidy-up: stop using leading underscores in macro names (c6589b88 #1248)
- tidy-up: around `stdint.h` (bfa00f1b #1212)
- tidy-up: fix typo in `readme.vms` (a9a79e7a)
- tidy-up: use built-in `_WIN32` macro to detect Windows (6fbc9505 #1195)
- tidy-up: drop `www.` from `www.libssh2.org` (6e3e8839 #1172)
- tidy-up: delete duplicate word from comment (76307435)
- tidy-up: avoid exclamations, prefer single quotes, in outputs (003fb454 #1079)
- TODO: disable or drop weak algos (0b4bdc85 #1261)
- transport: fix unstable connections over non-blocking sockets (de004875 #1454 #720 #1431 #1397)
- transport: check ETM on remote end when receiving (bde10825 #1332 #1331)
- transport: fix incorrect byte offset in debug message (2388a3aa #1096)
- userauth: avoid oob with huge interactive kbd response (f3a85cad #1337)
- userauth: add a new structure to separate memory read and file read (63b4c20e #773)
- userauth: check whether `*key_method` is a NULL pointer instead of `key_method` (bec57c40)
- wincng: fix `DH_GEX_MAXGROUP` set higher than supported (48584671 #1372 #493)
- wincng: add to ci/GHA, add `./configure` option `--enable-ecdsa-wincng` (3f98bfb0 #1368 #1315)
- wincng: add ECDSA support for host and user authentication (3e723437 #1315)
- wincng: prefer `ULONG`/`DWORD` over `unsigned long` (186c1d63 #1165)
- wincng: tidy-ups (7bb669b5 #1164)
- wolfssl: drop header path hack (8ae1b2d7 #1439)
- wolfssl: fix `EVP_Cipher()` use with v5.6.0 and older (a5b0fac2 #1407 #1394 #797 #1299 #1020)
- wolfssl: bump version in upstream issue comment (5cab802c)
- wolfssl: require v5.4.0 for AES-GCM (260a721c #1411 #1299 #1020)
- wolfssl: enable debug logging in wolfSSL when compiled in (76e7a68a #1310)
This release would not have looked like this without help, code, reports and
advice from friends like these:
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)
Viktor Szakats, Michael Buckley, Patrick Monnerat, Ren Mingshuai,
Will Cosgrove, Daniel Stenberg, Josef Cejka, Nicolas Mora, Ryan Kelley,
Aaron Stone, Adam, Anders Borum, András Fekete, Andrei Augustin, binary1248,
Brian Inglis, brucsc on GitHub, concussious on github, Dan Fandrich,
dksslq on github, Haowei Hsu, Harmen Stoppels, Harry Mallon, Jack L,
Jakob Egger, Jiwoo Park, João M. S. Silva, Joel Depooter, Johannes Passing,
Jose Quaresma, Juliusz Sosinowicz, Kai Pastor, Kenneth Davidson,
klux21 on github, Lyndon Brown, Marc Hoersken, mike-jumper, naddy,
Nursan Valeyev, Paul Howarth, PewPewPew, Radek Brich, rahmanih on github,
rolag on github, Seo Suchan, shubhamhii on github, Steve McIntyre,
Tejaswi Kandula, Tobias Stoeckmann, Trzik, Xi Ruoyao

View file

@ -1,6 +1,6 @@
/*
* Copyright (c) 2009 by Daiki Ueno
* Copyright (C) 2010-2014 by Daniel Stenberg
* Copyright (C) Daiki Ueno
* Copyright (C) Daniel Stenberg
* All rights reserved.
*
* Redistribution and use in source and binary forms,
@ -35,12 +35,15 @@
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
* USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
* OF SUCH DAMAGE.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#include "libssh2_priv.h"
#include "agent.h"
#include "misc.h"
#include <errno.h>
#include <stdlib.h> /* for getenv() */
#ifdef HAVE_SYS_UN_H
#include <sys/un.h>
#else
@ -49,12 +52,15 @@
support them. */
#undef PF_UNIX
#endif
#include "userauth.h"
#include "session.h"
#ifdef WIN32
#include <stdlib.h>
#if defined(_WIN32) && !defined(LIBSSH2_WINDOWS_UWP)
#define HAVE_WIN32_AGENTS
#endif
#include "userauth.h"
#include "session.h"
#if 0
/* Requests from client to agent for protocol 1 key operations */
#define SSH_AGENTC_REQUEST_RSA_IDENTITIES 1
#define SSH_AGENTC_RSA_CHALLENGE 3
@ -62,10 +68,12 @@
#define SSH_AGENTC_REMOVE_RSA_IDENTITY 8
#define SSH_AGENTC_REMOVE_ALL_RSA_IDENTITIES 9
#define SSH_AGENTC_ADD_RSA_ID_CONSTRAINED 24
#endif
/* Requests from client to agent for protocol 2 key operations */
#define SSH2_AGENTC_REQUEST_IDENTITIES 11
#define SSH2_AGENTC_SIGN_REQUEST 13
#if 0
#define SSH2_AGENTC_ADD_IDENTITY 17
#define SSH2_AGENTC_REMOVE_IDENTITY 18
#define SSH2_AGENTC_REMOVE_ALL_IDENTITIES 19
@ -86,13 +94,79 @@
#define SSH_AGENT_RSA_IDENTITIES_ANSWER 2
#define SSH_AGENT_RSA_RESPONSE 4
/* Key constraint identifiers */
#define SSH_AGENT_CONSTRAIN_LIFETIME 1
#define SSH_AGENT_CONSTRAIN_CONFIRM 2
#endif
/* Replies from agent to client for protocol 2 key operations */
#define SSH2_AGENT_IDENTITIES_ANSWER 12
#define SSH2_AGENT_SIGN_RESPONSE 14
/* Key constraint identifiers */
#define SSH_AGENT_CONSTRAIN_LIFETIME 1
#define SSH_AGENT_CONSTRAIN_CONFIRM 2
/* Signature request methods */
#define SSH_AGENT_RSA_SHA2_256 2
#define SSH_AGENT_RSA_SHA2_512 4
/* 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 {
const agent_connect_func connect;
const agent_transact_func transact;
const 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 HAVE_WIN32_AGENTS
OVERLAPPED overlapped;
HANDLE pipe;
BOOL pending_io;
#endif
};
#include "agent_win.c"
#ifdef PF_UNIX
static int
@ -115,10 +189,10 @@ agent_connect_unix(LIBSSH2_AGENT *agent)
"failed creating socket");
s_un.sun_family = AF_UNIX;
strncpy(s_un.sun_path, path, sizeof s_un.sun_path);
strncpy(s_un.sun_path, path, sizeof(s_un.sun_path));
s_un.sun_path[sizeof(s_un.sun_path)-1] = 0; /* make sure there's a trailing
zero */
if(connect(agent->fd, (struct sockaddr*)(&s_un), sizeof s_un) != 0) {
if(connect(agent->fd, (struct sockaddr*)(&s_un), sizeof(s_un)) != 0) {
close(agent->fd);
return _libssh2_error(agent->session, LIBSSH2_ERROR_AGENT_PROTOCOL,
"failed connecting with agent");
@ -128,20 +202,22 @@ agent_connect_unix(LIBSSH2_AGENT *agent)
}
#define RECV_SEND_ALL(func, socket, buffer, length, flags, abstract) \
int rc; \
size_t finished = 0; \
do { \
size_t finished = 0; \
\
while(finished < length) { \
rc = func(socket, \
(char *)buffer + finished, length - finished, \
flags, abstract); \
if(rc < 0) \
return rc; \
while(finished < length) { \
ssize_t rc; \
rc = func(socket, \
(char *)buffer + finished, length - finished, \
flags, abstract); \
if(rc < 0) \
return rc; \
\
finished += rc; \
} \
finished += rc; \
} \
\
return finished;
return finished; \
} while(0)
static ssize_t _send_all(LIBSSH2_SEND_FUNC(func), libssh2_socket_t socket,
const void *buffer, size_t length,
@ -167,9 +243,10 @@ 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 = _send_all(agent->session->send, agent->fd,
buf, sizeof buf, 0, &agent->session->abstract);
_libssh2_htonu32(buf, (uint32_t)transctx->request_len);
rc = (int)_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)
@ -180,8 +257,9 @@ 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 = _send_all(agent->session->send, agent->fd, transctx->request,
transctx->request_len, 0, &agent->session->abstract);
rc = (int)_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)
@ -192,8 +270,9 @@ 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 = _recv_all(agent->session->recv, agent->fd,
buf, sizeof buf, 0, &agent->session->abstract);
rc = (int)_recv_all(agent->session->recv, agent->fd,
buf, sizeof(buf), 0,
&agent->session->abstract);
if(rc < 0) {
if(rc == -EAGAIN)
return LIBSSH2_ERROR_EAGAIN;
@ -211,8 +290,9 @@ 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 = _recv_all(agent->session->recv, agent->fd, transctx->response,
transctx->response_len, 0, &agent->session->abstract);
rc = (int)_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;
@ -238,14 +318,14 @@ agent_disconnect_unix(LIBSSH2_AGENT *agent)
return LIBSSH2_ERROR_NONE;
}
struct agent_ops agent_ops_unix = {
static struct agent_ops agent_ops_unix = {
agent_connect_unix,
agent_transact_unix,
agent_disconnect_unix
};
#endif /* PF_UNIX */
#ifdef WIN32
#ifdef HAVE_WIN32_AGENTS
/* Code to talk to Pageant was taken from PuTTY.
*
* Portions copyright Robert de Bath, Joris van Rantwijk, Delian
@ -276,7 +356,7 @@ agent_transact_pageant(LIBSSH2_AGENT *agent, agent_transaction_ctx_t transctx)
HANDLE filemap;
unsigned char *p;
unsigned char *p2;
int id;
LRESULT id;
COPYDATASTRUCT cds;
if(!transctx || 4 + transctx->request_len > PAGEANT_MAX_MSGLEN)
@ -289,16 +369,16 @@ agent_transact_pageant(LIBSSH2_AGENT *agent, agent_transaction_ctx_t transctx)
"found no pageant");
snprintf(mapname, sizeof(mapname),
"PageantRequest%08x%c", (unsigned)GetCurrentThreadId(), '\0');
"PageantRequest%08x", (unsigned)GetCurrentThreadId());
filemap = CreateFileMappingA(INVALID_HANDLE_VALUE, NULL, PAGE_READWRITE,
0, PAGEANT_MAX_MSGLEN, mapname);
if(filemap == NULL || filemap == INVALID_HANDLE_VALUE)
if(!filemap || filemap == INVALID_HANDLE_VALUE)
return _libssh2_error(agent->session, LIBSSH2_ERROR_AGENT_PROTOCOL,
"failed setting up pageant filemap");
p2 = p = MapViewOfFile(filemap, FILE_MAP_WRITE, 0, 0, 0);
if(p == NULL || p2 == NULL) {
if(!p || !p2) {
CloseHandle(filemap);
return _libssh2_error(agent->session, LIBSSH2_ERROR_AGENT_PROTOCOL,
"failed to open pageant filemap for writing");
@ -308,7 +388,7 @@ agent_transact_pageant(LIBSSH2_AGENT *agent, agent_transaction_ctx_t transctx)
transctx->request_len);
cds.dwData = PAGEANT_COPYDATA_ID;
cds.cbData = 1 + strlen(mapname);
cds.cbData = (DWORD)(1 + strlen(mapname));
cds.lpData = mapname;
id = SendMessage(hwnd, WM_COPYDATA, (WPARAM) NULL, (LPARAM) &cds);
@ -343,21 +423,21 @@ agent_disconnect_pageant(LIBSSH2_AGENT *agent)
return 0;
}
struct agent_ops agent_ops_pageant = {
static struct agent_ops agent_ops_pageant = {
agent_connect_pageant,
agent_transact_pageant,
agent_disconnect_pageant
};
#endif /* WIN32 */
#endif /* HAVE_WIN32_AGENTS */
static struct {
const char *name;
struct agent_ops *ops;
} supported_backends[] = {
#ifdef WIN32
#ifdef HAVE_WIN32_AGENTS
{"Pageant", &agent_ops_pageant},
{"OpenSSH", &agent_ops_openssh},
#endif /* WIN32 */
#endif /* HAVE_WIN32_AGENTS */
#ifdef PF_UNIX
{"Unix", &agent_ops_unix},
#endif /* PF_UNIX */
@ -375,6 +455,9 @@ agent_sign(LIBSSH2_SESSION *session, unsigned char **sig, size_t *sig_len,
ssize_t method_len;
unsigned char *s;
int rc;
unsigned char *method_name = NULL;
uint32_t sign_flags = 0;
ssize_t plain_len;
/* Create a request to sign the data */
if(transctx->state == agent_NB_state_init) {
@ -391,7 +474,18 @@ agent_sign(LIBSSH2_SESSION *session, unsigned char **sig, size_t *sig_len,
_libssh2_store_str(&s, (const char *)data, data_len);
/* flags */
_libssh2_store_u32(&s, 0);
if(session->userauth_pblc_method_len > 0 &&
session->userauth_pblc_method) {
if(session->userauth_pblc_method_len == 12 &&
!memcmp(session->userauth_pblc_method, "rsa-sha2-512", 12)) {
sign_flags = SSH_AGENT_RSA_SHA2_512;
}
else if(session->userauth_pblc_method_len == 12 &&
!memcmp(session->userauth_pblc_method, "rsa-sha2-256", 12)) {
sign_flags = SSH_AGENT_RSA_SHA2_256;
}
}
_libssh2_store_u32(&s, sign_flags);
transctx->request_len = s - transctx->request;
transctx->send_recv_total = 0;
@ -449,8 +543,32 @@ agent_sign(LIBSSH2_SESSION *session, unsigned char **sig, size_t *sig_len,
rc = LIBSSH2_ERROR_AGENT_PROTOCOL;
goto error;
}
/* method name */
method_name = LIBSSH2_ALLOC(session, method_len);
if(!method_name) {
rc = LIBSSH2_ERROR_ALLOC;
goto error;
}
memcpy(method_name, s, method_len);
s += method_len;
plain_len = plain_method((char *)session->userauth_pblc_method,
session->userauth_pblc_method_len);
/* check to see if we match requested */
if(((size_t)method_len != session->userauth_pblc_method_len &&
method_len != plain_len) ||
memcmp(method_name, session->userauth_pblc_method, method_len)) {
_libssh2_debug((session,
LIBSSH2_TRACE_KEX,
"Agent sign method %.*s",
(int)method_len, method_name));
rc = LIBSSH2_ERROR_ALGO_UNSUPPORTED;
goto error;
}
/* Read the signature */
len -= 4;
if(len < 0) {
@ -472,13 +590,19 @@ agent_sign(LIBSSH2_SESSION *session, unsigned char **sig, size_t *sig_len,
}
memcpy(*sig, s, *sig_len);
error:
error:
if(method_name)
LIBSSH2_FREE(session, method_name);
LIBSSH2_FREE(session, transctx->request);
transctx->request = NULL;
LIBSSH2_FREE(session, transctx->response);
transctx->response = NULL;
transctx->state = agent_NB_state_init;
return _libssh2_error(session, rc, "agent sign failure");
}
@ -541,7 +665,7 @@ agent_list_identities(LIBSSH2_AGENT *agent)
while(num_identities--) {
struct agent_publickey *identity;
ssize_t comment_len;
size_t comment_len;
/* Read the length of the blob */
len -= 4;
@ -549,7 +673,7 @@ agent_list_identities(LIBSSH2_AGENT *agent)
rc = LIBSSH2_ERROR_AGENT_PROTOCOL;
goto error;
}
identity = LIBSSH2_ALLOC(agent->session, sizeof *identity);
identity = LIBSSH2_ALLOC(agent->session, sizeof(*identity));
if(!identity) {
rc = LIBSSH2_ERROR_ALLOC;
goto error;
@ -586,14 +710,14 @@ agent_list_identities(LIBSSH2_AGENT *agent)
comment_len = _libssh2_ntohu32(s);
s += 4;
/* Read the comment */
len -= comment_len;
if(len < 0) {
if(comment_len > (size_t)len) {
rc = LIBSSH2_ERROR_AGENT_PROTOCOL;
LIBSSH2_FREE(agent->session, identity->external.blob);
LIBSSH2_FREE(agent->session, identity);
goto error;
}
/* Read the comment */
len -= comment_len;
identity->external.comment = LIBSSH2_ALLOC(agent->session,
comment_len + 1);
@ -609,7 +733,7 @@ agent_list_identities(LIBSSH2_AGENT *agent)
_libssh2_list_add(&agent->head, &identity->node);
}
error:
error:
LIBSSH2_FREE(agent->session, transctx->response);
transctx->response = NULL;
@ -634,7 +758,7 @@ agent_free_identities(LIBSSH2_AGENT *agent)
#define AGENT_PUBLICKEY_MAGIC 0x3bdefed2
/*
* agent_publickey_to_external()
* agent_publickey_to_external
*
* Copies data from the internal to the external representation struct.
*
@ -661,7 +785,7 @@ libssh2_agent_init(LIBSSH2_SESSION *session)
{
LIBSSH2_AGENT *agent;
agent = LIBSSH2_CALLOC(session, sizeof *agent);
agent = LIBSSH2_CALLOC(session, sizeof(*agent));
if(!agent) {
_libssh2_error(session, LIBSSH2_ERROR_ALLOC,
"Unable to allocate space for agent connection");
@ -672,7 +796,7 @@ libssh2_agent_init(LIBSSH2_SESSION *session)
agent->identity_agent_path = NULL;
_libssh2_list_init(&agent->head);
#ifdef WIN32
#ifdef HAVE_WIN32_AGENTS
agent->pipe = INVALID_HANDLE_VALUE;
memset(&agent->overlapped, 0, sizeof(OVERLAPPED));
agent->pending_io = FALSE;
@ -682,7 +806,7 @@ libssh2_agent_init(LIBSSH2_SESSION *session)
}
/*
* libssh2_agent_connect()
* libssh2_agent_connect
*
* Connect to an ssh-agent.
*
@ -702,7 +826,7 @@ libssh2_agent_connect(LIBSSH2_AGENT *agent)
}
/*
* libssh2_agent_list_identities()
* libssh2_agent_list_identities
*
* Request ssh-agent to list identities.
*
@ -711,14 +835,14 @@ libssh2_agent_connect(LIBSSH2_AGENT *agent)
LIBSSH2_API int
libssh2_agent_list_identities(LIBSSH2_AGENT *agent)
{
memset(&agent->transctx, 0, sizeof agent->transctx);
memset(&agent->transctx, 0, sizeof(agent->transctx));
/* Abandon the last fetched identities */
agent_free_identities(agent);
return agent_list_identities(agent);
}
/*
* libssh2_agent_get_identity()
* libssh2_agent_get_identity
*
* Traverse the internal list of public keys. Pass NULL to 'prev' to get
* the first one. Or pass a pointer to the previously returned one to get the
@ -755,7 +879,7 @@ libssh2_agent_get_identity(LIBSSH2_AGENT *agent,
}
/*
* libssh2_agent_userauth()
* libssh2_agent_userauth
*
* Do publickey user authentication with the help of ssh-agent.
*
@ -770,7 +894,7 @@ libssh2_agent_userauth(LIBSSH2_AGENT *agent,
int rc;
if(agent->session->userauth_pblc_state == libssh2_NB_state_idle) {
memset(&agent->transctx, 0, sizeof agent->transctx);
memset(&agent->transctx, 0, sizeof(agent->transctx));
agent->identity = identity->node;
}
@ -785,7 +909,58 @@ libssh2_agent_userauth(LIBSSH2_AGENT *agent,
}
/*
* libssh2_agent_disconnect()
* libssh2_agent_sign
*
* Sign a payload using a system-installed ssh-agent.
*
* Returns 0 if succeeded, or a negative value for error.
*/
LIBSSH2_API int
libssh2_agent_sign(LIBSSH2_AGENT *agent,
struct libssh2_agent_publickey *identity,
unsigned char **sig,
size_t *s_len,
const unsigned char *data,
size_t d_len,
const char *method,
unsigned int method_len)
{
void *abstract = agent;
int rc;
uint32_t methodLen;
if(agent->session->userauth_pblc_state == libssh2_NB_state_idle) {
memset(&agent->transctx, 0, sizeof(agent->transctx));
agent->identity = identity->node;
}
if(identity->blob_len < sizeof(uint32_t)) {
return LIBSSH2_ERROR_BUFFER_TOO_SMALL;
}
methodLen = _libssh2_ntohu32(identity->blob);
if(identity->blob_len < sizeof(uint32_t) + methodLen) {
return LIBSSH2_ERROR_BUFFER_TOO_SMALL;
}
agent->session->userauth_pblc_method_len = method_len;
agent->session->userauth_pblc_method = LIBSSH2_ALLOC(agent->session,
method_len);
memcpy(agent->session->userauth_pblc_method, method, methodLen);
rc = agent_sign(agent->session, sig, s_len, data, d_len, &abstract);
LIBSSH2_FREE(agent->session, agent->session->userauth_pblc_method);
agent->session->userauth_pblc_method = NULL;
agent->session->userauth_pblc_method_len = 0;
return rc;
}
/*
* libssh2_agent_disconnect
*
* Close a connection to an ssh-agent.
*
@ -800,7 +975,7 @@ libssh2_agent_disconnect(LIBSSH2_AGENT *agent)
}
/*
* libssh2_agent_free()
* libssh2_agent_free
*
* Free an ssh-agent handle. This function also frees the internal
* collection of public keys.
@ -813,7 +988,7 @@ libssh2_agent_free(LIBSSH2_AGENT *agent)
libssh2_agent_disconnect(agent);
}
if(agent->identity_agent_path != NULL)
if(agent->identity_agent_path)
LIBSSH2_FREE(agent->session, agent->identity_agent_path);
agent_free_identities(agent);
@ -821,7 +996,7 @@ libssh2_agent_free(LIBSSH2_AGENT *agent)
}
/*
* libssh2_agent_set_identity_path()
* libssh2_agent_set_identity_path
*
* Allows a custom agent socket path beyond SSH_AUTH_SOCK env
*
@ -846,7 +1021,7 @@ libssh2_agent_set_identity_path(LIBSSH2_AGENT *agent, const char *path)
}
/*
* libssh2_agent_get_identity_path()
* libssh2_agent_get_identity_path
*
* Returns the custom agent socket path if set
*

View file

@ -1,112 +0,0 @@
#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 */

View file

@ -1,6 +1,6 @@
/*
* Copyright (c) 2009 by Daiki Ueno
* Copyright (C) 2010-2014 by Daniel Stenberg
* Copyright (C) Daiki Ueno
* Copyright (C) Daniel Stenberg
* All rights reserved.
*
* Redistribution and use in source and binary forms,
@ -35,32 +35,19 @@
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
* USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
* OF SUCH DAMAGE.
*
* SPDX-License-Identifier: BSD-3-Clause AND BSD-2-Clause
*/
#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 HAVE_WIN32_AGENTS /* Compile this via agent.c */
#include <stdlib.h> /* for getenv() */
#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:
* specifically the following files:
*
* - contrib\win32\win32compat\fileio.c
* - Structure of agent_connect_openssh from ssh_get_authentication_socket
@ -74,7 +61,7 @@
* - fileio_close replacing close
*
* Author: Tatu Ylonen <ylo@cs.hut.fi>
* Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
* Copyright (C) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
* All rights reserved
* Functions for connecting the local authentication agent.
*
@ -85,7 +72,7 @@
* called by a name other than "ssh" or "Secure Shell".
*
* SSH2 implementation,
* Copyright (c) 2000 Markus Friedl. All rights reserved.
* 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
@ -107,7 +94,7 @@
* (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.
* Copyright (C) 2015 Microsoft Corp.
* All rights reserved
*
* Microsoft openssh win32 port
@ -195,7 +182,7 @@ agent_connect_openssh(LIBSSH2_AGENT *agent)
}
event = CreateEventA(NULL, TRUE, FALSE, NULL);
if(event == NULL) {
if(!event) {
ret = _libssh2_error(agent->session, LIBSSH2_ERROR_AGENT_PROTOCOL,
"unable to create async I/O event");
goto cleanup;
@ -208,7 +195,7 @@ agent_connect_openssh(LIBSSH2_AGENT *agent)
agent->fd = 0; /* Mark as the connection has been established */
cleanup:
if(event != NULL)
if(event)
CloseHandle(event);
if(pipe != INVALID_HANDLE_VALUE)
CloseHandle(pipe);
@ -273,7 +260,7 @@ agent_transact_openssh(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, (uint32_t)transctx->request_len);
rc = win32_openssh_send_all(agent, buf, sizeof buf,
rc = win32_openssh_send_all(agent, buf, sizeof(buf),
&transctx->send_recv_total);
if(rc == LIBSSH2_ERROR_EAGAIN)
return LIBSSH2_ERROR_EAGAIN;
@ -298,7 +285,7 @@ agent_transact_openssh(LIBSSH2_AGENT *agent, agent_transaction_ctx_t transctx)
/* Receive the length of the body */
if(transctx->state == agent_NB_state_request_sent) {
rc = win32_openssh_recv_all(agent, buf, sizeof buf,
rc = win32_openssh_recv_all(agent, buf, sizeof(buf),
&transctx->send_recv_total);
if(rc == LIBSSH2_ERROR_EAGAIN)
return LIBSSH2_ERROR_EAGAIN;
@ -353,9 +340,10 @@ agent_disconnect_openssh(LIBSSH2_AGENT *agent)
return LIBSSH2_ERROR_NONE;
}
struct agent_ops agent_ops_openssh = {
static struct agent_ops agent_ops_openssh = {
agent_connect_openssh,
agent_transact_openssh,
agent_disconnect_openssh
};
#endif /* WIN32 */
#endif /* HAVE_WIN32_AGENTS */

View file

@ -1,6 +1,6 @@
/* $OpenBSD: bcrypt_pbkdf.c,v 1.4 2013/07/29 00:55:53 tedu Exp $ */
/*
* Copyright (c) 2013 Ted Unangst <tedu@openbsd.org>
* Copyright (C) Ted Unangst <tedu@openbsd.org>
*
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
@ -13,21 +13,18 @@
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*
* SPDX-License-Identifier: MIT
*/
#include "libssh2_priv.h"
#ifndef HAVE_BCRYPT_PBKDF
#include "libssh2_priv.h"
#include <stdlib.h>
#include <sys/types.h>
#ifdef HAVE_SYS_PARAM_H
#include <sys/param.h>
#endif
#include "blf.h"
#define MINIMUM(a,b) (((a) < (b)) ? (a) : (b))
#define LIBSSH2_BCRYPT_PBKDF_C
#include "blowfish.c"
/*
* pkcs #5 pbkdf2 implementation using the "bcrypt" hash
@ -60,12 +57,15 @@ static void
bcrypt_hash(uint8_t *sha2pass, uint8_t *sha2salt, uint8_t *out)
{
blf_ctx state;
uint8_t ciphertext[BCRYPT_HASHSIZE] =
"OxychromaticBlowfishSwatDynamite";
uint8_t ciphertext[BCRYPT_HASHSIZE] = {
'O', 'x', 'y', 'c', 'h', 'r', 'o', 'm', 'a', 't', 'i', 'c',
'B', 'l', 'o', 'w', 'f', 'i', 's', 'h',
'S', 'w', 'a', 't',
'D', 'y', 'n', 'a', 'm', 'i', 't', 'e' };
uint32_t cdata[BCRYPT_BLOCKS];
int i;
uint16_t j;
size_t shalen = SHA512_DIGEST_LENGTH;
uint16_t shalen = SHA512_DIGEST_LENGTH;
/* key expansion */
Blowfish_initstate(&state);
@ -85,7 +85,7 @@ bcrypt_hash(uint8_t *sha2pass, uint8_t *sha2salt, uint8_t *out)
/* copy out */
for(i = 0; i < BCRYPT_BLOCKS; i++) {
out[4 * i + 3] = (cdata[i] >> 24) & 0xff;
out[4 * i + 3] = (uint8_t)((cdata[i] >> 24) & 0xff);
out[4 * i + 2] = (cdata[i] >> 16) & 0xff;
out[4 * i + 1] = (cdata[i] >> 8) & 0xff;
out[4 * i + 0] = cdata[i] & 0xff;
@ -97,7 +97,7 @@ bcrypt_hash(uint8_t *sha2pass, uint8_t *sha2salt, uint8_t *out)
_libssh2_explicit_zero(&state, sizeof(state));
}
int
static int
bcrypt_pbkdf(const char *pass, size_t passlen, const uint8_t *salt,
size_t saltlen,
uint8_t *key, size_t keylen, unsigned int rounds)
@ -116,10 +116,10 @@ bcrypt_pbkdf(const char *pass, size_t passlen, const uint8_t *salt,
if(rounds < 1)
return -1;
if(passlen == 0 || saltlen == 0 || keylen == 0 ||
keylen > sizeof(out) * sizeof(out) || saltlen > 1<<20)
keylen > sizeof(out) * sizeof(out) || saltlen > 1 << 20)
return -1;
countsalt = calloc(1, saltlen + 4);
if(countsalt == NULL)
if(!countsalt)
return -1;
stride = (keylen + sizeof(out) - 1) / sizeof(out);
amt = (keylen + stride - 1) / stride;
@ -127,30 +127,41 @@ bcrypt_pbkdf(const char *pass, size_t passlen, const uint8_t *salt,
memcpy(countsalt, salt, saltlen);
/* collapse password */
libssh2_sha512_init(&ctx);
libssh2_sha512_update(ctx, pass, passlen);
libssh2_sha512_final(ctx, sha2pass);
if(!libssh2_sha512_init(&ctx) ||
!libssh2_sha512_update(ctx, pass, passlen) ||
!libssh2_sha512_final(ctx, sha2pass)) {
free(countsalt);
return -1;
}
/* generate key, sizeof(out) at a time */
for(count = 1; keylen > 0; count++) {
countsalt[saltlen + 0] = (count >> 24) & 0xff;
countsalt[saltlen + 0] = (uint8_t)((count >> 24) & 0xff);
countsalt[saltlen + 1] = (count >> 16) & 0xff;
countsalt[saltlen + 2] = (count >> 8) & 0xff;
countsalt[saltlen + 3] = count & 0xff;
/* first round, salt is salt */
libssh2_sha512_init(&ctx);
libssh2_sha512_update(ctx, countsalt, saltlen + 4);
libssh2_sha512_final(ctx, sha2salt);
if(!libssh2_sha512_init(&ctx) ||
!libssh2_sha512_update(ctx, countsalt, saltlen + 4) ||
!libssh2_sha512_final(ctx, sha2salt)) {
_libssh2_explicit_zero(out, sizeof(out));
free(countsalt);
return -1;
}
bcrypt_hash(sha2pass, sha2salt, tmpout);
memcpy(out, tmpout, sizeof(out));
for(i = 1; i < rounds; i++) {
/* subsequent rounds, salt is previous output */
libssh2_sha512_init(&ctx);
libssh2_sha512_update(ctx, tmpout, sizeof(tmpout));
libssh2_sha512_final(ctx, sha2salt);
if(!libssh2_sha512_init(&ctx) ||
!libssh2_sha512_update(ctx, tmpout, sizeof(tmpout)) ||
!libssh2_sha512_final(ctx, sha2salt)) {
_libssh2_explicit_zero(out, sizeof(out));
free(countsalt);
return -1;
}
bcrypt_hash(sha2pass, sha2salt, tmpout);
for(j = 0; j < sizeof(out); j++)
@ -160,7 +171,7 @@ bcrypt_pbkdf(const char *pass, size_t passlen, const uint8_t *salt,
/*
* pbkdf2 deviation: output the key material non-linearly.
*/
amt = MINIMUM(amt, keylen);
amt = LIBSSH2_MIN(amt, keylen);
for(i = 0; i < amt; i++) {
size_t dest = i * stride + (count - 1);
if(dest >= origkeylen) {
@ -178,3 +189,22 @@ bcrypt_pbkdf(const char *pass, size_t passlen, const uint8_t *salt,
return 0;
}
#endif /* HAVE_BCRYPT_PBKDF */
/* Wrapper */
int _libssh2_bcrypt_pbkdf(const char *pass,
size_t passlen,
const uint8_t *salt,
size_t saltlen,
uint8_t *key,
size_t keylen,
unsigned int rounds)
{
return bcrypt_pbkdf(pass,
passlen,
salt,
saltlen,
key,
keylen,
rounds);
}

View file

@ -1,89 +0,0 @@
#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
*
* Copyright 1997 Niels Provos <provos@physnet.uni-hamburg.de>
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by Niels Provos.
* 4. The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#if !defined(HAVE_BCRYPT_PBKDF) && !defined(HAVE_BLH_H)
/* Schneier specifies a maximum key length of 56 bytes.
* This ensures that every key bit affects every cipher
* bit. However, the subkeys can hold up to 72 bytes.
* Warning: For normal blowfish encryption only 56 bytes
* of the key affect all cipherbits.
*/
#define BLF_N 16 /* Number of Subkeys */
#define BLF_MAXKEYLEN ((BLF_N-2)*4) /* 448 bits */
#define BLF_MAXUTILIZED ((BLF_N + 2)*4) /* 576 bits */
/* Blowfish context */
typedef struct BlowfishContext {
uint32_t S[4][256]; /* S-Boxes */
uint32_t P[BLF_N + 2]; /* Subkeys */
} blf_ctx;
/* Raw access to customized Blowfish
* blf_key is just:
* Blowfish_initstate( state )
* Blowfish_expand0state( state, key, keylen )
*/
void Blowfish_encipher(blf_ctx *, uint32_t *, uint32_t *);
void Blowfish_decipher(blf_ctx *, uint32_t *, uint32_t *);
void Blowfish_initstate(blf_ctx *);
void Blowfish_expand0state(blf_ctx *, const uint8_t *, uint16_t);
void Blowfish_expandstate
(blf_ctx *, const uint8_t *, uint16_t, const uint8_t *, uint16_t);
/* Standard Blowfish */
void blf_key(blf_ctx *, const uint8_t *, uint16_t);
void blf_enc(blf_ctx *, uint32_t *, uint16_t);
void blf_dec(blf_ctx *, uint32_t *, uint16_t);
void blf_ecb_encrypt(blf_ctx *, uint8_t *, uint32_t);
void blf_ecb_decrypt(blf_ctx *, uint8_t *, uint32_t);
void blf_cbc_encrypt(blf_ctx *, uint8_t *, uint8_t *, uint32_t);
void blf_cbc_decrypt(blf_ctx *, uint8_t *, uint8_t *, uint32_t);
/* Converts uint8_t to uint32_t */
uint32_t Blowfish_stream2word(const uint8_t *, uint16_t, uint16_t *);
/* bcrypt with pbkd */
int bcrypt_pbkdf(const char *pass, size_t passlen, const uint8_t *salt,
size_t saltlen,
uint8_t *key, size_t keylen, unsigned int rounds);
#endif /* !defined(HAVE_BCRYPT_PBKDF) && !defined(HAVE_BLH_H) */
#endif /* __LIBSSH2_BLF_H */

View file

@ -1,7 +1,8 @@
/* $OpenBSD: blowfish.c,v 1.18 2004/11/02 17:23:26 hshoexer Exp $ */
/*
* Blowfish block cipher for OpenBSD
* Copyright 1997 Niels Provos <provos@physnet.uni-hamburg.de>
* Blowfish for OpenBSD - a fast block cipher designed by Bruce Schneier
*
* Copyright (C) Niels Provos <provos@physnet.uni-hamburg.de>
* All rights reserved.
*
* Implementation advice by David Mazieres <dm@lcs.mit.edu>.
@ -14,10 +15,7 @@
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by Niels Provos.
* 4. The name of the author may not be used to endorse or promote products
* 3. The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
@ -30,6 +28,8 @@
* 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.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
/*
@ -39,38 +39,81 @@
* Bruce Schneier.
*/
#if defined(LIBSSH2_BCRYPT_PBKDF_C) || defined(_DEBUG_BLOWFISH)
#if !defined(HAVE_BCRYPT_PBKDF) && (!defined(HAVE_BLOWFISH_INITSTATE) || \
!defined(HAVE_BLOWFISH_EXPAND0STATE) || \
!defined(HAVE_BLF_ENC))
#if 0
#include <stdio.h> /* used for debugging */
#ifdef _DEBUG_BLOWFISH
#include <stdio.h>
#include <string.h>
#include <inttypes.h>
#endif
#include <sys/types.h>
/* Schneier specifies a maximum key length of 56 bytes.
* This ensures that every key bit affects every cipher
* bit. However, the subkeys can hold up to 72 bytes.
* Warning: For normal blowfish encryption only 56 bytes
* of the key affect all cipherbits.
*/
#include "libssh2.h"
#include "blf.h"
#define BLF_N 16 /* Number of Subkeys */
#define BLF_MAXKEYLEN ((BLF_N-2)*4) /* 448 bits */
#define BLF_MAXUTILIZED ((BLF_N + 2)*4) /* 576 bits */
#undef inline
#ifdef __GNUC__
#define inline __inline
#else /* !__GNUC__ */
#define inline
#endif /* !__GNUC__ */
/* Blowfish context */
typedef struct BlowfishContext {
uint32_t S[4][256]; /* S-Boxes */
uint32_t P[BLF_N + 2]; /* Subkeys */
} blf_ctx;
/* Raw access to customized Blowfish
* blf_key is just:
* Blowfish_initstate( state )
* Blowfish_expand0state( state, key, keylen )
*/
static void Blowfish_encipher(blf_ctx *, uint32_t *, uint32_t *);
#ifdef _DEBUG_BLOWFISH
static void Blowfish_decipher(blf_ctx *, uint32_t *, uint32_t *);
#endif
static void Blowfish_initstate(blf_ctx *);
static void Blowfish_expand0state(blf_ctx *, const uint8_t *, uint16_t);
static void Blowfish_expandstate
(blf_ctx *, const uint8_t *, uint16_t, const uint8_t *, uint16_t);
/* Standard Blowfish */
#ifdef _DEBUG_BLOWFISH
static void blf_key(blf_ctx *, const uint8_t *, uint16_t);
#endif
static void blf_enc(blf_ctx *, uint32_t *, uint16_t);
#ifdef _DEBUG_BLOWFISH
static void blf_dec(blf_ctx *, uint32_t *, uint16_t);
#endif
#if 0
static void blf_ecb_encrypt(blf_ctx *, uint8_t *, uint32_t);
static void blf_ecb_decrypt(blf_ctx *, uint8_t *, uint32_t);
static void blf_cbc_encrypt(blf_ctx *, uint8_t *, uint8_t *, uint32_t);
static void blf_cbc_decrypt(blf_ctx *, uint8_t *, uint8_t *, uint32_t);
#endif
/* Converts uint8_t to uint32_t */
static uint32_t Blowfish_stream2word(const uint8_t *, uint16_t, uint16_t *);
/* Function for Feistel Networks */
#define F(s, x) ((((s)[ (((x)>>24)&0xFF)] \
+ (s)[0x100 + (((x)>>16)&0xFF)]) \
^ (s)[0x200 + (((x)>> 8)&0xFF)]) \
+ (s)[0x300 + ( (x) &0xFF)])
#define F(s, x) ((((s)[ (((x) >> 24) & 0xFF)] \
+ (s)[0x100 + (((x) >> 16) & 0xFF)]) \
^ (s)[0x200 + (((x) >> 8) & 0xFF)]) \
+ (s)[0x300 + ( (x) & 0xFF)])
#define BLFRND(s,p,i,j,n) (i ^= F(s,j) ^ (p)[n])
void
static void
Blowfish_encipher(blf_ctx *c, uint32_t *xl, uint32_t *xr)
{
uint32_t Xl;
@ -95,7 +138,8 @@ Blowfish_encipher(blf_ctx *c, uint32_t *xl, uint32_t *xr)
*xr = Xl;
}
void
#ifdef _DEBUG_BLOWFISH
static void
Blowfish_decipher(blf_ctx *c, uint32_t *xl, uint32_t *xr)
{
uint32_t Xl;
@ -119,8 +163,9 @@ Blowfish_decipher(blf_ctx *c, uint32_t *xl, uint32_t *xr)
*xl = Xr ^ p[0];
*xr = Xl;
}
#endif
void
static void
Blowfish_initstate(blf_ctx *c)
{
/* P-box and S-box tables initialized with digits of Pi */
@ -399,7 +444,7 @@ Blowfish_initstate(blf_ctx *c)
*c = initstate;
}
uint32_t
static uint32_t
Blowfish_stream2word(const uint8_t *data, uint16_t databytes,
uint16_t *current)
{
@ -420,12 +465,12 @@ Blowfish_stream2word(const uint8_t *data, uint16_t databytes,
return temp;
}
void
static void
Blowfish_expand0state(blf_ctx *c, const uint8_t *key, uint16_t keybytes)
{
uint16_t i;
int i;
int k;
uint16_t j;
uint16_t k;
uint32_t temp;
uint32_t datal;
uint32_t datar;
@ -457,14 +502,13 @@ Blowfish_expand0state(blf_ctx *c, const uint8_t *key, uint16_t keybytes)
}
}
void
static void
Blowfish_expandstate(blf_ctx *c, const uint8_t *data, uint16_t databytes,
const uint8_t *key, uint16_t keybytes)
{
uint16_t i;
int i;
int k;
uint16_t j;
uint16_t k;
uint32_t temp;
uint32_t datal;
uint32_t datar;
@ -501,7 +545,8 @@ Blowfish_expandstate(blf_ctx *c, const uint8_t *data, uint16_t databytes,
}
void
#ifdef _DEBUG_BLOWFISH
static void
blf_key(blf_ctx *c, const uint8_t *k, uint16_t len)
{
/* Initialize S-boxes and subkeys with Pi */
@ -510,8 +555,9 @@ blf_key(blf_ctx *c, const uint8_t *k, uint16_t len)
/* Transform S-boxes and subkeys with key */
Blowfish_expand0state(c, k, len);
}
#endif
void
static void
blf_enc(blf_ctx *c, uint32_t *data, uint16_t blocks)
{
uint32_t *d;
@ -524,7 +570,8 @@ blf_enc(blf_ctx *c, uint32_t *data, uint16_t blocks)
}
}
void
#ifdef _DEBUG_BLOWFISH
static void
blf_dec(blf_ctx *c, uint32_t *data, uint16_t blocks)
{
uint32_t *d;
@ -536,8 +583,10 @@ blf_dec(blf_ctx *c, uint32_t *data, uint16_t blocks)
d += 2;
}
}
#endif
void
#if 0
static void
blf_ecb_encrypt(blf_ctx *c, uint8_t *data, uint32_t len)
{
uint32_t l, r;
@ -547,11 +596,11 @@ blf_ecb_encrypt(blf_ctx *c, uint8_t *data, uint32_t len)
l = data[0] << 24 | data[1] << 16 | data[2] << 8 | data[3];
r = data[4] << 24 | data[5] << 16 | data[6] << 8 | data[7];
Blowfish_encipher(c, &l, &r);
data[0] = l >> 24 & 0xff;
data[0] = (uint8_t)(l >> 24 & 0xff);
data[1] = l >> 16 & 0xff;
data[2] = l >> 8 & 0xff;
data[3] = l & 0xff;
data[4] = r >> 24 & 0xff;
data[4] = (uint8_t)(r >> 24 & 0xff);
data[5] = r >> 16 & 0xff;
data[6] = r >> 8 & 0xff;
data[7] = r & 0xff;
@ -559,7 +608,7 @@ blf_ecb_encrypt(blf_ctx *c, uint8_t *data, uint32_t len)
}
}
void
static void
blf_ecb_decrypt(blf_ctx *c, uint8_t *data, uint32_t len)
{
uint32_t l, r;
@ -569,11 +618,11 @@ blf_ecb_decrypt(blf_ctx *c, uint8_t *data, uint32_t len)
l = data[0] << 24 | data[1] << 16 | data[2] << 8 | data[3];
r = data[4] << 24 | data[5] << 16 | data[6] << 8 | data[7];
Blowfish_decipher(c, &l, &r);
data[0] = l >> 24 & 0xff;
data[0] = (uint8_t)(l >> 24 & 0xff);
data[1] = l >> 16 & 0xff;
data[2] = l >> 8 & 0xff;
data[3] = l & 0xff;
data[4] = r >> 24 & 0xff;
data[4] = (uint8_t)(r >> 24 & 0xff);
data[5] = r >> 16 & 0xff;
data[6] = r >> 8 & 0xff;
data[7] = r & 0xff;
@ -581,7 +630,7 @@ blf_ecb_decrypt(blf_ctx *c, uint8_t *data, uint32_t len)
}
}
void
static void
blf_cbc_encrypt(blf_ctx *c, uint8_t *iv, uint8_t *data, uint32_t len)
{
uint32_t l, r;
@ -593,11 +642,11 @@ blf_cbc_encrypt(blf_ctx *c, uint8_t *iv, uint8_t *data, uint32_t len)
l = data[0] << 24 | data[1] << 16 | data[2] << 8 | data[3];
r = data[4] << 24 | data[5] << 16 | data[6] << 8 | data[7];
Blowfish_encipher(c, &l, &r);
data[0] = l >> 24 & 0xff;
data[0] = (uint8_t)(l >> 24 & 0xff);
data[1] = l >> 16 & 0xff;
data[2] = l >> 8 & 0xff;
data[3] = l & 0xff;
data[4] = r >> 24 & 0xff;
data[4] = (uint8_t)(r >> 24 & 0xff);
data[5] = r >> 16 & 0xff;
data[6] = r >> 8 & 0xff;
data[7] = r & 0xff;
@ -606,7 +655,7 @@ blf_cbc_encrypt(blf_ctx *c, uint8_t *iv, uint8_t *data, uint32_t len)
}
}
void
static void
blf_cbc_decrypt(blf_ctx *c, uint8_t *iva, uint8_t *data, uint32_t len)
{
uint32_t l, r;
@ -619,11 +668,11 @@ blf_cbc_decrypt(blf_ctx *c, uint8_t *iva, uint8_t *data, uint32_t len)
l = data[0] << 24 | data[1] << 16 | data[2] << 8 | data[3];
r = data[4] << 24 | data[5] << 16 | data[6] << 8 | data[7];
Blowfish_decipher(c, &l, &r);
data[0] = l >> 24 & 0xff;
data[0] = (uint8_t)(l >> 24 & 0xff);
data[1] = l >> 16 & 0xff;
data[2] = l >> 8 & 0xff;
data[3] = l & 0xff;
data[4] = r >> 24 & 0xff;
data[4] = (uint8_t)(r >> 24 & 0xff);
data[5] = r >> 16 & 0xff;
data[6] = r >> 8 & 0xff;
data[7] = r & 0xff;
@ -635,31 +684,31 @@ blf_cbc_decrypt(blf_ctx *c, uint8_t *iva, uint8_t *data, uint32_t len)
l = data[0] << 24 | data[1] << 16 | data[2] << 8 | data[3];
r = data[4] << 24 | data[5] << 16 | data[6] << 8 | data[7];
Blowfish_decipher(c, &l, &r);
data[0] = l >> 24 & 0xff;
data[0] = (uint8_t)(l >> 24 & 0xff);
data[1] = l >> 16 & 0xff;
data[2] = l >> 8 & 0xff;
data[3] = l & 0xff;
data[4] = r >> 24 & 0xff;
data[4] = (uint8_t)(r >> 24 & 0xff);
data[5] = r >> 16 & 0xff;
data[6] = r >> 8 & 0xff;
data[7] = r & 0xff;
for(j = 0; j < 8; j++)
data[j] ^= iva[j];
}
#endif
#if 0
void
#ifdef _DEBUG_BLOWFISH
static void
report(uint32_t data[], uint16_t len)
{
uint16_t i;
int i;
for(i = 0; i < len; i += 2)
printf("Block %0hd: %08lx %08lx.\n",
i / 2, data[i], data[i + 1]);
printf("Block %d: 0x%08lx 0x%08lx.\n",
i / 2, (unsigned long)data[i], (unsigned long)data[i + 1]);
}
void
int
main(void)
{
blf_ctx c;
char key[] = "AAAAA";
char key2[] = "abcdefghijklmnopqrstuvwxyz";
@ -682,12 +731,15 @@ main(void)
report(data, 10);
/* Second test */
blf_key(&c, (uint8_t *) key2, strlen(key2));
blf_key(&c, (uint8_t *) key2, (uint16_t)strlen(key2));
blf_enc(&c, data2, 1);
printf("\nShould read as: 0x324ed0fe 0xf413a203.\n");
report(data2, 2);
blf_dec(&c, data2, 1);
printf("\nShould read as: 0x424c4f57 0x46495348.\n");
report(data2, 2);
return 0;
}
#endif
@ -695,3 +747,5 @@ main(void)
(!defined(HAVE_BLOWFISH_INITSTATE) || \
!defined(HAVE_BLOWFISH_EXPAND0STATE) || \
'!defined(HAVE_BLF_ENC)) */
#endif /* defined(LIBSSH2_BCRYPT_PBKDF_C) || defined(_DEBUG_BLOWFISH) */

View file

@ -0,0 +1,224 @@
/*
* chacha-merged.c version 20080118
* D. J. Bernstein
* Public domain.
* Copyright not intended 2024.
*
* SPDX-License-Identifier: SAX-PD-2.0
*/
#include "libssh2_priv.h"
#include "chacha.h"
/* $OpenBSD: chacha.c,v 1.1 2013/11/21 00:45:44 djm Exp $ */
typedef unsigned char u8;
typedef unsigned int u32;
typedef struct chacha_ctx chacha_ctx;
#define U8C(v) (v##U)
#define U32C(v) (v##U)
#define U8V(v) ((u8)(v) & U8C(0xFF))
#define U32V(v) ((u32)(v) & U32C(0xFFFFFFFF))
#define ROTL32(v, n) \
(U32V((v) << (n)) | ((v) >> (32 - (n))))
#define U8TO32_LITTLE(p) \
(((u32)((p)[0]) ) | \
((u32)((p)[1]) << 8) | \
((u32)((p)[2]) << 16) | \
((u32)((p)[3]) << 24))
#define U32TO8_LITTLE(p, v) \
do { \
(p)[0] = U8V((v) ); \
(p)[1] = U8V((v) >> 8); \
(p)[2] = U8V((v) >> 16); \
(p)[3] = U8V((v) >> 24); \
} while (0)
#define ROTATE(v,c) (ROTL32(v,c))
#define XOR(v,w) ((v) ^ (w))
#define PLUS(v,w) (U32V((v) + (w)))
#define PLUSONE(v) (PLUS((v),1))
#define QUARTERROUND(a,b,c,d) \
a = PLUS(a,b); d = ROTATE(XOR(d,a),16); \
c = PLUS(c,d); b = ROTATE(XOR(b,c),12); \
a = PLUS(a,b); d = ROTATE(XOR(d,a), 8); \
c = PLUS(c,d); b = ROTATE(XOR(b,c), 7);
static const char sigma[17] = "expand 32-byte k";
static const char tau[17] = "expand 16-byte k";
void
chacha_keysetup(chacha_ctx *x, const u8 *k, u32 kbits)
{
const char *constants;
x->input[4] = U8TO32_LITTLE(k + 0);
x->input[5] = U8TO32_LITTLE(k + 4);
x->input[6] = U8TO32_LITTLE(k + 8);
x->input[7] = U8TO32_LITTLE(k + 12);
if(kbits == 256) { /* recommended */
k += 16;
constants = sigma;
}
else { /* kbits == 128 */
constants = tau;
}
x->input[8] = U8TO32_LITTLE(k + 0);
x->input[9] = U8TO32_LITTLE(k + 4);
x->input[10] = U8TO32_LITTLE(k + 8);
x->input[11] = U8TO32_LITTLE(k + 12);
x->input[0] = U8TO32_LITTLE(constants + 0);
x->input[1] = U8TO32_LITTLE(constants + 4);
x->input[2] = U8TO32_LITTLE(constants + 8);
x->input[3] = U8TO32_LITTLE(constants + 12);
}
void
chacha_ivsetup(chacha_ctx *x, const u8 *iv, const u8 *counter)
{
x->input[12] = counter == NULL ? 0 : U8TO32_LITTLE(counter + 0);
x->input[13] = counter == NULL ? 0 : U8TO32_LITTLE(counter + 4);
x->input[14] = U8TO32_LITTLE(iv + 0);
x->input[15] = U8TO32_LITTLE(iv + 4);
}
void
chacha_encrypt_bytes(chacha_ctx *x, const u8 *m, u8 *c, u32 bytes)
{
u32 x0, x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11, x12, x13, x14, x15;
u32 j0, j1, j2, j3, j4, j5, j6, j7, j8, j9, j10, j11, j12, j13, j14, j15;
u8 *ctarget = NULL;
u8 tmp[64];
u_int i;
if(!bytes)
return;
j0 = x->input[0];
j1 = x->input[1];
j2 = x->input[2];
j3 = x->input[3];
j4 = x->input[4];
j5 = x->input[5];
j6 = x->input[6];
j7 = x->input[7];
j8 = x->input[8];
j9 = x->input[9];
j10 = x->input[10];
j11 = x->input[11];
j12 = x->input[12];
j13 = x->input[13];
j14 = x->input[14];
j15 = x->input[15];
for(;;) {
if(bytes < 64) {
for(i = 0; i < bytes;++i) tmp[i] = m[i];
m = tmp;
ctarget = c;
c = tmp;
}
x0 = j0;
x1 = j1;
x2 = j2;
x3 = j3;
x4 = j4;
x5 = j5;
x6 = j6;
x7 = j7;
x8 = j8;
x9 = j9;
x10 = j10;
x11 = j11;
x12 = j12;
x13 = j13;
x14 = j14;
x15 = j15;
for(i = 20; i > 0; i -= 2) {
QUARTERROUND(x0, x4, x8, x12)
QUARTERROUND(x1, x5, x9, x13)
QUARTERROUND(x2, x6, x10, x14)
QUARTERROUND(x3, x7, x11, x15)
QUARTERROUND(x0, x5, x10, x15)
QUARTERROUND(x1, x6, x11, x12)
QUARTERROUND(x2, x7, x8, x13)
QUARTERROUND(x3, x4, x9, x14)
}
x0 = PLUS(x0, j0);
x1 = PLUS(x1, j1);
x2 = PLUS(x2, j2);
x3 = PLUS(x3, j3);
x4 = PLUS(x4, j4);
x5 = PLUS(x5, j5);
x6 = PLUS(x6, j6);
x7 = PLUS(x7, j7);
x8 = PLUS(x8, j8);
x9 = PLUS(x9, j9);
x10 = PLUS(x10, j10);
x11 = PLUS(x11, j11);
x12 = PLUS(x12, j12);
x13 = PLUS(x13, j13);
x14 = PLUS(x14, j14);
x15 = PLUS(x15, j15);
x0 = XOR(x0, U8TO32_LITTLE(m + 0));
x1 = XOR(x1, U8TO32_LITTLE(m + 4));
x2 = XOR(x2, U8TO32_LITTLE(m + 8));
x3 = XOR(x3, U8TO32_LITTLE(m + 12));
x4 = XOR(x4, U8TO32_LITTLE(m + 16));
x5 = XOR(x5, U8TO32_LITTLE(m + 20));
x6 = XOR(x6, U8TO32_LITTLE(m + 24));
x7 = XOR(x7, U8TO32_LITTLE(m + 28));
x8 = XOR(x8, U8TO32_LITTLE(m + 32));
x9 = XOR(x9, U8TO32_LITTLE(m + 36));
x10 = XOR(x10, U8TO32_LITTLE(m + 40));
x11 = XOR(x11, U8TO32_LITTLE(m + 44));
x12 = XOR(x12, U8TO32_LITTLE(m + 48));
x13 = XOR(x13, U8TO32_LITTLE(m + 52));
x14 = XOR(x14, U8TO32_LITTLE(m + 56));
x15 = XOR(x15, U8TO32_LITTLE(m + 60));
j12 = PLUSONE(j12);
if(!j12) {
j13 = PLUSONE(j13);
/* stopping at 2^70 bytes per nonce is user's responsibility */
}
U32TO8_LITTLE(c + 0, x0);
U32TO8_LITTLE(c + 4, x1);
U32TO8_LITTLE(c + 8, x2);
U32TO8_LITTLE(c + 12, x3);
U32TO8_LITTLE(c + 16, x4);
U32TO8_LITTLE(c + 20, x5);
U32TO8_LITTLE(c + 24, x6);
U32TO8_LITTLE(c + 28, x7);
U32TO8_LITTLE(c + 32, x8);
U32TO8_LITTLE(c + 36, x9);
U32TO8_LITTLE(c + 40, x10);
U32TO8_LITTLE(c + 44, x11);
U32TO8_LITTLE(c + 48, x12);
U32TO8_LITTLE(c + 52, x13);
U32TO8_LITTLE(c + 56, x14);
U32TO8_LITTLE(c + 60, x15);
if(bytes <= 64) {
if(bytes < 64) {
for(i = 0; i < bytes;++i) ctarget[i] = c[i];
}
x->input[12] = j12;
x->input[13] = j13;
return;
}
bytes -= 64;
c += 64;
m += 64;
}
}

View file

@ -0,0 +1,33 @@
/* $OpenBSD: chacha.h,v 1.4 2016/08/27 04:04:56 guenther Exp $ */
/*
* chacha-merged.c version 20080118
* D. J. Bernstein
* Public domain.
* Copyright not intended 2024.
*
* SPDX-License-Identifier: SAX-PD-2.0
*/
#ifndef CHACHA_H
#define CHACHA_H
#include <stdlib.h>
struct chacha_ctx {
u_int input[16];
};
#define CHACHA_MINKEYLEN 16
#define CHACHA_NONCELEN 8
#define CHACHA_CTRLEN 8
#define CHACHA_STATELEN (CHACHA_NONCELEN+CHACHA_CTRLEN)
#define CHACHA_BLOCKLEN 64
void chacha_keysetup(struct chacha_ctx *x, const u_char *k, u_int kbits);
void chacha_ivsetup(struct chacha_ctx *x, const u_char *iv, const u_char *ctr);
void chacha_encrypt_bytes(struct chacha_ctx *x, const u_char *m,
u_char *c, u_int bytes);
#endif /* CHACHA_H */

View file

@ -1,7 +1,6 @@
/* Copyright (c) 2004-2007 Sara Golemon <sarag@libssh2.org>
* Copyright (c) 2005 Mikhail Gusarov <dottedmag@dottedmag.net>
* Copyright (c) 2008-2019 by Daniel Stenberg
*
/* Copyright (C) Sara Golemon <sarag@libssh2.org>
* Copyright (C) Mikhail Gusarov <dottedmag@dottedmag.net>
* Copyright (C) Daniel Stenberg
* All rights reserved.
*
* Redistribution and use in source and binary forms,
@ -36,16 +35,19 @@
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
* USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
* OF SUCH DAMAGE.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#include "libssh2_priv.h"
#ifdef HAVE_UNISTD_H
#include <unistd.h>
#endif
#include <fcntl.h>
#ifdef HAVE_INTTYPES_H
#include <inttypes.h>
#endif
#include <assert.h>
#include "channel.h"
@ -81,8 +83,8 @@ _libssh2_channel_nextid(LIBSSH2_SESSION * session)
* told...
*/
session->next_channel = id + 1;
_libssh2_debug(session, LIBSSH2_TRACE_CONN, "Allocated new channel ID#%lu",
id);
_libssh2_debug((session, LIBSSH2_TRACE_CONN,
"Allocated new channel ID#%u", id));
return id;
}
@ -154,9 +156,9 @@ _libssh2_channel_open(LIBSSH2_SESSION * session, const char *channel_type,
memset(&session->open_packet_requirev_state, 0,
sizeof(session->open_packet_requirev_state));
_libssh2_debug(session, LIBSSH2_TRACE_CONN,
_libssh2_debug((session, LIBSSH2_TRACE_CONN,
"Opening Channel - win %d pack %d", window_size,
packet_size);
packet_size));
session->open_channel =
LIBSSH2_CALLOC(session, sizeof(LIBSSH2_CHANNEL));
if(!session->open_channel) {
@ -262,15 +264,15 @@ _libssh2_channel_open(LIBSSH2_SESSION * session, const char *channel_type,
_libssh2_ntohu32(session->open_data + 9);
session->open_channel->local.packet_size =
_libssh2_ntohu32(session->open_data + 13);
_libssh2_debug(session, LIBSSH2_TRACE_CONN,
"Connection Established - ID: %lu/%lu win: %lu/%lu"
" pack: %lu/%lu",
_libssh2_debug((session, LIBSSH2_TRACE_CONN,
"Connection Established - ID: %u/%u win: %u/%u"
" pack: %u/%u",
session->open_channel->local.id,
session->open_channel->remote.id,
session->open_channel->local.window_size,
session->open_channel->remote.window_size,
session->open_channel->local.packet_size,
session->open_channel->remote.packet_size);
session->open_channel->remote.packet_size));
LIBSSH2_FREE(session, session->open_packet);
session->open_packet = NULL;
LIBSSH2_FREE(session, session->open_data);
@ -308,7 +310,7 @@ _libssh2_channel_open(LIBSSH2_SESSION * session, const char *channel_type,
}
}
channel_error:
channel_error:
if(session->open_data) {
LIBSSH2_FREE(session, session->open_data);
@ -327,14 +329,14 @@ _libssh2_channel_open(LIBSSH2_SESSION * session, const char *channel_type,
/* Clear out packets meant for this channel */
_libssh2_htonu32(channel_id, session->open_channel->local.id);
while((_libssh2_packet_ask(session, SSH_MSG_CHANNEL_DATA,
&session->open_data,
&session->open_data_len, 1,
channel_id, 4) >= 0)
||
(_libssh2_packet_ask(session, SSH_MSG_CHANNEL_EXTENDED_DATA,
&session->open_data,
&session->open_data_len, 1,
channel_id, 4) >= 0)) {
&session->open_data,
&session->open_data_len, 1,
channel_id, 4) >= 0)
||
(_libssh2_packet_ask(session, SSH_MSG_CHANNEL_EXTENDED_DATA,
&session->open_data,
&session->open_data_len, 1,
channel_id, 4) >= 0)) {
LIBSSH2_FREE(session, session->open_data);
session->open_data = NULL;
}
@ -390,9 +392,9 @@ channel_direct_tcpip(LIBSSH2_SESSION * session, const char *host,
session->direct_message_len =
session->direct_host_len + session->direct_shost_len + 16;
_libssh2_debug(session, LIBSSH2_TRACE_CONN,
_libssh2_debug((session, LIBSSH2_TRACE_CONN,
"Requesting direct-tcpip session from %s:%d to %s:%d",
shost, sport, host, port);
shost, sport, host, port));
s = session->direct_message =
LIBSSH2_ALLOC(session, session->direct_message_len);
@ -452,6 +454,85 @@ libssh2_channel_direct_tcpip_ex(LIBSSH2_SESSION *session, const char *host,
return ptr;
}
/*
* libssh2_channel_direct_streamlocal_ex
*
* Tunnel TCP/IP connect through the SSH session to direct UNIX socket
*/
static LIBSSH2_CHANNEL *
channel_direct_streamlocal(LIBSSH2_SESSION * session, const char *socket_path,
const char *shost, int sport)
{
LIBSSH2_CHANNEL *channel;
unsigned char *s;
if(session->direct_state == libssh2_NB_state_idle) {
session->direct_host_len = strlen(socket_path);
session->direct_shost_len = strlen(shost);
session->direct_message_len =
session->direct_host_len + session->direct_shost_len + 12;
_libssh2_debug((session, LIBSSH2_TRACE_CONN,
"Requesting direct-streamlocal session to %s",
socket_path));
s = session->direct_message =
LIBSSH2_ALLOC(session, session->direct_message_len);
if(!session->direct_message) {
_libssh2_error(session, LIBSSH2_ERROR_ALLOC,
"Unable to allocate memory for direct-streamlocal connection");
return NULL;
}
_libssh2_store_str(&s, socket_path, session->direct_host_len);
_libssh2_store_str(&s, shost, session->direct_shost_len);
_libssh2_store_u32(&s, sport);
}
channel =
_libssh2_channel_open(session, "direct-streamlocal@openssh.com",
sizeof("direct-streamlocal@openssh.com") - 1,
LIBSSH2_CHANNEL_WINDOW_DEFAULT,
LIBSSH2_CHANNEL_PACKET_DEFAULT,
session->direct_message,
session->direct_message_len);
if(!channel &&
libssh2_session_last_errno(session) == LIBSSH2_ERROR_EAGAIN) {
/* The error code is still set to LIBSSH2_ERROR_EAGAIN, set our state
to created to avoid re-creating the package on next invoke */
session->direct_state = libssh2_NB_state_created;
return NULL;
}
/* by default we set (keep?) idle state... */
session->direct_state = libssh2_NB_state_idle;
LIBSSH2_FREE(session, session->direct_message);
session->direct_message = NULL;
return channel;
}
/*
* libssh2_channel_direct_streamlocal_ex
*
* Tunnel TCP/IP connect through the SSH session to direct UNIX socket
*/
LIBSSH2_API LIBSSH2_CHANNEL *
libssh2_channel_direct_streamlocal_ex(LIBSSH2_SESSION * session,
const char *socket_path,
const char *shost, int sport)
{
LIBSSH2_CHANNEL *ptr;
if(!session)
return NULL;
BLOCK_ADJUST_ERRNO(ptr, session,
channel_direct_streamlocal(session,
socket_path, shost, sport));
return ptr;
}
/*
* channel_forward_listen
*
@ -470,19 +551,20 @@ channel_forward_listen(LIBSSH2_SESSION * session, const char *host,
host = "0.0.0.0";
if(session->fwdLstn_state == libssh2_NB_state_idle) {
session->fwdLstn_host_len = strlen(host);
session->fwdLstn_host_len = (uint32_t)strlen(host);
/* 14 = packet_type(1) + request_len(4) + want_replay(1) + host_len(4)
+ port(4) */
session->fwdLstn_packet_len =
session->fwdLstn_host_len + (sizeof("tcpip-forward") - 1) + 14;
session->fwdLstn_host_len +
(uint32_t)(sizeof("tcpip-forward") - 1) + 14;
/* Zero the whole thing out */
memset(&session->fwdLstn_packet_requirev_state, 0,
sizeof(session->fwdLstn_packet_requirev_state));
_libssh2_debug(session, LIBSSH2_TRACE_CONN,
_libssh2_debug((session, LIBSSH2_TRACE_CONN,
"Requesting tcpip-forward session for %s:%d", host,
port);
port));
s = session->fwdLstn_packet =
LIBSSH2_ALLOC(session, session->fwdLstn_packet_len);
@ -567,10 +649,10 @@ channel_forward_listen(LIBSSH2_SESSION * session, const char *host,
listener->host[session->fwdLstn_host_len] = 0;
if(data_len >= 5 && !port) {
listener->port = _libssh2_ntohu32(data + 1);
_libssh2_debug(session, LIBSSH2_TRACE_CONN,
_libssh2_debug((session, LIBSSH2_TRACE_CONN,
"Dynamic tcpip-forward port "
"allocated: %d",
listener->port);
listener->port));
}
else
listener->port = port;
@ -647,9 +729,9 @@ int _libssh2_channel_forward_cancel(LIBSSH2_LISTENER *listener)
int retcode = 0;
if(listener->chanFwdCncl_state == libssh2_NB_state_idle) {
_libssh2_debug(session, LIBSSH2_TRACE_CONN,
_libssh2_debug((session, LIBSSH2_TRACE_CONN,
"Cancelling tcpip-forward session for %s:%d",
listener->host, listener->port);
listener->host, listener->port));
s = packet = LIBSSH2_ALLOC(session, packet_len);
if(!packet) {
@ -818,10 +900,10 @@ static int channel_setenv(LIBSSH2_CHANNEL *channel,
memset(&channel->setenv_packet_requirev_state, 0,
sizeof(channel->setenv_packet_requirev_state));
_libssh2_debug(session, LIBSSH2_TRACE_CONN,
_libssh2_debug((session, LIBSSH2_TRACE_CONN,
"Setting remote environment variable: %s=%s on "
"channel %lu/%lu",
varname, value, channel->local.id, channel->remote.id);
"channel %u/%u",
varname, value, channel->local.id, channel->remote.id));
s = channel->setenv_packet =
LIBSSH2_ALLOC(session, channel->setenv_packet_len);
@ -877,7 +959,9 @@ static int channel_setenv(LIBSSH2_CHANNEL *channel,
}
if(rc) {
channel->setenv_state = libssh2_NB_state_idle;
return rc;
return _libssh2_error(session, rc,
"Failed getting response for "
"channel-setenv");
}
else if(data_len < 1) {
channel->setenv_state = libssh2_NB_state_idle;
@ -951,9 +1035,9 @@ static int channel_request_pty(LIBSSH2_CHANNEL *channel,
memset(&channel->reqPTY_packet_requirev_state, 0,
sizeof(channel->reqPTY_packet_requirev_state));
_libssh2_debug(session, LIBSSH2_TRACE_CONN,
"Allocating tty on channel %lu/%lu", channel->local.id,
channel->remote.id);
_libssh2_debug((session, LIBSSH2_TRACE_CONN,
"Allocating tty on channel %u/%u", channel->local.id,
channel->remote.id));
s = channel->reqPTY_packet;
@ -1054,9 +1138,9 @@ static int channel_request_auth_agent(LIBSSH2_CHANNEL *channel,
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);
_libssh2_debug((session, LIBSSH2_TRACE_CONN,
"Requesting auth agent on channel %u/%u",
channel->local.id, channel->remote.id));
/*
* byte SSH_MSG_CHANNEL_REQUEST
@ -1083,6 +1167,7 @@ static int channel_request_auth_agent(LIBSSH2_CHANNEL *channel,
if(rc == LIBSSH2_ERROR_EAGAIN) {
_libssh2_error(session, rc,
"Would block sending auth-agent request");
return rc;
}
else if(rc) {
channel->req_auth_agent_state = libssh2_NB_state_idle;
@ -1099,10 +1184,10 @@ static int channel_request_auth_agent(LIBSSH2_CHANNEL *channel,
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);
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;
}
@ -1125,13 +1210,14 @@ static int channel_request_auth_agent(LIBSSH2_CHANNEL *channel,
"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)
{
@ -1140,6 +1226,8 @@ libssh2_channel_request_auth_agent(LIBSSH2_CHANNEL *channel)
if(!channel)
return LIBSSH2_ERROR_BAD_USE;
rc = LIBSSH2_ERROR_CHANNEL_UNKNOWN;
/* 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
@ -1152,7 +1240,8 @@ libssh2_channel_request_auth_agent(LIBSSH2_CHANNEL *channel)
/* 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)
if(rc != LIBSSH2_ERROR_NONE &&
rc != LIBSSH2_ERROR_EAGAIN)
channel->req_auth_agent_try_state = libssh2_NB_state_sent;
}
@ -1163,12 +1252,13 @@ libssh2_channel_request_auth_agent(LIBSSH2_CHANNEL *channel)
/* If we failed without an EAGAIN, then move on with this
* state machine. */
if(rc != 0 && rc != LIBSSH2_ERROR_EAGAIN)
if(rc != LIBSSH2_ERROR_NONE &&
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)
if(rc == LIBSSH2_ERROR_NONE)
channel->req_auth_agent_try_state = libssh2_NB_state_idle;
return rc;
@ -1212,10 +1302,10 @@ channel_request_pty_size(LIBSSH2_CHANNEL * channel, int width,
memset(&channel->reqPTY_packet_requirev_state, 0,
sizeof(channel->reqPTY_packet_requirev_state));
_libssh2_debug(session, LIBSSH2_TRACE_CONN,
"changing tty size on channel %lu/%lu",
channel->local.id,
channel->remote.id);
_libssh2_debug((session, LIBSSH2_TRACE_CONN,
"changing tty size on channel %u/%u",
channel->local.id,
channel->remote.id));
s = channel->reqPTY_packet;
@ -1301,13 +1391,13 @@ channel_x11_req(LIBSSH2_CHANNEL *channel, int single_connection,
memset(&channel->reqX11_packet_requirev_state, 0,
sizeof(channel->reqX11_packet_requirev_state));
_libssh2_debug(session, LIBSSH2_TRACE_CONN,
"Requesting x11-req for channel %lu/%lu: single=%d "
_libssh2_debug((session, LIBSSH2_TRACE_CONN,
"Requesting x11-req for channel %u/%u: single=%d "
"proto=%s cookie=%s screen=%d",
channel->local.id, channel->remote.id,
single_connection,
auth_proto ? auth_proto : "MIT-MAGIC-COOKIE-1",
auth_cookie ? auth_cookie : "<random>", screen_number);
auth_cookie ? auth_cookie : "<random>", screen_number));
s = channel->reqX11_packet =
LIBSSH2_ALLOC(session, channel->reqX11_packet_len);
@ -1326,7 +1416,7 @@ channel_x11_req(LIBSSH2_CHANNEL *channel, int single_connection,
_libssh2_store_str(&s, auth_proto ? auth_proto : "MIT-MAGIC-COOKIE-1",
proto_len);
_libssh2_store_u32(&s, cookie_len);
_libssh2_store_u32(&s, (uint32_t)cookie_len);
if(auth_cookie) {
memcpy(s, auth_cookie, cookie_len);
}
@ -1459,10 +1549,10 @@ _libssh2_channel_process_startup(LIBSSH2_CHANNEL *channel,
if(message)
channel->process_packet_len += + 4;
_libssh2_debug(session, LIBSSH2_TRACE_CONN,
"starting request(%s) on channel %lu/%lu, message=%s",
_libssh2_debug((session, LIBSSH2_TRACE_CONN,
"starting request(%s) on channel %u/%u, message=%s",
request, channel->local.id, channel->remote.id,
message ? message : "<null>");
message ? message : "<null>"));
s = channel->process_packet =
LIBSSH2_ALLOC(session, channel->process_packet_len);
if(!channel->process_packet)
@ -1476,7 +1566,7 @@ _libssh2_channel_process_startup(LIBSSH2_CHANNEL *channel,
*(s++) = 0x01;
if(message)
_libssh2_store_u32(&s, message_len);
_libssh2_store_u32(&s, (uint32_t)message_len);
channel->process_state = libssh2_NB_state_created;
}
@ -1567,7 +1657,7 @@ LIBSSH2_API void
libssh2_channel_set_blocking(LIBSSH2_CHANNEL * channel, int blocking)
{
if(channel)
(void) _libssh2_session_set_blocking(channel->session, blocking);
(void)_libssh2_session_set_blocking(channel->session, blocking);
}
/*
@ -1591,8 +1681,8 @@ _libssh2_channel_flush(LIBSSH2_CHANNEL *channel, int streamid)
if(packet->data_len < 1) {
packet = next;
_libssh2_debug(channel->session, LIBSSH2_TRACE_ERROR,
"Unexpected packet length");
_libssh2_debug((channel->session, LIBSSH2_TRACE_ERROR,
"Unexpected packet length"));
continue;
}
@ -1628,11 +1718,11 @@ _libssh2_channel_flush(LIBSSH2_CHANNEL *channel, int streamid)
size_t bytes_to_flush = packet->data_len -
packet->data_head;
_libssh2_debug(channel->session, LIBSSH2_TRACE_CONN,
"Flushing %d bytes of data from stream "
"%lu on channel %lu/%lu",
bytes_to_flush, packet_stream_id,
channel->local.id, channel->remote.id);
_libssh2_debug((channel->session, LIBSSH2_TRACE_CONN,
"Flushing %ld bytes of data from stream "
"%d on channel %u/%u",
(long)bytes_to_flush, packet_stream_id,
channel->local.id, channel->remote.id));
/* It's one of the streams we wanted to flush */
channel->flush_refund_bytes += packet->data_len - 13;
@ -1652,20 +1742,20 @@ _libssh2_channel_flush(LIBSSH2_CHANNEL *channel, int streamid)
}
channel->read_avail -= channel->flush_flush_bytes;
channel->remote.window_size -= channel->flush_flush_bytes;
channel->remote.window_size -= (uint32_t)channel->flush_flush_bytes;
if(channel->flush_refund_bytes) {
int rc =
_libssh2_channel_receive_window_adjust(channel,
channel->flush_refund_bytes,
1, NULL);
(uint32_t)channel->flush_refund_bytes,
1, NULL);
if(rc == LIBSSH2_ERROR_EAGAIN)
return rc;
}
channel->flush_state = libssh2_NB_state_idle;
return channel->flush_flush_bytes;
return (int)channel->flush_flush_bytes;
}
/*
@ -1734,7 +1824,7 @@ libssh2_channel_get_exit_signal(LIBSSH2_CHANNEL *channel,
*exitsignal = LIBSSH2_ALLOC(session, namelen + 1);
if(!*exitsignal) {
return _libssh2_error(session, LIBSSH2_ERROR_ALLOC,
"Unable to allocate memory for signal name");
"Unable to allocate memory for signal name");
}
memcpy(*exitsignal, channel->exit_signal, namelen);
(*exitsignal)[namelen] = '\0';
@ -1791,10 +1881,10 @@ _libssh2_channel_receive_window_adjust(LIBSSH2_CHANNEL * channel,
if(!force
&& (adjustment + channel->adjust_queue <
LIBSSH2_CHANNEL_MINADJUST)) {
_libssh2_debug(channel->session, LIBSSH2_TRACE_CONN,
"Queueing %lu bytes for receive window adjustment "
"for channel %lu/%lu",
adjustment, channel->local.id, channel->remote.id);
_libssh2_debug((channel->session, LIBSSH2_TRACE_CONN,
"Queueing %u bytes for receive window adjustment "
"for channel %u/%u",
adjustment, channel->local.id, channel->remote.id));
channel->adjust_queue += adjustment;
return 0;
}
@ -1810,10 +1900,10 @@ _libssh2_channel_receive_window_adjust(LIBSSH2_CHANNEL * channel,
channel->adjust_adjust[0] = SSH_MSG_CHANNEL_WINDOW_ADJUST;
_libssh2_htonu32(&channel->adjust_adjust[1], channel->remote.id);
_libssh2_htonu32(&channel->adjust_adjust[5], adjustment);
_libssh2_debug(channel->session, LIBSSH2_TRACE_CONN,
"Adjusting window %lu bytes for data on "
"channel %lu/%lu",
adjustment, channel->local.id, channel->remote.id);
_libssh2_debug((channel->session, LIBSSH2_TRACE_CONN,
"Adjusting window %u bytes for data on "
"channel %u/%u",
adjustment, channel->local.id, channel->remote.id));
channel->adjust_state = libssh2_NB_state_created;
}
@ -1840,10 +1930,9 @@ _libssh2_channel_receive_window_adjust(LIBSSH2_CHANNEL * channel,
return 0;
}
#ifndef LIBSSH2_NO_DEPRECATED
/*
* libssh2_channel_receive_window_adjust
*
* DEPRECATED
* libssh2_channel_receive_window_adjust (DEPRECATED, DO NOT USE!)
*
* Adjust the receive window for a channel by adjustment bytes. If the amount
* to be adjusted is less than LIBSSH2_CHANNEL_MINADJUST and force is 0 the
@ -1865,13 +1954,15 @@ libssh2_channel_receive_window_adjust(LIBSSH2_CHANNEL *channel,
return (unsigned long)LIBSSH2_ERROR_BAD_USE;
BLOCK_ADJUST(rc, channel->session,
_libssh2_channel_receive_window_adjust(channel, adj,
_libssh2_channel_receive_window_adjust(channel,
(uint32_t)adj,
force, &window));
/* stupid - but this is how it was made to work before and this is just
kept for backwards compatibility */
return rc ? (unsigned long)rc : window;
}
#endif
/*
* libssh2_channel_receive_window_adjust2
@ -1896,8 +1987,9 @@ libssh2_channel_receive_window_adjust2(LIBSSH2_CHANNEL *channel,
return LIBSSH2_ERROR_BAD_USE;
BLOCK_ADJUST(rc, channel->session,
_libssh2_channel_receive_window_adjust(channel, adj, force,
window));
_libssh2_channel_receive_window_adjust(channel,
(uint32_t)adj,
force, window));
return rc;
}
@ -1905,10 +1997,10 @@ int
_libssh2_channel_extended_data(LIBSSH2_CHANNEL *channel, int ignore_mode)
{
if(channel->extData2_state == libssh2_NB_state_idle) {
_libssh2_debug(channel->session, LIBSSH2_TRACE_CONN,
"Setting channel %lu/%lu handle_extended_data"
_libssh2_debug((channel->session, LIBSSH2_TRACE_CONN,
"Setting channel %u/%u handle_extended_data"
" mode to %d",
channel->local.id, channel->remote.id, ignore_mode);
channel->local.id, channel->remote.id, ignore_mode));
channel->remote.extended_data_ignore_mode = (char)ignore_mode;
channel->extData2_state = libssh2_NB_state_created;
@ -1929,7 +2021,7 @@ _libssh2_channel_extended_data(LIBSSH2_CHANNEL *channel, int ignore_mode)
}
/*
* libssh2_channel_handle_extended_data2()
* libssh2_channel_handle_extended_data2
*
*/
LIBSSH2_API int
@ -1946,10 +2038,9 @@ libssh2_channel_handle_extended_data2(LIBSSH2_CHANNEL *channel,
return rc;
}
#ifndef LIBSSH2_NO_DEPRECATED
/*
* libssh2_channel_handle_extended_data
*
* DEPRECATED DO NOTE USE!
* libssh2_channel_handle_extended_data (DEPRECATED, DO NOT USE!)
*
* How should extended data look to the calling app? Keep it in separate
* channels[_read() _read_stdder()]? (NORMAL) Merge the extended data to the
@ -1962,7 +2053,7 @@ libssh2_channel_handle_extended_data(LIBSSH2_CHANNEL *channel,
{
(void)libssh2_channel_handle_extended_data2(channel, ignore_mode);
}
#endif
/*
@ -1988,19 +2079,19 @@ ssize_t _libssh2_channel_read(LIBSSH2_CHANNEL *channel, int stream_id,
LIBSSH2_PACKET *read_packet;
LIBSSH2_PACKET *read_next;
_libssh2_debug(session, LIBSSH2_TRACE_CONN,
"channel_read() wants %d bytes from channel %lu/%lu "
_libssh2_debug((session, LIBSSH2_TRACE_CONN,
"channel_read() wants %ld bytes from channel %u/%u "
"stream #%d",
(int) buflen, channel->local.id, channel->remote.id,
stream_id);
(long)buflen, channel->local.id, channel->remote.id,
stream_id));
/* expand the receiving window first if it has become too narrow */
if((channel->read_state == libssh2_NB_state_jump1) ||
(channel->remote.window_size <
channel->remote.window_size_initial / 4 * 3 + buflen) ) {
channel->remote.window_size_initial / 4 * 3 + buflen)) {
uint32_t adjustment = channel->remote.window_size_initial + buflen -
channel->remote.window_size;
uint32_t adjustment = (uint32_t)(channel->remote.window_size_initial +
buflen - channel->remote.window_size);
if(adjustment < LIBSSH2_CHANNEL_MINADJUST)
adjustment = LIBSSH2_CHANNEL_MINADJUST;
@ -2041,8 +2132,13 @@ ssize_t _libssh2_channel_read(LIBSSH2_CHANNEL *channel, int stream_id,
if(readpkt->data_len < 5) {
read_packet = read_next;
_libssh2_debug(channel->session, LIBSSH2_TRACE_ERROR,
"Unexpected packet length");
if(readpkt->data_len != 1 ||
readpkt->data[0] != SSH_MSG_REQUEST_FAILURE) {
_libssh2_debug((channel->session, LIBSSH2_TRACE_ERROR,
"Unexpected packet length"));
}
continue;
}
@ -2080,11 +2176,11 @@ ssize_t _libssh2_channel_read(LIBSSH2_CHANNEL *channel, int stream_id,
unlink_packet = TRUE;
}
_libssh2_debug(session, LIBSSH2_TRACE_CONN,
"channel_read() got %d of data from %lu/%lu/%d%s",
bytes_want, channel->local.id,
_libssh2_debug((session, LIBSSH2_TRACE_CONN,
"channel_read() got %ld of data from %u/%u/%d%s",
(long)bytes_want, channel->local.id,
channel->remote.id, stream_id,
unlink_packet?" [ul]":"");
unlink_packet ? " [ul]" : ""));
/* copy data from this struct to the target buffer */
memcpy(&buf[bytes_read],
@ -2123,7 +2219,7 @@ ssize_t _libssh2_channel_read(LIBSSH2_CHANNEL *channel, int stream_id,
}
channel->read_avail -= bytes_read;
channel->remote.window_size -= bytes_read;
channel->remote.window_size -= (uint32_t)bytes_read;
return bytes_read;
}
@ -2146,7 +2242,7 @@ LIBSSH2_API ssize_t
libssh2_channel_read_ex(LIBSSH2_CHANNEL *channel, int stream_id, char *buf,
size_t buflen)
{
int rc;
ssize_t rc;
unsigned long recv_window;
if(!channel)
@ -2156,8 +2252,8 @@ libssh2_channel_read_ex(LIBSSH2_CHANNEL *channel, int stream_id, char *buf,
if(buflen > recv_window) {
BLOCK_ADJUST(rc, channel->session,
_libssh2_channel_receive_window_adjust(channel, buflen,
1, NULL));
_libssh2_channel_receive_window_adjust(channel,
(uint32_t)buflen, 1, NULL));
}
BLOCK_ADJUST(rc, channel->session,
@ -2180,7 +2276,7 @@ _libssh2_channel_packet_data_len(LIBSSH2_CHANNEL * channel, int stream_id)
uint32_t read_local_id;
read_packet = _libssh2_list_first(&session->packets);
if(read_packet == NULL)
if(!read_packet)
return 0;
while(read_packet) {
@ -2189,8 +2285,8 @@ _libssh2_channel_packet_data_len(LIBSSH2_CHANNEL * channel, int stream_id)
if(read_packet->data_len < 5) {
read_packet = next_packet;
_libssh2_debug(channel->session, LIBSSH2_TRACE_ERROR,
"Unexpected packet length");
_libssh2_debug((channel->session, LIBSSH2_TRACE_ERROR,
"Unexpected packet length"));
continue;
}
@ -2218,7 +2314,7 @@ _libssh2_channel_packet_data_len(LIBSSH2_CHANNEL * channel, int stream_id)
&& (channel->local.id == read_local_id)
&& (channel->remote.extended_data_ignore_mode
== LIBSSH2_CHANNEL_EXTENDED_DATA_MERGE))) {
return (read_packet->data_len - read_packet->data_head);
return read_packet->data_len - read_packet->data_head;
}
read_packet = next_packet;
@ -2258,15 +2354,15 @@ _libssh2_channel_write(LIBSSH2_CHANNEL *channel, int stream_id,
if(channel->write_state == libssh2_NB_state_idle) {
unsigned char *s = channel->write_packet;
_libssh2_debug(channel->session, LIBSSH2_TRACE_CONN,
"Writing %d bytes on channel %lu/%lu, stream #%d",
(int) buflen, channel->local.id, channel->remote.id,
stream_id);
_libssh2_debug((channel->session, LIBSSH2_TRACE_CONN,
"Writing %ld bytes on channel %u/%u, stream #%d",
(long)buflen, channel->local.id, channel->remote.id,
stream_id));
if(channel->local.close)
return _libssh2_error(channel->session,
LIBSSH2_ERROR_CHANNEL_CLOSED,
"We've already closed this channel");
"We have already closed this channel");
else if(channel->local.eof)
return _libssh2_error(channel->session,
LIBSSH2_ERROR_CHANNEL_EOF_SENT,
@ -2293,7 +2389,7 @@ _libssh2_channel_write(LIBSSH2_CHANNEL *channel, int stream_id,
*/
session->socket_block_directions = LIBSSH2_SESSION_BLOCK_INBOUND;
return (rc == LIBSSH2_ERROR_EAGAIN?rc:0);
return rc == LIBSSH2_ERROR_EAGAIN ? rc : 0;
}
channel->write_bufwrite = buflen;
@ -2307,30 +2403,30 @@ _libssh2_channel_write(LIBSSH2_CHANNEL *channel, int stream_id,
/* Don't exceed the remote end's limits */
/* REMEMBER local means local as the SOURCE of the data */
if(channel->write_bufwrite > channel->local.window_size) {
_libssh2_debug(session, LIBSSH2_TRACE_CONN,
"Splitting write block due to %lu byte "
"window_size on %lu/%lu/%d",
_libssh2_debug((session, LIBSSH2_TRACE_CONN,
"Splitting write block due to %u byte "
"window_size on %u/%u/%d",
channel->local.window_size, channel->local.id,
channel->remote.id, stream_id);
channel->remote.id, stream_id));
channel->write_bufwrite = channel->local.window_size;
}
if(channel->write_bufwrite > channel->local.packet_size) {
_libssh2_debug(session, LIBSSH2_TRACE_CONN,
"Splitting write block due to %lu byte "
"packet_size on %lu/%lu/%d",
_libssh2_debug((session, LIBSSH2_TRACE_CONN,
"Splitting write block due to %u byte "
"packet_size on %u/%u/%d",
channel->local.packet_size, channel->local.id,
channel->remote.id, stream_id);
channel->remote.id, stream_id));
channel->write_bufwrite = channel->local.packet_size;
}
/* store the size here only, the buffer is passed in as-is to
_libssh2_transport_send() */
_libssh2_store_u32(&s, channel->write_bufwrite);
_libssh2_store_u32(&s, (uint32_t)channel->write_bufwrite);
channel->write_packet_len = s - channel->write_packet;
_libssh2_debug(session, LIBSSH2_TRACE_CONN,
"Sending %d bytes on channel %lu/%lu, stream_id=%d",
(int) channel->write_bufwrite, channel->local.id,
channel->remote.id, stream_id);
_libssh2_debug((session, LIBSSH2_TRACE_CONN,
"Sending %ld bytes on channel %u/%u, stream_id=%d",
(long)channel->write_bufwrite, channel->local.id,
channel->remote.id, stream_id));
channel->write_state = libssh2_NB_state_created;
}
@ -2349,7 +2445,7 @@ _libssh2_channel_write(LIBSSH2_CHANNEL *channel, int stream_id,
"Unable to send channel data");
}
/* Shrink local window size */
channel->local.window_size -= channel->write_bufwrite;
channel->local.window_size -= (uint32_t)channel->write_bufwrite;
wrote += channel->write_bufwrite;
@ -2402,9 +2498,9 @@ static int channel_send_eof(LIBSSH2_CHANNEL *channel)
unsigned char packet[5]; /* packet_type(1) + channelno(4) */
int rc;
_libssh2_debug(session, LIBSSH2_TRACE_CONN,
"Sending EOF on channel %lu/%lu",
channel->local.id, channel->remote.id);
_libssh2_debug((session, LIBSSH2_TRACE_CONN,
"Sending EOF on channel %u/%u",
channel->local.id, channel->remote.id));
packet[0] = SSH_MSG_CHANNEL_EOF;
_libssh2_htonu32(packet + 1, channel->remote.id);
rc = _libssh2_transport_send(session, packet, 5, NULL, 0);
@ -2463,8 +2559,8 @@ libssh2_channel_eof(LIBSSH2_CHANNEL * channel)
if(packet->data_len < 1) {
packet = next_packet;
_libssh2_debug(channel->session, LIBSSH2_TRACE_ERROR,
"Unexpected packet length");
_libssh2_debug((channel->session, LIBSSH2_TRACE_ERROR,
"Unexpected packet length"));
continue;
}
@ -2492,9 +2588,9 @@ static int channel_wait_eof(LIBSSH2_CHANNEL *channel)
int rc;
if(channel->wait_eof_state == libssh2_NB_state_idle) {
_libssh2_debug(session, LIBSSH2_TRACE_CONN,
"Awaiting EOF for channel %lu/%lu", channel->local.id,
channel->remote.id);
_libssh2_debug((session, LIBSSH2_TRACE_CONN,
"Awaiting EOF for channel %u/%u", channel->local.id,
channel->remote.id));
channel->wait_eof_state = libssh2_NB_state_created;
}
@ -2521,7 +2617,7 @@ static int channel_wait_eof(LIBSSH2_CHANNEL *channel)
else if(rc < 0) {
channel->wait_eof_state = libssh2_NB_state_idle;
return _libssh2_error(session, rc,
"_libssh2_transport_read() bailed out!");
"_libssh2_transport_read() bailed out");
}
} while(1);
@ -2566,7 +2662,7 @@ int _libssh2_channel_close(LIBSSH2_CHANNEL * channel)
return rc;
}
_libssh2_error(session, rc,
"Unable to send EOF, but closing channel anyway");
"Unable to send EOF, but closing channel anyway");
}
}
@ -2574,8 +2670,8 @@ int _libssh2_channel_close(LIBSSH2_CHANNEL * channel)
late for us to wait for it. Continue closing! */
if(channel->close_state == libssh2_NB_state_idle) {
_libssh2_debug(session, LIBSSH2_TRACE_CONN, "Closing channel %lu/%lu",
channel->local.id, channel->remote.id);
_libssh2_debug((session, LIBSSH2_TRACE_CONN, "Closing channel %u/%u",
channel->local.id, channel->remote.id));
channel->close_packet[0] = SSH_MSG_CHANNEL_CLOSE;
_libssh2_htonu32(channel->close_packet + 1, channel->remote.id);
@ -2643,7 +2739,7 @@ libssh2_channel_close(LIBSSH2_CHANNEL *channel)
if(!channel)
return LIBSSH2_ERROR_BAD_USE;
BLOCK_ADJUST(rc, channel->session, _libssh2_channel_close(channel) );
BLOCK_ADJUST(rc, channel->session, _libssh2_channel_close(channel));
return rc;
}
@ -2664,9 +2760,9 @@ static int channel_wait_closed(LIBSSH2_CHANNEL *channel)
}
if(channel->wait_closed_state == libssh2_NB_state_idle) {
_libssh2_debug(session, LIBSSH2_TRACE_CONN,
"Awaiting close of channel %lu/%lu", channel->local.id,
channel->remote.id);
_libssh2_debug((session, LIBSSH2_TRACE_CONN,
"Awaiting close of channel %u/%u", channel->local.id,
channel->remote.id));
channel->wait_closed_state = libssh2_NB_state_created;
}
@ -2727,9 +2823,9 @@ int _libssh2_channel_free(LIBSSH2_CHANNEL *channel)
assert(session);
if(channel->free_state == libssh2_NB_state_idle) {
_libssh2_debug(session, LIBSSH2_TRACE_CONN,
"Freeing channel %lu/%lu resources", channel->local.id,
channel->remote.id);
_libssh2_debug((session, LIBSSH2_TRACE_CONN,
"Freeing channel %u/%u resources", channel->local.id,
channel->remote.id));
channel->free_state = libssh2_NB_state_created;
}
@ -2761,10 +2857,10 @@ int _libssh2_channel_free(LIBSSH2_CHANNEL *channel)
/* Clear out packets meant for this channel */
_libssh2_htonu32(channel_id, channel->local.id);
while((_libssh2_packet_ask(session, SSH_MSG_CHANNEL_DATA, &data,
&data_len, 1, channel_id, 4) >= 0)
||
(_libssh2_packet_ask(session, SSH_MSG_CHANNEL_EXTENDED_DATA, &data,
&data_len, 1, channel_id, 4) >= 0)) {
&data_len, 1, channel_id, 4) >= 0)
||
(_libssh2_packet_ask(session, SSH_MSG_CHANNEL_EXTENDED_DATA, &data,
&data_len, 1, channel_id, 4) >= 0)) {
LIBSSH2_FREE(session, data);
}
@ -2824,7 +2920,7 @@ libssh2_channel_free(LIBSSH2_CHANNEL *channel)
*/
LIBSSH2_API unsigned long
libssh2_channel_window_read_ex(LIBSSH2_CHANNEL *channel,
unsigned long *read_avail,
/* FIXME: -> size_t */ unsigned long *read_avail,
unsigned long *window_size_initial)
{
if(!channel)
@ -2846,8 +2942,8 @@ libssh2_channel_window_read_ex(LIBSSH2_CHANNEL *channel,
if(packet->data_len < 1) {
packet = next_packet;
_libssh2_debug(channel->session, LIBSSH2_TRACE_ERROR,
"Unexpected packet length");
_libssh2_debug((channel->session, LIBSSH2_TRACE_ERROR,
"Unexpected packet length"));
continue;
}
@ -2864,7 +2960,7 @@ libssh2_channel_window_read_ex(LIBSSH2_CHANNEL *channel,
packet = next_packet;
}
*read_avail = bytes_queued;
*read_avail = (unsigned long)bytes_queued;
}
return channel->remote.window_size;
@ -2893,3 +2989,87 @@ libssh2_channel_window_write_ex(LIBSSH2_CHANNEL *channel,
return channel->local.window_size;
}
/* A signal can be delivered to the remote process/service using the
following message. Some systems may not implement signals, in which
case they SHOULD ignore this message.
byte SSH_MSG_CHANNEL_REQUEST
uint32 recipient channel
string "signal"
boolean FALSE
string signal name (without the "SIG" prefix)
'signal name' values will be encoded as discussed in the passage
describing SSH_MSG_CHANNEL_REQUEST messages using "exit-signal" in
this section.
*/
static int channel_signal(LIBSSH2_CHANNEL *channel,
const char *signame,
size_t signame_len)
{
LIBSSH2_SESSION *session = channel->session;
int retcode = LIBSSH2_ERROR_PROTO;
if(channel->sendsignal_state == libssh2_NB_state_idle) {
unsigned char *s;
/* 20 = packet_type(1) + channel(4) +
signal_len + sizeof(signal) - 1 + want_reply(1) +
signame_len_len(4) */
channel->sendsignal_packet_len = 20 + signame_len;
s = channel->sendsignal_packet =
LIBSSH2_ALLOC(session, channel->sendsignal_packet_len);
if(!channel->sendsignal_packet)
return _libssh2_error(session, LIBSSH2_ERROR_ALLOC,
"Unable to allocate memory for "
"signal request");
*(s++) = SSH_MSG_CHANNEL_REQUEST;
_libssh2_store_u32(&s, channel->remote.id);
_libssh2_store_str(&s, "signal", sizeof("signal") - 1);
*(s++) = 0x00; /* Don't reply */
_libssh2_store_str(&s, signame, signame_len);
channel->sendsignal_state = libssh2_NB_state_created;
}
if(channel->sendsignal_state == libssh2_NB_state_created) {
int rc;
rc = _libssh2_transport_send(session, channel->sendsignal_packet,
channel->sendsignal_packet_len,
NULL, 0);
if(rc == LIBSSH2_ERROR_EAGAIN) {
_libssh2_error(session, rc, "Would block sending signal request");
return rc;
}
else if(rc) {
LIBSSH2_FREE(session, channel->sendsignal_packet);
channel->sendsignal_state = libssh2_NB_state_idle;
return _libssh2_error(session, rc, "Unable to send signal packet");
}
LIBSSH2_FREE(session, channel->sendsignal_packet);
retcode = LIBSSH2_ERROR_NONE;
}
channel->sendsignal_state = libssh2_NB_state_idle;
return retcode;
}
LIBSSH2_API int
libssh2_channel_signal_ex(LIBSSH2_CHANNEL *channel,
const char *signame,
size_t signame_len)
{
int rc;
if(!channel)
return LIBSSH2_ERROR_BAD_USE;
BLOCK_ADJUST(rc, channel->session,
channel_signal(channel, signame, signame_len));
return rc;
}

View file

@ -1,6 +1,6 @@
#ifndef __LIBSSH2_CHANNEL_H
#define __LIBSSH2_CHANNEL_H
/* Copyright (c) 2008-2010 by Daniel Stenberg
#ifndef LIBSSH2_CHANNEL_H
#define LIBSSH2_CHANNEL_H
/* Copyright (C) Daniel Stenberg
*
* All rights reserved.
*
@ -36,6 +36,8 @@
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
* USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
* OF SUCH DAMAGE.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
/*
@ -137,5 +139,4 @@ int _libssh2_channel_close(LIBSSH2_CHANNEL * channel);
*/
int _libssh2_channel_forward_cancel(LIBSSH2_LISTENER *listener);
#endif /* __LIBSSH2_CHANNEL_H */
#endif /* LIBSSH2_CHANNEL_H */

View file

@ -0,0 +1,134 @@
/*
* Copyright (c) 2013 Damien Miller <djm@mindrot.org>
*
* Adapted by Will Cosgrove <will@panic.com> for libssh2
*
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*
* SPDX-License-Identifier: BSD-2-Clause
*/
/* $OpenBSD: cipher-chachapoly.c,v 1.8 2016/08/03 05:41:57 djm Exp $ */
#include "libssh2_priv.h"
#include "misc.h"
#include "cipher-chachapoly.h"
int
chachapoly_timingsafe_bcmp(const void *b1, const void *b2, size_t n);
int
chachapoly_init(struct chachapoly_ctx *ctx, const u_char *key, u_int keylen)
{
if(keylen != (32 + 32)) /* 2 x 256 bit keys */
return LIBSSH2_ERROR_INVAL;
chacha_keysetup(&ctx->main_ctx, key, 256);
chacha_keysetup(&ctx->header_ctx, key + 32, 256);
return 0;
}
/*
* chachapoly_crypt() operates as following:
* En/decrypt with header key 'aadlen' bytes from 'src', storing result
* to 'dest'. The ciphertext here is treated as additional authenticated
* data for MAC calculation.
* En/decrypt 'len' bytes at offset 'aadlen' from 'src' to 'dest'. Use
* POLY1305_TAGLEN bytes at offset 'len'+'aadlen' as the authentication
* tag. This tag is written on encryption and verified on decryption.
*/
int
chachapoly_crypt(struct chachapoly_ctx *ctx, u_int seqnr, u_char *dest,
const u_char *src, u_int len, u_int aadlen, int do_encrypt)
{
u_char seqbuf[8];
const u_char one[8] = { 1, 0, 0, 0, 0, 0, 0, 0 }; /* NB little-endian */
u_char expected_tag[POLY1305_TAGLEN], poly_key[POLY1305_KEYLEN];
int r = LIBSSH2_ERROR_INVAL;
unsigned char *ptr = NULL;
/*
* Run ChaCha20 once to generate the Poly1305 key. The IV is the
* packet sequence number.
*/
memset(poly_key, 0, sizeof(poly_key));
ptr = &seqbuf[0];
_libssh2_store_u64(&ptr, seqnr);
chacha_ivsetup(&ctx->main_ctx, seqbuf, NULL);
chacha_encrypt_bytes(&ctx->main_ctx,
poly_key, poly_key, sizeof(poly_key));
/* If decrypting, check tag before anything else */
if(!do_encrypt) {
const u_char *tag = src + aadlen + len;
poly1305_auth(expected_tag, src, aadlen + len, poly_key);
if(chachapoly_timingsafe_bcmp(expected_tag, tag, POLY1305_TAGLEN)
!= 0) {
r = LIBSSH2_ERROR_DECRYPT;
goto out;
}
}
/* Crypt additional data */
if(aadlen) {
chacha_ivsetup(&ctx->header_ctx, seqbuf, NULL);
chacha_encrypt_bytes(&ctx->header_ctx, src, dest, aadlen);
}
/* Set Chacha's block counter to 1 */
chacha_ivsetup(&ctx->main_ctx, seqbuf, one);
chacha_encrypt_bytes(&ctx->main_ctx, src + aadlen,
dest + aadlen, len);
/* If encrypting, calculate and append tag */
if(do_encrypt) {
poly1305_auth(dest + aadlen + len, dest, aadlen + len,
poly_key);
}
r = 0;
out:
memset(expected_tag, 0, sizeof(expected_tag));
memset(seqbuf, 0, sizeof(seqbuf));
memset(poly_key, 0, sizeof(poly_key));
return r;
}
/* Decrypt and extract the encrypted packet length */
int
chachapoly_get_length(struct chachapoly_ctx *ctx, unsigned int *plenp,
unsigned int seqnr, const unsigned char *cp,
unsigned int len)
{
u_char buf[4], seqbuf[8];
unsigned char *ptr = NULL;
if(len < 4)
return -1;
ptr = &seqbuf[0];
_libssh2_store_u64(&ptr, seqnr);
chacha_ivsetup(&ctx->header_ctx, seqbuf, NULL);
chacha_encrypt_bytes(&ctx->header_ctx, cp, buf, 4);
*plenp = _libssh2_ntohu32(buf);
return 0;
}
int
chachapoly_timingsafe_bcmp(const void *b1, const void *b2, size_t n)
{
const unsigned char *p1 = b1, *p2 = b2;
int ret = 0;
for(; n > 0; n--)
ret |= *p1++ ^ *p2++;
return (ret != 0);
}

View file

@ -0,0 +1,41 @@
/* $OpenBSD: cipher-chachapoly.h,v 1.4 2014/06/24 01:13:21 djm Exp $ */
/*
* Copyright (c) Damien Miller 2013 <djm@mindrot.org>
*
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*
* SPDX-License-Identifier: BSD-2-Clause
*/
#ifndef CHACHA_POLY_AEAD_H
#define CHACHA_POLY_AEAD_H
#include "chacha.h"
#include "poly1305.h"
#define CHACHA_KEYLEN 32 /* Only 256 bit keys used here */
struct chachapoly_ctx {
struct chacha_ctx main_ctx, header_ctx;
};
int chachapoly_init(struct chachapoly_ctx *cpctx,
const u_char *key, u_int keylen);
int chachapoly_crypt(struct chachapoly_ctx *cpctx, u_int seqnr,
u_char *dest, const u_char *src, u_int len, u_int aadlen,
int do_encrypt);
int chachapoly_get_length(struct chachapoly_ctx *cpctx,
u_int *plenp, u_int seqnr, const u_char *cp,
u_int len);
#endif /* CHACHA_POLY_AEAD_H */

View file

@ -1,5 +1,5 @@
/* Copyright (c) 2004-2007, 2019, Sara Golemon <sarag@libssh2.org>
* Copyright (c) 2010-2014, Daniel Stenberg <daniel@haxx.se>
/* Copyright (C) Sara Golemon <sarag@libssh2.org>
* Copyright (C) Daniel Stenberg <daniel@haxx.se>
* All rights reserved.
*
* Redistribution and use in source and binary forms,
@ -34,13 +34,15 @@
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
* USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
* OF SUCH DAMAGE.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#include "libssh2_priv.h"
#ifdef LIBSSH2_HAVE_ZLIB
#include UPP_ZLIB_INCLUDE /* Upp-SSH: Patched, 11/17/2020 */
#undef compress /* dodge name clash with ZLIB macro */
#include UPP_ZLIB_INCLUDE
#undef compress /* dodge name clash with ZLIB macro */
#endif
#include "comp.h"
@ -62,12 +64,12 @@ comp_method_none_comp(LIBSSH2_SESSION *session,
size_t src_len,
void **abstract)
{
(void) session;
(void) abstract;
(void) dest;
(void) dest_len;
(void) src;
(void) src_len;
(void)session;
(void)abstract;
(void)dest;
(void)dest_len;
(void)src;
(void)src_len;
return 0;
}
@ -85,9 +87,9 @@ comp_method_none_decomp(LIBSSH2_SESSION * session,
const unsigned char *src,
size_t src_len, void **abstract)
{
(void) session;
(void) payload_limit;
(void) abstract;
(void)session;
(void)payload_limit;
(void)abstract;
*dest = (unsigned char *) src;
*dest_len = src_len;
return 0;
@ -164,8 +166,8 @@ comp_method_zlib_init(LIBSSH2_SESSION * session, int compr,
if(status != Z_OK) {
LIBSSH2_FREE(session, strm);
_libssh2_debug(session, LIBSSH2_TRACE_TRANS,
"unhandled zlib error %d", status);
_libssh2_debug((session, LIBSSH2_TRACE_TRANS,
"unhandled zlib error %d", status));
return LIBSSH2_ERROR_COMPRESS;
}
*abstract = strm;
@ -190,11 +192,11 @@ comp_method_zlib_comp(LIBSSH2_SESSION *session,
void **abstract)
{
z_stream *strm = *abstract;
int out_maxlen = *dest_len;
uInt out_maxlen = (uInt)*dest_len;
int status;
strm->next_in = (unsigned char *) src;
strm->avail_in = src_len;
strm->avail_in = (uInt)src_len;
strm->next_out = dest;
strm->avail_out = out_maxlen;
@ -205,9 +207,9 @@ comp_method_zlib_comp(LIBSSH2_SESSION *session,
return 0;
}
_libssh2_debug(session, LIBSSH2_TRACE_TRANS,
"unhandled zlib compression error %d, avail_out",
status, strm->avail_out);
_libssh2_debug((session, LIBSSH2_TRACE_TRANS,
"unhandled zlib compression error %d, avail_out %u",
status, strm->avail_out));
return _libssh2_error(session, LIBSSH2_ERROR_ZLIB, "compression failure");
}
@ -228,17 +230,17 @@ comp_method_zlib_decomp(LIBSSH2_SESSION * session,
/* A short-term alloc of a full data chunk is better than a series of
reallocs */
char *out;
size_t out_maxlen = src_len;
size_t out_maxlen;
if(src_len <= SIZE_MAX / 4)
out_maxlen = src_len * 4;
out_maxlen = (uInt)src_len * 4;
else
out_maxlen = payload_limit;
/* If strm is null, then we have not yet been initialized. */
if(strm == NULL)
if(!strm)
return _libssh2_error(session, LIBSSH2_ERROR_COMPRESS,
"decompression uninitialized");;
"decompression uninitialized");
/* In practice they never come smaller than this */
if(out_maxlen < 25)
@ -248,10 +250,11 @@ comp_method_zlib_decomp(LIBSSH2_SESSION * session,
out_maxlen = payload_limit;
strm->next_in = (unsigned char *) src;
strm->avail_in = src_len;
strm->next_out = (unsigned char *) LIBSSH2_ALLOC(session, out_maxlen);
strm->avail_in = (uInt)src_len;
strm->next_out = (unsigned char *) LIBSSH2_ALLOC(session,
(uInt)out_maxlen);
out = (char *) strm->next_out;
strm->avail_out = out_maxlen;
strm->avail_out = (uInt)out_maxlen;
if(!strm->next_out)
return _libssh2_error(session, LIBSSH2_ERROR_ALLOC,
"Unable to allocate decompression buffer");
@ -277,8 +280,8 @@ comp_method_zlib_decomp(LIBSSH2_SESSION * session,
else {
/* error state */
LIBSSH2_FREE(session, out);
_libssh2_debug(session, LIBSSH2_TRACE_TRANS,
"unhandled zlib error %d", status);
_libssh2_debug((session, LIBSSH2_TRACE_TRANS,
"unhandled zlib error %d", status));
return _libssh2_error(session, LIBSSH2_ERROR_ZLIB,
"decompression failure");
}
@ -300,7 +303,7 @@ comp_method_zlib_decomp(LIBSSH2_SESSION * session,
}
out = newout;
strm->next_out = (unsigned char *) out + out_ofs;
strm->avail_out = out_maxlen - out_ofs;
strm->avail_out = (uInt)(out_maxlen - out_ofs);
}
*dest = (unsigned char *) out;

View file

@ -1,6 +1,6 @@
#ifndef __LIBSSH2_COMP_H
#define __LIBSSH2_COMP_H
/* Copyright (C) 2009-2010 by Daniel Stenberg
#ifndef LIBSSH2_COMP_H
#define LIBSSH2_COMP_H
/* Copyright (C) Daniel Stenberg
*
* Redistribution and use in source and binary forms,
* with or without modification, are permitted provided
@ -35,10 +35,11 @@
* USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
* OF SUCH DAMAGE.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#include "libssh2_priv.h"
const LIBSSH2_COMP_METHOD **_libssh2_comp_methods(LIBSSH2_SESSION *session);
#endif /* __LIBSSH2_COMP_H */
#endif /* LIBSSH2_COMP_H */

View file

@ -1,5 +1,5 @@
/* Copyright (c) 2009, 2010 Simon Josefsson <simon@josefsson.org>
* Copyright (c) 2004-2007, Sara Golemon <sarag@libssh2.org>
/* Copyright (C) Simon Josefsson <simon@josefsson.org>
* Copyright (C) Sara Golemon <sarag@libssh2.org>
* All rights reserved.
*
* Redistribution and use in source and binary forms,
@ -34,18 +34,36 @@
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
* USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
* OF SUCH DAMAGE.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#include "libssh2_priv.h"
#include "cipher-chachapoly.h"
#ifdef LIBSSH2_CRYPT_NONE
#include <assert.h>
#if defined(LIBSSH2DEBUG) && defined(LIBSSH2_CRYPT_NONE_INSECURE)
/* crypt_none_crypt
* Minimalist cipher: VERY secure *wink*
* Minimalist cipher: no encryption. DO NOT USE.
*
* The SSH2 Transport allows for unencrypted data transmission using
* the "none" cipher. Because this is such a huge security hole, it is
* typically disabled on SSH2 implementations and is disabled in libssh2
* by default as well.
*
* Enabling this option will allow for "none" as a negotiable method,
* however it still requires that the method be advertised by the remote
* end and that no more-preferable methods are available.
*
*/
static int
crypt_none_crypt(LIBSSH2_SESSION * session, unsigned char *buf,
void **abstract)
crypt_none_crypt(LIBSSH2_SESSION * session,
unsigned int seqno,
unsigned char *buf,
size_t buf_len,
void **abstract,
int firstlast)
{
/* Do nothing to the data! */
return 0;
@ -62,13 +80,14 @@ static const LIBSSH2_CRYPT_METHOD libssh2_crypt_method_none = {
crypt_none_crypt,
NULL
};
#endif /* LIBSSH2_CRYPT_NONE */
#endif /* defined(LIBSSH2DEBUG) && defined(LIBSSH2_CRYPT_NONE_INSECURE) */
struct crypt_ctx
{
int encrypt;
_libssh2_cipher_type(algo);
_libssh2_cipher_ctx h;
struct chachapoly_ctx chachapoly_ctx;
};
static int
@ -96,13 +115,18 @@ crypt_init(LIBSSH2_SESSION * session,
}
static int
crypt_encrypt(LIBSSH2_SESSION * session, unsigned char *block,
size_t blocksize, void **abstract)
crypt_encrypt(LIBSSH2_SESSION * session,
unsigned int seqno,
unsigned char *buf,
size_t buf_len,
void **abstract,
int firstlast)
{
struct crypt_ctx *cctx = *(struct crypt_ctx **) abstract;
(void) session;
return _libssh2_cipher_crypt(&cctx->h, cctx->algo, cctx->encrypt, block,
blocksize);
(void) seqno;
return _libssh2_cipher_crypt(&cctx->h, cctx->algo, cctx->encrypt, buf,
buf_len, firstlast);
}
static int
@ -117,6 +141,38 @@ crypt_dtor(LIBSSH2_SESSION * session, void **abstract)
return 0;
}
#if LIBSSH2_AES_GCM
static const LIBSSH2_CRYPT_METHOD libssh2_crypt_method_aes256_gcm = {
"aes256-gcm@openssh.com",
"",
16, /* blocksize */
12, /* initial value length */
32, /* secret length -- 32*8 == 256bit */
16, /* length of the authentication tag */
LIBSSH2_CRYPT_FLAG_INTEGRATED_MAC | LIBSSH2_CRYPT_FLAG_PKTLEN_AAD,
&crypt_init,
NULL,
&crypt_encrypt,
&crypt_dtor,
_libssh2_cipher_aes256gcm
};
static const LIBSSH2_CRYPT_METHOD libssh2_crypt_method_aes128_gcm = {
"aes128-gcm@openssh.com",
"",
16, /* blocksize */
12, /* initial value length */
16, /* secret length -- 16*8 == 128bit */
16, /* length of the authentication tag */
LIBSSH2_CRYPT_FLAG_INTEGRATED_MAC | LIBSSH2_CRYPT_FLAG_PKTLEN_AAD,
&crypt_init,
NULL,
&crypt_encrypt,
&crypt_dtor,
_libssh2_cipher_aes128gcm
};
#endif
#if LIBSSH2_AES_CTR
static const LIBSSH2_CRYPT_METHOD libssh2_crypt_method_aes128_ctr = {
"aes128-ctr",
@ -124,8 +180,10 @@ static const LIBSSH2_CRYPT_METHOD libssh2_crypt_method_aes128_ctr = {
16, /* blocksize */
16, /* initial value length */
16, /* secret length -- 16*8 == 128bit */
0, /* length of the authentication tag */
0, /* flags */
&crypt_init,
NULL,
&crypt_encrypt,
&crypt_dtor,
_libssh2_cipher_aes128ctr
@ -137,8 +195,10 @@ static const LIBSSH2_CRYPT_METHOD libssh2_crypt_method_aes192_ctr = {
16, /* blocksize */
16, /* initial value length */
24, /* secret length -- 24*8 == 192bit */
0, /* length of the authentication tag */
0, /* flags */
&crypt_init,
NULL,
&crypt_encrypt,
&crypt_dtor,
_libssh2_cipher_aes192ctr
@ -150,23 +210,27 @@ static const LIBSSH2_CRYPT_METHOD libssh2_crypt_method_aes256_ctr = {
16, /* blocksize */
16, /* initial value length */
32, /* secret length -- 32*8 == 256bit */
0, /* length of the authentication tag */
0, /* flags */
&crypt_init,
NULL,
&crypt_encrypt,
&crypt_dtor,
_libssh2_cipher_aes256ctr
};
#endif
#if LIBSSH2_AES
#if LIBSSH2_AES_CBC
static const LIBSSH2_CRYPT_METHOD libssh2_crypt_method_aes128_cbc = {
"aes128-cbc",
"DEK-Info: AES-128-CBC",
16, /* blocksize */
16, /* initial value length */
16, /* secret length -- 16*8 == 128bit */
0, /* length of the authentication tag */
0, /* flags */
&crypt_init,
NULL,
&crypt_encrypt,
&crypt_dtor,
_libssh2_cipher_aes128
@ -178,8 +242,10 @@ static const LIBSSH2_CRYPT_METHOD libssh2_crypt_method_aes192_cbc = {
16, /* blocksize */
16, /* initial value length */
24, /* secret length -- 24*8 == 192bit */
0, /* length of the authentication tag */
0, /* flags */
&crypt_init,
NULL,
&crypt_encrypt,
&crypt_dtor,
_libssh2_cipher_aes192
@ -191,8 +257,10 @@ static const LIBSSH2_CRYPT_METHOD libssh2_crypt_method_aes256_cbc = {
16, /* blocksize */
16, /* initial value length */
32, /* secret length -- 32*8 == 256bit */
0, /* length of the authentication tag */
0, /* flags */
&crypt_init,
NULL,
&crypt_encrypt,
&crypt_dtor,
_libssh2_cipher_aes256
@ -206,13 +274,15 @@ static const LIBSSH2_CRYPT_METHOD
16, /* blocksize */
16, /* initial value length */
32, /* secret length -- 32*8 == 256bit */
0, /* length of the authentication tag */
0, /* flags */
&crypt_init,
NULL,
&crypt_encrypt,
&crypt_dtor,
_libssh2_cipher_aes256
};
#endif /* LIBSSH2_AES */
#endif /* LIBSSH2_AES_CBC */
#if LIBSSH2_BLOWFISH
static const LIBSSH2_CRYPT_METHOD libssh2_crypt_method_blowfish_cbc = {
@ -221,8 +291,10 @@ static const LIBSSH2_CRYPT_METHOD libssh2_crypt_method_blowfish_cbc = {
8, /* blocksize */
8, /* initial value length */
16, /* secret length */
0, /* length of the authentication tag */
0, /* flags */
&crypt_init,
NULL,
&crypt_encrypt,
&crypt_dtor,
_libssh2_cipher_blowfish
@ -236,8 +308,10 @@ static const LIBSSH2_CRYPT_METHOD libssh2_crypt_method_arcfour = {
8, /* blocksize */
8, /* initial value length */
16, /* secret length */
0, /* length of the authentication tag */
0, /* flags */
&crypt_init,
NULL,
&crypt_encrypt,
&crypt_dtor,
_libssh2_cipher_arcfour
@ -260,7 +334,8 @@ crypt_init_arcfour128(LIBSSH2_SESSION * session,
size_t discard = 1536;
for(; discard; discard -= 8)
_libssh2_cipher_crypt(&cctx->h, cctx->algo, cctx->encrypt, block,
method->blocksize);
method->blocksize, MIDDLE_BLOCK);
/* Not all middle, but here it doesn't matter */
}
return rc;
@ -272,8 +347,10 @@ static const LIBSSH2_CRYPT_METHOD libssh2_crypt_method_arcfour128 = {
8, /* blocksize */
8, /* initial value length */
16, /* secret length */
0, /* length of the authentication tag */
0, /* flags */
&crypt_init_arcfour128,
NULL,
&crypt_encrypt,
&crypt_dtor,
_libssh2_cipher_arcfour
@ -287,8 +364,10 @@ static const LIBSSH2_CRYPT_METHOD libssh2_crypt_method_cast128_cbc = {
8, /* blocksize */
8, /* initial value length */
16, /* secret length */
0, /* length of the authentication tag */
0, /* flags */
&crypt_init,
NULL,
&crypt_encrypt,
&crypt_dtor,
_libssh2_cipher_cast5
@ -302,26 +381,147 @@ static const LIBSSH2_CRYPT_METHOD libssh2_crypt_method_3des_cbc = {
8, /* blocksize */
8, /* initial value length */
24, /* secret length */
0, /* length of the authentication tag */
0, /* flags */
&crypt_init,
NULL,
&crypt_encrypt,
&crypt_dtor,
_libssh2_cipher_3des
};
#endif
static int
crypt_init_chacha20_poly(LIBSSH2_SESSION * session,
const LIBSSH2_CRYPT_METHOD * method,
unsigned char *iv, int *free_iv,
unsigned char *secret, int *free_secret,
int encrypt, void **abstract)
{
struct crypt_ctx *ctx = LIBSSH2_ALLOC(session,
sizeof(struct crypt_ctx));
(void)iv;
if(!ctx)
return LIBSSH2_ERROR_ALLOC;
ctx->encrypt = encrypt;
ctx->algo = method->algo;
if(chachapoly_init(&ctx->chachapoly_ctx, secret, method->secret_len)) {
LIBSSH2_FREE(session, ctx);
return -1;
}
*abstract = ctx;
*free_iv = 1;
*free_secret = 1;
return 0;
}
static int
crypt_encrypt_chacha20_poly_buffer(LIBSSH2_SESSION * session,
unsigned int seqno,
unsigned char *buf,
size_t buf_len,
void **abstract,
int firstlast)
{
int ret = 1;
struct crypt_ctx *ctx = *(struct crypt_ctx **) abstract;
(void)session;
(void)firstlast;
if(ctx) {
if(ctx->encrypt) {
/* requires out_buf to be large enough to hold encrypted output
plus auth tag (auth len)
buf is a full packet so we need to subtract packet length from
length
*/
ret = chachapoly_crypt(&ctx->chachapoly_ctx, seqno, buf, buf,
((u_int)buf_len) - 4, 4, ctx->encrypt);
}
else {
/* buf is full packet including size and auth tag but buf_len
doesn't include size */
ret = chachapoly_crypt(&ctx->chachapoly_ctx, seqno, buf, buf,
((u_int)buf_len), 4, ctx->encrypt);
/* the api expects the size field to already be removed
from the decrypted packet so we'll help it out */
if(ret == 0) {
memmove(buf, buf + 4, buf_len - 4);
}
}
}
return (ret == 0 ? 0 : 1);
}
static int
crypt_get_length_chacha20_poly(LIBSSH2_SESSION * session, unsigned int seqno,
unsigned char *data, size_t data_size,
unsigned int *len, void **abstract)
{
struct crypt_ctx *ctx = *(struct crypt_ctx **) abstract;
(void)session;
return chachapoly_get_length(&ctx->chachapoly_ctx, len, seqno, data,
(u_int)data_size);
}
static int
crypt_dtor_chacha20_poly(LIBSSH2_SESSION * session, void **abstract)
{
struct crypt_ctx **cctx = (struct crypt_ctx **) abstract;
if(cctx && *cctx) {
LIBSSH2_FREE(session, *cctx);
*abstract = NULL;
}
return 0;
}
static const LIBSSH2_CRYPT_METHOD
libssh2_crypt_method_chacha20_poly1305_openssh = {
"chacha20-poly1305@openssh.com",
"",
8, /* blocksize */
0, /* initial value length */
64, /* secret length */
16, /* length of the auth_tag */
LIBSSH2_CRYPT_FLAG_REQUIRES_FULL_PACKET, /* flags */
&crypt_init_chacha20_poly,
&crypt_get_length_chacha20_poly,
&crypt_encrypt_chacha20_poly_buffer,
&crypt_dtor_chacha20_poly,
_libssh2_cipher_chacha20 /* not actually used */
};
/* These are the crypt methods that are available to be negotiated. Methods
towards the start are chosen in preference to ones further down the list. */
static const LIBSSH2_CRYPT_METHOD *_libssh2_crypt_methods[] = {
&libssh2_crypt_method_chacha20_poly1305_openssh,
#if LIBSSH2_AES_GCM
&libssh2_crypt_method_aes256_gcm,
&libssh2_crypt_method_aes128_gcm,
#endif /* LIBSSH2_AES_GCM */
#if LIBSSH2_AES_CTR
&libssh2_crypt_method_aes128_ctr,
&libssh2_crypt_method_aes192_ctr,
&libssh2_crypt_method_aes256_ctr,
#endif /* LIBSSH2_AES */
#if LIBSSH2_AES
&libssh2_crypt_method_aes256_ctr,
&libssh2_crypt_method_aes192_ctr,
&libssh2_crypt_method_aes128_ctr,
#endif /* LIBSSH2_AES_CTR */
#if LIBSSH2_AES_CBC
&libssh2_crypt_method_aes256_cbc,
&libssh2_crypt_method_rijndael_cbc_lysator_liu_se, /* == aes256-cbc */
&libssh2_crypt_method_aes192_cbc,
&libssh2_crypt_method_aes128_cbc,
#endif /* LIBSSH2_AES */
#endif /* LIBSSH2_AES_CBC */
#if LIBSSH2_BLOWFISH
&libssh2_crypt_method_blowfish_cbc,
#endif /* LIBSSH2_BLOWFISH */
@ -335,7 +535,7 @@ static const LIBSSH2_CRYPT_METHOD *_libssh2_crypt_methods[] = {
#if LIBSSH2_3DES
&libssh2_crypt_method_3des_cbc,
#endif /* LIBSSH2_DES */
#ifdef LIBSSH2_CRYPT_NONE
#if defined(LIBSSH2DEBUG) && defined(LIBSSH2_CRYPT_NONE_INSECURE)
&libssh2_crypt_method_none,
#endif
NULL

View file

@ -0,0 +1,19 @@
/* Copyright (C) Viktor Szakats
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#define LIBSSH2_CRYPTO_C
#include "libssh2_priv.h"
#if defined(LIBSSH2_OPENSSL) || defined(LIBSSH2_WOLFSSL)
#include "openssl.c"
#elif defined(LIBSSH2_LIBGCRYPT)
#include "libgcrypt.c"
#elif defined(LIBSSH2_MBEDTLS)
#include "mbedtls.c"
#elif defined(LIBSSH2_OS400QC3)
#include "os400qc3.c"
#elif defined(LIBSSH2_WINCNG)
#include "wincng.c"
#endif

View file

@ -1,8 +1,9 @@
#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
#ifndef LIBSSH2_CRYPTO_H
#define LIBSSH2_CRYPTO_H
/* Copyright (C) Simon Josefsson
* Copyright (C) The Written Word, Inc.
* Copyright (C) Daniel Stenberg
* All rights reserved.
*
* Redistribution and use in source and binary forms,
* with or without modification, are permitted provided
@ -36,28 +37,45 @@
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
* USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
* OF SUCH DAMAGE.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#ifdef LIBSSH2_OPENSSL
#define LIBSSH2_OPENSSL
#if defined(LIBSSH2_OPENSSL) || defined(LIBSSH2_WOLFSSL)
#include "openssl.h"
#endif
#ifdef LIBSSH2_LIBGCRYPT
#elif defined(LIBSSH2_LIBGCRYPT)
#include "libgcrypt.h"
#endif
#ifdef LIBSSH2_WINCNG
#include "wincng.h"
#endif
#ifdef LIBSSH2_OS400QC3
#include "os400qc3.h"
#endif
#ifdef LIBSSH2_MBEDTLS
#elif defined(LIBSSH2_MBEDTLS)
#include "mbedtls.h"
#elif defined(LIBSSH2_OS400QC3)
#include "os400qc3.h"
#elif defined(LIBSSH2_WINCNG)
#include "wincng.h"
#else
#error "no cryptography backend selected"
#endif
/* return: success = 1, error = 0 */
int _libssh2_hmac_ctx_init(libssh2_hmac_ctx *ctx);
#if LIBSSH2_MD5
int _libssh2_hmac_md5_init(libssh2_hmac_ctx *ctx,
void *key, size_t keylen);
#endif
#if LIBSSH2_HMAC_RIPEMD
int _libssh2_hmac_ripemd160_init(libssh2_hmac_ctx *ctx,
void *key, size_t keylen);
#endif
int _libssh2_hmac_sha1_init(libssh2_hmac_ctx *ctx,
void *key, size_t keylen);
int _libssh2_hmac_sha256_init(libssh2_hmac_ctx *ctx,
void *key, size_t keylen);
int _libssh2_hmac_sha512_init(libssh2_hmac_ctx *ctx,
void *key, size_t keylen);
int _libssh2_hmac_update(libssh2_hmac_ctx *ctx,
const void *data, size_t datalen);
int _libssh2_hmac_final(libssh2_hmac_ctx *ctx, void *data);
void _libssh2_hmac_cleanup(libssh2_hmac_ctx *ctx);
#define LIBSSH2_ED25519_KEY_LEN 32
#define LIBSSH2_ED25519_PRIVATE_KEY_LEN 64
#define LIBSSH2_ED25519_SIG_LEN 64
@ -83,16 +101,31 @@ int _libssh2_rsa_new_private(libssh2_rsa_ctx ** rsa,
LIBSSH2_SESSION * session,
const char *filename,
unsigned const char *passphrase);
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);
#if LIBSSH2_RSA_SHA1
int _libssh2_rsa_sha1_sign(LIBSSH2_SESSION * session,
libssh2_rsa_ctx * rsactx,
const unsigned char *hash,
size_t hash_len,
unsigned char **signature,
size_t *signature_len);
int _libssh2_rsa_sha1_verify(libssh2_rsa_ctx * rsa,
const unsigned char *sig,
size_t sig_len,
const unsigned char *m, size_t m_len);
#endif
#if LIBSSH2_RSA_SHA2
int _libssh2_rsa_sha2_sign(LIBSSH2_SESSION * session,
libssh2_rsa_ctx * rsactx,
const unsigned char *hash,
size_t hash_len,
unsigned char **signature,
size_t *signature_len);
int _libssh2_rsa_sha2_verify(libssh2_rsa_ctx * rsa,
size_t hash_len,
const unsigned char *sig,
size_t sig_len,
const unsigned char *m, size_t m_len);
#endif
int _libssh2_rsa_new_private_frommemory(libssh2_rsa_ctx ** rsa,
LIBSSH2_SESSION * session,
const char *filedata,
@ -117,10 +150,10 @@ int _libssh2_dsa_new_private(libssh2_dsa_ctx ** dsa,
unsigned const char *passphrase);
int _libssh2_dsa_sha1_verify(libssh2_dsa_ctx * dsactx,
const unsigned char *sig,
const unsigned char *m, unsigned long m_len);
const unsigned char *m, size_t m_len);
int _libssh2_dsa_sha1_sign(libssh2_dsa_ctx * dsactx,
const unsigned char *hash,
unsigned long hash_len, unsigned char *sig);
size_t hash_len, unsigned char *sig);
int _libssh2_dsa_new_private_frommemory(libssh2_dsa_ctx ** dsa,
LIBSSH2_SESSION * session,
const char *filedata,
@ -134,12 +167,23 @@ _libssh2_ecdsa_curve_name_with_octal_new(libssh2_ecdsa_ctx ** ecdsactx,
const unsigned char *k,
size_t k_len,
libssh2_curve_type type);
int
_libssh2_ecdsa_new_private(libssh2_ecdsa_ctx ** ec_ctx,
LIBSSH2_SESSION * session,
const char *filename,
unsigned const char *passphrase);
int
_libssh2_ecdsa_new_private_sk(libssh2_ecdsa_ctx ** ec_ctx,
unsigned char *flags,
const char **application,
const unsigned char **key_handle,
size_t *handle_len,
LIBSSH2_SESSION * session,
const char *filename,
unsigned const char *passphrase);
int
_libssh2_ecdsa_verify(libssh2_ecdsa_ctx * ctx,
const unsigned char *r, size_t r_len,
@ -160,7 +204,7 @@ _libssh2_ecdh_gen_k(_libssh2_bn **k, _libssh2_ec_key *private_key,
int
_libssh2_ecdsa_sign(LIBSSH2_SESSION *session, libssh2_ecdsa_ctx *ec_ctx,
const unsigned char *hash, unsigned long hash_len,
const unsigned char *hash, size_t hash_len,
unsigned char **signature, size_t *signature_len);
int _libssh2_ecdsa_new_private_frommemory(libssh2_ecdsa_ctx ** ec_ctx,
@ -169,6 +213,16 @@ int _libssh2_ecdsa_new_private_frommemory(libssh2_ecdsa_ctx ** ec_ctx,
size_t filedata_len,
unsigned const char *passphrase);
int _libssh2_ecdsa_new_private_frommemory_sk(libssh2_ecdsa_ctx ** ec_ctx,
unsigned char *flags,
const char **application,
const unsigned char **key_handle,
size_t *handle_len,
LIBSSH2_SESSION * session,
const char *filedata,
size_t filedata_len,
unsigned const char *passphrase);
libssh2_curve_type
_libssh2_ecdsa_get_curve_type(libssh2_ecdsa_ctx *ec_ctx);
@ -198,11 +252,21 @@ _libssh2_ed25519_new_private(libssh2_ed25519_ctx **ed_ctx,
LIBSSH2_SESSION *session,
const char *filename, const uint8_t *passphrase);
int
_libssh2_ed25519_new_private_sk(libssh2_ed25519_ctx **ed_ctx,
unsigned char *flags,
const char **application,
const unsigned char **key_handle,
size_t *handle_len,
LIBSSH2_SESSION *session,
const char *filename,
const uint8_t *passphrase);
int
_libssh2_ed25519_new_public(libssh2_ed25519_ctx **ed_ctx,
LIBSSH2_SESSION *session,
const unsigned char *raw_pub_key,
const uint8_t key_len);
const size_t key_len);
int
_libssh2_ed25519_sign(libssh2_ed25519_ctx *ctx, LIBSSH2_SESSION *session,
@ -216,6 +280,17 @@ _libssh2_ed25519_new_private_frommemory(libssh2_ed25519_ctx **ed_ctx,
size_t filedata_len,
unsigned const char *passphrase);
int
_libssh2_ed25519_new_private_frommemory_sk(libssh2_ed25519_ctx **ed_ctx,
unsigned char *flags,
const char **application,
const unsigned char **key_handle,
size_t *handle_len,
LIBSSH2_SESSION *session,
const char *filedata,
size_t filedata_len,
unsigned const char *passphrase);
#endif /* LIBSSH2_ED25519 */
@ -226,7 +301,8 @@ int _libssh2_cipher_init(_libssh2_cipher_ctx * h,
int _libssh2_cipher_crypt(_libssh2_cipher_ctx * ctx,
_libssh2_cipher_type(algo),
int encrypt, unsigned char *block, size_t blocksize);
int encrypt, unsigned char *block, size_t blocksize,
int firstlast);
int _libssh2_pub_priv_keyfile(LIBSSH2_SESSION *session,
unsigned char **method,
@ -245,4 +321,37 @@ int _libssh2_pub_priv_keyfilememory(LIBSSH2_SESSION *session,
size_t privatekeydata_len,
const char *passphrase);
#endif /* __LIBSSH2_CRYPTO_H */
int _libssh2_sk_pub_keyfilememory(LIBSSH2_SESSION *session,
unsigned char **method,
size_t *method_len,
unsigned char **pubkeydata,
size_t *pubkeydata_len,
int *algorithm,
unsigned char *flags,
const char **application,
const unsigned char **key_handle,
size_t *handle_len,
const char *privatekeydata,
size_t privatekeydata_len,
const char *passphrase);
/**
* @function _libssh2_supported_key_sign_algorithms
* @abstract Returns supported algorithms used for upgrading public
* key signing RFC 8332
* @discussion Based on the incoming key_method value, this function
* will return supported algorithms that can upgrade the key method
* @related _libssh2_key_sign_algorithm()
* @param key_method current key method, usually the default key sig method
* @param key_method_len length of the key method buffer
* @result comma separated list of supported upgrade options per RFC 8332, if
* there is no upgrade option return NULL
*/
const char *
_libssh2_supported_key_sign_algorithms(LIBSSH2_SESSION *session,
unsigned char *key_method,
size_t key_method_len);
#endif /* LIBSSH2_CRYPTO_H */

View file

@ -0,0 +1,76 @@
/* Copyright (C) Viktor Szakats
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#define LIBSSH2_MD5_PEM LIBSSH2_MD5
#ifdef LIBSSH2_NO_MD5
#undef LIBSSH2_MD5
#define LIBSSH2_MD5 0
#endif
#ifdef LIBSSH2_NO_MD5_PEM
#undef LIBSSH2_MD5_PEM
#define LIBSSH2_MD5_PEM 0
#endif
#ifdef LIBSSH2_NO_HMAC_RIPEMD
#undef LIBSSH2_HMAC_RIPEMD
#define LIBSSH2_HMAC_RIPEMD 0
#endif
#if !defined(LIBSSH2_DSA_ENABLE)
#undef LIBSSH2_DSA
#define LIBSSH2_DSA 0
#endif
#ifdef LIBSSH2_NO_RSA
#undef LIBSSH2_RSA
#define LIBSSH2_RSA 0
#endif
#ifdef LIBSSH2_NO_RSA_SHA1
#undef LIBSSH2_RSA_SHA1
#define LIBSSH2_RSA_SHA1 0
#endif
#ifdef LIBSSH2_NO_ECDSA
#undef LIBSSH2_ECDSA
#define LIBSSH2_ECDSA 0
#endif
#ifdef LIBSSH2_NO_ED25519
#undef LIBSSH2_ED25519
#define LIBSSH2_ED25519 0
#endif
#ifdef LIBSSH2_NO_AES_CTR
#undef LIBSSH2_AES_CTR
#define LIBSSH2_AES_CTR 0
#endif
#ifdef LIBSSH2_NO_AES_CBC
#undef LIBSSH2_AES_CBC
#define LIBSSH2_AES_CBC 0
#endif
#ifdef LIBSSH2_NO_BLOWFISH
#undef LIBSSH2_BLOWFISH
#define LIBSSH2_BLOWFISH 0
#endif
#ifdef LIBSSH2_NO_RC4
#undef LIBSSH2_RC4
#define LIBSSH2_RC4 0
#endif
#ifdef LIBSSH2_NO_CAST
#undef LIBSSH2_CAST
#define LIBSSH2_CAST 0
#endif
#ifdef LIBSSH2_NO_3DES
#undef LIBSSH2_3DES
#define LIBSSH2_3DES 0
#endif

View file

@ -1,5 +1,5 @@
/* Copyright (c) 2010 Lars Nordin <Lars.Nordin@SDlabs.se>
* Copyright (C) 2010 Simon Josefsson <simon@josefsson.org>
/* Copyright (C) Lars Nordin <Lars.Nordin@SDlabs.se>
* Copyright (C) Simon Josefsson <simon@josefsson.org>
* All rights reserved.
*
* Redistribution and use in source and binary forms,
@ -34,6 +34,8 @@
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
* USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
* OF SUCH DAMAGE.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#include "libssh2_priv.h"
@ -74,5 +76,5 @@ void
_libssh2_init_if_needed(void)
{
if(_libssh2_initialized == 0)
(void)libssh2_init (0);
(void)libssh2_init(0);
}

View file

@ -1,5 +1,5 @@
/* Copyright (c) 2004-2006, Sara Golemon <sarag@libssh2.org>
* Copyright (c) 2009-2019 by Daniel Stenberg
/* Copyright (C) Sara Golemon <sarag@libssh2.org>
* Copyright (C) Daniel Stenberg
* All rights reserved.
*
* Redistribution and use in source and binary forms,
@ -34,10 +34,11 @@
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
* USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
* OF SUCH DAMAGE.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#include "libssh2_priv.h"
#include "misc.h"
/* Needed for struct iovec on some platforms */
#ifdef HAVE_SYS_UIO_H
@ -64,8 +65,8 @@ hostkey_method_ssh_rsa_init(LIBSSH2_SESSION * session,
void **abstract)
{
libssh2_rsa_ctx *rsactx;
unsigned char *e, *n;
size_t e_len, n_len;
unsigned char *e, *n, *type;
size_t e_len, n_len, type_len;
struct string_buf buf;
if(*abstract) {
@ -74,8 +75,8 @@ hostkey_method_ssh_rsa_init(LIBSSH2_SESSION * session,
}
if(hostkey_data_len < 19) {
_libssh2_debug(session, LIBSSH2_TRACE_ERROR,
"host key length too short");
_libssh2_debug((session, LIBSSH2_TRACE_ERROR,
"host key length too short"));
return -1;
}
@ -83,8 +84,31 @@ hostkey_method_ssh_rsa_init(LIBSSH2_SESSION * session,
buf.dataptr = buf.data;
buf.len = hostkey_data_len;
if(_libssh2_match_string(&buf, "ssh-rsa"))
if(_libssh2_get_string(&buf, &type, &type_len)) {
return -1;
}
/* we accept one of 3 header types */
#if LIBSSH2_RSA_SHA1
if(type_len == 7 && strncmp("ssh-rsa", (char *)type, 7) == 0) {
/* ssh-rsa */
}
else
#endif
#if LIBSSH2_RSA_SHA2
if(type_len == 12 && strncmp("rsa-sha2-256", (char *)type, 12) == 0) {
/* rsa-sha2-256 */
}
else if(type_len == 12 && strncmp("rsa-sha2-512", (char *)type, 12) == 0) {
/* rsa-sha2-512 */
}
else
#endif
{
_libssh2_debug((session, LIBSSH2_TRACE_ERROR,
"unexpected rsa type: %.*s", (int)type_len, type));
return -1;
}
if(_libssh2_get_string(&buf, &e, &e_len))
return -1;
@ -92,8 +116,14 @@ hostkey_method_ssh_rsa_init(LIBSSH2_SESSION * session,
if(_libssh2_get_string(&buf, &n, &n_len))
return -1;
if(_libssh2_rsa_new(&rsactx, e, e_len, n, n_len, NULL, 0,
NULL, 0, NULL, 0, NULL, 0, NULL, 0, NULL, 0)) {
if(!_libssh2_eob(&buf))
return -1;
if(_libssh2_rsa_new(&rsactx,
e, (unsigned long)e_len,
n, (unsigned long)n_len,
NULL, 0, NULL, 0, NULL, 0,
NULL, 0, NULL, 0, NULL, 0)) {
return -1;
}
@ -163,6 +193,7 @@ hostkey_method_ssh_rsa_initPEMFromMemory(LIBSSH2_SESSION * session,
return 0;
}
#if LIBSSH2_RSA_SHA1
/*
* hostkey_method_ssh_rsa_sign
*
@ -176,7 +207,7 @@ hostkey_method_ssh_rsa_sig_verify(LIBSSH2_SESSION * session,
size_t m_len, void **abstract)
{
libssh2_rsa_ctx *rsactx = (libssh2_rsa_ctx *) (*abstract);
(void) session;
(void)session;
/* Skip past keyname_len(4) + keyname(7){"ssh-rsa"} + signature_len(4) */
if(sig_len < 15)
@ -211,11 +242,18 @@ hostkey_method_ssh_rsa_signv(LIBSSH2_SESSION * session,
unsigned char hash[SHA_DIGEST_LENGTH];
libssh2_sha1_ctx ctx;
libssh2_sha1_init(&ctx);
for(i = 0; i < veccount; i++) {
libssh2_sha1_update(ctx, datavec[i].iov_base, datavec[i].iov_len);
if(!libssh2_sha1_init(&ctx)) {
return -1;
}
for(i = 0; i < veccount; i++) {
if(!libssh2_sha1_update(ctx,
datavec[i].iov_base, datavec[i].iov_len)) {
return -1;
}
}
if(!libssh2_sha1_final(ctx, hash)) {
return -1;
}
libssh2_sha1_final(ctx, hash);
ret = _libssh2_rsa_sha1_sign(session, rsactx, hash, SHA_DIGEST_LENGTH,
signature, signature_len);
@ -226,6 +264,161 @@ hostkey_method_ssh_rsa_signv(LIBSSH2_SESSION * session,
return 0;
#endif
}
#endif
/*
* hostkey_method_ssh_rsa_sha2_256_sig_verify
*
* Verify signature created by remote
*/
#if LIBSSH2_RSA_SHA2
static int
hostkey_method_ssh_rsa_sha2_256_sig_verify(LIBSSH2_SESSION * session,
const unsigned char *sig,
size_t sig_len,
const unsigned char *m,
size_t m_len, void **abstract)
{
libssh2_rsa_ctx *rsactx = (libssh2_rsa_ctx *) (*abstract);
(void)session;
/* Skip past keyname_len(4) + keyname(12){"rsa-sha2-256"} +
signature_len(4) */
if(sig_len < 20)
return -1;
sig += 20;
sig_len -= 20;
return _libssh2_rsa_sha2_verify(rsactx, SHA256_DIGEST_LENGTH, sig, sig_len,
m, m_len);
}
/*
* hostkey_method_ssh_rsa_sha2_256_signv
*
* Construct a signature from an array of vectors
*/
static int
hostkey_method_ssh_rsa_sha2_256_signv(LIBSSH2_SESSION * session,
unsigned char **signature,
size_t *signature_len,
int veccount,
const struct iovec datavec[],
void **abstract)
{
libssh2_rsa_ctx *rsactx = (libssh2_rsa_ctx *) (*abstract);
#ifdef _libssh2_rsa_sha2_256_signv
return _libssh2_rsa_sha2_256_signv(session, signature, signature_len,
veccount, datavec, rsactx);
#else
int ret;
int i;
unsigned char hash[SHA256_DIGEST_LENGTH];
libssh2_sha256_ctx ctx;
if(!libssh2_sha256_init(&ctx)) {
return -1;
}
for(i = 0; i < veccount; i++) {
if(!libssh2_sha256_update(ctx,
datavec[i].iov_base, datavec[i].iov_len)) {
return -1;
}
}
if(!libssh2_sha256_final(ctx, hash)) {
return -1;
}
ret = _libssh2_rsa_sha2_sign(session, rsactx, hash, SHA256_DIGEST_LENGTH,
signature, signature_len);
if(ret) {
return -1;
}
return 0;
#endif
}
/*
* hostkey_method_ssh_rsa_sha2_512_sig_verify
*
* Verify signature created by remote
*/
static int
hostkey_method_ssh_rsa_sha2_512_sig_verify(LIBSSH2_SESSION * session,
const unsigned char *sig,
size_t sig_len,
const unsigned char *m,
size_t m_len, void **abstract)
{
libssh2_rsa_ctx *rsactx = (libssh2_rsa_ctx *) (*abstract);
(void)session;
/* Skip past keyname_len(4) + keyname(12){"rsa-sha2-512"} +
signature_len(4) */
if(sig_len < 20)
return -1;
sig += 20;
sig_len -= 20;
return _libssh2_rsa_sha2_verify(rsactx, SHA512_DIGEST_LENGTH, sig,
sig_len, m, m_len);
}
/*
* hostkey_method_ssh_rsa_sha2_512_signv
*
* Construct a signature from an array of vectors
*/
static int
hostkey_method_ssh_rsa_sha2_512_signv(LIBSSH2_SESSION * session,
unsigned char **signature,
size_t *signature_len,
int veccount,
const struct iovec datavec[],
void **abstract)
{
libssh2_rsa_ctx *rsactx = (libssh2_rsa_ctx *) (*abstract);
#ifdef _libssh2_rsa_sha2_512_signv
return _libssh2_rsa_sha2_512_signv(session, signature, signature_len,
veccount, datavec, rsactx);
#else
int ret;
int i;
unsigned char hash[SHA512_DIGEST_LENGTH];
libssh2_sha512_ctx ctx;
if(!libssh2_sha512_init(&ctx)) {
return -1;
}
for(i = 0; i < veccount; i++) {
if(!libssh2_sha512_update(ctx,
datavec[i].iov_base, datavec[i].iov_len)) {
return -1;
}
}
if(!libssh2_sha512_final(ctx, hash)) {
return -1;
}
ret = _libssh2_rsa_sha2_sign(session, rsactx, hash, SHA512_DIGEST_LENGTH,
signature, signature_len);
if(ret) {
return -1;
}
return 0;
#endif
}
#endif /* LIBSSH2_RSA_SHA2 */
/*
* hostkey_method_ssh_rsa_dtor
@ -236,7 +429,7 @@ static int
hostkey_method_ssh_rsa_dtor(LIBSSH2_SESSION * session, void **abstract)
{
libssh2_rsa_ctx *rsactx = (libssh2_rsa_ctx *) (*abstract);
(void) session;
(void)session;
_libssh2_rsa_free(rsactx);
@ -245,13 +438,11 @@ hostkey_method_ssh_rsa_dtor(LIBSSH2_SESSION * session, void **abstract)
return 0;
}
#ifdef OPENSSL_NO_MD5
#define MD5_DIGEST_LENGTH 16
#endif
#if LIBSSH2_RSA_SHA1
static const LIBSSH2_HOSTKEY_METHOD hostkey_method_ssh_rsa = {
"ssh-rsa",
MD5_DIGEST_LENGTH,
SHA_DIGEST_LENGTH,
hostkey_method_ssh_rsa_init,
hostkey_method_ssh_rsa_initPEM,
hostkey_method_ssh_rsa_initPEMFromMemory,
@ -260,6 +451,81 @@ static const LIBSSH2_HOSTKEY_METHOD hostkey_method_ssh_rsa = {
NULL, /* encrypt */
hostkey_method_ssh_rsa_dtor,
};
#endif /* LIBSSH2_RSA_SHA1 */
#if LIBSSH2_RSA_SHA2
static const LIBSSH2_HOSTKEY_METHOD hostkey_method_ssh_rsa_sha2_256 = {
"rsa-sha2-256",
SHA256_DIGEST_LENGTH,
hostkey_method_ssh_rsa_init,
hostkey_method_ssh_rsa_initPEM,
hostkey_method_ssh_rsa_initPEMFromMemory,
hostkey_method_ssh_rsa_sha2_256_sig_verify,
hostkey_method_ssh_rsa_sha2_256_signv,
NULL, /* encrypt */
hostkey_method_ssh_rsa_dtor,
};
static const LIBSSH2_HOSTKEY_METHOD hostkey_method_ssh_rsa_sha2_512 = {
"rsa-sha2-512",
SHA512_DIGEST_LENGTH,
hostkey_method_ssh_rsa_init,
hostkey_method_ssh_rsa_initPEM,
hostkey_method_ssh_rsa_initPEMFromMemory,
hostkey_method_ssh_rsa_sha2_512_sig_verify,
hostkey_method_ssh_rsa_sha2_512_signv,
NULL, /* encrypt */
hostkey_method_ssh_rsa_dtor,
};
#endif /* LIBSSH2_RSA_SHA2 */
#if LIBSSH2_RSA_SHA1
static const LIBSSH2_HOSTKEY_METHOD hostkey_method_ssh_rsa_cert = {
"ssh-rsa-cert-v01@openssh.com",
SHA_DIGEST_LENGTH,
NULL,
hostkey_method_ssh_rsa_initPEM,
hostkey_method_ssh_rsa_initPEMFromMemory,
NULL,
hostkey_method_ssh_rsa_signv,
NULL, /* encrypt */
hostkey_method_ssh_rsa_dtor,
};
#endif /* LIBSSH2_RSA_SHA1 */
#if LIBSSH2_RSA_SHA2
static const LIBSSH2_HOSTKEY_METHOD hostkey_method_ssh_rsa_sha2_256_cert = {
"rsa-sha2-256-cert-v01@openssh.com",
SHA256_DIGEST_LENGTH,
NULL,
hostkey_method_ssh_rsa_initPEM,
hostkey_method_ssh_rsa_initPEMFromMemory,
NULL,
hostkey_method_ssh_rsa_sha2_256_signv,
NULL, /* encrypt */
hostkey_method_ssh_rsa_dtor,
};
static const LIBSSH2_HOSTKEY_METHOD hostkey_method_ssh_rsa_sha2_512_cert = {
"rsa-sha2-512-cert-v01@openssh.com",
SHA512_DIGEST_LENGTH,
NULL,
hostkey_method_ssh_rsa_initPEM,
hostkey_method_ssh_rsa_initPEMFromMemory,
NULL,
hostkey_method_ssh_rsa_sha2_512_signv,
NULL, /* encrypt */
hostkey_method_ssh_rsa_dtor,
};
#endif /* LIBSSH2_RSA_SHA2 */
#endif /* LIBSSH2_RSA */
#if LIBSSH2_DSA
@ -292,8 +558,8 @@ hostkey_method_ssh_dss_init(LIBSSH2_SESSION * session,
}
if(hostkey_data_len < 27) {
_libssh2_debug(session, LIBSSH2_TRACE_ERROR,
"host key length too short");
_libssh2_debug((session, LIBSSH2_TRACE_ERROR,
"host key length too short"));
return -1;
}
@ -305,7 +571,7 @@ hostkey_method_ssh_dss_init(LIBSSH2_SESSION * session,
return -1;
if(_libssh2_get_string(&buf, &p, &p_len))
return -1;
return -1;
if(_libssh2_get_string(&buf, &q, &q_len))
return -1;
@ -316,8 +582,15 @@ hostkey_method_ssh_dss_init(LIBSSH2_SESSION * session,
if(_libssh2_get_string(&buf, &y, &y_len))
return -1;
if(_libssh2_dsa_new(&dsactx, p, p_len, q, q_len,
g, g_len, y, y_len, NULL, 0)) {
if(!_libssh2_eob(&buf))
return -1;
if(_libssh2_dsa_new(&dsactx,
p, (unsigned long)p_len,
q, (unsigned long)q_len,
g, (unsigned long)g_len,
y, (unsigned long)y_len,
NULL, 0)) {
return -1;
}
@ -431,6 +704,12 @@ hostkey_method_ssh_dss_signv(LIBSSH2_SESSION * session,
libssh2_sha1_ctx ctx;
int i;
if(!libssh2_sha1_init(&ctx)) {
*signature = NULL;
*signature_len = 0;
return -1;
}
*signature = LIBSSH2_CALLOC(session, 2 * SHA_DIGEST_LENGTH);
if(!*signature) {
return -1;
@ -438,11 +717,15 @@ hostkey_method_ssh_dss_signv(LIBSSH2_SESSION * session,
*signature_len = 2 * SHA_DIGEST_LENGTH;
libssh2_sha1_init(&ctx);
for(i = 0; i < veccount; i++) {
libssh2_sha1_update(ctx, datavec[i].iov_base, datavec[i].iov_len);
if(!libssh2_sha1_update(ctx,
datavec[i].iov_base, datavec[i].iov_len)) {
return -1;
}
}
if(!libssh2_sha1_final(ctx, hash)) {
return -1;
}
libssh2_sha1_final(ctx, hash);
if(_libssh2_dsa_sha1_sign(dsactx, hash, SHA_DIGEST_LENGTH, *signature)) {
LIBSSH2_FREE(session, *signature);
@ -461,7 +744,7 @@ static int
hostkey_method_ssh_dss_dtor(LIBSSH2_SESSION * session, void **abstract)
{
libssh2_dsa_ctx *dsactx = (libssh2_dsa_ctx *) (*abstract);
(void) session;
(void)session;
_libssh2_dsa_free(dsactx);
@ -472,7 +755,7 @@ hostkey_method_ssh_dss_dtor(LIBSSH2_SESSION * session, void **abstract)
static const LIBSSH2_HOSTKEY_METHOD hostkey_method_ssh_dss = {
"ssh-dss",
MD5_DIGEST_LENGTH,
SHA_DIGEST_LENGTH,
hostkey_method_ssh_dss_init,
hostkey_method_ssh_dss_initPEM,
hostkey_method_ssh_dss_initPEMFromMemory,
@ -500,9 +783,9 @@ hostkey_method_ssh_ecdsa_dtor(LIBSSH2_SESSION * session,
*/
static int
hostkey_method_ssh_ecdsa_init(LIBSSH2_SESSION * session,
const unsigned char *hostkey_data,
size_t hostkey_data_len,
void **abstract)
const unsigned char *hostkey_data,
size_t hostkey_data_len,
void **abstract)
{
libssh2_ecdsa_ctx *ecdsactx = NULL;
unsigned char *type_str, *domain, *public_key;
@ -510,14 +793,14 @@ hostkey_method_ssh_ecdsa_init(LIBSSH2_SESSION * session,
libssh2_curve_type type;
struct string_buf buf;
if(abstract != NULL && *abstract) {
if(abstract && *abstract) {
hostkey_method_ssh_ecdsa_dtor(session, abstract);
*abstract = NULL;
}
if(hostkey_data_len < 39) {
_libssh2_debug(session, LIBSSH2_TRACE_ERROR,
"host key length too short");
_libssh2_debug((session, LIBSSH2_TRACE_ERROR,
"host key length too short"));
return -1;
}
@ -561,11 +844,14 @@ hostkey_method_ssh_ecdsa_init(LIBSSH2_SESSION * session,
if(_libssh2_get_string(&buf, &public_key, &key_len))
return -1;
if(!_libssh2_eob(&buf))
return -1;
if(_libssh2_ecdsa_curve_name_with_octal_new(&ecdsactx, public_key,
key_len, type))
return -1;
if(abstract != NULL)
if(abstract)
*abstract = ecdsactx;
return 0;
@ -578,14 +864,14 @@ hostkey_method_ssh_ecdsa_init(LIBSSH2_SESSION * session,
*/
static int
hostkey_method_ssh_ecdsa_initPEM(LIBSSH2_SESSION * session,
const char *privkeyfile,
unsigned const char *passphrase,
void **abstract)
const char *privkeyfile,
unsigned const char *passphrase,
void **abstract)
{
libssh2_ecdsa_ctx *ec_ctx = NULL;
int ret;
if(abstract != NULL && *abstract) {
if(abstract && *abstract) {
hostkey_method_ssh_ecdsa_dtor(session, abstract);
*abstract = NULL;
}
@ -593,7 +879,7 @@ hostkey_method_ssh_ecdsa_initPEM(LIBSSH2_SESSION * session,
ret = _libssh2_ecdsa_new_private(&ec_ctx, session,
privkeyfile, passphrase);
if(abstract != NULL)
if(abstract)
*abstract = ec_ctx;
return ret;
@ -606,15 +892,15 @@ hostkey_method_ssh_ecdsa_initPEM(LIBSSH2_SESSION * session,
*/
static int
hostkey_method_ssh_ecdsa_initPEMFromMemory(LIBSSH2_SESSION * session,
const char *privkeyfiledata,
size_t privkeyfiledata_len,
unsigned const char *passphrase,
void **abstract)
const char *privkeyfiledata,
size_t privkeyfiledata_len,
unsigned const char *passphrase,
void **abstract)
{
libssh2_ecdsa_ctx *ec_ctx = NULL;
int ret;
if(abstract != NULL && *abstract) {
if(abstract && *abstract) {
hostkey_method_ssh_ecdsa_dtor(session, abstract);
*abstract = NULL;
}
@ -627,7 +913,7 @@ hostkey_method_ssh_ecdsa_initPEMFromMemory(LIBSSH2_SESSION * session,
return -1;
}
if(abstract != NULL)
if(abstract)
*abstract = ec_ctx;
return 0;
@ -651,7 +937,7 @@ hostkey_method_ssh_ecdsa_sig_verify(LIBSSH2_SESSION * session,
struct string_buf buf;
libssh2_ecdsa_ctx *ctx = (libssh2_ecdsa_ctx *) (*abstract);
(void) session;
(void)session;
if(sig_len < 35)
return -1;
@ -662,14 +948,14 @@ hostkey_method_ssh_ecdsa_sig_verify(LIBSSH2_SESSION * session,
buf.dataptr = buf.data;
buf.len = sig_len;
if(_libssh2_get_string(&buf, &name, &name_len) || name_len != 19)
if(_libssh2_get_string(&buf, &name, &name_len) || name_len != 19)
return -1;
if(_libssh2_get_u32(&buf, &len) != 0 || len < 8)
return -1;
if(_libssh2_get_string(&buf, &r, &r_len))
return -1;
return -1;
if(_libssh2_get_string(&buf, &s, &s_len))
return -1;
@ -678,21 +964,34 @@ hostkey_method_ssh_ecdsa_sig_verify(LIBSSH2_SESSION * session,
}
#define LIBSSH2_HOSTKEY_METHOD_EC_SIGNV_HASH(digest_type) \
{ \
unsigned char hash[SHA##digest_type##_DIGEST_LENGTH]; \
libssh2_sha##digest_type##_ctx ctx; \
int i; \
libssh2_sha##digest_type##_init(&ctx); \
for(i = 0; i < veccount; i++) { \
libssh2_sha##digest_type##_update(ctx, datavec[i].iov_base, \
datavec[i].iov_len); \
} \
libssh2_sha##digest_type##_final(ctx, hash); \
ret = _libssh2_ecdsa_sign(session, ec_ctx, hash, \
SHA##digest_type##_DIGEST_LENGTH, \
signature, signature_len); \
}
#define LIBSSH2_HOSTKEY_METHOD_EC_SIGNV_HASH(digest_type) \
do { \
unsigned char hash[SHA##digest_type##_DIGEST_LENGTH]; \
libssh2_sha##digest_type##_ctx ctx; \
int i; \
if(!libssh2_sha##digest_type##_init(&ctx)) { \
ret = -1; \
break; \
} \
for(i = 0; i < veccount; i++) { \
if(!libssh2_sha##digest_type##_update(ctx, \
datavec[i].iov_base, \
datavec[i].iov_len)) { \
ret = -1; \
break; \
} \
} \
if(ret == -1) { \
break; \
} \
if(!libssh2_sha##digest_type##_final(ctx, hash)) { \
ret = -1; \
break; \
} \
ret = _libssh2_ecdsa_sign(session, ec_ctx, hash, \
SHA##digest_type##_DIGEST_LENGTH, \
signature, signature_len); \
} while(0)
/*
@ -737,9 +1036,9 @@ static int
hostkey_method_ssh_ecdsa_dtor(LIBSSH2_SESSION * session, void **abstract)
{
libssh2_ecdsa_ctx *keyctx = (libssh2_ecdsa_ctx *) (*abstract);
(void) session;
(void)session;
if(keyctx != NULL)
if(keyctx)
_libssh2_ecdsa_free(keyctx);
*abstract = NULL;
@ -841,9 +1140,10 @@ hostkey_method_ssh_ed25519_init(LIBSSH2_SESSION * session,
size_t hostkey_data_len,
void **abstract)
{
const unsigned char *s;
unsigned long len, key_len;
size_t key_len;
unsigned char *key;
libssh2_ed25519_ctx *ctx = NULL;
struct string_buf buf;
if(*abstract) {
hostkey_method_ssh_ed25519_dtor(session, abstract);
@ -851,26 +1151,26 @@ hostkey_method_ssh_ed25519_init(LIBSSH2_SESSION * session,
}
if(hostkey_data_len < 19) {
_libssh2_debug(session, LIBSSH2_TRACE_ERROR,
"host key length too short");
_libssh2_debug((session, LIBSSH2_TRACE_ERROR,
"host key length too short"));
return -1;
}
s = hostkey_data;
len = _libssh2_ntohu32(s);
s += 4;
buf.data = (unsigned char *)hostkey_data;
buf.dataptr = buf.data;
buf.len = hostkey_data_len;
if(len != 11 || strncmp((char *) s, "ssh-ed25519", 11) != 0) {
if(_libssh2_match_string(&buf, "ssh-ed25519"))
return -1;
}
s += 11;
/* public key */
key_len = _libssh2_ntohu32(s);
s += 4;
if(_libssh2_get_string(&buf, &key, &key_len))
return -1;
if(_libssh2_ed25519_new_public(&ctx, session, s, key_len) != 0) {
if(!_libssh2_eob(&buf))
return -1;
if(_libssh2_ed25519_new_public(&ctx, session, key, key_len) != 0) {
return -1;
}
@ -886,9 +1186,9 @@ hostkey_method_ssh_ed25519_init(LIBSSH2_SESSION * session,
*/
static int
hostkey_method_ssh_ed25519_initPEM(LIBSSH2_SESSION * session,
const char *privkeyfile,
unsigned const char *passphrase,
void **abstract)
const char *privkeyfile,
unsigned const char *passphrase,
void **abstract)
{
libssh2_ed25519_ctx *ec_ctx = NULL;
int ret;
@ -924,7 +1224,7 @@ hostkey_method_ssh_ed25519_initPEMFromMemory(LIBSSH2_SESSION * session,
libssh2_ed25519_ctx *ed_ctx = NULL;
int ret;
if(abstract != NULL && *abstract) {
if(abstract && *abstract) {
hostkey_method_ssh_ed25519_dtor(session, abstract);
*abstract = NULL;
}
@ -937,7 +1237,7 @@ hostkey_method_ssh_ed25519_initPEMFromMemory(LIBSSH2_SESSION * session,
return -1;
}
if(abstract != NULL)
if(abstract)
*abstract = ed_ctx;
return 0;
@ -956,7 +1256,7 @@ hostkey_method_ssh_ed25519_sig_verify(LIBSSH2_SESSION * session,
size_t m_len, void **abstract)
{
libssh2_ed25519_ctx *ctx = (libssh2_ed25519_ctx *) (*abstract);
(void) session;
(void)session;
if(sig_len < 19)
return -1;
@ -979,11 +1279,11 @@ hostkey_method_ssh_ed25519_sig_verify(LIBSSH2_SESSION * session,
*/
static int
hostkey_method_ssh_ed25519_signv(LIBSSH2_SESSION * session,
unsigned char **signature,
size_t *signature_len,
int veccount,
const struct iovec datavec[],
void **abstract)
unsigned char **signature,
size_t *signature_len,
int veccount,
const struct iovec datavec[],
void **abstract)
{
libssh2_ed25519_ctx *ctx = (libssh2_ed25519_ctx *) (*abstract);
@ -992,7 +1292,8 @@ hostkey_method_ssh_ed25519_signv(LIBSSH2_SESSION * session,
}
return _libssh2_ed25519_sign(ctx, session, signature, signature_len,
datavec[0].iov_base, datavec[0].iov_len);
(const uint8_t *)datavec[0].iov_base,
datavec[0].iov_len);
}
@ -1005,7 +1306,7 @@ static int
hostkey_method_ssh_ed25519_dtor(LIBSSH2_SESSION * session, void **abstract)
{
libssh2_ed25519_ctx *keyctx = (libssh2_ed25519_ctx*) (*abstract);
(void) session;
(void)session;
if(keyctx)
_libssh2_ed25519_free(keyctx);
@ -1027,7 +1328,19 @@ static const LIBSSH2_HOSTKEY_METHOD hostkey_method_ssh_ed25519 = {
hostkey_method_ssh_ed25519_dtor,
};
#endif /*LIBSSH2_ED25519*/
static const LIBSSH2_HOSTKEY_METHOD hostkey_method_ssh_ed25519_cert = {
"ssh-ed25519-cert-v01@openssh.com",
SHA256_DIGEST_LENGTH,
hostkey_method_ssh_ed25519_init,
hostkey_method_ssh_ed25519_initPEM,
hostkey_method_ssh_ed25519_initPEMFromMemory,
hostkey_method_ssh_ed25519_sig_verify,
hostkey_method_ssh_ed25519_signv,
NULL, /* encrypt */
hostkey_method_ssh_ed25519_dtor,
};
#endif /* LIBSSH2_ED25519 */
static const LIBSSH2_HOSTKEY_METHOD *hostkey_methods[] = {
@ -1041,9 +1354,19 @@ static const LIBSSH2_HOSTKEY_METHOD *hostkey_methods[] = {
#endif
#if LIBSSH2_ED25519
&hostkey_method_ssh_ed25519,
&hostkey_method_ssh_ed25519_cert,
#endif
#if LIBSSH2_RSA
#if LIBSSH2_RSA_SHA2
&hostkey_method_ssh_rsa_sha2_512,
&hostkey_method_ssh_rsa_sha2_256,
&hostkey_method_ssh_rsa_sha2_512_cert,
&hostkey_method_ssh_rsa_sha2_256_cert,
#endif /* LIBSSH2_RSA_SHA2 */
#if LIBSSH2_RSA_SHA1
&hostkey_method_ssh_rsa,
&hostkey_method_ssh_rsa_cert,
#endif /* LIBSSH2_RSA_SHA1 */
#endif /* LIBSSH2_RSA */
#if LIBSSH2_DSA
&hostkey_method_ssh_dss,
@ -1074,18 +1397,15 @@ libssh2_hostkey_hash(LIBSSH2_SESSION * session, int hash_type)
return (session->server_hostkey_md5_valid)
? (char *) session->server_hostkey_md5
: NULL;
break;
#endif /* LIBSSH2_MD5 */
case LIBSSH2_HOSTKEY_HASH_SHA1:
return (session->server_hostkey_sha1_valid)
? (char *) session->server_hostkey_sha1
: NULL;
break;
case LIBSSH2_HOSTKEY_HASH_SHA256:
return (session->server_hostkey_sha256_valid)
? (char *) session->server_hostkey_sha256
: NULL;
break;
default:
return NULL;
}
@ -1096,9 +1416,11 @@ static int hostkey_type(const unsigned char *hostkey, size_t len)
static const unsigned char rsa[] = {
0, 0, 0, 0x07, 's', 's', 'h', '-', 'r', 's', 'a'
};
#if LIBSSH2_DSA
static const unsigned char dss[] = {
0, 0, 0, 0x07, 's', 's', 'h', '-', 'd', 's', 's'
};
#endif
static const unsigned char ecdsa_256[] = {
0, 0, 0, 0x13, 'e', 'c', 'd', 's', 'a', '-', 's', 'h', 'a', '2', '-',
'n', 'i', 's', 't', 'p', '2', '5', '6'
@ -1121,8 +1443,10 @@ static int hostkey_type(const unsigned char *hostkey, size_t len)
if(!memcmp(rsa, hostkey, 11))
return LIBSSH2_HOSTKEY_TYPE_RSA;
#if LIBSSH2_DSA
if(!memcmp(dss, hostkey, 11))
return LIBSSH2_HOSTKEY_TYPE_DSS;
#endif
if(len < 15)
return LIBSSH2_HOSTKEY_TYPE_UNKNOWN;
@ -1146,7 +1470,7 @@ static int hostkey_type(const unsigned char *hostkey, size_t len)
}
/*
* libssh2_session_hostkey()
* libssh2_session_hostkey
*
* Returns the server key and length.
*

View file

@ -1,5 +1,5 @@
/* Copyright (C) 2010 Simon Josefsson
* Author: Simon Josefsson
/* Copyright (C) Simon Josefsson
* All rights reserved.
*
* Redistribution and use in source and binary forms,
* with or without modification, are permitted provided
@ -34,6 +34,7 @@
* USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
* OF SUCH DAMAGE.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#include "libssh2_priv.h"
@ -42,9 +43,9 @@
/* Keep-alive stuff. */
LIBSSH2_API void
libssh2_keepalive_config (LIBSSH2_SESSION *session,
int want_reply,
unsigned interval)
libssh2_keepalive_config(LIBSSH2_SESSION *session,
int want_reply,
unsigned int interval)
{
if(interval == 1)
session->keepalive_interval = 2;
@ -54,8 +55,8 @@ libssh2_keepalive_config (LIBSSH2_SESSION *session,
}
LIBSSH2_API int
libssh2_keepalive_send (LIBSSH2_SESSION *session,
int *seconds_to_next)
libssh2_keepalive_send(LIBSSH2_SESSION *session,
int *seconds_to_next)
{
time_t now;

File diff suppressed because it is too large Load diff

View file

@ -1,5 +1,5 @@
/*
* Copyright (c) 2009-2019 by Daniel Stenberg
* Copyright (C) Daniel Stenberg
* All rights reserved.
*
* Redistribution and use in source and binary forms,
@ -34,10 +34,11 @@
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
* USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
* OF SUCH DAMAGE.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#include "libssh2_priv.h"
#include "misc.h"
struct known_host {
struct list_node node;
@ -111,7 +112,7 @@ libssh2_knownhost_init(LIBSSH2_SESSION *session)
#define KNOWNHOST_MAGIC 0xdeadcafe
/*
* knownhost_to_external()
* knownhost_to_external
*
* Copies data from the internal to the external representation struct.
*
@ -123,7 +124,7 @@ static struct libssh2_knownhost *knownhost_to_external(struct known_host *node)
ext->magic = KNOWNHOST_MAGIC;
ext->node = node;
ext->name = ((node->typemask & LIBSSH2_KNOWNHOST_TYPE_MASK) ==
LIBSSH2_KNOWNHOST_TYPE_PLAIN)? node->name:NULL;
LIBSSH2_KNOWNHOST_TYPE_PLAIN) ? node->name : NULL;
ext->key = node->key;
ext->typemask = node->typemask;
@ -142,7 +143,7 @@ knownhost_add(LIBSSH2_KNOWNHOSTS *hosts,
size_t hostlen = strlen(host);
int rc;
char *ptr;
unsigned int ptrlen;
size_t ptrlen;
/* make sure we have a key type set */
if(!(typemask & LIBSSH2_KNOWNHOST_KEY_MASK))
@ -170,15 +171,15 @@ knownhost_add(LIBSSH2_KNOWNHOSTS *hosts,
entry->name_len = hostlen;
break;
case LIBSSH2_KNOWNHOST_TYPE_SHA1:
rc = libssh2_base64_decode(hosts->session, &ptr, &ptrlen,
host, hostlen);
rc = _libssh2_base64_decode(hosts->session, &ptr, &ptrlen,
host, hostlen);
if(rc)
goto error;
entry->name = ptr;
entry->name_len = ptrlen;
rc = libssh2_base64_decode(hosts->session, &ptr, &ptrlen,
salt, strlen(salt));
rc = _libssh2_base64_decode(hosts->session, &ptr, &ptrlen,
salt, strlen(salt));
if(rc)
goto error;
entry->salt = ptr;
@ -252,7 +253,7 @@ knownhost_add(LIBSSH2_KNOWNHOSTS *hosts,
*store = knownhost_to_external(entry);
return LIBSSH2_ERROR_NONE;
error:
error:
free_host(hosts->session, entry);
return rc;
}
@ -420,19 +421,23 @@ knownhost_check(LIBSSH2_KNOWNHOSTS *hosts,
*/
unsigned char hash[SHA_DIGEST_LENGTH];
libssh2_hmac_ctx ctx;
libssh2_hmac_ctx_init(ctx);
if(!_libssh2_hmac_ctx_init(&ctx))
break;
if(SHA_DIGEST_LENGTH != node->name_len) {
/* the name hash length must be the sha1 size or
we can't match it */
break;
}
libssh2_hmac_sha1_init(&ctx, (unsigned char *)node->salt,
node->salt_len);
libssh2_hmac_update(ctx, (unsigned char *)host,
strlen(host));
libssh2_hmac_final(ctx, hash);
libssh2_hmac_cleanup(&ctx);
if(!_libssh2_hmac_sha1_init(&ctx,
node->salt, node->salt_len))
break;
if(!_libssh2_hmac_update(&ctx, host, strlen(host)) ||
!_libssh2_hmac_final(&ctx, hash)) {
_libssh2_hmac_cleanup(&ctx);
break;
}
_libssh2_hmac_cleanup(&ctx);
if(!memcmp(hash, node->name, SHA_DIGEST_LENGTH))
/* this is a node we're interested in */
@ -727,7 +732,7 @@ static int hashed_hostline(LIBSSH2_KNOWNHOSTS *hosts,
}
/*
* hostline()
* hostline
*
* Parse a single known_host line pre-split into host and key.
*
@ -774,18 +779,20 @@ static int hostline(LIBSSH2_KNOWNHOSTS *hosts,
}
key_type_len = key - key_type_name;
if(!strncmp(key_type_name, "ssh-dss", key_type_len))
key_type = LIBSSH2_KNOWNHOST_KEY_SSHDSS;
else if(!strncmp(key_type_name, "ssh-rsa", key_type_len))
key_type = LIBSSH2_KNOWNHOST_KEY_SSHRSA;
if(!strncmp(key_type_name, "ssh-ed25519", key_type_len))
key_type = LIBSSH2_KNOWNHOST_KEY_ED25519;
else if(!strncmp(key_type_name, "ecdsa-sha2-nistp256", key_type_len))
key_type = LIBSSH2_KNOWNHOST_KEY_ECDSA_256;
else if(!strncmp(key_type_name, "ecdsa-sha2-nistp384", key_type_len))
key_type = LIBSSH2_KNOWNHOST_KEY_ECDSA_384;
else if(!strncmp(key_type_name, "ecdsa-sha2-nistp521", key_type_len))
key_type = LIBSSH2_KNOWNHOST_KEY_ECDSA_521;
else if(!strncmp(key_type_name, "ssh-ed25519", key_type_len))
key_type = LIBSSH2_KNOWNHOST_KEY_ED25519;
else if(!strncmp(key_type_name, "ssh-rsa", key_type_len))
key_type = LIBSSH2_KNOWNHOST_KEY_SSHRSA;
#if LIBSSH2_DSA
else if(!strncmp(key_type_name, "ssh-dss", key_type_len))
key_type = LIBSSH2_KNOWNHOST_KEY_SSHDSS;
#endif
else
key_type = LIBSSH2_KNOWNHOST_KEY_UNKNOWN;
@ -822,7 +829,7 @@ static int hostline(LIBSSH2_KNOWNHOSTS *hosts,
}
/* Figure out host format */
if((hostlen >2) && memcmp(host, "|1|", 3)) {
if((hostlen > 2) && memcmp(host, "|1|", 3)) {
/* old style plain text: [name]([,][name])*
for the sake of simplicity, we add them as separate hosts with the
@ -841,7 +848,7 @@ static int hostline(LIBSSH2_KNOWNHOSTS *hosts,
}
/*
* libssh2_knownhost_readline()
* libssh2_knownhost_readline
*
* Pass in a line of a file of 'type'.
*
@ -983,7 +990,7 @@ libssh2_knownhost_readfile(LIBSSH2_KNOWNHOSTS *hosts,
}
/*
* knownhost_writeline()
* knownhost_writeline
*
* Ask libssh2 to convert a known host to an output line for storage.
*
@ -1021,10 +1028,12 @@ knownhost_writeline(LIBSSH2_KNOWNHOSTS *hosts,
key_type_name = "ssh-rsa";
key_type_len = 7;
break;
#if LIBSSH2_DSA
case LIBSSH2_KNOWNHOST_KEY_SSHDSS:
key_type_name = "ssh-dss";
key_type_len = 7;
break;
#endif
case LIBSSH2_KNOWNHOST_KEY_ECDSA_256:
key_type_name = "ecdsa-sha2-nistp256";
key_type_len = 19;
@ -1048,7 +1057,7 @@ knownhost_writeline(LIBSSH2_KNOWNHOSTS *hosts,
break;
}
/* otherwise fallback to default and error */
/* FALL-THROUGH */
LIBSSH2_FALLTHROUGH();
default:
return _libssh2_error(hosts->session,
LIBSSH2_ERROR_METHOD_NOT_SUPPORTED,
@ -1157,7 +1166,7 @@ knownhost_writeline(LIBSSH2_KNOWNHOSTS *hosts,
}
/*
* libssh2_knownhost_writeline()
* libssh2_knownhost_writeline
*
* Ask libssh2 to convert a known host to an output line for storage.
*
@ -1183,7 +1192,7 @@ libssh2_knownhost_writeline(LIBSSH2_KNOWNHOSTS *hosts,
}
/*
* libssh2_knownhost_writefile()
* libssh2_knownhost_writefile
*
* Write hosts+key pairs to the given file.
*/
@ -1234,7 +1243,7 @@ libssh2_knownhost_writefile(LIBSSH2_KNOWNHOSTS *hosts,
/*
* libssh2_knownhost_get()
* libssh2_knownhost_get
*
* Traverse the internal list of known hosts. Pass NULL to 'prev' to get
* the first one.

View file

@ -1,5 +1,5 @@
/* Copyright (C) 2008, 2009, Simon Josefsson
* Copyright (C) 2006, 2007, The Written Word, Inc.
/* Copyright (C) Simon Josefsson
* Copyright (C) The Written Word, Inc.
* All rights reserved.
*
* Redistribution and use in source and binary forms,
@ -34,14 +34,112 @@
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
* USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
* OF SUCH DAMAGE.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#include "libssh2_priv.h"
#ifdef LIBSSH2_CRYPTO_C /* Compile this via crypto.c */
#ifdef LIBSSH2_LIBGCRYPT /* compile only if we build with libgcrypt */
int _libssh2_hmac_ctx_init(libssh2_hmac_ctx *ctx)
{
*ctx = NULL;
return 1;
}
#include <string.h>
#if LIBSSH2_MD5
int _libssh2_hmac_md5_init(libssh2_hmac_ctx *ctx,
void *key, size_t keylen)
{
gcry_error_t err;
err = gcry_md_open(ctx, GCRY_MD_MD5, GCRY_MD_FLAG_HMAC);
if(gcry_err_code(err) != GPG_ERR_NO_ERROR)
return 0;
err = gcry_md_setkey(*ctx, key, keylen);
if(gcry_err_code(err) != GPG_ERR_NO_ERROR)
return 0;
return 1;
}
#endif
#if LIBSSH2_HMAC_RIPEMD
int _libssh2_hmac_ripemd160_init(libssh2_hmac_ctx *ctx,
void *key, size_t keylen)
{
gcry_error_t err;
err = gcry_md_open(ctx, GCRY_MD_RMD160, GCRY_MD_FLAG_HMAC);
if(gcry_err_code(err) != GPG_ERR_NO_ERROR)
return 0;
err = gcry_md_setkey(*ctx, key, keylen);
if(gcry_err_code(err) != GPG_ERR_NO_ERROR)
return 0;
return 1;
}
#endif
int _libssh2_hmac_sha1_init(libssh2_hmac_ctx *ctx,
void *key, size_t keylen)
{
gcry_error_t err;
err = gcry_md_open(ctx, GCRY_MD_SHA1, GCRY_MD_FLAG_HMAC);
if(gcry_err_code(err) != GPG_ERR_NO_ERROR)
return 0;
err = gcry_md_setkey(*ctx, key, keylen);
if(gcry_err_code(err) != GPG_ERR_NO_ERROR)
return 0;
return 1;
}
int _libssh2_hmac_sha256_init(libssh2_hmac_ctx *ctx,
void *key, size_t keylen)
{
gcry_error_t err;
err = gcry_md_open(ctx, GCRY_MD_SHA256, GCRY_MD_FLAG_HMAC);
if(gcry_err_code(err) != GPG_ERR_NO_ERROR)
return 0;
err = gcry_md_setkey(*ctx, key, keylen);
if(gcry_err_code(err) != GPG_ERR_NO_ERROR)
return 0;
return 1;
}
int _libssh2_hmac_sha512_init(libssh2_hmac_ctx *ctx,
void *key, size_t keylen)
{
gcry_error_t err;
err = gcry_md_open(ctx, GCRY_MD_SHA512, GCRY_MD_FLAG_HMAC);
if(gcry_err_code(err) != GPG_ERR_NO_ERROR)
return 0;
err = gcry_md_setkey(*ctx, key, keylen);
if(gcry_err_code(err) != GPG_ERR_NO_ERROR)
return 0;
return 1;
}
int _libssh2_hmac_update(libssh2_hmac_ctx *ctx,
const void *data, size_t datalen)
{
gcry_md_write(*ctx, data, datalen);
return 1;
}
int _libssh2_hmac_final(libssh2_hmac_ctx *ctx, void *data)
{
unsigned char *res = gcry_md_read(*ctx, 0);
if(!res)
return 0;
memcpy(data, res, gcry_md_get_algo_dlen(gcry_md_get_algo(*ctx)));
return 1;
}
void _libssh2_hmac_cleanup(libssh2_hmac_ctx *ctx)
{
gcry_md_close(*ctx);
}
#if LIBSSH2_RSA
int
_libssh2_rsa_new(libssh2_rsa_ctx ** rsa,
const unsigned char *edata,
@ -61,17 +159,17 @@ _libssh2_rsa_new(libssh2_rsa_ctx ** rsa,
const unsigned char *coeffdata, unsigned long coefflen)
{
int rc;
(void) e1data;
(void) e1len;
(void) e2data;
(void) e2len;
(void)e1data;
(void)e1len;
(void)e2data;
(void)e2len;
if(ddata) {
rc = gcry_sexp_build
(rsa, NULL,
"(private-key(rsa(n%b)(e%b)(d%b)(q%b)(p%b)(u%b)))",
nlen, ndata, elen, edata, dlen, ddata, plen, pdata,
qlen, qdata, coefflen, coeffdata);
rc = gcry_sexp_build(rsa, NULL,
"(private-key(rsa(n%b)(e%b)(d%b)(q%b)(p%b)(u%b)))",
nlen, ndata, elen, edata, dlen, ddata, plen, pdata,
qlen, qdata, coefflen, coeffdata);
}
else {
rc = gcry_sexp_build(rsa, NULL, "(public-key(rsa(n%b)(e%b)))",
@ -85,27 +183,30 @@ _libssh2_rsa_new(libssh2_rsa_ctx ** rsa,
return 0;
}
#if LIBSSH2_RSA_SHA1
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)
size_t sig_len,
const unsigned char *m, size_t m_len)
{
unsigned char hash[SHA_DIGEST_LENGTH];
gcry_sexp_t s_sig, s_hash;
int rc = -1;
libssh2_sha1(m, m_len, hash);
if(libssh2_sha1(m, m_len, hash)) {
return -1;
}
rc = gcry_sexp_build(&s_hash, NULL,
"(data (flags pkcs1) (hash sha1 %b))",
SHA_DIGEST_LENGTH, hash);
if(rc != 0) {
if(rc) {
return -1;
}
rc = gcry_sexp_build(&s_sig, NULL, "(sig-val(rsa(s %b)))", sig_len, sig);
if(rc != 0) {
if(rc) {
gcry_sexp_release(s_hash);
return -1;
}
@ -116,7 +217,10 @@ _libssh2_rsa_sha1_verify(libssh2_rsa_ctx * rsa,
return (rc == 0) ? 0 : -1;
}
#endif
#endif
#if LIBSSH2_DSA
int
_libssh2_dsa_new(libssh2_dsa_ctx ** dsactx,
const unsigned char *p,
@ -132,10 +236,9 @@ _libssh2_dsa_new(libssh2_dsa_ctx ** dsactx,
int rc;
if(x_len) {
rc = gcry_sexp_build
(dsactx, NULL,
"(private-key(dsa(p%b)(q%b)(g%b)(y%b)(x%b)))",
p_len, p, q_len, q, g_len, g, y_len, y, x_len, x);
rc = gcry_sexp_build(dsactx, NULL,
"(private-key(dsa(p%b)(q%b)(g%b)(y%b)(x%b)))",
p_len, p, q_len, q, g_len, g, y_len, y, x_len, x);
}
else {
rc = gcry_sexp_build(dsactx, NULL,
@ -150,16 +253,23 @@ _libssh2_dsa_new(libssh2_dsa_ctx ** dsactx,
return 0;
}
#endif
#if LIBSSH2_RSA
int
_libssh2_rsa_new_private_frommemory(libssh2_rsa_ctx ** rsa,
LIBSSH2_SESSION * session,
const char *filedata, size_t filedata_len,
unsigned const char *passphrase)
{
(void)rsa;
(void)filedata;
(void)filedata_len;
(void)passphrase;
return _libssh2_error(session, LIBSSH2_ERROR_METHOD_NOT_SUPPORTED,
"Unable to extract private key from memory: "
"Method unimplemented in libgcrypt backend");
"Unable to extract private key from memory: "
"Method unimplemented in libgcrypt backend");
}
int
@ -169,7 +279,7 @@ _libssh2_rsa_new_private(libssh2_rsa_ctx ** rsa,
{
FILE *fp;
unsigned char *data, *save_data;
unsigned int datalen;
size_t datalen;
int ret;
unsigned char *n, *e, *d, *p, *q, *e1, *e2, *coeff;
unsigned int nlen, elen, dlen, plen, qlen, e1len, e2len, coefflen;
@ -195,83 +305,91 @@ _libssh2_rsa_new_private(libssh2_rsa_ctx ** rsa,
ret = -1;
goto fail;
}
/* First read Version field (should be 0). */
/* First read Version field (should be 0). */
ret = _libssh2_pem_decode_integer(&data, &datalen, &n, &nlen);
if(ret != 0 || (nlen != 1 && *n != '\0')) {
if(ret || (nlen != 1 && *n != '\0')) {
ret = -1;
goto fail;
}
ret = _libssh2_pem_decode_integer(&data, &datalen, &n, &nlen);
if(ret != 0) {
if(ret) {
ret = -1;
goto fail;
}
ret = _libssh2_pem_decode_integer(&data, &datalen, &e, &elen);
if(ret != 0) {
if(ret) {
ret = -1;
goto fail;
}
ret = _libssh2_pem_decode_integer(&data, &datalen, &d, &dlen);
if(ret != 0) {
if(ret) {
ret = -1;
goto fail;
}
ret = _libssh2_pem_decode_integer(&data, &datalen, &p, &plen);
if(ret != 0) {
if(ret) {
ret = -1;
goto fail;
}
ret = _libssh2_pem_decode_integer(&data, &datalen, &q, &qlen);
if(ret != 0) {
if(ret) {
ret = -1;
goto fail;
}
ret = _libssh2_pem_decode_integer(&data, &datalen, &e1, &e1len);
if(ret != 0) {
if(ret) {
ret = -1;
goto fail;
}
ret = _libssh2_pem_decode_integer(&data, &datalen, &e2, &e2len);
if(ret != 0) {
if(ret) {
ret = -1;
goto fail;
}
ret = _libssh2_pem_decode_integer(&data, &datalen, &coeff, &coefflen);
if(ret != 0) {
if(ret) {
ret = -1;
goto fail;
}
if(_libssh2_rsa_new(rsa, e, elen, n, nlen, d, dlen, p, plen,
q, qlen, e1, e1len, e2, e2len, coeff, coefflen)) {
q, qlen, e1, e1len, e2, e2len, coeff, coefflen)) {
ret = -1;
goto fail;
}
ret = 0;
fail:
fail:
LIBSSH2_FREE(session, save_data);
return ret;
}
#endif
#if LIBSSH2_DSA
int
_libssh2_dsa_new_private_frommemory(libssh2_dsa_ctx ** dsa,
LIBSSH2_SESSION * session,
const char *filedata, size_t filedata_len,
unsigned const char *passphrase)
{
(void)dsa;
(void)filedata;
(void)filedata_len;
(void)passphrase;
return _libssh2_error(session, LIBSSH2_ERROR_METHOD_NOT_SUPPORTED,
"Unable to extract private key from memory: "
"Method unimplemented in libgcrypt backend");
"Unable to extract private key from memory: "
"Method unimplemented in libgcrypt backend");
}
int
@ -281,7 +399,7 @@ _libssh2_dsa_new_private(libssh2_dsa_ctx ** dsa,
{
FILE *fp;
unsigned char *data, *save_data;
unsigned int datalen;
size_t datalen;
int ret;
unsigned char *p, *q, *g, *y, *x;
unsigned int plen, qlen, glen, ylen, xlen;
@ -308,44 +426,44 @@ _libssh2_dsa_new_private(libssh2_dsa_ctx ** dsa,
goto fail;
}
/* First read Version field (should be 0). */
/* First read Version field (should be 0). */
ret = _libssh2_pem_decode_integer(&data, &datalen, &p, &plen);
if(ret != 0 || (plen != 1 && *p != '\0')) {
if(ret || (plen != 1 && *p != '\0')) {
ret = -1;
goto fail;
}
ret = _libssh2_pem_decode_integer(&data, &datalen, &p, &plen);
if(ret != 0) {
if(ret) {
ret = -1;
goto fail;
}
ret = _libssh2_pem_decode_integer(&data, &datalen, &q, &qlen);
if(ret != 0) {
if(ret) {
ret = -1;
goto fail;
}
ret = _libssh2_pem_decode_integer(&data, &datalen, &g, &glen);
if(ret != 0) {
if(ret) {
ret = -1;
goto fail;
}
ret = _libssh2_pem_decode_integer(&data, &datalen, &y, &ylen);
if(ret != 0) {
if(ret) {
ret = -1;
goto fail;
}
ret = _libssh2_pem_decode_integer(&data, &datalen, &x, &xlen);
if(ret != 0) {
if(ret) {
ret = -1;
goto fail;
}
if(datalen != 0) {
if(datalen) {
ret = -1;
goto fail;
}
@ -357,11 +475,14 @@ _libssh2_dsa_new_private(libssh2_dsa_ctx ** dsa,
ret = 0;
fail:
fail:
LIBSSH2_FREE(session, save_data);
return ret;
}
#endif
#if LIBSSH2_RSA
#if LIBSSH2_RSA_SHA1
int
_libssh2_rsa_sha1_sign(LIBSSH2_SESSION * session,
libssh2_rsa_ctx * rsactx,
@ -380,8 +501,8 @@ _libssh2_rsa_sha1_sign(LIBSSH2_SESSION * session,
}
if(gcry_sexp_build(&data, NULL,
"(data (flags pkcs1) (hash sha1 %b))",
hash_len, hash)) {
"(data (flags pkcs1) (hash sha1 %b))",
hash_len, hash)) {
return -1;
}
@ -389,7 +510,7 @@ _libssh2_rsa_sha1_sign(LIBSSH2_SESSION * session,
gcry_sexp_release(data);
if(rc != 0) {
if(rc) {
return -1;
}
@ -421,11 +542,14 @@ _libssh2_rsa_sha1_sign(LIBSSH2_SESSION * session,
return rc;
}
#endif
#endif
#if LIBSSH2_DSA
int
_libssh2_dsa_sha1_sign(libssh2_dsa_ctx * dsactx,
const unsigned char *hash,
unsigned long hash_len, unsigned char *sig)
size_t hash_len, unsigned char *sig)
{
unsigned char zhash[SHA_DIGEST_LENGTH + 1];
gcry_sexp_t sig_sexp;
@ -442,7 +566,7 @@ _libssh2_dsa_sha1_sign(libssh2_dsa_ctx * dsactx,
zhash[0] = 0;
if(gcry_sexp_build(&data, NULL, "(data (value %b))",
hash_len + 1, zhash)) {
(int)(hash_len + 1), zhash)) {
return -1;
}
@ -450,13 +574,13 @@ _libssh2_dsa_sha1_sign(libssh2_dsa_ctx * dsactx,
gcry_sexp_release(data);
if(ret != 0) {
if(ret) {
return -1;
}
memset(sig, 0, 40);
/* Extract R. */
/* Extract R. */
data = gcry_sexp_find_token(sig_sexp, "r", 0);
if(!data)
@ -478,7 +602,7 @@ _libssh2_dsa_sha1_sign(libssh2_dsa_ctx * dsactx,
gcry_sexp_release(data);
/* Extract S. */
/* Extract S. */
data = gcry_sexp_find_token(sig_sexp, "s", 0);
if(!data)
@ -499,10 +623,10 @@ _libssh2_dsa_sha1_sign(libssh2_dsa_ctx * dsactx,
memcpy(sig + 20 + (20 - size), tmp, size);
goto out;
err:
err:
ret = -1;
out:
out:
if(sig_sexp) {
gcry_sexp_release(sig_sexp);
}
@ -515,22 +639,24 @@ _libssh2_dsa_sha1_sign(libssh2_dsa_ctx * dsactx,
int
_libssh2_dsa_sha1_verify(libssh2_dsa_ctx * dsactx,
const unsigned char *sig,
const unsigned char *m, unsigned long m_len)
const unsigned char *m, size_t m_len)
{
unsigned char hash[SHA_DIGEST_LENGTH + 1];
gcry_sexp_t s_sig, s_hash;
int rc = -1;
libssh2_sha1(m, m_len, hash + 1);
if(libssh2_sha1(m, m_len, hash + 1)) {
return -1;
}
hash[0] = 0;
if(gcry_sexp_build(&s_hash, NULL, "(data(flags raw)(value %b))",
SHA_DIGEST_LENGTH + 1, hash)) {
SHA_DIGEST_LENGTH + 1, hash)) {
return -1;
}
if(gcry_sexp_build(&s_sig, NULL, "(sig-val(dsa(r %b)(s %b)))",
20, sig, 20, sig + 20)) {
20, sig, 20, sig + 20)) {
gcry_sexp_release(s_hash);
return -1;
}
@ -541,6 +667,7 @@ _libssh2_dsa_sha1_verify(libssh2_dsa_ctx * dsactx,
return (rc == 0) ? 0 : -1;
}
#endif
int
_libssh2_cipher_init(_libssh2_cipher_ctx * h,
@ -550,9 +677,9 @@ _libssh2_cipher_init(_libssh2_cipher_ctx * h,
int ret;
int cipher = _libssh2_gcry_cipher(algo);
int mode = _libssh2_gcry_mode(algo);
int keylen = gcry_cipher_get_algo_keylen(cipher);
size_t keylen = gcry_cipher_get_algo_keylen(cipher);
(void) encrypt;
(void)encrypt;
ret = gcry_cipher_open(h, cipher, mode, 0);
if(ret) {
@ -566,7 +693,7 @@ _libssh2_cipher_init(_libssh2_cipher_ctx * h,
}
if(mode != GCRY_CIPHER_MODE_STREAM) {
int blklen = gcry_cipher_get_algo_blklen(cipher);
size_t blklen = gcry_cipher_get_algo_blklen(cipher);
if(mode == GCRY_CIPHER_MODE_CTR)
ret = gcry_cipher_setctr(*h, iv, blklen);
else
@ -583,11 +710,14 @@ _libssh2_cipher_init(_libssh2_cipher_ctx * h,
int
_libssh2_cipher_crypt(_libssh2_cipher_ctx * ctx,
_libssh2_cipher_type(algo),
int encrypt, unsigned char *block, size_t blklen)
int encrypt, unsigned char *block, size_t blklen,
int firstlast)
{
int cipher = _libssh2_gcry_cipher(algo);
int ret;
(void)algo;
(void)firstlast;
if(encrypt) {
ret = gcry_cipher_encrypt(*ctx, block, blklen, block, blklen);
}
@ -607,6 +737,14 @@ _libssh2_pub_priv_keyfilememory(LIBSSH2_SESSION *session,
size_t privatekeydata_len,
const char *passphrase)
{
(void)method;
(void)method_len;
(void)pubkeydata;
(void)pubkeydata_len;
(void)privatekeydata;
(void)privatekeydata_len;
(void)passphrase;
return _libssh2_error(session, LIBSSH2_ERROR_METHOD_NOT_SUPPORTED,
"Unable to extract public key from private "
"key in memory: "
@ -622,9 +760,49 @@ _libssh2_pub_priv_keyfile(LIBSSH2_SESSION *session,
const char *privatekey,
const char *passphrase)
{
(void)method;
(void)method_len;
(void)pubkeydata;
(void)pubkeydata_len;
(void)privatekey;
(void)passphrase;
return _libssh2_error(session, LIBSSH2_ERROR_FILE,
"Unable to extract public key from private key file: "
"Method unimplemented in libgcrypt backend");
"Unable to extract public key from private key file: "
"Method unimplemented in libgcrypt backend");
}
int
_libssh2_sk_pub_keyfilememory(LIBSSH2_SESSION *session,
unsigned char **method,
size_t *method_len,
unsigned char **pubkeydata,
size_t *pubkeydata_len,
int *algorithm,
unsigned char *flags,
const char **application,
const unsigned char **key_handle,
size_t *handle_len,
const char *privatekeydata,
size_t privatekeydata_len,
const char *passphrase)
{
(void)method;
(void)method_len;
(void)pubkeydata;
(void)pubkeydata_len;
(void)algorithm;
(void)flags;
(void)application;
(void)key_handle;
(void)handle_len;
(void)privatekeydata;
(void)privatekeydata_len;
(void)passphrase;
return _libssh2_error(session, LIBSSH2_ERROR_FILE,
"Unable to extract public SK key from private key file: "
"Method unimplemented in libgcrypt backend");
}
void _libssh2_init_aes_ctr(void)
@ -664,4 +842,22 @@ _libssh2_dh_dtor(_libssh2_dh_ctx *dhctx)
*dhctx = NULL;
}
#endif /* LIBSSH2_LIBGCRYPT */
/* _libssh2_supported_key_sign_algorithms
*
* Return supported key hash algo upgrades, see crypto.h
*
*/
const char *
_libssh2_supported_key_sign_algorithms(LIBSSH2_SESSION *session,
unsigned char *key_method,
size_t key_method_len)
{
(void)session;
(void)key_method;
(void)key_method_len;
return NULL;
}
#endif /* LIBSSH2_CRYPTO_C */

View file

@ -1,8 +1,8 @@
#ifndef __LIBSSH2_LIBGCRYPT_H
#define __LIBSSH2_LIBGCRYPT_H
#ifndef LIBSSH2_LIBGCRYPT_H
#define LIBSSH2_LIBGCRYPT_H
/*
* Copyright (C) 2008, 2009, 2010 Simon Josefsson
* Copyright (C) 2006, 2007, The Written Word, Inc.
* Copyright (C) Simon Josefsson
* Copyright (C) The Written Word, Inc.
* All rights reserved.
*
* Redistribution and use in source and binary forms,
@ -37,8 +37,12 @@
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
* USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
* OF SUCH DAMAGE.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#define LIBSSH2_CRYPTO_ENGINE libssh2_gcrypt
#include <gcrypt.h>
#define LIBSSH2_MD5 1
@ -47,19 +51,26 @@
#define LIBSSH2_HMAC_SHA256 1
#define LIBSSH2_HMAC_SHA512 1
#define LIBSSH2_AES 1
#define LIBSSH2_AES_CBC 1
#define LIBSSH2_AES_CTR 1
#define LIBSSH2_AES_GCM 0
#define LIBSSH2_BLOWFISH 1
#define LIBSSH2_RC4 1
#define LIBSSH2_CAST 1
#define LIBSSH2_3DES 1
#define LIBSSH2_RSA 1
#define LIBSSH2_RSA_SHA1 1
#define LIBSSH2_RSA_SHA2 0
#define LIBSSH2_DSA 1
#define LIBSSH2_ECDSA 0
#define LIBSSH2_ED25519 0
#include "crypto_config.h"
#if LIBSSH2_MD5 || LIBSSH2_MD5_PEM
#define MD5_DIGEST_LENGTH 16
#endif
#define SHA_DIGEST_LENGTH 20
#define SHA256_DIGEST_LENGTH 32
#define SHA384_DIGEST_LENGTH 48
@ -67,103 +78,79 @@
#define EC_MAX_POINT_LEN ((528 * 2 / 8) + 1)
#define _libssh2_random(buf, len) \
(gcry_randomize ((buf), (len), GCRY_STRONG_RANDOM), 0)
#define _libssh2_random(buf, len) \
(gcry_randomize((buf), (len), GCRY_STRONG_RANDOM), 0)
#define libssh2_prepare_iovec(vec, len) /* Empty. */
#define libssh2_sha1_ctx gcry_md_hd_t
/* returns 0 in case of failure */
#define libssh2_sha1_init(ctx) \
(GPG_ERR_NO_ERROR == gcry_md_open(ctx, GCRY_MD_SHA1, 0))
(GPG_ERR_NO_ERROR == gcry_md_open(ctx, GCRY_MD_SHA1, 0))
#define libssh2_sha1_update(ctx, data, len) \
gcry_md_write(ctx, (unsigned char *) data, len)
(gcry_md_write(ctx, (unsigned char *) data, len), 1)
#define libssh2_sha1_final(ctx, out) \
memcpy(out, gcry_md_read(ctx, 0), SHA_DIGEST_LENGTH), gcry_md_close(ctx)
(memcpy(out, gcry_md_read(ctx, 0), SHA_DIGEST_LENGTH), \
gcry_md_close(ctx), 1)
#define libssh2_sha1(message, len, out) \
gcry_md_hash_buffer(GCRY_MD_SHA1, out, message, len)
(gcry_md_hash_buffer(GCRY_MD_SHA1, out, message, len), 0)
#define libssh2_sha256_ctx gcry_md_hd_t
#define libssh2_sha256_init(ctx) \
(GPG_ERR_NO_ERROR == gcry_md_open(ctx, GCRY_MD_SHA256, 0))
(GPG_ERR_NO_ERROR == gcry_md_open(ctx, GCRY_MD_SHA256, 0))
#define libssh2_sha256_update(ctx, data, len) \
gcry_md_write(ctx, (unsigned char *) data, len)
(gcry_md_write(ctx, (unsigned char *) data, len), 1)
#define libssh2_sha256_final(ctx, out) \
memcpy(out, gcry_md_read(ctx, 0), SHA256_DIGEST_LENGTH), gcry_md_close(ctx)
(memcpy(out, gcry_md_read(ctx, 0), SHA256_DIGEST_LENGTH), \
gcry_md_close(ctx), 1)
#define libssh2_sha256(message, len, out) \
gcry_md_hash_buffer(GCRY_MD_SHA256, out, message, len)
(gcry_md_hash_buffer(GCRY_MD_SHA256, out, message, len), 0)
#define libssh2_sha384_ctx gcry_md_hd_t
#define libssh2_sha384_init(ctx) \
(GPG_ERR_NO_ERROR == gcry_md_open(ctx, GCRY_MD_SHA384, 0))
(GPG_ERR_NO_ERROR == gcry_md_open(ctx, GCRY_MD_SHA384, 0))
#define libssh2_sha384_update(ctx, data, len) \
gcry_md_write(ctx, (unsigned char *) data, len)
(gcry_md_write(ctx, (unsigned char *) data, len), 1)
#define libssh2_sha384_final(ctx, out) \
memcpy(out, gcry_md_read(ctx, 0), SHA384_DIGEST_LENGTH), gcry_md_close(ctx)
(memcpy(out, gcry_md_read(ctx, 0), SHA384_DIGEST_LENGTH), \
gcry_md_close(ctx), 1)
#define libssh2_sha384(message, len, out) \
gcry_md_hash_buffer(GCRY_MD_SHA384, out, message, len)
(gcry_md_hash_buffer(GCRY_MD_SHA384, out, message, len), 0)
#define libssh2_sha512_ctx gcry_md_hd_t
#define libssh2_sha512_init(ctx) \
(GPG_ERR_NO_ERROR == gcry_md_open(ctx, GCRY_MD_SHA512, 0))
(GPG_ERR_NO_ERROR == gcry_md_open(ctx, GCRY_MD_SHA512, 0))
#define libssh2_sha512_update(ctx, data, len) \
gcry_md_write(ctx, (unsigned char *) data, len)
(gcry_md_write(ctx, (unsigned char *) data, len), 1)
#define libssh2_sha512_final(ctx, out) \
memcpy(out, gcry_md_read(ctx, 0), SHA512_DIGEST_LENGTH), gcry_md_close(ctx)
(memcpy(out, gcry_md_read(ctx, 0), SHA512_DIGEST_LENGTH), \
gcry_md_close(ctx), 1)
#define libssh2_sha512(message, len, out) \
gcry_md_hash_buffer(GCRY_MD_SHA512, out, message, len)
(gcry_md_hash_buffer(GCRY_MD_SHA512, out, message, len), 0)
#if LIBSSH2_MD5 || LIBSSH2_MD5_PEM
#define libssh2_md5_ctx gcry_md_hd_t
/* returns 0 in case of failure */
#define libssh2_md5_init(ctx) \
(GPG_ERR_NO_ERROR == gcry_md_open(ctx, GCRY_MD_MD5, 0))
(GPG_ERR_NO_ERROR == gcry_md_open(ctx, GCRY_MD_MD5, 0))
#define libssh2_md5_update(ctx, data, len) \
gcry_md_write(ctx, (unsigned char *) data, len)
(gcry_md_write(ctx, (unsigned char *) data, len), 1)
#define libssh2_md5_final(ctx, out) \
memcpy(out, gcry_md_read(ctx, 0), MD5_DIGEST_LENGTH), gcry_md_close(ctx)
#define libssh2_md5(message, len, out) \
gcry_md_hash_buffer(GCRY_MD_MD5, out, message, len)
(memcpy(out, gcry_md_read(ctx, 0), MD5_DIGEST_LENGTH), \
gcry_md_close(ctx), 1)
#endif
#define libssh2_hmac_ctx gcry_md_hd_t
#define libssh2_hmac_ctx_init(ctx)
#define libssh2_hmac_sha1_init(ctx, key, keylen) \
gcry_md_open(ctx, GCRY_MD_SHA1, GCRY_MD_FLAG_HMAC), \
gcry_md_setkey(*ctx, key, keylen)
#define libssh2_hmac_md5_init(ctx, key, keylen) \
gcry_md_open(ctx, GCRY_MD_MD5, GCRY_MD_FLAG_HMAC), \
gcry_md_setkey(*ctx, key, keylen)
#define libssh2_hmac_ripemd160_init(ctx, key, keylen) \
gcry_md_open(ctx, GCRY_MD_RMD160, GCRY_MD_FLAG_HMAC), \
gcry_md_setkey(*ctx, key, keylen)
#define libssh2_hmac_sha256_init(ctx, key, keylen) \
gcry_md_open(ctx, GCRY_MD_SHA256, GCRY_MD_FLAG_HMAC), \
gcry_md_setkey(*ctx, key, keylen)
#define libssh2_hmac_sha512_init(ctx, key, keylen) \
gcry_md_open(ctx, GCRY_MD_SHA512, GCRY_MD_FLAG_HMAC), \
gcry_md_setkey(*ctx, key, keylen)
#define libssh2_hmac_update(ctx, data, datalen) \
gcry_md_write(ctx, (unsigned char *) data, datalen)
#define libssh2_hmac_final(ctx, data) \
memcpy(data, gcry_md_read(ctx, 0), \
gcry_md_get_algo_dlen(gcry_md_get_algo(ctx)))
#define libssh2_hmac_cleanup(ctx) gcry_md_close (*ctx);
#define libssh2_crypto_init() gcry_control (GCRYCTL_DISABLE_SECMEM)
#define libssh2_crypto_init() gcry_control(GCRYCTL_DISABLE_SECMEM)
#define libssh2_crypto_exit()
#define libssh2_rsa_ctx struct gcry_sexp
#define _libssh2_rsa_free(rsactx) gcry_sexp_release (rsactx)
#define _libssh2_rsa_free(rsactx) gcry_sexp_release(rsactx)
#define libssh2_dsa_ctx struct gcry_sexp
#define _libssh2_dsa_free(dsactx) gcry_sexp_release (dsactx)
#define _libssh2_dsa_free(dsactx) gcry_sexp_release(dsactx)
#if LIBSSH2_ECDSA
#else
@ -178,25 +165,27 @@
#define _libssh2_gcry_mode(m) (m & 0xFF)
#define _libssh2_cipher_aes256ctr \
_libssh2_gcry_ciphermode(GCRY_CIPHER_AES256, GCRY_CIPHER_MODE_CTR)
_libssh2_gcry_ciphermode(GCRY_CIPHER_AES256, GCRY_CIPHER_MODE_CTR)
#define _libssh2_cipher_aes192ctr \
_libssh2_gcry_ciphermode(GCRY_CIPHER_AES192, GCRY_CIPHER_MODE_CTR)
_libssh2_gcry_ciphermode(GCRY_CIPHER_AES192, GCRY_CIPHER_MODE_CTR)
#define _libssh2_cipher_aes128ctr \
_libssh2_gcry_ciphermode(GCRY_CIPHER_AES128, GCRY_CIPHER_MODE_CTR)
_libssh2_gcry_ciphermode(GCRY_CIPHER_AES128, GCRY_CIPHER_MODE_CTR)
#define _libssh2_cipher_aes256 \
_libssh2_gcry_ciphermode(GCRY_CIPHER_AES256, GCRY_CIPHER_MODE_CBC)
_libssh2_gcry_ciphermode(GCRY_CIPHER_AES256, GCRY_CIPHER_MODE_CBC)
#define _libssh2_cipher_aes192 \
_libssh2_gcry_ciphermode(GCRY_CIPHER_AES192, GCRY_CIPHER_MODE_CBC)
_libssh2_gcry_ciphermode(GCRY_CIPHER_AES192, GCRY_CIPHER_MODE_CBC)
#define _libssh2_cipher_aes128 \
_libssh2_gcry_ciphermode(GCRY_CIPHER_AES128, GCRY_CIPHER_MODE_CBC)
_libssh2_gcry_ciphermode(GCRY_CIPHER_AES128, GCRY_CIPHER_MODE_CBC)
#define _libssh2_cipher_blowfish \
_libssh2_gcry_ciphermode(GCRY_CIPHER_BLOWFISH, GCRY_CIPHER_MODE_CBC)
_libssh2_gcry_ciphermode(GCRY_CIPHER_BLOWFISH, GCRY_CIPHER_MODE_CBC)
#define _libssh2_cipher_arcfour \
_libssh2_gcry_ciphermode(GCRY_CIPHER_ARCFOUR, GCRY_CIPHER_MODE_STREAM)
_libssh2_gcry_ciphermode(GCRY_CIPHER_ARCFOUR, GCRY_CIPHER_MODE_STREAM)
#define _libssh2_cipher_cast5 \
_libssh2_gcry_ciphermode(GCRY_CIPHER_CAST5, GCRY_CIPHER_MODE_CBC)
_libssh2_gcry_ciphermode(GCRY_CIPHER_CAST5, GCRY_CIPHER_MODE_CBC)
#define _libssh2_cipher_3des \
_libssh2_gcry_ciphermode(GCRY_CIPHER_3DES, GCRY_CIPHER_MODE_CBC)
_libssh2_gcry_ciphermode(GCRY_CIPHER_3DES, GCRY_CIPHER_MODE_CBC)
#define _libssh2_cipher_chacha20 \
_libssh2_gcry_ciphermode(GCRY_CIPHER_CHACHA20, GCRY_CIPHER_MODE_STREAM)
#define _libssh2_cipher_dtor(ctx) gcry_cipher_close(*(ctx))
@ -206,26 +195,35 @@
#define _libssh2_bn_ctx_new() 0
#define _libssh2_bn_ctx_free(bnctx) ((void)0)
#define _libssh2_bn_init() gcry_mpi_new(0)
#define _libssh2_bn_init_from_bin() NULL /* because gcry_mpi_scan() creates a
new bignum */
#define _libssh2_bn_init_from_bin() NULL /* because gcry_mpi_scan() creates a
new bignum */
#define _libssh2_bn_set_word(bn, val) gcry_mpi_set_ui(bn, val)
#define _libssh2_bn_from_bin(bn, len, val) \
#define _libssh2_bn_from_bin(bn, len, val) \
gcry_mpi_scan(&((bn)), GCRYMPI_FMT_USG, val, len, NULL)
#define _libssh2_bn_to_bin(bn, val) \
#define _libssh2_bn_to_bin(bn, val) \
gcry_mpi_print(GCRYMPI_FMT_USG, val, _libssh2_bn_bytes(bn), NULL, bn)
#define _libssh2_bn_bytes(bn) \
(gcry_mpi_get_nbits (bn) / 8 + \
((gcry_mpi_get_nbits (bn) % 8 == 0) ? 0 : 1))
#define _libssh2_bn_bits(bn) gcry_mpi_get_nbits (bn)
#define _libssh2_bn_bytes(bn) \
(gcry_mpi_get_nbits(bn) / 8 + \
((gcry_mpi_get_nbits(bn) % 8 == 0) ? 0 : 1))
#define _libssh2_bn_bits(bn) gcry_mpi_get_nbits(bn)
#define _libssh2_bn_free(bn) gcry_mpi_release(bn)
/* Default generate and safe prime sizes for
diffie-hellman-group-exchange-sha1 */
#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
#define _libssh2_dh_ctx struct gcry_mpi *
#define libssh2_dh_init(dhctx) _libssh2_dh_init(dhctx)
#define libssh2_dh_key_pair(dhctx, public, g, p, group_order, bnctx) \
_libssh2_dh_key_pair(dhctx, public, g, p, group_order)
_libssh2_dh_key_pair(dhctx, public, g, p, group_order)
#define libssh2_dh_secret(dhctx, secret, f, p, bnctx) \
_libssh2_dh_secret(dhctx, secret, f, p)
_libssh2_dh_secret(dhctx, secret, f, p)
#define libssh2_dh_dtor(dhctx) _libssh2_dh_dtor(dhctx)
extern void _libssh2_init_aes_ctr(void);
extern void _libssh2_dh_init(_libssh2_dh_ctx *dhctx);
extern int _libssh2_dh_key_pair(_libssh2_dh_ctx *dhctx, _libssh2_bn *public,
_libssh2_bn *g, _libssh2_bn *p,
@ -234,4 +232,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 */
#endif /* LIBSSH2_LIBGCRYPT_H */

View file

@ -1,6 +1,6 @@
/* Copyright (c) 2004-2009, Sara Golemon <sarag@libssh2.org>
* Copyright (c) 2009-2015 Daniel Stenberg
* Copyright (c) 2010 Simon Josefsson <simon@josefsson.org>
/* Copyright (C) Sara Golemon <sarag@libssh2.org>
* Copyright (C) Daniel Stenberg
* Copyright (C) Simon Josefsson <simon@josefsson.org>
* All rights reserved.
*
* Redistribution and use in source and binary forms,
@ -35,27 +35,29 @@
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
* USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
* OF SUCH DAMAGE.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#ifndef LIBSSH2_H
#define LIBSSH2_H 1
#define LIBSSH2_COPYRIGHT "2004-2019 The libssh2 project and its contributors."
#define LIBSSH2_COPYRIGHT "The libssh2 project and its contributors."
/* We use underscore instead of dash when appending DEV in dev versions just
to make the BANNER define (used by src/session.c) be a valid SSH
banner. Release versions have no appended strings and may of course not
have dashes either. */
#define LIBSSH2_VERSION "1.10.0"
#define LIBSSH2_VERSION "1.11.1"
/* The numeric version number is also available "in parts" by using these
defines: */
#define LIBSSH2_VERSION_MAJOR 1
#define LIBSSH2_VERSION_MINOR 10
#define LIBSSH2_VERSION_PATCH 0
#define LIBSSH2_VERSION_MINOR 11
#define LIBSSH2_VERSION_PATCH 1
/* This is the numeric version of the libssh2 version number, meant for easier
parsing and comparions by programs. The LIBSSH2_VERSION_NUM define will
parsing and comparisons by programs. The LIBSSH2_VERSION_NUM define will
always follow this syntax:
0xXXYYZZ
@ -69,7 +71,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 0x010a00
#define LIBSSH2_VERSION_NUM 0x010b01
/*
* This is the date and time when the full source package was created. The
@ -80,13 +82,14 @@
*
* "Mon Feb 12 11:35:33 UTC 2007"
*/
#define LIBSSH2_TIMESTAMP "Sun 29 Aug 2021 08:37:50 PM UTC"
#define LIBSSH2_TIMESTAMP "Wed Oct 16 08:03:21 UTC 2024"
#ifndef RC_INVOKED
#ifdef __cplusplus
extern "C" {
#endif
#ifdef _WIN32
# include <basetsd.h>
# include <winsock2.h>
@ -99,8 +102,8 @@ extern "C" {
/* Allow alternate API prefix from CFLAGS or calling app */
#ifndef LIBSSH2_API
# ifdef LIBSSH2_WIN32
# ifdef _WINDLL
# ifdef _WIN32
# if defined(LIBSSH2_EXPORTS) || defined(_WINDLL)
# ifdef LIBSSH2_LIBRARY
# define LIBSSH2_API __declspec(dllexport)
# else
@ -109,25 +112,15 @@ extern "C" {
# else
# define LIBSSH2_API
# endif
# else /* !LIBSSH2_WIN32 */
# else /* !_WIN32 */
# define LIBSSH2_API
# endif /* LIBSSH2_WIN32 */
# endif /* _WIN32 */
#endif /* LIBSSH2_API */
#ifdef HAVE_SYS_UIO_H
# include <sys/uio.h>
#endif
#if (defined(NETWARE) && !defined(__NOVELL_LIBC__))
# include <sys/bsdskt.h>
typedef unsigned char uint8_t;
typedef unsigned short int uint16_t;
typedef unsigned int uint32_t;
typedef int int32_t;
typedef unsigned long long uint64_t;
typedef long long int64_t;
#endif
#ifdef _MSC_VER
typedef unsigned char uint8_t;
typedef unsigned short int uint16_t;
@ -147,13 +140,44 @@ typedef unsigned long long libssh2_uint64_t;
typedef long long libssh2_int64_t;
#endif
#ifdef WIN32
#ifdef _WIN32
typedef SOCKET libssh2_socket_t;
#define LIBSSH2_INVALID_SOCKET INVALID_SOCKET
#else /* !WIN32 */
#define LIBSSH2_SOCKET_CLOSE(s) closesocket(s)
#else /* !_WIN32 */
typedef int libssh2_socket_t;
#define LIBSSH2_INVALID_SOCKET -1
#endif /* WIN32 */
#define LIBSSH2_SOCKET_CLOSE(s) close(s)
#endif /* _WIN32 */
/* Compile-time deprecation macros */
#if !defined(LIBSSH2_DISABLE_DEPRECATION) && !defined(LIBSSH2_LIBRARY)
# if defined(_MSC_VER)
# if _MSC_VER >= 1400
# define LIBSSH2_DEPRECATED(version, message) \
__declspec(deprecated("since libssh2 " # version ". " message))
# elif _MSC_VER >= 1310
# define LIBSSH2_DEPRECATED(version, message) \
__declspec(deprecated)
# endif
# elif defined(__GNUC__) && !defined(__INTEL_COMPILER)
# if (defined(__clang__) && __clang_major__ >= 3) || \
(__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 5))
# define LIBSSH2_DEPRECATED(version, message) \
__attribute__((deprecated("since libssh2 " # version ". " message)))
# elif __GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ > 0)
# define LIBSSH2_DEPRECATED(version, message) \
__attribute__((deprecated))
# endif
# elif defined(__SUNPRO_C) && __SUNPRO_C >= 0x5130
# define LIBSSH2_DEPRECATED(version, message) \
__attribute__((deprecated))
# endif
#endif
#ifndef LIBSSH2_DEPRECATED
#define LIBSSH2_DEPRECATED(version, message)
#endif
/*
* Determine whether there is small or large file support on windows.
@ -190,8 +214,6 @@ typedef int libssh2_socket_t;
#ifdef LIBSSH2_USE_WIN32_LARGE_FILES
# include <io.h>
# include <sys/types.h>
# include <sys/stat.h>
# define LIBSSH2_STRUCT_STAT_SIZE_FORMAT "%I64d"
typedef struct _stati64 libssh2_struct_stat;
typedef __int64 libssh2_struct_stat_size;
@ -202,8 +224,6 @@ typedef __int64 libssh2_struct_stat_size;
*/
#ifdef LIBSSH2_USE_WIN32_SMALL_FILES
# include <sys/types.h>
# include <sys/stat.h>
# ifndef _WIN32_WCE
# define LIBSSH2_STRUCT_STAT_SIZE_FORMAT "%d"
typedef struct _stat libssh2_struct_stat;
@ -233,14 +253,6 @@ typedef off_t libssh2_struct_stat_size;
#define LIBSSH2_SSH_DEFAULT_BANNER LIBSSH2_SSH_BANNER
#define LIBSSH2_SSH_DEFAULT_BANNER_WITH_CRLF LIBSSH2_SSH_DEFAULT_BANNER "\r\n"
/* Default generate and safe prime sizes for
diffie-hellman-group-exchange-sha1 */
#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
#define LIBSSH2_TERM_HEIGHT 24
@ -272,59 +284,102 @@ typedef off_t libssh2_struct_stat_size;
typedef struct _LIBSSH2_USERAUTH_KBDINT_PROMPT
{
char *text;
unsigned int length;
unsigned char *text;
size_t length;
unsigned char echo;
} LIBSSH2_USERAUTH_KBDINT_PROMPT;
typedef struct _LIBSSH2_USERAUTH_KBDINT_RESPONSE
{
char *text;
unsigned int length;
unsigned int length; /* FIXME: change type to size_t */
} LIBSSH2_USERAUTH_KBDINT_RESPONSE;
typedef struct _LIBSSH2_SK_SIG_INFO {
uint8_t flags;
uint32_t counter;
unsigned char *sig_r;
size_t sig_r_len;
unsigned char *sig_s;
size_t sig_s_len;
} LIBSSH2_SK_SIG_INFO;
/* 'publickey' authentication callback */
#define LIBSSH2_USERAUTH_PUBLICKEY_SIGN_FUNC(name) \
int name(LIBSSH2_SESSION *session, unsigned char **sig, size_t *sig_len, \
const unsigned char *data, size_t data_len, void **abstract)
int name(LIBSSH2_SESSION *session, unsigned char **sig, size_t *sig_len, \
const unsigned char *data, size_t data_len, void **abstract)
/* 'keyboard-interactive' authentication callback */
/* FIXME: name_len, instruction_len -> size_t, num_prompts -> unsigned int? */
#define LIBSSH2_USERAUTH_KBDINT_RESPONSE_FUNC(name_) \
void name_(const char *name, int name_len, const char *instruction, \
int instruction_len, int num_prompts, \
const LIBSSH2_USERAUTH_KBDINT_PROMPT *prompts, \
LIBSSH2_USERAUTH_KBDINT_RESPONSE *responses, void **abstract)
void name_(const char *name, int name_len, const char *instruction, \
int instruction_len, int num_prompts, \
const LIBSSH2_USERAUTH_KBDINT_PROMPT *prompts, \
LIBSSH2_USERAUTH_KBDINT_RESPONSE *responses, void **abstract)
/* SK authentication callback */
#define LIBSSH2_USERAUTH_SK_SIGN_FUNC(name) \
int name(LIBSSH2_SESSION *session, LIBSSH2_SK_SIG_INFO *sig_info, \
const unsigned char *data, size_t data_len, \
int algorithm, uint8_t flags, \
const char *application, const unsigned char *key_handle, \
size_t handle_len, \
void **abstract)
/* Flags for SK authentication */
#define LIBSSH2_SK_PRESENCE_REQUIRED 0x01
#define LIBSSH2_SK_VERIFICATION_REQUIRED 0x04
/* FIXME: update lengths to size_t (or ssize_t): */
/* Callbacks for special SSH packets */
#define LIBSSH2_IGNORE_FUNC(name) \
void name(LIBSSH2_SESSION *session, const char *message, int message_len, \
void **abstract)
void name(LIBSSH2_SESSION *session, const char *message, int message_len, \
void **abstract)
#define LIBSSH2_DEBUG_FUNC(name) \
void name(LIBSSH2_SESSION *session, int always_display, const char *message, \
int message_len, const char *language, int language_len, \
void **abstract)
void name(LIBSSH2_SESSION *session, int always_display, \
const char *message, int message_len, \
const char *language, int language_len, \
void **abstract)
#define LIBSSH2_DISCONNECT_FUNC(name) \
void name(LIBSSH2_SESSION *session, int reason, const char *message, \
int message_len, const char *language, int language_len, \
void **abstract)
void name(LIBSSH2_SESSION *session, int reason, \
const char *message, int message_len, \
const char *language, int language_len, \
void **abstract)
#define LIBSSH2_PASSWD_CHANGEREQ_FUNC(name) \
void name(LIBSSH2_SESSION *session, char **newpw, int *newpw_len, \
void **abstract)
void name(LIBSSH2_SESSION *session, char **newpw, int *newpw_len, \
void **abstract)
#define LIBSSH2_MACERROR_FUNC(name) \
int name(LIBSSH2_SESSION *session, const char *packet, int packet_len, \
void **abstract)
int name(LIBSSH2_SESSION *session, const char *packet, int packet_len, \
void **abstract)
#define LIBSSH2_X11_OPEN_FUNC(name) \
void name(LIBSSH2_SESSION *session, LIBSSH2_CHANNEL *channel, \
const char *shost, int sport, void **abstract)
void name(LIBSSH2_SESSION *session, LIBSSH2_CHANNEL *channel, \
const char *shost, int sport, void **abstract)
#define LIBSSH2_AUTHAGENT_FUNC(name) \
void name(LIBSSH2_SESSION *session, LIBSSH2_CHANNEL *channel, \
void **abstract)
#define LIBSSH2_ADD_IDENTITIES_FUNC(name) \
void name(LIBSSH2_SESSION *session, void *buffer, \
const char *agent_path, void **abstract)
#define LIBSSH2_AUTHAGENT_SIGN_FUNC(name) \
int name(LIBSSH2_SESSION* session, \
unsigned char *blob, unsigned int blen, \
const unsigned char *data, unsigned int dlen, \
unsigned char **signature, unsigned int *sigLen, \
const char *agentPath, \
void **abstract)
#define LIBSSH2_CHANNEL_CLOSE_FUNC(name) \
void name(LIBSSH2_SESSION *session, void **session_abstract, \
LIBSSH2_CHANNEL *channel, void **channel_abstract)
void name(LIBSSH2_SESSION *session, void **session_abstract, \
LIBSSH2_CHANNEL *channel, void **channel_abstract)
/* I/O callbacks */
#define LIBSSH2_RECV_FUNC(name) \
@ -337,13 +392,16 @@ typedef struct _LIBSSH2_USERAUTH_KBDINT_RESPONSE
int flags, void **abstract)
/* libssh2_session_callback_set() constants */
#define LIBSSH2_CALLBACK_IGNORE 0
#define LIBSSH2_CALLBACK_DEBUG 1
#define LIBSSH2_CALLBACK_DISCONNECT 2
#define LIBSSH2_CALLBACK_MACERROR 3
#define LIBSSH2_CALLBACK_X11 4
#define LIBSSH2_CALLBACK_SEND 5
#define LIBSSH2_CALLBACK_RECV 6
#define LIBSSH2_CALLBACK_IGNORE 0
#define LIBSSH2_CALLBACK_DEBUG 1
#define LIBSSH2_CALLBACK_DISCONNECT 2
#define LIBSSH2_CALLBACK_MACERROR 3
#define LIBSSH2_CALLBACK_X11 4
#define LIBSSH2_CALLBACK_SEND 5
#define LIBSSH2_CALLBACK_RECV 6
#define LIBSSH2_CALLBACK_AUTHAGENT 7
#define LIBSSH2_CALLBACK_AUTHAGENT_IDENTITIES 8
#define LIBSSH2_CALLBACK_AUTHAGENT_SIGN 9
/* libssh2_session_method_pref() constants */
#define LIBSSH2_METHOD_KEX 0
@ -356,10 +414,12 @@ typedef struct _LIBSSH2_USERAUTH_KBDINT_RESPONSE
#define LIBSSH2_METHOD_COMP_SC 7
#define LIBSSH2_METHOD_LANG_CS 8
#define LIBSSH2_METHOD_LANG_SC 9
#define LIBSSH2_METHOD_SIGN_ALGO 10
/* flags */
#define LIBSSH2_FLAG_SIGPIPE 1
#define LIBSSH2_FLAG_COMPRESS 2
#define LIBSSH2_FLAG_QUOTE_PATHS 3
typedef struct _LIBSSH2_SESSION LIBSSH2_SESSION;
typedef struct _LIBSSH2_CHANNEL LIBSSH2_CHANNEL;
@ -367,6 +427,25 @@ typedef struct _LIBSSH2_LISTENER LIBSSH2_LISTENER;
typedef struct _LIBSSH2_KNOWNHOSTS LIBSSH2_KNOWNHOSTS;
typedef struct _LIBSSH2_AGENT LIBSSH2_AGENT;
/* SK signature callback */
typedef struct _LIBSSH2_PRIVKEY_SK {
int algorithm;
uint8_t flags;
const char *application;
const unsigned char *key_handle;
size_t handle_len;
LIBSSH2_USERAUTH_SK_SIGN_FUNC((*sign_callback));
void **orig_abstract;
} LIBSSH2_PRIVKEY_SK;
int
libssh2_sign_sk(LIBSSH2_SESSION *session,
unsigned char **sig,
size_t *sig_len,
const unsigned char *data,
size_t data_len,
void **abstract);
typedef struct _LIBSSH2_POLLFD {
unsigned char type; /* LIBSSH2_POLLFD_* below */
@ -423,7 +502,7 @@ typedef struct _LIBSSH2_POLLFD {
/* Hostkey Types */
#define LIBSSH2_HOSTKEY_TYPE_UNKNOWN 0
#define LIBSSH2_HOSTKEY_TYPE_RSA 1
#define LIBSSH2_HOSTKEY_TYPE_DSS 2
#define LIBSSH2_HOSTKEY_TYPE_DSS 2 /* deprecated */
#define LIBSSH2_HOSTKEY_TYPE_ECDSA_256 3
#define LIBSSH2_HOSTKEY_TYPE_ECDSA_384 4
#define LIBSSH2_HOSTKEY_TYPE_ECDSA_521 5
@ -506,6 +585,11 @@ typedef struct _LIBSSH2_POLLFD {
#define LIBSSH2_ERROR_CHANNEL_WINDOW_FULL -47
#define LIBSSH2_ERROR_KEYFILE_AUTH_FAILED -48
#define LIBSSH2_ERROR_RANDGEN -49
#define LIBSSH2_ERROR_MISSING_USERAUTH_BANNER -50
#define LIBSSH2_ERROR_ALGO_UNSUPPORTED -51
#define LIBSSH2_ERROR_MAC_FAILURE -52
#define LIBSSH2_ERROR_HASH_INIT -53
#define LIBSSH2_ERROR_HASH_CALC -54
/* this is a define to provide the old (<= 1.2.7) name */
#define LIBSSH2_ERROR_BANNER_NONE LIBSSH2_ERROR_BANNER_RECV
@ -566,14 +650,25 @@ libssh2_session_init_ex(LIBSSH2_ALLOC_FUNC((*my_alloc)),
LIBSSH2_API void **libssh2_session_abstract(LIBSSH2_SESSION *session);
typedef void (libssh2_cb_generic)(void);
LIBSSH2_API libssh2_cb_generic *
libssh2_session_callback_set2(LIBSSH2_SESSION *session, int cbtype,
libssh2_cb_generic *callback);
LIBSSH2_DEPRECATED(1.11.1, "Use libssh2_session_callback_set2()")
LIBSSH2_API void *libssh2_session_callback_set(LIBSSH2_SESSION *session,
int cbtype, void *callback);
LIBSSH2_API int libssh2_session_banner_set(LIBSSH2_SESSION *session,
const char *banner);
#ifndef LIBSSH2_NO_DEPRECATED
LIBSSH2_DEPRECATED(1.4.0, "Use libssh2_session_banner_set()")
LIBSSH2_API int libssh2_banner_set(LIBSSH2_SESSION *session,
const char *banner);
LIBSSH2_DEPRECATED(1.2.8, "Use libssh2_session_handshake()")
LIBSSH2_API int libssh2_session_startup(LIBSSH2_SESSION *session, int sock);
#endif
LIBSSH2_API int libssh2_session_handshake(LIBSSH2_SESSION *session,
libssh2_socket_t sock);
LIBSSH2_API int libssh2_session_disconnect_ex(LIBSSH2_SESSION *session,
@ -581,8 +676,8 @@ LIBSSH2_API int libssh2_session_disconnect_ex(LIBSSH2_SESSION *session,
const char *description,
const char *lang);
#define libssh2_session_disconnect(session, description) \
libssh2_session_disconnect_ex((session), SSH_DISCONNECT_BY_APPLICATION, \
(description), "")
libssh2_session_disconnect_ex((session), SSH_DISCONNECT_BY_APPLICATION, \
(description), "")
LIBSSH2_API int libssh2_session_free(LIBSSH2_SESSION *session);
@ -614,6 +709,8 @@ LIBSSH2_API const char *libssh2_session_banner_get(LIBSSH2_SESSION *session);
LIBSSH2_API char *libssh2_userauth_list(LIBSSH2_SESSION *session,
const char *username,
unsigned int username_len);
LIBSSH2_API int libssh2_userauth_banner(LIBSSH2_SESSION *session,
char **banner);
LIBSSH2_API int libssh2_userauth_authenticated(LIBSSH2_SESSION *session);
LIBSSH2_API int
@ -623,12 +720,13 @@ libssh2_userauth_password_ex(LIBSSH2_SESSION *session,
const char *password,
unsigned int password_len,
LIBSSH2_PASSWD_CHANGEREQ_FUNC
((*passwd_change_cb)));
((*passwd_change_cb)));
#define libssh2_userauth_password(session, username, password) \
libssh2_userauth_password_ex((session), (username), \
(unsigned int)strlen(username), \
(password), (unsigned int)strlen(password), NULL)
libssh2_userauth_password_ex((session), (username), \
(unsigned int)strlen(username), \
(password), (unsigned int)strlen(password), \
NULL)
LIBSSH2_API int
libssh2_userauth_publickey_fromfile_ex(LIBSSH2_SESSION *session,
@ -638,11 +736,11 @@ libssh2_userauth_publickey_fromfile_ex(LIBSSH2_SESSION *session,
const char *privatekey,
const char *passphrase);
#define libssh2_userauth_publickey_fromfile(session, username, publickey, \
privatekey, passphrase) \
libssh2_userauth_publickey_fromfile_ex((session), (username), \
#define libssh2_userauth_publickey_fromfile(session, username, publickey, \
privatekey, passphrase) \
libssh2_userauth_publickey_fromfile_ex((session), (username), \
(unsigned int)strlen(username), \
(publickey), \
(publickey), \
(privatekey), (passphrase))
LIBSSH2_API int
@ -651,7 +749,7 @@ libssh2_userauth_publickey(LIBSSH2_SESSION *session,
const unsigned char *pubkeydata,
size_t pubkeydata_len,
LIBSSH2_USERAUTH_PUBLICKEY_SIGN_FUNC
((*sign_callback)),
((*sign_callback)),
void **abstract);
LIBSSH2_API int
@ -666,16 +764,16 @@ libssh2_userauth_hostbased_fromfile_ex(LIBSSH2_SESSION *session,
const char *local_username,
unsigned int local_username_len);
#define libssh2_userauth_hostbased_fromfile(session, username, publickey, \
#define libssh2_userauth_hostbased_fromfile(session, username, publickey, \
privatekey, passphrase, hostname) \
libssh2_userauth_hostbased_fromfile_ex((session), (username), \
(unsigned int)strlen(username), \
(publickey), \
(privatekey), (passphrase), \
(hostname), \
(unsigned int)strlen(hostname), \
(username), \
(unsigned int)strlen(username))
libssh2_userauth_hostbased_fromfile_ex((session), (username), \
(unsigned int)strlen(username), \
(publickey), \
(privatekey), (passphrase), \
(hostname), \
(unsigned int)strlen(hostname), \
(username), \
(unsigned int)strlen(username))
LIBSSH2_API int
libssh2_userauth_publickey_frommemory(LIBSSH2_SESSION *session,
@ -697,15 +795,28 @@ LIBSSH2_API int
libssh2_userauth_keyboard_interactive_ex(LIBSSH2_SESSION* session,
const char *username,
unsigned int username_len,
LIBSSH2_USERAUTH_KBDINT_RESPONSE_FUNC(
(*response_callback)));
LIBSSH2_USERAUTH_KBDINT_RESPONSE_FUNC
((*response_callback)));
#define libssh2_userauth_keyboard_interactive(session, username, \
response_callback) \
libssh2_userauth_keyboard_interactive_ex((session), (username), \
#define libssh2_userauth_keyboard_interactive(session, username, \
response_callback) \
libssh2_userauth_keyboard_interactive_ex((session), (username), \
(unsigned int)strlen(username), \
(response_callback))
LIBSSH2_API int
libssh2_userauth_publickey_sk(LIBSSH2_SESSION *session,
const char *username,
size_t username_len,
const unsigned char *pubkeydata,
size_t pubkeydata_len,
const char *privatekeydata,
size_t privatekeydata_len,
const char *passphrase,
LIBSSH2_USERAUTH_SK_SIGN_FUNC
((*sign_callback)),
void **abstract);
LIBSSH2_API int libssh2_poll(LIBSSH2_POLLFD *fds, unsigned int nfds,
long timeout);
@ -731,22 +842,27 @@ libssh2_channel_open_ex(LIBSSH2_SESSION *session, const char *channel_type,
const char *message, unsigned int message_len);
#define libssh2_channel_open_session(session) \
libssh2_channel_open_ex((session), "session", sizeof("session") - 1, \
LIBSSH2_CHANNEL_WINDOW_DEFAULT, \
LIBSSH2_CHANNEL_PACKET_DEFAULT, NULL, 0)
libssh2_channel_open_ex((session), "session", sizeof("session") - 1, \
LIBSSH2_CHANNEL_WINDOW_DEFAULT, \
LIBSSH2_CHANNEL_PACKET_DEFAULT, NULL, 0)
LIBSSH2_API LIBSSH2_CHANNEL *
libssh2_channel_direct_tcpip_ex(LIBSSH2_SESSION *session, const char *host,
int port, const char *shost, int sport);
#define libssh2_channel_direct_tcpip(session, host, port) \
libssh2_channel_direct_tcpip_ex((session), (host), (port), "127.0.0.1", 22)
libssh2_channel_direct_tcpip_ex((session), (host), (port), "127.0.0.1", 22)
LIBSSH2_API LIBSSH2_CHANNEL *
libssh2_channel_direct_streamlocal_ex(LIBSSH2_SESSION * session,
const char *socket_path,
const char *shost, int sport);
LIBSSH2_API LIBSSH2_LISTENER *
libssh2_channel_forward_listen_ex(LIBSSH2_SESSION *session, const char *host,
int port, int *bound_port,
int queue_maxsize);
#define libssh2_channel_forward_listen(session, port) \
libssh2_channel_forward_listen_ex((session), NULL, (port), NULL, 16)
libssh2_channel_forward_listen_ex((session), NULL, (port), NULL, 16)
LIBSSH2_API int libssh2_channel_forward_cancel(LIBSSH2_LISTENER *listener);
@ -787,7 +903,7 @@ LIBSSH2_API int libssh2_channel_request_pty_size_ex(LIBSSH2_CHANNEL *channel,
int width_px,
int height_px);
#define libssh2_channel_request_pty_size(channel, width, height) \
libssh2_channel_request_pty_size_ex((channel), (width), (height), 0, 0)
libssh2_channel_request_pty_size_ex((channel), (width), (height), 0, 0)
LIBSSH2_API int libssh2_channel_x11_req_ex(LIBSSH2_CHANNEL *channel,
int single_connection,
@ -795,7 +911,13 @@ LIBSSH2_API int libssh2_channel_x11_req_ex(LIBSSH2_CHANNEL *channel,
const char *auth_cookie,
int screen_number);
#define libssh2_channel_x11_req(channel, screen_number) \
libssh2_channel_x11_req_ex((channel), 0, NULL, NULL, (screen_number))
libssh2_channel_x11_req_ex((channel), 0, NULL, NULL, (screen_number))
LIBSSH2_API int libssh2_channel_signal_ex(LIBSSH2_CHANNEL *channel,
const char *signame,
size_t signame_len);
#define libssh2_channel_signal(channel, signame) \
libssh2_channel_signal_ex((channel), signame, strlen(signame))
LIBSSH2_API int libssh2_channel_process_startup(LIBSSH2_CHANNEL *channel,
const char *request,
@ -803,23 +925,25 @@ LIBSSH2_API int libssh2_channel_process_startup(LIBSSH2_CHANNEL *channel,
const char *message,
unsigned int message_len);
#define libssh2_channel_shell(channel) \
libssh2_channel_process_startup((channel), "shell", sizeof("shell") - 1, \
NULL, 0)
libssh2_channel_process_startup((channel), "shell", sizeof("shell") - 1, \
NULL, 0)
#define libssh2_channel_exec(channel, command) \
libssh2_channel_process_startup((channel), "exec", sizeof("exec") - 1, \
(command), (unsigned int)strlen(command))
libssh2_channel_process_startup((channel), "exec", sizeof("exec") - 1, \
(command), (unsigned int)strlen(command))
#define libssh2_channel_subsystem(channel, subsystem) \
libssh2_channel_process_startup((channel), "subsystem", \
sizeof("subsystem") - 1, (subsystem), \
(unsigned int)strlen(subsystem))
libssh2_channel_process_startup((channel), "subsystem", \
sizeof("subsystem") - 1, (subsystem), \
(unsigned int)strlen(subsystem))
LIBSSH2_API ssize_t libssh2_channel_read_ex(LIBSSH2_CHANNEL *channel,
int stream_id, char *buf,
size_t buflen);
#define libssh2_channel_read(channel, buf, buflen) \
libssh2_channel_read_ex((channel), 0, (buf), (buflen))
libssh2_channel_read_ex((channel), 0, \
(buf), (buflen))
#define libssh2_channel_read_stderr(channel, buf, buflen) \
libssh2_channel_read_ex((channel), SSH_EXTENDED_DATA_STDERR, (buf), (buflen))
libssh2_channel_read_ex((channel), SSH_EXTENDED_DATA_STDERR, \
(buf), (buflen))
LIBSSH2_API int libssh2_poll_channel_read(LIBSSH2_CHANNEL *channel,
int extended);
@ -829,14 +953,15 @@ libssh2_channel_window_read_ex(LIBSSH2_CHANNEL *channel,
unsigned long *read_avail,
unsigned long *window_size_initial);
#define libssh2_channel_window_read(channel) \
libssh2_channel_window_read_ex((channel), NULL, NULL)
libssh2_channel_window_read_ex((channel), NULL, NULL)
/* libssh2_channel_receive_window_adjust is DEPRECATED, do not use! */
#ifndef LIBSSH2_NO_DEPRECATED
LIBSSH2_DEPRECATED(1.1.0, "Use libssh2_channel_receive_window_adjust2()")
LIBSSH2_API unsigned long
libssh2_channel_receive_window_adjust(LIBSSH2_CHANNEL *channel,
unsigned long adjustment,
unsigned char force);
#endif
LIBSSH2_API int
libssh2_channel_receive_window_adjust2(LIBSSH2_CHANNEL *channel,
unsigned long adjustment,
@ -848,16 +973,17 @@ LIBSSH2_API ssize_t libssh2_channel_write_ex(LIBSSH2_CHANNEL *channel,
size_t buflen);
#define libssh2_channel_write(channel, buf, buflen) \
libssh2_channel_write_ex((channel), 0, (buf), (buflen))
#define libssh2_channel_write_stderr(channel, buf, buflen) \
libssh2_channel_write_ex((channel), SSH_EXTENDED_DATA_STDERR, \
libssh2_channel_write_ex((channel), 0, \
(buf), (buflen))
#define libssh2_channel_write_stderr(channel, buf, buflen) \
libssh2_channel_write_ex((channel), SSH_EXTENDED_DATA_STDERR, \
(buf), (buflen))
LIBSSH2_API unsigned long
libssh2_channel_window_write_ex(LIBSSH2_CHANNEL *channel,
unsigned long *window_size_initial);
#define libssh2_channel_window_write(channel) \
libssh2_channel_window_write_ex((channel), NULL)
libssh2_channel_window_write_ex((channel), NULL)
LIBSSH2_API void libssh2_session_set_blocking(LIBSSH2_SESSION* session,
int blocking);
@ -870,12 +996,19 @@ LIBSSH2_API void libssh2_session_set_timeout(LIBSSH2_SESSION* session,
long timeout);
LIBSSH2_API long libssh2_session_get_timeout(LIBSSH2_SESSION* session);
/* libssh2_channel_handle_extended_data is DEPRECATED, do not use! */
LIBSSH2_API void libssh2_session_set_read_timeout(LIBSSH2_SESSION* session,
long timeout);
LIBSSH2_API long libssh2_session_get_read_timeout(LIBSSH2_SESSION* session);
#ifndef LIBSSH2_NO_DEPRECATED
LIBSSH2_DEPRECATED(1.1.0, "libssh2_channel_handle_extended_data2()")
LIBSSH2_API void libssh2_channel_handle_extended_data(LIBSSH2_CHANNEL *channel,
int ignore_mode);
#endif
LIBSSH2_API int libssh2_channel_handle_extended_data2(LIBSSH2_CHANNEL *channel,
int ignore_mode);
#ifndef LIBSSH2_NO_DEPRECATED
/* libssh2_channel_ignore_extended_data() is defined below for BC with version
* 0.1
*
@ -883,12 +1016,12 @@ LIBSSH2_API int libssh2_channel_handle_extended_data2(LIBSSH2_CHANNEL *channel,
* LIBSSH2_CHANNEL_EXTENDED_DATA_MERGE is passed, extended data will be read
* (FIFO) from the standard data channel
*/
/* DEPRECATED */
#define libssh2_channel_ignore_extended_data(channel, ignore) \
libssh2_channel_handle_extended_data((channel), \
(ignore) ? \
/* DEPRECATED since 0.3.0. Use libssh2_channel_handle_extended_data2(). */
#define libssh2_channel_ignore_extended_data(channel, ignore) \
libssh2_channel_handle_extended_data((channel), (ignore) ? \
LIBSSH2_CHANNEL_EXTENDED_DATA_IGNORE : \
LIBSSH2_CHANNEL_EXTENDED_DATA_NORMAL)
#endif
#define LIBSSH2_CHANNEL_FLUSH_EXTENDED_DATA -1
#define LIBSSH2_CHANNEL_FLUSH_ALL -2
@ -896,7 +1029,7 @@ LIBSSH2_API int libssh2_channel_flush_ex(LIBSSH2_CHANNEL *channel,
int streamid);
#define libssh2_channel_flush(channel) libssh2_channel_flush_ex((channel), 0)
#define libssh2_channel_flush_stderr(channel) \
libssh2_channel_flush_ex((channel), SSH_EXTENDED_DATA_STDERR)
libssh2_channel_flush_ex((channel), SSH_EXTENDED_DATA_STDERR)
LIBSSH2_API int libssh2_channel_get_exit_status(LIBSSH2_CHANNEL* channel);
LIBSSH2_API int libssh2_channel_get_exit_signal(LIBSSH2_CHANNEL* channel,
@ -913,11 +1046,13 @@ LIBSSH2_API int libssh2_channel_close(LIBSSH2_CHANNEL *channel);
LIBSSH2_API int libssh2_channel_wait_closed(LIBSSH2_CHANNEL *channel);
LIBSSH2_API int libssh2_channel_free(LIBSSH2_CHANNEL *channel);
/* libssh2_scp_recv is DEPRECATED, do not use! */
#ifndef LIBSSH2_NO_DEPRECATED
LIBSSH2_DEPRECATED(1.7.0, "Use libssh2_scp_recv2()")
LIBSSH2_API LIBSSH2_CHANNEL *libssh2_scp_recv(LIBSSH2_SESSION *session,
const char *path,
struct stat *sb);
/* Use libssh2_scp_recv2 for large (> 2GB) file support on windows */
#endif
/* Use libssh2_scp_recv2() for large (> 2GB) file support on windows */
LIBSSH2_API LIBSSH2_CHANNEL *libssh2_scp_recv2(LIBSSH2_SESSION *session,
const char *path,
libssh2_struct_stat *sb);
@ -930,8 +1065,9 @@ libssh2_scp_send64(LIBSSH2_SESSION *session, const char *path, int mode,
libssh2_int64_t size, time_t mtime, time_t atime);
#define libssh2_scp_send(session, path, mode, size) \
libssh2_scp_send_ex((session), (path), (mode), (size), 0, 0)
libssh2_scp_send_ex((session), (path), (mode), (size), 0, 0)
/* DEPRECATED */
LIBSSH2_API int libssh2_base64_decode(LIBSSH2_SESSION *session, char **dest,
unsigned int *dest_len,
const char *src, unsigned int src_len);
@ -939,8 +1075,22 @@ LIBSSH2_API int libssh2_base64_decode(LIBSSH2_SESSION *session, char **dest,
LIBSSH2_API
const char *libssh2_version(int req_version_num);
typedef enum {
libssh2_no_crypto = 0,
libssh2_openssl,
libssh2_gcrypt,
libssh2_mbedtls,
libssh2_wincng,
libssh2_os400qc3
} libssh2_crypto_engine_t;
LIBSSH2_API
libssh2_crypto_engine_t libssh2_crypto_engine(void);
#define HAVE_LIBSSH2_KNOWNHOST_API 0x010101 /* since 1.1.1 */
#define HAVE_LIBSSH2_VERSION_API 0x010100 /* libssh2_version since 1.1 */
#define HAVE_LIBSSH2_CRYPTOENGINE_API 0x011100 /* libssh2_crypto_engine
since 1.11 */
struct libssh2_knownhost {
unsigned int magic; /* magic stored by the library */
@ -951,7 +1101,7 @@ struct libssh2_knownhost {
};
/*
* libssh2_knownhost_init
* libssh2_knownhost_init()
*
* Init a collection of known hosts. Returns the pointer to a collection.
*
@ -960,7 +1110,7 @@ LIBSSH2_API LIBSSH2_KNOWNHOSTS *
libssh2_knownhost_init(LIBSSH2_SESSION *session);
/*
* libssh2_knownhost_add
* libssh2_knownhost_add()
*
* Add a host and its associated key to the collection of known hosts.
*
@ -997,7 +1147,7 @@ libssh2_knownhost_init(LIBSSH2_SESSION *session);
#define LIBSSH2_KNOWNHOST_KEY_SHIFT 18
#define LIBSSH2_KNOWNHOST_KEY_RSA1 (1<<18)
#define LIBSSH2_KNOWNHOST_KEY_SSHRSA (2<<18)
#define LIBSSH2_KNOWNHOST_KEY_SSHDSS (3<<18)
#define LIBSSH2_KNOWNHOST_KEY_SSHDSS (3<<18) /* deprecated */
#define LIBSSH2_KNOWNHOST_KEY_ECDSA_256 (4<<18)
#define LIBSSH2_KNOWNHOST_KEY_ECDSA_384 (5<<18)
#define LIBSSH2_KNOWNHOST_KEY_ECDSA_521 (6<<18)
@ -1012,7 +1162,7 @@ libssh2_knownhost_add(LIBSSH2_KNOWNHOSTS *hosts,
struct libssh2_knownhost **store);
/*
* libssh2_knownhost_addc
* libssh2_knownhost_addc()
*
* Add a host and its associated key to the collection of known hosts.
*
@ -1030,8 +1180,8 @@ libssh2_knownhost_add(LIBSSH2_KNOWNHOSTS *hosts,
* If 'sha1' is selected as type, the salt must be provided to the salt
* argument. This too base64 encoded.
*
* The SHA-1 hash is what OpenSSH can be told to use in known_hosts files. If
* a custom type is used, salt is ignored and you must provide the host
* The SHA-1 hash is what OpenSSH can be told to use in known_hosts files.
* If a custom type is used, salt is ignored and you must provide the host
* pre-hashed when checking for it in the libssh2_knownhost_check() function.
*
* The keylen parameter may be omitted (zero) if the key is provided as a
@ -1047,7 +1197,7 @@ libssh2_knownhost_addc(LIBSSH2_KNOWNHOSTS *hosts,
struct libssh2_knownhost **store);
/*
* libssh2_knownhost_check
* libssh2_knownhost_check()
*
* Check a host and its associated key against the collection of known hosts.
*
@ -1086,7 +1236,7 @@ libssh2_knownhost_checkp(LIBSSH2_KNOWNHOSTS *hosts,
struct libssh2_knownhost **knownhost);
/*
* libssh2_knownhost_del
* libssh2_knownhost_del()
*
* Remove a host from the collection of known hosts. The 'entry' struct is
* retrieved by a call to libssh2_knownhost_check().
@ -1097,7 +1247,7 @@ libssh2_knownhost_del(LIBSSH2_KNOWNHOSTS *hosts,
struct libssh2_knownhost *entry);
/*
* libssh2_knownhost_free
* libssh2_knownhost_free()
*
* Free an entire collection of known hosts.
*
@ -1118,7 +1268,7 @@ libssh2_knownhost_readline(LIBSSH2_KNOWNHOSTS *hosts,
const char *line, size_t len, int type);
/*
* libssh2_knownhost_readfile
* libssh2_knownhost_readfile()
*
* Add hosts+key pairs from a given file.
*
@ -1154,7 +1304,7 @@ libssh2_knownhost_writeline(LIBSSH2_KNOWNHOSTS *hosts,
int type);
/*
* libssh2_knownhost_writefile
* libssh2_knownhost_writefile()
*
* Write hosts+key pairs to a given file.
*
@ -1194,7 +1344,7 @@ struct libssh2_agent_publickey {
};
/*
* libssh2_agent_init
* libssh2_agent_init()
*
* Init an ssh-agent handle. Returns the pointer to the handle.
*
@ -1236,8 +1386,8 @@ libssh2_agent_list_identities(LIBSSH2_AGENT *agent);
*/
LIBSSH2_API int
libssh2_agent_get_identity(LIBSSH2_AGENT *agent,
struct libssh2_agent_publickey **store,
struct libssh2_agent_publickey *prev);
struct libssh2_agent_publickey **store,
struct libssh2_agent_publickey *prev);
/*
* libssh2_agent_userauth()
@ -1248,8 +1398,25 @@ libssh2_agent_get_identity(LIBSSH2_AGENT *agent,
*/
LIBSSH2_API int
libssh2_agent_userauth(LIBSSH2_AGENT *agent,
const char *username,
struct libssh2_agent_publickey *identity);
const char *username,
struct libssh2_agent_publickey *identity);
/*
* libssh2_agent_sign()
*
* Sign a payload using a system-installed ssh-agent.
*
* Returns 0 if succeeded, or a negative value for error.
*/
LIBSSH2_API int
libssh2_agent_sign(LIBSSH2_AGENT *agent,
struct libssh2_agent_publickey *identity,
unsigned char **sig,
size_t *s_len,
const unsigned char *data,
size_t d_len,
const char *method,
unsigned int method_len);
/*
* libssh2_agent_disconnect()
@ -1304,7 +1471,7 @@ libssh2_agent_get_identity_path(LIBSSH2_AGENT *agent);
*/
LIBSSH2_API void libssh2_keepalive_config(LIBSSH2_SESSION *session,
int want_reply,
unsigned interval);
unsigned int interval);
/*
* libssh2_keepalive_send()
@ -1322,15 +1489,15 @@ LIBSSH2_API int libssh2_keepalive_send(LIBSSH2_SESSION *session,
enabled
*/
LIBSSH2_API int libssh2_trace(LIBSSH2_SESSION *session, int bitmask);
#define LIBSSH2_TRACE_TRANS (1<<1)
#define LIBSSH2_TRACE_KEX (1<<2)
#define LIBSSH2_TRACE_AUTH (1<<3)
#define LIBSSH2_TRACE_CONN (1<<4)
#define LIBSSH2_TRACE_SCP (1<<5)
#define LIBSSH2_TRACE_SFTP (1<<6)
#define LIBSSH2_TRACE_ERROR (1<<7)
#define LIBSSH2_TRACE_PUBLICKEY (1<<8)
#define LIBSSH2_TRACE_SOCKET (1<<9)
#define LIBSSH2_TRACE_TRANS (1<<1)
#define LIBSSH2_TRACE_KEX (1<<2)
#define LIBSSH2_TRACE_AUTH (1<<3)
#define LIBSSH2_TRACE_CONN (1<<4)
#define LIBSSH2_TRACE_SCP (1<<5)
#define LIBSSH2_TRACE_SFTP (1<<6)
#define LIBSSH2_TRACE_ERROR (1<<7)
#define LIBSSH2_TRACE_PUBLICKEY (1<<8)
#define LIBSSH2_TRACE_SOCKET (1<<9)
typedef void (*libssh2_trace_handler_func)(LIBSSH2_SESSION*,
void *,

View file

@ -1,17 +0,0 @@
###########################################################################
# libssh2 installation details
###########################################################################
prefix=@CMAKE_INSTALL_PREFIX@
exec_prefix=${prefix}
libdir=${prefix}/@CMAKE_INSTALL_LIBDIR@
includedir=${prefix}/@CMAKE_INSTALL_INCLUDEDIR@
Name: @PROJECT_NAME@
URL: @PROJECT_URL@
Description: @PROJECT_DESCRIPTION@
Version: @LIBSSH2_VERSION@
Requires.private: @PC_REQUIRES_PRIVATE@
Libs: -L${libdir} -lssh2 @PC_LIBS@
Libs.private: @PC_LIBS@
Cflags: -I${includedir}

View file

@ -0,0 +1,48 @@
/***************************************************************************
* libssh2 Windows resource file
* Copyright (C) The libssh2 project and its contributors.
*
* SPDX-License-Identifier: BSD-3-Clause
***************************************************************************/
#include <winver.h>
#include "libssh2.h"
LANGUAGE 0, 0
#define RC_VERSION LIBSSH2_VERSION_MAJOR, LIBSSH2_VERSION_MINOR, LIBSSH2_VERSION_PATCH, 0
VS_VERSION_INFO VERSIONINFO
FILEVERSION RC_VERSION
PRODUCTVERSION RC_VERSION
FILEFLAGSMASK VS_FFI_FILEFLAGSMASK
#if defined(LIBSSH2DEBUG) || defined(_DEBUG)
FILEFLAGS VS_FF_DEBUG
#else
FILEFLAGS 0
#endif
FILEOS VOS__WINDOWS32
FILETYPE VFT_DLL
FILESUBTYPE 0
BEGIN
BLOCK "StringFileInfo"
BEGIN
BLOCK "040904b0" /* 0x0409: en-US, 1200/0x04b0: UTF-16LE */
BEGIN
VALUE "CompanyName", "The libssh2 library, https://libssh2.org/\0"
VALUE "FileDescription", "libssh2 Shared Library\0"
VALUE "FileVersion", LIBSSH2_VERSION "\0"
VALUE "InternalName", "libssh2\0"
VALUE "OriginalFilename", "libssh2.dll\0"
VALUE "ProductName", "The libssh2 library\0"
VALUE "ProductVersion", LIBSSH2_VERSION "\0"
VALUE "LegalCopyright", "Copyright (C) " LIBSSH2_COPYRIGHT "\0"
VALUE "License", "https://libssh2.org/license.html\0"
END
END
BLOCK "VarFileInfo"
BEGIN
VALUE "Translation", 0x0409, 0x04b0 /* 0x0409: en-US, 1200/0x04b0: UTF-16LE */
END
END

View file

@ -41,19 +41,10 @@
/* Package information */
#define PACKAGE "Upp::SSH"
#define PACKAGE_BUGREPORT "https://github.com/ultimatepp/ultimatepp/issues"
#define PACKAGE_NAME "Ultimate++ SSH package"
#define PACKAGE_STRING "Ultimate++ SSH package, a libssh2 wrapper, (ver. 2022.2)"
#define PACKAGE_NAME "U++ SSH package"
#define PACKAGE_STRING "U++ SSH package, a libssh2 wrapper, (ver. 2024.1)"
#define PACKAGE_URL "https://github.com/ultimatepp/ultimatepp"
#define PACKAGE_VERSION "2022.2 (libssh2 v.1.10.0)"
/*
OpenSSL version 3.0 deprecated a bunch of api calls.
Until libssh2 adopts the new API calls, we will simply
suppress the deprecation warnings by compiling the library
in compatibility mode.
*/
#define OPENSSL_API_COMPAT 0x10100000L
#define PACKAGE_VERSION "2024.1b (libssh2 v.1.11.1)"
/* Headers */
#define HAVE_INTTYPES_H
@ -99,6 +90,9 @@
/* Let us enable Z compression. */
#define LIBSSH2_HAVE_ZLIB
// enable DSS (this is actually deprecated, but we want to keep bw-compat, until the next release.
#define LIBSSH2_DSA_ENABLE
/* Upp-SSH package uses OpenSSL by default. */
#define LIBSSH2_OPENSSL
@ -190,4 +184,4 @@ static int snprintf(char * cp, int cp_max_len, const char * fmt, ...)
}
#define HAVE_SNPRINTF
#endif
#endif

View file

@ -1,252 +0,0 @@
/* src/libssh2_config.h.in. Generated from configure.ac by autoheader. */
/* Define if building universal (internal helper macro) */
#undef AC_APPLE_UNIVERSAL_BUILD
/* Define to 1 if using 'alloca.c'. */
#undef C_ALLOCA
/* Define to 1 if you have 'alloca', as a function or macro. */
#undef HAVE_ALLOCA
/* Define to 1 if <alloca.h> works. */
#undef HAVE_ALLOCA_H
/* Define to 1 if you have the <arpa/inet.h> header file. */
#undef HAVE_ARPA_INET_H
/* Define to 1 if you have the declaration of `SecureZeroMemory', and to 0 if
you don't. */
#undef HAVE_DECL_SECUREZEROMEMORY
/* disabled non-blocking sockets */
#undef HAVE_DISABLED_NONBLOCKING
/* Define to 1 if you have the <dlfcn.h> header file. */
#undef HAVE_DLFCN_H
/* Define to 1 if you have the <errno.h> header file. */
#undef HAVE_ERRNO_H
/* Define to 1 if you have the `EVP_aes_128_ctr' function. */
#undef HAVE_EVP_AES_128_CTR
/* Define to 1 if you have the <fcntl.h> header file. */
#undef HAVE_FCNTL_H
/* use FIONBIO for non-blocking sockets */
#undef HAVE_FIONBIO
/* Define to 1 if you have the `gettimeofday' function. */
#undef HAVE_GETTIMEOFDAY
/* Define to 1 if you have the <inttypes.h> header file. */
#undef HAVE_INTTYPES_H
/* use ioctlsocket() for non-blocking sockets */
#undef HAVE_IOCTLSOCKET
/* use Ioctlsocket() for non-blocking sockets */
#undef HAVE_IOCTLSOCKET_CASE
/* Define if you have the bcrypt library. */
#undef HAVE_LIBBCRYPT
/* Define if you have the crypt32 library. */
#undef HAVE_LIBCRYPT32
/* Define if you have the gcrypt library. */
#undef HAVE_LIBGCRYPT
/* Define if you have the mbedcrypto library. */
#undef HAVE_LIBMBEDCRYPTO
/* Define if you have the ssl library. */
#undef HAVE_LIBSSL
/* Define if you have the z library. */
#undef HAVE_LIBZ
/* Define to 1 if the compiler supports the 'long long' data type. */
#undef HAVE_LONGLONG
/* Define to 1 if you have the `memset_s' function. */
#undef HAVE_MEMSET_S
/* Define to 1 if you have the <netinet/in.h> header file. */
#undef HAVE_NETINET_IN_H
/* Define to 1 if you have the <ntdef.h> header file. */
#undef HAVE_NTDEF_H
/* Define to 1 if you have the <ntstatus.h> header file. */
#undef HAVE_NTSTATUS_H
/* use O_NONBLOCK for non-blocking sockets */
#undef HAVE_O_NONBLOCK
/* Define to 1 if you have the `poll' function. */
#undef HAVE_POLL
/* Define to 1 if you have the select function. */
#undef HAVE_SELECT
/* use SO_NONBLOCK for non-blocking sockets */
#undef HAVE_SO_NONBLOCK
/* Define to 1 if you have the <stdint.h> header file. */
#undef HAVE_STDINT_H
/* Define to 1 if you have the <stdio.h> header file. */
#undef HAVE_STDIO_H
/* Define to 1 if you have the <stdlib.h> header file. */
#undef HAVE_STDLIB_H
/* Define to 1 if you have the <strings.h> header file. */
#undef HAVE_STRINGS_H
/* Define to 1 if you have the <string.h> header file. */
#undef HAVE_STRING_H
/* Define to 1 if you have the `strtoll' function. */
#undef HAVE_STRTOLL
/* Define to 1 if you have the <sys/ioctl.h> header file. */
#undef HAVE_SYS_IOCTL_H
/* Define to 1 if you have the <sys/select.h> header file. */
#undef HAVE_SYS_SELECT_H
/* Define to 1 if you have the <sys/socket.h> header file. */
#undef HAVE_SYS_SOCKET_H
/* Define to 1 if you have the <sys/stat.h> header file. */
#undef HAVE_SYS_STAT_H
/* Define to 1 if you have the <sys/time.h> header file. */
#undef HAVE_SYS_TIME_H
/* Define to 1 if you have the <sys/types.h> header file. */
#undef HAVE_SYS_TYPES_H
/* Define to 1 if you have the <sys/uio.h> header file. */
#undef HAVE_SYS_UIO_H
/* Define to 1 if you have the <sys/un.h> header file. */
#undef HAVE_SYS_UN_H
/* Define to 1 if you have the <unistd.h> header file. */
#undef HAVE_UNISTD_H
/* Define to 1 if you have the <windows.h> header file. */
#undef HAVE_WINDOWS_H
/* Define to 1 if you have the <winsock2.h> header file. */
#undef HAVE_WINSOCK2_H
/* Define to 1 if you have the <ws2tcpip.h> header file. */
#undef HAVE_WS2TCPIP_H
/* to make a symbol visible */
#undef LIBSSH2_API
/* Enable clearing of memory before being freed */
#undef LIBSSH2_CLEAR_MEMORY
/* Enable "none" cipher -- NOT RECOMMENDED */
#undef LIBSSH2_CRYPT_NONE
/* Enable newer diffie-hellman-group-exchange-sha1 syntax */
#undef LIBSSH2_DH_GEX_NEW
/* Compile in zlib support */
#undef LIBSSH2_HAVE_ZLIB
/* Use libgcrypt */
#undef LIBSSH2_LIBGCRYPT
/* Enable "none" MAC -- NOT RECOMMENDED */
#undef LIBSSH2_MAC_NONE
/* Use mbedtls */
#undef LIBSSH2_MBEDTLS
/* Use openssl */
#undef LIBSSH2_OPENSSL
/* Use wincng */
#undef LIBSSH2_WINCNG
/* Define to the sub-directory where libtool stores uninstalled libraries. */
#undef LT_OBJDIR
/* Define to 1 if _REENTRANT preprocessor symbol must be defined. */
#undef NEED_REENTRANT
/* Name of package */
#undef PACKAGE
/* Define to the address where bug reports for this package should be sent. */
#undef PACKAGE_BUGREPORT
/* Define to the full name of this package. */
#undef PACKAGE_NAME
/* Define to the full name and version of this package. */
#undef PACKAGE_STRING
/* Define to the one symbol short name of this package. */
#undef PACKAGE_TARNAME
/* Define to the home page for this package. */
#undef PACKAGE_URL
/* Define to the version of this package. */
#undef PACKAGE_VERSION
/* If using the C implementation of alloca, define if you know the
direction of stack growth for your system; otherwise it will be
automatically deduced at runtime.
STACK_DIRECTION > 0 => grows toward higher addresses
STACK_DIRECTION < 0 => grows toward lower addresses
STACK_DIRECTION = 0 => direction of growth unknown */
#undef STACK_DIRECTION
/* 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 */
#undef VERSION
/* Define WORDS_BIGENDIAN to 1 if your processor stores words with the most
significant byte first (like Motorola and SPARC, unlike Intel). */
#if defined AC_APPLE_UNIVERSAL_BUILD
# if defined __BIG_ENDIAN__
# define WORDS_BIGENDIAN 1
# endif
#else
# ifndef WORDS_BIGENDIAN
# undef WORDS_BIGENDIAN
# endif
#endif
/* Number of bits in a file offset, on hosts where this is settable. */
#undef _FILE_OFFSET_BITS
/* Define for large files, on AIX-style hosts. */
#undef _LARGE_FILES
/* Define to empty if `const' does not conform to ANSI C. */
#undef const
/* Define to `__inline__' or `__inline' if that's what the C compiler
calls it, or to nothing if 'inline' is not supported under any name. */
#ifndef __cplusplus
#undef inline
#endif
/* Define to `unsigned int' if <sys/types.h> does not define. */
#undef size_t

View file

@ -1,5 +1,6 @@
/* Copyright (c) 2014 Alexander Lamaison <alexander.lamaison@gmail.com>
* Copyright (c) 1999-2011 Douglas Gilbert. All rights reserved.
/* Copyright (C) Alexander Lamaison <alexander.lamaison@gmail.com>
* Copyright (C) Douglas Gilbert
* All rights reserved.
*
* Redistribution and use in source and binary forms,
* with or without modification, are permitted provided
@ -33,73 +34,43 @@
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
* USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
* OF SUCH DAMAGE.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
/* Headers */
#cmakedefine HAVE_UNISTD_H
#cmakedefine HAVE_INTTYPES_H
#cmakedefine HAVE_STDLIB_H
#cmakedefine HAVE_SYS_SELECT_H
#cmakedefine HAVE_SYS_UIO_H
#cmakedefine HAVE_SYS_SOCKET_H
#cmakedefine HAVE_SYS_IOCTL_H
#cmakedefine HAVE_SYS_TIME_H
#cmakedefine HAVE_SYS_UN_H
#cmakedefine HAVE_WINDOWS_H
#cmakedefine HAVE_WS2TCPIP_H
#cmakedefine HAVE_WINSOCK2_H
#cmakedefine HAVE_NTDEF_H
#cmakedefine HAVE_NTSTATUS_H
/* Libraries */
#cmakedefine HAVE_LIBCRYPT32
/* Types */
#cmakedefine HAVE_LONGLONG
/* for example and tests */
#cmakedefine HAVE_ARPA_INET_H
#cmakedefine HAVE_NETINET_IN_H
/* Functions */
#cmakedefine HAVE_GETTIMEOFDAY
#cmakedefine HAVE_INET_ADDR
#cmakedefine HAVE_POLL
#cmakedefine HAVE_SELECT
#cmakedefine HAVE_SOCKET
#cmakedefine HAVE_STRTOLL
#cmakedefine HAVE_STRTOI64
#cmakedefine HAVE_SNPRINTF
#cmakedefine HAVE_EXPLICIT_BZERO
#cmakedefine HAVE_EXPLICIT_MEMSET
#cmakedefine HAVE_MEMSET_S
/* OpenSSL functions */
#cmakedefine HAVE_EVP_AES_128_CTR
#cmakedefine HAVE_POLL
#cmakedefine HAVE_SELECT
/* Socket non-blocking support */
#cmakedefine HAVE_O_NONBLOCK
#cmakedefine HAVE_FIONBIO
#cmakedefine HAVE_IOCTLSOCKET
#cmakedefine HAVE_IOCTLSOCKET_CASE
#cmakedefine HAVE_SO_NONBLOCK
#cmakedefine HAVE_DISABLED_NONBLOCKING
/* snprintf not in Visual Studio CRT and _snprintf dangerously incompatible.
We provide a safe wrapper if snprintf not found */
#ifndef HAVE_SNPRINTF
#include <stdio.h>
#include <stdarg.h>
/* Want safe, 'n += snprintf(b + n ...)' like function. If cp_max_len is 1
* then assume cp is pointing to a null char and do nothing. Returns number
* number of chars placed in cp excluding the trailing null char. So for
* cp_max_len > 0 the return value is always < cp_max_len; for cp_max_len
* <= 0 the return value is 0 (and no chars are written to cp). */
static int snprintf(char * cp, int cp_max_len, const char * fmt, ...)
{
va_list args;
int n;
if (cp_max_len < 2)
return 0;
va_start(args, fmt);
n = vsnprintf(cp, cp_max_len, fmt, args);
va_end(args);
return (n < cp_max_len) ? n : (cp_max_len - 1);
}
#define HAVE_SNPRINTF
/* attribute to export symbol */
#if defined(LIBSSH2_EXPORTS) && defined(LIBSSH2_LIBRARY)
#cmakedefine LIBSSH2_API ${LIBSSH2_API}
#endif

View file

@ -1,8 +1,8 @@
#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
#ifndef LIBSSH2_PRIV_H
#define LIBSSH2_PRIV_H
/* Copyright (C) Sara Golemon <sarag@libssh2.org>
* Copyright (C) Daniel Stenberg
* Copyright (C) Simon Josefsson
* All rights reserved.
*
* Redistribution and use in source and binary forms,
@ -37,25 +37,28 @@
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
* USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
* OF SUCH DAMAGE.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
/* Header used by 'src' and 'tests' */
/* FIXME: Disable warnings for 'src' */
#if !defined(LIBSSH2_TESTS) && !defined(LIBSSH2_WARN_SIGN_CONVERSION)
#ifdef __GNUC__
#pragma GCC diagnostic ignored "-Wsign-conversion"
#endif
#endif
#define LIBSSH2_LIBRARY
#include "libssh2_config.h"
#ifdef HAVE_WINDOWS_H
#ifndef WIN32_LEAN_AND_MEAN
#define WIN32_LEAN_AND_MEAN
#endif
#include <windows.h>
#undef WIN32_LEAN_AND_MEAN
#endif
#ifdef HAVE_WS2TCPIP_H
#include <ws2tcpip.h>
#endif
/* platform/compiler-specific setup */
#include "libssh2_setup.h"
#include <stdio.h>
#include <string.h>
#include <time.h>
#include <limits.h>
/* The following CPP block should really only be in session.c and packet.c.
However, AIX have #define's for 'events' and 'revents' and we are using
@ -66,15 +69,8 @@
*/
#ifdef HAVE_POLL
# include <poll.h>
#else
# if defined(HAVE_SELECT) && !defined(WIN32)
# ifdef HAVE_SYS_SELECT_H
#elif defined(HAVE_SELECT) && defined(HAVE_SYS_SELECT_H)
# include <sys/select.h>
# else
# include <sys/time.h>
# include <sys/types.h>
# endif
# endif
#endif
/* Needed for struct iovec on some platforms */
@ -83,10 +79,10 @@
#endif
#ifdef HAVE_SYS_SOCKET_H
# include <sys/socket.h>
#include <sys/socket.h>
#endif
#ifdef HAVE_SYS_IOCTL_H
# include <sys/ioctl.h>
#include <sys/ioctl.h>
#endif
#ifdef HAVE_INTTYPES_H
#include <inttypes.h>
@ -95,7 +91,20 @@
#include "libssh2.h"
#include "libssh2_publickey.h"
#include "libssh2_sftp.h"
#include "misc.h" /* for the linked list stuff */
#include "misc.h"
#ifdef _WIN32
/* Detect Windows App environment which has a restricted access
to the Win32 APIs. */
# if (defined(_WIN32_WINNT) && (_WIN32_WINNT >= 0x0602)) || \
defined(WINAPI_FAMILY)
# include <winapifamily.h>
# if WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_APP) && \
!WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP)
# define LIBSSH2_WINDOWS_UWP
# endif
# endif
#endif
#ifndef FALSE
#define FALSE 0
@ -104,13 +113,64 @@
#define TRUE 1
#endif
#ifdef _MSC_VER
#ifndef UINT32_MAX
#define UINT32_MAX 0xffffffffU
#endif
#if (defined(__GNUC__) || defined(__clang__)) && \
defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L) && \
!defined(LIBSSH2_NO_FMT_CHECKS)
#ifdef __MINGW_PRINTF_FORMAT
#define LIBSSH2_PRINTF(fmt, arg) \
__attribute__((format(__MINGW_PRINTF_FORMAT, fmt, arg)))
#elif !defined(__MINGW32__)
#define LIBSSH2_PRINTF(fmt, arg) \
__attribute__((format(printf, fmt, arg)))
#endif
#endif
#ifndef LIBSSH2_PRINTF
#define LIBSSH2_PRINTF(fmt, arg)
#endif
/* Use local implementation when not available */
#if !defined(HAVE_SNPRINTF)
#undef snprintf
#define snprintf _libssh2_snprintf
#define LIBSSH2_SNPRINTF
int _libssh2_snprintf(char *cp, size_t cp_max_len, const char *fmt, ...)
LIBSSH2_PRINTF(3, 4);
#endif
#if !defined(HAVE_GETTIMEOFDAY)
#define HAVE_GETTIMEOFDAY
#undef gettimeofday
#define gettimeofday _libssh2_gettimeofday
#define LIBSSH2_GETTIMEOFDAY
int _libssh2_gettimeofday(struct timeval *tp, void *tzp);
#elif defined(HAVE_SYS_TIME_H)
#include <sys/time.h>
#endif
#if !defined(LIBSSH2_FALLTHROUGH)
#if (defined(__GNUC__) && __GNUC__ >= 7) || \
(defined(__clang__) && __clang_major__ >= 10)
# define LIBSSH2_FALLTHROUGH() __attribute__((fallthrough))
#else
# define LIBSSH2_FALLTHROUGH() do {} while (0)
#endif
#endif
/* "inline" keyword is valid only with C++ engine! */
#ifdef __GNUC__
#undef inline
#define inline __inline__
#elif defined(_MSC_VER)
#undef inline
#define inline __inline
#endif
/* 3DS doesn't seem to have iovec */
#if defined(WIN32) || defined(_3DS)
#if defined(_WIN32) || defined(_3DS)
struct iovec {
size_t iov_len;
@ -119,20 +179,6 @@ struct iovec {
#endif
/* Provide iovec / writev on WIN32 platform. */
#ifdef WIN32
static inline int writev(int sock, struct iovec *iov, int nvecs)
{
DWORD ret;
if(WSASend(sock, (LPWSABUF)iov, nvecs, &ret, 0, NULL, NULL) == 0) {
return ret;
}
return -1;
}
#endif /* WIN32 */
#ifdef __OS400__
/* Force parameter type. */
#define send(s, b, l, f) send((s), (unsigned char *) (b), (l), (f))
@ -140,13 +186,6 @@ static inline int writev(int sock, struct iovec *iov, int nvecs)
#include "crypto.h"
#ifdef HAVE_WINSOCK2_H
#include <winsock2.h>
#include <ws2tcpip.h>
#endif
#ifndef SIZE_MAX
#if _WIN64
#define SIZE_MAX 0xFFFFFFFFFFFFFFFF
@ -159,6 +198,12 @@ static inline int writev(int sock, struct iovec *iov, int nvecs)
#define UINT_MAX 0xFFFFFFFF
#endif
#define LIBSSH2_MAX(x, y) ((x) > (y) ? (x) : (y))
#define LIBSSH2_MIN(x, y) ((x) < (y) ? (x) : (y))
#define MAX_BLOCKSIZE 32 /* MUST fit biggest crypto block size we use/get */
#define MAX_MACSIZE 64 /* MUST fit biggest MAC length we support */
/* RFC4253 section 6.1 Maximum Packet Length says:
*
* "All implementations MUST be able to process packets with
@ -170,33 +215,51 @@ static inline int writev(int sock, struct iovec *iov, int nvecs)
#define MAX_SHA_DIGEST_LEN SHA512_DIGEST_LENGTH
#define LIBSSH2_ALLOC(session, count) \
session->alloc((count), &(session)->abstract)
session->alloc((count), &(session)->abstract)
#define LIBSSH2_CALLOC(session, count) _libssh2_calloc(session, count)
#define LIBSSH2_REALLOC(session, ptr, count) \
((ptr) ? session->realloc((ptr), (count), &(session)->abstract) : \
session->alloc((count), &(session)->abstract))
((ptr) ? session->realloc((ptr), (count), &(session)->abstract) : \
session->alloc((count), &(session)->abstract))
#define LIBSSH2_FREE(session, ptr) \
session->free((ptr), &(session)->abstract)
session->free((ptr), &(session)->abstract)
#define LIBSSH2_IGNORE(session, data, datalen) \
session->ssh_msg_ignore((session), (data), (datalen), &(session)->abstract)
session->ssh_msg_ignore((session), (data), (int)(datalen), \
&(session)->abstract)
#define LIBSSH2_DEBUG(session, always_display, message, message_len, \
language, language_len) \
session->ssh_msg_debug((session), (always_display), (message), \
(message_len), (language), (language_len), \
language, language_len) \
session->ssh_msg_debug((session), (always_display), \
(message), (int)(message_len), \
(language), (int)(language_len), \
&(session)->abstract)
#define LIBSSH2_DISCONNECT(session, reason, message, message_len, \
language, language_len) \
session->ssh_msg_disconnect((session), (reason), (message), \
(message_len), (language), (language_len), \
language, language_len) \
session->ssh_msg_disconnect((session), (reason), \
(message), (int)(message_len), \
(language), (int)(language_len), \
&(session)->abstract)
#define LIBSSH2_MACERROR(session, data, datalen) \
session->macerror((session), (data), (datalen), &(session)->abstract)
#define LIBSSH2_X11_OPEN(channel, shost, sport) \
#define LIBSSH2_MACERROR(session, data, datalen) \
session->macerror((session), (data), (int)(datalen), &(session)->abstract)
#define LIBSSH2_X11_OPEN(channel, shost, sport) \
channel->session->x11(((channel)->session), (channel), \
(shost), (sport), (&(channel)->session->abstract))
#define LIBSSH2_CHANNEL_CLOSE(session, channel) \
#define LIBSSH2_AUTHAGENT(channel) \
channel->session->authagent(((channel)->session), (channel), \
(&(channel)->session->abstract))
#define LIBSSH2_ADD_IDENTITIES(session, buffer, agentPath) \
session->addLocalIdentities((session), (buffer), \
(agentPath), (&(session->abstract)))
#define LIBSSH2_AUTHAGENT_SIGN(session, blob, blen, \
data, dlen, sig, sigLen, \
agentPath) \
session->agentSignCallback((session), (blob), (blen), \
(data), (dlen), (sig), (sigLen), \
(agentPath), (&(session->abstract)))
#define LIBSSH2_CHANNEL_CLOSE(session, channel) \
channel->close_cb((session), &(session)->abstract, \
(channel), &(channel)->abstract)
@ -205,9 +268,9 @@ static inline int writev(int sock, struct iovec *iov, int nvecs)
#define LIBSSH2_RECV_FD(session, fd, buffer, length, flags) \
(session->recv)(fd, buffer, length, flags, &session->abstract)
#define LIBSSH2_SEND(session, buffer, length, flags) \
#define LIBSSH2_SEND(session, buffer, length, flags) \
LIBSSH2_SEND_FD(session, session->socket_fd, buffer, length, flags)
#define LIBSSH2_RECV(session, buffer, length, flags) \
#define LIBSSH2_RECV(session, buffer, length, flags) \
LIBSSH2_RECV_FD(session, session->socket_fd, buffer, length, flags)
typedef struct _LIBSSH2_KEX_METHOD LIBSSH2_KEX_METHOD;
@ -235,7 +298,9 @@ typedef enum
libssh2_NB_state_jump3,
libssh2_NB_state_jump4,
libssh2_NB_state_jump5,
libssh2_NB_state_end
libssh2_NB_state_error_closing,
libssh2_NB_state_end,
libssh2_NB_state_jumpauthagent
} libssh2_nonblocking_states;
typedef struct packet_require_state_t
@ -341,6 +406,18 @@ typedef struct packet_x11_open_state_t
LIBSSH2_CHANNEL *channel;
} packet_x11_open_state_t;
#define AuthAgentUnavail "Auth Agent unavailable"
typedef struct packet_authagent_state_t
{
libssh2_nonblocking_states state;
unsigned char packet[17 + (sizeof(AuthAgentUnavail) - 1)];
uint32_t sender_channel;
uint32_t initial_window_size;
uint32_t packet_size;
LIBSSH2_CHANNEL *channel;
} packet_authagent_state_t;
struct _LIBSSH2_PACKET
{
struct list_node node; /* linked list header */
@ -371,7 +448,7 @@ struct _LIBSSH2_CHANNEL
struct list_node node;
unsigned char *channel_type;
unsigned channel_type_len;
size_t channel_type_len;
/* channel's program exit status */
int exit_status;
@ -383,7 +460,7 @@ struct _LIBSSH2_CHANNEL
/* Amount of bytes to be refunded to receive window (but not yet sent) */
uint32_t adjust_queue;
/* Data immediately available for reading */
uint32_t read_avail;
size_t read_avail;
LIBSSH2_SESSION *session;
@ -424,7 +501,7 @@ struct _LIBSSH2_CHANNEL
size_t flush_refund_bytes;
size_t flush_flush_bytes;
/* State variables used in libssh2_channel_receive_window_adjust() */
/* State variables used in libssh2_channel_receive_window_adjust2() */
libssh2_nonblocking_states adjust_state;
unsigned char adjust_adjust[9]; /* packet_type(1) + channel(4) +
adjustment(4) */
@ -463,6 +540,11 @@ struct _LIBSSH2_CHANNEL
size_t req_auth_agent_packet_len;
unsigned char req_auth_agent_local_channel[4];
packet_requirev_state_t req_auth_agent_requirev_state;
/* State variables used in libssh2_channel_signal_ex() */
libssh2_nonblocking_states sendsignal_state;
unsigned char *sendsignal_packet;
size_t sendsignal_packet_len;
};
struct _LIBSSH2_LISTENER
@ -510,7 +592,7 @@ typedef struct _libssh2_endpoint_data
char *lang_prefs;
} libssh2_endpoint_data;
#define PACKETBUFSIZE (1024*16)
#define PACKETBUFSIZE MAX_SSH_PACKET_LEN
struct transportpacket
{
@ -533,14 +615,15 @@ struct transportpacket
packet_length + padding_length + 4 +
mac_length. */
unsigned char *payload; /* this is a pointer to a LIBSSH2_ALLOC()
area to which we write decrypted data */
area to which we write incoming packet data
which is not yet decrypted in etm mode. */
unsigned char *wptr; /* write pointer into the payload to where we
are currently writing decrypted data */
/* ------------- for outgoing data --------------- */
unsigned char outbuf[MAX_SSH_PACKET_LEN]; /* area for the outgoing data */
int ototal_num; /* size of outbuf in number of bytes */
ssize_t ototal_num; /* size of outbuf in number of bytes */
const unsigned char *odata; /* original pointer to the data */
size_t olen; /* original size of the data we stored in
outbuf */
@ -578,26 +661,31 @@ struct _LIBSSH2_PUBLICKEY
#define LIBSSH2_SCP_RESPONSE_BUFLEN 256
struct flags {
int sigpipe; /* LIBSSH2_FLAG_SIGPIPE */
int compress; /* LIBSSH2_FLAG_COMPRESS */
int sigpipe; /* LIBSSH2_FLAG_SIGPIPE */
int compress; /* LIBSSH2_FLAG_COMPRESS */
int quote_paths; /* LIBSSH2_FLAG_QUOTE_PATHS */
};
struct _LIBSSH2_SESSION
{
/* Memory management callbacks */
void *abstract;
LIBSSH2_ALLOC_FUNC((*alloc));
LIBSSH2_REALLOC_FUNC((*realloc));
LIBSSH2_FREE_FUNC((*free));
LIBSSH2_ALLOC_FUNC((*alloc));
LIBSSH2_REALLOC_FUNC((*realloc));
LIBSSH2_FREE_FUNC((*free));
/* Other callbacks */
LIBSSH2_IGNORE_FUNC((*ssh_msg_ignore));
LIBSSH2_DEBUG_FUNC((*ssh_msg_debug));
LIBSSH2_DISCONNECT_FUNC((*ssh_msg_disconnect));
LIBSSH2_MACERROR_FUNC((*macerror));
LIBSSH2_X11_OPEN_FUNC((*x11));
LIBSSH2_SEND_FUNC((*send));
LIBSSH2_RECV_FUNC((*recv));
LIBSSH2_IGNORE_FUNC((*ssh_msg_ignore));
LIBSSH2_DEBUG_FUNC((*ssh_msg_debug));
LIBSSH2_DISCONNECT_FUNC((*ssh_msg_disconnect));
LIBSSH2_MACERROR_FUNC((*macerror));
LIBSSH2_X11_OPEN_FUNC((*x11));
LIBSSH2_AUTHAGENT_FUNC((*authagent));
LIBSSH2_ADD_IDENTITIES_FUNC((*addLocalIdentities));
LIBSSH2_AUTHAGENT_SIGN_FUNC((*agentSignCallback));
LIBSSH2_SEND_FUNC((*send));
LIBSSH2_RECV_FUNC((*recv));
/* Method preferences -- NULL yields "load order" */
char *kex_prefs;
@ -610,7 +698,7 @@ struct _LIBSSH2_SESSION
/* Agreed Key Exchange Method */
const LIBSSH2_KEX_METHOD *kex;
unsigned int burn_optimistic_kexinit:1;
unsigned int burn_optimistic_kexinit;
unsigned char *session_id;
uint32_t session_id_len;
@ -633,13 +721,22 @@ struct _LIBSSH2_SESSION
#if LIBSSH2_MD5
unsigned char server_hostkey_md5[MD5_DIGEST_LENGTH];
int server_hostkey_md5_valid;
#endif /* ! LIBSSH2_MD5 */
#endif /* ! LIBSSH2_MD5 */
unsigned char server_hostkey_sha1[SHA_DIGEST_LENGTH];
int server_hostkey_sha1_valid;
unsigned char server_hostkey_sha256[SHA256_DIGEST_LENGTH];
int server_hostkey_sha256_valid;
/* public key algorithms accepted as comma separated list */
char *server_sign_algorithms;
/* key signing algorithm preferences -- NULL yields server order */
char *sign_algo_prefs;
/* Whether to use the OpenSSH Strict KEX extension */
int kex_strict;
/* (remote as source of data -- packet_read ) */
libssh2_endpoint_data remote;
@ -662,7 +759,8 @@ struct _LIBSSH2_SESSION
int socket_state;
int socket_block_directions;
int socket_prev_blockstate; /* stores the state of the socket blockiness
when libssh2_session_startup() is called */
when libssh2_session_handshake()
is called */
/* Error tracking */
const char *err_msg;
@ -680,7 +778,7 @@ struct _LIBSSH2_SESSION
/* State variables used in libssh2_banner_send() */
libssh2_nonblocking_states banner_TxRx_state;
char banner_TxRx_banner[256];
char banner_TxRx_banner[8192];
ssize_t banner_TxRx_total_send;
/* State variables used in libssh2_kexinit() */
@ -688,7 +786,7 @@ struct _LIBSSH2_SESSION
unsigned char *kexinit_data;
size_t kexinit_data_len;
/* State variables used in libssh2_session_startup() */
/* State variables used in libssh2_session_handshake() */
libssh2_nonblocking_states startup_state;
unsigned char *startup_data;
size_t startup_data_len;
@ -713,6 +811,7 @@ struct _LIBSSH2_SESSION
libssh2_nonblocking_states userauth_list_state;
unsigned char *userauth_list_data;
size_t userauth_list_data_len;
char *userauth_banner;
packet_requirev_state_t userauth_list_packet_requirev_state;
/* State variables used in libssh2_userauth_password_ex() */
@ -753,10 +852,10 @@ struct _LIBSSH2_SESSION
size_t userauth_kybd_data_len;
unsigned char *userauth_kybd_packet;
size_t userauth_kybd_packet_len;
unsigned int userauth_kybd_auth_name_len;
char *userauth_kybd_auth_name;
unsigned userauth_kybd_auth_instruction_len;
char *userauth_kybd_auth_instruction;
size_t userauth_kybd_auth_name_len;
unsigned char *userauth_kybd_auth_name;
size_t userauth_kybd_auth_instruction_len;
unsigned char *userauth_kybd_auth_instruction;
unsigned int userauth_kybd_num_prompts;
int userauth_kybd_auth_failure;
LIBSSH2_USERAUTH_KBDINT_PROMPT *userauth_kybd_prompts;
@ -803,12 +902,14 @@ struct _LIBSSH2_SESSION
states */
packet_queue_listener_state_t packAdd_Qlstn_state;
packet_x11_open_state_t packAdd_x11open_state;
packet_authagent_state_t packAdd_authagent_state;
/* State variables used in fullpacket() */
libssh2_nonblocking_states fullpacket_state;
int fullpacket_macstate;
size_t fullpacket_payload_len;
int fullpacket_packet_type;
uint32_t fullpacket_required_type;
/* State variables used in libssh2_sftp_init() */
libssh2_nonblocking_states sftpInit_state;
@ -816,27 +917,17 @@ struct _LIBSSH2_SESSION
LIBSSH2_CHANNEL *sftpInit_channel;
unsigned char sftpInit_buffer[9]; /* sftp_header(5){excludes request_id}
+ version_id(4) */
int sftpInit_sent; /* number of bytes from the buffer that have been
sent */
size_t sftpInit_sent; /* number of bytes from the buffer that have been
sent */
/* State variables used in libssh2_scp_recv() / libssh_scp_recv2() */
/* State variables used in libssh2_scp_recv2() */
libssh2_nonblocking_states scpRecv_state;
unsigned char *scpRecv_command;
size_t scpRecv_command_len;
unsigned char scpRecv_response[LIBSSH2_SCP_RESPONSE_BUFLEN];
size_t scpRecv_response_len;
long scpRecv_mode;
#if defined(HAVE_LONGLONG) && defined(HAVE_STRTOLL)
/* we have the type and we can parse such numbers */
long long scpRecv_size;
#define scpsize_strtol strtoll
#elif defined(HAVE_STRTOI64)
__int64 scpRecv_size;
#define scpsize_strtol _strtoi64
#else
long scpRecv_size;
#define scpsize_strtol strtol
#endif
libssh2_int64_t scpRecv_size;
long scpRecv_mtime;
long scpRecv_atime;
LIBSSH2_CHANNEL *scpRecv_channel;
@ -853,19 +944,23 @@ struct _LIBSSH2_SESSION
int keepalive_interval;
int keepalive_want_reply;
time_t keepalive_last_sent;
/* Configurable timeout for packets. Replaces LIBSSH2_READ_TIMEOUT */
long packet_read_timeout;
};
/* session.state bits */
#define LIBSSH2_STATE_EXCHANGING_KEYS 0x00000001
#define LIBSSH2_STATE_NEWKEYS 0x00000002
#define LIBSSH2_STATE_AUTHENTICATED 0x00000004
#define LIBSSH2_STATE_KEX_ACTIVE 0x00000008
#define LIBSSH2_STATE_INITIAL_KEX 0x00000001
#define LIBSSH2_STATE_EXCHANGING_KEYS 0x00000002
#define LIBSSH2_STATE_NEWKEYS 0x00000004
#define LIBSSH2_STATE_AUTHENTICATED 0x00000008
#define LIBSSH2_STATE_KEX_ACTIVE 0x00000010
/* session.flag helpers */
#ifdef MSG_NOSIGNAL
#define LIBSSH2_SOCKET_SEND_FLAGS(session) \
#define LIBSSH2_SOCKET_SEND_FLAGS(session) \
(((session)->flag.sigpipe) ? 0 : MSG_NOSIGNAL)
#define LIBSSH2_SOCKET_RECV_FLAGS(session) \
#define LIBSSH2_SOCKET_RECV_FLAGS(session) \
(((session)->flag.sigpipe) ? 0 : MSG_NOSIGNAL)
#else
/* If MSG_NOSIGNAL isn't defined we're SOL on blocking SIGPIPE */
@ -887,13 +982,16 @@ struct _LIBSSH2_KEX_METHOD
int (*exchange_keys) (LIBSSH2_SESSION * session,
key_exchange_state_low_t * key_state);
void (*cleanup) (LIBSSH2_SESSION * session,
key_exchange_state_low_t * key_state);
long flags;
};
struct _LIBSSH2_HOSTKEY_METHOD
{
const char *name;
unsigned long hash_len;
size_t hash_len;
int (*init) (LIBSSH2_SESSION * session, const unsigned char *hostkey_data,
size_t hostkey_data_len, void **abstract);
@ -927,19 +1025,52 @@ struct _LIBSSH2_CRYPT_METHOD
int iv_len;
int secret_len;
/* length of the authentication tag */
int auth_len;
long flags;
int (*init) (LIBSSH2_SESSION * session,
const LIBSSH2_CRYPT_METHOD * method, unsigned char *iv,
int *free_iv, unsigned char *secret, int *free_secret,
int encrypt, void **abstract);
int (*crypt) (LIBSSH2_SESSION * session, unsigned char *block,
size_t blocksize, void **abstract);
int (*get_len) (LIBSSH2_SESSION * session, unsigned int seqno,
unsigned char *data, size_t data_size, unsigned int *len,
void **abstract);
int (*crypt) (LIBSSH2_SESSION * session, unsigned int seqno,
unsigned char *block, size_t blocksize, void **abstract,
int firstlast);
int (*dtor) (LIBSSH2_SESSION * session, void **abstract);
_libssh2_cipher_type(algo);
_libssh2_cipher_type(algo);
};
/* Bit flags for _LIBSSH2_CRYPT_METHOD */
/* Crypto method has integrated message authentication */
#define LIBSSH2_CRYPT_FLAG_INTEGRATED_MAC 1
/* Crypto method does not encrypt the packet length */
#define LIBSSH2_CRYPT_FLAG_PKTLEN_AAD 2
/* Crypto method must encrypt and decrypt entire messages */
#define LIBSSH2_CRYPT_FLAG_REQUIRES_FULL_PACKET 4
/* Convenience macros for accessing crypt flags */
/* Local crypto flags */
#define CRYPT_FLAG_L(session, flag) ((session)->local.crypt && \
((session)->local.crypt->flags & LIBSSH2_CRYPT_FLAG_##flag))
/* Remote crypto flags */
#define CRYPT_FLAG_R(session, flag) ((session)->remote.crypt && \
((session)->remote.crypt->flags & LIBSSH2_CRYPT_FLAG_##flag))
/* Values for firstlast */
#define FIRST_BLOCK 1
#define MIDDLE_BLOCK 0
#define LAST_BLOCK 2
/* Convenience macros for accessing firstlast */
#define IS_FIRST(firstlast) (firstlast & FIRST_BLOCK)
#define IS_LAST(firstlast) (firstlast & LAST_BLOCK)
struct _LIBSSH2_COMP_METHOD
{
const char *name;
@ -963,23 +1094,12 @@ struct _LIBSSH2_COMP_METHOD
};
#ifdef LIBSSH2DEBUG
void _libssh2_debug(LIBSSH2_SESSION * session, int context, const char *format,
...);
void
_libssh2_debug_low(LIBSSH2_SESSION * session, int context, const char *format,
...) LIBSSH2_PRINTF(3, 4);
#define _libssh2_debug(x) _libssh2_debug_low x
#else
#if (defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L)) || \
defined(__GNUC__)
/* C99 supported and also by older GCC */
#define _libssh2_debug(x,y,z,...) do {} while (0)
#else
/* no gcc and not C99, do static and hopefully inline */
static inline void
_libssh2_debug(LIBSSH2_SESSION * session, int context, const char *format, ...)
{
(void)session;
(void)context;
(void)format;
}
#endif
#define _libssh2_debug(x) do {} while(0)
#endif
#define LIBSSH2_SOCKET_UNKNOWN 1
@ -1006,6 +1126,7 @@ _libssh2_debug(LIBSSH2_SESSION * session, int context, const char *format, ...)
#define SSH_MSG_DEBUG 4
#define SSH_MSG_SERVICE_REQUEST 5
#define SSH_MSG_SERVICE_ACCEPT 6
#define SSH_MSG_EXT_INFO 7
#define SSH_MSG_KEXINIT 20
#define SSH_MSG_NEWKEYS 21
@ -1069,18 +1190,22 @@ ssize_t _libssh2_recv(libssh2_socket_t socket, void *buffer,
ssize_t _libssh2_send(libssh2_socket_t socket, const void *buffer,
size_t length, int flags, void **abstract);
#define LIBSSH2_READ_TIMEOUT 60 /* generic timeout in seconds used when
waiting for more data to arrive */
#define LIBSSH2_DEFAULT_READ_TIMEOUT 60 /* generic timeout in seconds used when
waiting for more data to arrive */
int _libssh2_kex_exchange(LIBSSH2_SESSION * session, int reexchange,
key_exchange_state_t * state);
unsigned char *_libssh2_kex_agree_instr(unsigned char *haystack,
size_t haystack_len,
const unsigned char *needle,
size_t needle_len);
/* Let crypt.c/hostkey.c expose their method structs */
const LIBSSH2_CRYPT_METHOD **libssh2_crypt_methods(void);
const LIBSSH2_HOSTKEY_METHOD **libssh2_hostkey_methods(void);
/* misc.c */
int _libssh2_bcrypt_pbkdf(const char *pass,
size_t passlen,
const uint8_t *salt,
@ -1094,12 +1219,12 @@ int _libssh2_pem_parse(LIBSSH2_SESSION * session,
const char *headerbegin,
const char *headerend,
const unsigned char *passphrase,
FILE * fp, unsigned char **data, unsigned int *datalen);
FILE * fp, unsigned char **data, size_t *datalen);
int _libssh2_pem_parse_memory(LIBSSH2_SESSION * session,
const char *headerbegin,
const char *headerend,
const char *filedata, size_t filedata_len,
unsigned char **data, unsigned int *datalen);
unsigned char **data, size_t *datalen);
/* OpenSSL keys */
int
_libssh2_openssh_pem_parse(LIBSSH2_SESSION * session,
@ -1111,37 +1236,41 @@ _libssh2_openssh_pem_parse_memory(LIBSSH2_SESSION * session,
const char *filedata, size_t filedata_len,
struct string_buf **decrypted_buf);
int _libssh2_pem_decode_sequence(unsigned char **data, unsigned int *datalen);
int _libssh2_pem_decode_integer(unsigned char **data, unsigned int *datalen,
int _libssh2_pem_decode_sequence(unsigned char **data, size_t *datalen);
int _libssh2_pem_decode_integer(unsigned char **data, size_t *datalen,
unsigned char **i, unsigned int *ilen);
/* global.c */
void _libssh2_init_if_needed(void);
/* Utility function for certificate auth */
size_t plain_method(char *method, size_t method_len);
#define ARRAY_SIZE(a) (sizeof ((a)) / sizeof ((a)[0]))
/* define to output the libssh2_int64_t type in a *printf() */
#if defined(__BORLANDC__) || defined(_MSC_VER) || defined(__MINGW32__)
#if defined(__BORLANDC__) || defined(_MSC_VER)
#define LIBSSH2_INT64_T_FORMAT "I64d"
#elif defined(__MINGW32__)
#define LIBSSH2_INT64_T_FORMAT PRId64
#else
#define LIBSSH2_INT64_T_FORMAT "lld"
#endif
/* In Windows the default file mode is text but an application can override it.
Therefore we specify it explicitly. https://github.com/curl/curl/pull/258
*/
#if defined(WIN32) || defined(MSDOS)
Therefore we specify it explicitly. https://github.com/curl/curl/pull/258
*/
#if defined(_WIN32) || defined(MSDOS)
#define FOPEN_READTEXT "rt"
#define FOPEN_WRITETEXT "wt"
#define FOPEN_APPENDTEXT "at"
#elif defined(__CYGWIN__)
/* Cygwin has specific behavior we need to address when WIN32 is not defined.
https://cygwin.com/cygwin-ug-net/using-textbinary.html
For write we want our output to have line endings of LF and be compatible with
other Cygwin utilities. For read we want to handle input that may have line
endings either CRLF or LF so 't' is appropriate.
*/
/* Cygwin has specific behavior we need to address when _WIN32 is not defined.
https://cygwin.com/cygwin-ug-net/using-textbinary.html
For write we want our output to have line endings of LF and be compatible
with other Cygwin utilities. For read we want to handle input that may have
line endings either CRLF or LF so 't' is appropriate.
*/
#define FOPEN_READTEXT "rt"
#define FOPEN_WRITETEXT "w"
#define FOPEN_APPENDTEXT "a"
@ -1151,4 +1280,4 @@ endings either CRLF or LF so 't' is appropriate.
#define FOPEN_APPENDTEXT "a"
#endif
#endif /* __LIBSSH2_PRIV_H */
#endif /* LIBSSH2_PRIV_H */

View file

@ -1,4 +1,4 @@
/* Copyright (c) 2004-2006, Sara Golemon <sarag@libssh2.org>
/* Copyright (C) Sara Golemon <sarag@libssh2.org>
* All rights reserved.
*
* Redistribution and use in source and binary forms,
@ -41,6 +41,8 @@
*
* For more information on the publickey subsystem,
* refer to IETF draft: secsh-publickey
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#ifndef LIBSSH2_PUBLICKEY_H
@ -72,9 +74,9 @@ typedef struct _libssh2_publickey_list {
/* Generally use the first macro here, but if both name and value are string
literals, you can use _fast() to take advantage of preprocessing */
#define libssh2_publickey_attribute(name, value, mandatory) \
{ (name), strlen(name), (value), strlen(value), (mandatory) },
{ (name), strlen(name), (value), strlen(value), (mandatory) },
#define libssh2_publickey_attribute_fast(name, value, mandatory) \
{ (name), sizeof(name) - 1, (value), sizeof(value) - 1, (mandatory) },
{ (name), sizeof(name) - 1, (value), sizeof(value) - 1, (mandatory) },
#ifdef __cplusplus
extern "C" {
@ -92,10 +94,12 @@ libssh2_publickey_add_ex(LIBSSH2_PUBLICKEY *pkey,
unsigned long blob_len, char overwrite,
unsigned long num_attrs,
const libssh2_publickey_attribute attrs[]);
#define libssh2_publickey_add(pkey, name, blob, blob_len, overwrite, \
num_attrs, attrs) \
libssh2_publickey_add_ex((pkey), (name), strlen(name), (blob), (blob_len), \
(overwrite), (num_attrs), (attrs))
#define libssh2_publickey_add(pkey, name, blob, blob_len, overwrite, \
num_attrs, attrs) \
libssh2_publickey_add_ex((pkey), \
(name), strlen(name), \
(blob), (blob_len), \
(overwrite), (num_attrs), (attrs))
LIBSSH2_API int libssh2_publickey_remove_ex(LIBSSH2_PUBLICKEY *pkey,
const unsigned char *name,
@ -103,7 +107,9 @@ LIBSSH2_API int libssh2_publickey_remove_ex(LIBSSH2_PUBLICKEY *pkey,
const unsigned char *blob,
unsigned long blob_len);
#define libssh2_publickey_remove(pkey, name, blob, blob_len) \
libssh2_publickey_remove_ex((pkey), (name), strlen(name), (blob), (blob_len))
libssh2_publickey_remove_ex((pkey), \
(name), strlen(name), \
(blob), (blob_len))
LIBSSH2_API int
libssh2_publickey_list_fetch(LIBSSH2_PUBLICKEY *pkey,
@ -119,4 +125,4 @@ LIBSSH2_API int libssh2_publickey_shutdown(LIBSSH2_PUBLICKEY *pkey);
} /* extern "C" */
#endif
#endif /* ifndef: LIBSSH2_PUBLICKEY_H */
#endif /* LIBSSH2_PUBLICKEY_H */

View file

@ -0,0 +1,103 @@
/* Copyright (C) Viktor Szakats
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#ifndef LIBSSH2_SETUP_H
#define LIBSSH2_SETUP_H
/* Header for platform/compiler-specific initialization.
Used by 'src', 'example', 'tests' */
/* Define mingw-w64 version macros, eg __MINGW{32,64}_{MINOR,MAJOR}_VERSION */
#ifdef __MINGW32__
#include <_mingw.h>
#endif
/* Configuration provided by build tools (autotools and CMake),
and via platform-specific directories for os400 and vms */
#define HAVE_CONFIG_H 1
#if defined(HAVE_CONFIG_H) || defined(__OS400__) || defined(__VMS)
#include "libssh2_config.h"
/* Hand-crafted configuration for platforms which lack config tool.
Keep this synced with root CMakeLists.txt */
#elif defined(_WIN32)
#define HAVE_SELECT
#define HAVE_SNPRINTF
#ifdef __MINGW32__
# define HAVE_UNISTD_H
# define HAVE_INTTYPES_H
# define HAVE_SYS_TIME_H
# define HAVE_GETTIMEOFDAY
# define HAVE_STRTOLL
#elif defined(_MSC_VER)
# if _MSC_VER >= 1800
# define HAVE_INTTYPES_H
# define HAVE_STRTOLL
# else
# define HAVE_STRTOI64
# endif
# if _MSC_VER < 1900
# undef HAVE_SNPRINTF
# endif
#endif
#endif /* defined(HAVE_CONFIG_H) */
/* Below applies to both auto-detected and hand-crafted configs */
#ifdef _WIN32
#ifndef WIN32_LEAN_AND_MEAN
#define WIN32_LEAN_AND_MEAN
#endif
#ifndef NOGDI
#define NOGDI
#endif
#ifndef NONLS
#define NONLS
#endif
#ifdef __MINGW32__
# ifdef __MINGW64_VERSION_MAJOR
/* Number of bits in a file offset, on hosts where this is settable. */
# ifndef _FILE_OFFSET_BITS
# define _FILE_OFFSET_BITS 64
# endif
# endif
#elif defined(_MSC_VER)
# ifndef _CRT_SECURE_NO_WARNINGS
# define _CRT_SECURE_NO_WARNINGS /* for fopen(), getenv() */
# endif
# if !defined(LIBSSH2_LIBRARY) || defined(LIBSSH2_TESTS)
/* apply to examples and tests only */
# ifndef _CRT_NONSTDC_NO_DEPRECATE
# define _CRT_NONSTDC_NO_DEPRECATE /* for strdup(), write() */
# endif
# ifndef _WINSOCK_DEPRECATED_NO_WARNINGS
# define _WINSOCK_DEPRECATED_NO_WARNINGS /* for inet_addr() */
# endif
/* we cannot access our internal snprintf() implementation in examples and
tests when linking to a shared libssh2. */
# if _MSC_VER < 1900
# undef HAVE_SNPRINTF
# define HAVE_SNPRINTF
# define snprintf _snprintf
# endif
# endif
# if _MSC_VER < 1500
# define vsnprintf _vsnprintf
# endif
# if _MSC_VER < 1900
# define strdup _strdup
/* Silence bogus warning C4127: conditional expression is constant */
# pragma warning(disable:4127)
# endif
#endif
#endif /* _WIN32 */
#endif /* LIBSSH2_SETUP_H */

View file

@ -1,4 +1,4 @@
/* Copyright (c) 2004-2008, Sara Golemon <sarag@libssh2.org>
/* Copyright (C) Sara Golemon <sarag@libssh2.org>
* All rights reserved.
*
* Redistribution and use in source and binary forms,
@ -33,6 +33,8 @@
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
* USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
* OF SUCH DAMAGE.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#ifndef LIBSSH2_SFTP_H
@ -40,7 +42,7 @@
#include "libssh2.h"
#ifndef WIN32
#ifndef _WIN32
#include <unistd.h>
#endif
@ -165,19 +167,19 @@ struct _LIBSSH2_SFTP_STATVFS {
/* macros to check for specific file types, added in 1.2.5 */
#define LIBSSH2_SFTP_S_ISLNK(m) \
(((m) & LIBSSH2_SFTP_S_IFMT) == LIBSSH2_SFTP_S_IFLNK)
(((m) & LIBSSH2_SFTP_S_IFMT) == LIBSSH2_SFTP_S_IFLNK)
#define LIBSSH2_SFTP_S_ISREG(m) \
(((m) & LIBSSH2_SFTP_S_IFMT) == LIBSSH2_SFTP_S_IFREG)
(((m) & LIBSSH2_SFTP_S_IFMT) == LIBSSH2_SFTP_S_IFREG)
#define LIBSSH2_SFTP_S_ISDIR(m) \
(((m) & LIBSSH2_SFTP_S_IFMT) == LIBSSH2_SFTP_S_IFDIR)
(((m) & LIBSSH2_SFTP_S_IFMT) == LIBSSH2_SFTP_S_IFDIR)
#define LIBSSH2_SFTP_S_ISCHR(m) \
(((m) & LIBSSH2_SFTP_S_IFMT) == LIBSSH2_SFTP_S_IFCHR)
(((m) & LIBSSH2_SFTP_S_IFMT) == LIBSSH2_SFTP_S_IFCHR)
#define LIBSSH2_SFTP_S_ISBLK(m) \
(((m) & LIBSSH2_SFTP_S_IFMT) == LIBSSH2_SFTP_S_IFBLK)
(((m) & LIBSSH2_SFTP_S_IFMT) == LIBSSH2_SFTP_S_IFBLK)
#define LIBSSH2_SFTP_S_ISFIFO(m) \
(((m) & LIBSSH2_SFTP_S_IFMT) == LIBSSH2_SFTP_S_IFIFO)
(((m) & LIBSSH2_SFTP_S_IFMT) == LIBSSH2_SFTP_S_IFIFO)
#define LIBSSH2_SFTP_S_ISSOCK(m) \
(((m) & LIBSSH2_SFTP_S_IFMT) == LIBSSH2_SFTP_S_IFSOCK)
(((m) & LIBSSH2_SFTP_S_IFMT) == LIBSSH2_SFTP_S_IFSOCK)
/* SFTP File Transfer Flags -- (e.g. flags parameter to sftp_open())
* Danger will robinson... APPEND doesn't have any effect on OpenSSH servers */
@ -230,12 +232,25 @@ libssh2_sftp_open_ex(LIBSSH2_SFTP *sftp,
unsigned int filename_len,
unsigned long flags,
long mode, int open_type);
#define libssh2_sftp_open(sftp, filename, flags, mode) \
libssh2_sftp_open_ex((sftp), (filename), strlen(filename), (flags), \
(mode), LIBSSH2_SFTP_OPENFILE)
#define libssh2_sftp_open(sftp, filename, flags, mode) \
libssh2_sftp_open_ex((sftp), \
(filename), (unsigned int)strlen(filename), \
(flags), (mode), LIBSSH2_SFTP_OPENFILE)
#define libssh2_sftp_opendir(sftp, path) \
libssh2_sftp_open_ex((sftp), (path), strlen(path), 0, 0, \
LIBSSH2_SFTP_OPENDIR)
libssh2_sftp_open_ex((sftp), \
(path), (unsigned int)strlen(path), \
0, 0, LIBSSH2_SFTP_OPENDIR)
LIBSSH2_API LIBSSH2_SFTP_HANDLE *
libssh2_sftp_open_ex_r(LIBSSH2_SFTP *sftp,
const char *filename,
size_t filename_len,
unsigned long flags,
long mode, int open_type,
LIBSSH2_SFTP_ATTRIBUTES *attrs);
#define libssh2_sftp_open_r(sftp, filename, flags, mode, attrs) \
libssh2_sftp_open_ex_r((sftp), (filename), strlen(filename), \
(flags), (mode), LIBSSH2_SFTP_OPENFILE, \
(attrs))
LIBSSH2_API ssize_t libssh2_sftp_read(LIBSSH2_SFTP_HANDLE *handle,
char *buffer, size_t buffer_maxlen);
@ -245,7 +260,7 @@ LIBSSH2_API int libssh2_sftp_readdir_ex(LIBSSH2_SFTP_HANDLE *handle, \
char *longentry,
size_t longentry_maxlen,
LIBSSH2_SFTP_ATTRIBUTES *attrs);
#define libssh2_sftp_readdir(handle, buffer, buffer_maxlen, attrs) \
#define libssh2_sftp_readdir(handle, buffer, buffer_maxlen, attrs) \
libssh2_sftp_readdir_ex((handle), (buffer), (buffer_maxlen), NULL, 0, \
(attrs))
@ -281,17 +296,27 @@ LIBSSH2_API int libssh2_sftp_rename_ex(LIBSSH2_SFTP *sftp,
unsigned int dest_filename_len,
long flags);
#define libssh2_sftp_rename(sftp, sourcefile, destfile) \
libssh2_sftp_rename_ex((sftp), (sourcefile), strlen(sourcefile), \
(destfile), strlen(destfile), \
libssh2_sftp_rename_ex((sftp), \
(sourcefile), (unsigned int)strlen(sourcefile), \
(destfile), (unsigned int)strlen(destfile), \
LIBSSH2_SFTP_RENAME_OVERWRITE | \
LIBSSH2_SFTP_RENAME_ATOMIC | \
LIBSSH2_SFTP_RENAME_NATIVE)
LIBSSH2_API int libssh2_sftp_posix_rename_ex(LIBSSH2_SFTP *sftp,
const char *source_filename,
size_t srouce_filename_len,
const char *dest_filename,
size_t dest_filename_len);
#define libssh2_sftp_posix_rename(sftp, sourcefile, destfile) \
libssh2_sftp_posix_rename_ex((sftp), (sourcefile), strlen(sourcefile), \
(destfile), strlen(destfile))
LIBSSH2_API int libssh2_sftp_unlink_ex(LIBSSH2_SFTP *sftp,
const char *filename,
unsigned int filename_len);
#define libssh2_sftp_unlink(sftp, filename) \
libssh2_sftp_unlink_ex((sftp), (filename), strlen(filename))
libssh2_sftp_unlink_ex((sftp), (filename), (unsigned int)strlen(filename))
LIBSSH2_API int libssh2_sftp_fstatvfs(LIBSSH2_SFTP_HANDLE *handle,
LIBSSH2_SFTP_STATVFS *st);
@ -305,13 +330,13 @@ LIBSSH2_API int libssh2_sftp_mkdir_ex(LIBSSH2_SFTP *sftp,
const char *path,
unsigned int path_len, long mode);
#define libssh2_sftp_mkdir(sftp, path, mode) \
libssh2_sftp_mkdir_ex((sftp), (path), strlen(path), (mode))
libssh2_sftp_mkdir_ex((sftp), (path), (unsigned int)strlen(path), (mode))
LIBSSH2_API int libssh2_sftp_rmdir_ex(LIBSSH2_SFTP *sftp,
const char *path,
unsigned int path_len);
#define libssh2_sftp_rmdir(sftp, path) \
libssh2_sftp_rmdir_ex((sftp), (path), strlen(path))
libssh2_sftp_rmdir_ex((sftp), (path), (unsigned int)strlen(path))
LIBSSH2_API int libssh2_sftp_stat_ex(LIBSSH2_SFTP *sftp,
const char *path,
@ -319,14 +344,14 @@ LIBSSH2_API int libssh2_sftp_stat_ex(LIBSSH2_SFTP *sftp,
int stat_type,
LIBSSH2_SFTP_ATTRIBUTES *attrs);
#define libssh2_sftp_stat(sftp, path, attrs) \
libssh2_sftp_stat_ex((sftp), (path), strlen(path), LIBSSH2_SFTP_STAT, \
(attrs))
libssh2_sftp_stat_ex((sftp), (path), (unsigned int)strlen(path), \
LIBSSH2_SFTP_STAT, (attrs))
#define libssh2_sftp_lstat(sftp, path, attrs) \
libssh2_sftp_stat_ex((sftp), (path), strlen(path), LIBSSH2_SFTP_LSTAT, \
(attrs))
libssh2_sftp_stat_ex((sftp), (path), (unsigned int)strlen(path), \
LIBSSH2_SFTP_LSTAT, (attrs))
#define libssh2_sftp_setstat(sftp, path, attrs) \
libssh2_sftp_stat_ex((sftp), (path), strlen(path), LIBSSH2_SFTP_SETSTAT, \
(attrs))
libssh2_sftp_stat_ex((sftp), (path), (unsigned int)strlen(path), \
LIBSSH2_SFTP_SETSTAT, (attrs))
LIBSSH2_API int libssh2_sftp_symlink_ex(LIBSSH2_SFTP *sftp,
const char *path,
@ -335,13 +360,19 @@ LIBSSH2_API int libssh2_sftp_symlink_ex(LIBSSH2_SFTP *sftp,
unsigned int target_len,
int link_type);
#define libssh2_sftp_symlink(sftp, orig, linkpath) \
libssh2_sftp_symlink_ex((sftp), (orig), strlen(orig), (linkpath), \
strlen(linkpath), LIBSSH2_SFTP_SYMLINK)
libssh2_sftp_symlink_ex((sftp), \
(orig), (unsigned int)strlen(orig), \
(linkpath), (unsigned int)strlen(linkpath), \
LIBSSH2_SFTP_SYMLINK)
#define libssh2_sftp_readlink(sftp, path, target, maxlen) \
libssh2_sftp_symlink_ex((sftp), (path), strlen(path), (target), (maxlen), \
LIBSSH2_SFTP_READLINK)
libssh2_sftp_symlink_ex((sftp), \
(path), (unsigned int)strlen(path), \
(target), (maxlen), \
LIBSSH2_SFTP_READLINK)
#define libssh2_sftp_realpath(sftp, path, target, maxlen) \
libssh2_sftp_symlink_ex((sftp), (path), strlen(path), (target), (maxlen), \
libssh2_sftp_symlink_ex((sftp), \
(path), (unsigned int)strlen(path), \
(target), (maxlen), \
LIBSSH2_SFTP_REALPATH)
#ifdef __cplusplus

View file

@ -1,4 +1,4 @@
/* Copyright (c) 2004-2007, Sara Golemon <sarag@libssh2.org>
/* Copyright (C) Sara Golemon <sarag@libssh2.org>
* All rights reserved.
*
* Redistribution and use in source and binary forms,
@ -33,20 +33,33 @@
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
* USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
* OF SUCH DAMAGE.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#include "libssh2_priv.h"
#include "mac.h"
#ifdef LIBSSH2_MAC_NONE
#if defined(LIBSSH2DEBUG) && defined(LIBSSH2_MAC_NONE_INSECURE)
/* mac_none_MAC
* Minimalist MAC: No MAC
*
* Minimalist MAC: No MAC. DO NOT USE.
*
* The SSH2 Transport allows implementations to forego a message
* authentication code. While this is less of a security risk than using
* a "none" cipher, it is still not recommended as disabling MAC hashes
* removes a layer of security.
*
* Enabling this option will allow for "none" as a negotiable method,
* however it still requires that the method be advertised by the remote
* end and that no more-preferable methods are available.
*
*/
static int
mac_none_MAC(LIBSSH2_SESSION * session, unsigned char *buf,
uint32_t seqno, const unsigned char *packet,
uint32_t packet_len, const unsigned char *addtl,
uint32_t addtl_len, void **abstract)
size_t packet_len, const unsigned char *addtl,
size_t addtl_len, void **abstract)
{
return 0;
}
@ -60,9 +73,10 @@ static LIBSSH2_MAC_METHOD mac_method_none = {
0,
NULL,
mac_none_MAC,
NULL
NULL,
0
};
#endif /* LIBSSH2_MAC_NONE */
#endif /* defined(LIBSSH2DEBUG) && defined(LIBSSH2_MAC_NONE_INSECURE) */
/* mac_method_common_init
* Initialize simple mac methods
@ -73,7 +87,7 @@ mac_method_common_init(LIBSSH2_SESSION * session, unsigned char *key,
{
*abstract = key;
*free_key = 0;
(void) session;
(void)session;
return 0;
}
@ -102,29 +116,31 @@ mac_method_common_dtor(LIBSSH2_SESSION * session, void **abstract)
*/
static int
mac_method_hmac_sha2_512_hash(LIBSSH2_SESSION * session,
unsigned char *buf, uint32_t seqno,
const unsigned char *packet,
uint32_t packet_len,
const unsigned char *addtl,
uint32_t addtl_len, void **abstract)
unsigned char *buf, uint32_t seqno,
const unsigned char *packet,
size_t packet_len,
const unsigned char *addtl,
size_t addtl_len, void **abstract)
{
libssh2_hmac_ctx ctx;
unsigned char seqno_buf[4];
(void) session;
int res;
(void)session;
_libssh2_htonu32(seqno_buf, seqno);
libssh2_hmac_ctx_init(ctx);
libssh2_hmac_sha512_init(&ctx, *abstract, 64);
libssh2_hmac_update(ctx, seqno_buf, 4);
libssh2_hmac_update(ctx, packet, packet_len);
if(addtl && addtl_len) {
libssh2_hmac_update(ctx, addtl, addtl_len);
}
libssh2_hmac_final(ctx, buf);
libssh2_hmac_cleanup(&ctx);
if(!_libssh2_hmac_ctx_init(&ctx))
return 1;
res = _libssh2_hmac_sha512_init(&ctx, *abstract, 64) &&
_libssh2_hmac_update(&ctx, seqno_buf, 4) &&
_libssh2_hmac_update(&ctx, packet, packet_len);
if(res && addtl && addtl_len)
res = _libssh2_hmac_update(&ctx, addtl, addtl_len);
if(res)
res = _libssh2_hmac_final(&ctx, buf);
_libssh2_hmac_cleanup(&ctx);
return 0;
return !res;
}
@ -136,7 +152,19 @@ static const LIBSSH2_MAC_METHOD mac_method_hmac_sha2_512 = {
mac_method_common_init,
mac_method_hmac_sha2_512_hash,
mac_method_common_dtor,
0
};
static const LIBSSH2_MAC_METHOD mac_method_hmac_sha2_512_etm = {
"hmac-sha2-512-etm@openssh.com",
64,
64,
mac_method_common_init,
mac_method_hmac_sha2_512_hash,
mac_method_common_dtor,
1
};
#endif
@ -147,29 +175,31 @@ static const LIBSSH2_MAC_METHOD mac_method_hmac_sha2_512 = {
*/
static int
mac_method_hmac_sha2_256_hash(LIBSSH2_SESSION * session,
unsigned char *buf, uint32_t seqno,
const unsigned char *packet,
uint32_t packet_len,
const unsigned char *addtl,
uint32_t addtl_len, void **abstract)
unsigned char *buf, uint32_t seqno,
const unsigned char *packet,
size_t packet_len,
const unsigned char *addtl,
size_t addtl_len, void **abstract)
{
libssh2_hmac_ctx ctx;
unsigned char seqno_buf[4];
(void) session;
int res;
(void)session;
_libssh2_htonu32(seqno_buf, seqno);
libssh2_hmac_ctx_init(ctx);
libssh2_hmac_sha256_init(&ctx, *abstract, 32);
libssh2_hmac_update(ctx, seqno_buf, 4);
libssh2_hmac_update(ctx, packet, packet_len);
if(addtl && addtl_len) {
libssh2_hmac_update(ctx, addtl, addtl_len);
}
libssh2_hmac_final(ctx, buf);
libssh2_hmac_cleanup(&ctx);
if(!_libssh2_hmac_ctx_init(&ctx))
return 1;
res = _libssh2_hmac_sha256_init(&ctx, *abstract, 32) &&
_libssh2_hmac_update(&ctx, seqno_buf, 4) &&
_libssh2_hmac_update(&ctx, packet, packet_len);
if(res && addtl && addtl_len)
res = _libssh2_hmac_update(&ctx, addtl, addtl_len);
if(res)
res = _libssh2_hmac_final(&ctx, buf);
_libssh2_hmac_cleanup(&ctx);
return 0;
return !res;
}
@ -181,7 +211,19 @@ static const LIBSSH2_MAC_METHOD mac_method_hmac_sha2_256 = {
mac_method_common_init,
mac_method_hmac_sha2_256_hash,
mac_method_common_dtor,
0
};
static const LIBSSH2_MAC_METHOD mac_method_hmac_sha2_256_etm = {
"hmac-sha2-256-etm@openssh.com",
32,
32,
mac_method_common_init,
mac_method_hmac_sha2_256_hash,
mac_method_common_dtor,
1
};
#endif
@ -194,27 +236,29 @@ static int
mac_method_hmac_sha1_hash(LIBSSH2_SESSION * session,
unsigned char *buf, uint32_t seqno,
const unsigned char *packet,
uint32_t packet_len,
size_t packet_len,
const unsigned char *addtl,
uint32_t addtl_len, void **abstract)
size_t addtl_len, void **abstract)
{
libssh2_hmac_ctx ctx;
unsigned char seqno_buf[4];
(void) session;
int res;
(void)session;
_libssh2_htonu32(seqno_buf, seqno);
libssh2_hmac_ctx_init(ctx);
libssh2_hmac_sha1_init(&ctx, *abstract, 20);
libssh2_hmac_update(ctx, seqno_buf, 4);
libssh2_hmac_update(ctx, packet, packet_len);
if(addtl && addtl_len) {
libssh2_hmac_update(ctx, addtl, addtl_len);
}
libssh2_hmac_final(ctx, buf);
libssh2_hmac_cleanup(&ctx);
if(!_libssh2_hmac_ctx_init(&ctx))
return 1;
res = _libssh2_hmac_sha1_init(&ctx, *abstract, 20) &&
_libssh2_hmac_update(&ctx, seqno_buf, 4) &&
_libssh2_hmac_update(&ctx, packet, packet_len);
if(res && addtl && addtl_len)
res = _libssh2_hmac_update(&ctx, addtl, addtl_len);
if(res)
res = _libssh2_hmac_final(&ctx, buf);
_libssh2_hmac_cleanup(&ctx);
return 0;
return !res;
}
@ -226,6 +270,17 @@ static const LIBSSH2_MAC_METHOD mac_method_hmac_sha1 = {
mac_method_common_init,
mac_method_hmac_sha1_hash,
mac_method_common_dtor,
0
};
static const LIBSSH2_MAC_METHOD mac_method_hmac_sha1_etm = {
"hmac-sha1-etm@openssh.com",
20,
20,
mac_method_common_init,
mac_method_hmac_sha1_hash,
mac_method_common_dtor,
1
};
/* mac_method_hmac_sha1_96_hash
@ -235,16 +290,17 @@ static int
mac_method_hmac_sha1_96_hash(LIBSSH2_SESSION * session,
unsigned char *buf, uint32_t seqno,
const unsigned char *packet,
uint32_t packet_len,
size_t packet_len,
const unsigned char *addtl,
uint32_t addtl_len, void **abstract)
size_t addtl_len, void **abstract)
{
unsigned char temp[SHA_DIGEST_LENGTH];
mac_method_hmac_sha1_hash(session, temp, seqno, packet, packet_len,
addtl, addtl_len, abstract);
memcpy(buf, (char *) temp, 96 / 8);
if(mac_method_hmac_sha1_hash(session, temp, seqno, packet, packet_len,
addtl, addtl_len, abstract))
return 1;
memcpy(buf, (char *) temp, 96 / 8);
return 0;
}
@ -257,6 +313,7 @@ static const LIBSSH2_MAC_METHOD mac_method_hmac_sha1_96 = {
mac_method_common_init,
mac_method_hmac_sha1_96_hash,
mac_method_common_dtor,
0
};
#if LIBSSH2_MD5
@ -267,27 +324,29 @@ static int
mac_method_hmac_md5_hash(LIBSSH2_SESSION * session, unsigned char *buf,
uint32_t seqno,
const unsigned char *packet,
uint32_t packet_len,
size_t packet_len,
const unsigned char *addtl,
uint32_t addtl_len, void **abstract)
size_t addtl_len, void **abstract)
{
libssh2_hmac_ctx ctx;
unsigned char seqno_buf[4];
(void) session;
int res;
(void)session;
_libssh2_htonu32(seqno_buf, seqno);
libssh2_hmac_ctx_init(ctx);
libssh2_hmac_md5_init(&ctx, *abstract, 16);
libssh2_hmac_update(ctx, seqno_buf, 4);
libssh2_hmac_update(ctx, packet, packet_len);
if(addtl && addtl_len) {
libssh2_hmac_update(ctx, addtl, addtl_len);
}
libssh2_hmac_final(ctx, buf);
libssh2_hmac_cleanup(&ctx);
if(!_libssh2_hmac_ctx_init(&ctx))
return 1;
res = _libssh2_hmac_md5_init(&ctx, *abstract, 16) &&
_libssh2_hmac_update(&ctx, seqno_buf, 4) &&
_libssh2_hmac_update(&ctx, packet, packet_len);
if(res && addtl && addtl_len)
res = _libssh2_hmac_update(&ctx, addtl, addtl_len);
if(res)
res = _libssh2_hmac_final(&ctx, buf);
_libssh2_hmac_cleanup(&ctx);
return 0;
return !res;
}
@ -299,6 +358,7 @@ static const LIBSSH2_MAC_METHOD mac_method_hmac_md5 = {
mac_method_common_init,
mac_method_hmac_md5_hash,
mac_method_common_dtor,
0
};
/* mac_method_hmac_md5_96_hash
@ -308,13 +368,16 @@ static int
mac_method_hmac_md5_96_hash(LIBSSH2_SESSION * session,
unsigned char *buf, uint32_t seqno,
const unsigned char *packet,
uint32_t packet_len,
size_t packet_len,
const unsigned char *addtl,
uint32_t addtl_len, void **abstract)
size_t addtl_len, void **abstract)
{
unsigned char temp[MD5_DIGEST_LENGTH];
mac_method_hmac_md5_hash(session, temp, seqno, packet, packet_len,
addtl, addtl_len, abstract);
if(mac_method_hmac_md5_hash(session, temp, seqno, packet, packet_len,
addtl, addtl_len, abstract))
return 1;
memcpy(buf, (char *) temp, 96 / 8);
return 0;
}
@ -328,6 +391,7 @@ static const LIBSSH2_MAC_METHOD mac_method_hmac_md5_96 = {
mac_method_common_init,
mac_method_hmac_md5_96_hash,
mac_method_common_dtor,
0
};
#endif /* LIBSSH2_MD5 */
@ -339,28 +403,30 @@ static int
mac_method_hmac_ripemd160_hash(LIBSSH2_SESSION * session,
unsigned char *buf, uint32_t seqno,
const unsigned char *packet,
uint32_t packet_len,
size_t packet_len,
const unsigned char *addtl,
uint32_t addtl_len,
size_t addtl_len,
void **abstract)
{
libssh2_hmac_ctx ctx;
unsigned char seqno_buf[4];
(void) session;
int res;
(void)session;
_libssh2_htonu32(seqno_buf, seqno);
libssh2_hmac_ctx_init(ctx);
libssh2_hmac_ripemd160_init(&ctx, *abstract, 20);
libssh2_hmac_update(ctx, seqno_buf, 4);
libssh2_hmac_update(ctx, packet, packet_len);
if(addtl && addtl_len) {
libssh2_hmac_update(ctx, addtl, addtl_len);
}
libssh2_hmac_final(ctx, buf);
libssh2_hmac_cleanup(&ctx);
if(!_libssh2_hmac_ctx_init(&ctx))
return 1;
res = _libssh2_hmac_ripemd160_init(&ctx, *abstract, 20) &&
_libssh2_hmac_update(&ctx, seqno_buf, 4) &&
_libssh2_hmac_update(&ctx, packet, packet_len);
if(res && addtl && addtl_len)
res = _libssh2_hmac_update(&ctx, addtl, addtl_len);
if(res)
res = _libssh2_hmac_final(&ctx, buf);
_libssh2_hmac_cleanup(&ctx);
return 0;
return !res;
}
@ -372,6 +438,7 @@ static const LIBSSH2_MAC_METHOD mac_method_hmac_ripemd160 = {
mac_method_common_init,
mac_method_hmac_ripemd160_hash,
mac_method_common_dtor,
0
};
static const LIBSSH2_MAC_METHOD mac_method_hmac_ripemd160_openssh_com = {
@ -381,17 +448,21 @@ static const LIBSSH2_MAC_METHOD mac_method_hmac_ripemd160_openssh_com = {
mac_method_common_init,
mac_method_hmac_ripemd160_hash,
mac_method_common_dtor,
0
};
#endif /* LIBSSH2_HMAC_RIPEMD */
static const LIBSSH2_MAC_METHOD *mac_methods[] = {
#if LIBSSH2_HMAC_SHA256
&mac_method_hmac_sha2_256,
&mac_method_hmac_sha2_256_etm,
#endif
#if LIBSSH2_HMAC_SHA512
&mac_method_hmac_sha2_512,
&mac_method_hmac_sha2_512_etm,
#endif
&mac_method_hmac_sha1,
&mac_method_hmac_sha1_etm,
&mac_method_hmac_sha1_96,
#if LIBSSH2_MD5
&mac_method_hmac_md5,
@ -401,9 +472,9 @@ static const LIBSSH2_MAC_METHOD *mac_methods[] = {
&mac_method_hmac_ripemd160,
&mac_method_hmac_ripemd160_openssh_com,
#endif /* LIBSSH2_HMAC_RIPEMD */
#ifdef LIBSSH2_MAC_NONE
#if defined(LIBSSH2DEBUG) && defined(LIBSSH2_MAC_NONE_INSECURE)
&mac_method_none,
#endif /* LIBSSH2_MAC_NONE */
#endif
NULL
};
@ -412,3 +483,71 @@ _libssh2_mac_methods(void)
{
return mac_methods;
}
#if LIBSSH2_AES_GCM
static int
mac_method_none_init(LIBSSH2_SESSION * session, unsigned char *key,
int *free_key, void **abstract)
{
(void)session;
(void)key;
(void)free_key;
(void)abstract;
return 0;
}
static int
mac_method_hmac_none_hash(LIBSSH2_SESSION * session,
unsigned char *buf, uint32_t seqno,
const unsigned char *packet,
size_t packet_len,
const unsigned char *addtl,
size_t addtl_len, void **abstract)
{
(void)session;
(void)buf;
(void)seqno;
(void)packet;
(void)packet_len;
(void)addtl;
(void)addtl_len;
(void)abstract;
return 0;
}
static int
mac_method_none_dtor(LIBSSH2_SESSION * session, void **abstract)
{
(void)session;
(void)abstract;
return 0;
}
/* Stub for aes256-gcm@openssh.com crypto type, which has an integrated
HMAC method. This must not be added to mac_methods[] since it cannot be
negotiated separately. */
static const LIBSSH2_MAC_METHOD mac_method_hmac_aesgcm = {
"INTEGRATED-AES-GCM", /* made up name for display only */
16,
16,
mac_method_none_init,
mac_method_hmac_none_hash,
mac_method_none_dtor,
0
};
#endif /* LIBSSH2_AES_GCM */
/* See if the negotiated crypto method has its own authentication scheme that
* obviates the need for a separate negotiated hmac method */
const LIBSSH2_MAC_METHOD *
_libssh2_mac_override(const LIBSSH2_CRYPT_METHOD *crypt)
{
#if LIBSSH2_AES_GCM
if(!strcmp(crypt->name, "aes256-gcm@openssh.com") ||
!strcmp(crypt->name, "aes128-gcm@openssh.com"))
return &mac_method_hmac_aesgcm;
#else
(void) crypt;
#endif /* LIBSSH2_AES_GCM */
return NULL;
}

View file

@ -1,6 +1,7 @@
#ifndef __LIBSSH2_MAC_H
#define __LIBSSH2_MAC_H
/* Copyright (C) 2009-2010 by Daniel Stenberg
#ifndef LIBSSH2_MAC_H
#define LIBSSH2_MAC_H
/* Copyright (C) Daniel Stenberg
* All rights reserved.
*
* Redistribution and use in source and binary forms,
* with or without modification, are permitted provided
@ -35,6 +36,7 @@
* USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
* OF SUCH DAMAGE.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#include "libssh2_priv.h"
@ -54,13 +56,17 @@ struct _LIBSSH2_MAC_METHOD
void **abstract);
int (*hash) (LIBSSH2_SESSION * session, unsigned char *buf,
uint32_t seqno, const unsigned char *packet,
uint32_t packet_len, const unsigned char *addtl,
uint32_t addtl_len, void **abstract);
size_t packet_len, const unsigned char *addtl,
size_t addtl_len, void **abstract);
int (*dtor) (LIBSSH2_SESSION * session, void **abstract);
int etm; /* encrypt-then-mac */
};
typedef struct _LIBSSH2_MAC_METHOD LIBSSH2_MAC_METHOD;
const LIBSSH2_MAC_METHOD **_libssh2_mac_methods(void);
const LIBSSH2_MAC_METHOD *_libssh2_mac_override(
const LIBSSH2_CRYPT_METHOD *crypt);
#endif /* __LIBSSH2_MAC_H */
#endif /* LIBSSH2_MAC_H */

File diff suppressed because it is too large Load diff

View file

@ -1,6 +1,6 @@
#ifndef __LIBSSH2_MBEDTLS_H
#define __LIBSSH2_MBEDTLS_H
/* Copyright (c) 2016, Art <https://github.com/wildart>
#ifndef LIBSSH2_MBEDTLS_H
#define LIBSSH2_MBEDTLS_H
/* Copyright (C) Art <https://github.com/wildart>
* All rights reserved.
*
* Redistribution and use in source and binary forms,
@ -35,11 +35,28 @@
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
* USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
* OF SUCH DAMAGE.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#include <stdlib.h>
#include <string.h>
#define LIBSSH2_CRYPTO_ENGINE libssh2_mbedtls
#ifdef __GNUC__
#pragma GCC diagnostic push
/* mbedTLS (as of v3.5.1) has a `[-Werror=arith-conversion]`
warning in its public headers. */
#if !defined(__clang__) && __GNUC__ >= 10
#pragma GCC diagnostic ignored "-Warith-conversion"
#endif
#if defined(__clang__)
#pragma GCC diagnostic ignored "-Wsign-conversion"
#endif
/* mbedTLS (as of v3.5.1) has a duplicate function declaration
in its public headers. Disable the warning that detects it. */
#pragma GCC diagnostic ignored "-Wredundant-decls"
#endif
#include <mbedtls/version.h>
#include <mbedtls/platform.h>
#include <mbedtls/md.h>
#include <mbedtls/rsa.h>
@ -56,6 +73,10 @@
#include <mbedtls/pk.h>
#include <mbedtls/error.h>
#ifdef __GNUC__
#pragma GCC diagnostic pop
#endif
/* Define which features are supported. */
#define LIBSSH2_MD5 1
@ -63,14 +84,25 @@
#define LIBSSH2_HMAC_SHA256 1
#define LIBSSH2_HMAC_SHA512 1
#define LIBSSH2_AES 1
#define LIBSSH2_AES_CBC 1
#define LIBSSH2_AES_CTR 1
#define LIBSSH2_BLOWFISH 1
#define LIBSSH2_RC4 1
#define LIBSSH2_AES_GCM 0
#ifdef MBEDTLS_CIPHER_BLOWFISH_CBC
# define LIBSSH2_BLOWFISH 1
#else
# define LIBSSH2_BLOWFISH 0
#endif
#ifdef MBEDTLS_CIPHER_ARC4_128
# define LIBSSH2_RC4 1
#else
# define LIBSSH2_RC4 0
#endif
#define LIBSSH2_CAST 0
#define LIBSSH2_3DES 1
#define LIBSSH2_RSA 1
#define LIBSSH2_RSA_SHA1 1
#define LIBSSH2_RSA_SHA2 1
#define LIBSSH2_DSA 0
#ifdef MBEDTLS_ECDSA_C
# define LIBSSH2_ECDSA 1
@ -79,7 +111,11 @@
#endif
#define LIBSSH2_ED25519 0
#include "crypto_config.h"
#if LIBSSH2_MD5 || LIBSSH2_MD5_PEM
#define MD5_DIGEST_LENGTH 16
#endif
#define SHA_DIGEST_LENGTH 20
#define SHA256_DIGEST_LENGTH 32
#define SHA384_DIGEST_LENGTH 48
@ -94,12 +130,12 @@
*/
#define libssh2_crypto_init() \
_libssh2_mbedtls_init()
_libssh2_mbedtls_init()
#define libssh2_crypto_exit() \
_libssh2_mbedtls_free()
_libssh2_mbedtls_free()
#define _libssh2_random(buf, len) \
_libssh2_mbedtls_random(buf, len)
_libssh2_mbedtls_random(buf, len)
#define libssh2_prepare_iovec(vec, len) /* Empty. */
@ -111,27 +147,6 @@
#define libssh2_hmac_ctx mbedtls_md_context_t
#define libssh2_hmac_ctx_init(ctx)
#define libssh2_hmac_cleanup(pctx) \
mbedtls_md_free(pctx)
#define libssh2_hmac_update(ctx, data, datalen) \
mbedtls_md_hmac_update(&ctx, (unsigned char *) data, datalen)
#define libssh2_hmac_final(ctx, hash) \
mbedtls_md_hmac_finish(&ctx, hash)
#define libssh2_hmac_sha1_init(pctx, key, keylen) \
_libssh2_mbedtls_hash_init(pctx, MBEDTLS_MD_SHA1, key, keylen)
#define libssh2_hmac_md5_init(pctx, key, keylen) \
_libssh2_mbedtls_hash_init(pctx, MBEDTLS_MD_MD5, key, keylen)
#define libssh2_hmac_ripemd160_init(pctx, key, keylen) \
_libssh2_mbedtls_hash_init(pctx, MBEDTLS_MD_RIPEMD160, key, keylen)
#define libssh2_hmac_sha256_init(pctx, key, keylen) \
_libssh2_mbedtls_hash_init(pctx, MBEDTLS_MD_SHA256, key, keylen)
#define libssh2_hmac_sha384_init(pctx, key, keylen) \
_libssh2_mbedtls_hash_init(pctx, MBEDTLS_MD_SHA384, key, keylen)
#define libssh2_hmac_sha512_init(pctx, key, keylen) \
_libssh2_mbedtls_hash_init(pctx, MBEDTLS_MD_SHA512, key, keylen)
/*******************************************************************/
/*
@ -141,13 +156,14 @@
#define libssh2_sha1_ctx mbedtls_md_context_t
#define libssh2_sha1_init(pctx) \
_libssh2_mbedtls_hash_init(pctx, MBEDTLS_MD_SHA1, NULL, 0)
_libssh2_mbedtls_hash_init(pctx, MBEDTLS_MD_SHA1, NULL, 0)
#define libssh2_sha1_update(ctx, data, datalen) \
mbedtls_md_update(&ctx, (unsigned char *) data, datalen)
(mbedtls_md_update(&ctx, (const unsigned char *) data, datalen) == 0)
#define libssh2_sha1_final(ctx, hash) \
_libssh2_mbedtls_hash_final(&ctx, hash)
_libssh2_mbedtls_hash_final(&ctx, hash)
#define libssh2_sha1(data, datalen, hash) \
_libssh2_mbedtls_hash(data, datalen, MBEDTLS_MD_SHA1, hash)
_libssh2_mbedtls_hash(data, datalen, MBEDTLS_MD_SHA1, hash)
/*******************************************************************/
/*
@ -157,13 +173,13 @@
#define libssh2_sha256_ctx mbedtls_md_context_t
#define libssh2_sha256_init(pctx) \
_libssh2_mbedtls_hash_init(pctx, MBEDTLS_MD_SHA256, NULL, 0)
_libssh2_mbedtls_hash_init(pctx, MBEDTLS_MD_SHA256, NULL, 0)
#define libssh2_sha256_update(ctx, data, datalen) \
mbedtls_md_update(&ctx, (unsigned char *) data, datalen)
(mbedtls_md_update(&ctx, (const unsigned char *) data, datalen) == 0)
#define libssh2_sha256_final(ctx, hash) \
_libssh2_mbedtls_hash_final(&ctx, hash)
_libssh2_mbedtls_hash_final(&ctx, hash)
#define libssh2_sha256(data, datalen, hash) \
_libssh2_mbedtls_hash(data, datalen, MBEDTLS_MD_SHA256, hash)
_libssh2_mbedtls_hash(data, datalen, MBEDTLS_MD_SHA256, hash)
/*******************************************************************/
@ -174,13 +190,13 @@
#define libssh2_sha384_ctx mbedtls_md_context_t
#define libssh2_sha384_init(pctx) \
_libssh2_mbedtls_hash_init(pctx, MBEDTLS_MD_SHA384, NULL, 0)
_libssh2_mbedtls_hash_init(pctx, MBEDTLS_MD_SHA384, NULL, 0)
#define libssh2_sha384_update(ctx, data, datalen) \
mbedtls_md_update(&ctx, (unsigned char *) data, datalen)
(mbedtls_md_update(&ctx, (const unsigned char *) data, datalen) == 0)
#define libssh2_sha384_final(ctx, hash) \
_libssh2_mbedtls_hash_final(&ctx, hash)
_libssh2_mbedtls_hash_final(&ctx, hash)
#define libssh2_sha384(data, datalen, hash) \
_libssh2_mbedtls_hash(data, datalen, MBEDTLS_MD_SHA384, hash)
_libssh2_mbedtls_hash(data, datalen, MBEDTLS_MD_SHA384, hash)
/*******************************************************************/
@ -191,13 +207,13 @@
#define libssh2_sha512_ctx mbedtls_md_context_t
#define libssh2_sha512_init(pctx) \
_libssh2_mbedtls_hash_init(pctx, MBEDTLS_MD_SHA512, NULL, 0)
_libssh2_mbedtls_hash_init(pctx, MBEDTLS_MD_SHA512, NULL, 0)
#define libssh2_sha512_update(ctx, data, datalen) \
mbedtls_md_update(&ctx, (unsigned char *) data, datalen)
(mbedtls_md_update(&ctx, (const unsigned char *) data, datalen) == 0)
#define libssh2_sha512_final(ctx, hash) \
_libssh2_mbedtls_hash_final(&ctx, hash)
_libssh2_mbedtls_hash_final(&ctx, hash)
#define libssh2_sha512(data, datalen, hash) \
_libssh2_mbedtls_hash(data, datalen, MBEDTLS_MD_SHA512, hash)
_libssh2_mbedtls_hash(data, datalen, MBEDTLS_MD_SHA512, hash)
/*******************************************************************/
@ -205,17 +221,16 @@
* mbedTLS backend: MD5 functions
*/
#if LIBSSH2_MD5 || LIBSSH2_MD5_PEM
#define libssh2_md5_ctx mbedtls_md_context_t
#define libssh2_md5_init(pctx) \
_libssh2_mbedtls_hash_init(pctx, MBEDTLS_MD_MD5, NULL, 0)
_libssh2_mbedtls_hash_init(pctx, MBEDTLS_MD_MD5, NULL, 0)
#define libssh2_md5_update(ctx, data, datalen) \
mbedtls_md_update(&ctx, (unsigned char *) data, datalen)
(mbedtls_md_update(&ctx, (const unsigned char *) data, datalen) == 0)
#define libssh2_md5_final(ctx, hash) \
_libssh2_mbedtls_hash_final(&ctx, hash)
#define libssh2_md5(data, datalen, hash) \
_libssh2_mbedtls_hash(data, datalen, MBEDTLS_MD_MD5, hash)
_libssh2_mbedtls_hash_final(&ctx, hash)
#endif
/*******************************************************************/
/*
@ -227,26 +242,33 @@
#define _libssh2_rsa_new(rsactx, e, e_len, n, n_len, \
d, d_len, p, p_len, q, q_len, \
e1, e1_len, e2, e2_len, c, c_len) \
_libssh2_mbedtls_rsa_new(rsactx, e, e_len, n, n_len, \
d, d_len, p, p_len, q, q_len, \
e1, e1_len, e2, e2_len, c, c_len)
_libssh2_mbedtls_rsa_new(rsactx, e, e_len, n, n_len, \
d, d_len, p, p_len, q, q_len, \
e1, e1_len, e2, e2_len, c, c_len)
#define _libssh2_rsa_new_private(rsactx, s, filename, passphrase) \
_libssh2_mbedtls_rsa_new_private(rsactx, s, filename, passphrase)
_libssh2_mbedtls_rsa_new_private(rsactx, s, filename, passphrase)
#define _libssh2_rsa_new_private_frommemory(rsactx, s, filedata, \
filedata_len, passphrase) \
_libssh2_mbedtls_rsa_new_private_frommemory(rsactx, s, filedata, \
filedata_len, passphrase)
_libssh2_mbedtls_rsa_new_private_frommemory(rsactx, s, filedata, \
filedata_len, passphrase)
#define _libssh2_rsa_sha1_sign(s, rsactx, hash, hash_len, sig, sig_len) \
_libssh2_mbedtls_rsa_sha1_sign(s, rsactx, hash, hash_len, sig, sig_len)
_libssh2_mbedtls_rsa_sha1_sign(s, rsactx, hash, hash_len, sig, sig_len)
#define _libssh2_rsa_sha2_sign(s, rsactx, hash, hash_len, sig, sig_len) \
_libssh2_mbedtls_rsa_sha2_sign(s, rsactx, hash, hash_len, sig, sig_len)
#define _libssh2_rsa_sha1_verify(rsactx, sig, sig_len, m, m_len) \
_libssh2_mbedtls_rsa_sha1_verify(rsactx, sig, sig_len, m, m_len)
_libssh2_mbedtls_rsa_sha1_verify(rsactx, sig, sig_len, m, m_len)
#define _libssh2_rsa_sha2_verify(rsactx, hash_len, sig, sig_len, m, m_len) \
_libssh2_mbedtls_rsa_sha2_verify(rsactx, hash_len, sig, sig_len, m, m_len)
#define _libssh2_rsa_free(rsactx) \
_libssh2_mbedtls_rsa_free(rsactx)
_libssh2_mbedtls_rsa_free(rsactx)
/*******************************************************************/
@ -291,34 +313,34 @@ typedef enum {
#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)
_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)
_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)
_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)
_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)
_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)
_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)
_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)
_libssh2_mbedtls_ecdsa_get_curve_type(ctx)
#define _libssh2_ecdsa_free(ctx) \
_libssh2_mbedtls_ecdsa_free(ctx)
_libssh2_mbedtls_ecdsa_free(ctx)
#endif /* LIBSSH2_ECDSA */
@ -329,11 +351,15 @@ typedef enum {
*/
#define _libssh2_pub_priv_keyfile(s, m, m_len, p, p_len, pk, pw) \
_libssh2_mbedtls_pub_priv_keyfile(s, m, m_len, p, p_len, pk, pw)
_libssh2_mbedtls_pub_priv_keyfile(s, m, m_len, p, p_len, pk, pw)
#define _libssh2_pub_priv_keyfilememory(s, m, m_len, p, p_len, \
pk, pk_len, pw) \
_libssh2_mbedtls_pub_priv_keyfilememory(s, m, m_len, p, p_len, \
pk, pk_len, pw)
pk, pk_len, pw) \
_libssh2_mbedtls_pub_priv_keyfilememory(s, m, m_len, p, p_len, \
pk, pk_len, pw)
#define _libssh2_sk_pub_keyfilememory(s, m, m_len, p, p_len, alg, app, \
f, kh, kh_len, pk, pk_len, pw) \
_libssh2_mbedtls_sk_pub_keyfilememory(s, m, m_len, p, p_len, alg, app, \
f, kh, kh_len, pk, pk_len, pw)
/*******************************************************************/
@ -351,10 +377,14 @@ typedef enum {
#define _libssh2_cipher_aes256 MBEDTLS_CIPHER_AES_256_CBC
#define _libssh2_cipher_aes192 MBEDTLS_CIPHER_AES_192_CBC
#define _libssh2_cipher_aes128 MBEDTLS_CIPHER_AES_128_CBC
#ifdef MBEDTLS_CIPHER_BLOWFISH_CBC
#define _libssh2_cipher_blowfish MBEDTLS_CIPHER_BLOWFISH_CBC
#endif
#ifdef MBEDTLS_CIPHER_ARC4_128
#define _libssh2_cipher_arcfour MBEDTLS_CIPHER_ARC4_128
#define _libssh2_cipher_cast5 MBEDTLS_CIPHER_NULL
#endif
#define _libssh2_cipher_3des MBEDTLS_CIPHER_DES_EDE3_CBC
#define _libssh2_cipher_chacha20 MBEDTLS_CIPHER_CHACHA20_POLY1305
/*******************************************************************/
@ -363,11 +393,11 @@ typedef enum {
*/
#define _libssh2_cipher_init(ctx, type, iv, secret, encrypt) \
_libssh2_mbedtls_cipher_init(ctx, type, iv, secret, encrypt)
#define _libssh2_cipher_crypt(ctx, type, encrypt, block, blocklen) \
_libssh2_mbedtls_cipher_crypt(ctx, type, encrypt, block, blocklen)
_libssh2_mbedtls_cipher_init(ctx, type, iv, secret, encrypt)
#define _libssh2_cipher_crypt(ctx, type, encrypt, block, blocklen, fl) \
_libssh2_mbedtls_cipher_crypt(ctx, type, encrypt, block, blocklen, fl)
#define _libssh2_cipher_dtor(ctx) \
_libssh2_mbedtls_cipher_dtor(ctx)
_libssh2_mbedtls_cipher_dtor(ctx)
/*******************************************************************/
@ -382,21 +412,21 @@ typedef enum {
#define _libssh2_bn mbedtls_mpi
#define _libssh2_bn_init() \
_libssh2_mbedtls_bignum_init()
_libssh2_mbedtls_bignum_init()
#define _libssh2_bn_init_from_bin() \
_libssh2_mbedtls_bignum_init()
_libssh2_mbedtls_bignum_init()
#define _libssh2_bn_set_word(bn, word) \
mbedtls_mpi_lset(bn, word)
mbedtls_mpi_lset(bn, word)
#define _libssh2_bn_from_bin(bn, len, bin) \
mbedtls_mpi_read_binary(bn, bin, len)
mbedtls_mpi_read_binary(bn, bin, len)
#define _libssh2_bn_to_bin(bn, bin) \
mbedtls_mpi_write_binary(bn, bin, mbedtls_mpi_size(bn))
mbedtls_mpi_write_binary(bn, bin, mbedtls_mpi_size(bn))
#define _libssh2_bn_bytes(bn) \
mbedtls_mpi_size(bn)
mbedtls_mpi_size(bn)
#define _libssh2_bn_bits(bn) \
mbedtls_mpi_bitlen(bn)
mbedtls_mpi_bitlen(bn)
#define _libssh2_bn_free(bn) \
_libssh2_mbedtls_bignum_free(bn)
_libssh2_mbedtls_bignum_free(bn)
/*******************************************************************/
@ -404,12 +434,20 @@ typedef enum {
* mbedTLS backend: Diffie-Hellman support.
*/
/* Default generate and safe prime sizes for
diffie-hellman-group-exchange-sha1 */
#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
#define _libssh2_dh_ctx mbedtls_mpi *
#define libssh2_dh_init(dhctx) _libssh2_dh_init(dhctx)
#define libssh2_dh_key_pair(dhctx, public, g, p, group_order, bnctx) \
_libssh2_dh_key_pair(dhctx, public, g, p, group_order)
_libssh2_dh_key_pair(dhctx, public, g, p, group_order)
#define libssh2_dh_secret(dhctx, secret, f, p, bnctx) \
_libssh2_dh_secret(dhctx, secret, f, p)
_libssh2_dh_secret(dhctx, secret, f, p)
#define libssh2_dh_dtor(dhctx) _libssh2_dh_dtor(dhctx)
@ -425,32 +463,20 @@ void
_libssh2_mbedtls_free(void);
int
_libssh2_mbedtls_random(unsigned char *buf, int len);
_libssh2_mbedtls_random(unsigned char *buf, size_t len);
int
_libssh2_mbedtls_cipher_init(_libssh2_cipher_ctx *ctx,
_libssh2_cipher_type(type),
unsigned char *iv,
unsigned char *secret,
int encrypt);
int
_libssh2_mbedtls_cipher_crypt(_libssh2_cipher_ctx *ctx,
_libssh2_cipher_type(type),
int encrypt,
unsigned char *block,
size_t blocklen);
void
_libssh2_mbedtls_cipher_dtor(_libssh2_cipher_ctx *ctx);
int
_libssh2_mbedtls_hash_init(mbedtls_md_context_t *ctx,
mbedtls_md_type_t mdtype,
const unsigned char *key, unsigned long keylen);
mbedtls_md_type_t mdtype,
const unsigned char *key, size_t keylen);
int
_libssh2_mbedtls_hash_final(mbedtls_md_context_t *ctx, unsigned char *hash);
int
_libssh2_mbedtls_hash(const unsigned char *data, unsigned long datalen,
_libssh2_mbedtls_hash(const unsigned char *data, size_t datalen,
mbedtls_md_type_t mdtype, unsigned char *hash);
_libssh2_bn *
@ -459,110 +485,10 @@ _libssh2_mbedtls_bignum_init(void);
void
_libssh2_mbedtls_bignum_free(_libssh2_bn *bn);
int
_libssh2_mbedtls_rsa_new(libssh2_rsa_ctx **rsa,
const unsigned char *edata,
unsigned long elen,
const unsigned char *ndata,
unsigned long nlen,
const unsigned char *ddata,
unsigned long dlen,
const unsigned char *pdata,
unsigned long plen,
const unsigned char *qdata,
unsigned long qlen,
const unsigned char *e1data,
unsigned long e1len,
const unsigned char *e2data,
unsigned long e2len,
const unsigned char *coeffdata,
unsigned long coefflen);
int
_libssh2_mbedtls_rsa_new_private(libssh2_rsa_ctx **rsa,
LIBSSH2_SESSION *session,
const char *filename,
const unsigned char *passphrase);
int
_libssh2_mbedtls_rsa_new_private_frommemory(libssh2_rsa_ctx **rsa,
LIBSSH2_SESSION *session,
const char *filedata,
size_t filedata_len,
unsigned const char *passphrase);
int
_libssh2_mbedtls_rsa_sha1_verify(libssh2_rsa_ctx *rsa,
const unsigned char *sig,
unsigned long sig_len,
const unsigned char *m,
unsigned long m_len);
int
_libssh2_mbedtls_rsa_sha1_sign(LIBSSH2_SESSION *session,
libssh2_rsa_ctx *rsa,
const unsigned char *hash,
size_t hash_len,
unsigned char **signature,
size_t *signature_len);
void
_libssh2_mbedtls_rsa_free(libssh2_rsa_ctx *rsa);
int
_libssh2_mbedtls_pub_priv_keyfile(LIBSSH2_SESSION *session,
unsigned char **method,
size_t *method_len,
unsigned char **pubkeydata,
size_t *pubkeydata_len,
const char *privatekey,
const char *passphrase);
int
_libssh2_mbedtls_pub_priv_keyfilememory(LIBSSH2_SESSION *session,
unsigned char **method,
size_t *method_len,
unsigned char **pubkeydata,
size_t *pubkeydata_len,
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
@ -572,15 +498,17 @@ void
_libssh2_mbedtls_ecdsa_free(libssh2_ecdsa_ctx *ctx);
#endif /* LIBSSH2_ECDSA */
extern void
_libssh2_init_aes_ctr(void);
extern void
_libssh2_dh_init(_libssh2_dh_ctx *dhctx);
extern int
_libssh2_dh_key_pair(_libssh2_dh_ctx *dhctx, _libssh2_bn *public,
_libssh2_bn *g, _libssh2_bn *p, int group_order);
_libssh2_bn *g, _libssh2_bn *p, int group_order);
extern int
_libssh2_dh_secret(_libssh2_dh_ctx *dhctx, _libssh2_bn *secret,
_libssh2_bn *f, _libssh2_bn *p);
_libssh2_bn *f, _libssh2_bn *p);
extern void
_libssh2_dh_dtor(_libssh2_dh_ctx *dhctx);
#endif /* __LIBSSH2_MBEDTLS_H */
#endif /* LIBSSH2_MBEDTLS_H */

View file

@ -1,6 +1,6 @@
/* Copyright (c) 2004-2007 Sara Golemon <sarag@libssh2.org>
* Copyright (c) 2009-2019 by Daniel Stenberg
* Copyright (c) 2010 Simon Josefsson
/* Copyright (C) Sara Golemon <sarag@libssh2.org>
* Copyright (C) Daniel Stenberg
* Copyright (C) Simon Josefsson
* All rights reserved.
*
* Redistribution and use in source and binary forms,
@ -35,43 +35,65 @@
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
* USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
* OF SUCH DAMAGE.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#include "libssh2_priv.h"
#include "misc.h"
#include "blf.h"
#ifdef HAVE_STDLIB_H
#include <stdlib.h>
#endif
#ifdef HAVE_UNISTD_H
#include <unistd.h>
#endif
#ifdef HAVE_SYS_TIME_H
#include <sys/time.h>
#endif
#if defined(HAVE_DECL_SECUREZEROMEMORY) && HAVE_DECL_SECUREZEROMEMORY
#ifdef HAVE_WINDOWS_H
#include <windows.h>
#endif
#endif
#include <stdio.h>
#include <errno.h>
#include <assert.h>
#ifdef _WIN32
/* Force parameter type. */
#define recv(s, b, l, f) recv((s), (b), (int)(l), (f))
#define send(s, b, l, f) send((s), (b), (int)(l), (f))
#endif
/* snprintf not in Visual Studio CRT and _snprintf dangerously incompatible.
We provide a safe wrapper if snprintf not found */
#ifdef LIBSSH2_SNPRINTF
#include <stdarg.h>
/* Want safe, 'n += snprintf(b + n ...)' like function. If cp_max_len is 1
* then assume cp is pointing to a null char and do nothing. Returns number
* number of chars placed in cp excluding the trailing null char. So for
* cp_max_len > 0 the return value is always < cp_max_len; for cp_max_len
* <= 0 the return value is 0 (and no chars are written to cp). */
int _libssh2_snprintf(char *cp, size_t cp_max_len, const char *fmt, ...)
{
va_list args;
int n;
if(cp_max_len < 2)
return 0;
va_start(args, fmt);
n = vsnprintf(cp, cp_max_len, fmt, args);
va_end(args);
return (n < (int)cp_max_len) ? n : (int)(cp_max_len - 1);
}
#endif
int _libssh2_error_flags(LIBSSH2_SESSION* session, int errcode,
const char *errmsg, int errflags)
{
if(!session) {
if(errmsg)
fprintf(stderr, "Session is NULL, error: %s\n", errmsg);
return errcode;
}
if(session->err_flags & LIBSSH2_ERR_FLAG_DUP)
LIBSSH2_FREE(session, (char *)session->err_msg);
session->err_code = errcode;
session->err_flags = 0;
if((errmsg != NULL) && ((errflags & LIBSSH2_ERR_FLAG_DUP) != 0)) {
if(errmsg && ((errflags & LIBSSH2_ERR_FLAG_DUP) != 0)) {
size_t len = strlen(errmsg);
char *copy = LIBSSH2_ALLOC(session, len + 1);
if(copy) {
@ -91,8 +113,8 @@ int _libssh2_error_flags(LIBSSH2_SESSION* session, int errcode,
/* if this is EAGAIN and we're in non-blocking mode, don't generate
a debug output for this */
return errcode;
_libssh2_debug(session, LIBSSH2_TRACE_ERROR, "%d - %s", session->err_code,
session->err_msg);
_libssh2_debug((session, LIBSSH2_TRACE_ERROR, "%d - %s", session->err_code,
session->err_msg));
#endif
return errcode;
@ -103,8 +125,8 @@ int _libssh2_error(LIBSSH2_SESSION* session, int errcode, const char *errmsg)
return _libssh2_error_flags(session, errcode, errmsg, 0);
}
#ifdef WIN32
static int wsa2errno(void)
#ifdef _WIN32
int _libssh2_wsa2errno(void)
{
switch(WSAGetLastError()) {
case WSAEWOULDBLOCK:
@ -135,26 +157,32 @@ _libssh2_recv(libssh2_socket_t sock, void *buffer, size_t length,
{
ssize_t rc;
(void) abstract;
(void)abstract;
rc = recv(sock, buffer, length, flags);
#ifdef WIN32
if(rc < 0)
return -wsa2errno();
#else
if(rc < 0) {
int err;
#ifdef _WIN32
err = _libssh2_wsa2errno();
#else
err = errno;
#endif
/* Profiling tools that use SIGPROF can cause EINTR responses.
recv() does not modify its arguments when it returns EINTR,
but there may be data waiting, so the caller should try again */
if(err == EINTR)
return -EAGAIN;
/* Sometimes the first recv() function call sets errno to ENOENT on
Solaris and HP-UX */
if(errno == ENOENT)
if(err == ENOENT)
return -EAGAIN;
#ifdef EWOULDBLOCK /* For VMS and other special unixes */
else if(errno == EWOULDBLOCK)
return -EAGAIN;
else if(err == EWOULDBLOCK)
return -EAGAIN;
#endif
else
return -errno;
return -err;
}
#endif
return rc;
}
@ -168,33 +196,39 @@ _libssh2_send(libssh2_socket_t sock, const void *buffer, size_t length,
{
ssize_t rc;
(void) abstract;
(void)abstract;
rc = send(sock, buffer, length, flags);
#ifdef WIN32
if(rc < 0)
return -wsa2errno();
#else
if(rc < 0) {
int err;
#ifdef _WIN32
err = _libssh2_wsa2errno();
#else
err = errno;
#endif
/* Profiling tools that use SIGPROF can cause EINTR responses.
send() is defined as not yet sending any data when it returns EINTR,
so the caller should try again */
if(err == EINTR)
return -EAGAIN;
#ifdef EWOULDBLOCK /* For VMS and other special unixes */
if(errno == EWOULDBLOCK)
return -EAGAIN;
if(err == EWOULDBLOCK)
return -EAGAIN;
#endif
return -errno;
return -err;
}
#endif
return rc;
}
/* libssh2_ntohu32
*/
unsigned int
uint32_t
_libssh2_ntohu32(const unsigned char *buf)
{
return (((unsigned int)buf[0] << 24)
| ((unsigned int)buf[1] << 16)
| ((unsigned int)buf[2] << 8)
| ((unsigned int)buf[3]));
return ((uint32_t)buf[0] << 24)
| ((uint32_t)buf[1] << 16)
| ((uint32_t)buf[2] << 8)
| ((uint32_t)buf[3]);
}
@ -203,14 +237,14 @@ _libssh2_ntohu32(const unsigned char *buf)
libssh2_uint64_t
_libssh2_ntohu64(const unsigned char *buf)
{
unsigned long msl, lsl;
msl = ((libssh2_uint64_t)buf[0] << 24) | ((libssh2_uint64_t)buf[1] << 16)
| ((libssh2_uint64_t)buf[2] << 8) | (libssh2_uint64_t)buf[3];
lsl = ((libssh2_uint64_t)buf[4] << 24) | ((libssh2_uint64_t)buf[5] << 16)
| ((libssh2_uint64_t)buf[6] << 8) | (libssh2_uint64_t)buf[7];
return ((libssh2_uint64_t)msl <<32) | lsl;
return ((libssh2_uint64_t)buf[0] << 56)
| ((libssh2_uint64_t)buf[1] << 48)
| ((libssh2_uint64_t)buf[2] << 40)
| ((libssh2_uint64_t)buf[3] << 32)
| ((libssh2_uint64_t)buf[4] << 24)
| ((libssh2_uint64_t)buf[5] << 16)
| ((libssh2_uint64_t)buf[6] << 8)
| ((libssh2_uint64_t)buf[7]);
}
/* _libssh2_htonu32
@ -218,7 +252,7 @@ _libssh2_ntohu64(const unsigned char *buf)
void
_libssh2_htonu32(unsigned char *buf, uint32_t value)
{
buf[0] = (value >> 24) & 0xFF;
buf[0] = (unsigned char)((value >> 24) & 0xFF);
buf[1] = (value >> 16) & 0xFF;
buf[2] = (value >> 8) & 0xFF;
buf[3] = value & 0xFF;
@ -232,15 +266,70 @@ void _libssh2_store_u32(unsigned char **buf, uint32_t value)
*buf += sizeof(uint32_t);
}
/* _libssh2_store_u64
*/
void _libssh2_store_u64(unsigned char **buf, libssh2_uint64_t value)
{
unsigned char *ptr = *buf;
ptr[0] = (unsigned char)((value >> 56) & 0xFF);
ptr[1] = (unsigned char)((value >> 48) & 0xFF);
ptr[2] = (unsigned char)((value >> 40) & 0xFF);
ptr[3] = (unsigned char)((value >> 32) & 0xFF);
ptr[4] = (unsigned char)((value >> 24) & 0xFF);
ptr[5] = (unsigned char)((value >> 16) & 0xFF);
ptr[6] = (unsigned char)((value >> 8) & 0xFF);
ptr[7] = (unsigned char)(value & 0xFF);
*buf += sizeof(libssh2_uint64_t);
}
/* _libssh2_store_str
*/
void _libssh2_store_str(unsigned char **buf, const char *str, size_t len)
int _libssh2_store_str(unsigned char **buf, const char *str, size_t len)
{
_libssh2_store_u32(buf, (uint32_t)len);
if(len) {
memcpy(*buf, str, len);
*buf += len;
uint32_t len_stored = (uint32_t)len;
_libssh2_store_u32(buf, len_stored);
if(len_stored) {
memcpy(*buf, str, len_stored);
*buf += len_stored;
}
assert(len_stored == len);
return len_stored == len;
}
/* _libssh2_store_bignum2_bytes
*/
int _libssh2_store_bignum2_bytes(unsigned char **buf,
const unsigned char *bytes,
size_t len)
{
uint32_t len_stored;
uint32_t extraByte;
const unsigned char *p;
for(p = bytes; len > 0 && *p == 0; --len, ++p) {}
extraByte = (len > 0 && (p[0] & 0x80) != 0);
len_stored = (uint32_t)len;
if(extraByte && len_stored == UINT32_MAX)
len_stored--;
_libssh2_store_u32(buf, len_stored + extraByte);
if(extraByte) {
*buf[0] = 0;
*buf += 1;
}
if(len_stored) {
memcpy(*buf, p, len_stored);
*buf += len_stored;
}
assert(len_stored == len);
return len_stored == len;
}
/* Base64 Conversion */
@ -266,26 +355,46 @@ static const short base64_reverse_table[256] = {
/* libssh2_base64_decode
*
* Decode a base64 chunk and store it into a newly alloc'd buffer
* Legacy public function. DEPRECATED.
*/
LIBSSH2_API int
libssh2_base64_decode(LIBSSH2_SESSION *session, char **data,
unsigned int *datalen, const char *src,
unsigned int src_len)
{
unsigned char *s, *d;
short v;
int i = 0, len = 0;
int rc;
size_t dlen;
*data = LIBSSH2_ALLOC(session, (3 * src_len / 4) + 1);
rc = _libssh2_base64_decode(session, data, &dlen, src, src_len);
if(datalen)
*datalen = (unsigned int)dlen;
return rc;
}
/* _libssh2_base64_decode
*
* Decode a base64 chunk and store it into a newly alloc'd buffer
*/
int _libssh2_base64_decode(LIBSSH2_SESSION *session,
char **data, size_t *datalen,
const char *src, size_t src_len)
{
unsigned char *d;
const char *s;
short v;
ssize_t i = 0, len = 0;
*data = LIBSSH2_ALLOC(session, ((src_len / 4) * 3) + 1);
d = (unsigned char *) *data;
if(!d) {
return _libssh2_error(session, LIBSSH2_ERROR_ALLOC,
"Unable to allocate memory for base64 decoding");
}
for(s = (unsigned char *) src; ((char *) s) < (src + src_len); s++) {
v = base64_reverse_table[*s];
for(s = src; s < (src + src_len); s++) {
v = base64_reverse_table[(unsigned char)*s];
if(v < 0)
continue;
switch(i % 4) {
@ -293,15 +402,15 @@ libssh2_base64_decode(LIBSSH2_SESSION *session, char **data,
d[len] = (unsigned char)(v << 2);
break;
case 1:
d[len++] |= v >> 4;
d[len++] |= (unsigned char)(v >> 4);
d[len] = (unsigned char)(v << 4);
break;
case 2:
d[len++] |= v >> 2;
d[len++] |= (unsigned char)(v >> 2);
d[len] = (unsigned char)(v << 6);
break;
case 3:
d[len++] |= v;
d[len++] |= (unsigned char)v;
break;
}
i++;
@ -320,10 +429,10 @@ libssh2_base64_decode(LIBSSH2_SESSION *session, char **data,
/* ---- Base64 Encoding/Decoding Table --- */
static const char table64[]=
"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
/*
* _libssh2_base64_encode()
* _libssh2_base64_encode
*
* Returns the length of the newly created base64 string. The third argument
* is a pointer to an allocated area holding the base64 data. If something
@ -344,11 +453,11 @@ size_t _libssh2_base64_encode(LIBSSH2_SESSION *session,
*outptr = NULL; /* set to NULL in case of failure before we reach the
end */
if(0 == insize)
if(insize == 0)
insize = strlen(indata);
base64data = output = LIBSSH2_ALLOC(session, insize * 4 / 3 + 4);
if(NULL == output)
if(!output)
return 0;
while(insize > 0) {
@ -372,22 +481,22 @@ size_t _libssh2_base64_encode(LIBSSH2_SESSION *session,
switch(inputparts) {
case 1: /* only one byte read */
snprintf(output, 5, "%c%c==",
table64[obuf[0]],
table64[obuf[1]]);
output[0] = table64[obuf[0]];
output[1] = table64[obuf[1]];
output[2] = '=';
output[3] = '=';
break;
case 2: /* two bytes read */
snprintf(output, 5, "%c%c%c=",
table64[obuf[0]],
table64[obuf[1]],
table64[obuf[2]]);
output[0] = table64[obuf[0]];
output[1] = table64[obuf[1]];
output[2] = table64[obuf[2]];
output[3] = '=';
break;
default:
snprintf(output, 5, "%c%c%c%c",
table64[obuf[0]],
table64[obuf[1]],
table64[obuf[2]],
table64[obuf[3]]);
output[0] = table64[obuf[0]];
output[1] = table64[obuf[1]];
output[2] = table64[obuf[2]];
output[3] = table64[obuf[3]];
break;
}
output += 4;
@ -425,13 +534,14 @@ libssh2_trace_sethandler(LIBSSH2_SESSION *session, void *handler_context,
}
void
_libssh2_debug(LIBSSH2_SESSION * session, int context, const char *format, ...)
_libssh2_debug_low(LIBSSH2_SESSION * session, int context, const char *format,
...)
{
char buffer[1536];
int len, msglen, buflen = sizeof(buffer);
va_list vargs;
struct timeval now;
static int firstsec;
static long firstsec;
static const char *const contexts[] = {
"Unknown",
"Transport",
@ -461,7 +571,7 @@ _libssh2_debug(LIBSSH2_SESSION * session, int context, const char *format, ...)
}
}
_libssh2_gettimeofday(&now, NULL);
gettimeofday(&now, NULL);
if(!firstsec) {
firstsec = now.tv_sec;
}
@ -492,8 +602,8 @@ _libssh2_debug(LIBSSH2_SESSION * session, int context, const char *format, ...)
LIBSSH2_API int
libssh2_trace(LIBSSH2_SESSION * session, int bitmask)
{
(void) session;
(void) bitmask;
(void)session;
(void)bitmask;
return 0;
}
@ -501,9 +611,9 @@ LIBSSH2_API int
libssh2_trace_sethandler(LIBSSH2_SESSION *session, void *handler_context,
libssh2_trace_handler_func callback)
{
(void) session;
(void) handler_context;
(void) callback;
(void)session;
(void)handler_context;
(void)callback;
return 0;
}
#endif
@ -600,10 +710,10 @@ void _libssh2_list_insert(struct list_node *after, /* insert before this */
#endif
/* this define is defined in misc.h for the correct platforms */
#ifdef LIBSSH2_GETTIMEOFDAY_WIN32
/* Defined in libssh2_priv.h for the correct platforms */
#ifdef LIBSSH2_GETTIMEOFDAY
/*
* gettimeofday
* _libssh2_gettimeofday
* Implementation according to:
* The Open Group Base Specifications Issue 6
* IEEE Std 1003.1, 2004 Edition
@ -624,27 +734,31 @@ void _libssh2_list_insert(struct list_node *after, /* insert before this */
* Danny Smith <dannysmith@users.sourceforge.net>
*/
/* Offset between 1/1/1601 and 1/1/1970 in 100 nanosec units */
#define _W32_FT_OFFSET (116444736000000000)
int __cdecl _libssh2_gettimeofday(struct timeval *tp, void *tzp)
int _libssh2_gettimeofday(struct timeval *tp, void *tzp)
{
union {
unsigned __int64 ns100; /*time since 1 Jan 1601 in 100ns units */
FILETIME ft;
} _now;
(void)tzp;
if(tp) {
#ifdef _WIN32
/* Offset between 1601-01-01 and 1970-01-01 in 100 nanosec units */
#define _WIN32_FT_OFFSET (116444736000000000)
union {
libssh2_uint64_t ns100; /* time since 1 Jan 1601 in 100ns units */
FILETIME ft;
} _now;
GetSystemTimeAsFileTime(&_now.ft);
tp->tv_usec = (long)((_now.ns100 / 10) % 1000000);
tp->tv_sec = (long)((_now.ns100 - _W32_FT_OFFSET) / 10000000);
tp->tv_sec = (long)((_now.ns100 - _WIN32_FT_OFFSET) / 10000000);
#else
/* Platforms without a native implementation or local replacement */
tp->tv_usec = 0;
tp->tv_sec = 0;
#endif
}
/* Always return 0 as per Open Group Base Specifications Issue 6.
Do not set errno on error. */
return 0;
}
#endif
void *_libssh2_calloc(LIBSSH2_SESSION* session, size_t size)
@ -687,34 +801,23 @@ void _libssh2_aes_ctr_increment(unsigned char *ctr,
}
}
#ifdef WIN32
static void * (__cdecl * const volatile memset_libssh)(void *, int, size_t) =
memset;
#else
#ifdef LIBSSH2_MEMZERO
static void * (* const volatile memset_libssh)(void *, int, size_t) = memset;
#endif
void _libssh2_explicit_zero(void *buf, size_t size)
void _libssh2_memzero(void *buf, size_t size)
{
#if defined(HAVE_DECL_SECUREZEROMEMORY) && HAVE_DECL_SECUREZEROMEMORY
SecureZeroMemory(buf, size);
(void)memset_libssh; /* Silence unused variable warning */
#elif defined(HAVE_MEMSET_S)
(void)memset_s(buf, size, 0, size);
(void)memset_libssh; /* Silence unused variable warning */
#else
memset_libssh(buf, 0, size);
#endif
}
#endif
/* String buffer */
struct string_buf* _libssh2_string_buf_new(LIBSSH2_SESSION *session)
struct string_buf *_libssh2_string_buf_new(LIBSSH2_SESSION *session)
{
struct string_buf *ret;
ret = _libssh2_calloc(session, sizeof(*ret));
if(ret == NULL)
if(!ret)
return NULL;
return ret;
@ -722,16 +825,39 @@ struct string_buf* _libssh2_string_buf_new(LIBSSH2_SESSION *session)
void _libssh2_string_buf_free(LIBSSH2_SESSION *session, struct string_buf *buf)
{
if(buf == NULL)
if(!buf)
return;
if(buf->data != NULL)
if(buf->data)
LIBSSH2_FREE(session, buf->data);
LIBSSH2_FREE(session, buf);
buf = NULL;
}
int _libssh2_get_byte(struct string_buf *buf, unsigned char *out)
{
if(!_libssh2_check_length(buf, 1)) {
return -1;
}
*out = buf->dataptr[0];
buf->dataptr += 1;
return 0;
}
int _libssh2_get_boolean(struct string_buf *buf, unsigned char *out)
{
if(!_libssh2_check_length(buf, 1)) {
return -1;
}
*out = buf->dataptr[0] == 0 ? 0 : 1;
buf->dataptr += 1;
return 0;
}
int _libssh2_get_u32(struct string_buf *buf, uint32_t *out)
{
if(!_libssh2_check_length(buf, 4)) {
@ -769,7 +895,7 @@ int _libssh2_get_string(struct string_buf *buf, unsigned char **outbuf,
size_t *outlen)
{
uint32_t data_len;
if(_libssh2_get_u32(buf, &data_len) != 0) {
if(!buf || _libssh2_get_u32(buf, &data_len) != 0) {
return -1;
}
if(!_libssh2_check_length(buf, data_len)) {
@ -794,12 +920,17 @@ int _libssh2_copy_string(LIBSSH2_SESSION *session, struct string_buf *buf,
return -1;
}
*outbuf = LIBSSH2_ALLOC(session, str_len);
if(*outbuf) {
memcpy(*outbuf, str, str_len);
if(str_len) {
*outbuf = LIBSSH2_ALLOC(session, str_len);
if(*outbuf) {
memcpy(*outbuf, str, str_len);
}
else {
return -1;
}
}
else {
return -1;
*outbuf = NULL;
}
if(outlen)
@ -848,25 +979,11 @@ int _libssh2_check_length(struct string_buf *buf, size_t len)
{
unsigned char *endp = &buf->data[buf->len];
size_t left = endp - buf->dataptr;
return ((len <= left) && (left <= buf->len));
return (len <= left) && (left <= buf->len);
}
/* Wrappers */
int _libssh2_bcrypt_pbkdf(const char *pass,
size_t passlen,
const uint8_t *salt,
size_t saltlen,
uint8_t *key,
size_t keylen,
unsigned int rounds)
int _libssh2_eob(struct string_buf *buf)
{
/* defined in bcrypt_pbkdf.c */
return bcrypt_pbkdf(pass,
passlen,
salt,
saltlen,
key,
keylen,
rounds);
unsigned char *endp = &buf->data[buf->len];
return buf->dataptr >= endp;
}

View file

@ -1,7 +1,6 @@
#ifndef __LIBSSH2_MISC_H
#define __LIBSSH2_MISC_H
/* Copyright (c) 2009-2019 by Daniel Stenberg
*
#ifndef LIBSSH2_MISC_H
#define LIBSSH2_MISC_H
/* Copyright (C) Daniel Stenberg
* All rights reserved.
*
* Redistribution and use in source and binary forms,
@ -36,8 +35,29 @@
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
* USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
* OF SUCH DAMAGE.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#ifdef LIBSSH2_NO_CLEAR_MEMORY
#define _libssh2_explicit_zero(buf, size) do { \
(void)(buf); \
(void)(size); \
} while(0)
#elif defined(_WIN32)
#define _libssh2_explicit_zero(buf, size) SecureZeroMemory(buf, size)
#elif defined(HAVE_EXPLICIT_BZERO)
#define _libssh2_explicit_zero(buf, size) explicit_bzero(buf, size)
#elif defined(HAVE_EXPLICIT_MEMSET)
#define _libssh2_explicit_zero(buf, size) (void)explicit_memset(buf, 0, size)
#elif defined(HAVE_MEMSET_S)
#define _libssh2_explicit_zero(buf, size) (void)memset_s(buf, size, 0, size)
#else
#define LIBSSH2_MEMZERO
void _libssh2_memzero(void *buf, size_t size);
#define _libssh2_explicit_zero(buf, size) _libssh2_memzero(buf, size)
#endif
struct list_head {
struct list_node *last;
struct list_node *first;
@ -59,6 +79,11 @@ int _libssh2_error_flags(LIBSSH2_SESSION* session, int errcode,
const char *errmsg, int errflags);
int _libssh2_error(LIBSSH2_SESSION* session, int errcode, const char *errmsg);
#ifdef _WIN32
/* Convert Win32 WSAGetLastError to errno equivalent */
int _libssh2_wsa2errno(void);
#endif
void _libssh2_list_init(struct list_head *head);
/* add a node last in the list */
@ -77,20 +102,28 @@ void *_libssh2_list_prev(struct list_node *node);
/* remove this node from the list */
void _libssh2_list_remove(struct list_node *entry);
int _libssh2_base64_decode(LIBSSH2_SESSION *session,
char **data, size_t *datalen,
const char *src, size_t src_len);
size_t _libssh2_base64_encode(LIBSSH2_SESSION *session,
const char *inp, size_t insize, char **outptr);
unsigned int _libssh2_ntohu32(const unsigned char *buf);
uint32_t _libssh2_ntohu32(const unsigned char *buf);
libssh2_uint64_t _libssh2_ntohu64(const unsigned char *buf);
void _libssh2_htonu32(unsigned char *buf, uint32_t val);
void _libssh2_store_u32(unsigned char **buf, uint32_t value);
void _libssh2_store_str(unsigned char **buf, const char *str, size_t len);
void _libssh2_store_u64(unsigned char **buf, libssh2_uint64_t value);
int _libssh2_store_str(unsigned char **buf, const char *str, size_t len);
int _libssh2_store_bignum2_bytes(unsigned char **buf,
const unsigned char *bytes,
size_t len);
void *_libssh2_calloc(LIBSSH2_SESSION *session, size_t size);
void _libssh2_explicit_zero(void *buf, size_t size);
struct string_buf* _libssh2_string_buf_new(LIBSSH2_SESSION *session);
struct string_buf *_libssh2_string_buf_new(LIBSSH2_SESSION *session);
void _libssh2_string_buf_free(LIBSSH2_SESSION *session,
struct string_buf *buf);
int _libssh2_get_boolean(struct string_buf *buf, unsigned char *out);
int _libssh2_get_byte(struct string_buf *buf, unsigned char *out);
int _libssh2_get_u32(struct string_buf *buf, uint32_t *out);
int _libssh2_get_u64(struct string_buf *buf, libssh2_uint64_t *out);
int _libssh2_match_string(struct string_buf *buf, const char *match);
@ -101,19 +134,7 @@ int _libssh2_copy_string(LIBSSH2_SESSION* session, struct string_buf *buf,
int _libssh2_get_bignum_bytes(struct string_buf *buf, unsigned char **outbuf,
size_t *outlen);
int _libssh2_check_length(struct string_buf *buf, size_t requested_len);
#if defined(LIBSSH2_WIN32) && !defined(__MINGW32__) && !defined(__CYGWIN__)
/* provide a private one */
#undef HAVE_GETTIMEOFDAY
int __cdecl _libssh2_gettimeofday(struct timeval *tp, void *tzp);
#define HAVE_LIBSSH2_GETTIMEOFDAY
#define LIBSSH2_GETTIMEOFDAY_WIN32 /* enable the win32 implementation */
#else
#ifdef HAVE_GETTIMEOFDAY
#define _libssh2_gettimeofday(x,y) gettimeofday(x,y)
#define HAVE_LIBSSH2_GETTIMEOFDAY
#endif
#endif
int _libssh2_eob(struct string_buf *buf);
void _libssh2_xor_data(unsigned char *output,
const unsigned char *input1,
@ -122,4 +143,4 @@ void _libssh2_xor_data(unsigned char *output,
void _libssh2_aes_ctr_increment(unsigned char *ctr, size_t length);
#endif /* _LIBSSH2_MISC_H */
#endif /* LIBSSH2_MISC_H */

File diff suppressed because it is too large Load diff

View file

@ -1,9 +1,8 @@
#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.
*
* Author: Simon Josefsson
#ifndef LIBSSH2_OPENSSL_H
#define LIBSSH2_OPENSSL_H
/* Copyright (C) Simon Josefsson
* Copyright (C) The Written Word, Inc.
* All rights reserved.
*
* Redistribution and use in source and binary forms,
* with or without modification, are permitted provided
@ -37,8 +36,64 @@
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
* USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
* OF SUCH DAMAGE.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#define LIBSSH2_CRYPTO_ENGINE libssh2_openssl
/* disable deprecated warnings in OpenSSL 3 */
#define OPENSSL_SUPPRESS_DEPRECATED
#ifdef LIBSSH2_WOLFSSL
#include <wolfssl/options.h>
#include <wolfssl/openssl/ecdh.h>
#if defined(NO_DSA) || defined(HAVE_FIPS)
#define OPENSSL_NO_DSA
#endif
#if defined(NO_MD5) || defined(HAVE_FIPS)
#define OPENSSL_NO_MD5
#endif
#if !defined(WOLFSSL_RIPEMD) || defined(HAVE_FIPS)
#define OPENSSL_NO_RIPEMD
#endif
#if defined(NO_RC4) || defined(HAVE_FIPS)
#define OPENSSL_NO_RC4
#endif
#ifdef NO_DES3
#define OPENSSL_NO_DES
#endif
/* wolfSSL doesn't support Blowfish or CAST. */
#define OPENSSL_NO_BF
#define OPENSSL_NO_CAST
/* wolfSSL has no engine framework. */
#define OPENSSL_NO_ENGINE
#include <wolfssl/openssl/opensslconf.h>
#include <wolfssl/openssl/sha.h>
#include <wolfssl/openssl/rsa.h>
#ifndef OPENSSL_NO_DSA
#include <wolfssl/openssl/dsa.h>
#endif
#ifndef OPENSSL_NO_MD5
#include <wolfssl/openssl/md5.h>
#endif
#include <wolfssl/openssl/err.h>
#include <wolfssl/openssl/evp.h>
#include <wolfssl/openssl/hmac.h>
#include <wolfssl/openssl/bn.h>
#include <wolfssl/openssl/pem.h>
#include <wolfssl/openssl/rand.h>
#else /* !LIBSSH2_WOLFSSL */
#include <openssl/opensslconf.h>
#include <openssl/sha.h>
#include <openssl/rsa.h>
@ -51,21 +106,37 @@
#ifndef OPENSSL_NO_MD5
#include <openssl/md5.h>
#endif
#include <openssl/err.h>
#include <openssl/evp.h>
#include <openssl/hmac.h>
#include <openssl/bn.h>
#include <openssl/pem.h>
#include <openssl/rand.h>
#if OPENSSL_VERSION_NUMBER >= 0x10100000L && \
!defined(LIBRESSL_VERSION_NUMBER)
#if OPENSSL_VERSION_NUMBER >= 0x30000000L
#define USE_OPENSSL_3 1
#include <openssl/core_names.h>
#endif
#endif /* LIBSSH2_WOLFSSL */
#if (OPENSSL_VERSION_NUMBER >= 0x10100000L && \
!defined(LIBRESSL_VERSION_NUMBER)) || defined(LIBSSH2_WOLFSSL) || \
(defined(LIBRESSL_VERSION_NUMBER) && \
LIBRESSL_VERSION_NUMBER >= 0x3050000fL)
/* For wolfSSL, whether the structs are truly opaque or not, it's best to not
* rely on their internal data members being exposed publicly. */
# define HAVE_OPAQUE_STRUCTS 1
#endif
#ifdef OPENSSL_NO_RSA
# define LIBSSH2_RSA 0
# define LIBSSH2_RSA_SHA1 0
# define LIBSSH2_RSA_SHA2 0
#else
# define LIBSSH2_RSA 1
# define LIBSSH2_RSA_SHA1 1
# define LIBSSH2_RSA_SHA2 1
#endif
#ifdef OPENSSL_NO_DSA
@ -74,14 +145,16 @@
# define LIBSSH2_DSA 1
#endif
#ifdef OPENSSL_NO_ECDSA
#if defined(OPENSSL_NO_ECDSA) || defined(OPENSSL_NO_EC)
# define LIBSSH2_ECDSA 0
#else
# define LIBSSH2_ECDSA 1
#endif
#if OPENSSL_VERSION_NUMBER >= 0x10101000L && \
!defined(LIBRESSL_VERSION_NUMBER)
#if (OPENSSL_VERSION_NUMBER >= 0x10101000L && \
!defined(LIBRESSL_VERSION_NUMBER)) || \
(defined(LIBRESSL_VERSION_NUMBER) && \
LIBRESSL_VERSION_NUMBER >= 0x3070000fL)
# define LIBSSH2_ED25519 1
#else
# define LIBSSH2_ED25519 0
@ -94,7 +167,7 @@
# define LIBSSH2_MD5 1
#endif
#ifdef OPENSSL_NO_RIPEMD
#if defined(OPENSSL_NO_RIPEMD) || defined(OPENSSL_NO_RMD160)
# define LIBSSH2_HMAC_RIPEMD 0
#else
# define LIBSSH2_HMAC_RIPEMD 1
@ -103,12 +176,24 @@
#define LIBSSH2_HMAC_SHA256 1
#define LIBSSH2_HMAC_SHA512 1
#if OPENSSL_VERSION_NUMBER >= 0x00907000L && !defined(OPENSSL_NO_AES)
#if (OPENSSL_VERSION_NUMBER >= 0x00907000L && !defined(OPENSSL_NO_AES)) || \
(defined(LIBSSH2_WOLFSSL) && defined(WOLFSSL_AES_COUNTER))
# define LIBSSH2_AES_CTR 1
# define LIBSSH2_AES 1
# define LIBSSH2_AES_CBC 1
#else
# define LIBSSH2_AES_CTR 0
# define LIBSSH2_AES 0
# define LIBSSH2_AES_CBC 0
#endif
/* wolfSSL v5.4.0 is required due to possibly this bug:
https://github.com/wolfSSL/wolfssl/pull/5205
Before this release, all libssh2 tests crash with AES-GCM enabled */
#if (OPENSSL_VERSION_NUMBER >= 0x01010100fL && !defined(OPENSSL_NO_AES)) || \
(defined(LIBSSH2_WOLFSSL) && LIBWOLFSSL_VERSION_HEX >= 0x05004000 && \
defined(HAVE_AESGCM) && defined(WOLFSSL_AESGCM_STREAM))
# define LIBSSH2_AES_GCM 1
#else
# define LIBSSH2_AES_GCM 0
#endif
#ifdef OPENSSL_NO_BF
@ -135,9 +220,12 @@
# define LIBSSH2_3DES 1
#endif
#include "crypto_config.h"
#define EC_MAX_POINT_LEN ((528 * 2 / 8) + 1)
#define _libssh2_random(buf, len) (RAND_bytes((buf), (len)) == 1 ? 0 : -1)
#define _libssh2_random(buf, len) \
_libssh2_openssl_random((buf), (len))
#define libssh2_prepare_iovec(vec, len) /* Empty. */
@ -149,19 +237,15 @@
/* returns 0 in case of failure */
int _libssh2_sha1_init(libssh2_sha1_ctx *ctx);
#define libssh2_sha1_init(x) _libssh2_sha1_init(x)
#ifdef HAVE_OPAQUE_STRUCTS
#define libssh2_sha1_update(ctx, data, len) EVP_DigestUpdate(ctx, data, len)
#define libssh2_sha1_final(ctx, out) do { \
EVP_DigestFinal(ctx, out, NULL); \
EVP_MD_CTX_free(ctx); \
} while(0)
#else
#define libssh2_sha1_update(ctx, data, len) EVP_DigestUpdate(&(ctx), data, len)
#define libssh2_sha1_final(ctx, out) EVP_DigestFinal(&(ctx), out, NULL)
#endif
int _libssh2_sha1(const unsigned char *message, unsigned long len,
int _libssh2_sha1_update(libssh2_sha1_ctx *ctx,
const void *data, size_t len);
int _libssh2_sha1_final(libssh2_sha1_ctx *ctx, unsigned char *out);
int _libssh2_sha1(const unsigned char *message, size_t len,
unsigned char *out);
#define libssh2_sha1_init(x) _libssh2_sha1_init(x)
#define libssh2_sha1_update(ctx, data, len) \
_libssh2_sha1_update(&(ctx), data, len)
#define libssh2_sha1_final(ctx, out) _libssh2_sha1_final(&(ctx), out)
#define libssh2_sha1(x,y,z) _libssh2_sha1(x,y,z)
#ifdef HAVE_OPAQUE_STRUCTS
@ -172,20 +256,15 @@ int _libssh2_sha1(const unsigned char *message, unsigned long len,
/* returns 0 in case of failure */
int _libssh2_sha256_init(libssh2_sha256_ctx *ctx);
int _libssh2_sha256_update(libssh2_sha256_ctx *ctx,
const void *data, size_t len);
int _libssh2_sha256_final(libssh2_sha256_ctx *ctx, unsigned char *out);
int _libssh2_sha256(const unsigned char *message, size_t len,
unsigned char *out);
#define libssh2_sha256_init(x) _libssh2_sha256_init(x)
#ifdef HAVE_OPAQUE_STRUCTS
#define libssh2_sha256_update(ctx, data, len) EVP_DigestUpdate(ctx, data, len)
#define libssh2_sha256_final(ctx, out) do { \
EVP_DigestFinal(ctx, out, NULL); \
EVP_MD_CTX_free(ctx); \
} while(0)
#else
#define libssh2_sha256_update(ctx, data, len) \
EVP_DigestUpdate(&(ctx), data, len)
#define libssh2_sha256_final(ctx, out) EVP_DigestFinal(&(ctx), out, NULL)
#endif
int _libssh2_sha256(const unsigned char *message, unsigned long len,
unsigned char *out);
_libssh2_sha256_update(&(ctx), data, len)
#define libssh2_sha256_final(ctx, out) _libssh2_sha256_final(&(ctx), out)
#define libssh2_sha256(x,y,z) _libssh2_sha256(x,y,z)
#ifdef HAVE_OPAQUE_STRUCTS
@ -196,20 +275,15 @@ int _libssh2_sha256(const unsigned char *message, unsigned long len,
/* returns 0 in case of failure */
int _libssh2_sha384_init(libssh2_sha384_ctx *ctx);
#define libssh2_sha384_init(x) _libssh2_sha384_init(x)
#ifdef HAVE_OPAQUE_STRUCTS
#define libssh2_sha384_update(ctx, data, len) EVP_DigestUpdate(ctx, data, len)
#define libssh2_sha384_final(ctx, out) do { \
EVP_DigestFinal(ctx, out, NULL); \
EVP_MD_CTX_free(ctx); \
} while(0)
#else
#define libssh2_sha384_update(ctx, data, len) \
EVP_DigestUpdate(&(ctx), data, len)
#define libssh2_sha384_final(ctx, out) EVP_DigestFinal(&(ctx), out, NULL)
#endif
int _libssh2_sha384(const unsigned char *message, unsigned long len,
int _libssh2_sha384_update(libssh2_sha384_ctx *ctx,
const void *data, size_t len);
int _libssh2_sha384_final(libssh2_sha384_ctx *ctx, unsigned char *out);
int _libssh2_sha384(const unsigned char *message, size_t len,
unsigned char *out);
#define libssh2_sha384_init(x) _libssh2_sha384_init(x)
#define libssh2_sha384_update(ctx, data, len) \
_libssh2_sha384_update(&(ctx), data, len)
#define libssh2_sha384_final(ctx, out) _libssh2_sha384_final(&(ctx), out)
#define libssh2_sha384(x,y,z) _libssh2_sha384(x,y,z)
#ifdef HAVE_OPAQUE_STRUCTS
@ -220,22 +294,18 @@ int _libssh2_sha384(const unsigned char *message, unsigned long len,
/* returns 0 in case of failure */
int _libssh2_sha512_init(libssh2_sha512_ctx *ctx);
#define libssh2_sha512_init(x) _libssh2_sha512_init(x)
#ifdef HAVE_OPAQUE_STRUCTS
#define libssh2_sha512_update(ctx, data, len) EVP_DigestUpdate(ctx, data, len)
#define libssh2_sha512_final(ctx, out) do { \
EVP_DigestFinal(ctx, out, NULL); \
EVP_MD_CTX_free(ctx); \
} while(0)
#else
#define libssh2_sha512_update(ctx, data, len) \
EVP_DigestUpdate(&(ctx), data, len)
#define libssh2_sha512_final(ctx, out) EVP_DigestFinal(&(ctx), out, NULL)
#endif
int _libssh2_sha512(const unsigned char *message, unsigned long len,
int _libssh2_sha512_update(libssh2_sha512_ctx *ctx,
const void *data, size_t len);
int _libssh2_sha512_final(libssh2_sha512_ctx *ctx, unsigned char *out);
int _libssh2_sha512(const unsigned char *message, size_t len,
unsigned char *out);
#define libssh2_sha512_init(x) _libssh2_sha512_init(x)
#define libssh2_sha512_update(ctx, data, len) \
_libssh2_sha512_update(&(ctx), data, len)
#define libssh2_sha512_final(ctx, out) _libssh2_sha512_final(&(ctx), out)
#define libssh2_sha512(x,y,z) _libssh2_sha512(x,y,z)
#if LIBSSH2_MD5 || LIBSSH2_MD5_PEM
#ifdef HAVE_OPAQUE_STRUCTS
#define libssh2_md5_ctx EVP_MD_CTX *
#else
@ -244,74 +314,63 @@ int _libssh2_sha512(const unsigned char *message, unsigned long len,
/* returns 0 in case of failure */
int _libssh2_md5_init(libssh2_md5_ctx *ctx);
int _libssh2_md5_update(libssh2_md5_ctx *ctx,
const void *data, size_t len);
int _libssh2_md5_final(libssh2_md5_ctx *ctx, unsigned char *out);
#define libssh2_md5_init(x) _libssh2_md5_init(x)
#ifdef HAVE_OPAQUE_STRUCTS
#define libssh2_md5_update(ctx, data, len) EVP_DigestUpdate(ctx, data, len)
#define libssh2_md5_final(ctx, out) do { \
EVP_DigestFinal(ctx, out, NULL); \
EVP_MD_CTX_free(ctx); \
} while(0)
#else
#define libssh2_md5_update(ctx, data, len) EVP_DigestUpdate(&(ctx), data, len)
#define libssh2_md5_final(ctx, out) EVP_DigestFinal(&(ctx), out, NULL)
#endif
#define libssh2_md5_update(ctx, data, len) \
_libssh2_md5_update(&(ctx), data, len)
#define libssh2_md5_final(ctx, out) _libssh2_md5_final(&(ctx), out)
#endif /* LIBSSH2_MD5 || LIBSSH2_MD5_PEM */
#ifdef HAVE_OPAQUE_STRUCTS
#ifdef USE_OPENSSL_3
#define libssh2_hmac_ctx EVP_MAC_CTX *
#elif defined(HAVE_OPAQUE_STRUCTS)
#define libssh2_hmac_ctx HMAC_CTX *
#define libssh2_hmac_ctx_init(ctx) ctx = HMAC_CTX_new()
#define libssh2_hmac_sha1_init(ctx, key, keylen) \
HMAC_Init_ex(*(ctx), key, keylen, EVP_sha1(), NULL)
#define libssh2_hmac_md5_init(ctx, key, keylen) \
HMAC_Init_ex(*(ctx), key, keylen, EVP_md5(), NULL)
#define libssh2_hmac_ripemd160_init(ctx, key, keylen) \
HMAC_Init_ex(*(ctx), key, keylen, EVP_ripemd160(), NULL)
#define libssh2_hmac_sha256_init(ctx, key, keylen) \
HMAC_Init_ex(*(ctx), key, keylen, EVP_sha256(), NULL)
#define libssh2_hmac_sha512_init(ctx, key, keylen) \
HMAC_Init_ex(*(ctx), key, keylen, EVP_sha512(), NULL)
#define libssh2_hmac_update(ctx, data, datalen) \
HMAC_Update(ctx, data, datalen)
#define libssh2_hmac_final(ctx, data) HMAC_Final(ctx, data, NULL)
#define libssh2_hmac_cleanup(ctx) HMAC_CTX_free(*(ctx))
#else
#else /* !HAVE_OPAQUE_STRUCTS */
#define libssh2_hmac_ctx HMAC_CTX
#define libssh2_hmac_ctx_init(ctx) \
HMAC_CTX_init(&ctx)
#define libssh2_hmac_sha1_init(ctx, key, keylen) \
HMAC_Init_ex(ctx, key, keylen, EVP_sha1(), NULL)
#define libssh2_hmac_md5_init(ctx, key, keylen) \
HMAC_Init_ex(ctx, key, keylen, EVP_md5(), NULL)
#define libssh2_hmac_ripemd160_init(ctx, key, keylen) \
HMAC_Init_ex(ctx, key, keylen, EVP_ripemd160(), NULL)
#define libssh2_hmac_sha256_init(ctx, key, keylen) \
HMAC_Init_ex(ctx, key, keylen, EVP_sha256(), NULL)
#define libssh2_hmac_sha512_init(ctx, key, keylen) \
HMAC_Init_ex(ctx, key, keylen, EVP_sha512(), NULL)
#define libssh2_hmac_update(ctx, data, datalen) \
HMAC_Update(&(ctx), data, datalen)
#define libssh2_hmac_final(ctx, data) HMAC_Final(&(ctx), data, NULL)
#define libssh2_hmac_cleanup(ctx) HMAC_cleanup(ctx)
#endif
#endif /* USE_OPENSSL_3 */
extern void _libssh2_openssl_crypto_init(void);
extern void _libssh2_openssl_crypto_exit(void);
#define libssh2_crypto_init() _libssh2_openssl_crypto_init()
#define libssh2_crypto_exit() _libssh2_openssl_crypto_exit()
#if LIBSSH2_RSA
#ifdef USE_OPENSSL_3
#define libssh2_rsa_ctx EVP_PKEY
#define _libssh2_rsa_free(rsactx) EVP_PKEY_free(rsactx)
#else
#define libssh2_rsa_ctx RSA
#define _libssh2_rsa_free(rsactx) RSA_free(rsactx)
#endif
#endif /* LIBSSH2_RSA */
#if LIBSSH2_DSA
#ifdef USE_OPENSSL_3
#define libssh2_dsa_ctx EVP_PKEY
#define _libssh2_dsa_free(rsactx) EVP_PKEY_free(rsactx)
#else
#define libssh2_dsa_ctx DSA
#define _libssh2_dsa_free(dsactx) DSA_free(dsactx)
#endif
#endif /* LIBSSH2_DSA */
#if LIBSSH2_ECDSA
#ifdef USE_OPENSSL_3
#define libssh2_ecdsa_ctx EVP_PKEY
#define _libssh2_ecdsa_free(ecdsactx) EVP_PKEY_free(ecdsactx)
#define _libssh2_ec_key EVP_PKEY
#else
#define libssh2_ecdsa_ctx EC_KEY
#define _libssh2_ecdsa_free(ecdsactx) EC_KEY_free(ecdsactx)
#define _libssh2_ec_key EC_KEY
#endif
typedef enum {
LIBSSH2_EC_CURVE_NISTP256 = NID_X9_62_prime256v1,
@ -319,15 +378,14 @@ typedef enum {
LIBSSH2_EC_CURVE_NISTP521 = NID_secp521r1
}
libssh2_curve_type;
#else
#else /* !LIBSSH2_ECDSA */
#define _libssh2_ec_key void
#endif /* LIBSSH2_ECDSA */
#if LIBSSH2_ED25519
#define libssh2_ed25519_ctx EVP_PKEY
#define _libssh2_ed25519_free(ctx) EVP_PKEY_free(ctx)
#endif /* ED25519 */
#endif /* LIBSSH2_ED25519 */
#define _libssh2_cipher_type(name) const EVP_CIPHER *(*name)(void)
#ifdef HAVE_OPAQUE_STRUCTS
@ -336,22 +394,20 @@ libssh2_curve_type;
#define _libssh2_cipher_ctx EVP_CIPHER_CTX
#endif
#define _libssh2_cipher_aes256gcm EVP_aes_256_gcm
#define _libssh2_cipher_aes128gcm EVP_aes_128_gcm
#define _libssh2_cipher_aes256 EVP_aes_256_cbc
#define _libssh2_cipher_aes192 EVP_aes_192_cbc
#define _libssh2_cipher_aes128 EVP_aes_128_cbc
#ifdef HAVE_EVP_AES_128_CTR
#define _libssh2_cipher_aes128ctr EVP_aes_128_ctr
#define _libssh2_cipher_aes192ctr EVP_aes_192_ctr
#define _libssh2_cipher_aes256ctr EVP_aes_256_ctr
#else
#define _libssh2_cipher_aes128ctr _libssh2_EVP_aes_128_ctr
#define _libssh2_cipher_aes192ctr _libssh2_EVP_aes_192_ctr
#define _libssh2_cipher_aes256ctr _libssh2_EVP_aes_256_ctr
#endif
#define _libssh2_cipher_blowfish EVP_bf_cbc
#define _libssh2_cipher_arcfour EVP_rc4
#define _libssh2_cipher_cast5 EVP_cast5_cbc
#define _libssh2_cipher_3des EVP_des_ede3_cbc
#define _libssh2_cipher_chacha20 NULL
#ifdef HAVE_OPAQUE_STRUCTS
#define _libssh2_cipher_dtor(ctx) EVP_CIPHER_CTX_free(*(ctx))
@ -365,19 +421,28 @@ libssh2_curve_type;
#define _libssh2_bn_ctx_free(bnctx) BN_CTX_free(bnctx)
#define _libssh2_bn_init() BN_new()
#define _libssh2_bn_init_from_bin() _libssh2_bn_init()
#define _libssh2_bn_set_word(bn, val) BN_set_word(bn, val)
#define _libssh2_bn_from_bin(bn, len, val) BN_bin2bn(val, len, bn)
#define _libssh2_bn_to_bin(bn, val) BN_bn2bin(bn, val)
#define _libssh2_bn_set_word(bn, val) !BN_set_word(bn, val)
extern int _libssh2_bn_from_bin(_libssh2_bn *bn, size_t len,
const unsigned char *v);
#define _libssh2_bn_to_bin(bn, val) (BN_bn2bin(bn, val) <= 0)
#define _libssh2_bn_bytes(bn) BN_num_bytes(bn)
#define _libssh2_bn_bits(bn) BN_num_bits(bn)
#define _libssh2_bn_free(bn) BN_clear_free(bn)
/* Default generate and safe prime sizes for
diffie-hellman-group-exchange-sha1 */
#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
#define _libssh2_dh_ctx BIGNUM *
#define libssh2_dh_init(dhctx) _libssh2_dh_init(dhctx)
#define libssh2_dh_key_pair(dhctx, public, g, p, group_order, bnctx) \
_libssh2_dh_key_pair(dhctx, public, g, p, group_order, bnctx)
_libssh2_dh_key_pair(dhctx, public, g, p, group_order, bnctx)
#define libssh2_dh_secret(dhctx, secret, f, p, bnctx) \
_libssh2_dh_secret(dhctx, secret, f, p, bnctx)
_libssh2_dh_secret(dhctx, secret, f, p, bnctx)
#define libssh2_dh_dtor(dhctx) _libssh2_dh_dtor(dhctx)
extern void _libssh2_dh_init(_libssh2_dh_ctx *dhctx);
extern int _libssh2_dh_key_pair(_libssh2_dh_ctx *dhctx, _libssh2_bn *public,
@ -389,8 +454,10 @@ extern int _libssh2_dh_secret(_libssh2_dh_ctx *dhctx, _libssh2_bn *secret,
_libssh2_bn_ctx *bnctx);
extern void _libssh2_dh_dtor(_libssh2_dh_ctx *dhctx);
extern int _libssh2_openssl_random(void *buf, size_t len);
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 */
#endif /* LIBSSH2_OPENSSL_H */

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,397 @@
#ifndef LIBSSH2_OS400QC3_H
#define LIBSSH2_OS400QC3_H
/*
* Copyright (C) Patrick Monnerat <patrick@monnerat.net>
* 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.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#define LIBSSH2_CRYPTO_ENGINE libssh2_os400qc3
#include <stdlib.h>
#include <string.h>
#include <qc3cci.h>
/* Redefine character/string literals as always EBCDIC. */
#undef Qc3_Alg_Token
#define Qc3_Alg_Token "\xC1\xD3\xC7\xC4\xF0\xF1\xF0\xF0" /* ALGD0100 */
#undef Qc3_Alg_Block_Cipher
#define Qc3_Alg_Block_Cipher "\xC1\xD3\xC7\xC4\xF0\xF2\xF0\xF0" /* ALGD0200 */
#undef Qc3_Alg_Block_CipherAuth
#define Qc3_Alg_Block_CipherAuth \
"\xC1\xD3\xC7\xC4\xF0\xF2\xF1\xF0" /* ALGD0210 */
#undef Qc3_Alg_Stream_Cipher
#define Qc3_Alg_Stream_Cipher \
"\xC1\xD3\xC7\xC4\xF0\xF3\xF0\xF0" /* ALGD0300 */
#undef Qc3_Alg_Public_Key
#define Qc3_Alg_Public_Key "\xC1\xD3\xC7\xC4\xF0\xF4\xF0\xF0" /* ALGD0400 */
#undef Qc3_Alg_Hash
#define Qc3_Alg_Hash "\xC1\xD3\xC7\xC4\xF0\xF5\xF0\xF0" /* ALGD0500 */
#undef Qc3_Data
#define Qc3_Data "\xC4\xC1\xE3\xC1\xF0\xF1\xF0\xF0" /* DATA0100 */
#undef Qc3_Array
#define Qc3_Array "\xC4\xC1\xE3\xC1\xF0\xF2\xF0\xF0" /* DATA0200 */
#undef Qc3_Key_Token
#define Qc3_Key_Token "\xD2\xC5\xE8\xC4\xF0\xF1\xF0\xF0" /* KEYD0100 */
#undef Qc3_Key_Parms
#define Qc3_Key_Parms "\xD2\xC5\xE8\xC4\xF0\xF2\xF0\xF0" /* KEYD0200 */
#undef Qc3_Key_KSLabel
#define Qc3_Key_KSLabel "\xD2\xC5\xE8\xC4\xF0\xF4\xF0\xF0" /* KEYD0400 */
#undef Qc3_Key_PKCS5
#define Qc3_Key_PKCS5 "\xD2\xC5\xE8\xC4\xF0\xF5\xF0\xF0" /* KEYD0500 */
#undef Qc3_Key_PEMCert
#define Qc3_Key_PEMCert "\xD2\xC5\xE8\xC4\xF0\xF6\xF0\xF0" /* KEYD0600 */
#undef Qc3_Key_CSLabel
#define Qc3_Key_CSLabel "\xD2\xC5\xE8\xC4\xF0\xF7\xF0\xF0" /* KEYD0700 */
#undef Qc3_Key_CSDN
#define Qc3_Key_CSDN "\xD2\xC5\xE8\xC4\xF0\xF8\xF0\xF0" /* KEYD0800 */
#undef Qc3_Key_AppID
#define Qc3_Key_AppID "\xD2\xC5\xE8\xC4\xF0\xF9\xF0\xF0" /* KEYD0900 */
#undef Qc3_ECB
#define Qc3_ECB '\xF0' /* '0' */
#undef Qc3_CBC
#define Qc3_CBC '\xF1' /* '1' */
#undef Qc3_OFB
#define Qc3_OFB '\xF2' /* '2' */
#undef Qc3_CFB1Bit
#define Qc3_CFB1Bit '\xF3' /* '3' */
#undef Qc3_CFB8Bit
#define Qc3_CFB8Bit '\xF4' /* '4' */
#undef Qc3_CFB64Bit
#define Qc3_CFB64Bit '\xF5' /* '5' */
#undef Qc3_CUSP
#define Qc3_CUSP '\xF6' /* '6' */
#undef Qc3_CTR
#define Qc3_CTR '\xF7' /* '7' */
#undef Qc3_CCM
#define Qc3_CCM '\xF8' /* '8' */
#undef Qc3_No_Pad
#define Qc3_No_Pad '\xF0' /* '0' */
#undef Qc3_Pad_Char
#define Qc3_Pad_Char '\xF1' /* '1' */
#undef Qc3_Pad_Counter
#define Qc3_Pad_Counter '\xF2' /* '2' */
#undef Qc3_PKCS1_00
#define Qc3_PKCS1_00 '\xF0' /* '0' */
#undef Qc3_PKCS1_01
#define Qc3_PKCS1_01 '\xF1' /* '1' */
#undef Qc3_PKCS1_02
#define Qc3_PKCS1_02 '\xF2' /* '2' */
#undef Qc3_ISO9796
#define Qc3_ISO9796 '\xF3' /* '3' */
#undef Qc3_Zero_Pad
#define Qc3_Zero_Pad '\xF4' /* '4' */
#undef Qc3_ANSI_X931
#define Qc3_ANSI_X931 '\xF5' /* '5' */
#undef Qc3_OAEP
#define Qc3_OAEP '\xF6' /* '6' */
#undef Qc3_Bin_String
#define Qc3_Bin_String '\xF0' /* '0' */
#undef Qc3_BER_String
#define Qc3_BER_String '\xF1' /* '1' */
#undef Qc3_MK_Struct
#define Qc3_MK_Struct '\xF3' /* '3' */
#undef Qc3_KSLabel_Struct
#define Qc3_KSLabel_Struct '\xF4' /* '4' */
#undef Qc3_PKCS5_Struct
#define Qc3_PKCS5_Struct '\xF5' /* '5' */
#undef Qc3_PEMCert_String
#define Qc3_PEMCert_String '\xF6' /* '6' */
#undef Qc3_CSLabel_String
#define Qc3_CSLabel_String '\xF7' /* '7' */
#undef Qc3_CSDN_String
#define Qc3_CSDN_String '\xF8' /* '8' */
#undef Qc3_Clear
#define Qc3_Clear '\xF0' /* '0' */
#undef Qc3_Encrypted
#define Qc3_Encrypted '\xF1' /* '1' */
#undef Qc3_MK_Encrypted
#define Qc3_MK_Encrypted '\xF2' /* '2' */
#undef Qc3_Any_CSP
#define Qc3_Any_CSP '\xF0' /* '0' */
#undef Qc3_Sfw_CSP
#define Qc3_Sfw_CSP '\xF1' /* '1' */
#undef Qc3_Hdw_CSP
#define Qc3_Hdw_CSP '\xF2' /* '2' */
#undef Qc3_Continue
#define Qc3_Continue '\xF0' /* '0' */
#undef Qc3_Final
#define Qc3_Final '\xF1' /* '1' */
#undef Qc3_MK_New
#define Qc3_MK_New '\xF0' /* '0' */
#undef Qc3_MK_Current
#define Qc3_MK_Current '\xF1' /* '1' */
#undef Qc3_MK_Old
#define Qc3_MK_Old '\xF2' /* '2' */
#undef Qc3_MK_Pending
#define Qc3_MK_Pending '\xF3' /* '3' */
/* Define which features are supported. */
#ifdef OPENSSL_NO_MD5
# define LIBSSH2_MD5 0
#else
# define LIBSSH2_MD5 1
#endif
#define LIBSSH2_HMAC_RIPEMD 0
#define LIBSSH2_HMAC_SHA256 1
#define LIBSSH2_HMAC_SHA512 1
#define LIBSSH2_AES_CBC 1
#define LIBSSH2_AES_CTR 1
#define LIBSSH2_AES_GCM 0
#define LIBSSH2_BLOWFISH 0
#define LIBSSH2_RC4 1
#define LIBSSH2_CAST 0
#define LIBSSH2_3DES 1
#define LIBSSH2_RSA 1
#define LIBSSH2_RSA_SHA1 1
#define LIBSSH2_RSA_SHA2 1
#define LIBSSH2_DSA 0
#define LIBSSH2_ECDSA 0
#define LIBSSH2_ED25519 0
#include "crypto_config.h"
#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)
#if LIBSSH2_ECDSA
#else
#define _libssh2_ec_key void
#endif
/*******************************************************************
*
* OS/400 QC3 crypto-library backend: global handles structures.
*
*******************************************************************/
/* HMAC & private key algorithms support structure. */
typedef struct _libssh2_os400qc3_crypto_ctx _libssh2_os400qc3_crypto_ctx;
struct _libssh2_os400qc3_crypto_ctx {
Qc3_Format_ALGD0100_T hash; /* Hash algorithm. */
Qc3_Format_KEYD0100_T key; /* Key. */
_libssh2_os400qc3_crypto_ctx * kek; /* Key encryption. */
};
typedef struct { /* Big number. */
unsigned char * bignum; /* Number bits, little-endian. */
unsigned int length; /* Length of bignum (# bytes). */
} _libssh2_bn;
typedef struct { /* Algorithm description. */
char * fmt; /* Format of Qc3 structure. */
int algo; /* Algorithm identifier. */
unsigned char size; /* Block length. */
unsigned char mode; /* Block mode. */
int keylen; /* Key length. */
} _libssh2_os400qc3_cipher_t;
typedef struct { /* Diffie-Hellman context. */
char token[8]; /* Context token. */
} _libssh2_os400qc3_dh_ctx;
/*******************************************************************
*
* OS/400 QC3 crypto-library backend: Define global types/codes.
*
*******************************************************************/
#define libssh2_crypto_init()
#define libssh2_crypto_exit()
#define libssh2_sha1_ctx Qc3_Format_ALGD0100_T
#define libssh2_sha256_ctx Qc3_Format_ALGD0100_T
#define libssh2_sha384_ctx Qc3_Format_ALGD0100_T
#define libssh2_sha512_ctx Qc3_Format_ALGD0100_T
#define libssh2_hmac_ctx _libssh2_os400qc3_crypto_ctx
#define _libssh2_cipher_ctx _libssh2_os400qc3_crypto_ctx
#define libssh2_sha1_init(x) _libssh2_os400qc3_hash_init(x, Qc3_SHA1)
#define libssh2_sha1_update(ctx, data, len) \
_libssh2_os400qc3_hash_update(&(ctx), data, len)
#define libssh2_sha1_final(ctx, out) \
_libssh2_os400qc3_hash_final(&(ctx), out)
#define libssh2_sha256_init(x) _libssh2_os400qc3_hash_init(x, Qc3_SHA256)
#define libssh2_sha256_update(ctx, data, len) \
_libssh2_os400qc3_hash_update(&(ctx), data, len)
#define libssh2_sha256_final(ctx, out) \
_libssh2_os400qc3_hash_final(&(ctx), out)
#define libssh2_sha256(message, len, out) \
_libssh2_os400qc3_hash(message, len, out, \
Qc3_SHA256)
#define libssh2_sha384_init(x) _libssh2_os400qc3_hash_init(x, Qc3_SHA384)
#define libssh2_sha384_update(ctx, data, len) \
_libssh2_os400qc3_hash_update(&(ctx), data, len)
#define libssh2_sha384_final(ctx, out) \
_libssh2_os400qc3_hash_final(&(ctx), out)
#define libssh2_sha384(message, len, out) \
_libssh2_os400qc3_hash(message, len, out, \
Qc3_SHA384)
#define libssh2_sha512_init(x) _libssh2_os400qc3_hash_init(x, Qc3_SHA512)
#define libssh2_sha512_update(ctx, data, len) \
_libssh2_os400qc3_hash_update(&(ctx), data, len)
#define libssh2_sha512_final(ctx, out) \
_libssh2_os400qc3_hash_final(&(ctx), out)
#define libssh2_sha512(message, len, out) \
_libssh2_os400qc3_hash(message, len, out, \
Qc3_SHA512)
#if LIBSSH2_MD5 || LIBSSH2_MD5_PEM
#define MD5_DIGEST_LENGTH 16
#define libssh2_md5_ctx Qc3_Format_ALGD0100_T
#define libssh2_md5_init(x) _libssh2_os400qc3_hash_init(x, Qc3_MD5)
#define libssh2_md5_update(ctx, data, len) \
_libssh2_os400qc3_hash_update(&(ctx), data, len)
#define libssh2_md5_final(ctx, out) \
_libssh2_os400qc3_hash_final(&(ctx), out)
#endif
#define _libssh2_bn_ctx int /* Not used. */
#define _libssh2_bn_ctx_new() 0
#define _libssh2_bn_ctx_free(bnctx) ((void) 0)
#define _libssh2_bn_init_from_bin() _libssh2_bn_init()
#define _libssh2_bn_bytes(bn) ((bn)->length)
#define _libssh2_cipher_type(name) _libssh2_os400qc3_cipher_t name
#define _libssh2_cipher_aes128 {Qc3_Alg_Block_Cipher, Qc3_AES, 16, \
Qc3_CBC, 16}
#define _libssh2_cipher_aes192 {Qc3_Alg_Block_Cipher, Qc3_AES, 16, \
Qc3_CBC, 24}
#define _libssh2_cipher_aes256 {Qc3_Alg_Block_Cipher, Qc3_AES, 16, \
Qc3_CBC, 32}
#define _libssh2_cipher_aes128ctr {Qc3_Alg_Block_Cipher, Qc3_AES, 16, \
Qc3_CTR, 16}
#define _libssh2_cipher_aes192ctr {Qc3_Alg_Block_Cipher, Qc3_AES, 16, \
Qc3_CTR, 24}
#define _libssh2_cipher_aes256ctr {Qc3_Alg_Block_Cipher, Qc3_AES, 16, \
Qc3_CTR, 32}
#define _libssh2_cipher_3des {Qc3_Alg_Block_Cipher, Qc3_TDES, 8, \
Qc3_CBC, 24}
/* Nonsense values for chacha20-poly1305 */
#define _libssh2_cipher_chacha20 {Qc3_Alg_Stream_Cipher, Qc3_RC4, 8, 0, 16}
#define _libssh2_cipher_arcfour {Qc3_Alg_Stream_Cipher, Qc3_RC4, 8, 0, 16}
#define _libssh2_cipher_dtor(ctx) _libssh2_os400qc3_crypto_dtor(ctx)
#define libssh2_rsa_ctx _libssh2_os400qc3_crypto_ctx
#define _libssh2_rsa_free(ctx) (_libssh2_os400qc3_crypto_dtor(ctx), \
free((char *) ctx))
#define libssh2_prepare_iovec(vec, len) memset((char *) (vec), 0, \
(len) * sizeof(struct iovec))
#define _libssh2_rsa_sha1_signv(session, sig, siglen, count, vector, ctx) \
_libssh2_os400qc3_rsa_signv(session, Qc3_SHA1, sig, siglen, \
count, vector, ctx)
#define _libssh2_rsa_sha2_256_signv(session, sig, siglen, cnt, vector, ctx) \
_libssh2_os400qc3_rsa_signv(session, Qc3_SHA256, sig, siglen, \
cnt, vector, ctx)
#define _libssh2_rsa_sha2_512_signv(session, sig, siglen, cnt, vector, ctx) \
_libssh2_os400qc3_rsa_signv(session, Qc3_SHA512, sig, siglen, \
cnt, vector, ctx)
/* Default generate and safe prime sizes for diffie-hellman-group-exchange-sha1
Qc3 is limited to a maximum 2048-bit modulus/key size. */
#define LIBSSH2_DH_GEX_MINGROUP 1024
#define LIBSSH2_DH_GEX_OPTGROUP 1536
#define LIBSSH2_DH_GEX_MAXGROUP 2048
#define LIBSSH2_DH_MAX_MODULUS_BITS 2048
#define _libssh2_dh_ctx _libssh2_os400qc3_dh_ctx
#define libssh2_dh_init(dhctx) _libssh2_os400qc3_dh_init(dhctx)
#define libssh2_dh_key_pair(dhctx, public, g, p, group_order, bnctx) \
_libssh2_os400qc3_dh_key_pair(dhctx, public, g, p, group_order)
#define libssh2_dh_secret(dhctx, secret, f, p, bnctx) \
_libssh2_os400qc3_dh_secret(dhctx, secret, f, p)
#define libssh2_dh_dtor(dhctx) _libssh2_os400qc3_dh_dtor(dhctx)
/*******************************************************************
*
* OS/400 QC3 crypto-library backend: Support procedure prototypes.
*
*******************************************************************/
extern _libssh2_bn * _libssh2_bn_init(void);
extern void _libssh2_bn_free(_libssh2_bn *bn);
extern unsigned long _libssh2_bn_bits(_libssh2_bn *bn);
extern int _libssh2_bn_from_bin(_libssh2_bn *bn, size_t len,
const unsigned char *v);
extern int _libssh2_bn_set_word(_libssh2_bn *bn, unsigned long val);
extern int _libssh2_bn_to_bin(_libssh2_bn *bn, unsigned char *val);
extern int _libssh2_random(unsigned char *buf, size_t len);
extern void _libssh2_os400qc3_crypto_dtor(_libssh2_os400qc3_crypto_ctx *x);
extern int _libssh2_os400qc3_hash_init(Qc3_Format_ALGD0100_T *x,
unsigned int algo);
extern int _libssh2_os400qc3_hash_update(Qc3_Format_ALGD0100_T *ctx,
const unsigned char *data,
int len);
extern int _libssh2_os400qc3_hash_final(Qc3_Format_ALGD0100_T *ctx,
unsigned char *out);
extern int _libssh2_os400qc3_hash(const unsigned char *message,
unsigned long len, unsigned char *out,
unsigned int algo);
extern int _libssh2_os400qc3_rsa_signv(LIBSSH2_SESSION *session, int algo,
unsigned char **signature,
size_t *signature_len,
int veccount,
const struct iovec vector[],
libssh2_rsa_ctx *ctx);
extern void _libssh2_os400qc3_dh_init(_libssh2_dh_ctx *dhctx);
extern int _libssh2_os400qc3_dh_key_pair(_libssh2_dh_ctx *dhctx,
_libssh2_bn *public,
_libssh2_bn *g,
_libssh2_bn *p, int group_order);
extern int _libssh2_os400qc3_dh_secret(_libssh2_dh_ctx *dhctx,
_libssh2_bn *secret,
_libssh2_bn *f, _libssh2_bn *p);
extern void _libssh2_os400qc3_dh_dtor(_libssh2_dh_ctx *dhctx);
#endif /* LIBSSH2_OS400QC3_H */
/* vim: set expandtab ts=4 sw=4: */

File diff suppressed because it is too large Load diff

View file

@ -1,8 +1,8 @@
#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>
* Copyright (C) Daniel Stenberg
* All rights reserved.
*
* Redistribution and use in source and binary forms,
* with or without modification, are permitted provided
@ -37,6 +37,7 @@
* USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
* OF SUCH DAMAGE.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
int _libssh2_packet_read(LIBSSH2_SESSION * session);
@ -71,6 +72,6 @@ int _libssh2_packet_burn(LIBSSH2_SESSION * session,
int _libssh2_packet_write(LIBSSH2_SESSION * session, unsigned char *data,
unsigned long data_len);
int _libssh2_packet_add(LIBSSH2_SESSION * session, unsigned char *data,
size_t datalen, int macstate);
size_t datalen, int macstate, uint32_t seq);
#endif /* __LIBSSH2_PACKET_H */
#endif /* LIBSSH2_PACKET_H */

View file

@ -1,5 +1,5 @@
/* Copyright (C) 2007 The Written Word, Inc.
* Copyright (C) 2008, Simon Josefsson
/* Copyright (C) The Written Word, Inc.
* Copyright (C) Simon Josefsson
* All rights reserved.
*
* Redistribution and use in source and binary forms,
@ -34,6 +34,8 @@
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
* USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
* OF SUCH DAMAGE.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#include "libssh2_priv.h"
@ -100,7 +102,8 @@ static const char *crypt_annotation = "Proc-Type: 4,ENCRYPTED";
static unsigned char hex_decode(char digit)
{
return (digit >= 'A') ? 0xA + (digit - 'A') : (digit - '0');
return (unsigned char)
((digit >= 'A') ? (0xA + (digit - 'A')) : (digit - '0'));
}
int
@ -108,12 +111,12 @@ _libssh2_pem_parse(LIBSSH2_SESSION * session,
const char *headerbegin,
const char *headerend,
const unsigned char *passphrase,
FILE * fp, unsigned char **data, unsigned int *datalen)
FILE * fp, unsigned char **data, size_t *datalen)
{
char line[LINE_SIZE];
unsigned char iv[LINE_SIZE];
char *b64data = NULL;
unsigned int b64datalen = 0;
size_t b64datalen = 0;
int ret;
const LIBSSH2_CRYPT_METHOD *method = NULL;
@ -123,8 +126,7 @@ _libssh2_pem_parse(LIBSSH2_SESSION * session,
if(readline(line, LINE_SIZE, fp)) {
return -1;
}
}
while(strcmp(line, headerbegin) != 0);
} while(strcmp(line, headerbegin) != 0);
if(readline(line, LINE_SIZE, fp)) {
return -1;
@ -141,7 +143,8 @@ _libssh2_pem_parse(LIBSSH2_SESSION * session,
}
all_methods = libssh2_crypt_methods();
while((cur_method = *all_methods++)) {
/* !checksrc! disable EQUALSNULL 1 */
while((cur_method = *all_methods++) != NULL) {
if(*cur_method->pem_annotation &&
memcmp(line, cur_method->pem_annotation,
strlen(cur_method->pem_annotation)) == 0) {
@ -152,12 +155,12 @@ _libssh2_pem_parse(LIBSSH2_SESSION * session,
}
/* None of the available crypt methods were able to decrypt the key */
if(method == NULL)
if(!method)
return -1;
/* Decode IV from hex */
for(i = 0; i < method->iv_len; ++i) {
iv[i] = hex_decode(iv[2*i]) << 4;
iv[i] = (unsigned char)(hex_decode(iv[2*i]) << 4);
iv[i] |= hex_decode(iv[2*i + 1]);
}
@ -198,13 +201,14 @@ _libssh2_pem_parse(LIBSSH2_SESSION * session,
return -1;
}
if(libssh2_base64_decode(session, (char **) data, datalen,
if(_libssh2_base64_decode(session, (char **) data, datalen,
b64data, b64datalen)) {
ret = -1;
goto out;
}
if(method) {
#if LIBSSH2_MD5_PEM
/* Set up decryption */
int free_iv = 0, free_secret = 0, len_decrypted = 0, padding = 0;
int blocksize = method->blocksize;
@ -213,24 +217,26 @@ _libssh2_pem_parse(LIBSSH2_SESSION * session,
libssh2_md5_ctx fingerprint_ctx;
/* Perform key derivation (PBKDF1/MD5) */
if(!libssh2_md5_init(&fingerprint_ctx)) {
if(!libssh2_md5_init(&fingerprint_ctx) ||
!libssh2_md5_update(fingerprint_ctx, passphrase,
strlen((char *)passphrase)) ||
!libssh2_md5_update(fingerprint_ctx, iv, 8) ||
!libssh2_md5_final(fingerprint_ctx, secret)) {
ret = -1;
goto out;
}
libssh2_md5_update(fingerprint_ctx, passphrase,
strlen((char *)passphrase));
libssh2_md5_update(fingerprint_ctx, iv, 8);
libssh2_md5_final(fingerprint_ctx, secret);
if(method->secret_len > MD5_DIGEST_LENGTH) {
if(!libssh2_md5_init(&fingerprint_ctx)) {
if(!libssh2_md5_init(&fingerprint_ctx) ||
!libssh2_md5_update(fingerprint_ctx,
secret, MD5_DIGEST_LENGTH) ||
!libssh2_md5_update(fingerprint_ctx,
passphrase, strlen((char *)passphrase)) ||
!libssh2_md5_update(fingerprint_ctx, iv, 8) ||
!libssh2_md5_final(fingerprint_ctx,
secret + MD5_DIGEST_LENGTH)) {
ret = -1;
goto out;
}
libssh2_md5_update(fingerprint_ctx, secret, MD5_DIGEST_LENGTH);
libssh2_md5_update(fingerprint_ctx, passphrase,
strlen((char *)passphrase));
libssh2_md5_update(fingerprint_ctx, iv, 8);
libssh2_md5_final(fingerprint_ctx, secret + MD5_DIGEST_LENGTH);
}
/* Initialize the decryption */
@ -256,9 +262,8 @@ _libssh2_pem_parse(LIBSSH2_SESSION * session,
goto out;
}
while(len_decrypted <= (int)*datalen - blocksize) {
if(method->crypt(session, *data + len_decrypted, blocksize,
&abstract)) {
if(method->flags & LIBSSH2_CRYPT_FLAG_REQUIRES_FULL_PACKET) {
if(method->crypt(session, 0, *data, *datalen, &abstract, 0)) {
ret = LIBSSH2_ERROR_DECRYPT;
_libssh2_explicit_zero((char *)secret, sizeof(secret));
method->dtor(session, &abstract);
@ -266,8 +271,25 @@ _libssh2_pem_parse(LIBSSH2_SESSION * session,
LIBSSH2_FREE(session, *data);
goto out;
}
}
else {
while(len_decrypted <= (int)*datalen - blocksize) {
if(method->crypt(session, 0, *data + len_decrypted, blocksize,
&abstract,
len_decrypted == 0 ? FIRST_BLOCK :
((len_decrypted == (int)*datalen - blocksize) ?
LAST_BLOCK : MIDDLE_BLOCK)
)) {
ret = LIBSSH2_ERROR_DECRYPT;
_libssh2_explicit_zero((char *)secret, sizeof(secret));
method->dtor(session, &abstract);
_libssh2_explicit_zero(*data, *datalen);
LIBSSH2_FREE(session, *data);
goto out;
}
len_decrypted += blocksize;
len_decrypted += blocksize;
}
}
/* Account for padding */
@ -278,10 +300,14 @@ _libssh2_pem_parse(LIBSSH2_SESSION * session,
/* Clean up */
_libssh2_explicit_zero((char *)secret, sizeof(secret));
method->dtor(session, &abstract);
#else
ret = -1;
goto out;
#endif
}
ret = 0;
out:
out:
if(b64data) {
_libssh2_explicit_zero(b64data, b64datalen);
LIBSSH2_FREE(session, b64data);
@ -294,11 +320,11 @@ _libssh2_pem_parse_memory(LIBSSH2_SESSION * session,
const char *headerbegin,
const char *headerend,
const char *filedata, size_t filedata_len,
unsigned char **data, unsigned int *datalen)
unsigned char **data, size_t *datalen)
{
char line[LINE_SIZE];
char *b64data = NULL;
unsigned int b64datalen = 0;
size_t b64datalen = 0;
size_t off = 0;
int ret;
@ -308,8 +334,7 @@ _libssh2_pem_parse_memory(LIBSSH2_SESSION * session,
if(readline_memory(line, LINE_SIZE, filedata, filedata_len, &off)) {
return -1;
}
}
while(strcmp(line, headerbegin) != 0);
} while(strcmp(line, headerbegin) != 0);
*line = '\0';
@ -343,14 +368,14 @@ _libssh2_pem_parse_memory(LIBSSH2_SESSION * session,
return -1;
}
if(libssh2_base64_decode(session, (char **) data, datalen,
if(_libssh2_base64_decode(session, (char **) data, datalen,
b64data, b64datalen)) {
ret = -1;
goto out;
}
ret = 0;
out:
out:
if(b64data) {
_libssh2_explicit_zero(b64data, b64datalen);
LIBSSH2_FREE(session, b64data);
@ -382,7 +407,7 @@ _libssh2_openssh_pem_parse_data(LIBSSH2_SESSION * session,
unsigned char *key_part = NULL;
unsigned char *iv_part = NULL;
unsigned char *f = NULL;
unsigned int f_len = 0;
size_t f_len = 0;
int ret = 0, keylen = 0, ivlen = 0, total_len = 0;
size_t kdf_len = 0, tmp_len = 0, salt_len = 0;
@ -390,10 +415,10 @@ _libssh2_openssh_pem_parse_data(LIBSSH2_SESSION * session,
*decrypted_buf = NULL;
/* decode file */
if(libssh2_base64_decode(session, (char **)&f, &f_len,
b64data, b64datalen)) {
ret = -1;
goto out;
if(_libssh2_base64_decode(session, (char **)&f, &f_len,
b64data, b64datalen)) {
ret = -1;
goto out;
}
/* Parse the file */
@ -425,7 +450,7 @@ _libssh2_openssh_pem_parse_data(LIBSSH2_SESSION * session,
if(_libssh2_get_string(&decoded, &kdfname, &tmp_len) ||
tmp_len == 0) {
ret = _libssh2_error(session, LIBSSH2_ERROR_PROTO,
"kdfname is missing");
"kdfname is missing");
goto out;
}
@ -440,7 +465,7 @@ _libssh2_openssh_pem_parse_data(LIBSSH2_SESSION * session,
kdf_buf.len = kdf_len;
}
if((passphrase == NULL || strlen((const char *)passphrase) == 0) &&
if((!passphrase || strlen((const char *)passphrase) == 0) &&
strcmp((const char *)ciphername, "none") != 0) {
/* passphrase required */
ret = LIBSSH2_ERROR_KEYFILE_AUTH_FAILED;
@ -456,8 +481,8 @@ _libssh2_openssh_pem_parse_data(LIBSSH2_SESSION * session,
if(!strcmp((const char *)kdfname, "none") &&
strcmp((const char *)ciphername, "none") != 0) {
ret =_libssh2_error(session, LIBSSH2_ERROR_PROTO,
"invalid format");
ret = _libssh2_error(session, LIBSSH2_ERROR_PROTO,
"invalid format");
goto out;
}
@ -478,7 +503,7 @@ _libssh2_openssh_pem_parse_data(LIBSSH2_SESSION * session,
if(_libssh2_get_string(&decoded, &buf, &tmp_len) || tmp_len == 0) {
ret = _libssh2_error(session, LIBSSH2_ERROR_PROTO,
"Private key data not found");
"Private key data not found");
goto out;
}
@ -490,7 +515,8 @@ _libssh2_openssh_pem_parse_data(LIBSSH2_SESSION * session,
const LIBSSH2_CRYPT_METHOD **all_methods, *cur_method;
all_methods = libssh2_crypt_methods();
while((cur_method = *all_methods++)) {
/* !checksrc! disable EQUALSNULL 1 */
while((cur_method = *all_methods++) != NULL) {
if(*cur_method->name &&
memcmp(ciphername, cur_method->name,
strlen(cur_method->name)) == 0) {
@ -500,9 +526,9 @@ _libssh2_openssh_pem_parse_data(LIBSSH2_SESSION * session,
/* None of the available crypt methods were able to decrypt the key */
if(method == NULL) {
if(!method) {
ret = _libssh2_error(session, LIBSSH2_ERROR_PROTO,
"No supported cipher found");
"No supported cipher found");
goto out;
}
}
@ -517,16 +543,15 @@ _libssh2_openssh_pem_parse_data(LIBSSH2_SESSION * session,
total_len = keylen + ivlen;
key = LIBSSH2_CALLOC(session, total_len);
if(key == NULL) {
if(!key) {
ret = _libssh2_error(session, LIBSSH2_ERROR_PROTO,
"Could not alloc key");
"Could not alloc key");
goto out;
}
if(strcmp((const char *)kdfname, "bcrypt") == 0 &&
passphrase != NULL) {
if(strcmp((const char *)kdfname, "bcrypt") == 0 && passphrase) {
if((_libssh2_get_string(&kdf_buf, &salt, &salt_len)) ||
(_libssh2_get_u32(&kdf_buf, &rounds) != 0) ) {
(_libssh2_get_u32(&kdf_buf, &rounds) != 0)) {
ret = _libssh2_error(session, LIBSSH2_ERROR_PROTO,
"kdf contains unexpected values");
LIBSSH2_FREE(session, key);
@ -545,7 +570,7 @@ _libssh2_openssh_pem_parse_data(LIBSSH2_SESSION * session,
}
else {
ret = _libssh2_error(session, LIBSSH2_ERROR_KEYFILE_AUTH_FAILED,
"bcrypted without passphrase");
"bcrypted without passphrase");
LIBSSH2_FREE(session, key);
goto out;
}
@ -554,14 +579,14 @@ _libssh2_openssh_pem_parse_data(LIBSSH2_SESSION * session,
blocksize = method->blocksize;
key_part = LIBSSH2_CALLOC(session, keylen);
if(key_part == NULL) {
if(!key_part) {
ret = _libssh2_error(session, LIBSSH2_ERROR_PROTO,
"Could not alloc key part");
goto out;
}
iv_part = LIBSSH2_CALLOC(session, ivlen);
if(iv_part == NULL) {
if(!iv_part) {
ret = _libssh2_error(session, LIBSSH2_ERROR_PROTO,
"Could not alloc iv part");
goto out;
@ -572,7 +597,7 @@ _libssh2_openssh_pem_parse_data(LIBSSH2_SESSION * session,
/* Initialize the decryption */
if(method->init(session, method, iv_part, &free_iv, key_part,
&free_secret, 0, &abstract)) {
&free_secret, 0, &abstract)) {
ret = LIBSSH2_ERROR_DECRYPT;
goto out;
}
@ -584,19 +609,59 @@ _libssh2_openssh_pem_parse_data(LIBSSH2_SESSION * session,
goto out;
}
while((size_t)len_decrypted <= decrypted.len - blocksize) {
if(method->crypt(session, decrypted.data + len_decrypted,
blocksize,
&abstract)) {
if(method->flags & LIBSSH2_CRYPT_FLAG_REQUIRES_FULL_PACKET) {
if(method->crypt(session, 0, decrypted.data,
decrypted.len,
&abstract,
MIDDLE_BLOCK)) {
ret = LIBSSH2_ERROR_DECRYPT;
method->dtor(session, &abstract);
goto out;
}
len_decrypted += blocksize;
}
else {
while((size_t)len_decrypted <= decrypted.len - blocksize) {
/* We always pass MIDDLE_BLOCK here because OpenSSH Key Files
* do not use AAD to authenticate the length.
* Furthermore, the authentication tag is appended after the
* encrypted key, and the length of the authentication tag is
* not included in the key length, so we check it after the
* loop.
*/
if(method->crypt(session, 0, decrypted.data + len_decrypted,
blocksize,
&abstract,
MIDDLE_BLOCK)) {
ret = LIBSSH2_ERROR_DECRYPT;
method->dtor(session, &abstract);
goto out;
}
/* No padding */
len_decrypted += blocksize;
}
/* No padding */
/* for the AES GCM methods, the 16 byte authentication tag is
* appended to the encrypted key */
if(strcmp(method->name, "aes256-gcm@openssh.com") == 0 ||
strcmp(method->name, "aes128-gcm@openssh.com") == 0) {
if(!_libssh2_check_length(&decoded, 16)) {
ret = _libssh2_error(session, LIBSSH2_ERROR_PROTO,
"GCM auth tag missing");
method->dtor(session, &abstract);
goto out;
}
if(method->crypt(session, 0, decoded.dataptr, 16, &abstract,
LAST_BLOCK)) {
ret = _libssh2_error(session, LIBSSH2_ERROR_DECRYPT,
"GCM auth tag invalid");
method->dtor(session, &abstract);
goto out;
}
decoded.dataptr += 16;
}
}
method->dtor(session, &abstract);
}
@ -606,13 +671,13 @@ _libssh2_openssh_pem_parse_data(LIBSSH2_SESSION * session,
if(_libssh2_get_u32(&decrypted, &check1) != 0 ||
_libssh2_get_u32(&decrypted, &check2) != 0 ||
check1 != check2) {
_libssh2_error(session, LIBSSH2_ERROR_PROTO,
"Private key unpack failed (correct password?)");
ret = LIBSSH2_ERROR_KEYFILE_AUTH_FAILED;
goto out;
_libssh2_error(session, LIBSSH2_ERROR_PROTO,
"Private key unpack failed (correct password?)");
ret = LIBSSH2_ERROR_KEYFILE_AUTH_FAILED;
goto out;
}
if(decrypted_buf != NULL) {
if(decrypted_buf) {
/* copy data to out-going buffer */
struct string_buf *out_buf = _libssh2_string_buf_new(session);
if(!out_buf) {
@ -623,7 +688,7 @@ _libssh2_openssh_pem_parse_data(LIBSSH2_SESSION * session,
}
out_buf->data = LIBSSH2_CALLOC(session, decrypted.len);
if(out_buf->data == NULL) {
if(!out_buf->data) {
ret = _libssh2_error(session, LIBSSH2_ERROR_ALLOC,
"Unable to allocate memory for "
"decrypted struct");
@ -668,7 +733,7 @@ _libssh2_openssh_pem_parse(LIBSSH2_SESSION * session,
{
char line[LINE_SIZE];
char *b64data = NULL;
unsigned int b64datalen = 0;
size_t b64datalen = 0;
int ret = 0;
/* read file */
@ -679,8 +744,7 @@ _libssh2_openssh_pem_parse(LIBSSH2_SESSION * session,
if(readline(line, LINE_SIZE, fp)) {
return -1;
}
}
while(strcmp(line, OPENSSH_HEADER_BEGIN) != 0);
} while(strcmp(line, OPENSSH_HEADER_BEGIN) != 0);
if(readline(line, LINE_SIZE, fp)) {
return -1;
@ -719,7 +783,7 @@ _libssh2_openssh_pem_parse(LIBSSH2_SESSION * session,
ret = _libssh2_openssh_pem_parse_data(session,
passphrase,
(const char *)b64data,
(size_t)b64datalen,
b64datalen,
decrypted_buf);
if(b64data) {
@ -740,11 +804,11 @@ _libssh2_openssh_pem_parse_memory(LIBSSH2_SESSION * session,
{
char line[LINE_SIZE];
char *b64data = NULL;
unsigned int b64datalen = 0;
size_t b64datalen = 0;
size_t off = 0;
int ret;
if(filedata == NULL || filedata_len <= 0)
if(!filedata || filedata_len <= 0)
return _libssh2_error(session, LIBSSH2_ERROR_PROTO,
"Error parsing PEM: filedata missing");
@ -754,18 +818,18 @@ _libssh2_openssh_pem_parse_memory(LIBSSH2_SESSION * session,
if(off >= filedata_len)
return _libssh2_error(session, LIBSSH2_ERROR_PROTO,
"Error parsing PEM: offset out of bounds");
"Error parsing PEM: "
"OpenSSH header not found");
if(readline_memory(line, LINE_SIZE, filedata, filedata_len, &off)) {
return -1;
}
}
while(strcmp(line, OPENSSH_HEADER_BEGIN) != 0);
} while(strcmp(line, OPENSSH_HEADER_BEGIN) != 0);
*line = '\0';
do {
if (*line) {
if(*line) {
char *tmp;
size_t linelen;
@ -814,7 +878,7 @@ out:
static int
read_asn1_length(const unsigned char *data,
unsigned int datalen, unsigned int *len)
size_t datalen, size_t *len)
{
unsigned int lenlen;
int nextpos;
@ -848,9 +912,9 @@ read_asn1_length(const unsigned char *data,
}
int
_libssh2_pem_decode_sequence(unsigned char **data, unsigned int *datalen)
_libssh2_pem_decode_sequence(unsigned char **data, size_t *datalen)
{
unsigned int len;
size_t len;
int lenlen;
if(*datalen < 1) {
@ -876,10 +940,10 @@ _libssh2_pem_decode_sequence(unsigned char **data, unsigned int *datalen)
}
int
_libssh2_pem_decode_integer(unsigned char **data, unsigned int *datalen,
_libssh2_pem_decode_integer(unsigned char **data, size_t *datalen,
unsigned char **i, unsigned int *ilen)
{
unsigned int len;
size_t len;
int lenlen;
if(*datalen < 1) {
@ -902,7 +966,7 @@ _libssh2_pem_decode_integer(unsigned char **data, unsigned int *datalen,
*datalen -= lenlen;
*i = *data;
*ilen = len;
*ilen = (unsigned int)len;
*data += len;
*datalen -= len;

View file

@ -0,0 +1,206 @@
/*
* Public Domain poly1305 from Andrew Moon
* poly1305-donna-unrolled.c from https://github.com/floodyberry/poly1305-donna
* Copyright not intended 2024.
*
* SPDX-License-Identifier: SAX-PD-2.0
*/
/* $OpenBSD: poly1305.c,v 1.3 2013/12/19 22:57:13 djm Exp $ */
#include "libssh2_priv.h"
#include "poly1305.h"
#define mul32x32_64(a,b) ((uint64_t)(a) * (b))
#define U8TO32_LE(p) \
(((uint32_t)((p)[0])) | \
((uint32_t)((p)[1]) << 8) | \
((uint32_t)((p)[2]) << 16) | \
((uint32_t)((p)[3]) << 24))
#define U32TO8_LE(p, v) \
do { \
(p)[0] = (uint8_t)((v)); \
(p)[1] = (uint8_t)((v) >> 8); \
(p)[2] = (uint8_t)((v) >> 16); \
(p)[3] = (uint8_t)((v) >> 24); \
} while (0)
void
poly1305_auth(unsigned char out[POLY1305_TAGLEN], const unsigned char *m,
size_t inlen, const unsigned char key[POLY1305_KEYLEN]) {
uint32_t t0;
uint32_t t1;
uint32_t t2;
uint32_t t3;
uint32_t h0;
uint32_t h1;
uint32_t h2;
uint32_t h3;
uint32_t h4;
uint32_t r0;
uint32_t r1;
uint32_t r2;
uint32_t r3;
uint32_t r4;
uint32_t s1;
uint32_t s2;
uint32_t s3;
uint32_t s4;
uint32_t b;
uint32_t nb;
size_t j;
uint64_t t[5];
uint64_t f0;
uint64_t f1;
uint64_t f2;
uint64_t f3;
uint32_t g0;
uint32_t g1;
uint32_t g2;
uint32_t g3;
uint32_t g4;
uint64_t c;
unsigned char mp[16];
/* clamp key */
t0 = U8TO32_LE(key + 0);
t1 = U8TO32_LE(key + 4);
t2 = U8TO32_LE(key + 8);
t3 = U8TO32_LE(key + 12);
/* precompute multipliers */
r0 = t0 & 0x3ffffff; t0 >>= 26; t0 |= t1 << 6;
r1 = t0 & 0x3ffff03; t1 >>= 20; t1 |= t2 << 12;
r2 = t1 & 0x3ffc0ff; t2 >>= 14; t2 |= t3 << 18;
r3 = t2 & 0x3f03fff; t3 >>= 8;
r4 = t3 & 0x00fffff;
s1 = r1 * 5;
s2 = r2 * 5;
s3 = r3 * 5;
s4 = r4 * 5;
/* init state */
h0 = 0;
h1 = 0;
h2 = 0;
h3 = 0;
h4 = 0;
/* full blocks */
if(inlen < 16)
goto poly1305_donna_atmost15bytes;
poly1305_donna_16bytes:
m += 16;
inlen -= 16;
t0 = U8TO32_LE(m-16);
t1 = U8TO32_LE(m-12);
t2 = U8TO32_LE(m-8);
t3 = U8TO32_LE(m-4);
h0 += t0 & 0x3ffffff;
h1 += ((uint32_t)((((uint64_t)t1 << 32) | t0) >> 26) & 0x3ffffff);
h2 += ((uint32_t)((((uint64_t)t2 << 32) | t1) >> 20) & 0x3ffffff);
h3 += ((uint32_t)((((uint64_t)t3 << 32) | t2) >> 14) & 0x3ffffff);
h4 += (t3 >> 8) | (1 << 24);
poly1305_donna_mul:
t[0] = mul32x32_64(h0, r0) + mul32x32_64(h1, s4) + mul32x32_64(h2, s3) +
mul32x32_64(h3, s2) + mul32x32_64(h4, s1);
t[1] = mul32x32_64(h0, r1) + mul32x32_64(h1, r0) + mul32x32_64(h2, s4) +
mul32x32_64(h3, s3) + mul32x32_64(h4, s2);
t[2] = mul32x32_64(h0, r2) + mul32x32_64(h1, r1) + mul32x32_64(h2, r0) +
mul32x32_64(h3, s4) + mul32x32_64(h4, s3);
t[3] = mul32x32_64(h0, r3) + mul32x32_64(h1, r2) + mul32x32_64(h2, r1) +
mul32x32_64(h3, r0) + mul32x32_64(h4, s4);
t[4] = mul32x32_64(h0, r4) + mul32x32_64(h1, r3) + mul32x32_64(h2, r2) +
mul32x32_64(h3, r1) + mul32x32_64(h4, r0);
h0 = (uint32_t)t[0] & 0x3ffffff;
c = (t[0] >> 26);
t[1] += c;
h1 = (uint32_t)t[1] & 0x3ffffff;
b = (uint32_t)(t[1] >> 26);
t[2] += b;
h2 = (uint32_t)t[2] & 0x3ffffff;
b = (uint32_t)(t[2] >> 26);
t[3] += b;
h3 = (uint32_t)t[3] & 0x3ffffff;
b = (uint32_t)(t[3] >> 26);
t[4] += b;
h4 = (uint32_t)t[4] & 0x3ffffff;
b = (uint32_t)(t[4] >> 26);
h0 += b * 5;
if(inlen >= 16)
goto poly1305_donna_16bytes;
/* final bytes */
poly1305_donna_atmost15bytes:
if(!inlen)
goto poly1305_donna_finish;
for(j = 0; j < inlen; j++) mp[j] = m[j];
mp[j++] = 1;
for(; j < 16; j++)
mp[j] = 0;
inlen = 0;
t0 = U8TO32_LE(mp + 0);
t1 = U8TO32_LE(mp + 4);
t2 = U8TO32_LE(mp + 8);
t3 = U8TO32_LE(mp + 12);
h0 += t0 & 0x3ffffff;
h1 += ((uint32_t)((((uint64_t)t1 << 32) | t0) >> 26) & 0x3ffffff);
h2 += ((uint32_t)((((uint64_t)t2 << 32) | t1) >> 20) & 0x3ffffff);
h3 += ((uint32_t)((((uint64_t)t3 << 32) | t2) >> 14) & 0x3ffffff);
h4 += (t3 >> 8);
goto poly1305_donna_mul;
poly1305_donna_finish:
b = h0 >> 26; h0 = h0 & 0x3ffffff;
h1 += b; b = h1 >> 26; h1 = h1 & 0x3ffffff;
h2 += b; b = h2 >> 26; h2 = h2 & 0x3ffffff;
h3 += b; b = h3 >> 26; h3 = h3 & 0x3ffffff;
h4 += b; b = h4 >> 26; h4 = h4 & 0x3ffffff;
h0 += b * 5; b = h0 >> 26; h0 = h0 & 0x3ffffff;
h1 += b;
g0 = h0 + 5; b = g0 >> 26; g0 &= 0x3ffffff;
g1 = h1 + b; b = g1 >> 26; g1 &= 0x3ffffff;
g2 = h2 + b; b = g2 >> 26; g2 &= 0x3ffffff;
g3 = h3 + b; b = g3 >> 26; g3 &= 0x3ffffff;
g4 = h4 + b - (1 << 26);
b = (g4 >> 31) - 1;
nb = ~b;
h0 = (h0 & nb) | (g0 & b);
h1 = (h1 & nb) | (g1 & b);
h2 = (h2 & nb) | (g2 & b);
h3 = (h3 & nb) | (g3 & b);
h4 = (h4 & nb) | (g4 & b);
f0 = ((h0 ) | (h1 << 26)) + (uint64_t)U8TO32_LE(&key[16]);
f1 = ((h1 >> 6) | (h2 << 20)) + (uint64_t)U8TO32_LE(&key[20]);
f2 = ((h2 >> 12) | (h3 << 14)) + (uint64_t)U8TO32_LE(&key[24]);
f3 = ((h3 >> 18) | (h4 << 8)) + (uint64_t)U8TO32_LE(&key[28]);
U32TO8_LE(&out[ 0], f0); f1 += (f0 >> 32);
U32TO8_LE(&out[ 4], f1); f2 += (f1 >> 32);
U32TO8_LE(&out[ 8], f2); f3 += (f2 >> 32);
U32TO8_LE(&out[12], f3);
}

View file

@ -0,0 +1,20 @@
/* $OpenBSD: poly1305.h,v 1.4 2014/05/02 03:27:54 djm Exp $ */
/*
* Public Domain poly1305 from Andrew Moon
* poly1305-donna-unrolled.c from https://github.com/floodyberry/poly1305-donna
* Copyright not intended 2024.
*
* SPDX-License-Identifier: SAX-PD-2.0
*/
#ifndef POLY1305_H
#define POLY1305_H
#define POLY1305_KEYLEN 32
#define POLY1305_TAGLEN 16
void poly1305_auth(u_char out[POLY1305_TAGLEN], const u_char *m, size_t inlen,
const u_char key[POLY1305_KEYLEN]);
#endif /* POLY1305_H */

View file

@ -1,5 +1,5 @@
/* Copyright (c) 2004-2007, Sara Golemon <sarag@libssh2.org>
* Copyright (c) 2010-2014 by Daniel Stenberg
/* Copyright (C) Sara Golemon <sarag@libssh2.org>
* Copyright (C) Daniel Stenberg
* All rights reserved.
*
* Redistribution and use in source and binary forms,
@ -34,6 +34,8 @@
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
* USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
* OF SUCH DAMAGE.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#include "libssh2_priv.h"
@ -105,7 +107,7 @@ static const LIBSSH2_PUBLICKEY_CODE_LIST publickey_status_codes[] = {
*/
static void
publickey_status_error(const LIBSSH2_PUBLICKEY *pkey,
LIBSSH2_SESSION *session, int status)
LIBSSH2_SESSION *session, unsigned long status)
{
const char *msg;
@ -114,7 +116,7 @@ publickey_status_error(const LIBSSH2_PUBLICKEY *pkey,
status = 7;
}
if(status < 0 || status > LIBSSH2_PUBLICKEY_STATUS_CODE_MAX) {
if(status > LIBSSH2_PUBLICKEY_STATUS_CODE_MAX) {
msg = "unknown";
}
else {
@ -136,14 +138,14 @@ publickey_packet_receive(LIBSSH2_PUBLICKEY * pkey,
LIBSSH2_CHANNEL *channel = pkey->channel;
LIBSSH2_SESSION *session = channel->session;
unsigned char buffer[4];
int rc;
ssize_t rc;
*data = NULL; /* default to nothing returned */
*data_len = 0;
if(pkey->receive_state == libssh2_NB_state_idle) {
rc = _libssh2_channel_read(channel, 0, (char *) buffer, 4);
if(rc == LIBSSH2_ERROR_EAGAIN) {
return rc;
return (int)rc;
}
else if(rc != 4) {
return _libssh2_error(session, LIBSSH2_ERROR_PUBLICKEY_PROTOCOL,
@ -166,9 +168,9 @@ publickey_packet_receive(LIBSSH2_PUBLICKEY * pkey,
rc = _libssh2_channel_read(channel, 0, (char *) pkey->receive_packet,
pkey->receive_packet_len);
if(rc == LIBSSH2_ERROR_EAGAIN) {
return rc;
return (int)rc;
}
else if(rc != (int)pkey->receive_packet_len) {
else if(rc != (ssize_t)pkey->receive_packet_len) {
LIBSSH2_FREE(session, pkey->receive_packet);
pkey->receive_packet = NULL;
pkey->receive_state = libssh2_NB_state_idle;
@ -234,7 +236,7 @@ publickey_response_success(LIBSSH2_PUBLICKEY * pkey)
size_t data_len;
int response;
while(1) {
for(;;) {
int rc = publickey_packet_receive(pkey, &data, &data_len);
if(rc == LIBSSH2_ERROR_EAGAIN) {
return rc;
@ -272,7 +274,7 @@ publickey_response_success(LIBSSH2_PUBLICKEY * pkey)
return 0;
publickey_status_error(pkey, session, status);
return -1;
goto err_exit;
}
default:
LIBSSH2_FREE(session, data);
@ -287,7 +289,7 @@ publickey_response_success(LIBSSH2_PUBLICKEY * pkey)
data = NULL;
}
}
/* never reached, but include `return` to silence compiler warnings */
err_exit:
return -1;
}
@ -310,8 +312,8 @@ static LIBSSH2_PUBLICKEY *publickey_init(LIBSSH2_SESSION *session)
session->pkeyInit_pkey = NULL;
session->pkeyInit_channel = NULL;
_libssh2_debug(session, LIBSSH2_TRACE_PUBLICKEY,
"Initializing publickey subsystem");
_libssh2_debug((session, LIBSSH2_TRACE_PUBLICKEY,
"Initializing publickey subsystem"));
session->pkeyInit_state = libssh2_NB_state_allocated;
}
@ -387,28 +389,29 @@ static LIBSSH2_PUBLICKEY *publickey_init(LIBSSH2_SESSION *session)
session->pkeyInit_buffer_sent = 0;
_libssh2_debug(session, LIBSSH2_TRACE_PUBLICKEY,
_libssh2_debug((session, LIBSSH2_TRACE_PUBLICKEY,
"Sending publickey advertising version %d support",
(int) LIBSSH2_PUBLICKEY_VERSION);
(int) LIBSSH2_PUBLICKEY_VERSION));
session->pkeyInit_state = libssh2_NB_state_sent2;
}
if(session->pkeyInit_state == libssh2_NB_state_sent2) {
rc = _libssh2_channel_write(session->pkeyInit_channel, 0,
session->pkeyInit_buffer,
19 - session->pkeyInit_buffer_sent);
if(rc == LIBSSH2_ERROR_EAGAIN) {
ssize_t nwritten;
nwritten = _libssh2_channel_write(session->pkeyInit_channel, 0,
session->pkeyInit_buffer,
19 - session->pkeyInit_buffer_sent);
if(nwritten == LIBSSH2_ERROR_EAGAIN) {
_libssh2_error(session, LIBSSH2_ERROR_EAGAIN,
"Would block sending publickey version packet");
return NULL;
}
else if(rc < 0) {
_libssh2_error(session, rc,
else if(nwritten < 0) {
_libssh2_error(session, (int)nwritten,
"Unable to send publickey version packet");
goto err_exit;
}
session->pkeyInit_buffer_sent += rc;
session->pkeyInit_buffer_sent += nwritten;
if(session->pkeyInit_buffer_sent < 19) {
_libssh2_error(session, LIBSSH2_ERROR_EAGAIN,
"Need to be called again to complete this");
@ -419,7 +422,7 @@ static LIBSSH2_PUBLICKEY *publickey_init(LIBSSH2_SESSION *session)
}
if(session->pkeyInit_state == libssh2_NB_state_sent3) {
while(1) {
for(;;) {
unsigned char *s;
rc = publickey_packet_receive(session->pkeyInit_pkey,
&session->pkeyInit_data,
@ -511,16 +514,16 @@ static LIBSSH2_PUBLICKEY *publickey_init(LIBSSH2_SESSION *session)
session->pkeyInit_pkey->version = _libssh2_ntohu32(s);
if(session->pkeyInit_pkey->version >
LIBSSH2_PUBLICKEY_VERSION) {
_libssh2_debug(session, LIBSSH2_TRACE_PUBLICKEY,
_libssh2_debug((session, LIBSSH2_TRACE_PUBLICKEY,
"Truncate remote publickey version "
"from %lu",
session->pkeyInit_pkey->version);
"from %u",
session->pkeyInit_pkey->version));
session->pkeyInit_pkey->version =
LIBSSH2_PUBLICKEY_VERSION;
}
_libssh2_debug(session, LIBSSH2_TRACE_PUBLICKEY,
"Enabling publickey subsystem version %lu",
session->pkeyInit_pkey->version);
_libssh2_debug((session, LIBSSH2_TRACE_PUBLICKEY,
"Enabling publickey subsystem version %u",
session->pkeyInit_pkey->version));
LIBSSH2_FREE(session, session->pkeyInit_data);
session->pkeyInit_data = NULL;
session->pkeyInit_state = libssh2_NB_state_idle;
@ -538,7 +541,7 @@ static LIBSSH2_PUBLICKEY *publickey_init(LIBSSH2_SESSION *session)
}
/* Never reached except by direct goto */
err_exit:
err_exit:
session->pkeyInit_state = libssh2_NB_state_sent4;
if(session->pkeyInit_channel) {
rc = _libssh2_channel_close(session->pkeyInit_channel);
@ -607,8 +610,8 @@ libssh2_publickey_add_ex(LIBSSH2_PUBLICKEY *pkey, const unsigned char *name,
if(pkey->add_state == libssh2_NB_state_idle) {
pkey->add_packet = NULL;
_libssh2_debug(session, LIBSSH2_TRACE_PUBLICKEY, "Adding %s publickey",
name);
_libssh2_debug((session, LIBSSH2_TRACE_PUBLICKEY,
"Adding %s publickey", name));
if(pkey->version == 1) {
for(i = 0; i < num_attrs; i++) {
@ -639,25 +642,25 @@ libssh2_publickey_add_ex(LIBSSH2_PUBLICKEY *pkey, const unsigned char *name,
}
pkey->add_s = pkey->add_packet;
_libssh2_htonu32(pkey->add_s, packet_len - 4);
_libssh2_htonu32(pkey->add_s, (uint32_t)(packet_len - 4));
pkey->add_s += 4;
_libssh2_htonu32(pkey->add_s, sizeof("add") - 1);
pkey->add_s += 4;
memcpy(pkey->add_s, "add", sizeof("add") - 1);
pkey->add_s += sizeof("add") - 1;
if(pkey->version == 1) {
_libssh2_htonu32(pkey->add_s, comment_len);
_libssh2_htonu32(pkey->add_s, (uint32_t)comment_len);
pkey->add_s += 4;
if(comment) {
memcpy(pkey->add_s, comment, comment_len);
pkey->add_s += comment_len;
}
_libssh2_htonu32(pkey->add_s, name_len);
_libssh2_htonu32(pkey->add_s, (uint32_t)name_len);
pkey->add_s += 4;
memcpy(pkey->add_s, name, name_len);
pkey->add_s += name_len;
_libssh2_htonu32(pkey->add_s, blob_len);
_libssh2_htonu32(pkey->add_s, (uint32_t)blob_len);
pkey->add_s += 4;
memcpy(pkey->add_s, blob, blob_len);
pkey->add_s += blob_len;
@ -665,23 +668,23 @@ libssh2_publickey_add_ex(LIBSSH2_PUBLICKEY *pkey, const unsigned char *name,
else {
/* Version == 2 */
_libssh2_htonu32(pkey->add_s, name_len);
_libssh2_htonu32(pkey->add_s, (uint32_t)name_len);
pkey->add_s += 4;
memcpy(pkey->add_s, name, name_len);
pkey->add_s += name_len;
_libssh2_htonu32(pkey->add_s, blob_len);
_libssh2_htonu32(pkey->add_s, (uint32_t)blob_len);
pkey->add_s += 4;
memcpy(pkey->add_s, blob, blob_len);
pkey->add_s += blob_len;
*(pkey->add_s++) = overwrite ? 0x01 : 0;
_libssh2_htonu32(pkey->add_s, num_attrs);
_libssh2_htonu32(pkey->add_s, (uint32_t)num_attrs);
pkey->add_s += 4;
for(i = 0; i < num_attrs; i++) {
_libssh2_htonu32(pkey->add_s, attrs[i].name_len);
_libssh2_htonu32(pkey->add_s, (uint32_t)attrs[i].name_len);
pkey->add_s += 4;
memcpy(pkey->add_s, attrs[i].name, attrs[i].name_len);
pkey->add_s += attrs[i].name_len;
_libssh2_htonu32(pkey->add_s, attrs[i].value_len);
_libssh2_htonu32(pkey->add_s, (uint32_t)attrs[i].value_len);
pkey->add_s += 4;
memcpy(pkey->add_s, attrs[i].value, attrs[i].value_len);
pkey->add_s += attrs[i].value_len;
@ -689,21 +692,22 @@ libssh2_publickey_add_ex(LIBSSH2_PUBLICKEY *pkey, const unsigned char *name,
}
}
_libssh2_debug(session, LIBSSH2_TRACE_PUBLICKEY,
_libssh2_debug((session, LIBSSH2_TRACE_PUBLICKEY,
"Sending publickey \"add\" packet: "
"type=%s blob_len=%ld num_attrs=%ld",
name, blob_len, num_attrs);
name, blob_len, num_attrs));
pkey->add_state = libssh2_NB_state_created;
}
if(pkey->add_state == libssh2_NB_state_created) {
rc = _libssh2_channel_write(channel, 0, pkey->add_packet,
(pkey->add_s - pkey->add_packet));
if(rc == LIBSSH2_ERROR_EAGAIN) {
return rc;
ssize_t nwritten;
nwritten = _libssh2_channel_write(channel, 0, pkey->add_packet,
(pkey->add_s - pkey->add_packet));
if(nwritten == LIBSSH2_ERROR_EAGAIN) {
return (int)nwritten;
}
else if((pkey->add_s - pkey->add_packet) != rc) {
else if((pkey->add_s - pkey->add_packet) != nwritten) {
LIBSSH2_FREE(session, pkey->add_packet);
pkey->add_packet = NULL;
return _libssh2_error(session, LIBSSH2_ERROR_SOCKET_SEND,
@ -758,36 +762,37 @@ libssh2_publickey_remove_ex(LIBSSH2_PUBLICKEY * pkey,
}
pkey->remove_s = pkey->remove_packet;
_libssh2_htonu32(pkey->remove_s, packet_len - 4);
_libssh2_htonu32(pkey->remove_s, (uint32_t)(packet_len - 4));
pkey->remove_s += 4;
_libssh2_htonu32(pkey->remove_s, sizeof("remove") - 1);
pkey->remove_s += 4;
memcpy(pkey->remove_s, "remove", sizeof("remove") - 1);
pkey->remove_s += sizeof("remove") - 1;
_libssh2_htonu32(pkey->remove_s, name_len);
_libssh2_htonu32(pkey->remove_s, (uint32_t)name_len);
pkey->remove_s += 4;
memcpy(pkey->remove_s, name, name_len);
pkey->remove_s += name_len;
_libssh2_htonu32(pkey->remove_s, blob_len);
_libssh2_htonu32(pkey->remove_s, (uint32_t)blob_len);
pkey->remove_s += 4;
memcpy(pkey->remove_s, blob, blob_len);
pkey->remove_s += blob_len;
_libssh2_debug(session, LIBSSH2_TRACE_PUBLICKEY,
_libssh2_debug((session, LIBSSH2_TRACE_PUBLICKEY,
"Sending publickey \"remove\" packet: "
"type=%s blob_len=%ld",
name, blob_len);
name, blob_len));
pkey->remove_state = libssh2_NB_state_created;
}
if(pkey->remove_state == libssh2_NB_state_created) {
rc = _libssh2_channel_write(channel, 0, pkey->remove_packet,
(pkey->remove_s - pkey->remove_packet));
if(rc == LIBSSH2_ERROR_EAGAIN) {
return rc;
ssize_t nwritten;
nwritten = _libssh2_channel_write(channel, 0, pkey->remove_packet,
(pkey->remove_s - pkey->remove_packet));
if(nwritten == LIBSSH2_ERROR_EAGAIN) {
return (int)nwritten;
}
else if((pkey->remove_s - pkey->remove_packet) != rc) {
else if((pkey->remove_s - pkey->remove_packet) != nwritten) {
LIBSSH2_FREE(session, pkey->remove_packet);
pkey->remove_packet = NULL;
pkey->remove_state = libssh2_NB_state_idle;
@ -835,28 +840,29 @@ libssh2_publickey_list_fetch(LIBSSH2_PUBLICKEY * pkey, unsigned long *num_keys,
pkey->listFetch_data = NULL;
pkey->listFetch_s = pkey->listFetch_buffer;
_libssh2_htonu32(pkey->listFetch_s, buffer_len - 4);
_libssh2_htonu32(pkey->listFetch_s, (uint32_t)(buffer_len - 4));
pkey->listFetch_s += 4;
_libssh2_htonu32(pkey->listFetch_s, sizeof("list") - 1);
pkey->listFetch_s += 4;
memcpy(pkey->listFetch_s, "list", sizeof("list") - 1);
pkey->listFetch_s += sizeof("list") - 1;
_libssh2_debug(session, LIBSSH2_TRACE_PUBLICKEY,
"Sending publickey \"list\" packet");
_libssh2_debug((session, LIBSSH2_TRACE_PUBLICKEY,
"Sending publickey \"list\" packet"));
pkey->listFetch_state = libssh2_NB_state_created;
}
if(pkey->listFetch_state == libssh2_NB_state_created) {
rc = _libssh2_channel_write(channel, 0,
pkey->listFetch_buffer,
(pkey->listFetch_s -
pkey->listFetch_buffer));
if(rc == LIBSSH2_ERROR_EAGAIN) {
return rc;
ssize_t nwritten;
nwritten = _libssh2_channel_write(channel, 0,
pkey->listFetch_buffer,
(pkey->listFetch_s -
pkey->listFetch_buffer));
if(nwritten == LIBSSH2_ERROR_EAGAIN) {
return (int)nwritten;
}
else if((pkey->listFetch_s - pkey->listFetch_buffer) != rc) {
else if((pkey->listFetch_s - pkey->listFetch_buffer) != nwritten) {
pkey->listFetch_state = libssh2_NB_state_idle;
return _libssh2_error(session, LIBSSH2_ERROR_SOCKET_SEND,
"Unable to send publickey list packet");
@ -865,7 +871,7 @@ libssh2_publickey_list_fetch(LIBSSH2_PUBLICKEY * pkey, unsigned long *num_keys,
pkey->listFetch_state = libssh2_NB_state_sent;
}
while(1) {
for(;;) {
rc = publickey_packet_receive(pkey, &pkey->listFetch_data,
&pkey->listFetch_data_len);
if(rc == LIBSSH2_ERROR_EAGAIN) {
@ -1197,7 +1203,7 @@ libssh2_publickey_list_fetch(LIBSSH2_PUBLICKEY * pkey, unsigned long *num_keys,
}
/* Only reached via explicit goto */
err_exit:
err_exit:
if(pkey->listFetch_data) {
LIBSSH2_FREE(session, pkey->listFetch_data);
pkey->listFetch_data = NULL;

View file

@ -1,5 +1,5 @@
/* Copyright (c) 2009-2019 by Daniel Stenberg
* Copyright (c) 2004-2008, Sara Golemon <sarag@libssh2.org>
/* Copyright (C) Daniel Stenberg
* Copyright (C) Sara Golemon <sarag@libssh2.org>
* All rights reserved.
*
* Redistribution and use in source and binary forms,
@ -34,15 +34,24 @@
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
* USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
* OF SUCH DAMAGE.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#include "libssh2_priv.h"
#include <errno.h>
#include <stdlib.h>
#include "channel.h"
#include "session.h"
#include <stdlib.h> /* strtoll(), _strtoi64(), strtol() */
#if defined(HAVE_STRTOLL)
#define scpsize_strtol strtoll
#elif defined(HAVE_STRTOI64)
#define scpsize_strtol _strtoi64
#else
#define scpsize_strtol strtol
#endif
/* Max. length of a quoted string after libssh2_shell_quotearg() processing */
#define _libssh2_shell_quotedsize(s) (3 * strlen(s) + 2)
@ -112,7 +121,7 @@
References:
o csh-compatible quotation (special handling for '!' etc.), see
http://www.grymoire.com/Unix/Csh.html#toc-uh-10
https://www.grymoire.com/Unix/Csh.html#toc-uh-10
Return value:
Length of the resulting string (not counting the terminating '\0'),
@ -122,9 +131,9 @@
until then it is kept static and in this source file.
*/
static unsigned
static size_t
shell_quotearg(const char *path, unsigned char *buf,
unsigned bufsize)
size_t bufsize)
{
const char *src;
unsigned char *dst, *endp;
@ -270,7 +279,7 @@ shell_quotearg(const char *path, unsigned char *buf,
static LIBSSH2_CHANNEL *
scp_recv(LIBSSH2_SESSION * session, const char *path, libssh2_struct_stat * sb)
{
int cmd_len;
size_t cmd_len;
int rc;
int tmp_err_code;
const char *tmp_err_msg;
@ -282,7 +291,7 @@ scp_recv(LIBSSH2_SESSION * session, const char *path, libssh2_struct_stat * sb)
session->scpRecv_atime = 0;
session->scpRecv_command_len =
_libssh2_shell_quotedsize(path) + sizeof("scp -f ") + (sb?1:0);
_libssh2_shell_quotedsize(path) + sizeof("scp -f ") + (sb ? 1 : 0);
session->scpRecv_command =
LIBSSH2_ALLOC(session, session->scpRecv_command_len);
@ -296,18 +305,30 @@ scp_recv(LIBSSH2_SESSION * session, const char *path, libssh2_struct_stat * sb)
snprintf((char *)session->scpRecv_command,
session->scpRecv_command_len,
"scp -%sf ", sb?"p":"");
"scp -%sf ", sb ? "p" : "");
cmd_len = strlen((char *)session->scpRecv_command);
cmd_len += shell_quotearg(path,
&session->scpRecv_command[cmd_len],
session->scpRecv_command_len - cmd_len);
if(!session->flag.quote_paths) {
size_t path_len;
path_len = strlen(path);
/* no NUL-termination needed, so memcpy will do */
memcpy(&session->scpRecv_command[cmd_len], path, path_len);
cmd_len += path_len;
}
else {
cmd_len += shell_quotearg(path,
&session->scpRecv_command[cmd_len],
session->scpRecv_command_len - cmd_len);
}
/* the command to exec should _not_ be NUL-terminated */
session->scpRecv_command_len = cmd_len;
_libssh2_debug(session, LIBSSH2_TRACE_SCP,
"Opening channel for SCP receive");
_libssh2_debug((session, LIBSSH2_TRACE_SCP,
"Opening channel for SCP receive"));
session->scpRecv_state = libssh2_NB_state_created;
}
@ -356,7 +377,7 @@ scp_recv(LIBSSH2_SESSION * session, const char *path, libssh2_struct_stat * sb)
LIBSSH2_FREE(session, session->scpRecv_command);
session->scpRecv_command = NULL;
_libssh2_debug(session, LIBSSH2_TRACE_SCP, "Sending initial wakeup");
_libssh2_debug((session, LIBSSH2_TRACE_SCP, "Sending initial wakeup"));
/* SCP ACK */
session->scpRecv_response[0] = '\0';
@ -364,8 +385,8 @@ scp_recv(LIBSSH2_SESSION * session, const char *path, libssh2_struct_stat * sb)
}
if(session->scpRecv_state == libssh2_NB_state_sent1) {
rc = _libssh2_channel_write(session->scpRecv_channel, 0,
session->scpRecv_response, 1);
rc = (int)_libssh2_channel_write(session->scpRecv_channel, 0,
session->scpRecv_response, 1);
if(rc == LIBSSH2_ERROR_EAGAIN) {
_libssh2_error(session, LIBSSH2_ERROR_EAGAIN,
"Would block sending initial wakeup");
@ -384,14 +405,15 @@ scp_recv(LIBSSH2_SESSION * session, const char *path, libssh2_struct_stat * sb)
if((session->scpRecv_state == libssh2_NB_state_sent2)
|| (session->scpRecv_state == libssh2_NB_state_sent3)) {
while(sb && (session->scpRecv_response_len <
LIBSSH2_SCP_RESPONSE_BUFLEN)) {
LIBSSH2_SCP_RESPONSE_BUFLEN)) {
unsigned char *s, *p;
if(session->scpRecv_state == libssh2_NB_state_sent2) {
rc = _libssh2_channel_read(session->scpRecv_channel, 0,
(char *) session->
scpRecv_response +
session->scpRecv_response_len, 1);
rc = (int)_libssh2_channel_read(session->scpRecv_channel, 0,
(char *) session->
scpRecv_response +
session->scpRecv_response_len,
1);
if(rc == LIBSSH2_ERROR_EAGAIN) {
_libssh2_error(session, LIBSSH2_ERROR_EAGAIN,
"Would block waiting for SCP response");
@ -435,9 +457,9 @@ scp_recv(LIBSSH2_SESSION * session, const char *path, libssh2_struct_stat * sb)
/* zero terminate the error */
err_msg[err_len] = 0;
_libssh2_debug(session, LIBSSH2_TRACE_SCP,
_libssh2_debug((session, LIBSSH2_TRACE_SCP,
"got %02x %s", session->scpRecv_response[0],
err_msg);
err_msg));
_libssh2_error(session, LIBSSH2_ERROR_SCP_PROTOCOL,
"Failed to recv file");
@ -550,8 +572,8 @@ scp_recv(LIBSSH2_SESSION * session, const char *path, libssh2_struct_stat * sb)
}
if(session->scpRecv_state == libssh2_NB_state_sent3) {
rc = _libssh2_channel_write(session->scpRecv_channel, 0,
session->scpRecv_response, 1);
rc = (int)_libssh2_channel_write(session->scpRecv_channel, 0,
session->scpRecv_response, 1);
if(rc == LIBSSH2_ERROR_EAGAIN) {
_libssh2_error(session, LIBSSH2_ERROR_EAGAIN,
"Would block waiting to send SCP ACK");
@ -561,9 +583,10 @@ scp_recv(LIBSSH2_SESSION * session, const char *path, libssh2_struct_stat * sb)
goto scp_recv_error;
}
_libssh2_debug(session, LIBSSH2_TRACE_SCP,
_libssh2_debug((session, LIBSSH2_TRACE_SCP,
"mtime = %ld, atime = %ld",
session->scpRecv_mtime, session->scpRecv_atime);
session->scpRecv_mtime,
session->scpRecv_atime));
/* We *should* check that atime.usec is valid, but why let
that stop use? */
@ -586,17 +609,18 @@ scp_recv(LIBSSH2_SESSION * session, const char *path, libssh2_struct_stat * sb)
char *s, *p, *e = NULL;
if(session->scpRecv_state == libssh2_NB_state_sent5) {
rc = _libssh2_channel_read(session->scpRecv_channel, 0,
(char *) session->
scpRecv_response +
session->scpRecv_response_len, 1);
rc = (int)_libssh2_channel_read(session->scpRecv_channel, 0,
(char *) session->
scpRecv_response +
session->scpRecv_response_len,
1);
if(rc == LIBSSH2_ERROR_EAGAIN) {
_libssh2_error(session, LIBSSH2_ERROR_EAGAIN,
"Would block waiting for SCP response");
return NULL;
}
else if(rc < 0) {
/* error, bail out*/
/* error, bail out */
_libssh2_error(session, rc, "Failed reading SCP response");
goto scp_recv_error;
}
@ -678,7 +702,6 @@ scp_recv(LIBSSH2_SESSION * session, const char *path, libssh2_struct_stat * sb)
*(p++) = '\0';
/* Make sure we don't get fooled by leftover values */
session->scpRecv_mode = strtol(s, &e, 8);
if(e && *e) {
_libssh2_error(session, LIBSSH2_ERROR_SCP_PROTOCOL,
@ -713,8 +736,8 @@ scp_recv(LIBSSH2_SESSION * session, const char *path, libssh2_struct_stat * sb)
}
if(session->scpRecv_state == libssh2_NB_state_sent6) {
rc = _libssh2_channel_write(session->scpRecv_channel, 0,
session->scpRecv_response, 1);
rc = (int)_libssh2_channel_write(session->scpRecv_channel, 0,
session->scpRecv_response, 1);
if(rc == LIBSSH2_ERROR_EAGAIN) {
_libssh2_error(session, LIBSSH2_ERROR_EAGAIN,
"Would block sending SCP ACK");
@ -723,9 +746,9 @@ scp_recv(LIBSSH2_SESSION * session, const char *path, libssh2_struct_stat * sb)
else if(rc != 1) {
goto scp_recv_error;
}
_libssh2_debug(session, LIBSSH2_TRACE_SCP,
_libssh2_debug((session, LIBSSH2_TRACE_SCP,
"mode = 0%lo size = %ld", session->scpRecv_mode,
session->scpRecv_size);
(long)session->scpRecv_size));
/* We *should* check that basename is valid, but why let that
stop us? */
@ -741,14 +764,14 @@ scp_recv(LIBSSH2_SESSION * session, const char *path, libssh2_struct_stat * sb)
sb->st_mtime = session->scpRecv_mtime;
sb->st_atime = session->scpRecv_atime;
sb->st_size = session->scpRecv_size;
sb->st_size = (libssh2_struct_stat_size)session->scpRecv_size;
sb->st_mode = (unsigned short)session->scpRecv_mode;
}
session->scpRecv_state = libssh2_NB_state_idle;
return session->scpRecv_channel;
scp_recv_empty_channel:
scp_recv_empty_channel:
/* the code only jumps here as a result of a zero read from channel_read()
so we check EOF status to avoid getting stuck in a loop */
if(libssh2_channel_eof(session->scpRecv_channel))
@ -757,11 +780,11 @@ scp_recv(LIBSSH2_SESSION * session, const char *path, libssh2_struct_stat * sb)
else
return session->scpRecv_channel;
/* fall-through */
scp_recv_error:
scp_recv_error:
tmp_err_code = session->err_code;
tmp_err_msg = session->err_msg;
while(libssh2_channel_free(session->scpRecv_channel) ==
LIBSSH2_ERROR_EAGAIN);
LIBSSH2_ERROR_EAGAIN);
session->err_code = tmp_err_code;
session->err_msg = tmp_err_msg;
session->scpRecv_channel = NULL;
@ -769,6 +792,7 @@ scp_recv(LIBSSH2_SESSION * session, const char *path, libssh2_struct_stat * sb)
return NULL;
}
#ifndef LIBSSH2_NO_DEPRECATED
/*
* libssh2_scp_recv
*
@ -780,7 +804,7 @@ scp_recv(LIBSSH2_SESSION * session, const char *path, libssh2_struct_stat * sb)
*
*/
LIBSSH2_API LIBSSH2_CHANNEL *
libssh2_scp_recv(LIBSSH2_SESSION *session, const char *path, struct stat * sb)
libssh2_scp_recv(LIBSSH2_SESSION *session, const char *path, struct stat *sb)
{
LIBSSH2_CHANNEL *ptr;
@ -805,6 +829,7 @@ libssh2_scp_recv(LIBSSH2_SESSION *session, const char *path, struct stat * sb)
return ptr;
}
#endif
/*
* libssh2_scp_recv2
@ -823,7 +848,7 @@ libssh2_scp_recv2(LIBSSH2_SESSION *session, const char *path,
}
/*
* scp_send()
* scp_send
*
* Send a file using SCP
*
@ -832,7 +857,7 @@ static LIBSSH2_CHANNEL *
scp_send(LIBSSH2_SESSION * session, const char *path, int mode,
libssh2_int64_t size, time_t mtime, time_t atime)
{
int cmd_len;
size_t cmd_len;
int rc;
int tmp_err_code;
const char *tmp_err_msg;
@ -840,7 +865,7 @@ scp_send(LIBSSH2_SESSION * session, const char *path, int mode,
if(session->scpSend_state == libssh2_NB_state_idle) {
session->scpSend_command_len =
_libssh2_shell_quotedsize(path) + sizeof("scp -t ") +
((mtime || atime)?1:0);
((mtime || atime) ? 1 : 0);
session->scpSend_command =
LIBSSH2_ALLOC(session, session->scpSend_command_len);
@ -854,18 +879,31 @@ scp_send(LIBSSH2_SESSION * session, const char *path, int mode,
snprintf((char *)session->scpSend_command,
session->scpSend_command_len,
"scp -%st ", (mtime || atime)?"p":"");
"scp -%st ", (mtime || atime) ? "p" : "");
cmd_len = strlen((char *)session->scpSend_command);
cmd_len += shell_quotearg(path,
&session->scpSend_command[cmd_len],
session->scpSend_command_len - cmd_len);
if(!session->flag.quote_paths) {
size_t path_len;
path_len = strlen(path);
/* no NUL-termination needed, so memcpy will do */
memcpy(&session->scpSend_command[cmd_len], path, path_len);
cmd_len += path_len;
}
else {
cmd_len += shell_quotearg(path,
&session->scpSend_command[cmd_len],
session->scpSend_command_len - cmd_len);
}
/* the command to exec should _not_ be NUL-terminated */
session->scpSend_command_len = cmd_len;
_libssh2_debug(session, LIBSSH2_TRACE_SCP,
"Opening channel for SCP send");
_libssh2_debug((session, LIBSSH2_TRACE_SCP,
"Opening channel for SCP send"));
/* Allocate a channel */
session->scpSend_state = libssh2_NB_state_created;
@ -922,8 +960,8 @@ scp_send(LIBSSH2_SESSION * session, const char *path, int mode,
if(session->scpSend_state == libssh2_NB_state_sent1) {
/* Wait for ACK */
rc = _libssh2_channel_read(session->scpSend_channel, 0,
(char *) session->scpSend_response, 1);
rc = (int)_libssh2_channel_read(session->scpSend_channel, 0,
(char *) session->scpSend_response, 1);
if(rc == LIBSSH2_ERROR_EAGAIN) {
_libssh2_error(session, LIBSSH2_ERROR_EAGAIN,
"Would block waiting for response from remote");
@ -936,7 +974,7 @@ scp_send(LIBSSH2_SESSION * session, const char *path, int mode,
else if(!rc)
/* remain in the same state */
goto scp_send_empty_channel;
else if(session->scpSend_response[0] != 0) {
else if(session->scpSend_response[0]) {
_libssh2_error(session, LIBSSH2_ERROR_SCP_PROTOCOL,
"Invalid ACK response from remote");
goto scp_send_error;
@ -947,8 +985,8 @@ scp_send(LIBSSH2_SESSION * session, const char *path, int mode,
snprintf((char *) session->scpSend_response,
LIBSSH2_SCP_RESPONSE_BUFLEN, "T%ld 0 %ld 0\n",
(long)mtime, (long)atime);
_libssh2_debug(session, LIBSSH2_TRACE_SCP, "Sent %s",
session->scpSend_response);
_libssh2_debug((session, LIBSSH2_TRACE_SCP, "Sent %s",
session->scpSend_response));
}
session->scpSend_state = libssh2_NB_state_sent2;
@ -957,9 +995,9 @@ scp_send(LIBSSH2_SESSION * session, const char *path, int mode,
/* Send mtime and atime to be used for file */
if(mtime || atime) {
if(session->scpSend_state == libssh2_NB_state_sent2) {
rc = _libssh2_channel_write(session->scpSend_channel, 0,
session->scpSend_response,
session->scpSend_response_len);
rc = (int)_libssh2_channel_write(session->scpSend_channel, 0,
session->scpSend_response,
session->scpSend_response_len);
if(rc == LIBSSH2_ERROR_EAGAIN) {
_libssh2_error(session, LIBSSH2_ERROR_EAGAIN,
"Would block sending time data for SCP file");
@ -976,8 +1014,9 @@ scp_send(LIBSSH2_SESSION * session, const char *path, int mode,
if(session->scpSend_state == libssh2_NB_state_sent3) {
/* Wait for ACK */
rc = _libssh2_channel_read(session->scpSend_channel, 0,
(char *) session->scpSend_response, 1);
rc = (int)_libssh2_channel_read(session->scpSend_channel, 0,
(char *) session->scpSend_response,
1);
if(rc == LIBSSH2_ERROR_EAGAIN) {
_libssh2_error(session, LIBSSH2_ERROR_EAGAIN,
"Would block waiting for response");
@ -990,7 +1029,7 @@ scp_send(LIBSSH2_SESSION * session, const char *path, int mode,
else if(!rc)
/* remain in the same state */
goto scp_send_empty_channel;
else if(session->scpSend_response[0] != 0) {
else if(session->scpSend_response[0]) {
_libssh2_error(session, LIBSSH2_ERROR_SCP_PROTOCOL,
"Invalid SCP ACK response");
goto scp_send_error;
@ -1018,16 +1057,16 @@ scp_send(LIBSSH2_SESSION * session, const char *path, int mode,
LIBSSH2_SCP_RESPONSE_BUFLEN, "C0%o %"
LIBSSH2_INT64_T_FORMAT " %s\n", mode,
size, base);
_libssh2_debug(session, LIBSSH2_TRACE_SCP, "Sent %s",
session->scpSend_response);
_libssh2_debug((session, LIBSSH2_TRACE_SCP, "Sent %s",
session->scpSend_response));
session->scpSend_state = libssh2_NB_state_sent5;
}
if(session->scpSend_state == libssh2_NB_state_sent5) {
rc = _libssh2_channel_write(session->scpSend_channel, 0,
session->scpSend_response,
session->scpSend_response_len);
rc = (int)_libssh2_channel_write(session->scpSend_channel, 0,
session->scpSend_response,
session->scpSend_response_len);
if(rc == LIBSSH2_ERROR_EAGAIN) {
_libssh2_error(session, LIBSSH2_ERROR_EAGAIN,
"Would block send core file data for SCP file");
@ -1044,8 +1083,9 @@ scp_send(LIBSSH2_SESSION * session, const char *path, int mode,
if(session->scpSend_state == libssh2_NB_state_sent6) {
/* Wait for ACK */
rc = _libssh2_channel_read(session->scpSend_channel, 0,
(char *) session->scpSend_response, 1);
rc = (int)_libssh2_channel_read(session->scpSend_channel, 0,
(char *) session->scpSend_response,
1);
if(rc == LIBSSH2_ERROR_EAGAIN) {
_libssh2_error(session, LIBSSH2_ERROR_EAGAIN,
"Would block waiting for response");
@ -1059,7 +1099,7 @@ scp_send(LIBSSH2_SESSION * session, const char *path, int mode,
else if(rc == 0)
goto scp_send_empty_channel;
else if(session->scpSend_response[0] != 0) {
else if(session->scpSend_response[0]) {
size_t err_len;
char *err_msg;
@ -1073,13 +1113,13 @@ scp_send(LIBSSH2_SESSION * session, const char *path, int mode,
}
/* Read the remote error message */
rc = _libssh2_channel_read(session->scpSend_channel, 0,
err_msg, err_len);
rc = (int)_libssh2_channel_read(session->scpSend_channel, 0,
err_msg, err_len);
if(rc > 0) {
err_msg[err_len] = 0;
_libssh2_debug(session, LIBSSH2_TRACE_SCP,
_libssh2_debug((session, LIBSSH2_TRACE_SCP,
"got %02x %s", session->scpSend_response[0],
err_msg);
err_msg));
}
LIBSSH2_FREE(session, err_msg);
_libssh2_error(session, LIBSSH2_ERROR_SCP_PROTOCOL,
@ -1091,7 +1131,7 @@ scp_send(LIBSSH2_SESSION * session, const char *path, int mode,
session->scpSend_state = libssh2_NB_state_idle;
return session->scpSend_channel;
scp_send_empty_channel:
scp_send_empty_channel:
/* the code only jumps here as a result of a zero read from channel_read()
so we check EOF status to avoid getting stuck in a loop */
if(libssh2_channel_eof(session->scpSend_channel)) {
@ -1101,7 +1141,7 @@ scp_send(LIBSSH2_SESSION * session, const char *path, int mode,
else
return session->scpSend_channel;
/* fall-through */
scp_send_error:
scp_send_error:
tmp_err_code = session->err_code;
tmp_err_msg = session->err_msg;
while(libssh2_channel_free(session->scpSend_channel) ==

File diff suppressed because it is too large Load diff

View file

@ -1,8 +1,8 @@
#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>
#ifndef LIBSSH2_SESSION_H
#define LIBSSH2_SESSION_H
/* Copyright (C) Sara Golemon <sarag@libssh2.org>
* Copyright (C) Daniel Stenberg
* Copyright (C) Simon Josefsson <simon@josefsson.org>
* All rights reserved.
*
* Redistribution and use in source and binary forms,
@ -37,31 +37,32 @@
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
* USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
* OF SUCH DAMAGE.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
/* Conveniance-macros to allow code like this;
int rc = BLOCK_ADJUST(rc, session, session_startup(session, sock) );
int rc = BLOCK_ADJUST(rc, session, session_startup(session, sock));
int rc = BLOCK_ADJUST_ERRNO(ptr, session, session_startup(session, sock) );
int rc = BLOCK_ADJUST_ERRNO(ptr, session, session_startup(session, sock));
The point of course being to make sure that while in non-blocking mode
these always return no matter what the return code is, but in blocking mode
it blocks if EAGAIN is the reason for the return from the underlying
function.
The point being to make sure that while in non-blocking mode these always
return no matter what the return code is, but in blocking mode it blocks
if EAGAIN is the reason for the return from the underlying function.
*/
#define BLOCK_ADJUST(rc, sess, x) \
do { \
time_t entry_time = time(NULL); \
do { \
rc = x; \
/* the order of the check below is important to properly deal with \
the case when the 'sess' is freed */ \
if((rc != LIBSSH2_ERROR_EAGAIN) || !sess->api_block_mode) \
break; \
rc = _libssh2_wait_socket(sess, entry_time); \
} while(!rc); \
time_t entry_time = time(NULL); \
do { \
rc = x; \
/* the order of the check below is important to properly \
deal with the case when the 'sess' is freed */ \
if((rc != LIBSSH2_ERROR_EAGAIN) || !sess->api_block_mode) \
break; \
rc = _libssh2_wait_socket(sess, entry_time); \
} while(!rc); \
} while(0)
/*
@ -72,15 +73,15 @@
*/
#define BLOCK_ADJUST_ERRNO(ptr, sess, x) \
do { \
time_t entry_time = time(NULL); \
int rc; \
do { \
ptr = x; \
if(!sess->api_block_mode || \
(ptr != NULL) || \
(libssh2_session_last_errno(sess) != LIBSSH2_ERROR_EAGAIN) ) \
break; \
rc = _libssh2_wait_socket(sess, entry_time); \
time_t entry_time = time(NULL); \
int rc; \
do { \
ptr = x; \
if(!sess->api_block_mode || \
(ptr != NULL) || \
(libssh2_session_last_errno(sess) != LIBSSH2_ERROR_EAGAIN)) \
break; \
rc = _libssh2_wait_socket(sess, entry_time); \
} while(!rc); \
} while(0)
@ -90,4 +91,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 */

File diff suppressed because it is too large Load diff

View file

@ -1,8 +1,8 @@
#ifndef __LIBSSH2_SFTP_H
#define __LIBSSH2_SFTP_H
#ifndef LIBSSH2_SFTP_PRIV_H
#define LIBSSH2_SFTP_PRIV_H
/*
* Copyright (C) 2010 - 2012 by Daniel Stenberg
* Author: Daniel Stenberg <daniel@haxx.se>
* Copyright (C) Daniel Stenberg
* All rights reserved.
*
* Redistribution and use in source and binary forms,
* with or without modification, are permitted provided
@ -37,6 +37,7 @@
* USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
* OF SUCH DAMAGE.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
/*
@ -67,10 +68,6 @@ struct sftp_zombie_requests {
uint32_t request_id;
};
#ifndef MIN
#define MIN(x,y) ((x)<(y)?(x):(y))
#endif
struct _LIBSSH2_SFTP_PACKET
{
struct list_node node; /* linked list header */
@ -81,7 +78,8 @@ struct _LIBSSH2_SFTP_PACKET
typedef struct _LIBSSH2_SFTP_PACKET LIBSSH2_SFTP_PACKET;
#define SFTP_HANDLE_MAXLEN 256 /* according to spec! */
/* Increasing from 256 to 4092 since OpenSSH doesn't honor it. */
#define SFTP_HANDLE_MAXLEN 4092 /* according to spec, this should be 256! */
struct _LIBSSH2_SFTP_HANDLE
{
@ -140,7 +138,7 @@ struct _LIBSSH2_SFTP
{
LIBSSH2_CHANNEL *channel;
uint32_t request_id, version;
uint32_t request_id, version, posix_rename_version;
struct list_head packets;
@ -153,9 +151,10 @@ struct _LIBSSH2_SFTP
uint32_t last_errno;
/* Holder for partial packet, use in libssh2_sftp_packet_read() */
unsigned char partial_size[4]; /* buffer for size field */
size_t partial_size_len; /* size field length */
unsigned char *partial_packet; /* The data */
unsigned char packet_header[9];
/* packet size (4) packet type (1) request id (4) */
size_t packet_header_len; /* packet_header length */
unsigned char *partial_packet; /* The data, with header */
uint32_t partial_len; /* Desired number of bytes */
size_t partial_received; /* Bytes received so far */
@ -204,6 +203,11 @@ struct _LIBSSH2_SFTP
unsigned char *rename_s;
uint32_t rename_request_id;
/* State variables used in libssh2_sftp_posix_rename_ex() */
libssh2_nonblocking_states posix_rename_state;
unsigned char *posix_rename_packet;
uint32_t posix_rename_request_id;
/* State variables used in libssh2_sftp_fstatvfs() */
libssh2_nonblocking_states fstatvfs_state;
unsigned char *fstatvfs_packet;
@ -235,4 +239,4 @@ struct _LIBSSH2_SFTP
uint32_t symlink_request_id;
};
#endif /* __LIBSSH2_SFTP_H */
#endif /* LIBSSH2_SFTP_PRIV_H */

File diff suppressed because it is too large Load diff

View file

@ -1,8 +1,8 @@
#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>
#ifndef LIBSSH2_TRANSPORT_H
#define LIBSSH2_TRANSPORT_H
/* Copyright (C) The Written Word, Inc.
* Copyright (C) Daniel Stenberg
* All rights reserved.
*
* Redistribution and use in source and binary forms,
* with or without modification, are permitted provided
@ -38,12 +38,13 @@
* OF SUCH DAMAGE.
*
* This file handles reading and writing to the SECSH transport layer. RFC4253.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#include "libssh2_priv.h"
#include "packet.h"
/*
* libssh2_transport_send
*
@ -83,4 +84,4 @@ int _libssh2_transport_send(LIBSSH2_SESSION *session,
*/
int _libssh2_transport_read(LIBSSH2_SESSION * session);
#endif /* __LIBSSH2_TRANSPORT_H */
#endif /* LIBSSH2_TRANSPORT_H */

File diff suppressed because it is too large Load diff

View file

@ -1,7 +1,7 @@
#ifndef __LIBSSH2_USERAUTH_H
#define __LIBSSH2_USERAUTH_H
/* Copyright (c) 2004-2007, Sara Golemon <sarag@libssh2.org>
* Copyright (c) 2009-2010 by Daniel Stenberg
#ifndef LIBSSH2_USERAUTH_H
#define LIBSSH2_USERAUTH_H
/* Copyright (C) Sara Golemon <sarag@libssh2.org>
* Copyright (C) Daniel Stenberg
* All rights reserved.
*
* Redistribution and use in source and binary forms,
@ -36,16 +36,18 @@
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
* USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
* OF SUCH DAMAGE.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
int
_libssh2_userauth_publickey(LIBSSH2_SESSION *session,
const char *username,
unsigned int username_len,
size_t username_len,
const unsigned char *pubkeydata,
unsigned long pubkeydata_len,
size_t pubkeydata_len,
LIBSSH2_USERAUTH_PUBLICKEY_SIGN_FUNC
((*sign_callback)),
((*sign_callback)),
void *abstract);
#endif /* __LIBSSH2_USERAUTH_H */
#endif /* LIBSSH2_USERAUTH_H */

View file

@ -0,0 +1,166 @@
/* Copyright (C) Xaver Loppenstedt <xaver@loppenstedt.de>
* All rights reserved.
*
* Redistribution and use in source and binary forms,
* with or without modification, are permitted provided
* that the following conditions are met:
*
* 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.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#include "libssh2_priv.h"
#include "userauth_kbd_packet.h"
int userauth_keyboard_interactive_decode_info_request(LIBSSH2_SESSION *session)
{
unsigned char *language_tag;
size_t language_tag_len;
unsigned int i;
unsigned char packet_type;
uint32_t tmp_u32;
struct string_buf decoded;
decoded.data = session->userauth_kybd_data;
decoded.dataptr = session->userauth_kybd_data;
decoded.len = session->userauth_kybd_data_len;
if(session->userauth_kybd_data_len < 17) {
_libssh2_error(session, LIBSSH2_ERROR_BUFFER_TOO_SMALL,
"userauth keyboard data buffer too small "
"to get length");
return -1;
}
/* byte SSH_MSG_USERAUTH_INFO_REQUEST */
_libssh2_get_byte(&decoded, &packet_type);
/* string name (ISO-10646 UTF-8) */
if(_libssh2_copy_string(session, &decoded,
&session->userauth_kybd_auth_name,
&session->userauth_kybd_auth_name_len) == -1) {
_libssh2_error(session, LIBSSH2_ERROR_ALLOC,
"Unable to decode "
"keyboard-interactive 'name' "
"request field");
return -1;
}
/* string instruction (ISO-10646 UTF-8) */
if(_libssh2_copy_string(session, &decoded,
&session->userauth_kybd_auth_instruction,
&session->userauth_kybd_auth_instruction_len)
== -1) {
_libssh2_error(session, LIBSSH2_ERROR_ALLOC,
"Unable to decode "
"keyboard-interactive 'instruction' "
"request field");
return -1;
}
/* string language tag (as defined in [RFC-3066]) */
if(_libssh2_get_string(&decoded, &language_tag,
&language_tag_len) == -1) {
_libssh2_error(session, LIBSSH2_ERROR_ALLOC,
"Unable to decode "
"keyboard-interactive 'language tag' "
"request field");
return -1;
}
/* int num-prompts */
if(_libssh2_get_u32(&decoded, &tmp_u32) == -1 ||
(session->userauth_kybd_num_prompts = tmp_u32) != tmp_u32) {
_libssh2_error(session, LIBSSH2_ERROR_BUFFER_TOO_SMALL,
"Unable to decode "
"keyboard-interactive number of keyboard prompts");
return -1;
}
if(session->userauth_kybd_num_prompts > 100) {
_libssh2_error(session, LIBSSH2_ERROR_OUT_OF_BOUNDARY,
"Too many replies for "
"keyboard-interactive prompts");
return -1;
}
if(session->userauth_kybd_num_prompts == 0) {
return 0;
}
session->userauth_kybd_prompts =
LIBSSH2_CALLOC(session,
sizeof(LIBSSH2_USERAUTH_KBDINT_PROMPT) *
session->userauth_kybd_num_prompts);
if(!session->userauth_kybd_prompts) {
_libssh2_error(session, LIBSSH2_ERROR_ALLOC,
"Unable to allocate memory for "
"keyboard-interactive prompts array");
return -1;
}
session->userauth_kybd_responses =
LIBSSH2_CALLOC(session,
sizeof(LIBSSH2_USERAUTH_KBDINT_RESPONSE) *
session->userauth_kybd_num_prompts);
if(!session->userauth_kybd_responses) {
_libssh2_error(session, LIBSSH2_ERROR_ALLOC,
"Unable to allocate memory for "
"keyboard-interactive responses array");
return -1;
}
for(i = 0; i < session->userauth_kybd_num_prompts; i++) {
/* string prompt[1] (ISO-10646 UTF-8) */
if(_libssh2_copy_string(session, &decoded,
&session->userauth_kybd_prompts[i].text,
&session->userauth_kybd_prompts[i].length)
== -1) {
_libssh2_error(session, LIBSSH2_ERROR_ALLOC,
"Unable to decode "
"keyboard-interactive prompt message");
return -1;
}
/* boolean echo[1] */
if(_libssh2_get_boolean(&decoded,
&session->userauth_kybd_prompts[i].echo)
== -1) {
_libssh2_error(session, LIBSSH2_ERROR_BUFFER_TOO_SMALL,
"Unable to decode "
"user auth keyboard prompt echo");
return -1;
}
}
return 0;
}

View file

@ -0,0 +1,45 @@
/* Copyright (C) Xaver Loppenstedt <xaver@loppenstedt.de>
* All rights reserved.
*
* Redistribution and use in source and binary forms,
* with or without modification, are permitted provided
* that the following conditions are met:
*
* 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.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#ifndef LIBSSH2_USERAUTH_KBD_PACKET_H
#define LIBSSH2_USERAUTH_KBD_PACKET_H
int userauth_keyboard_interactive_decode_info_request(LIBSSH2_SESSION *);
#endif /* LIBSSH2_USERAUTH_KBD_PACKET_H */

View file

@ -1,4 +1,5 @@
/* Copyright (C) 2009 Daniel Stenberg. All rights reserved.
/* Copyright (C) Daniel Stenberg
* All rights reserved.
*
* Redistribution and use in source and binary forms,
* with or without modification, are permitted provided
@ -33,18 +34,11 @@
* USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
* OF SUCH DAMAGE.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#include "libssh2_priv.h"
/*
libssh2_version() can be used like this:
if (!libssh2_version(LIBSSH2_VERSION_NUM)) {
fprintf (stderr, "Runtime libssh2 version too old!\n");
exit(1);
}
*/
LIBSSH2_API
const char *libssh2_version(int req_version_num)
{
@ -52,3 +46,9 @@ const char *libssh2_version(int req_version_num)
return LIBSSH2_VERSION;
return NULL; /* this is not a suitable library! */
}
LIBSSH2_API
libssh2_crypto_engine_t libssh2_crypto_engine(void)
{
return LIBSSH2_CRYPTO_ENGINE;
}

File diff suppressed because it is too large Load diff

View file

@ -1,7 +1,7 @@
#ifndef __LIBSSH2_WINCNG_H
#define __LIBSSH2_WINCNG_H
#ifndef LIBSSH2_WINCNG_H
#define LIBSSH2_WINCNG_H
/*
* Copyright (C) 2013-2020 Marc Hoersken <info@marc-hoersken.de>
* Copyright (C) Marc Hoersken <info@marc-hoersken.de>
* All rights reserved.
*
* Redistribution and use in source and binary forms,
@ -36,8 +36,12 @@
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
* USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
* OF SUCH DAMAGE.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#define LIBSSH2_CRYPTO_ENGINE libssh2_wincng
/* required for cross-compilation against the w64 mingw-runtime package */
#if defined(_WIN32_WINNT) && (_WIN32_WINNT < 0x0600)
#undef _WIN32_WINNT
@ -55,19 +59,43 @@
#define LIBSSH2_HMAC_SHA256 1
#define LIBSSH2_HMAC_SHA512 1
#define LIBSSH2_AES 1
#define LIBSSH2_AES_CBC 1
#define LIBSSH2_AES_CTR 1
#define LIBSSH2_AES_GCM 0
#define LIBSSH2_BLOWFISH 0
#define LIBSSH2_RC4 1
#define LIBSSH2_CAST 0
#define LIBSSH2_3DES 1
#define LIBSSH2_RSA 1
#define LIBSSH2_RSA_SHA1 1
#define LIBSSH2_RSA_SHA2 1
#define LIBSSH2_DSA 1
#define LIBSSH2_ECDSA 0
#define LIBSSH2_ED25519 0
/*
* Conditionally enable ECDSA support.
*
* ECDSA support requires the use of
*
* BCryptDeriveKey(..., BCRYPT_KDF_RAW_SECRET, ... )
*
* This functionality is only available as of Windows 10. To maintain
* backward compatibility, ECDSA support is therefore disabled
* by default and needs to be explicitly enabled using a build
* flag.
*/
#ifdef LIBSSH2_ECDSA_WINCNG
#define LIBSSH2_ECDSA 1
#else
#define LIBSSH2_ECDSA 0
#endif
#include "crypto_config.h"
#if LIBSSH2_MD5 || LIBSSH2_MD5_PEM
#define MD5_DIGEST_LENGTH 16
#endif
#define SHA_DIGEST_LENGTH 20
#define SHA256_DIGEST_LENGTH 32
#define SHA384_DIGEST_LENGTH 48
@ -104,6 +132,11 @@ struct _libssh2_wincng_ctx {
BCRYPT_ALG_HANDLE hAlgRC4_NA;
BCRYPT_ALG_HANDLE hAlg3DES_CBC;
BCRYPT_ALG_HANDLE hAlgDH;
BCRYPT_ALG_HANDLE hAlgChacha20;
#if LIBSSH2_ECDSA
BCRYPT_ALG_HANDLE hAlgECDH[3]; /* indexed by libssh2_curve_type */
BCRYPT_ALG_HANDLE hAlgECDSA[3]; /* indexed by libssh2_curve_type */
#endif
volatile int hasAlgDHwithKDF; /* -1=no, 0=maybe, 1=yes */
};
@ -115,16 +148,13 @@ extern struct _libssh2_wincng_ctx _libssh2_wincng;
* Windows CNG backend: Generic functions
*/
void _libssh2_wincng_init(void);
void _libssh2_wincng_free(void);
#define libssh2_crypto_init() \
_libssh2_wincng_init()
_libssh2_wincng_init()
#define libssh2_crypto_exit() \
_libssh2_wincng_free()
_libssh2_wincng_free()
#define _libssh2_random(buf, len) \
_libssh2_wincng_random(buf, len)
_libssh2_wincng_random(buf, len)
#define libssh2_prepare_iovec(vec, len) /* Empty. */
@ -137,8 +167,8 @@ void _libssh2_wincng_free(void);
typedef struct __libssh2_wincng_hash_ctx {
BCRYPT_HASH_HANDLE hHash;
unsigned char *pbHashObject;
unsigned long dwHashObject;
unsigned long cbHash;
ULONG dwHashObject;
ULONG cbHash;
} _libssh2_wincng_hash_ctx;
/*
@ -147,88 +177,68 @@ typedef struct __libssh2_wincng_hash_ctx {
#define libssh2_sha1_ctx _libssh2_wincng_hash_ctx
#define libssh2_sha1_init(ctx) \
(_libssh2_wincng_hash_init(ctx, _libssh2_wincng.hAlgHashSHA1, \
SHA_DIGEST_LENGTH, NULL, 0) == 0)
(_libssh2_wincng_hash_init(ctx, _libssh2_wincng.hAlgHashSHA1, \
SHA_DIGEST_LENGTH, NULL, 0) == 0)
#define libssh2_sha1_update(ctx, data, datalen) \
_libssh2_wincng_hash_update(&ctx, (unsigned char *) data, datalen)
(_libssh2_wincng_hash_update(&ctx, data, (ULONG) datalen) == 0)
#define libssh2_sha1_final(ctx, hash) \
_libssh2_wincng_hash_final(&ctx, hash)
(_libssh2_wincng_hash_final(&ctx, hash) == 0)
#define libssh2_sha1(data, datalen, hash) \
_libssh2_wincng_hash(data, datalen, _libssh2_wincng.hAlgHashSHA1, \
hash, SHA_DIGEST_LENGTH)
_libssh2_wincng_hash(data, datalen, _libssh2_wincng.hAlgHashSHA1, \
hash, SHA_DIGEST_LENGTH)
#define libssh2_sha256_ctx _libssh2_wincng_hash_ctx
#define libssh2_sha256_init(ctx) \
(_libssh2_wincng_hash_init(ctx, _libssh2_wincng.hAlgHashSHA256, \
SHA256_DIGEST_LENGTH, NULL, 0) == 0)
(_libssh2_wincng_hash_init(ctx, _libssh2_wincng.hAlgHashSHA256, \
SHA256_DIGEST_LENGTH, NULL, 0) == 0)
#define libssh2_sha256_update(ctx, data, datalen) \
_libssh2_wincng_hash_update(&ctx, (unsigned char *) data, datalen)
(_libssh2_wincng_hash_update(&ctx, data, (ULONG) datalen) == 0)
#define libssh2_sha256_final(ctx, hash) \
_libssh2_wincng_hash_final(&ctx, hash)
(_libssh2_wincng_hash_final(&ctx, hash) == 0)
#define libssh2_sha256(data, datalen, hash) \
_libssh2_wincng_hash(data, datalen, _libssh2_wincng.hAlgHashSHA256, \
hash, SHA256_DIGEST_LENGTH)
_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)
(_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)
(_libssh2_wincng_hash_update(&ctx, data, (ULONG) datalen) == 0)
#define libssh2_sha384_final(ctx, hash) \
_libssh2_wincng_hash_final(&ctx, hash)
(_libssh2_wincng_hash_final(&ctx, hash) == 0)
#define libssh2_sha384(data, datalen, hash) \
_libssh2_wincng_hash(data, datalen, _libssh2_wincng.hAlgHashSHA384, \
hash, SHA384_DIGEST_LENGTH)
_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, \
SHA512_DIGEST_LENGTH, NULL, 0) == 0)
(_libssh2_wincng_hash_init(ctx, _libssh2_wincng.hAlgHashSHA512, \
SHA512_DIGEST_LENGTH, NULL, 0) == 0)
#define libssh2_sha512_update(ctx, data, datalen) \
_libssh2_wincng_hash_update(&ctx, (unsigned char *) data, datalen)
(_libssh2_wincng_hash_update(&ctx, data, (ULONG) datalen) == 0)
#define libssh2_sha512_final(ctx, hash) \
_libssh2_wincng_hash_final(&ctx, hash)
(_libssh2_wincng_hash_final(&ctx, hash) == 0)
#define libssh2_sha512(data, datalen, hash) \
_libssh2_wincng_hash(data, datalen, _libssh2_wincng.hAlgHashSHA512, \
hash, SHA512_DIGEST_LENGTH)
_libssh2_wincng_hash(data, datalen, _libssh2_wincng.hAlgHashSHA512, \
hash, SHA512_DIGEST_LENGTH)
#if LIBSSH2_MD5 || LIBSSH2_MD5_PEM
#define libssh2_md5_ctx _libssh2_wincng_hash_ctx
#define libssh2_md5_init(ctx) \
(_libssh2_wincng_hash_init(ctx, _libssh2_wincng.hAlgHashMD5, \
MD5_DIGEST_LENGTH, NULL, 0) == 0)
(_libssh2_wincng_hash_init(ctx, _libssh2_wincng.hAlgHashMD5, \
MD5_DIGEST_LENGTH, NULL, 0) == 0)
#define libssh2_md5_update(ctx, data, datalen) \
_libssh2_wincng_hash_update(&ctx, (unsigned char *) data, datalen)
(_libssh2_wincng_hash_update(&ctx, data, (ULONG) datalen) == 0)
#define libssh2_md5_final(ctx, hash) \
_libssh2_wincng_hash_final(&ctx, hash)
#define libssh2_md5(data, datalen, hash) \
_libssh2_wincng_hash(data, datalen, _libssh2_wincng.hAlgHashMD5, \
hash, MD5_DIGEST_LENGTH)
(_libssh2_wincng_hash_final(&ctx, hash) == 0)
#endif
/*
* Windows CNG backend: HMAC functions
*/
#define libssh2_hmac_ctx _libssh2_wincng_hash_ctx
#define libssh2_hmac_ctx_init(ctx)
#define libssh2_hmac_sha1_init(ctx, key, keylen) \
_libssh2_wincng_hash_init(ctx, _libssh2_wincng.hAlgHmacSHA1, \
SHA_DIGEST_LENGTH, key, keylen)
#define libssh2_hmac_md5_init(ctx, key, keylen) \
_libssh2_wincng_hash_init(ctx, _libssh2_wincng.hAlgHmacMD5, \
MD5_DIGEST_LENGTH, key, keylen)
#define libssh2_hmac_ripemd160_init(ctx, key, keylen)
/* not implemented */
#define libssh2_hmac_sha256_init(ctx, key, keylen) \
_libssh2_wincng_hash_init(ctx, _libssh2_wincng.hAlgHmacSHA256, \
SHA256_DIGEST_LENGTH, key, keylen)
#define libssh2_hmac_sha512_init(ctx, key, keylen) \
_libssh2_wincng_hash_init(ctx, _libssh2_wincng.hAlgHmacSHA512, \
SHA512_DIGEST_LENGTH, key, keylen)
#define libssh2_hmac_update(ctx, data, datalen) \
_libssh2_wincng_hash_update(&ctx, (unsigned char *) data, datalen)
#define libssh2_hmac_final(ctx, hash) \
_libssh2_wincng_hmac_final(&ctx, hash)
#define libssh2_hmac_cleanup(ctx) \
_libssh2_wincng_hmac_cleanup(ctx)
/*******************************************************************/
@ -238,8 +248,8 @@ _libssh2_wincng_hash(data, datalen, _libssh2_wincng.hAlgHashSHA384, \
typedef struct __libssh2_wincng_key_ctx {
BCRYPT_KEY_HANDLE hKey;
unsigned char *pbKeyObject;
unsigned long cbKeyObject;
void *pbKeyObject;
DWORD cbKeyObject;
} _libssh2_wincng_key_ctx;
@ -251,21 +261,25 @@ typedef struct __libssh2_wincng_key_ctx {
#define _libssh2_rsa_new(rsactx, e, e_len, n, n_len, \
d, d_len, p, p_len, q, q_len, \
e1, e1_len, e2, e2_len, c, c_len) \
_libssh2_wincng_rsa_new(rsactx, e, e_len, n, n_len, \
d, d_len, p, p_len, q, q_len, \
e1, e1_len, e2, e2_len, c, c_len)
_libssh2_wincng_rsa_new(rsactx, e, e_len, n, n_len, \
d, d_len, p, p_len, q, q_len, \
e1, e1_len, e2, e2_len, c, c_len)
#define _libssh2_rsa_new_private(rsactx, s, filename, passphrase) \
_libssh2_wincng_rsa_new_private(rsactx, s, filename, passphrase)
_libssh2_wincng_rsa_new_private(rsactx, s, filename, passphrase)
#define _libssh2_rsa_new_private_frommemory(rsactx, s, filedata, \
filedata_len, passphrase) \
_libssh2_wincng_rsa_new_private_frommemory(rsactx, s, filedata, \
filedata_len, passphrase)
_libssh2_wincng_rsa_new_private_frommemory(rsactx, s, filedata, \
filedata_len, passphrase)
#define _libssh2_rsa_sha1_sign(s, rsactx, hash, hash_len, sig, sig_len) \
_libssh2_wincng_rsa_sha1_sign(s, rsactx, hash, hash_len, sig, sig_len)
_libssh2_wincng_rsa_sha1_sign(s, rsactx, hash, hash_len, sig, sig_len)
#define _libssh2_rsa_sha2_sign(s, rsactx, hash, hash_len, sig, sig_len) \
_libssh2_wincng_rsa_sha2_sign(s, rsactx, hash, hash_len, sig, sig_len)
#define _libssh2_rsa_sha1_verify(rsactx, sig, sig_len, m, m_len) \
_libssh2_wincng_rsa_sha1_verify(rsactx, sig, sig_len, m, m_len)
_libssh2_wincng_rsa_sha1_verify(rsactx, sig, sig_len, m, m_len)
#define _libssh2_rsa_sha2_verify(rsactx, hash_len, sig, sig_len, m, m_len) \
_libssh2_wincng_rsa_sha2_verify(rsactx, hash_len, sig, sig_len, m, m_len)
#define _libssh2_rsa_free(rsactx) \
_libssh2_wincng_rsa_free(rsactx)
_libssh2_wincng_rsa_free(rsactx)
/*
* Windows CNG backend: DSA functions
@ -274,32 +288,92 @@ typedef struct __libssh2_wincng_key_ctx {
#define libssh2_dsa_ctx _libssh2_wincng_key_ctx
#define _libssh2_dsa_new(dsactx, p, p_len, q, q_len, \
g, g_len, y, y_len, x, x_len) \
_libssh2_wincng_dsa_new(dsactx, p, p_len, q, q_len, \
g, g_len, y, y_len, x, x_len)
_libssh2_wincng_dsa_new(dsactx, p, p_len, q, q_len, \
g, g_len, y, y_len, x, x_len)
#define _libssh2_dsa_new_private(dsactx, s, filename, passphrase) \
_libssh2_wincng_dsa_new_private(dsactx, s, filename, passphrase)
_libssh2_wincng_dsa_new_private(dsactx, s, filename, passphrase)
#define _libssh2_dsa_new_private_frommemory(dsactx, s, filedata, \
filedata_len, passphrase) \
_libssh2_wincng_dsa_new_private_frommemory(dsactx, s, filedata, \
filedata_len, passphrase)
_libssh2_wincng_dsa_new_private_frommemory(dsactx, s, filedata, \
filedata_len, passphrase)
#define _libssh2_dsa_sha1_sign(dsactx, hash, hash_len, sig) \
_libssh2_wincng_dsa_sha1_sign(dsactx, hash, hash_len, sig)
_libssh2_wincng_dsa_sha1_sign(dsactx, hash, hash_len, sig)
#define _libssh2_dsa_sha1_verify(dsactx, sig, m, m_len) \
_libssh2_wincng_dsa_sha1_verify(dsactx, sig, m, m_len)
_libssh2_wincng_dsa_sha1_verify(dsactx, sig, m, m_len)
#define _libssh2_dsa_free(dsactx) \
_libssh2_wincng_dsa_free(dsactx)
_libssh2_wincng_dsa_free(dsactx)
/*
* Windows CNG backend: ECDSA functions
*/
typedef enum {
LIBSSH2_EC_CURVE_NISTP256 = 0,
LIBSSH2_EC_CURVE_NISTP384 = 1,
LIBSSH2_EC_CURVE_NISTP521 = 2,
} libssh2_curve_type;
typedef struct __libssh2_wincng_ecdsa_ctx {
BCRYPT_KEY_HANDLE handle;
libssh2_curve_type curve;
} _libssh2_wincng_ecdsa_key;
#define libssh2_ecdsa_ctx _libssh2_wincng_ecdsa_key
#if LIBSSH2_ECDSA
#define _libssh2_ec_key _libssh2_wincng_ecdsa_key
#endif
void
_libssh2_wincng_ecdsa_free(libssh2_ecdsa_ctx* ctx);
#define _libssh2_ecdsa_create_key(session, privkey, pubkey_octal, \
pubkey_octal_len, curve) \
_libssh2_wincng_ecdh_create_key(session, privkey, pubkey_octal, \
pubkey_octal_len, curve)
#define _libssh2_ecdsa_curve_name_with_octal_new(ctx, k, k_len, curve) \
_libssh2_wincng_ecdsa_curve_name_with_octal_new(ctx, k, k_len, curve)
#define _libssh2_ecdh_gen_k(k, privkey, server_pubkey, server_pubkey_len) \
_libssh2_wincng_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_wincng_ecdsa_verify(ctx, r, r_len, s, s_len, m, m_len)
#define _libssh2_ecdsa_new_private(ctx, session, filename, passphrase) \
_libssh2_wincng_ecdsa_new_private(ctx, session, filename, passphrase)
#define _libssh2_ecdsa_new_private_frommemory(ctx, session, filedata, \
filedata_len, passphrase) \
_libssh2_wincng_ecdsa_new_private_frommemory(ctx, session, filedata, \
filedata_len, passphrase)
#define _libssh2_ecdsa_sign(session, ctx, hash, hash_len, sign, sign_len) \
_libssh2_wincng_ecdsa_sign(session, ctx, hash, hash_len, sign, sign_len)
#define _libssh2_ecdsa_get_curve_type(ctx) \
_libssh2_wincng_ecdsa_get_curve_type(ctx)
#define _libssh2_ecdsa_free(ecdsactx) \
_libssh2_wincng_ecdsa_free(ecdsactx)
/*
* Windows CNG backend: Key functions
*/
#define _libssh2_pub_priv_keyfile(s, m, m_len, p, p_len, pk, pw) \
_libssh2_wincng_pub_priv_keyfile(s, m, m_len, p, p_len, pk, pw)
_libssh2_wincng_pub_priv_keyfile(s, m, m_len, p, p_len, pk, pw)
#define _libssh2_pub_priv_keyfilememory(s, m, m_len, p, p_len, \
pk, pk_len, pw) \
_libssh2_wincng_pub_priv_keyfilememory(s, m, m_len, p, p_len, \
pk, pk_len, pw)
pk, pk_len, pw) \
_libssh2_wincng_pub_priv_keyfilememory(s, m, m_len, p, p_len, \
pk, pk_len, pw)
#define _libssh2_sk_pub_keyfilememory(s, m, m_len, p, p_len, alg, app, \
f, kh, kh_len, pk, pk_len, pw) \
_libssh2_wincng_sk_pub_keyfilememory(s, m, m_len, p, p_len, alg, app, \
f, kh, kh_len, pk, pk_len, pw)
/*******************************************************************/
/*
@ -311,10 +385,10 @@ struct _libssh2_wincng_cipher_ctx {
unsigned char *pbKeyObject;
unsigned char *pbIV;
unsigned char *pbCtr;
unsigned long dwKeyObject;
unsigned long dwIV;
unsigned long dwBlockLength;
unsigned long dwCtrLength;
ULONG dwKeyObject;
ULONG dwIV;
ULONG dwBlockLength;
ULONG dwCtrLength;
};
#define _libssh2_cipher_ctx struct _libssh2_wincng_cipher_ctx
@ -325,7 +399,7 @@ struct _libssh2_wincng_cipher_ctx {
struct _libssh2_wincng_cipher_type {
BCRYPT_ALG_HANDLE *phAlg;
unsigned long dwKeyLength;
ULONG dwKeyLength;
int useIV; /* TODO: Convert to bool when a C89 compatible bool type
is defined */
int ctrMode;
@ -336,22 +410,23 @@ struct _libssh2_wincng_cipher_type {
#define _libssh2_cipher_aes256ctr { &_libssh2_wincng.hAlgAES_ECB, 32, 0, 1 }
#define _libssh2_cipher_aes192ctr { &_libssh2_wincng.hAlgAES_ECB, 24, 0, 1 }
#define _libssh2_cipher_aes128ctr { &_libssh2_wincng.hAlgAES_ECB, 16, 0, 1 }
#define _libssh2_cipher_aes256 { &_libssh2_wincng.hAlgAES_CBC, 32, 1, 0 }
#define _libssh2_cipher_aes192 { &_libssh2_wincng.hAlgAES_CBC, 24, 1, 0 }
#define _libssh2_cipher_aes128 { &_libssh2_wincng.hAlgAES_CBC, 16, 1, 0 }
#define _libssh2_cipher_arcfour { &_libssh2_wincng.hAlgRC4_NA, 16, 0, 0 }
#define _libssh2_cipher_3des { &_libssh2_wincng.hAlg3DES_CBC, 24, 1, 0 }
#define _libssh2_cipher_aes256 { &_libssh2_wincng.hAlgAES_CBC, 32, 1, 0 }
#define _libssh2_cipher_aes192 { &_libssh2_wincng.hAlgAES_CBC, 24, 1, 0 }
#define _libssh2_cipher_aes128 { &_libssh2_wincng.hAlgAES_CBC, 16, 1, 0 }
#define _libssh2_cipher_arcfour { &_libssh2_wincng.hAlgRC4_NA, 16, 0, 0 }
#define _libssh2_cipher_3des { &_libssh2_wincng.hAlg3DES_CBC, 24, 1, 0 }
#define _libssh2_cipher_chacha20 { &_libssh2_wincng.hAlgChacha20, 24, 1, 0 }
/*
* Windows CNG backend: Cipher functions
*/
#define _libssh2_cipher_init(ctx, type, iv, secret, encrypt) \
_libssh2_wincng_cipher_init(ctx, type, iv, secret, encrypt)
#define _libssh2_cipher_crypt(ctx, type, encrypt, block, blocklen) \
_libssh2_wincng_cipher_crypt(ctx, type, encrypt, block, blocklen)
_libssh2_wincng_cipher_init(ctx, type, iv, secret, encrypt)
#define _libssh2_cipher_crypt(ctx, type, encrypt, block, blocklen, fl) \
_libssh2_wincng_cipher_crypt(ctx, type, encrypt, block, blocklen, fl)
#define _libssh2_cipher_dtor(ctx) \
_libssh2_wincng_cipher_dtor(ctx)
_libssh2_wincng_cipher_dtor(ctx)
/*******************************************************************/
/*
@ -370,7 +445,7 @@ struct _libssh2_wincng_cipher_type {
struct _libssh2_wincng_bignum {
unsigned char *bignum;
unsigned long length;
ULONG length;
};
#define _libssh2_bn struct _libssh2_wincng_bignum
@ -379,28 +454,34 @@ struct _libssh2_wincng_bignum {
* Windows CNG backend: BigNumber functions
*/
_libssh2_bn *_libssh2_wincng_bignum_init(void);
#define _libssh2_bn_init() \
_libssh2_wincng_bignum_init()
_libssh2_wincng_bignum_init()
#define _libssh2_bn_init_from_bin() \
_libssh2_bn_init()
_libssh2_bn_init()
#define _libssh2_bn_set_word(bn, word) \
_libssh2_wincng_bignum_set_word(bn, word)
_libssh2_wincng_bignum_set_word(bn, word)
#define _libssh2_bn_from_bin(bn, len, bin) \
_libssh2_wincng_bignum_from_bin(bn, len, bin)
_libssh2_wincng_bignum_from_bin(bn, (ULONG) len, bin)
#define _libssh2_bn_to_bin(bn, bin) \
_libssh2_wincng_bignum_to_bin(bn, bin)
_libssh2_wincng_bignum_to_bin(bn, bin)
#define _libssh2_bn_bytes(bn) bn->length
#define _libssh2_bn_bits(bn) \
_libssh2_wincng_bignum_bits(bn)
_libssh2_wincng_bignum_bits(bn)
#define _libssh2_bn_free(bn) \
_libssh2_wincng_bignum_free(bn)
_libssh2_wincng_bignum_free(bn)
/*
* Windows CNG backend: Diffie-Hellman support
*/
/* Default generate and safe prime sizes for
diffie-hellman-group-exchange-sha1 */
#define LIBSSH2_DH_GEX_MINGROUP 2048
#define LIBSSH2_DH_GEX_OPTGROUP 4096
#define LIBSSH2_DH_GEX_MAXGROUP 4096
#define LIBSSH2_DH_MAX_MODULUS_BITS 16384
typedef struct {
/* holds our private and public key components */
BCRYPT_KEY_HANDLE dh_handle;
@ -409,14 +490,14 @@ typedef struct {
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;
struct _libssh2_wincng_bignum *dh_privbn;
} _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)
_libssh2_dh_key_pair(dhctx, public, g, p, group_order)
#define libssh2_dh_secret(dhctx, secret, f, p, bnctx) \
_libssh2_dh_secret(dhctx, secret, f, p)
_libssh2_dh_secret(dhctx, secret, f, p)
#define libssh2_dh_dtor(dhctx) _libssh2_dh_dtor(dhctx)
/*******************************************************************/
@ -425,163 +506,44 @@ typedef struct {
*/
void _libssh2_wincng_init(void);
void _libssh2_wincng_free(void);
int _libssh2_wincng_random(void *buf, int len);
int _libssh2_wincng_random(void *buf, size_t len);
int
_libssh2_wincng_hash_init(_libssh2_wincng_hash_ctx *ctx,
BCRYPT_ALG_HANDLE hAlg, unsigned long hashlen,
unsigned char *key, unsigned long keylen);
BCRYPT_ALG_HANDLE hAlg, ULONG hashlen,
unsigned char *key, ULONG keylen);
int
_libssh2_wincng_hash_update(_libssh2_wincng_hash_ctx *ctx,
const unsigned char *data, unsigned long datalen);
const void *data, ULONG datalen);
int
_libssh2_wincng_hash_final(_libssh2_wincng_hash_ctx *ctx,
unsigned char *hash);
int
_libssh2_wincng_hash(unsigned char *data, unsigned long datalen,
_libssh2_wincng_hash(const unsigned char *data, ULONG datalen,
BCRYPT_ALG_HANDLE hAlg,
unsigned char *hash, unsigned long hashlen);
unsigned char *hash, ULONG hashlen);
int
_libssh2_wincng_hmac_final(_libssh2_wincng_hash_ctx *ctx,
unsigned char *hash);
void
_libssh2_wincng_hmac_cleanup(_libssh2_wincng_hash_ctx *ctx);
int
_libssh2_wincng_key_sha1_verify(_libssh2_wincng_key_ctx *ctx,
const unsigned char *sig,
unsigned long sig_len,
const unsigned char *m,
unsigned long m_len,
unsigned long flags);
int
_libssh2_wincng_rsa_new(libssh2_rsa_ctx **rsa,
const unsigned char *edata,
unsigned long elen,
const unsigned char *ndata,
unsigned long nlen,
const unsigned char *ddata,
unsigned long dlen,
const unsigned char *pdata,
unsigned long plen,
const unsigned char *qdata,
unsigned long qlen,
const unsigned char *e1data,
unsigned long e1len,
const unsigned char *e2data,
unsigned long e2len,
const unsigned char *coeffdata,
unsigned long coefflen);
int
_libssh2_wincng_rsa_new_private(libssh2_rsa_ctx **rsa,
LIBSSH2_SESSION *session,
const char *filename,
const unsigned char *passphrase);
int
_libssh2_wincng_rsa_new_private_frommemory(libssh2_rsa_ctx **rsa,
LIBSSH2_SESSION *session,
const char *filedata,
size_t filedata_len,
unsigned const char *passphrase);
int
_libssh2_wincng_rsa_sha1_verify(libssh2_rsa_ctx *rsa,
const unsigned char *sig,
unsigned long sig_len,
const unsigned char *m,
unsigned long m_len);
int
_libssh2_wincng_rsa_sha1_sign(LIBSSH2_SESSION *session,
libssh2_rsa_ctx *rsa,
const unsigned char *hash,
size_t hash_len,
unsigned char **signature,
size_t *signature_len);
void
_libssh2_wincng_rsa_free(libssh2_rsa_ctx *rsa);
#if LIBSSH2_DSA
int
_libssh2_wincng_dsa_new(libssh2_dsa_ctx **dsa,
const unsigned char *pdata,
unsigned long plen,
const unsigned char *qdata,
unsigned long qlen,
const unsigned char *gdata,
unsigned long glen,
const unsigned char *ydata,
unsigned long ylen,
const unsigned char *xdata,
unsigned long xlen);
int
_libssh2_wincng_dsa_new_private(libssh2_dsa_ctx **dsa,
LIBSSH2_SESSION *session,
const char *filename,
const unsigned char *passphrase);
int
_libssh2_wincng_dsa_new_private_frommemory(libssh2_dsa_ctx **dsa,
LIBSSH2_SESSION *session,
const char *filedata,
size_t filedata_len,
unsigned const char *passphrase);
int
_libssh2_wincng_dsa_sha1_verify(libssh2_dsa_ctx *dsa,
const unsigned char *sig_fixed,
const unsigned char *m,
unsigned long m_len);
int
_libssh2_wincng_dsa_sha1_sign(libssh2_dsa_ctx *dsa,
const unsigned char *hash,
unsigned long hash_len,
unsigned char *sig_fixed);
void
_libssh2_wincng_dsa_free(libssh2_dsa_ctx *dsa);
#endif
int
_libssh2_wincng_pub_priv_keyfile(LIBSSH2_SESSION *session,
unsigned char **method,
size_t *method_len,
unsigned char **pubkeydata,
size_t *pubkeydata_len,
const char *privatekey,
const char *passphrase);
int
_libssh2_wincng_pub_priv_keyfilememory(LIBSSH2_SESSION *session,
unsigned char **method,
size_t *method_len,
unsigned char **pubkeydata,
size_t *pubkeydata_len,
const char *privatekeydata,
size_t privatekeydata_len,
const char *passphrase);
int
_libssh2_wincng_cipher_init(_libssh2_cipher_ctx *ctx,
_libssh2_cipher_type(type),
unsigned char *iv,
unsigned char *secret,
int encrypt);
int
_libssh2_wincng_cipher_crypt(_libssh2_cipher_ctx *ctx,
_libssh2_cipher_type(type),
int encrypt,
unsigned char *block,
size_t blocklen);
void
_libssh2_wincng_cipher_dtor(_libssh2_cipher_ctx *ctx);
_libssh2_bn *
_libssh2_wincng_bignum_init(void);
int
_libssh2_wincng_bignum_set_word(_libssh2_bn *bn, unsigned long word);
unsigned long
_libssh2_wincng_bignum_set_word(_libssh2_bn *bn, ULONG word);
ULONG
_libssh2_wincng_bignum_bits(const _libssh2_bn *bn);
void
_libssh2_wincng_bignum_from_bin(_libssh2_bn *bn, unsigned long len,
int
_libssh2_wincng_bignum_from_bin(_libssh2_bn *bn, ULONG len,
const unsigned char *bin);
void
int
_libssh2_wincng_bignum_to_bin(const _libssh2_bn *bn, unsigned char *bin);
void
_libssh2_wincng_bignum_free(_libssh2_bn *bn);
@ -596,4 +558,4 @@ _libssh2_dh_secret(_libssh2_dh_ctx *dhctx, _libssh2_bn *secret,
extern void
_libssh2_dh_dtor(_libssh2_dh_ctx *dhctx);
#endif /* __LIBSSH2_WINCNG_H */
#endif /* LIBSSH2_WINCNG_H */

View file

@ -1,32 +0,0 @@
#ifndef _UPP_SSH_libssh2upp_h_
#define _UPP_SSH_libssh2upp_h_
#include "libssh2/agent.c"
#include "libssh2/agent_win.c"
#include "libssh2/bcrypt_pbkdf.c"
#include "libssh2/blowfish.c"
#include "libssh2/channel.c"
#include "libssh2/comp.c"
#include "libssh2/crypt.c"
#include "libssh2/global.c"
#include "libssh2/hostkey.c"
#include "libssh2/keepalive.c"
#include "libssh2/kex.c"
#include "libssh2/knownhost.c"
#include "libssh2/libgcrypt.c"
#include "libssh2/mac.c"
#include "libssh2/mbedtls.c"
#include "libssh2/misc.c"
#include "libssh2/openssl.c"
#include "libssh2/packet.c"
#include "libssh2/pem.c"
#include "libssh2/publickey.c"
#include "libssh2/scp.c"
#include "libssh2/session.c"
#include "libssh2/sftp.c"
#include "libssh2/transport.c"
#include "libssh2/userauth.c"
#include "libssh2/version.c"
#include "libssh2/wincng.c"
#endif

View file

@ -0,0 +1,7 @@
// Imports the source files of winpty-agent executable, filters out the test code and other files.
files
libssh2/*.c
;
includes ;

View file

@ -54,14 +54,17 @@ shSession][@(0.0.255) `&]_[* Keys]([@(0.0.255) const]_[_^Upp`:`:String^ String][
]_[*@3 prikey], [@(0.0.255) const]_[_^Upp`:`:String^ String][@(0.0.255) `&]_[*@3 pubkey],
[@(0.0.255) const]_[_^Upp`:`:String^ String][@(0.0.255) `&]_[*@3 phrase],
[@(0.0.255) bool]_[*@3 fromfile]_`=_[@(0.0.255) true])&]
[s2;%% Sets the asymmetric encryption keys to be used to authenticate
[s0;l288;%% Sets the asymmetric encryption keys to be used to authenticate
the session. [%-*@3 phrase] can be used to decipher the private
key, or it can be empty (not recommended). Returns `*this for
method chaining. Note that when the [%-*@3 fromfile] parameter
is true, [%-*@3 prikey] and [%-*@3 pubkey] strings will be treated
as file paths to the respective key files. This is the default
behaviour. Otherwise they will be treated as memory buffers containing
the actual keys.&]
the actual keys. Note that it is possible to compute public key
from public key (aka. private key auth). To enable it, simply
&]
[s2;%% pass an empty or Null [%-*@3 pubkey].&]
[s3;%% &]
[s4; &]
[s5;:Upp`:`:SshSession`:`:Method`(int`,Upp`:`:Value`): [_^Upp`:`:SshSession^ SshSession
@ -161,33 +164,6 @@ The `"[C none]`" method allows logging in without an authentication
scheme. It is rarely used by the servers, and handled automatically
by the session.&]
[s3;^Upp`:`:SFtp^ &]
[s4;^Upp`:`:SFtp^ &]
[s5;:Upp`:`:SshSession`:`:CreateSFtp`(`): [_^Upp`:`:SFtp^ SFtp]_[* CreateSFtp]()&]
[s2;%% Creates an sftp channel instance.&]
[s3; &]
[s4; &]
[s5;:Upp`:`:SshSession`:`:CreateChannel`(`): [_^Upp`:`:SshChannel^ SshChannel]_[* CreateC
hannel]()&]
[s2;%% Creates a generic channel instance.&]
[s3; &]
[s4; &]
[s5;:Upp`:`:SshSession`:`:CreateExec`(`): [_^Upp`:`:SshExec^ SshExec]_[* CreateExec]()&]
[s2;%% Creates an exec channel instance.&]
[s3; &]
[s4; &]
[s5;:Upp`:`:SshSession`:`:CreateScp`(`): [_^Upp`:`:Scp^ Scp]_[* CreateScp]()&]
[s2;%% Creates an scp channel instance.&]
[s3; &]
[s4; &]
[s5;:Upp`:`:SshSession`:`:CreateTunnel`(`): [_^Upp`:`:SshTunnel^ SshTunnel]_[* CreateTunn
el]()&]
[s2;%% Creates a tcp`-ip and port forwarding channel instance.&]
[s3; &]
[s4; &]
[s5;:Upp`:`:SshSession`:`:CreateShell`(`): [_^Upp`:`:SshShell^ SshShell]_[* CreateShell](
)&]
[s2;%% Creates a remote shell channel instance.&]
[s3; &]
[s4; &]
[s5;:Upp`:`:SshSession`:`:Connect`(const Upp`:`:String`&`): [@(0.0.255) bool]_[* Connect](
[@(0.0.255) const]_[_^Upp`:`:String^ String][@(0.0.255) `&]_[*@3 url])&]

View file

@ -1,21 +1,20 @@
TITLE("Session")
COMPRESSED
120,156,237,27,127,119,219,182,241,171,224,53,107,39,231,217,50,73,137,146,44,117,123,118,21,167,206,107,98,231,69,206,214,77,143,54,33,10,146,88,83,164,70,128,118,180,182,249,236,187,3,64,18,148,37,91,178,147,117,127,172,47,181,73,240,112,184,223,184,59,192,195,176,217,236,244,168,227,246,110,126,186,56,234,57,228,79,127,178,247,173,23,141,182,221,232,184,13,187,233,180,224,135,221,176,29,215,105,52,237,142,115,212,236,52,26,29,171,27,68,148,115,111,24,57,157,142,156,228,236,59,47,156,182,235,216,237,102,167,217,177,27,237,142,3,115,29,203,114,172,182,227,218,205,70,199,113,187,99,198,3,111,104,1,120,3,214,56,106,53,142,44,219,178,218,182,109,53,156,182,213,112,155,182,221,112,0,133,211,118,108,203,237,178,120,236,13,207,90,61,156,208,132,9,150,219,178,44,171,5,216,154,77,11,176,227,180,102,195,110,88,78,195,181,143,220,86,119,196,166,97,236,13,239,179,228,62,202,82,219,234,134,130,205,53,71,180,217,123,121,236,246,108,152,218,218,
111,189,104,195,178,77,23,22,59,66,142,26,48,205,113,90,238,145,237,54,129,164,166,229,116,83,246,175,44,76,217,156,197,66,99,8,109,219,177,123,35,187,221,3,18,62,127,254,92,183,155,150,146,84,27,104,177,45,160,219,177,97,12,248,104,219,238,145,117,228,118,236,142,213,104,55,29,183,13,172,47,104,74,231,154,147,81,211,233,105,62,58,251,157,23,45,187,5,18,181,58,64,191,123,4,8,44,96,2,126,131,32,93,248,215,232,116,133,158,140,243,112,210,209,254,209,11,16,82,195,181,218,71,86,187,217,118,155,192,137,99,183,108,16,164,133,252,131,26,186,113,146,206,105,228,13,113,130,133,178,126,228,191,238,43,54,161,89,4,236,254,122,253,59,25,146,95,127,181,113,248,184,6,42,172,55,157,186,181,71,134,220,234,125,251,45,25,190,60,110,247,154,100,192,103,3,198,121,152,196,158,247,251,239,223,121,67,222,232,17,252,101,247,186,31,23,11,191,235,119,75,16,124,147,22,214,37,195,227,154,85,183,234,192,236,94,131,104,171,107,144,107,111,248,178,97,
226,196,177,46,140,154,208,139,108,20,133,65,14,126,220,232,201,25,30,46,106,245,94,72,53,1,125,151,179,144,43,196,132,197,1,93,240,44,162,130,113,66,9,103,65,150,50,194,103,44,138,72,237,150,165,184,18,113,246,0,58,4,77,195,119,185,118,157,188,17,4,112,164,140,47,146,152,135,163,136,145,73,146,18,198,5,5,2,248,44,140,167,251,132,102,98,6,147,194,128,10,245,30,143,201,156,198,20,44,118,10,107,5,233,114,33,146,105,74,23,51,0,137,162,165,94,125,172,151,215,107,17,248,71,99,50,24,156,57,36,72,230,139,40,164,146,144,20,168,171,27,242,208,12,1,85,99,150,134,183,128,102,146,38,115,50,188,18,201,34,12,64,188,135,254,97,63,73,153,127,8,168,252,67,158,6,254,33,106,225,26,80,248,215,63,80,206,252,107,22,251,7,25,247,95,148,218,41,212,114,37,5,73,70,0,167,86,82,252,204,40,39,128,254,6,8,2,214,128,87,94,47,21,157,155,200,235,154,237,116,246,126,148,63,143,237,210,74,200,123,169,46,242,142,137,89,
50,38,111,67,46,86,44,197,221,96,41,151,225,156,37,153,240,107,97,44,252,61,48,153,235,171,123,112,87,21,99,41,173,132,248,223,121,215,176,184,198,225,213,204,111,128,15,63,30,55,200,156,123,123,72,130,131,180,14,152,224,68,168,9,228,150,70,25,3,72,50,15,65,215,44,72,226,49,175,35,8,170,153,128,206,87,32,69,66,206,51,80,232,34,67,36,240,217,80,90,50,250,133,5,2,151,77,200,40,74,130,27,68,49,79,198,172,78,62,48,145,165,49,39,254,75,129,246,138,246,53,87,130,10,102,52,140,1,176,78,206,19,1,248,103,20,12,130,207,8,207,70,124,201,33,166,113,169,27,0,139,99,22,129,77,196,51,48,9,129,107,135,41,152,135,116,227,42,145,92,89,139,130,200,173,92,41,2,216,199,135,230,195,26,233,131,105,166,250,181,54,74,146,232,169,106,49,16,85,85,131,72,181,110,70,222,181,255,151,107,243,163,72,51,102,232,235,52,6,63,4,166,64,102,227,144,171,231,127,74,247,209,168,165,56,199,84,80,152,73,99,62,1,79,223,78,
226,6,121,210,215,20,246,49,25,45,115,193,214,85,124,209,51,233,100,2,10,86,122,191,155,37,16,40,138,24,114,9,90,97,176,8,216,146,32,243,140,11,50,66,179,186,77,110,0,31,11,97,70,10,35,18,128,198,75,160,30,180,25,8,92,152,10,80,242,66,32,123,119,0,7,166,136,232,183,116,245,92,105,107,188,221,208,231,223,33,116,245,147,120,18,78,175,72,249,236,17,118,11,33,173,42,6,30,204,96,31,132,136,10,97,10,56,224,11,22,132,147,16,120,184,13,169,114,7,20,241,34,73,69,46,20,174,124,197,140,21,143,217,215,121,82,177,176,167,90,87,5,141,87,43,45,230,213,90,51,1,183,166,115,16,63,55,25,174,77,104,196,217,222,255,237,101,123,123,217,94,207,63,177,37,247,107,64,59,176,151,3,136,20,68,233,127,231,239,239,54,252,156,40,132,100,84,195,143,92,4,190,149,200,228,66,128,72,254,94,131,4,2,213,34,13,111,216,210,219,39,207,199,148,141,190,20,166,89,10,155,248,10,38,35,184,226,70,48,9,35,246,88,140,85,123,
226,12,189,99,57,7,235,77,97,39,135,116,10,179,26,180,57,160,150,227,214,7,54,154,113,48,80,120,52,18,34,38,103,22,166,61,252,246,192,32,45,143,36,249,188,49,4,148,5,90,55,206,1,145,222,226,124,192,191,143,6,13,190,160,193,209,196,151,164,22,39,2,18,51,112,98,200,205,199,108,188,165,159,150,59,233,29,208,168,252,67,17,85,200,131,200,44,155,9,32,4,176,160,52,246,11,194,149,158,229,182,155,15,41,133,17,46,85,193,193,241,32,5,24,97,48,100,64,254,24,99,10,98,5,164,98,38,5,133,75,98,66,137,62,123,43,249,147,0,92,199,135,80,9,59,223,189,71,108,70,111,195,36,131,28,240,2,61,255,14,50,17,4,88,174,91,104,206,230,73,186,36,163,108,130,27,29,154,141,80,124,43,253,5,34,163,145,84,216,78,91,190,74,219,84,14,182,175,33,254,134,201,196,83,157,78,33,220,148,144,137,229,66,90,109,129,88,174,117,69,228,175,60,105,83,24,214,24,41,4,97,224,29,179,235,123,187,17,218,3,130,232,87,173,63,185,
28,200,190,128,214,227,26,202,43,141,97,78,151,185,72,177,132,0,177,70,57,50,105,161,148,64,154,8,193,119,162,7,33,117,198,40,172,214,76,224,75,73,155,70,142,240,185,137,164,0,128,102,133,208,17,163,21,112,0,128,84,92,108,101,225,187,107,22,226,176,41,233,119,116,241,60,197,98,64,173,42,15,80,106,253,193,83,69,133,247,147,239,245,122,224,160,34,141,93,73,153,207,146,44,26,23,250,0,163,246,15,84,26,190,160,32,203,125,116,239,148,169,232,148,50,220,154,177,174,91,36,92,85,113,90,106,168,124,93,225,232,244,184,132,45,84,140,66,6,87,12,23,209,253,20,167,198,247,54,107,249,143,86,239,123,40,223,238,146,116,124,2,241,248,233,169,148,137,197,204,164,202,125,193,168,127,97,67,200,69,155,96,17,9,123,197,66,207,95,129,219,129,219,173,120,149,37,38,108,231,207,100,214,68,179,27,183,170,39,33,227,249,87,229,244,12,140,12,203,248,103,170,181,130,102,55,78,103,104,230,216,33,248,202,58,5,53,140,18,250,92,251,53,177,236,198,
231,141,158,233,31,192,238,196,82,170,54,236,26,112,18,69,44,158,178,67,221,23,98,123,95,87,14,39,83,64,253,60,33,20,40,76,9,228,213,115,198,101,167,42,198,230,130,127,64,17,84,82,188,137,169,205,217,149,89,225,232,206,41,207,29,3,163,159,145,212,229,73,163,14,183,59,136,227,71,38,206,0,89,196,10,113,188,125,243,3,246,205,160,134,57,29,12,222,92,156,95,145,213,145,170,76,94,74,153,20,120,10,153,20,28,82,216,41,164,206,243,132,45,10,71,32,28,167,104,214,205,228,68,236,217,241,44,8,24,182,201,206,63,190,125,139,3,19,26,70,89,202,118,99,232,7,108,225,164,200,144,204,245,43,74,174,230,250,154,114,53,1,40,191,190,95,40,20,10,46,21,198,116,39,209,255,51,7,207,197,169,36,156,16,122,11,180,162,13,236,70,236,187,87,238,107,32,133,165,160,78,200,9,183,39,186,58,113,51,241,15,172,61,56,59,177,159,182,248,202,204,167,174,238,184,173,39,175,95,157,251,136,242,46,103,224,24,121,250,3,222,132,170,148,154,196,
190,69,134,137,197,56,156,50,149,112,86,21,140,241,25,183,33,211,58,147,180,46,155,147,165,129,26,165,16,44,5,41,74,65,152,164,4,114,23,142,168,83,122,71,70,97,76,177,174,88,10,204,150,176,240,154,177,79,184,124,40,224,157,39,88,156,129,227,227,135,49,184,124,32,162,37,145,152,118,183,173,65,18,220,48,177,26,232,46,131,133,250,112,69,138,199,117,97,174,64,96,134,185,210,169,101,198,5,181,43,203,221,58,119,103,46,39,237,232,5,121,242,188,198,2,214,103,189,164,156,181,89,247,86,47,63,190,40,233,206,235,10,158,45,48,247,92,83,220,240,138,178,49,212,66,56,87,133,178,154,92,198,37,50,40,176,152,89,48,161,41,43,179,95,213,185,242,191,193,64,237,127,163,49,230,209,194,168,111,102,97,48,203,235,242,34,97,86,165,112,181,36,210,229,241,254,250,101,84,242,237,127,99,214,231,176,201,230,73,57,206,129,36,63,74,238,88,26,224,201,68,196,132,192,86,238,46,217,48,8,31,55,64,67,109,21,141,129,213,38,41,232,75,254,246,190,
223,232,205,127,213,138,52,112,105,99,219,78,115,25,248,233,250,148,195,232,76,23,202,187,149,228,84,212,39,157,53,137,64,24,40,228,73,146,109,66,39,197,22,100,80,98,196,232,144,5,9,93,16,248,176,95,228,229,30,234,87,141,200,141,26,187,25,197,16,134,18,153,233,149,67,107,179,34,47,55,18,9,18,39,49,142,40,90,205,145,162,251,137,228,67,213,147,76,229,33,25,232,22,107,40,60,165,0,206,87,184,81,109,231,226,40,14,152,2,102,100,203,8,76,167,12,124,197,65,21,110,204,50,49,77,230,84,232,19,183,2,210,60,240,40,20,252,90,128,163,42,11,186,63,182,241,32,68,182,93,16,238,94,86,38,231,226,79,117,208,81,0,154,65,73,141,74,77,243,137,88,228,135,56,32,10,46,40,68,168,29,98,145,66,213,87,8,214,164,136,250,139,76,17,245,179,65,88,62,178,142,54,2,169,32,195,126,223,179,169,59,253,196,130,53,164,225,176,164,11,31,12,162,228,235,122,105,49,248,244,124,122,6,193,125,181,5,168,181,160,162,180,96,163,206,130,
47,160,178,203,108,131,198,212,7,41,24,245,104,208,164,7,214,170,75,0,87,7,225,66,165,218,184,57,64,146,126,7,174,138,62,246,124,145,225,105,245,186,10,4,199,85,253,129,79,166,248,228,251,90,74,83,54,199,64,175,78,192,159,67,154,58,252,216,116,146,176,215,93,219,253,38,122,218,23,232,252,103,105,100,180,176,52,94,89,219,80,117,150,175,162,147,113,90,166,99,145,110,111,225,124,163,178,74,51,179,168,168,147,178,90,93,66,54,245,41,207,245,62,126,120,139,193,16,59,75,114,39,192,219,20,125,192,230,15,177,132,251,13,172,19,126,64,88,241,127,67,119,241,189,238,225,161,63,196,157,167,155,71,125,255,216,247,48,184,251,195,46,90,138,239,121,16,165,235,222,110,71,193,15,202,126,95,246,139,119,58,202,249,250,234,66,150,87,142,68,202,206,51,10,226,75,156,188,160,160,191,200,9,78,190,67,239,102,96,180,232,157,74,110,43,135,21,200,225,102,115,219,69,251,175,66,30,228,6,176,170,184,219,36,28,75,197,149,64,43,103,176,65,206,71,126,
29,193,228,101,7,255,47,143,32,205,168,116,138,135,145,87,68,254,242,190,151,25,155,113,86,105,84,88,224,67,242,224,18,157,137,205,67,33,148,248,144,30,121,227,76,158,157,104,159,91,164,137,72,130,36,146,41,6,159,209,27,24,154,97,50,138,170,64,39,84,169,29,188,253,43,99,80,45,37,120,193,66,172,61,24,223,229,64,28,9,199,92,115,11,254,100,127,167,154,137,238,198,98,94,14,173,100,96,219,178,185,54,13,173,241,189,221,152,205,251,205,152,152,76,153,201,246,235,44,150,231,220,87,36,127,242,190,87,254,83,187,103,125,123,133,84,170,248,74,237,191,153,232,70,150,198,165,174,84,65,25,204,198,251,88,208,230,231,107,249,201,187,60,47,164,101,59,59,144,248,100,155,11,171,112,121,116,199,179,213,180,180,78,250,250,74,153,58,176,48,234,248,152,221,21,216,114,159,212,141,56,149,252,235,58,10,3,125,196,181,244,217,120,71,219,121,143,202,219,108,60,171,145,176,20,27,206,219,228,43,185,76,192,144,2,150,202,19,24,105,36,178,99,96,92,72,
0,159,41,43,82,217,26,196,75,109,170,241,23,198,19,188,153,136,112,52,170,147,247,249,209,140,174,249,0,81,8,241,161,60,126,131,196,31,216,120,217,39,239,207,78,6,167,254,245,171,243,193,126,254,220,191,56,63,63,237,95,190,185,56,47,134,206,78,206,95,13,206,78,126,58,45,70,78,62,94,158,93,124,120,243,207,147,10,220,224,99,191,127,58,24,120,187,73,245,111,144,22,79,150,166,88,127,132,204,230,138,224,207,7,138,199,251,59,79,33,111,133,113,157,251,78,177,99,106,10,125,34,197,145,71,237,73,22,173,139,77,247,220,245,86,46,32,45,79,54,240,233,148,98,194,101,20,169,55,113,114,23,147,26,236,10,120,110,181,39,193,32,7,65,7,98,170,137,40,104,58,5,103,199,15,177,188,48,147,39,154,113,54,31,33,81,188,170,52,110,218,181,188,78,3,20,70,186,239,126,223,78,118,53,237,52,249,180,81,7,165,33,35,212,125,183,207,165,170,93,126,157,199,167,225,116,38,242,171,54,72,113,24,135,34,164,145,110,23,25,12,228,213,105,97,223,
90,244,34,140,194,127,171,243,247,16,66,6,200,5,220,218,63,240,191,89,68,217,20,11,104,40,137,99,38,32,2,220,160,12,62,45,9,29,211,5,10,14,182,101,255,96,140,151,45,199,95,85,134,63,219,246,230,224,0,224,240,93,53,201,11,121,194,136,148,102,171,71,222,95,12,222,252,12,148,70,75,164,81,183,251,33,185,207,212,174,242,179,185,159,175,70,17,41,108,93,159,72,86,0,175,193,78,113,85,34,175,43,138,234,128,235,246,16,24,255,66,200,89,58,4,203,203,153,91,95,119,210,117,47,95,123,223,73,150,58,93,243,74,172,170,101,118,20,110,126,244,244,216,38,182,49,94,212,30,138,36,79,248,84,238,138,57,105,235,2,14,246,76,70,52,184,81,87,159,165,90,139,93,237,201,103,98,58,29,80,61,33,25,128,164,5,200,61,19,76,72,29,179,163,163,21,168,212,237,86,77,128,172,25,21,102,117,5,155,98,227,49,7,53,47,205,9,147,133,253,123,119,183,147,81,126,39,70,6,198,28,41,236,81,120,191,195,240,254,185,66,70,241,102,118,192,
202,107,208,13,240,209,113,168,182,45,35,210,145,26,124,211,93,78,76,135,229,221,146,80,68,242,46,11,190,160,253,166,153,50,110,79,161,211,119,199,18,216,237,241,10,10,66,171,157,210,0,205,201,50,83,130,34,172,98,144,202,25,40,194,23,195,29,148,138,82,103,40,237,135,18,12,57,17,99,202,106,72,209,247,9,119,185,234,221,79,52,237,120,239,150,129,168,163,45,175,122,27,111,170,158,120,105,30,105,154,213,131,190,25,21,148,43,237,224,150,254,231,123,11,153,165,215,103,239,209,117,199,172,88,150,156,84,186,140,65,148,228,27,101,181,211,72,148,147,233,194,202,170,72,242,193,191,171,48,174,37,229,189,102,45,77,167,167,123,3,228,7,134,91,77,104,118,155,239,93,125,82,29,254,26,118,243,247,212,223,39,232,22,113,77,101,91,123,70,131,26,140,6,226,37,88,118,112,67,167,172,110,44,86,152,64,211,110,52,186,110,167,213,142,14,157,86,10,255,139,67,187,57,130,255,143,237,3,101,12,127,81,214,0,81,134,156,126,82,153,178,231,117,187,0,239,
2,188,11,240,46,192,187,199,142,132,38,234,83,21,85,205,110,119,246,10,100,128,9,128,138,87,121,172,2,165,197,90,156,191,217,38,17,125,98,90,64,247,221,41,100,129,175,252,235,211,159,251,144,34,254,120,234,229,104,17,184,79,198,225,4,138,104,255,0,195,61,108,190,254,193,52,77,178,133,237,31,64,86,101,23,176,100,171,73,205,103,204,114,220,214,142,243,90,114,158,107,59,59,206,235,60,109,158,127,192,180,98,159,194,229,202,236,7,184,101,193,120,166,96,252,131,24,236,123,177,11,108,163,211,220,26,214,117,54,242,16,100,144,198,64,128,176,143,114,106,253,99,117,35,160,158,164,211,237,103,121,235,236,124,197,101,240,94,14,26,251,127,207,91,220,199,157,229,236,98,112,249,211,233,63,86,124,69,94,23,25,115,190,73,0,242,123,202,233,3,42,224,116,7,221,174,0,63,172,220,21,224,7,180,43,201,100,99,169,169,109,52,212,87,151,148,107,186,176,135,112,122,8,155,221,64,166,186,123,255,99,81,174,127,122,222,255,240,143,247,88,241,234,76,239,65,
240,129,1,94,21,18,101,28,205,254,32,16,41,217,36,72,128,177,143,28,9,243,60,16,181,210,40,32,181,52,252,37,30,83,22,201,87,112,186,37,167,184,241,70,97,86,135,20,243,209,85,70,193,67,32,78,231,65,144,6,236,244,207,3,8,40,23,143,173,66,211,0,207,112,31,249,12,88,54,65,200,163,213,45,204,246,221,73,159,156,81,249,55,139,127,188,237,182,183,48,93,32,120,43,155,69,184,170,72,102,115,26,228,222,255,64,72,49,193,30,216,255,10,176,141,17,164,132,240,15,142,30,89,110,62,118,31,5,120,28,75,26,46,216,124,108,183,44,82,91,25,240,143,147,5,139,113,107,10,146,249,70,15,217,214,104,204,63,107,250,239,26,13,24,137,243,184,145,12,250,23,239,222,127,208,119,252,182,48,150,190,9,95,21,201,191,97,71,175,8,111,29,103,27,249,90,65,244,212,185,185,94,86,245,240,22,82,165,12,210,241,63,220,115,183,240,219,183,144,86,127,60,129,204,122,27,231,45,128,171,202,192,70,142,55,236,95,205,132,88,112,213,202,17,73,18,
113,191,30,50,49,241,49,237,242,15,103,98,30,249,135,233,36,104,182,154,173,43,242,225,117,223,63,192,71,60,202,84,127,248,41,11,80,94,207,139,38,137,221,243,254,3,138,221,87,36,
120,156,237,27,253,115,218,200,245,95,217,185,244,174,56,131,177,36,16,96,184,118,236,35,206,57,115,137,157,9,73,123,45,35,91,139,180,128,106,33,169,90,201,14,189,94,254,246,190,183,187,146,86,24,108,176,47,189,254,208,76,98,131,244,246,237,251,254,218,205,36,232,116,250,67,106,217,195,155,159,46,143,135,22,249,195,31,204,166,241,162,221,51,219,125,187,109,118,172,46,252,48,219,166,101,91,237,142,217,183,142,59,253,118,187,111,12,188,144,114,238,76,66,171,223,23,139,172,166,245,194,234,217,150,217,235,244,59,125,179,221,235,91,176,214,50,12,203,232,89,182,217,105,247,45,123,224,51,238,57,19,3,192,219,176,199,113,183,125,108,152,134,209,51,77,163,109,245,140,182,221,49,205,182,5,40,172,158,101,26,246,128,69,190,51,57,239,14,113,65,7,22,24,118,215,48,140,46,96,235,116,12,192,142,203,58,109,179,109,88,109,219,60,182,187,131,41,155,7,145,51,185,207,146,253,40,75,61,99,16,100,108,169,56,162,157,225,203,19,123,104,194,210,110,179,251,
162,7,219,118,108,216,236,24,57,106,195,50,203,234,218,199,166,221,1,146,58,134,53,72,217,63,243,32,101,75,22,101,10,67,96,154,150,57,156,154,189,33,144,240,229,203,151,150,217,49,164,164,122,64,139,105,0,221,150,9,207,128,143,158,105,31,27,199,118,223,236,27,237,94,199,178,123,192,122,66,83,186,84,156,76,59,214,80,241,209,111,246,95,116,205,46,72,212,232,3,253,246,49,32,48,128,9,248,13,130,180,225,111,187,63,200,212,98,92,135,139,142,155,199,47,64,72,109,219,232,29,27,189,78,207,238,0,39,150,217,53,65,144,6,242,15,106,24,68,113,186,164,161,51,193,5,6,202,250,145,63,131,87,108,70,243,16,216,253,229,250,87,50,33,191,252,98,226,227,147,6,168,176,213,177,90,198,1,153,112,99,248,237,183,100,242,242,164,55,236,144,49,95,140,25,231,65,28,57,206,175,191,126,231,76,120,123,72,240,151,57,28,124,74,18,119,224,14,42,16,252,38,44,108,64,38,39,13,163,101,180,128,217,131,54,81,86,215,38,215,206,228,101,91,199,137,
207,6,240,84,135,78,242,105,24,120,5,248,73,123,40,86,56,184,169,49,124,33,212,4,244,125,92,4,92,34,38,44,242,104,194,243,144,102,140,19,74,56,243,242,148,17,190,96,97,72,26,183,44,197,157,136,117,0,208,1,104,26,222,139,189,91,228,77,70,0,71,202,120,18,71,60,152,134,140,204,226,148,48,158,81,32,128,47,130,104,222,36,52,207,22,176,40,240,104,38,191,71,62,89,210,136,130,197,206,97,47,47,93,37,89,60,79,105,178,0,144,48,92,169,221,125,181,189,218,139,192,95,26,145,241,248,220,34,94,188,76,194,128,10,66,82,160,174,165,201,67,49,4,84,249,44,13,110,1,205,44,141,151,100,114,149,197,73,224,129,120,143,220,163,81,156,50,247,8,80,185,71,60,245,220,35,212,194,53,160,112,175,127,160,156,185,215,44,114,15,115,238,190,168,180,83,170,229,74,8,146,76,1,78,238,36,249,89,80,78,0,253,13,16,4,172,1,175,188,85,41,186,48,145,215,13,211,234,31,252,40,126,158,152,149,149,144,247,66,93,228,29,203,22,177,79,
222,6,60,91,179,20,123,139,165,124,12,150,44,206,51,183,17,68,153,123,0,38,115,125,117,15,238,170,102,44,149,149,16,247,59,231,26,54,87,56,156,134,254,14,240,225,203,147,54,89,114,231,0,73,176,144,214,49,203,56,201,228,2,114,75,195,156,1,36,89,6,160,107,230,197,145,207,91,8,130,106,38,160,243,53,200,44,38,23,57,40,52,201,17,9,188,214,148,22,79,255,193,188,12,183,141,201,52,140,189,27,68,177,140,125,214,34,31,88,150,167,17,39,238,203,12,237,21,237,107,41,5,229,45,104,16,1,96,139,92,196,25,224,95,80,48,8,190,32,60,159,242,21,135,152,198,133,110,0,44,138,88,8,54,17,45,192,36,50,220,59,72,193,60,132,27,215,137,228,210,90,36,68,97,229,82,17,192,62,126,232,60,172,145,17,152,102,170,190,54,166,113,28,62,85,45,26,162,186,106,16,169,210,205,212,185,118,255,116,173,191,204,210,156,105,250,58,139,192,15,129,41,144,153,31,112,249,249,239,194,125,20,106,33,78,159,102,20,86,210,136,207,192,211,119,147,
184,70,158,240,53,137,221,39,211,85,33,216,150,140,47,106,37,157,205,64,193,82,239,119,139,24,2,69,25,67,62,130,86,24,108,2,182,148,145,101,206,51,50,69,179,186,141,111,0,31,11,96,69,10,79,4,0,141,86,64,61,104,211,203,112,99,154,129,146,147,12,217,187,3,56,48,69,68,191,163,171,23,74,219,224,237,154,62,255,10,161,107,20,71,179,96,126,69,170,207,14,97,183,16,210,234,98,224,222,2,242,32,68,84,8,83,192,1,79,152,23,204,2,224,225,54,160,210,29,80,196,73,156,102,133,80,184,244,21,61,86,60,102,95,23,113,205,194,158,106,93,53,52,78,163,178,152,87,27,205,4,220,154,46,65,252,92,103,184,49,163,33,103,7,255,183,151,221,237,101,119,61,255,196,86,220,109,0,237,192,94,1,144,165,32,74,247,59,183,185,223,227,231,68,33,36,163,30,126,196,38,240,174,66,38,54,2,68,226,247,6,36,16,168,146,52,184,97,43,167,73,158,143,41,159,254,86,152,22,41,36,241,53,76,90,112,197,68,48,11,66,246,64,140,53,134,
69,41,37,19,227,2,93,100,181,4,19,78,33,157,67,77,133,165,13,26,30,144,204,49,255,129,161,230,28,172,20,62,106,85,17,19,43,75,251,158,124,123,168,209,87,132,147,98,157,15,81,37,65,19,199,53,32,215,91,92,15,248,155,104,213,224,16,10,28,237,124,69,26,81,156,65,117,6,158,12,5,186,207,252,29,157,181,74,167,119,64,163,116,18,73,84,41,20,34,74,109,150,1,33,128,5,69,210,44,9,151,202,22,185,183,120,36,181,70,184,208,7,7,239,131,58,96,138,17,145,1,249,62,6,22,196,10,72,179,133,16,20,110,137,85,37,58,238,173,224,79,0,112,21,36,2,41,236,34,133,79,217,130,222,6,113,14,133,224,37,186,255,29,148,35,8,176,218,180,209,146,45,227,116,69,166,249,12,179,29,218,78,38,249,150,250,243,178,156,134,66,97,186,28,2,81,231,38,49,151,69,46,80,136,209,49,135,215,178,212,150,20,98,233,160,125,111,208,27,218,210,117,36,148,14,58,248,24,131,113,96,252,3,188,77,194,3,168,102,87,164,12,193,9,214,175,
160,69,169,66,208,143,168,154,234,146,220,171,38,145,117,165,44,18,155,10,226,47,88,237,60,53,42,72,132,219,42,198,108,149,8,183,42,17,139,189,174,136,248,85,84,149,18,195,122,101,41,76,154,129,94,176,252,191,151,46,209,86,17,68,125,85,18,17,219,129,76,75,104,245,92,65,57,149,161,46,233,170,80,55,246,56,160,242,176,64,38,188,135,18,168,99,33,59,204,212,67,168,237,49,77,200,61,99,120,83,209,166,144,35,124,97,190,41,0,160,201,35,116,200,104,13,28,0,160,87,200,118,242,190,253,53,11,137,66,151,244,59,154,60,79,177,24,241,235,202,3,148,74,127,240,169,166,194,251,221,193,102,61,112,80,145,194,46,165,204,23,113,30,250,165,62,192,168,221,67,217,39,36,20,100,217,196,208,147,50,25,57,83,134,181,3,54,158,165,7,42,169,161,242,85,11,166,234,247,10,182,84,49,10,25,194,68,144,132,247,107,176,6,63,216,174,229,223,91,189,239,33,18,220,197,169,127,10,97,227,233,181,158,142,69,47,245,170,156,165,53,232,144,172,10,209,
198,216,229,66,40,75,212,250,53,184,61,184,221,137,87,17,55,161,222,120,38,179,58,154,253,184,213,34,247,87,229,244,28,140,12,231,12,207,84,107,13,205,126,156,46,208,204,113,132,241,149,117,10,106,152,198,244,185,246,171,99,217,143,207,27,181,210,61,132,236,196,82,42,139,137,6,112,18,134,44,154,179,35,53,184,98,7,95,87,14,167,115,64,253,60,33,148,40,116,9,20,237,125,206,197,40,45,194,233,135,123,72,17,84,80,188,141,169,237,149,159,222,130,169,209,46,47,28,3,163,159,86,204,20,5,173,10,183,123,136,227,71,150,157,3,178,144,149,226,120,251,230,7,28,236,65,147,117,54,30,191,185,188,184,34,235,79,234,50,121,41,100,82,226,41,101,82,114,72,33,83,8,157,23,197,100,24,76,65,56,86,57,77,92,136,133,56,84,228,185,231,49,156,227,93,124,122,251,22,31,204,104,16,230,41,219,143,161,31,112,198,148,34,67,162,25,169,41,185,222,140,40,202,229,2,160,252,250,126,39,83,42,184,82,24,83,163,78,247,143,28,60,23,151,146,96,
70,232,45,208,138,54,176,31,177,239,94,217,175,129,20,150,130,58,161,38,220,157,232,250,194,237,196,63,176,247,248,252,212,124,218,230,107,43,159,186,187,101,119,159,188,127,125,237,35,202,251,184,0,199,40,202,31,240,38,84,165,208,164,106,29,124,226,7,115,38,11,206,186,130,49,62,99,26,210,173,51,78,91,162,15,168,12,84,107,79,96,43,40,81,74,194,4,37,80,187,112,68,157,210,59,50,13,34,138,61,207,42,195,106,9,155,194,5,251,140,219,7,25,124,231,177,234,111,240,133,15,46,239,101,208,143,8,76,251,219,214,56,246,110,88,182,30,232,62,122,137,124,113,69,202,143,155,194,92,137,64,15,115,149,83,139,138,11,250,106,86,184,117,225,206,92,44,218,211,11,138,226,121,131,5,108,174,122,73,181,106,187,238,171,161,64,69,119,209,87,240,60,193,218,115,67,115,195,107,202,198,80,91,118,128,114,113,21,151,200,184,196,162,87,193,132,166,172,170,126,229,104,205,253,6,3,181,251,141,194,88,68,11,173,191,89,4,222,162,152,25,148,5,179,108,211,
235,45,145,106,221,155,155,183,145,197,183,251,141,222,51,67,146,45,138,114,92,3,69,126,24,223,177,212,195,163,147,144,101,25,206,154,247,169,134,65,248,152,0,53,181,213,52,6,86,27,167,160,47,241,219,249,126,171,55,255,89,41,82,195,165,140,109,55,205,229,224,167,155,75,14,109,116,94,42,239,86,144,83,83,159,112,214,56,4,97,160,144,103,113,190,13,157,16,155,151,67,139,17,161,67,150,36,12,64,224,147,81,89,151,59,168,95,249,68,36,106,156,15,148,143,48,148,136,74,175,122,180,177,42,114,10,35,17,32,81,28,225,19,73,171,254,164,28,207,34,249,208,245,196,115,113,138,7,186,197,30,10,143,81,128,243,53,110,228,92,188,60,43,4,166,128,25,49,206,2,211,169,2,95,121,146,134,137,89,20,166,241,146,102,234,72,176,132,212,79,100,74,5,191,206,192,81,119,58,156,17,163,224,109,115,213,131,193,198,89,32,81,203,126,131,57,104,158,134,90,191,172,240,138,66,138,202,147,77,41,10,237,236,64,49,174,122,105,92,175,149,113,105,174,87,48,
173,106,132,52,94,65,232,254,92,36,150,79,31,222,162,228,177,141,21,102,135,103,203,35,192,230,78,176,94,252,55,247,18,248,49,203,224,39,251,204,60,215,25,28,29,185,19,52,243,65,97,98,238,137,235,160,37,185,147,1,154,160,235,56,96,18,45,103,191,131,177,7,101,223,20,195,169,189,6,219,95,95,93,200,242,218,128,184,26,115,161,32,126,139,57,52,10,250,55,153,103,23,225,96,63,3,163,229,160,70,112,91,155,218,34,135,219,205,109,31,237,191,10,184,87,24,192,186,226,110,227,192,23,138,171,128,214,78,164,188,130,143,226,112,86,231,101,143,164,95,29,200,232,153,227,12,143,102,174,136,248,229,124,47,210,131,118,114,163,149,115,224,67,226,24,7,157,137,45,131,44,147,226,67,122,196,253,27,49,68,86,62,151,164,113,22,123,113,40,226,25,95,208,27,120,180,192,204,135,170,64,39,148,121,4,190,253,51,103,169,24,243,114,150,109,60,38,220,231,120,16,9,199,196,182,3,127,162,153,172,167,189,253,88,44,106,175,181,112,191,43,155,27,115,94,131,
31,236,199,108,49,220,26,129,156,231,76,103,251,117,30,137,83,191,43,82,124,114,190,151,254,211,184,103,125,7,165,84,234,248,42,237,191,153,169,174,89,225,146,23,76,160,230,102,126,19,171,231,226,160,161,56,135,20,7,39,180,154,157,121,2,159,232,169,177,228,23,103,24,60,95,207,129,45,50,82,23,108,228,116,84,107,26,34,118,87,98,43,124,82,117,253,178,210,80,69,27,6,250,144,43,233,51,127,79,219,121,143,202,219,110,60,235,145,176,18,27,174,219,230,43,133,76,192,144,60,150,138,113,175,48,18,209,158,104,199,179,224,51,85,249,43,230,16,120,197,71,78,25,130,104,134,247,180,16,142,134,45,242,190,152,3,171,2,19,16,65,43,163,29,74,65,149,1,108,188,28,145,247,231,167,227,51,247,250,213,197,184,89,124,30,93,94,92,156,141,62,190,185,188,40,31,157,159,94,188,130,254,238,167,179,242,201,233,167,143,231,151,31,222,252,253,180,6,55,254,52,26,157,141,199,206,126,82,253,11,75,131,217,74,23,235,143,52,99,87,4,127,62,80,169,222,
207,60,165,188,37,198,77,238,59,199,241,140,46,244,153,16,71,17,181,103,121,184,41,54,221,115,215,91,177,129,176,60,49,45,164,115,80,27,254,46,43,226,155,40,190,139,72,3,178,2,14,201,15,4,24,212,32,232,64,76,78,44,50,154,206,193,217,241,69,36,174,15,224,0,9,227,90,148,47,167,72,20,175,43,141,235,118,45,46,23,0,133,161,26,242,221,183,147,125,77,59,141,63,111,213,65,101,200,8,117,223,237,11,169,42,151,223,228,241,105,48,95,100,197,197,3,164,56,136,130,44,160,161,234,77,53,6,138,82,184,180,111,37,250,44,8,131,127,201,131,200,0,66,6,200,5,220,218,61,116,191,73,194,124,142,213,58,212,223,17,203,32,2,220,160,12,62,175,8,245,105,130,130,131,180,236,30,250,120,245,204,255,170,50,252,217,52,183,7,7,0,135,247,114,34,87,202,19,158,8,105,118,135,228,253,229,248,205,207,64,105,184,66,26,213,108,17,122,250,92,102,149,159,245,124,190,30,69,132,176,65,178,119,208,183,8,86,0,175,198,78,121,102,140,36,139,
91,131,104,172,52,242,132,37,98,47,10,198,159,100,98,149,10,193,226,170,218,206,151,63,70,234,14,217,198,219,31,184,97,253,130,160,120,228,236,41,220,98,206,253,88,18,219,26,47,26,15,69,146,39,188,170,178,98,65,218,166,128,131,13,218,148,122,55,242,34,168,80,107,153,213,158,60,128,87,229,128,108,64,69,0,18,22,32,114,38,152,144,60,211,67,71,43,81,201,187,126,138,0,49,42,146,152,229,133,84,138,83,142,2,84,191,66,148,233,44,52,239,221,100,141,167,197,229,0,17,24,11,164,144,163,240,48,89,243,254,165,68,70,241,158,170,199,170,75,161,109,240,81,63,144,105,75,139,116,164,1,239,212,72,5,203,97,113,144,29,100,161,56,56,199,47,104,191,105,46,141,219,145,232,212,77,154,24,178,61,158,119,35,180,204,148,26,104,65,150,94,18,148,97,21,131,84,193,64,25,190,24,102,80,154,85,58,67,105,63,84,96,136,133,24,83,214,67,138,186,93,181,207,197,215,81,172,104,199,91,136,12,68,29,238,120,241,85,251,38,251,137,151,250,249,137,
222,61,168,43,34,94,181,211,30,110,233,126,185,183,145,222,122,125,113,30,221,215,103,229,182,228,180,54,210,240,194,184,72,148,245,177,6,145,78,166,26,43,163,38,201,7,111,153,107,119,32,138,193,150,146,166,53,84,179,1,242,3,195,84,19,232,163,173,123,247,44,228,56,177,129,163,195,3,121,91,91,205,163,26,178,218,58,208,166,97,96,52,16,47,193,178,189,27,58,103,45,109,179,210,4,58,102,187,61,176,251,221,94,120,100,117,83,248,151,29,153,157,41,252,59,49,15,165,49,252,73,90,3,68,25,114,246,89,86,202,142,51,24,0,188,13,240,54,192,219,0,111,159,88,2,154,200,87,117,84,13,179,215,63,40,145,1,38,0,42,191,138,25,46,180,22,27,113,254,219,212,137,24,17,221,2,6,239,206,160,10,124,229,94,159,253,60,130,18,241,199,51,167,64,139,192,35,226,7,51,104,162,221,67,12,247,144,124,221,195,121,26,231,137,233,30,66,85,101,150,176,100,167,69,157,103,172,178,236,238,158,235,186,98,157,109,90,123,174,235,63,109,157,123,200,148,
98,159,194,229,218,234,7,184,101,158,191,144,48,238,97,4,246,157,236,3,219,238,119,118,134,181,173,173,60,120,57,148,49,16,32,204,227,130,90,247,68,30,63,182,226,116,190,251,42,103,147,157,175,185,12,94,2,64,99,255,239,121,139,253,184,179,156,95,142,63,254,116,246,183,53,95,17,103,211,62,231,219,4,32,222,167,156,62,160,2,78,247,208,237,26,240,195,202,93,3,126,64,187,130,76,230,11,77,237,162,161,145,188,173,217,80,141,61,132,211,35,72,118,99,81,234,30,252,143,69,185,209,217,197,232,195,223,222,99,199,171,42,189,7,193,199,26,120,93,72,148,113,52,251,67,47,75,201,54,65,2,140,121,108,9,152,231,129,200,157,166,30,105,164,193,63,34,159,178,80,124,5,167,91,113,138,137,55,12,242,22,148,152,143,238,50,245,30,2,177,250,15,130,180,33,211,63,15,192,163,60,123,108,23,154,122,120,96,244,200,107,192,178,13,66,156,227,236,96,182,239,78,71,228,156,138,255,193,245,251,219,110,111,7,211,5,130,119,178,89,132,171,139,100,177,164,
94,225,253,15,132,20,29,236,129,252,87,130,109,141,32,21,132,123,120,252,200,118,75,223,126,20,224,113,44,105,144,176,165,111,118,13,210,88,123,224,158,196,9,139,48,53,121,241,114,171,135,236,106,52,250,127,242,248,239,26,13,24,137,245,184,145,140,71,151,239,222,127,80,23,138,118,48,150,145,14,95,23,201,191,32,163,215,132,183,137,179,173,124,173,33,122,234,218,66,47,235,122,120,11,165,82,14,229,248,239,238,185,59,248,237,91,40,171,63,157,66,101,189,139,243,150,192,117,101,224,32,199,153,140,174,22,89,150,112,57,202,201,226,56,228,110,43,96,217,204,197,178,203,61,90,100,203,208,61,74,103,94,167,219,233,94,145,15,175,71,238,33,126,196,163,76,249,223,224,68,3,202,91,69,211,36,176,59,206,127,0,33,114,88,67,