summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorIru Cai <mytbk920423@gmail.com>2018-05-21 20:38:06 +0800
committerIru Cai <mytbk920423@gmail.com>2018-06-08 15:25:57 +0800
commit5033441c905536656cd8bfeaa869621346a2bc1e (patch)
tree36a01da2e82368563581fe72ea681ee9185d7444
parent9ceadd480c24d61148c120335931456b39a4837b (diff)
downloadfqterm-5033441c905536656cd8bfeaa869621346a2bc1e.tar.xz
warn SSH2 for mismatched/unknown host key
-rw-r--r--src/protocol/fqterm_ssh_socket.cpp48
1 files changed, 44 insertions, 4 deletions
diff --git a/src/protocol/fqterm_ssh_socket.cpp b/src/protocol/fqterm_ssh_socket.cpp
index 8649bb9..e273029 100644
--- a/src/protocol/fqterm_ssh_socket.cpp
+++ b/src/protocol/fqterm_ssh_socket.cpp
@@ -30,7 +30,11 @@
#include "fqterm_trace.h"
#include "fqterm_path.h"
#include "ssh_known_hosts.h"
+#include "ccan_base64.h"
#include <QString>
+#include <cstdlib>
+#include <cstring>
+
namespace FQTerm {
#define V1STR "SSH-1.5-FQTermSSH\n"
@@ -152,17 +156,53 @@ void FQTermSSHSocket::kexOK()
struct ssh_host *hosts;
const char *hosts_file;
#ifdef WIN32
- hosts_file = (getPath(USER_CONFIG) + "known_hosts").toLatin1().constData();
+ QString known_hosts = getPath(USER_CONFIG) + "known_hosts";
+ hosts_file = strdup(known_hosts.toLatin1().constData());
#else
hosts_file = ssh_hosts_filename();
#endif
hosts = parse_hosts_file(hosts_file, &nhosts);
int idx = find_ssh_host(hosts, nhosts, conn_info.hostname, conn_info.port);
FQTermSSH2Kex *kex = dynamic_cast<FQTermSSH2Kex *> (key_exchanger_);
- if (idx >=0 && key_matches(&hosts[idx], kex->K_S(), kex->K_S_len()))
- conn_info.ssh_proto_info.key_matches = 1;
- else
+ bool isok;
+ if (idx >=0) {
+ if (key_matches(&hosts[idx], kex->K_S(), kex->K_S_len())) {
+ conn_info.ssh_proto_info.key_matches = 1;
+ } else {
+ conn_info.ssh_proto_info.key_matches = 0;
+ emit warnInsecure("Host key mismatch!", &isok);
+ if (!isok)
+ handleError("Uesr closed connection due to key mismatch.");
+ }
+ } else {
conn_info.ssh_proto_info.key_matches = 0;
+ unsigned char hash[32];
+ char hash_b64[64];
+ kex->hostKeyHash(hash);
+ base64_encode(hash_b64, sizeof(hash_b64), (const char*)hash, 32);
+ hash_b64[base64_encoded_length(32)-1] = 0; /* final byte is '=' */
+
+ const char *tab = "0123456789ABCDEF";
+ QString msg = "Unknown host, trust the host key?\nSHA256: ";
+ for (int i = 0; i < 32; i++) {
+ char d[4];
+ d[0] = tab[hash[i]>>4];
+ d[1] = tab[hash[i]&0xf];
+ d[2] = (i==31)?'\n':':';
+ d[3] = 0;
+ msg.append(d);
+ }
+ msg.append(QString("base64: %1").arg(hash_b64));
+ emit warnInsecure(msg, &isok);
+ if (!isok)
+ handleError("Uesr closed connection due to an unknown host.");
+ else
+ /* FIXME: port != 22? */
+ append_hostkey(hosts_file, conn_info.hostname, kex->K_S(), kex->K_S_len());
+ }
+#ifdef WIN32
+ free(hosts_file);
+#endif
}
key_exchanger_->hostKeyHash(conn_info.ssh_proto_info.hash);