def _check_source_route_uses_default_gateway_in_rdf(self, is_public): ui_root = helpers.get_ui_config() if not ui_root.hasS(ns_ui.sourceRouting): return False return self._check_route_uses_default_gateway_in_rdf(ui_root.getS(ns_ui.sourceRouting), is_public)
def fill_client_connection_group(self, form, ctx, cc_fda): ui_root = helpers.get_ui_config() # Server address & psk #if ui_root.hasS(ns_ui.vpnServerAddress): # cc_fda['server_name'] = ui_root.getS(ns_ui.vpnServerAddress, rdf.String) #else: # cc_fda['server_name'] = '' cc_fda['psk_1'] = '' cc_fda['psk_2'] = '' psk_seq = ui_root.getS(ns_ui.preSharedKeys, rdf.Seq(rdf.Type(ns_ui.PreSharedKey))) if len(psk_seq) >= 1: cc_fda['psk_1'] = psk_seq[0].getS(ns_ui.preSharedKey, rdf.String) if len(psk_seq) >= 2: cc_fda['psk_2'] = psk_seq[1].getS(ns_ui.preSharedKey, rdf.String) dns_root = ui_root.getS(ns_ui.clientDnsServers) # DNS if dns_root.hasType(ns_ui.NetworkConnectionDns): cc_fda['dns'] = 'use_ic_dns' elif dns_root.hasType(ns_ui.SetDnsServers): cc_fda['dns'] = 'manual_dns' uidatahelpers.fill_optional_field_to_form(dns_root, ns_ui.primaryDns, rdf.IPv4Address, cc_fda, 'dns_1') uidatahelpers.fill_optional_field_to_form(dns_root, ns_ui.secondaryDns, rdf.IPv4Address, cc_fda, 'dns_2') else: raise uidatahelpers.RdfDataError('Client connection dns servers is neither Network connection dns nor set dns servers.') uidatahelpers.fill_optional_field_to_form(ui_root, ns_ui.clientPrimaryWins, rdf.IPv4Address, cc_fda, 'wins_1') uidatahelpers.fill_optional_field_to_form(ui_root, ns_ui.clientSecondaryWins, rdf.IPv4Address, cc_fda, 'wins_2') cc_fda['client_subnet'] = ui_root.getS(ns_ui.clientSubnet, rdf.IPv4Subnet) cc_fda['client_address_range'] = ui_root.getS(ns_ui.clientAddressRange, rdf.IPv4AddressRange) cc_fda['client_compression'] = ui_root.getS(ns_ui.clientCompression, rdf.Boolean)
def create_additional_routes_group(self, form, ctx): txt = self.route_uitexts def _create_route_list_entry(index): g = formalutils.CollapsibleGroup(str(index), label='') g.setCollapsed(False) g.add(formalutils.Field('subnet', dt.FormIPv4Subnet(required=True), label=txt.routing_subnet)) g.add(formalutils.Field('network_connection', formal.String(required=True), formal.widgetFactory(formal.SelectChoice, options=txt.routing_nw_options), label=txt.routing_nw_label)) g.add(formalutils.Field('gateway_selection', formal.String(required=True), formal.widgetFactory(formal.RadioChoice, options=txt.routing_gw_select_options), label=txt.routing_gw_select_label)) g.add(formalutils.Field('gateway', dt.FormIPv4Address(required=False), label=txt.routing_gw_label)) return g # Dynamic route list. routes_list = formalutils.DynamicList('ar_group', label=txt.additional_routes_caption, childCreationCallback=_create_route_list_entry) routes_list.setCollapsible(True) routes_list.setCollapsed(uihelpers.collapse_setting(ns_ui.collapseAdditionalRoutes)) try: ui_root = helpers.get_ui_config() if ui_root.hasS(ns_ui.routes): route_index = 0 for route in ui_root.getS(ns_ui.routes, rdf.Seq(rdf.Type(ns_ui.Route))): routes_list.add(_create_route_list_entry(str(route_index))) route_index += 1 except: _log.exception('failed to create dynamic routes list') return routes_list
def render_s2s_warning_heavy(self, ctx, data): ui_root = helpers.get_ui_config() if ui_root.hasS(ns_ui.clientSubnet) and \ (ui_root.getS(ns_ui.clientSubnet, rdf.IPv4Subnet) == datatypes.IPv4Subnet.fromString(uidatahelpers.uidefaults.CLIENT_SUBNET)): return ctx.tag else: return ''
def create_port_forwarding_group(self, form, ctx): txt = self.fw_uitexts def _create_port_forward_list_entry(index): g = formalutils.CollapsibleGroup(str(index), label='') g.setCollapsed(collapsed=False) g.add(formalutils.Field('new_fw_protocol', formal.String(required=True), formal.widgetFactory(formal.SelectChoice, options=txt.new_fw_protocol_options), label=txt.new_fw_protocol_label)) g.add(formalutils.Field('new_fw_port_in', formal.Integer(required=True, validators=[formal.RangeValidator(min=0, max=65535)]), label=txt.new_fw_port_in_label)) g.add(formalutils.Field('new_fw_ip_out', dt.FormIPv4Address(required=True), label=txt.new_fw_ip_out_label)) g.add(formalutils.Field('new_fw_port_out', formal.Integer(required=True, validators=[formal.RangeValidator(min=0, max=65535)]), label=txt.new_fw_port_out_label)) return g pf_list = formalutils.DynamicList('port_forwards', label=txt.port_forwards_group_caption, childCreationCallback=_create_port_forward_list_entry) pf_list.setCollapsible(True) pf_list.setCollapsed(uihelpers.collapse_setting(ns_ui.collapsePortForwardingRules)) try: ui_root = helpers.get_ui_config() if ui_root.hasS(ns_ui.portForwards): pf_index = 0 for pf in ui_root.getS(ns_ui.portForwards, rdf.Seq(rdf.Type(ns_ui.PortForward))): pf_list.add(_create_port_forward_list_entry(pf_index)) pf_index += 1 except: _log.exception('failed to create dynamic port forwardings list') return pf_list
def create_ppp_firewall_group(self, form, ctx): txt = self.route_uitexts def _create_fwrule_list_entry(index): g = formalutils.CollapsibleGroup(str(index), label='') g.setCollapsed(collapsed=False) g.add(formalutils.Field('ip_subnet', dt.FormIPv4Subnet(required=True), label='IP address or subnet')) g.add(formalutils.Field('protocol', formal.String(required=True), formal.widgetFactory(formal.SelectChoice, options=txt.fw_protocol_select_options), label='Protocol')) g.add(formalutils.Field('port', formal.Integer(required=False, validators=[formal.RangeValidator(min=0, max=65535)]), label='Port')) g.add(formalutils.Field('action', formal.String(required=True), formal.widgetFactory(formal.SelectChoice, options=txt.fw_protocol_action_options), label='Action')) return g fwrule_list = formalutils.DynamicList('fwrule_group', 'VPN Traffic Firewall Rules', childCreationCallback=_create_fwrule_list_entry) fwrule_list.setCollapsible(True) fwrule_list.setCollapsed(uihelpers.collapse_setting(ns_ui.collapsePppFirewallRules)) try: ui_root = helpers.get_ui_config() if ui_root.hasS(ns_ui.pppFirewallRules): fwrule_index = 0 for fwrule in ui_root.getS(ns_ui.pppFirewallRules, rdf.Seq(rdf.Type(ns_ui.PppFirewallRule))): fwrule_list.add(_create_fwrule_list_entry(fwrule_index)) fwrule_index += 1 except: _log.exception('failed to create dynamic ppp firewall rule list') return fwrule_list
def _callback(res): t = res["licenseKey"] _log.info("received test license: %s" % t) # parse the test license: we don't want to "taint" rdf with an invalid license license_ok = False try: from codebay.common import licensekey val, broken = licensekey.decode_license(t) if val is None: raise Exception("license is broken, groups: %s" % broken) license_ok = True except: _log.exception("test license is broken, ignoring") # store test license & force reidentify if license_ok: _log.info("received test license passes sanity check, storing") ui_root = helpers.get_ui_config() ui_root.setS(ns_ui.testLicenseKey, rdf.String, t) ign = self.managementconnection.trigger_reidentify() # returns deferred # re-export database if license_ok: @db.untransact() def _export(): try: self._export_rdf_database() except: _log.exception("failed to export rdf database (test license assigned)") _export()
def check_route_destination_valid(self): """ Checks following: - In one interface setup the destination network cannot be private. - If network router is used and nw has static ip, gw must be defined. """ ui_root = helpers.get_ui_config() def _check_interface_and_gateway(route_fda, iface_uri): if ui_root.hasS(iface_uri): if not route_fda.has_key('gateway') or route_fda['gateway'] is None: if self._network_interface_has_default_router_in_rdf(ui_root.getS(iface_uri, rdf.Type(ns_ui.NetworkConnection))): pass else: route_fda.add_error('network_connection', 'Network interface does not have a default gateway') else: pass else: route_fda.add_error('network_connection', 'Network interface not active') def _check_destination(route_fda, list_index = None): if self._can_validate(route_fda, ['network_connection']): # Check that interface and gateways exist if route_fda['network_connection'] == 'private': _check_interface_and_gateway(route_fda, ns_ui.privateNetworkConnection) elif route_fda['network_connection'] == 'internet': _check_interface_and_gateway(route_fda, ns_ui.internetConnection) else: _log.warning('unexpected case') # XXX: should not happen txt = uitexts.GlobalValidationTexts() _check_destination(self.toplevel_fda.descend('dr_group')) self._walk_through_dynamic_list(self.toplevel_fda.descend('ar_group'), _check_destination) source_route_fda = self.toplevel_fda.descend('sr_group') if source_route_fda['source_routing_selection'] == 'on': _check_destination(source_route_fda)
def _get_radius_info(self, new_ui_config=False): """Return RADIUS information in an array that we can compare later. Information included in the array is precisely the fields that, if changed, require a full runner restart (instead of just FreeRADIUS restart). Currently it is just the RADIUS server addresses, because the are required for ICMP monitoring; note that ports are *not* needed here. """ if new_ui_config: ui_root = helpers.get_new_ui_config() else: ui_root = helpers.get_ui_config() res = [] try: res.append(ui_root.getS(ns_ui.radiusPrimaryServer, rdf.String)) except: _log.exception('cannot get radius info') res.append(None) try: res.append(ui_root.getS(ns_ui.radiusSecondaryServer, rdf.String)) except: _log.exception('cannot get radius info') res.append(None) return res
def fill_users_group(self, ctx, form, g): fda = formalutils.FormDataAccessor(form, ['userlist_group'], ctx) ui_root = helpers.get_ui_config() if ui_root.hasS(ns_ui.users): for idx, user in enumerate( ui_root.getS(ns_ui.users, rdf.Seq(rdf.Type(ns_ui.User)))): try: g = self._create_user_list_entry(idx) fda_user = fda.descend(str(idx)) fda_user['username'] = user.getS(ns_ui.username, rdf.String) #fda_user['password'] = user.getS(ns_ui.password, rdf.String) fda_user['password'] = '' if user.hasS(ns_ui.fixedIp): fda_user['fixed_ip'] = user.getS( ns_ui.fixedIp, rdf.IPv4Address) else: fda_user['fixed_ip'] = None fda_user['admin_rights'] = user.getS( ns_ui.adminRights, rdf.Boolean) fda_user['vpn_rights'] = user.getS(ns_ui.vpnRights, rdf.Boolean) except: _log.exception('cannot fill data for a user, skipping')
def fill_s2s_list(self, form, ctx, conn_list): fda = formalutils.FormDataAccessor(form, ['s2s_connections'], ctx) ui_root = helpers.get_ui_config() if ui_root.hasS(ns_ui.siteToSiteConnections): for idx, conn in enumerate(ui_root.getS(ns_ui.siteToSiteConnections, rdf.Seq(rdf.Type(ns_ui.SiteToSiteConnection)))): try: g = self._create_s2s_connection_list_entry(idx) fda_conn = fda.descend(str(idx)) fda_conn['s2s_username'] = conn.getS(ns_ui.username, rdf.String) fda_conn['s2s_password'] = conn.getS(ns_ui.password, rdf.String) # XXX: why is this API so weird? why not give the rdf:Seq and get a string in response? uidatahelpers.fill_subnet_list_to_form(conn, ns_ui.subnetList, fda_conn, 's2s_subnets') mode = conn.getS(ns_ui.mode, rdf.String) if mode == 'client': fda_conn['s2s_mode'] = 'client' fda_conn['s2s_psk'] = conn.getS(ns_ui.preSharedKey, rdf.String) fda_conn['s2s_server'] = conn.getS(ns_ui.serverAddress, rdf.String) elif mode == 'server': fda_conn['s2s_mode'] = 'server' fda_conn['s2s_psk'] = '' fda_conn['s2s_server'] = '' else: raise 'unknown mode: %s' % mode conn_list.add(g) except: _log.exception('cannot fill data for s2s connection, skipping')
def _get_user_fixed_ips_rdf(self): res = [] for user in helpers.get_ui_config().getS(ns_ui.users, rdf.Seq(rdf.Type( ns_ui.User))): if user.hasS(ns_ui.fixedIp): res.append(user.getS(ns_ui.fixedIp, rdf.IPv4Address)) return res
def _check_source_route_uses_default_gateway_in_rdf(self, is_public): ui_root = helpers.get_ui_config() if not ui_root.hasS(ns_ui.sourceRouting): return False return self._check_route_uses_default_gateway_in_rdf( ui_root.getS(ns_ui.sourceRouting), is_public)
def fill_port_forwarding_group(self, form, ctx, pf_fda): def _fill_port_forward_to_form(rdf_node, fda): fda['new_fw_protocol'] = rdf_node.getS(ns_ui.protocol, rdf.String) fda['new_fw_port_in'] = rdf_node.getS(ns_ui.incomingPort, rdf.Integer) fda['new_fw_ip_out'] = rdf_node.getS(ns_ui.ipAddress, rdf.IPv4Address) fda['new_fw_port_out'] = rdf_node.getS(ns_ui.destinationPort, rdf.Integer) ui_root = helpers.get_ui_config() uidatahelpers.fill_dynamic_list_to_form(ui_root, ns_ui.portForwards, ns_ui.PortForward, pf_fda, _fill_port_forward_to_form)
def _validate_radius(self, ctx, form, data): fda = formalutils.FormDataAccessor(form, ['radius'], ctx) ui_root = helpers.get_ui_config() # Basic RADIUS validation - currently limit server addresses to IP addresses # because of FreeRADIUS DNS lookup issues (lookup happens during startup and # failed lookup makes daemon exit) server_ip_addrs = [] for srv, prt, sec in [('server1', 'serverport1', 'secret1'), ('server2', 'serverport2', 'secret2')]: has_ip = False if fda.has_key(srv) and fda[srv] is not None and fda[srv] != '': # must be IP if nonempty has_ip = True ip_ok = False try: tmp = datatypes.IPv4Address.fromString(fda[srv]) server_ip_addrs.append(tmp) ip_ok = True except: _log.exception( 'cannot parse IP address from user input: %s' % fda[srv]) if not ip_ok: fda.add_error(srv, 'Invalid IP address') if fda.has_key(prt) and fda[prt] is not None: pass # already integer and range validated else: if has_ip: fda.add_error( prt, 'Required when server defined (suggested value: 1812)') if fda.has_key(sec) and fda[sec] is not None: if not uihelpers.check_radius_secret_characters(fda[sec]): fda.add_error(sec, 'Invalid characters') else: if has_ip: fda.add_error(sec, 'Required when server defined') # If two servers, don't allow same IP for both if len(server_ip_addrs) == 2: if server_ip_addrs[0] == server_ip_addrs[1]: fda.add_error( 'server2', 'Secondary server address cannot be the same as primary server address' ) # Nas-Identifier validation if fda.has_key('nasidentifier') and fda['nasidentifier'] is not None: if not uihelpers.check_radius_nai_identifier_characters( fda['nasidentifier']): fda.add_error('nasidentifier', 'Invalid characters')
def create_ppp_firewall_group(self, form, ctx): txt = self.route_uitexts def _create_fwrule_list_entry(index): g = formalutils.CollapsibleGroup(str(index), label='') g.setCollapsed(collapsed=False) g.add( formalutils.Field('ip_subnet', dt.FormIPv4Subnet(required=True), label='IP address or subnet')) g.add( formalutils.Field('protocol', formal.String(required=True), formal.widgetFactory( formal.SelectChoice, options=txt.fw_protocol_select_options), label='Protocol')) g.add( formalutils.Field( 'port', formal.Integer( required=False, validators=[formal.RangeValidator(min=0, max=65535)]), label='Port')) g.add( formalutils.Field('action', formal.String(required=True), formal.widgetFactory( formal.SelectChoice, options=txt.fw_protocol_action_options), label='Action')) return g fwrule_list = formalutils.DynamicList( 'fwrule_group', 'VPN Traffic Firewall Rules', childCreationCallback=_create_fwrule_list_entry) fwrule_list.setCollapsible(True) fwrule_list.setCollapsed( uihelpers.collapse_setting(ns_ui.collapsePppFirewallRules)) try: ui_root = helpers.get_ui_config() if ui_root.hasS(ns_ui.pppFirewallRules): fwrule_index = 0 for fwrule in ui_root.getS( ns_ui.pppFirewallRules, rdf.Seq(rdf.Type(ns_ui.PppFirewallRule))): fwrule_list.add(_create_fwrule_list_entry(fwrule_index)) fwrule_index += 1 except: _log.exception('failed to create dynamic ppp firewall rule list') return fwrule_list
def fill_radius_group(self, ctx, form, g): fda = formalutils.FormDataAccessor(form, ['radius'], ctx) ui_root = helpers.get_ui_config() fda['server1'] = ui_root.getS(ns_ui.radiusPrimaryServer, rdf.String) fda['serverport1'] = ui_root.getS(ns_ui.radiusPrimaryServerPort, rdf.Integer) fda['secret1'] = ui_root.getS(ns_ui.radiusPrimarySecret, rdf.String) fda['server2'] = ui_root.getS(ns_ui.radiusSecondaryServer, rdf.String) fda['serverport2'] = ui_root.getS(ns_ui.radiusSecondaryServerPort, rdf.Integer) fda['secret2'] = ui_root.getS(ns_ui.radiusSecondarySecret, rdf.String) fda['nasidentifier'] = ui_root.getS(ns_ui.radiusNasIdentifier, rdf.String)
def create_users_group(self, ctx, form): # XXX: _group is unnecessary in name g = formalutils.DynamicList('userlist_group', label='Users', childCreationCallback=self._create_user_list_entry) g.setCollapsible(True) g.setCollapsed(False) ui_root = helpers.get_ui_config() if ui_root.hasS(ns_ui.users): for idx, user in enumerate(ui_root.getS(ns_ui.users, rdf.Seq(rdf.Type(ns_ui.User)))): g.add(self._create_user_list_entry(idx)) return g
def fill_management(self, ctx, fda): def _get_access(pub, priv): if pub: if priv: return 'both' else: return 'public' else: if priv: return 'private' else: return 'none' ui_root = helpers.get_ui_config() tmp = fda.descend('license_group') tmp['license_key'] = ui_root.getS(ns_ui.licenseKey, rdf.String) tmp = fda.descend('locale_group') tmp['timezone'] = ui_root.getS(ns_ui.timezone, rdf.String) tmp['keymap'] = ui_root.getS(ns_ui.keymap, rdf.String) tmp = fda.descend('reboot_group') tmp['reboot_day'] = ui_root.getS(ns_ui.periodicRebootDay, rdf.Integer) tmp['reboot_time'] = ui_root.getS(ns_ui.periodicRebootTime, rdf.Integer) tmp['automatic_updates'] = ui_root.getS(ns_ui.automaticUpdates, rdf.Boolean) tmp = fda.descend('snmp_group') tmp['snmp_access'] = _get_access( ui_root.getS(ns_ui.snmpAccessPublic, rdf.Boolean), ui_root.getS(ns_ui.snmpAccessPrivate, rdf.Boolean)) tmp['snmp_community'] = ui_root.getS(ns_ui.snmpCommunity, rdf.String) tmp = fda.descend('remote_group') tmp['www_administration'] = _get_access( ui_root.getS(ns_ui.webAccessPublic, rdf.Boolean), ui_root.getS(ns_ui.webAccessPrivate, rdf.Boolean)) tmp['ssh_connection'] = _get_access( ui_root.getS(ns_ui.sshAccessPublic, rdf.Boolean), ui_root.getS(ns_ui.sshAccessPrivate, rdf.Boolean)) # XXX: private cert chain / key not currently supported tmp = fda.descend('ssl_group') tmp['ssl_certificate_chain'] = '' tmp['ssl_private_key'] = '' if ui_root.hasS(ns_ui.publicSslCertificateChain): tmp['ssl_certificate_chain'] = ui_root.getS( ns_ui.publicSslCertificateChain, rdf.String) if ui_root.hasS(ns_ui.publicSslPrivateKey): tmp['ssl_private_key'] = ui_root.getS(ns_ui.publicSslPrivateKey, rdf.String)
def render_login_action(self, ctx, data): # XXX: this causes a session to be created automatically, because # local access from anonymous mind is allowed ui_root = helpers.get_ui_config() next = '/admin/status/main.html' # XXX: constant? if ui_root.hasS(ns_ui.initialConfigSaved) and (not ui_root.getS(ns_ui.initialConfigSaved, rdf.Boolean)): next = '/admin/misc/initialconfig.html' elif not uihelpers.check_network_interface_configuration(): next = '/admin/misc/interfaceerror.html' return next
def create_port_forwarding_group(self, form, ctx): txt = self.fw_uitexts def _create_port_forward_list_entry(index): g = formalutils.CollapsibleGroup(str(index), label='') g.setCollapsed(collapsed=False) g.add( formalutils.Field('new_fw_protocol', formal.String(required=True), formal.widgetFactory( formal.SelectChoice, options=txt.new_fw_protocol_options), label=txt.new_fw_protocol_label)) g.add( formalutils.Field( 'new_fw_port_in', formal.Integer( required=True, validators=[formal.RangeValidator(min=0, max=65535)]), label=txt.new_fw_port_in_label)) g.add( formalutils.Field('new_fw_ip_out', dt.FormIPv4Address(required=True), label=txt.new_fw_ip_out_label)) g.add( formalutils.Field( 'new_fw_port_out', formal.Integer( required=True, validators=[formal.RangeValidator(min=0, max=65535)]), label=txt.new_fw_port_out_label)) return g pf_list = formalutils.DynamicList( 'port_forwards', label=txt.port_forwards_group_caption, childCreationCallback=_create_port_forward_list_entry) pf_list.setCollapsible(True) pf_list.setCollapsed( uihelpers.collapse_setting(ns_ui.collapsePortForwardingRules)) try: ui_root = helpers.get_ui_config() if ui_root.hasS(ns_ui.portForwards): pf_index = 0 for pf in ui_root.getS(ns_ui.portForwards, rdf.Seq(rdf.Type(ns_ui.PortForward))): pf_list.add(_create_port_forward_list_entry(pf_index)) pf_index += 1 except: _log.exception('failed to create dynamic port forwardings list') return pf_list
def _check_overlap_against_sitetosite_subnets(self, subnet): ui_root = helpers.get_ui_config() if ui_root.hasS(ns_ui.siteToSiteConnections): for i in ui_root.getS(ns_ui.siteToSiteConnections, rdf.Seq(rdf.Type(ns_ui.SiteToSiteConnection))): if i.hasS(ns_ui.subnetList): for j in i.getS(ns_ui.subnetList, rdf.Seq(rdf.Type(ns_ui.Subnet))): s2s_sub = j.getS(ns_ui.subnet, rdf.IPv4Subnet) _log.debug('comparing ppp subnet %s against site-to-site subnet %s' % (subnet.toString(), s2s_sub.toString())) if subnet.overlapsWithSubnet(s2s_sub): return False return True
def render_dump(self, ctx, data): myenv = dict(os.environ) myenv['MIBS'] = '+VPNEASE-MIB' community = None try: community = helpers.get_ui_config().getS(ns_ui.snmpCommunity, rdf.String) except: _log.exception('cannot get snmp communit string, defaulting to public') community = 'public' rc, stdout, stderr = run_command([constants.CMD_SNMPWALK, '-v', '2c', '-c', community, '127.0.0.1', 'vpneaseMIB'], retval=runcommand.FAIL, env=myenv) return stdout
def create_additional_routes_group(self, form, ctx): txt = self.route_uitexts def _create_route_list_entry(index): g = formalutils.CollapsibleGroup(str(index), label='') g.setCollapsed(False) g.add( formalutils.Field('subnet', dt.FormIPv4Subnet(required=True), label=txt.routing_subnet)) g.add( formalutils.Field('network_connection', formal.String(required=True), formal.widgetFactory( formal.SelectChoice, options=txt.routing_nw_options), label=txt.routing_nw_label)) g.add( formalutils.Field('gateway_selection', formal.String(required=True), formal.widgetFactory( formal.RadioChoice, options=txt.routing_gw_select_options), label=txt.routing_gw_select_label)) g.add( formalutils.Field('gateway', dt.FormIPv4Address(required=False), label=txt.routing_gw_label)) return g # Dynamic route list. routes_list = formalutils.DynamicList( 'ar_group', label=txt.additional_routes_caption, childCreationCallback=_create_route_list_entry) routes_list.setCollapsible(True) routes_list.setCollapsed( uihelpers.collapse_setting(ns_ui.collapseAdditionalRoutes)) try: ui_root = helpers.get_ui_config() if ui_root.hasS(ns_ui.routes): route_index = 0 for route in ui_root.getS(ns_ui.routes, rdf.Seq(rdf.Type(ns_ui.Route))): routes_list.add(_create_route_list_entry(str(route_index))) route_index += 1 except: _log.exception('failed to create dynamic routes list') return routes_list
def _check_routes_use_default_gateway_in_rdf(self, is_public): ui_root = helpers.get_ui_config() if ui_root.hasS(ns_ui.routes): for r in ui_root.getS(ns_ui.routes, rdf.Seq(rdf.Type(ns_ui.Route))): if r.hasS(ns_ui.route): if self._check_route_uses_default_gateway_in_rdf(r.getS(ns_ui.route), is_public): return True if ui_root.hasS(ns_ui.defaultRoute): if self._check_route_uses_default_gateway_in_rdf(ui_root.getS(ns_ui.defaultRoute), is_public): return True return False
def fill_client_connection_group(self, form, ctx, cc_fda): ui_root = helpers.get_ui_config() # Server address & psk #if ui_root.hasS(ns_ui.vpnServerAddress): # cc_fda['server_name'] = ui_root.getS(ns_ui.vpnServerAddress, rdf.String) #else: # cc_fda['server_name'] = '' cc_fda['psk_1'] = '' cc_fda['psk_2'] = '' psk_seq = ui_root.getS(ns_ui.preSharedKeys, rdf.Seq(rdf.Type(ns_ui.PreSharedKey))) if len(psk_seq) >= 1: cc_fda['psk_1'] = psk_seq[0].getS(ns_ui.preSharedKey, rdf.String) if len(psk_seq) >= 2: cc_fda['psk_2'] = psk_seq[1].getS(ns_ui.preSharedKey, rdf.String) dns_root = ui_root.getS(ns_ui.clientDnsServers) # DNS if dns_root.hasType(ns_ui.NetworkConnectionDns): cc_fda['dns'] = 'use_ic_dns' elif dns_root.hasType(ns_ui.SetDnsServers): cc_fda['dns'] = 'manual_dns' uidatahelpers.fill_optional_field_to_form(dns_root, ns_ui.primaryDns, rdf.IPv4Address, cc_fda, 'dns_1') uidatahelpers.fill_optional_field_to_form(dns_root, ns_ui.secondaryDns, rdf.IPv4Address, cc_fda, 'dns_2') else: raise uidatahelpers.RdfDataError( 'Client connection dns servers is neither Network connection dns nor set dns servers.' ) uidatahelpers.fill_optional_field_to_form(ui_root, ns_ui.clientPrimaryWins, rdf.IPv4Address, cc_fda, 'wins_1') uidatahelpers.fill_optional_field_to_form(ui_root, ns_ui.clientSecondaryWins, rdf.IPv4Address, cc_fda, 'wins_2') cc_fda['client_subnet'] = ui_root.getS(ns_ui.clientSubnet, rdf.IPv4Subnet) cc_fda['client_address_range'] = ui_root.getS(ns_ui.clientAddressRange, rdf.IPv4AddressRange) cc_fda['client_compression'] = ui_root.getS(ns_ui.clientCompression, rdf.Boolean)
def create_users_group(self, ctx, form): # XXX: _group is unnecessary in name g = formalutils.DynamicList( 'userlist_group', label='Users', childCreationCallback=self._create_user_list_entry) g.setCollapsible(True) g.setCollapsed(False) ui_root = helpers.get_ui_config() if ui_root.hasS(ns_ui.users): for idx, user in enumerate( ui_root.getS(ns_ui.users, rdf.Seq(rdf.Type(ns_ui.User)))): g.add(self._create_user_list_entry(idx)) return g
def _f(): # this is to handle races if self._dyndns_resolve_in_progress: _log.info("dyndns resolution already in progress, not starting another one") return None ui_root = helpers.get_ui_config() now = datetime.datetime.utcnow() if ui_root.hasS(ns_ui.dynDnsServer): ddns_root = ui_root.getS(ns_ui.dynDnsServer, rdf.Type(ns_ui.DynDnsServer)) if ddns_root.hasS(ns_ui.dynDnsHostname): hostname = ddns_root.getS(ns_ui.dynDnsHostname, rdf.String) _log.info("dyndns configured, resolving %s" % hostname) # NB: not inside transact def _success(res): _log.info("dyndns lookup successful, %s -> %s" % (hostname, res.toString())) self._dyndns_address = res.toString() self._dyndns_address_timestamp = datetime.datetime.utcnow() # NB: not inside transact def _failed(reason): _log.info("dyndns lookup failed, reason: %s" % reason) self._dyndns_address = "ERROR" self._dyndns_address_timestamp = datetime.datetime.utcnow() # NB: not inside transact def _clear_marker(res): _log.info("dyndns in progress marker cleared") self._dyndns_resolve_in_progress = False self._dyndns_resolve_in_progress = True d = uihelpers.dns_lookup(hostname) d.addCallback(_success) d.addErrback(_failed) # this intentionally follows _success d.addCallbacks(_clear_marker, _clear_marker) return d else: _log.info("dyndns configured, but missing hostname") self._dyndns_address = "" self._dyndns_address_timestamp = now else: _log.info("dyndns not configured, no need to resolve") self._dyndns_address = "" self._dyndns_address_timestamp = now
def _validate_radius(self, ctx, form, data): fda = formalutils.FormDataAccessor(form, ['radius'], ctx) ui_root = helpers.get_ui_config() # Basic RADIUS validation - currently limit server addresses to IP addresses # because of FreeRADIUS DNS lookup issues (lookup happens during startup and # failed lookup makes daemon exit) server_ip_addrs = [] for srv, prt, sec in [ ('server1', 'serverport1', 'secret1'), ('server2', 'serverport2', 'secret2') ]: has_ip = False if fda.has_key(srv) and fda[srv] is not None and fda[srv] != '': # must be IP if nonempty has_ip = True ip_ok = False try: tmp = datatypes.IPv4Address.fromString(fda[srv]) server_ip_addrs.append(tmp) ip_ok = True except: _log.exception('cannot parse IP address from user input: %s' % fda[srv]) if not ip_ok: fda.add_error(srv, 'Invalid IP address') if fda.has_key(prt) and fda[prt] is not None: pass # already integer and range validated else: if has_ip: fda.add_error(prt, 'Required when server defined (suggested value: 1812)') if fda.has_key(sec) and fda[sec] is not None: if not uihelpers.check_radius_secret_characters(fda[sec]): fda.add_error(sec, 'Invalid characters') else: if has_ip: fda.add_error(sec, 'Required when server defined') # If two servers, don't allow same IP for both if len(server_ip_addrs) == 2: if server_ip_addrs[0] == server_ip_addrs[1]: fda.add_error('server2', 'Secondary server address cannot be the same as primary server address') # Nas-Identifier validation if fda.has_key('nasidentifier') and fda['nasidentifier'] is not None: if not uihelpers.check_radius_nai_identifier_characters(fda['nasidentifier']): fda.add_error('nasidentifier', 'Invalid characters')
def _check_routes_use_default_gateway_in_rdf(self, is_public): ui_root = helpers.get_ui_config() if ui_root.hasS(ns_ui.routes): for r in ui_root.getS(ns_ui.routes, rdf.Seq(rdf.Type(ns_ui.Route))): if r.hasS(ns_ui.route): if self._check_route_uses_default_gateway_in_rdf( r.getS(ns_ui.route), is_public): return True if ui_root.hasS(ns_ui.defaultRoute): if self._check_route_uses_default_gateway_in_rdf( ui_root.getS(ns_ui.defaultRoute), is_public): return True return False
def _check_update_on_next_reboot(): try: ui_root = helpers.get_ui_config() if ui_root.hasS(ns_ui.automaticUpdates) and ui_root.getS(ns_ui.automaticUpdates, rdf.Boolean): # XXX: duplication update_info = helpers.get_db_root().getS(ns_ui.updateInfo, rdf.Type(ns_ui.UpdateInfo)) latest = update_info.getS(ns_ui.latestKnownVersion, rdf.String) current = helpers.get_product_version() if (latest != '') and (helpers.compare_product_versions(latest, current) > 0): return True else: return False else: return False except: # default, assume False _log.exception('cannot determine whether product update happens on next reboot') return False
def _check_overlap_against_sitetosite_subnets(self, subnet): ui_root = helpers.get_ui_config() if ui_root.hasS(ns_ui.siteToSiteConnections): for i in ui_root.getS( ns_ui.siteToSiteConnections, rdf.Seq(rdf.Type(ns_ui.SiteToSiteConnection))): if i.hasS(ns_ui.subnetList): for j in i.getS(ns_ui.subnetList, rdf.Seq(rdf.Type(ns_ui.Subnet))): s2s_sub = j.getS(ns_ui.subnet, rdf.IPv4Subnet) _log.debug( 'comparing ppp subnet %s against site-to-site subnet %s' % (subnet.toString(), s2s_sub.toString())) if subnet.overlapsWithSubnet(s2s_sub): return False return True
def fill_management(self, ctx, fda): def _get_access(pub, priv): if pub: if priv: return 'both' else: return 'public' else: if priv: return 'private' else: return 'none' ui_root = helpers.get_ui_config() tmp = fda.descend('license_group') tmp['license_key'] = ui_root.getS(ns_ui.licenseKey, rdf.String) tmp = fda.descend('locale_group') tmp['timezone'] = ui_root.getS(ns_ui.timezone, rdf.String) tmp['keymap'] = ui_root.getS(ns_ui.keymap, rdf.String) tmp = fda.descend('reboot_group') tmp['reboot_day'] = ui_root.getS(ns_ui.periodicRebootDay, rdf.Integer) tmp['reboot_time'] = ui_root.getS(ns_ui.periodicRebootTime, rdf.Integer) tmp['automatic_updates'] = ui_root.getS(ns_ui.automaticUpdates, rdf.Boolean) tmp = fda.descend('snmp_group') tmp['snmp_access'] = _get_access(ui_root.getS(ns_ui.snmpAccessPublic, rdf.Boolean), ui_root.getS(ns_ui.snmpAccessPrivate, rdf.Boolean)) tmp['snmp_community'] = ui_root.getS(ns_ui.snmpCommunity, rdf.String) tmp = fda.descend('remote_group') tmp['www_administration'] = _get_access(ui_root.getS(ns_ui.webAccessPublic, rdf.Boolean), ui_root.getS(ns_ui.webAccessPrivate, rdf.Boolean)) tmp['ssh_connection'] = _get_access(ui_root.getS(ns_ui.sshAccessPublic, rdf.Boolean), ui_root.getS(ns_ui.sshAccessPrivate, rdf.Boolean)) # XXX: private cert chain / key not currently supported tmp = fda.descend('ssl_group') tmp['ssl_certificate_chain'] = '' tmp['ssl_private_key'] = '' if ui_root.hasS(ns_ui.publicSslCertificateChain): tmp['ssl_certificate_chain'] = ui_root.getS(ns_ui.publicSslCertificateChain, rdf.String) if ui_root.hasS(ns_ui.publicSslPrivateKey): tmp['ssl_private_key'] = ui_root.getS(ns_ui.publicSslPrivateKey, rdf.String)
def check_route_destination_valid(self): """ Checks following: - In one interface setup the destination network cannot be private. - If network router is used and nw has static ip, gw must be defined. """ ui_root = helpers.get_ui_config() def _check_interface_and_gateway(route_fda, iface_uri): if ui_root.hasS(iface_uri): if not route_fda.has_key( 'gateway') or route_fda['gateway'] is None: if self._network_interface_has_default_router_in_rdf( ui_root.getS(iface_uri, rdf.Type(ns_ui.NetworkConnection))): pass else: route_fda.add_error( 'network_connection', 'Network interface does not have a default gateway' ) else: pass else: route_fda.add_error('network_connection', 'Network interface not active') def _check_destination(route_fda, list_index=None): if self._can_validate(route_fda, ['network_connection']): # Check that interface and gateways exist if route_fda['network_connection'] == 'private': _check_interface_and_gateway( route_fda, ns_ui.privateNetworkConnection) elif route_fda['network_connection'] == 'internet': _check_interface_and_gateway(route_fda, ns_ui.internetConnection) else: _log.warning('unexpected case') # XXX: should not happen txt = uitexts.GlobalValidationTexts() _check_destination(self.toplevel_fda.descend('dr_group')) self._walk_through_dynamic_list(self.toplevel_fda.descend('ar_group'), _check_destination) source_route_fda = self.toplevel_fda.descend('sr_group') if source_route_fda['source_routing_selection'] == 'on': _check_destination(source_route_fda)
def render_dump(self, ctx, data): myenv = dict(os.environ) myenv['MIBS'] = '+VPNEASE-MIB' community = None try: community = helpers.get_ui_config().getS(ns_ui.snmpCommunity, rdf.String) except: _log.exception( 'cannot get snmp communit string, defaulting to public') community = 'public' rc, stdout, stderr = run_command([ constants.CMD_SNMPWALK, '-v', '2c', '-c', community, '127.0.0.1', 'vpneaseMIB' ], retval=runcommand.FAIL, env=myenv) return stdout
def fill_users_group(self, ctx, form, g): fda = formalutils.FormDataAccessor(form, ['userlist_group'], ctx) ui_root = helpers.get_ui_config() if ui_root.hasS(ns_ui.users): for idx, user in enumerate(ui_root.getS(ns_ui.users, rdf.Seq(rdf.Type(ns_ui.User)))): try: g = self._create_user_list_entry(idx) fda_user = fda.descend(str(idx)) fda_user['username'] = user.getS(ns_ui.username, rdf.String) #fda_user['password'] = user.getS(ns_ui.password, rdf.String) fda_user['password'] = '' if user.hasS(ns_ui.fixedIp): fda_user['fixed_ip'] = user.getS(ns_ui.fixedIp, rdf.IPv4Address) else: fda_user['fixed_ip'] = None fda_user['admin_rights'] = user.getS(ns_ui.adminRights, rdf.Boolean) fda_user['vpn_rights'] = user.getS(ns_ui.vpnRights, rdf.Boolean) except: _log.exception('cannot fill data for a user, skipping')
def fill_s2s_list(self, form, ctx, conn_list): fda = formalutils.FormDataAccessor(form, ['s2s_connections'], ctx) ui_root = helpers.get_ui_config() if ui_root.hasS(ns_ui.siteToSiteConnections): for idx, conn in enumerate( ui_root.getS(ns_ui.siteToSiteConnections, rdf.Seq(rdf.Type( ns_ui.SiteToSiteConnection)))): try: g = self._create_s2s_connection_list_entry(idx) fda_conn = fda.descend(str(idx)) fda_conn['s2s_username'] = conn.getS( ns_ui.username, rdf.String) fda_conn['s2s_password'] = conn.getS( ns_ui.password, rdf.String) # XXX: why is this API so weird? why not give the rdf:Seq and get a string in response? uidatahelpers.fill_subnet_list_to_form( conn, ns_ui.subnetList, fda_conn, 's2s_subnets') mode = conn.getS(ns_ui.mode, rdf.String) if mode == 'client': fda_conn['s2s_mode'] = 'client' fda_conn['s2s_psk'] = conn.getS( ns_ui.preSharedKey, rdf.String) fda_conn['s2s_server'] = conn.getS( ns_ui.serverAddress, rdf.String) elif mode == 'server': fda_conn['s2s_mode'] = 'server' fda_conn['s2s_psk'] = '' fda_conn['s2s_server'] = '' else: raise 'unknown mode: %s' % mode conn_list.add(g) except: _log.exception( 'cannot fill data for s2s connection, skipping')
def _check_update_on_next_reboot(): try: ui_root = helpers.get_ui_config() if ui_root.hasS(ns_ui.automaticUpdates) and ui_root.getS( ns_ui.automaticUpdates, rdf.Boolean): # XXX: duplication update_info = helpers.get_db_root().getS( ns_ui.updateInfo, rdf.Type(ns_ui.UpdateInfo)) latest = update_info.getS(ns_ui.latestKnownVersion, rdf.String) current = helpers.get_product_version() if (latest != '') and (helpers.compare_product_versions( latest, current) > 0): return True else: return False else: return False except: # default, assume False _log.exception( 'cannot determine whether product update happens on next reboot') return False
def _get_user_fixed_ips_rdf(self): res = [] for user in helpers.get_ui_config().getS(ns_ui.users, rdf.Seq(rdf.Type(ns_ui.User))): if user.hasS(ns_ui.fixedIp): res.append(user.getS(ns_ui.fixedIp, rdf.IPv4Address)) return res
def submitted(self, ctx, form, data): fda = formalutils.FormDataAccessor(form, [], ctx) pd = uidatahelpers.CreateProtocolData() # Save collapsed states first, so they feed back to next round for [rdf_uri, key] in [[ns_ui.collapseInterfaceCount, 'ifcount_group'], [ns_ui.collapseInternetConnection, 'ic_group'], [ns_ui.collapsePrivateNetwork, 'pn_group'], [ns_ui.collapseDns, 'dns_group'], [ns_ui.collapseDynamicDns, 'ddns_group'], [ns_ui.collapseClientConnection, 'client_connection']]: try: # XXX: passing of the hidden _collapsedstate_ parameter is not too clean uihelpers.update_collapse_setting( rdf_uri, fda['%s._collapsedstate_' % key]) except: _log.exception('error updating collapsed state for %s' % rdf_uri) # Validation and config generation old_vpn_server_address = None try: # Form global canonicalization gc = networkconfigvalidation.ConfigNetworkCanonicalizator( ctx, form, data) gc.canonicalize_ip_subnet() # Form global validation gv = networkconfigvalidation.ConfigNetworkValidator( ctx, form, data) # Check required fields. Some fields may be required because of some other fields value and thus cannot # be checked locally. gv.check_required_fields() gv.ip_and_subnet_match() # Checks public and private. gv.public_private_ip_not_same( ) # XXX: warning for now only; worth a warning, but still works to some extent gv.public_private_eth_not_same() gv.check_single_interface_ok() gv.check_interface_default_gateways() gv.check_public_subnet( ) # XXX: warning for now only, overlaps don't cause runner errors gv.check_private_subnet( ) # XXX: warning for now only, overlaps don't cause runner errors gv.check_uplink() gv.check_only_one_proxyarp() gv.check_dns_dhcp_valid() gv.check_client_settings( ) # XXX: some checks commented to warnings for now # Intermediate early bail out to avoid saving if there are errors gv.finalize_validation() # XXX: One interface setup could rename the internet connection tab to # network connection, and update all the selections. # Get old VPN server address for comparison ui_root = helpers.get_ui_config() if ui_root.hasS(ns_ui.vpnServerAddress): old_vpn_server_address = ui_root.getS(ns_ui.vpnServerAddress, rdf.String) # Deep copy UI config to 'new' UI config pd.clone_ui_config() # Save form data self.save_network_data(ctx, form, data) self.save_client_connection_data(ctx, form, data) # newUiConfig -> newL2tpDeviceConfig pd.save_protocol_data() except: _log.exception( 'validation failed unexpectedly, adding global error') fda.add_global_error('Unknown validation error') # Finalize raises exception if there are errors and handles disabled fields as well as copying form data to errors data. gv.finalize_validation() # Save ok, activate config pd.activate_protocol_data() # Update initial config saved flag pd.update_initial_config_saved() # If certificate name has changed, regenerate and re-read cert files new_vpn_server_address = None ui_root = helpers.get_ui_config() # reget root after change if ui_root.hasS(ns_ui.vpnServerAddress): new_vpn_server_address = ui_root.getS(ns_ui.vpnServerAddress, rdf.String) # XXX: unnecessary to check for None now, but doesn't hurt if (old_vpn_server_address != new_vpn_server_address): common_name = None if (new_vpn_server_address is not None) and (new_vpn_server_address != ''): common_name = new_vpn_server_address _log.info('regenerating ssl certificates, common name %s' % common_name) @db.untransact() def _regenerate(): helpers.generate_self_signed_certificate( constants.WEBUI_PRIVATE_KEY, constants.WEBUI_CERTIFICATE, common_name=common_name) _regenerate() self.master.reread_ssl_files() else: _log.debug('certificate name unchanged, not regenerating') # # XXX: It would be cleaner if we could first stop the runner, then change the # config, and then restart it. If we do that with a deferred, then it is possible # that the user changes the config again before we have time to activate it. # Putting the config into some sort of "staging area" might help. Currently we # simply assume that runner stop (and start) are robust enough. # # stop, configure, start followup = uihelpers.build_uri(ctx, 'status/main.html') return uihelpers.reconfigure_and_restart_page(self.master, ctx, followup_uri=followup)
def fill_firewall_group(self, form, ctx, fw_fda): ui_root = helpers.get_ui_config() fw_fda['firewall_in_use'] = ui_root.getS(ns_ui.firewallInUse, rdf.Boolean)
def fill_routing_group(self, form, ctx, toplevel_fda): def _fill_route_to_form(rdf_node, fda, subnet_exist): if rdf_node.hasType(ns_ui.InternetConnectionRoute): fda['network_connection'] = 'internet' elif rdf_node.hasType(ns_ui.PrivateNetworkConnectionRoute): fda['network_connection'] = 'private' else: raise uidatahelpers.RdfDataError( 'Route\'s destination network is neither internet nor private network connection' ) # Default route does not have subnet # XXX: why not 0.0.0.0/0 instead? if subnet_exist: fda['subnet'] = rdf_node.getS(ns_ui.subnet, rdf.IPv4Subnet) gw_node = rdf_node.getS(ns_ui.routeGateway) if gw_node.hasType(ns_ui.RouteGatewayNetworkDefault): fda['gateway_selection'] = 'nw_default_gw' elif gw_node.hasType(ns_ui.RouteGatewayManual): fda['gateway_selection'] = 'manual_gw' fda['gateway'] = gw_node.getS(ns_ui.ipAddress, rdf.IPv4Address) else: raise uidatahelpers.RdfDataError( 'Route\'s gateway is neither network default nor set gateway.' ) def _fill_additional_route_to_form(rdf_node, fda): _fill_route_to_form(rdf_node.getS(ns_ui.route), fda, True) def _fill_ppp_firewall_rule_to_form(rdf_node, fda): if rdf_node.hasS(ns_ui.ipAddress): # XXX: this is never encountered in practice? fda['ip_subnet'] = rdf_node.getS(ns_ui.ipAddress, rdf.IPv4Address) elif rdf_node.hasS(ns_ui.subnet): fda['ip_subnet'] = rdf_node.getS(ns_ui.subnet, rdf.IPv4Subnet) else: raise uidatahelpers.RdfDataError( 'Prohibited service ip/subnet is neither ipaddress nor subnet.' ) if rdf_node.hasS(ns_ui.protocol): fda['protocol'] = rdf_node.getS(ns_ui.protocol, rdf.String) else: fda['protocol'] = 'any' uidatahelpers.fill_optional_field_to_form(rdf_node, ns_ui.port, rdf.Integer, fda, 'port') fda['action'] = rdf_node.getS(ns_ui.action, rdf.String) ui_root = helpers.get_ui_config() # Default route _fill_route_to_form(ui_root.getS(ns_ui.defaultRoute), toplevel_fda.descend('dr_group'), False) # Additional routes add_route_fda = toplevel_fda.descend('ar_group') uidatahelpers.fill_dynamic_list_to_form( ui_root, ns_ui.routes, ns_ui.Route, add_route_fda, _fill_additional_route_to_form) # Source routing (forced routing) source_fda = toplevel_fda.descend('sr_group') if ui_root.hasS(ns_ui.sourceRouting): source_fda['source_routing_selection'] = 'on' _fill_route_to_form(ui_root.getS(ns_ui.sourceRouting), source_fda, False) else: source_fda['source_routing_selection'] = 'off' # PPP firewall rules fwrule_fda = toplevel_fda.descend('fwrule_group') uidatahelpers.fill_dynamic_list_to_form( ui_root, ns_ui.pppFirewallRules, ns_ui.PppFirewallRule, fwrule_fda, _fill_ppp_firewall_rule_to_form)
def _validate_users(self, ctx, form, data, userpw_dict): fda = formalutils.FormDataAccessor(form, ['userlist_group'], ctx) ui_root = helpers.get_ui_config() # user list validation idx = 0 users = [] while True: fda_user = fda.descend(str(idx)) if len(fda_user.keys()) == 0: break users.append(fda_user) idx += 1 s2s_server_usernames = [] if ui_root.hasS(ns_ui.siteToSiteConnections): for s2s_conn in ui_root.getS(ns_ui.siteToSiteConnections, rdf.Seq(rdf.Type(ns_ui.SiteToSiteConnection))): if s2s_conn.hasS(ns_ui.mode) and s2s_conn.getS(ns_ui.mode, rdf.String) == 'server' and s2s_conn.hasS(ns_ui.username): s2s_server_usernames.append(s2s_conn.getS(ns_ui.username, rdf.String)) usernames_found = [] fixed_ips_found = [] for fda_user_index, fda_user in enumerate(users): # username checks if fda_user.has_key('username'): if not uihelpers.check_ppp_username_characters(fda_user['username']): fda_user.add_error('username', 'Invalid characters') else: username = fda_user['username'] if username in usernames_found: fda_user.add_error('username', 'Duplicate username') elif username in s2s_server_usernames: fda_user.add_error('username', 'Duplicate username (already a site-to-site server-mode connection of that name)') elif len(username) > constants.MAX_USERNAME_LENGTH: fda_user.add_error('username', 'Username too long') else: usernames_found.append(username) # password chars if fda_user.has_key('password') and (fda_user['password'] is not None): if not uihelpers.check_ppp_password_characters(fda_user['password']): fda_user.add_error('password', 'Invalid characters') elif len(fda_user['password']) > constants.MAX_PASSWORD_LENGTH: fda_user.add_error('password', 'Password too long') # Password is a bit tricky; admin may have changed a username and we don't have # any permanent user identifiers that allow us to identify this as the same user # and keep its password despite the name change. So, we require either that the # password is set, or that a user previously existed with this username (changed # or not !) and use the old password. if fda_user.has_key('username') and (fda_user['username'] is not None) and \ (not fda_user.has_key('password') or fda_user['password'] is None or fda_user['password'] == ''): username = fda_user['username'] if userpw_dict.has_key(username): # all ok pass else: fda_user.add_error('password', 'Required for new users') # fixed ip checks # XXX: we could also check that the fixed IP is from the # PPP subnet to try to prevent admin configuration errors, # but this would be too restrictive and is currently not # done: a warning would help here. if fda_user.has_key('fixed_ip') and (fda_user['fixed_ip'] is not None) and (fda_user['fixed_ip'] != ''): fixed_ip_errors = False fixed_ip = fda_user['fixed_ip'] iprange = ui_root.getS(ns_ui.clientAddressRange, rdf.IPv4AddressRange) pppsubnet = ui_root.getS(ns_ui.clientSubnet, rdf.IPv4Subnet) # The fixed IP may not overlap with other users fixed IP addresses if fixed_ip.toString() in fixed_ips_found: fda_user.add_error('fixed_ip', 'Duplicate fixed IP address') fixed_ip_errors = True # Check restricted addresses inside PPP subnet if pppsubnet.inSubnet(fixed_ip): # The fixed IP must not be from the PPP address range (dynamic allocation pool) if iprange.inRange(fixed_ip): fda_user.add_error('fixed_ip', 'Overlaps with client address range') fixed_ip_errors = True if fixed_ip < pppsubnet.getFirstUsableAddress(): fda_user.add_error('fixed_ip', 'First address of the client subnet prohibited') fixed_ip_errors = True elif fixed_ip == pppsubnet.getLastUsableAddress(): fda_user.add_error('fixed_ip', 'Last usable address of the client subnet prohibited') fixed_ip_errors = True elif fixed_ip > pppsubnet.getLastUsableAddress(): fda_user.add_error('fixed_ip', 'Last address of the client subnet prohibited') fixed_ip_errors = True if not fixed_ip_errors: fixed_ips_found.append(fixed_ip.toString())
def _f(): try: return helpers.get_ui_config().getS(ns_ui.timezone, rdf.String) except: _log.exception('cannot figure out timezone, using %s' % constants.DEFAULT_TIMEZONE) return constants.DEFAULT_TIMEZONE
def fill_routing_group(self, form, ctx, toplevel_fda): def _fill_route_to_form(rdf_node, fda, subnet_exist): if rdf_node.hasType(ns_ui.InternetConnectionRoute): fda['network_connection'] = 'internet' elif rdf_node.hasType(ns_ui.PrivateNetworkConnectionRoute): fda['network_connection'] = 'private' else: raise uidatahelpers.RdfDataError('Route\'s destination network is neither internet nor private network connection') # Default route does not have subnet # XXX: why not 0.0.0.0/0 instead? if subnet_exist: fda['subnet'] = rdf_node.getS(ns_ui.subnet, rdf.IPv4Subnet) gw_node = rdf_node.getS(ns_ui.routeGateway) if gw_node.hasType(ns_ui.RouteGatewayNetworkDefault): fda['gateway_selection'] = 'nw_default_gw' elif gw_node.hasType(ns_ui.RouteGatewayManual): fda['gateway_selection'] = 'manual_gw' fda['gateway'] = gw_node.getS(ns_ui.ipAddress, rdf.IPv4Address) else: raise uidatahelpers.RdfDataError('Route\'s gateway is neither network default nor set gateway.') def _fill_additional_route_to_form(rdf_node, fda): _fill_route_to_form(rdf_node.getS(ns_ui.route), fda, True) def _fill_ppp_firewall_rule_to_form(rdf_node, fda): if rdf_node.hasS(ns_ui.ipAddress): # XXX: this is never encountered in practice? fda['ip_subnet'] = rdf_node.getS(ns_ui.ipAddress, rdf.IPv4Address) elif rdf_node.hasS(ns_ui.subnet): fda['ip_subnet'] = rdf_node.getS(ns_ui.subnet, rdf.IPv4Subnet) else: raise uidatahelpers.RdfDataError('Prohibited service ip/subnet is neither ipaddress nor subnet.') if rdf_node.hasS(ns_ui.protocol): fda['protocol'] = rdf_node.getS(ns_ui.protocol, rdf.String) else: fda['protocol'] = 'any' uidatahelpers.fill_optional_field_to_form(rdf_node, ns_ui.port, rdf.Integer, fda, 'port') fda['action'] = rdf_node.getS(ns_ui.action, rdf.String) ui_root = helpers.get_ui_config() # Default route _fill_route_to_form(ui_root.getS(ns_ui.defaultRoute), toplevel_fda.descend('dr_group'), False) # Additional routes add_route_fda = toplevel_fda.descend('ar_group') uidatahelpers.fill_dynamic_list_to_form(ui_root, ns_ui.routes, ns_ui.Route, add_route_fda, _fill_additional_route_to_form) # Source routing (forced routing) source_fda = toplevel_fda.descend('sr_group') if ui_root.hasS(ns_ui.sourceRouting): source_fda['source_routing_selection'] = 'on' _fill_route_to_form(ui_root.getS(ns_ui.sourceRouting), source_fda, False) else: source_fda['source_routing_selection'] = 'off' # PPP firewall rules fwrule_fda = toplevel_fda.descend('fwrule_group') uidatahelpers.fill_dynamic_list_to_form(ui_root, ns_ui.pppFirewallRules, ns_ui.PppFirewallRule, fwrule_fda, _fill_ppp_firewall_rule_to_form)
def _validate_users(self, ctx, form, data, userpw_dict): fda = formalutils.FormDataAccessor(form, ['userlist_group'], ctx) ui_root = helpers.get_ui_config() # user list validation idx = 0 users = [] while True: fda_user = fda.descend(str(idx)) if len(fda_user.keys()) == 0: break users.append(fda_user) idx += 1 s2s_server_usernames = [] if ui_root.hasS(ns_ui.siteToSiteConnections): for s2s_conn in ui_root.getS( ns_ui.siteToSiteConnections, rdf.Seq(rdf.Type(ns_ui.SiteToSiteConnection))): if s2s_conn.hasS(ns_ui.mode) and s2s_conn.getS( ns_ui.mode, rdf.String) == 'server' and s2s_conn.hasS( ns_ui.username): s2s_server_usernames.append( s2s_conn.getS(ns_ui.username, rdf.String)) usernames_found = [] fixed_ips_found = [] for fda_user_index, fda_user in enumerate(users): # username checks if fda_user.has_key('username'): if not uihelpers.check_ppp_username_characters( fda_user['username']): fda_user.add_error('username', 'Invalid characters') else: username = fda_user['username'] if username in usernames_found: fda_user.add_error('username', 'Duplicate username') elif username in s2s_server_usernames: fda_user.add_error( 'username', 'Duplicate username (already a site-to-site server-mode connection of that name)' ) elif len(username) > constants.MAX_USERNAME_LENGTH: fda_user.add_error('username', 'Username too long') else: usernames_found.append(username) # password chars if fda_user.has_key('password') and (fda_user['password'] is not None): if not uihelpers.check_ppp_password_characters( fda_user['password']): fda_user.add_error('password', 'Invalid characters') elif len(fda_user['password']) > constants.MAX_PASSWORD_LENGTH: fda_user.add_error('password', 'Password too long') # Password is a bit tricky; admin may have changed a username and we don't have # any permanent user identifiers that allow us to identify this as the same user # and keep its password despite the name change. So, we require either that the # password is set, or that a user previously existed with this username (changed # or not !) and use the old password. if fda_user.has_key('username') and (fda_user['username'] is not None) and \ (not fda_user.has_key('password') or fda_user['password'] is None or fda_user['password'] == ''): username = fda_user['username'] if userpw_dict.has_key(username): # all ok pass else: fda_user.add_error('password', 'Required for new users') # fixed ip checks # XXX: we could also check that the fixed IP is from the # PPP subnet to try to prevent admin configuration errors, # but this would be too restrictive and is currently not # done: a warning would help here. if fda_user.has_key('fixed_ip') and ( fda_user['fixed_ip'] is not None) and (fda_user['fixed_ip'] != ''): fixed_ip_errors = False fixed_ip = fda_user['fixed_ip'] iprange = ui_root.getS(ns_ui.clientAddressRange, rdf.IPv4AddressRange) pppsubnet = ui_root.getS(ns_ui.clientSubnet, rdf.IPv4Subnet) # The fixed IP may not overlap with other users fixed IP addresses if fixed_ip.toString() in fixed_ips_found: fda_user.add_error('fixed_ip', 'Duplicate fixed IP address') fixed_ip_errors = True # Check restricted addresses inside PPP subnet if pppsubnet.inSubnet(fixed_ip): # The fixed IP must not be from the PPP address range (dynamic allocation pool) if iprange.inRange(fixed_ip): fda_user.add_error( 'fixed_ip', 'Overlaps with client address range') fixed_ip_errors = True if fixed_ip < pppsubnet.getFirstUsableAddress(): fda_user.add_error( 'fixed_ip', 'First address of the client subnet prohibited') fixed_ip_errors = True elif fixed_ip == pppsubnet.getLastUsableAddress(): fda_user.add_error( 'fixed_ip', 'Last usable address of the client subnet prohibited' ) fixed_ip_errors = True elif fixed_ip > pppsubnet.getLastUsableAddress(): fda_user.add_error( 'fixed_ip', 'Last address of the client subnet prohibited') fixed_ip_errors = True if not fixed_ip_errors: fixed_ips_found.append(fixed_ip.toString())
def _do_mgmt_identify_args(self): root = self.rdf_root licinfo = self.rdf_root.getS(ns_ui.licenseInfo, rdf.Type(ns_ui.LicenseInfo)) uiconfig = self.rdf_root.getS(ns_ui.uiConfig, rdf.Type(ns_ui.UiConfig)) args = {} try: ui_root = helpers.get_ui_config() if ui_root.hasS(ns_ui.licenseKey) and ui_root.getS( ns_ui.licenseKey, rdf.String) != '': args['licenseKey'] = ui_root.getS(ns_ui.licenseKey, rdf.String) elif ui_root.hasS(ns_ui.testLicenseKey) and ui_root.getS( ns_ui.testLicenseKey, rdf.String) != '': args['licenseKey'] = ui_root.getS(ns_ui.testLicenseKey, rdf.String) else: raise Exception('no configured license') except: args['licenseKey'] = '' # anonymous try: t = helpers.get_boot_uuid() if t is None: args['bootUuid'] = '' else: args['bootUuid'] = t except: args['bootUuid'] = '' try: t = helpers.get_installation_uuid() if t is None: args['installationUuid'] = '' else: args['installationUuid'] = t except: args['installationUuid'] = '' try: t = helpers.get_cookie_uuid() if t is None: args['cookieUuid'] = '' else: args['cookieUuid'] = t except: args['cookieUuid'] = '' args['address'] = '0.0.0.0' # overridden by managementconnection args['port'] = 0 # overridden by managementconnection try: args['softwareVersion'] = helpers.get_product_version() except: args['softwareVersion'] = '' args['softwareBuildInfo'] = '' # XXX args['hardwareType'] = '' # XXX args['hardwareInfo'] = '' # XXX try: if self.force_update: args['automaticUpdates'] = True else: args['automaticUpdates'] = uiconfig.getS( ns_ui.automaticUpdates, rdf.Boolean) except: args['automaticUpdates'] = True try: args['isLiveCd'] = helpers.is_live_cd() except: args['isLiveCd'] = False return args
def renderHTTP(self, ctx): # XXX: refactor this to a helper?? def _xml_escape(x): return helpers.xml_escape(x) # XXX: simple base64 encoding does not seem to be enough def _base64_encode(x): # base64 produces a newline, strip it away; still not correct tho return x.encode('base64').strip() request = inevow.IRequest(ctx) # figure parameters server_address = '' try: server_address = str(request.getRequestHostname()) except: _log.exception('cannot figure out server_address') preshared_key = '' try: psk_seq = helpers.get_ui_config().getS(ns_ui.preSharedKeys, rdf.Seq(rdf.Type(ns_ui.PreSharedKey))) preshared_key = str(psk_seq[0].getS(ns_ui.preSharedKey, rdf.String)) except: _log.exception('cannot figure out preshared_key') username = '' try: tmp = self.get_logged_in_username() if tmp is not None: username = str(tmp) except: _log.exception('cannot figure out username') # Profile name profile_prefix = 'VPNease' try: if os.path.exists(constants.AUTOCONFIG_PROFILE_PREFIX_FILE): profile_prefix = helpers.read_and_strip_file(constants.AUTOCONFIG_PROFILE_PREFIX_FILE) except: _log.exception('failed when checking for alternative profile name') profile_name = '%s (%s)' % (profile_prefix, server_address) # Server behind port forward server_portfw = False try: global_st = helpers.get_global_status() if global_st.hasS(ns.behindNat): if global_st.getS(ns.behindNat, rdf.Boolean): server_portfw = True else: server_portfw = False else: # assume worst - reboot *MAY* be required server_portfw = True # markerfile for debugging if helpers.check_marker_file(constants.FORCE_NATTREBOOT_MARKERFILE): _log.warning('force nat-t reboot marker file exists, pretending server is behind port forward') server_portfw = True except: _log.exception('cannot determine whether server is behind port forward, may be OK') # # Notes about OSX plist for networkConnect # # * There are settings for PPP redial counts etc. We don't use them # because we want to minimize risks. # # * DisconnectOnXXX settings only seem to work when inside SystemConfig, # not inside UserConfigs. # # * SystemConfig -> IPv4 -> OverridePrimary=1 should, based on PPP code, # set 'default route' setting but doesn't seem to work. # # * UserConfigs -> IPsec -> ExportedSharedSecret contains the pre-shared # key for IKE in some sort of encrypted format. The value is base64 # encoded but the pre-shared key is processed (encrypted or masked) # prior to base64. Note that whatever the unknown (and seemingly # undocumented transform is, it has to be reversible because IKE needs # the PSK. # # * CCP / MPPC / MPPE are disabled now. They don't actually work in # Leopard at least. # # create xml plist textdata = textwrap.dedent("""\ <?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"> <plist version="1.0"> <dict> <key>L2TP</key> <dict> <key>SystemConfig</key> <dict> <key>PPP</key> <dict> <key>DisconnectOnSleep</key> <integer>1</integer> <key>DisconnectOnFastUserSwitch</key> <integer>1</integer> <key>DisconnectOnLogout</key> <integer>1</integer> </dict> </dict> <key>UserConfigs</key> <array> <dict> <key>EAP</key> <dict/> <key>IPSec</key> <dict> <key>AuthenticationMethod</key> <string>SharedSecret</string> <key>LocalIdentifier</key> <string></string> <key>LocalIdentifierType</key> <string>KeyID</string> </dict> <key>PPP</key> <dict> <key>AuthName</key> <string>%(username)s</string> <key>CommRemoteAddress</key> <string>%(server_address)s</string> <key>UserDefinedName</key> <string>%(profile_name)s</string> <key>CCPEnabled</key> <integer>%(ccp_enabled)d</integer> <key>CCPMPPE128Enabled</key> <integer>%(ccp_mppe40_enabled)d</integer> <key>CCPMPPE40Enabled</key> <integer>%(ccp_mppe128_enabled)d</integer> </dict> </dict> </array> </dict> </dict> </plist> """) % { 'preshared_key_base64': _xml_escape(_base64_encode(preshared_key)), 'username': _xml_escape(username), 'server_address': _xml_escape(server_address), 'profile_name': _xml_escape(profile_name), 'override_primary': 1, # XXX: force default route 'ccp_enabled': 0, 'ccp_mppe40_enabled': 0, 'ccp_mppe128_enabled': 0, } # # Content-Type is interesting. If this is served as 'text/xml', Safari # will display the file without offering a save option. Even if it is # saved, Safari will *refuse* saving the file with '.networkConnect' # extension. # # 'application/octet-stream' causes Safari to save the file, and use can # double click to run it. # return uihelpers.UncachedData(textdata, 'application/octet-stream')
def render_normal_page(self, ctx, data): ui_root = helpers.get_ui_config() if ui_root.hasS(ns_ui.welcomePageShown) and ui_root.getS(ns_ui.welcomePageShown, rdf.Boolean): return ctx.tag else: return ''
def render_welcome_rendered(self, ctx, data): ui_root = helpers.get_ui_config() ui_root.setS(ns_ui.welcomePageShown, rdf.Boolean, True) return ''
def renderHTTP(self, ctx): # XXX: refactor this to a helper?? def _xml_escape(x): return helpers.xml_escape(x) # XXX: simple base64 encoding does not seem to be enough def _base64_encode(x): # base64 produces a newline, strip it away; still not correct tho return x.encode('base64').strip() request = inevow.IRequest(ctx) # figure parameters server_address = '' try: server_address = str(request.getRequestHostname()) except: _log.exception('cannot figure out server_address') preshared_key = '' try: psk_seq = helpers.get_ui_config().getS( ns_ui.preSharedKeys, rdf.Seq(rdf.Type(ns_ui.PreSharedKey))) preshared_key = str(psk_seq[0].getS(ns_ui.preSharedKey, rdf.String)) except: _log.exception('cannot figure out preshared_key') username = '' try: tmp = self.get_logged_in_username() if tmp is not None: username = str(tmp) except: _log.exception('cannot figure out username') # Profile name profile_prefix = 'VPNease' try: if os.path.exists(constants.AUTOCONFIG_PROFILE_PREFIX_FILE): profile_prefix = helpers.read_and_strip_file( constants.AUTOCONFIG_PROFILE_PREFIX_FILE) except: _log.exception('failed when checking for alternative profile name') profile_name = '%s (%s)' % (profile_prefix, server_address) # Server behind port forward server_portfw = False try: global_st = helpers.get_global_status() if global_st.hasS(ns.behindNat): if global_st.getS(ns.behindNat, rdf.Boolean): server_portfw = True else: server_portfw = False else: # assume worst - reboot *MAY* be required server_portfw = True # markerfile for debugging if helpers.check_marker_file( constants.FORCE_NATTREBOOT_MARKERFILE): _log.warning( 'force nat-t reboot marker file exists, pretending server is behind port forward' ) server_portfw = True except: _log.exception( 'cannot determine whether server is behind port forward, may be OK' ) # # Notes about OSX plist for networkConnect # # * There are settings for PPP redial counts etc. We don't use them # because we want to minimize risks. # # * DisconnectOnXXX settings only seem to work when inside SystemConfig, # not inside UserConfigs. # # * SystemConfig -> IPv4 -> OverridePrimary=1 should, based on PPP code, # set 'default route' setting but doesn't seem to work. # # * UserConfigs -> IPsec -> ExportedSharedSecret contains the pre-shared # key for IKE in some sort of encrypted format. The value is base64 # encoded but the pre-shared key is processed (encrypted or masked) # prior to base64. Note that whatever the unknown (and seemingly # undocumented transform is, it has to be reversible because IKE needs # the PSK. # # * CCP / MPPC / MPPE are disabled now. They don't actually work in # Leopard at least. # # create xml plist textdata = textwrap.dedent("""\ <?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"> <plist version="1.0"> <dict> <key>L2TP</key> <dict> <key>SystemConfig</key> <dict> <key>PPP</key> <dict> <key>DisconnectOnSleep</key> <integer>1</integer> <key>DisconnectOnFastUserSwitch</key> <integer>1</integer> <key>DisconnectOnLogout</key> <integer>1</integer> </dict> </dict> <key>UserConfigs</key> <array> <dict> <key>EAP</key> <dict/> <key>IPSec</key> <dict> <key>AuthenticationMethod</key> <string>SharedSecret</string> <key>LocalIdentifier</key> <string></string> <key>LocalIdentifierType</key> <string>KeyID</string> </dict> <key>PPP</key> <dict> <key>AuthName</key> <string>%(username)s</string> <key>CommRemoteAddress</key> <string>%(server_address)s</string> <key>UserDefinedName</key> <string>%(profile_name)s</string> <key>CCPEnabled</key> <integer>%(ccp_enabled)d</integer> <key>CCPMPPE128Enabled</key> <integer>%(ccp_mppe40_enabled)d</integer> <key>CCPMPPE40Enabled</key> <integer>%(ccp_mppe128_enabled)d</integer> </dict> </dict> </array> </dict> </dict> </plist> """) % { 'preshared_key_base64': _xml_escape(_base64_encode(preshared_key)), 'username': _xml_escape(username), 'server_address': _xml_escape(server_address), 'profile_name': _xml_escape(profile_name), 'override_primary': 1, # XXX: force default route 'ccp_enabled': 0, 'ccp_mppe40_enabled': 0, 'ccp_mppe128_enabled': 0, } # # Content-Type is interesting. If this is served as 'text/xml', Safari # will display the file without offering a save option. Even if it is # saved, Safari will *refuse* saving the file with '.networkConnect' # extension. # # 'application/octet-stream' causes Safari to save the file, and use can # double click to run it. # return uihelpers.UncachedData(textdata, 'application/octet-stream')
def _validate(self, ctx, form, data): fda = formalutils.FormDataAccessor(form, ['s2s_connections'], ctx) # Get some useful stuff for validation ui_root = helpers.get_ui_config() pub_iface, pub_addr_subnet = None, None if ui_root.hasS(ns_ui.internetConnection): pub_iface = ui_root.getS(ns_ui.internetConnection, rdf.Type(ns_ui.NetworkConnection)) pub_addr = pub_iface.getS(ns_ui.address) if pub_addr.hasType(ns_ui.StaticAddress): pub_addr_subnet = datatypes.IPv4AddressSubnet.fromStrings(pub_addr.getS(ns_ui.ipAddress, rdf.IPv4Address).toString(), pub_addr.getS(ns_ui.subnetMask, rdf.IPv4Address).toString()) priv_iface, priv_addr_subnet = None, None if ui_root.hasS(ns_ui.privateNetworkConnection): priv_iface = ui_root.getS(ns_ui.privateNetworkConnection, rdf.Type(ns_ui.NetworkConnection)) priv_addr = priv_iface.getS(ns_ui.address) if priv_addr.hasType(ns_ui.StaticAddress): priv_addr_subnet = datatypes.IPv4AddressSubnet.fromStrings(priv_addr.getS(ns_ui.ipAddress, rdf.IPv4Address).toString(), priv_addr.getS(ns_ui.subnetMask, rdf.IPv4Address).toString()) ppp_subnet = None if ui_root.hasS(ns_ui.clientSubnet): ppp_subnet = ui_root.getS(ns_ui.clientSubnet, rdf.IPv4Subnet) # Validate individual site-to-site connections idx = 0 conns = [] while True: fda_conn = fda.descend(str(idx)) if len(fda_conn.keys()) == 0: break conns.append(fda_conn) idx += 1 remote_access_usernames = [] if ui_root.hasS(ns_ui.users): for user in ui_root.getS(ns_ui.users, rdf.Seq(rdf.Type(ns_ui.User))): if user.hasS(ns_ui.username): remote_access_usernames.append(user.getS(ns_ui.username, rdf.String)) s2s_server_usernames_found = [] for fda_conn_index, fda_conn in enumerate(conns): if fda_conn.has_key('s2s_username'): if not uihelpers.check_ppp_username_characters(fda_conn['s2s_username']): fda_conn.add_error('s2s_username', 'Invalid characters') elif len(fda_conn['s2s_username']) > constants.MAX_USERNAME_LENGTH: fda_conn.add_error('s2s_username', 'Username too long') if fda_conn.has_key('s2s_password'): if not uihelpers.check_ppp_password_characters(fda_conn['s2s_password']): fda_conn.add_error('s2s_password', 'Invalid characters') elif len(fda_conn['s2s_password']) > constants.MAX_PASSWORD_LENGTH: fda_conn.add_error('s2s_password', 'Password too long') if fda_conn.has_key('s2s_mode'): mode = fda_conn['s2s_mode'] if mode == 'client': # psk and server address are mandatory for client if not fda_conn.has_key('s2s_psk') or fda_conn['s2s_psk'] == '' or fda_conn['s2s_psk'] is None: fda_conn.add_error('s2s_psk', 'Required for initiator') else: if not uihelpers.check_preshared_key_characters(fda_conn['s2s_psk']): fda_conn.add_error('s2s_psk', 'Invalid characters') if not fda_conn.has_key('s2s_server') or fda_conn['s2s_server'] == '' or fda_conn['s2s_server'] is None: fda_conn.add_error('s2s_server', 'Required for initiator') else: if not uihelpers.check_dns_name_characters(fda_conn['s2s_server']): fda_conn.add_error('s2s_server', 'Invalid characters') else: # server # must not have duplicate server-mode names; client mode names may be duplicates if fda_conn.has_key('s2s_username'): username = fda_conn['s2s_username'] if username in s2s_server_usernames_found: fda_conn.add_error('s2s_username', 'Duplicate username for server mode connection') elif username in remote_access_usernames: fda_conn.add_error('s2s_username', 'Duplicate username for server mode connection (already a user with that name)') else: s2s_server_usernames_found.append(fda_conn['s2s_username']) # check subnets if fda_conn.has_key('s2s_subnets'): subnets = fda_conn['s2s_subnets'] # check that list doesn't contain overlap inside itself overlap_inside_list = False for i in xrange(len(subnets)): for j in xrange(len(subnets)): if i != j: if subnets[i].overlapsWithSubnet(subnets[j]): overlap_inside_list = True if overlap_inside_list: fda_conn.add_warning('s2s_subnets', 'Subnets in list overlap') # check that no element of list overlaps with any other subnet of any other site-to-site connection overlap_with_other = False for subnet in subnets: for other_conn_index, other_conn in enumerate(conns): if other_conn.has_key('s2s_subnets') and other_conn_index != fda_conn_index: for other_subnet in other_conn['s2s_subnets']: if subnet.overlapsWithSubnet(other_subnet): overlap_with_other = True if overlap_with_other: fda_conn.add_warning('s2s_subnets', 'Remote subnet(s) overlap with other connections') # check overlap against public interface if pub_addr_subnet is not None: if subnet.overlapsWithSubnet(pub_addr_subnet.getSubnet()): fda_conn.add_warning('s2s_subnets', 'Remote subnet(s) overlap with Internet connection subnet') # check overlap against private interface if priv_addr_subnet is not None: if subnet.overlapsWithSubnet(priv_addr_subnet.getSubnet()): fda_conn.add_warning('s2s_subnets', 'Remote subnet(s) overlap with private network connection subnet') # check overlap against ppp subnet if ppp_subnet is not None: if subnet.overlapsWithSubnet(ppp_subnet): fda_conn.add_warning('s2s_subnets', 'Remote subnet(s) overlap with client subnet')