File indexing completed on 2025-01-05 04:37:21
0001 /* 0002 SPDX-FileCopyrightText: 2005 Joris Guisson <joris.guisson@gmail.com> 0003 0004 SPDX-License-Identifier: GPL-2.0-or-later 0005 */ 0006 #include "authenticate.h" 0007 #include "peerconnector.h" 0008 #include <mse/encryptedpacketsocket.h> 0009 #include <net/socks.h> 0010 #include <peer/accessmanager.h> 0011 #include <util/log.h> 0012 #include <utp/utpsocket.h> 0013 0014 namespace bt 0015 { 0016 Authenticate::Authenticate(const net::Address &addr, TransportProtocol proto, const SHA1Hash &info_hash, const PeerID &peer_id, PeerConnector::WPtr pcon) 0017 : info_hash(info_hash) 0018 , our_peer_id(peer_id) 0019 , addr(addr) 0020 , pcon(pcon) 0021 , socks(nullptr) 0022 { 0023 finished = succes = false; 0024 if (proto == TCP) 0025 sock = mse::EncryptedPacketSocket::Ptr(new mse::EncryptedPacketSocket(addr.ipVersion())); 0026 else 0027 sock = mse::EncryptedPacketSocket::Ptr(new mse::EncryptedPacketSocket(new utp::UTPSocket())); 0028 0029 Out(SYS_CON | LOG_NOTICE) << "Initiating connection to " << addr.toString() << " via (" << (proto == TCP ? "TCP" : "UTP") << ")" << endl; 0030 if (net::Socks::enabled()) { 0031 socks = new net::Socks(sock, addr); 0032 switch (socks->setup()) { 0033 case net::Socks::FAILED: 0034 Out(SYS_CON | LOG_NOTICE) << "Failed to connect to " << addr.toString() << " via socks server " << endl; 0035 // Don't call onFinish here, will lead to problems 0036 // Instead change the interval of timeout timer, to force a failure 0037 timer.setInterval(1); 0038 break; 0039 case net::Socks::CONNECTED: 0040 delete socks; 0041 socks = nullptr; 0042 connected(); 0043 break; 0044 default: 0045 break; 0046 } 0047 } else { 0048 if (sock->connectTo(addr)) { 0049 connected(); 0050 } else if (sock->connecting()) { 0051 // do nothing the monitor will notify us when we are connected 0052 } else { 0053 // Don't call onFinish here, will lead to problems 0054 // Instead change the interval of timeout timer, to force a failure 0055 timer.setInterval(1); 0056 } 0057 } 0058 } 0059 0060 Authenticate::~Authenticate() 0061 { 0062 delete socks; 0063 } 0064 0065 void Authenticate::onReadyWrite() 0066 { 0067 if (!sock) 0068 return; 0069 0070 if (socks) { 0071 switch (socks->onReadyToWrite()) { 0072 case net::Socks::FAILED: 0073 Out(SYS_CON | LOG_NOTICE) << "Failed to connect to socks server " << endl; 0074 onFinish(false); 0075 break; 0076 case net::Socks::CONNECTED: 0077 delete socks; 0078 socks = nullptr; 0079 connected(); 0080 break; 0081 default: 0082 break; 0083 } 0084 } else if (sock->connectSuccesFull()) { 0085 connected(); 0086 } else { 0087 onFinish(false); 0088 } 0089 } 0090 0091 void Authenticate::onReadyRead() 0092 { 0093 if (!sock) 0094 return; 0095 0096 if (!socks) { 0097 AuthenticateBase::onReadyRead(); 0098 } else { 0099 switch (socks->onReadyToRead()) { 0100 case net::Socks::FAILED: 0101 Out(SYS_CON | LOG_NOTICE) << "Failed to connect to host via socks server " << endl; 0102 onFinish(false); 0103 break; 0104 case net::Socks::CONNECTED: 0105 // connection established, so get rid of socks shit 0106 delete socks; 0107 socks = nullptr; 0108 connected(); 0109 if (sock->bytesAvailable() > 0) 0110 AuthenticateBase::onReadyRead(); 0111 break; 0112 default: 0113 break; 0114 } 0115 } 0116 } 0117 0118 void Authenticate::connected() 0119 { 0120 sendHandshake(info_hash, our_peer_id); 0121 } 0122 0123 void Authenticate::onFinish(bool succes) 0124 { 0125 Out(SYS_CON | LOG_NOTICE) << "Authentication to " << addr.toString() << " : " << (succes ? "ok" : "failure") << endl; 0126 finished = true; 0127 this->succes = succes; 0128 0129 if (!succes) 0130 sock.clear(); 0131 0132 timer.stop(); 0133 PeerConnector::Ptr pc = pcon.toStrongRef(); 0134 if (pc) 0135 pc->authenticationFinished(this, succes); 0136 } 0137 0138 void Authenticate::handshakeReceived(bool full) 0139 { 0140 const Uint8 *hs = handshake; 0141 if (!AccessManager::instance().allowed(addr)) { 0142 Out(SYS_CON | LOG_DEBUG) << "The IP address " << addr.toString() << " is blocked " << endl; 0143 onFinish(false); 0144 return; 0145 } 0146 0147 SHA1Hash rh(hs + 28); 0148 if (rh != info_hash) { 0149 Out(SYS_CON | LOG_DEBUG) << "Wrong info_hash : " << rh.toString() << endl; 0150 onFinish(false); 0151 return; 0152 } 0153 0154 if (full) { 0155 char tmp[21]; 0156 tmp[20] = '\0'; 0157 memcpy(tmp, hs + 48, 20); 0158 peer_id = PeerID(tmp); 0159 0160 if (our_peer_id == peer_id) { 0161 Out(SYS_CON | LOG_DEBUG) << "Lets not connect to our selves " << endl; 0162 onFinish(false); 0163 return; 0164 } 0165 0166 // only finish when the handshake was fully received 0167 onFinish(true); 0168 } 0169 } 0170 0171 void Authenticate::stop() 0172 { 0173 if (finished) 0174 return; 0175 0176 onFinish(false); 0177 } 0178 0179 } 0180 0181 #include "moc_authenticate.cpp"