feat(pia): port forwarding options VPN_PORT_FORWARDING_USERNAME and VPN_PORT_FORWARDING_PASSWORD

- Retro-compatible with `OPENVPN_USER` + `OPENVPN_PASSWORD`
- No more reading for the OpenVPN auth file
- Allow to use PIA port forwarding with Wireguard
This commit is contained in:
Quentin McGaw
2024-07-09 14:44:46 +00:00
parent 06c9bc55d3
commit 0501743814
11 changed files with 69 additions and 45 deletions

View File

@@ -32,6 +32,10 @@ func (p *Provider) PortForward(ctx context.Context,
panic("server name cannot be empty")
case !objects.Gateway.IsValid():
panic("gateway is not set")
case objects.Username == "":
panic("username is not set")
case objects.Password == "":
panic("password is not set")
}
serverName := objects.ServerName
@@ -67,7 +71,7 @@ func (p *Provider) PortForward(ctx context.Context,
if !dataFound || expired {
client := objects.Client
data, err = refreshPIAPortForwardData(ctx, client, privateIPClient, objects.Gateway,
p.portForwardPath, p.authFilePath)
p.portForwardPath, objects.Username, objects.Password)
if err != nil {
return 0, fmt.Errorf("refreshing port forward data: %w", err)
}
@@ -136,8 +140,8 @@ func (p *Provider) KeepPortForward(ctx context.Context,
}
func refreshPIAPortForwardData(ctx context.Context, client, privateIPClient *http.Client,
gateway netip.Addr, portForwardPath, authFilePath string) (data piaPortForwardData, err error) {
data.Token, err = fetchToken(ctx, client, authFilePath)
gateway netip.Addr, portForwardPath, username, password string) (data piaPortForwardData, err error) {
data.Token, err = fetchToken(ctx, client, username, password)
if err != nil {
return data, fmt.Errorf("fetching token: %w", err)
}
@@ -237,12 +241,7 @@ var (
)
func fetchToken(ctx context.Context, client *http.Client,
authFilePath string) (token string, err error) {
username, password, err := getOpenvpnCredentials(authFilePath)
if err != nil {
return "", fmt.Errorf("getting username and password: %w", err)
}
username, password string) (token string, err error) {
errSubstitutions := map[string]string{
url.QueryEscape(username): "<username>",
url.QueryEscape(password): "<password>",
@@ -287,37 +286,6 @@ func fetchToken(ctx context.Context, client *http.Client,
return result.Token, nil
}
var (
errAuthFileMalformed = errors.New("authentication file is malformed")
)
func getOpenvpnCredentials(authFilePath string) (
username, password string, err error) {
file, err := os.Open(authFilePath)
if err != nil {
return "", "", fmt.Errorf("reading OpenVPN authentication file: %w", err)
}
authData, err := io.ReadAll(file)
if err != nil {
_ = file.Close()
return "", "", fmt.Errorf("reading authentication file: %w", err)
}
if err := file.Close(); err != nil {
return "", "", err
}
lines := strings.Split(string(authData), "\n")
const minLines = 2
if len(lines) < minLines {
return "", "", fmt.Errorf("%w: only %d lines exist", errAuthFileMalformed, len(lines))
}
username, password = lines[0], lines[1]
return username, password, nil
}
func fetchPortForwardData(ctx context.Context, client *http.Client, gateway netip.Addr, token string) (
port uint16, signature string, expiration time.Time, err error) {
errSubstitutions := map[string]string{url.QueryEscape(token): "<token>"}

View File

@@ -5,7 +5,6 @@ import (
"net/http"
"time"
"github.com/qdm12/gluetun/internal/constants/openvpn"
"github.com/qdm12/gluetun/internal/constants/providers"
"github.com/qdm12/gluetun/internal/provider/common"
"github.com/qdm12/gluetun/internal/provider/privateinternetaccess/updater"
@@ -18,7 +17,6 @@ type Provider struct {
common.Fetcher
// Port forwarding
portForwardPath string
authFilePath string
}
func New(storage common.Storage, randSource rand.Source,
@@ -29,7 +27,6 @@ func New(storage common.Storage, randSource rand.Source,
timeNow: timeNow,
randSource: randSource,
portForwardPath: jsonPortForwardPath,
authFilePath: openvpn.AuthConf,
Fetcher: updater.New(client),
}
}

View File

@@ -19,6 +19,10 @@ type PortForwardObjects struct {
ServerName string
// CanPortForward is used by Private Internet Access for port forwarding.
CanPortForward bool
// Username is used by Private Internet Access for port forwarding.
Username string
// Password is used by Private Internet Access for port forwarding.
Password string
}
type Routing interface {