# SCAR Chat - Authentication & Nickname System ## Overview The SCAR Chat system now includes user authentication with database-backed nicknames. Each client must login with valid credentials before they can send messages or perform actions. ## Authentication Flow ### Server-Side 1. **Client connects** via SSL/TLS 2. **Server waits for LOGIN message**: `LOGIN:username:password` 3. **Server validates credentials** against SQLite database 4. **If valid**: Server sends `LOGIN_SUCCESS:username` and accepts messages from this client 5. **If invalid**: Server sends `LOGIN_FAILED:reason` and blocks messages 6. **All messages must come from authenticated clients** - unauthenticated clients are rejected with `ERROR:Not authenticated` ### Client-Side (Android) 1. User enters server hostname and port 2. Click "Connect" to establish SSL connection 3. After connecting, username/password fields become enabled 4. User enters credentials and clicks "Login" 5. On successful login, credentials fields are disabled and user can send messages 6. All sent messages show the authenticated username in the format: `*{HH:MM:SS}* username: message` ## Message Format All messages now include timestamp and authenticated username: ``` *{HH:MM:SS}* username: message content ``` **Examples:** - `*{14:32:45}* alice: Hello everyone!` - `*{14:32:52}* admin: System message` - `*{14:33:01}* bob: Nice to meet you` ## Server Authentication Flow ### 1. Parse LOGIN Message ```cpp LOGIN:username:password ``` Server extracts username and password from the message format. ### 2. Database Lookup ```cpp if (global_db->authenticate_user(username, password)) { // Authentication successful nickname = username; authenticated = true; client_nicknames[ssl] = username; } ``` The database validates the credentials by: - Checking if user exists - Checking if user account is active - Computing SHA256(password + salt) and comparing with stored hash ### 3. Track Authenticated Client ```cpp std::map client_nicknames; // Track authenticated clients std::mutex nicknames_mutex; ``` The server maintains a map of SSL connections to usernames to ensure: - Only authenticated clients can send messages - Camera events are attributed to correct user - Disconnects are properly logged ### 4. Accept/Reject Messages **Authenticated clients:** - Messages are accepted and broadcast with nickname - Format: `*{timestamp}* nickname: message` - CAMERA_ENABLE/DISABLE events also use nickname **Unauthenticated clients:** - Messages are rejected - Response: `ERROR:Not authenticated. Send LOGIN:username:password` - Client must send LOGIN message first ## Server API ### Initialize with Database ```cpp // In main() global_db = new Database("scar_chat.db"); if (!global_db->initialize()) { std::cerr << "Failed to initialize database" << std::endl; return 1; } ``` ### Per-Client Handler ```cpp void handle_client(SSL *ssl, int client_socket) { std::string nickname; bool authenticated = false; // Wait for LOGIN message // Validate against database // If valid, set authenticated = true and nickname = username // Reject all messages from unauthenticated clients if (!authenticated) { SSL_write(ssl, error_msg); continue; } // Process authenticated messages } ``` ## Android Client Flow ### UI Components Added - **Username Input**: Text field (disabled until connected) - **Password Input**: Password field (disabled until connected) - **Login Button**: Sends LOGIN:username:password (disabled until connected) - **Connection Status**: Shows current connection and login state ### Login Handling ```java private void attemptLogin() { String username = usernameInput.getText().toString().trim(); String password = passwordInput.getText().toString().trim(); String loginCmd = "LOGIN:" + username + ":" + password; chatConnection.sendMessage(loginCmd); } ``` ### Response Handling ```java @Override public void onMessageReceived(String message) { if (message.startsWith("LOGIN_SUCCESS:")) { // Extract username currentUsername = message.substring("LOGIN_SUCCESS:".length()).trim(); // Enable chat connectionStatus.setText("Logged in as: " + currentUsername); loginBtn.setEnabled(false); } else if (message.startsWith("LOGIN_FAILED:")) { // Show error String reason = message.substring("LOGIN_FAILED:".length()).trim(); Toast.makeText(this, "Login failed: " + reason, Toast.LENGTH_SHORT).show(); } } ``` ### Send Messages with Nickname ```java private void sendMessage() { if (mainActivity.getCurrentUsername().isEmpty()) { Toast.makeText(getContext(), "Please login first", Toast.LENGTH_SHORT).show(); return; } String username = mainActivity.getCurrentUsername(); String timestamp = new SimpleDateFormat("HH:mm:ss").format(new Date()); String formattedMsg = "*{" + timestamp + "}* " + username + ": " + message; } ``` ## Database User Management ### Create Users for Testing ```bash cd build ./dbmanager register alice AlicePassword789 alice@scar.local user ./dbmanager register bob BobPassword000 bob@scar.local user ./dbmanager register admin AdminPass123 admin@scar.local admin ``` ### Verify Users ```bash ./dbmanager list ``` ### Test Authentication ```bash ./dbmanager authenticate alice AlicePassword789 ``` ## Running the System ### 1. Setup Database ```bash cd build ./dbmanager register alice AlicePassword789 alice@scar.local user ./dbmanager register bob BobPassword000 bob@scar.local user ``` ### 2. Start Server ```bash ./chat_server ../certs/server.crt ../certs/server.key ``` Server output: ``` Database initialized successfully SCAR Chat Server listening on port 42317 ``` ### 3. Connect Android Client 1. Open SCAR Chat app 2. Enter server hostname (e.g., "192.168.1.100") 3. Enter port (42317) 4. Click "Connect" 5. Username/Password fields become enabled 6. Enter credentials: alice / AlicePassword789 7. Click "Login" 8. Send messages - they will appear with nickname "alice" ### 4. Verify Server Logs ``` User authenticated: alice (FD: 4) User authenticated: bob (FD: 5) Received: *{14:32:45}* alice: Hello Bob! ``` ## Security Considerations 1. **Passwords are NOT transmitted in plain text** - TLS/SSL encrypts all traffic 2. **Passwords are stored securely** - SHA256 with unique salt per user 3. **Each connection is independent** - disconnecting doesn't affect other users 4. **Unauthenticated clients are isolated** - cannot access chat or perform actions ## Error Handling ### Server-Side Errors | Message | Meaning | |---------|---------| | `LOGIN_FAILED:Invalid credentials` | Username not found or password incorrect | | `ERROR:Not authenticated` | Client tried to send message without logging in | | `ERROR:Account inactive` | User account has been deactivated | ### Client-Side Errors | Error | Resolution | |-------|-----------| | "Not connected to server" | Click Connect first | | "Login failed: Invalid credentials" | Check username/password spelling | | "Please login first" | User must complete login before sending messages | ## Future Enhancements - Session tokens with expiration - Multiple devices per user - Rate limiting per user - Activity logging - User profile information - Message history per user - Direct messaging between users