diff --git a/internal/configuration/settings/openvpn.go b/internal/configuration/settings/openvpn.go index 95be2c3e..51983e4a 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" @@ -172,7 +173,7 @@ func validateOpenVPNClientCertificate(vpnProvider, return nil } - _, err = extract.PEM([]byte(clientCert)) + _, err = base64.StdEncoding.DecodeString(clientCert) if err != nil { return err } @@ -194,7 +195,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 } 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 a0499bdc..bd9095ea 100644 --- a/internal/configuration/sources/env/openvpn.go +++ b/internal/configuration/sources/env/openvpn.go @@ -30,15 +30,8 @@ func (r *Reader) readOpenVPN() ( openVPN.Auth = &auth } - openVPN.ClientCrt, err = readBase64OrNil("OPENVPN_CLIENTCRT") - if err != nil { - return openVPN, fmt.Errorf("environment variable OPENVPN_CLIENTCRT: %w", err) - } - - openVPN.ClientKey, err = readBase64OrNil("OPENVPN_CLIENTKEY") - if err != nil { - return openVPN, fmt.Errorf("environment variable OPENVPN_CLIENTKEY: %w", err) - } + openVPN.ClientCrt = envToStringPtr("OPENVPN_CLIENTCRT") + openVPN.ClientKey = envToStringPtr("OPENVPN_CLIENTKEY") openVPN.PIAEncPreset = r.readPIAEncryptionPreset() @@ -83,20 +76,6 @@ func (r *Reader) readOpenVPNPassword() (password string) { return password } -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 e3183a8b..fd6e3d69 100644 --- a/internal/configuration/sources/files/openvpn.go +++ b/internal/configuration/sources/files/openvpn.go @@ -14,12 +14,12 @@ const ( ) func (r *Reader) readOpenVPN() (settings settings.OpenVPN, err error) { - settings.ClientKey, err = ReadFromFile(OpenVPNClientKeyPath) + settings.ClientKey, err = readPEMFile(OpenVPNClientKeyPath) if err != nil { return settings, fmt.Errorf("client key: %w", err) } - settings.ClientCrt, err = ReadFromFile(OpenVPNClientCertificatePath) + settings.ClientCrt, err = readPEMFile(OpenVPNClientCertificatePath) if err != nil { return settings, fmt.Errorf("client certificate: %w", err) } diff --git a/internal/configuration/sources/secrets/helpers.go b/internal/configuration/sources/secrets/helpers.go index 905a9c99..11b71c7b 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 @@ -40,3 +42,22 @@ func readSecretFileAsString(secretPathEnvKey, defaultSecretPath string) ( } return *stringPtr, nil } + +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 f10dbe92..05d878ee 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.ClientKey, err = readSecretFileAsStringPtr( + settings.ClientKey, 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.ClientCrt, err = readSecretFileAsStringPtr( + settings.ClientCrt, err = readPEMSecretFile( "OPENVPN_CLIENTCRT_SECRETFILE", "/run/secrets/openvpn_clientcrt", ) diff --git a/internal/provider/utils/openvpn.go b/internal/provider/utils/openvpn.go index 38773d29..077a0b2c 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 { @@ -190,15 +189,11 @@ func OpenVPNConfig(provider OpenVPNProviderSettings, } if *settings.ClientCrt != "" { - certData, err := extract.PEM([]byte(*settings.ClientCrt)) - panicOnError(err, "cannot extract client crt") - lines.addLines(WrapOpenvpnCert(certData)) + lines.addLines(WrapOpenvpnCert(*settings.ClientCrt)) } if *settings.ClientKey != "" { - keyData, err := extract.PEM([]byte(*settings.ClientKey)) - panicOnError(err, "cannot extract client private key") - lines.addLines(WrapOpenvpnKey(keyData)) + lines.addLines(WrapOpenvpnKey(*settings.ClientKey)) } lines.addLines(provider.ExtraLines) @@ -247,14 +242,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{ "",