common

package
v1.2.2 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Nov 18, 2020 License: GPL-3.0 Imports: 25 Imported by: 0

Documentation

Overview

Package common defines code shared among file transfer packages and protocols

Index

Constants

View Source
const (
	StatAttrUIDGID = 1
	StatAttrPerms  = 2
	StatAttrTimes  = 4
	StatAttrSize   = 8
)

Stat flags

View Source
const (
	TransferUpload = iota
	TransferDownload
)

Transfer types

View Source
const (
	ProtocolSFTP   = "SFTP"
	ProtocolSCP    = "SCP"
	ProtocolSSH    = "SSH"
	ProtocolFTP    = "FTP"
	ProtocolWebDAV = "DAV"
)

Supported protocols

View Source
const (
	UploadModeStandard = iota
	UploadModeAtomic
	UploadModeAtomicWithResume
)

Upload modes

Variables

View Source
var (
	ErrPermissionDenied     = errors.New("permission denied")
	ErrNotExist             = errors.New("no such file or directory")
	ErrOpUnsupported        = errors.New("operation unsupported")
	ErrGenericFailure       = errors.New("failure")
	ErrQuotaExceeded        = errors.New("denying write due to space limit")
	ErrSkipPermissionsCheck = errors.New("permission check skipped")
	ErrConnectionDenied     = errors.New("You are not allowed to connect")
)

errors definitions

View Source
var (
	// Config is the configuration for the supported protocols
	Config Configuration
	// Connections is the list of active connections
	Connections ActiveConnections
	// QuotaScans is the list of active quota scans
	QuotaScans ActiveScans
)
View Source
var (
	// ErrTransferClosed defines the error returned for a closed transfer
	ErrTransferClosed = errors.New("transfer already closed")
)

Functions

func Initialize

func Initialize(c Configuration)

Initialize sets the common configuration

func InitializeActionHandler added in v1.2.0

func InitializeActionHandler(handler ActionHandler)

InitializeActionHandler lets the user choose an action handler implementation.

Do NOT call this function after application initialization.

func SSHCommandActionNotification

func SSHCommandActionNotification(user *dataprovider.User, filePath, target, sshCmd string, err error)

SSHCommandActionNotification executes the defined action for the specified SSH command.

Types

type ActionHandler added in v1.2.0

type ActionHandler interface {
	Handle(notification ActionNotification) error
}

ActionHandler handles a notification for a Protocol Action.

type ActionNotification added in v1.2.0

type ActionNotification struct {
	Action     string `json:"action"`
	Username   string `json:"username"`
	Path       string `json:"path"`
	TargetPath string `json:"target_path,omitempty"`
	SSHCmd     string `json:"ssh_cmd,omitempty"`
	FileSize   int64  `json:"file_size,omitempty"`
	FsProvider int    `json:"fs_provider"`
	Bucket     string `json:"bucket,omitempty"`
	Endpoint   string `json:"endpoint,omitempty"`
	Status     int    `json:"status"`
	Protocol   string `json:"protocol"`
}

ActionNotification defines a notification for a Protocol Action.

type ActiveConnection

type ActiveConnection interface {
	GetID() string
	GetUsername() string
	GetRemoteAddress() string
	GetClientVersion() string
	GetProtocol() string
	GetConnectionTime() time.Time
	GetLastActivity() time.Time
	GetCommand() string
	Disconnect() error
	AddTransfer(t ActiveTransfer)
	RemoveTransfer(t ActiveTransfer)
	GetTransfers() []ConnectionTransfer
}

ActiveConnection defines the interface for the current active connections

type ActiveConnections

type ActiveConnections struct {
	sync.RWMutex
	// contains filtered or unexported fields
}

ActiveConnections holds the currect active connections with the associated transfers

func (*ActiveConnections) Add

func (conns *ActiveConnections) Add(c ActiveConnection)

Add adds a new connection to the active ones

func (*ActiveConnections) AddSSHConnection

func (conns *ActiveConnections) AddSSHConnection(c *SSHConnection)

AddSSHConnection adds a new ssh connection to the active ones

