certstream-1.12/0000755000076500000240000000000014042340421014354 5ustar fitblipstaff00000000000000certstream-1.12/PKG-INFO0000644000076500000240000000170514042340421015454 0ustar fitblipstaff00000000000000Metadata-Version: 1.1 Name: certstream Version: 1.12 Summary: CertStream is a library for receiving certificate transparency list updates in real time. Home-page: https://github.com/CaliDog/certstream-python/ Author: Ryan Sears Author-email: ryan@calidog.io License: MIT Description: Certstream is a library to connect to the certstream network (certstream.calidog.io). It supports automatic reconnection when networks issues occur, and should be stable for long-running jobs. Platform: UNKNOWN Classifier: Development Status :: 4 - Beta Classifier: License :: OSI Approved :: MIT License Classifier: Topic :: Internet :: WWW/HTTP Classifier: Topic :: Security :: Cryptography Classifier: Environment :: Console Classifier: Operating System :: MacOS :: MacOS X Classifier: Operating System :: POSIX Classifier: Programming Language :: Python :: 3 Classifier: Programming Language :: Python :: 2 Classifier: Framework :: AsyncIO certstream-1.12/certstream/0000755000076500000240000000000014042340421016525 5ustar fitblipstaff00000000000000certstream-1.12/certstream/__init__.py0000644000076500000240000000004313173001051020630 0ustar fitblipstaff00000000000000from .core import listen_for_eventscertstream-1.12/certstream/core.py0000644000076500000240000000405414042340151020032 0ustar fitblipstaff00000000000000from __future__ import print_function import json import logging import time from websocket import WebSocketApp class Context(dict): """dot.notation access to dictionary attributes""" __getattr__ = dict.get __setattr__ = dict.__setitem__ __delattr__ = dict.__delitem__ class CertStreamClient(WebSocketApp): _context = Context() def __init__(self, message_callback, url, skip_heartbeats=True, on_open=None, on_error=None): self.message_callback = message_callback self.skip_heartbeats = skip_heartbeats self.on_open_handler = on_open self.on_error_handler = on_error super(CertStreamClient, self).__init__( url=url, on_open=self._on_open, on_message=self._on_message, on_error=self._on_error, ) def _on_open(self, _): certstream_logger.info("Connection established to CertStream! Listening for events...") if self.on_open_handler: self.on_open_handler() def _on_message(self, _, message): frame = json.loads(message) if frame.get('message_type', None) == "heartbeat" and self.skip_heartbeats: return self.message_callback(frame, self._context) def _on_error(self, _, ex): if type(ex) == KeyboardInterrupt: raise if self.on_error_handler: self.on_error_handler(ex) certstream_logger.error("Error connecting to CertStream - {} - Sleeping for a few seconds and trying again...".format(ex)) def listen_for_events(message_callback, url, skip_heartbeats=True, setup_logger=True, on_open=None, on_error=None, **kwargs): try: while True: c = CertStreamClient(message_callback, url, skip_heartbeats=skip_heartbeats, on_open=on_open, on_error=on_error) c.run_forever(ping_interval=15, **kwargs) time.sleep(5) except KeyboardInterrupt: certstream_logger.info("Kill command received, exiting!!") certstream_logger = logging.getLogger('certstream') certstream_logger.setLevel(logging.INFO) certstream-1.12/certstream/cli.py0000644000076500000240000000550613246231702017662 0ustar fitblipstaff00000000000000import argparse import datetime import json import logging import sys import termcolor from signal import signal, SIGPIPE, SIG_DFL import certstream parser = argparse.ArgumentParser(description='Connect to the CertStream and process CTL list updates.') parser.add_argument('--json', action='store_true', help='Output raw JSON to the console.') parser.add_argument('--full', action='store_true', help='Output all SAN addresses as well') parser.add_argument('--disable-colors', action='store_true', help='Disable colors when writing a human readable ') parser.add_argument('--verbose', action='store_true', default=False, dest='verbose', help='Display debug logging.') parser.add_argument('--url', default="wss://certstream.calidog.io", dest='url', help='Connect to a certstream server.') def main(): args = parser.parse_args() # Ignore broken pipes signal(SIGPIPE, SIG_DFL) log_level = logging.INFO if args.verbose: log_level = logging.DEBUG logging.basicConfig(format='[%(levelname)s:%(name)s] %(asctime)s - %(message)s', level=log_level) def _handle_messages(message, context): if args.json: sys.stdout.flush() sys.stdout.write(json.dumps(message) + "\n") sys.stdout.flush() else: if args.disable_colors: logging.debug("Starting normal output.") payload = "{} {} - {} {}\n".format( "[{}]".format(datetime.datetime.fromtimestamp(message['data']['seen']).isoformat()), message['data']['source']['url'], message['data']['leaf_cert']['subject']['CN'], "[{}]".format(", ".join(message['data']['leaf_cert']['all_domains'])) if args.full else "" ) sys.stdout.write(payload) else: logging.debug("Starting colored output.") payload = "{} {} - {} {}\n".format( termcolor.colored("[{}]".format(datetime.datetime.fromtimestamp(message['data']['seen']).isoformat()), 'cyan', attrs=["bold", ]), termcolor.colored(message['data']['source']['url'], 'blue', attrs=["bold",]), termcolor.colored(message['data']['leaf_cert']['subject']['CN'], 'green', attrs=["bold",]), termcolor.colored("[", 'blue') + "{}".format( termcolor.colored(", ", 'blue').join( [termcolor.colored(x, 'white', attrs=["bold",]) for x in message['data']['leaf_cert']['all_domains']] ) ) + termcolor.colored("]", 'blue') if args.full else "", ) sys.stdout.write(payload) sys.stdout.flush() certstream.listen_for_events(_handle_messages, args.url, skip_heartbeats=True) if __name__ == "__main__": main() certstream-1.12/LICENSE0000644000076500000240000000206113172467371015401 0ustar fitblipstaff00000000000000MIT License Copyright (c) 2017 Cali Dog Security Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.certstream-1.12/requirements.txt0000644000076500000240000000004314042340151017635 0ustar fitblipstaff00000000000000websocket-client>=0.58.0 termcolor certstream-1.12/certstream.egg-info/0000755000076500000240000000000014042340421020217 5ustar fitblipstaff00000000000000certstream-1.12/certstream.egg-info/PKG-INFO0000644000076500000240000000170514042340421021317 0ustar fitblipstaff00000000000000Metadata-Version: 1.1 Name: certstream Version: 1.12 Summary: CertStream is a library for receiving certificate transparency list updates in real time. Home-page: https://github.com/CaliDog/certstream-python/ Author: Ryan Sears Author-email: ryan@calidog.io License: MIT Description: Certstream is a library to connect to the certstream network (certstream.calidog.io). It supports automatic reconnection when networks issues occur, and should be stable for long-running jobs. Platform: UNKNOWN Classifier: Development Status :: 4 - Beta Classifier: License :: OSI Approved :: MIT License Classifier: Topic :: Internet :: WWW/HTTP Classifier: Topic :: Security :: Cryptography Classifier: Environment :: Console Classifier: Operating System :: MacOS :: MacOS X Classifier: Operating System :: POSIX Classifier: Programming Language :: Python :: 3 Classifier: Programming Language :: Python :: 2 Classifier: Framework :: AsyncIO certstream-1.12/certstream.egg-info/SOURCES.txt0000644000076500000240000000050114042340421022077 0ustar fitblipstaff00000000000000LICENSE MANIFEST.in README.md requirements.txt setup.py certstream/__init__.py certstream/cli.py certstream/core.py certstream.egg-info/PKG-INFO certstream.egg-info/SOURCES.txt certstream.egg-info/dependency_links.txt certstream.egg-info/entry_points.txt certstream.egg-info/requires.txt certstream.egg-info/top_level.txtcertstream-1.12/certstream.egg-info/entry_points.txt0000644000076500000240000000006414042340421023515 0ustar fitblipstaff00000000000000[console_scripts] certstream = certstream.cli:main certstream-1.12/certstream.egg-info/requires.txt0000644000076500000240000000004314042340421022614 0ustar fitblipstaff00000000000000websocket-client>=0.58.0 termcolor certstream-1.12/certstream.egg-info/top_level.txt0000644000076500000240000000001314042340421022743 0ustar fitblipstaff00000000000000certstream certstream-1.12/certstream.egg-info/dependency_links.txt0000644000076500000240000000000114042340421024265 0ustar fitblipstaff00000000000000 certstream-1.12/MANIFEST.in0000644000076500000240000000005113351012763016115 0ustar fitblipstaff00000000000000include requirements.txt include LICENSE certstream-1.12/README.md0000644000076500000240000002742014042340144015642 0ustar fitblipstaff00000000000000

