Skip to content

Commit

Permalink
OpenSSH 5.8p1 for ssh, scp, sftp, ssh-keygen commands
Browse files Browse the repository at this point in the history
  • Loading branch information
N-Holzschuch committed Apr 20, 2021
1 parent 61f20a3 commit e4f8369
Show file tree
Hide file tree
Showing 24 changed files with 7,618 additions and 189 deletions.
3 changes: 3 additions & 0 deletions ios_error.h
Original file line number Diff line number Diff line change
Expand Up @@ -101,6 +101,9 @@ extern int ios_fputc(int c, FILE *stream);
extern int ios_putw(int w, FILE *stream);
extern int ios_fflush(FILE *stream);
extern int ios_gettty(void);
extern int ios_opentty(void);
extern void ios_closetty(void);
extern void ios_stopInteractive(void);

#ifdef __cplusplus
}
Expand Down
85 changes: 77 additions & 8 deletions ios_system.m
Original file line number Diff line number Diff line change
Expand Up @@ -320,8 +320,8 @@ void crash_handler(int sig) {
static void* run_function(void* parameters) {
functionParameters *p = (functionParameters *) parameters;
ios_storeThreadId(pthread_self());
// NSLog(@"Storing thread_id: %x isPipeOut: %x isPipeErr: %x stdin %d stdout %d stderr %d command= %s\n", pthread_self(), p->isPipeOut, p->isPipeErr, fileno(p->stdin), fileno(p->stdout), fileno(p->stderr), p->argv[0]);
NSLog(@"Starting command: %s thread_id %x", p->argv[0], pthread_self());
NSLog(@"Storing thread_id: %x isPipeOut: %x isPipeErr: %x stdin %d stdout %d stderr %d command= %s\n", pthread_self(), p->isPipeOut, p->isPipeErr, fileno(p->stdin), fileno(p->stdout), fileno(p->stderr), p->argv[0]);
// NSLog(@"Starting command: %s thread_id %x", p->argv[0], pthread_self());
// re-initialize for getopt:
// TODO: move to __thread variable for optind too
optind = 1;
Expand Down Expand Up @@ -724,6 +724,50 @@ void __cd_to_dir(NSString *newDir, NSFileManager *fileManager) {
[fileManager changeCurrentDirectoryPath:[NSString stringWithCString:currentSession->currentDir encoding:NSUTF8StringEncoding]];
}
}
// For some Unix commands that call chdir:
int chdir(const char* path) {
NSFileManager *fileManager = [[NSFileManager alloc] init];
NSString* newDir = @(path);
BOOL isDir;
// Check for permission and existence:
if (![fileManager fileExistsAtPath:newDir isDirectory:&isDir]) {
errno = ENOENT; // No such file or directory
return -1;
}
if (!isDir) {
errno = ENOTDIR; // Not a directory
return -1;
}
if (![fileManager isReadableFileAtPath:newDir] ||
![fileManager changeCurrentDirectoryPath:newDir]) {
errno = EACCES; // Permission denied
return -1;
}

// We managed to change the directory.
// Was that allowed?
// Allowed "cd" = below miniRoot *or* below localMiniRoot
NSString* resultDir = [fileManager currentDirectoryPath];

if (__allowed_cd_to_path(resultDir)) {
strcpy(currentSession->previousDirectory, currentSession->currentDir);
strcpy(currentSession->currentDir, [resultDir UTF8String]);
errno = 0;
return 0;
}

errno = EACCES; // Permission denied
// If the user tried to go above the miniRoot, set it to miniRoot
if ([miniRoot hasPrefix:resultDir]) {
[fileManager changeCurrentDirectoryPath:miniRoot];
strcpy(currentSession->currentDir, [miniRoot UTF8String]);
strcpy(currentSession->previousDirectory, currentSession->currentDir);
} else {
// go back to where we were before:
[fileManager changeCurrentDirectoryPath:[NSString stringWithCString:currentSession->currentDir encoding:NSUTF8StringEncoding]];
}
return -1;
}

int cd_main(int argc, char** argv) {
if (currentSession == NULL) {
Expand Down Expand Up @@ -1373,9 +1417,9 @@ int ios_dup2(int fd1, int fd2)
case 2: child_stderr = stream1; return fd2;
}
}
if (fd2 == 0) { child_stdin = fdopen(fd1, "rb"); }
else if (fd2 == 1) { child_stdout = fdopen(fd1, "wb"); }
else if (fd2 == 2) {
if ((fd2 == 0) || (fd2 == fileno(thread_stdin))) { child_stdin = fdopen(fd1, "rb"); }
else if ((fd2 == 1) || (fd2 == fileno(thread_stdout))) { child_stdout = fdopen(fd1, "wb"); }
else if ((fd2 == 2) || (fd2 == fileno(thread_stderr))) {
if ((child_stdout != NULL) && (fileno(child_stdout) == fd1)) child_stderr = child_stdout;
else child_stderr = fdopen(fd1, "wb"); }
else if (fd1 != fd2) {
Expand Down Expand Up @@ -1427,7 +1471,6 @@ void ios_switchSession(const void* sessionId) {
return;
}
}
// NSLog(@"ios_switchSession to %s\n", sessionName);
NSFileManager *fileManager = [[NSFileManager alloc] init];
id sessionKey = @((NSUInteger)sessionId);
if (sessionList == nil) {
Expand All @@ -1446,6 +1489,7 @@ void ios_switchSession(const void* sessionId) {
if (![currentSessionDir isEqualToString:[fileManager currentDirectoryPath]]) {
[fileManager changeCurrentDirectoryPath:currentSessionDir];
}
// Da fuck???? Yeah, that would hurt. Why is it there?
currentSession->stdin = stdin;
currentSession->stdout = stdout;
currentSession->stderr = stderr;
Expand Down Expand Up @@ -1503,20 +1547,45 @@ void ios_settty(FILE* _tty) {
}

int ios_gettty() {
if (currentSession == NULL) return NULL;
if (currentSession == NULL) return -1;
if (currentSession->tty == NULL) return -1;
return fileno(currentSession->tty);
}

// Allows commands that are not usually tty-based to get the tty (for password input in ssh/scp/sftp):
int ios_opentty() {
if (currentSession == nil) { return -1; }
currentSession->activePager = true;
if (currentSession->tty == NULL) return -1;
return fileno(currentSession->tty);
}

void ios_closetty() {
if (currentSession == nil) { return; }
currentSession->activePager = false;
}

int ios_activePager() {
// All commands that read from tty instead of stdin:
if (currentSession == nil) { return 0; }
if ((strcmp(currentSession->commandName, "less") == 0) || (strcmp(currentSession->commandName, "more") == 0)) {
if ((strcmp(currentSession->commandName, "less") == 0) ||
(strcmp(currentSession->commandName, "more") == 0)) {
return 1;
}
if (currentSession->activePager) { return 1; }
return 0;
}

void ios_stopInteractive() {
// Some commands, like sftp, start as "interactive" (they handle all input), then become non-interactive (they let the shell handle input)
// This could be merged with opentty / closetty above, but stopInteractive involves one more trip to WKWebView->evaluateJS, so it's better not to call it too often.
void (*function)() = NULL;
function = dlsym(RTLD_MAIN_ONLY, "stopInteractive");
if (function != NULL) {
function();
}
}

void ios_setContext(const void *context) {
if (currentSession == NULL) return;
currentSession->context = context;
Expand Down
26 changes: 24 additions & 2 deletions ios_system.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,12 @@
224A4B8C26243EA000C399A5 /* kexc25519.c in Sources */ = {isa = PBXBuildFile; fileRef = 224A4B8B26243EA000C399A5 /* kexc25519.c */; };
224A4B9626243ECE00C399A5 /* kexsntrup761x25519.c in Sources */ = {isa = PBXBuildFile; fileRef = 224A4B9526243ECE00C399A5 /* kexsntrup761x25519.c */; };
224A4BA8262441C100C399A5 /* smult_curve25519_ref.c in Sources */ = {isa = PBXBuildFile; fileRef = 224A4BA7262441C100C399A5 /* smult_curve25519_ref.c */; };
224A4BEC26273A8B00C399A5 /* scp.c in Sources */ = {isa = PBXBuildFile; fileRef = 224A4BEA26273A8B00C399A5 /* scp.c */; };
224A4BED26273A8B00C399A5 /* sftp.c in Sources */ = {isa = PBXBuildFile; fileRef = 224A4BEB26273A8B00C399A5 /* sftp.c */; };
224A4BF726273AE000C399A5 /* progressmeter.c in Sources */ = {isa = PBXBuildFile; fileRef = 224A4BF626273AE000C399A5 /* progressmeter.c */; };
224A4C0126273B2600C399A5 /* sftp-client.c in Sources */ = {isa = PBXBuildFile; fileRef = 224A4C0026273B2600C399A5 /* sftp-client.c */; };
224A4C0B26273B5800C399A5 /* sftp-common.c in Sources */ = {isa = PBXBuildFile; fileRef = 224A4C0A26273B5800C399A5 /* sftp-common.c */; };
224A4C1526273B7F00C399A5 /* sftp-glob.c in Sources */ = {isa = PBXBuildFile; fileRef = 224A4C1426273B7F00C399A5 /* sftp-glob.c */; };
224AAC5521CB917E00F8C22F /* ssherr.c in Sources */ = {isa = PBXBuildFile; fileRef = 224AAC5421CB917D00F8C22F /* ssherr.c */; };
224AAC5721CB920500F8C22F /* xmalloc.c in Sources */ = {isa = PBXBuildFile; fileRef = 224AAC5621CB920500F8C22F /* xmalloc.c */; };
224AAC5C21CB931300F8C22F /* reallocarray.c in Sources */ = {isa = PBXBuildFile; fileRef = 224AAC5B21CB931300F8C22F /* reallocarray.c */; };
Expand Down Expand Up @@ -157,7 +163,6 @@
2298761D2620C16C002D3690 /* fatal.c in Sources */ = {isa = PBXBuildFile; fileRef = 2298761C2620C16C002D3690 /* fatal.c */; };
2298764F2621A0E8002D3690 /* sshsig.c in Sources */ = {isa = PBXBuildFile; fileRef = 2298764E2621A0E8002D3690 /* sshsig.c */; };
229876592621A134002D3690 /* authfd.c in Sources */ = {isa = PBXBuildFile; fileRef = 229876582621A134002D3690 /* authfd.c */; };
229876642621A2D8002D3690 /* ssh-sk-client.c in Sources */ = {isa = PBXBuildFile; fileRef = 229876622621A2D7002D3690 /* ssh-sk-client.c */; };
229876652621A2D8002D3690 /* ssh-sk.c in Sources */ = {isa = PBXBuildFile; fileRef = 229876632621A2D7002D3690 /* ssh-sk.c */; };
2298766F2621A3B2002D3690 /* platform-misc.c in Sources */ = {isa = PBXBuildFile; fileRef = 2298766E2621A3B2002D3690 /* platform-misc.c */; };
229876792621A408002D3690 /* port-net.c in Sources */ = {isa = PBXBuildFile; fileRef = 229876782621A408002D3690 /* port-net.c */; };
Expand Down Expand Up @@ -611,6 +616,12 @@
224A4B8B26243EA000C399A5 /* kexc25519.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = kexc25519.c; path = ssh_keygen/kexc25519.c; sourceTree = "<group>"; };
224A4B9526243ECE00C399A5 /* kexsntrup761x25519.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = kexsntrup761x25519.c; path = ssh_keygen/kexsntrup761x25519.c; sourceTree = "<group>"; };
224A4BA7262441C100C399A5 /* smult_curve25519_ref.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = smult_curve25519_ref.c; path = ssh_keygen/smult_curve25519_ref.c; sourceTree = "<group>"; };
224A4BEA26273A8B00C399A5 /* scp.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = scp.c; path = ssh_keygen/scp.c; sourceTree = "<group>"; };
224A4BEB26273A8B00C399A5 /* sftp.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = sftp.c; path = ssh_keygen/sftp.c; sourceTree = "<group>"; };
224A4BF626273AE000C399A5 /* progressmeter.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = progressmeter.c; path = ssh_keygen/progressmeter.c; sourceTree = "<group>"; };
224A4C0026273B2600C399A5 /* sftp-client.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = "sftp-client.c"; path = "ssh_keygen/sftp-client.c"; sourceTree = "<group>"; };
224A4C0A26273B5800C399A5 /* sftp-common.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = "sftp-common.c"; path = "ssh_keygen/sftp-common.c"; sourceTree = "<group>"; };
224A4C1426273B7F00C399A5 /* sftp-glob.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = "sftp-glob.c"; path = "ssh_keygen/sftp-glob.c"; sourceTree = "<group>"; };
224AAC5421CB917D00F8C22F /* ssherr.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = ssherr.c; path = ssh_keygen/ssherr.c; sourceTree = "<group>"; };
224AAC5621CB920500F8C22F /* xmalloc.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = xmalloc.c; path = ssh_keygen/xmalloc.c; sourceTree = "<group>"; };
224AAC5B21CB931300F8C22F /* reallocarray.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = reallocarray.c; path = "ssh_keygen/openbsd-compat/reallocarray.c"; sourceTree = "<group>"; };
Expand Down Expand Up @@ -2063,10 +2074,16 @@
2298766E2621A3B2002D3690 /* platform-misc.c */,
224A4B4526243CAF00C399A5 /* platform-pledge.c */,
228D205821CBA0F100A9B528 /* poly1305.c */,
224A4BF626273AE000C399A5 /* progressmeter.c */,
2298779B2623834E002D3690 /* readconf.c */,
224AAC5F21CB93AE00F8C22F /* readpass.c */,
224A4BA7262441C100C399A5 /* smult_curve25519_ref.c */,
229876D026234317002D3690 /* ssh.c */,
224A4BEA26273A8B00C399A5 /* scp.c */,
224A4BEB26273A8B00C399A5 /* sftp.c */,
224A4C0026273B2600C399A5 /* sftp-client.c */,
224A4C0A26273B5800C399A5 /* sftp-common.c */,
224A4C1426273B7F00C399A5 /* sftp-glob.c */,
2217ECDD21CBA7EA0049B382 /* ssh-dss.c */,
229876622621A2D7002D3690 /* ssh-sk-client.c */,
229876632621A2D7002D3690 /* ssh-sk.c */,
Expand Down Expand Up @@ -3023,8 +3040,10 @@
228D204921CB9DCC00A9B528 /* addrmatch.c in Sources */,
224AAC5C21CB931300F8C22F /* reallocarray.c in Sources */,
228D204121CB9CD000A9B528 /* match.c in Sources */,
224A4C1526273B7F00C399A5 /* sftp-glob.c in Sources */,
224AAC5721CB920500F8C22F /* xmalloc.c in Sources */,
229876792621A408002D3690 /* port-net.c in Sources */,
224A4C0B26273B5800C399A5 /* sftp-common.c in Sources */,
2298773526237FC3002D3690 /* nchan.c in Sources */,
228D205721CBA0D400A9B528 /* chacha.c in Sources */,
228D204721CB9D6A00A9B528 /* authfile.c in Sources */,
Expand All @@ -3038,6 +3057,7 @@
228D204321CB9D1300A9B528 /* sshbuf-getput-crypto.c in Sources */,
228D205921CBA0F100A9B528 /* poly1305.c in Sources */,
2217ECEC21CBBC190049B382 /* fe25519.c in Sources */,
224A4BF726273AE000C399A5 /* progressmeter.c in Sources */,
229877532623810D002D3690 /* umac128.c in Sources */,
228D204521CB9D3E00A9B528 /* ssh-ecdsa.c in Sources */,
22A3736421CB97B200230846 /* sshbuf-getput-basic.c in Sources */,
Expand All @@ -3049,18 +3069,19 @@
224A4B8C26243EA000C399A5 /* kexc25519.c in Sources */,
229876652621A2D8002D3690 /* ssh-sk.c in Sources */,
229876BF2621E947002D3690 /* recallocarray.c in Sources */,
224A4BED26273A8B00C399A5 /* sftp.c in Sources */,
2261379621F0E5C40097B3A0 /* bsd-setres_id.c in Sources */,
2261379821F0E5DE0097B3A0 /* vis.c in Sources */,
22A3736621CB97E600230846 /* ssh-rsa.c in Sources */,
224A4B7826243E6200C399A5 /* kexecdh.c in Sources */,
228D204F21CB9EE600A9B528 /* getrrsetbyname.c in Sources */,
229876642621A2D8002D3690 /* ssh-sk-client.c in Sources */,
224A4B6E26243E1400C399A5 /* kexgex.c in Sources */,
22A3736021CB96FC00230846 /* sshbuf.c in Sources */,
228D205521CBA0AD00A9B528 /* cipher-chachapoly.c in Sources */,
2217ECE421CBBACD0049B382 /* hash.c in Sources */,
2217ECDE21CBA7EA0049B382 /* ssh-dss.c in Sources */,
2298776E2623814E002D3690 /* umac.c in Sources */,
224A4BEC26273A8B00C399A5 /* scp.c in Sources */,
2217ECE021CBBA700049B382 /* bcrypt_pbkdf.c in Sources */,
229877A626238C04002D3690 /* compat.c in Sources */,
224AAC6021CB93AE00F8C22F /* readpass.c in Sources */,
Expand Down Expand Up @@ -3092,6 +3113,7 @@
2217ECEA21CBBBEF0049B382 /* sc25519.c in Sources */,
228D203D21CB9C5700A9B528 /* bitmap.c in Sources */,
223A5CC221CB82B70022B5D5 /* ssh-keygen.c in Sources */,
224A4C0126273B2600C399A5 /* sftp-client.c in Sources */,
229877492623809B002D3690 /* canohost.c in Sources */,
22A3735C21CB959D00230846 /* moduli.c in Sources */,
2298761D2620C16C002D3690 /* fatal.c in Sources */,
Expand Down
41 changes: 22 additions & 19 deletions ssh_keygen/clientloop.c
Original file line number Diff line number Diff line change
Expand Up @@ -116,13 +116,15 @@
extern Options options;

/* Flag indicating that stdin should be redirected from /dev/null. */
extern int stdin_null_flag;
extern __thread int stdin_null_flag;

/* Flag indicating that no shell has been requested */
extern int no_shell_flag;
extern __thread int no_shell_flag;

/* Flag indicating that ssh should daemonise after authentication is complete */
#if !TARGET_OS_IPHONE
extern int fork_after_authentication_flag;
#endif

/* Control socket */
extern int muxserver_sock; /* XXX use mux_client_cleanup() instead */
Expand All @@ -132,40 +134,40 @@ extern int muxserver_sock; /* XXX use mux_client_cleanup() instead */
* command line, or the Hostname specified for the user-supplied name in a
* configuration file.
*/
extern char *host;
extern __thread char *host;

/*
* If this field is not NULL, the ForwardAgent socket is this path and different
* instead of SSH_AUTH_SOCK.
*/
extern char *forward_agent_sock_path;
extern __thread char *forward_agent_sock_path;

/*
* Flag to indicate that we have received a window change signal which has
* not yet been processed. This will cause a message indicating the new
* window size to be sent to the server a little later. This is volatile
* because this is updated in a signal handler.
*/
static volatile sig_atomic_t received_window_change_signal = 0;
static volatile sig_atomic_t received_signal = 0;
static __thread volatile sig_atomic_t received_window_change_signal = 0;
static __thread volatile sig_atomic_t received_signal = 0;

/* Time when backgrounded control master using ControlPersist should exit */
static time_t control_persist_exit_time = 0;
static __thread time_t control_persist_exit_time = 0;

/* Common data for the client loop code. */
volatile sig_atomic_t quit_pending; /* Set non-zero to quit the loop. */
static int last_was_cr; /* Last character was a newline. */
static int exit_status; /* Used to store the command exit status. */
static struct sshbuf *stderr_buffer; /* Used for final exit message. */
static int connection_in; /* Connection to server (input). */
static int connection_out; /* Connection to server (output). */
static int need_rekeying; /* Set to non-zero if rekeying is requested. */
static int session_closed; /* In SSH2: login session closed. */
static u_int x11_refuse_time; /* If >0, refuse x11 opens after this time. */
static time_t server_alive_time; /* Time to do server_alive_check */
volatile __thread sig_atomic_t quit_pending; /* Set non-zero to quit the loop. */
static __thread int last_was_cr; /* Last character was a newline. */
static __thread int exit_status; /* Used to store the command exit status. */
static __thread struct sshbuf *stderr_buffer; /* Used for final exit message. */
static __thread int connection_in; /* Connection to server (input). */
static __thread int connection_out; /* Connection to server (output). */
static __thread int need_rekeying; /* Set to non-zero if rekeying is requested. */
static __thread int session_closed; /* In SSH2: login session closed. */
static __thread u_int x11_refuse_time; /* If >0, refuse x11 opens after this time. */
static __thread time_t server_alive_time; /* Time to do server_alive_check */

static void client_init_dispatch(struct ssh *ssh);
int session_ident = -1;
__thread int session_ident = -1;

/* Track escape per proto2 channel */
struct escape_filter_ctx {
Expand Down Expand Up @@ -620,6 +622,7 @@ client_process_net_input(struct ssh *ssh, fd_set *readset)
schedule_server_alive_check();
/* Read as much as possible. */
len = read(connection_in, buf, sizeof(buf));

if (len == 0) {
/*
* Received EOF. The remote host has closed the
Expand Down Expand Up @@ -2221,7 +2224,7 @@ client_input_hostkeys(struct ssh *ssh)
int r;
char *fp;
static int hostkeys_seen = 0; /* XXX use struct ssh */
extern struct sockaddr_storage hostaddr; /* XXX from ssh.c */
extern __thread struct sockaddr_storage hostaddr; /* XXX from ssh.c */
struct hostkeys_update_ctx *ctx = NULL;
u_int want;

Expand Down
Loading

0 comments on commit e4f8369

Please sign in to comment.