diff --git a/TODO b/TODO index d3b7e44..31faf73 100644 --- a/TODO +++ b/TODO @@ -37,3 +37,6 @@ index 6ba2a6e..6486e11 100755 parser.add_argument('fname', nargs='?', default=None, help="Nom du fichier à afficher") +ssh-keygen -y -f ~/test_agent > test_agent.pub +ssh-add ma_cle_prive +ssh-add -d ma_cle_publique diff --git a/client.py b/client.py index ec8d29a..fbc4029 100755 --- a/client.py +++ b/client.py @@ -33,12 +33,14 @@ try: sys.path.append(os.path.expanduser("~/.config/%s/" % (bootstrap_cmd_name,))) import clientconfig as config except ImportError: - ducktape_display_error = sys.stderr.isatty() and not any([opt in sys.argv for opt in ["-q", "--quiet"]]) + ducktape_display_error = sys.stderr.isatty() and \ + not any([opt in sys.argv for opt in ["-q", "--quiet"]]) and \ + __name__ == '__main__' envspecified = os.getenv(envvar, None) if envspecified is None: if ducktape_display_error: sys.stderr.write(u"Va lire le fichier README.\n".encode("utf-8")) - sys.exit(1) + sys.exit(1) else: # On a spécifié à la main le dossier de conf try: diff --git a/clientconfigs/tudor/clientconfig.py b/clientconfigs/tudor/clientconfig.py index d8120df..007a2fa 100644 --- a/clientconfigs/tudor/clientconfig.py +++ b/clientconfigs/tudor/clientconfig.py @@ -1,9 +1,32 @@ #!/usr/bin/env python # -*- encoding: utf-8 -*- +""" Configuration du client cranspasswords """ + +import os + + +#: Liste des serveurs sur lesquels ont peut récupérer des mots de passe. +#: +#: Sans précision du paramètre --server, la clé ``'default'`` sera utilisée. +#: +#: * ``'server_cmd'`` : La commande exécutée sur le client pour appeler +#: le script sur le serveur distant. servers = { 'default': { 'server_cmd': ['/home/dstan/cranspasswords/serverconfigs/tudor/cpasswords-server', ], - 'keep-alive': True, # <-- experimental, n'ouvre qu'une connexion - } + 'keep-alive': True, + }, + 'gladys': { + 'server_cmd': ['/usr/bin/ssh', 'home.b2moo.fr', '/home/dstan/cranspasswords/serverconfigs/tudor/cpasswords-server', ], + 'keep-alive': True, + }, + 'gladys-home': { + 'server_cmd': ['/usr/bin/ssh', 'gladys.home', '/home/dstan/cranspasswords/serverconfigs/tudor/cpasswords-server', ], + 'keep-alive': True, + }, + 'pimeys': { + 'server_cmd': ['/usr/bin/ssh', 'pimeys.fr', 'sudo', '-n', '/usr/local/bin/cranspasswords-server', ], + 'keep-alive': True, + }, } diff --git a/cpasswords/clientlib.py b/cpasswords/clientlib.py new file mode 100644 index 0000000..247df05 --- /dev/null +++ b/cpasswords/clientlib.py @@ -0,0 +1,25 @@ +# -*- coding: utf-8 -*- + +"""Client class definition for cpasswords protocol. + +(WIP) +""" + +from cpasswords import client as _old_client + +class Client(object): + """A client connection.""" + + verbose = False + + def __init__(self, serverdata): + """ + serverdata should be a classic dict object (from eg a clientconfig + module) + """ + self.serverdata = serverdata + + def put_file(self, data): + """Send file to server""" + # TODO put code here + _old_client.put_files(self, [data]) diff --git a/server.py b/server.py index a26c2fd..d0f5bd1 100755 --- a/server.py +++ b/server.py @@ -17,10 +17,19 @@ import itertools from email.mime.text import MIMEText from email.mime.multipart import MIMEMultipart +try: + from cpasswords import clientlib +except ImportError: + print("Couldn't import clientlib. Remote sync may not work") + # Même problème que pour le client, il faut bootstraper le nom de la commande # Pour accéder à la config -cmd_name = os.path.split(sys.argv[0])[1].replace("-server", "") -sys.path.append("/etc/%s/" % (cmd_name,)) +conf_path = os.getenv('CRANSPASSWORDS_SERVER_CONFIG_DIR', None) +if not conf_path: + cmd_name = os.path.split(sys.argv[0])[1].replace("-server", "") + conf_path = "/etc/%s/" % (cmd_name,) + +sys.path.append(conf_path) import serverconfig MYUID = pwd.getpwuid(os.getuid())[0] @@ -190,6 +199,11 @@ def _putfile(filename, roles, contents): # Or fuck yourself writefile(filepath, json.dumps({'roles': roles, 'contents': contents})) + + data = {'filename': filename, 'roles': roles, 'contents': contents} + for client in _list_to_replicate(data): + client.put_file(data) + return [True, u"Modification effectuée."] @server_command('putfile', stdin_input=True, write=True) @@ -228,7 +242,7 @@ def rmfile(filename): if validate(roles, 'w'): corps = u"Le fichier %s a été supprimé par %s." % (filename, MYUID) backup(corps, filename, old) - notification(u"Suppression", fname, MYUID) + notification(u"Suppression", filename, MYUID) os.remove(getpath(filename)) else: return u"Vous n'avez pas les droits d'écriture sur le fichier %s." % filename @@ -245,6 +259,16 @@ def backup(corps, fname, old): back.write((u'* %s: %s\n' % (str(datetime.datetime.now()), corps)).encode("utf-8")) back.close() +def _list_to_replicate(data): + """Renvoie une liste d'options clients sur lesquels appliquer relancer + la procédure (pour réplication auto)""" + roles = data.get('roles', []) + backups = getattr(serverconfig, 'BACKUP_ROLES', {}) + servers = getattr(serverconfig, 'BACKUP_SERVERS', {}) + + configs = set(name for role in roles for name in backups.get(role, [])) + return [ clientlib.Client(servers[name]) for name in configs ] + _notif_todo = [] def notification(action, fname, actor): """Enregistre une notification""" diff --git a/serverconfigs/tudor/.gitignore b/serverconfigs/tudor/.gitignore deleted file mode 100644 index 23cf86a..0000000 --- a/serverconfigs/tudor/.gitignore +++ /dev/null @@ -1 +0,0 @@ -cpasswords-server diff --git a/serverconfigs/tudor/cpasswords-server b/serverconfigs/tudor/cpasswords-server new file mode 100755 index 0000000..038c71b --- /dev/null +++ b/serverconfigs/tudor/cpasswords-server @@ -0,0 +1,12 @@ +#!/bin/bash + +# Où trouver le paquet python +PKG_DIR=~/cranspasswords + +# Où trouver la conf serveur +CONF=$PKG_DIR/serverconfigs/tudor + +# Binaire python +PYTHON=/usr/bin/python + +/usr/bin/env PYTHONPATH=$PKG_DIR CRANSPASSWORDS_SERVER_CONFIG_DIR=$CONF $PYTHON $PKG_DIR/cpasswords/server.py "$@" diff --git a/serverconfigs/tudor/serverconfig.py b/serverconfigs/tudor/serverconfig.py index 99cf6ca..7c4e714 100755 --- a/serverconfigs/tudor/serverconfig.py +++ b/serverconfigs/tudor/serverconfig.py @@ -30,10 +30,22 @@ KEYS = { } -ME = [u'dstan'] +_ME = [u'dstan'] #: Les roles utilisés pour savoir qui a le droit le lire/écrire quoi ROLES = { - 'moi': ME, - 'moi-w': ME, + 'moi': _ME, + 'moi-w': _ME, +} + +BACKUP_SERVERS = { + 'gladys': { + 'server_cmd': ['/usr/bin/ssh', 'home.b2moo.fr', '/home/dstan/cranspasswords/serverconfigs/tudor/cpasswords-server', ], + 'keep-alive': True, + }, +} + + +BACKUP_ROLES = { + 'moi': ['gladys'], }