assemblyline-v4-service 4.4.0.9__py3-none-any.whl → 4.4.0.14__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.
Potentially problematic release.
This version of assemblyline-v4-service might be problematic. Click here for more details.
- assemblyline_v4_service/VERSION +1 -1
- assemblyline_v4_service/common/base.py +8 -0
- assemblyline_v4_service/common/dynamic_service_helper.py +19 -32
- assemblyline_v4_service/common/result.py +25 -11
- assemblyline_v4_service/updater/updater.py +11 -8
- {assemblyline_v4_service-4.4.0.9.dist-info → assemblyline_v4_service-4.4.0.14.dist-info}/METADATA +1 -1
- {assemblyline_v4_service-4.4.0.9.dist-info → assemblyline_v4_service-4.4.0.14.dist-info}/RECORD +10 -10
- {assemblyline_v4_service-4.4.0.9.dist-info → assemblyline_v4_service-4.4.0.14.dist-info}/LICENCE.md +0 -0
- {assemblyline_v4_service-4.4.0.9.dist-info → assemblyline_v4_service-4.4.0.14.dist-info}/WHEEL +0 -0
- {assemblyline_v4_service-4.4.0.9.dist-info → assemblyline_v4_service-4.4.0.14.dist-info}/top_level.txt +0 -0
assemblyline_v4_service/VERSION
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
4.4.0.
|
|
1
|
+
4.4.0.14
|
|
@@ -29,6 +29,7 @@ LOG_LEVEL = logging.getLevelName(os.environ.get("LOG_LEVEL", "INFO"))
|
|
|
29
29
|
UPDATES_DIR = os.environ.get('UPDATES_DIR', '/updates')
|
|
30
30
|
UPDATES_CA = os.environ.get('UPDATES_CA', '/etc/assemblyline/ssl/al_root-ca.crt')
|
|
31
31
|
PRIVILEGED = os.environ.get('PRIVILEGED', 'false') == 'true'
|
|
32
|
+
MIN_SECONDS_BETWEEN_UPDATES = float(os.environ.get('MIN_SECONDS_BETWEEN_UPDATES', '10.0'))
|
|
32
33
|
|
|
33
34
|
RECOVERABLE_RE_MSG = [
|
|
34
35
|
"cannot schedule new futures after interpreter shutdown",
|
|
@@ -77,6 +78,7 @@ class ServiceBase:
|
|
|
77
78
|
self.rules_directory: str = None
|
|
78
79
|
self.rules_list: list = []
|
|
79
80
|
self.update_time: int = None
|
|
81
|
+
self.update_check_time: float = 0.0
|
|
80
82
|
self.rules_hash: str = None
|
|
81
83
|
|
|
82
84
|
@property
|
|
@@ -236,6 +238,12 @@ class ServiceBase:
|
|
|
236
238
|
|
|
237
239
|
# Only relevant for services using updaters (reserving 'updates' as the defacto container name)
|
|
238
240
|
def _download_rules(self):
|
|
241
|
+
# check if we just tried to download rules to reduce traffic
|
|
242
|
+
if time.time() - self.update_check_time < MIN_SECONDS_BETWEEN_UPDATES:
|
|
243
|
+
return
|
|
244
|
+
self.update_check_time = time.time()
|
|
245
|
+
|
|
246
|
+
# Resolve the update target
|
|
239
247
|
scheme, verify = 'http', None
|
|
240
248
|
if os.path.exists(UPDATES_CA):
|
|
241
249
|
scheme, verify = 'https', UPDATES_CA
|
|
@@ -2,46 +2,29 @@ from datetime import datetime
|
|
|
2
2
|
from hashlib import sha256
|
|
3
3
|
from json import dumps
|
|
4
4
|
from logging import getLogger
|
|
5
|
-
from re import compile, escape,
|
|
5
|
+
from re import compile, escape, findall
|
|
6
|
+
from re import match as re_match
|
|
7
|
+
from re import sub
|
|
6
8
|
from typing import Any, Dict, List, Optional, Union
|
|
7
9
|
from urllib.parse import urlparse
|
|
8
10
|
from uuid import UUID, uuid4
|
|
9
11
|
|
|
10
12
|
from assemblyline.common import log as al_log
|
|
11
|
-
from assemblyline.common.attack_map import
|
|
12
|
-
attack_map,
|
|
13
|
-
software_map,
|
|
14
|
-
group_map,
|
|
15
|
-
revoke_map,
|
|
16
|
-
)
|
|
13
|
+
from assemblyline.common.attack_map import attack_map, group_map, revoke_map, software_map
|
|
17
14
|
from assemblyline.common.digests import get_sha256_for_file
|
|
18
|
-
from assemblyline.common.isotime import
|
|
19
|
-
epoch_to_local,
|
|
20
|
-
LOCAL_FMT,
|
|
21
|
-
local_to_epoch,
|
|
22
|
-
MAX_TIME,
|
|
23
|
-
MIN_TIME,
|
|
24
|
-
format_time,
|
|
25
|
-
)
|
|
15
|
+
from assemblyline.common.isotime import LOCAL_FMT, MAX_TIME, MIN_TIME, epoch_to_local, format_time, local_to_epoch
|
|
26
16
|
from assemblyline.common.uid import get_random_id
|
|
27
|
-
from assemblyline.odm.base import DOMAIN_REGEX, IP_REGEX, IPV4_REGEX,
|
|
28
|
-
from assemblyline.odm.models.ontology.results import
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
)
|
|
33
|
-
|
|
17
|
+
from assemblyline.odm.base import DOMAIN_REGEX, FULL_URI, IP_REGEX, IPV4_REGEX, URI_PATH
|
|
18
|
+
from assemblyline.odm.models.ontology.results import NetworkConnection as NetworkConnectionModel
|
|
19
|
+
from assemblyline.odm.models.ontology.results import Process as ProcessModel
|
|
20
|
+
from assemblyline.odm.models.ontology.results import Sandbox as SandboxModel
|
|
21
|
+
from assemblyline.odm.models.ontology.results import Signature as SignatureModel
|
|
34
22
|
# from assemblyline_v4_service.common.balbuzard.patterns import PatternMatch
|
|
35
23
|
from assemblyline_v4_service.common.base import ServiceBase
|
|
36
24
|
from assemblyline_v4_service.common.request import ServiceRequest
|
|
37
|
-
from assemblyline_v4_service.common.result import (
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
ResultProcessTreeSection,
|
|
41
|
-
ResultTableSection,
|
|
42
|
-
TableRow,
|
|
43
|
-
)
|
|
44
|
-
from assemblyline_v4_service.common.safelist_helper import is_tag_safelisted, URL_REGEX
|
|
25
|
+
from assemblyline_v4_service.common.result import (ProcessItem, ResultProcessTreeSection, ResultSection,
|
|
26
|
+
ResultTableSection, TableRow)
|
|
27
|
+
from assemblyline_v4_service.common.safelist_helper import URL_REGEX, is_tag_safelisted
|
|
45
28
|
from assemblyline_v4_service.common.tag_helper import add_tag
|
|
46
29
|
from assemblyline_v4_service.common.task import MaxExtractedExceeded
|
|
47
30
|
|
|
@@ -1875,13 +1858,17 @@ class OntologyResults:
|
|
|
1875
1858
|
else:
|
|
1876
1859
|
return network_http_with_details[0]
|
|
1877
1860
|
|
|
1878
|
-
def get_network_connection_by_network_http(self, network_http: NetworkHTTP) -> Optional[
|
|
1861
|
+
def get_network_connection_by_network_http(self, network_http: NetworkHTTP) -> Optional[NetworkConnection]:
|
|
1879
1862
|
"""
|
|
1880
1863
|
This method returns the network connection corresponding to the given network http object
|
|
1881
1864
|
:param network_http: The given network http object
|
|
1882
1865
|
:return: The corresponding network connection
|
|
1883
1866
|
"""
|
|
1884
|
-
|
|
1867
|
+
for netflow in self.netflows:
|
|
1868
|
+
if netflow.http_details == network_http:
|
|
1869
|
+
return netflow
|
|
1870
|
+
|
|
1871
|
+
return None
|
|
1885
1872
|
|
|
1886
1873
|
# Process manipulation methods
|
|
1887
1874
|
def set_processes(self, processes: List[Process]) -> None:
|
|
@@ -14,6 +14,9 @@ from assemblyline_v4_service.common.helper import get_service_attributes, get_he
|
|
|
14
14
|
if TYPE_CHECKING: # Avoid circular dependency
|
|
15
15
|
from assemblyline_v4_service.common.request import ServiceRequest
|
|
16
16
|
|
|
17
|
+
# Type of values in KV sections
|
|
18
|
+
KV_VALUE_TYPE = Union[str, bool, int]
|
|
19
|
+
|
|
17
20
|
al_log.init_logging('service.result')
|
|
18
21
|
log = logging.getLogger('assemblyline.service.result')
|
|
19
22
|
|
|
@@ -211,7 +214,7 @@ class SectionBody:
|
|
|
211
214
|
return self._format
|
|
212
215
|
|
|
213
216
|
@property
|
|
214
|
-
def body(self):
|
|
217
|
+
def body(self) -> str | None:
|
|
215
218
|
if not self._data:
|
|
216
219
|
return None
|
|
217
220
|
elif not isinstance(self._data, str):
|
|
@@ -278,21 +281,23 @@ class GraphSectionBody(SectionBody):
|
|
|
278
281
|
|
|
279
282
|
|
|
280
283
|
class KVSectionBody(SectionBody):
|
|
281
|
-
def __init__(self, **kwargs) -> None:
|
|
284
|
+
def __init__(self, **kwargs: KV_VALUE_TYPE) -> None:
|
|
285
|
+
self._data: dict[str, KV_VALUE_TYPE]
|
|
282
286
|
super().__init__(BODY_FORMAT.KEY_VALUE, body=kwargs)
|
|
283
287
|
|
|
284
|
-
def set_item(self, key: str, value:
|
|
288
|
+
def set_item(self, key: str, value: KV_VALUE_TYPE) -> None:
|
|
285
289
|
self._data[str(key)] = value
|
|
286
290
|
|
|
287
|
-
def update_items(self, new_dict: dict):
|
|
291
|
+
def update_items(self, new_dict: dict[str, KV_VALUE_TYPE]):
|
|
288
292
|
self._data.update({str(k): v for k, v in new_dict.items()})
|
|
289
293
|
|
|
290
294
|
|
|
291
295
|
class OrderedKVSectionBody(SectionBody):
|
|
292
|
-
def __init__(self) -> None:
|
|
293
|
-
|
|
296
|
+
def __init__(self, **kwargs: KV_VALUE_TYPE) -> None:
|
|
297
|
+
self._data: list[tuple[str, KV_VALUE_TYPE]]
|
|
298
|
+
super().__init__(BODY_FORMAT.ORDERED_KEY_VALUE, body=[(str(key), value) for key, value in kwargs.items()])
|
|
294
299
|
|
|
295
|
-
def add_item(self, key: str, value:
|
|
300
|
+
def add_item(self, key: str, value: KV_VALUE_TYPE) -> None:
|
|
296
301
|
self._data.append((str(key), value))
|
|
297
302
|
|
|
298
303
|
|
|
@@ -650,6 +655,7 @@ class ResultMemoryDumpSection(ResultSection):
|
|
|
650
655
|
|
|
651
656
|
class ResultGraphSection(TypeSpecificResultSection):
|
|
652
657
|
def __init__(self, title_text: Union[str, List], **kwargs):
|
|
658
|
+
self.section_body: GraphSectionBody
|
|
653
659
|
super().__init__(title_text, GraphSectionBody(), **kwargs)
|
|
654
660
|
|
|
655
661
|
def set_colormap(self, cmap_min: int, cmap_max: int, values: List[int]) -> None:
|
|
@@ -658,6 +664,7 @@ class ResultGraphSection(TypeSpecificResultSection):
|
|
|
658
664
|
|
|
659
665
|
class ResultURLSection(TypeSpecificResultSection):
|
|
660
666
|
def __init__(self, title_text: Union[str, List], **kwargs):
|
|
667
|
+
self.section_body: URLSectionBody
|
|
661
668
|
super().__init__(title_text, URLSectionBody(), **kwargs)
|
|
662
669
|
|
|
663
670
|
def add_url(self, url: str, name: Optional[str] = None) -> None:
|
|
@@ -665,8 +672,9 @@ class ResultURLSection(TypeSpecificResultSection):
|
|
|
665
672
|
|
|
666
673
|
|
|
667
674
|
class ResultKeyValueSection(TypeSpecificResultSection):
|
|
668
|
-
def __init__(self, title_text: Union[str, List], **kwargs):
|
|
669
|
-
|
|
675
|
+
def __init__(self, title_text: Union[str, List], body: dict[str, KV_VALUE_TYPE] | None = None, **kwargs):
|
|
676
|
+
self.section_body: KVSectionBody
|
|
677
|
+
super().__init__(title_text, KVSectionBody(**(body if body else {})), **kwargs)
|
|
670
678
|
|
|
671
679
|
def set_item(self, key: str, value: Union[str, bool, int]) -> None:
|
|
672
680
|
self.section_body.set_item(key, value)
|
|
@@ -676,8 +684,9 @@ class ResultKeyValueSection(TypeSpecificResultSection):
|
|
|
676
684
|
|
|
677
685
|
|
|
678
686
|
class ResultOrderedKeyValueSection(TypeSpecificResultSection):
|
|
679
|
-
def __init__(self, title_text: Union[str, List], **kwargs):
|
|
680
|
-
|
|
687
|
+
def __init__(self, title_text: Union[str, List], body: dict[str, KV_VALUE_TYPE] | None = None, **kwargs):
|
|
688
|
+
self.section_body: OrderedKVSectionBody
|
|
689
|
+
super().__init__(title_text, OrderedKVSectionBody(**(body if body else {})), **kwargs)
|
|
681
690
|
|
|
682
691
|
def add_item(self, key: str, value: Union[str, bool, int]) -> None:
|
|
683
692
|
self.section_body.add_item(key, value)
|
|
@@ -685,6 +694,7 @@ class ResultOrderedKeyValueSection(TypeSpecificResultSection):
|
|
|
685
694
|
|
|
686
695
|
class ResultJSONSection(TypeSpecificResultSection):
|
|
687
696
|
def __init__(self, title_text: Union[str, List], **kwargs):
|
|
697
|
+
self.section_body: JSONSectionBody
|
|
688
698
|
super().__init__(title_text, JSONSectionBody(), **kwargs)
|
|
689
699
|
|
|
690
700
|
def set_json(self, json_body: dict) -> None:
|
|
@@ -696,6 +706,7 @@ class ResultJSONSection(TypeSpecificResultSection):
|
|
|
696
706
|
|
|
697
707
|
class ResultProcessTreeSection(TypeSpecificResultSection):
|
|
698
708
|
def __init__(self, title_text: Union[str, List], **kwargs):
|
|
709
|
+
self.section_body: ProcessTreeSectionBody
|
|
699
710
|
super().__init__(title_text, ProcessTreeSectionBody(), **kwargs)
|
|
700
711
|
|
|
701
712
|
def add_process(self, process: ProcessItem) -> None:
|
|
@@ -704,6 +715,7 @@ class ResultProcessTreeSection(TypeSpecificResultSection):
|
|
|
704
715
|
|
|
705
716
|
class ResultTableSection(TypeSpecificResultSection):
|
|
706
717
|
def __init__(self, title_text: Union[str, List], **kwargs):
|
|
718
|
+
self.section_body: TableSectionBody
|
|
707
719
|
super().__init__(title_text, TableSectionBody(), **kwargs)
|
|
708
720
|
|
|
709
721
|
def add_row(self, row: TableRow) -> None:
|
|
@@ -731,6 +743,7 @@ class ResultImageSection(TypeSpecificResultSection):
|
|
|
731
743
|
|
|
732
744
|
class ResultTimelineSection(TypeSpecificResultSection):
|
|
733
745
|
def __init__(self, title_text: Union[str, List], **kwargs):
|
|
746
|
+
self.section_body: TimelineSectionBody
|
|
734
747
|
super().__init__(title_text, TimelineSectionBody(), **kwargs)
|
|
735
748
|
|
|
736
749
|
def add_node(self, title: str, content: str, opposite_content: str, icon: str = None, signatures: List[str] = [],
|
|
@@ -741,6 +754,7 @@ class ResultTimelineSection(TypeSpecificResultSection):
|
|
|
741
754
|
|
|
742
755
|
class ResultMultiSection(TypeSpecificResultSection):
|
|
743
756
|
def __init__(self, title_text: Union[str, List], **kwargs):
|
|
757
|
+
self.section_body: MultiSectionBody
|
|
744
758
|
super().__init__(title_text, MultiSectionBody(), **kwargs)
|
|
745
759
|
|
|
746
760
|
def add_section_part(self, section_part: SectionBody) -> bool:
|
|
@@ -222,17 +222,20 @@ class ServiceUpdater(ThreadedCoreBase):
|
|
|
222
222
|
return 0
|
|
223
223
|
return hash(json.dumps(service.update_config.as_primitives()))
|
|
224
224
|
|
|
225
|
-
def _handle_source_update_event(self, data: list[str]):
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
225
|
+
def _handle_source_update_event(self, data: Optional[list[str]]):
|
|
226
|
+
if data is not None:
|
|
227
|
+
# Received an event regarding a change to source
|
|
228
|
+
self.log.info(f'Triggered to update the following: {data}')
|
|
229
|
+
self.do_source_update(self._service, specific_sources=data)
|
|
230
|
+
self.local_update_flag.set()
|
|
231
|
+
else:
|
|
232
|
+
self.source_update_flag.set()
|
|
230
233
|
|
|
231
|
-
def _handle_signature_change_event(self, data: SignatureChange):
|
|
234
|
+
def _handle_signature_change_event(self, data: Optional[SignatureChange]):
|
|
232
235
|
self.local_update_flag.set()
|
|
233
236
|
|
|
234
|
-
def _handle_service_change_event(self, data: ServiceChange):
|
|
235
|
-
if data.operation == Operation.Modified:
|
|
237
|
+
def _handle_service_change_event(self, data: Optional[ServiceChange]):
|
|
238
|
+
if data is None or data.operation == Operation.Modified:
|
|
236
239
|
self._pull_settings()
|
|
237
240
|
|
|
238
241
|
def _sync_settings(self):
|
{assemblyline_v4_service-4.4.0.9.dist-info → assemblyline_v4_service-4.4.0.14.dist-info}/RECORD
RENAMED
|
@@ -1,18 +1,18 @@
|
|
|
1
|
-
assemblyline_v4_service/VERSION,sha256=
|
|
1
|
+
assemblyline_v4_service/VERSION,sha256=A9KFeWrS1AwZZBnk60nZgClg6j-A0_X4-XyN5wWDKPE,9
|
|
2
2
|
assemblyline_v4_service/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
3
3
|
assemblyline_v4_service/healthz.py,sha256=3QGBg0EZuXC6UN411HFwpLNEop9UvS9feFhvBUTP-k4,1576
|
|
4
4
|
assemblyline_v4_service/run_privileged_service.py,sha256=9uTfHetXR5G-EDKMDrgfWUOw34yr64-cj6Cm9eZaCbQ,14547
|
|
5
5
|
assemblyline_v4_service/run_service.py,sha256=RCqxdm-OAwJhl15BnKFkuavpQ5k6eTX3ZGeSna5JJBw,5557
|
|
6
6
|
assemblyline_v4_service/common/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
7
7
|
assemblyline_v4_service/common/api.py,sha256=U908p3wlW9fEydx77GgI2E-6wW6T8Nc3R91nNOKU0H0,4453
|
|
8
|
-
assemblyline_v4_service/common/base.py,sha256=
|
|
9
|
-
assemblyline_v4_service/common/dynamic_service_helper.py,sha256=
|
|
8
|
+
assemblyline_v4_service/common/base.py,sha256=STzfZ9dwqvbgbKiFs-aLk05pdhyK6Psz4hZ3_fOmQYM,13039
|
|
9
|
+
assemblyline_v4_service/common/dynamic_service_helper.py,sha256=xIuuJLtf9Wz_mXdoquzCL7TmHtH_trH4a1PfRL9A-GM,147593
|
|
10
10
|
assemblyline_v4_service/common/helper.py,sha256=Fgimk8DhnS23aijTGewA1HwvPoAM61UUbHlrGBnSzL0,3290
|
|
11
11
|
assemblyline_v4_service/common/icap.py,sha256=phT3CT5uII3Qm90Nzi4O-eDkQ2jmr3zHcVVra4sqYSc,5376
|
|
12
12
|
assemblyline_v4_service/common/keytool_parse.py,sha256=e829hrNNG5LFw1kjLsYVZsafCm2S3NpgM6jBc6JKawY,2219
|
|
13
13
|
assemblyline_v4_service/common/ontology_helper.py,sha256=HJdFvZCP6OPNGySjjmXa-fLqTwaa9V-lnhCSv-isztQ,7768
|
|
14
14
|
assemblyline_v4_service/common/request.py,sha256=p8A9boDZ6KuVxl3EdhvaU1D_5K6_gAVoIbJYDz8TzjA,9711
|
|
15
|
-
assemblyline_v4_service/common/result.py,sha256=
|
|
15
|
+
assemblyline_v4_service/common/result.py,sha256=LEzZq0YjEoHZvhVZmlMd5AqAhsHE6mKqotX1mdmbTbg,29727
|
|
16
16
|
assemblyline_v4_service/common/safelist_helper.py,sha256=QHTuG8q52o3U307AADPgrIgug7aYFK2uQE4-EtWG3yQ,3037
|
|
17
17
|
assemblyline_v4_service/common/section_reducer.py,sha256=JJOT7eFfBn4hFJKHY9UeVEbHS-E8FpmQ_dPZC-dWla0,1513
|
|
18
18
|
assemblyline_v4_service/common/tag_helper.py,sha256=om3TVPY_XDeFDqVW2iUA349xbljSAy5tv667jCiA7JI,4186
|
|
@@ -45,9 +45,9 @@ assemblyline_v4_service/updater/__main__.py,sha256=9Os-u8Tf7MD73JSrUSPmOaErTgfve
|
|
|
45
45
|
assemblyline_v4_service/updater/app.py,sha256=Ass5DZtOCr0tdoRbLo7Qn8Ujlw8T8mUDroAaHxx2oMo,3198
|
|
46
46
|
assemblyline_v4_service/updater/gunicorn_config.py,sha256=p3j2KPBeD5jvMw9O5i7vAtlRgPSVVxIG9AO0DfN82J8,1247
|
|
47
47
|
assemblyline_v4_service/updater/helper.py,sha256=JD0gX3KHY-wvsFjTbWkT83F0d5Up3OfubMPinuNzbTQ,9069
|
|
48
|
-
assemblyline_v4_service/updater/updater.py,sha256=
|
|
49
|
-
assemblyline_v4_service-4.4.0.
|
|
50
|
-
assemblyline_v4_service-4.4.0.
|
|
51
|
-
assemblyline_v4_service-4.4.0.
|
|
52
|
-
assemblyline_v4_service-4.4.0.
|
|
53
|
-
assemblyline_v4_service-4.4.0.
|
|
48
|
+
assemblyline_v4_service/updater/updater.py,sha256=7Ep-qeQLuKffnrvOwi9Gb8eFyDxBtLUbFNkUlRpu2Fc,29163
|
|
49
|
+
assemblyline_v4_service-4.4.0.14.dist-info/LICENCE.md,sha256=NSkYo9EH8h5oOkzg4VhjAHF4339MqPP2cQ8msTPgl-c,1396
|
|
50
|
+
assemblyline_v4_service-4.4.0.14.dist-info/METADATA,sha256=0j_Omnpx1W995VjMeUoszqHLPfdl-CuAjDXJFgLW7nI,9328
|
|
51
|
+
assemblyline_v4_service-4.4.0.14.dist-info/WHEEL,sha256=pkctZYzUS4AYVn6dJ-7367OJZivF2e8RA9b_ZBjif18,92
|
|
52
|
+
assemblyline_v4_service-4.4.0.14.dist-info/top_level.txt,sha256=Ut5IqePObcxlJ8rv2--dOAzYbxzqlllfiV_51cbqjbA,24
|
|
53
|
+
assemblyline_v4_service-4.4.0.14.dist-info/RECORD,,
|
{assemblyline_v4_service-4.4.0.9.dist-info → assemblyline_v4_service-4.4.0.14.dist-info}/LICENCE.md
RENAMED
|
File without changes
|
{assemblyline_v4_service-4.4.0.9.dist-info → assemblyline_v4_service-4.4.0.14.dist-info}/WHEEL
RENAMED
|
File without changes
|
|
File without changes
|