NSTask и Git - Проблемы с разрешениями - PullRequest
9 голосов
/ 03 июня 2011

В моем приложении Какао я пытаюсь использовать NSTask для запуска некоторых основных команд Git.Всякий раз, когда я запускаю команду, которой требуются разрешения (ключи SSH) для доступа к удаленному устройству (например, git push, git pull), происходит сбой со следующей ошибкой:

В доступе отказано (publickey).Удаленный конец неожиданно зависает

Выполнение тех же команд из Терминала работает просто отлично, поэтому я думаю, что это может быть проблемой, если NSTask не задает переменную среды, которая будет использоваться где-тов процессе доступа к ключам SSH.Я попытался вручную установить переменные окружения HOME и USER следующим образом:

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

Но это не имеет никакого эффекта.Есть ли какая-то конкретная переменная окружения, которую я должен установить в NSTask, чтобы это работало должным образом?

РЕДАКТИРОВАТЬ: Благодаря совету Дастина, я получил немного больше, чтобы выяснить это.Я использовал команду env, чтобы вывести список переменных среды для моего текущего сеанса, и обнаружил следующее:

SSH_AUTH_SOCK=/tmp/launch-DMQopt/Listeners

Чтобы проверить, я скопировал этот путь и установил его в качестве переменной среды NSTask и запустилкод снова, и на этот раз это сработало!Тем не менее, я уверен, что SSH_AUTH_SOCK меняется для каждой сессии, поэтому я не могу просто жестко закодировать его.Как мне динамически генерировать / извлекать эту переменную?

1 Ответ

4 голосов
/ 03 июня 2011

Вы можете попробовать следовать учебнику " Обертывание rsync или SSH в NSTask " (от Ира ), в котором упоминается SSH_AUTH_SOCK переменная:

С момента написания этого поста я понял, что пропустил важный дополнительный шаг при настройке переменных среды для NSTask.
Чтобы заставить работать аутентификацию на основе пароля без пароля, необходимо захватить SSH_AUTH_SOCK переменная из среды пользователя и включить ее в среду NSTask .
Так, например, при настройке переменных среды;

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];

Однако OP indragie комментарии:

Я пробовал это раньше, но так как он вызывался с XCode, SSH_AUTH_SOCK env var.не было передано ему.
Открытие приложения из Finder исправляет эту проблему .



С askPassPath - путь к исполняемому файлу Askpass, который входит в состав основного пакета приложения.(Для этого найдите исполняемый файл в разделе «Products» в xcode, а затем перетащите его в «Copy Bundle Resources» на цели основного приложения.)

// 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]];
...