[Erp5-report] r42350 luke - in /erp5/trunk/products/Vifib: ./ Tool/ www/
nobody at svn.erp5.org
nobody at svn.erp5.org
Fri Jan 14 17:28:17 CET 2011
Author: luke
Date: Fri Jan 14 17:28:16 2011
New Revision: 42350
URL: http://svn.erp5.org?rev=42350&view=rev
Log:
- a tool to have locally available simple Certificate Authority to
fetch and revoke Vifib friendly SSL keys
Added:
erp5/trunk/products/Vifib/Tool/CertificateAuthorityTool.py
erp5/trunk/products/Vifib/www/Vifib_editCertificateAuthorityTool.zpt
Modified:
erp5/trunk/products/Vifib/__init__.py
Added: erp5/trunk/products/Vifib/Tool/CertificateAuthorityTool.py
URL: http://svn.erp5.org/erp5/trunk/products/Vifib/Tool/CertificateAuthorityTool.py?rev=42350&view=auto
==============================================================================
--- erp5/trunk/products/Vifib/Tool/CertificateAuthorityTool.py (added)
+++ erp5/trunk/products/Vifib/Tool/CertificateAuthorityTool.py [utf8] Fri Jan 14 17:28:16 2011
@@ -0,0 +1,249 @@
+# -*- coding: utf-8 -*-
+##############################################################################
+#
+# Copyright (c) 2010 Nexedi SA and Contributors. All Rights Reserved.
+# Łukasz Nowak <luke at nexedi.com>
+#
+# WARNING: This program as such is intended to be used by professional
+# programmers who take the whole responsibility of assessing all potential
+# consequences resulting from its eventual inadequacies and bugs
+# End users who are looking for a ready-to-use solution with commercial
+# guarantees and support are strongly advised to contract a Free Software
+# Service Company
+#
+# This program is Free Software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+#
+##############################################################################
+
+from AccessControl import ClassSecurityInfo
+from Products.ERP5Type.Globals import InitializeClass
+from Products.ERP5Type.Tool.BaseTool import BaseTool
+from Products.ERP5Type import Permissions
+from Products.PageTemplates.PageTemplateFile import PageTemplateFile
+from zLOG import LOG, INFO, ERROR
+
+import os
+import subprocess
+import base64
+
+class CertificateGenerationError(Exception):
+ """Exception raised when certificate authority failed to work"""
+ pass
+
+class CertificateAuthorityBusy(Exception):
+ """Exception raised when certificate authority is busy"""
+ pass
+
+class CertificateAuthorityDamaged(Exception):
+ """Exception raised when certificate authority is damaged"""
+ pass
+
+class CertificateAuthorityTool(BaseTool):
+ """CertificateAuthorityTool
+
+ This tool assumes that in certificate_authority_path openssl configuration is ready.
+ """
+
+ id = 'portal_certificate_authority'
+ meta_type = 'ERP5 Certificate Authority Tool'
+ portal_type = 'Certificate Authority Tool'
+ security = ClassSecurityInfo()
+ allowed_types = ()
+
+ certificate_authority_path = ''
+
+ manage_options = (({'label': 'Edit',
+ 'action': 'manage_editCertificateAuthorityToolForm',},
+ )
+ ) + BaseTool.manage_options
+
+ _properties = (({'id':'certificate_authority_path',
+ 'type':'string',
+ 'mode':'w',
+ 'label':'Path to certificate authority'
+ },
+ )
+ )
+
+ def _lockCertificateAuthority(self):
+ """Checks lock and locks Certificate Authority tool, raises CertificateAuthorityBusy"""
+ if os.path.exists(self.lock):
+ raise CertificateAuthorityBusy
+ open(self.lock, 'w').write('locked')
+
+ def _unlockCertificateAuthority(self):
+ """Checks lock and locks Certificate Authority tool"""
+ if os.path.exists(self.lock):
+ os.unlink(self.lock)
+ else:
+ LOG('CertificateAuthorityTool', INFO, 'Lock file %r did not existed '
+ 'during unlocking' % self.lock)
+
+ def _checkCertificateAuthority(self):
+ """Checks Certificate Authority configuration, raises CertificateAuthorityDamaged"""
+ if not self.certificate_authority_path:
+ raise CertificateAuthorityDamaged('Certificate authority path is not '
+ 'configured' % self.certificate_authority_path)
+ if not os.path.isdir(self.certificate_authority_path):
+ raise CertificateAuthorityDamaged('Path to Certificate Authority %r is '
+ 'wrong' % self.certificate_authority_path)
+ self.serial = os.path.join(self.certificate_authority_path, 'serial')
+ self.crl = os.path.join(self.certificate_authority_path, 'crlnumber')
+ self.index = os.path.join(self.certificate_authority_path, 'index.txt')
+ self.openssl = os.path.join(self.certificate_authority_path, 'openssl')
+ self.openssl_config = os.path.join(self.certificate_authority_path,
+ 'openssl.cnf')
+ self.lock = os.path.join(self.certificate_authority_path, 'lock')
+ for f in [self.serial, self.crl, self.index]:
+ if not os.path.isfile(f):
+ raise CertificateAuthorityDamaged('File %r does not exists.' % f)
+ if not os.path.isfile(self.openssl):
+ raise CertificateAuthorityDamaged('Openssl wrapper %r does not exists' %
+ self.openssl)
+
+ security.declarePrivate('manage_afterAdd')
+ def manage_afterAdd(self, item, container) :
+ """Init permissions right after creation.
+
+ Permissions in slap tool are simple:
+ o Each member can access the tool.
+ o Only manager can view and create.
+ o Anonymous can not access
+ """
+ item.manage_permission(Permissions.AddPortalContent,
+ ['Manager'])
+ item.manage_permission(Permissions.AccessContentsInformation,
+ ['Member', 'Manager'])
+ item.manage_permission(Permissions.View,
+ ['Manager',])
+ BaseTool.inheritedAttribute('manage_afterAdd')(self, item, container)
+
+ #'Edit' option form
+ manage_editCertificateAuthorityToolForm = PageTemplateFile(
+ '../www/Vifib_editCertificateAuthorityTool',
+ globals(),
+ __name__='manage_editCertificateAuthorityToolForm')
+
+ security.declareProtected(Permissions.ManageProperties, 'manage_editCertificateAuthorityTool')
+ def manage_editCertificateAuthorityTool(self, certificate_authority_path, RESPONSE=None):
+ """Edit the object"""
+ error_message = ''
+
+ #Save certificate_authority_path
+ if certificate_authority_path == '' or certificate_authority_path is None:
+ error_message += 'Invalid path '
+ else:
+ self.certificate_authority_path = certificate_authority_path
+
+ #Redirect
+ if RESPONSE is not None:
+ if error_message != '':
+ self.REQUEST.form['manage_tabs_message'] = error_message
+ return self.manage_editCertificateAuthorityToolForm(RESPONSE)
+ else:
+ message = "Updated"
+ RESPONSE.redirect('%s/manage_editCertificateAuthorityToolForm'
+ '?manage_tabs_message=%s'
+ % (self.absolute_url(), message)
+ )
+
+ security.declareProtected(Permissions.AccessContentsInformation, 'getNewCertificate')
+ def getNewCertificate(self):
+ """Returns dictionary {key, certificate, id} where id is certificate id to be used"""
+ self._checkCertificateAuthority()
+ self._lockCertificateAuthority()
+ try:
+ new_id = open(self.serial, 'r').read().strip()
+ cn = base64.encodestring(str(new_id) + ':')
+ key = os.path.join(self.certificate_authority_path, 'private', new_id+'.key')
+ csr = os.path.join(self.certificate_authority_path, new_id + '.csr')
+ cert = os.path.join(self.certificate_authority_path, 'certs', new_id + '.crt')
+ try:
+ keygen = subprocess.Popen([self.openssl, 'req', '-nodes', '-config',
+ self.openssl_config, '-new', '-keyout', key, '-out', csr, '-days',
+ '3650'], stdout=subprocess.PIPE, stderr=subprocess.STDOUT,
+ stdin=subprocess.PIPE)
+ result = keygen.communicate('%s\n' % cn)[0]
+ if keygen.returncode is None or keygen.returncode != 0:
+ LOG('CertificateAuthorityTool', ERROR, 'Issue during key generation, result was:%r' % result)
+ keygen.kill()
+ raise CertificateGenerationError
+ keysign = subprocess.Popen([self.openssl, 'ca', '-batch', '-config',
+ self.openssl_config, '-out', cert, '-infiles', csr], stdout=subprocess.PIPE,
+ stderr=subprocess.STDOUT)
+ result = keysign.communicate()[0]
+ if keysign.returncode is None or keysign.returncode != 0:
+ LOG('CertificateAuthorityTool', ERROR, 'Issue during key signing, result was:%r' % result)
+ keygen.kill()
+ raise CertificateGenerationError
+ os.unlink(csr)
+ return dict(
+ key=open(key).read(),
+ certificate=open(cert).read(),
+ id=new_id)
+ except:
+ try:
+ for p in [key, csr, cert]:
+ if os.path.exists(p):
+ os.unlink(p)
+ except:
+ # do not raise during cleanup
+ pass
+ raise
+ finally:
+ self._unlockCertificateAuthority()
+
+ security.declareProtected(Permissions.AccessContentsInformation, 'revokeCertificate')
+ def revokeCertificate(self, serial):
+ """Revokes certificate with serial, returns dictionary {crl}"""
+ self._checkCertificateAuthority()
+ self._lockCertificateAuthority()
+ try:
+ new_id = open(self.crl, 'r').read().strip()
+ crl = os.path.join(self.certificate_authority_path, 'crl', new_id + '.crl')
+ cert = os.path.join(self.certificate_authority_path, 'certs', serial + '.crt')
+ if not os.path.exists(cert):
+ raise ValueError('Certificate with serial %r does not exists' % serial)
+ try:
+ crl_update = subprocess.Popen([self.openssl, 'ca', '-config',
+ self.openssl_config, '-revoke', cert], stdout=subprocess.PIPE,
+ stderr=subprocess.STDOUT)
+ result = crl_update.communicate()[0]
+ if crl_update.returncode is None or crl_update.returncode != 0:
+ LOG('CertificateAuthorityTool', ERROR, 'Issue during CRL update, result was:%r' % result)
+ crl_update.kill()
+ raise CertificateGenerationError
+ crl_gen = subprocess.Popen([self.openssl, 'ca', '-config',
+ self.openssl_config, '-gencrl', '-out', crl], stdout=subprocess.PIPE,
+ stderr=subprocess.STDOUT)
+ result = crl_gen.communicate()[0]
+ if crl_gen.returncode is None or crl_gen.returncode != 0:
+ LOG('CertificateAuthorityTool', ERROR, 'Issue during CRL generation, result was:%r' % result)
+ crl_gen.kill()
+ raise CertificateGenerationError
+ return dict(crl=open(crl).read())
+ except:
+ try:
+ for p in [crl]:
+ if os.path.exists(p):
+ os.unlink(p)
+ except:
+ # do not raise during cleanup
+ pass
+ raise
+ finally:
+ self._unlockCertificateAuthority()
+
+InitializeClass(CertificateAuthorityTool)
Modified: erp5/trunk/products/Vifib/__init__.py
URL: http://svn.erp5.org/erp5/trunk/products/Vifib/__init__.py?rev=42350&r1=42349&r2=42350&view=diff
==============================================================================
--- erp5/trunk/products/Vifib/__init__.py [utf8] (original)
+++ erp5/trunk/products/Vifib/__init__.py [utf8] Fri Jan 14 17:28:16 2011
@@ -37,8 +37,8 @@ document_classes = updateGlobals(this_mo
object_classes = ()
content_classes = ()
content_constructors = ()
-from Tool import SlapTool
-portal_tools = ( SlapTool.SlapTool, )
+from Tool import SlapTool, CertificateAuthorityTool
+portal_tools = ( SlapTool.SlapTool, CertificateAuthorityTool.CertificateAuthorityTool )
from Products.PluggableAuthService.PluggableAuthService import registerMultiPlugin
import VifibMachineAuthenticationPlugin
Added: erp5/trunk/products/Vifib/www/Vifib_editCertificateAuthorityTool.zpt
URL: http://svn.erp5.org/erp5/trunk/products/Vifib/www/Vifib_editCertificateAuthorityTool.zpt?rev=42350&view=auto
==============================================================================
--- erp5/trunk/products/Vifib/www/Vifib_editCertificateAuthorityTool.zpt (added)
+++ erp5/trunk/products/Vifib/www/Vifib_editCertificateAuthorityTool.zpt [utf8] Fri Jan 14 17:28:16 2011
@@ -0,0 +1,29 @@
+<h1 tal:replace="structure context/manage_page_header">PAGE HEADER</h1>
+<h2 tal:replace="structure here/manage_tabs"> TABS </h2>
+<h2 tal:define="form_title string:Edit ERP5 Certificate Authority Tool"
+ tal:replace="structure context/manage_form_title">FORM TITLE</h2>
+
+<p class="form-help">Please input the Certificate Authority path</p>
+
+<form action="manage_editCertificateAuthorityTool" method="POST">
+
+<table tal:define="certificate_authority_path request/certificate_authority_path|context/certificate_authority_path|string:;">
+
+<tr>
+ <td>Path to configured Certificate Authority</td>
+ <td>
+ <input type="text" name="certificate_authority_path" value=""
+ tal:attributes="value certificate_authority_path;" />
+ </td>
+</tr>
+<tr>
+ <td colspan="2">
+ <input type="submit" value="save"/>
+ </td>
+</tr>
+
+</table>
+
+</form>
+
+<h1 tal:replace="structure context/manage_page_footer">PAGE FOOTER</h1>
More information about the Erp5-report
mailing list