func (*ActiveConnections) Close

func (conns *ActiveConnections) Close(connectionID string) bool

Close closes an active connection. It returns true on success

func (*ActiveConnections) GetActiveSessions

func (conns *ActiveConnections) GetActiveSessions(username string) int

GetActiveSessions returns the number of active sessions for the given username. We return the open sessions for any protocol

func (*ActiveConnections) GetStats

func (conns *ActiveConnections) GetStats() []ConnectionStatus

GetStats returns stats for active connections

func (*ActiveConnections) Remove

func (conns *ActiveConnections) Remove(connectionID string)

Remove removes a connection from the active ones

func (*ActiveConnections) RemoveSSHConnection

func (conns *ActiveConnections) RemoveSSHConnection(connectionID string)

RemoveSSHConnection removes a connection from the active ones

func (*ActiveConnections) Swap

func (conns *ActiveConnections) Swap(c ActiveConnection) error

Swap replaces an existing connection with the given one. This method is useful if you have to change some connection details for example for FTP is used to update the connection once the user authenticates

type ActiveQuotaScan

type ActiveQuotaScan struct {
	// Username to which the quota scan refers
	Username string `json:"username"`
	// quota scan start time as unix timestamp in milliseconds
	StartTime int64 `json:"start_time"`
}

ActiveQuotaScan defines an active quota scan for a user home dir

type ActiveScans

type ActiveScans struct {
	sync.RWMutex
	UserHomeScans []ActiveQuotaScan
	FolderScans   []ActiveVirtualFolderQuotaScan
}

ActiveScans holds the active quota scans

func (*ActiveScans) AddUserQuotaScan

func (s *ActiveScans) AddUserQuotaScan(username string) bool

AddUserQuotaScan adds a user to the ones with active quota scans. Returns false if the user has a quota scan already running

func (*ActiveScans) AddVFolderQuotaScan

func (s *ActiveScans) AddVFolderQuotaScan(folderPath string) bool

AddVFolderQuotaScan adds a virtual folder to the ones with active quota scans. Returns false if the folder has a quota scan already running

func (*ActiveScans) GetUsersQuotaScans

func (s *ActiveScans) GetUsersQuotaScans() []ActiveQuotaScan

GetUsersQuotaScans returns the active quota scans for users home directories

func (*ActiveScans) GetVFoldersQuotaScans

func (s *ActiveScans) GetVFoldersQuotaScans() []ActiveVirtualFolderQuotaScan

GetVFoldersQuotaScans returns the active quota scans for virtual folders

func (*ActiveScans) RemoveUserQuotaScan

func (s *ActiveScans) RemoveUserQuotaScan(username string) bool

RemoveUserQuotaScan removes a user from the ones with active quota scans. Returns false if the user has no active quota scans

func (*ActiveScans) RemoveVFolderQuotaScan

func (s *ActiveScans) RemoveVFolderQuotaScan(folderPath string) bool

RemoveVFolderQuotaScan removes a folder from the ones with active quota scans. Returns false if the folder has no active quota scans

type ActiveTransfer

type ActiveTransfer interface {
	GetID() uint64
	GetType() int
	GetSize() int64
	GetVirtualPath() string
	GetStartTime() time.Time
	SignalClose()
	Truncate(fsPath string, size int64) (int64, error)
	GetRealFsPath(fsPath string) string
}

ActiveTransfer defines the interface for the current active transfers

type ActiveVirtualFolderQuotaScan

type ActiveVirtualFolderQuotaScan struct {
	// folder path to which the quota scan refers
	MappedPath string `json:"mapped_path"`
	// quota scan start time as unix timestamp in milliseconds
	StartTime int64 `json:"start_time"`
}

ActiveVirtualFolderQuotaScan defines an active quota scan for a virtual folder

type BaseConnection

type BaseConnection struct {
	// Unique identifier for the connection
	ID string
	// user associated with this connection if any
	User dataprovider.User

	Fs vfs.Fs
	sync.RWMutex
	// contains filtered or unexported fields
}

BaseConnection defines common fields for a connection using any supported protocol

func NewBaseConnection

