We are currently solving the following issue within our repository. Here is the issue text:
--- BEGIN ISSUE ---
HPFeeds3 UnicodeDecodeError in ttylog.read().encode().hex()
**Describe the bug**
Stack Trace from the cowrie version v2.3.0, as already described in #1307 

```
cowrie           | 2022-01-23T14:52:17+0000 [twisted.logger._observer#critical] Temporarily disabling observer LegacyLogObserverWrapper(<bound method Output.emit of <cowrie.output.hpfeeds3.Output object at 0x7f4019656490>>) due to exception: [Failure instance: Traceback: <class 'UnicodeDecodeError'>: 'utf-8' codec can't decode byte 0x88 in position 16: invalid start byte
cowrie           | 	/home/cowrie/cowrie/src/cowrie/insults/insults.py:226:connectionLost
cowrie           | 	/usr/lib/python3.9/site-packages/twisted/python/threadable.py:51:sync
cowrie           | 	/usr/lib/python3.9/site-packages/twisted/python/log.py:281:msg
cowrie           | 	/usr/lib/python3.9/site-packages/twisted/logger/_legacy.py:147:publishToNewObserver
cowrie           | 	--- <exception caught here> ---
cowrie           | 	/usr/lib/python3.9/site-packages/twisted/logger/_observer.py:82:__call__
cowrie           | 	/usr/lib/python3.9/site-packages/twisted/logger/_legacy.py:90:__call__
cowrie           | 	/home/cowrie/cowrie/src/cowrie/core/output.py:240:emit
cowrie           | 	/home/cowrie/cowrie/src/cowrie/output/hpfeeds3.py:110:write
cowrie           | 	/usr/lib/python3.9/codecs.py:322:decode
cowrie           | 	]
cowrie           | 	Traceback (most recent call last):
cowrie           | 	  File "/home/cowrie/cowrie/src/cowrie/insults/insults.py", line 226, in connectionLost
cowrie           | 	    log.msg(
cowrie           | 	  File "/usr/lib/python3.9/site-packages/twisted/python/threadable.py", line 51, in sync
cowrie           | 	    return function(self, *args, **kwargs)
cowrie           | 	  File "/usr/lib/python3.9/site-packages/twisted/python/log.py", line 281, in msg
cowrie           | 	    _publishNew(self._publishPublisher, actualEventDict, textFromEventDict)
cowrie           | 	  File "/usr/lib/python3.9/site-packages/twisted/logger/_legacy.py", line 147, in publishToNewObserver
cowrie           | 	    observer(eventDict)
cowrie           | 	--- <exception caught here> ---
cowrie           | 	  File "/usr/lib/python3.9/site-packages/twisted/logger/_observer.py", line 82, in __call__
cowrie           | 	    observer(event)
cowrie           | 	  File "/usr/lib/python3.9/site-packages/twisted/logger/_legacy.py", line 90, in __call__
cowrie           | 	    self.legacyObserver(event)
cowrie           | 	  File "/home/cowrie/cowrie/src/cowrie/core/output.py", line 240, in emit
cowrie           | 	    self.write(ev)
cowrie           | 	  File "/home/cowrie/cowrie/src/cowrie/output/hpfeeds3.py", line 110, in write
cowrie           | 	    self.meta[session]["ttylog"] = ttylog.read().encode().hex()
cowrie           | 	  File "/usr/lib/python3.9/codecs.py", line 322, in decode
cowrie           | 	    (result, consumed) = self._buffer_decode(data, self.errors, final)
cowrie           | 	builtins.UnicodeDecodeError: 'utf-8' codec can't decode byte 0x88 in position 16: invalid start byte
```

**Server (please complete the following information):**
 - OS: Alpine Linux in Docker
 - Python: Python 3.9

**Additional context**
The ttylog seems to be a binary file with only parts of it being text. 

At the moment the file is opened as a text file, then encoded to utf-8 bytes and then to a hex representation. Opening it as a binary file and directly transforming it to a hex reprenstation should fix it.
HPFeeds3 UnicodeDecodeError in ttylog.read().encode().hex()
**Describe the bug**
Stack Trace from the cowrie version v2.3.0, as already described in #1307 

