dissect.target 3.11.dev21__py3-none-any.whl → 3.11.dev22__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,6 +1,8 @@
1
+ import io
1
2
  import re
3
+ from configparser import ConfigParser
2
4
  from itertools import chain
3
- from typing import BinaryIO, Iterator
5
+ from typing import Iterator, TextIO
4
6
 
5
7
  from dissect.target.exceptions import FileNotFoundError, UnsupportedPluginError
6
8
  from dissect.target.helpers.record import TargetRecordDescriptor
@@ -51,30 +53,29 @@ class ServicesPlugin(Plugin):
51
53
  if not path.exists() or not path.is_dir():
52
54
  continue
53
55
 
54
- for file_ in path.iterdir():
55
- if should_ignore_file(file_.name, ignored_suffixes):
56
+ for service_file in path.iterdir():
57
+ if should_ignore_file(service_file.name, ignored_suffixes):
56
58
  continue
57
59
 
58
60
  try:
59
- fh = file_.open("rt")
61
+ with service_file.open("rt") as fh:
62
+ config = parse_systemd_config(fh)
60
63
  except FileNotFoundError:
61
64
  # The service is registered but the symlink is broken.
62
65
  yield LinuxServiceRecord(
63
- ts=file_.stat(follow_symlinks=False).st_mtime,
64
- name=file_.name,
66
+ ts=service_file.stat(follow_symlinks=False).st_mtime,
67
+ name=service_file.name,
65
68
  config=None,
66
- source=file_,
69
+ source=service_file,
67
70
  _target=self.target,
68
71
  )
69
72
  continue
70
73
 
71
- config = parse_systemd_config(fh)
72
-
73
74
  yield LinuxServiceRecord(
74
- ts=file_.stat().st_mtime,
75
- name=file_.name,
75
+ ts=service_file.stat().st_mtime,
76
+ name=service_file.name,
76
77
  config=config,
77
- source=file_,
78
+ source=service_file,
78
79
  _target=self.target,
79
80
  )
80
81
 
@@ -106,43 +107,45 @@ def should_ignore_file(needle: str, haystack: list) -> bool:
106
107
  return False
107
108
 
108
109
 
109
- def parse_systemd_config(fh: BinaryIO) -> str:
110
+ def parse_systemd_config(fh: TextIO) -> str:
110
111
  """Returns a string of key/value pairs from a toml/ini-like string.
111
112
 
112
113
  This should probably be rewritten to return a proper dict as in
113
114
  its current form this is only useful when used in Splunk.
114
115
  """
115
- variables = ""
116
+ parser = ConfigParser(strict=False, delimiters=("=",), allow_no_value=True)
117
+ # to preserve casing from configuration.
118
+ parser.optionxform = str
119
+ parser.read_file(fh)
116
120
 
121
+ output = io.StringIO()
117
122
  try:
118
- for line in fh:
119
- line = line.strip().replace("\n", "")
120
-
121
- # segment start eg. [ExampleSegment]
122
- if line[:1] == "[":
123
- segment = re.sub(r"\[|\]", "", line)
124
-
125
- # ignore comments and empty lines
126
- elif line[:1] == ";" or line[:1] == "#" or line == "":
127
- continue
128
-
129
- # if line ends with \ it is likely part of a multi-line command argument
130
- elif line[-1] == "\\" or line[-1] == "'":
131
- variables = f"{variables} {line} "
132
-
133
- else:
134
- line = line.split("=", 1)
135
- if "segment" in locals():
136
- # some variables/arguments are not delimited by a '='
137
- # (eg. '-Kvalue' instead of '-key=value')
138
- if len(line) < 2:
139
- variables = f"{variables} {segment}_{line[0]} "
140
- else:
141
- variables = f'{variables} {segment}_{line[0]}="{line[1]}" '
123
+ for segment, configuration in parser.items():
124
+ original_key = ""
125
+ previous_value = ""
126
+ concat_value = False
127
+ for key, value in configuration.items():
128
+ original_key = original_key or key
129
+
130
+ if concat_value:
131
+ # A backslash was found at the end of the previous line
132
+ # If value is None, it might not contain a backslash
133
+ # So we turn it into an empty string.
134
+ value = f"{previous_value} {key} {value or ''}".strip()
135
+
136
+ concat_value = str(value).endswith("\\")
137
+ if concat_value:
138
+ # Remove any dangling empty space or backslashes
139
+ previous_value = value.rstrip("\\ ")
142
140
  else:
143
- variables = f"{variables} {line} ".strip()
141
+ output.write(f'{segment}_{original_key or key}="{value}" ')
142
+ original_key = ""
143
+ previous_value = ""
144
144
 
145
145
  except UnicodeDecodeError:
146
146
  pass
147
147
 
148
- return variables.strip()
148
+ output_data = output.getvalue()
149
+ # Remove any back slashes or new line characters.
150
+ output_data = re.sub(r"(\\|\n)", "", output_data)
151
+ return output_data.strip()
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: dissect.target
3
- Version: 3.11.dev21
3
+ Version: 3.11.dev22
4
4
  Summary: This module ties all other Dissect modules together, it provides a programming API and command line tools which allow easy access to various data sources inside disk images or file collections (a.k.a. targets)
