Diff

Differences From Artifact [daf924be17]:

To Artifact [a444001e7a]:


53
54
55
56
57
58
59

60
61
62
63
64
65
66
static int verbose = 0;
static int recursive = 0;
static int preserve = 0;
static int targetshouldbedirectory = 0;
static int statistics = 1;
static int portnumber = 0;
static int prev_stats_len = 0;

static char *password = NULL;
static int errs = 0;
/* GUI Adaptation - Sept 2000 */
#define NAME_STR_MAX 2048
static char statname[NAME_STR_MAX + 1];
static unsigned long statsize = 0;
static int statperct = 0;







>







53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
static int verbose = 0;
static int recursive = 0;
static int preserve = 0;
static int targetshouldbedirectory = 0;
static int statistics = 1;
static int portnumber = 0;
static int prev_stats_len = 0;
static int scp_unsafe_mode = 0;
static char *password = NULL;
static int errs = 0;
/* GUI Adaptation - Sept 2000 */
#define NAME_STR_MAX 2048
static char statname[NAME_STR_MAX + 1];
static unsigned long statsize = 0;
static int statperct = 0;
1169
1170
1171
1172
1173
1174
1175
1176
1177
1178
1179
1180
1181
1182
1183

	if (!scp_sftp_dirstack_head) {
	    if (!scp_sftp_donethistarget) {
		/*
		 * Simple case: we are only dealing with one file.
		 */
		fname = scp_sftp_remotepath;
printf("oi :%s:\n", fname);
		must_free_fname = 0;
		scp_sftp_donethistarget = 1;
	    } else {
		/*
		 * Even simpler case: one file _which we've done_.
		 * Return 1 (finished).
		 */







<







1170
1171
1172
1173
1174
1175
1176

1177
1178
1179
1180
1181
1182
1183

	if (!scp_sftp_dirstack_head) {
	    if (!scp_sftp_donethistarget) {
		/*
		 * Simple case: we are only dealing with one file.
		 */
		fname = scp_sftp_remotepath;

		must_free_fname = 0;
		scp_sftp_donethistarget = 1;
	    } else {
		/*
		 * Even simpler case: one file _which we've done_.
		 * Return 1 (finished).
		 */
1192
1193
1194
1195
1196
1197
1198
1199
1200
1201
1202
1203
1204
1205
1206
1207
1208
1209
1210
1211
	    struct scp_sftp_dirstack *head = scp_sftp_dirstack_head;
	    while (head->namepos < head->namelen &&
		   (is_dots(head->names[head->namepos].filename) ||
		    (head->wildcard &&
		     !wc_match(head->wildcard,
			       head->names[head->namepos].filename))))
		head->namepos++;       /* skip . and .. */
printf("ooh\n");
	    if (head->namepos < head->namelen) {
		fname = dupcat(head->dirpath, "/",
			       head->names[head->namepos++].filename,
			       NULL);
printf("got :%s:\n", fname);
		must_free_fname = 1;
	    } else {
		/*
		 * We've come to the end of the list; pop it off
		 * the stack and return an ENDDIR action (or RETRY
		 * if this was a wildcard match).
		 */







<




<







1192
1193
1194
1195
1196
1197
1198

1199
1200
1201
1202

1203
1204
1205
1206
1207
1208
1209
	    struct scp_sftp_dirstack *head = scp_sftp_dirstack_head;
	    while (head->namepos < head->namelen &&
		   (is_dots(head->names[head->namepos].filename) ||
		    (head->wildcard &&
		     !wc_match(head->wildcard,
			       head->names[head->namepos].filename))))
		head->namepos++;       /* skip . and .. */

	    if (head->namepos < head->namelen) {
		fname = dupcat(head->dirpath, "/",
			       head->names[head->namepos++].filename,
			       NULL);

		must_free_fname = 1;
	    } else {
		/*
		 * We've come to the end of the list; pop it off
		 * the stack and return an ENDDIR action (or RETRY
		 * if this was a wildcard match).
		 */
1220
1221
1222
1223
1224
1225
1226
1227
1228
1229
1230
1231
1232
1233
1234
		sfree(head->names);
		scp_sftp_dirstack_head = head->next;
		sfree(head);

		return 0;
	    }
	}
printf("filename :%s:\n", fname);
	/*
	 * Now we have a filename. Stat it, and see if it's a file
	 * or a directory.
	 */
	ret = fxp_stat(fname, &attrs);
	if (!ret || !(attrs.flags & SSH_FILEXFER_ATTR_PERMISSIONS)) {
	    tell_user(stderr, "unable to identify %s: %s", fname,







|







1218
1219
1220
1221
1222
1223
1224
1225
1226
1227
1228
1229
1230
1231
1232
		sfree(head->names);
		scp_sftp_dirstack_head = head->next;
		sfree(head);

		return 0;
	    }
	}

	/*
	 * Now we have a filename. Stat it, and see if it's a file
	 * or a directory.
	 */
	ret = fxp_stat(fname, &attrs);
	if (!ret || !(attrs.flags & SSH_FILEXFER_ATTR_PERMISSIONS)) {
	    tell_user(stderr, "unable to identify %s: %s", fname,
1735
1736
1737
1738
1739
1740
1741
1742
1743
1744
1745
1746
1747
1748
1749
1750



1751
1752
1753
1754
1755
1756
1757
1758
	     * copying a single file and the target is a directory
	     * (common usage: `pscp host:filename .') the remote
	     * can't send us a _different_ file name. We can
	     * distinguish this case because `src' will be non-NULL
	     * and the last component of that will fail to match
	     * (the last component of) the name sent.
	     * 
	     * (Well, not always; if `src' is a wildcard, we do
	     * expect to get back filenames that don't correspond
	     * exactly to it. So we skip this check if `src'
	     * contains a *, a ? or a []. This is non-ideal - we
	     * would like to ensure that the returned filename
	     * actually matches the wildcard pattern - but one of
	     * SCP's protocol infelicities is that wildcard
	     * matching is done at the server end _by the server's
	     * rules_ and so in general this is infeasible. Live



	     * with it, or upgrade to SFTP.)
	     */
	    char *striptarget, *stripsrc;

	    striptarget = stripslashes(act.name, 1);
	    if (striptarget != act.name) {
		tell_user(stderr, "warning: remote host sent a compound"
			  " pathname - possibly malicious! (ignored)");







|

|
<
|
|
|
|
|
>
>
>
|







1733
1734
1735
1736
1737
1738
1739
1740
1741
1742

1743
1744
1745
1746
1747
1748
1749
1750
1751
1752
1753
1754
1755
1756
1757
1758
	     * copying a single file and the target is a directory
	     * (common usage: `pscp host:filename .') the remote
	     * can't send us a _different_ file name. We can
	     * distinguish this case because `src' will be non-NULL
	     * and the last component of that will fail to match
	     * (the last component of) the name sent.
	     * 
	     * Well, not always; if `src' is a wildcard, we do
	     * expect to get back filenames that don't correspond
	     * exactly to it. Ideally in this case, we would like

	     * to ensure that the returned filename actually
	     * matches the wildcard pattern - but one of SCP's
	     * protocol infelicities is that wildcard matching is
	     * done at the server end _by the server's rules_ and
	     * so in general this is infeasible. Hence, we only
	     * accept filenames that don't correspond to `src' if
	     * unsafe mode is enabled or we are using SFTP (which
	     * resolves remote wildcards on the client side and can
	     * be trusted).
	     */
	    char *striptarget, *stripsrc;

	    striptarget = stripslashes(act.name, 1);
	    if (striptarget != act.name) {
		tell_user(stderr, "warning: remote host sent a compound"
			  " pathname - possibly malicious! (ignored)");
1766
1767
1768
1769
1770
1771
1772
1773
1774

1775






1776
1777
1778
1779
1780
1781
1782
1783
	    if (is_dots(striptarget)) {
		bump("security violation: remote host attempted to write to"
		     " a '.' or '..' path!");
	    }

	    if (src) {
		stripsrc = stripslashes(src, 1);
		if (!stripsrc[strcspn(stripsrc, "*?[]")] &&
		    strcmp(striptarget, stripsrc)) {

		    tell_user(stderr, "warning: remote host attempted to"






			      " write to a different filename: disallowing");
		    /* Override the name the server provided with our own. */
		    striptarget = stripsrc;
		}
	    }

	    if (targ[0] != '\0')
		destfname = dupcat(targ, "\\", striptarget, NULL);







<
|
>
|
>
>
>
>
>
>
|







1766
1767
1768
1769
1770
1771
1772

1773
1774
1775
1776
1777
1778
1779
1780
1781
1782
1783
1784
1785
1786
1787
1788
1789
	    if (is_dots(striptarget)) {
		bump("security violation: remote host attempted to write to"
		     " a '.' or '..' path!");
	    }

	    if (src) {
		stripsrc = stripslashes(src, 1);

		if (strcmp(striptarget, stripsrc) &&
		    !using_sftp && !scp_unsafe_mode) {
		    tell_user(stderr, "warning: remote host tried to write "
			      "to a file called '%s'", striptarget);
		    tell_user(stderr, "         when we requested a file "
			      "called '%s'.", stripsrc);
		    tell_user(stderr, "         If this is a wildcard, "
			      "consider upgrading to SSH 2 or using");
		    tell_user(stderr, "         the '-unsafe' option. Renaming"
			      " of this file has been disallowed.");
		    /* Override the name the server provided with our own. */
		    striptarget = stripsrc;
		}
	    }

	    if (targ[0] != '\0')
		destfname = dupcat(targ, "\\", striptarget, NULL);
2140
2141
2142
2143
2144
2145
2146

2147
2148
2149
2150
2151
2152
2153
    printf("Options:\n");
    printf("  -p        preserve file attributes\n");
    printf("  -q        quiet, don't show statistics\n");
    printf("  -r        copy directories recursively\n");
    printf("  -v        show verbose messages\n");
    printf("  -P port   connect to specified port\n");
    printf("  -pw passw login with specified password\n");

#if 0
    /*
     * -gui is an internal option, used by GUI front ends to get
     * pscp to pass progress reports back to them. It's not an
     * ordinary user-accessible option, so it shouldn't be part of
     * the command-line help. The only people who need to know
     * about it are programmers, and they can read the source.







>







2146
2147
2148
2149
2150
2151
2152
2153
2154
2155
2156
2157
2158
2159
2160
    printf("Options:\n");
    printf("  -p        preserve file attributes\n");
    printf("  -q        quiet, don't show statistics\n");
    printf("  -r        copy directories recursively\n");
    printf("  -v        show verbose messages\n");
    printf("  -P port   connect to specified port\n");
    printf("  -pw passw login with specified password\n");
    printf("  -unsafe   allow server-side wildcards (DANGEROUS)\n");
#if 0
    /*
     * -gui is an internal option, used by GUI front ends to get
     * pscp to pass progress reports back to them. It's not an
     * ordinary user-accessible option, so it shouldn't be part of
     * the command-line help. The only people who need to know
     * about it are programmers, and they can read the source.
2190
2191
2192
2193
2194
2195
2196


2197
2198
2199
2200
2201
2202
2203
	else if (strcmp(argv[i], "-pw") == 0 && i + 1 < argc)
	    password = argv[++i];
	else if (strcmp(argv[i], "-gui") == 0 && i + 1 < argc) {
	    gui_hwnd = argv[++i];
	    gui_mode = 1;
	} else if (strcmp(argv[i], "-ls") == 0)
	    list = 1;


	else if (strcmp(argv[i], "--") == 0) {
	    i++;
	    break;
	} else
	    usage();
    }
    argc -= i;







>
>







2197
2198
2199
2200
2201
2202
2203
2204
2205
2206
2207
2208
2209
2210
2211
2212
	else if (strcmp(argv[i], "-pw") == 0 && i + 1 < argc)
	    password = argv[++i];
	else if (strcmp(argv[i], "-gui") == 0 && i + 1 < argc) {
	    gui_hwnd = argv[++i];
	    gui_mode = 1;
	} else if (strcmp(argv[i], "-ls") == 0)
	    list = 1;
	else if (strcmp(argv[i], "-unsafe") == 0)
	    scp_unsafe_mode = 1;
	else if (strcmp(argv[i], "--") == 0) {
	    i++;
	    break;
	} else
	    usage();
    }
    argc -= i;