Skip to content

Instantly share code, notes, and snippets.

@ostcar
Last active August 29, 2015 14:27
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save ostcar/fe10106e511499737053 to your computer and use it in GitHub Desktop.
Save ostcar/fe10106e511499737053 to your computer and use it in GitHub Desktop.
Anleitung zum versenden der eigenen Passwörter an eine Vertrauensperson (in german)

Key Export

Mit dieser Anleitung wird erklärt, wie Passwörter an vertrauensvolle Personen verteilt werden können.

Hintergrund

Nach dem hier beschriebenen System werden alle Passwörter nicht nur mit dem eigenen, sondern auch mit dem private GPG-Key von einer Vertrauensperson verschlüsselt. Hierbei liegen alle verschlüsselten Passwörter in einem git-repository. Mittels git bundle werden alle Änderungen an den eigenen Passwörtern (neue Passwörter, geänderte Passwörter, etc) in eine unabhängige Datei exportiert, die an die Vertrauensperson geschickt werden kann.

Voraussetzung

Voraussetzung für diese Anleitung ist, dass die eigenen Passwörter mittels pass[1] gespeichert werden. Hierbei muss pass so konfiguriert sein, dass es alle Änderungen mit git speichert.

[1] http://www.passwordstore.org/

Einrichtung

Auf dem eigenen Rechner

pass init EIGENE_KEY_ID FREMDE_KEY_ID

Hierdurch werden alle vorhandenen Passwörter neu verschlüsselt, so dass sie von beiden GPG-Keys gelesen werden können.

pass git bundle create DATEI_NAME master

Hierdurch wird die Datei DATEI_NAME angelegt, welche das komplette git repo enthält.

pass git tag -f last_FREMDE_KEY_ID master

Hierdurch wird ein Tag auf den aktuellen master angelegt, um später nachvollziehen zu können, auf welchem stand das fremde Repo ist.

Als nächstes muss die Datei DATEI_NAME an die Vertrauensperson geschickt werden.

Auf dem fremden Rechner

git clone -m master DATEI_NAME PFAD

Nachdem die Datei an den fremden PC übermittelt wurde, kann sie mit diesem Befehl wieder in ein git Repo umgewandelt werden.

Regelmäßige Updates

Auf dem eigenen Rechner

pass git bundle create DATEI_NAME last_FREMDE_KEY_ID..master pass git tag -f last_FREMDE_KEY_ID master

Mit diesen Befehlen wird eine neue Datei DATEI_NAME erstellt, welche alle commits seit der letzten Datenübertragung enthält.

Als nächstes muss die Datei DATEI_NAME an die Vertrauensperson geschickt werden.

Auf dem fremden Rechner

git bundle unbundle DATEI_NAME

Dieser Befehl muss innerhalb des oben erstellten Repositories erstellt werden.

Auf Passwörter zugreifen

PASSWORD_STORE_DIR=/PFAD/ZUM/GIT/REPO pass 0_README

Die Vertrauensperson kann auf die übermittelten Passwörter wie gewohnt mittels pass zugreifen. Jedoch muss die environment Variable PASSWORD_STORE_DIR auf den Ort zeigen, in welchem die fremden Passwörter ausgecheckt sind.

Sicherheitshinweise

pass verschlüsselt lediglich die Dateien, jedoch nicht die Dateinamen. Alle Daten die mittels pass list angezeigt werden, kann daher auch von jeder Person gelesen werden, welche zugriff auf die git bundles erhält. Die Dateinamen sollten daher keine sensiblen Informationen enthalten und die bundle Dateien sicherheitshalber nur verschlüsselt übertragen werden.

# TODO: * send file via mail
# * do "pass init EIGENE_KEY_ID FREMDE_KEY_ID"
# * Add functions to import the file
import os
import sys
from gnupg import GPG
from git import Repo
# TODO: Use the environment variable to find the homedir
# The documentation of gnupg says, that if homedir is None, it uses the
# the default. But this does not work. 2015-08-15 by ostcar
gpg = GPG(homedir=os.path.expanduser("~/.gnupg"))
# TODO: Use environment variables or get_pass_dir()
repo = Repo(os.path.expanduser('~/.password-store/'))
def get_pass_dir():
"""
Returns the path to the password store dir.
"""
value = os.getenv("PASSWORD_STORE_DIR")
if value is None:
value = os.path.expanduser("~/.password-store")
return value
def get_gpg_secret_key_ids():
"""
Returns a set with all secret gpg key ids.
"""
return set(key['keyid'] for key in gpg.list_keys(secret=True))
def get_pass_other_keys():
"""
Returns a set that conatins the gpg ids used by pass, except the own keys
"""
# TODO: This function expects, that the gpg key id in the pass file is in
# the long form (16 digets). Fix this so it also works for the 8
# digits version.
gpg_secret_key_ids = get_gpg_secret_key_ids()
key_ids = set()
with open(os.path.join(get_pass_dir(), '.gpg-id')) as f:
for line in f.readlines():
line = line.strip()
if line not in gpg_secret_key_ids:
key_ids.add(line)
return key_ids
def get_name_from_key_id(key_id):
"""
Returns the name of the person owning the key for key_id.
Uses the first uuid if the key and replaces each space by a '_'.
"""
for key in gpg.list_keys():
# TODO: support key ids with 8 digits
if key['keyid'] == key_id:
uuid = key['uids'][0]
# TODO: use regex
return uuid.partition('<')[0].strip().lower().replace(' ', '_')
def generate_git_bundle(key_id, filename):
"""
Generates the git bundle containing all commits since the last call.
key_id: The gnupg id to use as reference.
filename: Path to a file to save the bundle.
"""
tag_name = "last_{}".format(key_id)
try:
tag = repo.tags[tag_name]
except IndexError:
# Tag does not exist. Create a bundle over the whole repo.
# sufix -- to the ref. This is important if there is a file named
# 'master' in the repo
bundle_ref = 'master'
else:
bundle_ref = '{}..master'.format(tag_name)
repo.git.bundle('create', filename, bundle_ref, '--')
# TODO: Set the argument "ref" explicit to the same commit that was used
# for the bundle in the last line. The master-commit could have
# changed
repo.create_tag(tag_name, force=True)
def main():
# TODO: set the filename via argparse
for key_id in get_pass_other_keys():
filename = os.path.expanduser(
"~/{}.bundle".format(get_name_from_key_id(key_id)))
generate_git_bundle(
key_id,
filename)
if __name__ == '__main__':
main()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment