From f81ea8960efa1e15c3ea4e0f8242747c0d5e7333 Mon Sep 17 00:00:00 2001 From: Thibaud Cartegnie Date: Tue, 20 Jul 2021 10:38:01 +0200 Subject: [PATCH 1/4] Added support for udp protocol Updated version to 1.2.3 --- darwin/darwinapi.py | 40 ++++++++++++++++++++++++++-------------- setup.py | 2 +- 2 files changed, 27 insertions(+), 15 deletions(-) diff --git a/darwin/darwinapi.py b/darwin/darwinapi.py index eea1e80..8dd9ba9 100644 --- a/darwin/darwinapi.py +++ b/darwin/darwinapi.py @@ -96,6 +96,8 @@ class DarwinApi: 'unix': (socket.AF_UNIX, socket.SOCK_STREAM), 'tcp': (socket.AF_INET, socket.SOCK_STREAM), 'tcp6': (socket.AF_INET6, socket.SOCK_STREAM), + 'udp': (socket.AF_INET, socket.SOCK_DGRAM), + 'udp6': (socket.AF_INET6, socket.SOCK_DGRAM), } @classmethod @@ -149,14 +151,14 @@ def __init__(self, **kwargs): darwin_timeout = self.DEFAULT_TIMEOUT self.socket = None - connection_info = None + self.connection_info = None if socket_type == "unix": - connection_info = kwargs.get("socket_path", None) - if connection_info is None: + self.connection_info = kwargs.get("socket_path", None) + if self.connection_info is None: raise DarwinInvalidArgumentError("DarwinApi:: __init__:: No socket path has been given") if self.verbose: - print("DarwinApi:: __init__:: Connecting to " + str(connection_info) + "...") + print("DarwinApi:: __init__:: Connecting to " + str(self.connection_info) + "...") elif socket_type in self._SOCKET_PROTOCOL: darwin_socket_host = kwargs.get("socket_host", None) @@ -165,7 +167,7 @@ def __init__(self, **kwargs): raise DarwinInvalidArgumentError("DarwinApi:: __init__:: No socket host has been given") if darwin_socket_port is None: raise DarwinInvalidArgumentError("DarwinApi:: __init__:: No socket port has been given") - connection_info = (darwin_socket_host, darwin_socket_port) + self.connection_info = (darwin_socket_host, darwin_socket_port) if self.verbose: print("DarwinApi:: __init__:: Connecting to {darwin_socket_host}: {darwin_socket_port}...".format( darwin_socket_host=darwin_socket_host, @@ -178,7 +180,8 @@ def __init__(self, **kwargs): self.socket = socket.socket(*self._SOCKET_PROTOCOL[socket_type]) self.socket.setblocking(False) self.socket.settimeout(darwin_timeout) - self.socket.connect(connection_info) + if socket_type != "udp": + self.socket.connect(self.connection_info) except socket.error as error: raise DarwinConnectionError(str(error)) @@ -236,6 +239,10 @@ def low_level_call(self, **kwargs): darwin_header_descr["event_id"] = event_id darwin_header = DarwinPacket(verbose=self.verbose, **darwin_header_descr) + if darwin_header.response_type != DarwinPacket.RESPONSE_TYPE["no"] and \ + self.socket.type == socket.SOCK_DGRAM: #udp + raise DarwinInvalidArgumentError('The UDP mode cannot be used with response_type other than \'no\'') + try: darwin_packet_len = ctypes.sizeof(DarwinPacket) + ctypes.sizeof(ctypes.c_uint) * (len(darwin_data) - 1) if self.verbose: @@ -260,9 +267,16 @@ def low_level_call(self, **kwargs): header_descr=darwin_header.get_python_descr() )) - self.socket.sendall(darwin_header) + # in the udp version, we send the header along with the body + if self.socket.type != socket.SOCK_DGRAM: + self.socket.sendall(darwin_header) - if darwin_body is not None: + if darwin_body is None: + if self.verbose: + print("DarwinApi:: low_level_call:: No body provided") + if self.socket.type == socket.SOCK_DGRAM: #udp + self.socket.sendto(darwin_header, self.connection_info) + else: # # This '\n' is added to make sure the packets are correctly forwarded to Darwin with all TCP forwarder. # This addition does not interfere with the json parsing made by Darwin. @@ -276,12 +290,10 @@ def low_level_call(self, **kwargs): print("DarwinApi:: low_level_call:: Sending body \"{darwin_body}\" to Darwin...".format( darwin_body=darwin_body, )) - - self.socket.sendall(darwin_body.encode("utf-8")) - - else: - if self.verbose: - print("DarwinApi:: low_level_call:: No body provided") + if self.socket.type == socket.SOCK_DGRAM: #udp + self.socket.sendto(bytes(darwin_header) + darwin_body.encode("utf-8"), self.connection_info) + else: + self.socket.sendall(darwin_body.encode("utf-8")) if darwin_header.response_type == DarwinPacket.RESPONSE_TYPE["back"] or \ darwin_header.response_type == DarwinPacket.RESPONSE_TYPE["both"]: diff --git a/setup.py b/setup.py index d13574a..597ddcf 100644 --- a/setup.py +++ b/setup.py @@ -2,7 +2,7 @@ setup( name="darwin", - version="1.2.2", + version="1.2.3", description="Call Darwin with your Python code!", url="https://github.com/VultureProject/darwin-client-python", author="Guillaume Catto", From e48adcdde4d67ec05919a07fe0fb833a008c57e2 Mon Sep 17 00:00:00 2001 From: Thibaud Cartegnie Date: Tue, 27 Jul 2021 16:36:51 +0200 Subject: [PATCH 2/4] Fixed issue when sending udp packet: Api did not accept sending to next filter as it should --- darwin/darwinapi.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/darwin/darwinapi.py b/darwin/darwinapi.py index 8dd9ba9..b06242f 100644 --- a/darwin/darwinapi.py +++ b/darwin/darwinapi.py @@ -239,9 +239,9 @@ def low_level_call(self, **kwargs): darwin_header_descr["event_id"] = event_id darwin_header = DarwinPacket(verbose=self.verbose, **darwin_header_descr) - if darwin_header.response_type != DarwinPacket.RESPONSE_TYPE["no"] and \ + if darwin_header.response_type not in [DarwinPacket.RESPONSE_TYPE["no"], DarwinPacket.RESPONSE_TYPE["darwin"]] and \ self.socket.type == socket.SOCK_DGRAM: #udp - raise DarwinInvalidArgumentError('The UDP mode cannot be used with response_type other than \'no\'') + raise DarwinInvalidArgumentError('The UDP mode cannot be used with response_type other than \'no\' or \'darwin\'') try: darwin_packet_len = ctypes.sizeof(DarwinPacket) + ctypes.sizeof(ctypes.c_uint) * (len(darwin_data) - 1) From bb79cd6506723002abb4224aa6deaa3a89ea3a49 Mon Sep 17 00:00:00 2001 From: Thibaud Cartegnie Date: Wed, 28 Jul 2021 18:02:06 +0200 Subject: [PATCH 3/4] Set default cert size to 0 --- darwin/darwinprotocol.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/darwin/darwinprotocol.py b/darwin/darwinprotocol.py index cbeec12..bc53405 100644 --- a/darwin/darwinprotocol.py +++ b/darwin/darwinprotocol.py @@ -63,7 +63,7 @@ class DarwinPacket(ctypes.Structure): """ DARWIN_FILTER_CODE_NO = 0x00000000 - DEFAULT_CERTITUDE_LIST_SIZE = 1 + DEFAULT_CERTITUDE_LIST_SIZE = 0 DEFAULT_MAX_CERTITUDE_SIZE = 10000 RESPONSE_TYPE = { @@ -77,7 +77,7 @@ class DarwinPacket(ctypes.Structure): "other": 0, "filter": 1, } - + _pack_ = 1 _fields_ = [("packet_type", ctypes.c_int), ("response_type", ctypes.c_int), ("filter_code", ctypes.c_long), From 78662e9bf770cbb2a6336f8c019c8189a61a6387 Mon Sep 17 00:00:00 2001 From: Thibaud Cartegnie Date: Fri, 30 Jul 2021 11:37:26 +0200 Subject: [PATCH 4/4] Fixed issue when using UDP with ipv6 on freeBSD --- darwin/darwinapi.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/darwin/darwinapi.py b/darwin/darwinapi.py index b06242f..b39dfda 100644 --- a/darwin/darwinapi.py +++ b/darwin/darwinapi.py @@ -180,7 +180,7 @@ def __init__(self, **kwargs): self.socket = socket.socket(*self._SOCKET_PROTOCOL[socket_type]) self.socket.setblocking(False) self.socket.settimeout(darwin_timeout) - if socket_type != "udp": + if not socket_type.startswith("udp"): self.socket.connect(self.connection_info) except socket.error as error: raise DarwinConnectionError(str(error))