From df33123bd7f1e0cb4e98580b7e63818c82aa7206 Mon Sep 17 00:00:00 2001 From: Ophestra Umiker Date: Sat, 16 Nov 2024 21:19:45 +0900 Subject: app: integrate fsu This removes the dependency on external user switchers like sudo/machinectl and decouples fortify user ids from the passwd database. Signed-off-by: Ophestra Umiker --- cmd/fsu/parse.go | 77 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 77 insertions(+) create mode 100644 cmd/fsu/parse.go (limited to 'cmd/fsu/parse.go') diff --git a/cmd/fsu/parse.go b/cmd/fsu/parse.go new file mode 100644 index 00000000..d0298357 --- /dev/null +++ b/cmd/fsu/parse.go @@ -0,0 +1,77 @@ +package main + +import ( + "bufio" + "errors" + "fmt" + "log" + "os" + "strings" + "syscall" +) + +func parseUint32Fast(s string) (int, error) { + sLen := len(s) + if sLen < 1 { + return -1, errors.New("zero length string") + } + if sLen > 10 { + return -1, errors.New("string too long") + } + + n := 0 + for i, ch := range []byte(s) { + ch -= '0' + if ch > 9 { + return -1, fmt.Errorf("invalid character '%s' at index %d", string([]byte{ch}), i) + } + n = n*10 + int(ch) + } + return n, nil +} + +func parseConfig(p string, puid int) (fid int, ok bool) { + // refuse to run if fsurc is not protected correctly + if s, err := os.Stat(p); err != nil { + log.Fatal(err) + } else if s.Mode().Perm() != 0400 { + log.Fatal("bad fsurc perm") + } else if st := s.Sys().(*syscall.Stat_t); st.Uid != 0 || st.Gid != 0 { + log.Fatal("fsurc must be owned by uid 0") + } + + if r, err := os.Open(p); err != nil { + log.Fatal(err) + return -1, false + } else { + s := bufio.NewScanner(r) + var line int + for s.Scan() { + line++ + + // + lf := strings.SplitN(s.Text(), " ", 2) + if len(lf) != 2 { + log.Fatalf("invalid entry on line %d", line) + } + + var puid0 int + if puid0, err = parseUint32Fast(lf[0]); err != nil || puid0 < 1 { + log.Fatalf("invalid parent uid on line %d", line) + } + + ok = puid0 == puid + if ok { + // allowed fid range 0 to 99 + if fid, err = parseUint32Fast(lf[1]); err != nil || fid < 0 || fid > 99 { + log.Fatalf("invalid fortify uid on line %d", line) + } + return + } + } + if err = s.Err(); err != nil { + log.Fatalf("cannot read fsurc: %v", err) + } + return -1, false + } +} -- cgit v1.3.1