1
0
mirror of https://gitlab.com/fdroid/fdroidserver.git synced 2024-10-05 18:50:09 +02:00

Eliminate the need for password files

The passwords are now passed as private environment variables to the
processes that need them.
This commit is contained in:
Torsten Grote 2017-04-11 16:34:49 -03:00
parent cb942168d5
commit 4d25113fa0
No known key found for this signature in database
GPG Key ID: 3E5F77D92CF891FF
4 changed files with 46 additions and 54 deletions

View File

@ -254,10 +254,6 @@ def read_config(opts, config_file='config.py'):
fill_config_defaults(config)
for k in ["keystorepass", "keypass"]:
if k in config:
write_password_file(k)
for k in ["repo_description", "archive_description"]:
if k in config:
config[k] = clean_description(config[k])
@ -381,21 +377,6 @@ def ensure_build_tools_exists(thisconfig):
sys.exit(3)
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_TRUNC | os.O_WRONLY, 0o600)
if password is None:
os.write(fd, config[pwtype].encode('utf-8'))
else:
os.write(fd, password.encode('utf-8'))
os.close(fd)
config[pwtype + 'file'] = filename
def get_local_metadata_files():
'''get any metadata files local to an app's source repo
@ -1744,12 +1725,13 @@ def SdkToolsPopen(commands, cwd=None, output=True):
cwd=cwd, output=output)
def FDroidPopenBytes(commands, cwd=None, output=True, stderr_to_stdout=True):
def FDroidPopenBytes(commands, cwd=None, envs=None, output=True, stderr_to_stdout=True):
"""
Run a command and capture the possibly huge output as bytes.
:param commands: command and argument list like in subprocess.Popen
:param cwd: optionally specifies a working directory
:param envs: a optional dictionary of environment variables and their values
:returns: A PopenResult.
"""
@ -1757,6 +1739,10 @@ def FDroidPopenBytes(commands, cwd=None, output=True, stderr_to_stdout=True):
if env is None:
set_FDroidPopen_env()
process_env = env.copy()
if envs is not None and len(envs) > 0:
process_env.update(envs)
if cwd:
cwd = os.path.normpath(cwd)
logging.debug("Directory: %s" % cwd)
@ -1766,7 +1752,7 @@ def FDroidPopenBytes(commands, cwd=None, output=True, stderr_to_stdout=True):
result = PopenResult()
p = None
try:
p = subprocess.Popen(commands, cwd=cwd, shell=False, env=env,
p = subprocess.Popen(commands, cwd=cwd, shell=False, env=process_env,
stdout=subprocess.PIPE, stderr=stderr_param)
except OSError as e:
raise BuildException("OSError while trying to execute " +
@ -1806,15 +1792,16 @@ def FDroidPopenBytes(commands, cwd=None, output=True, stderr_to_stdout=True):
return result
def FDroidPopen(commands, cwd=None, output=True, stderr_to_stdout=True):
def FDroidPopen(commands, cwd=None, envs=None, output=True, stderr_to_stdout=True):
"""
Run a command and capture the possibly huge output as a str.
:param commands: command and argument list like in subprocess.Popen
:param cwd: optionally specifies a working directory
:param envs: a optional dictionary of environment variables and their values
:returns: A PopenResult.
"""
result = FDroidPopenBytes(commands, cwd, output, stderr_to_stdout)
result = FDroidPopenBytes(commands, cwd, envs, output, stderr_to_stdout)
result.output = result.output.decode('utf-8', 'ignore')
return result
@ -2180,18 +2167,19 @@ def genkeystore(localconfig):
if not os.path.exists(keystoredir):
os.makedirs(keystoredir, mode=0o700)
write_password_file("keystorepass", localconfig['keystorepass'])
write_password_file("keypass", localconfig['keypass'])
env_vars = {
'FDROID_KEY_STORE_PASS': localconfig['keystorepass'],
'FDROID_KEY_PASS': localconfig['keypass'],
}
p = FDroidPopen([config['keytool'], '-genkey',
'-keystore', localconfig['keystore'],
'-alias', localconfig['repo_keyalias'],
'-keyalg', 'RSA', '-keysize', '4096',
'-sigalg', 'SHA256withRSA',
'-validity', '10000',
'-storepass:file', config['keystorepassfile'],
'-keypass:file', config['keypassfile'],
'-dname', localconfig['keydname']])
# TODO keypass should be sent via stdin
'-storepass:env', 'FDROID_KEY_STORE_PASS',
'-keypass:env', 'FDROID_KEY_PASS',
'-dname', localconfig['keydname']], envs=env_vars)
if p.returncode != 0:
raise BuildException("Failed to generate key", p.output)
os.chmod(localconfig['keystore'], 0o0600)
@ -2200,15 +2188,15 @@ def genkeystore(localconfig):
p = FDroidPopen([config['keytool'], '-list', '-v',
'-keystore', localconfig['keystore'],
'-alias', localconfig['repo_keyalias'],
'-storepass:file', config['keystorepassfile']])
'-storepass:env', 'FDROID_KEY_STORE_PASS'], envs=env_vars)
logging.info(p.output.strip() + '\n\n')
# get the public key
p = FDroidPopenBytes([config['keytool'], '-exportcert',
'-keystore', localconfig['keystore'],
'-alias', localconfig['repo_keyalias'],
'-storepass:file', config['keystorepassfile']]
'-storepass:env', 'FDROID_KEY_STORE_PASS']
+ config['smartcardoptions'],
output=False, stderr_to_stdout=False)
envs=env_vars, output=False, stderr_to_stdout=False)
if p.returncode != 0 or len(p.output) < 20:
raise BuildException("Failed to get public key", p.output)
pubkey = p.output

View File

@ -69,10 +69,10 @@ def make(apps, sortedids, apks, repodir, archive):
if 'keystore' not in common.config:
nosigningkey = True
logging.critical("'keystore' not found in config.py!")
if 'keystorepass' not in common.config and 'keystorepassfile' not in common.config:
if 'keystorepass' not in common.config:
nosigningkey = True
logging.critical("'keystorepass' not found in config.py!")
if 'keypass' not in common.config and 'keypassfile' not in common.config:
if 'keypass' not in common.config:
nosigningkey = True
logging.critical("'keypass' not found in config.py!")
if not os.path.exists(common.config['keystore']):
@ -501,12 +501,13 @@ def extract_pubkey():
if 'repo_pubkey' in common.config:
pubkey = unhexlify(common.config['repo_pubkey'])
else:
env_vars = {'FDROID_KEY_STORE_PASS': common.config['keystorepass']}
p = FDroidPopenBytes([common.config['keytool'], '-exportcert',
'-alias', common.config['repo_keyalias'],
'-keystore', common.config['keystore'],
'-storepass:file', common.config['keystorepassfile']]
'-storepass:env', 'FDROID_KEY_STORE_PASS']
+ common.config['smartcardoptions'],
output=False, stderr_to_stdout=False)
envs=env_vars, output=False, stderr_to_stdout=False)
if p.returncode != 0 or len(p.output) < 20:
msg = "Failed to get repo pubkey!"
if common.config['keystore'] == 'NONE':

View File

@ -72,12 +72,9 @@ def main():
logging.warning("No unsigned directory - nothing to do")
sys.exit(1)
for f in [config['keystorepassfile'],
config['keystore'],
config['keypassfile']]:
if not os.path.exists(f):
logging.error("Config error - missing '{0}'".format(f))
sys.exit(1)
if not os.path.exists(config['keystore']):
logging.error("Config error - missing '{0}'".format(config['keystore']))
sys.exit(1)
# It was suggested at
# https://dev.guardianproject.info/projects/bazaar/wiki/FDroid_Audit
@ -175,9 +172,13 @@ def main():
# See if we already have a key for this application, and
# if not generate one...
env_vars = {
'FDROID_KEY_STORE_PASS': config['keystorepass'],
'FDROID_KEY_PASS': config['keypass'],
}
p = FDroidPopen([config['keytool'], '-list',
'-alias', keyalias, '-keystore', config['keystore'],
'-storepass:file', config['keystorepassfile']])
'-storepass:env', 'FDROID_KEY_STORE_PASS'], envs=env_vars)
if p.returncode != 0:
logging.info("Key does not exist - generating...")
p = FDroidPopen([config['keytool'], '-genkey',
@ -185,20 +186,18 @@ def main():
'-alias', keyalias,
'-keyalg', 'RSA', '-keysize', '2048',
'-validity', '10000',
'-storepass:file', config['keystorepassfile'],
'-keypass:file', config['keypassfile'],
'-dname', config['keydname']])
# TODO keypass should be sent via stdin
'-storepass:env', 'FDROID_KEY_STORE_PASS',
'-keypass:env', 'FDROID_KEY_PASS',
'-dname', config['keydname']], envs=env_vars)
if p.returncode != 0:
raise BuildException("Failed to generate key")
# Sign the application...
p = FDroidPopen([config['jarsigner'], '-keystore', config['keystore'],
'-storepass:file', config['keystorepassfile'],
'-keypass:file', config['keypassfile'], '-sigalg',
'-storepass:env', 'FDROID_KEY_STORE_PASS',
'-keypass:env', 'FDROID_KEY_PASS', '-sigalg',
'SHA1withRSA', '-digestalg', 'SHA1',
apkfile, keyalias])
# TODO keypass should be sent via stdin
apkfile, keyalias], envs=env_vars)
if p.returncode != 0:
raise BuildException("Failed to sign application")

View File

@ -40,14 +40,18 @@ def sign_jar(jar):
https://code.google.com/p/android/issues/detail?id=38321
"""
args = [config['jarsigner'], '-keystore', config['keystore'],
'-storepass:file', config['keystorepassfile'],
'-storepass:env', 'FDROID_KEY_STORE_PASS',
'-digestalg', 'SHA1', '-sigalg', 'SHA1withRSA',
jar, config['repo_keyalias']]
if config['keystore'] == 'NONE':
args += config['smartcardoptions']
else: # smardcards never use -keypass
args += ['-keypass:file', config['keypassfile']]
p = common.FDroidPopen(args)
args += ['-keypass:env', 'FDROID_KEY_PASS']
env_vars = {
'FDROID_KEY_STORE_PASS': config['keystorepass'],
'FDROID_KEY_PASS': config['keypass'],
}
p = common.FDroidPopen(args, envs=env_vars)
if p.returncode != 0:
logging.critical("Failed to sign %s!" % jar)
sys.exit(1)