84 lines
2.9 KiB
Go
84 lines
2.9 KiB
Go
//go:build linux
|
|
|
|
package adminconsole
|
|
|
|
import (
|
|
"os"
|
|
"strconv"
|
|
"strings"
|
|
"testing"
|
|
)
|
|
|
|
func TestAdminCommandRequiresExplicitInteractiveStart(t *testing.T) {
|
|
tests := []struct {
|
|
command string
|
|
targets bool
|
|
allowed bool
|
|
}{
|
|
{"systemctl start Scert-admin", true, true},
|
|
{"/usr/bin/systemctl --system start Scert-admin.service --no-pager", true, true},
|
|
{"systemctl --wait --quiet start Scert-admin", true, true},
|
|
{"systemctl restart Scert-admin", true, false},
|
|
{"systemctl reload Scert-admin", true, false},
|
|
{"systemctl stop Scert-admin", true, false},
|
|
{"systemctl try-restart Scert-admin", true, false},
|
|
{"systemctl reload-or-restart Scert-admin", true, false},
|
|
{"systemctl try-reload-or-restart Scert-admin", true, false},
|
|
{"systemctl force-reload Scert-admin", true, false},
|
|
{"systemctl --no-block start Scert-admin", true, false},
|
|
{"systemctl --no-ask-password start Scert-admin", true, false},
|
|
{"systemctl --user start Scert-admin", true, false},
|
|
{"systemctl --host=other start Scert-admin", true, false},
|
|
{"systemctl start Scert-admin smail", true, false},
|
|
{"systemctl start Scert-*", true, false},
|
|
{"systemctl restart Scert-*", true, false},
|
|
{"systemctl status Scert-admin", false, false},
|
|
{"systemctl show Scert-admin", false, false},
|
|
{"systemctl list-jobs", false, false},
|
|
{"systemctl restart smail", false, false},
|
|
}
|
|
for _, test := range tests {
|
|
t.Run(test.command, func(t *testing.T) {
|
|
targets, allowed := classifyAdminCommand(strings.Fields(test.command))
|
|
if targets != test.targets || allowed != test.allowed {
|
|
t.Fatalf("target=%v allowed=%v", targets, allowed)
|
|
}
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestCallerIdentityIncludesStartTimeAndTerminal(t *testing.T) {
|
|
fields := strings.Fields("S 1 123 123 34817 123 0 0 0 0 0 0 0 0 0 0 0 1 0 9000")
|
|
data := "123 (name with ) spaces) " + strings.Join(fields, " ")
|
|
caller, err := parseCallerIdentity(123, data)
|
|
if err != nil || caller.pid != 123 || caller.started != 9000 || caller.group != 123 || caller.terminal != 34817 || caller.foreground != 123 {
|
|
t.Fatalf("identity=%+v err=%v", caller, err)
|
|
}
|
|
fields[19] = "9001"
|
|
reused, err := parseCallerIdentity(123, "123 (systemctl) "+strings.Join(fields, " "))
|
|
if err != nil || reused == caller {
|
|
t.Fatal("PID 重用未被识别")
|
|
}
|
|
fields[0] = "Z"
|
|
if _, err := parseCallerIdentity(123, "123 (systemctl) "+strings.Join(fields, " ")); err == nil {
|
|
t.Fatal("僵尸进程被接受")
|
|
}
|
|
self, err := readCallerIdentity(os.Getpid())
|
|
if err != nil || self.pid != os.Getpid() || self.started == 0 {
|
|
t.Fatalf("真实进程标识读取失败:%+v %v", self, err)
|
|
}
|
|
}
|
|
|
|
func TestCallerRequiresRootIdentity(t *testing.T) {
|
|
if !rootProcessStatus("Name:\tsystemctl\nUid:\t0\t0\t0\t0\n") {
|
|
t.Fatal("root 身份未通过")
|
|
}
|
|
for index := 0; index < 4; index++ {
|
|
ids := []string{"0", "0", "0", "0"}
|
|
ids[index] = strconv.Itoa(1000)
|
|
if rootProcessStatus("Uid:\t" + strings.Join(ids, "\t")) {
|
|
t.Fatal("非 root 身份被接受")
|
|
}
|
|
}
|
|
}
|