eXept Software AG Logo

Smalltalk/X Webserver

Documentation of class 'AbstractFTPSession':

Home

Documentation
www.exept.de
Everywhere
for:
[back]

Class: AbstractFTPSession


Inheritance:

   Object
   |
   +--AbstractTCPSession
      |
      +--AbstractFTPSession
         |
         +--FTPSession
         |
         +--SmalltalkFTPSession

Package:
stx:goodies/communication
Category:
Net-Communication-FTP
Version:
rev: 1.23 date: 2019/02/08 21:00:45
user: cg
file: AbstractFTPSession.st directory: goodies/communication
module: stx stc-classLibrary: communication
Author:
Claus Gittinger (extracted code from FTPSession)

Description:


Helper class for the FTPServer.

Common code for FTP serverSessions - add concrete subclass
The stuff implemented here realizes the protocol;
real file operations and authorization must be implemented in subclasses.

Methods which should be redefined are found in the 'must be redefined' category.

Be aware, that FTPSessions may allow a client to GET all files
which are readable by me (except for the white- and blacklists below).

To limit access to certain folders, you can explicitly whiteList
allowed folders (by setting whiteListedFolders) and/or exclude individual folders
via a blackList (setting blackListedFolders).

Whitelisting is done first, then blacklisting
i.e. it is possible to allow everything under '/foo/...' by adding '/foo' to the whitelist,
and still exclude individual subdirectories under it by adding (say) '/foo/bar/baz' to the blacklist.


    
    FTPServer start.
    FTPServer startOnPort:portNr.

    (FTPServer forPort:12345)
        sessionClass:SmalltalkFTPSession;
        start

    then, on the command line, try:
        ftp loalhost 12345


Related information:

    [ttps]

Class protocol:

defaults
o  ftpVersion

queries
o  isAbstract
Return if this class is an abstract class.
True is returned here for myself only; false for subclasses.
Abstract subclasses must redefine this again.


Instance protocol:

accessing
o  blackListedFoldersForReading
if non-nil, folders whose names match any in the given list will
NOT be visible to clients

o  blackListedFoldersForReading: aListOfGlobPatterns
if non-nil, folders whose names match any in the given list will
NOT be visible to clients

o  blackListedFoldersForWriting
if non-nil, folders whose names match any in the given list will
NOT be allowed to be written into by clients

o  blackListedFoldersForWriting: aListOfGlobPatterns
if non-nil, folders whose names match any in the given list will
NOT be allowed to be written into by clients

o  exitOnBadCommand: aBoolean
can be set to enforce connection closing, whenever a bad command arrives

o  whiteListedFoldersForReading
if non-nil, only folders whose names match any in the given list will
be visible to clients

o  whiteListedFoldersForReading: aListOfGlobPatterns
if non-nil, only folders whose names match any in the given list will
be visible to clients

o  whiteListedFoldersForWriting
if non-nil, only folders whose names match any in the given list will
NOT be allowed to be written into by clients

o  whiteListedFoldersForWriting: aListOfGlobPatterns
if non-nil, only folders whose names match any in the given list will
NOT be allowed to be written into by clients

debugging
o  logCommand: aMessage

ftp system commands
o  FEAT
return list of features

usage example(s):

^ socket nextPutLine:('501 FEAT command syntax')

o  HELP
send all commands supported by FTP server

o  NOOP
no instruction command

o  PASS
password from user; already readin from USER command

o  PASV
incoming PASV command.
Open a listening socket on a random port,
wait for the session partner to connect to it.
Timeout after some time, if he does not connect to me.
(separate data connection)

o  PORT
incoming PORT command.
Connect to the session partner (separate data connection)

o  QUIT
shutdown server

o  REIN
reinitialize server

o  SITE
incoming SITE command.
sends back some statistic info;
or allows the idle timeout to be changed (SITE IDLE <seconds>)

o  STAT
incoming STAT command.
sends back some statistic info

o  SYST
incoming SYST command.
send back the system type

o  USER
incoming USER command.
login to a new session

ftp user commands
o  CDUP
change to parent directory

o  CWD
change working directory

o  DELE
delete file or (empty) directory

o  LIST
show directory contents; longFormat

