commit 6fbe899e8c228f2bfacf0b6a917a49c398999a8f
parent 19d4963812366e7de84fc013423db627419bb344
Author: Matsuda Kenji <info@mtkn.jp>
Date: Wed, 20 Dec 2023 12:40:26 +0900
add auth test
Diffstat:
| M | auth.go | | | 3 | +-- |
| M | auth_test.go | | | 90 | +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++---- |
| M | fid.go | | | 4 | ---- |
| M | server.go | | | 37 | ++++++++++++++++++++++++++++--------- |
4 files changed, 115 insertions(+), 19 deletions(-)
diff --git a/auth.go b/auth.go
@@ -22,13 +22,12 @@ func (af *AuthFile) Stat() (fs.FileInfo, error) {
}
s := Stat{
Qid: af.Qid,
- Mode: fs.ModeAppend | fs.ModeExclusive | fs.ModeTemporary, // TODO: right?
+ Mode: fs.ModeAppend | fs.ModeExclusive | fs.ModeTemporary | 0666, // TODO: right?
Name: "auth",
Uid: af.Uname,
Gid: af.Uname,
Muid: af.Uname,
}
-
return &FileInfo{Stat: s}, nil
}
diff --git a/auth_test.go b/auth_test.go
@@ -1,12 +1,94 @@
package lib9p_test
-/*
+
import (
+ "context"
+ "io"
"testing"
"git.mtkn.jp/lib9p"
"git.mtkn.jp/lib9p/client"
+ "git.mtkn.jp/lib9p/testfs"
)
func TestAuth(t *testing.T) {
- s := lib9p.NewServer()
-}*/
-\ No newline at end of file
+ const (
+ mSize = 8 * 1024
+ uname = "kenji"
+ )
+ cr, sw := io.Pipe()
+ sr, cw := io.Pipe()
+ defer func() {
+ cr.Close()
+ cw.Close()
+ sr.Close()
+ sw.Close()
+ }()
+ server := lib9p.NewServer(testfs.FS, mSize, sr, sw)
+ server.Chatty()
+ acr, asw := io.Pipe()
+ asr, acw := io.Pipe()
+ defer func() {
+ acr.Close()
+ acw.Close()
+ asr.Close()
+ asw.Close()
+ }()
+ server.Auth = func(ctx context.Context, r *lib9p.Req) {
+ ifcall := r.Ifcall.(*lib9p.TAuth)
+ aqid := lib9p.Qid{Type: lib9p.QTAUTH, Vers: 0, Path: ^uint64(0)}
+ r.Afid.File = &lib9p.AuthFile{
+ Qid: aqid,
+ Uname: ifcall.Uname,
+ Aname: ifcall.Aname,
+ W: acw,
+ R: acr,
+ }
+ runAuth(ctx, t, r.Afid.File.(*lib9p.AuthFile), asr, asw)
+ r.Ofcall = &lib9p.RAuth{Tag: ifcall.Tag, Aqid: aqid}
+ lib9p.Respond(ctx, r, nil)
+ }
+ clnt := client.NewClient(mSize, uname, cr, cw)
+ ctx, cancel := context.WithCancel(context.Background())
+ defer cancel()
+ go server.Serve(ctx)
+ _, _, err := clnt.Version(ctx, lib9p.NOTAG, mSize, "9P2000")
+ if err != nil {
+ t.Log(err)
+ }
+ _, err = clnt.Auth(ctx, 0, 0, "kenji", "")
+ if err != nil {
+ t.Error(err)
+ }
+ _, err = clnt.Attach(ctx, 0, 1, 0, "kenji", "")
+ if err == nil {
+ t.Error("authentication skipped")
+ }
+ _, _, err = clnt.Open(ctx, 0, 0, lib9p.ORDWR)
+ if err != nil {
+ t.Error(err)
+ }
+ _, err = clnt.Write(ctx, 0, 0, 0, 5, []byte("kenji"))
+ if err != nil {
+ t.Error(err)
+ }
+ _, err = clnt.Write(ctx, 0, 0, 0, 8, []byte("password"))
+ if err != nil {
+ t.Error(err)
+ }
+ _, err = clnt.Attach(ctx, 0, 1, 0, "kenji", "")
+ if err != nil {
+ t.Error(err)
+ }
+}
+
+func runAuth(ctx context.Context, t *testing.T, afile *lib9p.AuthFile, r io.Reader, w io.Writer) {
+ go func() {
+ buf := make([]byte, 10)
+ r.Read(buf)
+ t.Logf("read username: %s", string(buf))
+ r.Read(buf)
+ t.Logf("read password: %s", string(buf))
+ afile.AuthOK = true
+ t.Log("authenticated")
+ }()
+}
+\ No newline at end of file
diff --git a/fid.go b/fid.go
@@ -64,7 +64,6 @@ func newFidPool() *FidPool {
func (pool *FidPool) lookup(fid uint32) (*Fid, bool) {
pool.lock.Lock()
defer pool.lock.Unlock()
-
f, ok := pool.m[fid]
return f, ok
}
@@ -72,7 +71,6 @@ func (pool *FidPool) lookup(fid uint32) (*Fid, bool) {
func (pool *FidPool) add(fid uint32) (*Fid, error) {
pool.lock.Lock()
defer pool.lock.Unlock()
-
if _, ok := pool.m[fid]; ok {
return nil, fmt.Errorf("fid already in use.")
}
@@ -89,8 +87,6 @@ func (pool *FidPool) delete(fid uint32) {
}
func (pool *FidPool) String() string {
- pool.lock.Lock() // TODO: need?
- defer pool.lock.Unlock()
s := "&FidPool{\n"
for fnum, fstruct := range pool.m {
if fstruct.File == nil {
diff --git a/server.go b/server.go
@@ -270,6 +270,7 @@ func sAttach(ctx context.Context, s *Server, r *Req) {
}
af, ok := afid.File.(*AuthFile)
if !ok {
+ log.Printf("afile: %[1]T, %[1]v", afid.File)
Respond(ctx, r, fmt.Errorf("not auth file"))
return
}
@@ -402,16 +403,31 @@ func sOpen(ctx context.Context, s *Server, r *Req) {
Respond(ctx, r, ErrBotch)
return
}
- // Write attempt to a directory is prohibitted by the protocol.
- // See open(5).
- // In plan9 implementation, ifcall.Mode() is ANDed with ^ORCLOSE,
- // but ORCLOSE is also prohibitted by the protocol...
- st, err := fs.Stat(ExportFS{s.fs}, r.Fid.path)
- if err != nil {
- Respond(ctx, r, fmt.Errorf("stat: %v", err))
- return
+ var (
+ err error
+ qid Qid
+ st fs.FileInfo
+ )
+ if afile, ok := r.Fid.File.(*AuthFile); ok {
+ // TODO: r.Fid.File should not be nil.
+ st, err = r.Fid.File.Stat()
+ if err != nil {
+ Respond(ctx, r, fmt.Errorf("stat: %v", err))
+ return
+ }
+ qid = afile.Qid
+ } else {
+ // Write attempt to a directory is prohibitted by the protocol.
+ // See open(5).
+ // In plan9 implementation, ifcall.Mode() is ANDed with ^ORCLOSE,
+ // but ORCLOSE is also prohibitted by the protocol...
+ st, err = fs.Stat(ExportFS{s.fs}, r.Fid.path)
+ if err != nil {
+ Respond(ctx, r, fmt.Errorf("stat: %v", err))
+ return
+ }
+ qid = st.Sys().(*Stat).Qid
}
- qid := st.Sys().(*Stat).Qid
if qid.Type == QTDIR && ifcall.Mode != OREAD {
Respond(ctx, r, fmt.Errorf("is a directory"))
return
@@ -465,6 +481,9 @@ func rOpen(r *Req, err error) {
return
}
r.Fid.OMode = r.Ifcall.(*TOpen).Mode
+ if _, ok := r.Fid.File.(*AuthFile); ok {
+ return
+ }
f, err := r.Srv.fs.OpenFile(r.Fid.path, r.Fid.OMode)
if err != nil {
setError(r, err)