You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

110 lines
2.9 KiB

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)
}
}