prompt: We are currently solving the following issue within our repository. Here is the issue text:
  --- BEGIN ISSUE ---
  greynoise should catch timeout error
  ```2019-04-08T03:12:05.460833Z [twisted.internet.defer#critical] Unhandled error in Deferred:
  2019-04-08T03:12:05.462257Z [twisted.internet.defer#critical]
          Traceback (most recent call last):
          --- <exception caught here> ---
            File "/home/cowrie/cowrie/src/cowrie/output/greynoise.py", line 65, in scanip
              headers=headers)
          twisted.internet.error.TimeoutError: User timeout caused connection failure.
  ```
  
  
  --- 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/greynoise.py`
  Content:
  ```
  1 """
  2 Send attackers IP to GreyNoise
  3 """
  4 
  5 from __future__ import absolute_import, division
  6 
  7 import treq
  8 
  9 from twisted.internet import defer
  10 from twisted.python import log
  11 
  12 import cowrie.core.output
  13 from cowrie.core.config import CONFIG
  14 
  15 COWRIE_USER_AGENT = 'Cowrie Honeypot'
  16 GNAPI_URL = 'http://api.greynoise.io:8888/v1/'
  17 
  18 
  19 class Output(cowrie.core.output.Output):
  20 
  21     def __init__(self):
  22         self.apiKey = CONFIG.get('output_greynoise', 'api_key', fallback=None)
  23         self.tags = CONFIG.get('output_greynoise', 'tags', fallback="all").split(",")
  24         self.debug = CONFIG.getboolean('output_greynoise', 'debug', fallback=False)
  25         cowrie.core.output.Output.__init__(self)
  26 
  27     def start(self):
  28         """
  29         Start output plugin
  30         """
  31 
  32     def stop(self):
  33         """
  34         Stop output plugin
  35         """
  36         pass
  37 
  38     def write(self, entry):
  39         if entry['eventid'] == "cowrie.session.connect":
  40             self.scanip(entry)
  41 
  42     @defer.inlineCallbacks
  43     def scanip(self, entry):
  44         """
  45         Scan IP againt Greynoise API
  46         """
  47         def message(query):
  48             log.msg(
  49                 eventid='cowrie.greynoise.result',
  50                 format='greynoise: Scan for %(IP)s with %(tag)s have %(conf)s confidence'
  51                 ' along with the following %(meta)s metadata',
  52                 IP=entry['src_ip'],
  53                 tag=query['name'],
  54                 conf=query['confidence'],
  55                 meta=query['metadata']
  56             )
  57 
  58         gnUrl = '{0}query/ip'.format(GNAPI_URL).encode('utf8')
  59         headers = ({'User-Agent': [COWRIE_USER_AGENT]})
  60         fields = {'key': self.apiKey, 'ip': entry['src_ip']}
  61 
  62         response = yield treq.post(
  63             url=gnUrl,
  64             data=fields,
  65             headers=headers)
  66 
  67         if response.code != 200:
  68             rsp = yield response.text()
  69             log.error("greynoise: got error {}".format(rsp))
  70             return
  71 
  72         j = yield response.json()
  73         if self.debug:
  74             log.msg("greynoise: debug: "+repr(j))
  75             if j['status'] == "ok":
  76                 if "all" not in self.tags:
  77                     for query in j['records']:
  78                         if query['name'] in self.tags:
  79                             message(query)
  80                 else:
  81                     for query in j['records']:
  82                         message(query)
  83             else:
  84                 log.msg("greynoise: no results for for IP {0}".format(entry['src_ip']))
  85
  ```
  --- 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()
  
  ```
  
golden_diff: diff --git a/src/cowrie/output/greynoise.py b/src/cowrie/output/greynoise.py
  --- a/src/cowrie/output/greynoise.py
  +++ b/src/cowrie/output/greynoise.py
  @@ -6,7 +6,7 @@
   
   import treq
   
  -from twisted.internet import defer
  +from twisted.internet import defer, error
   from twisted.python import log
   
   import cowrie.core.output
  @@ -59,10 +59,15 @@
           headers = ({'User-Agent': [COWRIE_USER_AGENT]})
           fields = {'key': self.apiKey, 'ip': entry['src_ip']}
   
  -        response = yield treq.post(
  -            url=gnUrl,
  -            data=fields,
  -            headers=headers)
  +        try:
  +            response = yield treq.post(
  +                url=gnUrl,
  +                data=fields,
  +                headers=headers,
  +                timeout=10)
  +        except (defer.CancelledError, error.ConnectingCancelledError, error.DNSLookupError):
  +            log.msg("GreyNoise requests timeout")
  +            return
   
           if response.code != 200:
               rsp = yield response.text()
  @@ -72,13 +77,14 @@
           j = yield response.json()
           if self.debug:
               log.msg("greynoise: debug: "+repr(j))
  -            if j['status'] == "ok":
  -                if "all" not in self.tags:
  -                    for query in j['records']:
  -                        if query['name'] in self.tags:
  -                            message(query)
  -                else:
  -                    for query in j['records']:
  +
  +        if j['status'] == "ok":
  +            if "all" not in self.tags:
  +                for query in j['records']:
  +                    if query['name'] in self.tags:
                           message(query)
               else:
  -                log.msg("greynoise: no results for for IP {0}".format(entry['src_ip']))
  +                for query in j['records']:
  +                    message(query)
  +        else:
  +            log.msg("greynoise: no results for for IP {0}".format(entry['src_ip']))
  
