diff options
author | Andreas Schneider <mail@cynapses.org> | 2009-04-28 07:25:19 +0000 |
---|---|---|
committer | Andreas Schneider <mail@cynapses.org> | 2009-04-28 07:25:19 +0000 |
commit | 9f7d4d2d60b4f6ff2f2305b6db75dd85f82577f5 (patch) | |
tree | 26e05177a750e8467afdca9b3447e068353f638c /libssh/keyfiles.c | |
parent | 511213872bf9a9b2a8ca01a6c5999928a0dec2db (diff) | |
download | libssh-9f7d4d2d60b4f6ff2f2305b6db75dd85f82577f5.tar.gz libssh-9f7d4d2d60b4f6ff2f2305b6db75dd85f82577f5.tar.xz libssh-9f7d4d2d60b4f6ff2f2305b6db75dd85f82577f5.zip |
Improve ssh_write_knownhost.
git-svn-id: svn+ssh://svn.berlios.de/svnroot/repos/libssh/trunk@635 7dcaeef0-15fb-0310-b436-a5af3365683c
Diffstat (limited to 'libssh/keyfiles.c')
-rw-r--r-- | libssh/keyfiles.c | 184 |
1 files changed, 130 insertions, 54 deletions
diff --git a/libssh/keyfiles.c b/libssh/keyfiles.c index aca1d80b..cc627d8c 100644 --- a/libssh/keyfiles.c +++ b/libssh/keyfiles.c @@ -1412,72 +1412,148 @@ int ssh_is_server_known(SSH_SESSION *session) { * \param session ssh session * \return 0 on success, -1 on error */ -int ssh_write_knownhost(SSH_SESSION *session){ - unsigned char *pubkey_64; - STRING *pubkey=session->current_crypto->server_pubkey; - char buffer[4096]; - size_t len = 0; - FILE *file; - ssh_options_default_known_hosts_file(session->options); - if(!session->options->host){ - ssh_set_error(session,SSH_FATAL,"Cannot write host in known hosts if the hostname is unknown"); - return -1; - } - /* a = append only */ - file=fopen(session->options->known_hosts_file,"a"); - if(!file){ - ssh_set_error(session,SSH_FATAL,"Opening known host file %s for appending : %s", - session->options->known_hosts_file,strerror(errno)); - return -1; +int ssh_write_knownhost(SSH_SESSION *session) { + STRING *pubkey = session->current_crypto->server_pubkey; + unsigned char *pubkey_64; + char buffer[4096] = {0}; + FILE *file; + size_t len = 0; + + if (ssh_options_default_known_hosts_file(session->options) < 0) { + ssh_set_error(session, SSH_FATAL, "Cannot find known_hosts file."); + return -1; + } + + if (session->options->host == NULL) { + ssh_set_error(session, SSH_FATAL, + "Cannot write host in known hosts if the hostname is unknown"); + return -1; + } + + file = fopen(session->options->known_hosts_file, "a"); + if (file == NULL) { + ssh_set_error(session, SSH_FATAL, + "Couldn't open known_hosts file %s for appending: %s", + session->options->known_hosts_file, strerror(errno)); + return -1; + } + + 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 + gcry_sexp_t sexp; +#endif + + key = publickey_from_string(session, pubkey); + if (key == NULL) { + fclose(file); + return -1; } - if (!strcmp(session->current_crypto->server_pubkey_type, "ssh-rsa1")) { - /* openssh uses a different format for ssh-rsa1 keys. - Be compatible --kv */ - char *e_string, *n_string; - bignum e, n; - PUBLIC_KEY *key = publickey_from_string(session, pubkey); - int rsa_size; + #ifdef HAVE_LIBGCRYPT - 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; + 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); + 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); - snprintf(buffer, sizeof(buffer), "%s %d %s %s\n", - session->options->host, rsa_size << 3, - e_string, n_string); + + e_string = bignum_bn2dec(e); + n_string = bignum_bn2dec(n); + if (e_string == NULL || n_string == NULL) { #ifdef HAVE_LIBGCRYPT - free(e_string); - gcry_mpi_release(e); - free(n_string); - gcry_mpi_release(n); + 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); + 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); + publickey_free(key); + fclose(file); + return -1; } - len = strlen(buffer); - if (fwrite(buffer, len, 1, file) != len || ferror(file)) { + + 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); - return 0; + return -1; + } + + fclose(file); + return 0; } /** @} */ |