summaryrefslogtreecommitdiff
path: root/bitmask
diff options
context:
space:
mode:
authorRuben Pollan <meskio@sindominio.net>2018-06-08 10:26:58 +0200
committerRuben Pollan <meskio@sindominio.net>2018-06-20 12:18:03 +0200
commitfcc7514ec5f1b35068b1033d8ac4278c45043a80 (patch)
tree0ad4d5f4d650ab2a01879e4f31faedf848c39287 /bitmask
parent11094e0f58e1f28f5333a91f3c4129b56ad154e6 (diff)
[feat] pure go bitmask vpn implemenation
- Resolves: #42
Diffstat (limited to 'bitmask')
-rw-r--r--bitmask/bitmask.go (renamed from bitmask/events.go)43
-rw-r--r--bitmask/main.go161
-rw-r--r--bitmask/vpn.go92
3 files changed, 11 insertions, 285 deletions
diff --git a/bitmask/events.go b/bitmask/bitmask.go
index e97804c..f9b1cc9 100644
--- a/bitmask/events.go
+++ b/bitmask/bitmask.go
@@ -15,36 +15,15 @@
package bitmask
-import (
- "log"
- "net/http"
-)
-
-const (
- statusEvent = "VPN_STATUS_CHANGED"
-)
-
-func (b *Bitmask) eventsHandler() {
- b.send("events", "register", statusEvent)
- client := &http.Client{
- Timeout: 0,
- }
- for {
- resJSON, err := send(b.apiToken, client, "events", "poll")
- res, ok := resJSON.([]interface{})
- if err != nil || !ok || len(res) < 1 {
- continue
- }
- event, ok := res[0].(string)
- if !ok || event != statusEvent {
- continue
- }
-
- status, err := b.GetStatus()
- if err != nil {
- log.Printf("Error receiving status: %v", err)
- continue
- }
- b.statusCh <- status
- }
+type Bitmask interface {
+ GetStatusCh() <-chan string
+ Close()
+ Version() (string, error)
+ StartVPN(provider string) error
+ StopVPN() error
+ GetStatus() (string, error)
+ InstallHelpers() error
+ VPNCheck() (helpers bool, priviledge bool, err error)
+ ListGateways(provider string) ([]string, error)
+ UseGateway(name string) error
}
diff --git a/bitmask/main.go b/bitmask/main.go
deleted file mode 100644
index e0bf4a0..0000000
--- a/bitmask/main.go
+++ /dev/null
@@ -1,161 +0,0 @@
-// Copyright (C) 2018 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
-// the Free Software Foundation, either version 3 of the License, or
-// (at your option) any later version.
-//
-// This program is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-// GNU General Public License for more details.
-//
-// You should have received a copy of the GNU General Public License
-// along with this program. If not, see <http://www.gnu.org/licenses/>.
-
-package bitmask
-
-import (
- "bytes"
- "encoding/json"
- "errors"
- "io/ioutil"
- "log"
- "net/http"
- "path"
- "time"
-)
-
-const (
- timeout = time.Second * 15
- url = "http://localhost:7070/API/"
- headerAuth = "X-Bitmask-Auth"
-)
-
-// Bitmask holds the bitmask client data
-type Bitmask struct {
- client *http.Client
- apiToken string
- statusCh chan string
-}
-
-// Init the connection to bitmask
-func Init() (*Bitmask, error) {
- statusCh := make(chan string)
- client := &http.Client{
- Timeout: timeout,
- }
-
- err := waitForBitmaskd()
- if err != nil {
- return nil, err
- }
-
- apiToken, err := getToken()
- if err != nil {
- return nil, err
- }
-
- b := Bitmask{client, apiToken, statusCh}
- go b.eventsHandler()
- return &b, nil
-}
-
-// GetStatusCh returns a channel that will recieve VPN status changes
-func (b *Bitmask) GetStatusCh() chan string {
- return b.statusCh
-}
-
-// Close the connection to bitmask
-func (b *Bitmask) Close() {
- _, err := b.send("core", "stop")
- if err != nil {
- log.Printf("Got an error stopping bitmaskd: %v", err)
- }
-}
-
-// Version gets the bitmask version string
-func (b *Bitmask) Version() (string, error) {
- res, err := b.send("core", "version")
- if err != nil {
- return "", err
- }
- return res["version_core"].(string), nil
-}
-
-func waitForBitmaskd() error {
- var err error
- for i := 0; i < 30; i++ {
- resp, err := http.Post(url, "", nil)
- if err == nil {
- resp.Body.Close()
- return nil
- }
- log.Printf("Bitmask is not ready (iteration %d): %v", i, err)
- time.Sleep(1 * time.Second)
- }
- return err
-}
-
-func (b *Bitmask) send(parts ...interface{}) (map[string]interface{}, error) {
- resJSON, err := send(b.apiToken, b.client, parts...)
- if err != nil {
- return nil, err
- }
- result, ok := resJSON.(map[string]interface{})
- if !ok {
- return nil, errors.New("Not valid response")
- }
- return result, nil
-}
-
-func send(apiToken string, client *http.Client, parts ...interface{}) (interface{}, error) {
- apiSection, _ := parts[0].(string)
- reqBody, err := json.Marshal(parts[1:])
- if err != nil {
- return nil, err
- }
- req, err := http.NewRequest("POST", url+apiSection, bytes.NewReader(reqBody))
- if err != nil {
- return nil, err
- }
- req.Header.Add(headerAuth, apiToken)
-
- resp, err := client.Do(req)
- if err != nil {
- return nil, err
- }
- defer resp.Body.Close()
-
- resJSON, err := ioutil.ReadAll(resp.Body)
- if err != nil {
- return nil, err
- }
- return parseResponse(resJSON)
-}
-
-func parseResponse(resJSON []byte) (interface{}, error) {
- var response struct {
- Result interface{}
- Error string
- }
- err := json.Unmarshal(resJSON, &response)
- if response.Error != "" {
- return nil, errors.New(response.Error)
- }
- return response.Result, err
-}
-
-func getToken() (string, error) {
- var err error
- path := path.Join(ConfigPath, "authtoken")
- for i := 0; i < 30; i++ {
- b, err := ioutil.ReadFile(path)
- if err == nil {
- return string(b), nil
- }
- log.Printf("Auth token is not ready (iteration %d): %v", i, err)
- time.Sleep(1 * time.Second)
- }
- return "", err
-}
diff --git a/bitmask/vpn.go b/bitmask/vpn.go
deleted file mode 100644
index aee5e8f..0000000
--- a/bitmask/vpn.go
+++ /dev/null
@@ -1,92 +0,0 @@
-// Copyright (C) 2018 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
-// the Free Software Foundation, either version 3 of the License, or
-// (at your option) any later version.
-//
-// This program is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-// GNU General Public License for more details.
-//
-// You should have received a copy of the GNU General Public License
-// along with this program. If not, see <http://www.gnu.org/licenses/>.
-
-package bitmask
-
-import (
- "errors"
- "log"
-)
-
-// StartVPN for provider
-func (b *Bitmask) StartVPN(provider string) error {
- _, err := b.send("vpn", "start", provider)
- return err
-}
-
-// StopVPN or cancel
-func (b *Bitmask) StopVPN() error {
- _, err := b.send("vpn", "stop")
- return err
-}
-
-// GetStatus returns the VPN status
-func (b *Bitmask) GetStatus() (string, error) {
- res, err := b.send("vpn", "status")
- if err != nil {
- return "", err
- }
- return res["status"].(string), nil
-}
-
-// InstallHelpers into the system
-func (b *Bitmask) InstallHelpers() error {
- _, err := b.send("vpn", "install")
- return err
-}
-
-// VPNCheck returns if the helpers are installed and up to date and if polkit is running
-func (b *Bitmask) VPNCheck() (helpers bool, priviledge bool, err error) {
- res, err := b.send("vpn", "check", "")
- if err != nil {
- return false, false, err
- }
- installed, ok := res["installed"].(bool)
- if !ok {
- log.Printf("Unexpected value for installed on 'vpn check': %v", res)
- return false, false, errors.New("Invalid response format")
- }
- privcheck, ok := res["privcheck"].(bool)
- if !ok {
- log.Printf("Unexpected value for privcheck on 'vpn check': %v", res)
- return installed, false, errors.New("Invalid response format")
- }
- return installed, privcheck, nil
-}
-
-// ListGateways return the names of the gateways
-func (b *Bitmask) ListGateways(provider string) ([]string, error) {
- res, err := b.send("vpn", "list")
- if err != nil {
- return nil, err
- }
-
- names := []string{}
- locations, ok := res[provider].([]interface{})
- if !ok {
- return nil, errors.New("Can't read the locations for provider " + provider)
- }
- for i := range locations {
- loc := locations[i].(map[string]interface{})
- names = append(names, loc["name"].(string))
- }
- return names, nil
-}
-
-// UseGateway selects name as the default gateway
-func (b *Bitmask) UseGateway(name string) error {
- _, err := b.send("vpn", "locations", name)
- return err
-}