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.
master
Leif Middelschulte 9 years ago committed by Kai Huuhko
parent 72838d004b
commit f797c7d2d8
  1. 2
      AUTHORS
  2. 4
      ChangeLog
  3. 6
      Makefile.am
  4. 1
      README
  5. 0
      data/config/econnman.config
  6. 130
      econnman-bin.in

@ -1 +1,3 @@
Gustavo Sverzut Barbieri <barbieri@profusion.mobi>
Matthias Wauer <matthiaswauer@gmail.com>
Leif Middelschulte <leif.middelschulte@gmail.com>

@ -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

@ -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 \

@ -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!

@ -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)

Loading…
Cancel
Save