Maint: move OpenVPN configurator to openvpn/config

This commit is contained in:
Quentin McGaw (desktop)
2021-08-18 20:23:50 +00:00
parent df51aa40f4
commit ecdf9396a5
6 changed files with 11 additions and 11 deletions

View 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()
}

View 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
}

View 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()
}

View 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,
}
}