Ajout d'objets certifcats comme enfant des objets machine

This commit is contained in:
Valentin Samir 2014-02-22 23:01:56 +01:00
parent 8eb8aa2ba6
commit 44936fde9d
4 changed files with 157 additions and 8 deletions

View file

@ -37,6 +37,7 @@
import re
import sys
import ssl
import netaddr
import time
import base64
@ -252,6 +253,7 @@ class Attr(object):
#: Le nom de l'attribut dans le schéma LDAP
ldap_name = None
python_type = None
binary = False
"""La liste des droits qui suffisent à avoir le droit de modifier la valeur"""
can_modify = [nounou]
@ -389,8 +391,8 @@ class objectClass(Attr):
def parse_value(self, val):
if val not in [ 'top', 'organizationalUnit', 'posixAccount', 'shadowAccount',
'proprio', 'adherent', 'club', 'machine', 'machineCrans',
'borneWifi', 'machineWifi', 'machineFixe',
'cransAccount', 'service', 'facture', 'freeMid' ]:
'borneWifi', 'machineWifi', 'machineFixe', 'x509Cert', 'TLSACert',
'baseCert', 'cransAccount', 'service', 'facture', 'freeMid' ]:
raise ValueError("Pourquoi insérer un objectClass=%r ?" % val)
else:
self.value = unicode(val)
@ -401,7 +403,7 @@ class intAttr(Attr):
python_type = int
def parse_value(self, val):
if self.python_type(val) <= 0:
if self.python_type(val) < 0:
raise ValueError("Valeur entière invalide : %r" % val)
self.value = self.python_type(val)
@ -1434,3 +1436,74 @@ class rewriteMailHeaders(boolAttr):
@crans_attribute
class machineAlias(boolAttr):
ldap_name = "machineAlias"
@crans_attribute
class issuerCN(Attr):
ldap_name = "issuerCN"
@crans_attribute
class serialNumber(Attr):
ldap_name = "serialNumber"
@crans_attribute
class start(intAttr):
ldap_name = "start"
@crans_attribute
class end(intAttr):
ldap_name = "end"
@crans_attribute
class crlUrl(Attr):
ldap_name = "crlUrl"
optional = True
@crans_attribute
class revocked(boolAttr):
ldap_name = "revocked"
singlevalue = True
optional = True
@crans_attribute
class certificat(Attr):
ldap_name = "certificat"
binary = True
python_type = str
def __unicode__(self):
return unicode(ssl.DER_cert_to_PEM_cert(self.value))
def __str__(self):
return self.value
@crans_attribute
class certificatUsage(intAttr):
ldap_name = "certificatUsage"
singlevalue = True
@crans_attribute
class selector(intAttr):
ldap_name = "selector"
singlevalue = True
@crans_attribute
class matchingType(intAttr):
ldap_name = "matchingType"
singlevalue = True
@crans_attribute
class xid(intAttr):
ldap_name = "xid"
category = 'id'
unique = True
singlevalue = True
@crans_attribute
class hostCert(dnsAttr):
optional = False
can_modify = [parent, nounou]
ldap_name = "hostCert"
def parse_value(self, host):
if not host in self.parent.machine()['host'] + self.parent.machine()['hostAlias']:
raise ValueError("hostCert doit être inclus dans les host et hostAlias de la machine parente : %s" % ', '.join(self.parent.machine()['host'] + self.parent.machine()['hostAlias']))
self.value = host

View file

