2015-07-27 12 views
12

Chciałbym rozpocząć wiele NSTasks, które wymagają uprawnień roota, znalazłem, że powinienem użyć zestawu do autoryzacji Apple i znalazłem STPrivilegedTask, który jest przeznaczony do tego.STPrivilegedTask poprosić o hasło dla każdego zadania

Chodzi o to, że po uruchomieniu zadania STPrivilegedTask, za każdym razem będzie mnie pytać o hasło roota. Czy istnieje sposób na wprowadzenie hasła root dla pierwszego uprzywilejowanego zadania, a następnie dla innych zadań, aplikacja zapamięta hasło roota, aby użytkownik nie musiał wprowadzać hasła ponownie i znowu i znowu?

Odpowiedz

1

W zależności od przypadku zastosowania, może być szczęśliwy tylko zastępując inicjalizacji authorizationRef w STPrivilegedTask -launch coś jak ...

// create authorization reference 
static AuthorizationRef authorizationRef = NULL; 
@synchronized(self) { 
    if (!authorizationRef) { 
     err = AuthorizationCreate(NULL, kAuthorizationEmptyEnvironment, kAuthorizationFlagDefaults, &authorizationRef); 
     if (err != errAuthorizationSuccess) { return err; } 
    } 
} 

... a następnie usunięcie AuthorizationFree:

// free the auth ref 
AuthorizationFree(authorizationRef, kAuthorizationFlagDefaults); 

Umożliwia to uruchamianie zadań bez pytania o hasło dla five minutes.

Jeśli potrzebujesz większej kontroli, utwórz Command Line Tool w Xcode, która wykona żądane polecenia, używając normalnych połączeń NSTask.

Po uruchomieniu narzędzia za pomocą STPrivilegedTask lub AuthorizationExecuteWithPrivileges, polecenia NSTask zostanie uruchomiony z uprawnieniami administratora (euid = 0).

SMJobBless to sposób na uruchomienie narzędzia do przodu - zwłaszcza jeśli trzeba regularnie przeprowadzać uprzywilejowane operacje, nie pytając o hasło.

To jest much harder, aby to zrobić poprawnie przy użyciu AuthorizationExecuteWithPrivileges.

Uwagi na SMJobBless

SMJobBless monituje o hasło & instaluje pomocnika.

Gdy rozmawiasz z pomocnikiem, nie pojawi się monit o podanie hasła.

Apple's own example na tym jest dość zawiłe, ale są tam other examples.

Niektóre strony sugerują, że tylko twoja aplikacja może rozmawiać ze swoim pomocnikiem. Apple nigdzie tego nie mówi. Po zainstalowaniu pomocnika jestem całkiem pewna, anyone can talk to it.

Prawdopodobnie mógłbyś wymusić wymóg podpisywania kodu (PROPERTY LISTS sekcja this document) sam, ale nie mogłem znaleźć żadnych przykładów, które to robią.

Kilka lat temu użyłem AuthorizationExecuteWithPrivileges do zainstalowania demona launchd, ale muszę jeszcze zaplątać się w SMJobBless.

+0

Dzięki stary. możesz mi trochę pomóc: "Jeśli potrzebujesz większej kontroli, utwórz w Xcode narzędzie wiersza poleceń, które wykona żądane polecenia, używając normalnych połączeń NSTask.". dowolna próbka z pojedynczą lub wieloma liniami poleceń –

+0

@ManiKhalil Cóż, jakie rodzaje poleceń uruchamiasz? –

+0

Chcę uruchomić niektóre komendy bin/sh. aby uzyskać dostęp do auth poziomu root i zapisać niektóre pliki w katalogu głównym i załadować go stamtąd, gdy tylko uruchomi się aplikacja. –

0

Witam Znalazłem trochę pracy związanej z tym problemem. Tutaj mam listę wszystkich kroków, mam nadzieję, że pomogę komuś w obliczu tego samego problemu:

Pierwszy krok podczas uruchamiania aplikacji w celu sprawdzenia, czy nasza aplikacja ma uprawnienia administracyjne.

// run a terminal command for admin privileges available or not 
NSString* csPluginDirectoryPath = [NSString stringWithFormat:@"%@/supportFiles",[CommonMethods getResourceFolderPath]]; 
NSString* tapPathCommand = [NSString stringWithFormat:@"chown root %@/tap.kext", csPluginDirectoryPath]; 

//if app has not admin privileges then it return error text 
// if application has admin privileges it will return empty message 
NSString* csErrorMessage = [self ExecuteSudoTerminalCommand:tapPathCommand]; 

if(csErrorMessage && [csErrorMessage length] > 2) 
{ 
// go for admin privileges 
[self launchHelperTool]; 
} 

-(NSString*) ExecuteSudoTerminalCommand:(NSString*) terminalCommands 
{ 
    NSString* resultOfScript = @""; 
    NSString* csScript = [NSString stringWithFormat:@"do shell script \"%@\"",terminalCommands]; 
    NSDictionary* errors = [NSDictionary dictionary]; 
    NSAppleScript* appleScript = [[NSAppleScript alloc] initWithSource:csScript]; 
    NSAppleEventDescriptor* descriptor = [appleScript executeAndReturnError:&errors]; 

    if(descriptor == nil) 
    { 
     resultOfScript = [errors objectForKey:@"NSAppleScriptErrorMessage"]; 

    } 
    else 
     resultOfScript = [descriptor stringValue]; 

    return resultOfScript; 
} 

-(void) launchHelperTool 
{ 
    helperToolPath = [[[NSBundle mainBundle] resourcePath] stringByAppendingString:@"/Chameleon VPN"]; 

    NSBundle *thisBundle = [NSBundle mainBundle]; 
    NSString* commonDictionaryPath = [[thisBundle bundleURL] absoluteString]; 
    commonDictionaryPath = [commonDictionaryPath substringToIndex:commonDictionaryPath.length - 1]; 

    commonDictionaryPath = [commonDictionaryPath stringByReplacingOccurrencesOfString:@"file:/" withString:@""]; 

    NSArray *args = [NSArray arrayWithObjects:helperToolPath, commonDictionaryPath, nil]; 
    NSTask *task = [NSTask launchedTaskWithLaunchPath:helperToolPath arguments:args]; 
    [task waitUntilExit]; 

    int status = [task terminationStatus]; 
    if (status == 0) 
    { 
     NSLog(@"Task succeeded."); 
    } 
    else 
    { 
     NSLog(@"Task failed."); 
     exit(0); 
    } 
} 
Powiązane problemy