| 2671 | } |
| 2672 | |
| 2673 | void NetworkBase::ServerHandleAuth(Connection& connection, Packet& packet) |
| 2674 | { |
| 2675 | if (connection.authStatus != Auth::ok) |
| 2676 | { |
| 2677 | auto* hostName = connection.socket->GetHostName(); |
| 2678 | auto gameversion = packet.readString(); |
| 2679 | auto name = packet.readString(); |
| 2680 | auto password = packet.readString(); |
| 2681 | auto pubkey = packet.readString(); |
| 2682 | uint32_t sigsize; |
| 2683 | packet >> sigsize; |
| 2684 | if (pubkey.empty()) |
| 2685 | { |
| 2686 | connection.authStatus = Auth::verificationFailure; |
| 2687 | } |
| 2688 | else |
| 2689 | { |
| 2690 | try |
| 2691 | { |
| 2692 | // RSA technically supports keys up to 65536 bits, so this is the |
| 2693 | // maximum signature size for now. |
| 2694 | constexpr auto MaxRSASignatureSizeInBytes = 8192; |
| 2695 | |
| 2696 | if (sigsize == 0 || sigsize > MaxRSASignatureSizeInBytes) |
| 2697 | { |
| 2698 | throw std::runtime_error("Invalid signature size"); |
| 2699 | } |
| 2700 | |
| 2701 | std::vector<uint8_t> signature; |
| 2702 | signature.resize(sigsize); |
| 2703 | |
| 2704 | const uint8_t* signatureData = packet.read(sigsize); |
| 2705 | if (signatureData == nullptr) |
| 2706 | { |
| 2707 | throw std::runtime_error("Failed to read packet."); |
| 2708 | } |
| 2709 | |
| 2710 | std::memcpy(signature.data(), signatureData, sigsize); |
| 2711 | |
| 2712 | auto ms = MemoryStream(pubkey.data(), pubkey.size()); |
| 2713 | if (!connection.key.LoadPublic(&ms)) |
| 2714 | { |
| 2715 | throw std::runtime_error("Failed to load public key."); |
| 2716 | } |
| 2717 | |
| 2718 | bool verified = connection.key.Verify(connection.challenge.data(), connection.challenge.size(), signature); |
| 2719 | const std::string hash = connection.key.PublicKeyHash(); |
| 2720 | if (verified) |
| 2721 | { |
| 2722 | LOG_VERBOSE("Connection %s: Signature verification ok. Hash %s", hostName, hash.c_str()); |
| 2723 | if (Config::Get().network.knownKeysOnly && _userManager.getUserByHash(hash) == nullptr) |
| 2724 | { |
| 2725 | LOG_VERBOSE("Connection %s: Hash %s, not known", hostName, hash.c_str()); |
| 2726 | connection.authStatus = Auth::unknownKeyDisallowed; |
| 2727 | } |
| 2728 | else |
| 2729 | { |
| 2730 | connection.authStatus = Auth::verified; |
nothing calls this directly
no test coverage detected