```
cowrie           | 2022-01-23T14:52:17+0000 [twisted.logger._observer#critical] Temporarily disabling observer LegacyLogObserverWrapper(<bound method Output.emit of <cowrie.output.hpfeeds3.Output object at 0x7f4019656490>>) due to exception: [Failure instance: Traceback: <class 'UnicodeDecodeError'>: 'utf-8' codec can't decode byte 0x88 in position 16: invalid start byte
cowrie           | 	/home/cowrie/cowrie/src/cowrie/insults/insults.py:226:connectionLost
cowrie           | 	/usr/lib/python3.9/site-packages/twisted/python/threadable.py:51:sync
cowrie           | 	/usr/lib/python3.9/site-packages/twisted/python/log.py:281:msg
cowrie           | 	/usr/lib/python3.9/site-packages/twisted/logger/_legacy.py:147:publishToNewObserver
cowrie           | 	--- <exception caught here> ---
cowrie           | 	/usr/lib/python3.9/site-packages/twisted/logger/_observer.py:82:__call__
cowrie           | 	/usr/lib/python3.9/site-packages/twisted/logger/_legacy.py:90:__call__
cowrie           | 	/home/cowrie/cowrie/src/cowrie/core/output.py:240:emit
cowrie           | 	/home/cowrie/cowrie/src/cowrie/output/hpfeeds3.py:110:write
cowrie           | 	/usr/lib/python3.9/codecs.py:322:decode
cowrie           | 	]
cowrie           | 	Traceback (most recent call last):
cowrie           | 	  File "/home/cowrie/cowrie/src/cowrie/insults/insults.py", line 226, in connectionLost
cowrie           | 	    log.msg(
cowrie           | 	  File "/usr/lib/python3.9/site-packages/twisted/python/threadable.py", line 51, in sync
cowrie           | 	    return function(self, *args, **kwargs)
cowrie           | 	  File "/usr/lib/python3.9/site-packages/twisted/python/log.py", line 281, in msg
cowrie           | 	    _publishNew(self._publishPublisher, actualEventDict, textFromEventDict)
cowrie           | 	  File "/usr/lib/python3.9/site-packages/twisted/logger/_legacy.py", line 147, in publishToNewObserver
cowrie           | 	    observer(eventDict)
cowrie           | 	--- <exception caught here> ---
cowrie           | 	  File "/usr/lib/python3.9/site-packages/twisted/logger/_observer.py", line 82, in __call__
cowrie           | 	    observer(event)
cowrie           | 	  File "/usr/lib/python3.9/site-packages/twisted/logger/_legacy.py", line 90, in __call__
cowrie           | 	    self.legacyObserver(event)
cowrie           | 	  File "/home/cowrie/cowrie/src/cowrie/core/output.py", line 240, in emit
cowrie           | 	    self.write(ev)
cowrie           | 	  File "/home/cowrie/cowrie/src/cowrie/output/hpfeeds3.py", line 110, in write
cowrie           | 	    self.meta[session]["ttylog"] = ttylog.read().encode().hex()
cowrie           | 	  File "/usr/lib/python3.9/codecs.py", line 322, in decode
cowrie           | 	    (result, consumed) = self._buffer_decode(data, self.errors, final)
cowrie           | 	builtins.UnicodeDecodeError: 'utf-8' codec can't decode byte 0x88 in position 16: invalid start byte
```

**Server (please complete the following information):**
 - OS: Alpine Linux in Docker
 - Python: Python 3.9

**Additional context**
The ttylog seems to be a binary file with only parts of it being text. 

At the moment the file is opened as a text file, then encoded to utf-8 bytes and then to a hex representation. Opening it as a binary file and directly transforming it to a hex reprenstation should fix it.

