Documentation ¶
Overview ¶
Package ftpserver provides all the tools to build your own FTP server: The core library and the driver.
Index ¶
- Constants
- Variables
- func Control(network, address string, c syscall.RawConn) error
- type ClientContext
- type ClientDriver
- type ClientDriverExtensionAllocate
- type ClientDriverExtensionAvailableSpace
- type ClientDriverExtensionFileList
- type ClientDriverExtensionHasher
- type ClientDriverExtensionRemoveDir
- type ClientDriverExtensionSymlink
- type ClientDriverExtentionFileTransfer
- type CommandDescription
- type DataChannel
- type DataConnectionRequirement
- type FileTransfer
- type FileTransferError
- type FtpServer
- type GlobalTCPListenerBox
- type HASHAlgo
- type MainDriver
- type MainDriverExtensionPassiveWrapper
- type MainDriverExtensionTLSVerifier
- type MainDriverExtensionUserVerifier
- type PortRange
- type PublicIPResolver
- type Settings
- type TLSRequirement
- type TransferType
Constants ¶
const ( // 100 Series - The requested action is being initiated, expect another reply before // proceeding with a new command. StatusFileStatusOK = 150 // RFC 959, 4.2.1 // 200 Series - The requested action has been successfully completed. StatusOK = 200 // RFC 959, 4.2.1 StatusNotImplemented = 202 // RFC 959, 4.2.1 StatusSystemStatus = 211 // RFC 959, 4.2.1 StatusDirectoryStatus = 212 // RFC 959, 4.2.1 StatusFileStatus = 213 // RFC 959, 4.2.1 StatusHelpMessage = 214 // RFC 959, 4.2.1 StatusSystemType = 215 // RFC 959, 4.2.1 StatusServiceReady = 220 // RFC 959, 4.2.1 StatusClosingControlConn = 221 // RFC 959, 4.2.1 StatusClosingDataConn = 226 // RFC 959, 4.2.1 StatusEnteringPASV = 227 // RFC 959, 4.2.1 StatusEnteringEPSV = 229 // RFC 2428, 3 StatusUserLoggedIn = 230 // RFC 959, 4.2.1 StatusAuthAccepted = 234 // RFC 2228, 3 StatusFileOK = 250 // RFC 959, 4.2.1 StatusPathCreated = 257 // RFC 959, 4.2.1 // 300 Series - The command has been accepted, but the requested action is on hold, // pending receipt of further information. StatusUserOK = 331 // RFC 959, 4.2.1 StatusFileActionPending = 350 // RFC 959, 4.2.1 // 400 Series - The command was not accepted and the requested action did not take place, // but the error condition is temporary and the action may be requested again. StatusServiceNotAvailable = 421 // RFC 959, 4.2.1 StatusCannotOpenDataConnection = 425 // RFC 959, 4.2.1 StatusTransferAborted = 426 // RFC 959, 4.2.1 StatusFileActionNotTaken = 450 // RFC 959, 4.2.1 // 500 Series - Syntax error, command unrecognized and the requested action did not take // place. This may include errors such as command line too long. StatusSyntaxErrorNotRecognised = 500 // RFC 959, 4.2.1 StatusSyntaxErrorParameters = 501 // RFC 959, 4.2.1 StatusCommandNotImplemented = 502 // RFC 959, 4.2.1 StatusBadCommandSequence = 503 // RFC 959, 4.2.1 StatusNotImplementedParam = 504 // RFC 959, 4.2.1 StatusNotLoggedIn = 530 // RFC 959, 4.2.1 StatusActionNotTaken = 550 // RFC 959, 4.2.1 StatusActionAborted = 552 // RFC 959, 4.2.1 StatusActionNotTakenNoFile = 553 // RFC 959, 4.2.1 )
Status codes as documented by: https://tools.ietf.org/html/rfc959 https://tools.ietf.org/html/rfc2428 https://tools.ietf.org/html/rfc2228
Variables ¶
var ( // ErrStorageExceeded defines the error mapped to the FTP 552 reply code. // As for RFC 959 this error is checked for STOR, APPE ErrStorageExceeded = errors.New("storage limit exceeded") // ErrFileNameNotAllowed defines the error mapped to the FTP 553 reply code. // As for RFC 959 this error is checked for STOR, APPE, RNTO ErrFileNameNotAllowed = errors.New("filename not allowed") )
var ErrNoAvailableListeningPort = errors.New("could not find any port to listen to or MaxClientsSingle limit")
ErrNoAvailableListeningPort is returned when no port could be found to accept incoming connection
var ( // ErrNotListening is returned when we are performing an action that is only valid while listening ErrNotListening = errors.New("we aren't listening") )
var ErrRemoteAddrFormat = errors.New("remote address has a bad format")
ErrRemoteAddrFormat is returned when the remote address has a bad format
var GlobalTCPListener *net.TCPListener
var GlobalTCPListeners sync.Map
key:string value:GlobalTCPListenerBox
Functions ¶
Types ¶
type ClientContext ¶
type ClientContext interface { // Path provides the path of the current connection Path() string // SetPath sets the path of the current connection. // This method is useful to set a start directory, you should use it before returning a successful // authentication response from your driver implementation. // Calling this method after the authentication step could lead to undefined behavior SetPath(value string) // SetListPath allows to change the path for the last LIST/NLST request. // This method is useful if the driver expands wildcards and so the returned results // refer to a path different from the requested one. // The value must be cleaned using path.Clean SetListPath(value string) // SetDebug activates the debugging of this connection commands SetDebug(debug bool) // Debug returns the current debugging status of this connection commands Debug() bool // Client's ID on the server ID() uint32 // Client's address RemoteAddr() net.Addr // Servers's address LocalAddr() net.Addr // Client's version can be empty GetClientVersion() string // Close closes the connection and disconnects the client. Close() error // HasTLSForControl returns true if the control connection is over TLS HasTLSForControl() bool // HasTLSForTransfers returns true if the transfer connection is over TLS HasTLSForTransfers() bool // GetLastCommand returns the last received command GetLastCommand() string // GetLastDataChannel returns the last data channel mode GetLastDataChannel() DataChannel // SetTLSRequirement sets the TLS requirement to respect on a per-client basis. // The requirement is checked when the client issues the "USER" command, // after executing the MainDriverExtensionUserVerifier extension, and // before opening transfer connections. // Supported values: ClearOrEncrypted, MandatoryEncryption. // If you want to enforce the same requirement for all // clients, use the TLSRequired parameter defined in server settings instead SetTLSRequirement(requirement TLSRequirement) error }
ClientContext is implemented on the server side to provide some access to few data around the client
type ClientDriver ¶
ClientDriver is the base FS implementation that allows to manipulate files
type ClientDriverExtensionAllocate ¶
type ClientDriverExtensionAllocate interface { // AllocateSpace reserves the space necessary to upload files AllocateSpace(size int) error }
ClientDriverExtensionAllocate is an extension to support the "ALLO" - file allocation - command
type ClientDriverExtensionAvailableSpace ¶
type ClientDriverExtensionAvailableSpace interface {
GetAvailableSpace(dirName string) (int64, error)
}
ClientDriverExtensionAvailableSpace is an extension to implement to support the AVBL ftp command
type ClientDriverExtensionFileList ¶
type ClientDriverExtensionFileList interface { // ReadDir reads the directory named by name and return a list of directory entries. ReadDir(name string) ([]os.FileInfo, error) }
ClientDriverExtensionFileList is a convenience extension to allow to return file listing without requiring to implement the methods Open/Readdir for your custom afero.File
type ClientDriverExtensionHasher ¶
type ClientDriverExtensionHasher interface {
ComputeHash(name string, algo HASHAlgo, startOffset, endOffset int64) (string, error)
}
ClientDriverExtensionHasher is an extension to implement if you want to handle file digests yourself. You have to set EnableHASH to true for this extension to be called
type ClientDriverExtensionRemoveDir ¶
ClientDriverExtensionRemoveDir is an extension to implement if you need to distinguish between the FTP command DELE (remove a file) and RMD (remove a dir). If you don't implement this extension they will be both mapped to the Remove method defined in your afero.Fs implementation
type ClientDriverExtensionSymlink ¶
type ClientDriverExtensionSymlink interface { // Symlink creates a symlink Symlink(oldname, newname string) error }
ClientDriverExtensionSymlink is an extension to support the "SITE SYMLINK" - symbolic link creation - command
type ClientDriverExtentionFileTransfer ¶
type ClientDriverExtentionFileTransfer interface { // GetHandle return an handle to upload or download a file based on flags: // os.O_RDONLY indicates a download // os.O_WRONLY indicates an upload and can be combined with os.O_APPEND (resume) or // os.O_CREATE (upload to new file/truncate) // // offset is the argument of a previous REST command, if any, or 0 GetHandle(name string, flags int, offset int64) (FileTransfer, error) }
ClientDriverExtentionFileTransfer is a convenience extension to allow to transfer files without requiring to implement the methods Create/Open/OpenFile for your custom afero.File.
type CommandDescription ¶
type CommandDescription struct { Open bool // Open to clients without auth TransferRelated bool // This is a command that can open a transfer connection SpecialAction bool // Command to handle even if there is a transfer in progress Fn func(*clientHandler, string) error // Function to handle it }
CommandDescription defines which function should be used and if it should be open to anyone or only logged in users
type DataChannel ¶
type DataChannel int8
DataChannel is the enumerable that represents the data channel (active or passive)
const ( DataChannelPassive DataChannel = iota + 1 DataChannelActive )
Supported data channel types
type DataConnectionRequirement ¶
type DataConnectionRequirement int8
DataConnectionRequirement is the enumerable that represents the supported protection mode for data channels
const ( // IPMatchRequired requires matching peer IP addresses of control and data connection IPMatchRequired DataConnectionRequirement = iota // IPMatchDisabled disables checking peer IP addresses of control and data connection IPMatchDisabled )
Supported data connection requirements
type FileTransfer ¶
FileTransfer defines the inferface for file transfers.
type FileTransferError ¶
type FileTransferError interface {
TransferError(err error)
}
FileTransferError is a FileTransfer extension used to notify errors.
type FtpServer ¶
type FtpServer struct { //Logger log.Logger // fclairamb/go-log generic logger Logger *logdot.Logdot // fclairamb/go-log generic logger // contains filtered or unexported fields }
FtpServer is where everything is stored We want to keep it as simple as possible
func NewFtpServer ¶
func NewFtpServer(driver MainDriver) *FtpServer
NewFtpServer creates a new FtpServer instance
func (*FtpServer) ListenAndServe ¶
ListenAndServe simply chains the Listen and Serve method calls
type GlobalTCPListenerBox ¶
type GlobalTCPListenerBox struct { Listener *net.TCPListener ClientNum int //传输客户端连接数 MaxClientsSingle int //允许最大的客户端连接数量 IsListened bool //是否已经启用监听 }
type HASHAlgo ¶
type HASHAlgo int8
HASHAlgo is the enumerable that represents the supported HASH algorithms
type MainDriver ¶
type MainDriver interface { // GetSettings returns some general settings around the server setup GetSettings() (*Settings, error) // ClientConnected is called to send the very first welcome message ClientConnected(cc ClientContext) (string, error) // ClientDisconnected is called when the user disconnects, even if he never authenticated ClientDisconnected(cc ClientContext) // AuthUser authenticates the user and selects an handling driver AuthUser(cc ClientContext, user, pass string) (ClientDriver, error) // GetTLSConfig returns a TLS Certificate to use // The certificate could frequently change if we use something like "let's encrypt" GetTLSConfig() (*tls.Config, error) }
MainDriver handles the authentication and ClientHandlingDriver selection
type MainDriverExtensionPassiveWrapper ¶
type MainDriverExtensionPassiveWrapper interface { // WrapPassiveListener is called after creating the listener for passive // data connections. // You can wrap the passed listener or just return it unmodified. // Returning an error will cause the passive connection to fail WrapPassiveListener(listener net.Listener) (net.Listener, error) }
MainDriverExtensionPassiveWrapper is an extension that allows to wrap the listener used for passive connection
type MainDriverExtensionTLSVerifier ¶
type MainDriverExtensionTLSVerifier interface { // VerifyConnection is called when receiving the "USER" command. // If it returns a non-nil error, the client will receive a 530 error and it will be disconnected. // If it returns a non-nil ClientDriver and a nil error the client will be authenticated. // If it returns a nil ClientDriver and a nil error the user password is required VerifyConnection(cc ClientContext, user string, tlsConn *tls.Conn) (ClientDriver, error) }
MainDriverExtensionTLSVerifier is an extension that allows to verify the TLS connection estabilished on the control channel
type MainDriverExtensionUserVerifier ¶
type MainDriverExtensionUserVerifier interface { // PreAuthUser is called when receiving the "USER" command before proceeding with any other checks // If it returns a non-nil error, the client will receive a 530 error and be disconnected. PreAuthUser(cc ClientContext, user string) error }
MainDriverExtensionUserVerifier is an extension that allows to control user access once username is known, before the authentication
type PublicIPResolver ¶
type PublicIPResolver func(ClientContext) (string, error)
PublicIPResolver takes a ClientContext for a connection and returns the public IP to use in the response to the PASV command, or an error if a public IP cannot be determined.
type Settings ¶
type Settings struct { Listener net.Listener // (Optional) To provide an already initialized listener ListenAddr string // Listening address PublicHost string // Public IP to expose (only an IP address is accepted at this stage) PublicIPResolver PublicIPResolver // (Optional) To fetch a public IP lookup PassiveTransferPortRange *PortRange // (Optional) Port Range for data connections. Random if not specified ActiveTransferPortNon20 bool // Do not impose the port 20 for active data transfer (#88, RFC 1579) IdleTimeout int // Maximum inactivity time before disconnecting (#58) ConnectionTimeout int // Maximum time to establish passive or active transfer connections DisableMLSD bool // Disable MLSD support DisableMLST bool // Disable MLST support DisableMFMT bool // Disable MFMT support (modify file mtime) Banner string // Banner to use in server status response TLSRequired TLSRequirement // defines the TLS mode DisableLISTArgs bool // Disable ls like options (-a,-la etc.) for directory listing DisableSite bool // Disable SITE command DisableActiveMode bool // Disable Active FTP EnableHASH bool // Enable support for calculating hash value of files DisableSTAT bool // Disable Server STATUS, STAT on files and directories will still work DisableSYST bool // Disable SYST EnableCOMB bool // Enable COMB support DefaultTransferType TransferType // Transfer type to use if the client don't send the TYPE command // ActiveConnectionsCheck defines the security requirements for active connections ActiveConnectionsCheck DataConnectionRequirement // PasvConnectionsCheck defines the security requirements for passive connections PasvConnectionsCheck DataConnectionRequirement MaxClientsSingle int //每个监听端口 能承载最大的客户端连接数量 }
Settings defines all the server settings
type TLSRequirement ¶
type TLSRequirement int8
TLSRequirement is the enumerable that represents the supported TLS mode
const ( ClearOrEncrypted TLSRequirement = iota MandatoryEncryption ImplicitEncryption )
TLS modes
type TransferType ¶
type TransferType int8
TransferType is the enumerable that represents the supported transfer types
const ( TransferTypeASCII TransferType = iota TransferTypeBinary )
Supported transfer type