summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRuben Pollan <meskio@sindominio.net>2020-02-11 13:43:01 +0100
committerkali kaneko (leap communications) <kali@leap.se>2020-08-20 20:27:42 +0200
commitc56df01274a91ff730018dcd6272423a3e1593f0 (patch)
tree0650d3b8cb27caff177b7306cc7f27d987824664
parent8bb41cff9f47895e00d7773dfd9372a7e17fae59 (diff)
[feat] expose auth API in pkg/vpn
Be able to check if it needs auth and then be able to login. Use the logged in token for fetching the cert.
-rw-r--r--pkg/bitmask/bitmask.go2
-rw-r--r--pkg/vpn/bonafide/auth.go3
-rw-r--r--pkg/vpn/bonafide/auth_anon.go28
-rw-r--r--pkg/vpn/bonafide/auth_sip.go34
-rw-r--r--pkg/vpn/bonafide/bonafide.go59
-rw-r--r--pkg/vpn/bonafide/eip_service.go2
-rw-r--r--pkg/vpn/main.go8
7 files changed, 54 insertions, 82 deletions
diff --git a/pkg/bitmask/bitmask.go b/pkg/bitmask/bitmask.go
index df26fc0..927e486 100644
--- a/pkg/bitmask/bitmask.go
+++ b/pkg/bitmask/bitmask.go
@@ -28,4 +28,6 @@ type Bitmask interface {
ListGateways(provider string) ([]string, error)
UseGateway(name string) error
UseTransport(transport string) error
+ NeedsCredentials() bool
+ DoLogin(username, password string) (bool, error)
}
diff --git a/pkg/vpn/bonafide/auth.go b/pkg/vpn/bonafide/auth.go
index 62d3d8f..5a97b3f 100644
--- a/pkg/vpn/bonafide/auth.go
+++ b/pkg/vpn/bonafide/auth.go
@@ -25,6 +25,5 @@ type credentials struct {
type authentication interface {
needsCredentials() bool
- getToken(cred *credentials) ([]byte, error)
- getPemCertificate(cred *credentials) ([]byte, error)
+ getToken(user, password string) ([]byte, error)
}
diff --git a/pkg/vpn/bonafide/auth_anon.go b/pkg/vpn/bonafide/auth_anon.go
index 3a666a8..8a55e3a 100644
--- a/pkg/vpn/bonafide/auth_anon.go
+++ b/pkg/vpn/bonafide/auth_anon.go
@@ -17,40 +17,16 @@ package bonafide
import (
"errors"
- "fmt"
- "io/ioutil"
)
type anonymousAuthentication struct {
- client httpClient
- authURI string
- certURI string
+ client httpClient
}
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.client.Post(certAPI3, "", nil)
- if err != nil {
- return nil, err
- }
- defer resp.Body.Close()
- }
- if resp.StatusCode != 200 {
- return nil, fmt.Errorf("Get vpn cert has failed with status: %s", resp.Status)
- }
-
- return ioutil.ReadAll(resp.Body)
-}
-
-func (a *anonymousAuthentication) getToken(cred *credentials) ([]byte, error) {
+func (a *anonymousAuthentication) getToken(user, password string) ([]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 b7ab0c8..1bfef52 100644
--- a/pkg/vpn/bonafide/auth_sip.go
+++ b/pkg/vpn/bonafide/auth_sip.go
@@ -26,34 +26,18 @@ import (
type sipAuthentication struct {
client httpClient
authURI string
- certURI string
}
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")
- }
- token, err := a.getToken(cred)
- if err != nil {
- return nil, fmt.Errorf("Error while getting token: %s", err)
- }
- 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) getToken(cred *credentials) ([]byte, error) {
+func (a *sipAuthentication) getToken(user, password string) ([]byte, error) {
/* TODO
[ ] get token from disk?
[ ] check if expired? set a goroutine to refresh it periodically?
*/
- credJSON, err := formatCredentials(cred.User, cred.Password)
+ credJSON, err := formatCredentials(user, password)
if err != nil {
return nil, fmt.Errorf("Cannot encode credentials: %s", err)
}
@@ -68,20 +52,6 @@ func (a *sipAuthentication) getToken(cred *credentials) ([]byte, error) {
return ioutil.ReadAll(resp.Body)
}
-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 while getting token: %s", err)
- }
- defer resp.Body.Close()
- if resp.StatusCode != 200 {
- 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}
credJSON, err := json.Marshal(c)
diff --git a/pkg/vpn/bonafide/bonafide.go b/pkg/vpn/bonafide/bonafide.go
index 1b48276..4561eb1 100644
--- a/pkg/vpn/bonafide/bonafide.go
+++ b/pkg/vpn/bonafide/bonafide.go
@@ -25,6 +25,7 @@ import (
"io/ioutil"
"log"
"net/http"
+ "strings"
"time"
"0xacab.org/leap/bitmask-vpn/pkg/config"
@@ -50,7 +51,7 @@ type Bonafide struct {
eip *eipService
tzOffsetHours int
auth authentication
- credentials credentials
+ token []byte
apiURL string
}
@@ -101,28 +102,29 @@ func New() *Bonafide {
switch auth := config.Auth; auth {
case "sip":
log.Println("Client expects sip auth")
- b.auth = &sipAuthentication{client, b.getURL("auth"), b.getURL("certv3")}
+ b.auth = &sipAuthentication{client, b.getURL("auth")}
case "anon":
log.Println("Client expects anon auth")
- b.auth = &anonymousAuthentication{client, "", b.getURL("certv3")}
+ b.auth = &anonymousAuthentication{client}
default:
log.Println("Client expects invalid auth", auth)
- b.auth = &anonymousAuthentication{client, "", b.getURL("certv3")}
+ b.auth = &anonymousAuthentication{client}
}
return b
}
+func (b *Bonafide) NeedsCredentials() bool {
+ return b.auth.needsCredentials()
+}
+
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)
+ var err error
+ b.token, err = b.auth.getToken(username, password)
if err != nil {
return false, err
}
@@ -130,24 +132,39 @@ func (b *Bonafide) DoLogin(username, password string) (bool, error) {
return true, nil
}
-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()
+ if b.auth.needsCredentials() && b.token == nil {
+ log.Println("BUG: expected token to be set, but is not there")
+ return nil, errors.New("Needs to login, but it was not logged in. Please, restart the application and report it if it continues happening")
+ }
+
+ req, err := http.NewRequest("POST", b.getURL("certv3"), strings.NewReader(""))
+ if err != nil {
+ return nil, err
+ }
+ if b.token != nil {
+ req.Header.Add("Authorization", fmt.Sprintf("Bearer %s", b.token))
+ }
+ resp, err := b.client.Do(req)
+ if err != nil {
+ return nil, err
+ }
+ defer resp.Body.Close()
+ if resp.StatusCode == 404 {
+ resp, err = b.client.Post(b.getURL("cert"), "", nil)
+ if err != nil {
+ return nil, err
+ }
+ defer resp.Body.Close()
+ }
+ if resp.StatusCode != 200 {
+ return nil, fmt.Errorf("Get vpn cert has failed with status: %s", resp.Status)
}
- cert, err := b.auth.getPemCertificate(&b.credentials)
- return cert, err
+ return ioutil.ReadAll(resp.Body)
}
func (b *Bonafide) getURL(object string) string {
diff --git a/pkg/vpn/bonafide/eip_service.go b/pkg/vpn/bonafide/eip_service.go
index 618eda4..ff73da9 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.client, b.getURL("auth"), b.getURL("certv3")}
+ b.auth = &sipAuthentication{b.client, b.getURL("auth")}
default:
log.Printf("BUG: unknown authentication method %s", auth)
}
diff --git a/pkg/vpn/main.go b/pkg/vpn/main.go
index 4bf4395..de8e61f 100644
--- a/pkg/vpn/main.go
+++ b/pkg/vpn/main.go
@@ -92,3 +92,11 @@ func (b *Bitmask) Close() {
func (b *Bitmask) Version() (string, error) {
return "", nil
}
+
+func (b *Bitmask) NeedsCredentials() bool {
+ return b.bonafide.NeedsCredentials()
+}
+
+func (b *Bitmask) DoLogin(username, password string) (bool, error) {
+ return b.bonafide.DoLogin(username, password)
+}