1
0
mirror of https://github.com/Yubico/yubiadmin.git synced 2025-02-26 23:54:26 +01:00

Delay import of YubiAuth until needed (fixes #3).

This commit is contained in:
Dain Nilsson 2013-11-21 14:47:09 +01:00
parent 8e0169263f
commit 4ac015e0e6
7 changed files with 101 additions and 29 deletions

View File

@ -3,5 +3,6 @@ include COPYING
include NEWS include NEWS
include ChangeLog include ChangeLog
include bin/*.1 include bin/*.1
include conf/*
recursive-include yubiadmin/static * recursive-include yubiadmin/static *
recursive-include yubiadmin/templates * recursive-include yubiadmin/templates *

4
NEWS
View File

@ -1,3 +1,7 @@
* Version 0.1.6 (unreleased)
* Added LDAP settings to YubiAuth.
* Version 0.1.5 (released 2013-06-07) * Version 0.1.5 (released 2013-06-07)
* Fixed YubiAuth user management which sometimes failed due to database * Fixed YubiAuth user management which sometimes failed due to database

21
conf/logging.conf Normal file
View File

@ -0,0 +1,21 @@
[loggers]
keys=root
[logger_root]
level=INFO
handlers=fileHandler
[formatters]
keys=formatter
[handlers]
keys=fileHandler
[formatter_formatter]
format=[%(levelname)s] %(asctime)s %(name)s: %(message)s
datefmt=%Y-%m-%d %I:%M:%S
[handler_fileHandler]
class=handlers.WatchedFileHandler
formatter=formatter
args=("/var/log/yubiadmin.log",)

View File

@ -32,7 +32,7 @@ from release import release
setup( setup(
name='yubiadmin', name='yubiadmin',
version='0.1.5', version='0.1.6',
author='Dain Nilsson', author='Dain Nilsson',
author_email='dain@yubico.com', author_email='dain@yubico.com',
maintainer='Yubico Open Source Maintainers', maintainer='Yubico Open Source Maintainers',

View File

@ -27,6 +27,7 @@
import os import os
import requests import requests
import imp
from wtforms import Form from wtforms import Form
from wtforms.fields import (SelectField, TextField, BooleanField, IntegerField, from wtforms.fields import (SelectField, TextField, BooleanField, IntegerField,
PasswordField) PasswordField)
@ -39,17 +40,16 @@ from yubiadmin.util.config import (python_handler, python_list_handler,
FileConfig) FileConfig)
from yubiadmin.util.form import ConfigForm, FileForm, ListField from yubiadmin.util.form import ConfigForm, FileForm, ListField
from yubiadmin.apps.dashboard import panel from yubiadmin.apps.dashboard import panel
import logging as log import logging
try:
from yubiauth import YubiAuth
except:
YubiAuth = None
User = None
__all__ = [ __all__ = [
'app' 'app'
] ]
log = logging.getLogger(__name__)
YUBIAUTH_INSTALLED = imp.find_module('yubiauth')
YubiAuth = None
AUTH_CONFIG_FILE = '/etc/yubico/auth/yubiauth.conf' AUTH_CONFIG_FILE = '/etc/yubico/auth/yubiauth.conf'
YKVAL_SERVERS = [ YKVAL_SERVERS = [
@ -150,24 +150,39 @@ class SecurityForm(ConfigForm):
class HSMForm(ConfigForm): class HSMForm(ConfigForm):
legend = 'YubiHSM' legend = 'YubiHSM'
description = 'Settings for the YubiHSM hardware device' description = 'Settings for the YubiHSM hardware device.'
config = auth_config config = auth_config
use_hsm = BooleanField( use_hsm = BooleanField(
'Use a YubiHSM', 'Use a YubiHSM',
description='Check this if you have a YubiHSM to be used by YubiAuth.' description="""
Check this if you have a YubiHSM to be used by YubiAuth for more
secure local password validation.
"""
) )
hsm_device = TextField('YubiHSM device') hsm_device = TextField('YubiHSM device')
class LDAPForm(ConfigForm): class LDAPForm(ConfigForm):
legend = 'LDAP authentication' legend = 'LDAP authentication'
descripting = 'Settings for authenticating users against an LDAP server.' description = """
Settings for authenticating users against an LDAP server. When LDAP
authentication is used only users that exist on the LDAP server will be
permitted to log in, and password validatoin will be delegated to the LDAP
server.
"""
config = auth_config config = auth_config
attrs = {
'ldap_server': {'class': 'input-xxlarge'},
'ldap_bind_dn': {'class': 'input-xxlarge'}
}
use_ldap = BooleanField( use_ldap = BooleanField(
'Authenticate users against LDAP', 'Authenticate users against LDAP',
description='Check this to authenticate users passwords against LDAP.' description="""
Check this to authenticate users passwords externally against an LDAP
server.
"""
) )
ldap_server = TextField('LDAP server URL') ldap_server = TextField('LDAP server URL')
ldap_bind_dn = TextField('Bind DN for user authentication') ldap_bind_dn = TextField('Bind DN for user authentication')
@ -262,6 +277,11 @@ def using_default_client():
auth_config['client_secret'] == YKVAL_DEFAULT_SECRET auth_config['client_secret'] == YKVAL_DEFAULT_SECRET
def using_ldap():
auth_config.read()
return auth_config['use_ldap']
class YubiAuthApp(App): class YubiAuthApp(App):
""" """
@ -271,7 +291,6 @@ class YubiAuthApp(App):
""" """
name = 'auth' name = 'auth'
sections = ['general', 'database', 'validation', 'advanced']
priority = 40 priority = 40
@property @property
@ -280,19 +299,19 @@ class YubiAuthApp(App):
@property @property
def sections(self): def sections(self):
if not YubiAuth: base = ['general', 'database', 'password', 'otp']
return ['general', 'database', 'validation', 'advanced'] if YUBIAUTH_INSTALLED:
return ['general', 'database', 'validation', 'users', 'advanced'] return base + ['users', 'advanced']
return base + ['advanced']
@property @property
def dash_panels(self): def dash_panels(self):
if using_default_client(): if using_default_client():
yield panel('YubiAuth', 'Using default YubiCloud client!', yield panel('YubiAuth', 'Using default YubiCloud client!',
'/%s/validation' % self.name, 'danger') '/%s/otp' % self.name, 'danger')
def general(self, request): def general(self, request):
return self.render_forms(request, return self.render_forms(request, [SecurityForm()],
[SecurityForm(), LDAPForm(), HSMForm()],
template='auth/general') template='auth/general')
def reload(self, request): def reload(self, request):
@ -302,9 +321,9 @@ class YubiAuthApp(App):
def database(self, request): def database(self, request):
return self.render_forms(request, [DatabaseForm()]) return self.render_forms(request, [DatabaseForm()])
def validation(self, request): def otp(self, request):
""" """
Validation Server(s) OTP Validation
""" """
form = ValidationServerForm() form = ValidationServerForm()
resp = self.render_forms(request, [form]) resp = self.render_forms(request, [form])
@ -320,6 +339,12 @@ class YubiAuthApp(App):
}) })
return resp return resp
def password(self, request):
"""
Password Validation
"""
return self.render_forms(request, [LDAPForm(), HSMForm()])
def getapikey(self, request): def getapikey(self, request):
return self.render_forms(request, [GetApiKeyForm()], success_msg= return self.render_forms(request, [GetApiKeyForm()], success_msg=
"API Key registered!") "API Key registered!")
@ -333,9 +358,11 @@ class YubiAuthApp(App):
""" """
Manage Users Manage Users
""" """
global User global YubiAuth, User
if User is None: if YubiAuth is None:
from yubiauth import YubiAuth as _yubiauth
from yubiauth.core.model import User as _user from yubiauth.core.model import User as _user
YubiAuth = _yubiauth
User = _user User = _user
with YubiAuth() as auth: with YubiAuth() as auth:
@ -388,6 +415,11 @@ class SetPasswordForm(Form):
self.verify.data = None self.verify.data = None
class SetPasswordDisabledForm(Form):
legend = 'Change Password'
description = 'Cannot change password when using LDAP for authentication.'
class AssignYubiKeyForm(Form): class AssignYubiKeyForm(Form):
legend = 'Assign YubiKey' legend = 'Assign YubiKey'
assign = TextField('Assign YubiKey', assign = TextField('Assign YubiKey',
@ -459,10 +491,10 @@ class YubiAuthUsers(CollectionApp):
msg = 'YubiKey assigned!' msg = 'YubiKey assigned!'
elif request.params.get('unassign', None): elif request.params.get('unassign', None):
msg = 'YubiKey unassigned!' msg = 'YubiKey unassigned!'
return self.render_forms(request, pwd_form = SetPasswordDisabledForm() if using_ldap() else \
[SetPasswordForm(user.id), SetPasswordForm(user.id)
AssignYubiKeyForm(user.id)], forms = [pwd_form, AssignYubiKeyForm(user.id)]
'auth/user', user=user.data, return self.render_forms(request, forms, 'auth/user', user=user.data,
success_msg=msg) success_msg=msg)

View File

@ -29,6 +29,8 @@ import sys
import os import os
import imp import imp
import errno import errno
import logging
import logging.config
from yubiadmin import default_settings from yubiadmin import default_settings
__all__ = [ __all__ = [
@ -37,9 +39,11 @@ __all__ = [
SETTINGS_FILE = os.getenv('YUBIADMIN_SETTINGS', SETTINGS_FILE = os.getenv('YUBIADMIN_SETTINGS',
'/etc/yubico/admin/yubiadmin.conf') '/etc/yubico/admin/yubiadmin.conf')
LOG_CONFIG_FILE = os.path.join(os.path.dirname(os.path.abspath(SETTINGS_FILE)),
'logging.conf')
VALUES = { VALUES = {
#Web interface # Web interface
'USERNAME': 'user', 'USERNAME': 'user',
'PASSWORD': 'pass', 'PASSWORD': 'pass',
'INTERFACE': 'iface', 'INTERFACE': 'iface',
@ -61,8 +65,16 @@ try:
sys.dont_write_bytecode = True sys.dont_write_bytecode = True
user_settings = imp.load_source('user_settings', SETTINGS_FILE) user_settings = imp.load_source('user_settings', SETTINGS_FILE)
settings = parse(user_settings, settings) settings = parse(user_settings, settings)
except IOError, e: except IOError as e:
if not e.errno in [errno.ENOENT, errno.EACCES]: if not e.errno in [errno.ENOENT, errno.EACCES]:
raise e raise e
finally: finally:
sys.dont_write_bytecode = dont_write_bytecode sys.dont_write_bytecode = dont_write_bytecode
# Set up logging
try:
logging.config.fileConfig(LOG_CONFIG_FILE)
except:
logging.basicConfig(level=logging.INFO)
log = logging.getLogger(__name__)
log.exception("Unable to configure logging. Logging to console.")

View File

@ -29,7 +29,7 @@ import os
import re import re
import errno import errno
import csv import csv
import logging as log import logging
from collections import MutableMapping, OrderedDict from collections import MutableMapping, OrderedDict
__all__ = [ __all__ = [
@ -43,6 +43,8 @@ __all__ = [
'parse_value' 'parse_value'
] ]
log = logging.getLogger(__name__)
PHP_BLOCKS = re.compile('(?ms)<\?php(.*?)\s*\?>') PHP_BLOCKS = re.compile('(?ms)<\?php(.*?)\s*\?>')
QUOTED_STR = re.compile(r'\s*[\'"](.*)[\'"]\s*') QUOTED_STR = re.compile(r'\s*[\'"](.*)[\'"]\s*')
COMMENTS = re.compile( COMMENTS = re.compile(