-
Notifications
You must be signed in to change notification settings - Fork 3
/
config.go
208 lines (174 loc) · 4.78 KB
/
config.go
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
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
package client
import (
"encoding/json"
"os"
"path/filepath"
"reflect"
"strings"
"github.com/telekom-mms/oc-daemon/pkg/xmlprofile"
)
var (
// ConfigName is the name of the configuration file.
ConfigName = "oc-client.json"
// ConfigDirName is the name of the directory where the configuration
// file is stored.
ConfigDirName = "oc-daemon"
// SystemConfigDirPath is the path of the directory where the directory
// of the system configuration is stored.
SystemConfigDirPath = "/var/lib"
// OpenConnect is the openconnect executable.
OpenConnect = "openconnect"
// Protocol is the protocol used by openconnect.
Protocol = "anyconnect"
// UserAgent is the user agent used by openconnect.
UserAgent = "AnyConnect"
// Quiet specifies whether the quiet flag is set in openconnect.
Quiet = true
// NoProxy specifies whether the no proxy flag is set in openconnect.
NoProxy = true
// ExtraEnv are extra environment variables used by openconnect.
ExtraEnv = []string{}
// ExtraArgs are extra command line arguments used by openconnect.
ExtraArgs = []string{}
)
// Config is a configuration for the OC client.
type Config struct {
ClientCertificate string
ClientKey string
UserCertificate string
UserKey string
CACertificate string
XMLProfile string
VPNServer string
User string
Password string `json:"-"`
OpenConnect string
Protocol string
UserAgent string
Quiet bool
NoProxy bool
ExtraEnv []string
ExtraArgs []string
}
// Copy returns a copy of Config.
func (c *Config) Copy() *Config {
if c == nil {
return nil
}
cp := *c
cp.ExtraEnv = append(c.ExtraEnv[:0:0], c.ExtraEnv...)
cp.ExtraArgs = append(c.ExtraArgs[:0:0], c.ExtraArgs...)
return &cp
}
// Empty returns whether the config is empty.
func (c *Config) Empty() bool {
if c == nil {
return true
}
empty := &Config{}
return reflect.DeepEqual(c, empty)
}
// Valid returns whether the config is valid.
func (c *Config) Valid() bool {
if c.Empty() ||
c.ClientCertificate == "" ||
c.ClientKey == "" ||
c.XMLProfile == "" ||
c.VPNServer == "" ||
c.OpenConnect == "" ||
c.Protocol == "" ||
c.UserAgent == "" {
// invalid
return false
}
return true
}
// expandPath expands tilde and environment variables in path.
func expandPath(path string) string {
// note: handling of tilde is limited:
// it only works with file paths beginning with ~/
if strings.HasPrefix(path, "~") {
path = filepath.Join("$HOME", path[1:])
}
return os.ExpandEnv(path)
}
// expandPaths expands the paths in config.
func (c *Config) expandPaths() {
c.ClientCertificate = expandPath(c.ClientCertificate)
c.ClientKey = expandPath(c.ClientKey)
c.CACertificate = expandPath(c.CACertificate)
}
// expandUser expands the username in config.
func (c *Config) expandUser() {
c.User = os.ExpandEnv(c.User)
}
// Expand expands variables in config.
func (c *Config) Expand() {
c.expandPaths()
c.expandUser()
}
// jsonMarshalIndent is json.MarshalIndent for testing.
var jsonMarshalIndent = json.MarshalIndent
// Save saves the config to file.
func (c *Config) Save(file string) error {
b, err := jsonMarshalIndent(c, "", " ")
if err != nil {
return err
}
return os.WriteFile(file, b, 0600)
}
// NewConfig returns a new Config.
func NewConfig() *Config {
return &Config{
XMLProfile: xmlprofile.SystemProfile,
OpenConnect: OpenConnect,
Protocol: Protocol,
UserAgent: UserAgent,
Quiet: Quiet,
NoProxy: NoProxy,
ExtraEnv: append(ExtraEnv[:0:0], ExtraEnv...),
ExtraArgs: append(ExtraArgs[:0:0], ExtraArgs...),
}
}
// LoadConfig loads a Config from file.
func LoadConfig(file string) (*Config, error) {
b, err := os.ReadFile(file)
if err != nil {
return nil, err
}
conf := NewConfig()
if err := json.Unmarshal(b, conf); err != nil {
return nil, err
}
return conf, nil
}
// SystemConfig returns the default file path of the system configuration.
func SystemConfig() string {
return filepath.Join(SystemConfigDirPath, ConfigDirName, ConfigName)
}
// osUserConfigDir is os.UserConfigDir for testing.
var osUserConfigDir = os.UserConfigDir
// UserConfig returns the default file path of the current user's configuration.
func UserConfig() string {
dir, err := osUserConfigDir()
if err != nil {
return ""
}
return filepath.Join(dir, ConfigDirName, ConfigName)
}
// LoadUserSystemConfig loads the user or system configuration from its
// default location, expands variables in config.
func LoadUserSystemConfig() *Config {
// try user config
if config, err := LoadConfig(UserConfig()); err == nil && config != nil {
config.Expand()
return config
}
// try system config
if config, err := LoadConfig(SystemConfig()); err == nil && config != nil {
config.Expand()
return config
}
// could not load a config
return nil
}