예제 #1
0
    def time_to_int(self, value, default_unit):
        number, unit = split_unit(value)

        if unit == '':
            unit = default_unit

        if unit in ['us', 'microsecond', 'microseconds']:
            number = number / 1000000.0
            if default_unit == 'seconds':
                raise AppArmorException(_('Invalid unit in rlimit cpu %s rule') % value)
        elif unit in ['ms', 'millisecond', 'milliseconds']:
            number = number / 1000.0
            if default_unit == 'seconds':
                raise AppArmorException(_('Invalid unit in rlimit cpu %s rule') % value)
        elif unit in ['s', 'sec', 'second', 'seconds']: # manpage doesn't list sec
            pass
        elif unit in ['min', 'minute', 'minutes']:
            number = number * 60
        elif unit in ['h', 'hour', 'hours']:
            number = number * 60 * 60
        elif unit in ['d', 'day', 'days']: # manpage doesn't list 'd'
            number = number * 60 * 60 * 24
        elif unit in ['week', 'weeks']:
            number = number * 60 * 60 * 24 * 7
        else:
            raise AppArmorException('Unknown unit %s in rlimit %s %s' % (unit, self.rlimit, value))

        return number
예제 #2
0
파일: regex.py 프로젝트: pexip/os-apparmor
def re_match_include(line):
    """Matches the path for include and returns the include path"""
    matches = RE_INCLUDE.search(line)

    if not matches:
        return None

    path = None
    if matches.group('magicpath'):
        path = matches.group('magicpath').strip()
    elif matches.group('unquotedpath'):
        # LP: #1738879 - parser doesn't handle unquoted paths everywhere
        # path = matches.group('unquotedpath').strip()
        raise AppArmorException(
            _('Syntax error: #include must use quoted path or <...>'))
    elif matches.group('quotedpath'):
        path = matches.group('quotedpath')
        # LP: 1738880 - parser doesn't handle relative paths everywhere, and
        # neither do we (see aa.py)
        if len(path) > 0 and path[0] != '/':
            raise AppArmorException(
                _('Syntax error: #include must use quoted path or <...>'))

    # if path is empty or the empty string
    if path is None or path == "":
        raise AppArmorException(
            _('Syntax error: #include rule with empty filename'))

    # LP: #1738877 - parser doesn't handle files with spaces in the name
    if re.search('\s', path):
        raise AppArmorException(
            _('Syntax error: #include rule filename cannot contain spaces'))

    return path
예제 #3
0
def split_perms(perm_string, deny):
    '''parse permission string
       - perm_string: the permission string to parse
       - deny: True if this is a deny rule
   '''
    perms = set()
    exec_mode = None

    while perm_string:
        if perm_string[0] in file_permissions:
            perms.add(perm_string[0])
            perm_string = perm_string[1:]
        elif perm_string[0] == 'x':
            if not deny:
                raise AppArmorException(_("'x' must be preceded by an exec qualifier (i, P, C or U)"))
            exec_mode = 'x'
            perm_string = perm_string[1:]
        elif perm_string.startswith(allow_exec_transitions):
            if exec_mode and exec_mode != perm_string[0:2]:
                raise AppArmorException(_('conflicting execute permissions found: %s and %s' % (exec_mode, perm_string[0:2])))
            exec_mode = perm_string[0:2]
            perm_string = perm_string[2:]
        elif perm_string.startswith(allow_exec_fallback_transitions):
            if exec_mode and exec_mode != perm_string[0:3]:
                raise AppArmorException(_('conflicting execute permissions found: %s and %s' % (exec_mode, perm_string[0:3])))
            exec_mode = perm_string[0:3]
            perm_string = perm_string[3:]
        else:
            raise AppArmorException(_('permission contains unknown character(s) %s' % perm_string))

    return perms, exec_mode
