Files
@ c01402cc810c
Branch filter:
Location: C3L-NOC/tls-expiry-tracker/backend/tls_utils.py - annotation
c01402cc810c
4.1 KiB
text/x-python
feat: web is now https, which is a special case of tls
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 | d0238a1adb40 d0238a1adb40 d0238a1adb40 d0238a1adb40 b3456703e541 b3456703e541 b3456703e541 b3456703e541 b3456703e541 d0238a1adb40 d0238a1adb40 769134152475 d0238a1adb40 b3456703e541 d0238a1adb40 769134152475 d0238a1adb40 769134152475 d0238a1adb40 b3456703e541 d969304ee9cb 769134152475 769134152475 769134152475 d0238a1adb40 b3456703e541 aea800cedcbd b3456703e541 aea800cedcbd d0238a1adb40 769134152475 769134152475 769134152475 769134152475 769134152475 769134152475 769134152475 769134152475 769134152475 769134152475 769134152475 769134152475 769134152475 769134152475 769134152475 769134152475 769134152475 769134152475 769134152475 769134152475 769134152475 769134152475 769134152475 769134152475 769134152475 769134152475 769134152475 769134152475 769134152475 769134152475 769134152475 769134152475 769134152475 769134152475 769134152475 769134152475 769134152475 769134152475 769134152475 769134152475 769134152475 769134152475 769134152475 769134152475 769134152475 769134152475 769134152475 769134152475 769134152475 769134152475 769134152475 769134152475 769134152475 769134152475 769134152475 769134152475 769134152475 d0238a1adb40 769134152475 769134152475 769134152475 769134152475 c11dd0c93877 c11dd0c93877 c11dd0c93877 c11dd0c93877 769134152475 769134152475 769134152475 769134152475 769134152475 769134152475 769134152475 769134152475 769134152475 | #!/usr/bin/env python3
from rich.console import Console
import datetime
EXPIRED = 10
REVOKED = 23
SELF_SIGNED = 18
ROOT_NOT_TRUSTED = 19
class TLSDetails:
domain_name = None
expiry_timestamp_utc = None
error_message = None
connection_error = False
def __init__(self, domain_name : str = None, expiry_timestamp_utc : int = None, error_message : str = None, connection_error : bool = False):
self.domain_name = domain_name
self.expiry_timestamp_utc = expiry_timestamp_utc
self.error_message = error_message
self.connection_error = connection_error
# Green - Valid
# Orange - Non-TLS error
# Red - TLS error
def print(self, console: Console):
if self.connection_error:
console.log("[bold underline]" + self.domain_name, self.error_message, style="orange")
elif self.error_message != None:
console.log("[bold underline]" + self.domain_name, self.error_message, style="red")
else:
msg, future = self.relative_time_comparison()
if not future:
console.log("[bold underline]" + self.domain_name, "expired", msg + ".", style="red")
else:
console.log("[bold underline]" + self.domain_name, "expires", msg + ".", style="green")
def is_valid(self) -> bool:
if self.connection_error:
return None
return (self.error_message is None) and (not self.is_expired())
def is_expired(self) -> bool:
if self.expiry_timestamp_utc is None:
return True
now_timestamp = datetime.datetime.now(datetime.UTC).timestamp()
# notAfter, so it includes the second itself
return now_timestamp >= self.expiry_timestamp_utc
# Returns a human-readable relative string, and if the date is future (true) or past (false)
def relative_time_comparison(self, now = datetime.datetime.now(datetime.UTC).timestamp()) -> tuple[str, bool]:
if self.expiry_timestamp_utc is None:
return ""
diff = round(self.expiry_timestamp_utc) - round(now)
future = diff > 0
seconds_diff = int(abs(diff))
minutes_diff = seconds_diff // 60
hours_diff = minutes_diff // 60
days_diff = hours_diff // 24
months_diff = days_diff // 30
msg = ""
if months_diff > 0:
days_diff = days_diff % 30
msg += str(months_diff) + " month" + ("s" if months_diff > 1 else "")
if future and months_diff < 3 and days_diff > 0:
msg += " and " + str(days_diff) + " day" + ("s" if days_diff > 1 else "")
elif days_diff > 0:
msg += str(days_diff) + " day" + ("s" if days_diff > 1 else "")
elif hours_diff > 0:
msg += str(hours_diff) + " hour" + ("s" if hours_diff > 1 else "")
elif minutes_diff > 0:
msg += str(minutes_diff) + " minute" + ("s" if minutes_diff > 1 else "")
elif seconds_diff > 0:
msg += str(seconds_diff) + " second" + ("s" if seconds_diff > 1 else "")
else:
msg = "now"
if future:
if seconds_diff > 0:
msg = "in " + msg
else:
if seconds_diff > 0:
msg = msg + " ago"
return (msg, future)
def get_cert_expiry_timestamp(cert) -> int:
notAfter = cert['notAfter']
notAfter_date = datetime.datetime.strptime(notAfter, '%b %d %H:%M:%S %Y %Z').astimezone(datetime.UTC)
return notAfter_date.timestamp()
# Test expiry checking (timestamps)
if __name__ == "__main__":
console = Console()
test = TLSDetails(domain_name="now.example.org", expiry_timestamp_utc=datetime.datetime.now(datetime.UTC).timestamp())
console.log("Now: ", test.relative_time_comparison())
test = TLSDetails(domain_name="past.example.org", expiry_timestamp_utc=datetime.datetime.now(datetime.UTC).timestamp() - 1)
console.log("Past: ", test.relative_time_comparison())
test = TLSDetails(domain_name="future.example.org", expiry_timestamp_utc=datetime.datetime.now(datetime.UTC).timestamp() + 1)
console.log("Future: ", test.relative_time_comparison())
|