Пример #1
0
def _get_violation_events(sieve, input_auth, attributes, indent):
	try:
		auth = _process_auth_list(input_auth, indent)
	except json.decoder.JSONDecodeError as e:
		raise USBRipError(
			'Failed to decode authorized device list (JSON)',
			errors={'initial_error': str(e)}
		)

	if not attributes:
		attributes = auth.keys()

	ue = USBEvents()
	if not ue:
		return None

	for event in ue._all_events:
		try:
			if any(event[key] not in vals and
                   event[key] is not None
                   for key, vals in zip(attributes, auth.values())):
				ue._violations.append(event)
		except KeyError as e:
			raise USBRipError(
				'No such attribute in authorized device list',
				errors={'initial_error': str(e)}
			)

	return _filter_events(ue._violations, sieve)
Пример #2
0
def _get_filtered_history():
    filtered_history = []

    print_info(
        'Searching for log files: "/var/log/syslog*" or "/var/log/messages*"')

    syslog_files = sorted([
        filename for filename in list_files('/var/log/')
        if filename.rsplit('/', 1)[1].startswith('syslog')
    ])

    if syslog_files:
        for syslog in syslog_files:
            filtered_history.extend(_read_log_file(syslog))
    else:
        messages_files = sorted([
            filename for filename in list_files('/var/log/')
            if filename.rsplit('/', 1)[1].startswith('messages')
        ])

        if messages_files:
            for messages in messages_files:
                filtered_history.extend(_read_log_file(messages))
        else:
            raise USBRipError('None of log file types was found!')

    return filtered_history
Пример #3
0
def _dump_events(events_to_show, list_name, abs_filename, indent):
	print_info(f'Generating {list_name} list (JSON)')

	out = []
	for event in events_to_show:
		tmp_event_dict = OrderedDict()

		for key in ('conn', 'host', 'vid', 'pid', 'prod', 'manufact', 'serial', 'port', 'disconn'):
			tmp_event_dict[key] = event[key]

		out.append(tmp_event_dict)

	try:
		with open(abs_filename, 'w', encoding='utf-8') as out_json:
			json.dump(out, out_json, indent=indent)

	except PermissionError as e:
		raise USBRipError(
			f'Permission denied: "{abs_filename}". Retry with sudo',
			errors={'initial_error': str(e)}
		)

	os.chmod(abs_filename, stat.S_IRUSR | stat.S_IWUSR)  # 600

	print_info(f'New {list_name} list: "{abs_filename}"')
Пример #4
0
def _get_raw_history():
    raw_history = DefaultOrderedDict(default_factory=list)

    print_info(
        'Searching for log files: "/var/log/syslog*" or "/var/log/messages*"')

    syslog_files = sorted([
        filename for filename in list_files('/var/log/')
        if filename.rsplit('/', 1)[1].startswith('syslog')
    ])

    if syslog_files:
        for syslog in syslog_files:
            raw_history.update(_read_log_file(syslog))
    else:
        messages_files = sorted([
            filename for filename in list_files('/var/log/')
            if filename.rsplit('/', 1)[1].startswith('messages')
        ])

        if messages_files:
            for messages in messages_files:
                raw_history.update(_read_log_file(messages))
        else:
            raise USBRipError('None of log file types was found!')

    return raw_history
Пример #5
0
def _get_filtered_history():
    filtered_history = []

    print_info(
        'Searching for log files: C:\\Users\\eyver-dev\\Documents\\python\\usbrip\\test\\syslog* or C:\\Users\\eyver-dev\\Documents\\python\\usbrip\\test\\messages*'
    )

    syslog_files = sorted([
        filename for filename in list_files(
            'C:\\Users\\eyver-dev\\Documents\\python\\usbrip\\test')
        if filename.rsplit('\\', 1)[1].startswith('syslog')
    ])

    if syslog_files:
        for syslog in syslog_files:
            filtered_history.extend(_read_log_file(syslog))
    else:
        messages_files = sorted([
            filename for filename in list_files('/var/log/')
            if filename.rsplit('/', 1)[1].startswith('messages')
        ])

        if messages_files:
            for messages in messages_files:
                filtered_history.extend(_read_log_file(messages))
        else:
            raise USBRipError('None of log file types was found!')

    return filtered_history
