network.ftp.go 8.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368
  1. package main
  2. import (
  3. "encoding/json"
  4. "errors"
  5. "log"
  6. "net/http"
  7. "strconv"
  8. prout "imuslab.com/arozos/mod/prouter"
  9. ftp "imuslab.com/arozos/mod/storage/ftp"
  10. )
  11. /*
  12. FTP Server related handlers
  13. */
  14. var (
  15. ftpServer *ftp.Handler
  16. )
  17. //Handle init of the FTP server endpoints
  18. func FTPServerInit() {
  19. //Register FTP Server Setting page
  20. registerSetting(settingModule{
  21. Name: "FTP Server",
  22. Desc: "File Transfer Protocol Server",
  23. IconPath: "SystemAO/disk/smart/img/small_icon.png",
  24. Group: "Network",
  25. StartDir: "SystemAO/disk/ftp.html",
  26. RequireAdmin: true,
  27. })
  28. //Register FTP Endpoints
  29. adminRouter := prout.NewModuleRouter(prout.RouterOption{
  30. ModuleName: "System Setting",
  31. AdminOnly: true,
  32. UserHandler: userHandler,
  33. DeniedHandler: func(w http.ResponseWriter, r *http.Request) {
  34. errorHandlePermissionDenied(w, r)
  35. },
  36. })
  37. //Create database related tables
  38. sysdb.NewTable("ftp")
  39. defaultEnable := false
  40. if sysdb.KeyExists("ftp", "default") {
  41. sysdb.Read("ftp", "default", &defaultEnable)
  42. } else {
  43. sysdb.Write("ftp", "default", false)
  44. }
  45. //Enable this service
  46. if defaultEnable {
  47. storageFTPServerStart()
  48. }
  49. adminRouter.HandleFunc("/system/storage/ftp/start", storageHandleFTPServerStart)
  50. adminRouter.HandleFunc("/system/storage/ftp/stop", storageHandleFTPServerStop)
  51. adminRouter.HandleFunc("/system/storage/ftp/upnp", storageHandleFTPuPnP)
  52. adminRouter.HandleFunc("/system/storage/ftp/status", storageHandleFTPServerStatus)
  53. adminRouter.HandleFunc("/system/storage/ftp/updateGroups", storageHandleFTPAccessUpdate)
  54. adminRouter.HandleFunc("/system/storage/ftp/setPort", storageHandleFTPSetPort)
  55. adminRouter.HandleFunc("/system/storage/ftp/passivemode", storageHandleFTPPassiveModeSettings)
  56. }
  57. /*
  58. Handle the settings for passive mode related files
  59. Example set commands
  60. set=ip&ip=123.456.789.1
  61. set=mode&passive=true
  62. */
  63. func storageHandleFTPPassiveModeSettings(w http.ResponseWriter, r *http.Request) {
  64. set, err := mv(r, "set", true)
  65. if err != nil {
  66. sendErrorResponse(w, "Invalid set type")
  67. return
  68. }
  69. if set == "ip" {
  70. //Updat the public up addr
  71. ip, err := mv(r, "ip", true)
  72. if err != nil {
  73. sendErrorResponse(w, "Invalid ip given")
  74. return
  75. }
  76. sysdb.Write("ftp", "publicip", ip)
  77. } else if set == "mode" {
  78. //Update the passive mode setting
  79. passive, err := mv(r, "passive", true)
  80. if err != nil {
  81. sendErrorResponse(w, "Invalid passive option (true/false)")
  82. return
  83. }
  84. log.Println("Updatng FTP Server PassiveMode to", passive)
  85. if passive == "true" {
  86. sysdb.Write("ftp", "passive", true)
  87. } else {
  88. sysdb.Write("ftp", "passive", false)
  89. }
  90. } else {
  91. sendErrorResponse(w, "Unknown setting filed")
  92. return
  93. }
  94. //Restart the FTP server if it is running now
  95. if ftpServer != nil && ftpServer.ServerRunning {
  96. storageFTPServerStart()
  97. }
  98. }
  99. //Start the FTP Server by request
  100. func storageHandleFTPServerStart(w http.ResponseWriter, r *http.Request) {
  101. err := storageFTPServerStart()
  102. if err != nil {
  103. sendErrorResponse(w, err.Error())
  104. }
  105. //Remember the FTP server status
  106. sysdb.Write("ftp", "default", true)
  107. sendOK(w)
  108. }
  109. //Stop the FTP server by request
  110. func storageHandleFTPServerStop(w http.ResponseWriter, r *http.Request) {
  111. if ftpServer != nil {
  112. ftpServer.Close()
  113. }
  114. sysdb.Write("ftp", "default", false)
  115. log.Println("FTP Server Stopped")
  116. sendOK(w)
  117. }
  118. //Update UPnP setting on FTP server
  119. func storageHandleFTPuPnP(w http.ResponseWriter, r *http.Request) {
  120. enable, _ := mv(r, "enable", false)
  121. if enable == "true" {
  122. log.Println("Enabling UPnP on FTP Server Port")
  123. sysdb.Write("ftp", "upnp", true)
  124. } else {
  125. log.Println("Disabling UPnP on FTP Server Port")
  126. sysdb.Write("ftp", "upnp", false)
  127. }
  128. //Restart FTP Server if server is running
  129. if ftpServer != nil && ftpServer.ServerRunning {
  130. storageFTPServerStart()
  131. }
  132. sendOK(w)
  133. }
  134. //Update access permission on FTP server
  135. func storageHandleFTPAccessUpdate(w http.ResponseWriter, r *http.Request) {
  136. //Get groups paramter from post req
  137. groupString, err := mv(r, "groups", true)
  138. if err != nil {
  139. sendErrorResponse(w, "groups not defined")
  140. return
  141. }
  142. //Prase it
  143. groups := []string{}
  144. err = json.Unmarshal([]byte(groupString), &groups)
  145. if err != nil {
  146. sendErrorResponse(w, "Unable to parse groups")
  147. return
  148. }
  149. log.Println("Updating FTP Access group to: ", groups)
  150. //Set the accessable group
  151. ftp.UpdateAccessableGroups(sysdb, groups)
  152. sendOK(w)
  153. }
  154. func storageHandleFTPSetPort(w http.ResponseWriter, r *http.Request) {
  155. port, err := mv(r, "port", true)
  156. if err != nil {
  157. sendErrorResponse(w, "Port not defined")
  158. return
  159. }
  160. //Try parse the port into int
  161. portInt, err := strconv.Atoi(port)
  162. if err != nil {
  163. sendErrorResponse(w, "Invalid port number")
  164. return
  165. }
  166. //Update the database port configuration
  167. sysdb.Write("ftp", "port", portInt)
  168. //Restart the FTP server
  169. storageFTPServerStart()
  170. sendOK(w)
  171. }
  172. func storageHandleFTPServerStatus(w http.ResponseWriter, r *http.Request) {
  173. type ServerStatus struct {
  174. Enabled bool
  175. Port int
  176. AllowUPNP bool
  177. UPNPEnabled bool
  178. FTPUpnpEnabled bool
  179. PublicAddr string
  180. PassiveMode bool
  181. UserGroups []string
  182. }
  183. enabled := false
  184. if ftpServer != nil && ftpServer.ServerRunning {
  185. enabled = true
  186. }
  187. serverPort := 21
  188. if sysdb.KeyExists("ftp", "port") {
  189. sysdb.Read("ftp", "port", &serverPort)
  190. }
  191. enableUPnP := false
  192. if sysdb.KeyExists("ftp", "upnp") {
  193. sysdb.Read("ftp", "upnp", &enableUPnP)
  194. }
  195. userGroups := []string{}
  196. if sysdb.KeyExists("ftp", "groups") {
  197. sysdb.Read("ftp", "groups", &userGroups)
  198. }
  199. ftpUpnp := false
  200. if ftpServer != nil && ftpServer.UPNPEnabled {
  201. ftpUpnp = true
  202. }
  203. publicAddr := ""
  204. if UPNP != nil && UPNP.ExternalIP != "" && ftpUpnp == true {
  205. publicAddr = UPNP.ExternalIP
  206. } else {
  207. manualPublicIpEntry := ""
  208. if sysdb.KeyExists("ftp", "publicip") {
  209. sysdb.Read("ftp", "publicip", &manualPublicIpEntry)
  210. }
  211. publicAddr = manualPublicIpEntry
  212. }
  213. forcePassiveMode := false
  214. if ftpUpnp == true {
  215. forcePassiveMode = true
  216. } else {
  217. if sysdb.KeyExists("ftp", "passive") {
  218. sysdb.Read("ftp", "passive", &forcePassiveMode)
  219. }
  220. if forcePassiveMode {
  221. //Read the ip setting from database
  222. manualPublicIpEntry := ""
  223. if sysdb.KeyExists("ftp", "publicip") {
  224. sysdb.Read("ftp", "publicip", &manualPublicIpEntry)
  225. }
  226. publicAddr = manualPublicIpEntry
  227. }
  228. }
  229. jsonString, _ := json.Marshal(ServerStatus{
  230. Enabled: enabled,
  231. Port: serverPort,
  232. AllowUPNP: *allow_upnp,
  233. UPNPEnabled: enableUPnP,
  234. FTPUpnpEnabled: ftpUpnp,
  235. PublicAddr: publicAddr,
  236. UserGroups: userGroups,
  237. PassiveMode: forcePassiveMode,
  238. })
  239. sendJSONResponse(w, string(jsonString))
  240. }
  241. func storageFTPServerStart() error {
  242. if ftpServer != nil {
  243. //If the previous ftp server is not closed, close it and open a new one
  244. if ftpServer.UPNPEnabled && UPNP != nil {
  245. UPNP.ClosePort(ftpServer.Port)
  246. }
  247. ftpServer.Close()
  248. }
  249. //Load new server config from database
  250. serverPort := int(21)
  251. if sysdb.KeyExists("ftp", "port") {
  252. sysdb.Read("ftp", "port", &serverPort)
  253. }
  254. enableUPnP := false
  255. if sysdb.KeyExists("ftp", "upnp") {
  256. sysdb.Read("ftp", "upnp", &enableUPnP)
  257. }
  258. forcePassiveMode := false
  259. sysdb.Read("ftp", "passive", &forcePassiveMode)
  260. //Create a new FTP Handler
  261. passiveModeIP := ""
  262. if *allow_upnp && enableUPnP {
  263. //Using External IP address from the UPnP router reply
  264. externalIP := UPNP.ExternalIP
  265. if externalIP != "" {
  266. passiveModeIP = externalIP
  267. }
  268. } else if forcePassiveMode {
  269. //Not allowing upnp but still use passive mode (aka manual port forward)
  270. externalIP := ""
  271. if sysdb.KeyExists("ftp", "publicip") {
  272. sysdb.Read("ftp", "publicip", &externalIP)
  273. }
  274. passiveModeIP = externalIP
  275. }
  276. h, err := ftp.NewFTPHandler(userHandler, *host_name, serverPort, *tmp_directory, passiveModeIP)
  277. if err != nil {
  278. return err
  279. }
  280. h.Start()
  281. ftpServer = h
  282. if *allow_upnp {
  283. if enableUPnP {
  284. if UPNP == nil {
  285. return errors.New("UPnP did not started correctly on this host. Ignore this option")
  286. } else {
  287. //Forward the port
  288. err := UPNP.ForwardPort(ftpServer.Port, *host_name+" FTP Server")
  289. if err != nil {
  290. log.Println("Failed to start FTP Server UPnP: ", err)
  291. ftpServer.UPNPEnabled = false
  292. return err
  293. } else {
  294. //Forward other data ports
  295. UPNP.ForwardPort(ftpServer.Port+1, *host_name+" FTP Data 1")
  296. UPNP.ForwardPort(ftpServer.Port+2, *host_name+" FTP Data 2")
  297. ftpServer.UPNPEnabled = true
  298. }
  299. return nil
  300. }
  301. } else {
  302. //UPNP disabled
  303. if UPNP == nil {
  304. return errors.New("UPnP did not started correctly on this host. Ignore this option")
  305. } else {
  306. UPNP.ClosePort(ftpServer.Port)
  307. UPNP.ClosePort(ftpServer.Port + 1)
  308. UPNP.ClosePort(ftpServer.Port + 2)
  309. ftpServer.UPNPEnabled = false
  310. }
  311. }
  312. }
  313. return nil
  314. }