aboutsummaryrefslogtreecommitdiffstats
path: root/WireGuard/Shared/Model/Configuration.swift
blob: f6598bba980122c1516ac2c846e3d8c767c81d0a (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
// SPDX-License-Identifier: MIT
// Copyright © 2018 WireGuard LLC. All Rights Reserved.

import Foundation

@available(OSX 10.14, iOS 12.0, *)
final class TunnelConfiguration {
    var interface: InterfaceConfiguration
    let peers: [PeerConfiguration]
    var activationType: ActivationType
    init(interface: InterfaceConfiguration, peers: [PeerConfiguration]) {
        self.interface = interface
        self.peers = peers
        self.activationType = .activateManually

        let peerPublicKeysArray = peers.map { $0.publicKey }
        let peerPublicKeysSet = Set<Data>(peerPublicKeysArray)
        if (peerPublicKeysArray.count != peerPublicKeysSet.count) {
            fatalError("Two or more peers cannot have the same public key")
        }
    }
}

@available(OSX 10.14, iOS 12.0, *)
struct InterfaceConfiguration: Codable {
    var name: String
    var privateKey: Data
    var addresses: [IPAddressRange] = []
    var listenPort: UInt16?
    var mtu: UInt16?
    var dns: [DNSServer] = []

    init(name: String, privateKey: Data) {
        self.name = name
        self.privateKey = privateKey
        if (name.isEmpty) { fatalError("Empty name") }
        if (privateKey.count != 32) { fatalError("Invalid private key") }
    }
}

@available(OSX 10.14, iOS 12.0, *)
struct PeerConfiguration: Codable {
    var publicKey: Data
    var preSharedKey: Data? {
        didSet(value) {
            if let value = value {
                if (value.count != 32) { fatalError("Invalid preshared key") }
            }
        }
    }
    var allowedIPs: [IPAddressRange] = []
    var endpoint: Endpoint?
    var persistentKeepAlive: UInt16?

    init(publicKey: Data) {
        self.publicKey = publicKey
        if (publicKey.count != 32) { fatalError("Invalid public key") }
    }
}

extension TunnelConfiguration: Encodable { }
extension TunnelConfiguration: Decodable {
    enum CodingKeys: CodingKey {
        case interface
        case peers
        case activationType
    }
    convenience init(from decoder: Decoder) throws {
        let values = try decoder.container(keyedBy: CodingKeys.self)
        let interface = try values.decode(InterfaceConfiguration.self, forKey: .interface)
        let peers = try values.decode([PeerConfiguration].self, forKey: .peers)
        let activationType = (try? values.decode(ActivationType.self, forKey: .activationType)) ?? .activateManually

        self.init(interface: interface, peers: peers)
        self.activationType = activationType
    }
}