--- END ISSUE ---

Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
--- BEGIN FILES ---
Path: `src/cowrie/output/hpfeeds3.py`
Content:
```
1 """
2 Output plugin for HPFeeds
3 """
4 
5 from __future__ import annotations
6 
7 import json
8 import logging
9 
10 from hpfeeds.twisted import ClientSessionService
11 
12 from twisted.internet import endpoints, ssl
13 from twisted.internet import reactor  # type: ignore
14 from twisted.python import log
15 
16 import cowrie.core.output
17 from cowrie.core.config import CowrieConfig
18 
19 
20 class Output(cowrie.core.output.Output):
21     """
22     Output plugin for HPFeeds
23     """
24 
25     channel = "cowrie.sessions"
26 
27     def start(self):
28         if CowrieConfig.has_option("output_hpfeeds3", "channel"):
29             self.channel = CowrieConfig.get("output_hpfeeds3", "channel")
30 
31         if CowrieConfig.has_option("output_hpfeeds3", "endpoint"):
32             endpoint = CowrieConfig.get("output_hpfeeds3", "endpoint")
33         else:
34             server = CowrieConfig.get("output_hpfeeds3", "server")
35             port = CowrieConfig.getint("output_hpfeeds3", "port")
36 
37             if CowrieConfig.has_option("output_hpfeeds3", "tlscert"):
38                 with open(CowrieConfig.get("output_hpfeeds3", "tlscert")) as fp:
39                     authority = ssl.Certificate.loadPEM(fp.read())
40                 options = ssl.optionsForClientTLS(server, authority)
41                 endpoint = endpoints.SSL4ClientEndpoint(reactor, server, port, options)
42             else:
43                 endpoint = endpoints.HostnameEndpoint(reactor, server, port)
44 
45         ident = CowrieConfig.get("output_hpfeeds3", "identifier")
46         secret = CowrieConfig.get("output_hpfeeds3", "secret")
47 
48         self.meta = {}
49 
50         self.client = ClientSessionService(endpoint, ident, secret)
51         self.client.startService()
52 
53     def stop(self):
54         self.client.stopService()
55 
56     def write(self, entry):
57         session = entry["session"]
58         if entry["eventid"] == "cowrie.session.connect":
59             self.meta[session] = {
60                 "session": session,
61                 "startTime": entry["timestamp"],
62                 "endTime": "",
63                 "peerIP": entry["src_ip"],
64                 "peerPort": entry["src_port"],
65                 "hostIP": entry["dst_ip"],
66                 "hostPort": entry["dst_port"],
67                 "loggedin": None,
68                 "credentials": [],
69                 "commands": [],
70                 "unknownCommands": [],
71                 "urls": [],
72                 "version": None,
73                 "ttylog": None,
74                 "hashes": set(),
75                 "protocol": entry["protocol"],
76             }
77 
78         elif entry["eventid"] == "cowrie.login.success":
79             u, p = entry["username"], entry["password"]
80             self.meta[session]["loggedin"] = (u, p)
81 
82         elif entry["eventid"] == "cowrie.login.failed":
83             u, p = entry["username"], entry["password"]
84             self.meta[session]["credentials"].append((u, p))
85 
86         elif entry["eventid"] == "cowrie.command.input":
87             c = entry["input"]
88             self.meta[session]["commands"].append(c)
89 
90         elif entry["eventid"] == "cowrie.command.failed":
91             uc = entry["input"]
92             self.meta[session]["unknownCommands"].append(uc)
93 
94         elif entry["eventid"] == "cowrie.session.file_download":
95             if "url" in entry:
96                 url = entry["url"]
97                 self.meta[session]["urls"].append(url)
98             self.meta[session]["hashes"].add(entry["shasum"])
99 
100         elif entry["eventid"] == "cowrie.session.file_upload":
101             self.meta[session]["hashes"].add(entry["shasum"])
102 
103         elif entry["eventid"] == "cowrie.client.version":
104             v = entry["version"]
105             self.meta[session]["version"] = v
106 
107         elif entry["eventid"] == "cowrie.log.closed":
108             # entry["ttylog"]
109             with open(entry["ttylog"]) as ttylog:
110                 self.meta[session]["ttylog"] = ttylog.read().encode().hex()
111 
112         elif entry["eventid"] == "cowrie.session.closed":
113             meta = self.meta.pop(session, None)
114             if meta:
115                 log.msg("publishing metadata to hpfeeds", logLevel=logging.DEBUG)
116                 meta["endTime"] = entry["timestamp"]
117                 meta["hashes"] = list(meta["hashes"])
118                 self.client.publish(self.channel, json.dumps(meta).encode("utf-8"))
119
```
--- END FILES ---

Please first localize the bug based on the issue statement, and then generate a patch according to the `git diff` format fenced by three backticks.

