diff options
author | John DeHelian <john.de.helian@cranepi.com> | 2017-12-08 11:31:01 -0500 |
---|---|---|
committer | Daniel Stenberg <daniel@haxx.se> | 2017-12-09 13:38:38 +0100 |
commit | a4a56ec93e727293f30074f4eac24c19110bd39d (patch) | |
tree | da8c65c9dc9a14e1a1cbf3c6640310b59a507edf | |
parent | 9fb5a943f56496fabd9dc4de6b4b27a2404bfe79 (diff) |
sftp: allow quoted commands to use relative paths
Closes #1900
-rw-r--r-- | lib/curl_path.c | 34 | ||||
-rw-r--r-- | lib/curl_path.h | 3 | ||||
-rw-r--r-- | lib/ssh-libssh.c | 8 | ||||
-rw-r--r-- | lib/ssh.c | 8 |
4 files changed, 34 insertions, 19 deletions
diff --git a/lib/curl_path.c b/lib/curl_path.c index cd6592096..e843deac7 100644 --- a/lib/curl_path.c +++ b/lib/curl_path.c @@ -110,21 +110,25 @@ CURLcode Curl_getworkingpath(struct connectdata *conn, * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ -CURLcode Curl_get_pathname(const char **cpp, char **path) +CURLcode Curl_get_pathname(const char **cpp, char **path, char *homedir) { const char *cp = *cpp, *end; char quot; unsigned int i, j; + size_t fullPathLength, pathLength; + bool relativePath = false; static const char WHITESPACE[] = " \t\r\n"; - cp += strspn(cp, WHITESPACE); if(!*cp) { - *cpp = cp; + *cpp = NULL; *path = NULL; return CURLE_QUOTE_ERROR; } - - *path = malloc(strlen(cp) + 1); + /* Ignore leading whitespace */ + cp += strspn(cp, WHITESPACE); + /* Allocate enough space for home directory and filename + separator */ + fullPathLength = strlen(cp) + strlen(homedir) + 2; + *path = malloc(fullPathLength); if(*path == NULL) return CURLE_OUT_OF_MEMORY; @@ -162,14 +166,26 @@ CURLcode Curl_get_pathname(const char **cpp, char **path) *cpp = cp + i + strspn(cp + i, WHITESPACE); } else { - /* Read to end of filename */ + /* Read to end of filename - either to white space or terminator */ end = strpbrk(cp, WHITESPACE); if(end == NULL) end = strchr(cp, '\0'); + /* return pointer to second parameter if it exists */ *cpp = end + strspn(end, WHITESPACE); - - memcpy(*path, cp, end - cp); - (*path)[end - cp] = '\0'; + pathLength = 0; + relativePath = (cp[0] == '/' && cp[1] == '~' && cp[2] == '/'); + /* Handling for relative path - prepend home directory */ + if(relativePath) { + strcpy(*path, homedir); + pathLength = strlen(homedir); + (*path)[pathLength++] = '/'; + (*path)[pathLength] = '\0'; + cp += 3; + } + /* Copy path name up until first "white space" */ + memcpy(&(*path)[pathLength], cp, (int)(end - cp)); + pathLength += (int)(end - cp); + (*path)[pathLength] = '\0'; } return CURLE_OK; diff --git a/lib/curl_path.h b/lib/curl_path.h index 3ce16eb88..f9d432750 100644 --- a/lib/curl_path.h +++ b/lib/curl_path.h @@ -41,5 +41,4 @@ CURLcode Curl_getworkingpath(struct connectdata *conn, char *homedir, char **path); -CURLcode -Curl_get_pathname(const char **cpp, char **path); +CURLcode Curl_get_pathname(const char **cpp, char **path, char *homedir); diff --git a/lib/ssh-libssh.c b/lib/ssh-libssh.c index 822a7419c..fb49a22d5 100644 --- a/lib/ssh-libssh.c +++ b/lib/ssh-libssh.c @@ -2534,7 +2534,7 @@ static void sftp_quote(struct connectdata *conn) * also, every command takes at least one argument so we get that * first argument right now */ - result = Curl_get_pathname(&cp, &sshc->quote_path1); + result = Curl_get_pathname(&cp, &sshc->quote_path1, sshc->homedir); if(result) { if(result == CURLE_OUT_OF_MEMORY) failf(data, "Out of memory"); @@ -2559,7 +2559,7 @@ static void sftp_quote(struct connectdata *conn) /* sshc->quote_path1 contains the mode to set */ /* get the destination */ - result = Curl_get_pathname(&cp, &sshc->quote_path2); + result = Curl_get_pathname(&cp, &sshc->quote_path2, sshc->homedir); if(result) { if(result == CURLE_OUT_OF_MEMORY) failf(data, "Out of memory"); @@ -2581,7 +2581,7 @@ static void sftp_quote(struct connectdata *conn) /* symbolic linking */ /* sshc->quote_path1 is the source */ /* get the destination */ - result = Curl_get_pathname(&cp, &sshc->quote_path2); + result = Curl_get_pathname(&cp, &sshc->quote_path2, sshc->homedir); if(result) { if(result == CURLE_OUT_OF_MEMORY) failf(data, "Out of memory"); @@ -2605,7 +2605,7 @@ static void sftp_quote(struct connectdata *conn) /* rename file */ /* first param is the source path */ /* second param is the dest. path */ - result = Curl_get_pathname(&cp, &sshc->quote_path2); + result = Curl_get_pathname(&cp, &sshc->quote_path2, sshc->homedir); if(result) { if(result == CURLE_OUT_OF_MEMORY) failf(data, "Out of memory"); @@ -1205,7 +1205,7 @@ static CURLcode ssh_statemach_act(struct connectdata *conn, bool *block) * also, every command takes at least one argument so we get that * first argument right now */ - result = Curl_get_pathname(&cp, &sshc->quote_path1); + result = Curl_get_pathname(&cp, &sshc->quote_path1, sshc->homedir); if(result) { if(result == CURLE_OUT_OF_MEMORY) failf(data, "Out of memory"); @@ -1230,7 +1230,7 @@ static CURLcode ssh_statemach_act(struct connectdata *conn, bool *block) /* sshc->quote_path1 contains the mode to set */ /* get the destination */ - result = Curl_get_pathname(&cp, &sshc->quote_path2); + result = Curl_get_pathname(&cp, &sshc->quote_path2, sshc->homedir); if(result) { if(result == CURLE_OUT_OF_MEMORY) failf(data, "Out of memory"); @@ -1252,7 +1252,7 @@ static CURLcode ssh_statemach_act(struct connectdata *conn, bool *block) /* symbolic linking */ /* sshc->quote_path1 is the source */ /* get the destination */ - result = Curl_get_pathname(&cp, &sshc->quote_path2); + result = Curl_get_pathname(&cp, &sshc->quote_path2, sshc->homedir); if(result) { if(result == CURLE_OUT_OF_MEMORY) failf(data, "Out of memory"); @@ -1277,7 +1277,7 @@ static CURLcode ssh_statemach_act(struct connectdata *conn, bool *block) /* rename file */ /* first param is the source path */ /* second param is the dest. path */ - result = Curl_get_pathname(&cp, &sshc->quote_path2); + result = Curl_get_pathname(&cp, &sshc->quote_path2, sshc->homedir); if(result) { if(result == CURLE_OUT_OF_MEMORY) failf(data, "Out of memory"); |