-
Notifications
You must be signed in to change notification settings - Fork 11
/
Copy pathattributes_builtin.go
136 lines (118 loc) · 3.3 KB
/
attributes_builtin.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
package radius
import (
"encoding/binary"
"errors"
"net"
"time"
"unicode/utf8"
)
// The base attribute value formats that are defined in RFC 2865.
var (
// string
AttributeText AttributeCodec
// []byte
AttributeString AttributeCodec
// net.IP
AttributeAddress AttributeCodec
// uint32
AttributeInteger AttributeCodec
// time.Time
AttributeTime AttributeCodec
// []byte
AttributeUnknown AttributeCodec
)
func init() {
AttributeText = attributeText{}
AttributeString = attributeString{}
AttributeAddress = attributeAddress{}
AttributeInteger = attributeInteger{}
AttributeTime = attributeTime{}
AttributeUnknown = attributeString{}
}
type attributeText struct{}
func (attributeText) Decode(packet *Packet, value []byte) (interface{}, error) {
if !utf8.Valid(value) {
return nil, errors.New("radius: text attribute is not valid UTF-8")
}
return string(value), nil
}
func (attributeText) Encode(packet *Packet, value interface{}) ([]byte, error) {
str, ok := value.(string)
if ok {
return []byte(str), nil
}
raw, ok := value.([]byte)
if ok {
return raw, nil
}
return nil, errors.New("radius: text attribute must be string or []byte")
}
type attributeString struct{}
func (attributeString) Decode(packet *Packet, value []byte) (interface{}, error) {
v := make([]byte, len(value))
copy(v, value)
return v, nil
}
func (attributeString) Encode(packet *Packet, value interface{}) ([]byte, error) {
raw, ok := value.([]byte)
if ok {
return raw, nil
}
str, ok := value.(string)
if ok {
return []byte(str), nil
}
return nil, errors.New("radius: string attribute must be []byte or string")
}
type attributeAddress struct{}
func (attributeAddress) Decode(packet *Packet, value []byte) (interface{}, error) {
if len(value) != net.IPv4len {
return nil, errors.New("radius: address attribute has invalid size")
}
v := make([]byte, len(value))
copy(v, value)
return net.IP(v), nil
}
func (attributeAddress) Encode(packet *Packet, value interface{}) ([]byte, error) {
ip, ok := value.(net.IP)
if !ok {
return nil, errors.New("radius: address attribute must be net.IP")
}
ip = ip.To4()
if ip == nil {
return nil, errors.New("radius: address attribute must be an IPv4 net.IP")
}
return []byte(ip), nil
}
type attributeInteger struct{}
func (attributeInteger) Decode(packet *Packet, value []byte) (interface{}, error) {
if len(value) != 4 {
return nil, errors.New("radius: integer attribute has invalid size")
}
return binary.BigEndian.Uint32(value), nil
}
func (attributeInteger) Encode(packet *Packet, value interface{}) ([]byte, error) {
integer, ok := value.(uint32)
if !ok {
return nil, errors.New("radius: integer attribute must be uint32")
}
raw := make([]byte, 4)
binary.BigEndian.PutUint32(raw, integer)
return raw, nil
}
type attributeTime struct{}
func (attributeTime) Decode(packet *Packet, value []byte) (interface{}, error) {
if len(value) != 4 {
return nil, errors.New("radius: time attribute has invalid size")
}
return time.Unix(int64(binary.BigEndian.Uint32(value)), 0), nil
}
func (attributeTime) Encode(packet *Packet, value interface{}) ([]byte, error) {
timestamp, ok := value.(time.Time)
if !ok {
return nil, errors.New("radius: time attribute must be time.Time")
}
raw := make([]byte, 4)
binary.BigEndian.PutUint32(raw, uint32(timestamp.Unix()))
return raw, nil
}