def save_client_connection_data(self, ctx, form, data): cc_fda = formalutils.FormDataAccessor(form, ['client_connection'], ctx) ui_root = helpers.get_new_ui_config() # Server address & psk if cc_fda.has_key('server_name') and cc_fda['server_name'] is not None: ui_root.setS(ns_ui.vpnServerAddress, rdf.String, cc_fda['server_name']) else: ui_root.setS(ns_ui.vpnServerAddress, rdf.String, '') psk_seq = ui_root.setS(ns_ui.preSharedKeys, rdf.Seq(rdf.Type(ns_ui.PreSharedKey))) if cc_fda.has_key('psk_1') and (cc_fda['psk_1'] != '') and (cc_fda['psk_1'] is not None): psk = psk_seq.new() psk.setS(ns_ui.preSharedKey, rdf.String, cc_fda['psk_1']) if cc_fda.has_key('psk_2') and (cc_fda['psk_2'] != '') and (cc_fda['psk_2'] is not None): psk = psk_seq.new() psk.setS(ns_ui.preSharedKey, rdf.String, cc_fda['psk_2']) # DNS if cc_fda['dns'] == 'use_ic_dns': ui_root.setS(ns_ui.clientDnsServers, rdf.Type(ns_ui.NetworkConnectionDns)) elif cc_fda['dns'] == 'manual_dns': dns_root = ui_root.setS(ns_ui.clientDnsServers, rdf.Type(ns_ui.SetDnsServers)) uidatahelpers.save_optional_field_to_rdf(dns_root, ns_ui.primaryDns, rdf.IPv4Address, cc_fda, 'dns_1') uidatahelpers.save_optional_field_to_rdf(dns_root, ns_ui.secondaryDns, rdf.IPv4Address, cc_fda, 'dns_2') else: raise uidatahelpers.FormDataError( 'Client connection dns is neither network dns nor set dns.') # WINS # Note: parent node is ui-root, which may already have a value from old config, use empty default # value to remove old data in case form value is missing. uidatahelpers.save_optional_field_to_rdf(ui_root, ns_ui.clientPrimaryWins, rdf.IPv4Address, cc_fda, 'wins_1', default=None) uidatahelpers.save_optional_field_to_rdf(ui_root, ns_ui.clientSecondaryWins, rdf.IPv4Address, cc_fda, 'wins_2', default=None) ui_root.setS(ns_ui.clientSubnet, rdf.IPv4Subnet, cc_fda['client_subnet']) ui_root.setS(ns_ui.clientAddressRange, rdf.IPv4AddressRange, cc_fda['client_address_range']) ui_root.setS(ns_ui.clientCompression, rdf.Boolean, cc_fda['client_compression'])
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 _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_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 create_config_pluto(self, cfg, resinfo, extra_psks=[]): def _psk_sanity_check(pskbin): for i in xrange( len(pskbin)): # basic sanity check - XXX: insufficient c = ord(pskbin[i]) if (c <= 0x20) or (c > 0x7e): raise Exception('PSK contains invalid character(s)') ipsec_cfg = cfg.getS(ns.ipsecConfig, rdf.Type(ns.IpsecConfig)) ike_lifetime = ipsec_cfg.getS(ns.ikeLifeTime, rdf.Timedelta).seconds ipsec_lifetime = ipsec_cfg.getS(ns.ipsecLifeTime, rdf.Timedelta).seconds self.debug_on = helpers.get_debug(cfg) self.debug_heavy = helpers.get_debug_heavy(cfg) self.ip = resinfo.public_interface.address.getAddress().toString() self.ike_lifetime = str(ike_lifetime) self.ipsec_lifetime = str(ipsec_lifetime) ownaddr = resinfo.public_interface.address.getAddress().toString() psks = ipsec_cfg.getS(ns.preSharedKeys, rdf.Seq(rdf.Type(ns.PreSharedKey))) # log unusual psk amounts (0, >1) if len(psks) == 0: self._log.warning('zero psks') elif len(psks) > 1: self._log.info('more than one psk (%s)' % len(psks)) else: self._log.debug('one psk, good') pskfile = '' def _encode_hex(s): r = '0x' for i in s: r += '%02x' % ord(i) return r # start with specific "extra_psks" for [addr, pskbin] in extra_psks: # XXX: no sanity check because using hex encoding # _psk_sanity_check(pskbin) pskfile += '%s : PSK %s\n' % (addr, _encode_hex(pskbin)) # end with generic psks for psk in psks: pskbin = psk.getS(ns.preSharedKey, rdf.Binary) # XXX: no sanity check because using hex encoding # _psk_sanity_check(pskbin) pskfile += ': PSK %s\n' % _encode_hex(pskbin) self.configs = [{ 'file': constants.PLUTO_CONF, 'cont': pskfile, 'mode': 0600 }]
def _resolve_dns_servers(self, cfg, pub, priv): """Determine DNS server list by resolving configured and DHCP-obtained value.""" (pub_if, pub_if_name), (priv_if, priv_if_name) = helpers.get_ifaces(cfg) net_cfg = cfg.getS(ns.networkConfig, rdf.Type(ns.NetworkConfig)) dns = net_cfg.getS(ns.dnsServers) if dns.hasType(ns.StaticDnsServers): _log.debug('dns servers from configured data') dns_servers = [] for i in dns.getS(ns.addressList, rdf.Seq(rdf.Type(ns.DnsServer))): srv = ResolvedDnsServer() srv.address = i.getS(ns.address, rdf.IPv4Address) srv.rdf_server_list = dns srv.from_dhcp = False srv.from_dhcp_rdf_interface = None dns_servers.append(srv) return dns_servers elif dns.hasType(ns.DhcpDnsServers): iface = dns.getS(ns.interface, rdf.Type(ns.NetworkInterface)) if iface == pub_if: _log.debug('dns servers from dhcp public') if pub is not None: dns_servers = [] for i in pub.dns_servers: srv = ResolvedDnsServer() srv.address = i # IPv4Address srv.rdf_server_list = dns srv.from_dhcp = True srv.from_dhcp_rdf_interface = pub_if dns_servers.append(srv) return dns_servers else: return [] elif iface == priv_if: _log.debug('dns servers from dhcp private') if priv is not None: dns_servers = [] for i in priv.dns_servers: srv = ResolvedDnsServer() srv.address = i # IPv4Address srv.rdf_server_list = dns srv.from_dhcp = True srv.from_dhcp_rdf_interface = priv_if dns_servers.append(srv) return dns_servers else: return [] else: raise Exception('unknown interface in dnsServers') else: raise Exception('unknown dnsServers variant') raise Exception('internal error - unexpected exit from function')
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 resolve(self, cfg, pub_dhcpaddrinfo, priv_dhcpaddrinfo): net_cfg = cfg.getS(ns.networkConfig, rdf.Type(ns.NetworkConfig)) (pub_iface, pub_iface_name), (priv_iface, priv_iface_name) = helpers.get_ifaces(cfg) self._pub_addrinfo = pub_dhcpaddrinfo self._priv_addrinfo = priv_dhcpaddrinfo pub_addr, priv_addr = self._resolve_addresses(cfg, pub_dhcpaddrinfo, priv_dhcpaddrinfo) if pub_iface is not None: self.public_interface = ResolvedInterface() self.public_interface.address = pub_addr self.public_interface.device = pub_iface_name self.public_interface.rdf_interface = pub_iface if priv_iface is not None: self.private_interface = ResolvedInterface() self.private_interface.address = priv_addr self.private_interface.device = priv_iface_name self.private_interface.rdf_interface = priv_iface self.dns_servers = self._resolve_dns_servers(cfg, pub_dhcpaddrinfo, priv_dhcpaddrinfo) self.gateway_routes = self._resolve_routes( cfg, pub_dhcpaddrinfo, priv_dhcpaddrinfo, net_cfg.getS(ns.gatewayRoutes, rdf.Seq(rdf.Type(ns.Route)))) self.client_routes = self._resolve_routes( cfg, pub_dhcpaddrinfo, priv_dhcpaddrinfo, net_cfg.getS(ns.clientRoutes, rdf.Seq(rdf.Type(ns.Route)))) self.ppp_dns_servers, self.ppp_wins_servers = self._resolve_ppp_dns_wins_servers( cfg, pub_dhcpaddrinfo, priv_dhcpaddrinfo) self.ppp_forced_router = self._resolve_ppp_forced_router( cfg, pub_dhcpaddrinfo, priv_dhcpaddrinfo) # XXX: post checks? if len(self.dns_servers) == 0: # XXX: this should be converted to a more useful exception # XXX: for a 'lenient' startup (e.g. for sending e-mail to fixed IP address SMTP server) # this check is too strict raise Exception('no dns servers')
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_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 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 _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_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_radius_parameters(self, cfg): proxy = False servers = [] nas_id = None rad_cfg = cfg.getS(ns.radiusConfig) if rad_cfg.hasS(ns.radiusNasIdentifier): n = rad_cfg.getS(ns.radiusNasIdentifier, rdf.String) if (n is not None) and (n != ''): nas_id = n if not rad_cfg.hasS(ns.radiusServers): return proxy, nas_id, servers for server in rad_cfg.getS(ns.radiusServers, rdf.Seq(rdf.Resource)): addr = server.getS(ns.address, rdf.String) port = server.getS(ns.port, rdf.Integer) secret = server.getS(ns.secret, rdf.String) if addr is not None and addr != '' and port is not None and int(port) > 0 and secret is not None and secret != '': servers.append([addr, int(port), secret]) proxy = True return proxy, nas_id, servers
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')
def up_firewall_rules(self, cfg, pub_addr, priv_addr, ppp_forced_iface, ppp_forced_gw): """Configure and enable firewall rules.""" _log.debug('up_firewall_rules') # ROUTE support through modprobe test retval, stdout, stderr = run_command( [constants.CMD_MODPROBE, 'ipt_ROUTE']) route_target_supported = False if retval == 0: route_target_supported = True _log.info('ROUTE target support detected') else: _log.warning('ROUTE target support NOT detected') net_cfg = cfg.getS(ns.networkConfig, rdf.Type(ns.NetworkConfig)) fw_cfg = net_cfg.getS(ns.firewallConfig, rdf.Type(ns.FirewallConfig)) (pub_iface, pub_iface_name), (priv_iface, priv_iface_name) = helpers.get_ifaces(cfg) (_, proxyarp_interface) = helpers.get_proxyarp_iface(cfg) pub_nat = helpers.is_public_nat(cfg) priv_nat = helpers.is_private_nat(cfg) # XXX: this could be in firewall rules cli_routing = helpers.is_client_routing(cfg) pub_addr_str = None if pub_addr is not None: pub_addr_str = pub_addr.getAddress().toString() priv_addr_str = None if priv_addr is not None: priv_addr_str = priv_addr.getAddress().toString() if_dict = { 'pub_if': pub_iface_name, 'priv_if': priv_iface_name, 'ppp_if': ppp_interfaces, 'pub_ip': pub_addr_str, 'priv_ip': priv_addr_str, 'fwmark_ipsec': constants.FWMARK_IPSEC, 'fwmark_skipnat': constants.FWMARK_SKIPNAT, 'fwmark_ppp': constants.FWMARK_PPP, 'fwmark_ppp_s2s': constants.FWMARK_PPP_S2S, 'fwmark_local_l2tp': constants.FWMARK_LOCAL_L2TP, 'fwmark_license_restricted': constants.FWMARK_LICENSE_RESTRICTED, 'http_fwd1': constants.WEBUI_FORWARD_PORT_UIFORCED_HTTP, 'https_fwd1': constants.WEBUI_FORWARD_PORT_UIFORCED_HTTPS, 'http_fwd2': constants.WEBUI_FORWARD_PORT_LICENSE_HTTP, 'https_fwd2': constants.WEBUI_FORWARD_PORT_LICENSE_HTTPS, 'http_fwd3': constants.WEBUI_FORWARD_PORT_OLDPSK_HTTP, 'https_fwd3': constants.WEBUI_FORWARD_PORT_OLDPSK_HTTPS, } # # rules for -t raw # raw_rules = textwrap.dedent("""\ -A raw_prerouting -i %(ppp_if)s -j raw_prerouting_ppp -A raw_output -o %(ppp_if)s -j raw_output_ppp """) % if_dict # # rules for -t nat # nat_rules = textwrap.dedent("""\ -A nat_prerouting -i %(ppp_if)s -j nat_prerouting_ppp -A nat_postrouting -o %(ppp_if)s -j nat_postrouting_ppp -A nat_output -o %(ppp_if)s -j nat_output_ppp """) % if_dict pf_cfg = fw_cfg.getS(ns.portForward, rdf.Seq(rdf.Type(ns.PortForwardRule))) for i in pf_cfg: iface = i.getS(ns.interface, rdf.Type(ns.NetworkInterface)).getS( ns.interfaceName, rdf.String) proto = str(i.getS(ns.protocol, rdf.Integer)) port = str(i.getS(ns.port, rdf.Integer)) daddr = i.getS(ns.destinationAddress, rdf.IPv4Address).toString() dport = str(i.getS(ns.destinationPort, rdf.Integer)) nat_rules += textwrap.dedent("""\ -A nat_prerouting -i %(iface)s -p %(proto)s --dport %(port)s -j DNAT --to-destination %(daddr)s:%(dport)s-%(dport)s """) % { 'iface': iface, 'proto': proto, 'port': port, 'daddr': daddr, 'dport': dport } # nat all traffic (both ppp and other), because we support routing of non-client traffic if pub_nat: # These bizarre rules are used to prevent clients which use our gateway as a router/NAT # from accidentally getting an unmodified UDP port when they are using IPsec. This would # be hazardous to IKE because our IKE already uses UDP/500 and UDP/4500 (but may not be # running due to a startup race when the client connects). # # The ports are pretty arbitrary; Linux maps >= 1024 starting from 1024; we choose to # start higher to make it easier to track NATted and other ports (and also so that all # ports we use, namely 500, 4500, 1701, 1702, etc) are below the start point). # # Mark 2 is used as a "skip NAT" marker: we can add this mark to e.g. site-to-site packets # to avoid NAT for them if we wish. # # We use a two-chain workaround here to implement NAT: our NAT rule must have a match # "not public address AND not private address", but iptables does not support multiple # -s matches in the same rule. So, packets are only NATted if they satisfy: # 1. Source address != public address # 2. Source address != private address # 3. Packet is not marked as "skip NAT" # # We need to exclude private interface address (from public NAT) to avoid NATting # IPsec packets when they are used through the private interface. nat_rules += textwrap.dedent("""\ -A nat_postrouting -o %(pub_if)s ! -s %(pub_ip)s -m mark --mark 0/%(fwmark_skipnat)s -j nat_pub1 """) % if_dict if priv_iface is not None: nat_rules += textwrap.dedent("""\ -A nat_pub1 ! -s %(priv_ip)s -j nat_pub2 """) % if_dict else: nat_rules += textwrap.dedent("""\ -A nat_pub1 -j nat_pub2 """) % if_dict nat_rules += textwrap.dedent("""\ -A nat_pub2 -p tcp -j SNAT --to-source %(pub_ip)s:16384-49151 -A nat_pub2 -p udp -j SNAT --to-source %(pub_ip)s:16384-49151 -A nat_pub2 -j SNAT --to-source %(pub_ip)s """) % if_dict if priv_nat: nat_rules += textwrap.dedent("""\ -A nat_postrouting -o %(priv_if)s ! -s %(priv_ip)s -m mark --mark 0/%(fwmark_skipnat)s -j nat_priv1 """) % if_dict if pub_iface is not None: nat_rules += textwrap.dedent("""\ -A nat_priv1 ! -s %(pub_ip)s -j nat_priv2 """) % if_dict else: nat_rules += textwrap.dedent("""\ -A nat_priv1 -j nat_priv2 """) % if_dict nat_rules += textwrap.dedent("""\ -A nat_priv2 -p tcp -j SNAT --to-source %(priv_ip)s:16384-49151 -A nat_priv2 -p udp -j SNAT --to-source %(priv_ip)s:16384-49151 -A nat_priv2 -j SNAT --to-source %(priv_ip)s """) % if_dict # # rules for -t mangle # mangle_rules = textwrap.dedent("""\ -A mangle_prerouting -i %(ppp_if)s -j MARK --set-mark %(fwmark_ppp)s -A mangle_prerouting -i %(ppp_if)s -j mangle_prerouting_ppp -A mangle_prerouting -p esp -j MARK --set-mark %(fwmark_ipsec)s -A mangle_prerouting -p udp --dport 500 -j MARK --set-mark %(fwmark_ipsec)s -A mangle_prerouting -p udp --dport 4500 -j MARK --set-mark %(fwmark_ipsec)s -A mangle_input -i %(ppp_if)s -j mangle_input_ppp -A mangle_forward -p tcp --tcp-flags SYN,RST SYN -j TCPMSS --clamp-mss-to-pmtu -A mangle_forward -i %(ppp_if)s -j mangle_forward_ppp -A mangle_forward -o %(ppp_if)s -j mangle_forward_ppp -A mangle_output -o %(ppp_if)s -j mangle_output_ppp # Not necessary, openl2tp patch #-A mangle_output -p udp --sport 1701 -j MARK --set-mark %(fwmark_local_l2tp)s #-A mangle_output -p udp --sport 1702 -j MARK --set-mark %(fwmark_local_l2tp)s -A mangle_postrouting -o %(ppp_if)s -j mangle_postrouting_ppp """) % if_dict if (ppp_forced_iface is not None) and (ppp_forced_gw is not None): if route_target_supported: _log.info('forced routing enabled: %s / %s' % (ppp_forced_iface, ppp_forced_gw.toString())) # forced routing is applied but only if packets are not license restricted mangle_rules += '\n' mangle_rules += ('-A mangle_prerouting -m mark --mark 0/%(fwmark_license_restricted)s -i %(ppp_if)s -j ROUTE' % if_dict) + \ (' --oif %s --gw %s\n' % (ppp_forced_iface, ppp_forced_gw.toString())) else: _log.error( 'forced routing enabled but route target not supported!') # # rules for -t filter (we accept esp, udp/500, udp/4500 from any interface) # filter_rules = textwrap.dedent("""\ -A filter_input -i lo -j ACCEPT -A filter_input -m state --state ESTABLISHED,RELATED -j ACCEPT -A filter_input -i %(ppp_if)s -j filter_input_ppp # esp protected traffic (= l2tp) or IKE -A filter_input -m mark --mark %(fwmark_ipsec)s/%(fwmark_ipsec)s -j ACCEPT # rate limited public icmp -A filter_input -i %(pub_if)s -p icmp -m limit --limit 10/second --limit-burst 50 -j ACCEPT -A filter_input -i %(pub_if)s -p icmp -j DROP -A filter_input -i %(ppp_if)s -p icmp -j ACCEPT # all web ui ports -A filter_input -i %(ppp_if)s -p tcp --dport 80 -j ACCEPT -A filter_input -i %(ppp_if)s -p tcp --dport 443 -j ACCEPT -A filter_input -i %(ppp_if)s -p tcp --dport %(http_fwd1)d -j ACCEPT -A filter_input -i %(ppp_if)s -p tcp --dport %(https_fwd1)d -j ACCEPT -A filter_input -i %(ppp_if)s -p tcp --dport %(http_fwd2)d -j ACCEPT -A filter_input -i %(ppp_if)s -p tcp --dport %(https_fwd2)d -j ACCEPT -A filter_input -i %(ppp_if)s -p tcp --dport %(http_fwd3)d -j ACCEPT -A filter_input -i %(ppp_if)s -p tcp --dport %(https_fwd3)d -j ACCEPT """) % if_dict if priv_iface is not None: # Note: we assume that private interface is always different # from public interface if it is defined at all. filter_rules += textwrap.dedent("""\ -A filter_input -i %(priv_if)s -p icmp -m limit --limit 10/second --limit-burst 50 -j ACCEPT -A filter_input -i %(priv_if)s -p icmp -j DROP """) % if_dict ia_cfg = fw_cfg.getS(ns.inputAccept, rdf.Seq(rdf.Type(ns.InputAcceptRule))) for i in ia_cfg: iface = i.getS(ns.interface, rdf.Type(ns.NetworkInterface)).getS( ns.interfaceName, rdf.String()) proto = str(i.getS(ns.protocol, rdf.Integer)) port = str(i.getS(ns.port, rdf.Integer)) filter_rules += textwrap.dedent("""\ -A filter_input -i %(iface)s -p %(proto)s --dport %(port)s -j ACCEPT """) % { 'iface': iface, 'proto': proto, 'port': port } filter_rules += textwrap.dedent("""\ -A filter_output -o %(ppp_if)s -j filter_output_ppp -A filter_output -o %(ppp_if)s -j ACCEPT -A filter_output -j ACCEPT """) % if_dict ppp_firewall_rules = '' if fw_cfg.hasS(ns.pppFirewallRules): fr_cfg = fw_cfg.getS(ns.pppFirewallRules, rdf.Seq(rdf.Type(ns.PppFirewallRule))) else: fr_cfg = [] for i in fr_cfg: dest = '-d ' + i.getS(ns.subnet, rdf.IPv4Subnet).toString() if i.hasS(ns.protocol): proto = '-p ' + str(i.getS(ns.protocol, rdf.Integer)) if i.hasS(ns.port): port = '--dport ' + str(i.getS(ns.port, rdf.Integer)) else: port = '' else: proto = '' port = '' fr_action = i.getS(ns.action) if fr_action.hasType(ns.ActionAllow): action = 'ACCEPT' elif fr_action.hasType(ns.ActionDeny): action = 'REJECT --reject-with icmp-port-unreachable' else: raise Exception('invalid firewall action') ppp_firewall_rules += textwrap.dedent("""\ -A filter_forward_ppp_firewall %(dest)s %(proto)s %(port)s -j %(action)s """) % { 'dest': dest, 'proto': proto, 'port': port, 'action': action } # XXX: conn track? (e.g. pub->ppp ?) filter_rules += textwrap.dedent("""\ -A filter_forward -m conntrack --ctstate DNAT -j ACCEPT -A filter_forward -m state --state ESTABLISHED,RELATED -j ACCEPT """) % if_dict # client-to-client routing: note that we need to separate between # true client-to-client and site-to-site related routing if cli_routing: _log.info('client-to-client routing allowed, no rule added') else: # XXX -- This doesn't work (see #828) for client-to-s2s packets. # Currently never used. # match ppp -> ppp packets with *no* s2s mark _log.info( 'client-to-client routing not allowed, adding firewall rule to prevent' ) _log.error( 'client-to-client routing not allowed -- but unsupported in this build' ) filter_rules += textwrap.dedent("""\ -A filter_forward -i %(ppp_if)s -o %(ppp_if)s -m mark --mark 0/%(fwmark_ppp_s2s)s -j DROP """) % if_dict # ppp forwarding rules are only applied if traffic is not blocked # by client-to-client restrictions above filter_rules += textwrap.dedent("""\ -A filter_forward -i %(ppp_if)s -j filter_forward_ppp -A filter_forward -o %(ppp_if)s -j filter_forward_ppp -A filter_forward -i %(ppp_if)s -o %(pub_if)s -j ACCEPT -A filter_forward -i %(pub_if)s -o %(ppp_if)s -j ACCEPT -A filter_forward -i %(ppp_if)s -o %(ppp_if)s -j ACCEPT """) % if_dict # non-client routing if priv_iface is not None: if fw_cfg.getS(ns.allowNonClientRouting, rdf.Boolean): filter_rules += textwrap.dedent("""\ -A filter_forward -i %(pub_if)s -o %(pub_if)s -j ACCEPT -A filter_forward -i %(priv_if)s -o %(priv_if)s -j ACCEPT -A filter_forward -i %(priv_if)s -o %(pub_if)s -j ACCEPT """) % if_dict else: if fw_cfg.getS(ns.allowNonClientRouting, rdf.Boolean): filter_rules += textwrap.dedent("""\ -A filter_forward -i %(pub_if)s -o %(pub_if)s -j ACCEPT """) % if_dict if priv_iface is not None: filter_rules += textwrap.dedent("""\ -A filter_forward -i %(ppp_if)s -o %(priv_if)s -j ACCEPT -A filter_forward -i %(priv_if)s -o %(ppp_if)s -j ACCEPT """) % if_dict # # finally, build the tables # tables = textwrap.dedent("""\ # Iptables restore script *raw :PREROUTING ACCEPT :OUTPUT ACCEPT :raw_prerouting - :raw_output - :raw_prerouting_ppp - :raw_output_ppp - :raw_prerouting_ppp_cust - :raw_output_ppp_cust - -A PREROUTING -j raw_prerouting -A OUTPUT -j raw_output %(raw_rules)s COMMIT *filter :INPUT DROP :FORWARD DROP :OUTPUT DROP :filter_input - :filter_forward - :filter_forward_ppp_firewall - :filter_output - :filter_input_ppp - :filter_forward_ppp - :filter_output_ppp - :filter_input_ppp_cust - :filter_forward_ppp_cust - :filter_output_ppp_cust - -A INPUT -j filter_input -A FORWARD -j filter_forward -A OUTPUT -j filter_output %(filter_rules)s %(ppp_firewall_rules)s COMMIT *nat :PREROUTING ACCEPT :POSTROUTING ACCEPT :OUTPUT ACCEPT :nat_prerouting - :nat_postrouting - :nat_output - :nat_prerouting_ppp - :nat_postrouting_ppp - :nat_output_ppp - :nat_prerouting_ppp_cust - :nat_postrouting_ppp_cust - :nat_output_ppp_cust - # chains for public/private natting, see above :nat_pub1 - :nat_pub2 - :nat_priv1 - :nat_priv2 - -A PREROUTING -j nat_prerouting -A POSTROUTING -j nat_postrouting -A OUTPUT -j nat_output %(nat_rules)s COMMIT *mangle :PREROUTING ACCEPT :INPUT ACCEPT :FORWARD ACCEPT :OUTPUT ACCEPT :POSTROUTING ACCEPT :mangle_prerouting - :mangle_input - :mangle_forward - :mangle_output - :mangle_postrouting - :mangle_prerouting_ppp - :mangle_input_ppp - :mangle_forward_ppp - :mangle_output_ppp - :mangle_postrouting_ppp - :mangle_prerouting_ppp_cust - :mangle_input_ppp_cust - :mangle_forward_ppp_cust - :mangle_output_ppp_cust - :mangle_postrouting_ppp_cust - -A PREROUTING -j mangle_prerouting -A INPUT -j mangle_input -A FORWARD -j mangle_forward -A OUTPUT -j mangle_output -A POSTROUTING -j mangle_postrouting %(mangle_rules)s COMMIT # end of script. """) % { 'raw_rules': raw_rules, 'filter_rules': filter_rules, 'nat_rules': nat_rules, 'mangle_rules': mangle_rules, 'ppp_firewall_rules': ppp_firewall_rules } _log.debug('iptables-restore script dump:') for i, l in enumerate(tables.split('\n')): _log.debug('%d: %s' % (i + 1, l)) (retval, retout, reterr) = run_command([constants.CMD_IPTABLES_RESTORE], stdin=tables.encode('ascii'), retval=runcommand.FAIL) _log.debug('iptables-restore => %s\n%s\n%s' % (retval, retout, reterr))
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 renderHTTP(self, ctx): request = inevow.IRequest(ctx) # read unpatched exe f = None exedata = '' try: f = open(self.autoconfig_exe_filename, 'rb') exedata = f.read() finally: if f is not None: f.close() f = None # figure parameters server_address_in_uri = None try: server_address_in_uri = str(request.getRequestHostname()) except: _log.exception('cannot figure out server_address_in_uri') server_ip = None try: server_ip = self._get_server_ip_for_win2k(ctx) except: _log.exception('cannot figure out server_ip') server_address = None if self.force_server_address_to_ip: server_address = server_ip else: server_address = server_address_in_uri if (server_address_in_uri is None) or (server_address_in_uri == ''): raise Exception('server_address_in_uri missing, failing') if (server_address is None) or (server_address == ''): raise Exception('server_address missing, failing') if self.include_win2k_regdata and ((server_ip is None) or (server_ip == '')): raise Exception('server_ip is needed and missing, failing') 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, always uses address in URI, even if server address itself forced to IP 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_in_uri) # 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') # Windows 2000 registry-based IPsec policy + prohibitIpsec win2k_ipsec_policy_registry_file = '' try: if self.include_win2k_regdata: # Registry data is HEX encoded UTF-16; HEX encoding is used to avoid problems # with the parameters.cpp mechanism (null termination). The resulting data is # large, around 50 kilobytes (!). # Always uses server IP for IPsec policy, because that's what Windows 2000 IPsec wants t = self._get_win2k_reg_file(server_ip, preshared_key) t = self._encode_windows_reg_file(t) # UTF-16 win2k_ipsec_policy_registry_file = t.encode('hex') # hex-encoded UTF-16 except: _log.exception('cannot create win2k registry file') # Fill paramdict and return paramdict = {} paramdict['operation'] = 'configure_profile' paramdict['profile_name'] = profile_name paramdict['desktop_shortcut_name'] = '%s.LNK' % profile_name # xxx: for now the same paramdict['server_address'] = server_address paramdict['preshared_key'] = preshared_key paramdict['username'] = username paramdict['ppp_compression_enabled'] = '1' paramdict['default_route_enabled'] = '1' paramdict['create_desktop_shortcut'] = '1' paramdict['open_profile_after_creation'] = '1' if server_portfw: paramdict['server_behind_port_forward'] = '1' else: paramdict['server_behind_port_forward'] = '0' if self.include_win2k_regdata: paramdict['win2k_registry_file'] = win2k_ipsec_policy_registry_file return uihelpers.RewritingBinaryResource(exedata, paramdict)
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 _resolve_ppp_dns_wins_servers(self, cfg, pub_addrinfo, priv_addrinfo): (pub_if, pub_if_name), (priv_if, priv_if_name) = helpers.get_ifaces(cfg) ppp_cfg = cfg.getS(ns.pppConfig, rdf.Type(ns.PppConfig)) # dns servers if ppp_cfg.hasS(ns.pppDnsServers): dns_cfg = ppp_cfg.getS(ns.pppDnsServers) dns_list = None if dns_cfg.hasType(ns.StaticDnsServers): dns_list = [] for i in dns_cfg.getS(ns.addressList, rdf.Seq(rdf.Type(ns.DnsServer))): srv = ResolvedDnsServer() srv.address = i.getS(ns.address, rdf.IPv4Address) srv.rdf_server_list = dns_cfg srv.from_dhcp = False srv.from_dhcp_rdf_interface = None dns_list.append(srv) elif dns_cfg.hasType(ns.DhcpDnsServers): iface = dns_cfg.getS(ns.interface, rdf.Type(ns.NetworkInterface)) if iface == pub_if: if pub_addrinfo is not None: dns_list = [] for i in pub_addrinfo.dns_servers: srv = ResolvedDnsServer() srv.address = i # IPv4Address srv.rdf_server_list = dns_cfg srv.from_dhcp = True srv.from_dhcp_rdf_interface = pub_if dns_list.append(srv) else: dns_list = [] elif iface == priv_if: if priv_addrinfo is not None: dns_list = [] for i in priv_addrinfo.dns_servers: srv = ResolvedDnsServer() srv.address = i # IPv4Address srv.rdf_server_list = dns_cfg srv.from_dhcp = True srv.from_dhcp_rdf_interface = priv_if dns_list.append(srv) else: dns_list = [] else: raise Exception( 'unknown interface for dhcp-assigned dns servers for ppp' ) else: # XXX: better exception? InternalError or something? raise Exception('unknown dns servers variant for ppp') # wins servers if ppp_cfg.hasS(ns.pppWinsServers): wins_cfg = ppp_cfg.getS(ns.pppWinsServers) wins_list = None if wins_cfg.hasType(ns.StaticWinsServers): wins_list = [] for i in wins_cfg.getS(ns.addressList, rdf.Seq(rdf.Type(ns.WinsServer))): srv = ResolvedWinsServer() srv.address = i.getS(ns.address, rdf.IPv4Address) srv.rdf_server_list = wins_cfg srv.from_dhcp = False srv.from_dhcp_rdf_interface = None wins_list.append(srv) elif wins_cfg.hasType(ns.DhcpWinsServers): iface = wins_cfg.getS(ns.interface, rdf.Type(ns.NetworkInterface)) if iface == pub_if: if pub_addrinfo is not None: wins_list = [] for i in pub_addrinfo.wins_servers: srv = ResolvedWinsServer() srv.address = i # IPv4Address srv.rdf_server_list = wins_cfg srv.from_dhcp = True srv.from_dhcp_rdf_interface = pub_if wins_list.append(srv) else: wins_list = [] elif iface == priv_if: if priv_addrinfo is not None: wins_list = [] for i in priv_addrinfo.wins_servers: srv = ResolvedWinsServer() srv.address = i # IPv4Address srv.rdf_server_list = wins_cfg srv.from_dhcp = True srv.from_dhcp_rdf_interface = priv_if wins_list.append(srv) else: wins_list = [] else: raise Exception( 'unknown interface for dhcp-assigned wins servers for ppp' ) else: # XXX: better exception? InternalError or something? raise Exception('unknown wins servers variant for ppp') return dns_list, wins_list