#include "Session.h" #include // for CHAR_BIT #include // for uint8_t #include // for __base #include // for shared_ptr, unique_ptr, make_unique #include // for default_random_engine, independent_bi... #include // for remove_extent_t #include // for move #include "ApResolve.h" // for ApResolve, cspot #include "AuthChallenges.h" // for AuthChallenges #include "BellLogger.h" // for AbstractLogger #include "Logger.h" // for CSPOT_LOG #include "LoginBlob.h" // for LoginBlob #include "Packet.h" // for Packet #include "PlainConnection.h" // for PlainConnection, timeoutCallback #include "ShannonConnection.h" // for ShannonConnection #include "NanoPBHelper.h" // for pbPutString, pbEncode, pbDecode #include "pb_decode.h" #include "protobuf/authentication.pb.h" using random_bytes_engine = std::independent_bits_engine; using namespace cspot; Session::Session() { this->challenges = std::make_unique(); } Session::~Session() {} void Session::connect(std::unique_ptr connection) { this->conn = std::move(connection); conn->timeoutHandler = [this]() { return this->triggerTimeout(); }; auto helloPacket = this->conn->sendPrefixPacket( {0x00, 0x04}, this->challenges->prepareClientHello()); auto apResponse = this->conn->recvPacket(); CSPOT_LOG(info, "Received APHello response"); auto solvedHello = this->challenges->solveApHello(helloPacket, apResponse); conn->sendPrefixPacket({}, solvedHello); CSPOT_LOG(debug, "Received shannon keys"); // Generates the public and priv key this->shanConn = std::make_shared(); // Init shanno-encrypted connection this->shanConn->wrapConnection(this->conn, challenges->shanSendKey, challenges->shanRecvKey); } void Session::connectWithRandomAp() { auto apResolver = std::make_unique(""); auto conn = std::make_unique(); conn->timeoutHandler = [this]() { return this->triggerTimeout(); }; auto apAddr = apResolver->fetchFirstApAddress(); CSPOT_LOG(debug, "Connecting with AP <%s>", apAddr.c_str()); conn->connect(apAddr); this->connect(std::move(conn)); } std::vector Session::authenticate(std::shared_ptr blob) { // save auth blob for reconnection purposes authBlob = blob; // prepare authentication request proto auto data = challenges->prepareAuthPacket(blob->authData, blob->authType, deviceId, blob->username); // Send login request this->shanConn->sendPacket(LOGIN_REQUEST_COMMAND, data); auto packet = this->shanConn->recvPacket(); switch (packet.command) { case AUTH_SUCCESSFUL_COMMAND: { APWelcome welcome; CSPOT_LOG(debug, "Authorization successful"); pbDecode(welcome, APWelcome_fields, packet.data); return std::vector(welcome.reusable_auth_credentials.bytes, welcome.reusable_auth_credentials.bytes + welcome.reusable_auth_credentials.size); break; } case AUTH_DECLINED_COMMAND: { CSPOT_LOG(error, "Authorization declined"); break; } default: CSPOT_LOG(error, "Unknown auth fail code %d", packet.command); } return std::vector(0); } void Session::close() { this->conn->close(); }