Here is an example:

```diff
diff --git a/examples/server_async.py b/examples/server_async.py
--- a/examples/server_async.py
+++ b/examples/server_async.py
@@ -313,4 +313,4 @@
 
 
 if __name__ == "__main__":
-    asyncio.run(run_async_server("."), debug=True)
+    asyncio.run(run_async_server(), debug=True)
diff --git a/examples/server_sync.py b/examples/server_sync.py
--- a/examples/server_sync.py
+++ b/examples/server_sync.py
@@ -313,5 +313,5 @@
 
 
 if __name__ == "__main__":
-    server = run_sync_server(".")
+    server = run_sync_server()
     server.shutdown()

```

diff --git a/src/cowrie/output/hpfeeds3.py b/src/cowrie/output/hpfeeds3.py
--- a/src/cowrie/output/hpfeeds3.py
+++ b/src/cowrie/output/hpfeeds3.py
@@ -106,8 +106,8 @@
 
         elif entry["eventid"] == "cowrie.log.closed":
             # entry["ttylog"]
-            with open(entry["ttylog"]) as ttylog:
-                self.meta[session]["ttylog"] = ttylog.read().encode().hex()
+            with open(entry["ttylog"], 'rb') as ttylog:
+                self.meta[session]["ttylog"] = ttylog.read().hex()
 
         elif entry["eventid"] == "cowrie.session.closed":
             meta = self.meta.pop(session, None)

