コード例 #1
0
    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'])
コード例 #2
0
ファイル: userconfig.py プロジェクト: zeus911/vpnease-l2tp
    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')
コード例 #3
0
 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
コード例 #4
0
    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
コード例 #5
0
ファイル: pluto.py プロジェクト: zeus911/vpnease-l2tp
    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
        }]
コード例 #6
0
ファイル: configresolve.py プロジェクト: zeus911/vpnease-l2tp
    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')
コード例 #7
0
    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
コード例 #8
0
ファイル: configresolve.py プロジェクト: zeus911/vpnease-l2tp
    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')
コード例 #9
0
    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
コード例 #10
0
    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
コード例 #11
0
    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)
コード例 #12
0
ファイル: userconfig.py プロジェクト: zeus911/vpnease-l2tp
    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
コード例 #13
0
    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
コード例 #14
0
    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')
コード例 #15
0
    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
コード例 #16
0
    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')
コード例 #17
0
    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))
コード例 #18
0
ファイル: userconfig.py プロジェクト: zeus911/vpnease-l2tp
    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())
コード例 #19
0
ファイル: autoconfigexe.py プロジェクト: zeus911/vpnease-l2tp
    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)
コード例 #20
0
    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')
コード例 #21
0
ファイル: configresolve.py プロジェクト: zeus911/vpnease-l2tp
    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