ollie/experiments/auth9p/client.go

126 lines
2.5 KiB
Go

// Client: 9P client that authenticates via Tauth
package main
import (
"crypto/rand"
"encoding/hex"
"fmt"
"log"
"net"
"os"
"9fans.net/go/plan9"
)
func main() {
if len(os.Args) < 2 {
fmt.Println("Usage: client <secret>")
fmt.Println(" client new (generate new secret)")
os.Exit(1)
}
secret := os.Args[1]
if secret == "new" {
b := make([]byte, 16)
rand.Read(b)
secret = hex.EncodeToString(b)
fmt.Printf("Generated secret: %s\n", secret)
}
sockPath := "/tmp/auth9p-test.sock"
conn, err := net.Dial("unix", sockPath)
if err != nil {
log.Fatalf("dial: %v", err)
}
defer conn.Close()
fmt.Println("Connected to server")
// Tversion
tag := uint16(1)
if err := plan9.WriteFcall(conn, &plan9.Fcall{
Type: plan9.Tversion,
Tag: plan9.NOTAG,
Msize: 8192,
Version: "9P2000",
}); err != nil {
log.Fatal(err)
}
resp, _ := plan9.ReadFcall(conn)
fmt.Printf("Version: %v\n", resp)
// Tauth
afid := uint32(1)
if err := plan9.WriteFcall(conn, &plan9.Fcall{
Type: plan9.Tauth,
Tag: tag,
Afid: afid,
Uname: "agent",
Aname: "",
}); err != nil {
log.Fatal(err)
}
tag++
resp, _ = plan9.ReadFcall(conn)
fmt.Printf("Auth: %v\n", resp)
if resp.Type == plan9.Rerror {
log.Fatalf("Tauth failed: %s", resp.Ename)
}
// Write secret to auth fid
if err := plan9.WriteFcall(conn, &plan9.Fcall{
Type: plan9.Twrite,
Tag: tag,
Fid: afid,
Data: []byte(secret),
Count: uint32(len(secret)),
}); err != nil {
log.Fatal(err)
}
tag++
resp, _ = plan9.ReadFcall(conn)
fmt.Printf("Write secret: %v\n", resp)
if resp.Type == plan9.Rerror {
log.Fatalf("Auth failed: %s", resp.Ename)
}
// Read token from auth fid
if err := plan9.WriteFcall(conn, &plan9.Fcall{
Type: plan9.Tread,
Tag: tag,
Fid: afid,
Offset: 0,
Count: 1024,
}); err != nil {
log.Fatal(err)
}
tag++
resp, _ = plan9.ReadFcall(conn)
fmt.Printf("Read token: %v\n", resp)
token := string(resp.Data)
fmt.Printf("Session token: %s", token)
// Tattach
fid := uint32(2)
if err := plan9.WriteFcall(conn, &plan9.Fcall{
Type: plan9.Tattach,
Tag: tag,
Fid: fid,
Afid: afid,
Uname: "agent",
Aname: "",
}); err != nil {
log.Fatal(err)
}
tag++
resp, _ = plan9.ReadFcall(conn)
fmt.Printf("Attach: %v\n", resp)
if resp.Type == plan9.Rerror {
log.Fatalf("Attach failed: %s", resp.Ename)
}
fmt.Println("\n✓ Successfully authenticated and attached!")
fmt.Printf("Use this secret to reconnect: %s\n", secret)
}