func NewBaseConnection(ID, protocol string, user dataprovider.User, fs vfs.Fs) *BaseConnection

NewBaseConnection returns a new BaseConnection

func (*BaseConnection) AddTransfer

func (c *BaseConnection) AddTransfer(t ActiveTransfer)

AddTransfer associates a new transfer to this connection

func (*BaseConnection) CreateDir

func (c *BaseConnection) CreateDir(fsPath, virtualPath string) error

CreateDir creates a new directory at the specified fsPath

func (c *BaseConnection) CreateSymlink(fsSourcePath, fsTargetPath, virtualSourcePath, virtualTargetPath string) error

CreateSymlink creates fsTargetPath as a symbolic link to fsSourcePath

func (*BaseConnection) DoStat

func (c *BaseConnection) DoStat(fsPath string, mode int) (os.FileInfo, error)

DoStat execute a Stat if mode = 0, Lstat if mode = 1

func (*BaseConnection) GetConnectionTime

func (c *BaseConnection) GetConnectionTime() time.Time

GetConnectionTime returns the initial connection time

func (*BaseConnection) GetFsError

func (c *BaseConnection) GetFsError(err error) error

GetFsError converts a filesystem error to a protocol error

func (*BaseConnection) GetGenericError

func (c *BaseConnection) GetGenericError(err error) error

GetGenericError returns an appropriate generic error for the connection protocol

func (*BaseConnection) GetID

func (c *BaseConnection) GetID() string

GetID returns the connection ID

func (*BaseConnection) GetLastActivity

func (c *BaseConnection) GetLastActivity() time.Time

GetLastActivity returns the last connection activity

func (*BaseConnection) GetMaxWriteSize

func (c *BaseConnection) GetMaxWriteSize(quotaResult vfs.QuotaCheckResult, isResume bool, fileSize int64) (int64, error)

GetMaxWriteSize returns the allowed size for an upload or an error if no enough size is available for a resume/append

func (*BaseConnection) GetNotExistError

func (c *BaseConnection) GetNotExistError() error

GetNotExistError returns an appropriate not exist error for the connection protocol

func (*BaseConnection) GetOpUnsupportedError

func (c *BaseConnection) GetOpUnsupportedError() error

GetOpUnsupportedError returns an appropriate operation not supported error for the connection protocol

func (*BaseConnection) GetPermissionDeniedError

func (c *BaseConnection) GetPermissionDeniedError() error

GetPermissionDeniedError returns an appropriate permission denied error for the connection protocol

func (*BaseConnection) GetProtocol

func (c *BaseConnection) GetProtocol() string

GetProtocol returns the protocol for the connection

func (*BaseConnection) GetTransferID

func (c *BaseConnection) GetTransferID() uint64

GetTransferID returns an unique transfer ID for this connection

func (*BaseConnection) GetTransfers

func (c *BaseConnection) GetTransfers() []ConnectionTransfer

GetTransfers returns the active transfers

func (*BaseConnection) GetUsername

func (c *BaseConnection) GetUsername() string

GetUsername returns the authenticated username associated with this connection if any

func (*BaseConnection) HasSpace

func (c *BaseConnection) HasSpace(checkFiles bool, requestPath string) vfs.QuotaCheckResult

HasSpace checks user's quota usage

func (*BaseConnection) IsRemoveDirAllowed

func (c *BaseConnection) IsRemoveDirAllowed(fsPath, virtualPath string) error

IsRemoveDirAllowed returns an error if removing this directory is not allowed

func (*BaseConnection) IsRemoveFileAllowed

func (c *BaseConnection) IsRemoveFileAllowed(fsPath, virtualPath string) error

IsRemoveFileAllowed returns an error if removing this file is not allowed

func (*BaseConnection) ListDir

func (c *BaseConnection) ListDir(fsPath, virtualPath string) ([]os.FileInfo, error)

ListDir reads the directory named by fsPath and returns a list of directory entries

func (*BaseConnection) Log

func (c *BaseConnection) Log(level logger.LogLevel, format string, v ...interface{})

Log outputs a log entry to the configured logger

