PageRenderTime 44ms CodeModel.GetById 15ms RepoModel.GetById 0ms app.codeStats 0ms

/lib/os_captive_portals/os_captive_portal.rb

https://github.com/idemarinis/OpenWISP-Captive-Portals-Manager
Ruby | 234 lines | 146 code | 46 blank | 42 comment | 6 complexity | 5b42ea58ff8fc800e8ed697444283573 MD5 | raw file
  1. # This file is part of the OpenWISP Captive Portal Manager
  2. #
  3. # Copyright (C) 2012 OpenWISP.org
  4. #
  5. # This program is free software: you can redistribute it and/or modify
  6. # it under the terms of the GNU General Public License as published by
  7. # the Free Software Foundation, either version 3 of the License, or
  8. # (at your option) any later version.
  9. #
  10. # This program is distributed in the hope that it will be useful,
  11. # but WITHOUT ANY WARRANTY; without even the implied warranty of
  12. # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  13. # GNU General Public License for more details.
  14. #
  15. # You should have received a copy of the GNU General Public License
  16. # along with this program. If not, see <http://www.gnu.org/licenses/>.
  17. require 'ipaddr'
  18. require 'singleton'
  19. module OsUtils
  20. # Test to see if a string contains a valid interface name
  21. def is_interface_name?(interface_name)
  22. not_implemented
  23. true
  24. end
  25. # Test to see if the passed parameter is a valid interface name
  26. def is_port?(port)
  27. if port.class == Fixnum
  28. (0..65535).include?(port.to_i)
  29. elsif port.class == String
  30. port =~ /\A\d+\Z/ and (0..65535).include?(port.to_i)
  31. else
  32. false
  33. end
  34. end
  35. # Test to see if the passed parameter is a valid ipv4 address
  36. def is_ipv4_address?(address)
  37. IPAddr.new(address).ipv4?
  38. end
  39. # Test to see if the passed parameter is a valid ipv6 address
  40. def is_ipv6_address?(address)
  41. IPAddr.new(address).ipv6?
  42. end
  43. # Test to see if the passed parameter is a valid mac address
  44. def is_mac_address?(address)
  45. (address =~ /\A([0-9a-f]{1,2}:){5}[0-9a-f]{1,2}\Z/i) != nil
  46. end
  47. # Returns the client mac address associated with the passed ipv4/v6 address
  48. def get_host_mac_address(address)
  49. not_implemented
  50. "00:00:00:00:00:00"
  51. end
  52. # Returns the interface that will be used to reach the passed ip address
  53. def get_interface(address)
  54. not_implemented
  55. "null"
  56. end
  57. # Returns the first ipv4 address assigned to the passed interface name
  58. def get_interface_ipv4_address(interface)
  59. not_implemented
  60. "127.0.0.1"
  61. end
  62. # Returns the first non-link-local ipv6 address assigned to the passed interface name
  63. def get_interface_ipv6_address(interface)
  64. not_implemented
  65. "::1"
  66. end
  67. def os_type
  68. ost = %x[uname -s]
  69. ost.chomp.downcase
  70. end
  71. module_function :os_type
  72. end
  73. class OsCaptivePortal
  74. include OsUtils
  75. DNS_PORT = 53
  76. DHCP_SRC_PORT = 68
  77. DHCP_DST_PORT = 67
  78. private
  79. def not_implemented
  80. puts "[WARNING] Missing (not implemented) code @ '#{caller.first}'"
  81. end
  82. public
  83. # Adds a new captive portal
  84. def start
  85. not_implemented
  86. end
  87. # Removes a captive portal
  88. # cp_interface is the name of the interface directly connected the clients
  89. def stop
  90. not_implemented
  91. end
  92. attr_reader :cp_interface, :wan_interface, :local_http_port, :local_https_port
  93. # Constructor
  94. # * cp_interface is the name of the interface directly connected the clients.
  95. # * wan_interface is the interface the clients will be allowed after the authentication
  96. # * local_http_port is the local port to witch client will be redirected to when they try to use the http protocol
  97. # * local_https_port is the local port used for authentication
  98. def initialize(cp_interface, wan_interface, local_http_port, local_https_port, options = {})
  99. raise("[BUG] Invalid CP Interface") unless is_interface_name?(cp_interface)
  100. raise("[BUG] Invalid WAN Interface") unless is_interface_name?(wan_interface)
  101. raise("[BUG] Invalid Local HTTP Port") unless is_port?(local_http_port)
  102. raise("[BUG] Invalid Local HTTPS Port") unless is_port?(local_https_port)
  103. @cp_interface = cp_interface
  104. @wan_interface = wan_interface
  105. @local_http_port = local_http_port
  106. @local_https_port = local_https_port
  107. @total_upload_bandwidth = options[:total_upload_bandwidth]
  108. @total_download_bandwidth = options[:total_download_bandwidth]
  109. @default_upload_bandwidth = options[:default_upload_bandwidth]
  110. @default_download_bandwidth = options[:default_download_bandwidth]
  111. end
  112. # Add an exception to firewall rules
  113. def add_allowed_traffic(options = {})
  114. not_implemented
  115. end
  116. # Removes an exception from firewall rules
  117. def remove_allowed_traffic(options = {})
  118. not_implemented
  119. end
  120. # Allows a client through the captive portal
  121. def add_user(client_address, client_mac_address, options = {})
  122. not_implemented
  123. end
  124. # Removes a client
  125. def remove_user(client_address, client_mac_address, options = {})
  126. not_implemented
  127. end
  128. # Returns uploaded and downloaded bytes (respectively) for a given client
  129. def get_user_bytes_counters(client_address)
  130. not_implemented
  131. [0,0]
  132. end
  133. # Returns uploaded and downloaded packets (respectively) for a given client
  134. def get_user_packets_counters(client_address)
  135. not_implemented
  136. [0,0]
  137. end
  138. end
  139. class OsControl
  140. include Singleton
  141. private
  142. def not_implemented
  143. puts "[WARNING] virtual method not implemented: '#{caller.first}'"
  144. end
  145. public
  146. # Initializes captive portal firewalling infrastructure
  147. def start
  148. not_implemented
  149. end
  150. # Finalize captive portal firewalling infrastructure
  151. def stop
  152. not_implemented
  153. end
  154. def initialize
  155. @captive_portals = Hash.new
  156. end
  157. def get_captive_portal(cp_interface)
  158. @captive_portals[cp_interface]
  159. end
  160. def add_captive_portal(cp_interface, wan_interface, local_http_port, local_https_port, options = {})
  161. raise("[BUG] Captive portal for #{cp_interface} already exists!") unless @captive_portals[cp_interface].nil?
  162. @captive_portals[cp_interface] = OsCaptivePortal.new(
  163. cp_interface,
  164. wan_interface,
  165. local_http_port,
  166. local_https_port,
  167. options
  168. )
  169. @captive_portals[cp_interface].start
  170. end
  171. def remove_captive_portal(cp_interface)
  172. raise("[BUG] Captive portal for #{cp_interface} doesn't exists!") unless @captive_portals[cp_interface]
  173. @captive_portals[cp_interface].stop
  174. @captive_portals.delete(cp_interface)
  175. end
  176. def OsControl.get_os_control
  177. os = OsUtils.os_type
  178. begin
  179. #noinspection RubyResolve
  180. require File.join(Rails.root.to_s, "lib", "os_captive_portals", "#{os}_captive_portal")
  181. puts "[INFO] Using #{os} Captive Portal Implementation"
  182. rescue LoadError
  183. puts "[WARNING] Using Abstract Captive Portal Implementation (#{os} needed)"
  184. end
  185. ensure
  186. return OsControl.instance
  187. end
  188. end