예제 #4
0
    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)

        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 rlimit in rlimit_all:
                self.rlimit = rlimit
            else:
                raise AppArmorException('Unknown rlimit keyword in rlimit rule: %s' % rlimit)
        else:
            raise AppArmorBug('Passed unknown object to RlimitRule: %s' % str(rlimit))

        self.value = None
        self.value_as_int = None
        self.all_values = False
        if value == RlimitRule.ALL:
            self.all_values = True
        elif type_is_str(value):
            if not value.strip():
                raise AppArmorBug('Empty value in rlimit rule')

            elif rlimit in rlimit_size:
                if not RE_UNIT_SIZE.match(value):
                    raise AppArmorException('Invalid value or unit in rlimit %s %s rule' % (rlimit, value))
                self.value_as_int = self.size_to_int(value)

            elif rlimit in rlimit_number:
                if not RE_NUMBER.match(value):
                    raise AppArmorException('Invalid value in rlimit %s %s rule' % (rlimit, value))
                self.value_as_int = int(value)

            elif rlimit in rlimit_time:
                if not RE_NUMBER_UNIT.match(value):
                    raise AppArmorException('Invalid value in rlimit %s %s rule' % (rlimit, value))
                number, unit = split_unit(value)

                if rlimit == 'rttime':
                    self.value_as_int = self.time_to_int(value, 'us')
                else:
                    self.value_as_int = self.time_to_int(value, 'seconds')

            elif rlimit in rlimit_nice:  # pragma: no branch - "if rlimit in rlimit_all:" above avoids the need for an "else:" branch
                if not RE_NICE.match(value):
                    raise AppArmorException('Invalid value or unit in rlimit %s %s rule' % (rlimit, value))
                self.value_as_int = 0 - int(value)  # lower numbers mean a higher limit for nice

            # still here? fine :-)
            self.value = value
        else:
            raise AppArmorBug('Passed unknown object to RlimitRule: %s' % str(value))
예제 #5
0
파일: signal.py 프로젝트: youngker/apparmor
    def _parse(cls, raw_rule):
        '''parse raw_rule and return SignalRule'''

        matches = cls._match(raw_rule)
        if not matches:
            raise AppArmorException(_("Invalid signal rule '%s'") % raw_rule)

        audit, deny, allow_keyword, comment = parse_modifiers(matches)

        rule_details = ''
        if matches.group('details'):
            rule_details = matches.group('details')

        if rule_details:
            details = RE_SIGNAL_DETAILS.search(rule_details)
            if not details:
                raise AppArmorException(
                    _("Invalid or unknown keywords in 'signal %s" %
                      rule_details))

            if details.group('access'):
                access = details.group('access')
                if access.startswith('(') and access.endswith(')'):
                    access = access[1:-1]
                access = access.replace(
                    ',', ' ').split()  # split by ',' or whitespace
            else:
                access = SignalRule.ALL

            if details.group('signal'):
                signal = details.group('signal')
                signal = RE_FILTER_SET_1.sub(r'\1',
                                             signal)  # filter out 'set='
                signal = RE_FILTER_SET_2.sub('', signal)  # filter out 'set='
                signal = RE_FILTER_QUOTES.sub(r' \1 ',
                                              signal)  # filter out quote pairs
                signal = signal.replace(
                    ',', ' ').split()  # split at ',' or whitespace
            else:
                signal = SignalRule.ALL

            if details.group('peer'):
                peer = details.group('peer')
            else:
                peer = SignalRule.ALL
        else:
            access = SignalRule.ALL
            signal = SignalRule.ALL
            peer = SignalRule.ALL

        return SignalRule(access,
                          signal,
                          peer,
                          audit=audit,
                          deny=deny,
                          allow_keyword=allow_keyword,
                          comment=comment)
예제 #6
0
def output_policy(easyp, params, count, destdir, force=False, include=[]):
    '''Output policy'''
    policy = easyp.gen_policy(**params)

    # Inject include if it is specified
    if len(include) > 0:
        inject_s = '# injected via click hook'
        for f in include:
            inject_s += '''
  #include "%s"''' % f
        policy = re.sub(r'(\s}\s+)$', '\n  %s\\1' % inject_s, policy)

    out_fn = None
    if not destdir:  # pragma: no cover
        if count:
            sys.stdout.write('### aa-easyprof profile #%d ###\n' % count)
        sys.stdout.write('%s\n' % policy)
        return None
    else:
        if 'profile_name' in params:
            appname = AppName(raw_name=params['profile_name'])
        # elif 'binary' in params:
        #     out_fn = params['binary']
        else:  # pragma: no cover
            raise AppArmorException("Could not determine output filename")

        # Generate an absolute path, converting any path delimiters to '.'
        out_fn = os.path.join(destdir, appname.profile_filename)

        if not os.path.exists(destdir):
            os.mkdir(destdir)

        if not os.path.isdir(destdir):  # pragma: no cover
            raise AppArmorException("'%s' is not a directory" % destdir)

        f, fn = tempfile.mkstemp(prefix='aa-easyprof')
        if not isinstance(policy, bytes):
            policy = policy.encode('utf-8')
        os.write(f, policy)
        os.close(f)

        # Only update if the contents are different
        policy_orig = "".encode('utf-8')
        if not force and os.path.exists(out_fn):
            with open(out_fn) as orig:
                policy_orig = orig.read()
                if not isinstance(policy_orig, bytes):
                    policy_orig = policy_orig.encode('utf-8')

        if force or policy_orig != policy:
            shutil.move(fn, out_fn)
            os.chmod(out_fn, 0o644)
        else:
            os.unlink(fn)

    return out_fn
