mirror of
https://github.com/tmate-io/tmate.git
synced 2024-12-04 05:54:44 +01:00
Update libssh
This commit is contained in:
parent
92bf230b8a
commit
2535b531bb
@ -71,6 +71,13 @@ if (WITH_GSSAPI)
|
|||||||
find_package(GSSAPI)
|
find_package(GSSAPI)
|
||||||
endif (WITH_GSSAPI)
|
endif (WITH_GSSAPI)
|
||||||
|
|
||||||
|
if (WITH_NACL)
|
||||||
|
find_package(NaCl)
|
||||||
|
if (NOT NACL_FOUND)
|
||||||
|
set(WITH_NACL OFF)
|
||||||
|
endif (NOT NACL_FOUND)
|
||||||
|
endif (WITH_NACL)
|
||||||
|
|
||||||
# config.h checks
|
# config.h checks
|
||||||
include(ConfigureChecks.cmake)
|
include(ConfigureChecks.cmake)
|
||||||
configure_file(config.h.cmake ${CMAKE_CURRENT_BINARY_DIR}/config.h)
|
configure_file(config.h.cmake ${CMAKE_CURRENT_BINARY_DIR}/config.h)
|
||||||
@ -125,6 +132,7 @@ message(STATUS "********** ${PROJECT_NAME} build options : **********")
|
|||||||
|
|
||||||
message(STATUS "zlib support: ${WITH_ZLIB}")
|
message(STATUS "zlib support: ${WITH_ZLIB}")
|
||||||
message(STATUS "libgcrypt support: ${WITH_GCRYPT}")
|
message(STATUS "libgcrypt support: ${WITH_GCRYPT}")
|
||||||
|
message(STATUS "libnacl support: ${WITH_NACL}")
|
||||||
message(STATUS "SSH-1 support: ${WITH_SSH1}")
|
message(STATUS "SSH-1 support: ${WITH_SSH1}")
|
||||||
message(STATUS "SFTP support: ${WITH_SFTP}")
|
message(STATUS "SFTP support: ${WITH_SFTP}")
|
||||||
message(STATUS "Server support : ${WITH_SERVER}")
|
message(STATUS "Server support : ${WITH_SERVER}")
|
||||||
|
@ -50,6 +50,7 @@ check_include_file(argp.h HAVE_ARGP_H)
|
|||||||
check_include_file(pty.h HAVE_PTY_H)
|
check_include_file(pty.h HAVE_PTY_H)
|
||||||
check_include_file(termios.h HAVE_TERMIOS_H)
|
check_include_file(termios.h HAVE_TERMIOS_H)
|
||||||
check_include_file(unistd.h HAVE_UNISTD_H)
|
check_include_file(unistd.h HAVE_UNISTD_H)
|
||||||
|
check_include_file(util.h HAVE_UTIL_H)
|
||||||
|
|
||||||
if (WIN32)
|
if (WIN32)
|
||||||
check_include_files("winsock2.h;ws2tcpip.h;wspiapi.h" HAVE_WSPIAPI_H)
|
check_include_files("winsock2.h;ws2tcpip.h;wspiapi.h" HAVE_WSPIAPI_H)
|
||||||
@ -93,6 +94,7 @@ endif (NOT WITH_GCRYPT)
|
|||||||
|
|
||||||
# FUNCTIONS
|
# FUNCTIONS
|
||||||
|
|
||||||
|
check_function_exists(isblank HAVE_ISBLANK)
|
||||||
check_function_exists(strncpy HAVE_STRNCPY)
|
check_function_exists(strncpy HAVE_STRNCPY)
|
||||||
check_function_exists(vsnprintf HAVE_VSNPRINTF)
|
check_function_exists(vsnprintf HAVE_VSNPRINTF)
|
||||||
check_function_exists(snprintf HAVE_SNPRINTF)
|
check_function_exists(snprintf HAVE_SNPRINTF)
|
||||||
|
@ -13,7 +13,7 @@ option(WITH_TESTING "Build with unit tests" OFF)
|
|||||||
option(WITH_CLIENT_TESTING "Build with client tests; requires a running sshd" OFF)
|
option(WITH_CLIENT_TESTING "Build with client tests; requires a running sshd" OFF)
|
||||||
option(WITH_BENCHMARKS "Build benchmarks tools" OFF)
|
option(WITH_BENCHMARKS "Build benchmarks tools" OFF)
|
||||||
option(WITH_EXAMPLES "Build examples" ON)
|
option(WITH_EXAMPLES "Build examples" ON)
|
||||||
|
option(WITH_NACL "Build with libnacl (curve25519" ON)
|
||||||
if (WITH_ZLIB)
|
if (WITH_ZLIB)
|
||||||
set(WITH_LIBZ ON)
|
set(WITH_LIBZ ON)
|
||||||
else (WITH_ZLIB)
|
else (WITH_ZLIB)
|
||||||
@ -27,3 +27,7 @@ endif(WITH_BENCHMARKS)
|
|||||||
if (WITH_TESTING)
|
if (WITH_TESTING)
|
||||||
set(WITH_STATIC_LIB ON)
|
set(WITH_STATIC_LIB ON)
|
||||||
endif (WITH_TESTING)
|
endif (WITH_TESTING)
|
||||||
|
|
||||||
|
if (WITH_NACL)
|
||||||
|
set(WITH_NACL ON)
|
||||||
|
endif (WITH_NACL)
|
@ -26,3 +26,7 @@ endif (CMAKE_SYSTEM_NAME MATCHES "(Solaris|SunOS)")
|
|||||||
if (CMAKE_SYSTEM_NAME MATCHES "OS2")
|
if (CMAKE_SYSTEM_NAME MATCHES "OS2")
|
||||||
set(OS2 TRUE)
|
set(OS2 TRUE)
|
||||||
endif (CMAKE_SYSTEM_NAME MATCHES "OS2")
|
endif (CMAKE_SYSTEM_NAME MATCHES "OS2")
|
||||||
|
|
||||||
|
if (CMAKE_SYSTEM_NAME MATCHES "Darwin")
|
||||||
|
set (OSX TRUE)
|
||||||
|
endif (CMAKE_SYSTEM_NAME MATCHES "Darwin")
|
||||||
|
@ -20,6 +20,9 @@
|
|||||||
/* Define to 1 if you have the <pty.h> header file. */
|
/* Define to 1 if you have the <pty.h> header file. */
|
||||||
#cmakedefine HAVE_PTY_H 1
|
#cmakedefine HAVE_PTY_H 1
|
||||||
|
|
||||||
|
/* Define to 1 if you have the <util.h> header file. */
|
||||||
|
#cmakedefine HAVE_UTIL_H 1
|
||||||
|
|
||||||
/* Define to 1 if you have the <termios.h> header file. */
|
/* Define to 1 if you have the <termios.h> header file. */
|
||||||
#cmakedefine HAVE_TERMIOS_H 1
|
#cmakedefine HAVE_TERMIOS_H 1
|
||||||
|
|
||||||
@ -79,6 +82,9 @@
|
|||||||
/* Define to 1 if you have the `_vsnprintf_s' function. */
|
/* Define to 1 if you have the `_vsnprintf_s' function. */
|
||||||
#cmakedefine HAVE__VSNPRINTF_S 1
|
#cmakedefine HAVE__VSNPRINTF_S 1
|
||||||
|
|
||||||
|
/* Define to 1 if you have the `isblank' function. */
|
||||||
|
#cmakedefine HAVE_ISBLANK 1
|
||||||
|
|
||||||
/* Define to 1 if you have the `strncpy' function. */
|
/* Define to 1 if you have the `strncpy' function. */
|
||||||
#cmakedefine HAVE_STRNCPY 1
|
#cmakedefine HAVE_STRNCPY 1
|
||||||
|
|
||||||
@ -123,7 +129,6 @@
|
|||||||
/* Define to 1 if you have the `pthread' library (-lpthread). */
|
/* Define to 1 if you have the `pthread' library (-lpthread). */
|
||||||
#cmakedefine HAVE_PTHREAD 1
|
#cmakedefine HAVE_PTHREAD 1
|
||||||
|
|
||||||
|
|
||||||
/**************************** OPTIONS ****************************/
|
/**************************** OPTIONS ****************************/
|
||||||
|
|
||||||
#cmakedefine HAVE_GCC_THREAD_LOCAL_STORAGE 1
|
#cmakedefine HAVE_GCC_THREAD_LOCAL_STORAGE 1
|
||||||
@ -155,6 +160,9 @@
|
|||||||
/* Define to 1 if you want to enable calltrace debug output */
|
/* Define to 1 if you want to enable calltrace debug output */
|
||||||
#cmakedefine DEBUG_CALLTRACE 1
|
#cmakedefine DEBUG_CALLTRACE 1
|
||||||
|
|
||||||
|
/* Define to 1 if you want to enable NaCl support */
|
||||||
|
#cmakedefine WITH_NACL 1
|
||||||
|
|
||||||
/*************************** ENDIAN *****************************/
|
/*************************** ENDIAN *****************************/
|
||||||
|
|
||||||
/* Define WORDS_BIGENDIAN to 1 if your processor stores words with the most
|
/* Define WORDS_BIGENDIAN to 1 if your processor stores words with the most
|
||||||
|
@ -1628,7 +1628,7 @@ INCLUDE_FILE_PATTERNS =
|
|||||||
# undefined via #undef or recursively expanded use the := operator
|
# undefined via #undef or recursively expanded use the := operator
|
||||||
# instead of the = operator.
|
# instead of the = operator.
|
||||||
|
|
||||||
PREDEFINED =
|
PREDEFINED = WITH_SERVER WITH_SFTP WITH_PCAP
|
||||||
|
|
||||||
# If the MACRO_EXPANSION and EXPAND_ONLY_PREDEF tags are set to YES then
|
# If the MACRO_EXPANSION and EXPAND_ONLY_PREDEF tags are set to YES then
|
||||||
# this tag can be used to specify a list of macro names that should be expanded.
|
# this tag can be used to specify a list of macro names that should be expanded.
|
||||||
|
@ -19,7 +19,7 @@ the interesting functions as you go.
|
|||||||
|
|
||||||
The libssh library provides:
|
The libssh library provides:
|
||||||
|
|
||||||
- <strong>Key Exchange Methods</strong>: <i>ecdh-sha2-nistp256</i>, diffie-hellman-group1-sha1, diffie-hellman-group14-sha1
|
- <strong>Key Exchange Methods</strong>: <i>curve25519-sha256@libssh.org, ecdh-sha2-nistp256</i>, diffie-hellman-group1-sha1, diffie-hellman-group14-sha1
|
||||||
- <strong>Hostkey Types</strong>: <i>ecdsa-sha2-nistp256</i>, ssh-dss, ssh-rsa
|
- <strong>Hostkey Types</strong>: <i>ecdsa-sha2-nistp256</i>, ssh-dss, ssh-rsa
|
||||||
- <strong>Ciphers</strong>: <i>aes256-ctr, aes192-ctr, aes128-ctr</i>, aes256-cbc (rijndael-cbc@lysator.liu.se), aes192-cbc, aes128-cbc, 3des-cbc, des-cbc-ssh1, blowfish-cbc, none
|
- <strong>Ciphers</strong>: <i>aes256-ctr, aes192-ctr, aes128-ctr</i>, aes256-cbc (rijndael-cbc@lysator.liu.se), aes192-cbc, aes128-cbc, 3des-cbc, des-cbc-ssh1, blowfish-cbc, none
|
||||||
- <strong>Compression Schemes</strong>: zlib, <i>zlib@openssh.com</i>, none
|
- <strong>Compression Schemes</strong>: zlib, <i>zlib@openssh.com</i>, none
|
||||||
@ -184,6 +184,8 @@ It was later modified and expanded by the following RFCs.
|
|||||||
Authentication and Key Exchange for the Secure Shell (SSH) Protocol
|
Authentication and Key Exchange for the Secure Shell (SSH) Protocol
|
||||||
- <a href="http://tools.ietf.org/html/rfc4716" target="_blank">RFC 4716</a>,
|
- <a href="http://tools.ietf.org/html/rfc4716" target="_blank">RFC 4716</a>,
|
||||||
The Secure Shell (SSH) Public Key File Format
|
The Secure Shell (SSH) Public Key File Format
|
||||||
|
- <a href="http://tools.ietf.org/html/rfc5647" target="_blank">RFC 5647</a>,
|
||||||
|
AES Galois Counter Mode for the Secure Shell Transport Layer Protocol
|
||||||
- <a href="http://tools.ietf.org/html/rfc5656" target="_blank">RFC 5656</a>,
|
- <a href="http://tools.ietf.org/html/rfc5656" target="_blank">RFC 5656</a>,
|
||||||
Elliptic Curve Algorithm Integration in the Secure Shell Transport Layer
|
Elliptic Curve Algorithm Integration in the Secure Shell Transport Layer
|
||||||
|
|
||||||
@ -203,6 +205,12 @@ do the same in libssh.
|
|||||||
|
|
||||||
@subsection main-rfc-extensions Secure Shell Extensions
|
@subsection main-rfc-extensions Secure Shell Extensions
|
||||||
|
|
||||||
|
The libssh project has an extension to support Curve25519 which is also supported by
|
||||||
|
the OpenSSH project.
|
||||||
|
|
||||||
|
- <a href="" target="_blank">curve25519-sha256@libssh.org</a>,
|
||||||
|
Curve25519-SHA256 for ECDH KEX
|
||||||
|
|
||||||
The OpenSSH project has defined some extensions to the protocol. We support some of
|
The OpenSSH project has defined some extensions to the protocol. We support some of
|
||||||
them like the statvfs calls in SFTP or the ssh-agent.
|
them like the statvfs calls in SFTP or the ssh-agent.
|
||||||
|
|
||||||
|
@ -210,52 +210,63 @@ results to come.
|
|||||||
|
|
||||||
Synchronous read is done with sftp_read().
|
Synchronous read is done with sftp_read().
|
||||||
|
|
||||||
The following example prints the contents of remote file "/etc/profile". For
|
Files are normally transferred in chunks. A good chunk size is 16 KB. The following
|
||||||
each 1024 bytes of information read, it waits until the end of the read operation:
|
example transfers the remote file "/etc/profile" in 16 KB chunks. For each chunk we
|
||||||
|
request, sftp_read blocks till the data has been received:
|
||||||
|
|
||||||
@code
|
@code
|
||||||
|
// Good chunk size
|
||||||
|
#define MAX_XFER_BUF_SIZE 16384
|
||||||
|
|
||||||
int sftp_read_sync(ssh_session session, sftp_session sftp)
|
int sftp_read_sync(ssh_session session, sftp_session sftp)
|
||||||
{
|
{
|
||||||
int access_type;
|
int access_type;
|
||||||
sftp_file file;
|
sftp_file file;
|
||||||
char buffer[1024];
|
char buffer[MAX_XFER_BUF_SIZE];
|
||||||
int nbytes, rc;
|
int nbytes, nwritten, rc;
|
||||||
|
int fd;
|
||||||
|
|
||||||
access_type = O_RDONLY;
|
access_type = O_RDONLY;
|
||||||
file = sftp_open(sftp, "/etc/profile",
|
file = sftp_open(sftp, "/etc/profile",
|
||||||
access_type, 0);
|
access_type, 0);
|
||||||
if (file == NULL)
|
if (file == NULL) {
|
||||||
{
|
fprintf(stderr, "Can't open file for reading: %s\n",
|
||||||
fprintf(stderr, "Can't open file for reading: %s\n",
|
ssh_get_error(session));
|
||||||
ssh_get_error(session));
|
|
||||||
return SSH_ERROR;
|
|
||||||
}
|
|
||||||
|
|
||||||
nbytes = sftp_read(file, buffer, sizeof(buffer));
|
|
||||||
while (nbytes > 0)
|
|
||||||
{
|
|
||||||
if (write(1, buffer, nbytes) != nbytes)
|
|
||||||
{
|
|
||||||
sftp_close(file);
|
|
||||||
return SSH_ERROR;
|
return SSH_ERROR;
|
||||||
}
|
|
||||||
nbytes = sftp_read(file, buffer, sizeof(buffer));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (nbytes < 0)
|
fd = open("/path/to/profile", O_CREAT);
|
||||||
{
|
if (fd < 0) {
|
||||||
fprintf(stderr, "Error while reading file: %s\n",
|
fprintf(stderr, "Can't open file for writing: %s\n",
|
||||||
ssh_get_error(session));
|
strerror(errno));
|
||||||
sftp_close(file);
|
return SSH_ERROR;
|
||||||
return SSH_ERROR;
|
}
|
||||||
|
|
||||||
|
for (;;) {
|
||||||
|
nbytes = sftp_read(file, buffer, sizeof(buffer));
|
||||||
|
if (nbytes == 0) {
|
||||||
|
break; // EOF
|
||||||
|
} else if (nbytes < 0) {
|
||||||
|
fprintf(stderr, "Error while reading file: %s\n",
|
||||||
|
ssh_get_error(session));
|
||||||
|
sftp_close(file);
|
||||||
|
return SSH_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
nwritten = write(fd, buf, nbytes);
|
||||||
|
if (nwritten != nbytes) {
|
||||||
|
fprintf(stderr, "Error writing: %s\n",
|
||||||
|
strerror(errno));
|
||||||
|
sftp_close(file);
|
||||||
|
return SSH_ERROR;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
rc = sftp_close(file);
|
rc = sftp_close(file);
|
||||||
if (rc != SSH_OK)
|
if (rc != SSH_OK) {
|
||||||
{
|
fprintf(stderr, "Can't close the read file: %s\n",
|
||||||
fprintf(stderr, "Can't close the read file: %s\n",
|
ssh_get_error(session));
|
||||||
ssh_get_error(session));
|
return rc;
|
||||||
return rc;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return SSH_OK;
|
return SSH_OK;
|
||||||
@ -274,11 +285,14 @@ The example below reads a very big file in asynchronous, nonblocking, mode. Each
|
|||||||
time the data are not ready yet, a counter is incrementer.
|
time the data are not ready yet, a counter is incrementer.
|
||||||
|
|
||||||
@code
|
@code
|
||||||
|
// Good chunk size
|
||||||
|
#define MAX_XFER_BUF_SIZE 16384
|
||||||
|
|
||||||
int sftp_read_async(ssh_session session, sftp_session sftp)
|
int sftp_read_async(ssh_session session, sftp_session sftp)
|
||||||
{
|
{
|
||||||
int access_type;
|
int access_type;
|
||||||
sftp_file file;
|
sftp_file file;
|
||||||
char buffer[1024];
|
char buffer[MAX_XFER_BUF_SIZE];
|
||||||
int async_request;
|
int async_request;
|
||||||
int nbytes;
|
int nbytes;
|
||||||
long counter;
|
long counter;
|
||||||
@ -287,8 +301,7 @@ int sftp_read_async(ssh_session session, sftp_session sftp)
|
|||||||
access_type = O_RDONLY;
|
access_type = O_RDONLY;
|
||||||
file = sftp_open(sftp, "some_very_big_file",
|
file = sftp_open(sftp, "some_very_big_file",
|
||||||
access_type, 0);
|
access_type, 0);
|
||||||
if (file == NULL)
|
if (file == NULL) {
|
||||||
{
|
|
||||||
fprintf(stderr, "Can't open file for reading: %s\n",
|
fprintf(stderr, "Can't open file for reading: %s\n",
|
||||||
ssh_get_error(session));
|
ssh_get_error(session));
|
||||||
return SSH_ERROR;
|
return SSH_ERROR;
|
||||||
@ -298,27 +311,31 @@ int sftp_read_async(ssh_session session, sftp_session sftp)
|
|||||||
async_request = sftp_async_read_begin(file, sizeof(buffer));
|
async_request = sftp_async_read_begin(file, sizeof(buffer));
|
||||||
counter = 0L;
|
counter = 0L;
|
||||||
usleep(10000);
|
usleep(10000);
|
||||||
if (async_request >= 0)
|
if (async_request >= 0) {
|
||||||
nbytes = sftp_async_read(file, buffer, sizeof(buffer),
|
nbytes = sftp_async_read(file, buffer, sizeof(buffer),
|
||||||
async_request);
|
async_request);
|
||||||
else nbytes = -1;
|
} else {
|
||||||
while (nbytes > 0 || nbytes == SSH_AGAIN)
|
nbytes = -1;
|
||||||
{
|
|
||||||
if (nbytes > 0)
|
|
||||||
{
|
|
||||||
write(1, buffer, nbytes);
|
|
||||||
async_request = sftp_async_read_begin(file, sizeof(buffer));
|
|
||||||
}
|
|
||||||
else counter++;
|
|
||||||
usleep(10000);
|
|
||||||
if (async_request >= 0)
|
|
||||||
nbytes = sftp_async_read(file, buffer, sizeof(buffer),
|
|
||||||
async_request);
|
|
||||||
else nbytes = -1;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (nbytes < 0)
|
while (nbytes > 0 || nbytes == SSH_AGAIN) {
|
||||||
{
|
if (nbytes > 0) {
|
||||||
|
write(1, buffer, nbytes);
|
||||||
|
async_request = sftp_async_read_begin(file, sizeof(buffer));
|
||||||
|
} else {
|
||||||
|
counter++;
|
||||||
|
}
|
||||||
|
usleep(10000);
|
||||||
|
|
||||||
|
if (async_request >= 0) {
|
||||||
|
nbytes = sftp_async_read(file, buffer, sizeof(buffer),
|
||||||
|
async_request);
|
||||||
|
} else {
|
||||||
|
nbytes = -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (nbytes < 0) {
|
||||||
fprintf(stderr, "Error while reading file: %s\n",
|
fprintf(stderr, "Error while reading file: %s\n",
|
||||||
ssh_get_error(session));
|
ssh_get_error(session));
|
||||||
sftp_close(file);
|
sftp_close(file);
|
||||||
@ -328,8 +345,7 @@ int sftp_read_async(ssh_session session, sftp_session sftp)
|
|||||||
printf("The counter has reached value: %ld\n", counter);
|
printf("The counter has reached value: %ld\n", counter);
|
||||||
|
|
||||||
rc = sftp_close(file);
|
rc = sftp_close(file);
|
||||||
if (rc != SSH_OK)
|
if (rc != SSH_OK) {
|
||||||
{
|
|
||||||
fprintf(stderr, "Can't close the read file: %s\n",
|
fprintf(stderr, "Can't close the read file: %s\n",
|
||||||
ssh_get_error(session));
|
ssh_get_error(session));
|
||||||
return rc;
|
return rc;
|
||||||
|
@ -11,9 +11,9 @@ include_directories(
|
|||||||
${CMAKE_BINARY_DIR}
|
${CMAKE_BINARY_DIR}
|
||||||
)
|
)
|
||||||
|
|
||||||
if (BSD OR SOLARIS)
|
if (BSD OR SOLARIS OR OSX)
|
||||||
find_package(Argp)
|
find_package(Argp)
|
||||||
endif (BSD OR SOLARIS)
|
endif (BSD OR SOLARIS OR OSX)
|
||||||
|
|
||||||
if (UNIX AND NOT WIN32)
|
if (UNIX AND NOT WIN32)
|
||||||
add_executable(libssh_scp libssh_scp.c ${examples_SRCS})
|
add_executable(libssh_scp libssh_scp.c ${examples_SRCS})
|
||||||
@ -28,7 +28,7 @@ if (UNIX AND NOT WIN32)
|
|||||||
if (WITH_SERVER)
|
if (WITH_SERVER)
|
||||||
if (HAVE_LIBUTIL)
|
if (HAVE_LIBUTIL)
|
||||||
add_executable(samplesshd-tty samplesshd-tty.c)
|
add_executable(samplesshd-tty samplesshd-tty.c)
|
||||||
target_link_libraries(samplesshd-tty ${LIBSSH_SHARED_LIBRARY} util)
|
target_link_libraries(samplesshd-tty ${LIBSSH_SHARED_LIBRARY} ${ARGP_LIBRARIES} util)
|
||||||
endif (HAVE_LIBUTIL)
|
endif (HAVE_LIBUTIL)
|
||||||
endif (WITH_SERVER)
|
endif (WITH_SERVER)
|
||||||
|
|
||||||
|
@ -34,14 +34,26 @@ int verify_knownhost(ssh_session session){
|
|||||||
int state;
|
int state;
|
||||||
char buf[10];
|
char buf[10];
|
||||||
unsigned char *hash = NULL;
|
unsigned char *hash = NULL;
|
||||||
int hlen;
|
size_t hlen;
|
||||||
|
ssh_key srv_pubkey;
|
||||||
|
int rc;
|
||||||
|
|
||||||
state=ssh_is_server_known(session);
|
state=ssh_is_server_known(session);
|
||||||
|
|
||||||
hlen = ssh_get_pubkey_hash(session, &hash);
|
rc = ssh_get_publickey(session, &srv_pubkey);
|
||||||
if (hlen < 0) {
|
if (rc < 0) {
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
rc = ssh_get_publickey_hash(srv_pubkey,
|
||||||
|
SSH_PUBLICKEY_HASH_SHA1,
|
||||||
|
&hash,
|
||||||
|
&hlen);
|
||||||
|
ssh_key_free(srv_pubkey);
|
||||||
|
if (rc < 0) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
switch(state){
|
switch(state){
|
||||||
case SSH_SERVER_KNOWN_OK:
|
case SSH_SERVER_KNOWN_OK:
|
||||||
break; /* ok */
|
break; /* ok */
|
||||||
|
@ -25,8 +25,12 @@ clients must be made or how a client should react.
|
|||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <poll.h>
|
#include <poll.h>
|
||||||
|
#ifdef HAVE_PTY_H
|
||||||
#include <pty.h>
|
#include <pty.h>
|
||||||
|
#endif
|
||||||
|
#ifdef HAVE_UTIL_H
|
||||||
|
#include <util.h>
|
||||||
|
#endif
|
||||||
#define SSHD_USER "libssh"
|
#define SSHD_USER "libssh"
|
||||||
#define SSHD_PASSWORD "libssh"
|
#define SSHD_PASSWORD "libssh"
|
||||||
|
|
||||||
|
@ -166,7 +166,7 @@ typedef struct ssh_callbacks_struct *ssh_callbacks;
|
|||||||
* @param user User that wants to authenticate
|
* @param user User that wants to authenticate
|
||||||
* @param password Password used for authentication
|
* @param password Password used for authentication
|
||||||
* @param userdata Userdata to be passed to the callback function.
|
* @param userdata Userdata to be passed to the callback function.
|
||||||
* @returns SSH_AUTH_OK Authentication is accepted.
|
* @returns SSH_AUTH_SUCCESS Authentication is accepted.
|
||||||
* @returns SSH_AUTH_PARTIAL Partial authentication, more authentication means are needed.
|
* @returns SSH_AUTH_PARTIAL Partial authentication, more authentication means are needed.
|
||||||
* @returns SSH_AUTH_DENIED Authentication failed.
|
* @returns SSH_AUTH_DENIED Authentication failed.
|
||||||
*/
|
*/
|
||||||
@ -179,7 +179,7 @@ typedef int (*ssh_auth_password_callback) (ssh_session session, const char *user
|
|||||||
* @param session Current session handler
|
* @param session Current session handler
|
||||||
* @param user User that wants to authenticate
|
* @param user User that wants to authenticate
|
||||||
* @param userdata Userdata to be passed to the callback function.
|
* @param userdata Userdata to be passed to the callback function.
|
||||||
* @returns SSH_AUTH_OK Authentication is accepted.
|
* @returns SSH_AUTH_SUCCESS Authentication is accepted.
|
||||||
* @returns SSH_AUTH_PARTIAL Partial authentication, more authentication means are needed.
|
* @returns SSH_AUTH_PARTIAL Partial authentication, more authentication means are needed.
|
||||||
* @returns SSH_AUTH_DENIED Authentication failed.
|
* @returns SSH_AUTH_DENIED Authentication failed.
|
||||||
*/
|
*/
|
||||||
@ -191,7 +191,7 @@ typedef int (*ssh_auth_none_callback) (ssh_session session, const char *user, vo
|
|||||||
* @param user Username of the user (can be spoofed)
|
* @param user Username of the user (can be spoofed)
|
||||||
* @param principal Authenticated principal of the user, including realm.
|
* @param principal Authenticated principal of the user, including realm.
|
||||||
* @param userdata Userdata to be passed to the callback function.
|
* @param userdata Userdata to be passed to the callback function.
|
||||||
* @returns SSH_AUTH_OK Authentication is accepted.
|
* @returns SSH_AUTH_SUCCESS Authentication is accepted.
|
||||||
* @returns SSH_AUTH_PARTIAL Partial authentication, more authentication means are needed.
|
* @returns SSH_AUTH_PARTIAL Partial authentication, more authentication means are needed.
|
||||||
* @returns SSH_AUTH_DENIED Authentication failed.
|
* @returns SSH_AUTH_DENIED Authentication failed.
|
||||||
* @warning Implementations should verify that parameter user matches in some way the principal.
|
* @warning Implementations should verify that parameter user matches in some way the principal.
|
||||||
@ -209,7 +209,7 @@ typedef int (*ssh_auth_gssapi_mic_callback) (ssh_session session, const char *us
|
|||||||
* SSH_PUBLICKEY_STATE_VALID if the signature is valid. Others values should be
|
* SSH_PUBLICKEY_STATE_VALID if the signature is valid. Others values should be
|
||||||
* replied with a SSH_AUTH_DENIED.
|
* replied with a SSH_AUTH_DENIED.
|
||||||
* @param userdata Userdata to be passed to the callback function.
|
* @param userdata Userdata to be passed to the callback function.
|
||||||
* @returns SSH_AUTH_OK Authentication is accepted.
|
* @returns SSH_AUTH_SUCCESS Authentication is accepted.
|
||||||
* @returns SSH_AUTH_PARTIAL Partial authentication, more authentication means are needed.
|
* @returns SSH_AUTH_PARTIAL Partial authentication, more authentication means are needed.
|
||||||
* @returns SSH_AUTH_DENIED Authentication failed.
|
* @returns SSH_AUTH_DENIED Authentication failed.
|
||||||
*/
|
*/
|
||||||
|
@ -26,15 +26,23 @@
|
|||||||
|
|
||||||
#ifdef WITH_NACL
|
#ifdef WITH_NACL
|
||||||
|
|
||||||
#define HAVE_CURVE25519
|
|
||||||
#include <nacl/crypto_scalarmult_curve25519.h>
|
#include <nacl/crypto_scalarmult_curve25519.h>
|
||||||
#define CURVE25519_PUBKEY_SIZE crypto_scalarmult_curve25519_BYTES
|
#define CURVE25519_PUBKEY_SIZE crypto_scalarmult_curve25519_BYTES
|
||||||
#define CURVE25519_PRIVKEY_SIZE crypto_scalarmult_curve25519_SCALARBYTES
|
#define CURVE25519_PRIVKEY_SIZE crypto_scalarmult_curve25519_SCALARBYTES
|
||||||
|
#define crypto_scalarmult_base crypto_scalarmult_curve25519_base
|
||||||
|
#define crypto_scalarmult crypto_scalarmult_curve25519
|
||||||
|
#else
|
||||||
|
|
||||||
|
#define CURVE25519_PUBKEY_SIZE 32
|
||||||
|
#define CURVE25519_PRIVKEY_SIZE 32
|
||||||
|
int crypto_scalarmult_base(unsigned char *q, const unsigned char *n);
|
||||||
|
int crypto_scalarmult(unsigned char *q, const unsigned char *n, const unsigned char *p);
|
||||||
|
#endif /* WITH_NACL */
|
||||||
|
|
||||||
|
#define HAVE_CURVE25519
|
||||||
typedef unsigned char ssh_curve25519_pubkey[CURVE25519_PUBKEY_SIZE];
|
typedef unsigned char ssh_curve25519_pubkey[CURVE25519_PUBKEY_SIZE];
|
||||||
typedef unsigned char ssh_curve25519_privkey[CURVE25519_PRIVKEY_SIZE];
|
typedef unsigned char ssh_curve25519_privkey[CURVE25519_PRIVKEY_SIZE];
|
||||||
|
|
||||||
#endif /* WITH_NACL */
|
|
||||||
|
|
||||||
int ssh_client_curve25519_init(ssh_session session);
|
int ssh_client_curve25519_init(ssh_session session);
|
||||||
int ssh_client_curve25519_reply(ssh_session session, ssh_buffer packet);
|
int ssh_client_curve25519_reply(ssh_session session, ssh_buffer packet);
|
||||||
|
@ -38,6 +38,11 @@ typedef SHA_CTX* SHACTX;
|
|||||||
typedef SHA256_CTX* SHA256CTX;
|
typedef SHA256_CTX* SHA256CTX;
|
||||||
typedef MD5_CTX* MD5CTX;
|
typedef MD5_CTX* MD5CTX;
|
||||||
typedef HMAC_CTX* HMACCTX;
|
typedef HMAC_CTX* HMACCTX;
|
||||||
|
#ifdef HAVE_ECC
|
||||||
|
typedef EVP_MD_CTX *EVPCTX;
|
||||||
|
#else
|
||||||
|
typedef void *EVPCTX;
|
||||||
|
#endif
|
||||||
|
|
||||||
#define SHA_DIGEST_LEN SHA_DIGEST_LENGTH
|
#define SHA_DIGEST_LEN SHA_DIGEST_LENGTH
|
||||||
#ifdef MD5_DIGEST_LEN
|
#ifdef MD5_DIGEST_LEN
|
||||||
|
@ -29,6 +29,7 @@
|
|||||||
typedef gcry_md_hd_t SHACTX;
|
typedef gcry_md_hd_t SHACTX;
|
||||||
typedef gcry_md_hd_t MD5CTX;
|
typedef gcry_md_hd_t MD5CTX;
|
||||||
typedef gcry_md_hd_t HMACCTX;
|
typedef gcry_md_hd_t HMACCTX;
|
||||||
|
typedef void *EVPCTX;
|
||||||
#define SHA_DIGEST_LENGTH 20
|
#define SHA_DIGEST_LENGTH 20
|
||||||
#define SHA_DIGEST_LEN SHA_DIGEST_LENGTH
|
#define SHA_DIGEST_LEN SHA_DIGEST_LENGTH
|
||||||
#define MD5_DIGEST_LEN 16
|
#define MD5_DIGEST_LEN 16
|
||||||
|
@ -208,10 +208,14 @@ enum ssh_publickey_state_e {
|
|||||||
SSH_PUBLICKEY_STATE_WRONG=2
|
SSH_PUBLICKEY_STATE_WRONG=2
|
||||||
};
|
};
|
||||||
|
|
||||||
/* status flags */
|
/* Status flags */
|
||||||
|
/** Socket is closed */
|
||||||
#define SSH_CLOSED 0x01
|
#define SSH_CLOSED 0x01
|
||||||
|
/** Reading to socket won't block */
|
||||||
#define SSH_READ_PENDING 0x02
|
#define SSH_READ_PENDING 0x02
|
||||||
|
/** Session was closed due to an error */
|
||||||
#define SSH_CLOSED_ERROR 0x04
|
#define SSH_CLOSED_ERROR 0x04
|
||||||
|
/** Output buffer not empty */
|
||||||
#define SSH_WRITE_PENDING 0x08
|
#define SSH_WRITE_PENDING 0x08
|
||||||
|
|
||||||
enum ssh_server_known_e {
|
enum ssh_server_known_e {
|
||||||
@ -408,8 +412,20 @@ LIBSSH_API socket_t ssh_get_fd(ssh_session session);
|
|||||||
LIBSSH_API char *ssh_get_hexa(const unsigned char *what, size_t len);
|
LIBSSH_API char *ssh_get_hexa(const unsigned char *what, size_t len);
|
||||||
LIBSSH_API char *ssh_get_issue_banner(ssh_session session);
|
LIBSSH_API char *ssh_get_issue_banner(ssh_session session);
|
||||||
LIBSSH_API int ssh_get_openssh_version(ssh_session session);
|
LIBSSH_API int ssh_get_openssh_version(ssh_session session);
|
||||||
|
|
||||||
LIBSSH_API int ssh_get_publickey(ssh_session session, ssh_key *key);
|
LIBSSH_API int ssh_get_publickey(ssh_session session, ssh_key *key);
|
||||||
LIBSSH_API int ssh_get_pubkey_hash(ssh_session session, unsigned char **hash);
|
|
||||||
|
enum ssh_publickey_hash_type {
|
||||||
|
SSH_PUBLICKEY_HASH_SHA1,
|
||||||
|
SSH_PUBLICKEY_HASH_MD5
|
||||||
|
};
|
||||||
|
LIBSSH_API int ssh_get_publickey_hash(const ssh_key key,
|
||||||
|
enum ssh_publickey_hash_type type,
|
||||||
|
unsigned char **hash,
|
||||||
|
size_t *hlen);
|
||||||
|
|
||||||
|
SSH_DEPRECATED LIBSSH_API int ssh_get_pubkey_hash(ssh_session session, unsigned char **hash);
|
||||||
|
|
||||||
LIBSSH_API int ssh_get_random(void *where,int len,int strong);
|
LIBSSH_API int ssh_get_random(void *where,int len,int strong);
|
||||||
LIBSSH_API int ssh_get_version(ssh_session session);
|
LIBSSH_API int ssh_get_version(ssh_session session);
|
||||||
LIBSSH_API int ssh_get_status(ssh_session session);
|
LIBSSH_API int ssh_get_status(ssh_session session);
|
||||||
|
@ -60,6 +60,7 @@ struct ssh_key_struct {
|
|||||||
|
|
||||||
struct ssh_signature_struct {
|
struct ssh_signature_struct {
|
||||||
enum ssh_keytypes_e type;
|
enum ssh_keytypes_e type;
|
||||||
|
const char *type_c;
|
||||||
#ifdef HAVE_LIBGCRYPT
|
#ifdef HAVE_LIBGCRYPT
|
||||||
gcry_sexp_t dsa_sig;
|
gcry_sexp_t dsa_sig;
|
||||||
gcry_sexp_t rsa_sig;
|
gcry_sexp_t rsa_sig;
|
||||||
|
@ -67,7 +67,9 @@
|
|||||||
|
|
||||||
# define strcasecmp _stricmp
|
# define strcasecmp _stricmp
|
||||||
# define strncasecmp _strnicmp
|
# define strncasecmp _strnicmp
|
||||||
# define isblank(ch) ((ch) == ' ' || (ch) == '\t' || (ch) == '\n' || (ch) == '\r')
|
# if ! defined(HAVE_ISBLANK)
|
||||||
|
# define isblank(ch) ((ch) == ' ' || (ch) == '\t' || (ch) == '\n' || (ch) == '\r')
|
||||||
|
# endif
|
||||||
|
|
||||||
# define usleep(X) Sleep(((X)+1000)/1000)
|
# define usleep(X) Sleep(((X)+1000)/1000)
|
||||||
|
|
||||||
@ -153,6 +155,16 @@ int gettimeofday(struct timeval *__p, void *__t);
|
|||||||
#include <sys/time.h>
|
#include <sys/time.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
/*
|
||||||
|
* get rid of deprecacy warnings on OSX when using OpenSSL
|
||||||
|
*/
|
||||||
|
#if defined(__APPLE__)
|
||||||
|
#ifdef MAC_OS_X_VERSION_MIN_REQUIRED
|
||||||
|
#undef MAC_OS_X_VERSION_MIN_REQUIRED
|
||||||
|
#endif
|
||||||
|
#define MAC_OS_X_VERSION_MIN_REQUIRED MAC_OS_X_VERSION_10_6
|
||||||
|
#endif
|
||||||
|
|
||||||
/* forward declarations */
|
/* forward declarations */
|
||||||
struct ssh_common_struct;
|
struct ssh_common_struct;
|
||||||
struct ssh_kex_struct;
|
struct ssh_kex_struct;
|
||||||
@ -252,7 +264,7 @@ int match_hostname(const char *host, const char *pattern, unsigned int len);
|
|||||||
/** Overwrite the buffer with '\0' */
|
/** Overwrite the buffer with '\0' */
|
||||||
# define BURN_BUFFER(x, size) do { \
|
# define BURN_BUFFER(x, size) do { \
|
||||||
if ((x) != NULL) \
|
if ((x) != NULL) \
|
||||||
memset((x), '\0', (size))); __asm__ volatile("" : : "r"(&(x)) : "memory"); \
|
memset((x), '\0', (size)); __asm__ volatile("" : : "r"(&(x)) : "memory"); \
|
||||||
} while(0)
|
} while(0)
|
||||||
#else /* HAVE_GCC_VOLATILE_MEMORY_PROTECTION */
|
#else /* HAVE_GCC_VOLATILE_MEMORY_PROTECTION */
|
||||||
/** Overwrite a string with '\0' */
|
/** Overwrite a string with '\0' */
|
||||||
@ -263,7 +275,7 @@ int match_hostname(const char *host, const char *pattern, unsigned int len);
|
|||||||
/** Overwrite the buffer with '\0' */
|
/** Overwrite the buffer with '\0' */
|
||||||
# define BURN_BUFFER(x, size) do { \
|
# define BURN_BUFFER(x, size) do { \
|
||||||
if ((x) != NULL) \
|
if ((x) != NULL) \
|
||||||
memset((x), '\0', (size))); __asm__ volatile("" : : "r"(&(x)) : "memory"); \
|
memset((x), '\0', (size)); __asm__ volatile("" : : "r"(&(x)) : "memory"); \
|
||||||
} while(0)
|
} while(0)
|
||||||
#endif /* HAVE_GCC_VOLATILE_MEMORY_PROTECTION */
|
#endif /* HAVE_GCC_VOLATILE_MEMORY_PROTECTION */
|
||||||
|
|
||||||
|
@ -53,6 +53,9 @@ void sha1(unsigned char *digest,int len,unsigned char *hash);
|
|||||||
void sha256(unsigned char *digest, int len, unsigned char *hash);
|
void sha256(unsigned char *digest, int len, unsigned char *hash);
|
||||||
|
|
||||||
void evp(int nid, unsigned char *digest, int len, unsigned char *hash, unsigned int *hlen);
|
void evp(int nid, unsigned char *digest, int len, unsigned char *hash, unsigned int *hlen);
|
||||||
|
EVPCTX evp_init(int nid);
|
||||||
|
void evp_update(EVPCTX ctx, const void *data, unsigned long len);
|
||||||
|
void evp_final(EVPCTX ctx, unsigned char *md, unsigned int *mdlen);
|
||||||
|
|
||||||
ssh_mac_ctx ssh_mac_ctx_init(enum ssh_mac_e type);
|
ssh_mac_ctx ssh_mac_ctx_init(enum ssh_mac_e type);
|
||||||
void ssh_mac_update(ssh_mac_ctx ctx, const void *data, unsigned long len);
|
void ssh_mac_update(ssh_mac_ctx ctx, const void *data, unsigned long len);
|
||||||
|
@ -115,6 +115,7 @@ set(libssh_SRCS
|
|||||||
client.c
|
client.c
|
||||||
config.c
|
config.c
|
||||||
connect.c
|
connect.c
|
||||||
|
curve25519.c
|
||||||
dh.c
|
dh.c
|
||||||
ecdh.c
|
ecdh.c
|
||||||
error.c
|
error.c
|
||||||
@ -204,12 +205,12 @@ if (WITH_GSSAPI AND GSSAPI_FOUND)
|
|||||||
)
|
)
|
||||||
endif (WITH_GSSAPI AND GSSAPI_FOUND)
|
endif (WITH_GSSAPI AND GSSAPI_FOUND)
|
||||||
|
|
||||||
if (WITH_NACL)
|
if (NOT WITH_NACL)
|
||||||
set(libssh_SRCS
|
set(libssh_SRCS
|
||||||
${libssh_SRCS}
|
${libssh_SRCS}
|
||||||
curve25519.c
|
curve25519_ref.c
|
||||||
)
|
)
|
||||||
endif (WITH_NACL)
|
endif (NOT WITH_NACL)
|
||||||
|
|
||||||
include_directories(
|
include_directories(
|
||||||
${LIBSSH_PUBLIC_INCLUDE_DIRS}
|
${LIBSSH_PUBLIC_INCLUDE_DIRS}
|
||||||
|
@ -355,7 +355,7 @@ int ssh_userauth_list(ssh_session session, const char *username)
|
|||||||
* later.
|
* later.
|
||||||
*
|
*
|
||||||
* @note Most server implementations do not permit changing the username during
|
* @note Most server implementations do not permit changing the username during
|
||||||
* authentication. The username should only be set with ssh_optoins_set() only
|
* authentication. The username should only be set with ssh_options_set() only
|
||||||
* before you connect to the server.
|
* before you connect to the server.
|
||||||
*/
|
*/
|
||||||
int ssh_userauth_none(ssh_session session, const char *username) {
|
int ssh_userauth_none(ssh_session session, const char *username) {
|
||||||
@ -478,7 +478,7 @@ fail:
|
|||||||
* later.
|
* later.
|
||||||
*
|
*
|
||||||
* @note Most server implementations do not permit changing the username during
|
* @note Most server implementations do not permit changing the username during
|
||||||
* authentication. The username should only be set with ssh_optoins_set() only
|
* authentication. The username should only be set with ssh_options_set() only
|
||||||
* before you connect to the server.
|
* before you connect to the server.
|
||||||
*/
|
*/
|
||||||
int ssh_userauth_try_publickey(ssh_session session,
|
int ssh_userauth_try_publickey(ssh_session session,
|
||||||
@ -640,7 +640,7 @@ fail:
|
|||||||
* later.
|
* later.
|
||||||
*
|
*
|
||||||
* @note Most server implementations do not permit changing the username during
|
* @note Most server implementations do not permit changing the username during
|
||||||
* authentication. The username should only be set with ssh_optoins_set() only
|
* authentication. The username should only be set with ssh_options_set() only
|
||||||
* before you connect to the server.
|
* before you connect to the server.
|
||||||
*/
|
*/
|
||||||
int ssh_userauth_publickey(ssh_session session,
|
int ssh_userauth_publickey(ssh_session session,
|
||||||
@ -961,7 +961,7 @@ struct ssh_agent_state_struct {
|
|||||||
* later.
|
* later.
|
||||||
*
|
*
|
||||||
* @note Most server implementations do not permit changing the username during
|
* @note Most server implementations do not permit changing the username during
|
||||||
* authentication. The username should only be set with ssh_optoins_set() only
|
* authentication. The username should only be set with ssh_options_set() only
|
||||||
* before you connect to the server.
|
* before you connect to the server.
|
||||||
*/
|
*/
|
||||||
int ssh_userauth_agent(ssh_session session,
|
int ssh_userauth_agent(ssh_session session,
|
||||||
@ -1083,7 +1083,7 @@ struct ssh_auth_auto_state_struct {
|
|||||||
* later.
|
* later.
|
||||||
*
|
*
|
||||||
* @note Most server implementations do not permit changing the username during
|
* @note Most server implementations do not permit changing the username during
|
||||||
* authentication. The username should only be set with ssh_optoins_set() only
|
* authentication. The username should only be set with ssh_options_set() only
|
||||||
* before you connect to the server.
|
* before you connect to the server.
|
||||||
*/
|
*/
|
||||||
int ssh_userauth_publickey_auto(ssh_session session,
|
int ssh_userauth_publickey_auto(ssh_session session,
|
||||||
@ -1297,7 +1297,7 @@ int ssh_userauth_publickey_auto(ssh_session session,
|
|||||||
* later.
|
* later.
|
||||||
*
|
*
|
||||||
* @note Most server implementations do not permit changing the username during
|
* @note Most server implementations do not permit changing the username during
|
||||||
* authentication. The username should only be set with ssh_optoins_set() only
|
* authentication. The username should only be set with ssh_options_set() only
|
||||||
* before you connect to the server.
|
* before you connect to the server.
|
||||||
*
|
*
|
||||||
* @see ssh_userauth_none()
|
* @see ssh_userauth_none()
|
||||||
|
@ -454,8 +454,7 @@ int ssh_bind_accept(ssh_bind sshbind, ssh_session session) {
|
|||||||
#else
|
#else
|
||||||
close(fd);
|
close(fd);
|
||||||
#endif
|
#endif
|
||||||
if (session->socket)
|
ssh_socket_free(session->socket);
|
||||||
ssh_socket_close(session->socket);
|
|
||||||
}
|
}
|
||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
@ -2089,7 +2089,7 @@ SSH_PACKET_CALLBACK(ssh_request_denied){
|
|||||||
static int ssh_global_request_termination(void *s){
|
static int ssh_global_request_termination(void *s){
|
||||||
ssh_session session = (ssh_session) s;
|
ssh_session session = (ssh_session) s;
|
||||||
if (session->global_req_state != SSH_CHANNEL_REQ_STATE_PENDING ||
|
if (session->global_req_state != SSH_CHANNEL_REQ_STATE_PENDING ||
|
||||||
session->session_state != SSH_SESSION_STATE_ERROR)
|
session->session_state == SSH_SESSION_STATE_ERROR)
|
||||||
return 1;
|
return 1;
|
||||||
else
|
else
|
||||||
return 0;
|
return 0;
|
||||||
@ -2117,43 +2117,66 @@ static int ssh_global_request_termination(void *s){
|
|||||||
static int global_request(ssh_session session, const char *request,
|
static int global_request(ssh_session session, const char *request,
|
||||||
ssh_buffer buffer, int reply) {
|
ssh_buffer buffer, int reply) {
|
||||||
ssh_string req = NULL;
|
ssh_string req = NULL;
|
||||||
int rc = SSH_ERROR;
|
int rc;
|
||||||
|
|
||||||
if(session->global_req_state != SSH_CHANNEL_REQ_STATE_NONE)
|
switch (session->global_req_state) {
|
||||||
|
case SSH_CHANNEL_REQ_STATE_NONE:
|
||||||
|
break;
|
||||||
|
default:
|
||||||
goto pending;
|
goto pending;
|
||||||
|
}
|
||||||
|
|
||||||
|
rc = buffer_add_u8(session->out_buffer, SSH2_MSG_GLOBAL_REQUEST);
|
||||||
|
if (rc < 0) {
|
||||||
|
goto error;
|
||||||
|
}
|
||||||
|
|
||||||
req = ssh_string_from_char(request);
|
req = ssh_string_from_char(request);
|
||||||
if (req == NULL) {
|
if (req == NULL) {
|
||||||
ssh_set_error_oom(session);
|
ssh_set_error_oom(session);
|
||||||
goto error;
|
rc = SSH_ERROR;
|
||||||
|
goto error;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (buffer_add_u8(session->out_buffer, SSH2_MSG_GLOBAL_REQUEST) < 0 ||
|
rc = buffer_add_ssh_string(session->out_buffer, req);
|
||||||
buffer_add_ssh_string(session->out_buffer, req) < 0 ||
|
|
||||||
buffer_add_u8(session->out_buffer, reply == 0 ? 0 : 1) < 0) {
|
|
||||||
ssh_set_error_oom(session);
|
|
||||||
goto error;
|
|
||||||
}
|
|
||||||
ssh_string_free(req);
|
ssh_string_free(req);
|
||||||
req=NULL;
|
if (rc < 0) {
|
||||||
|
ssh_set_error_oom(session);
|
||||||
|
rc = SSH_ERROR;
|
||||||
|
goto error;
|
||||||
|
}
|
||||||
|
|
||||||
|
rc = buffer_add_u8(session->out_buffer, reply == 0 ? 0 : 1);
|
||||||
|
if (rc < 0) {
|
||||||
|
ssh_set_error_oom(session);
|
||||||
|
rc = SSH_ERROR;
|
||||||
|
goto error;
|
||||||
|
}
|
||||||
|
|
||||||
if (buffer != NULL) {
|
if (buffer != NULL) {
|
||||||
if (buffer_add_data(session->out_buffer, buffer_get_rest(buffer),
|
rc = buffer_add_data(session->out_buffer,
|
||||||
buffer_get_rest_len(buffer)) < 0) {
|
buffer_get_rest(buffer),
|
||||||
ssh_set_error_oom(session);
|
buffer_get_rest_len(buffer));
|
||||||
goto error;
|
if (rc < 0) {
|
||||||
}
|
ssh_set_error_oom(session);
|
||||||
|
rc = SSH_ERROR;
|
||||||
|
goto error;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
session->global_req_state = SSH_CHANNEL_REQ_STATE_PENDING;
|
session->global_req_state = SSH_CHANNEL_REQ_STATE_PENDING;
|
||||||
if (packet_send(session) == SSH_ERROR) {
|
rc = packet_send(session);
|
||||||
return rc;
|
if (rc == SSH_ERROR) {
|
||||||
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
SSH_LOG(SSH_LOG_PACKET,
|
SSH_LOG(SSH_LOG_PACKET,
|
||||||
"Sent a SSH_MSG_GLOBAL_REQUEST %s", request);
|
"Sent a SSH_MSG_GLOBAL_REQUEST %s", request);
|
||||||
if (reply == 0) {
|
|
||||||
session->global_req_state=SSH_CHANNEL_REQ_STATE_NONE;
|
|
||||||
|
|
||||||
return SSH_OK;
|
if (reply == 0) {
|
||||||
|
session->global_req_state = SSH_CHANNEL_REQ_STATE_NONE;
|
||||||
|
|
||||||
|
return SSH_OK;
|
||||||
}
|
}
|
||||||
pending:
|
pending:
|
||||||
rc = ssh_handle_packets_termination(session,
|
rc = ssh_handle_packets_termination(session,
|
||||||
@ -2178,16 +2201,16 @@ pending:
|
|||||||
break;
|
break;
|
||||||
case SSH_CHANNEL_REQ_STATE_ERROR:
|
case SSH_CHANNEL_REQ_STATE_ERROR:
|
||||||
case SSH_CHANNEL_REQ_STATE_NONE:
|
case SSH_CHANNEL_REQ_STATE_NONE:
|
||||||
rc=SSH_ERROR;
|
rc = SSH_ERROR;
|
||||||
break;
|
break;
|
||||||
case SSH_CHANNEL_REQ_STATE_PENDING:
|
case SSH_CHANNEL_REQ_STATE_PENDING:
|
||||||
rc=SSH_AGAIN;
|
return SSH_AGAIN;
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
|
session->global_req_state = SSH_CHANNEL_REQ_STATE_NONE;
|
||||||
|
|
||||||
return rc;
|
return rc;
|
||||||
error:
|
error:
|
||||||
ssh_string_free(req);
|
buffer_reinit(session->out_buffer);
|
||||||
|
|
||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
@ -3325,17 +3348,18 @@ error:
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Send the exit status to the remote process (as described in RFC 4254, section 6.10).
|
* @brief Send the exit status to the remote process
|
||||||
*
|
*
|
||||||
* Sends the exit status to the remote process.
|
* Sends the exit status to the remote process (as described in RFC 4254,
|
||||||
|
* section 6.10).
|
||||||
* Only SSH-v2 is supported (I'm not sure about SSH-v1).
|
* Only SSH-v2 is supported (I'm not sure about SSH-v1).
|
||||||
*
|
*
|
||||||
* @param[in] channel The channel to send exit status.
|
* @param[in] channel The channel to send exit status.
|
||||||
*
|
*
|
||||||
* @param[in] sig The exit status to send
|
* @param[in] exit_status The exit status to send
|
||||||
*
|
*
|
||||||
* @return SSH_OK on success, SSH_ERROR if an error occurred
|
* @return SSH_OK on success, SSH_ERROR if an error occurred.
|
||||||
* (including attempts to send exit status via SSH-v1 session).
|
* (including attempts to send exit status via SSH-v1 session).
|
||||||
*/
|
*/
|
||||||
int ssh_channel_request_send_exit_status(ssh_channel channel, int exit_status) {
|
int ssh_channel_request_send_exit_status(ssh_channel channel, int exit_status) {
|
||||||
ssh_buffer buffer = NULL;
|
ssh_buffer buffer = NULL;
|
||||||
|
@ -105,14 +105,18 @@ static int callback_receive_banner(const void *data, size_t len, void *user) {
|
|||||||
ssh_pcap_context_write(session->pcap_ctx,SSH_PCAP_DIR_IN,buffer,i+1,i+1);
|
ssh_pcap_context_write(session->pcap_ctx,SSH_PCAP_DIR_IN,buffer,i+1,i+1);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
if(buffer[i]=='\r')
|
if(buffer[i]=='\r') {
|
||||||
buffer[i]='\0';
|
buffer[i]='\0';
|
||||||
if(buffer[i]=='\n'){
|
}
|
||||||
buffer[i]='\0';
|
if (buffer[i]=='\n') {
|
||||||
str=strdup(buffer);
|
buffer[i] = '\0';
|
||||||
/* number of bytes read */
|
str = strdup(buffer);
|
||||||
ret=i+1;
|
if (str == NULL) {
|
||||||
session->serverbanner=str;
|
return SSH_ERROR;
|
||||||
|
}
|
||||||
|
/* number of bytes read */
|
||||||
|
ret = i + 1;
|
||||||
|
session->serverbanner = str;
|
||||||
session->session_state=SSH_SESSION_STATE_BANNER_RECEIVED;
|
session->session_state=SSH_SESSION_STATE_BANNER_RECEIVED;
|
||||||
SSH_LOG(SSH_LOG_PACKET,"Received banner: %s",str);
|
SSH_LOG(SSH_LOG_PACKET,"Received banner: %s",str);
|
||||||
session->ssh_connection_callback(session);
|
session->ssh_connection_callback(session);
|
||||||
@ -529,7 +533,7 @@ pending:
|
|||||||
if (timeout == 0) {
|
if (timeout == 0) {
|
||||||
timeout = 10 * 1000;
|
timeout = 10 * 1000;
|
||||||
}
|
}
|
||||||
SSH_LOG(SSH_LOG_PACKET,"ssh_connect: Actual timeout : %d", timeout);
|
SSH_LOG(SSH_LOG_PACKET,"Actual timeout : %d", timeout);
|
||||||
ret = ssh_handle_packets_termination(session, timeout, ssh_connect_termination, session);
|
ret = ssh_handle_packets_termination(session, timeout, ssh_connect_termination, session);
|
||||||
if (ret == SSH_ERROR || !ssh_connect_termination(session)) {
|
if (ret == SSH_ERROR || !ssh_connect_termination(session)) {
|
||||||
ssh_set_error(session, SSH_FATAL,
|
ssh_set_error(session, SSH_FATAL,
|
||||||
@ -546,7 +550,7 @@ pending:
|
|||||||
session->session_state = SSH_SESSION_STATE_ERROR;
|
session->session_state = SSH_SESSION_STATE_ERROR;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
SSH_LOG(SSH_LOG_PACKET,"ssh_connect: Actual state : %d",session->session_state);
|
SSH_LOG(SSH_LOG_PACKET,"current state : %d",session->session_state);
|
||||||
if(!ssh_is_blocking(session) && !ssh_connect_termination(session)){
|
if(!ssh_is_blocking(session) && !ssh_connect_termination(session)){
|
||||||
return SSH_AGAIN;
|
return SSH_AGAIN;
|
||||||
}
|
}
|
||||||
|
@ -436,6 +436,7 @@ static int ssh_select_cb (socket_t fd, int revents, void *userdata){
|
|||||||
*/
|
*/
|
||||||
int ssh_select(ssh_channel *channels, ssh_channel *outchannels, socket_t maxfd,
|
int ssh_select(ssh_channel *channels, ssh_channel *outchannels, socket_t maxfd,
|
||||||
fd_set *readfds, struct timeval *timeout) {
|
fd_set *readfds, struct timeval *timeout) {
|
||||||
|
fd_set origfds;
|
||||||
socket_t fd;
|
socket_t fd;
|
||||||
int i,j;
|
int i,j;
|
||||||
int rc;
|
int rc;
|
||||||
@ -449,9 +450,11 @@ int ssh_select(ssh_channel *channels, ssh_channel *outchannels, socket_t maxfd,
|
|||||||
ssh_event_add_session(event, channels[i]->session);
|
ssh_event_add_session(event, channels[i]->session);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
FD_ZERO(&origfds);
|
||||||
for (fd = 0; fd < maxfd ; fd++) {
|
for (fd = 0; fd < maxfd ; fd++) {
|
||||||
if (FD_ISSET(fd, readfds)) {
|
if (FD_ISSET(fd, readfds)) {
|
||||||
ssh_event_add_fd(event, fd, POLLIN, ssh_select_cb, readfds);
|
ssh_event_add_fd(event, fd, POLLIN, ssh_select_cb, readfds);
|
||||||
|
FD_SET(fd, &origfds);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
outchannels[0] = NULL;
|
outchannels[0] = NULL;
|
||||||
@ -485,13 +488,17 @@ int ssh_select(ssh_channel *channels, ssh_channel *outchannels, socket_t maxfd,
|
|||||||
/* since there's nothing, let's fire the polling */
|
/* since there's nothing, let's fire the polling */
|
||||||
rc = ssh_event_dopoll(event,tm);
|
rc = ssh_event_dopoll(event,tm);
|
||||||
if (rc == SSH_ERROR){
|
if (rc == SSH_ERROR){
|
||||||
ssh_event_free(event);
|
goto out;
|
||||||
return SSH_ERROR;
|
|
||||||
}
|
}
|
||||||
tm = ssh_timeout_update(&ts, base_tm);
|
tm = ssh_timeout_update(&ts, base_tm);
|
||||||
firstround=0;
|
firstround=0;
|
||||||
} while (1);
|
} while (1);
|
||||||
out:
|
out:
|
||||||
|
for (fd = 0; fd < maxfd; fd++) {
|
||||||
|
if (FD_ISSET(fd, &origfds)) {
|
||||||
|
ssh_event_remove_fd(event, fd);
|
||||||
|
}
|
||||||
|
}
|
||||||
ssh_event_free(event);
|
ssh_event_free(event);
|
||||||
return SSH_OK;
|
return SSH_OK;
|
||||||
}
|
}
|
||||||
|
@ -26,7 +26,10 @@
|
|||||||
#include "libssh/curve25519.h"
|
#include "libssh/curve25519.h"
|
||||||
#ifdef HAVE_CURVE25519
|
#ifdef HAVE_CURVE25519
|
||||||
|
|
||||||
|
#ifdef WITH_NACL
|
||||||
#include "nacl/crypto_scalarmult_curve25519.h"
|
#include "nacl/crypto_scalarmult_curve25519.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
#include "libssh/ssh2.h"
|
#include "libssh/ssh2.h"
|
||||||
#include "libssh/buffer.h"
|
#include "libssh/buffer.h"
|
||||||
#include "libssh/priv.h"
|
#include "libssh/priv.h"
|
||||||
@ -53,7 +56,7 @@ int ssh_client_curve25519_init(ssh_session session){
|
|||||||
return SSH_ERROR;
|
return SSH_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
crypto_scalarmult_curve25519_base(session->next_crypto->curve25519_client_pubkey,
|
crypto_scalarmult_base(session->next_crypto->curve25519_client_pubkey,
|
||||||
session->next_crypto->curve25519_privkey);
|
session->next_crypto->curve25519_privkey);
|
||||||
client_pubkey = ssh_string_new(CURVE25519_PUBKEY_SIZE);
|
client_pubkey = ssh_string_new(CURVE25519_PUBKEY_SIZE);
|
||||||
if (client_pubkey == NULL) {
|
if (client_pubkey == NULL) {
|
||||||
@ -81,10 +84,10 @@ static int ssh_curve25519_build_k(ssh_session session) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (session->server)
|
if (session->server)
|
||||||
crypto_scalarmult_curve25519(k, session->next_crypto->curve25519_privkey,
|
crypto_scalarmult(k, session->next_crypto->curve25519_privkey,
|
||||||
session->next_crypto->curve25519_client_pubkey);
|
session->next_crypto->curve25519_client_pubkey);
|
||||||
else
|
else
|
||||||
crypto_scalarmult_curve25519(k, session->next_crypto->curve25519_privkey,
|
crypto_scalarmult(k, session->next_crypto->curve25519_privkey,
|
||||||
session->next_crypto->curve25519_server_pubkey);
|
session->next_crypto->curve25519_server_pubkey);
|
||||||
|
|
||||||
BN_bin2bn(k, CURVE25519_PUBKEY_SIZE, session->next_crypto->k);
|
BN_bin2bn(k, CURVE25519_PUBKEY_SIZE, session->next_crypto->k);
|
||||||
@ -125,7 +128,7 @@ int ssh_client_curve25519_reply(ssh_session session, ssh_buffer packet){
|
|||||||
}
|
}
|
||||||
if (ssh_string_len(q_s_string) != CURVE25519_PUBKEY_SIZE){
|
if (ssh_string_len(q_s_string) != CURVE25519_PUBKEY_SIZE){
|
||||||
ssh_set_error(session, SSH_FATAL, "Incorrect size for server Curve25519 public key: %d",
|
ssh_set_error(session, SSH_FATAL, "Incorrect size for server Curve25519 public key: %d",
|
||||||
ssh_string_len(q_s_string));
|
(int)ssh_string_len(q_s_string));
|
||||||
ssh_string_free(q_s_string);
|
ssh_string_free(q_s_string);
|
||||||
goto error;
|
goto error;
|
||||||
}
|
}
|
||||||
@ -179,7 +182,7 @@ int ssh_server_curve25519_init(ssh_session session, ssh_buffer packet){
|
|||||||
}
|
}
|
||||||
if (ssh_string_len(q_c_string) != CURVE25519_PUBKEY_SIZE){
|
if (ssh_string_len(q_c_string) != CURVE25519_PUBKEY_SIZE){
|
||||||
ssh_set_error(session, SSH_FATAL, "Incorrect size for server Curve25519 public key: %d",
|
ssh_set_error(session, SSH_FATAL, "Incorrect size for server Curve25519 public key: %d",
|
||||||
ssh_string_len(q_c_string));
|
(int)ssh_string_len(q_c_string));
|
||||||
ssh_string_free(q_c_string);
|
ssh_string_free(q_c_string);
|
||||||
return SSH_ERROR;
|
return SSH_ERROR;
|
||||||
}
|
}
|
||||||
@ -195,7 +198,7 @@ int ssh_server_curve25519_init(ssh_session session, ssh_buffer packet){
|
|||||||
return SSH_ERROR;
|
return SSH_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
crypto_scalarmult_curve25519_base(session->next_crypto->curve25519_server_pubkey,
|
crypto_scalarmult_base(session->next_crypto->curve25519_server_pubkey,
|
||||||
session->next_crypto->curve25519_privkey);
|
session->next_crypto->curve25519_privkey);
|
||||||
|
|
||||||
q_s_string = ssh_string_new(CURVE25519_PUBKEY_SIZE);
|
q_s_string = ssh_string_new(CURVE25519_PUBKEY_SIZE);
|
||||||
|
235
libssh/src/dh.c
235
libssh/src/dh.c
@ -239,63 +239,6 @@ void ssh_print_bignum(const char *which, bignum num) {
|
|||||||
SAFE_FREE(hex);
|
SAFE_FREE(hex);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Convert a buffer into a colon separated hex string.
|
|
||||||
* The caller has to free the memory.
|
|
||||||
*
|
|
||||||
* @param what What should be converted to a hex string.
|
|
||||||
*
|
|
||||||
* @param len Length of the buffer to convert.
|
|
||||||
*
|
|
||||||
* @return The hex string or NULL on error.
|
|
||||||
*
|
|
||||||
* @see ssh_string_free_char()
|
|
||||||
*/
|
|
||||||
char *ssh_get_hexa(const unsigned char *what, size_t len) {
|
|
||||||
const char h[] = "0123456789abcdef";
|
|
||||||
char *hexa;
|
|
||||||
size_t i;
|
|
||||||
size_t hlen = len * 3;
|
|
||||||
|
|
||||||
if (len > (UINT_MAX - 1) / 3) {
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
hexa = malloc(hlen + 1);
|
|
||||||
if (hexa == NULL) {
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
for (i = 0; i < len; i++) {
|
|
||||||
hexa[i * 3] = h[(what[i] >> 4) & 0xF];
|
|
||||||
hexa[i * 3 + 1] = h[what[i] & 0xF];
|
|
||||||
hexa[i * 3 + 2] = ':';
|
|
||||||
}
|
|
||||||
hexa[hlen - 1] = '\0';
|
|
||||||
|
|
||||||
return hexa;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Print a buffer as colon separated hex string.
|
|
||||||
*
|
|
||||||
* @param descr Description printed in front of the hex string.
|
|
||||||
*
|
|
||||||
* @param what What should be converted to a hex string.
|
|
||||||
*
|
|
||||||
* @param len Length of the buffer to convert.
|
|
||||||
*/
|
|
||||||
void ssh_print_hexa(const char *descr, const unsigned char *what, size_t len) {
|
|
||||||
char *hexa = ssh_get_hexa(what, len);
|
|
||||||
|
|
||||||
if (hexa == NULL) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
printf("%s: %s\n", descr, hexa);
|
|
||||||
|
|
||||||
free(hexa);
|
|
||||||
}
|
|
||||||
|
|
||||||
int dh_generate_x(ssh_session session) {
|
int dh_generate_x(ssh_session session) {
|
||||||
session->next_crypto->x = bignum_new();
|
session->next_crypto->x = bignum_new();
|
||||||
if (session->next_crypto->x == NULL) {
|
if (session->next_crypto->x == NULL) {
|
||||||
@ -1047,25 +990,7 @@ error:
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Allocates a buffer with the MD5 hash of the server public key.
|
* @deprecated Use ssh_get_publickey_hash()
|
||||||
*
|
|
||||||
* This function allows you to get a MD5 hash of the public key. You can then
|
|
||||||
* print this hash in a human-readable form to the user so that he is able to
|
|
||||||
* verify it. Use ssh_get_hexa() or ssh_print_hexa() to display it.
|
|
||||||
*
|
|
||||||
* @param[in] session The SSH session to use.
|
|
||||||
*
|
|
||||||
* @param[in] hash The buffer to allocate.
|
|
||||||
*
|
|
||||||
* @return The bytes allocated or < 0 on error.
|
|
||||||
*
|
|
||||||
* @warning It is very important that you verify at some moment that the hash
|
|
||||||
* matches a known server. If you don't do it, cryptography wont help
|
|
||||||
* you at making things secure
|
|
||||||
*
|
|
||||||
* @see ssh_is_server_known()
|
|
||||||
* @see ssh_get_hexa()
|
|
||||||
* @see ssh_print_hexa()
|
|
||||||
*/
|
*/
|
||||||
int ssh_get_pubkey_hash(ssh_session session, unsigned char **hash) {
|
int ssh_get_pubkey_hash(ssh_session session, unsigned char **hash) {
|
||||||
ssh_string pubkey;
|
ssh_string pubkey;
|
||||||
@ -1142,6 +1067,164 @@ int ssh_get_publickey(ssh_session session, ssh_key *key)
|
|||||||
key);
|
key);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Allocates a buffer with the hash of the public key.
|
||||||
|
*
|
||||||
|
* This function allows you to get a hash of the public key. You can then
|
||||||
|
* print this hash in a human-readable form to the user so that he is able to
|
||||||
|
* verify it. Use ssh_get_hexa() or ssh_print_hexa() to display it.
|
||||||
|
*
|
||||||
|
* @param[in] key The public key to create the hash for.
|
||||||
|
*
|
||||||
|
* @param[in] type The type of the hash you want.
|
||||||
|
*
|
||||||
|
* @param[in] hash A pointer to store the allocated buffer. It can be
|
||||||
|
* freed using ssh_clean_pubkey_hash().
|
||||||
|
*
|
||||||
|
* @param[in] hlen The length of the hash.
|
||||||
|
*
|
||||||
|
* @return 0 on success, -1 if an error occured.
|
||||||
|
*
|
||||||
|
* @warning It is very important that you verify at some moment that the hash
|
||||||
|
* matches a known server. If you don't do it, cryptography wont help
|
||||||
|
* you at making things secure.
|
||||||
|
* OpenSSH uses SHA1 to print public key digests.
|
||||||
|
*
|
||||||
|
* @see ssh_is_server_known()
|
||||||
|
* @see ssh_get_hexa()
|
||||||
|
* @see ssh_print_hexa()
|
||||||
|
* @see ssh_clean_pubkey_hash()
|
||||||
|
*/
|
||||||
|
int ssh_get_publickey_hash(const ssh_key key,
|
||||||
|
enum ssh_publickey_hash_type type,
|
||||||
|
unsigned char **hash,
|
||||||
|
size_t *hlen)
|
||||||
|
{
|
||||||
|
ssh_string blob;
|
||||||
|
unsigned char *h;
|
||||||
|
int rc;
|
||||||
|
|
||||||
|
rc = ssh_pki_export_pubkey_blob(key, &blob);
|
||||||
|
if (rc < 0) {
|
||||||
|
return rc;
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (type) {
|
||||||
|
case SSH_PUBLICKEY_HASH_SHA1:
|
||||||
|
{
|
||||||
|
SHACTX ctx;
|
||||||
|
|
||||||
|
h = malloc(SHA_DIGEST_LEN);
|
||||||
|
if (h == NULL) {
|
||||||
|
rc = -1;
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
|
||||||
|
ctx = sha1_init();
|
||||||
|
if (ctx == NULL) {
|
||||||
|
free(h);
|
||||||
|
rc = -1;
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
|
||||||
|
sha1_update(ctx, ssh_string_data(blob), ssh_string_len(blob));
|
||||||
|
sha1_final(h, ctx);
|
||||||
|
|
||||||
|
*hlen = SHA_DIGEST_LEN;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case SSH_PUBLICKEY_HASH_MD5:
|
||||||
|
{
|
||||||
|
MD5CTX ctx;
|
||||||
|
|
||||||
|
h = malloc(MD5_DIGEST_LEN);
|
||||||
|
if (h == NULL) {
|
||||||
|
rc = -1;
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
|
||||||
|
ctx = md5_init();
|
||||||
|
if (ctx == NULL) {
|
||||||
|
free(h);
|
||||||
|
rc = -1;
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
|
||||||
|
md5_update(ctx, ssh_string_data(blob), ssh_string_len(blob));
|
||||||
|
md5_final(h, ctx);
|
||||||
|
|
||||||
|
*hlen = MD5_DIGEST_LEN;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
rc = -1;
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
|
||||||
|
*hash = h;
|
||||||
|
rc = 0;
|
||||||
|
out:
|
||||||
|
ssh_string_free(blob);
|
||||||
|
return rc;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Convert a buffer into a colon separated hex string.
|
||||||
|
* The caller has to free the memory.
|
||||||
|
*
|
||||||
|
* @param what What should be converted to a hex string.
|
||||||
|
*
|
||||||
|
* @param len Length of the buffer to convert.
|
||||||
|
*
|
||||||
|
* @return The hex string or NULL on error.
|
||||||
|
*
|
||||||
|
* @see ssh_string_free_char()
|
||||||
|
*/
|
||||||
|
char *ssh_get_hexa(const unsigned char *what, size_t len) {
|
||||||
|
const char h[] = "0123456789abcdef";
|
||||||
|
char *hexa;
|
||||||
|
size_t i;
|
||||||
|
size_t hlen = len * 3;
|
||||||
|
|
||||||
|
if (len > (UINT_MAX - 1) / 3) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
hexa = malloc(hlen + 1);
|
||||||
|
if (hexa == NULL) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (i = 0; i < len; i++) {
|
||||||
|
hexa[i * 3] = h[(what[i] >> 4) & 0xF];
|
||||||
|
hexa[i * 3 + 1] = h[what[i] & 0xF];
|
||||||
|
hexa[i * 3 + 2] = ':';
|
||||||
|
}
|
||||||
|
hexa[hlen - 1] = '\0';
|
||||||
|
|
||||||
|
return hexa;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Print a buffer as colon separated hex string.
|
||||||
|
*
|
||||||
|
* @param descr Description printed in front of the hex string.
|
||||||
|
*
|
||||||
|
* @param what What should be converted to a hex string.
|
||||||
|
*
|
||||||
|
* @param len Length of the buffer to convert.
|
||||||
|
*/
|
||||||
|
void ssh_print_hexa(const char *descr, const unsigned char *what, size_t len) {
|
||||||
|
char *hexa = ssh_get_hexa(what, len);
|
||||||
|
|
||||||
|
if (hexa == NULL) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
printf("%s: %s\n", descr, hexa);
|
||||||
|
|
||||||
|
free(hexa);
|
||||||
|
}
|
||||||
|
|
||||||
/** @} */
|
/** @} */
|
||||||
|
|
||||||
/* vim: set ts=4 sw=4 et cindent: */
|
/* vim: set ts=4 sw=4 et cindent: */
|
||||||
|
@ -123,6 +123,30 @@ void evp(int nid, unsigned char *digest, int len, unsigned char *hash, unsigned
|
|||||||
EVP_DigestUpdate(&md, digest, len);
|
EVP_DigestUpdate(&md, digest, len);
|
||||||
EVP_DigestFinal(&md, hash, hlen);
|
EVP_DigestFinal(&md, hash, hlen);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
EVPCTX evp_init(int nid)
|
||||||
|
{
|
||||||
|
const EVP_MD *evp_md = nid_to_evpmd(nid);
|
||||||
|
|
||||||
|
EVPCTX ctx = malloc(sizeof(EVP_MD_CTX));
|
||||||
|
if (ctx == NULL) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
EVP_DigestInit(ctx, evp_md);
|
||||||
|
|
||||||
|
return ctx;
|
||||||
|
}
|
||||||
|
|
||||||
|
void evp_update(EVPCTX ctx, const void *data, unsigned long len)
|
||||||
|
{
|
||||||
|
EVP_DigestUpdate(ctx, data, len);
|
||||||
|
}
|
||||||
|
|
||||||
|
void evp_final(EVPCTX ctx, unsigned char *md, unsigned int *mdlen)
|
||||||
|
{
|
||||||
|
EVP_DigestFinal(ctx, md, mdlen);
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
SHA256CTX sha256_init(void){
|
SHA256CTX sha256_init(void){
|
||||||
|
@ -65,7 +65,7 @@ static int current_timestring(int hires, char *buf, size_t len)
|
|||||||
|
|
||||||
if (hires) {
|
if (hires) {
|
||||||
strftime(tbuf, sizeof(tbuf) - 1, "%Y/%m/%d %H:%M:%S", tm);
|
strftime(tbuf, sizeof(tbuf) - 1, "%Y/%m/%d %H:%M:%S", tm);
|
||||||
snprintf(buf, len, "%s.%06ld", tbuf, tv.tv_usec);
|
snprintf(buf, len, "%s.%06ld", tbuf, (long)tv.tv_usec);
|
||||||
} else {
|
} else {
|
||||||
strftime(tbuf, sizeof(tbuf) - 1, "%Y/%m/%d %H:%M:%S", tm);
|
strftime(tbuf, sizeof(tbuf) - 1, "%Y/%m/%d %H:%M:%S", tm);
|
||||||
snprintf(buf, len, "%s", tbuf);
|
snprintf(buf, len, "%s", tbuf);
|
||||||
|
@ -120,10 +120,18 @@ static int ssh_execute_server_request(ssh_session session, ssh_message msg)
|
|||||||
msg->auth_request.username, msg->auth_request.pubkey,
|
msg->auth_request.username, msg->auth_request.pubkey,
|
||||||
msg->auth_request.signature_state,
|
msg->auth_request.signature_state,
|
||||||
session->server_callbacks->userdata);
|
session->server_callbacks->userdata);
|
||||||
if (rc == SSH_AUTH_SUCCESS || rc == SSH_AUTH_PARTIAL){
|
if (msg->auth_request.signature_state != SSH_PUBLICKEY_STATE_NONE) {
|
||||||
|
if (rc == SSH_AUTH_SUCCESS || rc == SSH_AUTH_PARTIAL) {
|
||||||
ssh_message_auth_reply_success(msg, rc == SSH_AUTH_PARTIAL);
|
ssh_message_auth_reply_success(msg, rc == SSH_AUTH_PARTIAL);
|
||||||
} else {
|
} else {
|
||||||
ssh_message_reply_default(msg);
|
ssh_message_reply_default(msg);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (rc == SSH_AUTH_SUCCESS) {
|
||||||
|
ssh_message_auth_reply_pk_ok_simple(msg);
|
||||||
|
} else {
|
||||||
|
ssh_message_reply_default(msg);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return SSH_OK;
|
return SSH_OK;
|
||||||
@ -301,10 +309,8 @@ static int ssh_execute_server_callbacks(ssh_session session, ssh_message msg){
|
|||||||
|
|
||||||
if (session->server_callbacks != NULL){
|
if (session->server_callbacks != NULL){
|
||||||
rc = ssh_execute_server_request(session, msg);
|
rc = ssh_execute_server_request(session, msg);
|
||||||
}
|
} else if (session->common.callbacks != NULL) {
|
||||||
|
/* This one is in fact a client callback... */
|
||||||
/* This one is in fact a client callback... */
|
|
||||||
if (session->common.callbacks != NULL) {
|
|
||||||
rc = ssh_execute_client_request(session, msg);
|
rc = ssh_execute_client_request(session, msg);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -856,6 +856,11 @@ int ssh_options_get_port(ssh_session session, unsigned int* port_target) {
|
|||||||
* It may include "%s" which will be replaced by the
|
* It may include "%s" which will be replaced by the
|
||||||
* user home directory.
|
* user home directory.
|
||||||
*
|
*
|
||||||
|
* - SSH_OPTIONS_PROXYCOMMAND:
|
||||||
|
* Get the proxycommand necessary to log into the
|
||||||
|
* remote host. When not explicitly set, it will be read
|
||||||
|
* from the ~/.ssh/config file.
|
||||||
|
*
|
||||||
* @param value The value to get into. As a char**, space will be
|
* @param value The value to get into. As a char**, space will be
|
||||||
* allocated by the function for the value, it is
|
* allocated by the function for the value, it is
|
||||||
* your responsibility to free the memory using
|
* your responsibility to free the memory using
|
||||||
@ -894,6 +899,10 @@ int ssh_options_get(ssh_session session, enum ssh_options_e type, char** value)
|
|||||||
src = ssh_iterator_value(char *, it);
|
src = ssh_iterator_value(char *, it);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
case SSH_OPTIONS_PROXYCOMMAND: {
|
||||||
|
src = session->opts.ProxyCommand;
|
||||||
|
break;
|
||||||
|
}
|
||||||
default:
|
default:
|
||||||
ssh_set_error(session, SSH_REQUEST_DENIED, "Unknown ssh option %d", type);
|
ssh_set_error(session, SSH_REQUEST_DENIED, "Unknown ssh option %d", type);
|
||||||
return SSH_ERROR;
|
return SSH_ERROR;
|
||||||
@ -1245,7 +1254,7 @@ static int ssh_bind_options_set_algo(ssh_bind sshbind, int algo,
|
|||||||
/**
|
/**
|
||||||
* @brief This function can set all possible ssh bind options.
|
* @brief This function can set all possible ssh bind options.
|
||||||
*
|
*
|
||||||
* @param session An allocated ssh option structure.
|
* @param sshbind An allocated ssh bind structure.
|
||||||
*
|
*
|
||||||
* @param type The option type to set. This could be one of the
|
* @param type The option type to set. This could be one of the
|
||||||
* following:
|
* following:
|
||||||
|
@ -1118,7 +1118,7 @@ int ssh_pki_export_signature_blob(const ssh_signature sig,
|
|||||||
return SSH_ERROR;
|
return SSH_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
str = ssh_string_from_char(ssh_key_type_to_char(sig->type));
|
str = ssh_string_from_char(sig->type_c);
|
||||||
if (str == NULL) {
|
if (str == NULL) {
|
||||||
ssh_buffer_free(buf);
|
ssh_buffer_free(buf);
|
||||||
return SSH_ERROR;
|
return SSH_ERROR;
|
||||||
@ -1271,11 +1271,9 @@ ssh_string ssh_pki_do_sign(ssh_session session,
|
|||||||
struct ssh_crypto_struct *crypto =
|
struct ssh_crypto_struct *crypto =
|
||||||
session->current_crypto ? session->current_crypto :
|
session->current_crypto ? session->current_crypto :
|
||||||
session->next_crypto;
|
session->next_crypto;
|
||||||
unsigned char hash[SHA_DIGEST_LEN] = {0};
|
|
||||||
ssh_signature sig;
|
ssh_signature sig;
|
||||||
ssh_string sig_blob;
|
ssh_string sig_blob;
|
||||||
ssh_string session_id;
|
ssh_string session_id;
|
||||||
SHACTX ctx;
|
|
||||||
int rc;
|
int rc;
|
||||||
|
|
||||||
if (privkey == NULL || !ssh_key_is_private(privkey)) {
|
if (privkey == NULL || !ssh_key_is_private(privkey)) {
|
||||||
@ -1287,24 +1285,46 @@ ssh_string ssh_pki_do_sign(ssh_session session,
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
ssh_string_fill(session_id, crypto->session_id, crypto->digest_len);
|
ssh_string_fill(session_id, crypto->session_id, crypto->digest_len);
|
||||||
/* TODO: change when supporting ECDSA keys */
|
|
||||||
ctx = sha1_init();
|
|
||||||
if (ctx == NULL) {
|
|
||||||
ssh_string_free(session_id);
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
sha1_update(ctx, session_id, ssh_string_len(session_id) + 4);
|
if (privkey->type == SSH_KEYTYPE_ECDSA) {
|
||||||
ssh_string_free(session_id);
|
#ifdef HAVE_ECC
|
||||||
|
unsigned char ehash[EVP_DIGEST_LEN] = {0};
|
||||||
|
uint32_t elen;
|
||||||
|
EVPCTX ctx;
|
||||||
|
|
||||||
sha1_update(ctx, buffer_get_rest(sigbuf), buffer_get_rest_len(sigbuf));
|
ctx = evp_init(privkey->ecdsa_nid);
|
||||||
sha1_final(hash, ctx);
|
if (ctx == NULL) {
|
||||||
|
ssh_string_free(session_id);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
evp_update(ctx, session_id, ssh_string_len(session_id) + 4);
|
||||||
|
evp_update(ctx, buffer_get_rest(sigbuf), buffer_get_rest_len(sigbuf));
|
||||||
|
evp_final(ctx, ehash, &elen);
|
||||||
|
|
||||||
|
sig = pki_do_sign(privkey, ehash, elen);
|
||||||
|
#endif
|
||||||
|
} else {
|
||||||
|
unsigned char hash[SHA_DIGEST_LEN] = {0};
|
||||||
|
SHACTX ctx;
|
||||||
|
|
||||||
|
ctx = sha1_init();
|
||||||
|
if (ctx == NULL) {
|
||||||
|
ssh_string_free(session_id);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
sha1_update(ctx, session_id, ssh_string_len(session_id) + 4);
|
||||||
|
sha1_update(ctx, buffer_get_rest(sigbuf), buffer_get_rest_len(sigbuf));
|
||||||
|
sha1_final(hash, ctx);
|
||||||
|
|
||||||
#ifdef DEBUG_CRYPTO
|
#ifdef DEBUG_CRYPTO
|
||||||
ssh_print_hexa("Hash being signed", hash, SHA_DIGEST_LEN);
|
ssh_print_hexa("Hash being signed", hash, SHA_DIGEST_LEN);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
sig = pki_do_sign(privkey, hash, SHA_DIGEST_LEN);
|
sig = pki_do_sign(privkey, hash, SHA_DIGEST_LEN);
|
||||||
|
}
|
||||||
|
ssh_string_free(session_id);
|
||||||
if (sig == NULL) {
|
if (sig == NULL) {
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
@ -25,6 +25,8 @@
|
|||||||
#ifndef _PKI_CRYPTO_H
|
#ifndef _PKI_CRYPTO_H
|
||||||
#define _PKI_CRYPTO_H
|
#define _PKI_CRYPTO_H
|
||||||
|
|
||||||
|
#include "libssh/priv.h"
|
||||||
|
|
||||||
#include <openssl/pem.h>
|
#include <openssl/pem.h>
|
||||||
#include <openssl/dsa.h>
|
#include <openssl/dsa.h>
|
||||||
#include <openssl/err.h>
|
#include <openssl/err.h>
|
||||||
@ -37,8 +39,6 @@
|
|||||||
#include <openssl/ecdsa.h>
|
#include <openssl/ecdsa.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
#include "libssh/priv.h"
|
|
||||||
#include "libssh/libssh.h"
|
#include "libssh/libssh.h"
|
||||||
#include "libssh/buffer.h"
|
#include "libssh/buffer.h"
|
||||||
#include "libssh/session.h"
|
#include "libssh/session.h"
|
||||||
@ -1018,36 +1018,52 @@ ssh_string pki_signature_to_blob(const ssh_signature sig)
|
|||||||
break;
|
break;
|
||||||
case SSH_KEYTYPE_ECDSA:
|
case SSH_KEYTYPE_ECDSA:
|
||||||
#ifdef HAVE_OPENSSL_ECC
|
#ifdef HAVE_OPENSSL_ECC
|
||||||
|
{
|
||||||
|
ssh_buffer b;
|
||||||
|
int rc;
|
||||||
|
|
||||||
|
b = ssh_buffer_new();
|
||||||
|
if (b == NULL) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
r = make_bignum_string(sig->ecdsa_sig->r);
|
r = make_bignum_string(sig->ecdsa_sig->r);
|
||||||
if (r == NULL) {
|
if (r == NULL) {
|
||||||
|
ssh_buffer_free(b);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
rc = buffer_add_ssh_string(b, r);
|
||||||
|
ssh_string_free(r);
|
||||||
|
if (rc < 0) {
|
||||||
|
ssh_buffer_free(b);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
s = make_bignum_string(sig->ecdsa_sig->s);
|
s = make_bignum_string(sig->ecdsa_sig->s);
|
||||||
if (s == NULL) {
|
if (s == NULL) {
|
||||||
ssh_string_free(r);
|
ssh_buffer_free(b);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
rc = buffer_add_ssh_string(b, s);
|
||||||
memcpy(buffer,
|
|
||||||
((char *)ssh_string_data(r)) + ssh_string_len(r) - 20,
|
|
||||||
20);
|
|
||||||
memcpy(buffer + 20,
|
|
||||||
((char *)ssh_string_data(s)) + ssh_string_len(s) - 20,
|
|
||||||
20);
|
|
||||||
|
|
||||||
ssh_string_free(r);
|
|
||||||
ssh_string_free(s);
|
ssh_string_free(s);
|
||||||
|
if (rc < 0) {
|
||||||
sig_blob = ssh_string_new(40);
|
ssh_buffer_free(b);
|
||||||
if (sig_blob == NULL) {
|
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
ssh_string_fill(sig_blob, buffer, 40);
|
sig_blob = ssh_string_new(buffer_get_rest_len(b));
|
||||||
|
if (sig_blob == NULL) {
|
||||||
|
ssh_buffer_free(b);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
ssh_string_fill(sig_blob, buffer_get_rest(b), buffer_get_rest_len(b));
|
||||||
|
ssh_buffer_free(b);
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
case SSH_KEYTYPE_UNKNOWN:
|
case SSH_KEYTYPE_UNKNOWN:
|
||||||
ssh_pki_log("Unknown signature key type: %d", sig->type);
|
ssh_pki_log("Unknown signature key type: %s", sig->type_c);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1070,6 +1086,7 @@ ssh_signature pki_signature_from_blob(const ssh_key pubkey,
|
|||||||
}
|
}
|
||||||
|
|
||||||
sig->type = type;
|
sig->type = type;
|
||||||
|
sig->type_c = ssh_key_type_to_char(type);
|
||||||
|
|
||||||
len = ssh_string_len(sig_blob);
|
len = ssh_string_len(sig_blob);
|
||||||
|
|
||||||
@ -1309,6 +1326,7 @@ ssh_signature pki_do_sign(const ssh_key privkey,
|
|||||||
}
|
}
|
||||||
|
|
||||||
sig->type = privkey->type;
|
sig->type = privkey->type;
|
||||||
|
sig->type_c = privkey->type_c;
|
||||||
|
|
||||||
switch(privkey->type) {
|
switch(privkey->type) {
|
||||||
case SSH_KEYTYPE_DSS:
|
case SSH_KEYTYPE_DSS:
|
||||||
@ -1368,6 +1386,7 @@ ssh_signature pki_do_sign_sessionid(const ssh_key key,
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
sig->type = key->type;
|
sig->type = key->type;
|
||||||
|
sig->type_c = key->type_c;
|
||||||
|
|
||||||
switch(key->type) {
|
switch(key->type) {
|
||||||
case SSH_KEYTYPE_DSS:
|
case SSH_KEYTYPE_DSS:
|
||||||
|
@ -450,7 +450,11 @@ void ssh_poll_ctx_free(ssh_poll_ctx ctx) {
|
|||||||
if (ctx->polls_allocated > 0) {
|
if (ctx->polls_allocated > 0) {
|
||||||
while (ctx->polls_used > 0){
|
while (ctx->polls_used > 0){
|
||||||
ssh_poll_handle p = ctx->pollptrs[0];
|
ssh_poll_handle p = ctx->pollptrs[0];
|
||||||
ssh_poll_ctx_remove(ctx, p);
|
/*
|
||||||
|
* The free function calls ssh_poll_ctx_remove() and decrements
|
||||||
|
* ctx->polls_used
|
||||||
|
*/
|
||||||
|
ssh_poll_free(p);
|
||||||
}
|
}
|
||||||
|
|
||||||
SAFE_FREE(ctx->pollptrs);
|
SAFE_FREE(ctx->pollptrs);
|
||||||
|
@ -814,7 +814,7 @@ int ssh_scp_integer_mode(const char *mode){
|
|||||||
*/
|
*/
|
||||||
char *ssh_scp_string_mode(int mode){
|
char *ssh_scp_string_mode(int mode){
|
||||||
char buffer[16];
|
char buffer[16];
|
||||||
snprintf(buffer,sizeof(buffer),"%.4o",mode);
|
snprintf(buffer,sizeof(buffer),"%.4d",mode);
|
||||||
return strdup(buffer);
|
return strdup(buffer);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1221,38 +1221,45 @@ int ssh_execute_message_callbacks(ssh_session session){
|
|||||||
return SSH_OK;
|
return SSH_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
int ssh_send_keepalive(ssh_session session)
|
int ssh_send_keepalive(ssh_session session)
|
||||||
{
|
{
|
||||||
/* TODO check the reply and all that */
|
|
||||||
struct ssh_string_struct *req;
|
struct ssh_string_struct *req;
|
||||||
int reply = 1;
|
int rc;
|
||||||
int rc = SSH_ERROR;
|
|
||||||
|
rc = buffer_add_u8(session->out_buffer, SSH2_MSG_GLOBAL_REQUEST);
|
||||||
|
if (rc < 0) {
|
||||||
|
goto err;
|
||||||
|
}
|
||||||
|
|
||||||
req = ssh_string_from_char("keepalive@openssh.com");
|
req = ssh_string_from_char("keepalive@openssh.com");
|
||||||
if (req == NULL) {
|
if (req == NULL) {
|
||||||
ssh_set_error_oom(session);
|
goto err;
|
||||||
goto out;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (buffer_add_u8(session->out_buffer, SSH2_MSG_GLOBAL_REQUEST) < 0 ||
|
rc = buffer_add_ssh_string(session->out_buffer, req);
|
||||||
buffer_add_ssh_string(session->out_buffer, req) < 0 ||
|
ssh_string_free(req);
|
||||||
buffer_add_u8(session->out_buffer, reply == 0 ? 0 : 1) < 0) {
|
if (rc < 0) {
|
||||||
ssh_set_error_oom(session);
|
goto err;
|
||||||
goto out;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (packet_send(session) == SSH_ERROR)
|
rc = buffer_add_u8(session->out_buffer, 1);
|
||||||
goto out;
|
if (rc < 0) {
|
||||||
|
goto err;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (packet_send(session) == SSH_ERROR) {
|
||||||
|
goto err;
|
||||||
|
}
|
||||||
|
|
||||||
ssh_handle_packets(session, 0);
|
ssh_handle_packets(session, 0);
|
||||||
|
|
||||||
SSH_LOG(SSH_LOG_PACKET, "Sent a keepalive");
|
SSH_LOG(SSH_LOG_PACKET, "Sent a keepalive");
|
||||||
rc = SSH_OK;
|
return SSH_OK;
|
||||||
|
|
||||||
out:
|
err:
|
||||||
ssh_string_free(req);
|
ssh_set_error_oom(session);
|
||||||
return rc;
|
buffer_reinit(session->out_buffer);
|
||||||
|
return SSH_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
/** @} */
|
/** @} */
|
||||||
|
@ -273,7 +273,7 @@ void ssh_free(ssh_session session) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* burn connection, it could hang sensitive datas */
|
/* burn connection, it could hang sensitive datas */
|
||||||
ZERO_STRUCTP(session);
|
BURN_BUFFER(session, sizeof(struct ssh_session_struct));
|
||||||
SAFE_FREE(session);
|
SAFE_FREE(session);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -695,11 +695,11 @@ int ssh_socket_buffered_write_bytes(ssh_socket s){
|
|||||||
int ssh_socket_get_status(ssh_socket s) {
|
int ssh_socket_get_status(ssh_socket s) {
|
||||||
int r = 0;
|
int r = 0;
|
||||||
|
|
||||||
if (s->read_wontblock) {
|
if (buffer_get_len(s->in_buffer) > 0) {
|
||||||
r |= SSH_READ_PENDING;
|
r |= SSH_READ_PENDING;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (s->write_wontblock) {
|
if (buffer_get_len(s->out_buffer) > 0) {
|
||||||
r |= SSH_WRITE_PENDING;
|
r |= SSH_WRITE_PENDING;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -158,7 +158,7 @@ void crypto_free(struct ssh_crypto_struct *crypto){
|
|||||||
SAFE_FREE(crypto->kex_methods[i]);
|
SAFE_FREE(crypto->kex_methods[i]);
|
||||||
}
|
}
|
||||||
|
|
||||||
memset(crypto,0,sizeof(*crypto));
|
BURN_BUFFER(crypto, sizeof(struct ssh_crypto_struct));
|
||||||
|
|
||||||
SAFE_FREE(crypto);
|
SAFE_FREE(crypto);
|
||||||
}
|
}
|
||||||
@ -317,8 +317,13 @@ int crypt_set_algorithms_server(ssh_session session){
|
|||||||
session->next_crypto->do_compress_in=1;
|
session->next_crypto->do_compress_in=1;
|
||||||
}
|
}
|
||||||
if(strcmp(method,"zlib@openssh.com") == 0){
|
if(strcmp(method,"zlib@openssh.com") == 0){
|
||||||
SSH_LOG(SSH_LOG_PACKET,"enabling C->S compression");
|
SSH_LOG(SSH_LOG_PACKET,"enabling C->S delayed compression");
|
||||||
session->next_crypto->delayed_compress_in=1;
|
|
||||||
|
if (session->flags & SSH_SESSION_FLAG_AUTHENTICATED) {
|
||||||
|
session->next_crypto->do_compress_in = 1;
|
||||||
|
} else {
|
||||||
|
session->next_crypto->delayed_compress_in = 1;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
method = session->next_crypto->kex_methods[SSH_COMP_S_C];
|
method = session->next_crypto->kex_methods[SSH_COMP_S_C];
|
||||||
@ -328,7 +333,12 @@ int crypt_set_algorithms_server(ssh_session session){
|
|||||||
}
|
}
|
||||||
if(strcmp(method,"zlib@openssh.com") == 0){
|
if(strcmp(method,"zlib@openssh.com") == 0){
|
||||||
SSH_LOG(SSH_LOG_PACKET,"enabling S->C delayed compression\n");
|
SSH_LOG(SSH_LOG_PACKET,"enabling S->C delayed compression\n");
|
||||||
session->next_crypto->delayed_compress_out=1;
|
|
||||||
|
if (session->flags & SSH_SESSION_FLAG_AUTHENTICATED) {
|
||||||
|
session->next_crypto->do_compress_out = 1;
|
||||||
|
} else {
|
||||||
|
session->next_crypto->delayed_compress_out = 1;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
method = session->next_crypto->kex_methods[SSH_HOSTKEYS];
|
method = session->next_crypto->kex_methods[SSH_HOSTKEYS];
|
||||||
|
@ -6,7 +6,10 @@ add_cmocka_test(torture_connect torture_connect.c ${TORTURE_LIBRARY})
|
|||||||
add_cmocka_test(torture_knownhosts torture_knownhosts.c ${TORTURE_LIBRARY})
|
add_cmocka_test(torture_knownhosts torture_knownhosts.c ${TORTURE_LIBRARY})
|
||||||
add_cmocka_test(torture_proxycommand torture_proxycommand.c ${TORTURE_LIBRARY})
|
add_cmocka_test(torture_proxycommand torture_proxycommand.c ${TORTURE_LIBRARY})
|
||||||
add_cmocka_test(torture_session torture_session.c ${TORTURE_LIBRARY})
|
add_cmocka_test(torture_session torture_session.c ${TORTURE_LIBRARY})
|
||||||
|
add_cmocka_test(torture_forward torture_forward.c ${TORTURE_LIBRARY})
|
||||||
|
add_cmocka_test(torture_request_env torture_request_env.c ${TORTURE_LIBRARY})
|
||||||
if (WITH_SFTP)
|
if (WITH_SFTP)
|
||||||
add_cmocka_test(torture_sftp_static torture_sftp_static.c ${TORTURE_LIBRARY})
|
add_cmocka_test(torture_sftp_static torture_sftp_static.c ${TORTURE_LIBRARY})
|
||||||
add_cmocka_test(torture_sftp_dir torture_sftp_dir.c ${TORTURE_LIBRARY})
|
add_cmocka_test(torture_sftp_dir torture_sftp_dir.c ${TORTURE_LIBRARY})
|
||||||
|
add_cmocka_test(torture_sftp_read torture_sftp_read.c ${TORTURE_LIBRARY})
|
||||||
endif (WITH_SFTP)
|
endif (WITH_SFTP)
|
||||||
|
@ -13,4 +13,6 @@ if (UNIX AND NOT WIN32)
|
|||||||
add_cmocka_test(torture_pki torture_pki.c ${TORTURE_LIBRARY})
|
add_cmocka_test(torture_pki torture_pki.c ${TORTURE_LIBRARY})
|
||||||
# requires pthread
|
# requires pthread
|
||||||
add_cmocka_test(torture_rand torture_rand.c ${TORTURE_LIBRARY})
|
add_cmocka_test(torture_rand torture_rand.c ${TORTURE_LIBRARY})
|
||||||
|
# requires /dev/null
|
||||||
|
add_cmocka_test(torture_channel torture_channel.c ${TORTURE_LIBRARY})
|
||||||
endif (UNIX AND NOT WIN32)
|
endif (UNIX AND NOT WIN32)
|
||||||
|
Loading…
Reference in New Issue
Block a user