def test_record_as_admin_user(self): """ Check tlog-rec preserves sudo activity of admin user in recordings """ logfile = mklogfile(self.tempdir) cfg = ''' %wheel ALL=(ALL) NOPASSWD: ALL ''' mkcfgfile('/etc/sudoers.d/01_wheel_nopass', cfg) shell = ssh_pexpect(self.admin1, 'Secret123', 'localhost') shell.sendline('tlog-rec -o {}'.format(logfile)) shell.sendline('whoami') shell.expect(self.admin1) shell.sendline('sleep 2') shell.sendline('echo test1223') shell.expect('test1223') shell.sendline('sudo ls -ltr /var/log/audit') shell.expect('audit.log') shell.sendline('exit') check_outfile('test1223', logfile) check_recording(shell, 'test1223', logfile) shell.close() shell = ssh_pexpect(self.admin1, 'Secret123', 'localhost') check_recording(shell, 'audit.log', logfile) shell.close()
def test_conf_file_var(self, session_env_config_setup): """ Validate configuration settings are overwritten by TLOG_REC_SESSION_CONF_FILE variable """ logfile = mklogfile(self.tempdir) msg = inspect.stack()[0][3] input_notice = "Test NOTICE" tmp_conf_file = TMP_TLOG_REC_SESSION_CONF # system wide journal configuration file sessionclass_system = TlogRecSessionConfig(writer="journal") sessionclass_system.generate_config(SYSTEM_TLOG_REC_SESSION_CONF) # temporary configuration file to override with sessionclass_tmp = TlogRecSessionConfig(writer="file", file_writer_path=logfile, notice=input_notice) sessionclass_tmp.generate_config(tmp_conf_file) shell = ssh_pexpect(self.user1, 'Secret123', 'localhost') shell.sendline(f'export TLOG_REC_SESSION_CONF_FILE={tmp_conf_file}') shell.sendline(TLOG_REC_SESSION_PROG) # validate the notice override shell.expect(input_notice) shell.sendline(f'echo {msg}') shell.expect(msg) shell.sendline('exit') check_recording(shell, msg, logfile) shell.close()
def test_record_command_to_syslog(self): """ Check tlog-rec preserves output when recording to syslog """ shell = ssh_pexpect(self.user1, 'Secret123', 'localhost') reccmd = 'echo test_record_to_syslog' shell.sendline('tlog-rec --writer=syslog {}'.format(reccmd)) check_journal('test_record_to_syslog') check_recording(shell, 'test_record_to_syslog') shell.close()
def test_record_command_to_file(self): """ Check tlog-rec preserves output when reording to file """ logfile = mklogfile(self.tempdir) shell = ssh_pexpect(self.user1, 'Secret123', 'localhost') shell.sendline('tlog-rec -o {} whoami'.format(logfile)) check_outfile('out_txt\":\"{}'.format(self.user1), logfile) check_recording(shell, self.user1, logfile) shell.close()
def test_record_binary_output(self): """ Check tlog-rec preserves binary output in recordings """ logfile = mklogfile(self.tempdir) shell = ssh_pexpect(self.user1, 'Secret123', 'localhost') reccmd = 'cat /usr/bin/gzip' shell.sendline('tlog-rec -o {} {}'.format(logfile, reccmd)) shell.expect(r'\u0000') check_recording(shell, r'\u0000', logfile) shell.close()
def test_record_command_to_syslog(self): """ Check tlog-rec preserves output when recording to syslog """ match_filter = '_COMM=tlog-rec' shell = ssh_pexpect(self.user1, 'Secret123', 'localhost') reccmd = 'test_record_to_syslog' shell.sendline('tlog-rec --writer=syslog echo {}'.format(reccmd)) check_journal(reccmd) check_recording(shell, reccmd) shell.close()
def test_record_command_to_journal(self): """ Check tlog-rec preserves output when recording to journal """ match_filter = '_COMM=tlog-rec' shell = ssh_pexpect(self.user1, 'Secret123', 'localhost') reccmd = 'test_record_to_journal' shell.sendline('tlog-rec -w journal echo {}'.format(reccmd)) find_journal_entry_with_match(reccmd, match_filter, 10) check_recording(shell, 'test_record_to_journal') shell.close()
def test_session_record_to_syslog(self): """ Check tlog-rec-session preserves session via syslog """ myname = inspect.stack()[0][3] sessionclass = TlogRecSessionConfig(writer="syslog") sessionclass.generate_config(SYSTEM_TLOG_REC_SESSION_CONF) shell = ssh_pexpect(self.user, 'Secret123', 'localhost') shell.sendline('echo {}'.format(myname)) shell.sendline('exit') check_recording(shell, myname) shell.close()
def test_record_fast_input_with_payload(self): """ Check tlog-rec limits output payload size """ logfile = mklogfile(self.tempdir) shell = ssh_pexpect(self.user1, 'Secret123', 'localhost') opts = '--payload=128' shell.sendline('tlog-rec {} ' '-o {} /bin/bash'.format(opts, logfile)) for num in range(0, 200): shell.sendline('echo test_{}'.format(num)) shell.sendline('exit') check_recording(shell, 'test_199', logfile) shell.close()
def test_record_fast_input_with_limit_action_pass(self): """ Check tlog-rec ignores logging limits """ logfile = mklogfile(self.tempdir) shell = ssh_pexpect(self.user1, 'Secret123', 'localhost') opts = '--limit-rate=10 --limit-action=pass' shell.sendline('tlog-rec {} ' '-o {} /bin/bash'.format(opts, logfile)) for num in range(0, 200): shell.sendline('echo test_{}'.format(num)) shell.sendline('exit') check_recording(shell, 'test_199', logfile) shell.close()
def test_record_fast_input(self): """ Check tlog-rec preserves fast flooded I/O in recordings """ logfile = mklogfile(self.tempdir) shell = ssh_pexpect(self.user1, 'Secret123', 'localhost') shell.sendline('tlog-rec -o {} /bin/bash'.format(logfile)) for num in range(0, 2000): shell.sendline('echo test_{}'.format(num)) shell.sendline('exit') for num in range(0, 2000, 100): check_recording(shell, 'test_{}'.format(num), logfile) shell.close()
def test_record_fast_input_with_latency(self): """ Check tlog-rec caches data some time before logging """ logfile = mklogfile(self.tempdir) shell = ssh_pexpect(self.user1, 'Secret123', 'localhost') opts = '--latency=9' shell.sendline('tlog-rec {} ' '-o {} /bin/bash'.format(opts, logfile)) for num in range(0, 200): shell.sendline('echo test_{}'.format(num)) shell.sendline('exit') check_recording(shell, 'test_199', logfile) shell.close()
def test_session_record_with_different_shell(self): """ Check tlog-rec-session can specify different shell """ logfile = mklogfile(self.tempdir) sessionclass = TlogRecSessionConfig(shell="/usr/bin/tcsh", writer="file", file_writer_path=logfile) sessionclass.generate_config(SYSTEM_TLOG_REC_SESSION_CONF) shell = ssh_pexpect(self.user, 'Secret123', 'localhost') shell.sendline('echo $SHELL') check_recording(shell, '/usr/bin/tcsh', logfile) shell.sendline('exit')
def test_record_fast_input_with_limit_action_delay(self): """ Check tlog-rec delays recording when logging limit reached """ logfile = mklogfile(self.tempdir) shell = ssh_pexpect(self.user1, 'Secret123', 'localhost') opts = '--limit-rate=10 --limit-action=delay' shell.sendline('tlog-rec {} ' '-o {} /bin/bash'.format(opts, logfile)) for num in range(0, 200): shell.sendline('echo test_{}'.format(num)) check_outfile('test_199', logfile, maxchecks=100) shell.sendline('exit') check_recording(shell, 'test_199', logfile) shell.close()
def test_session_record_to_file(self): """ Check tlog-rec-session preserves session in a file """ myname = inspect.stack()[0][3] logfile = mklogfile(self.tempdir) sessionclass = TlogRecSessionConfig(writer="file", file_writer_path=logfile) sessionclass.generate_config(SYSTEM_TLOG_REC_SESSION_CONF) shell = ssh_pexpect(self.user, 'Secret123', 'localhost') shell.sendline('echo {}'.format(myname)) shell.sendline('exit') check_recording(shell, myname, logfile) shell.close()
def test_session_record_fast_input_with_latency(self): """ Check tlog-rec-session caches data some time before logging """ myname = inspect.stack()[0][3] logfile = mklogfile(self.tempdir) sessionclass = TlogRecSessionConfig(writer="file", file_writer_path=logfile, latency=15) shell = ssh_pexpect(self.user, 'Secret123', 'localhost') for num in range(0, 200): shell.sendline('echo {}_{}'.format(myname, num)) shell.sendline('exit') check_recording(shell, '{}_199'.format(myname), logfile) shell.close()
def test_session_record_fast_input_with_payload(self): """ Check tlog-rec limits output payload size """ myname = inspect.stack()[0][3] logfile = mklogfile(self.tempdir) sessionclass = TlogRecSessionConfig(writer="file", file_writer_path=logfile, payload=128) sessionclass.generate_config(SYSTEM_TLOG_REC_SESSION_CONF) shell = ssh_pexpect(self.user, 'Secret123', 'localhost') for num in range(0, 200): shell.sendline('echo {}_{}'.format(myname, num)) shell.sendline('exit') check_recording(shell, '{}_199'.format(myname), logfile) shell.close()
def test_session_record_fast_input_with_limit_action_delay(self): """ Check tlog-rec-session delays recording when logging limit reached """ myname = inspect.stack()[0][3] logfile = mklogfile(self.tempdir) sessionclass = TlogRecSessionConfig(writer="file", file_writer_path=logfile, limit_rate=500, limit_action="delay") sessionclass.generate_config(SYSTEM_TLOG_REC_SESSION_CONF) shell = ssh_pexpect(self.user, 'Secret123', 'localhost') for num in range(0, 200): shell.sendline('echo {}_{}'.format(myname, num)) shell.sendline('exit') check_recording(shell, '{}_199'.format(myname), logfile) shell.close()
def test_record_interactive_session(self): """ Check tlog-rec preserves activity during interactive session in recordings """ logfile = mklogfile(self.tempdir) shell = ssh_pexpect(self.user1, 'Secret123', 'localhost') shell.sendline('tlog-rec -o {}'.format(logfile)) shell.sendline('whoami') shell.expect(self.user1) shell.sendline('sleep 2') shell.sendline('echo test123') shell.expect('test123') shell.sendline('echo test1123out>/tmp/pexpect.test1123out') check_outfile('test1123out', logfile) check_recording(shell, 'test1123out', logfile) shell.close()
def test_record_as_unprivileged_user(self): """ Check tlog-rec preserves unauthorized activity of unprivileged user in recordings """ logfile = mklogfile(self.tempdir) shell = ssh_pexpect(self.user1, 'Secret123', 'localhost') shell.sendline('tlog-rec -o {}'.format(logfile)) shell.sendline('whoami') shell.expect(self.user1) shell.sendline('echo test1123out') shell.sendline('sleep 2') shell.sendline('ls -ltr /var/log/audit') check_recording(shell, 'test1123out', logfile) check_recording(shell, 'Permission denied', logfile) shell.sendline('exit') shell.close()
def test_session_record_user_in_utmp(self, utempter_enabled): """ Check tlog-rec-session preserves session in a file """ if not utempter_enabled: pytest.skip('utempter not enabled, skipping test') myname = inspect.stack()[0][3] whoami = '{} pts'.format(self.user) logfile = mklogfile(self.tempdir) sessionclass = TlogRecSessionConfig(writer="file", file_writer_path=logfile) sessionclass.generate_config(SYSTEM_TLOG_REC_SESSION_CONF) shell = ssh_pexpect(self.user, 'Secret123', 'localhost') shell.sendline('echo {}'.format(myname)) shell.sendline('who am i') shell.sendline('exit') check_recording(shell, myname, logfile) check_recording(shell, whoami, logfile) shell.close()
def test_record_diff_char_sets(self): """ Check tlog-rec preserves non-English I/O in recordings """ logfile = '{}-ru_RU'.format(mklogfile(self.tempdir)) shell = ssh_pexpect(self.user1, 'Secret123', 'localhost') shell.sendline('tlog-rec -o {} /bin/bash'.format(logfile)) shell.sendline('export LANG=ru_RU.utf8') shell.sendline('badcommand') shell.sendline('exit') check_outfile('найдена', logfile) check_recording(shell, 'найдена', logfile) shell.close() logfile = '{}-el_GR'.format(mklogfile(self.tempdir)) shell = ssh_pexpect(self.user1, 'Secret123', 'localhost') shell.sendline('tlog-rec -o {} /bin/bash'.format(logfile)) shell.sendline('export LANG=el_GR.utf8') shell.sendline('badcommand') shell.sendline('exit') check_outfile('βρέθηκε', logfile) check_recording(shell, 'βρέθηκε', logfile) shell.close() logfile = '{}-en_US'.format(mklogfile(self.tempdir)) shell = ssh_pexpect(self.user1, 'Secret123', 'localhost') shell.sendline('tlog-rec -o {} /bin/bash'.format(logfile)) shell.sendline('export LANG=en_US.utf8') shell.sendline('echo Watérmân') shell.sendline('exit') check_outfile('Watérmân', logfile) check_recording(shell, 'Watérmân', logfile) shell.expect('Watérmân') shell.close()
def test_conf_file_var(self, rec_env_config_setup): """ Validate configuration settings are overwritten by TLOG_REC_CONF_FILE variable """ logfile = mklogfile(self.tempdir) msg = inspect.stack()[0][3] tmp_conf_file = TMP_TLOG_REC_CONF # system wide configuration file recclass_system = TlogRecConfig(writer="journal") recclass_system.generate_config(SYSTEM_TLOG_REC_CONF) # temporary configuration file to override with recclass_tmp = TlogRecConfig(writer="file", file_writer_path=logfile) recclass_tmp.generate_config(tmp_conf_file) # validate the file writer override shell = ssh_pexpect(self.user1, 'Secret123', 'localhost') shell.sendline(f'export TLOG_REC_CONF_FILE={tmp_conf_file}') shell.sendline(TLOG_REC_PROG + f"-c echo {msg}") check_recording(shell, msg, logfile) shell.close()