package externalauth import ( "context" "crypto/md5" "encoding/binary" "io" "net" "testing" "time" ) func TestRadiusAccessAcceptVerifiesResponseAuthenticator(t *testing.T) { server, err := net.ListenPacket("udp", "127.0.0.1:0") if err != nil { t.Fatal(err) } defer server.Close() secret := "radius-shared-secret" done := make(chan error, 1) go func() { buffer := make([]byte, 4096) n, address, err := server.ReadFrom(buffer) if err != nil { done <- err return } request := buffer[:n] response := make([]byte, 20) response[0], response[1] = 2, request[1] binary.BigEndian.PutUint16(response[2:4], 20) copy(response[4:20], request[4:20]) input := append(append([]byte(nil), response...), []byte(secret)...) digest := md5.Sum(input) copy(response[4:20], digest[:]) _, err = server.WriteTo(response, address) done <- err }() port := server.LocalAddr().(*net.UDPAddr).Port accepted, err := (Client{}).Authenticate(context.Background(), "radius", Server{Host: "127.0.0.1", Port: port, Secret: secret}, "operator", "password-1", 2*time.Second) if err != nil || !accepted { t.Fatalf("accepted=%v err=%v", accepted, err) } if err := <-done; err != nil { t.Fatal(err) } } func TestTACACSASCIIChallengeFlow(t *testing.T) { listener, err := net.Listen("tcp", "127.0.0.1:0") if err != nil { t.Fatal(err) } defer listener.Close() secret := []byte("tacacs-shared-secret") done := make(chan error, 1) go func() { conn, err := listener.Accept() if err != nil { done <- err return } defer conn.Close() header := make([]byte, 12) if _, err = io.ReadFull(conn, header); err != nil { done <- err return } body := make([]byte, binary.BigEndian.Uint32(header[8:12])) if _, err = io.ReadFull(conn, body); err != nil { done <- err return } body = tacacsXOR(header, secret, body) sessionID := binary.BigEndian.Uint32(header[4:8]) if string(body[8:]) != "operator" { done <- io.ErrUnexpectedEOF return } reply := []byte{5, 1, 0, 0, 0, 0} if err = writeTacacsPacket(conn, sessionID, 2, secret, reply); err != nil { done <- err return } if _, err = io.ReadFull(conn, header); err != nil { done <- err return } body = make([]byte, binary.BigEndian.Uint32(header[8:12])) if _, err = io.ReadFull(conn, body); err != nil { done <- err return } body = tacacsXOR(header, secret, body) if string(body[5:]) != "password-1" { done <- io.ErrUnexpectedEOF return } done <- writeTacacsPacket(conn, sessionID, 4, secret, []byte{1, 0, 0, 0, 0, 0}) }() port := listener.Addr().(*net.TCPAddr).Port accepted, err := (Client{}).Authenticate(context.Background(), "tacacs", Server{Host: "127.0.0.1", Port: port, Secret: string(secret)}, "operator", "password-1", 2*time.Second) if err != nil || !accepted { t.Fatalf("accepted=%v err=%v", accepted, err) } if err := <-done; err != nil { t.Fatal(err) } }