// Copyright (c) 2026 Petr BalvĂ­n (https://petrbalvin.org) // SPDX-License-Identifier: MIT package nfsclient import ( "net" "os" "path/filepath" "testing" "sourcedock.dev/petrbalvin/nfs/internal/krb5" "sourcedock.dev/petrbalvin/nfs/internal/nfs4" "sourcedock.dev/petrbalvin/nfs/internal/nfs4server" "sourcedock.dev/petrbalvin/nfs/internal/nfsfs" "sourcedock.dev/petrbalvin/nfs/internal/rpc" "sourcedock.dev/petrbalvin/nfs/internal/server" ) // The RPCSEC_GSS integrity and privacy levels of this client round trip // against the real server over TCP. func TestGSSRoundTrip(t *testing.T) { root := t.TempDir() if err := os.WriteFile(filepath.Join(root, "k.txt"), []byte("kerberos"), 0o644); err != nil { t.Fatal(err) } backend, err := nfsfs.NewLocal(root) if err != nil { t.Fatal(err) } key := make([]byte, 32) for i := range key { key[i] = byte(i + 3) } h := &nfs4server.Handler{FS: backend, ServerKey: key, ServiceName: "nfs"} ln, err := net.Listen("tcp", "127.0.0.1:0") if err != nil { t.Fatal(err) } srv := &server.Server{Handle: h.HandleConn} go srv.Serve(t.Context(), ln) defer ln.Close() for _, svc := range []uint32{rpc.SvcIntegrity, rpc.SvcPrivacy} { cl, err := Dial(ln.Addr().String()) if err != nil { t.Fatal(err) } if err := cl.Establish("gss-client"); err != nil { t.Fatalf("establish: %v", err) } if err := cl.EnableGSS(krb5.EtypeAES128, key, "EXAMPLE.ORG", "nfs", "petr@EXAMPLE.ORG", svc); err != nil { t.Fatalf("enable gss: %v", err) } res, _, err := cl.Compound("gss", [][]byte{ nfs4.AppendPutRootfh(nil), nfs4.AppendLookup(nil, "k.txt"), nfs4.AppendGetattr(nil, nfs4.OfBits(nfs4.AttrSize)), }) if err != nil { t.Fatalf("compound: %v", err) } if res.Status != nfs4.ErrOK { t.Fatalf("compound: status %d", res.Status) } if err := cl.DisableGSS(); err != nil { t.Fatalf("disable: %v", err) } cl.Close() } }