func (*BaseConnection) RemoveDir

func (c *BaseConnection) RemoveDir(fsPath, virtualPath string) error

RemoveDir removes a directory at the specified fsPath

func (*BaseConnection) RemoveFile

func (c *BaseConnection) RemoveFile(fsPath, virtualPath string, info os.FileInfo) error

RemoveFile removes a file at the specified fsPath

func (*BaseConnection) RemoveTransfer

func (c *BaseConnection) RemoveTransfer(t ActiveTransfer)

RemoveTransfer removes the specified transfer from the active ones

func (*BaseConnection) Rename

func (c *BaseConnection) Rename(fsSourcePath, fsTargetPath, virtualSourcePath, virtualTargetPath string) error

Rename renames (moves) fsSourcePath to fsTargetPath

func (*BaseConnection) SetProtocol

func (c *BaseConnection) SetProtocol(protocol string)

SetProtocol sets the protocol for this connection

func (*BaseConnection) SetStat

func (c *BaseConnection) SetStat(fsPath, virtualPath string, attributes *StatAttributes) error

SetStat set StatAttributes for the specified fsPath

func (*BaseConnection) SignalTransfersAbort

func (c *BaseConnection) SignalTransfersAbort() error

SignalTransfersAbort signals to the active transfers to exit as soon as possible

func (*BaseConnection) UpdateLastActivity

func (c *BaseConnection) UpdateLastActivity()

UpdateLastActivity updates last activity for this connection

type BaseTransfer

type BaseTransfer struct {
	ID         uint64
	Fs         vfs.Fs
	File       vfs.File
	Connection *BaseConnection

	MinWriteOffset int64
	InitialSize    int64

	BytesSent     int64
	BytesReceived int64
	MaxWriteSize  int64
	AbortTransfer int32
	sync.Mutex
	ErrTransfer error
	// contains filtered or unexported fields
}

BaseTransfer contains protocols common transfer details for an upload or a download.

func NewBaseTransfer

func NewBaseTransfer(file vfs.File, conn *BaseConnection, cancelFn func(), fsPath, requestPath string, transferType int,
	minWriteOffset, initialSize, maxWriteSize int64, isNewFile bool, fs vfs.Fs) *BaseTransfer

NewBaseTransfer returns a new BaseTransfer and adds it to the given connection

func (*BaseTransfer) Close

func (t *BaseTransfer) Close() error

Close it is called when the transfer is completed. It logs the transfer info, updates the user quota (for uploads) and executes any defined action. If there is an error no action will be executed and, in atomic mode, we try to delete the temporary file

func (*BaseTransfer) GetFsPath

func (t *BaseTransfer) GetFsPath() string

GetFsPath returns the transfer filesystem path

func (*BaseTransfer) GetID

func (t *BaseTransfer) GetID() uint64

GetID returns the transfer ID

func (*BaseTransfer) GetRealFsPath

func (t *BaseTransfer) GetRealFsPath(fsPath string) string

GetRealFsPath returns the real transfer filesystem path. If atomic uploads are enabled this differ from fsPath

func (*BaseTransfer) GetSize

func (t *BaseTransfer) GetSize() int64

GetSize returns the transferred size

func (*BaseTransfer) GetStartTime

func (t *BaseTransfer) GetStartTime() time.Time

GetStartTime returns the start time

func (*BaseTransfer) GetType

func (t *BaseTransfer) GetType() int

GetType returns the transfer type

func (*BaseTransfer) GetVirtualPath

func (t *BaseTransfer) GetVirtualPath() string

GetVirtualPath returns the transfer virtual path

func (*BaseTransfer) HandleThrottle

func (t *BaseTransfer) HandleThrottle()

HandleThrottle manage bandwidth throttling

func (*BaseTransfer) SetCancelFn

func (t *BaseTransfer) SetCancelFn(cancelFn func())

SetCancelFn sets the cancel function for the transfer

func (*BaseTransfer) SignalClose

func (t *BaseTransfer) SignalClose()

SignalClose signals that the transfer should be closed. For same protocols, for example WebDAV, we have no access to the network connection, so we use this method to make the next read or write to fail

