//go:build linux package host import ( "context" "crypto/ed25519" "crypto/sha256" "encoding/hex" "fmt" "io" "os" "strconv" "strings" "github.com/carlosframework/platform/internal/hostfloor" "github.com/carlosframework/platform/internal/hostwrite" "github.com/carlosframework/platform/internal/release" "golang.org/x/sys/unix" ) type productionStopControllers struct{} func (productionStopControllers) VerifiedController(ctx context.Context, pid int) (string, error) { if ctx.Err() != nil { return "", ctx.Err() } if pid <= 0 { return "", hostwrite.ErrUnavailable } boot, err := os.ReadFile("/proc/sys/kernel/random/boot_id") if err != nil { return "", err } raw, err := os.ReadFile(fmt.Sprintf("/proc/%d/stat", pid)) if err != nil { return "", err } end := strings.LastIndexByte(string(raw), ')') if end < 0 { return "", hostwrite.ErrUnavailable } fields := strings.Fields(string(raw)[end+1:]) if len(fields) < 20 { return "", hostwrite.ErrUnavailable } if _, err := strconv.ParseUint(fields[19], 10, 64); err != nil { return "", err } sum := sha256.Sum256([]byte(strings.TrimSpace(string(boot)) + "\x00" + strconv.Itoa(pid) + "\x00" + fields[19])) return hex.EncodeToString(sum[:]), nil } func readClaimEvidenceKey(path string) (ed25519.PrivateKey, error) { if os.Geteuid() != 0 { return nil, hostwrite.ErrUnavailable } f, err := hostfloor.OpenProtected(path) if err != nil { return nil, err } defer f.Close() var stat unix.Stat_t if err = unix.Fstat(int(f.Fd()), &stat); err != nil { return nil, err } if stat.Uid != 0 || stat.Mode&unix.S_IFMT != unix.S_IFREG || stat.Mode&0077 != 0 || stat.Nlink != 1 { return nil, hostwrite.ErrUnavailable } raw, err := io.ReadAll(io.LimitReader(f, 4097)) if err != nil || len(raw) > 4096 { return nil, hostwrite.ErrUnavailable } return release.ParseSigningKey(strings.TrimSpace(string(raw)), path) } func prepareClaimParticipationDirectory(path string) error { uid, gid, err := claimStateOwner() if err != nil { return err } if err = os.Mkdir(path, 0700); err != nil && !os.IsExist(err) { return err } return claimPrivatePathOwner(path, uid, gid, true) }