diff --git a/auth/token_issuer.go b/auth/token_issuer.go index c57356c..4b98a7a 100644 --- a/auth/token_issuer.go +++ b/auth/token_issuer.go @@ -1,26 +1,30 @@ package auth import ( + "fmt" "net/http" "encoding/json" + "strings" + "time" + goldap "github.com/go-ldap/ldap" "github.com/golang/glog" "github.com/prometheus/client_golang/prometheus" + "github.com/proofpoint/kubernetes-ldap/client" "github.com/proofpoint/kubernetes-ldap/ldap" "github.com/proofpoint/kubernetes-ldap/token" - "strings" - "time" ) // LDAPTokenIssuer issues cryptographically secure tokens after authenticating the // user against a backing LDAP directory. type LDAPTokenIssuer struct { - LDAPServer string - LDAPAuthenticator ldap.Authenticator - TokenSigner token.Signer - TTL time.Duration - UsernameAttribute string + LDAPServer string + LDAPAuthenticator ldap.Authenticator + TokenSigner token.Signer + TTL time.Duration + UsernameAttribute string + EnforceClientVersions bool } var ( @@ -75,6 +79,24 @@ func (lti *LDAPTokenIssuer) ServeHTTP(resp http.ResponseWriter, req *http.Reques return } + if lti.EnforceClientVersions { + pluginVersion := req.Header.Get("x-pfpt-k8sldapctl-version") + kubectlVersion := req.Header.Get("x-pfpt-kubectl-version") + + if pluginVersion == "" || kubectlVersion == "" { + resp.WriteHeader(http.StatusBadRequest) + resp.Write([]byte(fmt.Sprintf("\nError: you are using an old version of k8sldapctl plugin. Please upgrade to minimum of %q", client.MinimumPluginVersion))) + return + } + + err := client.Validate(pluginVersion, kubectlVersion) + if err != nil { + resp.WriteHeader(http.StatusBadRequest) + resp.Write([]byte(fmt.Sprintf("\nError: %s", err.Error()))) + return + } + } + // Authenticate the user via LDAP ldapEntry, err := lti.LDAPAuthenticator.Authenticate(user, password) if err != nil { diff --git a/cmd/serve.go b/cmd/serve.go index a0715d7..7b46630 100644 --- a/cmd/serve.go +++ b/cmd/serve.go @@ -21,6 +21,8 @@ import ( "net/http" "os" + "time" + "github.com/golang/glog" "github.com/mitchellh/go-homedir" "github.com/prometheus/client_golang/prometheus/promhttp" @@ -30,7 +32,6 @@ import ( "github.com/spf13/cast" "github.com/spf13/cobra" "github.com/spf13/viper" - "time" ) //different flags supported by serve command @@ -58,6 +59,8 @@ var ( keypairDir string genKeypair bool + + enforceClientVersions bool ) // RootCmd represents the serve command @@ -120,6 +123,8 @@ func init() { RootCmd.Flags().DurationVar(&tokenTtl, "token-ttl", 24*time.Hour, "TTL for the token") RootCmd.Flags().BoolVar(&genKeypair, "gen-keypair", false, "generate new keypair while starting server") + RootCmd.Flags().BoolVar(&enforceClientVersions, "enforce-client-versions", false, "if true enforces minimum version of k8sldapctl and kubectl") + viper.BindPFlags(RootCmd.Flags()) flag.CommandLine.Parse([]string{}) } @@ -233,10 +238,11 @@ func serve() error { webhook := auth.NewTokenWebhook(tokenVerifier) ldapTokenIssuer := &auth.LDAPTokenIssuer{ - LDAPAuthenticator: ldapClient, - TokenSigner: tokenSigner, - TTL: tokenTtl, - UsernameAttribute: usernameAttribute, + LDAPAuthenticator: ldapClient, + TokenSigner: tokenSigner, + TTL: tokenTtl, + UsernameAttribute: usernameAttribute, + EnforceClientVersions: enforceClientVersions, } // Endpoint for authenticating with token