diff --git a/.github/workflows/security.yml b/.github/workflows/security.yml new file mode 100644 index 00000000..f2c42081 --- /dev/null +++ b/.github/workflows/security.yml @@ -0,0 +1,137 @@ +name: Security + +on: + push: + branches: [master] + pull_request: + branches: [master] + workflow_dispatch: + +permissions: + contents: read + +jobs: + codeql: + name: CodeQL (C/C++) + runs-on: ubuntu-24.04 + permissions: + actions: read + contents: read + security-events: write + steps: + - name: Checkout + uses: actions/checkout@v4 + with: + submodules: true + + - name: Install dependencies + run: | + sudo apt-get update + sudo apt-get install -y \ + cmake \ + build-essential \ + pkg-config \ + libsdl2-dev \ + libglew-dev \ + libglm-dev \ + libssl-dev \ + zlib1g-dev \ + libavformat-dev \ + libavcodec-dev \ + libswscale-dev \ + libavutil-dev \ + libunicorn-dev \ + libx11-dev + sudo apt-get install -y libstormlib-dev || true + + - name: Initialize CodeQL + uses: github/codeql-action/init@v3 + with: + languages: cpp + + - name: Build + run: | + cmake -S . -B build -DCMAKE_BUILD_TYPE=Release + cmake --build build --parallel $(nproc) + + - name: Analyze + uses: github/codeql-action/analyze@v3 + + semgrep: + name: Semgrep + runs-on: ubuntu-24.04 + steps: + - name: Checkout + uses: actions/checkout@v4 + with: + submodules: true + + - name: Set up Python + uses: actions/setup-python@v5 + with: + python-version: "3.x" + + - name: Install Semgrep + run: | + python -m pip install --upgrade pip + python -m pip install semgrep + + - name: Run Semgrep (security + secrets) + run: | + semgrep scan \ + --config p/security-audit \ + --config p/secrets \ + --error + + sanitizer-build: + name: Sanitizer Build (ASan/UBSan) + runs-on: ubuntu-24.04 + steps: + - name: Checkout + uses: actions/checkout@v4 + with: + submodules: true + + - name: Install dependencies + run: | + sudo apt-get update + sudo apt-get install -y \ + cmake \ + build-essential \ + pkg-config \ + libsdl2-dev \ + libglew-dev \ + libglm-dev \ + libssl-dev \ + zlib1g-dev \ + libavformat-dev \ + libavcodec-dev \ + libswscale-dev \ + libavutil-dev \ + libunicorn-dev \ + libx11-dev + sudo apt-get install -y libstormlib-dev || true + + - name: Configure (ASan/UBSan) + run: | + cmake -S . -B build \ + -DCMAKE_BUILD_TYPE=RelWithDebInfo \ + -DWOWEE_BUILD_TESTS=ON \ + -DCMAKE_C_FLAGS="-fsanitize=address,undefined -fno-omit-frame-pointer" \ + -DCMAKE_CXX_FLAGS="-fsanitize=address,undefined -fno-omit-frame-pointer" \ + -DCMAKE_EXE_LINKER_FLAGS="-fsanitize=address,undefined" \ + -DCMAKE_SHARED_LINKER_FLAGS="-fsanitize=address,undefined" + + - name: Build + run: cmake --build build --parallel $(nproc) + + - name: Run tests (if present) + env: + ASAN_OPTIONS: detect_leaks=1:halt_on_error=1 + UBSAN_OPTIONS: print_stacktrace=1:halt_on_error=1 + run: | + if [ -f build/CTestTestfile.cmake ] || [ -d build/tests ]; then + ctest --test-dir build --output-on-failure + else + echo "No tests configured; sanitizer build completed." + fi diff --git a/docs/authentication.md b/docs/authentication.md index c8b0b4f6..ff514399 100644 --- a/docs/authentication.md +++ b/docs/authentication.md @@ -286,7 +286,7 @@ std::string host = realm.address.substr(0, colonPos); uint16_t port = std::stoi(realm.address.substr(colonPos + 1)); ``` -**Realm address format:** `"127.0.0.1:8085"` +**Realm address format:** `"localhost:8085"` ### Phase 3: World Server Connection @@ -295,7 +295,7 @@ uint16_t port = std::stoi(realm.address.substr(colonPos + 1)); ```cpp game::GameHandler gameHandler; gameHandler.connect( - host, // e.g., "127.0.0.1" + host, // e.g., "localhost" port, // e.g., 8085 sessionKey, // 40 bytes from auth server accountName, // Same account @@ -447,7 +447,7 @@ void testCompleteAuthFlow() { // Real auth handler auth::AuthHandler auth; - auth.connect("127.0.0.1", 3724); + auth.connect("localhost", 3724); bool success = false; std::vector key; @@ -472,7 +472,7 @@ void testCompleteAuthFlow() { MockWorldServer worldServer(8085); game::GameHandler game; - game.connect("127.0.0.1", 8085, key, "TEST", 12340); + game.connect("localhost", 8085, key, "TEST", 12340); bool worldSuccess = false; game.setOnSuccess([&worldSuccess]() { diff --git a/docs/realm-list.md b/docs/realm-list.md index bba2a59a..3993a8db 100644 --- a/docs/realm-list.md +++ b/docs/realm-list.md @@ -28,7 +28,7 @@ struct Realm { uint8_t lock; // Lock status uint8_t flags; // Realm flags (bit 0x04 = has version info) std::string name; // Realm name (e.g., "My Private Server") - std::string address; // Server address (e.g., "127.0.0.1:8085") + std::string address; // Server address (e.g., "localhost:8085") float population; // Population level (0.0 to 2.0+) uint8_t characters; // Number of characters player has on this realm uint8_t timezone; // Timezone ID @@ -127,7 +127,7 @@ int main() { // Connect std::cout << "Connecting to authentication server..." << std::endl; - if (!auth.connect("127.0.0.1", 3724)) { + if (!auth.connect("localhost", 3724)) { std::cerr << "Connection failed" << std::endl; return 1; } @@ -218,7 +218,7 @@ int main() { std::cout << "Address: " << selectedRealm.address << std::endl; // TODO: Parse address and connect to world server - // Example: "127.0.0.1:8085" -> host="127.0.0.1", port=8085 + // Example: "localhost:8085" -> host="localhost", port=8085 } } @@ -424,7 +424,7 @@ For testing without a live server, you can create mock realms: Realm mockRealm; mockRealm.id = 1; mockRealm.name = "Test Realm"; -mockRealm.address = "127.0.0.1:8085"; +mockRealm.address = "localhost:8085"; mockRealm.icon = 1; mockRealm.lock = 0; mockRealm.flags = 0x04; // Has version info @@ -438,7 +438,7 @@ mockRealm.build = 12340; // Test parsing address std::string host = parseHost(mockRealm.address); -assert(host == "127.0.0.1"); +assert(host == "localhost"); uint16_t port = parsePort(mockRealm.address); assert(port == 8085); diff --git a/docs/server-setup.md b/docs/server-setup.md index 279fc51b..44a6b588 100644 --- a/docs/server-setup.md +++ b/docs/server-setup.md @@ -16,7 +16,7 @@ The authentication screen comes with local server defaults: | Setting | Default Value | Description | |---------|---------------|-------------| -| **Hostname** | 127.0.0.1 | Localhost (your machine) | +| **Hostname** | localhost | Localhost (your machine) | | **Port** | 3724 | Standard auth server port | | **Username** | (empty) | Your account username | | **Password** | (empty) | Your account password | @@ -120,16 +120,16 @@ nano authserver.conf **Key settings in `authserver.conf`:** ```ini -LoginDatabaseInfo = "127.0.0.1;3306;trinity;trinity;auth" +LoginDatabaseInfo = "localhost;3306;trinity;trinity;auth" RealmServerPort = 3724 -BindIP = "127.0.0.1" +BindIP = "localhost" ``` **Key settings in `worldserver.conf`:** ```ini -LoginDatabaseInfo = "127.0.0.1;3306;trinity;trinity;auth" -WorldDatabaseInfo = "127.0.0.1;3306;trinity;trinity;world" -CharacterDatabaseInfo = "127.0.0.1;3306;trinity;trinity;characters" +LoginDatabaseInfo = "localhost;3306;trinity;trinity;auth" +WorldDatabaseInfo = "localhost;3306;trinity;trinity;world" +CharacterDatabaseInfo = "localhost;3306;trinity;trinity;characters" DataDir = "/path/to/your/WoW-3.3.5a/Data" # Your WoW client data directory ``` @@ -154,7 +154,7 @@ account set gmlevel testuser 3 -1 In the worldserver console: ``` -realm add "Local Test Realm" 127.0.0.1:8085 0 1 +realm add "Local Test Realm" localhost:8085 0 1 ``` Or directly in database: @@ -162,7 +162,7 @@ Or directly in database: mysql -u trinity -ptrinity auth INSERT INTO realmlist (name, address, port, icon, realmflags, timezone, allowedSecurityLevel) -VALUES ('Local Test Realm', '127.0.0.1', 8085, 1, 0, 1, 0); +VALUES ('Local Test Realm', 'localhost', 8085, 1, 0, 1, 0); ``` ## Running the Server @@ -212,14 +212,14 @@ server shutdown 10 # Shutdown in 10 seconds ### 1. Start the Client ```bash -cd /home/k/Desktop/wowee/wowee +cd /path/to/wowee ./build/bin/wowee ``` ### 2. Login Screen You'll see the authentication screen with default values: -- **Hostname:** 127.0.0.1 (already set) +- **Hostname:** localhost (already set) - **Port:** 3724 (already set) - **Username:** (enter your account username) - **Password:** (enter your account password) @@ -291,7 +291,7 @@ ps aux | grep worldserver netstat -an | grep 8085 # Update realmlist address -UPDATE realmlist SET address='127.0.0.1' WHERE id=1; +UPDATE realmlist SET address='localhost' WHERE id=1; ``` ### Cannot Enter World @@ -335,13 +335,13 @@ ifconfig | grep inet Edit `authserver.conf`: ```ini -BindIP = "0.0.0.0" # Listen on all interfaces +BindIP = "" # Listen on all interfaces ``` Edit database: ```sql mysql -u trinity -ptrinity auth -UPDATE realmlist SET address='192.168.1.100' WHERE id=1; # Your local IP +UPDATE realmlist SET address='' WHERE id=1; # Your local IP ``` **3. Configure firewall:** @@ -351,7 +351,7 @@ sudo ufw allow 8085 # World server ``` **4. In wowee:** -- Change hostname to your server's local IP (e.g., 192.168.1.100) +- Change hostname to your server's local IP (e.g., ) - Keep port as 3724 - Connect @@ -366,7 +366,7 @@ For testing with a remote server (VPS, dedicated server): **Server configuration:** ```ini # authserver.conf -BindIP = "0.0.0.0" +BindIP = "" # Database UPDATE realmlist SET address='your.server.ip' WHERE id=1; @@ -600,7 +600,7 @@ server shutdown 10 - [ ] Account created with proper credentials - [ ] Firewall allows ports 3724 and 8085 - [ ] WOW_DATA_PATH set correctly (if using MPQ assets) -- [ ] Client can resolve hostname (127.0.0.1 for localhost) +- [ ] Client can resolve hostname (localhost for localhost) ## Next Steps diff --git a/include/ui/auth_screen.hpp b/include/ui/auth_screen.hpp index 65e943aa..af1088af 100644 --- a/include/ui/auth_screen.hpp +++ b/include/ui/auth_screen.hpp @@ -51,7 +51,7 @@ private: }; // UI state - char hostname[256] = "127.0.0.1"; + char hostname[256] = "localhost"; char username[256] = ""; char password[256] = ""; char pinCode[32] = "";