diff --git a/authserv/app_common.py b/authserv/app_common.py index c3681aa56f16cd2f95e7a695da2c39a086e37a0f..9d5c8df10cec1b797839b68b94640a8942181049 100644 --- a/authserv/app_common.py +++ b/authserv/app_common.py @@ -41,7 +41,8 @@ def do_auth(username, service, shard, password, otp_token, source_ip, user = current_app.userdb.get_user(username, service, shard) if user: retval, errmsg = auth.authenticate( - user, service, password, otp_token, source_ip, password_only) + user, service, password, otp_token, source_ip, password_only, + current_app.config.get('ALLOW_PLAIN_PASSWORD_FROM_LOCALHOST', False)) out_shard = user.get_shard() if shard and out_shard != shard: retval = protocol.ERR_AUTHENTICATION_FAILURE diff --git a/authserv/auth.py b/authserv/auth.py index 77e675491724fb893b120a3937c950e25784e66d..295ec36ddf89fbb389b884f6a23573cf5adc714b 100644 --- a/authserv/auth.py +++ b/authserv/auth.py @@ -31,7 +31,8 @@ def _check_otp(totp_key, token): def authenticate(user, service, password, otp_token, source_ip=None, - password_only=False): + password_only=False, + allow_plain_password_from_localhost=False): if not password: return protocol.ERR_AUTHENTICATION_FAILURE, 'empty password' @@ -47,7 +48,11 @@ def authenticate(user, service, password, otp_token, source_ip=None, if user.app_specific_passwords_enabled(): result = _check_app_specific_password( user.get_app_specific_passwords(service), password) - if result == protocol.OK or source_ip != '127.0.0.1': + # If allow_plain_password_from_localhost is set to False, + # return the ASP check result in any case. Otherwise fall + # back to plain password check (if the host is localhost). + if result == protocol.OK or ( + not allow_plain_password_from_localhost or source_ip != '127.0.0.1'): return result # If OTP is enabled for this account, require it along with the diff --git a/authserv/test/test_auth.py b/authserv/test/test_auth.py index 7a050119049612beae74c5badcbad0784d0a564c..fd9cdfcf6ea73bf63b7041fb64fd7851e2dfb8ba 100644 --- a/authserv/test/test_auth.py +++ b/authserv/test/test_auth.py @@ -62,12 +62,20 @@ class AuthTest(unittest.TestCase): protocol.ERR_AUTHENTICATION_FAILURE, authenticate(u, 'svc', 'pass', None, '1.2.3.4')[0]) - def test_app_specific_password_ok_with_main_password_from_localhost(self): + def test_app_specific_password_with_main_password_from_localhost(self): u = FakeUser('user', 'pass', asps=[ ('svc', crypt.crypt('app-specific', 'zz'))]) + # Result should be OK if the flag is set to True. self.assertEquals( protocol.OK, - authenticate(u, 'svc', 'pass', None, '127.0.0.1')[0]) + authenticate(u, 'svc', 'pass', None, '127.0.0.1', + allow_plain_password_from_localhost=True)[0]) + # Expect authentication failure if + # allow_plain_password_from_localhost is False. + self.assertEquals( + protocol.ERR_AUTHENTICATION_FAILURE, + authenticate(u, 'svc', 'pass', None, '127.0.0.1', + allow_plain_password_from_localhost=False)[0]) def test_app_specific_password_fail(self): u = FakeUser('user', 'pass', asps=[