def test_match_filter_recurses_exec_command_filter_matches(self): filter_list = [ filters.IpNetnsExecFilter(self._ip, 'root'), filters.IpFilter(self._ip, 'root') ] args = ['ip', 'netns', 'exec', 'foo', 'ip', 'link', 'list'] self.assertIsNotNone(wrapper.match_filter(filter_list, args))
def test_ChainingRegExpFilter_match(self): filter_list = [filters.ChainingRegExpFilter('nice', 'root', 'nice', '-?\d+'), filters.CommandFilter('cat', 'root')] args = ['nice', '5', 'cat', '/a'] dirs = ['/bin', '/usr/bin'] self.assertIsNotNone(wrapper.match_filter(filter_list, args, dirs))
def test_ChainingRegExpFilter_match(self): filter_list = [ filters.ChainingRegExpFilter("nice", "root", "nice", "-?\d+"), filters.CommandFilter("cat", "root"), ] args = ["nice", "5", "cat", "/a"] dirs = ["/bin", "/usr/bin"] self.assertIsNotNone(wrapper.match_filter(filter_list, args, dirs))
def test_ChainingRegExpFilter_match(self): filter_list = [ filters.ChainingRegExpFilter('nice', 'root', 'nice', '-?\d+'), filters.CommandFilter('cat', 'root') ] args = ['nice', '5', 'cat', '/a'] dirs = ['/bin', '/usr/bin'] self.assertIsNotNone(wrapper.match_filter(filter_list, args, dirs))
def test_ChainingRegExpFilter_multiple(self): filter_list = [ filters.ChainingRegExpFilter("ionice", "root", "ionice", "-c[0-3]"), filters.ChainingRegExpFilter("ionice", "root", "ionice", "-c[0-3]", "-n[0-7]"), filters.CommandFilter("cat", "root"), ] # both filters match to ['ionice', '-c2'], but only the second accepts args = ["ionice", "-c2", "-n7", "cat", "/a"] dirs = ["/bin", "/usr/bin"] self.assertIsNotNone(wrapper.match_filter(filter_list, args, dirs))
def test_ChainingRegExpFilter_multiple(self): filter_list = [filters.ChainingRegExpFilter('ionice', 'root', 'ionice', '-c[0-3]'), filters.ChainingRegExpFilter('ionice', 'root', 'ionice', '-c[0-3]', '-n[0-7]'), filters.CommandFilter('cat', 'root')] # both filters match to ['ionice', '-c2'], but only the second accepts args = ['ionice', '-c2', '-n7', 'cat', '/a'] dirs = ['/bin', '/usr/bin'] self.assertIsNotNone(wrapper.match_filter(filter_list, args, dirs))
def test_ChainingRegExpFilter_multiple(self): filter_list = [ filters.ChainingRegExpFilter('ionice', 'root', 'ionice', '-c[0-3]'), filters.ChainingRegExpFilter('ionice', 'root', 'ionice', '-c[0-3]', '-n[0-7]'), filters.CommandFilter('cat', 'root') ] # both filters match to ['ionice', '-c2'], but only the second accepts args = ['ionice', '-c2', '-n7', 'cat', '/a'] dirs = ['/bin', '/usr/bin'] self.assertIsNotNone(wrapper.match_filter(filter_list, args, dirs))
def test_RegExpFilter_match(self): usercmd = ["ls", "/root"] filtermatch = wrapper.match_filter(self.filters, usercmd) self.assertFalse(filtermatch is None) self.assertEqual(filtermatch.get_command(usercmd), ["/bin/ls", "/root"])
def test_skips(self): # Check that all filters are skipped and that the last matches usercmd = ["cat", "/"] filtermatch = wrapper.match_filter(self.filters, usercmd) self.assertTrue(filtermatch is self.filters[-1])
def test_match_filter_recurses_exec_command_filter_matches(self): filter_list = [filters.IpNetnsExecFilter(self._ip, "root"), filters.IpFilter(self._ip, "root")] args = ["ip", "netns", "exec", "foo", "ip", "link", "list"] self.assertIsNotNone(wrapper.match_filter(filter_list, args))
def main(): # Split arguments, require at least a command execname = sys.argv.pop(0) if len(sys.argv) < 2: _exit_error(execname, "No command specified", RC_NOCOMMAND, log=False) configfile = sys.argv.pop(0) userargs = sys.argv[:] # Add ../ to sys.path to allow running from branch possible_topdir = os.path.normpath(os.path.join(os.path.abspath(execname), os.pardir, os.pardir)) if os.path.exists(os.path.join(possible_topdir, "oslo", "__init__.py")): sys.path.insert(0, possible_topdir) from oslo.rootwrap import wrapper # Load configuration try: rawconfig = moves.configparser.RawConfigParser() rawconfig.read(configfile) config = wrapper.RootwrapConfig(rawconfig) except ValueError as exc: msg = "Incorrect value in %s: %s" % (configfile, exc.message) _exit_error(execname, msg, RC_BADCONFIG, log=False) except moves.configparser.Error: _exit_error(execname, "Incorrect configuration file: %s" % configfile, RC_BADCONFIG, log=False) if config.use_syslog: wrapper.setup_syslog(execname, config.syslog_log_facility, config.syslog_log_level) # Execute command if it matches any of the loaded filters filters = wrapper.load_filters(config.filters_path) try: filtermatch = wrapper.match_filter(filters, userargs, exec_dirs=config.exec_dirs) if filtermatch: command = filtermatch.get_command(userargs, exec_dirs=config.exec_dirs) if config.use_syslog: logging.info("(%s > %s) Executing %s (filter match = %s)" % ( _getlogin(), pwd.getpwuid(os.getuid())[0], command, filtermatch.name)) obj = subprocess.Popen(command, stdin=sys.stdin, stdout=sys.stdout, stderr=sys.stderr, preexec_fn=_subprocess_setup, env=filtermatch.get_environment(userargs)) obj.wait() sys.exit(obj.returncode) except wrapper.FilterMatchNotExecutable as exc: msg = ("Executable not found: %s (filter match = %s)" % (exc.match.exec_path, exc.match.name)) _exit_error(execname, msg, RC_NOEXECFOUND, log=config.use_syslog) except wrapper.NoFilterMatched: msg = ("Unauthorized command: %s (no filter matched)" % ' '.join(userargs)) _exit_error(execname, msg, RC_UNAUTHORIZED, log=config.use_syslog)
def test_match_filter_recurses_exec_command_filter_matches(self): filter_list = [filters.IpNetnsExecFilter('/sbin/ip', 'root'), filters.IpFilter('/sbin/ip', 'root')] args = ['ip', 'netns', 'exec', 'foo', 'ip', 'link', 'list'] self.assertIsNotNone(wrapper.match_filter(filter_list, args))
def main(): # Split arguments, require at least a command execname = sys.argv.pop(0) if len(sys.argv) < 2: _exit_error(execname, "No command specified", RC_NOCOMMAND, log=False) configfile = sys.argv.pop(0) userargs = sys.argv[:] # Add ../ to sys.path to allow running from branch possible_topdir = os.path.normpath( os.path.join(os.path.abspath(execname), os.pardir, os.pardir)) if os.path.exists(os.path.join(possible_topdir, "oslo", "__init__.py")): sys.path.insert(0, possible_topdir) from oslo.rootwrap import wrapper # Load configuration try: rawconfig = moves.configparser.RawConfigParser() rawconfig.read(configfile) config = wrapper.RootwrapConfig(rawconfig) except ValueError as exc: msg = "Incorrect value in %s: %s" % (configfile, exc.message) _exit_error(execname, msg, RC_BADCONFIG, log=False) except moves.configparser.Error: _exit_error(execname, "Incorrect configuration file: %s" % configfile, RC_BADCONFIG, log=False) if config.use_syslog: wrapper.setup_syslog(execname, config.syslog_log_facility, config.syslog_log_level) # Execute command if it matches any of the loaded filters filters = wrapper.load_filters(config.filters_path) try: filtermatch = wrapper.match_filter(filters, userargs, exec_dirs=config.exec_dirs) if filtermatch: command = filtermatch.get_command(userargs, exec_dirs=config.exec_dirs) if config.use_syslog: logging.info("(%s > %s) Executing %s (filter match = %s)" % (_getlogin(), pwd.getpwuid( os.getuid())[0], command, filtermatch.name)) obj = subprocess.Popen(command, stdin=sys.stdin, stdout=sys.stdout, stderr=sys.stderr, preexec_fn=_subprocess_setup, env=filtermatch.get_environment(userargs)) obj.wait() sys.exit(obj.returncode) except wrapper.FilterMatchNotExecutable as exc: msg = ("Executable not found: %s (filter match = %s)" % (exc.match.exec_path, exc.match.name)) _exit_error(execname, msg, RC_NOEXECFOUND, log=config.use_syslog) except wrapper.NoFilterMatched: msg = ("Unauthorized command: %s (no filter matched)" % ' '.join(userargs)) _exit_error(execname, msg, RC_UNAUTHORIZED, log=config.use_syslog)