Changeset 240

Show
Ignore:
Timestamp:
01/05/07 21:17:57 (2 years ago)
Author:
gbooker
Message:

Authenticated install and remove.

Files:

Legend:

Unmodified
Added
Removed
Modified
Copied
Moved
  • trunk/CPFPerianPrefPaneController.m

    r238 r240  
    11#import "CPFPerianPrefPaneController.h" 
    22#import <Security/Security.h> 
     3#include <sys/stat.h> 
    34 
    45#define ComponentInfoDictionaryKey      @"Components" 
     
    3637} 
    3738 
     39- (BOOL)systemInstalled 
     40{ 
     41        NSString *myPath = [[self bundle] bundlePath]; 
     42         
     43        if([myPath hasPrefix:NSHomeDirectory()]) 
     44                return NO; 
     45        return YES; 
     46} 
     47 
    3848- (NSString *)quickTimeComponentDir 
    3949{ 
    40         NSString *myPath = [[self bundle] bundlePath]; 
    4150        NSString *basePath = nil; 
    4251         
    43         if([myPath hasPrefix:NSHomeDirectory()]) 
     52        if(![self systemInstalled]) 
    4453                basePath = NSHomeDirectory(); 
    4554        else 
     
    5160- (NSString *)coreAudioComponentDir 
    5261{ 
    53         NSString *myPath = [[self bundle] bundlePath]; 
    5462        NSString *basePath = nil; 
    5563         
    56         if([myPath hasPrefix:NSHomeDirectory()]) 
     64        if(![self systemInstalled]) 
    5765                basePath = NSHomeDirectory(); 
    5866        else 
     
    211219                        pclose(cmdFP); 
    212220                } 
     221                unsetenv("DESTINATION"); 
    213222                fclose(fp); 
    214223        }        
     
    217226} 
    218227 
    219 - (BOOL)installArchive:(NSString *)archivePath forPiece:(NSString *)component type:(ComponentType)type withMyVersion:(NSString *)myVersion andAuthorization:(AuthorizationRef *)auth 
     228- (BOOL)_authenticatedExtractArchivePath:(NSString *)archivePath toDestination:(NSString *)destination finalPath:(NSString *)finalPath authorization:(AuthorizationRef)auth 
     229
     230        BOOL ret = NO, oldExist = NO; 
     231        struct stat sb; 
     232        if(stat([finalPath fileSystemRepresentation], &sb) == 0) 
     233                oldExist = YES; 
     234         
     235        if(stat([destination fileSystemRepresentation], &sb) != 0) 
     236                return FALSE; 
     237         
     238        char *buf = NULL; 
     239        if(oldExist) 
     240                asprintf(&buf, 
     241                                 "mv -f \"$DST_COMPONENT\" \"$TMP_PATH\" && " 
     242                                 "ditto -x -k --rsrc \"$SRC_ARCHIVE\" \"$DST_PATH\" && " 
     243                                 "rm -rf \"$TMP_PATH\" && " 
     244                                 "chown -R %d:%d \"$DST_COMPONENT\"", 
     245                                 sb.st_uid, sb.st_gid); 
     246        else 
     247                asprintf(&buf, 
     248                                 "ditto -x -k --rsrc \"$SRC_ARCHIVE\" \"$DST_PATH\" && " 
     249                                 "chown -R %d:%d \"$DST_COMPONENT\"", 
     250                                 sb.st_uid, sb.st_gid); 
     251        if(!buf) 
     252                return FALSE; 
     253         
     254        setenv("SRC_ARCHIVE", [archivePath fileSystemRepresentation], 1); 
     255        setenv("$DST_COMPONENT", [finalPath fileSystemRepresentation], 1); 
     256        setenv("TMP_PATH", [[finalPath stringByAppendingPathExtension:@"old"] fileSystemRepresentation], 1); 
     257        setenv("DST_PATH", [destination fileSystemRepresentation], 1); 
     258         
     259        char* arguments[] = { "-c", buf, NULL }; 
     260        if(AuthorizationExecuteWithPrivileges(auth, "/bin/sh", kAuthorizationFlagDefaults, arguments, NULL) == errAuthorizationSuccess) 
     261        { 
     262                int status; 
     263                int pid = wait(&status); 
     264                if(pid != -1 && WIFEXITED(status) && WEXITSTATUS(status) == 0) 
     265                        ret = YES; 
     266        } 
     267        free(buf); 
     268        unsetenv("SRC_ARCHIVE"); 
     269        unsetenv("$DST_COMPONENT"); 
     270        unsetenv("TMP_PATH"); 
     271        unsetenv("DST_PATH"); 
     272        return ret; 
     273
     274 
     275- (BOOL)_authenticatedRemove:(NSString *)componentPath authorization:(AuthorizationRef)auth 
     276
     277        BOOL ret = NO; 
     278        struct stat sb; 
     279        if(stat([componentPath fileSystemRepresentation], &sb) != 0) 
     280                return FALSE; 
     281         
     282        char *buf = NULL; 
     283        asprintf(&buf, 
     284                         "rm -rf \"$COMP_PATH\" && "); 
     285        if(!buf) 
     286                return FALSE; 
     287         
     288        setenv("COMP_PATH", [componentPath fileSystemRepresentation], 1); 
     289         
     290        char* arguments[] = { "-c", buf, NULL }; 
     291        if(AuthorizationExecuteWithPrivileges(auth, "/bin/sh", kAuthorizationFlagDefaults, arguments, NULL) == errAuthorizationSuccess) 
     292        { 
     293                int status; 
     294                int pid = wait(&status); 
     295                if(pid != -1 && WIFEXITED(status) && WEXITSTATUS(status) == 0) 
     296                        ret = YES; 
     297        } 
     298        free(buf); 
     299        unsetenv("COMP_PATH"); 
     300        return ret; 
     301
     302 
     303 
     304- (BOOL)installArchive:(NSString *)archivePath forPiece:(NSString *)component type:(ComponentType)type withMyVersion:(NSString *)myVersion andAuthorization:(AuthorizationRef)auth 
    220305{ 
    221306        NSString *containingDir = nil; 
     
    230315        } 
    231316        InstallStatus pieceStatus = [self installStatusForComponent:component type:type withMyVersion:myVersion]; 
    232         if(pieceStatus == InstallStatusOutdated) 
    233         { 
    234                 //Remove the old one here 
    235                 //XXX what about authorized 
    236                 int tag = 0; 
    237                 BOOL result = [[NSWorkspace sharedWorkspace] performFileOperation:NSWorkspaceRecycleOperation source:containingDir destination:@"" files:[NSArray arrayWithObject:component] tag:&tag]; 
     317        if(auth != nil && pieceStatus != InstallStatusInstalled) 
     318        { 
     319                BOOL result = [self _authenticatedExtractArchivePath:archivePath toDestination:containingDir finalPath:[containingDir stringByAppendingPathComponent:component] authorization:auth]; 
    238320                if(result == NO) 
    239321                        return NO; 
    240322        } 
    241         if(pieceStatus != InstallStatusInstalled) 
    242         { 
    243                 //Decompress and install new one 
    244                 //XXX Need to do authorized version as well 
    245                 BOOL result = [self _extractArchivePath:archivePath toDestination:containingDir pipingDataToCommand:@"ditto -x -k - \"$DESTINATION\""]; 
    246                 if(result == NO) 
    247                         return NO; 
     323        else 
     324        { 
     325                //Not authenticated 
     326                if(pieceStatus == InstallStatusOutdated) 
     327                { 
     328                        //Remove the old one here 
     329                        int tag = 0; 
     330                        BOOL result = [[NSWorkspace sharedWorkspace] performFileOperation:NSWorkspaceRecycleOperation source:containingDir destination:@"" files:[NSArray arrayWithObject:component] tag:&tag]; 
     331                        if(result == NO) 
     332                                return NO; 
     333                } 
     334                if(pieceStatus != InstallStatusInstalled) 
     335                { 
     336                        //Decompress and install new one 
     337                        BOOL result = [self _extractArchivePath:archivePath toDestination:containingDir pipingDataToCommand:@"ditto -x -k - \"$DESTINATION\""]; 
     338                        if(result == NO) 
     339                                return NO; 
     340                }                
    248341        } 
    249342        return YES; 
     
    258351        NSString *coreAudioComponentPath = [componentPath stringByAppendingPathComponent:@"CoreAudio"]; 
    259352        NSString *quickTimeComponentPath = [componentPath stringByAppendingPathComponent:@"QuickTime"]; 
    260          
    261         [self installArchive:[componentPath stringByAppendingPathComponent:@"Perian.zip"] forPiece:@"Perian.component" type:ComponentTypeQuickTime withMyVersion:[infoDict objectForKey:BundleVersionKey] andAuthorization:NULL]; 
     353        AuthorizationRef auth = nil; 
     354         
     355        if([self systemInstalled]) 
     356        { 
     357                if(!AuthorizationCreate(NULL, kAuthorizationEmptyEnvironment, kAuthorizationFlagDefaults, &auth) == errAuthorizationSuccess) 
     358                        // Try it anyway, it will likely fail, but who knows what kind of screwed up systems people have 
     359                        auth = nil; 
     360        } 
     361         
     362        [self installArchive:[componentPath stringByAppendingPathComponent:@"Perian.zip"] forPiece:@"Perian.component" type:ComponentTypeQuickTime withMyVersion:[infoDict objectForKey:BundleVersionKey] andAuthorization:auth]; 
    262363         
    263364        NSEnumerator *componentEnum = [myComponentsInfo objectEnumerator]; 
     
    276377                                break; 
    277378                } 
    278                 [self installArchive:archivePath forPiece:[myComponent objectForKey:ComponentNameKey] type:type withMyVersion:[myComponent objectForKey:BundleVersionKey] andAuthorization:NULL]; 
    279         } 
     379                [self installArchive:archivePath forPiece:[myComponent objectForKey:ComponentNameKey] type:type withMyVersion:[myComponent objectForKey:BundleVersionKey] andAuthorization:auth]; 
     380        } 
     381        if(auth != nil) 
     382                AuthorizationFree(auth, 0); 
    280383        [self performSelectorOnMainThread:@selector(installComplete:) withObject:nil waitUntilDone:NO]; 
    281384        [pool release]; 
     
    287390        NSDictionary *infoDict = [[self bundle] infoDictionary]; 
    288391        NSDictionary *myComponentsInfo = [infoDict objectForKey:ComponentInfoDictionaryKey]; 
    289          
    290         //XXX what about authorized 
     392        AuthorizationRef auth = nil; 
     393         
     394        if([self systemInstalled]) 
     395        { 
     396                if(!AuthorizationCreate(NULL, kAuthorizationEmptyEnvironment, kAuthorizationFlagDefaults, &auth) == errAuthorizationSuccess) 
     397                        // Try it anyway, it will likely fail, but who knows what kind of screwed up systems people have 
     398                        auth = nil; 
     399        } 
     400         
    291401        int tag = 0; 
    292402        BOOL result = [[NSWorkspace sharedWorkspace] performFileOperation:NSWorkspaceRecycleOperation source:[self quickTimeComponentDir] destination:@"" files:[NSArray arrayWithObject:@"Perian.component"] tag:&tag]; 
     
    309419                BOOL result = [[NSWorkspace sharedWorkspace] performFileOperation:NSWorkspaceRecycleOperation source:directory destination:@"" files:[myComponent objectForKey:ComponentNameKey] tag:&tag]; 
    310420        } 
     421        if(auth != nil) 
     422                AuthorizationFree(auth, 0); 
     423         
    311424        [self performSelectorOnMainThread:@selector(installComplete:) withObject:nil waitUntilDone:NO]; 
    312425        [pool release]; 
  • trunk/Perian.xcodeproj/project.pbxproj

    r239 r240  
    179179                8F483B5E0A6426C1002CCA73 /* AudioToolbox.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 8F483B5D0A6426C1002CCA73 /* AudioToolbox.framework */; }; 
    180180                8F483B8C0A642886002CCA73 /* PerianAviImporter.r in Rez */ = {isa = PBXBuildFile; fileRef = 8F483B8B0A642886002CCA73 /* PerianAviImporter.r */; }; 
     181                F53E18E50B4F483C003A0471 /* Security.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = F53E18E40B4F483C003A0471 /* Security.framework */; }; 
    181182                F59E09F10A670E570019A3F0 /* Perian.component in CopyFiles */ = {isa = PBXBuildFile; fileRef = 11A70AC10A3D0105002058D4 /* Perian.component */; }; 
    182183/* End PBXBuildFile section */ 
     
    417418                8F483BBC0A642B3D002CCA73 /* ff_MovieImportDispatch.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ff_MovieImportDispatch.h; sourceTree = "<group>"; }; 
    418419                F50D440703EAD8DF01B1D299 /* FFusion.icns */ = {isa = PBXFileReference; lastKnownFileType = image.icns; path = FFusion.icns; sourceTree = "<group>"; }; 
     420                F53E18E40B4F483C003A0471 /* Security.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Security.framework; path = /System/Library/Frameworks/Security.framework; sourceTree = "<absolute>"; }; 
    419421                F560DECD03D61B6101ABA332 /* Components.k.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Components.k.h; sourceTree = "<group>"; }; 
    420422                F560DEFC03D61BE301ABA332 /* FFusionCodec.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FFusionCodec.h; sourceTree = "<group>"; }; 
     
    460462                        files = ( 
    461463                                83D1D6CF0B4C7AC400E09EC9 /* PreferencePanes.framework in Frameworks */, 
     464                                F53E18E50B4F483C003A0471 /* Security.framework in Frameworks */, 
    462465                        ); 
    463466                        runOnlyForDeploymentPostprocessing = 0; 
     
    492495                                11D4EEFC0A3CE7FA0066D45F /* Carbon.framework */, 
    493496                                11D4EED50A3CE7EC0066D45F /* QuickTime.framework */, 
     497                                F53E18E40B4F483C003A0471 /* Security.framework */, 
    494498                        ); 
    495499                        name = "External Frameworks and Libraries";