2 # -*- mode: python; coding: utf-8-unix; -*-
5 import argparse, errno, os, readline, subprocess, sys, tempfile, textwrap
8 if sys.version_info[0] == 2:
9 def input_string (prompt=""):
10 return raw_input (prompt)
11 elif sys.version_info[0] > 2:
12 def input_string (prompt=""):
15 raise Exception ("Unsupported Python version {}".format (sys.version_info))
19 return textwrap.dedent (text).strip ()
23 return textwrap.fill (dedented (text), width = 72)
26 def read_input_string (prompt="", default=""):
28 readline.set_startup_hook (lambda: readline.insert_text (default))
31 return input_string(prompt)
33 readline.set_startup_hook()
36 def parse_arguments ():
37 parser = argparse.ArgumentParser ()
42 version = "crypto-install.py version GIT-TAG (GIT-COMMIT/GIT-BRANCH)",
43 help = "Display version.")
44 gnupg_group = parser.add_argument_group ("GnuPG",
45 "Options related to the GnuPG setup.")
46 gnupg_group.add_argument (
49 action = "store_false",
50 help = "Disable GnuPG setup.")
51 gnupg_group.add_argument (
56 help = "Default directory for GnuPG files.")
57 openssh_group = parser.add_argument_group ("OpenSSH",
58 "Options related to the OpenSSH setup.")
59 openssh_group.add_argument (
62 action = "store_false",
63 help = "Disable OpenSSH setup.")
64 openssh_group.add_argument (
66 dest = "openssh_home",
69 help = "Default directory for OpenSSH files.")
70 return parser.parse_args ()
73 def ensure_directories (path, mode = 0o777):
75 os.makedirs (path, mode)
76 except OSError as exception:
77 if exception.errno != errno.EEXIST:
81 def gnupg_setup (arguments):
82 gnupg_home = os.path.expanduser (arguments.gnupg_home)
83 gnupg_secring = os.path.join (gnupg_home, "secring.gpg")
85 if os.path.exists (gnupg_secring):
86 print ("GnuPG secret keyring already exists at {!r}."
87 .format (gnupg_secring))
91 No default GnuPG key available. Please enter your information to
92 create a new key."""))
94 default_name = os.getenv ("FULLNAME")
95 name = read_input_string ("What is your name? ", default_name)
97 default_email = os.getenv ("EMAIL")
98 email = read_input_string ("What is your email address? ", default_email)
100 comment = read_input_string ("What is your comment phrase, if any (e.g. 'key for 2014')? ")
102 if not os.path.exists (gnupg_home):
103 print ("Creating GnuPG directory at {!r}.".format (gnupg_home))
104 ensure_directories (gnupg_home, 0o700)
106 with tempfile.NamedTemporaryFile () as tmp:
107 batch_key = dedented ("""
116 """).format (name, email)
119 batch_key += "\nName-Comment: {}\n".format (comment)
121 tmp.write (batch_key)
124 batch_env = dict(os.environ)
125 del batch_env["DISPLAY"]
127 gnupg_process = subprocess.Popen (["gpg2", "--homedir", gnupg_home, "--batch", "--gen-key", tmp.name],
129 gnupg_process.wait ()
131 if gnupg_process.returncode != 0:
132 raise Exception ("Couldn't create GnuPG key.")
135 def openssh_setup (arguments):
136 openssh_home = os.path.expanduser (arguments.openssh_home)
137 openssh_config = os.path.join (openssh_home, "config")
139 if not os.path.exists (openssh_config):
140 print ("Creating OpenSSH directory at {!r}.".format (openssh_home))
141 ensure_directories (openssh_home, 0o700)
143 print ("Creating OpenSSH configuration at {!r}.".format (openssh_config))
144 with open (openssh_config, "w") as config:
145 config.write (dedented ("""
150 openssh_key = os.path.join (openssh_home, "id_rsa")
152 if os.path.exists (openssh_key):
153 print ("OpenSSH key already exists at {!r}.".format (openssh_key))
156 print (filled ("No OpenSSH key available. Generating new key."))
158 openssh_process = subprocess.Popen (["ssh-keygen", "-f", openssh_key])
159 openssh_process.wait ()
161 if openssh_process.returncode != 0:
162 raise Exception ("Couldn't create OpenSSH key.")
166 arguments = parse_arguments ()
169 gnupg_setup (arguments)
171 if arguments.openssh:
172 openssh_setup (arguments)
175 if __name__ == "__main__":