diff --git a/.circleci/config.yml b/.circleci/config.yml index 740687a7..15052377 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -6,7 +6,7 @@ jobs: build: docker: # specify the version - - image: circleci/golang:1.10 + - image: circleci/golang:1.15 working_directory: /go/src/layeh.com/radius steps: diff --git a/attribute.go b/attribute.go index 506438b3..7137bb39 100644 --- a/attribute.go +++ b/attribute.go @@ -197,6 +197,14 @@ func NewUserPassword(plaintext, secret, requestAuthenticator []byte) (Attribute, chunks = 1 } + pt2 := plaintext + // fill plaintext pt2 with 0s if needed + remainder := len(pt2) % 16 + if remainder != 0 || len(pt2) == 0 { + fill := make([]byte, (16 - remainder)) + pt2 = append(pt2, fill...) + } + enc := make([]byte, 0, chunks*16) hash := md5.New() @@ -204,17 +212,17 @@ func NewUserPassword(plaintext, secret, requestAuthenticator []byte) (Attribute, hash.Write(requestAuthenticator) enc = hash.Sum(enc) - for i, b := range plaintext[:16] { + for i, b := range pt2[:16] { enc[i] ^= b } - for i := 16; i < len(plaintext); i += 16 { + for i := 16; i < len(pt2); i += 16 { hash.Reset() hash.Write(secret) hash.Write(enc[i-16 : i]) enc = hash.Sum(enc) - for j, b := range plaintext[i : i+16] { + for j, b := range pt2[i : i+16] { enc[i+j] ^= b } } diff --git a/attribute_test.go b/attribute_test.go index 2df7dc5f..ae4b7696 100644 --- a/attribute_test.go +++ b/attribute_test.go @@ -35,6 +35,33 @@ func TestNewUserPassword_length(t *testing.T) { } } +func TestNewUserPassword_byteLength(t *testing.T) { + tbl := []struct { + Password []byte + EncodedLength int + }{ + {[]byte(""), 16}, + {[]byte("abc"), 16}, + {[]byte("0123456789abcde"), 16}, + {[]byte("0123456789abcdef"), 16}, + {[]byte("0123456789abcdef0"), 16 * 2}, + {[]byte("0123456789abcdef0123456789abcdef0123456789abcdef"), 16 * 3}, + } + + secret := []byte(`12345`) + ra := []byte(`0123456789abcdef`) + + for _, x := range tbl { + attr, err := NewUserPassword(x.Password, secret, ra) + if err != nil { + t.Fatal(err) + } + if len(attr) != x.EncodedLength { + t.Fatalf("expected encoded length of %#v = %d, got %d", x.Password, x.EncodedLength, len(attr)) + } + } +} + func TestTunnelPassword(t *testing.T) { roundtrip := []string{ "", diff --git a/client-example_test.go b/client-example_test.go index ccf12625..09a9a147 100644 --- a/client-example_test.go +++ b/client-example_test.go @@ -4,8 +4,8 @@ import ( "context" "log" - "layeh.com/radius" - "layeh.com/radius/rfc2865" + "github.com/holgermetschulat/radius" + "github.com/holgermetschulat/radius/rfc2865" ) var ( diff --git a/client.go b/client.go index 6c826bca..518b6d4c 100644 --- a/client.go +++ b/client.go @@ -69,7 +69,10 @@ func (c *Client) Exchange(ctx context.Context, packet *Packet, addr string) (*Pa } defer conn.Close() - conn.Write(wire) + _, err = conn.Write(wire) + if err != nil { + return nil, err + } var cancel context.CancelFunc ctx, cancel = context.WithCancel(ctx) @@ -108,7 +111,7 @@ func (c *Client) Exchange(ctx context.Context, packet *Packet, addr string) (*Pa return nil, err } - received, err := Parse(incoming[:n], packet.Secret) + received, err := Parse(incoming[:n], packet.CryptoAuthenticator[:], packet.Secret) if err != nil { packetErrorCount++ if c.MaxPacketErrors > 0 && packetErrorCount >= c.MaxPacketErrors { diff --git a/cmd/radius-dict-gen/main.go b/cmd/radius-dict-gen/main.go index d3a4c027..023b2247 100644 --- a/cmd/radius-dict-gen/main.go +++ b/cmd/radius-dict-gen/main.go @@ -9,8 +9,8 @@ import ( "sort" "strings" - "layeh.com/radius/dictionary" - "layeh.com/radius/dictionarygen" + "github.com/holgermetschulat/radius/dictionary" + "github.com/holgermetschulat/radius/dictionarygen" ) type Refs map[string]string diff --git a/cmd/radserver/main.go b/cmd/radserver/main.go index a66a1a47..6917b40c 100644 --- a/cmd/radserver/main.go +++ b/cmd/radserver/main.go @@ -7,8 +7,8 @@ import ( "os" "os/exec" - "layeh.com/radius" - "layeh.com/radius/rfc2865" + "github.com/holgermetschulat/radius" + "github.com/holgermetschulat/radius/rfc2865" ) var secret = flag.String("secret", "", "shared RADIUS secret between clients and server") diff --git a/cmd/radtest/main.go b/cmd/radtest/main.go index 3dc1d1e8..ba48c534 100644 --- a/cmd/radtest/main.go +++ b/cmd/radtest/main.go @@ -9,8 +9,8 @@ import ( "strconv" "time" - "layeh.com/radius" - "layeh.com/radius/rfc2865" + "github.com/holgermetschulat/radius" + "github.com/holgermetschulat/radius/rfc2865" ) const usage = ` diff --git a/cryptotest/dictionary.cryptotest b/cryptotest/dictionary.cryptotest new file mode 100644 index 00000000..60da6cdf --- /dev/null +++ b/cryptotest/dictionary.cryptotest @@ -0,0 +1,3 @@ +ATTRIBUTE CT-Int 11 integer encrypt=2 +ATTRIBUTE CT-Octects 12 octets encrypt=2 +ATTRIBUTE CT-IPADDR 13 ipaddr encrypt=2 diff --git a/cryptotest/generate.go b/cryptotest/generate.go new file mode 100644 index 00000000..4224f664 --- /dev/null +++ b/cryptotest/generate.go @@ -0,0 +1,3 @@ +//go:generate go run ../cmd/radius-dict-gen/main.go -package cryptotest -output generated_cryptotest_test.go dictionary.cryptotest + +package cryptotest diff --git a/cryptotest/generated_cryptotest_test.go b/cryptotest/generated_cryptotest_test.go new file mode 100644 index 00000000..fa566528 --- /dev/null +++ b/cryptotest/generated_cryptotest_test.go @@ -0,0 +1,329 @@ +// Code generated by radius-dict-gen. DO NOT EDIT. + +package cryptotest + +import ( + "crypto/rand" + "net" + "strconv" + + "github.com/holgermetschulat/radius" +) + +const ( + CTInt_Type radius.Type = 11 + CTOctects_Type radius.Type = 12 + CTIPADDR_Type radius.Type = 13 +) + +type CTInt uint32 + +var CTInt_Strings = map[CTInt]string{} + +func (a CTInt) String() string { + if str, ok := CTInt_Strings[a]; ok { + return str + } + return "CTInt(" + strconv.FormatUint(uint64(a), 10) + ")" +} + +func CTInt_Add(p *radius.Packet, value CTInt) (err error) { + a := radius.NewInteger(uint32(value)) + var salt [2]byte + _, err = rand.Read(salt[:]) + if err != nil { + return + } + salt[0] |= 1 << 7 + a, err = radius.NewTunnelPassword(a, salt[:], p.Secret, p.CryptoAuthenticator[:]) + if err != nil { + return + } + p.Add(CTInt_Type, a) + return +} + +func CTInt_Get(p *radius.Packet) (value CTInt) { + value, _ = CTInt_Lookup(p) + return +} + +func CTInt_Gets(p *radius.Packet) (values []CTInt, err error) { + var i uint32 + for _, avp := range p.Attributes { + if avp.Type != CTInt_Type { + continue + } + attr := avp.Attribute + attr, _, err = radius.TunnelPassword(attr, p.Secret, p.CryptoAuthenticator[:]) + if err != nil { + return + } + i, err = radius.Integer(attr) + if err != nil { + return + } + values = append(values, CTInt(i)) + } + return +} + +func CTInt_Lookup(p *radius.Packet) (value CTInt, err error) { + a, ok := p.Lookup(CTInt_Type) + if !ok { + err = radius.ErrNoAttribute + return + } + a, _, err = radius.TunnelPassword(a, p.Secret, p.CryptoAuthenticator[:]) + if err != nil { + return + } + var i uint32 + i, err = radius.Integer(a) + if err != nil { + return + } + value = CTInt(i) + return +} + +func CTInt_Set(p *radius.Packet, value CTInt) (err error) { + a := radius.NewInteger(uint32(value)) + var salt [2]byte + _, err = rand.Read(salt[:]) + if err != nil { + return + } + salt[0] |= 1 << 7 + a, err = radius.NewTunnelPassword(a, salt[:], p.Secret, p.CryptoAuthenticator[:]) + if err != nil { + return + } + p.Set(CTInt_Type, a) + return +} + +func CTInt_Del(p *radius.Packet) { + p.Attributes.Del(CTInt_Type) +} + +func CTOctects_Add(p *radius.Packet, value []byte) (err error) { + var a radius.Attribute + var salt [2]byte + _, err = rand.Read(salt[:]) + if err != nil { + return + } + salt[0] |= 1 << 7 + a, err = radius.NewTunnelPassword(value, salt[:], p.Secret, p.CryptoAuthenticator[:]) + if err != nil { + return + } + p.Add(CTOctects_Type, a) + return +} + +func CTOctects_AddString(p *radius.Packet, value string) (err error) { + var a radius.Attribute + var salt [2]byte + _, err = rand.Read(salt[:]) + if err != nil { + return + } + salt[0] |= 1 << 7 + a, err = radius.NewTunnelPassword([]byte(value), salt[:], p.Secret, p.CryptoAuthenticator[:]) + if err != nil { + return + } + p.Add(CTOctects_Type, a) + return +} + +func CTOctects_Get(p *radius.Packet) (value []byte) { + value, _ = CTOctects_Lookup(p) + return +} + +func CTOctects_GetString(p *radius.Packet) (value string) { + value, _ = CTOctects_LookupString(p) + return +} + +func CTOctects_Gets(p *radius.Packet) (values [][]byte, err error) { + var i []byte + for _, avp := range p.Attributes { + if avp.Type != CTOctects_Type { + continue + } + attr := avp.Attribute + i, _, err = radius.TunnelPassword(attr, p.Secret, p.CryptoAuthenticator[:]) + if err != nil { + return + } + values = append(values, i) + } + return +} + +func CTOctects_GetStrings(p *radius.Packet) (values []string, err error) { + var i string + for _, avp := range p.Attributes { + if avp.Type != CTOctects_Type { + continue + } + attr := avp.Attribute + var up []byte + up, _, err = radius.TunnelPassword(attr, p.Secret, p.CryptoAuthenticator[:]) + if err == nil { + i = string(up) + } + if err != nil { + return + } + values = append(values, i) + } + return +} + +func CTOctects_Lookup(p *radius.Packet) (value []byte, err error) { + a, ok := p.Lookup(CTOctects_Type) + if !ok { + err = radius.ErrNoAttribute + return + } + value, _, err = radius.TunnelPassword(a, p.Secret, p.CryptoAuthenticator[:]) + return +} + +func CTOctects_LookupString(p *radius.Packet) (value string, err error) { + a, ok := p.Lookup(CTOctects_Type) + if !ok { + err = radius.ErrNoAttribute + return + } + var b []byte + b, _, err = radius.TunnelPassword(a, p.Secret, p.CryptoAuthenticator[:]) + if err == nil { + value = string(b) + } + return +} + +func CTOctects_Set(p *radius.Packet, value []byte) (err error) { + var a radius.Attribute + var salt [2]byte + _, err = rand.Read(salt[:]) + if err != nil { + return + } + salt[0] |= 1 << 7 + a, err = radius.NewTunnelPassword(value, salt[:], p.Secret, p.CryptoAuthenticator[:]) + if err != nil { + return + } + p.Set(CTOctects_Type, a) + return +} + +func CTOctects_SetString(p *radius.Packet, value string) (err error) { + var a radius.Attribute + var salt [2]byte + _, err = rand.Read(salt[:]) + if err != nil { + return + } + salt[0] |= 1 << 7 + a, err = radius.NewTunnelPassword([]byte(value), salt[:], p.Secret, p.CryptoAuthenticator[:]) + if err != nil { + return + } + p.Set(CTOctects_Type, a) + return +} + +func CTOctects_Del(p *radius.Packet) { + p.Attributes.Del(CTOctects_Type) +} + +func CTIPADDR_Add(p *radius.Packet, value net.IP) (err error) { + var a radius.Attribute + a, err = radius.NewIPAddr(value) + if err != nil { + return + } + var salt [2]byte + _, err = rand.Read(salt[:]) + if err != nil { + return + } + salt[0] |= 1 << 7 + a, err = radius.NewTunnelPassword(a, salt[:], p.Secret, p.CryptoAuthenticator[:]) + if err != nil { + return + } + p.Add(CTIPADDR_Type, a) + return +} + +func CTIPADDR_Get(p *radius.Packet) (value net.IP) { + value, _ = CTIPADDR_Lookup(p) + return +} + +func CTIPADDR_Gets(p *radius.Packet) (values []net.IP, err error) { + var i net.IP + for _, avp := range p.Attributes { + if avp.Type != CTIPADDR_Type { + continue + } + attr := avp.Attribute + attr, _, err = radius.TunnelPassword(attr, p.Secret, p.CryptoAuthenticator[:]) + if err != nil { + return + } + i, err = radius.IPAddr(attr) + if err != nil { + return + } + values = append(values, i) + } + return +} + +func CTIPADDR_Lookup(p *radius.Packet) (value net.IP, err error) { + a, ok := p.Lookup(CTIPADDR_Type) + if !ok { + err = radius.ErrNoAttribute + return + } + a, _, err = radius.TunnelPassword(a, p.Secret, p.CryptoAuthenticator[:]) + if err != nil { + return + } + value, err = radius.IPAddr(a) + return +} + +func CTIPADDR_Set(p *radius.Packet, value net.IP) (err error) { + var a radius.Attribute + a, err = radius.NewIPAddr(value) + if err != nil { + return + } + var salt [2]byte + _, err = rand.Read(salt[:]) + if err != nil { + return + } + salt[0] |= 1 << 7 + a, err = radius.NewTunnelPassword(a, salt[:], p.Secret, p.CryptoAuthenticator[:]) + if err != nil { + return + } + p.Set(CTIPADDR_Type, a) + return +} + +func CTIPADDR_Del(p *radius.Packet) { + p.Attributes.Del(CTIPADDR_Type) +} diff --git a/cryptotest/generated_test.go b/cryptotest/generated_test.go new file mode 100644 index 00000000..5218d38a --- /dev/null +++ b/cryptotest/generated_test.go @@ -0,0 +1,162 @@ +package cryptotest + +import ( + "bytes" + "context" + "net" + "testing" + "time" + + "github.com/holgermetschulat/radius" +) + +type TestServer struct { + Addr string + Server *radius.PacketServer + l net.PacketConn + serveErr error +} + +func NewTestServer(handler radius.Handler, secretSource radius.SecretSource) *TestServer { + addr, err := net.ResolveUDPAddr("udp", "localhost:0") + if err != nil { + panic(err) + } + + conn, err := net.ListenUDP("udp", addr) + if err != nil { + panic(err) + } + + s := &TestServer{ + Addr: conn.LocalAddr().String(), + Server: &radius.PacketServer{ + Handler: handler, + SecretSource: secretSource, + }, + l: conn, + } + + go func() { + s.serveErr = s.Server.Serve(s.l) + }() + + return s +} + +func (s *TestServer) Close() error { + return s.l.Close() +} + +func TestCOASaltEncryptionFromClientToServer(t *testing.T) { + secret := []byte(`12345`) + expected := []byte("testsecret") + + handler := radius.HandlerFunc(func(w radius.ResponseWriter, r *radius.Request) { + resp := r.Response(radius.CodeCoAACK) + + returned, err := CTOctects_Lookup(r.Packet) + if err != nil { + t.Fatalf("Could not decode encrypted tunnel password with error %v", err) + } + if !bytes.Equal(returned, expected) { + t.Fatalf("incorrect tunnel password: expected %v, got %v", expected, returned) + } + err = w.Write(resp) + if err != nil { + t.Fatal(err) + } + }) + + server := NewTestServer(handler, radius.StaticSecretSource(secret)) + defer server.Close() + + client := radius.Client{ + Retry: time.Millisecond * 50, + MaxPacketErrors: 2, + } + + req := radius.New(radius.CodeCoARequest, secret) + if err := CTOctects_Add(req, expected); err != nil { + t.Fatal(err) + } + ctx, cancel := context.WithTimeout(context.Background(), 100*time.Millisecond) + defer cancel() + + _, err := client.Exchange(ctx, req, server.Addr) + if err != nil { + t.Fatalf("Exchange error %v", err) + } +} + +func newRadiusPacket() (p *radius.Packet) { + p = &radius.Packet{ + Attributes: radius.Attributes{}, + Authenticator: [16]byte{0x0B, 0x00, 0x00, 0x07, 0x0B, 0x00, 0x00, 0x07, 0x0B, 0x00, 0x00, 0x07, 0x0B, 0x00, 0x00, 0x07}, + Secret: []byte{0x0B, 0x00, 0x00, 0x07}, + } + + p.CryptoAuthenticator = p.Authenticator + return +} + +func Test_CTIPADDR_Add(t *testing.T) { + tunnelCTIPADDRAdd := func() (p *radius.Packet) { + p = newRadiusPacket() + testIP := net.IPv4(8, 8, 8, 8) + if err := CTIPADDR_Add(p, testIP); err != nil { + t.Fatalf("DTA4LIMedIPAddress_Set unexpected err %s", err) + } + + returned, err := CTIPADDR_Lookup(p) + if err != nil { + t.Fatalf("unexpected err: %s", err) + } + if !returned.Equal(testIP) { + t.Fatalf("decrypted DTA4LIMedIPAddress does not match encrypted") + } + + returnedArray, err := CTIPADDR_Gets(p) + if err != nil { + t.Fatalf("unexpected err: %s", err) + } + if len(returnedArray) != 1 || !testIP.Equal(returnedArray[0]) { + t.Fatalf("decrypted DTA4LIMedIPAddress does not match encrypted") + } + + return + } + + p1 := tunnelCTIPADDRAdd() + p2 := tunnelCTIPADDRAdd() + + if bytes.Equal(p1.Attributes[0].Attribute, p2.Attributes[0].Attribute) { + t.Fatalf("tunnel encrypted passwords should not be identical since salts are rands") + } +} + +func Test_DTA4LIAction_With_Sample_RADIUS_WrongDecryptAuthenticator(t *testing.T) { + packet := newRadiusPacket() + + var testInt CTInt = 1 + err := CTInt_Add(packet, 1) + if err != nil { + t.Fatalf("unexpected err: %s", err) + } + + returned, err := CTInt_Lookup(packet) + if err != nil { + t.Fatalf("unexpected err: %s", err) + } + + if returned != testInt { + t.Fatalf("returned int does not match encrypted") + } + + packet.CryptoAuthenticator[3] = 0xff + _, err = CTInt_Lookup(packet) + + if err == nil { + t.Fatalf("expected a decoder failure") + } +} diff --git a/debug/debug.go b/debug/debug.go index 00700bb9..223cf407 100644 --- a/debug/debug.go +++ b/debug/debug.go @@ -12,8 +12,8 @@ import ( "strings" "time" - "layeh.com/radius" - "layeh.com/radius/dictionary" + "github.com/holgermetschulat/radius" + "github.com/holgermetschulat/radius/dictionary" ) type Config struct { @@ -68,7 +68,7 @@ func dumpAttrs(w io.Writer, c *Config, p *radius.Packet) { switch dictAttr.Type { case dictionary.AttributeString, dictionary.AttributeOctets: if dictAttr != nil && dictAttr.FlagEncrypt.Valid && dictAttr.FlagEncrypt.Int == 1 { - decryptedValue, err := radius.UserPassword(avp.Attribute, p.Secret, p.Authenticator[:]) + decryptedValue, err := radius.UserPassword(avp.Attribute, p.Secret, p.CryptoAuthenticator[:]) if err == nil { attrStr = fmt.Sprintf("%q", decryptedValue) break diff --git a/debug/debug_test.go b/debug/debug_test.go index d226ddaf..93760fa3 100644 --- a/debug/debug_test.go +++ b/debug/debug_test.go @@ -7,12 +7,12 @@ import ( "testing" "time" - "layeh.com/radius" - "layeh.com/radius/debug" - . "layeh.com/radius/rfc2865" - . "layeh.com/radius/rfc2866" - . "layeh.com/radius/rfc2869" - . "layeh.com/radius/rfc3162" + "github.com/holgermetschulat/radius" + "github.com/holgermetschulat/radius/debug" + . "github.com/holgermetschulat/radius/rfc2865" + . "github.com/holgermetschulat/radius/rfc2866" + . "github.com/holgermetschulat/radius/rfc2869" + . "github.com/holgermetschulat/radius/rfc3162" ) var secret = []byte(`1234567`) @@ -30,6 +30,7 @@ func TestDumpPacket(t *testing.T) { Secret: secret, } p.Authenticator[0] = 0x01 + p.CryptoAuthenticator = p.Authenticator UserName_SetString(p, "Tim") UserPassword_SetString(p, "12345") diff --git a/debug/generate_main.go b/debug/generate_main.go index 6aecf4e8..ceaca1f6 100644 --- a/debug/generate_main.go +++ b/debug/generate_main.go @@ -8,7 +8,7 @@ import ( "io" "os" - "layeh.com/radius/dictionary" + "github.com/holgermetschulat/radius/dictionary" ) func main() { @@ -52,7 +52,7 @@ func main() { fmt.Fprintln(w, "") fmt.Fprintln(w, "package debug") fmt.Fprintln(w, "") - fmt.Fprintln(w, `import "layeh.com/radius/dictionary"`) + fmt.Fprintln(w, `import "github.com/holgermetschulat/radius/dictionary"`) fmt.Fprintln(w, "") fmt.Fprintf(w, "var IncludedDictionary = %#v\n", dict) } diff --git a/debug/generated.go b/debug/generated.go index 860ca8e9..f480b6c5 100644 --- a/debug/generated.go +++ b/debug/generated.go @@ -2,6 +2,6 @@ package debug -import "layeh.com/radius/dictionary" +import "github.com/holgermetschulat/radius/dictionary" -var IncludedDictionary = &dictionary.Dictionary{Attributes:[]*dictionary.Attribute{&dictionary.Attribute{Name:"User-Name",OID:dictionary.OID{1},Type:1,},&dictionary.Attribute{Name:"User-Password",OID:dictionary.OID{2},Type:1,FlagEncrypt:dictionary.IntFlag{Int:1, Valid:true},},&dictionary.Attribute{Name:"CHAP-Password",OID:dictionary.OID{3},Type:2,},&dictionary.Attribute{Name:"NAS-IP-Address",OID:dictionary.OID{4},Type:3,},&dictionary.Attribute{Name:"NAS-Port",OID:dictionary.OID{5},Type:5,},&dictionary.Attribute{Name:"Service-Type",OID:dictionary.OID{6},Type:5,},&dictionary.Attribute{Name:"Framed-Protocol",OID:dictionary.OID{7},Type:5,},&dictionary.Attribute{Name:"Framed-IP-Address",OID:dictionary.OID{8},Type:3,},&dictionary.Attribute{Name:"Framed-IP-Netmask",OID:dictionary.OID{9},Type:3,},&dictionary.Attribute{Name:"Framed-Routing",OID:dictionary.OID{10},Type:5,},&dictionary.Attribute{Name:"Filter-Id",OID:dictionary.OID{11},Type:1,},&dictionary.Attribute{Name:"Framed-MTU",OID:dictionary.OID{12},Type:5,},&dictionary.Attribute{Name:"Framed-Compression",OID:dictionary.OID{13},Type:5,},&dictionary.Attribute{Name:"Login-IP-Host",OID:dictionary.OID{14},Type:3,},&dictionary.Attribute{Name:"Login-Service",OID:dictionary.OID{15},Type:5,},&dictionary.Attribute{Name:"Login-TCP-Port",OID:dictionary.OID{16},Type:5,},&dictionary.Attribute{Name:"Reply-Message",OID:dictionary.OID{18},Type:1,},&dictionary.Attribute{Name:"Callback-Number",OID:dictionary.OID{19},Type:1,},&dictionary.Attribute{Name:"Callback-Id",OID:dictionary.OID{20},Type:1,},&dictionary.Attribute{Name:"Framed-Route",OID:dictionary.OID{22},Type:1,},&dictionary.Attribute{Name:"Framed-IPX-Network",OID:dictionary.OID{23},Type:3,},&dictionary.Attribute{Name:"State",OID:dictionary.OID{24},Type:2,},&dictionary.Attribute{Name:"Class",OID:dictionary.OID{25},Type:2,},&dictionary.Attribute{Name:"Vendor-Specific",OID:dictionary.OID{26},Type:10,},&dictionary.Attribute{Name:"Session-Timeout",OID:dictionary.OID{27},Type:5,},&dictionary.Attribute{Name:"Idle-Timeout",OID:dictionary.OID{28},Type:5,},&dictionary.Attribute{Name:"Termination-Action",OID:dictionary.OID{29},Type:5,},&dictionary.Attribute{Name:"Called-Station-Id",OID:dictionary.OID{30},Type:1,},&dictionary.Attribute{Name:"Calling-Station-Id",OID:dictionary.OID{31},Type:1,},&dictionary.Attribute{Name:"NAS-Identifier",OID:dictionary.OID{32},Type:1,},&dictionary.Attribute{Name:"Proxy-State",OID:dictionary.OID{33},Type:2,},&dictionary.Attribute{Name:"Login-LAT-Service",OID:dictionary.OID{34},Type:1,},&dictionary.Attribute{Name:"Login-LAT-Node",OID:dictionary.OID{35},Type:1,},&dictionary.Attribute{Name:"Login-LAT-Group",OID:dictionary.OID{36},Type:2,},&dictionary.Attribute{Name:"Framed-AppleTalk-Link",OID:dictionary.OID{37},Type:5,},&dictionary.Attribute{Name:"Framed-AppleTalk-Network",OID:dictionary.OID{38},Type:5,},&dictionary.Attribute{Name:"Framed-AppleTalk-Zone",OID:dictionary.OID{39},Type:1,},&dictionary.Attribute{Name:"CHAP-Challenge",OID:dictionary.OID{60},Type:2,},&dictionary.Attribute{Name:"NAS-Port-Type",OID:dictionary.OID{61},Type:5,},&dictionary.Attribute{Name:"Port-Limit",OID:dictionary.OID{62},Type:5,},&dictionary.Attribute{Name:"Login-LAT-Port",OID:dictionary.OID{63},Type:1,},&dictionary.Attribute{Name:"Acct-Status-Type",OID:dictionary.OID{40},Type:5,},&dictionary.Attribute{Name:"Acct-Delay-Time",OID:dictionary.OID{41},Type:5,},&dictionary.Attribute{Name:"Acct-Input-Octets",OID:dictionary.OID{42},Type:5,},&dictionary.Attribute{Name:"Acct-Output-Octets",OID:dictionary.OID{43},Type:5,},&dictionary.Attribute{Name:"Acct-Session-Id",OID:dictionary.OID{44},Type:1,},&dictionary.Attribute{Name:"Acct-Authentic",OID:dictionary.OID{45},Type:5,},&dictionary.Attribute{Name:"Acct-Session-Time",OID:dictionary.OID{46},Type:5,},&dictionary.Attribute{Name:"Acct-Input-Packets",OID:dictionary.OID{47},Type:5,},&dictionary.Attribute{Name:"Acct-Output-Packets",OID:dictionary.OID{48},Type:5,},&dictionary.Attribute{Name:"Acct-Terminate-Cause",OID:dictionary.OID{49},Type:5,},&dictionary.Attribute{Name:"Acct-Multi-Session-Id",OID:dictionary.OID{50},Type:1,},&dictionary.Attribute{Name:"Acct-Link-Count",OID:dictionary.OID{51},Type:5,},&dictionary.Attribute{Name:"Acct-Tunnel-Connection",OID:dictionary.OID{68},Type:1,},&dictionary.Attribute{Name:"Acct-Tunnel-Packets-Lost",OID:dictionary.OID{86},Type:5,},&dictionary.Attribute{Name:"Acct-Input-Gigawords",OID:dictionary.OID{52},Type:5,},&dictionary.Attribute{Name:"Acct-Output-Gigawords",OID:dictionary.OID{53},Type:5,},&dictionary.Attribute{Name:"Event-Timestamp",OID:dictionary.OID{55},Type:4,},&dictionary.Attribute{Name:"ARAP-Password",OID:dictionary.OID{70},Type:2,Size:dictionary.IntFlag{Int:16, Valid:true},},&dictionary.Attribute{Name:"ARAP-Features",OID:dictionary.OID{71},Type:2,Size:dictionary.IntFlag{Int:14, Valid:true},},&dictionary.Attribute{Name:"ARAP-Zone-Access",OID:dictionary.OID{72},Type:5,},&dictionary.Attribute{Name:"ARAP-Security",OID:dictionary.OID{73},Type:5,},&dictionary.Attribute{Name:"ARAP-Security-Data",OID:dictionary.OID{74},Type:1,},&dictionary.Attribute{Name:"Password-Retry",OID:dictionary.OID{75},Type:5,},&dictionary.Attribute{Name:"Prompt",OID:dictionary.OID{76},Type:5,},&dictionary.Attribute{Name:"Connect-Info",OID:dictionary.OID{77},Type:1,},&dictionary.Attribute{Name:"Configuration-Token",OID:dictionary.OID{78},Type:1,},&dictionary.Attribute{Name:"EAP-Message",OID:dictionary.OID{79},Type:2,FlagConcat:dictionary.BoolFlag{Bool:true, Valid:true},},&dictionary.Attribute{Name:"Message-Authenticator",OID:dictionary.OID{80},Type:2,},&dictionary.Attribute{Name:"ARAP-Challenge-Response",OID:dictionary.OID{84},Type:2,Size:dictionary.IntFlag{Int:8, Valid:true},},&dictionary.Attribute{Name:"Acct-Interim-Interval",OID:dictionary.OID{85},Type:5,},&dictionary.Attribute{Name:"NAS-Port-Id",OID:dictionary.OID{87},Type:1,},&dictionary.Attribute{Name:"Framed-Pool",OID:dictionary.OID{88},Type:1,},&dictionary.Attribute{Name:"NAS-IPv6-Address",OID:dictionary.OID{95},Type:6,},&dictionary.Attribute{Name:"Framed-Interface-Id",OID:dictionary.OID{96},Type:8,},&dictionary.Attribute{Name:"Framed-IPv6-Prefix",OID:dictionary.OID{97},Type:7,},&dictionary.Attribute{Name:"Login-IPv6-Host",OID:dictionary.OID{98},Type:6,},&dictionary.Attribute{Name:"Framed-IPv6-Route",OID:dictionary.OID{99},Type:1,},&dictionary.Attribute{Name:"Framed-IPv6-Pool",OID:dictionary.OID{100},Type:1,},&dictionary.Attribute{Name:"Error-Cause",OID:dictionary.OID{101},Type:5,},},Values:[]*dictionary.Value{&dictionary.Value{Attribute:"Service-Type", Name:"Login-User", Number:1},&dictionary.Value{Attribute:"Service-Type", Name:"Framed-User", Number:2},&dictionary.Value{Attribute:"Service-Type", Name:"Callback-Login-User", Number:3},&dictionary.Value{Attribute:"Service-Type", Name:"Callback-Framed-User", Number:4},&dictionary.Value{Attribute:"Service-Type", Name:"Outbound-User", Number:5},&dictionary.Value{Attribute:"Service-Type", Name:"Administrative-User", Number:6},&dictionary.Value{Attribute:"Service-Type", Name:"NAS-Prompt-User", Number:7},&dictionary.Value{Attribute:"Service-Type", Name:"Authenticate-Only", Number:8},&dictionary.Value{Attribute:"Service-Type", Name:"Callback-NAS-Prompt", Number:9},&dictionary.Value{Attribute:"Service-Type", Name:"Call-Check", Number:10},&dictionary.Value{Attribute:"Service-Type", Name:"Callback-Administrative", Number:11},&dictionary.Value{Attribute:"Framed-Protocol", Name:"PPP", Number:1},&dictionary.Value{Attribute:"Framed-Protocol", Name:"SLIP", Number:2},&dictionary.Value{Attribute:"Framed-Protocol", Name:"ARAP", Number:3},&dictionary.Value{Attribute:"Framed-Protocol", Name:"Gandalf-SLML", Number:4},&dictionary.Value{Attribute:"Framed-Protocol", Name:"Xylogics-IPX-SLIP", Number:5},&dictionary.Value{Attribute:"Framed-Protocol", Name:"X.75-Synchronous", Number:6},&dictionary.Value{Attribute:"Framed-Routing", Name:"None", Number:0},&dictionary.Value{Attribute:"Framed-Routing", Name:"Broadcast", Number:1},&dictionary.Value{Attribute:"Framed-Routing", Name:"Listen", Number:2},&dictionary.Value{Attribute:"Framed-Routing", Name:"Broadcast-Listen", Number:3},&dictionary.Value{Attribute:"Framed-Compression", Name:"None", Number:0},&dictionary.Value{Attribute:"Framed-Compression", Name:"Van-Jacobson-TCP-IP", Number:1},&dictionary.Value{Attribute:"Framed-Compression", Name:"IPX-Header-Compression", Number:2},&dictionary.Value{Attribute:"Framed-Compression", Name:"Stac-LZS", Number:3},&dictionary.Value{Attribute:"Login-Service", Name:"Telnet", Number:0},&dictionary.Value{Attribute:"Login-Service", Name:"Rlogin", Number:1},&dictionary.Value{Attribute:"Login-Service", Name:"TCP-Clear", Number:2},&dictionary.Value{Attribute:"Login-Service", Name:"PortMaster", Number:3},&dictionary.Value{Attribute:"Login-Service", Name:"LAT", Number:4},&dictionary.Value{Attribute:"Login-Service", Name:"X25-PAD", Number:5},&dictionary.Value{Attribute:"Login-Service", Name:"X25-T3POS", Number:6},&dictionary.Value{Attribute:"Login-Service", Name:"TCP-Clear-Quiet", Number:8},&dictionary.Value{Attribute:"Login-TCP-Port", Name:"Telnet", Number:23},&dictionary.Value{Attribute:"Login-TCP-Port", Name:"Rlogin", Number:513},&dictionary.Value{Attribute:"Login-TCP-Port", Name:"Rsh", Number:514},&dictionary.Value{Attribute:"Termination-Action", Name:"Default", Number:0},&dictionary.Value{Attribute:"Termination-Action", Name:"RADIUS-Request", Number:1},&dictionary.Value{Attribute:"NAS-Port-Type", Name:"Async", Number:0},&dictionary.Value{Attribute:"NAS-Port-Type", Name:"Sync", Number:1},&dictionary.Value{Attribute:"NAS-Port-Type", Name:"ISDN", Number:2},&dictionary.Value{Attribute:"NAS-Port-Type", Name:"ISDN-V120", Number:3},&dictionary.Value{Attribute:"NAS-Port-Type", Name:"ISDN-V110", Number:4},&dictionary.Value{Attribute:"NAS-Port-Type", Name:"Virtual", Number:5},&dictionary.Value{Attribute:"NAS-Port-Type", Name:"PIAFS", Number:6},&dictionary.Value{Attribute:"NAS-Port-Type", Name:"HDLC-Clear-Channel", Number:7},&dictionary.Value{Attribute:"NAS-Port-Type", Name:"X.25", Number:8},&dictionary.Value{Attribute:"NAS-Port-Type", Name:"X.75", Number:9},&dictionary.Value{Attribute:"NAS-Port-Type", Name:"G.3-Fax", Number:10},&dictionary.Value{Attribute:"NAS-Port-Type", Name:"SDSL", Number:11},&dictionary.Value{Attribute:"NAS-Port-Type", Name:"ADSL-CAP", Number:12},&dictionary.Value{Attribute:"NAS-Port-Type", Name:"ADSL-DMT", Number:13},&dictionary.Value{Attribute:"NAS-Port-Type", Name:"IDSL", Number:14},&dictionary.Value{Attribute:"NAS-Port-Type", Name:"Ethernet", Number:15},&dictionary.Value{Attribute:"NAS-Port-Type", Name:"xDSL", Number:16},&dictionary.Value{Attribute:"NAS-Port-Type", Name:"Cable", Number:17},&dictionary.Value{Attribute:"NAS-Port-Type", Name:"Wireless-Other", Number:18},&dictionary.Value{Attribute:"NAS-Port-Type", Name:"Wireless-802.11", Number:19},&dictionary.Value{Attribute:"Acct-Status-Type", Name:"Start", Number:1},&dictionary.Value{Attribute:"Acct-Status-Type", Name:"Stop", Number:2},&dictionary.Value{Attribute:"Acct-Status-Type", Name:"Alive", Number:3},&dictionary.Value{Attribute:"Acct-Status-Type", Name:"Interim-Update", Number:3},&dictionary.Value{Attribute:"Acct-Status-Type", Name:"Accounting-On", Number:7},&dictionary.Value{Attribute:"Acct-Status-Type", Name:"Accounting-Off", Number:8},&dictionary.Value{Attribute:"Acct-Status-Type", Name:"Failed", Number:15},&dictionary.Value{Attribute:"Acct-Authentic", Name:"RADIUS", Number:1},&dictionary.Value{Attribute:"Acct-Authentic", Name:"Local", Number:2},&dictionary.Value{Attribute:"Acct-Authentic", Name:"Remote", Number:3},&dictionary.Value{Attribute:"Acct-Authentic", Name:"Diameter", Number:4},&dictionary.Value{Attribute:"Acct-Terminate-Cause", Name:"User-Request", Number:1},&dictionary.Value{Attribute:"Acct-Terminate-Cause", Name:"Lost-Carrier", Number:2},&dictionary.Value{Attribute:"Acct-Terminate-Cause", Name:"Lost-Service", Number:3},&dictionary.Value{Attribute:"Acct-Terminate-Cause", Name:"Idle-Timeout", Number:4},&dictionary.Value{Attribute:"Acct-Terminate-Cause", Name:"Session-Timeout", Number:5},&dictionary.Value{Attribute:"Acct-Terminate-Cause", Name:"Admin-Reset", Number:6},&dictionary.Value{Attribute:"Acct-Terminate-Cause", Name:"Admin-Reboot", Number:7},&dictionary.Value{Attribute:"Acct-Terminate-Cause", Name:"Port-Error", Number:8},&dictionary.Value{Attribute:"Acct-Terminate-Cause", Name:"NAS-Error", Number:9},&dictionary.Value{Attribute:"Acct-Terminate-Cause", Name:"NAS-Request", Number:10},&dictionary.Value{Attribute:"Acct-Terminate-Cause", Name:"NAS-Reboot", Number:11},&dictionary.Value{Attribute:"Acct-Terminate-Cause", Name:"Port-Unneeded", Number:12},&dictionary.Value{Attribute:"Acct-Terminate-Cause", Name:"Port-Preempted", Number:13},&dictionary.Value{Attribute:"Acct-Terminate-Cause", Name:"Port-Suspended", Number:14},&dictionary.Value{Attribute:"Acct-Terminate-Cause", Name:"Service-Unavailable", Number:15},&dictionary.Value{Attribute:"Acct-Terminate-Cause", Name:"Callback", Number:16},&dictionary.Value{Attribute:"Acct-Terminate-Cause", Name:"User-Error", Number:17},&dictionary.Value{Attribute:"Acct-Terminate-Cause", Name:"Host-Request", Number:18},&dictionary.Value{Attribute:"Acct-Status-Type", Name:"Tunnel-Start", Number:9},&dictionary.Value{Attribute:"Acct-Status-Type", Name:"Tunnel-Stop", Number:10},&dictionary.Value{Attribute:"Acct-Status-Type", Name:"Tunnel-Reject", Number:11},&dictionary.Value{Attribute:"Acct-Status-Type", Name:"Tunnel-Link-Start", Number:12},&dictionary.Value{Attribute:"Acct-Status-Type", Name:"Tunnel-Link-Stop", Number:13},&dictionary.Value{Attribute:"Acct-Status-Type", Name:"Tunnel-Link-Reject", Number:14},&dictionary.Value{Attribute:"ARAP-Zone-Access", Name:"Default-Zone", Number:1},&dictionary.Value{Attribute:"ARAP-Zone-Access", Name:"Zone-Filter-Inclusive", Number:2},&dictionary.Value{Attribute:"ARAP-Zone-Access", Name:"Zone-Filter-Exclusive", Number:4},&dictionary.Value{Attribute:"Prompt", Name:"No-Echo", Number:0},&dictionary.Value{Attribute:"Prompt", Name:"Echo", Number:1},&dictionary.Value{Attribute:"Service-Type", Name:"Authorize-Only", Number:17},&dictionary.Value{Attribute:"Error-Cause", Name:"Residual-Context-Removed", Number:201},&dictionary.Value{Attribute:"Error-Cause", Name:"Invalid-EAP-Packet", Number:202},&dictionary.Value{Attribute:"Error-Cause", Name:"Unsupported-Attribute", Number:401},&dictionary.Value{Attribute:"Error-Cause", Name:"Missing-Attribute", Number:402},&dictionary.Value{Attribute:"Error-Cause", Name:"NAS-Identification-Mismatch", Number:403},&dictionary.Value{Attribute:"Error-Cause", Name:"Invalid-Request", Number:404},&dictionary.Value{Attribute:"Error-Cause", Name:"Unsupported-Service", Number:405},&dictionary.Value{Attribute:"Error-Cause", Name:"Unsupported-Extension", Number:406},&dictionary.Value{Attribute:"Error-Cause", Name:"Administratively-Prohibited", Number:501},&dictionary.Value{Attribute:"Error-Cause", Name:"Proxy-Request-Not-Routable", Number:502},&dictionary.Value{Attribute:"Error-Cause", Name:"Session-Context-Not-Found", Number:503},&dictionary.Value{Attribute:"Error-Cause", Name:"Session-Context-Not-Removable", Number:504},&dictionary.Value{Attribute:"Error-Cause", Name:"Proxy-Processing-Error", Number:505},&dictionary.Value{Attribute:"Error-Cause", Name:"Resources-Unavailable", Number:506},&dictionary.Value{Attribute:"Error-Cause", Name:"Request-Initiated", Number:507},&dictionary.Value{Attribute:"Error-Cause", Name:"Invalid-Attribute-Value", Number:407},&dictionary.Value{Attribute:"Error-Cause", Name:"Multiple-Session-Selection-Unsupported", Number:508},},} +var IncludedDictionary = &dictionary.Dictionary{Attributes:[]*dictionary.Attribute{&dictionary.Attribute{Name:"User-Name",OID:dictionary.OID{1},Type:1,},&dictionary.Attribute{Name:"User-Password",OID:dictionary.OID{2},Type:1,FlagEncrypt:dictionary.IntFlag{Int:1, Valid:true},},&dictionary.Attribute{Name:"CHAP-Password",OID:dictionary.OID{3},Type:2,},&dictionary.Attribute{Name:"NAS-IP-Address",OID:dictionary.OID{4},Type:3,},&dictionary.Attribute{Name:"NAS-Port",OID:dictionary.OID{5},Type:5,},&dictionary.Attribute{Name:"Service-Type",OID:dictionary.OID{6},Type:5,},&dictionary.Attribute{Name:"Framed-Protocol",OID:dictionary.OID{7},Type:5,},&dictionary.Attribute{Name:"Framed-IP-Address",OID:dictionary.OID{8},Type:3,},&dictionary.Attribute{Name:"Framed-IP-Netmask",OID:dictionary.OID{9},Type:3,},&dictionary.Attribute{Name:"Framed-Routing",OID:dictionary.OID{10},Type:5,},&dictionary.Attribute{Name:"Filter-Id",OID:dictionary.OID{11},Type:1,},&dictionary.Attribute{Name:"Framed-MTU",OID:dictionary.OID{12},Type:5,},&dictionary.Attribute{Name:"Framed-Compression",OID:dictionary.OID{13},Type:5,},&dictionary.Attribute{Name:"Login-IP-Host",OID:dictionary.OID{14},Type:3,},&dictionary.Attribute{Name:"Login-Service",OID:dictionary.OID{15},Type:5,},&dictionary.Attribute{Name:"Login-TCP-Port",OID:dictionary.OID{16},Type:5,},&dictionary.Attribute{Name:"Reply-Message",OID:dictionary.OID{18},Type:1,},&dictionary.Attribute{Name:"Callback-Number",OID:dictionary.OID{19},Type:1,},&dictionary.Attribute{Name:"Callback-Id",OID:dictionary.OID{20},Type:1,},&dictionary.Attribute{Name:"Framed-Route",OID:dictionary.OID{22},Type:1,},&dictionary.Attribute{Name:"Framed-IPX-Network",OID:dictionary.OID{23},Type:3,},&dictionary.Attribute{Name:"State",OID:dictionary.OID{24},Type:2,},&dictionary.Attribute{Name:"Class",OID:dictionary.OID{25},Type:2,},&dictionary.Attribute{Name:"Vendor-Specific",OID:dictionary.OID{26},Type:10,},&dictionary.Attribute{Name:"Session-Timeout",OID:dictionary.OID{27},Type:5,},&dictionary.Attribute{Name:"Idle-Timeout",OID:dictionary.OID{28},Type:5,},&dictionary.Attribute{Name:"Termination-Action",OID:dictionary.OID{29},Type:5,},&dictionary.Attribute{Name:"Called-Station-Id",OID:dictionary.OID{30},Type:1,},&dictionary.Attribute{Name:"Calling-Station-Id",OID:dictionary.OID{31},Type:1,},&dictionary.Attribute{Name:"NAS-Identifier",OID:dictionary.OID{32},Type:1,},&dictionary.Attribute{Name:"Proxy-State",OID:dictionary.OID{33},Type:2,},&dictionary.Attribute{Name:"Login-LAT-Service",OID:dictionary.OID{34},Type:1,},&dictionary.Attribute{Name:"Login-LAT-Node",OID:dictionary.OID{35},Type:1,},&dictionary.Attribute{Name:"Login-LAT-Group",OID:dictionary.OID{36},Type:2,},&dictionary.Attribute{Name:"Framed-AppleTalk-Link",OID:dictionary.OID{37},Type:5,},&dictionary.Attribute{Name:"Framed-AppleTalk-Network",OID:dictionary.OID{38},Type:5,},&dictionary.Attribute{Name:"Framed-AppleTalk-Zone",OID:dictionary.OID{39},Type:1,},&dictionary.Attribute{Name:"CHAP-Challenge",OID:dictionary.OID{60},Type:2,},&dictionary.Attribute{Name:"NAS-Port-Type",OID:dictionary.OID{61},Type:5,},&dictionary.Attribute{Name:"Port-Limit",OID:dictionary.OID{62},Type:5,},&dictionary.Attribute{Name:"Login-LAT-Port",OID:dictionary.OID{63},Type:1,},&dictionary.Attribute{Name:"Acct-Status-Type",OID:dictionary.OID{40},Type:5,},&dictionary.Attribute{Name:"Acct-Delay-Time",OID:dictionary.OID{41},Type:5,},&dictionary.Attribute{Name:"Acct-Input-Octets",OID:dictionary.OID{42},Type:5,},&dictionary.Attribute{Name:"Acct-Output-Octets",OID:dictionary.OID{43},Type:5,},&dictionary.Attribute{Name:"Acct-Session-Id",OID:dictionary.OID{44},Type:1,},&dictionary.Attribute{Name:"Acct-Authentic",OID:dictionary.OID{45},Type:5,},&dictionary.Attribute{Name:"Acct-Session-Time",OID:dictionary.OID{46},Type:5,},&dictionary.Attribute{Name:"Acct-Input-Packets",OID:dictionary.OID{47},Type:5,},&dictionary.Attribute{Name:"Acct-Output-Packets",OID:dictionary.OID{48},Type:5,},&dictionary.Attribute{Name:"Acct-Terminate-Cause",OID:dictionary.OID{49},Type:5,},&dictionary.Attribute{Name:"Acct-Multi-Session-Id",OID:dictionary.OID{50},Type:1,},&dictionary.Attribute{Name:"Acct-Link-Count",OID:dictionary.OID{51},Type:5,},&dictionary.Attribute{Name:"Acct-Tunnel-Connection",OID:dictionary.OID{68},Type:1,},&dictionary.Attribute{Name:"Acct-Tunnel-Packets-Lost",OID:dictionary.OID{86},Type:5,},&dictionary.Attribute{Name:"Acct-Input-Gigawords",OID:dictionary.OID{52},Type:5,},&dictionary.Attribute{Name:"Acct-Output-Gigawords",OID:dictionary.OID{53},Type:5,},&dictionary.Attribute{Name:"Event-Timestamp",OID:dictionary.OID{55},Type:4,},&dictionary.Attribute{Name:"ARAP-Password",OID:dictionary.OID{70},Type:2,Size:dictionary.IntFlag{Int:16, Valid:true},},&dictionary.Attribute{Name:"ARAP-Features",OID:dictionary.OID{71},Type:2,Size:dictionary.IntFlag{Int:14, Valid:true},},&dictionary.Attribute{Name:"ARAP-Zone-Access",OID:dictionary.OID{72},Type:5,},&dictionary.Attribute{Name:"ARAP-Security",OID:dictionary.OID{73},Type:5,},&dictionary.Attribute{Name:"ARAP-Security-Data",OID:dictionary.OID{74},Type:1,},&dictionary.Attribute{Name:"Password-Retry",OID:dictionary.OID{75},Type:5,},&dictionary.Attribute{Name:"Prompt",OID:dictionary.OID{76},Type:5,},&dictionary.Attribute{Name:"Connect-Info",OID:dictionary.OID{77},Type:1,},&dictionary.Attribute{Name:"Configuration-Token",OID:dictionary.OID{78},Type:1,},&dictionary.Attribute{Name:"EAP-Message",OID:dictionary.OID{79},Type:2,FlagConcat:dictionary.BoolFlag{Bool:true, Valid:true},},&dictionary.Attribute{Name:"Message-Authenticator",OID:dictionary.OID{80},Type:2,},&dictionary.Attribute{Name:"ARAP-Challenge-Response",OID:dictionary.OID{84},Type:2,Size:dictionary.IntFlag{Int:8, Valid:true},},&dictionary.Attribute{Name:"Acct-Interim-Interval",OID:dictionary.OID{85},Type:5,},&dictionary.Attribute{Name:"NAS-Port-Id",OID:dictionary.OID{87},Type:1,},&dictionary.Attribute{Name:"Framed-Pool",OID:dictionary.OID{88},Type:1,},&dictionary.Attribute{Name:"NAS-IPv6-Address",OID:dictionary.OID{95},Type:6,},&dictionary.Attribute{Name:"Framed-Interface-Id",OID:dictionary.OID{96},Type:8,},&dictionary.Attribute{Name:"Framed-IPv6-Prefix",OID:dictionary.OID{97},Type:7,},&dictionary.Attribute{Name:"Login-IPv6-Host",OID:dictionary.OID{98},Type:6,},&dictionary.Attribute{Name:"Framed-IPv6-Route",OID:dictionary.OID{99},Type:1,},&dictionary.Attribute{Name:"Framed-IPv6-Pool",OID:dictionary.OID{100},Type:1,},&dictionary.Attribute{Name:"Error-Cause",OID:dictionary.OID{101},Type:5,},},Values:[]*dictionary.Value{&dictionary.Value{Attribute:"Service-Type", Name:"Login-User", Number:0x1},&dictionary.Value{Attribute:"Service-Type", Name:"Framed-User", Number:0x2},&dictionary.Value{Attribute:"Service-Type", Name:"Callback-Login-User", Number:0x3},&dictionary.Value{Attribute:"Service-Type", Name:"Callback-Framed-User", Number:0x4},&dictionary.Value{Attribute:"Service-Type", Name:"Outbound-User", Number:0x5},&dictionary.Value{Attribute:"Service-Type", Name:"Administrative-User", Number:0x6},&dictionary.Value{Attribute:"Service-Type", Name:"NAS-Prompt-User", Number:0x7},&dictionary.Value{Attribute:"Service-Type", Name:"Authenticate-Only", Number:0x8},&dictionary.Value{Attribute:"Service-Type", Name:"Callback-NAS-Prompt", Number:0x9},&dictionary.Value{Attribute:"Service-Type", Name:"Call-Check", Number:0xa},&dictionary.Value{Attribute:"Service-Type", Name:"Callback-Administrative", Number:0xb},&dictionary.Value{Attribute:"Framed-Protocol", Name:"PPP", Number:0x1},&dictionary.Value{Attribute:"Framed-Protocol", Name:"SLIP", Number:0x2},&dictionary.Value{Attribute:"Framed-Protocol", Name:"ARAP", Number:0x3},&dictionary.Value{Attribute:"Framed-Protocol", Name:"Gandalf-SLML", Number:0x4},&dictionary.Value{Attribute:"Framed-Protocol", Name:"Xylogics-IPX-SLIP", Number:0x5},&dictionary.Value{Attribute:"Framed-Protocol", Name:"X.75-Synchronous", Number:0x6},&dictionary.Value{Attribute:"Framed-Routing", Name:"None", Number:0x0},&dictionary.Value{Attribute:"Framed-Routing", Name:"Broadcast", Number:0x1},&dictionary.Value{Attribute:"Framed-Routing", Name:"Listen", Number:0x2},&dictionary.Value{Attribute:"Framed-Routing", Name:"Broadcast-Listen", Number:0x3},&dictionary.Value{Attribute:"Framed-Compression", Name:"None", Number:0x0},&dictionary.Value{Attribute:"Framed-Compression", Name:"Van-Jacobson-TCP-IP", Number:0x1},&dictionary.Value{Attribute:"Framed-Compression", Name:"IPX-Header-Compression", Number:0x2},&dictionary.Value{Attribute:"Framed-Compression", Name:"Stac-LZS", Number:0x3},&dictionary.Value{Attribute:"Login-Service", Name:"Telnet", Number:0x0},&dictionary.Value{Attribute:"Login-Service", Name:"Rlogin", Number:0x1},&dictionary.Value{Attribute:"Login-Service", Name:"TCP-Clear", Number:0x2},&dictionary.Value{Attribute:"Login-Service", Name:"PortMaster", Number:0x3},&dictionary.Value{Attribute:"Login-Service", Name:"LAT", Number:0x4},&dictionary.Value{Attribute:"Login-Service", Name:"X25-PAD", Number:0x5},&dictionary.Value{Attribute:"Login-Service", Name:"X25-T3POS", Number:0x6},&dictionary.Value{Attribute:"Login-Service", Name:"TCP-Clear-Quiet", Number:0x8},&dictionary.Value{Attribute:"Login-TCP-Port", Name:"Telnet", Number:0x17},&dictionary.Value{Attribute:"Login-TCP-Port", Name:"Rlogin", Number:0x201},&dictionary.Value{Attribute:"Login-TCP-Port", Name:"Rsh", Number:0x202},&dictionary.Value{Attribute:"Termination-Action", Name:"Default", Number:0x0},&dictionary.Value{Attribute:"Termination-Action", Name:"RADIUS-Request", Number:0x1},&dictionary.Value{Attribute:"NAS-Port-Type", Name:"Async", Number:0x0},&dictionary.Value{Attribute:"NAS-Port-Type", Name:"Sync", Number:0x1},&dictionary.Value{Attribute:"NAS-Port-Type", Name:"ISDN", Number:0x2},&dictionary.Value{Attribute:"NAS-Port-Type", Name:"ISDN-V120", Number:0x3},&dictionary.Value{Attribute:"NAS-Port-Type", Name:"ISDN-V110", Number:0x4},&dictionary.Value{Attribute:"NAS-Port-Type", Name:"Virtual", Number:0x5},&dictionary.Value{Attribute:"NAS-Port-Type", Name:"PIAFS", Number:0x6},&dictionary.Value{Attribute:"NAS-Port-Type", Name:"HDLC-Clear-Channel", Number:0x7},&dictionary.Value{Attribute:"NAS-Port-Type", Name:"X.25", Number:0x8},&dictionary.Value{Attribute:"NAS-Port-Type", Name:"X.75", Number:0x9},&dictionary.Value{Attribute:"NAS-Port-Type", Name:"G.3-Fax", Number:0xa},&dictionary.Value{Attribute:"NAS-Port-Type", Name:"SDSL", Number:0xb},&dictionary.Value{Attribute:"NAS-Port-Type", Name:"ADSL-CAP", Number:0xc},&dictionary.Value{Attribute:"NAS-Port-Type", Name:"ADSL-DMT", Number:0xd},&dictionary.Value{Attribute:"NAS-Port-Type", Name:"IDSL", Number:0xe},&dictionary.Value{Attribute:"NAS-Port-Type", Name:"Ethernet", Number:0xf},&dictionary.Value{Attribute:"NAS-Port-Type", Name:"xDSL", Number:0x10},&dictionary.Value{Attribute:"NAS-Port-Type", Name:"Cable", Number:0x11},&dictionary.Value{Attribute:"NAS-Port-Type", Name:"Wireless-Other", Number:0x12},&dictionary.Value{Attribute:"NAS-Port-Type", Name:"Wireless-802.11", Number:0x13},&dictionary.Value{Attribute:"Acct-Status-Type", Name:"Start", Number:0x1},&dictionary.Value{Attribute:"Acct-Status-Type", Name:"Stop", Number:0x2},&dictionary.Value{Attribute:"Acct-Status-Type", Name:"Alive", Number:0x3},&dictionary.Value{Attribute:"Acct-Status-Type", Name:"Interim-Update", Number:0x3},&dictionary.Value{Attribute:"Acct-Status-Type", Name:"Accounting-On", Number:0x7},&dictionary.Value{Attribute:"Acct-Status-Type", Name:"Accounting-Off", Number:0x8},&dictionary.Value{Attribute:"Acct-Status-Type", Name:"Failed", Number:0xf},&dictionary.Value{Attribute:"Acct-Authentic", Name:"RADIUS", Number:0x1},&dictionary.Value{Attribute:"Acct-Authentic", Name:"Local", Number:0x2},&dictionary.Value{Attribute:"Acct-Authentic", Name:"Remote", Number:0x3},&dictionary.Value{Attribute:"Acct-Authentic", Name:"Diameter", Number:0x4},&dictionary.Value{Attribute:"Acct-Terminate-Cause", Name:"User-Request", Number:0x1},&dictionary.Value{Attribute:"Acct-Terminate-Cause", Name:"Lost-Carrier", Number:0x2},&dictionary.Value{Attribute:"Acct-Terminate-Cause", Name:"Lost-Service", Number:0x3},&dictionary.Value{Attribute:"Acct-Terminate-Cause", Name:"Idle-Timeout", Number:0x4},&dictionary.Value{Attribute:"Acct-Terminate-Cause", Name:"Session-Timeout", Number:0x5},&dictionary.Value{Attribute:"Acct-Terminate-Cause", Name:"Admin-Reset", Number:0x6},&dictionary.Value{Attribute:"Acct-Terminate-Cause", Name:"Admin-Reboot", Number:0x7},&dictionary.Value{Attribute:"Acct-Terminate-Cause", Name:"Port-Error", Number:0x8},&dictionary.Value{Attribute:"Acct-Terminate-Cause", Name:"NAS-Error", Number:0x9},&dictionary.Value{Attribute:"Acct-Terminate-Cause", Name:"NAS-Request", Number:0xa},&dictionary.Value{Attribute:"Acct-Terminate-Cause", Name:"NAS-Reboot", Number:0xb},&dictionary.Value{Attribute:"Acct-Terminate-Cause", Name:"Port-Unneeded", Number:0xc},&dictionary.Value{Attribute:"Acct-Terminate-Cause", Name:"Port-Preempted", Number:0xd},&dictionary.Value{Attribute:"Acct-Terminate-Cause", Name:"Port-Suspended", Number:0xe},&dictionary.Value{Attribute:"Acct-Terminate-Cause", Name:"Service-Unavailable", Number:0xf},&dictionary.Value{Attribute:"Acct-Terminate-Cause", Name:"Callback", Number:0x10},&dictionary.Value{Attribute:"Acct-Terminate-Cause", Name:"User-Error", Number:0x11},&dictionary.Value{Attribute:"Acct-Terminate-Cause", Name:"Host-Request", Number:0x12},&dictionary.Value{Attribute:"Acct-Status-Type", Name:"Tunnel-Start", Number:0x9},&dictionary.Value{Attribute:"Acct-Status-Type", Name:"Tunnel-Stop", Number:0xa},&dictionary.Value{Attribute:"Acct-Status-Type", Name:"Tunnel-Reject", Number:0xb},&dictionary.Value{Attribute:"Acct-Status-Type", Name:"Tunnel-Link-Start", Number:0xc},&dictionary.Value{Attribute:"Acct-Status-Type", Name:"Tunnel-Link-Stop", Number:0xd},&dictionary.Value{Attribute:"Acct-Status-Type", Name:"Tunnel-Link-Reject", Number:0xe},&dictionary.Value{Attribute:"ARAP-Zone-Access", Name:"Default-Zone", Number:0x1},&dictionary.Value{Attribute:"ARAP-Zone-Access", Name:"Zone-Filter-Inclusive", Number:0x2},&dictionary.Value{Attribute:"ARAP-Zone-Access", Name:"Zone-Filter-Exclusive", Number:0x4},&dictionary.Value{Attribute:"Prompt", Name:"No-Echo", Number:0x0},&dictionary.Value{Attribute:"Prompt", Name:"Echo", Number:0x1},&dictionary.Value{Attribute:"Service-Type", Name:"Authorize-Only", Number:0x11},&dictionary.Value{Attribute:"Error-Cause", Name:"Residual-Context-Removed", Number:0xc9},&dictionary.Value{Attribute:"Error-Cause", Name:"Invalid-EAP-Packet", Number:0xca},&dictionary.Value{Attribute:"Error-Cause", Name:"Unsupported-Attribute", Number:0x191},&dictionary.Value{Attribute:"Error-Cause", Name:"Missing-Attribute", Number:0x192},&dictionary.Value{Attribute:"Error-Cause", Name:"NAS-Identification-Mismatch", Number:0x193},&dictionary.Value{Attribute:"Error-Cause", Name:"Invalid-Request", Number:0x194},&dictionary.Value{Attribute:"Error-Cause", Name:"Unsupported-Service", Number:0x195},&dictionary.Value{Attribute:"Error-Cause", Name:"Unsupported-Extension", Number:0x196},&dictionary.Value{Attribute:"Error-Cause", Name:"Administratively-Prohibited", Number:0x1f5},&dictionary.Value{Attribute:"Error-Cause", Name:"Proxy-Request-Not-Routable", Number:0x1f6},&dictionary.Value{Attribute:"Error-Cause", Name:"Session-Context-Not-Found", Number:0x1f7},&dictionary.Value{Attribute:"Error-Cause", Name:"Session-Context-Not-Removable", Number:0x1f8},&dictionary.Value{Attribute:"Error-Cause", Name:"Proxy-Processing-Error", Number:0x1f9},&dictionary.Value{Attribute:"Error-Cause", Name:"Resources-Unavailable", Number:0x1fa},&dictionary.Value{Attribute:"Error-Cause", Name:"Request-Initiated", Number:0x1fb},&dictionary.Value{Attribute:"Error-Cause", Name:"Invalid-Attribute-Value", Number:0x197},&dictionary.Value{Attribute:"Error-Cause", Name:"Multiple-Session-Selection-Unsupported", Number:0x1fc},},} diff --git a/dictionarygen/attributes.go b/dictionarygen/attributes.go index 3c7bcc25..4ccf7882 100644 --- a/dictionarygen/attributes.go +++ b/dictionarygen/attributes.go @@ -5,7 +5,7 @@ import ( "net" "strconv" - "layeh.com/radius/dictionary" + "github.com/holgermetschulat/radius/dictionary" ) func (g *Generator) genAttributeStringOctets(w io.Writer, attr *dictionary.Attribute, vendor *dictionary.Vendor) { @@ -37,7 +37,7 @@ func (g *Generator) genAttributeStringOctets(w io.Writer, attr *dictionary.Attri p(w, ` return`) p(w, ` }`) p(w, ` salt[0] |= 1 << 7`) // RFC 2868 § 3.5 - p(w, ` a, err = radius.NewTunnelPassword(value, salt[:], p.Secret, p.Authenticator[:])`) + p(w, ` a, err = radius.NewTunnelPassword(value, salt[:], p.Secret, p.CryptoAuthenticator[:])`) } else { p(w, ` a, err = radius.NewBytes(value)`) } @@ -79,7 +79,7 @@ func (g *Generator) genAttributeStringOctets(w io.Writer, attr *dictionary.Attri p(w, ` return`) p(w, ` }`) p(w, ` salt[0] |= 1 << 7`) // RFC 2868 § 3.5 - p(w, ` a, err = radius.NewTunnelPassword([]byte(value), salt[:], p.Secret, p.Authenticator[:])`) + p(w, ` a, err = radius.NewTunnelPassword([]byte(value), salt[:], p.Secret, p.CryptoAuthenticator[:])`) } else { p(w, ` a, err = radius.NewString(value)`) } @@ -147,7 +147,7 @@ func (g *Generator) genAttributeStringOctets(w io.Writer, attr *dictionary.Attri if attr.FlagEncrypt.Valid && attr.FlagEncrypt.Int == dictionary.EncryptUserPassword { p(w, ` i, err = radius.UserPassword(attr, p.Secret, p.Authenticator[:])`) } else if attr.FlagEncrypt.Valid && attr.FlagEncrypt.Int == dictionary.EncryptTunnelPassword { - p(w, ` i, _, err = radius.TunnelPassword(attr, p.Secret, p.Authenticator[:])`) + p(w, ` i, _, err = radius.TunnelPassword(attr, p.Secret, p.CryptoAuthenticator[:])`) } else { p(w, ` i = radius.Bytes(attr)`) } @@ -198,7 +198,7 @@ func (g *Generator) genAttributeStringOctets(w io.Writer, attr *dictionary.Attri p(w, ` }`) } else if attr.FlagEncrypt.Valid && attr.FlagEncrypt.Int == dictionary.EncryptTunnelPassword { p(w, ` var up []byte`) - p(w, ` up, _, err = radius.TunnelPassword(attr, p.Secret, p.Authenticator[:])`) + p(w, ` up, _, err = radius.TunnelPassword(attr, p.Secret, p.CryptoAuthenticator[:])`) p(w, ` if err == nil {`) p(w, ` i = string(up)`) p(w, ` }`) @@ -245,7 +245,7 @@ func (g *Generator) genAttributeStringOctets(w io.Writer, attr *dictionary.Attri if attr.FlagEncrypt.Valid && attr.FlagEncrypt.Int == dictionary.EncryptUserPassword { p(w, ` value, err = radius.UserPassword(a, p.Secret, p.Authenticator[:])`) } else if attr.FlagEncrypt.Valid && attr.FlagEncrypt.Int == dictionary.EncryptTunnelPassword { - p(w, ` value, _, err = radius.TunnelPassword(a, p.Secret, p.Authenticator[:])`) + p(w, ` value, _, err = radius.TunnelPassword(a, p.Secret, p.CryptoAuthenticator[:])`) } else { p(w, ` value = radius.Bytes(a)`) } @@ -286,7 +286,7 @@ func (g *Generator) genAttributeStringOctets(w io.Writer, attr *dictionary.Attri p(w, ` }`) } else if attr.FlagEncrypt.Valid && attr.FlagEncrypt.Int == dictionary.EncryptTunnelPassword { p(w, ` var b []byte`) - p(w, ` b, _, err = radius.TunnelPassword(a, p.Secret, p.Authenticator[:])`) + p(w, ` b, _, err = radius.TunnelPassword(a, p.Secret, p.CryptoAuthenticator[:])`) p(w, ` if err == nil {`) p(w, ` value = string(b)`) p(w, ` }`) @@ -323,7 +323,7 @@ func (g *Generator) genAttributeStringOctets(w io.Writer, attr *dictionary.Attri p(w, ` return`) p(w, ` }`) p(w, ` salt[0] |= 1 << 7`) // RFC 2868 § 3.5 - p(w, ` a, err = radius.NewTunnelPassword(value, salt[:], p.Secret, p.Authenticator[:])`) + p(w, ` a, err = radius.NewTunnelPassword(value, salt[:], p.Secret, p.CryptoAuthenticator[:])`) } else { p(w, ` a, err = radius.NewBytes(value)`) } @@ -365,7 +365,7 @@ func (g *Generator) genAttributeStringOctets(w io.Writer, attr *dictionary.Attri p(w, ` return`) p(w, ` }`) p(w, ` salt[0] |= 1 << 7`) // RFC 2868 § 3.5 - p(w, ` a, err = radius.NewTunnelPassword([]byte(value), salt[:], p.Secret, p.Authenticator[:])`) + p(w, ` a, err = radius.NewTunnelPassword([]byte(value), salt[:], p.Secret, p.CryptoAuthenticator[:])`) } else { p(w, ` a, err = radius.NewString(value)`) } @@ -530,6 +530,9 @@ func (g *Generator) genAttributeIPAddr(w io.Writer, attr *dictionary.Attribute, p(w, ` if err != nil {`) p(w, ` return`) p(w, ` }`) + + genEncryptAttribute(w, attr.FlagEncrypt) + if vendor != nil { p(w, ` return _`, vendorIdent, `_AddVendor(p, `, strconv.Itoa(attr.OID[0]), `, a)`) } else { @@ -556,6 +559,9 @@ func (g *Generator) genAttributeIPAddr(w io.Writer, attr *dictionary.Attribute, p(w, ` }`) p(w, ` attr := avp.Attribute`) } + + genDecryptAttributes(w, attr.FlagEncrypt) + if length == net.IPv4len { p(w, ` i, err = radius.IPAddr(attr)`) } else { @@ -580,6 +586,9 @@ func (g *Generator) genAttributeIPAddr(w io.Writer, attr *dictionary.Attribute, p(w, ` err = radius.ErrNoAttribute`) p(w, ` return`) p(w, ` }`) + + genDecryptAttribute(w, attr.FlagEncrypt) + if length == net.IPv4len { p(w, ` value, err = radius.IPAddr(a)`) } else { @@ -599,6 +608,9 @@ func (g *Generator) genAttributeIPAddr(w io.Writer, attr *dictionary.Attribute, p(w, ` if err != nil {`) p(w, ` return`) p(w, ` }`) + + genEncryptAttribute(w, attr.FlagEncrypt) + if vendor != nil { p(w, ` return _`, vendorIdent, `_SetVendor(p, `, strconv.Itoa(attr.OID[0]), `, a)`) } else { @@ -958,6 +970,9 @@ func (g *Generator) genAttributeInteger(w io.Writer, attr *dictionary.Attribute, p(w, ` a[0] = 0x00`) p(w, ` }`) } + + genEncryptAttribute(w, attr.FlagEncrypt) + if vendor != nil { p(w, ` return _`, vendorIdent, `_AddVendor(p, `, strconv.Itoa(attr.OID[0]), `, a)`) } else { @@ -1006,6 +1021,7 @@ func (g *Generator) genAttributeInteger(w io.Writer, attr *dictionary.Attribute, p(w, ` attr[0] = 0x00`) p(w, ` }`) } + genDecryptAttributes(w, attr.FlagEncrypt) if bitsize == 64 { p(w, ` i, err = radius.Integer64(attr)`) } else if bitsize == 16 { @@ -1042,18 +1058,30 @@ func (g *Generator) genAttributeInteger(w io.Writer, attr *dictionary.Attribute, if attr.HasTag() { p(w, ` if len(a) >= 1 && a[0] <= 0x1F {`) p(w, ` tag = a[0]`) - p(w, ` a[0] = 0x00`) +// p(w, ` a[0] = 0x00`) p(w, ` }`) } + + genDecryptAttribute(w, attr.FlagEncrypt) + if bitsize == 64 { p(w, ` var i uint64`) p(w, ` i, err = radius.Integer64(a)`) + if attr.HasTag() { + p(w, ` i = i & 0xffffffffffffff // remove tag in the upper 8 bits`) + } } else if bitsize == 16 { p(w, ` var i uint16`) p(w, ` i, err = radius.Short(a)`) + if attr.HasTag() { + p(w, ` i = i & 0xff // remove tag in the upper 8 bits`) + } } else { // 32 p(w, ` var i uint32`) p(w, ` i, err = radius.Integer(a)`) + if attr.HasTag() { + p(w, ` i = i & 0xffffff // remove tag in the upper 8 bits`) + } } p(w, ` if err != nil {`) p(w, ` return`) @@ -1075,6 +1103,7 @@ func (g *Generator) genAttributeInteger(w io.Writer, attr *dictionary.Attribute, } else { // 32 p(w, ` a := radius.NewInteger(uint32(value))`) } + if attr.HasTag() { p(w, ` if tag >= 0x01 && tag <= 0x1F {`) p(w, ` a[0] = tag`) @@ -1082,6 +1111,9 @@ func (g *Generator) genAttributeInteger(w io.Writer, attr *dictionary.Attribute, p(w, ` a[0] = 0x00`) p(w, ` }`) } + + genEncryptAttribute(w, attr.FlagEncrypt) + if vendor != nil { p(w, ` return _`, vendorIdent, `_SetVendor(p, `, strconv.Itoa(attr.OID[0]), `, a)`) } else { @@ -1100,6 +1132,54 @@ func (g *Generator) genAttributeInteger(w io.Writer, attr *dictionary.Attribute, p(w, `}`) } +func genEncryptAttribute(w io.Writer, encryptFlag dictionary.IntFlag) { + if encryptFlag.Valid && encryptFlag.Int == dictionary.EncryptUserPassword { + p(w, ` a, err = radius.NewUserPassword(a, p.Secret, p.Authenticator[:])`) + p(w, ` if err != nil {`) + p(w, ` return`) + p(w, ` }`) + } else if encryptFlag.Valid && encryptFlag.Int == dictionary.EncryptTunnelPassword { + p(w, ` var salt [2]byte`) + p(w, ` _, err = rand.Read(salt[:])`) + p(w, ` if err != nil {`) + p(w, ` return`) + p(w, ` }`) + p(w, ` salt[0] |= 1 << 7`) // RFC 2868 § 3.5 + p(w, ` a, err = radius.NewTunnelPassword(a, salt[:], p.Secret, p.CryptoAuthenticator[:])`) + p(w, ` if err != nil {`) + p(w, ` return`) + p(w, ` }`) + } +} + +func genDecryptAttribute(w io.Writer, encryptFlag dictionary.IntFlag) { + if encryptFlag.Valid && encryptFlag.Int == dictionary.EncryptUserPassword { + p(w, ` a, err = radius.UserPassword(a, p.Secret, p.Authenticator[:])`) + p(w, ` if err != nil {`) + p(w, ` return`) + p(w, ` }`) + } else if encryptFlag.Valid && encryptFlag.Int == dictionary.EncryptTunnelPassword { + p(w, ` a, _, err = radius.TunnelPassword(a, p.Secret, p.CryptoAuthenticator[:])`) + p(w, ` if err != nil {`) + p(w, ` return`) + p(w, ` }`) + } +} + +func genDecryptAttributes(w io.Writer, encryptFlag dictionary.IntFlag) { + if encryptFlag.Valid && encryptFlag.Int == dictionary.EncryptUserPassword { + p(w, ` attr, err = radius.UserPassword(attr, p.Secret, p.Authenticator[:])`) + p(w, ` if err != nil {`) + p(w, ` return`) + p(w, ` }`) + } else if encryptFlag.Valid && encryptFlag.Int == dictionary.EncryptTunnelPassword { + p(w, ` attr, _, err = radius.TunnelPassword(attr, p.Secret, p.CryptoAuthenticator[:])`) + p(w, ` if err != nil {`) + p(w, ` return`) + p(w, ` }`) + } +} + func (g *Generator) genAttributeByte(w io.Writer, attr *dictionary.Attribute, vendor *dictionary.Vendor) { ident := identifier(attr.Name) var vendorIdent string diff --git a/dictionarygen/generator.go b/dictionarygen/generator.go index 15629e67..61f7c979 100644 --- a/dictionarygen/generator.go +++ b/dictionarygen/generator.go @@ -8,7 +8,7 @@ import ( "net" "strconv" - "layeh.com/radius/dictionary" + "github.com/holgermetschulat/radius/dictionary" ) type externalAttribute struct { @@ -73,6 +73,7 @@ func (g *Generator) Generate(dict *dictionary.Dictionary) ([]byte, error) { switch attr.Type { case dictionary.AttributeString: case dictionary.AttributeOctets: + case dictionary.AttributeABinary: case dictionary.AttributeIPAddr, dictionary.AttributeIPv6Addr, dictionary.AttributeIPv6Prefix, dictionary.AttributeIFID: baseImports["net"] = struct{}{} case dictionary.AttributeDate: @@ -181,6 +182,7 @@ func (g *Generator) Generate(dict *dictionary.Dictionary) ([]byte, error) { switch attr.Type { case dictionary.AttributeString: case dictionary.AttributeOctets: + case dictionary.AttributeABinary: case dictionary.AttributeIPAddr, dictionary.AttributeIPv6Addr, dictionary.AttributeIPv6Prefix, dictionary.AttributeIFID: baseImports["net"] = struct{}{} case dictionary.AttributeDate: @@ -239,10 +241,10 @@ func (g *Generator) Generate(dict *dictionary.Dictionary) ([]byte, error) { } if len(attrs) > 0 || len(vendors) > 0 { p(&w) - p(&w, ` "layeh.com/radius"`) + p(&w, ` "github.com/holgermetschulat/radius"`) } if len(vendors) > 0 { - p(&w, ` "layeh.com/radius/rfc2865"`) + p(&w, ` "github.com/holgermetschulat/radius/rfc2865"`) } if len(externalAttributes) > 0 { printedNewLine := false @@ -299,7 +301,7 @@ func (g *Generator) Generate(dict *dictionary.Dictionary) ([]byte, error) { for _, attr := range attrs { switch attr.Type { - case dictionary.AttributeString, dictionary.AttributeOctets: + case dictionary.AttributeString, dictionary.AttributeOctets, dictionary.AttributeABinary: if attr.FlagConcat.Valid && attr.FlagConcat.Bool { g.genAttributeStringOctetsConcat(&w, attr) } else { @@ -332,7 +334,7 @@ func (g *Generator) Generate(dict *dictionary.Dictionary) ([]byte, error) { g.genVendor(&w, vendor) for _, attr := range vendor.Attributes { switch attr.Type { - case dictionary.AttributeString, dictionary.AttributeOctets: + case dictionary.AttributeString, dictionary.AttributeOctets, dictionary.AttributeABinary: g.genAttributeStringOctets(&w, attr, vendor) case dictionary.AttributeIPAddr: g.genAttributeIPAddr(&w, attr, vendor, net.IPv4len) diff --git a/dictionarygen/generator_test.go b/dictionarygen/generator_test.go index b25e37a0..d4b26a97 100644 --- a/dictionarygen/generator_test.go +++ b/dictionarygen/generator_test.go @@ -14,7 +14,7 @@ import ( "strings" "testing" - "layeh.com/radius/dictionary" + "github.com/holgermetschulat/radius/dictionary" ) func TestTestData(t *testing.T) { diff --git a/dictionarygen/vendor.go b/dictionarygen/vendor.go index 8a1befe4..34faff75 100644 --- a/dictionarygen/vendor.go +++ b/dictionarygen/vendor.go @@ -3,7 +3,7 @@ package dictionarygen import ( "io" - "layeh.com/radius/dictionary" + "github.com/holgermetschulat/radius/dictionary" ) func (g *Generator) genVendor(w io.Writer, vendor *dictionary.Vendor) { @@ -76,41 +76,12 @@ func (g *Generator) genVendor(w io.Writer, vendor *dictionary.Vendor) { p(w) p(w, `func _`, ident, `_SetVendor(p *radius.Packet, typ byte, attr radius.Attribute) (err error) {`) - p(w, ` for i := 0; i < len(p.Attributes); {`) - p(w, ` avp := p.Attributes[i]`) - p(w, ` if avp.Type != rfc2865.VendorSpecific_Type {`) - p(w, ` i++`) - p(w, ` continue`) - p(w, ` }`) - p(w, ` vendorID, vsa, err := radius.VendorSpecific(avp.Attribute)`) - p(w, ` if err != nil || vendorID != _`, ident, `_VendorID {`) - p(w, ` i++`) - p(w, ` continue`) - p(w, ` }`) - p(w, ` for j := 0; len(vsa[j:]) >= 3; {`) - p(w, ` vsaTyp, vsaLen := vsa[0], vsa[1]`) - p(w, ` if int(vsaLen) > len(vsa[j:]) || vsaLen < 3 {`) // malformed - p(w, ` i++`) - p(w, ` break`) - p(w, ` }`) - p(w, ` if vsaTyp == typ {`) - p(w, ` vsa = append(vsa[:j], vsa[j+int(vsaLen):]...)`) - p(w, ` }`) - p(w, ` j += int(vsaLen)`) - p(w, ` }`) - p(w, ` if len(vsa) > 0 {`) - p(w, ` copy(avp.Attribute[4:], vsa)`) - p(w, ` i++`) - p(w, ` } else {`) - p(w, ` p.Attributes = append(p.Attributes[:i], p.Attributes[i+i:]...)`) - p(w, ` }`) - p(w, ` }`) + p(w, ` _`, ident, `_DelVendor(p, typ)`) p(w, ` return _`, ident, `_AddVendor(p, typ, attr)`) p(w, `}`) p(w) p(w, `func _`, ident, `_DelVendor(p *radius.Packet, typ byte) {`) - p(w, `vsaLoop:`) p(w, ` for i := 0; i < len(p.Attributes); {`) p(w, ` avp := p.Attributes[i]`) p(w, ` if avp.Type != rfc2865.VendorSpecific_Type {`) @@ -126,7 +97,7 @@ func (g *Generator) genVendor(w io.Writer, vendor *dictionary.Vendor) { p(w, ` for len(vsa[offset:]) >= 3 {`) p(w, ` vsaTyp, vsaLen := vsa[offset], vsa[offset+1]`) p(w, ` if int(vsaLen) > len(vsa) || vsaLen < 3 {`) // malformed - p(w, ` continue vsaLoop`) + p(w, ` break`) // skip this p(w, ` }`) p(w, ` if vsaTyp == typ {`) p(w, ` copy(vsa[offset:], vsa[offset+int(vsaLen):])`) @@ -135,9 +106,10 @@ func (g *Generator) genVendor(w io.Writer, vendor *dictionary.Vendor) { p(w, ` offset += int(vsaLen)`) p(w, ` }`) p(w, ` }`) - p(w, ` if offset == 0 {`) + p(w, ` if len(vsa) == 0 {`) p(w, ` p.Attributes = append(p.Attributes[:i], p.Attributes[i+1:]...)`) p(w, ` } else {`) + p(w, ` p.Attributes[i].Attribute = append(avp.Attribute[:4], vsa...)`) p(w, ` i++`) p(w, ` }`) p(w, ` }`) diff --git a/go.mod b/go.mod index 2eeb207a..d902b4f2 100644 --- a/go.mod +++ b/go.mod @@ -1,8 +1,10 @@ -module layeh.com/radius +module github.com/holgermetschulat/radius go 1.12 require ( + github.com/stretchr/testify v1.6.1 golang.org/x/crypto v0.0.0-20200709230013-948cd5f35899 golang.org/x/text v0.3.3 + layeh.com/radius v0.0.0-20201203135236-838e26d0c9be ) diff --git a/go.sum b/go.sum index 8188409c..a2ec9c1d 100644 --- a/go.sum +++ b/go.sum @@ -1,3 +1,10 @@ +github.com/davecgh/go-spew v1.1.0 h1:ZDRjVQ15GmhC3fiQ8ni8+OwkZQO4DARzQgrnXU1Liz8= +github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= +github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= +github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= +github.com/stretchr/testify v1.6.1 h1:hDPOHmpOpP40lSULcqw7IrRb/u7w6RpDC9399XyoNd0= +github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/crypto v0.0.0-20200709230013-948cd5f35899 h1:DZhuSZLsGlFL4CmhA8BcRA0mnthyA/nZ00AqCUo7vHg= golang.org/x/crypto v0.0.0-20200709230013-948cd5f35899/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= @@ -8,3 +15,9 @@ golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.3 h1:cokOdA+Jmi5PJGXLlLllQSgYigAEfHXJAERHVMaCc2k= golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM= +gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c h1:dUUwHk2QECo/6vqA44rthZ8ie2QXMNeKRTHCNY2nXvo= +gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= +layeh.com/radius v0.0.0-20201203135236-838e26d0c9be h1:4YeDNYYOf9Pnn3pWEktFE+ZCZ5qX5ZVMaw3VAtfoXPk= +layeh.com/radius v0.0.0-20201203135236-838e26d0c9be/go.mod h1:pFWM9De99EY9TPVyHIyA56QmoRViVck/x41WFkUlc9A= diff --git a/packet.go b/packet.go index 7955760b..7b9ed65c 100644 --- a/packet.go +++ b/packet.go @@ -13,10 +13,11 @@ const MaxPacketLength = 4096 // Packet is a RADIUS packet. type Packet struct { - Code Code - Identifier byte - Authenticator [16]byte - Secret []byte + Code Code + Identifier byte + Authenticator [16]byte + CryptoAuthenticator [16]byte + Secret []byte Attributes } @@ -37,12 +38,18 @@ func New(code Code, secret []byte) *Packet { Secret: secret, } copy(packet.Authenticator[:], buff[1:]) + switch code { + case CodeAccountingRequest, CodeDisconnectRequest, CodeCoARequest: + // use null CryptoAuthenticator + default: + packet.CryptoAuthenticator = packet.Authenticator + } return packet } // Parse parses an encoded RADIUS packet b. An error is returned if the packet // is malformed. -func Parse(b, secret []byte) (*Packet, error) { +func Parse(b []byte, cryptoAuthenticator []byte, secret []byte) (*Packet, error) { if len(b) < 20 { return nil, errors.New("radius: packet not at least 20 bytes long") } @@ -52,6 +59,10 @@ func Parse(b, secret []byte) (*Packet, error) { return nil, errors.New("radius: invalid packet length") } + if len(cryptoAuthenticator) != 0 && len(cryptoAuthenticator) != 16 { + return nil, errors.New("cryptoAuthenticator has invalid length") + } + attrs, err := ParseAttributes(b[20:length]) if err != nil { return nil, err @@ -63,7 +74,16 @@ func Parse(b, secret []byte) (*Packet, error) { Secret: secret, Attributes: attrs, } + copy(packet.Authenticator[:], b[4:20]) + + switch packet.Code { + case CodeAccountingRequest, CodeDisconnectRequest, CodeCoARequest: + // use null CryptoAuthenticator + default: + copy(packet.CryptoAuthenticator[:], cryptoAuthenticator) + } + return packet, nil } @@ -75,7 +95,8 @@ func (p *Packet) Response(code Code) *Packet { Identifier: p.Identifier, Secret: p.Secret, } - copy(q.Authenticator[:], p.Authenticator[:]) + q.Authenticator = p.Authenticator + q.CryptoAuthenticator = p.Authenticator return q } diff --git a/packet_test.go b/packet_test.go index b12d6576..6fac5a6f 100644 --- a/packet_test.go +++ b/packet_test.go @@ -7,9 +7,9 @@ import ( "strings" "testing" - "layeh.com/radius" - "layeh.com/radius/rfc2865" - "layeh.com/radius/rfc2869" + "github.com/holgermetschulat/radius" + "github.com/holgermetschulat/radius/rfc2865" + "github.com/holgermetschulat/radius/rfc2869" ) func Test_RFC2865_7_1(t *testing.T) { @@ -25,7 +25,8 @@ func Test_RFC2865_7_1(t *testing.T) { 0x01, 0x10, 0x05, 0x06, 0x00, 0x00, 0x00, 0x03, } - p, err := radius.Parse(request, secret) + p, err := radius.Parse(request, nil, secret) + p.CryptoAuthenticator = p.Authenticator if err != nil { t.Fatal(err) } @@ -106,7 +107,7 @@ func Test_RFC2865_7_2(t *testing.T) { 0x02, 0x07, 0x06, 0x00, 0x00, 0x00, 0x01, } - p, err := radius.Parse(request, secret) + p, err := radius.Parse(request, nil, secret) if err != nil { t.Fatal(err) } @@ -142,7 +143,7 @@ func Test_RFC2865_7_2(t *testing.T) { 0x00, 0x01, 0x0c, 0x06, 0x00, 0x00, 0x05, 0xdc, } - p, err = radius.Parse(response, secret) + p, err = radius.Parse(response, nil, secret) if err != nil { t.Fatal(err) } @@ -180,7 +181,7 @@ func Test_RFC5997_6_1(t *testing.T) { 0x18, 0x5d, 0x06, 0x23, 0x50, 0x12, 0x5a, 0x66, 0x5e, 0x2e, 0x1e, 0x84, 0x11, 0xf3, 0xe2, 0x43, 0x82, 0x20, 0x97, 0xc8, 0x4f, 0xa3, } - p, err := radius.Parse(request, secret) + p, err := radius.Parse(request, nil, secret) if err != nil { t.Error(err) } @@ -238,7 +239,7 @@ func TestPasswords(t *testing.T) { t.Fatal(err) } - q, err := radius.Parse(b, secret) + q, err := radius.Parse(b, r.CryptoAuthenticator[:], secret) if err != nil { t.Fatal(err) } @@ -284,7 +285,7 @@ func TestParse_invalid(t *testing.T) { secret := []byte("12345") for _, test := range tests { - packet, err := radius.Parse([]byte(test.Wire), secret) + packet, err := radius.Parse([]byte(test.Wire), nil, secret) if packet != nil { t.Errorf("(%#x): expected empty packet, got %v", test.Wire, packet) } else if err == nil { @@ -311,7 +312,7 @@ func TestPacketMarshalBinary(t *testing.T) { 0x18, 0x5d, 0x06, 0x23, 0x50, 0x12, 0x5a, 0x66, 0x5e, 0x2e, 0x1e, 0x84, 0x11, 0xf3, 0xe2, 0x43, 0x82, 0x20, 0x97, 0xc8, 0x4f, 0xa3, } - p, err := radius.Parse(request, secret) + p, err := radius.Parse(request, nil, secret) if err != nil { t.Error(err) } diff --git a/rfc2865/generated.go b/rfc2865/generated.go index 7ec9e2e6..444eead2 100644 --- a/rfc2865/generated.go +++ b/rfc2865/generated.go @@ -6,7 +6,7 @@ import ( "net" "strconv" - "layeh.com/radius" + "github.com/holgermetschulat/radius" ) const ( diff --git a/rfc2865/generated_test.go b/rfc2865/generated_test.go new file mode 100644 index 00000000..1dcc3699 --- /dev/null +++ b/rfc2865/generated_test.go @@ -0,0 +1,87 @@ +package rfc2865 + +import ( + "context" + "net" + "testing" + "time" + + "github.com/holgermetschulat/radius" +) + +type TestServer struct { + Addr string + Server *radius.PacketServer + l net.PacketConn + serveErr error +} + +func (s *TestServer) Close() error { + return s.l.Close() +} + +func NewTestServer(handler radius.Handler, secretSource radius.SecretSource) *TestServer { + addr, err := net.ResolveUDPAddr("udp", "localhost:0") + if err != nil { + panic(err) + } + + conn, err := net.ListenUDP("udp", addr) + if err != nil { + panic(err) + } + + s := &TestServer{ + Addr: conn.LocalAddr().String(), + Server: &radius.PacketServer{ + Handler: handler, + SecretSource: secretSource, + }, + l: conn, + } + + go func() { + s.serveErr = s.Server.Serve(s.l) + }() + + return s +} + +func TestClientEncryption(t *testing.T) { + secret := []byte(`12345`) + expectedPassword := "testsecret" + + handler := radius.HandlerFunc(func(w radius.ResponseWriter, r *radius.Request) { + resp := r.Response(radius.CodeAccessAccept) + password := UserPassword_GetString(r.Packet) + if password != expectedPassword { + t.Fatalf("incorrect password: expected %v, got %v", expectedPassword, password) + } + err := w.Write(resp) + if err != nil { + t.Fatal(err) + } + }) + + server := NewTestServer(handler, radius.StaticSecretSource(secret)) + defer server.Close() + + req := radius.New(radius.CodeAccessRequest, secret) + err := UserPassword_SetString(req, expectedPassword) + if err != nil { + t.Fatalf("Exchange error %v", err) + } + + client := radius.Client{ + Retry: time.Millisecond * 50, + MaxPacketErrors: 2, + } + + ctx, cancel := context.WithTimeout(context.Background(), 100*time.Millisecond) + defer cancel() + + _, err = client.Exchange(ctx, req, server.Addr) + if err != nil { + t.Fatalf("Exchange error %v", err) + } +} diff --git a/rfc2866/generated.go b/rfc2866/generated.go index 8c91e309..51b617b2 100644 --- a/rfc2866/generated.go +++ b/rfc2866/generated.go @@ -5,7 +5,7 @@ package rfc2866 import ( "strconv" - "layeh.com/radius" + "github.com/holgermetschulat/radius" ) const ( diff --git a/rfc2867/generate.go b/rfc2867/generate.go index 6a30a2cf..dd850840 100644 --- a/rfc2867/generate.go +++ b/rfc2867/generate.go @@ -1,3 +1,3 @@ -//go:generate go run ../cmd/radius-dict-gen/main.go -package rfc2867 -output generated.go -ref Acct-Status-Type:layeh.com/radius/rfc2866 /usr/share/freeradius/dictionary.rfc2867 +//go:generate go run ../cmd/radius-dict-gen/main.go -package rfc2867 -output generated.go -ref Acct-Status-Type:github.com/holgermetschulat/radius/rfc2866 /usr/share/freeradius/dictionary.rfc2867 package rfc2867 diff --git a/rfc2867/generated.go b/rfc2867/generated.go index 801489cc..62839c3d 100644 --- a/rfc2867/generated.go +++ b/rfc2867/generated.go @@ -5,9 +5,9 @@ package rfc2867 import ( "strconv" - "layeh.com/radius" + "github.com/holgermetschulat/radius" - . "layeh.com/radius/rfc2866" + . "github.com/holgermetschulat/radius/rfc2866" ) const ( diff --git a/rfc2868/generated.go b/rfc2868/generated.go index 51f8d6d8..58735a0b 100644 --- a/rfc2868/generated.go +++ b/rfc2868/generated.go @@ -6,7 +6,7 @@ import ( "crypto/rand" "strconv" - "layeh.com/radius" + "github.com/holgermetschulat/radius" ) const ( @@ -107,10 +107,10 @@ func TunnelType_Lookup(p *radius.Packet) (tag byte, value TunnelType, err error) } if len(a) >= 1 && a[0] <= 0x1F { tag = a[0] - a[0] = 0x00 } var i uint32 i, err = radius.Integer(a) + i = i & 0xffffff // remove tag in the upper 8 bits if err != nil { return } @@ -224,10 +224,10 @@ func TunnelMediumType_Lookup(p *radius.Packet) (tag byte, value TunnelMediumType } if len(a) >= 1 && a[0] <= 0x1F { tag = a[0] - a[0] = 0x00 } var i uint32 i, err = radius.Integer(a) + i = i & 0xffffff // remove tag in the upper 8 bits if err != nil { return } @@ -534,7 +534,7 @@ func TunnelPassword_Add(p *radius.Packet, tag byte, value []byte) (err error) { return } salt[0] |= 1 << 7 - a, err = radius.NewTunnelPassword(value, salt[:], p.Secret, p.Authenticator[:]) + a, err = radius.NewTunnelPassword(value, salt[:], p.Secret, p.CryptoAuthenticator[:]) if err != nil { return } @@ -553,7 +553,7 @@ func TunnelPassword_AddString(p *radius.Packet, tag byte, value string) (err err return } salt[0] |= 1 << 7 - a, err = radius.NewTunnelPassword([]byte(value), salt[:], p.Secret, p.Authenticator[:]) + a, err = radius.NewTunnelPassword([]byte(value), salt[:], p.Secret, p.CryptoAuthenticator[:]) if err != nil { return } @@ -569,8 +569,8 @@ func TunnelPassword_Get(p *radius.Packet) (tag byte, value []byte) { return } -func TunnelPassword_GetString(p *radius.Packet) (tag byte, value string) { - tag, value, _ = TunnelPassword_LookupString(p) +func TunnelPassword_GetString(p *radius.Packet) (tag byte, value string, err error) { + tag, value, err = TunnelPassword_LookupString(p) return } @@ -586,7 +586,7 @@ func TunnelPassword_Gets(p *radius.Packet) (tags []byte, values [][]byte, err er tag = attr[0] attr = attr[1:] } - i, _, err = radius.TunnelPassword(attr, p.Secret, p.Authenticator[:]) + i, _, err = radius.TunnelPassword(attr, p.Secret, p.CryptoAuthenticator[:]) if err != nil { return } @@ -609,7 +609,7 @@ func TunnelPassword_GetStrings(p *radius.Packet) (tags []byte, values []string, attr = attr[1:] } var up []byte - up, _, err = radius.TunnelPassword(attr, p.Secret, p.Authenticator[:]) + up, _, err = radius.TunnelPassword(attr, p.Secret, p.CryptoAuthenticator[:]) if err == nil { i = string(up) } @@ -632,7 +632,7 @@ func TunnelPassword_Lookup(p *radius.Packet) (tag byte, value []byte, err error) tag = a[0] a = a[1:] } - value, _, err = radius.TunnelPassword(a, p.Secret, p.Authenticator[:]) + value, _, err = radius.TunnelPassword(a, p.Secret, p.CryptoAuthenticator[:]) return } @@ -647,7 +647,7 @@ func TunnelPassword_LookupString(p *radius.Packet) (tag byte, value string, err a = a[1:] } var b []byte - b, _, err = radius.TunnelPassword(a, p.Secret, p.Authenticator[:]) + b, _, err = radius.TunnelPassword(a, p.Secret, p.CryptoAuthenticator[:]) if err == nil { value = string(b) } @@ -662,7 +662,7 @@ func TunnelPassword_Set(p *radius.Packet, tag byte, value []byte) (err error) { return } salt[0] |= 1 << 7 - a, err = radius.NewTunnelPassword(value, salt[:], p.Secret, p.Authenticator[:]) + a, err = radius.NewTunnelPassword(value, salt[:], p.Secret, p.CryptoAuthenticator[:]) if err != nil { return } @@ -681,7 +681,7 @@ func TunnelPassword_SetString(p *radius.Packet, tag byte, value string) (err err return } salt[0] |= 1 << 7 - a, err = radius.NewTunnelPassword([]byte(value), salt[:], p.Secret, p.Authenticator[:]) + a, err = radius.NewTunnelPassword([]byte(value), salt[:], p.Secret, p.CryptoAuthenticator[:]) if err != nil { return } @@ -1029,10 +1029,10 @@ func TunnelPreference_Lookup(p *radius.Packet) (tag byte, value TunnelPreference } if len(a) >= 1 && a[0] <= 0x1F { tag = a[0] - a[0] = 0x00 } var i uint32 i, err = radius.Integer(a) + i = i & 0xffffff // remove tag in the upper 8 bits if err != nil { return } diff --git a/rfc2868/generated_test.go b/rfc2868/generated_test.go index 475f8a04..7d33ef52 100644 --- a/rfc2868/generated_test.go +++ b/rfc2868/generated_test.go @@ -4,7 +4,7 @@ import ( "bytes" "testing" - "layeh.com/radius" + "github.com/holgermetschulat/radius" ) func Test_TunnelPasswordAdd(t *testing.T) { @@ -13,6 +13,7 @@ func Test_TunnelPasswordAdd(t *testing.T) { Authenticator: [16]byte{0x0B, 0x00, 0x00, 0x07, 0x0B, 0x00, 0x00, 0x07, 0x0B, 0x00, 0x00, 0x07, 0x0B, 0x00, 0x00, 0x07}, Secret: []byte{0x0B, 0x00, 0x00, 0x07}, } + p.CryptoAuthenticator = p.Authenticator password := []byte{0x00, 0x01, 0xde, 0xaf, 0x0B, 0x00, 0x00, 0x07} if err := TunnelPassword_Add(p, 0, password); err != nil { t.Fatalf("TunnelPassword_Add unexpected err iteration %d: %s", i, err) @@ -35,6 +36,7 @@ func Test_TunnelPasswordSet(t *testing.T) { Authenticator: [16]byte{0x0B, 0x00, 0x00, 0x07, 0x0B, 0x00, 0x00, 0x07, 0x0B, 0x00, 0x00, 0x07, 0x0B, 0x00, 0x00, 0x07}, Secret: []byte{0x0B, 0x00, 0x00, 0x07}, } + p.CryptoAuthenticator = p.Authenticator password := []byte{0x00, 0x01, 0xde, 0xaf, 0x0B, 0x00, 0x00, 0x07} if err := TunnelPassword_Set(p, 0, password); err != nil { t.Fatalf("TunnelPassword_Set unexpected err iteration %d: %s", i, err) @@ -57,6 +59,7 @@ func Test_TunnelPasswordSetString(t *testing.T) { Authenticator: [16]byte{0x0B, 0x00, 0x00, 0x07, 0x0B, 0x00, 0x00, 0x07, 0x0B, 0x00, 0x00, 0x07, 0x0B, 0x00, 0x00, 0x07}, Secret: []byte{0x0B, 0x00, 0x00, 0x07}, } + p.CryptoAuthenticator = p.Authenticator password := "TunnelPassword" if err := TunnelPassword_SetString(p, 0, password); err != nil { t.Fatalf("TunnelPassword_SetString unexpected err iteration %d: %s", i, err) @@ -79,6 +82,7 @@ func Test_TunnelPasswordAddString(t *testing.T) { Authenticator: [16]byte{0x0B, 0x00, 0x00, 0x07, 0x0B, 0x00, 0x00, 0x07, 0x0B, 0x00, 0x00, 0x07, 0x0B, 0x00, 0x00, 0x07}, Secret: []byte{0x0B, 0x00, 0x00, 0x07}, } + p.CryptoAuthenticator = p.Authenticator password := "TunnelPassword" if err := TunnelPassword_AddString(p, 0, password); err != nil { t.Fatalf("TunnelPassword_AddString unexpected err iteration %d: %s", i, err) diff --git a/rfc2869/generated.go b/rfc2869/generated.go index 185ede82..aa970e3d 100644 --- a/rfc2869/generated.go +++ b/rfc2869/generated.go @@ -7,7 +7,7 @@ import ( "strconv" "time" - "layeh.com/radius" + "github.com/holgermetschulat/radius" ) const ( diff --git a/rfc2869/generated_test.go b/rfc2869/generated_test.go index dfa90a13..2bd05483 100644 --- a/rfc2869/generated_test.go +++ b/rfc2869/generated_test.go @@ -4,7 +4,7 @@ import ( "bytes" "testing" - "layeh.com/radius" + "github.com/holgermetschulat/radius" ) func TestEAPMessage(t *testing.T) { diff --git a/rfc3079/mppe.go b/rfc3079/mppe.go index 04bca59d..4d5cf978 100644 --- a/rfc3079/mppe.go +++ b/rfc3079/mppe.go @@ -4,7 +4,7 @@ import ( "crypto/sha1" "errors" - "layeh.com/radius/rfc2759" + "github.com/holgermetschulat/radius/rfc2759" ) // KeyLength is the length of keys involved with the functions below diff --git a/rfc3162/generated.go b/rfc3162/generated.go index 571e6cc7..5327aa79 100644 --- a/rfc3162/generated.go +++ b/rfc3162/generated.go @@ -5,7 +5,7 @@ package rfc3162 import ( "net" - "layeh.com/radius" + "github.com/holgermetschulat/radius" ) const ( diff --git a/rfc3576/generate.go b/rfc3576/generate.go index 937793cf..9a91afcc 100644 --- a/rfc3576/generate.go +++ b/rfc3576/generate.go @@ -1,3 +1,3 @@ -//go:generate go run ../cmd/radius-dict-gen/main.go -package rfc3576 -output generated.go -ref Service-Type:layeh.com/radius/rfc2865 /usr/share/freeradius/dictionary.rfc3576 +//go:generate go run ../cmd/radius-dict-gen/main.go -package rfc3576 -output generated.go -ref Service-Type:github.com/holgermetschulat/radius/rfc2865 /usr/share/freeradius/dictionary.rfc3576 package rfc3576 diff --git a/rfc3576/generated.go b/rfc3576/generated.go index 7cebc633..276c87ed 100644 --- a/rfc3576/generated.go +++ b/rfc3576/generated.go @@ -5,9 +5,9 @@ package rfc3576 import ( "strconv" - "layeh.com/radius" + "github.com/holgermetschulat/radius" - . "layeh.com/radius/rfc2865" + . "github.com/holgermetschulat/radius/rfc2865" ) const ( diff --git a/rfc3580/generate.go b/rfc3580/generate.go index 50e58d84..926c6468 100644 --- a/rfc3580/generate.go +++ b/rfc3580/generate.go @@ -1,3 +1,3 @@ -//go:generate go run ../cmd/radius-dict-gen/main.go -package rfc3580 -output generated.go -ref Acct-Terminate-Cause:layeh.com/radius/rfc2866 -ref NAS-Port-Type:layeh.com/radius/rfc2865 -ref Tunnel-Type:layeh.com/radius/rfc2868 /usr/share/freeradius/dictionary.rfc3580 +//go:generate go run ../cmd/radius-dict-gen/main.go -package rfc3580 -output generated.go -ref Acct-Terminate-Cause:github.com/holgermetschulat/radius/rfc2866 -ref NAS-Port-Type:github.com/holgermetschulat/radius/rfc2865 -ref Tunnel-Type:github.com/holgermetschulat/radius/rfc2868 /usr/share/freeradius/dictionary.rfc3580 package rfc3580 diff --git a/rfc3580/generated.go b/rfc3580/generated.go index 05fc767d..539aebdd 100644 --- a/rfc3580/generated.go +++ b/rfc3580/generated.go @@ -3,9 +3,9 @@ package rfc3580 import ( - . "layeh.com/radius/rfc2865" - . "layeh.com/radius/rfc2866" - . "layeh.com/radius/rfc2868" + . "github.com/holgermetschulat/radius/rfc2865" + . "github.com/holgermetschulat/radius/rfc2866" + . "github.com/holgermetschulat/radius/rfc2868" ) func init() { diff --git a/rfc4072/generated.go b/rfc4072/generated.go index e2febcaf..db5d1a79 100644 --- a/rfc4072/generated.go +++ b/rfc4072/generated.go @@ -3,7 +3,7 @@ package rfc4072 import ( - "layeh.com/radius" + "github.com/holgermetschulat/radius" ) const ( diff --git a/rfc4372/generate.go b/rfc4372/generate.go index 405bfaa1..71f4d888 100644 --- a/rfc4372/generate.go +++ b/rfc4372/generate.go @@ -1,3 +1,3 @@ -//go:generate go run ../cmd/radius-dict-gen/main.go -package rfc4372 -output generated.go -ref Error-Cause:layeh.com/radius/rfc3576 /usr/share/freeradius/dictionary.rfc4372 +//go:generate go run ../cmd/radius-dict-gen/main.go -package rfc4372 -output generated.go -ref Error-Cause:github.com/holgermetschulat/radius/rfc3576 /usr/share/freeradius/dictionary.rfc4372 package rfc4372 diff --git a/rfc4372/generated.go b/rfc4372/generated.go index c6219cf8..116325fb 100644 --- a/rfc4372/generated.go +++ b/rfc4372/generated.go @@ -3,7 +3,7 @@ package rfc4372 import ( - "layeh.com/radius" + "github.com/holgermetschulat/radius" ) const ( diff --git a/rfc4603/generate.go b/rfc4603/generate.go index 394cb1e4..871a3ed5 100644 --- a/rfc4603/generate.go +++ b/rfc4603/generate.go @@ -1,3 +1,3 @@ -//go:generate go run ../cmd/radius-dict-gen/main.go -package rfc4603 -output generated.go -ref NAS-Port-Type:layeh.com/radius/rfc2865 /usr/share/freeradius/dictionary.rfc4603 +//go:generate go run ../cmd/radius-dict-gen/main.go -package rfc4603 -output generated.go -ref NAS-Port-Type:github.com/holgermetschulat/radius/rfc2865 /usr/share/freeradius/dictionary.rfc4603 package rfc4603 diff --git a/rfc4603/generated.go b/rfc4603/generated.go index 8eb49413..deaefeac 100644 --- a/rfc4603/generated.go +++ b/rfc4603/generated.go @@ -3,7 +3,7 @@ package rfc4603 import ( - . "layeh.com/radius/rfc2865" + . "github.com/holgermetschulat/radius/rfc2865" ) func init() { diff --git a/rfc4675/generated.go b/rfc4675/generated.go index 00afdaf7..c2fa2fa4 100644 --- a/rfc4675/generated.go +++ b/rfc4675/generated.go @@ -5,7 +5,7 @@ package rfc4675 import ( "strconv" - "layeh.com/radius" + "github.com/holgermetschulat/radius" ) const ( diff --git a/rfc4679/generated.go b/rfc4679/generated.go index b27d8b9e..8014cda6 100644 --- a/rfc4679/generated.go +++ b/rfc4679/generated.go @@ -5,8 +5,8 @@ package rfc4679 import ( "strconv" - "layeh.com/radius" - "layeh.com/radius/rfc2865" + "github.com/holgermetschulat/radius" + "github.com/holgermetschulat/radius/rfc2865" ) const ( @@ -76,40 +76,11 @@ func _ADSLForum_LookupVendor(p *radius.Packet, typ byte) (attr radius.Attribute, } func _ADSLForum_SetVendor(p *radius.Packet, typ byte, attr radius.Attribute) (err error) { - for i := 0; i < len(p.Attributes); { - avp := p.Attributes[i] - if avp.Type != rfc2865.VendorSpecific_Type { - i++ - continue - } - vendorID, vsa, err := radius.VendorSpecific(avp.Attribute) - if err != nil || vendorID != _ADSLForum_VendorID { - i++ - continue - } - for j := 0; len(vsa[j:]) >= 3; { - vsaTyp, vsaLen := vsa[0], vsa[1] - if int(vsaLen) > len(vsa[j:]) || vsaLen < 3 { - i++ - break - } - if vsaTyp == typ { - vsa = append(vsa[:j], vsa[j+int(vsaLen):]...) - } - j += int(vsaLen) - } - if len(vsa) > 0 { - copy(avp.Attribute[4:], vsa) - i++ - } else { - p.Attributes = append(p.Attributes[:i], p.Attributes[i+i:]...) - } - } + _ADSLForum_DelVendor(p, typ) return _ADSLForum_AddVendor(p, typ, attr) } func _ADSLForum_DelVendor(p *radius.Packet, typ byte) { -vsaLoop: for i := 0; i < len(p.Attributes); { avp := p.Attributes[i] if avp.Type != rfc2865.VendorSpecific_Type { @@ -125,7 +96,7 @@ vsaLoop: for len(vsa[offset:]) >= 3 { vsaTyp, vsaLen := vsa[offset], vsa[offset+1] if int(vsaLen) > len(vsa) || vsaLen < 3 { - continue vsaLoop + break } if vsaTyp == typ { copy(vsa[offset:], vsa[offset+int(vsaLen):]) @@ -134,391 +105,16 @@ vsaLoop: offset += int(vsaLen) } } - if offset == 0 { + if len(vsa) == 0 { p.Attributes = append(p.Attributes[:i], p.Attributes[i+1:]...) } else { + p.Attributes[i].Attribute = append(avp.Attribute[:4], vsa...) i++ } } return } -func ADSLForumDeviceManufacturerOUI_Add(p *radius.Packet, value []byte) (err error) { - var a radius.Attribute - a, err = radius.NewBytes(value) - if err != nil { - return - } - return _ADSLForum_AddVendor(p, 255, a) -} - -func ADSLForumDeviceManufacturerOUI_AddString(p *radius.Packet, value string) (err error) { - var a radius.Attribute - a, err = radius.NewString(value) - if err != nil { - return - } - return _ADSLForum_AddVendor(p, 255, a) -} - -func ADSLForumDeviceManufacturerOUI_Get(p *radius.Packet) (value []byte) { - value, _ = ADSLForumDeviceManufacturerOUI_Lookup(p) - return -} - -func ADSLForumDeviceManufacturerOUI_GetString(p *radius.Packet) (value string) { - value, _ = ADSLForumDeviceManufacturerOUI_LookupString(p) - return -} - -func ADSLForumDeviceManufacturerOUI_Gets(p *radius.Packet) (values [][]byte, err error) { - var i []byte - for _, attr := range _ADSLForum_GetsVendor(p, 255) { - i = radius.Bytes(attr) - if err != nil { - return - } - values = append(values, i) - } - return -} - -func ADSLForumDeviceManufacturerOUI_GetStrings(p *radius.Packet) (values []string, err error) { - var i string - for _, attr := range _ADSLForum_GetsVendor(p, 255) { - i = radius.String(attr) - if err != nil { - return - } - values = append(values, i) - } - return -} - -func ADSLForumDeviceManufacturerOUI_Lookup(p *radius.Packet) (value []byte, err error) { - a, ok := _ADSLForum_LookupVendor(p, 255) - if !ok { - err = radius.ErrNoAttribute - return - } - value = radius.Bytes(a) - return -} - -func ADSLForumDeviceManufacturerOUI_LookupString(p *radius.Packet) (value string, err error) { - a, ok := _ADSLForum_LookupVendor(p, 255) - if !ok { - err = radius.ErrNoAttribute - return - } - value = radius.String(a) - return -} - -func ADSLForumDeviceManufacturerOUI_Set(p *radius.Packet, value []byte) (err error) { - var a radius.Attribute - a, err = radius.NewBytes(value) - if err != nil { - return - } - return _ADSLForum_SetVendor(p, 255, a) -} - -func ADSLForumDeviceManufacturerOUI_SetString(p *radius.Packet, value string) (err error) { - var a radius.Attribute - a, err = radius.NewString(value) - if err != nil { - return - } - return _ADSLForum_SetVendor(p, 255, a) -} - -func ADSLForumDeviceManufacturerOUI_Del(p *radius.Packet) { - _ADSLForum_DelVendor(p, 255) -} - -func ADSLForumDeviceSerialNumber_Add(p *radius.Packet, value []byte) (err error) { - var a radius.Attribute - a, err = radius.NewBytes(value) - if err != nil { - return - } - return _ADSLForum_AddVendor(p, 255, a) -} - -func ADSLForumDeviceSerialNumber_AddString(p *radius.Packet, value string) (err error) { - var a radius.Attribute - a, err = radius.NewString(value) - if err != nil { - return - } - return _ADSLForum_AddVendor(p, 255, a) -} - -func ADSLForumDeviceSerialNumber_Get(p *radius.Packet) (value []byte) { - value, _ = ADSLForumDeviceSerialNumber_Lookup(p) - return -} - -func ADSLForumDeviceSerialNumber_GetString(p *radius.Packet) (value string) { - value, _ = ADSLForumDeviceSerialNumber_LookupString(p) - return -} - -func ADSLForumDeviceSerialNumber_Gets(p *radius.Packet) (values [][]byte, err error) { - var i []byte - for _, attr := range _ADSLForum_GetsVendor(p, 255) { - i = radius.Bytes(attr) - if err != nil { - return - } - values = append(values, i) - } - return -} - -func ADSLForumDeviceSerialNumber_GetStrings(p *radius.Packet) (values []string, err error) { - var i string - for _, attr := range _ADSLForum_GetsVendor(p, 255) { - i = radius.String(attr) - if err != nil { - return - } - values = append(values, i) - } - return -} - -func ADSLForumDeviceSerialNumber_Lookup(p *radius.Packet) (value []byte, err error) { - a, ok := _ADSLForum_LookupVendor(p, 255) - if !ok { - err = radius.ErrNoAttribute - return - } - value = radius.Bytes(a) - return -} - -func ADSLForumDeviceSerialNumber_LookupString(p *radius.Packet) (value string, err error) { - a, ok := _ADSLForum_LookupVendor(p, 255) - if !ok { - err = radius.ErrNoAttribute - return - } - value = radius.String(a) - return -} - -func ADSLForumDeviceSerialNumber_Set(p *radius.Packet, value []byte) (err error) { - var a radius.Attribute - a, err = radius.NewBytes(value) - if err != nil { - return - } - return _ADSLForum_SetVendor(p, 255, a) -} - -func ADSLForumDeviceSerialNumber_SetString(p *radius.Packet, value string) (err error) { - var a radius.Attribute - a, err = radius.NewString(value) - if err != nil { - return - } - return _ADSLForum_SetVendor(p, 255, a) -} - -func ADSLForumDeviceSerialNumber_Del(p *radius.Packet) { - _ADSLForum_DelVendor(p, 255) -} - -func ADSLForumDeviceProductClass_Add(p *radius.Packet, value []byte) (err error) { - var a radius.Attribute - a, err = radius.NewBytes(value) - if err != nil { - return - } - return _ADSLForum_AddVendor(p, 255, a) -} - -func ADSLForumDeviceProductClass_AddString(p *radius.Packet, value string) (err error) { - var a radius.Attribute - a, err = radius.NewString(value) - if err != nil { - return - } - return _ADSLForum_AddVendor(p, 255, a) -} - -func ADSLForumDeviceProductClass_Get(p *radius.Packet) (value []byte) { - value, _ = ADSLForumDeviceProductClass_Lookup(p) - return -} - -func ADSLForumDeviceProductClass_GetString(p *radius.Packet) (value string) { - value, _ = ADSLForumDeviceProductClass_LookupString(p) - return -} - -func ADSLForumDeviceProductClass_Gets(p *radius.Packet) (values [][]byte, err error) { - var i []byte - for _, attr := range _ADSLForum_GetsVendor(p, 255) { - i = radius.Bytes(attr) - if err != nil { - return - } - values = append(values, i) - } - return -} - -func ADSLForumDeviceProductClass_GetStrings(p *radius.Packet) (values []string, err error) { - var i string - for _, attr := range _ADSLForum_GetsVendor(p, 255) { - i = radius.String(attr) - if err != nil { - return - } - values = append(values, i) - } - return -} - -func ADSLForumDeviceProductClass_Lookup(p *radius.Packet) (value []byte, err error) { - a, ok := _ADSLForum_LookupVendor(p, 255) - if !ok { - err = radius.ErrNoAttribute - return - } - value = radius.Bytes(a) - return -} - -func ADSLForumDeviceProductClass_LookupString(p *radius.Packet) (value string, err error) { - a, ok := _ADSLForum_LookupVendor(p, 255) - if !ok { - err = radius.ErrNoAttribute - return - } - value = radius.String(a) - return -} - -func ADSLForumDeviceProductClass_Set(p *radius.Packet, value []byte) (err error) { - var a radius.Attribute - a, err = radius.NewBytes(value) - if err != nil { - return - } - return _ADSLForum_SetVendor(p, 255, a) -} - -func ADSLForumDeviceProductClass_SetString(p *radius.Packet, value string) (err error) { - var a radius.Attribute - a, err = radius.NewString(value) - if err != nil { - return - } - return _ADSLForum_SetVendor(p, 255, a) -} - -func ADSLForumDeviceProductClass_Del(p *radius.Packet) { - _ADSLForum_DelVendor(p, 255) -} - -func ADSLForumGatewayManufacturerOUI_Add(p *radius.Packet, value []byte) (err error) { - var a radius.Attribute - a, err = radius.NewBytes(value) - if err != nil { - return - } - return _ADSLForum_AddVendor(p, 255, a) -} - -func ADSLForumGatewayManufacturerOUI_AddString(p *radius.Packet, value string) (err error) { - var a radius.Attribute - a, err = radius.NewString(value) - if err != nil { - return - } - return _ADSLForum_AddVendor(p, 255, a) -} - -func ADSLForumGatewayManufacturerOUI_Get(p *radius.Packet) (value []byte) { - value, _ = ADSLForumGatewayManufacturerOUI_Lookup(p) - return -} - -func ADSLForumGatewayManufacturerOUI_GetString(p *radius.Packet) (value string) { - value, _ = ADSLForumGatewayManufacturerOUI_LookupString(p) - return -} - -func ADSLForumGatewayManufacturerOUI_Gets(p *radius.Packet) (values [][]byte, err error) { - var i []byte - for _, attr := range _ADSLForum_GetsVendor(p, 255) { - i = radius.Bytes(attr) - if err != nil { - return - } - values = append(values, i) - } - return -} - -func ADSLForumGatewayManufacturerOUI_GetStrings(p *radius.Packet) (values []string, err error) { - var i string - for _, attr := range _ADSLForum_GetsVendor(p, 255) { - i = radius.String(attr) - if err != nil { - return - } - values = append(values, i) - } - return -} - -func ADSLForumGatewayManufacturerOUI_Lookup(p *radius.Packet) (value []byte, err error) { - a, ok := _ADSLForum_LookupVendor(p, 255) - if !ok { - err = radius.ErrNoAttribute - return - } - value = radius.Bytes(a) - return -} - -func ADSLForumGatewayManufacturerOUI_LookupString(p *radius.Packet) (value string, err error) { - a, ok := _ADSLForum_LookupVendor(p, 255) - if !ok { - err = radius.ErrNoAttribute - return - } - value = radius.String(a) - return -} - -func ADSLForumGatewayManufacturerOUI_Set(p *radius.Packet, value []byte) (err error) { - var a radius.Attribute - a, err = radius.NewBytes(value) - if err != nil { - return - } - return _ADSLForum_SetVendor(p, 255, a) -} - -func ADSLForumGatewayManufacturerOUI_SetString(p *radius.Packet, value string) (err error) { - var a radius.Attribute - a, err = radius.NewString(value) - if err != nil { - return - } - return _ADSLForum_SetVendor(p, 255, a) -} - -func ADSLForumGatewayManufacturerOUI_Del(p *radius.Packet) { - _ADSLForum_DelVendor(p, 255) -} - func ADSLAgentCircuitID_Add(p *radius.Packet, value []byte) (err error) { var a radius.Attribute a, err = radius.NewBytes(value) diff --git a/rfc4679/generated_test.go b/rfc4679/generated_test.go new file mode 100644 index 00000000..3071128f --- /dev/null +++ b/rfc4679/generated_test.go @@ -0,0 +1,227 @@ +package rfc4679 + +import ( + "testing" + + "github.com/holgermetschulat/radius" + "github.com/holgermetschulat/radius/rfc2865" + "github.com/holgermetschulat/radius/rfc2866" + "github.com/stretchr/testify/assert" +) + +func TestSetVendorMalformedVSAs(t *testing.T) { + a := assert.New(t) + var err error + + packet := radius.New(radius.CodeAccessAccept, []byte("secret")) + + malformedTooShort := radius.Attribute([]byte{1, 1, 1}) + malformedTooShortVendor, err := radius.NewVendorSpecific(_ADSLForum_VendorID, malformedTooShort) + a.Nil(err) + malformedTooShortAVP := &radius.AVP{ + Type: rfc2865.VendorSpecific_Type, + Attribute: malformedTooShortVendor, + } + + malformedTooLong := radius.Attribute([]byte{1, 255, 1}) + malformedTooLongVendor, err := radius.NewVendorSpecific(_ADSLForum_VendorID, malformedTooLong) + a.Nil(err) + malformedTooLongAVP := &radius.AVP{ + Type: rfc2865.VendorSpecific_Type, + Attribute: malformedTooLongVendor, + } + packet.Attributes = append(packet.Attributes, malformedTooShortAVP, malformedTooLongAVP) + + attr := radius.Attribute([]byte("asdf")) + err = _ADSLForum_SetVendor(packet, 1, attr) + a.Nil(err) + err = _ADSLForum_SetVendor(packet, 1, attr) + a.Nil(err) + + adslAttribsType1 := _ADSLForum_GetsVendor(packet, 1) + a.Len(adslAttribsType1, 1) + a.Len(packet.Attributes, 3) // malformed attributes despite of being the same type are not being overwritten +} + +func TestSetVendorGroupedMalformedVSAs(t *testing.T) { + a := assert.New(t) + var err error + + packet := radius.New(radius.CodeAccessAccept, []byte("secret")) + + malformedGrouped := radius.Attribute([]byte{ 1, 3, 'X' , 1, 255, 1}) + malformedGroupedVendor, err := radius.NewVendorSpecific(_ADSLForum_VendorID, malformedGrouped) + a.Nil(err) + malformedGroupedAVP := &radius.AVP{ + Type: rfc2865.VendorSpecific_Type, + Attribute: malformedGroupedVendor, + } + + packet.Attributes = append(packet.Attributes, malformedGroupedAVP) + + attr := radius.Attribute([]byte("asdf")) + err = _ADSLForum_SetVendor(packet, 1, attr) + a.Nil(err) + err = _ADSLForum_SetVendor(packet, 1, attr) + a.Nil(err) + + adslAttribsType1 := _ADSLForum_GetsVendor(packet, 1) + a.Len(adslAttribsType1, 1) // in the grouped VSAs the valid vsa is removed, the malformed one is not removed but it is not returned here as it is invalid + + a.Len(packet.Attributes, 2) + for _,a := range packet.Attributes { + t.Logf("%+v",a) + } +} + +func TestSetVendorGroupedVSAs(t *testing.T) { + a := assert.New(t) + + packet := radius.New(radius.CodeAccessAccept, []byte("secret")) + + groupedVSAs := radius.Attribute([]byte{1, 3, 1, 2, 3, 1}) + groupedVendorVSAs, err := radius.NewVendorSpecific(_ADSLForum_VendorID, groupedVSAs) + a.Nil(err) + malformed := &radius.AVP{ + Type: rfc2865.VendorSpecific_Type, + Attribute: groupedVendorVSAs, + } + packet.Attributes = append(packet.Attributes, malformed) + + attr := radius.Attribute([]byte("asdf")) + err = _ADSLForum_SetVendor(packet, 1, attr) + a.Nil(err) + err = _ADSLForum_SetVendor(packet, 1, attr) + a.Nil(err) + + adslAttribsType1 := _ADSLForum_GetsVendor(packet, 1) + a.Len(adslAttribsType1, 1) + a.Len(packet.Attributes, 2) +} + +func TestSetVendor(t *testing.T) { + a := assert.New(t) + + packet := radius.New(radius.CodeAccessAccept, []byte("secret")) + + err := rfc2866.AcctStatusType_Set(packet, rfc2866.AcctStatusType_Value_Start) + a.Nil(err) + err = rfc2866.AcctInputOctets_Set(packet, rfc2866.AcctInputOctets(1)) + a.Nil(err) + + attr := radius.Attribute([]byte("asdf")) + err = _ADSLForum_SetVendor(packet, 2, attr) + a.Nil(err) + err = _ADSLForum_SetVendor(packet, 1, attr) + a.Nil(err) + err = _ADSLForum_SetVendor(packet, 1, attr) + a.Nil(err) + + adslAttribsType1 := _ADSLForum_GetsVendor(packet, 1) + a.Len(adslAttribsType1, 1) + adslAttribsType2 := _ADSLForum_GetsVendor(packet, 2) + a.Len(adslAttribsType2, 1) + a.Len(packet.Attributes, 4) +} + +func TestSetVendorNoStandardAttributes(t *testing.T) { + a := assert.New(t) + + packet := radius.New(radius.CodeAccessAccept, []byte("secret")) + + attr := radius.Attribute([]byte("asdf")) + err := _ADSLForum_SetVendor(packet, 1, attr) + a.Nil(err) + err = _ADSLForum_SetVendor(packet, 2, attr) + a.Nil(err) + err = _ADSLForum_SetVendor(packet, 1, attr) + a.Nil(err) + + adslAttribsType1 := _ADSLForum_GetsVendor(packet, 1) + a.Len(adslAttribsType1, 1) + adslAttribsType2 := _ADSLForum_GetsVendor(packet, 2) + a.Len(adslAttribsType2, 1) + a.Len(packet.Attributes, 2) +} + +func TestSetVendorNoVendorAttributes(t *testing.T) { + a := assert.New(t) + + packet := radius.New(radius.CodeAccessAccept, []byte("secret")) + + attr := radius.Attribute([]byte("asdf")) + err := _ADSLForum_SetVendor(packet, 1, attr) + a.Nil(err) + err = _ADSLForum_SetVendor(packet, 1, attr) + a.Nil(err) + + adslAttribs := _ADSLForum_GetsVendor(packet, 1) + a.Len(adslAttribs, 1) + a.Len(packet.Attributes, 1) +} + +func TestHolger(t *testing.T) { + a := assert.New(t) + + packet := radius.New(radius.CodeAccessAccept, []byte("secret")) + + groupedVSAs := radius.Attribute([]byte{1, 3, 1, 2, 3, 'X'}) + groupedVendorVSAs, err := radius.NewVendorSpecific(_ADSLForum_VendorID, groupedVSAs) + a.Nil(err) + malformed := &radius.AVP{ + Type: rfc2865.VendorSpecific_Type, + Attribute: groupedVendorVSAs, + } + packet.Attributes = append(packet.Attributes, malformed) + + attr := radius.Attribute([]byte("asdf")) + err = _ADSLForum_SetVendor(packet, 2, attr) + a.Nil(err) + err = _ADSLForum_SetVendor(packet, 2, attr) + a.Nil(err) + + adslAttribsType2 := _ADSLForum_GetsVendor(packet, 2) + a.Len(adslAttribsType2, 1) // only 1 time "asdf" + a.Len(packet.Attributes, 2) // "asdf" is appended as a non-grouped attribute + for _,a := range packet.Attributes { + t.Logf("%+v",a) + } +} + +func TestHolger2(t *testing.T) { + a := assert.New(t) + + packet := radius.New(radius.CodeAccessAccept, []byte("secret")) + + unrelatedgroupedVSAs := radius.Attribute([]byte{99, 3, 'Z'}) + unrelatedgroupedVendorVSAs, err := radius.NewVendorSpecific(_ADSLForum_VendorID, unrelatedgroupedVSAs) + a.Nil(err) + avpUnrelated := &radius.AVP{ + Type: rfc2865.VendorSpecific_Type, + Attribute: unrelatedgroupedVendorVSAs, + } + packet.Attributes = append(packet.Attributes, avpUnrelated) + + + groupedVSAs := radius.Attribute([]byte{1, 3, 'X'}) + groupedVendorVSAs, err := radius.NewVendorSpecific(_ADSLForum_VendorID, groupedVSAs) + a.Nil(err) + malformed := &radius.AVP{ + Type: rfc2865.VendorSpecific_Type, + Attribute: groupedVendorVSAs, + } + packet.Attributes = append(packet.Attributes, malformed) + // add second time, create a duplicate VSA intentionally + packet.Attributes = append(packet.Attributes, malformed) + + attr := radius.Attribute([]byte("asdf")) + err = _ADSLForum_SetVendor(packet, 1, attr) + a.Nil(err) + + adslAttribsType1 := _ADSLForum_GetsVendor(packet, 1) + a.Len(adslAttribsType1, 1) // only 1 time "asdf" + a.Len(packet.Attributes, 2) // "asdf" is appended as a non-grouped attribute + for _,a := range packet.Attributes { + t.Logf("%+v",a) + } +} diff --git a/rfc4818/generated.go b/rfc4818/generated.go index 89941c50..4a28af65 100644 --- a/rfc4818/generated.go +++ b/rfc4818/generated.go @@ -5,7 +5,7 @@ package rfc4818 import ( "net" - "layeh.com/radius" + "github.com/holgermetschulat/radius" ) const ( diff --git a/rfc4849/generated.go b/rfc4849/generated.go index ac1c54b7..43d4872e 100644 --- a/rfc4849/generated.go +++ b/rfc4849/generated.go @@ -3,7 +3,7 @@ package rfc4849 import ( - "layeh.com/radius" + "github.com/holgermetschulat/radius" ) const ( diff --git a/rfc5090/generated.go b/rfc5090/generated.go index d7fd9c8b..acdf2f8a 100644 --- a/rfc5090/generated.go +++ b/rfc5090/generated.go @@ -3,7 +3,7 @@ package rfc5090 import ( - "layeh.com/radius" + "github.com/holgermetschulat/radius" ) const ( diff --git a/rfc5176/generate.go b/rfc5176/generate.go index 3f985f1d..5908722e 100644 --- a/rfc5176/generate.go +++ b/rfc5176/generate.go @@ -1,3 +1,3 @@ -//go:generate go run ../cmd/radius-dict-gen/main.go -package rfc5176 -output generated.go -ref Error-Cause:layeh.com/radius/rfc3576 /usr/share/freeradius/dictionary.rfc5176 +//go:generate go run ../cmd/radius-dict-gen/main.go -package rfc5176 -output generated.go -ref Error-Cause:github.com/holgermetschulat/radius/rfc3576 /usr/share/freeradius/dictionary.rfc5176 package rfc5176 diff --git a/rfc5176/generated.go b/rfc5176/generated.go index 9d15aa71..4768c682 100644 --- a/rfc5176/generated.go +++ b/rfc5176/generated.go @@ -3,7 +3,7 @@ package rfc5176 import ( - . "layeh.com/radius/rfc3576" + . "github.com/holgermetschulat/radius/rfc3576" ) func init() { diff --git a/rfc5447/generated.go b/rfc5447/generated.go index 30ac5f36..c077d558 100644 --- a/rfc5447/generated.go +++ b/rfc5447/generated.go @@ -3,9 +3,9 @@ package rfc5447 import ( - "strconv" + "net" - "layeh.com/radius" + "github.com/holgermetschulat/radius" ) const ( @@ -13,123 +13,135 @@ const ( MIP6HomeLinkPrefix_Type radius.Type = 125 ) -type MIP6FeatureVector uint64 - -var MIP6FeatureVector_Strings = map[MIP6FeatureVector]string{} - -func (a MIP6FeatureVector) String() string { - if str, ok := MIP6FeatureVector_Strings[a]; ok { - return str +func MIP6FeatureVector_Add(p *radius.Packet, value []byte) (err error) { + var a radius.Attribute + a, err = radius.NewBytes(value) + if err != nil { + return } - return "MIP6FeatureVector(" + strconv.FormatUint(uint64(a), 10) + ")" + p.Add(MIP6FeatureVector_Type, a) + return } -func MIP6FeatureVector_Add(p *radius.Packet, value MIP6FeatureVector) (err error) { - a := radius.NewInteger64(uint64(value)) +func MIP6FeatureVector_AddString(p *radius.Packet, value string) (err error) { + var a radius.Attribute + a, err = radius.NewString(value) + if err != nil { + return + } p.Add(MIP6FeatureVector_Type, a) return } -func MIP6FeatureVector_Get(p *radius.Packet) (value MIP6FeatureVector) { +func MIP6FeatureVector_Get(p *radius.Packet) (value []byte) { value, _ = MIP6FeatureVector_Lookup(p) return } -func MIP6FeatureVector_Gets(p *radius.Packet) (values []MIP6FeatureVector, err error) { - var i uint64 +func MIP6FeatureVector_GetString(p *radius.Packet) (value string) { + value, _ = MIP6FeatureVector_LookupString(p) + return +} + +func MIP6FeatureVector_Gets(p *radius.Packet) (values [][]byte, err error) { + var i []byte for _, avp := range p.Attributes { if avp.Type != MIP6FeatureVector_Type { continue } attr := avp.Attribute - i, err = radius.Integer64(attr) + i = radius.Bytes(attr) if err != nil { return } - values = append(values, MIP6FeatureVector(i)) + values = append(values, i) } return } -func MIP6FeatureVector_Lookup(p *radius.Packet) (value MIP6FeatureVector, err error) { +func MIP6FeatureVector_GetStrings(p *radius.Packet) (values []string, err error) { + var i string + for _, avp := range p.Attributes { + if avp.Type != MIP6FeatureVector_Type { + continue + } + attr := avp.Attribute + i = radius.String(attr) + if err != nil { + return + } + values = append(values, i) + } + return +} + +func MIP6FeatureVector_Lookup(p *radius.Packet) (value []byte, err error) { a, ok := p.Lookup(MIP6FeatureVector_Type) if !ok { err = radius.ErrNoAttribute return } - var i uint64 - i, err = radius.Integer64(a) - if err != nil { - return - } - value = MIP6FeatureVector(i) + value = radius.Bytes(a) return } -func MIP6FeatureVector_Set(p *radius.Packet, value MIP6FeatureVector) (err error) { - a := radius.NewInteger64(uint64(value)) - p.Set(MIP6FeatureVector_Type, a) +func MIP6FeatureVector_LookupString(p *radius.Packet) (value string, err error) { + a, ok := p.Lookup(MIP6FeatureVector_Type) + if !ok { + err = radius.ErrNoAttribute + return + } + value = radius.String(a) return } -func MIP6FeatureVector_Del(p *radius.Packet) { - p.Attributes.Del(MIP6FeatureVector_Type) -} - -func MIP6HomeLinkPrefix_Add(p *radius.Packet, value []byte) (err error) { +func MIP6FeatureVector_Set(p *radius.Packet, value []byte) (err error) { var a radius.Attribute a, err = radius.NewBytes(value) if err != nil { return } - p.Add(MIP6HomeLinkPrefix_Type, a) + p.Set(MIP6FeatureVector_Type, a) return } -func MIP6HomeLinkPrefix_AddString(p *radius.Packet, value string) (err error) { +func MIP6FeatureVector_SetString(p *radius.Packet, value string) (err error) { var a radius.Attribute a, err = radius.NewString(value) if err != nil { return } - p.Add(MIP6HomeLinkPrefix_Type, a) + p.Set(MIP6FeatureVector_Type, a) return } -func MIP6HomeLinkPrefix_Get(p *radius.Packet) (value []byte) { - value, _ = MIP6HomeLinkPrefix_Lookup(p) - return +func MIP6FeatureVector_Del(p *radius.Packet) { + p.Attributes.Del(MIP6FeatureVector_Type) } -func MIP6HomeLinkPrefix_GetString(p *radius.Packet) (value string) { - value, _ = MIP6HomeLinkPrefix_LookupString(p) +func MIP6HomeLinkPrefix_Add(p *radius.Packet, value *net.IPNet) (err error) { + var a radius.Attribute + a, err = radius.NewIPv6Prefix(value) + if err != nil { + return + } + p.Add(MIP6HomeLinkPrefix_Type, a) return } -func MIP6HomeLinkPrefix_Gets(p *radius.Packet) (values [][]byte, err error) { - var i []byte - for _, avp := range p.Attributes { - if avp.Type != MIP6HomeLinkPrefix_Type { - continue - } - attr := avp.Attribute - i = radius.Bytes(attr) - if err != nil { - return - } - values = append(values, i) - } +func MIP6HomeLinkPrefix_Get(p *radius.Packet) (value *net.IPNet) { + value, _ = MIP6HomeLinkPrefix_Lookup(p) return } -func MIP6HomeLinkPrefix_GetStrings(p *radius.Packet) (values []string, err error) { - var i string +func MIP6HomeLinkPrefix_Gets(p *radius.Packet) (values []*net.IPNet, err error) { + var i *net.IPNet for _, avp := range p.Attributes { if avp.Type != MIP6HomeLinkPrefix_Type { continue } attr := avp.Attribute - i = radius.String(attr) + i, err = radius.IPv6Prefix(attr) if err != nil { return } @@ -138,39 +150,19 @@ func MIP6HomeLinkPrefix_GetStrings(p *radius.Packet) (values []string, err error return } -func MIP6HomeLinkPrefix_Lookup(p *radius.Packet) (value []byte, err error) { - a, ok := p.Lookup(MIP6HomeLinkPrefix_Type) - if !ok { - err = radius.ErrNoAttribute - return - } - value = radius.Bytes(a) - return -} - -func MIP6HomeLinkPrefix_LookupString(p *radius.Packet) (value string, err error) { +func MIP6HomeLinkPrefix_Lookup(p *radius.Packet) (value *net.IPNet, err error) { a, ok := p.Lookup(MIP6HomeLinkPrefix_Type) if !ok { err = radius.ErrNoAttribute return } - value = radius.String(a) - return -} - -func MIP6HomeLinkPrefix_Set(p *radius.Packet, value []byte) (err error) { - var a radius.Attribute - a, err = radius.NewBytes(value) - if err != nil { - return - } - p.Set(MIP6HomeLinkPrefix_Type, a) + value, err = radius.IPv6Prefix(a) return } -func MIP6HomeLinkPrefix_SetString(p *radius.Packet, value string) (err error) { +func MIP6HomeLinkPrefix_Set(p *radius.Packet, value *net.IPNet) (err error) { var a radius.Attribute - a, err = radius.NewString(value) + a, err = radius.NewIPv6Prefix(value) if err != nil { return } diff --git a/rfc5580/generated.go b/rfc5580/generated.go index d11a5ffd..0d1d5314 100644 --- a/rfc5580/generated.go +++ b/rfc5580/generated.go @@ -5,7 +5,7 @@ package rfc5580 import ( "strconv" - "layeh.com/radius" + "github.com/holgermetschulat/radius" ) const ( diff --git a/rfc5607/generate.go b/rfc5607/generate.go index aa138d24..71f6ab4d 100644 --- a/rfc5607/generate.go +++ b/rfc5607/generate.go @@ -1,3 +1,3 @@ -//go:generate go run ../cmd/radius-dict-gen/main.go -package rfc5607 -output generated.go -ref Service-Type:layeh.com/radius/rfc2865 /usr/share/freeradius/dictionary.rfc5607 +//go:generate go run ../cmd/radius-dict-gen/main.go -package rfc5607 -output generated.go -ref Service-Type:github.com/holgermetschulat/radius/rfc2865 /usr/share/freeradius/dictionary.rfc5607 package rfc5607 diff --git a/rfc5607/generated.go b/rfc5607/generated.go index 28474dba..9133fa2f 100644 --- a/rfc5607/generated.go +++ b/rfc5607/generated.go @@ -5,9 +5,9 @@ package rfc5607 import ( "strconv" - "layeh.com/radius" + "github.com/holgermetschulat/radius" - . "layeh.com/radius/rfc2865" + . "github.com/holgermetschulat/radius/rfc2865" ) const ( diff --git a/rfc5904/generated.go b/rfc5904/generated.go index 1adbcc96..2511528c 100644 --- a/rfc5904/generated.go +++ b/rfc5904/generated.go @@ -5,7 +5,7 @@ package rfc5904 import ( "strconv" - "layeh.com/radius" + "github.com/holgermetschulat/radius" ) const ( diff --git a/rfc6519/generated.go b/rfc6519/generated.go index 7a85278c..9d1b8200 100644 --- a/rfc6519/generated.go +++ b/rfc6519/generated.go @@ -3,7 +3,7 @@ package rfc6519 import ( - "layeh.com/radius" + "github.com/holgermetschulat/radius" ) const ( diff --git a/rfc6572/generated.go b/rfc6572/generated.go index 308cb404..0cb98ae3 100644 --- a/rfc6572/generated.go +++ b/rfc6572/generated.go @@ -5,7 +5,7 @@ package rfc6572 import ( "net" - "layeh.com/radius" + "github.com/holgermetschulat/radius" ) const ( diff --git a/rfc6677/generated.go b/rfc6677/generated.go index 65be05cd..4934b1e0 100644 --- a/rfc6677/generated.go +++ b/rfc6677/generated.go @@ -5,7 +5,7 @@ package rfc6677 import ( "strconv" - "layeh.com/radius" + "github.com/holgermetschulat/radius" ) const ( diff --git a/rfc6911/generated.go b/rfc6911/generated.go index a4133fa2..fce16331 100644 --- a/rfc6911/generated.go +++ b/rfc6911/generated.go @@ -5,7 +5,7 @@ package rfc6911 import ( "net" - "layeh.com/radius" + "github.com/holgermetschulat/radius" ) const ( diff --git a/rfc7055/generated.go b/rfc7055/generated.go index f4c5e529..612a836e 100644 --- a/rfc7055/generated.go +++ b/rfc7055/generated.go @@ -3,7 +3,7 @@ package rfc7055 import ( - "layeh.com/radius" + "github.com/holgermetschulat/radius" ) const ( diff --git a/rfc7268/generated.go b/rfc7268/generated.go index 775bd57e..e8871979 100644 --- a/rfc7268/generated.go +++ b/rfc7268/generated.go @@ -6,7 +6,7 @@ import ( "errors" "strconv" - "layeh.com/radius" + "github.com/holgermetschulat/radius" ) const ( diff --git a/server-example_test.go b/server-example_test.go index 3324ab99..c634b9bf 100644 --- a/server-example_test.go +++ b/server-example_test.go @@ -3,8 +3,8 @@ package radius_test import ( "log" - "layeh.com/radius" - "layeh.com/radius/rfc2865" + "github.com/holgermetschulat/radius" + "github.com/holgermetschulat/radius/rfc2865" ) var ( diff --git a/server-packet.go b/server-packet.go index 1347d43f..997fd285 100644 --- a/server-packet.go +++ b/server-packet.go @@ -161,7 +161,7 @@ func (s *PacketServer) Serve(conn net.PacketConn) error { return } - packet, err := Parse(buff, secret) + packet, err := Parse(buff, nil, secret) if err != nil { s.logf("radius: unable to parse packet: %v", err) return @@ -196,6 +196,7 @@ func (s *PacketServer) Serve(conn net.PacketConn) error { RemoteAddr: remoteAddr, Packet: packet, ctx: s.ctx, + Conn: conn, } s.Handler.ServeRADIUS(&response, &request) @@ -203,6 +204,32 @@ func (s *PacketServer) Serve(conn net.PacketConn) error { } } +// Listen listens on the address given in s. +func (s *PacketServer) Listen() (net.PacketConn, error) { + if s.Handler == nil { + return nil, errors.New("radius: nil Handler") + } + if s.SecretSource == nil { + return nil, errors.New("radius: nil SecretSource") + } + + addrStr := ":1812" + if s.Addr != "" { + addrStr = s.Addr + } + + network := "udp" + if s.Network != "" { + network = s.Network + } + + pc, err := net.ListenPacket(network, addrStr) + if err != nil { + return nil, err + } + return pc, nil +} + // ListenAndServe starts a RADIUS server on the address given in s. func (s *PacketServer) ListenAndServe() error { if s.Handler == nil { diff --git a/server.go b/server.go index 8a93abb3..ce94c02d 100644 --- a/server.go +++ b/server.go @@ -37,6 +37,8 @@ type Request struct { *Packet ctx context.Context + + Conn net.PacketConn } // Context returns the context of the request. If a context has not been set diff --git a/vendors/aruba/generate.go b/vendors/aruba/generate.go index f8f975d5..63c3e25b 100644 --- a/vendors/aruba/generate.go +++ b/vendors/aruba/generate.go @@ -1,3 +1,3 @@ -//go:generate go run generate_main.go +// deactivated because aruba network requires sign in: go:generate go run generate_main.go package aruba diff --git a/vendors/aruba/generate_main.go b/vendors/aruba/generate_main.go index bae59a60..227dc137 100644 --- a/vendors/aruba/generate_main.go +++ b/vendors/aruba/generate_main.go @@ -11,8 +11,8 @@ import ( "net/http" "os" - "layeh.com/radius/dictionary" - "layeh.com/radius/dictionarygen" + "github.com/holgermetschulat/radius/dictionary" + "github.com/holgermetschulat/radius/dictionarygen" ) func main() { diff --git a/vendors/aruba/generated.go b/vendors/aruba/generated.go index d92a96c9..7d1fe2c5 100644 --- a/vendors/aruba/generated.go +++ b/vendors/aruba/generated.go @@ -6,8 +6,8 @@ import ( "net" "strconv" - "layeh.com/radius" - "layeh.com/radius/rfc2865" + "github.com/holgermetschulat/radius" + "github.com/holgermetschulat/radius/rfc2865" ) const ( diff --git a/vendors/aruba/generated_test.go b/vendors/aruba/generated_test.go index ce05fc3c..51f38834 100644 --- a/vendors/aruba/generated_test.go +++ b/vendors/aruba/generated_test.go @@ -3,8 +3,8 @@ package aruba_test import ( "testing" - "layeh.com/radius" - . "layeh.com/radius/vendors/aruba" + "github.com/holgermetschulat/radius" + . "github.com/holgermetschulat/radius/vendors/aruba" ) func TestLookup(t *testing.T) { diff --git a/vendors/microsoft/generated.go b/vendors/microsoft/generated.go index 8fa65dc3..c6d14fa3 100644 --- a/vendors/microsoft/generated.go +++ b/vendors/microsoft/generated.go @@ -8,8 +8,8 @@ import ( "net" "strconv" - "layeh.com/radius" - "layeh.com/radius/rfc2865" + "github.com/holgermetschulat/radius" + "github.com/holgermetschulat/radius/rfc2865" ) const ( @@ -79,35 +79,7 @@ func _Microsoft_LookupVendor(p *radius.Packet, typ byte) (attr radius.Attribute, } func _Microsoft_SetVendor(p *radius.Packet, typ byte, attr radius.Attribute) (err error) { - for i := 0; i < len(p.Attributes); { - avp := p.Attributes[i] - if avp.Type != rfc2865.VendorSpecific_Type { - i++ - continue - } - vendorID, vsa, err := radius.VendorSpecific(avp.Attribute) - if err != nil || vendorID != _Microsoft_VendorID { - i++ - continue - } - for j := 0; len(vsa[j:]) >= 3; { - vsaTyp, vsaLen := vsa[0], vsa[1] - if int(vsaLen) > len(vsa[j:]) || vsaLen < 3 { - i++ - break - } - if vsaTyp == typ { - vsa = append(vsa[:j], vsa[j+int(vsaLen):]...) - } - j += int(vsaLen) - } - if len(vsa) > 0 { - copy(avp.Attribute[4:], vsa) - i++ - } else { - p.Attributes = append(p.Attributes[:i], p.Attributes[i+i:]...) - } - } + _Microsoft_DelVendor(p, typ) return _Microsoft_AddVendor(p, typ, attr) } @@ -1547,7 +1519,7 @@ func MSMPPESendKey_Add(p *radius.Packet, value []byte) (err error) { return } salt[0] |= 1 << 7 - a, err = radius.NewTunnelPassword(value, salt[:], p.Secret, p.Authenticator[:]) + a, err = radius.NewTunnelPassword(value, salt[:], p.Secret, p.CryptoAuthenticator[:]) if err != nil { return } @@ -1562,7 +1534,7 @@ func MSMPPESendKey_AddString(p *radius.Packet, value string) (err error) { return } salt[0] |= 1 << 7 - a, err = radius.NewTunnelPassword([]byte(value), salt[:], p.Secret, p.Authenticator[:]) + a, err = radius.NewTunnelPassword([]byte(value), salt[:], p.Secret, p.CryptoAuthenticator[:]) if err != nil { return } @@ -1582,7 +1554,7 @@ func MSMPPESendKey_GetString(p *radius.Packet) (value string) { func MSMPPESendKey_Gets(p *radius.Packet) (values [][]byte, err error) { var i []byte for _, attr := range _Microsoft_GetsVendor(p, 16) { - i, _, err = radius.TunnelPassword(attr, p.Secret, p.Authenticator[:]) + i, _, err = radius.TunnelPassword(attr, p.Secret, p.CryptoAuthenticator[:]) if err != nil { return } @@ -1595,7 +1567,7 @@ func MSMPPESendKey_GetStrings(p *radius.Packet) (values []string, err error) { var i string for _, attr := range _Microsoft_GetsVendor(p, 16) { var up []byte - up, _, err = radius.TunnelPassword(attr, p.Secret, p.Authenticator[:]) + up, _, err = radius.TunnelPassword(attr, p.Secret, p.CryptoAuthenticator[:]) if err == nil { i = string(up) } @@ -1613,7 +1585,7 @@ func MSMPPESendKey_Lookup(p *radius.Packet) (value []byte, err error) { err = radius.ErrNoAttribute return } - value, _, err = radius.TunnelPassword(a, p.Secret, p.Authenticator[:]) + value, _, err = radius.TunnelPassword(a, p.Secret, p.CryptoAuthenticator[:]) return } @@ -1624,7 +1596,7 @@ func MSMPPESendKey_LookupString(p *radius.Packet) (value string, err error) { return } var b []byte - b, _, err = radius.TunnelPassword(a, p.Secret, p.Authenticator[:]) + b, _, err = radius.TunnelPassword(a, p.Secret, p.CryptoAuthenticator[:]) if err == nil { value = string(b) } @@ -1639,7 +1611,7 @@ func MSMPPESendKey_Set(p *radius.Packet, value []byte) (err error) { return } salt[0] |= 1 << 7 - a, err = radius.NewTunnelPassword(value, salt[:], p.Secret, p.Authenticator[:]) + a, err = radius.NewTunnelPassword(value, salt[:], p.Secret, p.CryptoAuthenticator[:]) if err != nil { return } @@ -1654,7 +1626,7 @@ func MSMPPESendKey_SetString(p *radius.Packet, value string) (err error) { return } salt[0] |= 1 << 7 - a, err = radius.NewTunnelPassword([]byte(value), salt[:], p.Secret, p.Authenticator[:]) + a, err = radius.NewTunnelPassword([]byte(value), salt[:], p.Secret, p.CryptoAuthenticator[:]) if err != nil { return } @@ -1673,7 +1645,7 @@ func MSMPPERecvKey_Add(p *radius.Packet, value []byte) (err error) { return } salt[0] |= 1 << 7 - a, err = radius.NewTunnelPassword(value, salt[:], p.Secret, p.Authenticator[:]) + a, err = radius.NewTunnelPassword(value, salt[:], p.Secret, p.CryptoAuthenticator[:]) if err != nil { return } @@ -1688,7 +1660,7 @@ func MSMPPERecvKey_AddString(p *radius.Packet, value string) (err error) { return } salt[0] |= 1 << 7 - a, err = radius.NewTunnelPassword([]byte(value), salt[:], p.Secret, p.Authenticator[:]) + a, err = radius.NewTunnelPassword([]byte(value), salt[:], p.Secret, p.CryptoAuthenticator[:]) if err != nil { return } @@ -1708,7 +1680,7 @@ func MSMPPERecvKey_GetString(p *radius.Packet) (value string) { func MSMPPERecvKey_Gets(p *radius.Packet) (values [][]byte, err error) { var i []byte for _, attr := range _Microsoft_GetsVendor(p, 17) { - i, _, err = radius.TunnelPassword(attr, p.Secret, p.Authenticator[:]) + i, _, err = radius.TunnelPassword(attr, p.Secret, p.CryptoAuthenticator[:]) if err != nil { return } @@ -1721,7 +1693,7 @@ func MSMPPERecvKey_GetStrings(p *radius.Packet) (values []string, err error) { var i string for _, attr := range _Microsoft_GetsVendor(p, 17) { var up []byte - up, _, err = radius.TunnelPassword(attr, p.Secret, p.Authenticator[:]) + up, _, err = radius.TunnelPassword(attr, p.Secret, p.CryptoAuthenticator[:]) if err == nil { i = string(up) } @@ -1739,7 +1711,7 @@ func MSMPPERecvKey_Lookup(p *radius.Packet) (value []byte, err error) { err = radius.ErrNoAttribute return } - value, _, err = radius.TunnelPassword(a, p.Secret, p.Authenticator[:]) + value, _, err = radius.TunnelPassword(a, p.Secret, p.CryptoAuthenticator[:]) return } @@ -1750,7 +1722,7 @@ func MSMPPERecvKey_LookupString(p *radius.Packet) (value string, err error) { return } var b []byte - b, _, err = radius.TunnelPassword(a, p.Secret, p.Authenticator[:]) + b, _, err = radius.TunnelPassword(a, p.Secret, p.CryptoAuthenticator[:]) if err == nil { value = string(b) } @@ -1765,7 +1737,7 @@ func MSMPPERecvKey_Set(p *radius.Packet, value []byte) (err error) { return } salt[0] |= 1 << 7 - a, err = radius.NewTunnelPassword(value, salt[:], p.Secret, p.Authenticator[:]) + a, err = radius.NewTunnelPassword(value, salt[:], p.Secret, p.CryptoAuthenticator[:]) if err != nil { return } @@ -1780,7 +1752,7 @@ func MSMPPERecvKey_SetString(p *radius.Packet, value string) (err error) { return } salt[0] |= 1 << 7 - a, err = radius.NewTunnelPassword([]byte(value), salt[:], p.Secret, p.Authenticator[:]) + a, err = radius.NewTunnelPassword([]byte(value), salt[:], p.Secret, p.CryptoAuthenticator[:]) if err != nil { return } diff --git a/vendors/microsoft/mschapv2-server-example.go b/vendors/microsoft/mschapv2-server-example.go index 0bb67935..6f177e39 100644 --- a/vendors/microsoft/mschapv2-server-example.go +++ b/vendors/microsoft/mschapv2-server-example.go @@ -6,13 +6,13 @@ import ( "bytes" "log" - "layeh.com/radius" - "layeh.com/radius/rfc2759" - "layeh.com/radius/rfc2865" - "layeh.com/radius/rfc2868" - "layeh.com/radius/rfc2869" - "layeh.com/radius/rfc3079" - "layeh.com/radius/vendors/microsoft" + "github.com/holgermetschulat/radius" + "github.com/holgermetschulat/radius/rfc2759" + "github.com/holgermetschulat/radius/rfc2865" + "github.com/holgermetschulat/radius/rfc2868" + "github.com/holgermetschulat/radius/rfc2869" + "github.com/holgermetschulat/radius/rfc3079" + "github.com/holgermetschulat/radius/vendors/microsoft" ) const ( diff --git a/vendors/mikrotik/generate_main.go b/vendors/mikrotik/generate_main.go index aff7643b..3b62d122 100644 --- a/vendors/mikrotik/generate_main.go +++ b/vendors/mikrotik/generate_main.go @@ -12,8 +12,8 @@ import ( "net/http" "regexp" - "layeh.com/radius/dictionary" - "layeh.com/radius/dictionarygen" + "github.com/holgermetschulat/radius/dictionary" + "github.com/holgermetschulat/radius/dictionarygen" ) type ParseResponse struct { diff --git a/vendors/mikrotik/generated.go b/vendors/mikrotik/generated.go index 334ebd91..0d1dfce6 100644 --- a/vendors/mikrotik/generated.go +++ b/vendors/mikrotik/generated.go @@ -6,8 +6,8 @@ import ( "net" "strconv" - "layeh.com/radius" - "layeh.com/radius/rfc2865" + "github.com/holgermetschulat/radius" + "github.com/holgermetschulat/radius/rfc2865" ) const ( @@ -77,35 +77,7 @@ func _Mikrotik_LookupVendor(p *radius.Packet, typ byte) (attr radius.Attribute, } func _Mikrotik_SetVendor(p *radius.Packet, typ byte, attr radius.Attribute) (err error) { - for i := 0; i < len(p.Attributes); { - avp := p.Attributes[i] - if avp.Type != rfc2865.VendorSpecific_Type { - i++ - continue - } - vendorID, vsa, err := radius.VendorSpecific(avp.Attribute) - if err != nil || vendorID != _Mikrotik_VendorID { - i++ - continue - } - for j := 0; len(vsa[j:]) >= 3; { - vsaTyp, vsaLen := vsa[0], vsa[1] - if int(vsaLen) > len(vsa[j:]) || vsaLen < 3 { - i++ - break - } - if vsaTyp == typ { - vsa = append(vsa[:j], vsa[j+int(vsaLen):]...) - } - j += int(vsaLen) - } - if len(vsa) > 0 { - copy(avp.Attribute[4:], vsa) - i++ - } else { - p.Attributes = append(p.Attributes[:i], p.Attributes[i+i:]...) - } - } + _Mikrotik_DelVendor(p, typ) return _Mikrotik_AddVendor(p, typ, attr) } @@ -1999,7 +1971,7 @@ func MikrotikDHCPOptionParamSTR1_Del(p *radius.Packet) { _Mikrotik_DelVendor(p, 24) } -func MikortikDHCPOptionParamSTR2_Add(p *radius.Packet, value []byte) (err error) { +func MikrotikDHCPOptionParamSTR2_Add(p *radius.Packet, value []byte) (err error) { var a radius.Attribute a, err = radius.NewBytes(value) if err != nil { @@ -2008,7 +1980,7 @@ func MikortikDHCPOptionParamSTR2_Add(p *radius.Packet, value []byte) (err error) return _Mikrotik_AddVendor(p, 25, a) } -func MikortikDHCPOptionParamSTR2_AddString(p *radius.Packet, value string) (err error) { +func MikrotikDHCPOptionParamSTR2_AddString(p *radius.Packet, value string) (err error) { var a radius.Attribute a, err = radius.NewString(value) if err != nil { @@ -2017,17 +1989,17 @@ func MikortikDHCPOptionParamSTR2_AddString(p *radius.Packet, value string) (err return _Mikrotik_AddVendor(p, 25, a) } -func MikortikDHCPOptionParamSTR2_Get(p *radius.Packet) (value []byte) { - value, _ = MikortikDHCPOptionParamSTR2_Lookup(p) +func MikrotikDHCPOptionParamSTR2_Get(p *radius.Packet) (value []byte) { + value, _ = MikrotikDHCPOptionParamSTR2_Lookup(p) return } -func MikortikDHCPOptionParamSTR2_GetString(p *radius.Packet) (value string) { - value, _ = MikortikDHCPOptionParamSTR2_LookupString(p) +func MikrotikDHCPOptionParamSTR2_GetString(p *radius.Packet) (value string) { + value, _ = MikrotikDHCPOptionParamSTR2_LookupString(p) return } -func MikortikDHCPOptionParamSTR2_Gets(p *radius.Packet) (values [][]byte, err error) { +func MikrotikDHCPOptionParamSTR2_Gets(p *radius.Packet) (values [][]byte, err error) { var i []byte for _, attr := range _Mikrotik_GetsVendor(p, 25) { i = radius.Bytes(attr) @@ -2039,7 +2011,7 @@ func MikortikDHCPOptionParamSTR2_Gets(p *radius.Packet) (values [][]byte, err er return } -func MikortikDHCPOptionParamSTR2_GetStrings(p *radius.Packet) (values []string, err error) { +func MikrotikDHCPOptionParamSTR2_GetStrings(p *radius.Packet) (values []string, err error) { var i string for _, attr := range _Mikrotik_GetsVendor(p, 25) { i = radius.String(attr) @@ -2051,7 +2023,7 @@ func MikortikDHCPOptionParamSTR2_GetStrings(p *radius.Packet) (values []string, return } -func MikortikDHCPOptionParamSTR2_Lookup(p *radius.Packet) (value []byte, err error) { +func MikrotikDHCPOptionParamSTR2_Lookup(p *radius.Packet) (value []byte, err error) { a, ok := _Mikrotik_LookupVendor(p, 25) if !ok { err = radius.ErrNoAttribute @@ -2061,7 +2033,7 @@ func MikortikDHCPOptionParamSTR2_Lookup(p *radius.Packet) (value []byte, err err return } -func MikortikDHCPOptionParamSTR2_LookupString(p *radius.Packet) (value string, err error) { +func MikrotikDHCPOptionParamSTR2_LookupString(p *radius.Packet) (value string, err error) { a, ok := _Mikrotik_LookupVendor(p, 25) if !ok { err = radius.ErrNoAttribute @@ -2071,7 +2043,7 @@ func MikortikDHCPOptionParamSTR2_LookupString(p *radius.Packet) (value string, e return } -func MikortikDHCPOptionParamSTR2_Set(p *radius.Packet, value []byte) (err error) { +func MikrotikDHCPOptionParamSTR2_Set(p *radius.Packet, value []byte) (err error) { var a radius.Attribute a, err = radius.NewBytes(value) if err != nil { @@ -2080,7 +2052,7 @@ func MikortikDHCPOptionParamSTR2_Set(p *radius.Packet, value []byte) (err error) return _Mikrotik_SetVendor(p, 25, a) } -func MikortikDHCPOptionParamSTR2_SetString(p *radius.Packet, value string) (err error) { +func MikrotikDHCPOptionParamSTR2_SetString(p *radius.Packet, value string) (err error) { var a radius.Attribute a, err = radius.NewString(value) if err != nil { @@ -2089,7 +2061,7 @@ func MikortikDHCPOptionParamSTR2_SetString(p *radius.Packet, value string) (err return _Mikrotik_SetVendor(p, 25, a) } -func MikortikDHCPOptionParamSTR2_Del(p *radius.Packet) { +func MikrotikDHCPOptionParamSTR2_Del(p *radius.Packet) { _Mikrotik_DelVendor(p, 25) } diff --git a/vendors/mikrotik/generated_test.go b/vendors/mikrotik/generated_test.go index 7aae84a2..6a78351e 100644 --- a/vendors/mikrotik/generated_test.go +++ b/vendors/mikrotik/generated_test.go @@ -3,8 +3,8 @@ package mikrotik import ( "testing" - "layeh.com/radius" - "layeh.com/radius/rfc2865" + "github.com/holgermetschulat/radius" + "github.com/holgermetschulat/radius/rfc2865" ) func TestVendorGenerated(t *testing.T) { diff --git a/vendors/wispr/generated.go b/vendors/wispr/generated.go index d00f8dbe..c69d9be9 100644 --- a/vendors/wispr/generated.go +++ b/vendors/wispr/generated.go @@ -5,8 +5,8 @@ package wispr import ( "strconv" - "layeh.com/radius" - "layeh.com/radius/rfc2865" + "github.com/holgermetschulat/radius" + "github.com/holgermetschulat/radius/rfc2865" ) const ( @@ -76,35 +76,7 @@ func _WISPr_LookupVendor(p *radius.Packet, typ byte) (attr radius.Attribute, ok } func _WISPr_SetVendor(p *radius.Packet, typ byte, attr radius.Attribute) (err error) { - for i := 0; i < len(p.Attributes); { - avp := p.Attributes[i] - if avp.Type != rfc2865.VendorSpecific_Type { - i++ - continue - } - vendorID, vsa, err := radius.VendorSpecific(avp.Attribute) - if err != nil || vendorID != _WISPr_VendorID { - i++ - continue - } - for j := 0; len(vsa[j:]) >= 3; { - vsaTyp, vsaLen := vsa[0], vsa[1] - if int(vsaLen) > len(vsa[j:]) || vsaLen < 3 { - i++ - break - } - if vsaTyp == typ { - vsa = append(vsa[:j], vsa[j+int(vsaLen):]...) - } - j += int(vsaLen) - } - if len(vsa) > 0 { - copy(avp.Attribute[4:], vsa) - i++ - } else { - p.Attributes = append(p.Attributes[:i], p.Attributes[i+i:]...) - } - } + _WISPr_DelVendor(p, typ) return _WISPr_AddVendor(p, typ, attr) }