Try to prevent 'certificate leaks' when visiting a new domain with an active client cert.

This commit is contained in:
Solderpunk 2020-05-10 13:44:40 +02:00
parent a2aff0d2a5
commit 6bb2e20e69
1 changed files with 19 additions and 0 deletions

19
av98.py
View File

@ -219,6 +219,7 @@ class GeminiClient(cmd.Cmd):
self.client_certs = { self.client_certs = {
"active": None "active": None
} }
self.active_cert_domains = []
self.options = { self.options = {
"debug" : False, "debug" : False,
@ -261,6 +262,17 @@ class GeminiClient(cmd.Cmd):
new_gi = GeminiItem(self.permanent_redirects[gi.url], name=gi.name) new_gi = GeminiItem(self.permanent_redirects[gi.url], name=gi.name)
self._go_to_gi(new_gi) self._go_to_gi(new_gi)
return return
# Be careful with client certificates
if self.active_cert_domains and gi.host not in self.active_cert_domains:
print("PRIVACY ALERT: Deactivate client cert before connecting to a new domain?")
resp = input("Y/N? ")
if resp.lower in ("n", "no"):
print("Keeping certificate active for {}".format(gi.host))
else:
print("Deactivating certificate.")
self.client_certs["active"] = None
self.active_cert_domains = []
self.prompt = self.no_cert_prompt
# Do everything which touches the network in one block, # Do everything which touches the network in one block,
# so we only need to catch exceptions once # so we only need to catch exceptions once
try: try:
@ -465,6 +477,11 @@ Slow internet connection? Use 'set timeout' to be more patient.""")
self._debug("Established {} connection.".format(s.version())) self._debug("Established {} connection.".format(s.version()))
self._debug("Cipher is: {}.".format(s.cipher())) self._debug("Cipher is: {}.".format(s.cipher()))
# Remember that we showed the current cert to this domain...
if self.client_certs["active"]:
self.active_cert_domains.append(gi.host)
self.client_certs[gi.host] = self.client_certs["active"]
# Send request and wrap response in a file descriptor # Send request and wrap response in a file descriptor
self._debug("Sending %s<CRLF>" % gi.url) self._debug("Sending %s<CRLF>" % gi.url)
s.sendall((gi.url + CRLF).encode("UTF-8")) s.sendall((gi.url + CRLF).encode("UTF-8"))
@ -677,6 +694,7 @@ Slow internet connection? Use 'set timeout' to be more patient.""")
if self.client_certs["active"]: if self.client_certs["active"]:
print("Deactivating client certificate.") print("Deactivating client certificate.")
self.client_certs["active"] = None self.client_certs["active"] = None
self.active_cert_domains = []
self.prompt = self.no_cert_prompt self.prompt = self.no_cert_prompt
else: else:
print("Loading client certificate file, in PEM format (blank line to cancel)") print("Loading client certificate file, in PEM format (blank line to cancel)")
@ -684,6 +702,7 @@ Slow internet connection? Use 'set timeout' to be more patient.""")
print("Loading private key file, in PEM format (blank line to cancel)") print("Loading private key file, in PEM format (blank line to cancel)")
keyfile = input("Keyfile path: ") keyfile = input("Keyfile path: ")
self.client_certs["active"] = (certfile, keyfile) self.client_certs["active"] = (certfile, keyfile)
self.active_cert_domains = []
self.prompt = self.cert_prompt self.prompt = self.cert_prompt
@restricted @restricted