From 8bb41cff9f47895e00d7773dfd9372a7e17fae59 Mon Sep 17 00:00:00 2001 From: "kali kaneko (leap communications)" Date: Fri, 31 Jan 2020 12:15:06 -0600 Subject: [refactor] refactor auth files --- pkg/vpn/bonafide/auth.go | 11 +++++- pkg/vpn/bonafide/auth_anon.go | 21 +++++++--- pkg/vpn/bonafide/auth_sip.go | 59 +++++++++++++--------------- pkg/vpn/bonafide/bonafide.go | 87 ++++++++++++++++++++++++++++------------- pkg/vpn/bonafide/eip_service.go | 2 +- 5 files changed, 114 insertions(+), 66 deletions(-) (limited to 'pkg/vpn/bonafide') 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) } -- cgit v1.2.3