@ -2,26 +2,8 @@ package debug
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"github.com/google/gopacket"
|
||||
"github.com/google/gopacket/layers"
|
||||
log "github.com/sirupsen/logrus"
|
||||
"layeh.com/radius"
|
||||
)
|
||||
|
||||
func DebugPacket(p *radius.Packet) {
|
||||
log.Debug(p)
|
||||
log.Debug(p.Attributes)
|
||||
n, _ := p.Encode()
|
||||
log.Debug(n)
|
||||
packet := gopacket.NewPacket(n, layers.LayerTypeRADIUS, gopacket.Default)
|
||||
layer := packet.Layer(layers.LayerTypeRADIUS)
|
||||
if layer == nil {
|
||||
return
|
||||
}
|
||||
log.Debug(layer.(*layers.RADIUS))
|
||||
}
|
||||
|
||||
func FormatBytes(d []byte) string {
|
||||
b := d
|
||||
if len(b) > 32 {
|
||||
|
||||
@ -1,38 +0,0 @@
|
||||
package mschapv2
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"errors"
|
||||
|
||||
"layeh.com/radius/rfc2759"
|
||||
"layeh.com/radius/rfc3079"
|
||||
)
|
||||
|
||||
func (p *Payload) checkChapPassword(res *Response) ([]byte, error) {
|
||||
byteUser := []byte("foo")
|
||||
bytePwd := []byte("bar")
|
||||
ntResponse, err := rfc2759.GenerateNTResponse(p.st.Challenge, p.st.PeerChallenge, byteUser, bytePwd)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if !bytes.Equal(ntResponse, res.NTResponse) {
|
||||
return nil, errors.New("nt response mismatch")
|
||||
}
|
||||
|
||||
p.st.recvKey, err = rfc3079.MakeKey(ntResponse, bytePwd, false)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
p.st.sendKey, err = rfc3079.MakeKey(ntResponse, bytePwd, true)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
authenticatorResponse, err := rfc2759.GenerateAuthenticatorResponse(p.st.Challenge, p.st.PeerChallenge, ntResponse, byteUser, bytePwd)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return []byte(authenticatorResponse), nil
|
||||
}
|
||||
@ -1,6 +1,7 @@
|
||||
package mschapv2
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"encoding/binary"
|
||||
"fmt"
|
||||
|
||||
@ -115,6 +116,8 @@ func (p *Payload) Handle(ctx protocol.Context) protocol.Payload {
|
||||
MSCHAPv2ID: rootEap.ID + 1,
|
||||
}
|
||||
|
||||
settings := ctx.ProtocolSettings().(Settings)
|
||||
|
||||
ctx.Log().Debugf("MSCHAPv2: OpCode: %d", p.OpCode)
|
||||
if p.OpCode == OpResponse {
|
||||
res, err := ParseResponse(p.Response)
|
||||
@ -123,21 +126,28 @@ func (p *Payload) Handle(ctx protocol.Context) protocol.Payload {
|
||||
return nil
|
||||
}
|
||||
p.st.PeerChallenge = res.Challenge
|
||||
auth, err := p.checkChapPassword(res)
|
||||
auth, err := settings.AuthenticateRequest(AuthRequest{
|
||||
Challenge: p.st.Challenge,
|
||||
PeerChallenge: p.st.PeerChallenge,
|
||||
})
|
||||
if err != nil {
|
||||
ctx.Log().WithError(err).Warning("MSCHAPv2: failed to check password")
|
||||
return nil
|
||||
}
|
||||
if !bytes.Equal(auth.NTResponse, res.NTResponse) {
|
||||
ctx.Log().Warning("MSCHAPv2: NT response mismatch")
|
||||
return nil
|
||||
}
|
||||
ctx.Log().Info("MSCHAPv2: Successfully checked password")
|
||||
p.st.Authenticated = true
|
||||
p.st.AuthResponse = auth
|
||||
succ := &SuccessRequest{
|
||||
Payload: &Payload{
|
||||
OpCode: OpSuccess,
|
||||
},
|
||||
Authenticator: auth,
|
||||
Authenticator: []byte(auth.AuthenticatorResponse),
|
||||
}
|
||||
return succ
|
||||
} else if p.OpCode == OpSuccess && p.st.Authenticated {
|
||||
} else if p.OpCode == OpSuccess && p.st.AuthResponse != nil {
|
||||
ep := &peap.ExtensionPayload{
|
||||
AVPs: []peap.ExtensionAVP{
|
||||
{
|
||||
@ -152,10 +162,10 @@ func (p *Payload) Handle(ctx protocol.Context) protocol.Payload {
|
||||
} else if p.st.IsProtocolEnded {
|
||||
ctx.EndInnerProtocol(protocol.StatusSuccess, func(r *radius.Packet) *radius.Packet {
|
||||
if len(microsoft.MSMPPERecvKey_Get(r, ctx.Packet().Packet)) < 1 {
|
||||
microsoft.MSMPPERecvKey_Set(r, p.st.recvKey)
|
||||
microsoft.MSMPPERecvKey_Set(r, p.st.AuthResponse.RecvKey)
|
||||
}
|
||||
if len(microsoft.MSMPPESendKey_Get(r, ctx.Packet().Packet)) < 1 {
|
||||
microsoft.MSMPPESendKey_Set(r, p.st.sendKey)
|
||||
microsoft.MSMPPESendKey_Set(r, p.st.AuthResponse.SendKey)
|
||||
}
|
||||
return r
|
||||
})
|
||||
|
||||
50
internal/outpost/radius/eap/protocol/mschapv2/settings.go
Normal file
50
internal/outpost/radius/eap/protocol/mschapv2/settings.go
Normal file
@ -0,0 +1,50 @@
|
||||
package mschapv2
|
||||
|
||||
import (
|
||||
"layeh.com/radius/rfc2759"
|
||||
"layeh.com/radius/rfc3079"
|
||||
)
|
||||
|
||||
type Settings struct {
|
||||
AuthenticateRequest func(req AuthRequest) (*AuthResponse, error)
|
||||
}
|
||||
|
||||
type AuthRequest struct {
|
||||
Challenge []byte
|
||||
PeerChallenge []byte
|
||||
}
|
||||
|
||||
type AuthResponse struct {
|
||||
NTResponse []byte
|
||||
RecvKey []byte
|
||||
SendKey []byte
|
||||
AuthenticatorResponse string
|
||||
}
|
||||
|
||||
func DebugStaticCredentials(user, password []byte) func(req AuthRequest) (*AuthResponse, error) {
|
||||
return func(req AuthRequest) (*AuthResponse, error) {
|
||||
res := &AuthResponse{}
|
||||
ntResponse, err := rfc2759.GenerateNTResponse(req.Challenge, req.PeerChallenge, user, password)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
res.NTResponse = ntResponse
|
||||
|
||||
res.RecvKey, err = rfc3079.MakeKey(ntResponse, password, false)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
res.SendKey, err = rfc3079.MakeKey(ntResponse, password, true)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
res.AuthenticatorResponse, err = rfc2759.GenerateAuthenticatorResponse(req.Challenge, req.PeerChallenge, ntResponse, user, password)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return res, nil
|
||||
|
||||
}
|
||||
}
|
||||
@ -3,8 +3,6 @@ package mschapv2
|
||||
type State struct {
|
||||
Challenge []byte
|
||||
PeerChallenge []byte
|
||||
Authenticated bool
|
||||
IsProtocolEnded bool
|
||||
recvKey []byte
|
||||
sendKey []byte
|
||||
AuthResponse *AuthResponse
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user