1
0
mirror of https://github.com/tmate-io/tmate-ssh-server.git synced 2020-11-18 19:53:51 -08:00

Update libssh

This commit is contained in:
Nicolas Viennot 2013-11-06 19:39:12 -05:00
parent ed6224ba73
commit 1d16931564
25 changed files with 322 additions and 147 deletions

View File

@ -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}")

View File

@ -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)

View File

@ -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)

View File

@ -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")

View File

@ -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
@ -126,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
@ -158,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

View File

@ -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.

View File

@ -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)

View File

@ -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 */

View File

@ -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"

View File

@ -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);

View File

@ -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);

View File

@ -155,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;
@ -254,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' */
@ -265,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 */

View File

@ -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}

View File

@ -3348,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;

View File

@ -533,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,
@ -550,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;
} }

View File

@ -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);

View File

@ -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: */

View File

@ -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);

View File

@ -309,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... */
else if (session->common.callbacks != NULL) {
rc = ssh_execute_client_request(session, msg); rc = ssh_execute_client_request(session, msg);
} }

View File

@ -1254,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:

View File

@ -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"

View File

@ -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;
} }
/** @} */ /** @} */

View File

@ -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);
} }

View File

@ -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;
} }

View File

@ -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);
} }
@ -319,10 +319,11 @@ 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 C->S delayed compression"); SSH_LOG(SSH_LOG_PACKET,"enabling C->S delayed compression");
if (session->flags & SSH_SESSION_FLAG_AUTHENTICATED) if (session->flags & SSH_SESSION_FLAG_AUTHENTICATED) {
session->next_crypto->do_compress_in=1; session->next_crypto->do_compress_in = 1;
else } else {
session->next_crypto->delayed_compress_in=1; 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];
@ -333,10 +334,11 @@ 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");
if (session->flags & SSH_SESSION_FLAG_AUTHENTICATED) if (session->flags & SSH_SESSION_FLAG_AUTHENTICATED) {
session->next_crypto->do_compress_out=1; session->next_crypto->do_compress_out = 1;
else } else {
session->next_crypto->delayed_compress_out=1; session->next_crypto->delayed_compress_out = 1;
}
} }
method = session->next_crypto->kex_methods[SSH_HOSTKEYS]; method = session->next_crypto->kex_methods[SSH_HOSTKEYS];