Files
deb-nova/nova/vnc/auth.py
Anthony Young dbef492039 fix flag names
2011-03-29 13:32:03 -07:00

136 lines
4.2 KiB
Python

#!/usr/bin/env python
# vim: tabstop=4 shiftwidth=4 softtabstop=4
# Copyright (c) 2010 Openstack, LLC.
# All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
"""Auth Components for VNC Console."""
import time
import urlparse
import webob
from webob import Request
from nova import context
from nova import flags
from nova import log as logging
from nova import manager
from nova import rpc
from nova import utils
from nova import wsgi
from nova import vnc
LOG = logging.getLogger('nova.vnc-proxy')
FLAGS = flags.FLAGS
class VNCNovaAuthMiddleware(object):
"""Implementation of Middleware to Handle Nova Auth."""
def __init__(self, app):
self.app = app
self.token_cache = {}
utils.LoopingCall(self._delete_expired_tokens).start(1)
def get_token_info(self, token):
if token in self.token_cache:
return self.token_cache[token]
rval = rpc.call(context.get_admin_context(),
FLAGS.vncproxy_topic,
{"method": "check_token", "args": {'token': token}})
if rval:
self.token_cache[token] = rval
return rval
@webob.dec.wsgify
def __call__(self, req):
token = req.params.get('token')
if not token:
referrer = req.environ.get('HTTP_REFERER')
auth_params = urlparse.parse_qs(urlparse.urlparse(referrer).query)
if 'token' in auth_params:
token = auth_params['token'][0]
connection_info = self.get_token_info(token)
if not connection_info:
LOG.audit(_("Unauthorized Access: (%s)"), req.environ)
return webob.exc.HTTPForbidden(detail='Unauthorized')
if req.path == vnc.proxy.WS_ENDPOINT:
req.environ['vnc_host'] = connection_info['host']
req.environ['vnc_port'] = int(connection_info['port'])
return req.get_response(self.app)
def _delete_expired_tokens(self):
now = time.time()
to_delete = []
for k, v in self.token_cache.items():
if now - v['last_activity_at'] > FLAGS.vnc_token_ttl:
to_delete.append(k)
for k in to_delete:
del self.token_cache[k]
class LoggingMiddleware(object):
def __init__(self, app):
self.app = app
@webob.dec.wsgify
def __call__(self, req):
if req.path == vnc.proxy.WS_ENDPOINT:
LOG.info(_("Received Websocket Request: %s"), req.url)
else:
LOG.info(_("Received Request: %s"), req.url)
return req.get_response(self.app)
class VNCProxyAuthManager(manager.Manager):
"""Manages token based authentication."""
def __init__(self, scheduler_driver=None, *args, **kwargs):
super(VNCProxyAuthManager, self).__init__(*args, **kwargs)
self.tokens = {}
utils.LoopingCall(self._delete_expired_tokens).start(1)
def authorize_vnc_console(self, context, token, host, port):
self.tokens[token] = {'host': host,
'port': port,
'last_activity_at': time.time()}
LOG.audit(_("Received Token: %s, %s)"), token, self.tokens[token])
def check_token(self, context, token):
LOG.audit(_("Checking Token: %s, %s)"), token, (token in self.tokens))
if token in self.tokens:
return self.tokens[token]
def _delete_expired_tokens(self):
now = time.time()
to_delete = []
for k, v in self.tokens.items():
if now - v['last_activity_at'] > FLAGS.vnc_token_ttl:
to_delete.append(k)
for k in to_delete:
LOG.audit(_("Deleting Expired Token: %s)"), k)
del self.tokens[k]