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.
This commit is contained in:
parent
72838d004b
commit
f797c7d2d8
2
AUTHORS
2
AUTHORS
|
@ -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 \
|
||||
|
|
1
README
1
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!
|
||||
|
|
130
econnman-bin.in
130
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)
|
||||
|
||||
|
|
Loading…
Reference in New Issue