This commit is contained in:
Stefan Etringer 2025-07-02 11:43:45 +00:00
parent 40b552fd7b
commit 29ab1934b2
12 changed files with 89 additions and 24 deletions

View File

@ -340,7 +340,7 @@ func main() {
// defer db.Close()
name := randomname.GenerateRandomName()
fmt.Sprintf("Server instance: %s", name)
log.Println("Server instance: ", name)
webServer := &http.Server {
Addr: ":3333",

View File

@ -19,7 +19,6 @@ var (
logMutex sync.Mutex
logLimit = 100
// LogEntries []string
)
const (
@ -69,7 +68,7 @@ func InsertLog(level LogLevel, message string) error {
lite_dbMutex.Lock()
defer lite_dbMutex.Unlock()
// Future use may fulfill multiple transactions, a transaction is used
// Future use may fulfill multiple transactions
tx, err := Lite_db.Begin()
if err != nil {
return fmt.Errorf("Error starting transaction: %w", err)
@ -77,9 +76,7 @@ func InsertLog(level LogLevel, message string) error {
message = strings.ReplaceAll(message, `"`, `\"`)
// insertQuery := `INSERT INTO logs (message) VALUES (?)`
insertQuery := `INSERT INTO logs (message, level) VALUES (?, ?)`
// _, err := Lite_db.Exec(insertQuery, message, level)
_, err = tx.Exec(insertQuery, message, level)
if err != nil {
@ -120,7 +117,6 @@ func FetchLogs(limit int, levels []string) ([]LogEntry, error) {
args = append(args, limit)
// rows, err := Lite_db.Query(query, level, limit)
rows, err := Lite_db.Query(query, args...)
if err != nil {
return nil, fmt.Errorf("Error fetching logs: %w", err)

View File

@ -3,6 +3,7 @@ package randomname
import (
"math/rand"
)
func GenerateRandomName() string {
prefix := prefixes[rand.Intn(len(prefixes))]
suffix := suffixes[rand.Intn(len(suffixes))]

View File

@ -6,7 +6,6 @@ import (
"encoding/json"
"strconv"
"log"
// "gontrol/src/logger"
_ "github.com/go-sql-driver/mysql"
)
@ -23,8 +22,6 @@ type Agent struct {
HostName string `json:"HostName"`
}
// var db *sql.DB
func DeleteAgent(db *sql.DB, w http.ResponseWriter, r *http.Request, agentID string) ([]Agent, error) {
query := "DELETE FROM agents WHERE agentId = ?"
_, err := db.Exec(query, agentID)
@ -170,6 +167,5 @@ func GetAgentIds(db *sql.DB, w http.ResponseWriter, r *http.Request) {
agentIds = append(agentIds, strconv.Itoa(id))
}
// ocket.go.Header().Set("Content-Type", "application/json")
json.NewEncoder(w).Encode(agentIds)
}

View File

@ -81,12 +81,11 @@ func registerAgent(agentName, agentId, agentIp, agentType, addPort, hostname str
return err
}
// log.Printf("Agent %s successfully registered.", agentName)
}
func getAgentDetails(agentId string) (*api.Agent, error) {
agentURL := "http://localhost:3333/agents/" + agentId
// var ids []string
resp, err := http.Get(agentURL)
if err != nil {
log.Printf("Failed to make GET request: %s", err)
@ -130,9 +129,8 @@ func containsId(ids []string, agentId string) bool {
}
func getAgentIds() ([]string, error) {
idURL := "http://localhost:3333/agentIds"
// var ids []string
resp, err := http.Get(idURL)
if err != nil {
log.Printf("Failed to make GET request: %s", err)
@ -178,8 +176,6 @@ func (wsh webSocketHandler) ServeHTTP(w http.ResponseWriter, r *http.Request){
agentType := r.URL.Query().Get("agentType")
hostName := r.URL.Query().Get("hostname")
agentName := ""
log.Println("addPort is the following")
log.Println(r.URL.Query().Get("addPort"))
addPort := ""
if len(r.URL.Query().Get("addPort")) > 0 {

View File

@ -74,7 +74,8 @@ async function updateGraph(agentData) {
const status = agent.status;
if (id && name) {
let nodeColor = (status === 'Connected') ? '#28a745' : '#dc3545'; // Green for connected, Red for disconnected
// let nodeColor = (status === 'Connected') ? '#28a745' : '#dc3545'; // Green for connected, Red for disconnected
let nodeBg = (status === 'Connected') ? 'url(static/computer-online.svg)' : 'url(static/computer-offline.svg)'; // Green for connected, Red for disconnected
cy.add({
group: 'nodes',
@ -86,7 +87,11 @@ async function updateGraph(agentData) {
ip: agent.IPv4Address
},
style: {
'background-color': nodeColor,
// 'background-color': '#f8f9fa',
'background-opacity': '0',
'background-image': nodeBg,
'background-fit': 'contain',
'background-clip': 'none',
'label': name, // Display agent's name
'color': 'white',
'text-outline-width': 2,
@ -115,7 +120,11 @@ async function updateGraph(agentData) {
ip: 'N/A'
},
style: {
'background-color': '#6c757d', // Gray for target node
// 'background-color': '#6c757d', // Gray for target node
'background-opacity': '0',
'background-image': 'url(static/server-online.svg)',
'background-fit': 'contain',
'background-clip': 'none',
'label': 'g2',
'color': 'white',
'text-outline-width': 2,

17
static/computer-offline.svg Executable file
View File

@ -0,0 +1,17 @@
<?xml version="1.0" encoding="UTF-8"?>
<svg width="120" height="100" viewBox="0 0 120 100" xmlns="http://www.w3.org/2000/svg">
<!-- Monitor -->
<rect x="15" y="15" width="90" height="55" rx="6" ry="6" fill="none" stroke="black" stroke-width="4"/>
<!-- Status circle (offline) -->
<circle cx="60" cy="42.5" r="17" fill="red"/>
<!-- Cross -->
<path d="M51 33.5 L69 51.5 M69 33.5 L51 51.5" stroke="white" stroke-width="4" fill="none" stroke-linecap="round" stroke-linejoin="round"/>
<!-- Stand -->
<rect x="50" y="70" width="20" height="10" fill="black"/>
<!-- Base -->
<rect x="35" y="80" width="50" height="8" fill="black"/>
</svg>

After

Width:  |  Height:  |  Size: 655 B

17
static/computer-online.svg Executable file
View File

@ -0,0 +1,17 @@
<?xml version="1.0" encoding="UTF-8"?>
<svg width="120" height="100" viewBox="0 0 120 100" xmlns="http://www.w3.org/2000/svg">
<!-- Monitor -->
<rect x="15" y="15" width="90" height="55" rx="6" ry="6" fill="none" stroke="black" stroke-width="4"/>
<!-- Status circle (online) -->
<circle cx="60" cy="42.5" r="17" fill="green"/>
<!-- Check mark -->
<path d="M54 42.5 L58 46.5 L66 38.5" stroke="white" stroke-width="4" fill="none" stroke-linecap="round" stroke-linejoin="round"/>
<!-- Stand -->
<rect x="50" y="70" width="20" height="10" fill="black"/>
<!-- Base -->
<rect x="35" y="80" width="50" height="8" fill="black"/>
</svg>

After

Width:  |  Height:  |  Size: 652 B

View File

@ -1,13 +1,16 @@
const helpMsg = `
This is a non interactive Webshell with an interactive mode, including some
additional features to ease communications between server and client.
This is a shell in the browser, a web shell.
It includes a non-interactive shell with an optional interactive mode.
Furthermore, additional commands to ease communications between server
and client.
Available Commands:
upload Upload files to the server through the file selector of the browser.
download <file> Download files from the server to your local download directory.
theme <theme> Change the colorscheme of the shell. Type theme to get an overview of all colorschemes.
start-interactive Opens a bash shell in an interactive terminal. Type ctrl+d to go back to non-interactive mode.
`
// const helpMsg = 'This is a non interactive Webshell including some additional features to ease communications between server and client.\n Available Commands:\n upload\t\t\t\tUpload files to the server through the file selector of the browser.\n download <file>\t\t\tDownload files from the server to your local download directory.\n theme <theme>\t\t\tChange the colorscheme of the shell. Type theme to get an overview of all colorschemes.\n start-interactive\t\t\tOpens a bash shell in an interactive terminal. Type ctrl+d to exi the interactive shell.'
document.addEventListener("DOMContentLoaded", function() {
const input = document.getElementById("command-input");

15
static/server-offline.svg Executable file
View File

@ -0,0 +1,15 @@
<?xml version="1.0" encoding="UTF-8"?>
<svg width="100" height="120" viewBox="0 0 100 120" xmlns="http://www.w3.org/2000/svg">
<!-- Server body -->
<rect x="20" y="15" width="60" height="90" rx="6" ry="6" fill="none" stroke="black" stroke-width="4"/>
<!-- Server panel lines -->
<line x1="25" y1="40" x2="75" y2="40" stroke="black" stroke-width="2"/>
<line x1="25" y1="65" x2="75" y2="65" stroke="black" stroke-width="2"/>
<!-- Status circle (offline) -->
<circle cx="50" cy="90" r="13" fill="red"/>
<!-- Cross -->
<path d="M44 84 L56 96 M56 84 L44 96" stroke="white" stroke-width="3" fill="none" stroke-linecap="round" stroke-linejoin="round"/>
</svg>

After

Width:  |  Height:  |  Size: 674 B

15
static/server-online.svg Executable file
View File

@ -0,0 +1,15 @@
<?xml version="1.0" encoding="UTF-8"?>
<svg width="100" height="120" viewBox="0 0 100 120" xmlns="http://www.w3.org/2000/svg">
<!-- Server body -->
<rect x="20" y="15" width="60" height="90" rx="6" ry="6" fill="none" stroke="black" stroke-width="4"/>
<!-- Server panel lines -->
<line x1="25" y1="40" x2="75" y2="40" stroke="black" stroke-width="2"/>
<line x1="25" y1="65" x2="75" y2="65" stroke="black" stroke-width="2"/>
<!-- Status circle (online) -->
<circle cx="50" cy="90" r="13" fill="green"/>
<!-- Check mark -->
<path d="M45 89 L48 93 L55 85" stroke="white" stroke-width="3" fill="none" stroke-linecap="round" stroke-linejoin="round"/>
</svg>

After

Width:  |  Height:  |  Size: 673 B

View File

@ -27,8 +27,8 @@ function getQueryParam(name) {
function makeWsUrl() {
const proxyIp = getQueryParam("ip"); // "10.0.0.42" if you came via /proxyAgent
const proxyPort = getQueryParam("port"); // "8080"
const usingProxy = proxyIp && proxyPort; // truthy only in that case
const proxyPort = getQueryParam("port");
const usingProxy = proxyIp && proxyPort; // true only in that case
if (usingProxy) {
// Build ws(s)://<main-server>/proxyAgent/terminal?ip=…&port=…