mirror of
https://git.libssh.org/projects/libssh.git
synced 2026-02-04 20:30:38 +09:00
Compare commits
107 Commits
libssh-0.8
...
libssh-0.8
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
04685a74df | ||
|
|
ec853bb86a | ||
|
|
7850307210 | ||
|
|
30c0f0c0e3 | ||
|
|
b0edec4e8d | ||
|
|
391c78de9d | ||
|
|
2ba1dea549 | ||
|
|
82c375b7c9 | ||
|
|
4aea835974 | ||
|
|
2fbeb2ac88 | ||
|
|
e981113ee1 | ||
|
|
3736a0367b | ||
|
|
be73335f8e | ||
|
|
52986115b8 | ||
|
|
7a49ee5ffc | ||
|
|
c842bc2e8b | ||
|
|
8892577296 | ||
|
|
ac7c64a769 | ||
|
|
47014eb273 | ||
|
|
2223106113 | ||
|
|
4af77362b0 | ||
|
|
f4a0fcc85e | ||
|
|
fa150ef8d2 | ||
|
|
810dbd3db1 | ||
|
|
fa6aa125a2 | ||
|
|
a4948f6212 | ||
|
|
e05e4ae971 | ||
|
|
b6d275537e | ||
|
|
e69fb89e98 | ||
|
|
f9beb3c690 | ||
|
|
bfc39d578d | ||
|
|
0acfd81f85 | ||
|
|
d028b2495d | ||
|
|
68fc17caac | ||
|
|
d327712739 | ||
|
|
fded1fb9eb | ||
|
|
a6e055c42b | ||
|
|
32221ea9fb | ||
|
|
917ba07478 | ||
|
|
bcdbc11732 | ||
|
|
79289dc506 | ||
|
|
45172a70fa | ||
|
|
7b0c80b475 | ||
|
|
d5bc9a1ace | ||
|
|
80d3e10b47 | ||
|
|
455d495c74 | ||
|
|
b1bae1d90f | ||
|
|
ad4f1dbea0 | ||
|
|
5ffe695c3c | ||
|
|
230a437288 | ||
|
|
1df272c3cc | ||
|
|
c3a57fe2dc | ||
|
|
a238df2436 | ||
|
|
f5e8fa5c5f | ||
|
|
0a07266d9c | ||
|
|
953eae880f | ||
|
|
1d5215a5af | ||
|
|
2d06a83b82 | ||
|
|
fd844cac6d | ||
|
|
a106a00e0d | ||
|
|
d8372c3063 | ||
|
|
946210534e | ||
|
|
fe0331cf40 | ||
|
|
709c48eab6 | ||
|
|
3d56bdae37 | ||
|
|
8b4de1c477 | ||
|
|
906f63ba97 | ||
|
|
26ea4f059a | ||
|
|
3b46198c42 | ||
|
|
3de34944ad | ||
|
|
69cb3c5835 | ||
|
|
5102b16cf1 | ||
|
|
dc071dc6cf | ||
|
|
a8d4fbaccb | ||
|
|
56b7d2da4d | ||
|
|
a4b99eedf2 | ||
|
|
8a8498b586 | ||
|
|
44b32e940e | ||
|
|
059079581a | ||
|
|
f11be32e11 | ||
|
|
a9be4ab73e | ||
|
|
273fb4cfc6 | ||
|
|
56f7c27852 | ||
|
|
1285b37b60 | ||
|
|
b7de358cdc | ||
|
|
bea6393de0 | ||
|
|
9158cc524c | ||
|
|
8ba10ef42b | ||
|
|
2ff8a09ee6 | ||
|
|
d52fa9a02c | ||
|
|
ec3fdb434c | ||
|
|
d877969db3 | ||
|
|
b1a7bd21ad | ||
|
|
0831b85002 | ||
|
|
34d1f5e097 | ||
|
|
fcf2cd0d9e | ||
|
|
4a4ca44b19 | ||
|
|
17a6c3f88f | ||
|
|
e24bb932ed | ||
|
|
5c2d444fa8 | ||
|
|
9763563c02 | ||
|
|
5f9d9f4a53 | ||
|
|
e8f3207a0d | ||
|
|
e5cee205c1 | ||
|
|
63056d1bb1 | ||
|
|
09e4f3d331 | ||
|
|
4b886ac656 |
@@ -4,7 +4,6 @@ variables:
|
||||
CENTOS7_BUILD: buildenv-centos7
|
||||
TUMBLEWEED_BUILD: buildenv-tumbleweed
|
||||
MINGW_BUILD: buildenv-mingw
|
||||
DEBIAN_CROSS_BUILD: buildenv-debian-cross
|
||||
|
||||
# torture_auth fails on centos7 docker images, so we don't use -DCLIENT_TESTING=ON
|
||||
centos7/openssl_1.0.x/x86-64:
|
||||
@@ -333,29 +332,3 @@ mingw32:
|
||||
when: on_failure
|
||||
paths:
|
||||
- obj/
|
||||
|
||||
.Debian.cross.template: &Debian_cross_template
|
||||
stage: test
|
||||
image: $CI_REGISTRY/$BUILD_IMAGES_PROJECT:$DEBIAN_CROSS_BUILD
|
||||
script:
|
||||
- build=$(dpkg-architecture -qDEB_HOST_GNU_TYPE)
|
||||
- host="${CI_JOB_NAME#*.cross.}"
|
||||
- mkdir -p obj && cd obj && cmake
|
||||
-DCMAKE_C_COMPILER="$(which $host-gcc)"
|
||||
-DCMAKE_CXX_COMPILER="$(which $host-g++)"
|
||||
-DCMAKE_BUILD_TYPE=Debug
|
||||
-DUNIT_TESTING=ON -DWITH_SFTP=ON -DWITH_SERVER=ON -DWITH_ZLIB=ON
|
||||
-DWITH_PCAP=ON .. && make -j$(nproc)
|
||||
- ctest --output-on-failure -j$(nproc)
|
||||
tags:
|
||||
- shared
|
||||
except:
|
||||
- tags
|
||||
artifacts:
|
||||
expire_in: 1 week
|
||||
when: on_failure
|
||||
paths:
|
||||
- obj/
|
||||
|
||||
Debian.cross.mips-linux-gnu:
|
||||
<<: *Debian_cross_template
|
||||
|
||||
@@ -10,7 +10,7 @@ list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/cmake/Modules")
|
||||
include(DefineCMakeDefaults)
|
||||
include(DefineCompilerFlags)
|
||||
|
||||
project(libssh VERSION 0.8.4 LANGUAGES C)
|
||||
project(libssh VERSION 0.8.9 LANGUAGES C)
|
||||
|
||||
# global needed variable
|
||||
set(APPLICATION_NAME ${PROJECT_NAME})
|
||||
@@ -22,7 +22,7 @@ set(APPLICATION_NAME ${PROJECT_NAME})
|
||||
# Increment AGE. Set REVISION to 0
|
||||
# If the source code was changed, but there were no interface changes:
|
||||
# Increment REVISION.
|
||||
set(LIBRARY_VERSION "4.7.1")
|
||||
set(LIBRARY_VERSION "4.7.6")
|
||||
set(LIBRARY_SOVERSION "4")
|
||||
|
||||
# where to look first for cmake modules, before ${CMAKE_ROOT}/Modules/ is checked
|
||||
@@ -39,6 +39,9 @@ include(CompilerChecks.cmake)
|
||||
include(MacroEnsureOutOfSourceBuild)
|
||||
macro_ensure_out_of_source_build("${PROJECT_NAME} requires an out of source build. Please create a separate build directory and run 'cmake /path/to/${PROJECT_NAME} [options]' there.")
|
||||
|
||||
# Copy library files to a lib sub-directory
|
||||
set(CMAKE_LIBRARY_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/lib")
|
||||
|
||||
# search for libraries
|
||||
if (WITH_ZLIB)
|
||||
find_package(ZLIB REQUIRED)
|
||||
@@ -116,11 +119,22 @@ install(
|
||||
)
|
||||
endif (UNIX)
|
||||
|
||||
# cmake config files
|
||||
# CMake config files
|
||||
include(CMakePackageConfigHelpers)
|
||||
|
||||
set(LIBSSH_LIBRARY_NAME ${CMAKE_SHARED_LIBRARY_PREFIX}ssh${CMAKE_SHARED_LIBRARY_SUFFIX})
|
||||
|
||||
configure_file(${PROJECT_NAME}-config.cmake.in ${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}-config.cmake @ONLY)
|
||||
configure_file(${PROJECT_NAME}-config-version.cmake.in ${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}-config-version.cmake @ONLY)
|
||||
# libssh-config-version.cmake
|
||||
write_basic_package_version_file(libssh-config-version.cmake
|
||||
VERSION ${PROJECT_VERSION}
|
||||
COMPATIBILITY SameMajorVersion)
|
||||
|
||||
# libssh-config.cmake
|
||||
configure_package_config_file(${PROJECT_NAME}-config.cmake.in
|
||||
${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}-config.cmake
|
||||
INSTALL_DESTINATION ${CMAKE_INSTALL_DIR}/${PROJECT_NAME}
|
||||
PATH_VARS INCLUDE_INSTALL_DIR LIB_INSTALL_DIR)
|
||||
|
||||
install(
|
||||
FILES
|
||||
${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}-config.cmake
|
||||
@@ -131,10 +145,6 @@ install(
|
||||
devel
|
||||
)
|
||||
|
||||
|
||||
# in tree build settings
|
||||
configure_file(libssh-build-tree-settings.cmake.in ${CMAKE_CURRENT_BINARY_DIR}/libssh-build-tree-settings.cmake @ONLY)
|
||||
|
||||
if (WITH_EXAMPLES)
|
||||
add_subdirectory(examples)
|
||||
endif (WITH_EXAMPLES)
|
||||
|
||||
13
COPYING
13
COPYING
@@ -455,6 +455,15 @@ FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF
|
||||
SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
|
||||
DAMAGES.
|
||||
|
||||
Linking with OpenSSL
|
||||
17. In addition, as a special exception, we give permission to link the code of its release of libssh with the OpenSSL project's "OpenSSL" library (or with modified versions of it that use the same license as the "OpenSSL" library), and distribute the linked executables. You must obey the GNU Lesser General Public License in all respects for all of the code used other than "OpenSSL". If you modify this file, you may extend this exception to your version of the file, but you are not obligated to do so. If you do not wish to do so, delete this exception statement from your version.
|
||||
Linking with OpenSSL
|
||||
|
||||
17. In addition, as a special exception, we give permission to link the code
|
||||
of its release of libssh with the OpenSSL project's "OpenSSL" library (or with
|
||||
modified versions of it that use the same license as the "OpenSSL" library),
|
||||
and distribute the linked executables. You must obey the GNU Lesser General
|
||||
Public License in all respects for all of the code used other than "OpenSSL".
|
||||
If you modify this file, you may extend this exception to your version of the
|
||||
file, but you are not obligated to do so. If you do not wish to do so, delete
|
||||
this exception statement from your version.
|
||||
|
||||
END OF TERMS AND CONDITIONS
|
||||
|
||||
@@ -10,7 +10,7 @@ set(CPACK_PACKAGE_VERSION ${PROJECT_VERSION})
|
||||
|
||||
# SOURCE GENERATOR
|
||||
set(CPACK_SOURCE_GENERATOR "TXZ")
|
||||
set(CPACK_SOURCE_IGNORE_FILES "~$;[.]swp$;/[.]git/;.gitignore;/build*;/obj*;tags;cscope.*")
|
||||
set(CPACK_SOURCE_IGNORE_FILES "~$;[.]swp$;/[.]git/;/[.]clangd/;.gitignore;/build*;/obj*;tags;cscope.*;compile_commands.json;.*\.patch")
|
||||
set(CPACK_SOURCE_PACKAGE_FILE_NAME "${CPACK_PACKAGE_NAME}-${CPACK_PACKAGE_VERSION}")
|
||||
|
||||
### NSIS INSTALLER
|
||||
|
||||
35
ChangeLog
35
ChangeLog
@@ -1,6 +1,41 @@
|
||||
ChangeLog
|
||||
==========
|
||||
|
||||
version 0.8.9 (released 2020-04-09)
|
||||
* Fixed CVE-2020-1730 - Possible DoS in client and server when handling
|
||||
AES-CTR keys with OpenSSL
|
||||
|
||||
version 0.8.8 (released 2019-12-10)
|
||||
* Fixed CVE-2019-14889 - SCP: Unsanitized location leads to command execution
|
||||
|
||||
version 0.8.7 (released 2019-02-25)
|
||||
* Fixed handling extension flags in the server implementation
|
||||
* Fixed exporting ed25519 private keys
|
||||
* Fixed corner cases for rsa-sha2 signatures
|
||||
* Fixed some issues with connector
|
||||
|
||||
version 0.8.6 (released 2018-12-24)
|
||||
* Fixed compilation issues with different OpenSSL versions
|
||||
* Fixed StrictHostKeyChecking in new knownhosts API
|
||||
* Fixed ssh_send_keepalive() with packet filter
|
||||
* Fixed possible crash with knownhosts options
|
||||
* Fixed issus with rekeying
|
||||
* Fixed strong ECDSA keys
|
||||
* Fixed some issues with rsa-sha2 extentions
|
||||
* Fixed access violation in ssh_init() (static linking)
|
||||
* Fixed ssh_channel_close() handling
|
||||
|
||||
version 0.8.5 (released 2018-10-29)
|
||||
* Added support to get known_hosts locations with ssh_options_get()
|
||||
* Fixed preferred algorithm for known hosts negotiations
|
||||
* Fixed KEX with some server implementations (e.g. Cisco)
|
||||
* Fixed issues with MSVC
|
||||
* Fixed keyboard-interactive auth in server mode
|
||||
(regression from CVE-2018-10933)
|
||||
* Fixed gssapi auth in server mode (regression from CVE-2018-10933)
|
||||
* Fixed socket fd handling with proxy command
|
||||
* Fixed a memory leak with OpenSSL
|
||||
|
||||
version 0.8.4 (released 2018-10-16)
|
||||
* Fixed CVE-2018-10933
|
||||
* Fixed building without globbing support
|
||||
|
||||
@@ -127,7 +127,7 @@ The keyboard-interactive method is, as its name tells, interactive. The
|
||||
server will issue one or more challenges that the user has to answer,
|
||||
until the server takes an authentication decision.
|
||||
|
||||
ssh_userauth_kbdint() is the the main keyboard-interactive function.
|
||||
ssh_userauth_kbdint() is the the main keyboard-interactive function.
|
||||
It will return SSH_AUTH_SUCCESS,SSH_AUTH_DENIED, SSH_AUTH_PARTIAL,
|
||||
SSH_AUTH_ERROR, or SSH_AUTH_INFO, depending on the result of the request.
|
||||
|
||||
@@ -154,9 +154,9 @@ Here are a few remarks:
|
||||
- Even the first call can return SSH_AUTH_DENIED or SSH_AUTH_SUCCESS.
|
||||
- The server can send an empty question set (this is the default behavior
|
||||
on my system) after you have sent the answers to the first questions.
|
||||
You must still parse the answer, it might contain some
|
||||
You must still parse the answer, it might contain some
|
||||
message from the server saying hello or such things. Just call
|
||||
ssh_userauth_kbdint() until needed.
|
||||
ssh_userauth_kbdint() until needed.
|
||||
- The meaning of "name", "prompt", "instruction" may be a little
|
||||
confusing. An explanation is given in the RFC section that follows.
|
||||
|
||||
@@ -187,7 +187,7 @@ keyboard-interactive authentication, coming from the RFC itself (rfc4256):
|
||||
the name and prompts. If the server presents names or prompts longer than 30
|
||||
characters, the client MAY truncate these fields to the length it can
|
||||
display. If the client does truncate any fields, there MUST be an obvious
|
||||
indication that such truncation has occured.
|
||||
indication that such truncation has occurred.
|
||||
|
||||
The instruction field SHOULD NOT be truncated. Clients SHOULD use control
|
||||
character filtering as discussed in [SSH-ARCH] to avoid attacks by
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
|
||||
Port forwarding comes in SSH protocol in two different flavours:
|
||||
direct or reverse port forwarding. Direct port forwarding is also
|
||||
named local port forwardind, and reverse port forwarding is also called
|
||||
named local port forwarding, and reverse port forwarding is also called
|
||||
remote port forwarding. SSH also allows X11 tunnels.
|
||||
|
||||
|
||||
@@ -23,15 +23,15 @@ Mail client application Google Mail
|
||||
5555 (arbitrary) |
|
||||
| 143 (IMAP2)
|
||||
V |
|
||||
SSH client =====> SSH server
|
||||
SSH client =====> SSH server
|
||||
|
||||
Legend:
|
||||
--P-->: port connexion through port P
|
||||
--P-->: port connections through port P
|
||||
=====>: SSH tunnel
|
||||
@endverbatim
|
||||
A mail client connects to port 5555 of a client. An encrypted tunnel is
|
||||
established to the server. The server connects to port 143 of Google Mail (the
|
||||
end point). Now the local mail client can retreive mail.
|
||||
end point). Now the local mail client can retrieve mail.
|
||||
|
||||
|
||||
@subsection forwarding_reverse Reverse port forwarding
|
||||
@@ -51,7 +51,7 @@ Example of use of reverse port forwarding:
|
||||
SSH client <===== SSH server
|
||||
|
||||
Legend:
|
||||
--P-->: port connexion through port P
|
||||
--P-->: port connections through port P
|
||||
=====>: SSH tunnel
|
||||
@endverbatim
|
||||
In this example, the SSH client establishes the tunnel,
|
||||
@@ -148,9 +148,9 @@ To do reverse port forwarding, call ssh_channel_listen_forward(),
|
||||
then ssh_channel_accept_forward().
|
||||
|
||||
When you call ssh_channel_listen_forward(), you can let the remote server
|
||||
chose the non-priviledged port it should listen to. Otherwise, you can chose
|
||||
your own priviledged or non-priviledged port. Beware that you should have
|
||||
administrative priviledges on the remote server to open a priviledged port
|
||||
chose the non-privileged port it should listen to. Otherwise, you can chose
|
||||
your own privileged or non-privileged port. Beware that you should have
|
||||
administrative privileges on the remote server to open a privileged port
|
||||
(port number < 1024).
|
||||
|
||||
Below is an example of a very rough web server waiting for connections on port
|
||||
|
||||
@@ -31,20 +31,20 @@ A SSH session goes through the following steps:
|
||||
- Invoke your own subsystem. This is outside the scope of this document,
|
||||
but can be done.
|
||||
|
||||
- When everything is finished, just close the channels, and then the connection.
|
||||
- When everything is finished, just close the channels, and then the connection.
|
||||
|
||||
The sftp and scp subsystems use channels, but libssh hides them to
|
||||
the programmer. If you want to use those subsystems, instead of a channel,
|
||||
you'll usually open a "sftp session" or a "scp session".
|
||||
|
||||
|
||||
|
||||
@subsection setup Creating the session and setting options
|
||||
|
||||
The most important object in a SSH connection is the SSH session. In order
|
||||
to allocate a new SSH session, you use ssh_new(). Don't forget to
|
||||
always verify that the allocation successed.
|
||||
always verify that the allocation succeeded.
|
||||
@code
|
||||
#include <libssh/libssh.h>
|
||||
#include <libssh/libssh.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
int main()
|
||||
@@ -69,12 +69,12 @@ The ssh_options_set() function sets the options of the session. The most importa
|
||||
|
||||
The complete list of options can be found in the documentation of ssh_options_set().
|
||||
The only mandatory option is SSH_OPTIONS_HOST. If you don't use SSH_OPTIONS_USER,
|
||||
the local username of your account will be used.
|
||||
the local username of your account will be used.
|
||||
|
||||
Here is a small example of how to use it:
|
||||
|
||||
@code
|
||||
#include <libssh/libssh.h>
|
||||
#include <libssh/libssh.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
int main()
|
||||
@@ -122,7 +122,7 @@ Here's an example:
|
||||
@code
|
||||
#include <libssh/libssh.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <stdio.h>
|
||||
|
||||
int main()
|
||||
{
|
||||
@@ -285,9 +285,9 @@ int verify_knownhost(ssh_session session)
|
||||
|
||||
The authentication process is the way a service provider can identify a
|
||||
user and verify his/her identity. The authorization process is about enabling
|
||||
the authenticated user the access to ressources. In SSH, the two concepts
|
||||
the authenticated user the access to resources. In SSH, the two concepts
|
||||
are linked. After authentication, the server can grant the user access to
|
||||
several ressources such as port forwarding, shell, sftp subsystem, and so on.
|
||||
several resources such as port forwarding, shell, sftp subsystem, and so on.
|
||||
|
||||
libssh supports several methods of authentication:
|
||||
- "none" method. This method allows to get the available authentications
|
||||
@@ -313,7 +313,7 @@ The example below shows an authentication with password:
|
||||
@code
|
||||
#include <libssh/libssh.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <stdio.h>
|
||||
|
||||
int main()
|
||||
{
|
||||
@@ -338,7 +338,7 @@ int main()
|
||||
}
|
||||
|
||||
// Verify the server's identity
|
||||
// For the source code of verify_knowhost(), check previous example
|
||||
// For the source code of verify_knownhost(), check previous example
|
||||
if (verify_knownhost(my_ssh_session) < 0)
|
||||
{
|
||||
ssh_disconnect(my_ssh_session);
|
||||
@@ -415,7 +415,7 @@ int show_remote_processes(ssh_session session)
|
||||
}
|
||||
nbytes = ssh_channel_read(channel, buffer, sizeof(buffer), 0);
|
||||
}
|
||||
|
||||
|
||||
if (nbytes < 0)
|
||||
{
|
||||
ssh_channel_close(channel);
|
||||
@@ -456,7 +456,7 @@ might be recoverable. SSH_FATAL means the connection has an important
|
||||
problem and isn't probably recoverable.
|
||||
|
||||
Most of time, the error returned are SSH_FATAL, but some functions
|
||||
(generaly the ssh_request_xxx ones) may fail because of server denying request.
|
||||
(generally the ssh_request_xxx ones) may fail because of server denying request.
|
||||
In these cases, SSH_REQUEST_DENIED is returned.
|
||||
|
||||
For thread safety, errors are bound to ssh_session objects.
|
||||
|
||||
@@ -12,13 +12,13 @@ mean that you should not try to know about and understand these details.
|
||||
|
||||
libssh is a Free Software / Open Source project. The libssh library
|
||||
is distributed under LGPL license. The libssh project has nothing to do with
|
||||
"libssh2", which is a completly different and independant project.
|
||||
"libssh2", which is a completely different and independent project.
|
||||
|
||||
libssh can run on top of either libgcrypt or libcrypto,
|
||||
two general-purpose cryptographic libraries.
|
||||
|
||||
This tutorial concentrates for its main part on the "client" side of libssh.
|
||||
To learn how to accept incoming SSH connexions (how to write a SSH server),
|
||||
To learn how to accept incoming SSH connections (how to write a SSH server),
|
||||
you'll have to jump to the end of this document.
|
||||
|
||||
This tutorial describes libssh version 0.5.0. This version is a little different
|
||||
|
||||
@@ -27,4 +27,7 @@ the dllimport attribute.
|
||||
#include <libssh/libssh.h>
|
||||
@endcode
|
||||
|
||||
If you're are statically linking with OpenSSL, read the "Linking your
|
||||
application" section in the NOTES.<OS> in the OpenSSL source tree!
|
||||
|
||||
*/
|
||||
|
||||
@@ -23,7 +23,7 @@ The libssh library provides:
|
||||
- <strong>Public Key Algorithms</strong>: ssh-ed25519, ecdsa-sha2-nistp256, ecdsa-sha2-nistp384, ecdsa-sha2-nistp521, ssh-rsa, rsa-sha2-512, rsa-sha2-256,ssh-dss
|
||||
- <strong>Ciphers</strong>: <i>aes256-ctr, aes192-ctr, aes128-ctr</i>, aes256-cbc (rijndael-cbc@lysator.liu.se), aes192-cbc, aes128-cbc, 3des-cbc, blowfish-cbc, none
|
||||
- <strong>Compression Schemes</strong>: zlib, <i>zlib@openssh.com</i>, none
|
||||
- <strong>MAC hashes</strong>: hmac-sha1, hmac-sha2-256, hmac-sha2-384, hmac-sha2-512, hmac-md5, none
|
||||
- <strong>MAC hashes</strong>: hmac-sha1, hmac-sha2-256, hmac-sha2-512, hmac-md5, none
|
||||
- <strong>Authentication</strong>: none, password, public-key, keyboard-interactive, <i>gssapi-with-mic</i>
|
||||
- <strong>Channels</strong>: shell, exec (incl. SCP wrapper), direct-tcpip, subsystem, <i>auth-agent-req@openssh.com</i>
|
||||
- <strong>Global Requests</strong>: tcpip-forward, forwarded-tcpip
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
@page libssh_tutor_scp Chapter 6: The SCP subsystem
|
||||
@section scp_subsystem The SCP subsystem
|
||||
|
||||
The SCP subsystem has far less functionnality than the SFTP subsystem.
|
||||
The SCP subsystem has far less functionality than the SFTP subsystem.
|
||||
However, if you only need to copy files from and to the remote system,
|
||||
it does its job.
|
||||
|
||||
@@ -158,7 +158,7 @@ Let's say you want to copy the following tree of files to the remote site:
|
||||
+-- file1
|
||||
+-- B --+
|
||||
| +-- file2
|
||||
-- A --+
|
||||
-- A --+
|
||||
| +-- file3
|
||||
+-- C --+
|
||||
+-- file4
|
||||
@@ -210,7 +210,7 @@ int scp_receive(ssh_session session, ssh_scp scp)
|
||||
size = ssh_scp_request_get_size(scp);
|
||||
filename = strdup(ssh_scp_request_get_filename(scp));
|
||||
mode = ssh_scp_request_get_permissions(scp);
|
||||
printf("Receiving file %s, size %d, permisssions 0%o\n",
|
||||
printf("Receiving file %s, size %d, permissions 0%o\n",
|
||||
filename, size, mode);
|
||||
free(filename);
|
||||
|
||||
|
||||
@@ -100,7 +100,7 @@ Possible errors are:
|
||||
|
||||
@subsection sftp_mkdir Creating a directory
|
||||
|
||||
The function sftp_mkdir() tahes the "SFTP session" we juste created as
|
||||
The function sftp_mkdir() takes the "SFTP session" we just created as
|
||||
its first argument. It also needs the name of the file to create, and the
|
||||
desired permissions. The permissions are the same as for the usual mkdir()
|
||||
function. To get a comprehensive list of the available permissions, use the
|
||||
@@ -358,19 +358,19 @@ int sftp_read_async(ssh_session session, sftp_session sftp)
|
||||
@subsection sftp_ls Listing the contents of a directory
|
||||
|
||||
The functions sftp_opendir(), sftp_readdir(), sftp_dir_eof(),
|
||||
and sftp_closedir() enable to list the contents of a directory.
|
||||
and sftp_closedir() enable to list the contents of a directory.
|
||||
They use a new handle_type, "sftp_dir", which gives access to the
|
||||
directory being read.
|
||||
|
||||
In addition, sftp_readdir() returns a "sftp_attributes" which is a pointer
|
||||
to a structure with informations about a directory entry:
|
||||
to a structure with information about a directory entry:
|
||||
- name: the name of the file or directory
|
||||
- size: its size in bytes
|
||||
- etc.
|
||||
|
||||
sftp_readdir() might return NULL under two conditions:
|
||||
- when the end of the directory has been met
|
||||
- when an error occured
|
||||
- when an error occurred
|
||||
|
||||
To tell the difference, call sftp_dir_eof().
|
||||
|
||||
|
||||
@@ -209,7 +209,7 @@ int interactive_shell_session(ssh_channel channel)
|
||||
|
||||
Of course, this is a poor terminal emulator, since the echo from the keys
|
||||
pressed should not be done locally, but should be done by the remote side.
|
||||
Also, user's input should not be sent once "Enter" key is pressed, but
|
||||
Also, user's input should not be sent once "Enter" key is pressed, but
|
||||
immediately after each key is pressed. This can be accomplished
|
||||
by setting the local terminal to "raw" mode with the cfmakeraw(3) function.
|
||||
cfmakeraw() is a standard function under Linux, on other systems you can
|
||||
@@ -245,13 +245,13 @@ provide a more elegant way to wait for data coming from many sources.
|
||||
|
||||
The functions ssh_select() and ssh_channel_select() remind of the standard
|
||||
UNIX select(2) function. The idea is to wait for "something" to happen:
|
||||
incoming data to be read, outcoming data to block, or an exception to
|
||||
incoming data to be read, outgoing data to block, or an exception to
|
||||
occur. Both these functions do a "passive wait", i.e. you can safely use
|
||||
them repeatedly in a loop, it will not consume exaggerate processor time
|
||||
and make your computer unresponsive. It is quite common to use these
|
||||
functions in your application's main loop.
|
||||
|
||||
The difference between ssh_select() and ssh_channel_select() is that
|
||||
The difference between ssh_select() and ssh_channel_select() is that
|
||||
ssh_channel_select() is simpler, but allows you only to watch SSH channels.
|
||||
ssh_select() is more complete and enables watching regular file descriptors
|
||||
as well, in the same function call.
|
||||
|
||||
@@ -11,10 +11,10 @@ libssh may be used in multithreaded applications, but under several conditions :
|
||||
- If libssh is statically linked, threading must be initialized by calling
|
||||
ssh_init() before using any of libssh provided functions. This initialization
|
||||
must be done outside of any threading context. Don't forget to call
|
||||
ssh_finalize() to avoid memory leak
|
||||
ssh_finalize() to avoid memory leak
|
||||
- At all times, you may use different sessions inside threads, make parallel
|
||||
connections, read/write on different sessions and so on. You *cannot* use a
|
||||
single session (or channels for a single session) in several threads at the same
|
||||
single session (or channels for a single session) in several threads at the same
|
||||
time. This will most likely lead to internal state corruption. This limitation is
|
||||
being worked out and will maybe disappear later.
|
||||
|
||||
|
||||
@@ -23,6 +23,7 @@ clients must be made or how a client should react.
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
#include <stdbool.h>
|
||||
|
||||
#define SSHD_USER "libssh"
|
||||
#define SSHD_PASSWORD "libssh"
|
||||
@@ -36,6 +37,7 @@ clients must be made or how a client should react.
|
||||
#endif
|
||||
|
||||
static int port = 22;
|
||||
static bool authenticated = false;
|
||||
|
||||
#ifdef WITH_PCAP
|
||||
static const char *pcap_file = "debug.server.pcap";
|
||||
@@ -61,11 +63,20 @@ static void cleanup_pcap(void) {
|
||||
#endif
|
||||
|
||||
|
||||
static int auth_password(const char *user, const char *password){
|
||||
if(strcmp(user, SSHD_USER))
|
||||
static int auth_password(const char *user, const char *password)
|
||||
{
|
||||
int cmp;
|
||||
|
||||
cmp = strcmp(user, SSHD_USER);
|
||||
if (cmp != 0) {
|
||||
return 0;
|
||||
if(strcmp(password, SSHD_PASSWORD))
|
||||
}
|
||||
cmp = strcmp(password, SSHD_PASSWORD);
|
||||
if (cmp != 0) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
authenticated = true;
|
||||
return 1; // authenticated
|
||||
}
|
||||
#ifdef HAVE_ARGP_H
|
||||
@@ -200,6 +211,7 @@ static int kbdint_check_response(ssh_session session) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
authenticated = true;
|
||||
return 1;
|
||||
}
|
||||
|
||||
@@ -328,7 +340,7 @@ int main(int argc, char **argv){
|
||||
|
||||
/* proceed to authentication */
|
||||
auth = authenticate(session);
|
||||
if(!auth){
|
||||
if (!auth || !authenticated) {
|
||||
printf("Authentication error: %s\n", ssh_get_error(session));
|
||||
ssh_disconnect(session);
|
||||
return 1;
|
||||
|
||||
@@ -48,11 +48,16 @@ enum ssh_channel_state_e {
|
||||
};
|
||||
|
||||
/* The channel has been closed by the remote side */
|
||||
#define SSH_CHANNEL_FLAG_CLOSED_REMOTE 0x1
|
||||
#define SSH_CHANNEL_FLAG_CLOSED_REMOTE 0x0001
|
||||
|
||||
/* The channel has been closed locally */
|
||||
#define SSH_CHANNEL_FLAG_CLOSED_LOCAL 0x0002
|
||||
|
||||
/* The channel has been freed by the calling program */
|
||||
#define SSH_CHANNEL_FLAG_FREED_LOCAL 0x2
|
||||
#define SSH_CHANNEL_FLAG_FREED_LOCAL 0x0004
|
||||
|
||||
/* the channel has not yet been bound to a remote one */
|
||||
#define SSH_CHANNEL_FLAG_NOT_BOUND 0x4
|
||||
#define SSH_CHANNEL_FLAG_NOT_BOUND 0x0008
|
||||
|
||||
struct ssh_channel_struct {
|
||||
ssh_session session; /* SSH_SESSION pointer */
|
||||
@@ -98,5 +103,9 @@ int ssh_channel_flush(ssh_channel channel);
|
||||
uint32_t ssh_channel_new_id(ssh_session session);
|
||||
ssh_channel ssh_channel_from_local(ssh_session session, uint32_t id);
|
||||
void ssh_channel_do_free(ssh_channel channel);
|
||||
int ssh_global_request(ssh_session session,
|
||||
const char *request,
|
||||
ssh_buffer buffer,
|
||||
int reply);
|
||||
|
||||
#endif /* CHANNELS_H_ */
|
||||
|
||||
@@ -45,5 +45,6 @@ char *ssh_find_matching(const char *in_d, const char *what_d);
|
||||
const char *ssh_kex_get_supported_method(uint32_t algo);
|
||||
const char *ssh_kex_get_default_methods(uint32_t algo);
|
||||
const char *ssh_kex_get_description(uint32_t algo);
|
||||
char *ssh_client_select_hostkeys(ssh_session session);
|
||||
|
||||
#endif /* KEX_H_ */
|
||||
|
||||
@@ -23,5 +23,9 @@
|
||||
#define SSH_KNOWNHOSTS_H_
|
||||
|
||||
struct ssh_list *ssh_known_hosts_get_algorithms(ssh_session session);
|
||||
enum ssh_known_hosts_e
|
||||
ssh_session_get_known_hosts_entry_file(ssh_session session,
|
||||
const char *filename,
|
||||
struct ssh_knownhosts_entry **pentry);
|
||||
|
||||
#endif /* SSH_KNOWNHOSTS_H_ */
|
||||
|
||||
@@ -79,7 +79,7 @@
|
||||
/* libssh version */
|
||||
#define LIBSSH_VERSION_MAJOR 0
|
||||
#define LIBSSH_VERSION_MINOR 8
|
||||
#define LIBSSH_VERSION_MICRO 4
|
||||
#define LIBSSH_VERSION_MICRO 8
|
||||
|
||||
#define LIBSSH_VERSION_INT SSH_VERSION_INT(LIBSSH_VERSION_MAJOR, \
|
||||
LIBSSH_VERSION_MINOR, \
|
||||
|
||||
@@ -50,6 +50,12 @@ struct ssh_timestamp {
|
||||
long useconds;
|
||||
};
|
||||
|
||||
enum ssh_quote_state_e {
|
||||
NO_QUOTE,
|
||||
SINGLE_QUOTE,
|
||||
DOUBLE_QUOTE
|
||||
};
|
||||
|
||||
struct ssh_list *ssh_list_new(void);
|
||||
void ssh_list_free(struct ssh_list *list);
|
||||
struct ssh_iterator *ssh_list_get_iterator(const struct ssh_list *list);
|
||||
@@ -81,4 +87,6 @@ int ssh_timeout_update(struct ssh_timestamp *ts, int timeout);
|
||||
|
||||
int ssh_match_group(const char *group, const char *object);
|
||||
|
||||
int ssh_quote_file_name(const char *file_name, char *buf, size_t buf_len);
|
||||
|
||||
#endif /* MISC_H_ */
|
||||
|
||||
@@ -110,11 +110,11 @@ int ssh_pki_export_signature_blob(const ssh_signature sign,
|
||||
int ssh_pki_import_signature_blob(const ssh_string sig_blob,
|
||||
const ssh_key pubkey,
|
||||
ssh_signature *psig);
|
||||
int ssh_pki_signature_verify_blob(ssh_session session,
|
||||
ssh_string sig_blob,
|
||||
const ssh_key key,
|
||||
unsigned char *digest,
|
||||
size_t dlen);
|
||||
int ssh_pki_signature_verify(ssh_session session,
|
||||
ssh_signature sig,
|
||||
const ssh_key key,
|
||||
unsigned char *digest,
|
||||
size_t dlen);
|
||||
|
||||
/* SSH Public Key Functions */
|
||||
int ssh_pki_export_pubkey_blob(const ssh_key key,
|
||||
|
||||
@@ -29,6 +29,7 @@
|
||||
#ifndef _LIBSSH_PRIV_H
|
||||
#define _LIBSSH_PRIV_H
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
@@ -128,6 +129,13 @@ char *strndup(const char *s, size_t n);
|
||||
# endif /* HAVE__VSNPRINTF */
|
||||
# endif /* HAVE__VSNPRINTF_S */
|
||||
|
||||
# ifndef _SSIZE_T_DEFINED
|
||||
# undef ssize_t
|
||||
# include <BaseTsd.h>
|
||||
typedef _W64 SSIZE_T ssize_t;
|
||||
# define _SSIZE_T_DEFINED
|
||||
# endif /* _SSIZE_T_DEFINED */
|
||||
|
||||
# endif /* _MSC_VER */
|
||||
|
||||
struct timeval;
|
||||
|
||||
@@ -87,10 +87,11 @@ enum ssh_pending_call_e {
|
||||
#define SSH_OPT_FLAG_GSSAPI_AUTH 0x8
|
||||
|
||||
/* extensions flags */
|
||||
/* negotiation enabled */
|
||||
#define SSH_EXT_NEGOTIATION 0x01
|
||||
/* server-sig-algs extension */
|
||||
#define SSH_EXT_SIG_RSA_SHA256 0x01
|
||||
#define SSH_EXT_SIG_RSA_SHA512 0x02
|
||||
#define SSH_EXT_ALL SSH_EXT_SIG_RSA_SHA256 | SSH_EXT_SIG_RSA_SHA512
|
||||
#define SSH_EXT_SIG_RSA_SHA256 0x02
|
||||
#define SSH_EXT_SIG_RSA_SHA512 0x04
|
||||
|
||||
/* members that are common to ssh_session and ssh_bind */
|
||||
struct ssh_common_struct {
|
||||
@@ -164,8 +165,6 @@ struct ssh_session_struct {
|
||||
|
||||
struct ssh_list *channels; /* linked list of channels */
|
||||
int maxchannel;
|
||||
int exec_channel_opened; /* version 1 only. more
|
||||
info in channels1.c */
|
||||
ssh_agent agent; /* ssh agent */
|
||||
|
||||
/* keyb interactive data */
|
||||
|
||||
@@ -53,9 +53,14 @@ extern "C" {
|
||||
typedef uint32_t gid_t;
|
||||
#endif /* gid_t */
|
||||
#ifdef _MSC_VER
|
||||
#ifndef ssize_t
|
||||
typedef _W64 SSIZE_T ssize_t;
|
||||
#endif /* ssize_t */
|
||||
|
||||
# ifndef _SSIZE_T_DEFINED
|
||||
# undef ssize_t
|
||||
# include <BaseTsd.h>
|
||||
typedef _W64 SSIZE_T ssize_t;
|
||||
# define _SSIZE_T_DEFINED
|
||||
# endif /* _SSIZE_T_DEFINED */
|
||||
|
||||
#endif /* _MSC_VER */
|
||||
#endif /* _WIN32 */
|
||||
|
||||
@@ -813,7 +818,9 @@ LIBSSH_API int sftp_fsync(sftp_file file);
|
||||
*
|
||||
* @param path The path to be canonicalized.
|
||||
*
|
||||
* @return The canonicalize path, NULL on error.
|
||||
* @return A pointer to the newly allocated canonicalized path,
|
||||
* NULL on error. The caller needs to free the memory
|
||||
* using ssh_string_free_char().
|
||||
*/
|
||||
LIBSSH_API char *sftp_canonicalize_path(sftp_session sftp, const char *path);
|
||||
|
||||
|
||||
@@ -34,7 +34,7 @@ ssh_socket ssh_socket_new(ssh_session session);
|
||||
void ssh_socket_reset(ssh_socket s);
|
||||
void ssh_socket_free(ssh_socket s);
|
||||
void ssh_socket_set_fd(ssh_socket s, socket_t fd);
|
||||
socket_t ssh_socket_get_fd_in(ssh_socket s);
|
||||
socket_t ssh_socket_get_fd(ssh_socket s);
|
||||
#ifndef _WIN32
|
||||
int ssh_socket_unix(ssh_socket s, const char *path);
|
||||
void ssh_execute_command(const char *command, socket_t in, socket_t out);
|
||||
@@ -61,8 +61,7 @@ int ssh_socket_set_blocking(socket_t fd);
|
||||
|
||||
void ssh_socket_set_callbacks(ssh_socket s, ssh_socket_callbacks callbacks);
|
||||
int ssh_socket_pollcallback(struct ssh_poll_handle_struct *p, socket_t fd, int revents, void *v_s);
|
||||
struct ssh_poll_handle_struct * ssh_socket_get_poll_handle_in(ssh_socket s);
|
||||
struct ssh_poll_handle_struct * ssh_socket_get_poll_handle_out(ssh_socket s);
|
||||
struct ssh_poll_handle_struct * ssh_socket_get_poll_handle(ssh_socket s);
|
||||
|
||||
int ssh_socket_connect(ssh_socket s, const char *host, int port, const char *bind_addr);
|
||||
|
||||
|
||||
@@ -44,7 +44,6 @@ enum ssh_mac_e {
|
||||
enum ssh_hmac_e {
|
||||
SSH_HMAC_SHA1 = 1,
|
||||
SSH_HMAC_SHA256,
|
||||
SSH_HMAC_SHA384,
|
||||
SSH_HMAC_SHA512,
|
||||
SSH_HMAC_MD5,
|
||||
SSH_HMAC_AEAD_POLY1305
|
||||
|
||||
@@ -1 +0,0 @@
|
||||
set(LIBSSH_INLUDE_DIR @PROJECT_SOURCE_DIR@/include)
|
||||
@@ -1,11 +0,0 @@
|
||||
set(PACKAGE_VERSION @PROJECT_VERSION@)
|
||||
|
||||
# Check whether the requested PACKAGE_FIND_VERSION is compatible
|
||||
if("${PACKAGE_VERSION}" VERSION_LESS "${PACKAGE_FIND_VERSION}")
|
||||
set(PACKAGE_VERSION_COMPATIBLE FALSE)
|
||||
else()
|
||||
set(PACKAGE_VERSION_COMPATIBLE TRUE)
|
||||
if ("${PACKAGE_VERSION}" VERSION_EQUAL "${PACKAGE_FIND_VERSION}")
|
||||
set(PACKAGE_VERSION_EXACT TRUE)
|
||||
endif()
|
||||
endif()
|
||||
@@ -1,15 +1,15 @@
|
||||
get_filename_component(LIBSSH_CMAKE_DIR "${CMAKE_CURRENT_LIST_FILE}" PATH)
|
||||
@PACKAGE_INIT@
|
||||
|
||||
if (EXISTS "${LIBSSH_CMAKE_DIR}/CMakeCache.txt")
|
||||
# In build tree
|
||||
include(${LIBSSH_CMAKE_DIR}/libssh-build-tree-settings.cmake)
|
||||
if (EXISTS "${CMAKE_CURRENT_LIST_DIR}/CMakeCache.txt")
|
||||
# In tree build
|
||||
set_and_check(LIBSSH_INCLUDE_DIR "${CMAKE_CURRENT_LIST_DIR}/include")
|
||||
set_and_check(LIBSSH_LIBRARIES "${CMAKE_CURRENT_LIST_DIR}/lib/@LIBSSH_LIBRARY_NAME@")
|
||||
else()
|
||||
set(LIBSSH_INCLUDE_DIR @INCLUDE_INSTALL_DIR@)
|
||||
set_and_check(LIBSSH_INCLUDE_DIR "@PACKAGE_INCLUDE_INSTALL_DIR@")
|
||||
set_and_check(LIBSSH_LIBRARIES "@PACKAGE_LIB_INSTALL_DIR@/@LIBSSH_LIBRARY_NAME@")
|
||||
endif()
|
||||
|
||||
set(LIBSSH_LIBRARY @LIB_INSTALL_DIR@/@LIBSSH_LIBRARY_NAME@)
|
||||
set(LIBSSH_LIBRARIES @LIB_INSTALL_DIR@/@LIBSSH_LIBRARY_NAME@)
|
||||
# For backward compatibility
|
||||
set(LIBSSH_LIBRARY ${LIBSSH_LIBRARIES})
|
||||
|
||||
set(LIBSSH_THREADS_LIBRARY @LIB_INSTALL_DIR@/@LIBSSH_THREADS_LIBRARY_NAME@)
|
||||
|
||||
mark_as_advanced(LIBSSH_LIBRARIES LIBSSH_INCLUDE_DIR)
|
||||
mark_as_advanced(LIBSSH_LIBRARIES LIBSSH_LIBRARY LIBSSH_INCLUDE_DIR)
|
||||
|
||||
@@ -1 +1 @@
|
||||
4.7.1
|
||||
4.7.6
|
||||
415
src/ABI/libssh-4.7.2.symbols
Normal file
415
src/ABI/libssh-4.7.2.symbols
Normal file
@@ -0,0 +1,415 @@
|
||||
_ssh_log
|
||||
buffer_free
|
||||
buffer_get
|
||||
buffer_get_len
|
||||
buffer_new
|
||||
channel_accept_x11
|
||||
channel_change_pty_size
|
||||
channel_close
|
||||
channel_forward_accept
|
||||
channel_forward_cancel
|
||||
channel_forward_listen
|
||||
channel_free
|
||||
channel_get_exit_status
|
||||
channel_get_session
|
||||
channel_is_closed
|
||||
channel_is_eof
|
||||
channel_is_open
|
||||
channel_new
|
||||
channel_open_forward
|
||||
channel_open_session
|
||||
channel_poll
|
||||
channel_read
|
||||
channel_read_buffer
|
||||
channel_read_nonblocking
|
||||
channel_request_env
|
||||
channel_request_exec
|
||||
channel_request_pty
|
||||
channel_request_pty_size
|
||||
channel_request_send_signal
|
||||
channel_request_sftp
|
||||
channel_request_shell
|
||||
channel_request_subsystem
|
||||
channel_request_x11
|
||||
channel_select
|
||||
channel_send_eof
|
||||
channel_set_blocking
|
||||
channel_write
|
||||
channel_write_stderr
|
||||
privatekey_free
|
||||
privatekey_from_file
|
||||
publickey_free
|
||||
publickey_from_file
|
||||
publickey_from_privatekey
|
||||
publickey_to_string
|
||||
sftp_async_read
|
||||
sftp_async_read_begin
|
||||
sftp_attributes_free
|
||||
sftp_canonicalize_path
|
||||
sftp_chmod
|
||||
sftp_chown
|
||||
sftp_client_message_free
|
||||
sftp_client_message_get_data
|
||||
sftp_client_message_get_filename
|
||||
sftp_client_message_get_flags
|
||||
sftp_client_message_get_submessage
|
||||
sftp_client_message_get_type
|
||||
sftp_client_message_set_filename
|
||||
sftp_close
|
||||
sftp_closedir
|
||||
sftp_dir_eof
|
||||
sftp_extension_supported
|
||||
sftp_extensions_get_count
|
||||
sftp_extensions_get_data
|
||||
sftp_extensions_get_name
|
||||
sftp_file_set_blocking
|
||||
sftp_file_set_nonblocking
|
||||
sftp_free
|
||||
sftp_fstat
|
||||
sftp_fstatvfs
|
||||
sftp_fsync
|
||||
sftp_get_client_message
|
||||
sftp_get_error
|
||||
sftp_handle
|
||||
sftp_handle_alloc
|
||||
sftp_handle_remove
|
||||
sftp_init
|
||||
sftp_lstat
|
||||
sftp_mkdir
|
||||
sftp_new
|
||||
sftp_new_channel
|
||||
sftp_open
|
||||
sftp_opendir
|
||||
sftp_read
|
||||
sftp_readdir
|
||||
sftp_readlink
|
||||
sftp_rename
|
||||
sftp_reply_attr
|
||||
sftp_reply_data
|
||||
sftp_reply_handle
|
||||
sftp_reply_name
|
||||
sftp_reply_names
|
||||
sftp_reply_names_add
|
||||
sftp_reply_status
|
||||
sftp_rewind
|
||||
sftp_rmdir
|
||||
sftp_seek
|
||||
sftp_seek64
|
||||
sftp_send_client_message
|
||||
sftp_server_init
|
||||
sftp_server_new
|
||||
sftp_server_version
|
||||
sftp_setstat
|
||||
sftp_stat
|
||||
sftp_statvfs
|
||||
sftp_statvfs_free
|
||||
sftp_symlink
|
||||
sftp_tell
|
||||
sftp_tell64
|
||||
sftp_unlink
|
||||
sftp_utimes
|
||||
sftp_write
|
||||
ssh_accept
|
||||
ssh_add_channel_callbacks
|
||||
ssh_auth_list
|
||||
ssh_basename
|
||||
ssh_bind_accept
|
||||
ssh_bind_accept_fd
|
||||
ssh_bind_fd_toaccept
|
||||
ssh_bind_free
|
||||
ssh_bind_get_fd
|
||||
ssh_bind_listen
|
||||
ssh_bind_new
|
||||
ssh_bind_options_set
|
||||
ssh_bind_set_blocking
|
||||
ssh_bind_set_callbacks
|
||||
ssh_bind_set_fd
|
||||
ssh_blocking_flush
|
||||
ssh_buffer_add_data
|
||||
ssh_buffer_free
|
||||
ssh_buffer_get
|
||||
ssh_buffer_get_data
|
||||
ssh_buffer_get_len
|
||||
ssh_buffer_new
|
||||
ssh_buffer_reinit
|
||||
ssh_channel_accept_forward
|
||||
ssh_channel_accept_x11
|
||||
ssh_channel_cancel_forward
|
||||
ssh_channel_change_pty_size
|
||||
ssh_channel_close
|
||||
ssh_channel_free
|
||||
ssh_channel_get_exit_status
|
||||
ssh_channel_get_session
|
||||
ssh_channel_is_closed
|
||||
ssh_channel_is_eof
|
||||
ssh_channel_is_open
|
||||
ssh_channel_listen_forward
|
||||
ssh_channel_new
|
||||
ssh_channel_open_auth_agent
|
||||
ssh_channel_open_forward
|
||||
ssh_channel_open_reverse_forward
|
||||
ssh_channel_open_session
|
||||
ssh_channel_open_x11
|
||||
ssh_channel_poll
|
||||
ssh_channel_poll_timeout
|
||||
ssh_channel_read
|
||||
ssh_channel_read_nonblocking
|
||||
ssh_channel_read_timeout
|
||||
ssh_channel_request_auth_agent
|
||||
ssh_channel_request_env
|
||||
ssh_channel_request_exec
|
||||
ssh_channel_request_pty
|
||||
ssh_channel_request_pty_size
|
||||
ssh_channel_request_send_break
|
||||
ssh_channel_request_send_exit_signal
|
||||
ssh_channel_request_send_exit_status
|
||||
ssh_channel_request_send_signal
|
||||
ssh_channel_request_sftp
|
||||
ssh_channel_request_shell
|
||||
ssh_channel_request_subsystem
|
||||
ssh_channel_request_x11
|
||||
ssh_channel_select
|
||||
ssh_channel_send_eof
|
||||
ssh_channel_set_blocking
|
||||
ssh_channel_set_counter
|
||||
ssh_channel_window_size
|
||||
ssh_channel_write
|
||||
ssh_channel_write_stderr
|
||||
ssh_clean_pubkey_hash
|
||||
ssh_connect
|
||||
ssh_connector_free
|
||||
ssh_connector_new
|
||||
ssh_connector_set_in_channel
|
||||
ssh_connector_set_in_fd
|
||||
ssh_connector_set_out_channel
|
||||
ssh_connector_set_out_fd
|
||||
ssh_copyright
|
||||
ssh_dirname
|
||||
ssh_disconnect
|
||||
ssh_dump_knownhost
|
||||
ssh_event_add_connector
|
||||
ssh_event_add_fd
|
||||
ssh_event_add_session
|
||||
ssh_event_dopoll
|
||||
ssh_event_free
|
||||
ssh_event_new
|
||||
ssh_event_remove_connector
|
||||
ssh_event_remove_fd
|
||||
ssh_event_remove_session
|
||||
ssh_execute_message_callbacks
|
||||
ssh_finalize
|
||||
ssh_forward_accept
|
||||
ssh_forward_cancel
|
||||
ssh_forward_listen
|
||||
ssh_free
|
||||
ssh_get_cipher_in
|
||||
ssh_get_cipher_out
|
||||
ssh_get_clientbanner
|
||||
ssh_get_disconnect_message
|
||||
ssh_get_error
|
||||
ssh_get_error_code
|
||||
ssh_get_fd
|
||||
ssh_get_fingerprint_hash
|
||||
ssh_get_hexa
|
||||
ssh_get_hmac_in
|
||||
ssh_get_hmac_out
|
||||
ssh_get_issue_banner
|
||||
ssh_get_kex_algo
|
||||
ssh_get_log_callback
|
||||
ssh_get_log_level
|
||||
ssh_get_log_userdata
|
||||
ssh_get_openssh_version
|
||||
ssh_get_poll_flags
|
||||
ssh_get_pubkey
|
||||
ssh_get_pubkey_hash
|
||||
ssh_get_publickey
|
||||
ssh_get_publickey_hash
|
||||
ssh_get_random
|
||||
ssh_get_server_publickey
|
||||
ssh_get_serverbanner
|
||||
ssh_get_status
|
||||
ssh_get_version
|
||||
ssh_getpass
|
||||
ssh_gssapi_get_creds
|
||||
ssh_gssapi_set_creds
|
||||
ssh_handle_key_exchange
|
||||
ssh_init
|
||||
ssh_is_blocking
|
||||
ssh_is_connected
|
||||
ssh_is_server_known
|
||||
ssh_key_cmp
|
||||
ssh_key_free
|
||||
ssh_key_is_private
|
||||
ssh_key_is_public
|
||||
ssh_key_new
|
||||
ssh_key_type
|
||||
ssh_key_type_from_name
|
||||
ssh_key_type_to_char
|
||||
ssh_known_hosts_parse_line
|
||||
ssh_knownhosts_entry_free
|
||||
ssh_log
|
||||
ssh_message_auth_interactive_request
|
||||
ssh_message_auth_kbdint_is_response
|
||||
ssh_message_auth_password
|
||||
ssh_message_auth_pubkey
|
||||
ssh_message_auth_publickey
|
||||
ssh_message_auth_publickey_state
|
||||
ssh_message_auth_reply_pk_ok
|
||||
ssh_message_auth_reply_pk_ok_simple
|
||||
ssh_message_auth_reply_success
|
||||
ssh_message_auth_set_methods
|
||||
ssh_message_auth_user
|
||||
ssh_message_channel_request_channel
|
||||
ssh_message_channel_request_command
|
||||
ssh_message_channel_request_env_name
|
||||
ssh_message_channel_request_env_value
|
||||
ssh_message_channel_request_open_destination
|
||||
ssh_message_channel_request_open_destination_port
|
||||
ssh_message_channel_request_open_originator
|
||||
ssh_message_channel_request_open_originator_port
|
||||
ssh_message_channel_request_open_reply_accept
|
||||
ssh_message_channel_request_pty_height
|
||||
ssh_message_channel_request_pty_pxheight
|
||||
ssh_message_channel_request_pty_pxwidth
|
||||
ssh_message_channel_request_pty_term
|
||||
ssh_message_channel_request_pty_width
|
||||
ssh_message_channel_request_reply_success
|
||||
ssh_message_channel_request_subsystem
|
||||
ssh_message_channel_request_x11_auth_cookie
|
||||
ssh_message_channel_request_x11_auth_protocol
|
||||
ssh_message_channel_request_x11_screen_number
|
||||
ssh_message_channel_request_x11_single_connection
|
||||
ssh_message_free
|
||||
ssh_message_get
|
||||
ssh_message_global_request_address
|
||||
ssh_message_global_request_port
|
||||
ssh_message_global_request_reply_success
|
||||
ssh_message_reply_default
|
||||
ssh_message_retrieve
|
||||
ssh_message_service_reply_success
|
||||
ssh_message_service_service
|
||||
ssh_message_subtype
|
||||
ssh_message_type
|
||||
ssh_mkdir
|
||||
ssh_new
|
||||
ssh_options_copy
|
||||
ssh_options_get
|
||||
ssh_options_get_port
|
||||
ssh_options_getopt
|
||||
ssh_options_parse_config
|
||||
ssh_options_set
|
||||
ssh_pcap_file_close
|
||||
ssh_pcap_file_free
|
||||
ssh_pcap_file_new
|
||||
ssh_pcap_file_open
|
||||
ssh_pki_copy_cert_to_privkey
|
||||
ssh_pki_export_privkey_base64
|
||||
ssh_pki_export_privkey_file
|
||||
ssh_pki_export_privkey_to_pubkey
|
||||
ssh_pki_export_pubkey_base64
|
||||
ssh_pki_export_pubkey_file
|
||||
ssh_pki_generate
|
||||
ssh_pki_import_cert_base64
|
||||
ssh_pki_import_cert_file
|
||||
ssh_pki_import_privkey_base64
|
||||
ssh_pki_import_privkey_file
|
||||
ssh_pki_import_pubkey_base64
|
||||
ssh_pki_import_pubkey_file
|
||||
ssh_pki_key_ecdsa_name
|
||||
ssh_print_hash
|
||||
ssh_print_hexa
|
||||
ssh_privatekey_type
|
||||
ssh_publickey_to_file
|
||||
ssh_remove_channel_callbacks
|
||||
ssh_scp_accept_request
|
||||
ssh_scp_close
|
||||
ssh_scp_deny_request
|
||||
ssh_scp_free
|
||||
ssh_scp_init
|
||||
ssh_scp_leave_directory
|
||||
ssh_scp_new
|
||||
ssh_scp_pull_request
|
||||
ssh_scp_push_directory
|
||||
ssh_scp_push_file
|
||||
ssh_scp_push_file64
|
||||
ssh_scp_read
|
||||
ssh_scp_request_get_filename
|
||||
ssh_scp_request_get_permissions
|
||||
ssh_scp_request_get_size
|
||||
ssh_scp_request_get_size64
|
||||
ssh_scp_request_get_warning
|
||||
ssh_scp_write
|
||||
ssh_select
|
||||
ssh_send_debug
|
||||
ssh_send_ignore
|
||||
ssh_send_keepalive
|
||||
ssh_server_init_kex
|
||||
ssh_service_request
|
||||
ssh_session_export_known_hosts_entry
|
||||
ssh_session_has_known_hosts_entry
|
||||
ssh_session_is_known_server
|
||||
ssh_session_update_known_hosts
|
||||
ssh_set_agent_channel
|
||||
ssh_set_agent_socket
|
||||
ssh_set_auth_methods
|
||||
ssh_set_blocking
|
||||
ssh_set_callbacks
|
||||
ssh_set_channel_callbacks
|
||||
ssh_set_counters
|
||||
ssh_set_fd_except
|
||||
ssh_set_fd_toread
|
||||
ssh_set_fd_towrite
|
||||
ssh_set_log_callback
|
||||
ssh_set_log_level
|
||||
ssh_set_log_userdata
|
||||
ssh_set_message_callback
|
||||
ssh_set_pcap_file
|
||||
ssh_set_server_callbacks
|
||||
ssh_silent_disconnect
|
||||
ssh_string_burn
|
||||
ssh_string_copy
|
||||
ssh_string_data
|
||||
ssh_string_fill
|
||||
ssh_string_free
|
||||
ssh_string_free_char
|
||||
ssh_string_from_char
|
||||
ssh_string_get_char
|
||||
ssh_string_len
|
||||
ssh_string_new
|
||||
ssh_string_to_char
|
||||
ssh_threads_get_noop
|
||||
ssh_threads_get_pthread
|
||||
ssh_threads_set_callbacks
|
||||
ssh_try_publickey_from_file
|
||||
ssh_userauth_agent
|
||||
ssh_userauth_agent_pubkey
|
||||
ssh_userauth_autopubkey
|
||||
ssh_userauth_gssapi
|
||||
ssh_userauth_kbdint
|
||||
ssh_userauth_kbdint_getanswer
|
||||
ssh_userauth_kbdint_getinstruction
|
||||
ssh_userauth_kbdint_getname
|
||||
ssh_userauth_kbdint_getnanswers
|
||||
ssh_userauth_kbdint_getnprompts
|
||||
ssh_userauth_kbdint_getprompt
|
||||
ssh_userauth_kbdint_setanswer
|
||||
ssh_userauth_list
|
||||
ssh_userauth_none
|
||||
ssh_userauth_offer_pubkey
|
||||
ssh_userauth_password
|
||||
ssh_userauth_privatekey_file
|
||||
ssh_userauth_pubkey
|
||||
ssh_userauth_publickey
|
||||
ssh_userauth_publickey_auto
|
||||
ssh_userauth_try_publickey
|
||||
ssh_version
|
||||
ssh_write_knownhost
|
||||
string_burn
|
||||
string_copy
|
||||
string_data
|
||||
string_fill
|
||||
string_free
|
||||
string_from_char
|
||||
string_len
|
||||
string_new
|
||||
string_to_char
|
||||
415
src/ABI/libssh-4.7.3.symbols
Normal file
415
src/ABI/libssh-4.7.3.symbols
Normal file
@@ -0,0 +1,415 @@
|
||||
_ssh_log
|
||||
buffer_free
|
||||
buffer_get
|
||||
buffer_get_len
|
||||
buffer_new
|
||||
channel_accept_x11
|
||||
channel_change_pty_size
|
||||
channel_close
|
||||
channel_forward_accept
|
||||
channel_forward_cancel
|
||||
channel_forward_listen
|
||||
channel_free
|
||||
channel_get_exit_status
|
||||
channel_get_session
|
||||
channel_is_closed
|
||||
channel_is_eof
|
||||
channel_is_open
|
||||
channel_new
|
||||
channel_open_forward
|
||||
channel_open_session
|
||||
channel_poll
|
||||
channel_read
|
||||
channel_read_buffer
|
||||
channel_read_nonblocking
|
||||
channel_request_env
|
||||
channel_request_exec
|
||||
channel_request_pty
|
||||
channel_request_pty_size
|
||||
channel_request_send_signal
|
||||
channel_request_sftp
|
||||
channel_request_shell
|
||||
channel_request_subsystem
|
||||
channel_request_x11
|
||||
channel_select
|
||||
channel_send_eof
|
||||
channel_set_blocking
|
||||
channel_write
|
||||
channel_write_stderr
|
||||
privatekey_free
|
||||
privatekey_from_file
|
||||
publickey_free
|
||||
publickey_from_file
|
||||
publickey_from_privatekey
|
||||
publickey_to_string
|
||||
sftp_async_read
|
||||
sftp_async_read_begin
|
||||
sftp_attributes_free
|
||||
sftp_canonicalize_path
|
||||
sftp_chmod
|
||||
sftp_chown
|
||||
sftp_client_message_free
|
||||
sftp_client_message_get_data
|
||||
sftp_client_message_get_filename
|
||||
sftp_client_message_get_flags
|
||||
sftp_client_message_get_submessage
|
||||
sftp_client_message_get_type
|
||||
sftp_client_message_set_filename
|
||||
sftp_close
|
||||
sftp_closedir
|
||||
sftp_dir_eof
|
||||
sftp_extension_supported
|
||||
sftp_extensions_get_count
|
||||
sftp_extensions_get_data
|
||||
sftp_extensions_get_name
|
||||
sftp_file_set_blocking
|
||||
sftp_file_set_nonblocking
|
||||
sftp_free
|
||||
sftp_fstat
|
||||
sftp_fstatvfs
|
||||
sftp_fsync
|
||||
sftp_get_client_message
|
||||
sftp_get_error
|
||||
sftp_handle
|
||||
sftp_handle_alloc
|
||||
sftp_handle_remove
|
||||
sftp_init
|
||||
sftp_lstat
|
||||
sftp_mkdir
|
||||
sftp_new
|
||||
sftp_new_channel
|
||||
sftp_open
|
||||
sftp_opendir
|
||||
sftp_read
|
||||
sftp_readdir
|
||||
sftp_readlink
|
||||
sftp_rename
|
||||
sftp_reply_attr
|
||||
sftp_reply_data
|
||||
sftp_reply_handle
|
||||
sftp_reply_name
|
||||
sftp_reply_names
|
||||
sftp_reply_names_add
|
||||
sftp_reply_status
|
||||
sftp_rewind
|
||||
sftp_rmdir
|
||||
sftp_seek
|
||||
sftp_seek64
|
||||
sftp_send_client_message
|
||||
sftp_server_init
|
||||
sftp_server_new
|
||||
sftp_server_version
|
||||
sftp_setstat
|
||||
sftp_stat
|
||||
sftp_statvfs
|
||||
sftp_statvfs_free
|
||||
sftp_symlink
|
||||
sftp_tell
|
||||
sftp_tell64
|
||||
sftp_unlink
|
||||
sftp_utimes
|
||||
sftp_write
|
||||
ssh_accept
|
||||
ssh_add_channel_callbacks
|
||||
ssh_auth_list
|
||||
ssh_basename
|
||||
ssh_bind_accept
|
||||
ssh_bind_accept_fd
|
||||
ssh_bind_fd_toaccept
|
||||
ssh_bind_free
|
||||
ssh_bind_get_fd
|
||||
ssh_bind_listen
|
||||
ssh_bind_new
|
||||
ssh_bind_options_set
|
||||
ssh_bind_set_blocking
|
||||
ssh_bind_set_callbacks
|
||||
ssh_bind_set_fd
|
||||
ssh_blocking_flush
|
||||
ssh_buffer_add_data
|
||||
ssh_buffer_free
|
||||
ssh_buffer_get
|
||||
ssh_buffer_get_data
|
||||
ssh_buffer_get_len
|
||||
ssh_buffer_new
|
||||
ssh_buffer_reinit
|
||||
ssh_channel_accept_forward
|
||||
ssh_channel_accept_x11
|
||||
ssh_channel_cancel_forward
|
||||
ssh_channel_change_pty_size
|
||||
ssh_channel_close
|
||||
ssh_channel_free
|
||||
ssh_channel_get_exit_status
|
||||
ssh_channel_get_session
|
||||
ssh_channel_is_closed
|
||||
ssh_channel_is_eof
|
||||
ssh_channel_is_open
|
||||
ssh_channel_listen_forward
|
||||
ssh_channel_new
|
||||
ssh_channel_open_auth_agent
|
||||
ssh_channel_open_forward
|
||||
ssh_channel_open_reverse_forward
|
||||
ssh_channel_open_session
|
||||
ssh_channel_open_x11
|
||||
ssh_channel_poll
|
||||
ssh_channel_poll_timeout
|
||||
ssh_channel_read
|
||||
ssh_channel_read_nonblocking
|
||||
ssh_channel_read_timeout
|
||||
ssh_channel_request_auth_agent
|
||||
ssh_channel_request_env
|
||||
ssh_channel_request_exec
|
||||
ssh_channel_request_pty
|
||||
ssh_channel_request_pty_size
|
||||
ssh_channel_request_send_break
|
||||
ssh_channel_request_send_exit_signal
|
||||
ssh_channel_request_send_exit_status
|
||||
ssh_channel_request_send_signal
|
||||
ssh_channel_request_sftp
|
||||
ssh_channel_request_shell
|
||||
ssh_channel_request_subsystem
|
||||
ssh_channel_request_x11
|
||||
ssh_channel_select
|
||||
ssh_channel_send_eof
|
||||
ssh_channel_set_blocking
|
||||
ssh_channel_set_counter
|
||||
ssh_channel_window_size
|
||||
ssh_channel_write
|
||||
ssh_channel_write_stderr
|
||||
ssh_clean_pubkey_hash
|
||||
ssh_connect
|
||||
ssh_connector_free
|
||||
ssh_connector_new
|
||||
ssh_connector_set_in_channel
|
||||
ssh_connector_set_in_fd
|
||||
ssh_connector_set_out_channel
|
||||
ssh_connector_set_out_fd
|
||||
ssh_copyright
|
||||
ssh_dirname
|
||||
ssh_disconnect
|
||||
ssh_dump_knownhost
|
||||
ssh_event_add_connector
|
||||
ssh_event_add_fd
|
||||
ssh_event_add_session
|
||||
ssh_event_dopoll
|
||||
ssh_event_free
|
||||
ssh_event_new
|
||||
ssh_event_remove_connector
|
||||
ssh_event_remove_fd
|
||||
ssh_event_remove_session
|
||||
ssh_execute_message_callbacks
|
||||
ssh_finalize
|
||||
ssh_forward_accept
|
||||
ssh_forward_cancel
|
||||
ssh_forward_listen
|
||||
ssh_free
|
||||
ssh_get_cipher_in
|
||||
ssh_get_cipher_out
|
||||
ssh_get_clientbanner
|
||||
ssh_get_disconnect_message
|
||||
ssh_get_error
|
||||
ssh_get_error_code
|
||||
ssh_get_fd
|
||||
ssh_get_fingerprint_hash
|
||||
ssh_get_hexa
|
||||
ssh_get_hmac_in
|
||||
ssh_get_hmac_out
|
||||
ssh_get_issue_banner
|
||||
ssh_get_kex_algo
|
||||
ssh_get_log_callback
|
||||
ssh_get_log_level
|
||||
ssh_get_log_userdata
|
||||
ssh_get_openssh_version
|
||||
ssh_get_poll_flags
|
||||
ssh_get_pubkey
|
||||
ssh_get_pubkey_hash
|
||||
ssh_get_publickey
|
||||
ssh_get_publickey_hash
|
||||
ssh_get_random
|
||||
ssh_get_server_publickey
|
||||
ssh_get_serverbanner
|
||||
ssh_get_status
|
||||
ssh_get_version
|
||||
ssh_getpass
|
||||
ssh_gssapi_get_creds
|
||||
ssh_gssapi_set_creds
|
||||
ssh_handle_key_exchange
|
||||
ssh_init
|
||||
ssh_is_blocking
|
||||
ssh_is_connected
|
||||
ssh_is_server_known
|
||||
ssh_key_cmp
|
||||
ssh_key_free
|
||||
ssh_key_is_private
|
||||
ssh_key_is_public
|
||||
ssh_key_new
|
||||
ssh_key_type
|
||||
ssh_key_type_from_name
|
||||
ssh_key_type_to_char
|
||||
ssh_known_hosts_parse_line
|
||||
ssh_knownhosts_entry_free
|
||||
ssh_log
|
||||
ssh_message_auth_interactive_request
|
||||
ssh_message_auth_kbdint_is_response
|
||||
ssh_message_auth_password
|
||||
ssh_message_auth_pubkey
|
||||
ssh_message_auth_publickey
|
||||
ssh_message_auth_publickey_state
|
||||
ssh_message_auth_reply_pk_ok
|
||||
ssh_message_auth_reply_pk_ok_simple
|
||||
ssh_message_auth_reply_success
|
||||
ssh_message_auth_set_methods
|
||||
ssh_message_auth_user
|
||||
ssh_message_channel_request_channel
|
||||
ssh_message_channel_request_command
|
||||
ssh_message_channel_request_env_name
|
||||
ssh_message_channel_request_env_value
|
||||
ssh_message_channel_request_open_destination
|
||||
ssh_message_channel_request_open_destination_port
|
||||
ssh_message_channel_request_open_originator
|
||||
ssh_message_channel_request_open_originator_port
|
||||
ssh_message_channel_request_open_reply_accept
|
||||
ssh_message_channel_request_pty_height
|
||||
ssh_message_channel_request_pty_pxheight
|
||||
ssh_message_channel_request_pty_pxwidth
|
||||
ssh_message_channel_request_pty_term
|
||||
ssh_message_channel_request_pty_width
|
||||
ssh_message_channel_request_reply_success
|
||||
ssh_message_channel_request_subsystem
|
||||
ssh_message_channel_request_x11_auth_cookie
|
||||
ssh_message_channel_request_x11_auth_protocol
|
||||
ssh_message_channel_request_x11_screen_number
|
||||
ssh_message_channel_request_x11_single_connection
|
||||
ssh_message_free
|
||||
ssh_message_get
|
||||
ssh_message_global_request_address
|
||||
ssh_message_global_request_port
|
||||
ssh_message_global_request_reply_success
|
||||
ssh_message_reply_default
|
||||
ssh_message_retrieve
|
||||
ssh_message_service_reply_success
|
||||
ssh_message_service_service
|
||||
ssh_message_subtype
|
||||
ssh_message_type
|
||||
ssh_mkdir
|
||||
ssh_new
|
||||
ssh_options_copy
|
||||
ssh_options_get
|
||||
ssh_options_get_port
|
||||
ssh_options_getopt
|
||||
ssh_options_parse_config
|
||||
ssh_options_set
|
||||
ssh_pcap_file_close
|
||||
ssh_pcap_file_free
|
||||
ssh_pcap_file_new
|
||||
ssh_pcap_file_open
|
||||
ssh_pki_copy_cert_to_privkey
|
||||
ssh_pki_export_privkey_base64
|
||||
ssh_pki_export_privkey_file
|
||||
ssh_pki_export_privkey_to_pubkey
|
||||
ssh_pki_export_pubkey_base64
|
||||
ssh_pki_export_pubkey_file
|
||||
ssh_pki_generate
|
||||
ssh_pki_import_cert_base64
|
||||
ssh_pki_import_cert_file
|
||||
ssh_pki_import_privkey_base64
|
||||
ssh_pki_import_privkey_file
|
||||
ssh_pki_import_pubkey_base64
|
||||
ssh_pki_import_pubkey_file
|
||||
ssh_pki_key_ecdsa_name
|
||||
ssh_print_hash
|
||||
ssh_print_hexa
|
||||
ssh_privatekey_type
|
||||
ssh_publickey_to_file
|
||||
ssh_remove_channel_callbacks
|
||||
ssh_scp_accept_request
|
||||
ssh_scp_close
|
||||
ssh_scp_deny_request
|
||||
ssh_scp_free
|
||||
ssh_scp_init
|
||||
ssh_scp_leave_directory
|
||||
ssh_scp_new
|
||||
ssh_scp_pull_request
|
||||
ssh_scp_push_directory
|
||||
ssh_scp_push_file
|
||||
ssh_scp_push_file64
|
||||
ssh_scp_read
|
||||
ssh_scp_request_get_filename
|
||||
ssh_scp_request_get_permissions
|
||||
ssh_scp_request_get_size
|
||||
ssh_scp_request_get_size64
|
||||
ssh_scp_request_get_warning
|
||||
ssh_scp_write
|
||||
ssh_select
|
||||
ssh_send_debug
|
||||
ssh_send_ignore
|
||||
ssh_send_keepalive
|
||||
ssh_server_init_kex
|
||||
ssh_service_request
|
||||
ssh_session_export_known_hosts_entry
|
||||
ssh_session_has_known_hosts_entry
|
||||
ssh_session_is_known_server
|
||||
ssh_session_update_known_hosts
|
||||
ssh_set_agent_channel
|
||||
ssh_set_agent_socket
|
||||
ssh_set_auth_methods
|
||||
ssh_set_blocking
|
||||
ssh_set_callbacks
|
||||
ssh_set_channel_callbacks
|
||||
ssh_set_counters
|
||||
ssh_set_fd_except
|
||||
ssh_set_fd_toread
|
||||
ssh_set_fd_towrite
|
||||
ssh_set_log_callback
|
||||
ssh_set_log_level
|
||||
ssh_set_log_userdata
|
||||
ssh_set_message_callback
|
||||
ssh_set_pcap_file
|
||||
ssh_set_server_callbacks
|
||||
ssh_silent_disconnect
|
||||
ssh_string_burn
|
||||
ssh_string_copy
|
||||
ssh_string_data
|
||||
ssh_string_fill
|
||||
ssh_string_free
|
||||
ssh_string_free_char
|
||||
ssh_string_from_char
|
||||
ssh_string_get_char
|
||||
ssh_string_len
|
||||
ssh_string_new
|
||||
ssh_string_to_char
|
||||
ssh_threads_get_noop
|
||||
ssh_threads_get_pthread
|
||||
ssh_threads_set_callbacks
|
||||
ssh_try_publickey_from_file
|
||||
ssh_userauth_agent
|
||||
ssh_userauth_agent_pubkey
|
||||
ssh_userauth_autopubkey
|
||||
ssh_userauth_gssapi
|
||||
ssh_userauth_kbdint
|
||||
ssh_userauth_kbdint_getanswer
|
||||
ssh_userauth_kbdint_getinstruction
|
||||
ssh_userauth_kbdint_getname
|
||||
ssh_userauth_kbdint_getnanswers
|
||||
ssh_userauth_kbdint_getnprompts
|
||||
ssh_userauth_kbdint_getprompt
|
||||
ssh_userauth_kbdint_setanswer
|
||||
ssh_userauth_list
|
||||
ssh_userauth_none
|
||||
ssh_userauth_offer_pubkey
|
||||
ssh_userauth_password
|
||||
ssh_userauth_privatekey_file
|
||||
ssh_userauth_pubkey
|
||||
ssh_userauth_publickey
|
||||
ssh_userauth_publickey_auto
|
||||
ssh_userauth_try_publickey
|
||||
ssh_version
|
||||
ssh_write_knownhost
|
||||
string_burn
|
||||
string_copy
|
||||
string_data
|
||||
string_fill
|
||||
string_free
|
||||
string_from_char
|
||||
string_len
|
||||
string_new
|
||||
string_to_char
|
||||
415
src/ABI/libssh-4.7.4.symbols
Normal file
415
src/ABI/libssh-4.7.4.symbols
Normal file
@@ -0,0 +1,415 @@
|
||||
_ssh_log
|
||||
buffer_free
|
||||
buffer_get
|
||||
buffer_get_len
|
||||
buffer_new
|
||||
channel_accept_x11
|
||||
channel_change_pty_size
|
||||
channel_close
|
||||
channel_forward_accept
|
||||
channel_forward_cancel
|
||||
channel_forward_listen
|
||||
channel_free
|
||||
channel_get_exit_status
|
||||
channel_get_session
|
||||
channel_is_closed
|
||||
channel_is_eof
|
||||
channel_is_open
|
||||
channel_new
|
||||
channel_open_forward
|
||||
channel_open_session
|
||||
channel_poll
|
||||
channel_read
|
||||
channel_read_buffer
|
||||
channel_read_nonblocking
|
||||
channel_request_env
|
||||
channel_request_exec
|
||||
channel_request_pty
|
||||
channel_request_pty_size
|
||||
channel_request_send_signal
|
||||
channel_request_sftp
|
||||
channel_request_shell
|
||||
channel_request_subsystem
|
||||
channel_request_x11
|
||||
channel_select
|
||||
channel_send_eof
|
||||
channel_set_blocking
|
||||
channel_write
|
||||
channel_write_stderr
|
||||
privatekey_free
|
||||
privatekey_from_file
|
||||
publickey_free
|
||||
publickey_from_file
|
||||
publickey_from_privatekey
|
||||
publickey_to_string
|
||||
sftp_async_read
|
||||
sftp_async_read_begin
|
||||
sftp_attributes_free
|
||||
sftp_canonicalize_path
|
||||
sftp_chmod
|
||||
sftp_chown
|
||||
sftp_client_message_free
|
||||
sftp_client_message_get_data
|
||||
sftp_client_message_get_filename
|
||||
sftp_client_message_get_flags
|
||||
sftp_client_message_get_submessage
|
||||
sftp_client_message_get_type
|
||||
sftp_client_message_set_filename
|
||||
sftp_close
|
||||
sftp_closedir
|
||||
sftp_dir_eof
|
||||
sftp_extension_supported
|
||||
sftp_extensions_get_count
|
||||
sftp_extensions_get_data
|
||||
sftp_extensions_get_name
|
||||
sftp_file_set_blocking
|
||||
sftp_file_set_nonblocking
|
||||
sftp_free
|
||||
sftp_fstat
|
||||
sftp_fstatvfs
|
||||
sftp_fsync
|
||||
sftp_get_client_message
|
||||
sftp_get_error
|
||||
sftp_handle
|
||||
sftp_handle_alloc
|
||||
sftp_handle_remove
|
||||
sftp_init
|
||||
sftp_lstat
|
||||
sftp_mkdir
|
||||
sftp_new
|
||||
sftp_new_channel
|
||||
sftp_open
|
||||
sftp_opendir
|
||||
sftp_read
|
||||
sftp_readdir
|
||||
sftp_readlink
|
||||
sftp_rename
|
||||
sftp_reply_attr
|
||||
sftp_reply_data
|
||||
sftp_reply_handle
|
||||
sftp_reply_name
|
||||
sftp_reply_names
|
||||
sftp_reply_names_add
|
||||
sftp_reply_status
|
||||
sftp_rewind
|
||||
sftp_rmdir
|
||||
sftp_seek
|
||||
sftp_seek64
|
||||
sftp_send_client_message
|
||||
sftp_server_init
|
||||
sftp_server_new
|
||||
sftp_server_version
|
||||
sftp_setstat
|
||||
sftp_stat
|
||||
sftp_statvfs
|
||||
sftp_statvfs_free
|
||||
sftp_symlink
|
||||
sftp_tell
|
||||
sftp_tell64
|
||||
sftp_unlink
|
||||
sftp_utimes
|
||||
sftp_write
|
||||
ssh_accept
|
||||
ssh_add_channel_callbacks
|
||||
ssh_auth_list
|
||||
ssh_basename
|
||||
ssh_bind_accept
|
||||
ssh_bind_accept_fd
|
||||
ssh_bind_fd_toaccept
|
||||
ssh_bind_free
|
||||
ssh_bind_get_fd
|
||||
ssh_bind_listen
|
||||
ssh_bind_new
|
||||
ssh_bind_options_set
|
||||
ssh_bind_set_blocking
|
||||
ssh_bind_set_callbacks
|
||||
ssh_bind_set_fd
|
||||
ssh_blocking_flush
|
||||
ssh_buffer_add_data
|
||||
ssh_buffer_free
|
||||
ssh_buffer_get
|
||||
ssh_buffer_get_data
|
||||
ssh_buffer_get_len
|
||||
ssh_buffer_new
|
||||
ssh_buffer_reinit
|
||||
ssh_channel_accept_forward
|
||||
ssh_channel_accept_x11
|
||||
ssh_channel_cancel_forward
|
||||
ssh_channel_change_pty_size
|
||||
ssh_channel_close
|
||||
ssh_channel_free
|
||||
ssh_channel_get_exit_status
|
||||
ssh_channel_get_session
|
||||
ssh_channel_is_closed
|
||||
ssh_channel_is_eof
|
||||
ssh_channel_is_open
|
||||
ssh_channel_listen_forward
|
||||
ssh_channel_new
|
||||
ssh_channel_open_auth_agent
|
||||
ssh_channel_open_forward
|
||||
ssh_channel_open_reverse_forward
|
||||
ssh_channel_open_session
|
||||
ssh_channel_open_x11
|
||||
ssh_channel_poll
|
||||
ssh_channel_poll_timeout
|
||||
ssh_channel_read
|
||||
ssh_channel_read_nonblocking
|
||||
ssh_channel_read_timeout
|
||||
ssh_channel_request_auth_agent
|
||||
ssh_channel_request_env
|
||||
ssh_channel_request_exec
|
||||
ssh_channel_request_pty
|
||||
ssh_channel_request_pty_size
|
||||
ssh_channel_request_send_break
|
||||
ssh_channel_request_send_exit_signal
|
||||
ssh_channel_request_send_exit_status
|
||||
ssh_channel_request_send_signal
|
||||
ssh_channel_request_sftp
|
||||
ssh_channel_request_shell
|
||||
ssh_channel_request_subsystem
|
||||
ssh_channel_request_x11
|
||||
ssh_channel_select
|
||||
ssh_channel_send_eof
|
||||
ssh_channel_set_blocking
|
||||
ssh_channel_set_counter
|
||||
ssh_channel_window_size
|
||||
ssh_channel_write
|
||||
ssh_channel_write_stderr
|
||||
ssh_clean_pubkey_hash
|
||||
ssh_connect
|
||||
ssh_connector_free
|
||||
ssh_connector_new
|
||||
ssh_connector_set_in_channel
|
||||
ssh_connector_set_in_fd
|
||||
ssh_connector_set_out_channel
|
||||
ssh_connector_set_out_fd
|
||||
ssh_copyright
|
||||
ssh_dirname
|
||||
ssh_disconnect
|
||||
ssh_dump_knownhost
|
||||
ssh_event_add_connector
|
||||
ssh_event_add_fd
|
||||
ssh_event_add_session
|
||||
ssh_event_dopoll
|
||||
ssh_event_free
|
||||
ssh_event_new
|
||||
ssh_event_remove_connector
|
||||
ssh_event_remove_fd
|
||||
ssh_event_remove_session
|
||||
ssh_execute_message_callbacks
|
||||
ssh_finalize
|
||||
ssh_forward_accept
|
||||
ssh_forward_cancel
|
||||
ssh_forward_listen
|
||||
ssh_free
|
||||
ssh_get_cipher_in
|
||||
ssh_get_cipher_out
|
||||
ssh_get_clientbanner
|
||||
ssh_get_disconnect_message
|
||||
ssh_get_error
|
||||
ssh_get_error_code
|
||||
ssh_get_fd
|
||||
ssh_get_fingerprint_hash
|
||||
ssh_get_hexa
|
||||
ssh_get_hmac_in
|
||||
ssh_get_hmac_out
|
||||
ssh_get_issue_banner
|
||||
ssh_get_kex_algo
|
||||
ssh_get_log_callback
|
||||
ssh_get_log_level
|
||||
ssh_get_log_userdata
|
||||
ssh_get_openssh_version
|
||||
ssh_get_poll_flags
|
||||
ssh_get_pubkey
|
||||
ssh_get_pubkey_hash
|
||||
ssh_get_publickey
|
||||
ssh_get_publickey_hash
|
||||
ssh_get_random
|
||||
ssh_get_server_publickey
|
||||
ssh_get_serverbanner
|
||||
ssh_get_status
|
||||
ssh_get_version
|
||||
ssh_getpass
|
||||
ssh_gssapi_get_creds
|
||||
ssh_gssapi_set_creds
|
||||
ssh_handle_key_exchange
|
||||
ssh_init
|
||||
ssh_is_blocking
|
||||
ssh_is_connected
|
||||
ssh_is_server_known
|
||||
ssh_key_cmp
|
||||
ssh_key_free
|
||||
ssh_key_is_private
|
||||
ssh_key_is_public
|
||||
ssh_key_new
|
||||
ssh_key_type
|
||||
ssh_key_type_from_name
|
||||
ssh_key_type_to_char
|
||||
ssh_known_hosts_parse_line
|
||||
ssh_knownhosts_entry_free
|
||||
ssh_log
|
||||
ssh_message_auth_interactive_request
|
||||
ssh_message_auth_kbdint_is_response
|
||||
ssh_message_auth_password
|
||||
ssh_message_auth_pubkey
|
||||
ssh_message_auth_publickey
|
||||
ssh_message_auth_publickey_state
|
||||
ssh_message_auth_reply_pk_ok
|
||||
ssh_message_auth_reply_pk_ok_simple
|
||||
ssh_message_auth_reply_success
|
||||
ssh_message_auth_set_methods
|
||||
ssh_message_auth_user
|
||||
ssh_message_channel_request_channel
|
||||
ssh_message_channel_request_command
|
||||
ssh_message_channel_request_env_name
|
||||
ssh_message_channel_request_env_value
|
||||
ssh_message_channel_request_open_destination
|
||||
ssh_message_channel_request_open_destination_port
|
||||
ssh_message_channel_request_open_originator
|
||||
ssh_message_channel_request_open_originator_port
|
||||
ssh_message_channel_request_open_reply_accept
|
||||
ssh_message_channel_request_pty_height
|
||||
ssh_message_channel_request_pty_pxheight
|
||||
ssh_message_channel_request_pty_pxwidth
|
||||
ssh_message_channel_request_pty_term
|
||||
ssh_message_channel_request_pty_width
|
||||
ssh_message_channel_request_reply_success
|
||||
ssh_message_channel_request_subsystem
|
||||
ssh_message_channel_request_x11_auth_cookie
|
||||
ssh_message_channel_request_x11_auth_protocol
|
||||
ssh_message_channel_request_x11_screen_number
|
||||
ssh_message_channel_request_x11_single_connection
|
||||
ssh_message_free
|
||||
ssh_message_get
|
||||
ssh_message_global_request_address
|
||||
ssh_message_global_request_port
|
||||
ssh_message_global_request_reply_success
|
||||
ssh_message_reply_default
|
||||
ssh_message_retrieve
|
||||
ssh_message_service_reply_success
|
||||
ssh_message_service_service
|
||||
ssh_message_subtype
|
||||
ssh_message_type
|
||||
ssh_mkdir
|
||||
ssh_new
|
||||
ssh_options_copy
|
||||
ssh_options_get
|
||||
ssh_options_get_port
|
||||
ssh_options_getopt
|
||||
ssh_options_parse_config
|
||||
ssh_options_set
|
||||
ssh_pcap_file_close
|
||||
ssh_pcap_file_free
|
||||
ssh_pcap_file_new
|
||||
ssh_pcap_file_open
|
||||
ssh_pki_copy_cert_to_privkey
|
||||
ssh_pki_export_privkey_base64
|
||||
ssh_pki_export_privkey_file
|
||||
ssh_pki_export_privkey_to_pubkey
|
||||
ssh_pki_export_pubkey_base64
|
||||
ssh_pki_export_pubkey_file
|
||||
ssh_pki_generate
|
||||
ssh_pki_import_cert_base64
|
||||
ssh_pki_import_cert_file
|
||||
ssh_pki_import_privkey_base64
|
||||
ssh_pki_import_privkey_file
|
||||
ssh_pki_import_pubkey_base64
|
||||
ssh_pki_import_pubkey_file
|
||||
ssh_pki_key_ecdsa_name
|
||||
ssh_print_hash
|
||||
ssh_print_hexa
|
||||
ssh_privatekey_type
|
||||
ssh_publickey_to_file
|
||||
ssh_remove_channel_callbacks
|
||||
ssh_scp_accept_request
|
||||
ssh_scp_close
|
||||
ssh_scp_deny_request
|
||||
ssh_scp_free
|
||||
ssh_scp_init
|
||||
ssh_scp_leave_directory
|
||||
ssh_scp_new
|
||||
ssh_scp_pull_request
|
||||
ssh_scp_push_directory
|
||||
ssh_scp_push_file
|
||||
ssh_scp_push_file64
|
||||
ssh_scp_read
|
||||
ssh_scp_request_get_filename
|
||||
ssh_scp_request_get_permissions
|
||||
ssh_scp_request_get_size
|
||||
ssh_scp_request_get_size64
|
||||
ssh_scp_request_get_warning
|
||||
ssh_scp_write
|
||||
ssh_select
|
||||
ssh_send_debug
|
||||
ssh_send_ignore
|
||||
ssh_send_keepalive
|
||||
ssh_server_init_kex
|
||||
ssh_service_request
|
||||
ssh_session_export_known_hosts_entry
|
||||
ssh_session_has_known_hosts_entry
|
||||
ssh_session_is_known_server
|
||||
ssh_session_update_known_hosts
|
||||
ssh_set_agent_channel
|
||||
ssh_set_agent_socket
|
||||
ssh_set_auth_methods
|
||||
ssh_set_blocking
|
||||
ssh_set_callbacks
|
||||
ssh_set_channel_callbacks
|
||||
ssh_set_counters
|
||||
ssh_set_fd_except
|
||||
ssh_set_fd_toread
|
||||
ssh_set_fd_towrite
|
||||
ssh_set_log_callback
|
||||
ssh_set_log_level
|
||||
ssh_set_log_userdata
|
||||
ssh_set_message_callback
|
||||
ssh_set_pcap_file
|
||||
ssh_set_server_callbacks
|
||||
ssh_silent_disconnect
|
||||
ssh_string_burn
|
||||
ssh_string_copy
|
||||
ssh_string_data
|
||||
ssh_string_fill
|
||||
ssh_string_free
|
||||
ssh_string_free_char
|
||||
ssh_string_from_char
|
||||
ssh_string_get_char
|
||||
ssh_string_len
|
||||
ssh_string_new
|
||||
ssh_string_to_char
|
||||
ssh_threads_get_noop
|
||||
ssh_threads_get_pthread
|
||||
ssh_threads_set_callbacks
|
||||
ssh_try_publickey_from_file
|
||||
ssh_userauth_agent
|
||||
ssh_userauth_agent_pubkey
|
||||
ssh_userauth_autopubkey
|
||||
ssh_userauth_gssapi
|
||||
ssh_userauth_kbdint
|
||||
ssh_userauth_kbdint_getanswer
|
||||
ssh_userauth_kbdint_getinstruction
|
||||
ssh_userauth_kbdint_getname
|
||||
ssh_userauth_kbdint_getnanswers
|
||||
ssh_userauth_kbdint_getnprompts
|
||||
ssh_userauth_kbdint_getprompt
|
||||
ssh_userauth_kbdint_setanswer
|
||||
ssh_userauth_list
|
||||
ssh_userauth_none
|
||||
ssh_userauth_offer_pubkey
|
||||
ssh_userauth_password
|
||||
ssh_userauth_privatekey_file
|
||||
ssh_userauth_pubkey
|
||||
ssh_userauth_publickey
|
||||
ssh_userauth_publickey_auto
|
||||
ssh_userauth_try_publickey
|
||||
ssh_version
|
||||
ssh_write_knownhost
|
||||
string_burn
|
||||
string_copy
|
||||
string_data
|
||||
string_fill
|
||||
string_free
|
||||
string_from_char
|
||||
string_len
|
||||
string_new
|
||||
string_to_char
|
||||
415
src/ABI/libssh-4.7.5.symbols
Normal file
415
src/ABI/libssh-4.7.5.symbols
Normal file
@@ -0,0 +1,415 @@
|
||||
_ssh_log
|
||||
buffer_free
|
||||
buffer_get
|
||||
buffer_get_len
|
||||
buffer_new
|
||||
channel_accept_x11
|
||||
channel_change_pty_size
|
||||
channel_close
|
||||
channel_forward_accept
|
||||
channel_forward_cancel
|
||||
channel_forward_listen
|
||||
channel_free
|
||||
channel_get_exit_status
|
||||
channel_get_session
|
||||
channel_is_closed
|
||||
channel_is_eof
|
||||
channel_is_open
|
||||
channel_new
|
||||
channel_open_forward
|
||||
channel_open_session
|
||||
channel_poll
|
||||
channel_read
|
||||
channel_read_buffer
|
||||
channel_read_nonblocking
|
||||
channel_request_env
|
||||
channel_request_exec
|
||||
channel_request_pty
|
||||
channel_request_pty_size
|
||||
channel_request_send_signal
|
||||
channel_request_sftp
|
||||
channel_request_shell
|
||||
channel_request_subsystem
|
||||
channel_request_x11
|
||||
channel_select
|
||||
channel_send_eof
|
||||
channel_set_blocking
|
||||
channel_write
|
||||
channel_write_stderr
|
||||
privatekey_free
|
||||
privatekey_from_file
|
||||
publickey_free
|
||||
publickey_from_file
|
||||
publickey_from_privatekey
|
||||
publickey_to_string
|
||||
sftp_async_read
|
||||
sftp_async_read_begin
|
||||
sftp_attributes_free
|
||||
sftp_canonicalize_path
|
||||
sftp_chmod
|
||||
sftp_chown
|
||||
sftp_client_message_free
|
||||
sftp_client_message_get_data
|
||||
sftp_client_message_get_filename
|
||||
sftp_client_message_get_flags
|
||||
sftp_client_message_get_submessage
|
||||
sftp_client_message_get_type
|
||||
sftp_client_message_set_filename
|
||||
sftp_close
|
||||
sftp_closedir
|
||||
sftp_dir_eof
|
||||
sftp_extension_supported
|
||||
sftp_extensions_get_count
|
||||
sftp_extensions_get_data
|
||||
sftp_extensions_get_name
|
||||
sftp_file_set_blocking
|
||||
sftp_file_set_nonblocking
|
||||
sftp_free
|
||||
sftp_fstat
|
||||
sftp_fstatvfs
|
||||
sftp_fsync
|
||||
sftp_get_client_message
|
||||
sftp_get_error
|
||||
sftp_handle
|
||||
sftp_handle_alloc
|
||||
sftp_handle_remove
|
||||
sftp_init
|
||||
sftp_lstat
|
||||
sftp_mkdir
|
||||
sftp_new
|
||||
sftp_new_channel
|
||||
sftp_open
|
||||
sftp_opendir
|
||||
sftp_read
|
||||
sftp_readdir
|
||||
sftp_readlink
|
||||
sftp_rename
|
||||
sftp_reply_attr
|
||||
sftp_reply_data
|
||||
sftp_reply_handle
|
||||
sftp_reply_name
|
||||
sftp_reply_names
|
||||
sftp_reply_names_add
|
||||
sftp_reply_status
|
||||
sftp_rewind
|
||||
sftp_rmdir
|
||||
sftp_seek
|
||||
sftp_seek64
|
||||
sftp_send_client_message
|
||||
sftp_server_init
|
||||
sftp_server_new
|
||||
sftp_server_version
|
||||
sftp_setstat
|
||||
sftp_stat
|
||||
sftp_statvfs
|
||||
sftp_statvfs_free
|
||||
sftp_symlink
|
||||
sftp_tell
|
||||
sftp_tell64
|
||||
sftp_unlink
|
||||
sftp_utimes
|
||||
sftp_write
|
||||
ssh_accept
|
||||
ssh_add_channel_callbacks
|
||||
ssh_auth_list
|
||||
ssh_basename
|
||||
ssh_bind_accept
|
||||
ssh_bind_accept_fd
|
||||
ssh_bind_fd_toaccept
|
||||
ssh_bind_free
|
||||
ssh_bind_get_fd
|
||||
ssh_bind_listen
|
||||
ssh_bind_new
|
||||
ssh_bind_options_set
|
||||
ssh_bind_set_blocking
|
||||
ssh_bind_set_callbacks
|
||||
ssh_bind_set_fd
|
||||
ssh_blocking_flush
|
||||
ssh_buffer_add_data
|
||||
ssh_buffer_free
|
||||
ssh_buffer_get
|
||||
ssh_buffer_get_data
|
||||
ssh_buffer_get_len
|
||||
ssh_buffer_new
|
||||
ssh_buffer_reinit
|
||||
ssh_channel_accept_forward
|
||||
ssh_channel_accept_x11
|
||||
ssh_channel_cancel_forward
|
||||
ssh_channel_change_pty_size
|
||||
ssh_channel_close
|
||||
ssh_channel_free
|
||||
ssh_channel_get_exit_status
|
||||
ssh_channel_get_session
|
||||
ssh_channel_is_closed
|
||||
ssh_channel_is_eof
|
||||
ssh_channel_is_open
|
||||
ssh_channel_listen_forward
|
||||
ssh_channel_new
|
||||
ssh_channel_open_auth_agent
|
||||
ssh_channel_open_forward
|
||||
ssh_channel_open_reverse_forward
|
||||
ssh_channel_open_session
|
||||
ssh_channel_open_x11
|
||||
ssh_channel_poll
|
||||
ssh_channel_poll_timeout
|
||||
ssh_channel_read
|
||||
ssh_channel_read_nonblocking
|
||||
ssh_channel_read_timeout
|
||||
ssh_channel_request_auth_agent
|
||||
ssh_channel_request_env
|
||||
ssh_channel_request_exec
|
||||
ssh_channel_request_pty
|
||||
ssh_channel_request_pty_size
|
||||
ssh_channel_request_send_break
|
||||
ssh_channel_request_send_exit_signal
|
||||
ssh_channel_request_send_exit_status
|
||||
ssh_channel_request_send_signal
|
||||
ssh_channel_request_sftp
|
||||
ssh_channel_request_shell
|
||||
ssh_channel_request_subsystem
|
||||
ssh_channel_request_x11
|
||||
ssh_channel_select
|
||||
ssh_channel_send_eof
|
||||
ssh_channel_set_blocking
|
||||
ssh_channel_set_counter
|
||||
ssh_channel_window_size
|
||||
ssh_channel_write
|
||||
ssh_channel_write_stderr
|
||||
ssh_clean_pubkey_hash
|
||||
ssh_connect
|
||||
ssh_connector_free
|
||||
ssh_connector_new
|
||||
ssh_connector_set_in_channel
|
||||
ssh_connector_set_in_fd
|
||||
ssh_connector_set_out_channel
|
||||
ssh_connector_set_out_fd
|
||||
ssh_copyright
|
||||
ssh_dirname
|
||||
ssh_disconnect
|
||||
ssh_dump_knownhost
|
||||
ssh_event_add_connector
|
||||
ssh_event_add_fd
|
||||
ssh_event_add_session
|
||||
ssh_event_dopoll
|
||||
ssh_event_free
|
||||
ssh_event_new
|
||||
ssh_event_remove_connector
|
||||
ssh_event_remove_fd
|
||||
ssh_event_remove_session
|
||||
ssh_execute_message_callbacks
|
||||
ssh_finalize
|
||||
ssh_forward_accept
|
||||
ssh_forward_cancel
|
||||
ssh_forward_listen
|
||||
ssh_free
|
||||
ssh_get_cipher_in
|
||||
ssh_get_cipher_out
|
||||
ssh_get_clientbanner
|
||||
ssh_get_disconnect_message
|
||||
ssh_get_error
|
||||
ssh_get_error_code
|
||||
ssh_get_fd
|
||||
ssh_get_fingerprint_hash
|
||||
ssh_get_hexa
|
||||
ssh_get_hmac_in
|
||||
ssh_get_hmac_out
|
||||
ssh_get_issue_banner
|
||||
ssh_get_kex_algo
|
||||
ssh_get_log_callback
|
||||
ssh_get_log_level
|
||||
ssh_get_log_userdata
|
||||
ssh_get_openssh_version
|
||||
ssh_get_poll_flags
|
||||
ssh_get_pubkey
|
||||
ssh_get_pubkey_hash
|
||||
ssh_get_publickey
|
||||
ssh_get_publickey_hash
|
||||
ssh_get_random
|
||||
ssh_get_server_publickey
|
||||
ssh_get_serverbanner
|
||||
ssh_get_status
|
||||
ssh_get_version
|
||||
ssh_getpass
|
||||
ssh_gssapi_get_creds
|
||||
ssh_gssapi_set_creds
|
||||
ssh_handle_key_exchange
|
||||
ssh_init
|
||||
ssh_is_blocking
|
||||
ssh_is_connected
|
||||
ssh_is_server_known
|
||||
ssh_key_cmp
|
||||
ssh_key_free
|
||||
ssh_key_is_private
|
||||
ssh_key_is_public
|
||||
ssh_key_new
|
||||
ssh_key_type
|
||||
ssh_key_type_from_name
|
||||
ssh_key_type_to_char
|
||||
ssh_known_hosts_parse_line
|
||||
ssh_knownhosts_entry_free
|
||||
ssh_log
|
||||
ssh_message_auth_interactive_request
|
||||
ssh_message_auth_kbdint_is_response
|
||||
ssh_message_auth_password
|
||||
ssh_message_auth_pubkey
|
||||
ssh_message_auth_publickey
|
||||
ssh_message_auth_publickey_state
|
||||
ssh_message_auth_reply_pk_ok
|
||||
ssh_message_auth_reply_pk_ok_simple
|
||||
ssh_message_auth_reply_success
|
||||
ssh_message_auth_set_methods
|
||||
ssh_message_auth_user
|
||||
ssh_message_channel_request_channel
|
||||
ssh_message_channel_request_command
|
||||
ssh_message_channel_request_env_name
|
||||
ssh_message_channel_request_env_value
|
||||
ssh_message_channel_request_open_destination
|
||||
ssh_message_channel_request_open_destination_port
|
||||
ssh_message_channel_request_open_originator
|
||||
ssh_message_channel_request_open_originator_port
|
||||
ssh_message_channel_request_open_reply_accept
|
||||
ssh_message_channel_request_pty_height
|
||||
ssh_message_channel_request_pty_pxheight
|
||||
ssh_message_channel_request_pty_pxwidth
|
||||
ssh_message_channel_request_pty_term
|
||||
ssh_message_channel_request_pty_width
|
||||
ssh_message_channel_request_reply_success
|
||||
ssh_message_channel_request_subsystem
|
||||
ssh_message_channel_request_x11_auth_cookie
|
||||
ssh_message_channel_request_x11_auth_protocol
|
||||
ssh_message_channel_request_x11_screen_number
|
||||
ssh_message_channel_request_x11_single_connection
|
||||
ssh_message_free
|
||||
ssh_message_get
|
||||
ssh_message_global_request_address
|
||||
ssh_message_global_request_port
|
||||
ssh_message_global_request_reply_success
|
||||
ssh_message_reply_default
|
||||
ssh_message_retrieve
|
||||
ssh_message_service_reply_success
|
||||
ssh_message_service_service
|
||||
ssh_message_subtype
|
||||
ssh_message_type
|
||||
ssh_mkdir
|
||||
ssh_new
|
||||
ssh_options_copy
|
||||
ssh_options_get
|
||||
ssh_options_get_port
|
||||
ssh_options_getopt
|
||||
ssh_options_parse_config
|
||||
ssh_options_set
|
||||
ssh_pcap_file_close
|
||||
ssh_pcap_file_free
|
||||
ssh_pcap_file_new
|
||||
ssh_pcap_file_open
|
||||
ssh_pki_copy_cert_to_privkey
|
||||
ssh_pki_export_privkey_base64
|
||||
ssh_pki_export_privkey_file
|
||||
ssh_pki_export_privkey_to_pubkey
|
||||
ssh_pki_export_pubkey_base64
|
||||
ssh_pki_export_pubkey_file
|
||||
ssh_pki_generate
|
||||
ssh_pki_import_cert_base64
|
||||
ssh_pki_import_cert_file
|
||||
ssh_pki_import_privkey_base64
|
||||
ssh_pki_import_privkey_file
|
||||
ssh_pki_import_pubkey_base64
|
||||
ssh_pki_import_pubkey_file
|
||||
ssh_pki_key_ecdsa_name
|
||||
ssh_print_hash
|
||||
ssh_print_hexa
|
||||
ssh_privatekey_type
|
||||
ssh_publickey_to_file
|
||||
ssh_remove_channel_callbacks
|
||||
ssh_scp_accept_request
|
||||
ssh_scp_close
|
||||
ssh_scp_deny_request
|
||||
ssh_scp_free
|
||||
ssh_scp_init
|
||||
ssh_scp_leave_directory
|
||||
ssh_scp_new
|
||||
ssh_scp_pull_request
|
||||
ssh_scp_push_directory
|
||||
ssh_scp_push_file
|
||||
ssh_scp_push_file64
|
||||
ssh_scp_read
|
||||
ssh_scp_request_get_filename
|
||||
ssh_scp_request_get_permissions
|
||||
ssh_scp_request_get_size
|
||||
ssh_scp_request_get_size64
|
||||
ssh_scp_request_get_warning
|
||||
ssh_scp_write
|
||||
ssh_select
|
||||
ssh_send_debug
|
||||
ssh_send_ignore
|
||||
ssh_send_keepalive
|
||||
ssh_server_init_kex
|
||||
ssh_service_request
|
||||
ssh_session_export_known_hosts_entry
|
||||
ssh_session_has_known_hosts_entry
|
||||
ssh_session_is_known_server
|
||||
ssh_session_update_known_hosts
|
||||
ssh_set_agent_channel
|
||||
ssh_set_agent_socket
|
||||
ssh_set_auth_methods
|
||||
ssh_set_blocking
|
||||
ssh_set_callbacks
|
||||
ssh_set_channel_callbacks
|
||||
ssh_set_counters
|
||||
ssh_set_fd_except
|
||||
ssh_set_fd_toread
|
||||
ssh_set_fd_towrite
|
||||
ssh_set_log_callback
|
||||
ssh_set_log_level
|
||||
ssh_set_log_userdata
|
||||
ssh_set_message_callback
|
||||
ssh_set_pcap_file
|
||||
ssh_set_server_callbacks
|
||||
ssh_silent_disconnect
|
||||
ssh_string_burn
|
||||
ssh_string_copy
|
||||
ssh_string_data
|
||||
ssh_string_fill
|
||||
ssh_string_free
|
||||
ssh_string_free_char
|
||||
ssh_string_from_char
|
||||
ssh_string_get_char
|
||||
ssh_string_len
|
||||
ssh_string_new
|
||||
ssh_string_to_char
|
||||
ssh_threads_get_noop
|
||||
ssh_threads_get_pthread
|
||||
ssh_threads_set_callbacks
|
||||
ssh_try_publickey_from_file
|
||||
ssh_userauth_agent
|
||||
ssh_userauth_agent_pubkey
|
||||
ssh_userauth_autopubkey
|
||||
ssh_userauth_gssapi
|
||||
ssh_userauth_kbdint
|
||||
ssh_userauth_kbdint_getanswer
|
||||
ssh_userauth_kbdint_getinstruction
|
||||
ssh_userauth_kbdint_getname
|
||||
ssh_userauth_kbdint_getnanswers
|
||||
ssh_userauth_kbdint_getnprompts
|
||||
ssh_userauth_kbdint_getprompt
|
||||
ssh_userauth_kbdint_setanswer
|
||||
ssh_userauth_list
|
||||
ssh_userauth_none
|
||||
ssh_userauth_offer_pubkey
|
||||
ssh_userauth_password
|
||||
ssh_userauth_privatekey_file
|
||||
ssh_userauth_pubkey
|
||||
ssh_userauth_publickey
|
||||
ssh_userauth_publickey_auto
|
||||
ssh_userauth_try_publickey
|
||||
ssh_version
|
||||
ssh_write_knownhost
|
||||
string_burn
|
||||
string_copy
|
||||
string_data
|
||||
string_fill
|
||||
string_free
|
||||
string_from_char
|
||||
string_len
|
||||
string_new
|
||||
string_to_char
|
||||
415
src/ABI/libssh-4.7.6.symbols
Normal file
415
src/ABI/libssh-4.7.6.symbols
Normal file
@@ -0,0 +1,415 @@
|
||||
_ssh_log
|
||||
buffer_free
|
||||
buffer_get
|
||||
buffer_get_len
|
||||
buffer_new
|
||||
channel_accept_x11
|
||||
channel_change_pty_size
|
||||
channel_close
|
||||
channel_forward_accept
|
||||
channel_forward_cancel
|
||||
channel_forward_listen
|
||||
channel_free
|
||||
channel_get_exit_status
|
||||
channel_get_session
|
||||
channel_is_closed
|
||||
channel_is_eof
|
||||
channel_is_open
|
||||
channel_new
|
||||
channel_open_forward
|
||||
channel_open_session
|
||||
channel_poll
|
||||
channel_read
|
||||
channel_read_buffer
|
||||
channel_read_nonblocking
|
||||
channel_request_env
|
||||
channel_request_exec
|
||||
channel_request_pty
|
||||
channel_request_pty_size
|
||||
channel_request_send_signal
|
||||
channel_request_sftp
|
||||
channel_request_shell
|
||||
channel_request_subsystem
|
||||
channel_request_x11
|
||||
channel_select
|
||||
channel_send_eof
|
||||
channel_set_blocking
|
||||
channel_write
|
||||
channel_write_stderr
|
||||
privatekey_free
|
||||
privatekey_from_file
|
||||
publickey_free
|
||||
publickey_from_file
|
||||
publickey_from_privatekey
|
||||
publickey_to_string
|
||||
sftp_async_read
|
||||
sftp_async_read_begin
|
||||
sftp_attributes_free
|
||||
sftp_canonicalize_path
|
||||
sftp_chmod
|
||||
sftp_chown
|
||||
sftp_client_message_free
|
||||
sftp_client_message_get_data
|
||||
sftp_client_message_get_filename
|
||||
sftp_client_message_get_flags
|
||||
sftp_client_message_get_submessage
|
||||
sftp_client_message_get_type
|
||||
sftp_client_message_set_filename
|
||||
sftp_close
|
||||
sftp_closedir
|
||||
sftp_dir_eof
|
||||
sftp_extension_supported
|
||||
sftp_extensions_get_count
|
||||
sftp_extensions_get_data
|
||||
sftp_extensions_get_name
|
||||
sftp_file_set_blocking
|
||||
sftp_file_set_nonblocking
|
||||
sftp_free
|
||||
sftp_fstat
|
||||
sftp_fstatvfs
|
||||
sftp_fsync
|
||||
sftp_get_client_message
|
||||
sftp_get_error
|
||||
sftp_handle
|
||||
sftp_handle_alloc
|
||||
sftp_handle_remove
|
||||
sftp_init
|
||||
sftp_lstat
|
||||
sftp_mkdir
|
||||
sftp_new
|
||||
sftp_new_channel
|
||||
sftp_open
|
||||
sftp_opendir
|
||||
sftp_read
|
||||
sftp_readdir
|
||||
sftp_readlink
|
||||
sftp_rename
|
||||
sftp_reply_attr
|
||||
sftp_reply_data
|
||||
sftp_reply_handle
|
||||
sftp_reply_name
|
||||
sftp_reply_names
|
||||
sftp_reply_names_add
|
||||
sftp_reply_status
|
||||
sftp_rewind
|
||||
sftp_rmdir
|
||||
sftp_seek
|
||||
sftp_seek64
|
||||
sftp_send_client_message
|
||||
sftp_server_init
|
||||
sftp_server_new
|
||||
sftp_server_version
|
||||
sftp_setstat
|
||||
sftp_stat
|
||||
sftp_statvfs
|
||||
sftp_statvfs_free
|
||||
sftp_symlink
|
||||
sftp_tell
|
||||
sftp_tell64
|
||||
sftp_unlink
|
||||
sftp_utimes
|
||||
sftp_write
|
||||
ssh_accept
|
||||
ssh_add_channel_callbacks
|
||||
ssh_auth_list
|
||||
ssh_basename
|
||||
ssh_bind_accept
|
||||
ssh_bind_accept_fd
|
||||
ssh_bind_fd_toaccept
|
||||
ssh_bind_free
|
||||
ssh_bind_get_fd
|
||||
ssh_bind_listen
|
||||
ssh_bind_new
|
||||
ssh_bind_options_set
|
||||
ssh_bind_set_blocking
|
||||
ssh_bind_set_callbacks
|
||||
ssh_bind_set_fd
|
||||
ssh_blocking_flush
|
||||
ssh_buffer_add_data
|
||||
ssh_buffer_free
|
||||
ssh_buffer_get
|
||||
ssh_buffer_get_data
|
||||
ssh_buffer_get_len
|
||||
ssh_buffer_new
|
||||
ssh_buffer_reinit
|
||||
ssh_channel_accept_forward
|
||||
ssh_channel_accept_x11
|
||||
ssh_channel_cancel_forward
|
||||
ssh_channel_change_pty_size
|
||||
ssh_channel_close
|
||||
ssh_channel_free
|
||||
ssh_channel_get_exit_status
|
||||
ssh_channel_get_session
|
||||
ssh_channel_is_closed
|
||||
ssh_channel_is_eof
|
||||
ssh_channel_is_open
|
||||
ssh_channel_listen_forward
|
||||
ssh_channel_new
|
||||
ssh_channel_open_auth_agent
|
||||
ssh_channel_open_forward
|
||||
ssh_channel_open_reverse_forward
|
||||
ssh_channel_open_session
|
||||
ssh_channel_open_x11
|
||||
ssh_channel_poll
|
||||
ssh_channel_poll_timeout
|
||||
ssh_channel_read
|
||||
ssh_channel_read_nonblocking
|
||||
ssh_channel_read_timeout
|
||||
ssh_channel_request_auth_agent
|
||||
ssh_channel_request_env
|
||||
ssh_channel_request_exec
|
||||
ssh_channel_request_pty
|
||||
ssh_channel_request_pty_size
|
||||
ssh_channel_request_send_break
|
||||
ssh_channel_request_send_exit_signal
|
||||
ssh_channel_request_send_exit_status
|
||||
ssh_channel_request_send_signal
|
||||
ssh_channel_request_sftp
|
||||
ssh_channel_request_shell
|
||||
ssh_channel_request_subsystem
|
||||
ssh_channel_request_x11
|
||||
ssh_channel_select
|
||||
ssh_channel_send_eof
|
||||
ssh_channel_set_blocking
|
||||
ssh_channel_set_counter
|
||||
ssh_channel_window_size
|
||||
ssh_channel_write
|
||||
ssh_channel_write_stderr
|
||||
ssh_clean_pubkey_hash
|
||||
ssh_connect
|
||||
ssh_connector_free
|
||||
ssh_connector_new
|
||||
ssh_connector_set_in_channel
|
||||
ssh_connector_set_in_fd
|
||||
ssh_connector_set_out_channel
|
||||
ssh_connector_set_out_fd
|
||||
ssh_copyright
|
||||
ssh_dirname
|
||||
ssh_disconnect
|
||||
ssh_dump_knownhost
|
||||
ssh_event_add_connector
|
||||
ssh_event_add_fd
|
||||
ssh_event_add_session
|
||||
ssh_event_dopoll
|
||||
ssh_event_free
|
||||
ssh_event_new
|
||||
ssh_event_remove_connector
|
||||
ssh_event_remove_fd
|
||||
ssh_event_remove_session
|
||||
ssh_execute_message_callbacks
|
||||
ssh_finalize
|
||||
ssh_forward_accept
|
||||
ssh_forward_cancel
|
||||
ssh_forward_listen
|
||||
ssh_free
|
||||
ssh_get_cipher_in
|
||||
ssh_get_cipher_out
|
||||
ssh_get_clientbanner
|
||||
ssh_get_disconnect_message
|
||||
ssh_get_error
|
||||
ssh_get_error_code
|
||||
ssh_get_fd
|
||||
ssh_get_fingerprint_hash
|
||||
ssh_get_hexa
|
||||
ssh_get_hmac_in
|
||||
ssh_get_hmac_out
|
||||
ssh_get_issue_banner
|
||||
ssh_get_kex_algo
|
||||
ssh_get_log_callback
|
||||
ssh_get_log_level
|
||||
ssh_get_log_userdata
|
||||
ssh_get_openssh_version
|
||||
ssh_get_poll_flags
|
||||
ssh_get_pubkey
|
||||
ssh_get_pubkey_hash
|
||||
ssh_get_publickey
|
||||
ssh_get_publickey_hash
|
||||
ssh_get_random
|
||||
ssh_get_server_publickey
|
||||
ssh_get_serverbanner
|
||||
ssh_get_status
|
||||
ssh_get_version
|
||||
ssh_getpass
|
||||
ssh_gssapi_get_creds
|
||||
ssh_gssapi_set_creds
|
||||
ssh_handle_key_exchange
|
||||
ssh_init
|
||||
ssh_is_blocking
|
||||
ssh_is_connected
|
||||
ssh_is_server_known
|
||||
ssh_key_cmp
|
||||
ssh_key_free
|
||||
ssh_key_is_private
|
||||
ssh_key_is_public
|
||||
ssh_key_new
|
||||
ssh_key_type
|
||||
ssh_key_type_from_name
|
||||
ssh_key_type_to_char
|
||||
ssh_known_hosts_parse_line
|
||||
ssh_knownhosts_entry_free
|
||||
ssh_log
|
||||
ssh_message_auth_interactive_request
|
||||
ssh_message_auth_kbdint_is_response
|
||||
ssh_message_auth_password
|
||||
ssh_message_auth_pubkey
|
||||
ssh_message_auth_publickey
|
||||
ssh_message_auth_publickey_state
|
||||
ssh_message_auth_reply_pk_ok
|
||||
ssh_message_auth_reply_pk_ok_simple
|
||||
ssh_message_auth_reply_success
|
||||
ssh_message_auth_set_methods
|
||||
ssh_message_auth_user
|
||||
ssh_message_channel_request_channel
|
||||
ssh_message_channel_request_command
|
||||
ssh_message_channel_request_env_name
|
||||
ssh_message_channel_request_env_value
|
||||
ssh_message_channel_request_open_destination
|
||||
ssh_message_channel_request_open_destination_port
|
||||
ssh_message_channel_request_open_originator
|
||||
ssh_message_channel_request_open_originator_port
|
||||
ssh_message_channel_request_open_reply_accept
|
||||
ssh_message_channel_request_pty_height
|
||||
ssh_message_channel_request_pty_pxheight
|
||||
ssh_message_channel_request_pty_pxwidth
|
||||
ssh_message_channel_request_pty_term
|
||||
ssh_message_channel_request_pty_width
|
||||
ssh_message_channel_request_reply_success
|
||||
ssh_message_channel_request_subsystem
|
||||
ssh_message_channel_request_x11_auth_cookie
|
||||
ssh_message_channel_request_x11_auth_protocol
|
||||
ssh_message_channel_request_x11_screen_number
|
||||
ssh_message_channel_request_x11_single_connection
|
||||
ssh_message_free
|
||||
ssh_message_get
|
||||
ssh_message_global_request_address
|
||||
ssh_message_global_request_port
|
||||
ssh_message_global_request_reply_success
|
||||
ssh_message_reply_default
|
||||
ssh_message_retrieve
|
||||
ssh_message_service_reply_success
|
||||
ssh_message_service_service
|
||||
ssh_message_subtype
|
||||
ssh_message_type
|
||||
ssh_mkdir
|
||||
ssh_new
|
||||
ssh_options_copy
|
||||
ssh_options_get
|
||||
ssh_options_get_port
|
||||
ssh_options_getopt
|
||||
ssh_options_parse_config
|
||||
ssh_options_set
|
||||
ssh_pcap_file_close
|
||||
ssh_pcap_file_free
|
||||
ssh_pcap_file_new
|
||||
ssh_pcap_file_open
|
||||
ssh_pki_copy_cert_to_privkey
|
||||
ssh_pki_export_privkey_base64
|
||||
ssh_pki_export_privkey_file
|
||||
ssh_pki_export_privkey_to_pubkey
|
||||
ssh_pki_export_pubkey_base64
|
||||
ssh_pki_export_pubkey_file
|
||||
ssh_pki_generate
|
||||
ssh_pki_import_cert_base64
|
||||
ssh_pki_import_cert_file
|
||||
ssh_pki_import_privkey_base64
|
||||
ssh_pki_import_privkey_file
|
||||
ssh_pki_import_pubkey_base64
|
||||
ssh_pki_import_pubkey_file
|
||||
ssh_pki_key_ecdsa_name
|
||||
ssh_print_hash
|
||||
ssh_print_hexa
|
||||
ssh_privatekey_type
|
||||
ssh_publickey_to_file
|
||||
ssh_remove_channel_callbacks
|
||||
ssh_scp_accept_request
|
||||
ssh_scp_close
|
||||
ssh_scp_deny_request
|
||||
ssh_scp_free
|
||||
ssh_scp_init
|
||||
ssh_scp_leave_directory
|
||||
ssh_scp_new
|
||||
ssh_scp_pull_request
|
||||
ssh_scp_push_directory
|
||||
ssh_scp_push_file
|
||||
ssh_scp_push_file64
|
||||
ssh_scp_read
|
||||
ssh_scp_request_get_filename
|
||||
ssh_scp_request_get_permissions
|
||||
ssh_scp_request_get_size
|
||||
ssh_scp_request_get_size64
|
||||
ssh_scp_request_get_warning
|
||||
ssh_scp_write
|
||||
ssh_select
|
||||
ssh_send_debug
|
||||
ssh_send_ignore
|
||||
ssh_send_keepalive
|
||||
ssh_server_init_kex
|
||||
ssh_service_request
|
||||
ssh_session_export_known_hosts_entry
|
||||
ssh_session_has_known_hosts_entry
|
||||
ssh_session_is_known_server
|
||||
ssh_session_update_known_hosts
|
||||
ssh_set_agent_channel
|
||||
ssh_set_agent_socket
|
||||
ssh_set_auth_methods
|
||||
ssh_set_blocking
|
||||
ssh_set_callbacks
|
||||
ssh_set_channel_callbacks
|
||||
ssh_set_counters
|
||||
ssh_set_fd_except
|
||||
ssh_set_fd_toread
|
||||
ssh_set_fd_towrite
|
||||
ssh_set_log_callback
|
||||
ssh_set_log_level
|
||||
ssh_set_log_userdata
|
||||
ssh_set_message_callback
|
||||
ssh_set_pcap_file
|
||||
ssh_set_server_callbacks
|
||||
ssh_silent_disconnect
|
||||
ssh_string_burn
|
||||
ssh_string_copy
|
||||
ssh_string_data
|
||||
ssh_string_fill
|
||||
ssh_string_free
|
||||
ssh_string_free_char
|
||||
ssh_string_from_char
|
||||
ssh_string_get_char
|
||||
ssh_string_len
|
||||
ssh_string_new
|
||||
ssh_string_to_char
|
||||
ssh_threads_get_noop
|
||||
ssh_threads_get_pthread
|
||||
ssh_threads_set_callbacks
|
||||
ssh_try_publickey_from_file
|
||||
ssh_userauth_agent
|
||||
ssh_userauth_agent_pubkey
|
||||
ssh_userauth_autopubkey
|
||||
ssh_userauth_gssapi
|
||||
ssh_userauth_kbdint
|
||||
ssh_userauth_kbdint_getanswer
|
||||
ssh_userauth_kbdint_getinstruction
|
||||
ssh_userauth_kbdint_getname
|
||||
ssh_userauth_kbdint_getnanswers
|
||||
ssh_userauth_kbdint_getnprompts
|
||||
ssh_userauth_kbdint_getprompt
|
||||
ssh_userauth_kbdint_setanswer
|
||||
ssh_userauth_list
|
||||
ssh_userauth_none
|
||||
ssh_userauth_offer_pubkey
|
||||
ssh_userauth_password
|
||||
ssh_userauth_privatekey_file
|
||||
ssh_userauth_pubkey
|
||||
ssh_userauth_publickey
|
||||
ssh_userauth_publickey_auto
|
||||
ssh_userauth_try_publickey
|
||||
ssh_version
|
||||
ssh_write_knownhost
|
||||
string_burn
|
||||
string_copy
|
||||
string_data
|
||||
string_fill
|
||||
string_free
|
||||
string_from_char
|
||||
string_len
|
||||
string_new
|
||||
string_to_char
|
||||
@@ -93,7 +93,7 @@ static size_t atomicio(struct ssh_agent_struct *agent, void *buf, size_t n, int
|
||||
|
||||
/* Using a socket ? */
|
||||
if (channel == NULL) {
|
||||
fd = ssh_socket_get_fd_in(agent->sock);
|
||||
fd = ssh_socket_get_fd(agent->sock);
|
||||
pfd.fd = fd;
|
||||
pfd.events = do_read ? POLLIN : POLLOUT;
|
||||
|
||||
|
||||
@@ -447,7 +447,7 @@ int ssh_bind_accept_fd(ssh_bind sshbind, ssh_session session, socket_t fd){
|
||||
return SSH_ERROR;
|
||||
}
|
||||
ssh_socket_set_fd(session->socket, fd);
|
||||
ssh_socket_get_poll_handle_out(session->socket);
|
||||
ssh_socket_get_poll_handle(session->socket);
|
||||
|
||||
/* We must try to import any keys that could be imported in case
|
||||
* we are not using ssh_bind_listen (which is the other place
|
||||
|
||||
158
src/channels.c
158
src/channels.c
@@ -28,6 +28,7 @@
|
||||
#include <stdio.h>
|
||||
#include <errno.h>
|
||||
#include <time.h>
|
||||
#include <stdbool.h>
|
||||
|
||||
#ifndef _WIN32
|
||||
#include <netinet/in.h>
|
||||
@@ -999,28 +1000,50 @@ error:
|
||||
*
|
||||
* @warning Any data unread on this channel will be lost.
|
||||
*/
|
||||
void ssh_channel_free(ssh_channel channel) {
|
||||
ssh_session session;
|
||||
void ssh_channel_free(ssh_channel channel)
|
||||
{
|
||||
ssh_session session;
|
||||
|
||||
if (channel == NULL) {
|
||||
return;
|
||||
}
|
||||
if (channel == NULL) {
|
||||
return;
|
||||
}
|
||||
|
||||
session = channel->session;
|
||||
if (session->alive && channel->state == SSH_CHANNEL_STATE_OPEN) {
|
||||
ssh_channel_close(channel);
|
||||
}
|
||||
channel->flags |= SSH_CHANNEL_FLAG_FREED_LOCAL;
|
||||
session = channel->session;
|
||||
if (session->alive) {
|
||||
bool send_close = false;
|
||||
|
||||
/* The idea behind the flags is the following : it is well possible
|
||||
* that a client closes a channel that stills exists on the server side.
|
||||
* We definitively close the channel when we receive a close message *and*
|
||||
* the user closed it.
|
||||
*/
|
||||
if((channel->flags & SSH_CHANNEL_FLAG_CLOSED_REMOTE)
|
||||
|| (channel->flags & SSH_CHANNEL_FLAG_NOT_BOUND)){
|
||||
ssh_channel_do_free(channel);
|
||||
}
|
||||
switch (channel->state) {
|
||||
case SSH_CHANNEL_STATE_OPEN:
|
||||
send_close = true;
|
||||
break;
|
||||
case SSH_CHANNEL_STATE_CLOSED:
|
||||
if (channel->flags & SSH_CHANNEL_FLAG_CLOSED_REMOTE) {
|
||||
send_close = true;
|
||||
}
|
||||
if (channel->flags & SSH_CHANNEL_FLAG_CLOSED_LOCAL) {
|
||||
send_close = false;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
send_close = false;
|
||||
break;
|
||||
}
|
||||
|
||||
if (send_close) {
|
||||
ssh_channel_close(channel);
|
||||
}
|
||||
}
|
||||
channel->flags |= SSH_CHANNEL_FLAG_FREED_LOCAL;
|
||||
|
||||
/* The idea behind the flags is the following : it is well possible
|
||||
* that a client closes a channel that stills exists on the server side.
|
||||
* We definitively close the channel when we receive a close message *and*
|
||||
* the user closed it.
|
||||
*/
|
||||
if ((channel->flags & SSH_CHANNEL_FLAG_CLOSED_REMOTE) ||
|
||||
(channel->flags & SSH_CHANNEL_FLAG_NOT_BOUND)) {
|
||||
ssh_channel_do_free(channel);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1128,52 +1151,60 @@ error:
|
||||
* @see ssh_channel_free()
|
||||
* @see ssh_channel_is_eof()
|
||||
*/
|
||||
int ssh_channel_close(ssh_channel channel){
|
||||
ssh_session session;
|
||||
int rc = 0;
|
||||
int ssh_channel_close(ssh_channel channel)
|
||||
{
|
||||
ssh_session session;
|
||||
int rc = 0;
|
||||
|
||||
if(channel == NULL) {
|
||||
return SSH_ERROR;
|
||||
}
|
||||
if(channel == NULL) {
|
||||
return SSH_ERROR;
|
||||
}
|
||||
|
||||
session = channel->session;
|
||||
/* If the channel close has already been sent we're done here. */
|
||||
if (channel->flags & SSH_CHANNEL_FLAG_CLOSED_LOCAL) {
|
||||
return SSH_OK;
|
||||
}
|
||||
|
||||
if (channel->local_eof == 0) {
|
||||
rc = ssh_channel_send_eof(channel);
|
||||
}
|
||||
session = channel->session;
|
||||
|
||||
if (channel->local_eof == 0) {
|
||||
rc = ssh_channel_send_eof(channel);
|
||||
}
|
||||
|
||||
if (rc != SSH_OK) {
|
||||
return rc;
|
||||
}
|
||||
|
||||
rc = ssh_buffer_pack(session->out_buffer,
|
||||
"bd",
|
||||
SSH2_MSG_CHANNEL_CLOSE,
|
||||
channel->remote_channel);
|
||||
if (rc != SSH_OK) {
|
||||
ssh_set_error_oom(session);
|
||||
goto error;
|
||||
}
|
||||
|
||||
rc = ssh_packet_send(session);
|
||||
SSH_LOG(SSH_LOG_PACKET,
|
||||
"Sent a close on client channel (%d:%d)",
|
||||
channel->local_channel,
|
||||
channel->remote_channel);
|
||||
|
||||
if (rc == SSH_OK) {
|
||||
channel->state = SSH_CHANNEL_STATE_CLOSED;
|
||||
channel->flags |= SSH_CHANNEL_FLAG_CLOSED_LOCAL;
|
||||
}
|
||||
|
||||
rc = ssh_channel_flush(channel);
|
||||
if(rc == SSH_ERROR) {
|
||||
goto error;
|
||||
}
|
||||
|
||||
if (rc != SSH_OK) {
|
||||
return rc;
|
||||
}
|
||||
|
||||
rc = ssh_buffer_pack(session->out_buffer,
|
||||
"bd",
|
||||
SSH2_MSG_CHANNEL_CLOSE,
|
||||
channel->remote_channel);
|
||||
if (rc != SSH_OK) {
|
||||
ssh_set_error_oom(session);
|
||||
goto error;
|
||||
}
|
||||
|
||||
rc = ssh_packet_send(session);
|
||||
SSH_LOG(SSH_LOG_PACKET,
|
||||
"Sent a close on client channel (%d:%d)",
|
||||
channel->local_channel,
|
||||
channel->remote_channel);
|
||||
|
||||
if(rc == SSH_OK) {
|
||||
channel->state=SSH_CHANNEL_STATE_CLOSED;
|
||||
}
|
||||
|
||||
rc = ssh_channel_flush(channel);
|
||||
if(rc == SSH_ERROR)
|
||||
goto error;
|
||||
|
||||
return rc;
|
||||
error:
|
||||
ssh_buffer_reinit(session->out_buffer);
|
||||
ssh_buffer_reinit(session->out_buffer);
|
||||
|
||||
return rc;
|
||||
return rc;
|
||||
}
|
||||
|
||||
/* this termination function waits for a window growing condition */
|
||||
@@ -2082,8 +2113,11 @@ static int ssh_global_request_termination(void *s){
|
||||
* SSH_AGAIN if in nonblocking mode and call has
|
||||
* to be done again.
|
||||
*/
|
||||
static int global_request(ssh_session session, const char *request,
|
||||
ssh_buffer buffer, int reply) {
|
||||
int ssh_global_request(ssh_session session,
|
||||
const char *request,
|
||||
ssh_buffer buffer,
|
||||
int reply)
|
||||
{
|
||||
int rc;
|
||||
|
||||
switch (session->global_req_state) {
|
||||
@@ -2214,7 +2248,7 @@ int ssh_channel_listen_forward(ssh_session session,
|
||||
goto error;
|
||||
}
|
||||
pending:
|
||||
rc = global_request(session, "tcpip-forward", buffer, 1);
|
||||
rc = ssh_global_request(session, "tcpip-forward", buffer, 1);
|
||||
|
||||
/* TODO: FIXME no guarantee the last packet we received contains
|
||||
* that info */
|
||||
@@ -2294,7 +2328,7 @@ int ssh_channel_cancel_forward(ssh_session session,
|
||||
goto error;
|
||||
}
|
||||
pending:
|
||||
rc = global_request(session, "cancel-tcpip-forward", buffer, 1);
|
||||
rc = ssh_global_request(session, "cancel-tcpip-forward", buffer, 1);
|
||||
|
||||
error:
|
||||
ssh_buffer_free(buffer);
|
||||
|
||||
27
src/client.c
27
src/client.c
@@ -411,6 +411,14 @@ static void ssh_client_connection_callback(ssh_session session)
|
||||
|
||||
ssh_packet_set_default_callbacks(session);
|
||||
session->session_state = SSH_SESSION_STATE_INITIAL_KEX;
|
||||
rc = ssh_set_client_kex(session);
|
||||
if (rc != SSH_OK) {
|
||||
goto error;
|
||||
}
|
||||
rc = ssh_send_kex(session, 0);
|
||||
if (rc < 0) {
|
||||
goto error;
|
||||
}
|
||||
set_status(session, 0.5f);
|
||||
|
||||
break;
|
||||
@@ -420,14 +428,19 @@ static void ssh_client_connection_callback(ssh_session session)
|
||||
case SSH_SESSION_STATE_KEXINIT_RECEIVED:
|
||||
set_status(session,0.6f);
|
||||
ssh_list_kex(&session->next_crypto->server_kex);
|
||||
if (ssh_set_client_kex(session) < 0) {
|
||||
goto error;
|
||||
if (session->next_crypto->client_kex.methods[0] == NULL) {
|
||||
/* in rekeying state if next_crypto client_kex is empty */
|
||||
rc = ssh_set_client_kex(session);
|
||||
if (rc != SSH_OK) {
|
||||
goto error;
|
||||
}
|
||||
rc = ssh_send_kex(session, 0);
|
||||
if (rc < 0) {
|
||||
goto error;
|
||||
}
|
||||
}
|
||||
if (ssh_kex_select_methods(session) == SSH_ERROR)
|
||||
goto error;
|
||||
if (ssh_send_kex(session, 0) < 0) {
|
||||
goto error;
|
||||
}
|
||||
set_status(session,0.8f);
|
||||
session->session_state=SSH_SESSION_STATE_DH;
|
||||
if (dh_handshake(session) == SSH_ERROR) {
|
||||
@@ -481,8 +494,8 @@ static int ssh_connect_termination(void *user){
|
||||
* @param[in] session The ssh session to connect.
|
||||
*
|
||||
* @returns SSH_OK on success, SSH_ERROR on error.
|
||||
* @returns SSH_AGAIN, if the session is in nonblocking mode,
|
||||
* and call must be done again.
|
||||
* @returns SSH_AGAIN, if the session is in nonblocking mode,
|
||||
* and call must be done again.
|
||||
*
|
||||
* @see ssh_new()
|
||||
* @see ssh_disconnect()
|
||||
|
||||
@@ -210,6 +210,7 @@ static struct ssh_config_match_keyword_table_s ssh_config_match_keyword_table[]
|
||||
{ "originalhost", MATCH_ORIGINALHOST },
|
||||
{ "user", MATCH_USER },
|
||||
{ "localuser", MATCH_LOCALUSER },
|
||||
{ NULL, MATCH_UNKNOWN },
|
||||
};
|
||||
|
||||
static int ssh_config_parse_line(ssh_session session, const char *line,
|
||||
|
||||
@@ -476,7 +476,7 @@ int ssh_select(ssh_channel *channels, ssh_channel *outchannels, socket_t maxfd,
|
||||
fd_set *readfds, struct timeval *timeout) {
|
||||
fd_set origfds;
|
||||
socket_t fd;
|
||||
int i,j;
|
||||
size_t i, j;
|
||||
int rc;
|
||||
int base_tm, tm;
|
||||
struct ssh_timestamp ts;
|
||||
|
||||
@@ -641,14 +641,12 @@ int ssh_connector_remove_event(ssh_connector connector) {
|
||||
session = ssh_channel_get_session(connector->in_channel);
|
||||
|
||||
ssh_event_remove_session(connector->event, session);
|
||||
connector->in_channel = NULL;
|
||||
}
|
||||
|
||||
if (connector->out_channel != NULL) {
|
||||
session = ssh_channel_get_session(connector->out_channel);
|
||||
|
||||
ssh_event_remove_session(connector->event, session);
|
||||
connector->out_channel = NULL;
|
||||
}
|
||||
connector->event = NULL;
|
||||
|
||||
|
||||
4
src/dh.c
4
src/dh.c
@@ -1274,6 +1274,10 @@ int ssh_get_server_publickey(ssh_session session, ssh_key *key)
|
||||
|
||||
ssh_key ssh_dh_get_current_server_publickey(ssh_session session)
|
||||
{
|
||||
if (session->current_crypto == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return session->current_crypto->server_pubkey;
|
||||
}
|
||||
|
||||
|
||||
@@ -286,7 +286,7 @@ int ssh_server_ecdh_init(ssh_session session, ssh_buffer packet) {
|
||||
session->next_crypto->ecdh_client_pubkey = q_c_string;
|
||||
|
||||
/* Build server's keypair */
|
||||
err = gcry_sexp_build(¶m, NULL, "(genkey(ecdh(curve %s)))",
|
||||
err = gcry_sexp_build(¶m, NULL, "(genkey(ecdh(curve %s) (flags transient-key)))",
|
||||
curve);
|
||||
if (err) {
|
||||
goto out;
|
||||
|
||||
@@ -120,6 +120,7 @@ static int ssh_gssapi_send_response(ssh_session session, ssh_string oid){
|
||||
ssh_set_error_oom(session);
|
||||
return SSH_ERROR;
|
||||
}
|
||||
session->auth.state = SSH_AUTH_STATE_GSSAPI_TOKEN;
|
||||
|
||||
ssh_packet_send(session);
|
||||
SSH_LOG(SSH_LOG_PACKET,
|
||||
|
||||
126
src/kex.c
126
src/kex.c
@@ -26,6 +26,7 @@
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <stdbool.h>
|
||||
|
||||
#include "libssh/priv.h"
|
||||
#include "libssh/buffer.h"
|
||||
@@ -37,6 +38,7 @@
|
||||
#include "libssh/curve25519.h"
|
||||
#include "libssh/knownhosts.h"
|
||||
#include "libssh/misc.h"
|
||||
#include "libssh/pki.h"
|
||||
|
||||
#ifdef HAVE_LIBGCRYPT
|
||||
# define BLOWFISH "blowfish-cbc,"
|
||||
@@ -419,6 +421,7 @@ SSH_PACKET_CALLBACK(ssh_packet_kexinit){
|
||||
int server_kex=session->server;
|
||||
ssh_string str = NULL;
|
||||
char *strings[KEX_METHODS_SIZE] = {0};
|
||||
char *rsa_sig_ext = NULL;
|
||||
int rc = SSH_ERROR;
|
||||
|
||||
uint8_t first_kex_packet_follows = 0;
|
||||
@@ -525,13 +528,52 @@ SSH_PACKET_CALLBACK(ssh_packet_kexinit){
|
||||
ok = ssh_match_group(session->next_crypto->client_kex.methods[SSH_KEX],
|
||||
KEX_EXTENSION_CLIENT);
|
||||
if (ok) {
|
||||
const char *hostkeys = NULL;
|
||||
|
||||
/* The client supports extension negotiation */
|
||||
session->extensions |= SSH_EXT_NEGOTIATION;
|
||||
/*
|
||||
* Enable all the supported extensions and when the time comes
|
||||
* (after NEWKEYS) send them to the client.
|
||||
* RFC 8332 Section 3.1: Use for Server Authentication
|
||||
* Check what algorithms were provided in the SSH_HOSTKEYS list
|
||||
* by the client and enable the respective extensions to provide
|
||||
* correct signature in the next packet if RSA is negotiated
|
||||
*/
|
||||
hostkeys = session->next_crypto->client_kex.methods[SSH_HOSTKEYS];
|
||||
ok = ssh_match_group(hostkeys, "rsa-sha2-512");
|
||||
if (ok) {
|
||||
session->extensions |= SSH_EXT_SIG_RSA_SHA512;
|
||||
}
|
||||
ok = ssh_match_group(hostkeys, "rsa-sha2-256");
|
||||
if (ok) {
|
||||
session->extensions |= SSH_EXT_SIG_RSA_SHA256;
|
||||
}
|
||||
|
||||
/*
|
||||
* Ensure that the client preference is honored for the case
|
||||
* both signature types are enabled.
|
||||
*/
|
||||
if ((session->extensions & SSH_EXT_SIG_RSA_SHA256) &&
|
||||
(session->extensions & SSH_EXT_SIG_RSA_SHA512)) {
|
||||
session->extensions &= ~(SSH_EXT_SIG_RSA_SHA256 | SSH_EXT_SIG_RSA_SHA512);
|
||||
rsa_sig_ext = ssh_find_matching("rsa-sha2-512,rsa-sha2-256",
|
||||
session->next_crypto->client_kex.methods[SSH_HOSTKEYS]);
|
||||
if (rsa_sig_ext == NULL) {
|
||||
goto error; /* should never happen */
|
||||
} else if (strcmp(rsa_sig_ext, "rsa-sha2-512") == 0) {
|
||||
session->extensions |= SSH_EXT_SIG_RSA_SHA512;
|
||||
} else if (strcmp(rsa_sig_ext, "rsa-sha2-256") == 0) {
|
||||
session->extensions |= SSH_EXT_SIG_RSA_SHA256;
|
||||
} else {
|
||||
SAFE_FREE(rsa_sig_ext);
|
||||
goto error; /* should never happen */
|
||||
}
|
||||
SAFE_FREE(rsa_sig_ext);
|
||||
}
|
||||
|
||||
SSH_LOG(SSH_LOG_DEBUG, "The client supports extension "
|
||||
"negotiation: enabling all extensions");
|
||||
session->extensions = SSH_EXT_ALL;
|
||||
"negotiation. Enabled signature algorithms: %s%s",
|
||||
session->extensions & SSH_EXT_SIG_RSA_SHA256 ? "SHA256" : "",
|
||||
session->extensions & SSH_EXT_SIG_RSA_SHA512 ? " SHA512" : "");
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -592,14 +634,18 @@ void ssh_list_kex(struct ssh_kex_struct *kex) {
|
||||
* @returns a cstring containing a comma-separated list of hostkey methods.
|
||||
* NULL if no method matches
|
||||
*/
|
||||
static char *ssh_client_select_hostkeys(ssh_session session)
|
||||
char *ssh_client_select_hostkeys(ssh_session session)
|
||||
{
|
||||
char methods_buffer[128]={0};
|
||||
char tail_buffer[128]={0};
|
||||
char *new_hostkeys = NULL;
|
||||
static const char *preferred_hostkeys[] = {
|
||||
"ssh-ed25519",
|
||||
"ecdsa-sha2-nistp521",
|
||||
"ecdsa-sha2-nistp384",
|
||||
"ecdsa-sha2-nistp256",
|
||||
"rsa-sha2-512",
|
||||
"rsa-sha2-256",
|
||||
"ssh-rsa",
|
||||
#ifdef HAVE_DSA
|
||||
"ssh-dss",
|
||||
@@ -610,7 +656,7 @@ static char *ssh_client_select_hostkeys(ssh_session session)
|
||||
struct ssh_iterator *it = NULL;
|
||||
size_t algo_count;
|
||||
int needcomma = 0;
|
||||
int i;
|
||||
size_t i, len;
|
||||
|
||||
algo_list = ssh_known_hosts_get_algorithms(session);
|
||||
if (algo_list == NULL) {
|
||||
@@ -624,30 +670,41 @@ static char *ssh_client_select_hostkeys(ssh_session session)
|
||||
}
|
||||
|
||||
for (i = 0; preferred_hostkeys[i] != NULL; ++i) {
|
||||
bool found = false;
|
||||
/* This is a signature type: We list also the SHA2 extensions */
|
||||
enum ssh_keytypes_e base_preferred =
|
||||
ssh_key_type_from_signature_name(preferred_hostkeys[i]);
|
||||
|
||||
for (it = ssh_list_get_iterator(algo_list);
|
||||
it != NULL;
|
||||
it = ssh_list_get_iterator(algo_list)) {
|
||||
it = it->next) {
|
||||
const char *algo = ssh_iterator_value(const char *, it);
|
||||
int cmp;
|
||||
int ok;
|
||||
/* This is always key type so we do not have to care for the
|
||||
* SHA2 extension */
|
||||
enum ssh_keytypes_e base_algo = ssh_key_type_from_name(algo);
|
||||
|
||||
cmp = strcmp(preferred_hostkeys[i], algo);
|
||||
if (cmp == 0) {
|
||||
ok = ssh_verify_existing_algo(SSH_HOSTKEYS, algo);
|
||||
if (ok) {
|
||||
if (needcomma) {
|
||||
strncat(methods_buffer,
|
||||
",",
|
||||
sizeof(methods_buffer) - strlen(methods_buffer) - 1);
|
||||
}
|
||||
if (base_preferred == base_algo) {
|
||||
/* Matching the keys already verified it is a known type */
|
||||
if (needcomma) {
|
||||
strncat(methods_buffer,
|
||||
algo,
|
||||
",",
|
||||
sizeof(methods_buffer) - strlen(methods_buffer) - 1);
|
||||
needcomma = 1;
|
||||
}
|
||||
strncat(methods_buffer,
|
||||
preferred_hostkeys[i],
|
||||
sizeof(methods_buffer) - strlen(methods_buffer) - 1);
|
||||
needcomma = 1;
|
||||
found = true;
|
||||
}
|
||||
|
||||
ssh_list_remove(algo_list, it);
|
||||
}
|
||||
/* Collect the rest of the algorithms in other buffer, that will
|
||||
* follow the preferred buffer. This will signalize all the algorithms
|
||||
* we are willing to accept.
|
||||
*/
|
||||
if (!found) {
|
||||
snprintf(tail_buffer + strlen(tail_buffer),
|
||||
sizeof(tail_buffer) - strlen(tail_buffer),
|
||||
",%s", preferred_hostkeys[i]);
|
||||
}
|
||||
}
|
||||
ssh_list_free(algo_list);
|
||||
@@ -658,11 +715,23 @@ static char *ssh_client_select_hostkeys(ssh_session session)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* Append the supported list to the preferred.
|
||||
* The length is maximum 128 + 128 + 1, which will not overflow
|
||||
*/
|
||||
len = strlen(methods_buffer) + strlen(tail_buffer) + 1;
|
||||
new_hostkeys = malloc(len);
|
||||
if (new_hostkeys == NULL) {
|
||||
ssh_set_error_oom(session);
|
||||
return NULL;
|
||||
}
|
||||
snprintf(new_hostkeys, len,
|
||||
"%s%s", methods_buffer, tail_buffer);
|
||||
|
||||
SSH_LOG(SSH_LOG_DEBUG,
|
||||
"Changing host key method to \"%s\"",
|
||||
methods_buffer);
|
||||
new_hostkeys);
|
||||
|
||||
return strdup(methods_buffer);
|
||||
return new_hostkeys;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -687,10 +756,10 @@ int ssh_set_client_kex(ssh_session session)
|
||||
|
||||
memset(client->methods, 0, KEX_METHODS_SIZE * sizeof(char **));
|
||||
/* first check if we have specific host key methods */
|
||||
if(session->opts.wanted_methods[SSH_HOSTKEYS] == NULL){
|
||||
if (session->opts.wanted_methods[SSH_HOSTKEYS] == NULL) {
|
||||
/* Only if no override */
|
||||
session->opts.wanted_methods[SSH_HOSTKEYS] =
|
||||
ssh_client_select_hostkeys(session);
|
||||
ssh_client_select_hostkeys(session);
|
||||
}
|
||||
|
||||
for (i = 0; i < KEX_METHODS_SIZE; i++) {
|
||||
@@ -704,6 +773,11 @@ int ssh_set_client_kex(ssh_session session)
|
||||
}
|
||||
}
|
||||
|
||||
/* For rekeying, skip the extension negotiation */
|
||||
if (session->session_state == SSH_SESSION_STATE_AUTHENTICATED) {
|
||||
return SSH_OK;
|
||||
}
|
||||
|
||||
/* Here we append ext-info-c to the list of kex algorithms */
|
||||
kex = client->methods[SSH_KEX];
|
||||
len = strlen(kex);
|
||||
|
||||
134
src/knownhosts.c
134
src/knownhosts.c
@@ -182,11 +182,16 @@ static int known_hosts_read_line(FILE *fp,
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* This method reads the known_hosts file referenced by the path
|
||||
* in filename argument, and entries matching the match argument
|
||||
* will be added to the list in entries argument.
|
||||
* If the entries list is NULL, it will allocate a new list. Caller
|
||||
* is responsible to free it even if an error occurs.
|
||||
*/
|
||||
static int ssh_known_hosts_read_entries(const char *match,
|
||||
const char *filename,
|
||||
struct ssh_list **entries)
|
||||
{
|
||||
struct ssh_list *entry_list;
|
||||
char line[8192];
|
||||
size_t lineno = 0;
|
||||
size_t len = 0;
|
||||
@@ -195,13 +200,18 @@ static int ssh_known_hosts_read_entries(const char *match,
|
||||
|
||||
fp = fopen(filename, "r");
|
||||
if (fp == NULL) {
|
||||
return SSH_ERROR;
|
||||
SSH_LOG(SSH_LOG_WARN, "Failed to open the known_hosts file '%s': %s",
|
||||
filename, strerror(errno));
|
||||
/* The missing file is not an error here */
|
||||
return SSH_OK;
|
||||
}
|
||||
|
||||
entry_list = ssh_list_new();
|
||||
if (entry_list == NULL) {
|
||||
fclose(fp);
|
||||
return SSH_ERROR;
|
||||
if (*entries == NULL) {
|
||||
*entries = ssh_list_new();
|
||||
if (*entries == NULL) {
|
||||
fclose(fp);
|
||||
return SSH_ERROR;
|
||||
}
|
||||
}
|
||||
|
||||
for (rc = known_hosts_read_line(fp, line, sizeof(line), &len, &lineno);
|
||||
@@ -231,15 +241,12 @@ static int ssh_known_hosts_read_entries(const char *match,
|
||||
} else if (rc != SSH_OK) {
|
||||
goto error;
|
||||
}
|
||||
ssh_list_append(entry_list, entry);
|
||||
ssh_list_append(*entries, entry);
|
||||
}
|
||||
|
||||
*entries = entry_list;
|
||||
|
||||
fclose(fp);
|
||||
return SSH_OK;
|
||||
error:
|
||||
ssh_list_free(entry_list);
|
||||
fclose(fp);
|
||||
return SSH_ERROR;
|
||||
}
|
||||
@@ -299,7 +306,8 @@ struct ssh_list *ssh_known_hosts_get_algorithms(ssh_session session)
|
||||
int list_error = 0;
|
||||
int rc;
|
||||
|
||||
if (session->opts.knownhosts == NULL) {
|
||||
if (session->opts.knownhosts == NULL ||
|
||||
session->opts.global_knownhosts == NULL) {
|
||||
if (ssh_options_apply(session) < 0) {
|
||||
ssh_set_error(session,
|
||||
SSH_REQUEST_DENIED,
|
||||
@@ -323,8 +331,23 @@ struct ssh_list *ssh_known_hosts_get_algorithms(ssh_session session)
|
||||
rc = ssh_known_hosts_read_entries(host_port,
|
||||
session->opts.knownhosts,
|
||||
&entry_list);
|
||||
if (rc != 0) {
|
||||
ssh_list_free(entry_list);
|
||||
ssh_list_free(list);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
rc = ssh_known_hosts_read_entries(host_port,
|
||||
session->opts.global_knownhosts,
|
||||
&entry_list);
|
||||
SAFE_FREE(host_port);
|
||||
if (rc != 0) {
|
||||
ssh_list_free(entry_list);
|
||||
ssh_list_free(list);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (entry_list == NULL) {
|
||||
ssh_list_free(list);
|
||||
return NULL;
|
||||
}
|
||||
@@ -340,12 +363,10 @@ struct ssh_list *ssh_known_hosts_get_algorithms(ssh_session session)
|
||||
it != NULL;
|
||||
it = ssh_list_get_iterator(entry_list)) {
|
||||
struct ssh_knownhosts_entry *entry = NULL;
|
||||
enum ssh_keytypes_e key_type;
|
||||
const char *algo = NULL;
|
||||
|
||||
entry = ssh_iterator_value(struct ssh_knownhosts_entry *, it);
|
||||
key_type = ssh_key_type(entry->publickey);
|
||||
algo = ssh_key_type_to_char(key_type);
|
||||
algo = entry->publickey->type_c;
|
||||
|
||||
rc = ssh_list_append(list, algo);
|
||||
if (rc != SSH_OK) {
|
||||
@@ -556,8 +577,17 @@ enum ssh_known_hosts_e ssh_session_has_known_hosts_entry(ssh_session session)
|
||||
rc = ssh_known_hosts_read_entries(host_port,
|
||||
session->opts.knownhosts,
|
||||
&entry_list);
|
||||
if (rc != 0) {
|
||||
ssh_list_free(entry_list);
|
||||
return SSH_KNOWN_HOSTS_UNKNOWN;
|
||||
}
|
||||
|
||||
rc = ssh_known_hosts_read_entries(host_port,
|
||||
session->opts.global_knownhosts,
|
||||
&entry_list);
|
||||
SAFE_FREE(host_port);
|
||||
if (rc != 0) {
|
||||
ssh_list_free(entry_list);
|
||||
return SSH_KNOWN_HOSTS_UNKNOWN;
|
||||
}
|
||||
|
||||
@@ -621,7 +651,7 @@ int ssh_session_export_known_hosts_entry(ssh_session session,
|
||||
|
||||
if (session->current_crypto == NULL) {
|
||||
ssh_set_error(session, SSH_FATAL,
|
||||
"No current crypto context, please connnect first");
|
||||
"No current crypto context, please connect first");
|
||||
SAFE_FREE(host);
|
||||
return SSH_ERROR;
|
||||
}
|
||||
@@ -657,10 +687,11 @@ int ssh_session_export_known_hosts_entry(ssh_session session,
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Add the current connected server to the known_hosts file.
|
||||
* @brief Add the current connected server to the user known_hosts file.
|
||||
*
|
||||
* This adds the currently connected server to the known_hosts file by
|
||||
* appending a new line at the end.
|
||||
* appending a new line at the end. The global known_hosts file is considered
|
||||
* read-only so it is not touched by this function.
|
||||
*
|
||||
* @param[in] session The session to use to write the entry.
|
||||
*
|
||||
@@ -747,6 +778,7 @@ ssh_known_hosts_check_server_key(const char *hosts_entry,
|
||||
filename,
|
||||
&entry_list);
|
||||
if (rc != 0) {
|
||||
ssh_list_free(entry_list);
|
||||
return SSH_KNOWN_HOSTS_UNKNOWN;
|
||||
}
|
||||
|
||||
@@ -824,9 +856,7 @@ enum ssh_known_hosts_e
|
||||
ssh_session_get_known_hosts_entry(ssh_session session,
|
||||
struct ssh_knownhosts_entry **pentry)
|
||||
{
|
||||
ssh_key server_pubkey = NULL;
|
||||
char *host_port = NULL;
|
||||
enum ssh_known_hosts_e found = SSH_KNOWN_HOSTS_UNKNOWN;
|
||||
enum ssh_known_hosts_e old_rv, rv = SSH_KNOWN_HOSTS_UNKNOWN;
|
||||
|
||||
if (session->opts.knownhosts == NULL) {
|
||||
if (ssh_options_apply(session) < 0) {
|
||||
@@ -838,6 +868,68 @@ ssh_session_get_known_hosts_entry(ssh_session session,
|
||||
}
|
||||
}
|
||||
|
||||
rv = ssh_session_get_known_hosts_entry_file(session,
|
||||
session->opts.knownhosts,
|
||||
pentry);
|
||||
if (rv == SSH_KNOWN_HOSTS_OK) {
|
||||
/* We already found a match in the first file: return */
|
||||
return rv;
|
||||
}
|
||||
|
||||
old_rv = rv;
|
||||
rv = ssh_session_get_known_hosts_entry_file(session,
|
||||
session->opts.global_knownhosts,
|
||||
pentry);
|
||||
|
||||
/* If we did not find any match at all: we report the previous result */
|
||||
if (rv == SSH_KNOWN_HOSTS_UNKNOWN) {
|
||||
if (session->opts.StrictHostKeyChecking == 0) {
|
||||
return SSH_KNOWN_HOSTS_OK;
|
||||
}
|
||||
return old_rv;
|
||||
}
|
||||
|
||||
/* We found some match: return it */
|
||||
return rv;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Get the known_hosts entry for the current connected session
|
||||
* from the given known_hosts file.
|
||||
*
|
||||
* @param[in] session The session to validate.
|
||||
*
|
||||
* @param[in] filename The filename to parse.
|
||||
*
|
||||
* @param[in] pentry A pointer to store the allocated known hosts entry.
|
||||
*
|
||||
* @returns SSH_KNOWN_HOSTS_OK: The server is known and has not changed.\n
|
||||
* SSH_KNOWN_HOSTS_CHANGED: The server key has changed. Either you
|
||||
* are under attack or the administrator
|
||||
* changed the key. You HAVE to warn the
|
||||
* user about a possible attack.\n
|
||||
* SSH_KNOWN_HOSTS_OTHER: The server gave use a key of a type while
|
||||
* we had an other type recorded. It is a
|
||||
* possible attack.\n
|
||||
* SSH_KNOWN_HOSTS_UNKNOWN: The server is unknown. User should
|
||||
* confirm the public key hash is correct.\n
|
||||
* SSH_KNOWN_HOSTS_NOT_FOUND: The known host file does not exist. The
|
||||
* host is thus unknown. File will be
|
||||
* created if host key is accepted.\n
|
||||
* SSH_KNOWN_HOSTS_ERROR: There had been an eror checking the host.
|
||||
*
|
||||
* @see ssh_knownhosts_entry_free()
|
||||
*/
|
||||
enum ssh_known_hosts_e
|
||||
ssh_session_get_known_hosts_entry_file(ssh_session session,
|
||||
const char *filename,
|
||||
struct ssh_knownhosts_entry **pentry)
|
||||
{
|
||||
ssh_key server_pubkey = NULL;
|
||||
char *host_port = NULL;
|
||||
enum ssh_known_hosts_e found = SSH_KNOWN_HOSTS_UNKNOWN;
|
||||
|
||||
server_pubkey = ssh_dh_get_current_server_publickey(session);
|
||||
if (server_pubkey == NULL) {
|
||||
ssh_set_error(session,
|
||||
@@ -854,7 +946,7 @@ ssh_session_get_known_hosts_entry(ssh_session session,
|
||||
}
|
||||
|
||||
found = ssh_known_hosts_check_server_key(host_port,
|
||||
session->opts.knownhosts,
|
||||
filename,
|
||||
server_pubkey,
|
||||
pentry);
|
||||
SAFE_FREE(host_port);
|
||||
|
||||
@@ -10,9 +10,12 @@
|
||||
#include "config.h"
|
||||
|
||||
#include <string.h>
|
||||
#include <openssl/engine.h>
|
||||
#include "libcrypto-compat.h"
|
||||
|
||||
#ifndef OPENSSL_NO_ENGINE
|
||||
#include <openssl/engine.h>
|
||||
#endif
|
||||
|
||||
static void *OPENSSL_zalloc(size_t num)
|
||||
{
|
||||
void *ret = OPENSSL_malloc(num);
|
||||
|
||||
@@ -10,6 +10,7 @@
|
||||
#include <openssl/dh.h>
|
||||
#include <openssl/evp.h>
|
||||
#include <openssl/hmac.h>
|
||||
#include <openssl/bn.h>
|
||||
|
||||
int RSA_set0_key(RSA *r, BIGNUM *n, BIGNUM *e, BIGNUM *d);
|
||||
int RSA_set0_factors(RSA *r, BIGNUM *p, BIGNUM *q);
|
||||
|
||||
@@ -43,6 +43,7 @@
|
||||
#include <openssl/hmac.h>
|
||||
#include <openssl/opensslv.h>
|
||||
#include <openssl/rand.h>
|
||||
|
||||
#include "libcrypto-compat.h"
|
||||
|
||||
#ifdef HAVE_OPENSSL_AES_H
|
||||
@@ -54,6 +55,10 @@
|
||||
#include <openssl/des.h>
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_OPENSSL_CRYPTO_CTR128_ENCRYPT
|
||||
#include <openssl/modes.h>
|
||||
#endif
|
||||
|
||||
#if (OPENSSL_VERSION_NUMBER<0x00907000L)
|
||||
#define OLD_CRYPTO
|
||||
#endif
|
||||
@@ -196,6 +201,7 @@ void evp_update(EVPCTX ctx, const void *data, unsigned long len)
|
||||
void evp_final(EVPCTX ctx, unsigned char *md, unsigned int *mdlen)
|
||||
{
|
||||
EVP_DigestFinal(ctx, md, mdlen);
|
||||
EVP_MD_CTX_free(ctx);
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -426,9 +432,6 @@ HMACCTX hmac_init(const void *key, int len, enum ssh_hmac_e type) {
|
||||
case SSH_HMAC_SHA256:
|
||||
HMAC_Init_ex(ctx, key, len, EVP_sha256(), NULL);
|
||||
break;
|
||||
case SSH_HMAC_SHA384:
|
||||
HMAC_Init_ex(ctx, key, len, EVP_sha384(), NULL);
|
||||
break;
|
||||
case SSH_HMAC_SHA512:
|
||||
HMAC_Init_ex(ctx, key, len, EVP_sha512(), NULL);
|
||||
break;
|
||||
@@ -638,8 +641,12 @@ static void aes_ctr_encrypt(struct ssh_cipher_struct *cipher, void *in, void *ou
|
||||
}
|
||||
|
||||
static void aes_ctr_cleanup(struct ssh_cipher_struct *cipher){
|
||||
explicit_bzero(cipher->aes_key, sizeof(*cipher->aes_key));
|
||||
SAFE_FREE(cipher->aes_key);
|
||||
if (cipher != NULL) {
|
||||
if (cipher->aes_key != NULL) {
|
||||
explicit_bzero(cipher->aes_key, sizeof(*cipher->aes_key));
|
||||
}
|
||||
SAFE_FREE(cipher->aes_key);
|
||||
}
|
||||
}
|
||||
|
||||
#endif /* HAVE_OPENSSL_EVP_AES_CTR */
|
||||
|
||||
@@ -282,9 +282,6 @@ HMACCTX hmac_init(const void *key, int len, enum ssh_hmac_e type) {
|
||||
case SSH_HMAC_SHA256:
|
||||
gcry_md_open(&c, GCRY_MD_SHA256, GCRY_MD_FLAG_HMAC);
|
||||
break;
|
||||
case SSH_HMAC_SHA384:
|
||||
gcry_md_open(&c, GCRY_MD_SHA384, GCRY_MD_FLAG_HMAC);
|
||||
break;
|
||||
case SSH_HMAC_SHA512:
|
||||
gcry_md_open(&c, GCRY_MD_SHA512, GCRY_MD_FLAG_HMAC);
|
||||
break;
|
||||
|
||||
@@ -462,9 +462,6 @@ HMACCTX hmac_init(const void *key, int len, enum ssh_hmac_e type)
|
||||
case SSH_HMAC_SHA256:
|
||||
md_info = mbedtls_md_info_from_type(MBEDTLS_MD_SHA256);
|
||||
break;
|
||||
case SSH_HMAC_SHA384:
|
||||
md_info = mbedtls_md_info_from_type(MBEDTLS_MD_SHA384);
|
||||
break;
|
||||
case SSH_HMAC_SHA512:
|
||||
md_info = mbedtls_md_info_from_type(MBEDTLS_MD_SHA512);
|
||||
break;
|
||||
|
||||
@@ -702,8 +702,10 @@ static ssh_buffer ssh_msg_userauth_build_digest(ssh_session session,
|
||||
*/
|
||||
SSH_PACKET_CALLBACK(ssh_packet_userauth_request){
|
||||
ssh_message msg = NULL;
|
||||
ssh_signature sig = NULL;
|
||||
char *service = NULL;
|
||||
char *method = NULL;
|
||||
int cmp;
|
||||
int rc;
|
||||
|
||||
(void)user;
|
||||
@@ -730,6 +732,13 @@ SSH_PACKET_CALLBACK(ssh_packet_userauth_request){
|
||||
service, method,
|
||||
msg->auth_request.username);
|
||||
|
||||
cmp = strcmp(service, "ssh-connection");
|
||||
if (cmp != 0) {
|
||||
SSH_LOG(SSH_LOG_WARNING,
|
||||
"Invalid service request: %s",
|
||||
service);
|
||||
goto end;
|
||||
}
|
||||
|
||||
if (strcmp(method, "none") == 0) {
|
||||
msg->auth_request.method = SSH_AUTH_METHOD_NONE;
|
||||
@@ -827,13 +836,19 @@ SSH_PACKET_CALLBACK(ssh_packet_userauth_request){
|
||||
goto error;
|
||||
}
|
||||
|
||||
rc = ssh_pki_signature_verify_blob(session,
|
||||
sig_blob,
|
||||
rc = ssh_pki_import_signature_blob(sig_blob,
|
||||
msg->auth_request.pubkey,
|
||||
ssh_buffer_get(digest),
|
||||
ssh_buffer_get_len(digest));
|
||||
&sig);
|
||||
if (rc == SSH_OK) {
|
||||
rc = ssh_pki_signature_verify(session,
|
||||
sig,
|
||||
msg->auth_request.pubkey,
|
||||
ssh_buffer_get(digest),
|
||||
ssh_buffer_get_len(digest));
|
||||
}
|
||||
ssh_string_free(sig_blob);
|
||||
ssh_buffer_free(digest);
|
||||
ssh_signature_free(sig);
|
||||
if (rc < 0) {
|
||||
SSH_LOG(
|
||||
SSH_LOG_PACKET,
|
||||
|
||||
237
src/misc.c
237
src/misc.c
@@ -213,47 +213,50 @@ int ssh_is_ipaddr(const char *str) {
|
||||
#define NSS_BUFLEN_PASSWD 4096
|
||||
#endif /* NSS_BUFLEN_PASSWD */
|
||||
|
||||
char *ssh_get_user_home_dir(void) {
|
||||
char *szPath = NULL;
|
||||
struct passwd pwd;
|
||||
struct passwd *pwdbuf;
|
||||
char buf[NSS_BUFLEN_PASSWD] = {0};
|
||||
int rc;
|
||||
char *ssh_get_user_home_dir(void)
|
||||
{
|
||||
char *szPath = NULL;
|
||||
struct passwd pwd;
|
||||
struct passwd *pwdbuf = NULL;
|
||||
char buf[NSS_BUFLEN_PASSWD] = {0};
|
||||
int rc;
|
||||
|
||||
rc = getpwuid_r(getuid(), &pwd, buf, NSS_BUFLEN_PASSWD, &pwdbuf);
|
||||
if (rc != 0) {
|
||||
szPath = getenv("HOME");
|
||||
if (szPath == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
snprintf(buf, sizeof(buf), "%s", szPath);
|
||||
rc = getpwuid_r(getuid(), &pwd, buf, NSS_BUFLEN_PASSWD, &pwdbuf);
|
||||
if (rc != 0 || pwdbuf == NULL ) {
|
||||
szPath = getenv("HOME");
|
||||
if (szPath == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
snprintf(buf, sizeof(buf), "%s", szPath);
|
||||
|
||||
return strdup(buf);
|
||||
}
|
||||
return strdup(buf);
|
||||
}
|
||||
|
||||
szPath = strdup(pwd.pw_dir);
|
||||
szPath = strdup(pwd.pw_dir);
|
||||
|
||||
return szPath;
|
||||
return szPath;
|
||||
}
|
||||
|
||||
/* we have read access on file */
|
||||
int ssh_file_readaccess_ok(const char *file) {
|
||||
if (access(file, R_OK) < 0) {
|
||||
return 0;
|
||||
}
|
||||
int ssh_file_readaccess_ok(const char *file)
|
||||
{
|
||||
if (access(file, R_OK) < 0) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
return 1;
|
||||
return 1;
|
||||
}
|
||||
|
||||
char *ssh_get_local_username(void) {
|
||||
char *ssh_get_local_username(void)
|
||||
{
|
||||
struct passwd pwd;
|
||||
struct passwd *pwdbuf;
|
||||
struct passwd *pwdbuf = NULL;
|
||||
char buf[NSS_BUFLEN_PASSWD];
|
||||
char *name;
|
||||
int rc;
|
||||
|
||||
rc = getpwuid_r(getuid(), &pwd, buf, NSS_BUFLEN_PASSWD, &pwdbuf);
|
||||
if (rc != 0) {
|
||||
if (rc != 0 || pwdbuf == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@@ -1105,4 +1108,188 @@ char *strndup(const char *s, size_t n)
|
||||
}
|
||||
#endif /* ! HAVE_STRNDUP */
|
||||
|
||||
/**
|
||||
* @internal
|
||||
*
|
||||
* @brief Quote file name to be used on shell.
|
||||
*
|
||||
* Try to put the given file name between single quotes. There are special
|
||||
* cases:
|
||||
*
|
||||
* - When the '\'' char is found in the file name, it is double quoted
|
||||
* - example:
|
||||
* input: a'b
|
||||
* output: 'a'"'"'b'
|
||||
* - When the '!' char is found in the file name, it is replaced by an unquoted
|
||||
* verbatim char "\!"
|
||||
* - example:
|
||||
* input: a!b
|
||||
* output 'a'\!'b'
|
||||
*
|
||||
* @param[in] file_name File name string to be quoted before used on shell
|
||||
* @param[out] buf Buffer to receive the final quoted file name. Must
|
||||
* have room for the final quoted string. The maximum
|
||||
* output length would be (3 * strlen(file_name) + 1)
|
||||
* since in the worst case each character would be
|
||||
* replaced by 3 characters, plus the terminating '\0'.
|
||||
* @param[in] buf_len The size of the provided output buffer
|
||||
*
|
||||
* @returns SSH_ERROR on error; length of the resulting string not counting the
|
||||
* string terminator '\0'
|
||||
* */
|
||||
int ssh_quote_file_name(const char *file_name, char *buf, size_t buf_len)
|
||||
{
|
||||
const char *src = NULL;
|
||||
char *dst = NULL;
|
||||
size_t required_buf_len;
|
||||
|
||||
enum ssh_quote_state_e state = NO_QUOTE;
|
||||
|
||||
if (file_name == NULL || buf == NULL || buf_len == 0) {
|
||||
SSH_LOG(SSH_LOG_WARNING, "Invalid parameter");
|
||||
return SSH_ERROR;
|
||||
}
|
||||
|
||||
/* Only allow file names smaller than 32kb. */
|
||||
if (strlen(file_name) > 32 * 1024) {
|
||||
SSH_LOG(SSH_LOG_WARNING, "File name too long");
|
||||
return SSH_ERROR;
|
||||
}
|
||||
|
||||
/* Paranoia check */
|
||||
required_buf_len = (size_t)3 * strlen(file_name) + 1;
|
||||
if (required_buf_len > buf_len) {
|
||||
SSH_LOG(SSH_LOG_WARNING, "Buffer too small");
|
||||
return SSH_ERROR;
|
||||
}
|
||||
|
||||
src = file_name;
|
||||
dst = buf;
|
||||
|
||||
while ((*src != '\0')) {
|
||||
switch (*src) {
|
||||
|
||||
/* The '\'' char is double quoted */
|
||||
|
||||
case '\'':
|
||||
switch (state) {
|
||||
case NO_QUOTE:
|
||||
/* Start a new double quoted string. The '\'' char will be
|
||||
* copied to the beginning of it at the end of the loop. */
|
||||
*dst++ = '"';
|
||||
break;
|
||||
case SINGLE_QUOTE:
|
||||
/* Close the current single quoted string and start a new double
|
||||
* quoted string. The '\'' char will be copied to the beginning
|
||||
* of it at the end of the loop. */
|
||||
*dst++ = '\'';
|
||||
*dst++ = '"';
|
||||
break;
|
||||
case DOUBLE_QUOTE:
|
||||
/* If already in the double quoted string, keep copying the
|
||||
* sequence of chars. */
|
||||
break;
|
||||
default:
|
||||
/* Should never be reached */
|
||||
goto error;
|
||||
}
|
||||
|
||||
/* When the '\'' char is found, the resulting state will be
|
||||
* DOUBLE_QUOTE in any case*/
|
||||
state = DOUBLE_QUOTE;
|
||||
break;
|
||||
|
||||
/* The '!' char is replaced by unquoted "\!" */
|
||||
|
||||
case '!':
|
||||
switch (state) {
|
||||
case NO_QUOTE:
|
||||
/* The '!' char is interpreted in some shells (e.g. CSH) even
|
||||
* when is quoted with single quotes. Replace it with unquoted
|
||||
* "\!" which is correctly interpreted as the '!' character. */
|
||||
*dst++ = '\\';
|
||||
break;
|
||||
case SINGLE_QUOTE:
|
||||
/* Close the current quoted string and replace '!' for unquoted
|
||||
* "\!" */
|
||||
*dst++ = '\'';
|
||||
*dst++ = '\\';
|
||||
break;
|
||||
case DOUBLE_QUOTE:
|
||||
/* Close current quoted string and replace "!" for unquoted
|
||||
* "\!" */
|
||||
*dst++ = '"';
|
||||
*dst++ = '\\';
|
||||
break;
|
||||
default:
|
||||
/* Should never be reached */
|
||||
goto error;
|
||||
}
|
||||
|
||||
/* When the '!' char is found, the resulting state will be NO_QUOTE
|
||||
* in any case*/
|
||||
state = NO_QUOTE;
|
||||
break;
|
||||
|
||||
/* Ordinary chars are single quoted */
|
||||
|
||||
default:
|
||||
switch (state) {
|
||||
case NO_QUOTE:
|
||||
/* Start a new single quoted string */
|
||||
*dst++ = '\'';
|
||||
break;
|
||||
case SINGLE_QUOTE:
|
||||
/* If already in the single quoted string, keep copying the
|
||||
* sequence of chars. */
|
||||
break;
|
||||
case DOUBLE_QUOTE:
|
||||
/* Close current double quoted string and start a new single
|
||||
* quoted string. */
|
||||
*dst++ = '"';
|
||||
*dst++ = '\'';
|
||||
break;
|
||||
default:
|
||||
/* Should never be reached */
|
||||
goto error;
|
||||
}
|
||||
|
||||
/* When an ordinary char is found, the resulting state will be
|
||||
* SINGLE_QUOTE in any case*/
|
||||
state = SINGLE_QUOTE;
|
||||
break;
|
||||
}
|
||||
|
||||
/* Copy the current char to output */
|
||||
*dst++ = *src++;
|
||||
}
|
||||
|
||||
/* Close the quoted string when necessary */
|
||||
|
||||
switch (state) {
|
||||
case NO_QUOTE:
|
||||
/* No open string */
|
||||
break;
|
||||
case SINGLE_QUOTE:
|
||||
/* Close current single quoted string */
|
||||
*dst++ = '\'';
|
||||
break;
|
||||
case DOUBLE_QUOTE:
|
||||
/* Close current double quoted string */
|
||||
*dst++ = '"';
|
||||
break;
|
||||
default:
|
||||
/* Should never be reached */
|
||||
goto error;
|
||||
}
|
||||
|
||||
/* Put the string terminator */
|
||||
*dst = '\0';
|
||||
|
||||
return dst - buf;
|
||||
|
||||
error:
|
||||
return SSH_ERROR;
|
||||
}
|
||||
|
||||
/** @} */
|
||||
|
||||
@@ -302,37 +302,6 @@ int ssh_options_set_algo(ssh_session session,
|
||||
* \n
|
||||
* See the corresponding numbers in libssh.h.
|
||||
*
|
||||
* - SSH_OPTIONS_AUTH_CALLBACK:
|
||||
* Set a callback to use your own authentication function
|
||||
* (function pointer).
|
||||
*
|
||||
* - SSH_OPTIONS_AUTH_USERDATA:
|
||||
* Set the user data passed to the authentication
|
||||
* function (generic pointer).
|
||||
*
|
||||
* - SSH_OPTIONS_LOG_CALLBACK:
|
||||
* Set a callback to use your own logging function
|
||||
* (function pointer).
|
||||
*
|
||||
* - SSH_OPTIONS_LOG_USERDATA:
|
||||
* Set the user data passed to the logging function
|
||||
* (generic pointer).
|
||||
*
|
||||
* - SSH_OPTIONS_STATUS_CALLBACK:
|
||||
* Set a callback to show connection status in realtime
|
||||
* (function pointer).\n
|
||||
* \n
|
||||
* @code
|
||||
* fn(void *arg, float status)
|
||||
* @endcode
|
||||
* \n
|
||||
* During ssh_connect(), libssh will call the callback
|
||||
* with status from 0.0 to 1.0.
|
||||
*
|
||||
* - SSH_OPTIONS_STATUS_ARG:
|
||||
* Set the status argument which should be passed to the
|
||||
* status callback (generic pointer).
|
||||
*
|
||||
* - SSH_OPTIONS_CIPHERS_C_S:
|
||||
* Set the symmetric cipher client to server (const char *,
|
||||
* comma-separated list).
|
||||
@@ -605,12 +574,7 @@ int ssh_options_set(ssh_session session, enum ssh_options_e type,
|
||||
v = value;
|
||||
SAFE_FREE(session->opts.knownhosts);
|
||||
if (v == NULL) {
|
||||
session->opts.knownhosts = ssh_path_expand_escape(session,
|
||||
"%d/known_hosts");
|
||||
if (session->opts.knownhosts == NULL) {
|
||||
ssh_set_error_oom(session);
|
||||
return -1;
|
||||
}
|
||||
/* The default value will be set by the ssh_options_apply() */
|
||||
} else if (v[0] == '\0') {
|
||||
ssh_set_error_invalid(session);
|
||||
return -1;
|
||||
@@ -1022,6 +986,12 @@ int ssh_options_get_port(ssh_session session, unsigned int* port_target) {
|
||||
* remote host. When not explicitly set, it will be read
|
||||
* from the ~/.ssh/config file.
|
||||
*
|
||||
* - SSH_OPTIONS_GLOBAL_KNOWNHOSTS:
|
||||
* Get the path to the global known_hosts file being used.
|
||||
*
|
||||
* - SSH_OPTIONS_KNOWNHOSTS:
|
||||
* Get the path to the known_hosts file being used.
|
||||
*
|
||||
* @param value The value to get into. As a char**, space will be
|
||||
* allocated by the function for the value, it is
|
||||
* your responsibility to free the memory using
|
||||
@@ -1064,6 +1034,14 @@ int ssh_options_get(ssh_session session, enum ssh_options_e type, char** value)
|
||||
src = session->opts.ProxyCommand;
|
||||
break;
|
||||
}
|
||||
case SSH_OPTIONS_KNOWNHOSTS: {
|
||||
src = session->opts.knownhosts;
|
||||
break;
|
||||
}
|
||||
case SSH_OPTIONS_GLOBAL_KNOWNHOSTS: {
|
||||
src = session->opts.global_knownhosts;
|
||||
break;
|
||||
}
|
||||
default:
|
||||
ssh_set_error(session, SSH_REQUEST_DENIED, "Unknown ssh option %d", type);
|
||||
return SSH_ERROR;
|
||||
@@ -1356,6 +1334,17 @@ int ssh_options_apply(ssh_session session) {
|
||||
free(session->opts.knownhosts);
|
||||
session->opts.knownhosts = tmp;
|
||||
|
||||
if (session->opts.global_knownhosts == NULL) {
|
||||
tmp = strdup("/etc/ssh/ssh_known_hosts");
|
||||
} else {
|
||||
tmp = ssh_path_expand_escape(session, session->opts.global_knownhosts);
|
||||
}
|
||||
if (tmp == NULL) {
|
||||
return -1;
|
||||
}
|
||||
free(session->opts.global_knownhosts);
|
||||
session->opts.global_knownhosts = tmp;
|
||||
|
||||
if (session->opts.ProxyCommand != NULL) {
|
||||
tmp = ssh_path_expand_escape(session, session->opts.ProxyCommand);
|
||||
if (tmp == NULL) {
|
||||
|
||||
@@ -263,13 +263,17 @@ static enum ssh_packet_filter_result_e ssh_packet_incoming_filter(ssh_session se
|
||||
/*
|
||||
* States required:
|
||||
* - session_state == SSH_SESSION_STATE_AUTHENTICATING
|
||||
* or session->session_state == SSH_SESSION_STATE_AUTHENTICATED
|
||||
* (re-exchange)
|
||||
* - dh_handshake_state == DH_STATE_FINISHED
|
||||
*
|
||||
* Transitions:
|
||||
* - None
|
||||
* */
|
||||
|
||||
if (session->session_state != SSH_SESSION_STATE_AUTHENTICATING) {
|
||||
if ((session->session_state != SSH_SESSION_STATE_AUTHENTICATING) &&
|
||||
(session->session_state != SSH_SESSION_STATE_AUTHENTICATED))
|
||||
{
|
||||
rc = SSH_PACKET_DENIED;
|
||||
break;
|
||||
}
|
||||
@@ -308,6 +312,7 @@ static enum ssh_packet_filter_result_e ssh_packet_incoming_filter(ssh_session se
|
||||
(session->dh_handshake_state != DH_STATE_FINISHED))
|
||||
{
|
||||
rc = SSH_PACKET_DENIED;
|
||||
break;
|
||||
}
|
||||
|
||||
rc = SSH_PACKET_ALLOWED;
|
||||
|
||||
@@ -138,6 +138,7 @@ error:
|
||||
|
||||
SSH_PACKET_CALLBACK(ssh_packet_newkeys){
|
||||
ssh_string sig_blob = NULL;
|
||||
ssh_signature sig = NULL;
|
||||
int rc;
|
||||
(void)packet;
|
||||
(void)user;
|
||||
@@ -185,30 +186,36 @@ SSH_PACKET_CALLBACK(ssh_packet_newkeys){
|
||||
/* get the server public key */
|
||||
server_key = ssh_dh_get_next_server_publickey(session);
|
||||
if (server_key == NULL) {
|
||||
return SSH_ERROR;
|
||||
goto error;
|
||||
}
|
||||
|
||||
/* check if public key from server matches user preferences */
|
||||
rc = ssh_pki_import_signature_blob(sig_blob, server_key, &sig);
|
||||
if (rc != SSH_OK) {
|
||||
goto error;
|
||||
}
|
||||
|
||||
/* Check if signature from server matches user preferences */
|
||||
if (session->opts.wanted_methods[SSH_HOSTKEYS]) {
|
||||
if(!ssh_match_group(session->opts.wanted_methods[SSH_HOSTKEYS],
|
||||
server_key->type_c)) {
|
||||
if (!ssh_match_group(session->opts.wanted_methods[SSH_HOSTKEYS],
|
||||
sig->type_c)) {
|
||||
ssh_set_error(session,
|
||||
SSH_FATAL,
|
||||
"Public key from server (%s) doesn't match user "
|
||||
"preference (%s)",
|
||||
server_key->type_c,
|
||||
sig->type_c,
|
||||
session->opts.wanted_methods[SSH_HOSTKEYS]);
|
||||
return -1;
|
||||
goto error;
|
||||
}
|
||||
}
|
||||
|
||||
rc = ssh_pki_signature_verify_blob(session,
|
||||
sig_blob,
|
||||
server_key,
|
||||
session->next_crypto->secret_hash,
|
||||
session->next_crypto->digest_len);
|
||||
rc = ssh_pki_signature_verify(session,
|
||||
sig,
|
||||
server_key,
|
||||
session->next_crypto->secret_hash,
|
||||
session->next_crypto->digest_len);
|
||||
ssh_string_burn(sig_blob);
|
||||
ssh_string_free(sig_blob);
|
||||
ssh_signature_free(sig);
|
||||
sig_blob = NULL;
|
||||
if (rc == SSH_ERROR) {
|
||||
goto error;
|
||||
|
||||
@@ -176,6 +176,17 @@ unsigned char *ssh_packet_encrypt(ssh_session session, void *data, uint32_t len)
|
||||
return session->current_crypto->hmacbuf;
|
||||
}
|
||||
|
||||
static int secure_memcmp(const void *s1, const void *s2, size_t n)
|
||||
{
|
||||
int rc = 0;
|
||||
const unsigned char *p1 = s1;
|
||||
const unsigned char *p2 = s2;
|
||||
for (; n > 0; --n) {
|
||||
rc |= *p1++ ^ *p2++;
|
||||
}
|
||||
return (rc != 0);
|
||||
}
|
||||
|
||||
/**
|
||||
* @internal
|
||||
*
|
||||
@@ -219,7 +230,7 @@ int ssh_packet_hmac_verify(ssh_session session,
|
||||
ssh_print_hexa("Computed mac",hmacbuf,len);
|
||||
ssh_print_hexa("seq",(unsigned char *)&seq,sizeof(uint32_t));
|
||||
#endif
|
||||
if (memcmp(mac, hmacbuf, len) == 0) {
|
||||
if (secure_memcmp(mac, hmacbuf, len) == 0) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
@@ -312,7 +312,7 @@ static int ssh_pcap_context_connect(ssh_pcap_context ctx){
|
||||
return SSH_ERROR;
|
||||
if(session->socket==NULL)
|
||||
return SSH_ERROR;
|
||||
fd=ssh_socket_get_fd_in(session->socket);
|
||||
fd = ssh_socket_get_fd(session->socket);
|
||||
/* TODO: adapt for windows */
|
||||
if(fd<0)
|
||||
return SSH_ERROR;
|
||||
|
||||
52
src/pki.c
52
src/pki.c
@@ -214,6 +214,7 @@ ssh_key_signature_to_char(enum ssh_keytypes_e type,
|
||||
case SSH_DIGEST_SHA512:
|
||||
return "rsa-sha2-512";
|
||||
case SSH_DIGEST_SHA1:
|
||||
case SSH_DIGEST_AUTO:
|
||||
return "ssh-rsa";
|
||||
default:
|
||||
return NULL;
|
||||
@@ -271,13 +272,14 @@ static enum ssh_digest_e ssh_key_hash_from_name(const char *name)
|
||||
/* we do not care for others now */
|
||||
return SSH_DIGEST_AUTO;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Checks the given key against the configured allowed
|
||||
* public key algorithm types
|
||||
*
|
||||
* @param[in] session The SSH session
|
||||
* @parma[in] type The key algorithm to check
|
||||
* @returns 1 if the key algorithm is allowed 0 otherwise
|
||||
* @param[in] type The key algorithm to check
|
||||
* @returns 1 if the key algorithm is allowed, 0 otherwise
|
||||
*/
|
||||
int ssh_key_algorithm_allowed(ssh_session session, const char *type)
|
||||
{
|
||||
@@ -1534,7 +1536,7 @@ int ssh_pki_import_cert_file(const char *filename, ssh_key *pkey)
|
||||
* @param[in] parameter Parameter to the creation of key:
|
||||
* rsa : length of the key in bits (e.g. 1024, 2048, 4096)
|
||||
* dsa : length of the key in bits (e.g. 1024, 2048, 3072)
|
||||
* ecdsa : bits of the key (e.g. 256, 384, 512)
|
||||
* ecdsa : bits of the key (e.g. 256, 384, 521)
|
||||
* @param[out] pkey A pointer to store the allocated private key. You need
|
||||
* to free the memory.
|
||||
*
|
||||
@@ -1863,10 +1865,10 @@ int ssh_pki_import_signature_blob(const ssh_string sig_blob,
|
||||
const ssh_key pubkey,
|
||||
ssh_signature *psig)
|
||||
{
|
||||
ssh_signature sig;
|
||||
ssh_signature sig = NULL;
|
||||
enum ssh_keytypes_e type;
|
||||
enum ssh_digest_e hash_type;
|
||||
ssh_string str;
|
||||
ssh_string algorithm = NULL, blob = NULL;
|
||||
ssh_buffer buf;
|
||||
const char *alg = NULL;
|
||||
int rc;
|
||||
@@ -1888,25 +1890,25 @@ int ssh_pki_import_signature_blob(const ssh_string sig_blob,
|
||||
return SSH_ERROR;
|
||||
}
|
||||
|
||||
str = ssh_buffer_get_ssh_string(buf);
|
||||
if (str == NULL) {
|
||||
algorithm = ssh_buffer_get_ssh_string(buf);
|
||||
if (algorithm == NULL) {
|
||||
ssh_buffer_free(buf);
|
||||
return SSH_ERROR;
|
||||
}
|
||||
|
||||
alg = ssh_string_get_char(str);
|
||||
alg = ssh_string_get_char(algorithm);
|
||||
type = ssh_key_type_from_signature_name(alg);
|
||||
hash_type = ssh_key_hash_from_name(alg);
|
||||
ssh_string_free(str);
|
||||
ssh_string_free(algorithm);
|
||||
|
||||
str = ssh_buffer_get_ssh_string(buf);
|
||||
blob = ssh_buffer_get_ssh_string(buf);
|
||||
ssh_buffer_free(buf);
|
||||
if (str == NULL) {
|
||||
if (blob == NULL) {
|
||||
return SSH_ERROR;
|
||||
}
|
||||
|
||||
sig = pki_signature_from_blob(pubkey, str, type, hash_type);
|
||||
ssh_string_free(str);
|
||||
sig = pki_signature_from_blob(pubkey, blob, type, hash_type);
|
||||
ssh_string_free(blob);
|
||||
if (sig == NULL) {
|
||||
return SSH_ERROR;
|
||||
}
|
||||
@@ -1915,24 +1917,24 @@ int ssh_pki_import_signature_blob(const ssh_string sig_blob,
|
||||
return SSH_OK;
|
||||
}
|
||||
|
||||
int ssh_pki_signature_verify_blob(ssh_session session,
|
||||
ssh_string sig_blob,
|
||||
const ssh_key key,
|
||||
unsigned char *digest,
|
||||
size_t dlen)
|
||||
int ssh_pki_signature_verify(ssh_session session,
|
||||
ssh_signature sig,
|
||||
const ssh_key key,
|
||||
unsigned char *digest,
|
||||
size_t dlen)
|
||||
{
|
||||
ssh_signature sig;
|
||||
int rc;
|
||||
|
||||
rc = ssh_pki_import_signature_blob(sig_blob, key, &sig);
|
||||
if (rc < 0) {
|
||||
return SSH_ERROR;
|
||||
}
|
||||
|
||||
SSH_LOG(SSH_LOG_FUNCTIONS,
|
||||
"Going to verify a %s type signature",
|
||||
sig->type_c);
|
||||
|
||||
if (key->type != sig->type) {
|
||||
SSH_LOG(SSH_LOG_WARN,
|
||||
"Can not verify %s signature with %s key",
|
||||
sig->type_c, key->type_c);
|
||||
return SSH_ERROR;
|
||||
}
|
||||
|
||||
if (key->type == SSH_KEYTYPE_ECDSA) {
|
||||
#if HAVE_ECC
|
||||
@@ -1996,8 +1998,6 @@ int ssh_pki_signature_verify_blob(ssh_session session,
|
||||
hlen);
|
||||
}
|
||||
|
||||
ssh_signature_free(sig);
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
|
||||
@@ -409,7 +409,7 @@ static int pki_openssh_export_privkey_blob(const ssh_key privkey,
|
||||
return SSH_ERROR;
|
||||
}
|
||||
if (privkey->ed25519_privkey == NULL ||
|
||||
privkey->ed25519_pubkey == NULL){
|
||||
privkey->ed25519_pubkey == NULL) {
|
||||
return SSH_ERROR;
|
||||
}
|
||||
rc = ssh_buffer_pack(buffer,
|
||||
@@ -442,7 +442,6 @@ static int pki_private_key_encrypt(ssh_buffer privkey_buffer,
|
||||
char passphrase_buffer[128];
|
||||
int rc;
|
||||
int i;
|
||||
uint8_t padding = 1;
|
||||
int cmp;
|
||||
|
||||
cmp = strcmp(ciphername, "none");
|
||||
@@ -469,14 +468,6 @@ static int pki_private_key_encrypt(ssh_buffer privkey_buffer,
|
||||
SSH_LOG(SSH_LOG_WARN, "Unsupported KDF %s", kdfname);
|
||||
return SSH_ERROR;
|
||||
}
|
||||
while (ssh_buffer_get_len(privkey_buffer) % cipher.blocksize != 0) {
|
||||
rc = ssh_buffer_add_u8(privkey_buffer, padding);
|
||||
if (rc < 0) {
|
||||
return SSH_ERROR;
|
||||
}
|
||||
padding++;
|
||||
}
|
||||
|
||||
/* We need material for key (keysize bits / 8) and IV (blocksize) */
|
||||
key_material_len = cipher.keysize/8 + cipher.blocksize;
|
||||
if (key_material_len > sizeof(key_material)){
|
||||
@@ -553,6 +544,7 @@ ssh_string ssh_pki_openssh_privkey_export(const ssh_key privkey,
|
||||
int to_encrypt=0;
|
||||
unsigned char *b64;
|
||||
uint32_t str_len, len;
|
||||
uint8_t padding = 1;
|
||||
int ok;
|
||||
int rc;
|
||||
|
||||
@@ -603,6 +595,18 @@ ssh_string ssh_pki_openssh_privkey_export(const ssh_key privkey,
|
||||
goto error;
|
||||
}
|
||||
|
||||
/* Add padding regardless encryption because it is expected
|
||||
* by OpenSSH tools.
|
||||
* XXX Using 16 B as we use only AES cipher below anyway.
|
||||
*/
|
||||
while (ssh_buffer_get_len(privkey_buffer) % 16 != 0) {
|
||||
rc = ssh_buffer_add_u8(privkey_buffer, padding);
|
||||
if (rc < 0) {
|
||||
goto error;
|
||||
}
|
||||
padding++;
|
||||
}
|
||||
|
||||
if (to_encrypt){
|
||||
ssh_buffer kdf_buf;
|
||||
|
||||
|
||||
@@ -516,7 +516,7 @@ int pki_key_generate_rsa(ssh_key key, int parameter){
|
||||
|
||||
int pki_key_generate_dss(ssh_key key, int parameter){
|
||||
int rc;
|
||||
#if OPENSSL_VERSION_NUMBER > 0x10100000L
|
||||
#if OPENSSL_VERSION_NUMBER > 0x00908000L
|
||||
key->dsa = DSA_new();
|
||||
if (key->dsa == NULL) {
|
||||
return SSH_ERROR;
|
||||
@@ -558,7 +558,7 @@ int pki_key_generate_ecdsa(ssh_key key, int parameter) {
|
||||
case 384:
|
||||
nid = NID_secp384r1;
|
||||
break;
|
||||
case 512:
|
||||
case 521:
|
||||
nid = NID_secp521r1;
|
||||
break;
|
||||
case 256:
|
||||
@@ -790,7 +790,7 @@ ssh_string pki_private_key_to_pem(const ssh_key key,
|
||||
case SSH_KEYTYPE_UNKNOWN:
|
||||
default:
|
||||
BIO_free(mem);
|
||||
SSH_LOG(SSH_LOG_WARN, "Unkown or invalid private key type %d", key->type);
|
||||
SSH_LOG(SSH_LOG_WARN, "Unknown or invalid private key type %d", key->type);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@@ -916,7 +916,7 @@ ssh_key pki_private_key_from_base64(const char *b64_key,
|
||||
case SSH_KEYTYPE_RSA_CERT01:
|
||||
case SSH_KEYTYPE_UNKNOWN:
|
||||
BIO_free(mem);
|
||||
SSH_LOG(SSH_LOG_WARN, "Unkown or invalid private key type %d", type);
|
||||
SSH_LOG(SSH_LOG_WARN, "Unknown or invalid private key type %d", type);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@@ -1600,6 +1600,14 @@ ssh_signature pki_signature_from_blob(const ssh_key pubkey,
|
||||
int rc;
|
||||
BIGNUM *pr = NULL, *ps = NULL;
|
||||
|
||||
if (type != pubkey->type) {
|
||||
SSH_LOG(SSH_LOG_WARN,
|
||||
"Incompatible public key provided (%d) expecting (%d)",
|
||||
type,
|
||||
pubkey->type);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
sig = ssh_signature_new();
|
||||
if (sig == NULL) {
|
||||
return NULL;
|
||||
@@ -1607,7 +1615,7 @@ ssh_signature pki_signature_from_blob(const ssh_key pubkey,
|
||||
|
||||
sig->type = type;
|
||||
sig->hash_type = hash_type;
|
||||
sig->type_c = ssh_key_signature_to_char(type, hash_type);
|
||||
sig->type_c = pubkey->type_c; /* for all types but RSA */
|
||||
|
||||
len = ssh_string_len(sig_blob);
|
||||
|
||||
@@ -1649,6 +1657,7 @@ ssh_signature pki_signature_from_blob(const ssh_key pubkey,
|
||||
|
||||
s = ssh_string_new(20);
|
||||
if (s == NULL) {
|
||||
bignum_safe_free(pr);
|
||||
ssh_signature_free(sig);
|
||||
return NULL;
|
||||
}
|
||||
@@ -1657,6 +1666,7 @@ ssh_signature pki_signature_from_blob(const ssh_key pubkey,
|
||||
ps = ssh_make_string_bn(s);
|
||||
ssh_string_free(s);
|
||||
if (ps == NULL) {
|
||||
bignum_safe_free(pr);
|
||||
ssh_signature_free(sig);
|
||||
return NULL;
|
||||
}
|
||||
@@ -1665,6 +1675,8 @@ ssh_signature pki_signature_from_blob(const ssh_key pubkey,
|
||||
* object */
|
||||
rc = DSA_SIG_set0(sig->dsa_sig, pr, ps);
|
||||
if (rc == 0) {
|
||||
bignum_safe_free(ps);
|
||||
bignum_safe_free(pr);
|
||||
ssh_signature_free(sig);
|
||||
return NULL;
|
||||
}
|
||||
@@ -1673,6 +1685,10 @@ ssh_signature pki_signature_from_blob(const ssh_key pubkey,
|
||||
case SSH_KEYTYPE_RSA:
|
||||
case SSH_KEYTYPE_RSA1:
|
||||
sig = pki_signature_from_rsa_blob(pubkey, sig_blob, sig);
|
||||
if (sig == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
sig->type_c = ssh_key_signature_to_char(type, hash_type);
|
||||
break;
|
||||
case SSH_KEYTYPE_ECDSA:
|
||||
#ifdef HAVE_OPENSSL_ECC
|
||||
@@ -1725,6 +1741,7 @@ ssh_signature pki_signature_from_blob(const ssh_key pubkey,
|
||||
rlen = ssh_buffer_get_len(b);
|
||||
ssh_buffer_free(b);
|
||||
if (s == NULL) {
|
||||
bignum_safe_free(pr);
|
||||
ssh_signature_free(sig);
|
||||
return NULL;
|
||||
}
|
||||
@@ -1737,6 +1754,7 @@ ssh_signature pki_signature_from_blob(const ssh_key pubkey,
|
||||
ssh_string_burn(s);
|
||||
ssh_string_free(s);
|
||||
if (ps == NULL) {
|
||||
bignum_safe_free(pr);
|
||||
ssh_signature_free(sig);
|
||||
return NULL;
|
||||
}
|
||||
@@ -1745,6 +1763,8 @@ ssh_signature pki_signature_from_blob(const ssh_key pubkey,
|
||||
* ECDSA signature object */
|
||||
rc = ECDSA_SIG_set0(sig->ecdsa_sig, pr, ps);
|
||||
if (rc == 0) {
|
||||
bignum_safe_free(ps);
|
||||
bignum_safe_free(pr);
|
||||
ssh_signature_free(sig);
|
||||
return NULL;
|
||||
}
|
||||
@@ -1787,7 +1807,15 @@ int pki_signature_verify(ssh_session session,
|
||||
int rc;
|
||||
int nid;
|
||||
|
||||
switch(key->type) {
|
||||
if (key->type != sig->type) {
|
||||
SSH_LOG(SSH_LOG_WARN,
|
||||
"Can not verify %s signature with %s key",
|
||||
sig->type_c,
|
||||
key->type_c);
|
||||
return SSH_ERROR;
|
||||
}
|
||||
|
||||
switch (key->type) {
|
||||
case SSH_KEYTYPE_DSS:
|
||||
rc = DSA_do_verify(hash,
|
||||
hlen,
|
||||
|
||||
@@ -28,6 +28,7 @@
|
||||
#ifdef HAVE_LIBGCRYPT
|
||||
|
||||
#include <assert.h>
|
||||
#include <stdbool.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <gcrypt.h>
|
||||
@@ -389,7 +390,7 @@ static int privatekey_dek_header(const char *header, unsigned int header_len,
|
||||
while(p[len] == '\n' || p[len] == '\r') /* skip empty lines */ \
|
||||
len++; \
|
||||
if(p[len] == '\0') /* EOL */ \
|
||||
len = -1; \
|
||||
eol = true; \
|
||||
else /* calculate length */ \
|
||||
for(p += len, len = 0; p[len] && p[len] != '\n' \
|
||||
&& p[len] != '\r'; len++); \
|
||||
@@ -409,7 +410,8 @@ static ssh_buffer privatekey_string_to_buffer(const char *pkey, int type,
|
||||
unsigned int iv_len = 0;
|
||||
int algo = 0;
|
||||
int mode = 0;
|
||||
int len;
|
||||
bool eol = false;
|
||||
size_t len;
|
||||
|
||||
buffer = ssh_buffer_new();
|
||||
if (buffer == NULL) {
|
||||
@@ -441,25 +443,38 @@ static ssh_buffer privatekey_string_to_buffer(const char *pkey, int type,
|
||||
len = 0;
|
||||
get_next_line(p, len);
|
||||
|
||||
while(len > 0 && strncmp(p, header_begin, header_begin_size)) {
|
||||
while(!eol && strncmp(p, header_begin, header_begin_size)) {
|
||||
/* skip line */
|
||||
get_next_line(p, len);
|
||||
}
|
||||
if(len < 0) {
|
||||
/* no header found */
|
||||
if (eol) {
|
||||
ssh_buffer_free(buffer);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* skip header line */
|
||||
get_next_line(p, len);
|
||||
if (eol) {
|
||||
ssh_buffer_free(buffer);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (len > 11 && strncmp("Proc-Type: 4,ENCRYPTED", p, 11) == 0) {
|
||||
/* skip line */
|
||||
get_next_line(p, len);
|
||||
if (eol) {
|
||||
ssh_buffer_free(buffer);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (len > 10 && strncmp("DEK-Info: ", p, 10) == 0) {
|
||||
p += 10;
|
||||
len = 0;
|
||||
get_next_line(p, len);
|
||||
if (eol) {
|
||||
ssh_buffer_free(buffer);
|
||||
return NULL;
|
||||
}
|
||||
if (privatekey_dek_header(p, len, &algo, &mode, &key_len,
|
||||
&iv, &iv_len) < 0) {
|
||||
ssh_buffer_free(buffer);
|
||||
@@ -482,7 +497,7 @@ static ssh_buffer privatekey_string_to_buffer(const char *pkey, int type,
|
||||
}
|
||||
|
||||
get_next_line(p, len);
|
||||
while(len > 0 && strncmp(p, header_end, header_end_size) != 0) {
|
||||
while(!eol && strncmp(p, header_end, header_end_size) != 0) {
|
||||
if (ssh_buffer_add_data(buffer, p, len) < 0) {
|
||||
ssh_buffer_free(buffer);
|
||||
SAFE_FREE(iv);
|
||||
@@ -491,7 +506,7 @@ static ssh_buffer privatekey_string_to_buffer(const char *pkey, int type,
|
||||
get_next_line(p, len);
|
||||
}
|
||||
|
||||
if (len == -1 || strncmp(p, header_end, header_end_size) != 0) {
|
||||
if (eol || strncmp(p, header_end, header_end_size) != 0) {
|
||||
ssh_buffer_free(buffer);
|
||||
SAFE_FREE(iv);
|
||||
return NULL;
|
||||
@@ -998,7 +1013,7 @@ ssh_key pki_private_key_from_base64(const char *b64_key,
|
||||
case SSH_KEYTYPE_RSA1:
|
||||
case SSH_KEYTYPE_UNKNOWN:
|
||||
default:
|
||||
SSH_LOG(SSH_LOG_WARN, "Unkown or invalid private key type %d", type);
|
||||
SSH_LOG(SSH_LOG_WARN, "Unknown or invalid private key type %d", type);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@@ -1348,7 +1363,7 @@ int pki_key_generate_ecdsa(ssh_key key, int parameter) {
|
||||
case 384:
|
||||
nid = NID_gcrypt_nistp384;
|
||||
break;
|
||||
case 512:
|
||||
case 521:
|
||||
nid = NID_gcrypt_nistp521;
|
||||
break;
|
||||
case 256:
|
||||
@@ -1848,6 +1863,14 @@ ssh_signature pki_signature_from_blob(const ssh_key pubkey,
|
||||
size_t rsalen;
|
||||
int rc;
|
||||
|
||||
if (type != pubkey->type) {
|
||||
SSH_LOG(SSH_LOG_WARN,
|
||||
"Incompatible public key provided (%d) expecting (%d)",
|
||||
type,
|
||||
pubkey->type);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
sig = ssh_signature_new();
|
||||
if (sig == NULL) {
|
||||
return NULL;
|
||||
@@ -1855,7 +1878,7 @@ ssh_signature pki_signature_from_blob(const ssh_key pubkey,
|
||||
|
||||
sig->type = type;
|
||||
sig->hash_type = hash_type;
|
||||
sig->type_c = ssh_key_signature_to_char(type, hash_type);
|
||||
sig->type_c = pubkey->type_c; /* for all types but RSA */
|
||||
|
||||
len = ssh_string_len(sig_blob);
|
||||
|
||||
@@ -1921,6 +1944,7 @@ ssh_signature pki_signature_from_blob(const ssh_key pubkey,
|
||||
ssh_signature_free(sig);
|
||||
return NULL;
|
||||
}
|
||||
sig->type_c = ssh_key_signature_to_char(type, hash_type);
|
||||
break;
|
||||
case SSH_KEYTYPE_ED25519:
|
||||
rc = pki_ed25519_sig_from_blob(sig, sig_blob);
|
||||
@@ -2025,6 +2049,14 @@ int pki_signature_verify(ssh_session session,
|
||||
gcry_sexp_t sexp;
|
||||
gcry_error_t err;
|
||||
|
||||
if (key->type != sig->type) {
|
||||
SSH_LOG(SSH_LOG_WARN,
|
||||
"Can not verify %s signature with %s key",
|
||||
sig->type_c,
|
||||
key->type_c);
|
||||
return SSH_ERROR;
|
||||
}
|
||||
|
||||
switch(key->type) {
|
||||
case SSH_KEYTYPE_DSS:
|
||||
/* That is to mark the number as positive */
|
||||
@@ -2124,7 +2156,6 @@ int pki_signature_verify(ssh_session session,
|
||||
gcry_sexp_release(sexp);
|
||||
if (err) {
|
||||
ssh_set_error(session, SSH_FATAL, "Invalid ECDSA signature");
|
||||
abort();
|
||||
if (gcry_err_code(err) != GPG_ERR_BAD_SIGNATURE) {
|
||||
ssh_set_error(session,
|
||||
SSH_FATAL,
|
||||
|
||||
@@ -897,6 +897,14 @@ ssh_signature pki_signature_from_blob(const ssh_key pubkey,
|
||||
ssh_signature sig = NULL;
|
||||
int rc;
|
||||
|
||||
if (type != pubkey->type) {
|
||||
SSH_LOG(SSH_LOG_WARN,
|
||||
"Incompatible public key provided (%d) expecting (%d)",
|
||||
type,
|
||||
pubkey->type);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
sig = ssh_signature_new();
|
||||
if (sig == NULL) {
|
||||
return NULL;
|
||||
@@ -904,11 +912,15 @@ ssh_signature pki_signature_from_blob(const ssh_key pubkey,
|
||||
|
||||
sig->type = type;
|
||||
sig->hash_type = hash_type;
|
||||
sig->type_c = ssh_key_signature_to_char(type, hash_type);
|
||||
sig->type_c = pubkey->type_c; /* for all types but RSA */
|
||||
|
||||
switch(type) {
|
||||
case SSH_KEYTYPE_RSA:
|
||||
sig = pki_signature_from_rsa_blob(pubkey, sig_blob, sig);
|
||||
if (sig == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
sig->type_c = ssh_key_signature_to_char(type, hash_type);
|
||||
break;
|
||||
case SSH_KEYTYPE_ECDSA: {
|
||||
ssh_buffer b;
|
||||
@@ -999,6 +1011,14 @@ int pki_signature_verify(ssh_session session, const ssh_signature sig, const
|
||||
int rc;
|
||||
mbedtls_md_type_t md = 0;
|
||||
|
||||
if (key->type != sig->type) {
|
||||
SSH_LOG(SSH_LOG_WARN,
|
||||
"Can not verify %s signature with %s key",
|
||||
sig->type_c,
|
||||
key->type_c);
|
||||
return SSH_ERROR;
|
||||
}
|
||||
|
||||
switch (key->type) {
|
||||
case SSH_KEYTYPE_RSA:
|
||||
switch (sig->hash_type) {
|
||||
@@ -1439,7 +1459,7 @@ int pki_key_generate_ecdsa(ssh_key key, int parameter)
|
||||
case 384:
|
||||
nid = NID_mbedtls_nistp384;
|
||||
break;
|
||||
case 512:
|
||||
case 521:
|
||||
nid = NID_mbedtls_nistp521;
|
||||
break;
|
||||
case 256:
|
||||
|
||||
22
src/poll.c
22
src/poll.c
@@ -533,19 +533,17 @@ int ssh_poll_ctx_add(ssh_poll_ctx ctx, ssh_poll_handle p) {
|
||||
*
|
||||
* @return 0 on success, < 0 on error
|
||||
*/
|
||||
int ssh_poll_ctx_add_socket (ssh_poll_ctx ctx, ssh_socket s) {
|
||||
ssh_poll_handle p_in, p_out;
|
||||
int ret;
|
||||
p_in=ssh_socket_get_poll_handle_in(s);
|
||||
if(p_in==NULL)
|
||||
return -1;
|
||||
ret = ssh_poll_ctx_add(ctx,p_in);
|
||||
if(ret != 0)
|
||||
int ssh_poll_ctx_add_socket (ssh_poll_ctx ctx, ssh_socket s)
|
||||
{
|
||||
ssh_poll_handle p;
|
||||
int ret;
|
||||
|
||||
p = ssh_socket_get_poll_handle(s);
|
||||
if (p == NULL) {
|
||||
return -1;
|
||||
}
|
||||
ret = ssh_poll_ctx_add(ctx,p);
|
||||
return ret;
|
||||
p_out=ssh_socket_get_poll_handle_out(s);
|
||||
if(p_in != p_out)
|
||||
ret = ssh_poll_ctx_add(ctx,p_out);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
|
||||
46
src/server.c
46
src/server.c
@@ -453,6 +453,7 @@ static void ssh_server_connection_callback(ssh_session session){
|
||||
|
||||
/* from now, the packet layer is handling incoming packets */
|
||||
session->socket_callbacks.data=ssh_packet_socket_callback;
|
||||
ssh_packet_register_socket_callback(session, session->socket);
|
||||
|
||||
ssh_packet_set_default_callbacks(session);
|
||||
set_status(session, 0.5f);
|
||||
@@ -518,20 +519,22 @@ static void ssh_server_connection_callback(ssh_session session){
|
||||
goto error;
|
||||
}
|
||||
|
||||
/*
|
||||
* If the client supports extension negotiation, we will send
|
||||
* our supported extensions now. This is the first message after
|
||||
* sending NEWKEYS message and after turning on crypto.
|
||||
*/
|
||||
if (session->extensions & SSH_EXT_NEGOTIATION &&
|
||||
session->session_state != SSH_SESSION_STATE_AUTHENTICATED) {
|
||||
ssh_server_send_extensions(session);
|
||||
}
|
||||
|
||||
set_status(session,1.0f);
|
||||
session->connected = 1;
|
||||
session->session_state=SSH_SESSION_STATE_AUTHENTICATING;
|
||||
if (session->flags & SSH_SESSION_FLAG_AUTHENTICATED)
|
||||
session->session_state = SSH_SESSION_STATE_AUTHENTICATED;
|
||||
|
||||
/*
|
||||
* If the client supports extension negotiation, we will send
|
||||
* our supported extensions now. This is the first message after
|
||||
* sending NEWKEYS message and after turning on crypto.
|
||||
*/
|
||||
if (session->extensions) {
|
||||
ssh_server_send_extensions(session);
|
||||
}
|
||||
}
|
||||
break;
|
||||
case SSH_SESSION_STATE_AUTHENTICATING:
|
||||
@@ -1039,6 +1042,7 @@ int ssh_message_auth_interactive_request(ssh_message msg, const char *name,
|
||||
msg->session->kbdint->prompts = NULL;
|
||||
msg->session->kbdint->echo = NULL;
|
||||
}
|
||||
msg->session->auth.state = SSH_AUTH_STATE_INFO;
|
||||
|
||||
return rc;
|
||||
}
|
||||
@@ -1252,30 +1256,10 @@ int ssh_execute_message_callbacks(ssh_session session){
|
||||
|
||||
int ssh_send_keepalive(ssh_session session)
|
||||
{
|
||||
int rc;
|
||||
/* Client denies the request, so the error code is not meaningful */
|
||||
(void)ssh_global_request(session, "keepalive@openssh.com", NULL, 1);
|
||||
|
||||
rc = ssh_buffer_pack(session->out_buffer,
|
||||
"bsb",
|
||||
SSH2_MSG_GLOBAL_REQUEST,
|
||||
"keepalive@openssh.com",
|
||||
1);
|
||||
if (rc != SSH_OK) {
|
||||
goto err;
|
||||
}
|
||||
|
||||
if (ssh_packet_send(session) == SSH_ERROR) {
|
||||
goto err;
|
||||
}
|
||||
|
||||
ssh_handle_packets(session, SSH_TIMEOUT_NONBLOCKING);
|
||||
|
||||
SSH_LOG(SSH_LOG_PACKET, "Sent a keepalive");
|
||||
return SSH_OK;
|
||||
|
||||
err:
|
||||
ssh_set_error_oom(session);
|
||||
ssh_buffer_reinit(session->out_buffer);
|
||||
return SSH_ERROR;
|
||||
return SSH_OK;
|
||||
}
|
||||
|
||||
/** @} */
|
||||
|
||||
@@ -536,7 +536,7 @@ socket_t ssh_get_fd(ssh_session session) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
return ssh_socket_get_fd_in(session->socket);
|
||||
return ssh_socket_get_fd(session->socket);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -599,7 +599,7 @@ void ssh_set_fd_except(ssh_session session) {
|
||||
* @return SSH_OK on success, SSH_ERROR otherwise.
|
||||
*/
|
||||
int ssh_handle_packets(ssh_session session, int timeout) {
|
||||
ssh_poll_handle spoll_in,spoll_out;
|
||||
ssh_poll_handle spoll;
|
||||
ssh_poll_ctx ctx;
|
||||
int tm = timeout;
|
||||
int rc;
|
||||
@@ -608,17 +608,13 @@ int ssh_handle_packets(ssh_session session, int timeout) {
|
||||
return SSH_ERROR;
|
||||
}
|
||||
|
||||
spoll_in = ssh_socket_get_poll_handle_in(session->socket);
|
||||
spoll_out = ssh_socket_get_poll_handle_out(session->socket);
|
||||
ssh_poll_add_events(spoll_in, POLLIN);
|
||||
ctx = ssh_poll_get_ctx(spoll_in);
|
||||
spoll = ssh_socket_get_poll_handle(session->socket);
|
||||
ssh_poll_add_events(spoll, POLLIN);
|
||||
ctx = ssh_poll_get_ctx(spoll);
|
||||
|
||||
if (!ctx) {
|
||||
ctx = ssh_poll_get_default_ctx(session);
|
||||
ssh_poll_ctx_add(ctx, spoll_in);
|
||||
if (spoll_in != spoll_out) {
|
||||
ssh_poll_ctx_add(ctx, spoll_out);
|
||||
}
|
||||
ssh_poll_ctx_add(ctx, spoll);
|
||||
}
|
||||
|
||||
if (timeout == SSH_TIMEOUT_USER) {
|
||||
|
||||
@@ -127,22 +127,26 @@ sftp_session sftp_new(ssh_session session)
|
||||
|
||||
sftp->ext = sftp_ext_new();
|
||||
if (sftp->ext == NULL) {
|
||||
ssh_set_error_oom(session);
|
||||
goto error;
|
||||
}
|
||||
|
||||
sftp->read_packet = calloc(1, sizeof(struct sftp_packet_struct));
|
||||
if (sftp->read_packet == NULL) {
|
||||
ssh_set_error_oom(session);
|
||||
goto error;
|
||||
}
|
||||
|
||||
sftp->read_packet->payload = ssh_buffer_new();
|
||||
if (sftp->read_packet->payload == NULL) {
|
||||
ssh_set_error_oom(session);
|
||||
goto error;
|
||||
}
|
||||
|
||||
sftp->session = session;
|
||||
sftp->channel = ssh_channel_new(session);
|
||||
if (sftp->channel == NULL) {
|
||||
ssh_set_error_oom(session);
|
||||
goto error;
|
||||
}
|
||||
|
||||
@@ -156,7 +160,6 @@ sftp_session sftp_new(ssh_session session)
|
||||
|
||||
return sftp;
|
||||
error:
|
||||
ssh_set_error_oom(session);
|
||||
if (sftp->ext != NULL) {
|
||||
sftp_ext_free(sftp->ext);
|
||||
}
|
||||
|
||||
206
src/socket.c
206
src/socket.c
@@ -74,8 +74,7 @@ enum ssh_socket_states_e {
|
||||
};
|
||||
|
||||
struct ssh_socket_struct {
|
||||
socket_t fd_in;
|
||||
socket_t fd_out;
|
||||
socket_t fd;
|
||||
int fd_is_socket;
|
||||
int last_errno;
|
||||
int read_wontblock; /* reading now on socket will
|
||||
@@ -87,8 +86,7 @@ struct ssh_socket_struct {
|
||||
ssh_buffer in_buffer;
|
||||
ssh_session session;
|
||||
ssh_socket_callbacks callbacks;
|
||||
ssh_poll_handle poll_in;
|
||||
ssh_poll_handle poll_out;
|
||||
ssh_poll_handle poll_handle;
|
||||
};
|
||||
|
||||
static int sockets_initialized = 0;
|
||||
@@ -149,8 +147,7 @@ ssh_socket ssh_socket_new(ssh_session session) {
|
||||
ssh_set_error_oom(session);
|
||||
return NULL;
|
||||
}
|
||||
s->fd_in = SSH_INVALID_SOCKET;
|
||||
s->fd_out= SSH_INVALID_SOCKET;
|
||||
s->fd = SSH_INVALID_SOCKET;
|
||||
s->last_errno = -1;
|
||||
s->fd_is_socket = 1;
|
||||
s->session = session;
|
||||
@@ -170,7 +167,7 @@ ssh_socket ssh_socket_new(ssh_session session) {
|
||||
s->read_wontblock = 0;
|
||||
s->write_wontblock = 0;
|
||||
s->data_except = 0;
|
||||
s->poll_in=s->poll_out=NULL;
|
||||
s->poll_handle = NULL;
|
||||
s->state=SSH_SOCKET_NONE;
|
||||
return s;
|
||||
}
|
||||
@@ -181,8 +178,7 @@ ssh_socket ssh_socket_new(ssh_session session) {
|
||||
* @param[in] s socket to rest
|
||||
*/
|
||||
void ssh_socket_reset(ssh_socket s){
|
||||
s->fd_in = SSH_INVALID_SOCKET;
|
||||
s->fd_out= SSH_INVALID_SOCKET;
|
||||
s->fd = SSH_INVALID_SOCKET;
|
||||
s->last_errno = -1;
|
||||
s->fd_is_socket = 1;
|
||||
ssh_buffer_reinit(s->in_buffer);
|
||||
@@ -190,7 +186,7 @@ void ssh_socket_reset(ssh_socket s){
|
||||
s->read_wontblock = 0;
|
||||
s->write_wontblock = 0;
|
||||
s->data_except = 0;
|
||||
s->poll_in=s->poll_out=NULL;
|
||||
s->poll_handle = NULL;
|
||||
s->state=SSH_SOCKET_NONE;
|
||||
}
|
||||
|
||||
@@ -240,7 +236,7 @@ int ssh_socket_pollcallback(struct ssh_poll_handle_struct *p,
|
||||
(revents & POLLOUT) ? "POLLOUT ":"",
|
||||
(revents & POLLERR) ? "POLLERR":"",
|
||||
ssh_buffer_get_len(s->out_buffer));
|
||||
if (revents & POLLERR || revents & POLLHUP) {
|
||||
if ((revents & POLLERR) || (revents & POLLHUP)) {
|
||||
/* Check if we are in a connecting state */
|
||||
if (s->state == SSH_SOCKET_CONNECTING) {
|
||||
s->state = SSH_SOCKET_ERROR;
|
||||
@@ -274,17 +270,10 @@ int ssh_socket_pollcallback(struct ssh_poll_handle_struct *p,
|
||||
s->callbacks->exception(SSH_SOCKET_EXCEPTION_ERROR,
|
||||
s->last_errno,
|
||||
s->callbacks->userdata);
|
||||
|
||||
/* p may have been freed, so don't use it
|
||||
* anymore in this function */
|
||||
p = NULL;
|
||||
return -2;
|
||||
}
|
||||
return -2;
|
||||
}
|
||||
if (nread == 0) {
|
||||
if (p != NULL) {
|
||||
ssh_poll_remove_events(p, POLLIN);
|
||||
}
|
||||
if (p != NULL) {
|
||||
ssh_poll_remove_events(p, POLLIN);
|
||||
}
|
||||
@@ -292,12 +281,8 @@ int ssh_socket_pollcallback(struct ssh_poll_handle_struct *p,
|
||||
s->callbacks->exception(SSH_SOCKET_EXCEPTION_EOF,
|
||||
0,
|
||||
s->callbacks->userdata);
|
||||
|
||||
/* p may have been freed, so don't use it
|
||||
* anymore in this function */
|
||||
p = NULL;
|
||||
return -2;
|
||||
}
|
||||
return -2;
|
||||
}
|
||||
|
||||
if (s->session->socket_counter != NULL) {
|
||||
@@ -337,7 +322,7 @@ int ssh_socket_pollcallback(struct ssh_poll_handle_struct *p,
|
||||
ssh_poll_set_events(p, POLLOUT | POLLIN);
|
||||
}
|
||||
|
||||
rc = ssh_socket_set_blocking(ssh_socket_get_fd_in(s));
|
||||
rc = ssh_socket_set_blocking(ssh_socket_get_fd(s));
|
||||
if (rc < 0) {
|
||||
return -1;
|
||||
}
|
||||
@@ -370,8 +355,8 @@ int ssh_socket_pollcallback(struct ssh_poll_handle_struct *p,
|
||||
/* TODO: Find a way to put back POLLOUT when buffering occurs */
|
||||
}
|
||||
|
||||
/* Return -1 if one of the poll handlers disappeared */
|
||||
if (s->poll_in == NULL || s->poll_out == NULL) {
|
||||
/* Return -1 if the poll handler disappeared */
|
||||
if (s->poll_handle == NULL) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
@@ -379,31 +364,17 @@ int ssh_socket_pollcallback(struct ssh_poll_handle_struct *p,
|
||||
}
|
||||
|
||||
/** @internal
|
||||
* @brief returns the input poll handle corresponding to the socket,
|
||||
* @brief returns the poll handle corresponding to the socket,
|
||||
* creates it if it does not exist.
|
||||
* @returns allocated and initialized ssh_poll_handle object
|
||||
*/
|
||||
ssh_poll_handle ssh_socket_get_poll_handle_in(ssh_socket s){
|
||||
if(s->poll_in)
|
||||
return s->poll_in;
|
||||
s->poll_in=ssh_poll_new(s->fd_in,0,ssh_socket_pollcallback,s);
|
||||
if(s->fd_in == s->fd_out && s->poll_out == NULL)
|
||||
s->poll_out=s->poll_in;
|
||||
return s->poll_in;
|
||||
}
|
||||
|
||||
/** @internal
|
||||
* @brief returns the output poll handle corresponding to the socket,
|
||||
* creates it if it does not exist.
|
||||
* @returns allocated and initialized ssh_poll_handle object
|
||||
*/
|
||||
ssh_poll_handle ssh_socket_get_poll_handle_out(ssh_socket s){
|
||||
if(s->poll_out)
|
||||
return s->poll_out;
|
||||
s->poll_out=ssh_poll_new(s->fd_out,0,ssh_socket_pollcallback,s);
|
||||
if(s->fd_in == s->fd_out && s->poll_in == NULL)
|
||||
s->poll_in=s->poll_out;
|
||||
return s->poll_out;
|
||||
ssh_poll_handle ssh_socket_get_poll_handle(ssh_socket s)
|
||||
{
|
||||
if (s->poll_handle) {
|
||||
return s->poll_handle;
|
||||
}
|
||||
s->poll_handle = ssh_poll_new(s->fd,0,ssh_socket_pollcallback,s);
|
||||
return s->poll_handle;
|
||||
}
|
||||
|
||||
/** \internal
|
||||
@@ -460,27 +431,17 @@ int ssh_socket_unix(ssh_socket s, const char *path) {
|
||||
void ssh_socket_close(ssh_socket s){
|
||||
if (ssh_socket_is_open(s)) {
|
||||
#ifdef _WIN32
|
||||
CLOSE_SOCKET(s->fd_in);
|
||||
/* fd_in = fd_out under win32 */
|
||||
CLOSE_SOCKET(s->fd);
|
||||
s->last_errno = WSAGetLastError();
|
||||
#else
|
||||
if (s->fd_out != s->fd_in && s->fd_out != -1) {
|
||||
CLOSE_SOCKET(s->fd_out);
|
||||
}
|
||||
CLOSE_SOCKET(s->fd_in);
|
||||
CLOSE_SOCKET(s->fd);
|
||||
s->last_errno = errno;
|
||||
#endif
|
||||
}
|
||||
|
||||
if(s->poll_in != NULL){
|
||||
if(s->poll_out == s->poll_in)
|
||||
s->poll_out = NULL;
|
||||
ssh_poll_free(s->poll_in);
|
||||
s->poll_in=NULL;
|
||||
}
|
||||
if(s->poll_out != NULL){
|
||||
ssh_poll_free(s->poll_out);
|
||||
s->poll_out=NULL;
|
||||
if(s->poll_handle != NULL){
|
||||
ssh_poll_free(s->poll_handle);
|
||||
s->poll_handle=NULL;
|
||||
}
|
||||
|
||||
s->state = SSH_SOCKET_CLOSED;
|
||||
@@ -495,59 +456,34 @@ void ssh_socket_close(ssh_socket s){
|
||||
* file descriptors
|
||||
*/
|
||||
void ssh_socket_set_fd(ssh_socket s, socket_t fd) {
|
||||
s->fd_in = s->fd_out = fd;
|
||||
s->fd = fd;
|
||||
|
||||
if (s->poll_in) {
|
||||
ssh_poll_set_fd(s->poll_in,fd);
|
||||
if (s->poll_handle) {
|
||||
ssh_poll_set_fd(s->poll_handle,fd);
|
||||
} else {
|
||||
s->state = SSH_SOCKET_CONNECTING;
|
||||
|
||||
/* POLLOUT is the event to wait for in a nonblocking connect */
|
||||
ssh_poll_set_events(ssh_socket_get_poll_handle_in(s), POLLOUT);
|
||||
ssh_poll_set_events(ssh_socket_get_poll_handle(s), POLLOUT);
|
||||
#ifdef _WIN32
|
||||
ssh_poll_add_events(ssh_socket_get_poll_handle_in(s), POLLWRNORM);
|
||||
ssh_poll_add_events(ssh_socket_get_poll_handle(s), POLLWRNORM);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @internal
|
||||
* @brief sets the input file descriptor of the socket.
|
||||
* @param[out] s ssh_socket to update
|
||||
* @param[in] fd file descriptor to set
|
||||
*/
|
||||
void ssh_socket_set_fd_in(ssh_socket s, socket_t fd) {
|
||||
s->fd_in = fd;
|
||||
if(s->poll_in)
|
||||
ssh_poll_set_fd(s->poll_in,fd);
|
||||
}
|
||||
|
||||
/**
|
||||
* @internal
|
||||
* @brief sets the output file descriptor of the socket.
|
||||
* @param[out] s ssh_socket to update
|
||||
* @param[in] fd file descriptor to set
|
||||
*/
|
||||
void ssh_socket_set_fd_out(ssh_socket s, socket_t fd) {
|
||||
s->fd_out = fd;
|
||||
if(s->poll_out)
|
||||
ssh_poll_set_fd(s->poll_out,fd);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/** \internal
|
||||
* \brief returns the input file descriptor of the socket
|
||||
*/
|
||||
socket_t ssh_socket_get_fd_in(ssh_socket s) {
|
||||
return s->fd_in;
|
||||
socket_t ssh_socket_get_fd(ssh_socket s)
|
||||
{
|
||||
return s->fd;
|
||||
}
|
||||
|
||||
/** \internal
|
||||
* \brief returns nonzero if the socket is open
|
||||
*/
|
||||
int ssh_socket_is_open(ssh_socket s) {
|
||||
return s->fd_in != SSH_INVALID_SOCKET;
|
||||
return s->fd != SSH_INVALID_SOCKET;
|
||||
}
|
||||
|
||||
/** \internal
|
||||
@@ -563,9 +499,9 @@ static ssize_t ssh_socket_unbuffered_read(ssh_socket s,
|
||||
return -1;
|
||||
}
|
||||
if (s->fd_is_socket) {
|
||||
rc = recv(s->fd_in,buffer, len, 0);
|
||||
rc = recv(s->fd,buffer, len, 0);
|
||||
} else {
|
||||
rc = read(s->fd_in,buffer, len);
|
||||
rc = read(s->fd,buffer, len);
|
||||
}
|
||||
#ifdef _WIN32
|
||||
s->last_errno = WSAGetLastError();
|
||||
@@ -600,9 +536,9 @@ static ssize_t ssh_socket_unbuffered_write(ssh_socket s,
|
||||
}
|
||||
|
||||
if (s->fd_is_socket) {
|
||||
w = send(s->fd_out, buffer, len, flags);
|
||||
w = send(s->fd, buffer, len, flags);
|
||||
} else {
|
||||
w = write(s->fd_out, buffer, len);
|
||||
w = write(s->fd, buffer, len);
|
||||
}
|
||||
#ifdef _WIN32
|
||||
s->last_errno = WSAGetLastError();
|
||||
@@ -611,9 +547,9 @@ static ssize_t ssh_socket_unbuffered_write(ssh_socket s,
|
||||
#endif
|
||||
s->write_wontblock = 0;
|
||||
/* Reactive the POLLOUT detector in the poll multiplexer system */
|
||||
if (s->poll_out) {
|
||||
if (s->poll_handle) {
|
||||
SSH_LOG(SSH_LOG_PACKET, "Enabling POLLOUT for socket");
|
||||
ssh_poll_set_events(s->poll_out,ssh_poll_get_events(s->poll_out) | POLLOUT);
|
||||
ssh_poll_set_events(s->poll_handle,ssh_poll_get_events(s->poll_handle) | POLLOUT);
|
||||
}
|
||||
if (w < 0) {
|
||||
s->data_except = 1;
|
||||
@@ -626,10 +562,10 @@ static ssize_t ssh_socket_unbuffered_write(ssh_socket s,
|
||||
* \brief returns nonzero if the current socket is in the fd_set
|
||||
*/
|
||||
int ssh_socket_fd_isset(ssh_socket s, fd_set *set) {
|
||||
if(s->fd_in == SSH_INVALID_SOCKET) {
|
||||
if(s->fd == SSH_INVALID_SOCKET) {
|
||||
return 0;
|
||||
}
|
||||
return FD_ISSET(s->fd_in,set) || FD_ISSET(s->fd_out,set);
|
||||
return FD_ISSET(s->fd,set);
|
||||
}
|
||||
|
||||
/** \internal
|
||||
@@ -637,22 +573,16 @@ int ssh_socket_fd_isset(ssh_socket s, fd_set *set) {
|
||||
*/
|
||||
|
||||
void ssh_socket_fd_set(ssh_socket s, fd_set *set, socket_t *max_fd) {
|
||||
if (s->fd_in == SSH_INVALID_SOCKET) {
|
||||
if (s->fd == SSH_INVALID_SOCKET) {
|
||||
return;
|
||||
}
|
||||
|
||||
FD_SET(s->fd_in,set);
|
||||
FD_SET(s->fd_out,set);
|
||||
FD_SET(s->fd,set);
|
||||
|
||||
if (s->fd_in >= 0 &&
|
||||
s->fd_in >= *max_fd &&
|
||||
s->fd_in != SSH_INVALID_SOCKET) {
|
||||
*max_fd = s->fd_in + 1;
|
||||
}
|
||||
if (s->fd_out >= 0 &&
|
||||
s->fd_out >= *max_fd &&
|
||||
s->fd_out != SSH_INVALID_SOCKET) {
|
||||
*max_fd = s->fd_out + 1;
|
||||
if (s->fd >= 0 &&
|
||||
s->fd >= *max_fd &&
|
||||
s->fd != SSH_INVALID_SOCKET) {
|
||||
*max_fd = s->fd + 1;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -701,9 +631,9 @@ int ssh_socket_nonblocking_flush(ssh_socket s)
|
||||
}
|
||||
|
||||
len = ssh_buffer_get_len(s->out_buffer);
|
||||
if (!s->write_wontblock && s->poll_out && len > 0) {
|
||||
if (!s->write_wontblock && s->poll_handle && len > 0) {
|
||||
/* force the poll system to catch pollout events */
|
||||
ssh_poll_add_events(s->poll_out, POLLOUT);
|
||||
ssh_poll_add_events(s->poll_handle, POLLOUT);
|
||||
|
||||
return SSH_AGAIN;
|
||||
}
|
||||
@@ -741,9 +671,9 @@ int ssh_socket_nonblocking_flush(ssh_socket s)
|
||||
|
||||
/* Is there some data pending? */
|
||||
len = ssh_buffer_get_len(s->out_buffer);
|
||||
if (s->poll_out && len > 0) {
|
||||
if (s->poll_handle && len > 0) {
|
||||
/* force the poll system to catch pollout events */
|
||||
ssh_poll_add_events(s->poll_out, POLLOUT);
|
||||
ssh_poll_add_events(s->poll_handle, POLLOUT);
|
||||
|
||||
return SSH_AGAIN;
|
||||
}
|
||||
@@ -804,10 +734,10 @@ int ssh_socket_get_status(ssh_socket s) {
|
||||
|
||||
int ssh_socket_get_poll_flags(ssh_socket s) {
|
||||
int r = 0;
|
||||
if (s->poll_in != NULL && (ssh_poll_get_events (s->poll_in) & POLLIN) > 0) {
|
||||
if (s->poll_handle != NULL && (ssh_poll_get_events (s->poll_handle) & POLLIN) > 0) {
|
||||
r |= SSH_READ_PENDING;
|
||||
}
|
||||
if (s->poll_out != NULL && (ssh_poll_get_events (s->poll_out) & POLLOUT) > 0) {
|
||||
if (s->poll_handle != NULL && (ssh_poll_get_events (s->poll_handle) & POLLOUT) > 0) {
|
||||
r |= SSH_WRITE_PENDING;
|
||||
}
|
||||
return r;
|
||||
@@ -897,19 +827,15 @@ void ssh_execute_command(const char *command, socket_t in, socket_t out){
|
||||
*/
|
||||
|
||||
int ssh_socket_connect_proxycommand(ssh_socket s, const char *command){
|
||||
socket_t in_pipe[2];
|
||||
socket_t out_pipe[2];
|
||||
socket_t pair[2];
|
||||
int pid;
|
||||
int rc;
|
||||
|
||||
if(s->state != SSH_SOCKET_NONE)
|
||||
if (s->state != SSH_SOCKET_NONE) {
|
||||
return SSH_ERROR;
|
||||
|
||||
rc = pipe(in_pipe);
|
||||
if (rc < 0) {
|
||||
return SSH_ERROR;
|
||||
}
|
||||
rc = pipe(out_pipe);
|
||||
|
||||
rc = socketpair(PF_LOCAL, SOCK_STREAM, 0, pair);
|
||||
if (rc < 0) {
|
||||
return SSH_ERROR;
|
||||
}
|
||||
@@ -917,20 +843,18 @@ int ssh_socket_connect_proxycommand(ssh_socket s, const char *command){
|
||||
SSH_LOG(SSH_LOG_PROTOCOL,"Executing proxycommand '%s'",command);
|
||||
pid = fork();
|
||||
if(pid == 0){
|
||||
ssh_execute_command(command,out_pipe[0],in_pipe[1]);
|
||||
ssh_execute_command(command,pair[0],pair[0]);
|
||||
}
|
||||
close(in_pipe[1]);
|
||||
close(out_pipe[0]);
|
||||
SSH_LOG(SSH_LOG_PROTOCOL,"ProxyCommand connection pipe: [%d,%d]",in_pipe[0],out_pipe[1]);
|
||||
ssh_socket_set_fd_in(s,in_pipe[0]);
|
||||
ssh_socket_set_fd_out(s,out_pipe[1]);
|
||||
close(pair[0]);
|
||||
SSH_LOG(SSH_LOG_PROTOCOL,"ProxyCommand connection pipe: [%d,%d]",pair[0],pair[1]);
|
||||
ssh_socket_set_fd(s, pair[1]);
|
||||
s->state=SSH_SOCKET_CONNECTED;
|
||||
s->fd_is_socket=0;
|
||||
/* POLLOUT is the event to wait for in a nonblocking connect */
|
||||
ssh_poll_set_events(ssh_socket_get_poll_handle_in(s),POLLIN);
|
||||
ssh_poll_set_events(ssh_socket_get_poll_handle_out(s),POLLOUT);
|
||||
if(s->callbacks && s->callbacks->connected)
|
||||
ssh_poll_set_events(ssh_socket_get_poll_handle(s), POLLIN | POLLOUT);
|
||||
if(s->callbacks && s->callbacks->connected) {
|
||||
s->callbacks->connected(SSH_SOCKET_CONNECTED_OK,0,s->callbacks->userdata);
|
||||
}
|
||||
|
||||
return SSH_OK;
|
||||
}
|
||||
|
||||
@@ -116,6 +116,14 @@ void crypto_thread_finalize(void)
|
||||
return;
|
||||
}
|
||||
|
||||
#ifdef HAVE_OPENSSL_CRYPTO_THREADID_SET_CALLBACK
|
||||
CRYPTO_THREADID_set_callback(NULL);
|
||||
#else
|
||||
CRYPTO_set_id_callback(NULL);
|
||||
#endif
|
||||
|
||||
CRYPTO_set_locking_callback(NULL);
|
||||
|
||||
for (i = 0; i < n; ++i) {
|
||||
user_callbacks->mutex_destroy(&libcrypto_mutexes[i]);
|
||||
}
|
||||
|
||||
@@ -52,7 +52,6 @@
|
||||
static struct ssh_hmac_struct ssh_hmac_tab[] = {
|
||||
{ "hmac-sha1", SSH_HMAC_SHA1 },
|
||||
{ "hmac-sha2-256", SSH_HMAC_SHA256 },
|
||||
{ "hmac-sha2-384", SSH_HMAC_SHA384 },
|
||||
{ "hmac-sha2-512", SSH_HMAC_SHA512 },
|
||||
{ "hmac-md5", SSH_HMAC_MD5 },
|
||||
{ "aead-poly1305", SSH_HMAC_AEAD_POLY1305 },
|
||||
@@ -69,8 +68,6 @@ size_t hmac_digest_len(enum ssh_hmac_e type) {
|
||||
return SHA_DIGEST_LEN;
|
||||
case SSH_HMAC_SHA256:
|
||||
return SHA256_DIGEST_LEN;
|
||||
case SSH_HMAC_SHA384:
|
||||
return SHA384_DIGEST_LEN;
|
||||
case SSH_HMAC_SHA512:
|
||||
return SHA512_DIGEST_LEN;
|
||||
case SSH_HMAC_MD5:
|
||||
|
||||
@@ -84,7 +84,7 @@ if (CLIENT_TESTING)
|
||||
|
||||
# chroot_wrapper
|
||||
add_library(chroot_wrapper SHARED chroot_wrapper.c)
|
||||
set(CHROOT_WRAPPER_LIBRARY ${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_SHARED_LIBRARY_PREFIX}chroot_wrapper${CMAKE_SHARED_LIBRARY_SUFFIX})
|
||||
set(CHROOT_WRAPPER_LIBRARY ${libssh_BINARY_DIR}/lib/${CMAKE_SHARED_LIBRARY_PREFIX}chroot_wrapper${CMAKE_SHARED_LIBRARY_SUFFIX})
|
||||
set(TEST_TARGET_LIBRARIES
|
||||
${TEST_TARGET_LIBRARIES}
|
||||
chroot_wrapper
|
||||
@@ -121,6 +121,8 @@ if (CLIENT_TESTING)
|
||||
file(COPY keys/id_rsa.pub DESTINATION ${CMAKE_CURRENT_BINARY_DIR}/home/bob/.ssh/ FILE_PERMISSIONS OWNER_READ OWNER_WRITE)
|
||||
file(COPY keys/id_ecdsa DESTINATION ${CMAKE_CURRENT_BINARY_DIR}/home/bob/.ssh/ FILE_PERMISSIONS OWNER_READ OWNER_WRITE)
|
||||
file(COPY keys/id_ecdsa.pub DESTINATION ${CMAKE_CURRENT_BINARY_DIR}/home/bob/.ssh/ FILE_PERMISSIONS OWNER_READ OWNER_WRITE)
|
||||
file(COPY keys/id_ed25519 DESTINATION ${CMAKE_CURRENT_BINARY_DIR}/home/bob/.ssh/ FILE_PERMISSIONS OWNER_READ OWNER_WRITE)
|
||||
file(COPY keys/id_ed25519.pub DESTINATION ${CMAKE_CURRENT_BINARY_DIR}/home/bob/.ssh/ FILE_PERMISSIONS OWNER_READ OWNER_WRITE)
|
||||
|
||||
# Allow to auth with bob his public keys on alice account
|
||||
configure_file(keys/id_rsa.pub ${CMAKE_CURRENT_BINARY_DIR}/home/alice/.ssh/authorized_keys @ONLY)
|
||||
@@ -128,6 +130,10 @@ if (CLIENT_TESTING)
|
||||
file(READ keys/id_ecdsa.pub CONTENTS)
|
||||
file(APPEND ${CMAKE_CURRENT_BINARY_DIR}/home/alice/.ssh/authorized_keys "${CONTENTS}")
|
||||
|
||||
# append ed25519 public key
|
||||
file(READ keys/id_ed25519.pub CONTENTS)
|
||||
file(APPEND ${CMAKE_CURRENT_BINARY_DIR}/home/alice/.ssh/authorized_keys "${CONTENTS}")
|
||||
|
||||
# Copy the signed key to an alternative directory in bob's homedir.
|
||||
file(COPY keys/certauth/id_rsa DESTINATION ${CMAKE_CURRENT_BINARY_DIR}/home/bob/.ssh_cert/ FILE_PERMISSIONS OWNER_READ OWNER_WRITE)
|
||||
file(COPY keys/certauth/id_rsa.pub DESTINATION ${CMAKE_CURRENT_BINARY_DIR}/home/bob/.ssh_cert/ FILE_PERMISSIONS OWNER_READ OWNER_WRITE)
|
||||
|
||||
@@ -232,7 +232,7 @@ static void torture_auth_none_nonblocking(void **state) {
|
||||
|
||||
/* This request should return a SSH_REQUEST_DENIED error */
|
||||
if (rc == SSH_ERROR) {
|
||||
assert_true(ssh_get_error_code(session) == SSH_REQUEST_DENIED);
|
||||
assert_int_equal(ssh_get_error_code(session), SSH_REQUEST_DENIED);
|
||||
}
|
||||
|
||||
ssh_set_blocking(session,0);
|
||||
@@ -241,7 +241,7 @@ static void torture_auth_none_nonblocking(void **state) {
|
||||
rc = ssh_userauth_none(session,NULL);
|
||||
} while (rc == SSH_AUTH_AGAIN);
|
||||
assert_int_equal(rc, SSH_AUTH_DENIED);
|
||||
assert_true(ssh_get_error_code(session) == SSH_REQUEST_DENIED);
|
||||
assert_int_equal(ssh_get_error_code(session), SSH_REQUEST_DENIED);
|
||||
|
||||
}
|
||||
|
||||
@@ -260,7 +260,7 @@ static void torture_auth_autopubkey(void **state) {
|
||||
rc = ssh_userauth_none(session,NULL);
|
||||
/* This request should return a SSH_REQUEST_DENIED error */
|
||||
if (rc == SSH_ERROR) {
|
||||
assert_true(ssh_get_error_code(session) == SSH_REQUEST_DENIED);
|
||||
assert_int_equal(ssh_get_error_code(session), SSH_REQUEST_DENIED);
|
||||
}
|
||||
rc = ssh_userauth_list(session, NULL);
|
||||
assert_true(rc & SSH_AUTH_METHOD_PUBLICKEY);
|
||||
@@ -313,7 +313,7 @@ static void torture_auth_kbdint(void **state) {
|
||||
rc = ssh_userauth_none(session,NULL);
|
||||
/* This request should return a SSH_REQUEST_DENIED error */
|
||||
if (rc == SSH_ERROR) {
|
||||
assert_true(ssh_get_error_code(session) == SSH_REQUEST_DENIED);
|
||||
assert_int_equal(ssh_get_error_code(session), SSH_REQUEST_DENIED);
|
||||
}
|
||||
rc = ssh_userauth_list(session, NULL);
|
||||
assert_true(rc & SSH_AUTH_METHOD_INTERACTIVE);
|
||||
@@ -352,7 +352,7 @@ static void torture_auth_kbdint_nonblocking(void **state) {
|
||||
|
||||
/* This request should return a SSH_REQUEST_DENIED error */
|
||||
if (rc == SSH_ERROR) {
|
||||
assert_true(ssh_get_error_code(session) == SSH_REQUEST_DENIED);
|
||||
assert_int_equal(ssh_get_error_code(session), SSH_REQUEST_DENIED);
|
||||
}
|
||||
rc = ssh_userauth_list(session, NULL);
|
||||
assert_true(rc & SSH_AUTH_METHOD_INTERACTIVE);
|
||||
@@ -392,7 +392,7 @@ static void torture_auth_password(void **state) {
|
||||
rc = ssh_userauth_none(session, NULL);
|
||||
/* This request should return a SSH_REQUEST_DENIED error */
|
||||
if (rc == SSH_AUTH_ERROR) {
|
||||
assert_true(ssh_get_error_code(session) == SSH_REQUEST_DENIED);
|
||||
assert_int_equal(ssh_get_error_code(session), SSH_REQUEST_DENIED);
|
||||
}
|
||||
rc = ssh_userauth_list(session, NULL);
|
||||
assert_true(rc & SSH_AUTH_METHOD_PASSWORD);
|
||||
@@ -419,7 +419,7 @@ static void torture_auth_password_nonblocking(void **state) {
|
||||
|
||||
/* This request should return a SSH_REQUEST_DENIED error */
|
||||
if (rc == SSH_AUTH_ERROR) {
|
||||
assert_true(ssh_get_error_code(session) == SSH_REQUEST_DENIED);
|
||||
assert_int_equal(ssh_get_error_code(session), SSH_REQUEST_DENIED);
|
||||
}
|
||||
|
||||
rc = ssh_userauth_list(session, NULL);
|
||||
@@ -450,7 +450,7 @@ static void torture_auth_agent(void **state) {
|
||||
rc = ssh_userauth_none(session,NULL);
|
||||
/* This request should return a SSH_REQUEST_DENIED error */
|
||||
if (rc == SSH_ERROR) {
|
||||
assert_true(ssh_get_error_code(session) == SSH_REQUEST_DENIED);
|
||||
assert_int_equal(ssh_get_error_code(session), SSH_REQUEST_DENIED);
|
||||
}
|
||||
rc = ssh_userauth_list(session, NULL);
|
||||
assert_true(rc & SSH_AUTH_METHOD_PUBLICKEY);
|
||||
@@ -477,7 +477,7 @@ static void torture_auth_agent_nonblocking(void **state) {
|
||||
rc = ssh_userauth_none(session,NULL);
|
||||
/* This request should return a SSH_REQUEST_DENIED error */
|
||||
if (rc == SSH_ERROR) {
|
||||
assert_true(ssh_get_error_code(session) == SSH_REQUEST_DENIED);
|
||||
assert_int_equal(ssh_get_error_code(session), SSH_REQUEST_DENIED);
|
||||
}
|
||||
rc = ssh_userauth_list(session, NULL);
|
||||
assert_true(rc & SSH_AUTH_METHOD_PUBLICKEY);
|
||||
@@ -559,10 +559,10 @@ static void torture_auth_pubkey_types(void **state)
|
||||
rc = ssh_connect(session);
|
||||
assert_ssh_return_code(session, rc);
|
||||
|
||||
rc = ssh_userauth_none(session,NULL);
|
||||
rc = ssh_userauth_none(session, NULL);
|
||||
/* This request should return a SSH_REQUEST_DENIED error */
|
||||
if (rc == SSH_ERROR) {
|
||||
assert_true(ssh_get_error_code(session) == SSH_REQUEST_DENIED);
|
||||
assert_int_equal(ssh_get_error_code(session), SSH_REQUEST_DENIED);
|
||||
}
|
||||
rc = ssh_userauth_list(session, NULL);
|
||||
assert_true(rc & SSH_AUTH_METHOD_PUBLICKEY);
|
||||
@@ -596,10 +596,10 @@ static void torture_auth_pubkey_types_ecdsa(void **state)
|
||||
rc = ssh_connect(session);
|
||||
assert_ssh_return_code(session, rc);
|
||||
|
||||
rc = ssh_userauth_none(session,NULL);
|
||||
rc = ssh_userauth_none(session, NULL);
|
||||
/* This request should return a SSH_REQUEST_DENIED error */
|
||||
if (rc == SSH_ERROR) {
|
||||
assert_true(ssh_get_error_code(session) == SSH_REQUEST_DENIED);
|
||||
assert_int_equal(ssh_get_error_code(session), SSH_REQUEST_DENIED);
|
||||
}
|
||||
rc = ssh_userauth_list(session, NULL);
|
||||
assert_true(rc & SSH_AUTH_METHOD_PUBLICKEY);
|
||||
@@ -622,6 +622,44 @@ static void torture_auth_pubkey_types_ecdsa(void **state)
|
||||
|
||||
}
|
||||
|
||||
static void torture_auth_pubkey_types_ed25519(void **state)
|
||||
{
|
||||
struct torture_state *s = *state;
|
||||
ssh_session session = s->ssh.session;
|
||||
int rc;
|
||||
|
||||
rc = ssh_options_set(session, SSH_OPTIONS_USER, TORTURE_SSH_USER_ALICE);
|
||||
assert_ssh_return_code(session, rc);
|
||||
|
||||
rc = ssh_connect(session);
|
||||
assert_ssh_return_code(session, rc);
|
||||
|
||||
rc = ssh_userauth_none(session, NULL);
|
||||
/* This request should return a SSH_REQUEST_DENIED error */
|
||||
if (rc == SSH_ERROR) {
|
||||
assert_int_equal(ssh_get_error_code(session), SSH_REQUEST_DENIED);
|
||||
}
|
||||
rc = ssh_userauth_list(session, NULL);
|
||||
assert_true(rc & SSH_AUTH_METHOD_PUBLICKEY);
|
||||
|
||||
/* Enable only DSA keys -- authentication should fail */
|
||||
rc = ssh_options_set(session, SSH_OPTIONS_PUBLICKEY_ACCEPTED_TYPES,
|
||||
"ssh-dss");
|
||||
assert_ssh_return_code(session, rc);
|
||||
|
||||
rc = ssh_userauth_publickey_auto(session, NULL, NULL);
|
||||
assert_int_equal(rc, SSH_AUTH_DENIED);
|
||||
|
||||
/* Verify we can use also ed25519 keys */
|
||||
rc = ssh_options_set(session, SSH_OPTIONS_PUBLICKEY_ACCEPTED_TYPES,
|
||||
"ssh-ed25519");
|
||||
assert_ssh_return_code(session, rc);
|
||||
|
||||
rc = ssh_userauth_publickey_auto(session, NULL, NULL);
|
||||
assert_int_equal(rc, SSH_AUTH_SUCCESS);
|
||||
|
||||
}
|
||||
|
||||
static void torture_auth_pubkey_types_nonblocking(void **state)
|
||||
{
|
||||
struct torture_state *s = *state;
|
||||
@@ -634,7 +672,7 @@ static void torture_auth_pubkey_types_nonblocking(void **state)
|
||||
rc = ssh_connect(session);
|
||||
assert_ssh_return_code(session, rc);
|
||||
|
||||
ssh_set_blocking(session,0);
|
||||
ssh_set_blocking(session, 0);
|
||||
do {
|
||||
rc = ssh_userauth_none(session, NULL);
|
||||
} while (rc == SSH_AUTH_AGAIN);
|
||||
@@ -681,7 +719,7 @@ static void torture_auth_pubkey_types_ecdsa_nonblocking(void **state)
|
||||
rc = ssh_connect(session);
|
||||
assert_ssh_return_code(session, rc);
|
||||
|
||||
ssh_set_blocking(session,0);
|
||||
ssh_set_blocking(session, 0);
|
||||
do {
|
||||
rc = ssh_userauth_none(session, NULL);
|
||||
} while (rc == SSH_AUTH_AGAIN);
|
||||
@@ -704,7 +742,7 @@ static void torture_auth_pubkey_types_ecdsa_nonblocking(void **state)
|
||||
} while (rc == SSH_AUTH_AGAIN);
|
||||
assert_int_equal(rc, SSH_AUTH_DENIED);
|
||||
|
||||
/* Verify we can use also ECDSA keys with their various names */
|
||||
/* Verify we can use also ECDSA key to authenticate */
|
||||
rc = ssh_options_set(session, SSH_OPTIONS_PUBLICKEY_ACCEPTED_TYPES,
|
||||
"ecdsa-sha2-nistp256");
|
||||
assert_ssh_return_code(session, rc);
|
||||
@@ -716,6 +754,52 @@ static void torture_auth_pubkey_types_ecdsa_nonblocking(void **state)
|
||||
|
||||
}
|
||||
|
||||
static void torture_auth_pubkey_types_ed25519_nonblocking(void **state)
|
||||
{
|
||||
struct torture_state *s = *state;
|
||||
ssh_session session = s->ssh.session;
|
||||
int rc;
|
||||
|
||||
rc = ssh_options_set(session, SSH_OPTIONS_USER, TORTURE_SSH_USER_ALICE);
|
||||
assert_ssh_return_code(session, rc);
|
||||
|
||||
rc = ssh_connect(session);
|
||||
assert_ssh_return_code(session, rc);
|
||||
|
||||
ssh_set_blocking(session, 0);
|
||||
do {
|
||||
rc = ssh_userauth_none(session, NULL);
|
||||
} while (rc == SSH_AUTH_AGAIN);
|
||||
|
||||
/* This request should return a SSH_REQUEST_DENIED error */
|
||||
if (rc == SSH_ERROR) {
|
||||
assert_int_equal(ssh_get_error_code(session), SSH_REQUEST_DENIED);
|
||||
}
|
||||
|
||||
rc = ssh_userauth_list(session, NULL);
|
||||
assert_true(rc & SSH_AUTH_METHOD_PUBLICKEY);
|
||||
|
||||
/* Enable only DSA keys -- authentication should fail */
|
||||
rc = ssh_options_set(session, SSH_OPTIONS_PUBLICKEY_ACCEPTED_TYPES,
|
||||
"ssh-dss");
|
||||
assert_ssh_return_code(session, rc);
|
||||
|
||||
do {
|
||||
rc = ssh_userauth_publickey_auto(session, NULL, NULL);
|
||||
} while (rc == SSH_AUTH_AGAIN);
|
||||
assert_int_equal(rc, SSH_AUTH_DENIED);
|
||||
|
||||
/* Verify we can use also ED25519 key to authenticate */
|
||||
rc = ssh_options_set(session, SSH_OPTIONS_PUBLICKEY_ACCEPTED_TYPES,
|
||||
"ssh-ed25519");
|
||||
assert_ssh_return_code(session, rc);
|
||||
|
||||
do {
|
||||
rc = ssh_userauth_publickey_auto(session, NULL, NULL);
|
||||
} while (rc == SSH_AUTH_AGAIN);
|
||||
assert_int_equal(rc, SSH_AUTH_SUCCESS);
|
||||
|
||||
}
|
||||
|
||||
int torture_run_tests(void) {
|
||||
int rc;
|
||||
@@ -771,6 +855,12 @@ int torture_run_tests(void) {
|
||||
cmocka_unit_test_setup_teardown(torture_auth_pubkey_types_ecdsa_nonblocking,
|
||||
pubkey_setup,
|
||||
session_teardown),
|
||||
cmocka_unit_test_setup_teardown(torture_auth_pubkey_types_ed25519,
|
||||
pubkey_setup,
|
||||
session_teardown),
|
||||
cmocka_unit_test_setup_teardown(torture_auth_pubkey_types_ed25519_nonblocking,
|
||||
pubkey_setup,
|
||||
session_teardown),
|
||||
};
|
||||
|
||||
ssh_init();
|
||||
|
||||
@@ -163,7 +163,7 @@ static void torture_hostkey_ecdsa(void **state) {
|
||||
static void torture_hostkey_rsa_sha256(void **state) {
|
||||
struct torture_state *s = *state;
|
||||
ssh_session session = s->ssh.session;
|
||||
char rsa[] = "rsa-sha2-256,ssh-rsa";
|
||||
char rsa[] = "rsa-sha2-256";
|
||||
|
||||
int rc;
|
||||
|
||||
@@ -182,7 +182,7 @@ static void torture_hostkey_rsa_sha256(void **state) {
|
||||
static void torture_hostkey_rsa_sha512(void **state) {
|
||||
struct torture_state *s = *state;
|
||||
ssh_session session = s->ssh.session;
|
||||
char rsa[] = "rsa-sha2-512,ssh-rsa";
|
||||
char rsa[] = "rsa-sha2-512";
|
||||
|
||||
int rc;
|
||||
|
||||
|
||||
@@ -328,6 +328,41 @@ static void torture_knownhosts_conflict(void **state) {
|
||||
/* session will be freed by session_teardown() */
|
||||
}
|
||||
|
||||
static void torture_knownhosts_no_hostkeychecking(void **state)
|
||||
{
|
||||
|
||||
struct torture_state *s = *state;
|
||||
ssh_session session = s->ssh.session;
|
||||
char known_hosts_file[1024] = {0};
|
||||
enum ssh_known_hosts_e found;
|
||||
int strict_host_key_checking = 0;
|
||||
int rc;
|
||||
|
||||
snprintf(known_hosts_file,
|
||||
sizeof(known_hosts_file),
|
||||
"%s/%s",
|
||||
s->socket_dir,
|
||||
TORTURE_KNOWN_HOSTS_FILE);
|
||||
|
||||
rc = ssh_options_set(session, SSH_OPTIONS_KNOWNHOSTS, known_hosts_file);
|
||||
assert_ssh_return_code(session, rc);
|
||||
|
||||
rc = ssh_options_set(session, SSH_OPTIONS_HOSTKEYS, "ssh-ed25519");
|
||||
assert_ssh_return_code(session, rc);
|
||||
|
||||
rc = ssh_connect(session);
|
||||
assert_ssh_return_code(session, rc);
|
||||
|
||||
found = ssh_session_is_known_server(session);
|
||||
assert_int_equal(found, SSH_KNOWN_HOSTS_UNKNOWN);
|
||||
|
||||
rc = ssh_options_set(session, SSH_OPTIONS_STRICTHOSTKEYCHECK, &strict_host_key_checking);
|
||||
assert_ssh_return_code(session, rc);
|
||||
|
||||
found = ssh_session_is_known_server(session);
|
||||
assert_int_equal(found, SSH_KNOWN_HOSTS_OK);
|
||||
}
|
||||
|
||||
int torture_run_tests(void) {
|
||||
int rc;
|
||||
struct CMUnitTest tests[] = {
|
||||
@@ -346,6 +381,9 @@ int torture_run_tests(void) {
|
||||
cmocka_unit_test_setup_teardown(torture_knownhosts_conflict,
|
||||
session_setup,
|
||||
session_teardown),
|
||||
cmocka_unit_test_setup_teardown(torture_knownhosts_no_hostkeychecking,
|
||||
session_setup,
|
||||
session_teardown),
|
||||
};
|
||||
|
||||
ssh_init();
|
||||
|
||||
@@ -167,6 +167,10 @@ static void torture_knownhosts_precheck(void **state)
|
||||
"127.0.0.10 %s\n",
|
||||
torture_get_testkey_pub(SSH_KEYTYPE_ED25519, 0));
|
||||
|
||||
fprintf(file,
|
||||
"127.0.0.10 %s\n",
|
||||
torture_get_testkey_pub(SSH_KEYTYPE_ECDSA, 521));
|
||||
|
||||
fclose(file);
|
||||
|
||||
rc = ssh_options_set(session, SSH_OPTIONS_KNOWNHOSTS, known_hosts_file);
|
||||
@@ -176,7 +180,7 @@ static void torture_knownhosts_precheck(void **state)
|
||||
assert_non_null(algo_list);
|
||||
|
||||
algo_count = ssh_list_count(algo_list);
|
||||
assert_int_equal(algo_count, 2);
|
||||
assert_int_equal(algo_count, 3);
|
||||
|
||||
it = ssh_list_get_iterator(algo_list);
|
||||
assert_non_null(it);
|
||||
@@ -190,6 +194,13 @@ static void torture_knownhosts_precheck(void **state)
|
||||
algo = ssh_iterator_value(const char *, it);
|
||||
assert_string_equal(algo, "ssh-ed25519");
|
||||
|
||||
ssh_list_remove(algo_list, it);
|
||||
|
||||
it = ssh_list_get_iterator(algo_list);
|
||||
assert_non_null(it);
|
||||
algo = ssh_iterator_value(const char *, it);
|
||||
assert_string_equal(algo, "ecdsa-sha2-nistp521");
|
||||
|
||||
ssh_list_free(algo_list);
|
||||
}
|
||||
|
||||
|
||||
@@ -9,6 +9,7 @@
|
||||
#include <sys/types.h>
|
||||
#include <pwd.h>
|
||||
#include <errno.h>
|
||||
#include <fcntl.h>
|
||||
|
||||
static int sshd_setup(void **state)
|
||||
{
|
||||
@@ -61,11 +62,16 @@ static void torture_options_set_proxycommand(void **state) {
|
||||
struct torture_state *s = *state;
|
||||
ssh_session session = s->ssh.session;
|
||||
int rc;
|
||||
socket_t fd;
|
||||
|
||||
rc = ssh_options_set(session, SSH_OPTIONS_PROXYCOMMAND, "nc 127.0.0.10 22");
|
||||
assert_int_equal(rc, 0);
|
||||
rc = ssh_connect(session);
|
||||
assert_ssh_return_code(session, rc);
|
||||
fd = ssh_get_fd(session);
|
||||
assert_true(fd != SSH_INVALID_SOCKET);
|
||||
rc = fcntl(fd, F_GETFL);
|
||||
assert_int_equal(rc & O_RDWR, O_RDWR);
|
||||
}
|
||||
|
||||
static void torture_options_set_proxycommand_notexist(void **state) {
|
||||
|
||||
@@ -39,7 +39,7 @@ set(CTEST_SOURCE_DIRECTORY "${CTEST_DIRECTORY}/${CTEST_BUILD_NAME}/source")
|
||||
set(CTEST_BINARY_DIRECTORY "${CTEST_DIRECTORY}/${CTEST_BUILD_NAME}/build")
|
||||
|
||||
set(CTEST_MEMORYCHECK_SUPPRESSIONS_FILE ${CMAKE_SOURCE_DIR}/tests/valgrind.supp)
|
||||
set(CTEST_MEMORYCHECK_COMMAND_OPTIONS " --trace-children-skip=sshd")
|
||||
set(CTEST_MEMORYCHECK_COMMAND_OPTIONS " --trace-children-skip=${SSHD_EXECUTABLE}")
|
||||
|
||||
find_program(CTEST_GIT_COMMAND NAMES git)
|
||||
find_program(CTEST_COVERAGE_COMMAND NAMES gcov)
|
||||
|
||||
8
tests/keys/id_ed25519
Normal file
8
tests/keys/id_ed25519
Normal file
@@ -0,0 +1,8 @@
|
||||
-----BEGIN OPENSSH PRIVATE KEY-----
|
||||
b3BlbnNzaC1rZXktdjEAAAAABG5vbmUAAAAEbm9uZQAAAAAAAAABAAAAMwAAAAtzc2gtZW
|
||||
QyNTUxOQAAACCLo6vx1lX6ZZoe05lWTkuwrJUZN0T8hEer5UF9KPhOVgAAAKg+IRNSPiET
|
||||
UgAAAAtzc2gtZWQyNTUxOQAAACCLo6vx1lX6ZZoe05lWTkuwrJUZN0T8hEer5UF9KPhOVg
|
||||
AAAED2zFg52qYItoZaSUnir4VKubTxJveL9D2oWK7Prg/O24ujq/HWVfplmh7TmVZOS7Cs
|
||||
lRk3RPyER6vlQX0o+E5WAAAAHmpqZWxlbkB0NDcwcy5qamVsZW4ucmVkaGF0LmNvbQECAw
|
||||
QFBgc=
|
||||
-----END OPENSSH PRIVATE KEY-----
|
||||
1
tests/keys/id_ed25519.pub
Normal file
1
tests/keys/id_ed25519.pub
Normal file
@@ -0,0 +1 @@
|
||||
ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIIujq/HWVfplmh7TmVZOS7CslRk3RPyER6vlQX0o+E5W jjelen@t470s.jjelen.redhat.com
|
||||
@@ -46,12 +46,12 @@
|
||||
OPENSSH_PKACCEPTED_ECDSA \
|
||||
OPENSSH_PKACCEPTED_DSA
|
||||
|
||||
#define OPENSSH_CMD_START \
|
||||
#define OPENSSH_CMD_START(hostkey_algos) \
|
||||
OPENSSH_BINARY " " \
|
||||
"-o UserKnownHostsFile=/dev/null " \
|
||||
"-o StrictHostKeyChecking=no " \
|
||||
"-F /dev/null " \
|
||||
OPENSSH_HOSTKEY_ALGOS " " \
|
||||
hostkey_algos " " \
|
||||
OPENSSH_PKACCEPTED_TYPES " " \
|
||||
"-i " CLIENT_ID_FILE " " \
|
||||
"1> %s.out " \
|
||||
@@ -61,16 +61,19 @@
|
||||
#define OPENSSH_CMD_END "-p 1234 localhost ls"
|
||||
|
||||
#define OPENSSH_CMD \
|
||||
OPENSSH_CMD_START OPENSSH_CMD_END
|
||||
OPENSSH_CMD_START(OPENSSH_HOSTKEY_ALGOS) OPENSSH_CMD_END
|
||||
|
||||
#define OPENSSH_KEX_CMD(kexalgo) \
|
||||
OPENSSH_CMD_START "-o KexAlgorithms=" kexalgo " " OPENSSH_CMD_END
|
||||
OPENSSH_CMD_START(OPENSSH_HOSTKEY_ALGOS) "-o KexAlgorithms=" kexalgo " " OPENSSH_CMD_END
|
||||
|
||||
#define OPENSSH_CIPHER_CMD(ciphers) \
|
||||
OPENSSH_CMD_START "-c " ciphers " " OPENSSH_CMD_END
|
||||
OPENSSH_CMD_START(OPENSSH_HOSTKEY_ALGOS) "-c " ciphers " " OPENSSH_CMD_END
|
||||
|
||||
#define OPENSSH_MAC_CMD(macs) \
|
||||
OPENSSH_CMD_START "-o MACs=" macs " " OPENSSH_CMD_END
|
||||
OPENSSH_CMD_START(OPENSSH_HOSTKEY_ALGOS) "-o MACs=" macs " " OPENSSH_CMD_END
|
||||
|
||||
#define OPENSSH_HOSTKEY_CMD(hostkeyalgo) \
|
||||
OPENSSH_CMD_START("-o HostKeyAlgorithms=" hostkeyalgo " ") OPENSSH_CMD_END
|
||||
|
||||
|
||||
/* Dropbear */
|
||||
|
||||
@@ -35,7 +35,7 @@ struct pkd_daemon_args {
|
||||
unsigned int iterations;
|
||||
|
||||
struct {
|
||||
const char *mkdtemp_str;
|
||||
char *mkdtemp_str;
|
||||
} socket_wrapper;
|
||||
} opts;
|
||||
};
|
||||
|
||||
@@ -478,6 +478,12 @@ static int torture_pkd_setup_ecdsa_521(void **state) {
|
||||
f(client, ecdsa_521_hmac_sha2_512, maccmd("hmac-sha2-512"), setup_ecdsa_521, teardown)
|
||||
#endif
|
||||
|
||||
#define PKDTESTS_HOSTKEY_OPENSSHONLY(f, client, hkcmd) \
|
||||
f(client, rsa_sha2_256, hkcmd("rsa-sha2-256"), setup_rsa, teardown) \
|
||||
f(client, rsa_sha2_512, hkcmd("rsa-sha2-512"), setup_rsa, teardown) \
|
||||
f(client, rsa_sha2_256_512, hkcmd("rsa-sha2-256,rsa-sha2-512"), setup_rsa, teardown) \
|
||||
f(client, rsa_sha2_512_256, hkcmd("rsa-sha2-512,rsa-sha2-256"), setup_rsa, teardown)
|
||||
|
||||
static void torture_pkd_client_noop(void **state) {
|
||||
struct pkd_state *pstate = (struct pkd_state *) (*state);
|
||||
(void) pstate;
|
||||
@@ -545,6 +551,7 @@ PKDTESTS_CIPHER(emit_keytest, openssh_rsa, OPENSSH_CIPHER_CMD)
|
||||
PKDTESTS_CIPHER_OPENSSHONLY(emit_keytest, openssh_rsa, OPENSSH_CIPHER_CMD)
|
||||
PKDTESTS_MAC(emit_keytest, openssh_rsa, OPENSSH_MAC_CMD)
|
||||
PKDTESTS_MAC_OPENSSHONLY(emit_keytest, openssh_rsa, OPENSSH_MAC_CMD)
|
||||
PKDTESTS_HOSTKEY_OPENSSHONLY(emit_keytest, openssh_rsa, OPENSSH_HOSTKEY_CMD)
|
||||
#undef CLIENT_ID_FILE
|
||||
|
||||
#define CLIENT_ID_FILE OPENSSH_ECDSA256_TESTKEY
|
||||
@@ -621,6 +628,7 @@ struct {
|
||||
PKDTESTS_CIPHER_OPENSSHONLY(emit_testmap, openssh_rsa, OPENSSH_CIPHER_CMD)
|
||||
PKDTESTS_MAC(emit_testmap, openssh_rsa, OPENSSH_MAC_CMD)
|
||||
PKDTESTS_MAC_OPENSSHONLY(emit_testmap, openssh_rsa, OPENSSH_MAC_CMD)
|
||||
PKDTESTS_HOSTKEY_OPENSSHONLY(emit_testmap, openssh_rsa, OPENSSH_HOSTKEY_CMD)
|
||||
|
||||
PKDTESTS_DEFAULT(emit_testmap, openssh_e256, OPENSSH_CMD)
|
||||
PKDTESTS_DEFAULT_OPENSSHONLY(emit_testmap, openssh_e256, OPENSSH_CMD)
|
||||
@@ -849,6 +857,8 @@ static int pkd_cleanup_socket_wrapper(void) {
|
||||
goto errrmdir;
|
||||
}
|
||||
|
||||
free(pkd_dargs.opts.socket_wrapper.mkdtemp_str);
|
||||
|
||||
goto out;
|
||||
errrmdir:
|
||||
errrmfiles:
|
||||
|
||||
@@ -284,7 +284,7 @@ static void torture_config_auth_methods(void **state) {
|
||||
assert_false(session->opts.flags & SSH_OPT_FLAG_PUBKEY_AUTH);
|
||||
|
||||
/* no method should be left enabled */
|
||||
assert_int_equal(session->opts.port, 0);
|
||||
assert_int_equal(session->opts.flags, 0);
|
||||
|
||||
/* gradually enable them again */
|
||||
ssh_options_set(session, SSH_OPTIONS_HOST, "gss");
|
||||
|
||||
@@ -16,10 +16,27 @@ static void torture_ssh_init(void **state) {
|
||||
assert_int_equal(rc, SSH_OK);
|
||||
}
|
||||
|
||||
static void torture_ssh_init_after_finalize(void **state) {
|
||||
|
||||
int rc;
|
||||
|
||||
(void) state;
|
||||
|
||||
rc = ssh_init();
|
||||
assert_int_equal(rc, SSH_OK);
|
||||
rc = ssh_finalize();
|
||||
assert_int_equal(rc, SSH_OK);
|
||||
rc = ssh_init();
|
||||
assert_int_equal(rc, SSH_OK);
|
||||
rc = ssh_finalize();
|
||||
assert_int_equal(rc, SSH_OK);
|
||||
}
|
||||
|
||||
int torture_run_tests(void) {
|
||||
int rc;
|
||||
struct CMUnitTest tests[] = {
|
||||
cmocka_unit_test(torture_ssh_init),
|
||||
cmocka_unit_test(torture_ssh_init_after_finalize),
|
||||
};
|
||||
|
||||
torture_filter_tests(tests);
|
||||
|
||||
@@ -42,18 +42,24 @@ static int setup_knownhosts_file(void **state)
|
||||
|
||||
nwritten = fwrite(LOCALHOST_PATTERN_ED25519,
|
||||
sizeof(char),
|
||||
sizeof(LOCALHOST_PATTERN_ED25519),
|
||||
strlen(LOCALHOST_PATTERN_ED25519),
|
||||
fp);
|
||||
if (nwritten != sizeof(LOCALHOST_PATTERN_ED25519)) {
|
||||
if (nwritten != strlen(LOCALHOST_PATTERN_ED25519)) {
|
||||
fclose(fp);
|
||||
return -1;
|
||||
}
|
||||
|
||||
nwritten = fwrite("\n", sizeof(char), 1, fp);
|
||||
if (nwritten != 1) {
|
||||
fclose(fp);
|
||||
return -1;
|
||||
}
|
||||
|
||||
nwritten = fwrite(LOCALHOST_RSA_LINE,
|
||||
sizeof(char),
|
||||
sizeof(LOCALHOST_RSA_LINE),
|
||||
strlen(LOCALHOST_RSA_LINE),
|
||||
fp);
|
||||
if (nwritten != sizeof(LOCALHOST_RSA_LINE)) {
|
||||
if (nwritten != strlen(LOCALHOST_RSA_LINE)) {
|
||||
fclose(fp);
|
||||
return -1;
|
||||
}
|
||||
@@ -210,6 +216,8 @@ static void torture_knownhosts_read_file(void **state)
|
||||
const char *knownhosts_file = *state;
|
||||
struct ssh_list *entry_list = NULL;
|
||||
struct ssh_iterator *it = NULL;
|
||||
struct ssh_knownhosts_entry *entry = NULL;
|
||||
enum ssh_keytypes_e type;
|
||||
int rc;
|
||||
|
||||
rc = ssh_known_hosts_read_entries("localhost",
|
||||
@@ -219,22 +227,27 @@ static void torture_knownhosts_read_file(void **state)
|
||||
assert_non_null(entry_list);
|
||||
it = ssh_list_get_iterator(entry_list);
|
||||
assert_non_null(it);
|
||||
for (;it != NULL; it = it->next) {
|
||||
struct ssh_knownhosts_entry *entry = NULL;
|
||||
enum ssh_keytypes_e type;
|
||||
|
||||
entry = ssh_iterator_value(struct ssh_knownhosts_entry *, it);
|
||||
assert_non_null(entry);
|
||||
/* First key in known hosts file is ED25519 */
|
||||
entry = ssh_iterator_value(struct ssh_knownhosts_entry *, it);
|
||||
assert_non_null(entry);
|
||||
|
||||
assert_string_equal(entry->hostname, "localhost");
|
||||
type = ssh_key_type(entry->publickey);
|
||||
assert_int_equal(type, SSH_KEYTYPE_ED25519);
|
||||
}
|
||||
assert_string_equal(entry->hostname, "localhost");
|
||||
type = ssh_key_type(entry->publickey);
|
||||
assert_int_equal(type, SSH_KEYTYPE_ED25519);
|
||||
|
||||
it = it->next;
|
||||
|
||||
/* Second key in known hosts file is RSA */
|
||||
entry = ssh_iterator_value(struct ssh_knownhosts_entry *, it);
|
||||
assert_non_null(entry);
|
||||
|
||||
assert_string_equal(entry->hostname, "localhost");
|
||||
type = ssh_key_type(entry->publickey);
|
||||
assert_int_equal(type, SSH_KEYTYPE_RSA);
|
||||
|
||||
it = ssh_list_get_iterator(entry_list);
|
||||
for (;it != NULL; it = it->next) {
|
||||
struct ssh_knownhosts_entry *entry = NULL;
|
||||
|
||||
entry = ssh_iterator_value(struct ssh_knownhosts_entry *, it);
|
||||
SSH_KNOWNHOSTS_ENTRY_FREE(entry);
|
||||
}
|
||||
@@ -252,6 +265,8 @@ static void torture_knownhosts_host_exists(void **state)
|
||||
|
||||
ssh_options_set(session, SSH_OPTIONS_HOST, "localhost");
|
||||
ssh_options_set(session, SSH_OPTIONS_KNOWNHOSTS, knownhosts_file);
|
||||
/* This makes sure the system's known_hosts are not used */
|
||||
ssh_options_set(session, SSH_OPTIONS_GLOBAL_KNOWNHOSTS, "/dev/null");
|
||||
|
||||
found = ssh_session_has_known_hosts_entry(session);
|
||||
assert_int_equal(found, SSH_KNOWN_HOSTS_OK);
|
||||
@@ -264,6 +279,91 @@ static void torture_knownhosts_host_exists(void **state)
|
||||
ssh_free(session);
|
||||
}
|
||||
|
||||
static void torture_knownhosts_host_exists_global(void **state)
|
||||
{
|
||||
const char *knownhosts_file = *state;
|
||||
enum ssh_known_hosts_e found;
|
||||
ssh_session session;
|
||||
|
||||
session = ssh_new();
|
||||
assert_non_null(session);
|
||||
|
||||
ssh_options_set(session, SSH_OPTIONS_HOST, "localhost");
|
||||
/* This makes sure the user's known_hosts are not used */
|
||||
ssh_options_set(session, SSH_OPTIONS_KNOWNHOSTS, "/dev/null");
|
||||
ssh_options_set(session, SSH_OPTIONS_GLOBAL_KNOWNHOSTS, knownhosts_file);
|
||||
|
||||
found = ssh_session_has_known_hosts_entry(session);
|
||||
assert_int_equal(found, SSH_KNOWN_HOSTS_OK);
|
||||
assert_true(found == SSH_KNOWN_HOSTS_OK);
|
||||
|
||||
ssh_options_set(session, SSH_OPTIONS_HOST, "wurstbrot");
|
||||
found = ssh_session_has_known_hosts_entry(session);
|
||||
assert_true(found == SSH_KNOWN_HOSTS_UNKNOWN);
|
||||
|
||||
ssh_free(session);
|
||||
}
|
||||
|
||||
static void
|
||||
torture_knownhosts_algorithms(void **state)
|
||||
{
|
||||
const char *knownhosts_file = *state;
|
||||
char *algo_list = NULL;
|
||||
ssh_session session;
|
||||
const char *expect = "ssh-ed25519,rsa-sha2-512,rsa-sha2-256,ssh-rsa,"
|
||||
"ecdsa-sha2-nistp521,ecdsa-sha2-nistp384,"
|
||||
"ecdsa-sha2-nistp256"
|
||||
#ifdef HAVE_DSA
|
||||
",ssh-dss"
|
||||
#endif
|
||||
;
|
||||
|
||||
session = ssh_new();
|
||||
assert_non_null(session);
|
||||
|
||||
ssh_options_set(session, SSH_OPTIONS_HOST, "localhost");
|
||||
ssh_options_set(session, SSH_OPTIONS_KNOWNHOSTS, knownhosts_file);
|
||||
/* This makes sure the system's known_hosts are not used */
|
||||
ssh_options_set(session, SSH_OPTIONS_GLOBAL_KNOWNHOSTS, "/dev/null");
|
||||
|
||||
algo_list = ssh_client_select_hostkeys(session);
|
||||
assert_non_null(algo_list);
|
||||
assert_string_equal(algo_list, expect);
|
||||
free(algo_list);
|
||||
|
||||
ssh_free(session);
|
||||
}
|
||||
|
||||
static void
|
||||
torture_knownhosts_algorithms_global(void **state)
|
||||
{
|
||||
const char *knownhosts_file = *state;
|
||||
char *algo_list = NULL;
|
||||
ssh_session session;
|
||||
const char *expect = "ssh-ed25519,rsa-sha2-512,rsa-sha2-256,ssh-rsa,"
|
||||
"ecdsa-sha2-nistp521,ecdsa-sha2-nistp384,"
|
||||
"ecdsa-sha2-nistp256"
|
||||
#ifdef HAVE_DSA
|
||||
",ssh-dss"
|
||||
#endif
|
||||
;
|
||||
|
||||
session = ssh_new();
|
||||
assert_non_null(session);
|
||||
|
||||
ssh_options_set(session, SSH_OPTIONS_HOST, "localhost");
|
||||
/* This makes sure the current-user's known hosts are not used */
|
||||
ssh_options_set(session, SSH_OPTIONS_KNOWNHOSTS, "/dev/null");
|
||||
ssh_options_set(session, SSH_OPTIONS_GLOBAL_KNOWNHOSTS, knownhosts_file);
|
||||
|
||||
algo_list = ssh_client_select_hostkeys(session);
|
||||
assert_non_null(algo_list);
|
||||
assert_string_equal(algo_list, expect);
|
||||
free(algo_list);
|
||||
|
||||
ssh_free(session);
|
||||
}
|
||||
|
||||
int torture_run_tests(void) {
|
||||
int rc;
|
||||
struct CMUnitTest tests[] = {
|
||||
@@ -279,6 +379,15 @@ int torture_run_tests(void) {
|
||||
cmocka_unit_test_setup_teardown(torture_knownhosts_host_exists,
|
||||
setup_knownhosts_file,
|
||||
teardown_knownhosts_file),
|
||||
cmocka_unit_test_setup_teardown(torture_knownhosts_host_exists_global,
|
||||
setup_knownhosts_file,
|
||||
teardown_knownhosts_file),
|
||||
cmocka_unit_test_setup_teardown(torture_knownhosts_algorithms,
|
||||
setup_knownhosts_file,
|
||||
teardown_knownhosts_file),
|
||||
cmocka_unit_test_setup_teardown(torture_knownhosts_algorithms_global,
|
||||
setup_knownhosts_file,
|
||||
teardown_knownhosts_file),
|
||||
};
|
||||
|
||||
ssh_init();
|
||||
|
||||
@@ -12,6 +12,7 @@
|
||||
#include <libssh/session.h>
|
||||
#include <libssh/misc.h>
|
||||
#include <libssh/pki_priv.h>
|
||||
#include <libssh/options.h>
|
||||
|
||||
static int setup(void **state)
|
||||
{
|
||||
@@ -346,6 +347,86 @@ static void torture_options_get_identity(void **state) {
|
||||
free(identity);
|
||||
}
|
||||
|
||||
static void torture_options_set_global_knownhosts(void **state)
|
||||
{
|
||||
ssh_session session = *state;
|
||||
int rc;
|
||||
|
||||
rc = ssh_options_set(session,
|
||||
SSH_OPTIONS_GLOBAL_KNOWNHOSTS,
|
||||
"/etc/libssh/known_hosts");
|
||||
assert_ssh_return_code(session, rc);
|
||||
assert_string_equal(session->opts.global_knownhosts,
|
||||
"/etc/libssh/known_hosts");
|
||||
}
|
||||
|
||||
static void torture_options_get_global_knownhosts(void **state)
|
||||
{
|
||||
ssh_session session = *state;
|
||||
char *str = NULL;
|
||||
int rc;
|
||||
|
||||
rc = ssh_options_set(session,
|
||||
SSH_OPTIONS_GLOBAL_KNOWNHOSTS,
|
||||
"/etc/libssh/known_hosts");
|
||||
assert_ssh_return_code(session, rc);
|
||||
assert_string_equal(session->opts.global_knownhosts,
|
||||
"/etc/libssh/known_hosts");
|
||||
|
||||
|
||||
rc = ssh_options_get(session, SSH_OPTIONS_GLOBAL_KNOWNHOSTS, &str);
|
||||
assert_ssh_return_code(session, rc);
|
||||
assert_string_equal(session->opts.global_knownhosts,
|
||||
"/etc/libssh/known_hosts");
|
||||
|
||||
SSH_STRING_FREE_CHAR(str);
|
||||
}
|
||||
|
||||
static void torture_options_set_knownhosts(void **state)
|
||||
{
|
||||
ssh_session session = *state;
|
||||
int rc;
|
||||
|
||||
rc = ssh_options_set(session,
|
||||
SSH_OPTIONS_KNOWNHOSTS,
|
||||
"/home/libssh/.ssh/known_hosts");
|
||||
assert_ssh_return_code(session, rc);
|
||||
assert_string_equal(session->opts.knownhosts,
|
||||
"/home/libssh/.ssh/known_hosts");
|
||||
|
||||
/* The NULL value should not crash the libssh */
|
||||
rc = ssh_options_set(session, SSH_OPTIONS_KNOWNHOSTS, NULL);
|
||||
assert_ssh_return_code(session, rc);
|
||||
assert_null(session->opts.knownhosts);
|
||||
|
||||
/* ssh_options_apply() should set the path to correct value */
|
||||
rc = ssh_options_apply(session);
|
||||
assert_ssh_return_code(session, rc);
|
||||
assert_true(session->opts.knownhosts != NULL);
|
||||
}
|
||||
|
||||
static void torture_options_get_knownhosts(void **state)
|
||||
{
|
||||
ssh_session session = *state;
|
||||
char *str = NULL;
|
||||
int rc;
|
||||
|
||||
rc = ssh_options_set(session,
|
||||
SSH_OPTIONS_KNOWNHOSTS,
|
||||
"/home/libssh/.ssh/known_hosts");
|
||||
assert_ssh_return_code(session, rc);
|
||||
assert_string_equal(session->opts.knownhosts,
|
||||
"/home/libssh/.ssh/known_hosts");
|
||||
|
||||
|
||||
rc = ssh_options_get(session, SSH_OPTIONS_KNOWNHOSTS, &str);
|
||||
assert_ssh_return_code(session, rc);
|
||||
assert_string_equal(session->opts.knownhosts,
|
||||
"/home/libssh/.ssh/known_hosts");
|
||||
|
||||
SSH_STRING_FREE_CHAR(str);
|
||||
}
|
||||
|
||||
static void torture_options_proxycommand(void **state) {
|
||||
ssh_session session = *state;
|
||||
int rc;
|
||||
@@ -581,7 +662,7 @@ static void torture_bind_options_import_key(void **state)
|
||||
assert_int_equal(rc, 0);
|
||||
#endif
|
||||
/* set ecdsa key */
|
||||
base64_key = torture_get_testkey(SSH_KEYTYPE_ECDSA, 512, 0);
|
||||
base64_key = torture_get_testkey(SSH_KEYTYPE_ECDSA, 521, 0);
|
||||
rc = ssh_pki_import_privkey_base64(base64_key, NULL, NULL, NULL, &key);
|
||||
assert_int_equal(rc, SSH_OK);
|
||||
assert_non_null(key);
|
||||
@@ -604,6 +685,10 @@ int torture_run_tests(void) {
|
||||
cmocka_unit_test_setup_teardown(torture_options_get_user, setup, teardown),
|
||||
cmocka_unit_test_setup_teardown(torture_options_set_identity, setup, teardown),
|
||||
cmocka_unit_test_setup_teardown(torture_options_get_identity, setup, teardown),
|
||||
cmocka_unit_test_setup_teardown(torture_options_set_global_knownhosts, setup, teardown),
|
||||
cmocka_unit_test_setup_teardown(torture_options_get_global_knownhosts, setup, teardown),
|
||||
cmocka_unit_test_setup_teardown(torture_options_set_knownhosts, setup, teardown),
|
||||
cmocka_unit_test_setup_teardown(torture_options_get_knownhosts, setup, teardown),
|
||||
cmocka_unit_test_setup_teardown(torture_options_proxycommand, setup, teardown),
|
||||
cmocka_unit_test_setup_teardown(torture_options_set_ciphers, setup, teardown),
|
||||
cmocka_unit_test_setup_teardown(torture_options_set_key_exchange, setup, teardown),
|
||||
|
||||
@@ -104,8 +104,7 @@ static void torture_packet(const char *cipher,
|
||||
|
||||
assert_non_null(session->out_buffer);
|
||||
ssh_buffer_add_data(session->out_buffer, test_data, payload_len);
|
||||
session->socket->fd_out = sockets[0];
|
||||
session->socket->fd_in = -2;
|
||||
session->socket->fd = sockets[0];
|
||||
session->socket->write_wontblock = 1;
|
||||
rc = ssh_packet_send(session);
|
||||
assert_int_equal(rc, SSH_OK);
|
||||
@@ -126,8 +125,7 @@ static void torture_packet(const char *cipher,
|
||||
}
|
||||
close(sockets[0]);
|
||||
close(sockets[1]);
|
||||
session->socket->fd_in = SSH_INVALID_SOCKET;
|
||||
session->socket->fd_out = SSH_INVALID_SOCKET;
|
||||
session->socket->fd = SSH_INVALID_SOCKET;
|
||||
ssh_free(session);
|
||||
}
|
||||
|
||||
|
||||
@@ -462,6 +462,36 @@ static void torture_packet_filter_check_auth_success(void **state)
|
||||
assert_int_equal(rc, 0);
|
||||
}
|
||||
|
||||
static void torture_packet_filter_check_msg_ext_info(void **state)
|
||||
{
|
||||
int rc;
|
||||
|
||||
global_state accepted[] = {
|
||||
{
|
||||
.flags = (COMPARE_SESSION_STATE |
|
||||
COMPARE_DH_STATE),
|
||||
.session = SSH_SESSION_STATE_AUTHENTICATING,
|
||||
.dh = DH_STATE_FINISHED,
|
||||
},
|
||||
{
|
||||
.flags = (COMPARE_SESSION_STATE |
|
||||
COMPARE_DH_STATE),
|
||||
.session = SSH_SESSION_STATE_AUTHENTICATED,
|
||||
.dh = DH_STATE_FINISHED,
|
||||
},
|
||||
};
|
||||
|
||||
int accepted_count = 2;
|
||||
|
||||
/* Unused */
|
||||
(void) state;
|
||||
|
||||
rc = check_message_in_all_states(accepted, accepted_count,
|
||||
SSH2_MSG_EXT_INFO);
|
||||
|
||||
assert_int_equal(rc, 0);
|
||||
}
|
||||
|
||||
static void torture_packet_filter_check_channel_open(void **state)
|
||||
{
|
||||
int rc;
|
||||
@@ -492,6 +522,7 @@ int torture_run_tests(void)
|
||||
cmocka_unit_test(torture_packet_filter_check_auth_success),
|
||||
cmocka_unit_test(torture_packet_filter_check_channel_open),
|
||||
cmocka_unit_test(torture_packet_filter_check_unfiltered),
|
||||
cmocka_unit_test(torture_packet_filter_check_msg_ext_info)
|
||||
};
|
||||
|
||||
ssh_init();
|
||||
|
||||
@@ -9,6 +9,10 @@
|
||||
#include "torture_pki.h"
|
||||
#include "pki.c"
|
||||
|
||||
|
||||
const unsigned char HASH[] = "1234567890123456789012345678901234567890"
|
||||
"123456789012345678901234";
|
||||
|
||||
static void torture_pki_keytype(void **state) {
|
||||
enum ssh_keytypes_e type;
|
||||
const char *type_c;
|
||||
@@ -43,11 +47,227 @@ static void torture_pki_signature(void **state)
|
||||
ssh_signature_free(sig);
|
||||
}
|
||||
|
||||
/* Maps to enum ssh_keytypes_e */
|
||||
const char *key_types[] = {
|
||||
"", /* UNKNOWN */
|
||||
"ssh-dss",
|
||||
"ssh-rsa",
|
||||
"",/* RSA1 */
|
||||
"ecdsa-sha2-nistp521",
|
||||
"ssh-ed25519",
|
||||
};
|
||||
|
||||
/* Maps to enum ssh_keytypes_e */
|
||||
const int key_sizes[] = {
|
||||
0, /* UNKNOWN */
|
||||
1024,
|
||||
2048,
|
||||
0, /* RSA1 */
|
||||
521,
|
||||
0,
|
||||
};
|
||||
|
||||
/* Maps to enum ssh_keytypes_e */
|
||||
const int sig_lengths[] = {
|
||||
0, /* UNKNOWN */
|
||||
20,
|
||||
20,
|
||||
0, /* RSA1 */
|
||||
64,
|
||||
33,
|
||||
};
|
||||
|
||||
/* Maps to enum ssh_keytypes_e */
|
||||
const char *signature_types[] = {
|
||||
"", /* UNKNOWN */
|
||||
"ssh-dss",
|
||||
"ssh-rsa",
|
||||
"",/* RSA1 */
|
||||
"ecdsa-sha2-nistp521",
|
||||
"ssh-ed25519",
|
||||
};
|
||||
|
||||
/* Maps to enum ssh_digest_e */
|
||||
const char *hash_signatures[] = {
|
||||
"", /* Not used here */
|
||||
"ssh-rsa",
|
||||
"rsa-sha2-256",
|
||||
"rsa-sha2-512",
|
||||
};
|
||||
|
||||
/* Maps to enum ssh_digest_e */
|
||||
int hash_lengths[] = {
|
||||
0, /* Not used here */
|
||||
20,
|
||||
32,
|
||||
64,
|
||||
};
|
||||
|
||||
/* This tests all the base types and their signatures against each other */
|
||||
static void torture_pki_verify_mismatch(void **state)
|
||||
{
|
||||
int rc;
|
||||
int verbosity = torture_libssh_verbosity();
|
||||
ssh_key key = NULL, verify_key = NULL;
|
||||
ssh_signature sign = NULL, import_sig = NULL, new_sig = NULL;
|
||||
ssh_string blob;
|
||||
ssh_session session = ssh_new();
|
||||
enum ssh_keytypes_e key_type, sig_type, first_key;
|
||||
enum ssh_digest_e hash;
|
||||
int hash_length;
|
||||
|
||||
(void) state;
|
||||
|
||||
ssh_options_set(session, SSH_OPTIONS_LOG_VERBOSITY, &verbosity);
|
||||
|
||||
#ifdef HAVE_DSA
|
||||
first_key = SSH_KEYTYPE_DSS;
|
||||
#else
|
||||
first_key = SSH_KEYTYPE_RSA;
|
||||
#endif /* HAVE_DSA */
|
||||
|
||||
for (sig_type = first_key;
|
||||
sig_type <= SSH_KEYTYPE_ED25519;
|
||||
sig_type++) {
|
||||
if (sig_type == SSH_KEYTYPE_RSA1) {
|
||||
continue;
|
||||
}
|
||||
rc = ssh_pki_generate(sig_type, key_sizes[sig_type], &key);
|
||||
assert_true(rc == SSH_OK);
|
||||
assert_true(key != NULL);
|
||||
assert_int_equal(key->type, sig_type);
|
||||
assert_string_equal(key->type_c, key_types[sig_type]);
|
||||
|
||||
for (hash = SSH_DIGEST_AUTO;
|
||||
hash <= SSH_DIGEST_SHA512;
|
||||
hash++) {
|
||||
hash_length = ((hash == SSH_DIGEST_AUTO) ?
|
||||
sig_lengths[sig_type] : hash_lengths[hash]);
|
||||
|
||||
SSH_LOG(SSH_LOG_TRACE, "Creating signature %d with hash %d",
|
||||
sig_type, hash);
|
||||
|
||||
/* Create a valid signature using this key */
|
||||
sign = pki_do_sign_hash(key, HASH, hash_length, hash);
|
||||
assert_true(sign != NULL);
|
||||
assert_int_equal(sign->type, key->type);
|
||||
if (hash == SSH_DIGEST_AUTO) {
|
||||
assert_string_equal(sign->type_c, key->type_c);
|
||||
assert_string_equal(sign->type_c, signature_types[sig_type]);
|
||||
} else {
|
||||
assert_string_equal(sign->type_c, hash_signatures[hash]);
|
||||
}
|
||||
|
||||
/* Create a signature blob that can be imported and verified */
|
||||
blob = pki_signature_to_blob(sign);
|
||||
assert_non_null(blob);
|
||||
|
||||
/* Import and verify with current key
|
||||
* (this is not tested anywhere else yet) */
|
||||
import_sig = pki_signature_from_blob(key,
|
||||
blob,
|
||||
sig_type,
|
||||
hash);
|
||||
assert_non_null(import_sig);
|
||||
assert_int_equal(import_sig->type, key->type);
|
||||
if (hash == SSH_DIGEST_AUTO) {
|
||||
assert_string_equal(import_sig->type_c, key->type_c);
|
||||
assert_string_equal(import_sig->type_c, signature_types[sig_type]);
|
||||
} else {
|
||||
assert_string_equal(import_sig->type_c, hash_signatures[hash]);
|
||||
}
|
||||
|
||||
/* Internal API: Should work */
|
||||
rc = pki_signature_verify(session,
|
||||
import_sig,
|
||||
key,
|
||||
HASH,
|
||||
hash_length);
|
||||
assert_true(rc == SSH_OK);
|
||||
|
||||
/* XXX Test all the hash versions only with RSA.
|
||||
* This also skips the cleanup for the last hash so we can use the
|
||||
* created signatures later on
|
||||
*/
|
||||
if (sig_type != SSH_KEYTYPE_RSA || hash == SSH_DIGEST_SHA512) {
|
||||
break;
|
||||
}
|
||||
ssh_string_free(blob);
|
||||
ssh_signature_free(sign);
|
||||
ssh_signature_free(import_sig);
|
||||
}
|
||||
|
||||
for (key_type = first_key;
|
||||
key_type <= SSH_KEYTYPE_ED25519;
|
||||
key_type++) {
|
||||
if (key_type == SSH_KEYTYPE_RSA1) {
|
||||
continue;
|
||||
}
|
||||
SSH_LOG(SSH_LOG_TRACE, "Trying key %d with signature %d",
|
||||
key_type, sig_type);
|
||||
|
||||
rc = ssh_pki_generate(key_type, key_sizes[key_type], &verify_key);
|
||||
assert_true(rc == SSH_OK);
|
||||
assert_true(verify_key != NULL);
|
||||
|
||||
/* Should gradefully fail, but not crash */
|
||||
rc = pki_signature_verify(session,
|
||||
sign,
|
||||
verify_key,
|
||||
HASH,
|
||||
hash_length);
|
||||
assert_true(rc != SSH_OK);
|
||||
|
||||
/* Try the same with the imported signature */
|
||||
rc = pki_signature_verify(session,
|
||||
import_sig,
|
||||
verify_key,
|
||||
HASH,
|
||||
hash_length);
|
||||
assert_true(rc != SSH_OK);
|
||||
|
||||
/* Try to import the signature blob with different key */
|
||||
new_sig = pki_signature_from_blob(verify_key,
|
||||
blob,
|
||||
sig_type,
|
||||
SSH_DIGEST_SHA1);
|
||||
if (sig_type != key_type) {
|
||||
assert_true(new_sig == NULL);
|
||||
} else {
|
||||
/* Importing with the same key type should work */
|
||||
assert_true(new_sig != NULL);
|
||||
assert_int_equal(new_sig->type, key->type);
|
||||
assert_string_equal(new_sig->type_c, key->type_c);
|
||||
assert_string_equal(new_sig->type_c, signature_types[sig_type]);
|
||||
|
||||
/* The verificaiton should not work */
|
||||
rc = pki_signature_verify(session,
|
||||
new_sig,
|
||||
verify_key,
|
||||
HASH,
|
||||
hash_length);
|
||||
assert_true(rc != SSH_OK);
|
||||
|
||||
ssh_signature_free(new_sig);
|
||||
}
|
||||
SSH_KEY_FREE(verify_key);
|
||||
}
|
||||
ssh_string_free(blob);
|
||||
ssh_signature_free(sign);
|
||||
ssh_signature_free(import_sig);
|
||||
SSH_KEY_FREE(key);
|
||||
key = NULL;
|
||||
}
|
||||
|
||||
ssh_free(session);
|
||||
}
|
||||
|
||||
int torture_run_tests(void) {
|
||||
int rc;
|
||||
struct CMUnitTest tests[] = {
|
||||
cmocka_unit_test(torture_pki_keytype),
|
||||
cmocka_unit_test(torture_pki_signature),
|
||||
cmocka_unit_test(torture_pki_verify_mismatch),
|
||||
};
|
||||
|
||||
ssh_init();
|
||||
|
||||
@@ -392,7 +392,7 @@ static void torture_pki_generate_key_ecdsa(void **state)
|
||||
ssh_signature_free(sign);
|
||||
SSH_KEY_FREE(key);
|
||||
|
||||
rc = ssh_pki_generate(SSH_KEYTYPE_ECDSA, 512, &key);
|
||||
rc = ssh_pki_generate(SSH_KEYTYPE_ECDSA, 521, &key);
|
||||
assert_true(rc == SSH_OK);
|
||||
assert_true(key != NULL);
|
||||
sign = pki_do_sign(key, ECDSA_HASH, 20);
|
||||
|
||||
Reference in New Issue
Block a user