예제 #7
0
    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)

        # variables don't support audit or deny
        if audit:
            raise AppArmorBug('Attempt to initialize %s with audit flag' %
                              self.__class__.__name__)
        if deny:
            raise AppArmorBug('Attempt to initialize %s with deny flag' %
                              self.__class__.__name__)

        if not type_is_str(varname):
            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):
            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))

        if type(values) is not set:
            raise AppArmorBug('Passed unknown type for values to %s: %s' %
                              (self.__class__.__name__, values))
        if not values:
            raise AppArmorException('Passed empty list of values to %s: %s' %
                                    (self.__class__.__name__, values))

        self.varname = varname
        self.mode = mode
        self.values = values
예제 #8
0
def aa_exec(command, opt, environ={}, verify_rules=[]):
    '''Execute binary under specified policy'''
    if opt.profile != None:
        policy_name = opt.profile
    else:
        opt.ensure_value("template_var", None)
        opt.ensure_value("name", None)
        opt.ensure_value("comment", None)
        opt.ensure_value("author", None)
        opt.ensure_value("copyright", None)

        binary = command[0]
        policy_name = gen_policy_name(binary)
        easyp = apparmor.easyprof.AppArmorEasyProfile(binary, opt)
        params = apparmor.easyprof.gen_policy_params(policy_name, opt)
        policy = easyp.gen_policy(**params)
        debug("\n%s" % policy)

        tmp = tempfile.NamedTemporaryFile(prefix='%s-' % policy_name)
        if sys.version_info[0] >= 3:
            tmp.write(bytes(policy, 'utf-8'))
        else:
            tmp.write(policy)
        tmp.flush()

        debug("using '%s' template" % opt.template)
        # TODO: get rid of this
        if opt.withx:
            rc, report = cmd(
                ['pkexec', 'apparmor_parser', '-r',
                 '%s' % tmp.name])
        else:
            rc, report = cmd(['sudo', 'apparmor_parser', '-r', tmp.name])
        if rc != 0:
            raise AppArmorException("Could not load policy")

        rc, report = cmd(['sudo', 'apparmor_parser', '-p', tmp.name])
        if rc != 0:
            raise AppArmorException("Could not dump policy")

        # Make sure the dynamic profile has the appropriate line for X
        for r in verify_rules:
            found = False
            for line in report.splitlines():
                line = line.strip()
                if r == line:
                    found = True
                    break
            if not found:
                raise AppArmorException("Could not find required rule: %s" % r)

    set_environ(environ)
    args = ['aa-exec', '-p', policy_name, '--'] + command
    rc, report = cmd(args)
    return rc, report
예제 #9
0
def parse_manifest_name(name):
    '''Parse a manifest name'''
    (n, ext) = os.path.splitext(name)
    if not ext == ".json":
        raise AppArmorException("unable to parse manifest name %s" % (name))

    out = n.split("_")
    if len(out) != 3:
        raise AppArmorException("unable to parse manifest name %s" % (name))

    return tuple(out)
예제 #10
0
파일: ui.py 프로젝트: pexip/os-apparmor
def get_translated_hotkey(translated, cmsg=''):
    msg = 'PromptUser: '******'Invalid hotkey for')

    # Originally (\S) was used but with translations it would not work :(
    if re.search('\((\S+)\)', translated):
        return re.search('\((\S+)\)', translated).groups()[0]
    else:
        if cmsg:
            raise AppArmorException(cmsg)
        else:
            raise AppArmorException('%s %s' % (msg, translated))
