Provided by: libnet-sftp-sftpserver-perl_1.1.0-5_all bug

NAME

       Net::SFTP::SftpServer - A Perl implementation of the SFTP subsystem with user access
       controls

SYNOPSIS

         use Net::SFTP::SftpServer;

         my $sftp = Net::SFTP::SftpServer->new();

         $sftp->run();

DESCRIPTION

       A Perl port of sftp-server from openssh providing access control on a per user per command
       basis and improved logging via syslog

       The limitations compared with the openssh implementation are as follows:

       •   Only files and directories are dealt with - other types are not returned on readdir

       •   a virtual chroot is performed - / is treated as the users home directory from the
           client perspective and all file access to / will be in /<home_path>/<username>
           home_path is defined on object initialisation not accessed from /etc/passwd The script
           DOES NOT run under chroot - this prevents it needing SUID to start.  The virtual
           chroot is enforced by the objects and prevent opperations outside the home area

       •   all sym linked files or directories are hidden and not accessible on request

       •   symlink returns permission denied. Please contact me if you need this functionaility
           implementing

       •   readlink returns file does not exist. Please contact me if you need this
           functionaility implementing

       •   setting of stats (set_stat or set_fstat) is disabled - client will receive permission
           denied.  Please contact me if you need this functionaility implementing

       •   permissions for file or dir is defaulted - default set on object initialisation

USAGE

       Basic usage:

         use Net::SFTP::SftpServer;

       Import options:

         :LOG    - Import logging functions for use in callbacks
         :ACTION - Import constants for Allow/Deny of actions

       Configuring syslog:

       Syslog output mode must be configured in the use statement of the module as follows:

         use Net::SFTP::SftpServer ( { log => 'local5' }, qw ( :LOG :ACTIONS ) );

       Net::SFTP::SftpServer will default to using "daemon" see your system's syslog
       documentation for more details

       Options for object initialisation:

       •   debug

           Log debug level information. Deault=0 (note this will create very large log files -
           use with caution)

       •   home

           Filesystem location of user home directories. default=/home

       •   file_perms

           Octal file permissions to force on creation of files. Default=0666 or permissions
           specified by file open command from client

       •   dir_perms

           Octal dir permissions to force on creation of directories. Default=0777 or permissions
           specified by mkdir command from client

       •   on_file_sent, on_file_received

           References to callback functions to be called on complete file sent or received.
           Function will be passed the full path and filename on the filesystem as a single
           argument

       •   use_tmp_upload

           Use temporary upload filenames while a file is being uploaded - this allows a
           monitoring script to know which files are in transit without having to watch file
           size.  Will be done transparantly to the user, the file will be renamed to the
           original file name when close. The temportary extension is ".SftpXFR.$$". Default=0

       •   max_file_size

           Maximum file size (in bytes) which can be uploaded. Default=0 (no limit)

       •   valid_filename_char

           Array of valid characters for filenames

       •   allow, deny

           Actions allowed or denied - see "PERMISSIONS" for details, Default is to allow ALL.

       •   fake_ok

           Array of actions (see action contants in "PERMISSIONS") which will be given response
           SSH2_FX_OK instead of SSH2_FX_PERMISSION_DENIED when denied by above deny options.
           Default=[]

       •   log_action_supress

           Array of actions to log quietly (logDetail - syslog debug level), logs messages
           whenever this action is performed. Default is quiet for SSH2_FXP_READ, SSH2_FXP_WRITE,
           SSH2_FX_OPENDIR, SSH2_FXP_READDIR, SSH2_FXP_CLOSE, SSH2_FXP_STAT SSH2_FXP_FSTAT and
           SSH2_FXP_LSTAT override with log_action, see below.

       •   log_action

           Array of actions to log loudly (logGeneral - syslog info level), logs messages
           whenever this action is performed.

       •   log_all_status

           Log all status messages at info level. By default SSH2_FX_OK and SSH2_FX_EOF will be
           logged at debug level.

PERMISSIONS

         ALL                      - All actions
         NET_SFTP_SYMLINKS        - Symlinks in paths to files (recommended deny to enforce chroot)
         NET_SFTP_RENAME_DIR      - Rename directories (recommended deny if also denying SSH2_FXP_MKDIR)
         SSH2_FXP_OPEN
         SSH2_FXP_CLOSE
         SSH2_FXP_READ
         SSH2_FXP_WRITE
         SSH2_FXP_LSTAT
         SSH2_FXP_STAT_VERSION_0
         SSH2_FXP_FSTAT
         SSH2_FXP_SETSTAT         - Automatically denied, not implemented in module
         SSH2_FXP_FSETSTAT        - Automatically denied, not implemented in module
         SSH2_FXP_OPENDIR
         SSH2_FXP_READDIR
         SSH2_FXP_REMOVE
         SSH2_FXP_MKDIR
         SSH2_FXP_RMDIR
         SSH2_FXP_STAT
         SSH2_FXP_RENAME
         SSH2_FXP_READLINK        - Automatically denied, not implemented in module
         SSH2_FXP_SYMLINK         - Automatically denied, not implemented in module

