From a819ec4e227a748e3d3a9bb6a4fb6c50b9bbf18b Mon Sep 17 00:00:00 2001 From: mssalvatore Date: Tue, 9 Apr 2019 15:20:35 -0400 Subject: Gracefully handle multiple spaces in ssh_command option (#168) When using the "ssh_command" option, commands with multiple spaces in a row will not be properly parsed. Example: Properly parsed: ssh_command = "ssh -o IdentityFile=~/.ssh/id_rsa" Improperly parsed: ssh_command = "ssh -o IdentityFile=~/.ssh/id_rsa" This commit changes the ssh_command parsing logic so that both of the above examples are considered valid and properly handled. Resolves #114. --- ChangeLog.rst | 5 ++++ sshfs.c | 78 +++++++++++++++++++++++++++++++++++++---------------------- 2 files changed, 54 insertions(+), 29 deletions(-) diff --git a/ChangeLog.rst b/ChangeLog.rst index 9e91ce8..ddb6c08 100644 --- a/ChangeLog.rst +++ b/ChangeLog.rst @@ -1,3 +1,8 @@ +Unreleased Changes +------------------------- + +* Fixed improper handling of sequential spaces spaces in "ssh_command" option + Release 2.10 (2017-08-03) ------------------------- diff --git a/sshfs.c b/sshfs.c index f28f2ce..f282a91 100644 --- a/sshfs.c +++ b/sshfs.c @@ -3546,40 +3546,60 @@ static int read_password(void) return 0; } +// Behaves similarly to strtok(), but allows for the ' ' delimiter to be escaped +// by '\ '. +static char *tokenize_on_space(char *str) +{ + static char *pos = NULL; + char *start = NULL; + + if (str) + pos = str; + + if (!pos) + return NULL; + + // trim any leading spaces + while (*pos == ' ') + pos++; + + start = pos; + + while (pos && *pos != '\0') { + // break on space, but not on '\ ' + if (*pos == ' ' && *(pos - 1) != '\\') { + break; + } + pos++; + } + + if (*pos == '\0') { + pos = NULL; + } + else { + *pos = '\0'; + pos++; + } + + return start; +} + static void set_ssh_command(void) { - char *s; - char *d; + char *token = NULL; int i = 0; - int end = 0; - - d = sshfs.ssh_command; - s = sshfs.ssh_command; - while (!end) { - switch (*s) { - case '\0': - end = 1; - case ' ': - *d = '\0'; - if (i == 0) { - replace_arg(&sshfs.ssh_args.argv[0], - sshfs.ssh_command); - } else { - if (fuse_opt_insert_arg(&sshfs.ssh_args, i, - sshfs.ssh_command) == -1) - _exit(1); - } - i++; - d = sshfs.ssh_command; - break; - case '\\': - if (s[1]) - s++; - default: - *d++ = *s; + token = tokenize_on_space(sshfs.ssh_command); + while (token != NULL) { + if (i == 0) { + replace_arg(&sshfs.ssh_args.argv[0], token); + } else { + if (fuse_opt_insert_arg(&sshfs.ssh_args, i, token) == -1) + _exit(1); } - s++; + i++; + + token = tokenize_on_space(NULL); } } -- cgit v1.2.3