-----BEGIN PGP SIGNED MESSAGE----- Hash: SHA1 As I mentioned I would, I wrote a quick dummy shell to allow scp and sftp, but not anything else. It has a minor problem and a major problem (that I know about), but still should work in most cases for most people. The minor problem was that in a few cases, I was too lazy to check return codes. That's a 10-minute fix that I'm still too lazy to make. :) The major problem is that if one of the arguments to scp is a filename that contains a (quoted) space, the spaces will be treated as argument delimitors. I didn't make much effort to do a whole lot of processing on the command line, so any space that appears in argv[2] will be treated as an argument delimitor for the command which is exec'd. One could consider that a feature, as filenames with spaces in them are eeevil... =8^) I do actually plan to fix both of those problems one of these days, but I have a final exam in a week and don't have time to deal with it now. If anyone would like to offer other suggestions for improvements, or point out bugs I missed or security holes, then by all means please feel free to do so. If you find this thing useful, then use it... If not, then don't! ;-) Oh yeah... if you're not on recent Red Hat, you probably need to change _PATH_SFTP_SERVER to reflect your system. - ---- snip here ----- /* * rssh.c - restricted shell for ssh to allow scp or sftp only * * Copyright 2002 Derek D. Martin . * * This program is licensed under a BSD-style license, as follows: * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * */ #include #include #include #include /* for sftp */ #define _PATH_SFTP_SERVER "/usr/libexec/openssh/sftp-server" void do_exit_message( void ); char **build_arg_vector( char *str ); extern int errno; int main( int argc, char **argv ) { char **argvec; /* for argument vector from argv[2] */ /* q&d arg count check */ if ( argc < 3 ) do_exit_message(); /* if first arg is anything but -c, it's no good */ if ( strcmp("-c", argv[1]) ) do_exit_message(); /* convert argv[2] into an arg vector suitable for execvp() */ /* * FIXME: this should never return null (since argc >= 3) but * can't hurt being checked anyway... */ argvec = build_arg_vector(argv[2]); /* now check argvec[0] for scp or sftp */ if ( ! ( !strcmp(argvec[0], "scp") || !strcmp(argvec[0], _PATH_SFTP_SERVER)) ) do_exit_message(); /* if all that passed, exec the relevant command */ execvp(argvec[0], argvec); /* we only get here if the exec fails */ fprintf(stderr, "rssh: excecvp() failed. "); switch (errno){ case EACCES: case ENOTDIR: case ENOENT: fprintf(stderr, "%s is not an executable file, or permission denied.\n\n", argv[2]); break; case EPERM: fprintf(stderr, "FS mounted nosuid or process is being traced\n" "(and you are not root)\n\n"); break; default: fprintf(stderr, "an unknown error occurred.\n\n"); } exit(1); } void do_exit_message( void ) { fprintf( stderr, "\nThis account is restricted, for the use of scp or sftp" " only.\nIf you believe this is in error, please contact" " your system\nadministrator.\n\n" ); exit(0); } char **build_arg_vector( char *str ) { char *start; /* first char to look for arguments */ char *temp; /* copy of argument to add to ret */ char *next; /* where to start looking for next arg */ char **ret; /* address of argument vector */ int count; /* number of args in array */ ret = NULL; count = 0; start = str; /* * FIXME: This does not work if there is space in an arg, i.e. a filename * FIXME: check return codes on realloc * NOTE: this function modifies str, which is easy to change if * needed... */ /* assume words between spaces are arguments and grab them */ while ( next = strchr(start, ' ') ){ *next = '\0'; next++; /* only add argument if there is one (i.e. ignore multiple spaces) */ if ( strlen(start) ){ temp = strdup(start); ret = (char **)realloc(ret, sizeof(char*) * (count + 1)); ret[count] = temp; count++; } start = next; } /* if there are no more spaces, grab what's left */ if ( strlen(start) ){ temp = strdup(start); ret = (char **)realloc(ret, sizeof(char*) * (count + 1)); ret[count] = temp; count++; } /* add a null ptr to the end of the vector */ if ( count ){ ret = (char **)realloc(ret, sizeof(char*) * (count + 1)); ret[count] = NULL; } return ret; } - -- Derek Martin ddm@pizzashack.org - --------------------------------------------- I prefer mail encrypted with PGP/GPG! GnuPG Key ID: 0x81CFE75D Retrieve my public key at http://pgp.mit.edu Learn more about it at http://www.gnupg.org -----BEGIN PGP SIGNATURE----- Version: GnuPG v1.0.6 (GNU/Linux) Comment: For info see http://www.gnupg.org iD8DBQE9TNBOdjdlQoHP510RApbOAJ0Xh7OtOUj7TBw+JK8grOYrwIS1iACfcuSd UBlEhJ/rGZ6m36mxP3vwBms= =s/zo -----END PGP SIGNATURE-----