mirror of
https://git.zx2c4.com/wireguard-windows
synced 2024-11-10 16:59:18 +00:00
6ed37f30f5
Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com>
143 lines
3.4 KiB
Go
143 lines
3.4 KiB
Go
/* SPDX-License-Identifier: MIT
|
|
*
|
|
* Copyright (C) 2019-2022 WireGuard LLC. All Rights Reserved.
|
|
*/
|
|
|
|
package conf
|
|
|
|
import (
|
|
"errors"
|
|
"os"
|
|
"path/filepath"
|
|
"strings"
|
|
|
|
"golang.zx2c4.com/wireguard/windows/conf/dpapi"
|
|
)
|
|
|
|
const (
|
|
configFileSuffix = ".conf.dpapi"
|
|
configFileUnencryptedSuffix = ".conf"
|
|
)
|
|
|
|
func ListConfigNames() ([]string, error) {
|
|
configFileDir, err := tunnelConfigurationsDirectory()
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
files, err := os.ReadDir(configFileDir)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
configs := make([]string, len(files))
|
|
i := 0
|
|
for _, file := range files {
|
|
name, err := NameFromPath(file.Name())
|
|
if err != nil {
|
|
continue
|
|
}
|
|
if !file.Type().IsRegular() {
|
|
continue
|
|
}
|
|
info, err := file.Info()
|
|
if err != nil {
|
|
continue
|
|
}
|
|
if info.Mode().Perm()&0o444 == 0 {
|
|
continue
|
|
}
|
|
configs[i] = name
|
|
i++
|
|
}
|
|
return configs[:i], nil
|
|
}
|
|
|
|
func LoadFromName(name string) (*Config, error) {
|
|
configFileDir, err := tunnelConfigurationsDirectory()
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
return LoadFromPath(filepath.Join(configFileDir, name+configFileSuffix))
|
|
}
|
|
|
|
func LoadFromPath(path string) (*Config, error) {
|
|
name, err := NameFromPath(path)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
bytes, err := os.ReadFile(path)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
if strings.HasSuffix(path, configFileSuffix) {
|
|
bytes, err = dpapi.Decrypt(bytes, name)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
}
|
|
return FromWgQuickWithUnknownEncoding(string(bytes), name)
|
|
}
|
|
|
|
func PathIsEncrypted(path string) bool {
|
|
return strings.HasSuffix(filepath.Base(path), configFileSuffix)
|
|
}
|
|
|
|
func NameFromPath(path string) (string, error) {
|
|
name := filepath.Base(path)
|
|
if !((len(name) > len(configFileSuffix) && strings.HasSuffix(name, configFileSuffix)) ||
|
|
(len(name) > len(configFileUnencryptedSuffix) && strings.HasSuffix(name, configFileUnencryptedSuffix))) {
|
|
return "", errors.New("Path must end in either " + configFileSuffix + " or " + configFileUnencryptedSuffix)
|
|
}
|
|
if strings.HasSuffix(path, configFileSuffix) {
|
|
name = strings.TrimSuffix(name, configFileSuffix)
|
|
} else {
|
|
name = strings.TrimSuffix(name, configFileUnencryptedSuffix)
|
|
}
|
|
if !TunnelNameIsValid(name) {
|
|
return "", errors.New("Tunnel name is not valid")
|
|
}
|
|
return name, nil
|
|
}
|
|
|
|
func (config *Config) Save(overwrite bool) error {
|
|
if !TunnelNameIsValid(config.Name) {
|
|
return errors.New("Tunnel name is not valid")
|
|
}
|
|
configFileDir, err := tunnelConfigurationsDirectory()
|
|
if err != nil {
|
|
return err
|
|
}
|
|
filename := filepath.Join(configFileDir, config.Name+configFileSuffix)
|
|
bytes := []byte(config.ToWgQuick())
|
|
bytes, err = dpapi.Encrypt(bytes, config.Name)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
return writeLockedDownFile(filename, overwrite, bytes)
|
|
}
|
|
|
|
func (config *Config) Path() (string, error) {
|
|
if !TunnelNameIsValid(config.Name) {
|
|
return "", errors.New("Tunnel name is not valid")
|
|
}
|
|
configFileDir, err := tunnelConfigurationsDirectory()
|
|
if err != nil {
|
|
return "", err
|
|
}
|
|
return filepath.Join(configFileDir, config.Name+configFileSuffix), nil
|
|
}
|
|
|
|
func DeleteName(name string) error {
|
|
if !TunnelNameIsValid(name) {
|
|
return errors.New("Tunnel name is not valid")
|
|
}
|
|
configFileDir, err := tunnelConfigurationsDirectory()
|
|
if err != nil {
|
|
return err
|
|
}
|
|
return os.Remove(filepath.Join(configFileDir, name+configFileSuffix))
|
|
}
|
|
|
|
func (config *Config) Delete() error {
|
|
return DeleteName(config.Name)
|
|
}
|