verification_info: {"golden_diff": "diff --git a/src/cowrie/output/greynoise.py b/src/cowrie/output/greynoise.py\n--- a/src/cowrie/output/greynoise.py\n+++ b/src/cowrie/output/greynoise.py\n@@ -6,7 +6,7 @@\n \n import treq\n \n-from twisted.internet import defer\n+from twisted.internet import defer, error\n from twisted.python import log\n \n import cowrie.core.output\n@@ -59,10 +59,15 @@\n         headers = ({'User-Agent': [COWRIE_USER_AGENT]})\n         fields = {'key': self.apiKey, 'ip': entry['src_ip']}\n \n-        response = yield treq.post(\n-            url=gnUrl,\n-            data=fields,\n-            headers=headers)\n+        try:\n+            response = yield treq.post(\n+                url=gnUrl,\n+                data=fields,\n+                headers=headers,\n+                timeout=10)\n+        except (defer.CancelledError, error.ConnectingCancelledError, error.DNSLookupError):\n+            log.msg(\"GreyNoise requests timeout\")\n+            return\n \n         if response.code != 200:\n             rsp = yield response.text()\n@@ -72,13 +77,14 @@\n         j = yield response.json()\n         if self.debug:\n             log.msg(\"greynoise: debug: \"+repr(j))\n-            if j['status'] == \"ok\":\n-                if \"all\" not in self.tags:\n-                    for query in j['records']:\n-                        if query['name'] in self.tags:\n-                            message(query)\n-                else:\n-                    for query in j['records']:\n+\n+        if j['status'] == \"ok\":\n+            if \"all\" not in self.tags:\n+                for query in j['records']:\n+                    if query['name'] in self.tags:\n                         message(query)\n             else:\n-                log.msg(\"greynoise: no results for for IP {0}\".format(entry['src_ip']))\n+                for query in j['records']:\n+                    message(query)\n+        else:\n+            log.msg(\"greynoise: no results for for IP {0}\".format(entry['src_ip']))\n", "issue": "greynoise should catch timeout error\n```2019-04-08T03:12:05.460833Z [twisted.internet.defer#critical] Unhandled error in Deferred:\r\n2019-04-08T03:12:05.462257Z [twisted.internet.defer#critical]\r\n        Traceback (most recent call last):\r\n        --- <exception caught here> ---\r\n          File \"/home/cowrie/cowrie/src/cowrie/output/greynoise.py\", line 65, in scanip\r\n            headers=headers)\r\n        twisted.internet.error.TimeoutError: User timeout caused connection failure.\r\n```\r\n\n", "before_files": [{"content": "\"\"\"\nSend attackers IP to GreyNoise\n\"\"\"\n\nfrom __future__ import absolute_import, division\n\nimport treq\n\nfrom twisted.internet import defer\nfrom twisted.python import log\n\nimport cowrie.core.output\nfrom cowrie.core.config import CONFIG\n\nCOWRIE_USER_AGENT = 'Cowrie Honeypot'\nGNAPI_URL = 'http://api.greynoise.io:8888/v1/'\n\n\nclass Output(cowrie.core.output.Output):\n\n    def __init__(self):\n        self.apiKey = CONFIG.get('output_greynoise', 'api_key', fallback=None)\n        self.tags = CONFIG.get('output_greynoise', 'tags', fallback=\"all\").split(\",\")\n        self.debug = CONFIG.getboolean('output_greynoise', 'debug', fallback=False)\n        cowrie.core.output.Output.__init__(self)\n\n    def start(self):\n        \"\"\"\n        Start output plugin\n        \"\"\"\n\n    def stop(self):\n        \"\"\"\n        Stop output plugin\n        \"\"\"\n        pass\n\n    def write(self, entry):\n        if entry['eventid'] == \"cowrie.session.connect\":\n            self.scanip(entry)\n\n    @defer.inlineCallbacks\n    def scanip(self, entry):\n        \"\"\"\n        Scan IP againt Greynoise API\n        \"\"\"\n        def message(query):\n            log.msg(\n                eventid='cowrie.greynoise.result',\n                format='greynoise: Scan for %(IP)s with %(tag)s have %(conf)s confidence'\n                ' along with the following %(meta)s metadata',\n                IP=entry['src_ip'],\n                tag=query['name'],\n                conf=query['confidence'],\n                meta=query['metadata']\n            )\n\n        gnUrl = '{0}query/ip'.format(GNAPI_URL).encode('utf8')\n        headers = ({'User-Agent': [COWRIE_USER_AGENT]})\n        fields = {'key': self.apiKey, 'ip': entry['src_ip']}\n\n        response = yield treq.post(\n            url=gnUrl,\n            data=fields,\n            headers=headers)\n\n        if response.code != 200:\n            rsp = yield response.text()\n            log.error(\"greynoise: got error {}\".format(rsp))\n            return\n\n        j = yield response.json()\n        if self.debug:\n            log.msg(\"greynoise: debug: \"+repr(j))\n            if j['status'] == \"ok\":\n                if \"all\" not in self.tags:\n                    for query in j['records']:\n                        if query['name'] in self.tags:\n                            message(query)\n                else:\n                    for query in j['records']:\n                        message(query)\n            else:\n                log.msg(\"greynoise: no results for for IP {0}\".format(entry['src_ip']))\n", "path": "src/cowrie/output/greynoise.py"}], "after_files": [{"content": "\"\"\"\nSend attackers IP to GreyNoise\n\"\"\"\n\nfrom __future__ import absolute_import, division\n\nimport treq\n\nfrom twisted.internet import defer, error\nfrom twisted.python import log\n\nimport cowrie.core.output\nfrom cowrie.core.config import CONFIG\n\nCOWRIE_USER_AGENT = 'Cowrie Honeypot'\nGNAPI_URL = 'http://api.greynoise.io:8888/v1/'\n\n\nclass Output(cowrie.core.output.Output):\n\n    def __init__(self):\n        self.apiKey = CONFIG.get('output_greynoise', 'api_key', fallback=None)\n        self.tags = CONFIG.get('output_greynoise', 'tags', fallback=\"all\").split(\",\")\n        self.debug = CONFIG.getboolean('output_greynoise', 'debug', fallback=False)\n        cowrie.core.output.Output.__init__(self)\n\n    def start(self):\n        \"\"\"\n        Start output plugin\n        \"\"\"\n\n    def stop(self):\n        \"\"\"\n        Stop output plugin\n        \"\"\"\n        pass\n\n    def write(self, entry):\n        if entry['eventid'] == \"cowrie.session.connect\":\n            self.scanip(entry)\n\n    @defer.inlineCallbacks\n    def scanip(self, entry):\n        \"\"\"\n        Scan IP againt Greynoise API\n        \"\"\"\n        def message(query):\n            log.msg(\n                eventid='cowrie.greynoise.result',\n                format='greynoise: Scan for %(IP)s with %(tag)s have %(conf)s confidence'\n                ' along with the following %(meta)s metadata',\n                IP=entry['src_ip'],\n                tag=query['name'],\n                conf=query['confidence'],\n                meta=query['metadata']\n            )\n\n        gnUrl = '{0}query/ip'.format(GNAPI_URL).encode('utf8')\n        headers = ({'User-Agent': [COWRIE_USER_AGENT]})\n        fields = {'key': self.apiKey, 'ip': entry['src_ip']}\n\n        try:\n            response = yield treq.post(\n                url=gnUrl,\n                data=fields,\n                headers=headers,\n                timeout=10)\n        except (defer.CancelledError, error.ConnectingCancelledError, error.DNSLookupError):\n            log.msg(\"GreyNoise requests timeout\")\n            return\n\n        if response.code != 200:\n            rsp = yield response.text()\n            log.error(\"greynoise: got error {}\".format(rsp))\n            return\n\n        j = yield response.json()\n        if self.debug:\n            log.msg(\"greynoise: debug: \"+repr(j))\n\n        if j['status'] == \"ok\":\n            if \"all\" not in self.tags:\n                for query in j['records']:\n                    if query['name'] in self.tags:\n                        message(query)\n            else:\n                for query in j['records']:\n                    message(query)\n        else:\n            log.msg(\"greynoise: no results for for IP {0}\".format(entry['src_ip']))\n", "path": "src/cowrie/output/greynoise.py"}]}