Skip to content

Commit

Permalink
Add username and password options to MQTT loader (#732)
Browse files Browse the repository at this point in the history
(DIS-3240)
  • Loading branch information
cecinestpasunepipe committed Jul 1, 2024
1 parent e6a457a commit 64db578
Show file tree
Hide file tree
Showing 2 changed files with 15 additions and 2 deletions.
15 changes: 14 additions & 1 deletion dissect/target/loaders/mqtt.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
import urllib
from dataclasses import dataclass
from functools import lru_cache
from getpass import getpass
from pathlib import Path
from struct import pack, unpack_from
from threading import Thread
Expand Down Expand Up @@ -270,19 +271,25 @@ class Broker:
case = None
bytes_received = 0
monitor = False
username = None
password = None

diskinfo = {}
index = {}
topo = {}
factor = 1

def __init__(self, broker: Broker, port: str, key: str, crt: str, ca: str, case: str, **kwargs):
def __init__(
self, broker: Broker, port: str, key: str, crt: str, ca: str, case: str, username: str, password: str, **kwargs
):
self.broker_host = broker
self.broker_port = int(port)
self.private_key_file = key
self.certificate_file = crt
self.cacert_file = ca
self.case = case
self.username = username
self.password = password
self.command = kwargs.get("command", None)

def clear_cache(self) -> None:
Expand Down Expand Up @@ -393,6 +400,7 @@ def connect(self) -> None:
tls_version=ssl.PROTOCOL_TLS,
ciphers=None,
)
self.mqtt_client.username_pw_set(self.username, self.password)
self.mqtt_client.tls_insecure_set(True) # merely having the correct cert is ok
self.mqtt_client.on_connect = self._on_connect
self.mqtt_client.on_message = self._on_message
Expand All @@ -411,6 +419,8 @@ def connect(self) -> None:
@arg("--mqtt-ca", dest="ca", help="certificate authority file")
@arg("--mqtt-command", dest="command", help="direct command to client(s)")
@arg("--mqtt-diag", action="store_true", dest="diag", help="show MQTT diagnostic information")
@arg("--mqtt-username", dest="username", help="Username for connection")
@arg("--mqtt-password", action="store_true", dest="password", help="Ask for password before connecting")
class MQTTLoader(Loader):
"""Load remote targets through a broker."""

Expand All @@ -435,7 +445,10 @@ def find_all(path: Path, **kwargs) -> Iterator[str]:
if cls.broker is None:
if (uri := kwargs.get("parsed_path")) is None:
raise LoaderError("No URI connection details have been passed.")

options = dict(urllib.parse.parse_qsl(uri.query, keep_blank_values=True))
if options.get("password"):
options["password"] = getpass()
cls.broker = Broker(**options)
cls.broker.connect()
num_peers = int(options.get("peers", 1))
Expand Down
2 changes: 1 addition & 1 deletion tests/loaders/test_mqtt.py
Original file line number Diff line number Diff line change
Expand Up @@ -114,7 +114,7 @@ def test_remote_loader_stream(
) -> None:
from dissect.target.loaders.mqtt import Broker

broker = Broker("0.0.0.0", "1884", "key", "crt", "ca", "case1")
broker = Broker("0.0.0.0", "1884", "key", "crt", "ca", "case1", "user", "pass")
broker.connect()
broker.mqtt_client.fill_disks(disks)
broker.mqtt_client.hostnames = hosts
Expand Down

0 comments on commit 64db578

Please sign in to comment.