337 lines
8.6 KiB
Markdown
337 lines
8.6 KiB
Markdown
# RdpBroker Protocol Specification
|
|
|
|
## Overview
|
|
|
|
This document describes the protocol between web-gateway and RdpBroker for user authentication and target management.
|
|
|
|
## Connection Flow
|
|
|
|
```
|
|
Web-Gateway RdpBroker Samba AD / Target RDP Servers
|
|
| | |
|
|
|--AUTH\n{user}\n{pass}\n----->| |
|
|
| |---LDAP Auth----------------->|
|
|
| |<----Auth Result--------------|
|
|
| | |
|
|
|<---{type:targets,targets:[]}| |
|
|
| OR | |
|
|
|<---{type:auth_failed}--------| |
|
|
| | |
|
|
|--SELECT\n{target_name}\n---->| |
|
|
| |---Connect to Target--------->|
|
|
|<---{type:rdp_ready}----------|<-----------------------------|
|
|
| | |
|
|
|<====== RDP Binary Data ======|<===== RDP Session ==========|
|
|
```
|
|
|
|
## Protocol Messages
|
|
|
|
### Phase 1: Authentication
|
|
|
|
#### Request Format (Web-Gateway → RdpBroker)
|
|
|
|
```
|
|
AUTH\n
|
|
username\n
|
|
password\n
|
|
```
|
|
|
|
**Example:**
|
|
```
|
|
AUTH
|
|
user@example.com
|
|
SecurePassword123
|
|
```
|
|
|
|
#### Success Response (RdpBroker → Web-Gateway)
|
|
|
|
**JSON Format:**
|
|
```json
|
|
{
|
|
"type": "auth_success",
|
|
"targets": [
|
|
{
|
|
"name": "Windows Server 2022",
|
|
"host": "ws2022.example.com",
|
|
"port": 3389,
|
|
"description": "Production Windows Server"
|
|
},
|
|
{
|
|
"name": "Development Server",
|
|
"host": "dev.example.com",
|
|
"port": 3389,
|
|
"description": "Development environment"
|
|
}
|
|
]
|
|
}
|
|
```
|
|
|
|
**Notes:**
|
|
- The message must end with `\n\n` (double newline) to signal end of JSON message
|
|
- Targets list is personalized based on user permissions/groups in Samba AD
|
|
- Empty array means user is authenticated but has no authorized targets
|
|
|
|
#### Failure Response (RdpBroker → Web-Gateway)
|
|
|
|
**JSON Format:**
|
|
```json
|
|
{
|
|
"type": "auth_failed",
|
|
"message": "Invalid credentials"
|
|
}
|
|
```
|
|
|
|
Followed by connection close.
|
|
|
|
**Possible error messages:**
|
|
- "Invalid credentials"
|
|
- "User account disabled"
|
|
- "LDAP connection failed"
|
|
- "User not authorized for any targets"
|
|
|
|
### Phase 2: Target Selection
|
|
|
|
#### Request Format (Web-Gateway → RdpBroker)
|
|
|
|
```
|
|
SELECT\n
|
|
target_name\n
|
|
```
|
|
|
|
**Example:**
|
|
```
|
|
SELECT
|
|
Windows Server 2022
|
|
```
|
|
|
|
**Notes:**
|
|
- Target name must match exactly one of the names from the targets list
|
|
- Connection should be rejected if target name is invalid or not in user's authorized list
|
|
|
|
#### Success Response (RdpBroker → Web-Gateway)
|
|
|
|
**JSON Format:**
|
|
```json
|
|
{
|
|
"type": "rdp_ready"
|
|
}
|
|
```
|
|
|
|
Followed by `\n\n`, then RDP binary data stream begins.
|
|
|
|
After this message, the connection transitions to raw RDP protocol forwarding mode.
|
|
|
|
#### Failure Response (RdpBroker → Web-Gateway)
|
|
|
|
**JSON Format:**
|
|
```json
|
|
{
|
|
"type": "error",
|
|
"message": "Target not available"
|
|
}
|
|
```
|
|
|
|
Followed by connection close.
|
|
|
|
**Possible error messages:**
|
|
- "Target not found"
|
|
- "Target not authorized for user"
|
|
- "Failed to connect to target server"
|
|
- "Target server unreachable"
|
|
|
|
### Phase 3: RDP Session
|
|
|
|
After `rdp_ready` message, all subsequent data is raw RDP protocol:
|
|
- Web-Gateway forwards mouse/keyboard events as RDP protocol data
|
|
- RdpBroker forwards screen updates as RDP protocol data
|
|
- Connection is bidirectional binary stream
|
|
|
|
## Implementation Guidelines for RdpBroker
|
|
|
|
### 1. Accept Connection
|
|
Listen on port 3389 (configurable via RDP_LISTEN_PORT)
|
|
|
|
### 2. Read Authentication Message
|
|
```c
|
|
char buffer[4096];
|
|
int bytes = read(client_fd, buffer, sizeof(buffer));
|
|
|
|
// Parse "AUTH\n{username}\n{password}\n"
|
|
char *lines[3];
|
|
int line_count = 0;
|
|
char *token = strtok(buffer, "\n");
|
|
while (token != NULL && line_count < 3) {
|
|
lines[line_count++] = token;
|
|
token = strtok(NULL, "\n");
|
|
}
|
|
|
|
if (strcmp(lines[0], "AUTH") != 0) {
|
|
send_error(client_fd, "Invalid protocol");
|
|
close(client_fd);
|
|
return;
|
|
}
|
|
|
|
char *username = lines[1];
|
|
char *password = lines[2];
|
|
```
|
|
|
|
### 3. Authenticate with Samba AD
|
|
```c
|
|
int auth_result = authenticate_user(username, password,
|
|
config->samba_server,
|
|
config->samba_port,
|
|
config->base_dn);
|
|
```
|
|
|
|
### 4. Get User's Authorized Targets
|
|
```c
|
|
rdp_target_t *user_targets[MAX_TARGETS];
|
|
int target_count = get_user_targets(username, config, user_targets);
|
|
```
|
|
|
|
**Recommended approach:**
|
|
- Query user's groups from LDAP
|
|
- Filter targets based on group membership or user attributes
|
|
- Return only targets the user is authorized to access
|
|
|
|
**Example YAML configuration:**
|
|
```yaml
|
|
targets:
|
|
- name: "Windows Server 2022"
|
|
host: "ws2022.example.com"
|
|
port: 3389
|
|
description: "Production Windows Server"
|
|
authorized_groups:
|
|
- "Domain Admins"
|
|
- "Server Operators"
|
|
|
|
- name: "Development Server"
|
|
host: "dev.example.com"
|
|
port: 3389
|
|
description: "Development environment"
|
|
authorized_groups:
|
|
- "Developers"
|
|
- "Domain Admins"
|
|
```
|
|
|
|
### 5. Send Targets List
|
|
```c
|
|
char json_response[8192];
|
|
snprintf(json_response, sizeof(json_response),
|
|
"{\"type\":\"auth_success\",\"targets\":[");
|
|
|
|
for (int i = 0; i < target_count; i++) {
|
|
char target_json[512];
|
|
snprintf(target_json, sizeof(target_json),
|
|
"%s{\"name\":\"%s\",\"host\":\"%s\",\"port\":%d,\"description\":\"%s\"}",
|
|
(i > 0 ? "," : ""),
|
|
user_targets[i]->name,
|
|
user_targets[i]->host,
|
|
user_targets[i]->port,
|
|
user_targets[i]->description);
|
|
strcat(json_response, target_json);
|
|
}
|
|
|
|
strcat(json_response, "]}\n\n");
|
|
write(client_fd, json_response, strlen(json_response));
|
|
```
|
|
|
|
### 6. Read Target Selection
|
|
```c
|
|
bytes = read(client_fd, buffer, sizeof(buffer));
|
|
|
|
// Parse "SELECT\n{target_name}\n"
|
|
if (strncmp(buffer, "SELECT\n", 7) != 0) {
|
|
send_error(client_fd, "Invalid protocol");
|
|
close(client_fd);
|
|
return;
|
|
}
|
|
|
|
char *target_name = buffer + 7;
|
|
char *newline = strchr(target_name, '\n');
|
|
if (newline) *newline = '\0';
|
|
|
|
// Verify target is in user's authorized list
|
|
rdp_target_t *selected_target = find_target_in_list(target_name,
|
|
user_targets,
|
|
target_count);
|
|
if (!selected_target) {
|
|
send_error(client_fd, "Target not authorized");
|
|
close(client_fd);
|
|
return;
|
|
}
|
|
```
|
|
|
|
### 7. Connect to Target and Start Forwarding
|
|
```c
|
|
int target_fd = connect_to_rdp_target(selected_target->host,
|
|
selected_target->port);
|
|
|
|
// Send ready message
|
|
char *ready_msg = "{\"type\":\"rdp_ready\"}\n\n";
|
|
write(client_fd, ready_msg, strlen(ready_msg));
|
|
|
|
// Start bidirectional forwarding
|
|
forward_rdp_connection(client_fd, target_fd);
|
|
```
|
|
|
|
## Security Considerations
|
|
|
|
1. **Always validate target selection** - User must be authorized for selected target
|
|
2. **Close on protocol errors** - Invalid messages should immediately close connection
|
|
3. **Timeout authentication** - Implement timeout for AUTH phase (e.g., 30 seconds)
|
|
4. **Rate limiting** - Prevent brute force attacks on authentication
|
|
5. **Logging** - Log all authentication attempts and target selections
|
|
6. **TLS/SSL** - Consider wrapping connection in TLS for production
|
|
|
|
## Testing
|
|
|
|
### Test Authentication Success
|
|
```bash
|
|
(echo -e "AUTH\nuser@example.com\nPassword123\n"; sleep 1) | nc rdpbroker 3389
|
|
```
|
|
|
|
Expected response:
|
|
```json
|
|
{"type":"auth_success","targets":[...]}
|
|
```
|
|
|
|
### Test Authentication Failure
|
|
```bash
|
|
(echo -e "AUTH\nuser@example.com\nWrongPassword\n"; sleep 1) | nc rdpbroker 3389
|
|
```
|
|
|
|
Expected response:
|
|
```json
|
|
{"type":"auth_failed","message":"Invalid credentials"}
|
|
```
|
|
|
|
### Test Target Selection
|
|
```bash
|
|
(echo -e "AUTH\nuser@example.com\nPassword123\n"; sleep 1; echo -e "SELECT\nWindows Server 2022\n"; sleep 1) | nc rdpbroker 3389
|
|
```
|
|
|
|
Expected response:
|
|
```json
|
|
{"type":"auth_success","targets":[...]}
|
|
|
|
{"type":"rdp_ready"}
|
|
|
|
[RDP binary data follows]
|
|
```
|
|
|
|
## Migration Notes
|
|
|
|
Existing RdpBroker implementations that present login/menu screens via RDP protocol will need to be refactored to:
|
|
|
|
1. Accept the new text-based protocol on initial connection
|
|
2. Parse AUTH and SELECT commands
|
|
3. Return JSON responses instead of RDP login screens
|
|
4. Only start RDP forwarding after receiving SELECT command
|
|
|
|
The advantage is that authentication and target selection now happen via structured protocol before RDP session starts, allowing:
|
|
- Better error handling in web UI
|
|
- User-specific target lists
|
|
- Cleaner separation of concerns
|
|
- Easier debugging and monitoring
|