summaryrefslogtreecommitdiff
path: root/src/protocol/internal/fqterm_ssh1_packet.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/protocol/internal/fqterm_ssh1_packet.cpp')
-rw-r--r--src/protocol/internal/fqterm_ssh1_packet.cpp148
1 files changed, 148 insertions, 0 deletions
diff --git a/src/protocol/internal/fqterm_ssh1_packet.cpp b/src/protocol/internal/fqterm_ssh1_packet.cpp
new file mode 100644
index 0000000..ded7fe4
--- /dev/null
+++ b/src/protocol/internal/fqterm_ssh1_packet.cpp
@@ -0,0 +1,148 @@
+/***************************************************************************
+ * fqterm, a terminal emulator for both BBS and *nix. *
+ * Copyright (C) 2008 fqterm development group. *
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ * This program is distributed in the hope that it will be useful, *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
+ * GNU General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU General Public License *
+ * along with this program; if not, write to the *
+ * Free Software Foundation, Inc., *
+ * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. *
+ ***************************************************************************/
+
+#include "fqterm_trace.h"
+#include "fqterm_ssh_buffer.h"
+#include "fqterm_ssh1_packet.h"
+#include "fqterm_ssh_des.h"
+
+#include "fqterm_serialization.h"
+#include "crc32.h"
+
+namespace FQTerm {
+//==============================================================================
+//FQTermSSH1PacketSender
+//==============================================================================
+//==============================================================================
+//
+// SSH1 Packet Structure:
+// --------------------------------------------------------------------------
+// | length | padding | type | data | crc32 |
+// --------------------------------------------------------------------------
+// | uint32 | 1-7bytes | uchar | | 4bytes|
+// --------------------------------------------------------------------------
+// encrypt = padding + type + data + crc32
+// length = type + data + crc32
+//
+//==============================================================================
+
+void FQTermSSH1PacketSender::makePacket() {
+ int len, padding, i;
+ u_int32_t rand_val = 0;
+
+ delete output_buffer_;
+
+ len = buffer_->len() + 4; //CRC32
+ padding = 8-(len % 8);
+
+ output_buffer_ = new FQTermSSHBuffer(len + padding + 4); //pktlen and crc32
+ output_buffer_->putInt(len);
+
+ for (i = 0; i < padding; i++) {
+ if (i % 4 == 0) {
+ rand_val = rand(); // FIXME: rand() doesn't range from 0 to 2^32.
+ }
+
+ output_buffer_->putByte(rand_val &0xff);
+ rand_val >>= 8;
+ }
+
+ output_buffer_->putRawData((const char*)buffer_->data(), buffer_->len());
+ output_buffer_->putInt(ssh_crc32(output_buffer_->data() + 4, output_buffer_->len() - 4));
+
+ if (is_encrypt_) {
+ cipher_->encrypt(output_buffer_->data() + 4, output_buffer_->data() + 4, output_buffer_->len() - 4);
+ }
+
+}
+
+//==============================================================================
+//FQTermSSH1PacketReceiver
+//==============================================================================
+void FQTermSSH1PacketReceiver::parseData(FQTermSSHBuffer *input) {
+ u_int mycrc, gotcrc;
+ u_char *buf = NULL;
+ u_char *targetData = NULL;
+ u_char *sourceData = NULL;
+
+ // Get the length of the packet.
+ while (input->len() > 0) {
+ if (input->len() < 4) {
+ FQ_TRACE("ssh1packet", 3) << "The packet is too small.";
+ return ;
+ }
+ buf = input->data();
+ real_data_len_ = ntohu32(buf);
+
+ if (real_data_len_ > SSH_BUFFER_MAX) {
+ emit packetError(tr("parseData: The packet is too big"));
+ return ;
+ }
+
+ u_int total_len = (real_data_len_ + 8) &~7;
+ u_int padding_len = total_len - real_data_len_;
+
+ real_data_len_ -= 5;
+ buffer_->clear();
+
+ // Get the data of the packet.
+ if (input->len() - 4 < (long)total_len) {
+ FQ_TRACE("ssh1packet", 3) << "The packet is too small";
+ return ;
+ }
+
+ real_data_len_ = input->getInt() - 5;
+ targetData = new u_char[total_len];
+ sourceData = new u_char[total_len];
+ memset(targetData, 0, total_len);
+ memset(sourceData, 0, total_len);
+
+ input->getRawData((char*)sourceData, total_len);
+ if (is_decrypt_) {
+ cipher_->decrypt(sourceData, targetData, total_len);
+ } else {
+ memcpy(targetData, sourceData, total_len);
+ }
+
+ buffer_->putRawData((char*)targetData, total_len);
+
+ // Check the crc32.
+ buf = buffer_->data() + total_len - 4;
+ mycrc = ntohu32(buf);
+ gotcrc = ssh_crc32(buffer_->data(), total_len - 4);
+
+ if (mycrc != gotcrc) {
+ emit packetError(tr("parseData: bad CRC32"));
+ break;
+ }
+
+ // Drop the padding.
+ buffer_->consume(padding_len);
+
+ packet_type_ = buffer_->getByte();
+
+ emit packetAvaliable(packet_type_);
+
+ delete [] sourceData;
+ delete [] targetData;
+ }
+}
+
+} // namespace FQTerm