Maint: move OpenVPN configurator to openvpn/config
This commit is contained in:
69
internal/openvpn/config/auth.go
Normal file
69
internal/openvpn/config/auth.go
Normal file
@@ -0,0 +1,69 @@
|
||||
package config
|
||||
|
||||
import (
|
||||
"io"
|
||||
"os"
|
||||
"strings"
|
||||
)
|
||||
|
||||
type AuthWriter interface {
|
||||
WriteAuthFile(user, password string) error
|
||||
}
|
||||
|
||||
// WriteAuthFile writes the OpenVPN auth file to disk with the right permissions.
|
||||
func (c *configurator) WriteAuthFile(user, password string) error {
|
||||
file, err := os.Open(c.authFilePath)
|
||||
|
||||
if err != nil && !os.IsNotExist(err) {
|
||||
return err
|
||||
}
|
||||
|
||||
if os.IsNotExist(err) {
|
||||
file, err = os.OpenFile(c.authFilePath, os.O_WRONLY|os.O_CREATE, 0400)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
_, err = file.WriteString(user + "\n" + password)
|
||||
if err != nil {
|
||||
_ = file.Close()
|
||||
return err
|
||||
}
|
||||
err = file.Chown(c.puid, c.pgid)
|
||||
if err != nil {
|
||||
_ = file.Close()
|
||||
return err
|
||||
}
|
||||
return file.Close()
|
||||
}
|
||||
|
||||
data, err := io.ReadAll(file)
|
||||
if err != nil {
|
||||
_ = file.Close()
|
||||
return err
|
||||
}
|
||||
if err := file.Close(); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
lines := strings.Split(string(data), "\n")
|
||||
if len(lines) > 1 && lines[0] == user && lines[1] == password {
|
||||
return nil
|
||||
}
|
||||
|
||||
c.logger.Info("username and password changed in " + c.authFilePath)
|
||||
file, err = os.OpenFile(c.authFilePath, os.O_TRUNC|os.O_WRONLY, 0400)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
_, err = file.WriteString(user + "\n" + password)
|
||||
if err != nil {
|
||||
_ = file.Close()
|
||||
return err
|
||||
}
|
||||
err = file.Chown(c.puid, c.pgid)
|
||||
if err != nil {
|
||||
_ = file.Close()
|
||||
return err
|
||||
}
|
||||
return file.Close()
|
||||
}
|
||||
76
internal/openvpn/config/command.go
Normal file
76
internal/openvpn/config/command.go
Normal file
@@ -0,0 +1,76 @@
|
||||
package config
|
||||
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"fmt"
|
||||
"os/exec"
|
||||
"strings"
|
||||
"syscall"
|
||||
|
||||
"github.com/qdm12/gluetun/internal/constants"
|
||||
)
|
||||
|
||||
var ErrVersionUnknown = errors.New("OpenVPN version is unknown")
|
||||
|
||||
const (
|
||||
binOpenvpn24 = "openvpn2.4"
|
||||
binOpenvpn25 = "openvpn"
|
||||
)
|
||||
|
||||
type Starter interface {
|
||||
Start(ctx context.Context, version string, flags []string) (
|
||||
stdoutLines, stderrLines chan string, waitError chan error, err error)
|
||||
}
|
||||
|
||||
func (c *configurator) Start(ctx context.Context, version string, flags []string) (
|
||||
stdoutLines, stderrLines chan string, waitError chan error, err error) {
|
||||
var bin string
|
||||
switch version {
|
||||
case constants.Openvpn24:
|
||||
bin = binOpenvpn24
|
||||
case constants.Openvpn25:
|
||||
bin = binOpenvpn25
|
||||
default:
|
||||
return nil, nil, nil, fmt.Errorf("%w: %s", ErrVersionUnknown, version)
|
||||
}
|
||||
|
||||
c.logger.Info("starting OpenVPN " + version)
|
||||
|
||||
args := []string{"--config", constants.OpenVPNConf}
|
||||
args = append(args, flags...)
|
||||
cmd := exec.CommandContext(ctx, bin, args...)
|
||||
cmd.SysProcAttr = &syscall.SysProcAttr{Setpgid: true}
|
||||
|
||||
return c.cmder.Start(cmd)
|
||||
}
|
||||
|
||||
type VersionGetter interface {
|
||||
Version24(ctx context.Context) (version string, err error)
|
||||
Version25(ctx context.Context) (version string, err error)
|
||||
}
|
||||
|
||||
func (c *configurator) Version24(ctx context.Context) (version string, err error) {
|
||||
return c.version(ctx, binOpenvpn24)
|
||||
}
|
||||
|
||||
func (c *configurator) Version25(ctx context.Context) (version string, err error) {
|
||||
return c.version(ctx, binOpenvpn25)
|
||||
}
|
||||
|
||||
var ErrVersionTooShort = errors.New("version output is too short")
|
||||
|
||||
func (c *configurator) version(ctx context.Context, binName string) (version string, err error) {
|
||||
cmd := exec.CommandContext(ctx, binName, "--version")
|
||||
output, err := c.cmder.Run(cmd)
|
||||
if err != nil && err.Error() != "exit status 1" {
|
||||
return "", err
|
||||
}
|
||||
firstLine := strings.Split(output, "\n")[0]
|
||||
words := strings.Fields(firstLine)
|
||||
const minWords = 2
|
||||
if len(words) < minWords {
|
||||
return "", fmt.Errorf("%w: %s", ErrVersionTooShort, firstLine)
|
||||
}
|
||||
return words[1], nil
|
||||
}
|
||||
30
internal/openvpn/config/config.go
Normal file
30
internal/openvpn/config/config.go
Normal file
@@ -0,0 +1,30 @@
|
||||
package config
|
||||
|
||||
import (
|
||||
"os"
|
||||
"strings"
|
||||
)
|
||||
|
||||
type Writer interface {
|
||||
WriteConfig(lines []string) error
|
||||
}
|
||||
|
||||
func (c *configurator) WriteConfig(lines []string) error {
|
||||
file, err := os.OpenFile(c.configPath, os.O_CREATE|os.O_TRUNC|os.O_WRONLY, 0644)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
_, err = file.WriteString(strings.Join(lines, "\n"))
|
||||
if err != nil {
|
||||
_ = file.Close()
|
||||
return err
|
||||
}
|
||||
|
||||
err = file.Chown(c.puid, c.pgid)
|
||||
if err != nil {
|
||||
_ = file.Close()
|
||||
return err
|
||||
}
|
||||
|
||||
return file.Close()
|
||||
}
|
||||
34
internal/openvpn/config/openvpn.go
Normal file
34
internal/openvpn/config/openvpn.go
Normal file
@@ -0,0 +1,34 @@
|
||||
package config
|
||||
|
||||
import (
|
||||
"github.com/qdm12/gluetun/internal/constants"
|
||||
"github.com/qdm12/golibs/command"
|
||||
"github.com/qdm12/golibs/logging"
|
||||
)
|
||||
|
||||
type Configurator interface {
|
||||
VersionGetter
|
||||
AuthWriter
|
||||
Starter
|
||||
Writer
|
||||
}
|
||||
|
||||
type configurator struct {
|
||||
logger logging.Logger
|
||||
cmder command.RunStarter
|
||||
configPath string
|
||||
authFilePath string
|
||||
puid, pgid int
|
||||
}
|
||||
|
||||
func NewConfigurator(logger logging.Logger,
|
||||
cmder command.RunStarter, puid, pgid int) Configurator {
|
||||
return &configurator{
|
||||
logger: logger,
|
||||
cmder: cmder,
|
||||
configPath: constants.OpenVPNConf,
|
||||
authFilePath: constants.OpenVPNAuthConf,
|
||||
puid: puid,
|
||||
pgid: pgid,
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user