diff options
| author | James O'Doherty <james@theodohertyfamily.com> | 2026-05-22 16:17:55 -0400 |
|---|---|---|
| committer | James O'Doherty <james@theodohertyfamily.com> | 2026-05-22 16:17:55 -0400 |
| commit | 135f6edbd9389bc4783f13c26aed0a74d3c8aca0 (patch) | |
| tree | 41a8e80b0dcf2c42b045bc91d9101deceb049f47 /pkg/wgconf/wgconf.go | |
| parent | 2e3a1d07b43e6e942e51ba263c6fcdc2351afc0d (diff) | |
refactor: unify path management and complete profile management system
- Create internal/paths package for unified config and runtime directory resolution
- Implement robust WireGuard config parsing in pkg/wgconf
- Implement profile management subcommands: list, import, configure, delete, stop
- Fix namespace pinning path collisions (separating .ns files from pids directories)
- Implement and verify namespace unpinning logic
- Fix linting errors and improve error handling across the project
Diffstat (limited to 'pkg/wgconf/wgconf.go')
| -rw-r--r-- | pkg/wgconf/wgconf.go | 97 |
1 files changed, 97 insertions, 0 deletions
diff --git a/pkg/wgconf/wgconf.go b/pkg/wgconf/wgconf.go new file mode 100644 index 0000000..2615892 --- /dev/null +++ b/pkg/wgconf/wgconf.go @@ -0,0 +1,97 @@ +package wgconf + +import ( + "bufio" + "fmt" + "os" + "strings" +) + +// Config represents a parsed WireGuard configuration file. +type Config struct { + PrivateKey string + Address string + DNS string + Peers []Peer +} + +// Peer represents a WireGuard peer. +type Peer struct { + PublicKey string + Endpoint string + AllowedIPs []string +} + +// Parse reads a WireGuard .conf file and returns a Config struct. +func Parse(path string) (*Config, error) { + file, err := os.Open(path) + if err != nil { + return nil, fmt.Errorf("failed to open config file: %w", err) + } + defer func() { + if err := file.Close(); err != nil { + // We use a simple print here because we are in a defer + fmt.Printf("warning: failed to close config file %s: %v\n", path, err) + } + }() + + cfg := &Config{} + var currentPeer *Peer + + scanner := bufio.NewScanner(file) + for scanner.Scan() { + line := strings.TrimSpace(scanner.Text()) + if line == "" || strings.HasPrefix(line, "#") { + continue + } + + if strings.HasPrefix(line, "[") { + section := strings.Trim(line, "[]") + if section == "Peer" { + if currentPeer != nil { + cfg.Peers = append(cfg.Peers, *currentPeer) + } + currentPeer = &Peer{} + } + continue + } + + parts := strings.SplitN(line, "=", 2) + if len(parts) != 2 { + return nil, fmt.Errorf("invalid line format: %s", line) + } + + key := strings.TrimSpace(parts[0]) + val := strings.TrimSpace(parts[1]) + + if currentPeer != nil { + switch key { + case "PublicKey": + currentPeer.PublicKey = val + case "Endpoint": + currentPeer.Endpoint = val + case "AllowedIPs": + currentPeer.AllowedIPs = strings.Split(val, ",") + } + } else { + switch key { + case "PrivateKey": + cfg.PrivateKey = val + case "Address": + cfg.Address = val + case "DNS": + cfg.DNS = val + } + } + } + + if currentPeer != nil { + cfg.Peers = append(cfg.Peers, *currentPeer) + } + + if err := scanner.Err(); err != nil { + return nil, fmt.Errorf("error reading config file: %w", err) + } + + return cfg, nil +} |
