1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
|
package backend
import (
"log"
"os"
"0xacab.org/leap/bitmask-vpn/pkg/bitmask"
"0xacab.org/leap/bitmask-vpn/pkg/config"
"0xacab.org/leap/bitmask-vpn/pkg/config/version"
"0xacab.org/leap/bitmask-vpn/pkg/pid"
)
// initializeContext initializes an empty connStatus and assigns it to the
// global ctx holder. This is expected to be called only once, so the public
// api uses the sync.Once primitive to call this.
func initializeContext(opts *InitOpts) {
var st status = off
// TODO - now there's really no need to dance between opts and config anymore
// but this was the simplest transition. We should probably keep the
// multi-provider config in the backend too, and just
// switch the "active" here in the ctx, after the user has selected one
// in the combobox.
ctx = &connectionCtx{
AppName: opts.ProviderOptions.AppName,
Provider: opts.ProviderOptions.Provider,
TosURL: opts.ProviderOptions.TosURL,
HelpURL: opts.ProviderOptions.HelpURL,
DonateURL: opts.ProviderOptions.DonateURL,
AskForDonations: opts.ProviderOptions.AskForDonations,
DonateDialog: false,
Version: version.VERSION,
Status: st,
IsReady: false,
}
errCh := make(chan string)
go checkErrors(errCh)
// isReady is set after Bitmask initialization
initializeBitmask(errCh, opts)
go trigger(OnStatusChanged)
ctx.delayCheckForGateways()
}
func checkErrors(errCh chan string) {
for {
err := <-errCh
// TODO consider a queue instead
ctx.Errors = err
go trigger(OnStatusChanged)
}
}
func initializeBitmask(errCh chan string, opts *InitOpts) {
if ctx == nil {
log.Println("BUG: cannot initialize bitmask, ctx is nil!")
os.Exit(1)
}
bitmask.InitializeLogger()
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())
}
b, err := bitmask.InitializeBitmask(ctx.cfg)
if err != nil {
log.Println("ERROR: cannot initialize bitmask")
errCh <- err.Error()
return
}
// right now we just get autostart from an init flag,
// but we want to be able to persist that option from the preferences
// pane
ctx.autostart = initializeAutostart(ctx.cfg)
helpers, privilege, err := b.VPNCheck()
if err != nil {
log.Println("ERROR: vpn check")
errCh <- err.Error()
}
if helpers == false {
log.Println("ERROR: no helpers")
errCh <- "nohelpers"
}
if privilege == false {
log.Println("ERROR: no polkit")
errCh <- "nopolkit"
}
ctx.bm = b
ctx.IsReady = true
}
// transfer initialization options from the config json to the config object
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'")
} else {
conf.StartVPN = opts.StartVPN == "on"
}
}
if opts.Obfs4 {
conf.Obfs4 = opts.Obfs4
}
if opts.UDP {
conf.UDP = opts.UDP
}
if opts.DisableAutostart {
conf.DisableAutostart = opts.DisableAutostart
}
}
func initializeAutostart(conf *config.Config) bitmask.Autostart {
autostart := bitmask.NewAutostart(config.ApplicationName, "")
if conf.SkipLaunch || conf.DisableAutostart {
autostart.Disable()
autostart = &bitmask.DummyAutostart{}
} else {
err := autostart.Enable()
if err != nil {
log.Printf("Error enabling autostart: %v", err)
}
}
return autostart
}
|