aboutsummaryrefslogtreecommitdiff
path: root/wgcfg/parser.go
diff options
context:
space:
mode:
Diffstat (limited to 'wgcfg/parser.go')
-rw-r--r--wgcfg/parser.go397
1 files changed, 0 insertions, 397 deletions
diff --git a/wgcfg/parser.go b/wgcfg/parser.go
deleted file mode 100644
index 8db18f3..0000000
--- a/wgcfg/parser.go
+++ /dev/null
@@ -1,397 +0,0 @@
-/* SPDX-License-Identifier: MIT
- *
- * Copyright (C) 2019 WireGuard LLC. All Rights Reserved.
- */
-
-package wgcfg
-
-import (
- "encoding/hex"
- "fmt"
- "net"
- "strconv"
- "strings"
-)
-
-type ParseError struct {
- why string
- offender string
-}
-
-func (e *ParseError) Error() string {
- return fmt.Sprintf("%s: ā€˜%sā€™", e.why, e.offender)
-}
-
-func parseEndpoints(s string) ([]Endpoint, error) {
- var eps []Endpoint
- vals := strings.Split(s, ",")
- for _, val := range vals {
- e, err := parseEndpoint(val)
- if err != nil {
- return nil, err
- }
- eps = append(eps, *e)
- }
- return eps, nil
-}
-
-func parseEndpoint(s string) (*Endpoint, error) {
- i := strings.LastIndexByte(s, ':')
- if i < 0 {
- return nil, &ParseError{"Missing port from endpoint", s}
- }
- host, portStr := s[:i], s[i+1:]
- if len(host) < 1 {
- return nil, &ParseError{"Invalid endpoint host", host}
- }
- port, err := parsePort(portStr)
- if err != nil {
- return nil, err
- }
- hostColon := strings.IndexByte(host, ':')
- if host[0] == '[' || host[len(host)-1] == ']' || hostColon > 0 {
- err := &ParseError{"Brackets must contain an IPv6 address", host}
- if len(host) > 3 && host[0] == '[' && host[len(host)-1] == ']' && hostColon > 0 {
- maybeV6 := net.ParseIP(host[1 : len(host)-1])
- if maybeV6 == nil || len(maybeV6) != net.IPv6len {
- return nil, err
- }
- } else {
- return nil, err
- }
- host = host[1 : len(host)-1]
- }
- return &Endpoint{host, uint16(port)}, nil
-}
-
-func parseMTU(s string) (uint16, error) {
- m, err := strconv.Atoi(s)
- if err != nil {
- return 0, err
- }
- if m < 576 || m > 65535 {
- return 0, &ParseError{"Invalid MTU", s}
- }
- return uint16(m), nil
-}
-
-func parsePort(s string) (uint16, error) {
- m, err := strconv.Atoi(s)
- if err != nil {
- return 0, err
- }
- if m < 0 || m > 65535 {
- return 0, &ParseError{"Invalid port", s}
- }
- return uint16(m), nil
-}
-
-func parsePersistentKeepalive(s string) (uint16, error) {
- if s == "off" {
- return 0, nil
- }
- m, err := strconv.Atoi(s)
- if err != nil {
- return 0, err
- }
- if m < 0 || m > 65535 {
- return 0, &ParseError{"Invalid persistent keepalive", s}
- }
- return uint16(m), nil
-}
-
-func parseKeyHex(s string) (*PublicKey, error) {
- k, err := hex.DecodeString(s)
- if err != nil {
- return nil, &ParseError{"Invalid key: " + err.Error(), s}
- }
- if len(k) != KeySize {
- return nil, &ParseError{"Keys must decode to exactly 32 bytes", s}
- }
- var key PublicKey
- copy(key[:], k)
- return &key, nil
-}
-
-func parseBytesOrStamp(s string) (uint64, error) {
- b, err := strconv.ParseUint(s, 10, 64)
- if err != nil {
- return 0, &ParseError{"Number must be a number between 0 and 2^64-1: " + err.Error(), s}
- }
- return b, nil
-}
-
-func splitList(s string) ([]string, error) {
- var out []string
- for _, split := range strings.Split(s, ",") {
- trim := strings.TrimSpace(split)
- if len(trim) == 0 {
- return nil, &ParseError{"Two commas in a row", s}
- }
- out = append(out, trim)
- }
- return out, nil
-}
-
-type parserState int
-
-const (
- inInterfaceSection parserState = iota
- inPeerSection
- notInASection
-)
-
-func (c *Config) maybeAddPeer(p *Peer) {
- if p != nil {
- c.Peers = append(c.Peers, *p)
- }
-}
-
-func FromWgQuick(s string, name string) (*Config, error) {
- if !TunnelNameIsValid(name) {
- return nil, &ParseError{"Tunnel name is not valid", name}
- }
- lines := strings.Split(s, "\n")
- parserState := notInASection
- conf := Config{Name: name}
- sawPrivateKey := false
- var peer *Peer
- for _, line := range lines {
- pound := strings.IndexByte(line, '#')
- if pound >= 0 {
- line = line[:pound]
- }
- line = strings.TrimSpace(line)
- lineLower := strings.ToLower(line)
- if len(line) == 0 {
- continue
- }
- if lineLower == "[interface]" {
- conf.maybeAddPeer(peer)
- parserState = inInterfaceSection
- continue
- }
- if lineLower == "[peer]" {
- conf.maybeAddPeer(peer)
- peer = &Peer{}
- parserState = inPeerSection
- continue
- }
- if parserState == notInASection {
- return nil, &ParseError{"Line must occur in a section", line}
- }
- equals := strings.IndexByte(line, '=')
- if equals < 0 {
- return nil, &ParseError{"Invalid config key is missing an equals separator", line}
- }
- key, val := strings.TrimSpace(lineLower[:equals]), strings.TrimSpace(line[equals+1:])
- if len(val) == 0 {
- return nil, &ParseError{"Key must have a value", line}
- }
- if parserState == inInterfaceSection {
- switch key {
- case "privatekey":
- k, err := ParseKey(val)
- if err != nil {
- return nil, err
- }
- conf.PrivateKey = PrivateKey(*k)
- sawPrivateKey = true
- case "listenport":
- p, err := parsePort(val)
- if err != nil {
- return nil, err
- }
- conf.ListenPort = p
- case "mtu":
- m, err := parseMTU(val)
- if err != nil {
- return nil, err
- }
- conf.MTU = m
- case "address":
- addresses, err := splitList(val)
- if err != nil {
- return nil, err
- }
- for _, address := range addresses {
- a, err := ParseCIDR(address)
- if err != nil {
- return nil, err
- }
- conf.Addresses = append(conf.Addresses, a)
- }
- case "dns":
- addresses, err := splitList(val)
- if err != nil {
- return nil, err
- }
- for _, address := range addresses {
- a, ok := ParseIP(address)
- if !ok {
- return nil, &ParseError{"Invalid IP address", address}
- }
- conf.DNS = append(conf.DNS, a)
- }
- default:
- return nil, &ParseError{"Invalid key for [Interface] section", key}
- }
- } else if parserState == inPeerSection {
- switch key {
- case "publickey":
- k, err := ParseKey(val)
- if err != nil {
- return nil, err
- }
- peer.PublicKey = *k
- case "presharedkey":
- k, err := ParseKey(val)
- if err != nil {
- return nil, err
- }
- peer.PresharedKey = SymmetricKey(*k)
- case "allowedips":
- addresses, err := splitList(val)
- if err != nil {
- return nil, err
- }
- for _, address := range addresses {
- a, err := ParseCIDR(address)
- if err != nil {
- return nil, err
- }
- peer.AllowedIPs = append(peer.AllowedIPs, a)
- }
- case "persistentkeepalive":
- p, err := parsePersistentKeepalive(val)
- if err != nil {
- return nil, err
- }
- peer.PersistentKeepalive = p
- case "endpoint":
- eps, err := parseEndpoints(val)
- if err != nil {
- return nil, err
- }
- peer.Endpoints = eps
- default:
- return nil, &ParseError{"Invalid key for [Peer] section", key}
- }
- }
- }
- conf.maybeAddPeer(peer)
-
- if !sawPrivateKey {
- return nil, &ParseError{"An interface must have a private key", "[none specified]"}
- }
- for _, p := range conf.Peers {
- if p.PublicKey.IsZero() {
- return nil, &ParseError{"All peers must have public keys", "[none specified]"}
- }
- }
-
- return &conf, nil
-}
-
-// TODO(apenwarr): This is incompatibe with current Device.IpcSetOperation.
-// It duplicates all the parser stuff in there, but is missing some
-// keywords. Nothing useful seems to need it anymore.
-func Broken_FromUAPI(s string, existingConfig *Config) (*Config, error) {
- lines := strings.Split(s, "\n")
- parserState := inInterfaceSection
- conf := Config{
- Name: existingConfig.Name,
- Addresses: existingConfig.Addresses,
- DNS: existingConfig.DNS,
- MTU: existingConfig.MTU,
- }
- var peer *Peer
- for _, line := range lines {
- if len(line) == 0 {
- continue
- }
- equals := strings.IndexByte(line, '=')
- if equals < 0 {
- return nil, &ParseError{"Invalid config key is missing an equals separator", line}
- }
- key, val := line[:equals], line[equals+1:]
- if len(val) == 0 {
- return nil, &ParseError{"Key must have a value", line}
- }
- switch key {
- case "public_key":
- conf.maybeAddPeer(peer)
- peer = &Peer{}
- parserState = inPeerSection
- case "errno":
- if val == "0" {
- continue
- } else {
- return nil, &ParseError{"Error in getting configuration", val}
- }
- }
- if parserState == inInterfaceSection {
- switch key {
- case "private_key":
- k, err := parseKeyHex(val)
- if err != nil {
- return nil, err
- }
- conf.PrivateKey = PrivateKey(*k)
- case "listen_port":
- p, err := parsePort(val)
- if err != nil {
- return nil, err
- }
- conf.ListenPort = p
- case "fwmark":
- // Ignored for now.
-
- default:
- return nil, &ParseError{"Invalid key for interface section", key}
- }
- } else if parserState == inPeerSection {
- switch key {
- case "public_key":
- k, err := parseKeyHex(val)
- if err != nil {
- return nil, err
- }
- peer.PublicKey = *k
- case "preshared_key":
- k, err := parseKeyHex(val)
- if err != nil {
- return nil, err
- }
- peer.PresharedKey = SymmetricKey(*k)
- case "protocol_version":
- if val != "1" {
- return nil, &ParseError{"Protocol version must be 1", val}
- }
- case "allowed_ip":
- a, err := ParseCIDR(val)
- if err != nil {
- return nil, err
- }
- peer.AllowedIPs = append(peer.AllowedIPs, a)
- case "persistent_keepalive_interval":
- p, err := parsePersistentKeepalive(val)
- if err != nil {
- return nil, err
- }
- peer.PersistentKeepalive = p
- case "endpoint":
- eps, err := parseEndpoints(val)
- if err != nil {
- return nil, err
- }
- peer.Endpoints = eps
- default:
- return nil, &ParseError{"Invalid key for peer section", key}
- }
- }
- }
- conf.maybeAddPeer(peer)
-
- return &conf, nil
-}