예제 #11
0
def _raw_transform(fin, fout):
    '''Copy input file to output file'''
    if fin.endswith('.profile'):
        name = os.path.basename(os.path.splitext(fin)[0])
    else:
        name = os.path.basename(fin)

    orig = open_file_read(fin).read()
    out = re.sub(r'###PROFILEATTACH###', 'profile "%s"' % name, orig)

    tmp = name.split("_")
    if len(tmp) != 3:
        raise AppArmorException("unable to parse profile name %s" % (name))
    (package, appname, version) = tuple(tmp)

    profile_vars = '''@{CLICK_DIR}="%s"
@{APP_PKGNAME}="%s"
@{APP_APPNAME}="%s"
@{APP_VERSION}="%s"''' % (_get_click_dir_variable(), package, appname, version)

    out = re.sub(r'###VAR###', profile_vars, out)

    tmp, tmp_fn = tempfile.mkstemp(prefix='aa-profile-hook')
    if not isinstance(out, bytes):
        out = out.encode('utf-8')
    os.write(tmp, out)
    os.close(tmp)

    shutil.move(tmp_fn, fout)
    os.chmod(fout, 0o644)
예제 #12
0
def apparmor_available(parser="/sbin/apparmor_parser", apparmor_dirs=None):
    '''Is AppArmor available for use on this system'''
    dirs = apparmor_dirs
    if dirs is None:
        dirs = ['/sys/module/apparmor', apparmor_fs]

    for d in dirs:
        if mock_testenv and apparmor_dirs is None:  # pragma: no cover
            break
        if not os.path.isdir(d):
            raise AppArmorException("Could not find '%s'" % d)

    if not os.path.exists(parser):  # pragma: no cover
        rc, parser = apparmor.easyprof.cmd(['which', 'apparmor_parser'])
        if rc != 0:
            raise AppArmorException("Could not find apparmor_parser")
예제 #13
0
    def profile_filename(self, profile_filename):
        if not profile_filename.startswith(self._CLICK_PREFIX):
            raise AppArmorException("invalid click profile name '%s'" %
                                    (profile_filename))

        # Strip the click prefix off of the string
        self._clickname = profile_filename[len(self._CLICK_PREFIX):]
예제 #14
0
    def click_name(self, click_name):
        if not click_name.endswith(self._CLICK_SUFFIX):
            raise AppArmorException("invalid click manifest name '%s'" %
                                    (click_name))

        # strip the suffix off
        self._clickname = click_name[:-len(self._CLICK_SUFFIX)]
예제 #15
0
    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)

        self.access, self.all_access, unknown_items = check_and_split_list(
            access, access_keywords, PtraceRule.ALL, 'PtraceRule', 'access')
        if unknown_items:
            raise AppArmorException(
                _('Passed unknown access keyword to PtraceRule: %s') %
                ' '.join(unknown_items))

        self.peer, self.all_peers = self._aare_or_all(peer,
                                                      'peer',
                                                      is_path=False,
                                                      log_event=log_event)
예제 #16
0
def parse_profile_start_line(line, filename):
    matches = RE_PROFILE_START.search(line)

    if not matches:
        raise AppArmorBug('The given line from file %(filename)s is not the start of a profile: %(line)s' % { 'filename': filename, 'line': line } )

    result = {}

    for section in [ 'leadingspace', 'plainprofile', 'namedprofile', 'attachment', 'flags', 'comment']:
        if matches.group(section):
            result[section] = matches.group(section)

            # sections with optional quotes
            if section in ['plainprofile', 'namedprofile', 'attachment']:
                result[section] = strip_quotes(result[section])
        else:
            result[section] = None

    if result['flags'] and result['flags'].strip() == '':
        raise AppArmorException(_('Invalid syntax in %(filename)s: Empty set of flags in line %(line)s.' % { 'filename': filename, 'line': line } ))

    if result['plainprofile']:
        result['profile'] = result['plainprofile']
        result['profile_keyword'] = False
    else:
        result['profile'] = result['namedprofile']
        result['profile_keyword'] = True

    return result
예제 #17
0
    def __init__(self, title, geometry=None,
                              driver=None,
                              xauth=None,
                              clipboard=False):
        self.geometry = geometry
        self.title = title
        self.pids = []
        self.driver = driver
        self.clipboard = clipboard
        self.tempfiles = []
        self.timeout = 5 # used by xauth and for server starts

        # preserve our environment
        self.old_environ = dict()
        for env in ['DISPLAY', 'XAUTHORITY', 'UBUNTU_MENUPROXY',
                    'QT_X11_NO_NATIVE_MENUBAR', 'LIBOVERLAY_SCROLLBAR']:
            if env in os.environ:
                self.old_environ[env] = os.environ[env]

        # prepare the new environment
        self.display, self.xauth = self.find_free_x_display()
        if xauth:
            abs_xauth = os.path.expanduser(xauth)
            if os.path.expanduser("~/.Xauthority") == abs_xauth:
                raise AppArmorException("Trusted Xauthority file specified. Aborting")
            self.xauth = abs_xauth
        self.new_environ = dict()
        self.new_environ['DISPLAY'] = self.display
        self.new_environ['XAUTHORITY'] = self.xauth
        # Disable the global menu for now
        self.new_environ["UBUNTU_MENUPROXY"] = ""
        self.new_environ["QT_X11_NO_NATIVE_MENUBAR"] = "1"
        # Disable the overlay scrollbar for now-- they don't track correctly
        self.new_environ["LIBOVERLAY_SCROLLBAR"] = "0"
