LEFT | RIGHT |
(no file at all) | |
1 # -*- coding: utf-8 -*- | 1 # -*- coding: utf-8 -*- |
2 """This file contains preprocessors for Mac OS X.""" | 2 """This file contains preprocessors for MacOS.""" |
3 | 3 |
4 import abc | 4 import abc |
5 import plistlib | 5 import plistlib |
6 | 6 |
7 from plaso.containers import artifacts | 7 from plaso.containers import artifacts |
8 from plaso.lib import errors | 8 from plaso.lib import errors |
9 from plaso.lib import plist | 9 from plaso.lib import plist |
10 from plaso.parsers.plist_plugins import interface as plist_interface | 10 from plaso.parsers.plist_plugins import interface as plist_interface |
11 from plaso.preprocessors import interface | 11 from plaso.preprocessors import interface |
12 from plaso.preprocessors import manager | 12 from plaso.preprocessors import manager |
13 | 13 |
14 | 14 |
15 class PlistPreprocessPlugin(interface.FileSystemPreprocessPlugin): | 15 class PlistFileArtifactPreprocessorPlugin( |
16 """The plist preprocess plugin interface.""" | 16 interface.FileArtifactPreprocessorPlugin): |
17 | 17 """Plist file artifact preprocessor plugin interface. |
18 _PLIST_PATH = u'' | 18 |
19 | 19 Retrieves values from a plist file artifact using names of keys defined |
20 def _GetPlistRootKey(self, file_entry): | 20 in _PLIST_KEYS. |
21 """Opens a plist file entry. | |
22 | |
23 Args: | |
24 file_entry (dfvfs.FileEntry): file entry of the plist. | |
25 | |
26 Returns: | |
27 plistlib._InternalDict: plist root key. | |
28 | |
29 Raises: | |
30 errors.PreProcessFail: if the preprocessing fails. | |
31 """ | |
32 file_object = file_entry.GetFileObject() | |
33 | |
34 try: | |
35 plist_file = plist.PlistFile() | |
36 plist_file.Read(file_object) | |
37 | |
38 except IOError as exception: | |
39 location = getattr(file_entry.path_spec, u'location', u'') | |
40 raise errors.PreProcessFail( | |
41 u'Unable to read plist file: {0:s} with error: {1:s}'.format( | |
42 location, exception)) | |
43 | |
44 finally: | |
45 file_object.close() | |
46 | |
47 return plist_file.root_key | |
48 | |
49 @abc.abstractmethod | |
50 def Run(self, searcher, knowledge_base): | |
51 """Determines the value of the preprocessing attributes. | |
52 | |
53 Args: | |
54 searcher (dfvfs.FileSystemSearcher): file system searcher. | |
55 knowledge_base (KnowledgeBase): to fill with preprocessing information. | |
56 """ | |
57 | |
58 | |
59 class PlistKeyPreprocessPlugin(PlistPreprocessPlugin): | |
60 """The plist key preprocess plugin interface. | |
61 | |
62 The plist key preprocess plugin retieves values from key names, | |
63 defined in _PLIST_KEYS, from a specific plist file, defined in | |
64 _PLIST_PATH. | |
65 """ | 21 """ |
66 | 22 |
67 # The key that's value should be returned back. It is an ordered list | 23 # The key that's value should be returned back. It is an ordered list |
68 # of preference. If the first value is found it will be returned and no | 24 # of preference. If the first value is found it will be returned and no |
69 # others will be searched. | 25 # others will be searched. |
70 _PLIST_KEYS = [u''] | 26 _PLIST_KEYS = [u''] |
71 | 27 |
72 def _FindKeys(self, key, names, matches): | 28 def _FindKeys(self, key, names, matches): |
73 """Searches the plist key hierarchy for keys with matching names. | 29 """Searches the plist key hierarchy for keys with matching names. |
74 | 30 |
75 If a match is found a tuple of the key name and value is added to | 31 If a match is found a tuple of the key name and value is added to |
76 the matches list. | 32 the matches list. |
77 | 33 |
78 Args: | 34 Args: |
79 key (plistlib._InternalDict): plist key. | 35 key (plistlib._InternalDict): plist key. |
80 names (list[str]): names of the keys to match. | 36 names (list[str]): names of the keys to match. |
81 matches (list[str]): keys with matching names. | 37 matches (list[str]): keys with matching names. |
82 """ | 38 """ |
83 for name, subkey in iter(key.items()): | 39 for name, subkey in iter(key.items()): |
84 if name in names: | 40 if name in names: |
85 matches.append((name, subkey)) | 41 matches.append((name, subkey)) |
86 | 42 |
87 # pylint: disable=protected-access | 43 # pylint: disable=protected-access |
88 if isinstance(subkey, plistlib._InternalDict): | 44 if isinstance(subkey, plistlib._InternalDict): |
89 self._FindKeys(subkey, names, matches) | 45 self._FindKeys(subkey, names, matches) |
90 | 46 |
91 @abc.abstractmethod | 47 def _ParseFileData(self, knowledge_base, file_object): |
92 def _ParseValue(self, knowledge_base, name, value): | 48 """Parses file content (data) for a preprocessing attribute. |
93 """Parses a plist key value. | 49 |
94 | 50 Args: |
95 Args: | 51 knowledge_base (KnowledgeBase): to fill with preprocessing information. |
96 knowledge_base (KnowledgeBase): to fill with preprocessing information. | 52 file_object (dfvfs.FileIO): file-like object that contains the artifact |
97 name (str): name of the plist key. | 53 value data. |
98 value (str): value of the plist key. | 54 |
99 """ | 55 Returns: |
100 | 56 bool: True if all the preprocessing attributes were found and |
101 def Run(self, searcher, knowledge_base): | 57 the preprocessor plugin is done. |
102 """Determines the value of the preprocessing attributes. | |
103 | |
104 Args: | |
105 searcher (dfvfs.FileSystemSearcher): file system searcher. | |
106 knowledge_base (KnowledgeBase): to fill with preprocessing information. | |
107 | 58 |
108 Raises: | 59 Raises: |
109 errors.PreProcessFail: if the preprocessing fails. | 60 errors.PreProcessFail: if the preprocessing fails. |
110 """ | 61 """ |
111 file_entry = self._FindFileEntry(searcher, self._PLIST_PATH) | 62 plist_file = plist.PlistFile() |
112 if not file_entry: | 63 |
113 return | 64 try: |
114 | 65 plist_file.Read(file_object) |
115 root_key = self._GetPlistRootKey(file_entry) | 66 |
116 if not root_key: | 67 except IOError as exception: |
117 location = getattr(file_entry.path_spec, u'location', u'') | 68 raise errors.PreProcessFail( |
118 raise errors.PreProcessFail( | 69 u'Unable to read: {0:s} with error: {1!s}'.format( |
119 u'Missing root key in plist: {0:s}'.format(location)) | 70 self.ARTIFACT_DEFINITION_NAME, exception)) |
| 71 |
| 72 if not plist_file.root_key: |
| 73 raise errors.PreProcessFail(( |
| 74 u'Unable to read: {0:s} with error: missing root key').format( |
| 75 self.ARTIFACT_DEFINITION_NAME)) |
120 | 76 |
121 matches = [] | 77 matches = [] |
122 | 78 |
123 self._FindKeys(root_key, self._PLIST_KEYS, matches) | 79 self._FindKeys(plist_file.root_key, self._PLIST_KEYS, matches) |
124 if not matches: | 80 if not matches: |
125 raise errors.PreProcessFail(u'No such keys: {0:s}.'.format( | 81 raise errors.PreProcessFail( |
126 u', '.join(self._PLIST_KEYS))) | 82 u'Unable to read: {0:s} with error: no such keys: {1:s}.'.format( |
| 83 self.ARTIFACT_DEFINITION_NAME, u', '.join(self._PLIST_KEYS))) |
127 | 84 |
128 name = None | 85 name = None |
129 value = None | 86 value = None |
130 for name, value in matches: | 87 for name, value in matches: |
131 if value: | 88 if value: |
132 break | 89 break |
133 | 90 |
134 if value is None: | 91 if value is None: |
135 raise errors.PreProcessFail(u'No values found for keys: {0:s}.'.format( | 92 raise errors.PreProcessFail(( |
136 u', '.join(self._PLIST_KEYS))) | 93 u'Unable to read: {0:s} with error: no values found for keys: ' |
137 | 94 u'{1:s}.').format( |
138 self._ParseValue(knowledge_base, name, value) | 95 self.ARTIFACT_DEFINITION_NAME, u', '.join(self._PLIST_KEYS))) |
139 | 96 |
140 | 97 return self._ParsePlistKeyValue(knowledge_base, name, value) |
141 class MacOSXHostnamePreprocessPlugin(PlistKeyPreprocessPlugin): | 98 |
142 """Mac OS X hostname preprocessing plugin.""" | 99 @abc.abstractmethod |
143 | 100 def _ParsePlistKeyValue(self, knowledge_base, name, value): |
144 _PLIST_PATH = u'/Library/Preferences/SystemConfiguration/preferences.plist' | |
145 _PLIST_KEYS = [u'ComputerName', u'LocalHostName'] | |
146 | |
147 def _ParseValue(self, knowledge_base, name, value): | |
148 """Parses a plist key value. | 101 """Parses a plist key value. |
149 | 102 |
150 Args: | 103 Args: |
151 knowledge_base (KnowledgeBase): to fill with preprocessing information. | 104 knowledge_base (KnowledgeBase): to fill with preprocessing information. |
152 name (str): name of the plist key. | 105 name (str): name of the plist key. |
153 value (str): value of the plist key. | 106 value (str): value of the plist key. |
154 """ | 107 |
155 if name not in self._PLIST_KEYS: | 108 Returns: |
156 return | 109 bool: True if all the preprocessing attributes were found and |
157 | 110 the preprocessor plugin is done. |
158 hostname_artifact = artifacts.HostnameArtifact(name=value) | 111 """ |
159 knowledge_base.SetHostname(hostname_artifact) | 112 |
160 | 113 |
161 | 114 class MacOSHostnamePlugin(PlistFileArtifactPreprocessorPlugin): |
162 class MacOSXKeyboardLayoutPreprocessPlugin(PlistKeyPreprocessPlugin): | 115 """MacOS hostname plugin.""" |
163 """Mac OS X keyboard layout preprocessing plugin.""" | 116 |
164 | 117 ARTIFACT_DEFINITION_NAME = u'MacOSSystemConfigurationPreferencesPlistFile' |
165 _PLIST_PATH = u'/Library/Preferences/com.apple.HIToolbox.plist' | 118 |
166 _PLIST_KEYS = [u'AppleCurrentKeyboardLayoutInputSourceID'] | 119 _PLIST_KEYS = [u'ComputerName', u'LocalHostName'] |
167 | 120 |
168 def _ParseValue(self, knowledge_base, name, value): | 121 def _ParsePlistKeyValue(self, knowledge_base, name, value): |
169 """Parses a plist key value. | 122 """Parses a plist key value. |
170 | 123 |
171 Args: | 124 Args: |
172 knowledge_base (KnowledgeBase): to fill with preprocessing information. | 125 knowledge_base (KnowledgeBase): to fill with preprocessing information. |
173 name (str): name of the plist key. | 126 name (str): name of the plist key. |
174 value (str): value of the plist key. | 127 value (str): value of the plist key. |
175 """ | 128 |
176 if name not in self._PLIST_KEYS: | 129 Returns: |
177 return | 130 bool: True if all the preprocessing attributes were found and |
178 | 131 the preprocessor plugin is done. |
179 if isinstance(value, (list, tuple)): | 132 """ |
180 value = value[0] | 133 if name in self._PLIST_KEYS: |
181 | 134 hostname_artifact = artifacts.HostnameArtifact(name=value) |
182 _, _, keyboard_layout = value.rpartition(u'.') | 135 knowledge_base.SetHostname(hostname_artifact) |
183 | 136 |
184 knowledge_base.SetValue(u'keyboard_layout', keyboard_layout) | 137 return name in self._PLIST_KEYS |
185 | 138 |
186 | 139 |
187 class MacOSXSystemVersionPreprocessPlugin(PlistKeyPreprocessPlugin): | 140 class MacOSKeyboardLayoutPlugin(PlistFileArtifactPreprocessorPlugin): |
188 """Mac OS X system version information preprocessing plugin.""" | 141 """MacOS keyboard layout plugin.""" |
189 | 142 |
190 _PLIST_PATH = u'/System/Library/CoreServices/SystemVersion.plist' | 143 ARTIFACT_DEFINITION_NAME = u'MacOSKeyboardLayoutPlistFile' |
191 _PLIST_KEYS = [u'ProductUserVisibleVersion'] | 144 |
192 | 145 _PLIST_KEYS = [u'AppleCurrentKeyboardLayoutInputSourceID'] |
193 def _ParseValue(self, knowledge_base, name, value): | 146 |
| 147 def _ParsePlistKeyValue(self, knowledge_base, name, value): |
194 """Parses a plist key value. | 148 """Parses a plist key value. |
195 | 149 |
196 Args: | 150 Args: |
197 knowledge_base (KnowledgeBase): to fill with preprocessing information. | 151 knowledge_base (KnowledgeBase): to fill with preprocessing information. |
198 name (str): name of the plist key. | 152 name (str): name of the plist key. |
199 value (str): value of the plist key. | 153 value (str): value of the plist key. |
200 """ | 154 |
201 if name not in self._PLIST_KEYS: | 155 Returns: |
202 return | 156 bool: True if all the preprocessing attributes were found and |
203 | 157 the preprocessor plugin is done. |
204 knowledge_base.SetValue(u'operating_system_version', value) | 158 """ |
205 | 159 if name in self._PLIST_KEYS: |
206 | 160 if isinstance(value, (list, tuple)): |
207 class MacOSXTimeZonePreprocessPlugin(interface.FileSystemPreprocessPlugin): | 161 value = value[0] |
208 """Mac OS X time zone preprocessing plugin.""" | 162 |
209 | 163 _, _, keyboard_layout = value.rpartition(u'.') |
210 _PATH = u'/private/etc/localtime' | 164 |
211 | 165 knowledge_base.SetValue(u'keyboard_layout', keyboard_layout) |
212 def Run(self, searcher, knowledge_base): | 166 |
213 """Determines the value of the preprocessing attributes. | 167 return name in self._PLIST_KEYS |
214 | 168 |
215 Args: | 169 |
216 searcher (dfvfs.FileSystemSearcher): file system searcher. | 170 class MacOSSystemVersionPlugin(PlistFileArtifactPreprocessorPlugin): |
217 knowledge_base (KnowledgeBase): to fill with preprocessing information. | 171 """MacOS system version information plugin.""" |
| 172 |
| 173 ARTIFACT_DEFINITION_NAME = u'MacOSSystemVersionPlistFile' |
| 174 |
| 175 _PLIST_KEYS = [u'ProductUserVisibleVersion'] |
| 176 |
| 177 def _ParsePlistKeyValue(self, knowledge_base, name, value): |
| 178 """Parses a plist key value. |
| 179 |
| 180 Args: |
| 181 knowledge_base (KnowledgeBase): to fill with preprocessing information. |
| 182 name (str): name of the plist key. |
| 183 value (str): value of the plist key. |
| 184 |
| 185 Returns: |
| 186 bool: True if all the preprocessing attributes were found and |
| 187 the preprocessor plugin is done. |
| 188 """ |
| 189 if name in self._PLIST_KEYS: |
| 190 knowledge_base.SetValue(u'operating_system_version', value) |
| 191 |
| 192 return name in self._PLIST_KEYS |
| 193 |
| 194 |
| 195 class MacOSTimeZonePlugin(interface.FileEntryArtifactPreprocessorPlugin): |
| 196 """MacOS time zone plugin.""" |
| 197 |
| 198 ARTIFACT_DEFINITION_NAME = u'MacOSLocalTime' |
| 199 |
| 200 def _ParseFileEntry(self, knowledge_base, file_entry): |
| 201 """Parses artifact file system data for a preprocessing attribute. |
| 202 |
| 203 Args: |
| 204 knowledge_base (KnowledgeBase): to fill with preprocessing information. |
| 205 file_entry (dfvfs.FileEntry): file entry that contains the artifact |
| 206 value data. |
| 207 |
| 208 Returns: |
| 209 bool: True if all the preprocessing attributes were found and |
| 210 the preprocessor plugin is done. |
218 | 211 |
219 Raises: | 212 Raises: |
220 errors.PreProcessFail: if the preprocessing fails. | 213 errors.PreProcessFail: if the preprocessing fails. |
221 """ | 214 """ |
222 file_entry = self._FindFileEntry(searcher, self._PATH) | 215 if not file_entry or not file_entry.link: |
223 if not file_entry: | 216 raise errors.PreProcessFail( |
224 return | 217 u'Unable to read: {0:s} with error: not a symbolic link'.format( |
225 | 218 self.ARTIFACT_DEFINITION_NAME)) |
226 if not file_entry.link: | 219 |
227 raise errors.PreProcessFail( | 220 result = False |
228 u'Unable to retrieve time zone information from: {0:s}.'.format( | |
229 self._PATH)) | |
230 | 221 |
231 _, _, time_zone = file_entry.link.partition(u'zoneinfo/') | 222 _, _, time_zone = file_entry.link.partition(u'zoneinfo/') |
232 if not time_zone: | 223 if time_zone: |
233 return | 224 try: |
234 | 225 knowledge_base.SetTimeZone(time_zone) |
235 try: | 226 result = True |
236 knowledge_base.SetTimeZone(time_zone) | 227 except ValueError: |
237 except ValueError: | 228 # TODO: add and store preprocessing errors. |
238 # TODO: add and store preprocessing errors. | 229 pass |
239 pass | 230 |
240 | 231 return result |
241 | 232 |
242 class MacOSXUserAccountsPreprocessPlugin(PlistPreprocessPlugin): | 233 |
243 """Mac OS X user accouns preprocessing plugin.""" | 234 class MacOSUserAccountsPlugin(interface.FileEntryArtifactPreprocessorPlugin): |
244 | 235 """MacOS user accounts plugin.""" |
245 ATTRIBUTE = u'users' | 236 |
246 | 237 ARTIFACT_DEFINITION_NAME = u'MacOSUserPasswordHashesPlistFiles' |
247 # Define the path to the user account information. | |
248 _PLIST_PATH_REGEX = ( | |
249 u'/private/var/db/dslocal/nodes/Default/users/[^_].+.plist') | |
250 | 238 |
251 _KEYS = frozenset([u'gid', 'home', u'name', u'realname', u'shell', u'uid']) | 239 _KEYS = frozenset([u'gid', 'home', u'name', u'realname', u'shell', u'uid']) |
252 | 240 |
253 def _GetKeysDefaultEmpty(self, top_level, keys, depth=1): | 241 def _GetKeysDefaultEmpty(self, top_level, keys, depth=1): |
254 """Return keys nested in a plist dict, defaulting to an empty value. | 242 """Retrieves plist keys, defaulting to empty values. |
255 | |
256 The method GetKeys fails if the supplied key does not exist within the | |
257 plist object. This alternate method behaves the same way as GetKeys | |
258 except that instead of raising an error if the key doesn't exist it will | |
259 assign an empty string value ('') to the field. | |
260 | 243 |
261 Args: | 244 Args: |
262 top_level (plistlib._InternalDict): top level plist object. | 245 top_level (plistlib._InternalDict): top level plist object. |
263 keys (set[str]): names of keys that should be returned. | 246 keys (set[str]): names of keys that should be returned. |
264 depth (int): depth within the plist, where 1 is top level. | 247 depth (int): depth within the plist, where 1 is top level. |
265 | 248 |
266 Returns: | 249 Returns: |
267 dict[str,str]: values of the requested keys. | 250 dict[str, str]: values of the requested keys. |
268 """ | 251 """ |
269 keys = set(keys) | 252 keys = set(keys) |
270 match = {} | 253 match = {} |
271 | 254 |
272 if depth == 1: | 255 if depth == 1: |
273 for key in keys: | 256 for key in keys: |
274 value = top_level.get(key, None) | 257 value = top_level.get(key, None) |
275 if value is not None: | 258 if value is not None: |
276 match[key] = value | 259 match[key] = value |
277 else: | 260 else: |
278 for _, parsed_key, parsed_value in plist_interface.RecurseKey( | 261 for _, parsed_key, parsed_value in plist_interface.RecurseKey( |
279 top_level, depth=depth): | 262 top_level, depth=depth): |
280 if parsed_key in keys: | 263 if parsed_key in keys: |
281 match[parsed_key] = parsed_value | 264 match[parsed_key] = parsed_value |
282 if set(match.keys()) == keys: | 265 if set(match.keys()) == keys: |
283 return match | 266 return match |
284 return match | 267 return match |
285 | 268 |
286 def _ParsePlistFileEntry(self, knowledge_base, file_entry): | 269 def _GetPlistRootKey(self, file_entry): |
287 """Parses an user account plist file. | 270 """Retrieves the root key of a plist file. |
288 | 271 |
289 Args: | 272 Args: |
290 knowledge_base (KnowledgeBase): to fill with preprocessing information. | 273 file_entry (dfvfs.FileEntry): file entry of the plist. |
291 file_entry (dfvfs.FileNetry): file entry of the user account plist file. | 274 |
| 275 Returns: |
| 276 plistlib._InternalDict: plist root key. |
| 277 |
| 278 Raises: |
| 279 errors.PreProcessFail: if the preprocessing fails. |
| 280 """ |
| 281 file_object = file_entry.GetFileObject() |
| 282 |
| 283 try: |
| 284 plist_file = plist.PlistFile() |
| 285 plist_file.Read(file_object) |
| 286 |
| 287 except IOError as exception: |
| 288 location = getattr(file_entry.path_spec, u'location', u'') |
| 289 raise errors.PreProcessFail( |
| 290 u'Unable to read plist file: {0:s} with error: {1:s}'.format( |
| 291 location, exception)) |
| 292 |
| 293 finally: |
| 294 file_object.close() |
| 295 |
| 296 return plist_file.root_key |
| 297 |
| 298 def _ParseFileEntry(self, knowledge_base, file_entry): |
| 299 """Parses artifact file system data for a preprocessing attribute. |
| 300 |
| 301 Args: |
| 302 knowledge_base (KnowledgeBase): to fill with preprocessing information. |
| 303 file_entry (dfvfs.FileEntry): file entry that contains the artifact |
| 304 value data. |
| 305 |
| 306 Returns: |
| 307 bool: True if all the preprocessing attributes were found and |
| 308 the preprocessor plugin is done. |
292 | 309 |
293 Raises: | 310 Raises: |
294 errors.PreProcessFail: if the preprocessing fails. | 311 errors.PreProcessFail: if the preprocessing fails. |
295 """ | 312 """ |
296 root_key = self._GetPlistRootKey(file_entry) | 313 root_key = self._GetPlistRootKey(file_entry) |
297 if not root_key: | 314 if not root_key: |
298 location = getattr(file_entry.path_spec, u'location', u'') | 315 location = getattr(file_entry.path_spec, u'location', u'') |
299 raise errors.PreProcessFail( | 316 raise errors.PreProcessFail(( |
300 u'Missing root key in plist: {0:s}'.format(location)) | 317 u'Unable to read: {0:s} plist: {1:s} with error: missing root ' |
| 318 u'key.').format(self.ARTIFACT_DEFINITION_NAME, location)) |
301 | 319 |
302 try: | 320 try: |
303 match = self._GetKeysDefaultEmpty(root_key, self._KEYS) | 321 match = self._GetKeysDefaultEmpty(root_key, self._KEYS) |
304 except KeyError as exception: | 322 except KeyError as exception: |
305 location = getattr(file_entry.path_spec, u'location', u'') | 323 location = getattr(file_entry.path_spec, u'location', u'') |
306 raise errors.PreProcessFail( | 324 raise errors.PreProcessFail( |
307 u'Unable to read user plist file: {0:s} with error: {1:s}'.format( | 325 u'Unable to read: {0:s} plist: {1:s} with error: {2!s}'.format( |
308 location, exception)) | 326 self.ARTIFACT_DEFINITION_NAME, location, exception)) |
309 | 327 |
310 name = match.get(u'name', [None])[0] | 328 name = match.get(u'name', [None])[0] |
311 uid = match.get(u'uid', [None])[0] | 329 uid = match.get(u'uid', [None])[0] |
312 | 330 |
313 if not name or not uid: | 331 if not name or not uid: |
314 # TODO: add and store preprocessing errors. | 332 # TODO: add and store preprocessing errors. |
315 return | 333 return False |
316 | 334 |
317 user_account = artifacts.UserAccountArtifact( | 335 user_account = artifacts.UserAccountArtifact( |
318 identifier=uid, username=name) | 336 identifier=uid, username=name) |
319 user_account.group_identifier = match.get(u'gid', [None])[0] | 337 user_account.group_identifier = match.get(u'gid', [None])[0] |
320 user_account.full_name = match.get(u'realname', [None])[0] | 338 user_account.full_name = match.get(u'realname', [None])[0] |
321 user_account.shell = match.get(u'shell', [None])[0] | 339 user_account.shell = match.get(u'shell', [None])[0] |
322 user_account.user_directory = match.get(u'home', [None])[0] | 340 user_account.user_directory = match.get(u'home', [None])[0] |
323 | 341 |
324 try: | 342 try: |
325 knowledge_base.AddUserAccount(user_account) | 343 knowledge_base.AddUserAccount(user_account) |
326 except KeyError: | 344 except KeyError: |
327 # TODO: add and store preprocessing errors. | 345 # TODO: add and store preprocessing errors. |
328 pass | 346 pass |
329 | 347 |
330 def Run(self, searcher, knowledge_base): | 348 return False |
331 """Determines the value of the preprocessing attributes. | |
332 | |
333 Args: | |
334 searcher (dfvfs.FileSystemSearcher): file system searcher. | |
335 knowledge_base (KnowledgeBase): to fill with preprocessing information. | |
336 """ | |
337 path_specs = self._FindPathSpecs(searcher, self._PLIST_PATH_REGEX) | |
338 if not path_specs: | |
339 return | |
340 | |
341 for path_spec in path_specs: | |
342 file_entry = searcher.GetFileEntryByPathSpec(path_spec) | |
343 self._ParsePlistFileEntry(knowledge_base, file_entry) | |
344 | 349 |
345 | 350 |
346 manager.PreprocessPluginsManager.RegisterPlugins([ | 351 manager.PreprocessPluginsManager.RegisterPlugins([ |
347 MacOSXHostnamePreprocessPlugin, MacOSXKeyboardLayoutPreprocessPlugin, | 352 MacOSHostnamePlugin, MacOSKeyboardLayoutPlugin, MacOSSystemVersionPlugin, |
348 MacOSXSystemVersionPreprocessPlugin, MacOSXTimeZonePreprocessPlugin, | 353 MacOSTimeZonePlugin, MacOSUserAccountsPlugin]) |
349 MacOSXUserAccountsPreprocessPlugin]) | |
LEFT | RIGHT |