Browse Source

some OS X Authentication Services wizardry to get /Library/Application Support/ZeroTier/One/authtoken.secret and copy it to ~/Library/Application Support/ZeroTier/One/authtoken.secret

Grant Limberg 9 years ago
parent
commit
975bcb8aff

+ 13 - 0
ZeroTier One.xcodeproj/project.pbxproj

@@ -17,6 +17,7 @@
 		93326BEB1CE7D9B9005CA2AC /* JoinNetworkViewController.xib in Resources */ = {isa = PBXBuildFile; fileRef = 93326BE91CE7D9B9005CA2AC /* JoinNetworkViewController.xib */; };
 		93326BEE1CE7DA30005CA2AC /* ShowNetworksViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 93326BEC1CE7DA30005CA2AC /* ShowNetworksViewController.swift */; };
 		93326BEF1CE7DA30005CA2AC /* ShowNetworksViewController.xib in Resources */ = {isa = PBXBuildFile; fileRef = 93326BED1CE7DA30005CA2AC /* ShowNetworksViewController.xib */; };
+		93DAFE4B1CFE53CA00547CC4 /* AuthtokenCopy.m in Sources */ = {isa = PBXBuildFile; fileRef = 93DAFE4A1CFE53CA00547CC4 /* AuthtokenCopy.m */; };
 /* End PBXBuildFile section */
 
 /* Begin PBXFileReference section */
@@ -32,6 +33,9 @@
 		93326BE91CE7D9B9005CA2AC /* JoinNetworkViewController.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; path = JoinNetworkViewController.xib; sourceTree = "<group>"; };
 		93326BEC1CE7DA30005CA2AC /* ShowNetworksViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ShowNetworksViewController.swift; sourceTree = "<group>"; };
 		93326BED1CE7DA30005CA2AC /* ShowNetworksViewController.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; path = ShowNetworksViewController.xib; sourceTree = "<group>"; };
+		93DAFE491CFE53C900547CC4 /* ZeroTier One-Bridging-Header.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "ZeroTier One-Bridging-Header.h"; sourceTree = "<group>"; };
+		93DAFE4A1CFE53CA00547CC4 /* AuthtokenCopy.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = AuthtokenCopy.m; sourceTree = "<group>"; };
+		93DAFE4C1CFE53DA00547CC4 /* AuthtokenCopy.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = AuthtokenCopy.h; sourceTree = "<group>"; };
 /* End PBXFileReference section */
 
 /* Begin PBXFrameworksBuildPhase section */
@@ -75,6 +79,9 @@
 				93326BE21CE7C816005CA2AC /* Info.plist */,
 				93326BE91CE7D9B9005CA2AC /* JoinNetworkViewController.xib */,
 				93326BED1CE7DA30005CA2AC /* ShowNetworksViewController.xib */,
+				93DAFE4A1CFE53CA00547CC4 /* AuthtokenCopy.m */,
+				93DAFE4C1CFE53DA00547CC4 /* AuthtokenCopy.h */,
+				93DAFE491CFE53C900547CC4 /* ZeroTier One-Bridging-Header.h */,
 			);
 			path = "ZeroTier One";
 			sourceTree = "<group>";
@@ -153,6 +160,7 @@
 			files = (
 				9330F1371CEBF87200687EC8 /* Network.swift in Sources */,
 				93326BDC1CE7C816005CA2AC /* AppDelegate.swift in Sources */,
+				93DAFE4B1CFE53CA00547CC4 /* AuthtokenCopy.m in Sources */,
 				9330F13B1CF534E500687EC8 /* NetworkInfoCell.swift in Sources */,
 				93326BEA1CE7D9B9005CA2AC /* JoinNetworkViewController.swift in Sources */,
 				93326BEE1CE7DA30005CA2AC /* ShowNetworksViewController.swift in Sources */,
@@ -260,11 +268,14 @@
 			isa = XCBuildConfiguration;
 			buildSettings = {
 				ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
+				CLANG_ENABLE_MODULES = YES;
 				COMBINE_HIDPI_IMAGES = YES;
 				INFOPLIST_FILE = "ZeroTier One/Info.plist";
 				LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/../Frameworks";
 				PRODUCT_BUNDLE_IDENTIFIER = "com.zerotier.ZeroTier-One";
 				PRODUCT_NAME = "$(TARGET_NAME)";
+				SWIFT_OBJC_BRIDGING_HEADER = "ZeroTier One/ZeroTier One-Bridging-Header.h";
+				SWIFT_OPTIMIZATION_LEVEL = "-Onone";
 			};
 			name = Debug;
 		};
@@ -272,11 +283,13 @@
 			isa = XCBuildConfiguration;
 			buildSettings = {
 				ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
+				CLANG_ENABLE_MODULES = YES;
 				COMBINE_HIDPI_IMAGES = YES;
 				INFOPLIST_FILE = "ZeroTier One/Info.plist";
 				LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/../Frameworks";
 				PRODUCT_BUNDLE_IDENTIFIER = "com.zerotier.ZeroTier-One";
 				PRODUCT_NAME = "$(TARGET_NAME)";
+				SWIFT_OBJC_BRIDGING_HEADER = "ZeroTier One/ZeroTier One-Bridging-Header.h";
 			};
 			name = Release;
 		};

+ 16 - 0
ZeroTier One/AuthtokenCopy.h

