summaryrefslogtreecommitdiff
path: root/pkg/vpn
diff options
context:
space:
mode:
authorkali kaneko (leap communications) <kali@leap.se>2020-01-31 12:15:06 -0600
committerkali kaneko (leap communications) <kali@leap.se>2020-08-20 20:27:41 +0200
commit8bb41cff9f47895e00d7773dfd9372a7e17fae59 (patch)
tree8c7658ec44f9df7af01aaf8391c3d66ab1686b4e /pkg/vpn
parentefdeba8e994669ccd21c50d2b7491905b47a217e (diff)
[refactor] refactor auth files
Diffstat (limited to 'pkg/vpn')
-rw-r--r--pkg/vpn/bonafide/auth.go11
-rw-r--r--pkg/vpn/bonafide/auth_anon.go21
-rw-r--r--pkg/vpn/bonafide/auth_sip.go59
-rw-r--r--pkg/vpn/bonafide/bonafide.go87
-rw-r--r--pkg/vpn/bonafide/eip_service.go2
5 files changed, 114 insertions, 66 deletions
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)
}