func (*BaseTransfer) TransferError

func (t *BaseTransfer) TransferError(err error)

TransferError is called if there is an unexpected error. For example network or client issues

func (*BaseTransfer) Truncate

func (t *BaseTransfer) Truncate(fsPath string, size int64) (int64, error)

Truncate changes the size of the opened file. Supported for local fs only

type CertManager

type CertManager struct {
	sync.RWMutex
	// contains filtered or unexported fields
}

CertManager defines a TLS certificate manager

func NewCertManager

func NewCertManager(certificateFile, certificateKeyFile, logSender string) (*CertManager, error)

NewCertManager creates a new certificate manager

func (*CertManager) GetCertificateFunc

func (m *CertManager) GetCertificateFunc() func(*tls.ClientHelloInfo) (*tls.Certificate, error)

GetCertificateFunc returns the loaded certificate

func (*CertManager) LoadCertificate

func (m *CertManager) LoadCertificate(logSender string) error

LoadCertificate loads the configured x509 key pair

type Configuration

type Configuration struct {
	// Maximum idle timeout as minutes. If a client is idle for a time that exceeds this setting it will be disconnected.
	// 0 means disabled
	IdleTimeout int `json:"idle_timeout" mapstructure:"idle_timeout"`
	// UploadMode 0 means standard, the files are uploaded directly to the requested path.
	// 1 means atomic: the files are uploaded to a temporary path and renamed to the requested path
	// when the client ends the upload. Atomic mode avoid problems such as a web server that
	// serves partial files when the files are being uploaded.
	// In atomic mode if there is an upload error the temporary file is deleted and so the requested
	// upload path will not contain a partial file.
	// 2 means atomic with resume support: as atomic but if there is an upload error the temporary
	// file is renamed to the requested path and not deleted, this way a client can reconnect and resume
	// the upload.
	UploadMode int `json:"upload_mode" mapstructure:"upload_mode"`
	// Actions to execute for SFTP file operations and SSH commands
	Actions ProtocolActions `json:"actions" mapstructure:"actions"`
	// SetstatMode 0 means "normal mode": requests for changing permissions and owner/group are executed.
	// 1 means "ignore mode": requests for changing permissions and owner/group are silently ignored.
	// 2 means "ignore mode for cloud fs": requests for changing permissions and owner/group/time are
	// silently ignored for cloud based filesystem such as S3, GCS, Azure Blob
	SetstatMode int `json:"setstat_mode" mapstructure:"setstat_mode"`
	// Support for HAProxy PROXY protocol.
	// If you are running SFTPGo behind a proxy server such as HAProxy, AWS ELB or NGNIX, you can enable
	// the proxy protocol. It provides a convenient way to safely transport connection information
	// such as a client's address across multiple layers of NAT or TCP proxies to get the real
	// client IP address instead of the proxy IP. Both protocol versions 1 and 2 are supported.
	// - 0 means disabled
	// - 1 means proxy protocol enabled. Proxy header will be used and requests without proxy header will be accepted.
	// - 2 means proxy protocol required. Proxy header will be used and requests without proxy header will be rejected.
	// If the proxy protocol is enabled in SFTPGo then you have to enable the protocol in your proxy configuration too,
	// for example for HAProxy add "send-proxy" or "send-proxy-v2" to each server configuration line.
	ProxyProtocol int `json:"proxy_protocol" mapstructure:"proxy_protocol"`
	// List of IP addresses and IP ranges allowed to send the proxy header.
	// If proxy protocol is set to 1 and we receive a proxy header from an IP that is not in the list then the
	// connection will be accepted and the header will be ignored.
	// If proxy protocol is set to 2 and we receive a proxy header from an IP that is not in the list then the
	// connection will be rejected.
	ProxyAllowed []string `json:"proxy_allowed" mapstructure:"proxy_allowed"`
	// Absolute path to an external program or an HTTP URL to invoke after a user connects
	// and before he tries to login. It allows you to reject the connection based on the source
	// ip address. Leave empty do disable.
	PostConnectHook string `json:"post_connect_hook" mapstructure:"post_connect_hook"`
	// contains filtered or unexported fields
}

