@@ -2,6 +2,8 @@ package auth
22
33import (
44 "context"
5+ "encoding/hex"
6+ "errors"
57 "fmt"
68 "net/http"
79 "net/url"
@@ -13,21 +15,39 @@ import (
1315 "github.com/SenseUnit/dumbproxy/tlsutil"
1416)
1517
16- type TLSTicketAuth struct {
18+ type sessionValidator interface {
19+ Valid (sessionID , _ , userAddr string ) bool
20+ }
21+
22+ type TLSCookieAuth struct {
1723 logger * clog.CondLogger
1824 stopOnce sync.Once
1925 next Auth
2026 reject Auth
27+ lookup sessionValidator
2128}
2229
23- func NewTLSTicketAuth (param_url * url.URL , logger * clog.CondLogger ) (* TLSTicketAuth , error ) {
30+ func NewTLSCookieAuth (param_url * url.URL , logger * clog.CondLogger ) (* TLSCookieAuth , error ) {
2431 values , err := url .ParseQuery (param_url .RawQuery )
2532 if err != nil {
2633 return nil , err
2734 }
28- auth := & TLSTicketAuth {
35+ auth := & TLSCookieAuth {
2936 logger : logger ,
3037 }
38+ if lookupURL := values .Get ("lookup" ); lookupURL == "" {
39+ return nil , errors .New ("\" lookup\" parameter is mandatory for TLS cookie auth provider" )
40+ } else {
41+ lookupAuth , err := NewAuth (lookupURL , logger )
42+ if err != nil {
43+ return nil , fmt .Errorf ("unable to construct lookup provider for TLS cookie auth provider: %w" , err )
44+ }
45+ lookup , ok := lookupAuth .(sessionValidator )
46+ if ! ok {
47+ return nil , fmt .Errorf ("unable to construct TLS cookie auth provider: provided lookup provider %q is not suitable for session validation" , lookupURL )
48+ }
49+ auth .lookup = lookup
50+ }
3151 if nextAuth := values .Get ("next" ); nextAuth != "" {
3252 nap , err := NewAuth (nextAuth , logger )
3353 if err != nil {
@@ -45,25 +65,31 @@ func NewTLSTicketAuth(param_url *url.URL, logger *clog.CondLogger) (*TLSTicketAu
4565 return auth , nil
4666}
4767
48- func (auth * TLSTicketAuth ) Validate (ctx context.Context , wr http.ResponseWriter , req * http.Request ) (string , bool ) {
49- if ! tlsutil .NonDefaultKeyUsedFromContext (ctx ) {
68+ func (auth * TLSCookieAuth ) Validate (ctx context.Context , wr http.ResponseWriter , req * http.Request ) (string , bool ) {
69+ sessionID , ok := tlsutil .TLSSessionIDFromContext (ctx )
70+ if ! ok {
71+ auth .logger .Debug ("tlscookie: no session extracted for %s" , req .RemoteAddr )
72+ return auth .handleReject (ctx , wr , req )
73+ }
74+ if ! auth .lookup .Valid (hex .EncodeToString (sessionID [:]), "" , req .RemoteAddr ) {
75+ auth .logger .Info ("tlscookie: session ID %x from %s is not permitted" , sessionID , req .RemoteAddr )
5076 return auth .handleReject (ctx , wr , req )
5177 }
5278 if auth .next != nil {
5379 return auth .next .Validate (ctx , wr , req )
5480 }
55- return "" , true
81+ return fmt . Sprintf ( "tlscookie:%x" , sessionID ) , true
5682}
5783
58- func (auth * TLSTicketAuth ) handleReject (ctx context.Context , wr http.ResponseWriter , req * http.Request ) (string , bool ) {
84+ func (auth * TLSCookieAuth ) handleReject (ctx context.Context , wr http.ResponseWriter , req * http.Request ) (string , bool ) {
5985 if auth .reject != nil {
6086 return auth .reject .Validate (ctx , wr , req )
6187 }
6288 http .Error (wr , BAD_REQ_MSG , http .StatusBadRequest )
6389 return "" , false
6490}
6591
66- func (auth * TLSTicketAuth ) Close () error {
92+ func (auth * TLSCookieAuth ) Close () error {
6793 var err error
6894 auth .stopOnce .Do (func () {
6995 if auth .next != nil {
0 commit comments