mirror of
https://git.libssh.org/projects/libssh.git
synced 2025-08-08 19:02:06 +03:00
Rest in Peace SSHv1
Signed-off-by: Andreas Schneider <asn@cryptomilk.org> Reviewed-by: Jakub Jelen <jjelen@redhat.com>
This commit is contained in:
@@ -1,13 +0,0 @@
|
||||
-DWITH_SERVER=1
|
||||
-DWITH_GSSAPI=1
|
||||
-DWITH_ZLIB=1
|
||||
-DWITH_SFTP=1
|
||||
-DWITH_SSH1=1
|
||||
-DWITH_PCAP=1
|
||||
-DHAVE_ECDH=1
|
||||
-DHAVE_ECC=1
|
||||
-Iinclude/libssh
|
||||
-Iinclude
|
||||
-Ibuild
|
||||
-Itests
|
||||
-Isrc
|
@@ -160,7 +160,6 @@ message(STATUS "zlib support: ${WITH_ZLIB}")
|
||||
message(STATUS "libgcrypt support: ${WITH_GCRYPT}")
|
||||
message(STATUS "libmbedTLS support: ${WITH_MBEDTLS}")
|
||||
message(STATUS "libnacl support: ${WITH_NACL}")
|
||||
message(STATUS "SSH-1 support: ${WITH_SSH1}")
|
||||
message(STATUS "SFTP support: ${WITH_SFTP}")
|
||||
message(STATUS "Server support : ${WITH_SERVER}")
|
||||
message(STATUS "GSSAPI support : ${WITH_GSSAPI}")
|
||||
|
@@ -1,6 +1,5 @@
|
||||
option(WITH_GSSAPI "Build with GSSAPI support" ON)
|
||||
option(WITH_ZLIB "Build with ZLIB support" ON)
|
||||
option(WITH_SSH1 "Build with SSH1 support" OFF)
|
||||
option(WITH_SFTP "Build with SFTP support" ON)
|
||||
option(WITH_SERVER "Build with SSH server support" ON)
|
||||
option(WITH_STATIC_LIB "Build with a static library" OFF)
|
||||
|
@@ -210,9 +210,6 @@
|
||||
/* Define to 1 if you want to enable SFTP */
|
||||
#cmakedefine WITH_SFTP 1
|
||||
|
||||
/* Define to 1 if you want to enable SSH1 */
|
||||
#cmakedefine WITH_SSH1 1
|
||||
|
||||
/* Define to 1 if you want to enable server support */
|
||||
#cmakedefine WITH_SERVER 1
|
||||
|
||||
|
@@ -15,13 +15,6 @@ if (WITH_SFTP)
|
||||
)
|
||||
endif (WITH_SFTP)
|
||||
|
||||
if (WITH_SSH1)
|
||||
set(libssh_HDRS
|
||||
${libssh_HDRS}
|
||||
ssh1.h
|
||||
)
|
||||
endif (WITH_SSH1)
|
||||
|
||||
if (WITH_SERVER)
|
||||
set(libssh_HDRS
|
||||
${libssh_HDRS}
|
||||
|
@@ -49,20 +49,6 @@ ssh_kbdint ssh_kbdint_new(void);
|
||||
void ssh_kbdint_clean(ssh_kbdint kbd);
|
||||
void ssh_kbdint_free(ssh_kbdint kbd);
|
||||
|
||||
|
||||
#ifdef WITH_SSH1
|
||||
void ssh_auth1_handler(ssh_session session, uint8_t type);
|
||||
|
||||
/* auth1.c */
|
||||
int ssh_userauth1_none(ssh_session session, const char *username);
|
||||
int ssh_userauth1_offer_pubkey(ssh_session session, const char *username,
|
||||
int type, ssh_string pubkey);
|
||||
int ssh_userauth1_password(ssh_session session, const char *username,
|
||||
const char *password);
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
/** @internal
|
||||
* States of authentication in the client-side. They describe
|
||||
* what was the last response from the server
|
||||
@@ -104,8 +90,6 @@ enum ssh_auth_service_state_e {
|
||||
SSH_AUTH_SERVICE_ACCEPTED,
|
||||
/** Access to service denied (fatal) */
|
||||
SSH_AUTH_SERVICE_DENIED,
|
||||
/** Specific to SSH1 */
|
||||
SSH_AUTH_SERVICE_USER_SENT
|
||||
};
|
||||
|
||||
#endif /* AUTH_H_ */
|
||||
|
@@ -82,8 +82,7 @@ int ssh_buffer_get_u64(ssh_buffer buffer, uint64_t *data);
|
||||
|
||||
/* ssh_buffer_get_ssh_string() is an exception. if the String read is too large or invalid, it will answer NULL. */
|
||||
ssh_string ssh_buffer_get_ssh_string(ssh_buffer buffer);
|
||||
/* ssh_gets a string out of a SSH-1 mpint */
|
||||
ssh_string ssh_buffer_get_mpint(ssh_buffer buffer);
|
||||
|
||||
/* ssh_buffer_pass_bytes acts as if len bytes have been read (used for padding) */
|
||||
uint32_t ssh_buffer_pass_bytes_end(ssh_buffer buffer, uint32_t len);
|
||||
uint32_t ssh_buffer_pass_bytes(ssh_buffer buffer, uint32_t len);
|
||||
|
@@ -71,7 +71,6 @@ struct ssh_channel_struct {
|
||||
ssh_buffer stdout_buffer;
|
||||
ssh_buffer stderr_buffer;
|
||||
void *userarg;
|
||||
int version;
|
||||
int exit_status;
|
||||
enum ssh_channel_request_state_e request_state;
|
||||
struct ssh_list *callbacks; /* list of ssh_channel_callbacks */
|
||||
@@ -100,20 +99,5 @@ int ssh_channel_flush(ssh_channel channel);
|
||||
uint32_t ssh_channel_new_id(ssh_session session);
|
||||
ssh_channel ssh_channel_from_local(ssh_session session, uint32_t id);
|
||||
void ssh_channel_do_free(ssh_channel channel);
|
||||
#ifdef WITH_SSH1
|
||||
SSH_PACKET_CALLBACK(ssh_packet_data1);
|
||||
SSH_PACKET_CALLBACK(ssh_packet_close1);
|
||||
SSH_PACKET_CALLBACK(ssh_packet_exist_status1);
|
||||
|
||||
/* channels1.c */
|
||||
int ssh_channel_open_session1(ssh_channel channel);
|
||||
int ssh_channel_request_pty_size1(ssh_channel channel, const char *terminal,
|
||||
int cols, int rows);
|
||||
int ssh_channel_change_pty_size1(ssh_channel channel, int cols, int rows);
|
||||
int ssh_channel_request_shell1(ssh_channel channel);
|
||||
int ssh_channel_request_exec1(ssh_channel channel, const char *cmd);
|
||||
int ssh_channel_write1(ssh_channel channel, const void *data, int len);
|
||||
ssh_channel ssh_get_channel1(ssh_session session);
|
||||
#endif
|
||||
|
||||
#endif /* CHANNELS_H_ */
|
||||
|
@@ -67,8 +67,6 @@ enum ssh_cipher_e {
|
||||
SSH_NO_CIPHER=0,
|
||||
SSH_BLOWFISH_CBC,
|
||||
SSH_3DES_CBC,
|
||||
SSH_3DES_CBC_SSH1,
|
||||
SSH_DES_CBC_SSH1,
|
||||
SSH_AES128_CBC,
|
||||
SSH_AES192_CBC,
|
||||
SSH_AES256_CBC,
|
||||
|
@@ -32,9 +32,6 @@ struct ssh_kex_struct {
|
||||
};
|
||||
|
||||
SSH_PACKET_CALLBACK(ssh_packet_kexinit);
|
||||
#ifdef WITH_SSH1
|
||||
SSH_PACKET_CALLBACK(ssh_packet_publickey1);
|
||||
#endif
|
||||
|
||||
int ssh_send_kex(ssh_session session, int server_kex);
|
||||
void ssh_list_kex(struct ssh_kex_struct *kex);
|
||||
|
@@ -29,7 +29,7 @@ int ssh_file_readaccess_ok(const char *file);
|
||||
|
||||
char *ssh_path_expand_tilde(const char *d);
|
||||
char *ssh_path_expand_escape(ssh_session session, const char *s);
|
||||
int ssh_analyze_banner(ssh_session session, int server, int *ssh1, int *ssh2);
|
||||
int ssh_analyze_banner(ssh_session session, int server);
|
||||
int ssh_is_ipaddr_v4(const char *str);
|
||||
int ssh_is_ipaddr(const char *str);
|
||||
|
||||
|
@@ -45,17 +45,6 @@ enum ssh_packet_state_e {
|
||||
|
||||
int ssh_packet_send(ssh_session session);
|
||||
|
||||
#ifdef WITH_SSH1
|
||||
int ssh_packet_send1(ssh_session session) ;
|
||||
void ssh_packet_set_default_callbacks1(ssh_session session);
|
||||
|
||||
SSH_PACKET_CALLBACK(ssh_packet_disconnect1);
|
||||
SSH_PACKET_CALLBACK(ssh_packet_smsg_success1);
|
||||
SSH_PACKET_CALLBACK(ssh_packet_smsg_failure1);
|
||||
int ssh_packet_socket_callback1(const void *data, size_t receivedlen, void *user);
|
||||
|
||||
#endif
|
||||
|
||||
SSH_PACKET_CALLBACK(ssh_packet_unimplemented);
|
||||
SSH_PACKET_CALLBACK(ssh_packet_disconnect_callback);
|
||||
SSH_PACKET_CALLBACK(ssh_packet_ignore_callback);
|
||||
|
@@ -115,10 +115,6 @@ int ssh_pki_export_pubkey_blob(const ssh_key key,
|
||||
ssh_string *pblob);
|
||||
int ssh_pki_import_pubkey_blob(const ssh_string key_blob,
|
||||
ssh_key *pkey);
|
||||
int ssh_pki_export_pubkey_rsa1(const ssh_key key,
|
||||
const char *host,
|
||||
char *rsa1,
|
||||
size_t rsa1_len);
|
||||
|
||||
int ssh_pki_import_cert_blob(const ssh_string cert_blob,
|
||||
ssh_key *pkey);
|
||||
|
@@ -80,10 +80,6 @@ int pki_pubkey_build_rsa(ssh_key key,
|
||||
ssh_string n);
|
||||
int pki_pubkey_build_ecdsa(ssh_key key, int nid, ssh_string e);
|
||||
ssh_string pki_publickey_to_blob(const ssh_key key);
|
||||
int pki_export_pubkey_rsa1(const ssh_key key,
|
||||
const char *host,
|
||||
char *rsa1,
|
||||
size_t rsa1_len);
|
||||
|
||||
/* SSH Signature Functions */
|
||||
ssh_string pki_signature_to_blob(const ssh_signature sign);
|
||||
|
@@ -146,12 +146,11 @@ int gettimeofday(struct timeval *__p, void *__t);
|
||||
#ifndef ERROR_BUFFERLEN
|
||||
#define ERROR_BUFFERLEN 1024
|
||||
#endif
|
||||
#ifndef CLIENTBANNER1
|
||||
#define CLIENTBANNER1 "SSH-1.5-libssh_" SSH_STRINGIFY(LIBSSH_VERSION)
|
||||
#endif
|
||||
#ifndef CLIENTBANNER2
|
||||
#define CLIENTBANNER2 "SSH-2.0-libssh_" SSH_STRINGIFY(LIBSSH_VERSION)
|
||||
#endif
|
||||
|
||||
#ifndef CLIENT_BANNER_SSH2
|
||||
#define CLIENT_BANNER_SSH2 "SSH-2.0-libssh_" SSH_STRINGIFY(LIBSSH_VERSION)
|
||||
#endif /* CLIENT_BANNER_SSH2 */
|
||||
|
||||
#ifndef KBDINT_MAX_PROMPT
|
||||
#define KBDINT_MAX_PROMPT 256 /* more than openssh's :) */
|
||||
#endif
|
||||
|
@@ -157,7 +157,7 @@ struct ssh_session_struct {
|
||||
/* keyb interactive data */
|
||||
struct ssh_kbdint_struct *kbdint;
|
||||
struct ssh_gssapi_struct *gssapi;
|
||||
int version; /* 1 or 2 */
|
||||
|
||||
/* server host keys */
|
||||
struct {
|
||||
ssh_key rsa_key;
|
||||
@@ -198,8 +198,6 @@ struct ssh_session_struct {
|
||||
unsigned int port;
|
||||
socket_t fd;
|
||||
int StrictHostKeyChecking;
|
||||
int ssh2;
|
||||
int ssh1;
|
||||
char compressionlevel;
|
||||
char *gss_server_identity;
|
||||
char *gss_client_identity;
|
||||
|
@@ -1,82 +0,0 @@
|
||||
#ifndef __SSH1_H
|
||||
#define __SSH1_H
|
||||
|
||||
#define SSH_MSG_NONE 0 /* no message */
|
||||
#define SSH_MSG_DISCONNECT 1 /* cause (string) */
|
||||
#define SSH_SMSG_PUBLIC_KEY 2 /* ck,msk,srvk,hostk */
|
||||
#define SSH_CMSG_SESSION_KEY 3 /* key (BIGNUM) */
|
||||
#define SSH_CMSG_USER 4 /* user (string) */
|
||||
#define SSH_CMSG_AUTH_RHOSTS 5 /* user (string) */
|
||||
#define SSH_CMSG_AUTH_RSA 6 /* modulus (BIGNUM) */
|
||||
#define SSH_SMSG_AUTH_RSA_CHALLENGE 7 /* int (BIGNUM) */
|
||||
#define SSH_CMSG_AUTH_RSA_RESPONSE 8 /* int (BIGNUM) */
|
||||
#define SSH_CMSG_AUTH_PASSWORD 9 /* pass (string) */
|
||||
#define SSH_CMSG_REQUEST_PTY 10 /* TERM, tty modes */
|
||||
#define SSH_CMSG_WINDOW_SIZE 11 /* row,col,xpix,ypix */
|
||||
#define SSH_CMSG_EXEC_SHELL 12 /* */
|
||||
#define SSH_CMSG_EXEC_CMD 13 /* cmd (string) */
|
||||
#define SSH_SMSG_SUCCESS 14 /* */
|
||||
#define SSH_SMSG_FAILURE 15 /* */
|
||||
#define SSH_CMSG_STDIN_DATA 16 /* data (string) */
|
||||
#define SSH_SMSG_STDOUT_DATA 17 /* data (string) */
|
||||
#define SSH_SMSG_STDERR_DATA 18 /* data (string) */
|
||||
#define SSH_CMSG_EOF 19 /* */
|
||||
#define SSH_SMSG_EXITSTATUS 20 /* status (int) */
|
||||
#define SSH_MSG_CHANNEL_OPEN_CONFIRMATION 21 /* channel (int) */
|
||||
#define SSH_MSG_CHANNEL_OPEN_FAILURE 22 /* channel (int) */
|
||||
#define SSH_MSG_CHANNEL_DATA 23 /* ch,data (int,str) */
|
||||
#define SSH_MSG_CHANNEL_CLOSE 24 /* channel (int) */
|
||||
#define SSH_MSG_CHANNEL_CLOSE_CONFIRMATION 25 /* channel (int) */
|
||||
/* SSH_CMSG_X11_REQUEST_FORWARDING 26 OBSOLETE */
|
||||
#define SSH_SMSG_X11_OPEN 27 /* channel (int) */
|
||||
#define SSH_CMSG_PORT_FORWARD_REQUEST 28 /* p,host,hp (i,s,i) */
|
||||
#define SSH_MSG_PORT_OPEN 29 /* ch,h,p (i,s,i) */
|
||||
#define SSH_CMSG_AGENT_REQUEST_FORWARDING 30 /* */
|
||||
#define SSH_SMSG_AGENT_OPEN 31 /* port (int) */
|
||||
#define SSH_MSG_IGNORE 32 /* string */
|
||||
#define SSH_CMSG_EXIT_CONFIRMATION 33 /* */
|
||||
#define SSH_CMSG_X11_REQUEST_FORWARDING 34 /* proto,data (s,s) */
|
||||
#define SSH_CMSG_AUTH_RHOSTS_RSA 35 /* user,mod (s,mpi) */
|
||||
#define SSH_MSG_DEBUG 36 /* string */
|
||||
#define SSH_CMSG_REQUEST_COMPRESSION 37 /* level 1-9 (int) */
|
||||
#define SSH_CMSG_MAX_PACKET_SIZE 38 /* size 4k-1024k (int) */
|
||||
#define SSH_CMSG_AUTH_TIS 39 /* we use this for s/key */
|
||||
#define SSH_SMSG_AUTH_TIS_CHALLENGE 40 /* challenge (string) */
|
||||
#define SSH_CMSG_AUTH_TIS_RESPONSE 41 /* response (string) */
|
||||
#define SSH_CMSG_AUTH_KERBEROS 42 /* (KTEXT) */
|
||||
#define SSH_SMSG_AUTH_KERBEROS_RESPONSE 43 /* (KTEXT) */
|
||||
#define SSH_CMSG_HAVE_KERBEROS_TGT 44 /* credentials (s) */
|
||||
#define SSH_CMSG_HAVE_AFS_TOKEN 65 /* token (s) */
|
||||
|
||||
/* protocol version 1.5 overloads some version 1.3 message types */
|
||||
#define SSH_MSG_CHANNEL_INPUT_EOF SSH_MSG_CHANNEL_CLOSE
|
||||
#define SSH_MSG_CHANNEL_OUTPUT_CLOSE SSH_MSG_CHANNEL_CLOSE_CONFIRMATION
|
||||
|
||||
/*
|
||||
* Authentication methods. New types can be added, but old types should not
|
||||
* be removed for compatibility. The maximum allowed value is 31.
|
||||
*/
|
||||
#define SSH_AUTH_RHOSTS 1
|
||||
#define SSH_AUTH_RSA 2
|
||||
#define SSH_AUTH_PASSWORD 3
|
||||
#define SSH_AUTH_RHOSTS_RSA 4
|
||||
#define SSH_AUTH_TIS 5
|
||||
#define SSH_AUTH_KERBEROS 6
|
||||
#define SSH_PASS_KERBEROS_TGT 7
|
||||
/* 8 to 15 are reserved */
|
||||
#define SSH_PASS_AFS_TOKEN 21
|
||||
|
||||
/* Protocol flags. These are bit masks. */
|
||||
#define SSH_PROTOFLAG_SCREEN_NUMBER 1 /* X11 forwarding includes screen */
|
||||
#define SSH_PROTOFLAG_HOST_IN_FWD_OPEN 2 /* forwarding opens contain host */
|
||||
|
||||
/* cipher flags. they are bit numbers */
|
||||
#define SSH_CIPHER_NONE 0 /* No encryption */
|
||||
#define SSH_CIPHER_IDEA 1 /* IDEA in CFB mode */
|
||||
#define SSH_CIPHER_DES 2 /* DES in CBC mode */
|
||||
#define SSH_CIPHER_3DES 3 /* Triple-DES in CBC mode */
|
||||
#define SSH_CIPHER_RC4 5 /* RC4 */
|
||||
#define SSH_CIPHER_BLOWFISH 6
|
||||
|
||||
#endif
|
||||
|
@@ -92,7 +92,7 @@ void hmac_update(HMACCTX c, const void *data, unsigned long len);
|
||||
void hmac_final(HMACCTX ctx,unsigned char *hashmacbuf,unsigned int *len);
|
||||
size_t hmac_digest_len(enum ssh_hmac_e type);
|
||||
|
||||
int crypt_set_algorithms(ssh_session session, enum ssh_des_e des_type);
|
||||
int crypt_set_algorithms_client(ssh_session session);
|
||||
int crypt_set_algorithms_server(ssh_session session);
|
||||
struct ssh_crypto_struct *crypto_new(void);
|
||||
void crypto_free(struct ssh_crypto_struct *crypto);
|
||||
|
@@ -63,7 +63,7 @@ function clean_build_dir() {
|
||||
|
||||
function usage () {
|
||||
echo "Usage: `basename $0` [--prefix /install_prefix|--build [debug|final]|--clean|--verbose|--libsuffix (32|64)|--help|--clang|--cmakedir /directory|--make
|
||||
(gmake|make)|--ccompiler (gcc|cc)|--withstaticlib|--unittesting|--clientunittesting|--withssh1|--withserver]"
|
||||
(gmake|make)|--ccompiler (gcc|cc)|--withstaticlib|--unittesting|--clientunittesting|--withserver]"
|
||||
cleanup_and_exit
|
||||
}
|
||||
|
||||
@@ -142,9 +142,6 @@ while test -n "$1"; do
|
||||
*-clientunittesting)
|
||||
OPTIONS="${OPTIONS} -DCLIENT_TESTING=ON"
|
||||
;;
|
||||
*-withssh1)
|
||||
OPTIONS="${OPTIONS} -DWITH_SSH1=ON"
|
||||
;;
|
||||
*-withserver)
|
||||
OPTIONS="${OPTIONS} -DWITH_SERVER=ON"
|
||||
;;
|
||||
|
@@ -209,17 +209,6 @@ if (WITH_SFTP)
|
||||
endif (WITH_SERVER)
|
||||
endif (WITH_SFTP)
|
||||
|
||||
if (WITH_SSH1)
|
||||
set(libssh_SRCS
|
||||
${libssh_SRCS}
|
||||
auth1.c
|
||||
channels1.c
|
||||
crc32.c
|
||||
kex1.c
|
||||
packet1.c
|
||||
)
|
||||
endif (WITH_SSH1)
|
||||
|
||||
if (WITH_SERVER)
|
||||
set(libssh_SRCS
|
||||
${libssh_SRCS}
|
||||
|
84
src/agent.c
84
src/agent.c
@@ -331,30 +331,16 @@ int ssh_agent_get_ident_count(struct ssh_session_struct *session) {
|
||||
ssh_buffer request = NULL;
|
||||
ssh_buffer reply = NULL;
|
||||
unsigned int type = 0;
|
||||
unsigned int c1 = 0, c2 = 0;
|
||||
uint8_t buf[4] = {0};
|
||||
int rc;
|
||||
|
||||
switch (session->version) {
|
||||
case 1:
|
||||
c1 = SSH_AGENTC_REQUEST_RSA_IDENTITIES;
|
||||
c2 = SSH_AGENT_RSA_IDENTITIES_ANSWER;
|
||||
break;
|
||||
case 2:
|
||||
c1 = SSH2_AGENTC_REQUEST_IDENTITIES;
|
||||
c2 = SSH2_AGENT_IDENTITIES_ANSWER;
|
||||
break;
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* send message to the agent requesting the list of identities */
|
||||
request = ssh_buffer_new();
|
||||
if (request == NULL) {
|
||||
ssh_set_error_oom(session);
|
||||
return -1;
|
||||
}
|
||||
if (ssh_buffer_add_u8(request, c1) < 0) {
|
||||
if (ssh_buffer_add_u8(request, SSH2_AGENTC_REQUEST_IDENTITIES) < 0) {
|
||||
ssh_set_error_oom(session);
|
||||
ssh_buffer_free(request);
|
||||
return -1;
|
||||
@@ -388,12 +374,12 @@ int ssh_agent_get_ident_count(struct ssh_session_struct *session) {
|
||||
|
||||
SSH_LOG(SSH_LOG_WARN,
|
||||
"Answer type: %d, expected answer: %d",
|
||||
type, c2);
|
||||
type, SSH2_AGENT_IDENTITIES_ANSWER);
|
||||
|
||||
if (agent_failed(type)) {
|
||||
ssh_buffer_free(reply);
|
||||
return 0;
|
||||
} else if (type != c2) {
|
||||
} else if (type != SSH2_AGENT_IDENTITIES_ANSWER) {
|
||||
ssh_set_error(session, SSH_FATAL,
|
||||
"Bad authentication reply message type: %u", type);
|
||||
ssh_buffer_free(reply);
|
||||
@@ -442,47 +428,39 @@ ssh_key ssh_agent_get_next_ident(struct ssh_session_struct *session,
|
||||
return NULL;
|
||||
}
|
||||
|
||||
switch(session->version) {
|
||||
case 1:
|
||||
return NULL;
|
||||
case 2:
|
||||
/* get the blob */
|
||||
blob = ssh_buffer_get_ssh_string(session->agent->ident);
|
||||
if (blob == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
/* get the blob */
|
||||
blob = ssh_buffer_get_ssh_string(session->agent->ident);
|
||||
if (blob == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* get the comment */
|
||||
tmp = ssh_buffer_get_ssh_string(session->agent->ident);
|
||||
if (tmp == NULL) {
|
||||
ssh_string_free(blob);
|
||||
/* get the comment */
|
||||
tmp = ssh_buffer_get_ssh_string(session->agent->ident);
|
||||
if (tmp == NULL) {
|
||||
ssh_string_free(blob);
|
||||
|
||||
return NULL;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (comment) {
|
||||
*comment = ssh_string_to_char(tmp);
|
||||
} else {
|
||||
ssh_string_free(blob);
|
||||
ssh_string_free(tmp);
|
||||
if (comment) {
|
||||
*comment = ssh_string_to_char(tmp);
|
||||
} else {
|
||||
ssh_string_free(blob);
|
||||
ssh_string_free(tmp);
|
||||
|
||||
return NULL;
|
||||
}
|
||||
ssh_string_free(tmp);
|
||||
return NULL;
|
||||
}
|
||||
ssh_string_free(tmp);
|
||||
|
||||
/* get key from blob */
|
||||
rc = ssh_pki_import_pubkey_blob(blob, &key);
|
||||
if (rc == SSH_ERROR) {
|
||||
/* Try again as a cert. */
|
||||
rc = ssh_pki_import_cert_blob(blob, &key);
|
||||
}
|
||||
ssh_string_free(blob);
|
||||
if (rc == SSH_ERROR) {
|
||||
return NULL;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
return NULL;
|
||||
/* get key from blob */
|
||||
rc = ssh_pki_import_pubkey_blob(blob, &key);
|
||||
if (rc == SSH_ERROR) {
|
||||
/* Try again as a cert. */
|
||||
rc = ssh_pki_import_cert_blob(blob, &key);
|
||||
}
|
||||
ssh_string_free(blob);
|
||||
if (rc == SSH_ERROR) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return key;
|
||||
|
36
src/auth.c
36
src/auth.c
@@ -323,12 +323,6 @@ int ssh_userauth_list(ssh_session session, const char *username)
|
||||
return 0;
|
||||
}
|
||||
|
||||
#ifdef WITH_SSH1
|
||||
if(session->version == 1) {
|
||||
return SSH_AUTH_METHOD_PASSWORD;
|
||||
}
|
||||
#endif
|
||||
|
||||
return session->auth_methods;
|
||||
}
|
||||
|
||||
@@ -354,12 +348,6 @@ int ssh_userauth_list(ssh_session session, const char *username)
|
||||
int ssh_userauth_none(ssh_session session, const char *username) {
|
||||
int rc;
|
||||
|
||||
#ifdef WITH_SSH1
|
||||
if (session->version == 1) {
|
||||
return ssh_userauth1_none(session, username);
|
||||
}
|
||||
#endif
|
||||
|
||||
switch(session->pending_call_state){
|
||||
case SSH_PENDING_CALL_NONE:
|
||||
break;
|
||||
@@ -454,12 +442,6 @@ int ssh_userauth_try_publickey(ssh_session session,
|
||||
return SSH_AUTH_ERROR;
|
||||
}
|
||||
|
||||
#ifdef WITH_SSH1
|
||||
if (session->version == 1) {
|
||||
return SSH_AUTH_DENIED;
|
||||
}
|
||||
#endif
|
||||
|
||||
switch(session->pending_call_state) {
|
||||
case SSH_PENDING_CALL_NONE:
|
||||
break;
|
||||
@@ -564,12 +546,6 @@ int ssh_userauth_publickey(ssh_session session,
|
||||
return SSH_AUTH_ERROR;
|
||||
}
|
||||
|
||||
#ifdef WITH_SSH1
|
||||
if (session->version == 1) {
|
||||
return SSH_AUTH_DENIED;
|
||||
}
|
||||
#endif
|
||||
|
||||
switch(session->pending_call_state) {
|
||||
case SSH_PENDING_CALL_NONE:
|
||||
break;
|
||||
@@ -1135,13 +1111,6 @@ int ssh_userauth_password(ssh_session session,
|
||||
const char *password) {
|
||||
int rc;
|
||||
|
||||
#ifdef WITH_SSH1
|
||||
if (session->version == 1) {
|
||||
rc = ssh_userauth1_password(session, username, password);
|
||||
return rc;
|
||||
}
|
||||
#endif
|
||||
|
||||
switch(session->pending_call_state) {
|
||||
case SSH_PENDING_CALL_NONE:
|
||||
break;
|
||||
@@ -1550,11 +1519,6 @@ int ssh_userauth_kbdint(ssh_session session, const char *user,
|
||||
return SSH_AUTH_ERROR;
|
||||
}
|
||||
|
||||
#ifdef WITH_SSH1
|
||||
if (session->version == 1) {
|
||||
return SSH_AUTH_DENIED;
|
||||
}
|
||||
#endif
|
||||
if ((session->pending_call_state == SSH_PENDING_CALL_NONE && session->kbdint == NULL) ||
|
||||
session->pending_call_state == SSH_PENDING_CALL_AUTH_KBDINT_INIT)
|
||||
rc = ssh_userauth_kbdint_init(session, user, submethods);
|
||||
|
235
src/auth1.c
235
src/auth1.c
@@ -1,235 +0,0 @@
|
||||
/*
|
||||
* auth1.c - authentication with SSH-1 protocol
|
||||
*
|
||||
* This file is part of the SSH Library
|
||||
*
|
||||
* Copyright (c) 2005-2008 by Aris Adamantiadis
|
||||
*
|
||||
* The SSH Library is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as published by
|
||||
* the Free Software Foundation; either version 2.1 of the License, or (at your
|
||||
* option) any later version.
|
||||
*
|
||||
* The SSH Library is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
|
||||
* License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with the SSH Library; see the file COPYING. If not, write to
|
||||
* the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
|
||||
* MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include <errno.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "libssh/priv.h"
|
||||
#include "libssh/ssh1.h"
|
||||
#include "libssh/buffer.h"
|
||||
#include "libssh/packet.h"
|
||||
#include "libssh/session.h"
|
||||
#include "libssh/string.h"
|
||||
|
||||
#ifdef WITH_SSH1
|
||||
|
||||
static int ssh_auth_status_termination(void *s){
|
||||
ssh_session session=s;
|
||||
if(session->auth_state != SSH_AUTH_STATE_NONE ||
|
||||
session->session_state == SSH_SESSION_STATE_ERROR)
|
||||
return 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int wait_auth1_status(ssh_session session) {
|
||||
/* wait for a packet */
|
||||
if (ssh_handle_packets_termination(session,SSH_TIMEOUT_USER,
|
||||
ssh_auth_status_termination, session) != SSH_OK){
|
||||
|
||||
return SSH_AUTH_ERROR;
|
||||
}
|
||||
SSH_LOG(SSH_LOG_PROTOCOL,"Auth state : %d",session->auth_state);
|
||||
|
||||
switch(session->auth_state) {
|
||||
case SSH_AUTH_STATE_SUCCESS:
|
||||
return SSH_AUTH_SUCCESS;
|
||||
case SSH_AUTH_STATE_FAILED:
|
||||
return SSH_AUTH_DENIED;
|
||||
default:
|
||||
return SSH_AUTH_AGAIN;
|
||||
}
|
||||
return SSH_AUTH_ERROR;
|
||||
}
|
||||
|
||||
void ssh_auth1_handler(ssh_session session, uint8_t type){
|
||||
if(session->session_state != SSH_SESSION_STATE_AUTHENTICATING){
|
||||
ssh_set_error(session,SSH_FATAL,"SSH_SMSG_SUCCESS or FAILED received in wrong state");
|
||||
return;
|
||||
}
|
||||
if(type==SSH_SMSG_SUCCESS){
|
||||
session->auth_state=SSH_AUTH_STATE_SUCCESS;
|
||||
session->session_state=SSH_SESSION_STATE_AUTHENTICATED;
|
||||
} else if(type==SSH_SMSG_FAILURE)
|
||||
session->auth_state=SSH_AUTH_STATE_FAILED;
|
||||
}
|
||||
|
||||
static int send_username(ssh_session session, const char *username) {
|
||||
ssh_string user = NULL;
|
||||
int rc;
|
||||
/* returns SSH_AUTH_SUCCESS or SSH_AUTH_DENIED */
|
||||
if(session->auth_service_state == SSH_AUTH_SERVICE_USER_SENT) {
|
||||
if(session->auth_state == SSH_AUTH_STATE_FAILED)
|
||||
return SSH_AUTH_DENIED;
|
||||
if(session->auth_state == SSH_AUTH_STATE_SUCCESS)
|
||||
return SSH_AUTH_SUCCESS;
|
||||
return SSH_AUTH_ERROR;
|
||||
}
|
||||
if (session->auth_service_state == SSH_AUTH_SERVICE_SENT)
|
||||
goto pending;
|
||||
if (!username) {
|
||||
if(!(username = session->opts.username)) {
|
||||
if (ssh_options_set(session, SSH_OPTIONS_USER, NULL) < 0) {
|
||||
session->auth_service_state = SSH_AUTH_SERVICE_DENIED;
|
||||
return SSH_ERROR;
|
||||
} else {
|
||||
username = session->opts.username;
|
||||
}
|
||||
}
|
||||
}
|
||||
user = ssh_string_from_char(username);
|
||||
if (user == NULL) {
|
||||
return SSH_AUTH_ERROR;
|
||||
}
|
||||
|
||||
if (ssh_buffer_add_u8(session->out_buffer, SSH_CMSG_USER) < 0) {
|
||||
ssh_string_free(user);
|
||||
return SSH_AUTH_ERROR;
|
||||
}
|
||||
if (ssh_buffer_add_ssh_string(session->out_buffer, user) < 0) {
|
||||
ssh_string_free(user);
|
||||
return SSH_AUTH_ERROR;
|
||||
}
|
||||
ssh_string_free(user);
|
||||
session->auth_state=SSH_AUTH_STATE_NONE;
|
||||
session->auth_service_state = SSH_AUTH_SERVICE_SENT;
|
||||
if (ssh_packet_send(session) == SSH_ERROR) {
|
||||
return SSH_AUTH_ERROR;
|
||||
}
|
||||
return SSH_AUTH_AGAIN;
|
||||
pending:
|
||||
rc = wait_auth1_status(session);
|
||||
switch (rc){
|
||||
case SSH_AUTH_SUCCESS:
|
||||
session->auth_service_state=SSH_AUTH_SERVICE_USER_SENT;
|
||||
session->auth_state=SSH_AUTH_STATE_SUCCESS;
|
||||
ssh_set_error(session, SSH_NO_ERROR, "Authentication successful");
|
||||
return SSH_AUTH_SUCCESS;
|
||||
case SSH_AUTH_DENIED:
|
||||
session->auth_service_state=SSH_AUTH_SERVICE_USER_SENT;
|
||||
ssh_set_error(session,SSH_REQUEST_DENIED,"Password authentication necessary for user %s",username);
|
||||
return SSH_AUTH_DENIED;
|
||||
case SSH_AUTH_AGAIN:
|
||||
return SSH_AUTH_AGAIN;
|
||||
default:
|
||||
session->auth_service_state = SSH_AUTH_SERVICE_NONE;
|
||||
session->auth_state=SSH_AUTH_STATE_ERROR;
|
||||
return SSH_AUTH_ERROR;
|
||||
}
|
||||
}
|
||||
|
||||
/* use the "none" authentication question */
|
||||
int ssh_userauth1_none(ssh_session session, const char *username){
|
||||
return send_username(session, username);
|
||||
}
|
||||
|
||||
/** \internal
|
||||
* \todo implement ssh1 public key
|
||||
*/
|
||||
int ssh_userauth1_offer_pubkey(ssh_session session, const char *username,
|
||||
int type, ssh_string pubkey) {
|
||||
(void) session;
|
||||
(void) username;
|
||||
(void) type;
|
||||
(void) pubkey;
|
||||
|
||||
return SSH_AUTH_DENIED;
|
||||
}
|
||||
|
||||
int ssh_userauth1_password(ssh_session session, const char *username,
|
||||
const char *password) {
|
||||
ssh_string pwd = NULL;
|
||||
int rc;
|
||||
|
||||
if (session->pending_call_state == SSH_PENDING_CALL_AUTH_PASSWORD) {
|
||||
goto pending;
|
||||
}
|
||||
|
||||
rc = send_username(session, username);
|
||||
if (rc != SSH_AUTH_DENIED) {
|
||||
return rc;
|
||||
}
|
||||
/* we trick a bit here. A known flaw in SSH1 protocol is that it's
|
||||
* easy to guess password sizes.
|
||||
* not that sure ...
|
||||
*/
|
||||
|
||||
/* XXX fix me here ! */
|
||||
/* cisco IOS doesn't like when a password is followed by zeroes and random pad. */
|
||||
if(1 || strlen(password) >= 128) {
|
||||
/* not risky to disclose the size of such a big password .. */
|
||||
pwd = ssh_string_from_char(password);
|
||||
if (pwd == NULL) {
|
||||
return SSH_AUTH_ERROR;
|
||||
}
|
||||
} else {
|
||||
char buf[128] = {0};
|
||||
/* fill the password string from random things. the strcpy
|
||||
* ensure there is at least a nul byte after the password.
|
||||
* most implementation won't see the garbage at end.
|
||||
* why garbage ? because nul bytes will be compressed by
|
||||
* gzip and disclose password len.
|
||||
*/
|
||||
pwd = ssh_string_new(sizeof(buf));
|
||||
if (pwd == NULL) {
|
||||
return SSH_AUTH_ERROR;
|
||||
}
|
||||
ssh_get_random(buf, sizeof(buf), 0);
|
||||
strcpy(buf, password);
|
||||
ssh_string_fill(pwd, buf, sizeof(buf));
|
||||
}
|
||||
|
||||
if (ssh_buffer_add_u8(session->out_buffer, SSH_CMSG_AUTH_PASSWORD) < 0) {
|
||||
ssh_string_burn(pwd);
|
||||
ssh_string_free(pwd);
|
||||
|
||||
return SSH_AUTH_ERROR;
|
||||
}
|
||||
if (ssh_buffer_add_ssh_string(session->out_buffer, pwd) < 0) {
|
||||
ssh_string_burn(pwd);
|
||||
ssh_string_free(pwd);
|
||||
|
||||
return SSH_AUTH_ERROR;
|
||||
}
|
||||
|
||||
ssh_string_burn(pwd);
|
||||
ssh_string_free(pwd);
|
||||
session->auth_state=SSH_AUTH_STATE_NONE;
|
||||
session->pending_call_state = SSH_PENDING_CALL_AUTH_PASSWORD;
|
||||
if (ssh_packet_send(session) == SSH_ERROR) {
|
||||
return SSH_AUTH_ERROR;
|
||||
}
|
||||
pending:
|
||||
rc = wait_auth1_status(session);
|
||||
if (rc == SSH_AUTH_ERROR && errno == EAGAIN) {
|
||||
/* Nothing to do */
|
||||
} else if (rc != SSH_AUTH_AGAIN) {
|
||||
session->pending_call_state = SSH_PENDING_CALL_NONE;
|
||||
}
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
#endif /* WITH_SSH1 */
|
@@ -214,8 +214,7 @@ static int ssh_bind_import_keys(ssh_bind sshbind) {
|
||||
return SSH_ERROR;
|
||||
}
|
||||
|
||||
if (ssh_key_type(sshbind->rsa) != SSH_KEYTYPE_RSA &&
|
||||
ssh_key_type(sshbind->rsa) != SSH_KEYTYPE_RSA1) {
|
||||
if (ssh_key_type(sshbind->rsa) != SSH_KEYTYPE_RSA) {
|
||||
ssh_set_error(sshbind, SSH_FATAL,
|
||||
"The RSA host key has the wrong type");
|
||||
ssh_key_free(sshbind->rsa);
|
||||
@@ -394,7 +393,6 @@ int ssh_bind_accept_fd(ssh_bind sshbind, ssh_session session, socket_t fd){
|
||||
}
|
||||
|
||||
session->server = 1;
|
||||
session->version = 2;
|
||||
|
||||
/* copy options */
|
||||
for (i = 0; i < 10; i++) {
|
||||
|
35
src/buffer.c
35
src/buffer.c
@@ -683,41 +683,6 @@ struct ssh_string_struct *ssh_buffer_get_ssh_string(struct ssh_buffer_struct *bu
|
||||
return str;
|
||||
}
|
||||
|
||||
/**
|
||||
* @internal
|
||||
*
|
||||
* @brief Get a mpint out of the buffer and adjusts the read pointer.
|
||||
*
|
||||
* @note This function is SSH-1 only.
|
||||
*
|
||||
* @param[in] buffer The buffer to read.
|
||||
*
|
||||
* @returns The SSH String containing the mpint, NULL on error.
|
||||
*/
|
||||
struct ssh_string_struct *ssh_buffer_get_mpint(struct ssh_buffer_struct *buffer) {
|
||||
uint16_t bits;
|
||||
uint32_t len;
|
||||
struct ssh_string_struct *str = NULL;
|
||||
|
||||
if (ssh_buffer_get_data(buffer, &bits, sizeof(uint16_t)) != sizeof(uint16_t)) {
|
||||
return NULL;
|
||||
}
|
||||
bits = ntohs(bits);
|
||||
len = (bits + 7) / 8;
|
||||
if (buffer->pos + len < len || buffer->pos + len > buffer->used) {
|
||||
return NULL;
|
||||
}
|
||||
str = ssh_string_new(len);
|
||||
if (str == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
if (ssh_buffer_get_data(buffer, ssh_string_data(str), len) != len) {
|
||||
SAFE_FREE(str);
|
||||
return NULL;
|
||||
}
|
||||
return str;
|
||||
}
|
||||
|
||||
/** @internal
|
||||
* @brief Add multiple values in a buffer on a single function call
|
||||
* @param[in] buffer The buffer to add to
|
||||
|
@@ -106,7 +106,6 @@ ssh_channel ssh_channel_new(ssh_session session) {
|
||||
}
|
||||
|
||||
channel->session = session;
|
||||
channel->version = session->version;
|
||||
channel->exit_status = -1;
|
||||
channel->flags = SSH_CHANNEL_FLAG_NOT_BOUND;
|
||||
|
||||
@@ -346,13 +345,6 @@ static int grow_window(ssh_session session, ssh_channel channel, int minimumsize
|
||||
uint32_t new_window = minimumsize > WINDOWBASE ? minimumsize : WINDOWBASE;
|
||||
int rc;
|
||||
|
||||
#ifdef WITH_SSH1
|
||||
if (session->version == 1){
|
||||
channel->remote_window = new_window;
|
||||
|
||||
return SSH_OK;
|
||||
}
|
||||
#endif
|
||||
if(new_window <= channel->local_window){
|
||||
SSH_LOG(SSH_LOG_PROTOCOL,
|
||||
"growing window (channel %d:%d) to %d bytes : not needed (%d bytes)",
|
||||
@@ -398,8 +390,6 @@ error:
|
||||
*
|
||||
* @brief Parse a channel-related packet to resolve it to a ssh_channel.
|
||||
*
|
||||
* This works on SSH1 sessions too.
|
||||
*
|
||||
* @param[in] session The current SSH session.
|
||||
*
|
||||
* @param[in] packet The buffer to parse packet from. The read pointer will
|
||||
@@ -412,11 +402,7 @@ static ssh_channel channel_from_msg(ssh_session session, ssh_buffer packet) {
|
||||
ssh_channel channel;
|
||||
uint32_t chan;
|
||||
int rc;
|
||||
#ifdef WITH_SSH1
|
||||
/* With SSH1, the channel is always the first one */
|
||||
if(session->version==1)
|
||||
return ssh_get_channel1(session);
|
||||
#endif
|
||||
|
||||
rc = ssh_buffer_unpack(packet,"d",&chan);
|
||||
if (rc != SSH_OK) {
|
||||
ssh_set_error(session, SSH_FATAL,
|
||||
@@ -874,12 +860,6 @@ int ssh_channel_open_session(ssh_channel channel) {
|
||||
return SSH_ERROR;
|
||||
}
|
||||
|
||||
#ifdef WITH_SSH1
|
||||
if (channel->session->version == 1) {
|
||||
return ssh_channel_open_session1(channel);
|
||||
}
|
||||
#endif
|
||||
|
||||
return channel_open(channel,
|
||||
"session",
|
||||
CHANNEL_INITIAL_WINDOW,
|
||||
@@ -907,12 +887,6 @@ int ssh_channel_open_auth_agent(ssh_channel channel){
|
||||
return SSH_ERROR;
|
||||
}
|
||||
|
||||
#ifdef WITH_SSH1
|
||||
if (channel->session->version == 1) {
|
||||
return SSH_ERROR;
|
||||
}
|
||||
#endif
|
||||
|
||||
return channel_open(channel,
|
||||
"auth-agent@openssh.com",
|
||||
CHANNEL_INITIAL_WINDOW,
|
||||
@@ -1263,13 +1237,7 @@ static int channel_write_common(ssh_channel channel,
|
||||
if (session->session_state == SSH_SESSION_STATE_ERROR) {
|
||||
return SSH_ERROR;
|
||||
}
|
||||
#ifdef WITH_SSH1
|
||||
if (channel->version == 1) {
|
||||
rc = ssh_channel_write1(channel, data, len);
|
||||
|
||||
return rc;
|
||||
}
|
||||
#endif
|
||||
if (ssh_waitsession_unblocked(session) == 0){
|
||||
rc = ssh_handle_packets_termination(session, SSH_TIMEOUT_DEFAULT,
|
||||
ssh_waitsession_unblocked, session);
|
||||
@@ -1477,8 +1445,6 @@ void ssh_channel_set_blocking(ssh_channel channel, int blocking) {
|
||||
* @internal
|
||||
*
|
||||
* @brief handle a SSH_CHANNEL_SUCCESS packet and set the channel state.
|
||||
*
|
||||
* This works on SSH1 sessions too.
|
||||
*/
|
||||
SSH_PACKET_CALLBACK(ssh_packet_channel_success){
|
||||
ssh_channel channel;
|
||||
@@ -1509,8 +1475,6 @@ SSH_PACKET_CALLBACK(ssh_packet_channel_success){
|
||||
* @internal
|
||||
*
|
||||
* @brief Handle a SSH_CHANNEL_FAILURE packet and set the channel state.
|
||||
*
|
||||
* This works on SSH1 sessions too.
|
||||
*/
|
||||
SSH_PACKET_CALLBACK(ssh_packet_channel_failure){
|
||||
ssh_channel channel;
|
||||
@@ -1663,13 +1627,6 @@ int ssh_channel_request_pty_size(ssh_channel channel, const char *terminal,
|
||||
return rc;
|
||||
}
|
||||
|
||||
#ifdef WITH_SSH1
|
||||
if (channel->version==1) {
|
||||
rc = ssh_channel_request_pty_size1(channel,terminal, col, row);
|
||||
|
||||
return rc;
|
||||
}
|
||||
#endif
|
||||
switch(channel->request_state){
|
||||
case SSH_CHANNEL_REQ_STATE_NONE:
|
||||
break;
|
||||
@@ -1741,14 +1698,6 @@ int ssh_channel_change_pty_size(ssh_channel channel, int cols, int rows) {
|
||||
ssh_buffer buffer = NULL;
|
||||
int rc = SSH_ERROR;
|
||||
|
||||
#ifdef WITH_SSH1
|
||||
if (channel->version == 1) {
|
||||
rc = ssh_channel_change_pty_size1(channel,cols,rows);
|
||||
|
||||
return rc;
|
||||
}
|
||||
#endif
|
||||
|
||||
buffer = ssh_buffer_new();
|
||||
if (buffer == NULL) {
|
||||
ssh_set_error_oom(session);
|
||||
@@ -1787,12 +1736,8 @@ int ssh_channel_request_shell(ssh_channel channel) {
|
||||
if(channel == NULL) {
|
||||
return SSH_ERROR;
|
||||
}
|
||||
#ifdef WITH_SSH1
|
||||
if (channel->version == 1) {
|
||||
return ssh_channel_request_shell1(channel);
|
||||
}
|
||||
#endif
|
||||
return channel_request(channel, "shell", NULL, 1);
|
||||
|
||||
return channel_request(channel, "shell", NULL, 1);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -2428,11 +2373,6 @@ int ssh_channel_request_exec(ssh_channel channel, const char *cmd) {
|
||||
return rc;
|
||||
}
|
||||
|
||||
#ifdef WITH_SSH1
|
||||
if (channel->version == 1) {
|
||||
return ssh_channel_request_exec1(channel, cmd);
|
||||
}
|
||||
#endif
|
||||
switch(channel->request_state){
|
||||
case SSH_CHANNEL_REQ_STATE_NONE:
|
||||
break;
|
||||
@@ -2503,12 +2443,6 @@ int ssh_channel_request_send_signal(ssh_channel channel, const char *sig) {
|
||||
return rc;
|
||||
}
|
||||
|
||||
#ifdef WITH_SSH1
|
||||
if (channel->version == 1) {
|
||||
return SSH_ERROR; // TODO: Add support for SSH-v1 if possible.
|
||||
}
|
||||
#endif
|
||||
|
||||
buffer = ssh_buffer_new();
|
||||
if (buffer == NULL) {
|
||||
ssh_set_error_oom(channel->session);
|
||||
@@ -2551,12 +2485,6 @@ int ssh_channel_request_send_break(ssh_channel channel, uint32_t length) {
|
||||
return SSH_ERROR;
|
||||
}
|
||||
|
||||
#ifdef WITH_SSH1
|
||||
if (channel->version == 1) {
|
||||
return SSH_ERROR;
|
||||
}
|
||||
#endif
|
||||
|
||||
buffer = ssh_buffer_new();
|
||||
if (buffer == NULL) {
|
||||
ssh_set_error_oom(channel->session);
|
||||
@@ -3432,12 +3360,6 @@ int ssh_channel_request_send_exit_status(ssh_channel channel, int exit_status) {
|
||||
return SSH_ERROR;
|
||||
}
|
||||
|
||||
#ifdef WITH_SSH1
|
||||
if (channel->version == 1) {
|
||||
return SSH_ERROR; // TODO: Add support for SSH-v1 if possible.
|
||||
}
|
||||
#endif
|
||||
|
||||
buffer = ssh_buffer_new();
|
||||
if (buffer == NULL) {
|
||||
ssh_set_error_oom(channel->session);
|
||||
@@ -3487,11 +3409,6 @@ int ssh_channel_request_send_exit_signal(ssh_channel channel, const char *sig,
|
||||
ssh_set_error_invalid(channel->session);
|
||||
return rc;
|
||||
}
|
||||
#ifdef WITH_SSH1
|
||||
if (channel->version == 1) {
|
||||
return SSH_ERROR; // TODO: Add support for SSH-v1 if possible.
|
||||
}
|
||||
#endif
|
||||
|
||||
buffer = ssh_buffer_new();
|
||||
if (buffer == NULL) {
|
||||
|
397
src/channels1.c
397
src/channels1.c
@@ -1,397 +0,0 @@
|
||||
/*
|
||||
* channels1.c - Support for SSH-1 type channels
|
||||
*
|
||||
* This file is part of the SSH Library
|
||||
*
|
||||
* Copyright (c) 2003-2008 by Aris Adamantiadis
|
||||
* Copyright (c) 2009 by Andreas Schneider <asn@cryptomilk.org>
|
||||
*
|
||||
* The SSH Library is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as published by
|
||||
* the Free Software Foundation; either version 2.1 of the License, or (at your
|
||||
* option) any later version.
|
||||
*
|
||||
* The SSH Library is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
|
||||
* License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with the SSH Library; see the file COPYING. If not, write to
|
||||
* the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
|
||||
* MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#ifndef _WIN32
|
||||
#include <arpa/inet.h>
|
||||
#endif
|
||||
#ifdef HAVE_UNISTD_H
|
||||
#include <unistd.h>
|
||||
#endif
|
||||
|
||||
#include "libssh/priv.h"
|
||||
#include "libssh/ssh1.h"
|
||||
#include "libssh/buffer.h"
|
||||
#include "libssh/packet.h"
|
||||
#include "libssh/channels.h"
|
||||
#include "libssh/session.h"
|
||||
#include "libssh/misc.h"
|
||||
|
||||
#ifdef WITH_SSH1
|
||||
|
||||
/*
|
||||
* This is a big hack. In fact, SSH1 doesn't make a clever use of channels.
|
||||
* The whole packets concerning shells are sent outside of a channel.
|
||||
* Thus, an inside limitation of this behavior is that you can't only
|
||||
* request one shell.
|
||||
* The question is still how they managed to embed two "channel" into one
|
||||
* protocol.
|
||||
*/
|
||||
|
||||
int ssh_channel_open_session1(ssh_channel chan) {
|
||||
ssh_session session;
|
||||
|
||||
if (chan == NULL) {
|
||||
return -1;
|
||||
}
|
||||
session = chan->session;
|
||||
|
||||
/*
|
||||
* We guess we are requesting an *exec* channel. It can only have one exec
|
||||
* channel. So we abort with an error if we need more than one.
|
||||
*/
|
||||
if (session->exec_channel_opened) {
|
||||
ssh_set_error(session, SSH_REQUEST_DENIED,
|
||||
"SSH1 supports only one execution channel. "
|
||||
"One has already been opened");
|
||||
return -1;
|
||||
}
|
||||
session->exec_channel_opened = 1;
|
||||
chan->request_state = SSH_CHANNEL_REQ_STATE_ACCEPTED;
|
||||
chan->state = SSH_CHANNEL_STATE_OPEN;
|
||||
chan->local_maxpacket = 32000;
|
||||
chan->local_window = 64000;
|
||||
SSH_LOG(SSH_LOG_PACKET, "Opened a SSH1 channel session");
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* 10 SSH_CMSG_REQUEST_PTY
|
||||
*
|
||||
* string TERM environment variable value (e.g. vt100)
|
||||
* 32-bit int terminal height, rows (e.g., 24)
|
||||
* 32-bit int terminal width, columns (e.g., 80)
|
||||
* 32-bit int terminal width, pixels (0 if no graphics) (e.g., 480)
|
||||
* 32-bit int terminal height, pixels (0 if no graphics) (e.g., 640)
|
||||
* n bytes tty modes encoded in binary
|
||||
* Some day, someone should have a look at that nasty tty encoded. It's
|
||||
* much simplier under ssh2. I just hope the defaults values are ok ...
|
||||
*/
|
||||
|
||||
int ssh_channel_request_pty_size1(ssh_channel channel, const char *terminal, int col,
|
||||
int row) {
|
||||
ssh_session session;
|
||||
ssh_string str = NULL;
|
||||
|
||||
if (channel == NULL) {
|
||||
return SSH_ERROR;
|
||||
}
|
||||
session = channel->session;
|
||||
|
||||
if(channel->request_state != SSH_CHANNEL_REQ_STATE_NONE &&
|
||||
channel->request_state != SSH_CHANNEL_REQ_STATE_ACCEPTED){
|
||||
ssh_set_error(session,SSH_REQUEST_DENIED,"Wrong request state");
|
||||
return SSH_ERROR;
|
||||
}
|
||||
str = ssh_string_from_char(terminal);
|
||||
if (str == NULL) {
|
||||
ssh_set_error_oom(session);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (ssh_buffer_add_u8(session->out_buffer, SSH_CMSG_REQUEST_PTY) < 0 ||
|
||||
ssh_buffer_add_ssh_string(session->out_buffer, str) < 0) {
|
||||
ssh_string_free(str);
|
||||
return -1;
|
||||
}
|
||||
ssh_string_free(str);
|
||||
|
||||
if (ssh_buffer_add_u32(session->out_buffer, ntohl(row)) < 0 ||
|
||||
ssh_buffer_add_u32(session->out_buffer, ntohl(col)) < 0 ||
|
||||
ssh_buffer_add_u32(session->out_buffer, 0) < 0 || /* x */
|
||||
ssh_buffer_add_u32(session->out_buffer, 0) < 0 || /* y */
|
||||
ssh_buffer_add_u8(session->out_buffer, 0) < 0) { /* tty things */
|
||||
return -1;
|
||||
}
|
||||
|
||||
SSH_LOG(SSH_LOG_FUNCTIONS, "Opening a ssh1 pty");
|
||||
channel->request_state = SSH_CHANNEL_REQ_STATE_PENDING;
|
||||
if (ssh_packet_send(session) == SSH_ERROR) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
while (channel->request_state == SSH_CHANNEL_REQ_STATE_PENDING) {
|
||||
ssh_handle_packets(session, SSH_TIMEOUT_INFINITE);
|
||||
}
|
||||
|
||||
switch(channel->request_state){
|
||||
case SSH_CHANNEL_REQ_STATE_ERROR:
|
||||
case SSH_CHANNEL_REQ_STATE_PENDING:
|
||||
case SSH_CHANNEL_REQ_STATE_NONE:
|
||||
channel->request_state=SSH_CHANNEL_REQ_STATE_NONE;
|
||||
return SSH_ERROR;
|
||||
case SSH_CHANNEL_REQ_STATE_ACCEPTED:
|
||||
channel->request_state=SSH_CHANNEL_REQ_STATE_NONE;
|
||||
SSH_LOG(SSH_LOG_RARE, "PTY: Success");
|
||||
return SSH_OK;
|
||||
case SSH_CHANNEL_REQ_STATE_DENIED:
|
||||
channel->request_state=SSH_CHANNEL_REQ_STATE_NONE;
|
||||
ssh_set_error(session, SSH_REQUEST_DENIED,
|
||||
"Server denied PTY allocation");
|
||||
SSH_LOG(SSH_LOG_RARE, "PTY: denied");
|
||||
return SSH_ERROR;
|
||||
}
|
||||
// Not reached
|
||||
return SSH_ERROR;
|
||||
}
|
||||
|
||||
int ssh_channel_change_pty_size1(ssh_channel channel, int cols, int rows) {
|
||||
ssh_session session;
|
||||
|
||||
if (channel == NULL) {
|
||||
return SSH_ERROR;
|
||||
}
|
||||
session = channel->session;
|
||||
|
||||
if(channel->request_state != SSH_CHANNEL_REQ_STATE_NONE){
|
||||
ssh_set_error(session,SSH_REQUEST_DENIED,"Wrong request state");
|
||||
return SSH_ERROR;
|
||||
}
|
||||
if (ssh_buffer_add_u8(session->out_buffer, SSH_CMSG_WINDOW_SIZE) < 0 ||
|
||||
ssh_buffer_add_u32(session->out_buffer, ntohl(rows)) < 0 ||
|
||||
ssh_buffer_add_u32(session->out_buffer, ntohl(cols)) < 0 ||
|
||||
ssh_buffer_add_u32(session->out_buffer, 0) < 0 ||
|
||||
ssh_buffer_add_u32(session->out_buffer, 0) < 0) {
|
||||
return SSH_ERROR;
|
||||
}
|
||||
channel->request_state=SSH_CHANNEL_REQ_STATE_PENDING;
|
||||
if (ssh_packet_send(session) == SSH_ERROR) {
|
||||
return SSH_ERROR;
|
||||
}
|
||||
|
||||
SSH_LOG(SSH_LOG_PROTOCOL, "Change pty size send");
|
||||
while(channel->request_state==SSH_CHANNEL_REQ_STATE_PENDING){
|
||||
ssh_handle_packets(session, SSH_TIMEOUT_INFINITE);
|
||||
}
|
||||
switch(channel->request_state){
|
||||
case SSH_CHANNEL_REQ_STATE_ERROR:
|
||||
case SSH_CHANNEL_REQ_STATE_PENDING:
|
||||
case SSH_CHANNEL_REQ_STATE_NONE:
|
||||
channel->request_state=SSH_CHANNEL_REQ_STATE_NONE;
|
||||
return SSH_ERROR;
|
||||
case SSH_CHANNEL_REQ_STATE_ACCEPTED:
|
||||
channel->request_state=SSH_CHANNEL_REQ_STATE_NONE;
|
||||
SSH_LOG(SSH_LOG_PROTOCOL, "pty size changed");
|
||||
return SSH_OK;
|
||||
case SSH_CHANNEL_REQ_STATE_DENIED:
|
||||
channel->request_state=SSH_CHANNEL_REQ_STATE_NONE;
|
||||
SSH_LOG(SSH_LOG_RARE, "pty size change denied");
|
||||
ssh_set_error(session, SSH_REQUEST_DENIED, "pty size change denied");
|
||||
return SSH_ERROR;
|
||||
}
|
||||
// Not reached
|
||||
return SSH_ERROR;
|
||||
|
||||
}
|
||||
|
||||
int ssh_channel_request_shell1(ssh_channel channel) {
|
||||
ssh_session session;
|
||||
|
||||
if (channel == NULL) {
|
||||
return -1;
|
||||
}
|
||||
session = channel->session;
|
||||
|
||||
if (ssh_buffer_add_u8(session->out_buffer,SSH_CMSG_EXEC_SHELL) < 0) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (ssh_packet_send(session) == SSH_ERROR) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
SSH_LOG(SSH_LOG_RARE, "Launched a shell");
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int ssh_channel_request_exec1(ssh_channel channel, const char *cmd) {
|
||||
ssh_session session;
|
||||
ssh_string command = NULL;
|
||||
|
||||
if (channel == NULL) {
|
||||
return -1;
|
||||
}
|
||||
session = channel->session;
|
||||
|
||||
command = ssh_string_from_char(cmd);
|
||||
if (command == NULL) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (ssh_buffer_add_u8(session->out_buffer, SSH_CMSG_EXEC_CMD) < 0 ||
|
||||
ssh_buffer_add_ssh_string(session->out_buffer, command) < 0) {
|
||||
ssh_string_free(command);
|
||||
return -1;
|
||||
}
|
||||
ssh_string_free(command);
|
||||
|
||||
if(ssh_packet_send(session) == SSH_ERROR) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
SSH_LOG(SSH_LOG_RARE, "Executing %s ...", cmd);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
SSH_PACKET_CALLBACK(ssh_packet_data1){
|
||||
ssh_channel channel = ssh_get_channel1(session);
|
||||
ssh_string str = NULL;
|
||||
int is_stderr=(type==SSH_SMSG_STDOUT_DATA ? 0 : 1);
|
||||
(void)user;
|
||||
|
||||
if (channel == NULL) {
|
||||
return SSH_PACKET_NOT_USED;
|
||||
}
|
||||
|
||||
str = ssh_buffer_get_ssh_string(packet);
|
||||
if (str == NULL) {
|
||||
SSH_LOG(SSH_LOG_FUNCTIONS, "Invalid data packet !");
|
||||
return SSH_PACKET_USED;
|
||||
}
|
||||
|
||||
SSH_LOG(SSH_LOG_PROTOCOL,
|
||||
"Adding %" PRIdS " bytes data in %d",
|
||||
ssh_string_len(str), is_stderr);
|
||||
|
||||
if (channel_default_bufferize(channel, ssh_string_data(str), ssh_string_len(str),
|
||||
is_stderr) < 0) {
|
||||
ssh_string_free(str);
|
||||
return SSH_PACKET_USED;
|
||||
}
|
||||
ssh_string_free(str);
|
||||
|
||||
return SSH_PACKET_USED;
|
||||
}
|
||||
|
||||
SSH_PACKET_CALLBACK(ssh_packet_close1){
|
||||
ssh_channel channel = ssh_get_channel1(session);
|
||||
uint32_t status;
|
||||
int rc;
|
||||
|
||||
(void)type;
|
||||
(void)user;
|
||||
|
||||
if (channel == NULL) {
|
||||
return SSH_PACKET_NOT_USED;
|
||||
}
|
||||
|
||||
ssh_buffer_get_u32(packet, &status);
|
||||
/*
|
||||
* It's much more than a channel closing. spec says it's the last
|
||||
* message sent by server (strange)
|
||||
*/
|
||||
|
||||
/* actually status is lost somewhere */
|
||||
channel->state = SSH_CHANNEL_STATE_CLOSED;
|
||||
channel->remote_eof = 1;
|
||||
|
||||
rc = ssh_buffer_add_u8(session->out_buffer, SSH_CMSG_EXIT_CONFIRMATION);
|
||||
if (rc < 0) {
|
||||
return SSH_PACKET_NOT_USED;
|
||||
}
|
||||
ssh_packet_send(session);
|
||||
|
||||
return SSH_PACKET_USED;
|
||||
}
|
||||
|
||||
SSH_PACKET_CALLBACK(ssh_packet_exist_status1){
|
||||
ssh_channel channel = ssh_get_channel1(session);
|
||||
uint32_t status;
|
||||
(void)type;
|
||||
(void)user;
|
||||
|
||||
if (channel == NULL) {
|
||||
return SSH_PACKET_NOT_USED;
|
||||
}
|
||||
|
||||
ssh_buffer_get_u32(packet, &status);
|
||||
channel->state = SSH_CHANNEL_STATE_CLOSED;
|
||||
channel->remote_eof = 1;
|
||||
channel->exit_status = ntohl(status);
|
||||
|
||||
return SSH_PACKET_USED;
|
||||
}
|
||||
|
||||
|
||||
int ssh_channel_write1(ssh_channel channel, const void *data, int len) {
|
||||
ssh_session session;
|
||||
int origlen = len;
|
||||
int effectivelen;
|
||||
const unsigned char *ptr=data;
|
||||
|
||||
if (channel == NULL) {
|
||||
return -1;
|
||||
}
|
||||
session = channel->session;
|
||||
|
||||
while (len > 0) {
|
||||
if (ssh_buffer_add_u8(session->out_buffer, SSH_CMSG_STDIN_DATA) < 0) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
effectivelen = len > 32000 ? 32000 : len;
|
||||
|
||||
if (ssh_buffer_add_u32(session->out_buffer, htonl(effectivelen)) < 0 ||
|
||||
ssh_buffer_add_data(session->out_buffer, ptr, effectivelen) < 0) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
ptr += effectivelen;
|
||||
len -= effectivelen;
|
||||
|
||||
if (ssh_packet_send(session) == SSH_ERROR) {
|
||||
return -1;
|
||||
}
|
||||
ssh_handle_packets(session, SSH_TIMEOUT_NONBLOCKING);
|
||||
if (channel->counter != NULL) {
|
||||
channel->counter->out_bytes += effectivelen;
|
||||
}
|
||||
}
|
||||
if (ssh_blocking_flush(session,SSH_TIMEOUT_USER) == SSH_ERROR)
|
||||
return -1;
|
||||
return origlen;
|
||||
}
|
||||
|
||||
ssh_channel ssh_get_channel1(ssh_session session){
|
||||
struct ssh_iterator *it;
|
||||
|
||||
if (session == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* With SSH1, the channel is always the first one */
|
||||
if(session->channels != NULL){
|
||||
it = ssh_list_get_iterator(session->channels);
|
||||
if(it)
|
||||
return ssh_iterator_value(ssh_channel, it);
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
#endif /* WITH_SSH1 */
|
198
src/client.c
198
src/client.c
@@ -171,16 +171,13 @@ static int callback_receive_banner(const void *data, size_t len, void *user)
|
||||
*/
|
||||
int ssh_send_banner(ssh_session session, int server)
|
||||
{
|
||||
const char *banner = NULL;
|
||||
const char *terminator = NULL;
|
||||
const char *banner = CLIENT_BANNER_SSH2;
|
||||
const char *terminator = "\r\n";
|
||||
/* The maximum banner length is 255 for SSH2 */
|
||||
char buffer[256] = {0};
|
||||
size_t len;
|
||||
int rc = SSH_ERROR;
|
||||
|
||||
banner = session->version == 1 ? CLIENTBANNER1 : CLIENTBANNER2;
|
||||
terminator = session->version == 1 ? "\n" : "\r\n";
|
||||
|
||||
if (server == 1) {
|
||||
if (session->opts.custombanner == NULL){
|
||||
len = strlen(banner);
|
||||
@@ -211,11 +208,8 @@ int ssh_send_banner(ssh_session session, int server)
|
||||
goto end;
|
||||
}
|
||||
|
||||
/* SSH version 1 has a banner length of 128 only */
|
||||
len = session->version == 1 ? 128 : 0;
|
||||
|
||||
snprintf(buffer,
|
||||
sizeof(buffer) - len,
|
||||
sizeof(buffer),
|
||||
"%s%s",
|
||||
session->clientbanner,
|
||||
terminator);
|
||||
@@ -361,8 +355,6 @@ pending:
|
||||
rc=SSH_AGAIN;
|
||||
break;
|
||||
case SSH_AUTH_SERVICE_NONE:
|
||||
case SSH_AUTH_SERVICE_USER_SENT:
|
||||
/* Invalid state, SSH1 specific */
|
||||
rc=SSH_ERROR;
|
||||
break;
|
||||
}
|
||||
@@ -382,122 +374,86 @@ pending:
|
||||
* @brief A function to be called each time a step has been done in the
|
||||
* connection.
|
||||
*/
|
||||
static void ssh_client_connection_callback(ssh_session session){
|
||||
int ssh1,ssh2;
|
||||
static void ssh_client_connection_callback(ssh_session session)
|
||||
{
|
||||
int rc;
|
||||
|
||||
switch(session->session_state){
|
||||
case SSH_SESSION_STATE_NONE:
|
||||
case SSH_SESSION_STATE_CONNECTING:
|
||||
break;
|
||||
case SSH_SESSION_STATE_SOCKET_CONNECTED:
|
||||
/* If SSHv1 is disabled, we can send the banner immedietly */
|
||||
if (session->opts.ssh1 == 0) {
|
||||
ssh_set_fd_towrite(session);
|
||||
ssh_send_banner(session, 0);
|
||||
switch(session->session_state) {
|
||||
case SSH_SESSION_STATE_NONE:
|
||||
case SSH_SESSION_STATE_CONNECTING:
|
||||
break;
|
||||
case SSH_SESSION_STATE_SOCKET_CONNECTED:
|
||||
ssh_set_fd_towrite(session);
|
||||
ssh_send_banner(session, 0);
|
||||
|
||||
break;
|
||||
case SSH_SESSION_STATE_BANNER_RECEIVED:
|
||||
if (session->serverbanner == NULL) {
|
||||
goto error;
|
||||
}
|
||||
break;
|
||||
case SSH_SESSION_STATE_BANNER_RECEIVED:
|
||||
if (session->serverbanner == NULL) {
|
||||
goto error;
|
||||
}
|
||||
set_status(session, 0.4f);
|
||||
SSH_LOG(SSH_LOG_RARE,
|
||||
"SSH server banner: %s", session->serverbanner);
|
||||
set_status(session, 0.4f);
|
||||
SSH_LOG(SSH_LOG_RARE,
|
||||
"SSH server banner: %s", session->serverbanner);
|
||||
|
||||
/* Here we analyze the different protocols the server allows. */
|
||||
if (ssh_analyze_banner(session, 0, &ssh1, &ssh2) < 0) {
|
||||
goto error;
|
||||
}
|
||||
/* Here we decide which version of the protocol to use. */
|
||||
if (ssh2 && session->opts.ssh2) {
|
||||
session->version = 2;
|
||||
#ifdef WITH_SSH1
|
||||
} else if(ssh1 && session->opts.ssh1) {
|
||||
session->version = 1;
|
||||
#endif
|
||||
} else if(ssh1 && !session->opts.ssh1){
|
||||
#ifdef WITH_SSH1
|
||||
ssh_set_error(session, SSH_FATAL,
|
||||
"SSH-1 protocol not available (configure session to allow SSH-1)");
|
||||
goto error;
|
||||
#else
|
||||
ssh_set_error(session, SSH_FATAL,
|
||||
"SSH-1 protocol not available (libssh compiled without SSH-1 support)");
|
||||
goto error;
|
||||
#endif
|
||||
} else {
|
||||
ssh_set_error(session, SSH_FATAL,
|
||||
"No version of SSH protocol usable (banner: %s)",
|
||||
session->serverbanner);
|
||||
goto error;
|
||||
}
|
||||
/* from now, the packet layer is handling incoming packets */
|
||||
if (session->version == 2) {
|
||||
ssh_packet_register_socket_callback(session, session->socket);
|
||||
}
|
||||
#ifdef WITH_SSH1
|
||||
else
|
||||
session->socket_callbacks.data=ssh_packet_socket_callback1;
|
||||
#endif
|
||||
ssh_packet_set_default_callbacks(session);
|
||||
session->session_state=SSH_SESSION_STATE_INITIAL_KEX;
|
||||
if (session->opts.ssh1 == 1) {
|
||||
ssh_send_banner(session, 0);
|
||||
}
|
||||
set_status(session, 0.5f);
|
||||
break;
|
||||
case SSH_SESSION_STATE_INITIAL_KEX:
|
||||
/* TODO: This state should disappear in favor of get_key handle */
|
||||
#ifdef WITH_SSH1
|
||||
if(session->version==1){
|
||||
if (ssh_get_kex1(session) < 0)
|
||||
goto error;
|
||||
set_status(session,0.6f);
|
||||
session->connected = 1;
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
break;
|
||||
case SSH_SESSION_STATE_KEXINIT_RECEIVED:
|
||||
set_status(session,0.6f);
|
||||
ssh_list_kex(&session->next_crypto->server_kex);
|
||||
if (ssh_set_client_kex(session) < 0) {
|
||||
goto error;
|
||||
}
|
||||
if (ssh_kex_select_methods(session) == SSH_ERROR)
|
||||
goto error;
|
||||
if (ssh_send_kex(session, 0) < 0) {
|
||||
goto error;
|
||||
}
|
||||
set_status(session,0.8f);
|
||||
session->session_state=SSH_SESSION_STATE_DH;
|
||||
if (dh_handshake(session) == SSH_ERROR) {
|
||||
goto error;
|
||||
}
|
||||
/* Here we analyze the different protocols the server allows. */
|
||||
rc = ssh_analyze_banner(session, 0);
|
||||
if (rc < 0) {
|
||||
ssh_set_error(session, SSH_FATAL,
|
||||
"No version of SSH protocol usable (banner: %s)",
|
||||
session->serverbanner);
|
||||
goto error;
|
||||
}
|
||||
|
||||
ssh_packet_register_socket_callback(session, session->socket);
|
||||
|
||||
ssh_packet_set_default_callbacks(session);
|
||||
session->session_state = SSH_SESSION_STATE_INITIAL_KEX;
|
||||
set_status(session, 0.5f);
|
||||
|
||||
break;
|
||||
case SSH_SESSION_STATE_INITIAL_KEX:
|
||||
/* TODO: This state should disappear in favor of get_key handle */
|
||||
break;
|
||||
case SSH_SESSION_STATE_KEXINIT_RECEIVED:
|
||||
set_status(session,0.6f);
|
||||
ssh_list_kex(&session->next_crypto->server_kex);
|
||||
if (ssh_set_client_kex(session) < 0) {
|
||||
goto error;
|
||||
}
|
||||
if (ssh_kex_select_methods(session) == SSH_ERROR)
|
||||
goto error;
|
||||
if (ssh_send_kex(session, 0) < 0) {
|
||||
goto error;
|
||||
}
|
||||
set_status(session,0.8f);
|
||||
session->session_state=SSH_SESSION_STATE_DH;
|
||||
if (dh_handshake(session) == SSH_ERROR) {
|
||||
goto error;
|
||||
}
|
||||
/* FALL THROUGH */
|
||||
case SSH_SESSION_STATE_DH:
|
||||
if(session->dh_handshake_state==DH_STATE_FINISHED){
|
||||
set_status(session,1.0f);
|
||||
session->connected = 1;
|
||||
if (session->flags & SSH_SESSION_FLAG_AUTHENTICATED)
|
||||
session->session_state = SSH_SESSION_STATE_AUTHENTICATED;
|
||||
else
|
||||
session->session_state=SSH_SESSION_STATE_AUTHENTICATING;
|
||||
}
|
||||
break;
|
||||
case SSH_SESSION_STATE_AUTHENTICATING:
|
||||
break;
|
||||
case SSH_SESSION_STATE_ERROR:
|
||||
goto error;
|
||||
default:
|
||||
ssh_set_error(session,SSH_FATAL,"Invalid state %d",session->session_state);
|
||||
}
|
||||
case SSH_SESSION_STATE_DH:
|
||||
if(session->dh_handshake_state==DH_STATE_FINISHED){
|
||||
set_status(session,1.0f);
|
||||
session->connected = 1;
|
||||
if (session->flags & SSH_SESSION_FLAG_AUTHENTICATED)
|
||||
session->session_state = SSH_SESSION_STATE_AUTHENTICATED;
|
||||
else
|
||||
session->session_state=SSH_SESSION_STATE_AUTHENTICATING;
|
||||
}
|
||||
break;
|
||||
case SSH_SESSION_STATE_AUTHENTICATING:
|
||||
break;
|
||||
case SSH_SESSION_STATE_ERROR:
|
||||
goto error;
|
||||
default:
|
||||
ssh_set_error(session,SSH_FATAL,"Invalid state %d",session->session_state);
|
||||
}
|
||||
|
||||
return;
|
||||
return;
|
||||
error:
|
||||
ssh_socket_close(session->socket);
|
||||
session->alive = 0;
|
||||
session->session_state=SSH_SESSION_STATE_ERROR;
|
||||
ssh_socket_close(session->socket);
|
||||
session->alive = 0;
|
||||
session->session_state=SSH_SESSION_STATE_ERROR;
|
||||
|
||||
}
|
||||
|
||||
|
@@ -487,14 +487,11 @@ static int ssh_config_parse_line(ssh_session session, const char *line,
|
||||
return -1;
|
||||
}
|
||||
i = 0;
|
||||
ssh_options_set(session, SSH_OPTIONS_SSH1, &i);
|
||||
ssh_options_set(session, SSH_OPTIONS_SSH2, &i);
|
||||
|
||||
for (a = strtok(b, ","); a; a = strtok(NULL, ",")) {
|
||||
switch (atoi(a)) {
|
||||
case 1:
|
||||
i = 1;
|
||||
ssh_options_set(session, SSH_OPTIONS_SSH1, &i);
|
||||
break;
|
||||
case 2:
|
||||
i = 1;
|
||||
|
93
src/crc32.c
93
src/crc32.c
@@ -1,93 +0,0 @@
|
||||
/*
|
||||
* crc32.c - simple CRC32 code
|
||||
*
|
||||
* This file is part of the SSH Library
|
||||
*
|
||||
* Copyright (c) 2005 by Aris Adamantiadis
|
||||
*
|
||||
* The SSH Library is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as published by
|
||||
* the Free Software Foundation; either version 2.1 of the License, or (at your
|
||||
* option) any later version.
|
||||
*
|
||||
* The SSH Library is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
|
||||
* License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with the SSH Library; see the file COPYING. If not, write to
|
||||
* the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
|
||||
* MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include "libssh/priv.h"
|
||||
#include "libssh/crc32.h"
|
||||
|
||||
static uint32_t crc_table[] = {
|
||||
0x00000000UL, 0x77073096UL, 0xee0e612cUL, 0x990951baUL, 0x076dc419UL,
|
||||
0x706af48fUL, 0xe963a535UL, 0x9e6495a3UL, 0x0edb8832UL, 0x79dcb8a4UL,
|
||||
0xe0d5e91eUL, 0x97d2d988UL, 0x09b64c2bUL, 0x7eb17cbdUL, 0xe7b82d07UL,
|
||||
0x90bf1d91UL, 0x1db71064UL, 0x6ab020f2UL, 0xf3b97148UL, 0x84be41deUL,
|
||||
0x1adad47dUL, 0x6ddde4ebUL, 0xf4d4b551UL, 0x83d385c7UL, 0x136c9856UL,
|
||||
0x646ba8c0UL, 0xfd62f97aUL, 0x8a65c9ecUL, 0x14015c4fUL, 0x63066cd9UL,
|
||||
0xfa0f3d63UL, 0x8d080df5UL, 0x3b6e20c8UL, 0x4c69105eUL, 0xd56041e4UL,
|
||||
0xa2677172UL, 0x3c03e4d1UL, 0x4b04d447UL, 0xd20d85fdUL, 0xa50ab56bUL,
|
||||
0x35b5a8faUL, 0x42b2986cUL, 0xdbbbc9d6UL, 0xacbcf940UL, 0x32d86ce3UL,
|
||||
0x45df5c75UL, 0xdcd60dcfUL, 0xabd13d59UL, 0x26d930acUL, 0x51de003aUL,
|
||||
0xc8d75180UL, 0xbfd06116UL, 0x21b4f4b5UL, 0x56b3c423UL, 0xcfba9599UL,
|
||||
0xb8bda50fUL, 0x2802b89eUL, 0x5f058808UL, 0xc60cd9b2UL, 0xb10be924UL,
|
||||
0x2f6f7c87UL, 0x58684c11UL, 0xc1611dabUL, 0xb6662d3dUL, 0x76dc4190UL,
|
||||
0x01db7106UL, 0x98d220bcUL, 0xefd5102aUL, 0x71b18589UL, 0x06b6b51fUL,
|
||||
0x9fbfe4a5UL, 0xe8b8d433UL, 0x7807c9a2UL, 0x0f00f934UL, 0x9609a88eUL,
|
||||
0xe10e9818UL, 0x7f6a0dbbUL, 0x086d3d2dUL, 0x91646c97UL, 0xe6635c01UL,
|
||||
0x6b6b51f4UL, 0x1c6c6162UL, 0x856530d8UL, 0xf262004eUL, 0x6c0695edUL,
|
||||
0x1b01a57bUL, 0x8208f4c1UL, 0xf50fc457UL, 0x65b0d9c6UL, 0x12b7e950UL,
|
||||
0x8bbeb8eaUL, 0xfcb9887cUL, 0x62dd1ddfUL, 0x15da2d49UL, 0x8cd37cf3UL,
|
||||
0xfbd44c65UL, 0x4db26158UL, 0x3ab551ceUL, 0xa3bc0074UL, 0xd4bb30e2UL,
|
||||
0x4adfa541UL, 0x3dd895d7UL, 0xa4d1c46dUL, 0xd3d6f4fbUL, 0x4369e96aUL,
|
||||
0x346ed9fcUL, 0xad678846UL, 0xda60b8d0UL, 0x44042d73UL, 0x33031de5UL,
|
||||
0xaa0a4c5fUL, 0xdd0d7cc9UL, 0x5005713cUL, 0x270241aaUL, 0xbe0b1010UL,
|
||||
0xc90c2086UL, 0x5768b525UL, 0x206f85b3UL, 0xb966d409UL, 0xce61e49fUL,
|
||||
0x5edef90eUL, 0x29d9c998UL, 0xb0d09822UL, 0xc7d7a8b4UL, 0x59b33d17UL,
|
||||
0x2eb40d81UL, 0xb7bd5c3bUL, 0xc0ba6cadUL, 0xedb88320UL, 0x9abfb3b6UL,
|
||||
0x03b6e20cUL, 0x74b1d29aUL, 0xead54739UL, 0x9dd277afUL, 0x04db2615UL,
|
||||
0x73dc1683UL, 0xe3630b12UL, 0x94643b84UL, 0x0d6d6a3eUL, 0x7a6a5aa8UL,
|
||||
0xe40ecf0bUL, 0x9309ff9dUL, 0x0a00ae27UL, 0x7d079eb1UL, 0xf00f9344UL,
|
||||
0x8708a3d2UL, 0x1e01f268UL, 0x6906c2feUL, 0xf762575dUL, 0x806567cbUL,
|
||||
0x196c3671UL, 0x6e6b06e7UL, 0xfed41b76UL, 0x89d32be0UL, 0x10da7a5aUL,
|
||||
0x67dd4accUL, 0xf9b9df6fUL, 0x8ebeeff9UL, 0x17b7be43UL, 0x60b08ed5UL,
|
||||
0xd6d6a3e8UL, 0xa1d1937eUL, 0x38d8c2c4UL, 0x4fdff252UL, 0xd1bb67f1UL,
|
||||
0xa6bc5767UL, 0x3fb506ddUL, 0x48b2364bUL, 0xd80d2bdaUL, 0xaf0a1b4cUL,
|
||||
0x36034af6UL, 0x41047a60UL, 0xdf60efc3UL, 0xa867df55UL, 0x316e8eefUL,
|
||||
0x4669be79UL, 0xcb61b38cUL, 0xbc66831aUL, 0x256fd2a0UL, 0x5268e236UL,
|
||||
0xcc0c7795UL, 0xbb0b4703UL, 0x220216b9UL, 0x5505262fUL, 0xc5ba3bbeUL,
|
||||
0xb2bd0b28UL, 0x2bb45a92UL, 0x5cb36a04UL, 0xc2d7ffa7UL, 0xb5d0cf31UL,
|
||||
0x2cd99e8bUL, 0x5bdeae1dUL, 0x9b64c2b0UL, 0xec63f226UL, 0x756aa39cUL,
|
||||
0x026d930aUL, 0x9c0906a9UL, 0xeb0e363fUL, 0x72076785UL, 0x05005713UL,
|
||||
0x95bf4a82UL, 0xe2b87a14UL, 0x7bb12baeUL, 0x0cb61b38UL, 0x92d28e9bUL,
|
||||
0xe5d5be0dUL, 0x7cdcefb7UL, 0x0bdbdf21UL, 0x86d3d2d4UL, 0xf1d4e242UL,
|
||||
0x68ddb3f8UL, 0x1fda836eUL, 0x81be16cdUL, 0xf6b9265bUL, 0x6fb077e1UL,
|
||||
0x18b74777UL, 0x88085ae6UL, 0xff0f6a70UL, 0x66063bcaUL, 0x11010b5cUL,
|
||||
0x8f659effUL, 0xf862ae69UL, 0x616bffd3UL, 0x166ccf45UL, 0xa00ae278UL,
|
||||
0xd70dd2eeUL, 0x4e048354UL, 0x3903b3c2UL, 0xa7672661UL, 0xd06016f7UL,
|
||||
0x4969474dUL, 0x3e6e77dbUL, 0xaed16a4aUL, 0xd9d65adcUL, 0x40df0b66UL,
|
||||
0x37d83bf0UL, 0xa9bcae53UL, 0xdebb9ec5UL, 0x47b2cf7fUL, 0x30b5ffe9UL,
|
||||
0xbdbdf21cUL, 0xcabac28aUL, 0x53b39330UL, 0x24b4a3a6UL, 0xbad03605UL,
|
||||
0xcdd70693UL, 0x54de5729UL, 0x23d967bfUL, 0xb3667a2eUL, 0xc4614ab8UL,
|
||||
0x5d681b02UL, 0x2a6f2b94UL, 0xb40bbe37UL, 0xc30c8ea1UL, 0x5a05df1bUL,
|
||||
0x2d02ef8dUL
|
||||
};
|
||||
|
||||
uint32_t ssh_crc32(const char *buf, uint32_t len) {
|
||||
uint32_t ret = 0;
|
||||
while(len > 0) {
|
||||
ret = crc_table[(ret ^ *buf) & 0xff] ^ (ret >> 8);
|
||||
--len;
|
||||
++buf;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
@@ -41,13 +41,13 @@
|
||||
# define BLOWFISH "blowfish-cbc,"
|
||||
# define AES "aes256-ctr,aes192-ctr,aes128-ctr,aes256-cbc,aes192-cbc,aes128-cbc,"
|
||||
# define DES "3des-cbc"
|
||||
# define DES_SUPPORTED "3des-cbc,des-cbc-ssh1"
|
||||
# define DES_SUPPORTED "3des-cbc"
|
||||
|
||||
#elif defined HAVE_LIBMBEDCRYPTO
|
||||
# define BLOWFISH "blowfish-cbc,"
|
||||
# define AES "aes256-ctr,aes192-ctr,aes128-ctr,aes256-cbc,aes192-cbc,aes128-cbc,"
|
||||
# define DES "3des-cbc"
|
||||
# define DES_SUPPORTED "3des-cbc,des-cbc-ssh1"
|
||||
# define DES_SUPPORTED "3des-cbc"
|
||||
|
||||
#elif defined(HAVE_LIBCRYPTO)
|
||||
|
||||
@@ -68,7 +68,7 @@
|
||||
# endif /* HAVE_OPENSSL_AES_H */
|
||||
|
||||
# define DES "3des-cbc"
|
||||
# define DES_SUPPORTED "3des-cbc,des-cbc-ssh1"
|
||||
# define DES_SUPPORTED "3des-cbc"
|
||||
#endif /* HAVE_LIBCRYPTO */
|
||||
|
||||
#ifdef WITH_ZLIB
|
||||
@@ -575,7 +575,6 @@ static char *ssh_client_select_hostkeys(ssh_session session){
|
||||
#ifdef HAVE_DSA
|
||||
"ssh-dss",
|
||||
#endif
|
||||
"ssh-rsa1",
|
||||
NULL
|
||||
};
|
||||
char **methods;
|
||||
|
506
src/kex1.c
506
src/kex1.c
@@ -1,506 +0,0 @@
|
||||
/*
|
||||
* kex.c - key exchange
|
||||
*
|
||||
* This file is part of the SSH Library
|
||||
*
|
||||
* Copyright (c) 2003-2008 by Aris Adamantiadis
|
||||
*
|
||||
* The SSH Library is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as published by
|
||||
* the Free Software Foundation; either version 2.1 of the License, or (at your
|
||||
* option) any later version.
|
||||
*
|
||||
* The SSH Library is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
|
||||
* License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with the SSH Library; see the file COPYING. If not, write to
|
||||
* the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
|
||||
* MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#ifndef _WIN32
|
||||
#include <arpa/inet.h>
|
||||
#endif
|
||||
|
||||
#include "libssh/priv.h"
|
||||
#include "libssh/buffer.h"
|
||||
#include "libssh/crypto.h"
|
||||
#include "libssh/kex.h"
|
||||
#include "libssh/keys.h"
|
||||
#include "libssh/session.h"
|
||||
#include "libssh/ssh1.h"
|
||||
#include "libssh/wrapper.h"
|
||||
#include "libssh/dh.h"
|
||||
|
||||
#if defined(HAVE_LIBCRYPTO)
|
||||
#include "libcrypto-compat.h"
|
||||
#endif
|
||||
|
||||
/* SSHv1 functions */
|
||||
|
||||
/* makes a STRING contating 3 strings : ssh-rsa1,e and n */
|
||||
/* this is a public key in openssh's format */
|
||||
static ssh_string make_rsa1_string(ssh_string e, ssh_string n){
|
||||
ssh_buffer buffer = NULL;
|
||||
ssh_string rsa = NULL;
|
||||
ssh_string ret = NULL;
|
||||
|
||||
buffer = ssh_buffer_new();
|
||||
if (buffer == NULL) {
|
||||
goto error;
|
||||
}
|
||||
|
||||
rsa = ssh_string_from_char("ssh-rsa1");
|
||||
if (rsa == NULL) {
|
||||
goto error;
|
||||
}
|
||||
|
||||
if (ssh_buffer_add_ssh_string(buffer, rsa) < 0) {
|
||||
goto error;
|
||||
}
|
||||
if (ssh_buffer_add_ssh_string(buffer, e) < 0) {
|
||||
goto error;
|
||||
}
|
||||
if (ssh_buffer_add_ssh_string(buffer, n) < 0) {
|
||||
goto error;
|
||||
}
|
||||
|
||||
ret = ssh_string_new(ssh_buffer_get_len(buffer));
|
||||
if (ret == NULL) {
|
||||
goto error;
|
||||
}
|
||||
|
||||
ssh_string_fill(ret, ssh_buffer_get(buffer), ssh_buffer_get_len(buffer));
|
||||
error:
|
||||
ssh_buffer_free(buffer);
|
||||
ssh_string_free(rsa);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int build_session_id1(ssh_session session, ssh_string servern,
|
||||
ssh_string hostn) {
|
||||
MD5CTX md5 = NULL;
|
||||
|
||||
md5 = md5_init();
|
||||
if (md5 == NULL) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
#ifdef DEBUG_CRYPTO
|
||||
ssh_print_hexa("host modulus",ssh_string_data(hostn),ssh_string_len(hostn));
|
||||
ssh_print_hexa("server modulus",ssh_string_data(servern),ssh_string_len(servern));
|
||||
#endif
|
||||
md5_update(md5,ssh_string_data(hostn),ssh_string_len(hostn));
|
||||
md5_update(md5,ssh_string_data(servern),ssh_string_len(servern));
|
||||
md5_update(md5,session->next_crypto->server_kex.cookie,8);
|
||||
if(session->next_crypto->session_id != NULL)
|
||||
SAFE_FREE(session->next_crypto->session_id);
|
||||
session->next_crypto->session_id = malloc(MD5_DIGEST_LEN);
|
||||
if(session->next_crypto->session_id == NULL){
|
||||
ssh_set_error_oom(session);
|
||||
return SSH_ERROR;
|
||||
}
|
||||
md5_final(session->next_crypto->session_id,md5);
|
||||
#ifdef DEBUG_CRYPTO
|
||||
ssh_print_hexa("session_id",session->next_crypto->session_id,MD5_DIGEST_LEN);
|
||||
#endif
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* returns 1 if the modulus of k1 is < than the one of k2 */
|
||||
static int modulus_smaller(ssh_public_key k1, ssh_public_key k2){
|
||||
bignum n1;
|
||||
bignum n2;
|
||||
int res;
|
||||
#ifdef HAVE_LIBGCRYPT
|
||||
gcry_sexp_t sexp;
|
||||
sexp=gcry_sexp_find_token(k1->rsa_pub,"n",0);
|
||||
n1=gcry_sexp_nth_mpi(sexp,1,GCRYMPI_FMT_USG);
|
||||
gcry_sexp_release(sexp);
|
||||
sexp=gcry_sexp_find_token(k2->rsa_pub,"n",0);
|
||||
n2=gcry_sexp_nth_mpi(sexp,1,GCRYMPI_FMT_USG);
|
||||
gcry_sexp_release(sexp);
|
||||
#elif defined HAVE_LIBCRYPTO
|
||||
RSA_get0_key(k1->rsa_pub, (const BIGNUM **)&n1, NULL, NULL);
|
||||
RSA_get0_key(k2->rsa_pub, (const BIGNUM **)&n2, NULL, NULL);
|
||||
#endif
|
||||
if(bignum_cmp(n1,n2)<0)
|
||||
res=1;
|
||||
else
|
||||
res=0;
|
||||
#ifdef HAVE_LIBGCRYPT
|
||||
bignum_free(n1);
|
||||
bignum_free(n2);
|
||||
#endif
|
||||
return res;
|
||||
|
||||
}
|
||||
|
||||
static ssh_string ssh_encrypt_rsa1(ssh_session session,
|
||||
ssh_string data,
|
||||
ssh_public_key key) {
|
||||
ssh_string str = NULL;
|
||||
size_t len = ssh_string_len(data);
|
||||
size_t size = 0;
|
||||
#ifdef HAVE_LIBGCRYPT
|
||||
const char *tmp = NULL;
|
||||
gcry_sexp_t ret_sexp;
|
||||
gcry_sexp_t data_sexp;
|
||||
|
||||
if (gcry_sexp_build(&data_sexp, NULL, "(data(flags pkcs1)(value %b))",
|
||||
len, ssh_string_data(data))) {
|
||||
ssh_set_error(session, SSH_FATAL, "RSA1 encrypt: libgcrypt error");
|
||||
return NULL;
|
||||
}
|
||||
if (gcry_pk_encrypt(&ret_sexp, data_sexp, key->rsa_pub)) {
|
||||
gcry_sexp_release(data_sexp);
|
||||
ssh_set_error(session, SSH_FATAL, "RSA1 encrypt: libgcrypt error");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
gcry_sexp_release(data_sexp);
|
||||
|
||||
data_sexp = gcry_sexp_find_token(ret_sexp, "a", 0);
|
||||
if (data_sexp == NULL) {
|
||||
ssh_set_error(session, SSH_FATAL, "RSA1 encrypt: libgcrypt error");
|
||||
gcry_sexp_release(ret_sexp);
|
||||
return NULL;
|
||||
}
|
||||
tmp = gcry_sexp_nth_data(data_sexp, 1, &size);
|
||||
if (*tmp == 0) {
|
||||
size--;
|
||||
tmp++;
|
||||
}
|
||||
|
||||
str = ssh_string_new(size);
|
||||
if (str == NULL) {
|
||||
ssh_set_error(session, SSH_FATAL, "Not enough space");
|
||||
gcry_sexp_release(data_sexp);
|
||||
gcry_sexp_release(ret_sexp);
|
||||
return NULL;
|
||||
}
|
||||
ssh_string_fill(str, tmp, size);
|
||||
|
||||
gcry_sexp_release(data_sexp);
|
||||
gcry_sexp_release(ret_sexp);
|
||||
#elif defined HAVE_LIBCRYPTO
|
||||
size = RSA_size(key->rsa_pub);
|
||||
|
||||
str = ssh_string_new(size);
|
||||
if (str == NULL) {
|
||||
ssh_set_error(session, SSH_FATAL, "Not enough space");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (RSA_public_encrypt(len, ssh_string_data(data), ssh_string_data(str), key->rsa_pub,
|
||||
RSA_PKCS1_PADDING) < 0) {
|
||||
ssh_string_free(str);
|
||||
return NULL;
|
||||
}
|
||||
#endif
|
||||
|
||||
return str;
|
||||
}
|
||||
|
||||
#define ABS(A) ( (A)<0 ? -(A):(A) )
|
||||
static ssh_string encrypt_session_key(ssh_session session, ssh_public_key srvkey,
|
||||
ssh_public_key hostkey, int slen, int hlen) {
|
||||
unsigned char buffer[32] = {0};
|
||||
int i;
|
||||
ssh_string data1 = NULL;
|
||||
ssh_string data2 = NULL;
|
||||
if(session->next_crypto->encryptkey != NULL)
|
||||
SAFE_FREE(session->next_crypto->encryptkey);
|
||||
if(session->next_crypto->decryptkey != NULL)
|
||||
SAFE_FREE(session->next_crypto->decryptkey);
|
||||
if(session->next_crypto->encryptIV != NULL)
|
||||
SAFE_FREE(session->next_crypto->encryptIV);
|
||||
if(session->next_crypto->decryptIV != NULL)
|
||||
SAFE_FREE(session->next_crypto->decryptIV);
|
||||
session->next_crypto->encryptkey = malloc(32);
|
||||
session->next_crypto->decryptkey = malloc(32);
|
||||
session->next_crypto->encryptIV = malloc(32);
|
||||
session->next_crypto->decryptIV = malloc(32);
|
||||
if(session->next_crypto->encryptkey == NULL ||
|
||||
session->next_crypto->decryptkey == NULL ||
|
||||
session->next_crypto->encryptIV == NULL ||
|
||||
session->next_crypto->decryptIV == NULL){
|
||||
ssh_set_error_oom(session);
|
||||
return NULL;
|
||||
}
|
||||
/* first, generate a session key */
|
||||
ssh_get_random(session->next_crypto->encryptkey, 32, 1);
|
||||
memcpy(buffer, session->next_crypto->encryptkey, 32);
|
||||
memcpy(session->next_crypto->decryptkey, session->next_crypto->encryptkey, 32);
|
||||
memset(session->next_crypto->encryptIV, 0, 32);
|
||||
memset(session->next_crypto->decryptIV, 0, 32);
|
||||
|
||||
#ifdef DEBUG_CRYPTO
|
||||
ssh_print_hexa("session key",buffer,32);
|
||||
#endif
|
||||
|
||||
/* xor session key with session_id */
|
||||
for (i = 0; i < 16; i++) {
|
||||
buffer[i] ^= session->next_crypto->session_id[i];
|
||||
}
|
||||
data1 = ssh_string_new(32);
|
||||
if (data1 == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
ssh_string_fill(data1, buffer, 32);
|
||||
if (ABS(hlen - slen) < 128){
|
||||
SSH_LOG(SSH_LOG_FUNCTIONS,
|
||||
"Difference between server modulus and host modulus is only %d. "
|
||||
"It's illegal and may not work",
|
||||
ABS(hlen - slen));
|
||||
}
|
||||
|
||||
if (modulus_smaller(srvkey, hostkey)) {
|
||||
data2 = ssh_encrypt_rsa1(session, data1, srvkey);
|
||||
ssh_string_free(data1);
|
||||
data1 = NULL;
|
||||
if (data2 == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
data1 = ssh_encrypt_rsa1(session, data2, hostkey);
|
||||
ssh_string_free(data2);
|
||||
if (data1 == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
} else {
|
||||
data2 = ssh_encrypt_rsa1(session, data1, hostkey);
|
||||
ssh_string_free(data1);
|
||||
data1 = NULL;
|
||||
if (data2 == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
data1 = ssh_encrypt_rsa1(session, data2, srvkey);
|
||||
ssh_string_free(data2);
|
||||
if (data1 == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
return data1;
|
||||
}
|
||||
|
||||
/* 2 SSH_SMSG_PUBLIC_KEY
|
||||
*
|
||||
* 8 bytes anti_spoofing_cookie
|
||||
* 32-bit int server_key_bits
|
||||
* mp-int server_key_public_exponent
|
||||
* mp-int server_key_public_modulus
|
||||
* 32-bit int host_key_bits
|
||||
* mp-int host_key_public_exponent
|
||||
* mp-int host_key_public_modulus
|
||||
* 32-bit int protocol_flags
|
||||
* 32-bit int supported_ciphers_mask
|
||||
* 32-bit int supported_authentications_mask
|
||||
*/
|
||||
/**
|
||||
* @brief Wait for a SSH_SMSG_PUBLIC_KEY and does the key exchange
|
||||
*/
|
||||
SSH_PACKET_CALLBACK(ssh_packet_publickey1){
|
||||
ssh_string server_exp = NULL;
|
||||
ssh_string server_mod = NULL;
|
||||
ssh_string host_exp = NULL;
|
||||
ssh_string host_mod = NULL;
|
||||
ssh_string serverkey = NULL;
|
||||
ssh_string hostkey = NULL;
|
||||
ssh_public_key srv = NULL;
|
||||
ssh_public_key host = NULL;
|
||||
uint32_t server_bits;
|
||||
uint32_t host_bits;
|
||||
uint32_t protocol_flags;
|
||||
uint32_t supported_ciphers_mask;
|
||||
uint32_t supported_authentications_mask;
|
||||
ssh_string enc_session = NULL;
|
||||
uint16_t bits;
|
||||
int ko;
|
||||
uint32_t support_3DES = 0;
|
||||
uint32_t support_DES = 0;
|
||||
int rc;
|
||||
|
||||
(void)type;
|
||||
(void)user;
|
||||
SSH_LOG(SSH_LOG_PROTOCOL, "Got a SSH_SMSG_PUBLIC_KEY");
|
||||
if(session->session_state != SSH_SESSION_STATE_INITIAL_KEX){
|
||||
ssh_set_error(session,SSH_FATAL,"SSH_KEXINIT received in wrong state");
|
||||
goto error;
|
||||
}
|
||||
if (ssh_buffer_get_data(packet, session->next_crypto->server_kex.cookie, 8) != 8) {
|
||||
ssh_set_error(session, SSH_FATAL, "Can't get cookie in buffer");
|
||||
goto error;
|
||||
}
|
||||
|
||||
ssh_buffer_get_u32(packet, &server_bits);
|
||||
server_exp = ssh_buffer_get_mpint(packet);
|
||||
if (server_exp == NULL) {
|
||||
goto error;
|
||||
}
|
||||
server_mod = ssh_buffer_get_mpint(packet);
|
||||
if (server_mod == NULL) {
|
||||
goto error;
|
||||
}
|
||||
ssh_buffer_get_u32(packet, &host_bits);
|
||||
host_exp = ssh_buffer_get_mpint(packet);
|
||||
if (host_exp == NULL) {
|
||||
goto error;
|
||||
}
|
||||
host_mod = ssh_buffer_get_mpint(packet);
|
||||
if (host_mod == NULL) {
|
||||
goto error;
|
||||
}
|
||||
ssh_buffer_get_u32(packet, &protocol_flags);
|
||||
ssh_buffer_get_u32(packet, &supported_ciphers_mask);
|
||||
ko = ssh_buffer_get_u32(packet, &supported_authentications_mask);
|
||||
|
||||
if ((ko != sizeof(uint32_t)) || !host_mod || !host_exp
|
||||
|| !server_mod || !server_exp) {
|
||||
SSH_LOG(SSH_LOG_RARE, "Invalid SSH_SMSG_PUBLIC_KEY packet");
|
||||
ssh_set_error(session, SSH_FATAL, "Invalid SSH_SMSG_PUBLIC_KEY packet");
|
||||
goto error;
|
||||
}
|
||||
|
||||
server_bits = ntohl(server_bits);
|
||||
host_bits = ntohl(host_bits);
|
||||
protocol_flags = ntohl(protocol_flags);
|
||||
supported_ciphers_mask = ntohl(supported_ciphers_mask);
|
||||
supported_authentications_mask = ntohl(supported_authentications_mask);
|
||||
SSH_LOG(SSH_LOG_PROTOCOL,
|
||||
"Server bits: %d; Host bits: %d; Protocol flags: %.8lx; "
|
||||
"Cipher mask: %.8lx; Auth mask: %.8lx",
|
||||
server_bits,
|
||||
host_bits,
|
||||
(unsigned long int) protocol_flags,
|
||||
(unsigned long int) supported_ciphers_mask,
|
||||
(unsigned long int) supported_authentications_mask);
|
||||
|
||||
serverkey = make_rsa1_string(server_exp, server_mod);
|
||||
if (serverkey == NULL) {
|
||||
goto error;
|
||||
}
|
||||
hostkey = make_rsa1_string(host_exp,host_mod);
|
||||
if (hostkey == NULL) {
|
||||
goto error;
|
||||
}
|
||||
if (build_session_id1(session, server_mod, host_mod) < 0) {
|
||||
goto error;
|
||||
}
|
||||
|
||||
srv = publickey_from_string(session, serverkey);
|
||||
if (srv == NULL) {
|
||||
goto error;
|
||||
}
|
||||
host = publickey_from_string(session, hostkey);
|
||||
if (host == NULL) {
|
||||
goto error;
|
||||
}
|
||||
|
||||
rc = ssh_dh_import_next_pubkey_blob(session, hostkey);
|
||||
if (rc != SSH_OK) {
|
||||
goto error;
|
||||
}
|
||||
|
||||
/* now, we must choose an encryption algo */
|
||||
/* hardcode 3des */
|
||||
//
|
||||
support_3DES = (supported_ciphers_mask & (1<<SSH_CIPHER_3DES));
|
||||
support_DES = (supported_ciphers_mask & (1<<SSH_CIPHER_DES));
|
||||
if(!support_3DES && !support_DES){
|
||||
ssh_set_error(session, SSH_FATAL, "Remote server doesn't accept 3DES");
|
||||
goto error;
|
||||
}
|
||||
SSH_LOG(SSH_LOG_PROTOCOL, "Sending SSH_CMSG_SESSION_KEY");
|
||||
|
||||
if (ssh_buffer_add_u8(session->out_buffer, SSH_CMSG_SESSION_KEY) < 0) {
|
||||
goto error;
|
||||
}
|
||||
if (ssh_buffer_add_u8(session->out_buffer, support_3DES ? SSH_CIPHER_3DES : SSH_CIPHER_DES) < 0) {
|
||||
goto error;
|
||||
}
|
||||
if (ssh_buffer_add_data(session->out_buffer, session->next_crypto->server_kex.cookie, 8) < 0) {
|
||||
goto error;
|
||||
}
|
||||
|
||||
enc_session = encrypt_session_key(session, srv, host, server_bits, host_bits);
|
||||
if (enc_session == NULL) {
|
||||
goto error;
|
||||
}
|
||||
|
||||
bits = ssh_string_len(enc_session) * 8 - 7;
|
||||
SSH_LOG(SSH_LOG_PROTOCOL, "%d bits, %" PRIdS " bytes encrypted session",
|
||||
bits, ssh_string_len(enc_session));
|
||||
bits = htons(bits);
|
||||
/* the encrypted mpint */
|
||||
if (ssh_buffer_add_data(session->out_buffer, &bits, sizeof(uint16_t)) < 0) {
|
||||
goto error;
|
||||
}
|
||||
if (ssh_buffer_add_data(session->out_buffer, ssh_string_data(enc_session),
|
||||
ssh_string_len(enc_session)) < 0) {
|
||||
goto error;
|
||||
}
|
||||
/* the protocol flags */
|
||||
if (ssh_buffer_add_u32(session->out_buffer, 0) < 0) {
|
||||
goto error;
|
||||
}
|
||||
session->session_state=SSH_SESSION_STATE_KEXINIT_RECEIVED;
|
||||
if (ssh_packet_send(session) == SSH_ERROR) {
|
||||
goto error;
|
||||
}
|
||||
|
||||
/* we can set encryption */
|
||||
if(crypt_set_algorithms(session, support_3DES ? SSH_3DES : SSH_DES)){
|
||||
goto error;
|
||||
}
|
||||
|
||||
session->current_crypto = session->next_crypto;
|
||||
session->next_crypto = NULL;
|
||||
goto end;
|
||||
error:
|
||||
session->session_state=SSH_SESSION_STATE_ERROR;
|
||||
end:
|
||||
|
||||
ssh_string_free(host_mod);
|
||||
ssh_string_free(host_exp);
|
||||
ssh_string_free(server_mod);
|
||||
ssh_string_free(server_exp);
|
||||
ssh_string_free(serverkey);
|
||||
ssh_string_free(hostkey);
|
||||
ssh_string_free(enc_session);
|
||||
|
||||
publickey_free(srv);
|
||||
publickey_free(host);
|
||||
|
||||
return SSH_PACKET_USED;
|
||||
}
|
||||
|
||||
int ssh_get_kex1(ssh_session session) {
|
||||
SSH_LOG(SSH_LOG_PROTOCOL, "Waiting for a SSH_SMSG_PUBLIC_KEY");
|
||||
|
||||
/* Here the callback is called */
|
||||
while(session->session_state==SSH_SESSION_STATE_INITIAL_KEX){
|
||||
ssh_handle_packets(session, SSH_TIMEOUT_USER);
|
||||
}
|
||||
if (session->session_state==SSH_SESSION_STATE_ERROR) {
|
||||
return SSH_ERROR;
|
||||
}
|
||||
SSH_LOG(SSH_LOG_PROTOCOL, "Waiting for a SSH_SMSG_SUCCESS");
|
||||
/* Waiting for SSH_SMSG_SUCCESS */
|
||||
while(session->session_state==SSH_SESSION_STATE_KEXINIT_RECEIVED){
|
||||
ssh_handle_packets(session, SSH_TIMEOUT_USER);
|
||||
}
|
||||
if(session->session_state==SSH_SESSION_STATE_ERROR) {
|
||||
return SSH_ERROR;
|
||||
}
|
||||
SSH_LOG(SSH_LOG_PROTOCOL, "received SSH_SMSG_SUCCESS");
|
||||
|
||||
return SSH_OK;
|
||||
}
|
@@ -59,18 +59,6 @@
|
||||
* @{
|
||||
*/
|
||||
|
||||
static int alldigits(const char *s) {
|
||||
while (*s) {
|
||||
if (isdigit(*s)) {
|
||||
s++;
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* @internal
|
||||
*
|
||||
@@ -103,7 +91,7 @@ static void tokens_free(char **tokens) {
|
||||
* @param[out] found_type A pointer to a string to be set with the found key
|
||||
* type.
|
||||
*
|
||||
* @returns The found_type type of key (ie "dsa","ssh-rsa1"). Don't
|
||||
* @returns The found_type type of key (ie "dsa","ssh-rsa"). Don't
|
||||
* free that value. NULL if no match was found or the file
|
||||
* was not found.
|
||||
*/
|
||||
@@ -151,20 +139,14 @@ static char **ssh_get_knownhost_line(FILE **file, const char *filename,
|
||||
|
||||
*found_type = tokens[1];
|
||||
if (tokens[3]) {
|
||||
/* openssh rsa1 format has 4 tokens on the line. Recognize it
|
||||
by the fact that everything is all digits */
|
||||
if (tokens[4]) {
|
||||
/* that's never valid */
|
||||
tokens_free(tokens);
|
||||
continue;
|
||||
}
|
||||
if (alldigits(tokens[1]) && alldigits(tokens[2]) && alldigits(tokens[3])) {
|
||||
*found_type = "ssh-rsa1";
|
||||
} else {
|
||||
/* 3 tokens only, not four */
|
||||
tokens_free(tokens);
|
||||
continue;
|
||||
}
|
||||
/* 3 tokens only, not four */
|
||||
tokens_free(tokens);
|
||||
continue;
|
||||
}
|
||||
|
||||
return tokens;
|
||||
@@ -194,77 +176,9 @@ static int check_public_key(ssh_session session, char **tokens) {
|
||||
char *pubkey_64;
|
||||
int rc;
|
||||
|
||||
/* ok we found some public key in known hosts file. now un-base64it */
|
||||
if (alldigits(tokens[1])) {
|
||||
/* openssh rsa1 format */
|
||||
bignum tmpbn;
|
||||
ssh_string tmpstring;
|
||||
unsigned int len;
|
||||
int i;
|
||||
|
||||
pubkey_buffer = ssh_buffer_new();
|
||||
if (pubkey_buffer == NULL) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
tmpstring = ssh_string_from_char("ssh-rsa1");
|
||||
if (tmpstring == NULL) {
|
||||
ssh_buffer_free(pubkey_buffer);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (ssh_buffer_add_ssh_string(pubkey_buffer, tmpstring) < 0) {
|
||||
ssh_buffer_free(pubkey_buffer);
|
||||
ssh_string_free(tmpstring);
|
||||
return -1;
|
||||
}
|
||||
ssh_string_free(tmpstring);
|
||||
|
||||
for (i = 2; i < 4; i++) { /* e, then n */
|
||||
tmpbn = NULL;
|
||||
#ifdef HAVE_LIBMBEDCRYPTO
|
||||
bignum_dec2bn(tokens[i], tmpbn);
|
||||
#else
|
||||
bignum_dec2bn(tokens[i], &tmpbn);
|
||||
#endif
|
||||
if (tmpbn == NULL) {
|
||||
ssh_buffer_free(pubkey_buffer);
|
||||
return -1;
|
||||
}
|
||||
/* for some reason, ssh_make_bignum_string does not work
|
||||
because of the padding which it does --kv */
|
||||
/* tmpstring = ssh_make_bignum_string(tmpbn); */
|
||||
/* do it manually instead */
|
||||
len = bignum_num_bytes(tmpbn);
|
||||
tmpstring = malloc(4 + len);
|
||||
if (tmpstring == NULL) {
|
||||
ssh_buffer_free(pubkey_buffer);
|
||||
bignum_free(tmpbn);
|
||||
return -1;
|
||||
}
|
||||
/* TODO: fix the hardcoding */
|
||||
tmpstring->size = htonl(len);
|
||||
#ifdef HAVE_LIBGCRYPT
|
||||
bignum_bn2bin(tmpbn, len, ssh_string_data(tmpstring));
|
||||
#elif defined HAVE_LIBCRYPTO
|
||||
bignum_bn2bin(tmpbn, ssh_string_data(tmpstring));
|
||||
#elif defined HAVE_LIBMBEDCRYPTO
|
||||
bignum_bn2bin(tmpbn, ssh_string_data(tmpstring));
|
||||
#endif
|
||||
bignum_free(tmpbn);
|
||||
if (ssh_buffer_add_ssh_string(pubkey_buffer, tmpstring) < 0) {
|
||||
ssh_buffer_free(pubkey_buffer);
|
||||
ssh_string_free(tmpstring);
|
||||
bignum_free(tmpbn);
|
||||
return -1;
|
||||
}
|
||||
ssh_string_free(tmpstring);
|
||||
}
|
||||
} else {
|
||||
/* ssh-dss or ssh-rsa */
|
||||
pubkey_64 = tokens[2];
|
||||
pubkey_buffer = base64_to_bin(pubkey_64);
|
||||
}
|
||||
|
||||
if (pubkey_buffer == NULL) {
|
||||
ssh_set_error(session, SSH_FATAL,
|
||||
@@ -588,33 +502,22 @@ char * ssh_dump_knownhost(ssh_session session) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (ssh_key_type(server_pubkey) == SSH_KEYTYPE_RSA1) {
|
||||
/* openssh uses a different format for ssh-rsa1 keys.
|
||||
Be compatible --kv */
|
||||
rc = ssh_pki_export_pubkey_rsa1(server_pubkey, host, buffer, len);
|
||||
rc = ssh_pki_export_pubkey_base64(server_pubkey, &b64_key);
|
||||
if (rc < 0) {
|
||||
SAFE_FREE(buffer);
|
||||
SAFE_FREE(host);
|
||||
if (rc < 0) {
|
||||
SAFE_FREE(buffer);
|
||||
return NULL;
|
||||
}
|
||||
} else {
|
||||
rc = ssh_pki_export_pubkey_base64(server_pubkey, &b64_key);
|
||||
if (rc < 0) {
|
||||
SAFE_FREE(buffer);
|
||||
SAFE_FREE(host);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
snprintf(buffer, len,
|
||||
"%s %s %s\n",
|
||||
host,
|
||||
server_pubkey->type_c,
|
||||
b64_key);
|
||||
|
||||
SAFE_FREE(host);
|
||||
SAFE_FREE(b64_key);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
snprintf(buffer, len,
|
||||
"%s %s %s\n",
|
||||
host,
|
||||
server_pubkey->type_c,
|
||||
b64_key);
|
||||
|
||||
SAFE_FREE(host);
|
||||
SAFE_FREE(b64_key);
|
||||
|
||||
return buffer;
|
||||
}
|
||||
|
||||
|
@@ -504,6 +504,7 @@ int ssh_session_export_known_hosts_entry(ssh_session session,
|
||||
ssh_key server_pubkey = NULL;
|
||||
char *host = NULL;
|
||||
char entry_buf[4096] = {0};
|
||||
char *b64_key = NULL;
|
||||
int rc;
|
||||
|
||||
if (pentry_string == NULL) {
|
||||
@@ -536,34 +537,21 @@ int ssh_session_export_known_hosts_entry(ssh_session session,
|
||||
return SSH_ERROR;
|
||||
}
|
||||
|
||||
if (ssh_key_type(server_pubkey) == SSH_KEYTYPE_RSA1) {
|
||||
rc = ssh_pki_export_pubkey_rsa1(server_pubkey,
|
||||
host,
|
||||
entry_buf,
|
||||
sizeof(entry_buf));
|
||||
rc = ssh_pki_export_pubkey_base64(server_pubkey, &b64_key);
|
||||
if (rc < 0) {
|
||||
SAFE_FREE(host);
|
||||
if (rc < 0) {
|
||||
return SSH_ERROR;
|
||||
}
|
||||
} else {
|
||||
char *b64_key = NULL;
|
||||
|
||||
rc = ssh_pki_export_pubkey_base64(server_pubkey, &b64_key);
|
||||
if (rc < 0) {
|
||||
SAFE_FREE(host);
|
||||
return SSH_ERROR;
|
||||
}
|
||||
|
||||
snprintf(entry_buf, sizeof(entry_buf),
|
||||
"%s %s %s\n",
|
||||
host,
|
||||
server_pubkey->type_c,
|
||||
b64_key);
|
||||
|
||||
SAFE_FREE(host);
|
||||
SAFE_FREE(b64_key);
|
||||
return SSH_ERROR;
|
||||
}
|
||||
|
||||
snprintf(entry_buf, sizeof(entry_buf),
|
||||
"%s %s %s\n",
|
||||
host,
|
||||
server_pubkey->type_c,
|
||||
b64_key);
|
||||
|
||||
SAFE_FREE(host);
|
||||
SAFE_FREE(b64_key);
|
||||
|
||||
*pentry_string = strdup(entry_buf);
|
||||
if (*pentry_string == NULL) {
|
||||
return SSH_ERROR;
|
||||
|
@@ -358,7 +358,6 @@ void publickey_free(ssh_public_key key) {
|
||||
#endif
|
||||
break;
|
||||
case SSH_KEYTYPE_RSA:
|
||||
case SSH_KEYTYPE_RSA1:
|
||||
#ifdef HAVE_LIBGCRYPT
|
||||
gcry_sexp_release(key->rsa_pub);
|
||||
#elif defined HAVE_LIBCRYPTO
|
||||
|
115
src/libcrypto.c
115
src/libcrypto.c
@@ -471,10 +471,6 @@ static void evp_cipher_init(struct ssh_cipher_struct *cipher) {
|
||||
cipher->cipher = EVP_bf_cbc();
|
||||
break;
|
||||
/* ciphers not using EVP */
|
||||
case SSH_3DES_CBC_SSH1:
|
||||
case SSH_DES_CBC_SSH1:
|
||||
SSH_LOG(SSH_LOG_WARNING, "This cipher should not use evp_cipher_init");
|
||||
break;
|
||||
case SSH_NO_CIPHER:
|
||||
SSH_LOG(SSH_LOG_WARNING, "No valid ciphertype found");
|
||||
break;
|
||||
@@ -612,95 +608,6 @@ static void aes_ctr_cleanup(struct ssh_cipher_struct *cipher){
|
||||
}
|
||||
|
||||
#endif /* HAVE_OPENSSL_EVP_AES_CTR */
|
||||
#ifdef HAS_DES
|
||||
|
||||
typedef uint8_t des_iv_t[8];
|
||||
|
||||
struct ssh_3des_key_schedule {
|
||||
DES_key_schedule keys[3];
|
||||
union {
|
||||
des_iv_t v[3];
|
||||
uint8_t *c;
|
||||
} ivs;
|
||||
};
|
||||
|
||||
/* 3des cbc for SSH-1 has no suitable EVP construct and requires
|
||||
* a custom key setup
|
||||
*/
|
||||
static int des3_set_key(struct ssh_cipher_struct *cipher, void *key, void *IV){
|
||||
DES_cblock *keys = key;
|
||||
|
||||
DES_set_odd_parity(&keys[0]);
|
||||
DES_set_odd_parity(&keys[1]);
|
||||
DES_set_odd_parity(&keys[2]);
|
||||
|
||||
cipher->des3_key = malloc(sizeof (struct ssh_3des_key_schedule));
|
||||
if (cipher->des3_key == NULL){
|
||||
return SSH_ERROR;
|
||||
}
|
||||
DES_set_key_unchecked(&keys[0], &cipher->des3_key->keys[0]);
|
||||
DES_set_key_unchecked(&keys[1], &cipher->des3_key->keys[1]);
|
||||
DES_set_key_unchecked(&keys[2], &cipher->des3_key->keys[2]);
|
||||
memcpy(cipher->des3_key->ivs.v, IV, 24);
|
||||
return SSH_OK;
|
||||
}
|
||||
|
||||
static void des3_1_encrypt(struct ssh_cipher_struct *cipher, void *in,
|
||||
void *out, unsigned long len) {
|
||||
#ifdef DEBUG_CRYPTO
|
||||
ssh_print_hexa("Encrypt IV before", cipher->des3_key->ivs.c, 24);
|
||||
#endif
|
||||
DES_ncbc_encrypt(in, out, len, &cipher->des3_key->keys[0], &cipher->des3_key->ivs.v[0], 1);
|
||||
DES_ncbc_encrypt(out, in, len, &cipher->des3_key->keys[1], &cipher->des3_key->ivs.v[1], 0);
|
||||
DES_ncbc_encrypt(in, out, len, &cipher->des3_key->keys[2], &cipher->des3_key->ivs.v[2], 1);
|
||||
#ifdef DEBUG_CRYPTO
|
||||
ssh_print_hexa("Encrypt IV after", cipher->des3_key->ivs.c, 24);
|
||||
#endif
|
||||
}
|
||||
|
||||
static void des3_1_decrypt(struct ssh_cipher_struct *cipher, void *in,
|
||||
void *out, unsigned long len) {
|
||||
#ifdef DEBUG_CRYPTO
|
||||
ssh_print_hexa("Decrypt IV before", cipher->des3_key->ivs.c, 24);
|
||||
#endif
|
||||
|
||||
DES_ncbc_encrypt(in, out, len, &cipher->des3_key->keys[2], &cipher->des3_key->ivs.v[0], 0);
|
||||
DES_ncbc_encrypt(out, in, len, &cipher->des3_key->keys[1], &cipher->des3_key->ivs.v[1], 1);
|
||||
DES_ncbc_encrypt(in, out, len, &cipher->des3_key->keys[0], &cipher->des3_key->ivs.v[2], 0);
|
||||
|
||||
#ifdef DEBUG_CRYPTO
|
||||
ssh_print_hexa("Decrypt IV after", cipher->des3_key->ivs.c, 24);
|
||||
#endif
|
||||
}
|
||||
|
||||
static int des1_set_key(struct ssh_cipher_struct *cipher, void *key, void *IV) {
|
||||
DES_set_odd_parity(key);
|
||||
|
||||
cipher->des3_key = malloc(sizeof (struct ssh_3des_key_schedule));
|
||||
if (cipher->des3_key == NULL){
|
||||
return SSH_ERROR;
|
||||
}
|
||||
DES_set_key_unchecked(key, &cipher->des3_key->keys[0]);
|
||||
memcpy(cipher->des3_key->ivs.v, IV, 8);
|
||||
return SSH_OK;
|
||||
}
|
||||
|
||||
static void des1_1_encrypt(struct ssh_cipher_struct *cipher, void *in, void *out,
|
||||
unsigned long len){
|
||||
DES_ncbc_encrypt(in, out, len, &cipher->des3_key->keys[0], &cipher->des3_key->ivs.v[0], 1);
|
||||
}
|
||||
|
||||
static void des1_1_decrypt(struct ssh_cipher_struct *cipher, void *in, void *out,
|
||||
unsigned long len){
|
||||
DES_ncbc_encrypt(in,out,len, &cipher->des3_key->keys[0], &cipher->des3_key->ivs.v[0], 0);
|
||||
}
|
||||
|
||||
static void des_cleanup(struct ssh_cipher_struct *cipher){
|
||||
explicit_bzero(cipher->des3_key, sizeof(*cipher->des3_key));
|
||||
SAFE_FREE(cipher->des3_key);
|
||||
}
|
||||
|
||||
#endif /* HAS_DES */
|
||||
|
||||
/*
|
||||
* The table of supported ciphers
|
||||
@@ -838,28 +745,6 @@ static struct ssh_cipher_struct ssh_ciphertab[] = {
|
||||
.decrypt = evp_cipher_decrypt,
|
||||
.cleanup = evp_cipher_cleanup
|
||||
},
|
||||
{
|
||||
.name = "3des-cbc-ssh1",
|
||||
.blocksize = 8,
|
||||
.ciphertype = SSH_3DES_CBC_SSH1,
|
||||
.keysize = 192,
|
||||
.set_encrypt_key = des3_set_key,
|
||||
.set_decrypt_key = des3_set_key,
|
||||
.encrypt = des3_1_encrypt,
|
||||
.decrypt = des3_1_decrypt,
|
||||
.cleanup = des_cleanup
|
||||
},
|
||||
{
|
||||
.name = "des-cbc-ssh1",
|
||||
.blocksize = 8,
|
||||
.ciphertype = SSH_DES_CBC_SSH1,
|
||||
.keysize = 64,
|
||||
.set_encrypt_key = des1_set_key,
|
||||
.set_decrypt_key = des1_set_key,
|
||||
.encrypt = des1_1_encrypt,
|
||||
.decrypt = des1_1_decrypt,
|
||||
.cleanup = des_cleanup
|
||||
},
|
||||
#endif /* HAS_DES */
|
||||
{
|
||||
.name = "chacha20-poly1305@openssh.com"
|
||||
|
120
src/libgcrypt.c
120
src/libgcrypt.c
@@ -396,28 +396,6 @@ static void aes_decrypt(struct ssh_cipher_struct *cipher, void *in, void *out,
|
||||
gcry_cipher_decrypt(cipher->key[0], out, len, in, len);
|
||||
}
|
||||
|
||||
static int des1_set_key(struct ssh_cipher_struct *cipher, void *key, void *IV){
|
||||
if(!cipher->key){
|
||||
if (alloc_key(cipher) < 0) {
|
||||
return -1;
|
||||
}
|
||||
if (gcry_cipher_open(&cipher->key[0], GCRY_CIPHER_DES,
|
||||
GCRY_CIPHER_MODE_CBC, 0)) {
|
||||
SAFE_FREE(cipher->key);
|
||||
return -1;
|
||||
}
|
||||
if (gcry_cipher_setkey(cipher->key[0], key, 8)) {
|
||||
SAFE_FREE(cipher->key);
|
||||
return -1;
|
||||
}
|
||||
if (gcry_cipher_setiv(cipher->key[0], IV, 8)) {
|
||||
SAFE_FREE(cipher->key);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int des3_set_key(struct ssh_cipher_struct *cipher, void *key, void *IV) {
|
||||
if (cipher->key == NULL) {
|
||||
if (alloc_key(cipher) < 0) {
|
||||
@@ -441,17 +419,6 @@ static int des3_set_key(struct ssh_cipher_struct *cipher, void *key, void *IV) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static void des1_1_encrypt(struct ssh_cipher_struct *cipher, void *in,
|
||||
void *out, unsigned long len) {
|
||||
gcry_cipher_encrypt(cipher->key[0], out, len, in, len);
|
||||
}
|
||||
|
||||
static void des1_1_decrypt(struct ssh_cipher_struct *cipher, void *in,
|
||||
void *out, unsigned long len) {
|
||||
gcry_cipher_decrypt(cipher->key[0], out, len, in, len);
|
||||
}
|
||||
|
||||
static void des3_encrypt(struct ssh_cipher_struct *cipher, void *in,
|
||||
void *out, unsigned long len) {
|
||||
gcry_cipher_encrypt(cipher->key[0], out, len, in, len);
|
||||
@@ -462,71 +429,6 @@ static void des3_decrypt(struct ssh_cipher_struct *cipher, void *in,
|
||||
gcry_cipher_decrypt(cipher->key[0], out, len, in, len);
|
||||
}
|
||||
|
||||
static int des3_1_set_key(struct ssh_cipher_struct *cipher, void *key, void *IV) {
|
||||
if (cipher->key == NULL) {
|
||||
if (alloc_key(cipher) < 0) {
|
||||
return -1;
|
||||
}
|
||||
if (gcry_cipher_open(&cipher->key[0], GCRY_CIPHER_DES,
|
||||
GCRY_CIPHER_MODE_CBC, 0)) {
|
||||
SAFE_FREE(cipher->key);
|
||||
return -1;
|
||||
}
|
||||
if (gcry_cipher_setkey(cipher->key[0], key, 8)) {
|
||||
SAFE_FREE(cipher->key);
|
||||
return -1;
|
||||
}
|
||||
if (gcry_cipher_setiv(cipher->key[0], IV, 8)) {
|
||||
SAFE_FREE(cipher->key);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (gcry_cipher_open(&cipher->key[1], GCRY_CIPHER_DES,
|
||||
GCRY_CIPHER_MODE_CBC, 0)) {
|
||||
SAFE_FREE(cipher->key);
|
||||
return -1;
|
||||
}
|
||||
if (gcry_cipher_setkey(cipher->key[1], (unsigned char *)key + 8, 8)) {
|
||||
SAFE_FREE(cipher->key);
|
||||
return -1;
|
||||
}
|
||||
if (gcry_cipher_setiv(cipher->key[1], (unsigned char *)IV + 8, 8)) {
|
||||
SAFE_FREE(cipher->key);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (gcry_cipher_open(&cipher->key[2], GCRY_CIPHER_DES,
|
||||
GCRY_CIPHER_MODE_CBC, 0)) {
|
||||
SAFE_FREE(cipher->key);
|
||||
return -1;
|
||||
}
|
||||
if (gcry_cipher_setkey(cipher->key[2], (unsigned char *)key + 16, 8)) {
|
||||
SAFE_FREE(cipher->key);
|
||||
return -1;
|
||||
}
|
||||
if (gcry_cipher_setiv(cipher->key[2], (unsigned char *)IV + 16, 8)) {
|
||||
SAFE_FREE(cipher->key);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void des3_1_encrypt(struct ssh_cipher_struct *cipher, void *in,
|
||||
void *out, unsigned long len) {
|
||||
gcry_cipher_encrypt(cipher->key[0], out, len, in, len);
|
||||
gcry_cipher_decrypt(cipher->key[1], in, len, out, len);
|
||||
gcry_cipher_encrypt(cipher->key[2], out, len, in, len);
|
||||
}
|
||||
|
||||
static void des3_1_decrypt(struct ssh_cipher_struct *cipher, void *in,
|
||||
void *out, unsigned long len) {
|
||||
gcry_cipher_decrypt(cipher->key[2], out, len, in, len);
|
||||
gcry_cipher_encrypt(cipher->key[1], in, len, out, len);
|
||||
gcry_cipher_decrypt(cipher->key[0], out, len, in, len);
|
||||
}
|
||||
|
||||
/* the table of supported ciphers */
|
||||
static struct ssh_cipher_struct ssh_ciphertab[] = {
|
||||
{
|
||||
@@ -617,28 +519,6 @@ static struct ssh_cipher_struct ssh_ciphertab[] = {
|
||||
.encrypt = des3_encrypt,
|
||||
.decrypt = des3_decrypt
|
||||
},
|
||||
{
|
||||
.name = "3des-cbc-ssh1",
|
||||
.blocksize = 8,
|
||||
.keylen = sizeof(gcry_cipher_hd_t) * 3,
|
||||
.key = NULL,
|
||||
.keysize = 192,
|
||||
.set_encrypt_key = des3_1_set_key,
|
||||
.set_decrypt_key = des3_1_set_key,
|
||||
.encrypt = des3_1_encrypt,
|
||||
.decrypt = des3_1_decrypt
|
||||
},
|
||||
{
|
||||
.name = "des-cbc-ssh1",
|
||||
.blocksize = 8,
|
||||
.keylen = sizeof(gcry_cipher_hd_t),
|
||||
.key = NULL,
|
||||
.keysize = 64,
|
||||
.set_encrypt_key = des1_set_key,
|
||||
.set_decrypt_key = des1_set_key,
|
||||
.encrypt = des1_1_encrypt,
|
||||
.decrypt = des1_1_decrypt
|
||||
},
|
||||
{
|
||||
.name = "chacha20-poly1305@openssh.com"
|
||||
},
|
||||
|
@@ -835,129 +835,6 @@ static void cipher_cleanup(struct ssh_cipher_struct *cipher)
|
||||
mbedtls_cipher_free(&cipher->decrypt_ctx);
|
||||
}
|
||||
|
||||
static int des3_set_encrypt_key(struct ssh_cipher_struct *cipher, void *key,
|
||||
void *IV)
|
||||
{
|
||||
const mbedtls_cipher_info_t *cipher_info = NULL;
|
||||
unsigned char *des3_key = NULL;
|
||||
size_t des_key_size = 0;
|
||||
int rc;
|
||||
|
||||
mbedtls_cipher_init(&cipher->encrypt_ctx);
|
||||
cipher_info = mbedtls_cipher_info_from_type(cipher->type);
|
||||
|
||||
rc = mbedtls_cipher_setup(&cipher->encrypt_ctx, cipher_info);
|
||||
if (rc != 0) {
|
||||
SSH_LOG(SSH_LOG_WARNING, "mbedtls_cipher_setup failed");
|
||||
goto error;
|
||||
}
|
||||
|
||||
des3_key = malloc(cipher_info->key_bitlen / 8);
|
||||
if (des3_key == NULL) {
|
||||
SSH_LOG(SSH_LOG_WARNING, "error allocating memory for key");
|
||||
goto error;
|
||||
}
|
||||
|
||||
des_key_size = cipher_info->key_bitlen / (8 * 3);
|
||||
memcpy(des3_key, key, des_key_size);
|
||||
memcpy(des3_key + des_key_size, (unsigned char * )key + des_key_size,
|
||||
des_key_size);
|
||||
memcpy(des3_key + 2 * des_key_size,
|
||||
(unsigned char *) key + 2 * des_key_size, des_key_size);
|
||||
|
||||
rc = mbedtls_cipher_setkey(&cipher->encrypt_ctx, des3_key,
|
||||
cipher_info->key_bitlen,
|
||||
MBEDTLS_ENCRYPT);
|
||||
if (rc != 0) {
|
||||
SSH_LOG(SSH_LOG_WARNING, "mbedtls_cipher_setkey failed");
|
||||
goto error;
|
||||
}
|
||||
|
||||
rc = mbedtls_cipher_set_iv(&cipher->encrypt_ctx, IV, cipher_info->iv_size);
|
||||
|
||||
if (rc != 0) {
|
||||
SSH_LOG(SSH_LOG_WARNING, "mbedtls_cipher_set_iv failed");
|
||||
goto error;
|
||||
}
|
||||
|
||||
rc = mbedtls_cipher_reset(&cipher->encrypt_ctx);
|
||||
|
||||
if (rc != 0) {
|
||||
SSH_LOG(SSH_LOG_WARNING, "mbedtls_cipher_reset failed");
|
||||
goto error;
|
||||
}
|
||||
|
||||
SAFE_FREE(des3_key);
|
||||
return SSH_OK;
|
||||
error:
|
||||
mbedtls_cipher_free(&cipher->encrypt_ctx);
|
||||
SAFE_FREE(des3_key);
|
||||
return SSH_ERROR;
|
||||
}
|
||||
|
||||
static int des3_set_decrypt_key(struct ssh_cipher_struct *cipher, void *key,
|
||||
void *IV)
|
||||
{
|
||||
const mbedtls_cipher_info_t *cipher_info = NULL;
|
||||
unsigned char *des3_key = NULL;
|
||||
size_t des_key_size = 0;
|
||||
int rc;
|
||||
|
||||
mbedtls_cipher_init(&cipher->decrypt_ctx);
|
||||
cipher_info = mbedtls_cipher_info_from_type(cipher->type);
|
||||
|
||||
rc = mbedtls_cipher_setup(&cipher->decrypt_ctx, cipher_info);
|
||||
if (rc != 0) {
|
||||
SSH_LOG(SSH_LOG_WARNING, "mbedtls_cipher_setup failed");
|
||||
goto error;
|
||||
}
|
||||
|
||||
des3_key = malloc(cipher_info->key_bitlen / 8);
|
||||
if (des3_key == NULL) {
|
||||
SSH_LOG(SSH_LOG_WARNING, "error allocating memory for key");
|
||||
goto error;
|
||||
}
|
||||
|
||||
des_key_size = cipher_info->key_bitlen / (8 * 3);
|
||||
memcpy(des3_key, key, des_key_size);
|
||||
memcpy(des3_key + des_key_size, (unsigned char *) key + des_key_size,
|
||||
des_key_size);
|
||||
memcpy(des3_key + 2 * des_key_size,
|
||||
(unsigned char *) key + 2 * des_key_size,
|
||||
des_key_size);
|
||||
|
||||
rc = mbedtls_cipher_setkey(&cipher->decrypt_ctx, des3_key,
|
||||
cipher_info->key_bitlen,
|
||||
MBEDTLS_DECRYPT);
|
||||
if (rc != 0) {
|
||||
SSH_LOG(SSH_LOG_WARNING, "mbedtls_cipher_setkey failed");
|
||||
goto error;
|
||||
}
|
||||
|
||||
rc = mbedtls_cipher_set_iv(&cipher->decrypt_ctx, IV, cipher_info->iv_size);
|
||||
|
||||
if (rc != 0) {
|
||||
SSH_LOG(SSH_LOG_WARNING, "mbedtls_cipher_set_iv failed");
|
||||
goto error;
|
||||
}
|
||||
|
||||
rc = mbedtls_cipher_reset(&cipher->decrypt_ctx);
|
||||
|
||||
if (rc != 0) {
|
||||
SSH_LOG(SSH_LOG_WARNING, "mbedtls_cipher_reset failed");
|
||||
goto error;
|
||||
}
|
||||
|
||||
SAFE_FREE(des3_key);
|
||||
return SSH_OK;
|
||||
error:
|
||||
mbedtls_cipher_free(&cipher->decrypt_ctx);
|
||||
if (des3_key != NULL) {
|
||||
SAFE_FREE(des3_key);
|
||||
}
|
||||
return SSH_ERROR;
|
||||
}
|
||||
|
||||
static struct ssh_cipher_struct ssh_ciphertab[] = {
|
||||
{
|
||||
.name = "blowfish-cbc",
|
||||
@@ -1047,27 +924,6 @@ static struct ssh_cipher_struct ssh_ciphertab[] = {
|
||||
.decrypt = cipher_decrypt_cbc,
|
||||
.cleanup = cipher_cleanup
|
||||
},
|
||||
{
|
||||
.name = "3des-cbc-ssh1",
|
||||
.blocksize = 8,
|
||||
.keysize = 192,
|
||||
.type = MBEDTLS_CIPHER_DES_CBC,
|
||||
.set_encrypt_key = des3_set_encrypt_key,
|
||||
.set_decrypt_key = des3_set_decrypt_key,
|
||||
.encrypt = cipher_encrypt_cbc,
|
||||
.decrypt = cipher_decrypt_cbc,
|
||||
.cleanup = cipher_cleanup
|
||||
},
|
||||
{
|
||||
.name = "des-cbc-ssh1",
|
||||
.blocksize = 8,
|
||||
.keysize = 64,
|
||||
.type = MBEDTLS_CIPHER_DES_CBC,
|
||||
.set_encrypt_key = cipher_set_encrypt_key_cbc,
|
||||
.set_decrypt_key = cipher_set_decrypt_key_cbc,
|
||||
.encrypt = cipher_encrypt_cbc,
|
||||
.decrypt = cipher_decrypt_cbc,
|
||||
},
|
||||
{
|
||||
.name = "chacha20-poly1305@openssh.com"
|
||||
},
|
||||
|
18
src/misc.c
18
src/misc.c
@@ -821,14 +821,13 @@ char *ssh_path_expand_escape(ssh_session session, const char *s) {
|
||||
*
|
||||
* @param session The session to analyze the banner from.
|
||||
* @param server 0 means we are a client, 1 a server.
|
||||
* @param ssh1 The variable which is set if it is a SSHv1 server.
|
||||
* @param ssh2 The variable which is set if it is a SSHv2 server.
|
||||
*
|
||||
* @return 0 on success, < 0 on error.
|
||||
*
|
||||
* @see ssh_get_issue_banner()
|
||||
*/
|
||||
int ssh_analyze_banner(ssh_session session, int server, int *ssh1, int *ssh2) {
|
||||
int ssh_analyze_banner(ssh_session session, int server)
|
||||
{
|
||||
const char *banner;
|
||||
const char *openssh;
|
||||
|
||||
@@ -861,20 +860,15 @@ int ssh_analyze_banner(ssh_session session, int server, int *ssh1, int *ssh2) {
|
||||
SSH_LOG(SSH_LOG_RARE, "Analyzing banner: %s", banner);
|
||||
|
||||
switch (banner[4]) {
|
||||
case '2':
|
||||
break;
|
||||
case '1':
|
||||
*ssh1 = 1;
|
||||
if (strlen(banner) > 6) {
|
||||
if (banner[6] == '9') {
|
||||
*ssh2 = 1;
|
||||
} else {
|
||||
*ssh2 = 0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case '2':
|
||||
*ssh1 = 0;
|
||||
*ssh2 = 1;
|
||||
break;
|
||||
FALL_THROUGH;
|
||||
default:
|
||||
ssh_set_error(session, SSH_FATAL, "Protocol mismatch: %s", banner);
|
||||
return -1;
|
||||
|
@@ -151,8 +151,6 @@ int ssh_options_copy(ssh_session src, ssh_session *dest) {
|
||||
new->opts.port = src->opts.port;
|
||||
new->opts.timeout = src->opts.timeout;
|
||||
new->opts.timeout_usec = src->opts.timeout_usec;
|
||||
new->opts.ssh2 = src->opts.ssh2;
|
||||
new->opts.ssh1 = src->opts.ssh1;
|
||||
new->opts.compressionlevel = src->opts.compressionlevel;
|
||||
new->common.log_verbosity = src->common.log_verbosity;
|
||||
new->common.callbacks = src->common.callbacks;
|
||||
@@ -267,12 +265,10 @@ int ssh_options_set_algo(ssh_session session,
|
||||
* (long).
|
||||
*
|
||||
* - SSH_OPTIONS_SSH1:
|
||||
* Allow or deny the connection to SSH1 servers
|
||||
* (int, 0 is false).
|
||||
* Deprecated
|
||||
*
|
||||
* - SSH_OPTIONS_SSH2:
|
||||
* Allow or deny the connection to SSH2 servers
|
||||
* (int, 0 is false).
|
||||
Unused
|
||||
*
|
||||
* - SSH_OPTIONS_LOG_VERBOSITY:
|
||||
* Set the session logging verbosity (int).\n
|
||||
@@ -663,32 +659,8 @@ int ssh_options_set(ssh_session session, enum ssh_options_e type,
|
||||
}
|
||||
break;
|
||||
case SSH_OPTIONS_SSH1:
|
||||
if (value == NULL) {
|
||||
ssh_set_error_invalid(session);
|
||||
return -1;
|
||||
} else {
|
||||
int *x = (int *) value;
|
||||
if (*x < 0) {
|
||||
ssh_set_error_invalid(session);
|
||||
return -1;
|
||||
}
|
||||
|
||||
session->opts.ssh1 = *x;
|
||||
}
|
||||
break;
|
||||
case SSH_OPTIONS_SSH2:
|
||||
if (value == NULL) {
|
||||
ssh_set_error_invalid(session);
|
||||
return -1;
|
||||
} else {
|
||||
int *x = (int *) value;
|
||||
if (*x < 0) {
|
||||
ssh_set_error_invalid(session);
|
||||
return -1;
|
||||
}
|
||||
|
||||
session->opts.ssh2 = *x & 0xffff;
|
||||
}
|
||||
break;
|
||||
case SSH_OPTIONS_LOG_VERBOSITY:
|
||||
if (value == NULL) {
|
||||
@@ -1113,12 +1085,6 @@ int ssh_options_getopt(ssh_session session, int *argcptr, char **argv) {
|
||||
int compress = 0;
|
||||
int cont = 1;
|
||||
int current = 0;
|
||||
#ifdef WITH_SSH1
|
||||
int ssh1 = 1;
|
||||
#else
|
||||
int ssh1 = 0;
|
||||
#endif
|
||||
int ssh2 = 1;
|
||||
#ifdef _MSC_VER
|
||||
/* Not supported with a Microsoft compiler */
|
||||
return -1;
|
||||
@@ -1154,12 +1120,8 @@ int ssh_options_getopt(ssh_session session, int *argcptr, char **argv) {
|
||||
compress++;
|
||||
break;
|
||||
case '2':
|
||||
ssh2 = 1;
|
||||
ssh1 = 0;
|
||||
break;
|
||||
case '1':
|
||||
ssh2 = 0;
|
||||
ssh1 = 1;
|
||||
break;
|
||||
default:
|
||||
{
|
||||
@@ -1261,9 +1223,6 @@ int ssh_options_getopt(ssh_session session, int *argcptr, char **argv) {
|
||||
ssh_options_set(session, SSH_OPTIONS_PORT_STR, port);
|
||||
}
|
||||
|
||||
ssh_options_set(session, SSH_OPTIONS_SSH1, &ssh1);
|
||||
ssh_options_set(session, SSH_OPTIONS_SSH2, &ssh2);
|
||||
|
||||
if (!cont) {
|
||||
return SSH_ERROR;
|
||||
}
|
||||
@@ -1527,7 +1486,6 @@ int ssh_bind_options_set(ssh_bind sshbind, enum ssh_bind_options_e type,
|
||||
#endif
|
||||
break;
|
||||
case SSH_KEYTYPE_RSA:
|
||||
case SSH_KEYTYPE_RSA1:
|
||||
bind_key_loc = &sshbind->rsa;
|
||||
bind_key_path_loc = &sshbind->rsakey;
|
||||
break;
|
||||
@@ -1589,7 +1547,6 @@ int ssh_bind_options_set(ssh_bind sshbind, enum ssh_bind_options_e type,
|
||||
#endif
|
||||
break;
|
||||
case SSH_KEYTYPE_RSA:
|
||||
case SSH_KEYTYPE_RSA1:
|
||||
bind_key_loc = &sshbind->rsa;
|
||||
break;
|
||||
case SSH_KEYTYPE_ED25519:
|
||||
|
13
src/packet.c
13
src/packet.c
@@ -422,12 +422,6 @@ void ssh_packet_set_callbacks(ssh_session session, ssh_packet_callbacks callback
|
||||
* @brief sets the default packet handlers
|
||||
*/
|
||||
void ssh_packet_set_default_callbacks(ssh_session session){
|
||||
#ifdef WITH_SSH1
|
||||
if(session->version==1){
|
||||
ssh_packet_set_default_callbacks1(session);
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
session->default_packet_callbacks.start=1;
|
||||
session->default_packet_callbacks.n_callbacks=sizeof(default_packet_handlers)/sizeof(ssh_packet_callback);
|
||||
session->default_packet_callbacks.user=session;
|
||||
@@ -648,10 +642,5 @@ error:
|
||||
|
||||
|
||||
int ssh_packet_send(ssh_session session) {
|
||||
#ifdef WITH_SSH1
|
||||
if (session->version == 1) {
|
||||
return ssh_packet_send1(session);
|
||||
}
|
||||
#endif
|
||||
return packet_send2(session);
|
||||
return packet_send2(session);
|
||||
}
|
||||
|
371
src/packet1.c
371
src/packet1.c
@@ -1,371 +0,0 @@
|
||||
/*
|
||||
* This file is part of the SSH Library
|
||||
*
|
||||
* Copyright (c) 2010 by Aris Adamantiadis
|
||||
*
|
||||
* The SSH Library is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as published by
|
||||
* the Free Software Foundation; either version 2.1 of the License, or (at your
|
||||
* option) any later version.
|
||||
*
|
||||
* The SSH Library is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
|
||||
* License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with the SSH Library; see the file COPYING. If not, write to
|
||||
* the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
|
||||
* MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include <stdlib.h>
|
||||
|
||||
#ifndef _WIN32
|
||||
#include <netinet/in.h>
|
||||
#endif /* _WIN32 */
|
||||
|
||||
#include "libssh/priv.h"
|
||||
#include "libssh/ssh1.h"
|
||||
#include "libssh/crc32.h"
|
||||
#include "libssh/packet.h"
|
||||
#include "libssh/session.h"
|
||||
#include "libssh/buffer.h"
|
||||
#include "libssh/socket.h"
|
||||
#include "libssh/kex.h"
|
||||
#include "libssh/crypto.h"
|
||||
|
||||
#ifdef WITH_SSH1
|
||||
|
||||
static ssh_packet_callback default_packet_handlers1[]= {
|
||||
NULL, //SSH_MSG_NONE 0
|
||||
ssh_packet_disconnect1, //SSH_MSG_DISCONNECT 1
|
||||
ssh_packet_publickey1, //SSH_SMSG_PUBLIC_KEY 2
|
||||
NULL, //SSH_CMSG_SESSION_KEY 3
|
||||
NULL, //SSH_CMSG_USER 4
|
||||
NULL, //SSH_CMSG_AUTH_RHOSTS 5
|
||||
NULL, //SSH_CMSG_AUTH_RSA 6
|
||||
NULL, //SSH_SMSG_AUTH_RSA_CHALLENGE 7
|
||||
NULL, //SSH_CMSG_AUTH_RSA_RESPONSE 8
|
||||
NULL, //SSH_CMSG_AUTH_PASSWORD 9
|
||||
NULL, //SSH_CMSG_REQUEST_PTY 10
|
||||
NULL, //SSH_CMSG_WINDOW_SIZE 11
|
||||
NULL, //SSH_CMSG_EXEC_SHELL 12
|
||||
NULL, //SSH_CMSG_EXEC_CMD 13
|
||||
ssh_packet_smsg_success1, //SSH_SMSG_SUCCESS 14
|
||||
ssh_packet_smsg_failure1, //SSH_SMSG_FAILURE 15
|
||||
NULL, //SSH_CMSG_STDIN_DATA 16
|
||||
ssh_packet_data1, //SSH_SMSG_STDOUT_DATA 17
|
||||
ssh_packet_data1, //SSH_SMSG_STDERR_DATA 18
|
||||
NULL, //SSH_CMSG_EOF 19
|
||||
ssh_packet_exist_status1, //SSH_SMSG_EXITSTATUS 20
|
||||
NULL, //SSH_MSG_CHANNEL_OPEN_CONFIRMATION 21
|
||||
NULL, //SSH_MSG_CHANNEL_OPEN_FAILURE 22
|
||||
NULL, //SSH_MSG_CHANNEL_DATA 23
|
||||
ssh_packet_close1, //SSH_MSG_CHANNEL_CLOSE 24
|
||||
NULL, //SSH_MSG_CHANNEL_CLOSE_CONFIRMATION 25
|
||||
NULL, //SSH_CMSG_X11_REQUEST_FORWARDING 26
|
||||
NULL, //SSH_SMSG_X11_OPEN 27
|
||||
NULL, //SSH_CMSG_PORT_FORWARD_REQUEST 28
|
||||
NULL, //SSH_MSG_PORT_OPEN 29
|
||||
NULL, //SSH_CMSG_AGENT_REQUEST_FORWARDING 30
|
||||
NULL, //SSH_SMSG_AGENT_OPEN 31
|
||||
ssh_packet_ignore_callback, //SSH_MSG_IGNORE 32
|
||||
NULL, //SSH_CMSG_EXIT_CONFIRMATION 33
|
||||
NULL, //SSH_CMSG_X11_REQUEST_FORWARDING 34
|
||||
NULL, //SSH_CMSG_AUTH_RHOSTS_RSA 35
|
||||
ssh_packet_ignore_callback, //SSH_MSG_DEBUG 36
|
||||
};
|
||||
|
||||
/** @internal
|
||||
* @brief sets the default packet handlers
|
||||
*/
|
||||
void ssh_packet_set_default_callbacks1(ssh_session session){
|
||||
session->default_packet_callbacks.start=0;
|
||||
session->default_packet_callbacks.n_callbacks=sizeof(default_packet_handlers1)/sizeof(ssh_packet_callback);
|
||||
session->default_packet_callbacks.user=session;
|
||||
session->default_packet_callbacks.callbacks=default_packet_handlers1;
|
||||
ssh_packet_set_callbacks(session, &session->default_packet_callbacks);
|
||||
}
|
||||
|
||||
|
||||
/** @internal
|
||||
* @handles a data received event. It then calls the handlers for the different packet types
|
||||
* or and exception handler callback. Adapted for SSH-1 packets.
|
||||
* @param user pointer to current ssh_session
|
||||
* @param data pointer to the data received
|
||||
* @len length of data received. It might not be enough for a complete packet
|
||||
* @returns number of bytes read and processed.
|
||||
*/
|
||||
|
||||
int ssh_packet_socket_callback1(const void *data, size_t receivedlen, void *user) {
|
||||
void *packet = NULL;
|
||||
int to_be_read;
|
||||
size_t processed=0;
|
||||
uint32_t padding;
|
||||
uint32_t crc;
|
||||
uint32_t len, buffer_len;
|
||||
ssh_session session=(ssh_session)user;
|
||||
|
||||
switch (session->packet_state){
|
||||
case PACKET_STATE_INIT:
|
||||
memset(&session->in_packet, 0, sizeof(PACKET));
|
||||
|
||||
if (session->in_buffer) {
|
||||
if (ssh_buffer_reinit(session->in_buffer) < 0) {
|
||||
goto error;
|
||||
}
|
||||
} else {
|
||||
session->in_buffer = ssh_buffer_new();
|
||||
if (session->in_buffer == NULL) {
|
||||
goto error;
|
||||
}
|
||||
}
|
||||
/* must have at least enough bytes for size */
|
||||
if(receivedlen < sizeof(uint32_t)){
|
||||
return 0;
|
||||
}
|
||||
memcpy(&len,data,sizeof(uint32_t));
|
||||
processed += sizeof(uint32_t);
|
||||
|
||||
/* len is not encrypted */
|
||||
len = ntohl(len);
|
||||
if (len > MAX_PACKET_LEN) {
|
||||
ssh_set_error(session, SSH_FATAL,
|
||||
"read_packet(): Packet len too high (%u %.8x)", len, len);
|
||||
goto error;
|
||||
}
|
||||
|
||||
SSH_LOG(SSH_LOG_PACKET, "Reading a %d bytes packet", len);
|
||||
|
||||
session->in_packet.len = len;
|
||||
session->packet_state = PACKET_STATE_SIZEREAD;
|
||||
/* FALL THROUGH */
|
||||
case PACKET_STATE_SIZEREAD:
|
||||
len = session->in_packet.len;
|
||||
/* SSH-1 has a fixed padding lenght */
|
||||
padding = 8 - (len % 8);
|
||||
to_be_read = len + padding;
|
||||
if(to_be_read + processed > receivedlen){
|
||||
/* wait for rest of packet */
|
||||
return processed;
|
||||
}
|
||||
/* it is _not_ possible that to_be_read be < 8. */
|
||||
packet = (char *)data + processed;
|
||||
|
||||
if (ssh_buffer_add_data(session->in_buffer,packet,to_be_read) < 0) {
|
||||
goto error;
|
||||
}
|
||||
processed += to_be_read;
|
||||
#ifdef DEBUG_CRYPTO
|
||||
ssh_print_hexa("read packet:", ssh_buffer_get(session->in_buffer),
|
||||
ssh_buffer_get_len(session->in_buffer));
|
||||
#endif
|
||||
if (session->current_crypto) {
|
||||
/*
|
||||
* We decrypt everything, missing the lenght part (which was
|
||||
* previously read, unencrypted, and is not part of the buffer
|
||||
*/
|
||||
buffer_len = ssh_buffer_get_len(session->in_buffer);
|
||||
if (buffer_len > 0) {
|
||||
int rc;
|
||||
rc = ssh_packet_decrypt(session,
|
||||
ssh_buffer_get(session->in_buffer),
|
||||
buffer_len);
|
||||
if (rc < 0) {
|
||||
ssh_set_error(session, SSH_FATAL, "Packet decrypt error");
|
||||
goto error;
|
||||
}
|
||||
}
|
||||
}
|
||||
#ifdef DEBUG_CRYPTO
|
||||
ssh_print_hexa("read packet decrypted:", ssh_buffer_get(session->in_buffer),
|
||||
ssh_buffer_get_len(session->in_buffer));
|
||||
#endif
|
||||
SSH_LOG(SSH_LOG_PACKET, "%d bytes padding", padding);
|
||||
if(((len + padding) != ssh_buffer_get_len(session->in_buffer)) ||
|
||||
((len + padding) < sizeof(uint32_t))) {
|
||||
SSH_LOG(SSH_LOG_RARE, "no crc32 in packet");
|
||||
ssh_set_error(session, SSH_FATAL, "no crc32 in packet");
|
||||
goto error;
|
||||
}
|
||||
|
||||
memcpy(&crc,
|
||||
(unsigned char *)ssh_buffer_get(session->in_buffer) + (len+padding) - sizeof(uint32_t),
|
||||
sizeof(uint32_t));
|
||||
ssh_buffer_pass_bytes_end(session->in_buffer, sizeof(uint32_t));
|
||||
crc = ntohl(crc);
|
||||
if (ssh_crc32(ssh_buffer_get(session->in_buffer),
|
||||
(len + padding) - sizeof(uint32_t)) != crc) {
|
||||
#ifdef DEBUG_CRYPTO
|
||||
ssh_print_hexa("crc32 on",ssh_buffer_get(session->in_buffer),
|
||||
len + padding - sizeof(uint32_t));
|
||||
#endif
|
||||
SSH_LOG(SSH_LOG_RARE, "Invalid crc32");
|
||||
ssh_set_error(session, SSH_FATAL,
|
||||
"Invalid crc32: expected %.8x, got %.8x",
|
||||
crc,
|
||||
ssh_crc32(ssh_buffer_get(session->in_buffer),
|
||||
len + padding - sizeof(uint32_t)));
|
||||
goto error;
|
||||
}
|
||||
/* pass the padding */
|
||||
ssh_buffer_pass_bytes(session->in_buffer, padding);
|
||||
SSH_LOG(SSH_LOG_PACKET, "The packet is valid");
|
||||
|
||||
/* TODO FIXME
|
||||
#ifdef WITH_ZLIB
|
||||
if(session->current_crypto && session->current_crypto->do_compress_in){
|
||||
decompress_buffer(session,session->in_buffer);
|
||||
}
|
||||
#endif
|
||||
*/
|
||||
session->recv_seq++;
|
||||
/* We don't want to rewrite a new packet while still executing the packet callbacks */
|
||||
session->packet_state = PACKET_STATE_PROCESSING;
|
||||
ssh_packet_parse_type(session);
|
||||
/* execute callbacks */
|
||||
ssh_packet_process(session, session->in_packet.type);
|
||||
session->packet_state = PACKET_STATE_INIT;
|
||||
if(processed < receivedlen){
|
||||
int rc;
|
||||
/* Handle a potential packet left in socket buffer */
|
||||
SSH_LOG(SSH_LOG_PACKET,"Processing %" PRIdS " bytes left in socket buffer",
|
||||
receivedlen-processed);
|
||||
rc = ssh_packet_socket_callback1((char *)data + processed,
|
||||
receivedlen - processed,user);
|
||||
processed += rc;
|
||||
}
|
||||
|
||||
return processed;
|
||||
case PACKET_STATE_PROCESSING:
|
||||
SSH_LOG(SSH_LOG_PACKET, "Nested packet processing. Delaying.");
|
||||
return 0;
|
||||
}
|
||||
|
||||
error:
|
||||
session->session_state=SSH_SESSION_STATE_ERROR;
|
||||
|
||||
return processed;
|
||||
}
|
||||
|
||||
|
||||
int ssh_packet_send1(ssh_session session) {
|
||||
unsigned int blocksize = (session->current_crypto ?
|
||||
session->current_crypto->out_cipher->blocksize : 8);
|
||||
uint32_t currentlen = ssh_buffer_get_len(session->out_buffer) + sizeof(uint32_t);
|
||||
char padstring[32] = {0};
|
||||
int rc = SSH_ERROR;
|
||||
uint32_t finallen;
|
||||
uint32_t crc;
|
||||
uint8_t padding;
|
||||
|
||||
SSH_LOG(SSH_LOG_PACKET,"Sending a %d bytes long packet",currentlen);
|
||||
|
||||
/* TODO FIXME
|
||||
#ifdef WITH_ZLIB
|
||||
if (session->current_crypto && session->current_crypto->do_compress_out) {
|
||||
if (compress_buffer(session, session->out_buffer) < 0) {
|
||||
goto error;
|
||||
}
|
||||
currentlen = ssh_buffer_get_len(session->out_buffer);
|
||||
}
|
||||
#endif
|
||||
*/
|
||||
padding = blocksize - (currentlen % blocksize);
|
||||
if (session->current_crypto) {
|
||||
ssh_get_random(padstring, padding, 0);
|
||||
} else {
|
||||
memset(padstring, 0, padding);
|
||||
}
|
||||
|
||||
finallen = htonl(currentlen);
|
||||
SSH_LOG(SSH_LOG_PACKET,
|
||||
"%d bytes after comp + %d padding bytes = %d bytes packet",
|
||||
currentlen, padding, ntohl(finallen));
|
||||
|
||||
if (ssh_buffer_prepend_data(session->out_buffer, &padstring, padding) < 0) {
|
||||
goto error;
|
||||
}
|
||||
if (ssh_buffer_prepend_data(session->out_buffer, &finallen, sizeof(uint32_t)) < 0) {
|
||||
goto error;
|
||||
}
|
||||
|
||||
crc = ssh_crc32((char *)ssh_buffer_get(session->out_buffer) + sizeof(uint32_t),
|
||||
ssh_buffer_get_len(session->out_buffer) - sizeof(uint32_t));
|
||||
|
||||
if (ssh_buffer_add_u32(session->out_buffer, ntohl(crc)) < 0) {
|
||||
goto error;
|
||||
}
|
||||
|
||||
#ifdef DEBUG_CRYPTO
|
||||
ssh_print_hexa("Clear packet", ssh_buffer_get(session->out_buffer),
|
||||
ssh_buffer_get_len(session->out_buffer));
|
||||
#endif
|
||||
|
||||
/* session->out_buffer should have more than sizeof(uint32_t) bytes
|
||||
in it as required for ssh_packet_encrypt */
|
||||
ssh_packet_encrypt(session, (unsigned char *)ssh_buffer_get(session->out_buffer) + sizeof(uint32_t),
|
||||
ssh_buffer_get_len(session->out_buffer) - sizeof(uint32_t));
|
||||
|
||||
#ifdef DEBUG_CRYPTO
|
||||
ssh_print_hexa("encrypted packet",ssh_buffer_get(session->out_buffer),
|
||||
ssh_buffer_get_len(session->out_buffer));
|
||||
#endif
|
||||
rc=ssh_socket_write(session->socket, ssh_buffer_get(session->out_buffer),
|
||||
ssh_buffer_get_len(session->out_buffer));
|
||||
if(rc== SSH_ERROR) {
|
||||
goto error;
|
||||
}
|
||||
|
||||
session->send_seq++;
|
||||
|
||||
if (ssh_buffer_reinit(session->out_buffer) < 0) {
|
||||
rc = SSH_ERROR;
|
||||
}
|
||||
error:
|
||||
|
||||
return rc; /* SSH_OK, AGAIN or ERROR */
|
||||
}
|
||||
|
||||
SSH_PACKET_CALLBACK(ssh_packet_disconnect1){
|
||||
(void)packet;
|
||||
(void)user;
|
||||
(void)type;
|
||||
SSH_LOG(SSH_LOG_PACKET, "Received SSH_MSG_DISCONNECT");
|
||||
ssh_set_error(session, SSH_FATAL, "Received SSH_MSG_DISCONNECT");
|
||||
ssh_socket_close(session->socket);
|
||||
session->alive = 0;
|
||||
session->session_state=SSH_SESSION_STATE_DISCONNECTED;
|
||||
return SSH_PACKET_USED;
|
||||
}
|
||||
|
||||
SSH_PACKET_CALLBACK(ssh_packet_smsg_success1){
|
||||
if(session->session_state==SSH_SESSION_STATE_KEXINIT_RECEIVED){
|
||||
session->session_state=SSH_SESSION_STATE_AUTHENTICATING;
|
||||
return SSH_PACKET_USED;
|
||||
} else if(session->session_state==SSH_SESSION_STATE_AUTHENTICATING){
|
||||
ssh_auth1_handler(session,type);
|
||||
return SSH_PACKET_USED;
|
||||
} else {
|
||||
return ssh_packet_channel_success(session,type,packet,user);
|
||||
}
|
||||
}
|
||||
|
||||
SSH_PACKET_CALLBACK(ssh_packet_smsg_failure1){
|
||||
if(session->session_state==SSH_SESSION_STATE_KEXINIT_RECEIVED){
|
||||
session->session_state=SSH_SESSION_STATE_ERROR;
|
||||
ssh_set_error(session,SSH_FATAL,"Key exchange failed: received SSH_SMSG_FAILURE");
|
||||
return SSH_PACKET_USED;
|
||||
} else if(session->session_state==SSH_SESSION_STATE_AUTHENTICATING){
|
||||
ssh_auth1_handler(session,type);
|
||||
return SSH_PACKET_USED;
|
||||
} else {
|
||||
return ssh_packet_channel_failure(session,type,packet,user);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#endif /* WITH_SSH1 */
|
@@ -166,8 +166,9 @@ SSH_PACKET_CALLBACK(ssh_packet_newkeys){
|
||||
* Set the cryptographic functions for the next crypto
|
||||
* (it is needed for ssh_generate_session_keys for key lengths)
|
||||
*/
|
||||
if (crypt_set_algorithms(session, SSH_3DES) /* knows nothing about DES*/ ) {
|
||||
goto error;
|
||||
rc = crypt_set_algorithms_client(session);
|
||||
if (rc < 0) {
|
||||
goto error;
|
||||
}
|
||||
|
||||
if (ssh_generate_session_keys(session) < 0) {
|
||||
|
@@ -151,7 +151,6 @@ unsigned char *ssh_packet_encrypt(ssh_session session, void *data, uint32_t len)
|
||||
crypto->aead_encrypt(crypto, data, out, len,
|
||||
session->current_crypto->hmacbuf, session->send_seq);
|
||||
} else {
|
||||
if (session->version == 2) {
|
||||
ctx = hmac_init(session->current_crypto->encryptMAC, hmac_digest_len(type), type);
|
||||
if (ctx == NULL) {
|
||||
SAFE_FREE(out);
|
||||
@@ -168,18 +167,13 @@ unsigned char *ssh_packet_encrypt(ssh_session session, void *data, uint32_t len)
|
||||
}
|
||||
ssh_print_hexa("Packet hmac", session->current_crypto->hmacbuf, hmac_digest_len(type));
|
||||
#endif
|
||||
}
|
||||
crypto->encrypt(crypto, data, out, len);
|
||||
crypto->encrypt(crypto, data, out, len);
|
||||
}
|
||||
memcpy(data, out, len);
|
||||
explicit_bzero(out, len);
|
||||
SAFE_FREE(out);
|
||||
|
||||
if (session->version == 2) {
|
||||
return session->current_crypto->hmacbuf;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
return session->current_crypto->hmacbuf;
|
||||
}
|
||||
|
||||
/**
|
||||
|
27
src/pki.c
27
src/pki.c
@@ -181,7 +181,9 @@ void ssh_key_free (ssh_key key){
|
||||
/**
|
||||
* @brief returns the type of a ssh key
|
||||
* @param[in] key the ssh_key handle
|
||||
* @returns one of SSH_KEYTYPE_RSA,SSH_KEYTYPE_DSS,SSH_KEYTYPE_RSA1
|
||||
* @returns one of SSH_KEYTYPE_RSA, SSH_KEYTYPE_DSS,
|
||||
* SSH_KEYTYPE_ECDSA, SSH_KEYTYPE_ED25519,
|
||||
* SSH_KEYTYPE_DSS_CERT01, SSH_KEYTYPE_RSA_CERT01
|
||||
* @returns SSH_KEYTYPE_UNKNOWN if the type is unknown
|
||||
*/
|
||||
enum ssh_keytypes_e ssh_key_type(const ssh_key key){
|
||||
@@ -204,8 +206,6 @@ const char *ssh_key_type_to_char(enum ssh_keytypes_e type) {
|
||||
return "ssh-dss";
|
||||
case SSH_KEYTYPE_RSA:
|
||||
return "ssh-rsa";
|
||||
case SSH_KEYTYPE_RSA1:
|
||||
return "ssh-rsa1";
|
||||
case SSH_KEYTYPE_ECDSA:
|
||||
return "ssh-ecdsa";
|
||||
case SSH_KEYTYPE_ED25519:
|
||||
@@ -214,6 +214,7 @@ const char *ssh_key_type_to_char(enum ssh_keytypes_e type) {
|
||||
return "ssh-dss-cert-v01@openssh.com";
|
||||
case SSH_KEYTYPE_RSA_CERT01:
|
||||
return "ssh-rsa-cert-v01@openssh.com";
|
||||
case SSH_KEYTYPE_RSA1:
|
||||
case SSH_KEYTYPE_UNKNOWN:
|
||||
return NULL;
|
||||
}
|
||||
@@ -234,14 +235,10 @@ enum ssh_keytypes_e ssh_key_type_from_name(const char *name) {
|
||||
return SSH_KEYTYPE_UNKNOWN;
|
||||
}
|
||||
|
||||
if (strcmp(name, "rsa1") == 0) {
|
||||
return SSH_KEYTYPE_RSA1;
|
||||
} else if (strcmp(name, "rsa") == 0) {
|
||||
if (strcmp(name, "rsa") == 0) {
|
||||
return SSH_KEYTYPE_RSA;
|
||||
} else if (strcmp(name, "dsa") == 0) {
|
||||
return SSH_KEYTYPE_DSS;
|
||||
} else if (strcmp(name, "ssh-rsa1") == 0) {
|
||||
return SSH_KEYTYPE_RSA1;
|
||||
} else if (strcmp(name, "ssh-rsa") == 0) {
|
||||
return SSH_KEYTYPE_RSA;
|
||||
} else if (strcmp(name, "ssh-dss") == 0) {
|
||||
@@ -359,7 +356,6 @@ void ssh_signature_free(ssh_signature sig)
|
||||
#endif
|
||||
break;
|
||||
case SSH_KEYTYPE_RSA:
|
||||
case SSH_KEYTYPE_RSA1:
|
||||
#ifdef HAVE_LIBGCRYPT
|
||||
gcry_sexp_release(sig->rsa_sig);
|
||||
#elif defined HAVE_LIBCRYPTO
|
||||
@@ -383,6 +379,7 @@ void ssh_signature_free(ssh_signature sig)
|
||||
break;
|
||||
case SSH_KEYTYPE_DSS_CERT01:
|
||||
case SSH_KEYTYPE_RSA_CERT01:
|
||||
case SSH_KEYTYPE_RSA1:
|
||||
case SSH_KEYTYPE_UNKNOWN:
|
||||
break;
|
||||
}
|
||||
@@ -740,7 +737,6 @@ static int pki_import_pubkey_buffer(ssh_buffer buffer,
|
||||
}
|
||||
break;
|
||||
case SSH_KEYTYPE_RSA:
|
||||
case SSH_KEYTYPE_RSA1:
|
||||
{
|
||||
ssh_string e;
|
||||
ssh_string n;
|
||||
@@ -830,6 +826,7 @@ static int pki_import_pubkey_buffer(ssh_buffer buffer,
|
||||
break;
|
||||
case SSH_KEYTYPE_DSS_CERT01:
|
||||
case SSH_KEYTYPE_RSA_CERT01:
|
||||
case SSH_KEYTYPE_RSA1:
|
||||
case SSH_KEYTYPE_UNKNOWN:
|
||||
default:
|
||||
SSH_LOG(SSH_LOG_WARN, "Unknown public key protocol %d", type);
|
||||
@@ -1191,7 +1188,6 @@ int ssh_pki_generate(enum ssh_keytypes_e type, int parameter,
|
||||
|
||||
switch(type){
|
||||
case SSH_KEYTYPE_RSA:
|
||||
case SSH_KEYTYPE_RSA1:
|
||||
rc = pki_key_generate_rsa(key, parameter);
|
||||
if(rc == SSH_ERROR)
|
||||
goto error;
|
||||
@@ -1220,6 +1216,7 @@ int ssh_pki_generate(enum ssh_keytypes_e type, int parameter,
|
||||
break;
|
||||
case SSH_KEYTYPE_DSS_CERT01:
|
||||
case SSH_KEYTYPE_RSA_CERT01:
|
||||
case SSH_KEYTYPE_RSA1:
|
||||
case SSH_KEYTYPE_UNKNOWN:
|
||||
default:
|
||||
goto error;
|
||||
@@ -1437,14 +1434,6 @@ int ssh_pki_copy_cert_to_privkey(const ssh_key certkey, ssh_key privkey) {
|
||||
return SSH_OK;
|
||||
}
|
||||
|
||||
int ssh_pki_export_pubkey_rsa1(const ssh_key key,
|
||||
const char *host,
|
||||
char *rsa1,
|
||||
size_t rsa1_len)
|
||||
{
|
||||
return pki_export_pubkey_rsa1(key, host, rsa1, rsa1_len);
|
||||
}
|
||||
|
||||
int ssh_pki_export_signature_blob(const ssh_signature sig,
|
||||
ssh_string *sig_blob)
|
||||
{
|
||||
|
@@ -119,11 +119,11 @@ static int pki_openssh_import_privkey_blob(ssh_buffer key_blob_buffer,
|
||||
case SSH_KEYTYPE_RSA_CERT01:
|
||||
case SSH_KEYTYPE_RSA:
|
||||
/* n,e,d,iqmp,p,q */
|
||||
case SSH_KEYTYPE_RSA1:
|
||||
case SSH_KEYTYPE_ECDSA:
|
||||
/* curve_name, group, privkey */
|
||||
SSH_LOG(SSH_LOG_WARN, "Unsupported private key method %s", key->type_c);
|
||||
goto fail;
|
||||
case SSH_KEYTYPE_RSA1:
|
||||
case SSH_KEYTYPE_UNKNOWN:
|
||||
SSH_LOG(SSH_LOG_WARN, "Unknown private key protocol %s", key->type_c);
|
||||
goto fail;
|
||||
|
@@ -1180,37 +1180,6 @@ fail:
|
||||
return NULL;
|
||||
}
|
||||
|
||||
int pki_export_pubkey_rsa1(const ssh_key key,
|
||||
const char *host,
|
||||
char *rsa1,
|
||||
size_t rsa1_len)
|
||||
{
|
||||
char *e;
|
||||
char *n;
|
||||
int rsa_size = RSA_size(key->rsa);
|
||||
const BIGNUM *be, *bn;
|
||||
|
||||
RSA_get0_key(key->rsa, &bn, &be, NULL);
|
||||
e = bignum_bn2dec(be);
|
||||
if (e == NULL) {
|
||||
return SSH_ERROR;
|
||||
}
|
||||
|
||||
n = bignum_bn2dec(bn);
|
||||
if (n == NULL) {
|
||||
OPENSSL_free(e);
|
||||
return SSH_ERROR;
|
||||
}
|
||||
|
||||
snprintf(rsa1, rsa1_len,
|
||||
"%s %d %s %s\n",
|
||||
host, rsa_size << 3, e, n);
|
||||
OPENSSL_free(e);
|
||||
OPENSSL_free(n);
|
||||
|
||||
return SSH_OK;
|
||||
}
|
||||
|
||||
/**
|
||||
* @internal
|
||||
*
|
||||
|
@@ -950,7 +950,6 @@ ssh_key pki_private_key_from_base64(const char *b64_key,
|
||||
}
|
||||
break;
|
||||
case SSH_KEYTYPE_RSA:
|
||||
case SSH_KEYTYPE_RSA1:
|
||||
if (passphrase == NULL) {
|
||||
if (auth_fn) {
|
||||
valid = b64decode_rsa_privatekey(b64_key, &rsa, auth_fn,
|
||||
@@ -1000,7 +999,8 @@ ssh_key pki_private_key_from_base64(const char *b64_key,
|
||||
break;
|
||||
#endif
|
||||
case SSH_KEYTYPE_ED25519:
|
||||
/* Cannot open ed25519 keys with libgcrypt */
|
||||
/* Cannot open ed25519 keys with libgcrypt */
|
||||
case SSH_KEYTYPE_RSA1:
|
||||
case SSH_KEYTYPE_UNKNOWN:
|
||||
default:
|
||||
SSH_LOG(SSH_LOG_WARN, "Unkown or invalid private key type %d", type);
|
||||
@@ -1146,7 +1146,6 @@ ssh_key pki_key_dup(const ssh_key key, int demote)
|
||||
}
|
||||
break;
|
||||
case SSH_KEYTYPE_RSA:
|
||||
case SSH_KEYTYPE_RSA1:
|
||||
err = gcry_sexp_extract_param(key->rsa,
|
||||
NULL,
|
||||
"ned?p?q?u?",
|
||||
@@ -1216,6 +1215,7 @@ ssh_key pki_key_dup(const ssh_key key, int demote)
|
||||
}
|
||||
break;
|
||||
#endif
|
||||
case SSH_KEYTYPE_RSA1:
|
||||
case SSH_KEYTYPE_UNKNOWN:
|
||||
default:
|
||||
ssh_key_free(new);
|
||||
@@ -1366,7 +1366,6 @@ int pki_key_compare(const ssh_key k1,
|
||||
}
|
||||
break;
|
||||
case SSH_KEYTYPE_RSA:
|
||||
case SSH_KEYTYPE_RSA1:
|
||||
if (_bignum_cmp(k1->rsa, k2->rsa, "e") != 0) {
|
||||
return 1;
|
||||
}
|
||||
@@ -1413,6 +1412,7 @@ int pki_key_compare(const ssh_key k1,
|
||||
#endif
|
||||
case SSH_KEYTYPE_DSS_CERT01:
|
||||
case SSH_KEYTYPE_RSA_CERT01:
|
||||
case SSH_KEYTYPE_RSA1:
|
||||
case SSH_KEYTYPE_UNKNOWN:
|
||||
return 1;
|
||||
}
|
||||
@@ -1521,7 +1521,6 @@ ssh_string pki_publickey_to_blob(const ssh_key key)
|
||||
|
||||
break;
|
||||
case SSH_KEYTYPE_RSA:
|
||||
case SSH_KEYTYPE_RSA1:
|
||||
e = ssh_sexp_extract_mpi(key->rsa,
|
||||
"e",
|
||||
GCRYMPI_FMT_USG,
|
||||
@@ -1592,6 +1591,7 @@ ssh_string pki_publickey_to_blob(const ssh_key key)
|
||||
e = NULL;
|
||||
break;
|
||||
#endif
|
||||
case SSH_KEYTYPE_RSA1:
|
||||
case SSH_KEYTYPE_UNKNOWN:
|
||||
default:
|
||||
goto fail;
|
||||
@@ -1628,36 +1628,6 @@ fail:
|
||||
return NULL;
|
||||
}
|
||||
|
||||
int pki_export_pubkey_rsa1(const ssh_key key,
|
||||
const char *host,
|
||||
char *rsa1,
|
||||
size_t rsa1_len)
|
||||
{
|
||||
gpg_error_t err;
|
||||
int rsa_size;
|
||||
bignum E, N;
|
||||
char *e, *n;
|
||||
|
||||
err = gcry_sexp_extract_param(key->rsa, NULL, "en", &E, &N, NULL);
|
||||
if (err != 0) {
|
||||
return SSH_ERROR;
|
||||
}
|
||||
e = bignum_bn2dec(E);
|
||||
n = bignum_bn2dec(N);
|
||||
|
||||
rsa_size = (gcry_pk_get_nbits(key->rsa) + 7) / 8;
|
||||
|
||||
snprintf(rsa1, rsa1_len,
|
||||
"%s %d %s %s\n",
|
||||
host, rsa_size << 3, e, n);
|
||||
SAFE_FREE(e);
|
||||
SAFE_FREE(n);
|
||||
bignum_free(E);
|
||||
bignum_free(N);
|
||||
|
||||
return SSH_OK;
|
||||
}
|
||||
|
||||
ssh_string pki_signature_to_blob(const ssh_signature sig)
|
||||
{
|
||||
char buffer[40] = { 0 };
|
||||
@@ -1721,7 +1691,6 @@ ssh_string pki_signature_to_blob(const ssh_signature sig)
|
||||
ssh_string_fill(sig_blob, buffer, 40);
|
||||
break;
|
||||
case SSH_KEYTYPE_RSA:
|
||||
case SSH_KEYTYPE_RSA1:
|
||||
sexp = gcry_sexp_find_token(sig->rsa_sig, "s", 0);
|
||||
if (sexp == NULL) {
|
||||
return NULL;
|
||||
@@ -1796,6 +1765,7 @@ ssh_string pki_signature_to_blob(const ssh_signature sig)
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
case SSH_KEYTYPE_RSA1:
|
||||
case SSH_KEYTYPE_UNKNOWN:
|
||||
default:
|
||||
SSH_LOG(SSH_LOG_WARN, "Unknown signature key type: %d", sig->type);
|
||||
@@ -1856,7 +1826,6 @@ ssh_signature pki_signature_from_blob(const ssh_key pubkey,
|
||||
}
|
||||
break;
|
||||
case SSH_KEYTYPE_RSA:
|
||||
case SSH_KEYTYPE_RSA1:
|
||||
rsalen = (gcry_pk_get_nbits(pubkey->rsa) + 7) / 8;
|
||||
|
||||
if (len > rsalen) {
|
||||
@@ -1971,6 +1940,7 @@ ssh_signature pki_signature_from_blob(const ssh_key pubkey,
|
||||
}
|
||||
break;
|
||||
#endif
|
||||
case SSH_KEYTYPE_RSA1:
|
||||
case SSH_KEYTYPE_UNKNOWN:
|
||||
default:
|
||||
SSH_LOG(SSH_LOG_WARN, "Unknown signature type");
|
||||
@@ -2021,7 +1991,6 @@ int pki_signature_verify(ssh_session session,
|
||||
}
|
||||
break;
|
||||
case SSH_KEYTYPE_RSA:
|
||||
case SSH_KEYTYPE_RSA1:
|
||||
err = gcry_sexp_build(&sexp,
|
||||
NULL,
|
||||
"(data(flags pkcs1)(hash sha1 %b))",
|
||||
@@ -2082,6 +2051,7 @@ int pki_signature_verify(ssh_session session,
|
||||
}
|
||||
break;
|
||||
#endif
|
||||
case SSH_KEYTYPE_RSA1:
|
||||
case SSH_KEYTYPE_UNKNOWN:
|
||||
default:
|
||||
ssh_set_error(session, SSH_FATAL, "Unknown public key type");
|
||||
@@ -2129,7 +2099,6 @@ ssh_signature pki_do_sign(const ssh_key privkey,
|
||||
}
|
||||
break;
|
||||
case SSH_KEYTYPE_RSA:
|
||||
case SSH_KEYTYPE_RSA1:
|
||||
err = gcry_sexp_build(&sexp,
|
||||
NULL,
|
||||
"(data(flags pkcs1)(hash sha1 %b))",
|
||||
@@ -2174,6 +2143,7 @@ ssh_signature pki_do_sign(const ssh_key privkey,
|
||||
}
|
||||
break;
|
||||
#endif
|
||||
case SSH_KEYTYPE_RSA1:
|
||||
case SSH_KEYTYPE_UNKNOWN:
|
||||
default:
|
||||
ssh_signature_free(sig);
|
||||
@@ -2223,7 +2193,6 @@ ssh_signature pki_do_sign_sessionid(const ssh_key key,
|
||||
}
|
||||
break;
|
||||
case SSH_KEYTYPE_RSA:
|
||||
case SSH_KEYTYPE_RSA1:
|
||||
err = gcry_sexp_build(&sexp,
|
||||
NULL,
|
||||
"(data(flags pkcs1)(hash sha1 %b))",
|
||||
@@ -2261,6 +2230,7 @@ ssh_signature pki_do_sign_sessionid(const ssh_key key,
|
||||
}
|
||||
break;
|
||||
#endif
|
||||
case SSH_KEYTYPE_RSA1:
|
||||
case SSH_KEYTYPE_UNKNOWN:
|
||||
default:
|
||||
return NULL;
|
||||
|
@@ -86,7 +86,6 @@ ssh_key pki_private_key_from_base64(const char *b64_key, const char *passphrase,
|
||||
|
||||
switch (type) {
|
||||
case SSH_KEYTYPE_RSA:
|
||||
case SSH_KEYTYPE_RSA1:
|
||||
rsa = malloc(sizeof(mbedtls_pk_context));
|
||||
if (rsa == NULL) {
|
||||
return NULL;
|
||||
@@ -277,8 +276,7 @@ ssh_key pki_key_dup(const ssh_key key, int demote)
|
||||
|
||||
|
||||
switch(key->type) {
|
||||
case SSH_KEYTYPE_RSA:
|
||||
case SSH_KEYTYPE_RSA1: {
|
||||
case SSH_KEYTYPE_RSA: {
|
||||
mbedtls_rsa_context *rsa, *new_rsa;
|
||||
|
||||
new->rsa = malloc(sizeof(mbedtls_pk_context));
|
||||
@@ -418,8 +416,7 @@ int pki_key_generate_rsa(ssh_key key, int parameter)
|
||||
int pki_key_compare(const ssh_key k1, const ssh_key k2, enum ssh_keycmp_e what)
|
||||
{
|
||||
switch (k1->type) {
|
||||
case SSH_KEYTYPE_RSA:
|
||||
case SSH_KEYTYPE_RSA1: {
|
||||
case SSH_KEYTYPE_RSA: {
|
||||
mbedtls_rsa_context *rsa1, *rsa2;
|
||||
if (mbedtls_pk_can_do(k1->rsa, MBEDTLS_PK_RSA) &&
|
||||
mbedtls_pk_can_do(k2->rsa, MBEDTLS_PK_RSA)) {
|
||||
@@ -582,8 +579,7 @@ ssh_string pki_publickey_to_blob(const ssh_key key)
|
||||
}
|
||||
|
||||
switch (key->type) {
|
||||
case SSH_KEYTYPE_RSA:
|
||||
case SSH_KEYTYPE_RSA1: {
|
||||
case SSH_KEYTYPE_RSA: {
|
||||
mbedtls_rsa_context *rsa;
|
||||
if (mbedtls_pk_can_do(key->rsa, MBEDTLS_PK_RSA) == 0) {
|
||||
ssh_buffer_free(buffer);
|
||||
@@ -706,45 +702,12 @@ fail:
|
||||
return NULL;
|
||||
}
|
||||
|
||||
int pki_export_pubkey_rsa1(const ssh_key key, const char *host, char *rsa1,
|
||||
size_t rsa1_len)
|
||||
{
|
||||
char *e = NULL;
|
||||
char *n = NULL;
|
||||
int rsa_size = mbedtls_pk_get_bitlen(key->rsa);
|
||||
mbedtls_rsa_context *rsa = NULL;
|
||||
|
||||
if (!mbedtls_pk_can_do(key->rsa, MBEDTLS_PK_RSA)) {
|
||||
return SSH_ERROR;
|
||||
}
|
||||
|
||||
rsa = mbedtls_pk_rsa(*key->rsa);
|
||||
|
||||
n = bignum_bn2dec(&rsa->N);
|
||||
if (n == NULL) {
|
||||
return SSH_ERROR;
|
||||
}
|
||||
|
||||
e = bignum_bn2dec(&rsa->E);
|
||||
if (e == NULL) {
|
||||
return SSH_ERROR;
|
||||
}
|
||||
|
||||
snprintf(rsa1, rsa1_len, "%s %d %s %s\n",
|
||||
host, rsa_size << 3, e, n);
|
||||
|
||||
SAFE_FREE(e);
|
||||
SAFE_FREE(n);
|
||||
return SSH_OK;
|
||||
}
|
||||
|
||||
ssh_string pki_signature_to_blob(const ssh_signature sig)
|
||||
{
|
||||
ssh_string sig_blob = NULL;
|
||||
|
||||
switch(sig->type) {
|
||||
case SSH_KEYTYPE_RSA:
|
||||
case SSH_KEYTYPE_RSA1:
|
||||
sig_blob = ssh_string_copy(sig->rsa_sig);
|
||||
break;
|
||||
case SSH_KEYTYPE_ECDSA: {
|
||||
@@ -879,7 +842,6 @@ ssh_signature pki_signature_from_blob(const ssh_key pubkey, const ssh_string
|
||||
|
||||
switch(type) {
|
||||
case SSH_KEYTYPE_RSA:
|
||||
case SSH_KEYTYPE_RSA1:
|
||||
sig = pki_signature_from_rsa_blob(pubkey, sig_blob, sig);
|
||||
break;
|
||||
case SSH_KEYTYPE_ECDSA: {
|
||||
@@ -972,7 +934,6 @@ int pki_signature_verify(ssh_session session, const ssh_signature sig, const
|
||||
|
||||
switch (key->type) {
|
||||
case SSH_KEYTYPE_RSA:
|
||||
case SSH_KEYTYPE_RSA1:
|
||||
rc = mbedtls_pk_verify(key->rsa, MBEDTLS_MD_SHA1, hash, hlen,
|
||||
ssh_string_data(sig->rsa_sig),
|
||||
ssh_string_len(sig->rsa_sig));
|
||||
@@ -1061,7 +1022,6 @@ ssh_signature pki_do_sign(const ssh_key privkey, const unsigned char *hash,
|
||||
|
||||
switch(privkey->type) {
|
||||
case SSH_KEYTYPE_RSA:
|
||||
case SSH_KEYTYPE_RSA1:
|
||||
sig->rsa_sig = rsa_do_sign(hash, hlen, privkey->rsa);
|
||||
if (sig->rsa_sig == NULL) {
|
||||
ssh_signature_free(sig);
|
||||
@@ -1120,7 +1080,6 @@ ssh_signature pki_do_sign_sessionid(const ssh_key key, const unsigned char
|
||||
|
||||
switch (key->type) {
|
||||
case SSH_KEYTYPE_RSA:
|
||||
case SSH_KEYTYPE_RSA1:
|
||||
sig->rsa_sig = rsa_do_sign(hash, hlen, key->rsa);
|
||||
if (sig->rsa_sig == NULL) {
|
||||
ssh_signature_free(sig);
|
||||
|
211
src/server.c
211
src/server.c
@@ -248,15 +248,15 @@ int ssh_get_key_params(ssh_session session, ssh_key *privkey){
|
||||
*privkey = session->srv.dsa_key;
|
||||
break;
|
||||
case SSH_KEYTYPE_RSA:
|
||||
case SSH_KEYTYPE_RSA1:
|
||||
*privkey = session->srv.rsa_key;
|
||||
break;
|
||||
case SSH_KEYTYPE_ECDSA:
|
||||
*privkey = session->srv.ecdsa_key;
|
||||
break;
|
||||
case SSH_KEYTYPE_ED25519:
|
||||
*privkey = session->srv.ed25519_key;
|
||||
break;
|
||||
*privkey = session->srv.ed25519_key;
|
||||
break;
|
||||
case SSH_KEYTYPE_RSA1:
|
||||
case SSH_KEYTYPE_UNKNOWN:
|
||||
default:
|
||||
*privkey = NULL;
|
||||
@@ -383,94 +383,65 @@ static int dh_handshake_server(ssh_session session) {
|
||||
* connection.
|
||||
*/
|
||||
static void ssh_server_connection_callback(ssh_session session){
|
||||
int ssh1,ssh2;
|
||||
int rc;
|
||||
|
||||
switch(session->session_state){
|
||||
case SSH_SESSION_STATE_NONE:
|
||||
case SSH_SESSION_STATE_CONNECTING:
|
||||
case SSH_SESSION_STATE_SOCKET_CONNECTED:
|
||||
break;
|
||||
case SSH_SESSION_STATE_BANNER_RECEIVED:
|
||||
if (session->clientbanner == NULL) {
|
||||
goto error;
|
||||
}
|
||||
set_status(session, 0.4f);
|
||||
SSH_LOG(SSH_LOG_RARE,
|
||||
"SSH client banner: %s", session->clientbanner);
|
||||
switch(session->session_state){
|
||||
case SSH_SESSION_STATE_NONE:
|
||||
case SSH_SESSION_STATE_CONNECTING:
|
||||
case SSH_SESSION_STATE_SOCKET_CONNECTED:
|
||||
break;
|
||||
case SSH_SESSION_STATE_BANNER_RECEIVED:
|
||||
if (session->clientbanner == NULL) {
|
||||
goto error;
|
||||
}
|
||||
set_status(session, 0.4f);
|
||||
SSH_LOG(SSH_LOG_RARE,
|
||||
"SSH client banner: %s", session->clientbanner);
|
||||
|
||||
/* Here we analyze the different protocols the server allows. */
|
||||
if (ssh_analyze_banner(session, 1, &ssh1, &ssh2) < 0) {
|
||||
goto error;
|
||||
}
|
||||
/* Here we decide which version of the protocol to use. */
|
||||
if (ssh2 && session->opts.ssh2) {
|
||||
session->version = 2;
|
||||
} else if (ssh1 && session->opts.ssh1) {
|
||||
session->version = 1;
|
||||
} else if (ssh1 && !session->opts.ssh1) {
|
||||
#ifdef WITH_SSH1
|
||||
ssh_set_error(session, SSH_FATAL,
|
||||
"SSH-1 protocol not available (configure session to allow SSH-1)");
|
||||
goto error;
|
||||
#else
|
||||
ssh_set_error(session, SSH_FATAL,
|
||||
"SSH-1 protocol not available (libssh compiled without SSH-1 support)");
|
||||
goto error;
|
||||
#endif
|
||||
} else {
|
||||
ssh_set_error(session, SSH_FATAL,
|
||||
"No version of SSH protocol usable (banner: %s)",
|
||||
session->clientbanner);
|
||||
goto error;
|
||||
}
|
||||
/* from now, the packet layer is handling incoming packets */
|
||||
if(session->version==2)
|
||||
session->socket_callbacks.data=ssh_packet_socket_callback;
|
||||
#ifdef WITH_SSH1
|
||||
else
|
||||
session->socket_callbacks.data=ssh_packet_socket_callback1;
|
||||
#endif
|
||||
ssh_packet_set_default_callbacks(session);
|
||||
set_status(session, 0.5f);
|
||||
session->session_state=SSH_SESSION_STATE_INITIAL_KEX;
|
||||
if (ssh_send_kex(session, 1) < 0) {
|
||||
goto error;
|
||||
}
|
||||
break;
|
||||
case SSH_SESSION_STATE_INITIAL_KEX:
|
||||
/* TODO: This state should disappear in favor of get_key handle */
|
||||
#ifdef WITH_SSH1
|
||||
if(session->version==1){
|
||||
if (ssh_get_kex1(session) < 0)
|
||||
goto error;
|
||||
set_status(session,0.6f);
|
||||
session->connected = 1;
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
break;
|
||||
case SSH_SESSION_STATE_KEXINIT_RECEIVED:
|
||||
set_status(session,0.6f);
|
||||
if(session->next_crypto->server_kex.methods[0]==NULL){
|
||||
if(server_set_kex(session) == SSH_ERROR)
|
||||
goto error;
|
||||
/* We are in a rekeying, so we need to send the server kex */
|
||||
if(ssh_send_kex(session, 1) < 0)
|
||||
goto error;
|
||||
}
|
||||
ssh_list_kex(&session->next_crypto->client_kex); // log client kex
|
||||
if (ssh_kex_select_methods(session) < 0) {
|
||||
goto error;
|
||||
}
|
||||
/* Here we analyze the different protocols the server allows. */
|
||||
rc = ssh_analyze_banner(session, 1);
|
||||
if (rc < 0) {
|
||||
ssh_set_error(session, SSH_FATAL,
|
||||
"No version of SSH protocol usable (banner: %s)",
|
||||
session->clientbanner);
|
||||
goto error;
|
||||
}
|
||||
|
||||
/* from now, the packet layer is handling incoming packets */
|
||||
session->socket_callbacks.data=ssh_packet_socket_callback;
|
||||
|
||||
ssh_packet_set_default_callbacks(session);
|
||||
set_status(session, 0.5f);
|
||||
session->session_state=SSH_SESSION_STATE_INITIAL_KEX;
|
||||
if (ssh_send_kex(session, 1) < 0) {
|
||||
goto error;
|
||||
}
|
||||
break;
|
||||
case SSH_SESSION_STATE_INITIAL_KEX:
|
||||
/* TODO: This state should disappear in favor of get_key handle */
|
||||
break;
|
||||
case SSH_SESSION_STATE_KEXINIT_RECEIVED:
|
||||
set_status(session,0.6f);
|
||||
if(session->next_crypto->server_kex.methods[0]==NULL){
|
||||
if(server_set_kex(session) == SSH_ERROR)
|
||||
goto error;
|
||||
/* We are in a rekeying, so we need to send the server kex */
|
||||
if(ssh_send_kex(session, 1) < 0)
|
||||
goto error;
|
||||
}
|
||||
ssh_list_kex(&session->next_crypto->client_kex); // log client kex
|
||||
if (ssh_kex_select_methods(session) < 0) {
|
||||
goto error;
|
||||
}
|
||||
if (crypt_set_algorithms_server(session) == SSH_ERROR)
|
||||
goto error;
|
||||
set_status(session,0.8f);
|
||||
session->session_state=SSH_SESSION_STATE_DH;
|
||||
set_status(session,0.8f);
|
||||
session->session_state=SSH_SESSION_STATE_DH;
|
||||
break;
|
||||
case SSH_SESSION_STATE_DH:
|
||||
if(session->dh_handshake_state==DH_STATE_FINISHED){
|
||||
case SSH_SESSION_STATE_DH:
|
||||
if(session->dh_handshake_state==DH_STATE_FINISHED){
|
||||
if (ssh_generate_session_keys(session) < 0) {
|
||||
goto error;
|
||||
goto error;
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -478,51 +449,51 @@ static void ssh_server_connection_callback(ssh_session session){
|
||||
* current_crypto
|
||||
*/
|
||||
if (session->current_crypto) {
|
||||
crypto_free(session->current_crypto);
|
||||
crypto_free(session->current_crypto);
|
||||
}
|
||||
|
||||
/* FIXME TODO later, include a function to change keys */
|
||||
session->current_crypto = session->next_crypto;
|
||||
session->next_crypto = crypto_new();
|
||||
if (session->next_crypto == NULL) {
|
||||
goto error;
|
||||
goto error;
|
||||
}
|
||||
session->next_crypto->session_id = malloc(session->current_crypto->digest_len);
|
||||
if (session->next_crypto->session_id == NULL) {
|
||||
ssh_set_error_oom(session);
|
||||
goto error;
|
||||
}
|
||||
memcpy(session->next_crypto->session_id, session->current_crypto->session_id,
|
||||
session->current_crypto->digest_len);
|
||||
if (session->current_crypto->in_cipher->set_decrypt_key(session->current_crypto->in_cipher, session->current_crypto->decryptkey,
|
||||
session->current_crypto->decryptIV) < 0) {
|
||||
goto error;
|
||||
}
|
||||
if (session->current_crypto->out_cipher->set_encrypt_key(session->current_crypto->out_cipher, session->current_crypto->encryptkey,
|
||||
session->current_crypto->encryptIV) < 0) {
|
||||
goto error;
|
||||
}
|
||||
session->next_crypto->session_id = malloc(session->current_crypto->digest_len);
|
||||
if (session->next_crypto->session_id == NULL) {
|
||||
ssh_set_error_oom(session);
|
||||
goto error;
|
||||
}
|
||||
memcpy(session->next_crypto->session_id, session->current_crypto->session_id,
|
||||
session->current_crypto->digest_len);
|
||||
if (session->current_crypto->in_cipher->set_decrypt_key(session->current_crypto->in_cipher, session->current_crypto->decryptkey,
|
||||
session->current_crypto->decryptIV) < 0) {
|
||||
goto error;
|
||||
}
|
||||
if (session->current_crypto->out_cipher->set_encrypt_key(session->current_crypto->out_cipher, session->current_crypto->encryptkey,
|
||||
session->current_crypto->encryptIV) < 0) {
|
||||
goto error;
|
||||
}
|
||||
|
||||
set_status(session,1.0f);
|
||||
session->connected = 1;
|
||||
session->session_state=SSH_SESSION_STATE_AUTHENTICATING;
|
||||
if (session->flags & SSH_SESSION_FLAG_AUTHENTICATED)
|
||||
session->session_state = SSH_SESSION_STATE_AUTHENTICATED;
|
||||
}
|
||||
break;
|
||||
case SSH_SESSION_STATE_AUTHENTICATING:
|
||||
break;
|
||||
case SSH_SESSION_STATE_ERROR:
|
||||
goto error;
|
||||
default:
|
||||
ssh_set_error(session,SSH_FATAL,"Invalid state %d",session->session_state);
|
||||
}
|
||||
set_status(session,1.0f);
|
||||
session->connected = 1;
|
||||
session->session_state=SSH_SESSION_STATE_AUTHENTICATING;
|
||||
if (session->flags & SSH_SESSION_FLAG_AUTHENTICATED)
|
||||
session->session_state = SSH_SESSION_STATE_AUTHENTICATED;
|
||||
}
|
||||
break;
|
||||
case SSH_SESSION_STATE_AUTHENTICATING:
|
||||
break;
|
||||
case SSH_SESSION_STATE_ERROR:
|
||||
goto error;
|
||||
default:
|
||||
ssh_set_error(session,SSH_FATAL,"Invalid state %d",session->session_state);
|
||||
}
|
||||
|
||||
return;
|
||||
return;
|
||||
error:
|
||||
ssh_socket_close(session->socket);
|
||||
session->alive = 0;
|
||||
session->session_state=SSH_SESSION_STATE_ERROR;
|
||||
ssh_socket_close(session->socket);
|
||||
session->alive = 0;
|
||||
session->session_state=SSH_SESSION_STATE_ERROR;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@@ -31,9 +31,6 @@
|
||||
#include "libssh/crypto.h"
|
||||
#include "libssh/server.h"
|
||||
#include "libssh/socket.h"
|
||||
#ifdef WITH_SSH1
|
||||
#include "libssh/ssh1.h"
|
||||
#endif /* WITH_SSH1 */
|
||||
#include "libssh/ssh2.h"
|
||||
#include "libssh/agent.h"
|
||||
#include "libssh/packet.h"
|
||||
@@ -105,14 +102,8 @@ ssh_session ssh_new(void) {
|
||||
session->opts.StrictHostKeyChecking = 1;
|
||||
session->opts.port = 0;
|
||||
session->opts.fd = -1;
|
||||
session->opts.ssh2 = 1;
|
||||
session->opts.compressionlevel=7;
|
||||
session->opts.nodelay = 0;
|
||||
#ifdef WITH_SSH1
|
||||
session->opts.ssh1 = 1;
|
||||
#else
|
||||
session->opts.ssh1 = 0;
|
||||
#endif
|
||||
session->opts.flags = SSH_OPT_FLAG_PASSWORD_AUTH | SSH_OPT_FLAG_PUBKEY_AUTH |
|
||||
SSH_OPT_FLAG_KBDINT_AUTH | SSH_OPT_FLAG_GSSAPI_AUTH;
|
||||
session->opts.identity = ssh_list_new();
|
||||
@@ -807,14 +798,14 @@ const char *ssh_get_disconnect_message(ssh_session session) {
|
||||
*
|
||||
* @param session The ssh session to use.
|
||||
*
|
||||
* @return 1 or 2, for ssh1 or ssh2, < 0 on error.
|
||||
* @return The SSH version as integer, < 0 on error.
|
||||
*/
|
||||
int ssh_get_version(ssh_session session) {
|
||||
if (session == NULL) {
|
||||
return -1;
|
||||
}
|
||||
if (session == NULL) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
return session->version;
|
||||
return 2;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -845,11 +836,7 @@ void ssh_socket_exception_callback(int code, int errno_code, void *user){
|
||||
* @return SSH_OK on success, SSH_ERROR otherwise.
|
||||
*/
|
||||
int ssh_send_ignore (ssh_session session, const char *data) {
|
||||
#ifdef WITH_SSH1
|
||||
const int type = session->version == 1 ? SSH_MSG_IGNORE : SSH2_MSG_IGNORE;
|
||||
#else /* WITH_SSH1 */
|
||||
const int type = SSH2_MSG_IGNORE;
|
||||
#endif /* WITH_SSH1 */
|
||||
int rc;
|
||||
|
||||
if (ssh_socket_is_open(session->socket)) {
|
||||
@@ -887,22 +874,12 @@ int ssh_send_debug (ssh_session session, const char *message, int always_display
|
||||
int rc;
|
||||
|
||||
if (ssh_socket_is_open(session->socket)) {
|
||||
#ifdef WITH_SSH1
|
||||
if (session->version == 1) {
|
||||
rc = ssh_buffer_pack(session->out_buffer,
|
||||
"bs",
|
||||
SSH_MSG_DEBUG,
|
||||
message);
|
||||
} else
|
||||
#endif /* WITH_SSH1 */
|
||||
{
|
||||
rc = ssh_buffer_pack(session->out_buffer,
|
||||
"bbsd",
|
||||
SSH2_MSG_DEBUG,
|
||||
always_display != 0 ? 1 : 0,
|
||||
message,
|
||||
0); /* empty language tag */
|
||||
}
|
||||
rc = ssh_buffer_pack(session->out_buffer,
|
||||
"bbsd",
|
||||
SSH2_MSG_DEBUG,
|
||||
always_display != 0 ? 1 : 0,
|
||||
message,
|
||||
0); /* empty language tag */
|
||||
if (rc != SSH_OK) {
|
||||
ssh_set_error_oom(session);
|
||||
goto error;
|
||||
|
@@ -353,39 +353,9 @@ static int crypt_set_algorithms2(ssh_session session){
|
||||
return SSH_OK;
|
||||
}
|
||||
|
||||
static int crypt_set_algorithms1(ssh_session session, enum ssh_des_e des_type) {
|
||||
int i = 0;
|
||||
struct ssh_cipher_struct *ssh_ciphertab=ssh_get_ciphertab();
|
||||
|
||||
/* right now, we force 3des-cbc to be taken */
|
||||
while (ssh_ciphertab[i].name && strcmp(ssh_ciphertab[i].name,
|
||||
des_type == SSH_DES ? "des-cbc-ssh1" : "3des-cbc-ssh1")) {
|
||||
i++;
|
||||
}
|
||||
|
||||
if (ssh_ciphertab[i].name == NULL) {
|
||||
ssh_set_error(session, SSH_FATAL, "cipher 3des-cbc-ssh1 or des-cbc-ssh1 not found!");
|
||||
return SSH_ERROR;
|
||||
}
|
||||
|
||||
session->next_crypto->out_cipher = cipher_new(i);
|
||||
if (session->next_crypto->out_cipher == NULL) {
|
||||
ssh_set_error_oom(session);
|
||||
return SSH_ERROR;
|
||||
}
|
||||
|
||||
session->next_crypto->in_cipher = cipher_new(i);
|
||||
if (session->next_crypto->in_cipher == NULL) {
|
||||
ssh_set_error_oom(session);
|
||||
return SSH_ERROR;
|
||||
}
|
||||
|
||||
return SSH_OK;
|
||||
}
|
||||
|
||||
int crypt_set_algorithms(ssh_session session, enum ssh_des_e des_type) {
|
||||
return (session->version == 1) ? crypt_set_algorithms1(session, des_type) :
|
||||
crypt_set_algorithms2(session);
|
||||
int crypt_set_algorithms_client(ssh_session session)
|
||||
{
|
||||
return crypt_set_algorithms2(session);
|
||||
}
|
||||
|
||||
#ifdef WITH_SERVER
|
||||
|
@@ -13,7 +13,7 @@ set(CTEST_CMAKE_GENERATOR "Unix Makefiles")
|
||||
set(CTEST_BUILD_CONFIGURATION "Debug")
|
||||
|
||||
## The build options for the project
|
||||
set(CTEST_BUILD_OPTIONS "-DUNIT_TESTING=ON -DWITH_SSH1=ON -WITH_SFTP=ON -DWITH_SERVER=ON -DWITH_ZLIB=ON -DWITH_PCAP=ON -DDEBUG_CRYPTO=ON -DWITH_GCRYPT=OFF")
|
||||
set(CTEST_BUILD_OPTIONS "-DUNIT_TESTING=ON -WITH_SFTP=ON -DWITH_SERVER=ON -DWITH_ZLIB=ON -DWITH_PCAP=ON -DDEBUG_CRYPTO=ON -DWITH_GCRYPT=OFF")
|
||||
|
||||
#set(CTEST_CUSTOM_MEMCHECK_IGNORE torture_rand)
|
||||
|
||||
|
@@ -218,16 +218,12 @@ static void torture_timeout_update(void **state){
|
||||
|
||||
static void torture_ssh_analyze_banner(void **state) {
|
||||
int rc = 0;
|
||||
int ssh1 = 0;
|
||||
int ssh2 = 0;
|
||||
ssh_session session = NULL;
|
||||
(void) state;
|
||||
|
||||
#define reset_banner_test() \
|
||||
do { \
|
||||
rc = 0; \
|
||||
ssh1 = 0; \
|
||||
ssh2 = 0; \
|
||||
ssh_free(session); \
|
||||
session = ssh_new(); \
|
||||
assert_non_null(session); \
|
||||
@@ -235,7 +231,7 @@ static void torture_ssh_analyze_banner(void **state) {
|
||||
|
||||
#define assert_banner_rejected(is_server) \
|
||||
do { \
|
||||
rc = ssh_analyze_banner(session, is_server, &ssh1, &ssh2); \
|
||||
rc = ssh_analyze_banner(session, is_server); \
|
||||
assert_int_not_equal(0, rc); \
|
||||
} while (0);
|
||||
|
||||
@@ -257,29 +253,27 @@ static void torture_ssh_analyze_banner(void **state) {
|
||||
SAFE_FREE(session->serverbanner); \
|
||||
} while (0)
|
||||
|
||||
#define assert_banner_accepted(is_server, expected_ssh1, expected_ssh2) \
|
||||
#define assert_banner_accepted(is_server) \
|
||||
do { \
|
||||
rc = ssh_analyze_banner(session, is_server, &ssh1, &ssh2); \
|
||||
rc = ssh_analyze_banner(session, is_server); \
|
||||
assert_int_equal(0, rc); \
|
||||
assert_int_equal(expected_ssh1, ssh1); \
|
||||
assert_int_equal(expected_ssh2, ssh2); \
|
||||
} while (0)
|
||||
|
||||
#define assert_client_banner_accepted(banner, e1, e2) \
|
||||
#define assert_client_banner_accepted(banner) \
|
||||
do { \
|
||||
reset_banner_test(); \
|
||||
session->clientbanner = strdup(banner); \
|
||||
assert_non_null(session->clientbanner); \
|
||||
assert_banner_accepted(1 /*server*/, e1, e2); \
|
||||
assert_banner_accepted(1 /*server*/); \
|
||||
SAFE_FREE(session->clientbanner); \
|
||||
} while (0)
|
||||
|
||||
#define assert_server_banner_accepted(banner, e1, e2) \
|
||||
#define assert_server_banner_accepted(banner) \
|
||||
do { \
|
||||
reset_banner_test(); \
|
||||
session->serverbanner = strdup(banner); \
|
||||
assert_non_null(session->serverbanner); \
|
||||
assert_banner_accepted(0 /*client*/, e1, e2); \
|
||||
assert_banner_accepted(0 /*client*/); \
|
||||
SAFE_FREE(session->serverbanner); \
|
||||
} while (0)
|
||||
|
||||
@@ -298,60 +292,60 @@ static void torture_ssh_analyze_banner(void **state) {
|
||||
assert_server_banner_rejected("abc-2.0");
|
||||
|
||||
/* SSH v1 */
|
||||
assert_client_banner_accepted("SSH-1.0", 1, 0);
|
||||
assert_server_banner_accepted("SSH-1.0", 1, 0);
|
||||
assert_client_banner_rejected("SSH-1.0");
|
||||
assert_server_banner_rejected("SSH-1.0");
|
||||
|
||||
/* SSH v1.9 gets counted as both v1 and v2 */
|
||||
assert_client_banner_accepted("SSH-1.9", 1, 1);
|
||||
assert_server_banner_accepted("SSH-1.9", 1, 1);
|
||||
assert_client_banner_accepted("SSH-1.9");
|
||||
assert_server_banner_accepted("SSH-1.9");
|
||||
|
||||
/* SSH v2 */
|
||||
assert_client_banner_accepted("SSH-2.0", 0, 1);
|
||||
assert_server_banner_accepted("SSH-2.0", 0, 1);
|
||||
assert_client_banner_accepted("SSH-2.0");
|
||||
assert_server_banner_accepted("SSH-2.0");
|
||||
|
||||
/* OpenSSH banners: too short to extract major and minor versions */
|
||||
assert_client_banner_accepted("SSH-2.0-OpenSSH", 0, 1);
|
||||
assert_client_banner_accepted("SSH-2.0-OpenSSH");
|
||||
assert_int_equal(0, session->openssh);
|
||||
assert_server_banner_accepted("SSH-2.0-OpenSSH", 0, 1);
|
||||
assert_server_banner_accepted("SSH-2.0-OpenSSH");
|
||||
assert_int_equal(0, session->openssh);
|
||||
|
||||
/* OpenSSH banners: big enough to extract major and minor versions */
|
||||
assert_client_banner_accepted("SSH-2.0-OpenSSH_5.9p1", 0, 1);
|
||||
assert_client_banner_accepted("SSH-2.0-OpenSSH_5.9p1");
|
||||
assert_int_equal(SSH_VERSION_INT(5, 9, 0), session->openssh);
|
||||
assert_server_banner_accepted("SSH-2.0-OpenSSH_5.9p1", 0, 1);
|
||||
assert_server_banner_accepted("SSH-2.0-OpenSSH_5.9p1");
|
||||
assert_int_equal(SSH_VERSION_INT(5, 9, 0), session->openssh);
|
||||
|
||||
assert_client_banner_accepted("SSH-2.0-OpenSSH_1.99", 0, 1);
|
||||
assert_client_banner_accepted("SSH-2.0-OpenSSH_1.99");
|
||||
assert_int_equal(SSH_VERSION_INT(1, 99, 0), session->openssh);
|
||||
assert_server_banner_accepted("SSH-2.0-OpenSSH_1.99", 0, 1);
|
||||
assert_server_banner_accepted("SSH-2.0-OpenSSH_1.99");
|
||||
assert_int_equal(SSH_VERSION_INT(1, 99, 0), session->openssh);
|
||||
|
||||
/* OpenSSH banners: major, minor version limits result in zero */
|
||||
assert_client_banner_accepted("SSH-2.0-OpenSSH_0.99p1", 0, 1);
|
||||
assert_client_banner_accepted("SSH-2.0-OpenSSH_0.99p1");
|
||||
assert_int_equal(0, session->openssh);
|
||||
assert_server_banner_accepted("SSH-2.0-OpenSSH_0.99p1", 0, 1);
|
||||
assert_server_banner_accepted("SSH-2.0-OpenSSH_0.99p1");
|
||||
assert_int_equal(0, session->openssh);
|
||||
assert_client_banner_accepted("SSH-2.0-OpenSSH_1.101p1", 0, 1);
|
||||
assert_client_banner_accepted("SSH-2.0-OpenSSH_1.101p1");
|
||||
assert_int_equal(0, session->openssh);
|
||||
assert_server_banner_accepted("SSH-2.0-OpenSSH_1.101p1", 0, 1);
|
||||
assert_server_banner_accepted("SSH-2.0-OpenSSH_1.101p1");
|
||||
assert_int_equal(0, session->openssh);
|
||||
|
||||
/* OpenSSH banners: bogus major results in zero */
|
||||
assert_client_banner_accepted("SSH-2.0-OpenSSH_X.9p1", 0, 1);
|
||||
assert_client_banner_accepted("SSH-2.0-OpenSSH_X.9p1");
|
||||
assert_int_equal(0, session->openssh);
|
||||
assert_server_banner_accepted("SSH-2.0-OpenSSH_X.9p1", 0, 1);
|
||||
assert_server_banner_accepted("SSH-2.0-OpenSSH_X.9p1");
|
||||
assert_int_equal(0, session->openssh);
|
||||
|
||||
/* OpenSSH banners: bogus minor results in zero */
|
||||
assert_server_banner_accepted("SSH-2.0-OpenSSH_5.Yp1", 0, 1);
|
||||
assert_server_banner_accepted("SSH-2.0-OpenSSH_5.Yp1");
|
||||
assert_int_equal(0, session->openssh);
|
||||
assert_client_banner_accepted("SSH-2.0-OpenSSH_5.Yp1", 0, 1);
|
||||
assert_client_banner_accepted("SSH-2.0-OpenSSH_5.Yp1");
|
||||
assert_int_equal(0, session->openssh);
|
||||
|
||||
/* OpenSSH banners: ssh-keyscan(1) */
|
||||
assert_client_banner_accepted("SSH-2.0-OpenSSH-keyscan", 0, 1);
|
||||
assert_client_banner_accepted("SSH-2.0-OpenSSH-keyscan");
|
||||
assert_int_equal(0, session->openssh);
|
||||
assert_server_banner_accepted("SSH-2.0-OpenSSH-keyscan", 0, 1);
|
||||
assert_server_banner_accepted("SSH-2.0-OpenSSH-keyscan");
|
||||
assert_int_equal(0, session->openssh);
|
||||
|
||||
ssh_free(session);
|
||||
|
@@ -69,7 +69,6 @@ static void torture_packet(const char *cipher,
|
||||
rc = socketpair(AF_UNIX, SOCK_STREAM, 0, sockets);
|
||||
assert_int_equal(rc, 0);
|
||||
|
||||
session->version = 2;
|
||||
crypto->kex_methods[SSH_KEX] = strdup("curve25519-sha256@libssh.org");
|
||||
crypto->kex_methods[SSH_HOSTKEYS] = strdup("ssh-rsa");
|
||||
crypto->kex_methods[SSH_CRYPT_C_S] = strdup(cipher);
|
||||
@@ -80,7 +79,7 @@ static void torture_packet(const char *cipher,
|
||||
crypto->kex_methods[SSH_COMP_S_C] = strdup("none");
|
||||
crypto->kex_methods[SSH_LANG_C_S] = strdup("none");
|
||||
crypto->kex_methods[SSH_LANG_S_C] = strdup("none");
|
||||
rc = crypt_set_algorithms(session, 0);
|
||||
rc = crypt_set_algorithms_client(session);
|
||||
assert_int_equal(rc, SSH_OK);
|
||||
session->current_crypto = session->next_crypto;
|
||||
session->next_crypto = crypto_new();
|
||||
|
@@ -244,8 +244,7 @@ static void torture_pki_rsa_publickey_base64(void **state)
|
||||
*p = '\0';
|
||||
|
||||
type = ssh_key_type_from_name(q);
|
||||
assert_true(((type == SSH_KEYTYPE_RSA) ||
|
||||
(type == SSH_KEYTYPE_RSA1)));
|
||||
assert_true(type == SSH_KEYTYPE_RSA);
|
||||
|
||||
q = ++p;
|
||||
while (*p != ' ') p++;
|
||||
@@ -393,50 +392,6 @@ static void torture_pki_rsa_generate_key(void **state)
|
||||
ssh_free(session);
|
||||
}
|
||||
|
||||
static void torture_pki_rsa_generate_key1(void **state)
|
||||
{
|
||||
int rc;
|
||||
ssh_key key;
|
||||
ssh_signature sign;
|
||||
ssh_session session=ssh_new();
|
||||
(void) state;
|
||||
|
||||
rc = ssh_pki_generate(SSH_KEYTYPE_RSA1, 1024, &key);
|
||||
assert_true(rc == SSH_OK);
|
||||
assert_true(key != NULL);
|
||||
sign = pki_do_sign(key, RSA_HASH, 20);
|
||||
assert_true(sign != NULL);
|
||||
rc = pki_signature_verify(session,sign,key,RSA_HASH,20);
|
||||
assert_true(rc == SSH_OK);
|
||||
ssh_signature_free(sign);
|
||||
ssh_key_free(key);
|
||||
key=NULL;
|
||||
|
||||
rc = ssh_pki_generate(SSH_KEYTYPE_RSA1, 2048, &key);
|
||||
assert_true(rc == SSH_OK);
|
||||
assert_true(key != NULL);
|
||||
sign = pki_do_sign(key, RSA_HASH, 20);
|
||||
assert_true(sign != NULL);
|
||||
rc = pki_signature_verify(session,sign,key,RSA_HASH,20);
|
||||
assert_true(rc == SSH_OK);
|
||||
ssh_signature_free(sign);
|
||||
ssh_key_free(key);
|
||||
key=NULL;
|
||||
|
||||
rc = ssh_pki_generate(SSH_KEYTYPE_RSA1, 4096, &key);
|
||||
assert_true(rc == SSH_OK);
|
||||
assert_true(key != NULL);
|
||||
sign = pki_do_sign(key, RSA_HASH, 20);
|
||||
assert_true(sign != NULL);
|
||||
rc = pki_signature_verify(session,sign,key,RSA_HASH,20);
|
||||
assert_true(rc == SSH_OK);
|
||||
ssh_signature_free(sign);
|
||||
ssh_key_free(key);
|
||||
key=NULL;
|
||||
|
||||
ssh_free(session);
|
||||
}
|
||||
|
||||
#ifdef HAVE_LIBCRYPTO
|
||||
static void torture_pki_rsa_write_privkey(void **state)
|
||||
{
|
||||
@@ -595,7 +550,6 @@ int torture_run_tests(void) {
|
||||
setup_rsa_key,
|
||||
teardown),
|
||||
cmocka_unit_test(torture_pki_rsa_generate_key),
|
||||
cmocka_unit_test(torture_pki_rsa_generate_key1),
|
||||
#ifdef HAVE_LIBCRYPTO
|
||||
cmocka_unit_test_setup_teardown(torture_pki_rsa_write_privkey,
|
||||
setup_rsa_key,
|
||||
|
Reference in New Issue
Block a user