summaryrefslogtreecommitdiff
path: root/src/protocol/internal/fqterm_ssh_packet.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/protocol/internal/fqterm_ssh_packet.cpp')
-rw-r--r--src/protocol/internal/fqterm_ssh_packet.cpp148
1 files changed, 104 insertions, 44 deletions
diff --git a/src/protocol/internal/fqterm_ssh_packet.cpp b/src/protocol/internal/fqterm_ssh_packet.cpp
index 6e40de8..5db2385 100644
--- a/src/protocol/internal/fqterm_ssh_packet.cpp
+++ b/src/protocol/internal/fqterm_ssh_packet.cpp
@@ -25,6 +25,7 @@
#include "fqterm_serialization.h"
#include "crc32.h"
+#include <openssl/bn.h>
namespace FQTerm {
@@ -32,9 +33,10 @@ namespace FQTerm {
//FQTermSSHPacketSender
//==============================================================================
-FQTermSSHPacketSender::FQTermSSHPacketSender() {
- buffer_ = new FQTermSSHBuffer(1024);
- output_buffer_ = new FQTermSSHBuffer(1024);
+FQTermSSHPacketSender::FQTermSSHPacketSender()
+{
+ buffer_init(&orig_data);
+ buffer_init(&data_to_send);
is_encrypt_ = false;
cipher_type_ = SSH_CIPHER_NONE;
@@ -48,43 +50,56 @@ FQTermSSHPacketSender::FQTermSSHPacketSender() {
sequence_no_ = 0;
}
-FQTermSSHPacketSender::~FQTermSSHPacketSender() {
- delete buffer_;
- delete output_buffer_;
+FQTermSSHPacketSender::~FQTermSSHPacketSender()
+{
if (cipher)
cipher->cleanup(cipher);
if (mac)
mac->cleanup(mac);
+ buffer_deinit(&data_to_send);
+ buffer_deinit(&orig_data);
}
-void FQTermSSHPacketSender::putRawData(const char *data, int len) {
- buffer_->putRawData(data, len);
-}
-
-void FQTermSSHPacketSender::putByte(int data) {
- buffer_->putByte(data);
-}
-
-void FQTermSSHPacketSender::putInt(u_int data) {
- buffer_->putInt(data);
-}
-
-void FQTermSSHPacketSender::putString(const char *string, int len) {
- buffer_->putString(string, len);
-}
+void FQTermSSHPacketSender::putString(const char *s, int len)
+{
+ if (len < 0)
+ len = strlen(s);
-void FQTermSSHPacketSender::putBN(BIGNUM *bn) {
- buffer_->putSSH1BN(bn);
+ putInt(len);
+ putRawData((const uint8_t *)s, len);
}
-void FQTermSSHPacketSender::startPacket(int pkt_type) {
- buffer_->clear();
- buffer_->putByte(pkt_type);
+void FQTermSSHPacketSender::putBN(BIGNUM *bignum)
+{
+ int bits = BN_num_bits(bignum);
+ int bin_size = (bits + 7) / 8;
+ uint8_t buf[bin_size];
+ int oi;
+ uint8_t msg[2];
+
+ // Get the value of in binary
+ oi = BN_bn2bin(bignum, buf);
+ if (oi != bin_size) {
+ FQ_TRACE("sshbuffer", 0) << "BN_bn2bin() failed: oi = " << oi
+ << " != bin_size." << bin_size;
+ }
+
+ // Store the number of bits in the buffer in two bytes, msb first
+ buffer_append_be16(&orig_data, bits);
+ // Store the binary data.
+ putRawData(buf, oi);
+}
+
+void FQTermSSHPacketSender::startPacket(uint8_t pkt_type)
+{
+ buffer_clear(&orig_data);
+ putByte(pkt_type);
}
-void FQTermSSHPacketSender::write() {
- makePacket();
- emit dataToWrite();
+void FQTermSSHPacketSender::write()
+{
+ makePacket();
+ emit dataToWrite();
}
void FQTermSSHPacketSender::startEncryption(const u_char *key, const u_char *IV) {
@@ -114,8 +129,9 @@ void FQTermSSHPacketSender::resetMac() {
//FQTermSSHPacketReceiver
//==============================================================================
-FQTermSSHPacketReceiver::FQTermSSHPacketReceiver() {
- buffer_ = new FQTermSSHBuffer(1024);
+FQTermSSHPacketReceiver::FQTermSSHPacketReceiver()
+{
+ buffer_init(&recvbuf);
is_decrypt_ = false;
cipher_type_ = SSH_CIPHER_NONE;
@@ -131,35 +147,79 @@ FQTermSSHPacketReceiver::FQTermSSHPacketReceiver() {
FQTermSSHPacketReceiver::~FQTermSSHPacketReceiver()
{
- delete buffer_;
+ buffer_deinit(&recvbuf);
if (cipher)
cipher->cleanup(cipher);
if (mac)
mac->cleanup(mac);
}
-void FQTermSSHPacketReceiver::getRawData(char *data, int length) {
- buffer_->getRawData(data, length);
+void FQTermSSHPacketReceiver::getRawData(char *data, int length)
+{
+ if (buffer_len(&recvbuf) >= length)
+ buffer_get(&recvbuf, (uint8_t*)data, length);
+ else
+ emit packetError("Read too many bytes!");
}
-u_char FQTermSSHPacketReceiver::getByte() {
- return buffer_->getByte();
+u_char FQTermSSHPacketReceiver::getByte()
+{
+ if (buffer_len(&recvbuf) >= 1)
+ return buffer_get_u8(&recvbuf);
+ else
+ emit packetError("Read too many bytes!");
}
-u_int FQTermSSHPacketReceiver::getInt() {
- return buffer_->getInt();
+u_int FQTermSSHPacketReceiver::getInt()
+{
+ if (buffer_len(&recvbuf) >= 4)
+ return buffer_get_u32(&recvbuf);
+ else
+ emit packetError("Read too many bytes!");
}
-void *FQTermSSHPacketReceiver::getString(int *length) {
- return buffer_->getString(length);
+void *FQTermSSHPacketReceiver::getString(int *length)
+{
+ uint32_t l = getInt();
+ char *data = new char[l+1];
+ getRawData(data, l);
+ data[l] = 0;
+ if (length != NULL)
+ *length = l;
+ return data;
}
-void FQTermSSHPacketReceiver::getBN(BIGNUM *bignum) {
- buffer_->getSSH1BN(bignum);
+void FQTermSSHPacketReceiver::getBN(BIGNUM *bignum)
+{
+ int bits, bytes;
+ u_char buf[2];
+ u_char *bin;
+
+ // Get the number for bits.
+ if (buffer_len(&recvbuf) >= 2) {
+ bits = buffer_get_u16(&recvbuf);
+ } else {
+ emit packetError("Read too many bytes!");
+ return;
+ }
+ // Compute the number of binary bytes that follow.
+ bytes = (bits + 7) / 8;
+ if (bytes > 8 *1024) {
+ emit packetError("Can't handle BN of size!");
+ return ;
+ }
+ if (buffer_len(&recvbuf) < bytes) {
+ emit packetError("The input buffer is too small!");
+ return ;
+ }
+ bin = buffer_data(&recvbuf);
+ BN_bin2bn(bin, bytes, bignum);
+ buffer_consume(&recvbuf, bytes);
}
-void FQTermSSHPacketReceiver::consume(int len) {
- buffer_->consume(len);
+void FQTermSSHPacketReceiver::consume(int len)
+{
+ buffer_consume(&recvbuf, len);
}
void FQTermSSHPacketReceiver::startEncryption(const u_char *key, const u_char *IV) {