Remove Python 2 support.

This commit is contained in:
Mark Grassi 2022-06-28 21:08:50 -04:00
parent 43f419458e
commit df97cf89bd
37 changed files with 146 additions and 319 deletions

View file

@ -1,6 +1 @@
import sys
if sys.version_info[0] >= 3:
from LibAppArmor.LibAppArmor import *
else:
from .LibAppArmor import *
from LibAppArmor.LibAppArmor import *

View file

@ -17,7 +17,6 @@
from argparse import ArgumentParser
import os
import platform
import shutil
import time
import tempfile
@ -147,9 +146,6 @@ class AAParserCachingCommon(testlib.AATestTemplate):
class AAParserBasicCachingTests(AAParserCachingCommon):
def setUp(self):
super(AAParserBasicCachingTests, self).setUp()
def test_no_cache_by_default(self):
'''test profiles are not cached by default'''
@ -201,7 +197,7 @@ class AAParserAltCacheBasicTests(AAParserBasicCachingTests):
'''Same tests as above, but with an alternate cache location specified on the command line'''
def setUp(self):
super(AAParserAltCacheBasicTests, self).setUp()
super().setUp()
alt_cache_loc = tempfile.mkdtemp(prefix='aa-alt-cache', dir=self.tmp_dir)
os.chmod(alt_cache_loc, 0o755)
@ -213,14 +209,14 @@ class AAParserAltCacheBasicTests(AAParserBasicCachingTests):
def tearDown(self):
if len(os.listdir(self.unused_cache_loc)) > 0:
self.fail('original cache dir \'%s\' not empty' % self.unused_cache_loc)
super(AAParserAltCacheBasicTests, self).tearDown()
super().tearDown()
class AAParserCreateCacheBasicTestsCacheExists(AAParserBasicCachingTests):
'''Same tests as above, but with create cache option on the command line and the cache already exists'''
def setUp(self):
super(AAParserCreateCacheBasicTestsCacheExists, self).setUp()
super().setUp()
self.cmd_prefix.append('--create-cache-dir')
@ -228,7 +224,7 @@ class AAParserCreateCacheBasicTestsCacheNotExist(AAParserBasicCachingTests):
'''Same tests as above, but with create cache option on the command line and cache dir removed'''
def setUp(self):
super(AAParserCreateCacheBasicTestsCacheNotExist, self).setUp()
super().setUp()
shutil.rmtree(self.cache_dir)
self.cmd_prefix.append('--create-cache-dir')
@ -238,7 +234,7 @@ class AAParserCreateCacheAltCacheTestsCacheNotExist(AAParserBasicCachingTests):
alt cache specified, and cache dir removed'''
def setUp(self):
super(AAParserCreateCacheAltCacheTestsCacheNotExist, self).setUp()
super().setUp()
shutil.rmtree(self.cache_dir)
self.cmd_prefix.append('--create-cache-dir')
@ -246,7 +242,7 @@ class AAParserCreateCacheAltCacheTestsCacheNotExist(AAParserBasicCachingTests):
class AAParserCachingTests(AAParserCachingCommon):
def setUp(self):
super(AAParserCachingTests, self).setUp()
super().setUp()
r = testlib.filesystem_time_resolution()
self.mtime_res = r[1]
@ -258,24 +254,10 @@ class AAParserCachingTests(AAParserCachingCommon):
self.run_cmd_check(cmd)
self.assert_path_exists(self.cache_file)
def _assertTimeStampEquals(self, time1, time2):
'''Compare two timestamps to ensure equality'''
# python 3.2 and earlier don't support writing timestamps with
# nanosecond resolution, only microsecond. When comparing
# timestamps in such an environment, loosen the equality bounds
# to compensate
# Reference: https://bugs.python.org/issue12904
(major, minor, _) = platform.python_version_tuple()
if (int(major) < 3) or ((int(major) == 3) and (int(minor) <= 2)):
self.assertAlmostEquals(time1, time2, places=5)
else:
self.assertEqual(time1, time2)
def _set_mtime(self, path, mtime):
atime = os.stat(path).st_atime
os.utime(path, (atime, mtime))
self._assertTimeStampEquals(os.stat(path).st_mtime, mtime)
self.assertEqual(os.stat(path).st_mtime, mtime)
def test_cache_loaded_when_exists(self):
'''test cache is loaded when it exists, is newer than profile, and features match'''
@ -458,7 +440,7 @@ class AAParserCachingTests(AAParserCachingCommon):
stat = os.stat(self.cache_file)
self.assertNotEqual(orig_stat.st_ino, stat.st_ino)
self._assertTimeStampEquals(profile_mtime, stat.st_mtime)
self.assertEqual(profile_mtime, stat.st_mtime)
def test_abstraction_newer_rewrites_cache(self):
'''test cache is rewritten if abstraction is newer'''
@ -475,7 +457,7 @@ class AAParserCachingTests(AAParserCachingCommon):
stat = os.stat(self.cache_file)
self.assertNotEqual(orig_stat.st_ino, stat.st_ino)
self._assertTimeStampEquals(abstraction_mtime, stat.st_mtime)
self.assertEqual(abstraction_mtime, stat.st_mtime)
def test_parser_newer_uses_cache(self):
'''test cache is not skipped if parser is newer'''
@ -521,7 +503,7 @@ class AAParserAltCacheTests(AAParserCachingTests):
check_orig_cache = True
def setUp(self):
super(AAParserAltCacheTests, self).setUp()
super().setUp()
alt_cache_loc = tempfile.mkdtemp(prefix='aa-alt-cache', dir=self.tmp_dir)
os.chmod(alt_cache_loc, 0o755)
@ -534,7 +516,7 @@ class AAParserAltCacheTests(AAParserCachingTests):
def tearDown(self):
if self.check_orig_cache and len(os.listdir(self.orig_cache_dir)) > 0:
self.fail('original cache dir \'%s\' not empty' % self.orig_cache_dir)
super(AAParserAltCacheTests, self).tearDown()
super().tearDown()
def test_cache_purge_leaves_original_cache_alone(self):
'''test cache purging only touches alt cache'''

View file

@ -13,7 +13,7 @@
# TODO
# - finish adding suppressions for valgrind false positives
from argparse import ArgumentParser # requires python 2.7 or newer
from argparse import ArgumentParser
import os
import sys
import tempfile

View file

@ -13,7 +13,6 @@
#
# ----------------------------------------------------------------------
# No old version logs, only 2.6 + supported
from __future__ import division, with_statement
import os
import re
import shutil
@ -23,6 +22,7 @@ import time
import traceback
import atexit
import tempfile
from shutil import which
import apparmor.config
import apparmor.logparser
@ -33,7 +33,7 @@ from copy import deepcopy
from apparmor.aare import AARE
from apparmor.common import (AppArmorException, AppArmorBug, cmd, is_skippable_file, open_file_read, valid_path, hasher,
combine_profname, split_name, type_is_str, open_file_write, DebugLogger)
combine_profname, split_name, open_file_write, DebugLogger)
import apparmor.ui as aaui
@ -176,18 +176,6 @@ def check_for_apparmor(filesystem='/proc/filesystems', mounts='/proc/mounts'):
break
return aa_mountpoint
def which(file):
"""Returns the executable fullpath for the file, None otherwise"""
if sys.version_info >= (3, 3):
return shutil.which(file)
env_dirs = os.getenv('PATH').split(':')
for env_dir in env_dirs:
env_path = os.path.join(env_dir, file)
# Test if the path is executable or not
if os.access(env_path, os.X_OK):
return env_path
return None
def get_full_path(original_path):
"""Return the full path after resolving any symlinks"""
path = original_path
@ -626,7 +614,7 @@ def change_profile_flags(prof_filename, program, flag, set_flag):
found = False
depth = -1
if not flag or (type_is_str(flag) and flag.strip() == ''):
if not flag or (type(flag) is str and flag.strip() == ''):
raise AppArmorBug('New flag for %s is empty' % prof_filename)
with open_file_read(prof_filename) as f_in:
@ -1529,28 +1517,28 @@ def save_profiles(is_mergeprof=False):
ans, arg = q.promptUser()
q.selected = arg # remember selection
which = options[arg]
which_ = options[arg]
if ans == 'CMD_SAVE_SELECTED':
write_profile_ui_feedback(which)
reload_base(which)
write_profile_ui_feedback(which_)
reload_base(which_)
q.selected = 0 # saving the selected profile removes it from the list, therefore reset selection
elif ans == 'CMD_VIEW_CHANGES':
oldprofile = None
if aa[which][which].get('filename', False):
oldprofile = aa[which][which]['filename']
if aa[which_][which_].get('filename', False):
oldprofile = aa[which_][which_]['filename']
else:
oldprofile = get_profile_filename_from_attachment(which, True)
oldprofile = get_profile_filename_from_attachment(which_, True)
serialize_options = {'METADATA': True}
newprofile = serialize_profile(split_to_merged(aa), which, serialize_options)
newprofile = serialize_profile(split_to_merged(aa), which_, serialize_options)
aaui.UI_Changes(oldprofile, newprofile, comments=True)
elif ans == 'CMD_VIEW_CHANGES_CLEAN':
oldprofile = serialize_profile(split_to_merged(original_aa), which, {})
newprofile = serialize_profile(split_to_merged(aa), which, {})
oldprofile = serialize_profile(split_to_merged(original_aa), which_, {})
newprofile = serialize_profile(split_to_merged(aa), which_, {})
aaui.UI_Changes(oldprofile, newprofile)
@ -2385,10 +2373,7 @@ def check_qualifiers(program):
def get_subdirectories(current_dir):
"""Returns a list of all directories directly inside given directory"""
if sys.version_info < (3, 0):
return os.walk(current_dir).next()[1]
else:
return os.walk(current_dir).__next__()[1]
return next(os.walk(current_dir))[1]
def loadincludes():
loadincludes_dir('tunables', True)

View file

@ -14,9 +14,9 @@
import re
from apparmor.common import convert_regexp, type_is_str, AppArmorBug, AppArmorException
from apparmor.common import convert_regexp, AppArmorBug, AppArmorException
class AARE(object):
class AARE:
'''AARE (AppArmor Regular Expression) wrapper class'''
def __init__(self, regex, is_path, log_event=None):
@ -68,7 +68,7 @@ class AARE(object):
expression = expression.regex
else:
return self.is_equal(expression) # better safe than sorry
elif not type_is_str(expression):
elif type(expression) is not str:
raise AppArmorBug('AARE.match() called with unknown object: %s' % str(expression))
if self._regex_compiled is None:
@ -81,7 +81,7 @@ class AARE(object):
if type(expression) == AARE:
return self.regex == expression.regex
elif type_is_str(expression):
elif type(expression) is str:
return self.regex == expression
else:
raise AppArmorBug('AARE.is_equal() called with unknown object: %s' % str(expression))

View file

@ -14,7 +14,7 @@
# ----------------------------------------------------------------------
import apparmor.aa as apparmor
class Prof(object):
class Prof:
def __init__(self, filename):
apparmor.init_aa()
self.aa = apparmor.aa
@ -22,7 +22,7 @@ class Prof(object):
self.include = apparmor.include
self.filename = filename
class CleanProf(object):
class CleanProf:
def __init__(self, same_file, profile, other):
#If same_file we're basically comparing the file against itself to check superfluous rules
self.same_file = same_file

View file

@ -9,7 +9,6 @@
#
# ------------------------------------------------------------------
from __future__ import print_function
import codecs
import collections
import glob
@ -118,10 +117,7 @@ def cmd(command):
except OSError as ex:
return [127, str(ex)]
if sys.version_info[0] >= 3:
out = sp.communicate()[0].decode('ascii', 'ignore')
else:
out = sp.communicate()[0]
out = sp.communicate()[0].decode('ascii', 'ignore')
return [sp.returncode, out]
@ -134,10 +130,7 @@ def cmd_pipe(command1, command2):
except OSError as ex:
return [127, str(ex)]
if sys.version_info[0] >= 3:
out = sp2.communicate()[0].decode('ascii', 'ignore')
else:
out = sp2.communicate()[0]
out = sp2.communicate()[0].decode('ascii', 'ignore')
return [sp2.returncode, out]
@ -202,14 +195,7 @@ def open_file_anymode(mode, path, encoding='UTF-8'):
# This avoids a crash when reading a logfile with special characters that
# are not utf8-encoded (for example a latin1 "ö"), and also avoids crashes
# at several other places we don't know yet ;-)
errorhandling = 'surrogateescape'
if sys.version_info[0] < 3:
errorhandling = 'replace'
orig = codecs.open(path, mode, encoding, errors=errorhandling)
return orig
return codecs.open(path, mode, encoding, errors='surrogateescape')
def readkey():
'''Returns the pressed key'''
@ -268,15 +254,6 @@ def user_perm(prof_dir):
return False
return True
if sys.version_info[0] > 2:
unicode = str # python 3 dropped the unicode type. To keep type_is_str() simple (and pyflakes3 happy), re-create it as alias of str.
def type_is_str(var):
''' returns True if the given variable is a str (or unicode string when using python 2)'''
if type(var) in (str, unicode): # python 2 sometimes uses the 'unicode' type
return True
else:
return False
def split_name(full_profile):
if '//' in full_profile:
@ -301,7 +278,7 @@ def combine_profname(name_parts):
return '//'.join(name_parts)
class DebugLogger(object):
class DebugLogger:
'''Unified debug facility. Logs to file or stderr.
Does not log anything by default. Will only log if environment variable