CALLBACKS

       Callback functions can be used to perform actions when files are sent or received, for
       example move a fully downloaded file to a processed directory or move a received file into
       an input directory.  The callback is proided with a Net::SFTP::SftpServer::File object.
       This object allows access to the file within the virtual chroot environment. It will also
       return the full filename, or move the file to an explicit location on the full filesystem.
       Either of these actions will break the chroot and the methods on the object will no longer
       be available.

       The following methods are provided

       •   read

           Read the data from the file - as the IO::File->read. Will open the file for reading if
           it is not already open and read back the data.

       •   open

           Will open the file - as IO::File->open but the filename is not supplied.

       •   getFilename

           Will return the filename as within the virtual chroot

       •   getFullFilenameBREAKCHROOT

           Will return the full filename on the real file system and break the virtual chroot

       •   renameBREAKCHROOT

           Takes a single argument of the new filename, will rename the file to that location and
           break the virtual chroot

LOGGING

       If :LOG is used when including Net::SFTP::SftpServer the following logging functions will
       be available:

         logError    - syslog with a log level of error
         logWarning  - syslog with a log level of warning
         logGeneral  - syslog with a log level of info
         logDetail   - syslog with a log level of debug, unless object was created with debug=>1 then syslog with a level of info

HARDENED EXAMPLE SCRIPT

       The following example script shows how this module can be used to give far greater control
       over what is allowed on your SFTP server.

       This setup is aimed at admins which want to user SFTP uploads but do not wish to grant
       users a system account.  You will also need to set both the SFTP subsystem and the user's
       shell to the sftp script, eg /usr/local/bin/sftp-server.pl

       This configuration:

       •   Enforces that users can only access the sftp script, not an ssh shell.

       •   Chroots them into their home directory in /var/upload/sftp

       •   Sets all file permissions to 0660 and does not permit users to change them.

       •   Does not allow symlinks, making directories or renaming directories, but allows all
           other normal actions.

       •   Has a max upload filesize of 200Mb

       •   Has a script memory limit of 100Mb for safety

       •   Will log actions by user sftptest in debug mode

       •   Will only allow alphanumeric plus _ . and - in filenames

       •   Will call ActionOnSent and ActionOnReceived respectively when files have been sent or
           received.

         #!/usr/local/bin/perl

         use strict;
         use warnings;
         use Net::SFTP::SftpServer ( { log => 'local5' }, qw ( :LOG :ACTIONS ) );
         use BSD::Resource;        # for setrlimit

         use constant DEBUG_USER => {
           SFTPTEST => 1,
         };

         # Security - make sure we have started this as sftp not ssh
         unless ( scalar @ARGV == 2 and
                  $ARGV[0] eq '-c'  and
                  ($ARGV[1] eq '/usr/local/bin/sftp-server.pl') ){

                logError "SFTP connection attempted for application $ARGV[0] - exiting";
                print "\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";
                exit 1;
         }

         my $MEMLIMIT = 100 * 1024 * 1024; # 100 Mb

         # hard limits on process memory usage;
         setrlimit( RLIMIT_RSS,  $MEMLIMIT, $MEMLIMIT );
         setrlimit( RLIMIT_VMEM, $MEMLIMIT, $MEMLIMIT );

         my $debug = (defined DEBUG_USER->{uc(getpwuid($>))} and DEBUG_USER->{uc(getpwuid($>))}) ? 1 : 0;

         my $sftp = Net::SFTP::SftpServer->new(
           debug               => $debug,
           home                => '/var/upload/sftp',
           file_perms          => 0660,
           on_file_sent        => \&ActionOnSent,
           on_file_received    => \&ActionOnReceived,
           use_tmp_upload      => 1,
           max_file_size       => 200 * 1024 * 1024,
           valid_filename_char => [ 'a' .. 'z', 'A' .. 'Z', '0' .. '9', '_', '.', '-' ],
           deny                => ALL,
           allow               => [ (
                                       SSH2_FXP_OPEN,
                                       SSH2_FXP_CLOSE,
                                       SSH2_FXP_READ,
                                       SSH2_FXP_WRITE,
                                       SSH2_FXP_LSTAT,
                                       SSH2_FXP_STAT_VERSION_0,
                                       SSH2_FXP_FSTAT,
                                       SSH2_FXP_OPENDIR,
                                       SSH2_FXP_READDIR,
                                       SSH2_FXP_REMOVE,
                                       SSH2_FXP_STAT,
                                       SSH2_FXP_RENAME,
                                    )],
           fake_ok             => [ (
                                       SSH2_FXP_SETSTAT,
                                       SSH2_FXP_FSETSTAT,
                                    )],
         );

         $sftp->run();

         sub ActionOnSent {
           my $fileObject = shift;
            ## Do Stuff
         }

         sub ActionOnReceived {
           my $fileObject = shift;
            ## Do Stuff
         }

DEPENDENCIES

         Stat::lsMode
         Fcntl
         POSIX
         Sys::Syslog
         Errno

SEE ALSO

       Sftp protocol <http://www.openssh.org/txt/draft-ietf-secsh-filexfer-02.txt>

AUTHOR

         Simon Day, Pirum Systems Ltd
         cpan <at> simonday.info

COPYRIGHT AND LICENSE

       Based on sftp-server.c Copyright (c) 2000-2004 Markus Friedl.  All rights reserved.

       Ported to Perl and extended by Simon Day Copyright (c) 2009 Pirum Systems Ltd.  All rights
       reserved.

       Permission to use, copy, modify, and distribute this software for any purpose with or
       without fee is hereby granted, provided that the above copyright notice and this
       permission notice appear in all copies.

       THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD TO
       THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT
       SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR
       ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
       OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE
       USE OR PERFORMANCE OF THIS SOFTWARE.