sftpd.go 4.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138
  1. // Copyright (C) 2019 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. "sftpgo-copy", "sftpgo-remove"}
  30. defaultSSHCommands = []string{"md5sum", "sha1sum", "sha256sum", "cd", "pwd", "scp"}
  31. sshHashCommands = []string{"md5sum", "sha1sum", "sha256sum", "sha384sum", "sha512sum"}
  32. serviceStatus ServiceStatus
  33. certKeyAlgoNames = map[string]string{
  34. ssh.CertAlgoRSAv01: ssh.KeyAlgoRSA,
  35. ssh.CertAlgoRSASHA256v01: ssh.KeyAlgoRSASHA256,
  36. ssh.CertAlgoRSASHA512v01: ssh.KeyAlgoRSASHA512,
  37. ssh.InsecureCertAlgoDSAv01: ssh.InsecureKeyAlgoDSA, //nolint:staticcheck
  38. ssh.CertAlgoECDSA256v01: ssh.KeyAlgoECDSA256,
  39. ssh.CertAlgoECDSA384v01: ssh.KeyAlgoECDSA384,
  40. ssh.CertAlgoECDSA521v01: ssh.KeyAlgoECDSA521,
  41. ssh.CertAlgoSKECDSA256v01: ssh.KeyAlgoSKECDSA256,
  42. ssh.CertAlgoED25519v01: ssh.KeyAlgoED25519,
  43. ssh.CertAlgoSKED25519v01: ssh.KeyAlgoSKED25519,
  44. }
  45. )
  46. type sshSubsystemExitStatus struct {
  47. Status uint32
  48. }
  49. type sshSubsystemExecMsg struct {
  50. Command string
  51. }
  52. type hostCertificate struct {
  53. Certificate *ssh.Certificate
  54. Path string
  55. }
  56. // HostKey defines the details for a used host key
  57. type HostKey struct {
  58. Path string `json:"path"`
  59. Fingerprint string `json:"fingerprint"`
  60. Algorithms []string `json:"algorithms"`
  61. }
  62. // GetAlgosAsString returns the host key algorithms as comma separated string
  63. func (h *HostKey) GetAlgosAsString() string {
  64. return strings.Join(h.Algorithms, ", ")
  65. }
  66. // ServiceStatus defines the service status
  67. type ServiceStatus struct {
  68. IsActive bool `json:"is_active"`
  69. Bindings []Binding `json:"bindings"`
  70. SSHCommands []string `json:"ssh_commands"`
  71. HostKeys []HostKey `json:"host_keys"`
  72. Authentications []string `json:"authentications"`
  73. MACs []string `json:"macs"`
  74. KexAlgorithms []string `json:"kex_algorithms"`
  75. Ciphers []string `json:"ciphers"`
  76. PublicKeyAlgorithms []string `json:"public_key_algorithms"`
  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. // GetPublicKeysAlgosAsString returns enabled public key authentication
  99. // algorithms as comma separated string
  100. func (s *ServiceStatus) GetPublicKeysAlgosAsString() string {
  101. return strings.Join(s.PublicKeyAlgorithms, ", ")
  102. }
  103. // GetStatus returns the server status
  104. func GetStatus() ServiceStatus {
  105. return serviceStatus
  106. }
  107. // GetDefaultSSHCommands returns the SSH commands enabled as default
  108. func GetDefaultSSHCommands() []string {
  109. result := make([]string, len(defaultSSHCommands))
  110. copy(result, defaultSSHCommands)
  111. return result
  112. }
  113. // GetSupportedSSHCommands returns the supported SSH commands
  114. func GetSupportedSSHCommands() []string {
  115. result := make([]string, len(supportedSSHCommands))
  116. copy(result, supportedSSHCommands)
  117. return result
  118. }