2023-07-22 17:25:30 +02:00
|
|
|
package files
|
|
|
|
|
|
|
|
|
|
import (
|
|
|
|
|
"fmt"
|
|
|
|
|
"net/netip"
|
|
|
|
|
"regexp"
|
|
|
|
|
"strings"
|
|
|
|
|
|
|
|
|
|
"github.com/qdm12/gluetun/internal/configuration/settings"
|
|
|
|
|
"golang.zx2c4.com/wireguard/wgctrl/wgtypes"
|
|
|
|
|
"gopkg.in/ini.v1"
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
var (
|
|
|
|
|
regexINISectionNotExist = regexp.MustCompile(`^section ".+" does not exist$`)
|
|
|
|
|
regexINIKeyNotExist = regexp.MustCompile(`key ".*" not exists$`)
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
func (s *Source) readWireguard() (wireguard settings.Wireguard, err error) {
|
|
|
|
|
fileStringPtr, err := ReadFromFile(s.wireguardConfigPath)
|
|
|
|
|
if err != nil {
|
|
|
|
|
return wireguard, fmt.Errorf("reading file: %w", err)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if fileStringPtr == nil {
|
|
|
|
|
return wireguard, nil
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
rawData := []byte(*fileStringPtr)
|
|
|
|
|
iniFile, err := ini.Load(rawData)
|
|
|
|
|
if err != nil {
|
|
|
|
|
return wireguard, fmt.Errorf("loading ini from reader: %w", err)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
interfaceSection, err := iniFile.GetSection("Interface")
|
|
|
|
|
if err == nil {
|
|
|
|
|
err = parseWireguardInterfaceSection(interfaceSection, &wireguard)
|
|
|
|
|
if err != nil {
|
|
|
|
|
return wireguard, fmt.Errorf("parsing interface section: %w", err)
|
|
|
|
|
}
|
|
|
|
|
} else if !regexINISectionNotExist.MatchString(err.Error()) {
|
|
|
|
|
// can never happen
|
|
|
|
|
return wireguard, fmt.Errorf("getting interface section: %w", err)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return wireguard, nil
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func parseWireguardInterfaceSection(interfaceSection *ini.Section,
|
|
|
|
|
wireguard *settings.Wireguard) (err error) {
|
|
|
|
|
wireguard.PrivateKey, err = parseINIWireguardKey(interfaceSection, "PrivateKey")
|
|
|
|
|
if err != nil {
|
|
|
|
|
return err // error is already wrapped correctly
|
|
|
|
|
}
|
|
|
|
|
|
2023-11-08 09:38:10 +00:00
|
|
|
wireguard.PreSharedKey, err = parseINIWireguardKey(interfaceSection, "PresharedKey")
|
2023-07-22 17:25:30 +02:00
|
|
|
if err != nil {
|
|
|
|
|
return err // error is already wrapped correctly
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
wireguard.Addresses, err = parseINIWireguardAddress(interfaceSection)
|
|
|
|
|
if err != nil {
|
|
|
|
|
return err // error is already wrapped correctly
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return nil
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func parseINIWireguardKey(section *ini.Section, keyName string) (
|
|
|
|
|
key *string, err error) {
|
|
|
|
|
iniKey, err := section.GetKey(keyName)
|
|
|
|
|
if err != nil {
|
|
|
|
|
if regexINIKeyNotExist.MatchString(err.Error()) {
|
|
|
|
|
return nil, nil //nolint:nilnil
|
|
|
|
|
}
|
|
|
|
|
// can never happen
|
|
|
|
|
return nil, fmt.Errorf("getting %s key: %w", keyName, err)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
key = new(string)
|
|
|
|
|
*key = iniKey.String()
|
|
|
|
|
_, err = wgtypes.ParseKey(*key)
|
|
|
|
|
if err != nil {
|
|
|
|
|
return nil, fmt.Errorf("parsing %s: %s: %w", keyName, *key, err)
|
|
|
|
|
}
|
|
|
|
|
return key, nil
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func parseINIWireguardAddress(section *ini.Section) (
|
|
|
|
|
addresses []netip.Prefix, err error) {
|
|
|
|
|
addressKey, err := section.GetKey("Address")
|
|
|
|
|
if err != nil {
|
|
|
|
|
if regexINIKeyNotExist.MatchString(err.Error()) {
|
|
|
|
|
return nil, nil
|
|
|
|
|
}
|
|
|
|
|
// can never happen
|
|
|
|
|
return nil, fmt.Errorf("getting Address key: %w", err)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
addressStrings := strings.Split(addressKey.String(), ",")
|
|
|
|
|
addresses = make([]netip.Prefix, len(addressStrings))
|
|
|
|
|
for i, addressString := range addressStrings {
|
|
|
|
|
addressString = strings.TrimSpace(addressString)
|
2023-09-24 15:23:24 +00:00
|
|
|
if !strings.ContainsRune(addressString, '/') {
|
|
|
|
|
addressString += "/32"
|
|
|
|
|
}
|
2023-07-22 17:25:30 +02:00
|
|
|
addresses[i], err = netip.ParsePrefix(addressString)
|
|
|
|
|
if err != nil {
|
|
|
|
|
return nil, fmt.Errorf("parsing address: %w", err)
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return addresses, nil
|
|
|
|
|
}
|