start tying it into the flow
Signed-off-by: Jens Langhammer <jens@goauthentik.io>
This commit is contained in:
		| @ -94,6 +94,10 @@ func NewFlowExecutor(ctx context.Context, flowSlug string, refConfig *api.Config | |||||||
| 	return fe | 	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) { | func (fe *FlowExecutor) RoundTrip(req *http.Request) (*http.Response, error) { | ||||||
| 	res, err := fe.transport.RoundTrip(req) | 	res, err := fe.transport.RoundTrip(req) | ||||||
| 	if res != nil { | 	if res != nil { | ||||||
|  | |||||||
| @ -7,6 +7,7 @@ import ( | |||||||
| ) | ) | ||||||
|  |  | ||||||
| type context struct { | type context struct { | ||||||
|  | 	req         *radius.Request | ||||||
| 	state       interface{} | 	state       interface{} | ||||||
| 	log         *log.Entry | 	log         *log.Entry | ||||||
| 	settings    interface{} | 	settings    interface{} | ||||||
| @ -14,6 +15,10 @@ type context struct { | |||||||
| 	endModifier func(p *radius.Packet) *radius.Packet | 	endModifier func(p *radius.Packet) *radius.Packet | ||||||
| } | } | ||||||
|  |  | ||||||
|  | func (ctx context) Packet() *radius.Request { | ||||||
|  | 	return ctx.req | ||||||
|  | } | ||||||
|  |  | ||||||
| func (ctx context) ProtocolSettings() interface{} { | func (ctx context) ProtocolSettings() interface{} { | ||||||
| 	return ctx.settings | 	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) { | func (ctx *context) EndInnerProtocol(st protocol.Status, mf func(p *radius.Packet) *radius.Packet) { | ||||||
|  | 	if ctx.endStatus != protocol.StatusUnknown { | ||||||
|  | 		return | ||||||
|  | 	} | ||||||
| 	ctx.endStatus = st | 	ctx.endStatus = st | ||||||
| 	ctx.endModifier = mf | 	ctx.endModifier = mf | ||||||
| } | } | ||||||
|  | |||||||
| @ -14,8 +14,8 @@ import ( | |||||||
| 	"layeh.com/radius/rfc2869" | 	"layeh.com/radius/rfc2869" | ||||||
| ) | ) | ||||||
|  |  | ||||||
| func (p *Packet) Handle(stm StateManager, w radius.ResponseWriter, r *radius.Packet) { | func (p *Packet) Handle(stm StateManager, w radius.ResponseWriter, r *radius.Request) { | ||||||
| 	rst := rfc2865.State_GetString(r) | 	rst := rfc2865.State_GetString(r.Packet) | ||||||
| 	if rst == "" { | 	if rst == "" { | ||||||
| 		rst = base64.StdEncoding.EncodeToString(securecookie.GenerateRandomKey(12)) | 		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] | 	nextChallengeToOffer := st.ChallengesToOffer[0] | ||||||
|  |  | ||||||
| 	ctx := &context{ | 	ctx := &context{ | ||||||
|  | 		req:      r, | ||||||
| 		state:    st.TypeState[nextChallengeToOffer], | 		state:    st.TypeState[nextChallengeToOffer], | ||||||
| 		log:      log.WithField("type", nextChallengeToOffer), | 		log:      log.WithField("type", nextChallengeToOffer), | ||||||
| 		settings: stm.GetEAPSettings().ProtocolSettings[nextChallengeToOffer], | 		settings: stm.GetEAPSettings().ProtocolSettings[nextChallengeToOffer], | ||||||
|  | |||||||
| @ -14,7 +14,7 @@ const ( | |||||||
| ) | ) | ||||||
|  |  | ||||||
| type Context interface { | type Context interface { | ||||||
| 	// GlobalState() | 	Packet() *radius.Request | ||||||
|  |  | ||||||
| 	ProtocolSettings() interface{} | 	ProtocolSettings() interface{} | ||||||
| 	GetProtocolState(def func(Context) interface{}) interface{} | 	GetProtocolState(def func(Context) interface{}) interface{} | ||||||
|  | |||||||
| @ -159,6 +159,7 @@ func (p *Payload) tlsHandshakeFinished(ctx protocol.Context) { | |||||||
| 	ctx.Log().Debugf("TLS: ksm % x %v", ksm, err) | 	ctx.Log().Debugf("TLS: ksm % x %v", ksm, err) | ||||||
| 	p.st.MPPEKey = ksm | 	p.st.MPPEKey = ksm | ||||||
| 	p.st.HandshakeDone = true | 	p.st.HandshakeDone = true | ||||||
|  | 	ctx.ProtocolSettings().(Settings).HandshakeSuccessful(ctx, cs.PeerCertificates) | ||||||
| } | } | ||||||
|  |  | ||||||
| func (p *Payload) startChunkedTransfer(data []byte) *Payload { | func (p *Payload) startChunkedTransfer(data []byte) *Payload { | ||||||
|  | |||||||
| @ -1,7 +1,13 @@ | |||||||
| package tls | package tls | ||||||
|  |  | ||||||
| import "crypto/tls" | import ( | ||||||
|  | 	"crypto/tls" | ||||||
|  | 	"crypto/x509" | ||||||
|  |  | ||||||
|  | 	"goauthentik.io/internal/outpost/radius/eap/protocol" | ||||||
|  | ) | ||||||
|  |  | ||||||
| type Settings struct { | type Settings struct { | ||||||
| 	Config *tls.Config | 	Config              *tls.Config | ||||||
|  | 	HandshakeSuccessful func(ctx protocol.Context, certs []*x509.Certificate) | ||||||
| } | } | ||||||
|  | |||||||
| @ -1,8 +1,12 @@ | |||||||
| package radius | package radius | ||||||
|  |  | ||||||
| import ( | import ( | ||||||
|  | 	"context" | ||||||
| 	ttls "crypto/tls" | 	ttls "crypto/tls" | ||||||
|  | 	"crypto/x509" | ||||||
| 	"encoding/base64" | 	"encoding/base64" | ||||||
|  | 	"encoding/pem" | ||||||
|  | 	"net/url" | ||||||
|  |  | ||||||
| 	"github.com/prometheus/client_golang/prometheus" | 	"github.com/prometheus/client_golang/prometheus" | ||||||
| 	log "github.com/sirupsen/logrus" | 	log "github.com/sirupsen/logrus" | ||||||
| @ -11,6 +15,7 @@ import ( | |||||||
| 	"goauthentik.io/internal/outpost/radius/eap/protocol" | 	"goauthentik.io/internal/outpost/radius/eap/protocol" | ||||||
| 	"goauthentik.io/internal/outpost/radius/eap/tls" | 	"goauthentik.io/internal/outpost/radius/eap/tls" | ||||||
| 	"goauthentik.io/internal/outpost/radius/metrics" | 	"goauthentik.io/internal/outpost/radius/metrics" | ||||||
|  | 	"goauthentik.io/internal/utils" | ||||||
| 	"layeh.com/radius" | 	"layeh.com/radius" | ||||||
| 	"layeh.com/radius/rfc2865" | 	"layeh.com/radius/rfc2865" | ||||||
| 	"layeh.com/radius/rfc2869" | 	"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") | 		rs.log.WithError(err).Warning("failed to parse EAP packet") | ||||||
| 		return | 		return | ||||||
| 	} | 	} | ||||||
| 	ep.Handle(r.pi, w, r.Packet) | 	ep.Handle(r.pi, w, r.Request) | ||||||
| } | } | ||||||
|  |  | ||||||
| // ----------- |  | ||||||
|  |  | ||||||
| func (pi *ProviderInstance) GetEAPState(key string) *eap.State { | func (pi *ProviderInstance) GetEAPState(key string) *eap.State { | ||||||
| 	return pi.eapState[key] | 	return pi.eapState[key] | ||||||
| } | } | ||||||
| @ -142,6 +145,35 @@ func (pi *ProviderInstance) GetEAPSettings() eap.Settings { | |||||||
| 					Certificates: []ttls.Certificate{cert}, | 					Certificates: []ttls.Certificate{cert}, | ||||||
| 					ClientAuth:   ttls.RequireAnyClientCert, | 					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 | ||||||
|  | 						}) | ||||||
|  | 					} | ||||||
|  | 				}, | ||||||
| 			}, | 			}, | ||||||
| 		}, | 		}, | ||||||
| 	} | 	} | ||||||
|  | |||||||
		Reference in New Issue
	
	Block a user
	 Jens Langhammer
					Jens Langhammer