summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorIru Cai <mytbk920423@gmail.com>2018-04-28 21:50:54 +0800
committerIru Cai <mytbk920423@gmail.com>2018-04-30 15:20:28 +0800
commitef70cc73c69d04e93c9af5fb49c5d762ba226801 (patch)
tree2f96375bb6047f1a6161c00f659e222711db3cd7
parentbec678f312d282cd467a4d13dbf29c37ea111ce7 (diff)
downloadfqterm-ef70cc73c69d04e93c9af5fb49c5d762ba226801.tar.xz
Add a connection info field in FQTermSocket
- the connection info record contains the name of the cipher and MAC algorithms, and the key hash - after doing a key exchange, the connection info will be filled
-rw-r--r--src/protocol/connect_info.h25
-rw-r--r--src/protocol/fqterm_local_socket.cpp1
-rw-r--r--src/protocol/fqterm_socket.h6
-rw-r--r--src/protocol/fqterm_ssh_socket.cpp17
-rw-r--r--src/protocol/fqterm_telnet_socket.cpp1
-rw-r--r--src/protocol/internal/fqterm_ssh2_kex.cpp31
-rw-r--r--src/protocol/internal/fqterm_ssh2_kex.h9
-rw-r--r--src/protocol/internal/fqterm_ssh_kex.h2
8 files changed, 80 insertions, 12 deletions
diff --git a/src/protocol/connect_info.h b/src/protocol/connect_info.h
new file mode 100644
index 0000000..0111a39
--- /dev/null
+++ b/src/protocol/connect_info.h
@@ -0,0 +1,25 @@
+#ifndef CONNECT_INFO_H
+#define CONNECT_INFO_H
+
+enum protocol
+{
+ PROTO_LOCAL,
+ PROTO_TELNET,
+ PROTO_SSH
+};
+
+typedef struct
+{
+ enum protocol proto;
+ struct
+ {
+ int proto_version;
+ const char *c2s_cipher;
+ const char *s2c_cipher;
+ const char *c2s_mac;
+ const char *s2c_mac;
+ unsigned char hash[32];
+ } ssh_proto_info;
+} conn_info_t;
+
+#endif
diff --git a/src/protocol/fqterm_local_socket.cpp b/src/protocol/fqterm_local_socket.cpp
index dbfb5b1..dc81acd 100644
--- a/src/protocol/fqterm_local_socket.cpp
+++ b/src/protocol/fqterm_local_socket.cpp
@@ -15,6 +15,7 @@ FQTermLocalSocket::FQTermLocalSocket()
//TODO: Error
//FQ_VERIFY(connect(shell_process_, SIGNAL(error(QAbstractSocket::SocketError)), this, SIGNAL(error(QAbstractSocket::SocketError))));
//FQ_VERIFY(connect(shell_process_, SIGNAL(socketState(int)), this, SIGNAL(socketState(int))));
+ conn_info.proto = PROTO_LOCAL;
}
FQTermLocalSocket::~FQTermLocalSocket()
diff --git a/src/protocol/fqterm_socket.h b/src/protocol/fqterm_socket.h
index 11112c3..02b16eb 100644
--- a/src/protocol/fqterm_socket.h
+++ b/src/protocol/fqterm_socket.h
@@ -51,6 +51,8 @@
#include <QStringList>
#include <QProcess>
+#include "connect_info.h"
+
class QTcpSocket;
namespace FQTerm {
/*
@@ -115,6 +117,9 @@ class FQTermSocketPrivate: public QObject {
class FQTermSocket: public QObject {
Q_OBJECT;
+protected:
+ conn_info_t conn_info;
+
public:
FQTermSocket(QObject *parent = 0): QObject(parent) {}
@@ -133,6 +138,7 @@ class FQTermSocket: public QObject {
virtual unsigned long bytesAvailable() = 0;
virtual bool readyForInput() {return true;}
virtual bool setTermSize(int col, int row) {return 0;}
+ virtual conn_info_t * connectionInfo() { return &conn_info; }
signals:
void sshAuthOK();
void connected();
diff --git a/src/protocol/fqterm_ssh_socket.cpp b/src/protocol/fqterm_ssh_socket.cpp
index 20612bf..c48fc51 100644
--- a/src/protocol/fqterm_ssh_socket.cpp
+++ b/src/protocol/fqterm_ssh_socket.cpp
@@ -161,11 +161,22 @@ void FQTermSSHSocket::init(int ssh_version) {
key_exchanger_->initKex(packet_receiver_, packet_sender_);
}
+
+ conn_info.proto = PROTO_SSH;
+ conn_info.ssh_proto_info.proto_version = ssh_version;
}
-void FQTermSSHSocket::kexOK() {
- FQ_TRACE("sshsocket", 3) << "Key exchange completed!";
- authentication_->initAuth(packet_receiver_, packet_sender_);
+void FQTermSSHSocket::kexOK()
+{
+ FQ_TRACE("sshsocket", 3) << "Key exchange completed!";
+ conn_info.ssh_proto_info.c2s_cipher = packet_sender_->cipher->name;
+ conn_info.ssh_proto_info.s2c_cipher = packet_receiver_->cipher->name;
+ if (packet_sender_->mac)
+ conn_info.ssh_proto_info.c2s_mac = packet_sender_->mac->name;
+ if (packet_receiver_->mac)
+ conn_info.ssh_proto_info.s2c_mac = packet_receiver_->mac->name;
+ key_exchanger_->hostKeyHash(conn_info.ssh_proto_info.hash);
+ authentication_->initAuth(packet_receiver_, packet_sender_);
}
void FQTermSSHSocket::authOK() {
diff --git a/src/protocol/fqterm_telnet_socket.cpp b/src/protocol/fqterm_telnet_socket.cpp
index af04a8c..170edb9 100644
--- a/src/protocol/fqterm_telnet_socket.cpp
+++ b/src/protocol/fqterm_telnet_socket.cpp
@@ -13,6 +13,7 @@ FQTermTelnetSocket::FQTermTelnetSocket()
FQ_VERIFY(connect(private_socket_, SIGNAL(readyRead()), this, SIGNAL(readyRead())));
FQ_VERIFY(connect(private_socket_, SIGNAL(error(QAbstractSocket::SocketError)), this, SIGNAL(error(QAbstractSocket::SocketError))));
FQ_VERIFY(connect(private_socket_, SIGNAL(socketState(int)), this, SIGNAL(socketState(int))));
+ conn_info.proto = PROTO_TELNET;
}
FQTermTelnetSocket::~FQTermTelnetSocket() {
diff --git a/src/protocol/internal/fqterm_ssh2_kex.cpp b/src/protocol/internal/fqterm_ssh2_kex.cpp
index 570c29f..f51f459 100644
--- a/src/protocol/internal/fqterm_ssh2_kex.cpp
+++ b/src/protocol/internal/fqterm_ssh2_kex.cpp
@@ -42,6 +42,7 @@ FQTermSSH2Kex::FQTermSSH2Kex(const char *V_C, const char *V_S)
I_C_ = NULL;
I_S_len_ = 0;
I_S_ = NULL;
+ K_S_ = NULL;
bn_x_ = BN_new();
bn_e_ = BN_new();
@@ -56,6 +57,8 @@ FQTermSSH2Kex::FQTermSSH2Kex(const char *V_C, const char *V_S)
FQTermSSH2Kex::~FQTermSSH2Kex() {
delete[] I_C_;
delete[] I_S_;
+ if (K_S_)
+ delete [] K_S_;
BN_clear_free(bn_x_);
BN_clear_free(bn_e_);
@@ -110,6 +113,24 @@ void FQTermSSH2Kex::handlePacket(int type)
bool FQTermSSH2Kex::negotiateAlgorithms() {
FQ_FUNC_TRACE("ssh2kex", 10);
+ /*
+ * RFC 4253 section 7: kex begins by the following packet
+ * byte SSH_MSG_KEXINIT
+ * byte[16] cookie (random bytes)
+ * name-list kex_algorithms
+ * name-list server_host_key_algorithms
+ * name-list encryption_algorithms_client_to_server
+ * name-list encryption_algorithms_server_to_client
+ * name-list mac_algorithms_client_to_server
+ * name-list mac_algorithms_server_to_client
+ * name-list compression_algorithms_client_to_server
+ * name-list compression_algorithms_server_to_client
+ * name-list languages_client_to_server
+ * name-list languages_server_to_client
+ * boolean first_kex_packet_follows
+ * uint32 0 (reserved for future extension)
+ */
+
if (packet_receiver_->packetType() != SSH2_MSG_KEXINIT) {
emit kexError(tr("startKex: First packet is not SSH_MSG_KEXINIT"));
return false;
@@ -256,8 +277,9 @@ bool FQTermSSH2Kex::verifyKey() {
// Extract data
- int K_S_len = -1;
- unsigned char *K_S = (unsigned char *)packet_receiver_->getString(&K_S_len);
+ if (K_S_)
+ delete [] K_S_;
+ K_S_ = (char*)packet_receiver_->getString(&K_S_len_);
packet_receiver_->getBN2(bn_f_);
@@ -273,7 +295,7 @@ bool FQTermSSH2Kex::verifyKey() {
buffer->putString(V_S_);
buffer->putString(I_C_, I_C_len_);
buffer->putString(I_S_, I_S_len_);
- buffer->putString((char *)K_S, K_S_len);
+ buffer->putString(K_S_, K_S_len_);
buffer->putSSH2BN(bn_e_);
buffer->putSSH2BN(bn_f_);
buffer->putSSH2BN(bn_K_);
@@ -287,7 +309,7 @@ bool FQTermSSH2Kex::verifyKey() {
// Ignore the first 15 bytes of the signature of H sent from server:
// algorithm_name_length[4], algorithm_name[7]("ssh-rsa") and signature_length[4].
- RSA *rsactx = CreateRSAContext(K_S, K_S_len);
+ RSA *rsactx = CreateRSAContext((unsigned char*)K_S_, K_S_len_);
int sig_len = s_len - 15;
unsigned char *sig = s + 15;
int res = RSA_verify(NID_sha1, s_H, SHA_DIGEST_LENGTH,
@@ -295,7 +317,6 @@ bool FQTermSSH2Kex::verifyKey() {
RSA_free(rsactx);
- delete [] K_S;
delete [] s;
return res == 1;
diff --git a/src/protocol/internal/fqterm_ssh2_kex.h b/src/protocol/internal/fqterm_ssh2_kex.h
index 0a09cc1..80da76d 100644
--- a/src/protocol/internal/fqterm_ssh2_kex.h
+++ b/src/protocol/internal/fqterm_ssh2_kex.h
@@ -55,6 +55,8 @@ private:
char *I_C_;
int I_S_len_;
char *I_S_;
+ int K_S_len_;
+ char *K_S_;
SSH_DH *dh;
BIGNUM *bn_x_;
@@ -70,9 +72,6 @@ private:
bool is_first_kex_;
- ssh_pubkey_t *host_key_;
- ssh_pubkey_t *server_key_;
-
u_char cookie_[16];
int server_flag_, ciphers_, auth_;
// u_char session_id_[16];
@@ -92,6 +91,10 @@ public:
virtual void initKex(FQTermSSHPacketReceiver *packetReceiver,
FQTermSSHPacketSender *outputSender);
+ void hostKeyHash(unsigned char *md)
+ {
+ SHA256((const unsigned char*)K_S_, K_S_len_, md);
+ }
public slots:
void handlePacket(int type);
diff --git a/src/protocol/internal/fqterm_ssh_kex.h b/src/protocol/internal/fqterm_ssh_kex.h
index f84c0d5..2bd46b8 100644
--- a/src/protocol/internal/fqterm_ssh_kex.h
+++ b/src/protocol/internal/fqterm_ssh_kex.h
@@ -53,7 +53,7 @@ public:
virtual void initKex(FQTermSSHPacketReceiver *packetReceiver,
FQTermSSHPacketSender *outputSender) = 0;
-
+ virtual void hostKeyHash(unsigned char *md) {}
public slots:
virtual void handlePacket(int type) = 0;