def submitVlan(self, ctx, form, data): ifaces = self.sysconf.EthernetDevices if '/' in data['ip']: ip = data['ip'] network = Utils.getNetwork(ip) else: if "." in data['netmask']: cidr = Utils.netmask2cidr(data['netmask']) ip = "%s/%s" % (data['ip'], cidr) network = Utils.getNetwork(ip) else: ip = "%s/%s" % (data['ip'], data['netmask']) network = Utils.getNetwork(ip) defn = { 'ip': ip.encode("ascii", "replace"), 'network': network.encode("ascii", "replace"), 'interface': data['interface'].encode("ascii", "replace"), 'dhcpserver': data['dhcpserver'] } ifaces['vlan%s' % data['vlan']] = defn self.sysconf.EthernetDevices = ifaces WebUtils.restartNetworking(data['dhcpserver']) return url.root.child('Network')
def sendAlert(self, text, t=None, sub=""): if t: if self.alerts.get(t): return else: self.alerts[t] = True mailto = self.sysconf.General.get('notify', ['*****@*****.**']) if sub: subject = "%s from %s" % (sub, self.sysconf.ExternalName) else: subject = "Vulani critical alert from %s" % self.sysconf.ExternalName print mailto for to in mailto: Utils.sendMail('notify@%s' % self.sysconf.Domain, [to], subject, text, server='mx3.thusa.net', importance='high') # Log it l = open('/var/log/tums-eventlog.log', 'at') l.write("[%s] %s\n" % (time.ctime(), text)) l.close()
def __init__(self, pDefaultContent, pRootObj): self.DefaultContent = pDefaultContent self.RootObj = pRootObj self.ApplicationSelector = UI.ApplicationSelector( pDefaultContent, Core.MAIN.ScreenWidth / 2 - 550 / 2, Core.MAIN.ScreenHeight / 2 - 120 / 2) self.NoFoldersFound = False self.LoadApplicationsList() self.BottomButtonsList = Widget.Widget_Controller( pDefaultContent, (5, Core.MAIN.ScreenHeight - 50 - 5, Core.MAIN.ScreenWidth - 10, 50)) self.BottomButtonsList.Append( Widget.Widget_Label( pDefaultContent, "/Ubuntu_Bold.ttf", "Taiyou Framework v" + Utils.FormatNumber(Core.TaiyouGeneralVersion) + "\nTaiyou UI/Taskbar v" + UI.TaskBar_Version, 14, (200, 200, 200), 5, 5, 0)) self.ApplicationManagerBarAnimatorDisableToggle = True self.ApplicationManagerBarAnimator = Utils.AnimationController(2) self.ApplicationManagerBarAnimator.Enabled = False self.ApplicationManagerBar = Widget.Widget_Controller( pDefaultContent, (5, 650, Core.MAIN.ScreenWidth - 10, 50)) self.ApplicationManagerBar.Append( Widget.Widget_Button(pDefaultContent, "Open Application", 14, 5, 5, 0)) self.ApplicationManagerEnabled = False self.TextsBaseX = 0 self.DisableInput = False
def submitVlan(self, ctx, form, data): ifaces = self.sysconf.EthernetDevices if '/' in data['ip']: ip = data['ip'] network = Utils.getNetwork(ip) else: if "." in data['netmask']: cidr = Utils.netmask2cidr(data['netmask']) ip = "%s/%s" % (data['ip'], cidr) network = Utils.getNetwork(ip) else: ip = "%s/%s" % (data['ip'], data['netmask']) network = Utils.getNetwork(ip) defn = { 'ip': ip.encode(), 'network': network.encode(), 'interface': data['interface'].encode(), 'dhcpserver': data['dhcpserver'] } ifaces['vlan%s' % data['vlan']] = defn self.sysconf.EthernetDevices = ifaces if os.path.exists('/etc/debian_version'): WebUtils.system('/usr/local/tcs/tums/configurator --debnet') else: WebUtils.system('/usr/local/tcs/tums/configurator --net') return url.root.child('Network')
def render_content(self, ctx, data): """ Function is deffered to make less blocking on system calls""" if not self.avatarId.isAdmin: return ctx.tag[""] # Fetch running profile thisProfile = Utils.currentProfile() runningProfile = Utils.runningProfile()[0] if thisProfile[0] != runningProfile: thisProfile = [ thisProfile[0], " [", tags.a(href=url.root.child("Profiles").child("switch").child( thisProfile[1]))["Activate"] ], "]" else: thisProfile = thisProfile[0] return ctx.tag[tags.table( width="100%", cellspacing="10")[tags.tr[tags.td(colspan=2)[tags.div( id="ProfileBlock")[tags.div(_class="roundedBlock")[ tags.h1["Profile"], tags.div(id="123")["Current profile: ", thisProfile, tags.br, "Running profile: ", runningProfile, tags.br, tags.directive('form selectProfile'), tags.a(href=url.root.child("Profiles") )["Manage Profiles"]]], ], ]], tags.tr[tags.invisible( render=tags.directive('thisFragment'))]]]
def writeConfig(self, *a): # ddclient os.system('update-rc.d -f ddclient defaults') iface = config.WANPrimary ddclient = """daemon=300 mail-failure=root syslog=yes pid=/var/run/ddclient.pid use=if, if=%s\n""" % (iface) if config.ThusaDNSUsername: ddclient += """protocol=dyndns2 server=update.thusadns.com login=%s password=%s %s\n""" % (config.ThusaDNSUsername, config.ThusaDNSPassword, config.ThusaDNSAddress) for entry in config.General.get('dyndns', []): protocol = entry[0].replace('thusadns', 'dyndns2') ddclient += """\nprotocol=%s server=%s login=%s password=%s %s\n""" % (protocol, entry[1], entry[3], entry[4], entry[2]) Utils.writeConf('/etc/ddclient.conf', ddclient, '#')
def renderHTTP_exception(self, ctx, reason): conf = confparse.Config() now = time.time() hash = sha.sha("%s%s" % (conf.CompanyName, now)).hexdigest() refNo = sum([ord(i) for i in hash+hash]) log.err(reason) request = inevow.IRequest(ctx) request.setResponseCode(http.INTERNAL_SERVER_ERROR) request.write('<html><head><title>Vulani Error</title><link rel="stylesheet" type="text/css" href="/css/style.css"/></head><body>') request.write('<div id="pageTitle"><img id="pageTitleLogo" src="/images/vulani-tums.png" alt=""/>') request.write('</div>') request.write('<div id="sideContainer"><div id="pageNote">Error</div>') request.write('<div id="pageSide"> </div></div>') request.write('<div id="pageContent">') request.write("<h3>An error has occured</h3><p>An error has occurred. We apologise for this inconvenience.</p>") request.write('<div style="height:25em; width:50em; overflow: auto;">') from nevow import failure st = flat.flatten(failure.formatFailure(reason)) print type(st), "ERROR" result = ''.join(st) resHead = result.split('<a href="#tracebackEnd">')[0].replace('font-size: large;', '') realError = result.split('<div class="frame">')[-1] print realError result = resHead + '<div><div class="frame">' + realError if not 'stfu' in dir(Settings): Utils.sendMail("%s <*****@*****.**>" % Settings.LDAPOrganisation, ["*****@*****.**"], "[REF: %s] TUMS Error" % refNo, result, html=True) request.write(result) request.write('</div></div>') request.write("</body></html>") request.finishRequest( False )
def refilterTable(self, items, total): tab = [] for k, v in items.items(): tab.append((k, Utils.intToH(int(v) * 1024))) tab.append(('Total', Utils.intToH(total * 1024))) return tab
def mailUser(_): # Mail the key to the person if data['mailKey']: files = [ '/etc/openvpn/keys/%s.csr' % name, '/etc/openvpn/keys/%s.crt' % name, '/etc/openvpn/keys/%s.key' % name, '/etc/openvpn/keys/ca.crt', '/tmp/TCS.ovpn', '/usr/local/tcs/tums/packages/openvpn-install.exe' ] tempconf = """client dev tap proto udp remote tcs-gw.%s port 1194 resolv-retry infinite redirect-gateway def1 nobind persist-key persist-tun ca ca.crt cert %s.crt key %s.key comp-lzo verb 3 keepalive 10 360 tls-timeout 300""" % (self.sysconf.ExternalName, name, name) l = open('/tmp/TCS.ovpn', 'wt') l.write(tempconf) l.close() mailtext = """Your TCS VPN account has been created. Please see the attached files to configure your VPN. Save all the attached files to a folder on your computer and run the attached openvpn-install.exe program. Copy the rest of the attachments to this email to the folder C:\\Program Files\\OpenVPN\\config\\ To connect to the VPN find the icon in the system tray of two red computers, and double click on it. You may be required to edit the TCS.ovpn file, and replace the address on the line "remote %s" with the external address of your server. Should you have any trouble following these instructions please contact Thusa at [email protected] or via telephone at +27 31 277 1250.""" % (self.sysconf.ExternalName,) try: Utils.sendMail("TCS Server <root@%s>" % Settings.defaultDomain, [data['mail']], self.text.vpnConfigDetails, mailtext, files) except Exception, c: print c Utils.exceptionOccured(c) return url.root.child('VPN')
def render_treeView(self, ctx, data): try: T = Tree.Tree("r", "Domains") l = Tree.retrieveTree(Settings.LDAPServer, Settings.LDAPManager, Settings.LDAPPass, 'o='+Settings.LDAPBase) flatL = Tree.flattenTree(l, 'o='+Settings.LDAPBase) flatL.sort() self.flatFil = [] except Exception, e: flatL = [] Utils.exceptionOccured(e)
def writeFile(self, fileName, content, commentChar, indentChars=8): """Cleans up the content and then writes the file""" contentSplit = content.split('\n') content = "" contentState = False for line in contentSplit: if len(line) > 1 or contentState: content += line[indentChars:] + '\n' contentState = True Utils.writeConf(fileName, content, commentChar)
def ret(_): if Utils.runningProfile()[1] == source: run = open(Settings.BaseDir + '/runningProfile', 'wt') run.write(dest) run.close() if Utils.currentProfile()[1] == source: cur = open(Settings.BaseDir + '/currentProfile', 'wt') cur.write(dest) cur.close() return url.root.child('Profiles')
def config_set_password(self, username, password): """config user set password: <username> <new password>""" rec = {'userPassword': ["{SHA}" + LDAP.hashPassword(password)]} user, domain = self.udFromUname(username) if Settings.sambaDN and domain==Settings.defaultDomain: rec['sambaNTPassword'] = [Utils.createNTHash(password)] rec['sambaLMPassword'] = [Utils.createLMHash(password)] self.setUserAttr(username, rec)
def data_storage(self, ctx, data): d = Utils.getDf() filesystem = [] for i in d: l = [ i[1], Utils.intToHBnormal(i[2] * 1024.0, True), Utils.intToHBnormal(i[3] * 1024.0, True), "%s%%" % i[5], i[0] ] filesystem.append([unicode(j) for j in l]) return filesystem
def submitForm(self, ctx, form, data): ifaces = self.sysconf.EthernetDevices iface = data['interface'].encode("ascii", "replace") if '/' in data['ip']: ip = data['ip'] network = Utils.getNetwork(ip) else: if "." in data['netmask']: cidr = Utils.netmask2cidr(data['netmask']) ip = "%s/%s" % (data['ip'], cidr) network = Utils.getNetwork(ip) else: ip = "%s/%s" % (data['ip'], data['netmask']) network = Utils.getNetwork(ip) defn = { 'ip': ip, 'network': network, 'type': 'static', 'dhcpserver': data['dhcpserver'] } if (data['mtu'] > 1200) and (data['mtu'] < 1501): defn['mtu'] = data['mtu'] if data['dhcpserver']: d = self.sysconf.DHCP if not d.get(iface): d[iface] = {} self.sysconf.DHCP = d if data.get('ipv6', False): defn['ipv6'] = data['ipv6'].encode("ascii", "replace") defn['ipv6adv'] = data['ipv6adv'] if data['dhcp']: defn['type'] = 'dhcp' else: defn['type'] = 'static' ifaces[iface] = defn self.sysconf.EthernetDevices = ifaces WebUtils.restartNetworking(data['dhcpserver']) return url.root.child('Network')
def vlanBuilder(self, i, defn): iface = { 'ip': defn['ip'].split('/')[0], 'vnum': i.replace('vlan', ''), 'network': defn['network'].split('/')[0], 'netmask': Utils.cidr2netmask(defn['ip'].split('/')[-1]), 'interface': defn['interface'] } ifacedef = """auto vlan%(vnum)s iface vlan%(vnum)s inet static address %(ip)s netmask %(netmask)s network %(network)s vlan_raw_device %(interface)s """ % iface # check routes if defn.get('routes', None): for dest, gw in defn['routes']: if dest == 'default': ifacedef += ' gateway %s\n' % gw try: if defn.get('aliases', None): for alias in defn['aliases']: ifacedef += ' up ip addr add %s dev vlan%s || true\n' % ( alias, iface['vnum']) ifacedef += ' down ip addr del %s dev vlan%s || true\n' % ( alias, iface['vnum']) except: print "Failed to configure aliases for %s" % i ifacedef += "\n" return ifacedef
def form_addSNAT(self, data): form = formal.Form() ifs = [] for i in Utils.getInterfaces(): if 'eth' in i or 'tap' in i: # Only allow tap and eth binds... ifs.append((i, i)) form.addField('dstif', formal.String(required=True), formal.widgetFactory(formal.SelectChoice, options = ifs), label = "External Interface", description = "The interface to which this traffic will be NATed. (Generaly the outside/internet interface)") form.addField('dstip', formal.String(required=True, validators=[PageHelpers.IPValidator()]), label = "External IP", description = "The IP to which this traffic will be NATed") form.addField('srcip', formal.String(required=True, strip=True, validators=[PageHelpers.IPValidator()]), label = "Source IP", description = ["The source IP you would like to NAT to and from."]) form.addField('all', formal.Boolean(), label = "Any Interface", description = "Tick this if the rule should apply to all interfaces and not just the External Interface.") form.addField('local', formal.Boolean(), label = "Use Internal", description = "Apply this NAT rule to this servers traffic as well.") form.data['local'] = False form.data['all'] = False form.addAction(self.submitSNAT) return form
def form_addNAT(self, data): form = formal.Form() ifs = [] for i in Utils.getInterfaces(): if i[:3] in ['eth', 'ppp', 'tap', 'tun']: # Only allow tap and eth binds... ifs.append((i, i)) form.addField('dstif', formal.String(required=True), formal.widgetFactory(formal.SelectChoice, options = ifs), label = "External Interface", description = "The interface to which this traffic will be NATed.") form.addField('srcif', formal.String(), formal.widgetFactory(formal.SelectChoice, options = ifs), label = "Source Interface", description = "The interface which will have NAT applied to it") form.addField('destip', formal.String(), label = "Destination IP", description = ["Destination IP or network (Leave blank for ANY). ", "This is the destination network you would like to NAT to"]) form.addField('srcip', formal.String(), label = "Source IP", description = ["Source IP or network (Leave blank for ANY). ", "This is the source network you would like to NAT from."]) form.addField('natip', formal.String(), label = "NAT IP", description = ["The IP address that you would like to NAT the connections as.", "Leave this blank to let the firewall decide based on the interface configuration."]) form.addField('proto', formal.String(), formal.widgetFactory(formal.SelectChoice, options = self.protocols), label = "Protocol", description = "Protocol to NAT") form.addField('srcport', formal.String(strip=True, validators=[PageHelpers.PortRangeValidator()]), label = "Source port", description = "TCP/UDP port to NAT.") form.addAction(self.submitNAT) return form
def form_parp(self, data): form = formal.Form() ifs = [] for i in Utils.getInterfaces(): if 'eth' in i or 'tap' in i: # Only allow tap and eth binds... ifs.append((i, i)) form.addField('ip', formal.String(required=True, strip=True, validators=[PageHelpers.IPValidator()]), label="IP Address") form.addField( 'extif', formal.String(required=True), formal.widgetFactory(formal.SelectChoice, options=ifs), label="External Interface", description= "The interface where this server will advertise availability of this IP address" ) form.addField( 'intif', formal.String(required=True), formal.widgetFactory(formal.SelectChoice, options=ifs), label="Internal Interface", description= "The interface to which this IP address will be routed (Where the server binding this IP address is)" ) form.addAction(self.submitProxyARP) return form
def form_addVLAN(self, data): form = formal.Form() form.addField('interface', formal.String(required=True), formal.widgetFactory(formal.SelectChoice, options=[ (i, i.replace('eth', 'Port ')) for i in Utils.getInterfaces() if not i == "lo" ]), label="Attached Interface") form.addField('vlan', formal.Integer(), label="VLAN Number") form.addField('ip', formal.String(), label="IP Address") form.addField('netmask', formal.String(), label="Netmask", description="Netmask or CIDR bitmask for this range") form.addField('dhcpserver', formal.Boolean(), label="DHCP Server", description="Serve DHCP on this interface") form.addAction(self.submitVlan) return form
def addForm(self, form): ifs = [] for i in Utils.getInterfaces(): if 'eth' in i or 'tap' in i: # Only allow tap and eth binds... ifs.append((i, i)) form.addField('iface', formal.String(required=True), formal.widgetFactory(formal.SelectChoice, options = ifs), label = "Interface",)
def form_statroutes(self, data): form = formal.Form() form.addField( 'dest', formal.String(required=True, strip=True, validators=[PageHelpers.IPMaskValidator()]), label="Destination network", description= "Destination network in CIDR or '0.0.0.0/0' for the default route." ) form.addField('gate', formal.String(validators=[PageHelpers.IPValidator()]), label="Gateway", description="Gateway to forward this network to") ifs = [] for i in Utils.getInterfaces(): if 'eth' or 'ppp': # Only allow ppp and eth binds... ifs.append((i, i)) form.addField( 'device', formal.String(), formal.widgetFactory(formal.SelectChoice, options=ifs), label="Device", description= "Device to forward this traffic to, or the interface to assign this route to" ) form.addAction(self.submitRoute) return form
def persistFlows(self): """ Save our currently stored flow records to the database """ print "Persisting aggregated records..." dls = [] validIndexes = Utils.getNetflowIndexes(self.config) def createRec(ipr, v1, v2, port, index): return (ipr, v1, v2, port, index) def parseDefer(chunks): recs = [rec for returned, rec in chunks] self.saveFlowBlock(recs) print "Done persisting and aggregating" reactor.callLater(self.rtime, self.persistFlows) for rec, ports in self.sourcesSeen.items(): # Grab our ip and index from the key ip, index = rec # Reset the index if we get an interface we don't know about if not (index in validIndexes): index = 201 # Usualy the default index for port, volume in ports.items(): if (volume[0] or volume[1]) and ip.strip() and port: # Lookup the IP (We don't really treat our IP field as anything special dls.append( defer.maybeDeferred(WebUtils.getUsername, ip).addBoth( createRec, volume[0], volume[1], port, index)) # Clear out the buffer for this record self.sourcesSeen[rec] = {} return defer.DeferredList(dls).addBoth(parseDefer)
def get_dhcp_config(sysconf, iface): # Catch interfaces that are DHCP themselves if sysconf.EthernetDevices[iface]['type'] == 'dhcp': return {} config = sysconf.DHCP.get(iface, {}) # Determine myIp try: myIp = sysconf.EthernetDevices[iface]['ip'].split('/')[0] myNetmask = Utils.cidr2netmask(sysconf.EthernetDevices[iface]['ip'].split('/')[1]) except KeyError: myIp = '' myNetmask = '' data = { 'rangeStart' : config.get('rangeStart', "100"), 'rangeEnd' : config.get('rangeEnd', "220"), 'netmask' : config.get('netmask', myNetmask), 'netbios' : config.get('netbios', myIp), 'nameserver' : config.get('nameserver', myIp), 'gateway' : config.get('gateway', myIp), 'domain' : config.get('domain', sysconf.Domain), 'snomStart' : config.get('snomStart', '60'), 'snomEnd' : config.get('snomEnd', '80'), 'snomConfigAddr': config.get('snomConfigAddr', myIp + ':9682'), 'network' : config.get('network', '.'.join(myIp.split('.')[:3]) + ".0") } return data
def reconfItem(self, iface, data): wanDevices = self.sysconf.WANDevices defaults = [] for d in wanDevices.get(iface, {}).get('pppd', []): # If we append these, it's impossible to reconfigure them if d not in ['defaultroute', 'usepeerdns']: defaults.append(d) if data['defaultRoute']: defaults.append('defaultroute') if data['defaultDNS']: defaults.append('usepeerdns') seg = { 'pppd': defaults, 'username': data['username'], 'password': data['password'], 'link': data['link'], 'plugins': 'pppoe' } wanDevices[iface] = seg self.sysconf.WANDevices = wanDevices if data['localOnly']: self.sysconf.LocalRoute = iface else: if self.sysconf.LocalRoute == iface: self.sysconf.LocalRoute = '' if data['createNAT']: shorewall = self.sysconf.Shorewall masq = shorewall.get('masq') if not (iface in masq): masq[iface] = Utils.getLans(self.sysconf) shorewall['masq'] = masq self.sysconf.Shorewall = shorewall WebUtils.system('/usr/local/tcs/tums/configurator --shorewall; shorewall restart') wallZones = self.sysconf.Shorewall['zones'] s = self.sysconf.Shorewall # Remove interface from any and all zones for i,v in wallZones.items(): newIfs = [] for k in v['interfaces']: if not (iface in k): newIfs.append(k) s['zones'][i]['interfaces'] = newIfs if data['zone']: # Add to new zone s['zones'][data['zone'].encode()]['interfaces'].append( '%s detect' % iface ) self.sysconf.Shorewall = s
def addForm(self, form): ifaces = [(i,i) for i in Utils.getInterfaces()] form.addField('iface', formal.String(required=True), formal.widgetFactory(formal.SelectChoice, options = ifaces), label = "Interface") form.addField('dhcp', formal.Boolean(), label = "DHCP", description="Check this if DHCP is performed on this interface") form.addField('routeback', formal.Boolean(), label = "Check this if route reflection is allowed on this interface") form.data['iface'] = ifaces[0][0]
def getZones(self): zones = self.sysconf.Shorewall.get('zones', {}) baseZones = [("all", "Any"), ('fw', "Firewall")] if self.sysconf.ProxyConfig.get('captive'): for zo in Utils.getLanZones(self.sysconf): baseZones.append(("c%s" % zo, "Authenticted %s" % zo)) return baseZones + [(zo, zo) for zo in zones.keys() ] # Build something we can se for drop downs
def writeConfig(self, *a): # Build our configuration file conf = """set daemon 300 set postmaster "postmaster@%(domain)s" """ % { 'domain': config.Domain } # Iterate through configuration for server, domain, username, password, destination in config.Mail.get( 'fetchmail', []): conf += "poll %s proto POP3 localdomains %s\n" % (server, domain) conf += " envelope \"Envelope-to\"\n" conf += " envelope \"Delivered-To\"\n" conf += " user \"%s\" with pass \"%s\" to %s here\n\n" % ( username, password, destination) fetchmailrc = open('/etc/fetchmailrc', 'wt') fetchmailrc.write(conf) fetchmailrc.close() # If unconfigured, leave now. if not config.Mail.get('fetchmail'): # Make sure it is not set to start at bootup os.system('update-rc.d -f fetchmail remove > /dev/null 2>&1') os.system('/etc/init.d/fetchmail stop') return # Check if fetchmail is installed if not Utils.isPackageInstalled('fetchmail'): print "Installing fetchmail..." os.system( 'DEBIAN_FRONTEND="noninteractive" apt-get -y -q --force-yes install fetchmail' ) # Check if it installed now. if not Utils.isPackageInstalled('fetchmail'): print "ERROR: Failed to install fetchmail." return # Make sure it is set to start os.system('update-rc.d fetchmail defaults > /dev/null 2>&1') os.system( "sed 's/START_DAEMON=no/START_DAEMON=yes/' -i /etc/default/fetchmail" )
def addProxy(self): transwww = self.sysconf.Shorewall # XXX We should have support for multiple LANPrimary interfaces here. net = [i for j,i in Utils.getLanNetworks(self.sysconf).items()][0] transwww['rules'].append([ 1, "REDIRECT loc 8080 tcp 80 - !%s" % (net) ]) self.sysconf.Shorewall = transwww
def submitRoute(self, ctx, form, data): eth = self.sysconf.EthernetDevices target = None destination = data['dest'].encode("ascii", "replace").lower() if data['gate']: gateway = data['gate'].encode("ascii", "replace") if data['device']: target = data['device'].encode("ascii", "replace") else: gateway = data['device'].encode("ascii", "replace") if '0.0.0.0/0' in destination: destination = 'default' if destination == 'default': # Purge existing default routes, if any for dev, items in eth.items(): oldRoutes = items.get('routes', []) newRoutes = [] for dst, gw in oldRoutes: if dst == "default": continue newRoutes.append((dst, gw)) eth[dev]['routes'] = newRoutes if (not target) and data['gate']: # Dunno where to go... Look at gateway and make an intelligent choice for iface, net in Utils.getLanNetworks(self.sysconf).items(): print data['gate'] if Utils.matchIP(net, gateway): # Gateway matches this interface local-link target = iface if not target: # Still nothing, go for broke - these will be added to Quagga anyways target = Utils.getLans(self.sysconf)[0] routes = eth[target].get('routes', []) routes.append((destination, gateway)) eth[target]['routes'] = routes self.sysconf.EthernetDevices = eth def next(_): return url.root.child('Routing') return applySettings().addCallback(next)