View file

@ -11,29 +11,12 @@
# GNU General Public License for more details.
#
# ----------------------------------------------------------------------
from __future__ import with_statement
import os
import shlex
import shutil
import stat
import sys
import tempfile
if sys.version_info < (3, 0):
import ConfigParser as configparser
# Class to provide the object[section][option] behavior in Python2
class configparser_py2(configparser.ConfigParser):
def __getitem__(self, section):
section_val = self.items(section)
section_options = dict()
for option, value in section_val:
section_options[option] = value
return section_options
else:
import configparser
from configparser import ConfigParser
from apparmor.common import AppArmorException, open_file_read # , warn, msg,
@ -41,7 +24,7 @@ from apparmor.common import AppArmorException, open_file_read # , warn, msg,
# CFG = None
# REPO_CFG = None
# SHELL_FILES = ['easyprof.conf', 'notify.conf', 'parser.conf']
class Config(object):
class Config:
def __init__(self, conf_type, conf_dir='/etc/apparmor'):
self.CONF_DIR = conf_dir
# The type of config file that'll be read and/or written
@ -55,7 +38,7 @@ class Config(object):
if self.conf_type == 'shell':
config = {'': dict()}
elif self.conf_type == 'ini':
config = configparser.ConfigParser()
config = ConfigParser()
return config
def read_config(self, filename):
@ -65,21 +48,10 @@ class Config(object):
if self.conf_type == 'shell':
config = self.read_shell(filepath)
elif self.conf_type == 'ini':
if sys.version_info > (3, 0):
config = configparser.ConfigParser()
else:
config = configparser_py2()
config = ConfigParser()
# Set the option form to string -prevents forced conversion to lowercase
config.optionxform = str
if sys.version_info > (3, 0):
config.read(filepath)
else:
try:
config.read(filepath)
except configparser.ParsingError:
tmp_filepath = py2_parser(filepath)
config.read(tmp_filepath.name)
##config.__get__()
config.read(filepath)
return config
def write_config(self, filename, config):
@ -275,18 +247,3 @@ class Config(object):
for option in options:
line = ' ' + option + ' = ' + config[section][option] + '\n'
f_out.write(line)
def py2_parser(filename):
"""Returns the de-dented ini file from the new format ini"""
tmp = tempfile.NamedTemporaryFile('rw')
if os.path.exists(filename):
with open(tmp.name, 'w') as f_out, open_file_read(filename) as f_in:
for line in f_in:
# The ini format allows for multi-line entries, with the subsequent
# entries being indented deeper hence simple lstrip() is not appropriate
if line[:2] == ' ':
line = line[2:]
elif line[0] == '\t':
line = line[1:]
f_out.write(line)
return tmp

