start tying it into the flow

Signed-off-by: Jens Langhammer <jens@goauthentik.io>
This commit is contained in:
Jens Langhammer
2025-05-16 15:38:52 +02:00
parent 2a024238fe
commit fa06c9fe4e
7 changed files with 60 additions and 8 deletions

View File

@ -94,6 +94,10 @@ func NewFlowExecutor(ctx context.Context, flowSlug string, refConfig *api.Config
return fe
}
func (fe *FlowExecutor) AddHeader(name string, value string) {
fe.api.GetConfig().AddDefaultHeader(name, value)
}
func (fe *FlowExecutor) RoundTrip(req *http.Request) (*http.Response, error) {
res, err := fe.transport.RoundTrip(req)
if res != nil {

View File

@ -7,6 +7,7 @@ import (
)
type context struct {
req *radius.Request
state interface{}
log *log.Entry
settings interface{}
@ -14,6 +15,10 @@ type context struct {
endModifier func(p *radius.Packet) *radius.Packet
}
func (ctx context) Packet() *radius.Request {
return ctx.req
}
func (ctx context) ProtocolSettings() interface{} {
return ctx.settings
}
@ -30,6 +35,9 @@ func (ctx *context) SetProtocolState(st interface{}) {
}
func (ctx *context) EndInnerProtocol(st protocol.Status, mf func(p *radius.Packet) *radius.Packet) {
if ctx.endStatus != protocol.StatusUnknown {
return
}
ctx.endStatus = st
ctx.endModifier = mf
}

View File

@ -14,8 +14,8 @@ import (
"layeh.com/radius/rfc2869"
)
func (p *Packet) Handle(stm StateManager, w radius.ResponseWriter, r *radius.Packet) {
rst := rfc2865.State_GetString(r)
func (p *Packet) Handle(stm StateManager, w radius.ResponseWriter, r *radius.Request) {
rst := rfc2865.State_GetString(r.Packet)
if rst == "" {
rst = base64.StdEncoding.EncodeToString(securecookie.GenerateRandomKey(12))
}
@ -30,6 +30,7 @@ func (p *Packet) Handle(stm StateManager, w radius.ResponseWriter, r *radius.Pac
nextChallengeToOffer := st.ChallengesToOffer[0]
ctx := &context{
req: r,
state: st.TypeState[nextChallengeToOffer],
log: log.WithField("type", nextChallengeToOffer),
settings: stm.GetEAPSettings().ProtocolSettings[nextChallengeToOffer],

View File

@ -14,7 +14,7 @@ const (
)
type Context interface {
// GlobalState()
Packet() *radius.Request
ProtocolSettings() interface{}
GetProtocolState(def func(Context) interface{}) interface{}

View File

@ -159,6 +159,7 @@ func (p *Payload) tlsHandshakeFinished(ctx protocol.Context) {
ctx.Log().Debugf("TLS: ksm % x %v", ksm, err)
p.st.MPPEKey = ksm
p.st.HandshakeDone = true
ctx.ProtocolSettings().(Settings).HandshakeSuccessful(ctx, cs.PeerCertificates)
}
func (p *Payload) startChunkedTransfer(data []byte) *Payload {

View File

@ -1,7 +1,13 @@
package tls
import "crypto/tls"
import (
"crypto/tls"
"crypto/x509"
"goauthentik.io/internal/outpost/radius/eap/protocol"
)
type Settings struct {
Config *tls.Config
Config *tls.Config
HandshakeSuccessful func(ctx protocol.Context, certs []*x509.Certificate)
}

View File

@ -1,8 +1,12 @@
package radius
import (
"context"
ttls "crypto/tls"
"crypto/x509"
"encoding/base64"
"encoding/pem"
"net/url"
"github.com/prometheus/client_golang/prometheus"
log "github.com/sirupsen/logrus"
@ -11,6 +15,7 @@ import (
"goauthentik.io/internal/outpost/radius/eap/protocol"
"goauthentik.io/internal/outpost/radius/eap/tls"
"goauthentik.io/internal/outpost/radius/metrics"
"goauthentik.io/internal/utils"
"layeh.com/radius"
"layeh.com/radius/rfc2865"
"layeh.com/radius/rfc2869"
@ -111,11 +116,9 @@ func (rs *RadiusServer) Handle_AccessRequest_EAP(w radius.ResponseWriter, r *Rad
rs.log.WithError(err).Warning("failed to parse EAP packet")
return
}
ep.Handle(r.pi, w, r.Packet)
ep.Handle(r.pi, w, r.Request)
}
// -----------
func (pi *ProviderInstance) GetEAPState(key string) *eap.State {
return pi.eapState[key]
}
@ -142,6 +145,35 @@ func (pi *ProviderInstance) GetEAPSettings() eap.Settings {
Certificates: []ttls.Certificate{cert},
ClientAuth: ttls.RequireAnyClientCert,
},
HandshakeSuccessful: func(ctx protocol.Context, certs []*x509.Certificate) {
pem := pem.EncodeToMemory(&pem.Block{
Type: "CERTIFICATE",
Bytes: certs[0].Raw,
})
fe := flow.NewFlowExecutor(context.Background(), pi.flowSlug, pi.s.ac.Client.GetConfig(), log.Fields{
// "username": username,
// "client": r.RemoteAddr(),
// "requestId": r.ID(),
})
fe.DelegateClientIP(utils.GetIP(ctx.Packet().RemoteAddr))
fe.Params.Add("goauthentik.io/outpost/radius", "true")
fe.AddHeader("X-Authentik-Outpost-Certificate", url.QueryEscape(string(pem)))
passed, err := fe.Execute()
if err != nil {
panic(err)
}
if passed {
ctx.EndInnerProtocol(protocol.StatusSuccess, func(p *radius.Packet) *radius.Packet {
return p
})
} else {
ctx.EndInnerProtocol(protocol.StatusError, func(p *radius.Packet) *radius.Packet {
return p
})
}
},
},
},
}