2011-06-03 14 views
8

W mojej aplikacji Cocoa próbuję użyć NSTask do uruchomienia podstawowych poleceń Git. Ilekroć uruchomić polecenie, które wymaga uprawnień (klucze SSH), aby uzyskać dostęp do zdalnego (np git push, git pull), nie powiedzie się z powodu następującego błędu:NSTask i Git - problemy z uprawnieniami

Permission denied (publickey). The remote end hung up unexpectedly

Running te same polecenia z terminala działa dobrze, więc jestem m myśli, że to może być problem z NSTask nie ustawianiem zmiennej środowiskowej, która byłaby używana gdzieś w procesie uzyskiwania dostępu do kluczy ssh. Próbowałem ręcznie ustawienie zmiennych środowiskowych HOME i USER tak:

[task setEnvironment:[NSDictionary dictionaryWithObjectsAndKeys:NSHomeDirectory(), @"HOME", NSUserName(), @"USER", nil]]; 

Ale to nie ma znaczenia. Czy jest jakaś konkretna zmienna środowiskowa, którą muszę ustawić w NSTask, aby to działało poprawnie?

EDYTOWANIE: Dzięki wskazówkom Dustina, udało mi się to trochę lepiej zrozumieć. Użyłem komendy env do listy zmiennych środowiskowych dla mojego bieżącej sesji i znalazłem to:

SSH_AUTH_SOCK=/tmp/launch-DMQopt/Listeners 

Aby przetestować, skopiowałem tę ścieżkę i ustawić go jako zmiennej środowiskowej z NSTask i pobiegł ponownie kod, a to czas to działało! To powiedziawszy, jestem pewien, że SSH_AUTH_SOCK zmienia się dla każdej sesji, więc nie mogę po prostu jej zakodować. Jak dynamicznie generować/pobierać tę zmienną?

+1

Wypróbuj w inny sposób, użyj 'env -i' w linii poleceń i zobacz, ile musisz dodać, zanim zadziała. – Dustin

+0

Trochę dalej dzięki twojej wskazówce, przeczytaj mój zredagowany wpis :) – indragie

Odpowiedz

4

Można spróbować i postępuj zgodnie z samouczka "Wrapping rsync or SSH in an NSTask" (z Ira), który wspomina SSH_AUTH_SOCK zmiennej:

Since writing this post I've realised that I omitted an important additional step in setting up the environment variables for the NSTask.
In order to make passwordless key-based authentication work it's necessary to grab the SSH_AUTH_SOCK variable from the user's environment and include this in the NSTask's environment.
So, when setting environment variables for example;

NSTask *task; 
NSDictionary *environmentDict = [[NSProcessInfo processInfo] environment]; 
// Environment variables needed for password based authentication 
NSMutableDictionary *env = [NSMutableDictionary dictionaryWithObjectsAndKeys: 
         @"NONE", @"DISPLAY",       askPassPath, @"SSH_ASKPASS", 
         userName,@"AUTH_USERNAME", 
         hostName,@"AUTH_HOSTNAME", 
         nil]; 

// Environment variable needed for key based authentication 
[env setObject:[environmentDict objectForKey:@"SSH_AUTH_SOCK"] forKey:@"SSH_AUTH_SOCK"]; 

// Setting the task's environment 
[task setEnvironment:env]; 

Jednak OP indragie Komentarze:

I had tried this earlier but since it was being invoked with XCode, the SSH_AUTH_SOCK env var. wasn't being passed to it.
Opening the app from Finder corrects this issue.



With askPassPath being the path for the Askpass executable, which is included as part of the application’s main bundle. (In order to do this, find the executable under “Products” in xcode, and then drag it into “Copy Bundle Resources” on the main application’s target.)

// Get the path of the Askpass program, which is 
// setup to be included as part of the main application bundle 
NSString *askPassPath = [NSBundle pathForResource:@"Askpass" 
       ofType:@"" 
       inDirectory:[[NSBundle mainBundle] bundlePath]]; 
+1

Próbowałem już wcześniej, ale ponieważ był wywoływany z Xcode, SSH_AUTH_SOCK env var. nie został do niego przekazany. Otwarcie aplikacji od Findera rozwiązuje ten problem. Dziękuję Ci! – indragie

+0

@indragie: Excellent. Włączyłem Twój komentarz w odpowiedzi, aby uzyskać lepszą widoczność. – VonC

+0

@VonC Czy możesz mi powiedzieć jaka zmienna jest askPassPath? –

Powiązane problemy