mirror of
https://git.libssh.org/projects/libssh.git
synced 2026-02-09 09:54:25 +09:00
Improve ssh_write_knownhost.
git-svn-id: svn+ssh://svn.berlios.de/svnroot/repos/libssh/trunk@635 7dcaeef0-15fb-0310-b436-a5af3365683c
This commit is contained in:
@@ -1412,72 +1412,148 @@ int ssh_is_server_known(SSH_SESSION *session) {
|
|||||||
* \param session ssh session
|
* \param session ssh session
|
||||||
* \return 0 on success, -1 on error
|
* \return 0 on success, -1 on error
|
||||||
*/
|
*/
|
||||||
int ssh_write_knownhost(SSH_SESSION *session){
|
int ssh_write_knownhost(SSH_SESSION *session) {
|
||||||
unsigned char *pubkey_64;
|
STRING *pubkey = session->current_crypto->server_pubkey;
|
||||||
STRING *pubkey=session->current_crypto->server_pubkey;
|
unsigned char *pubkey_64;
|
||||||
char buffer[4096];
|
char buffer[4096] = {0};
|
||||||
size_t len = 0;
|
FILE *file;
|
||||||
FILE *file;
|
size_t len = 0;
|
||||||
ssh_options_default_known_hosts_file(session->options);
|
|
||||||
if(!session->options->host){
|
if (ssh_options_default_known_hosts_file(session->options) < 0) {
|
||||||
ssh_set_error(session,SSH_FATAL,"Cannot write host in known hosts if the hostname is unknown");
|
ssh_set_error(session, SSH_FATAL, "Cannot find known_hosts file.");
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
/* a = append only */
|
|
||||||
file=fopen(session->options->known_hosts_file,"a");
|
if (session->options->host == NULL) {
|
||||||
if(!file){
|
ssh_set_error(session, SSH_FATAL,
|
||||||
ssh_set_error(session,SSH_FATAL,"Opening known host file %s for appending : %s",
|
"Cannot write host in known hosts if the hostname is unknown");
|
||||||
session->options->known_hosts_file,strerror(errno));
|
return -1;
|
||||||
return -1;
|
}
|
||||||
}
|
|
||||||
if (!strcmp(session->current_crypto->server_pubkey_type, "ssh-rsa1")) {
|
file = fopen(session->options->known_hosts_file, "a");
|
||||||
/* openssh uses a different format for ssh-rsa1 keys.
|
if (file == NULL) {
|
||||||
Be compatible --kv */
|
ssh_set_error(session, SSH_FATAL,
|
||||||
char *e_string, *n_string;
|
"Couldn't open known_hosts file %s for appending: %s",
|
||||||
bignum e, n;
|
session->options->known_hosts_file, strerror(errno));
|
||||||
PUBLIC_KEY *key = publickey_from_string(session, pubkey);
|
return -1;
|
||||||
int rsa_size;
|
}
|
||||||
|
|
||||||
|
if (strcmp(session->current_crypto->server_pubkey_type, "ssh-rsa1") == 0) {
|
||||||
|
/* openssh uses a different format for ssh-rsa1 keys.
|
||||||
|
Be compatible --kv */
|
||||||
|
PUBLIC_KEY *key;
|
||||||
|
char *e_string = NULL;
|
||||||
|
char *n_string = NULL;
|
||||||
|
bignum e = NULL;
|
||||||
|
bignum n = NULL;
|
||||||
|
int rsa_size;
|
||||||
#ifdef HAVE_LIBGCRYPT
|
#ifdef HAVE_LIBGCRYPT
|
||||||
gcry_sexp_t sexp;
|
gcry_sexp_t sexp;
|
||||||
sexp=gcry_sexp_find_token(key->rsa_pub,"e",0);
|
|
||||||
e=gcry_sexp_nth_mpi(sexp,1,GCRYMPI_FMT_USG);
|
|
||||||
gcry_sexp_release(sexp);
|
|
||||||
sexp=gcry_sexp_find_token(key->rsa_pub,"n",0);
|
|
||||||
n=gcry_sexp_nth_mpi(sexp,1,GCRYMPI_FMT_USG);
|
|
||||||
gcry_sexp_release(sexp);
|
|
||||||
rsa_size=(gcry_pk_get_nbits(key->rsa_pub)+7)/8;
|
|
||||||
#elif defined HAVE_LIBCRYPTO
|
|
||||||
e = key->rsa_pub->e;
|
|
||||||
n = key->rsa_pub->n;
|
|
||||||
rsa_size = RSA_size(key->rsa_pub);
|
|
||||||
#endif
|
#endif
|
||||||
e_string = bignum_bn2dec(e);
|
|
||||||
n_string = bignum_bn2dec(n);
|
key = publickey_from_string(session, pubkey);
|
||||||
snprintf(buffer, sizeof(buffer), "%s %d %s %s\n",
|
if (key == NULL) {
|
||||||
session->options->host, rsa_size << 3,
|
|
||||||
e_string, n_string);
|
|
||||||
#ifdef HAVE_LIBGCRYPT
|
|
||||||
free(e_string);
|
|
||||||
gcry_mpi_release(e);
|
|
||||||
free(n_string);
|
|
||||||
gcry_mpi_release(n);
|
|
||||||
#elif defined HAVE_LIBCRYPTO
|
|
||||||
OPENSSL_free(e_string);
|
|
||||||
OPENSSL_free(n_string);
|
|
||||||
#endif
|
|
||||||
free(key);
|
|
||||||
} else {
|
|
||||||
pubkey_64=bin_to_base64(pubkey->string,string_len(pubkey));
|
|
||||||
snprintf(buffer,sizeof(buffer),"%s %s %s\n",session->options->host,session->current_crypto->server_pubkey_type,pubkey_64);
|
|
||||||
free(pubkey_64);
|
|
||||||
}
|
|
||||||
len = strlen(buffer);
|
|
||||||
if (fwrite(buffer, len, 1, file) != len || ferror(file)) {
|
|
||||||
fclose(file);
|
fclose(file);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef HAVE_LIBGCRYPT
|
||||||
|
sexp = gcry_sexp_find_token(key->rsa_pub, "e", 0);
|
||||||
|
if (sexp == NULL) {
|
||||||
|
publickey_free(key);
|
||||||
|
fclose(file);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
e = gcry_sexp_nth_mpi(sexp, 1, GCRYMPI_FMT_USG);
|
||||||
|
gcry_sexp_release(sexp);
|
||||||
|
if (e == NULL) {
|
||||||
|
publickey_free(key);
|
||||||
|
fclose(file);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
sexp = gcry_sexp_find_token(key->rsa_pub, "n", 0);
|
||||||
|
if (sexp == NULL) {
|
||||||
|
publickey_free(key);
|
||||||
|
bignum_free(e);
|
||||||
|
fclose(file);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
n = gcry_sexp_nth_mpi(sexp, 1, GCRYMPI_FMT_USG);
|
||||||
|
gcry_sexp_release(sexp);
|
||||||
|
if (n == NULL) {
|
||||||
|
publickey_free(key);
|
||||||
|
bignum_free(e);
|
||||||
|
fclose(file);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
rsa_size = (gcry_pk_get_nbits(key->rsa_pub) + 7) / 8;
|
||||||
|
#elif defined HAVE_LIBCRYPTO
|
||||||
|
e = key->rsa_pub->e;
|
||||||
|
n = key->rsa_pub->n;
|
||||||
|
rsa_size = RSA_size(key->rsa_pub);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
e_string = bignum_bn2dec(e);
|
||||||
|
n_string = bignum_bn2dec(n);
|
||||||
|
if (e_string == NULL || n_string == NULL) {
|
||||||
|
#ifdef HAVE_LIBGCRYPT
|
||||||
|
bignum_free(e);
|
||||||
|
bignum_free(n);
|
||||||
|
SAFE_FREE(e_string);
|
||||||
|
SAFE_FREE(n_string);
|
||||||
|
#elif defined HAVE_LIBCRYPTO
|
||||||
|
OPENSSL_free(e_string);
|
||||||
|
OPENSSL_free(n_string);
|
||||||
|
#endif
|
||||||
|
publickey_free(key);
|
||||||
|
fclose(file);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
snprintf(buffer, sizeof(buffer),
|
||||||
|
"%s %d %s %s\n",
|
||||||
|
session->options->host,
|
||||||
|
rsa_size << 3,
|
||||||
|
e_string,
|
||||||
|
n_string);
|
||||||
|
|
||||||
|
#ifdef HAVE_LIBGCRYPT
|
||||||
|
bignum_free(e);
|
||||||
|
bignum_free(n);
|
||||||
|
SAFE_FREE(e_string);
|
||||||
|
SAFE_FREE(n_string);
|
||||||
|
#elif defined HAVE_LIBCRYPTO
|
||||||
|
OPENSSL_free(e_string);
|
||||||
|
OPENSSL_free(n_string);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
publickey_free(key);
|
||||||
|
} else {
|
||||||
|
pubkey_64 = bin_to_base64(pubkey->string, string_len(pubkey));
|
||||||
|
if (pubkey_64 == NULL) {
|
||||||
|
fclose(file);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
snprintf(buffer, sizeof(buffer),
|
||||||
|
"%s %s %s\n",
|
||||||
|
session->options->host,
|
||||||
|
session->current_crypto->server_pubkey_type,
|
||||||
|
pubkey_64);
|
||||||
|
|
||||||
|
SAFE_FREE(pubkey_64);
|
||||||
|
}
|
||||||
|
|
||||||
|
len = strlen(buffer);
|
||||||
|
if (fwrite(buffer, len, 1, file) != len || ferror(file)) {
|
||||||
fclose(file);
|
fclose(file);
|
||||||
return 0;
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
fclose(file);
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/** @} */
|
/** @} */
|
||||||
|
|||||||
Reference in New Issue
Block a user