network.forward.go 4.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172
  1. package main
  2. import (
  3. "encoding/json"
  4. "net/http"
  5. "strconv"
  6. prout "imuslab.com/arozos/mod/prouter"
  7. "imuslab.com/arozos/mod/utils"
  8. )
  9. /*
  10. Network Forward Interface
  11. author: tobychui
  12. This is an interface for providing a web UI for port forwarding to this host
  13. on different ports. Useful if you need to forward alternative ports for your
  14. services.
  15. */
  16. func portForwardInit() {
  17. //Create database table if not exists
  18. sysdb.NewTable("portforward")
  19. //Register modules
  20. if *allow_upnp {
  21. //Forward the previous registered paths
  22. entries, _ := sysdb.ListTable("portforward")
  23. for _, keypairs := range entries {
  24. portNumber, _ := strconv.Atoi(string(keypairs[0]))
  25. policyName := "Unknown Forward Rule"
  26. json.Unmarshal(keypairs[1], &policyName)
  27. //Forward the recorded port
  28. err := UPNP.ForwardPort(portNumber, policyName)
  29. if err != nil {
  30. systemWideLogger.PrintAndLog("UpnP", "Port Fordware Failed: "+err.Error()+". Skipping "+policyName, err)
  31. }
  32. }
  33. //Create a setting interface for port forward
  34. router := prout.NewModuleRouter(prout.RouterOption{
  35. ModuleName: "System Setting",
  36. AdminOnly: false,
  37. UserHandler: userHandler,
  38. DeniedHandler: func(w http.ResponseWriter, r *http.Request) {
  39. utils.SendErrorResponse(w, "Permission Denied")
  40. },
  41. })
  42. registerSetting(settingModule{
  43. Name: "Port Forward",
  44. Desc: "UPnP based port forwarding",
  45. IconPath: "SystemAO/network/img/portforward.png",
  46. Group: "Network",
  47. StartDir: "SystemAO/network/portforward.html",
  48. })
  49. router.HandleFunc("/system/network/portforward", portforward_handleForward)
  50. }
  51. }
  52. func portforward_handleForward(w http.ResponseWriter, r *http.Request) {
  53. opr, _ := utils.PostPara(r, "opr")
  54. if opr == "" {
  55. if UPNP == nil {
  56. utils.SendErrorResponse(w, "UPNP is not enabled")
  57. return
  58. }
  59. //List the current forward port and names
  60. type register struct {
  61. Port int
  62. Name string
  63. ReadOnly bool
  64. }
  65. forwardPorts := []register{}
  66. for _, port := range UPNP.RequiredPorts {
  67. //Get the name of the policy
  68. name, ok := UPNP.PolicyNames.Load(port)
  69. if !ok {
  70. name = "Unknown Service"
  71. }
  72. readOnly := false
  73. if port == *listen_port {
  74. //This is the port where the webUI is hosted. No change allowed
  75. readOnly = true
  76. }
  77. thisPort := register{
  78. Port: port,
  79. Name: name.(string),
  80. ReadOnly: readOnly,
  81. }
  82. //systemWideLogger.PrintAndLog(thisPort,nil)
  83. forwardPorts = append(forwardPorts, thisPort)
  84. }
  85. //Send the result as json
  86. js, _ := json.Marshal(forwardPorts)
  87. utils.SendJSONResponse(w, string(js))
  88. } else if opr == "add" {
  89. port, err := utils.PostPara(r, "port")
  90. if err != nil {
  91. utils.SendErrorResponse(w, "Invalid port number")
  92. return
  93. }
  94. //Convert port to int
  95. portNumberic, err := strconv.Atoi(port)
  96. if err != nil {
  97. utils.SendErrorResponse(w, "Invalid port number")
  98. return
  99. }
  100. //Get the policy name
  101. policyName, err := utils.PostPara(r, "name")
  102. if err != nil {
  103. policyName = "Unnamed Forward Policy"
  104. }
  105. //Write port forward rules to database
  106. sysdb.Write("portforward", strconv.Itoa(portNumberic), policyName)
  107. if UPNP != nil {
  108. //Forward the port
  109. err := UPNP.ForwardPort(portNumberic, policyName)
  110. if err != nil {
  111. utils.SendErrorResponse(w, err.Error())
  112. } else {
  113. utils.SendOK(w)
  114. }
  115. } else {
  116. utils.SendErrorResponse(w, "UPNP is not enabled")
  117. return
  118. }
  119. } else if opr == "remove" {
  120. port, err := utils.PostPara(r, "port")
  121. if err != nil {
  122. utils.SendErrorResponse(w, "Invalid port number")
  123. return
  124. }
  125. //Convert port to int
  126. portNumberic, err := strconv.Atoi(port)
  127. if err != nil {
  128. utils.SendErrorResponse(w, "Invalid port number")
  129. return
  130. }
  131. //Remove it from db if exists
  132. if sysdb.KeyExists("portforward", strconv.Itoa(portNumberic)) {
  133. //Key exists. Remove it from db
  134. sysdb.Delete("portforward", strconv.Itoa(portNumberic))
  135. }
  136. if UPNP != nil {
  137. err := UPNP.ClosePort(portNumberic)
  138. if err != nil {
  139. utils.SendErrorResponse(w, err.Error())
  140. } else {
  141. utils.SendOK(w)
  142. }
  143. } else {
  144. utils.SendErrorResponse(w, "UPNP is not enabled")
  145. return
  146. }
  147. }
  148. }