summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorkali kaneko (leap communications) <kali@leap.se>2020-08-18 18:05:45 +0200
committerkali kaneko (leap communications) <kali@leap.se>2020-08-20 20:27:46 +0200
commitb9cae0b715ce34cfb0b7f85f023c31ef8ddd54d3 (patch)
treece8ff309c26150604e96eb9c5cd41cd61ff48470
parenta10c5ecd2b4bba6814fd66f0ec1997938d95bf92 (diff)
[feat] cache authentication token
-rw-r--r--pkg/config/unix.go3
-rw-r--r--pkg/vpn/bonafide/auth_sip.go59
-rw-r--r--pkg/vpn/bonafide/bonafide.go22
-rw-r--r--pkg/vpn/openvpn.go9
4 files changed, 75 insertions, 18 deletions
diff --git a/pkg/config/unix.go b/pkg/config/unix.go
index 7425f5b..f96f6a6 100644
--- a/pkg/config/unix.go
+++ b/pkg/config/unix.go
@@ -18,7 +18,8 @@ package config
import (
"os"
+ "path"
)
// Path for the config files
-var Path = os.Getenv("HOME") + "/.config/leap"
+var Path = path.Join(os.Getenv("HOME"), ".config", "leap")
diff --git a/pkg/vpn/bonafide/auth_sip.go b/pkg/vpn/bonafide/auth_sip.go
index 1f200bb..e00252f 100644
--- a/pkg/vpn/bonafide/auth_sip.go
+++ b/pkg/vpn/bonafide/auth_sip.go
@@ -19,7 +19,13 @@ import (
"encoding/json"
"fmt"
"io/ioutil"
+ "log"
+ "os"
+ "path"
"strings"
+ "time"
+
+ "0xacab.org/leap/bitmask-vpn/pkg/config"
)
type sipAuthentication struct {
@@ -32,10 +38,11 @@ func (a *sipAuthentication) needsCredentials() bool {
}
func (a *sipAuthentication) getToken(user, password string) ([]byte, error) {
- /* TODO
- [ ] get token from disk?
- [ ] check if expired? set a goroutine to refresh it periodically?
- */
+ /* TODO refresh session token periodically */
+ if hasRecentToken() {
+ log.Println("Got cached token")
+ return readToken()
+ }
credJSON, err := formatCredentials(user, password)
if err != nil {
return nil, fmt.Errorf("Cannot encode credentials: %s", err)
@@ -48,7 +55,49 @@ func (a *sipAuthentication) getToken(user, password string) ([]byte, error) {
if resp.StatusCode != 200 {
return nil, fmt.Errorf("Cannot get token: Error %d", resp.StatusCode)
}
- return ioutil.ReadAll(resp.Body)
+ token, err := ioutil.ReadAll(resp.Body)
+ if err != nil {
+ return nil, err
+ }
+ writeToken(token)
+ return token, nil
+}
+
+func getTokenPath() string {
+ return path.Join(config.Path, config.ApplicationName+".token")
+}
+
+func writeToken(token []byte) {
+ tp := getTokenPath()
+ err := ioutil.WriteFile(tp, token, 0600)
+ if err != nil {
+ log.Println("BUG: cannot write token to", tp)
+ }
+}
+
+func readToken() ([]byte, error) {
+ f, err := os.Open(getTokenPath())
+ if err != nil {
+ log.Println("Error: cannot open token file")
+ return nil, err
+ }
+ token, err := ioutil.ReadAll(f)
+ if err != nil {
+ log.Println("Error: cannot read token")
+ return nil, err
+ }
+ return token, nil
+}
+
+func hasRecentToken() bool {
+ statinfo, err := os.Stat(getTokenPath())
+ if err != nil {
+ return false
+ }
+ lastWrote := statinfo.ModTime().Unix()
+ /* in vpnweb we set the duration of the token to 24 hours */
+ old := time.Now().Add(-time.Hour * 20).Unix()
+ return lastWrote >= old
}
func formatCredentials(user, pass string) (string, error) {
diff --git a/pkg/vpn/bonafide/bonafide.go b/pkg/vpn/bonafide/bonafide.go
index dd8c597..b81fd84 100644
--- a/pkg/vpn/bonafide/bonafide.go
+++ b/pkg/vpn/bonafide/bonafide.go
@@ -114,8 +114,18 @@ func New() *Bonafide {
return b
}
+/* NeedsCredentials signals if we have to ask user for credentials. If false, it can be that we have a cached token */
func (b *Bonafide) NeedsCredentials() bool {
- return b.auth.needsCredentials()
+ if !b.auth.needsCredentials() {
+ return false
+ }
+ /* try cached */
+ /* TODO cleanup this call - maybe expose getCachedToken instead of relying on empty creds? */
+ _, err := b.auth.getToken("", "")
+ if err != nil {
+ return true
+ }
+ return false
}
func (b *Bonafide) DoLogin(username, password string) (bool, error) {
@@ -136,9 +146,13 @@ func (b *Bonafide) GetPemCertificate() ([]byte, error) {
if b.auth == nil {
log.Fatal("ERROR: bonafide did not initialize auth")
}
- if b.auth.needsCredentials() && b.token == nil {
- log.Println("Needs token, but token is empty")
- return nil, errors.New("Needs to login, but it was not logged in. Please, restart the application and report it if it continues happening")
+ if b.auth.needsCredentials() {
+ /* try cached token */
+ token, err := b.auth.getToken("", "")
+ if err != nil {
+ return nil, errors.New("BUG: This service needs login, but we were not logged in.")
+ }
+ b.token = token
}
req, err := http.NewRequest("POST", b.getURL("certv3"), strings.NewReader(""))
diff --git a/pkg/vpn/openvpn.go b/pkg/vpn/openvpn.go
index 11bba69..6055e6a 100644
--- a/pkg/vpn/openvpn.go
+++ b/pkg/vpn/openvpn.go
@@ -51,14 +51,7 @@ func (b *Bitmask) StartVPN(provider string) error {
}
func (b *Bitmask) CanStartVPN() bool {
- if !b.bonafide.NeedsCredentials() {
- return true
- }
- _, err := b.getCert()
- if err != nil {
- return false
- }
- return true
+ return !b.bonafide.NeedsCredentials()
}
func (b *Bitmask) startTransport() (proxy string, err error) {