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

Sign up to get free protection for your applications and to get access to all the features.
@@ -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,,