5
5
  Author-email: Dissect Team <dissect@fox-it.com>
6
6
  License: Affero General Public License v3
@@ -153,7 +153,7 @@ dissect/target/plugins/os/unix/generic.py,sha256=R9fi1qNDaY5_l5g0XVLuXv1jOSz9wpb
153
153
  dissect/target/plugins/os/unix/history.py,sha256=ocFkn3LX1-ptkWs6cfRHo3Daa2MSwSyaP2sxVOE7LIY,4423
154
154
  dissect/target/plugins/os/unix/locale.py,sha256=EJEZiRvhlETPbOp6NHCskBAb8dsJIulcZTxaKgttvxU,2811
155
155
  dissect/target/plugins/os/unix/packagemanager.py,sha256=-mxNhDjvj497-wBvu3z22316Ux4KOnMp4cs26BJchyQ,2437
156
- dissect/target/plugins/os/unix/services.py,sha256=G7Lcd4r7BPelr2ifcGTsv5UN-hxGMSbjFXLitl8bT4s,4935
156
+ dissect/target/plugins/os/unix/services.py,sha256=t9vN1OOdDM_f59JK47EnQHLWPrc3pFC0QnbaMarRIno,5273
157
157
  dissect/target/plugins/os/unix/shadow.py,sha256=7ztW_fYLihxNjS2opFToF-xKZngYDGcTEbZKnodRkc8,3409
158
158
  dissect/target/plugins/os/unix/bsd/_os.py,sha256=e5rttTOFOmd7e2HqP9ZZFMEiPLBr-8rfH0XH1IIeroQ,1372
159
159
  dissect/target/plugins/os/unix/bsd/freebsd/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
@@ -273,10 +273,10 @@ dissect/target/volumes/bde.py,sha256=gYGg5yF9MNARwNzEkrEfZmKkxyZW4rhLkpdnPJCbhGk
273
273
  dissect/target/volumes/disk.py,sha256=95grSsPt1BLVpKwTclwQYzPFGKTkFFqapIk0RoGWf38,968
274
274
  dissect/target/volumes/lvm.py,sha256=_kIB1mdRs1OFhRgoT4VEP5Fv8imQnI7oQ_ie4x710tQ,1814
275
275
  dissect/target/volumes/vmfs.py,sha256=mlAJ8278tYaoRjk1u6tFFlCaDQUrVu5ZZE4ikiFvxi8,1707
276
- dissect.target-3.11.dev21.dist-info/COPYRIGHT,sha256=m-9ih2RVhMiXHI2bf_oNSSgHgkeIvaYRVfKTwFbnJPA,301
277
- dissect.target-3.11.dev21.dist-info/LICENSE,sha256=DZak_2itbUtvHzD3E7GNUYSRK6jdOJ-GqncQ2weavLA,34523
278
- dissect.target-3.11.dev21.dist-info/METADATA,sha256=vItcyHWWxmMfSO1_bhaL_fYAVEBBfR8caKoKAaY4QgI,10755
279
- dissect.target-3.11.dev21.dist-info/WHEEL,sha256=AtBG6SXL3KF_v0NxLf0ehyVOh0cold-JbJYXNGorC6Q,92
280
- dissect.target-3.11.dev21.dist-info/entry_points.txt,sha256=tvFPa-Ap-gakjaPwRc6Fl6mxHzxEZ_arAVU-IUYeo_s,447
281
- dissect.target-3.11.dev21.dist-info/top_level.txt,sha256=Mn-CQzEYsAbkxrUI0TnplHuXnGVKzxpDw_po_sXpvv4,8
282
- dissect.target-3.11.dev21.dist-info/RECORD,,
276
+ dissect.target-3.11.dev22.dist-info/COPYRIGHT,sha256=m-9ih2RVhMiXHI2bf_oNSSgHgkeIvaYRVfKTwFbnJPA,301
277
+ dissect.target-3.11.dev22.dist-info/LICENSE,sha256=DZak_2itbUtvHzD3E7GNUYSRK6jdOJ-GqncQ2weavLA,34523
278
+ dissect.target-3.11.dev22.dist-info/METADATA,sha256=W5FRbLJTPd1qh1WasztwQ5BSCPpd0AzaSVihYRSXlvw,10755
279
+ dissect.target-3.11.dev22.dist-info/WHEEL,sha256=AtBG6SXL3KF_v0NxLf0ehyVOh0cold-JbJYXNGorC6Q,92
280
+ dissect.target-3.11.dev22.dist-info/entry_points.txt,sha256=tvFPa-Ap-gakjaPwRc6Fl6mxHzxEZ_arAVU-IUYeo_s,447
281
+ dissect.target-3.11.dev22.dist-info/top_level.txt,sha256=Mn-CQzEYsAbkxrUI0TnplHuXnGVKzxpDw_po_sXpvv4,8
282
+ dissect.target-3.11.dev22.dist-info/RECORD,,