Skip to content

Commit

Permalink
fix(settings): read PEM files but b64 env vars
Browse files Browse the repository at this point in the history
- Extract base64 data from PEM files and secret files
- Environment variables are not PEM encoded and only the base64 data
- Affects OpenVPN certificate, key and encrypted key
  • Loading branch information
qdm12 committed Aug 24, 2022
1 parent 0413a0a commit 732f826
Show file tree
Hide file tree
Showing 8 changed files with 53 additions and 54 deletions.
5 changes: 3 additions & 2 deletions internal/configuration/settings/openvpn.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package settings

import (
"encoding/base64"
"fmt"
"regexp"
"strings"
Expand Down Expand Up @@ -172,7 +173,7 @@ func validateOpenVPNClientCertificate(vpnProvider,
return nil
}

_, err = extract.PEM([]byte(clientCert))
_, err = base64.StdEncoding.DecodeString(clientCert)
if err != nil {
return err
}
Expand All @@ -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
}
Expand Down
10 changes: 0 additions & 10 deletions internal/configuration/sources/env/helpers.go
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
package env

import (
"encoding/base64"
"fmt"
"os"
"strconv"
Expand Down Expand Up @@ -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 {
Expand Down
25 changes: 2 additions & 23 deletions internal/configuration/sources/env/openvpn.go
Original file line number Diff line number Diff line change
Expand Up @@ -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()

Expand Down Expand Up @@ -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",
Expand Down
21 changes: 21 additions & 0 deletions internal/configuration/sources/files/helpers.go
Original file line number Diff line number Diff line change
@@ -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.
Expand Down Expand Up @@ -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
}
4 changes: 2 additions & 2 deletions internal/configuration/sources/files/openvpn.go
Original file line number Diff line number Diff line change
Expand Up @@ -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)
}
Expand Down
21 changes: 21 additions & 0 deletions internal/configuration/sources/secrets/helpers.go
Original file line number Diff line number Diff line change
@@ -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
Expand Down Expand Up @@ -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
}
4 changes: 2 additions & 2 deletions internal/configuration/sources/secrets/openvpn.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,15 +24,15 @@ 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",
)
if err != nil {
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",
)
Expand Down
17 changes: 2 additions & 15 deletions internal/provider/utils/openvpn.go
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand Down Expand Up @@ -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)
Expand Down Expand Up @@ -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{
"<ca>",
Expand Down

0 comments on commit 732f826

Please sign in to comment.