This repository has been archived by the owner on Sep 15, 2018. It is now read-only.
forked from CuberL/goDrClient
-
Notifications
You must be signed in to change notification settings - Fork 1
/
auth.go
170 lines (154 loc) · 4.54 KB
/
auth.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
160
161
162
163
164
165
166
167
168
169
170
package main
import (
"crypto/md5"
"log"
"net"
"sync"
"time"
"github.com/google/gopacket"
"github.com/google/gopacket/layers"
)
var (
challenge []byte
BoardCastAddr net.HardwareAddr = net.HardwareAddr{0xff, 0xff, 0xff, 0xff, 0xff, 0xff}
isOnline bool = false
mutex = &sync.Mutex{}
)
func setOnline(v bool) {
mutex.Lock()
isOnline = v
mutex.Unlock()
}
// sends the EAPOL message to Authenticator
func sendEAPOL(Version byte, Type layers.EAPOLType, SrcMAC net.HardwareAddr, DstMAC net.HardwareAddr) error {
buffer := gopacket.NewSerializeBuffer()
options := gopacket.SerializeOptions{}
ethernetLayer := &layers.Ethernet{
EthernetType: layers.EthernetTypeEAPOL,
SrcMAC: SrcMAC,
DstMAC: DstMAC,
}
eapolLayer := &layers.EAPOL{
Version: Version,
Type: Type,
Length: 0,
}
gopacket.SerializeLayers(buffer, options,
ethernetLayer,
eapolLayer,
)
// write packet
err := handle.WritePacketData(buffer.Bytes())
if err != nil {
return err
}
return nil
}
// sends the EAP message to Authenticator
func sendEAP(Id uint8, Type layers.EAPType, TypeData []byte, Code layers.EAPCode, SrcMAC net.HardwareAddr, DstMAC net.HardwareAddr) {
buffer := gopacket.NewSerializeBuffer()
options := gopacket.SerializeOptions{}
ethernetLayer := &layers.Ethernet{
EthernetType: layers.EthernetTypeEAPOL,
SrcMAC: SrcMAC,
DstMAC: DstMAC,
}
eapolLayer := &layers.EAPOL{
Version: 0x01,
Type: layers.EAPOLTypeEAP,
Length: uint16(len(TypeData) + 5),
}
eapLayer := &layers.EAP{
Id: Id,
Type: Type,
TypeData: TypeData,
Code: Code,
Length: uint16(len(TypeData) + 5),
}
gopacket.SerializeLayers(buffer, options,
ethernetLayer,
eapolLayer,
eapLayer,
)
// err error
err := handle.WritePacketData(buffer.Bytes())
if err != nil {
log.Println(err)
}
}
// sniff EAP packet for EAP authentication
func sniffEAP(eapLayer layers.EAP) {
switch eapLayer.Code {
case layers.EAPCodeRequest: //Request
switch eapLayer.Type { // request type
case layers.EAPTypeIdentity: //Identity
go responseIdentity(eapLayer.Id)
case layers.EAPTypeOTP: //EAP-MD5-CHALLENGE
go responseMd5Challenge(eapLayer.TypeData[1:17])
case layers.EAPTypeNotification: //Notification
log.Println("EAP packet error")
// vital errors
}
case layers.EAPCodeSuccess: //Success
log.Println("Success of EAP auth")
setOnline(true)
startUDPRequest() // start keep-alive
case layers.EAPCodeFailure: //Failure
log.Println("EAP auth Failed")
time.Sleep(time.Duration(3) * time.Second)
if !isOnline {
log.Println("Retry EAP auth...")
startRequest()
}
}
}
// start request to the Authenticator
func startRequest() bool {
log.Println("Start request to Authenticator...")
// sending the EAPOL-Start message to a multicast group
err := sendEAPOL(0x01, layers.EAPOLTypeStart, InterfaceMAC, BoardCastAddr)
if err != nil {
log.Println(err)
return false
}
return true
}
// sending logoff message
func logoff() {
//send EAPOL-Logoff message to be disconnected from the network.
sendEAPOL(0x01, layers.EAPOLTypeLogOff, InterfaceMAC, BoardCastAddr)
log.Println("Logoff...")
}
// relogin for a specify time interval
func relogin(interval int) {
logoff()
time.Sleep(time.Duration(interval) * time.Second)
startRequest()
}
// response Identity
func responseIdentity(id byte) {
dataPack := []byte{}
dataPack = append(dataPack, []byte(GConfig.Username)...) // Username
dataPack = append(dataPack, []byte{0x00, 0x44, 0x61, 0x00, 0x00}...) // Fixed Uknown bytes
dataPack = append(dataPack, []byte(GConfig.ClientIP.To4())...) // Client IP
log.Println("Response Identity...")
sendEAP(id, layers.EAPTypeIdentity, dataPack, layers.EAPCodeResponse, InterfaceMAC, BoardCastAddr)
}
// response MD5-Challenge md( EAP-MD5 Challange + Password) + Extra data
func responseMd5Challenge(m []byte) {
mPack := []byte{}
mPack = append(mPack, 0)
mPack = append(mPack, []byte(GConfig.Password)...)
mPack = append(mPack, m...)
mCal := md5.New() //new hash.Hash
mCal.Write(mPack)
challenge = mCal.Sum(nil) //用于后面心跳包
dataPack := []byte{}
dataPack = append(dataPack, 16) // EAP-MD5 Value-Size
dataPack = append(dataPack, mCal.Sum(nil)...)
dataPack = append(dataPack, []byte(GConfig.Username)...)
dataPack = append(dataPack, []byte{0x00, 0x44, 0x61, 0x26, 0x00}...)
dataPack = append(dataPack, []byte(GConfig.ClientIP.To4())...)
log.Println("Response EAP-MD5-Challenge...")
sendEAP(0, layers.EAPTypeOTP, dataPack, layers.EAPCodeResponse, InterfaceMAC, BoardCastAddr)
}