Commit d85eb03a authored by Philippe Pepiot's avatar Philippe Pepiot
Browse files

Drop trustedauth-secret-key-file option

This shared secret was used when cubicweb web server was living outside of the
data repository and forward requests with pyro.
We do not support pyro anymore so this is useless.

Just drop all related crypto code and drop the option
'trustedauth-secret-key-file' and drop the dependency on cryptodome/pycrypto.

Use a special kwargs "trustedauth_login", our BaseAuthentifier only match with
our WebAuthInfoRetriever.

As a side effect, this fix test/unittest_trustedauth.py which were broken in python 3 :)
parent 683e7b5f0b2a
......@@ -34,7 +34,6 @@ web = 'http://www.cubicweb.org/project/%s' % distname
__depends__ = {
'cubicweb': '>= 3.24.0',
'pycryptodome': None,
}
__recommends__ = {}
......
......@@ -24,21 +24,11 @@
__docformat__ = "restructuredtext en"
import base64
from cubicweb import AuthenticationError
from cubicweb.server.sources import native
from cubicweb_trustedauth.cryptutils import build_cypher
class XRemoteUserAuthentifier(native.BaseAuthentifier):
""" a source authentifier plugin
login comes encrypted + base64 encoded
we decrypt it with a special key to identify
the trustfulness of the `client` (pyro, web)
"""
auth_rql = ('Any X WHERE X is CWUser, X login %(login)s')
def authenticate(self, session, login, **kwargs):
"""return CWUser eid for the given login (coming from x-remote-user
......@@ -46,15 +36,10 @@ class XRemoteUserAuthentifier(native.BaseAuthentifier):
else raise `AuthenticationError`
"""
session.debug('authentication by %s', self.__class__.__name__)
try:
_secret = session.vreg.config._secret
cyphr = build_cypher(_secret)
clearlogin = cyphr.decrypt(base64.decodestring(kwargs.get('secret'))).strip()
if clearlogin != login:
raise AuthenticationError('wrong user secret')
rset = session.execute(self.auth_rql, {'login': clearlogin})
return rset[0][0]
except Exception as exc:
session.debug('authentication failure (%s)', exc)
pass
raise AuthenticationError('user is not registered')
if 'trustedauth_login' in kwargs:
rset = session.execute(
'Any U WHERE U is CWUser, U login %(trustedauth_login)s',
kwargs)
if rset:
return rset[0][0]
raise AuthenticationError('no trusted authentication for this user')
# copyright 2010-2013 LOGILAB S.A. (Paris, FRANCE), all rights reserved.
# contact http://www.logilab.fr -- mailto:contact@logilab.fr
#
# This program is free software: you can redistribute it and/or modify it under
# the terms of the GNU Lesser General Public License as published by the Free
# Software Foundation, either version 2.1 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 Lesser General Public License for more
# details.
#
# You should have received a copy of the GNU Lesser General Public License along
# with this program. If not, see <http://www.gnu.org/licenses/>.
from Crypto.Cipher import AES
def build_cypher(key):
""" see
http://www.dlitz.net/software/pycrypto/doc/#crypto-cipher-encryption-algorithms
"""
return AES.new(key, AES.MODE_ECB)
# copyright 2010-2013 LOGILAB S.A. (Paris, FRANCE), all rights reserved.
# contact http://www.logilab.fr -- mailto:contact@logilab.fr
#
# This program is free software: you can redistribute it and/or modify it under
# the terms of the GNU Lesser General Public License as published by the Free
# Software Foundation, either version 2.1 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 Lesser General Public License for more
# details.
#
# You should have received a copy of the GNU Lesser General Public License along
# with this program. If not, see <http://www.gnu.org/licenses/>.
"""cubicweb-trustedauth entity's classes"""
CONFENTRY = 'trustedauth-secret-key-file'
def set_secret(config, secretfile):
try:
secret = open(secretfile).read().strip()
except IOError:
config.error("Cannot open secret key file. Check your configuration file!")
return
if not secret or len(secret) > 32:
config.error('secret key must me a string 0 < len(key) <= 32')
return
config._secret = secret.ljust(32, '#')
# the presence of this registration callback here is a small hack to
# make sure the secret key file is loaded on both sides of cw (repo
# and web)
def registration_callback(vreg):
secretfile = vreg.config.get(CONFENTRY, "").strip()
if not secretfile:
vreg.config.warning("Configuration '%s' is missing or empty. "
"Please check your configuration file!" % CONFENTRY)
return
set_secret(vreg.config, secretfile)
option_removed('trustedauth-secret-key-file')
# copyright 2010-2013 LOGILAB S.A. (Paris, FRANCE), all rights reserved.
# contact http://www.logilab.fr -- mailto:contact@logilab.fr
#
# This program is free software: you can redistribute it and/or modify it under
# the terms of the GNU Lesser General Public License as published by the Free
# Software Foundation, either version 2.1 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 Lesser General Public License for more
# details.
#
# You should have received a copy of the GNU Lesser General Public License along
# with this program. If not, see <http://www.gnu.org/licenses/>.
from cubicweb import _
options = (
('trustedauth-secret-key-file',
{'type': 'string',
'help': _('Qualified file path to the shared secret key between '
'the web part and the data repository'),
'default': '',
'group': 'trustedauth',
}),
)
......@@ -24,14 +24,10 @@
__docformat__ = "restructuredtext en"
import base64
from logilab.common.registry import objectify_predicate
from cubicweb.web.views import authentication, actions, basecontrollers
from cubicweb_trustedauth.cryptutils import build_cypher
# web authentication info retreiver ############################################
......@@ -43,23 +39,14 @@ class XRemoteUserRetriever(authentication.WebAuthInfoRetriever):
def authentication_information(self, req):
"""retrieve authentication information from the given request, raise
NoAuthInfo if expected information is not found
return login crypted with secret shared key
or return login
"""
self.debug('web authenticator building auth info')
try:
login = req.get_header('x-remote-user', None)
if login is None:
self.debug('http header is missing x-remote-user')
raise authentication.NoAuthInfo('missing x-remote-user')
self.debug('encoding info for %s', login)
_secret = self._cw.config._secret
cyphr = build_cypher(_secret)
# need a multiple of 16 in length
secret = cyphr.encrypt('%128s' % login)
return login, {'secret': base64.encodestring(secret)}
except Exception as exc:
self.debug('web authenticator failed (%s)', exc)
raise authentication.NoAuthInfo()
login = req.get_header('x-remote-user', None)
if login is None:
self.debug('http header is missing x-remote-user')
raise authentication.NoAuthInfo('missing x-remote-user')
return login, {'trustedauth_login': login}
def authenticated(self, retriever, req, cnx, login, authinfo):
"""callback when return authentication information have opened a
......
......@@ -132,28 +132,7 @@ Setup your blog app
You now need to make your blog application use this ``trustedauth``
cube. For this, it is only a matter of telling your application cube
to use the ``trustedauth`` cube and to add a configration option to
your application ``all-in-one.conf`` file.
Modify your ``all-in-one.conf``
-------------------------------
Add the ``trustedauth-secret-key-file`` option in the ``trustedauth``
option group. The value should point to a file containing the secret key
that is used to secure the connection between the web part of the CubicWeb
application and the data part of the application (they may live on
different machines, communicating via pyro). Do not forget to create the
file. The secret key should be between 1 and 32 characters long.
.. sourcecode:: ini
# ...
[TRUSTEDAUTH]
trustedauth-secret-key-file="/etc/application/secret-key"
# ...
to use the ``trustedauth`` cube.
Modify your blog cube
......
......@@ -279,18 +279,10 @@ Dans /etc/apache2/sites-available/cw-kerberos::
Configuration CubicWeb
~~~~~~~~~~~~~~~~~~~~~~
Utiliser et configurer le cube trustedauth : il faut créer un
fichier contenant la "clef secrète" (dont la taille doit être un
multiple de 16 octets) et donner le chemin vers ce fichier dans le
all-in-one.conf::
secret-key-filepath=/path/to/secret
Dans le all-in-one.conf de l'instance, ne pas oublier de mettre des
valeurs raisonnables pour certains champs::
https-url=https://toto.logilab.fr
base-url=http://toto.logilab.fr
base-url=https://toto.logilab.fr
Démarrer l'instance en mode debug (``-l debug``) fournira suffisamment
d'information pour identifier où ça se passe mal.
......@@ -364,6 +356,3 @@ Conclusion
A partir de là il devrait être possible de pointer un navigateur vers
https://toto.logilab.fr et espérer que ça se passe bien.
Les "clients" web et pyro doivent être sécurisés (la clef secrête doit
rester inviolable).
......@@ -15,7 +15,6 @@ Package: cubicweb-trustedauth
Architecture: all
Depends:
python-cubicweb (>= 3.24.0),
python-crypto,
${python:Depends},
${misc:Depends},
Description: authentication plugin for CubicWeb instances behind a reverse proxy
......
[TRUSTEDAUTH]
trustedauth-secret-key-file="data/secretfile"
......@@ -20,19 +20,9 @@
from cubicweb.devtools.testlib import CubicWebTC
from cubicweb.web import LogOut
from cubicweb_trustedauth.entities import set_secret
class TrustedAuthTC(CubicWebTC):
@classmethod
def init_config(cls, config):
super(TrustedAuthTC, cls).init_config(config)
# XXX secret file in data/allinone.conf is a relative path, so test may
# fail depending on the CWD when starting them. Recall set_secret to fix
# this
set_secret(config, cls.datapath('secretfile'))
def test_login(self):
req = self.init_authentication('http')
req.set_request_header('x-remote-user', 'admin', raw=True)
......
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