CocoaDev

Edit AllPages

Any help on this would be appreciated. I am trying to launch an SSH session from a NSTask, but keep receiving the following errors on launch:

Pseudo-terminal will not be allocated because stdin is not a terminal. Permission denied, please try again. Permission denied, please try again. Permission denied (gssapi,publickey,password,keyboard-interactive).

Does anybody know of a way to set a NSPipe or NSFileHandle to emulate a terminal? Currently my relevant code looks as follows:

myTask = [[NSTask alloc] init]; inputPipe = [[NSPipe alloc] init]; inputHandle = [inputPipe fileHandleForReading];

[myTask setStandardInput:inputHandle]; [myTask setLaunchPath:@”/usr/bin/ssh”]; [myTask setArguments:[NSArray arrayWithObjects:@”-l”, [kci UserName], Location, nil]];

[myTask launch];

The basic problem that I am attempting to overcome is the need to pass in to the password to SSH after the task has been launched. If anybody can direct me to a good resource for this I would be grateful. So far Google, Apple Discussions, and macoshints have all turned up dry.


An easy solution is to generate a public/private key pair with ssh-keygen, that way, ssh won’t request a password.


Thanks for the quick responce, but unfortunately due to the setup/restrictions that the program may have to operate under ssh-keygen is not an option.


Try this commad format: ssh name:password@domain


as logical as that would seem, it doesn’t work. ssh still requests a password. having done some more digging it appears that I need to set two environmental variables. SSH_ASKPASS and DISPLAY. I know that these can be set by calling setEnvironment:… but I have no clue as to what they should be set as. anybody have an idea? Thanks


I believe DISPLAY is used for to designate an XWindows display for ssh to use during an X terminal session.


Take a look at cvsFinder which runs ssh and reads output. http://cvs.sourceforge.net/viewcvs.py/cvsfinder/src/cvsCommands/CVS_Module.m?rev=1.3&view=auto

		// see CVS_sshGetPassword for more on how SSH_ASKPASS works
		NSString *keyArray[] = {@"CVS_RSH", @"DISPLAY", @"SSH_ASKPASS"};
		NSString *valueArray[] = {@"ssh", @"localhost", NULL};
		NSBundle *bundle = [NSBundle bundleForClass:[self class]];
		valueArray[2] = [bundle pathForResource:File_sshPassTool ofType:@""];
		dict = [NSDictionary dictionaryWithObjects:valueArray
					forKeys:keyArray count:3];
		DEBUGS(NSLog(@"Env is %@", dict));

Note: According to

http://developer.apple.com/documentation/Cocoa/Reference/Foundation/ObjC_classic/Classes/NSTask.html#//apple_ref/doc/uid/20000317/BJFDJCCA

passing the filehandler for a NSPipe is a BAD IDEA. You should instead pass the pipe directly. IE use the following code.

myTask = [[NSTask alloc] init]; inputPipe = [[NSPipe alloc] init]; inputHandle = [inputPipe fileHandleForReading];

[myTask setStandardInput: inputPipe]; [myTask setLaunchPath:@”/usr/bin/ssh”]; [myTask setArguments:[NSArray arrayWithObjects:@”-l”, [kci UserName], Location, nil]];

[myTask launch];

You can use the inputHandle to access the pipes contents with out a problem.