summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorkali kaneko (leap communications) <kali@leap.se>2021-05-17 17:33:40 +0200
committerkali kaneko (leap communications) <kali@leap.se>2021-05-17 17:52:47 +0200
commit86d30f2a2edc0d9b9c54b51258a6566e37476849 (patch)
treef3f6d52eb6bd976e06a224480914c900338cba44
parent083f4095319b734f33f3e28a9f3234ff9cf6a7d7 (diff)
[feat] retry if dns lookup fails
-rw-r--r--pkg/vpn/bonafide/bonafide.go41
-rw-r--r--pkg/vpn/bonafide/eip_service.go7
-rw-r--r--pkg/vpn/openvpn.go22
3 files changed, 67 insertions, 3 deletions
diff --git a/pkg/vpn/bonafide/bonafide.go b/pkg/vpn/bonafide/bonafide.go
index fc1bc95..a9a7d85 100644
--- a/pkg/vpn/bonafide/bonafide.go
+++ b/pkg/vpn/bonafide/bonafide.go
@@ -1,4 +1,4 @@
-// Copyright (C) 2018-2020 LEAP
+// Copyright (C) 2018-2021 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
@@ -75,6 +75,17 @@ type geoLocation struct {
SortedGateways []geoGateway `json:"sortedGateways"`
}
+func getAPIAddr(provider string) string {
+ switch provider {
+ case "riseup.net":
+ return "198.252.153.107"
+ case "calyx.net":
+ return "162.247.73.194"
+ default:
+ return ""
+ }
+}
+
// New Bonafide: Initializes a Bonafide object. By default, no Credentials are passed.
func New() *Bonafide {
certs := x509.NewCertPool()
@@ -179,6 +190,17 @@ func (b *Bonafide) GetPemCertificate() ([]byte, error) {
return ioutil.ReadAll(resp.Body)
}
+func (b *Bonafide) GetPemCertificateNoDNS() ([]byte, error) {
+ req, err := http.NewRequest("POST", b.getURLNoDNS("certv3"), strings.NewReader(""))
+ resp, err := b.client.Do(req)
+ if err != nil {
+ return nil, err
+ }
+ defer resp.Body.Close()
+
+ return ioutil.ReadAll(resp.Body)
+}
+
func (b *Bonafide) getURL(object string) string {
switch object {
case "cert":
@@ -192,6 +214,23 @@ func (b *Bonafide) getURL(object string) string {
return ""
}
+func (b *Bonafide) getURLNoDNS(object string) string {
+ p := strings.ToLower(config.Provider)
+ base := "https://" + getAPIAddr(p) + "/"
+ switch object {
+ case "cert":
+ return base + certPathv1
+ case "certv3":
+ return base + certPathv3
+ case "auth":
+ return base + authPathv3
+ case "eip":
+ return base + "3/config/eip-service.json"
+ }
+ log.Println("BUG: unknown url object")
+ return ""
+}
+
func (b *Bonafide) maybeInitializeEIP() error {
if b.eip == nil {
err := b.fetchEipJSON()
diff --git a/pkg/vpn/bonafide/eip_service.go b/pkg/vpn/bonafide/eip_service.go
index d5dd751..5755b6c 100644
--- a/pkg/vpn/bonafide/eip_service.go
+++ b/pkg/vpn/bonafide/eip_service.go
@@ -83,6 +83,13 @@ func (b *Bonafide) fetchEipJSON() error {
// TODO why exactly 1 retry? Make it configurable, for tests
time.Sleep(retryFetchJSONSeconds * time.Second)
resp, err = b.client.Post(eip3API, "", nil)
+ if err != nil {
+ // TODO it might be that it's not an error, but an empty file or whatever done
+ // by DNS poisoning. Should try to parse the file.
+ uri := b.getURLNoDNS("eip")
+ log.Println("Fetching ", uri)
+ resp, err = b.client.Post(uri, "", nil)
+ }
}
defer resp.Body.Close()
diff --git a/pkg/vpn/openvpn.go b/pkg/vpn/openvpn.go
index 7cfa101..a568a32 100644
--- a/pkg/vpn/openvpn.go
+++ b/pkg/vpn/openvpn.go
@@ -1,4 +1,4 @@
-// Copyright (C) 2018-2020 LEAP
+// Copyright (C) 2018-2021 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
@@ -177,6 +177,7 @@ func (b *Bitmask) startOpenVPN() error {
}
func (b *Bitmask) getCert() (certPath string, err error) {
+ failed := false
persistentCertFile := filepath.Join(config.Path, strings.ToLower(config.Provider)+".pem")
if _, err := os.Stat(persistentCertFile); !os.IsNotExist(err) && isValidCert(persistentCertFile) {
// reuse cert. for the moment we're not writing one there, this is
@@ -191,9 +192,26 @@ func (b *Bitmask) getCert() (certPath string, err error) {
log.Println("Fetching certificate to", certPath)
cert, err := b.bonafide.GetPemCertificate()
if err != nil {
- return "", err
+ log.Println(err)
+ failed = true
}
err = ioutil.WriteFile(certPath, cert, 0600)
+ if err != nil {
+ failed = true
+ }
+ }
+ }
+ if failed || !isValidCert(certPath) {
+ cert, err := b.bonafide.GetPemCertificateNoDNS()
+ if cert != nil {
+ log.Println("Successfully did certificate bypass")
+ err = nil
+ } else {
+ err = errors.New("Cannot get vpn certificate")
+ }
+ err = ioutil.WriteFile(certPath, cert, 0600)
+ if err != nil {
+ failed = true
}
}
return certPath, err