diff --git a/utils/apparmor/notify.py b/utils/apparmor/notify.py index 81d702972..1101a2934 100644 --- a/utils/apparmor/notify.py +++ b/utils/apparmor/notify.py @@ -22,6 +22,16 @@ from apparmor.common import AppArmorBug, DebugLogger debug_logger = DebugLogger('apparmor.notify') +def sane_timestamp(timestamp): + ''' Check if the given timestamp is in a date range that makes sense for a wtmp file ''' + + if timestamp < 946681200: # 2000-01-01 + return False + elif timestamp > 2524604400: # 2050-01-01 + return False + + return True + def get_last_login_timestamp(username, filename='/var/log/wtmp'): '''Directly read wtmp and get last login for user as epoch timestamp''' timestamp = 0 @@ -33,11 +43,37 @@ def get_last_login_timestamp(username, filename='/var/log/wtmp'): offset = 0 wtmp_filesize = os.path.getsize(filename) debug_logger.debug('WTMP filesize: {}'.format(wtmp_filesize)) + + if wtmp_filesize < 356: + return 0 # (nearly) empty wtmp file, no entries + + # detect architecture based on utmp format differences + wtmp_file.seek(340) # first possible timestamp position + timestamp_x86_64 = struct.unpack("L", wtmp_file.read(4))[0] + debug_logger.debug('WTMP timestamps: x86_64 %s, aarch64 %s, s390x %s' % (timestamp_x86_64, timestamp_aarch64, timestamp_s390x)) + + if sane_timestamp(timestamp_x86_64): + endianness = '<' # little endian + extra_offset_before = 0 + extra_offset_after = 0 + elif sane_timestamp(timestamp_aarch64): + endianness = '<' # little endian + extra_offset_before = 4 + extra_offset_after = 12 + elif sane_timestamp(timestamp_s390x): + endianness = '>' # big endian + extra_offset_before = 8 + extra_offset_after = 8 + else: + raise AppArmorBug('Your /var/log/wtmp is broken or has an unknown format. Please open a bugreport with /var/log/wtmp and the output of "last" attached!') + while offset < wtmp_filesize: wtmp_file.seek(offset) - offset += 384 # Increment for next entry + offset += 384 + extra_offset_before + extra_offset_after # Increment for next entry - type = struct.unpack(" last +linux1 pts/0 77.21.253.246 Thu Jul 15 13:06 still logged in +root pts/0 77.21.253.246 Thu Jul 15 13:06 - 13:06 (00:00) +linux1 pts/0 77.21.253.246 Thu Jul 15 13:01 - 13:05 (00:04) +linux1 pts/0 94.134.117.140 Thu Jul 15 08:15 - 08:16 (00:01) +linux1 pts/0 10.6.22.160 Tue Jul 13 07:42 - 07:42 (00:00) +reboot system boot 5.3.18-24.67-def Tue Jul 13 07:41 still running +linux1 pts/0 10.6.22.160 Tue Jul 13 07:41 - 07:41 (00:00) +linux1 pts/0 10.6.22.160 Tue Jul 13 07:37 - 07:41 (00:03) +reboot system boot 5.3.18-24.64-def Tue Jul 13 07:30 - 07:41 (00:11) + +wtmp beginnt Tue Jul 13 07:30:36 2021 +linux1@opensuse03:~>