Skip to content
Snippets Groups Projects

Compare revisions

Changes are shown as if the source revision was being merged into the target revision. Learn more about comparing revisions.

Source

Select target project
No results found

Target

Select target project
  • m1ghtfr3e/bitmask-vpn
  • leap/bitmask-vpn
  • meskio/bitmask-vpn
  • kali/bitmask-vpn
  • nsheep/bitmask-vpn
  • nilesh/bitmask-vpn
  • micah/bitmask-vpn
  • kwadronaut/bitmask-vpn
  • th/bitmask-vpn
  • wxl/bitmask-vpn
  • Nowa-Ammerlaan/bitmask-vpn
  • elijah/bitmask-vpn
  • happysalada/bitmask-vpn
  • JUZZZEE/bitmask-vpn
  • jkito/bitmask-vpn
  • panetone/bitmask-vpn
  • hsilva/bitmask-vpn
  • S0b0tkaZ11gy/bitmask-vpn
  • polster/bitmask-vpn-pahoeohe
  • Kulibin/bitmask-vpn
  • TheMimoGz/bitmask-vpn
  • fifi/bitmask-vpn
  • fly/bitmask-vpn
  • VlKozlove/bitmask-vpn
  • DonMephedrone/bitmask-vpn
  • Arti/bitmask-vpn
  • annxxxxx/bitmask-vpn
  • Arti/arti-bitmask-vpn-fork
  • peanut2/bitmask-vpn
