assemblyline 4.7.2.dev41__tar.gz → 4.7.2.dev43__tar.gz
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.
- {assemblyline-4.7.2.dev41/assemblyline.egg-info → assemblyline-4.7.2.dev43}/PKG-INFO +1 -1
- assemblyline-4.7.2.dev43/assemblyline/VERSION +1 -0
- {assemblyline-4.7.2.dev41 → assemblyline-4.7.2.dev43}/assemblyline/common/backupmanager.py +4 -4
- {assemblyline-4.7.2.dev41 → assemblyline-4.7.2.dev43}/assemblyline/common/bundling.py +4 -4
- {assemblyline-4.7.2.dev41 → assemblyline-4.7.2.dev43}/assemblyline/common/classification.py +22 -26
- {assemblyline-4.7.2.dev41 → assemblyline-4.7.2.dev43}/assemblyline/common/identify.py +5 -5
- {assemblyline-4.7.2.dev41 → assemblyline-4.7.2.dev43}/assemblyline/common/path.py +2 -5
- {assemblyline-4.7.2.dev41 → assemblyline-4.7.2.dev43}/assemblyline/common/postprocess.py +4 -16
- {assemblyline-4.7.2.dev41 → assemblyline-4.7.2.dev43}/assemblyline/common/str_utils.py +2 -2
- {assemblyline-4.7.2.dev41 → assemblyline-4.7.2.dev43}/assemblyline/datastore/helper.py +39 -33
- {assemblyline-4.7.2.dev41 → assemblyline-4.7.2.dev43}/assemblyline/datastore/support/build.py +1 -4
- {assemblyline-4.7.2.dev41 → assemblyline-4.7.2.dev43}/assemblyline/odm/base.py +3 -3
- {assemblyline-4.7.2.dev41 → assemblyline-4.7.2.dev43}/assemblyline/odm/models/alert.py +1 -1
- {assemblyline-4.7.2.dev41 → assemblyline-4.7.2.dev43}/assemblyline/odm/models/config.py +2 -0
- {assemblyline-4.7.2.dev41 → assemblyline-4.7.2.dev43}/assemblyline/odm/models/ontology/results/network.py +1 -1
- {assemblyline-4.7.2.dev41 → assemblyline-4.7.2.dev43}/assemblyline/odm/models/user.py +2 -2
- {assemblyline-4.7.2.dev41 → assemblyline-4.7.2.dev43}/assemblyline/odm/random_data/__init__.py +3 -3
- {assemblyline-4.7.2.dev41 → assemblyline-4.7.2.dev43}/assemblyline/remote/datatypes/exporting_counter.py +1 -1
- {assemblyline-4.7.2.dev41 → assemblyline-4.7.2.dev43}/assemblyline/remote/datatypes/hash.py +1 -1
- {assemblyline-4.7.2.dev41 → assemblyline-4.7.2.dev43}/assemblyline/remote/datatypes/queues/named.py +1 -1
- {assemblyline-4.7.2.dev41 → assemblyline-4.7.2.dev43}/assemblyline/remote/datatypes/queues/priority.py +1 -1
- {assemblyline-4.7.2.dev41 → assemblyline-4.7.2.dev43/assemblyline.egg-info}/PKG-INFO +1 -1
- assemblyline-4.7.2.dev41/assemblyline/VERSION +0 -1
- {assemblyline-4.7.2.dev41 → assemblyline-4.7.2.dev43}/LICENCE.md +0 -0
- {assemblyline-4.7.2.dev41 → assemblyline-4.7.2.dev43}/MANIFEST.in +0 -0
- {assemblyline-4.7.2.dev41 → assemblyline-4.7.2.dev43}/README.md +0 -0
- {assemblyline-4.7.2.dev41 → assemblyline-4.7.2.dev43}/assemblyline/__init__.py +0 -0
- {assemblyline-4.7.2.dev41 → assemblyline-4.7.2.dev43}/assemblyline/cachestore/__init__.py +0 -0
- {assemblyline-4.7.2.dev41 → assemblyline-4.7.2.dev43}/assemblyline/common/__init__.py +0 -0
- {assemblyline-4.7.2.dev41 → assemblyline-4.7.2.dev43}/assemblyline/common/archiving.py +0 -0
- {assemblyline-4.7.2.dev41 → assemblyline-4.7.2.dev43}/assemblyline/common/attack_map.py +0 -0
- {assemblyline-4.7.2.dev41 → assemblyline-4.7.2.dev43}/assemblyline/common/banner.py +0 -0
- {assemblyline-4.7.2.dev41 → assemblyline-4.7.2.dev43}/assemblyline/common/caching.py +0 -0
- {assemblyline-4.7.2.dev41 → assemblyline-4.7.2.dev43}/assemblyline/common/chunk.py +0 -0
- {assemblyline-4.7.2.dev41 → assemblyline-4.7.2.dev43}/assemblyline/common/classification.yml +0 -0
- {assemblyline-4.7.2.dev41 → assemblyline-4.7.2.dev43}/assemblyline/common/cleanup_filestore.py +0 -0
- {assemblyline-4.7.2.dev41 → assemblyline-4.7.2.dev43}/assemblyline/common/codec.py +0 -0
- {assemblyline-4.7.2.dev41 → assemblyline-4.7.2.dev43}/assemblyline/common/comms.py +0 -0
- {assemblyline-4.7.2.dev41 → assemblyline-4.7.2.dev43}/assemblyline/common/constants.py +0 -0
- {assemblyline-4.7.2.dev41 → assemblyline-4.7.2.dev43}/assemblyline/common/custom.magic +0 -0
- {assemblyline-4.7.2.dev41 → assemblyline-4.7.2.dev43}/assemblyline/common/custom.yara +0 -0
- {assemblyline-4.7.2.dev41 → assemblyline-4.7.2.dev43}/assemblyline/common/dict_utils.py +0 -0
- {assemblyline-4.7.2.dev41 → assemblyline-4.7.2.dev43}/assemblyline/common/digests.py +0 -0
- {assemblyline-4.7.2.dev41 → assemblyline-4.7.2.dev43}/assemblyline/common/dispatcher.py +0 -0
- {assemblyline-4.7.2.dev41 → assemblyline-4.7.2.dev43}/assemblyline/common/entropy.py +0 -0
- {assemblyline-4.7.2.dev41 → assemblyline-4.7.2.dev43}/assemblyline/common/exceptions.py +0 -0
- {assemblyline-4.7.2.dev41 → assemblyline-4.7.2.dev43}/assemblyline/common/file.py +0 -0
- {assemblyline-4.7.2.dev41 → assemblyline-4.7.2.dev43}/assemblyline/common/forge.py +0 -0
- {assemblyline-4.7.2.dev41 → assemblyline-4.7.2.dev43}/assemblyline/common/heuristics.py +0 -0
- {assemblyline-4.7.2.dev41 → assemblyline-4.7.2.dev43}/assemblyline/common/hexdump.py +0 -0
- {assemblyline-4.7.2.dev41 → assemblyline-4.7.2.dev43}/assemblyline/common/identify_defaults.py +0 -0
- {assemblyline-4.7.2.dev41 → assemblyline-4.7.2.dev43}/assemblyline/common/importing.py +0 -0
- {assemblyline-4.7.2.dev41 → assemblyline-4.7.2.dev43}/assemblyline/common/iprange.py +0 -0
- {assemblyline-4.7.2.dev41 → assemblyline-4.7.2.dev43}/assemblyline/common/isotime.py +0 -0
- {assemblyline-4.7.2.dev41 → assemblyline-4.7.2.dev43}/assemblyline/common/log.py +0 -0
- {assemblyline-4.7.2.dev41 → assemblyline-4.7.2.dev43}/assemblyline/common/logformat.py +0 -0
- {assemblyline-4.7.2.dev41 → assemblyline-4.7.2.dev43}/assemblyline/common/lucene.lark +0 -0
- {assemblyline-4.7.2.dev41 → assemblyline-4.7.2.dev43}/assemblyline/common/memory_zip.py +0 -0
- {assemblyline-4.7.2.dev41 → assemblyline-4.7.2.dev43}/assemblyline/common/metrics.py +0 -0
- {assemblyline-4.7.2.dev41 → assemblyline-4.7.2.dev43}/assemblyline/common/net.py +0 -0
- {assemblyline-4.7.2.dev41 → assemblyline-4.7.2.dev43}/assemblyline/common/net_static.py +0 -0
- {assemblyline-4.7.2.dev41 → assemblyline-4.7.2.dev43}/assemblyline/common/null.py +0 -0
- {assemblyline-4.7.2.dev41 → assemblyline-4.7.2.dev43}/assemblyline/common/random_user.py +0 -0
- {assemblyline-4.7.2.dev41 → assemblyline-4.7.2.dev43}/assemblyline/common/security.py +0 -0
- {assemblyline-4.7.2.dev41 → assemblyline-4.7.2.dev43}/assemblyline/common/signaturing.py +0 -0
- {assemblyline-4.7.2.dev41 → assemblyline-4.7.2.dev43}/assemblyline/common/tag_safelist.yml +0 -0
- {assemblyline-4.7.2.dev41 → assemblyline-4.7.2.dev43}/assemblyline/common/tagging.py +0 -0
- {assemblyline-4.7.2.dev41 → assemblyline-4.7.2.dev43}/assemblyline/common/threading.py +0 -0
- {assemblyline-4.7.2.dev41 → assemblyline-4.7.2.dev43}/assemblyline/common/uid.py +0 -0
- {assemblyline-4.7.2.dev41 → assemblyline-4.7.2.dev43}/assemblyline/common/version.py +0 -0
- {assemblyline-4.7.2.dev41 → assemblyline-4.7.2.dev43}/assemblyline/datasource/__init__.py +0 -0
- {assemblyline-4.7.2.dev41 → assemblyline-4.7.2.dev43}/assemblyline/datasource/al.py +0 -0
- {assemblyline-4.7.2.dev41 → assemblyline-4.7.2.dev43}/assemblyline/datasource/alert.py +0 -0
- {assemblyline-4.7.2.dev41 → assemblyline-4.7.2.dev43}/assemblyline/datasource/common.py +0 -0
- {assemblyline-4.7.2.dev41 → assemblyline-4.7.2.dev43}/assemblyline/datastore/__init__.py +0 -0
- {assemblyline-4.7.2.dev41 → assemblyline-4.7.2.dev43}/assemblyline/datastore/bulk.py +0 -0
- {assemblyline-4.7.2.dev41 → assemblyline-4.7.2.dev43}/assemblyline/datastore/collection.py +0 -0
- {assemblyline-4.7.2.dev41 → assemblyline-4.7.2.dev43}/assemblyline/datastore/exceptions.py +0 -0
- {assemblyline-4.7.2.dev41 → assemblyline-4.7.2.dev43}/assemblyline/datastore/store.py +0 -0
- {assemblyline-4.7.2.dev41 → assemblyline-4.7.2.dev43}/assemblyline/datastore/support/__init__.py +0 -0
- {assemblyline-4.7.2.dev41 → assemblyline-4.7.2.dev43}/assemblyline/datastore/support/schemas.py +0 -0
- {assemblyline-4.7.2.dev41 → assemblyline-4.7.2.dev43}/assemblyline/filestore/__init__.py +0 -0
- {assemblyline-4.7.2.dev41 → assemblyline-4.7.2.dev43}/assemblyline/filestore/transport/__init__.py +0 -0
- {assemblyline-4.7.2.dev41 → assemblyline-4.7.2.dev43}/assemblyline/filestore/transport/azure.py +0 -0
- {assemblyline-4.7.2.dev41 → assemblyline-4.7.2.dev43}/assemblyline/filestore/transport/base.py +0 -0
- {assemblyline-4.7.2.dev41 → assemblyline-4.7.2.dev43}/assemblyline/filestore/transport/ftp.py +0 -0
- {assemblyline-4.7.2.dev41 → assemblyline-4.7.2.dev43}/assemblyline/filestore/transport/http.py +0 -0
- {assemblyline-4.7.2.dev41 → assemblyline-4.7.2.dev43}/assemblyline/filestore/transport/local.py +0 -0
- {assemblyline-4.7.2.dev41 → assemblyline-4.7.2.dev43}/assemblyline/filestore/transport/s3.py +0 -0
- {assemblyline-4.7.2.dev41 → assemblyline-4.7.2.dev43}/assemblyline/filestore/transport/sftp.py +0 -0
- {assemblyline-4.7.2.dev41 → assemblyline-4.7.2.dev43}/assemblyline/odm/__init__.py +0 -0
- {assemblyline-4.7.2.dev41 → assemblyline-4.7.2.dev43}/assemblyline/odm/common.py +0 -0
- {assemblyline-4.7.2.dev41 → assemblyline-4.7.2.dev43}/assemblyline/odm/messages/__init__.py +0 -0
- {assemblyline-4.7.2.dev41 → assemblyline-4.7.2.dev43}/assemblyline/odm/messages/alert.py +0 -0
- {assemblyline-4.7.2.dev41 → assemblyline-4.7.2.dev43}/assemblyline/odm/messages/alerter_heartbeat.py +0 -0
- {assemblyline-4.7.2.dev41 → assemblyline-4.7.2.dev43}/assemblyline/odm/messages/archive_heartbeat.py +0 -0
- {assemblyline-4.7.2.dev41 → assemblyline-4.7.2.dev43}/assemblyline/odm/messages/changes.py +0 -0
- {assemblyline-4.7.2.dev41 → assemblyline-4.7.2.dev43}/assemblyline/odm/messages/dispatcher_heartbeat.py +0 -0
- {assemblyline-4.7.2.dev41 → assemblyline-4.7.2.dev43}/assemblyline/odm/messages/dispatching.py +0 -0
- {assemblyline-4.7.2.dev41 → assemblyline-4.7.2.dev43}/assemblyline/odm/messages/elastic_heartbeat.py +0 -0
- {assemblyline-4.7.2.dev41 → assemblyline-4.7.2.dev43}/assemblyline/odm/messages/expiry_heartbeat.py +0 -0
- {assemblyline-4.7.2.dev41 → assemblyline-4.7.2.dev43}/assemblyline/odm/messages/ingest_heartbeat.py +0 -0
- {assemblyline-4.7.2.dev41 → assemblyline-4.7.2.dev43}/assemblyline/odm/messages/metrics.py +0 -0
- {assemblyline-4.7.2.dev41 → assemblyline-4.7.2.dev43}/assemblyline/odm/messages/retrohunt_heartbeat.py +0 -0
- {assemblyline-4.7.2.dev41 → assemblyline-4.7.2.dev43}/assemblyline/odm/messages/scaler_heartbeat.py +0 -0
- {assemblyline-4.7.2.dev41 → assemblyline-4.7.2.dev43}/assemblyline/odm/messages/scaler_status_heartbeat.py +0 -0
- {assemblyline-4.7.2.dev41 → assemblyline-4.7.2.dev43}/assemblyline/odm/messages/service_heartbeat.py +0 -0
- {assemblyline-4.7.2.dev41 → assemblyline-4.7.2.dev43}/assemblyline/odm/messages/service_timing_heartbeat.py +0 -0
- {assemblyline-4.7.2.dev41 → assemblyline-4.7.2.dev43}/assemblyline/odm/messages/submission.py +0 -0
- {assemblyline-4.7.2.dev41 → assemblyline-4.7.2.dev43}/assemblyline/odm/messages/task.py +0 -0
- {assemblyline-4.7.2.dev41 → assemblyline-4.7.2.dev43}/assemblyline/odm/messages/vacuum_heartbeat.py +0 -0
- {assemblyline-4.7.2.dev41 → assemblyline-4.7.2.dev43}/assemblyline/odm/models/__init__.py +0 -0
- {assemblyline-4.7.2.dev41 → assemblyline-4.7.2.dev43}/assemblyline/odm/models/actions.py +0 -0
- {assemblyline-4.7.2.dev41 → assemblyline-4.7.2.dev43}/assemblyline/odm/models/apikey.py +0 -0
- {assemblyline-4.7.2.dev41 → assemblyline-4.7.2.dev43}/assemblyline/odm/models/badlist.py +0 -0
- {assemblyline-4.7.2.dev41 → assemblyline-4.7.2.dev43}/assemblyline/odm/models/cached_file.py +0 -0
- {assemblyline-4.7.2.dev41 → assemblyline-4.7.2.dev43}/assemblyline/odm/models/emptyresult.py +0 -0
- {assemblyline-4.7.2.dev41 → assemblyline-4.7.2.dev43}/assemblyline/odm/models/error.py +0 -0
- {assemblyline-4.7.2.dev41 → assemblyline-4.7.2.dev43}/assemblyline/odm/models/file.py +0 -0
- {assemblyline-4.7.2.dev41 → assemblyline-4.7.2.dev43}/assemblyline/odm/models/filescore.py +0 -0
- {assemblyline-4.7.2.dev41 → assemblyline-4.7.2.dev43}/assemblyline/odm/models/heuristic.py +0 -0
- {assemblyline-4.7.2.dev41 → assemblyline-4.7.2.dev43}/assemblyline/odm/models/ontology/__init__.py +0 -0
- {assemblyline-4.7.2.dev41 → assemblyline-4.7.2.dev43}/assemblyline/odm/models/ontology/file.py +0 -0
- {assemblyline-4.7.2.dev41 → assemblyline-4.7.2.dev43}/assemblyline/odm/models/ontology/filetypes/__init__.py +0 -0
- {assemblyline-4.7.2.dev41 → assemblyline-4.7.2.dev43}/assemblyline/odm/models/ontology/filetypes/pe.py +0 -0
- {assemblyline-4.7.2.dev41 → assemblyline-4.7.2.dev43}/assemblyline/odm/models/ontology/ontology.py +0 -0
- {assemblyline-4.7.2.dev41 → assemblyline-4.7.2.dev43}/assemblyline/odm/models/ontology/results/__init__.py +0 -0
- {assemblyline-4.7.2.dev41 → assemblyline-4.7.2.dev43}/assemblyline/odm/models/ontology/results/antivirus.py +0 -0
- {assemblyline-4.7.2.dev41 → assemblyline-4.7.2.dev43}/assemblyline/odm/models/ontology/results/http.py +0 -0
- {assemblyline-4.7.2.dev41 → assemblyline-4.7.2.dev43}/assemblyline/odm/models/ontology/results/malware_config.py +0 -0
- {assemblyline-4.7.2.dev41 → assemblyline-4.7.2.dev43}/assemblyline/odm/models/ontology/results/process.py +0 -0
- {assemblyline-4.7.2.dev41 → assemblyline-4.7.2.dev43}/assemblyline/odm/models/ontology/results/sandbox.py +0 -0
- {assemblyline-4.7.2.dev41 → assemblyline-4.7.2.dev43}/assemblyline/odm/models/ontology/results/signature.py +0 -0
- {assemblyline-4.7.2.dev41 → assemblyline-4.7.2.dev43}/assemblyline/odm/models/replay.py +0 -0
- {assemblyline-4.7.2.dev41 → assemblyline-4.7.2.dev43}/assemblyline/odm/models/result.py +0 -0
- {assemblyline-4.7.2.dev41 → assemblyline-4.7.2.dev43}/assemblyline/odm/models/retrohunt.py +0 -0
- {assemblyline-4.7.2.dev41 → assemblyline-4.7.2.dev43}/assemblyline/odm/models/safelist.py +0 -0
- {assemblyline-4.7.2.dev41 → assemblyline-4.7.2.dev43}/assemblyline/odm/models/service.py +0 -0
- {assemblyline-4.7.2.dev41 → assemblyline-4.7.2.dev43}/assemblyline/odm/models/service_delta.py +0 -0
- {assemblyline-4.7.2.dev41 → assemblyline-4.7.2.dev43}/assemblyline/odm/models/signature.py +0 -0
- {assemblyline-4.7.2.dev41 → assemblyline-4.7.2.dev43}/assemblyline/odm/models/statistics.py +0 -0
- {assemblyline-4.7.2.dev41 → assemblyline-4.7.2.dev43}/assemblyline/odm/models/submission.py +0 -0
- {assemblyline-4.7.2.dev41 → assemblyline-4.7.2.dev43}/assemblyline/odm/models/submission_summary.py +0 -0
- {assemblyline-4.7.2.dev41 → assemblyline-4.7.2.dev43}/assemblyline/odm/models/submission_tree.py +0 -0
- {assemblyline-4.7.2.dev41 → assemblyline-4.7.2.dev43}/assemblyline/odm/models/tagging.py +0 -0
- {assemblyline-4.7.2.dev41 → assemblyline-4.7.2.dev43}/assemblyline/odm/models/user_favorites.py +0 -0
- {assemblyline-4.7.2.dev41 → assemblyline-4.7.2.dev43}/assemblyline/odm/models/user_settings.py +0 -0
- {assemblyline-4.7.2.dev41 → assemblyline-4.7.2.dev43}/assemblyline/odm/models/workflow.py +0 -0
- {assemblyline-4.7.2.dev41 → assemblyline-4.7.2.dev43}/assemblyline/odm/random_data/create_test_data.py +0 -0
- {assemblyline-4.7.2.dev41 → assemblyline-4.7.2.dev43}/assemblyline/odm/random_data/sample_rules.yar +0 -0
- {assemblyline-4.7.2.dev41 → assemblyline-4.7.2.dev43}/assemblyline/odm/random_data/sample_suricata.rules +0 -0
- {assemblyline-4.7.2.dev41 → assemblyline-4.7.2.dev43}/assemblyline/odm/randomizer.py +0 -0
- {assemblyline-4.7.2.dev41 → assemblyline-4.7.2.dev43}/assemblyline/py.typed +0 -0
- {assemblyline-4.7.2.dev41 → assemblyline-4.7.2.dev43}/assemblyline/remote/__init__.py +0 -0
- {assemblyline-4.7.2.dev41 → assemblyline-4.7.2.dev43}/assemblyline/remote/datatypes/__init__.py +0 -0
- {assemblyline-4.7.2.dev41 → assemblyline-4.7.2.dev43}/assemblyline/remote/datatypes/cache.py +0 -0
- {assemblyline-4.7.2.dev41 → assemblyline-4.7.2.dev43}/assemblyline/remote/datatypes/counters.py +0 -0
- {assemblyline-4.7.2.dev41 → assemblyline-4.7.2.dev43}/assemblyline/remote/datatypes/daily_quota_tracker.py +0 -0
- {assemblyline-4.7.2.dev41 → assemblyline-4.7.2.dev43}/assemblyline/remote/datatypes/events.py +0 -0
- {assemblyline-4.7.2.dev41 → assemblyline-4.7.2.dev43}/assemblyline/remote/datatypes/lock.py +0 -0
- {assemblyline-4.7.2.dev41 → assemblyline-4.7.2.dev43}/assemblyline/remote/datatypes/queues/__init__.py +0 -0
- {assemblyline-4.7.2.dev41 → assemblyline-4.7.2.dev43}/assemblyline/remote/datatypes/queues/comms.py +0 -0
- {assemblyline-4.7.2.dev41 → assemblyline-4.7.2.dev43}/assemblyline/remote/datatypes/queues/multi.py +0 -0
- {assemblyline-4.7.2.dev41 → assemblyline-4.7.2.dev43}/assemblyline/remote/datatypes/set.py +0 -0
- {assemblyline-4.7.2.dev41 → assemblyline-4.7.2.dev43}/assemblyline/remote/datatypes/user_quota_tracker.py +0 -0
- {assemblyline-4.7.2.dev41 → assemblyline-4.7.2.dev43}/assemblyline/run/__init__.py +0 -0
- {assemblyline-4.7.2.dev41 → assemblyline-4.7.2.dev43}/assemblyline/run/cli.py +0 -0
- {assemblyline-4.7.2.dev41 → assemblyline-4.7.2.dev43}/assemblyline/run/pubsub_reader.py +0 -0
- {assemblyline-4.7.2.dev41 → assemblyline-4.7.2.dev43}/assemblyline/run/suricata_importer.py +0 -0
- {assemblyline-4.7.2.dev41 → assemblyline-4.7.2.dev43}/assemblyline/run/yara_importer.py +0 -0
- {assemblyline-4.7.2.dev41 → assemblyline-4.7.2.dev43}/assemblyline.egg-info/SOURCES.txt +0 -0
- {assemblyline-4.7.2.dev41 → assemblyline-4.7.2.dev43}/assemblyline.egg-info/dependency_links.txt +0 -0
- {assemblyline-4.7.2.dev41 → assemblyline-4.7.2.dev43}/assemblyline.egg-info/entry_points.txt +0 -0
- {assemblyline-4.7.2.dev41 → assemblyline-4.7.2.dev43}/assemblyline.egg-info/requires.txt +0 -0
- {assemblyline-4.7.2.dev41 → assemblyline-4.7.2.dev43}/assemblyline.egg-info/top_level.txt +0 -0
- {assemblyline-4.7.2.dev41 → assemblyline-4.7.2.dev43}/pyproject.toml +0 -0
- {assemblyline-4.7.2.dev41 → assemblyline-4.7.2.dev43}/setup.cfg +0 -0
- {assemblyline-4.7.2.dev41 → assemblyline-4.7.2.dev43}/setup.py +0 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
4.7.2.dev43
|
|
@@ -106,7 +106,7 @@ class DistributedBackup(object):
|
|
|
106
106
|
self.done_queue: NamedQueue[dict[str, Any]] = NamedQueue(f"r-done-{self.instance_id}", ttl=1800)
|
|
107
107
|
self.hash_queue: Hash[str] = Hash(f"r-hash-{self.instance_id}")
|
|
108
108
|
self.bucket_error: list[str] = []
|
|
109
|
-
self.valid_buckets: list[str] = sorted(
|
|
109
|
+
self.valid_buckets: list[str] = sorted(self.datastore.ds.get_models().keys())
|
|
110
110
|
self.worker_count = worker_count
|
|
111
111
|
self.spawn_workers = spawn_workers
|
|
112
112
|
self.total_count = 0
|
|
@@ -187,17 +187,17 @@ class DistributedBackup(object):
|
|
|
187
187
|
for k, v in self.map_count.items():
|
|
188
188
|
summary += "\t%15s: %s\n" % (k.upper(), v)
|
|
189
189
|
|
|
190
|
-
if
|
|
190
|
+
if self.missing_map_count:
|
|
191
191
|
summary += "\n\nMissing data:\n\n"
|
|
192
192
|
for k, v in self.missing_map_count.items():
|
|
193
193
|
summary += "\t%15s: %s\n" % (k.upper(), v)
|
|
194
194
|
|
|
195
|
-
if
|
|
195
|
+
if self.error_map_count:
|
|
196
196
|
summary += "\n\nErrors:\n\n"
|
|
197
197
|
for k, v in self.error_map_count.items():
|
|
198
198
|
summary += "\t%15s: %s\n" % (k.upper(), v)
|
|
199
199
|
|
|
200
|
-
if
|
|
200
|
+
if self.bucket_error:
|
|
201
201
|
summary += f"\nThese buckets failed to {title.lower()} completely: {self.bucket_error}\n"
|
|
202
202
|
if self.logger:
|
|
203
203
|
self.logger.info(summary)
|
|
@@ -330,17 +330,17 @@ def import_bundle(
|
|
|
330
330
|
|
|
331
331
|
# Check if we have all the service results
|
|
332
332
|
for res_key in submission['results']:
|
|
333
|
-
if results is None or (res_key not in results['results']
|
|
333
|
+
if results is None or (res_key not in results['results'] and not allow_incomplete):
|
|
334
334
|
raise IncompleteBundle("Incomplete results in bundle. Skipping %s..." % sid)
|
|
335
335
|
|
|
336
336
|
# Check if we have all files
|
|
337
|
-
for sha256 in list(
|
|
338
|
-
if files is None or (sha256 not in files['infos']
|
|
337
|
+
for sha256 in list({x[:64] for x in submission['results']}):
|
|
338
|
+
if files is None or (sha256 not in files['infos'] and not allow_incomplete):
|
|
339
339
|
raise IncompleteBundle("Incomplete files in bundle. Skipping %s..." % sid)
|
|
340
340
|
|
|
341
341
|
# Check if we all errors
|
|
342
342
|
for err_key in submission['errors']:
|
|
343
|
-
if errors is None or (err_key not in errors['errors']
|
|
343
|
+
if errors is None or (err_key not in errors['errors'] and not allow_incomplete):
|
|
344
344
|
raise IncompleteBundle("Incomplete errors in bundle. Skipping %s..." % sid)
|
|
345
345
|
|
|
346
346
|
# Check if the submission does not already exist
|
|
@@ -258,7 +258,7 @@ class Classification(object):
|
|
|
258
258
|
|
|
259
259
|
if long_format:
|
|
260
260
|
return sorted([self.access_req_map_stl[r] for r in return_set]), unused
|
|
261
|
-
return sorted(
|
|
261
|
+
return sorted(return_set), unused
|
|
262
262
|
|
|
263
263
|
def _get_c12n_groups(self, c12n: list[str], long_format: bool = True, get_dynamic_groups: bool = True,
|
|
264
264
|
auto_select: bool = False) -> Tuple[List, List, list[str]]:
|
|
@@ -276,7 +276,7 @@ class Classification(object):
|
|
|
276
276
|
if gp.startswith("REL "):
|
|
277
277
|
gp = gp.replace("REL TO ", "")
|
|
278
278
|
gp = gp.replace("REL ", "")
|
|
279
|
-
temp_group =
|
|
279
|
+
temp_group = {x.strip() for x in gp.split(",")}
|
|
280
280
|
for t in temp_group:
|
|
281
281
|
groups.extend(t.split("/"))
|
|
282
282
|
else:
|
|
@@ -330,7 +330,7 @@ class Classification(object):
|
|
|
330
330
|
for subgroup in g2_set:
|
|
331
331
|
limited_to_group = self.params_map.get(subgroup, {}).get("limited_to_group", None)
|
|
332
332
|
if limited_to_group is not None:
|
|
333
|
-
if len(g1_set) > 1 or (len(g1_set) == 1 and g1_set !=
|
|
333
|
+
if len(g1_set) > 1 or (len(g1_set) == 1 and g1_set != {limited_to_group}):
|
|
334
334
|
raise InvalidClassification(f"Subgroup {subgroup} is limited to group "
|
|
335
335
|
f"{limited_to_group} (found: {', '.join(g1_set)})")
|
|
336
336
|
|
|
@@ -347,7 +347,7 @@ class Classification(object):
|
|
|
347
347
|
sorted([self.subgroups_map_stl[r] for r in g2_set]),
|
|
348
348
|
list(others)
|
|
349
349
|
)
|
|
350
|
-
return sorted(
|
|
350
|
+
return sorted(g1_set), sorted(g2_set), list(others)
|
|
351
351
|
|
|
352
352
|
@staticmethod
|
|
353
353
|
def _can_see_required(user_req: List, req: List) -> bool:
|
|
@@ -355,14 +355,10 @@ class Classification(object):
|
|
|
355
355
|
|
|
356
356
|
@staticmethod
|
|
357
357
|
def _can_see_groups(user_groups: List, req: List) -> bool:
|
|
358
|
-
if
|
|
358
|
+
if not req:
|
|
359
359
|
return True
|
|
360
360
|
|
|
361
|
-
for g in user_groups
|
|
362
|
-
if g in req:
|
|
363
|
-
return True
|
|
364
|
-
|
|
365
|
-
return False
|
|
361
|
+
return any(g in req for g in user_groups)
|
|
366
362
|
|
|
367
363
|
# noinspection PyTypeChecker
|
|
368
364
|
def _get_normalized_classification_text(self, lvl_idx: int, req: List, groups: List, subgroups: List,
|
|
@@ -391,10 +387,10 @@ class Classification(object):
|
|
|
391
387
|
# 3. Add auto-selected subgroups
|
|
392
388
|
if long_format:
|
|
393
389
|
if len(subgroups) > 0 and len(self.subgroups_auto_select) > 0 and not skip_auto_select:
|
|
394
|
-
subgroups = sorted(
|
|
390
|
+
subgroups = sorted(set(subgroups).union(set(self.subgroups_auto_select)))
|
|
395
391
|
else:
|
|
396
392
|
if len(subgroups) > 0 and len(self.subgroups_auto_select_short) > 0 and not skip_auto_select:
|
|
397
|
-
subgroups = sorted(
|
|
393
|
+
subgroups = sorted(set(subgroups).union(set(self.subgroups_auto_select_short)))
|
|
398
394
|
|
|
399
395
|
# 4. For every subgroup, check if the subgroup requires or is limited to a specific group
|
|
400
396
|
temp_groups = []
|
|
@@ -420,10 +416,10 @@ class Classification(object):
|
|
|
420
416
|
# 5. Add auto-selected groups
|
|
421
417
|
if long_format:
|
|
422
418
|
if len(groups) > 0 and len(self.groups_auto_select) > 0 and not skip_auto_select:
|
|
423
|
-
groups = sorted(
|
|
419
|
+
groups = sorted(set(groups).union(set(self.groups_auto_select)))
|
|
424
420
|
else:
|
|
425
421
|
if len(groups) > 0 and len(self.groups_auto_select_short) > 0 and not skip_auto_select:
|
|
426
|
-
groups = sorted(
|
|
422
|
+
groups = sorted(set(groups).union(set(self.groups_auto_select_short)))
|
|
427
423
|
|
|
428
424
|
if groups:
|
|
429
425
|
groups = sorted(groups)
|
|
@@ -786,9 +782,9 @@ class Classification(object):
|
|
|
786
782
|
|
|
787
783
|
cur_part = parts.pop(0)
|
|
788
784
|
# First parts as to be a classification level part
|
|
789
|
-
if cur_part not in self.levels_aliases
|
|
790
|
-
cur_part not in self.levels_map_lts
|
|
791
|
-
cur_part not in self.levels_map_stl
|
|
785
|
+
if cur_part not in self.levels_aliases and \
|
|
786
|
+
cur_part not in self.levels_map_lts and \
|
|
787
|
+
cur_part not in self.levels_map_stl:
|
|
792
788
|
return False
|
|
793
789
|
|
|
794
790
|
check_groups = False
|
|
@@ -810,19 +806,19 @@ class Classification(object):
|
|
|
810
806
|
for i in items:
|
|
811
807
|
if not check_groups:
|
|
812
808
|
# If current item not found in access req, we might already be dealing with groups
|
|
813
|
-
if i not in self.access_req_aliases
|
|
814
|
-
i not in self.access_req_map_stl
|
|
815
|
-
i not in self.access_req_map_lts
|
|
809
|
+
if i not in self.access_req_aliases and \
|
|
810
|
+
i not in self.access_req_map_stl and \
|
|
811
|
+
i not in self.access_req_map_lts:
|
|
816
812
|
check_groups = True
|
|
817
813
|
|
|
818
814
|
if check_groups and not self.dynamic_groups:
|
|
819
815
|
# If not groups. That stuff does not exists...
|
|
820
|
-
if i not in self.groups_aliases
|
|
821
|
-
i not in self.groups_map_stl
|
|
822
|
-
i not in self.groups_map_lts
|
|
823
|
-
i not in self.subgroups_aliases
|
|
824
|
-
i not in self.subgroups_map_stl
|
|
825
|
-
i not in self.subgroups_map_lts
|
|
816
|
+
if i not in self.groups_aliases and \
|
|
817
|
+
i not in self.groups_map_stl and \
|
|
818
|
+
i not in self.groups_map_lts and \
|
|
819
|
+
i not in self.subgroups_aliases and \
|
|
820
|
+
i not in self.subgroups_map_stl and \
|
|
821
|
+
i not in self.subgroups_map_lts:
|
|
826
822
|
return False
|
|
827
823
|
|
|
828
824
|
return True
|
|
@@ -373,8 +373,8 @@ class Identify:
|
|
|
373
373
|
with open(path, newline='') as csvfile:
|
|
374
374
|
try:
|
|
375
375
|
# Try to read the file as a normal csv without special sniffed dialect
|
|
376
|
-
complete_data =
|
|
377
|
-
if len(complete_data) > 2 and len(
|
|
376
|
+
complete_data = list(islice(csv.reader(csvfile), 100))
|
|
377
|
+
if len(complete_data) > 2 and len({len(x) for x in complete_data}) == 1:
|
|
378
378
|
data["type"] = "text/csv"
|
|
379
379
|
# Final type identified, shortcut further processing
|
|
380
380
|
return data
|
|
@@ -385,8 +385,8 @@ class Identify:
|
|
|
385
385
|
# Normal CSV didn't work, try sniffing the csv to see how we could parse it
|
|
386
386
|
dialect = csv.Sniffer().sniff(csvfile.read(1024))
|
|
387
387
|
csvfile.seek(0)
|
|
388
|
-
complete_data =
|
|
389
|
-
if len(complete_data) > 2 and len(
|
|
388
|
+
complete_data = list(islice(csv.reader(csvfile, dialect), 100))
|
|
389
|
+
if len(complete_data) > 2 and len({len(x) for x in complete_data}) == 1:
|
|
390
390
|
data["type"] = "text/csv"
|
|
391
391
|
# Final type identified, shortcut further processing
|
|
392
392
|
return data
|
|
@@ -463,7 +463,7 @@ def zip_ident(path: str, fallback: str) -> str:
|
|
|
463
463
|
|
|
464
464
|
try:
|
|
465
465
|
with zipfile.ZipFile(path, "r") as zf:
|
|
466
|
-
file_list =
|
|
466
|
+
file_list = list(zf.namelist())
|
|
467
467
|
except Exception:
|
|
468
468
|
try:
|
|
469
469
|
stdout, _ = subprocess.Popen(
|
|
@@ -37,10 +37,7 @@ VALID_UNC_CHARS = [chr(x) for x in ASCII_LOWER_CASE_LETTERS +
|
|
|
37
37
|
def is_unc_legal(path: str) -> bool:
|
|
38
38
|
"""Determine whether or not a given string representing a Windows file path is legal
|
|
39
39
|
or not as per the Unified Naming Convention (UNC) specifications."""
|
|
40
|
-
if
|
|
40
|
+
if not path:
|
|
41
41
|
return False
|
|
42
42
|
|
|
43
|
-
for char in path
|
|
44
|
-
if char not in VALID_UNC_CHARS:
|
|
45
|
-
return False
|
|
46
|
-
return True
|
|
43
|
+
return all(char in VALID_UNC_CHARS for char in path)
|
|
@@ -102,16 +102,10 @@ class AndOperatorNode(NodeInterface):
|
|
|
102
102
|
return f'({" AND ".join(repr(a) for a in self.args)})'
|
|
103
103
|
|
|
104
104
|
def test(self, sub: Submission, score=None, tags: Optional[list[dict[str, Any]]] = None) -> bool:
|
|
105
|
-
for arg in self.args
|
|
106
|
-
if not arg.test(sub, score, tags):
|
|
107
|
-
return False
|
|
108
|
-
return True
|
|
105
|
+
return all(arg.test(sub, score, tags) for arg in self.args)
|
|
109
106
|
|
|
110
107
|
def test_value(self, field, value) -> bool:
|
|
111
|
-
for arg in self.args
|
|
112
|
-
if not arg.test_value(field, value):
|
|
113
|
-
return False
|
|
114
|
-
return True
|
|
108
|
+
return all(arg.test_value(field, value) for arg in self.args)
|
|
115
109
|
|
|
116
110
|
|
|
117
111
|
class OrOperatorNode(NodeInterface):
|
|
@@ -122,16 +116,10 @@ class OrOperatorNode(NodeInterface):
|
|
|
122
116
|
return f'({" OR ".join(repr(a) for a in self.args)})'
|
|
123
117
|
|
|
124
118
|
def test(self, sub: Submission, score=None, tags: Optional[list[dict[str, Any]]] = None) -> bool:
|
|
125
|
-
for arg in self.args
|
|
126
|
-
if arg.test(sub, score, tags):
|
|
127
|
-
return True
|
|
128
|
-
return False
|
|
119
|
+
return any(arg.test(sub, score, tags) for arg in self.args)
|
|
129
120
|
|
|
130
121
|
def test_value(self, field, value) -> bool:
|
|
131
|
-
for arg in self.args
|
|
132
|
-
if arg.test_value(field, value):
|
|
133
|
-
return True
|
|
134
|
-
return False
|
|
122
|
+
return any(arg.test_value(field, value) for arg in self.args)
|
|
135
123
|
|
|
136
124
|
|
|
137
125
|
class NotOperatorNode(NodeInterface):
|
|
@@ -50,7 +50,7 @@ def wrap_bidir_unicode_string(uni_str: Union[str, bytes]) -> Union[str, bytes]:
|
|
|
50
50
|
affecting their left-to-right direction
|
|
51
51
|
"""
|
|
52
52
|
|
|
53
|
-
if
|
|
53
|
+
if not uni_str or isinstance(uni_str, bytes): # Not str, return it unchanged
|
|
54
54
|
return uni_str
|
|
55
55
|
|
|
56
56
|
re_obj = re.search(rf"[{''.join(CONTROL_CHARS)}]", uni_str)
|
|
@@ -243,7 +243,7 @@ class StringTable(object):
|
|
|
243
243
|
|
|
244
244
|
# we also import the list as attributes so things like
|
|
245
245
|
# tab completion and introspection still work.
|
|
246
|
-
for s in self._value_map
|
|
246
|
+
for s in self._value_map:
|
|
247
247
|
setattr(self, s, s)
|
|
248
248
|
|
|
249
249
|
def name_for_value(self, v):
|
|
@@ -9,7 +9,7 @@ from typing import Any, List, Optional, Tuple, Union
|
|
|
9
9
|
import elasticapm
|
|
10
10
|
|
|
11
11
|
from assemblyline.common import forge
|
|
12
|
-
from assemblyline.common.classification import InvalidClassification
|
|
12
|
+
from assemblyline.common.classification import Classification, InvalidClassification
|
|
13
13
|
from assemblyline.common.dict_utils import flatten, recursive_update
|
|
14
14
|
from assemblyline.common.isotime import now_as_iso
|
|
15
15
|
from assemblyline.common.tagging import tag_dict_to_ai_list
|
|
@@ -280,7 +280,9 @@ class AssemblylineDatastore(object):
|
|
|
280
280
|
return self.ds.with_retries(self.ds.client.bulk, operations=operations)
|
|
281
281
|
|
|
282
282
|
@elasticapm.capture_span(span_type='datastore')
|
|
283
|
-
def delete_submission_tree_bulk(
|
|
283
|
+
def delete_submission_tree_bulk(
|
|
284
|
+
self, sid: str, cl_engine: Classification = forge.get_classification(),
|
|
285
|
+
cleanup: bool = True, transport: FileStore | None = None) -> None:
|
|
284
286
|
submission = self.submission.get(sid, as_obj=False)
|
|
285
287
|
params = SubmissionParams(submission['params'])
|
|
286
288
|
if not submission:
|
|
@@ -309,28 +311,30 @@ class AssemblylineDatastore(object):
|
|
|
309
311
|
results = submission["results"]
|
|
310
312
|
files_to_delete = set()
|
|
311
313
|
fix_classification_files = set()
|
|
312
|
-
supp_map = {}
|
|
314
|
+
supp_map: dict[str, set[str]] = {}
|
|
313
315
|
|
|
314
|
-
temp_files =
|
|
315
|
-
temp_files.
|
|
316
|
-
temp_files.
|
|
317
|
-
temp_files = set(temp_files)
|
|
316
|
+
temp_files = {x['sha256'] for x in submission['files']}
|
|
317
|
+
temp_files.update(x[:64] for x in errors)
|
|
318
|
+
temp_files.update(x[:64] for x in results)
|
|
318
319
|
|
|
319
|
-
# Gather all supplementary files
|
|
320
|
-
for result in self.result.search("response.supplementary.sha256:*",
|
|
321
|
-
fl="
|
|
320
|
+
# Gather all supplementary files and extracted files
|
|
321
|
+
for result in self.result.search("response.supplementary.sha256:* OR response.extracted.sha256:*",
|
|
322
|
+
fl="sha256,response.supplementary.sha256,response.extracted.sha256",
|
|
323
|
+
rows=len(results), as_obj=False, key_space=results)['items']:
|
|
322
324
|
sha256 = result['sha256']
|
|
323
|
-
|
|
324
|
-
|
|
325
|
+
if sha256 not in supp_map:
|
|
326
|
+
supp_map[sha256] = set()
|
|
327
|
+
for supp in result['response'].get('supplementary', []):
|
|
325
328
|
supp_map[sha256].add(supp['sha256'])
|
|
329
|
+
for extracted in result['response'].get('extracted', []):
|
|
330
|
+
temp_files.add(extracted['sha256'])
|
|
326
331
|
|
|
327
332
|
# Inspect each files to see if they are reused
|
|
328
333
|
for temp in temp_files:
|
|
329
334
|
# Check if we delete the file or update the classification
|
|
330
335
|
if self.submission.search(f"errors:{temp}* OR results:{temp}*", rows=0, as_obj=False)["total"] < 2:
|
|
331
336
|
files_to_delete.add(temp)
|
|
332
|
-
|
|
333
|
-
files_to_delete = files_to_delete.union(supp_list)
|
|
337
|
+
files_to_delete |= supp_map.pop(temp, set())
|
|
334
338
|
else:
|
|
335
339
|
fix_classification_files.add(temp)
|
|
336
340
|
|
|
@@ -402,8 +406,8 @@ class AssemblylineDatastore(object):
|
|
|
402
406
|
|
|
403
407
|
@elasticapm.capture_span(span_type='datastore')
|
|
404
408
|
def delete_submission_tree(
|
|
405
|
-
self, sid, cl_engine=forge.get_classification(),
|
|
406
|
-
cleanup=True, transport: FileStore = None):
|
|
409
|
+
self, sid: str, cl_engine: Classification = forge.get_classification(),
|
|
410
|
+
cleanup: bool = True, transport: FileStore | None = None) -> None:
|
|
407
411
|
submission = self.submission.get(sid, as_obj=False)
|
|
408
412
|
if not submission:
|
|
409
413
|
return
|
|
@@ -413,27 +417,29 @@ class AssemblylineDatastore(object):
|
|
|
413
417
|
results = submission["results"]
|
|
414
418
|
files_to_delete = set()
|
|
415
419
|
fix_classification_files = set()
|
|
416
|
-
supp_map = {}
|
|
420
|
+
supp_map: dict[str, set[str]] = {}
|
|
417
421
|
|
|
418
|
-
temp_files =
|
|
419
|
-
temp_files.
|
|
420
|
-
temp_files = set(temp_files)
|
|
422
|
+
temp_files = {x[:64] for x in errors}
|
|
423
|
+
temp_files.update(x[:64] for x in results)
|
|
421
424
|
|
|
422
|
-
# Gather all supplementary files
|
|
423
|
-
for result in self.result.search("response.supplementary.sha256:*",
|
|
424
|
-
fl="
|
|
425
|
+
# Gather all supplementary files and extracted files
|
|
426
|
+
for result in self.result.search("response.supplementary.sha256:* OR response.extracted.sha256:*",
|
|
427
|
+
fl="sha256,response.supplementary.sha256,response.extracted.sha256",
|
|
428
|
+
rows=len(results), as_obj=False, key_space=results)['items']:
|
|
425
429
|
sha256 = result['sha256']
|
|
426
|
-
|
|
427
|
-
|
|
430
|
+
if sha256 not in supp_map:
|
|
431
|
+
supp_map[sha256] = set()
|
|
432
|
+
for supp in result['response'].get('supplementary', []):
|
|
428
433
|
supp_map[sha256].add(supp['sha256'])
|
|
434
|
+
for extracted in result['response'].get('extracted', []):
|
|
435
|
+
temp_files.add(extracted['sha256'])
|
|
429
436
|
|
|
430
437
|
# Inspect each files to see if they are reused
|
|
431
438
|
for temp in temp_files:
|
|
432
439
|
# Check if we delete the file or update the classification
|
|
433
|
-
if self.submission.search(f"errors:{temp}* OR results:{temp}*", rows=0, as_obj=False)["total"]
|
|
440
|
+
if self.submission.search(f"NOT sid:{sid} AND (errors:{temp}* OR results:{temp}*)", rows=0, as_obj=False)["total"] == 0:
|
|
434
441
|
files_to_delete.add(temp)
|
|
435
|
-
|
|
436
|
-
files_to_delete = files_to_delete.union(supp_list)
|
|
442
|
+
files_to_delete |= supp_map.pop(temp, set())
|
|
437
443
|
else:
|
|
438
444
|
fix_classification_files.add(temp)
|
|
439
445
|
|
|
@@ -607,7 +613,7 @@ class AssemblylineDatastore(object):
|
|
|
607
613
|
submission = submission.as_primitives()
|
|
608
614
|
|
|
609
615
|
# Get number of files and score
|
|
610
|
-
num_files = len(list(
|
|
616
|
+
num_files = len(list({x[:64] for x in submission['results']}))
|
|
611
617
|
max_score = submission['max_score']
|
|
612
618
|
|
|
613
619
|
# Load / Validate cache tree if exist
|
|
@@ -822,7 +828,7 @@ class AssemblylineDatastore(object):
|
|
|
822
828
|
return out
|
|
823
829
|
|
|
824
830
|
keys = [x for x in list(keys) if not x.endswith(".e")]
|
|
825
|
-
file_keys = list(
|
|
831
|
+
file_keys = list({x[:64] for x in keys})
|
|
826
832
|
try:
|
|
827
833
|
items = self.result.multiget(keys, as_obj=False)
|
|
828
834
|
except MultiKeyError as e:
|
|
@@ -1436,9 +1442,9 @@ class AssemblylineDatastore(object):
|
|
|
1436
1442
|
if min_score:
|
|
1437
1443
|
query += f" AND result.score:>={min_score}"
|
|
1438
1444
|
|
|
1439
|
-
item_list =
|
|
1445
|
+
item_list = list(self.result.stream_search(query, fl="id,created,response.service_name,result.score",
|
|
1440
1446
|
access_control=access_control, as_obj=False,
|
|
1441
|
-
index_type=index_type)
|
|
1447
|
+
index_type=index_type))
|
|
1442
1448
|
|
|
1443
1449
|
item_list.sort(key=lambda k: k["created"], reverse=True)
|
|
1444
1450
|
|
|
@@ -1563,7 +1569,7 @@ class MetadataValidator:
|
|
|
1563
1569
|
|
|
1564
1570
|
# Determine if there's extra metadata being set that isn't validated/known to the system
|
|
1565
1571
|
# Ignore metadata fields that have been set by the system
|
|
1566
|
-
system_configured_metadata =
|
|
1572
|
+
system_configured_metadata = {'ingest_id', 'ts', 'type'}
|
|
1567
1573
|
extra_metadata = list(set(metadata.keys()) - set(validation_scheme.keys()) - system_configured_metadata)
|
|
1568
1574
|
if missing_metadata:
|
|
1569
1575
|
return (None, f"Required metadata is missing from submission: {missing_metadata}")
|
{assemblyline-4.7.2.dev41 → assemblyline-4.7.2.dev43}/assemblyline/datastore/support/build.py
RENAMED
|
@@ -222,10 +222,7 @@ def any_indexed_part(field) -> bool:
|
|
|
222
222
|
elif isinstance(field, Compound):
|
|
223
223
|
if field.index is not None:
|
|
224
224
|
return field.index
|
|
225
|
-
for subfield in field.fields().values()
|
|
226
|
-
if any_indexed_part(subfield):
|
|
227
|
-
return True
|
|
228
|
-
return False
|
|
225
|
+
return any(any_indexed_part(subfield) for subfield in field.fields().values())
|
|
229
226
|
|
|
230
227
|
else:
|
|
231
228
|
return field.index
|
|
@@ -928,7 +928,7 @@ class TypedMapping(dict):
|
|
|
928
928
|
self.store = store
|
|
929
929
|
self.sanitizer = sanitizer
|
|
930
930
|
|
|
931
|
-
for key in items
|
|
931
|
+
for key in items:
|
|
932
932
|
if not self.sanitizer.match(key):
|
|
933
933
|
raise KeyError(f"Illegal key: {key}")
|
|
934
934
|
super().__init__({key: type_p.check(el, ignore_extra_values=ignore_extra_values) for key, el in items.items()})
|
|
@@ -943,7 +943,7 @@ class TypedMapping(dict):
|
|
|
943
943
|
# Update supports three input layouts:
|
|
944
944
|
# 1. A single dictionary
|
|
945
945
|
if len(args) == 1 and isinstance(args[0], dict):
|
|
946
|
-
for key in args[0]
|
|
946
|
+
for key in args[0]:
|
|
947
947
|
if not self.sanitizer.match(key):
|
|
948
948
|
raise KeyError(f"Illegal key: {key}")
|
|
949
949
|
return super().update({key: self.type.check(item) for key, item in args[0].items()})
|
|
@@ -957,7 +957,7 @@ class TypedMapping(dict):
|
|
|
957
957
|
|
|
958
958
|
# 3. Key values as arguments, can be combined with others
|
|
959
959
|
if kwargs:
|
|
960
|
-
for key in kwargs
|
|
960
|
+
for key in kwargs:
|
|
961
961
|
if not self.sanitizer.match(key):
|
|
962
962
|
raise KeyError(f"Illegal key: {key}")
|
|
963
963
|
return super().update({key: self.type.check(item) for key, item in kwargs.items()})
|
|
@@ -80,7 +80,7 @@ class DetailedResults(odm.Model):
|
|
|
80
80
|
yara = odm.List(odm.Compound(DetailedItem), default=[], description="Information on YARA rule matches that contributed to the alert.")
|
|
81
81
|
|
|
82
82
|
def update(self, other: DetailedResults) -> None:
|
|
83
|
-
for field in self.fields()
|
|
83
|
+
for field in self.fields():
|
|
84
84
|
setattr(self, field, list(set(getattr(self, field) + getattr(other, field))))
|
|
85
85
|
|
|
86
86
|
|
|
@@ -1687,6 +1687,7 @@ class UI(odm.Model):
|
|
|
1687
1687
|
api_proxies: APIProxies = odm.Mapping(
|
|
1688
1688
|
odm.Compound(APIProxies),
|
|
1689
1689
|
default=DEFAULT_API_PROXIES, description="Proxy requests to the configured API target and add headers")
|
|
1690
|
+
apikey_cache_seconds = odm.optional(odm.integer(description="Number of seconds to cache apikey validation."))
|
|
1690
1691
|
audit: bool = odm.Boolean(description="Should API calls be audited and saved to a separate log file?")
|
|
1691
1692
|
audit_login: bool = odm.Boolean(description="Should login successes and failures be part of the audit log as well?")
|
|
1692
1693
|
banner: Dict[str, str] = odm.Optional(odm.Mapping(
|
|
@@ -1746,6 +1747,7 @@ DEFAULT_UI = {
|
|
|
1746
1747
|
"allow_replay": False,
|
|
1747
1748
|
"allow_url_submissions": True,
|
|
1748
1749
|
"api_proxies": DEFAULT_API_PROXIES,
|
|
1750
|
+
"apikey_cache_seconds": 5 * 60,
|
|
1749
1751
|
"audit": True,
|
|
1750
1752
|
"audit_login": False,
|
|
1751
1753
|
"banner": None,
|
|
@@ -82,7 +82,7 @@ class NetworkConnection(odm.Model):
|
|
|
82
82
|
# Include any details involved in the request for hashing
|
|
83
83
|
hash_dict['http_details'] = {
|
|
84
84
|
field: http_details.get(field)
|
|
85
|
-
for field in NetworkHTTP.fields()
|
|
85
|
+
for field in NetworkHTTP.fields() if field.startswith('request_')
|
|
86
86
|
}
|
|
87
87
|
elif connection_type == "dns":
|
|
88
88
|
# Include the requested domain as part of the hash
|
|
@@ -200,7 +200,7 @@ def load_roles_form_acls(acls, curRoles):
|
|
|
200
200
|
|
|
201
201
|
# Otherwise load the roles from the api_key ACLs
|
|
202
202
|
roles = set({})
|
|
203
|
-
for acl in ACL_MAP
|
|
203
|
+
for acl in ACL_MAP:
|
|
204
204
|
if acl in acls:
|
|
205
205
|
roles = roles.union(ACL_MAP[acl])
|
|
206
206
|
|
|
@@ -215,7 +215,7 @@ def load_roles(types, curRoles):
|
|
|
215
215
|
|
|
216
216
|
# Otherwise load the roles from the user type
|
|
217
217
|
roles = set({})
|
|
218
|
-
for user_type in USER_TYPE_DEP
|
|
218
|
+
for user_type in USER_TYPE_DEP:
|
|
219
219
|
if user_type in types:
|
|
220
220
|
roles = roles.union(USER_TYPE_DEP[user_type])
|
|
221
221
|
|
{assemblyline-4.7.2.dev41 → assemblyline-4.7.2.dev43}/assemblyline/odm/random_data/__init__.py
RENAMED
|
@@ -73,7 +73,7 @@ def create_alerts(ds, alert_count=50, submission_list=None, log=None, workflows=
|
|
|
73
73
|
# Overwrite with user information
|
|
74
74
|
event.entity_type = 'user'
|
|
75
75
|
event.entity_id = get_random_word()
|
|
76
|
-
event.labels = list(
|
|
76
|
+
event.labels = list({get_random_word() for _ in range(random.randint(0, 20))})
|
|
77
77
|
event.status = random.choice(list(STATUSES) + [None])
|
|
78
78
|
event.priority = random.choice(list(PRIORITIES) + [None])
|
|
79
79
|
return event
|
|
@@ -127,7 +127,7 @@ def create_alerts(ds, alert_count=50, submission_list=None, log=None, workflows=
|
|
|
127
127
|
|
|
128
128
|
|
|
129
129
|
def create_heuristics(ds, log=None):
|
|
130
|
-
for srv in SERVICES
|
|
130
|
+
for srv in SERVICES:
|
|
131
131
|
for x in range(5):
|
|
132
132
|
h = random_model_obj(Heuristic)
|
|
133
133
|
h.heur_id = f"{srv.upper()}.{x + 1}"
|
|
@@ -402,7 +402,7 @@ def create_users(ds, log=None):
|
|
|
402
402
|
user_pass = os.getenv("DEV_USER_PASS", 'user') or 'user'
|
|
403
403
|
|
|
404
404
|
acl = ["R", "W"]
|
|
405
|
-
roles =
|
|
405
|
+
roles = list(load_roles_form_acls(acl, []))
|
|
406
406
|
|
|
407
407
|
user_data = User({
|
|
408
408
|
"agrees_with_tos": "NOW",
|
|
@@ -102,7 +102,7 @@ class AutoExportingCounters(object):
|
|
|
102
102
|
log.debug(f"{pprint.pformat(thread_copy)}")
|
|
103
103
|
|
|
104
104
|
# Only export if needs be
|
|
105
|
-
if self.export_zero or any(
|
|
105
|
+
if self.export_zero or any(isinstance(x, int) and x != 0 for x in thread_copy.values()):
|
|
106
106
|
self.channel.publish(thread_copy)
|
|
107
107
|
|
|
108
108
|
return thread_copy
|
|
@@ -142,7 +142,7 @@ class Hash(Generic[T]):
|
|
|
142
142
|
return retry_call(self.c.hset, self.name, key, json.dumps(value))
|
|
143
143
|
|
|
144
144
|
def multi_set(self, data: dict[str, T]):
|
|
145
|
-
if any(isinstance(key, bytes) for key in data
|
|
145
|
+
if any(isinstance(key, bytes) for key in data):
|
|
146
146
|
raise ValueError("Cannot use bytes for hashmap keys")
|
|
147
147
|
encoded = {key: json.dumps(value) for key, value in data.items()}
|
|
148
148
|
return retry_call(self.c.hset, self.name, mapping=encoded)
|
{assemblyline-4.7.2.dev41 → assemblyline-4.7.2.dev43}/assemblyline/remote/datatypes/queues/named.py
RENAMED
|
@@ -87,7 +87,7 @@ def select(*queues, **kw):
|
|
|
87
87
|
timeout = kw.get('timeout', 0)
|
|
88
88
|
if len(queues) < 1:
|
|
89
89
|
raise TypeError('At least one queue must be specified')
|
|
90
|
-
if any(
|
|
90
|
+
if any(type(q) != NamedQueue for q in queues):
|
|
91
91
|
raise TypeError('Only NamedQueues supported')
|
|
92
92
|
|
|
93
93
|
c = queues[0].c
|
|
@@ -183,7 +183,7 @@ def select(*queues, **kw):
|
|
|
183
183
|
timeout = kw.get('timeout', 0)
|
|
184
184
|
if len(queues) < 1:
|
|
185
185
|
raise TypeError('At least one queue must be specified')
|
|
186
|
-
if any(
|
|
186
|
+
if any(type(q) != PriorityQueue for q in queues):
|
|
187
187
|
raise TypeError('Only NamedQueues supported')
|
|
188
188
|
|
|
189
189
|
c = queues[0].c
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
4.7.2.dev41
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|