X-Git-Url: https://asedeno.scripts.mit.edu/gitweb/?a=blobdiff_plain;f=psftp.c;h=9637e2e015a361c3378ec46ed0be2620a9e24408;hb=693bbf0ec6007120b91dafb4eaed1ae833eb59f7;hp=b1cfe16d22fc3decf87ece3e8591159a88cd6490;hpb=5ea746b15d173ab75f10ae661432eb57a5a22c20;p=PuTTY.git diff --git a/psftp.c b/psftp.c index b1cfe16d..9637e2e0 100644 --- a/psftp.c +++ b/psftp.c @@ -40,14 +40,6 @@ static Config cfg; * Higher-level helper functions used in commands. */ -/* - * Determine whether a string is entirely composed of dots. - */ -static int is_dots(char *str) -{ - return str[strspn(str, ".")] == '\0'; -} - /* * Attempt to canonify a pathname starting from the pwd. If * canonification fails, at least fall back to returning a _valid_ @@ -209,7 +201,7 @@ int sftp_get_file(char *fname, char *outfname, int recurse, int restart, struct fxp_xfer *xfer; uint64 offset; FILE *fp; - int ret; + int ret, shown_err = FALSE; /* * In recursive mode, see if we're dealing with a directory. @@ -291,10 +283,19 @@ int sftp_get_file(char *fname, char *outfname, int recurse, int restart, ournames = sresize(ournames, namesize, struct fxp_name *); } for (i = 0; i < names->nnames; i++) - if (!is_dots(names->names[i].filename) && + if (strcmp(names->names[i].filename, ".") && + strcmp(names->names[i].filename, "..") && (!wildcard || wc_match(wildcard, - names->names[i].filename))) - ournames[nnames++] = fxp_dup_name(&names->names[i]); + names->names[i].filename))) { + if (!vet_filename(names->names[i].filename)) { + printf("ignoring potentially dangerous server-" + "supplied filename '%s'\n", + names->names[i].filename); + } else { + ournames[nnames++] = + fxp_dup_name(&names->names[i]); + } + } fxp_free_names(names); } sftp_register(req = fxp_close_send(dirhandle)); @@ -442,7 +443,10 @@ int sftp_get_file(char *fname, char *outfname, int recurse, int restart, ret = xfer_download_gotpkt(xfer, pktin); if (ret < 0) { - printf("error while reading: %s\n", fxp_error()); + if (!shown_err) { + printf("error while reading: %s\n", fxp_error()); + shown_err = TRUE; + } ret = 0; } @@ -1002,14 +1006,14 @@ int sftp_general_get(struct sftp_command *cmd, int restart, int multiple) } else if (!strcmp(cmd->words[i], "-r")) { recurse = TRUE; } else { - printf("get: unrecognised option '%s'\n", cmd->words[i]); + printf("%s: unrecognised option '%s'\n", cmd->words[0], cmd->words[i]); return 0; } i++; } if (i >= cmd->nwords) { - printf("get: expects a filename\n"); + printf("%s: expects a filename\n", cmd->words[0]); return 0; } @@ -1088,14 +1092,14 @@ int sftp_general_put(struct sftp_command *cmd, int restart, int multiple) } else if (!strcmp(cmd->words[i], "-r")) { recurse = TRUE; } else { - printf("put: unrecognised option '%s'\n", cmd->words[i]); + printf("%s: unrecognised option '%s'\n", cmd->words[0], cmd->words[i]); return 0; } i++; } if (i >= cmd->nwords) { - printf("put: expects a filename\n"); + printf("%s: expects a filename\n", cmd->words[0]); return 0; } @@ -1667,10 +1671,12 @@ static struct sftp_cmd_lookup { }, { "dir", TRUE, "list contents of a remote directory", - " [ ]\n" + " [ ]/[ ]\n" " List the contents of a specified directory on the server.\n" " If is not given, the current working directory\n" - " will be listed.\n", + " is assumed.\n" + " If is given, it is treated as a set of files to\n" + " list; otherwise, all files are listed.\n", sftp_cmd_ls }, { @@ -1678,10 +1684,11 @@ static struct sftp_cmd_lookup { }, { "get", TRUE, "download a file from the server to your local machine", - " [ ]\n" + " [ -r ] [ -- ] [ ]\n" " Downloads a file on the server and stores it locally under\n" " the same name, or under a different one if you supply the\n" - " argument .\n", + " argument .\n" + " If -r specified, recursively fetch a directory.\n", sftp_cmd_get }, { @@ -1712,10 +1719,11 @@ static struct sftp_cmd_lookup { }, { "mget", TRUE, "download multiple files at once", - " [ ... ]\n" + " [ -r ] [ -- ] [ ... ]\n" " Downloads many files from the server, storing each one under\n" " the same name it has on the server side. You can use wildcards\n" - " such as \"*.c\" to specify lots of files at once.\n", + " such as \"*.c\" to specify lots of files at once.\n" + " If -r specified, recursively fetch files and directories.\n", sftp_cmd_mget }, { @@ -1726,10 +1734,11 @@ static struct sftp_cmd_lookup { }, { "mput", TRUE, "upload multiple files at once", - " [ ... ]\n" + " [ -r ] [ -- ] [ ... ]\n" " Uploads many files to the server, storing each one under the\n" " same name it has on the client side. You can use wildcards\n" - " such as \"*.c\" to specify lots of files at once.\n", + " such as \"*.c\" to specify lots of files at once.\n" + " If -r specified, recursively store files and directories.\n", sftp_cmd_mput }, { @@ -1749,10 +1758,11 @@ static struct sftp_cmd_lookup { }, { "put", TRUE, "upload a file from your local machine to the server", - " [ ]\n" + " [ -r ] [ -- ] [ ]\n" " Uploads a file to the server and stores it there under\n" " the same name, or under a different one if you supply the\n" - " argument .\n", + " argument .\n" + " If -r specified, recursively store a directory.\n", sftp_cmd_put }, { @@ -1767,10 +1777,11 @@ static struct sftp_cmd_lookup { }, { "reget", TRUE, "continue downloading a file", - " [ ]\n" + " [ -r ] [ -- ] [ ]\n" " Works exactly like the \"get\" command, but the local file\n" " must already exist. The download will begin at the end of the\n" - " file. This is for resuming a download that was interrupted.\n", + " file. This is for resuming a download that was interrupted.\n" + " If -r specified, resume interrupted \"get -r\".\n", sftp_cmd_reget }, { @@ -1783,10 +1794,11 @@ static struct sftp_cmd_lookup { }, { "reput", TRUE, "continue uploading a file", - " [ ]\n" + " [ -r ] [ -- ] [ ]\n" " Works exactly like the \"put\" command, but the remote file\n" " must already exist. The upload will begin at the end of the\n" - " file. This is for resuming an upload that was interrupted.\n", + " file. This is for resuming an upload that was interrupted.\n" + " If -r specified, resume interrupted \"put -r\".\n", sftp_cmd_reput }, {