kuuko pushed a commit to branch master. http://git.enlightenment.org/apps/econnman.git/commit/?id=f797c7d2d8fd2a64e8d6ff74f862cd7d9bc1d4f9
commit f797c7d2d8fd2a64e8d6ff74f862cd7d9bc1d4f9 Author: Leif Middelschulte <leif.middelschu...@gmail.com> Date: Thu Dec 12 19:39:23 2013 +0100 Add support for ieee802.1x wireless networks. Connman does only support two phase authentication via config files. These config files reside in /var/lib/connman/ and are watched by the connman daemon. Unfortunatelly, connman does not support per session/user config files, so for simplicity's sake, we modify one in /var/lib/connman. With these changes, econnman manages a single file (/var/lib/connman/econnman.config), to which the user running it needs write access. By default the (empty) config file shipped with this packages has write permissions set for the group. Packagers might want to change the owner/group to root:users after installation or come around with a more sophisticated approach. --- AUTHORS | 2 + ChangeLog | 4 + Makefile.am | 6 ++ README | 1 + ChangeLog => data/config/econnman.config | 0 econnman-bin.in | 130 ++++++++++++++++++++++++++++++- 6 files changed, 142 insertions(+), 1 deletion(-) diff --git a/AUTHORS b/AUTHORS index 5ab1470..d236e58 100644 --- a/AUTHORS +++ b/AUTHORS @@ -1 +1,3 @@ Gustavo Sverzut Barbieri <barbi...@profusion.mobi> +Matthias Wauer <matthiaswa...@gmail.com> +Leif Middelschulte <leif.middelschu...@gmail.com> diff --git a/ChangeLog b/ChangeLog index e69de29..f51649d 100644 --- a/ChangeLog +++ b/ChangeLog @@ -0,0 +1,4 @@ +Since 1.1: +* Added basic support for ieee802.1x wireless networks configuration + The user running econnman needs to be able to write its own configfile at + /var/lib/connman/econnman.config diff --git a/Makefile.am b/Makefile.am index a65ebf2..83cf1ac 100644 --- a/Makefile.am +++ b/Makefile.am @@ -17,6 +17,12 @@ econnman-bin: $(top_srcdir)/econnman-bin.in $(top_builddir)/Makefile $(top_srcdir)/econnman-bin.in > $(top_builddir)/econnman-bin chmod +x $(top_builddir)/econnman-bin +configdir = $(localstatedir@)/lib/connman +dist_config_DATA = \ + data/config/econnman.config + +EXTRA_DIST += $(config_DATA) + desktopdir = $(datadir)/applications desktop_DATA = \ data/desktop/econnman-agent.desktop \ diff --git a/README b/README index 89a0ec5..ece4fb7 100644 --- a/README +++ b/README @@ -36,6 +36,7 @@ Build:: Install:: make install + chown root:users /var/lib/connman/econnman.config If you wish to install at alternative locations, then make sure to configure your PYTHONPATH to be able to access this location! diff --git a/ChangeLog b/data/config/econnman.config similarity index 100% copy from ChangeLog copy to data/config/econnman.config diff --git a/econnman-bin.in b/econnman-bin.in index 55d2256..3292638 100755 --- a/econnman-bin.in +++ b/econnman-bin.in @@ -14,6 +14,12 @@ import logging import argparse import os.path +''' For python2 backwards compatibility ''' +try: + import configparser +except ImportError: + import ConfigParser as configparser + try: import efl.evas as evas import efl.ecore as ecore @@ -58,6 +64,9 @@ log = logging.getLogger() manager = None +CONF_FILE = "/var/lib/connman/econnman.config" +configs = None + EXPAND_BOTH = (evas.EVAS_HINT_EXPAND, evas.EVAS_HINT_EXPAND) EXPAND_HORIZ = (evas.EVAS_HINT_EXPAND, 0.0) @@ -242,6 +251,52 @@ class ObjectView(object): en.callback_activated_add(callback) return lb, en +####################################################################### +# Config Files Helper: + +def config_del(name): + secname = 'service_' + name + if configs == None: + log.error("Config file was not parsed!") + return + if not configs.has_section(secname): + configs.remove_section(secname) + config_write(name) + +def config_set(name, key, value): + secname = 'service_' + name + if configs == None: + log.error("Config file was not parsed!") + return + if not configs.has_section(secname): + configs.add_section(secname) + configs.set(secname, 'Type', 'wifi') + configs.set(secname, 'Name', name) + if value != None: + configs.set(secname, key, value) + elif configs.has_option(secname, key): + configs.remove_option(sec, key) + config_write(name) + +def config_get(name): + if configs == None: + log.error("Config file was not parsed!") + return None + for sec in configs.sections(): + if configs.has_option(sec, 'Name') and configs.get(sec, 'Name') == name: + return sec + else: + return None + +def config_exists(name): + if config_get(name): + return True + else: + return False + +def config_write(name): + with open(CONF_FILE, 'w', encoding='utf8') as configfile: + configs.write(configfile) ######################################################################## # Views: @@ -803,13 +858,16 @@ class ServiceView(ObjectView): "proxy_frame", "ethernet_frame", "vpn_frame", + "ieee8021x_frame", ) def create_view(self, properties): self.type = str(properties.get("Type")) + self.security_mode = properties.get("Security") self.immutable = bool(properties.get("Immutable")) self.readwrite_list_properties = {} self.readwrite_list_widget = {} + self.name = str(properties.get("Name")) self.connect = self.add_button(self.box, "Connect", self._connect) self.disconnect = self.add_button(self.box, "Disconnect", @@ -890,6 +948,37 @@ class ServiceView(ObjectView): fr, bx = self.add_readonly_section("VPN", self.vpn_fields) self.vpn_frame = fr + # section 2 Phase Authentication + + if (self.type == "wifi") and ("ieee8021x" in self.security_mode): + fr, bx = self.add_frame_and_box(self.box, "ieee8021x") + self.ieee8021x_frame = fr + cfg_sec = config_get(self.name) + + lb = self.add_label(bx, "EAP:") + options = ("PEAP", "TLS", "TTLS", "None") + self.eap_method, self.eap_method_items = self.add_segment_control( + bx, options, self._on_eap_method) + if cfg_sec: + conf_val = configs.get(cfg_sec, 'EAP') + if conf_val == "peap": + self.eap_method_items["PEAP"].selected = True + elif conf_val == "tls": + self.eap_method_items["TLS"].selected = True + elif conf_val == "ttls": + self.eap_method_items["TTLS"].selected = True + + options = ("TLS", "MSCHAPv2", "None") + lb = self.add_label(bx, "Phase2:") + self.phase2, self.phase2_items = self.add_segment_control( + bx, options, self._on_phase2) + if cfg_sec: + conf_val = configs.get(cfg_sec, 'Phase2') + if conf_val == "tls": + self.phase2_items["TLS"].selected = True + elif conf_val == "MSCHAPV2": + self.phase2_items["MSCHAPv2"].selected = True + def add_readonly_section(self, title, fields): fr, bx = self.add_frame_and_box(self.box, title) for name, attr in fields: @@ -1108,7 +1197,10 @@ class ServiceView(ObjectView): log.error("Could not remove %s", exc) self.forget.disabled = False - self.bus_obj.Remove(reply_handler=on_reply, error_handler=on_error) + if self.security_mode == "ieee8021x": + config_del(self.name) + else: + self.bus_obj.Remove(reply_handler=on_reply, error_handler=on_error) self.forget.disabled = True def _on_user_auto_connect(self, obj): @@ -1232,6 +1324,31 @@ class ServiceView(ObjectView): pass #revert to configured values... + def _on_eap_method(self, obj, item): + eap_val = None + if item.text == "PEAP": + eap_val = "peap" + elif item.text == "TLS": + eap_val = "tls" + elif item.text == "TTLS": + eap_val = "ttls" + elif item.text == "None": + eap_val = None + + config_set(self.name, "EAP", eap_val) + return + + def _on_phase2(self, obj, item): + phase2_val = None + if item.text == "MSCHAPv2": + phase2_val = "MSCHAPV2" + elif item.text == "TLS": + phase2_val = "tls" + elif item.text == "None": + eap_val = None + + config_set(self.name, 'Phase2', phase2_val) + return ######################################################################## # Main Actions: @@ -1254,6 +1371,7 @@ def connect_service(path, properties): if type in ("system", "gps", "gadget"): log.error("cannot connect to service with type: %s", type) return + sec = properties.get("Security") name = properties.get("Name") if name: @@ -1261,6 +1379,12 @@ def connect_service(path, properties): log.debug("connect to %s (%s): %s", name, path, dbus_dict_to_str(properties)) + ''' Connman only supports 2 phase auth via config files ''' + if ("ieee8021x" in sec) and not config_exists(name): + popup_error(win, "This Network needs Configuration", "This network uses 802.1x authentication. Please configure the options in the section at the bottom.") + show_service(path, properties) + return + def on_reply(): log.info("Connected to %s (%s)", name, path) @@ -1486,6 +1610,10 @@ if __name__ == "__main__": level -= 10 * args.verbose log.setLevel(level) + configs = configparser.RawConfigParser() + configs.optionxform = str + configs.read(CONF_FILE) + elm.init() elm.policy_set(ELM_POLICY_QUIT, ELM_POLICY_QUIT_LAST_WINDOW_CLOSED) --