@ -329,8 +329,7 @@ class lc_ldap(ldap.ldapobject.LDAPObject, object):
raise EnvironmentError("Vous n'avez pas le droit de créer cet adhérent.")
def newFacture(self, parent, fldif):
"""Crée une nouvelle facture
--Non implémenté !"""
"""Crée une nouvelle facture"""
uldif = copy.deepcopy(fldif)
# fid
uldif['fid'] = [ unicode(self._find_id('fid')) ]
@ -341,6 +340,18 @@ class lc_ldap(ldap.ldapobject.LDAPObject, object):
else:
raise EnvironmentError("Vous n'avez pas le droit de créer cette facture.")
def newCertificat(self, parent, xldif):
"""Crée un nouveau certificat x509"""
uldif = copy.deepcopy(xldif)
# xid
uldif['xid'] = [ unicode(self._find_id('xid')) ]
uldif['objectClass'] = [u'baseCert']
baseCert = self._create_entity('xid=%s,%s' % (uldif['xid'][0], parent), uldif)
if baseCert.may_be(variables.created, self.droits + self._check_parent(baseCert.dn)):
return baseCert
else:
raise EnvironmentError("Vous n'avez pas le droit de créer ce certiticat.")
def _create_entity(self, dn, uldif):
'''Crée une nouvelle entité ldap avec le dn ``dn`` et les
attributs de ``ldif``. Attention, ldif doit contenir des
@ -393,7 +404,10 @@ class lc_ldap(ldap.ldapobject.LDAPObject, object):
raise EnvironmentError('Aucun %s libre dans la plage [%d, %d]' %
(attr, plage[0], i))
else:
try:
i = nonfree[-1] + 1
except IndexError:
i = 1
while True:
try:
self.lockholder.addlock(attr, str(i))

View file

@ -297,7 +297,10 @@ class CransLdapObject(object):
# On nettoie les locks
for key, values in self._modifs.to_ldif().iteritems():
for value in values:
try:
self.conn.lockholder.removelock(key, value)
except:
pass
self.conn.lockholder.purge(id(self))
# Services à relancer
@ -705,6 +708,7 @@ class machine(CransLdapObject):
def __init__(self, conn, dn, mode='ro', ldif = None):
super(machine, self).__init__(conn, dn, mode, ldif)
self._proprio = None
self._certificats = None
def proprio(self, mode=None):
u"""Renvoie le propriétaire de la machine"""
@ -713,6 +717,14 @@ class machine(CransLdapObject):
self._proprio = new_cransldapobject(self.conn, parent_dn, self.mode if mode is None else mode)
return self._proprio
def certificats(self):
"""Renvoie la liste des certificats de la machine"""
if self._certificats is None:
self._certificats = self.conn.search(u'xid=*', dn = self.dn, scope = 1, mode=self.mode)
for m in self._certificats:
m._machine = self
return self._certificats
def blacklist_actif(self, excepts=[]):
u"""Renvoie la liste des blacklistes actives sur la machine et le proprio"""
black=self.proprio().blacklist_actif(excepts)
@ -954,6 +966,10 @@ class machineMulticast(machine):
pass
def ressuscite(self, comm, login):
pass
def proprio(self, mode=None):
return None
def certificats(self):
return []
@crans_object
class machineWifi(machine):
@ -1048,6 +1064,52 @@ class facture(CransLdapObject):
self._proprio = new_cransldapobject(self.conn, parent_dn, self.mode)
return self._proprio
@crans_object
class baseCert(CransLdapObject):
can_be_by = { variables.created: [attributs.nounou, attributs.bureau],
variables.modified: [attributs.nounou, attributs.bureau],
variables.deleted: [attributs.nounou, attributs.bureau],
}
attribs = [ attributs.xid, attributs.certificat, attributs.hostCert, attributs.historique]
tlsa_attribs = [ attributs.certificatUsage, attributs.selector, attributs.matchingType,
attributs.portTCPin, attributs.portUDPin]
x509_attribs = [ attributs.issuerCN, attributs.start, attributs.end,
attributs.crlUrl, attributs.revocked, attributs.serialNumber ]
ldap_name = "baseCert"
_machine = None
def __init__(self, conn, dn, mode='ro', ldif=None):
super(baseCert, self).__init__(conn, dn, mode, ldif)
if "TLSACert" in self['objectClass']:
self.attribs.extend(self.tlsa_attribs)
if 'x509Cert' in self['objectClass']:
self.attribs.extend(self.x509_attribs)
def tlsa(self, certificatUsage, matchingType):
if not self.mode in ['w', 'rw']:
return
if u"TLSACert" in self['objectClass']:
return
self._modifs['objectClass'].append(u"TLSACert")
self.attribs.extend(self.tlsa_attribs)
self['certificatUsage']=certificatUsage
self['matchingType']=matchingType
self['selector']=0
def x509(issuerCN, start, end, serialNumber, crlUrl=None):
pass
def machine(self):
u"""Renvoie la machine du certificat"""
parent_dn = self.dn.split(',', 1)[1]
if not self._machine:
self._machine = new_cransldapobject(self.conn, parent_dn, self.mode)
return self._machine
@crans_object
class service(CransLdapObject):
ldap_name = "service"

View file

@ -36,7 +36,7 @@ services_to_objects['delete']['del_user'] = [objets.adherent, objets.club]
def services_to_args_mail_modif(x):
if isinstance(x, attributs.droits):
return [ "uid=%s" % x.parent['uid'][0] ]
elif isinstance(x, attributs.Attr) and x.__class__ in [ attributs.exempt ] + services_to_attrs['ports']:
elif isinstance(x, attributs.Attr) and x.__class__ in [ attributs.exempt ] + services_to_attrs['ports'] and isinstance(x.parent, objets.machine):
return [ "mid=%s" % x.parent['mid'][0] ]
elif isinstance(x.parent, objets.machine) and isinstance(x.parent.proprio(mode='ro'), objets.AssociationCrans):
return [ "mid=%s" % x.parent['mid'][0] ]