diff --git a/src/frontends/osx/README.md b/src/frontends/osx/README.md
index 8ad7e439f..9dfdeb224 100644
--- a/src/frontends/osx/README.md
+++ b/src/frontends/osx/README.md
@@ -4,8 +4,8 @@
The strongSwan OS X App consists of two components:
-* A frontend to configure and control connections
-* A privileged helper daemon, controlled using XPC, called charon-xpc
+* A frontend App to configure and control connections (under strongSwan)
+* A privileged helper daemon, controlled using XPC (under charon-xpc)
The privileged helper daemon gets installed automatically using SMJobBless
functionality on its first use, and gets started automatically by Launchd when
@@ -13,10 +13,10 @@ needed.
charon-xpc is a special build linking statically against strongSwan components.
-charon-xpc sources are not part of the official strongSwan distribution. Build
-the charon-xpc tarball with:
+charon-xpc and the App sources are currently not part of the official strongSwan
+distribution. Build the charon-xpc tarball with:
- git archive -o charon-xpc-$(grep AC_INIT configure.ac | \
+ git archive -o osx-sources-$(grep AC_INIT configure.ac | \
cut -d '[' -f3 | cut -d ']' -f1).tar.bz2 \
HEAD src/frontends/osx
@@ -25,7 +25,7 @@ the charon-xpc tarball with:
Before building the Xcode project, the strongSwan base tree must be built using
a monolithic and static build. This can be achieved on OS X by using:
- CFLAGS="-O2 -Wall -Wno-format -Wno-pointer-sign -Wno-deprecated-declarations" \
+ CFLAGS="-O2 -g -Wall -Wno-format -Wno-pointer-sign -Wno-deprecated-declarations" \
./configure --enable-monolithic --disable-shared --enable-static \
--disable-defaults \
--enable-openssl --enable-kernel-libipsec --enable-kernel-pfroute \
@@ -38,11 +38,17 @@ a monolithic and static build. This can be achieved on OS X by using:
followed by calling make (no need to make install).
Building charon-xpc using the Xcode project yields a single binary without
-any non OS X dependencies.
+any non OS X dependencies. The strongSwan target in the same project builds
+the App and integrates charon-xpc for the deployment.
Both charon-xpc and the App must be code-signed to allow the installation of
-the privileged helper. git-grep for "Joe Developer" to change the signing
-identity.
+the privileged helper. By default both targets use the _Developer ID: *_
+wildcard to use the first usable code signing identity. Both the App and
+charon-xpc require a hardcoded certificate subject under
+_strongSwan/strongSwan-Info.plist_ respectively
+_charon-xpc/charon-xpc-Info.plist_. Update the _org.strongswan.charon-xpc_
+_SMPrivilegedExecutables_ in the App and _SMAuthorizedClients_ in charon-xpc
+with your code signing certificate identity.
## XPC application protocol ##
diff --git a/src/frontends/osx/charon-xpc/charon-xpc-Info.plist b/src/frontends/osx/charon-xpc/charon-xpc-Info.plist
index e8ddd24b0..85e2e4dc2 100644
--- a/src/frontends/osx/charon-xpc/charon-xpc-Info.plist
+++ b/src/frontends/osx/charon-xpc/charon-xpc-Info.plist
@@ -12,7 +12,7 @@
1.0
SMAuthorizedClients
- identifier org.strongswan.osx and certificate leaf[subject.CN] = "Joe Developer"
+ identifier org.strongswan.osx and certificate leaf[subject.CN] = "Developer ID Application: revosec AG (SRXT3TB2PY)"
diff --git a/src/frontends/osx/charon-xpc/charon-xpc.c b/src/frontends/osx/charon-xpc/charon-xpc.c
index 2235be12d..057bfbd88 100644
--- a/src/frontends/osx/charon-xpc/charon-xpc.c
+++ b/src/frontends/osx/charon-xpc/charon-xpc.c
@@ -122,6 +122,29 @@ static void segv_handler(int signal)
abort();
}
+/**
+ * PF_ROUTE for some reason does not send an event for the first address
+ * installed after a fresh boot. Fix this by installing a fake tun address
+ * just to remove it afterwards.
+ */
+static void fixup_pf_route()
+{
+ tun_device_t *tun;
+ host_t *host;
+
+ tun = tun_device_create(NULL);
+ if (tun)
+ {
+ if (tun->up(tun))
+ {
+ host = host_create_from_string("127.0.0.99", 0);
+ tun->set_address(tun, host, 32);
+ host->destroy(host);
+ }
+ tun->destroy(tun);
+ }
+}
+
/**
* Main function, starts the daemon.
*/
@@ -204,5 +227,6 @@ int main(int argc, char *argv[])
atexit(dispatcher_cleanup);
charon->start(charon);
+ fixup_pf_route();
return run();
}
diff --git a/src/frontends/osx/strongSwan.xcodeproj/project.pbxproj b/src/frontends/osx/strongSwan.xcodeproj/project.pbxproj
index 3b77d2552..e7840e75a 100644
--- a/src/frontends/osx/strongSwan.xcodeproj/project.pbxproj
+++ b/src/frontends/osx/strongSwan.xcodeproj/project.pbxproj
@@ -7,22 +7,94 @@
objects = {
/* Begin PBXBuildFile section */
+ 5B04A712174558F100A13BDC /* icon.png in Resources */ = {isa = PBXBuildFile; fileRef = 5B04A711174558F100A13BDC /* icon.png */; };
+ 5B04A7211747800F00A13BDC /* icon-alt.png in Resources */ = {isa = PBXBuildFile; fileRef = 5B04A7201747800F00A13BDC /* icon-alt.png */; };
+ 5B313F9A17A93D590055C86A /* icon-large.icns in Resources */ = {isa = PBXBuildFile; fileRef = 5B313F9917A93D590055C86A /* icon-large.icns */; };
5B74989217311B200041971E /* xpc_channels.c in Sources */ = {isa = PBXBuildFile; fileRef = 5B74989117311B200041971E /* xpc_channels.c */; };
5B7498B8173275D10041971E /* xpc_logger.c in Sources */ = {isa = PBXBuildFile; fileRef = 5B7498B7173275D10041971E /* xpc_logger.c */; };
+ 5B7FA5A11754D5DB00264BAC /* LogController.m in Sources */ = {isa = PBXBuildFile; fileRef = 5B7FA59F1754D5DB00264BAC /* LogController.m */; };
+ 5B7FA5B01754EBC800264BAC /* ConnController.m in Sources */ = {isa = PBXBuildFile; fileRef = 5B7FA5AE1754EBC800264BAC /* ConnController.m */; };
+ 5B7FA5B51754F5AF00264BAC /* PasswordController.m in Sources */ = {isa = PBXBuildFile; fileRef = 5B7FA5B31754F5AF00264BAC /* PasswordController.m */; };
+ 5B8D879B1A40658B008E5702 /* Helper.m in Sources */ = {isa = PBXBuildFile; fileRef = 5B8D879A1A40658B008E5702 /* Helper.m */; };
+ 5B8D879C1A409E4D008E5702 /* LogWindow.xib in Resources */ = {isa = PBXBuildFile; fileRef = 5B8D879E1A409E4D008E5702 /* LogWindow.xib */; };
+ 5B8D879F1A409E5A008E5702 /* ConnWindow.xib in Resources */ = {isa = PBXBuildFile; fileRef = 5B8D87A11A409E5A008E5702 /* ConnWindow.xib */; };
+ 5B8D87A21A409E6D008E5702 /* PasswordWindow.xib in Resources */ = {isa = PBXBuildFile; fileRef = 5B8D87A41A409E6D008E5702 /* PasswordWindow.xib */; };
+ 5BAE9E9A17A94A2600858FE2 /* icon-active.png in Resources */ = {isa = PBXBuildFile; fileRef = 5BAE9E9917A94A2500858FE2 /* icon-active.png */; };
+ 5BD1CCB11726DB0100587077 /* Cocoa.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 5BD1CCB01726DB0100587077 /* Cocoa.framework */; };
+ 5BD1CCBB1726DB0100587077 /* InfoPlist.strings in Resources */ = {isa = PBXBuildFile; fileRef = 5BD1CCB91726DB0100587077 /* InfoPlist.strings */; };
+ 5BD1CCBD1726DB0100587077 /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 5BD1CCBC1726DB0100587077 /* main.m */; };
+ 5BD1CCC11726DB0100587077 /* Credits.rtf in Resources */ = {isa = PBXBuildFile; fileRef = 5BD1CCBF1726DB0100587077 /* Credits.rtf */; };
+ 5BD1CCC41726DB0100587077 /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 5BD1CCC31726DB0100587077 /* AppDelegate.m */; };
+ 5BD1CCC71726DB0200587077 /* MainMenu.xib in Resources */ = {isa = PBXBuildFile; fileRef = 5BD1CCC51726DB0200587077 /* MainMenu.xib */; };
5BD1CCD71726DB4000587077 /* charon-xpc.c in Sources */ = {isa = PBXBuildFile; fileRef = 5BD1CCD61726DB4000587077 /* charon-xpc.c */; };
+ 5BD1CCDF1726DC0A00587077 /* org.strongswan.charon-xpc in Copy Files */ = {isa = PBXBuildFile; fileRef = 5BD1CCD11726DB4000587077 /* org.strongswan.charon-xpc */; };
+ 5BD1CCEB1727CCA400587077 /* README.md in Resources */ = {isa = PBXBuildFile; fileRef = 5BD1CCEA1727CCA400587077 /* README.md */; };
+ 5BD1CCED1727D7AF00587077 /* ServiceManagement.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 5BD1CCEC1727D7AF00587077 /* ServiceManagement.framework */; };
+ 5BD1CCF31727DE3E00587077 /* Security.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 5BD1CCF21727DE3E00587077 /* Security.framework */; };
+ 5BD1CCFB1729365F00587077 /* Control.m in Sources */ = {isa = PBXBuildFile; fileRef = 5BD1CCFA1729365F00587077 /* Control.m */; };
5BF60F31173405A000E5D608 /* CoreFoundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 5BD1CCD31726DB4000587077 /* CoreFoundation.framework */; };
5BF60F33173405AC00E5D608 /* Security.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 5BD1CCF21727DE3E00587077 /* Security.framework */; };
5BF60F3E1734070A00E5D608 /* xpc_dispatch.c in Sources */ = {isa = PBXBuildFile; fileRef = 5B74984C172AA3550041971E /* xpc_dispatch.c */; };
5BF60F631743C57500E5D608 /* SystemConfiguration.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 5BF60F621743C57500E5D608 /* SystemConfiguration.framework */; };
/* End PBXBuildFile section */
+/* Begin PBXContainerItemProxy section */
+ 5BD1CCE81726E45200587077 /* PBXContainerItemProxy */ = {
+ isa = PBXContainerItemProxy;
+ containerPortal = 5BD1CCA31726DB0100587077 /* Project object */;
+ proxyType = 1;
+ remoteGlobalIDString = 5BD1CCD01726DB4000587077;
+ remoteInfo = "charon-xpc";
+ };
+/* End PBXContainerItemProxy section */
+
+/* Begin PBXCopyFilesBuildPhase section */
+ 5BD1CCDE1726DBF100587077 /* Copy Files */ = {
+ isa = PBXCopyFilesBuildPhase;
+ buildActionMask = 12;
+ dstPath = Contents/Library/LaunchServices;
+ dstSubfolderSpec = 1;
+ files = (
+ 5BD1CCDF1726DC0A00587077 /* org.strongswan.charon-xpc in Copy Files */,
+ );
+ name = "Copy Files";
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+/* End PBXCopyFilesBuildPhase section */
+
/* Begin PBXFileReference section */
+ 5B04A711174558F100A13BDC /* icon.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = icon.png; sourceTree = ""; };
+ 5B04A7201747800F00A13BDC /* icon-alt.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "icon-alt.png"; sourceTree = ""; };
+ 5B313F9917A93D590055C86A /* icon-large.icns */ = {isa = PBXFileReference; lastKnownFileType = image.icns; path = "icon-large.icns"; sourceTree = ""; };
5B74984C172AA3550041971E /* xpc_dispatch.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = xpc_dispatch.c; sourceTree = ""; };
5B74984E172AA3670041971E /* xpc_dispatch.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = xpc_dispatch.h; sourceTree = ""; };
5B74989017311AFC0041971E /* xpc_channels.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = xpc_channels.h; sourceTree = ""; };
5B74989117311B200041971E /* xpc_channels.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = xpc_channels.c; sourceTree = ""; };
5B7498B7173275D10041971E /* xpc_logger.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = xpc_logger.c; sourceTree = ""; };
5B7498B9173275DD0041971E /* xpc_logger.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = xpc_logger.h; sourceTree = ""; };
+ 5B7FA59E1754D5DB00264BAC /* LogController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = LogController.h; sourceTree = ""; };
+ 5B7FA59F1754D5DB00264BAC /* LogController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = LogController.m; sourceTree = ""; };
+ 5B7FA5AD1754EBC800264BAC /* ConnController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ConnController.h; sourceTree = ""; };
+ 5B7FA5AE1754EBC800264BAC /* ConnController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ConnController.m; sourceTree = ""; };
+ 5B7FA5B21754F5AF00264BAC /* PasswordController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PasswordController.h; sourceTree = ""; };
+ 5B7FA5B31754F5AF00264BAC /* PasswordController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = PasswordController.m; sourceTree = ""; };
+ 5B8D87991A406572008E5702 /* Helper.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = Helper.h; sourceTree = ""; };
+ 5B8D879A1A40658B008E5702 /* Helper.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = Helper.m; sourceTree = ""; };
+ 5B8D879D1A409E4D008E5702 /* en */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = en; path = en.lproj/LogWindow.xib; sourceTree = ""; };
+ 5B8D87A01A409E5A008E5702 /* en */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = en; path = en.lproj/ConnWindow.xib; sourceTree = ""; };
+ 5B8D87A31A409E6D008E5702 /* en */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = en; path = en.lproj/PasswordWindow.xib; sourceTree = ""; };
+ 5BAE9E9917A94A2500858FE2 /* icon-active.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "icon-active.png"; sourceTree = ""; };
+ 5BD1CCAC1726DB0100587077 /* strongSwan.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = strongSwan.app; sourceTree = BUILT_PRODUCTS_DIR; };
+ 5BD1CCB01726DB0100587077 /* Cocoa.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Cocoa.framework; path = System/Library/Frameworks/Cocoa.framework; sourceTree = SDKROOT; };
+ 5BD1CCB81726DB0100587077 /* strongSwan-Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = "strongSwan-Info.plist"; sourceTree = ""; };
+ 5BD1CCBA1726DB0100587077 /* en */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = en; path = en.lproj/InfoPlist.strings; sourceTree = ""; };
+ 5BD1CCBC1726DB0100587077 /* main.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = ""; };
+ 5BD1CCBE1726DB0100587077 /* strongSwan-Prefix.pch */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "strongSwan-Prefix.pch"; sourceTree = ""; };
+ 5BD1CCC01726DB0100587077 /* en */ = {isa = PBXFileReference; lastKnownFileType = text.rtf; name = en; path = en.lproj/Credits.rtf; sourceTree = ""; };
+ 5BD1CCC21726DB0100587077 /* AppDelegate.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = AppDelegate.h; sourceTree = ""; };
+ 5BD1CCC31726DB0100587077 /* AppDelegate.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = AppDelegate.m; sourceTree = ""; };
+ 5BD1CCC61726DB0200587077 /* en */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = en; path = en.lproj/MainMenu.xib; sourceTree = ""; };
+ 5BD1CCD11726DB4000587077 /* org.strongswan.charon-xpc */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = "org.strongswan.charon-xpc"; sourceTree = BUILT_PRODUCTS_DIR; };
5BD1CCD31726DB4000587077 /* CoreFoundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreFoundation.framework; path = System/Library/Frameworks/CoreFoundation.framework; sourceTree = SDKROOT; };
5BD1CCD61726DB4000587077 /* charon-xpc.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = "charon-xpc.c"; sourceTree = ""; };
5BD1CCE01726DCD000587077 /* charon-xpc-Launchd.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = "charon-xpc-Launchd.plist"; sourceTree = ""; };
@@ -30,10 +102,22 @@
5BD1CCEA1727CCA400587077 /* README.md */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = README.md; sourceTree = ""; };
5BD1CCEC1727D7AF00587077 /* ServiceManagement.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = ServiceManagement.framework; path = System/Library/Frameworks/ServiceManagement.framework; sourceTree = SDKROOT; };
5BD1CCF21727DE3E00587077 /* Security.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Security.framework; path = System/Library/Frameworks/Security.framework; sourceTree = SDKROOT; };
+ 5BD1CCF91729365F00587077 /* Control.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Control.h; sourceTree = ""; };
+ 5BD1CCFA1729365F00587077 /* Control.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = Control.m; sourceTree = ""; };
5BF60F621743C57500E5D608 /* SystemConfiguration.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = SystemConfiguration.framework; path = System/Library/Frameworks/SystemConfiguration.framework; sourceTree = SDKROOT; };
/* End PBXFileReference section */
/* Begin PBXFrameworksBuildPhase section */
+ 5BD1CCA91726DB0100587077 /* Frameworks */ = {
+ isa = PBXFrameworksBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ 5BD1CCF31727DE3E00587077 /* Security.framework in Frameworks */,
+ 5BD1CCED1727D7AF00587077 /* ServiceManagement.framework in Frameworks */,
+ 5BD1CCB11726DB0100587077 /* Cocoa.framework in Frameworks */,
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
5BD1CCCE1726DB4000587077 /* Frameworks */ = {
isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647;
@@ -51,6 +135,7 @@
isa = PBXGroup;
children = (
5BD1CCEA1727CCA400587077 /* README.md */,
+ 5BD1CCB61726DB0100587077 /* strongSwan */,
5BD1CCD51726DB4000587077 /* charon-xpc */,
5BD1CCAF1726DB0100587077 /* Frameworks */,
5BD1CCAD1726DB0100587077 /* Products */,
@@ -60,6 +145,7 @@
5BD1CCAD1726DB0100587077 /* Products */ = {
isa = PBXGroup;
children = (
+ 5BD1CCAC1726DB0100587077 /* strongSwan.app */,
5BD1CCD11726DB4000587077 /* org.strongswan.charon-xpc */,
);
name = Products;
@@ -71,11 +157,44 @@
5BF60F621743C57500E5D608 /* SystemConfiguration.framework */,
5BD1CCF21727DE3E00587077 /* Security.framework */,
5BD1CCEC1727D7AF00587077 /* ServiceManagement.framework */,
+ 5BD1CCB01726DB0100587077 /* Cocoa.framework */,
5BD1CCD31726DB4000587077 /* CoreFoundation.framework */,
);
name = Frameworks;
sourceTree = "";
};
+ 5BD1CCB61726DB0100587077 /* strongSwan */ = {
+ isa = PBXGroup;
+ children = (
+ 5B04A711174558F100A13BDC /* icon.png */,
+ 5B04A7201747800F00A13BDC /* icon-alt.png */,
+ 5BAE9E9917A94A2500858FE2 /* icon-active.png */,
+ 5B313F9917A93D590055C86A /* icon-large.icns */,
+ 5BD1CCBF1726DB0100587077 /* Credits.rtf */,
+ 5BD1CCBE1726DB0100587077 /* strongSwan-Prefix.pch */,
+ 5BD1CCBC1726DB0100587077 /* main.m */,
+ 5BD1CCB91726DB0100587077 /* InfoPlist.strings */,
+ 5BD1CCB81726DB0100587077 /* strongSwan-Info.plist */,
+ 5BD1CCC21726DB0100587077 /* AppDelegate.h */,
+ 5BD1CCC31726DB0100587077 /* AppDelegate.m */,
+ 5B7FA59E1754D5DB00264BAC /* LogController.h */,
+ 5B7FA59F1754D5DB00264BAC /* LogController.m */,
+ 5B8D879E1A409E4D008E5702 /* LogWindow.xib */,
+ 5BD1CCC51726DB0200587077 /* MainMenu.xib */,
+ 5BD1CCF91729365F00587077 /* Control.h */,
+ 5BD1CCFA1729365F00587077 /* Control.m */,
+ 5B7FA5AD1754EBC800264BAC /* ConnController.h */,
+ 5B7FA5AE1754EBC800264BAC /* ConnController.m */,
+ 5B8D87A11A409E5A008E5702 /* ConnWindow.xib */,
+ 5B7FA5B21754F5AF00264BAC /* PasswordController.h */,
+ 5B7FA5B31754F5AF00264BAC /* PasswordController.m */,
+ 5B8D87A41A409E6D008E5702 /* PasswordWindow.xib */,
+ 5B8D87991A406572008E5702 /* Helper.h */,
+ 5B8D879A1A40658B008E5702 /* Helper.m */,
+ );
+ path = strongSwan;
+ sourceTree = "";
+ };
5BD1CCD51726DB4000587077 /* charon-xpc */ = {
isa = PBXGroup;
children = (
@@ -95,6 +214,25 @@
/* End PBXGroup section */
/* Begin PBXNativeTarget section */
+ 5BD1CCAB1726DB0100587077 /* strongSwan */ = {
+ isa = PBXNativeTarget;
+ buildConfigurationList = 5BD1CCCA1726DB0200587077 /* Build configuration list for PBXNativeTarget "strongSwan" */;
+ buildPhases = (
+ 5BD1CCA81726DB0100587077 /* Sources */,
+ 5BD1CCA91726DB0100587077 /* Frameworks */,
+ 5BD1CCAA1726DB0100587077 /* Resources */,
+ 5BD1CCDE1726DBF100587077 /* Copy Files */,
+ );
+ buildRules = (
+ );
+ dependencies = (
+ 5BD1CCE91726E45200587077 /* PBXTargetDependency */,
+ );
+ name = strongSwan;
+ productName = strongSwan;
+ productReference = 5BD1CCAC1726DB0100587077 /* strongSwan.app */;
+ productType = "com.apple.product-type.application";
+ };
5BD1CCD01726DB4000587077 /* charon-xpc */ = {
isa = PBXNativeTarget;
buildConfigurationList = 5BD1CCDA1726DB4000587077 /* Build configuration list for PBXNativeTarget "charon-xpc" */;
@@ -117,7 +255,7 @@
5BD1CCA31726DB0100587077 /* Project object */ = {
isa = PBXProject;
attributes = {
- LastUpgradeCheck = 0450;
+ LastUpgradeCheck = 0610;
ORGANIZATIONNAME = "revosec AG";
};
buildConfigurationList = 5BD1CCA61726DB0100587077 /* Build configuration list for PBXProject "strongSwan" */;
@@ -132,12 +270,48 @@
projectDirPath = "";
projectRoot = "";
targets = (
+ 5BD1CCAB1726DB0100587077 /* strongSwan */,
5BD1CCD01726DB4000587077 /* charon-xpc */,
);
};
/* End PBXProject section */
+/* Begin PBXResourcesBuildPhase section */
+ 5BD1CCAA1726DB0100587077 /* Resources */ = {
+ isa = PBXResourcesBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ 5BD1CCBB1726DB0100587077 /* InfoPlist.strings in Resources */,
+ 5BD1CCC11726DB0100587077 /* Credits.rtf in Resources */,
+ 5BD1CCC71726DB0200587077 /* MainMenu.xib in Resources */,
+ 5BD1CCEB1727CCA400587077 /* README.md in Resources */,
+ 5B04A712174558F100A13BDC /* icon.png in Resources */,
+ 5B04A7211747800F00A13BDC /* icon-alt.png in Resources */,
+ 5B8D879C1A409E4D008E5702 /* LogWindow.xib in Resources */,
+ 5B8D879F1A409E5A008E5702 /* ConnWindow.xib in Resources */,
+ 5B8D87A21A409E6D008E5702 /* PasswordWindow.xib in Resources */,
+ 5B313F9A17A93D590055C86A /* icon-large.icns in Resources */,
+ 5BAE9E9A17A94A2600858FE2 /* icon-active.png in Resources */,
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+/* End PBXResourcesBuildPhase section */
+
/* Begin PBXSourcesBuildPhase section */
+ 5BD1CCA81726DB0100587077 /* Sources */ = {
+ isa = PBXSourcesBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ 5BD1CCBD1726DB0100587077 /* main.m in Sources */,
+ 5BD1CCC41726DB0100587077 /* AppDelegate.m in Sources */,
+ 5BD1CCFB1729365F00587077 /* Control.m in Sources */,
+ 5B7FA5A11754D5DB00264BAC /* LogController.m in Sources */,
+ 5B8D879B1A40658B008E5702 /* Helper.m in Sources */,
+ 5B7FA5B01754EBC800264BAC /* ConnController.m in Sources */,
+ 5B7FA5B51754F5AF00264BAC /* PasswordController.m in Sources */,
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
5BD1CCCD1726DB4000587077 /* Sources */ = {
isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647;
@@ -151,12 +325,70 @@
};
/* End PBXSourcesBuildPhase section */
+/* Begin PBXTargetDependency section */
+ 5BD1CCE91726E45200587077 /* PBXTargetDependency */ = {
+ isa = PBXTargetDependency;
+ target = 5BD1CCD01726DB4000587077 /* charon-xpc */;
+ targetProxy = 5BD1CCE81726E45200587077 /* PBXContainerItemProxy */;
+ };
+/* End PBXTargetDependency section */
+
+/* Begin PBXVariantGroup section */
+ 5B8D879E1A409E4D008E5702 /* LogWindow.xib */ = {
+ isa = PBXVariantGroup;
+ children = (
+ 5B8D879D1A409E4D008E5702 /* en */,
+ );
+ name = LogWindow.xib;
+ sourceTree = "";
+ };
+ 5B8D87A11A409E5A008E5702 /* ConnWindow.xib */ = {
+ isa = PBXVariantGroup;
+ children = (
+ 5B8D87A01A409E5A008E5702 /* en */,
+ );
+ name = ConnWindow.xib;
+ sourceTree = "";
+ };
+ 5B8D87A41A409E6D008E5702 /* PasswordWindow.xib */ = {
+ isa = PBXVariantGroup;
+ children = (
+ 5B8D87A31A409E6D008E5702 /* en */,
+ );
+ name = PasswordWindow.xib;
+ sourceTree = "";
+ };
+ 5BD1CCB91726DB0100587077 /* InfoPlist.strings */ = {
+ isa = PBXVariantGroup;
+ children = (
+ 5BD1CCBA1726DB0100587077 /* en */,
+ );
+ name = InfoPlist.strings;
+ sourceTree = "";
+ };
+ 5BD1CCBF1726DB0100587077 /* Credits.rtf */ = {
+ isa = PBXVariantGroup;
+ children = (
+ 5BD1CCC01726DB0100587077 /* en */,
+ );
+ name = Credits.rtf;
+ sourceTree = "";
+ };
+ 5BD1CCC51726DB0200587077 /* MainMenu.xib */ = {
+ isa = PBXVariantGroup;
+ children = (
+ 5BD1CCC61726DB0200587077 /* en */,
+ );
+ name = MainMenu.xib;
+ sourceTree = "";
+ };
+/* End PBXVariantGroup section */
+
/* Begin XCBuildConfiguration section */
5BD1CCC81726DB0200587077 /* Debug */ = {
isa = XCBuildConfiguration;
buildSettings = {
ALWAYS_SEARCH_USER_PATHS = NO;
- ARCHS = "$(ARCHS_STANDARD_64_BIT)";
CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
CLANG_CXX_LIBRARY = "libc++";
CLANG_WARN_EMPTY_BODY = YES;
@@ -175,7 +407,7 @@
GCC_WARN_ABOUT_RETURN_TYPE = YES;
GCC_WARN_UNINITIALIZED_AUTOS = YES;
GCC_WARN_UNUSED_VARIABLE = YES;
- MACOSX_DEPLOYMENT_TARGET = 10.8;
+ MACOSX_DEPLOYMENT_TARGET = 10.7;
ONLY_ACTIVE_ARCH = YES;
SDKROOT = macosx;
};
@@ -185,7 +417,6 @@
isa = XCBuildConfiguration;
buildSettings = {
ALWAYS_SEARCH_USER_PATHS = NO;
- ARCHS = "$(ARCHS_STANDARD_64_BIT)";
CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
CLANG_CXX_LIBRARY = "libc++";
CLANG_WARN_EMPTY_BODY = YES;
@@ -198,15 +429,48 @@
GCC_WARN_ABOUT_RETURN_TYPE = YES;
GCC_WARN_UNINITIALIZED_AUTOS = YES;
GCC_WARN_UNUSED_VARIABLE = YES;
- MACOSX_DEPLOYMENT_TARGET = 10.8;
+ MACOSX_DEPLOYMENT_TARGET = 10.7;
SDKROOT = macosx;
};
name = Release;
};
+ 5BD1CCCB1726DB0200587077 /* Debug */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ CODE_SIGN_IDENTITY = "Developer ID Application";
+ COMBINE_HIDPI_IMAGES = YES;
+ GCC_PRECOMPILE_PREFIX_HEADER = YES;
+ GCC_PREFIX_HEADER = "strongSwan/strongSwan-Prefix.pch";
+ INFOPLIST_FILE = "strongSwan/strongSwan-Info.plist";
+ MACOSX_DEPLOYMENT_TARGET = 10.7;
+ PRODUCT_NAME = "$(TARGET_NAME)";
+ PROVISIONING_PROFILE = "";
+ SDKROOT = macosx;
+ WRAPPER_EXTENSION = app;
+ };
+ name = Debug;
+ };
+ 5BD1CCCC1726DB0200587077 /* Release */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ CODE_SIGN_IDENTITY = "Developer ID Application";
+ COMBINE_HIDPI_IMAGES = YES;
+ COPY_PHASE_STRIP = NO;
+ GCC_PRECOMPILE_PREFIX_HEADER = YES;
+ GCC_PREFIX_HEADER = "strongSwan/strongSwan-Prefix.pch";
+ INFOPLIST_FILE = "strongSwan/strongSwan-Info.plist";
+ MACOSX_DEPLOYMENT_TARGET = 10.7;
+ PRODUCT_NAME = "$(TARGET_NAME)";
+ PROVISIONING_PROFILE = "";
+ SDKROOT = macosx;
+ WRAPPER_EXTENSION = app;
+ };
+ name = Release;
+ };
5BD1CCDB1726DB4000587077 /* Debug */ = {
isa = XCBuildConfiguration;
buildSettings = {
- CODE_SIGN_IDENTITY = "Joe Developer";
+ CODE_SIGN_IDENTITY = "Developer ID Application";
GCC_WARN_64_TO_32_BIT_CONVERSION = NO;
GCC_WARN_ABOUT_POINTER_SIGNEDNESS = NO;
GCC_WARN_TYPECHECK_CALLS_TO_PRINTF = NO;
@@ -224,6 +488,7 @@
../../libcharon/.libs,
../../libhydra/.libs,
);
+ MACOSX_DEPLOYMENT_TARGET = 10.7;
OTHER_CFLAGS = (
"-include",
../../../config.h,
@@ -249,6 +514,7 @@
);
PRODUCT_NAME = "org.strongswan.charon-xpc";
PROVISIONING_PROFILE = "";
+ SDKROOT = macosx;
STRIP_STYLE = "non-global";
};
name = Debug;
@@ -256,8 +522,8 @@
5BD1CCDC1726DB4000587077 /* Release */ = {
isa = XCBuildConfiguration;
buildSettings = {
- CODE_SIGN_IDENTITY = "Joe Developer";
- COPY_PHASE_STRIP = YES;
+ CODE_SIGN_IDENTITY = "Developer ID Application";
+ COPY_PHASE_STRIP = NO;
GCC_WARN_64_TO_32_BIT_CONVERSION = NO;
GCC_WARN_ABOUT_POINTER_SIGNEDNESS = NO;
GCC_WARN_TYPECHECK_CALLS_TO_PRINTF = NO;
@@ -275,6 +541,7 @@
../../libcharon/.libs,
../../libhydra/.libs,
);
+ MACOSX_DEPLOYMENT_TARGET = 10.7;
OTHER_CFLAGS = (
"-include",
../../../config.h,
@@ -300,6 +567,7 @@
);
PRODUCT_NAME = "org.strongswan.charon-xpc";
PROVISIONING_PROFILE = "";
+ SDKROOT = macosx;
STRIP_STYLE = "non-global";
};
name = Release;
@@ -316,6 +584,15 @@
defaultConfigurationIsVisible = 0;
defaultConfigurationName = Release;
};
+ 5BD1CCCA1726DB0200587077 /* Build configuration list for PBXNativeTarget "strongSwan" */ = {
+ isa = XCConfigurationList;
+ buildConfigurations = (
+ 5BD1CCCB1726DB0200587077 /* Debug */,
+ 5BD1CCCC1726DB0200587077 /* Release */,
+ );
+ defaultConfigurationIsVisible = 0;
+ defaultConfigurationName = Release;
+ };
5BD1CCDA1726DB4000587077 /* Build configuration list for PBXNativeTarget "charon-xpc" */ = {
isa = XCConfigurationList;
buildConfigurations = (
diff --git a/src/frontends/osx/strongSwan/AppDelegate.h b/src/frontends/osx/strongSwan/AppDelegate.h
new file mode 100644
index 000000000..062da7d3d
--- /dev/null
+++ b/src/frontends/osx/strongSwan/AppDelegate.h
@@ -0,0 +1,36 @@
+/*
+ * Copyright (C) 2013 Martin Willi
+ * Copyright (C) 2013 revosec AG
+ *
+ * This program 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 2 of the License, or (at your
+ * option) any later version. See .
+ *
+ * This program 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.
+ */
+
+#import
+
+#import "Control.h"
+
+/**
+ * Main application delegate, controls the status menu
+ */
+@interface AppDelegate : NSObject {
+
+ /**
+ * Status menu controlled
+ */
+ IBOutlet NSMenu *statusMenu;
+}
+
+/**
+ * Action to add a new connection
+ */
+- (IBAction)addConnection:(id)sender;
+
+@end
diff --git a/src/frontends/osx/strongSwan/AppDelegate.m b/src/frontends/osx/strongSwan/AppDelegate.m
new file mode 100644
index 000000000..8fe997e0e
--- /dev/null
+++ b/src/frontends/osx/strongSwan/AppDelegate.m
@@ -0,0 +1,358 @@
+/*
+ * Copyright (C) 2013 Martin Willi
+ * Copyright (C) 2013 revosec AG
+ *
+ * This program 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 2 of the License, or (at your
+ * option) any later version. See .
+ *
+ * This program 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.
+ */
+
+#import "AppDelegate.h"
+#import "Control.h"
+#import "LogController.h"
+#import "ConnController.h"
+#import "PasswordController.h"
+
+@implementation AppDelegate {
+ NSStatusItem *statusItem;
+ NSImage *active;
+ NSImage *inactive;
+ NSInteger nonConnectionItemCount;
+ NSMutableArray *connections;
+ Control *control;
+ ConnController *editor;
+ PasswordController *password;
+}
+
+- (void)change:(connectionState)state withConnection:(NSDictionary*)conn
+{
+ NSInteger idx;
+ NSMenuItem *item;
+
+ idx = [statusMenu indexOfItemWithRepresentedObject:conn];
+ if (idx != -1)
+ {
+ item = [statusMenu itemAtIndex:idx];
+
+ switch (state) {
+ case STATE_DOWN:
+ [item setState:NSOffState];
+ [item setAction:@selector(doConnection:)];
+ [[[item submenu] itemAtIndex:0] setAction:@selector(doConnection:)];
+ [[[item submenu] itemAtIndex:0] setTitle:@"Connect"];
+ [[[item submenu] itemAtIndex:1] setAction:@selector(editConnection:)];
+ [[[item submenu] itemAtIndex:2] setAction:@selector(removeConnection:)];
+ [self updateIcon];
+ break;
+ case STATE_WORKING:
+ [item setState:NSMixedState];
+ [item setAction:@selector(undoConnection:)];
+ [[[item submenu] itemAtIndex:0] setAction:@selector(undoConnection:)];
+ [[[item submenu] itemAtIndex:0] setTitle:@"Disconnect"];
+ [[[item submenu] itemAtIndex:1] setAction:nil];
+ [[[item submenu] itemAtIndex:2] setAction:nil];
+ [self updateIcon];
+ break;
+ case STATE_UP:
+ [item setState:NSOnState];
+ [self updateIcon];
+ break;
+ }
+ }
+}
+
+- (NSString*)createPasswordWithConnection:(NSDictionary*)conn
+{
+ return [password query];
+}
+
+- (void)raise:(NSString*)alert withConnection:(NSDictionary*)conn
+{
+ NSAlert *popup;
+ NSString *text;
+
+ text = [[NSString alloc]
+ initWithFormat:@"Establishing connection %@ failed:",
+ [conn objectForKey:@"name"]];
+ popup = [[NSAlert alloc] init];
+ [popup setMessageText:text];
+ [popup setInformativeText:alert];
+ [popup runModal];
+ [text release];
+ [popup release];
+}
+
+- (void)log:(NSString*)line withConnection:(NSDictionary*)conn
+{
+ [[self findLog:conn] appendLine:line];
+}
+
+- (IBAction)undoConnection:(id)sender
+{
+ NSDictionary *conn;
+
+ conn = [sender representedObject];
+ [control disconnect:conn];
+}
+
+- (IBAction)doConnection:(id)sender
+{
+ NSDictionary *conn;
+
+ conn = [sender representedObject];
+ [[self findLog:conn] clear];
+ [control connect:conn];
+}
+
+- (IBAction)addConnection:(id)sender
+{
+ NSMutableDictionary *conn;
+
+ conn = [editor createConnection];
+ if (conn)
+ {
+ [connections insertObject:conn atIndex:[connections count]];
+ [self saveConnections];
+ }
+}
+
+- (IBAction)editConnection:(id)sender
+{
+ NSMutableDictionary *conn;
+
+ conn = [sender representedObject];
+ if ([editor editConnection:conn])
+ {
+ [self saveConnections];
+ }
+}
+
+- (IBAction)removeConnection:(id)sender
+{
+ NSDictionary *conn;
+
+ conn = [sender representedObject];
+ [connections removeObject:conn];
+ [self saveConnections];
+}
+
+- (void)loadConnections
+{
+ NSUserDefaults *defaults;
+ NSArray *array;
+
+ defaults = [NSUserDefaults standardUserDefaults];
+ array = [defaults arrayForKey:@"connections"];
+ if (array)
+ {
+ [array enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL *stop) {
+ if ([obj isKindOfClass:[NSDictionary class]])
+ {
+ NSMutableDictionary *dict;
+
+ dict = [obj mutableCopy];
+ [connections insertObject:dict atIndex:[connections count]];
+ [dict release];
+ }
+ }];
+ }
+ [defaults addObserver:self
+ forKeyPath:@"connections"
+ options:NSKeyValueObservingOptionNew
+ context:NULL];
+}
+
+- (void)saveConnections
+{
+ NSUserDefaults *defaults;
+
+ defaults = [NSUserDefaults standardUserDefaults];
+ [defaults setObject:connections forKey:@"connections"];
+ [defaults synchronize];
+}
+
+- (void)viewLog:(id)sender
+{
+ [[sender representedObject] show];
+}
+
+- (LogController*)findLog:(NSDictionary *)connection
+{
+ NSInteger idx;
+ NSMenuItem *item;
+
+ idx = [statusMenu indexOfItemWithRepresentedObject:connection];
+ if (idx != -1)
+ {
+ item = [statusMenu itemAtIndex:idx];
+ item = [[item submenu] itemAtIndex:3];
+ return [item representedObject];
+ }
+ return nil;
+}
+
+- (void)addMenuItem:(NSDictionary *)connection
+{
+ NSString *name, *title;
+ NSMenuItem *item;
+ NSMenu *submenu;
+ LogController *ctl;
+
+ name = [connection objectForKey:@"name"];
+ if (name) {
+ /* create submenu first */
+ submenu = [[NSMenu alloc] initWithTitle:@"submenu"];
+
+ item = [[NSMenuItem alloc] initWithTitle:@"Connect"
+ action:@selector(doConnection:)
+ keyEquivalent:@""];
+ [item setTarget:self];
+ [item setRepresentedObject:connection];
+ [submenu insertItem:item atIndex:0];
+ [item release];
+
+ item = [[NSMenuItem alloc] initWithTitle:@"Edit..."
+ action:@selector(editConnection:)
+ keyEquivalent:@""];
+ [item setTarget:self];
+ [item setRepresentedObject:connection];
+ [submenu insertItem:item atIndex:1];
+ [item release];
+
+ item = [[NSMenuItem alloc] initWithTitle:@"Remove"
+ action:@selector(removeConnection:)
+ keyEquivalent:@""];
+ [item setTarget:self];
+ [item setRepresentedObject:connection];
+ [submenu insertItem:item atIndex:2];
+ [item release];
+
+ item = [[NSMenuItem alloc] initWithTitle:@"View Log..."
+ action:@selector(viewLog:)
+ keyEquivalent:@""];
+ [item setTarget:self];
+ ctl = [[LogController alloc] initWithWindowNibName:@"LogWindow"];
+ title = [NSString stringWithFormat: @"strongSwan Log: %@", name];
+ [[ctl window] setTitle:title];
+ [item setRepresentedObject:ctl];
+ [ctl release];
+ [submenu insertItem:item atIndex:3];
+ [item release];
+
+ item = [[NSMenuItem alloc] initWithTitle:name
+ action:@selector(doConnection:)
+ keyEquivalent:@""];
+ [item setTarget:self];
+ [item setRepresentedObject:connection];
+ [item setSubmenu:submenu];
+ [submenu release];
+ [statusMenu insertItem:item atIndex:
+ [statusMenu numberOfItems] - nonConnectionItemCount];
+ [item release];
+ }
+}
+
+- (void)repopulateMenu
+{
+ while ([statusMenu numberOfItems] > nonConnectionItemCount)
+ {
+ [statusMenu removeItemAtIndex:0];
+ }
+ [connections enumerateObjectsUsingBlock:^(id obj, NSUInteger index, BOOL *stop) {
+ if ([obj isKindOfClass:[NSDictionary class]]) {
+ [self addMenuItem:obj];
+ }
+ }];
+}
+
+- (void)observeValueForKeyPath:(NSString *)keyPath
+ ofObject:(id)object change:(NSDictionary *)change
+ context:(void *)context
+{
+ [self repopulateMenu];
+}
+
+- (void)updateIcon
+{
+ NSMenuItem *item;
+ bool anyactive = FALSE;
+ int i;
+
+ for (i = 0; i < [statusMenu numberOfItems] - nonConnectionItemCount; i++)
+ {
+ item = [statusMenu itemAtIndex:i];
+ if ([item state] == NSOnState)
+ {
+ anyactive = TRUE;
+ break;
+ }
+ }
+ [statusItem setImage: anyactive ? active : inactive];
+}
+
+- (void)initializeMenu
+{
+ NSImage *icon;
+ NSString *path;
+
+ statusItem = [[[NSStatusBar systemStatusBar]
+ statusItemWithLength:NSVariableStatusItemLength] retain];
+ [statusItem setMenu:statusMenu];
+ [statusItem setHighlightMode:YES];
+
+ path = [[NSBundle mainBundle] pathForResource:@"icon" ofType:@"png"];
+ icon = [[NSImage alloc] initWithContentsOfFile:path];
+ [statusItem setImage:icon];
+ inactive = icon;
+
+ path = [[NSBundle mainBundle] pathForResource:@"icon-active" ofType:@"png"];
+ icon = [[NSImage alloc] initWithContentsOfFile:path];
+ active = icon;
+
+ path = [[NSBundle mainBundle] pathForResource:@"icon-alt" ofType:@"png"];
+ icon = [[NSImage alloc] initWithContentsOfFile:path];
+ [statusItem setAlternateImage:icon];
+ [icon release];
+
+ nonConnectionItemCount = [statusMenu numberOfItems];
+
+ [self repopulateMenu];
+}
+
+- (void)applicationDidFinishLaunching:(NSNotification *)aNotification
+{
+ [self loadConnections];
+ [self initializeMenu];
+}
+
+- (id)init
+{
+ self = [super init];
+ control = [[Control alloc] initWithDelegate:self];
+ connections = [[NSMutableArray alloc] init];
+ editor = [[ConnController alloc] initWithWindowNibName:@"ConnWindow"];
+ password = [[PasswordController alloc] initWithWindowNibName:@"PasswordWindow"];
+ return self;
+}
+
+- (void)dealloc
+{
+ NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
+ [defaults removeObserver:self forKeyPath:@"connections"];
+ [statusItem release];
+ [active release];
+ [inactive release];
+ [connections release];
+ [control release];
+ [editor release];
+ [password release];
+ [super dealloc];
+}
+
+@end
diff --git a/src/frontends/osx/strongSwan/ConnController.h b/src/frontends/osx/strongSwan/ConnController.h
new file mode 100644
index 000000000..21134fe5a
--- /dev/null
+++ b/src/frontends/osx/strongSwan/ConnController.h
@@ -0,0 +1,74 @@
+/*
+ * Copyright (C) 2013 Martin Willi
+ * Copyright (C) 2013 revosec AG
+ *
+ * This program 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 2 of the License, or (at your
+ * option) any later version. See .
+ *
+ * This program 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.
+ */
+
+#import
+
+/**
+ * Controller for the Connection Editor window
+ */
+@interface ConnController : NSWindowController {
+
+ /**
+ * Text field for the connection name
+ */
+ IBOutlet NSTextField *name;
+
+ /**
+ * Authentication method select control
+ */
+ IBOutlet NSPopUpButton *auth;
+
+ /**
+ * Server address of connection
+ */
+ IBOutlet NSTextField *server;
+
+ /**
+ * Username used for client authentication
+ */
+ IBOutlet NSTextField *user;
+
+ /**
+ * Confirmation button to save/create connection
+ */
+ IBOutlet NSButton *ok;
+}
+
+/**
+ * Save the currently edited connection
+ */
+- (IBAction)saveConnEditor:(id)sender;
+
+/**
+ * Cancel editing the current connection
+ */
+- (IBAction)cancelConnEditor:(id)sender;
+
+/**
+ * Open a dialog to create a new connection.
+ *
+ * @return dictionary with connection settings, retained
+ */
+- (NSMutableDictionary*)createConnection;
+
+/**
+ * Open a dialog to edit a connection
+ *
+ * @param conn dictionary with connection settings, gets updated
+ * @return TRUE if connection has been updated, FALSE if aborted
+ */
+- (bool)editConnection:(NSMutableDictionary*)conn;
+
+@end
diff --git a/src/frontends/osx/strongSwan/ConnController.m b/src/frontends/osx/strongSwan/ConnController.m
new file mode 100644
index 000000000..cd7b9f1dc
--- /dev/null
+++ b/src/frontends/osx/strongSwan/ConnController.m
@@ -0,0 +1,102 @@
+/*
+ * Copyright (C) 2013 Martin Willi
+ * Copyright (C) 2013 revosec AG
+ *
+ * This program 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 2 of the License, or (at your
+ * option) any later version. See .
+ *
+ * This program 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.
+ */
+
+#import "ConnController.h"
+
+@interface ConnController ()
+
+@end
+
+@implementation ConnController
+
+- (void)moveWindowToActiveSpace
+{
+ NSInteger behavior, old;
+
+ /* seems that NSWindowCollectionBehaviorMoveToActiveSpace does not work
+ * when a window is opened a second time. Fix that by changing the
+ * behavior forth and back. */
+ old = behavior = [[self window] collectionBehavior];
+ behavior &= ~NSWindowCollectionBehaviorMoveToActiveSpace;
+ behavior |= NSWindowCollectionBehaviorCanJoinAllSpaces;
+
+ [[self window] setCollectionBehavior: behavior];
+ [[self window] setCollectionBehavior: old];
+
+ [NSApp activateIgnoringOtherApps:YES];
+}
+
+- (IBAction)saveConnEditor:(id)sender
+{
+ [NSApp stopModal];
+}
+
+- (IBAction)cancelConnEditor:(id)sender
+{
+ [NSApp abortModal];
+}
+
+- (NSMutableDictionary*)createConnection
+{
+ NSMutableDictionary *conn = nil;
+
+ [[self window] setTitle:@"Add new connection"];
+ [name setStringValue:@""];
+ [server setStringValue:@""];
+ [user setStringValue:@""];
+ [ok setEnabled:FALSE];
+ [self moveWindowToActiveSpace];
+ if ([NSApp runModalForWindow: [self window]] == NSRunStoppedResponse)
+ {
+ conn = [NSMutableDictionary dictionaryWithObjectsAndKeys:
+ [name stringValue], @"name",
+ [server stringValue], @"server",
+ [user stringValue], @"username",
+ nil];
+ }
+ [[self window] orderOut: self];
+ return conn;
+}
+
+- (bool)editConnection:(NSMutableDictionary*)conn
+{
+ bool edited = NO;
+
+ [[self window] setTitle:@"Edit connection"];
+ [name setStringValue:[conn objectForKey:@"name"]];
+ [server setStringValue:[conn objectForKey:@"server"]];
+ [user setStringValue:[conn objectForKey:@"username"]];
+ [ok setEnabled:TRUE];
+ [self moveWindowToActiveSpace];
+ if ([NSApp runModalForWindow: [self window]] == NSRunStoppedResponse)
+ {
+ [conn setObject:[name stringValue] forKey:@"name"];
+ [conn setObject:[server stringValue] forKey:@"server"];
+ [conn setObject:[user stringValue] forKey:@"username"];
+ edited = YES;
+ }
+ [[self window] orderOut: self];
+ return edited;
+}
+
+- (void)controlTextDidChange:(NSNotification *)notification
+{
+ [ok setEnabled:
+ [[name stringValue] length] &&
+ [[server stringValue] length] &&
+ [[user stringValue] length]];
+}
+
+@end
diff --git a/src/frontends/osx/strongSwan/Control.h b/src/frontends/osx/strongSwan/Control.h
new file mode 100644
index 000000000..4bcfb5583
--- /dev/null
+++ b/src/frontends/osx/strongSwan/Control.h
@@ -0,0 +1,95 @@
+/*
+ * Copyright (C) 2013 Martin Willi
+ * Copyright (C) 2013 revosec AG
+ *
+ * This program 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 2 of the License, or (at your
+ * option) any later version. See .
+ *
+ * This program 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.
+ */
+
+#import
+
+/**
+ * State of a connection during connect.
+ */
+typedef enum {
+ /** The connection is currently down */
+ STATE_DOWN,
+ /** The connection is getting established, the daemon is working */
+ STATE_WORKING,
+ /** The connection has been established successfully */
+ STATE_UP,
+} connectionState;
+
+/**
+ * This protocol defines callback functions to invoke during connect.
+ */
+@protocol ControlDelegate
+
+/**
+ * The connection has changed its state
+ *
+ * @param state new connection state
+ * @param conn connection that changed its state
+ */
+- (void)change:(connectionState)state withConnection:(NSDictionary*)conn;
+
+/**
+ * A password is required for authentication
+ *
+ * @param conn connection a password is required for
+ * @return a retained password string
+ */
+- (NSString*)createPasswordWithConnection:(NSDictionary*)conn;
+
+/**
+ * Show an alert message to the user
+ *
+ * @param alert alert message string
+ * @param conn connection an error has occurred
+ */
+- (void)raise:(NSString*)alert withConnection:(NSDictionary*)conn;
+
+/**
+ * Log a line for a specific connection
+ *
+ * @param line log line string
+ * @param conn connection the line is logged for
+ */
+- (void)log:(NSString*)line withConnection:(NSDictionary*)conn;
+@end
+
+/**
+ * Implements connection connect/disconnect operations using a GUI delegate.
+ */
+@interface Control : NSObject
+
+/**
+ * Try to establish a connection
+ *
+ * @param conn connection configuration to initiate
+ */
+- (void)connect:(NSDictionary*)conn;
+
+/**
+ * Disconnect a previously established connection
+ *
+ * @param conn connection configuration to terminate
+ */
+- (void)disconnect:(NSDictionary*)conn;
+
+/**
+ * Initiate the Control class using a delegate for GUI operations
+ *
+ * @param delegate delegate to invoke callbacks on during connect operation
+ * @return class instance
+ */
+- (id)initWithDelegate:(id)delegate;
+
+@end
diff --git a/src/frontends/osx/strongSwan/Control.m b/src/frontends/osx/strongSwan/Control.m
new file mode 100644
index 000000000..6bb0d0fa5
--- /dev/null
+++ b/src/frontends/osx/strongSwan/Control.m
@@ -0,0 +1,258 @@
+/*
+ * Copyright (C) 2013 Martin Willi
+ * Copyright (C) 2013 revosec AG
+ *
+ * This program 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 2 of the License, or (at your
+ * option) any later version. See .
+ *
+ * This program 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.
+ */
+
+#import "Control.h"
+#import "Helper.h"
+
+@implementation Control {
+ /* Provides the XPC main connection to the privileged helper */
+ Helper *helper;
+ /* active connection specific XPC channels, indexed by connection name */
+ NSDictionary *active;
+ /* delegate to invoke callbacks on */
+ id del;
+}
+
+- (NSString*)translateAlert:(const char*)alert
+{
+ if (strcmp(alert, "local-auth") == 0)
+ {
+ return @"Client authentication failed";
+ }
+ if (strcmp(alert, "remote-auth") == 0)
+ {
+ return @"Server authentication failed";
+ }
+ if (strcmp(alert, "dns") == 0)
+ {
+ return @"Resolving server hostname failed";
+ }
+ if (strcmp(alert, "unreachable") == 0)
+ {
+ return @"Server is unreachable";
+ }
+ if (strcmp(alert, "timeout") == 0)
+ {
+ return @"Server did not respond";
+ }
+ if (strcmp(alert, "proposal-mismatch") == 0)
+ {
+ return @"No common cryptographic algorithms found";
+ }
+ if (strcmp(alert, "ts-mismatch") == 0)
+ {
+ return @"No common traffic selectors found";
+ }
+ return NULL;
+}
+
+- (void)changeState:(connectionState)state withChannel:(xpc_connection_t)channel
+ andConn:(NSDictionary*)conn
+{
+ NSString *name;
+
+ name = [conn objectForKey:@"name"];
+ switch (state)
+ {
+ case STATE_WORKING:
+ xpc_dictionary_set_value(active, [name UTF8String], channel);
+ break;
+ case STATE_DOWN:
+ xpc_dictionary_set_value(active, [name UTF8String], NULL);
+ break;
+ case STATE_UP:
+ break;
+ }
+ dispatch_sync(dispatch_get_main_queue(), ^{
+ [del change:state withConnection:conn];
+ });
+}
+
+- (void)handleEvent:(xpc_object_t)request withChannel:(xpc_connection_t)channel
+ andConn:(NSDictionary*)conn
+{
+ xpc_connection_t client;
+ xpc_object_t reply;
+ const char *type, *rpc, *event;
+ client = xpc_dictionary_get_remote_connection(request);
+ type = xpc_dictionary_get_string(request, "type");
+ if (type)
+ {
+ if (strcmp(type, "rpc") == 0)
+ {
+ reply = xpc_dictionary_create_reply(request);
+ rpc = xpc_dictionary_get_string(request, "rpc");
+ if (rpc)
+ {
+ if (strcmp(rpc, "get_password") == 0)
+ {
+ __block NSString *password;
+
+ dispatch_sync(dispatch_get_main_queue(), ^{
+ password = [del createPasswordWithConnection:conn];
+ });
+ xpc_dictionary_set_string(reply, "password",
+ [password UTF8String]);
+ [password release];
+ }
+ }
+ xpc_connection_send_message(client, reply);
+ xpc_release(reply);
+ }
+ if (strcmp(type, "event") == 0)
+ {
+ event = xpc_dictionary_get_string(request, "event");
+ if (event)
+ {
+ if (strcmp(event, "log") == 0)
+ {
+ NSString *line;
+
+ line = [[NSString alloc] initWithUTF8String:
+ xpc_dictionary_get_string(request, "message")];
+ dispatch_async(dispatch_get_main_queue(), ^{
+ [del log:line withConnection:conn];
+ });
+ [line release];
+ }
+ if (strcmp(event, "alert") == 0)
+ {
+ NSString *msg;
+ const char *str;
+
+ str = xpc_dictionary_get_string(request, "alert");
+ if (str)
+ {
+ msg = [self translateAlert:str];
+ if (msg)
+ {
+ dispatch_async(dispatch_get_main_queue(), ^{
+ [del raise:msg withConnection:conn];
+ });
+ }
+ }
+ }
+ if (strcmp(event, "connecting") == 0)
+ {
+ [self changeState:STATE_WORKING withChannel:channel andConn:conn];
+ }
+ if (strcmp(event, "up") == 0)
+ {
+ /* IKE_SA up */
+ }
+ if (strcmp(event, "down") == 0)
+ {
+ [self changeState:STATE_DOWN withChannel:channel andConn:conn];
+ }
+ if (strcmp(event, "child_up") == 0)
+ {
+ [self changeState:STATE_UP withChannel:channel andConn:conn];
+ }
+ if (strcmp(event, "child_down") == 0)
+ {
+ [self changeState:STATE_DOWN withChannel:channel andConn:conn];
+ }
+ }
+ }
+ }
+}
+
+- (void)connect:(NSDictionary*)conn
+{
+ xpc_object_t request;
+ xpc_connection_t service, daemon;
+ NSString *name, *server, *username;
+
+ name = [conn objectForKey:@"name"];
+ server = [conn objectForKey:@"server"];
+ username = [conn objectForKey:@"username"];
+
+ daemon = [helper getConnection];
+ if (!daemon)
+ {
+ [del raise:[helper getError] withConnection:conn];
+ }
+
+ request = xpc_dictionary_create(NULL, NULL, 0);
+ xpc_dictionary_set_string(request, "type", "rpc");
+ xpc_dictionary_set_string(request, "rpc", "start_connection");
+ xpc_dictionary_set_string(request, "name", [name UTF8String]);
+ xpc_dictionary_set_string(request, "host", [server UTF8String]);
+ xpc_dictionary_set_string(request, "id", [username UTF8String]);
+
+ service = xpc_connection_create(NULL, NULL);
+ xpc_connection_set_event_handler(service, ^(xpc_object_t channel) {
+
+ xpc_connection_set_event_handler(channel, ^(xpc_object_t event) {
+
+ if (event == XPC_ERROR_CONNECTION_INTERRUPTED ||
+ event == XPC_ERROR_CONNECTION_INVALID)
+ {
+ xpc_dictionary_set_value(active, [name UTF8String], NULL);
+ dispatch_sync(dispatch_get_main_queue(), ^{
+ [del change:STATE_DOWN withConnection:conn];
+ });
+ }
+ else
+ {
+ [self handleEvent:event withChannel:channel andConn:conn];
+ }
+ });
+ xpc_connection_resume(channel);
+ });
+
+ xpc_connection_resume(service);
+ xpc_dictionary_set_connection(request, "channel", xpc_retain(service));
+ xpc_connection_send_message_with_reply(daemon, request,
+ dispatch_get_main_queue(),
+ ^(xpc_object_t reply) {});
+ xpc_release(request);
+}
+
+- (void)disconnect:(NSDictionary*)conn
+{
+ xpc_connection_t tunnel;
+ xpc_object_t request;
+
+ tunnel = xpc_dictionary_get_value(active,
+ [[conn objectForKey:@"name"] UTF8String]);
+ if (tunnel)
+ {
+ request = xpc_dictionary_create(NULL, NULL, 0);
+ xpc_dictionary_set_string(request, "type", "rpc");
+ xpc_dictionary_set_string(request, "rpc", "stop_connection");
+ xpc_connection_send_message_with_reply(tunnel, request,
+ dispatch_get_main_queue(),
+ ^(xpc_object_t reply) {});
+ xpc_release(request);
+ }
+}
+
+- (void)dealloc
+{
+ xpc_release(active);
+ [super dealloc];
+}
+
+- (id)initWithDelegate:(id)delegate;
+{
+ self = [super init];
+ helper = [[Helper alloc] init];
+ active = xpc_dictionary_create(NULL, NULL, 0);
+ del = delegate;
+ return self;
+}
+
+@end
diff --git a/src/frontends/osx/strongSwan/Helper.h b/src/frontends/osx/strongSwan/Helper.h
new file mode 100644
index 000000000..0fa7da8bd
--- /dev/null
+++ b/src/frontends/osx/strongSwan/Helper.h
@@ -0,0 +1,41 @@
+/*
+ * Copyright (C) 2013 Martin Willi
+ * Copyright (C) 2013 revosec AG
+ *
+ * This program 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 2 of the License, or (at your
+ * option) any later version. See .
+ *
+ * This program 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.
+ */
+
+#import
+
+/**
+ * Privileged Helper abstraction.
+ *
+ * Manages the installation of the privileged helper charon-xpc binary
+ * using authorization, SMJobBless() installation using XPC and also
+ * checks the installed helper version.
+ */
+@interface Helper : NSObject
+
+/**
+ * Get the XPC connection singleton, installing helper if requried
+ *
+ * @return XPC service connection, as a singleton
+ */
+- (xpc_connection_t)getConnection;
+
+/**
+ * Return an errror string if if getConnection fails
+ *
+ * @return error string, unretained
+ */
+- (NSString*)getError;
+
+@end
\ No newline at end of file
diff --git a/src/frontends/osx/strongSwan/Helper.m b/src/frontends/osx/strongSwan/Helper.m
new file mode 100644
index 000000000..df4b4c248
--- /dev/null
+++ b/src/frontends/osx/strongSwan/Helper.m
@@ -0,0 +1,223 @@
+/*
+ * Copyright (C) 2013 Martin Willi
+ * Copyright (C) 2013 revosec AG
+ *
+ * This program 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 2 of the License, or (at your
+ * option) any later version. See .
+ *
+ * This program 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.
+ */
+
+#import "Helper.h"
+
+#include
+#include
+
+/* to check strongSwan version */
+#include "../../../../config.h"
+
+@implementation Helper {
+ /* XPC connection to the helper */
+ xpc_connection_t helper;
+ /* authorization instance, if authorized */
+ AuthorizationRef auth;
+ /* string of last error occurred */
+ NSString* errmsg;
+}
+
+- (void)setError:(NSString*)error
+{
+ if (errmsg)
+ {
+ [errmsg release];
+ }
+ errmsg = error;
+}
+
+- (bool)authorize
+{
+ AuthorizationItem item = { kSMRightBlessPrivilegedHelper, 0, NULL, 0 };
+ AuthorizationRights rights = { 1, &item };
+ OSStatus status;
+
+ if (auth)
+ {
+ return TRUE;
+ }
+ status = AuthorizationCreate(&rights, kAuthorizationEmptyEnvironment,
+ kAuthorizationFlagDefaults |
+ kAuthorizationFlagInteractionAllowed |
+ kAuthorizationFlagExtendRights, &auth);
+ if (status == errAuthorizationSuccess)
+ {
+ return TRUE;
+ }
+ if (errmsg)
+ {
+ [errmsg release];
+ }
+ [self setError:[NSString stringWithFormat:@"Authorization failed: %@",
+ SecCopyErrorMessageString(status, NULL)]];
+ return FALSE;
+}
+
+- (bool)manage:(CFStringRef)label bless:(bool)bless
+{
+ bool done;
+ CFErrorRef error;
+
+ if (![self authorize])
+ {
+ return FALSE;
+ }
+ if (bless)
+ {
+ done = SMJobBless(kSMDomainSystemLaunchd, label, auth, &error);
+ }
+ else
+ {
+ done = SMJobRemove(kSMDomainSystemLaunchd, label, auth, TRUE, &error);
+ }
+ if (!done)
+ {
+ [self setError:
+ [NSString stringWithFormat:@"Installing privileged helper failed: %@",
+ CFErrorCopyDescription(error)]];
+ CFRelease(error);
+ }
+ return done;
+}
+
+- (bool)make:(CFStringRef)label
+{
+ char str[128];
+
+ if (!CFStringGetCString(label, str, sizeof(str), kCFStringEncodingUTF8))
+ {
+ [self setError:@"converting XPC service name failed"];
+ return FALSE;
+ }
+ helper = xpc_connection_create_mach_service(str, NULL,
+ XPC_CONNECTION_MACH_SERVICE_PRIVILEGED);
+ if (!helper)
+ {
+ [self setError:@"creating XPC mach service failed"];
+ return FALSE;
+ }
+
+ xpc_connection_set_event_handler(helper, ^(xpc_object_t event) {
+ if (xpc_get_type(event) == XPC_TYPE_ERROR)
+ {
+ if (event == XPC_ERROR_CONNECTION_INTERRUPTED ||
+ event == XPC_ERROR_CONNECTION_INVALID)
+ {
+ if (helper)
+ {
+ xpc_connection_cancel(helper);
+ helper = NULL;
+ }
+ }
+ }
+ });
+ xpc_connection_resume(helper);
+
+ return TRUE;
+}
+
+- (bool)checkVersion
+{
+ xpc_object_t request, response;
+ bool match = FALSE;
+
+ request = xpc_dictionary_create(NULL, NULL, 0);
+ xpc_dictionary_set_string(request, "type", "rpc");
+ xpc_dictionary_set_string(request, "rpc", "get_version");
+
+ response = xpc_connection_send_message_with_reply_sync(helper, request);
+ xpc_release(request);
+ if (xpc_get_type(response) == XPC_TYPE_DICTIONARY)
+ {
+ match = strcmp(xpc_dictionary_get_string(response, "version"),
+ PACKAGE_VERSION) == 0;
+ }
+ xpc_release(response);
+ return match;
+}
+
+- (bool)makeAndCheck:(CFStringRef)label
+{
+ if (![self make:label])
+ {
+ return FALSE;
+ }
+ if ([self checkVersion])
+ {
+ return TRUE;
+ }
+ xpc_connection_cancel(helper);
+ helper = NULL;
+ /* version outdated, uninstall old helper */
+ [self manage:label bless:FALSE];
+ return FALSE;
+}
+
+- (bool)blessAndMake:(CFStringRef)label
+{
+#ifdef DEBUG
+ /* always update helper when debugging */
+ [self manage:label bless:FALSE];
+ [self manage:label bless:TRUE];
+#endif
+
+ if (![self makeAndCheck:label])
+ {
+ if ([self manage:label bless:TRUE])
+ {
+ [self makeAndCheck:label];
+ }
+ }
+ return helper;
+}
+
+- (xpc_connection_t)getConnection
+{
+ if (!helper)
+ {
+ [self blessAndMake:CFSTR("org.strongswan.charon-xpc")];
+ }
+ return helper;
+}
+
+- (NSString*)getError
+{
+ return errmsg;
+}
+
+- (id)init
+{
+ self = [super init];
+ return self;
+}
+
+- (void)dealloc
+{
+ if (helper)
+ {
+ xpc_connection_cancel(helper);
+ }
+ if (auth)
+ {
+ AuthorizationFree(auth, kAuthorizationFlagDefaults);
+ }
+ if (errmsg)
+ {
+ [errmsg release];
+ }
+ [super dealloc];
+}
+@end
diff --git a/src/frontends/osx/strongSwan/LogController.h b/src/frontends/osx/strongSwan/LogController.h
new file mode 100644
index 000000000..239dd5b05
--- /dev/null
+++ b/src/frontends/osx/strongSwan/LogController.h
@@ -0,0 +1,45 @@
+/*
+ * Copyright (C) 2013 Martin Willi
+ * Copyright (C) 2013 revosec AG
+ *
+ * This program 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 2 of the License, or (at your
+ * option) any later version. See .
+ *
+ * This program 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.
+ */
+
+#import
+
+/**
+ * Controller for a connection specific log Window
+ */
+@interface LogController : NSWindowController {
+ /**
+ * Text field for the log entries
+ */
+ IBOutlet NSTextView *textView;
+}
+
+/**
+ * Show the log window on the active Desktop
+ */
+- (void)show;
+
+/**
+ * Append a new log line to the log
+ *
+ * @param line log line to append
+ */
+- (void)appendLine:(NSString*)line;
+
+/**
+ * Clear the log window
+ */
+- (void)clear;
+
+@end
diff --git a/src/frontends/osx/strongSwan/LogController.m b/src/frontends/osx/strongSwan/LogController.m
new file mode 100644
index 000000000..56be8c893
--- /dev/null
+++ b/src/frontends/osx/strongSwan/LogController.m
@@ -0,0 +1,51 @@
+/*
+ * Copyright (C) 2013 Martin Willi
+ * Copyright (C) 2013 revosec AG
+ *
+ * This program 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 2 of the License, or (at your
+ * option) any later version. See .
+ *
+ * This program 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.
+ */
+
+#import "LogController.h"
+
+@interface LogController ()
+
+@end
+
+@implementation LogController
+
+- (void)appendLine:(NSString*)line
+{
+ NSAttributedString* attr;
+
+ attr = [[NSAttributedString alloc] initWithString:line];
+ [[textView textStorage] appendAttributedString:attr];
+ [attr release];
+
+ attr = [[NSAttributedString alloc] initWithString:@"\n"];
+ [[textView textStorage] appendAttributedString:attr];
+ [attr release];
+
+ [textView scrollRangeToVisible:NSMakeRange([[textView string] length], 0)];
+}
+
+- (void)clear
+{
+ [textView setString:@""];
+}
+
+- (void)show
+{
+ [self showWindow:self];
+ [[self window] makeKeyAndOrderFront:self];
+ [[self window] orderFrontRegardless];
+}
+
+@end
diff --git a/src/frontends/osx/strongSwan/PasswordController.h b/src/frontends/osx/strongSwan/PasswordController.h
new file mode 100644
index 000000000..eeaed0d35
--- /dev/null
+++ b/src/frontends/osx/strongSwan/PasswordController.h
@@ -0,0 +1,41 @@
+/*
+ * Copyright (C) 2013 Martin Willi
+ * Copyright (C) 2013 revosec AG
+ *
+ * This program 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 2 of the License, or (at your
+ * option) any later version. See .
+ *
+ * This program 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.
+ */
+
+#import
+
+/**
+ * Controller for the EAP password dialog.
+ */
+@interface PasswordController : NSWindowController {
+
+ /**
+ * Text field the user enters the password
+ */
+ IBOutlet NSTextField *password;
+}
+
+/**
+ * Action invoked when the user confirms the password entry
+ */
+- (IBAction)confirm: (id)sender;
+
+/**
+ * Query the user for a password by invoking the modal dialog.
+ *
+ * @return password string, retained
+ */
+- (NSString*)query;
+
+@end
diff --git a/src/frontends/osx/strongSwan/PasswordController.m b/src/frontends/osx/strongSwan/PasswordController.m
new file mode 100644
index 000000000..2e0ce556a
--- /dev/null
+++ b/src/frontends/osx/strongSwan/PasswordController.m
@@ -0,0 +1,56 @@
+/*
+ * Copyright (C) 2013 Martin Willi
+ * Copyright (C) 2013 revosec AG
+ *
+ * This program 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 2 of the License, or (at your
+ * option) any later version. See .
+ *
+ * This program 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.
+ */
+
+#import "PasswordController.h"
+
+@interface PasswordController ()
+
+@end
+
+@implementation PasswordController
+
+- (void)moveWindowToActiveSpace
+{
+ NSInteger behavior, old;
+
+ /* seems that NSWindowCollectionBehaviorMoveToActiveSpace does not work
+ * when a window is opened a second time. Fix that by changing the
+ * behavior forth and back. */
+ old = behavior = [[self window] collectionBehavior];
+ behavior &= ~NSWindowCollectionBehaviorMoveToActiveSpace;
+ behavior |= NSWindowCollectionBehaviorCanJoinAllSpaces;
+
+ [[self window] setCollectionBehavior: behavior];
+ [[self window] setCollectionBehavior: old];
+
+ [NSApp activateIgnoringOtherApps:YES];
+}
+
+- (IBAction)confirm:(id)sender
+{
+ [NSApp stopModal];
+}
+
+- (NSString *)query
+{
+ [password setStringValue:@""];
+ [self moveWindowToActiveSpace];
+ [NSApp runModalForWindow: [self window]];
+ [[self window] orderOut: self];
+
+ return [[password stringValue] retain];
+}
+
+@end
diff --git a/src/frontends/osx/strongSwan/en.lproj/ConnWindow.xib b/src/frontends/osx/strongSwan/en.lproj/ConnWindow.xib
new file mode 100644
index 000000000..37c74b4aa
--- /dev/null
+++ b/src/frontends/osx/strongSwan/en.lproj/ConnWindow.xib
@@ -0,0 +1,1469 @@
+
+
+
+ 1080
+ 12D78
+ 2840
+ 1187.37
+ 626.00
+
+
+ IBNSLayoutConstraint
+ NSButton
+ NSButtonCell
+ NSCustomObject
+ NSMenu
+ NSMenuItem
+ NSPopUpButton
+ NSPopUpButtonCell
+ NSTextField
+ NSTextFieldCell
+ NSView
+ NSWindowTemplate
+
+
+ com.apple.InterfaceBuilder.CocoaPlugin
+
+
+
+
+
+
+
+
+
+
+
+
+ auth
+
+
+
+ 58
+
+
+
+ name
+
+
+
+ 60
+
+
+
+ ok
+
+
+
+ 61
+
+
+
+ server
+
+
+
+ 62
+
+
+
+ user
+
+
+
+ 63
+
+
+
+ window
+
+
+
+ 64
+
+
+
+ saveConnEditor:
+
+
+
+ 65
+
+
+
+ cancelConnEditor:
+
+
+
+ 66
+
+
+
+ delegate
+
+
+
+ 69
+
+
+
+ delegate
+
+
+
+ 68
+
+
+
+ delegate
+
+
+
+ 67
+
+
+
+
+
+ 0
+
+
+
+
+
+ -2
+
+
+ File's Owner
+
+
+ -1
+
+
+ First Responder
+
+
+ -3
+
+
+ Application
+
+
+ 5
+
+
+
+
+
+ connEditor
+
+
+ 6
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 3
+ 0
+
+ 3
+ 1
+
+ 20
+
+ 1000
+
+ 8
+ 29
+ 3
+
+
+
+ 5
+ 0
+
+ 5
+ 1
+
+ 23
+
+ 1000
+
+ 3
+ 9
+ 3
+
+
+
+ 6
+ 0
+
+ 6
+ 1
+
+ 0.0
+
+ 1000
+
+ 6
+ 24
+ 2
+
+
+
+ 5
+ 0
+
+ 5
+ 1
+
+ 0.0
+
+ 1000
+
+ 6
+ 24
+ 2
+
+
+
+ 10
+ 0
+
+ 10
+ 1
+
+ 0.0
+
+ 1000
+
+ 6
+ 24
+ 2
+
+
+
+ 6
+ 0
+
+ 6
+ 1
+
+ 0.0
+
+ 1000
+
+ 6
+ 24
+ 2
+
+
+
+ 5
+ 0
+
+ 5
+ 1
+
+ 0.0
+
+ 1000
+
+ 6
+ 24
+ 2
+
+
+
+ 6
+ 0
+
+ 6
+ 1
+
+ 0.0
+
+ 1000
+
+ 6
+ 24
+ 2
+
+
+
+ 5
+ 0
+
+ 5
+ 1
+
+ 0.0
+
+ 1000
+
+ 6
+ 24
+ 2
+
+
+
+ 10
+ 0
+
+ 10
+ 1
+
+ 0.0
+
+ 1000
+
+ 6
+ 24
+ 2
+
+
+
+ 6
+ 0
+
+ 6
+ 1
+
+ 20
+
+ 1000
+
+ 8
+ 29
+ 3
+
+
+
+ 5
+ 0
+
+ 5
+ 1
+
+ 0.0
+
+ 1000
+
+ 6
+ 24
+ 2
+
+
+
+ 3
+ 0
+
+ 3
+ 1
+
+ 49
+
+ 1000
+
+ 3
+ 9
+ 3
+
+
+
+ 11
+ 0
+
+ 11
+ 1
+
+ 0.0
+
+ 1000
+
+ 6
+ 24
+ 2
+
+
+
+ 6
+ 0
+
+ 6
+ 1
+
+ 20
+
+ 1000
+
+ 8
+ 29
+ 3
+
+
+
+ 5
+ 0
+
+ 5
+ 1
+
+ 0.0
+
+ 1000
+
+ 6
+ 24
+ 2
+
+
+
+ 3
+ 0
+
+ 3
+ 1
+
+ 78
+
+ 1000
+
+ 3
+ 9
+ 3
+
+
+
+ 6
+ 0
+
+ 6
+ 1
+
+ 20
+
+ 1000
+
+ 8
+ 29
+ 3
+
+
+
+ 10
+ 0
+
+ 10
+ 1
+
+ 0.0
+
+ 1000
+
+ 6
+ 24
+ 2
+
+
+
+ 3
+ 0
+
+ 3
+ 1
+
+ 108
+
+ 1000
+
+ 3
+ 9
+ 3
+
+
+
+ 6
+ 0
+
+ 6
+ 1
+
+ 20
+
+ 1000
+
+ 8
+ 29
+ 3
+
+
+
+ 5
+ 0
+
+ 5
+ 1
+
+ 0.0
+
+ 1000
+
+ 6
+ 24
+ 2
+
+
+
+ 5
+ 0
+
+ 5
+ 1
+
+ 0.0
+
+ 1000
+
+ 6
+ 24
+ 2
+
+
+
+ 4
+ 0
+
+ 4
+ 1
+
+ 20
+
+ 1000
+
+ 8
+ 29
+ 3
+
+
+
+ 6
+ 0
+
+ 6
+ 1
+
+ 20
+
+ 1000
+
+ 8
+ 29
+ 3
+
+
+
+ 4
+ 0
+
+ 4
+ 1
+
+ 20
+
+ 1000
+
+ 8
+ 29
+ 3
+
+
+
+ 5
+ 0
+
+ 6
+ 1
+
+ 12
+
+ 1000
+
+ 6
+ 24
+ 3
+
+
+
+
+
+ 7
+
+
+
+
+ 7
+ 0
+
+ 0
+ 1
+
+ 70
+
+ 1000
+
+ 3
+ 9
+ 1
+
+
+
+
+ okButton
+
+
+ 8
+
+
+
+
+
+ cancelButton
+
+
+ 9
+
+
+
+
+
+ typePopup
+
+
+ 10
+
+
+
+
+
+ userText
+
+
+ 11
+
+
+
+
+
+ userLabel
+
+
+ 12
+
+
+
+
+
+ serverText
+
+
+ 13
+
+
+
+
+
+ serverLabel
+
+
+ 14
+
+
+
+
+
+ typeLabel
+
+
+ 15
+
+
+
+
+
+ nameText
+
+
+ 16
+
+
+
+
+ 7
+ 0
+
+ 0
+ 1
+
+ 156
+
+ 1000
+
+ 3
+ 9
+ 1
+
+
+
+
+ nameLabel
+
+
+ 17
+
+
+
+
+ 18
+
+
+
+
+ 19
+
+
+
+
+ 20
+
+
+
+
+ 21
+
+
+
+
+ 22
+
+
+
+
+ 23
+
+
+
+
+ 24
+
+
+
+
+ 25
+
+
+
+
+ 26
+
+
+
+
+ 27
+
+
+
+
+ 28
+
+
+
+
+ 29
+
+
+
+
+ 30
+
+
+
+
+ 31
+
+
+
+
+ 32
+
+
+
+
+ 33
+
+
+
+
+ 34
+
+
+
+
+ 35
+
+
+
+
+ 36
+
+
+
+
+ 37
+
+
+
+
+ 38
+
+
+
+
+ 39
+
+
+
+
+ 40
+
+
+
+
+ 41
+
+
+
+
+ 42
+
+
+
+
+ 43
+
+
+
+
+ 44
+
+
+
+
+ 45
+
+
+
+
+ 46
+
+
+
+
+ 47
+
+
+
+
+ 48
+
+
+
+
+ 49
+
+
+
+
+ 50
+
+
+
+
+ 51
+
+
+
+
+ 52
+
+
+
+
+
+
+
+ 53
+
+
+
+
+
+
+
+ 54
+
+
+
+
+ 55
+
+
+
+
+ 56
+
+
+
+
+ 57
+
+
+
+
+
+
+ com.apple.InterfaceBuilder.CocoaPlugin
+ com.apple.InterfaceBuilder.CocoaPlugin
+ com.apple.InterfaceBuilder.CocoaPlugin
+
+ com.apple.InterfaceBuilder.CocoaPlugin
+
+ com.apple.InterfaceBuilder.CocoaPlugin
+
+
+
+
+
+
+ com.apple.InterfaceBuilder.CocoaPlugin
+
+ com.apple.InterfaceBuilder.CocoaPlugin
+
+
+
+
+
+
+ com.apple.InterfaceBuilder.CocoaPlugin
+
+
+
+
+
+
+ com.apple.InterfaceBuilder.CocoaPlugin
+
+
+
+
+ com.apple.InterfaceBuilder.CocoaPlugin
+
+
+
+
+
+ com.apple.InterfaceBuilder.CocoaPlugin
+ com.apple.InterfaceBuilder.CocoaPlugin
+ com.apple.InterfaceBuilder.CocoaPlugin
+ com.apple.InterfaceBuilder.CocoaPlugin
+ com.apple.InterfaceBuilder.CocoaPlugin
+ com.apple.InterfaceBuilder.CocoaPlugin
+ com.apple.InterfaceBuilder.CocoaPlugin
+ com.apple.InterfaceBuilder.CocoaPlugin
+ com.apple.InterfaceBuilder.CocoaPlugin
+ com.apple.InterfaceBuilder.CocoaPlugin
+ com.apple.InterfaceBuilder.CocoaPlugin
+ com.apple.InterfaceBuilder.CocoaPlugin
+ com.apple.InterfaceBuilder.CocoaPlugin
+ com.apple.InterfaceBuilder.CocoaPlugin
+ com.apple.InterfaceBuilder.CocoaPlugin
+ com.apple.InterfaceBuilder.CocoaPlugin
+ com.apple.InterfaceBuilder.CocoaPlugin
+ com.apple.InterfaceBuilder.CocoaPlugin
+ com.apple.InterfaceBuilder.CocoaPlugin
+ com.apple.InterfaceBuilder.CocoaPlugin
+ com.apple.InterfaceBuilder.CocoaPlugin
+ com.apple.InterfaceBuilder.CocoaPlugin
+ com.apple.InterfaceBuilder.CocoaPlugin
+ com.apple.InterfaceBuilder.CocoaPlugin
+ com.apple.InterfaceBuilder.CocoaPlugin
+ com.apple.InterfaceBuilder.CocoaPlugin
+ com.apple.InterfaceBuilder.CocoaPlugin
+ com.apple.InterfaceBuilder.CocoaPlugin
+ com.apple.InterfaceBuilder.CocoaPlugin
+ com.apple.InterfaceBuilder.CocoaPlugin
+ com.apple.InterfaceBuilder.CocoaPlugin
+ com.apple.InterfaceBuilder.CocoaPlugin
+ com.apple.InterfaceBuilder.CocoaPlugin
+ com.apple.InterfaceBuilder.CocoaPlugin
+
+ com.apple.InterfaceBuilder.CocoaPlugin
+ com.apple.InterfaceBuilder.CocoaPlugin
+ com.apple.InterfaceBuilder.CocoaPlugin
+ com.apple.InterfaceBuilder.CocoaPlugin
+ com.apple.InterfaceBuilder.CocoaPlugin
+ com.apple.InterfaceBuilder.CocoaPlugin
+ com.apple.InterfaceBuilder.CocoaPlugin
+ com.apple.InterfaceBuilder.CocoaPlugin
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ com.apple.InterfaceBuilder.CocoaPlugin
+
+
+
+
+ com.apple.InterfaceBuilder.CocoaPlugin
+
+ com.apple.InterfaceBuilder.CocoaPlugin
+
+ com.apple.InterfaceBuilder.CocoaPlugin
+
+
+
+
+
+ 69
+
+
+
+
+ ConnController
+ NSWindowController
+
+ id
+ id
+
+
+
+ cancelConnEditor:
+ id
+
+
+ saveConnEditor:
+ id
+
+
+
+ NSPopUpButton
+ NSTextField
+ NSButton
+ NSTextField
+ NSTextField
+
+
+
+ auth
+ NSPopUpButton
+
+
+ name
+ NSTextField
+
+
+ ok
+ NSButton
+
+
+ server
+ NSTextField
+
+
+ user
+ NSTextField
+
+
+
+ IBProjectSource
+ ./Classes/ConnController.h
+
+
+
+ NSLayoutConstraint
+ NSObject
+
+ IBProjectSource
+ ./Classes/NSLayoutConstraint.h
+
+
+
+
+ 0
+ IBCocoaFramework
+ YES
+ 3
+
+ {11, 11}
+ {10, 3}
+
+ YES
+
+
diff --git a/src/frontends/osx/strongSwan/en.lproj/Credits.rtf b/src/frontends/osx/strongSwan/en.lproj/Credits.rtf
new file mode 100644
index 000000000..5684d78b9
--- /dev/null
+++ b/src/frontends/osx/strongSwan/en.lproj/Credits.rtf
@@ -0,0 +1,32 @@
+{\rtf1\ansi\ansicpg1252\cocoartf1265
+{\fonttbl\f0\fswiss\fcharset0 Helvetica;}
+{\colortbl;\red255\green255\blue255;\red0\green0\blue255;}
+\paperw11900\paperh16840\viewkind1\viewscale96
+\deftab720
+\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\pardeftab720\ri0
+
+\f0\fs24 \cf0 Based on the strongSwan Open Source project:\
+\
+ {\field{\*\fldinst{HYPERLINK "http://www.strongswan.org"}}{\fldrslt \cf2 \ul \ulc2 http://www.strongswan.org}}\
+\
+The App and the
+\i charon-xpc
+\i0 privileged helper tool are licensed under the {\field{\*\fldinst{HYPERLINK "http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt"}}{\fldrslt \cf2 \ul \ulc2 General Public License Version 2}}. The strongSwan source code is available for download at:\
+\
+ {\field{\*\fldinst{HYPERLINK "http://download.strongswan.org/"}}{\fldrslt \cf2 \ul \ulc2 http://download.strongswan.org/}}\
+\
+The App and the
+\i charon-xpc
+\i0 helper sources are not part of the main strongSwan distribution, but available separately under:\
+\
+ {\field{\*\fldinst{HYPERLINK "http://download.strongswan.org/osx/"}}{\fldrslt \cf2 \ul \ulc2 http://download.strongswan.org/osx/}}\
+\
+The
+\i osx-sources
+\i0 tarball should get extracted into the strongSwan sources root directory. The
+\i README.md
+\i0 in
+\i src/frontends/osx
+\i0 has more information about building
+\i charon-xpc
+\i0 and the App.}
\ No newline at end of file
diff --git a/src/frontends/osx/strongSwan/en.lproj/InfoPlist.strings b/src/frontends/osx/strongSwan/en.lproj/InfoPlist.strings
new file mode 100644
index 000000000..b92732c79
--- /dev/null
+++ b/src/frontends/osx/strongSwan/en.lproj/InfoPlist.strings
@@ -0,0 +1 @@
+/* Localized versions of Info.plist keys */
diff --git a/src/frontends/osx/strongSwan/en.lproj/LogWindow.xib b/src/frontends/osx/strongSwan/en.lproj/LogWindow.xib
new file mode 100644
index 000000000..4c326185d
--- /dev/null
+++ b/src/frontends/osx/strongSwan/en.lproj/LogWindow.xib
@@ -0,0 +1,587 @@
+
+
+
+ 1080
+ 12D78
+ 2840
+ 1187.37
+ 626.00
+
+ com.apple.InterfaceBuilder.CocoaPlugin
+ 2840
+
+
+ IBNSLayoutConstraint
+ NSCustomObject
+ NSScrollView
+ NSScroller
+ NSTextView
+ NSView
+ NSWindowTemplate
+
+
+ com.apple.InterfaceBuilder.CocoaPlugin
+
+
+ PluginDependencyRecalculationVersion
+
+
+
+
+ LogController
+
+
+ FirstResponder
+
+
+ NSApplication
+
+
+ 15
+ 2
+ {{121, 123}, {547, 312}}
+ 611845120
+ Window
+ NSWindow
+
+
+
+
+ 256
+
+
+
+ 256
+
+
+
+ 2304
+
+
+
+ 2322
+ {525, 286}
+
+
+
+ _NS:13
+
+
+
+
+
+
+
+
+
+
+
+ 166
+
+
+
+ 525
+ 1
+
+
+ 10593
+ 0
+
+
+ 3
+ MQA
+
+
+
+ 6
+ System
+ selectedTextBackgroundColor
+
+ 3
+ MC42NjY2NjY2NjY3AA
+
+
+
+ 6
+ System
+ selectedTextColor
+
+ 3
+ MAA
+
+
+
+
+
+
+ 1
+ MCAwIDEAA
+
+
+ {8, -8}
+ 13
+
+
+
+
+ 4
+
+ 1
+
+
+ 1
+
+ 6
+ {548, 10000000}
+
+
+
+ {{1, 1}, {525, 286}}
+
+
+
+ _NS:11
+
+
+
+ {4, 5}
+
+ 12582912
+
+
+
+
+
+ TU0AKgAAEAj///8A////qwAAAP8AAAD/AwMD/BYWFtIFBQVuAAAABv///wD///8E6+vrTGhoaLYtLS3p
+BAQE/QAAAP8AAAD/////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A
+////AP///wD///8A////AP///wD///+rAAAA/wAAAP8AAAD/AAAA/wAAAP8EBATSX19fK9HR0ZciIiLv
+AAAA/wAAAP8AAAD/AAAA/wAAAP////8A////AP///wD///8A////AP///wD///8A////AP///wD///8A
+////AP///wD///8A////AP///wD///8A////AP///wD///8A////CsPDw0CRkZG1FxcX9AAAAP8bGxvr
+ICAg8AAAAP8ICAjlFRUVVQAAAA////8A////AP///wD///8A////AP///wD///8A////AP///wD///8A
+////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wrm5uab
+FxcX9AAAAP8AAAD/AQEB3wAAAA////8A////AP///wD///8A////AP///wD///8A////AP///wD///8A
+////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A
+////AP///zaXl5fGAAAA/wAAAP8AAABR////AP///wD///8A////AP///wD///8A////AP///wD///8A
+////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A
+////AP///wD///8A////CO7u7q8AAAD/AAAA/wAAAAz///8A////AP///wD///8A////AP///wD///8A
+////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A
+////AP///wD///8A////AP///wD///8A////qwAAAP8AAAD/////AP///wD///8A////AP///wD///8A
+////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A
+////AP///wD///8A////AP///wD///8A////AP///wD///+rAAAA/wAAAP////8A////AP///wD///8A
+////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A
+////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///6sAAAD/AAAA/////wD///8A
+////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A
+////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////qwAAAP8AAAD/
+////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A
+////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///+r
+AAAA/wAAAP////8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A
+////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A
+////AP///6sAAAD/AAAA/////wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A
+////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A
+////AP///wD///8A////qwAAAP8AAAD/////AP///wD///8A////AP///wD///8A////AP///wD///8A
+////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A
+////AP///wD///8A////AP///wD///+rAAAA/wAAAP////8A////AP///wD///8A////AP///wD///8A
+////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A
+////AP///wD///8A////AP///wD///8A////AP///6sAAAD/AAAA/////wD///8A////AP///wD///8A
+////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A
+////AP///wD///8A////AP///wD///8A////AP///wD///8A////qwAAAP8AAAD/////AP///wD///8A
+////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A
+////AP///wD///8A////AP///wD///8A////AP///wD///8A////qwAAAP8AAAD/AAAA/wAAAP8AAAD/
+AAAA/////wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A
+////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///+rAAAA/wAAAP8AAAD/
+AAAA/wAAAP8AAAD/////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A
+////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A
+////qwAAAP8AAAD/////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A
+////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A
+////AP///wD///+rAAAA/wAAAP////8A////AP///wD///8A////AP///wD///8A////AP///wD///8A
+////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A
+////AP///wD///8A////AP///6sAAAD/AAAA/////wD///8A////AP///wD///8A////AP///wD///8A
+////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A
+////AP///wD///8A////AP///wD///8A////qwAAAP8AAAD/////AP///wD///8A////AP///wD///8A
+////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A
+////AP///wD///8A////AP///wD///8A////AP///wD///+rAAAA/wAAAP////8A////AP///wD///8A
+////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A
+////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///6sAAAD/AAAA/////wD///8A
+////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A
+////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////qwAAAP8AAAD/
+////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A
+////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///+r
+AAAA/wAAAP////8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A
+////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A
+////CO7u7q8AAAD/AAAA/wAAAAz///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A
+////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A
+////AP///wD///80mpqaxQAAAP8AAAD/AAAATv///wD///8A////AP///wD///8A////AP///wD///8A
+////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A
+////AP///wD///8A////CuXl5ZYeHh7xAAAA/wAAAP8CAgLXAAAAD////wD///8A////AP///wD///8A
+////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A
+////AP///wD///8A////EKurq0mOjo63FxcX9AAAAP8bGxvrICAg8AAAAP8ICAjlHh4eXAAAABj///8A
+////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A
+////AP///wD///8A////qwAAAP8AAAD/AAAA/wAAAP8AAAD/BAQE1V9fXyvS0tKZICAg8AAAAP8AAAD/
+AAAA/wAAAP8AAAD/////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A
+////AP///wD///8A////AP///wD///+rAAAA/wAAAP8AAAD/FBQU1AUFBXEAAAAG////AP///wTr6+tO
+ZWVluC4uLuoAAAD/AAAA/wAAAP////8A////AP///wD///8A////AP///wD///8A////AP///wD///8A
+////AP///wD///8A////AP///wD///8AABABAAADAAAAAQAgAAABAQADAAAAAQAgAAABAgADAAAABAAA
+EM4BAwADAAAAAQABAAABBgADAAAAAQACAAABEQAEAAAAAQAAAAgBEgADAAAAAQABAAABFQADAAAAAQAE
+AAABFgADAAAAAQAgAAABFwAEAAAAAQAAEAABGgAFAAAAAQAAENYBGwAFAAAAAQAAEN4BHAADAAAAAQAB
+AAABKAADAAAAAQACAAABUgADAAAAAQACAAABUwADAAAABAAAEOYAAAAAAAgACAAIAAgSAAAAACAAABIA
+AAAAIAAAAAEAAQABAAE
+
+
+
+
+
+
+
+ TU0AKgAABAj///9VQ0ND/wAAAP////8A////AP///6pDQ0P/AAAA/////wD///8A////AP///wD///8A
+////AP///wD///8A////AP///wD///+qAAAA/////6oAAAD/////AP///wD///8A////AP///wD///8A
+////AP///wD///8A////AP///wD///8A////AP///6oAAAD/////AP///wD///8A////AP///wD///8A
+////AP///wD///8A////AP///wD///8A////AP///wD///+qAAAA/////wD///8A////AP///wD///8A
+////AP///wD///8A////AP///wD///8A////AP///wD///8A////qgAAAP////8A////AP///wD///8A
+////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///6oAAAD/////AP///wD///8A
+////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///+qAAAA/////wD///8A
+////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////qgAAAP////8A
+////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////qgAAAP8AAAD/
+AAAA/////wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///+q
+AAAA/////wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A
+////qgAAAP////8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A
+////AP///6oAAAD/////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A
+////AP///wD///+qAAAA/////wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A
+////AP///wD///8A////qgAAAP////8A////AP///wD///8A////AP///wD///8A////AP///wD///8A
+////AP///wD///8A////qgAAAP////+qAAAA/////wD///8A////AP///wD///8A////AP///wD///8A
+////AP///wD///9VQ0ND/wAAAP////8A////AP///6pDQ0P/AAAA/////wD///8A////AP///wD///8A
+////AP///wD///8AAA4BAAADAAAAAQAQAAABAQADAAAAAQAQAAABAgADAAAABAAABLYBAwADAAAAAQAB
+AAABBgADAAAAAQACAAABEQAEAAAAAQAAAAgBEgADAAAAAQABAAABFQADAAAAAQAEAAABFgADAAAAAQAQ
+AAABFwAEAAAAAQAABAABHAADAAAAAQABAAABUgADAAAAAQACAAABUwADAAAABAAABL6HcwAHAAAHqAAA
+BMYAAAAAAAgACAAIAAgAAQABAAEAAQAAB6hhcHBsAiAAAG1udHJSR0IgWFlaIAfZAAIAGQALABoAC2Fj
+c3BBUFBMAAAAAGFwcGwAAAAAAAAAAAAAAAAAAAAAAAD21gABAAAAANMtYXBwbAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAC2Rlc2MAAAEIAAAAb2RzY20AAAF4AAAFbGNw
+cnQAAAbkAAAAOHd0cHQAAAccAAAAFHJYWVoAAAcwAAAAFGdYWVoAAAdEAAAAFGJYWVoAAAdYAAAAFHJU
+UkMAAAdsAAAADmNoYWQAAAd8AAAALGJUUkMAAAdsAAAADmdUUkMAAAdsAAAADmRlc2MAAAAAAAAAFEdl
+bmVyaWMgUkdCIFByb2ZpbGUAAAAAAAAAAAAAABRHZW5lcmljIFJHQiBQcm9maWxlAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABtbHVjAAAAAAAAAB4AAAAMc2tTSwAA
+ACgAAAF4aHJIUgAAACgAAAGgY2FFUwAAACQAAAHIcHRCUgAAACYAAAHsdWtVQQAAACoAAAISZnJGVQAA
+ACgAAAI8emhUVwAAABYAAAJkaXRJVAAAACgAAAJ6bmJOTwAAACYAAAKia29LUgAAABYAAALIY3NDWgAA
+ACIAAALeaGVJTAAAAB4AAAMAZGVERQAAACwAAAMeaHVIVQAAACgAAANKc3ZTRQAAACYAAAKiemhDTgAA
+ABYAAANyamFKUAAAABoAAAOIcm9STwAAACQAAAOiZWxHUgAAACIAAAPGcHRQTwAAACYAAAPobmxOTAAA
+ACgAAAQOZXNFUwAAACYAAAPodGhUSAAAACQAAAQ2dHJUUgAAACIAAARaZmlGSQAAACgAAAR8cGxQTAAA
+ACwAAASkcnVSVQAAACIAAATQYXJFRwAAACYAAATyZW5VUwAAACYAAAUYZGFESwAAAC4AAAU+AFYBYQBl
+AG8AYgBlAGMAbgD9ACAAUgBHAEIAIABwAHIAbwBmAGkAbABHAGUAbgBlAHIAaQENAGsAaQAgAFIARwBC
+ACAAcAByAG8AZgBpAGwAUABlAHIAZgBpAGwAIABSAEcAQgAgAGcAZQBuAOgAcgBpAGMAUABlAHIAZgBp
+AGwAIABSAEcAQgAgAEcAZQBuAOkAcgBpAGMAbwQXBDAEMwQwBDsETAQ9BDgEOQAgBD8EQAQ+BEQEMAQ5
+BDsAIABSAEcAQgBQAHIAbwBmAGkAbAAgAGcA6QBuAOkAcgBpAHEAdQBlACAAUgBWAEKQGnUoACAAUgBH
+AEIAIIJyX2ljz4/wAFAAcgBvAGYAaQBsAG8AIABSAEcAQgAgAGcAZQBuAGUAcgBpAGMAbwBHAGUAbgBl
+AHIAaQBzAGsAIABSAEcAQgAtAHAAcgBvAGYAaQBsx3y8GAAgAFIARwBCACDVBLhc0wzHfABPAGIAZQBj
+AG4A/QAgAFIARwBCACAAcAByAG8AZgBpAGwF5AXoBdUF5AXZBdwAIABSAEcAQgAgBdsF3AXcBdkAQQBs
+AGwAZwBlAG0AZQBpAG4AZQBzACAAUgBHAEIALQBQAHIAbwBmAGkAbADBAGwAdABhAGwA4QBuAG8AcwAg
+AFIARwBCACAAcAByAG8AZgBpAGxmbpAaACAAUgBHAEIAIGPPj/Blh072TgCCLAAgAFIARwBCACAw1zDt
+MNUwoTCkMOsAUAByAG8AZgBpAGwAIABSAEcAQgAgAGcAZQBuAGUAcgBpAGMDkwO1A70DuQO6A8wAIAPA
+A8EDvwPGA68DuwAgAFIARwBCAFAAZQByAGYAaQBsACAAUgBHAEIAIABnAGUAbgDpAHIAaQBjAG8AQQBs
+AGcAZQBtAGUAZQBuACAAUgBHAEIALQBwAHIAbwBmAGkAZQBsDkIOGw4jDkQOHw4lDkwAIABSAEcAQgAg
+DhcOMQ5IDicORA4bAEcAZQBuAGUAbAAgAFIARwBCACAAUAByAG8AZgBpAGwAaQBZAGwAZQBpAG4AZQBu
+ACAAUgBHAEIALQBwAHIAbwBmAGkAaQBsAGkAVQBuAGkAdwBlAHIAcwBhAGwAbgB5ACAAcAByAG8AZgBp
+AGwAIABSAEcAQgQeBDEESQQ4BDkAIAQ/BEAEPgREBDgEOwRMACAAUgBHAEIGRQZEBkEAIAYqBjkGMQZK
+BkEAIABSAEcAQgAgBicGRAY5BicGRQBHAGUAbgBlAHIAaQBjACAAUgBHAEIAIABQAHIAbwBmAGkAbABl
+AEcAZQBuAGUAcgBlAGwAIABSAEcAQgAtAGIAZQBzAGsAcgBpAHYAZQBsAHMAZXRleHQAAAAAQ29weXJp
+Z2h0IDIwMDcgQXBwbGUgSW5jLiwgYWxsIHJpZ2h0cyByZXNlcnZlZC4AWFlaIAAAAAAAAPNSAAEAAAAB
+Fs9YWVogAAAAAAAAdE0AAD3uAAAD0FhZWiAAAAAAAABadQAArHMAABc0WFlaIAAAAAAAACgaAAAVnwAA
+uDZjdXJ2AAAAAAAAAAEBzQAAc2YzMgAAAAAAAQxCAAAF3v//8yYAAAeSAAD9kf//+6L///2jAAAD3AAA
+wGw
+
+
+
+
+
+ 3
+ MCAwAA
+
+
+
+ 4
+
+
+
+ 256
+ {{510, 1}, {16, 286}}
+
+
+ _NS:83
+ NO
+
+ _doScroller:
+ 1
+ 0.85256409645080566
+
+
+
+ 256
+ {{1, 271}, {525, 16}}
+
+
+
+ _NS:33
+ NO
+ 1
+
+ _doScroller:
+ 1
+ 0.94565218687057495
+
+
+ {{10, 10}, {527, 288}}
+
+
+
+ _NS:9
+ 133170
+
+
+
+ 0.25
+ 4
+ 1
+
+
+ {547, 312}
+
+
+
+ _NS:20
+
+ {{0, 0}, {1366, 746}}
+ {10000000000000, 10000000000000}
+ YES
+
+
+
+
+
+
+ textView
+
+
+
+ 15
+
+
+
+ window
+
+
+
+ 16
+
+
+
+
+
+ 0
+
+
+
+
+
+ -2
+
+
+ File's Owner
+
+
+ -1
+
+
+ First Responder
+
+
+ -3
+
+
+ Application
+
+
+ 5
+
+
+
+
+
+ logWindow
+
+
+ 6
+
+
+
+
+
+ 9
+ 0
+
+ 9
+ 1
+
+ 0.0
+
+ 1000
+
+ 5
+ 22
+ 2
+
+
+
+ 3
+ 0
+
+ 3
+ 1
+
+ 14
+
+ 1000
+
+ 3
+ 9
+ 3
+
+
+
+ 4
+ 0
+
+ 4
+ 1
+
+ 10
+
+ 1000
+
+ 3
+ 9
+ 3
+
+
+
+ 6
+ 0
+
+ 6
+ 1
+
+ 10
+
+ 1000
+
+ 9
+ 40
+ 3
+
+
+
+
+
+ 7
+
+
+
+
+
+
+
+ logView
+
+
+ 12
+
+
+
+
+ 13
+
+
+
+
+ 14
+
+
+
+
+ 45
+
+
+
+
+ 47
+
+
+
+
+ 48
+
+
+
+
+ 49
+
+
+
+
+
+
+ com.apple.InterfaceBuilder.CocoaPlugin
+ com.apple.InterfaceBuilder.CocoaPlugin
+ com.apple.InterfaceBuilder.CocoaPlugin
+ com.apple.InterfaceBuilder.CocoaPlugin
+ com.apple.InterfaceBuilder.CocoaPlugin
+ com.apple.InterfaceBuilder.CocoaPlugin
+ com.apple.InterfaceBuilder.CocoaPlugin
+ com.apple.InterfaceBuilder.CocoaPlugin
+ com.apple.InterfaceBuilder.CocoaPlugin
+ com.apple.InterfaceBuilder.CocoaPlugin
+ com.apple.InterfaceBuilder.CocoaPlugin
+
+
+
+
+
+
+
+ com.apple.InterfaceBuilder.CocoaPlugin
+
+ com.apple.InterfaceBuilder.CocoaPlugin
+
+
+
+
+
+ 49
+
+
+
+
+ LogController
+ NSWindowController
+
+ textView
+ NSTextView
+
+
+ textView
+
+ textView
+ NSTextView
+
+
+
+ IBProjectSource
+ ./Classes/LogController.h
+
+
+
+
+ 0
+ IBCocoaFramework
+ YES
+ 3
+ YES
+
+
diff --git a/src/frontends/osx/strongSwan/en.lproj/MainMenu.xib b/src/frontends/osx/strongSwan/en.lproj/MainMenu.xib
new file mode 100644
index 000000000..c7cce11e6
--- /dev/null
+++ b/src/frontends/osx/strongSwan/en.lproj/MainMenu.xib
@@ -0,0 +1,277 @@
+
+
+
+ 1080
+ 12D78
+ 2840
+ 1187.37
+ 626.00
+
+ com.apple.InterfaceBuilder.CocoaPlugin
+ 2840
+
+
+ NSCustomObject
+ NSMenu
+ NSMenuItem
+
+
+ com.apple.InterfaceBuilder.CocoaPlugin
+
+
+ PluginDependencyRecalculationVersion
+
+
+
+
+ NSApplication
+
+
+ FirstResponder
+
+
+ NSApplication
+
+
+
+ AppDelegate
+
+
+ NSFontManager
+
+
+
+
+
+
+ terminate:
+
+
+
+ 559
+
+
+
+ orderFrontStandardAboutPanel:
+
+
+
+ 560
+
+
+
+ delegate
+
+
+
+ 495
+
+
+
+ statusMenu
+
+
+
+ 550
+
+
+
+ addConnection:
+
+
+
+ 561
+
+
+
+
+
+ 0
+
+
+
+
+
+ -2
+
+
+ File's Owner
+
+
+ -1
+
+
+ First Responder
+
+
+ -3
+
+
+ Application
+
+
+ 420
+
+
+
+
+ 494
+
+
+
+
+ 536
+
+
+
+
+
+
+
+
+ statusMenu
+
+
+ 538
+
+
+ quitItem
+
+
+ 547
+
+
+ aboutItem
+
+
+ 557
+
+
+ connSeparator
+
+
+ 558
+
+
+ addItem
+
+
+
+
+ com.apple.InterfaceBuilder.CocoaPlugin
+ com.apple.InterfaceBuilder.CocoaPlugin
+ com.apple.InterfaceBuilder.CocoaPlugin
+ com.apple.InterfaceBuilder.CocoaPlugin
+ com.apple.InterfaceBuilder.CocoaPlugin
+ com.apple.InterfaceBuilder.CocoaPlugin
+ com.apple.InterfaceBuilder.CocoaPlugin
+ com.apple.InterfaceBuilder.CocoaPlugin
+ com.apple.InterfaceBuilder.CocoaPlugin
+ com.apple.InterfaceBuilder.CocoaPlugin
+
+
+
+
+
+ 780
+
+
+
+
+ AppDelegate
+ NSObject
+
+ id
+ id
+
+
+
+ addConnection:
+ id
+
+
+ confirmPassword:
+ id
+
+
+
+ NSTextField
+ NSWindow
+ NSMenu
+
+
+
+ password
+ NSTextField
+
+
+ passwordDialog
+ NSWindow
+
+
+ statusMenu
+ NSMenu
+
+
+
+ IBProjectSource
+ ./Classes/AppDelegate.h
+
+
+
+
+ 0
+ IBCocoaFramework
+ YES
+ 3
+
+ {11, 11}
+ {10, 3}
+
+ YES
+
+
diff --git a/src/frontends/osx/strongSwan/en.lproj/PasswordWindow.xib b/src/frontends/osx/strongSwan/en.lproj/PasswordWindow.xib
new file mode 100644
index 000000000..1f4434348
--- /dev/null
+++ b/src/frontends/osx/strongSwan/en.lproj/PasswordWindow.xib
@@ -0,0 +1,578 @@
+
+
+
+ 1070
+ 14B25
+ 6254
+ 1343.16
+ 755.00
+
+ com.apple.InterfaceBuilder.CocoaPlugin
+ 6254
+
+
+ IBNSLayoutConstraint
+ NSButton
+ NSButtonCell
+ NSCustomObject
+ NSSecureTextField
+ NSSecureTextFieldCell
+ NSTextField
+ NSTextFieldCell
+ NSView
+ NSWindowTemplate
+
+
+ com.apple.InterfaceBuilder.CocoaPlugin
+
+
+ PluginDependencyRecalculationVersion
+
+
+
+
+ PasswordController
+
+
+ FirstResponder
+
+
+ NSApplication
+
+
+ 1
+ 2
+ {{121, 123}, {246, 91}}
+ 611845120
+ Password required
+ NSWindow
+
+
+
+
+ 256
+
+
+
+ 268
+ {{98, 51}, {128, 22}}
+
+
+
+ _NS:9
+ YES
+
+ 342884416
+ 272630848
+
+
+ YES
+ 13
+ 1044
+
+ _NS:9
+
+ YES
+
+ 6
+ System
+ textBackgroundColor
+
+ 3
+ MQA
+
+
+
+ 6
+ System
+ textColor
+
+ 3
+ MAA
+
+
+
+ NSAllRomanInputSourcesLocaleIdentifier
+
+
+ NO
+ 1
+
+
+
+ 268
+ {{21, 54}, {69, 17}}
+
+
+
+ _NS:1535
+ YES
+
+ 68157504
+ 272630784
+ Password:
+
+ _NS:1535
+
+
+ 6
+ System
+ controlColor
+
+ 3
+ MC42NjY2NjY2NjY3AA
+
+
+
+ 6
+ System
+ controlTextColor
+
+
+
+ NO
+ 1
+
+
+
+ 268
+ {{144, 13}, {88, 32}}
+
+
+ _NS:9
+ YES
+
+ 67108864
+ 134217728
+ OK
+
+ _NS:9
+
+ -2038284288
+ 129
+
+ DQ
+ 200
+ 25
+
+ NO
+
+
+ {246, 91}
+
+
+
+ _NS:20
+
+ {{0, 0}, {1366, 745}}
+ {10000000000000, 10000000000000}
+ 2
+ YES
+
+
+
+
+
+
+ password
+
+
+
+ 21
+
+
+
+ window
+
+
+
+ 22
+
+
+
+ confirm:
+
+
+
+ 23
+
+
+
+
+
+ 0
+
+
+
+
+
+ -2
+
+
+ File's Owner
+
+
+ -1
+
+
+ First Responder
+
+
+ -3
+
+
+ Application
+
+
+ 5
+
+
+
+
+
+ passwordDialog
+
+
+ 6
+
+
+
+
+
+
+
+ 5
+ 0
+
+ 5
+ 1
+ 1
+
+ 23
+
+ 1000
+
+ 3
+ 9
+ 3
+ NO
+
+
+
+ 3
+ 0
+
+ 3
+ 1
+ 1
+
+ 20
+
+ 1000
+
+ 0
+ 29
+ 3
+ NO
+
+
+
+ 10
+ 0
+
+ 10
+ 1
+ 1
+
+ 0.0
+
+ 1000
+
+ 6
+ 24
+ 2
+ NO
+
+
+
+ 6
+ 0
+
+ 6
+ 1
+ 1
+
+ 20
+
+ 1000
+
+ 0
+ 29
+ 3
+ NO
+
+
+
+ 6
+ 0
+
+ 6
+ 1
+ 1
+
+ 20
+
+ 1000
+
+ 0
+ 29
+ 3
+ NO
+
+
+
+ 4
+ 0
+
+ 4
+ 1
+ 1
+
+ 20
+
+ 1000
+
+ 0
+ 29
+ 3
+ NO
+
+
+
+
+
+ 7
+
+
+
+
+ 7
+ 0
+
+ 0
+ 1
+ 1
+
+ 76
+
+ 1000
+
+ 3
+ 9
+ 1
+ NO
+
+
+
+
+
+
+ 8
+
+
+
+
+ 7
+ 0
+
+ 0
+ 1
+ 1
+
+ 128
+
+ 1000
+
+ 3
+ 9
+ 1
+ NO
+
+
+
+
+
+
+ 9
+
+
+
+
+
+
+
+ 10
+
+
+
+
+ 11
+
+
+
+
+ 12
+
+
+
+
+ 13
+
+
+
+
+ 14
+
+
+
+
+ 15
+
+
+
+
+ 16
+
+
+
+
+ 17
+
+
+
+
+ 18
+
+
+
+
+ 19
+
+
+
+
+ 20
+
+
+
+
+
+
+ com.apple.InterfaceBuilder.CocoaPlugin
+ com.apple.InterfaceBuilder.CocoaPlugin
+ com.apple.InterfaceBuilder.CocoaPlugin
+ com.apple.InterfaceBuilder.CocoaPlugin
+ com.apple.InterfaceBuilder.CocoaPlugin
+ com.apple.InterfaceBuilder.CocoaPlugin
+ com.apple.InterfaceBuilder.CocoaPlugin
+ com.apple.InterfaceBuilder.CocoaPlugin
+ com.apple.InterfaceBuilder.CocoaPlugin
+ com.apple.InterfaceBuilder.CocoaPlugin
+ com.apple.InterfaceBuilder.CocoaPlugin
+ com.apple.InterfaceBuilder.CocoaPlugin
+ com.apple.InterfaceBuilder.CocoaPlugin
+ com.apple.InterfaceBuilder.CocoaPlugin
+ com.apple.InterfaceBuilder.CocoaPlugin
+
+
+
+
+
+
+
+
+
+ com.apple.InterfaceBuilder.CocoaPlugin
+
+
+
+
+ com.apple.InterfaceBuilder.CocoaPlugin
+
+
+
+
+ com.apple.InterfaceBuilder.CocoaPlugin
+
+ com.apple.InterfaceBuilder.CocoaPlugin
+
+
+
+
+
+ 23
+
+
+
+
+ PasswordController
+ NSWindowController
+
+ confirm:
+ id
+
+
+ confirm:
+
+ confirm:
+ id
+
+
+
+ password
+ NSTextField
+
+
+ password
+
+ password
+ NSTextField
+
+
+
+ IBProjectSource
+ ../strongSwan/PasswordController.h
+
+
+
+ PasswordController
+
+ confirm:
+ id
+
+
+ confirm:
+
+ confirm:
+ id
+
+
+
+ IBProjectSource
+ ../strongSwan/PasswordController.m
+
+
+
+
+ 0
+ IBCocoaFramework
+ NO
+
+ com.apple.InterfaceBuilder.CocoaPlugin.InterfaceBuilder3
+
+
+ YES
+ 3
+ YES
+
+
diff --git a/src/frontends/osx/strongSwan/icon-active.png b/src/frontends/osx/strongSwan/icon-active.png
new file mode 100644
index 000000000..e470b083b
Binary files /dev/null and b/src/frontends/osx/strongSwan/icon-active.png differ
diff --git a/src/frontends/osx/strongSwan/icon-alt.png b/src/frontends/osx/strongSwan/icon-alt.png
new file mode 100644
index 000000000..997652a16
Binary files /dev/null and b/src/frontends/osx/strongSwan/icon-alt.png differ
diff --git a/src/frontends/osx/strongSwan/icon-large.icns b/src/frontends/osx/strongSwan/icon-large.icns
new file mode 100644
index 000000000..209ff2170
Binary files /dev/null and b/src/frontends/osx/strongSwan/icon-large.icns differ
diff --git a/src/frontends/osx/strongSwan/icon.png b/src/frontends/osx/strongSwan/icon.png
new file mode 100644
index 000000000..07be18ecf
Binary files /dev/null and b/src/frontends/osx/strongSwan/icon.png differ
diff --git a/src/frontends/osx/strongSwan/main.m b/src/frontends/osx/strongSwan/main.m
new file mode 100644
index 000000000..5fa29c3dd
--- /dev/null
+++ b/src/frontends/osx/strongSwan/main.m
@@ -0,0 +1,21 @@
+/*
+ * Copyright (C) 2013 Martin Willi
+ * Copyright (C) 2013 revosec AG
+ *
+ * This program 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 2 of the License, or (at your
+ * option) any later version. See .
+ *
+ * This program 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.
+ */
+
+#import
+
+int main(int argc, char *argv[])
+{
+ return NSApplicationMain(argc, (const char **)argv);
+}
diff --git a/src/frontends/osx/strongSwan/strongSwan-Info.plist b/src/frontends/osx/strongSwan/strongSwan-Info.plist
new file mode 100644
index 000000000..56ab217ef
--- /dev/null
+++ b/src/frontends/osx/strongSwan/strongSwan-Info.plist
@@ -0,0 +1,43 @@
+
+
+
+
+ CFBundleDevelopmentRegion
+ en
+ CFBundleExecutable
+ ${EXECUTABLE_NAME}
+ CFBundleIconFile
+ icon-large.icns
+ CFBundleIdentifier
+ org.strongswan.osx
+ CFBundleInfoDictionaryVersion
+ 6.0
+ CFBundleName
+ strongSwan OS X App
+ CFBundlePackageType
+ APPL
+ CFBundleShortVersionString
+ 5.2.2
+ CFBundleSignature
+ ????
+ CFBundleVersion
+ 1
+ LSApplicationCategoryType
+ public.app-category.utilities
+ LSMinimumSystemVersion
+ ${MACOSX_DEPLOYMENT_TARGET}
+ LSUIElement
+
+ NSHumanReadableCopyright
+ Copyright © 2013 revosec AG. All rights reserved.
+ NSMainNibFile
+ MainMenu
+ NSPrincipalClass
+ NSApplication
+ SMPrivilegedExecutables
+
+ org.strongswan.charon-xpc
+ identifier "org.strongswan.charon-xpc" and certificate leaf[subject.CN] = "Developer ID Application: revosec AG (SRXT3TB2PY)"
+
+
+
diff --git a/src/frontends/osx/strongSwan/strongSwan-Prefix.pch b/src/frontends/osx/strongSwan/strongSwan-Prefix.pch
new file mode 100644
index 000000000..93e0dd127
--- /dev/null
+++ b/src/frontends/osx/strongSwan/strongSwan-Prefix.pch
@@ -0,0 +1,7 @@
+//
+// Prefix header for all source files of the 'strongSwan' target in the 'strongSwan' project
+//
+
+#ifdef __OBJC__
+ #import
+#endif
diff --git a/src/libcharon/sa/task.h b/src/libcharon/sa/task.h
index f2c4299cc..8e380851a 100644
--- a/src/libcharon/sa/task.h
+++ b/src/libcharon/sa/task.h
@@ -22,6 +22,8 @@
#ifndef TASK_H_
#define TASK_H_
+#include
+
typedef enum task_type_t task_type_t;
typedef struct task_t task_t;
diff --git a/src/libhydra/plugins/kernel_pfroute/kernel_pfroute_net.c b/src/libhydra/plugins/kernel_pfroute/kernel_pfroute_net.c
index 26fae0d6b..0f7802270 100644
--- a/src/libhydra/plugins/kernel_pfroute/kernel_pfroute_net.c
+++ b/src/libhydra/plugins/kernel_pfroute/kernel_pfroute_net.c
@@ -830,6 +830,15 @@ static void process_link(private_kernel_pfroute_net_t *this,
DBG1(DBG_KNL, "interface %s deactivated", iface->ifname);
}
}
+#ifdef __APPLE__
+ /* There seems to be a race condition on 10.10, where we get
+ * the RTM_IFINFO, but getifaddrs() does not return the virtual
+ * IP installed on a tun device, but we also don't get a
+ * RTM_NEWADDR. We therefore could miss the new address, letting
+ * virtual IP installation fail. Delaying getifaddrs() helps,
+ * but is obviously not a clean fix. */
+ usleep(50000);
+#endif
iface->flags = msg->ifm_flags;
repopulate_iface(this, iface);
found = TRUE;
diff --git a/src/libstrongswan/networking/host.h b/src/libstrongswan/networking/host.h
index 26f23bc99..db6f4dd49 100644
--- a/src/libstrongswan/networking/host.h
+++ b/src/libstrongswan/networking/host.h
@@ -24,6 +24,9 @@
#ifndef HOST_H_
#define HOST_H_
+#include
+#include
+
typedef enum host_diff_t host_diff_t;
typedef struct host_t host_t;
@@ -31,9 +34,6 @@ typedef struct host_t host_t;
#include
#include
-#include
-#include
-
/**
* Representates a Host
*
diff --git a/src/libstrongswan/processing/processor.h b/src/libstrongswan/processing/processor.h
index f96530e54..ee08870fb 100644
--- a/src/libstrongswan/processing/processor.h
+++ b/src/libstrongswan/processing/processor.h
@@ -23,6 +23,8 @@
#ifndef PROCESSOR_H_
#define PROCESSOR_H_
+#include
+
typedef struct processor_t processor_t;
#include
diff --git a/src/libstrongswan/utils/compat/apple.h b/src/libstrongswan/utils/compat/apple.h
index 77e072279..61afb9d9e 100644
--- a/src/libstrongswan/utils/compat/apple.h
+++ b/src/libstrongswan/utils/compat/apple.h
@@ -34,6 +34,12 @@
/* Mach uses a semaphore_create() call, use a different name for ours */
#define semaphore_create(x) strongswan_semaphore_create(x)
+/* Since OS X 10.10 XPC includes some additional conflicting Mach types */
+#define host_t strongswan_host_t
+#define processor_t strongswan_processor_t
+#define task_t strongswan_task_t
+#define thread_t strongswan_thread_t
+
/* forward declaration, see below */
static inline int precancellable_poll(struct pollfd fds[], nfds_t nfds,
int timeout);