lib9p

Go 9P library.
Log | Files | Refs | LICENSE

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 }