From: Hans-Christoph Steiner Date: Tue, 1 Apr 2014 01:02:42 +0000 (-0400) Subject: stop passing passphrases via args, instead use prepared files X-Git-Tag: 0.2~155^2~2 X-Git-Url: http://www.chiark.greenend.org.uk/ucgi/~ianmdlvl/git?a=commitdiff_plain;h=525759b235f20f5f21dc8af5d5e7626a68639bfe;p=fdroidserver.git stop passing passphrases via args, instead use prepared files Any process can read the process table, and can therefore see the entire command line of any other process. That means its a bad idea to ever put passwords as part of a command line. Python is executing keytool and jarsigner command lines here, so now instead of putting the password on the command line, a file is passed instead with suitable file permissions. This should reduce the exposure a lot. But still, sensitive passwords should not be written to any text file. This change requires OpenJDK-7 since the :file option to -storepass and -keypass was only added in Java 7's keytool and jarsigner. --- diff --git a/fdroidserver/common.py b/fdroidserver/common.py index 5014a0be..a89bfdc3 100644 --- a/fdroidserver/common.py +++ b/fdroidserver/common.py @@ -94,8 +94,26 @@ def read_config(opts, config_file='config.py'): if st.st_mode & stat.S_IRWXG or st.st_mode & stat.S_IRWXO: logging.warn("unsafe permissions on {0} (should be 0600)!".format(config_file)) + for k in ["keystorepass", "keypass"]: + if k in config: + write_password_file(k) + return config +def write_password_file(pwtype, password=None): + ''' + writes out passwords to a protected file instead of passing passwords as + command line argments + ''' + filename = '.fdroid.' + pwtype + '.txt' + fd = os.open(filename, os.O_CREAT | os.O_WRONLY, 0600) + if password == None: + os.write(fd, config[pwtype]) + else: + os.write(fd, password) + os.close(fd) + config[pwtype + 'file'] = filename + # Given the arguments in the form of multiple appid:[vc] strings, this returns # a dictionary with the set of vercodes specified for each package. def read_pkg_args(args, allow_vercodes=False): diff --git a/fdroidserver/init.py b/fdroidserver/init.py index 0c33400c..4a02e9a4 100644 --- a/fdroidserver/init.py +++ b/fdroidserver/init.py @@ -56,12 +56,15 @@ def genpassword(): def genkey(keystore, repo_keyalias, password, keydname): '''generate a new keystore with a new key in it for signing repos''' logging.info('Generating a new key in "' + keystore + '"...') + write_password_file("keystorepass", password) + write_password_file("keypass", password) p = FDroidPopen(['keytool', '-genkey', '-keystore', keystore, '-alias', repo_keyalias, '-keyalg', 'RSA', '-keysize', '4096', '-sigalg', 'SHA256withRSA', '-validity', '10000', - '-storepass', password, '-keypass', password, + '-storepass:file', config['keystorepassfile'], + '-keypass:file', config['keypassfile'], '-dname', keydname]) if p.returncode != 0: raise BuildException("Failed to generate key", p.stdout) diff --git a/fdroidserver/publish.py b/fdroidserver/publish.py index c7878d51..1c241501 100644 --- a/fdroidserver/publish.py +++ b/fdroidserver/publish.py @@ -122,23 +122,23 @@ def main(): # if not generate one... p = FDroidPopen(['keytool', '-list', '-alias', keyalias, '-keystore', config['keystore'], - '-storepass', config['keystorepass']]) + '-storepass:file', config['keystorepass']]) if p.returncode !=0: logging.info("Key does not exist - generating...") p = FDroidPopen(['keytool', '-genkey', '-keystore', config['keystore'], '-alias', keyalias, '-keyalg', 'RSA', '-keysize', '2048', '-validity', '10000', - '-storepass', config['keystorepass'], - '-keypass', config['keypass'], + '-storepass:file', config['keystorepassfile'], + '-keypass:file', config['keypassfile'], '-dname', config['keydname']]) if p.returncode != 0: raise BuildException("Failed to generate key") # Sign the application... p = FDroidPopen(['jarsigner', '-keystore', config['keystore'], - '-storepass', config['keystorepass'], - '-keypass', config['keypass'], '-sigalg', + '-storepass:file', config['keystorepassfile'], + '-keypass:file', config['keypassfile'], '-sigalg', 'MD5withRSA', '-digestalg', 'SHA1', apkfile, keyalias]) if p.returncode != 0: diff --git a/fdroidserver/update.py b/fdroidserver/update.py index 939af587..55d4b0e2 100644 --- a/fdroidserver/update.py +++ b/fdroidserver/update.py @@ -642,7 +642,7 @@ def make_index(apps, apks, repodir, archive, categories): p = FDroidPopen(['keytool', '-exportcert', '-alias', config['repo_keyalias'], '-keystore', config['keystore'], - '-storepass', config['keystorepass']]) + '-storepass:file', config['keystorepassfile']]) if p.returncode != 0: logging.critical("Failed to get repo pubkey") sys.exit(1) @@ -796,7 +796,8 @@ def make_index(apps, apks, repodir, archive, categories): # Sign the index... p = FDroidPopen(['jarsigner', '-keystore', config['keystore'], - '-storepass', config['keystorepass'], '-keypass', config['keypass'], + '-storepass:file', config['keystorepassfile'], + '-keypass:file', config['keypassfile'], '-digestalg', 'SHA1', '-sigalg', 'MD5withRSA', os.path.join(repodir, 'index.jar') , config['repo_keyalias']]) if p.returncode != 0: diff --git a/sampleconfigs/config.py b/sampleconfigs/config.py index 0e1919db..56b37ca6 100644 --- a/sampleconfigs/config.py +++ b/sampleconfigs/config.py @@ -62,12 +62,16 @@ repo_keyalias = None #somewhere safe and secure, and backed up! keystore = "/home/me/somewhere/my.keystore" -#The password for the keystore (at least 6 characters). -keystorepass = "password1" - -#The password for keys - the same is used for each auto-generated key -#as well as for the repository key. -keypass = "password2" +# The password for the keystore (at least 6 characters). If this password is +# different than the keypass below, it can be OK to store the password in this +# file for real use. But in general, sensitive passwords should not be stored +# in text files! +#keystorepass = "password1" + +# The password for keys - the same is used for each auto-generated key as well +# as for the repository key. You should not normally store this password in a +# file since it is a sensitive password. +#keypass = "password2" #The distinguished name used for all keys. keydname = "CN=Birdman, OU=Cell, O=Alcatraz, L=Alcatraz, S=California, C=US"