Skip to content
Snippets Groups Projects
Unverified Commit b9cae0b7 authored by Kali Kaneko's avatar Kali Kaneko
Browse files

[feat] cache authentication token

parent a10c5ecd
No related branches found
No related tags found
No related merge requests found
......@@ -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")
......@@ -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) {
......
......@@ -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(""))
......
......@@ -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) {
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment