separate eap logic into protocol
Signed-off-by: Jens Langhammer <jens@goauthentik.io>
This commit is contained in:
@ -18,6 +18,8 @@ type Context interface {
|
||||
Packet() *radius.Request
|
||||
|
||||
ProtocolSettings() interface{}
|
||||
|
||||
StateForProtocol(p Type) interface{}
|
||||
GetProtocolState() interface{}
|
||||
SetProtocolState(interface{})
|
||||
|
||||
|
||||
83
internal/outpost/radius/eap/protocol/eap/payload.go
Normal file
83
internal/outpost/radius/eap/protocol/eap/payload.go
Normal file
@ -0,0 +1,83 @@
|
||||
package eap
|
||||
|
||||
import (
|
||||
"encoding/binary"
|
||||
"errors"
|
||||
"fmt"
|
||||
|
||||
log "github.com/sirupsen/logrus"
|
||||
"goauthentik.io/internal/outpost/radius/eap/debug"
|
||||
"goauthentik.io/internal/outpost/radius/eap/protocol"
|
||||
)
|
||||
|
||||
const TypeEAP protocol.Type = 0
|
||||
|
||||
func Protocol() protocol.Payload {
|
||||
return &Payload{}
|
||||
}
|
||||
|
||||
type Payload struct {
|
||||
Code protocol.Code
|
||||
ID uint8
|
||||
Length uint16
|
||||
MsgType protocol.Type
|
||||
Payload protocol.Payload
|
||||
RawPayload []byte
|
||||
}
|
||||
|
||||
func (ip *Payload) Type() protocol.Type {
|
||||
return TypeEAP
|
||||
}
|
||||
|
||||
func (ip *Payload) Offerable() bool {
|
||||
return false
|
||||
}
|
||||
|
||||
func (packet *Payload) Decode(raw []byte) error {
|
||||
packet.Code = protocol.Code(raw[0])
|
||||
packet.ID = raw[1]
|
||||
packet.Length = binary.BigEndian.Uint16(raw[2:])
|
||||
if packet.Length != uint16(len(raw)) {
|
||||
return errors.New("mismatched packet length")
|
||||
}
|
||||
if len(raw) > 4 && (packet.Code == protocol.CodeRequest || packet.Code == protocol.CodeResponse) {
|
||||
packet.MsgType = protocol.Type(raw[4])
|
||||
}
|
||||
packet.RawPayload = raw[5:]
|
||||
if packet.Payload == nil {
|
||||
return nil
|
||||
}
|
||||
log.WithField("raw", debug.FormatBytes(raw)).WithField("payload", fmt.Sprintf("%T", packet.Payload)).Debug("EAP: decode raw")
|
||||
err := packet.Payload.Decode(raw[5:])
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (p *Payload) Encode() ([]byte, error) {
|
||||
buff := make([]byte, 4)
|
||||
buff[0] = uint8(p.Code)
|
||||
buff[1] = uint8(p.ID)
|
||||
|
||||
if p.Payload != nil {
|
||||
payloadBuffer, err := p.Payload.Encode()
|
||||
if err != nil {
|
||||
return buff, err
|
||||
}
|
||||
if p.Code == protocol.CodeRequest || p.Code == protocol.CodeResponse {
|
||||
buff = append(buff, uint8(p.MsgType))
|
||||
}
|
||||
buff = append(buff, payloadBuffer...)
|
||||
}
|
||||
binary.BigEndian.PutUint16(buff[2:], uint16(len(buff)))
|
||||
return buff, nil
|
||||
}
|
||||
|
||||
func (ip *Payload) Handle(ctx protocol.Context) protocol.Payload {
|
||||
ctx.Log().Debug("EAP: Handle")
|
||||
ctx.SetProtocolState(&State{
|
||||
PacketID: ip.ID,
|
||||
})
|
||||
return nil
|
||||
}
|
||||
5
internal/outpost/radius/eap/protocol/eap/state.go
Normal file
5
internal/outpost/radius/eap/protocol/eap/state.go
Normal file
@ -0,0 +1,5 @@
|
||||
package eap
|
||||
|
||||
type State struct {
|
||||
PacketID uint8
|
||||
}
|
||||
@ -9,3 +9,12 @@ type Payload interface {
|
||||
}
|
||||
|
||||
type Type uint8
|
||||
|
||||
type Code uint8
|
||||
|
||||
const (
|
||||
CodeRequest Code = 1
|
||||
CodeResponse Code = 2
|
||||
CodeSuccess Code = 3
|
||||
CodeFailure Code = 4
|
||||
)
|
||||
|
||||
@ -4,6 +4,8 @@ import (
|
||||
log "github.com/sirupsen/logrus"
|
||||
"goauthentik.io/internal/outpost/radius/eap/debug"
|
||||
"goauthentik.io/internal/outpost/radius/eap/protocol"
|
||||
"goauthentik.io/internal/outpost/radius/eap/protocol/eap"
|
||||
"goauthentik.io/internal/outpost/radius/eap/protocol/identity"
|
||||
"goauthentik.io/internal/outpost/radius/eap/protocol/tls"
|
||||
)
|
||||
|
||||
@ -11,11 +13,14 @@ const TypePEAP protocol.Type = 25
|
||||
|
||||
func Protocol() protocol.Payload {
|
||||
return &tls.Payload{
|
||||
Inner: &Payload{},
|
||||
Inner: &Payload{
|
||||
Inner: &eap.Payload{},
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
type Payload struct {
|
||||
Inner protocol.Payload
|
||||
}
|
||||
|
||||
func (p *Payload) Type() protocol.Type {
|
||||
@ -33,7 +38,16 @@ func (p *Payload) Encode() ([]byte, error) {
|
||||
}
|
||||
|
||||
func (p *Payload) Handle(ctx protocol.Context) protocol.Payload {
|
||||
log.Debug("PEAP: Handle")
|
||||
eapState := ctx.StateForProtocol(eap.TypeEAP).(*eap.State)
|
||||
if !ctx.IsProtocolStart() {
|
||||
ctx.Log().Debug("PEAP: Protocol start")
|
||||
return &eap.Payload{
|
||||
Code: protocol.CodeRequest,
|
||||
ID: eapState.PacketID,
|
||||
MsgType: identity.TypeIdentity,
|
||||
Payload: &identity.Payload{},
|
||||
}
|
||||
}
|
||||
return &Payload{}
|
||||
}
|
||||
|
||||
|
||||
@ -4,18 +4,19 @@ import (
|
||||
"goauthentik.io/internal/outpost/radius/eap/protocol"
|
||||
)
|
||||
|
||||
func (p *Payload) innerHandler(ctx protocol.Context) *Payload {
|
||||
func (p *Payload) innerHandler(ctx protocol.Context) {
|
||||
// p.st.TLS.read
|
||||
// d, _ := io.ReadAll(p.st.TLS)
|
||||
err := p.Inner.Decode([]byte{})
|
||||
if err != nil {
|
||||
ctx.Log().WithError(err).Warning("TLS: failed to decode inner protocol")
|
||||
ctx.EndInnerProtocol(protocol.StatusError, nil)
|
||||
return nil
|
||||
return
|
||||
}
|
||||
pl := p.Inner.Handle(ctx)
|
||||
enc, err := pl.Encode()
|
||||
return &Payload{
|
||||
Data: enc,
|
||||
}
|
||||
p.st.TLS.Write(enc)
|
||||
// return &Payload{
|
||||
// Data: enc,
|
||||
// }
|
||||
}
|
||||
|
||||
@ -124,7 +124,8 @@ func (p *Payload) Handle(ctx protocol.Context) protocol.Payload {
|
||||
defer p.st.ContextCancel()
|
||||
if p.Inner != nil {
|
||||
ctx.Log().Debug("TLS: Handshake is done, delegating to inner protocol")
|
||||
return p.innerHandler(ctx)
|
||||
p.innerHandler(ctx)
|
||||
return p.startChunkedTransfer(p.st.Conn.OutboundData())
|
||||
}
|
||||
// If we don't have a final status from the handshake finished function, stall for time
|
||||
pst, _ := retry.DoWithData(
|
||||
|
||||
Reference in New Issue
Block a user