View file

@ -8,8 +8,6 @@
#
# ------------------------------------------------------------------
from __future__ import with_statement
import codecs
import copy
import glob
@ -21,8 +19,8 @@ import shutil
import subprocess
import sys
import tempfile
from shutil import which
from apparmor.aa import which
from apparmor.common import AppArmorException

View file

@ -8,8 +8,6 @@
#
# ------------------------------------------------------------------
from __future__ import print_function # needed in py2 for print('...', file=sys.stderr)
import cgitb
import os
import sys

View file

@ -79,9 +79,6 @@ class ReadLog:
"""Parse the event from log into key value pairs"""
msg = msg.strip()
self.debug_logger.info('parse_event: %s' % msg)
if sys.version_info < (3, 0):
# parse_record fails with u'foo' style strings hence typecasting to string
msg = str(msg)
event = LibAppArmor.parse_record(msg)
ev = dict()
ev['resource'] = event.info
@ -288,8 +285,7 @@ class ReadLog:
except AppArmorException as e:
ex_msg = ('%(msg)s\n\nThis error was caused by the log line:\n%(logline)s' %
{'msg': e.value, 'logline': line})
# when py3 only: Drop the original AppArmorException by passing None as the parent exception
raise AppArmorBug(ex_msg) # py3-only: from None
raise AppArmorBug(ex_msg) from None
self.LOG.close()
self.logmark = ''

View file

@ -14,7 +14,7 @@
# ----------------------------------------------------------------------
from apparmor.common import AppArmorBug, AppArmorException, type_is_str
from apparmor.common import AppArmorBug, AppArmorException
from apparmor.rule.abi import AbiRule, AbiRuleset
from apparmor.rule.capability import CapabilityRule, CapabilityRuleset
@ -108,14 +108,14 @@ class ProfileStorage:
# allow writing str or None to some keys
elif key in ('flags', 'filename'):
if type_is_str(value) or value is None:
if type(value) is str or value is None:
self.data[key] = value
else:
raise AppArmorBug('Attempt to change type of "%s" from %s to %s, value %s' % (key, type(self.data[key]), type(value), value))
# allow writing str values
elif type_is_str(self.data[key]):
if type_is_str(value):
elif type(self.data[key]) is str:
if type(value) is str:
self.data[key] = value
else:
raise AppArmorBug('Attempt to change type of "%s" from %s to %s, value %s' % (key, type(self.data[key]), type(value), value))
@ -268,10 +268,10 @@ def split_flags(flags):
def add_or_remove_flag(flags, flags_to_change, set_flag):
'''add (if set_flag == True) or remove the given flags_to_change to flags'''
if type_is_str(flags) or flags is None:
if type(flags) is str or flags is None:
flags = split_flags(flags)
if type_is_str(flags_to_change) or flags_to_change is None:
if type(flags_to_change) is str or flags_to_change is None:
flags_to_change = split_flags(flags_to_change)
if set_flag:

