aboutsummaryrefslogtreecommitdiff
path: root/src/knownhosts.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/knownhosts.c')
-rw-r--r--src/knownhosts.c89
1 files changed, 89 insertions, 0 deletions
diff --git a/src/knownhosts.c b/src/knownhosts.c
index 7c49470c..da96102d 100644
--- a/src/knownhosts.c
+++ b/src/knownhosts.c
@@ -36,6 +36,7 @@
#include "libssh/options.h"
#include "libssh/misc.h"
#include "libssh/pki.h"
+#include "libssh/dh.h"
static int hash_hostname(const char *name,
unsigned char *salt,
@@ -471,3 +472,91 @@ enum ssh_known_hosts_e ssh_session_has_known_hosts_entry(ssh_session session)
return SSH_KNOWN_HOSTS_OK;
}
+
+/**
+ * @brief Export the current session information to a known_hosts string.
+ *
+ * This exports the current information of a session which is connected so a
+ * ssh server into an entry line which can be added to a known_hosts file.
+ *
+ * @param[in] session The session with information to export.
+ *
+ * @param[in] pentry_string A pointer to a string to store the alloocated
+ * line of the entry. The user must free it using
+ * ssh_string_free_char().
+ *
+ * @return SSH_OK on succcess, SSH_ERROR otherwise.
+ */
+int ssh_session_export_known_hosts_entry(ssh_session session,
+ char **pentry_string)
+{
+ ssh_key server_pubkey = NULL;
+ char *host = NULL;
+ char entry_buf[4096] = {0};
+ int rc;
+
+ if (pentry_string == NULL) {
+ ssh_set_error_invalid(session);
+ return SSH_ERROR;
+ }
+
+ if (session->opts.host == NULL) {
+ ssh_set_error(session, SSH_FATAL,
+ "Can't create known_hosts entry - hostname unknown");
+ return SSH_ERROR;
+ }
+
+ host = ssh_session_get_host_port(session);
+ if (host == NULL) {
+ return SSH_ERROR;
+ }
+
+ if (session->current_crypto == NULL) {
+ ssh_set_error(session, SSH_FATAL,
+ "No current crypto context, please connnect first");
+ SAFE_FREE(host);
+ return SSH_ERROR;
+ }
+
+ server_pubkey = ssh_dh_get_current_server_publickey(session);
+ if (server_pubkey == NULL){
+ ssh_set_error(session, SSH_FATAL, "No public key present");
+ SAFE_FREE(host);
+ 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));
+ 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);
+ }
+
+ *pentry_string = strdup(entry_buf);
+ if (*pentry_string == NULL) {
+ return SSH_ERROR;
+ }
+
+ return SSH_OK;
+}