Skip to content

Commit 0eb334c

Browse files
nbargnesirkoumis
authored andcommitted
implement some APIs in the mongodb backend
1 parent 71aa3a3 commit 0eb334c

File tree

2 files changed

+80
-6
lines changed

2 files changed

+80
-6
lines changed

lib/cuckoo/core/reporting/__init__.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77

88
class Backend(enum.Enum):
99
MONGODB = enum.auto()
10-
ELASTICSEARCH = enum.auto
10+
ELASTICSEARCH = enum.auto()
1111
NONE = enum.auto()
1212

1313

lib/cuckoo/core/reporting/backends/mongodb.py

Lines changed: 79 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,39 @@
1+
import logging
2+
3+
import pymongo
4+
import pymongo.collection
5+
import pymongo.database
6+
import pymongo.results
7+
18
from lib.cuckoo.common import config
9+
from lib.cuckoo.common.exceptions import CuckooOperationalError
210
from lib.cuckoo.core.reporting import api
311

12+
log = logging.getLogger(__name__)
13+
414

515
class MongoDBReports(api.Reports):
616
def __init__(self, cfg: config.Config):
7-
pass
17+
if not hasattr(cfg, "mongodb"):
18+
raise CuckooOperationalError("mongodb must be configured")
19+
mongodb_cfg: dict = cfg.mongodb
20+
21+
self._client: pymongo.MongoClient = _pymongo_client(mongodb_cfg)
22+
dbname = mongodb_cfg.get("db", "cuckoo")
23+
self._database: pymongo.database.Database = self._client[dbname]
24+
self._reports: pymongo.collection.Collection = self._database[_analysis_coll]
25+
26+
_init_pymongo_logging(mongodb_cfg)
827

928
def get(self, task_id: int) -> dict:
10-
pass
29+
query = {_info_id: task_id}
30+
report = self._reports.find_one(filter=query)
31+
return {} if not report else report
1132

1233
def delete(self, task_id: int) -> bool:
13-
pass
34+
query = {_info_id: task_id}
35+
rslt: pymongo.results.DeleteResult = self._reports.delete_one(filter=query)
36+
return True if rslt.deleted_count > 0 else False
1437

1538
def search(self, term, value, limit=False, projection=None) -> list:
1639
pass
@@ -28,10 +51,61 @@ def detections_by_sha256(self, sha256: str) -> dict:
2851
pass
2952

3053
def iocs(self, task_id: int) -> dict:
31-
pass
54+
# there's no well-defined representation of iocs data yet; defer to full get
55+
return self.get(task_id)
3256

3357
def summary(self, task_id: int) -> dict:
34-
pass
58+
query = {_info_id: task_id}
59+
projection = {
60+
_id: 0,
61+
_info: 1,
62+
"target.file.virustotal.summary": 1,
63+
"url.virustotal.summary": 1,
64+
"malscore": 1,
65+
"detections": 1,
66+
"network.pcap_sha256": 1,
67+
"mlist_cnt": 1,
68+
"f_mlist_cnt": 1,
69+
"target.file.clamav": 1,
70+
"suri_tls_cnt": 1,
71+
"suri_alert_cnt": 1,
72+
"suri_http_cnt": 1,
73+
"suri_file_cnt": 1,
74+
"trid": 1,
75+
}
76+
report = self._reports.find_one(filter=query, projection=projection)
77+
return {} if not report else report
3578

3679
def recent_suricata_alerts(self, minutes=60) -> list:
3780
pass
81+
82+
83+
# Temporarily duped with mongodb_constants
84+
_analysis_coll = "analysis"
85+
_calls_coll = "calls"
86+
_cuckoo_coll = "cuckoo_schema"
87+
_files_coll = "files"
88+
_file_key = "sha256"
89+
_id = "_id"
90+
_info = "info"
91+
_info_id = "info.id"
92+
_target = "target"
93+
_task_ids_key = "_task_ids"
94+
_version = "version"
95+
96+
97+
def _pymongo_client(cfg: dict) -> pymongo.MongoClient:
98+
return pymongo.MongoClient(
99+
host=cfg.get("host", "127.0.0.1"),
100+
port=cfg.get("port", 27017),
101+
username=cfg.get("username"),
102+
password=cfg.get("password"),
103+
authSource=cfg.get("authsource", "cuckoo"),
104+
tlsCAFile=cfg.get("tlscafile", None),
105+
)
106+
107+
108+
def _init_pymongo_logging(cfg: dict) -> None:
109+
mongodb_log_level = cfg.get("log_level", "ERROR")
110+
level = logging.getLevelName(mongodb_log_level.upper())
111+
logging.getLogger("pymongo").setLevel(level)

0 commit comments

Comments
 (0)