Add WireGuard package (#236)

* Add WireGuard packages

- Use eduVPN script for WireGuardKitGo
- Wrap WireGuardKit entities into Configuration
- Split demo into OpenVPN/WireGuard controllers

* Rewrite README with multiple VPN protocols
This commit is contained in:
Davide De Rosa 2021-12-01 13:54:00 +01:00 committed by GitHub
parent ae6cb4e8dc
commit fda232edcb
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
33 changed files with 2356 additions and 208 deletions

View File

@ -5,6 +5,12 @@ All notable changes to this project will be documented in this file.
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
## Unreleased
### Added
- WireGuard support. [#236](https://github.com/passepartoutvpn/tunnelkit/pull/236)
## 4.0.3 (2021-11-27)
### Fixed

View File

@ -26,8 +26,10 @@
import Foundation
import TunnelKitCore
import TunnelKitOpenVPN
import TunnelKitWireGuard
struct Configuration {
extension OpenVPN {
struct DemoConfiguration {
static let ca = OpenVPN.CryptoContainer(pem: """
-----BEGIN CERTIFICATE-----
MIIG6zCCBNOgAwIBAgIJAJhm2PWFkE8NMA0GCSqGSIb3DQEBCwUAMIGpMQswCQYD
@ -186,4 +188,30 @@ M69t86apMrAxkUxVJAWLRBd9fbYyzJgTW61tFqXWTZpiz6bhuWApSEzaHcL3/f5l
builder.masksPrivateData = false
return builder.build()
}
}
}
extension WireGuard {
struct DemoConfiguration {
static func make(
clientPrivateKey: String,
clientAddress: String,
serverPublicKey: String,
serverAddress: String,
serverPort: String
) -> WireGuardProvider.Configuration? {
var builder = WireGuard.ConfigurationBuilder()
builder.privateKey = clientPrivateKey
builder.addresses = [clientAddress]
builder.peerPublicKey = serverPublicKey
builder.peerAddress = serverAddress
builder.peerPort = UInt16(serverPort)
builder.allowedIPs = ["0.0.0.0/0"]
builder.dns = ["1.1.1.1", "1.0.0.1"]
guard let cfg = builder.build() else {
return nil
}
return WireGuardProvider.Configuration(innerConfiguration: cfg)
}
}
}

View File

@ -5,7 +5,7 @@
<key>CFBundleDevelopmentRegion</key>
<string>$(DEVELOPMENT_LANGUAGE)</string>
<key>CFBundleDisplayName</key>
<string>BasicTunnelExtension</string>
<string>TunnelKitDemoTunnel</string>
<key>CFBundleExecutable</key>
<string>$(EXECUTABLE_NAME)</string>
<key>CFBundleIdentifier</key>

View File

@ -1,5 +1,5 @@
//
// PacketTunnelProvider.swift
// OpenVPNPacketTunnelProvider.swift
// Demo
//
// Created by Davide De Rosa on 9/15/17.

View File

@ -0,0 +1,29 @@
//
// WireGuardPacketTunnelProvider.swift
// Demo
//
// Created by Davide De Rosa on 11/22/21.
// Copyright (c) 2021 Davide De Rosa. All rights reserved.
//
// https://github.com/keeshux
//
// This file is part of TunnelKit.
//
// TunnelKit is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// TunnelKit is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with TunnelKit. If not, see <http://www.gnu.org/licenses/>.
//
import TunnelKitWireGuardAppExtension
class PacketTunnelProvider: WireGuardTunnelProvider {
}

View File

@ -1,16 +1,196 @@
<?xml version="1.0" encoding="UTF-8"?>
<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="16097" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" colorMatched="YES" initialViewController="BYZ-38-t0r">
<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="19455" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" colorMatched="YES" initialViewController="26T-Cw-BJR">
<device id="retina4_7" orientation="portrait" appearance="light"/>
<dependencies>
<deployment identifier="iOS"/>
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="16087"/>
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="19454"/>
<capability name="System colors in document resources" minToolsVersion="11.0"/>
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
</dependencies>
<scenes>
<!--View Controller-->
<!--Wire Guard View Controller-->
<scene sceneID="nUZ-T3-AkK">
<objects>
<viewController id="b1w-nH-Bgg" customClass="WireGuardViewController" customModule="TunnelKitDemo_iOS" customModuleProvider="target" sceneMemberID="viewController">
<layoutGuides>
<viewControllerLayoutGuide type="top" id="YGc-BB-45n"/>
<viewControllerLayoutGuide type="bottom" id="Rh4-AH-xlg"/>
</layoutGuides>
<view key="view" contentMode="scaleToFill" id="yMG-68-KNY">
<rect key="frame" x="0.0" y="0.0" width="375" height="667"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<subviews>
<view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="dJK-qq-9T9">
<rect key="frame" x="0.0" y="44" width="375" height="623"/>
<subviews>
<textField opaque="NO" clipsSubviews="YES" contentMode="scaleToFill" contentHorizontalAlignment="left" contentVerticalAlignment="center" borderStyle="roundedRect" textAlignment="natural" minimumFontSize="17" clearButtonMode="always" translatesAutoresizingMaskIntoConstraints="NO" id="dIW-lB-7WF">
<rect key="frame" x="20" y="128" width="335" height="34"/>
<fontDescription key="fontDescription" type="system" pointSize="14"/>
<textInputTraits key="textInputTraits" autocorrectionType="no" spellCheckingType="no" keyboardType="alphabet" secureTextEntry="YES"/>
</textField>
<textField opaque="NO" clipsSubviews="YES" contentMode="scaleToFill" contentHorizontalAlignment="left" contentVerticalAlignment="center" borderStyle="roundedRect" textAlignment="natural" minimumFontSize="17" clearButtonMode="always" translatesAutoresizingMaskIntoConstraints="NO" id="IeJ-5Y-kdR">
<rect key="frame" x="20" y="74" width="335" height="34"/>
<fontDescription key="fontDescription" type="system" pointSize="14"/>
<textInputTraits key="textInputTraits" autocorrectionType="no" spellCheckingType="no" keyboardType="alphabet"/>
</textField>
<textField opaque="NO" clipsSubviews="YES" contentMode="scaleToFill" contentHorizontalAlignment="left" contentVerticalAlignment="center" borderStyle="roundedRect" textAlignment="natural" minimumFontSize="17" clearButtonMode="always" translatesAutoresizingMaskIntoConstraints="NO" id="NL5-P8-ffu">
<rect key="frame" x="20" y="182" width="245" height="34"/>
<fontDescription key="fontDescription" type="system" pointSize="14"/>
<textInputTraits key="textInputTraits" autocorrectionType="no" spellCheckingType="no" keyboardType="alphabet"/>
</textField>
<textField opaque="NO" clipsSubviews="YES" contentMode="scaleToFill" contentHorizontalAlignment="left" contentVerticalAlignment="center" borderStyle="roundedRect" textAlignment="natural" minimumFontSize="17" translatesAutoresizingMaskIntoConstraints="NO" id="neV-25-hSD">
<rect key="frame" x="275" y="182" width="80" height="34"/>
<constraints>
<constraint firstAttribute="width" constant="80" id="yDW-rv-uJL"/>
</constraints>
<fontDescription key="fontDescription" type="system" pointSize="14"/>
<textInputTraits key="textInputTraits"/>
</textField>
</subviews>
<color key="backgroundColor" systemColor="systemBackgroundColor"/>
<constraints>
<constraint firstItem="IeJ-5Y-kdR" firstAttribute="leading" secondItem="dIW-lB-7WF" secondAttribute="leading" id="O2S-h8-CCf"/>
<constraint firstItem="dIW-lB-7WF" firstAttribute="top" secondItem="IeJ-5Y-kdR" secondAttribute="bottom" constant="20" id="cuT-Ax-tG2"/>
<constraint firstItem="neV-25-hSD" firstAttribute="centerY" secondItem="NL5-P8-ffu" secondAttribute="centerY" id="kYa-bZ-Zcu"/>
<constraint firstItem="neV-25-hSD" firstAttribute="leading" secondItem="NL5-P8-ffu" secondAttribute="trailing" constant="10" id="m0M-df-psQ"/>
<constraint firstItem="NL5-P8-ffu" firstAttribute="top" secondItem="dIW-lB-7WF" secondAttribute="bottom" constant="20" id="rZe-1R-kkn"/>
<constraint firstItem="IeJ-5Y-kdR" firstAttribute="trailing" secondItem="dIW-lB-7WF" secondAttribute="trailing" id="vhb-Lu-oGq"/>
</constraints>
</view>
<textField opaque="NO" clipsSubviews="YES" contentMode="scaleToFill" contentHorizontalAlignment="left" contentVerticalAlignment="center" borderStyle="roundedRect" textAlignment="natural" minimumFontSize="17" clearButtonMode="always" translatesAutoresizingMaskIntoConstraints="NO" id="ilf-E0-oHx">
<rect key="frame" x="20" y="64" width="335" height="34"/>
<fontDescription key="fontDescription" type="system" pointSize="14"/>
<textInputTraits key="textInputTraits" autocorrectionType="no" spellCheckingType="no" keyboardType="alphabet"/>
</textField>
<button opaque="NO" contentMode="scaleToFill" horizontalHuggingPriority="249" contentHorizontalAlignment="left" contentVerticalAlignment="center" buttonType="system" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="Qvn-sk-hgq">
<rect key="frame" x="20" y="280" width="175" height="70"/>
<fontDescription key="fontDescription" type="system" pointSize="48"/>
<state key="normal" title="Connect"/>
<connections>
<action selector="connectionClicked:" destination="BYZ-38-t0r" eventType="touchUpInside" id="9zR-rY-dbb"/>
<action selector="connectionClicked:" destination="b1w-nH-Bgg" eventType="touchUpInside" id="S1R-FS-6pE"/>
</connections>
</button>
</subviews>
<color key="backgroundColor" systemColor="systemBackgroundColor"/>
<constraints>
<constraint firstAttribute="trailing" secondItem="ilf-E0-oHx" secondAttribute="trailing" constant="20" id="4kR-Vq-VaE"/>
<constraint firstItem="neV-25-hSD" firstAttribute="trailing" secondItem="ilf-E0-oHx" secondAttribute="trailing" id="9ix-OI-Xs8"/>
<constraint firstItem="IeJ-5Y-kdR" firstAttribute="trailing" secondItem="ilf-E0-oHx" secondAttribute="trailing" id="GtB-dJ-eSM"/>
<constraint firstItem="NL5-P8-ffu" firstAttribute="leading" secondItem="ilf-E0-oHx" secondAttribute="leading" id="JVf-BM-EE5"/>
<constraint firstItem="Qvn-sk-hgq" firstAttribute="leading" secondItem="NL5-P8-ffu" secondAttribute="leading" id="MT8-V0-fRl"/>
<constraint firstItem="IeJ-5Y-kdR" firstAttribute="top" secondItem="ilf-E0-oHx" secondAttribute="bottom" constant="20" id="NsQ-7Z-5Wg"/>
<constraint firstItem="Rh4-AH-xlg" firstAttribute="top" secondItem="dJK-qq-9T9" secondAttribute="bottom" id="PL0-AU-ktf"/>
<constraint firstItem="dJK-qq-9T9" firstAttribute="leading" secondItem="yMG-68-KNY" secondAttribute="leading" id="Rmv-Oh-00v"/>
<constraint firstAttribute="trailing" secondItem="dJK-qq-9T9" secondAttribute="trailing" id="Tod-2R-cCt"/>
<constraint firstItem="dIW-lB-7WF" firstAttribute="leading" secondItem="ilf-E0-oHx" secondAttribute="leading" id="YD7-ZD-fCT"/>
<constraint firstItem="ilf-E0-oHx" firstAttribute="top" secondItem="YGc-BB-45n" secondAttribute="bottom" constant="20" id="afY-J4-d2k"/>
<constraint firstItem="ilf-E0-oHx" firstAttribute="leading" secondItem="yMG-68-KNY" secondAttribute="leading" constant="20" id="g8h-Jz-0oQ"/>
<constraint firstItem="IeJ-5Y-kdR" firstAttribute="leading" secondItem="ilf-E0-oHx" secondAttribute="leading" id="lLd-HB-IXI"/>
<constraint firstItem="Qvn-sk-hgq" firstAttribute="top" secondItem="NL5-P8-ffu" secondAttribute="bottom" constant="20" id="p7g-zX-vBF"/>
<constraint firstItem="dIW-lB-7WF" firstAttribute="trailing" secondItem="ilf-E0-oHx" secondAttribute="trailing" id="rLo-kl-jUg"/>
<constraint firstItem="dJK-qq-9T9" firstAttribute="top" secondItem="YGc-BB-45n" secondAttribute="bottom" id="tQl-FY-23s"/>
</constraints>
</view>
<navigationItem key="navigationItem" id="bbk-hQ-5N6"/>
<connections>
<outlet property="buttonConnection" destination="Qvn-sk-hgq" id="nWL-K1-VGY"/>
<outlet property="textAddress" destination="ilf-E0-oHx" id="2ej-fm-Bop"/>
<outlet property="textClientPrivateKey" destination="IeJ-5Y-kdR" id="eTK-WO-g4M"/>
<outlet property="textServerAddress" destination="NL5-P8-ffu" id="S6t-eV-M8h"/>
<outlet property="textServerPort" destination="neV-25-hSD" id="IeB-M1-cEt"/>
<outlet property="textServerPublicKey" destination="dIW-lB-7WF" id="aGG-DX-bTk"/>
</connections>
</viewController>
<placeholder placeholderIdentifier="IBFirstResponder" id="0Er-HZ-cLv" userLabel="First Responder" customClass="UIResponder" sceneMemberID="firstResponder"/>
</objects>
<point key="canvasLocation" x="140" y="863"/>
</scene>
<!--Navigation Controller-->
<scene sceneID="msq-sC-Gx0">
<objects>
<navigationController id="26T-Cw-BJR" sceneMemberID="viewController">
<navigationBar key="navigationBar" contentMode="scaleToFill" id="WTG-Q2-AEi">
<rect key="frame" x="0.0" y="0.0" width="375" height="44"/>
<autoresizingMask key="autoresizingMask"/>
</navigationBar>
<connections>
<segue destination="oPT-bs-cQ9" kind="relationship" relationship="rootViewController" id="ljP-y1-Mde"/>
</connections>
</navigationController>
<placeholder placeholderIdentifier="IBFirstResponder" id="uh4-Vj-Jlw" userLabel="First Responder" customClass="UIResponder" sceneMemberID="firstResponder"/>
</objects>
<point key="canvasLocation" x="-1516" y="411"/>
</scene>
<!--TunnelKit-->
<scene sceneID="yt7-nG-u2w">
<objects>
<tableViewController id="oPT-bs-cQ9" sceneMemberID="viewController">
<tableView key="view" clipsSubviews="YES" contentMode="scaleToFill" alwaysBounceVertical="YES" dataMode="static" style="plain" separatorStyle="default" rowHeight="-1" estimatedRowHeight="-1" sectionHeaderHeight="-1" estimatedSectionHeaderHeight="-1" sectionFooterHeight="-1" estimatedSectionFooterHeight="-1" id="mcO-tP-Zgf">
<rect key="frame" x="0.0" y="0.0" width="375" height="667"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<color key="backgroundColor" systemColor="systemBackgroundColor"/>
<sections>
<tableViewSection id="NMC-O0-zXz">
<cells>
<tableViewCell clipsSubviews="YES" contentMode="scaleToFill" preservesSuperviewLayoutMargins="YES" selectionStyle="default" accessoryType="disclosureIndicator" indentationWidth="10" textLabel="N8j-VD-UD4" style="IBUITableViewCellStyleDefault" id="IFH-Qn-oXj">
<rect key="frame" x="0.0" y="44.5" width="375" height="43.5"/>
<autoresizingMask key="autoresizingMask"/>
<tableViewCellContentView key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" preservesSuperviewLayoutMargins="YES" insetsLayoutMarginsFromSafeArea="NO" tableViewCell="IFH-Qn-oXj" id="DGt-4C-TmV">
<rect key="frame" x="0.0" y="0.0" width="349.5" height="43.5"/>
<autoresizingMask key="autoresizingMask"/>
<subviews>
<label opaque="NO" multipleTouchEnabled="YES" contentMode="left" insetsLayoutMarginsFromSafeArea="NO" text="OpenVPN" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" id="N8j-VD-UD4">
<rect key="frame" x="16" y="0.0" width="325.5" height="43.5"/>
<autoresizingMask key="autoresizingMask"/>
<fontDescription key="fontDescription" style="UICTFontTextStyleBody"/>
<nil key="textColor"/>
<nil key="highlightedColor"/>
</label>
</subviews>
</tableViewCellContentView>
<connections>
<segue destination="BYZ-38-t0r" kind="show" id="UUt-jB-TTT"/>
</connections>
</tableViewCell>
<tableViewCell clipsSubviews="YES" contentMode="scaleToFill" preservesSuperviewLayoutMargins="YES" selectionStyle="default" accessoryType="disclosureIndicator" indentationWidth="10" textLabel="gst-1a-WPM" style="IBUITableViewCellStyleDefault" id="rX5-QA-nhj">
<rect key="frame" x="0.0" y="88" width="375" height="43.5"/>
<autoresizingMask key="autoresizingMask"/>
<tableViewCellContentView key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" preservesSuperviewLayoutMargins="YES" insetsLayoutMarginsFromSafeArea="NO" tableViewCell="rX5-QA-nhj" id="evF-dj-ePY">
<rect key="frame" x="0.0" y="0.0" width="349.5" height="43.5"/>
<autoresizingMask key="autoresizingMask"/>
<subviews>
<label opaque="NO" multipleTouchEnabled="YES" contentMode="left" insetsLayoutMarginsFromSafeArea="NO" text="WireGuard" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" id="gst-1a-WPM">
<rect key="frame" x="16" y="0.0" width="325.5" height="43.5"/>
<autoresizingMask key="autoresizingMask"/>
<fontDescription key="fontDescription" style="UICTFontTextStyleBody"/>
<nil key="textColor"/>
<nil key="highlightedColor"/>
</label>
</subviews>
</tableViewCellContentView>
<connections>
<segue destination="b1w-nH-Bgg" kind="show" id="2BK-GQ-yWH"/>
</connections>
</tableViewCell>
</cells>
</tableViewSection>
</sections>
<connections>
<outlet property="dataSource" destination="oPT-bs-cQ9" id="epg-kz-wgw"/>
<outlet property="delegate" destination="oPT-bs-cQ9" id="ETI-HH-zua"/>
</connections>
</tableView>
<navigationItem key="navigationItem" title="TunnelKit" id="Nrl-LP-Alb"/>
</tableViewController>
<placeholder placeholderIdentifier="IBFirstResponder" id="Qkt-Qp-9ol" userLabel="First Responder" customClass="UIResponder" sceneMemberID="firstResponder"/>
</objects>
<point key="canvasLocation" x="-726" y="411"/>
</scene>
<!--OpenVPN View Controller-->
<scene sceneID="tne-QT-ifu">
<objects>
<viewController id="BYZ-38-t0r" customClass="ViewController" customModule="BasicTunnel_iOS" customModuleProvider="target" sceneMemberID="viewController">
<viewController id="BYZ-38-t0r" customClass="OpenVPNViewController" customModule="TunnelKitDemo_iOS" customModuleProvider="target" sceneMemberID="viewController">
<layoutGuides>
<viewControllerLayoutGuide type="top" id="y3c-jy-aDJ"/>
<viewControllerLayoutGuide type="bottom" id="wfy-db-euE"/>
@ -20,35 +200,35 @@
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<subviews>
<textField opaque="NO" clipsSubviews="YES" contentMode="scaleToFill" contentHorizontalAlignment="left" contentVerticalAlignment="center" borderStyle="roundedRect" textAlignment="natural" minimumFontSize="17" clearButtonMode="always" translatesAutoresizingMaskIntoConstraints="NO" id="bc6-yT-aty">
<rect key="frame" x="20" y="182" width="335" height="34"/>
<rect key="frame" x="20" y="226" width="335" height="34"/>
<fontDescription key="fontDescription" type="system" pointSize="14"/>
<textInputTraits key="textInputTraits" autocorrectionType="no" spellCheckingType="no" keyboardType="alphabet" secureTextEntry="YES"/>
</textField>
<textField opaque="NO" clipsSubviews="YES" contentMode="scaleToFill" contentHorizontalAlignment="left" contentVerticalAlignment="center" borderStyle="roundedRect" textAlignment="natural" minimumFontSize="17" clearButtonMode="always" translatesAutoresizingMaskIntoConstraints="NO" id="ONL-vF-iUY">
<rect key="frame" x="20" y="20" width="335" height="34"/>
<rect key="frame" x="20" y="64" width="335" height="34"/>
<fontDescription key="fontDescription" type="system" pointSize="14"/>
<textInputTraits key="textInputTraits" autocorrectionType="no" spellCheckingType="no" keyboardType="alphabet"/>
</textField>
<textField opaque="NO" clipsSubviews="YES" contentMode="scaleToFill" contentHorizontalAlignment="left" contentVerticalAlignment="center" borderStyle="roundedRect" textAlignment="natural" minimumFontSize="17" clearButtonMode="always" translatesAutoresizingMaskIntoConstraints="NO" id="dQS-Ma-dYP">
<rect key="frame" x="20" y="128" width="335" height="34"/>
<rect key="frame" x="20" y="172" width="335" height="34"/>
<fontDescription key="fontDescription" type="system" pointSize="14"/>
<textInputTraits key="textInputTraits" autocorrectionType="no" spellCheckingType="no" keyboardType="alphabet"/>
</textField>
<textField opaque="NO" clipsSubviews="YES" contentMode="scaleToFill" contentHorizontalAlignment="left" contentVerticalAlignment="center" borderStyle="roundedRect" textAlignment="natural" minimumFontSize="17" clearButtonMode="always" translatesAutoresizingMaskIntoConstraints="NO" id="XwE-sE-aPN">
<rect key="frame" x="20" y="74" width="245" height="34"/>
<rect key="frame" x="20" y="118" width="245" height="34"/>
<fontDescription key="fontDescription" type="system" pointSize="14"/>
<textInputTraits key="textInputTraits" autocorrectionType="no" spellCheckingType="no" keyboardType="alphabet"/>
</textField>
<textField opaque="NO" clipsSubviews="YES" contentMode="scaleToFill" contentHorizontalAlignment="left" contentVerticalAlignment="center" borderStyle="roundedRect" textAlignment="natural" minimumFontSize="17" translatesAutoresizingMaskIntoConstraints="NO" id="7LH-tE-it9">
<rect key="frame" x="275" y="74" width="80" height="34"/>
<rect key="frame" x="275" y="118" width="80" height="34"/>
<constraints>
<constraint firstAttribute="width" constant="80" id="aWP-Ug-b9B"/>
</constraints>
<fontDescription key="fontDescription" type="system" pointSize="14"/>
<textInputTraits key="textInputTraits"/>
</textField>
<button opaque="NO" contentMode="scaleToFill" horizontalHuggingPriority="249" contentHorizontalAlignment="left" contentVerticalAlignment="center" buttonType="roundedRect" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="Teo-8d-LYJ">
<rect key="frame" x="20" y="236" width="276" height="70"/>
<button opaque="NO" contentMode="scaleToFill" horizontalHuggingPriority="249" contentHorizontalAlignment="left" contentVerticalAlignment="center" buttonType="system" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="Teo-8d-LYJ">
<rect key="frame" x="20" y="280" width="276" height="70"/>
<fontDescription key="fontDescription" type="system" pointSize="48"/>
<state key="normal" title="Connect"/>
<connections>
@ -56,19 +236,19 @@
</connections>
</button>
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="TCP" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="sA4-W9-jxo">
<rect key="frame" x="312" y="236" width="37.5" height="24"/>
<rect key="frame" x="312" y="280" width="37.5" height="24"/>
<fontDescription key="fontDescription" type="system" pointSize="20"/>
<nil key="textColor"/>
<nil key="highlightedColor"/>
</label>
<switch opaque="NO" contentMode="scaleToFill" horizontalHuggingPriority="750" verticalHuggingPriority="750" contentHorizontalAlignment="center" contentVerticalAlignment="center" translatesAutoresizingMaskIntoConstraints="NO" id="WZf-S5-SqC">
<rect key="frame" x="306" y="275" width="51" height="31"/>
<rect key="frame" x="306" y="319" width="51" height="31"/>
<connections>
<action selector="tcpClicked:" destination="BYZ-38-t0r" eventType="valueChanged" id="ZJI-Jw-pow"/>
</connections>
</switch>
<button opaque="NO" contentMode="scaleToFill" horizontalHuggingPriority="249" contentHorizontalAlignment="left" contentVerticalAlignment="center" buttonType="roundedRect" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="6dU-fF-FSg">
<rect key="frame" x="20" y="306" width="335" height="41"/>
<button opaque="NO" contentMode="scaleToFill" horizontalHuggingPriority="249" contentHorizontalAlignment="left" contentVerticalAlignment="center" buttonType="system" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="6dU-fF-FSg">
<rect key="frame" x="20" y="350" width="335" height="41"/>
<fontDescription key="fontDescription" type="system" pointSize="24"/>
<state key="normal" title="See log"/>
<connections>
@ -76,13 +256,13 @@
</connections>
</button>
<textView clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="scaleToFill" editable="NO" textAlignment="natural" translatesAutoresizingMaskIntoConstraints="NO" id="UNN-CR-rdr">
<rect key="frame" x="20" y="367" width="335" height="280"/>
<color key="backgroundColor" cocoaTouchSystemColor="groupTableViewBackgroundColor"/>
<rect key="frame" x="20" y="411" width="335" height="236"/>
<color key="backgroundColor" systemColor="groupTableViewBackgroundColor"/>
<fontDescription key="fontDescription" name="CourierNewPSMT" family="Courier New" pointSize="17"/>
<textInputTraits key="textInputTraits" autocapitalizationType="sentences"/>
</textView>
</subviews>
<color key="backgroundColor" systemColor="systemBackgroundColor" cocoaTouchSystemColor="whiteColor"/>
<color key="backgroundColor" systemColor="systemBackgroundColor"/>
<constraints>
<constraint firstItem="UNN-CR-rdr" firstAttribute="top" secondItem="6dU-fF-FSg" secondAttribute="bottom" constant="20" id="03h-H3-dSN"/>
<constraint firstItem="7LH-tE-it9" firstAttribute="centerY" secondItem="XwE-sE-aPN" secondAttribute="centerY" id="0wJ-c9-Gcy"/>
@ -114,6 +294,7 @@
<constraint firstAttribute="trailing" secondItem="WZf-S5-SqC" secondAttribute="trailing" constant="20" id="wMy-Qf-9Bi"/>
</constraints>
</view>
<navigationItem key="navigationItem" id="YgB-QB-eLJ"/>
<connections>
<outlet property="buttonConnection" destination="Teo-8d-LYJ" id="evE-2I-13A"/>
<outlet property="switchTCP" destination="WZf-S5-SqC" id="UyR-J2-iX0"/>
@ -130,4 +311,12 @@
<point key="canvasLocation" x="140" y="137.18140929535232"/>
</scene>
</scenes>
<resources>
<systemColor name="groupTableViewBackgroundColor">
<color red="0.94901960784313721" green="0.94901960784313721" blue="0.96862745098039216" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
</systemColor>
<systemColor name="systemBackgroundColor">
<color white="1" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
</systemColor>
</resources>
</document>

View File

@ -1,5 +1,5 @@
//
// ViewController.swift
// OpenVPNViewController.swift
// Demo
//
// Created by Davide De Rosa on 2/11/17.
@ -25,15 +25,14 @@
import UIKit
import TunnelKitCore
import TunnelKitAppExtension
import TunnelKitManager
import TunnelKitOpenVPN
private let appGroup = "group.com.algoritmico.TunnelKit.Demo"
private let tunnelIdentifier = "com.algoritmico.ios.TunnelKit.Demo.Tunnel"
private let tunnelIdentifier = "com.algoritmico.ios.TunnelKit.Demo.OpenVPN.Tunnel"
class ViewController: UIViewController, URLSessionDataDelegate {
class OpenVPNViewController: UIViewController {
@IBOutlet var textUsername: UITextField!
@IBOutlet var textPassword: UITextField!
@ -97,14 +96,14 @@ class ViewController: UIViewController, URLSessionDataDelegate {
let socketType: SocketType = switchTCP.isOn ? .tcp : .udp
let credentials = OpenVPN.Credentials(textUsername.text!, textPassword.text!)
let cfg = Configuration.make(hostname: hostname, port: port, socketType: socketType)
let cfg = OpenVPN.DemoConfiguration.make(hostname: hostname, port: port, socketType: socketType)
let proto = try! cfg.generatedTunnelProtocol(
withBundleIdentifier: tunnelIdentifier,
appGroup: appGroup,
context: tunnelIdentifier,
credentials: credentials
)
let neCfg = NetworkExtensionVPNConfiguration(title: "BasicTunnel", protocolConfiguration: proto, onDemandRules: [])
let neCfg = NetworkExtensionVPNConfiguration(title: "TunnelKit.OpenVPN", protocolConfiguration: proto, onDemandRules: [])
vpn.reconnect(configuration: neCfg) { (error) in
if let error = error {
print("configure error: \(error)")

View File

@ -0,0 +1,134 @@
//
// WireGuardViewController.swift
// Demo
//
// Created by Davide De Rosa on 11/22/21.
// Copyright (c) 2021 Davide De Rosa. All rights reserved.
//
// https://github.com/keeshux
//
// This file is part of TunnelKit.
//
// TunnelKit is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// TunnelKit is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with TunnelKit. If not, see <http://www.gnu.org/licenses/>.
//
import UIKit
import TunnelKitManager
import TunnelKitWireGuard
import NetworkExtension
private let appGroup = "group.com.algoritmico.TunnelKit.Demo"
private let tunnelIdentifier = "com.algoritmico.ios.TunnelKit.Demo.WireGuard.Tunnel"
class WireGuardViewController: UIViewController {
@IBOutlet var textClientPrivateKey: UITextField!
@IBOutlet var textAddress: UITextField!
@IBOutlet var textServerPublicKey: UITextField!
@IBOutlet var textServerAddress: UITextField!
@IBOutlet var textServerPort: UITextField!
@IBOutlet var buttonConnection: UIButton!
private let vpn = WireGuardProvider(bundleIdentifier: tunnelIdentifier)
override func viewDidLoad() {
super.viewDidLoad()
textClientPrivateKey.placeholder = "client private key"
textAddress.placeholder = "client address"
textServerPublicKey.placeholder = "server public key"
textServerAddress.placeholder = "server address"
textServerPort.placeholder = "server port"
textAddress.text = "192.168.30.2/32"
NotificationCenter.default.addObserver(
self,
selector: #selector(VPNStatusDidChange(notification:)),
name: VPN.didChangeStatus,
object: nil
)
vpn.prepare(completionHandler: nil)
}
@IBAction func connectionClicked(_ sender: Any) {
switch vpn.status {
case .disconnected:
connect()
case .connected, .connecting, .disconnecting:
disconnect()
}
}
func connect() {
let clientPrivateKey = textClientPrivateKey.text!
let clientAddress = textAddress.text!
let serverPublicKey = textServerPublicKey.text!
let serverAddress = textServerAddress.text!
let serverPort = textServerPort.text!
guard let cfg = WireGuard.DemoConfiguration.make(
clientPrivateKey: clientPrivateKey,
clientAddress: clientAddress,
serverPublicKey: serverPublicKey,
serverAddress: serverAddress,
serverPort: serverPort
) else {
print("Configuration incomplete")
return
}
let proto = try! cfg.generatedTunnelProtocol(
withBundleIdentifier: tunnelIdentifier,
appGroup: appGroup,
context: tunnelIdentifier
)
let neCfg = NetworkExtensionVPNConfiguration(title: "TunnelKit.WireGuard", protocolConfiguration: proto, onDemandRules: [])
vpn.reconnect(configuration: neCfg) { (error) in
if let error = error {
print("configure error: \(error)")
return
}
}
}
func disconnect() {
vpn.disconnect(completionHandler: nil)
}
func updateButton() {
switch vpn.status {
case .connected, .connecting:
buttonConnection.setTitle("Disconnect", for: .normal)
case .disconnected:
buttonConnection.setTitle("Connect", for: .normal)
case .disconnecting:
buttonConnection.setTitle("Disconnecting", for: .normal)
}
}
@objc private func VPNStatusDidChange(notification: NSNotification) {
print("VPNStatusDidChange: \(vpn.status)")
updateButton()
}
}

View File

@ -1,8 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<document type="com.apple.InterfaceBuilder3.Cocoa.Storyboard.XIB" version="3.0" toolsVersion="17701" targetRuntime="MacOSX.Cocoa" propertyAccessControl="none" useAutolayout="YES" initialViewController="B8D-0N-5wS">
<document type="com.apple.InterfaceBuilder3.Cocoa.Storyboard.XIB" version="3.0" toolsVersion="19455" targetRuntime="MacOSX.Cocoa" propertyAccessControl="none" useAutolayout="YES" initialViewController="B8D-0N-5wS">
<dependencies>
<deployment identifier="macosx"/>
<plugIn identifier="com.apple.InterfaceBuilder.CocoaPlugin" version="17701"/>
<plugIn identifier="com.apple.InterfaceBuilder.CocoaPlugin" version="19455"/>
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
</dependencies>
<scenes>
@ -12,11 +12,11 @@
<application id="hnw-xV-0zn" sceneMemberID="viewController">
<menu key="mainMenu" title="Main Menu" systemMenu="main" id="AYu-sK-qS6">
<items>
<menuItem title="BasicTunnelMac" id="1Xt-HY-uBw">
<menuItem title="TunnelKitDemo" id="1Xt-HY-uBw" userLabel="TunnelKitDemo">
<modifierMask key="keyEquivalentModifierMask"/>
<menu key="submenu" title="BasicTunnelMac" systemMenu="apple" id="uQy-DD-JDr">
<menu key="submenu" title="TunnelKitDemo" systemMenu="apple" id="uQy-DD-JDr">
<items>
<menuItem title="About BasicTunnelMac" id="5kV-Vb-QxS">
<menuItem title="About TunnelKitDemo" id="5kV-Vb-QxS">
<modifierMask key="keyEquivalentModifierMask"/>
<connections>
<action selector="orderFrontStandardAboutPanel:" target="Ady-hI-5gd" id="Exp-CZ-Vem"/>
@ -30,7 +30,7 @@
<menu key="submenu" title="Services" systemMenu="services" id="hz9-B4-Xy5"/>
</menuItem>
<menuItem isSeparatorItem="YES" id="4je-JR-u6R"/>
<menuItem title="Hide BasicTunnelMac" keyEquivalent="h" id="Olw-nP-bQN">
<menuItem title="Hide TunnelKitDemo" keyEquivalent="h" id="Olw-nP-bQN">
<connections>
<action selector="hide:" target="Ady-hI-5gd" id="PnN-Uc-m68"/>
</connections>
@ -48,7 +48,7 @@
</connections>
</menuItem>
<menuItem isSeparatorItem="YES" id="kCx-OE-vgT"/>
<menuItem title="Quit BasicTunnelMac" keyEquivalent="q" id="4sb-4s-VLi">
<menuItem title="Quit TunnelKitDemo" keyEquivalent="q" id="4sb-4s-VLi">
<connections>
<action selector="terminate:" target="Ady-hI-5gd" id="Te7-pn-YzF"/>
</connections>
@ -661,7 +661,7 @@
<modifierMask key="keyEquivalentModifierMask"/>
<menu key="submenu" title="Help" systemMenu="help" id="F2S-fz-NVQ">
<items>
<menuItem title="BasicTunnelMac Help" keyEquivalent="?" id="FKE-Sm-Kum">
<menuItem title="TunnelKitDemo Help" keyEquivalent="?" id="FKE-Sm-Kum">
<connections>
<action selector="showHelp:" target="Ady-hI-5gd" id="y7X-2Q-9no"/>
</connections>
@ -675,17 +675,17 @@
<outlet property="delegate" destination="Voe-Tx-rLC" id="PrD-fu-P6m"/>
</connections>
</application>
<customObject id="Voe-Tx-rLC" customClass="AppDelegate" customModule="Demo_macOS" customModuleProvider="target"/>
<customObject id="Voe-Tx-rLC" customClass="AppDelegate" customModule="TunnelKitDemo_macOS" customModuleProvider="target"/>
<customObject id="YLy-65-1bz" customClass="NSFontManager"/>
<customObject id="Ady-hI-5gd" userLabel="First Responder" customClass="NSResponder" sceneMemberID="firstResponder"/>
</objects>
<point key="canvasLocation" x="75" y="0.0"/>
<point key="canvasLocation" x="-662" y="-582"/>
</scene>
<!--Window Controller-->
<scene sceneID="R2V-B0-nI4">
<objects>
<windowController id="B8D-0N-5wS" sceneMemberID="viewController">
<window key="window" title="Window" allowsToolTipsWhenApplicationIsInactive="NO" autorecalculatesKeyViewLoop="NO" releasedWhenClosed="NO" visibleAtLaunch="NO" animationBehavior="default" id="IQv-IB-iLA">
<window key="window" title="TunnelKit" allowsToolTipsWhenApplicationIsInactive="NO" autorecalculatesKeyViewLoop="NO" releasedWhenClosed="NO" visibleAtLaunch="NO" animationBehavior="default" titlebarAppearsTransparent="YES" id="IQv-IB-iLA">
<windowStyleMask key="styleMask" titled="YES" closable="YES" miniaturizable="YES" resizable="YES"/>
<windowPositionMask key="initialPositionMask" leftStrut="YES" rightStrut="YES" topStrut="YES" bottomStrut="YES"/>
<rect key="contentRect" x="196" y="240" width="480" height="480"/>
@ -695,17 +695,150 @@
</connections>
</window>
<connections>
<segue destination="XfG-lQ-9wD" kind="relationship" relationship="window.shadowedContentViewController" id="cq2-FE-JQM"/>
<segue destination="Ph7-kL-etv" kind="relationship" relationship="window.shadowedContentViewController" id="J86-FA-iJb"/>
</connections>
</windowController>
<customObject id="Oky-zY-oP4" userLabel="First Responder" customClass="NSResponder" sceneMemberID="firstResponder"/>
</objects>
<point key="canvasLocation" x="75" y="250"/>
<point key="canvasLocation" x="-656" y="-222"/>
</scene>
<!--View Controller-->
<!--Tab View Controller-->
<scene sceneID="ygq-sG-3Ln">
<objects>
<tabViewController selectedTabViewItemIndex="0" id="Ph7-kL-etv" sceneMemberID="viewController">
<tabViewItems>
<tabViewItem id="p9v-bL-mqr"/>
<tabViewItem id="Ocn-Fg-u0t"/>
</tabViewItems>
<tabView key="tabView" type="noTabsNoBorder" id="iR8-80-79B">
<rect key="frame" x="0.0" y="0.0" width="450" height="300"/>
<autoresizingMask key="autoresizingMask"/>
<font key="font" metaFont="message"/>
<connections>
<outlet property="delegate" destination="Ph7-kL-etv" id="E0r-Ol-Xr3"/>
</connections>
</tabView>
<connections>
<outlet property="tabView" destination="iR8-80-79B" id="GQL-C9-54d"/>
<segue destination="XfG-lQ-9wD" kind="relationship" relationship="tabItems" id="EL7-V7-Rli"/>
<segue destination="veh-JO-i63" kind="relationship" relationship="tabItems" id="bXX-lO-UXd"/>
</connections>
</tabViewController>
<customObject id="eeQ-AU-wde" userLabel="First Responder" customClass="NSResponder" sceneMemberID="firstResponder"/>
</objects>
<point key="canvasLocation" x="-656" y="404"/>
</scene>
<!--WireGuard-->
<scene sceneID="Gpw-y6-EY1">
<objects>
<viewController title="WireGuard" id="veh-JO-i63" customClass="WireGuardViewController" customModule="TunnelKitDemo_macOS" customModuleProvider="target" sceneMemberID="viewController">
<view key="view" id="dOb-bH-xlV">
<rect key="frame" x="0.0" y="0.0" width="480" height="182"/>
<autoresizingMask key="autoresizingMask"/>
<subviews>
<customView translatesAutoresizingMaskIntoConstraints="NO" id="rq1-jz-XJV">
<rect key="frame" x="20" y="20" width="440" height="142"/>
<subviews>
<textField verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="uR4-9E-kLl">
<rect key="frame" x="0.0" y="121" width="440" height="21"/>
<textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" selectable="YES" editable="YES" sendsActionOnEndEditing="YES" borderStyle="bezel" drawsBackground="YES" id="JRs-jT-MUr">
<font key="font" usesAppearanceFont="YES"/>
<color key="textColor" name="controlTextColor" catalog="System" colorSpace="catalog"/>
<color key="backgroundColor" name="textBackgroundColor" catalog="System" colorSpace="catalog"/>
</textFieldCell>
</textField>
<textField verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="nk0-nl-iaW">
<rect key="frame" x="0.0" y="90" width="440" height="21"/>
<textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" selectable="YES" editable="YES" sendsActionOnEndEditing="YES" borderStyle="bezel" drawsBackground="YES" id="KgL-In-jV9">
<font key="font" usesAppearanceFont="YES"/>
<color key="textColor" name="controlTextColor" catalog="System" colorSpace="catalog"/>
<color key="backgroundColor" name="textBackgroundColor" catalog="System" colorSpace="catalog"/>
</textFieldCell>
</textField>
<textField verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="KGQ-ny-X4s">
<rect key="frame" x="0.0" y="59" width="440" height="21"/>
<textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" selectable="YES" editable="YES" sendsActionOnEndEditing="YES" borderStyle="bezel" drawsBackground="YES" id="i7u-Xh-TAb">
<font key="font" usesAppearanceFont="YES"/>
<color key="textColor" name="controlTextColor" catalog="System" colorSpace="catalog"/>
<color key="backgroundColor" name="textBackgroundColor" catalog="System" colorSpace="catalog"/>
</textFieldCell>
</textField>
<textField verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="2qO-tT-LCY">
<rect key="frame" x="0.0" y="28" width="312" height="21"/>
<textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" selectable="YES" editable="YES" sendsActionOnEndEditing="YES" borderStyle="bezel" drawsBackground="YES" id="XR9-No-Udo">
<font key="font" usesAppearanceFont="YES"/>
<color key="textColor" name="controlTextColor" catalog="System" colorSpace="catalog"/>
<color key="backgroundColor" name="textBackgroundColor" catalog="System" colorSpace="catalog"/>
</textFieldCell>
</textField>
<button verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="Tiq-ap-zD3">
<rect key="frame" x="-7" y="-7" width="454" height="32"/>
<buttonCell key="cell" type="push" title="Connect" bezelStyle="rounded" alignment="center" borderStyle="border" imageScaling="proportionallyDown" inset="2" id="Mx7-Fy-SJ6">
<behavior key="behavior" pushIn="YES" lightByBackground="YES" lightByGray="YES"/>
<font key="font" metaFont="system"/>
</buttonCell>
<connections>
<action selector="connectionClicked:" target="veh-JO-i63" id="7yr-xP-5NW"/>
</connections>
</button>
<textField verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="0SZ-mT-ekY">
<rect key="frame" x="320" y="28" width="120" height="21"/>
<constraints>
<constraint firstAttribute="width" constant="120" id="Y6G-q2-muW"/>
</constraints>
<textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" selectable="YES" editable="YES" sendsActionOnEndEditing="YES" borderStyle="bezel" drawsBackground="YES" id="zL3-gF-dTw">
<font key="font" usesAppearanceFont="YES"/>
<color key="textColor" name="controlTextColor" catalog="System" colorSpace="catalog"/>
<color key="backgroundColor" name="textBackgroundColor" catalog="System" colorSpace="catalog"/>
</textFieldCell>
</textField>
</subviews>
<constraints>
<constraint firstAttribute="trailing" secondItem="0SZ-mT-ekY" secondAttribute="trailing" id="3ib-83-Fzq"/>
<constraint firstItem="Tiq-ap-zD3" firstAttribute="top" secondItem="2qO-tT-LCY" secondAttribute="bottom" constant="8" symbolic="YES" id="6CE-7C-VeP"/>
<constraint firstItem="Tiq-ap-zD3" firstAttribute="leading" secondItem="rq1-jz-XJV" secondAttribute="leading" id="8l4-c3-88J"/>
<constraint firstItem="2qO-tT-LCY" firstAttribute="top" secondItem="KGQ-ny-X4s" secondAttribute="bottom" constant="10" symbolic="YES" id="A49-xG-MpP"/>
<constraint firstItem="0SZ-mT-ekY" firstAttribute="centerY" secondItem="2qO-tT-LCY" secondAttribute="centerY" id="EKs-iy-CXT"/>
<constraint firstItem="0SZ-mT-ekY" firstAttribute="leading" secondItem="2qO-tT-LCY" secondAttribute="trailing" constant="8" symbolic="YES" id="EVP-mS-GXl"/>
<constraint firstAttribute="trailing" secondItem="KGQ-ny-X4s" secondAttribute="trailing" id="I2q-zJ-6dl"/>
<constraint firstItem="uR4-9E-kLl" firstAttribute="leading" secondItem="rq1-jz-XJV" secondAttribute="leading" id="K90-IM-FOm"/>
<constraint firstItem="2qO-tT-LCY" firstAttribute="leading" secondItem="rq1-jz-XJV" secondAttribute="leading" id="LHr-Ar-Ap5"/>
<constraint firstAttribute="trailing" secondItem="nk0-nl-iaW" secondAttribute="trailing" id="ei2-ya-hZT"/>
<constraint firstItem="nk0-nl-iaW" firstAttribute="leading" secondItem="rq1-jz-XJV" secondAttribute="leading" id="few-oS-Tyc"/>
<constraint firstItem="uR4-9E-kLl" firstAttribute="top" secondItem="rq1-jz-XJV" secondAttribute="top" id="fjG-U6-4v1"/>
<constraint firstAttribute="bottom" secondItem="Tiq-ap-zD3" secondAttribute="bottom" id="gEg-rf-8Ii"/>
<constraint firstItem="KGQ-ny-X4s" firstAttribute="top" secondItem="nk0-nl-iaW" secondAttribute="bottom" constant="10" symbolic="YES" id="gbO-Lm-2lv"/>
<constraint firstAttribute="trailing" secondItem="uR4-9E-kLl" secondAttribute="trailing" id="ikN-Ft-JeC"/>
<constraint firstItem="nk0-nl-iaW" firstAttribute="top" secondItem="uR4-9E-kLl" secondAttribute="bottom" constant="10" symbolic="YES" id="pri-94-Pto"/>
<constraint firstItem="KGQ-ny-X4s" firstAttribute="leading" secondItem="rq1-jz-XJV" secondAttribute="leading" id="q6z-Cn-J3z"/>
<constraint firstAttribute="trailing" secondItem="Tiq-ap-zD3" secondAttribute="trailing" id="yKA-nb-XUR"/>
</constraints>
</customView>
</subviews>
<constraints>
<constraint firstItem="rq1-jz-XJV" firstAttribute="leading" secondItem="dOb-bH-xlV" secondAttribute="leading" constant="20" symbolic="YES" id="SRf-9v-bqS"/>
<constraint firstAttribute="trailing" secondItem="rq1-jz-XJV" secondAttribute="trailing" constant="20" symbolic="YES" id="Tuh-wz-3pJ"/>
<constraint firstAttribute="bottom" secondItem="rq1-jz-XJV" secondAttribute="bottom" constant="20" symbolic="YES" id="Zn8-xp-J3m"/>
<constraint firstItem="rq1-jz-XJV" firstAttribute="top" secondItem="dOb-bH-xlV" secondAttribute="top" constant="20" symbolic="YES" id="gRO-l8-uod"/>
</constraints>
</view>
<connections>
<outlet property="buttonConnection" destination="Tiq-ap-zD3" id="lXt-h5-V0q"/>
<outlet property="textAddress" destination="uR4-9E-kLl" id="gFs-K9-BS6"/>
<outlet property="textClientPrivateKey" destination="nk0-nl-iaW" id="cdn-Vz-28s"/>
<outlet property="textServerAddress" destination="2qO-tT-LCY" id="1tc-22-pSB"/>
<outlet property="textServerPort" destination="0SZ-mT-ekY" id="xnt-oV-11k"/>
<outlet property="textServerPublicKey" destination="KGQ-ny-X4s" id="o26-MI-51j"/>
</connections>
</viewController>
<customObject id="jiZ-E1-ajD" userLabel="First Responder" customClass="NSResponder" sceneMemberID="firstResponder"/>
</objects>
<point key="canvasLocation" x="-1" y="521"/>
</scene>
<!--OpenVPN-->
<scene sceneID="hIz-AP-VOD">
<objects>
<viewController id="XfG-lQ-9wD" customClass="ViewController" customModule="Demo_macOS" customModuleProvider="target" sceneMemberID="viewController">
<viewController title="OpenVPN" id="XfG-lQ-9wD" customClass="OpenVPNViewController" customModule="TunnelKitDemo_macOS" customModuleProvider="target" sceneMemberID="viewController">
<view key="view" wantsLayer="YES" id="m2S-Jp-Qdl">
<rect key="frame" x="0.0" y="0.0" width="480" height="140"/>
<autoresizingMask key="autoresizingMask"/>
@ -798,7 +931,7 @@
</viewController>
<customObject id="rPt-NT-nkU" userLabel="First Responder" customClass="NSResponder" sceneMemberID="firstResponder"/>
</objects>
<point key="canvasLocation" x="75" y="708"/>
<point key="canvasLocation" x="-1" y="193"/>
</scene>
</scenes>
</document>

View File

@ -14,6 +14,8 @@
</array>
<key>com.apple.security.network.client</key>
<true/>
<key>com.apple.security.network.server</key>
<true/>
<key>keychain-access-groups</key>
<array>
<string>$(AppIdentifierPrefix)group.com.algoritmico.TunnelKit.Demo</string>

View File

@ -1,5 +1,5 @@
//
// ViewController.swift
// OpenVPNViewController.swift
// Demo
//
// Created by Davide De Rosa on 10/15/17.
@ -25,15 +25,14 @@
import Cocoa
import TunnelKitCore
import TunnelKitAppExtension
import TunnelKitManager
import TunnelKitOpenVPN
private let appGroup = "DTDYD63ZX9.group.com.algoritmico.TunnelKit.Demo"
private let tunnelIdentifier = "com.algoritmico.macos.TunnelKit.Demo.Tunnel"
private let tunnelIdentifier = "com.algoritmico.macos.TunnelKit.Demo.OpenVPN.Tunnel"
class ViewController: NSViewController {
class OpenVPNViewController: NSViewController {
@IBOutlet var textUsername: NSTextField!
@IBOutlet var textPassword: NSTextField!
@ -88,14 +87,14 @@ class ViewController: NSViewController {
let port = UInt16(textPort.stringValue)!
let credentials = OpenVPN.Credentials(textUsername.stringValue, textPassword.stringValue)
let cfg = Configuration.make(hostname: hostname, port: port, socketType: .udp)
let cfg = OpenVPN.DemoConfiguration.make(hostname: hostname, port: port, socketType: .udp)
let proto = try! cfg.generatedTunnelProtocol(
withBundleIdentifier: tunnelIdentifier,
appGroup: appGroup,
context: tunnelIdentifier,
credentials: credentials
)
let neCfg = NetworkExtensionVPNConfiguration(title: "BasicTunnel", protocolConfiguration: proto, onDemandRules: [])
let neCfg = NetworkExtensionVPNConfiguration(title: "TunnelKit.OpenVPN", protocolConfiguration: proto, onDemandRules: [])
vpn.reconnect(configuration: neCfg) { (error) in
if let error = error {
print("configure error: \(error)")

View File

@ -0,0 +1,134 @@
//
// WireGuardViewController.swift
// Demo
//
// Created by Davide De Rosa on 11/22/21.
// Copyright (c) 2021 Davide De Rosa. All rights reserved.
//
// https://github.com/keeshux
//
// This file is part of TunnelKit.
//
// TunnelKit is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// TunnelKit is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with TunnelKit. If not, see <http://www.gnu.org/licenses/>.
//
import Cocoa
import TunnelKitManager
import TunnelKitWireGuard
import NetworkExtension
private let appGroup = "DTDYD63ZX9.group.com.algoritmico.TunnelKit.Demo"
private let tunnelIdentifier = "com.algoritmico.macos.TunnelKit.Demo.WireGuard.Tunnel"
class WireGuardViewController: NSViewController {
@IBOutlet var textClientPrivateKey: NSTextField!
@IBOutlet var textAddress: NSTextField!
@IBOutlet var textServerPublicKey: NSTextField!
@IBOutlet var textServerAddress: NSTextField!
@IBOutlet var textServerPort: NSTextField!
@IBOutlet var buttonConnection: NSButton!
private let vpn = WireGuardProvider(bundleIdentifier: tunnelIdentifier)
override func viewDidLoad() {
super.viewDidLoad()
textClientPrivateKey.placeholderString = "client private key"
textAddress.placeholderString = "client address"
textServerPublicKey.placeholderString = "server public key"
textServerAddress.placeholderString = "server address"
textServerPort.placeholderString = "server port"
textAddress.stringValue = "192.168.30.2/32"
NotificationCenter.default.addObserver(
self,
selector: #selector(VPNStatusDidChange(notification:)),
name: VPN.didChangeStatus,
object: nil
)
vpn.prepare(completionHandler: nil)
}
@IBAction func connectionClicked(_ sender: Any) {
switch vpn.status {
case .disconnected:
connect()
case .connected, .connecting, .disconnecting:
disconnect()
}
}
func connect() {
let clientPrivateKey = textClientPrivateKey.stringValue
let clientAddress = textAddress.stringValue
let serverPublicKey = textServerPublicKey.stringValue
let serverAddress = textServerAddress.stringValue
let serverPort = textServerPort.stringValue
guard let cfg = WireGuard.DemoConfiguration.make(
clientPrivateKey: clientPrivateKey,
clientAddress: clientAddress,
serverPublicKey: serverPublicKey,
serverAddress: serverAddress,
serverPort: serverPort
) else {
print("Configuration incomplete")
return
}
let proto = try! cfg.generatedTunnelProtocol(
withBundleIdentifier: tunnelIdentifier,
appGroup: appGroup,
context: tunnelIdentifier
)
let neCfg = NetworkExtensionVPNConfiguration(title: "TunnelKit.WireGuard", protocolConfiguration: proto, onDemandRules: [])
vpn.reconnect(configuration: neCfg) { (error) in
if let error = error {
print("configure error: \(error)")
return
}
}
}
func disconnect() {
vpn.disconnect(completionHandler: nil)
}
func updateButton() {
switch vpn.status {
case .connected, .connecting:
buttonConnection.title = "Disconnect"
case .disconnected:
buttonConnection.title = "Connect"
case .disconnecting:
buttonConnection.title = "Disconnecting"
}
}
@objc private func VPNStatusDidChange(notification: NSNotification) {
print("VPNStatusDidChange: \(vpn.status)")
updateButton()
}
}

View File

@ -8,22 +8,22 @@
/* Begin PBXBuildFile section */
0E05418725A2334500EFC5FF /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0E05414B25A231D500EFC5FF /* AppDelegate.swift */; };
0E05418825A2334500EFC5FF /* ViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0E05414425A231D500EFC5FF /* ViewController.swift */; };
0E05418825A2334500EFC5FF /* OpenVPNViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0E05414425A231D500EFC5FF /* OpenVPNViewController.swift */; };
0E05418925A2334500EFC5FF /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 0E05414525A231D500EFC5FF /* Assets.xcassets */; };
0E05418A25A2334900EFC5FF /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 0E05414825A231D500EFC5FF /* Main.storyboard */; };
0E05418B25A2334900EFC5FF /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 0E05414625A231D500EFC5FF /* LaunchScreen.storyboard */; };
0E0541A125A2343500EFC5FF /* NetworkExtension.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 0E0541A025A2343500EFC5FF /* NetworkExtension.framework */; };
0E0541A925A2343500EFC5FF /* TunnelKitDemoTunnel-iOS.appex in Embed App Extensions */ = {isa = PBXBuildFile; fileRef = 0E05419F25A2343500EFC5FF /* TunnelKitDemoTunnel-iOS.appex */; settings = {ATTRIBUTES = (RemoveHeadersOnCopy, ); }; };
0E0541D125A2354500EFC5FF /* PacketTunnelProvider.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0E05413825A231D500EFC5FF /* PacketTunnelProvider.swift */; };
0E0541A925A2343500EFC5FF /* TunnelKitDemoOpenVPNTunnel-iOS.appex in Embed App Extensions */ = {isa = PBXBuildFile; fileRef = 0E05419F25A2343500EFC5FF /* TunnelKitDemoOpenVPNTunnel-iOS.appex */; settings = {ATTRIBUTES = (RemoveHeadersOnCopy, ); }; };
0E0541D125A2354500EFC5FF /* OpenVPNPacketTunnelProvider.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0E05413825A231D500EFC5FF /* OpenVPNPacketTunnelProvider.swift */; };
0E0541D825A2355000EFC5FF /* Configuration.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0E05413425A231D500EFC5FF /* Configuration.swift */; };
0E05425825A2392E00EFC5FF /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0E05414125A231D500EFC5FF /* AppDelegate.swift */; };
0E05425925A2392E00EFC5FF /* ViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0E05413C25A231D500EFC5FF /* ViewController.swift */; };
0E05425925A2392E00EFC5FF /* OpenVPNViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0E05413C25A231D500EFC5FF /* OpenVPNViewController.swift */; };
0E05426125A2393300EFC5FF /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 0E05413D25A231D500EFC5FF /* Assets.xcassets */; };
0E05426925A2393B00EFC5FF /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 0E05413E25A231D500EFC5FF /* Main.storyboard */; };
0E05427825A239C600EFC5FF /* NetworkExtension.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 0E0541A025A2343500EFC5FF /* NetworkExtension.framework */; };
0E05428025A239C600EFC5FF /* TunnelKitDemoTunnel-macOS.appex in Embed App Extensions */ = {isa = PBXBuildFile; fileRef = 0E05427725A239C600EFC5FF /* TunnelKitDemoTunnel-macOS.appex */; settings = {ATTRIBUTES = (RemoveHeadersOnCopy, ); }; };
0E05428025A239C600EFC5FF /* TunnelKitDemoOpenVPNTunnel-macOS.appex in Embed App Extensions */ = {isa = PBXBuildFile; fileRef = 0E05427725A239C600EFC5FF /* TunnelKitDemoOpenVPNTunnel-macOS.appex */; settings = {ATTRIBUTES = (RemoveHeadersOnCopy, ); }; };
0E0542B925A23A8100EFC5FF /* Configuration.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0E05413425A231D500EFC5FF /* Configuration.swift */; };
0E0542C225A23A8400EFC5FF /* PacketTunnelProvider.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0E05413825A231D500EFC5FF /* PacketTunnelProvider.swift */; };
0E0542C225A23A8400EFC5FF /* OpenVPNPacketTunnelProvider.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0E05413825A231D500EFC5FF /* OpenVPNPacketTunnelProvider.swift */; };
0E1108AC1F77B9F900A92462 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0E1108AB1F77B9F900A92462 /* AppDelegate.swift */; };
0E1108AE1F77B9F900A92462 /* ViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0E1108AD1F77B9F900A92462 /* ViewController.swift */; };
0E1108B11F77B9F900A92462 /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 0E1108AF1F77B9F900A92462 /* Main.storyboard */; };
@ -31,6 +31,18 @@
0E1108B61F77B9F900A92462 /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 0E1108B41F77B9F900A92462 /* LaunchScreen.storyboard */; };
0E80FA5127396F5F000F5A45 /* TunnelKitOpenVPNAppExtension in Frameworks */ = {isa = PBXBuildFile; productRef = 0E80FA5027396F5F000F5A45 /* TunnelKitOpenVPNAppExtension */; };
0E80FA5327396F66000F5A45 /* TunnelKitOpenVPNAppExtension in Frameworks */ = {isa = PBXBuildFile; productRef = 0E80FA5227396F66000F5A45 /* TunnelKitOpenVPNAppExtension */; };
0E81EB4C274BACF200E5F2D3 /* WireGuardViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0E81EB4B274BACF200E5F2D3 /* WireGuardViewController.swift */; };
0E81EB4F274BAE0A00E5F2D3 /* WireGuardViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0E81EB4D274BAE0400E5F2D3 /* WireGuardViewController.swift */; };
0E81EB51274BB02100E5F2D3 /* TunnelKitWireGuard in Frameworks */ = {isa = PBXBuildFile; productRef = 0E81EB50274BB02100E5F2D3 /* TunnelKitWireGuard */; };
0E81EB53274BB02600E5F2D3 /* TunnelKitWireGuard in Frameworks */ = {isa = PBXBuildFile; productRef = 0E81EB52274BB02600E5F2D3 /* TunnelKitWireGuard */; };
0E833A85274BC39C008EA397 /* NetworkExtension.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 0E0541A025A2343500EFC5FF /* NetworkExtension.framework */; };
0E833A96274BC3B1008EA397 /* NetworkExtension.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 0E0541A025A2343500EFC5FF /* NetworkExtension.framework */; };
0E833AA3274BC480008EA397 /* TunnelKitWireGuardAppExtension in Frameworks */ = {isa = PBXBuildFile; productRef = 0E833AA2274BC480008EA397 /* TunnelKitWireGuardAppExtension */; };
0E833AA5274BC484008EA397 /* TunnelKitWireGuardAppExtension in Frameworks */ = {isa = PBXBuildFile; productRef = 0E833AA4274BC484008EA397 /* TunnelKitWireGuardAppExtension */; };
0E833AAA274BC5BA008EA397 /* TunnelKitDemoWireGuardTunnel-macOS.appex in Embed App Extensions */ = {isa = PBXBuildFile; fileRef = 0E833A95274BC3B1008EA397 /* TunnelKitDemoWireGuardTunnel-macOS.appex */; settings = {ATTRIBUTES = (RemoveHeadersOnCopy, ); }; };
0E833AAB274BC5C2008EA397 /* TunnelKitDemoWireGuardTunnel-iOS.appex in Embed App Extensions */ = {isa = PBXBuildFile; fileRef = 0E833A84274BC39C008EA397 /* TunnelKitDemoWireGuardTunnel-iOS.appex */; settings = {ATTRIBUTES = (RemoveHeadersOnCopy, ); }; };
0E833AAD274BC64F008EA397 /* WireGuardPacketTunnelProvider.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0E833AAC274BC64F008EA397 /* WireGuardPacketTunnelProvider.swift */; };
0E833AAE274BC64F008EA397 /* WireGuardPacketTunnelProvider.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0E833AAC274BC64F008EA397 /* WireGuardPacketTunnelProvider.swift */; };
0EFD5B312727250500C7D5FD /* TunnelKitOpenVPN in Frameworks */ = {isa = PBXBuildFile; productRef = 0EFD5B302727250500C7D5FD /* TunnelKitOpenVPN */; };
0EFD5B332727250B00C7D5FD /* TunnelKitOpenVPN in Frameworks */ = {isa = PBXBuildFile; productRef = 0EFD5B322727250B00C7D5FD /* TunnelKitOpenVPN */; };
/* End PBXBuildFile section */
@ -50,6 +62,34 @@
remoteGlobalIDString = 0E05427625A239C600EFC5FF;
remoteInfo = Tunnel;
};
0E833A8B274BC39C008EA397 /* PBXContainerItemProxy */ = {
isa = PBXContainerItemProxy;
containerPortal = 0E17D7F01F730D9F009EE129 /* Project object */;
proxyType = 1;
remoteGlobalIDString = 0E833A83274BC39C008EA397;
remoteInfo = "TunnelKitDemoWireGuardTunnel-iOS";
};
0E833A9C274BC3B1008EA397 /* PBXContainerItemProxy */ = {
isa = PBXContainerItemProxy;
containerPortal = 0E17D7F01F730D9F009EE129 /* Project object */;
proxyType = 1;
remoteGlobalIDString = 0E833A94274BC3B1008EA397;
remoteInfo = "TunnelKitDemoWireGuardTunnel-macOS";
};
0E833AA6274BC496008EA397 /* PBXContainerItemProxy */ = {
isa = PBXContainerItemProxy;
containerPortal = 0E17D7F01F730D9F009EE129 /* Project object */;
proxyType = 1;
remoteGlobalIDString = 0E81EB54274BB0D000E5F2D3;
remoteInfo = "TunnelKitDemoWireGuardKitGo-macOS";
};
0E833AA8274BC49B008EA397 /* PBXContainerItemProxy */ = {
isa = PBXContainerItemProxy;
containerPortal = 0E17D7F01F730D9F009EE129 /* Project object */;
proxyType = 1;
remoteGlobalIDString = 0EDD211D274BB4CF006833D1;
remoteInfo = "TunnelKitDemoWireGuardKitGo-iOS";
};
/* End PBXContainerItemProxy section */
/* Begin PBXCopyFilesBuildPhase section */
@ -59,7 +99,8 @@
dstPath = "";
dstSubfolderSpec = 13;
files = (
0E0541A925A2343500EFC5FF /* TunnelKitDemoTunnel-iOS.appex in Embed App Extensions */,
0E833AAB274BC5C2008EA397 /* TunnelKitDemoWireGuardTunnel-iOS.appex in Embed App Extensions */,
0E0541A925A2343500EFC5FF /* TunnelKitDemoOpenVPNTunnel-iOS.appex in Embed App Extensions */,
);
name = "Embed App Extensions";
runOnlyForDeploymentPostprocessing = 0;
@ -70,7 +111,8 @@
dstPath = "";
dstSubfolderSpec = 13;
files = (
0E05428025A239C600EFC5FF /* TunnelKitDemoTunnel-macOS.appex in Embed App Extensions */,
0E833AAA274BC5BA008EA397 /* TunnelKitDemoWireGuardTunnel-macOS.appex in Embed App Extensions */,
0E05428025A239C600EFC5FF /* TunnelKitDemoOpenVPNTunnel-macOS.appex in Embed App Extensions */,
);
name = "Embed App Extensions";
runOnlyForDeploymentPostprocessing = 0;
@ -111,15 +153,15 @@
0E05413025A231D500EFC5FF /* DemoTunnel.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = DemoTunnel.entitlements; sourceTree = "<group>"; };
0E05413225A231D500EFC5FF /* DemoTunnel.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = DemoTunnel.plist; sourceTree = "<group>"; };
0E05413425A231D500EFC5FF /* Configuration.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Configuration.swift; sourceTree = "<group>"; };
0E05413825A231D500EFC5FF /* PacketTunnelProvider.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PacketTunnelProvider.swift; sourceTree = "<group>"; };
0E05413825A231D500EFC5FF /* OpenVPNPacketTunnelProvider.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = OpenVPNPacketTunnelProvider.swift; sourceTree = "<group>"; };
0E05413925A231D500EFC5FF /* DemoTunnel.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = DemoTunnel.entitlements; sourceTree = "<group>"; };
0E05413C25A231D500EFC5FF /* ViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ViewController.swift; sourceTree = "<group>"; };
0E05413C25A231D500EFC5FF /* OpenVPNViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = OpenVPNViewController.swift; sourceTree = "<group>"; };
0E05413D25A231D500EFC5FF /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = "<group>"; };
0E05413F25A231D500EFC5FF /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = "<group>"; };
0E05414025A231D500EFC5FF /* Demo.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = Demo.entitlements; sourceTree = "<group>"; };
0E05414125A231D500EFC5FF /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = "<group>"; };
0E05414225A231D500EFC5FF /* Demo.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Demo.plist; sourceTree = "<group>"; };
0E05414425A231D500EFC5FF /* ViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ViewController.swift; sourceTree = "<group>"; };
0E05414425A231D500EFC5FF /* OpenVPNViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = OpenVPNViewController.swift; sourceTree = "<group>"; };
0E05414525A231D500EFC5FF /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = "<group>"; };
0E05414725A231D500EFC5FF /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = "<group>"; };
0E05414925A231D500EFC5FF /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = "<group>"; };
@ -127,10 +169,10 @@
0E05414B25A231D500EFC5FF /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = "<group>"; };
0E05414C25A231D500EFC5FF /* Demo.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Demo.plist; sourceTree = "<group>"; };
0E05416925A232FD00EFC5FF /* TunnelKitDemo-iOS.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = "TunnelKitDemo-iOS.app"; sourceTree = BUILT_PRODUCTS_DIR; };
0E05419F25A2343500EFC5FF /* TunnelKitDemoTunnel-iOS.appex */ = {isa = PBXFileReference; explicitFileType = "wrapper.app-extension"; includeInIndex = 0; path = "TunnelKitDemoTunnel-iOS.appex"; sourceTree = BUILT_PRODUCTS_DIR; };
0E05419F25A2343500EFC5FF /* TunnelKitDemoOpenVPNTunnel-iOS.appex */ = {isa = PBXFileReference; explicitFileType = "wrapper.app-extension"; includeInIndex = 0; path = "TunnelKitDemoOpenVPNTunnel-iOS.appex"; sourceTree = BUILT_PRODUCTS_DIR; };
0E0541A025A2343500EFC5FF /* NetworkExtension.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = NetworkExtension.framework; path = System/Library/Frameworks/NetworkExtension.framework; sourceTree = SDKROOT; };
0E05422C25A236EB00EFC5FF /* TunnelKitDemo-macOS.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = "TunnelKitDemo-macOS.app"; sourceTree = BUILT_PRODUCTS_DIR; };
0E05427725A239C600EFC5FF /* TunnelKitDemoTunnel-macOS.appex */ = {isa = PBXFileReference; explicitFileType = "wrapper.app-extension"; includeInIndex = 0; path = "TunnelKitDemoTunnel-macOS.appex"; sourceTree = BUILT_PRODUCTS_DIR; };
0E05427725A239C600EFC5FF /* TunnelKitDemoOpenVPNTunnel-macOS.appex */ = {isa = PBXFileReference; explicitFileType = "wrapper.app-extension"; includeInIndex = 0; path = "TunnelKitDemoOpenVPNTunnel-macOS.appex"; sourceTree = BUILT_PRODUCTS_DIR; };
0E1108A91F77B9F900A92462 /* TunnelKitHost.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = TunnelKitHost.app; sourceTree = BUILT_PRODUCTS_DIR; };
0E1108AB1F77B9F900A92462 /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = "<group>"; };
0E1108AD1F77B9F900A92462 /* ViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ViewController.swift; sourceTree = "<group>"; };
@ -141,6 +183,11 @@
0E26B05627272767008FB1E7 /* tunnelkit */ = {isa = PBXFileReference; lastKnownFileType = folder; name = tunnelkit; path = ..; sourceTree = "<group>"; };
0E411B9F2271FA3300E0852C /* libresolv.tbd */ = {isa = PBXFileReference; lastKnownFileType = "sourcecode.text-based-dylib-definition"; name = libresolv.tbd; path = Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.14.sdk/usr/lib/libresolv.tbd; sourceTree = DEVELOPER_DIR; };
0E411BA12271FA3C00E0852C /* libresolv.tbd */ = {isa = PBXFileReference; lastKnownFileType = "sourcecode.text-based-dylib-definition"; name = libresolv.tbd; path = usr/lib/libresolv.tbd; sourceTree = SDKROOT; };
0E81EB4B274BACF200E5F2D3 /* WireGuardViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = WireGuardViewController.swift; sourceTree = "<group>"; };
0E81EB4D274BAE0400E5F2D3 /* WireGuardViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = WireGuardViewController.swift; sourceTree = "<group>"; };
0E833A84274BC39C008EA397 /* TunnelKitDemoWireGuardTunnel-iOS.appex */ = {isa = PBXFileReference; explicitFileType = "wrapper.app-extension"; includeInIndex = 0; path = "TunnelKitDemoWireGuardTunnel-iOS.appex"; sourceTree = BUILT_PRODUCTS_DIR; };
0E833A95274BC3B1008EA397 /* TunnelKitDemoWireGuardTunnel-macOS.appex */ = {isa = PBXFileReference; explicitFileType = "wrapper.app-extension"; includeInIndex = 0; path = "TunnelKitDemoWireGuardTunnel-macOS.appex"; sourceTree = BUILT_PRODUCTS_DIR; };
0E833AAC274BC64F008EA397 /* WireGuardPacketTunnelProvider.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = WireGuardPacketTunnelProvider.swift; sourceTree = "<group>"; };
0E85A25B202CCA3D0059E9F9 /* Host.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = Host.entitlements; sourceTree = "<group>"; };
44612F27B9EF890AF8B926DB /* Pods_ios_TunnelKit_iOS.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_ios_TunnelKit_iOS.framework; sourceTree = BUILT_PRODUCTS_DIR; };
488FA71CA2DC38D2FDF7D1D8 /* Pods_ios_TunnelKitDemoTunnel_iOS.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_ios_TunnelKitDemoTunnel_iOS.framework; sourceTree = BUILT_PRODUCTS_DIR; };
@ -158,6 +205,7 @@
isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647;
files = (
0E81EB53274BB02600E5F2D3 /* TunnelKitWireGuard in Frameworks */,
0EFD5B332727250B00C7D5FD /* TunnelKitOpenVPN in Frameworks */,
);
runOnlyForDeploymentPostprocessing = 0;
@ -166,8 +214,8 @@
isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647;
files = (
0E0541A125A2343500EFC5FF /* NetworkExtension.framework in Frameworks */,
0E80FA5127396F5F000F5A45 /* TunnelKitOpenVPNAppExtension in Frameworks */,
0E0541A125A2343500EFC5FF /* NetworkExtension.framework in Frameworks */,
);
runOnlyForDeploymentPostprocessing = 0;
};
@ -175,6 +223,7 @@
isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647;
files = (
0E81EB51274BB02100E5F2D3 /* TunnelKitWireGuard in Frameworks */,
0EFD5B312727250500C7D5FD /* TunnelKitOpenVPN in Frameworks */,
);
runOnlyForDeploymentPostprocessing = 0;
@ -195,6 +244,24 @@
);
runOnlyForDeploymentPostprocessing = 0;
};
0E833A81274BC39C008EA397 /* Frameworks */ = {
isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647;
files = (
0E833AA3274BC480008EA397 /* TunnelKitWireGuardAppExtension in Frameworks */,
0E833A85274BC39C008EA397 /* NetworkExtension.framework in Frameworks */,
);
runOnlyForDeploymentPostprocessing = 0;
};
0E833A92274BC3B1008EA397 /* Frameworks */ = {
isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647;
files = (
0E833AA5274BC484008EA397 /* TunnelKitWireGuardAppExtension in Frameworks */,
0E833A96274BC3B1008EA397 /* NetworkExtension.framework in Frameworks */,
);
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXFrameworksBuildPhase section */
/* Begin PBXGroup section */
@ -205,7 +272,8 @@
0E05413B25A231D500EFC5FF /* macOS */,
0E05413225A231D500EFC5FF /* DemoTunnel.plist */,
0E05413425A231D500EFC5FF /* Configuration.swift */,
0E05413825A231D500EFC5FF /* PacketTunnelProvider.swift */,
0E05413825A231D500EFC5FF /* OpenVPNPacketTunnelProvider.swift */,
0E833AAC274BC64F008EA397 /* WireGuardPacketTunnelProvider.swift */,
);
path = Demo;
sourceTree = "<group>";
@ -217,7 +285,8 @@
0E05413025A231D500EFC5FF /* DemoTunnel.entitlements */,
0E05414225A231D500EFC5FF /* Demo.plist */,
0E05414125A231D500EFC5FF /* AppDelegate.swift */,
0E05413C25A231D500EFC5FF /* ViewController.swift */,
0E05413C25A231D500EFC5FF /* OpenVPNViewController.swift */,
0E81EB4D274BAE0400E5F2D3 /* WireGuardViewController.swift */,
0E05413D25A231D500EFC5FF /* Assets.xcassets */,
0E05413E25A231D500EFC5FF /* Main.storyboard */,
);
@ -231,7 +300,8 @@
0E05413925A231D500EFC5FF /* DemoTunnel.entitlements */,
0E05414C25A231D500EFC5FF /* Demo.plist */,
0E05414B25A231D500EFC5FF /* AppDelegate.swift */,
0E05414425A231D500EFC5FF /* ViewController.swift */,
0E05414425A231D500EFC5FF /* OpenVPNViewController.swift */,
0E81EB4B274BACF200E5F2D3 /* WireGuardViewController.swift */,
0E05414525A231D500EFC5FF /* Assets.xcassets */,
0E05414625A231D500EFC5FF /* LaunchScreen.storyboard */,
0E05414825A231D500EFC5FF /* Main.storyboard */,
@ -269,9 +339,11 @@
children = (
0E1108A91F77B9F900A92462 /* TunnelKitHost.app */,
0E05416925A232FD00EFC5FF /* TunnelKitDemo-iOS.app */,
0E05419F25A2343500EFC5FF /* TunnelKitDemoTunnel-iOS.appex */,
0E05419F25A2343500EFC5FF /* TunnelKitDemoOpenVPNTunnel-iOS.appex */,
0E05422C25A236EB00EFC5FF /* TunnelKitDemo-macOS.app */,
0E05427725A239C600EFC5FF /* TunnelKitDemoTunnel-macOS.appex */,
0E05427725A239C600EFC5FF /* TunnelKitDemoOpenVPNTunnel-macOS.appex */,
0E833A84274BC39C008EA397 /* TunnelKitDemoWireGuardTunnel-iOS.appex */,
0E833A95274BC3B1008EA397 /* TunnelKitDemoWireGuardTunnel-macOS.appex */,
);
name = Products;
sourceTree = "<group>";
@ -305,6 +377,37 @@
};
/* End PBXGroup section */
/* Begin PBXLegacyTarget section */
0E81EB54274BB0D000E5F2D3 /* TunnelKitDemoWireGuardKitGo-macOS */ = {
isa = PBXLegacyTarget;
buildArgumentsString = "$(ACTION)";
buildConfigurationList = 0E81EB55274BB0D000E5F2D3 /* Build configuration list for PBXLegacyTarget "TunnelKitDemoWireGuardKitGo-macOS" */;
buildPhases = (
);
buildToolPath = "$(PROJECT_DIR)/../Scripts/build_wireguard_go_bridge.sh";
buildWorkingDirectory = "";
dependencies = (
);
name = "TunnelKitDemoWireGuardKitGo-macOS";
passBuildSettingsInEnvironment = 1;
productName = "TunnelKitDemoWireGuardKitGo-macOS";
};
0EDD211D274BB4CF006833D1 /* TunnelKitDemoWireGuardKitGo-iOS */ = {
isa = PBXLegacyTarget;
buildArgumentsString = "$(ACTION)";
buildConfigurationList = 0EDD211E274BB4CF006833D1 /* Build configuration list for PBXLegacyTarget "TunnelKitDemoWireGuardKitGo-iOS" */;
buildPhases = (
);
buildToolPath = "$(PROJECT_DIR)/../Scripts/build_wireguard_go_bridge.sh";
buildWorkingDirectory = "";
dependencies = (
);
name = "TunnelKitDemoWireGuardKitGo-iOS";
passBuildSettingsInEnvironment = 1;
productName = "TunnelKitDemoWireGuardKitGo-iOS";
};
/* End PBXLegacyTarget section */
/* Begin PBXNativeTarget section */
0E05416825A232FD00EFC5FF /* TunnelKitDemo-iOS */ = {
isa = PBXNativeTarget;
@ -320,18 +423,20 @@
);
dependencies = (
0E0541A825A2343500EFC5FF /* PBXTargetDependency */,
0E833A8C274BC39C008EA397 /* PBXTargetDependency */,
);
name = "TunnelKitDemo-iOS";
packageProductDependencies = (
0EFD5B322727250B00C7D5FD /* TunnelKitOpenVPN */,
0E81EB52274BB02600E5F2D3 /* TunnelKitWireGuard */,
);
productName = Demo;
productReference = 0E05416925A232FD00EFC5FF /* TunnelKitDemo-iOS.app */;
productType = "com.apple.product-type.application";
};
0E05419E25A2343500EFC5FF /* TunnelKitDemoTunnel-iOS */ = {
0E05419E25A2343500EFC5FF /* TunnelKitDemoOpenVPNTunnel-iOS */ = {
isa = PBXNativeTarget;
buildConfigurationList = 0E0541AA25A2343500EFC5FF /* Build configuration list for PBXNativeTarget "TunnelKitDemoTunnel-iOS" */;
buildConfigurationList = 0E0541AA25A2343500EFC5FF /* Build configuration list for PBXNativeTarget "TunnelKitDemoOpenVPNTunnel-iOS" */;
buildPhases = (
0E05419B25A2343500EFC5FF /* Sources */,
0E05419C25A2343500EFC5FF /* Frameworks */,
@ -341,12 +446,12 @@
);
dependencies = (
);
name = "TunnelKitDemoTunnel-iOS";
name = "TunnelKitDemoOpenVPNTunnel-iOS";
packageProductDependencies = (
0E80FA5027396F5F000F5A45 /* TunnelKitOpenVPNAppExtension */,
);
productName = Tunnel;
productReference = 0E05419F25A2343500EFC5FF /* TunnelKitDemoTunnel-iOS.appex */;
productReference = 0E05419F25A2343500EFC5FF /* TunnelKitDemoOpenVPNTunnel-iOS.appex */;
productType = "com.apple.product-type.app-extension";
};
0E05422B25A236EB00EFC5FF /* TunnelKitDemo-macOS */ = {
@ -363,18 +468,20 @@
);
dependencies = (
0E05427F25A239C600EFC5FF /* PBXTargetDependency */,
0E833A9D274BC3B1008EA397 /* PBXTargetDependency */,
);
name = "TunnelKitDemo-macOS";
packageProductDependencies = (
0EFD5B302727250500C7D5FD /* TunnelKitOpenVPN */,
0E81EB50274BB02100E5F2D3 /* TunnelKitWireGuard */,
);
productName = Demo;
productReference = 0E05422C25A236EB00EFC5FF /* TunnelKitDemo-macOS.app */;
productType = "com.apple.product-type.application";
};
0E05427625A239C600EFC5FF /* TunnelKitDemoTunnel-macOS */ = {
0E05427625A239C600EFC5FF /* TunnelKitDemoOpenVPNTunnel-macOS */ = {
isa = PBXNativeTarget;
buildConfigurationList = 0E05428125A239C600EFC5FF /* Build configuration list for PBXNativeTarget "TunnelKitDemoTunnel-macOS" */;
buildConfigurationList = 0E05428125A239C600EFC5FF /* Build configuration list for PBXNativeTarget "TunnelKitDemoOpenVPNTunnel-macOS" */;
buildPhases = (
0E05427325A239C600EFC5FF /* Sources */,
0E05427425A239C600EFC5FF /* Frameworks */,
@ -384,12 +491,12 @@
);
dependencies = (
);
name = "TunnelKitDemoTunnel-macOS";
name = "TunnelKitDemoOpenVPNTunnel-macOS";
packageProductDependencies = (
0E80FA5227396F66000F5A45 /* TunnelKitOpenVPNAppExtension */,
);
productName = Tunnel;
productReference = 0E05427725A239C600EFC5FF /* TunnelKitDemoTunnel-macOS.appex */;
productReference = 0E05427725A239C600EFC5FF /* TunnelKitDemoOpenVPNTunnel-macOS.appex */;
productType = "com.apple.product-type.app-extension";
};
0E1108A81F77B9F900A92462 /* TunnelKitHost */ = {
@ -410,13 +517,55 @@
productReference = 0E1108A91F77B9F900A92462 /* TunnelKitHost.app */;
productType = "com.apple.product-type.application";
};
0E833A83274BC39C008EA397 /* TunnelKitDemoWireGuardTunnel-iOS */ = {
isa = PBXNativeTarget;
buildConfigurationList = 0E833A8E274BC39C008EA397 /* Build configuration list for PBXNativeTarget "TunnelKitDemoWireGuardTunnel-iOS" */;
buildPhases = (
0E833A80274BC39C008EA397 /* Sources */,
0E833A81274BC39C008EA397 /* Frameworks */,
0E833A82274BC39C008EA397 /* Resources */,
);
buildRules = (
);
dependencies = (
0E833AA9274BC49B008EA397 /* PBXTargetDependency */,
);
name = "TunnelKitDemoWireGuardTunnel-iOS";
packageProductDependencies = (
0E833AA2274BC480008EA397 /* TunnelKitWireGuardAppExtension */,
);
productName = "TunnelKitDemoWireGuardTunnel-iOS";
productReference = 0E833A84274BC39C008EA397 /* TunnelKitDemoWireGuardTunnel-iOS.appex */;
productType = "com.apple.product-type.app-extension";
};
0E833A94274BC3B1008EA397 /* TunnelKitDemoWireGuardTunnel-macOS */ = {
isa = PBXNativeTarget;
buildConfigurationList = 0E833A9F274BC3B2008EA397 /* Build configuration list for PBXNativeTarget "TunnelKitDemoWireGuardTunnel-macOS" */;
buildPhases = (
0E833A91274BC3B1008EA397 /* Sources */,
0E833A92274BC3B1008EA397 /* Frameworks */,
0E833A93274BC3B1008EA397 /* Resources */,
);
buildRules = (
);
dependencies = (
0E833AA7274BC496008EA397 /* PBXTargetDependency */,
);
name = "TunnelKitDemoWireGuardTunnel-macOS";
packageProductDependencies = (
0E833AA4274BC484008EA397 /* TunnelKitWireGuardAppExtension */,
);
productName = "TunnelKitDemoWireGuardTunnel-macOS";
productReference = 0E833A95274BC3B1008EA397 /* TunnelKitDemoWireGuardTunnel-macOS.appex */;
productType = "com.apple.product-type.app-extension";
};
/* End PBXNativeTarget section */
/* Begin PBXProject section */
0E17D7F01F730D9F009EE129 /* Project object */ = {
isa = PBXProject;
attributes = {
LastSwiftUpdateCheck = 1230;
LastSwiftUpdateCheck = 1310;
LastUpgradeCheck = 1230;
ORGANIZATIONNAME = "Davide De Rosa";
TargetAttributes = {
@ -449,6 +598,20 @@
};
};
};
0E81EB54274BB0D000E5F2D3 = {
CreatedOnToolsVersion = 13.1;
};
0E833A83274BC39C008EA397 = {
CreatedOnToolsVersion = 13.1;
LastSwiftMigration = 1310;
};
0E833A94274BC3B1008EA397 = {
CreatedOnToolsVersion = 13.1;
LastSwiftMigration = 1310;
};
0EDD211D274BB4CF006833D1 = {
CreatedOnToolsVersion = 13.1;
};
};
};
buildConfigurationList = 0E17D7F31F730D9F009EE129 /* Build configuration list for PBXProject "TunnelKit" */;
@ -467,8 +630,12 @@
0E1108A81F77B9F900A92462 /* TunnelKitHost */,
0E05416825A232FD00EFC5FF /* TunnelKitDemo-iOS */,
0E05422B25A236EB00EFC5FF /* TunnelKitDemo-macOS */,
0E05419E25A2343500EFC5FF /* TunnelKitDemoTunnel-iOS */,
0E05427625A239C600EFC5FF /* TunnelKitDemoTunnel-macOS */,
0E05419E25A2343500EFC5FF /* TunnelKitDemoOpenVPNTunnel-iOS */,
0E05427625A239C600EFC5FF /* TunnelKitDemoOpenVPNTunnel-macOS */,
0E833A83274BC39C008EA397 /* TunnelKitDemoWireGuardTunnel-iOS */,
0E833A94274BC3B1008EA397 /* TunnelKitDemoWireGuardTunnel-macOS */,
0EDD211D274BB4CF006833D1 /* TunnelKitDemoWireGuardKitGo-iOS */,
0E81EB54274BB0D000E5F2D3 /* TunnelKitDemoWireGuardKitGo-macOS */,
);
};
/* End PBXProject section */
@ -517,6 +684,20 @@
);
runOnlyForDeploymentPostprocessing = 0;
};
0E833A82274BC39C008EA397 /* Resources */ = {
isa = PBXResourcesBuildPhase;
buildActionMask = 2147483647;
files = (
);
runOnlyForDeploymentPostprocessing = 0;
};
0E833A93274BC3B1008EA397 /* Resources */ = {
isa = PBXResourcesBuildPhase;
buildActionMask = 2147483647;
files = (
);
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXResourcesBuildPhase section */
/* Begin PBXSourcesBuildPhase section */
@ -525,7 +706,8 @@
buildActionMask = 2147483647;
files = (
0E0541D825A2355000EFC5FF /* Configuration.swift in Sources */,
0E05418825A2334500EFC5FF /* ViewController.swift in Sources */,
0E81EB4C274BACF200E5F2D3 /* WireGuardViewController.swift in Sources */,
0E05418825A2334500EFC5FF /* OpenVPNViewController.swift in Sources */,
0E05418725A2334500EFC5FF /* AppDelegate.swift in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
@ -534,7 +716,7 @@
isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647;
files = (
0E0541D125A2354500EFC5FF /* PacketTunnelProvider.swift in Sources */,
0E0541D125A2354500EFC5FF /* OpenVPNPacketTunnelProvider.swift in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
@ -543,8 +725,9 @@
buildActionMask = 2147483647;
files = (
0E0542B925A23A8100EFC5FF /* Configuration.swift in Sources */,
0E81EB4F274BAE0A00E5F2D3 /* WireGuardViewController.swift in Sources */,
0E05425825A2392E00EFC5FF /* AppDelegate.swift in Sources */,
0E05425925A2392E00EFC5FF /* ViewController.swift in Sources */,
0E05425925A2392E00EFC5FF /* OpenVPNViewController.swift in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
@ -552,7 +735,7 @@
isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647;
files = (
0E0542C225A23A8400EFC5FF /* PacketTunnelProvider.swift in Sources */,
0E0542C225A23A8400EFC5FF /* OpenVPNPacketTunnelProvider.swift in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
@ -565,19 +748,55 @@
);
runOnlyForDeploymentPostprocessing = 0;
};
0E833A80274BC39C008EA397 /* Sources */ = {
isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647;
files = (
0E833AAD274BC64F008EA397 /* WireGuardPacketTunnelProvider.swift in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
0E833A91274BC3B1008EA397 /* Sources */ = {
isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647;
files = (
0E833AAE274BC64F008EA397 /* WireGuardPacketTunnelProvider.swift in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXSourcesBuildPhase section */
/* Begin PBXTargetDependency section */
0E0541A825A2343500EFC5FF /* PBXTargetDependency */ = {
isa = PBXTargetDependency;
target = 0E05419E25A2343500EFC5FF /* TunnelKitDemoTunnel-iOS */;
target = 0E05419E25A2343500EFC5FF /* TunnelKitDemoOpenVPNTunnel-iOS */;
targetProxy = 0E0541A725A2343500EFC5FF /* PBXContainerItemProxy */;
};
0E05427F25A239C600EFC5FF /* PBXTargetDependency */ = {
isa = PBXTargetDependency;
target = 0E05427625A239C600EFC5FF /* TunnelKitDemoTunnel-macOS */;
target = 0E05427625A239C600EFC5FF /* TunnelKitDemoOpenVPNTunnel-macOS */;
targetProxy = 0E05427E25A239C600EFC5FF /* PBXContainerItemProxy */;
};
0E833A8C274BC39C008EA397 /* PBXTargetDependency */ = {
isa = PBXTargetDependency;
target = 0E833A83274BC39C008EA397 /* TunnelKitDemoWireGuardTunnel-iOS */;
targetProxy = 0E833A8B274BC39C008EA397 /* PBXContainerItemProxy */;
};
0E833A9D274BC3B1008EA397 /* PBXTargetDependency */ = {
isa = PBXTargetDependency;
target = 0E833A94274BC3B1008EA397 /* TunnelKitDemoWireGuardTunnel-macOS */;
targetProxy = 0E833A9C274BC3B1008EA397 /* PBXContainerItemProxy */;
};
0E833AA7274BC496008EA397 /* PBXTargetDependency */ = {
isa = PBXTargetDependency;
target = 0E81EB54274BB0D000E5F2D3 /* TunnelKitDemoWireGuardKitGo-macOS */;
targetProxy = 0E833AA6274BC496008EA397 /* PBXContainerItemProxy */;
};
0E833AA9274BC49B008EA397 /* PBXTargetDependency */ = {
isa = PBXTargetDependency;
target = 0EDD211D274BB4CF006833D1 /* TunnelKitDemoWireGuardKitGo-iOS */;
targetProxy = 0E833AA8274BC49B008EA397 /* PBXContainerItemProxy */;
};
/* End PBXTargetDependency section */
/* Begin PBXVariantGroup section */
@ -627,6 +846,7 @@
0E05417B25A2330100EFC5FF /* Debug */ = {
isa = XCBuildConfiguration;
buildSettings = {
ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES;
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
CLANG_ENABLE_OBJC_WEAK = YES;
CODE_SIGN_ENTITLEMENTS = Demo/iOS/Demo.entitlements;
@ -641,7 +861,6 @@
MTL_FAST_MATH = YES;
PRODUCT_BUNDLE_IDENTIFIER = com.algoritmico.ios.TunnelKit.Demo;
PRODUCT_NAME = "$(TARGET_NAME)";
SWIFT_VERSION = 5.0;
TARGETED_DEVICE_FAMILY = "1,2";
};
name = Debug;
@ -649,6 +868,7 @@
0E05417C25A2330100EFC5FF /* Release */ = {
isa = XCBuildConfiguration;
buildSettings = {
ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES;
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
CLANG_ENABLE_OBJC_WEAK = YES;
CODE_SIGN_ENTITLEMENTS = Demo/iOS/Demo.entitlements;
@ -662,7 +882,6 @@
MTL_FAST_MATH = YES;
PRODUCT_BUNDLE_IDENTIFIER = com.algoritmico.ios.TunnelKit.Demo;
PRODUCT_NAME = "$(TARGET_NAME)";
SWIFT_VERSION = 5.0;
TARGETED_DEVICE_FAMILY = "1,2";
};
name = Release;
@ -674,7 +893,7 @@
CODE_SIGN_ENTITLEMENTS = Demo/iOS/DemoTunnel.entitlements;
CODE_SIGN_STYLE = Automatic;
DEVELOPMENT_TEAM = DTDYD63ZX9;
INFOPLIST_FILE = "$(SRCROOT)/Demo/DemoTunnel.plist";
INFOPLIST_FILE = Demo/DemoTunnel.plist;
LD_RUNPATH_SEARCH_PATHS = (
"$(inherited)",
"@executable_path/Frameworks",
@ -682,10 +901,9 @@
);
MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE;
MTL_FAST_MATH = YES;
PRODUCT_BUNDLE_IDENTIFIER = com.algoritmico.ios.TunnelKit.Demo.Tunnel;
PRODUCT_BUNDLE_IDENTIFIER = com.algoritmico.ios.TunnelKit.Demo.OpenVPN.Tunnel;
PRODUCT_NAME = "$(TARGET_NAME)";
SKIP_INSTALL = YES;
SWIFT_VERSION = 5.0;
TARGETED_DEVICE_FAMILY = "1,2";
};
name = Debug;
@ -697,17 +915,16 @@
CODE_SIGN_ENTITLEMENTS = Demo/iOS/DemoTunnel.entitlements;
CODE_SIGN_STYLE = Automatic;
DEVELOPMENT_TEAM = DTDYD63ZX9;
INFOPLIST_FILE = "$(SRCROOT)/Demo/DemoTunnel.plist";
INFOPLIST_FILE = Demo/DemoTunnel.plist;
LD_RUNPATH_SEARCH_PATHS = (
"$(inherited)",
"@executable_path/Frameworks",
"@executable_path/../../Frameworks",
);
MTL_FAST_MATH = YES;
PRODUCT_BUNDLE_IDENTIFIER = com.algoritmico.ios.TunnelKit.Demo.Tunnel;
PRODUCT_BUNDLE_IDENTIFIER = com.algoritmico.ios.TunnelKit.Demo.OpenVPN.Tunnel;
PRODUCT_NAME = "$(TARGET_NAME)";
SKIP_INSTALL = YES;
SWIFT_VERSION = 5.0;
TARGETED_DEVICE_FAMILY = "1,2";
};
name = Release;
@ -715,6 +932,7 @@
0E05423925A236EE00EFC5FF /* Debug */ = {
isa = XCBuildConfiguration;
buildSettings = {
ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES;
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
CLANG_ENABLE_OBJC_WEAK = YES;
CODE_SIGN_ENTITLEMENTS = Demo/macOS/Demo.entitlements;
@ -733,13 +951,13 @@
PRODUCT_BUNDLE_IDENTIFIER = com.algoritmico.macos.TunnelKit.Demo;
PRODUCT_NAME = "$(TARGET_NAME)";
SDKROOT = macosx;
SWIFT_VERSION = 5.0;
};
name = Debug;
};
0E05423A25A236EE00EFC5FF /* Release */ = {
isa = XCBuildConfiguration;
buildSettings = {
ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES;
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
CLANG_ENABLE_OBJC_WEAK = YES;
CODE_SIGN_ENTITLEMENTS = Demo/macOS/Demo.entitlements;
@ -757,7 +975,6 @@
PRODUCT_BUNDLE_IDENTIFIER = com.algoritmico.macos.TunnelKit.Demo;
PRODUCT_NAME = "$(TARGET_NAME)";
SDKROOT = macosx;
SWIFT_VERSION = 5.0;
};
name = Release;
};
@ -770,7 +987,7 @@
CODE_SIGN_STYLE = Automatic;
DEVELOPMENT_TEAM = DTDYD63ZX9;
ENABLE_HARDENED_RUNTIME = YES;
INFOPLIST_FILE = "$(SRCROOT)/Demo/DemoTunnel.plist";
INFOPLIST_FILE = Demo/DemoTunnel.plist;
LD_RUNPATH_SEARCH_PATHS = (
"$(inherited)",
"@executable_path/../Frameworks",
@ -778,11 +995,10 @@
);
MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE;
MTL_FAST_MATH = YES;
PRODUCT_BUNDLE_IDENTIFIER = com.algoritmico.macos.TunnelKit.Demo.Tunnel;
PRODUCT_BUNDLE_IDENTIFIER = com.algoritmico.macos.TunnelKit.Demo.OpenVPN.Tunnel;
PRODUCT_NAME = "$(TARGET_NAME)";
SDKROOT = macosx;
SKIP_INSTALL = YES;
SWIFT_VERSION = 5.0;
};
name = Debug;
};
@ -795,18 +1011,17 @@
CODE_SIGN_STYLE = Automatic;
DEVELOPMENT_TEAM = DTDYD63ZX9;
ENABLE_HARDENED_RUNTIME = YES;
INFOPLIST_FILE = "$(SRCROOT)/Demo/DemoTunnel.plist";
INFOPLIST_FILE = Demo/DemoTunnel.plist;
LD_RUNPATH_SEARCH_PATHS = (
"$(inherited)",
"@executable_path/../Frameworks",
"@executable_path/../../../../Frameworks",
);
MTL_FAST_MATH = YES;
PRODUCT_BUNDLE_IDENTIFIER = com.algoritmico.macos.TunnelKit.Demo.Tunnel;
PRODUCT_BUNDLE_IDENTIFIER = com.algoritmico.macos.TunnelKit.Demo.OpenVPN.Tunnel;
PRODUCT_NAME = "$(TARGET_NAME)";
SDKROOT = macosx;
SKIP_INSTALL = YES;
SWIFT_VERSION = 5.0;
};
name = Release;
};
@ -905,10 +1120,11 @@
MACOSX_DEPLOYMENT_TARGET = 10.15;
MTL_ENABLE_DEBUG_INFO = YES;
ONLY_ACTIVE_ARCH = YES;
PATH = "${PATH}:/opt/homebrew/bin";
SDKROOT = iphoneos;
SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG;
SWIFT_OPTIMIZATION_LEVEL = "-Onone";
SWIFT_VERSION = 4.2;
SWIFT_VERSION = 5.0;
VERSIONING_SYSTEM = "apple-generic";
VERSION_INFO_PREFIX = "";
};
@ -964,16 +1180,173 @@
IPHONEOS_DEPLOYMENT_TARGET = 12.0;
MACOSX_DEPLOYMENT_TARGET = 10.15;
MTL_ENABLE_DEBUG_INFO = NO;
PATH = "${PATH}:/opt/homebrew/bin";
SDKROOT = iphoneos;
SWIFT_COMPILATION_MODE = wholemodule;
SWIFT_OPTIMIZATION_LEVEL = "-O";
SWIFT_VERSION = 4.2;
SWIFT_VERSION = 5.0;
VALIDATE_PRODUCT = YES;
VERSIONING_SYSTEM = "apple-generic";
VERSION_INFO_PREFIX = "";
};
name = Release;
};
0E81EB56274BB0D000E5F2D3 /* Debug */ = {
isa = XCBuildConfiguration;
buildSettings = {
CODE_SIGN_STYLE = Automatic;
PRODUCT_NAME = "$(TARGET_NAME)";
SDKROOT = macosx;
};
name = Debug;
};
0E81EB57274BB0D000E5F2D3 /* Release */ = {
isa = XCBuildConfiguration;
buildSettings = {
CODE_SIGN_STYLE = Automatic;
PRODUCT_NAME = "$(TARGET_NAME)";
SDKROOT = macosx;
};
name = Release;
};
0E833A8F274BC39C008EA397 /* Debug */ = {
isa = XCBuildConfiguration;
buildSettings = {
CLANG_CXX_LANGUAGE_STANDARD = "gnu++17";
CLANG_ENABLE_MODULES = YES;
CLANG_ENABLE_OBJC_WEAK = YES;
CODE_SIGN_ENTITLEMENTS = Demo/iOS/DemoTunnel.entitlements;
CODE_SIGN_STYLE = Automatic;
CURRENT_PROJECT_VERSION = 1;
DEVELOPMENT_TEAM = DTDYD63ZX9;
INFOPLIST_FILE = Demo/DemoTunnel.plist;
LD_RUNPATH_SEARCH_PATHS = (
"$(inherited)",
"@executable_path/Frameworks",
"@executable_path/../../Frameworks",
);
MARKETING_VERSION = 1.0;
MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE;
MTL_FAST_MATH = YES;
PRODUCT_BUNDLE_IDENTIFIER = com.algoritmico.ios.TunnelKit.Demo.WireGuard.Tunnel;
PRODUCT_NAME = "$(TARGET_NAME)";
SKIP_INSTALL = YES;
SWIFT_EMIT_LOC_STRINGS = YES;
SWIFT_OPTIMIZATION_LEVEL = "-Onone";
SWIFT_VERSION = 5.0;
TARGETED_DEVICE_FAMILY = "1,2";
};
name = Debug;
};
0E833A90274BC39C008EA397 /* Release */ = {
isa = XCBuildConfiguration;
buildSettings = {
CLANG_CXX_LANGUAGE_STANDARD = "gnu++17";
CLANG_ENABLE_MODULES = YES;
CLANG_ENABLE_OBJC_WEAK = YES;
CODE_SIGN_ENTITLEMENTS = Demo/iOS/DemoTunnel.entitlements;
CODE_SIGN_STYLE = Automatic;
CURRENT_PROJECT_VERSION = 1;
DEVELOPMENT_TEAM = DTDYD63ZX9;
INFOPLIST_FILE = Demo/DemoTunnel.plist;
LD_RUNPATH_SEARCH_PATHS = (
"$(inherited)",
"@executable_path/Frameworks",
"@executable_path/../../Frameworks",
);
MARKETING_VERSION = 1.0;
MTL_FAST_MATH = YES;
PRODUCT_BUNDLE_IDENTIFIER = com.algoritmico.ios.TunnelKit.Demo.WireGuard.Tunnel;
PRODUCT_NAME = "$(TARGET_NAME)";
SKIP_INSTALL = YES;
SWIFT_EMIT_LOC_STRINGS = YES;
SWIFT_VERSION = 5.0;
TARGETED_DEVICE_FAMILY = "1,2";
};
name = Release;
};
0E833AA0274BC3B2008EA397 /* Debug */ = {
isa = XCBuildConfiguration;
buildSettings = {
CLANG_CXX_LANGUAGE_STANDARD = "gnu++17";
CLANG_ENABLE_MODULES = YES;
CLANG_ENABLE_OBJC_WEAK = YES;
CODE_SIGN_ENTITLEMENTS = Demo/macOS/DemoTunnel.entitlements;
CODE_SIGN_IDENTITY = "Apple Development";
CODE_SIGN_STYLE = Automatic;
CURRENT_PROJECT_VERSION = 1;
DEVELOPMENT_TEAM = DTDYD63ZX9;
ENABLE_HARDENED_RUNTIME = YES;
INFOPLIST_FILE = Demo/DemoTunnel.plist;
INFOPLIST_KEY_CFBundleDisplayName = "TunnelKitDemoWireGuardTunnel-macOS";
INFOPLIST_KEY_NSHumanReadableCopyright = "Copyright © 2021 Davide De Rosa. All rights reserved.";
LD_RUNPATH_SEARCH_PATHS = (
"$(inherited)",
"@executable_path/../Frameworks",
"@executable_path/../../../../Frameworks",
);
MACOSX_DEPLOYMENT_TARGET = 12.0;
MARKETING_VERSION = 1.0;
MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE;
MTL_FAST_MATH = YES;
PRODUCT_BUNDLE_IDENTIFIER = com.algoritmico.macos.TunnelKit.Demo.WireGuard.Tunnel;
PRODUCT_NAME = "$(TARGET_NAME)";
SDKROOT = macosx;
SKIP_INSTALL = YES;
SWIFT_EMIT_LOC_STRINGS = YES;
SWIFT_OPTIMIZATION_LEVEL = "-Onone";
SWIFT_VERSION = 5.0;
};
name = Debug;
};
0E833AA1274BC3B2008EA397 /* Release */ = {
isa = XCBuildConfiguration;
buildSettings = {
CLANG_CXX_LANGUAGE_STANDARD = "gnu++17";
CLANG_ENABLE_MODULES = YES;
CLANG_ENABLE_OBJC_WEAK = YES;
CODE_SIGN_ENTITLEMENTS = Demo/macOS/DemoTunnel.entitlements;
CODE_SIGN_IDENTITY = "Apple Development";
CODE_SIGN_STYLE = Automatic;
CURRENT_PROJECT_VERSION = 1;
DEVELOPMENT_TEAM = DTDYD63ZX9;
ENABLE_HARDENED_RUNTIME = YES;
INFOPLIST_FILE = Demo/DemoTunnel.plist;
INFOPLIST_KEY_CFBundleDisplayName = "TunnelKitDemoWireGuardTunnel-macOS";
INFOPLIST_KEY_NSHumanReadableCopyright = "Copyright © 2021 Davide De Rosa. All rights reserved.";
LD_RUNPATH_SEARCH_PATHS = (
"$(inherited)",
"@executable_path/../Frameworks",
"@executable_path/../../../../Frameworks",
);
MACOSX_DEPLOYMENT_TARGET = 12.0;
MARKETING_VERSION = 1.0;
MTL_FAST_MATH = YES;
PRODUCT_BUNDLE_IDENTIFIER = com.algoritmico.macos.TunnelKit.Demo.WireGuard.Tunnel;
PRODUCT_NAME = "$(TARGET_NAME)";
SDKROOT = macosx;
SKIP_INSTALL = YES;
SWIFT_EMIT_LOC_STRINGS = YES;
SWIFT_VERSION = 5.0;
};
name = Release;
};
0EDD211F274BB4CF006833D1 /* Debug */ = {
isa = XCBuildConfiguration;
buildSettings = {
CODE_SIGN_STYLE = Automatic;
PRODUCT_NAME = "$(TARGET_NAME)";
};
name = Debug;
};
0EDD2120274BB4CF006833D1 /* Release */ = {
isa = XCBuildConfiguration;
buildSettings = {
CODE_SIGN_STYLE = Automatic;
PRODUCT_NAME = "$(TARGET_NAME)";
};
name = Release;
};
/* End XCBuildConfiguration section */
/* Begin XCConfigurationList section */
@ -986,7 +1359,7 @@
defaultConfigurationIsVisible = 0;
defaultConfigurationName = Release;
};
0E0541AA25A2343500EFC5FF /* Build configuration list for PBXNativeTarget "TunnelKitDemoTunnel-iOS" */ = {
0E0541AA25A2343500EFC5FF /* Build configuration list for PBXNativeTarget "TunnelKitDemoOpenVPNTunnel-iOS" */ = {
isa = XCConfigurationList;
buildConfigurations = (
0E0541AB25A2343500EFC5FF /* Debug */,
@ -1004,7 +1377,7 @@
defaultConfigurationIsVisible = 0;
defaultConfigurationName = Release;
};
0E05428125A239C600EFC5FF /* Build configuration list for PBXNativeTarget "TunnelKitDemoTunnel-macOS" */ = {
0E05428125A239C600EFC5FF /* Build configuration list for PBXNativeTarget "TunnelKitDemoOpenVPNTunnel-macOS" */ = {
isa = XCConfigurationList;
buildConfigurations = (
0E05428225A239C600EFC5FF /* Debug */,
@ -1031,6 +1404,42 @@
defaultConfigurationIsVisible = 0;
defaultConfigurationName = Release;
};
0E81EB55274BB0D000E5F2D3 /* Build configuration list for PBXLegacyTarget "TunnelKitDemoWireGuardKitGo-macOS" */ = {
isa = XCConfigurationList;
buildConfigurations = (
0E81EB56274BB0D000E5F2D3 /* Debug */,
0E81EB57274BB0D000E5F2D3 /* Release */,
);
defaultConfigurationIsVisible = 0;
defaultConfigurationName = Release;
};
0E833A8E274BC39C008EA397 /* Build configuration list for PBXNativeTarget "TunnelKitDemoWireGuardTunnel-iOS" */ = {
isa = XCConfigurationList;
buildConfigurations = (
0E833A8F274BC39C008EA397 /* Debug */,
0E833A90274BC39C008EA397 /* Release */,
);
defaultConfigurationIsVisible = 0;
defaultConfigurationName = Release;
};
0E833A9F274BC3B2008EA397 /* Build configuration list for PBXNativeTarget "TunnelKitDemoWireGuardTunnel-macOS" */ = {
isa = XCConfigurationList;
buildConfigurations = (
0E833AA0274BC3B2008EA397 /* Debug */,
0E833AA1274BC3B2008EA397 /* Release */,
);
defaultConfigurationIsVisible = 0;
defaultConfigurationName = Release;
};
0EDD211E274BB4CF006833D1 /* Build configuration list for PBXLegacyTarget "TunnelKitDemoWireGuardKitGo-iOS" */ = {
isa = XCConfigurationList;
buildConfigurations = (
0EDD211F274BB4CF006833D1 /* Debug */,
0EDD2120274BB4CF006833D1 /* Release */,
);
defaultConfigurationIsVisible = 0;
defaultConfigurationName = Release;
};
/* End XCConfigurationList section */
/* Begin XCSwiftPackageProductDependency section */
@ -1042,6 +1451,22 @@
isa = XCSwiftPackageProductDependency;
productName = TunnelKitOpenVPNAppExtension;
};
0E81EB50274BB02100E5F2D3 /* TunnelKitWireGuard */ = {
isa = XCSwiftPackageProductDependency;
productName = TunnelKitWireGuard;
};
0E81EB52274BB02600E5F2D3 /* TunnelKitWireGuard */ = {
isa = XCSwiftPackageProductDependency;
productName = TunnelKitWireGuard;
};
0E833AA2274BC480008EA397 /* TunnelKitWireGuardAppExtension */ = {
isa = XCSwiftPackageProductDependency;
productName = TunnelKitWireGuardAppExtension;
};
0E833AA4274BC484008EA397 /* TunnelKitWireGuardAppExtension */ = {
isa = XCSwiftPackageProductDependency;
productName = TunnelKitWireGuardAppExtension;
};
0EFD5B302727250500C7D5FD /* TunnelKitOpenVPN */ = {
isa = XCSwiftPackageProductDependency;
productName = TunnelKitOpenVPN;

View File

@ -16,8 +16,8 @@
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "0E05419E25A2343500EFC5FF"
BuildableName = "TunnelKitDemoTunnel-iOS.appex"
BlueprintName = "TunnelKitDemoTunnel-iOS"
BuildableName = "TunnelKitDemoOpenVPNTunnel-iOS.appex"
BlueprintName = "TunnelKitDemoOpenVPNTunnel-iOS"
ReferencedContainer = "container:TunnelKit.xcodeproj">
</BuildableReference>
</BuildActionEntry>
@ -57,16 +57,6 @@
debugServiceExtension = "internal"
allowLocationSimulation = "YES"
launchAutomaticallySubstyle = "2">
<BuildableProductRunnable
runnableDebuggingMode = "0">
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "0E05416825A232FD00EFC5FF"
BuildableName = "TunnelKitDemo-iOS.app"
BlueprintName = "TunnelKitDemo-iOS"
ReferencedContainer = "container:TunnelKit.xcodeproj">
</BuildableReference>
</BuildableProductRunnable>
</LaunchAction>
<ProfileAction
buildConfiguration = "Release"
@ -76,16 +66,15 @@
debugDocumentVersioning = "YES"
askForAppToLaunch = "Yes"
launchAutomaticallySubstyle = "2">
<BuildableProductRunnable
runnableDebuggingMode = "0">
<MacroExpansion>
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "0E05416825A232FD00EFC5FF"
BuildableName = "TunnelKitDemo-iOS.app"
BlueprintName = "TunnelKitDemo-iOS"
BlueprintIdentifier = "0E05419E25A2343500EFC5FF"
BuildableName = "TunnelKitDemoOpenVPNTunnel-iOS.appex"
BlueprintName = "TunnelKitDemoOpenVPNTunnel-iOS"
ReferencedContainer = "container:TunnelKit.xcodeproj">
</BuildableReference>
</BuildableProductRunnable>
</MacroExpansion>
</ProfileAction>
<AnalyzeAction
buildConfiguration = "Debug">

View File

@ -16,8 +16,8 @@
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "0E05427625A239C600EFC5FF"
BuildableName = "TunnelKitDemoTunnel-macOS.appex"
BlueprintName = "TunnelKitDemoTunnel-macOS"
BuildableName = "TunnelKitDemoOpenVPNTunnel-macOS.appex"
BlueprintName = "TunnelKitDemoOpenVPNTunnel-macOS"
ReferencedContainer = "container:TunnelKit.xcodeproj">
</BuildableReference>
</BuildActionEntry>
@ -57,16 +57,6 @@
debugServiceExtension = "internal"
allowLocationSimulation = "YES"
launchAutomaticallySubstyle = "2">
<BuildableProductRunnable
runnableDebuggingMode = "0">
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "0E05422B25A236EB00EFC5FF"
BuildableName = "TunnelKitDemo-macOS.app"
BlueprintName = "TunnelKitDemo-macOS"
ReferencedContainer = "container:TunnelKit.xcodeproj">
</BuildableReference>
</BuildableProductRunnable>
</LaunchAction>
<ProfileAction
buildConfiguration = "Release"
@ -76,16 +66,15 @@
debugDocumentVersioning = "YES"
askForAppToLaunch = "Yes"
launchAutomaticallySubstyle = "2">
<BuildableProductRunnable
runnableDebuggingMode = "0">
<MacroExpansion>
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "0E05422B25A236EB00EFC5FF"
BuildableName = "TunnelKitDemo-macOS.app"
BlueprintName = "TunnelKitDemo-macOS"
BlueprintIdentifier = "0E05427625A239C600EFC5FF"
BuildableName = "TunnelKitDemoOpenVPNTunnel-macOS.appex"
BlueprintName = "TunnelKitDemoOpenVPNTunnel-macOS"
ReferencedContainer = "container:TunnelKit.xcodeproj">
</BuildableReference>
</BuildableProductRunnable>
</MacroExpansion>
</ProfileAction>
<AnalyzeAction
buildConfiguration = "Debug">

View File

@ -0,0 +1,86 @@
<?xml version="1.0" encoding="UTF-8"?>
<Scheme
LastUpgradeVersion = "1310"
wasCreatedForAppExtension = "YES"
version = "2.0">
<BuildAction
parallelizeBuildables = "YES"
buildImplicitDependencies = "YES">
<BuildActionEntries>
<BuildActionEntry
buildForTesting = "YES"
buildForRunning = "YES"
buildForProfiling = "YES"
buildForArchiving = "YES"
buildForAnalyzing = "YES">
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "0E833A83274BC39C008EA397"
BuildableName = "TunnelKitDemoWireGuardTunnel-iOS.appex"
BlueprintName = "TunnelKitDemoWireGuardTunnel-iOS"
ReferencedContainer = "container:TunnelKit.xcodeproj">
</BuildableReference>
</BuildActionEntry>
<BuildActionEntry
buildForTesting = "YES"
buildForRunning = "YES"
buildForProfiling = "YES"
buildForArchiving = "YES"
buildForAnalyzing = "YES">
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "0E05416825A232FD00EFC5FF"
BuildableName = "TunnelKitDemo-iOS.app"
BlueprintName = "TunnelKitDemo-iOS"
ReferencedContainer = "container:TunnelKit.xcodeproj">
</BuildableReference>
</BuildActionEntry>
</BuildActionEntries>
</BuildAction>
<TestAction
buildConfiguration = "Debug"
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
shouldUseLaunchSchemeArgsEnv = "YES">
<Testables>
</Testables>
</TestAction>
<LaunchAction
buildConfiguration = "Debug"
selectedDebuggerIdentifier = ""
selectedLauncherIdentifier = "Xcode.IDEFoundation.Launcher.PosixSpawn"
launchStyle = "0"
askForAppToLaunch = "Yes"
useCustomWorkingDirectory = "NO"
ignoresPersistentStateOnLaunch = "NO"
debugDocumentVersioning = "YES"
debugServiceExtension = "internal"
allowLocationSimulation = "YES"
launchAutomaticallySubstyle = "2">
</LaunchAction>
<ProfileAction
buildConfiguration = "Release"
shouldUseLaunchSchemeArgsEnv = "YES"
savedToolIdentifier = ""
useCustomWorkingDirectory = "NO"
debugDocumentVersioning = "YES"
askForAppToLaunch = "Yes"
launchAutomaticallySubstyle = "2">
<MacroExpansion>
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "0E833A83274BC39C008EA397"
BuildableName = "TunnelKitDemoWireGuardTunnel-iOS.appex"
BlueprintName = "TunnelKitDemoWireGuardTunnel-iOS"
ReferencedContainer = "container:TunnelKit.xcodeproj">
</BuildableReference>
</MacroExpansion>
</ProfileAction>
<AnalyzeAction
buildConfiguration = "Debug">
</AnalyzeAction>
<ArchiveAction
buildConfiguration = "Release"
revealArchiveInOrganizer = "YES">
</ArchiveAction>
</Scheme>

View File

@ -0,0 +1,86 @@
<?xml version="1.0" encoding="UTF-8"?>
<Scheme
LastUpgradeVersion = "1310"
wasCreatedForAppExtension = "YES"
version = "2.0">
<BuildAction
parallelizeBuildables = "YES"
buildImplicitDependencies = "YES">
<BuildActionEntries>
<BuildActionEntry
buildForTesting = "YES"
buildForRunning = "YES"
buildForProfiling = "YES"
buildForArchiving = "YES"
buildForAnalyzing = "YES">
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "0E833A94274BC3B1008EA397"
BuildableName = "TunnelKitDemoWireGuardTunnel-macOS.appex"
BlueprintName = "TunnelKitDemoWireGuardTunnel-macOS"
ReferencedContainer = "container:TunnelKit.xcodeproj">
</BuildableReference>
</BuildActionEntry>
<BuildActionEntry
buildForTesting = "YES"
buildForRunning = "YES"
buildForProfiling = "YES"
buildForArchiving = "YES"
buildForAnalyzing = "YES">
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "0E05422B25A236EB00EFC5FF"
BuildableName = "TunnelKitDemo-macOS.app"
BlueprintName = "TunnelKitDemo-macOS"
ReferencedContainer = "container:TunnelKit.xcodeproj">
</BuildableReference>
</BuildActionEntry>
</BuildActionEntries>
</BuildAction>
<TestAction
buildConfiguration = "Debug"
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
shouldUseLaunchSchemeArgsEnv = "YES">
<Testables>
</Testables>
</TestAction>
<LaunchAction
buildConfiguration = "Debug"
selectedDebuggerIdentifier = ""
selectedLauncherIdentifier = "Xcode.IDEFoundation.Launcher.PosixSpawn"
launchStyle = "0"
askForAppToLaunch = "Yes"
useCustomWorkingDirectory = "NO"
ignoresPersistentStateOnLaunch = "NO"
debugDocumentVersioning = "YES"
debugServiceExtension = "internal"
allowLocationSimulation = "YES"
launchAutomaticallySubstyle = "2">
</LaunchAction>
<ProfileAction
buildConfiguration = "Release"
shouldUseLaunchSchemeArgsEnv = "YES"
savedToolIdentifier = ""
useCustomWorkingDirectory = "NO"
debugDocumentVersioning = "YES"
askForAppToLaunch = "Yes"
launchAutomaticallySubstyle = "2">
<MacroExpansion>
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "0E833A94274BC3B1008EA397"
BuildableName = "TunnelKitDemoWireGuardTunnel-macOS.appex"
BlueprintName = "TunnelKitDemoWireGuardTunnel-macOS"
ReferencedContainer = "container:TunnelKit.xcodeproj">
</BuildableReference>
</MacroExpansion>
</ProfileAction>
<AnalyzeAction
buildConfiguration = "Debug">
</AnalyzeAction>
<ArchiveAction
buildConfiguration = "Release"
revealArchiveInOrganizer = "YES">
</ArchiveAction>
</Scheme>

View File

@ -18,6 +18,15 @@
"revision": "2c039501d6eeb4d4cd4aec4a8d884ad28862e044",
"version": "1.9.5"
}
},
{
"package": "WireGuardKit",
"repositoryURL": "https://git.zx2c4.com/wireguard-apple",
"state": {
"branch": null,
"revision": "10da5cfdef362889b438cfbeff867a74e6d717fd",
"version": "1.0.15-26"
}
}
]
},

View File

@ -6,7 +6,7 @@ import PackageDescription
let package = Package(
name: "TunnelKit",
platforms: [
.iOS(.v11), .macOS(.v10_15)
.iOS(.v12), .macOS(.v10_15)
],
products: [
// Products define the executables and libraries a package produces, and make them visible to other packages.
@ -26,6 +26,14 @@ let package = Package(
name: "TunnelKitOpenVPNAppExtension",
targets: ["TunnelKitOpenVPNAppExtension"]
),
.library(
name: "TunnelKitWireGuard",
targets: ["TunnelKitWireGuard"]
),
.library(
name: "TunnelKitWireGuardAppExtension",
targets: ["TunnelKitWireGuardAppExtension"]
),
.library(
name: "TunnelKitLZO",
targets: ["TunnelKitLZO"]
@ -35,7 +43,8 @@ let package = Package(
// Dependencies declare other packages that this package depends on.
// .package(url: /* package url */, from: "1.0.0"),
.package(url: "https://github.com/SwiftyBeaver/SwiftyBeaver", from: "1.9.0"),
.package(url: "https://github.com/passepartoutvpn/openssl-apple", from: "1.1.11200")
.package(url: "https://github.com/passepartoutvpn/openssl-apple", from: "1.1.11200"),
.package(name: "WireGuardKit", url: "https://git.zx2c4.com/wireguard-apple", .exact("1.0.15-26"))
],
targets: [
// Targets are the basic building blocks of a package. A target can define a module or a test suite.
@ -103,6 +112,30 @@ let package = Package(
"TunnelKitOpenVPNManager",
"TunnelKitOpenVPNProtocol"
]),
//
.target(
name: "TunnelKitWireGuard",
dependencies: [
"TunnelKitWireGuardCore",
"TunnelKitWireGuardManager"
]),
.target(
name: "TunnelKitWireGuardCore",
dependencies: [
"WireGuardKit"
]),
.target(
name: "TunnelKitWireGuardManager",
dependencies: [
"TunnelKitManager",
"TunnelKitWireGuardCore"
]),
.target(
name: "TunnelKitWireGuardAppExtension",
dependencies: [
"TunnelKitWireGuardCore",
"TunnelKitWireGuardManager"
]),
.target(
name: "TunnelKitLZO",
dependencies: [],

112
README.md
View File

@ -1,15 +1,19 @@
![iOS 11+](https://img.shields.io/badge/iOS-11+-green.svg)
![macOS 10.15+](https://img.shields.io/badge/macOS-10.15+-green.svg)
[![License GPLv3](https://img.shields.io/badge/License-GPLv3-lightgray.svg)](LICENSE)
[![GitHub Actions](https://github.com/passepartoutvpn/tunnelkit/actions/workflows/test.yml/badge.svg)](https://github.com/passepartoutvpn/tunnelkit/actions/workflows/test.yml)
![iOS 12+](https://img.shields.io/badge/ios-12+-green.svg)
![macOS 10.15+](https://img.shields.io/badge/macos-10.15+-green.svg)
[![License GPLv3](https://img.shields.io/badge/license-GPLv3-lightgray.svg)](LICENSE)
[![Unit Tests](https://github.com/passepartoutvpn/tunnelkit/actions/workflows/test.yml/badge.svg)](https://github.com/passepartoutvpn/tunnelkit/actions/workflows/test.yml)
[![Release](https://github.com/passepartoutvpn/tunnelkit/actions/workflows/release.yml/badge.svg)](https://github.com/passepartoutvpn/tunnelkit/actions/workflows/release.yml)
# TunnelKit
This library provides a generic framework for VPN development and a simplified Swift/Obj-C implementation of the OpenVPN® protocol for the Apple platforms. The crypto layer is built on top of [OpenSSL 1.1.1][dep-openssl], which in turn enables support for a certain range of encryption and digest algorithms.
This library provides a generic framework for VPN development on Apple platforms.
## Getting started
## OpenVPN
The client is known to work with [OpenVPN®][openvpn] 2.3+ servers.
TunnelKit comes with a simplified Swift/Obj-C implementation of the [OpenVPN®][dep-openvpn] protocol, whose crypto layer is built on top of [OpenSSL 1.1.1][dep-openssl].
The client is known to work with OpenVPN® 2.3+ servers.
- [x] Handshake and tunneling over UDP or TCP
- [x] Ciphers
@ -67,11 +71,36 @@ TunnelKit can parse .ovpn configuration files. Below are a few details worth men
Many other flags are ignored too but it's normally not an issue.
## WireGuard
TunnelKit offers a user-friendly API to the modern [WireGuard®][dep-wireguard] protocol.
### Manual Xcode steps
If you add any `TunnelKitWireGuard*` Swift package to the "Link with binary libraries" section of your app or tunnel extension, you are bound to hit this error:
```
ld: library not found for -lwg-go
```
because part of the WireGuardKit package is based on `make`, which SwiftPM doesn't support yet.
Therefore, make sure to follow the steps below for proper integration:
- Copy `Scripts/build_wireguard_go_bridge.sh` somewhere in your project.
- In Xcode, click File -> New -> Target. Switch to "Other" tab and choose "External Build System".
- Type a name for your target.
- Open the "Info" tab and replace `/usr/bin/make` with `$(PROJECT_DIR)/path/to/build_wireguard_go_bridge.sh` in "Build Tool".
- Switch to "Build Settings" and find SDKROOT. Type in `macosx` if you target macOS, or type in `iphoneos` if you target iOS.
- Locate your tunnel extension target and switch to "Build Phases" tab.
- Locate "Dependencies" section and hit "+" to add the target you have just created.
- Repeat the process for each platform.
## Installation
### Requirements
- iOS 11.0+ / macOS 10.15+
- iOS 12.0+ / macOS 10.15+
- SwiftPM 5.3
- Git (preinstalled with Xcode Command Line Tools)
@ -79,7 +108,7 @@ It's highly recommended to use the Git package provided by [Homebrew][dep-brew].
### Caveats
Make sure to set "Enable Bitcode" (iOS) to NO, otherwise the library [would not be able to link OpenSSL][about-pr-bitcode].
Make sure to set "Enable Bitcode" (iOS) to NO, otherwise the library [would not be able to link OpenSSL][about-pr-bitcode] (OpenVPN) and the `wg-go` bridge (WireGuard).
Recent versions of Xcode (latest is 13.1) have an issue where the "Frameworks" directory is replicated inside application extensions. This is not a blocker during development, but will prevent your archive from being validated against App Store Connect due to the following error:
@ -101,14 +130,14 @@ Download the library codebase locally:
$ git clone https://github.com/passepartoutvpn/tunnelkit.git
There are demo targets containing a simple app for testing the tunnel, called `BasicTunnel`. Open `Demo/TunnelKit.xcodeproject` in Xcode and run it on both iOS and macOS.
There are demo targets containing a simple app for testing the tunnels. Open `Demo/TunnelKit.xcodeproject` in Xcode and run it on both iOS and macOS.
For the VPN to work properly, the `BasicTunnel` demo requires:
For the VPN to work properly, the demo requires:
- _App Groups_ and _Keychain Sharing_ capabilities
- App IDs with _Packet Tunnel_ entitlements
both in the main app and the tunnel extension target.
both in the main app and the tunnel extension targets.
In order to test connectivity in your own environment, modify the file `Demo/Demo/Configuration.swift` to match your VPN server parameters.
@ -120,10 +149,10 @@ Example:
-----END CERTIFICATE-----
""")
Make sure to also update the following constants in the same files, according to your developer account and your target bundle identifiers:
Make sure to also update the following constants in the `*ViewController.swift` files, according to your developer account and your target bundle identifiers:
public static let appGroup
public static let tunnelIdentifier
private let appGroup = "..."
private let tunnelIdentifier = "..."
Remember that the App Group on macOS requires a team ID prefix.
@ -133,51 +162,32 @@ The library is split into several modules, in order to decouple the low-level pr
Full documentation of the public interface is available and can be generated by opening the package in Xcode and running "Build Documentation" (Xcode 13).
### TunnelKitCore
Contains the building blocks of a VPN protocol. Eventually, a consumer would implement the `Session` interface, expected to start and control the VPN session. A session is expected to work with generic network interfaces:
- `LinkInterface` (e.g. a socket)
- `TunnelInterface` (e.g. an `utun` interface)
There are no physical network implementations (e.g. UDP or TCP) in this module.
### TunnelKitManager
### TunnelKit
This component includes convenient classes to control the VPN tunnel from your app without the NetworkExtension headaches. Have a look at `VPNProvider` implementations:
- `MockVPNProvider` (default, useful to test on simulator)
- `NetworkExtensionVPNProvider` (anything based on NetworkExtension)
### TunnelKitAppExtension
Provides a layer on top of the NetworkExtension framework. Most importantly, bridges native [NWUDPSession][ne-udp] and [NWTCPConnection][ne-tcp] to an abstract `GenericSocket` interface, thus making a multi-protocol VPN dramatically easier to manage.
### TunnelKitIKE
Here you find `NativeProvider`, a generic way to manage a VPN profile based on the native IPSec/IKEv2 protocols. Just wrap a `NEVPNProtocolIPSec` or `NEVPNProtocolIKEv2` object in a `NetworkExtensionVPNConfiguration` and use it to install or connect to the VPN.
### TunnelKitOpenVPN*
### TunnelKitOpenVPN
#### Protocol
Provides the entities to interact with the OpenVPN tunnel.
Here are the low-level entities on top of which an OpenVPN connection is established. Code is mixed Swift and Obj-C, most of it is not exposed to consumers. The protocol implementation in particular depends on OpenSSL.
### TunnelKitOpenVPNAppExtension
The entry point is the `OpenVPNSession` class. The networking layer is fully abstract and delegated externally with the use of opaque `IOInterface` (`LinkInterface` and `TunnelInterface`) and `OpenVPNSessionDelegate` protocols.
Contains the `NEPacketTunnelProvider` implementation of a OpenVPN tunnel.
#### AppExtension
### TunnelKitWireGuard
Another goal of this area is packaging up a black box implementation of a [NEPacketTunnelProvider][ne-ptp], which is the essential part of a Packet Tunnel Provider app extension. You will find the main implementation in the `OpenVPNTunnelProvider` class.
Provides the entities to interact with the WireGuard tunnel.
A debug log snapshot is optionally maintained and shared by the tunnel provider to host apps via the App Group container.
### TunnelKitWireGuardAppExtension
#### Manager
On the client side, you manage the VPN profile with the `OpenVPNProvider` class, which is a specific implementation of `NetworkExtensionVPNProvider`.
### TunnelKitLZO
Due to the restrictive license (GPLv2), LZO support is provided as an optional component.
Contains the `NEPacketTunnelProvider` implementation of a WireGuard tunnel.
## License
@ -210,20 +220,29 @@ For more details please see [CONTRIBUTING][contrib-readme].
- [SURFnet][ppl-surfnet]
- [SwiftyBeaver][dep-swiftybeaver-repo] - Copyright (c) 2015 Sebastian Kreutzberger
- [XMB5][ppl-xmb5] for the [XOR patch][ppl-xmb5-xor] - Copyright (c) 2020 Sam Foxman
- [eduVPN][ppl-eduvpn] for the convenient WireGuardKitGo script
This product includes software developed by the OpenSSL Project for use in the OpenSSL Toolkit. ([https://www.openssl.org/][dep-openssl])
### OpenVPN
Copyright (c) 2002-2018 OpenVPN Inc. - OpenVPN is a registered trademark of OpenVPN Inc.
### WireGuard
© Copyright 2015-2021 Jason A. Donenfeld. All Rights Reserved. "WireGuard" and the "WireGuard" logo are registered trademarks of Jason A. Donenfeld.
### OpenSSL
This product includes software developed by the OpenSSL Project for use in the OpenSSL Toolkit. ([https://www.openssl.org/][dep-openssl])
## Contacts
Twitter: [@keeshux][about-twitter]
Website: [passepartoutvpn.app][about-website]
[openvpn]: https://openvpn.net/index.php/open-source/overview.html
[dep-brew]: https://brew.sh/
[dep-openvpn]: https://openvpn.net/index.php/open-source/overview.html
[dep-wireguard]: https://www.wireguard.com/
[dep-openssl]: https://www.openssl.org/
[ne-home]: https://developer.apple.com/documentation/networkextension
@ -243,6 +262,7 @@ Website: [passepartoutvpn.app][about-website]
[ppl-surfnet]: https://www.surf.nl/en/about-surf/subsidiaries/surfnet
[ppl-xmb5]: https://github.com/XMB5
[ppl-xmb5-xor]: https://github.com/passepartoutvpn/tunnelkit/pull/170
[ppl-eduvpn]: https://github.com/eduvpn/apple
[about-tunnelblick-xor]: https://tunnelblick.net/cOpenvpn_xorpatch.html
[about-pr-bitcode]: https://github.com/passepartoutvpn/tunnelkit/issues/51

View File

@ -0,0 +1,40 @@
#!/bin/sh
# build_wireguard_go_bridge.sh - Builds WireGuardKitGo
#
# Figures out the directory where the wireguard-apple SPM package
# is checked out by Xcode (so that it works when building as well as
# archiving), then cd-s to the WireGuardKitGo directory
# and runs make there.
project_data_dir="$BUILD_DIR"
# The wireguard-apple README suggests using ${BUILD_DIR%Build/*}, which
# doesn't seem to work. So here, we do the equivalent in script.
while true; do
parent_dir=$(dirname "$project_data_dir")
basename=$(basename "$project_data_dir")
project_data_dir="$parent_dir"
if [ "$basename" = "Build" ]; then
break
fi
done
# The wireguard-apple README looks into
# SourcePackages/checkouts/wireguard-apple, but Xcode seems to place the
# sources in SourcePackages/checkouts/ so just playing it safe and
# trying both.
checkouts_dir="$project_data_dir"/SourcePackages/checkouts
if [ -e "$checkouts_dir"/wireguard-apple ]; then
checkouts_dir="$checkouts_dir"/wireguard-apple
fi
wireguard_go_dir="$checkouts_dir"/Sources/WireGuardKitGo
# To ensure we have Go in our path, we add where
# Homebrew generally installs executables
export PATH=${PATH}:/usr/local/bin:/opt/homebrew/bin
cd "$wireguard_go_dir" && /usr/bin/make

View File

@ -0,0 +1,2 @@
@_exported import TunnelKitWireGuardCore
@_exported import TunnelKitWireGuardManager

View File

@ -0,0 +1,42 @@
import TunnelKitWireGuardCore
import TunnelKitWireGuardManager
// SPDX-License-Identifier: MIT
// Copyright © 2018-2021 WireGuard LLC. All Rights Reserved.
import NetworkExtension
class ErrorNotifier {
private let appGroupId: String
private var sharedFolderURL: URL? {
guard let sharedFolderURL = FileManager.default.containerURL(forSecurityApplicationGroupIdentifier: appGroupId) else {
wg_log(.error, message: "Cannot obtain shared folder URL")
return nil
}
return sharedFolderURL
}
init(appGroupId: String) {
self.appGroupId = appGroupId
removeLastErrorFile()
}
func notify(_ error: WireGuardProviderError) {
guard let lastErrorFilePath = networkExtensionLastErrorFileURL?.path else {
return
}
let errorMessageData = "\(error)".data(using: .utf8)
FileManager.default.createFile(atPath: lastErrorFilePath, contents: errorMessageData, attributes: nil)
}
func removeLastErrorFile() {
if let lastErrorFileURL = networkExtensionLastErrorFileURL {
try? FileManager.default.removeItem(at: lastErrorFileURL)
}
}
private var networkExtensionLastErrorFileURL: URL? {
return sharedFolderURL?.appendingPathComponent("last-error.txt")
}
}

View File

@ -0,0 +1,134 @@
import TunnelKitWireGuardCore
import TunnelKitWireGuardManager
import WireGuardKit
// SPDX-License-Identifier: MIT
// Copyright © 2018-2021 WireGuard LLC. All Rights Reserved.
import Foundation
import NetworkExtension
import os
open class WireGuardTunnelProvider: NEPacketTunnelProvider {
private var persistentErrorNotifier: ErrorNotifier?
private lazy var adapter: WireGuardAdapter = {
return WireGuardAdapter(with: self) { logLevel, message in
wg_log(logLevel.osLogLevel, message: message)
}
}()
open override func startTunnel(options: [String: NSObject]?, completionHandler: @escaping (Error?) -> Void) {
// BEGIN: TunnelKit
guard let tunnelProviderProtocol = protocolConfiguration as? NETunnelProviderProtocol else {
fatalError("Not a NETunnelProviderProtocol")
}
guard let appGroup = tunnelProviderProtocol.providerConfiguration?["AppGroup"] as? String else {
fatalError("AppGroup not found in providerConfiguration")
}
let errorNotifier = ErrorNotifier(appGroupId: appGroup)
persistentErrorNotifier = errorNotifier
let tunnelConfiguration: TunnelConfiguration
do {
tunnelConfiguration = try WireGuardProvider.Configuration.parsed(from: tunnelProviderProtocol).tunnelConfiguration
} catch {
errorNotifier.notify(WireGuardProviderError.savedProtocolConfigurationIsInvalid)
completionHandler(WireGuardProviderError.savedProtocolConfigurationIsInvalid)
return
}
// END: TunnelKit
// Start the tunnel
adapter.start(tunnelConfiguration: tunnelConfiguration) { adapterError in
guard let adapterError = adapterError else {
let interfaceName = self.adapter.interfaceName ?? "unknown"
wg_log(.info, message: "Tunnel interface is \(interfaceName)")
completionHandler(nil)
return
}
switch adapterError {
case .cannotLocateTunnelFileDescriptor:
wg_log(.error, staticMessage: "Starting tunnel failed: could not determine file descriptor")
errorNotifier.notify(WireGuardProviderError.couldNotDetermineFileDescriptor)
completionHandler(WireGuardProviderError.couldNotDetermineFileDescriptor)
case .dnsResolution(let dnsErrors):
let hostnamesWithDnsResolutionFailure = dnsErrors.map { $0.address }
.joined(separator: ", ")
wg_log(.error, message: "DNS resolution failed for the following hostnames: \(hostnamesWithDnsResolutionFailure)")
errorNotifier.notify(WireGuardProviderError.dnsResolutionFailure)
completionHandler(WireGuardProviderError.dnsResolutionFailure)
case .setNetworkSettings(let error):
wg_log(.error, message: "Starting tunnel failed with setTunnelNetworkSettings returning \(error.localizedDescription)")
errorNotifier.notify(WireGuardProviderError.couldNotSetNetworkSettings)
completionHandler(WireGuardProviderError.couldNotSetNetworkSettings)
case .startWireGuardBackend(let errorCode):
wg_log(.error, message: "Starting tunnel failed with wgTurnOn returning \(errorCode)")
errorNotifier.notify(WireGuardProviderError.couldNotStartBackend)
completionHandler(WireGuardProviderError.couldNotStartBackend)
case .invalidState:
// Must never happen
fatalError()
}
}
}
open override func stopTunnel(with reason: NEProviderStopReason, completionHandler: @escaping () -> Void) {
wg_log(.info, staticMessage: "Stopping tunnel")
adapter.stop { error in
// BEGIN: TunnelKit
self.persistentErrorNotifier?.removeLastErrorFile()
// END: TunnelKit
if let error = error {
wg_log(.error, message: "Failed to stop WireGuard adapter: \(error.localizedDescription)")
}
completionHandler()
#if os(macOS)
// HACK: This is a filthy hack to work around Apple bug 32073323 (dup'd by us as 47526107).
// Remove it when they finally fix this upstream and the fix has been rolled out to
// sufficient quantities of users.
exit(0)
#endif
}
}
open override func handleAppMessage(_ messageData: Data, completionHandler: ((Data?) -> Void)? = nil) {
guard let completionHandler = completionHandler else { return }
if messageData.count == 1 && messageData[0] == 0 {
adapter.getRuntimeConfiguration { settings in
var data: Data?
if let settings = settings {
data = settings.data(using: .utf8)!
}
completionHandler(data)
}
} else {
completionHandler(nil)
}
}
}
extension WireGuardLogLevel {
var osLogLevel: OSLogType {
switch self {
case .verbose:
return .debug
case .error:
return .error
}
}
}

View File

@ -0,0 +1,48 @@
//
// Configuration+WireGuardKit.swift
// TunnelKit
//
// Created by Davide De Rosa on 11/23/21.
// Copyright (c) 2021 Davide De Rosa. All rights reserved.
//
// https://github.com/passepartoutvpn
//
// This file is part of TunnelKit.
//
// TunnelKit is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// TunnelKit is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with TunnelKit. If not, see <http://www.gnu.org/licenses/>.
//
import Foundation
import WireGuardKit
extension WireGuard.Configuration {
public init(wgQuickConfig: String) throws {
tunnelConfiguration = try TunnelConfiguration(fromWgQuickConfig: wgQuickConfig)
}
public func asWgQuickConfig() -> String {
return tunnelConfiguration.asWgQuickConfig()
}
public var endpointRepresentation: String {
let endpoints = tunnelConfiguration.peers.compactMap { $0.endpoint }
if endpoints.count == 1 {
return endpoints[0].stringRepresentation
} else if endpoints.isEmpty {
return "Unspecified"
} else {
return "Multiple endpoints"
}
}
}

View File

@ -0,0 +1,99 @@
//
// Configuration.swift
// TunnelKit
//
// Created by Davide De Rosa on 11/23/21.
// Copyright (c) 2021 Davide De Rosa. All rights reserved.
//
// https://github.com/passepartoutvpn
//
// This file is part of TunnelKit.
//
// TunnelKit is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// TunnelKit is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with TunnelKit. If not, see <http://www.gnu.org/licenses/>.
//
import Foundation
import WireGuardKit
extension WireGuard {
public struct ConfigurationBuilder {
public var privateKey: String?
public var addresses: [String]?
public var dns: [String]?
public var mtu: UInt16?
public var peerPublicKey: String?
public var peerPreSharedKey: String?
public var peerAddress: String?
public var peerPort: UInt16?
public var allowedIPs: [String]?
public var keepAliveInterval: UInt16?
public init() {
}
public func build() -> Configuration? {
guard let privateKey = privateKey, let clientPrivateKey = PrivateKey(base64Key: privateKey) else {
return nil
}
guard let peerPublicKey = peerPublicKey, let serverPublicKey = PublicKey(base64Key: peerPublicKey) else {
return nil
}
guard let peerAddress = peerAddress, let peerPort = peerPort, let endpoint = Endpoint(from: "\(peerAddress):\(peerPort)") else {
return nil
}
var interfaceConfiguration = InterfaceConfiguration(privateKey: clientPrivateKey)
if let clientAddresses = addresses?.mapOptional({ IPAddressRange(from: $0) }) {
interfaceConfiguration.addresses = clientAddresses
}
if let dnsServers = dns?.mapOptional({ DNSServer(from: $0) }) {
interfaceConfiguration.dns = dnsServers
}
interfaceConfiguration.mtu = mtu
var peerConfiguration = PeerConfiguration(publicKey: serverPublicKey)
if let peerPreSharedKey = peerPreSharedKey {
peerConfiguration.preSharedKey = PreSharedKey(base64Key: peerPreSharedKey)
}
if let peerAllowedIPs = allowedIPs?.mapOptional({ IPAddressRange(from: $0) }) {
peerConfiguration.allowedIPs = peerAllowedIPs
}
peerConfiguration.endpoint = endpoint
peerConfiguration.persistentKeepAlive = keepAliveInterval
let tunnelConfiguration = TunnelConfiguration(name: nil, interface: interfaceConfiguration, peers: [peerConfiguration])
return Configuration(tunnelConfiguration: tunnelConfiguration)
}
}
public struct Configuration {
public let tunnelConfiguration: TunnelConfiguration
}
}
private extension Array {
func mapOptional<V>(_ transform: (Self.Element) throws -> V?) rethrows -> [V] {
return try map(transform)
.filter { $0 != nil }
.map { $0! }
}
}

View File

@ -0,0 +1,13 @@
// SPDX-License-Identifier: MIT
// Copyright © 2018-2021 WireGuard LLC. All Rights Reserved.
import Foundation
import os.log
public func wg_log(_ type: OSLogType, staticMessage msg: StaticString) {
os_log(msg, log: OSLog.default, type: type)
}
public func wg_log(_ type: OSLogType, message msg: String) {
os_log("%{public}s", log: OSLog.default, type: type, msg)
}

View File

@ -0,0 +1,32 @@
// SPDX-License-Identifier: MIT
// Copyright © 2018-2021 WireGuard LLC. All Rights Reserved.
import Foundation
extension String {
func splitToArray(separator: Character = ",", trimmingCharacters: CharacterSet? = nil) -> [String] {
return split(separator: separator)
.map {
if let charSet = trimmingCharacters {
return $0.trimmingCharacters(in: charSet)
} else {
return String($0)
}
}
}
}
extension Optional where Wrapped == String {
func splitToArray(separator: Character = ",", trimmingCharacters: CharacterSet? = nil) -> [String] {
switch self {
case .none:
return []
case .some(let wrapped):
return wrapped.splitToArray(separator: separator, trimmingCharacters: trimmingCharacters)
}
}
}

View File

@ -0,0 +1,254 @@
import WireGuardKit
// SPDX-License-Identifier: MIT
// Copyright © 2018-2021 WireGuard LLC. All Rights Reserved.
import Foundation
extension TunnelConfiguration {
enum ParserState {
case inInterfaceSection
case inPeerSection
case notInASection
}
enum ParseError: Error {
case invalidLine(String.SubSequence)
case noInterface
case multipleInterfaces
case interfaceHasNoPrivateKey
case interfaceHasInvalidPrivateKey(String)
case interfaceHasInvalidListenPort(String)
case interfaceHasInvalidAddress(String)
case interfaceHasInvalidDNS(String)
case interfaceHasInvalidMTU(String)
case interfaceHasUnrecognizedKey(String)
case peerHasNoPublicKey
case peerHasInvalidPublicKey(String)
case peerHasInvalidPreSharedKey(String)
case peerHasInvalidAllowedIP(String)
case peerHasInvalidEndpoint(String)
case peerHasInvalidPersistentKeepAlive(String)
case peerHasInvalidTransferBytes(String)
case peerHasInvalidLastHandshakeTime(String)
case peerHasUnrecognizedKey(String)
case multiplePeersWithSamePublicKey
case multipleEntriesForKey(String)
}
convenience init(fromWgQuickConfig wgQuickConfig: String, called name: String? = nil) throws {
var interfaceConfiguration: InterfaceConfiguration?
var peerConfigurations = [PeerConfiguration]()
let lines = wgQuickConfig.split { $0.isNewline }
var parserState = ParserState.notInASection
var attributes = [String: String]()
for (lineIndex, line) in lines.enumerated() {
var trimmedLine: String
if let commentRange = line.range(of: "#") {
trimmedLine = String(line[..<commentRange.lowerBound])
} else {
trimmedLine = String(line)
}
trimmedLine = trimmedLine.trimmingCharacters(in: .whitespacesAndNewlines)
let lowercasedLine = trimmedLine.lowercased()
if !trimmedLine.isEmpty {
if let equalsIndex = trimmedLine.firstIndex(of: "=") {
// Line contains an attribute
let keyWithCase = trimmedLine[..<equalsIndex].trimmingCharacters(in: .whitespacesAndNewlines)
let key = keyWithCase.lowercased()
let value = trimmedLine[trimmedLine.index(equalsIndex, offsetBy: 1)...].trimmingCharacters(in: .whitespacesAndNewlines)
let keysWithMultipleEntriesAllowed: Set<String> = ["address", "allowedips", "dns"]
if let presentValue = attributes[key] {
if keysWithMultipleEntriesAllowed.contains(key) {
attributes[key] = presentValue + "," + value
} else {
throw ParseError.multipleEntriesForKey(keyWithCase)
}
} else {
attributes[key] = value
}
let interfaceSectionKeys: Set<String> = ["privatekey", "listenport", "address", "dns", "mtu"]
let peerSectionKeys: Set<String> = ["publickey", "presharedkey", "allowedips", "endpoint", "persistentkeepalive"]
if parserState == .inInterfaceSection {
guard interfaceSectionKeys.contains(key) else {
throw ParseError.interfaceHasUnrecognizedKey(keyWithCase)
}
} else if parserState == .inPeerSection {
guard peerSectionKeys.contains(key) else {
throw ParseError.peerHasUnrecognizedKey(keyWithCase)
}
}
} else if lowercasedLine != "[interface]" && lowercasedLine != "[peer]" {
throw ParseError.invalidLine(line)
}
}
let isLastLine = lineIndex == lines.count - 1
if isLastLine || lowercasedLine == "[interface]" || lowercasedLine == "[peer]" {
// Previous section has ended; process the attributes collected so far
if parserState == .inInterfaceSection {
let interface = try TunnelConfiguration.collate(interfaceAttributes: attributes)
guard interfaceConfiguration == nil else { throw ParseError.multipleInterfaces }
interfaceConfiguration = interface
} else if parserState == .inPeerSection {
let peer = try TunnelConfiguration.collate(peerAttributes: attributes)
peerConfigurations.append(peer)
}
}
if lowercasedLine == "[interface]" {
parserState = .inInterfaceSection
attributes.removeAll()
} else if lowercasedLine == "[peer]" {
parserState = .inPeerSection
attributes.removeAll()
}
}
let peerPublicKeysArray = peerConfigurations.map { $0.publicKey }
let peerPublicKeysSet = Set<PublicKey>(peerPublicKeysArray)
if peerPublicKeysArray.count != peerPublicKeysSet.count {
throw ParseError.multiplePeersWithSamePublicKey
}
if let interfaceConfiguration = interfaceConfiguration {
self.init(name: name, interface: interfaceConfiguration, peers: peerConfigurations)
} else {
throw ParseError.noInterface
}
}
func asWgQuickConfig() -> String {
var output = "[Interface]\n"
output.append("PrivateKey = \(interface.privateKey.base64Key)\n")
if let listenPort = interface.listenPort {
output.append("ListenPort = \(listenPort)\n")
}
if !interface.addresses.isEmpty {
let addressString = interface.addresses.map { $0.stringRepresentation }.joined(separator: ", ")
output.append("Address = \(addressString)\n")
}
if !interface.dns.isEmpty || !interface.dnsSearch.isEmpty {
var dnsLine = interface.dns.map { $0.stringRepresentation }
dnsLine.append(contentsOf: interface.dnsSearch)
let dnsString = dnsLine.joined(separator: ", ")
output.append("DNS = \(dnsString)\n")
}
if let mtu = interface.mtu {
output.append("MTU = \(mtu)\n")
}
for peer in peers {
output.append("\n[Peer]\n")
output.append("PublicKey = \(peer.publicKey.base64Key)\n")
if let preSharedKey = peer.preSharedKey?.base64Key {
output.append("PresharedKey = \(preSharedKey)\n")
}
if !peer.allowedIPs.isEmpty {
let allowedIPsString = peer.allowedIPs.map { $0.stringRepresentation }.joined(separator: ", ")
output.append("AllowedIPs = \(allowedIPsString)\n")
}
if let endpoint = peer.endpoint {
output.append("Endpoint = \(endpoint.stringRepresentation)\n")
}
if let persistentKeepAlive = peer.persistentKeepAlive {
output.append("PersistentKeepalive = \(persistentKeepAlive)\n")
}
}
return output
}
private static func collate(interfaceAttributes attributes: [String: String]) throws -> InterfaceConfiguration {
guard let privateKeyString = attributes["privatekey"] else {
throw ParseError.interfaceHasNoPrivateKey
}
guard let privateKey = PrivateKey(base64Key: privateKeyString) else {
throw ParseError.interfaceHasInvalidPrivateKey(privateKeyString)
}
var interface = InterfaceConfiguration(privateKey: privateKey)
if let listenPortString = attributes["listenport"] {
guard let listenPort = UInt16(listenPortString) else {
throw ParseError.interfaceHasInvalidListenPort(listenPortString)
}
interface.listenPort = listenPort
}
if let addressesString = attributes["address"] {
var addresses = [IPAddressRange]()
for addressString in addressesString.splitToArray(trimmingCharacters: .whitespacesAndNewlines) {
guard let address = IPAddressRange(from: addressString) else {
throw ParseError.interfaceHasInvalidAddress(addressString)
}
addresses.append(address)
}
interface.addresses = addresses
}
if let dnsString = attributes["dns"] {
var dnsServers = [DNSServer]()
var dnsSearch = [String]()
for dnsServerString in dnsString.splitToArray(trimmingCharacters: .whitespacesAndNewlines) {
if let dnsServer = DNSServer(from: dnsServerString) {
dnsServers.append(dnsServer)
} else {
dnsSearch.append(dnsServerString)
}
}
interface.dns = dnsServers
interface.dnsSearch = dnsSearch
}
if let mtuString = attributes["mtu"] {
guard let mtu = UInt16(mtuString) else {
throw ParseError.interfaceHasInvalidMTU(mtuString)
}
interface.mtu = mtu
}
return interface
}
private static func collate(peerAttributes attributes: [String: String]) throws -> PeerConfiguration {
guard let publicKeyString = attributes["publickey"] else {
throw ParseError.peerHasNoPublicKey
}
guard let publicKey = PublicKey(base64Key: publicKeyString) else {
throw ParseError.peerHasInvalidPublicKey(publicKeyString)
}
var peer = PeerConfiguration(publicKey: publicKey)
if let preSharedKeyString = attributes["presharedkey"] {
guard let preSharedKey = PreSharedKey(base64Key: preSharedKeyString) else {
throw ParseError.peerHasInvalidPreSharedKey(preSharedKeyString)
}
peer.preSharedKey = preSharedKey
}
if let allowedIPsString = attributes["allowedips"] {
var allowedIPs = [IPAddressRange]()
for allowedIPString in allowedIPsString.splitToArray(trimmingCharacters: .whitespacesAndNewlines) {
guard let allowedIP = IPAddressRange(from: allowedIPString) else {
throw ParseError.peerHasInvalidAllowedIP(allowedIPString)
}
allowedIPs.append(allowedIP)
}
peer.allowedIPs = allowedIPs
}
if let endpointString = attributes["endpoint"] {
guard let endpoint = Endpoint(from: endpointString) else {
throw ParseError.peerHasInvalidEndpoint(endpointString)
}
peer.endpoint = endpoint
}
if let persistentKeepAliveString = attributes["persistentkeepalive"] {
guard let persistentKeepAlive = UInt16(persistentKeepAliveString) else {
throw ParseError.peerHasInvalidPersistentKeepAlive(persistentKeepAliveString)
}
peer.persistentKeepAlive = persistentKeepAlive
}
return peer
}
}

View File

@ -0,0 +1,29 @@
//
// WireGuard.swift
// TunnelKit
//
// Created by Davide De Rosa on 11/21/21.
// Copyright (c) 2021 Davide De Rosa. All rights reserved.
//
// https://github.com/passepartoutvpn
//
// This file is part of TunnelKit.
//
// TunnelKit is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// TunnelKit is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with TunnelKit. If not, see <http://www.gnu.org/licenses/>.
//
import Foundation
public class WireGuard {
}

View File

@ -0,0 +1,79 @@
//
// WireGuardProvider+Configuration.swift
// TunnelKit
//
// Created by Davide De Rosa on 11/21/21.
// Copyright (c) 2021 Davide De Rosa. All rights reserved.
//
// https://github.com/passepartoutvpn
//
// This file is part of TunnelKit.
//
// TunnelKit is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// TunnelKit is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with TunnelKit. If not, see <http://www.gnu.org/licenses/>.
//
import Foundation
import NetworkExtension
import TunnelKitManager
import TunnelKitWireGuardCore
import WireGuardKit
extension WireGuardProvider {
public struct Configuration {
public let innerConfiguration: WireGuard.Configuration
// required by WireGuardTunnelProvider
public var tunnelConfiguration: TunnelConfiguration {
return innerConfiguration.tunnelConfiguration
}
public init(innerConfiguration: WireGuard.Configuration) {
self.innerConfiguration = innerConfiguration
}
private init(wgQuickConfig: String) throws {
innerConfiguration = try WireGuard.Configuration(wgQuickConfig: wgQuickConfig)
}
public func generatedTunnelProtocol(withBundleIdentifier bundleIdentifier: String, appGroup: String, context: String) throws -> NETunnelProviderProtocol {
let protocolConfiguration = NETunnelProviderProtocol()
protocolConfiguration.providerBundleIdentifier = bundleIdentifier
protocolConfiguration.serverAddress = innerConfiguration.endpointRepresentation
let keychain = Keychain(group: appGroup)
let wgString = innerConfiguration.asWgQuickConfig()
protocolConfiguration.passwordReference = try keychain.set(password: wgString, for: "", context: context)
protocolConfiguration.providerConfiguration = ["AppGroup": appGroup]
return protocolConfiguration
}
public static func appGroup(from protocolConfiguration: NETunnelProviderProtocol) throws -> String {
guard let appGroup = protocolConfiguration.providerConfiguration?["AppGroup"] as? String else {
throw WireGuardProviderError.savedProtocolConfigurationIsInvalid
}
return appGroup
}
public static func parsed(from protocolConfiguration: NETunnelProviderProtocol) throws -> Configuration {
guard let passwordReference = protocolConfiguration.passwordReference,
let wgString = try? Keychain.password(forReference: passwordReference) else {
throw WireGuardProviderError.savedProtocolConfigurationIsInvalid
}
return try Configuration(wgQuickConfig: wgString)
}
}
}

View File

@ -0,0 +1,74 @@
//
// WireGuardProvider.swift
// TunnelKit
//
// Created by Davide De Rosa on 11/21/21.
// Copyright (c) 2021 Davide De Rosa. All rights reserved.
//
// https://github.com/passepartoutvpn
//
// This file is part of TunnelKit.
//
// TunnelKit is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// TunnelKit is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with TunnelKit. If not, see <http://www.gnu.org/licenses/>.
//
import Foundation
import NetworkExtension
import TunnelKitManager
public class WireGuardProvider: VPNProvider {
private let provider: NetworkExtensionVPNProvider
public init(bundleIdentifier: String) {
provider = NetworkExtensionVPNProvider(locator: NetworkExtensionTunnelLocator(bundleIdentifier: bundleIdentifier))
}
// MARK: VPNProvider
public var isPrepared: Bool {
return provider.isPrepared
}
public var isEnabled: Bool {
return provider.isEnabled
}
public var status: VPNStatus {
return provider.status
}
public func prepare(completionHandler: (() -> Void)?) {
provider.prepare(completionHandler: completionHandler)
}
public func install(configuration: VPNConfiguration, completionHandler: ((Error?) -> Void)?) {
provider.install(configuration: configuration, completionHandler: completionHandler)
}
public func connect(completionHandler: ((Error?) -> Void)?) {
provider.connect(completionHandler: completionHandler)
}
public func disconnect(completionHandler: ((Error?) -> Void)?) {
provider.disconnect(completionHandler: completionHandler)
}
public func reconnect(configuration: VPNConfiguration, delay: Double? = nil, completionHandler: ((Error?) -> Void)?) {
provider.reconnect(configuration: configuration, delay: delay, completionHandler: completionHandler)
}
public func uninstall(completionHandler: (() -> Void)?) {
provider.uninstall(completionHandler: completionHandler)
}
}

View File

@ -0,0 +1,12 @@
// SPDX-License-Identifier: MIT
// Copyright © 2018-2021 WireGuard LLC. All Rights Reserved.
import Foundation
public enum WireGuardProviderError: String, Error {
case savedProtocolConfigurationIsInvalid
case dnsResolutionFailure
case couldNotStartBackend
case couldNotDetermineFileDescriptor
case couldNotSetNetworkSettings
}