Fix accumulated nits
Fix nits from the following reviews: - https://review.openstack.org/#/c/345397/35 - https://review.openstack.org/#/c/345398/36 - https://review.openstack.org/#/c/345399/42 Change-Id: Iafa5b4432a85353a216da4d55e46e1eda30842e3 Blueprint: websocket-proxy-to-host-security
This commit is contained in:
@@ -40,19 +40,6 @@ class AuthType(enum.IntEnum):
|
||||
MSLOGON = 0xfffffffa # Used by UltraVNC
|
||||
|
||||
|
||||
class AuthVeNCryptSubtype(enum.IntEnum):
|
||||
|
||||
PLAIN = 256
|
||||
TLSNONE = 257
|
||||
TLSVNC = 258
|
||||
TLSPLAIN = 259
|
||||
X509NONE = 260
|
||||
X509VNC = 261
|
||||
X509PLAIN = 262
|
||||
X509SASL = 263
|
||||
TLSSASL = 264
|
||||
|
||||
|
||||
@six.add_metaclass(abc.ABCMeta)
|
||||
class RFBAuthScheme(object):
|
||||
|
||||
@@ -74,5 +61,7 @@ class RFBAuthScheme(object):
|
||||
|
||||
Should raise exception.RFBAuthHandshakeFailed if
|
||||
an error occurs
|
||||
|
||||
:param compute_sock: socket connected to the compute node instance
|
||||
"""
|
||||
pass
|
||||
|
||||
@@ -37,6 +37,13 @@ class RFBAuthSchemeList(object):
|
||||
self.schemes[scheme.security_type()] = scheme
|
||||
|
||||
def find_scheme(self, desired_types):
|
||||
"""Find a suitable authentication scheme to use with compute node.
|
||||
|
||||
Identify which of the ``desired_types`` we can accept.
|
||||
|
||||
:param desired_types: A list of ints corresponding to the various
|
||||
authentication types supported.
|
||||
"""
|
||||
for security_type in desired_types:
|
||||
if security_type in self.schemes:
|
||||
return self.schemes[security_type]
|
||||
|
||||
@@ -12,20 +12,39 @@
|
||||
# License for the specific language governing permissions and limitations
|
||||
# under the License.
|
||||
|
||||
import enum
|
||||
import ssl
|
||||
import struct
|
||||
|
||||
from oslo_config import cfg
|
||||
from oslo_log import log as logging
|
||||
import six
|
||||
|
||||
from nova.console.rfb import auth
|
||||
from nova import exception
|
||||
from nova.i18n import _, _LI
|
||||
from nova.i18n import _
|
||||
|
||||
LOG = logging.getLogger(__name__)
|
||||
CONF = cfg.CONF
|
||||
|
||||
|
||||
class AuthVeNCryptSubtype(enum.IntEnum):
|
||||
"""Possible VeNCrypt subtypes.
|
||||
|
||||
From https://github.com/rfbproto/rfbproto/blob/master/rfbproto.rst
|
||||
"""
|
||||
|
||||
PLAIN = 256
|
||||
TLSNONE = 257
|
||||
TLSVNC = 258
|
||||
TLSPLAIN = 259
|
||||
X509NONE = 260
|
||||
X509VNC = 261
|
||||
X509PLAIN = 262
|
||||
X509SASL = 263
|
||||
TLSSASL = 264
|
||||
|
||||
|
||||
class RFBAuthSchemeVeNCrypt(auth.RFBAuthScheme):
|
||||
"""A security proxy helper which uses VeNCrypt.
|
||||
|
||||
@@ -81,17 +100,20 @@ class RFBAuthSchemeVeNCrypt(auth.RFBAuthScheme):
|
||||
|
||||
LOG.debug("Server supports VeNCrypt sub-types %s", sub_types)
|
||||
|
||||
if auth.AuthVeNCryptSubtype.X509NONE not in sub_types:
|
||||
# We use X509None as we're only seeking to encrypt the channel (ruling
|
||||
# out PLAIN) and prevent MITM (ruling out TLS*, which uses trivially
|
||||
# MITM'd Anonymous Diffie Hellmann (DH) cyphers)
|
||||
if AuthVeNCryptSubtype.X509NONE not in sub_types:
|
||||
reason = _("Server does not support the x509None (%s) VeNCrypt"
|
||||
" sub-auth type") % \
|
||||
auth.AuthVeNCryptSubtype.X509NONE
|
||||
AuthVeNCryptSubtype.X509NONE
|
||||
raise exception.RFBAuthHandshakeFailed(reason=reason)
|
||||
|
||||
LOG.debug("Attempting to use the x509None (%s) auth sub-type",
|
||||
auth.AuthVeNCryptSubtype.X509NONE)
|
||||
AuthVeNCryptSubtype.X509NONE)
|
||||
|
||||
compute_sock.sendall(struct.pack(
|
||||
'!I', auth.AuthVeNCryptSubtype.X509NONE))
|
||||
'!I', AuthVeNCryptSubtype.X509NONE))
|
||||
|
||||
# NB(sross): the spec is missing a U8 here that's used in
|
||||
# multiple implementations (e.g. QEMU, GTK-VNC). 1 means
|
||||
@@ -120,9 +142,10 @@ class RFBAuthSchemeVeNCrypt(auth.RFBAuthScheme):
|
||||
cert_reqs=ssl.CERT_REQUIRED,
|
||||
ca_certs=CONF.vnc.vencrypt_ca_certs)
|
||||
|
||||
LOG.info(_LI("VeNCrypt security handshake accepted"))
|
||||
LOG.info("VeNCrypt security handshake accepted")
|
||||
return wrapped_sock
|
||||
|
||||
except ssl.SSLError as e:
|
||||
reason = _("Error establishing TLS connection to server: %s") % e
|
||||
reason = _("Error establishing TLS connection to server: %s") % (
|
||||
six.text_type(e))
|
||||
raise exception.RFBAuthHandshakeFailed(reason=reason)
|
||||
|
||||
@@ -23,7 +23,7 @@ from nova.console.rfb import auth
|
||||
from nova.console.rfb import auths
|
||||
from nova.console.securityproxy import base
|
||||
from nova import exception
|
||||
from nova.i18n import _, _LI
|
||||
from nova.i18n import _
|
||||
|
||||
LOG = logging.getLogger(__name__)
|
||||
|
||||
@@ -46,6 +46,10 @@ class RFBSecurityProxy(base.SecurityProxy):
|
||||
See the general RFB specification at:
|
||||
|
||||
https://tools.ietf.org/html/rfc6143
|
||||
|
||||
See an updated, maintained RDB specification at:
|
||||
|
||||
https://github.com/rfbproto/rfbproto/blob/master/rfbproto.rst
|
||||
"""
|
||||
|
||||
def __init__(self):
|
||||
@@ -67,7 +71,13 @@ class RFBSecurityProxy(base.SecurityProxy):
|
||||
# by sending the "Invalid" security type
|
||||
compute_sock.sendall(auth.AUTH_STATUS_FAIL)
|
||||
|
||||
def _parse_version(self, version_str):
|
||||
@staticmethod
|
||||
def _parse_version(version_str):
|
||||
r"""Convert a version string to a float.
|
||||
|
||||
>>> RFBSecurityProxy._parse_version('RFB 003.008\n')
|
||||
0.2
|
||||
"""
|
||||
maj_str = version_str[4:7]
|
||||
min_str = version_str[8:11]
|
||||
|
||||
@@ -119,6 +129,7 @@ class RFBSecurityProxy(base.SecurityProxy):
|
||||
permitted_auth_types_cnt = six.byte2int(recv(compute_sock, 1))
|
||||
|
||||
if permitted_auth_types_cnt == 0:
|
||||
# Decode the reason why the request failed
|
||||
reason_len_raw = recv(compute_sock, 4)
|
||||
reason_len = struct.unpack('!I', reason_len_raw)[0]
|
||||
reason = recv(compute_sock, reason_len)
|
||||
@@ -148,9 +159,8 @@ class RFBSecurityProxy(base.SecurityProxy):
|
||||
_("Only the security type None (%d) is supported") %
|
||||
auth.AuthType.NONE)
|
||||
|
||||
reason = _("Client requested a security type other than "
|
||||
" None (%(none_code)d): "
|
||||
"%(auth_type)s") % {
|
||||
reason = _("Client requested a security type other than None "
|
||||
"(%(none_code)d): %(auth_type)s") % {
|
||||
'auth_type': client_auth,
|
||||
'none_code': auth.AuthType.NONE}
|
||||
raise exception.SecurityProxyNegotiationFailed(reason=reason)
|
||||
@@ -179,10 +189,10 @@ class RFBSecurityProxy(base.SecurityProxy):
|
||||
_("Unable to negotiate security with server"))
|
||||
LOG.debug("Auth failed %s", six.text_type(e))
|
||||
raise exception.SecurityProxyNegotiationFailed(
|
||||
reason="Auth handshake failed")
|
||||
reason=_("Auth handshake failed"))
|
||||
|
||||
LOG.info(_LI("Finished security handshake, resuming normal proxy "
|
||||
"mode using secured socket"))
|
||||
LOG.info("Finished security handshake, resuming normal proxy "
|
||||
"mode using secured socket")
|
||||
|
||||
# we can just proxy the security result -- if the server security
|
||||
# negotiation fails, we want the client to think it has failed
|
||||
|
||||
Reference in New Issue
Block a user