예제 #18
0
    def start(self):
        '''Start a nested X server (need to override)'''
        # clean up the old one
        if os.path.exists(self.xauth):
            os.unlink(self.xauth)
        rc, cookie = cmd(['mcookie'])
        if rc != 0:
            raise AppArmorException("Could not generate magic cookie")

        rc, out = cmd(['xauth', '-f', self.xauth, \
                       'add', \
                       self.display, \
                       'MIT-MAGIC-COOKIE-1', \
                       cookie.strip()])
        if rc != 0:
            raise AppArmorException("Could not generate '%s'" % self.display)
예제 #19
0
def json_response(dialog_type):
    string = raw_input('\n')
    rh = json.loads(string.strip())
    if rh["dialog"] != dialog_type:
        raise AppArmorException('Expected response %s got %s.' %
                                (dialog_type, string))
    return rh
예제 #20
0
    def start(self):
        for e in ['Xephyr', 'matchbox-window-manager']:
            debug("Searching for '%s'" % e)
            rc, report = cmd(['which', e])
            if rc != 0:
                raise AppArmorException("Could not find '%s'" % e)
        '''Run any setup code'''
        SandboxXserver.start(self)
        '''Start a Xephyr server'''
        listener_x = os.fork()
        if listener_x == 0:
            # TODO: break into config file? Which are needed?
            x_exts = [
                '-extension', 'GLX', '-extension', 'MIT-SHM', '-extension',
                'RENDER', '-extension', 'SECURITY', '-extension', 'DAMAGE'
            ]
            # verify_these
            x_extra_args = [
                '-host-cursor',  # less secure?
                '-fakexa',  # for games? seems not needed
                '-nodri',  # more secure?
            ]

            if not self.geometry:
                self.geometry = "640x480"
            x_args = [
                '-nolisten',
                'tcp',
                '-screen',
                self.geometry,
                '-br',  # black background
                '-reset',  # reset after last client exists
                '-terminate',  # terminate at server reset
                '-title',
                self.generate_title(),
            ] + x_exts + x_extra_args

            args = ['/usr/bin/Xephyr'] + x_args + [self.display]
            debug(" ".join(args))
            os.execv(args[0], args)
            sys.exit(0)
        self.pids.append(listener_x)

        time.sleep(1)  # FIXME: detect if running

        # Next, start the window manager
        sys.stdout.flush()
        os.chdir(os.environ["HOME"])
        listener_wm = os.fork()
        if listener_wm == 0:
            # update environment
            set_environ(self.new_environ)

            args = ['/usr/bin/matchbox-window-manager', '-use_titlebar', 'no']
            debug(" ".join(args))
            cmd(args)
            sys.exit(0)

        self.pids.append(listener_wm)
        time.sleep(1)  # FIXME: detect if running
예제 #21
0
    def _parse(cls, raw_rule):
        '''parse raw_rule and return ChangeProfileRule'''

        matches = cls._match(raw_rule)
        if not matches:
            raise AppArmorException(
                _("Invalid change_profile rule '%s'") % raw_rule)

        audit, deny, allow_keyword, comment = parse_modifiers(matches)

        execmode = matches.group('execmode')

        if matches.group('execcond'):
            execcond = strip_quotes(matches.group('execcond'))
        else:
            execcond = ChangeProfileRule.ALL

        if matches.group('targetprofile'):
            targetprofile = strip_quotes(matches.group('targetprofile'))
        else:
            targetprofile = ChangeProfileRule.ALL

        return ChangeProfileRule(execmode,
                                 execcond,
                                 targetprofile,
                                 audit=audit,
                                 deny=deny,
                                 allow_keyword=allow_keyword,
                                 comment=comment)