View file

@ -13,15 +13,17 @@
#
# ----------------------------------------------------------------------
from abc import abstractmethod
from apparmor.aare import AARE
from apparmor.common import AppArmorBug, type_is_str
from apparmor.common import AppArmorBug
# setup module translations
from apparmor.translations import init_translation
_ = init_translation()
class BaseRule(object):
class BaseRule:
'''Base class to handle and store a single rule'''
# type specific rules should inherit from this class.
@ -76,7 +78,7 @@ class BaseRule(object):
if rulepart == self.ALL:
return None, True
elif type_is_str(rulepart):
elif type(rulepart) is str:
if len(rulepart.strip()) == 0:
raise AppArmorBug('Passed empty %(partname)s to %(classname)s: %(rulepart)s' %
{'partname': partname, 'classname': self.__class__.__name__, 'rulepart': str(rulepart)})
@ -104,8 +106,8 @@ class BaseRule(object):
else:
return False
# @abstractmethod FIXME - uncomment when python3 only
@classmethod
@abstractmethod
def _match(cls, raw_rule):
'''parse raw_rule and return regex match object'''
raise NotImplementedError("'%s' needs to implement _match(), but didn't" % (str(cls)))
@ -117,14 +119,14 @@ class BaseRule(object):
rule.raw_rule = raw_rule.strip()
return rule
# @abstractmethod FIXME - uncomment when python3 only
@classmethod
@abstractmethod
def _parse(cls, raw_rule):
'''returns a Rule object created from parsing the raw rule.
required to be implemented by subclasses; raise exception if not'''
raise NotImplementedError("'%s' needs to implement _parse(), but didn't" % (str(cls)))
# @abstractmethod FIXME - uncomment when python3 only
@abstractmethod
def get_clean(self, depth=0):
'''return clean rule (with default formatting, and leading whitespace as specified in the depth parameter)'''
raise NotImplementedError("'%s' needs to implement get_clean(), but didn't" % (str(self.__class__)))
@ -157,7 +159,7 @@ class BaseRule(object):
# still here? -> then the common part is covered, check rule-specific things now
return self.is_covered_localvars(other_rule)
# @abstractmethod FIXME - uncomment when python3 only
@abstractmethod
def is_covered_localvars(self, other_rule):
'''check if the rule-specific parts of other_rule is covered by this rule object'''
raise NotImplementedError("'%s' needs to implement is_covered_localvars(), but didn't" % (str(self)))
@ -238,7 +240,7 @@ class BaseRule(object):
# still here? -> then it is equal
return True
# @abstractmethod FIXME - uncomment when python3 only
@abstractmethod
def is_equal_localvars(self, other_rule, strict):
'''compare if rule-specific variables are equal'''
raise NotImplementedError("'%s' needs to implement is_equal_localvars(), but didn't" % (str(self)))
@ -273,24 +275,24 @@ class BaseRule(object):
return headers
# @abstractmethod FIXME - uncomment when python3 only
@abstractmethod
def logprof_header_localvars(self):
'''return the headers (human-readable version of the rule) to display in aa-logprof for this rule object
returns {'label1': 'value1', 'label2': 'value2'} '''
raise NotImplementedError("'%s' needs to implement logprof_header(), but didn't" % (str(self)))
# @abstractmethod FIXME - uncomment when python3 only
@abstractmethod
def edit_header(self):
'''return the prompt for, and the path to edit when using '(N)ew' '''
raise NotImplementedError("'%s' needs to implement edit_header(), but didn't" % (str(self)))
# @abstractmethod FIXME - uncomment when python3 only
@abstractmethod
def validate_edit(self, newpath):
'''validate the new path.
Returns True if it covers the previous path, False if it doesn't.'''
raise NotImplementedError("'%s' needs to implement validate_edit(), but didn't" % (str(self)))
# @abstractmethod FIXME - uncomment when python3 only
@abstractmethod
def store_edit(self, newpath):
'''store the changed path.
This is done even if the new path doesn't match the original one.'''
@ -314,7 +316,7 @@ class BaseRule(object):
return '%s%s' % (auditstr, allowstr)
class BaseRuleset(object):
class BaseRuleset:
'''Base class to handle and store a collection of rules'''
# decides if the (G)lob and Glob w/ (E)xt options are displayed
@ -499,7 +501,7 @@ def check_and_split_list(lst, allowed_keywords, all_obj, classname, keyword_name
if lst == all_obj:
return None, True, None
elif type_is_str(lst):
elif type(lst) is str:
result_list = {lst}
elif type(lst) in (list, tuple, set) and (len(lst) > 0 or allow_empty_list):
result_list = set(lst)

View file

@ -30,10 +30,9 @@ class AbiRule(IncludeRule):
def __init__(self, path, ifexists, ismagic, audit=False, deny=False, allow_keyword=False,
comment='', log_event=None):
super(AbiRule, self).__init__(path, ifexists, ismagic,
audit=audit, deny=deny, allow_keyword=allow_keyword,
comment=comment,
log_event=log_event)
super().__init__(path, ifexists, ismagic,
audit=audit, deny=deny, allow_keyword=allow_keyword,
comment=comment, log_event=log_event)
# abi doesn't support 'if exists'
if ifexists:

View file

@ -13,7 +13,7 @@
# ----------------------------------------------------------------------
from apparmor.regex import RE_PROFILE_ALIAS, strip_quotes
from apparmor.common import AppArmorBug, AppArmorException, type_is_str
from apparmor.common import AppArmorBug, AppArmorException
from apparmor.rule import BaseRule, BaseRuleset, parse_comment, quote_if_needed
# setup module translations
@ -29,10 +29,8 @@ class AliasRule(BaseRule):
def __init__(self, orig_path, target, audit=False, deny=False, allow_keyword=False,
comment='', log_event=None):
super(AliasRule, self).__init__(audit=audit, deny=deny,
allow_keyword=allow_keyword,
comment=comment,
log_event=log_event)
super().__init__(audit=audit, deny=deny, allow_keyword=allow_keyword,
comment=comment, log_event=log_event)
# aliass don't support audit or deny
if audit:
@ -40,14 +38,14 @@ class AliasRule(BaseRule):
if deny:
raise AppArmorBug('Attempt to initialize %s with deny flag' % self.__class__.__name__)
if not type_is_str(orig_path):
if type(orig_path) is not str:
raise AppArmorBug('Passed unknown type for orig_path to %s: %s' % (self.__class__.__name__, orig_path))
if not orig_path:
raise AppArmorException('Passed empty orig_path to %s: %s' % (self.__class__.__name__, orig_path))
if not orig_path.startswith('/'):
raise AppArmorException("Alias path doesn't start with '/'")
if not type_is_str(target):
if type(target) is not str:
raise AppArmorBug('Passed unknown type for target to %s: %s' % (self.__class__.__name__, target))
if not target:
raise AppArmorException('Passed empty target to %s: %s' % (self.__class__.__name__, target))

View file

@ -14,7 +14,7 @@
# ----------------------------------------------------------------------
from apparmor.regex import RE_PROFILE_BOOLEAN
from apparmor.common import AppArmorBug, AppArmorException, type_is_str
from apparmor.common import AppArmorBug, AppArmorException
from apparmor.rule import BaseRule, BaseRuleset, parse_comment
# setup module translations
@ -30,10 +30,8 @@ class BooleanRule(BaseRule):
def __init__(self, varname, value, audit=False, deny=False, allow_keyword=False,
comment='', log_event=None):
super(BooleanRule, self).__init__(audit=audit, deny=deny,
allow_keyword=allow_keyword,
comment=comment,
log_event=log_event)
super().__init__(audit=audit, deny=deny, allow_keyword=allow_keyword,
comment=comment, log_event=log_event)
# boolean variables don't support audit or deny
if audit:
@ -41,12 +39,12 @@ class BooleanRule(BaseRule):
if deny:
raise AppArmorBug('Attempt to initialize %s with deny flag' % self.__class__.__name__)
if not type_is_str(varname):
if type(varname) is not str:
raise AppArmorBug('Passed unknown type for boolean variable to %s: %s' % (self.__class__.__name__, varname))
if not varname.startswith('$'):
raise AppArmorException("Passed invalid boolean to %s (doesn't start with '$'): %s" % (self.__class__.__name__, varname))
if not type_is_str(value):
if type(value) is not str:
raise AppArmorBug('Passed unknown type for value to %s: %s' % (self.__class__.__name__, value))
if not value:
raise AppArmorException('Passed empty value to %s: %s' % (self.__class__.__name__, value))
@ -131,4 +129,4 @@ class BooleanRuleset(BaseRuleset):
if rule.varname == knownrule.varname:
raise AppArmorException(_('Redefining existing variable %(variable)s: %(value)s') % { 'variable': rule.varname, 'value': rule.value })
super(BooleanRuleset, self).add(rule, cleanup)
super().add(rule, cleanup)

View file

@ -16,7 +16,7 @@
import re
from apparmor.regex import RE_PROFILE_CAP
from apparmor.common import AppArmorBug, AppArmorException, type_is_str
from apparmor.common import AppArmorBug, AppArmorException
from apparmor.rule import BaseRule, BaseRuleset, logprof_value_or_all, parse_modifiers
# setup module translations
@ -29,7 +29,7 @@ class CapabilityRule(BaseRule):
# Nothing external should reference this class, all external users
# should reference the class field CapabilityRule.ALL
class __CapabilityAll(object):
class __CapabilityAll:
pass
ALL = __CapabilityAll
@ -39,10 +39,8 @@ class CapabilityRule(BaseRule):
def __init__(self, cap_list, audit=False, deny=False, allow_keyword=False,
comment='', log_event=None):
super(CapabilityRule, self).__init__(audit=audit, deny=deny,
allow_keyword=allow_keyword,
comment=comment,
log_event=log_event)
super().__init__(audit=audit, deny=deny, allow_keyword=allow_keyword,
comment=comment, log_event=log_event)
# Because we support having multiple caps in one rule,
# initializer needs to accept a list of caps.
self.all_caps = False
@ -50,7 +48,7 @@ class CapabilityRule(BaseRule):
self.all_caps = True
self.capability = set()
else:
if type_is_str(cap_list):
if type(cap_list) is str:
self.capability = {cap_list}
elif type(cap_list) == list and len(cap_list) > 0:
self.capability = set(cap_list)

View file

@ -14,7 +14,7 @@
# ----------------------------------------------------------------------
from apparmor.regex import RE_PROFILE_CHANGE_PROFILE, strip_quotes
from apparmor.common import AppArmorBug, AppArmorException, type_is_str
from apparmor.common import AppArmorBug, AppArmorException
from apparmor.rule import BaseRule, BaseRuleset, parse_modifiers, logprof_value_or_all, quote_if_needed
# setup module translations
@ -27,7 +27,7 @@ class ChangeProfileRule(BaseRule):
# Nothing external should reference this class, all external users
# should reference the class field ChangeProfileRule.ALL
class __ChangeProfileAll(object):
class __ChangeProfileAll:
pass
ALL = __ChangeProfileAll
@ -43,10 +43,8 @@ class ChangeProfileRule(BaseRule):
CHANGE_PROFILE RULE = 'change_profile' [ [ EXEC MODE ] EXEC COND ] [ -> PROGRAMCHILD ]
'''
super(ChangeProfileRule, self).__init__(audit=audit, deny=deny,
allow_keyword=allow_keyword,
comment=comment,
log_event=log_event)
super().__init__(audit=audit, deny=deny, allow_keyword=allow_keyword,
comment=comment, log_event=log_event)
if execmode:
if execmode != 'safe' and execmode != 'unsafe':
@ -59,7 +57,7 @@ class ChangeProfileRule(BaseRule):
self.all_execconds = False
if execcond == ChangeProfileRule.ALL:
self.all_execconds = True
elif type_is_str(execcond):
elif type(execcond) is str:
if not execcond.strip():
raise AppArmorBug('Empty exec condition in change_profile rule')
elif execcond.startswith('/') or execcond.startswith('@'):
@ -73,7 +71,7 @@ class ChangeProfileRule(BaseRule):
self.all_targetprofiles = False
if targetprofile == ChangeProfileRule.ALL:
self.all_targetprofiles = True
elif type_is_str(targetprofile):
elif type(targetprofile) is str:
if targetprofile.strip():
self.targetprofile = targetprofile
else:

View file

@ -68,7 +68,7 @@ class DbusRule(BaseRule):
# Nothing external should reference this class, all external users
# should reference the class field DbusRule.ALL
class __DbusAll(object):
class __DbusAll:
pass
ALL = __DbusAll
@ -78,10 +78,8 @@ class DbusRule(BaseRule):
def __init__(self, access, bus, path, name, interface, member, peername, peerlabel,
audit=False, deny=False, allow_keyword=False, comment='', log_event=None):
super(DbusRule, self).__init__(audit=audit, deny=deny,
allow_keyword=allow_keyword,
comment=comment,
log_event=log_event)
super().__init__(audit=audit, deny=deny, allow_keyword=allow_keyword,
comment=comment, log_event=log_event)
self.access, self.all_access, unknown_items = check_and_split_list(access, access_keywords, DbusRule.ALL, 'DbusRule', 'access')
if unknown_items:

View file

@ -14,7 +14,7 @@
from apparmor.aare import AARE
from apparmor.regex import RE_PROFILE_FILE_ENTRY, strip_quotes
from apparmor.common import AppArmorBug, AppArmorException, type_is_str
from apparmor.common import AppArmorBug, AppArmorException
from apparmor.rule import BaseRule, BaseRuleset, check_and_split_list, logprof_value_or_all, parse_modifiers, quote_if_needed
# setup module translations
@ -34,9 +34,9 @@ class FileRule(BaseRule):
# Nothing external should reference this class, all external users
# should reference the class field FileRule.ALL
class __FileAll(object):
class __FileAll:
pass
class __FileAnyExec(object):
class __FileAnyExec:
pass
ALL = __FileAll
@ -58,8 +58,8 @@ class FileRule(BaseRule):
- leading_perms: bool
'''
super(FileRule, self).__init__(audit=audit, deny=deny, allow_keyword=allow_keyword,
comment=comment, log_event=log_event)
super().__init__(audit=audit, deny=deny, allow_keyword=allow_keyword,
comment=comment, log_event=log_event)
# rulepart partperms is_path log_event
self.path, self.all_paths = self._aare_or_all(path, 'path', True, log_event)
@ -69,7 +69,7 @@ class FileRule(BaseRule):
self.can_glob_ext = not self.all_paths
self.can_edit = not self.all_paths
if type_is_str(perms):
if type(perms) is str:
perms, tmp_exec_perms = split_perms(perms, deny)
if tmp_exec_perms:
raise AppArmorBug('perms must not contain exec perms')
@ -96,7 +96,7 @@ class FileRule(BaseRule):
raise AppArmorBug("link rules can't have execute permissions")
elif exec_perms == self.ANY_EXEC:
self.exec_perms = exec_perms
elif type_is_str(exec_perms):
elif type(exec_perms) is str:
if deny:
if exec_perms != 'x':
raise AppArmorException(_("file deny rules only allow to use 'x' as execute mode, but not %s" % exec_perms))

View file

@ -13,7 +13,7 @@
# ----------------------------------------------------------------------
from apparmor.regex import RE_INCLUDE, re_match_include_parse
from apparmor.common import AppArmorBug, AppArmorException, is_skippable_file, type_is_str
from apparmor.common import AppArmorBug, AppArmorException, is_skippable_file
from apparmor.rule import BaseRule, BaseRuleset, parse_comment
import os
@ -30,10 +30,8 @@ class IncludeRule(BaseRule):
def __init__(self, path, ifexists, ismagic, audit=False, deny=False, allow_keyword=False,
comment='', log_event=None):
super(IncludeRule, self).__init__(audit=audit, deny=deny,
allow_keyword=allow_keyword,
comment=comment,
log_event=log_event)
super().__init__(audit=audit, deny=deny, allow_keyword=allow_keyword,
comment=comment, log_event=log_event)
# include doesn't support audit or deny
if audit:
@ -45,7 +43,7 @@ class IncludeRule(BaseRule):
raise AppArmorBug('Passed unknown type for ifexists to %s: %s' % (self.__class__.__name__, ifexists))
if type(ismagic) is not bool:
raise AppArmorBug('Passed unknown type for ismagic to %s: %s' % (self.__class__.__name__, ismagic))
if not type_is_str(path):
if type(path) is not str:
raise AppArmorBug('Passed unknown type for path to %s: %s' % (self.__class__.__name__, path))
if not path:
raise AppArmorBug('Passed empty path to %s: %s' % (self.__class__.__name__, path))

View file

@ -16,7 +16,7 @@
import re
from apparmor.regex import RE_PROFILE_NETWORK
from apparmor.common import AppArmorBug, AppArmorException, type_is_str
from apparmor.common import AppArmorBug, AppArmorException
from apparmor.rule import BaseRule, BaseRuleset, logprof_value_or_all, parse_modifiers
# setup module translations
@ -49,7 +49,7 @@ class NetworkRule(BaseRule):
# Nothing external should reference this class, all external users
# should reference the class field NetworkRule.ALL
class __NetworkAll(object):
class __NetworkAll:
pass
ALL = __NetworkAll
@ -59,16 +59,14 @@ class NetworkRule(BaseRule):
def __init__(self, domain, type_or_protocol, audit=False, deny=False, allow_keyword=False,
comment='', log_event=None):
super(NetworkRule, self).__init__(audit=audit, deny=deny,
allow_keyword=allow_keyword,
comment=comment,
log_event=log_event)
super().__init__(audit=audit, deny=deny, allow_keyword=allow_keyword,
comment=comment, log_event=log_event)
self.domain = None
self.all_domains = False
if domain == NetworkRule.ALL:
self.all_domains = True
elif type_is_str(domain):
elif type(domain) is str:
if domain in network_domain_keywords:
self.domain = domain
else:
@ -80,7 +78,7 @@ class NetworkRule(BaseRule):
self.all_type_or_protocols = False
if type_or_protocol == NetworkRule.ALL:
self.all_type_or_protocols = True
elif type_is_str(type_or_protocol):
elif type(type_or_protocol) is str:
if type_or_protocol in network_protocol_keywords:
self.type_or_protocol = type_or_protocol
elif type_or_protocol in network_type_keywords:

View file

@ -45,7 +45,7 @@ class PtraceRule(BaseRule):
# Nothing external should reference this class, all external users
# should reference the class field PtraceRule.ALL
class __PtraceAll(object):
class __PtraceAll:
pass
ALL = __PtraceAll
@ -55,10 +55,8 @@ class PtraceRule(BaseRule):
def __init__(self, access, peer, audit=False, deny=False, allow_keyword=False,
comment='', log_event=None):
super(PtraceRule, self).__init__(audit=audit, deny=deny,
allow_keyword=allow_keyword,
comment=comment,
log_event=log_event)
super().__init__(audit=audit, deny=deny, allow_keyword=allow_keyword,
comment=comment, log_event=log_event)
self.access, self.all_access, unknown_items = check_and_split_list(access, access_keywords, PtraceRule.ALL, 'PtraceRule', 'access')
if unknown_items:

View file

@ -16,7 +16,7 @@
import re
from apparmor.regex import RE_PROFILE_RLIMIT, strip_quotes
from apparmor.common import AppArmorBug, AppArmorException, type_is_str
from apparmor.common import AppArmorBug, AppArmorException
from apparmor.rule import BaseRule, BaseRuleset, parse_comment, quote_if_needed
# setup module translations
@ -41,7 +41,7 @@ class RlimitRule(BaseRule):
# Nothing external should reference this class, all external users
# should reference the class field RlimitRule.ALL
class __RlimitAll(object):
class __RlimitAll:
pass
ALL = __RlimitAll
@ -51,15 +51,13 @@ class RlimitRule(BaseRule):
def __init__(self, rlimit, value, audit=False, deny=False, allow_keyword=False,
comment='', log_event=None):
super(RlimitRule, self).__init__(audit=audit, deny=deny,
allow_keyword=allow_keyword,
comment=comment,
log_event=log_event)
super().__init__(audit=audit, deny=deny, allow_keyword=allow_keyword,
comment=comment, log_event=log_event)
if audit or deny or allow_keyword:
raise AppArmorBug('The audit, allow or deny keywords are not allowed in rlimit rules.')
if type_is_str(rlimit):
if type(rlimit) is str:
if rlimit in rlimit_all:
self.rlimit = rlimit
else:
@ -72,7 +70,7 @@ class RlimitRule(BaseRule):
self.all_values = False
if value == RlimitRule.ALL:
self.all_values = True
elif type_is_str(value):
elif type(value) is str:
if not value.strip():
raise AppArmorBug('Empty value in rlimit rule')

View file

@ -66,7 +66,7 @@ class SignalRule(BaseRule):
# Nothing external should reference this class, all external users
# should reference the class field SignalRule.ALL
class __SignalAll(object):
class __SignalAll:
pass
ALL = __SignalAll
@ -76,10 +76,8 @@ class SignalRule(BaseRule):
def __init__(self, access, signal, peer, audit=False, deny=False, allow_keyword=False,
comment='', log_event=None):
super(SignalRule, self).__init__(audit=audit, deny=deny,
allow_keyword=allow_keyword,
comment=comment,
log_event=log_event)
super().__init__(audit=audit, deny=deny, allow_keyword=allow_keyword,
comment=comment, log_event=log_event)
self.access, self.all_access, unknown_items = check_and_split_list(access, access_keywords, SignalRule.ALL, 'SignalRule', 'access')
if unknown_items:

View file

@ -14,7 +14,7 @@
# ----------------------------------------------------------------------
from apparmor.regex import RE_PROFILE_VARIABLE, strip_quotes
from apparmor.common import AppArmorBug, AppArmorException, type_is_str
from apparmor.common import AppArmorBug, AppArmorException
from apparmor.rule import BaseRule, BaseRuleset, parse_comment, quote_if_needed
import re
@ -32,10 +32,8 @@ class VariableRule(BaseRule):
def __init__(self, varname, mode, values, audit=False, deny=False, allow_keyword=False,
comment='', log_event=None):
super(VariableRule, self).__init__(audit=audit, deny=deny,
allow_keyword=allow_keyword,
comment=comment,
log_event=log_event)
super().__init__(audit=audit, deny=deny, allow_keyword=allow_keyword,
comment=comment, log_event=log_event)
# variables don't support audit or deny
if audit:
@ -43,14 +41,14 @@ class VariableRule(BaseRule):
if deny:
raise AppArmorBug('Attempt to initialize %s with deny flag' % self.__class__.__name__)
if not type_is_str(varname):
if type(varname) is not str:
raise AppArmorBug('Passed unknown type for varname to %s: %s' % (self.__class__.__name__, varname))
if not varname.startswith('@{'):
raise AppArmorException("Passed invalid varname to %s (doesn't start with '@{'): %s" % (self.__class__.__name__, varname))
if not varname.endswith('}'):
raise AppArmorException("Passed invalid varname to %s (doesn't end with '}'): %s" % (self.__class__.__name__, varname))
if not type_is_str(mode):
if type(mode) is not str:
raise AppArmorBug('Passed unknown type for variable assignment mode to %s: %s' % (self.__class__.__name__, mode))
if mode not in ('=', '+='):
raise AppArmorBug('Passed unknown variable assignment mode to %s: %s' % (self.__class__.__name__, mode))
@ -151,7 +149,7 @@ class VariableRuleset(BaseRuleset):
if rule.varname == knownrule.varname:
raise AppArmorException(_('Redefining existing variable %(variable)s: %(value)s') % { 'variable': rule.varname, 'value': rule.values })
super(VariableRuleset, self).add(rule, cleanup)
super().add(rule, cleanup)
def get_merged_variables(self):
''' Get merged variables of this VariableRuleset.

View file

@ -8,7 +8,7 @@
#
# ------------------------------------------------------------------
class _Raw_Rule(object):
class _Raw_Rule:
audit = False
deny = False

View file

@ -9,7 +9,6 @@
# ------------------------------------------------------------------
from apparmor.common import AppArmorException, debug, error, msg, cmd
from apparmor.aa import which
import apparmor.easyprof
import optparse
import os
@ -20,6 +19,7 @@ import socket
import sys
import tempfile
import time
from shutil import which
def check_requirements(binary):
'''Verify necessary software is installed'''
@ -129,10 +129,7 @@ def aa_exec(command, opt, environ={}, verify_rules=[]):
debug("\n%s" % policy)
with tempfile.NamedTemporaryFile(prefix='%s-' % policy_name) as tmp:
if sys.version_info[0] >= 3:
tmp.write(bytes(policy, 'utf-8'))
else:
tmp.write(policy)
tmp.write(bytes(policy, 'utf-8'))
debug("using '%s' template" % opt.template)
# TODO: get rid of this
@ -543,10 +540,7 @@ EndSection
tmp, xorg_conf = tempfile.mkstemp(prefix='aa-sandbox-xorg.conf-')
self.tempfiles.append(xorg_conf)
if sys.version_info[0] >= 3:
os.write(tmp, bytes(conf, 'utf-8'))
else:
os.write(tmp, conf)
os.write(tmp, bytes(conf, 'utf-8'))
os.close(tmp)
xvfb_args.append('--xvfb=Xorg')

View file

@ -11,11 +11,10 @@
# GNU General Public License for more details.
#
# ----------------------------------------------------------------------
from __future__ import with_statement
import re
from apparmor.common import AppArmorException, open_file_read, warn, convert_regexp # , msg, error, debug
class Severity(object):
class Severity:
def __init__(self, dbname=None, default_rank=10):
"""Initialises the class object"""
self.PROF_DIR = '/etc/apparmor.d' # The profile directory

View file

@ -14,6 +14,7 @@
# ----------------------------------------------------------------------
import os
import sys
from shutil import which
import apparmor.aa as apparmor
import apparmor.ui as aaui
@ -61,9 +62,9 @@ class aa_tools:
program = fq_path
profile = apparmor.get_profile_filename_from_attachment(fq_path, True)
else:
which = apparmor.which(p)
if which is not None:
program = apparmor.get_full_path(which)
which_ = which(p)
if which_ is not None:
program = apparmor.get_full_path(which_)
profile = apparmor.get_profile_filename_from_attachment(program, True)
elif os.path.exists(os.path.join(apparmor.profile_dir, p)):
program = None

View file

@ -31,10 +31,6 @@ _ = init_translation()
# Set up UI logger for separate messages from UI module
debug_logger = DebugLogger('UI')
# If Python3, wrap input in raw_input so make check passes
if 'raw_input' not in dir(__builtins__):
raw_input = input
ARROWS = {'A': 'UP', 'B': 'DOWN', 'C': 'RIGHT', 'D': 'LEFT'}
UI_mode = 'text'
@ -70,7 +66,7 @@ def set_text_mode():
# reads the response on command line for json and verifies the response
# for the dialog type
def json_response(dialog_type):
string = raw_input('\n')
string = input('\n')
rh = json.loads(string.strip())
if rh["dialog"] != dialog_type:
raise AppArmorException('Expected response %s got %s.' % (dialog_type, string))
@ -222,7 +218,7 @@ def UI_GetString(text, default):
else: # text mode
readline.set_startup_hook(lambda: readline.insert_text(default))
try:
string = raw_input('\n' + text)
string = input('\n' + text)
except EOFError:
string = ''
finally:
@ -362,7 +358,7 @@ CMDS = {'CMD_ALLOW': _('(A)llow'),
}
class PromptQuestion(object):
class PromptQuestion:
title = None
headers = None
explanation = None

View file

@ -26,11 +26,11 @@ import os
import shutil
import sys
class Install(_install, object):
class Install(_install):
'''Override setuptools to install the files where we want them.'''
def run(self):
# Now byte-compile everything
super(Install, self).run()
super().run()
prefix = self.prefix
if self.root != None:

View file

@ -58,7 +58,7 @@ class InterceptingOptionParser(optparse.OptionParser):
raise InterceptedError(error_message=msg)
class Manifest(object):
class Manifest:
def __init__(self, profile_name):
self.security = dict()
self.security['profiles'] = dict()

View file

@ -15,7 +15,6 @@ from common_test import read_file, write_file
import os
import shutil
import sys
import apparmor.aa # needed to set global vars in some tests
from apparmor.aa import (check_for_apparmor, get_output, get_reqs, get_interpreter_and_abstraction, create_new_profile,
@ -99,14 +98,7 @@ class AATest_get_reqs(AATest):
)
def _run_test(self, params, expected):
# for some reason, setting the ldd config option does not get
# honored in python2.7
# XXX KILL when python 2.7 is dropped XXX
if sys.version_info[0] < 3:
print("Skipping on python < 3.x")
return
apparmor.aa.cfg['settings']['ldd'] = './fake_ldd'
self.assertEqual(get_reqs(params), expected)
class AaTest_create_new_profile(AATest):
@ -118,12 +110,6 @@ class AaTest_create_new_profile(AATest):
)
def _run_test(self, params, expected):
apparmor.aa.cfg['settings']['ldd'] = './fake_ldd'
# for some reason, setting the ldd config option does not get
# honored in python2.7
# XXX KILL when python 2.7 is dropped XXX
if sys.version_info[0] < 3:
print("Skipping on python < 3.x")
return
self.createTmpdir()

View file

@ -13,19 +13,7 @@ import unittest
from common_test import AATest, setup_all_loops
from apparmor.common import AppArmorBug
from apparmor.common import type_is_str, split_name, combine_profname
class TestIs_str_type(AATest):
tests = (
('foo', True),
(u'foo', True),
(42, False),
(True, False),
([], False),
)
def _run_test(self, params, expected):
self.assertEqual(type_is_str(params), expected)
from apparmor.common import split_name, combine_profname
class AaTest_split_name(AATest):
tests = (

View file

@ -14,16 +14,13 @@
import os
import shutil
import subprocess
import sys
import unittest
from common_test import AATest, setup_all_loops, setup_aa
import apparmor.aa as apparmor
from common_test import read_file
python_interpreter = 'python'
if sys.version_info >= (3, 0):
python_interpreter = 'python3'
python_interpreter = 'python3'
class MinitoolsTest(AATest):

View file

@ -1,4 +1,4 @@
#!/usr/bin/python
#!/usr/bin/python3
#
# Copyright (C) 2012 Canonical Ltd.
#
@ -9,7 +9,6 @@
# Written by Steve Beattie <steve@nxnw.org>, based on work by
# Christian Boltz <apparmor@cboltz.de>
from __future__ import with_statement
import re
import subprocess
import sys