sftpd.go 4.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132
  1. // Copyright (C) 2019-2023 Nicola Murino
  2. //
  3. // This program is free software: you can redistribute it and/or modify
  4. // it under the terms of the GNU Affero General Public License as published
  5. // by the Free Software Foundation, version 3.
  6. //
  7. // This program is distributed in the hope that it will be useful,
  8. // but WITHOUT ANY WARRANTY; without even the implied warranty of
  9. // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  10. // GNU Affero General Public License for more details.
  11. //
  12. // You should have received a copy of the GNU Affero General Public License
  13. // along with this program. If not, see <https://www.gnu.org/licenses/>.
  14. // Package sftpd implements the SSH File Transfer Protocol as described in https://tools.ietf.org/html/draft-ietf-secsh-filexfer-02.
  15. // It uses pkg/sftp library:
  16. // https://github.com/pkg/sftp
  17. package sftpd
  18. import (
  19. "strings"
  20. "time"
  21. "golang.org/x/crypto/ssh"
  22. )
  23. const (
  24. logSender = "sftpd"
  25. handshakeTimeout = 2 * time.Minute
  26. )
  27. var (
  28. supportedSSHCommands = []string{"scp", "md5sum", "sha1sum", "sha256sum", "sha384sum", "sha512sum", "cd", "pwd",
  29. "git-receive-pack", "git-upload-pack", "git-upload-archive", "rsync", "sftpgo-copy", "sftpgo-remove"}
  30. defaultSSHCommands = []string{"md5sum", "sha1sum", "sha256sum", "cd", "pwd", "scp"}
  31. sshHashCommands = []string{"md5sum", "sha1sum", "sha256sum", "sha384sum", "sha512sum"}
  32. systemCommands = []string{"git-receive-pack", "git-upload-pack", "git-upload-archive", "rsync"}
  33. serviceStatus ServiceStatus
  34. certKeyAlgoNames = map[string]string{
  35. ssh.CertAlgoRSAv01: ssh.KeyAlgoRSA,
  36. ssh.CertAlgoRSASHA256v01: ssh.KeyAlgoRSASHA256,
  37. ssh.CertAlgoRSASHA512v01: ssh.KeyAlgoRSASHA512,
  38. ssh.CertAlgoDSAv01: ssh.KeyAlgoDSA,
  39. ssh.CertAlgoECDSA256v01: ssh.KeyAlgoECDSA256,
  40. ssh.CertAlgoECDSA384v01: ssh.KeyAlgoECDSA384,
  41. ssh.CertAlgoECDSA521v01: ssh.KeyAlgoECDSA521,
  42. ssh.CertAlgoSKECDSA256v01: ssh.KeyAlgoSKECDSA256,
  43. ssh.CertAlgoED25519v01: ssh.KeyAlgoED25519,
  44. ssh.CertAlgoSKED25519v01: ssh.KeyAlgoSKED25519,
  45. }
  46. )
  47. type sshSubsystemExitStatus struct {
  48. Status uint32
  49. }
  50. type sshSubsystemExecMsg struct {
  51. Command string
  52. }
  53. type hostCertificate struct {
  54. Certificate *ssh.Certificate
  55. Path string
  56. }
  57. // HostKey defines the details for a used host key
  58. type HostKey struct {
  59. Path string `json:"path"`
  60. Fingerprint string `json:"fingerprint"`
  61. Algorithms []string `json:"algorithms"`
  62. }
  63. // GetAlgosAsString returns the host key algorithms as comma separated string
  64. func (h *HostKey) GetAlgosAsString() string {
  65. return strings.Join(h.Algorithms, ", ")
  66. }
  67. // ServiceStatus defines the service status
  68. type ServiceStatus struct {
  69. IsActive bool `json:"is_active"`
  70. Bindings []Binding `json:"bindings"`
  71. SSHCommands []string `json:"ssh_commands"`
  72. HostKeys []HostKey `json:"host_keys"`
  73. Authentications []string `json:"authentications"`
  74. MACs []string `json:"macs"`
  75. KexAlgorithms []string `json:"kex_algorithms"`
  76. Ciphers []string `json:"ciphers"`
  77. }
  78. // GetSSHCommandsAsString returns enabled SSH commands as comma separated string
  79. func (s *ServiceStatus) GetSSHCommandsAsString() string {
  80. return strings.Join(s.SSHCommands, ", ")
  81. }
  82. // GetSupportedAuthsAsString returns the supported authentications as comma separated string
  83. func (s *ServiceStatus) GetSupportedAuthsAsString() string {
  84. return strings.Join(s.Authentications, ", ")
  85. }
  86. // GetMACsAsString returns the enabled MAC algorithms as comma separated string
  87. func (s *ServiceStatus) GetMACsAsString() string {
  88. return strings.Join(s.MACs, ", ")
  89. }
  90. // GetKEXsAsString returns the enabled KEX algorithms as comma separated string
  91. func (s *ServiceStatus) GetKEXsAsString() string {
  92. return strings.Join(s.KexAlgorithms, ", ")
  93. }
  94. // GetCiphersAsString returns the enabled ciphers as comma separated string
  95. func (s *ServiceStatus) GetCiphersAsString() string {
  96. return strings.Join(s.Ciphers, ", ")
  97. }
  98. // GetStatus returns the server status
  99. func GetStatus() ServiceStatus {
  100. return serviceStatus
  101. }
  102. // GetDefaultSSHCommands returns the SSH commands enabled as default
  103. func GetDefaultSSHCommands() []string {
  104. result := make([]string, len(defaultSSHCommands))
  105. copy(result, defaultSSHCommands)
  106. return result
  107. }
  108. // GetSupportedSSHCommands returns the supported SSH commands
  109. func GetSupportedSSHCommands() []string {
  110. result := make([]string, len(supportedSSHCommands))
  111. copy(result, supportedSSHCommands)
  112. return result
  113. }