ftpserv.go 6.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259
  1. package ftpserv
  2. import (
  3. "errors"
  4. "imuslab.com/arozos/mod/database"
  5. "imuslab.com/arozos/mod/fileservers"
  6. "imuslab.com/arozos/mod/info/logger"
  7. upnp "imuslab.com/arozos/mod/network/upnp"
  8. "imuslab.com/arozos/mod/storage/ftp"
  9. user "imuslab.com/arozos/mod/user"
  10. )
  11. type ServerStatus struct {
  12. Enabled bool
  13. Port int
  14. AllowUpnp bool
  15. UPNPEnabled bool
  16. FTPUPNPEnabled bool
  17. PublicAddr string
  18. PassiveMode bool
  19. UserGroups []string
  20. }
  21. type ManagerOption struct {
  22. Hostname string
  23. TmpFolder string
  24. Logger *logger.Logger
  25. UserManager *user.UserHandler
  26. FtpServer *ftp.Handler
  27. Sysdb *database.Database
  28. Upnp *upnp.UPnPClient
  29. AllowUpnp bool
  30. }
  31. type Manager struct {
  32. option ManagerOption
  33. }
  34. //Create a new FTP Manager
  35. func NewFTPManager(option *ManagerOption) *Manager {
  36. //Create database related tables
  37. option.Sysdb.NewTable("ftp")
  38. defaultEnable := false
  39. if option.Sysdb.KeyExists("ftp", "default") {
  40. option.Sysdb.Read("ftp", "default", &defaultEnable)
  41. } else {
  42. option.Sysdb.Write("ftp", "default", false)
  43. }
  44. //Create the Manager object
  45. manager := Manager{
  46. option: *option,
  47. }
  48. //Enable this service
  49. if defaultEnable {
  50. manager.StartFtpServer()
  51. }
  52. return &manager
  53. }
  54. func (m *Manager) StartFtpServer() error {
  55. if m.option.FtpServer != nil {
  56. //If the previous ftp server is not closed, close it and open a new one
  57. if m.option.FtpServer.UPNPEnabled && m.option.Upnp != nil {
  58. m.option.Upnp.ClosePort(m.option.FtpServer.Port)
  59. }
  60. m.option.FtpServer.Close()
  61. }
  62. //Load new server config from database
  63. serverPort := int(21)
  64. if m.option.Sysdb.KeyExists("ftp", "port") {
  65. m.option.Sysdb.Read("ftp", "port", &serverPort)
  66. }
  67. enableUpnp := false
  68. if m.option.Sysdb.KeyExists("ftp", "Upnp") {
  69. m.option.Sysdb.Read("ftp", "Upnp", &enableUpnp)
  70. }
  71. forcePassiveMode := false
  72. m.option.Sysdb.Read("ftp", "passive", &forcePassiveMode)
  73. //Create a new FTP Handler
  74. passiveModeIP := ""
  75. if m.option.AllowUpnp && enableUpnp {
  76. //Using External IP address from the Upnp router reply
  77. externalIP := m.option.Upnp.ExternalIP
  78. if externalIP != "" {
  79. passiveModeIP = externalIP
  80. }
  81. } else if forcePassiveMode {
  82. //Not allowing Upnp but still use passive mode (aka manual port forward)
  83. externalIP := ""
  84. if m.option.Sysdb.KeyExists("ftp", "publicip") {
  85. m.option.Sysdb.Read("ftp", "publicip", &externalIP)
  86. }
  87. passiveModeIP = externalIP
  88. }
  89. h, err := ftp.NewFTPHandler(m.option.UserManager, m.option.Hostname, serverPort, m.option.TmpFolder, passiveModeIP)
  90. if err != nil {
  91. return err
  92. }
  93. h.Start()
  94. m.option.FtpServer = h
  95. if m.option.AllowUpnp {
  96. if enableUpnp {
  97. if m.option.Upnp == nil {
  98. return errors.New("Upnp did not started correctly on this host. Ignore this option")
  99. } else {
  100. //Forward the port
  101. err := m.option.Upnp.ForwardPort(m.option.FtpServer.Port, m.option.Hostname+" FTP Server")
  102. if err != nil {
  103. m.option.Logger.PrintAndLog("FTP", "Failed to start FTP Server Upnp ", err)
  104. m.option.FtpServer.UPNPEnabled = false
  105. return err
  106. } else {
  107. //Forward other data ports
  108. m.option.Upnp.ForwardPort(m.option.FtpServer.Port+1, m.option.Hostname+" FTP Data 1")
  109. m.option.Upnp.ForwardPort(m.option.FtpServer.Port+2, m.option.Hostname+" FTP Data 2")
  110. m.option.FtpServer.UPNPEnabled = true
  111. }
  112. return nil
  113. }
  114. } else {
  115. //Upnp disabled
  116. if m.option.Upnp == nil {
  117. return errors.New("Upnp did not started correctly on this host. Ignore this option")
  118. } else {
  119. m.option.Upnp.ClosePort(m.option.FtpServer.Port)
  120. m.option.Upnp.ClosePort(m.option.FtpServer.Port + 1)
  121. m.option.Upnp.ClosePort(m.option.FtpServer.Port + 2)
  122. m.option.FtpServer.UPNPEnabled = false
  123. }
  124. }
  125. }
  126. //Remember the FTP server status
  127. m.option.Sysdb.Write("ftp", "default", true)
  128. return nil
  129. }
  130. func (m *Manager) StopFtpServer() {
  131. if m.option.FtpServer != nil {
  132. m.option.FtpServer.Close()
  133. }
  134. m.option.Sysdb.Write("ftp", "default", false)
  135. m.option.Logger.PrintAndLog("FTP", "FTP Server Stopped", nil)
  136. }
  137. func (m *Manager) GetFtpServerStatus() (*ServerStatus, error) {
  138. enabled := false
  139. if m.option.FtpServer != nil && m.option.FtpServer.ServerRunning {
  140. enabled = true
  141. }
  142. serverPort := 21
  143. if m.option.Sysdb.KeyExists("ftp", "port") {
  144. m.option.Sysdb.Read("ftp", "port", &serverPort)
  145. }
  146. enableUpnp := false
  147. if m.option.Sysdb.KeyExists("ftp", "Upnp") {
  148. m.option.Sysdb.Read("ftp", "Upnp", &enableUpnp)
  149. }
  150. userGroups := []string{}
  151. if m.option.Sysdb.KeyExists("ftp", "groups") {
  152. m.option.Sysdb.Read("ftp", "groups", &userGroups)
  153. }
  154. ftpUpnp := false
  155. if m.option.FtpServer != nil && m.option.FtpServer.UPNPEnabled {
  156. ftpUpnp = true
  157. }
  158. publicAddr := ""
  159. if m.option.Upnp != nil && m.option.Upnp.ExternalIP != "" && ftpUpnp == true {
  160. publicAddr = m.option.Upnp.ExternalIP
  161. } else {
  162. manualPublicIpEntry := ""
  163. if m.option.Sysdb.KeyExists("ftp", "publicip") {
  164. m.option.Sysdb.Read("ftp", "publicip", &manualPublicIpEntry)
  165. }
  166. publicAddr = manualPublicIpEntry
  167. }
  168. forcePassiveMode := false
  169. if ftpUpnp == true {
  170. forcePassiveMode = true
  171. } else {
  172. if m.option.Sysdb.KeyExists("ftp", "passive") {
  173. m.option.Sysdb.Read("ftp", "passive", &forcePassiveMode)
  174. }
  175. if forcePassiveMode {
  176. //Read the ip setting from database
  177. manualPublicIpEntry := ""
  178. if m.option.Sysdb.KeyExists("ftp", "publicip") {
  179. m.option.Sysdb.Read("ftp", "publicip", &manualPublicIpEntry)
  180. }
  181. publicAddr = manualPublicIpEntry
  182. }
  183. }
  184. currnetStatus := ServerStatus{
  185. Enabled: enabled,
  186. Port: serverPort,
  187. AllowUpnp: m.option.AllowUpnp,
  188. UPNPEnabled: enableUpnp,
  189. FTPUPNPEnabled: ftpUpnp,
  190. PublicAddr: publicAddr,
  191. UserGroups: userGroups,
  192. PassiveMode: forcePassiveMode,
  193. }
  194. return &currnetStatus, nil
  195. }
  196. func (m *Manager) IsFtpServerEnabled() bool {
  197. return m.option.FtpServer != nil && m.option.FtpServer.ServerRunning
  198. }
  199. func (m *Manager) FTPServerToggle(enabled bool) error {
  200. if m.option.FtpServer != nil && m.option.FtpServer.ServerRunning {
  201. //Enabled
  202. if !enabled {
  203. //Shut it down
  204. m.StopFtpServer()
  205. }
  206. } else if enabled {
  207. //Startup FTP Server
  208. return m.StartFtpServer()
  209. }
  210. return nil
  211. }
  212. func (m *Manager) FTPGetEndpoints(userinfo *user.User) []*fileservers.Endpoint {
  213. ftpEndpoints := []*fileservers.Endpoint{}
  214. port := 21
  215. if m.option.FtpServer != nil {
  216. port = m.option.FtpServer.Port
  217. }
  218. ftpEndpoints = append(ftpEndpoints, &fileservers.Endpoint{
  219. ProtocolName: "ftp://",
  220. Port: port,
  221. Subpath: "",
  222. })
  223. return ftpEndpoints
  224. }