29 results
Show changes
Showing
with 374 additions and 199 deletions
package bitmask
package backend
import (
"io/ioutil"
"log"
"math/rand"
"os"
"path/filepath"
"runtime"
"strings"
"time"
"github.com/rs/zerolog/log"
)
/* functions for local authentication of control endpoints */
const bitmaskToken = "bitmask-token"
func GenerateAuthToken() {
func generateAuthToken() {
if runtime.GOOS != "linux" {
log.Println("Authentication token only implemented in linux at the moment.")
log.Warn().Msg("Authentication token only implemented in linux at the moment.")
return
}
t := getRandomString()
tokenPath := filepath.Join(os.TempDir(), bitmaskToken)
err := ioutil.WriteFile(tokenPath, []byte(t), os.FileMode(int(0600)))
if err != nil {
log.Println("Could not write authentication token.")
log.Fatal().
Err(err).
Str("file", tokenPath).
Msg("Could not write authentication token")
}
}
func ReadAuthToken() string {
func readAuthToken() string {
if runtime.GOOS != "linux" {
log.Println("Authentication token only implemented in linux at the moment.")
log.Warn().Msg("Authentication token only implemented in linux at the moment.")
return ""
}
tokenPath := filepath.Join(os.TempDir(), bitmaskToken)
token, err := ioutil.ReadFile(tokenPath)
token, err := os.ReadFile(tokenPath)
if err != nil {
log.Println("Error reading token:", err)
log.Fatal().
Err(err).
Str("file", tokenPath).
Msg("Could not read auth token from disk")
}
return string(token)
}
......
package backend
import (
"fmt"
"sync"
"unsafe"
"github.com/rs/zerolog/log"
)
/* ATCHUNG! what follow are not silly comments. Well, *this one* is, but
......@@ -61,6 +62,8 @@ func trigger(event string) {
if cb != nil {
C._do_callback(cb)
} else {
fmt.Println("ERROR: this event does not have subscribers:", event)
log.Warn().
Str("event", event).
Msg("This event does not have subscribers")
}
}
......@@ -2,6 +2,8 @@ package backend
import (
"time"
"github.com/rs/zerolog/log"
)
// runDonationReminder checks every six hours if we need to show the reminder,
......@@ -23,8 +25,11 @@ func needsDonationReminder() bool {
return ctx.cfg.NeedsDonationReminder()
}
/* to be called from the gui, the visibility toggle will be updated on the next
status change */
/*
to be called from the gui, the visibility toggle will be updated on the next
status change
*/
func donateSeen() {
statusMutex.Lock()
defer statusMutex.Unlock()
......@@ -35,7 +40,12 @@ func donateAccepted() {
statusMutex.Lock()
defer statusMutex.Unlock()
ctx.DonateDialog = false
ctx.cfg.SetDonated()
err := ctx.cfg.SetDonated()
if err != nil {
log.Warn().
Err(err).
Msg("Could not set donated state")
}
go trigger(OnStatusChanged)
}
......@@ -43,6 +53,11 @@ func showDonate() {
statusMutex.Lock()
defer statusMutex.Unlock()
ctx.DonateDialog = true
ctx.cfg.SetLastReminded()
err := ctx.cfg.SetLastReminded()
if err != nil {
log.Warn().
Err(err).
Msg("Could not set donation lastReminded state")
}
go trigger(OnStatusChanged)
}
......@@ -13,9 +13,10 @@ func (c connectionCtx) delayCheckForGateways() {
if cnt > 60*2 {
break
}
cnt += 1
time.Sleep(time.Second * 5)
transport := c.bm.GetTransport()
locs := c.bm.ListLocationFullness(transport)
locs := c.bm.GetLocationQualityMap(transport)
if len(locs) != 0 {
c.Locations = locs
updateStatusForGateways()
......
package backend
import (
"log"
"errors"
"os"
"time"
"github.com/rs/zerolog/log"
"0xacab.org/leap/bitmask-vpn/pkg/bitmask"
bitmaskAutostart "0xacab.org/leap/bitmask-vpn/pkg/bitmask/autostart"
"0xacab.org/leap/bitmask-vpn/pkg/config"
"0xacab.org/leap/bitmask-vpn/pkg/config/version"
"0xacab.org/leap/bitmask-vpn/pkg/pid"
......@@ -29,7 +33,7 @@ func initializeContext(opts *InitOpts) {
DonateURL: opts.ProviderOptions.DonateURL,
AskForDonations: opts.ProviderOptions.AskForDonations,
DonateDialog: false,
Version: version.VERSION,
Version: version.Version(),
Status: st,
IsReady: false,
}
......@@ -52,26 +56,37 @@ func checkErrors(errCh chan string) {
func initializeBitmask(errCh chan string, opts *InitOpts) {
if ctx == nil {
log.Println("BUG: cannot initialize bitmask, ctx is nil!")
os.Exit(1)
log.Fatal().
Msg("Could not initialize bitmask, ctx is nil!")
}
bitmask.InitializeLogger()
config.ConfigureLogger()
ctx.cfg = config.ParseConfig()
setConfigOpts(opts, ctx.cfg)
ctx.UseUDP = ctx.cfg.UDP
err := pid.AcquirePID()
if err != nil {
log.Println("Error acquiring PID:", err)
log.Fatal(err.Error())
if err != nil && errors.Is(err, pid.AlreadyRunningErr) {
log.Error().
Err(err).
Msg("Could not acquire PID")
errCh <- "alreadyrunning"
// would be better to quit the app from cpp land
// using go trigger(OnInitPidError)
time.Sleep(10 * time.Second)
os.Exit(1)
}
b, err := bitmask.InitializeBitmask(ctx.cfg)
if err != nil {
log.Println("ERROR: cannot initialize bitmask")
config.CloseLogger()
log.Error().
Err(err).
Msg("Could not initialize bitmask")
errCh <- err.Error()
return
}
ctx.bm = b
// right now we just get autostart from an init flag,
// but we want to be able to persist that option from the preferences
// pane
......@@ -80,19 +95,20 @@ func initializeBitmask(errCh chan string, opts *InitOpts) {
helpers, privilege, err := b.VPNCheck()
if err != nil {
log.Println("ERROR: vpn check")
log.Error().
Err(err).
Msg("Could not check VPN (b.VPNCheck)")
errCh <- err.Error()
}
if helpers == false {
log.Println("ERROR: no helpers")
if !helpers {
log.Error().Msg("Could not find helpers")
errCh <- "nohelpers"
}
if privilege == false {
log.Println("ERROR: no polkit")
if !privilege {
log.Error().Msg("Could not find polkit")
errCh <- "nopolkit"
}
ctx.bm = b
ctx.IsReady = true
}
......@@ -101,7 +117,9 @@ func setConfigOpts(opts *InitOpts, conf *config.Config) {
conf.SkipLaunch = opts.SkipLaunch
if opts.StartVPN != "" {
if opts.StartVPN != "on" && opts.StartVPN != "off" {
log.Println("-start-vpn should be 'on' or 'off'")
log.Warn().
Str("startVPN", opts.StartVPN).
Msg("setConfigOpts: -start-vpn should be 'on' or 'off'")
} else {
conf.StartVPN = opts.StartVPN == "on"
}
......@@ -117,15 +135,19 @@ func setConfigOpts(opts *InitOpts, conf *config.Config) {
}
}
func initializeAutostart(conf *config.Config) bitmask.Autostart {
autostart := bitmask.NewAutostart(config.ApplicationName, "")
func initializeAutostart(conf *config.Config) bitmaskAutostart.Autostart {
autostart := bitmaskAutostart.NewAutostart(config.ApplicationName, "")
if conf.SkipLaunch || conf.DisableAutostart {
autostart.Disable()
autostart = &bitmask.DummyAutostart{}
// Disable removes ~.config/autostart/RiseupVPN.desktop: (on Linux)
// it's possible that the file does not exist, so no need to check err
_ = autostart.Disable()
autostart = &bitmaskAutostart.DummyAutostart{}
} else {
err := autostart.Enable()
if err != nil {
log.Printf("Error enabling autostart: %v", err)
log.Warn().
Err(err).
Msg("Could not enable autostart during initialization")
}
}
return autostart
......
package backend
import (
"log"
"net/http"
"github.com/rs/zerolog/log"
)
/* mock http server: easy way to mocking vpn behavior on ui interaction. This
......@@ -10,24 +11,29 @@ import (
* layer */
func enableMockBackend() {
log.Println("[+] You should not use this in production!")
log.Warn().Msg("[+] You should not use this in production!")
http.HandleFunc("/on", mockUIOn)
http.HandleFunc("/off", mockUIOff)
http.HandleFunc("/failed", mockUIFailed)
http.ListenAndServe(":8080", nil)
err := http.ListenAndServe(":8080", nil)
if err != nil {
log.Warn().
Err(err).
Msg("Could not run mock backend")
}
}
func mockUIOn(w http.ResponseWriter, r *http.Request) {
log.Println("changing status: on")
log.Info().Msg("changing status: on")
setStatus(on)
}
func mockUIOff(w http.ResponseWriter, r *http.Request) {
log.Println("changing status: off")
log.Info().Msg("changing status: off")
setStatus(off)
}
func mockUIFailed(w http.ResponseWriter, r *http.Request) {
log.Println("changing status: failed")
log.Info().Msg("changing status: failed")
setStatus(failed)
}
......@@ -3,10 +3,12 @@ package backend
import (
"bytes"
"encoding/json"
"log"
"sync"
"github.com/rs/zerolog/log"
"0xacab.org/leap/bitmask-vpn/pkg/bitmask"
bitmaskAutostart "0xacab.org/leap/bitmask-vpn/pkg/bitmask/autostart"
"0xacab.org/leap/bitmask-vpn/pkg/config"
"0xacab.org/leap/bitmask-vpn/pkg/snowflake"
)
......@@ -33,44 +35,46 @@ var updateMutex sync.Mutex
// them.
type connectionCtx struct {
AppName string `json:"appName"`
Provider string `json:"provider"`
TosURL string `json:"tosURL"`
HelpURL string `json:"helpURL"`
AskForDonations bool `json:"askForDonations"`
DonateDialog bool `json:"donateDialog"`
DonateURL string `json:"donateURL"`
LoginDialog bool `json:"loginDialog"`
LoginOk bool `json:"loginOk"`
Version string `json:"version"`
Errors string `json:"errors"`
Status status `json:"status"`
Locations map[string]float64 `json:"locations"`
LocationLabels map[string][]string `json:"locationLabels"`
CurrentGateway string `json:"currentGateway"`
CurrentLocation string `json:"currentLocation"`
CurrentCountry string `json:"currentCountry"`
BestLocation string `json:"bestLocation"`
Transport string `json:"transport"`
UseUDP bool `json:"udp"`
OffersUDP bool `json:"offersUdp"`
ManualLocation bool `json:"manualLocation"`
IsReady bool `json:"isReady"`
CanUpgrade bool `json:"canUpgrade"`
Motd string `json:"motd"`
HasTor bool `json:"hasTor"`
UseSnowflake bool `json:"snowflake"`
bm bitmask.Bitmask
autostart bitmask.Autostart
cfg *config.Config
AppName string `json:"appName"`
Provider string `json:"provider"`
TosURL string `json:"tosURL"`
HelpURL string `json:"helpURL"`
AskForDonations bool `json:"askForDonations"`
DonateDialog bool `json:"donateDialog"`
DonateURL string `json:"donateURL"`
LoginDialog bool `json:"loginDialog"`
LoginOk bool `json:"loginOk"`
Version string `json:"version"`
Errors string `json:"errors"`
Status status `json:"status"`
Locations map[string]float64 `json:"locations"`
LocationLabels map[string][]string `json:"locationLabels"`
CurrentGateway string `json:"currentGateway"`
CurrentLocation string `json:"currentLocation"`
CurrentCountry string `json:"currentCountry"`
BestLocation string `json:"bestLocation"`
Transport string `json:"transport"`
UseUDP bool `json:"udp"`
OffersUDP bool `json:"offersUdp"`
ManualLocation bool `json:"manualLocation"`
IsReady bool `json:"isReady"`
CanUpgrade bool `json:"canUpgrade"`
Motd string `json:"motd"`
HasTor bool `json:"hasTor"`
UseSnowflake bool `json:"snowflake"`
SnowflakeProgress int `json:"snowflakeProgress"`
SnowflakeTag string `json:"snowflakeTag"`
bm bitmask.Bitmask
autostart bitmaskAutostart.Autostart
cfg *config.Config
}
func (c *connectionCtx) toJson() ([]byte, error) {
statusMutex.Lock()
if c.bm != nil {
transport := c.bm.GetTransport()
c.Locations = c.bm.ListLocationFullness(transport)
c.LocationLabels = c.bm.ListLocationLabels(transport)
c.Locations = c.bm.GetLocationQualityMap(transport)
c.LocationLabels = c.bm.GetLocationLabels(transport)
c.CurrentGateway = c.bm.GetCurrentGateway()
c.CurrentLocation = c.bm.GetCurrentLocation()
c.CurrentCountry = c.bm.GetCurrentCountry()
......@@ -78,7 +82,7 @@ func (c *connectionCtx) toJson() ([]byte, error) {
c.Transport = transport
c.UseUDP = c.cfg.UDP // TODO initialize bitmask param?
c.OffersUDP = c.bm.OffersUDP()
c.UseSnowflake = c.cfg.Snowflake // TODO initialize bitmask param?
c.UseSnowflake = c.cfg.Snowflake // TODO initialize bitmask
c.ManualLocation = c.bm.IsManualLocation()
c.CanUpgrade = c.bm.CanUpgrade()
c.Motd = c.bm.GetMotd()
......@@ -87,7 +91,6 @@ func (c *connectionCtx) toJson() ([]byte, error) {
defer statusMutex.Unlock()
b, err := json.Marshal(c)
if err != nil {
log.Println(err)
return nil, err
}
return b, nil
......@@ -97,11 +100,23 @@ func (c connectionCtx) updateStatus() {
updateMutex.Lock()
defer updateMutex.Unlock()
if stStr, err := c.bm.GetStatus(); err != nil {
log.Printf("Error getting status: %v", err)
log.Error().
Err(err).
Msg("Could not get OpenVPN status")
} else {
setStatusFromStr(stStr)
}
go func() {
snowflakeCh := c.bm.GetSnowflakeCh()
for {
select {
case event := <-snowflakeCh:
setSnowflakeStatus(event)
}
}
}()
statusCh := c.bm.GetStatusCh()
for {
select {
......@@ -111,6 +126,14 @@ func (c connectionCtx) updateStatus() {
}
}
func setSnowflakeStatus(event *snowflake.StatusEvent) {
statusMutex.Lock()
defer statusMutex.Unlock()
ctx.SnowflakeProgress = event.Progress
ctx.SnowflakeTag = event.Tag
go trigger(OnStatusChanged)
}
func setStatus(st status) {
statusMutex.Lock()
defer statusMutex.Unlock()
......@@ -162,5 +185,8 @@ func (s status) fromString(st string) status {
}
func setStatusFromStr(stStr string) {
log.Trace().
Str("status", stStr).
Msg("Setting GUI status")
setStatus(unknown.fromString(stStr))
}
......@@ -3,13 +3,13 @@ package backend
import (
"encoding/json"
"fmt"
"log"
"github.com/rs/zerolog/log"
"net/http"
"os"
"strconv"
"time"
"0xacab.org/leap/bitmask-vpn/pkg/bitmask"
)
func CheckAuth(handler http.HandlerFunc, token string) http.HandlerFunc {
......@@ -25,12 +25,12 @@ func CheckAuth(handler http.HandlerFunc, token string) http.HandlerFunc {
}
func webOn(w http.ResponseWriter, r *http.Request) {
log.Println("Web UI: on")
log.Info().Msg("Web UI: on")
SwitchOn()
}
func webOff(w http.ResponseWriter, r *http.Request) {
log.Println("Web UI: off")
log.Info().Msg("Web UI: off")
SwitchOff()
}
......@@ -64,7 +64,7 @@ func webGatewaySet(w http.ResponseWriter, r *http.Request) {
func webGatewayList(w http.ResponseWriter, r *http.Request) {
transport := ctx.bm.GetTransport()
locationJson, err := json.Marshal(ctx.bm.ListLocationFullness(transport))
locationJson, err := json.Marshal(ctx.bm.GetLocationQualityMap(transport))
if err != nil {
fmt.Fprintf(w, "Error converting json: %v", err)
}
......@@ -108,15 +108,17 @@ func webTransportList(w http.ResponseWriter, r *http.Request) {
}
func webQuit(w http.ResponseWriter, r *http.Request) {
log.Println("Web UI: quit")
log.Info().Msg("Web UI: quit")
Quit()
os.Exit(0)
}
func enableWebAPI(port int) {
log.Println("Starting WebAPI in port", port)
bitmask.GenerateAuthToken()
token := bitmask.ReadAuthToken()
log.Debug().
Int("port", port).
Msg("Starting WebAPI")
generateAuthToken()
token := readAuthToken()
http.Handle("/vpn/start", CheckAuth(http.HandlerFunc(webOn), token))
http.Handle("/vpn/stop", CheckAuth(http.HandlerFunc(webOff), token))
http.Handle("/vpn/gw/get", CheckAuth(http.HandlerFunc(webGatewayGet), token))
......@@ -127,7 +129,14 @@ func enableWebAPI(port int) {
http.Handle("/vpn/transport/list", CheckAuth(http.HandlerFunc(webTransportList), token))
http.Handle("/vpn/status", CheckAuth(http.HandlerFunc(webStatus), token))
http.Handle("/vpn/quit", CheckAuth(http.HandlerFunc(webQuit), token))
http.ListenAndServe(":"+strconv.Itoa(port), nil)
err := http.ListenAndServe(":"+strconv.Itoa(port), nil)
if err != nil {
log.Warn().
Err(err).
Str("bindAddr", ":"+strconv.Itoa(port)).
Msg("Could not listen on port for WebAPI")
}
}
func isValidTransport(t string) bool {
......
//go:build !windows
// +build !windows
// Copyright (C) 2018 LEAP
//
// This program is free software: you can redistribute it and/or modify
......@@ -14,15 +16,16 @@
// 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
package autostart
import (
"fmt"
"log"
"os"
"path/filepath"
"regexp"
"github.com/rs/zerolog/log"
pmautostart "github.com/ProtonMail/go-autostart"
)
......@@ -46,7 +49,9 @@ func NewAutostart(appName string, iconPath string) Autostart {
snapName := match[1]
exec = []string{fmt.Sprintf("/snap/bin/%s.launcher", snapName)}
} else {
log.Printf("Snap binary has unknown path: %v", os.Args[0])
log.Warn().
Str("path", os.Args[0]).
Msg("Snap binary has unkown path")
}
}
......@@ -54,7 +59,9 @@ func NewAutostart(appName string, iconPath string) Autostart {
var err error
exec[0], err = filepath.Abs(exec[0])
if err != nil {
log.Printf("Error making the path absolute directory: %v", err)
log.Warn().
Err(err).
Msg("Could not make the path absolute directory")
}
}
......
//go:build windows
// +build windows
package bitmask
package autostart
// Workaround for broken autostart package on windows.
......
......@@ -16,12 +16,11 @@
package bitmask
import (
"log"
"os"
"path"
"0xacab.org/leap/bitmask-vpn/pkg/config"
"0xacab.org/leap/bitmask-vpn/pkg/vpn"
"github.com/rs/zerolog/log"
)
type ProviderInfo struct {
......@@ -30,19 +29,22 @@ type ProviderInfo struct {
}
type ProviderOpts struct {
Provider string `json:"name"`
AppName string `json:"applicationName"`
BinaryName string `json:"binaryName"`
Auth string `json:"auth"`
AuthEmptyPass bool `json:"authEmptyPass"`
ProviderURL string `json:"providerURL"`
DonateURL string `json:"donateURL"`
ApiURL string `json:"apiURL"`
TosURL string `json:"tosURL"`
HelpURL string `json:"helpURL"`
GeolocationURL string `json:"geolocationAPI"`
AskForDonations bool `json:"askForDonations"`
CaCert string `json:"caCertString"`
Provider string `json:"name"`
AppName string `json:"applicationName"`
BinaryName string `json:"binaryName"`
Auth string `json:"auth"`
AuthEmptyPass bool `json:"authEmptyPass"`
ProviderURL string `json:"providerURL"`
DonateURL string `json:"donateURL"`
ApiURL string `json:"apiURL"`
TosURL string `json:"tosURL"`
HelpURL string `json:"helpURL"`
GeolocationURL string `json:"geolocationAPI"`
AskForDonations bool `json:"askForDonations"`
CaCert string `json:"caCertString"`
ApiVersion int `json:"apiVersion"`
STUNServers []string `json:"STUNServers"`
CountryCodeLookupURL string `json:"countryCodeLookupURL"`
}
func GetConfiguredProvider() *ProviderInfo {
......@@ -52,39 +54,31 @@ func GetConfiguredProvider() *ProviderInfo {
}
func ConfigureProvider(opts *ProviderOpts) {
config.Provider = opts.ProviderURL
config.Provider = opts.Provider
config.ApplicationName = opts.AppName
config.BinaryName = opts.BinaryName
config.Auth = opts.Auth
config.GeolocationAPI = opts.GeolocationURL
config.APIURL = opts.ApiURL
config.CaCert = []byte(opts.CaCert)
}
func InitializeLogger() {
_, err := config.ConfigureLogger(path.Join(config.LogPath))
if err != nil {
log.Println("Can't configure logger: ", err)
}
}
func initBitmaskVPN() (Bitmask, error) {
b, err := vpn.Init()
if err != nil {
log.Printf("An error ocurred starting bitmask vpn: %v", err)
}
return b, err
config.ApiVersion = opts.ApiVersion
config.STUNServers = opts.STUNServers
config.CountryCodeLookupURL = opts.CountryCodeLookupURL
}
func InitializeBitmask(conf *config.Config) (Bitmask, error) {
log.Trace().Msg("Initializing bitmask")
if conf.SkipLaunch {
log.Println("Initializing bitmask, but not launching it...")
log.Info().Msg("Not autostarting OpenVPN")
}
if _, err := os.Stat(config.Path); os.IsNotExist(err) {
os.MkdirAll(config.Path, os.ModePerm)
err = os.MkdirAll(config.Path, os.ModePerm)
if err != nil {
return nil, err
}
}
b, err := initBitmaskVPN()
b, err := vpn.Init()
if err != nil {
return nil, err
}
......@@ -95,10 +89,7 @@ func InitializeBitmask(conf *config.Config) (Bitmask, error) {
return nil, err
}
err = setUDP(b, conf)
if err != nil {
return nil, err
}
setUDP(b, conf)
if !conf.SkipLaunch {
err := maybeStartVPN(b, conf)
......@@ -106,44 +97,62 @@ func InitializeBitmask(conf *config.Config) (Bitmask, error) {
// we don't want this error to avoid initialization of
// the bitmask object. If we cannot autostart it's not
// so terrible.
log.Println("Error starting VPN: ", err)
log.Warn().
Err(err).
Msg("Could not start OpenVPN (maybeStartVPN)")
}
}
return b, nil
}
func setTransport(b Bitmask, conf *config.Config) error {
if config.Provider == "riseup" {
log.Info().Msg("Using transport openvpn")
err := b.SetTransport("openvpn")
if err != nil {
return err
}
return nil
}
if conf.Obfs4 {
log.Printf("Use transport Obfs4")
log.Info().Msg("Using transport obfs4")
err := b.SetTransport("obfs4")
if err != nil {
log.Printf("Error setting transport: %v", err)
return err
}
return nil
}
return nil
}
func setUDP(b Bitmask, conf *config.Config) error {
if conf.UDP {
log.Printf("Use UDP")
err := b.UseUDP(true)
if conf.KCP {
log.Info().Msg("Using transport kcp")
err := b.SetTransport("kcp")
if err != nil {
log.Printf("Error setting UDP: %v", err)
return err
}
}
return nil
}
func setUDP(b Bitmask, conf *config.Config) {
if conf.UDP {
log.Info().Msg("Enabled UDP")
b.UseUDP(true)
} else {
log.Warn().Msg("UDP not enabled in config")
}
}
func maybeStartVPN(b Bitmask, conf *config.Config) error {
if !conf.StartVPN {
return nil
}
if b.CanStartVPN() {
log.Info().Msg("Starting OpenVPN")
err := b.StartVPN(config.Provider)
conf.SetUserStoppedVPN(false)
if err != nil {
return err
}
err = conf.SetUserStoppedVPN(false)
return err
}
return nil
......
......@@ -15,27 +15,30 @@
package bitmask
import "0xacab.org/leap/bitmask-vpn/pkg/snowflake"
// This interface is used to implement different versions (v3 + v5)
type Bitmask interface {
GetStatusCh() <-chan string
GetSnowflakeCh() <-chan *snowflake.StatusEvent
Close()
Version() (string, error)
StartVPN(provider string) error
CanStartVPN() bool
StopVPN() error
Reconnect() error
ReloadFirewall() error
GetStatus() (string, error)
InstallHelpers() error
VPNCheck() (helpers bool, priviledge bool, err error)
ListLocationFullness(protocol string) map[string]float64
ListLocationLabels(protocol string) map[string][]string
GetLocationQualityMap(protocol string) map[string]float64
GetLocationLabels(protocol string) map[string][]string
GetBestLocation(protocol string) string
UseGateway(name string)
UseAutomaticGateway()
SetProvider(string)
GetTransport() string
SetTransport(string) error
UseUDP(bool) error
UseUDP(bool)
UseSnowflake(bool) error
OffersUDP() bool
GetCurrentGateway() string
......
package config
var (
Provider = ""
ApplicationName = ""
BinaryName = ""
Auth = ""
APIURL = ""
GeolocationAPI = ""
Provider = ""
ApplicationName = ""
BinaryName = ""
Auth = ""
APIURL = ""
GeolocationAPI = ""
ApiVersion = -1
CaCert = []byte("")
STUNServers = []string{}
CountryCodeLookupURL = ""
)
var CaCert = []byte("")
//go:build darwin
// +build darwin
// Copyright (C) 2018 LEAP
//
// This program is free software: you can redistribute it and/or modify
......
......@@ -17,9 +17,13 @@ package config
import (
"encoding/json"
"errors"
"io/fs"
"os"
"path"
"time"
"github.com/rs/zerolog/log"
)
const (
......@@ -43,6 +47,7 @@ type Config struct {
DisableAutostart bool
UDP bool
Snowflake bool
KCP bool
}
SkipLaunch bool
Obfs4 bool
......@@ -50,6 +55,7 @@ type Config struct {
StartVPN bool
UDP bool
Snowflake bool
KCP bool
}
// ParseConfig reads the configuration from the configuration file
......@@ -57,12 +63,20 @@ func ParseConfig() *Config {
var conf Config
f, err := os.Open(configPath)
if err != nil {
conf.save()
if err != nil && errors.Is(err, fs.ErrNotExist) {
log.Debug().
Msg("Config file doesn't exist. Using default values to create")
conf.setDefaults()
} else {
defer f.Close()
dec := json.NewDecoder(f)
err = dec.Decode(&conf.file)
if err != nil {
log.Warn().
Err(err).
Str("configPath", configPath).
Msg("Could not json decode config")
}
}
conf.Obfs4 = conf.file.Obfs4
......@@ -70,9 +84,17 @@ func ParseConfig() *Config {
conf.StartVPN = !conf.file.UserStoppedVPN
conf.UDP = conf.file.UDP
conf.Snowflake = conf.file.Snowflake
conf.KCP = conf.file.KCP
return &conf
}
func (c *Config) setDefaults() {
if err := c.SetUseUDP(true); err != nil {
log.Err(err).
Msg("Unable to set default for UDP config")
}
}
func (c *Config) SetUserStoppedVPN(vpnStopped bool) error {
c.file.UserStoppedVPN = vpnStopped
return c.save()
......@@ -102,6 +124,12 @@ func (c *Config) SetUseObfs4(val bool) error {
return c.save()
}
func (c *Config) SetUseKCP(val bool) error {
c.KCP = val
c.file.KCP = val
return c.save()
}
func (c *Config) SetUseUDP(val bool) error {
c.UDP = val
c.file.UDP = val
......
......@@ -16,26 +16,45 @@
package config
import (
"io"
"log"
"os"
"path"
"github.com/rs/zerolog"
"github.com/rs/zerolog/log"
)
//ConfigureLogger to write logs into a file as well as the stderr
func ConfigureLogger(logPath string) (io.Closer, error) {
dir := path.Dir(logPath)
if _, err := os.Stat(dir); err != nil {
if os.IsNotExist(err) {
err := os.MkdirAll(dir, 0700)
if err != nil {
log.Println("ERROR: cannot create data dir:", dir)
}
}
var logFile *os.File
func ConfigureLogger() {
os.MkdirAll(Path, 0750)
logFile, _ = os.OpenFile(
LogPath,
os.O_RDWR|os.O_CREATE|os.O_APPEND,
0644,
)
consoleWriter := zerolog.ConsoleWriter{
Out: os.Stderr,
TimeFormat: "2006-01-02T15:04:05.999Z07:00",
}
logFile, err := os.OpenFile(logPath, os.O_RDWR|os.O_CREATE|os.O_APPEND, 0666)
if err == nil {
log.SetOutput(io.MultiWriter(logFile, os.Stderr))
multi := zerolog.MultiLevelWriter(consoleWriter, logFile)
log.Logger = zerolog.New(multi).With().Timestamp().Logger()
envLogLevel := os.Getenv("LOG_LEVEL")
if envLogLevel == "TRACE" {
zerolog.SetGlobalLevel(zerolog.TraceLevel)
} else if envLogLevel == "DEBUG" {
zerolog.SetGlobalLevel(zerolog.DebugLevel)
} else {
zerolog.SetGlobalLevel(zerolog.InfoLevel)
}
return logFile, err
log.Info().
Str("logFile", LogPath).
Str("hint", "you can change the log level with env LOG_LEVEL=INFO|DEBUG|TRACE").
Msg("Enabling logging")
}
func CloseLogger() {
logFile.Close()
}
//go:build !windows && !darwin
// +build !windows,!darwin
// Copyright (C) 2018 LEAP
//
// This program is free software: you can redistribute it and/or modify
......
version.go
package version
import (
"io/ioutil"
"log"
"io"
"net/http"
"os"
"runtime"
"strings"
"time"
"github.com/rs/zerolog/log"
)
const verURI = "https://downloads.leap.se/RiseupVPN/"
// returns true if there's a newer version string published on the server
// CanUpgrade returns true if there's a newer version string published on the server
// this needs to manually bump latest version for every platform in the
// downloads server.
// at the moment, we hardcode RiseupVPN in the path, assuming that all clients
// stay in sync.
func CanUpgrade() bool {
if os.Getenv("SKIP_VERSION_CHECK") == "1" {
log.Info().Msg("Not checking for upgrades")
return false
}
log.Println("Checking for updates...")
uri := verURI
switch runtime.GOOS {
case "windows":
......@@ -33,30 +35,44 @@ func CanUpgrade() bool {
uri += "linux"
}
uri += "/lastver"
resp, err := http.Get(uri)
c := http.Client{Timeout: 30 * time.Second}
resp, err := c.Get(uri)
log.Info().
Str("url", uri).
Msg("Checking for updates")
if err != nil {
log.Println(err)
log.Warn().
Err(err).
Str("url", uri).
Msg("Could not check if there are updates available")
return false
}
defer resp.Body.Close()
verStr, err := ioutil.ReadAll(resp.Body)
verStr, err := io.ReadAll(resp.Body)
if err != nil {
log.Println(err)
log.Warn().
Err(err).
Msg("Could not read http response")
return false
}
r := strings.TrimSpace(string(verStr))
if strings.Count(r, "\n") > 1 {
log.Println("No remote version found at " + uri)
log.Warn().
Str("versionString", string(verStr)).
Msg("Could not parse version string")
return false
}
canUpgrade := versionOrdinal(r) > versionOrdinal(VERSION)
if os.Getenv("DEBUG") == "1" {
log.Println(">>> Remote version: " + r)
log.Println(">>> Current version: " + VERSION)
}
if canUpgrade {
log.Println("There's a newer version available:", r)
}
canUpgrade := versionOrdinal(r) > versionOrdinal(Version())
log.Debug().
Str("version", r).
Msg("Remote version")
log.Debug().
Str("version", Version()).
Msg("Installed version")
log.Info().
Bool("updateAvailable", canUpgrade).
Msg("Sucessfully checked if there is an update")
return canUpgrade
}
......@@ -81,7 +97,7 @@ func versionOrdinal(version string) string {
continue
}
if vo[j]+1 > maxByte {
log.Println("VersionOrdinal: invalid version")
log.Warn().Msg("VersionOrdinal: invalid version")
return string(vo)
}
vo = append(vo, b)
......
package main
//go:generate go run . -output=../version.go