ÿØÿà JFIF ÿþ >CREATOR: gd-jpeg v1.0 (using IJG JPEG v62), default quality
ÿÛ C
Server IP : 172.67.171.101 / Your IP : 216.73.216.123 Web Server : Apache System : Linux server1.morocco-tours.com 3.10.0-1127.19.1.el7.x86_64 #1 SMP Tue Aug 25 17:23:54 UTC 2020 x86_64 User : zagoradraa ( 1005) PHP Version : 7.4.33 Disable Function : NONE MySQL : OFF | cURL : ON | WGET : ON | Perl : ON | Python : ON | Sudo : ON | Pkexec : ON Directory : /lib/python2.7/site-packages/firewall/core/ |
Upload File : |
| Current File : /lib/python2.7/site-packages/firewall/core/fw.py |
# -*- coding: utf-8 -*-
#
# Copyright (C) 2010-2016 Red Hat, Inc.
#
# Authors:
# Thomas Woerner <twoerner@redhat.com>
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
#
__all__ = [ "Firewall" ]
import os.path
import sys
import copy
import time
import traceback
from firewall import config
from firewall import functions
from firewall.core import ipXtables
from firewall.core import ebtables
from firewall.core import nftables
from firewall.core import ipset
from firewall.core import modules
from firewall.core.fw_icmptype import FirewallIcmpType
from firewall.core.fw_service import FirewallService
from firewall.core.fw_zone import FirewallZone
from firewall.core.fw_direct import FirewallDirect
from firewall.core.fw_config import FirewallConfig
from firewall.core.fw_policies import FirewallPolicies
from firewall.core.fw_ipset import FirewallIPSet
from firewall.core.fw_transaction import FirewallTransaction
from firewall.core.fw_helper import FirewallHelper
from firewall.core.logger import log
from firewall.core.io.firewalld_conf import firewalld_conf
from firewall.core.io.direct import Direct
from firewall.core.io.service import service_reader
from firewall.core.io.icmptype import icmptype_reader
from firewall.core.io.zone import zone_reader, Zone
from firewall.core.io.ipset import ipset_reader
from firewall.core.io.helper import helper_reader
from firewall import errors
from firewall.errors import FirewallError
############################################################################
#
# class Firewall
#
############################################################################
class Firewall(object):
def __init__(self):
self._firewalld_conf = firewalld_conf(config.FIREWALLD_CONF)
self.ip4tables_backend = ipXtables.ip4tables(self)
self.ip4tables_enabled = True
self.ip4tables_supported_icmp_types = [ ]
self.ip6tables_backend = ipXtables.ip6tables(self)
self.ip6tables_enabled = True
self.ip6tables_supported_icmp_types = [ ]
self.ebtables_backend = ebtables.ebtables()
self.ebtables_enabled = True
self.ipset_backend = ipset.ipset()
self.ipset_enabled = True
self.ipset_supported_types = [ ]
self.nftables_backend = nftables.nftables(self)
self.nftables_enabled = True
self.modules_backend = modules.modules()
self.icmptype = FirewallIcmpType(self)
self.service = FirewallService(self)
self.zone = FirewallZone(self)
self.direct = FirewallDirect(self)
self.config = FirewallConfig(self)
self.policies = FirewallPolicies()
self.ipset = FirewallIPSet(self)
self.helper = FirewallHelper(self)
self.__init_vars()
def __repr__(self):
return '%s(%r, %r, %r, %r, %r, %r, %r, %r, %r, %r, %r, %r, %r, %r, %r)' % \
(self.__class__, self.ip4tables_enabled, self.ip6tables_enabled,
self.ebtables_enabled, self._state, self._panic,
self._default_zone, self._module_refcount, self._marks,
self._min_mark, self.cleanup_on_exit, self.ipv6_rpfilter_enabled,
self.ipset_enabled, self._individual_calls, self._log_denied,
self._automatic_helpers)
def __init_vars(self):
self._state = "INIT"
self._panic = False
self._default_zone = ""
self._module_refcount = { }
self._marks = [ ]
# fallback settings will be overloaded by firewalld.conf
self._min_mark = config.FALLBACK_MINIMAL_MARK
self.cleanup_on_exit = config.FALLBACK_CLEANUP_ON_EXIT
self.ipv6_rpfilter_enabled = config.FALLBACK_IPV6_RPFILTER
self._individual_calls = config.FALLBACK_INDIVIDUAL_CALLS
self._log_denied = config.FALLBACK_LOG_DENIED
self._automatic_helpers = config.FALLBACK_AUTOMATIC_HELPERS
self._firewall_backend = config.FALLBACK_FIREWALL_BACKEND
self.nf_conntrack_helper_setting = 0
self._allow_zone_drifting = config.FALLBACK_ALLOW_ZONE_DRIFTING
def individual_calls(self):
return self._individual_calls
def _check_tables(self):
# check if iptables, ip6tables and ebtables are usable, else disable
if self.ip4tables_enabled and \
"filter" not in self.get_backend_by_ipv("ipv4").get_available_tables():
log.warning("iptables not usable, disabling IPv4 firewall.")
self.ip4tables_enabled = False
if self.ip6tables_enabled and \
"filter" not in self.get_backend_by_ipv("ipv6").get_available_tables():
log.warning("ip6tables not usable, disabling IPv6 firewall.")
self.ip6tables_enabled = False
if self.ebtables_enabled and \
"filter" not in self.get_backend_by_ipv("eb").get_available_tables():
log.warning("ebtables not usable, disabling ethernet bridge firewall.")
self.ebtables_enabled = False
# is there at least support for ipv4 or ipv6
if not self.ip4tables_enabled and not self.ip6tables_enabled \
and not self.nftables_enabled:
log.fatal("No IPv4 and IPv6 firewall.")
sys.exit(1)
def _start_check(self):
try:
self.ipset_backend.set_list()
except ValueError:
log.warning("ipset not usable, disabling ipset usage in firewall.")
# ipset is not usable, no supported types
self.ipset_enabled = False
self.ipset_supported_types = [ ]
else:
# ipset is usable, get all supported types
self.ipset_supported_types = self.ipset_backend.set_supported_types()
self.ip4tables_backend.fill_exists()
if not self.ip4tables_backend.restore_command_exists:
if self.ip4tables_backend.command_exists:
log.warning("iptables-restore is missing, using "
"individual calls for IPv4 firewall.")
else:
log.warning("iptables-restore and iptables are missing, "
"disabling IPv4 firewall.")
self.ip4tables_enabled = False
if self.ip4tables_enabled:
self.ip4tables_supported_icmp_types = \
self.ip4tables_backend.supported_icmp_types()
else:
self.ip4tables_supported_icmp_types = [ ]
self.ip6tables_backend.fill_exists()
if not self.ip6tables_backend.restore_command_exists:
if self.ip6tables_backend.command_exists:
log.warning("ip6tables-restore is missing, using "
"individual calls for IPv6 firewall.")
else:
log.warning("ip6tables-restore and ip6tables are missing, "
"disabling IPv6 firewall.")
self.ip6tables_enabled = False
if self.ip6tables_enabled:
self.ip6tables_supported_icmp_types = \
self.ip6tables_backend.supported_icmp_types()
else:
self.ip6tables_supported_icmp_types = [ ]
self.ebtables_backend.fill_exists()
if not self.ebtables_backend.restore_command_exists:
if self.ebtables_backend.command_exists:
log.warning("ebtables-restore is missing, using "
"individual calls for bridge firewall.")
else:
log.warning("ebtables-restore and ebtables are missing, "
"disabling bridge firewall.")
self.ebtables_enabled = False
if self.ebtables_enabled and not self._individual_calls and \
not self.ebtables_backend.restore_noflush_option:
log.debug1("ebtables-restore is not supporting the --noflush "
"option, will therefore not be used")
def _start(self, reload=False, complete_reload=False):
# initialize firewall
default_zone = config.FALLBACK_ZONE
# load firewalld config
log.debug1("Loading firewalld config file '%s'", config.FIREWALLD_CONF)
try:
self._firewalld_conf.read()
except Exception as msg:
log.warning(msg)
log.warning("Using fallback firewalld configuration settings.")
else:
if self._firewalld_conf.get("DefaultZone"):
default_zone = self._firewalld_conf.get("DefaultZone")
if self._firewalld_conf.get("MinimalMark"):
self._min_mark = int(self._firewalld_conf.get("MinimalMark"))
if self._firewalld_conf.get("CleanupOnExit"):
value = self._firewalld_conf.get("CleanupOnExit")
if value is not None and value.lower() in [ "no", "false" ]:
self.cleanup_on_exit = False
log.debug1("CleanupOnExit is set to '%s'",
self.cleanup_on_exit)
if self._firewalld_conf.get("Lockdown"):
value = self._firewalld_conf.get("Lockdown")
if value is not None and value.lower() in [ "yes", "true" ]:
log.debug1("Lockdown is enabled")
try:
self.policies.enable_lockdown()
except FirewallError:
# already enabled, this is probably reload
pass
if self._firewalld_conf.get("IPv6_rpfilter"):
value = self._firewalld_conf.get("IPv6_rpfilter")
if value is not None:
if value.lower() in [ "no", "false" ]:
self.ipv6_rpfilter_enabled = False
if value.lower() in [ "yes", "true" ]:
self.ipv6_rpfilter_enabled = True
if self.ipv6_rpfilter_enabled:
log.debug1("IPv6 rpfilter is enabled")
else:
log.debug1("IPV6 rpfilter is disabled")
if self._firewalld_conf.get("IndividualCalls"):
value = self._firewalld_conf.get("IndividualCalls")
if value is not None and value.lower() in [ "yes", "true" ]:
log.debug1("IndividualCalls is enabled")
self._individual_calls = True
if self._firewalld_conf.get("LogDenied"):
value = self._firewalld_conf.get("LogDenied")
if value is None or value.lower() == "no":
self._log_denied = "off"
else:
self._log_denied = value.lower()
log.debug1("LogDenied is set to '%s'", self._log_denied)
if self._firewalld_conf.get("AutomaticHelpers"):
value = self._firewalld_conf.get("AutomaticHelpers")
if value is not None:
if value.lower() in [ "no", "false" ]:
self._automatic_helpers = "no"
elif value.lower() in [ "yes", "true" ]:
self._automatic_helpers = "yes"
else:
self._automatic_helpers = value.lower()
log.debug1("AutomaticHelpers is set to '%s'",
self._automatic_helpers)
if self._firewalld_conf.get("AllowZoneDrifting"):
value = self._firewalld_conf.get("AllowZoneDrifting")
if value.lower() in [ "no", "false" ]:
self._allow_zone_drifting = False
else:
self._allow_zone_drifting = True
log.warning("AllowZoneDrifting is enabled. This is considered "
"an insecure configuration option. It will be "
"removed in a future release. Please consider "
"disabling it now.")
log.debug1("AllowZoneDrifting is set to '%s'",
self._allow_zone_drifting)
self.config.set_firewalld_conf(copy.deepcopy(self._firewalld_conf))
self._select_firewall_backend(self._firewall_backend)
self._start_check()
# load lockdown whitelist
log.debug1("Loading lockdown whitelist")
try:
self.policies.lockdown_whitelist.read()
except Exception as msg:
if self.policies.query_lockdown():
log.error("Failed to load lockdown whitelist '%s': %s",
self.policies.lockdown_whitelist.filename, msg)
else:
log.debug1("Failed to load lockdown whitelist '%s': %s",
self.policies.lockdown_whitelist.filename, msg)
# copy policies to config interface
self.config.set_policies(copy.deepcopy(self.policies))
# load ipset files
self._loader(config.FIREWALLD_IPSETS, "ipset")
self._loader(config.ETC_FIREWALLD_IPSETS, "ipset")
# load icmptype files
self._loader(config.FIREWALLD_ICMPTYPES, "icmptype")
self._loader(config.ETC_FIREWALLD_ICMPTYPES, "icmptype")
if len(self.icmptype.get_icmptypes()) == 0:
log.error("No icmptypes found.")
# load helper files
self._loader(config.FIREWALLD_HELPERS, "helper")
self._loader(config.ETC_FIREWALLD_HELPERS, "helper")
# load service files
self._loader(config.FIREWALLD_SERVICES, "service")
self._loader(config.ETC_FIREWALLD_SERVICES, "service")
if len(self.service.get_services()) == 0:
log.error("No services found.")
# load zone files
self._loader(config.FIREWALLD_ZONES, "zone")
self._loader(config.ETC_FIREWALLD_ZONES, "zone")
if len(self.zone.get_zones()) == 0:
log.fatal("No zones found.")
sys.exit(1)
# check minimum required zones
error = False
for z in [ "block", "drop", "trusted" ]:
if z not in self.zone.get_zones():
log.fatal("Zone '%s' is not available.", z)
error = True
if error:
sys.exit(1)
# check if default_zone is a valid zone
if default_zone not in self.zone.get_zones():
if "public" in self.zone.get_zones():
zone = "public"
elif "external" in self.zone.get_zones():
zone = "external"
else:
zone = "block" # block is a base zone, therefore it has to exist
log.error("Default zone '%s' is not valid. Using '%s'.",
default_zone, zone)
default_zone = zone
else:
log.debug1("Using default zone '%s'", default_zone)
# load direct rules
obj = Direct(config.FIREWALLD_DIRECT)
if os.path.exists(config.FIREWALLD_DIRECT):
log.debug1("Loading direct rules file '%s'" % \
config.FIREWALLD_DIRECT)
try:
obj.read()
except Exception as msg:
log.error("Failed to load direct rules file '%s': %s",
config.FIREWALLD_DIRECT, msg)
self.direct.set_permanent_config(obj)
self.config.set_direct(copy.deepcopy(obj))
# automatic helpers
#
# NOTE: must force loading of nf_conntrack to make sure the values are
# available in /proc
(status, msg) = self.handle_modules(["nf_conntrack"], True)
if status != 0:
log.warning("Failed to load nf_conntrack module: %s" % msg)
if self._automatic_helpers != "system":
functions.set_nf_conntrack_helper_setting(self._automatic_helpers == "yes")
self.nf_conntrack_helper_setting = \
functions.get_nf_conntrack_helper_setting()
# check if needed tables are there
self._check_tables()
if log.getDebugLogLevel() > 0:
# get time before flushing and applying
tm1 = time.time()
# Start transaction
transaction = FirewallTransaction(self)
# flush rules
self.flush(use_transaction=transaction)
# If modules need to be unloaded in complete reload or if there are
# ipsets to get applied, limit the transaction to flush.
#
# Future optimization for the ipset case in reload: The transaction
# only needs to be split here if there are conflicting ipset types in
# exsting ipsets and the configuration in firewalld.
if (reload and complete_reload) or \
(self.ipset_enabled and self.ipset.has_ipsets()):
transaction.execute(True)
transaction.clear()
# complete reload: unload modules also
if reload and complete_reload:
log.debug1("Unloading firewall modules")
self.modules_backend.unload_firewall_modules()
self.apply_default_tables(use_transaction=transaction)
transaction.execute(True)
transaction.clear()
# apply settings for loaded ipsets while reloading here
if self.ipset_enabled and self.ipset.has_ipsets():
log.debug1("Applying ipsets")
self.ipset.apply_ipsets()
# Start or continue with transaction
# apply default rules
log.debug1("Applying default rule set")
self.apply_default_rules(use_transaction=transaction)
# apply settings for loaded zones
log.debug1("Applying used zones")
self.zone.apply_zones(use_transaction=transaction)
self._default_zone = self.check_zone(default_zone)
self.zone.change_default_zone(None, self._default_zone,
use_transaction=transaction)
# Execute transaction
transaction.execute(True)
# Start new transaction for direct rules
transaction.clear()
# apply direct chains, rules and passthrough rules
if self.direct.has_configuration():
log.debug1("Applying direct chains rules and passthrough rules")
self.direct.apply_direct(transaction)
# since direct rules are easy to make syntax errors lets highlight
# the cause if the transaction fails.
try:
transaction.execute(True)
transaction.clear()
except FirewallError as e:
raise FirewallError(e.code, "Direct: %s" % (e.msg if e.msg else ""))
except Exception:
raise
del transaction
if log.getDebugLogLevel() > 1:
# get time after flushing and applying
tm2 = time.time()
log.debug2("Flushing and applying took %f seconds" % (tm2 - tm1))
def start(self):
try:
self._start()
except Exception:
self._state = "FAILED"
self.set_policy("ACCEPT")
raise
else:
self._state = "RUNNING"
self.set_policy("ACCEPT")
def _loader(self, path, reader_type, combine=False):
# combine: several zone files are getting combined into one obj
if not os.path.isdir(path):
return
if combine:
if path.startswith(config.ETC_FIREWALLD) and reader_type == "zone":
combined_zone = Zone()
combined_zone.name = os.path.basename(path)
combined_zone.check_name(combined_zone.name)
combined_zone.path = path
combined_zone.default = False
else:
combine = False
for filename in sorted(os.listdir(path)):
if not filename.endswith(".xml"):
if path.startswith(config.ETC_FIREWALLD) and \
reader_type == "zone" and \
os.path.isdir("%s/%s" % (path, filename)):
self._loader("%s/%s" % (path, filename), reader_type,
combine=True)
continue
name = "%s/%s" % (path, filename)
log.debug1("Loading %s file '%s'", reader_type, name)
try:
if reader_type == "icmptype":
obj = icmptype_reader(filename, path)
if obj.name in self.icmptype.get_icmptypes():
orig_obj = self.icmptype.get_icmptype(obj.name)
log.debug1(" Overloads %s '%s' ('%s/%s')", reader_type,
orig_obj.name, orig_obj.path,
orig_obj.filename)
self.icmptype.remove_icmptype(orig_obj.name)
elif obj.path.startswith(config.ETC_FIREWALLD):
obj.default = True
try:
self.icmptype.add_icmptype(obj)
except FirewallError as error:
log.info1("%s: %s, ignoring for run-time." % \
(obj.name, str(error)))
# add a deep copy to the configuration interface
self.config.add_icmptype(copy.deepcopy(obj))
elif reader_type == "service":
obj = service_reader(filename, path)
if obj.name in self.service.get_services():
orig_obj = self.service.get_service(obj.name)
log.debug1(" Overloads %s '%s' ('%s/%s')", reader_type,
orig_obj.name, orig_obj.path,
orig_obj.filename)
self.service.remove_service(orig_obj.name)
elif obj.path.startswith(config.ETC_FIREWALLD):
obj.default = True
self.service.add_service(obj)
# add a deep copy to the configuration interface
self.config.add_service(copy.deepcopy(obj))
elif reader_type == "zone":
obj = zone_reader(filename, path, no_check_name=combine)
if combine:
# Change name for permanent configuration
obj.name = "%s/%s" % (
os.path.basename(path),
os.path.basename(filename)[0:-4])
obj.check_name(obj.name)
# Copy object before combine
config_obj = copy.deepcopy(obj)
if obj.name in self.zone.get_zones():
orig_obj = self.zone.get_zone(obj.name)
self.zone.remove_zone(orig_obj.name)
if orig_obj.combined:
log.debug1(" Combining %s '%s' ('%s/%s')",
reader_type, obj.name,
path, filename)
obj.combine(orig_obj)
else:
log.debug1(" Overloads %s '%s' ('%s/%s')",
reader_type,
orig_obj.name, orig_obj.path,
orig_obj.filename)
elif obj.path.startswith(config.ETC_FIREWALLD):
obj.default = True
config_obj.default = True
self.config.add_zone(config_obj)
if combine:
log.debug1(" Combining %s '%s' ('%s/%s')",
reader_type, combined_zone.name,
path, filename)
combined_zone.combine(obj)
else:
self.zone.add_zone(obj)
elif reader_type == "ipset":
obj = ipset_reader(filename, path)
if obj.name in self.ipset.get_ipsets():
orig_obj = self.ipset.get_ipset(obj.name)
log.debug1(" Overloads %s '%s' ('%s/%s')", reader_type,
orig_obj.name, orig_obj.path,
orig_obj.filename)
self.ipset.remove_ipset(orig_obj.name)
elif obj.path.startswith(config.ETC_FIREWALLD):
obj.default = True
try:
self.ipset.add_ipset(obj)
except FirewallError as error:
log.warning("%s: %s, ignoring for run-time." % \
(obj.name, str(error)))
# add a deep copy to the configuration interface
self.config.add_ipset(copy.deepcopy(obj))
elif reader_type == "helper":
obj = helper_reader(filename, path)
if obj.name in self.helper.get_helpers():
orig_obj = self.helper.get_helper(obj.name)
log.debug1(" Overloads %s '%s' ('%s/%s')", reader_type,
orig_obj.name, orig_obj.path,
orig_obj.filename)
self.helper.remove_helper(orig_obj.name)
elif obj.path.startswith(config.ETC_FIREWALLD):
obj.default = True
self.helper.add_helper(obj)
# add a deep copy to the configuration interface
self.config.add_helper(copy.deepcopy(obj))
else:
log.fatal("Unknown reader type %s", reader_type)
except FirewallError as msg:
log.error("Failed to load %s file '%s': %s", reader_type,
name, msg)
except Exception:
log.error("Failed to load %s file '%s':", reader_type, name)
log.exception()
if combine and combined_zone.combined:
if combined_zone.name in self.zone.get_zones():
orig_obj = self.zone.get_zone(combined_zone.name)
log.debug1(" Overloading and deactivating %s '%s' ('%s/%s')",
reader_type, orig_obj.name, orig_obj.path,
orig_obj.filename)
try:
self.zone.remove_zone(combined_zone.name)
except Exception:
pass
self.config.forget_zone(combined_zone.name)
self.zone.add_zone(combined_zone)
def cleanup(self):
self.icmptype.cleanup()
self.service.cleanup()
self.zone.cleanup()
self.ipset.cleanup()
self.helper.cleanup()
self.config.cleanup()
self.direct.cleanup()
self.policies.cleanup()
self._firewalld_conf.cleanup()
self.__init_vars()
def stop(self):
if self.cleanup_on_exit:
self.flush()
self.set_policy("ACCEPT")
self.modules_backend.unload_firewall_modules()
self.cleanup()
# marks
def new_mark(self):
# return first unused mark
i = self._min_mark
while i in self._marks:
i += 1
self._marks.append(i)
return i
def del_mark(self, mark):
self._marks.remove(mark)
# handle modules
def handle_modules(self, _modules, enable):
num_failed = 0
error_msgs = ""
for i,module in enumerate(_modules):
if enable:
(status, msg) = self.modules_backend.load_module(module)
else:
if self._module_refcount[module] > 1:
status = 0 # module referenced more then one, do not unload
else:
(status, msg) = self.modules_backend.unload_module(module)
if status != 0:
num_failed += 1
error_msgs += msg
continue
if enable:
self._module_refcount.setdefault(module, 0)
self._module_refcount[module] += 1
else:
if module in self._module_refcount:
self._module_refcount[module] -= 1
if self._module_refcount[module] == 0:
del self._module_refcount[module]
return (num_failed, error_msgs)
def _select_firewall_backend(self, backend):
if backend != "nftables":
self.nftables_enabled = False
# even if using nftables, the other backends are enabled for use with
# the direct interface. nftables is used for the firewalld primitives.
def get_backend_by_name(self, name):
for backend in self.all_backends():
if backend.name == name:
return backend
raise FirewallError(errors.UNKNOWN_ERROR,
"'%s' backend does not exist" % name)
def get_backend_by_ipv(self, ipv):
if self.nftables_enabled:
return self.nftables_backend
if ipv == "ipv4" and self.ip4tables_enabled:
return self.ip4tables_backend
elif ipv == "ipv6" and self.ip6tables_enabled:
return self.ip6tables_backend
elif ipv == "eb" and self.ebtables_enabled:
return self.ebtables_backend
raise FirewallError(errors.INVALID_IPV,
"'%s' is not a valid backend or is unavailable" % ipv)
def get_direct_backend_by_ipv(self, ipv):
if ipv == "ipv4" and self.ip4tables_enabled:
return self.ip4tables_backend
elif ipv == "ipv6" and self.ip6tables_enabled:
return self.ip6tables_backend
elif ipv == "eb" and self.ebtables_enabled:
return self.ebtables_backend
raise FirewallError(errors.INVALID_IPV,
"'%s' is not a valid backend or is unavailable" % ipv)
def is_backend_enabled(self, name):
if name == "ip4tables":
return self.ip4tables_enabled
elif name == "ip6tables":
return self.ip6tables_enabled
elif name == "ebtables":
return self.ebtables_enabled
elif name == "nftables":
return self.nftables_enabled
return False
def is_ipv_enabled(self, ipv):
if self.nftables_enabled:
return True
if ipv == "ipv4":
return self.ip4tables_enabled
elif ipv == "ipv6":
return self.ip6tables_enabled
elif ipv == "eb":
return self.ebtables_enabled
return False
def enabled_backends(self):
backends = []
if self.nftables_enabled:
backends.append(self.nftables_backend)
else:
if self.ip4tables_enabled:
backends.append(self.ip4tables_backend)
if self.ip6tables_enabled:
backends.append(self.ip6tables_backend)
if self.ebtables_enabled:
backends.append(self.ebtables_backend)
return backends
def all_backends(self):
backends = []
if self.ip4tables_enabled:
backends.append(self.ip4tables_backend)
if self.ip6tables_enabled:
backends.append(self.ip6tables_backend)
if self.ebtables_enabled:
backends.append(self.ebtables_backend)
if self.nftables_enabled:
backends.append(self.nftables_backend)
return backends
def apply_default_tables(self, use_transaction=None):
if use_transaction is None:
transaction = FirewallTransaction(self)
else:
transaction = use_transaction
for backend in self.enabled_backends():
transaction.add_rules(backend, backend.build_default_tables())
if use_transaction is None:
transaction.execute(True)
def apply_default_rules(self, use_transaction=None):
if use_transaction is None:
transaction = FirewallTransaction(self)
else:
transaction = use_transaction
for backend in self.enabled_backends():
rules = backend.build_default_rules(self._log_denied)
transaction.add_rules(backend, rules)
if self.is_ipv_enabled("ipv6"):
ipv6_backend = self.get_backend_by_ipv("ipv6")
if self.ipv6_rpfilter_enabled and \
"raw" in ipv6_backend.get_available_tables():
# Execute existing transaction
transaction.execute(True)
# Start new transaction
transaction.clear()
rules = ipv6_backend.build_rpfilter_rules(self._log_denied)
transaction.add_rules(ipv6_backend, rules)
# Execute ipv6_rpfilter transaction, it might fail
try:
transaction.execute(True)
except FirewallError as msg:
log.warning("Applying rules for ipv6_rpfilter failed: %s", msg)
# Start new transaction
transaction.clear()
if use_transaction is None:
transaction.execute(True)
# flush and policy
def flush(self, use_transaction=None):
if use_transaction is None:
transaction = FirewallTransaction(self)
else:
transaction = use_transaction
log.debug1("Flushing rule set")
for backend in self.all_backends():
rules = backend.build_flush_rules()
transaction.add_rules(backend, rules)
if use_transaction is None:
transaction.execute(True)
def set_policy(self, policy, use_transaction=None):
if use_transaction is None:
transaction = FirewallTransaction(self)
else:
transaction = use_transaction
log.debug1("Setting policy to '%s'", policy)
for backend in self.enabled_backends():
rules = backend.build_set_policy_rules(policy)
transaction.add_rules(backend, rules)
if use_transaction is None:
transaction.execute(True)
# rule function used in handle_ functions
def rule(self, backend_name, rule):
if not rule:
return ""
backend = self.get_backend_by_name(backend_name)
if not backend:
raise FirewallError(errors.INVALID_IPV,
"'%s' is not a valid backend" % backend_name)
if not self.is_backend_enabled(backend_name):
return ""
return backend.set_rule(rule, self._log_denied)
def rules(self, backend_name, rules):
_rules = list(filter(None, rules))
backend = self.get_backend_by_name(backend_name)
if not backend:
raise FirewallError(errors.INVALID_IPV,
"'%s' is not a valid backend" % backend_name)
if not self.is_backend_enabled(backend_name):
return ""
if self._individual_calls or \
not backend.restore_command_exists or \
(backend_name == "ebtables" and not self.ebtables_backend.restore_noflush_option):
for i,rule in enumerate(_rules):
try:
backend.set_rule(rule, self._log_denied)
except Exception as msg:
log.debug1(traceback.format_exc())
log.error(msg)
for rule in reversed(_rules[:i]):
try:
backend.set_rule(backend.reverse_rule(rule), self._log_denied)
except Exception:
# ignore errors here
pass
raise msg
return True
else:
return backend.set_rules(_rules, self._log_denied)
# check functions
def check_panic(self):
if self._panic:
raise FirewallError(errors.PANIC_MODE)
def check_zone(self, zone):
_zone = zone
if not _zone or _zone == "":
_zone = self.get_default_zone()
if _zone not in self.zone.get_zones():
raise FirewallError(errors.INVALID_ZONE, _zone)
return _zone
def check_interface(self, interface):
if not functions.checkInterface(interface):
raise FirewallError(errors.INVALID_INTERFACE, interface)
def check_service(self, service):
self.service.check_service(service)
def check_port(self, port):
if not functions.check_port(port):
raise FirewallError(errors.INVALID_PORT, port)
def check_tcpudp(self, protocol):
if not protocol:
raise FirewallError(errors.MISSING_PROTOCOL)
if protocol not in [ "tcp", "udp", "sctp", "dccp" ]:
raise FirewallError(errors.INVALID_PROTOCOL,
"'%s' not in {'tcp'|'udp'|'sctp'|'dccp'}" % \
protocol)
def check_ip(self, ip):
if not functions.checkIP(ip):
raise FirewallError(errors.INVALID_ADDR, ip)
def check_address(self, ipv, source):
if ipv == "ipv4":
if not functions.checkIPnMask(source):
raise FirewallError(errors.INVALID_ADDR, source)
elif ipv == "ipv6":
if not functions.checkIP6nMask(source):
raise FirewallError(errors.INVALID_ADDR, source)
else:
raise FirewallError(errors.INVALID_IPV,
"'%s' not in {'ipv4'|'ipv6'}")
def check_icmptype(self, icmp):
self.icmptype.check_icmptype(icmp)
def check_timeout(self, timeout):
if not isinstance(timeout, int):
raise TypeError("%s is %s, expected int" % (timeout, type(timeout)))
if int(timeout) < 0:
raise FirewallError(errors.INVALID_VALUE,
"timeout '%d' is not positive number" % timeout)
# RELOAD
def reload(self, stop=False):
_panic = self._panic
# save zone interfaces
_zone_interfaces = { }
for zone in self.zone.get_zones():
_zone_interfaces[zone] = self.zone.get_settings(zone)["interfaces"]
# save direct config
_direct_config = self.direct.get_runtime_config()
_old_dz = self.get_default_zone()
self.set_policy("DROP")
# stop
self.cleanup()
start_exception = None
try:
self._start(reload=True, complete_reload=stop)
except Exception as e:
# save the exception for later, but continue restoring interfaces,
# etc. We'll re-raise it at the end.
start_exception = e
# handle interfaces in the default zone and move them to the new
# default zone if it changed
_new_dz = self.get_default_zone()
if _new_dz != _old_dz:
# if_new_dz has been introduced with the reload, we need to add it
# https://github.com/firewalld/firewalld/issues/53
if _new_dz not in _zone_interfaces:
_zone_interfaces[_new_dz] = { }
# default zone changed. Move interfaces from old default zone to
# the new one.
for iface, settings in list(_zone_interfaces[_old_dz].items()):
if settings["__default__"]:
# move only those that were added to default zone
# (not those that were added to specific zone same as
# default)
_zone_interfaces[_new_dz][iface] = \
_zone_interfaces[_old_dz][iface]
del _zone_interfaces[_old_dz][iface]
# add interfaces to zones again
for zone in self.zone.get_zones():
if zone in _zone_interfaces:
self.zone.set_settings(zone, { "interfaces":
_zone_interfaces[zone] })
del _zone_interfaces[zone]
else:
log.info1("New zone '%s'.", zone)
if len(_zone_interfaces) > 0:
for zone in list(_zone_interfaces.keys()):
log.info1("Lost zone '%s', zone interfaces dropped.", zone)
del _zone_interfaces[zone]
del _zone_interfaces
# restore direct config
self.direct.set_config(_direct_config)
# enable panic mode again if it has been enabled before or set policy
# to ACCEPT
if _panic:
self.enable_panic_mode()
else:
self.set_policy("ACCEPT")
if start_exception:
self._state = "FAILED"
raise start_exception
else:
self._state = "RUNNING"
# STATE
def get_state(self):
return self._state
# PANIC MODE
def enable_panic_mode(self):
if self._panic:
raise FirewallError(errors.ALREADY_ENABLED,
"panic mode already enabled")
# TODO: use rule in raw table not default chain policy
try:
self.set_policy("DROP")
except Exception as msg:
raise FirewallError(errors.COMMAND_FAILED, msg)
self._panic = True
def disable_panic_mode(self):
if not self._panic:
raise FirewallError(errors.NOT_ENABLED,
"panic mode is not enabled")
# TODO: use rule in raw table not default chain policy
try:
self.set_policy("ACCEPT")
except Exception as msg:
raise FirewallError(errors.COMMAND_FAILED, msg)
self._panic = False
def query_panic_mode(self):
return self._panic
# LOG DENIED
def get_log_denied(self):
return self._log_denied
def set_log_denied(self, value):
if value not in config.LOG_DENIED_VALUES:
raise FirewallError(errors.INVALID_VALUE,
"'%s', choose from '%s'" % \
(value, "','".join(config.LOG_DENIED_VALUES)))
if value != self.get_log_denied():
self._log_denied = value
self._firewalld_conf.set("LogDenied", value)
self._firewalld_conf.write()
else:
raise FirewallError(errors.ALREADY_SET, value)
# AUTOMATIC HELPERS
def get_automatic_helpers(self):
return self._automatic_helpers
def set_automatic_helpers(self, value):
if value not in config.AUTOMATIC_HELPERS_VALUES:
raise FirewallError(errors.INVALID_VALUE,
"'%s', choose from '%s'" % \
(value, "','".join(config.AUTOMATIC_HELPERS_VALUES)))
if value != self.get_automatic_helpers():
self._automatic_helpers = value
self._firewalld_conf.set("AutomaticHelpers", value)
self._firewalld_conf.write()
else:
raise FirewallError(errors.ALREADY_SET, value)
# DEFAULT ZONE
def get_default_zone(self):
return self._default_zone
def set_default_zone(self, zone):
_zone = self.check_zone(zone)
if _zone != self._default_zone:
_old_dz = self._default_zone
self._default_zone = _zone
self._firewalld_conf.set("DefaultZone", _zone)
self._firewalld_conf.write()
# remove old default zone from ZONES and add new default zone
self.zone.change_default_zone(_old_dz, _zone)
# Move interfaces from old default zone to the new one.
_old_dz_settings = self.zone.get_settings(_old_dz)
for iface, settings in list(_old_dz_settings["interfaces"].items()):
if settings["__default__"]:
# move only those that were added to default zone
# (not those that were added to specific zone same as default)
self.zone.change_zone_of_interface("", iface)
else:
raise FirewallError(errors.ZONE_ALREADY_SET, _zone)
| N4m3 |
5!z3 |
L45t M0d!f!3d |
0wn3r / Gr0up |
P3Rm!55!0n5 |
0pt!0n5 |
| .. |
-- |
August 03 2021 20:11:04 |
root / root |
0755 |
|
| io |
-- |
August 03 2021 20:11:04 |
root / root |
0755 |
|
| | | | | |
| __init__.py |
0 KB |
April 28 2021 13:31:12 |
root / root |
0644 |
|
| __init__.pyc |
0.142 KB |
April 28 2021 13:31:13 |
root / root |
0644 |
|
| __init__.pyo |
0.142 KB |
April 28 2021 13:31:13 |
root / root |
0644 |
|
| base.py |
1.936 KB |
April 28 2021 13:31:12 |
root / root |
0644 |
|
| base.pyc |
1.29 KB |
April 28 2021 13:31:13 |
root / root |
0644 |
|
| base.pyo |
1.29 KB |
April 28 2021 13:31:13 |
root / root |
0644 |
|
| ebtables.py |
9.128 KB |
April 28 2021 13:31:12 |
root / root |
0644 |
|
| ebtables.pyc |
9.036 KB |
April 28 2021 13:31:13 |
root / root |
0644 |
|
| ebtables.pyo |
9.036 KB |
April 28 2021 13:31:13 |
root / root |
0644 |
|
| fw.py |
43.706 KB |
April 28 2021 13:31:12 |
root / root |
0644 |
|
| fw.pyc |
30.673 KB |
April 28 2021 13:31:13 |
root / root |
0644 |
|
| fw.pyo |
30.673 KB |
April 28 2021 13:31:13 |
root / root |
0644 |
|
| fw_config.py |
35.99 KB |
April 28 2021 13:31:12 |
root / root |
0644 |
|
| fw_config.pyc |
30.686 KB |
April 28 2021 13:31:13 |
root / root |
0644 |
|
| fw_config.pyo |
30.686 KB |
April 28 2021 13:31:13 |
root / root |
0644 |
|
| fw_direct.py |
20.115 KB |
April 28 2021 13:31:12 |
root / root |
0644 |
|
| fw_direct.pyc |
14.772 KB |
April 28 2021 13:31:13 |
root / root |
0644 |
|
| fw_direct.pyo |
14.772 KB |
April 28 2021 13:31:13 |
root / root |
0644 |
|
| fw_helper.py |
1.79 KB |
April 28 2021 13:31:12 |
root / root |
0644 |
|
| fw_helper.pyc |
2.57 KB |
April 28 2021 13:31:13 |
root / root |
0644 |
|
| fw_helper.pyo |
2.57 KB |
April 28 2021 13:31:13 |
root / root |
0644 |
|
| fw_icmptype.py |
2.773 KB |
April 28 2021 13:31:12 |
root / root |
0644 |
|
| fw_icmptype.pyc |
2.995 KB |
April 28 2021 13:31:13 |
root / root |
0644 |
|
| fw_icmptype.pyo |
2.995 KB |
April 28 2021 13:31:13 |
root / root |
0644 |
|
| fw_ifcfg.py |
2.502 KB |
April 28 2021 13:31:12 |
root / root |
0644 |
|
| fw_ifcfg.pyc |
1.838 KB |
April 28 2021 13:31:13 |
root / root |
0644 |
|
| fw_ifcfg.pyo |
1.838 KB |
April 28 2021 13:31:13 |
root / root |
0644 |
|
| fw_ipset.py |
8.96 KB |
April 28 2021 13:31:12 |
root / root |
0644 |
|
| fw_ipset.pyc |
9.018 KB |
April 28 2021 13:31:13 |
root / root |
0644 |
|
| fw_ipset.pyo |
9.018 KB |
April 28 2021 13:31:13 |
root / root |
0644 |
|
| fw_nm.py |
6.494 KB |
April 28 2021 13:31:12 |
root / root |
0644 |
|
| fw_nm.pyc |
5.929 KB |
April 28 2021 13:31:13 |
root / root |
0644 |
|
| fw_nm.pyo |
5.929 KB |
April 28 2021 13:31:13 |
root / root |
0644 |
|
| fw_policies.py |
2.737 KB |
April 28 2021 13:31:12 |
root / root |
0644 |
|
| fw_policies.pyc |
2.941 KB |
April 28 2021 13:31:13 |
root / root |
0644 |
|
| fw_policies.pyo |
2.941 KB |
April 28 2021 13:31:13 |
root / root |
0644 |
|
| fw_service.py |
1.601 KB |
April 28 2021 13:31:12 |
root / root |
0644 |
|
| fw_service.pyc |
2.145 KB |
April 28 2021 13:31:13 |
root / root |
0644 |
|
| fw_service.pyo |
2.145 KB |
April 28 2021 13:31:13 |
root / root |
0644 |
|
| fw_test.py |
22.056 KB |
April 28 2021 13:31:12 |
root / root |
0644 |
|
| fw_test.pyc |
17.445 KB |
April 28 2021 13:31:13 |
root / root |
0644 |
|
| fw_test.pyo |
17.445 KB |
April 28 2021 13:31:13 |
root / root |
0644 |
|
| fw_transaction.py |
10.539 KB |
April 28 2021 13:31:12 |
root / root |
0644 |
|
| fw_transaction.pyc |
10.958 KB |
April 28 2021 13:31:13 |
root / root |
0644 |
|
| fw_transaction.pyo |
10.958 KB |
April 28 2021 13:31:13 |
root / root |
0644 |
|
| fw_zone.py |
75.604 KB |
April 28 2021 13:31:12 |
root / root |
0644 |
|
| fw_zone.pyc |
57.309 KB |
April 28 2021 13:31:13 |
root / root |
0644 |
|
| fw_zone.pyo |
57.309 KB |
April 28 2021 13:31:13 |
root / root |
0644 |
|
| helper.py |
0.785 KB |
April 28 2021 13:31:12 |
root / root |
0644 |
|
| helper.pyc |
0.217 KB |
April 28 2021 13:31:13 |
root / root |
0644 |
|
| helper.pyo |
0.217 KB |
April 28 2021 13:31:13 |
root / root |
0644 |
|
| icmp.py |
3.028 KB |
April 28 2021 13:31:12 |
root / root |
0644 |
|
| icmp.pyc |
2.894 KB |
April 28 2021 13:31:13 |
root / root |
0644 |
|
| icmp.pyo |
2.894 KB |
April 28 2021 13:31:13 |
root / root |
0644 |
|
| ipXtables.py |
47.679 KB |
April 28 2021 13:31:12 |
root / root |
0644 |
|
| ipXtables.pyc |
34.804 KB |
April 28 2021 13:31:13 |
root / root |
0644 |
|
| ipXtables.pyo |
34.804 KB |
April 28 2021 13:31:13 |
root / root |
0644 |
|
| ipset.py |
9.1 KB |
April 28 2021 13:31:12 |
root / root |
0644 |
|
| ipset.pyc |
9.15 KB |
April 28 2021 13:31:13 |
root / root |
0644 |
|
| ipset.pyo |
9.15 KB |
April 28 2021 13:31:13 |
root / root |
0644 |
|
| logger.py |
30.311 KB |
April 28 2021 13:31:12 |
root / root |
0644 |
|
| logger.pyc |
27.429 KB |
April 28 2021 13:31:13 |
root / root |
0644 |
|
| logger.pyo |
27.429 KB |
April 28 2021 13:31:13 |
root / root |
0644 |
|
| modules.py |
3.627 KB |
April 28 2021 13:31:12 |
root / root |
0644 |
|
| modules.pyc |
3.563 KB |
April 28 2021 13:31:13 |
root / root |
0644 |
|
| modules.pyo |
3.563 KB |
April 28 2021 13:31:13 |
root / root |
0644 |
|
| nftables.py |
60.549 KB |
April 28 2021 13:31:12 |
root / root |
0644 |
|
| nftables.pyc |
38.556 KB |
April 28 2021 13:31:13 |
root / root |
0644 |
|
| nftables.pyo |
38.556 KB |
April 28 2021 13:31:13 |
root / root |
0644 |
|
| prog.py |
1.475 KB |
April 28 2021 13:31:12 |
root / root |
0644 |
|
| prog.pyc |
0.965 KB |
April 28 2021 13:31:13 |
root / root |
0644 |
|
| prog.pyo |
0.965 KB |
April 28 2021 13:31:13 |
root / root |
0644 |
|
| rich.py |
29.336 KB |
April 28 2021 13:31:12 |
root / root |
0644 |
|
| rich.pyc |
23.73 KB |
April 28 2021 13:31:13 |
root / root |
0644 |
|
| rich.pyo |
23.73 KB |
April 28 2021 13:31:13 |
root / root |
0644 |
|
| watcher.py |
3.152 KB |
April 28 2021 13:31:12 |
root / root |
0644 |
|
| watcher.pyc |
3.549 KB |
April 28 2021 13:31:13 |
root / root |
0644 |
|
| watcher.pyo |
3.549 KB |
April 28 2021 13:31:13 |
root / root |
0644 |
|
$.' ",#(7),01444'9=82<.342ÿÛ C
2!!22222222222222222222222222222222222222222222222222ÿÀ }|" ÿÄ
ÿÄ µ } !1AQa "q2‘¡#B±ÁRÑð$3br‚
%&'()*456789:CDEFGHIJSTUVWXYZcdefghijstuvwxyzƒ„…†‡ˆ‰Š’“”•–—˜™š¢£¤¥¦§¨©ª²³´µ¶·¸¹ºÂÃÄÅÆÇÈÉÊÒÓÔÕÖרÙÚáâãäåæçèéêñòóôõö÷øùúÿÄ
ÿÄ µ w !1AQ aq"2B‘¡±Á #3RðbrÑ
$4á%ñ&'()*56789:CDEFGHIJSTUVWXYZcdefghijstuvwxyz‚ƒ„…†‡ˆ‰Š’“”•–—˜™š¢£¤¥¦§¨©ª²³´µ¶·¸¹ºÂÃÄÅÆÇÈÉÊÒÓÔÕÖרÙÚâãäåæçèéêòóôõö÷øùúÿÚ ? ÷HR÷j¹ûA <̃.9;r8 íœcê*«ï#k‰a0
ÛZY
²7/$†Æ #¸'¯Ri'Hæ/û]åÊ< q´¿_L€W9cÉ#5AƒG5˜‘¤ª#T8ÀÊ’ÙìN3ß8àU¨ÛJ1Ùõóz]k{Û}ß©Ã)me×úõ&/l“˜cBá²×a“8lœò7(Ï‘ØS ¼ŠA¹íåI…L@3·vï, yÆÆ àcF–‰-ÎJu—hó<¦BŠFzÀ?tãúguR‹u#
‡{~?Ú•£=n¾qo~öôüô¸¾³$õüÑ»jò]Mä¦
>ÎÈ[¢à–?) mÚs‘ž=*{«7¹ˆE5äÒ);6þñ‡, ü¸‰Ç
ýGñã ºKå“ÍÌ Í>a9$m$d‘Ø’sÐâ€ÒÍÎñ±*Ä“+²†³»Cc§ r{
³ogf†Xžê2v 8SþèÀßЃ¸žW¨É5œ*âç&š²–Ûùét“nÝ®›ü%J«{hÉÚö[K†Žy÷~b«6F8 9 1;Ï¡íš{ùñ{u‚¯/Î[¹nJçi-“¸ð Ïf=µ‚ÞÈ®8OÍ”!c H%N@<ŽqÈlu"š…xHm®ä<*ó7•…Á
Á#‡|‘Ó¦õq“êífÛüŸ•oNÚ{ËFý;– ŠÙ–!½Òq–‹væRqŒ®?„ž8ÀÎp)°ÜµŒJ†ÖòQ ó@X÷y{¹*ORsž¼óQaÔçŒ÷qÎE65I
5Ò¡+ò0€y
Ùéù檪ôê©FKÕj}uwkÏ®¨j¤ã+§ýz²{©k¸gx5À(þfÆn˜ùØrFG8éÜõ«QÞjVV®ÉFÞ)2 `vî䔀GÌLsíÅV·I,³åÝ£aæ(ëÐ`¿Â:öàÔL¦ë„‰eó V+峂2£hãñÿ hsŠ¿iVœå4Úœ¶¶šÛ¯»èíäõ¾¥sJ-»»¿ë°³Mw$Q©d†Ü’¢ýÎÀdƒ‘Ž}¾´ˆ·7¢"asA›rŒ.v@ ÞÇj”Y´%Š–·–5\ܲõåË2Hã×°*¾d_(˜»#'<ŒîØ1œuþ!ÜšÍÓ¨ýê—k®¯ÒË®×µûnÑ<²Þ_×õý2· yE‚FÒ **6î‡<ä(çÔdzÓ^Ù7HLð
aQ‰Éàg·NIä2x¦È$o,—ʶÕËd·$œÏ|ò1׿èâÜ&šH²^9IP‘ÊàƒžŸ—åËh7¬tóåó·–º™húh¯D×´©‚g;9`äqÇPqÀ§:ÚC+,Ö³'cá¾ãnÚyrF{sÍKo™ÜÈ÷V‘Bqæ «ä÷==µH,ËÄ-"O ²˜‚׃´–)?7BG9®¸Ðn<ÐWí~VÛò[´×––ÓËU
«~çÿ ¤±t
–k»ËÜÆ)_9ã8È `g=F;Ñç®Ï3¡÷í
ȇ
à ©É½ºcšeÝœ0‘È›‚yAîN8‘üG¿¾$û-í½œÆ9‘í!ˆ9F9çxëøž*o_žIÆÖZò¥ÓºVùöõ¿w¦Ýˆæ•´ÓYÄ®³ËV£êƒæõç?áNòîn.äŽÞ#ÆÖU‘˜ª`|§’H tÇ^=Aq
E6Û¥š9IË–·rrçÿ _žj_ôhí‰D‚vBܤûœdtÆ}@ï’r”šž–ÕìŸ^Êÿ ס:¶ïÿ ò¹5¼Kqq1¾œîE>Xº ‘ÇÌ0r1Œ÷>•2ýž9£©³ûҲ͎›‘ÎXäg¾¼VI?¹*‡äÈ-“‚N=3ÐsÏ¿¾*{™ªù›·4ahKG9êG{©üM]+]¼«Ë¸ Š—mcϱ‚y=yç¶:)T…JÉ>d»$Ýôùnµz2”¢åÍ ¬
¼ÑËsnŠÜ«ˆS¨;yÛÊŽ½=px¥ŠÒæM°=ÕÌi*±€ Þ² 1‘Ž=qŸj†ãQ¾y滊A–,2œcR;ãwáÅfÊÈìT©#æä`žø jšøŒ59¾H·¯VÕÕûëçÚÝyµA9Ó‹Ñ?Çúþºš—QÇ
ÔvòßNqù«¼!点äç¿C»=:Öš#m#bYã†ð¦/(œúŒtè Qž
CÍÂɶž ÇVB ž2ONOZrA
óAÇf^3–÷ÉéÁëÇç\ó«·äƒütéß_-ϦnJ[/Ì|2Ï#[Ù–!’,Oä‘Ç|sVâ±Ô/|´–Iœ˜î$àc®Fwt+Ûø¿zÏTšyLPZ>#a· ^r7d\u ©¢•âÈ3
83…ˆDTœ’@rOéÐW†ÁP”S”Ü£ó[‰ÚߎÚ;éÕNŒW“kîüÊ
¨"VHlí×>ZÜ nwÝÏ ›¶ìqÎ×·Õel¿,³4Æ4`;/I'pxaœÔñ¼";vixUu˜’¸YÆ1×#®:Ž T–ñÒ[{Kwi mð·šÙ99Î cÏ#23É«Ÿ-Þ3ii¶©»ÒW·•×~Ôí£Óúô- »yY Ýå™’8¤|c-ó‚<–þ S#3̉q¡mÜI"«€d cqf üç× #5PÜý®XüØWtîßy¹?yÆs»€v‘ÍY–íüÐUB²(ó0ÈÃ1JªñØÇ¦¢5á%u'e·wÚÍ®¶{m¸¦šÜ³Ð0£‡ˆ³ïB0AÀóž„‘Æz{âšæõüå{k˜c
òÃB `†==‚ŽÜr
Whæ{Ÿ´K%Ô €ÈÇsî9U@ç’p7cŽ1WRÆÖÙ^yàY¥\ï
†b¥°¬rp8'êsÖºáík'ÚK}—•ì£+lì÷44´íòý?«Ö÷0¤I"Ú³.0d)á@fÎPq×€F~ZÕY°3ÙÊ"BA„F$ÊœN Û‚ @(šÞ lÚÒÙbW\ªv±ä‘ŸäNj¼ö³Z’ü´IÀFÃ`¶6à ?!
NxÇÒ©Ò†Oª²½’·ŸM¶{êºjÚqŒ©®èþ
‰ ’&yL%?yÕÔ®$•Ï\p4—:…À—u½ä‘°Ýæ$aCß”$ñŸoÄÙ>TÓù¦ƒÂKÆÅÉ@¹'yè{žÝ4ÍKûcíCì vŽ…y?]Ol©Ê|Íê¾Þ_;üÿ Ï¡Rçånÿ rÔ’[m²»˜¡Ž4ùDŽ›Ë) $’XxËëšY8¹i•†Á!‘þpJ•V^0
Œ±õèi²Å²en%·„†8eeù²Yˆ,S†=?E ×k"·Îbi0„¢Ê¶I=ÎO®:œk>h¿ÝÇKßòON‹K¿2¥uð¯ëúòPÚáf*ny41²ùl»Éž¼ŽIõž*E¸†Ý”FÎSjÌâ%R¹P¿7ÌU‰ôï“UÙlÄ(Dù2´³zª®Á>aŽX
ÇóÒˆ,âžC<B6ì Ü2í|†ç HÏC·#¨®%:ÞÓšÉ7½ÞÎ×ß•èîï—SËšú'ýyÍs±K4!Ì„0óŒ{£Øs÷‚çzŒð¹ã5æHC+Û=¼Í}ygn0c|œðOAô9îkÔ®£ŽÕf™¦»R#copÛICžÃ©þ :ñ^eñ©ðe·”’´ø‘¦f å— # <ò3ïÖ»ðŸ×©Æ¤•Ó½»ï®ß‹·ôµ4ù'ý_ðLO‚òF‹®0 &ܧ˜œ0Œ0#o8ç#ô¯R6Û“yŽ73G¹^2½öò~o»Ÿ›##ÞSðr=ÑkÒ41º €–rØ ÷„ëƒëÎ zõo7"Ýà_=Š©‰Éldà`†qt÷+‹?æxù©%m,ö{.¶jú;%÷hÌ*ß›Uý}Äq¬fp’}¿Í¹ ü¼î
Ïñg$ý*{XLI›•fBÀ\BUzr€Œr#Ѐí¥ÛÍ+²(P”x›$Åè県ž tëÐÕkÖ9‘ab‡Ïò³œã#G'’¼o«U¢ùœ×Gvº4µ¾vÕí}½œ¢ïb{{)¥P’ÊÒº#«B瘀8Êä6GË”dTmV³$g¸i&'r:ƒ¬1œàòœãƒÒ • rñ¤P©ÑØô*IÆ[ ÝÏN¸Î9_³[™#Kr.Fí¤í*IÁ?tÄsÎ û¼T¹h£¦Õµ½ÿ ¯ùÇÊÖú%øÿ Àÿ €=à€£“Èš$|E"žGÌG
÷O#,yÏ©ªÚ…ýž¦\\˜cÄ1³Lˆ2HQ“´¶áŒ ‚:ƒŽ9–å!Š–Í‚É¾F''‘÷yÇNüûãëpÆ|=~¢D•䵕vn2„sÓžGLë
IUP´Uíw®Ú-/mm£²×Ì–ìíeý]? øÑüa¨ÞZÏeki,q‰c10PTpAÜÀg%zSß°2Ĥ¡U]®ØŠÜçžI;€èpx?_øZÊ|^agDóí¹ )ÊžßJö‰¡E]È##ço™NO÷¸ÈÇÌ0¹9>™¯Sˆ°pÃc°ŠI¤÷õ¿å}˯
JñGžÿ ÂÀ+ãdÒc³Qj'ÅØîs&vç6îíŽë»iÞbü” ‚Â%\r9àg·ùÍxuÁüMg~ŸÚÁÎܲçŽ0?*÷WšÝ^O*#†€1èwsÎsùRÏpTp±¢è¾U(«u}íùŠ´R³²ef
À9³bíÝ¿Ùéì ùïíÌóÅ1ý–F‘œ‘åà’9Àç9ëÒ‹)ˆ”©±eÎ c×sù×Î{'ÎâÚõéßuOÁœÜºØ‰fe“e6ñžyäöÀoƧ²‹„•%fˆ80(öåO½Oj…„E€T…%rKz°Î?.;{šXÙ‡ŸeUÚd!üx9þtã%wO_øoòcM-
j–ÒHX_iK#*) ž@Ž{ôǽBd¹‰RÝn–ê0«7ˆìyÀ÷Í@¬Ì¢³³’ 9é÷½?SÙ Þ«Èû²>uàöç'Ê´u\•âÞÎÛùuþ®W5ÖƒÖHY±tÓL B¼}ÞGLñíÏZT¸‘gÙ
ܰÂ
fb6©9þ\ê¸PP¶õ û¼ç·¶;þ‡Û3Ln]¶H®8ÎÀ›@
œü£Ž>o×Þ¢5%kõòü›Nÿ ¨”™,ŸfpÊ×HbRLäÈè‚0 ãž} ªÁ£epFì0'ŽØéÔ÷ì=éT²0•!…Îzt9ç¾?”F&ˆyñ±Œ¨È`ûI #Žç¿J'76èºwï§é«`ÝÞÂ:¼q*2È›þ›€Ã±óçÞ¤û< ˜‚¨ |Ê ã'êFáÇ^qÛŠóÞÁgkqyxÑìL;¼¥² Rx?‡¯Y7PŽwnù¶†û¾Ü·.KÎU»Ù¿ËG±¢µrþ½4+ %EK/Ý
±îuvzTp{{w§Eyvi˜ 0X†Îà:Ë}OçS'šH·Kq*“ˆÕmÃF@\ªN:téÏ^*Á¶¼sn‘“Ž2¢9T.½„\ýò@>˜7NFïNRÓ·wèôßEÕua'¬[þ¾cö¡ÌOæ¦âÅŠ². Ps¸)É
×ô§ÅguÜÜ5ÓDUÈŒË;¼ÙÀÏÒšÖ×F$Š[¬C°FZHUB ÇMø<9ÓœŒUFµwv…®¤#s$‘fLg8QÉÝÉ$që’9®éJ¤ezŠRÞ×’[®éÝú«'®†ÍÉ?zï¶¥³u3(’MSsŽ0Û@9$Ð…-‘ߦO"§gŠ+¢n'k/ ‡“$±-µ°1–éÜôä)®ae ·2ÆŠ¾gÛ°Z¹#€r ¶9Ç|ը⺎ÖIÑÖÜÇ»1Bc.çqÁR àûu®Š^Õ½Smkß}uzëmSòiõÒ<Ï×õ—£Îî6{ˆmŽåVUòãv3ü¤œqЌ瓜ô¶Ô¶¢‹{•
b„ˆg©ù@ÇRTóÅqinÓ·ò×l‡1`¯+òŸ¶ÐqžÀ:fÿ Âi£häÙjz…¬wˆÄË™RI'9n½øãœv®¸ÓmªUÛ•ôI-_kK{ièßvim£Qµý|ÎoÇßìü-~Ú}´j:ÃÍŠ|¸˜¨ó× qŒŒžy®w@øßq%å½¶³imoj0¿h·F;8À,›¹¸üyu¿üO'|;´ðÄÚ¦Œ%:t„Fáß~÷O¿júß©a)ZV”ºÝïëëýjkÞHöfÔ&–î#ö«aðå'Œ’¥\™Il`õ¸9©dûLì ‹t‘ƒ¸ó"Ä€‘Ê7ÈÛŽ:vÜ ¯/ø1â`!»Ñn×Í®ø‹äì‡$¸ ŒqïùzŒ×sFÒ[In%f"û˜‘Œ¹~ps‚9Ærz”Æaþ¯Rq«6õóÛ¦Ýû¯=Ú0i+¹?ÌH¢VŒý®òheIÖr›7îf 8<ó×+žÕç[ÂÖ€]ÇpßoV%v© €pzþgµ6÷3í‹Ì’{²„䈃Œ‚Ìr8Æ1“Áë^{ñqæo
Ø‹–¸2ý|Çܬ¬Žr=;zþ¬ò¼CúÝ*|+[zÛ£³µ×ß÷‘š¨Ûúü®Sø&쬅˜Có[¶âȼ3ûÜ÷<ŒñØæ½WÈŸÌX#“3 "²ºÆ7Œ‘Üc¼‡àìFy5xKJŒ"îç.r@ï×Þ½Ä-ÿ þ“}ª}’*Þ!,Fm¸Î@†9b?1W{Yæ3„`Ú¼VõŠÚÛ_kùöG.mhÎñ ôíhí§Ô$.ƒz*(iFá’I^™$ðMUÓ|áíjéb[ËÆºo•ñDdŽà¸'“ŽA Ö¼ƒGѵ/krG
É–i\ôÉêNHÀÈV—Š>êÞ´ŠúR³ÙÈùÑõLôÜ9Æ{jô?°°Kýš¥WíZ¿V—m6·E}{X~Æ?
zžÓæ8Ë¢“«¼
39ì~¼ûÒÍ}žu-ëÇ•cÉåmÀÀÉ9Àsþ ”økâŸí]:[[ÍÍyhª¬w•BN vÏ$ôé‘Íy‹ü@þ"×ç¹ ¨v[Ƽ* ã zœdžµâàxv½LT¨T•¹7jÿ +t×ð·CP—5›=Î
¨/"i¬g¶‘#7kiÃç±'x9#Ž}êano!òKD‘ílï”('¿SÔð?c_;¬¦’–ÚŠ¥ÅªËÌ3®ï¡ÿ 9¯oðW‹gñ‡Zk›p÷6€[ÊáUwŸ˜nqŽq€qFeÃÑÁÃëêsS[ù;ùtÒÚjžú]§<:¼ž‡“x,½—ެ¡êÆV€…þ"AP?ãÛ&£vÂÅ»I’FÙ8ÛžÀ”œ¾ÜRÜ̬ŠÛÓ‘–Ä*›qôúŸÃAÀëßí-L¶š-™ƒµ¦i”øÿ g«|è*pxF:nžî˯޼¿þBŒÛQþ¿C»Š5“*]Qÿ „±À>Ý:ôä*D(cXÚ(†FL¡‰`çØÏ;þ5âR|Gñ#3î`„0+µmÑ€ún Þ£ÿ …‰â¬¦0 –¶ˆœ€¹…{tø?ʯ(_çþ_Š5XY[¡Ù|Q¿ú
µŠ2︛sO* Бÿ ×â°<+à›MkÂ÷š…ij
·Ü–ˆ«ò‚?ˆœúäc½øåunû]¹Iïåè› ç ¯[ð&©¥Ýxn;6>}²’'`IË0ÁèN}zö5éâ©âr\¢0¥ñs^Ml¿«%®ýM$¥F•–ç‘Øj÷Ze¦£k
2¥ô"FqÀ`„~5Ùü+Ò¤—QºÕ†GÙ—Ë‹ çqä°=¶ÏûÔÍcá¶¡/ˆ¤[ý†iK ™°"ó•Æp;`t¯MÑt}+@²¶Óí·Ídy’3mÕË‘’zc€0 íyÎq„ž ¬4×5[_]Rë{]ì¬UZ±p÷^åØÞÈ[©&OúÝÛ‚‚s÷zžIïßó btÎΪ\ya¾U;C¤t*IÎFF3Џ™c
1žYD…U° êÄàõë\oŒ¼a ‡c[[GŽãP‘7 â znÈ>Ãü3ñ˜,=lUENŒäô¾ÚÀÓ[_ð9 œ´JçMy©E¢Àí}x,bpAó¦üdcûŒW9?Å[Há$¿¹pÄ™#^9O88©zO=«Ë!µÖüY¨³ªÍy9ûÒ1 úôÚ»M?àô÷«ÞëÖ–ÙMÌ#C&ßnJ“Üp#Ђ~²†G–àíekϵío»_žŸuΨQ„t“ÔÛ²øáû›´W6»Øoy FQÎr $Óõìk¬„‹ïÞÚ¼sÆíòÉ67\míÎyF¯ð¯TÓã’K;ë[ð·ld«7üyíšÉ𯊵 êáeYžÏq[«&vMÀðßFà}p3ÅgW‡°8ØßVín›þšõ³¹/ ü,÷ií|’‘´R,®ŠÉ‡W“Ž1ØöëÓ¾xžÖÞ¹xÞݬXZGù\’vŒž˜ÆsØúÓïí&ÒÒ{]Qž9£Ê¡ù·ÄÀ»¶áHäž™5—ìö« -&ù¤U<±ÉÆA>½ý+æg
jžö륢þNÛ=÷JÖÛfdÔ õýËúû‹ÓØB²¬fInZ8wÌÉЮ~aƒÎ=3ìx‚+/¶äÁlŠ‚?™Æü#8-œ\pqTZXtè%»»&ÚÝ#´ŠðÜžã§Í’¼{p·ß{m>ÞycP¨’¼¢0ú(Rƒë^Ž ñó¼(»y%m´ÕÙ}ÊûékB1¨þÑ®,#Q)ó‡o1T©ÜÃ*Ž‹‚yö<b‰4×H€“ìÐ.
¤²9ÌŠ>„Žãøgšñ
¯Š~)¸ßå\ÛÛoBŒa·L²œg$‚Iã¯ZÈ—Æ~%”äë—È8â)Œcƒ‘Âàu9¯b%)ÞS²¿Ïïÿ 4Öºù}Z/[H%¤vÉ#Ì’x§†b
© ³´tÜ{gn=iï%õªÇç]ܧ—!åw„SÓp ·VÈÏ¡?5Âcâb¥_ĤŠz¬—nàþÖΟñKÄöJé=ÌWèêT‹¸÷qÎჟ•q’zWUN«N/ØO^Ÿe|í¾©k{üõ4öV^ïù~G¹êzÂèº|·÷×[’Þ31†rpjg·n
Æ0Ý}kåË‹‰nîe¹ËÍ+™ÏVbrOç]'‰¼o®xÎh`¹Ç*±ÙÚ!T$d/$žN>¼WqᯅZ9ÑÒO\ÜÛê1o&,-z ~^NCgNÕéá)ÒÊ©7‰¨¯'Õþ¯þ_¿Ehîþóâ €ï¬uÛûý*ÎK9ä.â-öv<²‘×h$àãúW%ö¯~«g-ÕõÀàG~>Zú¾Iš+(šM³ Û#9äl%ðc¬ ûÝ xÖKG´x®|¸¤Ï™O:Ê8Ã’qÉcÔä‚yÇNJyËŒTj¥&µOmztjÿ ?KëaµÔù¯áýóXøãLeb¾tžAÇû`¨êGBAõ¾•:g˜’ù·,þhÀ`¬qÜ` e·~+å[±ý“âYÄjWì—µHé±ø?Nõô>½âX<5 Ç©ÏѼM¶8cܪXŽÉ^r?¼IróÈS•ZmÇ›™5»òÚÚ7ïu«&|·÷•Ά
>[©ÞXHeS$Œyà€ ÷ù²:ò2|óãDf? Z¼PD¶ÓßC(xÆ0|©ßR;ôMsÿ µ´ÔVi¬,͹›Ìxâi˜`¹,GAéÇlV§ÄýF×Yø§ê–‘:Ã=ò2³9n±ÉžØÏ@yÎWžæ±Ãàe„ÄÒN ]ïòêìú_Go'¦ŽÑ’_×õЯðR66þ!›ÑÄ gFMÙ— äžäqôÈ;ÿ eX<#%»Aö‰ãR¤ Í”Ž¹È G&¹Ÿƒ&á?¶Zˆ±keRè Kãnz·ãŠÕøÄÒÂ9j%@®×q±ÜŒý[õ-É$uíè&¤¶9zÇï·Oøï®ÄJKšÖìdü"µˆ[jײÎc;ã…B(g<9nàȯG½µŸPÓ.´Éfâ¼FŽP
31 ‘ÏR}<3šä~
Ã2xVöî Dr
Ç\›}Ý#S÷ÈÀëŽHÆI®à\OçKuäI¹†ó(”—GWî ñ³¹¸æ2¨›‹ºÚû%¾ýÖ_3ºNú¯ëúì|ÕÅÖ‰}ylM’ZËîTÿ á[ðÐñ/ˆ9Àû
¸ón3 Mòd‘÷ döª^.Êñް›BâîNp>cëÏçÍzïÃôÏ
YÍ%ª¬·ãÏ-*9ÜÂãhéŒc¾dÈêú¼Ë,. VŠ÷çeÿ n/¡¼äãõâ=‹xGQKx”|¹bÌŠD@2Œ 8'Ž àúƒŽ+áDÒ&¡¨"Œ§–Žr22 Ç·s]ŸÄ‹«ð%ÚÄ<¹ä’(×{e›HÀqÁç©Ç½`üŽÚõK饚9ƒÄ±€<–úƒú~ çðñO#Í%iKKlµ¦¾F)'Iê¬Î+Ç(`ñ¾£œdÈ’`™ºcßéé^ÿ i¸”Û\ý¡æhÔB«aq¸}ãÀÆ:ÜWƒ|FÛÿ BŒÇÀeaŸ-sÊ€:úW½ÜÝÜ<%$µ†%CóDªÀí%IÈÏʤ…ôäñÞŒ÷‘a0“ôŽÚë¤nŸoW÷0«e¶y'Å»aΗ2r’# Û°A^ý9ÉQÔõ=ù5¬£Öü.(Þ’M$~V«=éSÄFN½®©ÔWô»ÿ þHžkR‹ìÏ+µµžöê;khÚI¤m¨‹Ôš–âÖçJ¾_Z•’6a”Èô> ÕÉaÕ<%®£2n bQŠå\tÈõUÿ ø»þ‹k15‚ÃuCL$ݹp P1=Oøýs¯^u éEJ”–éêŸê½5ýzy›jÛ³á›Ûkÿ ÚOcn±ÛÏîW;boºz{ãžüVÆ¡a£a5½äÎÂks¸J@?1è¿{$ä‘=k”øsÖ^nŒ¦)ÝåXÃíùN1ØõÚOJë–xF÷h¸ Œ"Ž?x䜚ü³ì¨c*Fœ¯i;7~ñí׫Ðó¥Ë»3Ãü púw ‰°<Á%»ñž ÿ P+Û^ ¾Ye£ŽCÄŒ„/>˜>•á¶Ìm~&&À>M[hÈÈÿ [Ž•íd…RO@3^Ç(ʽ*¶ÖQZyßþ
1Vº}Ñç?¼O4Rh6R€ª£í¡ûÙ
a‚3ß·Õ
ü=mRÍ/µ9¤‚0ÑC¼Iè:cŽsÛ¾™x£ÆÐ¬ªÍöˢ샒W$•€Å{¨ÀPG
ÀÀàŸZìÍ1RÉ0´ðxEË9+Éÿ ^rEÕ—±Š„70l¼áË@û.' ¼¹Žz€N3úUÉ<3á×*?²¬‚ä†"Ùc=p íÛ'¡ª1ñ"økJ†HÒ'»Ÿ+
oÏN¬Ã9 dÙãÜדÏâÍ~æc+j·Jzâ7(£ðW]•æ™?nê´º6åwéåç÷N•ZŠíž›¬|?Ðõ?Ñ-E…®³ÇV$~X¯/…õ x‘LˆÑÜÚÈ7¦pzãÜüë½ðÄ^õtÝYËÍ7ÉÖÕ8ÏUe# #€r=sU¾/é’E§jRC4mxNÝ´9†íuá»›V‘
ZI€×cr1Ÿpzsøf»¨åV‹ìû`qËLÊIã?\~¼³áËC©êhªOîO»‘ÃmçÛçút×¢x“Z}?Üê#b-¤X7õÄò gž zzbº3œm*qvs·M=íúéw}¿&Úª°^Ö×µÏ(ø‡â†Öµƒenñý†×åQáYûœ÷ÇLœôÎNk¡ð‡¼/µ¸n0æÉ0¬ƒ‚üîÉÆvŒw®Sáö”š¯‹-üÕVŠØÙ[$`(9cqƒÔ_@BëqûÙ`Ýæ0;79È?w<ó |ÙÜkßÌ1±Ëã¿ìÒ»ðlìï«ÓnªèèrP´NÏš&ŽéöÙ¸÷æ°~-_O'‰`°!RÚÚÝ%]Ø%þbß1'¿ÿ XÕáOöÎŒ·‹¬+Åæ*ÛÛ™0¤ƒOÍÔ`u¯¦ÂaèÐÃÓ«‹¨Ô¥µœ¿¯ÉyÅÙ.oÔôŸ Úx&(STðݽ¦õ] ’ÒNóÁäÈùr3í·žÚ[™ƒ¼veÈ÷ÞIõÎGlqÎ=M|«gsªxÅI6
]Z·Îªä,¨zŒŽÄ~#ØŠúFñiÉqc©éÐD>S딑 GñŽ1éÐ^+
Ëi;Ô„µVÕú»i¯ÈÒ-ZÍ]òܘ®ì`bÛÙ¥_/y(@÷qÐúg Ô÷W0.Ø›
6Ò© r>QƒŒ0+Èîzb¨É+I0TbNñ"$~)ÕÒ6Þ‹{0VÆ27œWWñcÄcX×íôûyKZéðªc'iQ¿¯LaWŠŸS\·Š“źʸ…ôÙÂí|öÀÇåV|!¤ÂGâÛ[[’ï
3OrÙËPY¹=Î1õ5öåTžÑè Ú64/üö?Zëžk}¬¶éàoá¾á}3“ü]8Éæ¿´n²Žš_6¾pœ)2?úWÓÚ¥¾¨iWúdŽq{*ª1rXŒd…m»‰äcô¯–dâ•ã‘Jº¬§¨#¨®§,df«8ÉÅßN¾hˆ;îÓ=7áùpën®É 6ûJžO2^œÐò JÖø¥²ã›Ò6Ü·‰!wbÍ‚¬O©»õ¬ÿ ƒP=Ä:â¤-&ÙŽ
`È9 r9íϧzë> XÅ7ƒ5X–krÑ¢L7€ìw}ÑŸNHëŒüþ:2†á¼+u·á÷N/Û'Ðç~ߘô«ëh!ónRéeQ´6QÛÿ èEwëÅÒ|¸Yqó1uêyùzð8 ƒŠù¦Ò;¹ä6öi<'ü³„[ÃZhu½ ùÍ¡g‚>r¯×ŠîÌx}bñ2“k꣧oø~›hTèóËWò4|ki"xßQ˜Ï6øÀLnß‚0 ¹Æ{±–¶Öe#¨27È@^Ìß.1N¾œyç€õ†ñeé·Õã†çQ°€=Ì©ºB€Ø8<‚ÃSõ®ùcc>×Ú .Fr:žÝGæ=kÁâ,^!Fž
¬,àµ}%¶«îõ¹†"r²ƒGœüYÕd?aÑÃY®49PyU ÷þ!žxÅm|/‚ãNð˜¼PcûTÒ,¹/Ý=FkÏ|u¨¶«âë…{¤m¢]Û¾ïP>®XãÞ½iÓÁ¾
‰'¬–6ß¼(„ï— í!úÙäzôë^–:œ¨å|,_¿&š×]uÓѵÛô4’j”bž§x‘Æ©ã›á,‚[Ô
ÎÞ= ŒËæ ÀùYÁ?ŽïÚ¼?ÁªxºÕÛ,°1¸‘¿ÝäãØ¯v…@¤åq½ºã œàûââ·z8Xýˆþz~—û»™âµj=Ž
â~ãáh@'h¼F#·Üp?ŸëQü-løvépx»cŸø…lxâÃûG·‰¶ø”L£©%y?¦úõÆü-Õ¶¥y`Òl7>q’2üA?•F}c‡jB:¸Jÿ +§¹¿¸Q÷°ív=VÑìu[Qml%R7a×IèTõéŽx¬
?†š7
1†îã-ˆã’L¡lŽ0OÓ=ÅuˆpÇ•¼3ÛùÒ¶W/!|’wŽw^qÔ×ÏaóM8Q¨ãÑ?ëï0IEhÄa¸X•`a
?!ÐñùQ!Rä žqŽžÝO`I0ÿ J“y|ñ!Îã@99>þ8–+éáu…!ù—ä
ʰ<÷6’I®z
ÅS„¾)Zþ_Öýµ×ËPåOwø÷þ*üïænÖùmØÝûþ¹=>¦½öî×Jh]¼ç&@§nTŒ6ITÀõ^Fxð7Å3!Ö·aÛ$þÿ ¹ã5îIo:ȪmËY[’8ÇӾlj*òû¢¥xõ¾¼ú•åk+\ð¯ HÚoŽl•Ûk,¯ ç²²cõÅ{²Z\
´ìQ åpzŽ3Ôð}ÿ Jð¯XO¡øÎé€hÙ¥ûLdŒ`““ù6Gá^ÃáÝ^Ë[Ñb¾YåŒÊ»dŽ4†2§,;ÿ CQÄ´¾°¨c–±”mºV{«ßÕýÄW\ÖŸ‘çŸ,çMRÆí“l-ƒn~ë©ÉÈê Ü?#Ž•¹ðãSÒ¥ÐWNíà½;ãž)™ÎSÈ9cóLj뵿ūiÍk¨ió¶X‚7÷ƒ€yãnyÏŽëÞ Öt`×À×V's$È9Ú:ä{wÆEk€«†Çàc—â$éÎ.éí~Ýëk}ÅAÆpörÑ¢‡Šl¡ÑüSs‹¨‰IÄóÀ×wñ&eºðf™pŒÆ9gŽTø£lñëÀçŽ NkÊUK0U’p ï^¡ãÈ¥´ø{£ÙHp`’ØåbqÏ©äó^Æ:
Ž' ÊóM«õz+ß×ó5Ÿ»('¹ð¦C„$˜Å¢_ºÈI?»^äã'ñêzž+ë€ñ-½»´}¡Ë*õ?.xÇ^1ŽMyǸ&“—L–îëöâ7…' bqéÎGé]˪â1$o²¸R8Ã`.q€}sÖ¾C98cêÆÞíïóòvÓòùœÕfÔÚéýuèÖ·Ú
Å‚_¤³ÜۺƑß”àרý:׃xPþÅÕî-/üØmnQìïGΊÙRqê=>¢½õnæ·r!—h`+’;ò3È<“Û©éšóŸx*÷V¹¸×tÈiˆßwiÔÿ |cŒñÏ®3ֽ̰‰Ë Qr©ö½®¼ÛoÑÙZÅÑ«O൯ýw8;k›ÿ x†;ˆJa;‘º9÷÷R+¡ñgŽí|Iáë{ôáo2ʲ9 029ÉÏLí\‰¿¸Ÿb˜ "Bv$£ßiê>=ªª©f
’N ëí>¡NXW~5×úíø\‰»½Ï^ø(—wÖú¥¤2íŽÞXæÁ$°eÈ888^nÝë²ñÝÔ^ ÖÚ9Q~Ëå7ï
DC¶ÑµƒsËÇè9®Wáþƒ6‡£´·°2\Ý:ÈÑ?(#¨'$õèGJ¥ñW\ÿ ‰E¶—¸™g˜ÌÀ¹;Pv ú±ÎNs·ëŸ’–"Ž/:té+ûË]öJöÓM»ëø˜*‘•^Uý—êd|‰åñMæÔÝ‹23å™6æHùÛ‚ëüñ^…ñ1¢oêûÑEØ.õ7*ÅHtÎp{g<·Á«+¸c¿¿pÓ¾Æby=8É_ÄsÆk¬ñB\jÞÔì••Ë[9Píb‹Bヅ =93§ð§LšÛáÖšÆæXÌÞdÛP.0\ãïÛ0?™úJ¸™Ë
”•œº+=<µI£¦í¯õêt¬d‹T¬P=ËFêT>ÍØØ@Ï9<÷AQÌ×»Õ¡xùk",JÎæù±Éç$œŽŸZWH®¯"·UÌQ ’ÙÈ]ÅXg<ã
ߨg3-Üqe€0¢¨*Œ$܃
’Sû 8㎼_/e'+Ï–-èÓ¶¶Õíß[·ÙÙ½îì—¼sk%§µxä‰â-pÒeÆCrú
ôσžû=”šÅô(QW‚Õd\ƒæ. \àö¹¯F½°³½0M>‘gr÷q+œ¶NïºHO— ¤ ܥݔn·J|ÆP6Kµc=Isó}Ò çGš)a=—#vK›åoK§ßóÙ¤¶¿õú…ÄRÚ[ËsöÙ¼Ë•Ë ópw®qœŒ·Ø
ùÇâ‹ý‡ãKèS&ÞvûDAù‘É9ŒîqÅ}
$SnIV[]Ñ´Ó}ØÜ¾A Ü|½kÅþÓ|EMuR¼.I¼¶däò‚ÃkÆ}ðy¹vciUœZ…Õõ»z¾÷¿n¦*j-É/àœHã\y5 Û ß™ó0—äŸnzôã#Ô¯,†¥ÚeÔ÷ÜÅ´„“'c…<íÝ€<·SŠ¥k§Ã¢éÆÆÙna‚8–=«Êª[Ÿ™°pNî02z“ÔÙ–K8.È’Þî(vƒ2®@ äÈûãçžxäÇf¯ˆu¹yUÕîýWšÙ|›ëÒ%Q^í[æ|éo5ZY•^{96ˆY‚§v*x>âº_|U¹Ö´©tûMÒÂ9PÇ#«£#€ éÉñ‘ƒÍz/‰´-į¹°dd,Б›p03ƒœ{ç9=+
Ûᧇ¬¦[‡‚ê婺¸#±ß=³ý¿•Õµjñ½HÙh›Û[§ÚýÊöô÷{˜?ô÷·Ô.u©–_%còcAÀ˜’
}0x9Î>žñÇáÍ9,ahï¦Ì2òÓ ñÛAäry$V²Nð
]=$Ž
‚#Ù‚1ƒƒødõMax‡ÂÖ^!±KkÛ‘
«“Çó²FN8+ëÎ{Ò¼oí§[«ÕMRoËeç×[_m/¦¦k.kôgŽxsSÓ´ý`êzªÜÜKo‰cPC9ÎY‰#§^üý9¹âïÞx£Ë·Ú`±‰‹¤;³–=ÏaôÕAð‚÷kêÁNBéÎælcõö®£Fð†ô2Ò¬]ßÂK$ÓÜ®•”/ÊHàã$ä¸÷ëf¹Oµúâ“”’²øè´µþöjçNü÷üÌ¿ xNïFÒd»¼·h®îT9ŽAµÖ>qÁçÔœtïÒ»\ȶÎîcÞäîó3¶@#ÉIÎ ÔñW.<´’¥–ÑÑ€ÕšA‚ ;†qÓë‚2q
ÒÂó$# Çí‡
!Ë}Õ9ÈÎÑÉã=;ŒÇÎuñ+ÉûÏ¥öíeÙ+$úíÜ娯'+êZH4ƒq¶FV‹gïŒ208ÆÌ)íб>M|÷âÍã¾"iì‹¥£Jd´™OÝç;sÈúr+ÜäˆË)DŒ¥šF°*3Õ”d{zÔwºQ¿·UžÉf†~>I+ŒqÔ`ð3œ“Ü×f]œTÁÔn4“ƒø’Ýßõ_«*5šzGCÊ,þ+ê1ò÷O¶¸cœºb2yÇ;cùÕ£ñh¬›áÑŠr¤ÝäNBk¥—á—†gxšX/쑘hŸ*Tçn =ûã¦2|(ð¿e·ºÖ$
ýìŸ!'åΰyîî+×öœ=Y:²¦ÓÞ×iü’—ü
-BK™£˜›âÆ¡&véðõ-ûÉY¹=Onj¹ø¯¯yf4·±T Pó`çœ7={×mÃ/¢˜ZÚòK…G½¥b„’G AãÜœ*í¯Ã¿ IoæI¦NU8‘RwÈã;·€ Û×ëÒ”1Y
•£E»ÿ Oyto¢<£Áö·šï,䉧ûA¼sû»Nò}¹üE{ÜÖªò1’õÞr0â}ÎØ#>à/8ïéÎ~—áÍ#ñÎlí§³2f'h”?C÷YËdð:qëõÓ·‚ïeÄ©
ÔÈØÜRL+žAÎ3¼g=åšó³Œt3
ÑQ¦ùRÙßE®¼±w_;þhš’Sirÿ ^ˆã¼iੇ|RòO„m°J/“$·l“ ÇÓ¿ÿ [ÑŠÆ“„†Õø>cFÆ6Ø1ƒ– àz7Ldòxäüwá‹ÝAXùO•Úý’é®ähm •NÀ±ÌTÈç
ƒ‘I$pGž:‚ÄbêW¢®œ´|¦nÍ>¶ÖÏ¢§ÎÜ¢ºö¹•%ÄqL^öÛKpNA<ã¡ …î==ª¸óffËF‡yÌcÉ ©ç$ð=ñÏYþÊ’Ú]—¥‚¬‚eDïÎH>Ÿ_ÌTP™a‰ch['çÆÜò7a‡?w°Ïn§âÎ5”’¨¹uÚÛ|´ÓÓc§{O—ü1•ªxsÃZ…ÊÏy¡Ã3¸Ë2Èé» ‘ƒÎ äžÜðA§cáOéúÛ4ý5-fŒï„ù¬ûô.Ç Üsž•Ò¾•wo<¶Ÿ"¬¡º|£
î2sÇ¡éE²ÉFѱrU°dÜ6œ¨ mc†Îxë׺Þ'0²¡Rr„{j¾í·è›µ÷)º·å–‹î2|I®Y¼ºÍË·–ÃÆàã£'óÆxƒOÆÞ&>\lóÌxP Xc¸ì Sþ5§qà/ê>#žÞW¸if$\3 ® ûÄ“ùŽÕê¾ð<Ó‹H¶óÏ" å·( á‘€:ã†8Ï=+ꨬUA×ÃËÚT’ÑÞöù¥¢]{»ms¥F0\ÑÕ—ô}&ÛB´ƒOŽÚ+›xíÄÀ1
,v± žIëíZ0ǧ™3í2®0ทp9öÝÔž)ÓZËoq/Ú“‘L ²ŒmùŽï‘Ó9§[Û#Ä‘\ÞB¬Çs [;à à«g‚2ôòªœÝV§»·¯/[uó½õÛï¾
/šÍ}öüÿ «=x»HŸÂÞ.™ ÌQùŸh´‘#a$‚'¡u<Š›Æ>2>+ƒLSiöwµFó1!eg`£åœ ÷ëÛö}Á¿ÛVÙêv $¬ƒ|,s÷z€ð΃¨x÷ÅD\ÜŒÞmåÔ„ ˆ o| :{ÇÓ¶–òÁn!´0Ål€, ƒ ( ÛŒŒc¶rsšæ,4‹MÛOH!@¢ ÇŽ„`å²9ÝÃw;AÍt0®¤¡…¯ØÄ.Àìí´ƒ‘ßñ5Í,Óëu-ÈÔc¢KÃÓ£òÖ̺U.õL¯0…%2È—"~x
‚[`có±nHàŽyàö™¥keˆìŒÛFç{(Ø©†`Jã#Žwg<“:ÚÉ;M
^\yhûX‡vB·÷zrF?§BÊÔ/s<ÐÈB)Û± ·ÍÔwç5Âã:så§e{mѤï«Òíh—]Wm4âí¿ùþW4bC3¶ª¾Ùr$pw`àädzt!yŠI„hÂîàM)!edŒm'æ>Ç?wzºKìcŒ´¯Ìq6fp$)ãw¡éUl`µ»ARAˆÝÕgr:äŒgƒéé[Ôö±”iYs5Ýï«ÙG—K=þF’æMG«óÿ `ŠKɦuOQ!ÕåŒ/ÎGÞ`@ËqÕzdõâ«Ê/Ö(ƒK´%ŽbMüåÜŸö—>¤óŒŒV‘°„I¢Yž#™¥ùÏÊ@8
œgqöö5ª4vד[¬(q cò¨À!FGaÁõõ¯?§†¥ÏU½í¿WªZ$úyú½Žz×§Éþ?>Ã×È•6°{™™ŽÙ.$`ÎUœ…çè ' ¤r$1Ø(y7 ðV<ž:È ÁÎMw¾Â'Øb§øxb7gãО½óÉÊë²,i„Fȹ£§8ãä½k¹¥¦ê/ç{ïê驪2œ/«ü?¯Ô›ìñÜ$þeýœRIåŒg9Ác’zrrNO bÚi¢
ѺË/$,“ª¯Ýä;Œ× ´<ÛÑn³IvŸb™¥ nm–ÄŸ—nÝÀãŽ3ëÍG,.öó³˜Ù£¹uÊÌrŠ[<±!@Æ:c9ÅZh
ì’M5ÄìÌ-‚¼ëÉùqŽGì9¬á ;¨A-ž—évþÖ–^ON·Ô”ŸEý}ú×PO&e[]ÒG¸˜Ûp ƒÃà/Ë·8ûÀ€1ž@¿ÚB*²¼ñì8@p™8Q“žÆH'8«I-%¸‚
F»“åó6°Uù|¶Ú¸ã ò^Äw¥ŠÖK–1ÜÝK,Žddlí²0PÀü“×ükG…¯U«·¶–´w¶ŽÍ¾©yÞú[Zös•¯Á[™6°
¨¼ÉVæq·,#
ìãï‘×8îry®A››¨,ãc66»Ë´ã'æÉù?t}¢æH--Òá"›|ˆ¬[í 7¶ö#¸9«––‹$,+Ëqœ\Êøc€yê^ݸÄa°«™B-9%«×®‹V´w~vÜTéꢷþ¼ˆ%·¹• ’[xç•÷2gØS?6åÀÚ õ9É#š@÷bT¸º²C*3Bá¤òÎA9 =úU§Ó"2Ãlá0iÝIc‚2Î@%öç94ùô»'»HÄ¥Ô¾@à Tp£šíx:úÊ:5eºßMý×wµ›Ó_+šº3Ýyvÿ "ºÇ<ÂI>Õ1G·Ë«È«É# àÈÇ øp Jv·šæDûE¿›†Ë’NFr2qŸ½ÇAÜšu•´éí#Ħ8£2”Ú2Ã/€[ÎTr;qŠz*ý’Îþ(≠;¡TÆâ›;ºÿ àçœk‘Þ8¾Uª¾íé{^×IZéwÓkXÉûÑZo¯_øo×È¡¬ â–ÞR§2„‚Àœü½ùç® SVa†Âüª¼±D‘ŒísŸàä|ä2 æ[‹z”¯s{wn„ÆmáóCO+†GO8Ïeçåº`¯^¼ðG5f{Xžä,k‰<á y™¥voÆ éÛõëI=œ1‹éíÔÀÑ)R#;AÂncäŽ:tÏ#¶TkB.0Œ-ÖÞZÛgumß}fÎJÉ+#2êÔP£žùÈÅi¢%œ3P*Yƒò‚A쓎2r:ƒÐúñiRUQq‰H9!”={~¼“JŽV¥»×²m.ÛߺiYl¾òk˜gL³·rT•
’…wHÁ6ä`–Î3ùÌ4Øe³†&òL‘•%clyîAÂäà0 žüç$[3uŘpNOÀÉ=† cï{rYK
ååä~FÁ
•a»"Lär1Ó¯2Äõæ<™C•.fÕ»è¥~½-¿g½Â4¡{[ør¨¶·Žõäx¥’l®qpwÇ»8ärF \cޏܯÓ-g‚yciÏÀ¾rÎwèØÈ#o°Á9ã5¢šfÔxÞæfGusÏÌJÿ µ×œ/LtãÅT7²¶w,l
ɳ;”eúà·¨çîŒsÜgTÃS¦^ '~‹®›¯+k÷ZÖd©Æ*Ó[Ü«%Œk0ŽXƒ”$k#Ȩ P2bv‘ƒŸáÇ™ÆÕb)m$É*8óLE‘8'–ÜN Úyàúô+{uº±I'wvš4fÜr íì½=úuú
sFlìV$‘ö†HÑù€$§ õ=½¸«Ž]
:Ž+•¦ïmRþ½l´îÊT#nkiøÿ _ðÆT¶7Ò½ºÒ£Î¸d\ã8=yãŽÜäR{x]ZâÚé#¸r²#»ÎHÆ6õ ç® ÎFkr;sºÄ.&;só±Ç9êH÷ýSšÕtÐU¢-n Ì| vqœ„{gŒt§S.P‹’މ_[;m¥ÞZýRûÂX{+¥úü¼ú•-àÓ7!„G"“´‹žƒnrYXã¸îp éœ!ÓoPÌtÑ (‰Þ¹é€sÓ#GLçÕšÑnJý¡!‘Tä#“ß?îýp}xÇ‚I¥Õn#·¸–y'qó@r[ Êô÷<ÔWÃÓ¢áN¥4Ô’I&ݼ¬¬¼ÞºvéÆ
FQV~_ÒüJÖÚt¥¦Xá3BÄP^%ÈÎW-×c¡ú©¤·Iþèk¥š?–UQåIR[’O 5x\ÉhÆI¶K4«2ùªŠŒ<¼óœçØ`u«‚Í.VHä€ Ëgfx''9ÆI#±®Z8
sISºku¢ßÞ]úk»Jößl¡B.Ü»ÿ MWe
°·Ž%šêɆ¼»Âù³´œ O¿cÐÓÄh©"ÛÜÏ.ÖV’3nüÄmnq[ŒòznšÖ>J¬òˆæ…qýØP Ž:ä7^0yëWšÍ_79äoaÈ °#q0{ää×mœy”R{vÒÞ¶ÚÏe¥“ÚÆÐ¥Ì®—õýjR •íç›Ìb„+JyÜØÙ•Ç]¿Ôd þËOL²”9-Œ—õÃc'æÝלçÚ²ìejP“½
âù°¨†ðqòädЃÉäÖÜj÷PÇp“ÍšŠå«‘î
<iWNsmª»¶vÓz5»ûì:Rs\Ðßôû×uÔÿÙ