/* * sftpsh -- Secure Shell File Transfer Protocol Shell * * This "shell" is to be used to restrict a user's usage of SSH to SFTP access * only. By setting the user's shell to /path/to/sftpsh the SSH server will * allow the user access to SFTP services without interactive login access. * * To use, be certain to change the USER-DEFINED VALUES below to settings * appropriate to your system. * * This and other hacks can be found at: http://oddgeek.info/ * * Copyright (c) 2005 Jason A. Dour * * This software is provided 'as-is', without any express or implied warranty. * In no event will the authors be held liable for any damages arising from the * use of this software. * * Permission is granted to anyone to use this software for any purpose, * including commercial applications, and to alter it and redistribute it * freely, subject to the following restrictions: * * 1. The origin of this software must not be misrepresented; you must not * claim that you wrote the original software. If you use this software in * a product, an acknowledgment in the product documentation would be * appreciated but is not required. * * 2. Altered source versions must be plainly marked as such, and must not * be misrepresented as being the original software. * * 3. This notice may not be removed or altered from any source * distribution. * */ /* * Version Information * * 1.0 2005.05.25 * * First public release. Nothing really changed other than comments and * adding one include to ensure a -Wall returns no warnings. * * ooze 2001.05.31 * * First documented version. Given to a few people in the SSH community, * but not distributed widely. This version has since been hosted by * others, and even used as a basis for other code projects such as * chressh. * * primordial ooze * * Used briefly on various private systems. Given to a few others * privately when they had need of it. Never distributed widely. * */ /* * USER-DEFINED VALUES * * Define the path to the SFTP Server binary, the execution * command name of the server, and any command arguments. * With openssh these values are generally '/path/to/sftp-server,' * 'sftp-server,' and '' respectively. * * Lastly, define the message that is written to stdout when * an interactive shell is attempted. */ #define SFTP_BINARY "/usr/local/libexec/sftp-server" #define SFTP_EXNAME "sftp-server" #define SFTP_ARGS "" #define DENY_MESG "\n\rYou do not have interactive login access to this machine.\n\r\n\rContact the system administrator should this not be the case.\n\r" /* * DO NOT MODIFY BEYOND THIS POINT UNLESS YOU ARE CERTAIN YOU * WILL NOT OPEN UP THE SHELL TO ALLOW ANYTHING OTHER THAN THE * SFTP SERVER TO EXECUTE. */ #include #include #include #include /* * Output the error and return. */ void error(char *program, char *why) { /* Holder for output format. */ char *outputstr; /* Build the output format... */ if ( strlen(program) ) /* Prepend error output with program name. */ outputstr = "%s: %s\n\r"; else /* Just output the error. */ outputstr = "%s%s\n\n"; /* If stderr is a tty... */ if ( isatty( fileno(stderr) ) ) { /* Output this to stderr... */ fprintf(stderr, outputstr, program, why); } else { /* Otherwise, output to stdout. */ fprintf(stdout, outputstr, program, why); } /* All is well. Return. */ return; } /* * There isn't much to this program. Grab the shell's name. * Check the argument passed. Either execute or error out. */ int main(int argc, char **argv) { char *progname; /* The sftpsh execution name. */ char *sftp_cmd[] = { /* The SFTP Server command array. */ SFTP_EXNAME, SFTP_ARGS, NULL }; /* Grab the sftpsh execution name. */ if ( strchr(argv[0], '/') ) progname = strrchr(argv[0], '/') + 1; else progname = argv[0]; /* Check the of args. Error out if bad. */ if ( ( (argc == 3) && (strcmp(argv[1], "-c") == 0) && (strcmp(argv[2], SFTP_EXNAME) == 0) ) || ( (argc == 2) && (strcmp(argv[1], SFTP_EXNAME) == 0) ) ) { /* Exec the SFTP Server binary. */ execv(SFTP_BINARY, sftp_cmd); /* * Still here? Where's the kaboom? There was supposed to be * an earth-shattering kaboom! */ error(progname, "SFTP Server binary cannot be executed."); exit(-1); } /* Check whether it is a command attempt or a login. */ if (argc > 1) { /* Command not allowed. Exit. */ error(progname, "Command not allowed."); exit(1); } else { /* Print DENY_MESG and exit. */ error("", DENY_MESG); sleep(3); exit(2); } /* That's it...we should never get past the above checks. */ exit(255); }