diff -Nur openssh-3.8.1p1/scp.c openssh-3.8.1p1.flo/scp.c --- openssh-3.8.1p1/scp.c 2003-11-24 03:09:28.000000000 +0100 +++ openssh-3.8.1p1.flo/scp.c 2005-06-10 12:54:20.000000000 +0200 @@ -214,16 +214,41 @@ void usage(void); int -main(int argc, char **argv) +main(int sargc, char **sargv) { - int ch, fflag, tflag, status; + int ch, slen, argc, fflag, tflag, status; double speed; char *targ, *endp; extern char *optarg; extern int optind; + char *cmdline; + /* Tweak it like this - later codes need to ++ argv */ + char *argva[64]; + char **argv=argva; __progname = ssh_get_progname(argv[0]); + /* we need at least "-c" and "scp -f config" */ + if (sargc < 2) + return -1; + + /* Copy command line - it might be **argv buffer is non writeable */ + cmdline=strdup(sargv[2]); + if (!cmdline) + return -1; + + /* Split command line argument to be parsed instead of others */ + argc=0; + argv[argc++]=cmdline; + slen=strlen(cmdline); + for(ch=0;ch 0 && cmdline[ch-1] == 0x0) { + argv[argc++]=&cmdline[ch]; + } + } + args.list = NULL; addargs(&args, "ssh"); /* overwritten with ssh_program */ addargs(&args, "-x"); @@ -231,7 +256,7 @@ addargs(&args, "-oClearAllForwardings yes"); fflag = tflag = 0; - while ((ch = getopt(argc, argv, "dfl:prtvBCc:i:P:q1246S:o:F:")) != -1) + while ((ch = getopt(argc, argv, "dfl:prtvBCc:i:P:q1246S:o:F:")) != -1) { switch (ch) { /* User-visible flags. */ case '1': @@ -241,8 +266,8 @@ case 'C': addargs(&args, "-%c", ch); break; - case 'o': case 'c': + case 'o': case 'i': case 'F': addargs(&args, "-%c%s", ch, optarg); @@ -295,7 +320,8 @@ default: usage(); } - argc -= optind; + } + argc -= optind; argv += optind; if ((pwd = getpwuid(userid = getuid())) == NULL) @@ -307,12 +333,22 @@ remin = STDIN_FILENO; remout = STDOUT_FILENO; + /* Chroot to users homedir */ + chroot(pwd->pw_dir); + + /* We are suid - so set uid to real uid after chroot (drop privs) */ + if (getuid() != geteuid()) + setreuid(getuid(), getuid()); + if (fflag) { /* Follow "protocol", send data. */ (void) response(); source(argc, argv); exit(errs != 0); - } + } + +#if 0 +#error We dont want user to write to its directory - so disable it completly if (tflag) { /* Receive data. */ sink(argc, argv); @@ -356,7 +392,9 @@ errs = 1; } } +#endif exit(errs != 0); + } void