diff options
Diffstat (limited to 'pkg/vpn/bonafide')
-rw-r--r-- | pkg/vpn/bonafide/auth_sip.go | 25 | ||||
-rw-r--r-- | pkg/vpn/bonafide/bonafide.go | 42 | ||||
-rw-r--r-- | pkg/vpn/bonafide/bonafide_integration_test.go | 2 | ||||
-rw-r--r-- | pkg/vpn/bonafide/bonafide_sip_integration_test.go | 70 | ||||
-rw-r--r-- | pkg/vpn/bonafide/bonafide_test.go | 30 |
5 files changed, 149 insertions, 20 deletions
diff --git a/pkg/vpn/bonafide/auth_sip.go b/pkg/vpn/bonafide/auth_sip.go index d8ebedb..072812f 100644 --- a/pkg/vpn/bonafide/auth_sip.go +++ b/pkg/vpn/bonafide/auth_sip.go @@ -19,7 +19,6 @@ import ( "encoding/json" "fmt" "io/ioutil" - "log" "net/http" "strings" ) @@ -33,11 +32,11 @@ func (a *SipAuthentication) GetPemCertificate() ([]byte, error) { if cred == nil { return nil, fmt.Errorf("Need bonafide credentials for sip auth") } - credJson, err := formatCredentials(cred.User, cred.Password) + 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(credJSON) if err != nil { return nil, fmt.Errorf("Error while getting token: %s", err) } @@ -49,7 +48,11 @@ func (a *SipAuthentication) GetPemCertificate() ([]byte, error) { } func (a *SipAuthentication) getProtectedCert(token string) ([]byte, error) { - req, err := http.NewRequest("POST", certAPI, strings.NewReader("")) + certURL, err := a.bonafide.GetURL("certv3") + if err != nil { + return nil, 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) if err != nil { @@ -57,7 +60,7 @@ func (a *SipAuthentication) getProtectedCert(token string) ([]byte, error) { } defer resp.Body.Close() if resp.StatusCode != 200 { - return nil, fmt.Errorf("Cannot get cert: Error %d", resp.StatusCode) + return nil, fmt.Errorf("Error %d", resp.StatusCode) } return ioutil.ReadAll(resp.Body) } @@ -67,9 +70,13 @@ func (a *SipAuthentication) getToken(credJson string) ([]byte, error) { [ ] get token from disk? [ ] check if expired? set a goroutine to refresh it periodically? */ - resp, err := http.Post(authAPI, "text/json", strings.NewReader(credJson)) + 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)) if err != nil { - log.Fatal("Error on auth request: ", err) + return nil, fmt.Errorf("Error on auth request: %v", err) } defer resp.Body.Close() if resp.StatusCode != 200 { @@ -80,9 +87,9 @@ func (a *SipAuthentication) getToken(credJson string) ([]byte, error) { func formatCredentials(user, pass string) (string, error) { c := Credentials{User: user, Password: pass} - credJson, err := json.Marshal(c) + credJSON, err := json.Marshal(c) if err != nil { return "", err } - return string(credJson), nil + return string(credJSON), nil } diff --git a/pkg/vpn/bonafide/bonafide.go b/pkg/vpn/bonafide/bonafide.go index 16a900d..1bc6072 100644 --- a/pkg/vpn/bonafide/bonafide.go +++ b/pkg/vpn/bonafide/bonafide.go @@ -30,23 +30,29 @@ import ( ) const ( - certAPI = config.APIURL + "1/cert" - certAPI3 = config.APIURL + "3/cert" - authAPI = config.APIURL + "3/auth" secondsPerHour = 60 * 60 retryFetchJSONSeconds = 15 ) -// Bonafide exposes all the methods needed to communicate with the LEAP server. +const ( + certPathv1 = "1/cert" + certPathv3 = "3/cert" + authPathv3 = "3/auth" + + certAPI = config.APIURL + certPathv1 + certAPI3 = config.APIURL + certPathv3 + authAPI = config.APIURL + authPathv3 +) + type Bonafide struct { client httpClient eip *eipService tzOffsetHours int auth Authentication credentials *Credentials + apiURL string } -// A Gateway is each one of the remotes we can pass to OpenVPN. It contains a description of all the fields that the eip-service advertises. type Gateway struct { Host string IPAddress string @@ -106,7 +112,33 @@ func (b *Bonafide) SetCredentials(username, password string) { b.credentials = &Credentials{username, password} } +func (b *Bonafide) GetURL(object string) (string, error) { + if b.apiURL == "" { + switch object { + case "cert": + return certAPI, nil + case "certv3": + return certAPI3, nil + case "auth": + return authAPI, nil + } + } else { + switch object { + case "cert": + return b.apiURL + certPathv1, nil + case "certv3": + return b.apiURL + certPathv3, nil + case "auth": + return b.apiURL + authPathv3, nil + } + } + 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 } diff --git a/pkg/vpn/bonafide/bonafide_integration_test.go b/pkg/vpn/bonafide/bonafide_integration_test.go index bea00fe..166b2a9 100644 --- a/pkg/vpn/bonafide/bonafide_integration_test.go +++ b/pkg/vpn/bonafide/bonafide_integration_test.go @@ -32,7 +32,7 @@ var ( func TestIntegrationGetCert(t *testing.T) { b := New() - cert, err := b.GetCertPem() + cert, err := b.GetPemCertificate() if err != nil { t.Fatal("getCert returned an error: ", err) } diff --git a/pkg/vpn/bonafide/bonafide_sip_integration_test.go b/pkg/vpn/bonafide/bonafide_sip_integration_test.go new file mode 100644 index 0000000..e5a516c --- /dev/null +++ b/pkg/vpn/bonafide/bonafide_sip_integration_test.go @@ -0,0 +1,70 @@ +// +build integration +// Copyright (C) 2018 LEAP +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see <http://www.gnu.org/licenses/>. + +package bonafide + +import ( + "bytes" + "os" + "testing" +) + +type SIPCreds struct { + userOk, passOk string +} + +func getFromEnv(name, defaultVar string) string { + val, ok := os.LookupEnv(name) + if !ok { + return defaultVar + } + return val +} + +func getSIPCreds() SIPCreds { + userOk := getFromEnv("SIP_USER_OK", "test_user_ok") + passOk := getFromEnv("SIP_PASS_OK", "test_pass_ok") + creds := SIPCreds{ + userOk: userOk, + passOk: passOk, + } + return creds +} + +func TestSIPIntegrationGetCert(t *testing.T) { + creds := getSIPCreds() + + b := New() + b.auth = &SipAuthentication{b} + b.SetCredentials(creds.userOk, creds.passOk) + b.apiURL = "http://localhost:8000/" + + cert, err := b.GetPemCertificate() + if err != nil { + t.Fatal("getCert returned an error: ", err) + } + + if !bytes.Contains(cert, privateKeyHeader) { + t.Errorf("No private key present: \n%q", cert) + } + + if !bytes.Contains(cert, certHeader) { + t.Errorf("No cert present: \n%q", cert) + } + + /* TODO -- check we receive 401 for bad credentials */ + /* TODO -- check we receive 4xx for no credentials */ +} diff --git a/pkg/vpn/bonafide/bonafide_test.go b/pkg/vpn/bonafide/bonafide_test.go index 8fb7f72..0e463e0 100644 --- a/pkg/vpn/bonafide/bonafide_test.go +++ b/pkg/vpn/bonafide/bonafide_test.go @@ -27,9 +27,10 @@ import ( ) const ( - certPath = "testdata/cert" - eip1Path = "testdata/eip-service.json" - eipPath = "testdata/eip-service3.json" + certPath = "testdata/cert" + eip1Path = "testdata/eip-service.json" + eipPath = "testdata/eip-service3.json" + eipPathSip = "testdata/eip-service3-sip.json" ) type client struct { @@ -44,9 +45,18 @@ func (c client) Post(url, contentType string, body io.Reader) (resp *http.Respon }, err } -func TestGetCert(t *testing.T) { +func (c client) Do(req *http.Request) (*http.Response, error) { + f, err := os.Open(c.path) + return &http.Response{ + Body: f, + StatusCode: 200, + }, err +} + +func TestAnonGetCert(t *testing.T) { b := Bonafide{client: client{certPath}} - cert, err := b.GetCertPem() + b.auth = &AnonymousAuthentication{&b} + cert, err := b.GetPemCertificate() if err != nil { t.Fatal("getCert returned an error: ", err) } @@ -182,6 +192,8 @@ func TestObfs4Gateways(t *testing.T) { } } +/* TODO -- failClient instead? */ + type fallClient struct { path string } @@ -198,6 +210,14 @@ func (c fallClient) Post(url, contentType string, body io.Reader) (resp *http.Re }, err } +func (c fallClient) Do(req *http.Request) (*http.Response, error) { + f, err := os.Open(c.path) + return &http.Response{ + Body: f, + StatusCode: 401, + }, err +} + func TestEipServiceV1Fallback(t *testing.T) { b := Bonafide{ client: fallClient{eip1Path}, |