Simplified provider object creation

This commit is contained in:
Quentin McGaw
2020-07-13 23:34:03 +00:00
parent 618441b008
commit 2f955e0190
8 changed files with 65 additions and 90 deletions

View File

@@ -10,6 +10,7 @@ import (
"github.com/qdm12/golibs/files" "github.com/qdm12/golibs/files"
"github.com/qdm12/golibs/logging" "github.com/qdm12/golibs/logging"
"github.com/qdm12/golibs/network" "github.com/qdm12/golibs/network"
"github.com/qdm12/private-internet-access-docker/internal/constants"
"github.com/qdm12/private-internet-access-docker/internal/firewall" "github.com/qdm12/private-internet-access-docker/internal/firewall"
"github.com/qdm12/private-internet-access-docker/internal/models" "github.com/qdm12/private-internet-access-docker/internal/models"
"github.com/qdm12/private-internet-access-docker/internal/provider" "github.com/qdm12/private-internet-access-docker/internal/provider"
@@ -69,10 +70,10 @@ func (l *looper) Run(ctx context.Context, restart, portForward <-chan struct{},
defer l.logger.Warn("loop exited") defer l.logger.Warn("loop exited")
for ctx.Err() == nil { for ctx.Err() == nil {
providerConf := provider.New(l.provider, l.client, l.fileManager) providerConf := provider.New(l.provider)
connections, err := providerConf.GetOpenVPNConnections(l.settings.Provider.ServerSelection) connections, err := providerConf.GetOpenVPNConnections(l.settings.Provider.ServerSelection)
l.fatalOnError(err) l.fatalOnError(err)
err = providerConf.BuildConf( lines := providerConf.BuildConf(
connections, connections,
l.settings.Verbosity, l.settings.Verbosity,
l.uid, l.uid,
@@ -82,6 +83,7 @@ func (l *looper) Run(ctx context.Context, restart, portForward <-chan struct{},
l.settings.Auth, l.settings.Auth,
l.settings.Provider.ExtraConfigOptions, l.settings.Provider.ExtraConfigOptions,
) )
err = l.fileManager.WriteLinesToFile(string(constants.OpenVPNConf), lines, files.Ownership(l.uid, l.gid), files.Permissions(0400))
l.fatalOnError(err) l.fatalOnError(err)
err = l.conf.WriteAuthFile(l.settings.User, l.settings.Password, l.uid, l.gid) err = l.conf.WriteAuthFile(l.settings.User, l.settings.Password, l.uid, l.gid)
@@ -106,7 +108,7 @@ func (l *looper) Run(ctx context.Context, restart, portForward <-chan struct{},
case <-ctx.Done(): case <-ctx.Done():
return return
case <-portForward: case <-portForward:
l.portForward(ctx, providerConf) l.portForward(ctx, providerConf, l.client)
} }
} }
}(openvpnCtx) }(openvpnCtx)
@@ -145,7 +147,7 @@ func (l *looper) logAndWait(ctx context.Context, err error) {
<-ctx.Done() <-ctx.Done()
} }
func (l *looper) portForward(ctx context.Context, providerConf provider.Provider) { func (l *looper) portForward(ctx context.Context, providerConf provider.Provider, client network.Client) {
if !l.settings.Provider.PortForwarding.Enabled { if !l.settings.Provider.PortForwarding.Enabled {
return return
} }
@@ -155,7 +157,7 @@ func (l *looper) portForward(ctx context.Context, providerConf provider.Provider
if ctx.Err() != nil { if ctx.Err() != nil {
return return
} }
port, err = providerConf.GetPortForward() port, err = providerConf.GetPortForward(client)
if err != nil { if err != nil {
l.logAndWait(ctx, err) l.logAndWait(ctx, err)
continue continue

View File

@@ -5,17 +5,15 @@ import (
"net" "net"
"strings" "strings"
"github.com/qdm12/golibs/files" "github.com/qdm12/golibs/network"
"github.com/qdm12/private-internet-access-docker/internal/constants" "github.com/qdm12/private-internet-access-docker/internal/constants"
"github.com/qdm12/private-internet-access-docker/internal/models" "github.com/qdm12/private-internet-access-docker/internal/models"
) )
type cyberghost struct { type cyberghost struct{}
fileManager files.FileManager
}
func newCyberghost(fileManager files.FileManager) *cyberghost { func newCyberghost() *cyberghost {
return &cyberghost{fileManager: fileManager} return &cyberghost{}
} }
func (c *cyberghost) GetOpenVPNConnections(selection models.ServerSelection) (connections []models.OpenVPNConnection, err error) { func (c *cyberghost) GetOpenVPNConnections(selection models.ServerSelection) (connections []models.OpenVPNConnection, err error) {
@@ -47,14 +45,14 @@ func (c *cyberghost) GetOpenVPNConnections(selection models.ServerSelection) (co
return connections, nil return connections, nil
} }
func (c *cyberghost) BuildConf(connections []models.OpenVPNConnection, verbosity, uid, gid int, root bool, cipher, auth string, extras models.ExtraConfigOptions) (err error) { func (c *cyberghost) BuildConf(connections []models.OpenVPNConnection, verbosity, uid, gid int, root bool, cipher, auth string, extras models.ExtraConfigOptions) (lines []string) {
if len(cipher) == 0 { if len(cipher) == 0 {
cipher = aes256cbc cipher = aes256cbc
} }
if len(auth) == 0 { if len(auth) == 0 {
auth = "SHA256" auth = "SHA256"
} }
lines := []string{ lines = []string{
"client", "client",
"dev tun", "dev tun",
"nobind", "nobind",
@@ -116,9 +114,9 @@ func (c *cyberghost) BuildConf(connections []models.OpenVPNConnection, verbosity
"</key>", "</key>",
"", "",
}...) }...)
return c.fileManager.WriteLinesToFile(string(constants.OpenVPNConf), lines, files.Ownership(uid, gid), files.Permissions(0400)) return lines
} }
func (c *cyberghost) GetPortForward() (port uint16, err error) { func (c *cyberghost) GetPortForward(client network.Client) (port uint16, err error) {
panic("port forwarding is not supported for cyberghost") panic("port forwarding is not supported for cyberghost")
} }

View File

@@ -3,19 +3,15 @@ package provider
import ( import (
"fmt" "fmt"
"github.com/qdm12/golibs/files" "github.com/qdm12/golibs/network"
"github.com/qdm12/private-internet-access-docker/internal/constants" "github.com/qdm12/private-internet-access-docker/internal/constants"
"github.com/qdm12/private-internet-access-docker/internal/models" "github.com/qdm12/private-internet-access-docker/internal/models"
) )
type mullvad struct { type mullvad struct{}
fileManager files.FileManager
}
func newMullvad(fileManager files.FileManager) *mullvad { func newMullvad() *mullvad {
return &mullvad{ return &mullvad{}
fileManager: fileManager,
}
} }
func (m *mullvad) GetOpenVPNConnections(selection models.ServerSelection) (connections []models.OpenVPNConnection, err error) { func (m *mullvad) GetOpenVPNConnections(selection models.ServerSelection) (connections []models.OpenVPNConnection, err error) {
@@ -44,14 +40,11 @@ func (m *mullvad) GetOpenVPNConnections(selection models.ServerSelection) (conne
return connections, nil return connections, nil
} }
func (m *mullvad) BuildConf(connections []models.OpenVPNConnection, verbosity, uid, gid int, root bool, cipher, auth string, extras models.ExtraConfigOptions) (err error) { func (m *mullvad) BuildConf(connections []models.OpenVPNConnection, verbosity, uid, gid int, root bool, cipher, auth string, extras models.ExtraConfigOptions) (lines []string) {
if len(connections) == 0 {
return fmt.Errorf("at least one connection string is expected")
}
if len(cipher) == 0 { if len(cipher) == 0 {
cipher = aes256cbc cipher = aes256cbc
} }
lines := []string{ lines = []string{
"client", "client",
"dev tun", "dev tun",
"nobind", "nobind",
@@ -96,9 +89,9 @@ func (m *mullvad) BuildConf(connections []models.OpenVPNConnection, verbosity, u
"</ca>", "</ca>",
"", "",
}...) }...)
return m.fileManager.WriteLinesToFile(string(constants.OpenVPNConf), lines, files.Ownership(uid, gid), files.Permissions(0400)) return lines
} }
func (m *mullvad) GetPortForward() (port uint16, err error) { func (m *mullvad) GetPortForward(client network.Client) (port uint16, err error) {
panic("port forwarding is not supported for mullvad") panic("port forwarding is not supported for mullvad")
} }

View File

@@ -9,28 +9,19 @@ import (
"strings" "strings"
"github.com/qdm12/golibs/crypto/random" "github.com/qdm12/golibs/crypto/random"
"github.com/qdm12/golibs/files"
"github.com/qdm12/golibs/network" "github.com/qdm12/golibs/network"
"github.com/qdm12/golibs/verification"
"github.com/qdm12/private-internet-access-docker/internal/constants" "github.com/qdm12/private-internet-access-docker/internal/constants"
"github.com/qdm12/private-internet-access-docker/internal/models" "github.com/qdm12/private-internet-access-docker/internal/models"
) )
type pia struct { type pia struct {
client network.Client random random.Random
fileManager files.FileManager
random random.Random
verifyPort func(port string) error
lookupIP func(host string) ([]net.IP, error)
} }
func newPrivateInternetAccess(client network.Client, fileManager files.FileManager) *pia { func newPrivateInternetAccess() *pia {
return &pia{ return &pia{
client: client, random: random.NewRandom(),
fileManager: fileManager, }
random: random.NewRandom(),
verifyPort: verification.NewVerifier().VerifyPort,
lookupIP: net.LookupIP}
} }
func (p *pia) GetOpenVPNConnections(selection models.ServerSelection) (connections []models.OpenVPNConnection, err error) { func (p *pia) GetOpenVPNConnections(selection models.ServerSelection) (connections []models.OpenVPNConnection, err error) {
@@ -82,7 +73,7 @@ func (p *pia) GetOpenVPNConnections(selection models.ServerSelection) (connectio
return connections, nil return connections, nil
} }
func (p *pia) BuildConf(connections []models.OpenVPNConnection, verbosity, uid, gid int, root bool, cipher, auth string, extras models.ExtraConfigOptions) (err error) { func (p *pia) BuildConf(connections []models.OpenVPNConnection, verbosity, uid, gid int, root bool, cipher, auth string, extras models.ExtraConfigOptions) (lines []string) {
var X509CRL, certificate string var X509CRL, certificate string
if extras.EncryptionPreset == constants.PIAEncryptionPresetNormal { if extras.EncryptionPreset == constants.PIAEncryptionPresetNormal {
if len(cipher) == 0 { if len(cipher) == 0 {
@@ -103,7 +94,7 @@ func (p *pia) BuildConf(connections []models.OpenVPNConnection, verbosity, uid,
X509CRL = constants.PiaX509CRLStrong X509CRL = constants.PiaX509CRLStrong
certificate = constants.PIACertificateStrong certificate = constants.PIACertificateStrong
} }
lines := []string{ lines = []string{
"client", "client",
"dev tun", "dev tun",
"nobind", "nobind",
@@ -154,17 +145,17 @@ func (p *pia) BuildConf(connections []models.OpenVPNConnection, verbosity, uid,
"</ca>", "</ca>",
"", "",
}...) }...)
return p.fileManager.WriteLinesToFile(string(constants.OpenVPNConf), lines, files.Ownership(uid, gid), files.Permissions(0400)) return lines
} }
func (p *pia) GetPortForward() (port uint16, err error) { func (p *pia) GetPortForward(client network.Client) (port uint16, err error) {
b, err := p.random.GenerateRandomBytes(32) b, err := p.random.GenerateRandomBytes(32)
if err != nil { if err != nil {
return 0, err return 0, err
} }
clientID := hex.EncodeToString(b) clientID := hex.EncodeToString(b)
url := fmt.Sprintf("%s/?client_id=%s", constants.PIAPortForwardURL, clientID) url := fmt.Sprintf("%s/?client_id=%s", constants.PIAPortForwardURL, clientID)
content, status, err := p.client.GetContent(url) // TODO add ctx content, status, err := client.GetContent(url) // TODO add ctx
switch { switch {
case err != nil: case err != nil:
return 0, err return 0, err

View File

@@ -1,7 +1,6 @@
package provider package provider
import ( import (
"github.com/qdm12/golibs/files"
"github.com/qdm12/golibs/network" "github.com/qdm12/golibs/network"
"github.com/qdm12/private-internet-access-docker/internal/constants" "github.com/qdm12/private-internet-access-docker/internal/constants"
"github.com/qdm12/private-internet-access-docker/internal/models" "github.com/qdm12/private-internet-access-docker/internal/models"
@@ -10,24 +9,24 @@ import (
// Provider contains methods to read and modify the openvpn configuration to connect as a client // Provider contains methods to read and modify the openvpn configuration to connect as a client
type Provider interface { type Provider interface {
GetOpenVPNConnections(selection models.ServerSelection) (connections []models.OpenVPNConnection, err error) GetOpenVPNConnections(selection models.ServerSelection) (connections []models.OpenVPNConnection, err error)
BuildConf(connections []models.OpenVPNConnection, verbosity, uid, gid int, root bool, cipher, auth string, extras models.ExtraConfigOptions) (err error) BuildConf(connections []models.OpenVPNConnection, verbosity, uid, gid int, root bool, cipher, auth string, extras models.ExtraConfigOptions) (lines []string)
GetPortForward() (port uint16, err error) GetPortForward(client network.Client) (port uint16, err error)
} }
func New(provider models.VPNProvider, client network.Client, fileManager files.FileManager) Provider { func New(provider models.VPNProvider) Provider {
switch provider { switch provider {
case constants.PrivateInternetAccess: case constants.PrivateInternetAccess:
return newPrivateInternetAccess(client, fileManager) return newPrivateInternetAccess()
case constants.Mullvad: case constants.Mullvad:
return newMullvad(fileManager) return newMullvad()
case constants.Windscribe: case constants.Windscribe:
return newWindscribe(fileManager) return newWindscribe()
case constants.Surfshark: case constants.Surfshark:
return newSurfshark(fileManager) return newSurfshark()
case constants.Cyberghost: case constants.Cyberghost:
return newCyberghost(fileManager) return newCyberghost()
case constants.Vyprvpn: case constants.Vyprvpn:
return newVyprvpn(fileManager) return newVyprvpn()
default: default:
return nil // should never occur return nil // should never occur
} }

View File

@@ -5,18 +5,15 @@ import (
"net" "net"
"strings" "strings"
"github.com/qdm12/golibs/files" "github.com/qdm12/golibs/network"
"github.com/qdm12/private-internet-access-docker/internal/constants" "github.com/qdm12/private-internet-access-docker/internal/constants"
"github.com/qdm12/private-internet-access-docker/internal/models" "github.com/qdm12/private-internet-access-docker/internal/models"
) )
type surfshark struct { type surfshark struct{}
fileManager files.FileManager
lookupIP func(host string) ([]net.IP, error)
}
func newSurfshark(fileManager files.FileManager) *surfshark { func newSurfshark() *surfshark {
return &surfshark{fileManager, net.LookupIP} return &surfshark{}
} }
func (s *surfshark) GetOpenVPNConnections(selection models.ServerSelection) (connections []models.OpenVPNConnection, err error) { func (s *surfshark) GetOpenVPNConnections(selection models.ServerSelection) (connections []models.OpenVPNConnection, err error) {
@@ -57,14 +54,14 @@ func (s *surfshark) GetOpenVPNConnections(selection models.ServerSelection) (con
return connections, nil return connections, nil
} }
func (s *surfshark) BuildConf(connections []models.OpenVPNConnection, verbosity, uid, gid int, root bool, cipher, auth string, extras models.ExtraConfigOptions) (err error) { func (s *surfshark) BuildConf(connections []models.OpenVPNConnection, verbosity, uid, gid int, root bool, cipher, auth string, extras models.ExtraConfigOptions) (lines []string) {
if len(cipher) == 0 { if len(cipher) == 0 {
cipher = aes256cbc cipher = aes256cbc
} }
if len(auth) == 0 { if len(auth) == 0 {
auth = "SHA512" auth = "SHA512"
} }
lines := []string{ lines = []string{
"client", "client",
"dev tun", "dev tun",
"nobind", "nobind",
@@ -119,9 +116,9 @@ func (s *surfshark) BuildConf(connections []models.OpenVPNConnection, verbosity,
"</tls-auth>", "</tls-auth>",
"", "",
}...) }...)
return s.fileManager.WriteLinesToFile(string(constants.OpenVPNConf), lines, files.Ownership(uid, gid), files.Permissions(0400)) return lines
} }
func (s *surfshark) GetPortForward() (port uint16, err error) { func (s *surfshark) GetPortForward(client network.Client) (port uint16, err error) {
panic("port forwarding is not supported for surfshark") panic("port forwarding is not supported for surfshark")
} }

View File

@@ -5,18 +5,15 @@ import (
"net" "net"
"strings" "strings"
"github.com/qdm12/golibs/files" "github.com/qdm12/golibs/network"
"github.com/qdm12/private-internet-access-docker/internal/constants" "github.com/qdm12/private-internet-access-docker/internal/constants"
"github.com/qdm12/private-internet-access-docker/internal/models" "github.com/qdm12/private-internet-access-docker/internal/models"
) )
type vyprvpn struct { type vyprvpn struct{}
fileManager files.FileManager
lookupIP func(host string) ([]net.IP, error)
}
func newVyprvpn(fileManager files.FileManager) *vyprvpn { func newVyprvpn() *vyprvpn {
return &vyprvpn{fileManager, net.LookupIP} return &vyprvpn{}
} }
func (s *vyprvpn) GetOpenVPNConnections(selection models.ServerSelection) (connections []models.OpenVPNConnection, err error) { func (s *vyprvpn) GetOpenVPNConnections(selection models.ServerSelection) (connections []models.OpenVPNConnection, err error) {
@@ -57,14 +54,14 @@ func (s *vyprvpn) GetOpenVPNConnections(selection models.ServerSelection) (conne
return connections, nil return connections, nil
} }
func (s *vyprvpn) BuildConf(connections []models.OpenVPNConnection, verbosity, uid, gid int, root bool, cipher, auth string, extras models.ExtraConfigOptions) (err error) { func (s *vyprvpn) BuildConf(connections []models.OpenVPNConnection, verbosity, uid, gid int, root bool, cipher, auth string, extras models.ExtraConfigOptions) (lines []string) {
if len(cipher) == 0 { if len(cipher) == 0 {
cipher = aes256cbc cipher = aes256cbc
} }
if len(auth) == 0 { if len(auth) == 0 {
auth = "SHA256" auth = "SHA256"
} }
lines := []string{ lines = []string{
"client", "client",
"dev tun", "dev tun",
"nobind", "nobind",
@@ -105,9 +102,9 @@ func (s *vyprvpn) BuildConf(connections []models.OpenVPNConnection, verbosity, u
"-----END CERTIFICATE-----", "-----END CERTIFICATE-----",
"</ca>", "</ca>",
}...) }...)
return s.fileManager.WriteLinesToFile(string(constants.OpenVPNConf), lines, files.Ownership(uid, gid), files.Permissions(0400)) return lines
} }
func (s *vyprvpn) GetPortForward() (port uint16, err error) { func (s *vyprvpn) GetPortForward(client network.Client) (port uint16, err error) {
panic("port forwarding is not supported for vyprvpn") panic("port forwarding is not supported for vyprvpn")
} }

View File

@@ -5,17 +5,15 @@ import (
"net" "net"
"strings" "strings"
"github.com/qdm12/golibs/files" "github.com/qdm12/golibs/network"
"github.com/qdm12/private-internet-access-docker/internal/constants" "github.com/qdm12/private-internet-access-docker/internal/constants"
"github.com/qdm12/private-internet-access-docker/internal/models" "github.com/qdm12/private-internet-access-docker/internal/models"
) )
type windscribe struct { type windscribe struct{}
fileManager files.FileManager
}
func newWindscribe(fileManager files.FileManager) *windscribe { func newWindscribe() *windscribe {
return &windscribe{fileManager: fileManager} return &windscribe{}
} }
func (w *windscribe) GetOpenVPNConnections(selection models.ServerSelection) (connections []models.OpenVPNConnection, err error) { func (w *windscribe) GetOpenVPNConnections(selection models.ServerSelection) (connections []models.OpenVPNConnection, err error) {
@@ -58,14 +56,14 @@ func (w *windscribe) GetOpenVPNConnections(selection models.ServerSelection) (co
return connections, nil return connections, nil
} }
func (w *windscribe) BuildConf(connections []models.OpenVPNConnection, verbosity, uid, gid int, root bool, cipher, auth string, extras models.ExtraConfigOptions) (err error) { func (w *windscribe) BuildConf(connections []models.OpenVPNConnection, verbosity, uid, gid int, root bool, cipher, auth string, extras models.ExtraConfigOptions) (lines []string) {
if len(cipher) == 0 { if len(cipher) == 0 {
cipher = aes256cbc cipher = aes256cbc
} }
if len(auth) == 0 { if len(auth) == 0 {
auth = "sha512" auth = "sha512"
} }
lines := []string{ lines = []string{
"client", "client",
"dev tun", "dev tun",
"nobind", "nobind",
@@ -116,9 +114,9 @@ func (w *windscribe) BuildConf(connections []models.OpenVPNConnection, verbosity
"</tls-auth>", "</tls-auth>",
"", "",
}...) }...)
return w.fileManager.WriteLinesToFile(string(constants.OpenVPNConf), lines, files.Ownership(uid, gid), files.Permissions(0400)) return lines
} }
func (w *windscribe) GetPortForward() (port uint16, err error) { func (w *windscribe) GetPortForward(client network.Client) (port uint16, err error) {
panic("port forwarding is not supported for windscribe") panic("port forwarding is not supported for windscribe")
} }