CertStream-Python

See SSL certs as they're issued live.

**Certstream-python** is a library for interacting with the [certstream network](https://certstream.calidog.io/) to monitor an aggregated feed from a collection of [Certificate Transparency Lists](https://www.certificate-transparency.org/known-logs). It leverages the excellent 2/3 compatible [websocket-client](https://github.com/websocket-client/websocket-client) library and supports reconnecting automatically. # Installing ``` pip install certstream ``` # Usage Usage is about as simple as it gets, simply import the `certstream` module and register a callback with `certstream.listen_for_events`. Once you register a callback it will be called with 2 arguments - `message`, and `context`. ```python import logging import sys import datetime import certstream def print_callback(message, context): logging.debug("Message -> {}".format(message)) if message['message_type'] == "heartbeat": return if message['message_type'] == "certificate_update": all_domains = message['data']['leaf_cert']['all_domains'] if len(all_domains) == 0: domain = "NULL" else: domain = all_domains[0] sys.stdout.write(u"[{}] {} (SAN: {})\n".format(datetime.datetime.now().strftime('%m/%d/%y %H:%M:%S'), domain, ", ".join(message['data']['leaf_cert']['all_domains'][1:]))) sys.stdout.flush() logging.basicConfig(format='[%(levelname)s:%(name)s] %(asctime)s - %(message)s', level=logging.INFO) certstream.listen_for_events(print_callback, url='wss://certstream.calidog.io/') ``` You can also register an `on_open` and `on_error` handler as well, which do exactly what you'd expect: ```python import certstream def print_callback(message, context): print("Received messaged -> {}".format(message)) def on_open(instance): # Instance is the CertStreamClient instance that was opened print("Connection successfully established!") def on_error(instance, exception): # Instance is the CertStreamClient instance that barfed print("Exception in CertStreamClient! -> {}".format(exception)) certstream.listen_for_events(print_callback, on_open=on_open, on_error=on_error, url='wss://certstream.calidog.io/') ``` We also support connection via http proxy: ```python import certstream def print_callback(message, context): print("Received messaged -> {}".format(message)) certstream.listen_for_events(print_callback, url='wss://certstream.calidog.io/', http_proxy_host="proxy_host", http_proxy_port=8080, http_proxy_auth=("user", "password")) ``` Need more connection options? Take a look at `**kwargs` in `certstream.listen_for_events`. We pass it to `run_forever` method of [websocket-client](https://github.com/websocket-client/websocket-client/blob/87861f951d1a65ed5d9080f7aaaf44310f376c56/websocket/_app.py#L169-L192). # Example data structure The data structure coming from CertStream looks like this: ``` { "message_type": "certificate_update", "data": { "update_type": "X509LogEntry", "leaf_cert": { "subject": { "aggregated": "/CN=app.theaffairsite.com", "C": null, "ST": null, "L": null, "O": null, "OU": null, "CN": "app.theaffairsite.com" }, "extensions": { "keyUsage": "Digital Signature, Key Encipherment", "extendedKeyUsage": "TLS Web Server Authentication, TLS Web Client Authentication", "basicConstraints": "CA:FALSE", "subjectKeyIdentifier": "01:BE:17:27:B8:D8:26:EF:E1:5C:7A:F6:14:A7:EA:B5:D0:D8:B5:9B", "authorityKeyIdentifier": "keyid:A8:4A:6A:63:04:7D:DD:BA:E6:D1:39:B7:A6:45:65:EF:F3:A8:EC:A1\n", "authorityInfoAccess": "OCSP - URI:http://ocsp.int-x3.letsencrypt.org\nCA Issuers - URI:http://cert.int-x3.letsencrypt.org/\n", "subjectAltName": "DNS:app.theaffairsite.com", "certificatePolicies": "Policy: 2.23.140.1.2.1\nPolicy: 1.3.6.1.4.1.44947.1.1.1\n CPS: http://cps.letsencrypt.org\n User Notice:\n Explicit Text: This Certificate may only be relied upon by Relying Parties and only in accordance with the Certificate Policy found at https://letsencrypt.org/repository/\n" }, "not_before": 1509908649.0, "not_after": 1517684649.0, "serial_number": "33980d1bef9b6a76cfc708e3139f55f33c5", "fingerprint": "95:CA:86:6B:B4:98:59:D2:EC:C7:CA:E8:42:70:80:0B:18:03:C7:75", "as_der": "MIIFDTCCA/WgAwIBAgISAzmA0b75tqds/HCOMTn1XzPFMA0GCSqGSIb3DQEBCwUAMEoxCzAJBgNVBAYTAlVTMRYwFAYDVQQKEw1MZXQncyBFbmNyeXB0MSMwIQYDVQQDExpMZXQncyBFbmNyeXB0IEF1dGhvcml0eSBYMzAeFw0xNzExMDUxOTA0MDlaFw0xODAyMDMxOTA0MDlaMCAxHjAcBgNVBAMTFWFwcC50aGVhZmZhaXJzaXRlLmNvbTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBALtVFBtTDAMq5yt/fRujvt3XbxjAb58NG6ThmXiFN/rDyysKt4tsqYcOQRZc5D/z4Pm8hI3lgLgmiZdxJF6zUnJ7GoYGdpPwItmYHmp1rWo735NNw16zFMKw9KPi1l+aiKQqZQA9hcgXpbWoyoIZBwHS5K5Id6/uXfLk//9nRxaKqDQzB1ZokIzlv0u+hJxKA4Q+JyOiZvfQKDBcC9lEXsNJ74MTkCwu75qjvHYHB4jSrb3aiCxn7q934bI+CFFjCK1adyGJVnckXOcumZrPo4c8GL0Fc1uwZ/PdLvU9/4d/PpbSHdaN94B3bVxCjio/KnSJ8QNJo60QoEOZ60aCFN0CAwEAAaOCAhUwggIRMA4GA1UdDwEB/wQEAwIFoDAdBgNVHSUEFjAUBggrBgEFBQcDAQYIKwYBBQUHAwIwDAYDVR0TAQH/BAIwADAdBgNVHQ4EFgQUAb4XJ7jYJu/hXHr2FKfqtdDYtZswHwYDVR0jBBgwFoAUqEpqYwR93brm0Tm3pkVl7/Oo7KEwbwYIKwYBBQUHAQEEYzBhMC4GCCsGAQUFBzABhiJodHRwOi8vb2NzcC5pbnQteDMubGV0c2VuY3J5cHQub3JnMC8GCCsGAQUFBzAChiNodHRwOi8vY2VydC5pbnQteDMubGV0c2VuY3J5cHQub3JnLzAgBgNVHREEGTAXghVhcHAudGhlYWZmYWlyc2l0ZS5jb20wgf4GA1UdIASB9jCB8zAIBgZngQwBAgEwgeYGCysGAQQBgt8TAQEBMIHWMCYGCCsGAQUFBwIBFhpodHRwOi8vY3BzLmxldHNlbmNyeXB0Lm9yZzCBqwYIKwYBBQUHAgIwgZ4MgZtUaGlzIENlcnRpZmljYXRlIG1heSBvbmx5IGJlIHJlbGllZCB1cG9uIGJ5IFJlbHlpbmcgUGFydGllcyBhbmQgb25seSBpbiBhY2NvcmRhbmNlIHdpdGggdGhlIENlcnRpZmljYXRlIFBvbGljeSBmb3VuZCBhdCBodHRwczovL2xldHNlbmNyeXB0Lm9yZy9yZXBvc2l0b3J5LzANBgkqhkiG9w0BAQsFAAOCAQEASpYg0ISnbyXpqYYzgpLdc8o6GZwKrMDrTARm63aT+2L88s2Ff6JlMz4XRH3v4iihLpLVUDoiXbNUyggyVqbkQLFtHtgj8ScLvWku8n7l7lp6DpV7j3h6byM2K6a+jasJKplL+Zbqzng0RaJlFFnnBXYE9a5BW3JlOzNbOMUOSKTZSB0+6pmeohU1DhNiPQNqT2katRu0LLGbwtcEpsWyScVc3VkJVu1l0QNq8gC+F3C2MpBtiSjjz6umP1F1z+sXhUx9dFVzJ2nSk7XxZaH+DW4OAb6zjwqqYjjf2S0VQM398URhfYzLQX6xEyDuZG4W58g5SMtOWDnslPhlIax3LA==", "all_domains": [ "app.theaffairsite.com" ] }, "chain": [ { "subject": { "aggregated": "/C=US/O=Let's Encrypt/CN=Let's Encrypt Authority X3", "C": "US", "ST": null, "L": null, "O": "Let's Encrypt", "OU": null, "CN": "Let's Encrypt Authority X3" }, "extensions": { "basicConstraints": "CA:TRUE, pathlen:0", "keyUsage": "Digital Signature, Certificate Sign, CRL Sign", "authorityInfoAccess": "OCSP - URI:http://isrg.trustid.ocsp.identrust.com\nCA Issuers - URI:http://apps.identrust.com/roots/dstrootcax3.p7c\n", "authorityKeyIdentifier": "keyid:C4:A7:B1:A4:7B:2C:71:FA:DB:E1:4B:90:75:FF:C4:15:60:85:89:10\n", "certificatePolicies": "Policy: 2.23.140.1.2.1\nPolicy: 1.3.6.1.4.1.44947.1.1.1\n CPS: http://cps.root-x1.letsencrypt.org\n", "crlDistributionPoints": "\nFull Name:\n URI:http://crl.identrust.com/DSTROOTCAX3CRL.crl\n", "subjectKeyIdentifier": "A8:4A:6A:63:04:7D:DD:BA:E6:D1:39:B7:A6:45:65:EF:F3:A8:EC:A1" }, "not_before": 1458232846.0, "not_after": 1615999246.0, "serial_number": "a0141420000015385736a0b85eca708", "fingerprint": "E6:A3:B4:5B:06:2D:50:9B:33:82:28:2D:19:6E:FE:97:D5:95:6C:CB", "as_der": "MIIEkjCCA3qgAwIBAgIQCgFBQgAAAVOFc2oLheynCDANBgkqhkiG9w0BAQsFADA/MSQwIgYDVQQKExtEaWdpdGFsIFNpZ25hdHVyZSBUcnVzdCBDby4xFzAVBgNVBAMTDkRTVCBSb290IENBIFgzMB4XDTE2MDMxNzE2NDA0NloXDTIxMDMxNzE2NDA0NlowSjELMAkGA1UEBhMCVVMxFjAUBgNVBAoTDUxldCdzIEVuY3J5cHQxIzAhBgNVBAMTGkxldCdzIEVuY3J5cHQgQXV0aG9yaXR5IFgzMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAnNMM8FrlLke3cl03g7NoYzDq1zUmGSXhvb418XCSL7e4S0EFq6meNQhY7LEqxGiHC6PjdeTm86dicbp5gWAf15Gan/PQeGdxyGkOlZHP/uaZ6WA8SMx+yk13EiSdRxta67nsHjcAHJyse6cF6s5K671B5TaYucv9bTyWaN8jKkKQDIZ0Z8h/pZq4UmEUEz9l6YKHy9v6Dlb2honzhT+Xhq+w3Brvaw2VFn3EK6BlspkENnWAa6xK8xuQSXgvopZPKiAlKQTGdMDQMc2PMTiVFrqoM7hD8bEfwzB/onkxEz0tNvjj/PIzark5McWvxI0NHWQWM6r6hCm21AvA2H3DkwIDAQABo4IBfTCCAXkwEgYDVR0TAQH/BAgwBgEB/wIBADAOBgNVHQ8BAf8EBAMCAYYwfwYIKwYBBQUHAQEEczBxMDIGCCsGAQUFBzABhiZodHRwOi8vaXNyZy50cnVzdGlkLm9jc3AuaWRlbnRydXN0LmNvbTA7BggrBgEFBQcwAoYvaHR0cDovL2FwcHMuaWRlbnRydXN0LmNvbS9yb290cy9kc3Ryb290Y2F4My5wN2MwHwYDVR0jBBgwFoAUxKexpHsscfrb4UuQdf/EFWCFiRAwVAYDVR0gBE0wSzAIBgZngQwBAgEwPwYLKwYBBAGC3xMBAQEwMDAuBggrBgEFBQcCARYiaHR0cDovL2Nwcy5yb290LXgxLmxldHNlbmNyeXB0Lm9yZzA8BgNVHR8ENTAzMDGgL6AthitodHRwOi8vY3JsLmlkZW50cnVzdC5jb20vRFNUUk9PVENBWDNDUkwuY3JsMB0GA1UdDgQWBBSoSmpjBH3duubRObemRWXv86jsoTANBgkqhkiG9w0BAQsFAAOCAQEA3TPXEfNjWDjdGBX7CVW+dla5cEilaUcne8IkCJLxWh9KEik3JHRRHGJouM2VcGfl96S8TihRzZvoroed6ti6WqEBmtzw3Wodatg+VyOeph4EYpr/1wXKtx8/wApIvJSwtmVi4MFU5aMqrSDE6ea73Mj2tcMyo5jMd6jmeWUHK8so/joWUoHOUgwuX4Po1QYz+3dszkDqMp4fklxBwXRsW10KXzPMTZ+sOPAveyxindmjkW8lGy+QsRlGPfZ+G6Z6h7mjem0Y+iWlkYcV4PIWL1iwBi8saCbGS5jN2p8M+X+Q7UNKEkROb3N6KOqkqm57TH2H3eDJAkSnh6/DNFu0Qg==" }, { "subject": { "aggregated": "/O=Digital Signature Trust Co./CN=DST Root CA X3", "C": null, "ST": null, "L": null, "O": "Digital Signature Trust Co.", "OU": null, "CN": "DST Root CA X3" }, "extensions": { "basicConstraints": "CA:TRUE", "keyUsage": "Certificate Sign, CRL Sign", "subjectKeyIdentifier": "C4:A7:B1:A4:7B:2C:71:FA:DB:E1:4B:90:75:FF:C4:15:60:85:89:10" }, "not_before": 970348339.0, "not_after": 1633010475.0, "serial_number": "44afb080d6a327ba893039862ef8406b", "fingerprint": "DA:C9:02:4F:54:D8:F6:DF:94:93:5F:B1:73:26:38:CA:6A:D7:7C:13", "as_der": "MIIDSjCCAjKgAwIBAgIQRK+wgNajJ7qJMDmGLvhAazANBgkqhkiG9w0BAQUFADA/MSQwIgYDVQQKExtEaWdpdGFsIFNpZ25hdHVyZSBUcnVzdCBDby4xFzAVBgNVBAMTDkRTVCBSb290IENBIFgzMB4XDTAwMDkzMDIxMTIxOVoXDTIxMDkzMDE0MDExNVowPzEkMCIGA1UEChMbRGlnaXRhbCBTaWduYXR1cmUgVHJ1c3QgQ28uMRcwFQYDVQQDEw5EU1QgUm9vdCBDQSBYMzCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAN+v6ZdQCINXtMxiZfaQguzH0yxrMMpb7NnDfcdAwRgUi+DoM3ZJKuM/IUmTrE4Orz5Iy2Xu/NMhD2XSKtkyj4zl93ewEnu1lcCJo6m67XMuegwGMoOifooUMM0RoOEqOLl5CjH9UL2AZd+3UWODyOKIYepLYYHsUmu5ouJLGiifSKOeDNoJjj4XLh7dIN9bxiqKqy69cK3FCxolkHRyxXtqqzTWMIn/5WgTe1QLyNau7Fqckh49ZLOMxt+/yUFw7BZy1SbsOFU5Q9D8/RhcQPGX69Wam40dutolucbY38EVAjqr2m7xPi71XAicPNaDaeQQmxkqtilX4+U9m5/wAl0CAwEAAaNCMEAwDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYwHQYDVR0OBBYEFMSnsaR7LHH62+FLkHX/xBVghYkQMA0GCSqGSIb3DQEBBQUAA4IBAQCjGiybFwBcqR7uKGY3Or+Dxz9LwwmglSBd49lZRNI+DT69ikugdB/OEIKcdBodfpga3csTS7MgROSR6cz8faXbauX+5v3gTt23ADq1cEmv8uXrAvHRAosZy5Q6XkjEGB5YGV8eAlrwDPGxrancWYaLbumR9YbK+rlmM6pZW87ipxZzR8srzJmwN0jP41ZL9c8PDHIyh8bwRLtTcm1D9SZImlJnt1ir/md2cXjbDaJWFBM5JDGFoqgCWjBH4d1QB7wCCZAA62RjYJsWvIjJEubSfZGL+T0yjWW06XyxV3bqxbYoOb8VZRzI9neWagqNdwvYkQsEjgfbKbYK7p2CNTUQ" } ], "cert_index": 27910635, "seen": 1509912803.959279, "source": { "url": "sabre.ct.comodo.com", "name": "Comodo 'Sabre' CT log" } } } ``` certstream-1.12/setup.py0000644000076500000240000000262014042340244016071 0ustar fitblipstaff00000000000000from setuptools import setup import os here = os.path.abspath(os.path.dirname(__file__)) with open('requirements.txt') as f: dependencies = f.read().splitlines() long_description = """ Certstream is a library to connect to the certstream network (certstream.calidog.io). It supports automatic reconnection when networks issues occur, and should be stable for long-running jobs. """ setup( name='certstream', version="1.12", url='https://github.com/CaliDog/certstream-python/', author='Ryan Sears', install_requires=dependencies, setup_requires=dependencies, author_email='ryan@calidog.io', description='CertStream is a library for receiving certificate transparency list updates in real time.', long_description=long_description, packages=['certstream',], include_package_data=True, entry_points={ 'console_scripts': [ 'certstream = certstream.cli:main', ], }, license = "MIT", classifiers = [ "Development Status :: 4 - Beta", "License :: OSI Approved :: MIT License", "Topic :: Internet :: WWW/HTTP", "Topic :: Security :: Cryptography", "Environment :: Console", "Operating System :: MacOS :: MacOS X", "Operating System :: POSIX", "Programming Language :: Python :: 3", "Programming Language :: Python :: 2", "Framework :: AsyncIO" ], ) certstream-1.12/setup.cfg0000644000076500000240000000004614042340421016175 0ustar fitblipstaff00000000000000[egg_info] tag_build = tag_date = 0