From e733cdcf335682cba73b44e1f1db58132783709e Mon Sep 17 00:00:00 2001 From: Pascal Fischer Date: Mon, 25 Sep 2023 13:02:56 +0200 Subject: [PATCH] first working connection --- iface/iface_ios.go | 2 +- iface/ipc_parser_android.go | 3 + iface/ipc_parser_ios.go | 63 ++++++++++++++++ iface/tun_ios.go | 2 +- iface/wg_configurer_ios.go | 117 ++++++++++++++++++++++++++++++ iface/wg_configurer_nonandroid.go | 4 +- 6 files changed, 187 insertions(+), 4 deletions(-) create mode 100644 iface/ipc_parser_ios.go create mode 100644 iface/wg_configurer_ios.go diff --git a/iface/iface_ios.go b/iface/iface_ios.go index 62432f7ed..901faec30 100644 --- a/iface/iface_ios.go +++ b/iface/iface_ios.go @@ -24,7 +24,7 @@ func NewWGIFace(ifaceName string, address string, mtu int, tunAdapter TunAdapter tun := newTunDevice(wgAddress, mtu, tunAdapter, transportNet) wgIFace.tun = tun - wgIFace.configurer = newWGConfigurer(tun.name) + wgIFace.configurer = newWGConfigurer(tun) wgIFace.userspaceBind = !WireGuardModuleIsLoaded() diff --git a/iface/ipc_parser_android.go b/iface/ipc_parser_android.go index e1dd66856..56e52d1a0 100644 --- a/iface/ipc_parser_android.go +++ b/iface/ipc_parser_android.go @@ -1,3 +1,6 @@ +//go:build android +// +build android + package iface import ( diff --git a/iface/ipc_parser_ios.go b/iface/ipc_parser_ios.go new file mode 100644 index 000000000..de5e50664 --- /dev/null +++ b/iface/ipc_parser_ios.go @@ -0,0 +1,63 @@ +//go:build ios +// +build ios + +package iface + +import ( + "encoding/hex" + "fmt" + "strings" + + "golang.zx2c4.com/wireguard/wgctrl/wgtypes" +) + +func toWgUserspaceString(wgCfg wgtypes.Config) string { + var sb strings.Builder + if wgCfg.PrivateKey != nil { + hexKey := hex.EncodeToString(wgCfg.PrivateKey[:]) + sb.WriteString(fmt.Sprintf("private_key=%s\n", hexKey)) + } + + if wgCfg.ListenPort != nil { + sb.WriteString(fmt.Sprintf("listen_port=%d\n", *wgCfg.ListenPort)) + } + + if wgCfg.ReplacePeers { + sb.WriteString("replace_peers=true\n") + } + + if wgCfg.FirewallMark != nil { + sb.WriteString(fmt.Sprintf("fwmark=%d\n", *wgCfg.FirewallMark)) + } + + for _, p := range wgCfg.Peers { + hexKey := hex.EncodeToString(p.PublicKey[:]) + sb.WriteString(fmt.Sprintf("public_key=%s\n", hexKey)) + + if p.PresharedKey != nil { + preSharedHexKey := hex.EncodeToString(p.PresharedKey[:]) + sb.WriteString(fmt.Sprintf("preshared_key=%s\n", preSharedHexKey)) + } + + if p.Remove { + sb.WriteString("remove=true") + } + + if p.ReplaceAllowedIPs { + sb.WriteString("replace_allowed_ips=true\n") + } + + for _, aip := range p.AllowedIPs { + sb.WriteString(fmt.Sprintf("allowed_ip=%s\n", aip.String())) + } + + if p.Endpoint != nil { + sb.WriteString(fmt.Sprintf("endpoint=%s\n", p.Endpoint.String())) + } + + if p.PersistentKeepaliveInterval != nil { + sb.WriteString(fmt.Sprintf("persistent_keepalive_interval=%d\n", int(p.PersistentKeepaliveInterval.Seconds()))) + } + } + return sb.String() +} diff --git a/iface/tun_ios.go b/iface/tun_ios.go index eb39bf787..4ea80c9a2 100644 --- a/iface/tun_ios.go +++ b/iface/tun_ios.go @@ -38,7 +38,7 @@ func newTunDevice(address WGAddress, mtu int, tunAdapter TunAdapter, transportNe } func (t *tunDevice) Create(tunFd int32) error { - log.Info("create tun interface") + log.Infof("create tun interface") dupTunFd, err := unix.Dup(int(tunFd)) if err != nil { diff --git a/iface/wg_configurer_ios.go b/iface/wg_configurer_ios.go new file mode 100644 index 000000000..232402278 --- /dev/null +++ b/iface/wg_configurer_ios.go @@ -0,0 +1,117 @@ +//go:build ios +// +build ios + +package iface + +import ( + "errors" + "net" + "time" + + log "github.com/sirupsen/logrus" + + "golang.zx2c4.com/wireguard/wgctrl/wgtypes" +) + +var ( + errFuncNotImplemented = errors.New("function not implemented") +) + +type wGConfigurer struct { + tunDevice *tunDevice +} + +func newWGConfigurer(tunDevice *tunDevice) wGConfigurer { + return wGConfigurer{ + tunDevice: tunDevice, + } +} + +func (c *wGConfigurer) configureInterface(privateKey string, port int) error { + log.Debugf("adding Wireguard private key") + key, err := wgtypes.ParseKey(privateKey) + if err != nil { + return err + } + fwmark := 0 + config := wgtypes.Config{ + PrivateKey: &key, + ReplacePeers: true, + FirewallMark: &fwmark, + ListenPort: &port, + } + + return c.tunDevice.Device().IpcSet(toWgUserspaceString(config)) +} + +func (c *wGConfigurer) updatePeer(peerKey string, allowedIps string, keepAlive time.Duration, endpoint *net.UDPAddr, preSharedKey *wgtypes.Key) error { + // parse allowed ips + _, ipNet, err := net.ParseCIDR(allowedIps) + if err != nil { + return err + } + + peerKeyParsed, err := wgtypes.ParseKey(peerKey) + if err != nil { + return err + } + peer := wgtypes.PeerConfig{ + PublicKey: peerKeyParsed, + ReplaceAllowedIPs: true, + AllowedIPs: []net.IPNet{*ipNet}, + PersistentKeepaliveInterval: &keepAlive, + PresharedKey: preSharedKey, + Endpoint: endpoint, + } + + config := wgtypes.Config{ + Peers: []wgtypes.PeerConfig{peer}, + } + + return c.tunDevice.Device().IpcSet(toWgUserspaceString(config)) +} + +func (c *wGConfigurer) removePeer(peerKey string) error { + peerKeyParsed, err := wgtypes.ParseKey(peerKey) + if err != nil { + return err + } + + peer := wgtypes.PeerConfig{ + PublicKey: peerKeyParsed, + Remove: true, + } + + config := wgtypes.Config{ + Peers: []wgtypes.PeerConfig{peer}, + } + return c.tunDevice.Device().IpcSet(toWgUserspaceString(config)) +} + +func (c *wGConfigurer) addAllowedIP(peerKey string, allowedIP string) error { + _, ipNet, err := net.ParseCIDR(allowedIP) + if err != nil { + return err + } + + peerKeyParsed, err := wgtypes.ParseKey(peerKey) + if err != nil { + return err + } + peer := wgtypes.PeerConfig{ + PublicKey: peerKeyParsed, + UpdateOnly: true, + ReplaceAllowedIPs: false, + AllowedIPs: []net.IPNet{*ipNet}, + } + + config := wgtypes.Config{ + Peers: []wgtypes.PeerConfig{peer}, + } + + return c.tunDevice.Device().IpcSet(toWgUserspaceString(config)) +} + +func (c *wGConfigurer) removeAllowedIP(peerKey string, allowedIP string) error { + return errFuncNotImplemented +} diff --git a/iface/wg_configurer_nonandroid.go b/iface/wg_configurer_nonandroid.go index 6749c0966..239dd94fe 100644 --- a/iface/wg_configurer_nonandroid.go +++ b/iface/wg_configurer_nonandroid.go @@ -1,4 +1,4 @@ -//go:build !android +//go:build !android && !ios package iface @@ -44,7 +44,7 @@ func (c *wGConfigurer) configureInterface(privateKey string, port int) error { } func (c *wGConfigurer) updatePeer(peerKey string, allowedIps string, keepAlive time.Duration, endpoint *net.UDPAddr, preSharedKey *wgtypes.Key) error { - //parse allowed ips + // parse allowed ips _, ipNet, err := net.ParseCIDR(allowedIps) if err != nil { return err