7.3 KiB
7.3 KiB
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
- Client connects via SSL/TLS
- Server waits for LOGIN message:
LOGIN:username:password - Server validates credentials against SQLite database
- If valid: Server sends
LOGIN_SUCCESS:usernameand accepts messages from this client - If invalid: Server sends
LOGIN_FAILED:reasonand blocks messages - All messages must come from authenticated clients - unauthenticated clients are rejected with
ERROR:Not authenticated
Client-Side (Android)
- User enters server hostname and port
- Click "Connect" to establish SSL connection
- After connecting, username/password fields become enabled
- User enters credentials and clicks "Login"
- On successful login, credentials fields are disabled and user can send messages
- 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
LOGIN:username:password
Server extracts username and password from the message format.
2. Database Lookup
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
std::map<SSL*, std::string> 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
// 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
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
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
@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
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
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
./dbmanager list
Test Authentication
./dbmanager authenticate alice AlicePassword789
Running the System
1. Setup Database
cd build
./dbmanager register alice AlicePassword789 alice@scar.local user
./dbmanager register bob BobPassword000 bob@scar.local user
2. Start Server
./chat_server ../certs/server.crt ../certs/server.key
Server output:
Database initialized successfully
SCAR Chat Server listening on port 42317
3. Connect Android Client
- Open SCAR Chat app
- Enter server hostname (e.g., "192.168.1.100")
- Enter port (42317)
- Click "Connect"
- Username/Password fields become enabled
- Enter credentials: alice / AlicePassword789
- Click "Login"
- 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
- Passwords are NOT transmitted in plain text - TLS/SSL encrypts all traffic
- Passwords are stored securely - SHA256 with unique salt per user
- Each connection is independent - disconnecting doesn't affect other users
- 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