Unverified Commit a4a56ec9 authored by John DeHelian's avatar John DeHelian Committed by Daniel Stenberg
Browse files

sftp: allow quoted commands to use relative paths

Closes #1900
parent 9fb5a943
Loading
Loading
Loading
Loading
+25 −9
Original line number Diff line number Diff line
@@ -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;

+1 −2
Original line number Diff line number Diff line
@@ -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);
+4 −4
Original line number Diff line number Diff line
@@ -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");
+4 −4
Original line number Diff line number Diff line
@@ -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");