class VpnApp(App): def __init__(self, **kwargs): super(VpnApp, self).__init__(**kwargs) self.client = None self.server = None self.message_receiver = None self.debug = False self.continue_pressed = False def client_connected_callback(self, ip_addr, port): self.enable_disable_widgets( chat_input=True, send_button=True, debug_continue=False, ) sender = "SERVER" conn = self.client chat_panel = self.chat_panel if self.servermode.state == "down": self.chat_panel.write_info("Client connected from (%s, %i)" % (ip_addr, port)) sender = "CLIENT" conn = self.server self.message_receiver = MessageReceiver(sender, conn, chat_panel) self.message_receiver.start() # specify which widgets to enable. All unspecified widgets will get disabled def enable_disable_widgets( self, clientmode=None, servermode=None, ip_address=None, port=None, shared_value=None, connect=None, disconnect=None, chat_panel=None, chat_input=None, send_button=None, debug_switch=None, debug_continue=None, ): def enable_widget(enable, widget): if enable is None: return if enable: widget.disabled = False else: widget.disabled = True enable_widget(clientmode, self.clientmode) enable_widget(servermode, self.servermode) enable_widget(ip_address, self.ip_address) enable_widget(port, self.port) enable_widget(shared_value, self.shared_value) enable_widget(connect, self.connect) enable_widget(disconnect, self.disconnect) enable_widget(chat_panel, self.chat_panel) enable_widget(chat_input, self.chat_input) enable_widget(send_button, self.send_button) enable_widget(debug_continue, self.debug_continue) enable_widget(debug_switch, self.debug_switch) # called when 'Client' toggle button is pressed def client_callback(self, *args): state = args[1] if state == "down": self.settings_panel.add_widget(self.ip_address, 7) self.settings_panel.remove_widget(self.debug_boxlayout) self.settings_panel.remove_widget(self.debug_continue) self.chat_panel.write_info("Switched to Client Mode") # called when 'Server' toggle button is pressed def server_callback(self, *args): state = args[1] if state == "down": self.settings_panel.remove_widget(self.ip_address) self.settings_panel.add_widget(self.debug_boxlayout, 3) self.settings_panel.add_widget(self.debug_continue, 3) self.chat_panel.write_info("Switched to Server Mode") def debug_continue_callback(self, instance): self.continue_pressed = True # called when 'debug' toggled def debug_callback(self, btn, value): if value: self.debug = True else: self.debug = False # called when 'Connect' button is pressed def connect_callback(self, btn): self.disconnect.disabled = True # get inserted port number port = 0 for child in self.port.children: if isinstance(child, TextInput): try: port = int(child.text) except ValueError: self.chat_panel.write_info("Invalid port: " + child.text) return # get the shared key value shared_key = "" for child in self.shared_value.children: if isinstance(child, TextInput): shared_key = str(child.text) if not shared_key: self.chat_panel.write_info("Shared key must have some value") return # get the inserted ip address if (self.clientmode.state == 'down'): ip_address = "" for child in self.ip_address.children: if isinstance(child, TextInput): try: ip_address = child.text ipaddress.ip_address(unicode(child.text, 'utf-8')) except ValueError: #TODO: print error to chat panel self.chat_panel.write_info("Invalid IP Address: " + child.text) return if (self.servermode.state == 'down'): # vpn is in 'server' mode self.server = VpnServer( port, shared_key, self.client_connected_callback, self.broken_conn_callback, self.debug_continue, self.debug, self ) error, message = self.server.setup() if (error != 0): # error while setting up socket self.chat_panel.write_info(message) return else: self.chat_panel.write_info(message) self.enable_disable_widgets( clientmode=False, servermode=False, port=False, shared_value=False, connect=False, disconnect=True, chat_input=False, send_button=False, debug_switch=False, debug_continue=False, ) self.server.start(callback=self.client_connected_callback) else: # vpn is in 'client' mode self.client = VpnClient( ip_address, port, shared_key, self.broken_conn_callback, self ) error, message = self.client.connect() if (error != 0): self.chat_panel.write_info(message) return else: self.chat_panel.write_info(message) self.enable_disable_widgets( clientmode=False, servermode=False, ip_address=False, port=False, shared_value=False, connect=False, disconnect=True, chat_input=False, send_button=False, debug_switch=False, debug_continue=True, ) self.client_connected_callback(ip_address, port) def send_msg(self, btn): msg = self.chat_input.text if (len(msg) > 500): self.chat_panel.write_info("Input cannot be more than 500 characters") else: if self.servermode.state == 'down': self.chat_panel.write_server(msg) self.server.send(msg) else: self.chat_panel.write_client(msg) self.client.send(msg) self.chat_input.text = "" def SettingsEntry(self,text=None): boxlayout = BoxLayout(orientation="vertical", padding=30) self.label = Label(text=text, size=(300, 50),size_hint=(1, None)) boxlayout.add_widget(self.label) self.textinput = TextInput(multiline=False, size=(300, 50), size_hint=(1, None)) boxlayout.add_widget(self.textinput) return boxlayout def build(self): # create the root window for the app self.root = BoxLayout( orientation="horizontal", spacing=10, padding=10 ) # create settings panel self.settings_panel = ColoredBoxLayout( orientation="vertical", background_color=(0,169,184,0.5), size_hint=(0.3, 1), padding=10, ) self.root.add_widget(self.settings_panel) # client and server toggle buttons self.clientmode = ClientServerToggle( text='Client', group='mode', state='down', allow_no_selection=False, size=(300,100), size_hint=(1, None) ) self.servermode = ClientServerToggle( text='Server', group='mode', allow_no_selection=False, size=(300,100), size_hint=(1, None) ) self.clientmode.bind(state=self.client_callback) self.servermode.bind(state=self.server_callback) self.settings_panel.add_widget(self.clientmode) self.settings_panel.add_widget(self.servermode) # add empty space empty_widget = Widget() self.settings_panel.add_widget(empty_widget) # add ip address input self.ip_address = self.SettingsEntry(text="VPN Server IP Address") self.settings_panel.add_widget(self.ip_address) # add port input self.port = self.SettingsEntry(text="VPN Server Port") self.settings_panel.add_widget(self.port) # add shared value self.shared_value = self.SettingsEntry(text="Shared Secret Value") self.settings_panel.add_widget(self.shared_value) # add debug mode self.debug_boxlayout = BoxLayout(orientation="vertical", padding=30) self.debug_label = Label(text="Debug Mode", size=(300, 50), size_hint=(1, None)) self.debug_boxlayout.add_widget(self.debug_label) self.debug_switch = Switch(active=False, size=(300, 50), size_hint=(1, None)) self.debug_switch.bind(active=self.debug_callback) self.debug_boxlayout.add_widget(self.debug_switch) #self.settings_panel.add_widget(self.debug_boxlayout) # add debug continue button self.debug_continue = Button( text="Continue", background_color=(0,0,1,1), size=(300, 100), size_hint=(1, None), disabled=True, ) self.debug_continue.bind(on_press=self.debug_continue_callback) #self.settings_panel.add_widget(self.debug_continue) # add empty space empty_widget = Widget() self.settings_panel.add_widget(empty_widget) # add connect and disconnect buttons self.connect = Button( text="Connect", background_color=(0,1,0,1), size=(300, 150), size_hint=(1, None) ) self.connect.bind(on_press=self.connect_callback) self.disconnect = Button( text="Disconnect", background_color=(1,0,0,1), size=(300, 150), size_hint=(1, None), disabled=True, ) self.disconnect.bind(on_press=self.disconnect_callback) self.settings_panel.add_widget(self.connect) self.settings_panel.add_widget(self.disconnect) # create chat panel self.chat_layout = BoxLayout( orientation="vertical", spacing=10, size_hint=(0.7, 1) ) self.chat_panel = ChatPanel( markup=True, readonly=True, scroll_y=1, focused=True, cursor_color=(0,0,0,0), bar_color=(1,0,0,1), ) self.input_layout = BoxLayout( orientation="horizontal", spacing=10, size=(0, 50), size_hint=(1, None) ) self.chat_input = TextInput(size_hint=(0.8, 1)) self.send_button = Button(size_hint=(0.2, 1), text="Send") self.send_button.bind(on_press=self.send_msg) self.input_layout.add_widget(self.chat_input) self.input_layout.add_widget(self.send_button) self.chat_layout.add_widget(self.chat_panel) self.chat_layout.add_widget(self.input_layout) self.root.add_widget(self.chat_layout) self.chat_input.disabled=True self.send_button.disabled=True return self.root def broken_conn_callback(self): if self.message_receiver: self.message_receiver.close() if self.server: self.server.broken_conn() self.server.start(callback=self.client_connected_callback) self.chat_panel.write_info("Client disconnected") self.chat_panel.write_info("Listening for connections...") self.enable_disable_widgets( chat_input=False, send_button=False, debug_continue=False, ) else: self.client.close() self.enable_disable_widgets( clientmode=True, servermode=True, ip_address=True, port=True, shared_value=True, connect=True, disconnect=False, chat_input=False, send_button=False, debug_switch=True, debug_continue=False, ) self.chat_panel.write_info("Lost connection to server") def disconnect_callback(self, instance): if self.servermode.state == 'down': self.server.close() self.chat_panel.write_info("Closing Server...") else: self.client.close() self.chat_panel.write_info("Disconnecting from server...") if self.message_receiver: self.message_receiver.close() self.clientmode.disabled=False self.servermode.disabled=False self.ip_address.disabled=False self.port.disabled=False self.shared_value.disabled=False self.connect.disabled=False self.disconnect.disabled=True self.chat_input.disabled=True self.send_button.disabled=True self.debug_switch.disabled=False self.debug_continue.disabled=True def close(self): if self.server: self.server.close() if self.client: self.client.close() if self.message_receiver: self.message_receiver.close()
def connect_callback(self, btn): self.disconnect.disabled = True # get inserted port number port = 0 for child in self.port.children: if isinstance(child, TextInput): try: port = int(child.text) except ValueError: self.chat_panel.write_info("Invalid port: " + child.text) return # get the shared key value shared_key = "" for child in self.shared_value.children: if isinstance(child, TextInput): shared_key = str(child.text) if not shared_key: self.chat_panel.write_info("Shared key must have some value") return # get the inserted ip address if (self.clientmode.state == 'down'): ip_address = "" for child in self.ip_address.children: if isinstance(child, TextInput): try: ip_address = child.text ipaddress.ip_address(unicode(child.text, 'utf-8')) except ValueError: #TODO: print error to chat panel self.chat_panel.write_info("Invalid IP Address: " + child.text) return if (self.servermode.state == 'down'): # vpn is in 'server' mode self.server = VpnServer( port, shared_key, self.client_connected_callback, self.broken_conn_callback, self.debug_continue, self.debug, self ) error, message = self.server.setup() if (error != 0): # error while setting up socket self.chat_panel.write_info(message) return else: self.chat_panel.write_info(message) self.enable_disable_widgets( clientmode=False, servermode=False, port=False, shared_value=False, connect=False, disconnect=True, chat_input=False, send_button=False, debug_switch=False, debug_continue=False, ) self.server.start(callback=self.client_connected_callback) else: # vpn is in 'client' mode self.client = VpnClient( ip_address, port, shared_key, self.broken_conn_callback, self ) error, message = self.client.connect() if (error != 0): self.chat_panel.write_info(message) return else: self.chat_panel.write_info(message) self.enable_disable_widgets( clientmode=False, servermode=False, ip_address=False, port=False, shared_value=False, connect=False, disconnect=True, chat_input=False, send_button=False, debug_switch=False, debug_continue=True, ) self.client_connected_callback(ip_address, port)