예제 #22
0
    def find_free_x_display(self):
        '''Find a free X display'''
        old_lang = None
        if 'LANG' in os.environ:
            old_lang = os.environ['LANG']
        os.environ['LANG'] = 'C'

        display = ""
        current = self.old_environ["DISPLAY"]
        for i in range(1, 257):  # TODO: this puts an artificial limit of 256
            #       sandboxed applications
            tmp = ":%d" % i
            os.environ["DISPLAY"] = tmp
            rc, report = cmd(['xset', '-q'])
            if rc != 0 and 'Invalid MIT-MAGIC-COOKIE-1' not in report:
                display = tmp
                break

        if old_lang:
            os.environ['LANG'] = old_lang

        os.environ["DISPLAY"] = current
        if display == "":
            raise AppArmorException("Could not find available X display")

        # Use dedicated .Xauthority file
        xauth = os.path.join(os.path.expanduser('~'), \
                             '.Xauthority-sandbox%s' % display.split(':')[1])

        return display, xauth
예제 #23
0
파일: ui.py 프로젝트: pexip/os-apparmor
def generate_diff_with_comments(oldprofile, newprofile):
    if not os.path.exists(oldprofile):
        raise AppArmorException(_("Can't find existing profile %s to compare changes.") % oldprofile)
    newtemp = write_profile_to_tempfile(newprofile)
    difftemp = diff(oldprofile, newtemp.name)
    newtemp.close()
    return difftemp
예제 #24
0
 def write_config(self, filename, config):
     """Writes the given config to the specified file"""
     filepath = self.CONF_DIR + '/' + filename
     permission_600 = stat.S_IRUSR | stat.S_IWUSR  # Owner read and write
     try:
         # Open a temporary file in the CONF_DIR to write the config file
         config_file = tempfile.NamedTemporaryFile('w',
                                                   prefix='aa_temp',
                                                   delete=False,
                                                   dir=self.CONF_DIR)
         if os.path.exists(self.input_file):
             # Copy permissions from an existing file to temporary file
             shutil.copymode(self.input_file, config_file.name)
         else:
             # If no existing permission set the file permissions as 0600
             os.chmod(config_file.name, permission_600)
         if self.conf_type == 'shell':
             self.write_shell(filepath, config_file, config)
         elif self.conf_type == 'ini':
             self.write_configparser(filepath, config_file, config)
         config_file.close()
     except IOError:
         raise AppArmorException("Unable to write to %s" % filename)
     else:
         # Replace the target config file with the temporary file
         os.rename(config_file.name, filepath)
예제 #25
0
def unload_profile(profile):
    '''Unload a profile name from the kernel'''
    try:
        apparmor_available()
    except AppArmorException as e:  # pragma: no cover
        raise AppArmorException("%s. Skipping unload" % e)

    _unload_profile(profile)
예제 #26
0
 def rank_path(self, path, mode=None):
     """Returns the rank for the given path"""
     if '@' in path:  # path contains variable
         return self.handle_variable_rank(path, mode)
     elif path[0] == '/':  # file resource
         return self.handle_file(path, mode)
     else:
         raise AppArmorException("Unexpected path input: %s" % path)
예제 #27
0
 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
     if conf_type == 'shell' or conf_type == 'ini':
         self.conf_type = conf_type
         self.input_file = None
     else:
         raise AppArmorException("Unknown configuration file type")
예제 #28
0
def unload_profiles(profiles):
    '''Unload a list of profile names from the kernel'''
    try:
        apparmor_available()
    except AppArmorException as e:  # pragma: no cover
        raise AppArmorException("%s. Skipping unload" % e)

    for profile in profiles:
        _unload_profile(profile)
예제 #29
0
def read_click_manifest(manifest):
    '''Read click manifest'''
    f = open(manifest, "r", encoding="UTF-8")
    j = json.load(f)
    for field in required_click_fields:
        if field not in j:
            raise AppArmorException("could not find required field " +
                                    "'%s' in json" % (field))
    return j
예제 #30
0
def load_profile(profile,
                 parser="/sbin/apparmor_parser",
                 args=['-r', '--write-cache']):
    '''Load individual profile into the kernel'''

    try:
        apparmor_available(parser)
    except AppArmorException as e:  # pragma: nocover
        raise AppArmorException("%s. Skipping load" % e)

    command = [parser]
    command.extend(args)
    command.append(profile)
    rc, output = apparmor.easyprof.cmd(command)
    if rc != 0:  # pragma: nocover
        raise AppArmorException("policy load failed with exit status %d: %s" %
                                (rc, output))
    return (rc, output)