Commit 167e9887 authored by Vincent Le gallic's avatar Vincent Le gallic

Doc sphinx-like serveur

parent 44e7b1a6
#!/usr/bin/env python
# -*- encoding: utf-8 -*-
"""Configuration du client cranspasswords"""
import os
#: Serveurs distants utilisables,
#: avec la commande distante à exécuter et l'username sur le serveur
servers = {
'default': {
'server_cmd': ['/usr/bin/ssh', 'vert.adm.crans.org',\
......@@ -17,4 +21,3 @@ servers = {
# n'ayant pas le même login sur leur pc
}
}
#!/bin/bash
# sudo-wrapper pour exécuter cranspasswords côté serveur
sudo /root/cranspasswords/server.py $*
#!/usr/bin/env python
# -*- encoding: utf-8 -*-
"""cranspasswords-server.py: Serveur pour cranspasswords"""
"""Serveur pour cranspasswords"""
import glob
import os
......@@ -18,22 +19,23 @@ MYUID = pwd.getpwuid(os.getuid())[0]
if MYUID == 'root':
MYUID = os.environ['SUDO_USER']
def validate(roles,mode='r'):
"""Valide que l'appelant appartient bien aux roles précisés
def validate(roles, mode='r'):
"""Vérifie que l'appelant appartient bien aux roles précisés
Si mode mode='w', recherche un rôle en écriture
"""
for role in roles:
if mode == 'w': role+='-w'
if mode == 'w':
role += '-w'
if ROLES.has_key(role) and MYUID in ROLES[role]:
return True
return False
def getpath(filename,backup=False):
"""Récupère le chemin du fichier `filename'"""
return os.path.join(STORE, '%s.%s' % (filename,'bak' if backup else 'json'))
def getpath(filename, backup=False):
"""Récupère le chemin du fichier ``filename``"""
return os.path.join(STORE, '%s.%s' % (filename, 'bak' if backup else 'json'))
def writefile(filename, contents):
"""Écrit le fichier de manière sécure"""
"""Écrit le fichier avec les bons droits UNIX"""
os.umask(0077)
f = open(filename, 'w')
f.write(contents)
......@@ -44,26 +46,22 @@ def listroles():
return ROLES
def listkeys():
"""Liste les uid et les clés correspondantes"""
"""Liste les usernames et les (mail, fingerprint) correspondants"""
return KEYS
def listfiles():
"""Liste les fichiers dans l'espace de stockage, et les roles qui peuvent y accéder"""
os.chdir(STORE)
filenames = glob.glob('*.json')
files = {}
for filename in filenames:
file_dict = json.loads(open(filename).read())
files[filename[:-5]] = file_dict["roles"]
return files
def getfile(filename):
"""Récupère le fichier `filename'"""
"""Récupère le fichier ``filename``"""
filepath = getpath(filename)
try:
obj = json.loads(open(filepath).read())
......@@ -75,19 +73,16 @@ def getfile(filename):
def putfile(filename):
"""Écrit le fichier `filename' avec les données reçues sur stdin."""
"""Écrit le fichier ``filename`` avec les données reçues sur stdin."""
filepath = getpath(filename)
stdin = sys.stdin.read()
parsed_stdin = json.loads(stdin)
try:
roles = parsed_stdin['roles']
contents = parsed_stdin['contents']
except KeyError:
return False
try:
old = getfile(filename)
oldroles = old['roles']
......@@ -98,9 +93,9 @@ def putfile(filename):
if not validate(oldroles,'w'):
return False
notification("Modification de %s" % filename,\
"Le fichier %s a été modifié par %s." %\
(filename,MYUID),filename,old)
notification("Modification de %s" % filename,
"Le fichier %s a été modifié par %s." % (filename, MYUID),
filename, old)
writefile(filepath, json.dumps({'roles': roles, 'contents': contents}))
......@@ -123,22 +118,22 @@ def rmfile(filename):
return False
return True
def notification(subject,corps,fname,old):
back = open(getpath(fname,True),'a')
def backup(fname, old):
"""Backupe l'ancienne version du fichier"""
back = open(getpath(fname, backup=True), 'a')
back.write(json.dumps(old))
back.write('\n')
back.write('* %s: %s\n' % (str(datetime.datetime.now()),corps))
back.close()
# Puis envoi du message
def notification(subject, corps, fname, old):
"""Envoie par mail une notification de changement de fichier"""
conn = smtplib.SMTP('localhost')
frommail = CRANSP_MAIL
tomail = DEST_MAIL
msg = MIMEMultipart(_charset="utf-8")
msg['Subject'] = subject
msg['X-Mailer'] = "cranspasswords"
# me == the sender's email address
# family = the list of all recipients' email addresses
msg['From'] = CRANSP_MAIL
msg['To'] = DEST_MAIL
msg.preamble = "cranspasswords report"
......@@ -167,7 +162,7 @@ if __name__ == "__main__":
filename = argv[1]
except IndexError:
pass
if command == "listroles":
print json.dumps(listroles())
elif command == "listkeys":
......@@ -185,4 +180,3 @@ if __name__ == "__main__":
print json.dumps(rmfile(filename))
else:
sys.exit(1)
#!/usr/bin/env python
# -*- encoding: utf-8 -*-
""" Configuration Serveur de cranspasswords.
Sont définis ici les utilisateurs et les rôles associés.
Ce fichier est donné à titre d'exemple, mais n'est PAS
......@@ -7,19 +8,19 @@ utilisé lorsque fonctionnement en mode client.
Dans le futur, sera remplacé par une connexion ldap.
"""
#: Répertoire de stockage des mots de passe
STORE = '/root/cranspasswords/db/'
""" Répertoire de stockage """
#: Ce serveur est-il read-only (on ne peut pas y modifier les mots de passe)
READONLY = False
""" Ce serveur est-il read-only (on ne peut pas y modifier les mots de passe) """
#: Expéditeur du mail de notification
CRANSP_MAIL = "cranspasswords <root@crans.org>"
""" Expéditeur du mail de notification """
#: Destinataire du mail de notification
DEST_MAIL = "root@crans.org"
""" Destinataire du mail de notification """
#: Mapping des utilisateurs et de leurs (mail, fingerprint GPG)
KEYS = {
'aza-vallina': ('Damien.Aza-Vallina@crans.org', None),
'becue': ('becue@crans.org', '9AE04D986400E3B67528F4930D442664194974E2'),
......@@ -62,11 +63,12 @@ KEYS = {
'kviard': ('kviard@crans.org', None)
}
# Les variables suivantes sont utilisées pour définir le dictionnaire des
# rôles.
#: Les variables suivantes sont utilisées pour définir le dictionnaire des
#: rôles.
RTC=[
"iffrig"
]
#: Liste des usernames des nounous
NOUNOUS=RTC+[
"blockelet",
"becue",
......@@ -86,12 +88,14 @@ NOUNOUS=RTC+[
]
# Autogen:
#: Liste des usernames des apprentis
APPRENTIS=['grande', 'bonaque', 'moisy-mabille', 'baste', 'duplouy', 'besson', 'pvincent', 'quelennec', 'pommeret', 'guiraud', 'serrano', 'kherouf', 'randazzo', 'tilquin', 'lasseri', 'epalle', 'soret', 'gstalter', 'kviard']
#: Liste des usernames des membres du CA
CA=[
]
## Les vrais rôles !
#: Les roles utilisés pour savoir qui a le droit le lire/écrire quoi
ROLES = {
"ca": CA,
"ca-w": CA,
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment