From 42725426ec02d359b67cd8d665afe17882d38958 Mon Sep 17 00:00:00 2001 From: ficus Date: Sat, 15 Sep 2012 19:46:49 +0200 Subject: more WIP --- TODO | 22 ++++-- helpers/netif.py | 188 +++++++++++++++++++++++++++++++++++++++++++++-- helpers/sysstatus.py | 26 ++++++- helpers/tor.py | 11 +++ helpers/util.py | 2 +- templates/base.html | 12 ++- templates/home.html | 96 ++++++++++++++++-------- templates/lan.html | 32 ++++++++ templates/lib.html | 65 +++++++++++++--- templates/processes.html | 6 +- templates/tor.html | 19 +++++ templates/wan.html | 35 +++++++++ templates/wifi.html | 38 ++++++++++ torouterui.py | 155 ++++++++++++++++++++++++++++++++++---- 14 files changed, 625 insertions(+), 82 deletions(-) create mode 100644 templates/lan.html create mode 100644 templates/tor.html create mode 100644 templates/wifi.html diff --git a/TODO b/TODO index d9d76ed..012684a 100644 --- a/TODO +++ b/TODO @@ -3,7 +3,7 @@ - imitate Tomato firmware style/layout - flask python web framework -- bootstrap with non-standard color scheme +- bootstrap with a non-standard color scheme - modularize configuration "nuggets"; compare and apply changes all or none - write nugget getters/setters @@ -12,16 +12,20 @@ - in some cases execute changes without restart? - monitoring - enable/disable - bandwidth and system status charts via... mrtg? nagios? - dmesg, syslog, auth, ??? - top + dmesg, syslog, auth + ps aux - front page status uptime current cpu, disk, ram utilization upstream: dhcp ip equivalent + last login (?) +- about + uname + software versions + project links - administration + hostname (?) ssh access, keys autocron updates - WAN network @@ -35,11 +39,19 @@ torification - tor generic status + enable relay + enable bridge common configuration # Later +- dhcp configuration +- enable/disable hotplug in interfaces when method changes +- flesh out README +- installation script +- debian packaging - admin authentication scheme +- not-root permissions scheme for: interfaces, tor, wireless, ssh keys - firewall configuration port forwarding enable remote login diff --git a/helpers/netif.py b/helpers/netif.py index 6d7a194..77f710c 100644 --- a/helpers/netif.py +++ b/helpers/netif.py @@ -1,5 +1,6 @@ import os +import augeas from util import * @@ -20,6 +21,10 @@ def parse_ip(ifname): for k, v in val_indexes.iteritems(): if len(iplinkl) > v and iplinkl[v] == k: d[k] = iplinkl[v+1] + if 'LOWER_UP' in iplinkl[2][1:-1].split(","): + d['state'] = "RUNNING" + elif 'NO-CARRIER' in iplinkl[2][1:-1].split(","): + d['state'] = "DISCONNECTED" d['ipv4addrs'] = list() d['ipv6addrs'] = list() for l in ipinfo[1:]: @@ -38,15 +43,121 @@ def parse_ip(ifname): addr=l[1].split('/')[0], prefix=int(l[1].split('/')[1]), scope=l[3])) - print d['ipv6addrs'] return d -def get_wan_status(ifname='eth1'): +def parse_iw(ifname): + """ + Example `iw dev wlan0 link` string (sic): + + Connected to c0:25:06:51:22:9b (on wlan0) + SSID: fleischfressendepflanze + freq: 2427 + RX: 73744193 bytes (456838 packets) + TX: 3269174 bytes (19709 packets) + signal: -44 dBm + tx bitrate: 72.2 MBit/s MCS 7 short GI + + bss flags: + dtim period: 0 + beacon int: 100 + """ + d = dict() + iwinfo = cli_read_lines('iw dev %s link' % ifname) + if 0 == len(iwinfo): + raise KeyError('No such interface: ' + ifname) + if iwinfo[0].strip() == "Not connected.": + d['radio_state'] = "disabled" + return d + else: + d['radio_state'] = "enabled" + for l in iwinfo: + l = l.strip() + if l.startswith("SSID:"): + d['ssid'] = l[6:].strip() + elif l.startswith("freq:"): + d['freq'] = "%sMHz" % l.split()[-1].strip() + elif l.startswith("signal:"): + d['signal_dbm'] = l.split()[1] + elif l.startswith("tx bitrate:"): + d['signal_throughput'] = ' '.join(l.split()[2:4]) + return d + +def read_augeas_ifinfo(ifname): + d = dict() + aug = augeas.Augeas(flags=augeas.Augeas.NO_MODL_AUTOLOAD) + aug.set("/augeas/load/Interfaces/lens", "Interfaces.lns") + aug.set("/augeas/load/Interfaces/incl", "/etc/network/interfaces") + aug.load() + for iface in aug.match("/files/etc/network/interfaces/iface"): + if aug.get(iface) == ifname: + if aug.get(iface + "/family") == 'inet': + d['ipv4method'] = aug.get(iface + "/method") + if d['ipv4method'] == 'manual': + d['ipv4method'] = 'disabled' + d['ipv4addr'] = aug.get(iface + "/address") + d['ipv4netmask'] = aug.get(iface + "/netmask") + d['ipv4gateway'] = aug.get(iface + "/gateway") + d['ipv4mtu'] = aug.get(iface + "/mtu") + d['ipv4mac'] = aug.get(iface + "/hwaddress") + elif aug.get(iface + "/family") == 'inet6': + # handle ipv6 stuff + pass + aug.close() + return d + aug.close() + return None + +def write_augeas_ifinfo(ifname, settings, method='disabled'): + d = dict() + aug = augeas.Augeas(flags=augeas.Augeas.NO_MODL_AUTOLOAD) + aug.set("/augeas/load/Interfaces/lens", "Interfaces.lns") + aug.set("/augeas/load/Interfaces/incl", "/etc/network/interfaces") + aug.load() + path = None + for iface in aug.match("/files/etc/network/interfaces/iface"): + if aug.get(iface) == ifname and aug.get(iface + "/family") == 'inet': + path = iface + if not path: + # insert iface + if len(aug.match("/files/etc/network/interfaces/iface")) == 0: + # no interfaces at all, insert wherever + path = "/files/etc/network/interfaces/iface" + aug.set(path, ifname) + else: + aug.insert("/files/etc/network/interfaces/iface", "iface", + before=False) + path = aug.match("/files/etc/network/interfaces/iface")[-1] + aug.set(path, ifname) + assert path, "require path to be set" + aug.set(path + "/family", 'inet') + if method == 'disabled': + aug.set(path + "/method", 'manual') + aug.remove(path + "/address") + aug.remove(path + "/netmask") + aug.remove(path + "/gateway") + elif method == 'dhcp': + aug.set(path + "/method", 'dhcp') + aug.remove(path + "/address") + aug.remove(path + "/netmask") + aug.remove(path + "/gateway") + elif method == 'static': + aug.set(path + "/method", 'static') + aug.set(path + "/address", str(settings['ipv4addr'])) + aug.set(path + "/netmask", str(settings['ipv4netmask'])) + aug.set(path + "/gateway", str(settings['ipv4gateway'])) + else: + raise ValueError("unrecognized network interface method: " + method) + print "committing with augeas..." + aug.save() + print "augeas errors: %s" % aug.get("/augeas/error") + aug.close() + +def get_wan_status(ifname='eth0'): d = dict() try: d.update(parse_ip(ifname)) except KeyError: - None + return None return d def get_lan_status(ifname='eth0'): @@ -54,15 +165,80 @@ def get_lan_status(ifname='eth0'): try: d.update(parse_ip(ifname)) except KeyError: - None + return None return d -def get_wireless_status(ifname='wlan0'): +def get_wifi_status(ifname='wlan0'): d = dict() try: d.update(parse_ip(ifname)) except KeyError, ke: - raise ke return None + d.update(parse_iw(ifname)) return d +def get_wan_settings(ifname='eth0'): + return read_augeas_ifinfo(ifname) + +def save_wan_settings(form, ifname='eth0'): + write_augeas_ifinfo(ifname, method=form['ipv4method'], settings=form) + if form['ipv4method'] == 'disabled': + print "ifdown..." + os.system("ifdown %s" % ifname) + else: + print "ifup..." + os.system("ifdown %s" % ifname) + os.system("ifup %s &" % ifname) + +def get_lan_settings(ifname='eth0'): + d = read_augeas_ifinfo(ifname) + return d + +def save_lan_settings(ifname='eth0'): + write_augeas_ifinfo(ifname, method=form['ipv4method'], settings=form) + if form['ipv4method'] == 'disabled': + print "ifdown..." + os.system("ifdown %s" % ifname) + else: + print "ifup..." + os.system("ifdown %s" % ifname) + os.system("ifup %s &" % ifname) + +def get_wifi_settings(ifname='wlan0'): + #d = read_augeas_ifinfo(ifname) + d = dict() + if not d: + return d + d.update(dict()) # extra wireless settings + return d + +def save_wifi_settings(ifname='eth0'): + pass + +def is_valid_ipv4(s): + # TODO: this is a hack + l = s.split('.') + if not len(l) == 4: + return False + try: + l = map(int, l) + except ValueError: + return False + if l[0] > 255 or l[1] > 255 or l[2] > 255 or l[3] > 255: + return False + if l[0] == 0 or l[3] == 0: + return False + return True + +def is_valid_ipv4mask(s): + # TODO: this is a hack + l = s.split('.') + if not len(l) == 4: + return False + try: + l = map(int, l) + except ValueError: + return False + if l[0] > 255 or l[1] > 255 or l[2] > 255 or l[3] > 255: + return False + return True diff --git a/helpers/sysstatus.py b/helpers/sysstatus.py index b2eec6f..933f625 100644 --- a/helpers/sysstatus.py +++ b/helpers/sysstatus.py @@ -12,6 +12,28 @@ def get_system_status(): d['uptime'] = cli_read('uptime') return d +def get_resources_status(): + d = dict() + disk_info = cli_read_lines('df -h /home')[1].split() + d['disk_used'] = disk_info[2] + d['disk_avail'] = disk_info[1] + d['disk_percent'] = int(disk_info[4][:-1]) + + ram_info = cli_read_lines('free -m')[1].split() + d['ram_used'] = "%sMB" % ram_info[2] + d['ram_avail'] = "%sMB" % ram_info[1] + d['ram_percent'] = int(float(ram_info[2])/float(ram_info[1]) * 100.0) + + d['cpu_cores'] = 1 + for l in open('/proc/cpuinfo', 'r'): + if l.split(":")[0].strip() == "cpu cores": + d['cpu_cores'] = int(l.split(":")[-1].strip()) + break + cpu_info = cli_read('uptime') + d['cpu_load'] = cpu_info.split()[-3].strip(',') + d['cpu_percent'] = int(float(d['cpu_load'])/float(d['cpu_cores']) * 100.0) + return d + def get_dmesg(): try: return cli_read('dmesg') @@ -21,14 +43,14 @@ def get_dmesg(): def get_authlog(): try: with open('/var/log/auth.log') as f: - return '\n'.join(f.readlines()) + return ''.join(f.readlines()) except IOError: return None def get_syslog(): try: with open('/var/log/syslog') as f: - return '\n'.join(f.readlines()) + return ''.join(f.readlines()) except IOError: return None diff --git a/helpers/tor.py b/helpers/tor.py index e69de29..438cb5d 100644 --- a/helpers/tor.py +++ b/helpers/tor.py @@ -0,0 +1,11 @@ + +def get_tor_status(): + d = dict() + d['state'] = 'DISABLED' + return d + +def get_tor_settings(): + return dict() + +def save_tor_settings(): + pass diff --git a/helpers/util.py b/helpers/util.py index 46030bf..229d975 100644 --- a/helpers/util.py +++ b/helpers/util.py @@ -11,7 +11,7 @@ def cli_read_lines(cmd): def fs_read(path): with open(path, 'r') as f: - return '\n'.join(f.readlines()).strip() + return ''.join(f.readlines()) def prefix_to_ipv4_mask(prefixlen): assert(prefixlen >= 0) diff --git a/templates/base.html b/templates/base.html index a2c1407..4c15c73 100644 --- a/templates/base.html +++ b/templates/base.html @@ -37,13 +37,12 @@
  • {{name}}
  • {%- endmacro %} {{ pagelink("/", "Status") }} - {{ pagelink("/admin/", "Administration") }} {{ pagelink("/reboot/", "Reboot...") }} - {{ pagelink("/wan/", "Upstream") }} - {{ pagelink("/lan/", "Local") }} - {{ pagelink("/wireless/", "Wireless") }} - {{ pagelink("/tor/", "Tor") }} + {{ pagelink("/wan/", "Upstream Ethernet") }} + {{ pagelink("/lan/", "Local Ethernet") }} + {{ pagelink("/wifi/", "WiFi") }} + {{ pagelink("/tor/", "Tor Network") }} {{ pagelink("/logs/", "Logs") }} {{ pagelink("/processes/", "Processes") }} @@ -51,8 +50,8 @@
    - {% with messages = get_flashed_messages(with_categories=true) %} {% if messages %} + {{ mesages }} {% for category, message in messages %}
    @@ -63,7 +62,6 @@
    {% endfor %} {% endif %} - {% endwith %} {% block body %}{% endblock %}
    diff --git a/templates/home.html b/templates/home.html index 30c328e..fa2ed2b 100644 --- a/templates/home.html +++ b/templates/home.html @@ -1,39 +1,71 @@ {% import "lib.html" as lib %} {% extends "base.html" %} {% block body %} -

    System

    - - - - -
    Host Name - {{ status.system.hostname }} -
    Current Time - {{ status.system.current_time }} -
    System Uptime - {{ status.system.uptime }} -
    -

    WAN

    -{% if not status.wan %} -Upstream ethernet interface hardware not detected at all! -{% else %} -{{ lib.ifstatus(status.wan) }} -{% endif %} - -

    LAN

    -{% if not status.lan %} -Local network ethernet interface hardware not detected at all! -{% else %} -{{ lib.ifstatus(status.lan) }} -{% endif %} - -

    Wireless

    -{% if not status.wireless %} -Wireless interface hardware not detected at all! -{% else %} -{{ lib.ifstatus(status.wireless) }} -{% endif %} +
    +
    +

    System

    + + + + +
    Host Name + {{ status.system.hostname }} +
    Current Time + {{ status.system.current_time }} +
    System Uptime + {{ status.system.uptime }} +
    +
    +
    +

    Resources

    +
      +
    • + CPU Load{{status.resources.cpu_load}} / {{status.resources.cpu_cores}} cores +
      +
      +
      +
    • +
    • RAM Usage{{status.resources.ram_used}} / {{status.resources.ram_avail}} +
      +
      +
      +
    • +
    • Primary Disk Space{{status.resources.disk_used}} / {{status.resources.disk_avail}} +
      +
      +
      +
    • +
    +
    +
    +
    +
    +

    WAN

    + {{ lib.ifstatus(status.wan) }} +
    +
    +

    LAN

    + {{ lib.ifstatus(status.lan) }} +
    +
    +
    +
    +

    WiFi

    + {{ lib.ifstatus(status.wifi) }} +
    +
    +

    Tor

    + + +
    Status + + {{ status.tor.state }} + +
    +
    +
    {% endblock %} diff --git a/templates/lan.html b/templates/lan.html new file mode 100644 index 0000000..09bcf0a --- /dev/null +++ b/templates/lan.html @@ -0,0 +1,32 @@ +{% import "lib.html" as lib %} +{% extends "base.html" %} +{% block body %} + +
    +Local Ethernet Configuration + +{% if not status.lan %} +Could not find the local ethernet hardware device! +{% else %} + +{{ lib.formcheckbox(form, formerr, 'ipv4enable', 'Enable this interface', 'true') }} + +Address Configuration +{{ lib.forminput(form, formerr, 'ipv4addr', 'IPv4 Address', '0.0.0.0') }} +{{ lib.forminput(form, formerr, 'ipv4netmask', 'Netmask', '255.255.0.0') }} +{{ lib.forminput(form, formerr, 'ipv4gateway', 'Gateway IP Address', '0.0.0.0') }} + +DHCP Configuration +{{ lib.forminput(form, formerr, 'dhcpbase', 'DHCP Range Base', '192.168.1.100') }} +{{ lib.forminput(form, formerr, 'dhcptop', 'DHCP Range Top', '192.168.1.200') }} +{{ lib.forminput(form, formerr, 'dhcptime', 'Lease Time', '12h') }} + +
    + + +
    +
    +{% endif %} + +{% endblock %} diff --git a/templates/lib.html b/templates/lib.html index 33534da..6ac5e12 100644 --- a/templates/lib.html +++ b/templates/lib.html @@ -1,41 +1,84 @@ + {% macro ifstatus(ifstatus) -%} - +{% if not ifstatus %} + +Network hardware not detected at all! + +{% else %} +
    + + + +
    Interface Name - {{ ifstatus.ifname }} + {{ ifstatus.ifname }}
    Status - + {{ ifstatus.state }}
    MAC Address - {{ ifstatus.mac }} + {{ ifstatus.mac }}
    IPv4 Addresses - + {% for addr in ifstatus.ipv4addrs %} {{ addr.addr }}/{{ addr.prefix}} ({{ addr.scope }})
    - {% endfor %} + {% endfor %}
    IPv6 Addresses - + {% for addr in ifstatus.ipv6addrs %} {{ addr.addr }}/{{ addr.prefix}} ({{ addr.scope }})
    - {% endfor %} + {% endfor %}
    + {% if ifstatus.radio_state %} +
    Radio State + {{ ifstatus.radio_state }} +
    SSID + {{ ifstatus.ssid }} +
    Frequency + {{ ifstatus.freq }} +
    Signal Strength + {{ ifstatus.signal_dbm }} + {% endif %}
    +{% endif %} {%- endmacro %} + {% macro logbox(name, contents) -%}

    {{name}}

    {% if contents == None %} Access to {{name}} was denied, or file did not exist. {% else %} - -
    +
    +
     {{ contents }}
     
    +
    {% endif%} {%- endmacro %} + + +{% macro forminput(form, formerr, name, title, placeholder) -%} +
    + +
    + + {% if formerr[name] %} + {{ formerr[name] }} + {% endif %} +
    +
    +{%- endmacro %} + +{% macro formcheckbox(form, formerr, name, title, value) -%} + +{% endmacro %} diff --git a/templates/processes.html b/templates/processes.html index c911b0a..2e35162 100644 --- a/templates/processes.html +++ b/templates/processes.html @@ -8,12 +8,12 @@ PID %CPU %MEM - Status Code + Status Started Time Command {% for proc in process_list %} - + {{ proc.user }} {{ proc.pid}} {{ proc.perc_cpu }} @@ -21,7 +21,7 @@ {{ proc.status_code }} {{ proc.started }} {{ proc.time }} - {{ proc.command }} +
    {{ proc.command }}
    {% endfor %} diff --git a/templates/tor.html b/templates/tor.html new file mode 100644 index 0000000..a1f30dc --- /dev/null +++ b/templates/tor.html @@ -0,0 +1,19 @@ +{% import "lib.html" as lib %} +{% extends "base.html" %} +{% block body %} + +
    +Tor Network Configuration + +{{ lib.formcheckbox(form, formerr, 'torenable', 'Enable Tor daemon', 'true') }} +{{ lib.formcheckbox(form, formerr, 'torrelayenable', 'Enable Tor Relay', 'true') }} +{{ lib.formcheckbox(form, formerr, 'torbridgeenable', 'Enable Tor Bridge', 'true') }} + +
    + + +
    +
    + +{% endblock %} diff --git a/templates/wan.html b/templates/wan.html index e69de29..2da2733 100644 --- a/templates/wan.html +++ b/templates/wan.html @@ -0,0 +1,35 @@ +{% import "lib.html" as lib %} +{% extends "base.html" %} +{% block body %} + +
    +Upstream Ethernet Configuration + + + + + +{{ lib.forminput(form, formerr, 'ipv4addr', 'IPv4 Address', '0.0.0.0') }} +{{ lib.forminput(form, formerr, 'ipv4netmask', 'Netmask', '255.255.255.0') }} +{{ lib.forminput(form, formerr, 'ipv4gateway', 'Gateway IP Address', '0.0.0.0') }} + + + +
    + + +
    +
    + + +{% endblock %} diff --git a/templates/wifi.html b/templates/wifi.html new file mode 100644 index 0000000..3e41788 --- /dev/null +++ b/templates/wifi.html @@ -0,0 +1,38 @@ +{% import "lib.html" as lib %} +{% extends "base.html" %} +{% block body %} + +
    +WiFi Configuration + +{% if not status.wifi %} +Could not find the WiFi hardware device! +{% else %} + +{{ lib.formcheckbox(form, formerr, 'wifienable', 'Enable the radio', 'true') }} +{{ lib.formcheckbox(form, formerr, 'torifylanenable', 'Transparently "Tor-ify" this network interface', 'true') }} + +Radio +{{ lib.forminput(form, formerr, 'wifissid', 'SSID name', 'internet') }} +{{ lib.forminput(form, formerr, 'wifipower', 'Transmit Power', 'high, low') }} +{{ lib.forminput(form, formerr, 'wifichannel', 'Channel', '11') }} + +Network Address +{{ lib.forminput(form, formerr, 'ipv4addr', 'IPv4 Address', '0.0.0.0') }} +{{ lib.forminput(form, formerr, 'ipv4netmask', 'Netmask', '255.255.0.0') }} +{{ lib.forminput(form, formerr, 'ipv4gateway', 'Gateway IP Address', '0.0.0.0') }} + +DHCP Server +{{ lib.forminput(form, formerr, 'dhcpbase', 'DHCP Range Base', '192.168.1.100') }} +{{ lib.forminput(form, formerr, 'dhcptop', 'DHCP Range Top', '192.168.1.200') }} +{{ lib.forminput(form, formerr, 'dhcptime', 'Lease Time', '12h') }} + +
    + + +
    +
    +{% endif %} + +{% endblock %} diff --git a/torouterui.py b/torouterui.py index 33a0018..5e8f346 100755 --- a/torouterui.py +++ b/torouterui.py @@ -6,6 +6,7 @@ import os from helpers import sysstatus from helpers import netif +from helpers import tor import config app = Flask(__name__) @@ -15,9 +16,11 @@ app = Flask(__name__) def status(): status = dict() status['system'] = sysstatus.get_system_status() + status['resources'] = sysstatus.get_resources_status() status['wan'] = netif.get_wan_status() status['lan'] = netif.get_lan_status() - status['wireless'] = netif.get_wireless_status() + status['wifi'] = netif.get_wifi_status() + status['tor'] = tor.get_tor_status() return render_template('home.html', settings=None, status=status) @app.route('/administer/', methods=['GET', 'POST']) @@ -26,35 +29,157 @@ def administer(): @app.route('/reboot/', methods=['GET', 'POST']) def administer(): - print request.form if request.method == 'GET': return render_template('reboot.html', status=None) - if request.form.has_key('confirm'): - # TODO: check reboot flag here? + elif request.form.has_key('confirm'): + # XXX: execute reboot return render_template('reboot.html', status='rebooting') else: # XXX: flashing introduces cookies #flash("Didn't confirm, not rebooting", "warning") return render_template('reboot.html', status=None) - @app.route('/wan/', methods=['GET', 'POST']) def wan(): - status = dict() - status['wan'] = netif.get_wan_status() - return render_template('wan.html', settings=None, status=None) + msg = list() + status = dict(wan=netif.get_wan_status()) + if not status['wan']: + msg.append(("error", + "Interface not detected, can not be configured."),) + return render_template('wan.html', form=None, status=status, + messages=msg, formerr=None) + if request.method == 'GET': + form = netif.get_wan_settings() + return render_template('wan.html', form=form, status=status, + formerr=None) + # Got this far, need to validated form + formerr = dict() + if request.form['ipv4method'] == 'disabled': + pass # no further validation + elif request.form['ipv4method'] == 'dhcp': + pass # no further validation + elif request.form['ipv4method'] == 'static': + if not netif.is_valid_ipv4(request.form['ipv4addr']): + formerr['ipv4addr'] = "Not a valid IPv4 address" + if not netif.is_valid_ipv4mask(request.form['ipv4netmask']): + formerr['ipv4netmask'] = "Not a valid IPv4 netmask" + if not netif.is_valid_ipv4(request.form['ipv4gateway']): + formerr['ipv4gateway'] = "Not a valid IPv4 address" + else: + ke = KeyError("Invalid net config method: %s" % form['ipv4method']) + print ke + raise ke + if len(formerr.keys()) > 0: + msg.append(("error", + "Please correct the validation issues below"),) + else: + # Ok, we have a valid form, now to commit it + try: + netif.save_wan_settings(request.form) + msg.append(("success", + "Configuration saved! Check logs for any errors"),) + except IOError, ioerr: + msg.append(("error", + "Was unable to commit changes... permissions problem? \"%s\"" \ + % ioerr)) + return render_template('wan.html', form=request.form, status=status, + formerr=formerr, messages=msg) @app.route('/lan/', methods=['GET', 'POST']) def lan(): - return render_template('lan.html', settings=None, status=None) - -@app.route('/wireless/', methods=['GET', 'POST']) -def wireless(): - return render_template('wireless.html', settings=None, status=None) + msg = list() + status = dict() + status['lan'] = netif.get_lan_status() + if not status['lan']: + msg.append(("error", + "Interface not detected, can not be configured."),) + return render_template('lan.html', form=None, status=status, + messages=msg, formerr=None) + if request.method == 'GET': + form = netif.get_lan_settings() + return render_template('lan.html', form=form, status=status, + formerr=None) + # Got this far, need to validated form + formerr = dict() + if request.form['ipv4method'] == 'disabled': + pass # no further validation + elif request.form['ipv4method'] == 'static': + if not netif.is_valid_ipv4(request.form['ipv4addr']): + formerr['ipv4addr'] = "Not a valid IPv4 address" + if not netif.is_valid_ipv4mask(request.form['ipv4netmask']): + formerr['ipv4netmask'] = "Not a valid IPv4 netmask" + if not netif.is_valid_ipv4(request.form['ipv4gateway']): + formerr['ipv4gateway'] = "Not a valid IPv4 address" + else: + ke = KeyError("Invalid method: %s" % form['ipv4method']) + print ke + raise ke + if len(formerr.keys()) > 0: + msg.append(("error", + "Please correct the validation issues below"),) + else: + # Ok, we have a valid form, now to commit it + try: + netif.save_lan_settings(request.form) + msg.append(("success", + "Configuration saved! Check logs for any errors"),) + except IOError, ioerr: + msg.append(("error", + "Was unable to commit changes... permissions problem? \"%s\"" \ + % ioerr)) + return render_template('lan.html', form=request.form, status=status, + formerr=formerr, messages=msg) + +@app.route('/wifi/', methods=['GET', 'POST']) +def wifi(): + status = dict() + status['wifi'] = netif.get_wifi_status() + if not status['wifi']: + msg.append(("error", + "Interface not detected, can not be configured."),) + return render_template('wifi.html', form=None, status=status, + messages=msg, formerr=None) + if request.method == 'GET': + form = netif.get_wifi_settings() + return render_template('wifi.html', form=form, status=status, + formerr=None) + # Got this far, need to validated form + formerr = dict() + if request.form['ipv4method'] == 'disabled': + pass # no further validation + elif request.form['ipv4method'] == 'static': + if not netif.is_valid_ipv4(request.form['ipv4addr']): + formerr['ipv4addr'] = "Not a valid IPv4 address" + if not netif.is_valid_ipv4mask(request.form['ipv4netmask']): + formerr['ipv4netmask'] = "Not a valid IPv4 netmask" + if not netif.is_valid_ipv4(request.form['ipv4gateway']): + formerr['ipv4gateway'] = "Not a valid IPv4 address" + else: + ke = KeyError("Invalid method: %s" % form['ipv4method']) + print ke + raise ke + if len(formerr.keys()) > 0: + msg.append(("error", + "Please correct the validation issues below"),) + else: + # Ok, we have a valid form, now to commit it + try: + netif.save_wifi_settings(request.form) + msg.append(("success", + "Configuration saved! Check logs for any errors"),) + except IOError, ioerr: + msg.append(("error", + "Was unable to commit changes... permissions problem? \"%s\"" \ + % ioerr)) + return render_template('wifi.html', form=request.form, status=status, + formerr=formerr, messages=msg) + return render_template('wifi.html', settings=None, status=None) @app.route('/tor/', methods=['GET', 'POST']) -def tor(): - return render_template('tor.html', settings=None, status=None) +def torpage(): + msg = list() + return render_template('tor.html', settings=None, status=None, + form=request.form, formerr=None, messages=msg) @app.route('/logs/', methods=['GET']) def logs(): -- cgit v1.2.3