aboutsummaryrefslogtreecommitdiffhomepage
path: root/cmd/fsu/parse.go
diff options
context:
space:
mode:
Diffstat (limited to 'cmd/fsu/parse.go')
-rw-r--r--cmd/fsu/parse.go77
1 files changed, 77 insertions, 0 deletions
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++
+
+ // <puid> <fid>
+ 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
+ }
+}