o  MKD
make directory

o  NLST
show directory contents; shortFormat

o  PWD
get current working directory

o  RETR
incoming RETR command.
retrieve a file (i.e. download as seen from client)

o  RMD
recursive delete directory

o  STOR
incoming STOR command.
upload as seen from ftp client

o  STOU
incoming STOU command.
upload as seen from ftp client

o  TYPE
set mode:
bin (I or i) := #binary
ascii(A or a) := #ascii

must be redefined
o  canChangeWorkingDirectory: newDirectory
raise an error: must be redefined in concrete subclass(es)

** This method raises an error - it must be redefined in concrete classes **

o  checkPassword: arg1 for: arg2
raise an error: must be redefined in concrete subclass(es)

** This method raises an error - it must be redefined in concrete classes **

o  defaultDirectoryForUser: userName
raise an error: must be redefined in concrete subclass(es)

** This method raises an error - it must be redefined in concrete classes **

o  doDELETE: recursive
raise an error: must be redefined in concrete subclass(es)

o  doLIST: arg
raise an error: must be redefined in concrete subclass(es)

o  doMKD: arg
raise an error: must be redefined in concrete subclass(es)

o  doRETR: file onTo: outStream
raise an error: must be redefined in concrete subclass(es)

o  doSTORE: arg
raise an error: must be redefined in concrete subclass(es)

o  loginUserNeedsPassword: arg
raise an error: must be redefined in concrete subclass(es)

** This method raises an error - it must be redefined in concrete classes **

private
o  closeDataConnection

o  doReinitialize
reinitialize the system; called when:
- user logged out
- system before shutdown
- reinitialize request
- during startup

o  doUserLoggedIn: aUser
setup user context

o  listOfSupportedCommands
^ self class methodDictionary keys

o  listOfSupportedFeatures

o  nextCommand
reads the next command from socket; if a timeout occurs nil is returned otherwise
the command as string and the lastArgument is set to the received argument

o  serveNextCommandFromSocket
make sure that nobody sends funny messages to me or my superclass

o  serveSocket: aSocket
(comment from inherited method)
redefine in concrete classes to something like:

private ftp
o  checkAndGetArgFilename

o  checkAndGetCWD

o  checkAndGetDataConnection

protocol testing
o  allowedToSeeDirectory: dir
|ftp|
ftp := FTPSession basicNew.
ftp whiteListedFoldersForReading:#( '/foo' '/bar*' ).
ftp blackListedFoldersForReading:#( '/foo/bar' '/bar/baz/').
self assert:( ftp allowedToSeeDirectory:'/foo' ).
self assert:( ftp allowedToSeeDirectory:'/fooo' ) not.
self assert:( ftp allowedToSeeDirectory:'/foo/bar' ) not.
self assert:( ftp allowedToSeeDirectory:'/foo/baz' ).

o  allowedToWriteIntoDirectory: dir
|ftp|
ftp := FTPSession basicNew.
ftp whiteListedFoldersForWriting:#( '/foo' '/bar*' ).
ftp blackListedFoldersForWriting:#( '/foo/bar' '/bar/baz/').
self assert:( ftp allowedToWriteIntoDirectory:'/foo' ).

o  isPath: aFilename inList: aWhiteOrBlackList
|ftp|
ftp := FTPSession basicNew.
self assert:( ftp isPath:'/foo' inList:#( '/foo' '/bar*' ) ).
self assert:( ftp isPath:'/barr' inList:#( '/foo' '/bar*' ) ).
self assert:( ftp isPath:'/bar/bla' inList:#( '/foo' '/bar*' ) ).
self assert:( ftp isPath:'/baz' inList:#( '/foo' '/bar*' ) ) not.
self assert:( ftp isPath:'/fooo' inList:#( '/foo' '/bar*' ) ) not.
self assert:( ftp isPath:'/fooo' inList:#( '/foo*' '/bar*' ) ).

queries
o  isBinary

serving
o  clientOn: aSocket
process for new client


Demonstration:


    FTPServer verbose:true



ST/X 7.2.0.0; WebServer 1.670 at bd0aa1f87cdd.unknown:8081; Fri, 07 Oct 2022 16:31:42 GMT