diff options
Diffstat (limited to 'libssh/kex.c')
-rw-r--r-- | libssh/kex.c | 835 |
1 files changed, 0 insertions, 835 deletions
diff --git a/libssh/kex.c b/libssh/kex.c deleted file mode 100644 index d57273ec..00000000 --- a/libssh/kex.c +++ /dev/null @@ -1,835 +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" - -#include <string.h> -#include <stdlib.h> -#include <stdio.h> - -#ifndef _WIN32 -#include <arpa/inet.h> -#endif - -#include "libssh/priv.h" -#include "libssh/ssh2.h" -#include "libssh/ssh1.h" -#include "libssh/buffer.h" -#include "libssh/packet.h" -#include "libssh/session.h" -#include "libssh/wrapper.h" -#include "libssh/keys.h" -#include "libssh/dh.h" -#include "libssh/kex.h" -#include "libssh/string.h" - -#ifdef HAVE_LIBGCRYPT -#define BLOWFISH "blowfish-cbc," -#define AES "aes256-ctr,aes192-ctr,aes128-ctr,aes256-cbc,aes192-cbc,aes128-cbc," -#define DES "3des-cbc" -#elif defined HAVE_LIBCRYPTO -#ifdef HAVE_OPENSSL_BLOWFISH_H -#define BLOWFISH "blowfish-cbc," -#else -#define BLOWFISH "" -#endif -#ifdef HAVE_OPENSSL_AES_H -#ifdef BROKEN_AES_CTR -#define AES "aes256-cbc,aes192-cbc,aes128-cbc," -#else -#define AES "aes256-ctr,aes192-ctr,aes128-ctr,aes256-cbc,aes192-cbc,aes128-cbc," -#endif /* BROKEN_AES_CTR */ -#else -#define AES "" -#endif - -#define DES "3des-cbc" -#endif - -#if defined(HAVE_LIBZ) && defined(WITH_LIBZ) -#define ZLIB "none,zlib,zlib@openssh.org" -#else -#define ZLIB "none" -#endif - -const char *default_methods[] = { - "diffie-hellman-group1-sha1", - "ssh-rsa,ssh-dss", - AES BLOWFISH DES, - AES BLOWFISH DES, - "hmac-sha1", - "hmac-sha1", - "none", - "none", - "", - "", - NULL -}; - -const char *supported_methods[] = { - "diffie-hellman-group1-sha1", - "ssh-rsa,ssh-dss", - AES BLOWFISH DES, - AES BLOWFISH DES, - "hmac-sha1", - "hmac-sha1", - ZLIB, - ZLIB, - "", - "", - NULL -}; - -/* descriptions of the key exchange packet */ -const char *ssh_kex_nums[] = { - "kex algos", - "server host key algo", - "encryption client->server", - "encryption server->client", - "mac algo client->server", - "mac algo server->client", - "compression algo client->server", - "compression algo server->client", - "languages client->server", - "languages server->client", - NULL -}; - -/* tokenize will return a token of strings delimited by ",". the first element has to be freed */ -static char **tokenize(const char *chain){ - char **tokens; - int n=1; - int i=0; - char *tmp; - char *ptr; - - tmp = strdup(chain); - if (tmp == NULL) { - return NULL; - } - ptr = tmp; - while(*ptr){ - if(*ptr==','){ - n++; - *ptr=0; - } - ptr++; - } - /* now n contains the number of tokens, the first possibly empty if the list was empty too e.g. "" */ - tokens=malloc(sizeof(char *) * (n+1) ); /* +1 for the null */ - if (tokens == NULL) { - SAFE_FREE(tmp); - return NULL; - } - ptr=tmp; - for(i=0;i<n;i++){ - tokens[i]=ptr; - while(*ptr) - ptr++; // find a zero - ptr++; // then go one step further - } - tokens[i]=NULL; - return tokens; -} - -/* same as tokenize(), but with spaces instead of ',' */ -/* TODO FIXME rewrite me! */ -char **space_tokenize(const char *chain){ - char **tokens; - int n=1; - int i=0; - char *tmp; - char *ptr; - - tmp = strdup(chain); - if (tmp == NULL) { - return NULL; - } - ptr = tmp; - - while(*ptr==' ') - ++ptr; /* skip initial spaces */ - while(*ptr){ - if(*ptr==' '){ - n++; /* count one token per word */ - *ptr=0; - while(*(ptr+1)==' '){ /* don't count if the tokens have more than 2 spaces */ - *(ptr++)=0; - } - } - ptr++; - } - /* now n contains the number of tokens, the first possibly empty if the list was empty too e.g. "" */ - tokens = malloc(sizeof(char *) * (n + 1)); /* +1 for the null */ - if (tokens == NULL) { - SAFE_FREE(tmp); - return NULL; - } - ptr=tmp; /* we don't pass the initial spaces because the "tmp" pointer is needed by the caller */ - /* function to free the tokens. */ - for(i=0;i<n;i++){ - tokens[i]=ptr; - if(i!=n-1){ - while(*ptr) - ptr++; // find a zero - while(!*(ptr+1)) - ++ptr; /* if the zero is followed by other zeros, go through them */ - ptr++; // then go one step further - } - } - tokens[i]=NULL; - return tokens; -} - -/* find_matching gets 2 parameters : a list of available objects (available_d), separated by colons,*/ -/* and a list of preferred objects (preferred_d) */ -/* it will return a strduped pointer on the first preferred object found in the available objects list */ - -char *ssh_find_matching(const char *available_d, const char *preferred_d){ - char ** tok_available, **tok_preferred; - int i_avail, i_pref; - char *ret; - - if ((available_d == NULL) || (preferred_d == NULL)) { - return NULL; /* don't deal with null args */ - } - - tok_available = tokenize(available_d); - if (tok_available == NULL) { - return NULL; - } - - tok_preferred = tokenize(preferred_d); - if (tok_preferred == NULL) { - SAFE_FREE(tok_available[0]); - SAFE_FREE(tok_available); - return NULL; - } - - for(i_pref=0; tok_preferred[i_pref] ; ++i_pref){ - for(i_avail=0; tok_available[i_avail]; ++i_avail){ - if(!strcmp(tok_available[i_avail],tok_preferred[i_pref])){ - /* match */ - ret=strdup(tok_available[i_avail]); - /* free the tokens */ - SAFE_FREE(tok_available[0]); - SAFE_FREE(tok_preferred[0]); - SAFE_FREE(tok_available); - SAFE_FREE(tok_preferred); - return ret; - } - } - } - SAFE_FREE(tok_available[0]); - SAFE_FREE(tok_preferred[0]); - SAFE_FREE(tok_available); - SAFE_FREE(tok_preferred); - return NULL; -} - -SSH_PACKET_CALLBACK(ssh_packet_kexinit){ - int server_kex=session->server; - ssh_string str = NULL; - char *strings[10]; - int i; - - enter_function(); - (void)type; - (void)user; - if(session->session_state != SSH_SESSION_STATE_INITIAL_KEX){ - ssh_set_error(session,SSH_FATAL,"SSH_KEXINIT received in wrong state"); - goto error; - } - if (server_kex) { - if (buffer_get_data(packet,session->client_kex.cookie,16) != 16) { - ssh_set_error(session, SSH_FATAL, "ssh_packet_kexinit: no cookie in packet"); - goto error; - } - - if (hashbufin_add_cookie(session, session->client_kex.cookie) < 0) { - ssh_set_error(session, SSH_FATAL, "ssh_packet_kexinit: adding cookie failed"); - goto error; - } - } else { - if (buffer_get_data(packet,session->server_kex.cookie,16) != 16) { - ssh_set_error(session, SSH_FATAL, "ssh_packet_kexinit: no cookie in packet"); - goto error; - } - - if (hashbufin_add_cookie(session, session->server_kex.cookie) < 0) { - ssh_set_error(session, SSH_FATAL, "ssh_packet_kexinit: adding cookie failed"); - goto error; - } - } - - memset(strings, 0, sizeof(char *) * 10); - - for (i = 0; i < 10; i++) { - str = buffer_get_ssh_string(packet); - if (str == NULL) { - break; - } - - if (buffer_add_ssh_string(session->in_hashbuf, str) < 0) { - goto error; - } - - strings[i] = ssh_string_to_char(str); - if (strings[i] == NULL) { - goto error; - } - ssh_string_free(str); - str = NULL; - } - - /* copy the server kex info into an array of strings */ - if (server_kex) { - session->client_kex.methods = malloc(10 * sizeof(char **)); - if (session->client_kex.methods == NULL) { - leave_function(); - return -1; - } - - for (i = 0; i < 10; i++) { - session->client_kex.methods[i] = strings[i]; - } - } else { /* client */ - session->server_kex.methods = malloc(10 * sizeof(char **)); - if (session->server_kex.methods == NULL) { - leave_function(); - return -1; - } - - for (i = 0; i < 10; i++) { - session->server_kex.methods[i] = strings[i]; - } - } - - leave_function(); - session->session_state=SSH_SESSION_STATE_KEXINIT_RECEIVED; - session->ssh_connection_callback(session); - return SSH_PACKET_USED; -error: - ssh_string_free(str); - for (i = 0; i < 10; i++) { - SAFE_FREE(strings[i]); - } - - session->session_state = SSH_SESSION_STATE_ERROR; - leave_function(); - return SSH_PACKET_USED; -} - -void ssh_list_kex(ssh_session session, KEX *kex) { - int i = 0; - -#ifdef DEBUG_CRYPTO - ssh_print_hexa("session cookie", kex->cookie, 16); -#endif - if(kex->methods==NULL){ - ssh_log(session, SSH_LOG_RARE,"kex->methods is NULL"); - return; - } - for(i = 0; i < 10; i++) { - ssh_log(session, SSH_LOG_FUNCTIONS, "%s: %s", - ssh_kex_nums[i], kex->methods[i]); - } -} - -/* set_kex basicaly look at the option structure of the session and set the output kex message */ -/* it must be aware of the server kex message */ -/* it can fail if option is null, not any user specified kex method matches the server one, if not any default kex matches */ - -int set_kex(ssh_session session){ - KEX *server = &session->server_kex; - KEX *client=&session->client_kex; - int i; - const char *wanted; - enter_function(); - ssh_get_random(client->cookie,16,0); - client->methods=malloc(10 * sizeof(char **)); - if (client->methods == NULL) { - ssh_set_error(session, SSH_FATAL, "No space left"); - leave_function(); - return -1; - } - memset(client->methods,0,10*sizeof(char **)); - for (i=0;i<10;i++){ - if(!(wanted=session->wanted_methods[i])) - wanted=default_methods[i]; - client->methods[i]=ssh_find_matching(server->methods[i],wanted); - if(!client->methods[i] && i < SSH_LANG_C_S){ - ssh_set_error(session,SSH_FATAL,"kex error : did not find one of algos %s in list %s for %s", - wanted,server->methods[i],ssh_kex_nums[i]); - leave_function(); - return -1; - } else { - if ((i >= SSH_LANG_C_S) && (client->methods[i] == NULL)) { - /* we can safely do that for languages */ - client->methods[i] = strdup(""); - if (client->methods[i] == NULL) { - return -1; - } - } - } - } - leave_function(); - return 0; -} - -/* this function only sends the predefined set of kex methods */ -int ssh_send_kex(ssh_session session, int server_kex) { - KEX *kex = (server_kex ? &session->server_kex : &session->client_kex); - ssh_string str = NULL; - int i; - - enter_function(); - - if (buffer_add_u8(session->out_buffer, SSH2_MSG_KEXINIT) < 0) { - goto error; - } - if (buffer_add_data(session->out_buffer, kex->cookie, 16) < 0) { - goto error; - } - - if (hashbufout_add_cookie(session) < 0) { - goto error; - } - - ssh_list_kex(session, kex); - - for (i = 0; i < 10; i++) { - str = ssh_string_from_char(kex->methods[i]); - if (str == NULL) { - goto error; - } - - if (buffer_add_ssh_string(session->out_hashbuf, str) < 0) { - goto error; - } - if (buffer_add_ssh_string(session->out_buffer, str) < 0) { - goto error; - } - ssh_string_free(str); - } - - if (buffer_add_u8(session->out_buffer, 0) < 0) { - goto error; - } - if (buffer_add_u32(session->out_buffer, 0) < 0) { - goto error; - } - - if (packet_send(session) == SSH_ERROR) { - leave_function(); - return -1; - } - - leave_function(); - return 0; -error: - buffer_reinit(session->out_buffer); - buffer_reinit(session->out_hashbuf); - ssh_string_free(str); - - leave_function(); - return -1; -} - -/* returns 1 if at least one of the name algos is in the default algorithms table */ -int verify_existing_algo(int algo, const char *name){ - char *ptr; - if(algo>9 || algo <0) - return -1; - ptr=ssh_find_matching(supported_methods[algo],name); - if(ptr){ - free(ptr); - return 1; - } - return 0; -} - -#ifdef WITH_SSH1 - -/* 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(); - rsa = ssh_string_from_char("ssh-rsa1"); - - if (buffer_add_ssh_string(buffer, rsa) < 0) { - goto error; - } - if (buffer_add_ssh_string(buffer, e) < 0) { - goto error; - } - if (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_begin(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->server_kex.cookie,8); - 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 - n1=k1->rsa_pub->n; - n2=k2->rsa_pub->n; -#endif - if(bignum_cmp(n1,n2)<0) - res=1; - else - res=0; -#ifdef HAVE_LIBGCRYPT - bignum_free(n1); - bignum_free(n2); -#endif - return res; - -} - -#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; - - /* 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); - -#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(session, 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; -} - -/* SSH-1 functions */ -/* 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; - enter_function(); - (void)type; - (void)user; - ssh_log(session, 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 (buffer_get_data(packet, session->server_kex.cookie, 8) != 8) { - ssh_set_error(session, SSH_FATAL, "Can't get cookie in buffer"); - goto error; - } - - buffer_get_u32(packet, &server_bits); - server_exp = buffer_get_mpint(packet); - if (server_exp == NULL) { - goto error; - } - server_mod = buffer_get_mpint(packet); - if (server_mod == NULL) { - goto error; - } - buffer_get_u32(packet, &host_bits); - host_exp = buffer_get_mpint(packet); - if (host_exp == NULL) { - goto error; - } - host_mod = buffer_get_mpint(packet); - if (host_mod == NULL) { - goto error; - } - buffer_get_u32(packet, &protocol_flags); - buffer_get_u32(packet, &supported_ciphers_mask); - ko = buffer_get_u32(packet, &supported_authentications_mask); - - if ((ko != sizeof(uint32_t)) || !host_mod || !host_exp - || !server_mod || !server_exp) { - ssh_log(session, 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(session, 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 (serverkey == 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; - } - - session->next_crypto->server_pubkey = ssh_string_copy(hostkey); - if (session->next_crypto->server_pubkey == NULL) { - goto error; - } - session->next_crypto->server_pubkey_type = "ssh-rsa1"; - - /* now, we must choose an encryption algo */ - /* hardcode 3des */ - if (!(supported_ciphers_mask & (1 << SSH_CIPHER_3DES))) { - ssh_set_error(session, SSH_FATAL, "Remote server doesn't accept 3DES"); - goto error; - } - ssh_log(session, SSH_LOG_PROTOCOL, "Sending SSH_CMSG_SESSION_KEY"); - - if (buffer_add_u8(session->out_buffer, SSH_CMSG_SESSION_KEY) < 0) { - goto error; - } - if (buffer_add_u8(session->out_buffer, SSH_CIPHER_3DES) < 0) { - goto error; - } - if (buffer_add_data(session->out_buffer, session->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(session, SSH_LOG_PROTOCOL, "%d bits, %zu bytes encrypted session", - bits, ssh_string_len(enc_session)); - bits = htons(bits); - /* the encrypted mpint */ - if (buffer_add_data(session->out_buffer, &bits, sizeof(uint16_t)) < 0) { - goto error; - } - if (buffer_add_data(session->out_buffer, ssh_string_data(enc_session), - ssh_string_len(enc_session)) < 0) { - goto error; - } - /* the protocol flags */ - if (buffer_add_u32(session->out_buffer, 0) < 0) { - goto error; - } - session->session_state=SSH_SESSION_STATE_KEXINIT_RECEIVED; - if (packet_send(session) == SSH_ERROR) { - goto error; - } - - /* we can set encryption */ - if (crypt_set_algorithms(session)) { - 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); - - leave_function(); - return SSH_PACKET_USED; -} - -int ssh_get_kex1(ssh_session session) { - int ret=SSH_ERROR; - enter_function(); - ssh_log(session, 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,-1); - } - if(session->session_state==SSH_SESSION_STATE_ERROR) - goto error; - ssh_log(session, 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,-1); - } - if(session->session_state==SSH_SESSION_STATE_ERROR) - goto error; - ssh_log(session, SSH_LOG_PROTOCOL, "received SSH_SMSG_SUCCESS\n"); - ret=SSH_OK; -error: - leave_function(); - return ret; -} - -#endif /* WITH_SSH1 */ -/* vim: set ts=2 sw=2 et cindent: */ |