@@ -0,0 +1,16 @@
+//
+//  AuthtokenCopy.h
+//  ZeroTier One
+//
+//  Created by Grant Limberg on 5/31/16.
+//  Copyright © 2016 ZeroTier, Inc. All rights reserved.
+//
+
+#ifndef AuthtokenCopy_h
+#define AuthtokenCopy_h
+
+#import <Foundation/Foundation.h>
+
+NSString* getAdminAuthToken(AuthorizationRef authRef);
+
+#endif /* AuthtokenCopy_h */

+ 87 - 0
ZeroTier One/AuthtokenCopy.m

@@ -0,0 +1,87 @@
+//
+//  AuthtokenCopy.m
+//  ZeroTier One
+//
+//  Created by Grant Limberg on 5/31/16.
+//  Copyright © 2016 ZeroTier, Inc. All rights reserved.
+//
+
+#import <Foundation/Foundation.h>
+
+#import "AuthtokenCopy.h"
+
+
+NSString* getAdminAuthToken(AuthorizationRef authRef) {
+    char *tool = "/bin/cat";
+    char *args[] = { "/Library/Application Support/ZeroTier/One/authtoken.secret", NULL};
+    FILE *pipe = nil;
+    char token[25];
+    memset(token, 0, sizeof(char)*25);
+
+
+    OSStatus status = AuthorizationExecuteWithPrivileges(authRef, tool, kAuthorizationFlagDefaults, args, &pipe);
+
+    if (status != errAuthorizationSuccess) {
+        NSLog(@"Reading authtoken failed!");
+
+
+        switch(status) {
+            case errAuthorizationDenied:
+                NSLog(@"Autorization Denied");
+                break;
+            case errAuthorizationCanceled:
+                NSLog(@"Authorization Canceled");
+                break;
+            case errAuthorizationInternal:
+                NSLog(@"Authorization Internal");
+                break;
+            case errAuthorizationBadAddress:
+                NSLog(@"Bad Address");
+                break;
+            case errAuthorizationInvalidRef:
+                NSLog(@"Invalid Ref");
+                break;
+            case errAuthorizationInvalidSet:
+                NSLog(@"Invalid Set");
+                break;
+            case errAuthorizationInvalidTag:
+                NSLog(@"Invalid Tag");
+                break;
+            case errAuthorizationInvalidFlags:
+                NSLog(@"Invalid Flags");
+                break;
+            case errAuthorizationInvalidPointer:
+                NSLog(@"Invalid Pointer");
+                break;
+            case errAuthorizationToolExecuteFailure:
+                NSLog(@"Tool Execute Failure");
+                break;
+            case errAuthorizationToolEnvironmentError:
+                NSLog(@"Tool Environment Failure");
+                break;
+            case errAuthorizationExternalizeNotAllowed:
+                NSLog(@"Externalize Not Allowed");
+                break;
+            case errAuthorizationInteractionNotAllowed:
+                NSLog(@"Interaction Not Allowed");
+                break;
+            case errAuthorizationInternalizeNotAllowed:
+                NSLog(@"Internalize Not Allowed");
+                break;
+            default:
+                NSLog(@"Unknown Error");
+                break;
+        }
+
+        return @"";
+    }
+
+    if(pipe != nil) {
+        fread(&token, sizeof(char), 24, pipe);
+        fclose(pipe);
+
+        return [NSString stringWithUTF8String:token];
+    }
+
+    return @"";
+}

+ 30 - 1
ZeroTier One/ServiceCom.swift

@@ -30,7 +30,36 @@ class ServiceCom: NSObject {
                     Holder.key = try String(contentsOfURL: authtokenURL)
                 }
                 else {
-                    // TODO: Elevate priviledge to copy /Library/Application Support/ZeroTier/One/authtoken.secret to the user's local AppSupport directory
+                    try NSFileManager.defaultManager().createDirectoryAtURL(appSupportDir, withIntermediateDirectories: true, attributes: nil)
+
+                    var authRef: AuthorizationRef = nil
+                    var status = AuthorizationCreate(nil, nil, .Defaults, &authRef)
+
+                    if status != errAuthorizationSuccess {
+                        NSLog("Authorization Failed! \(status)")
+                        return ""
+                    }
+
+                    var authItem = AuthorizationItem(name: kAuthorizationRightExecute, valueLength: 0, value: nil, flags: 0)
+                    var authRights = AuthorizationRights(count: 1, items: &authItem)
+                    let authFlags: AuthorizationFlags = [.Defaults, .InteractionAllowed, .PreAuthorize, .ExtendRights]
+
+                    status = AuthorizationCopyRights(authRef, &authRights, nil, authFlags, nil)
+
+                    if status != errAuthorizationSuccess {
+                        NSLog("Authorization Failed! \(status)")
+                        return ""
+                    }
+
+                    let localKey = getAdminAuthToken(authRef)
+                    AuthorizationFree(authRef, .DestroyRights)
+
+                    if localKey != nil && localKey.lengthOfBytesUsingEncoding(NSUTF8StringEncoding) > 0 {
+                        NSLog("\(localKey)")
+                        Holder.key = localKey
+
+                        try localKey.writeToURL(authtokenURL, atomically: true, encoding: NSUTF8StringEncoding)
+                    }
                 }
             }
             catch {

+ 5 - 0
ZeroTier One/ZeroTier One-Bridging-Header.h

@@ -0,0 +1,5 @@
+//
+//  Use this file to import your target's public headers that you would like to expose to Swift.
+//
+
+#import "AuthtokenCopy.h"