From 03b48a4ad4894b6dff5220e32d21bdce1b762f56 Mon Sep 17 00:00:00 2001
From: Grant Limberg <grant.limberg@zerotier.com>
Date: Wed, 22 Mar 2017 10:22:15 -0700
Subject: [PATCH] add lock around [ServiceCom key] and remove some debug code

---
 macui/ZeroTier One/ServiceCom.m | 263 ++++++++++++++++----------------
 1 file changed, 134 insertions(+), 129 deletions(-)

diff --git a/macui/ZeroTier One/ServiceCom.m b/macui/ZeroTier One/ServiceCom.m
index 6040ef7b5..75b98502f 100644
--- a/macui/ZeroTier One/ServiceCom.m	
+++ b/macui/ZeroTier One/ServiceCom.m	
@@ -55,154 +55,159 @@
 - (NSString*)key:(NSError* __autoreleasing *)err
 {
     static NSString *k = nil;
-    static NSUInteger resetCount = 10;
+    static NSUInteger resetCount = 0;
     
-    if (_resetKey && k != nil) {
-        k = nil;
-        ++resetCount;
-        NSLog(@"ResetCount: %lu", (unsigned long)resetCount);
-        if (resetCount > 10) {
-            [[NSOperationQueue mainQueue] addOperationWithBlock:^{
-                NSAlert *alert = [NSAlert alertWithMessageText:@"Error obtaining Auth Token"
-                                                 defaultButton:@"Quit"
-                                               alternateButton:@"Retry"
-                                                   otherButton:nil
-                                     informativeTextWithFormat:@"Please ensure ZeroTier is installed correctly"];
-                alert.alertStyle = NSCriticalAlertStyle;
-                
-                NSModalResponse res;
-                if (!_isQuitting) {
-                    res = [alert runModal];
-                }
-                else {
-                    return;
-                }
-                
-                if(res == 1) {
-                    _isQuitting = YES;
-                    [NSApp performSelector:@selector(terminate:) withObject:nil afterDelay:0.0];
-                }
-            }];
+    @synchronized (self) {
+        if (_isQuitting) {
             return @"";
         }
-    }
-
-    if (k == nil) {
-        NSError *error = nil;
-        NSURL *appSupportDir = [[NSFileManager defaultManager] URLForDirectory:NSApplicationSupportDirectory inDomain:NSUserDomainMask appropriateForURL:nil create:false error:&error];
-
-        if (error) {
-            NSLog(@"Error: %@", error);
-            return @"";
+        
+        if (_resetKey && k != nil) {
+            k = nil;
+            ++resetCount;
+            NSLog(@"ResetCount: %lu", (unsigned long)resetCount);
+            if (resetCount > 10) {
+                [[NSOperationQueue mainQueue] addOperationWithBlock:^{
+                    NSAlert *alert = [NSAlert alertWithMessageText:@"Error obtaining Auth Token"
+                                                     defaultButton:@"Quit"
+                                                   alternateButton:@"Retry"
+                                                       otherButton:nil
+                                         informativeTextWithFormat:@"Please ensure ZeroTier is installed correctly"];
+                    alert.alertStyle = NSCriticalAlertStyle;
+                    
+                    NSModalResponse res;
+                    if (!_isQuitting) {
+                        res = [alert runModal];
+                    }
+                    else {
+                        return;
+                    }
+                    
+                    if(res == 1) {
+                        _isQuitting = YES;
+                        [NSApp performSelector:@selector(terminate:) withObject:nil afterDelay:0.0];
+                    }
+                }];
+                return @"";
+            }
         }
 
-        appSupportDir = [[appSupportDir URLByAppendingPathComponent:@"ZeroTier"] URLByAppendingPathComponent:@"One"];
-        NSURL *authtokenURL = [appSupportDir URLByAppendingPathComponent:@"authtoken.secret"];
-
-        if (!_resetKey && [[NSFileManager defaultManager] fileExistsAtPath:[authtokenURL path]]) {
-            k = [NSString stringWithContentsOfURL:authtokenURL
-                                         encoding:NSUTF8StringEncoding
-                                            error:&error];
-            
-            k = [k stringByReplacingOccurrencesOfString:@"\n" withString:@""];
+        if (k == nil) {
+            NSError *error = nil;
+            NSURL *appSupportDir = [[NSFileManager defaultManager] URLForDirectory:NSApplicationSupportDirectory inDomain:NSUserDomainMask appropriateForURL:nil create:false error:&error];
 
             if (error) {
                 NSLog(@"Error: %@", error);
-                k = nil;
-                *err = error;
-                return @"";
-            }
-        }
-        else {
-            _resetKey = NO;
-            NSURL *sysAppSupportDir = [[NSFileManager defaultManager] URLForDirectory:NSApplicationSupportDirectory inDomain:NSSystemDomainMask appropriateForURL:nil create:false error:nil];
-
-            sysAppSupportDir = [[sysAppSupportDir URLByAppendingPathComponent:@"ZeroTier"] URLByAppendingPathComponent:@"One"];
-            NSURL *sysAuthtokenURL = [sysAppSupportDir URLByAppendingPathComponent:@"authtoken.secret"];
-
-            if(![[NSFileManager defaultManager] fileExistsAtPath:[sysAuthtokenURL path]]) {
-
-            }
-
-            [[NSFileManager defaultManager] createDirectoryAtURL:appSupportDir
-                                     withIntermediateDirectories:YES
-                                                      attributes:nil
-                                                           error:&error];
-
-            if (error) {
-                NSLog(@"Error: %@", error);
-                *err = error;
-                k = nil;
                 return @"";
             }
 
-            AuthorizationRef authRef;
-            OSStatus status = AuthorizationCreate(nil, nil, kAuthorizationFlagDefaults, &authRef);
+            appSupportDir = [[appSupportDir URLByAppendingPathComponent:@"ZeroTier"] URLByAppendingPathComponent:@"One"];
+            NSURL *authtokenURL = [appSupportDir URLByAppendingPathComponent:@"authtoken.secret"];
 
-            if (status != errAuthorizationSuccess) {
-                NSLog(@"Authorization Failed! %d", status);
-
-                NSDictionary *userInfo = @{
-                                           NSLocalizedDescriptionKey: NSLocalizedString(@"Couldn't create AuthorizationRef", nil),
-                                           };
-                *err = [NSError errorWithDomain:@"com.zerotier.one" code:-1 userInfo:userInfo];
-
-                return @"";
-            }
-
-            AuthorizationItem authItem;
-            authItem.name = kAuthorizationRightExecute;
-            authItem.valueLength = 0;
-            authItem.flags = 0;
-
-            AuthorizationRights authRights;
-            authRights.count = 1;
-            authRights.items = &authItem;
-
-            AuthorizationFlags authFlags = kAuthorizationFlagDefaults |
-                                           kAuthorizationFlagInteractionAllowed |
-                                           kAuthorizationFlagPreAuthorize |
-                                           kAuthorizationFlagExtendRights;
-
-            status = AuthorizationCopyRights(authRef, &authRights, nil, authFlags, nil);
-
-            if (status != errAuthorizationSuccess) {
-                NSLog(@"Authorization Failed! %d", status);
-                NSDictionary *userInfo = @{
-                                           NSLocalizedDescriptionKey: NSLocalizedString(@"Couldn't copy authorization rights", nil),
-                                           };
-                *err = [NSError errorWithDomain:@"com.zerotier.one" code:-1 userInfo:userInfo];
-                return @"";
-            }
-
-            NSString *localKey = getAdminAuthToken(authRef);
-            AuthorizationFree(authRef, kAuthorizationFlagDestroyRights);
-
-            if (localKey != nil && [localKey lengthOfBytesUsingEncoding:NSUTF8StringEncoding] > 0) {
-                k = localKey;
-
-                [localKey writeToURL:authtokenURL
-                          atomically:YES
-                            encoding:NSUTF8StringEncoding
-                               error:&error];
+            if (!_resetKey && [[NSFileManager defaultManager] fileExistsAtPath:[authtokenURL path]]) {
+                k = [NSString stringWithContentsOfURL:authtokenURL
+                                             encoding:NSUTF8StringEncoding
+                                                error:&error];
+                
+                k = [k stringByReplacingOccurrencesOfString:@"\n" withString:@""];
 
                 if (error) {
-                    NSLog(@"Error writing token to disk: %@", error);
+                    NSLog(@"Error: %@", error);
+                    k = nil;
                     *err = error;
+                    return @"";
+                }
+            }
+            else {
+                _resetKey = NO;
+                NSURL *sysAppSupportDir = [[NSFileManager defaultManager] URLForDirectory:NSApplicationSupportDirectory inDomain:NSSystemDomainMask appropriateForURL:nil create:false error:nil];
+
+                sysAppSupportDir = [[sysAppSupportDir URLByAppendingPathComponent:@"ZeroTier"] URLByAppendingPathComponent:@"One"];
+                NSURL *sysAuthtokenURL = [sysAppSupportDir URLByAppendingPathComponent:@"authtoken.secret"];
+
+                if(![[NSFileManager defaultManager] fileExistsAtPath:[sysAuthtokenURL path]]) {
+
+                }
+
+                [[NSFileManager defaultManager] createDirectoryAtURL:appSupportDir
+                                         withIntermediateDirectories:YES
+                                                          attributes:nil
+                                                               error:&error];
+
+                if (error) {
+                    NSLog(@"Error: %@", error);
+                    *err = error;
+                    k = nil;
+                    return @"";
+                }
+
+                AuthorizationRef authRef;
+                OSStatus status = AuthorizationCreate(nil, nil, kAuthorizationFlagDefaults, &authRef);
+
+                if (status != errAuthorizationSuccess) {
+                    NSLog(@"Authorization Failed! %d", status);
+
+                    NSDictionary *userInfo = @{
+                                               NSLocalizedDescriptionKey: NSLocalizedString(@"Couldn't create AuthorizationRef", nil),
+                                               };
+                    *err = [NSError errorWithDomain:@"com.zerotier.one" code:-1 userInfo:userInfo];
+
+                    return @"";
+                }
+
+                AuthorizationItem authItem;
+                authItem.name = kAuthorizationRightExecute;
+                authItem.valueLength = 0;
+                authItem.flags = 0;
+
+                AuthorizationRights authRights;
+                authRights.count = 1;
+                authRights.items = &authItem;
+
+                AuthorizationFlags authFlags = kAuthorizationFlagDefaults |
+                                               kAuthorizationFlagInteractionAllowed |
+                                               kAuthorizationFlagPreAuthorize |
+                                               kAuthorizationFlagExtendRights;
+
+                status = AuthorizationCopyRights(authRef, &authRights, nil, authFlags, nil);
+
+                if (status != errAuthorizationSuccess) {
+                    NSLog(@"Authorization Failed! %d", status);
+                    NSDictionary *userInfo = @{
+                                               NSLocalizedDescriptionKey: NSLocalizedString(@"Couldn't copy authorization rights", nil),
+                                               };
+                    *err = [NSError errorWithDomain:@"com.zerotier.one" code:-1 userInfo:userInfo];
+                    return @"";
+                }
+
+                NSString *localKey = getAdminAuthToken(authRef);
+                AuthorizationFree(authRef, kAuthorizationFlagDestroyRights);
+
+                if (localKey != nil && [localKey lengthOfBytesUsingEncoding:NSUTF8StringEncoding] > 0) {
+                    k = localKey;
+
+                    [localKey writeToURL:authtokenURL
+                              atomically:YES
+                                encoding:NSUTF8StringEncoding
+                                   error:&error];
+
+                    if (error) {
+                        NSLog(@"Error writing token to disk: %@", error);
+                        *err = error;
+                    }
                 }
             }
         }
+
+        if (k == nil) {
+            NSDictionary *userInfo = @{
+                                       NSLocalizedDescriptionKey: NSLocalizedString(@"Unknown error finding authorization key", nil),
+                                       };
+            *err = [NSError errorWithDomain:@"com.zerotier.one" code:-1 userInfo:userInfo];
+
+            return @"";
+        }
     }
-
-    if (k == nil) {
-        NSDictionary *userInfo = @{
-                                   NSLocalizedDescriptionKey: NSLocalizedString(@"Unknown error finding authorization key", nil),
-                                   };
-        *err = [NSError errorWithDomain:@"com.zerotier.one" code:-1 userInfo:userInfo];
-
-        return @"";
-    }
-
     return k;
 }