ftp_server.go 2.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990
  1. package ftpd
  2. import (
  3. "crypto/tls"
  4. "errors"
  5. "fmt"
  6. "github.com/spf13/afero"
  7. "net"
  8. ftpserver "github.com/fclairamb/ftpserverlib"
  9. "google.golang.org/grpc"
  10. )
  11. type FtpServerOption struct {
  12. Filer string
  13. IP string
  14. IpBind string
  15. Port int
  16. FilerGrpcAddress string
  17. FtpRoot string
  18. GrpcDialOption grpc.DialOption
  19. PassivePortStart int
  20. PassivePortStop int
  21. }
  22. type SftpServer struct {
  23. option *FtpServerOption
  24. ftpListener net.Listener
  25. fs *FtpFileSystem
  26. }
  27. var _ = ftpserver.MainDriver(&SftpServer{})
  28. // NewServer returns a new FTP server driver
  29. func NewFtpServer(ftpListener net.Listener, option *FtpServerOption) (*SftpServer, error) {
  30. fs, err := NewFtpFileSystem(option)
  31. server := &SftpServer{
  32. option: option,
  33. ftpListener: ftpListener,
  34. fs: fs,
  35. }
  36. return server, err
  37. }
  38. // GetSettings returns some general settings around the server setup
  39. func (s *SftpServer) GetSettings() (*ftpserver.Settings, error) {
  40. var portRange *ftpserver.PortRange
  41. if s.option.PassivePortStart > 0 && s.option.PassivePortStop > s.option.PassivePortStart {
  42. portRange = &ftpserver.PortRange{
  43. Start: s.option.PassivePortStart,
  44. End: s.option.PassivePortStop,
  45. }
  46. }
  47. return &ftpserver.Settings{
  48. Listener: s.ftpListener,
  49. ListenAddr: fmt.Sprintf("%s:%d", s.option.IpBind, s.option.Port),
  50. PublicHost: s.option.IP,
  51. PassiveTransferPortRange: portRange,
  52. ActiveTransferPortNon20: true,
  53. IdleTimeout: -1,
  54. ConnectionTimeout: 20,
  55. }, nil
  56. }
  57. // ClientConnected is called to send the very first welcome message
  58. func (s *SftpServer) ClientConnected(cc ftpserver.ClientContext) (string, error) {
  59. return "Welcome to SeaweedFS FTP Server", nil
  60. }
  61. // ClientDisconnected is called when the user disconnects, even if he never authenticated
  62. func (s *SftpServer) ClientDisconnected(cc ftpserver.ClientContext) {
  63. }
  64. // AuthUser authenticates the user and selects an handling driver
  65. func (s *SftpServer) AuthUser(cc ftpserver.ClientContext, username, password string) (ftpserver.ClientDriver, error) {
  66. return &ClientDriver{
  67. Fs: s.fs,
  68. }, nil
  69. }
  70. // GetTLSConfig returns a TLS Certificate to use
  71. // The certificate could frequently change if we use something like "let's encrypt"
  72. func (s *SftpServer) GetTLSConfig() (*tls.Config, error) {
  73. return nil, errors.New("no TLS certificate configured")
  74. }
  75. type ClientDriver struct {
  76. afero.Fs
  77. }