From f5afa79d0a51b63006ee422b138f2f6aa17f7070 Mon Sep 17 00:00:00 2001 From: "kali kaneko (leap communications)" Date: Wed, 19 Aug 2020 19:46:19 +0200 Subject: [feat] passwordless-sip --- README.md | 27 ++++++++++++++------------- pkg/auth/sip2/auth.go | 6 +++--- pkg/auth/sip2/client.go | 27 ++++++++++++++++----------- pkg/config/config.go | 11 ++++++++++- pkg/web/middleware.go | 16 ++++++++++++---- 5 files changed, 55 insertions(+), 32 deletions(-) diff --git a/README.md b/README.md index 6197957..60936a6 100644 --- a/README.md +++ b/README.md @@ -10,19 +10,20 @@ You can pass generic configuration options either as a flag or an environment variable. Some specific options can be passed only as env vars (like authentication credentials). -| Flag | Env var | default | Description | -|-------------------|:--------------------:|----------------------|-------------------------------------------------------:| -| **apiPath** | `VPNWEB_API_PATH` | /etc/leap/config/vpn | _Path for the public API static files_ | -| **providerCaCrt** | `VPNWEB_PROVIDER_CA` | /etc/leap/ca/ca.crt | _Path for the provider CA certificate_ | -| **port** | `VPNWEB_PORT` | 8000 | _Port where the api server will listen_ | -| **metricsPort** | `VPNWEB_METRICS_PORT`| 8001 | _Port where the metrics server will listen_ | -| **tls** | | false | _Enable TLS on the service_ | -| **tlsCrt** | `VPNWEB_TLSCRT` | | _Path to the cert file for TLS_ | -| **tlsKey** | `VPNWEB_TLSKEY` | | _Path to the key file for TLS_ | -| **vpnCaCrt** | `VPNWEB_CACRT` | | _Path to the CA public key used for VPN certificates_ | -| **vpnCaKey** | `VPNWEB_CAKEY` | | _Path to the CA private key used for VPN certificates_ | -| **auth** | `VPNWEB_AUTH` | | _Authentication module to use (one of: sip2, anon)_ | -| **authSecret** | `VPNWEB_AUTH_SECRET` | | _Authentication secret to sign auth tokens_ | +| Flag | Env var | default | Description | +|--------------------|:------------------------:|----------------------|-------------------------------------------------------:| +| **apiPath** | `VPNWEB_API_PATH` | /etc/leap/config/vpn | _Path for the public API static files_ | +| **providerCaCrt** | `VPNWEB_PROVIDER_CA` | /etc/leap/ca/ca.crt | _Path for the provider CA certificate_ | +| **port** | `VPNWEB_PORT` | 8000 | _Port where the api server will listen_ | +| **metricsPort** | `VPNWEB_METRICS_PORT` | 8001 | _Port where the metrics server will listen_ | +| **tls** | | false | _Enable TLS on the service_ | +| **tlsCrt** | `VPNWEB_TLSCRT` | | _Path to the cert file for TLS_ | +| **tlsKey** | `VPNWEB_TLSKEY` | | _Path to the key file for TLS_ | +| **vpnCaCrt** | `VPNWEB_CACRT` | | _Path to the CA public key used for VPN certificates_ | +| **vpnCaKey** | `VPNWEB_CAKEY` | | _Path to the CA private key used for VPN certificates_ | +| **auth** | `VPNWEB_AUTH` | | _Authentication module to use (one of: sip2, anon)_ | +| **authSecret** | `VPNWEB_AUTH_SECRET` | | _Authentication secret to sign auth tokens_ | +| **passwordPolicy** | `VPNWEB_PASSWORD_POLICY` | require | _Password policy, if used (one of: require, ignore)_ | SIP2 authentication: diff --git a/pkg/auth/sip2/auth.go b/pkg/auth/sip2/auth.go index 72b94cd..0ee6cdd 100644 --- a/pkg/auth/sip2/auth.go +++ b/pkg/auth/sip2/auth.go @@ -53,7 +53,7 @@ func setupTerminatorFromEnv() { } } -func initializeSipConnection(skipConnect bool) (sipClient, error) { +func initializeSipConnection(skipConnect bool, passwordPolicy string) (sipClient, error) { log.Println("Initializing SIP2 authenticator") user := getConfigFromEnv(sipUserVar, "") @@ -64,7 +64,7 @@ func initializeSipConnection(skipConnect bool) (sipClient, error) { setupTerminatorFromEnv() - sip := newClient(host, port, loc) + sip := newClient(host, port, loc, passwordPolicy) if skipConnect { // for testing purposes @@ -81,7 +81,7 @@ func initializeSipConnection(skipConnect bool) (sipClient, error) { func GetAuthenticator(opts *config.Opts, skipConnect bool) *sipClient { - sip, err := initializeSipConnection(skipConnect) + sip, err := initializeSipConnection(skipConnect, opts.PasswordPolicy) if err != nil { log.Fatal("Cannot initialize sip:", err) } diff --git a/pkg/auth/sip2/client.go b/pkg/auth/sip2/client.go index 567d908..ed7fc73 100644 --- a/pkg/auth/sip2/client.go +++ b/pkg/auth/sip2/client.go @@ -33,15 +33,16 @@ const ( ) type sipClient struct { - host string - port string - location string - user string - pass string - conn gote.Connection - heartBeatDone chan bool - reqQueue chan request - parser *Parser + host string + port string + location string + passwordPolicy string + user string + pass string + conn gote.Connection + heartBeatDone chan bool + reqQueue chan request + parser *Parser } type request struct { @@ -54,10 +55,10 @@ type response struct { err error } -func newClient(host, port, location string) sipClient { +func newClient(host, port, location, passwordPolicy string) sipClient { reqQ := make(chan request) parser := getParser() - c := sipClient{host, port, location, "", "", nil, nil, reqQ, parser} + c := sipClient{host, port, location, passwordPolicy, "", "", nil, nil, reqQ, parser} return c } @@ -217,6 +218,10 @@ func (c *sipClient) CheckCredentials(credentials *creds.Credentials) (bool, erro return false, err } if valid, err := isValidUser(statusMsg); valid { + if c.passwordPolicy == "ignore" { + // passwordless library + return true, nil + } if valid, err := isValidPassword(statusMsg); valid { return true, nil } else { diff --git a/pkg/config/config.go b/pkg/config/config.go index 2e5eac7..ab59f63 100644 --- a/pkg/config/config.go +++ b/pkg/config/config.go @@ -21,7 +21,10 @@ import ( "os" ) -const DefaultAuthenticationModule string = "anon" +const ( + DefaultAuthenticationModule string = "anon" + DefaultPasswordPolicy string = "require" +) type Opts struct { Tls bool @@ -35,6 +38,7 @@ type Opts struct { AuthSecret string ApiPath string ProviderCaPath string + PasswordPolicy string } func checkPathExists(path string) bool { @@ -92,6 +96,7 @@ func initializeFlags(opts *Opts) { flag.StringVar(&opts.Auth, "auth", "", "Authentication module (anon, sip2)") flag.StringVar(&opts.ApiPath, "apiPath", "", "Path to the API public files") flag.StringVar(&opts.ProviderCaPath, "providerCaCrt", "", "Path to the provider CA certificate") + flag.StringVar(&opts.PasswordPolicy, "passwordPolicy", DefaultPasswordPolicy, "Password policy, if used (require|ignore)") flag.Parse() FallbackToEnv(&opts.CaCrt, "VPNWEB_CACRT", "") @@ -104,6 +109,7 @@ func initializeFlags(opts *Opts) { FallbackToEnv(&opts.AuthSecret, "VPNWEB_AUTH_SECRET", "") FallbackToEnv(&opts.ApiPath, "VPNWEB_API_PATH", "/etc/leap/config/vpn") FallbackToEnv(&opts.ProviderCaPath, "VPNWEB_PROVIDER_CA", "/etc/leap/ca/ca.crt") + FallbackToEnv(&opts.PasswordPolicy, "VPNWEB_PASSWORD_POLICY", DefaultPasswordPolicy) } func checkConfigurationOptions(opts *Opts) { @@ -136,4 +142,7 @@ func checkConfigurationOptions(opts *Opts) { } log.Println("Authentication module:", opts.Auth) + if opts.Auth != DefaultAuthenticationModule { + log.Println("Password policy:", opts.PasswordPolicy) + } } diff --git a/pkg/web/middleware.go b/pkg/web/middleware.go index 3ff8938..21e6cd4 100644 --- a/pkg/web/middleware.go +++ b/pkg/web/middleware.go @@ -52,10 +52,18 @@ func AuthMiddleware(authenticationFunc func(*creds.Credentials) (bool, error), o return } - if c.User == "" || c.Password == "" { - log.Println("Auth request did not include user or password") - http.Error(w, "Missing user and/or password", http.StatusBadRequest) - return + if opts.PasswordPolicy == "ignore" { + if c.User == "" { + log.Println("Auth request did not include user") + http.Error(w, "Missing username", http.StatusBadRequest) + return + } + } else { + if c.User == "" || c.Password == "" { + log.Println("Auth request did not include user/password") + http.Error(w, "Missing username or password", http.StatusBadRequest) + return + } } valid, err := authenticationFunc(&c) -- cgit v1.2.3