Blob Blame History Raw
commit 85f0beed719cf123eebcf705ffa24ef7f13a4442
Author: Jiri Popelka <jpopelka@redhat.com>
Date:   Thu Feb 6 19:52:20 2014 +0100

    if Python2 then encode strings from sax parser (RHBZ#1059104,RHBZ#1058853)
    
    this kinda reverts 0a6900516f, but should be Python 2 & 3 compatible

diff --git a/src/firewall/core/io/direct.py b/src/firewall/core/io/direct.py
index 0f786a7..7d15987 100644
--- a/src/firewall/core/io/direct.py
+++ b/src/firewall/core/io/direct.py
@@ -106,7 +106,7 @@ class Direct(IO_Object):
 
     IMPORT_EXPORT_STRUCTURE = (
         # chain: [ ipv, table, [ chain ] ]
-        ( "chains", [ ( "", "", "" ), ], ),                   # a(ssas)
+        ( "chains", [ ( "", "", "" ), ], ),                   # a(sss)
         # rule: [ ipv, table, chain, [ priority, [ arg ] ] ]
         ( "rules", [ ( "", "", "", 0, [ "" ] ), ], ),         # a(sssias)
         # passthrough: [ ipv, [ [ arg ] ] ]
diff --git a/src/firewall/core/io/icmptype.py b/src/firewall/core/io/icmptype.py
index ab42313..a3ef5e4 100644
--- a/src/firewall/core/io/icmptype.py
+++ b/src/firewall/core/io/icmptype.py
@@ -26,7 +26,7 @@ import shutil
 
 from firewall.config import ETC_FIREWALLD
 from firewall.errors import *
-from firewall import functions
+from firewall.functions import u2b_if_py2
 from firewall.core.io.io_object import *
 from firewall.core.logger import log
 
@@ -59,9 +59,18 @@ class IcmpType(IO_Object):
     def cleanup(self):
         self.version = ""
         self.short = ""
-        self.description = ""        
+        self.description = ""
         del self.destination[:]
 
+    def encode_strings(self):
+        """ HACK. I haven't been able to make sax parser return
+            strings encoded (because of python 2) instead of in unicode.
+            Get rid of it once we throw out python 2 support."""
+        self.version = u2b_if_py2(self.version)
+        self.short = u2b_if_py2(self.short)
+        self.description = u2b_if_py2(self.description)
+        self.destination = [u2b_if_py2(m) for m in self.destination]
+
     def _check_config(self, config, item):
         if item == "destination":
             for destination in config:
@@ -107,6 +116,8 @@ def icmptype_reader(filename, path):
         parser.parse(f)
     del handler
     del parser
+    if PY2:
+        icmptype.encode_strings()
     return icmptype
 
 def icmptype_writer(icmptype, path=None):
diff --git a/src/firewall/core/io/lockdown_whitelist.py b/src/firewall/core/io/lockdown_whitelist.py
index 7cc416c..6221eeb 100644
--- a/src/firewall/core/io/lockdown_whitelist.py
+++ b/src/firewall/core/io/lockdown_whitelist.py
@@ -28,7 +28,7 @@ from firewall.errors import *
 from firewall.core.io.io_object import *
 from firewall.core.logger import log
 from firewall.functions import uniqify, checkUser, checkUid, checkCommand, \
-    checkContext
+                               checkContext, u2b_if_py2
 
 class lockdown_whitelist_ContentHandler(IO_Object_ContentHandler):
     def __init__(self, item):
@@ -138,6 +138,14 @@ class LockdownWhitelist(IO_Object):
 #        del self.gids[:]
 #        del self.groups[:]
 
+    def encode_strings(self):
+        """ HACK. I haven't been able to make sax parser return
+            strings encoded (because of python 2) instead of in unicode.
+            Get rid of it once we throw out python 2 support."""
+        self.commands = u2b_if_py2(self.commands)
+        self.contexts = u2b_if_py2(self.contexts)
+        self.users = u2b_if_py2(self.users)
+
     # commands
 
     def add_command(self, command):
@@ -297,6 +305,8 @@ class LockdownWhitelist(IO_Object):
         parser.parse(self.filename)
         del handler
         del parser
+        if PY2:
+            self.encode_strings()
 
     def write(self):
         if os.path.exists(self.filename):
diff --git a/src/firewall/core/io/service.py b/src/firewall/core/io/service.py
index 1ff161c..b56550a 100644
--- a/src/firewall/core/io/service.py
+++ b/src/firewall/core/io/service.py
@@ -26,7 +26,8 @@ import shutil
 
 from firewall.config import ETC_FIREWALLD
 from firewall.errors import *
-from firewall import functions
+from firewall.functions import checkProtocol, check_address, \
+                               checkIPnMask, checkIP6nMask, u2b_if_py2
 from firewall.core.io.io_object import *
 from firewall.core.logger import log
 
@@ -70,6 +71,17 @@ class Service(IO_Object):
         del self.modules[:]
         self.destination.clear()
 
+    def encode_strings(self):
+        """ HACK. I haven't been able to make sax parser return
+            strings encoded (because of python 2) instead of in unicode.
+            Get rid of it once we throw out python 2 support."""
+        self.version = u2b_if_py2(self.version)
+        self.short = u2b_if_py2(self.short)
+        self.description = u2b_if_py2(self.description)
+        self.ports = [(u2b_if_py2(po),u2b_if_py2(pr)) for (po,pr) in self.ports]
+        self.modules = [u2b_if_py2(m) for m in self.modules]
+        self.destination = {u2b_if_py2(k):u2b_if_py2(v) for k,v in self.destination.items()}
+
     def _check_config(self, config, item):
         if item == "ports":
             for port in config:
@@ -78,14 +90,14 @@ class Service(IO_Object):
                     check_protocol(port[1])
                 else:
                     # only protocol
-                    if not functions.checkProtocol(port[1]):
+                    if not checkProtocol(port[1]):
                         raise FirewallError(INVALID_PROTOCOL, port[1])
 
         elif item == "destination":
             for destination in config:
                 if destination not in [ "ipv4", "ipv6" ]:
                     raise FirewallError(INVALID_DESTINATION, destination)
-                if not functions.check_address(destination, config[destination]):
+                if not check_address(destination, config[destination]):
                     raise FirewallError(INVALID_ADDR, config[destination])
 
 # PARSER
@@ -109,9 +121,9 @@ class service_ContentHandler(IO_Object_ContentHandler):
             for x in [ "ipv4", "ipv6" ]:
                 if x in attrs:
                     s = attrs[x]
-                    if x == "ipv4" and not functions.checkIPnMask(s):
+                    if x == "ipv4" and not checkIPnMask(s):
                         raise FirewallError(INVALID_DESTINATION, s)
-                    if x == "ipv6" and not functions.checkIP6nMask(s):
+                    if x == "ipv6" and not checkIP6nMask(s):
                         raise FirewallError(INVALID_DESTINATION, s)
                     self.item.destination[x] = attrs[x]
         elif name == "module":
@@ -134,6 +146,8 @@ def service_reader(filename, path):
         parser.parse(f)
     del handler
     del parser
+    if PY2:
+        service.encode_strings()
     return service
 
 def service_writer(service, path=None):
diff --git a/src/firewall/core/io/zone.py b/src/firewall/core/io/zone.py
index 8783dc6..b0d5ca2 100644
--- a/src/firewall/core/io/zone.py
+++ b/src/firewall/core/io/zone.py
@@ -25,7 +25,7 @@ import shutil
 
 from firewall.config import ETC_FIREWALLD
 from firewall.errors import *
-from firewall.functions import checkIP, uniqify, max_zone_name_len
+from firewall.functions import checkIP, uniqify, max_zone_name_len, u2b_if_py2
 from firewall.core.base import DEFAULT_ZONE_TARGET, ZONE_TARGETS
 from firewall.core.io.io_object import *
 from firewall.core.rich import *
@@ -123,9 +123,25 @@ class Zone(IO_Object):
         del self.sources[:]
         self.fw_config = None # to be able to check services and a icmp_blocks
         del self.rules[:]
-        self.combined = False        
+        self.combined = False
         self.applied = False
 
+    def encode_strings(self):
+        """ HACK. I haven't been able to make sax parser return
+            strings encoded (because of python 2) instead of in unicode.
+            Get rid of it once we throw out python 2 support."""
+        self.version = u2b_if_py2(self.version)
+        self.short = u2b_if_py2(self.short)
+        self.description = u2b_if_py2(self.description)
+        self.target = u2b_if_py2(self.target)
+        self.services = [u2b_if_py2(s) for s in self.services]
+        self.ports = [(u2b_if_py2(po),u2b_if_py2(pr)) for (po,pr) in self.ports]
+        self.icmp_blocks = [u2b_if_py2(i) for i in self.icmp_blocks]
+        self.forward_ports = [(u2b_if_py2(p1),u2b_if_py2(p2),u2b_if_py2(p3),u2b_if_py2(p4)) for (p1,p2,p3,p4) in self.forward_ports]
+        self.interfaces = [u2b_if_py2(i) for i in self.interfaces]
+        self.sources = [u2b_if_py2(s) for s in self.sources]
+        self.rules = [u2b_if_py2(s) for s in self.rules]
+
     def __getattr__(self, name):
         if name == "rules_str":
             rules_str = [str(rule) for rule in self.rules]
@@ -482,6 +497,8 @@ def zone_reader(filename, path):
         parser.parse(f)
     del handler
     del parser
+    if PY2:
+        zone.encode_strings()
     return zone
 
 def zone_writer(zone, path=None):
diff --git a/src/firewall/functions.py b/src/firewall/functions.py
index fc70179..6dd4240 100644
--- a/src/firewall/functions.py
+++ b/src/firewall/functions.py
@@ -401,11 +401,17 @@ def splitArgs(string):
 def b2u(string):
     """ bytes to unicode """
     if isinstance(string, bytes):
-        return string.decode('utf-8', 'replace')
+        return string.decode('UTF-8', 'replace')
     return string
 
 def u2b(string):
     """ unicode to bytes """
     if not isinstance(string, bytes):
-        return string.encode('utf-8', 'replace')
+        return string.encode('UTF-8', 'replace')
+    return string
+
+def u2b_if_py2(string):
+    """ unicode to bytes only if Python 2"""
+    if PY2 and isinstance(string, unicode):
+            return string.encode('UTF-8', 'replace')
     return string