mirror of
https://git.libssh.org/projects/libssh.git
synced 2026-02-04 20:30:38 +09:00
Compare commits
59 Commits
libssh-0.6
...
libssh-0.6
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
319129399d | ||
|
|
87ae95eb3c | ||
|
|
055f102601 | ||
|
|
2d6862ddb9 | ||
|
|
22aa60d506 | ||
|
|
4b02bbbd32 | ||
|
|
31ded2070e | ||
|
|
df3d53e561 | ||
|
|
f28c3099da | ||
|
|
32a106c70d | ||
|
|
5d75090d9f | ||
|
|
32a3cfe661 | ||
|
|
1c59844dfe | ||
|
|
f071954a76 | ||
|
|
a033b93c61 | ||
|
|
b7856780a9 | ||
|
|
8b3425865a | ||
|
|
a30e234c03 | ||
|
|
bbf172a79c | ||
|
|
f28748578d | ||
|
|
36f7d1a614 | ||
|
|
71241ca68c | ||
|
|
bfbf9283d0 | ||
|
|
d75573e665 | ||
|
|
8fe36e3d07 | ||
|
|
f2e9ce68e7 | ||
|
|
cfb4d27c47 | ||
|
|
d366e289f3 | ||
|
|
2fc8347504 | ||
|
|
2691ed595e | ||
|
|
7b133cf9f5 | ||
|
|
9b59f1a222 | ||
|
|
8f21f879d3 | ||
|
|
67752dabfc | ||
|
|
34ac4e4248 | ||
|
|
1928fb6a85 | ||
|
|
5b1678f197 | ||
|
|
8aff91dfcb | ||
|
|
c0cc12d582 | ||
|
|
a162071f9a | ||
|
|
2091dab273 | ||
|
|
7f18ec4620 | ||
|
|
8e698382db | ||
|
|
ce10d40325 | ||
|
|
3fed9a5aff | ||
|
|
da0c77fdb1 | ||
|
|
818c80baed | ||
|
|
bb55bb2daf | ||
|
|
fdced9d544 | ||
|
|
96db44ff17 | ||
|
|
70dbbfa320 | ||
|
|
1118fc2adf | ||
|
|
257449a0b6 | ||
|
|
8752460df4 | ||
|
|
6f089a098b | ||
|
|
8b3be050c9 | ||
|
|
ade33474be | ||
|
|
dbf7749696 | ||
|
|
2db45dd547 |
1
.gitignore
vendored
1
.gitignore
vendored
@@ -6,3 +6,4 @@
|
||||
build
|
||||
cscope.*
|
||||
tags
|
||||
build
|
||||
|
||||
@@ -8,7 +8,7 @@ set(APPLICATION_NAME ${PROJECT_NAME})
|
||||
|
||||
set(APPLICATION_VERSION_MAJOR "0")
|
||||
set(APPLICATION_VERSION_MINOR "6")
|
||||
set(APPLICATION_VERSION_PATCH "3")
|
||||
set(APPLICATION_VERSION_PATCH "4")
|
||||
|
||||
set(APPLICATION_VERSION "${APPLICATION_VERSION_MAJOR}.${APPLICATION_VERSION_MINOR}.${APPLICATION_VERSION_PATCH}")
|
||||
|
||||
@@ -19,7 +19,7 @@ set(APPLICATION_VERSION "${APPLICATION_VERSION_MAJOR}.${APPLICATION_VERSION_MINO
|
||||
# Increment AGE. Set REVISION to 0
|
||||
# If the source code was changed, but there were no interface changes:
|
||||
# Increment REVISION.
|
||||
set(LIBRARY_VERSION "4.4.1")
|
||||
set(LIBRARY_VERSION "4.5.0")
|
||||
set(LIBRARY_SOVERSION "4")
|
||||
|
||||
# where to look first for cmake modules, before ${CMAKE_ROOT}/Modules/ is checked
|
||||
@@ -97,18 +97,22 @@ install(
|
||||
)
|
||||
|
||||
# cmake config files
|
||||
configure_file(libssh-config.cmake.in ${CMAKE_CURRENT_BINARY_DIR}/libssh-config.cmake @ONLY)
|
||||
configure_file(libssh-config-version.cmake.in ${CMAKE_CURRENT_BINARY_DIR}/libssh-config-version.cmake @ONLY)
|
||||
set(LIBSSH_LIBRARY_NAME ${CMAKE_SHARED_LIBRARY_PREFIX}ssh${CMAKE_SHARED_LIBRARY_SUFFIX})
|
||||
set(LIBSSH_THREADS_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)
|
||||
install(
|
||||
FILES
|
||||
${CMAKE_CURRENT_BINARY_DIR}/libssh-config.cmake
|
||||
${CMAKE_CURRENT_BINARY_DIR}/libssh-config-version.cmake
|
||||
${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}-config.cmake
|
||||
${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}-config-version.cmake
|
||||
DESTINATION
|
||||
${CMAKE_INSTALL_DIR}
|
||||
${CMAKE_INSTALL_DIR}/${PROJECT_NAME}
|
||||
COMPONENT
|
||||
devel
|
||||
)
|
||||
|
||||
|
||||
# in tree build settings
|
||||
configure_file(libssh-build-tree-settings.cmake.in ${CMAKE_CURRENT_BINARY_DIR}/libssh-build-tree-settings.cmake @ONLY)
|
||||
|
||||
|
||||
14
ChangeLog
14
ChangeLog
@@ -1,6 +1,20 @@
|
||||
ChangeLog
|
||||
==========
|
||||
|
||||
version 0.6.4 (released 2014-12-19)
|
||||
* Fixed CVE-2014-8132.
|
||||
* Added SHA-2 for session ID signing with ECDSA keys.
|
||||
* Added support for ECDSA host keys.
|
||||
* Added support for more ECDSA hostkey algorithms.
|
||||
* Added ssh_pki_key_ecdsa_name() API.
|
||||
* Fixed setting the bindfd only after successful listen.
|
||||
* Fixed issues with user created sockets.
|
||||
* Fixed several issues in libssh C++ wrapper.
|
||||
* Fixed several documentation issues.
|
||||
* Fixed channel exit-signal request.
|
||||
* Fixed X11 request screen number in messages.
|
||||
* Fixed several memory leaks.
|
||||
|
||||
version 0.6.3 (released 2014-03-04)
|
||||
* Fixed CVE-2014-0017.
|
||||
* Fixed memory leak with ecdsa signatures.
|
||||
|
||||
@@ -51,6 +51,7 @@ check_include_file(pty.h HAVE_PTY_H)
|
||||
check_include_file(termios.h HAVE_TERMIOS_H)
|
||||
check_include_file(unistd.h HAVE_UNISTD_H)
|
||||
check_include_file(util.h HAVE_UTIL_H)
|
||||
check_include_file(sys/time.h HAVE_SYS_TIME_H)
|
||||
|
||||
if (WIN32)
|
||||
check_include_files("winsock2.h;ws2tcpip.h;wspiapi.h" HAVE_WSPIAPI_H)
|
||||
|
||||
@@ -25,3 +25,6 @@ if (NOT CMAKE_BUILD_TYPE)
|
||||
"Choose the type of build, options are: None Debug Release RelWithDebInfo MinSizeRel."
|
||||
)
|
||||
endif (NOT CMAKE_BUILD_TYPE)
|
||||
|
||||
# Create the compile command database for clang by default
|
||||
set(CMAKE_EXPORT_COMPILE_COMMANDS ON)
|
||||
|
||||
@@ -2,10 +2,18 @@
|
||||
#
|
||||
# Adds a doxygen target that runs doxygen to generate the html
|
||||
# and optionally the LaTeX API documentation.
|
||||
# The doxygen target is added to the doc target as dependency.
|
||||
# The doxygen target is added to the doc target as a dependency.
|
||||
# i.e.: the API documentation is built with:
|
||||
# make doc
|
||||
#
|
||||
# USAGE: GLOBAL INSTALL
|
||||
#
|
||||
# Install it with:
|
||||
# cmake ./ && sudo make install
|
||||
# Add the following to the CMakeLists.txt of your project:
|
||||
# include(UseDoxygen OPTIONAL)
|
||||
# Optionally copy Doxyfile.in in the directory of CMakeLists.txt and edit it.
|
||||
#
|
||||
# USAGE: INCLUDE IN PROJECT
|
||||
#
|
||||
# set(CMAKE_MODULE_PATH ${CMAKE_CURRENT_SOURCE_DIR})
|
||||
@@ -13,88 +21,120 @@
|
||||
# Add the Doxyfile.in and UseDoxygen.cmake files to the projects source directory.
|
||||
#
|
||||
#
|
||||
# CONFIGURATION
|
||||
#
|
||||
# To configure Doxygen you can edit Doxyfile.in and set some variables in cmake.
|
||||
# Variables you may define are:
|
||||
# DOXYFILE_OUTPUT_DIR - Path where the Doxygen output is stored. Defaults to "doc".
|
||||
#
|
||||
# DOXYFILE_LATEX_DIR - Directory where the Doxygen LaTeX output is stored. Defaults to "latex".
|
||||
#
|
||||
# DOXYFILE_HTML_DIR - Directory where the Doxygen html output is stored. Defaults to "html".
|
||||
# DOXYFILE_SOURCE_DIR - Path where the Doxygen input files are.
|
||||
# Defaults to the current source directory.
|
||||
# DOXYFILE_EXTRA_SOURCES - Additional source diretories/files for Doxygen to scan.
|
||||
# The Paths should be in double quotes and separated by space. e.g.:
|
||||
# "${CMAKE_CURRENT_BINARY_DIR}/foo.c" "${CMAKE_CURRENT_BINARY_DIR}/bar/"
|
||||
#
|
||||
# DOXYFILE_OUTPUT_DIR - Path where the Doxygen output is stored.
|
||||
# Defaults to "${CMAKE_CURRENT_BINARY_DIR}/doc".
|
||||
#
|
||||
# DOXYFILE_LATEX - ON/OFF; Set to "ON" if you want the LaTeX documentation
|
||||
# to be built.
|
||||
# DOXYFILE_LATEX_DIR - Directory relative to DOXYFILE_OUTPUT_DIR where
|
||||
# the Doxygen LaTeX output is stored. Defaults to "latex".
|
||||
#
|
||||
# DOXYFILE_HTML_DIR - Directory relative to DOXYFILE_OUTPUT_DIR where
|
||||
# the Doxygen html output is stored. Defaults to "html".
|
||||
#
|
||||
|
||||
#
|
||||
# Copyright (c) 2009-2010 Tobias Rautenkranz <tobias@rautenkranz.ch>
|
||||
# Copyright (c) 2010 Andreas Schneider <asn@cryptomilk.org>
|
||||
# Copyright (c) 2009, 2010, 2011 Tobias Rautenkranz <tobias@rautenkranz.ch>
|
||||
#
|
||||
# Redistribution and use is allowed according to the terms of the New
|
||||
# BSD license.
|
||||
# For details see the accompanying COPYING-CMAKE-SCRIPTS file.
|
||||
#
|
||||
|
||||
macro(usedoxygen_set_default name value)
|
||||
if(NOT DEFINED "${name}")
|
||||
set("${name}" "${value}")
|
||||
endif()
|
||||
macro(usedoxygen_set_default name value type docstring)
|
||||
if(NOT DEFINED "${name}")
|
||||
set("${name}" "${value}" CACHE "${type}" "${docstring}")
|
||||
endif()
|
||||
endmacro()
|
||||
|
||||
find_package(Doxygen)
|
||||
|
||||
if(DOXYGEN_FOUND)
|
||||
find_file(DOXYFILE_IN
|
||||
NAMES
|
||||
doxy.config.in
|
||||
PATHS
|
||||
${CMAKE_CURRENT_SOURCE_DIR}
|
||||
${CMAKE_ROOT}/Modules/
|
||||
NO_DEFAULT_PATH)
|
||||
include(FindPackageHandleStandardArgs)
|
||||
find_package_handle_standard_args(DOXYFILE_IN DEFAULT_MSG "DOXYFILE_IN")
|
||||
find_file(DOXYFILE_IN "Doxyfile.in"
|
||||
PATHS "${CMAKE_CURRENT_SOURCE_DIR}" "${CMAKE_ROOT}/Modules/"
|
||||
NO_DEFAULT_PATH
|
||||
DOC "Path to the doxygen configuration template file")
|
||||
set(DOXYFILE "${CMAKE_CURRENT_BINARY_DIR}/Doxyfile")
|
||||
include(FindPackageHandleStandardArgs)
|
||||
find_package_handle_standard_args(DOXYFILE_IN DEFAULT_MSG "DOXYFILE_IN")
|
||||
endif()
|
||||
|
||||
if(DOXYGEN_FOUND AND DOXYFILE_IN_FOUND)
|
||||
add_custom_target(doxygen ${DOXYGEN_EXECUTABLE} ${CMAKE_CURRENT_BINARY_DIR}/doxy.config)
|
||||
usedoxygen_set_default(DOXYFILE_OUTPUT_DIR "${CMAKE_CURRENT_BINARY_DIR}/doc"
|
||||
PATH "Doxygen output directory")
|
||||
usedoxygen_set_default(DOXYFILE_HTML_DIR "html"
|
||||
STRING "Doxygen HTML output directory")
|
||||
usedoxygen_set_default(DOXYFILE_SOURCE_DIR "${CMAKE_CURRENT_SOURCE_DIR}"
|
||||
PATH "Input files source directory")
|
||||
usedoxygen_set_default(DOXYFILE_EXTRA_SOURCE_DIRS ""
|
||||
STRING "Additional source files/directories separated by space")
|
||||
set(DOXYFILE_SOURCE_DIRS "\"${DOXYFILE_SOURCE_DIR}\" ${DOXYFILE_EXTRA_SOURCES}")
|
||||
|
||||
usedoxygen_set_default(DOXYFILE_OUTPUT_DIR "${CMAKE_CURRENT_BINARY_DIR}")
|
||||
usedoxygen_set_default(DOXYFILE_HTML_DIR "html")
|
||||
usedoxygen_set_default(DOXYFILE_LATEX YES BOOL "Generate LaTeX API documentation" OFF)
|
||||
usedoxygen_set_default(DOXYFILE_LATEX_DIR "latex" STRING "LaTex output directory")
|
||||
|
||||
set_property(DIRECTORY APPEND PROPERTY
|
||||
ADDITIONAL_MAKE_CLEAN_FILES "${DOXYFILE_OUTPUT_DIR}/${DOXYFILE_HTML_DIR}")
|
||||
mark_as_advanced(DOXYFILE_OUTPUT_DIR DOXYFILE_HTML_DIR DOXYFILE_LATEX_DIR
|
||||
DOXYFILE_SOURCE_DIR DOXYFILE_EXTRA_SOURCE_DIRS DOXYFILE_IN)
|
||||
|
||||
set(DOXYFILE_LATEX FALSE)
|
||||
set(DOXYFILE_PDFLATEX FALSE)
|
||||
set(DOXYFILE_DOT FALSE)
|
||||
|
||||
#find_package(LATEX)
|
||||
#if(LATEX_COMPILER AND MAKEINDEX_COMPILER)
|
||||
# set(DOXYFILE_LATEX TRUE)
|
||||
# usedoxygen_set_default(DOXYFILE_LATEX_DIR "latex")
|
||||
#
|
||||
# set_property(DIRECTORY APPEND PROPERTY
|
||||
# ADDITIONAL_MAKE_CLEAN_FILES
|
||||
# "${DOXYFILE_OUTPUT_DIR}/${DOXYFILE_LATEX_DIR}")
|
||||
#
|
||||
# if(PDFLATEX_COMPILER)
|
||||
# set(DOXYFILE_PDFLATEX TRUE)
|
||||
# endif()
|
||||
# if(DOXYGEN_DOT_EXECUTABLE)
|
||||
# set(DOXYFILE_DOT TRUE)
|
||||
# endif()
|
||||
#
|
||||
# add_custom_command(TARGET doxygen
|
||||
# POST_BUILD
|
||||
# COMMAND ${CMAKE_MAKE_PROGRAM}
|
||||
# WORKING_DIRECTORY "${DOXYFILE_OUTPUT_DIR}/${DOXYFILE_LATEX_DIR}")
|
||||
#endif()
|
||||
set_property(DIRECTORY
|
||||
APPEND PROPERTY
|
||||
ADDITIONAL_MAKE_CLEAN_FILES
|
||||
"${DOXYFILE_OUTPUT_DIR}/${DOXYFILE_HTML_DIR}")
|
||||
|
||||
configure_file(${DOXYFILE_IN} ${CMAKE_CURRENT_BINARY_DIR}/doxy.config ESCAPE_QUOTES IMMEDIATE @ONLY)
|
||||
if (EXISTS ${CMAKE_CURRENT_SOURCE_DIR}/doxy.trac.in)
|
||||
configure_file(${CMAKE_CURRENT_SOURCE_DIR}/doxy.trac.in ${CMAKE_CURRENT_BINARY_DIR}/doxy.trac ESCAPE_QUOTES IMMEDIATE @ONLY)
|
||||
add_custom_target(doxygen-trac ${DOXYGEN_EXECUTABLE} ${CMAKE_CURRENT_BINARY_DIR}/doxy.trac)
|
||||
endif()
|
||||
add_custom_target(doxygen
|
||||
COMMAND "${DOXYGEN_EXECUTABLE}"
|
||||
"${DOXYFILE}"
|
||||
COMMENT "Writing documentation to ${DOXYFILE_OUTPUT_DIR}..."
|
||||
WORKING_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}")
|
||||
|
||||
get_target_property(DOC_TARGET doc TYPE)
|
||||
if(NOT DOC_TARGET)
|
||||
add_custom_target(doc)
|
||||
endif()
|
||||
set(DOXYFILE_DOT "NO")
|
||||
if(DOXYGEN_DOT_EXECUTABLE)
|
||||
set(DOXYFILE_DOT "YES")
|
||||
endif()
|
||||
|
||||
add_dependencies(doc doxygen)
|
||||
## LaTeX
|
||||
set(DOXYFILE_PDFLATEX "NO")
|
||||
|
||||
set_property(DIRECTORY APPEND PROPERTY
|
||||
ADDITIONAL_MAKE_CLEAN_FILES
|
||||
"${DOXYFILE_OUTPUT_DIR}/${DOXYFILE_LATEX_DIR}")
|
||||
|
||||
if(DOXYFILE_LATEX STREQUAL "ON")
|
||||
set(DOXYFILE_GENERATE_LATEX "YES")
|
||||
find_package(LATEX)
|
||||
find_program(DOXYFILE_MAKE make)
|
||||
mark_as_advanced(DOXYFILE_MAKE)
|
||||
if(LATEX_COMPILER AND MAKEINDEX_COMPILER AND DOXYFILE_MAKE)
|
||||
if(PDFLATEX_COMPILER)
|
||||
set(DOXYFILE_PDFLATEX "YES")
|
||||
endif()
|
||||
|
||||
add_custom_command(TARGET doxygen
|
||||
POST_BUILD
|
||||
COMMAND "${DOXYFILE_MAKE}"
|
||||
COMMENT "Running LaTeX for Doxygen documentation in ${DOXYFILE_OUTPUT_DIR}/${DOXYFILE_LATEX_DIR}..."
|
||||
WORKING_DIRECTORY "${DOXYFILE_OUTPUT_DIR}/${DOXYFILE_LATEX_DIR}")
|
||||
else()
|
||||
set(DOXYGEN_LATEX "NO")
|
||||
endif()
|
||||
else()
|
||||
set(DOXYFILE_GENERATE_LATEX "NO")
|
||||
endif()
|
||||
|
||||
|
||||
configure_file("${DOXYFILE_IN}" "${DOXYFILE}" @ONLY)
|
||||
|
||||
add_custom_target(doc)
|
||||
add_dependencies(doc doxygen)
|
||||
endif()
|
||||
|
||||
@@ -23,6 +23,9 @@
|
||||
/* Define to 1 if you have the <util.h> header file. */
|
||||
#cmakedefine HAVE_UTIL_H 1
|
||||
|
||||
/* Define to 1 if you have the <sys/time.h> header file. */
|
||||
#cmakedefine HAVE_SYS_TIME_H 1
|
||||
|
||||
/* Define to 1 if you have the <termios.h> header file. */
|
||||
#cmakedefine HAVE_TERMIOS_H 1
|
||||
|
||||
|
||||
@@ -285,7 +285,7 @@ int authenticate_kbdint(ssh_session session)
|
||||
{
|
||||
int rc;
|
||||
|
||||
rc = ssh_userauth_none(session, NULL, NULL);
|
||||
rc = ssh_userauth_none(session, NULL);
|
||||
return rc;
|
||||
}
|
||||
@endcode
|
||||
@@ -304,7 +304,7 @@ int test_several_auth_methods(ssh_session session)
|
||||
{
|
||||
int method, rc;
|
||||
|
||||
rc = ssh_userauth_none(session, NULL, NULL);
|
||||
rc = ssh_userauth_none(session, NULL);
|
||||
if (rc != SSH_AUTH_SUCCESS) {
|
||||
return rc;
|
||||
}
|
||||
|
||||
1546
doc/doxy.trac.in
1546
doc/doxy.trac.in
File diff suppressed because it is too large
Load Diff
@@ -443,11 +443,10 @@ 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.
|
||||
In these cases, SSH_REQUEST_DENIED is returned.
|
||||
|
||||
ssh_get_error() and ssh_get_error_code() take a ssh_session as a parameter.
|
||||
That's for thread safety, error messages that can be attached to a session
|
||||
aren't static anymore. Any error that happens during ssh_options_xxx()
|
||||
or ssh_connect() (i.e., outside of any session) can be retrieved by
|
||||
giving NULL as argument.
|
||||
For thread safety, errors are bound to ssh_session objects.
|
||||
As long as your ssh_session object is not NULL, you can retrieve the last error
|
||||
message and error code from the ssh_session using ssh_get_error() and
|
||||
ssh_get_error_code() respectively.
|
||||
|
||||
The SFTP subsystem has its own error codes, in addition to libssh ones.
|
||||
|
||||
|
||||
@@ -49,7 +49,7 @@ int hashbufin_add_cookie(ssh_session session, unsigned char *cookie);
|
||||
int hashbufout_add_cookie(ssh_session session);
|
||||
int generate_session_keys(ssh_session session);
|
||||
bignum make_string_bn(ssh_string string);
|
||||
void make_string_bn_inplace(ssh_string string, bignum bnout);
|
||||
ssh_string make_bignum_string(bignum num);
|
||||
|
||||
|
||||
#endif /* DH_H_ */
|
||||
|
||||
@@ -78,7 +78,7 @@
|
||||
/* libssh version */
|
||||
#define LIBSSH_VERSION_MAJOR 0
|
||||
#define LIBSSH_VERSION_MINOR 6
|
||||
#define LIBSSH_VERSION_MICRO 3
|
||||
#define LIBSSH_VERSION_MICRO 4
|
||||
|
||||
#define LIBSSH_VERSION_INT SSH_VERSION_INT(LIBSSH_VERSION_MAJOR, \
|
||||
LIBSSH_VERSION_MINOR, \
|
||||
@@ -534,6 +534,8 @@ LIBSSH_API int ssh_pki_export_pubkey_base64(const ssh_key key,
|
||||
LIBSSH_API int ssh_pki_export_pubkey_file(const ssh_key key,
|
||||
const char *filename);
|
||||
|
||||
LIBSSH_API const char *ssh_pki_key_ecdsa_name(const ssh_key key);
|
||||
|
||||
LIBSSH_API void ssh_print_hexa(const char *descr, const unsigned char *what, size_t len);
|
||||
LIBSSH_API int ssh_send_ignore (ssh_session session, const char *data);
|
||||
LIBSSH_API int ssh_send_debug (ssh_session session, const char *message, int always_display);
|
||||
|
||||
@@ -361,8 +361,8 @@ public:
|
||||
* @see ssh_channel_forward_accept
|
||||
* @see Session::listenForward
|
||||
*/
|
||||
Channel *acceptForward(int timeout_ms);
|
||||
/* acceptForward is implemented later in this file */
|
||||
inline Channel *acceptForward(int timeout_ms);
|
||||
/* implemented outside the class due Channel references */
|
||||
|
||||
void_throwable cancelForward(const char *address, int port){
|
||||
int err=ssh_forward_cancel(c_session, address, port);
|
||||
@@ -480,12 +480,30 @@ public:
|
||||
ssh_throw(err);
|
||||
return err;
|
||||
}
|
||||
int read(void *dest, size_t count, bool is_stderr=false){
|
||||
int read(void *dest, size_t count, bool is_stderr){
|
||||
int err;
|
||||
/* handle int overflow */
|
||||
if(count > 0x7fffffff)
|
||||
count = 0x7fffffff;
|
||||
err=ssh_channel_read(channel,dest,count,is_stderr);
|
||||
err=ssh_channel_read_timeout(channel,dest,count,is_stderr,-1);
|
||||
ssh_throw(err);
|
||||
return err;
|
||||
}
|
||||
int read(void *dest, size_t count, int timeout){
|
||||
int err;
|
||||
/* handle int overflow */
|
||||
if(count > 0x7fffffff)
|
||||
count = 0x7fffffff;
|
||||
err=ssh_channel_read_timeout(channel,dest,count,false,timeout);
|
||||
ssh_throw(err);
|
||||
return err;
|
||||
}
|
||||
int read(void *dest, size_t count, bool is_stderr=false, int timeout=-1){
|
||||
int err;
|
||||
/* handle int overflow */
|
||||
if(count > 0x7fffffff)
|
||||
count = 0x7fffffff;
|
||||
err=ssh_channel_read_timeout(channel,dest,count,is_stderr,timeout);
|
||||
ssh_throw(err);
|
||||
return err;
|
||||
}
|
||||
|
||||
@@ -34,6 +34,7 @@ void _ssh_pki_log(const char *function,
|
||||
const char *format, ...) PRINTF_ATTRIBUTE(2, 3);
|
||||
|
||||
int pki_key_ecdsa_nid_from_name(const char *name);
|
||||
const char *pki_key_ecdsa_nid_to_name(int nid);
|
||||
|
||||
/* SSH Key Functions */
|
||||
ssh_key pki_key_dup(const ssh_key key, int demote);
|
||||
|
||||
@@ -44,7 +44,8 @@ enum ssh_bind_options_e {
|
||||
SSH_BIND_OPTIONS_RSAKEY,
|
||||
SSH_BIND_OPTIONS_BANNER,
|
||||
SSH_BIND_OPTIONS_LOG_VERBOSITY,
|
||||
SSH_BIND_OPTIONS_LOG_VERBOSITY_STR
|
||||
SSH_BIND_OPTIONS_LOG_VERBOSITY_STR,
|
||||
SSH_BIND_OPTIONS_ECDSAKEY
|
||||
};
|
||||
|
||||
typedef struct ssh_bind_struct* ssh_bind;
|
||||
@@ -80,69 +81,6 @@ typedef struct ssh_bind_callbacks_struct *ssh_bind_callbacks;
|
||||
*/
|
||||
LIBSSH_API ssh_bind ssh_bind_new(void);
|
||||
|
||||
/**
|
||||
* @brief Set the options for the current SSH server bind.
|
||||
*
|
||||
* @param sshbind The ssh server bind to configure.
|
||||
*
|
||||
* @param type The option type to set. This could be one of the
|
||||
* following:
|
||||
*
|
||||
* - SSH_BIND_OPTIONS_BINDADDR
|
||||
* The ip address to bind (const char *).
|
||||
*
|
||||
* - SSH_BIND_OPTIONS_BINDPORT
|
||||
* The port to bind (unsigned int).
|
||||
*
|
||||
* - SSH_BIND_OPTIONS_BINDPORT_STR
|
||||
* The port to bind (const char *).
|
||||
*
|
||||
* - SSH_BIND_OPTIONS_HOSTKEY
|
||||
* This specifies the file containing the private host key used
|
||||
* by SSHv1. (const char *).
|
||||
*
|
||||
* - SSH_BIND_OPTIONS_DSAKEY
|
||||
* This specifies the file containing the private host dsa key
|
||||
* used by SSHv2. (const char *).
|
||||
*
|
||||
* - SSH_BIND_OPTIONS_RSAKEY
|
||||
* This specifies the file containing the private host dsa key
|
||||
* used by SSHv2. (const char *).
|
||||
*
|
||||
* - SSH_BIND_OPTIONS_BANNER
|
||||
* That the server banner (version string) for SSH.
|
||||
* (const char *).
|
||||
*
|
||||
* - SSH_BIND_OPTIONS_LOG_VERBOSITY
|
||||
* Set the session logging verbosity (int).\n
|
||||
* \n
|
||||
* The verbosity of the messages. Every log smaller or
|
||||
* equal to verbosity will be shown.
|
||||
* - SSH_LOG_NOLOG: No logging
|
||||
* - SSH_LOG_RARE: Rare conditions or warnings
|
||||
* - SSH_LOG_ENTRY: API-accessible entrypoints
|
||||
* - SSH_LOG_PACKET: Packet id and size
|
||||
* - SSH_LOG_FUNCTIONS: Function entering and leaving
|
||||
*
|
||||
* - SSH_BIND_OPTIONS_LOG_VERBOSITY_STR
|
||||
* Set the session logging verbosity (const char *).\n
|
||||
* \n
|
||||
* The verbosity of the messages. Every log smaller or
|
||||
* equal to verbosity will be shown.
|
||||
* - SSH_LOG_NOLOG: No logging
|
||||
* - SSH_LOG_RARE: Rare conditions or warnings
|
||||
* - SSH_LOG_ENTRY: API-accessible entrypoints
|
||||
* - SSH_LOG_PACKET: Packet id and size
|
||||
* - SSH_LOG_FUNCTIONS: Function entering and leaving
|
||||
* \n
|
||||
* See the corresponding numbers in libssh.h.
|
||||
*
|
||||
* @param value The value to set. This is a generic pointer and the
|
||||
* datatype which is used should be set according to the
|
||||
* type set.
|
||||
*
|
||||
* @returns SSH_OK on success, SSH_ERROR on invalid option or parameter.
|
||||
*/
|
||||
LIBSSH_API int ssh_bind_options_set(ssh_bind sshbind,
|
||||
enum ssh_bind_options_e type, const void *value);
|
||||
|
||||
|
||||
@@ -7,5 +7,7 @@ else()
|
||||
set(LIBSSH_INCLUDE_DIR @INCLUDE_INSTALL_DIR@)
|
||||
endif()
|
||||
|
||||
set(LIBSSH_LIRBARY @LIB_INSTALL_DIR@/libssh.so)
|
||||
set(LIBSSH_LIRBARIES @LIB_INSTALL_DIR@/libssh.so)
|
||||
set(LIBSSH_LIBRARY @LIB_INSTALL_DIR@/@LIBSSH_LIBRARY_NAME@)
|
||||
set(LIBSSH_LIBRARIES @LIB_INSTALL_DIR@/@LIBSSH_LIBRARY_NAME@)
|
||||
|
||||
set(LIBSSH_THREADS_LIBRARY @LIB_INSTALL_DIR@/@LIBSSH_THREADS_LIBRARY_NAME@)
|
||||
|
||||
@@ -254,7 +254,6 @@ int ssh_bind_listen(ssh_bind sshbind) {
|
||||
sshbind->rsa = NULL;
|
||||
return -1;
|
||||
}
|
||||
sshbind->bindfd = fd;
|
||||
|
||||
if (listen(fd, 10) < 0) {
|
||||
ssh_set_error(sshbind, SSH_FATAL,
|
||||
@@ -267,6 +266,8 @@ int ssh_bind_listen(ssh_bind sshbind) {
|
||||
sshbind->rsa = NULL;
|
||||
return -1;
|
||||
}
|
||||
|
||||
sshbind->bindfd = fd;
|
||||
} else {
|
||||
SSH_LOG(SSH_LOG_INFO, "Using app-provided bind socket");
|
||||
}
|
||||
|
||||
@@ -1238,7 +1238,8 @@ error:
|
||||
static int ssh_channel_waitwindow_termination(void *c){
|
||||
ssh_channel channel = (ssh_channel) c;
|
||||
if (channel->remote_window > 0 ||
|
||||
channel->session->session_state == SSH_SESSION_STATE_ERROR)
|
||||
channel->session->session_state == SSH_SESSION_STATE_ERROR ||
|
||||
channel->state == SSH_CHANNEL_STATE_CLOSED)
|
||||
return 1;
|
||||
else
|
||||
return 0;
|
||||
@@ -1345,7 +1346,8 @@ int channel_write_common(ssh_channel channel, const void *data,
|
||||
ssh_channel_waitwindow_termination,channel);
|
||||
if (rc == SSH_ERROR ||
|
||||
!ssh_channel_waitwindow_termination(channel) ||
|
||||
channel->session->session_state == SSH_SESSION_STATE_ERROR)
|
||||
channel->session->session_state == SSH_SESSION_STATE_ERROR ||
|
||||
channel->state == SSH_CHANNEL_STATE_CLOSED)
|
||||
goto out;
|
||||
continue;
|
||||
}
|
||||
@@ -3022,6 +3024,11 @@ static int ssh_channel_exit_status_termination(void *c){
|
||||
* (yet).
|
||||
* @warning This function may block until a timeout (or never)
|
||||
* if the other side is not willing to close the channel.
|
||||
*
|
||||
* If you're looking for an async handling of this register a callback for the
|
||||
* exit status.
|
||||
*
|
||||
* @see ssh_channel_exit_status_callback
|
||||
*/
|
||||
int ssh_channel_get_exit_status(ssh_channel channel) {
|
||||
int rc;
|
||||
@@ -3460,9 +3467,9 @@ error:
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Send an exit signal to remote process (as described in RFC 4254, section 6.10).
|
||||
* @brief Send an exit signal to remote process (RFC 4254, section 6.10).
|
||||
*
|
||||
* Sends a signal 'sig' to the remote process.
|
||||
* This sends the exit status of the remote process.
|
||||
* Note, that remote system may not support signals concept.
|
||||
* In such a case this request will be silently ignored.
|
||||
* Only SSH-v2 is supported (I'm not sure about SSH-v1).
|
||||
@@ -3540,7 +3547,7 @@ int ssh_channel_request_send_exit_signal(ssh_channel channel, const char *sig,
|
||||
goto error;
|
||||
}
|
||||
|
||||
rc = channel_request(channel, "signal", buffer, 0);
|
||||
rc = channel_request(channel, "exit-signal", buffer, 0);
|
||||
error:
|
||||
ssh_buffer_free(buffer);
|
||||
if(tmp)
|
||||
|
||||
@@ -60,12 +60,15 @@
|
||||
static void socket_callback_connected(int code, int errno_code, void *user){
|
||||
ssh_session session=(ssh_session)user;
|
||||
|
||||
if(session->session_state != SSH_SESSION_STATE_CONNECTING){
|
||||
if (session->session_state != SSH_SESSION_STATE_CONNECTING &&
|
||||
session->session_state != SSH_SESSION_STATE_SOCKET_CONNECTED)
|
||||
{
|
||||
ssh_set_error(session,SSH_FATAL, "Wrong state in socket_callback_connected : %d",
|
||||
session->session_state);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
SSH_LOG(SSH_LOG_RARE,"Socket connection callback: %d (%d)",code, errno_code);
|
||||
if(code == SSH_SOCKET_CONNECTED_OK)
|
||||
session->session_state=SSH_SESSION_STATE_SOCKET_CONNECTED;
|
||||
|
||||
@@ -128,7 +128,7 @@ static char *ssh_config_get_token(char **str) {
|
||||
c = ssh_config_get_cmd(str);
|
||||
|
||||
for (r = c; *c; c++) {
|
||||
if (isblank(*c)) {
|
||||
if (isblank(*c) || *c == '=') {
|
||||
*c = '\0';
|
||||
goto out;
|
||||
}
|
||||
|
||||
@@ -382,7 +382,15 @@ socket_t ssh_connect_host_nonblocking(ssh_session session, const char *host,
|
||||
continue;
|
||||
}
|
||||
|
||||
connect(s, itr->ai_addr, itr->ai_addrlen);
|
||||
rc = connect(s, itr->ai_addr, itr->ai_addrlen);
|
||||
if (rc == -1 && (errno != EINPROGRESS)) {
|
||||
ssh_set_error(session, SSH_FATAL,
|
||||
"Failed to connect: %s", strerror(errno));
|
||||
ssh_connect_socket_close(s);
|
||||
s = -1;
|
||||
continue;
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
9
src/dh.c
9
src/dh.c
@@ -407,6 +407,15 @@ bignum make_string_bn(ssh_string string){
|
||||
return bn;
|
||||
}
|
||||
|
||||
void make_string_bn_inplace(ssh_string string, bignum bnout) {
|
||||
unsigned int len = ssh_string_len(string);
|
||||
#ifdef HAVE_LIBGCRYPT
|
||||
#error "unsupported"
|
||||
#elif defined HAVE_LIBCRYPTO
|
||||
bignum_bin2bn(string->data, len, bnout);
|
||||
#endif
|
||||
}
|
||||
|
||||
ssh_string dh_get_e(ssh_session session) {
|
||||
return make_bignum_string(session->next_crypto->e);
|
||||
}
|
||||
|
||||
@@ -539,8 +539,12 @@ ssh_gssapi_creds ssh_gssapi_get_creds(ssh_session session){
|
||||
return (ssh_gssapi_creds)session->gssapi->client_creds;
|
||||
}
|
||||
|
||||
#endif /* SERVER */
|
||||
|
||||
/**
|
||||
* @brief Set the forwadable ticket to be given to the server for authentication.
|
||||
* Unlike ssh_gssapi_get_creds() this is called on the client side of an ssh
|
||||
* connection.
|
||||
*
|
||||
* @param[in] creds gssapi credentials handle.
|
||||
*/
|
||||
@@ -559,8 +563,6 @@ void ssh_gssapi_set_creds(ssh_session session, const ssh_gssapi_creds creds)
|
||||
session->gssapi->client.client_deleg_creds = (gss_cred_id_t)creds;
|
||||
}
|
||||
|
||||
#endif /* SERVER */
|
||||
|
||||
static int ssh_gssapi_send_auth_mic(ssh_session session, ssh_string *oid_set, int n_oid){
|
||||
ssh_string str;
|
||||
int rc;
|
||||
|
||||
@@ -73,7 +73,7 @@
|
||||
|
||||
#ifdef HAVE_ECDH
|
||||
#define ECDH "ecdh-sha2-nistp256,"
|
||||
#define HOSTKEYS "ecdsa-sha2-nistp256,ssh-rsa,ssh-dss"
|
||||
#define HOSTKEYS "ecdsa-sha2-nistp256,ecdsa-sha2-nistp384,ecdsa-sha2-nistp521,ssh-rsa,ssh-dss"
|
||||
#else
|
||||
#define HOSTKEYS "ssh-rsa,ssh-dss"
|
||||
#define ECDH ""
|
||||
@@ -315,7 +315,7 @@ SSH_PACKET_CALLBACK(ssh_packet_kexinit){
|
||||
for (i = 0; i < KEX_METHODS_SIZE; i++) {
|
||||
str = buffer_get_ssh_string(packet);
|
||||
if (str == NULL) {
|
||||
break;
|
||||
goto error;
|
||||
}
|
||||
|
||||
if (buffer_add_ssh_string(session->in_hashbuf, str) < 0) {
|
||||
@@ -350,6 +350,11 @@ SSH_PACKET_CALLBACK(ssh_packet_kexinit){
|
||||
error:
|
||||
ssh_string_free(str);
|
||||
for (i = 0; i < SSH_KEX_METHODS; i++) {
|
||||
if (server_kex) {
|
||||
session->next_crypto->client_kex.methods[i] = NULL;
|
||||
} else { /* client */
|
||||
session->next_crypto->server_kex.methods[i] = NULL;
|
||||
}
|
||||
SAFE_FREE(strings[i]);
|
||||
}
|
||||
|
||||
|
||||
@@ -19,11 +19,14 @@
|
||||
* MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#ifdef HAVE_SYS_TIME_H
|
||||
#include <sys/time.h>
|
||||
#endif
|
||||
|
||||
#include "libssh/priv.h"
|
||||
#include "libssh/session.h"
|
||||
@@ -78,9 +81,11 @@ static int alloc_key(struct ssh_cipher_struct *cipher) {
|
||||
}
|
||||
|
||||
void ssh_reseed(void){
|
||||
#ifndef _WIN32
|
||||
struct timeval tv;
|
||||
gettimeofday(&tv, NULL);
|
||||
RAND_add(&tv, sizeof(tv), 0.0);
|
||||
#endif
|
||||
}
|
||||
|
||||
SHACTX sha1_init(void) {
|
||||
@@ -202,7 +207,11 @@ void md5_final(unsigned char *md, MD5CTX c) {
|
||||
}
|
||||
|
||||
ssh_mac_ctx ssh_mac_ctx_init(enum ssh_mac_e type){
|
||||
ssh_mac_ctx ctx=malloc(sizeof(struct ssh_mac_ctx_struct));
|
||||
ssh_mac_ctx ctx = malloc(sizeof(struct ssh_mac_ctx_struct));
|
||||
if (ctx == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
ctx->mac_type=type;
|
||||
switch(type){
|
||||
case SSH_MAC_SHA1:
|
||||
|
||||
@@ -91,7 +91,11 @@ void md5_final(unsigned char *md, MD5CTX c) {
|
||||
}
|
||||
|
||||
ssh_mac_ctx ssh_mac_ctx_init(enum ssh_mac_e type){
|
||||
ssh_mac_ctx ctx=malloc(sizeof(struct ssh_mac_ctx_struct));
|
||||
ssh_mac_ctx ctx = malloc(sizeof(struct ssh_mac_ctx_struct));
|
||||
if (ctx == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
ctx->mac_type=type;
|
||||
switch(type){
|
||||
case SSH_MAC_SHA1:
|
||||
|
||||
@@ -508,8 +508,7 @@ void ssh_message_free(ssh_message msg){
|
||||
case SSH_REQUEST_AUTH:
|
||||
SAFE_FREE(msg->auth_request.username);
|
||||
if (msg->auth_request.password) {
|
||||
memset(msg->auth_request.password, 0,
|
||||
strlen(msg->auth_request.password));
|
||||
BURN_STRING(msg->auth_request.password);
|
||||
SAFE_FREE(msg->auth_request.password);
|
||||
}
|
||||
ssh_key_free(msg->auth_request.pubkey);
|
||||
@@ -1372,6 +1371,7 @@ int ssh_message_handle_channel_request(ssh_session session, ssh_channel channel,
|
||||
msg->channel_request.pxheight = ntohl(msg->channel_request.pxheight);
|
||||
msg->channel_request.modes = buffer_get_ssh_string(packet);
|
||||
if (msg->channel_request.modes == NULL) {
|
||||
msg->channel_request.TERM = NULL;
|
||||
SAFE_FREE(term_c);
|
||||
goto error;
|
||||
}
|
||||
@@ -1470,6 +1470,7 @@ int ssh_message_handle_channel_request(ssh_session session, ssh_channel channel,
|
||||
if (strcmp(request, "x11-req") == 0) {
|
||||
ssh_string auth_protocol = NULL;
|
||||
ssh_string auth_cookie = NULL;
|
||||
uint32_t screen_number;
|
||||
|
||||
buffer_get_u8(packet, &msg->channel_request.x11_single_connection);
|
||||
|
||||
@@ -1497,7 +1498,8 @@ int ssh_message_handle_channel_request(ssh_session session, ssh_channel channel,
|
||||
ssh_string_free(auth_protocol);
|
||||
ssh_string_free(auth_cookie);
|
||||
|
||||
buffer_get_u32(packet, &msg->channel_request.x11_screen_number);
|
||||
buffer_get_u32(packet, &screen_number);
|
||||
msg->channel_request.x11_screen_number = ntohl(screen_number);
|
||||
|
||||
goto end;
|
||||
}
|
||||
|
||||
150
src/options.c
150
src/options.c
@@ -512,7 +512,7 @@ int ssh_options_set(ssh_session session, enum ssh_options_e type,
|
||||
}
|
||||
session->opts.username = q;
|
||||
} else if (v[0] == '\0') {
|
||||
ssh_set_error_oom(session);
|
||||
ssh_set_error_invalid(session);
|
||||
return -1;
|
||||
} else { /* username provided */
|
||||
session->opts.username = strdup(value);
|
||||
@@ -531,7 +531,7 @@ int ssh_options_set(ssh_session session, enum ssh_options_e type,
|
||||
return -1;
|
||||
}
|
||||
} else if (v[0] == '\0') {
|
||||
ssh_set_error_oom(session);
|
||||
ssh_set_error_invalid(session);
|
||||
return -1;
|
||||
} else {
|
||||
session->opts.sshdir = ssh_path_expand_tilde(v);
|
||||
@@ -1303,65 +1303,89 @@ static int ssh_bind_options_set_algo(ssh_bind sshbind, int algo,
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int ssh_bind_set_key(ssh_bind sshbind, char **key_loc,
|
||||
const void *value) {
|
||||
if (value == NULL) {
|
||||
ssh_set_error_invalid(sshbind);
|
||||
return -1;
|
||||
} else {
|
||||
SAFE_FREE(*key_loc);
|
||||
*key_loc = strdup(value);
|
||||
if (*key_loc == NULL) {
|
||||
ssh_set_error_oom(sshbind);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief This function can set all possible ssh bind options.
|
||||
* @brief Set options for an SSH server bind.
|
||||
*
|
||||
* @param sshbind An allocated ssh bind structure.
|
||||
* @param sshbind The ssh server bind to configure.
|
||||
*
|
||||
* @param type The option type to set. This could be one of the
|
||||
* @param type The option type to set. This should be one of the
|
||||
* following:
|
||||
*
|
||||
* SSH_BIND_OPTIONS_LOG_VERBOSITY:
|
||||
* Set the session logging verbosity (integer).
|
||||
*
|
||||
* The verbosity of the messages. Every log smaller or
|
||||
* equal to verbosity will be shown.
|
||||
* SSH_LOG_NOLOG: No logging
|
||||
* SSH_LOG_RARE: Rare conditions or warnings
|
||||
* SSH_LOG_ENTRY: API-accessible entrypoints
|
||||
* SSH_LOG_PACKET: Packet id and size
|
||||
* SSH_LOG_FUNCTIONS: Function entering and leaving
|
||||
*
|
||||
* SSH_BIND_OPTIONS_LOG_VERBOSITY_STR:
|
||||
* Set the session logging verbosity (integer).
|
||||
*
|
||||
* The verbosity of the messages. Every log smaller or
|
||||
* equal to verbosity will be shown.
|
||||
* SSH_LOG_NOLOG: No logging
|
||||
* SSH_LOG_RARE: Rare conditions or warnings
|
||||
* SSH_LOG_ENTRY: API-accessible entrypoints
|
||||
* SSH_LOG_PACKET: Packet id and size
|
||||
* SSH_LOG_FUNCTIONS: Function entering and leaving
|
||||
*
|
||||
* SSH_BIND_OPTIONS_BINDADDR:
|
||||
* Set the bind address.
|
||||
*
|
||||
* SSH_BIND_OPTIONS_BINDPORT:
|
||||
* Set the bind port, default is 22.
|
||||
*
|
||||
* SSH_BIND_OPTIONS_HOSTKEY:
|
||||
* - SSH_BIND_OPTIONS_HOSTKEY:
|
||||
* Set the server public key type: ssh-rsa or ssh-dss
|
||||
* (string).
|
||||
* (const char *).
|
||||
*
|
||||
* SSH_BIND_OPTIONS_DSAKEY:
|
||||
* Set the path to the dsa ssh host key (string).
|
||||
* - SSH_BIND_OPTIONS_BINDADDR:
|
||||
* Set the IP address to bind (const char *).
|
||||
*
|
||||
* SSH_BIND_OPTIONS_RSAKEY:
|
||||
* Set the path to the ssh host rsa key (string).
|
||||
* - SSH_BIND_OPTIONS_BINDPORT:
|
||||
* Set the port to bind (unsigned int *).
|
||||
*
|
||||
* SSH_BIND_OPTIONS_BANNER:
|
||||
* Set the server banner sent to clients (string).
|
||||
* - SSH_BIND_OPTIONS_BINDPORT_STR:
|
||||
* Set the port to bind (const char *).
|
||||
*
|
||||
* - SSH_BIND_OPTIONS_LOG_VERBOSITY:
|
||||
* Set the session logging verbosity (int *).
|
||||
* The logging verbosity should have one of the
|
||||
* following values, which are listed in order
|
||||
* of increasing verbosity. Every log message
|
||||
* with verbosity less than or equal to the
|
||||
* logging verbosity will be shown.
|
||||
* - SSH_LOG_NOLOG: No logging
|
||||
* - SSH_LOG_RARE: Rare conditions or warnings
|
||||
* - SSH_LOG_ENTRY: API-accessible entrypoints
|
||||
* - SSH_LOG_PACKET: Packet id and size
|
||||
* - SSH_LOG_FUNCTIONS: Function entering and leaving
|
||||
*
|
||||
* - SSH_BIND_OPTIONS_LOG_VERBOSITY_STR:
|
||||
* Set the session logging verbosity via a
|
||||
* string that will be converted to a numerical
|
||||
* value (e.g. "3") and interpreted according
|
||||
* to the values of
|
||||
* SSH_BIND_OPTIONS_LOG_VERBOSITY above (const
|
||||
* char *).
|
||||
*
|
||||
* - SSH_BIND_OPTIONS_DSAKEY:
|
||||
* Set the path to the ssh host dsa key, SSHv2
|
||||
* only (const char *).
|
||||
*
|
||||
* - SSH_BIND_OPTIONS_RSAKEY:
|
||||
* Set the path to the ssh host rsa key, SSHv2
|
||||
* only (const char *).
|
||||
*
|
||||
* - SSH_BIND_OPTIONS_ECDSAKEY:
|
||||
* Set the path to the ssh host ecdsa key,
|
||||
* SSHv2 only (const char *).
|
||||
*
|
||||
* - SSH_BIND_OPTIONS_BANNER:
|
||||
* Set the server banner sent to clients (const char *).
|
||||
*
|
||||
* @param value The value to set. This is a generic pointer and the
|
||||
* datatype which is used should be set according to the
|
||||
* type set.
|
||||
* datatype which should be used is described at the
|
||||
* corresponding value of type above.
|
||||
*
|
||||
* @return 0 on success, < 0 on error.
|
||||
* @return 0 on success, < 0 on error, invalid option, or parameter.
|
||||
*/
|
||||
int ssh_bind_options_set(ssh_bind sshbind, enum ssh_bind_options_e type,
|
||||
const void *value) {
|
||||
char *p, *q;
|
||||
int i;
|
||||
int i, rc;
|
||||
|
||||
if (sshbind == NULL) {
|
||||
return -1;
|
||||
@@ -1445,31 +1469,23 @@ int ssh_bind_options_set(ssh_bind sshbind, enum ssh_bind_options_e type,
|
||||
}
|
||||
break;
|
||||
case SSH_BIND_OPTIONS_DSAKEY:
|
||||
if (value == NULL) {
|
||||
ssh_set_error_invalid(sshbind);
|
||||
return -1;
|
||||
} else {
|
||||
SAFE_FREE(sshbind->dsakey);
|
||||
sshbind->dsakey = strdup(value);
|
||||
if (sshbind->dsakey == NULL) {
|
||||
ssh_set_error_oom(sshbind);
|
||||
return -1;
|
||||
rc = ssh_bind_set_key(sshbind, &sshbind->dsakey, value);
|
||||
if (rc < 0) {
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
break;
|
||||
break;
|
||||
case SSH_BIND_OPTIONS_RSAKEY:
|
||||
if (value == NULL) {
|
||||
ssh_set_error_invalid(sshbind);
|
||||
return -1;
|
||||
} else {
|
||||
SAFE_FREE(sshbind->rsakey);
|
||||
sshbind->rsakey = strdup(value);
|
||||
if (sshbind->rsakey == NULL) {
|
||||
ssh_set_error_oom(sshbind);
|
||||
return -1;
|
||||
rc = ssh_bind_set_key(sshbind, &sshbind->rsakey, value);
|
||||
if (rc < 0) {
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
break;
|
||||
break;
|
||||
case SSH_BIND_OPTIONS_ECDSAKEY:
|
||||
rc = ssh_bind_set_key(sshbind, &sshbind->ecdsakey, value);
|
||||
if (rc < 0) {
|
||||
return -1;
|
||||
}
|
||||
break;
|
||||
case SSH_BIND_OPTIONS_BANNER:
|
||||
if (value == NULL) {
|
||||
ssh_set_error_invalid(sshbind);
|
||||
|
||||
17
src/packet.c
17
src/packet.c
@@ -504,11 +504,13 @@ static int packet_send2(ssh_session session) {
|
||||
session->current_crypto->out_cipher->blocksize : 8);
|
||||
uint32_t currentlen = buffer_get_rest_len(session->out_buffer);
|
||||
unsigned char *hmac = NULL;
|
||||
char padstring[32] = {0};
|
||||
char padstring[32] = { 0 };
|
||||
int rc = SSH_ERROR;
|
||||
uint32_t finallen,payloadsize,compsize;
|
||||
uint8_t padding;
|
||||
|
||||
uint8_t header[sizeof(padding) + sizeof(finallen)] = { 0 };
|
||||
|
||||
payloadsize = currentlen;
|
||||
#ifdef WITH_ZLIB
|
||||
if (session->current_crypto
|
||||
@@ -528,19 +530,18 @@ static int packet_send2(ssh_session session) {
|
||||
|
||||
if (session->current_crypto) {
|
||||
ssh_get_random(padstring, padding, 0);
|
||||
} else {
|
||||
memset(padstring,0,padding);
|
||||
}
|
||||
|
||||
finallen = htonl(currentlen + padding + 1);
|
||||
|
||||
if (buffer_prepend_data(session->out_buffer, &padding, sizeof(uint8_t)) < 0) {
|
||||
memcpy(&header[0], &finallen, sizeof(finallen));
|
||||
header[sizeof(finallen)] = padding;
|
||||
rc = buffer_prepend_data(session->out_buffer, &header, sizeof(header));
|
||||
if (rc < 0) {
|
||||
goto error;
|
||||
}
|
||||
if (buffer_prepend_data(session->out_buffer, &finallen, sizeof(uint32_t)) < 0) {
|
||||
goto error;
|
||||
}
|
||||
if (buffer_add_data(session->out_buffer, padstring, padding) < 0) {
|
||||
rc = buffer_add_data(session->out_buffer, padstring, padding);
|
||||
if (rc < 0) {
|
||||
goto error;
|
||||
}
|
||||
#ifdef WITH_PCAP
|
||||
|
||||
@@ -43,29 +43,35 @@
|
||||
* @brief Handle a SSH_DISCONNECT packet.
|
||||
*/
|
||||
SSH_PACKET_CALLBACK(ssh_packet_disconnect_callback){
|
||||
uint32_t code;
|
||||
char *error=NULL;
|
||||
ssh_string error_s;
|
||||
(void)user;
|
||||
(void)type;
|
||||
buffer_get_u32(packet, &code);
|
||||
int rc;
|
||||
uint32_t code = 0;
|
||||
char *error = NULL;
|
||||
ssh_string error_s;
|
||||
(void)user;
|
||||
(void)type;
|
||||
|
||||
rc = buffer_get_u32(packet, &code);
|
||||
if (rc != 0) {
|
||||
code = ntohl(code);
|
||||
}
|
||||
|
||||
error_s = buffer_get_ssh_string(packet);
|
||||
if (error_s != NULL) {
|
||||
error = ssh_string_to_char(error_s);
|
||||
ssh_string_free(error_s);
|
||||
}
|
||||
SSH_LOG(SSH_LOG_PACKET, "Received SSH_MSG_DISCONNECT %d:%s",code,
|
||||
error != NULL ? error : "no error");
|
||||
SSH_LOG(SSH_LOG_PACKET, "Received SSH_MSG_DISCONNECT %d:%s",
|
||||
code, error != NULL ? error : "no error");
|
||||
ssh_set_error(session, SSH_FATAL,
|
||||
"Received SSH_MSG_DISCONNECT: %d:%s",code,
|
||||
error != NULL ? error : "no error");
|
||||
"Received SSH_MSG_DISCONNECT: %d:%s",
|
||||
code, error != NULL ? error : "no error");
|
||||
SAFE_FREE(error);
|
||||
|
||||
ssh_socket_close(session->socket);
|
||||
session->alive = 0;
|
||||
session->session_state= SSH_SESSION_STATE_ERROR;
|
||||
/* TODO: handle a graceful disconnect */
|
||||
return SSH_PACKET_USED;
|
||||
session->session_state = SSH_SESSION_STATE_ERROR;
|
||||
/* TODO: handle a graceful disconnect */
|
||||
return SSH_PACKET_USED;
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
82
src/pki.c
82
src/pki.c
@@ -98,6 +98,25 @@ enum ssh_keytypes_e pki_privatekey_type_from_string(const char *privkey) {
|
||||
return SSH_KEYTYPE_UNKNOWN;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief returns the ECDSA key name ("ecdsa-sha2-nistp256" for example)
|
||||
*
|
||||
* @param[in] key the ssh_key whose ECDSA name to get
|
||||
*
|
||||
* @returns the ECDSA key name ("ecdsa-sha2-nistp256" for example)
|
||||
*
|
||||
* @returns "unknown" if the ECDSA key name is not known
|
||||
*/
|
||||
const char *ssh_pki_key_ecdsa_name(const ssh_key key)
|
||||
{
|
||||
#ifdef HAVE_OPENSSL_ECC /* FIXME Better ECC check needed */
|
||||
return pki_key_ecdsa_nid_to_name(key->ecdsa_nid);
|
||||
#else
|
||||
(void) key; /* unused */
|
||||
return NULL;
|
||||
#endif
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief creates a new empty SSH key
|
||||
* @returns an empty ssh_key handle, or NULL on error.
|
||||
@@ -724,6 +743,9 @@ static int pki_import_pubkey_buffer(ssh_buffer buffer,
|
||||
if (rc < 0) {
|
||||
goto fail;
|
||||
}
|
||||
|
||||
/* Update key type */
|
||||
key->type_c = ssh_pki_key_ecdsa_name(key);
|
||||
}
|
||||
break;
|
||||
#endif
|
||||
@@ -980,8 +1002,12 @@ int ssh_pki_generate(enum ssh_keytypes_e type, int parameter,
|
||||
case SSH_KEYTYPE_ECDSA:
|
||||
#ifdef HAVE_ECC
|
||||
rc = pki_key_generate_ecdsa(key, parameter);
|
||||
if(rc == SSH_ERROR)
|
||||
if (rc == SSH_ERROR) {
|
||||
goto error;
|
||||
}
|
||||
|
||||
/* Update key type */
|
||||
key->type_c = ssh_pki_key_ecdsa_name(key);
|
||||
break;
|
||||
#endif
|
||||
case SSH_KEYTYPE_UNKNOWN:
|
||||
@@ -1299,6 +1325,11 @@ int ssh_pki_signature_verify_blob(ssh_session session,
|
||||
|
||||
evp(key->ecdsa_nid, digest, dlen, ehash, &elen);
|
||||
|
||||
#ifdef DEBUG_CRYPTO
|
||||
ssh_print_hexa("Hash to be verified with ecdsa",
|
||||
ehash, elen);
|
||||
#endif
|
||||
|
||||
rc = pki_signature_verify(session,
|
||||
sig,
|
||||
key,
|
||||
@@ -1365,6 +1396,10 @@ ssh_string ssh_pki_do_sign(ssh_session session,
|
||||
evp_update(ctx, buffer_get_rest(sigbuf), buffer_get_rest_len(sigbuf));
|
||||
evp_final(ctx, ehash, &elen);
|
||||
|
||||
#ifdef DEBUG_CRYPTO
|
||||
ssh_print_hexa("Hash being signed", ehash, elen);
|
||||
#endif
|
||||
|
||||
sig = pki_do_sign(privkey, ehash, elen);
|
||||
#endif
|
||||
} else {
|
||||
@@ -1458,10 +1493,8 @@ ssh_string ssh_srv_pki_do_sign_sessionid(ssh_session session,
|
||||
const ssh_key privkey)
|
||||
{
|
||||
struct ssh_crypto_struct *crypto;
|
||||
unsigned char hash[SHA_DIGEST_LEN] = {0};
|
||||
ssh_signature sig;
|
||||
ssh_string sig_blob;
|
||||
SHACTX ctx;
|
||||
int rc;
|
||||
|
||||
if (session == NULL || privkey == NULL || !ssh_key_is_private(privkey)) {
|
||||
@@ -1470,24 +1503,47 @@ ssh_string ssh_srv_pki_do_sign_sessionid(ssh_session session,
|
||||
crypto = session->next_crypto ? session->next_crypto :
|
||||
session->current_crypto;
|
||||
|
||||
ctx = sha1_init();
|
||||
if (ctx == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
if (crypto->secret_hash == NULL){
|
||||
ssh_set_error(session,SSH_FATAL,"Missing secret_hash");
|
||||
return NULL;
|
||||
}
|
||||
sha1_update(ctx, crypto->secret_hash, crypto->digest_len);
|
||||
sha1_final(hash, ctx);
|
||||
|
||||
if (privkey->type == SSH_KEYTYPE_ECDSA) {
|
||||
#ifdef HAVE_ECC
|
||||
unsigned char ehash[EVP_DIGEST_LEN] = {0};
|
||||
uint32_t elen;
|
||||
|
||||
evp(privkey->ecdsa_nid, crypto->secret_hash, crypto->digest_len,
|
||||
ehash, &elen);
|
||||
|
||||
#ifdef DEBUG_CRYPTO
|
||||
ssh_print_hexa("Hash being signed", hash, SHA_DIGEST_LEN);
|
||||
ssh_print_hexa("Hash being signed", ehash, elen);
|
||||
#endif
|
||||
|
||||
sig = pki_do_sign_sessionid(privkey, hash, SHA_DIGEST_LEN);
|
||||
if (sig == NULL) {
|
||||
return NULL;
|
||||
sig = pki_do_sign_sessionid(privkey, ehash, elen);
|
||||
if (sig == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
#endif
|
||||
} else {
|
||||
unsigned char hash[SHA_DIGEST_LEN] = {0};
|
||||
SHACTX ctx;
|
||||
|
||||
ctx = sha1_init();
|
||||
if (ctx == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
sha1_update(ctx, crypto->secret_hash, crypto->digest_len);
|
||||
sha1_final(hash, ctx);
|
||||
|
||||
#ifdef DEBUG_CRYPTO
|
||||
ssh_print_hexa("Hash being signed", hash, SHA_DIGEST_LEN);
|
||||
#endif
|
||||
|
||||
sig = pki_do_sign_sessionid(privkey, hash, SHA_DIGEST_LEN);
|
||||
if (sig == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
rc = ssh_pki_export_signature_blob(sig, &sig_blob);
|
||||
|
||||
@@ -89,7 +89,7 @@ static int pki_key_ecdsa_to_nid(EC_KEY *k)
|
||||
return -1;
|
||||
}
|
||||
|
||||
static const char *pki_key_ecdsa_nid_to_name(int nid)
|
||||
const char *pki_key_ecdsa_nid_to_name(int nid)
|
||||
{
|
||||
switch (nid) {
|
||||
case NID_X9_62_prime256v1:
|
||||
@@ -345,13 +345,13 @@ ssh_key pki_key_dup(const ssh_key key, int demote)
|
||||
break;
|
||||
case SSH_KEYTYPE_ECDSA:
|
||||
#ifdef HAVE_OPENSSL_ECC
|
||||
new->ecdsa_nid = key->ecdsa_nid;
|
||||
|
||||
/* privkey -> pubkey */
|
||||
if (demote && ssh_key_is_private(key)) {
|
||||
const EC_POINT *p;
|
||||
int ok;
|
||||
|
||||
new->ecdsa_nid = key->ecdsa_nid;
|
||||
|
||||
new->ecdsa = EC_KEY_new_by_curve_name(key->ecdsa_nid);
|
||||
if (new->ecdsa == NULL) {
|
||||
goto fail;
|
||||
@@ -383,10 +383,20 @@ fail:
|
||||
}
|
||||
|
||||
int pki_key_generate_rsa(ssh_key key, int parameter){
|
||||
key->rsa = RSA_generate_key(parameter, 65537, NULL, NULL);
|
||||
if(key->rsa == NULL)
|
||||
return SSH_ERROR;
|
||||
return SSH_OK;
|
||||
BIGNUM *e;
|
||||
int rc;
|
||||
|
||||
e = BN_new();
|
||||
key->rsa = RSA_new();
|
||||
|
||||
BN_set_word(e, 65537);
|
||||
rc = RSA_generate_key_ex(key->rsa, parameter, e, NULL);
|
||||
|
||||
BN_free(e);
|
||||
|
||||
if (rc == -1 || key->rsa == NULL)
|
||||
return SSH_ERROR;
|
||||
return SSH_OK;
|
||||
}
|
||||
|
||||
int pki_key_generate_dss(ssh_key key, int parameter){
|
||||
@@ -1223,9 +1233,15 @@ static ssh_signature pki_signature_from_rsa_blob(const ssh_key pubkey,
|
||||
char *blob_padded_data;
|
||||
ssh_string sig_blob_padded;
|
||||
|
||||
size_t rsalen = 0;
|
||||
size_t len = ssh_string_len(sig_blob);
|
||||
size_t rsalen= RSA_size(pubkey->rsa);
|
||||
|
||||
if (pubkey->rsa == NULL) {
|
||||
ssh_pki_log("Pubkey RSA field NULL");
|
||||
goto errout;
|
||||
}
|
||||
|
||||
rsalen = RSA_size(pubkey->rsa);
|
||||
if (len > rsalen) {
|
||||
ssh_pki_log("Signature is too big: %lu > %lu",
|
||||
(unsigned long)len, (unsigned long)rsalen);
|
||||
@@ -1381,7 +1397,7 @@ ssh_signature pki_signature_from_blob(const ssh_key pubkey,
|
||||
ssh_print_hexa("r", ssh_string_data(r), ssh_string_len(r));
|
||||
#endif
|
||||
|
||||
sig->ecdsa_sig->r = make_string_bn(r);
|
||||
make_string_bn_inplace(r, sig->ecdsa_sig->r);
|
||||
ssh_string_burn(r);
|
||||
ssh_string_free(r);
|
||||
if (sig->ecdsa_sig->r == NULL) {
|
||||
@@ -1402,7 +1418,7 @@ ssh_signature pki_signature_from_blob(const ssh_key pubkey,
|
||||
ssh_print_hexa("s", ssh_string_data(s), ssh_string_len(s));
|
||||
#endif
|
||||
|
||||
sig->ecdsa_sig->s = make_string_bn(s);
|
||||
make_string_bn_inplace(s, sig->ecdsa_sig->s);
|
||||
ssh_string_burn(s);
|
||||
ssh_string_free(s);
|
||||
if (sig->ecdsa_sig->s == NULL) {
|
||||
|
||||
@@ -1657,6 +1657,7 @@ ssh_signature pki_do_sign_sessionid(const ssh_key key,
|
||||
return NULL;
|
||||
}
|
||||
sig->type = key->type;
|
||||
sig->type_c = key->type_c;
|
||||
|
||||
switch(key->type) {
|
||||
case SSH_KEYTYPE_DSS:
|
||||
|
||||
@@ -217,6 +217,7 @@ int ssh_get_key_params(ssh_session session, ssh_key *privkey){
|
||||
*privkey = session->srv.ecdsa_key;
|
||||
break;
|
||||
case SSH_KEYTYPE_UNKNOWN:
|
||||
default:
|
||||
*privkey = NULL;
|
||||
}
|
||||
|
||||
|
||||
@@ -226,7 +226,11 @@ void ssh_free(ssh_session session) {
|
||||
#endif /* _WIN32 */
|
||||
|
||||
ssh_key_free(session->srv.dsa_key);
|
||||
session->srv.dsa_key = NULL;
|
||||
ssh_key_free(session->srv.rsa_key);
|
||||
session->srv.rsa_key = NULL;
|
||||
ssh_key_free(session->srv.ecdsa_key);
|
||||
session->srv.ecdsa_key = NULL;
|
||||
|
||||
if (session->ssh_message_list) {
|
||||
ssh_message msg;
|
||||
@@ -261,6 +265,7 @@ void ssh_free(ssh_session session) {
|
||||
SAFE_FREE(session->banner);
|
||||
|
||||
SAFE_FREE(session->opts.bindaddr);
|
||||
SAFE_FREE(session->opts.custombanner);
|
||||
SAFE_FREE(session->opts.username);
|
||||
SAFE_FREE(session->opts.host);
|
||||
SAFE_FREE(session->opts.sshdir);
|
||||
@@ -275,7 +280,7 @@ void ssh_free(ssh_session session) {
|
||||
}
|
||||
}
|
||||
|
||||
/* burn connection, it could hang sensitive datas */
|
||||
/* burn connection, it could contain sensitive data */
|
||||
BURN_BUFFER(session, sizeof(struct ssh_session_struct));
|
||||
SAFE_FREE(session);
|
||||
}
|
||||
|
||||
@@ -235,10 +235,11 @@ struct ssh_string_struct *ssh_string_copy(struct ssh_string_struct *s) {
|
||||
* @param[in] s The string to burn.
|
||||
*/
|
||||
void ssh_string_burn(struct ssh_string_struct *s) {
|
||||
if (s == NULL) {
|
||||
return;
|
||||
}
|
||||
memset(s->data, 'X', ssh_string_len(s));
|
||||
if (s == NULL || s->size == 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
BURN_BUFFER(s->data, ssh_string_len(s));
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -53,73 +53,75 @@ include_directories(
|
||||
${LIBSSH_THREADS_PRIVATE_INCLUDE_DIRS}
|
||||
)
|
||||
|
||||
add_library(${LIBSSH_THREADS_SHARED_LIBRARY} SHARED ${libssh_threads_SRCS})
|
||||
if (libssh_threads_SRCS)
|
||||
add_library(${LIBSSH_THREADS_SHARED_LIBRARY} SHARED ${libssh_threads_SRCS})
|
||||
|
||||
target_link_libraries(${LIBSSH_THREADS_SHARED_LIBRARY} ${LIBSSH_THREADS_LINK_LIBRARIES})
|
||||
target_link_libraries(${LIBSSH_THREADS_SHARED_LIBRARY} ${LIBSSH_THREADS_LINK_LIBRARIES})
|
||||
|
||||
set_target_properties(
|
||||
${LIBSSH_THREADS_SHARED_LIBRARY}
|
||||
PROPERTIES
|
||||
VERSION
|
||||
${LIBRARY_VERSION}
|
||||
SOVERSION
|
||||
${LIBRARY_SOVERSION}
|
||||
OUTPUT_NAME
|
||||
ssh_threads
|
||||
DEFINE_SYMBOL
|
||||
LIBSSH_EXPORTS
|
||||
)
|
||||
|
||||
if (WITH_VISIBILITY_HIDDEN)
|
||||
set_target_properties(${LIBSSH_THREADS_SHARED_LIBRARY} PROPERTIES COMPILE_FLAGS "-fvisibility=hidden")
|
||||
endif (WITH_VISIBILITY_HIDDEN)
|
||||
|
||||
install(
|
||||
TARGETS
|
||||
${LIBSSH_THREADS_SHARED_LIBRARY}
|
||||
RUNTIME DESTINATION ${BIN_INSTALL_DIR}
|
||||
LIBRARY DESTINATION ${LIB_INSTALL_DIR}
|
||||
ARCHIVE DESTINATION ${LIB_INSTALL_DIR}
|
||||
COMPONENT libraries
|
||||
)
|
||||
|
||||
if (WITH_STATIC_LIB)
|
||||
add_library(${LIBSSH_THREADS_STATIC_LIBRARY} STATIC ${libssh_threads_SRCS})
|
||||
|
||||
if (MSVC)
|
||||
set(OUTPUT_SUFFIX static)
|
||||
else (MSVC)
|
||||
set(OUTPUT_SUFFIX )
|
||||
endif (MSVC)
|
||||
|
||||
set_target_properties(
|
||||
${LIBSSH_THREADS_STATIC_LIBRARY}
|
||||
PROPERTIES
|
||||
VERSION
|
||||
${LIBRARY_VERSION}
|
||||
SOVERSION
|
||||
${LIBRARY_SOVERSION}
|
||||
OUTPUT_NAME
|
||||
ssh_threads
|
||||
ARCHIVE_OUTPUT_DIRECTORY
|
||||
${CMAKE_CURRENT_BINARY_DIR}/${OUTPUT_SUFFIX}
|
||||
)
|
||||
|
||||
if (WIN32)
|
||||
set_target_properties(
|
||||
${LIBSSH_THREADS_STATIC_LIBRARY}
|
||||
PROPERTIES
|
||||
COMPILE_FLAGS
|
||||
"-DLIBSSH_STATIC"
|
||||
)
|
||||
endif (WIN32)
|
||||
${LIBSSH_THREADS_SHARED_LIBRARY}
|
||||
PROPERTIES
|
||||
VERSION
|
||||
${LIBRARY_VERSION}
|
||||
SOVERSION
|
||||
${LIBRARY_SOVERSION}
|
||||
OUTPUT_NAME
|
||||
ssh_threads
|
||||
DEFINE_SYMBOL
|
||||
LIBSSH_EXPORTS
|
||||
)
|
||||
|
||||
install(
|
||||
TARGETS
|
||||
${LIBSSH_THREADS_STATIC_LIBRARY}
|
||||
DESTINATION
|
||||
${LIB_INSTALL_DIR}/${OUTPUT_SUFFIX}
|
||||
COMPONENT
|
||||
libraries
|
||||
)
|
||||
endif (WITH_STATIC_LIB)
|
||||
if (WITH_VISIBILITY_HIDDEN)
|
||||
set_target_properties(${LIBSSH_THREADS_SHARED_LIBRARY} PROPERTIES COMPILE_FLAGS "-fvisibility=hidden")
|
||||
endif (WITH_VISIBILITY_HIDDEN)
|
||||
|
||||
install(
|
||||
TARGETS
|
||||
${LIBSSH_THREADS_SHARED_LIBRARY}
|
||||
RUNTIME DESTINATION ${BIN_INSTALL_DIR}
|
||||
LIBRARY DESTINATION ${LIB_INSTALL_DIR}
|
||||
ARCHIVE DESTINATION ${LIB_INSTALL_DIR}
|
||||
COMPONENT libraries
|
||||
)
|
||||
|
||||
if (WITH_STATIC_LIB)
|
||||
add_library(${LIBSSH_THREADS_STATIC_LIBRARY} STATIC ${libssh_threads_SRCS})
|
||||
|
||||
if (MSVC)
|
||||
set(OUTPUT_SUFFIX static)
|
||||
else (MSVC)
|
||||
set(OUTPUT_SUFFIX )
|
||||
endif (MSVC)
|
||||
|
||||
set_target_properties(
|
||||
${LIBSSH_THREADS_STATIC_LIBRARY}
|
||||
PROPERTIES
|
||||
VERSION
|
||||
${LIBRARY_VERSION}
|
||||
SOVERSION
|
||||
${LIBRARY_SOVERSION}
|
||||
OUTPUT_NAME
|
||||
ssh_threads
|
||||
ARCHIVE_OUTPUT_DIRECTORY
|
||||
${CMAKE_CURRENT_BINARY_DIR}/${OUTPUT_SUFFIX}
|
||||
)
|
||||
|
||||
if (WIN32)
|
||||
set_target_properties(
|
||||
${LIBSSH_THREADS_STATIC_LIBRARY}
|
||||
PROPERTIES
|
||||
COMPILE_FLAGS
|
||||
"-DLIBSSH_STATIC"
|
||||
)
|
||||
endif (WIN32)
|
||||
|
||||
install(
|
||||
TARGETS
|
||||
${LIBSSH_THREADS_STATIC_LIBRARY}
|
||||
DESTINATION
|
||||
${LIB_INSTALL_DIR}/${OUTPUT_SUFFIX}
|
||||
COMPONENT
|
||||
libraries
|
||||
)
|
||||
endif (WITH_STATIC_LIB)
|
||||
endif (libssh_threads_SRCS)
|
||||
|
||||
@@ -130,10 +130,13 @@ void crypto_free(struct ssh_crypto_struct *crypto){
|
||||
(deflateEnd(crypto->compress_out_ctx) != 0)) {
|
||||
inflateEnd(crypto->compress_out_ctx);
|
||||
}
|
||||
SAFE_FREE(crypto->compress_out_ctx);
|
||||
|
||||
if (crypto->compress_in_ctx &&
|
||||
(deflateEnd(crypto->compress_in_ctx) != 0)) {
|
||||
inflateEnd(crypto->compress_in_ctx);
|
||||
}
|
||||
SAFE_FREE(crypto->compress_in_ctx);
|
||||
#endif /* WITH_ZLIB */
|
||||
if(crypto->encryptIV)
|
||||
SAFE_FREE(crypto->encryptIV);
|
||||
|
||||
@@ -24,6 +24,7 @@
|
||||
#include "torture.h"
|
||||
#include <libssh/libssh.h>
|
||||
#include <sys/time.h>
|
||||
#include <arpa/inet.h>
|
||||
|
||||
#define HOST "localhost"
|
||||
/* Should work until Apnic decides to assign it :) */
|
||||
@@ -54,12 +55,11 @@ static void torture_connect_nonblocking(void **state) {
|
||||
ssh_set_blocking(session,0);
|
||||
|
||||
do {
|
||||
rc = ssh_connect(session);
|
||||
assert_true(rc != SSH_ERROR);
|
||||
rc = ssh_connect(session);
|
||||
assert_true(rc != SSH_ERROR);
|
||||
} while(rc == SSH_AGAIN);
|
||||
|
||||
assert_true(rc==SSH_OK);
|
||||
|
||||
assert_true(rc == SSH_OK);
|
||||
}
|
||||
|
||||
static void torture_connect_timeout(void **state) {
|
||||
@@ -84,9 +84,9 @@ static void torture_connect_timeout(void **state) {
|
||||
sec = after.tv_sec - before.tv_sec;
|
||||
usec = after.tv_usec - before.tv_usec;
|
||||
/* Borrow a second for the missing usecs, but don't bother calculating */
|
||||
if(usec < 0)
|
||||
if (usec < 0)
|
||||
sec--;
|
||||
assert_in_range(sec,1,3);
|
||||
assert_in_range(sec, 1, 3);
|
||||
}
|
||||
|
||||
static void torture_connect_double(void **state) {
|
||||
@@ -102,10 +102,9 @@ static void torture_connect_double(void **state) {
|
||||
|
||||
rc = ssh_connect(session);
|
||||
assert_true(rc == SSH_OK);
|
||||
|
||||
}
|
||||
|
||||
static void torture_connect_failure(void **state){
|
||||
static void torture_connect_failure(void **state) {
|
||||
/*
|
||||
* The intent of this test is to check that a fresh
|
||||
* ssh_new/ssh_disconnect/ssh_free sequence doesn't crash/leak
|
||||
@@ -114,6 +113,30 @@ static void torture_connect_failure(void **state){
|
||||
ssh_session session = *state;
|
||||
ssh_disconnect(session);
|
||||
}
|
||||
|
||||
static void torture_connect_socket(void **state) {
|
||||
ssh_session session = *state;
|
||||
|
||||
int rc;
|
||||
int sock_fd = 0;
|
||||
struct sockaddr_in server_addr;
|
||||
|
||||
sock_fd = socket(AF_INET, SOCK_STREAM, 0);
|
||||
assert_true(sock_fd > 0);
|
||||
|
||||
server_addr.sin_family = AF_INET;
|
||||
server_addr.sin_port = htons(22);
|
||||
server_addr.sin_addr.s_addr = inet_addr("127.0.0.1");
|
||||
|
||||
rc = connect(sock_fd, &server_addr, sizeof(server_addr));
|
||||
assert_true(rc == 0);
|
||||
|
||||
ssh_options_set(session, SSH_OPTIONS_FD, &sock_fd);
|
||||
|
||||
rc = ssh_connect(session);
|
||||
assert_true(rc == SSH_OK);
|
||||
}
|
||||
|
||||
int torture_run_tests(void) {
|
||||
int rc;
|
||||
const UnitTest tests[] = {
|
||||
@@ -121,6 +144,7 @@ int torture_run_tests(void) {
|
||||
unit_test_setup_teardown(torture_connect_double, setup, teardown),
|
||||
unit_test_setup_teardown(torture_connect_failure, setup, teardown),
|
||||
unit_test_setup_teardown(torture_connect_timeout, setup, teardown),
|
||||
unit_test_setup_teardown(torture_connect_socket, setup, teardown),
|
||||
};
|
||||
|
||||
ssh_init();
|
||||
|
||||
@@ -36,17 +36,36 @@ static void setup_dsa_key(void **state) {
|
||||
}
|
||||
|
||||
#ifdef HAVE_OPENSSL_ECC
|
||||
static void setup_ecdsa_key(void **state) {
|
||||
int rc;
|
||||
static void setup_ecdsa_key(void **state, int ecdsa_bits) {
|
||||
int rc = -1;
|
||||
|
||||
(void) state; /* unused */
|
||||
|
||||
unlink(LIBSSH_ECDSA_TESTKEY);
|
||||
unlink(LIBSSH_ECDSA_TESTKEY ".pub");
|
||||
|
||||
rc = system("ssh-keygen -t ecdsa -q -N \"\" -f " LIBSSH_ECDSA_TESTKEY);
|
||||
if (ecdsa_bits == 256) {
|
||||
rc = system("ssh-keygen -t ecdsa -b 256 -q -N \"\" -f " LIBSSH_ECDSA_TESTKEY);
|
||||
} else if (ecdsa_bits == 384) {
|
||||
rc = system("ssh-keygen -t ecdsa -b 384 -q -N \"\" -f " LIBSSH_ECDSA_TESTKEY);
|
||||
} else if (ecdsa_bits == 521) {
|
||||
rc = system("ssh-keygen -t ecdsa -b 521 -q -N \"\" -f " LIBSSH_ECDSA_TESTKEY);
|
||||
}
|
||||
|
||||
assert_true(rc == 0);
|
||||
}
|
||||
|
||||
static void setup_ecdsa_key_521(void **state) {
|
||||
setup_ecdsa_key(state, 521);
|
||||
}
|
||||
|
||||
static void setup_ecdsa_key_384(void **state) {
|
||||
setup_ecdsa_key(state, 384);
|
||||
}
|
||||
|
||||
static void setup_ecdsa_key_256(void **state) {
|
||||
setup_ecdsa_key(state, 256);
|
||||
}
|
||||
#endif
|
||||
|
||||
static void setup_both_keys(void **state) {
|
||||
@@ -766,6 +785,39 @@ static void torture_pki_duplicate_key_ecdsa(void **state)
|
||||
ssh_string_free_char(b64_key);
|
||||
ssh_string_free_char(b64_key_gen);
|
||||
}
|
||||
|
||||
/* Test case for bug #147: Private ECDSA key duplication did not carry
|
||||
* over parts of the key that then caused subsequent key demotion to
|
||||
* fail.
|
||||
*/
|
||||
static void torture_pki_ecdsa_duplicate_then_demote(void **state)
|
||||
{
|
||||
ssh_key pubkey;
|
||||
ssh_key privkey;
|
||||
ssh_key privkey_dup;
|
||||
int rc;
|
||||
|
||||
(void) state;
|
||||
|
||||
rc = ssh_pki_import_privkey_file(LIBSSH_ECDSA_TESTKEY,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
&privkey);
|
||||
assert_true(rc == 0);
|
||||
|
||||
privkey_dup = ssh_key_dup(privkey);
|
||||
assert_true(privkey_dup != NULL);
|
||||
assert_int_equal(privkey->ecdsa_nid, privkey_dup->ecdsa_nid);
|
||||
|
||||
rc = ssh_pki_export_privkey_to_pubkey(privkey_dup, &pubkey);
|
||||
assert_true(rc == 0);
|
||||
assert_int_equal(pubkey->ecdsa_nid, privkey->ecdsa_nid);
|
||||
|
||||
ssh_key_free(pubkey);
|
||||
ssh_key_free(privkey);
|
||||
ssh_key_free(privkey_dup);
|
||||
}
|
||||
#endif
|
||||
|
||||
static void torture_pki_generate_key_rsa(void **state)
|
||||
@@ -906,6 +958,9 @@ static void torture_pki_generate_key_ecdsa(void **state)
|
||||
int rc;
|
||||
ssh_key key;
|
||||
ssh_signature sign;
|
||||
enum ssh_keytypes_e type = SSH_KEYTYPE_UNKNOWN;
|
||||
const char *type_char = NULL;
|
||||
const char *etype_char = NULL;
|
||||
ssh_session session=ssh_new();
|
||||
(void) state;
|
||||
|
||||
@@ -916,6 +971,13 @@ static void torture_pki_generate_key_ecdsa(void **state)
|
||||
assert_true(sign != NULL);
|
||||
rc = pki_signature_verify(session,sign,key,HASH,20);
|
||||
assert_true(rc == SSH_OK);
|
||||
type = ssh_key_type(key);
|
||||
assert_true(type == SSH_KEYTYPE_ECDSA);
|
||||
type_char = ssh_key_type_to_char(type);
|
||||
assert_true(strcmp(type_char, "ssh-ecdsa") == 0);
|
||||
etype_char = ssh_pki_key_ecdsa_name(key);
|
||||
assert_true(strcmp(etype_char, "ecdsa-sha2-nistp256") == 0);
|
||||
|
||||
ssh_signature_free(sign);
|
||||
ssh_key_free(key);
|
||||
key=NULL;
|
||||
@@ -927,6 +989,13 @@ static void torture_pki_generate_key_ecdsa(void **state)
|
||||
assert_true(sign != NULL);
|
||||
rc = pki_signature_verify(session,sign,key,HASH,20);
|
||||
assert_true(rc == SSH_OK);
|
||||
type = ssh_key_type(key);
|
||||
assert_true(type == SSH_KEYTYPE_ECDSA);
|
||||
type_char = ssh_key_type_to_char(type);
|
||||
assert_true(strcmp(type_char, "ssh-ecdsa") == 0);
|
||||
etype_char =ssh_pki_key_ecdsa_name(key);
|
||||
assert_true(strcmp(etype_char, "ecdsa-sha2-nistp384") == 0);
|
||||
|
||||
ssh_signature_free(sign);
|
||||
ssh_key_free(key);
|
||||
key=NULL;
|
||||
@@ -938,6 +1007,13 @@ static void torture_pki_generate_key_ecdsa(void **state)
|
||||
assert_true(sign != NULL);
|
||||
rc = pki_signature_verify(session,sign,key,HASH,20);
|
||||
assert_true(rc == SSH_OK);
|
||||
type = ssh_key_type(key);
|
||||
assert_true(type == SSH_KEYTYPE_ECDSA);
|
||||
type_char = ssh_key_type_to_char(type);
|
||||
assert_true(strcmp(type_char, "ssh-ecdsa") == 0);
|
||||
etype_char =ssh_pki_key_ecdsa_name(key);
|
||||
assert_true(strcmp(etype_char, "ecdsa-sha2-nistp521") == 0);
|
||||
|
||||
ssh_signature_free(sign);
|
||||
ssh_key_free(key);
|
||||
key=NULL;
|
||||
@@ -1070,6 +1146,42 @@ static void torture_pki_write_privkey_ecdsa(void **state)
|
||||
#endif
|
||||
#endif /* HAVE_LIBCRYPTO */
|
||||
|
||||
#ifdef HAVE_ECC
|
||||
static void torture_pki_ecdsa_name(void **state, const char *expected_name)
|
||||
{
|
||||
int rc;
|
||||
ssh_key key;
|
||||
const char *etype_char = NULL;
|
||||
|
||||
(void) state; /* unused */
|
||||
|
||||
ssh_set_log_level(5);
|
||||
|
||||
rc = ssh_pki_import_privkey_file(LIBSSH_ECDSA_TESTKEY, NULL, NULL, NULL, &key);
|
||||
assert_true(rc == 0);
|
||||
|
||||
etype_char =ssh_pki_key_ecdsa_name(key);
|
||||
assert_true(strcmp(etype_char, expected_name) == 0);
|
||||
|
||||
ssh_key_free(key);
|
||||
}
|
||||
|
||||
static void torture_pki_ecdsa_name256(void **state)
|
||||
{
|
||||
torture_pki_ecdsa_name(state, "ecdsa-sha2-nistp256");
|
||||
}
|
||||
|
||||
static void torture_pki_ecdsa_name384(void **state)
|
||||
{
|
||||
torture_pki_ecdsa_name(state, "ecdsa-sha2-nistp384");
|
||||
}
|
||||
|
||||
static void torture_pki_ecdsa_name521(void **state)
|
||||
{
|
||||
torture_pki_ecdsa_name(state, "ecdsa-sha2-nistp521");
|
||||
}
|
||||
#endif
|
||||
|
||||
int torture_run_tests(void) {
|
||||
int rc;
|
||||
const UnitTest tests[] = {
|
||||
@@ -1092,7 +1204,13 @@ int torture_run_tests(void) {
|
||||
teardown),
|
||||
#ifdef HAVE_ECC
|
||||
unit_test_setup_teardown(torture_pki_import_privkey_base64_ECDSA,
|
||||
setup_ecdsa_key,
|
||||
setup_ecdsa_key_256,
|
||||
teardown),
|
||||
unit_test_setup_teardown(torture_pki_import_privkey_base64_ECDSA,
|
||||
setup_ecdsa_key_384,
|
||||
teardown),
|
||||
unit_test_setup_teardown(torture_pki_import_privkey_base64_ECDSA,
|
||||
setup_ecdsa_key_521,
|
||||
teardown),
|
||||
#endif
|
||||
unit_test_setup_teardown(torture_pki_import_privkey_base64_passphrase,
|
||||
@@ -1107,7 +1225,22 @@ int torture_run_tests(void) {
|
||||
teardown),
|
||||
#ifdef HAVE_ECC
|
||||
unit_test_setup_teardown(torture_pki_publickey_from_privatekey_ECDSA,
|
||||
setup_ecdsa_key,
|
||||
setup_ecdsa_key_256,
|
||||
teardown),
|
||||
unit_test_setup_teardown(torture_pki_publickey_from_privatekey_ECDSA,
|
||||
setup_ecdsa_key_384,
|
||||
teardown),
|
||||
unit_test_setup_teardown(torture_pki_publickey_from_privatekey_ECDSA,
|
||||
setup_ecdsa_key_521,
|
||||
teardown),
|
||||
unit_test_setup_teardown(torture_pki_ecdsa_duplicate_then_demote,
|
||||
setup_ecdsa_key_256,
|
||||
teardown),
|
||||
unit_test_setup_teardown(torture_pki_ecdsa_duplicate_then_demote,
|
||||
setup_ecdsa_key_384,
|
||||
teardown),
|
||||
unit_test_setup_teardown(torture_pki_ecdsa_duplicate_then_demote,
|
||||
setup_ecdsa_key_521,
|
||||
teardown),
|
||||
#endif
|
||||
/* public key */
|
||||
@@ -1119,7 +1252,13 @@ int torture_run_tests(void) {
|
||||
teardown),
|
||||
#ifdef HAVE_ECC
|
||||
unit_test_setup_teardown(torture_pki_publickey_ecdsa_base64,
|
||||
setup_ecdsa_key,
|
||||
setup_ecdsa_key_256,
|
||||
teardown),
|
||||
unit_test_setup_teardown(torture_pki_publickey_ecdsa_base64,
|
||||
setup_ecdsa_key_384,
|
||||
teardown),
|
||||
unit_test_setup_teardown(torture_pki_publickey_ecdsa_base64,
|
||||
setup_ecdsa_key_521,
|
||||
teardown),
|
||||
#endif
|
||||
|
||||
@@ -1131,7 +1270,13 @@ int torture_run_tests(void) {
|
||||
teardown),
|
||||
#ifdef HAVE_ECC
|
||||
unit_test_setup_teardown(torture_generate_pubkey_from_privkey_ecdsa,
|
||||
setup_ecdsa_key,
|
||||
setup_ecdsa_key_256,
|
||||
teardown),
|
||||
unit_test_setup_teardown(torture_generate_pubkey_from_privkey_ecdsa,
|
||||
setup_ecdsa_key_384,
|
||||
teardown),
|
||||
unit_test_setup_teardown(torture_generate_pubkey_from_privkey_ecdsa,
|
||||
setup_ecdsa_key_521,
|
||||
teardown),
|
||||
#endif
|
||||
|
||||
@@ -1143,7 +1288,13 @@ int torture_run_tests(void) {
|
||||
teardown),
|
||||
#ifdef HAVE_ECC
|
||||
unit_test_setup_teardown(torture_pki_duplicate_key_ecdsa,
|
||||
setup_ecdsa_key,
|
||||
setup_ecdsa_key_256,
|
||||
teardown),
|
||||
unit_test_setup_teardown(torture_pki_duplicate_key_ecdsa,
|
||||
setup_ecdsa_key_384,
|
||||
teardown),
|
||||
unit_test_setup_teardown(torture_pki_duplicate_key_ecdsa,
|
||||
setup_ecdsa_key_521,
|
||||
teardown),
|
||||
#endif
|
||||
unit_test(torture_pki_generate_key_rsa),
|
||||
@@ -1161,10 +1312,27 @@ int torture_run_tests(void) {
|
||||
teardown),
|
||||
#ifdef HAVE_ECC
|
||||
unit_test_setup_teardown(torture_pki_write_privkey_ecdsa,
|
||||
setup_ecdsa_key,
|
||||
setup_ecdsa_key_256,
|
||||
teardown),
|
||||
unit_test_setup_teardown(torture_pki_write_privkey_ecdsa,
|
||||
setup_ecdsa_key_384,
|
||||
teardown),
|
||||
unit_test_setup_teardown(torture_pki_write_privkey_ecdsa,
|
||||
setup_ecdsa_key_521,
|
||||
teardown),
|
||||
#endif
|
||||
#endif /* HAVE_LIBCRYPTO */
|
||||
#ifdef HAVE_ECC
|
||||
unit_test_setup_teardown(torture_pki_ecdsa_name256,
|
||||
setup_ecdsa_key_256,
|
||||
teardown),
|
||||
unit_test_setup_teardown(torture_pki_ecdsa_name384,
|
||||
setup_ecdsa_key_384,
|
||||
teardown),
|
||||
unit_test_setup_teardown(torture_pki_ecdsa_name521,
|
||||
setup_ecdsa_key_521,
|
||||
teardown),
|
||||
#endif
|
||||
};
|
||||
|
||||
(void)setup_both_keys;
|
||||
|
||||
Reference in New Issue
Block a user