def _prompt_user_for_vss_store_identifiers(self, volume_system, volume_identifiers, interactive): """Prompts the user to provide the VSS store identifiers. This method first checks for the preferred VSS stores and falls back to prompt the user if no usable preferences were specified. Args: volume_system: The volume system (instance of dfvfs.VShadowVolumeSystem). volume_identifiers: List of allowed volume identifiers. Returns: The list of selected VSS store identifiers or None. Raises: SourceScannerError: if the source cannot be processed. """ normalized_volume_identifiers = [] for volume_identifier in volume_identifiers: volume = volume_system.GetVolumeByIdentifier(volume_identifier) if not volume: raise errors.SourceScannerError( u'Volume missing for identifier: {0:s}.'.format( volume_identifier)) try: volume_identifier = int(volume.identifier[3:], 10) normalized_volume_identifiers.append(volume_identifier) except ValueError: pass return range(1, volume_system.number_of_volumes + 1)
def _scan_volume_scan_node_vss(self, scan_context, volume_scan_node, base_path_specs, interactive): """Scans a VSS volume scan node for volume and file systems. Args: scan_context: the source scanner context (instance of SourceScannerContext). volume_scan_node: the volume scan node (instance of dfvfs.ScanNode). base_path_specs: a list of source path specification (instances of dfvfs.PathSpec). Raises: SourceScannerError: if a VSS sub scan node scannot be retrieved. """ vss_store_identifiers = self._get_vss_store_identifiers( volume_scan_node, interactive) if self.initialized < 0: return self._vss_stores = list(vss_store_identifiers) # Process VSS stores starting with the most recent one. vss_store_identifiers.reverse() for vss_store_identifier in vss_store_identifiers: location = u'/vss{0:d}'.format(vss_store_identifier) sub_scan_node = volume_scan_node.GetSubNodeByLocation(location) if not sub_scan_node: raise errors.SourceScannerError( u'Scan node missing for VSS store identifier: {0:d}.'. format(vss_store_identifier)) self._source_scanner.Scan(scan_context, scan_path_spec=sub_scan_node.path_spec) self._scan_volume(scan_context, sub_scan_node, base_path_specs, interactive)
def _prompt_user_for_vss_store_identifiers( self, volume_system, volume_identifiers, interactive): """Prompts the user to provide the VSS store identifiers. This method first checks for the preferred VSS stores and falls back to prompt the user if no usable preferences were specified. Args: volume_system: The volume system (instance of dfvfs.VShadowVolumeSystem). volume_identifiers: List of allowed volume identifiers. Returns: The list of selected VSS store identifiers or None. Raises: SourceScannerError: if the source cannot be processed. """ normalized_volume_identifiers = [] for volume_identifier in volume_identifiers: volume = volume_system.GetVolumeByIdentifier(volume_identifier) if not volume: raise errors.SourceScannerError( u'Volume missing for identifier: {0:s}.'.format(volume_identifier)) try: volume_identifier = int(volume.identifier[3:], 10) normalized_volume_identifiers.append(volume_identifier) except ValueError: pass print_header = True while True: if interactive: if print_header: print(u'The following Volume Shadow Snapshots (VSS) were found:') print(u'Identifier\tVSS store identifier') for volume_identifier in volume_identifiers: volume = volume_system.GetVolumeByIdentifier(volume_identifier) if not volume: raise errors.SourceScannerError( u'Volume missing for identifier: {0:s}.'.format( volume_identifier)) vss_identifier = volume.GetAttribute(u'identifier') print(u'{0:s}\t\t{1:s}'.format( volume.identifier, vss_identifier.value)) print(u'') print_header = False print( u'Please specify the identifier(s) of the VSS that should be ' u'processed:') print( u'Note that a range of stores can be defined as: 3..5. Multiple ' u'stores can') print( u'be defined as: 1,3,5 (a list of comma separated values). Ranges ' u'and lists can') print( u'also be combined as: 1,3..5. The first store is 1. All stores ' u'can be defined') print(u'as "all". If no stores are specified none will be processed. You') print(u'can abort with Ctrl^C.') selected_vss_stores = sys.stdin.readline() self.settings.append(selected_vss_stores.strip()) else: self.display = u'The following Volume Shadow Snapshots (VSS) were found:\nTo add evidence without any snapshots use "none"\nIdentifier\tVSS store identifier\n' self.options = ['none'] for volume_identifier in volume_identifiers: volume = volume_system.GetVolumeByIdentifier(volume_identifier) if not volume: raise errors.SourceScannerError( u'Volume missing for identifier: {0:s}.'.format( volume_identifier)) vss_identifier = volume.GetAttribute(u'identifier') self.display += u'{0:s}\t\t{1:s}\n'.format(volume.identifier, vss_identifier.value) self.options.append(volume.identifier) if self.settings: selected_vss_stores = self.settings.pop(0) if str(selected_vss_stores).lower() == 'none': selected_vss_stores = [] else: self.initialized = -1 return if not selected_vss_stores: break selected_vss_stores = selected_vss_stores.strip() try: selected_vss_stores = self._parse_vss_stores_string(selected_vss_stores) except errors.BadConfigOption: selected_vss_stores = [] if selected_vss_stores == [u'all']: # We need to set the stores to cover all vss stores. selected_vss_stores = range(1, volume_system.number_of_volumes + 1) if not set(selected_vss_stores).difference(normalized_volume_identifiers): break print(u'') print( u'Unsupported VSS identifier(s), please try again or abort with ' u'Ctrl^C.') print(u'') return selected_vss_stores