factotum.go (1614B)
1 package lib9p 2 3 import ( 4 "context" 5 "fmt" 6 "io" 7 "log" 8 "os" 9 ) 10 11 type AuthInfo struct { 12 cuid string // caller id 13 suid string // server id 14 cap string // capability 15 nsecret int // length of secret 16 secret string 17 } 18 19 func SetFactotum(s *Server, rpcpath string) error { 20 s.Auth = func(ctx context.Context, r *request) error { 21 ifcall := r.ifcall.(*TAuth) // TODO: need assertion? 22 rpcfile, err := os.OpenFile(rpcpath, os.O_RDWR, 0) 23 if err != nil { 24 return fmt.Errorf("openfile: %v", err) 25 } 26 cr, sw := io.Pipe() 27 sr, cw := io.Pipe() 28 // TODO: close rpcfile. 29 // TODO: check race condition. Can I ignore? 30 afile := &AuthFile{ 31 // TODO: BUG: allocate Qid 32 Qid: Qid{Type: QTAUTH, Vers: 0, Path: ^uint64(0)}, 33 Uname: ifcall.Uname, // TODO: need to check. 34 Aname: ifcall.Aname, 35 AuthOK: false, 36 W: cw, 37 R: cr, 38 } 39 r.afid.file = afile 40 runAuth(ctx, rpcfile, afile, sr, sw) 41 r.ofcall = &RAuth{Tag: ifcall.Tag, Aqid: afile.Qid} 42 return nil 43 } 44 return nil 45 } 46 47 func runAuth(ctx context.Context, rpcfile *os.File, afile *AuthFile, r io.Reader, w io.Writer) { 48 buf := make([]byte, 1024) 49 for { 50 n, err := r.Read(buf) 51 if err != nil { 52 log.Printf("read from auth channel: %v", err) 53 } 54 n, err = rpcfile.Write(buf[:n]) 55 if err != nil { 56 log.Printf("write to auth file: %v", err) 57 } 58 n, err = rpcfile.Read(buf) 59 if err != nil { 60 log.Printf("read from auth file: %v", err) 61 } 62 if n >= 4 && string(buf[:4]) == "done" { 63 afile.AuthOK = true 64 break 65 } 66 n, err = w.Write(buf[:n]) 67 if err != nil { 68 log.Printf("write to auth channel: %v", err) 69 } 70 } 71 }