Пример #6
0
def _read_log_file(filename):
    filtered = []

    abs_filename = os.path.abspath(filename)

    if abs_filename.endswith('.gz'):
        print_info(f'Unpacking "{abs_filename}"')

        try:
            log = gzip.open(abs_filename, 'rb')
        except PermissionError as e:
            print_warning(
                f'Permission denied: "{abs_filename}". Retry with sudo',
                initial_error=str(e))
            return filtered
        else:
            end_of_file = b''
            abs_filename = os.path.splitext(abs_filename)

    else:
        log = codecs.open(abs_filename, 'r', encoding='utf-8', errors='ignore')
        end_of_file = ''

    print_info(f'Reading "{abs_filename}"')

    regex = re.compile(r'] usb (.*?): ')
    for line in iter(log.readline, end_of_file):
        if isinstance(line, bytes):
            line = line.decode(encoding='utf-8', errors='ignore')

        if regex.search(line):
            date = line[:32]
            if date.count(':') > 2:
                date = ''.join(
                    line[:32].rsplit(':', 1)
                )  # rreplace(':', 1) to remove the last ':' from "2019-08-09T06:15:49.655261-04:00" timestamp if there is one

            try:
                date = datetime.strptime(
                    date, '%Y-%m-%dT%H:%M:%S.%f%z'
                )  # ex. 2019-08-09T06:15:49.655261-0400
            except ValueError as e:
                raise USBRipError(
                    f'Wrong timestamp format found in "{abs_filename}"',
                    errors={'initial_error': str(e)})
            else:
                date = date.strftime('%Y-%m-%d %H:%M:%S')
                logline = line[32:].strip()
                if any(pat in line
                       for pat in ('New USB device found, ', 'Product: ',
                                   'Manufacturer: ', 'SerialNumber: ')):
                    filtered.append((date, 'c', logline))
                elif 'disconnect' in line:
                    filtered.append((date, 'd', logline))

    log.close()
    return filtered
Пример #7
0
def _download_database(filename):
    try:
        dirname = os.path.dirname(filename)
        os_makedirs(dirname)
    except USBRipError as e:
        raise USBRipError(str(e),
                          errors={'initial_error': e.errors['initial_error']})
    else:
        print_info(f'Created directory "{dirname}/"')

    try:
        usb_ids = open(filename, 'w+', encoding='utf-8')
    except PermissionError as e:
        raise USBRipError(f'Permission denied: "{filename}"',
                          errors={'initial_error': str(e)})

    db, latest_ver, latest_date, errcode, e = _get_latest_version()

    if errcode:
        usb_ids.close()
        os.remove(filename)

        if errcode == USBIDs._INTERNET_CONNECTION_ERROR:
            errmsg = 'No internet connection'
        elif errcode == USBIDs._SERVER_TIMEOUT_ERROR:
            errmsg = 'Server timeout'
        elif errcode == USBIDs._SERVER_CONTENT_ERROR:
            errmsg = 'Server content error: no version or date found'

        raise USBRipError(errmsg,
                          errors={
                              'errcode': errcode,
                              'initial_error': e
                          })

    usb_ids.write(db)
    usb_ids.seek(0)

    print_info('Database downloaded')

    print(f'Version:  {latest_ver}')
    print(f'Date:     {latest_date}')

    return usb_ids
