File indexing completed on 2025-01-05 04:37:18

0001 /*
0002     SPDX-FileCopyrightText: 2005 Joris Guisson <joris.guisson@gmail.com>
0003 
0004     SPDX-License-Identifier: GPL-2.0-or-later
0005 */
0006 #include "encryptedpacketsocket.h"
0007 #include <QtGlobal>
0008 #include <errno.h>
0009 #include <stdlib.h>
0010 #include <sys/socket.h>
0011 #include <sys/types.h>
0012 #include <util/log.h>
0013 #include <util/sha1hash.h>
0014 #ifndef Q_WS_WIN
0015 #include <netinet/in.h>
0016 #include <netinet/in_systm.h>
0017 #include <netinet/ip.h>
0018 #else
0019 #define IPTOS_THROUGHPUT 0x08
0020 #endif
0021 #include "rc4encryptor.h"
0022 #include <net/socketmonitor.h>
0023 #include <netinet/tcp.h>
0024 #include <util/functions.h>
0025 
0026 using namespace bt;
0027 using namespace net;
0028 
0029 namespace mse
0030 {
0031 Uint8 EncryptedPacketSocket::tos = IPTOS_THROUGHPUT;
0032 
0033 EncryptedPacketSocket::EncryptedPacketSocket(int ip_version)
0034     : net::PacketSocket(true, ip_version)
0035     , enc(nullptr)
0036     , monitored(false)
0037 {
0038     sock->setBlocking(false);
0039     sock->setTOS(tos);
0040     reinserted_data = nullptr;
0041     reinserted_data_size = 0;
0042     reinserted_data_read = 0;
0043 }
0044 
0045 EncryptedPacketSocket::EncryptedPacketSocket(int fd, int ip_version)
0046     : net::PacketSocket(fd, ip_version)
0047     , enc(nullptr)
0048     , monitored(false)
0049 {
0050     sock->setBlocking(false);
0051     sock->setTOS(tos);
0052     reinserted_data = nullptr;
0053     reinserted_data_size = 0;
0054     reinserted_data_read = 0;
0055 }
0056 
0057 EncryptedPacketSocket::EncryptedPacketSocket(net::SocketDevice *sd)
0058     : net::PacketSocket(sd)
0059     , enc(nullptr)
0060     , monitored(false)
0061 {
0062     sd->setBlocking(false);
0063     sd->setTOS(tos);
0064     reinserted_data = nullptr;
0065     reinserted_data_size = 0;
0066     reinserted_data_read = 0;
0067 }
0068 
0069 EncryptedPacketSocket::~EncryptedPacketSocket()
0070 {
0071     if (monitored)
0072         stopMonitoring();
0073 
0074     delete[] reinserted_data;
0075     delete enc;
0076 }
0077 
0078 void EncryptedPacketSocket::startMonitoring(net::SocketReader *rdr)
0079 {
0080     setReader(rdr);
0081     SocketMonitor::instance().add(this);
0082     monitored = true;
0083     if (reinserted_data) {
0084         if (enc)
0085             enc->decrypt(reinserted_data + reinserted_data_read, reinserted_data_size - reinserted_data_read);
0086 
0087         rdr->onDataReady(reinserted_data + reinserted_data_read, reinserted_data_size - reinserted_data_read);
0088         delete[] reinserted_data;
0089         reinserted_data = nullptr;
0090         reinserted_data_size = 0;
0091     }
0092 }
0093 
0094 void EncryptedPacketSocket::stopMonitoring()
0095 {
0096     SocketMonitor::instance().remove(this);
0097     monitored = false;
0098     rdr = nullptr;
0099 }
0100 
0101 Uint32 EncryptedPacketSocket::sendData(const Uint8 *data, Uint32 len)
0102 {
0103     if (enc) {
0104         // we need to make sure all data is sent because of the encryption
0105         Uint32 ds = 0;
0106         const Uint8 *ed = enc->encrypt(data, len);
0107         while (sock->ok() && ds < len) {
0108             Uint32 ret = sock->send(ed + ds, len - ds);
0109             ds += ret;
0110             if (ret == 0) {
0111                 Out(SYS_CON | LOG_DEBUG) << "ret = 0" << endl;
0112             }
0113         }
0114         if (ds != len)
0115             Out(SYS_CON | LOG_DEBUG) << "ds != len" << endl;
0116         return ds;
0117     } else {
0118         Uint32 ret = sock->send(data, len);
0119         if (ret != len)
0120             Out(SYS_CON | LOG_DEBUG) << "ret != len" << endl;
0121         return ret;
0122     }
0123 }
0124 
0125 Uint32 EncryptedPacketSocket::readData(Uint8 *buf, Uint32 len)
0126 {
0127     Uint32 ret2 = 0;
0128     if (reinserted_data) {
0129         Uint32 tr = reinserted_data_size - reinserted_data_read;
0130         if (tr < len) {
0131             memcpy(buf, reinserted_data + reinserted_data_read, tr);
0132             delete[] reinserted_data;
0133             reinserted_data = nullptr;
0134             reinserted_data_size = reinserted_data_read = 0;
0135             ret2 = tr;
0136             if (enc)
0137                 enc->decrypt(buf, tr);
0138         } else {
0139             tr = len;
0140             memcpy(buf, reinserted_data + reinserted_data_read, tr);
0141             reinserted_data_read += tr;
0142             if (enc)
0143                 enc->decrypt(buf, tr);
0144             return tr;
0145         }
0146     }
0147 
0148     if (len == ret2)
0149         return ret2;
0150 
0151     Uint32 ret = sock->recv(buf + ret2, len - ret2);
0152     if (ret + ret2 > 0 && enc)
0153         enc->decrypt(buf, ret + ret2);
0154 
0155     return ret;
0156 }
0157 
0158 Uint32 EncryptedPacketSocket::bytesAvailable() const
0159 {
0160     Uint32 ba = sock->bytesAvailable();
0161     if (reinserted_data_size - reinserted_data_read > 0)
0162         return ba + (reinserted_data_size - reinserted_data_read);
0163     else
0164         return ba;
0165 }
0166 
0167 void EncryptedPacketSocket::close()
0168 {
0169     sock->close();
0170 }
0171 
0172 bool EncryptedPacketSocket::connectTo(const QString &ip, Uint16 port)
0173 {
0174     // do a safety check
0175     if (ip.isNull() || ip.length() == 0)
0176         return false;
0177 
0178     return connectTo(net::Address(ip, port));
0179 }
0180 
0181 bool EncryptedPacketSocket::connectTo(const net::Address &addr)
0182 {
0183     // we don't wanna block the current thread so set non blocking
0184     sock->setBlocking(false);
0185     sock->setTOS(tos);
0186     if (sock->connectTo(addr))
0187         return true;
0188 
0189     return false;
0190 }
0191 
0192 void EncryptedPacketSocket::initCrypt(const bt::SHA1Hash &dkey, const bt::SHA1Hash &ekey)
0193 {
0194     delete enc;
0195     enc = new RC4Encryptor(dkey, ekey);
0196 }
0197 
0198 void EncryptedPacketSocket::disableCrypt()
0199 {
0200     delete enc;
0201     enc = nullptr;
0202 }
0203 
0204 bool EncryptedPacketSocket::ok() const
0205 {
0206     return sock->ok();
0207 }
0208 
0209 QString EncryptedPacketSocket::getRemoteIPAddress() const
0210 {
0211     return sock->getPeerName().toString();
0212 }
0213 
0214 bt::Uint16 EncryptedPacketSocket::getRemotePort() const
0215 {
0216     return sock->getPeerName().port();
0217 }
0218 
0219 net::Address EncryptedPacketSocket::getRemoteAddress() const
0220 {
0221     return sock->getPeerName();
0222 }
0223 
0224 void EncryptedPacketSocket::setRC4Encryptor(RC4Encryptor *e)
0225 {
0226     delete enc;
0227     enc = e;
0228 }
0229 
0230 void EncryptedPacketSocket::reinsert(const Uint8 *d, Uint32 size)
0231 {
0232     //      Out() << "Reinsert : " << size << endl;
0233     Uint32 off = 0;
0234     if (reinserted_data) {
0235         off = reinserted_data_size;
0236         reinserted_data = (Uint8 *)realloc(reinserted_data, reinserted_data_size + size);
0237         reinserted_data_size += size;
0238     } else {
0239         reinserted_data = new Uint8[size];
0240         reinserted_data_size = size;
0241     }
0242     memcpy(reinserted_data + off, d, size);
0243 }
0244 
0245 bool EncryptedPacketSocket::connecting() const
0246 {
0247     return sock->state() == net::SocketDevice::CONNECTING;
0248 }
0249 
0250 bool EncryptedPacketSocket::connectSuccesFull() const
0251 {
0252     return sock->connectSuccesFull();
0253 }
0254 
0255 void EncryptedPacketSocket::setRemoteAddress(const net::Address &addr)
0256 {
0257     sock->setRemoteAddress(addr);
0258 }
0259 
0260 void EncryptedPacketSocket::preProcess(Packet::Ptr packet)
0261 {
0262     if (enc)
0263         enc->encryptReplace(packet->getData(), packet->getDataLength());
0264 }
0265 
0266 void EncryptedPacketSocket::postProcess(Uint8 *data, Uint32 size)
0267 {
0268     if (enc)
0269         enc->decrypt(data, size);
0270 }
0271 
0272 }