mirror of
https://github.com/Cockatrice/Cockatrice.git
synced 2026-10-28 18:40:48 -05:00
trusted_sources was checked with QString::contains. A dual-stack listener reports a local proxy as ::ffff:127.0.0.1, which never matches the default "127.0.0.1,::1". Behind nginx the forwarded client IP header was then ignored, every websocket user shared the proxy's address, and logins failed with "too many concurrent connections" once max_users_per_address was reached. Add isTrustedSource(), which parses each entry as a QHostAddress and compares exact addresses with IPv4-mapped addresses normalized, and use it at all four call sites. The ban command also read server/trusted_sources instead of the documented security/trusted_sources; it now uses the same getter. Entries that are not IP addresses are logged at startup since they no longer match anything. Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
59 lines
1.9 KiB
C++
59 lines
1.9 KiB
C++
#include "trusted_sources.h"
|
|
|
|
#include "gtest/gtest.h"
|
|
#include <QHostAddress>
|
|
|
|
namespace
|
|
{
|
|
|
|
const QString kDefault = QStringLiteral("127.0.0.1,::1");
|
|
|
|
TEST(TrustedSourcesTest, MatchesListedAddresses)
|
|
{
|
|
ASSERT_TRUE(isTrustedSource(kDefault, QHostAddress("127.0.0.1")));
|
|
ASSERT_TRUE(isTrustedSource(kDefault, QHostAddress("::1")));
|
|
ASSERT_FALSE(isTrustedSource(kDefault, QHostAddress("10.0.0.1")));
|
|
}
|
|
|
|
TEST(TrustedSourcesTest, MatchesIpv4MappedPeerAgainstPlainIpv4Entry)
|
|
{
|
|
// A dual-stack listener reports a local IPv4 proxy as ::ffff:127.0.0.1;
|
|
// it must still match the default 127.0.0.1 entry.
|
|
ASSERT_TRUE(isTrustedSource(kDefault, QHostAddress("::ffff:127.0.0.1")));
|
|
}
|
|
|
|
TEST(TrustedSourcesTest, MatchesPlainIpv4PeerAgainstMappedEntry)
|
|
{
|
|
ASSERT_TRUE(isTrustedSource("::ffff:192.0.2.7", QHostAddress("192.0.2.7")));
|
|
}
|
|
|
|
TEST(TrustedSourcesTest, DoesNotMatchSubstrings)
|
|
{
|
|
// Substring matching would let 27.0.0.1 or 0.0.1 pass as 127.0.0.1.
|
|
ASSERT_FALSE(isTrustedSource(kDefault, QHostAddress("27.0.0.1")));
|
|
ASSERT_FALSE(isTrustedSource("192.0.2.10", QHostAddress("192.0.2.1")));
|
|
ASSERT_FALSE(isTrustedSource(kDefault, QHostAddress(":")));
|
|
}
|
|
|
|
TEST(TrustedSourcesTest, ToleratesWhitespaceAndCase)
|
|
{
|
|
ASSERT_TRUE(isTrustedSource(" 192.0.2.7 , 2001:DB8::1 ", QHostAddress("2001:db8::1")));
|
|
ASSERT_TRUE(isTrustedSource(" 192.0.2.7 , 2001:DB8::1 ", QHostAddress("192.0.2.7")));
|
|
}
|
|
|
|
TEST(TrustedSourcesTest, IgnoresMalformedEntriesAndNullAddresses)
|
|
{
|
|
ASSERT_FALSE(isTrustedSource("not-an-ip,,", QHostAddress("127.0.0.1")));
|
|
ASSERT_FALSE(isTrustedSource("", QHostAddress("127.0.0.1")));
|
|
ASSERT_FALSE(isTrustedSource(kDefault, QHostAddress()));
|
|
}
|
|
|
|
TEST(TrustedSourcesTest, StringOverloadParsesAddress)
|
|
{
|
|
ASSERT_TRUE(isTrustedSource(kDefault, QStringLiteral("::ffff:127.0.0.1")));
|
|
ASSERT_FALSE(isTrustedSource(kDefault, QStringLiteral("27.0.0.1")));
|
|
ASSERT_FALSE(isTrustedSource(kDefault, QString()));
|
|
}
|
|
|
|
} // namespace
|