Пример #8
0
def _update_database(filename):
	try:
		usb_ids = open(filename, 'r+', encoding='utf-8')
	except PermissionError as e:
		raise USBRipError(
			f'Permission denied: "{filename}"',
			errors={'initial_error': str(e)}
		)

	print_info('Getting current database version')
	curr_ver, curr_date = _get_current_version(usb_ids)
	print(f'Version:  {curr_ver}')
	print(f'Date:     {curr_date}')

	print_info('Checking local database for update')
	db, latest_ver, latest_date, errcode, e = _get_latest_version()

	if errcode:
		if errcode == USBIDs._INTERNET_CONNECTION_ERROR:
			print_warning(
				'No internet connection, using current version',
				errcode=errcode
			)

		elif errcode == USBIDs._SERVER_TIMEOUT_ERROR:
			print_warning(
				'Server timeout, using current version',
				errcode=errcode,
				initial_error=e
			)

		elif errcode == USBIDs._SERVER_CONTENT_ERROR:
			print_warning(
				'Server error, using current version',
				errcode=errcode,
				initial_error=e
			)

		return usb_ids

	if curr_ver != latest_ver and curr_date != latest_date:  # if there's newer database version
		print('Updating database... ', end='')

		usb_ids.write(db)
		usb_ids.truncate()
		usb_ids.seek(0)

		print('Done\n')

		print(f'Version:  {latest_ver}')
		print(f'Date:     {latest_date}')

	print_info('Local database is up-to-date')

	return usb_ids
Пример #9
0
def _get_current_version(usb_ids):
    db = usb_ids.read()
    usb_ids.seek(0)

    try:
        curr_ver = re.search(r'^# Version:\s*(.*?$)', db,
                             re.MULTILINE).group(1)
        curr_date = re.search(r'^# Date:\s*(.*?$)', db, re.MULTILINE).group(1)
    except AttributeError as e:
        raise USBRipError(
            'Invalid database content structure: no version or date found',
            errors={'initial_error': str(e)})

    return (curr_ver, curr_date)
Пример #10
0
def _7zip_list(archive, password):
    print_info(f'Listing archive: "{archive}"')

    cmd = ['7z', 'l', archive, '-p' + password]

    out, errcode, errmsg, e = _7zip_subprocess_handler(cmd)
    if errcode:
        raise USBRipError(errmsg,
                          errors={
                              'errcode': errcode,
                              'initial_error': e
                          })

    return out
Пример #11
0
    def prepare_database(*, offline=True):
        filename = f'{os.path.abspath(str(Path.home()))}/.config/usbrip/usb.ids'
        file_exists = os.path.isfile(filename)

        if file_exists and offline:
            usb_ids = open(filename, 'r', encoding='utf-8')
        elif file_exists and not offline:
            usb_ids = _update_database(filename)
        elif not file_exists and not offline:
            print_warning('No local database found, trying to download')
            usb_ids = _download_database(filename)
        elif not file_exists and offline:
            raise USBRipError('No local database found')

        return usb_ids
Пример #12
0
    def prepare_database(*, offline=True):
        filename = root_dir_join('usb_ids/usb.ids')
        file_exists = os.path.isfile(filename)

        if file_exists and offline:
            usb_ids = open(filename, 'r', encoding='utf-8')
        elif file_exists and not offline:
            usb_ids = _update_database(filename)
        elif not file_exists and not offline:
            print_warning('No local database found, trying to download')
            usb_ids = _download_database(filename)
        elif not file_exists and offline:
            raise USBRipError('No local database found')

        return usb_ids
Пример #13
0
def _7zip_unpack(archive, password):
	print_info(f'Unpacking archive: "{archive}"')

	cmd = [
		'7z',
		'e',
		archive,
		'-p' + password,
		'-o' + USBStorage._STORAGE_BASE,
		'-y'
	]

	out, errcode, errmsg, e = _7zip_subprocess_handler(cmd)
	if errcode:
		raise USBRipError(errmsg, errors={'errcode': errcode, 'initial_error': e})

	return out
