conf.go 8.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374
  1. // Copyright 2019 the Kilo authors
  2. //
  3. // Licensed under the Apache License, Version 2.0 (the "License");
  4. // you may not use this file except in compliance with the License.
  5. // You may obtain a copy of the License at
  6. //
  7. // http://www.apache.org/licenses/LICENSE-2.0
  8. //
  9. // Unless required by applicable law or agreed to in writing, software
  10. // distributed under the License is distributed on an "AS IS" BASIS,
  11. // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  12. // See the License for the specific language governing permissions and
  13. // limitations under the License.
  14. package wireguard
  15. import (
  16. "bufio"
  17. "bytes"
  18. "fmt"
  19. "net"
  20. "sort"
  21. "strconv"
  22. "strings"
  23. )
  24. type section string
  25. type key string
  26. const (
  27. separator = "="
  28. interfaceSection section = "Interface"
  29. peerSection section = "Peer"
  30. listenPortKey key = "ListenPort"
  31. allowedIPsKey key = "AllowedIPs"
  32. endpointKey key = "Endpoint"
  33. persistentKeepaliveKey key = "PersistentKeepalive"
  34. privateKeyKey key = "PrivateKey"
  35. publicKeyKey key = "PublicKey"
  36. )
  37. // Conf represents a WireGuard configuration file.
  38. type Conf struct {
  39. Interface *Interface
  40. Peers []*Peer
  41. }
  42. // Interface represents the `interface` section of a WireGuard configuration.
  43. type Interface struct {
  44. ListenPort uint32
  45. PrivateKey []byte
  46. }
  47. // Peer represents a `peer` section of a WireGuard configuration.
  48. type Peer struct {
  49. AllowedIPs []*net.IPNet
  50. Endpoint *Endpoint
  51. PersistentKeepalive int
  52. PublicKey []byte
  53. }
  54. // Endpoint represents an `endpoint` key of a `peer` section.
  55. type Endpoint struct {
  56. IP net.IP
  57. Port uint32
  58. }
  59. // Parse parses a given WireGuard configuration file and produces a Conf struct.
  60. func Parse(buf []byte) *Conf {
  61. var (
  62. active section
  63. ai *net.IPNet
  64. kv []string
  65. c Conf
  66. err error
  67. iface *Interface
  68. i int
  69. ip, ip4 net.IP
  70. k key
  71. line, v string
  72. peer *Peer
  73. port uint64
  74. )
  75. s := bufio.NewScanner(bytes.NewBuffer(buf))
  76. for s.Scan() {
  77. line = strings.TrimSpace(s.Text())
  78. // Skip comments.
  79. if strings.HasPrefix(line, "#") {
  80. continue
  81. }
  82. // Line is a section title.
  83. if strings.HasPrefix(line, "[") {
  84. if peer != nil {
  85. c.Peers = append(c.Peers, peer)
  86. peer = nil
  87. }
  88. if iface != nil {
  89. c.Interface = iface
  90. iface = nil
  91. }
  92. active = section(strings.TrimSpace(strings.Trim(line, "[]")))
  93. switch active {
  94. case interfaceSection:
  95. iface = new(Interface)
  96. case peerSection:
  97. peer = new(Peer)
  98. }
  99. continue
  100. }
  101. kv = strings.SplitN(line, separator, 2)
  102. if len(kv) != 2 {
  103. continue
  104. }
  105. k = key(strings.TrimSpace(kv[0]))
  106. v = strings.TrimSpace(kv[1])
  107. switch active {
  108. case interfaceSection:
  109. switch k {
  110. case listenPortKey:
  111. port, err = strconv.ParseUint(v, 10, 32)
  112. if err != nil {
  113. continue
  114. }
  115. iface.ListenPort = uint32(port)
  116. case privateKeyKey:
  117. iface.PrivateKey = []byte(v)
  118. }
  119. case peerSection:
  120. switch k {
  121. case allowedIPsKey:
  122. // Reuse string slice.
  123. kv = strings.Split(v, ",")
  124. for i = range kv {
  125. ip, ai, err = net.ParseCIDR(strings.TrimSpace(kv[i]))
  126. if err != nil {
  127. continue
  128. }
  129. if ip4 = ip.To4(); ip4 != nil {
  130. ip = ip4
  131. } else {
  132. ip = ip.To16()
  133. }
  134. ai.IP = ip
  135. peer.AllowedIPs = append(peer.AllowedIPs, ai)
  136. }
  137. case endpointKey:
  138. // Reuse string slice.
  139. kv = strings.Split(v, ":")
  140. if len(kv) != 2 {
  141. continue
  142. }
  143. ip = net.ParseIP(kv[0])
  144. if ip == nil {
  145. continue
  146. }
  147. port, err = strconv.ParseUint(kv[1], 10, 32)
  148. if err != nil {
  149. continue
  150. }
  151. if ip4 = ip.To4(); ip4 != nil {
  152. ip = ip4
  153. } else {
  154. ip = ip.To16()
  155. }
  156. peer.Endpoint = &Endpoint{
  157. IP: ip,
  158. Port: uint32(port),
  159. }
  160. case persistentKeepaliveKey:
  161. i, err = strconv.Atoi(v)
  162. if err != nil {
  163. continue
  164. }
  165. peer.PersistentKeepalive = i
  166. case publicKeyKey:
  167. peer.PublicKey = []byte(v)
  168. }
  169. }
  170. }
  171. if peer != nil {
  172. c.Peers = append(c.Peers, peer)
  173. }
  174. if iface != nil {
  175. c.Interface = iface
  176. }
  177. return &c
  178. }
  179. // Bytes renders a WireGuard configuration to bytes.
  180. func (c *Conf) Bytes() ([]byte, error) {
  181. var err error
  182. buf := bytes.NewBuffer(make([]byte, 0, 512))
  183. if c.Interface != nil {
  184. if err = writeSection(buf, interfaceSection); err != nil {
  185. return nil, fmt.Errorf("failed to write interface: %v", err)
  186. }
  187. if err = writePKey(buf, privateKeyKey, c.Interface.PrivateKey); err != nil {
  188. return nil, fmt.Errorf("failed to write private key: %v", err)
  189. }
  190. if err = writeValue(buf, listenPortKey, strconv.FormatUint(uint64(c.Interface.ListenPort), 10)); err != nil {
  191. return nil, fmt.Errorf("failed to write listen port: %v", err)
  192. }
  193. }
  194. for i, p := range c.Peers {
  195. // Add newlines to make the formatting nicer.
  196. if i == 0 && c.Interface != nil || i != 0 {
  197. if err = buf.WriteByte('\n'); err != nil {
  198. return nil, err
  199. }
  200. }
  201. if err = writeSection(buf, peerSection); err != nil {
  202. return nil, fmt.Errorf("failed to write interface: %v", err)
  203. }
  204. if err = writeAllowedIPs(buf, p.AllowedIPs); err != nil {
  205. return nil, fmt.Errorf("failed to write allowed IPs: %v", err)
  206. }
  207. if err = writeEndpoint(buf, p.Endpoint); err != nil {
  208. return nil, fmt.Errorf("failed to write endpoint: %v", err)
  209. }
  210. if err = writeValue(buf, persistentKeepaliveKey, strconv.Itoa(p.PersistentKeepalive)); err != nil {
  211. return nil, fmt.Errorf("failed to write persistent keepalive: %v", err)
  212. }
  213. if err = writePKey(buf, publicKeyKey, p.PublicKey); err != nil {
  214. return nil, fmt.Errorf("failed to write public key: %v", err)
  215. }
  216. }
  217. return buf.Bytes(), nil
  218. }
  219. // Equal checks if two WireGuare configurations are equivalent.
  220. func (c *Conf) Equal(b *Conf) bool {
  221. if (c.Interface == nil) != (b.Interface == nil) {
  222. return false
  223. }
  224. if c.Interface != nil {
  225. if c.Interface.ListenPort != b.Interface.ListenPort || !bytes.Equal(c.Interface.PrivateKey, b.Interface.PrivateKey) {
  226. return false
  227. }
  228. }
  229. if len(c.Peers) != len(b.Peers) {
  230. return false
  231. }
  232. sortPeers(c.Peers)
  233. sortPeers(b.Peers)
  234. for i := range c.Peers {
  235. if len(c.Peers[i].AllowedIPs) != len(b.Peers[i].AllowedIPs) {
  236. return false
  237. }
  238. sortCIDRs(c.Peers[i].AllowedIPs)
  239. sortCIDRs(b.Peers[i].AllowedIPs)
  240. for j := range c.Peers[i].AllowedIPs {
  241. if c.Peers[i].AllowedIPs[j].String() != b.Peers[i].AllowedIPs[j].String() {
  242. return false
  243. }
  244. }
  245. if (c.Peers[i].Endpoint == nil) != (b.Peers[i].Endpoint == nil) {
  246. return false
  247. }
  248. if c.Peers[i].Endpoint != nil {
  249. if !c.Peers[i].Endpoint.IP.Equal(b.Peers[i].Endpoint.IP) || c.Peers[i].Endpoint.Port != b.Peers[i].Endpoint.Port {
  250. return false
  251. }
  252. }
  253. if c.Peers[i].PersistentKeepalive != b.Peers[i].PersistentKeepalive || !bytes.Equal(c.Peers[i].PublicKey, b.Peers[i].PublicKey) {
  254. return false
  255. }
  256. }
  257. return true
  258. }
  259. func sortPeers(peers []*Peer) {
  260. sort.Slice(peers, func(i, j int) bool {
  261. if bytes.Compare(peers[i].PublicKey, peers[j].PublicKey) < 0 {
  262. return true
  263. }
  264. return false
  265. })
  266. }
  267. func sortCIDRs(cidrs []*net.IPNet) {
  268. sort.Slice(cidrs, func(i, j int) bool {
  269. return cidrs[i].String() < cidrs[j].String()
  270. })
  271. }
  272. func writeAllowedIPs(buf *bytes.Buffer, ais []*net.IPNet) error {
  273. if len(ais) == 0 {
  274. return nil
  275. }
  276. var err error
  277. if err = writeKey(buf, allowedIPsKey); err != nil {
  278. return err
  279. }
  280. for i := range ais {
  281. if i != 0 {
  282. if _, err = buf.WriteString(", "); err != nil {
  283. return err
  284. }
  285. }
  286. if _, err = buf.WriteString(ais[i].String()); err != nil {
  287. return err
  288. }
  289. }
  290. return buf.WriteByte('\n')
  291. }
  292. func writePKey(buf *bytes.Buffer, k key, b []byte) error {
  293. if len(b) == 0 {
  294. return nil
  295. }
  296. var err error
  297. if err = writeKey(buf, k); err != nil {
  298. return err
  299. }
  300. if _, err = buf.Write(b); err != nil {
  301. return err
  302. }
  303. return buf.WriteByte('\n')
  304. }
  305. func writeValue(buf *bytes.Buffer, k key, v string) error {
  306. var err error
  307. if err = writeKey(buf, k); err != nil {
  308. return err
  309. }
  310. if _, err = buf.WriteString(v); err != nil {
  311. return err
  312. }
  313. return buf.WriteByte('\n')
  314. }
  315. func writeEndpoint(buf *bytes.Buffer, e *Endpoint) error {
  316. if e == nil {
  317. return nil
  318. }
  319. var err error
  320. if err = writeKey(buf, endpointKey); err != nil {
  321. return err
  322. }
  323. if _, err = buf.WriteString(e.IP.String()); err != nil {
  324. return err
  325. }
  326. if err = buf.WriteByte(':'); err != nil {
  327. return err
  328. }
  329. if _, err = buf.WriteString(strconv.FormatUint(uint64(e.Port), 10)); err != nil {
  330. return err
  331. }
  332. return buf.WriteByte('\n')
  333. }
  334. func writeSection(buf *bytes.Buffer, s section) error {
  335. var err error
  336. if err = buf.WriteByte('['); err != nil {
  337. return err
  338. }
  339. if _, err = buf.WriteString(string(s)); err != nil {
  340. return err
  341. }
  342. if err = buf.WriteByte(']'); err != nil {
  343. return err
  344. }
  345. return buf.WriteByte('\n')
  346. }
  347. func writeKey(buf *bytes.Buffer, k key) error {
  348. var err error
  349. if _, err = buf.WriteString(string(k)); err != nil {
  350. return err
  351. }
  352. _, err = buf.WriteString(" = ")
  353. return err
  354. }