{"golden_diff": "diff --git a/src/cowrie/output/hpfeeds3.py b/src/cowrie/output/hpfeeds3.py\n--- a/src/cowrie/output/hpfeeds3.py\n+++ b/src/cowrie/output/hpfeeds3.py\n@@ -106,8 +106,8 @@\n \n         elif entry[\"eventid\"] == \"cowrie.log.closed\":\n             # entry[\"ttylog\"]\n-            with open(entry[\"ttylog\"]) as ttylog:\n-                self.meta[session][\"ttylog\"] = ttylog.read().encode().hex()\n+            with open(entry[\"ttylog\"], 'rb') as ttylog:\n+                self.meta[session][\"ttylog\"] = ttylog.read().hex()\n \n         elif entry[\"eventid\"] == \"cowrie.session.closed\":\n             meta = self.meta.pop(session, None)\n", "issue": "HPFeeds3 UnicodeDecodeError in ttylog.read().encode().hex()\n**Describe the bug**\r\nStack Trace from the cowrie version v2.3.0, as already described in #1307 \r\n\r\n```\r\ncowrie           | 2022-01-23T14:52:17+0000 [twisted.logger._observer#critical] Temporarily disabling observer LegacyLogObserverWrapper(<bound method Output.emit of <cowrie.output.hpfeeds3.Output object at 0x7f4019656490>>) due to exception: [Failure instance: Traceback: <class 'UnicodeDecodeError'>: 'utf-8' codec can't decode byte 0x88 in position 16: invalid start byte\r\ncowrie           | \t/home/cowrie/cowrie/src/cowrie/insults/insults.py:226:connectionLost\r\ncowrie           | \t/usr/lib/python3.9/site-packages/twisted/python/threadable.py:51:sync\r\ncowrie           | \t/usr/lib/python3.9/site-packages/twisted/python/log.py:281:msg\r\ncowrie           | \t/usr/lib/python3.9/site-packages/twisted/logger/_legacy.py:147:publishToNewObserver\r\ncowrie           | \t--- <exception caught here> ---\r\ncowrie           | \t/usr/lib/python3.9/site-packages/twisted/logger/_observer.py:82:__call__\r\ncowrie           | \t/usr/lib/python3.9/site-packages/twisted/logger/_legacy.py:90:__call__\r\ncowrie           | \t/home/cowrie/cowrie/src/cowrie/core/output.py:240:emit\r\ncowrie           | \t/home/cowrie/cowrie/src/cowrie/output/hpfeeds3.py:110:write\r\ncowrie           | \t/usr/lib/python3.9/codecs.py:322:decode\r\ncowrie           | \t]\r\ncowrie           | \tTraceback (most recent call last):\r\ncowrie           | \t  File \"/home/cowrie/cowrie/src/cowrie/insults/insults.py\", line 226, in connectionLost\r\ncowrie           | \t    log.msg(\r\ncowrie           | \t  File \"/usr/lib/python3.9/site-packages/twisted/python/threadable.py\", line 51, in sync\r\ncowrie           | \t    return function(self, *args, **kwargs)\r\ncowrie           | \t  File \"/usr/lib/python3.9/site-packages/twisted/python/log.py\", line 281, in msg\r\ncowrie           | \t    _publishNew(self._publishPublisher, actualEventDict, textFromEventDict)\r\ncowrie           | \t  File \"/usr/lib/python3.9/site-packages/twisted/logger/_legacy.py\", line 147, in publishToNewObserver\r\ncowrie           | \t    observer(eventDict)\r\ncowrie           | \t--- <exception caught here> ---\r\ncowrie           | \t  File \"/usr/lib/python3.9/site-packages/twisted/logger/_observer.py\", line 82, in __call__\r\ncowrie           | \t    observer(event)\r\ncowrie           | \t  File \"/usr/lib/python3.9/site-packages/twisted/logger/_legacy.py\", line 90, in __call__\r\ncowrie           | \t    self.legacyObserver(event)\r\ncowrie           | \t  File \"/home/cowrie/cowrie/src/cowrie/core/output.py\", line 240, in emit\r\ncowrie           | \t    self.write(ev)\r\ncowrie           | \t  File \"/home/cowrie/cowrie/src/cowrie/output/hpfeeds3.py\", line 110, in write\r\ncowrie           | \t    self.meta[session][\"ttylog\"] = ttylog.read().encode().hex()\r\ncowrie           | \t  File \"/usr/lib/python3.9/codecs.py\", line 322, in decode\r\ncowrie           | \t    (result, consumed) = self._buffer_decode(data, self.errors, final)\r\ncowrie           | \tbuiltins.UnicodeDecodeError: 'utf-8' codec can't decode byte 0x88 in position 16: invalid start byte\r\n```\r\n\r\n**Server (please complete the following information):**\r\n - OS: Alpine Linux in Docker\r\n - Python: Python 3.9\r\n\r\n**Additional context**\r\nThe ttylog seems to be a binary file with only parts of it being text. \r\n\r\nAt the moment the file is opened as a text file, then encoded to utf-8 bytes and then to a hex representation. Opening it as a binary file and directly transforming it to a hex reprenstation should fix it.\nHPFeeds3 UnicodeDecodeError in ttylog.read().encode().hex()\n**Describe the bug**\r\nStack Trace from the cowrie version v2.3.0, as already described in #1307 \r\n\r\n```\r\ncowrie           | 2022-01-23T14:52:17+0000 [twisted.logger._observer#critical] Temporarily disabling observer LegacyLogObserverWrapper(<bound method Output.emit of <cowrie.output.hpfeeds3.Output object at 0x7f4019656490>>) due to exception: [Failure instance: Traceback: <class 'UnicodeDecodeError'>: 'utf-8' codec can't decode byte 0x88 in position 16: invalid start byte\r\ncowrie           | \t/home/cowrie/cowrie/src/cowrie/insults/insults.py:226:connectionLost\r\ncowrie           | \t/usr/lib/python3.9/site-packages/twisted/python/threadable.py:51:sync\r\ncowrie           | \t/usr/lib/python3.9/site-packages/twisted/python/log.py:281:msg\r\ncowrie           | \t/usr/lib/python3.9/site-packages/twisted/logger/_legacy.py:147:publishToNewObserver\r\ncowrie           | \t--- <exception caught here> ---\r\ncowrie           | \t/usr/lib/python3.9/site-packages/twisted/logger/_observer.py:82:__call__\r\ncowrie           | \t/usr/lib/python3.9/site-packages/twisted/logger/_legacy.py:90:__call__\r\ncowrie           | \t/home/cowrie/cowrie/src/cowrie/core/output.py:240:emit\r\ncowrie           | \t/home/cowrie/cowrie/src/cowrie/output/hpfeeds3.py:110:write\r\ncowrie           | \t/usr/lib/python3.9/codecs.py:322:decode\r\ncowrie           | \t]\r\ncowrie           | \tTraceback (most recent call last):\r\ncowrie           | \t  File \"/home/cowrie/cowrie/src/cowrie/insults/insults.py\", line 226, in connectionLost\r\ncowrie           | \t    log.msg(\r\ncowrie           | \t  File \"/usr/lib/python3.9/site-packages/twisted/python/threadable.py\", line 51, in sync\r\ncowrie           | \t    return function(self, *args, **kwargs)\r\ncowrie           | \t  File \"/usr/lib/python3.9/site-packages/twisted/python/log.py\", line 281, in msg\r\ncowrie           | \t    _publishNew(self._publishPublisher, actualEventDict, textFromEventDict)\r\ncowrie           | \t  File \"/usr/lib/python3.9/site-packages/twisted/logger/_legacy.py\", line 147, in publishToNewObserver\r\ncowrie           | \t    observer(eventDict)\r\ncowrie           | \t--- <exception caught here> ---\r\ncowrie           | \t  File \"/usr/lib/python3.9/site-packages/twisted/logger/_observer.py\", line 82, in __call__\r\ncowrie           | \t    observer(event)\r\ncowrie           | \t  File \"/usr/lib/python3.9/site-packages/twisted/logger/_legacy.py\", line 90, in __call__\r\ncowrie           | \t    self.legacyObserver(event)\r\ncowrie           | \t  File \"/home/cowrie/cowrie/src/cowrie/core/output.py\", line 240, in emit\r\ncowrie           | \t    self.write(ev)\r\ncowrie           | \t  File \"/home/cowrie/cowrie/src/cowrie/output/hpfeeds3.py\", line 110, in write\r\ncowrie           | \t    self.meta[session][\"ttylog\"] = ttylog.read().encode().hex()\r\ncowrie           | \t  File \"/usr/lib/python3.9/codecs.py\", line 322, in decode\r\ncowrie           | \t    (result, consumed) = self._buffer_decode(data, self.errors, final)\r\ncowrie           | \tbuiltins.UnicodeDecodeError: 'utf-8' codec can't decode byte 0x88 in position 16: invalid start byte\r\n```\r\n\r\n**Server (please complete the following information):**\r\n - OS: Alpine Linux in Docker\r\n - Python: Python 3.9\r\n\r\n**Additional context**\r\nThe ttylog seems to be a binary file with only parts of it being text. \r\n\r\nAt the moment the file is opened as a text file, then encoded to utf-8 bytes and then to a hex representation. Opening it as a binary file and directly transforming it to a hex reprenstation should fix it.\n", "before_files": [{"content": "\"\"\"\nOutput plugin for HPFeeds\n\"\"\"\n\nfrom __future__ import annotations\n\nimport json\nimport logging\n\nfrom hpfeeds.twisted import ClientSessionService\n\nfrom twisted.internet import endpoints, ssl\nfrom twisted.internet import reactor  # type: ignore\nfrom twisted.python import log\n\nimport cowrie.core.output\nfrom cowrie.core.config import CowrieConfig\n\n\nclass Output(cowrie.core.output.Output):\n    \"\"\"\n    Output plugin for HPFeeds\n    \"\"\"\n\n    channel = \"cowrie.sessions\"\n\n    def start(self):\n        if CowrieConfig.has_option(\"output_hpfeeds3\", \"channel\"):\n            self.channel = CowrieConfig.get(\"output_hpfeeds3\", \"channel\")\n\n        if CowrieConfig.has_option(\"output_hpfeeds3\", \"endpoint\"):\n            endpoint = CowrieConfig.get(\"output_hpfeeds3\", \"endpoint\")\n        else:\n            server = CowrieConfig.get(\"output_hpfeeds3\", \"server\")\n            port = CowrieConfig.getint(\"output_hpfeeds3\", \"port\")\n\n            if CowrieConfig.has_option(\"output_hpfeeds3\", \"tlscert\"):\n                with open(CowrieConfig.get(\"output_hpfeeds3\", \"tlscert\")) as fp:\n                    authority = ssl.Certificate.loadPEM(fp.read())\n                options = ssl.optionsForClientTLS(server, authority)\n                endpoint = endpoints.SSL4ClientEndpoint(reactor, server, port, options)\n            else:\n                endpoint = endpoints.HostnameEndpoint(reactor, server, port)\n\n        ident = CowrieConfig.get(\"output_hpfeeds3\", \"identifier\")\n        secret = CowrieConfig.get(\"output_hpfeeds3\", \"secret\")\n\n        self.meta = {}\n\n        self.client = ClientSessionService(endpoint, ident, secret)\n        self.client.startService()\n\n    def stop(self):\n        self.client.stopService()\n\n    def write(self, entry):\n        session = entry[\"session\"]\n        if entry[\"eventid\"] == \"cowrie.session.connect\":\n            self.meta[session] = {\n                \"session\": session,\n                \"startTime\": entry[\"timestamp\"],\n                \"endTime\": \"\",\n                \"peerIP\": entry[\"src_ip\"],\n                \"peerPort\": entry[\"src_port\"],\n                \"hostIP\": entry[\"dst_ip\"],\n                \"hostPort\": entry[\"dst_port\"],\n                \"loggedin\": None,\n                \"credentials\": [],\n                \"commands\": [],\n                \"unknownCommands\": [],\n                \"urls\": [],\n                \"version\": None,\n                \"ttylog\": None,\n                \"hashes\": set(),\n                \"protocol\": entry[\"protocol\"],\n            }\n\n        elif entry[\"eventid\"] == \"cowrie.login.success\":\n            u, p = entry[\"username\"], entry[\"password\"]\n            self.meta[session][\"loggedin\"] = (u, p)\n\n        elif entry[\"eventid\"] == \"cowrie.login.failed\":\n            u, p = entry[\"username\"], entry[\"password\"]\n            self.meta[session][\"credentials\"].append((u, p))\n\n        elif entry[\"eventid\"] == \"cowrie.command.input\":\n            c = entry[\"input\"]\n            self.meta[session][\"commands\"].append(c)\n\n        elif entry[\"eventid\"] == \"cowrie.command.failed\":\n            uc = entry[\"input\"]\n            self.meta[session][\"unknownCommands\"].append(uc)\n\n        elif entry[\"eventid\"] == \"cowrie.session.file_download\":\n            if \"url\" in entry:\n                url = entry[\"url\"]\n                self.meta[session][\"urls\"].append(url)\n            self.meta[session][\"hashes\"].add(entry[\"shasum\"])\n\n        elif entry[\"eventid\"] == \"cowrie.session.file_upload\":\n            self.meta[session][\"hashes\"].add(entry[\"shasum\"])\n\n        elif entry[\"eventid\"] == \"cowrie.client.version\":\n            v = entry[\"version\"]\n            self.meta[session][\"version\"] = v\n\n        elif entry[\"eventid\"] == \"cowrie.log.closed\":\n            # entry[\"ttylog\"]\n            with open(entry[\"ttylog\"]) as ttylog:\n                self.meta[session][\"ttylog\"] = ttylog.read().encode().hex()\n\n        elif entry[\"eventid\"] == \"cowrie.session.closed\":\n            meta = self.meta.pop(session, None)\n            if meta:\n                log.msg(\"publishing metadata to hpfeeds\", logLevel=logging.DEBUG)\n                meta[\"endTime\"] = entry[\"timestamp\"]\n                meta[\"hashes\"] = list(meta[\"hashes\"])\n                self.client.publish(self.channel, json.dumps(meta).encode(\"utf-8\"))\n", "path": "src/cowrie/output/hpfeeds3.py"}], "after_files": [{"content": "\"\"\"\nOutput plugin for HPFeeds\n\"\"\"\n\nfrom __future__ import annotations\n\nimport json\nimport logging\n\nfrom hpfeeds.twisted import ClientSessionService\n\nfrom twisted.internet import endpoints, ssl\nfrom twisted.internet import reactor  # type: ignore\nfrom twisted.python import log\n\nimport cowrie.core.output\nfrom cowrie.core.config import CowrieConfig\n\n\nclass Output(cowrie.core.output.Output):\n    \"\"\"\n    Output plugin for HPFeeds\n    \"\"\"\n\n    channel = \"cowrie.sessions\"\n\n    def start(self):\n        if CowrieConfig.has_option(\"output_hpfeeds3\", \"channel\"):\n            self.channel = CowrieConfig.get(\"output_hpfeeds3\", \"channel\")\n\n        if CowrieConfig.has_option(\"output_hpfeeds3\", \"endpoint\"):\n            endpoint = CowrieConfig.get(\"output_hpfeeds3\", \"endpoint\")\n        else:\n            server = CowrieConfig.get(\"output_hpfeeds3\", \"server\")\n            port = CowrieConfig.getint(\"output_hpfeeds3\", \"port\")\n\n            if CowrieConfig.has_option(\"output_hpfeeds3\", \"tlscert\"):\n                with open(CowrieConfig.get(\"output_hpfeeds3\", \"tlscert\")) as fp:\n                    authority = ssl.Certificate.loadPEM(fp.read())\n                options = ssl.optionsForClientTLS(server, authority)\n                endpoint = endpoints.SSL4ClientEndpoint(reactor, server, port, options)\n            else:\n                endpoint = endpoints.HostnameEndpoint(reactor, server, port)\n\n        ident = CowrieConfig.get(\"output_hpfeeds3\", \"identifier\")\n        secret = CowrieConfig.get(\"output_hpfeeds3\", \"secret\")\n\n        self.meta = {}\n\n        self.client = ClientSessionService(endpoint, ident, secret)\n        self.client.startService()\n\n    def stop(self):\n        self.client.stopService()\n\n    def write(self, entry):\n        session = entry[\"session\"]\n        if entry[\"eventid\"] == \"cowrie.session.connect\":\n            self.meta[session] = {\n                \"session\": session,\n                \"startTime\": entry[\"timestamp\"],\n                \"endTime\": \"\",\n                \"peerIP\": entry[\"src_ip\"],\n                \"peerPort\": entry[\"src_port\"],\n                \"hostIP\": entry[\"dst_ip\"],\n                \"hostPort\": entry[\"dst_port\"],\n                \"loggedin\": None,\n                \"credentials\": [],\n                \"commands\": [],\n                \"unknownCommands\": [],\n                \"urls\": [],\n                \"version\": None,\n                \"ttylog\": None,\n                \"hashes\": set(),\n                \"protocol\": entry[\"protocol\"],\n            }\n\n        elif entry[\"eventid\"] == \"cowrie.login.success\":\n            u, p = entry[\"username\"], entry[\"password\"]\n            self.meta[session][\"loggedin\"] = (u, p)\n\n        elif entry[\"eventid\"] == \"cowrie.login.failed\":\n            u, p = entry[\"username\"], entry[\"password\"]\n            self.meta[session][\"credentials\"].append((u, p))\n\n        elif entry[\"eventid\"] == \"cowrie.command.input\":\n            c = entry[\"input\"]\n            self.meta[session][\"commands\"].append(c)\n\n        elif entry[\"eventid\"] == \"cowrie.command.failed\":\n            uc = entry[\"input\"]\n            self.meta[session][\"unknownCommands\"].append(uc)\n\n        elif entry[\"eventid\"] == \"cowrie.session.file_download\":\n            if \"url\" in entry:\n                url = entry[\"url\"]\n                self.meta[session][\"urls\"].append(url)\n            self.meta[session][\"hashes\"].add(entry[\"shasum\"])\n\n        elif entry[\"eventid\"] == \"cowrie.session.file_upload\":\n            self.meta[session][\"hashes\"].add(entry[\"shasum\"])\n\n        elif entry[\"eventid\"] == \"cowrie.client.version\":\n            v = entry[\"version\"]\n            self.meta[session][\"version\"] = v\n\n        elif entry[\"eventid\"] == \"cowrie.log.closed\":\n            # entry[\"ttylog\"]\n            with open(entry[\"ttylog\"], 'rb') as ttylog:\n                self.meta[session][\"ttylog\"] = ttylog.read().hex()\n\n        elif entry[\"eventid\"] == \"cowrie.session.closed\":\n            meta = self.meta.pop(session, None)\n            if meta:\n                log.msg(\"publishing metadata to hpfeeds\", logLevel=logging.DEBUG)\n                meta[\"endTime\"] = entry[\"timestamp\"]\n                meta[\"hashes\"] = list(meta[\"hashes\"])\n                self.client.publish(self.channel, json.dumps(meta).encode(\"utf-8\"))\n", "path": "src/cowrie/output/hpfeeds3.py"}]}