Пример #14
0
def _7zip_pack(archive, file, password, compression_level):
    print_info(f'Creating storage (7-Zip): "{archive}"')

    cmd = [
        '7z', 'a', archive, file, '-mhe=on', '-p' + password,
        '-mx=' + compression_level
    ]

    out, errcode, errmsg, e = _7zip_subprocess_handler(cmd)
    if errcode:
        raise USBRipError(errmsg,
                          errors={
                              'errcode': errcode,
                              'initial_error': e
                          })

    return out
Пример #15
0
def _dump_events(events_to_show, list_name, filename, indent):
	print_info('Generating {} list (JSON)'.format(list_name))

	out = []
	for event in events_to_show:
		tmp_event_dict = OrderedDict()
		for key in ('conn', 'user', 'vid', 'pid', 'prod', 'manufact', 'serial', 'port', 'disconn'):
			tmp_event_dict[key] = event[key]
		out.append(tmp_event_dict)

	try:
		with open(filename, 'w', encoding='utf-8') as out_json:
			json.dump(out, out_json, indent=indent)
	except PermissionError as e:
		raise USBRipError(
			'Permission denied: \'{}\'. Retry with sudo'.format(filename),
			errors={'initial_error': str(e)}
		)

	print_info('New {} list: \'{}\''.format(list_name, os.path.abspath(filename)))
Пример #16
0
def _read_log_file(filename, log=None):
    filtered = []

    if log is None:
        abs_filename = os.path.abspath(filename)

        if abs_filename.endswith('.gz'):
            print_info(f'Unpacking "{abs_filename}"')

            try:
                log = gzip.open(abs_filename, 'rb')
            except PermissionError as e:
                print_warning(
                    f'Permission denied: "{abs_filename}". Retry with sudo',
                    initial_error=str(e))
                return filtered
            else:
                end_of_file = b''
                abs_filename = os.path.splitext(abs_filename)

        else:
            log = codecs.open(abs_filename,
                              'r',
                              encoding='utf-8',
                              errors='ignore')
            end_of_file = ''

        print_info(f'Reading "{abs_filename}"')

    else:
        abs_filename = 'journalctl output'
        end_of_file = ''
        print_info(f'Reading journalctl output')

    regex = re.compile(r'(?:]|:) usb (.*?): ')
    for line in tqdm(iter(log.readline, end_of_file), unit='line'):
        if isinstance(line, bytes):
            line = line.decode('utf-8', errors='ignore')

        if regex.search(line):
            # Case 1 -- Modified Timestamp ("%Y-%m-%dT%H:%M:%S.%f%z")

            date = line[:32].strip()
            if date.count(':') == 3:
                date = ''.join(
                    line[:32].rsplit(':', 1)
                )  # rreplace(':', '', 1) to remove the last ':' from "2019-08-09T06:15:49.655261-04:00" timestamp if there is one

            try:
                date = datetime.strptime(
                    date, '%Y-%m-%dT%H:%M:%S.%f%z'
                )  # ex. "2019-08-09T06:15:49.655261-0400"

            except ValueError:
                # Case 2 -- Non-Modified Timestamp ("%b %d %H:%M:%S")

                date = line[:15].strip()
                if '  ' in date:
                    date = date.replace('  ', ' 0',
                                        1)  # pad day of the week with zero

                try:
                    date = datetime.strptime(
                        date, '%b %d %H:%M:%S')  # ex. "Mar 18 13:56:07"
                except ValueError as e:
                    raise USBRipError(
                        f'Wrong timestamp format found in "{abs_filename}"',
                        errors={'initial_error': str(e)})
                else:
                    date = date.strftime('????-%m-%d %H:%M:%S')
                    logline = line[15:].strip()

            else:
                date = date.strftime('%Y-%m-%d %H:%M:%S')
                logline = line[32:].strip()

            if any(pat in line
                   for pat in ('New USB device found, ', 'Product: ',
                               'Manufacturer: ', 'SerialNumber: ')):
                filtered.append((date, 'c', logline))
            elif 'disconnect' in line:
                filtered.append((date, 'd', logline))

    log.close()
    return filtered