diff --git a/internal/configuration/settings/openvpn.go b/internal/configuration/settings/openvpn.go index 71eb98d2..af847dd8 100644 --- a/internal/configuration/settings/openvpn.go +++ b/internal/configuration/settings/openvpn.go @@ -1,6 +1,7 @@ package settings import ( + "encoding/base64" "fmt" "regexp" "strings" @@ -193,7 +194,7 @@ func validateOpenVPNClientCertificate(vpnProvider, return nil } - _, err = extract.PEM([]byte(clientCert)) + _, err = base64.StdEncoding.DecodeString(clientCert) if err != nil { return err } @@ -215,7 +216,7 @@ func validateOpenVPNClientKey(vpnProvider, clientKey string) (err error) { return nil } - _, err = extract.PEM([]byte(clientKey)) + _, err = base64.StdEncoding.DecodeString(clientKey) if err != nil { return err } @@ -232,9 +233,9 @@ func validateOpenVPNEncryptedKey(vpnProvider, return nil } - _, err = extract.PEM([]byte(encryptedPrivateKey)) + _, err = base64.StdEncoding.DecodeString(encryptedPrivateKey) if err != nil { - return fmt.Errorf("extracting encrypted key: %w", err) + return err } return nil } diff --git a/internal/configuration/sources/env/helpers.go b/internal/configuration/sources/env/helpers.go index 96a516d0..06a6a9d0 100644 --- a/internal/configuration/sources/env/helpers.go +++ b/internal/configuration/sources/env/helpers.go @@ -1,7 +1,6 @@ package env import ( - "encoding/base64" "fmt" "os" "strconv" @@ -133,15 +132,6 @@ func lowerAndSplit(csv string) (values []string) { return strings.Split(csv, ",") } -func decodeBase64(b64String string) (decoded string, err error) { - b, err := base64.StdEncoding.DecodeString(b64String) - if err != nil { - return "", fmt.Errorf("cannot decode base64 string %q: %w", - b64String, err) - } - return string(b), nil -} - func unsetEnvKeys(envKeys []string, err error) (newErr error) { newErr = err for _, envKey := range envKeys { diff --git a/internal/configuration/sources/env/openvpn.go b/internal/configuration/sources/env/openvpn.go index a5bd3ba5..995e1e14 100644 --- a/internal/configuration/sources/env/openvpn.go +++ b/internal/configuration/sources/env/openvpn.go @@ -31,20 +31,9 @@ func (r *Reader) readOpenVPN() ( openVPN.Auth = &auth } - openVPN.Cert, err = readBase64OrNil("OPENVPN_CERT") - if err != nil { - return openVPN, fmt.Errorf("environment variable OPENVPN_CERT: %w", err) - } - - openVPN.Key, err = readBase64OrNil("OPENVPN_KEY") - if err != nil { - return openVPN, fmt.Errorf("environment variable OPENVPN_KEY: %w", err) - } - - openVPN.EncryptedKey, err = readBase64OrNil("OPENVPN_ENCRYPTED_KEY") - if err != nil { - return openVPN, fmt.Errorf("environment variable OPENVPN_ENCRYPTED_KEY: %w", err) - } + openVPN.Cert = envToStringPtr("OPENVPN_CERT") + openVPN.Key = envToStringPtr("OPENVPN_KEY") + openVPN.EncryptedKey = envToStringPtr("OPENVPN_ENCRYPTED_KEY") openVPN.KeyPassphrase = r.readOpenVPNKeyPassphrase() @@ -111,20 +100,6 @@ func (r *Reader) readOpenVPNKeyPassphrase() (passphrase *string) { return passphrase } -func readBase64OrNil(envKey string) (valueOrNil *string, err error) { - value := getCleanedEnv(envKey) - if value == "" { - return nil, nil //nolint:nilnil - } - - decoded, err := decodeBase64(value) - if err != nil { - return nil, err - } - - return &decoded, nil -} - func (r *Reader) readPIAEncryptionPreset() (presetPtr *string) { _, preset := r.getEnvWithRetro( "PRIVATE_INTERNET_ACCESS_OPENVPN_ENCRYPTION_PRESET", diff --git a/internal/configuration/sources/files/helpers.go b/internal/configuration/sources/files/helpers.go index aba1a5fd..83c5842f 100644 --- a/internal/configuration/sources/files/helpers.go +++ b/internal/configuration/sources/files/helpers.go @@ -1,9 +1,12 @@ package files import ( + "fmt" "io" "os" "strings" + + "github.com/qdm12/gluetun/internal/openvpn/extract" ) // ReadFromFile reads the content of the file as a string. @@ -32,3 +35,21 @@ func ReadFromFile(filepath string) (s *string, err error) { content = strings.TrimSuffix(content, "\n") return &content, nil } + +func readPEMFile(filepath string) (base64Ptr *string, err error) { + pemData, err := ReadFromFile(filepath) + if err != nil { + return nil, fmt.Errorf("reading file: %w", err) + } + + if pemData == nil { + return nil, nil //nolint:nilnil + } + + base64Data, err := extract.PEM([]byte(*pemData)) + if err != nil { + return nil, fmt.Errorf("extracting base64 encoded data from PEM content: %w", err) + } + + return &base64Data, nil +} diff --git a/internal/configuration/sources/files/openvpn.go b/internal/configuration/sources/files/openvpn.go index 896526b7..6bfb3a0e 100644 --- a/internal/configuration/sources/files/openvpn.go +++ b/internal/configuration/sources/files/openvpn.go @@ -15,17 +15,16 @@ const ( ) func (r *Reader) readOpenVPN() (settings settings.OpenVPN, err error) { - settings.Key, err = ReadFromFile(OpenVPNClientKeyPath) + settings.Key, err = readPEMFile(OpenVPNClientKeyPath) if err != nil { return settings, fmt.Errorf("client key: %w", err) } - settings.Cert, err = ReadFromFile(OpenVPNClientCertificatePath) + settings.Cert, err = readPEMFile(OpenVPNClientCertificatePath) if err != nil { return settings, fmt.Errorf("client certificate: %w", err) } - - settings.EncryptedKey, err = ReadFromFile(openVPNEncryptedKey) + settings.EncryptedKey, err = readPEMFile(openVPNEncryptedKey) if err != nil { return settings, fmt.Errorf("reading encrypted key file: %w", err) } diff --git a/internal/configuration/sources/secrets/helpers.go b/internal/configuration/sources/secrets/helpers.go index effa54fb..fba038d6 100644 --- a/internal/configuration/sources/secrets/helpers.go +++ b/internal/configuration/sources/secrets/helpers.go @@ -1,10 +1,12 @@ package secrets import ( + "fmt" "os" "strings" "github.com/qdm12/gluetun/internal/configuration/sources/files" + "github.com/qdm12/gluetun/internal/openvpn/extract" ) // getCleanedEnv returns an environment variable value with @@ -25,3 +27,22 @@ func readSecretFileAsStringPtr(secretPathEnvKey, defaultSecretPath string) ( } return files.ReadFromFile(path) } + +func readPEMSecretFile(secretPathEnvKey, defaultSecretPath string) ( + base64Ptr *string, err error) { + pemData, err := readSecretFileAsStringPtr(secretPathEnvKey, defaultSecretPath) + if err != nil { + return nil, fmt.Errorf("reading secret file: %w", err) + } + + if pemData == nil { + return nil, nil //nolint:nilnil + } + + base64Data, err := extract.PEM([]byte(*pemData)) + if err != nil { + return nil, fmt.Errorf("extracting base64 encoded data from PEM content: %w", err) + } + + return &base64Data, nil +} diff --git a/internal/configuration/sources/secrets/openvpn.go b/internal/configuration/sources/secrets/openvpn.go index 303ad9e7..e1028d5a 100644 --- a/internal/configuration/sources/secrets/openvpn.go +++ b/internal/configuration/sources/secrets/openvpn.go @@ -24,7 +24,7 @@ func readOpenVPN() ( return settings, fmt.Errorf("cannot read password file: %w", err) } - settings.Key, err = readSecretFileAsStringPtr( + settings.Key, err = readPEMSecretFile( "OPENVPN_CLIENTKEY_SECRETFILE", "/run/secrets/openvpn_clientkey", ) @@ -32,7 +32,7 @@ func readOpenVPN() ( return settings, fmt.Errorf("cannot read client key file: %w", err) } - settings.EncryptedKey, err = readSecretFileAsStringPtr( + settings.EncryptedKey, err = readPEMSecretFile( "OPENVPN_ENCRYPTED_KEY_SECRETFILE", "/run/secrets/openvpn_encrypted_key", ) @@ -48,7 +48,7 @@ func readOpenVPN() ( return settings, fmt.Errorf("reading key passphrase file: %w", err) } - settings.Cert, err = readSecretFileAsStringPtr( + settings.Cert, err = readPEMSecretFile( "OPENVPN_CLIENTCRT_SECRETFILE", "/run/secrets/openvpn_clientcrt", ) diff --git a/internal/provider/utils/openvpn.go b/internal/provider/utils/openvpn.go index 357f778e..077278da 100644 --- a/internal/provider/utils/openvpn.go +++ b/internal/provider/utils/openvpn.go @@ -8,7 +8,6 @@ import ( "github.com/qdm12/gluetun/internal/constants" "github.com/qdm12/gluetun/internal/constants/openvpn" "github.com/qdm12/gluetun/internal/models" - "github.com/qdm12/gluetun/internal/openvpn/extract" ) type OpenVPNProviderSettings struct { @@ -191,21 +190,15 @@ func OpenVPNConfig(provider OpenVPNProviderSettings, if *settings.EncryptedKey != "" { lines.add("askpass", openvpn.AskPassPath) - keyData, err := extract.PEM([]byte(*settings.EncryptedKey)) - panicOnError(err, "cannot extract PEM encrypted key") - lines.addLines(WrapOpenvpnEncryptedKey(keyData)) + lines.addLines(WrapOpenvpnEncryptedKey(*settings.EncryptedKey)) } if *settings.Cert != "" { - certData, err := extract.PEM([]byte(*settings.Cert)) - panicOnError(err, "cannot extract OpenVPN certificate") - lines.addLines(WrapOpenvpnCert(certData)) + lines.addLines(WrapOpenvpnCert(*settings.Cert)) } if *settings.Key != "" { - keyData, err := extract.PEM([]byte(*settings.Key)) - panicOnError(err, "cannot extract OpenVPN key") - lines.addLines(WrapOpenvpnKey(keyData)) + lines.addLines(WrapOpenvpnKey(*settings.Key)) } lines.addLines(provider.ExtraLines) @@ -254,14 +247,6 @@ func defaultStringSlice(value, defaultValue []string) ( return result } -func panicOnError(err error, context string) { - if err == nil { - return - } - panicMessage := fmt.Sprintf("%s: %s", context, err) - panic(panicMessage) -} - func WrapOpenvpnCA(certificate string) (lines []string) { return []string{ "",