diff options
author | kali kaneko (leap communications) <kali@leap.se> | 2020-01-31 12:15:06 -0600 |
---|---|---|
committer | kali kaneko (leap communications) <kali@leap.se> | 2020-08-20 20:27:41 +0200 |
commit | 8bb41cff9f47895e00d7773dfd9372a7e17fae59 (patch) | |
tree | 8c7658ec44f9df7af01aaf8391c3d66ab1686b4e | |
parent | efdeba8e994669ccd21c50d2b7491905b47a217e (diff) |
[refactor] refactor auth files
-rw-r--r-- | branding/config/vendor.conf | 3 | ||||
-rw-r--r-- | branding/scripts/provider.py | 2 | ||||
-rw-r--r-- | branding/templates/bitmaskvpn/config.go | 1 | ||||
-rw-r--r-- | pkg/config/config.go | 1 | ||||
-rw-r--r-- | pkg/vpn/bonafide/auth.go | 11 | ||||
-rw-r--r-- | pkg/vpn/bonafide/auth_anon.go | 21 | ||||
-rw-r--r-- | pkg/vpn/bonafide/auth_sip.go | 59 | ||||
-rw-r--r-- | pkg/vpn/bonafide/bonafide.go | 87 | ||||
-rw-r--r-- | pkg/vpn/bonafide/eip_service.go | 2 |
9 files changed, 120 insertions, 67 deletions
diff --git a/branding/config/vendor.conf b/branding/config/vendor.conf index 0df2503..a1aca33 100644 --- a/branding/config/vendor.conf +++ b/branding/config/vendor.conf @@ -10,6 +10,7 @@ applicationName = RiseupVPN binaryName = riseup-vpn providerURL = riseup.net +auth = anon apiURL = https://api.black.riseup.net/ caURL = https://black.riseup.net/ca.crt @@ -30,6 +31,7 @@ applicationName = CalyxVPN binaryName = calyx-vpn providerURL = https://calyx.net +auth = anon apiURL = https://api.calyx.net:4430/ caURL = https://calyx.net/ca.crt @@ -47,6 +49,7 @@ donateURL = http://example.org name = demo applicationName = DemoVPN binaryName = demo-vpn +auth = anon providerURL = pt.demo.bitmask.net apiURL = https://pt.demo.bitmask.net:8000/ diff --git a/branding/scripts/provider.py b/branding/scripts/provider.py index b1beab9..a88179b 100644 --- a/branding/scripts/provider.py +++ b/branding/scripts/provider.py @@ -18,7 +18,7 @@ def getProviderData(provider, config): c = config[provider] d = dict() - keys = ('name', 'applicationName', 'binaryName', + keys = ('name', 'applicationName', 'binaryName', 'auth', 'providerURL', 'tosURL', 'helpURL', 'askForDonations', 'donateURL', 'apiURL', 'geolocationAPI', 'caCertString') diff --git a/branding/templates/bitmaskvpn/config.go b/branding/templates/bitmaskvpn/config.go index a4dc28c..e3d70cf 100644 --- a/branding/templates/bitmaskvpn/config.go +++ b/branding/templates/bitmaskvpn/config.go @@ -10,6 +10,7 @@ const ( Provider = "$providerURL" ApplicationName = "$applicationName" BinaryName = "$binaryName" + Auth = "$auth" DonateURL = "$donateURL" AskForDonations = "$askForDonations" HelpURL = "$helpURL" diff --git a/pkg/config/config.go b/pkg/config/config.go index ad159a1..80f5df4 100644 --- a/pkg/config/config.go +++ b/pkg/config/config.go @@ -10,6 +10,7 @@ const ( Provider = "riseup.net" ApplicationName = "RiseupVPN" BinaryName = "riseup-vpn" + Auth = "anon" DonateURL = "https://riseup.net/vpn/donate" AskForDonations = "true" HelpURL = "https://riseup.net/support" diff --git a/pkg/vpn/bonafide/auth.go b/pkg/vpn/bonafide/auth.go index b6b3eec..62d3d8f 100644 --- a/pkg/vpn/bonafide/auth.go +++ b/pkg/vpn/bonafide/auth.go @@ -15,7 +15,16 @@ package bonafide -type Credentials struct { +type credentials struct { User string Password string } + +// The authentication interface allows to get a Certificate in Pem format. +// We implement Anonymous Authentication (Riseup et al), and Sip (Libraries). + +type authentication interface { + needsCredentials() bool + getToken(cred *credentials) ([]byte, error) + getPemCertificate(cred *credentials) ([]byte, error) +} diff --git a/pkg/vpn/bonafide/auth_anon.go b/pkg/vpn/bonafide/auth_anon.go index 61916e6..3a666a8 100644 --- a/pkg/vpn/bonafide/auth_anon.go +++ b/pkg/vpn/bonafide/auth_anon.go @@ -16,22 +16,29 @@ package bonafide import ( + "errors" "fmt" "io/ioutil" ) -type AnonymousAuthentication struct { - bonafide *Bonafide +type anonymousAuthentication struct { + client httpClient + authURI string + certURI string } -func (a *AnonymousAuthentication) GetPemCertificate() ([]byte, error) { - resp, err := a.bonafide.client.Post(certAPI, "", nil) +func (a *anonymousAuthentication) needsCredentials() bool { + return true +} + +func (a *anonymousAuthentication) getPemCertificate(cred *credentials) ([]byte, error) { + resp, err := a.client.Post(certAPI, "", nil) if err != nil { return nil, err } defer resp.Body.Close() if resp.StatusCode == 404 { - resp, err = a.bonafide.client.Post(certAPI3, "", nil) + resp, err = a.client.Post(certAPI3, "", nil) if err != nil { return nil, err } @@ -43,3 +50,7 @@ func (a *AnonymousAuthentication) GetPemCertificate() ([]byte, error) { return ioutil.ReadAll(resp.Body) } + +func (a *anonymousAuthentication) getToken(cred *credentials) ([]byte, error) { + return []byte(""), errors.New("anon authentication should not call getToken") +} diff --git a/pkg/vpn/bonafide/auth_sip.go b/pkg/vpn/bonafide/auth_sip.go index 072812f..b7ab0c8 100644 --- a/pkg/vpn/bonafide/auth_sip.go +++ b/pkg/vpn/bonafide/auth_sip.go @@ -23,70 +23,67 @@ import ( "strings" ) -type SipAuthentication struct { - bonafide *Bonafide +type sipAuthentication struct { + client httpClient + authURI string + certURI string } -func (a *SipAuthentication) GetPemCertificate() ([]byte, error) { - cred := a.bonafide.credentials +func (a *sipAuthentication) needsCredentials() bool { + return true +} + +func (a *sipAuthentication) getPemCertificate(cred *credentials) ([]byte, error) { if cred == nil { return nil, fmt.Errorf("Need bonafide credentials for sip auth") } - credJSON, err := formatCredentials(cred.User, cred.Password) - if err != nil { - return nil, fmt.Errorf("Cannot encode credentials: %s", err) - } - token, err := a.getToken(credJSON) + token, err := a.getToken(cred) if err != nil { return nil, fmt.Errorf("Error while getting token: %s", err) } - cert, err := a.getProtectedCert(string(token)) + cert, err := a.getProtectedCert(a.certURI, string(token)) if err != nil { return nil, fmt.Errorf("Error while getting cert: %s", err) } return cert, nil } -func (a *SipAuthentication) getProtectedCert(token string) ([]byte, error) { - certURL, err := a.bonafide.GetURL("certv3") +func (a *sipAuthentication) getToken(cred *credentials) ([]byte, error) { + /* TODO + [ ] get token from disk? + [ ] check if expired? set a goroutine to refresh it periodically? + */ + credJSON, err := formatCredentials(cred.User, cred.Password) if err != nil { - return nil, err + return nil, fmt.Errorf("Cannot encode credentials: %s", err) } - req, err := http.NewRequest("POST", certURL, strings.NewReader("")) - req.Header.Add("Authorization", fmt.Sprintf("Bearer %s", token)) - resp, err := a.bonafide.client.Do(req) + resp, err := http.Post(a.authURI, "text/json", strings.NewReader(credJSON)) if err != nil { - return nil, fmt.Errorf("Error while getting token: %s", err) + return nil, fmt.Errorf("Error on auth request: %v", err) } defer resp.Body.Close() if resp.StatusCode != 200 { - return nil, fmt.Errorf("Error %d", resp.StatusCode) + return nil, fmt.Errorf("Cannot get token: Error %d", resp.StatusCode) } return ioutil.ReadAll(resp.Body) } -func (a *SipAuthentication) getToken(credJson string) ([]byte, error) { - /* TODO - [ ] get token from disk? - [ ] check if expired? set a goroutine to refresh it periodically? - */ - authURL, err := a.bonafide.GetURL("auth") - if err != nil { - return nil, fmt.Errorf("Error getting auth url") - } - resp, err := http.Post(authURL, "text/json", strings.NewReader(credJson)) +func (a *sipAuthentication) getProtectedCert(uri, token string) ([]byte, error) { + req, err := http.NewRequest("POST", uri, strings.NewReader("")) + req.Header.Add("Authorization", fmt.Sprintf("Bearer %s", token)) + resp, err := a.client.Do(req) if err != nil { - return nil, fmt.Errorf("Error on auth request: %v", err) + return nil, fmt.Errorf("Error while getting token: %s", err) } defer resp.Body.Close() if resp.StatusCode != 200 { - return nil, fmt.Errorf("Cannot get token: Error %d", resp.StatusCode) + return nil, fmt.Errorf("Error %d", resp.StatusCode) } return ioutil.ReadAll(resp.Body) } func formatCredentials(user, pass string) (string, error) { - c := Credentials{User: user, Password: pass} + c := credentials{User: user, Password: pass} credJSON, err := json.Marshal(c) if err != nil { return "", err diff --git a/pkg/vpn/bonafide/bonafide.go b/pkg/vpn/bonafide/bonafide.go index 1bc6072..1b48276 100644 --- a/pkg/vpn/bonafide/bonafide.go +++ b/pkg/vpn/bonafide/bonafide.go @@ -19,6 +19,7 @@ import ( "crypto/tls" "crypto/x509" "encoding/json" + "errors" "fmt" "io" "io/ioutil" @@ -48,8 +49,8 @@ type Bonafide struct { client httpClient eip *eipService tzOffsetHours int - auth Authentication - credentials *Credentials + auth authentication + credentials credentials apiURL string } @@ -69,12 +70,6 @@ type httpClient interface { Do(req *http.Request) (*http.Response, error) } -// The Authentication interface allows to get a Certificate in Pem format. -// We implement Anonymous Authentication (Riseup et al), and Sip (Libraries). -type Authentication interface { - GetPemCertificate() ([]byte, error) -} - type geoLocation struct { IPAddress string `json:"ip"` Country string `json:"cc"` @@ -103,44 +98,80 @@ func New() *Bonafide { eip: nil, tzOffsetHours: tzOffsetHours, } - auth := AnonymousAuthentication{b} - b.auth = &auth + switch auth := config.Auth; auth { + case "sip": + log.Println("Client expects sip auth") + b.auth = &sipAuthentication{client, b.getURL("auth"), b.getURL("certv3")} + case "anon": + log.Println("Client expects anon auth") + b.auth = &anonymousAuthentication{client, "", b.getURL("certv3")} + default: + log.Println("Client expects invalid auth", auth) + b.auth = &anonymousAuthentication{client, "", b.getURL("certv3")} + } + return b } -func (b *Bonafide) SetCredentials(username, password string) { - b.credentials = &Credentials{username, password} +func (b *Bonafide) DoLogin(username, password string) (bool, error) { + if !b.auth.needsCredentials() { + return false, errors.New("Auth method does not need login") + } + + cred := credentials{username, password} + b.credentials = cred + + /* TODO keep this in memory */ + _, err := b.auth.getToken(&cred) + if err != nil { + return false, err + } + + return true, nil } -func (b *Bonafide) GetURL(object string) (string, error) { +func (b *Bonafide) checkCredentialsAreSet() bool { + if b.credentials.User == "" || b.credentials.Password == "" { + log.Println("BUG: expected credentials to be set") + return false + } + return true +} + +func (b *Bonafide) GetPemCertificate() ([]byte, error) { + if b.auth == nil { + log.Fatal("ERROR: bonafide did not initialize auth") + } + if b.auth.needsCredentials() { + b.checkCredentialsAreSet() + } + + cert, err := b.auth.getPemCertificate(&b.credentials) + return cert, err +} + +func (b *Bonafide) getURL(object string) string { if b.apiURL == "" { switch object { case "cert": - return certAPI, nil + return certAPI case "certv3": - return certAPI3, nil + return certAPI3 case "auth": - return authAPI, nil + return authAPI } } else { switch object { case "cert": - return b.apiURL + certPathv1, nil + return b.apiURL + certPathv1 case "certv3": - return b.apiURL + certPathv3, nil + return b.apiURL + certPathv3 case "auth": - return b.apiURL + authPathv3, nil + return b.apiURL + authPathv3 } } - return "", fmt.Errorf("ERROR: unknown object for api url") -} - -func (b *Bonafide) GetPemCertificate() ([]byte, error) { - if b.auth == nil { - log.Fatal("ERROR: bonafide did not initialize auth") - } - cert, err := b.auth.GetPemCertificate() - return cert, err + log.Println("BUG: unknown url object") + return "" } func (b *Bonafide) GetGateways(transport string) ([]Gateway, error) { diff --git a/pkg/vpn/bonafide/eip_service.go b/pkg/vpn/bonafide/eip_service.go index 148b052..618eda4 100644 --- a/pkg/vpn/bonafide/eip_service.go +++ b/pkg/vpn/bonafide/eip_service.go @@ -73,7 +73,7 @@ func (b *Bonafide) setupAuthentication(i interface{}) { case "anon": // Do nothing, we're set on initialization. case "sip": - b.auth = &SipAuthentication{b} + b.auth = &sipAuthentication{b.client, b.getURL("auth"), b.getURL("certv3")} default: log.Printf("BUG: unknown authentication method %s", auth) } |