/*
 * 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.
 *
 * This software is released under no license or guarantee.
 * Use at your own risk.
 *
 *
 * 31 MAY 2001 - Jason A. Dour <jason++@dour.org>
 */

/*
 * 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.
 *
 * Compile with gcc -O2 sftpsh.c -o sftpsh
 * Copy to /bin
 */
#define SFTP_BINARY "/usr/local/libexec/sftp-server"
#define SFTP_EXNAME "sftp-server"
#define SFTP_ARGS   ""

#define DENY_MESG   "\n\rYou do not have permission to login interactively to this host.\n\r\n\rPlease contact the system administrator if you believe this to be a configuration error.\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 <stdio.h>
#include <string.h>
#include <unistd.h>
#include <stdlib.h>

/*
 * Output the error and return.
 */
void error(char *program, char *why) {
   char *outputstr;

   if ( strlen(program) )
      outputstr = "%s: %s\n\r";
   else
      outputstr = "%s%s\n\n";

   if ( isatty( fileno(stderr) ) ) {
      fprintf(stderr, outputstr, program, why);
      return;
      } else {
      fprintf(stdout, outputstr, program, why);
      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_BINARY) == 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. */
   }

