1
0
mirror of https://github.com/Yubico/yubiadmin.git synced 2024-12-01 16:24:13 +01:00

Added support for KSM urls.

This commit is contained in:
Dain Nilsson 2013-04-30 13:48:49 +02:00
parent 7d808721cb
commit 62a4ae56a2
5 changed files with 116 additions and 24 deletions

View File

@ -31,14 +31,15 @@ import subprocess
from wtforms.fields import IntegerField
from wtforms.validators import NumberRange, IPAddress, URL
from yubiadmin.util.app import App
from yubiadmin.util.config import ValueHandler, FileConfig, php_inserter
from yubiadmin.util.config import (RegexHandler, FileConfig, php_inserter,
parse_block, strip_comments)
from yubiadmin.util.form import ConfigForm, DBConfigForm, ListField
__all__ = [
'app'
]
COMMENT = re.compile(r'/\*.*?\*/')
COMMENT = re.compile(r'(?ms)(/\*.*?\*/)|(//[^$]*$)|(#[^$]*$)')
VALUE = re.compile(r'\s*[\'"](.*)[\'"]\s*')
@ -56,7 +57,7 @@ def yk_write(varname, prefix='', suffix=''):
def yk_handler(varname, default):
return ValueHandler(yk_pattern(varname), yk_write(varname),
return RegexHandler(yk_pattern(varname), yk_write(varname),
inserter=php_inserter, default=default)
@ -67,13 +68,9 @@ def strip_quotes(value):
return value
def strip_comments(value):
return COMMENT.sub('', value)
def yk_parse_arraystring(value):
value = strip_comments(value).strip()
return filter(None, [strip_quotes(x) for x in value.split(',')])
return filter(None, [strip_quotes(x).strip() for x in strip_comments(value)
.split(',')])
def yk_array_handler(varname):
@ -82,7 +79,43 @@ def yk_array_handler(varname):
writer = lambda xs: str_write((',' + os.linesep)
.join(['\t"%s"' % x for x in xs]))
reader = lambda match: yk_parse_arraystring(match.group(1))
return ValueHandler(pattern, writer, reader, php_inserter, [])
return RegexHandler(pattern, writer, reader, php_inserter, [])
QUOTED_STRS = re.compile(r'((?:"[^"]+")|(?:\'[^\']+\'))')
class KSMHandler(object):
FUNCTION = re.compile(r'function\s+otp2ksmurls\s*\([^)]+\)\s*{')
def _get_block(self, content):
match = self.FUNCTION.search(content)
if match:
return parse_block(content[match.end():], '{', '}')
return None
def read(self, content):
block = self._get_block(content)
print block
if block:
quoted = QUOTED_STRS.findall(strip_comments(block))
return [strip_quotes(x) for x in quoted]
else:
[]
def write(self, content, value):
block = self._get_block(content)
value = ('function otp2ksmurls($otp, $client) {' + os.linesep +
'\treturn array (' + os.linesep +
os.linesep.join(['\t\t"%s",' % x for x in value]) +
os.linesep + '\t);' + os.linesep + '}')
if block:
match = self.FUNCTION.search(content)
start = content[:match.start()]
end = content[match.end() + len(block) + 1:]
return start + value + end
else:
return php_inserter(content, value)
def run(cmd):
@ -116,7 +149,8 @@ ykval_config = FileConfig(
('resync_timeout', yk_handler('SYNC_RESYNC_TIMEOUT', 30)),
('old_limit', yk_handler('SYNC_OLD_LIMIT', 10)),
('sync_pool', yk_array_handler('SYNC_POOL')),
('allowed_sync_pool', yk_array_handler('ALLOWED_SYNC_POOL'))
('allowed_sync_pool', yk_array_handler('ALLOWED_SYNC_POOL')),
('ksm_urls', KSMHandler())
]
)
@ -135,7 +169,8 @@ class MiscForm(ConfigForm):
legend = 'Misc'
config = ykval_config
default_timeout = IntegerField('Default Timeout', [NumberRange(0)])
default_timeout = IntegerField('Default Timeout (seconds)',
[NumberRange(0)])
class SyncPoolForm(ConfigForm):
@ -153,11 +188,17 @@ class SyncPoolForm(ConfigForm):
old_limit = IntegerField('Old Limit', [NumberRange(1)])
sync_pool = ListField(
'Sync Pool URLs', [URL()],
description='List of URLs to other servers in the sync pool.')
description="""
List of URLs to other servers in the sync pool.<br />
Example: <code>http://example.com/wsapi/2.0/sync</code>
""")
allowed_sync_pool = ListField(
'Allowed Sync IPs', [IPAddress()],
description='List of IP-addresses of other servers that are ' +
'allowed to sync with this server.')
description="""
List of IP-addresses of other servers that are allowed to sync with
this server.<br />
Example: <code>10.0.0.1</code>
""")
def save(self):
super(SyncPoolForm, self).save()
@ -165,6 +206,22 @@ class SyncPoolForm(ConfigForm):
restart_daemon()
class KSMForm(ConfigForm):
legend = 'Key Store Modules'
config = ykval_config
attrs = {'ksm_urls': {'rows': 5, 'class': 'input-xxlarge'}}
ksm_urls = ListField(
'KSM URLs', [URL()],
description="""
List of URLs to KSMs.<br />
The URLs must be fully qualified, i.e., contain the OTP itself.<br />
Example: <code>http://example.com/wsapi/decrypt?otp=$otp</code><br />
More advanced OTP to KSM mapping is possible by manually editing the
configuration file.
""")
class YubikeyVal(App):
"""
YubiKey Validation Server
@ -213,6 +270,6 @@ class YubikeyVal(App):
"""
Key Store Modules
"""
return 'Not yet implemented.'
return self.render_forms(request, [KSMForm()])
app = YubikeyVal()

View File

@ -1,7 +1,7 @@
# Copyright (c) 2007 Ian Bicking and Contributors
#
# Permission is hereby granted, free of charge, to any person obtaining a copy
# of this software and associated documentation files (the “Software”), to deal
# of this software and associated documentation files (the "Software"), to deal
# in the Software without restriction, including without limitation the rights
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
# copies of the Software, and to permit persons to whom the Software is
@ -10,7 +10,7 @@
# The above copyright notice and this permission notice shall be included in
# all copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER

View File

@ -15,6 +15,9 @@
<div>
<legend>Sync Daemon</legend>
<span class="help-block">
The sync daemon is a process which synchronizes the counter data of the yubikey-val server with the other servers in its sync pool.
</span>
<p>
Current status: <span class="{{ status_cls }}">{{ status_txt }}</span>
</p>

View File

@ -30,9 +30,11 @@ import re
from UserDict import DictMixin
__all__ = [
'ValueHandler',
'RegexHandler',
'FileConfig',
'php_inserter'
'strip_comments',
'php_inserter',
'parse_block'
]
PHP_BLOCKS = re.compile('(?ms)<\?php(.*?)\s*\?>')
@ -50,9 +52,39 @@ def php_inserter(content, value):
return content
class ValueHandler(object):
def strip_comments(text):
COMMENTS = re.compile(
r'#.*?$|//.*?$|/\*.*?\*/|\'(?:\\.|[^\\\'])*\'|"(?:\\.|[^\\"])*"',
re.DOTALL | re.MULTILINE
)
def replacer(match):
s = match.group(0)
if s[0] in ['/', '#']:
return ''
else:
return s
return COMMENTS.sub(replacer, text)
def parse_block(content, opening='(', closing=')'):
level = 0
index = 0
for c in content:
if c == opening:
level += 1
elif c == closing:
level -= 1
if level < 0:
return content[:index]
index += 1
return content
class RegexHandler(object):
def __init__(self, pattern, writer, reader=lambda x: x.group(1),
inserter=lambda x, y: x + os.linesep + y, default=None):
inserter=lambda x, y: x + os.linesep + y,
default=None):
self.pattern = re.compile(pattern)
self.writer = writer
self.reader = reader

View File

@ -30,7 +30,7 @@ from wtforms.fields import (
TextField, IntegerField, PasswordField, HiddenField, Field)
from wtforms.widgets import PasswordInput, TextArea
from wtforms.validators import Optional, NumberRange
from yubiadmin.util.config import ValueHandler, FileConfig, php_inserter
from yubiadmin.util.config import RegexHandler, FileConfig, php_inserter
__all__ = [
'ListField',
@ -104,7 +104,7 @@ class DBConfigForm(ConfigForm):
def db_handler(self, varname, default):
pattern = r'\$%s=\'(.*)\';' % varname
writer = lambda x: '$%s=\'%s\';' % (varname, x)
return ValueHandler(pattern, writer, inserter=php_inserter,
return RegexHandler(pattern, writer, inserter=php_inserter,
default=default)
def __init__(self, filename, *args, **kwargs):