Configuration defines configuration parameters common to all supported protocols

func (*Configuration) ExecutePostConnectHook

func (c *Configuration) ExecutePostConnectHook(remoteAddr, protocol string) error

ExecutePostConnectHook executes the post connect hook if defined

func (*Configuration) GetProxyListener

func (c *Configuration) GetProxyListener(listener net.Listener) (*proxyproto.Listener, error)

GetProxyListener returns a wrapper for the given listener that supports the HAProxy Proxy Protocol or nil if the proxy protocol is not configured

func (*Configuration) IsAtomicUploadEnabled

func (c *Configuration) IsAtomicUploadEnabled() bool

IsAtomicUploadEnabled returns true if atomic upload is enabled

type ConnectionStatus

type ConnectionStatus struct {
	// Logged in username
	Username string `json:"username"`
	// Unique identifier for the connection
	ConnectionID string `json:"connection_id"`
	// client's version string
	ClientVersion string `json:"client_version,omitempty"`
	// Remote address for this connection
	RemoteAddress string `json:"remote_address"`
	// Connection time as unix timestamp in milliseconds
	ConnectionTime int64 `json:"connection_time"`
	// Last activity as unix timestamp in milliseconds
	LastActivity int64 `json:"last_activity"`
	// Protocol for this connection
	Protocol string `json:"protocol"`
	// active uploads/downloads
	Transfers []ConnectionTransfer `json:"active_transfers,omitempty"`
	// SSH command or WevDAV method
	Command string `json:"command,omitempty"`
}

ConnectionStatus returns the status for an active connection

func (ConnectionStatus) GetConnectionDuration

func (c ConnectionStatus) GetConnectionDuration() string

GetConnectionDuration returns the connection duration as string

func (ConnectionStatus) GetConnectionInfo

func (c ConnectionStatus) GetConnectionInfo() string

GetConnectionInfo returns connection info. Protocol,Client Version and RemoteAddress are returned. For SSH commands the issued command is returned too.

func (ConnectionStatus) GetTransfersAsString

func (c ConnectionStatus) GetTransfersAsString() string

GetTransfersAsString returns the active transfers as string

type ConnectionTransfer

type ConnectionTransfer struct {
	ID            uint64 `json:"-"`
	OperationType string `json:"operation_type"`
	StartTime     int64  `json:"start_time"`
	Size          int64  `json:"size"`
	VirtualPath   string `json:"path"`
}

ConnectionTransfer defines the trasfer details to expose

type ProtocolActions

type ProtocolActions struct {
	// Valid values are download, upload, pre-delete, delete, rename, ssh_cmd. Empty slice to disable
	ExecuteOn []string `json:"execute_on" mapstructure:"execute_on"`
	// Absolute path to an external program or an HTTP URL
	Hook string `json:"hook" mapstructure:"hook"`
}

ProtocolActions defines the action to execute on file operations and SSH commands

type SSHConnection

type SSHConnection struct {
	// contains filtered or unexported fields
}

SSHConnection defines an ssh connection. Each SSH connection can open several channels for SFTP or SSH commands

func NewSSHConnection

func NewSSHConnection(id string, conn net.Conn) *SSHConnection

NewSSHConnection returns a new SSHConnection

func (*SSHConnection) Close

func (c *SSHConnection) Close() error

Close closes the underlying network connection

func (*SSHConnection) GetID

func (c *SSHConnection) GetID() string

GetID returns the ID for this SSHConnection

func (*SSHConnection) GetLastActivity

func (c *SSHConnection) GetLastActivity() time.Time

GetLastActivity returns the last connection activity

func (*SSHConnection) UpdateLastActivity

func (c *SSHConnection) UpdateLastActivity()

UpdateLastActivity updates last activity for this connection

type StatAttributes

type StatAttributes struct {
	Mode  os.FileMode
	Atime time.Time
	Mtime time.Time
	UID   int
	GID   int
	Flags int
	Size  int64
}

StatAttributes defines the attributes for set stat commands

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL