Refactor pnac config into a class and separate module
This will make it easier to add proper authorization for it in the future.
This commit is contained in:
parent
1551b89b81
commit
80b83a2e28
|
@ -1,3 +1,4 @@
|
|||
*.py[oc]
|
||||
INSTALL
|
||||
Makefile
|
||||
Makefile.in
|
||||
|
|
155
econnman-bin.in
155
econnman-bin.in
|
@ -14,16 +14,10 @@ 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
|
||||
import efl.edje
|
||||
import efl.edje as edje # Class resolve hack for edje_get
|
||||
from efl.dbus_mainloop import DBusEcoreMainLoop
|
||||
import efl.elementary as elm
|
||||
from efl.elementary import ELM_POLICY_QUIT, \
|
||||
|
@ -51,7 +45,7 @@ except:
|
|||
import elementary as elm
|
||||
import evas
|
||||
import ecore
|
||||
import edje
|
||||
import edje # Class resolve hack for edje_get
|
||||
from e_dbus import DBusEcoreMainLoop
|
||||
from elementary import Window, Background, Box, Label, Naviframe, Popup, \
|
||||
Button, Scroller, Check, Progressbar, Genlist, GenlistItemClass, \
|
||||
|
@ -59,6 +53,7 @@ except:
|
|||
ELM_WIN_DIALOG_BASIC, ELM_POLICY_QUIT, ELM_SCROLLER_POLICY_OFF, \
|
||||
ELM_SCROLLER_POLICY_AUTO, ELM_POLICY_QUIT_LAST_WINDOW_CLOSED
|
||||
|
||||
from pnac import PNACConfig
|
||||
|
||||
dbus_ml = DBusEcoreMainLoop()
|
||||
bus = dbus.SystemBus(mainloop=dbus_ml)
|
||||
|
@ -72,9 +67,6 @@ log.addHandler(log_handler)
|
|||
|
||||
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)
|
||||
|
||||
|
@ -268,103 +260,6 @@ class ObjectView(object):
|
|||
return lb, en
|
||||
|
||||
|
||||
#######################################################################
|
||||
# Config Files Helper:
|
||||
def config_file_setup():
|
||||
global configs
|
||||
configs = configparser.RawConfigParser()
|
||||
configs.optionxform = str
|
||||
try:
|
||||
fd = open(CONF_FILE, 'r', encoding='utf8')
|
||||
configs.readfp(fd)
|
||||
fd.close()
|
||||
except IOError:
|
||||
popup_error(
|
||||
win,
|
||||
"Cannot read configuration file",
|
||||
"Econnman cannot read the coniguration file \"" + CONF_FILE +
|
||||
"\", used by connman to configure your ieee802.1x networks. "
|
||||
"Make sure the user running connman is able to read/write it."
|
||||
)
|
||||
configs = None
|
||||
raise IOError
|
||||
|
||||
|
||||
def config_del(name):
|
||||
global configs
|
||||
secname = 'service_' + name
|
||||
if configs is None:
|
||||
try:
|
||||
config_file_setup()
|
||||
except IOError:
|
||||
return
|
||||
if configs.has_section(secname):
|
||||
configs.remove_section(secname)
|
||||
config_write(name)
|
||||
|
||||
|
||||
def config_set(name, key, value):
|
||||
global configs
|
||||
secname = 'service_' + name
|
||||
if configs is None:
|
||||
try:
|
||||
config_file_setup()
|
||||
except IOError:
|
||||
return
|
||||
if not configs.has_section(secname):
|
||||
configs.add_section(secname)
|
||||
configs.set(secname, 'Type', 'wifi')
|
||||
configs.set(secname, 'Name', name)
|
||||
if value is not None:
|
||||
configs.set(secname, key, value)
|
||||
elif configs.has_option(secname, key):
|
||||
configs.remove_option(secname, key)
|
||||
config_write(name)
|
||||
|
||||
|
||||
def config_get(name):
|
||||
global configs
|
||||
if configs is None:
|
||||
try:
|
||||
config_file_setup()
|
||||
except IOError:
|
||||
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_option_get(secname, key):
|
||||
if configs.has_option(secname, key):
|
||||
return configs.get(secname, key)
|
||||
return None
|
||||
|
||||
|
||||
def config_exists(name):
|
||||
if config_get(name):
|
||||
return True
|
||||
else:
|
||||
return False
|
||||
|
||||
|
||||
def config_write(name):
|
||||
global configs
|
||||
try:
|
||||
with open(CONF_FILE, 'w', encoding='utf8') as configfile:
|
||||
configs.write(configfile)
|
||||
except IOError:
|
||||
popup_error(
|
||||
win,
|
||||
"Cannot write configuration file",
|
||||
"Econnman cannot write the coniguration file \"" + CONF_FILE +
|
||||
"\", used by connman to configure your ieee802.1x networks. "
|
||||
"Make sure the user running connman is able to read/write it."
|
||||
)
|
||||
|
||||
|
||||
########################################################################
|
||||
# Views:
|
||||
class OfflineModeMonitor(object):
|
||||
|
@ -967,10 +862,10 @@ class ServiceView(ObjectView):
|
|||
if not self.immutable and self.type != "ethernet":
|
||||
self.forget = self.add_button(self.box, "Forget Network",
|
||||
self._forget)
|
||||
elif (self.type == "wifi") and ("ieee8021x" in self.security_mode):
|
||||
elif self.type == "wifi" and "ieee8021x" in self.security_mode:
|
||||
self.forget = self.add_button(self.box, "Forget Network",
|
||||
self._forget)
|
||||
if not config_exists(self.name):
|
||||
if not pnac_conf.has_section(self.name):
|
||||
self.forget.disabled = True
|
||||
|
||||
self.error = self.add_label(self.box, "error here")
|
||||
|
@ -1005,6 +900,7 @@ class ServiceView(ObjectView):
|
|||
self.domains_label = lb
|
||||
self.domains_entry = en
|
||||
|
||||
# section: IPv4
|
||||
self.ipv4_properties = {"IPv4": {}, "IPv4.Configuration": {}}
|
||||
fr, bx = self.add_frame_and_box(self.box, "IPv4")
|
||||
self.ipv4_frame = fr
|
||||
|
@ -1018,10 +914,15 @@ class ServiceView(ObjectView):
|
|||
en.callback_unfocused_add(self._on_ipv4_property_unfocused)
|
||||
setattr(self, attr, en)
|
||||
|
||||
# section: IPv6: similar to ipv4? refactor ipv4?
|
||||
if properties.get("IPv6"):
|
||||
fr, bx = self.add_frame_and_box(self.box, "IPv6")
|
||||
lb = self.add_label(bx, "TODO")
|
||||
|
||||
# section: Proxy: custom contents for direct, auto and manual
|
||||
# - direct: nothing
|
||||
# - auto: url
|
||||
# - manual: servers, excludes
|
||||
self.proxy_properties = {"Proxy": {}, "Proxy.Configuration": {}}
|
||||
fr, bx = self.add_frame_and_box(self.box, "Proxy")
|
||||
self.proxy_frame = fr
|
||||
|
@ -1031,12 +932,7 @@ class ServiceView(ObjectView):
|
|||
bx, options, self._on_proxy_method)
|
||||
self.add_label(bx, "TODO")
|
||||
|
||||
# section IPv6: similar to ipv4? refactor ipv4?
|
||||
# section Proxy: custom contents for direct, auto and manual
|
||||
# - direct: nothing
|
||||
# - auto: url
|
||||
# - manual: servers, excludes
|
||||
|
||||
# section: Ethernet / VPN
|
||||
if self.type in ("wifi", "ethernet", "wimax", "bluetooth", "cellular"):
|
||||
fr, bx = self.add_readonly_section("Ethernet", self.eth_fields)
|
||||
self.ethernet_frame = fr
|
||||
|
@ -1044,20 +940,19 @@ class ServiceView(ObjectView):
|
|||
fr, bx = self.add_readonly_section("VPN", self.vpn_fields)
|
||||
self.vpn_frame = fr
|
||||
|
||||
# section 2 Phase Authentication
|
||||
|
||||
# section: Two 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)
|
||||
#cfg_sec = pnac_conf.section_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 = config_option_get(cfg_sec, 'EAP')
|
||||
if pnac_conf.has_section(self.name):
|
||||
conf_val = pnac_conf.get(self.name, 'EAP')
|
||||
if conf_val == "peap":
|
||||
self.eap_method_items["PEAP"].selected = True
|
||||
elif conf_val == "tls":
|
||||
|
@ -1072,8 +967,8 @@ class ServiceView(ObjectView):
|
|||
self.phase2, self.phase2_items = self.add_segment_control(
|
||||
bx, options, self._on_phase2
|
||||
)
|
||||
if cfg_sec:
|
||||
conf_val = config_option_get(cfg_sec, 'Phase2')
|
||||
if pnac_conf.has_section(self.name):
|
||||
conf_val = pnac_conf.get(self.name, 'Phase2')
|
||||
if conf_val == "tls":
|
||||
self.phase2_items["TLS"].selected = True
|
||||
elif conf_val == "MSCHAPV2":
|
||||
|
@ -1306,8 +1201,8 @@ class ServiceView(ObjectView):
|
|||
self.forget.disabled = False
|
||||
|
||||
if self.type == "wifi" and "ieee8021x" in self.security_mode:
|
||||
if config_exists(self.name):
|
||||
config_del(self.name)
|
||||
if pnac_conf.has_section(self.name):
|
||||
pnac_conf.remove_section(self.name)
|
||||
for it in self.phase2_items:
|
||||
self.phase2_items[it].selected = False
|
||||
for it in self.eap_method_items:
|
||||
|
@ -1456,7 +1351,7 @@ class ServiceView(ObjectView):
|
|||
elif item.text == "None":
|
||||
eap_val = None
|
||||
|
||||
config_set(self.name, "EAP", eap_val)
|
||||
pnac_conf.set(self.name, "EAP", eap_val)
|
||||
return
|
||||
|
||||
def _on_phase2(self, obj, item):
|
||||
|
@ -1468,7 +1363,7 @@ class ServiceView(ObjectView):
|
|||
elif item.text == "None":
|
||||
phase2_val = None
|
||||
|
||||
config_set(self.name, 'Phase2', phase2_val)
|
||||
pnac_conf.set(self.name, 'Phase2', phase2_val)
|
||||
return
|
||||
|
||||
|
||||
|
@ -1501,8 +1396,8 @@ 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):
|
||||
# Connman only supports two phase auth via config files
|
||||
if ("ieee8021x" in sec) and not pnac_conf.has_section(name):
|
||||
popup_error(
|
||||
win,
|
||||
"This Network needs Configuration",
|
||||
|
@ -1738,6 +1633,8 @@ if __name__ == "__main__":
|
|||
level -= 10 * args.verbose
|
||||
log.setLevel(level)
|
||||
|
||||
pnac_conf = PNACConfig()
|
||||
|
||||
elm.init()
|
||||
elm.policy_set(ELM_POLICY_QUIT, ELM_POLICY_QUIT_LAST_WINDOW_CLOSED)
|
||||
|
||||
|
|
|
@ -0,0 +1,114 @@
|
|||
import sys
|
||||
import logging
|
||||
log = logging.getLogger("econnman.pnac")
|
||||
|
||||
CONF_FILE = "/var/lib/connman/econnman.config"
|
||||
|
||||
# python2 backwards compatibility
|
||||
try:
|
||||
from configparser import SafeConfigParser
|
||||
except ImportError:
|
||||
from ConfigParser import SafeConfigParser
|
||||
|
||||
|
||||
class PNACConfig(SafeConfigParser):
|
||||
|
||||
"""A custom config parser for IEEE802.1x (PNAC)
|
||||
|
||||
Section names are prefixed with service_
|
||||
|
||||
"""
|
||||
|
||||
def __init__(self):
|
||||
SafeConfigParser.__init__(self)
|
||||
self.optionxform = str
|
||||
|
||||
def read(self):
|
||||
args = CONF_FILE, 'r'
|
||||
kwargs = {}
|
||||
if sys.hexversion >= 0x03000000:
|
||||
kwargs["encoding"] = 'utf8'
|
||||
try:
|
||||
with open(*args, **kwargs) as fd:
|
||||
self.readfp(fd)
|
||||
except IOError:
|
||||
log.error(
|
||||
"Econnman cannot read the configuration file \"%s\" used by "
|
||||
"connman to configure your ieee802.1x networks. Make sure the "
|
||||
"user running econnman is able to read/write it.",
|
||||
CONF_FILE
|
||||
)
|
||||
#raise
|
||||
|
||||
# defaults()
|
||||
# sections()
|
||||
|
||||
def add_section(self, service_name):
|
||||
secname = 'service_' + service_name
|
||||
SafeConfigParser.add_section(self, secname)
|
||||
self.set(service_name, 'Type', 'wifi')
|
||||
self.set(service_name, 'Name', service_name)
|
||||
|
||||
def has_section(self, service_name): # config_exists
|
||||
return bool(self.section_get(service_name))
|
||||
|
||||
# options()
|
||||
|
||||
def has_option(self, service_name, key):
|
||||
secname = self.section_get(service_name)
|
||||
return SafeConfigParser.has_option(secname, key)
|
||||
|
||||
# read()
|
||||
# readfp()
|
||||
|
||||
def get(self, service_name, key): # config_option_get
|
||||
secname = self.section_get(service_name)
|
||||
if self.has_option(service_name, key):
|
||||
return SafeConfigParser.get(self, secname, key)
|
||||
return None
|
||||
|
||||
# getint()
|
||||
# getfloat()
|
||||
# getboolean()
|
||||
# items()
|
||||
|
||||
def set(self, service_name, key, value): # config_set
|
||||
secname = self.section_get(service_name)
|
||||
if not self.has_section(service_name):
|
||||
self.add_section(service_name)
|
||||
if value is not None:
|
||||
SafeConfigParser.set(self, secname, key, value)
|
||||
elif self.has_option(secname, key):
|
||||
self.remove_option(secname, key)
|
||||
#self.write()
|
||||
|
||||
def write(self):
|
||||
try:
|
||||
with open(CONF_FILE, 'w', encoding='utf8') as configfile:
|
||||
SafeConfigParser.write(self, configfile)
|
||||
except IOError:
|
||||
log.error(
|
||||
"Econnman cannot write to the configuration file \"%s\" used "
|
||||
"by connman to configure your ieee802.1x networks. Make sure "
|
||||
"the user running econnman is able to read/write it.",
|
||||
CONF_FILE
|
||||
)
|
||||
|
||||
def remove_option(self, service_name, key):
|
||||
secname = self.section_get(service_name)
|
||||
SafeConfigParser.remove_option(self, secname, key)
|
||||
|
||||
def remove_section(self, service_name): # config_del
|
||||
secname = self.section_get(service_name)
|
||||
ret = SafeConfigParser.remove_section(self, secname)
|
||||
#self.write()
|
||||
return ret
|
||||
|
||||
def section_get(self, service_name): # config_get
|
||||
#secname = 'service_' + service_name
|
||||
for sec in self.sections():
|
||||
if self.has_option(sec, 'Name') and \
|
||||
self.get(sec, 'Name') == service_name:
|
||||
return sec
|
||||
else:
|
||||
return None
|
Loading…
Reference in New Issue