objective c - NSTask for SSH using PTY -


i'm trying write app programmatically log in remote device using ssh expect script (i know can use expect in obj-c).

i have researched lot on , know need use pty. code have works fine telnet can't seem ssh work. seems though ssh not using pty ask password. when execute following code see device asking password, don't see nslog output.

i'm new , on head, i'd appreciate can me working.

#import <foundation/foundation.h> #import <util.h>  @interface nstask (pty)  - (nsfilehandle *)mastersideofptyorerror:(nserror **)error;  @end  @implementation nstask (pty)  - (nsfilehandle *)mastersideofptyorerror:(nserror *__autoreleasing *)error { int fdmaster, fdslave; int rc = openpty(&fdmaster, &fdslave, null, null, null); if (rc != 0) {     if (error) {         *error = [nserror errorwithdomain:nsposixerrordomain code:errno userinfo:nil];     }     return null; } fcntl(fdmaster, f_setfd, fd_cloexec); fcntl(fdslave, f_setfd, fd_cloexec); nsfilehandle *masterhandle = [[nsfilehandle alloc] initwithfiledescriptor:fdmaster closeondealloc:yes]; nsfilehandle *slavehandle = [[nsfilehandle alloc] initwithfiledescriptor:fdslave closeondealloc:yes]; self.standardinput = slavehandle; self.standardoutput = slavehandle; return masterhandle; }  @end 

int main(int argc, const char * argv[]) {  @autoreleasepool {      nstask *task = [[nstask alloc] init];      [task setlaunchpath:@"/usr/bin/ssh"];      [task setarguments:@[@"user@192.168.1.1"]];      nserror *error;     nsfilehandle *masterhandle = [task mastersideofptyorerror:&error];     if (!masterhandle) {         nslog(@"error: not set pty task: %@", error);         exit(0);     }      [task launch];      [masterhandle waitfordatainbackgroundandnotify];     nsmutablestring *buff = [[nsmutablestring alloc] init];     [[nsnotificationcenter defaultcenter] addobserverforname:nsfilehandledataavailablenotification                                                       object:masterhandle queue:nil                                                   usingblock:^(nsnotification *note)      {          nsdata *outdata = [masterhandle availabledata];          nsstring *outstr = [[nsstring alloc] initwithdata:outdata encoding:nsutf8stringencoding];          [buff appendstring:outstr];          nslog(@"output: %@", outstr);           nsregularexpression *regex = [nsregularexpression regularexpressionwithpattern:@"sername:"                                                                                 options:nsregularexpressioncaseinsensitive                                                                                   error:nil];          nstextcheckingresult *match = [regex firstmatchinstring:buff                                                          options:0                                                            range:nsmakerange(0, [buff length])];          if (match) {              nslog(@"got match!!");              [buff setstring:@""];              [masterhandle writedata:[@"bhughes\n" datausingencoding:nsutf8stringencoding]];          }           nslog(@"exiting function.\n");          [masterhandle waitfordatainbackgroundandnotify];      }];      [task waituntilexit];      nslog(@"program complete.\n"); } return 0; } 

as far know, nstask not support pty ability. working ssh requires interactive pty device context.

the simplest way forkpty, forks process itself, cannot used nstask.

finally wrote wrapper class manages forkpty. forks child process , calls forkpty , execve.

here's implementation: https://github.com/eonil/pseudoteletypewriter.swift

you can read/write using single master device file handle. confirmed sudo working, , believe ssh should work fine.


Comments

Popular posts from this blog

user interface - How to replace the Python logo in a Tkinter-based Python GUI app? -

objective c - Greedy NSProgressIndicator Allocation -

how to set an OCR language in Google Drive -