Move CookieOptions validation to it's own file
This commit is contained in:
		
							parent
							
								
									b3ba2594c6
								
							
						
					
					
						commit
						900061b88a
					
				|  | @ -0,0 +1,69 @@ | ||||||
|  | package validation | ||||||
|  | 
 | ||||||
|  | import ( | ||||||
|  | 	"fmt" | ||||||
|  | 	"net/http" | ||||||
|  | 	"sort" | ||||||
|  | 
 | ||||||
|  | 	"github.com/oauth2-proxy/oauth2-proxy/pkg/apis/options" | ||||||
|  | 	"github.com/oauth2-proxy/oauth2-proxy/pkg/encryption" | ||||||
|  | ) | ||||||
|  | 
 | ||||||
|  | func validateCookieOptions(o options.CookieOptions) []string { | ||||||
|  | 	msgs := validateCookieSecret(o.Secret) | ||||||
|  | 
 | ||||||
|  | 	if o.Refresh >= o.Expire { | ||||||
|  | 		msgs = append(msgs, fmt.Sprintf( | ||||||
|  | 			"cookie_refresh (%q) must be less than cookie_expire (%q)", | ||||||
|  | 			o.Refresh.String(), | ||||||
|  | 			o.Expire.String())) | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	switch o.SameSite { | ||||||
|  | 	case "", "none", "lax", "strict": | ||||||
|  | 	default: | ||||||
|  | 		msgs = append(msgs, fmt.Sprintf("cookie_samesite (%q) must be one of ['', 'lax', 'strict', 'none']", o.SameSite)) | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	// Sort cookie domains by length, so that we try longer (and more specific) domains first
 | ||||||
|  | 	sort.Slice(o.Domains, func(i, j int) bool { | ||||||
|  | 		return len(o.Domains[i]) > len(o.Domains[j]) | ||||||
|  | 	}) | ||||||
|  | 
 | ||||||
|  | 	msgs = append(msgs, validateCookieName(o.Name)...) | ||||||
|  | 	return msgs | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | func validateCookieName(name string) []string { | ||||||
|  | 	cookie := &http.Cookie{Name: name} | ||||||
|  | 	if cookie.String() == "" { | ||||||
|  | 		return []string{fmt.Sprintf("invalid cookie name: %q", name)} | ||||||
|  | 	} | ||||||
|  | 	return []string{} | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | func validateCookieSecret(secret string) []string { | ||||||
|  | 	if secret == "" { | ||||||
|  | 		return []string{"missing setting: cookie-secret"} | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	secretBytes := encryption.SecretBytes(secret) | ||||||
|  | 	// Check if the secret is a valid length
 | ||||||
|  | 	switch len(secretBytes) { | ||||||
|  | 	case 16, 24, 32: | ||||||
|  | 		// Valid secret size found
 | ||||||
|  | 		return []string{} | ||||||
|  | 	} | ||||||
|  | 	// Invalid secret size found, return a message
 | ||||||
|  | 
 | ||||||
|  | 	// If the secretBytes is different to the raw secret, it was decoded from Base64
 | ||||||
|  | 	// Add a note to the error message
 | ||||||
|  | 	var decodedSuffix string | ||||||
|  | 	if string(secretBytes) != secret { | ||||||
|  | 		decodedSuffix = " note: cookie secret was base64 decoded" | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	return []string{fmt.Sprintf( | ||||||
|  | 		"cookie_secret must be 16, 24, or 32 bytes to create an AES cipher, but is %d bytes.%s", | ||||||
|  | 		len(secretBytes), decodedSuffix)} | ||||||
|  | } | ||||||
|  | @ -10,14 +10,12 @@ import ( | ||||||
| 	"net/url" | 	"net/url" | ||||||
| 	"os" | 	"os" | ||||||
| 	"regexp" | 	"regexp" | ||||||
| 	"sort" |  | ||||||
| 	"strings" | 	"strings" | ||||||
| 
 | 
 | ||||||
| 	"github.com/coreos/go-oidc" | 	"github.com/coreos/go-oidc" | ||||||
| 	"github.com/dgrijalva/jwt-go" | 	"github.com/dgrijalva/jwt-go" | ||||||
| 	"github.com/mbland/hmacauth" | 	"github.com/mbland/hmacauth" | ||||||
| 	"github.com/oauth2-proxy/oauth2-proxy/pkg/apis/options" | 	"github.com/oauth2-proxy/oauth2-proxy/pkg/apis/options" | ||||||
| 	"github.com/oauth2-proxy/oauth2-proxy/pkg/encryption" |  | ||||||
| 	"github.com/oauth2-proxy/oauth2-proxy/pkg/ip" | 	"github.com/oauth2-proxy/oauth2-proxy/pkg/ip" | ||||||
| 	"github.com/oauth2-proxy/oauth2-proxy/pkg/logger" | 	"github.com/oauth2-proxy/oauth2-proxy/pkg/logger" | ||||||
| 	"github.com/oauth2-proxy/oauth2-proxy/pkg/requests" | 	"github.com/oauth2-proxy/oauth2-proxy/pkg/requests" | ||||||
|  | @ -28,7 +26,8 @@ import ( | ||||||
| // Validate checks that required options are set and validates those that they
 | // Validate checks that required options are set and validates those that they
 | ||||||
| // are of the correct format
 | // are of the correct format
 | ||||||
| func Validate(o *options.Options) error { | func Validate(o *options.Options) error { | ||||||
| 	msgs := make([]string, 0) | 	msgs := validateCookieOptions(o.Cookie) | ||||||
|  | 
 | ||||||
| 	if o.SSLInsecureSkipVerify { | 	if o.SSLInsecureSkipVerify { | ||||||
| 		insecureTransport := &http.Transport{ | 		insecureTransport := &http.Transport{ | ||||||
| 			TLSClientConfig: &tls.Config{InsecureSkipVerify: true}, | 			TLSClientConfig: &tls.Config{InsecureSkipVerify: true}, | ||||||
|  | @ -49,30 +48,6 @@ func Validate(o *options.Options) error { | ||||||
| 		} | 		} | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	if o.Cookie.Secret == "" { |  | ||||||
| 		msgs = append(msgs, "missing setting: cookie-secret") |  | ||||||
| 	} else { |  | ||||||
| 		validCookieSecretSize := false |  | ||||||
| 		for _, i := range []int{16, 24, 32} { |  | ||||||
| 			if len(encryption.SecretBytes(o.Cookie.Secret)) == i { |  | ||||||
| 				validCookieSecretSize = true |  | ||||||
| 			} |  | ||||||
| 		} |  | ||||||
| 		var decoded bool |  | ||||||
| 		if string(encryption.SecretBytes(o.Cookie.Secret)) != o.Cookie.Secret { |  | ||||||
| 			decoded = true |  | ||||||
| 		} |  | ||||||
| 		if !validCookieSecretSize { |  | ||||||
| 			var suffix string |  | ||||||
| 			if decoded { |  | ||||||
| 				suffix = " note: cookie secret was base64 decoded" |  | ||||||
| 			} |  | ||||||
| 			msgs = append(msgs, |  | ||||||
| 				fmt.Sprintf("Cookie secret must be 16, 24, or 32 bytes to create an AES cipher. Got %d bytes.%s", |  | ||||||
| 					len(encryption.SecretBytes(o.Cookie.Secret)), suffix)) |  | ||||||
| 		} |  | ||||||
| 	} |  | ||||||
| 
 |  | ||||||
| 	if o.ClientID == "" { | 	if o.ClientID == "" { | ||||||
| 		msgs = append(msgs, "missing setting: client-id") | 		msgs = append(msgs, "missing setting: client-id") | ||||||
| 	} | 	} | ||||||
|  | @ -222,14 +197,6 @@ func Validate(o *options.Options) error { | ||||||
| 	} | 	} | ||||||
| 	msgs = parseProviderInfo(o, msgs) | 	msgs = parseProviderInfo(o, msgs) | ||||||
| 
 | 
 | ||||||
| 	if o.Cookie.Refresh >= o.Cookie.Expire { |  | ||||||
| 		msgs = append(msgs, fmt.Sprintf( |  | ||||||
| 			"cookie_refresh (%s) must be less than "+ |  | ||||||
| 				"cookie_expire (%s)", |  | ||||||
| 			o.Cookie.Refresh.String(), |  | ||||||
| 			o.Cookie.Expire.String())) |  | ||||||
| 	} |  | ||||||
| 
 |  | ||||||
| 	if len(o.GoogleGroups) > 0 || o.GoogleAdminEmail != "" || o.GoogleServiceAccountJSON != "" { | 	if len(o.GoogleGroups) > 0 || o.GoogleAdminEmail != "" || o.GoogleServiceAccountJSON != "" { | ||||||
| 		if len(o.GoogleGroups) < 1 { | 		if len(o.GoogleGroups) < 1 { | ||||||
| 			msgs = append(msgs, "missing setting: google-group") | 			msgs = append(msgs, "missing setting: google-group") | ||||||
|  | @ -242,20 +209,7 @@ func Validate(o *options.Options) error { | ||||||
| 		} | 		} | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	switch o.Cookie.SameSite { |  | ||||||
| 	case "", "none", "lax", "strict": |  | ||||||
| 	default: |  | ||||||
| 		msgs = append(msgs, fmt.Sprintf("cookie_samesite (%s) must be one of ['', 'lax', 'strict', 'none']", o.Cookie.SameSite)) |  | ||||||
| 	} |  | ||||||
| 
 |  | ||||||
| 	// Sort cookie domains by length, so that we try longer (and more specific)
 |  | ||||||
| 	// domains first
 |  | ||||||
| 	sort.Slice(o.Cookie.Domains, func(i, j int) bool { |  | ||||||
| 		return len(o.Cookie.Domains[i]) > len(o.Cookie.Domains[j]) |  | ||||||
| 	}) |  | ||||||
| 
 |  | ||||||
| 	msgs = parseSignatureKey(o, msgs) | 	msgs = parseSignatureKey(o, msgs) | ||||||
| 	msgs = validateCookieName(o, msgs) |  | ||||||
| 	msgs = configureLogger(o.Logging, msgs) | 	msgs = configureLogger(o.Logging, msgs) | ||||||
| 
 | 
 | ||||||
| 	if o.ReverseProxy { | 	if o.ReverseProxy { | ||||||
|  | @ -442,14 +396,6 @@ func newVerifierFromJwtIssuer(jwtIssuer jwtIssuer) (*oidc.IDTokenVerifier, error | ||||||
| 	return verifier, nil | 	return verifier, nil | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| func validateCookieName(o *options.Options, msgs []string) []string { |  | ||||||
| 	cookie := &http.Cookie{Name: o.Cookie.Name} |  | ||||||
| 	if cookie.String() == "" { |  | ||||||
| 		return append(msgs, fmt.Sprintf("invalid cookie name: %q", o.Cookie.Name)) |  | ||||||
| 	} |  | ||||||
| 	return msgs |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| // jwtIssuer hold parsed JWT issuer info that's used to construct a verifier.
 | // jwtIssuer hold parsed JWT issuer info that's used to construct a verifier.
 | ||||||
| type jwtIssuer struct { | type jwtIssuer struct { | ||||||
| 	issuerURI string | 	issuerURI string | ||||||
|  |  | ||||||
		Loading…
	
		Reference in New Issue