chore: OpenVPN user and password as nullable
- Username and password can be the empty string for custom provider
This commit is contained in:
@@ -19,13 +19,15 @@ type OpenVPN struct {
|
|||||||
// It can only be "2.4" or "2.5".
|
// It can only be "2.4" or "2.5".
|
||||||
Version string
|
Version string
|
||||||
// User is the OpenVPN authentication username.
|
// User is the OpenVPN authentication username.
|
||||||
// It cannot be an empty string in the internal state
|
// It cannot be nil in the internal state if OpenVPN is used.
|
||||||
// if OpenVPN is used.
|
// It is usually required but in some cases can be the empty string
|
||||||
User string
|
// to indicate no user+password authentication is needed.
|
||||||
|
User *string
|
||||||
// Password is the OpenVPN authentication password.
|
// Password is the OpenVPN authentication password.
|
||||||
// It cannot be an empty string in the internal state
|
// It cannot be nil in the internal state if OpenVPN is used.
|
||||||
// if OpenVPN is used.
|
// It is usually required but in some cases can be the empty string
|
||||||
Password string
|
// to indicate no user+password authentication is needed.
|
||||||
|
Password *string
|
||||||
// ConfFile is a custom OpenVPN configuration file path.
|
// ConfFile is a custom OpenVPN configuration file path.
|
||||||
// It can be set to the empty string for it to be ignored.
|
// It can be set to the empty string for it to be ignored.
|
||||||
// It cannot be nil in the internal state.
|
// It cannot be nil in the internal state.
|
||||||
@@ -88,14 +90,14 @@ func (o OpenVPN) validate(vpnProvider string) (err error) {
|
|||||||
|
|
||||||
isCustom := vpnProvider == providers.Custom
|
isCustom := vpnProvider == providers.Custom
|
||||||
|
|
||||||
if !isCustom && o.User == "" {
|
if !isCustom && *o.User == "" {
|
||||||
return ErrOpenVPNUserIsEmpty
|
return ErrOpenVPNUserIsEmpty
|
||||||
}
|
}
|
||||||
|
|
||||||
passwordRequired := !isCustom &&
|
passwordRequired := !isCustom &&
|
||||||
(vpnProvider != providers.Ivpn || !ivpnAccountID.MatchString(o.User))
|
(vpnProvider != providers.Ivpn || !ivpnAccountID.MatchString(*o.User))
|
||||||
|
|
||||||
if passwordRequired && o.Password == "" {
|
if passwordRequired && *o.Password == "" {
|
||||||
return ErrOpenVPNPasswordIsEmpty
|
return ErrOpenVPNPasswordIsEmpty
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -204,8 +206,8 @@ func validateOpenVPNClientKey(vpnProvider, clientKey string) (err error) {
|
|||||||
func (o *OpenVPN) copy() (copied OpenVPN) {
|
func (o *OpenVPN) copy() (copied OpenVPN) {
|
||||||
return OpenVPN{
|
return OpenVPN{
|
||||||
Version: o.Version,
|
Version: o.Version,
|
||||||
User: o.User,
|
User: helpers.CopyStringPtr(o.User),
|
||||||
Password: o.Password,
|
Password: helpers.CopyStringPtr(o.Password),
|
||||||
ConfFile: helpers.CopyStringPtr(o.ConfFile),
|
ConfFile: helpers.CopyStringPtr(o.ConfFile),
|
||||||
Ciphers: helpers.CopyStringSlice(o.Ciphers),
|
Ciphers: helpers.CopyStringSlice(o.Ciphers),
|
||||||
Auth: helpers.CopyStringPtr(o.Auth),
|
Auth: helpers.CopyStringPtr(o.Auth),
|
||||||
@@ -225,8 +227,8 @@ func (o *OpenVPN) copy() (copied OpenVPN) {
|
|||||||
// unset field of the receiver settings object.
|
// unset field of the receiver settings object.
|
||||||
func (o *OpenVPN) mergeWith(other OpenVPN) {
|
func (o *OpenVPN) mergeWith(other OpenVPN) {
|
||||||
o.Version = helpers.MergeWithString(o.Version, other.Version)
|
o.Version = helpers.MergeWithString(o.Version, other.Version)
|
||||||
o.User = helpers.MergeWithString(o.User, other.User)
|
o.User = helpers.MergeWithStringPtr(o.User, other.User)
|
||||||
o.Password = helpers.MergeWithString(o.Password, other.Password)
|
o.Password = helpers.MergeWithStringPtr(o.Password, other.Password)
|
||||||
o.ConfFile = helpers.MergeWithStringPtr(o.ConfFile, other.ConfFile)
|
o.ConfFile = helpers.MergeWithStringPtr(o.ConfFile, other.ConfFile)
|
||||||
o.Ciphers = helpers.MergeStringSlices(o.Ciphers, other.Ciphers)
|
o.Ciphers = helpers.MergeStringSlices(o.Ciphers, other.Ciphers)
|
||||||
o.Auth = helpers.MergeWithStringPtr(o.Auth, other.Auth)
|
o.Auth = helpers.MergeWithStringPtr(o.Auth, other.Auth)
|
||||||
@@ -246,8 +248,8 @@ func (o *OpenVPN) mergeWith(other OpenVPN) {
|
|||||||
// settings.
|
// settings.
|
||||||
func (o *OpenVPN) overrideWith(other OpenVPN) {
|
func (o *OpenVPN) overrideWith(other OpenVPN) {
|
||||||
o.Version = helpers.OverrideWithString(o.Version, other.Version)
|
o.Version = helpers.OverrideWithString(o.Version, other.Version)
|
||||||
o.User = helpers.OverrideWithString(o.User, other.User)
|
o.User = helpers.OverrideWithStringPtr(o.User, other.User)
|
||||||
o.Password = helpers.OverrideWithString(o.Password, other.Password)
|
o.Password = helpers.OverrideWithStringPtr(o.Password, other.Password)
|
||||||
o.ConfFile = helpers.OverrideWithStringPtr(o.ConfFile, other.ConfFile)
|
o.ConfFile = helpers.OverrideWithStringPtr(o.ConfFile, other.ConfFile)
|
||||||
o.Ciphers = helpers.OverrideWithStringSlice(o.Ciphers, other.Ciphers)
|
o.Ciphers = helpers.OverrideWithStringSlice(o.Ciphers, other.Ciphers)
|
||||||
o.Auth = helpers.OverrideWithStringPtr(o.Auth, other.Auth)
|
o.Auth = helpers.OverrideWithStringPtr(o.Auth, other.Auth)
|
||||||
@@ -264,8 +266,11 @@ func (o *OpenVPN) overrideWith(other OpenVPN) {
|
|||||||
|
|
||||||
func (o *OpenVPN) setDefaults(vpnProvider string) {
|
func (o *OpenVPN) setDefaults(vpnProvider string) {
|
||||||
o.Version = helpers.DefaultString(o.Version, openvpn.Openvpn25)
|
o.Version = helpers.DefaultString(o.Version, openvpn.Openvpn25)
|
||||||
|
o.User = helpers.DefaultStringPtr(o.User, "")
|
||||||
if vpnProvider == providers.Mullvad {
|
if vpnProvider == providers.Mullvad {
|
||||||
o.Password = "m"
|
o.Password = helpers.DefaultStringPtr(o.Password, "m")
|
||||||
|
} else {
|
||||||
|
o.Password = helpers.DefaultStringPtr(o.Password, "")
|
||||||
}
|
}
|
||||||
|
|
||||||
o.ConfFile = helpers.DefaultStringPtr(o.ConfFile, "")
|
o.ConfFile = helpers.DefaultStringPtr(o.ConfFile, "")
|
||||||
@@ -293,8 +298,8 @@ func (o OpenVPN) String() string {
|
|||||||
func (o OpenVPN) toLinesNode() (node *gotree.Node) {
|
func (o OpenVPN) toLinesNode() (node *gotree.Node) {
|
||||||
node = gotree.New("OpenVPN settings:")
|
node = gotree.New("OpenVPN settings:")
|
||||||
node.Appendf("OpenVPN version: %s", o.Version)
|
node.Appendf("OpenVPN version: %s", o.Version)
|
||||||
node.Appendf("User: %s", helpers.ObfuscatePassword(o.User))
|
node.Appendf("User: %s", helpers.ObfuscatePassword(*o.User))
|
||||||
node.Appendf("Password: %s", helpers.ObfuscatePassword(o.Password))
|
node.Appendf("Password: %s", helpers.ObfuscatePassword(*o.Password))
|
||||||
|
|
||||||
if *o.ConfFile != "" {
|
if *o.ConfFile != "" {
|
||||||
node.Appendf("Custom configuration file: %s", *o.ConfFile)
|
node.Appendf("Custom configuration file: %s", *o.ConfFile)
|
||||||
|
|||||||
21
internal/configuration/sources/env/openvpn.go
vendored
21
internal/configuration/sources/env/openvpn.go
vendored
@@ -72,14 +72,25 @@ func (r *Reader) readOpenVPN() (
|
|||||||
return openVPN, nil
|
return openVPN, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (r *Reader) readOpenVPNUser() (user string) {
|
func (r *Reader) readOpenVPNUser() (user *string) {
|
||||||
_, user = r.getEnvWithRetro("OPENVPN_USER", "USER")
|
user = new(string)
|
||||||
|
_, *user = r.getEnvWithRetro("OPENVPN_USER", "USER")
|
||||||
|
if *user == "" {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
// Remove spaces in user ID to simplify user's life, thanks @JeordyR
|
// Remove spaces in user ID to simplify user's life, thanks @JeordyR
|
||||||
return strings.ReplaceAll(user, " ", "")
|
*user = strings.ReplaceAll(*user, " ", "")
|
||||||
|
return user
|
||||||
}
|
}
|
||||||
|
|
||||||
func (r *Reader) readOpenVPNPassword() (password string) {
|
func (r *Reader) readOpenVPNPassword() (password *string) {
|
||||||
_, password = r.getEnvWithRetro("OPENVPN_PASSWORD", "PASSWORD")
|
password = new(string)
|
||||||
|
_, *password = r.getEnvWithRetro("OPENVPN_PASSWORD", "PASSWORD")
|
||||||
|
if *password == "" {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
return password
|
return password
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -25,18 +25,3 @@ func readSecretFileAsStringPtr(secretPathEnvKey, defaultSecretPath string) (
|
|||||||
}
|
}
|
||||||
return files.ReadFromFile(path)
|
return files.ReadFromFile(path)
|
||||||
}
|
}
|
||||||
|
|
||||||
func readSecretFileAsString(secretPathEnvKey, defaultSecretPath string) (
|
|
||||||
s string, err error) {
|
|
||||||
path := getCleanedEnv(secretPathEnvKey)
|
|
||||||
if path == "" {
|
|
||||||
path = defaultSecretPath
|
|
||||||
}
|
|
||||||
stringPtr, err := files.ReadFromFile(path)
|
|
||||||
if err != nil {
|
|
||||||
return "", err
|
|
||||||
} else if stringPtr == nil {
|
|
||||||
return "", nil
|
|
||||||
}
|
|
||||||
return *stringPtr, nil
|
|
||||||
}
|
|
||||||
|
|||||||
@@ -8,7 +8,7 @@ import (
|
|||||||
|
|
||||||
func readOpenVPN() (
|
func readOpenVPN() (
|
||||||
settings settings.OpenVPN, err error) {
|
settings settings.OpenVPN, err error) {
|
||||||
settings.User, err = readSecretFileAsString(
|
settings.User, err = readSecretFileAsStringPtr(
|
||||||
"OPENVPN_USER_SECRETFILE",
|
"OPENVPN_USER_SECRETFILE",
|
||||||
"/run/secrets/openvpn_user",
|
"/run/secrets/openvpn_user",
|
||||||
)
|
)
|
||||||
@@ -16,7 +16,7 @@ func readOpenVPN() (
|
|||||||
return settings, fmt.Errorf("cannot read user file: %w", err)
|
return settings, fmt.Errorf("cannot read user file: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
settings.Password, err = readSecretFileAsString(
|
settings.Password, err = readSecretFileAsStringPtr(
|
||||||
"OPENVPN_PASSWORD_SECRETFILE",
|
"OPENVPN_PASSWORD_SECRETFILE",
|
||||||
"/run/secrets/openvpn_password",
|
"/run/secrets/openvpn_password",
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -74,7 +74,7 @@ func modifyConfig(lines []string, connection models.Connection,
|
|||||||
modified = append(modified, "pull-filter ignore \"auth-token\"") // prevent auth failed loop
|
modified = append(modified, "pull-filter ignore \"auth-token\"") // prevent auth failed loop
|
||||||
modified = append(modified, "auth-retry nointeract")
|
modified = append(modified, "auth-retry nointeract")
|
||||||
modified = append(modified, "suppress-timestamps")
|
modified = append(modified, "suppress-timestamps")
|
||||||
if settings.User != "" {
|
if *settings.User != "" {
|
||||||
modified = append(modified, "auth-user-pass "+openvpn.AuthConf)
|
modified = append(modified, "auth-user-pass "+openvpn.AuthConf)
|
||||||
}
|
}
|
||||||
modified = append(modified, "verb "+strconv.Itoa(*settings.Verbosity))
|
modified = append(modified, "verb "+strconv.Itoa(*settings.Verbosity))
|
||||||
|
|||||||
@@ -36,7 +36,7 @@ func Test_modifyConfig(t *testing.T) {
|
|||||||
"auth bla",
|
"auth bla",
|
||||||
},
|
},
|
||||||
settings: settings.OpenVPN{
|
settings: settings.OpenVPN{
|
||||||
User: "user",
|
User: stringPtr("user"),
|
||||||
Ciphers: []string{"cipher"},
|
Ciphers: []string{"cipher"},
|
||||||
Auth: stringPtr("auth"),
|
Auth: stringPtr("auth"),
|
||||||
MSSFix: uint16Ptr(1000),
|
MSSFix: uint16Ptr(1000),
|
||||||
|
|||||||
3
internal/server/helpers.go
Normal file
3
internal/server/helpers.go
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
package server
|
||||||
|
|
||||||
|
func stringPtr(s string) *string { return &s }
|
||||||
@@ -94,8 +94,8 @@ func (h *openvpnHandler) setStatus(w http.ResponseWriter, r *http.Request) {
|
|||||||
func (h *openvpnHandler) getSettings(w http.ResponseWriter) {
|
func (h *openvpnHandler) getSettings(w http.ResponseWriter) {
|
||||||
vpnSettings := h.looper.GetSettings()
|
vpnSettings := h.looper.GetSettings()
|
||||||
settings := vpnSettings.OpenVPN
|
settings := vpnSettings.OpenVPN
|
||||||
settings.User = "redacted"
|
settings.User = stringPtr("redacted")
|
||||||
settings.Password = "redacted"
|
settings.Password = stringPtr("redacted")
|
||||||
encoder := json.NewEncoder(w)
|
encoder := json.NewEncoder(w)
|
||||||
if err := encoder.Encode(settings); err != nil {
|
if err := encoder.Encode(settings); err != nil {
|
||||||
h.warner.Warn(err.Error())
|
h.warner.Warn(err.Error())
|
||||||
|
|||||||
@@ -27,8 +27,8 @@ func setupOpenVPN(ctx context.Context, fw Firewall,
|
|||||||
return nil, "", fmt.Errorf("failed writing configuration to file: %w", err)
|
return nil, "", fmt.Errorf("failed writing configuration to file: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
if settings.OpenVPN.User != "" {
|
if *settings.OpenVPN.User != "" {
|
||||||
err := openvpnConf.WriteAuthFile(settings.OpenVPN.User, settings.OpenVPN.Password)
|
err := openvpnConf.WriteAuthFile(*settings.OpenVPN.User, *settings.OpenVPN.Password)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, "", fmt.Errorf("failed writing auth to file: %w", err)
|
return nil, "", fmt.Errorf("failed writing auth to file: %w", err)
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user