Session.cpp 3.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107
  1. #include "Session.h"
  2. #include <limits.h> // for CHAR_BIT
  3. #include <cstdint> // for uint8_t
  4. #include <functional> // for __base
  5. #include <memory> // for shared_ptr, unique_ptr, make_unique
  6. #include <random> // for default_random_engine, independent_bi...
  7. #include <type_traits> // for remove_extent_t
  8. #include <utility> // for move
  9. #include "ApResolve.h" // for ApResolve, cspot
  10. #include "AuthChallenges.h" // for AuthChallenges
  11. #include "BellLogger.h" // for AbstractLogger
  12. #include "Logger.h" // for CSPOT_LOG
  13. #include "LoginBlob.h" // for LoginBlob
  14. #include "Packet.h" // for Packet
  15. #include "PlainConnection.h" // for PlainConnection, timeoutCallback
  16. #include "ShannonConnection.h" // for ShannonConnection
  17. #include "NanoPBHelper.h" // for pbPutString, pbEncode, pbDecode
  18. #include "pb_decode.h"
  19. #include "protobuf/authentication.pb.h"
  20. using random_bytes_engine =
  21. std::independent_bits_engine<std::default_random_engine, CHAR_BIT, uint8_t>;
  22. using namespace cspot;
  23. Session::Session() {
  24. this->challenges = std::make_unique<cspot::AuthChallenges>();
  25. }
  26. Session::~Session() {}
  27. void Session::connect(std::unique_ptr<cspot::PlainConnection> connection) {
  28. this->conn = std::move(connection);
  29. conn->timeoutHandler = [this]() {
  30. return this->triggerTimeout();
  31. };
  32. auto helloPacket = this->conn->sendPrefixPacket(
  33. {0x00, 0x04}, this->challenges->prepareClientHello());
  34. auto apResponse = this->conn->recvPacket();
  35. CSPOT_LOG(info, "Received APHello response");
  36. auto solvedHello = this->challenges->solveApHello(helloPacket, apResponse);
  37. conn->sendPrefixPacket({}, solvedHello);
  38. CSPOT_LOG(debug, "Received shannon keys");
  39. // Generates the public and priv key
  40. this->shanConn = std::make_shared<ShannonConnection>();
  41. // Init shanno-encrypted connection
  42. this->shanConn->wrapConnection(this->conn, challenges->shanSendKey,
  43. challenges->shanRecvKey);
  44. }
  45. void Session::connectWithRandomAp() {
  46. auto apResolver = std::make_unique<ApResolve>("");
  47. auto conn = std::make_unique<cspot::PlainConnection>();
  48. conn->timeoutHandler = [this]() {
  49. return this->triggerTimeout();
  50. };
  51. auto apAddr = apResolver->fetchFirstApAddress();
  52. CSPOT_LOG(debug, "Connecting with AP <%s>", apAddr.c_str());
  53. conn->connect(apAddr);
  54. this->connect(std::move(conn));
  55. }
  56. std::vector<uint8_t> Session::authenticate(std::shared_ptr<LoginBlob> blob) {
  57. // save auth blob for reconnection purposes
  58. authBlob = blob;
  59. // prepare authentication request proto
  60. auto data = challenges->prepareAuthPacket(blob->authData, blob->authType,
  61. deviceId, blob->username);
  62. // Send login request
  63. this->shanConn->sendPacket(LOGIN_REQUEST_COMMAND, data);
  64. auto packet = this->shanConn->recvPacket();
  65. switch (packet.command) {
  66. case AUTH_SUCCESSFUL_COMMAND: {
  67. APWelcome welcome;
  68. CSPOT_LOG(debug, "Authorization successful");
  69. pbDecode(welcome, APWelcome_fields, packet.data);
  70. return std::vector<uint8_t>(welcome.reusable_auth_credentials.bytes,
  71. welcome.reusable_auth_credentials.bytes +
  72. welcome.reusable_auth_credentials.size);
  73. break;
  74. }
  75. case AUTH_DECLINED_COMMAND: {
  76. CSPOT_LOG(error, "Authorization declined");
  77. break;
  78. }
  79. default:
  80. CSPOT_LOG(error, "Unknown auth fail code %d", packet.command);
  81. }
  82. return std::vector<uint8_t>(0);
  83. }
  84. void Session::close() {
  85. this->conn->close();
  86. }