This repository has been archived by the owner on Jun 28, 2022. It is now read-only.
forked from bronze1man/radius
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy patheap.go
159 lines (141 loc) · 3.5 KB
/
eap.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
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
package radius
import (
"encoding/binary"
"fmt"
"strconv"
)
// ietf docs:
// Code
// 1 - Request
// 2 - Response
type EapCode uint8
const (
EapCodeRequest EapCode = 1
EapCodeResponse EapCode = 2
)
func (c EapCode) String() string {
switch c {
case EapCodeRequest:
return "Request"
case EapCodeResponse:
return "Response"
default:
return "unknow EapCode " + strconv.Itoa(int(c))
}
}
// OpCode
// The OpCode field is one octet and identifies the type of EAP MS-CHAP-
// v2 packet. OpCodes are assigned as follows:
// 1 Challenge
// 2 Response
// 3 Success
// 4 Failure
// 7 Change-Password
type EapOpCode uint8
const (
EapOpCodeChallenge EapOpCode = 1
EapOpCodeResponse EapOpCode = 2
EapOpCodeSuccess EapOpCode = 3
EapOpCodeFailure EapOpCode = 4
EapOpCodeChangePassword EapOpCode = 7
)
func (c EapOpCode) String() string {
switch c {
case EapOpCodeChallenge:
return "Challenge"
case EapOpCodeResponse:
return "Response"
case EapOpCodeSuccess:
return "Success"
case EapOpCodeFailure:
return "Failure"
case EapOpCodeChangePassword:
return "Change-Password"
default:
return "unknow EapCode " + strconv.Itoa(int(c))
}
}
type EapType uint8
const (
EapTypeIdentity EapType = 1
EapTypeNotification EapType = 2
EapTypeNak EapType = 3 //Response only
EapTypeMd5Challenge EapType = 4
EapTypeOneTimePassword EapType = 5 //otp
EapTypeGenericTokenCard EapType = 6 //gtc
EapTypeMSCHAPV2 EapType = 26
EapTypeExpandedTypes EapType = 254
EapTypeExperimentalUse EapType = 255
)
func (c EapType) String() string {
switch c {
case EapTypeIdentity:
return "Identity"
case EapTypeNotification:
return "Notification"
case EapTypeNak:
return "Nak"
case EapTypeMd5Challenge:
return "Md5Challenge"
case EapTypeOneTimePassword:
return "OneTimePassword"
case EapTypeGenericTokenCard:
return "GenericTokenCard"
case EapTypeMSCHAPV2:
return "MSCHAPV2"
case EapTypeExpandedTypes:
return "ExpandedTypes"
case EapTypeExperimentalUse:
return "ExperimentalUse"
default:
return "unknow EapType " + strconv.Itoa(int(c))
}
}
type EapPacket struct {
Code EapCode
Identifier uint8
Type EapType
Data []byte
OpCode MsChapV2OpCode
}
func (a *EapPacket) String() string {
return fmt.Sprintf("Eap Code:%s id:%d Type:%s Data:[%s]", a.Code.String(), a.Identifier, a.Type.String(), string(a.Data))
}
func (a *EapPacket) DecodeMsChapV2() (*MsChapV2Packet, error) {
return MsChapV2PacketFromEap(a)
}
func (a *EapPacket) Copy() *EapPacket {
eap := *a
eap.Data = append([]byte(nil), a.Data...)
return &eap
}
func (a *EapPacket) Encode() (b []byte) {
b = make([]byte, len(a.Data)+5)
b[0] = byte(a.Code)
b[1] = byte(a.Identifier)
length := uint16(len(b))
binary.BigEndian.PutUint16(b[2:4], length)
b[4] = byte(a.Type)
if a.OpCode == MsChapV2OpCodeSuccess {
//The MS-Length field is two octets and MUST be set to the value of the Length field minus 5.
a.Data[3] = b[3] - 5
}
copy(b[5:], a.Data)
return b
}
func EapDecode(b []byte) (eap *EapPacket, err error) {
if len(b) < 5 {
return nil, fmt.Errorf("[EapDecode] protocol error input too small")
}
length := binary.BigEndian.Uint16(b[2:4])
if len(b) < int(length) {
return nil, fmt.Errorf("[EapDecode] protocol error input too length does not match header")
}
eap = &EapPacket{
Code: EapCode(b[0]),
Identifier: uint8(b[1]),
Type: EapType(b[4]),
Data: b[5:length],
}
return eap, nil
}