Skip to content

Commit c96f604

Browse files
committed
first commit
0 parents  commit c96f604

File tree

19 files changed

+3464
-0
lines changed

19 files changed

+3464
-0
lines changed

README.md

Lines changed: 160 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,160 @@
1+
# User Session Monitor Agent
2+
3+
## Overview
4+
5+
This application monitors Windows session events (logon, logoff, lock, unlock) and sends them to a specified API endpoint. It's designed to run as a Windows service on any version of Windows, collecting user session activity and securely transmitting it with an API key.
6+
7+
It is meant to be used as a service installed with the command `winagentUSM.exe --service install`.
8+
Then it will copy the .exe to a folder in `C:\ProgramData\UserSessionMon\` where it will create a default `config.ini`, local record keeping with `event_log.csv` and `error.log` for errors.
9+
All these files will have permissions restricted to SYSTEM and Administrators to view and edit.
10+
11+
## Core Features
12+
13+
- **Session Event Monitoring**: Detects and logs Windows user session events (logon, logoff, lock, unlock)
14+
- **Secure API Communication**: Sends event data to a REST API with API key authentication
15+
- **Configurable Settings**: Uses config.ini for API key, server URL, debug logging, and timezone
16+
- **CSV Logging**: Maintains a local CSV log of all events with send status
17+
- **Error Recovery**: Automatically retries sending failed events
18+
- **Windows Service**: Can be installed and managed as a Windows service
19+
- **Secure Permissions**: Ensures secure file permissions for config and logs
20+
21+
## Data Collected
22+
23+
For each session event, the following data is collected and sent:
24+
25+
- **Event Type**: Logon, Logoff, Lock, or Unlock
26+
- **Username**: The Windows username associated with the session
27+
- **Computer Name**: The hostname of the computer
28+
- **IP Address**: The primary IPv4 address of the computer
29+
- **Timestamp**: The time of the event (in the configured timezone)
30+
31+
## Configuration
32+
33+
After installing the application as a service with `winagentUSM.exe --service install`, the application will use a config.ini file located at `C:\ProgramData\UserSessionMon\config.ini` with the following structure:
34+
35+
```ini
36+
[API]
37+
api_key = 47959c6d5d8db64eb0ec3ad824ccbe82618632e2a58823d84aba92078da693fa
38+
server_url = https://192.168.27.1:8000
39+
debug_logs = false
40+
timezone = Europe/London
41+
health_check_interval = 30
42+
health_check_path = /api/health
43+
install_dir = C:\ProgramData\UserSessionMon
44+
```
45+
46+
You can modify these settings directly in the config file or use command-line options.
47+
48+
## Command-Line Usage
49+
50+
The application supports the following command-line options:
51+
52+
### Service Management
53+
54+
```
55+
winagentUSM.exe --service install # Install the Windows service
56+
winagentUSM.exe --service start # Start the service
57+
winagentUSM.exe --service stop # Stop the service
58+
winagentUSM.exe --service restart # Restart the service
59+
winagentUSM.exe --service remove # Remove the service
60+
winagentUSM.exe --service run # Run the service directly (for debugging)
61+
```
62+
63+
### Configuration
64+
65+
```
66+
winagentUSM.exe --api-key <key> # Update the API key
67+
winagentUSM.exe --url <url> # Update the server URL
68+
winagentUSM.exe --debug true|false # Enable or disable debug logging
69+
winagentUSM.exe --timezone <timezone> # Update the timezone (e.g., Europe/London)
70+
winagentUSM.exe --check-interval <mins> # Update health check interval (0 to disable)
71+
```
72+
73+
### Help
74+
75+
```
76+
winagentUSM.exe --help # Display help information
77+
```
78+
79+
## Health Checks
80+
81+
The application includes automatic health checks to ensure connectivity and retry failed events:
82+
83+
- **Startup Check**: Validates API key and server connectivity when the service starts
84+
- **Periodic Checks**: Runs every 30 minutes by default (configurable)
85+
- **Config Change Checks**: Triggered when configuration is updated via command-line flags
86+
- **Failed Event Retry**: Automatically retries sending failed events after successful health checks
87+
88+
### Health Check Configuration
89+
90+
- `health_check_interval`: Minutes between health checks (default: 30, set to 0 to disable)
91+
- `health_check_path`: API endpoint path for health checks (default: `/api/health`)
92+
93+
## Installation
94+
95+
To install as a Windows service:
96+
97+
1. Run Command Prompt or PowerShell as Administrator
98+
2. Navigate to the directory containing the executable
99+
3. Execute: `winagentUSM.exe --service install`
100+
4. (Optional) Configure: `winagentUSM.exe --url "https://your-server:8000" --api-key "your-api-key"`
101+
102+
## File Locations
103+
104+
- **Executable**: `C:\ProgramData\UserSessionMon\winagentUSM.exe` (after installation)
105+
- **Config**: `C:\ProgramData\UserSessionMon\config.ini`
106+
- **Event Log**: `C:\ProgramData\UserSessionMon\event_log.csv`
107+
- **Error Log**: `C:\ProgramData\UserSessionMon\error.log`
108+
- **Service Log**: `C:\ProgramData\UserSessionMon\session_monitor.log`
109+
110+
## Building from Source
111+
112+
### Prerequisites
113+
114+
- Go 1.20 or newer
115+
- Windows operating system
116+
- Administrator rights (for service installation)
117+
118+
### Build Steps
119+
120+
1. Clone the repository
121+
2. Navigate to the project directory
122+
3. Run the build command:
123+
124+
```
125+
go build -o winagentUSM.exe ./cmd/winagent
126+
```
127+
128+
## CSV Log Format
129+
130+
The CSV log file contains the following columns:
131+
132+
```
133+
eventtype,username,hostname,ipaddress,timestamp,send_status
134+
```
135+
136+
Where `send_status` is:
137+
- 0: Failed to send to API
138+
- 1: Successfully sent to API
139+
- 2: Successfully sent on retry
140+
141+
### Example CSV:
142+
```csv
143+
eventtype,username,hostname,ipaddress,timestamp,send_status
144+
Lock,Josh,DESKTOP-5D51HM9,192.168.66.34,2025-04-27T07:06:14Z,1
145+
Unlock,Josh,DESKTOP-5D51HM9,192.168.66.34,2025-04-27T07:06:24Z,1
146+
Lock,Josh,DESKTOP-5D51HM9,192.168.66.34,2025-04-27T07:08:30Z,1
147+
Unlock,Josh,DESKTOP-5D51HM9,192.168.66.34,2025-04-27T07:09:10Z,1
148+
Lock,Josh,DESKTOP-5D51HM9,192.168.66.34,2025-04-27T07:10:23Z,0
149+
Logon,Irena,DESKTOP-5D51HM9,192.168.66.34,2025-04-27T07:10:38Z,0
150+
Logoff,Irena,DESKTOP-5D51HM9,192.168.66.34,2025-04-27T07:10:51Z,0
151+
Unlock,Josh,DESKTOP-5D51HM9,192.168.66.34,2025-04-27T07:11:03Z,0
152+
```
153+
154+
## Troubleshooting
155+
156+
Common issues and solutions:
157+
158+
- **Service Won't Start**: Check `error.log` for details
159+
- **Events Not Being Sent**: Verify network connectivity and API endpoint availability
160+
- **Permission Errors**: Ensure the application is run as administrator

agent_icon.ico

953 Bytes
Binary file not shown.

api/client.go

Lines changed: 105 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,105 @@
1+
package api
2+
3+
import (
4+
"bytes"
5+
"crypto/tls"
6+
"encoding/json"
7+
"fmt"
8+
"net/http"
9+
"time"
10+
)
11+
12+
// EventData represents the data sent to the API
13+
type EventData struct {
14+
EventType string `json:"EventType"`
15+
UserName string `json:"UserName"`
16+
ComputerName string `json:"ComputerName"`
17+
IPAddress string `json:"IPAddress"`
18+
Timestamp string `json:"Timestamp"`
19+
Retry int `json:"retry,omitempty"`
20+
}
21+
22+
// Client represents an API client
23+
type Client struct {
24+
apiKey string
25+
serverURL string
26+
client *http.Client
27+
}
28+
29+
// NewClient creates a new API client
30+
func NewClient(apiKey, serverURL string) *Client {
31+
// Create HTTP client with TLS configuration that skips certificate validation
32+
transport := &http.Transport{
33+
TLSClientConfig: &tls.Config{
34+
InsecureSkipVerify: true,
35+
},
36+
}
37+
38+
client := &http.Client{
39+
Transport: transport,
40+
Timeout: 10 * time.Second,
41+
}
42+
43+
return &Client{
44+
apiKey: apiKey,
45+
serverURL: serverURL,
46+
client: client,
47+
}
48+
}
49+
50+
// SendEvent sends an event to the API
51+
func (c *Client) SendEvent(eventType, username, computerName, ipAddress, timestamp string, retry int) (bool, error) {
52+
// Create event data
53+
eventData := EventData{
54+
EventType: eventType,
55+
UserName: username,
56+
ComputerName: computerName,
57+
IPAddress: ipAddress,
58+
Timestamp: timestamp,
59+
}
60+
61+
// Add retry flag if this is a retry
62+
if retry > 0 {
63+
eventData.Retry = retry
64+
}
65+
66+
// Convert to JSON
67+
jsonData, err := json.Marshal(eventData)
68+
if err != nil {
69+
return false, fmt.Errorf("failed to marshal event data: %v", err)
70+
}
71+
72+
// Create request
73+
req, err := http.NewRequest("POST", fmt.Sprintf("%s/api/log_event", c.serverURL), bytes.NewBuffer(jsonData))
74+
if err != nil {
75+
return false, fmt.Errorf("failed to create request: %v", err)
76+
}
77+
78+
// Set headers
79+
req.Header.Set("Content-Type", "application/json")
80+
req.Header.Set("X-API-Key", c.apiKey)
81+
82+
// Send request
83+
resp, err := c.client.Do(req)
84+
if err != nil {
85+
return false, fmt.Errorf("failed to send request: %v", err)
86+
}
87+
defer resp.Body.Close()
88+
89+
// Check response status
90+
if resp.StatusCode != http.StatusOK && resp.StatusCode != http.StatusCreated {
91+
return false, fmt.Errorf("API returned non-success status: %d", resp.StatusCode)
92+
}
93+
94+
return true, nil
95+
}
96+
97+
// UpdateAPIKey updates the API key
98+
func (c *Client) UpdateAPIKey(apiKey string) {
99+
c.apiKey = apiKey
100+
}
101+
102+
// UpdateServerURL updates the server URL
103+
func (c *Client) UpdateServerURL(serverURL string) {
104+
c.serverURL = serverURL
105+
}

0 commit comments

Comments
 (0)