mirror of
https://git.libssh.org/projects/libssh.git
synced 2026-02-04 12:20:42 +09:00
Compare commits
10 Commits
02cbd41b92
...
301d0e16df
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
301d0e16df | ||
|
|
c182a21e11 | ||
|
|
3a28fbe5c6 | ||
|
|
65f363c9e3 | ||
|
|
1c763e29d1 | ||
|
|
7d85085d2a | ||
|
|
8e4d67aa9e | ||
|
|
266174a6d3 | ||
|
|
87db2659ec | ||
|
|
0fad4e6307 |
@@ -1,6 +1,15 @@
|
|||||||
CHANGELOG
|
CHANGELOG
|
||||||
=========
|
=========
|
||||||
|
|
||||||
|
version 0.11.3 (released 2025-09-09)
|
||||||
|
* Security:
|
||||||
|
* CVE-2025-8114: Fix NULL pointer dereference after allocation failure
|
||||||
|
* CVE-2025-8277: Fix memory leak of ephemeral key pair during repeated wrong KEX
|
||||||
|
* Potential UAF when send() fails during key exchange
|
||||||
|
* Fix possible timeout during KEX if client sends authentication too early (#311)
|
||||||
|
* Cleanup OpenSSL PKCS#11 provider when loaded
|
||||||
|
* Zeroize buffers containing private key blobs during export
|
||||||
|
|
||||||
version 0.11.2 (released 2025-06-24)
|
version 0.11.2 (released 2025-06-24)
|
||||||
* Security:
|
* Security:
|
||||||
* CVE-2025-4877 - Write beyond bounds in binary to base64 conversion
|
* CVE-2025-4877 - Write beyond bounds in binary to base64 conversion
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
cmake_minimum_required(VERSION 3.12.0)
|
cmake_minimum_required(VERSION 3.14.0)
|
||||||
|
|
||||||
# Specify search path for CMake modules to be loaded by include()
|
# Specify search path for CMake modules to be loaded by include()
|
||||||
# and find_package()
|
# and find_package()
|
||||||
@@ -9,7 +9,7 @@ list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/cmake/Modules")
|
|||||||
include(DefineCMakeDefaults)
|
include(DefineCMakeDefaults)
|
||||||
include(DefineCompilerFlags)
|
include(DefineCompilerFlags)
|
||||||
|
|
||||||
project(libssh VERSION 0.11.2 LANGUAGES C)
|
project(libssh VERSION 0.11.3 LANGUAGES C)
|
||||||
|
|
||||||
# global needed variable
|
# global needed variable
|
||||||
set(APPLICATION_NAME ${PROJECT_NAME})
|
set(APPLICATION_NAME ${PROJECT_NAME})
|
||||||
@@ -21,7 +21,7 @@ set(APPLICATION_NAME ${PROJECT_NAME})
|
|||||||
# Increment AGE. Set REVISION to 0
|
# Increment AGE. Set REVISION to 0
|
||||||
# If the source code was changed, but there were no interface changes:
|
# If the source code was changed, but there were no interface changes:
|
||||||
# Increment REVISION.
|
# Increment REVISION.
|
||||||
set(LIBRARY_VERSION "4.10.2")
|
set(LIBRARY_VERSION "4.10.3")
|
||||||
set(LIBRARY_SOVERSION "4")
|
set(LIBRARY_SOVERSION "4")
|
||||||
|
|
||||||
# where to look first for cmake modules, before ${CMAKE_ROOT}/Modules/ is checked
|
# where to look first for cmake modules, before ${CMAKE_ROOT}/Modules/ is checked
|
||||||
|
|||||||
@@ -157,6 +157,7 @@ void ssh_poll_ctx_free(ssh_poll_ctx ctx);
|
|||||||
int ssh_poll_ctx_add(ssh_poll_ctx ctx, ssh_poll_handle p);
|
int ssh_poll_ctx_add(ssh_poll_ctx ctx, ssh_poll_handle p);
|
||||||
int ssh_poll_ctx_add_socket (ssh_poll_ctx ctx, struct ssh_socket_struct *s);
|
int ssh_poll_ctx_add_socket (ssh_poll_ctx ctx, struct ssh_socket_struct *s);
|
||||||
void ssh_poll_ctx_remove(ssh_poll_ctx ctx, ssh_poll_handle p);
|
void ssh_poll_ctx_remove(ssh_poll_ctx ctx, ssh_poll_handle p);
|
||||||
|
bool ssh_poll_is_locked(ssh_poll_handle p);
|
||||||
int ssh_poll_ctx_dopoll(ssh_poll_ctx ctx, int timeout);
|
int ssh_poll_ctx_dopoll(ssh_poll_ctx ctx, int timeout);
|
||||||
ssh_poll_ctx ssh_poll_get_default_ctx(ssh_session session);
|
ssh_poll_ctx ssh_poll_get_default_ctx(ssh_session session);
|
||||||
int ssh_event_add_poll(ssh_event event, ssh_poll_handle p);
|
int ssh_event_add_poll(ssh_event event, ssh_poll_handle p);
|
||||||
|
|||||||
@@ -1 +1 @@
|
|||||||
4.10.2
|
4.10.3
|
||||||
445
src/ABI/libssh-4.10.3.symbols
Normal file
445
src/ABI/libssh-4.10.3.symbols
Normal file
@@ -0,0 +1,445 @@
|
|||||||
|
_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_aio_begin_read
|
||||||
|
sftp_aio_begin_write
|
||||||
|
sftp_aio_free
|
||||||
|
sftp_aio_wait_read
|
||||||
|
sftp_aio_wait_write
|
||||||
|
sftp_async_read
|
||||||
|
sftp_async_read_begin
|
||||||
|
sftp_attributes_free
|
||||||
|
sftp_canonicalize_path
|
||||||
|
sftp_channel_default_data_callback
|
||||||
|
sftp_channel_default_subsystem_request
|
||||||
|
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_expand_path
|
||||||
|
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_hardlink
|
||||||
|
sftp_home_directory
|
||||||
|
sftp_init
|
||||||
|
sftp_limits
|
||||||
|
sftp_limits_free
|
||||||
|
sftp_lsetstat
|
||||||
|
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_free
|
||||||
|
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_parse_config
|
||||||
|
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_state
|
||||||
|
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_forward_port
|
||||||
|
ssh_channel_open_forward_unix
|
||||||
|
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_pty_size_modes
|
||||||
|
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_dup
|
||||||
|
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_open_reply_accept_channel
|
||||||
|
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_base64_format
|
||||||
|
ssh_pki_export_privkey_file
|
||||||
|
ssh_pki_export_privkey_file_format
|
||||||
|
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_request_no_more_sessions
|
||||||
|
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_issue_banner
|
||||||
|
ssh_send_keepalive
|
||||||
|
ssh_server_init_kex
|
||||||
|
ssh_service_request
|
||||||
|
ssh_session_export_known_hosts_entry
|
||||||
|
ssh_session_get_known_hosts_entry
|
||||||
|
ssh_session_has_known_hosts_entry
|
||||||
|
ssh_session_is_known_server
|
||||||
|
ssh_session_set_disconnect_message
|
||||||
|
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_default
|
||||||
|
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_publickey_auto_get_current_identity
|
||||||
|
ssh_userauth_try_publickey
|
||||||
|
ssh_version
|
||||||
|
ssh_vlog
|
||||||
|
ssh_write_knownhost
|
||||||
|
string_burn
|
||||||
|
string_copy
|
||||||
|
string_data
|
||||||
|
string_fill
|
||||||
|
string_free
|
||||||
|
string_from_char
|
||||||
|
string_len
|
||||||
|
string_new
|
||||||
|
string_to_char
|
||||||
@@ -407,6 +407,11 @@ int ssh_dh_init_common(struct ssh_crypto_struct *crypto)
|
|||||||
struct dh_ctx *ctx = NULL;
|
struct dh_ctx *ctx = NULL;
|
||||||
int rc;
|
int rc;
|
||||||
|
|
||||||
|
/* Cleanup any previously allocated dh_ctx */
|
||||||
|
if (crypto->dh_ctx != NULL) {
|
||||||
|
ssh_dh_cleanup(crypto);
|
||||||
|
}
|
||||||
|
|
||||||
ctx = calloc(1, sizeof(*ctx));
|
ctx = calloc(1, sizeof(*ctx));
|
||||||
if (ctx == NULL) {
|
if (ctx == NULL) {
|
||||||
return SSH_ERROR;
|
return SSH_ERROR;
|
||||||
|
|||||||
@@ -237,6 +237,11 @@ int ssh_dh_init_common(struct ssh_crypto_struct *crypto)
|
|||||||
struct dh_ctx *ctx = NULL;
|
struct dh_ctx *ctx = NULL;
|
||||||
int rc;
|
int rc;
|
||||||
|
|
||||||
|
/* Cleanup any previously allocated dh_ctx */
|
||||||
|
if (crypto->dh_ctx != NULL) {
|
||||||
|
ssh_dh_cleanup(crypto);
|
||||||
|
}
|
||||||
|
|
||||||
ctx = calloc(1, sizeof(*ctx));
|
ctx = calloc(1, sizeof(*ctx));
|
||||||
if (ctx == NULL) {
|
if (ctx == NULL) {
|
||||||
return SSH_ERROR;
|
return SSH_ERROR;
|
||||||
|
|||||||
@@ -191,6 +191,17 @@ static ssh_string ssh_ecdh_generate(ssh_session session)
|
|||||||
#endif /* OPENSSL_VERSION_NUMBER */
|
#endif /* OPENSSL_VERSION_NUMBER */
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Free any previously allocated privkey */
|
||||||
|
if (session->next_crypto->ecdh_privkey != NULL) {
|
||||||
|
#if OPENSSL_VERSION_NUMBER < 0x30000000L
|
||||||
|
EC_KEY_free(session->next_crypto->ecdh_privkey);
|
||||||
|
#else
|
||||||
|
EVP_PKEY_free(session->next_crypto->ecdh_privkey);
|
||||||
|
#endif
|
||||||
|
session->next_crypto->ecdh_privkey = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
session->next_crypto->ecdh_privkey = key;
|
session->next_crypto->ecdh_privkey = key;
|
||||||
return pubkey_string;
|
return pubkey_string;
|
||||||
}
|
}
|
||||||
@@ -219,6 +230,7 @@ int ssh_client_ecdh_init(ssh_session session)
|
|||||||
return SSH_ERROR;
|
return SSH_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ssh_string_free(session->next_crypto->ecdh_client_pubkey);
|
||||||
session->next_crypto->ecdh_client_pubkey = client_pubkey;
|
session->next_crypto->ecdh_client_pubkey = client_pubkey;
|
||||||
|
|
||||||
/* register the packet callbacks */
|
/* register the packet callbacks */
|
||||||
|
|||||||
@@ -101,8 +101,15 @@ int ssh_client_ecdh_init(ssh_session session)
|
|||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Free any previously allocated privkey */
|
||||||
|
if (session->next_crypto->ecdh_privkey != NULL) {
|
||||||
|
gcry_sexp_release(session->next_crypto->ecdh_privkey);
|
||||||
|
session->next_crypto->ecdh_privkey = NULL;
|
||||||
|
}
|
||||||
session->next_crypto->ecdh_privkey = key;
|
session->next_crypto->ecdh_privkey = key;
|
||||||
key = NULL;
|
key = NULL;
|
||||||
|
|
||||||
|
SSH_STRING_FREE(session->next_crypto->ecdh_client_pubkey);
|
||||||
session->next_crypto->ecdh_client_pubkey = client_pubkey;
|
session->next_crypto->ecdh_client_pubkey = client_pubkey;
|
||||||
client_pubkey = NULL;
|
client_pubkey = NULL;
|
||||||
|
|
||||||
|
|||||||
@@ -70,6 +70,12 @@ int ssh_client_ecdh_init(ssh_session session)
|
|||||||
return SSH_ERROR;
|
return SSH_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Free any previously allocated privkey */
|
||||||
|
if (session->next_crypto->ecdh_privkey != NULL) {
|
||||||
|
mbedtls_ecp_keypair_free(session->next_crypto->ecdh_privkey);
|
||||||
|
SAFE_FREE(session->next_crypto->ecdh_privkey);
|
||||||
|
}
|
||||||
|
|
||||||
session->next_crypto->ecdh_privkey = malloc(sizeof(mbedtls_ecp_keypair));
|
session->next_crypto->ecdh_privkey = malloc(sizeof(mbedtls_ecp_keypair));
|
||||||
if (session->next_crypto->ecdh_privkey == NULL) {
|
if (session->next_crypto->ecdh_privkey == NULL) {
|
||||||
return SSH_ERROR;
|
return SSH_ERROR;
|
||||||
@@ -110,6 +116,7 @@ int ssh_client_ecdh_init(ssh_session session)
|
|||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
SSH_STRING_FREE(session->next_crypto->ecdh_client_pubkey);
|
||||||
session->next_crypto->ecdh_client_pubkey = client_pubkey;
|
session->next_crypto->ecdh_client_pubkey = client_pubkey;
|
||||||
client_pubkey = NULL;
|
client_pubkey = NULL;
|
||||||
|
|
||||||
|
|||||||
@@ -1487,6 +1487,8 @@ int ssh_make_sessionid(ssh_session session)
|
|||||||
ssh_log_hexdump("hash buffer", ssh_buffer_get(buf), ssh_buffer_get_len(buf));
|
ssh_log_hexdump("hash buffer", ssh_buffer_get(buf), ssh_buffer_get_len(buf));
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
/* Set rc for the following switch statement in case we goto error. */
|
||||||
|
rc = SSH_ERROR;
|
||||||
switch (session->next_crypto->kex_type) {
|
switch (session->next_crypto->kex_type) {
|
||||||
case SSH_KEX_DH_GROUP1_SHA1:
|
case SSH_KEX_DH_GROUP1_SHA1:
|
||||||
case SSH_KEX_DH_GROUP14_SHA1:
|
case SSH_KEX_DH_GROUP14_SHA1:
|
||||||
@@ -1546,6 +1548,7 @@ int ssh_make_sessionid(ssh_session session)
|
|||||||
session->next_crypto->secret_hash);
|
session->next_crypto->secret_hash);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* During the first kex, secret hash and session ID are equal. However, after
|
/* During the first kex, secret hash and session ID are equal. However, after
|
||||||
* a key re-exchange, a new secret hash is calculated. This hash will not replace
|
* a key re-exchange, a new secret hash is calculated. This hash will not replace
|
||||||
* but complement existing session id.
|
* but complement existing session id.
|
||||||
@@ -1554,6 +1557,7 @@ int ssh_make_sessionid(ssh_session session)
|
|||||||
session->next_crypto->session_id = malloc(session->next_crypto->digest_len);
|
session->next_crypto->session_id = malloc(session->next_crypto->digest_len);
|
||||||
if (session->next_crypto->session_id == NULL) {
|
if (session->next_crypto->session_id == NULL) {
|
||||||
ssh_set_error_oom(session);
|
ssh_set_error_oom(session);
|
||||||
|
rc = SSH_ERROR;
|
||||||
goto error;
|
goto error;
|
||||||
}
|
}
|
||||||
memcpy(session->next_crypto->session_id, session->next_crypto->secret_hash,
|
memcpy(session->next_crypto->session_id, session->next_crypto->secret_hash,
|
||||||
|
|||||||
@@ -294,6 +294,7 @@ static enum ssh_packet_filter_result_e ssh_packet_incoming_filter(ssh_session se
|
|||||||
* or session_state == SSH_SESSION_STATE_INITIAL_KEX
|
* or session_state == SSH_SESSION_STATE_INITIAL_KEX
|
||||||
* - dh_handshake_state == DH_STATE_INIT
|
* - dh_handshake_state == DH_STATE_INIT
|
||||||
* or dh_handshake_state == DH_STATE_INIT_SENT (re-exchange)
|
* or dh_handshake_state == DH_STATE_INIT_SENT (re-exchange)
|
||||||
|
* or dh_handshake_state == DH_STATE_REQUEST_SENT (dh-gex)
|
||||||
* or dh_handshake_state == DH_STATE_FINISHED (re-exchange)
|
* or dh_handshake_state == DH_STATE_FINISHED (re-exchange)
|
||||||
*
|
*
|
||||||
* Transitions:
|
* Transitions:
|
||||||
@@ -313,6 +314,7 @@ static enum ssh_packet_filter_result_e ssh_packet_incoming_filter(ssh_session se
|
|||||||
|
|
||||||
if ((session->dh_handshake_state != DH_STATE_INIT) &&
|
if ((session->dh_handshake_state != DH_STATE_INIT) &&
|
||||||
(session->dh_handshake_state != DH_STATE_INIT_SENT) &&
|
(session->dh_handshake_state != DH_STATE_INIT_SENT) &&
|
||||||
|
(session->dh_handshake_state != DH_STATE_REQUEST_SENT) &&
|
||||||
(session->dh_handshake_state != DH_STATE_FINISHED))
|
(session->dh_handshake_state != DH_STATE_FINISHED))
|
||||||
{
|
{
|
||||||
rc = SSH_PACKET_DENIED;
|
rc = SSH_PACKET_DENIED;
|
||||||
|
|||||||
18
src/poll.c
18
src/poll.c
@@ -422,7 +422,7 @@ void ssh_poll_set_events(ssh_poll_handle p, short events)
|
|||||||
{
|
{
|
||||||
p->events = events;
|
p->events = events;
|
||||||
if (p->ctx != NULL) {
|
if (p->ctx != NULL) {
|
||||||
if (p->lock_cnt == 0) {
|
if (!ssh_poll_is_locked(p)) {
|
||||||
p->ctx->pollfds[p->x.idx].events = events;
|
p->ctx->pollfds[p->x.idx].events = events;
|
||||||
} else if (!(p->ctx->pollfds[p->x.idx].events & POLLOUT)) {
|
} else if (!(p->ctx->pollfds[p->x.idx].events & POLLOUT)) {
|
||||||
/* if locked, allow only setting POLLOUT to prevent recursive
|
/* if locked, allow only setting POLLOUT to prevent recursive
|
||||||
@@ -669,6 +669,20 @@ void ssh_poll_ctx_remove(ssh_poll_ctx ctx, ssh_poll_handle p)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Returns if a poll object is locked.
|
||||||
|
*
|
||||||
|
* @param p Pointer to an already allocated poll object.
|
||||||
|
* @returns true if the poll object is locked; false otherwise.
|
||||||
|
*/
|
||||||
|
bool ssh_poll_is_locked(ssh_poll_handle p)
|
||||||
|
{
|
||||||
|
if (p == NULL) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return p->lock_cnt > 0;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Poll all the sockets associated through a poll object with a
|
* @brief Poll all the sockets associated through a poll object with a
|
||||||
* poll context. If any of the events are set after the poll, the
|
* poll context. If any of the events are set after the poll, the
|
||||||
@@ -703,7 +717,7 @@ int ssh_poll_ctx_dopoll(ssh_poll_ctx ctx, int timeout)
|
|||||||
* output buffer */
|
* output buffer */
|
||||||
for (i = 0; i < ctx->polls_used; i++) {
|
for (i = 0; i < ctx->polls_used; i++) {
|
||||||
/* The lock allows only POLLOUT events: drop the rest */
|
/* The lock allows only POLLOUT events: drop the rest */
|
||||||
if (ctx->pollptrs[i]->lock_cnt > 0) {
|
if (ssh_poll_is_locked(ctx->pollptrs[i])) {
|
||||||
ctx->pollfds[i].events &= POLLOUT;
|
ctx->pollfds[i].events &= POLLOUT;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -478,7 +478,7 @@ void ssh_socket_close(ssh_socket s)
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
if (s->poll_handle != NULL) {
|
if (s->poll_handle != NULL && !ssh_poll_is_locked(s->poll_handle)) {
|
||||||
ssh_poll_free(s->poll_handle);
|
ssh_poll_free(s->poll_handle);
|
||||||
s->poll_handle = NULL;
|
s->poll_handle = NULL;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -181,7 +181,10 @@ void crypto_free(struct ssh_crypto_struct *crypto)
|
|||||||
#endif /* OPENSSL_VERSION_NUMBER */
|
#endif /* OPENSSL_VERSION_NUMBER */
|
||||||
#elif defined HAVE_GCRYPT_ECC
|
#elif defined HAVE_GCRYPT_ECC
|
||||||
gcry_sexp_release(crypto->ecdh_privkey);
|
gcry_sexp_release(crypto->ecdh_privkey);
|
||||||
#endif
|
#elif defined HAVE_LIBMBEDCRYPTO
|
||||||
|
mbedtls_ecp_keypair_free(crypto->ecdh_privkey);
|
||||||
|
SAFE_FREE(crypto->ecdh_privkey);
|
||||||
|
#endif /* HAVE_LIBGCRYPT */
|
||||||
crypto->ecdh_privkey = NULL;
|
crypto->ecdh_privkey = NULL;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -105,6 +105,7 @@ add_subdirectory(unittests)
|
|||||||
# OpenSSH Capabilities are required for all unit tests
|
# OpenSSH Capabilities are required for all unit tests
|
||||||
find_program(SSH_EXECUTABLE NAMES ssh)
|
find_program(SSH_EXECUTABLE NAMES ssh)
|
||||||
if (SSH_EXECUTABLE)
|
if (SSH_EXECUTABLE)
|
||||||
|
file(SIZE ${SSH_EXECUTABLE} SSH_EXECUTABLE_SIZE)
|
||||||
execute_process(COMMAND ${SSH_EXECUTABLE} -V ERROR_VARIABLE OPENSSH_VERSION_STR)
|
execute_process(COMMAND ${SSH_EXECUTABLE} -V ERROR_VARIABLE OPENSSH_VERSION_STR)
|
||||||
string(REGEX REPLACE "^.*OpenSSH_([0-9]+).[0-9].*$" "\\1" OPENSSH_VERSION_MAJOR "${OPENSSH_VERSION_STR}")
|
string(REGEX REPLACE "^.*OpenSSH_([0-9]+).[0-9].*$" "\\1" OPENSSH_VERSION_MAJOR "${OPENSSH_VERSION_STR}")
|
||||||
string(REGEX REPLACE "^.*OpenSSH_[0-9]+.([0-9]).*$" "\\1" OPENSSH_VERSION_MINOR "${OPENSSH_VERSION_STR}")
|
string(REGEX REPLACE "^.*OpenSSH_[0-9]+.([0-9]).*$" "\\1" OPENSSH_VERSION_MINOR "${OPENSSH_VERSION_STR}")
|
||||||
|
|||||||
@@ -31,6 +31,7 @@
|
|||||||
#include "libssh/priv.h"
|
#include "libssh/priv.h"
|
||||||
#include "libssh/session.h"
|
#include "libssh/session.h"
|
||||||
#include "libssh/crypto.h"
|
#include "libssh/crypto.h"
|
||||||
|
#include "libssh/token.h"
|
||||||
|
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
@@ -96,6 +97,7 @@ static int session_teardown(void **state)
|
|||||||
struct torture_state *s = *state;
|
struct torture_state *s = *state;
|
||||||
|
|
||||||
ssh_free(s->ssh.session);
|
ssh_free(s->ssh.session);
|
||||||
|
s->ssh.session = NULL;
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@@ -148,7 +150,7 @@ static void torture_rekey_default(void **state)
|
|||||||
ssh_disconnect(s->ssh.session);
|
ssh_disconnect(s->ssh.session);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void sanity_check_session(void **state)
|
static void sanity_check_session_size(void **state, uint64_t rekey_limit)
|
||||||
{
|
{
|
||||||
struct torture_state *s = *state;
|
struct torture_state *s = *state;
|
||||||
struct ssh_crypto_struct *c = NULL;
|
struct ssh_crypto_struct *c = NULL;
|
||||||
@@ -156,9 +158,9 @@ static void sanity_check_session(void **state)
|
|||||||
c = s->ssh.session->current_crypto;
|
c = s->ssh.session->current_crypto;
|
||||||
assert_non_null(c);
|
assert_non_null(c);
|
||||||
assert_int_equal(c->in_cipher->max_blocks,
|
assert_int_equal(c->in_cipher->max_blocks,
|
||||||
bytes / c->in_cipher->blocksize);
|
rekey_limit / c->in_cipher->blocksize);
|
||||||
assert_int_equal(c->out_cipher->max_blocks,
|
assert_int_equal(c->out_cipher->max_blocks,
|
||||||
bytes / c->out_cipher->blocksize);
|
rekey_limit / c->out_cipher->blocksize);
|
||||||
/* when strict kex is used, the newkeys reset the sequence number */
|
/* when strict kex is used, the newkeys reset the sequence number */
|
||||||
if ((s->ssh.session->flags & SSH_SESSION_FLAG_KEX_STRICT) != 0) {
|
if ((s->ssh.session->flags & SSH_SESSION_FLAG_KEX_STRICT) != 0) {
|
||||||
assert_int_equal(c->out_cipher->packets, s->ssh.session->send_seq);
|
assert_int_equal(c->out_cipher->packets, s->ssh.session->send_seq);
|
||||||
@@ -170,6 +172,10 @@ static void sanity_check_session(void **state)
|
|||||||
assert_true(c->in_cipher->packets < s->ssh.session->recv_seq);
|
assert_true(c->in_cipher->packets < s->ssh.session->recv_seq);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
static void sanity_check_session(void **state)
|
||||||
|
{
|
||||||
|
sanity_check_session_size(state, bytes);
|
||||||
|
}
|
||||||
|
|
||||||
/* We lower the rekey limits manually and check that the rekey
|
/* We lower the rekey limits manually and check that the rekey
|
||||||
* really happens when sending data
|
* really happens when sending data
|
||||||
@@ -275,7 +281,7 @@ static int session_setup_sftp_client(void **state)
|
|||||||
/* To trigger rekey by receiving data, the easiest thing is probably to
|
/* To trigger rekey by receiving data, the easiest thing is probably to
|
||||||
* use sftp
|
* use sftp
|
||||||
*/
|
*/
|
||||||
static void torture_rekey_recv(void **state)
|
static void torture_rekey_recv_size(void **state, uint64_t rekey_limit)
|
||||||
{
|
{
|
||||||
struct torture_state *s = *state;
|
struct torture_state *s = *state;
|
||||||
struct ssh_crypto_struct *c = NULL;
|
struct ssh_crypto_struct *c = NULL;
|
||||||
@@ -290,7 +296,7 @@ static void torture_rekey_recv(void **state)
|
|||||||
mode_t mask;
|
mode_t mask;
|
||||||
int rc;
|
int rc;
|
||||||
|
|
||||||
sanity_check_session(state);
|
sanity_check_session_size(state, rekey_limit);
|
||||||
/* Copy the initial secret hash = session_id so we know we changed keys later */
|
/* Copy the initial secret hash = session_id so we know we changed keys later */
|
||||||
c = s->ssh.session->current_crypto;
|
c = s->ssh.session->current_crypto;
|
||||||
assert_non_null(c);
|
assert_non_null(c);
|
||||||
@@ -324,8 +330,10 @@ static void torture_rekey_recv(void **state)
|
|||||||
|
|
||||||
/* The rekey limit was restored in the new crypto to the same value */
|
/* The rekey limit was restored in the new crypto to the same value */
|
||||||
c = s->ssh.session->current_crypto;
|
c = s->ssh.session->current_crypto;
|
||||||
assert_int_equal(c->in_cipher->max_blocks, bytes / c->in_cipher->blocksize);
|
assert_int_equal(c->in_cipher->max_blocks,
|
||||||
assert_int_equal(c->out_cipher->max_blocks, bytes / c->out_cipher->blocksize);
|
rekey_limit / c->in_cipher->blocksize);
|
||||||
|
assert_int_equal(c->out_cipher->max_blocks,
|
||||||
|
rekey_limit / c->out_cipher->blocksize);
|
||||||
/* Check that the secret hash is different than initially */
|
/* Check that the secret hash is different than initially */
|
||||||
assert_memory_not_equal(secret_hash, c->secret_hash, c->digest_len);
|
assert_memory_not_equal(secret_hash, c->secret_hash, c->digest_len);
|
||||||
free(secret_hash);
|
free(secret_hash);
|
||||||
@@ -333,6 +341,11 @@ static void torture_rekey_recv(void **state)
|
|||||||
torture_sftp_close(s->ssh.tsftp);
|
torture_sftp_close(s->ssh.tsftp);
|
||||||
ssh_disconnect(s->ssh.session);
|
ssh_disconnect(s->ssh.session);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void torture_rekey_recv(void **state)
|
||||||
|
{
|
||||||
|
torture_rekey_recv_size(state, bytes);
|
||||||
|
}
|
||||||
#endif /* WITH_SFTP */
|
#endif /* WITH_SFTP */
|
||||||
|
|
||||||
/* Rekey time requires rekey after specified time and is off by default.
|
/* Rekey time requires rekey after specified time and is off by default.
|
||||||
@@ -836,6 +849,81 @@ static void torture_rekey_guess_wrong_recv(void **state)
|
|||||||
|
|
||||||
torture_rekey_recv(state);
|
torture_rekey_recv(state);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void torture_rekey_guess_all_combinations(void **state)
|
||||||
|
{
|
||||||
|
struct torture_state *s = *state;
|
||||||
|
char sshd_config[256] = "";
|
||||||
|
char client_kex[256] = "";
|
||||||
|
const char *supported = NULL;
|
||||||
|
struct ssh_tokens_st *s_tok = NULL;
|
||||||
|
uint64_t rekey_limit = 0;
|
||||||
|
int rc, i, j;
|
||||||
|
|
||||||
|
/* The rekey limit is 1/2 of the transferred file size so we will likely get
|
||||||
|
* 2 rekeys per test, which still runs for acceptable time */
|
||||||
|
rekey_limit = atoll(SSH_EXECUTABLE_SIZE);
|
||||||
|
rekey_limit /= 2;
|
||||||
|
|
||||||
|
if (ssh_fips_mode()) {
|
||||||
|
supported = ssh_kex_get_fips_methods(SSH_KEX);
|
||||||
|
} else {
|
||||||
|
supported = ssh_kex_get_supported_method(SSH_KEX);
|
||||||
|
}
|
||||||
|
assert_non_null(supported);
|
||||||
|
|
||||||
|
s_tok = ssh_tokenize(supported, ',');
|
||||||
|
assert_non_null(s_tok);
|
||||||
|
for (i = 0; s_tok->tokens[i]; i++) {
|
||||||
|
/* Skip algorithms not supported by the OpenSSH server */
|
||||||
|
if (strstr(OPENSSH_KEX, s_tok->tokens[i]) == NULL) {
|
||||||
|
SSH_LOG(SSH_LOG_INFO, "Server: %s [skipping]", s_tok->tokens[i]);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
SSH_LOG(SSH_LOG_INFO, "Server: %s", s_tok->tokens[i]);
|
||||||
|
snprintf(sshd_config,
|
||||||
|
sizeof(sshd_config),
|
||||||
|
"KexAlgorithms %s",
|
||||||
|
s_tok->tokens[i]);
|
||||||
|
/* This sets an only supported kex algorithm that we do not have as
|
||||||
|
* a first option in the client */
|
||||||
|
torture_update_sshd_config(state, sshd_config);
|
||||||
|
|
||||||
|
for (j = 0; s_tok->tokens[j]; j++) {
|
||||||
|
if (i == j) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
session_setup(state);
|
||||||
|
/* Make the client send the first_kex_packet_follows flag during key
|
||||||
|
* exchange as well as during the rekey */
|
||||||
|
s->ssh.session->send_first_kex_follows = true;
|
||||||
|
|
||||||
|
rc = ssh_options_set(s->ssh.session,
|
||||||
|
SSH_OPTIONS_REKEY_DATA,
|
||||||
|
&rekey_limit);
|
||||||
|
assert_ssh_return_code(s->ssh.session, rc);
|
||||||
|
|
||||||
|
/* Client kex preference will have the second of the pair and the
|
||||||
|
* server one as a second to negotiate on the second attempt */
|
||||||
|
snprintf(client_kex,
|
||||||
|
sizeof(client_kex),
|
||||||
|
"%s,%s",
|
||||||
|
s_tok->tokens[j],
|
||||||
|
s_tok->tokens[i]);
|
||||||
|
SSH_LOG(SSH_LOG_INFO, "Client: %s", client_kex);
|
||||||
|
rc = ssh_options_set(s->ssh.session,
|
||||||
|
SSH_OPTIONS_KEY_EXCHANGE,
|
||||||
|
client_kex);
|
||||||
|
assert_ssh_return_code(s->ssh.session, rc);
|
||||||
|
session_setup_sftp(state);
|
||||||
|
torture_rekey_recv_size(state, rekey_limit);
|
||||||
|
session_teardown(state);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ssh_tokens_free(s_tok);
|
||||||
|
}
|
||||||
#endif /* WITH_SFTP */
|
#endif /* WITH_SFTP */
|
||||||
|
|
||||||
int torture_run_tests(void) {
|
int torture_run_tests(void) {
|
||||||
@@ -905,6 +993,7 @@ int torture_run_tests(void) {
|
|||||||
cmocka_unit_test_setup_teardown(torture_rekey_guess_wrong_recv,
|
cmocka_unit_test_setup_teardown(torture_rekey_guess_wrong_recv,
|
||||||
session_setup,
|
session_setup,
|
||||||
session_teardown),
|
session_teardown),
|
||||||
|
cmocka_unit_test(torture_rekey_guess_all_combinations),
|
||||||
#endif /* WITH_SFTP */
|
#endif /* WITH_SFTP */
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -27,6 +27,7 @@ int main(int argc, char **argv)
|
|||||||
const char *banner = NULL;
|
const char *banner = NULL;
|
||||||
ssh_session session = NULL;
|
ssh_session session = NULL;
|
||||||
const char *hostkeys = NULL;
|
const char *hostkeys = NULL;
|
||||||
|
const char *kex = NULL;
|
||||||
int rc = 1;
|
int rc = 1;
|
||||||
|
|
||||||
bool process_config = false;
|
bool process_config = false;
|
||||||
@@ -67,6 +68,13 @@ int main(int argc, char **argv)
|
|||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Enable all supported kex algorithms */
|
||||||
|
kex = ssh_kex_get_supported_method(SSH_KEX);
|
||||||
|
rc = ssh_options_set(session, SSH_OPTIONS_KEY_EXCHANGE, kex);
|
||||||
|
if (rc < 0) {
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
|
||||||
rc = ssh_connect(session);
|
rc = ssh_connect(session);
|
||||||
if (rc != SSH_OK) {
|
if (rc != SSH_OK) {
|
||||||
fprintf(stderr, "Connection failed : %s\n", ssh_get_error(session));
|
fprintf(stderr, "Connection failed : %s\n", ssh_get_error(session));
|
||||||
|
|||||||
@@ -65,6 +65,7 @@
|
|||||||
#cmakedefine NCAT_EXECUTABLE "${NCAT_EXECUTABLE}"
|
#cmakedefine NCAT_EXECUTABLE "${NCAT_EXECUTABLE}"
|
||||||
#cmakedefine SSHD_EXECUTABLE "${SSHD_EXECUTABLE}"
|
#cmakedefine SSHD_EXECUTABLE "${SSHD_EXECUTABLE}"
|
||||||
#cmakedefine SSH_EXECUTABLE "${SSH_EXECUTABLE}"
|
#cmakedefine SSH_EXECUTABLE "${SSH_EXECUTABLE}"
|
||||||
|
#cmakedefine SSH_EXECUTABLE_SIZE "${SSH_EXECUTABLE_SIZE}"
|
||||||
#cmakedefine DROPBEAR_EXECUTABLE "${DROPBEAR_EXECUTABLE}"
|
#cmakedefine DROPBEAR_EXECUTABLE "${DROPBEAR_EXECUTABLE}"
|
||||||
#cmakedefine WITH_TIMEOUT ${WITH_TIMEOUT}
|
#cmakedefine WITH_TIMEOUT ${WITH_TIMEOUT}
|
||||||
#cmakedefine TIMEOUT_EXECUTABLE "${TIMEOUT_EXECUTABLE}"
|
#cmakedefine TIMEOUT_EXECUTABLE "${TIMEOUT_EXECUTABLE}"
|
||||||
|
|||||||
Reference in New Issue
Block a user