debsso 2.3 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768
  1. #!/usr/bin/python3
  2. # coding: utf-8
  3. import subprocess
  4. import tempfile
  5. import requests
  6. import ssl
  7. import os
  8. class Certs:
  9. def __init__(self, workdir):
  10. self.workdir = workdir
  11. self.dbname = "sql:" + os.path.expanduser("~/.pki/nssdb")
  12. def run_certutil(self, args, input=None):
  13. cmd = ["certutil", "-d", self.dbname]
  14. cmd.extend(args)
  15. output = subprocess.check_output(cmd, universal_newlines=True, input=input)
  16. return output
  17. def run_pk12util(self, args, input=None):
  18. cmd = ["pk12util", "-d", self.dbname]
  19. cmd.extend(args)
  20. output = subprocess.check_output(cmd, universal_newlines=False, input=input)
  21. return output
  22. def get_key_nicks(self):
  23. output = self.run_certutil(["-L"])
  24. payload = output.split("\n\n")[1]
  25. for line in payload.splitlines():
  26. nick, flags = line.rsplit(None, 1)
  27. yield nick, flags
  28. def get_sso_cert_nickname(self):
  29. debemail = os.environ.get("DEBEMAIL", None)
  30. if debemail is None: raise RuntimeError("$DEBEMAIL is not set")
  31. for nick, flags in self.get_key_nicks():
  32. if flags != "u,u,u": continue
  33. if not nick.startswith(debemail): continue
  34. if not "SSO" in nick: continue
  35. return nick
  36. def get_cert(self, nick, outfile):
  37. self.run_certutil(["-L", "-n", nick, "-a", "-o", outfile])
  38. def get_key(self, nick, outfile):
  39. pkcs12 = self.run_pk12util(["-n", nick, "-o", "/dev/stdout", "-W", ""])
  40. pem = subprocess.check_output(["openssl", "pkcs12", "-nodes", "-passin", "pass:"], input=pkcs12, stderr=open("/dev/null", "wb"))
  41. with open(outfile, "wb") as out:
  42. out.write(pem)
  43. # Try to get SSO keys out of the browser and connect to nm.debian.org with
  44. # them.
  45. # Requires $DEBEMAIL to be set.
  46. # Requires libnss3-tools, openssl, python3-requests
  47. # Tested with chromium.
  48. with tempfile.TemporaryDirectory() as tmpdir:
  49. certs = Certs(tmpdir)
  50. nick = certs.get_sso_cert_nickname()
  51. #print("Nickname:", repr(nick))
  52. cert_file = os.path.join(certs.workdir, "tmp.cert")
  53. key_file = os.path.join(certs.workdir, "tmp.key")
  54. certs.get_cert(nick, cert_file)
  55. certs.get_key(nick, key_file)
  56. res = requests.get("https://nm.debian.org/api/whoami", cert=(cert_file, key_file))
  57. print(res.text)