mirror of
https://opendev.org/x/pyghmi
synced 2025-01-14 19:57:47 +00:00
Add TLS support and TSM remote video (WIP)
Provide a method for applications to evaluate target certificates. Force them to do so if such a thing is needed. Use this to support TSM remote graphics, which sholud be over https for sake of security. Change-Id: Ie67b629b0021c356d2ea001e24c72ad196e5460d
This commit is contained in:
parent
4cc75b4736
commit
03e3da529b
@ -29,6 +29,12 @@ class IpmiException(PyghmiException):
|
||||
self.ipmicode = code
|
||||
|
||||
|
||||
class UnrecognizedCertificate(Exception):
|
||||
def __init__(self, text='', certdata=None):
|
||||
super(UnrecognizedCertificate, self).__init__(text)
|
||||
self.certdata = certdata
|
||||
|
||||
|
||||
class InvalidParameterValue(PyghmiException):
|
||||
pass
|
||||
|
||||
|
@ -127,6 +127,24 @@ class Command(object):
|
||||
port=port,
|
||||
kg=kg)
|
||||
|
||||
def register_key_handler(self, callback, type='tls'):
|
||||
"""Assign a verification handler for a public key
|
||||
|
||||
When the library attempts to communicate with the management target
|
||||
using a non-IPMI protocol, it will try to verify a key. This
|
||||
allows a caller to register a key handler for accepting or rejecting
|
||||
a public key/certificate. The callback will be passed the peer public
|
||||
key or certificate.
|
||||
|
||||
:param callback: The function to call with public key/certificate
|
||||
:param type: Whether the callback is meant to handle 'tls' or 'ssh',
|
||||
defaults to 'tls'
|
||||
"""
|
||||
if type == 'tls':
|
||||
self._certverify = callback
|
||||
self.oem_init()
|
||||
self._oem.register_key_handler(callback, type)
|
||||
|
||||
def logged(self, response):
|
||||
self.onlogon(response, self)
|
||||
|
||||
@ -270,6 +288,16 @@ class Command(object):
|
||||
else:
|
||||
return lastresponse
|
||||
|
||||
def get_video_launchdata(self):
|
||||
"""Get data required to launch a remote video session to target.
|
||||
|
||||
This is a highly proprietary scenario, the return data may vary greatly
|
||||
host to host. The return should be a dict describing the type of data
|
||||
and the data. For example {'jnlp': jnlpstring}
|
||||
"""
|
||||
self.oem_init()
|
||||
return self._oem.get_video_launchdata()
|
||||
|
||||
def reset_bmc(self):
|
||||
"""Do a cold reset in BMC
|
||||
"""
|
||||
|
@ -27,6 +27,25 @@ class OEMHandler(object):
|
||||
def __init__(self, oemid, ipmicmd):
|
||||
pass
|
||||
|
||||
def register_key_handler(self, callback, type='tls'):
|
||||
"""Assign a verification handler for a public key
|
||||
|
||||
When the library attempts to communicate with the management target
|
||||
using a non-IPMI protocol, it will try to verify a key. This
|
||||
allows a caller to register a key handler for accepting or rejecting
|
||||
a public key/certificate. The callback will be passed the peer public
|
||||
key or certificate.
|
||||
|
||||
:param callback: The function to call with public key/certificate
|
||||
:param type: Whether the callback is meant to handle 'tls' or 'ssh',
|
||||
defaults to 'tls'
|
||||
"""
|
||||
if type == 'tls':
|
||||
self._certverify = callback
|
||||
|
||||
def get_video_launchdata(self):
|
||||
return {}
|
||||
|
||||
def process_event(self, event, ipmicmd, seldata):
|
||||
"""Modify an event according with OEM understanding.
|
||||
|
||||
|
@ -33,6 +33,8 @@ from pyghmi.ipmi.oem.lenovo import psu
|
||||
from pyghmi.ipmi.oem.lenovo import raid_controller
|
||||
from pyghmi.ipmi.oem.lenovo import raid_drive
|
||||
|
||||
#import pyghmi.util.webclient as wc
|
||||
|
||||
inventory.register_inventory_category(cpu)
|
||||
inventory.register_inventory_category(dimm)
|
||||
inventory.register_inventory_category(pci)
|
||||
@ -115,6 +117,13 @@ class OEMHandler(generic.OEMHandler):
|
||||
self.ipmicmd = ipmicmd
|
||||
self.oem_inventory_info = None
|
||||
|
||||
def get_video_launchdata(self):
|
||||
if self.has_tsm:
|
||||
return self.get_tsm_launchdata()
|
||||
|
||||
def get_tsm_launchdata(self):
|
||||
pass
|
||||
|
||||
def process_event(self, event, ipmicmd, seldata):
|
||||
if 'oemdata' in event:
|
||||
oemtype = seldata[2]
|
||||
|
1
pyghmi/util/__init__.py
Normal file
1
pyghmi/util/__init__.py
Normal file
@ -0,0 +1 @@
|
||||
__author__ = 'jjohnson2'
|
42
pyghmi/util/webclient.py
Normal file
42
pyghmi/util/webclient.py
Normal file
@ -0,0 +1,42 @@
|
||||
# Copyright 2015 Lenovo
|
||||
#
|
||||
# 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.
|
||||
|
||||
# This provides ability to do HTTPS in a manner like ssh host keys for the
|
||||
# sake of typical internal management devices. Compatibility back to python
|
||||
# 2.6 as is found in commonly used enterprise linux distributions.
|
||||
|
||||
__author__ = 'jjohnson2'
|
||||
import httplib
|
||||
import pyghmi.exceptions as pygexc
|
||||
import socket
|
||||
import ssl
|
||||
|
||||
|
||||
class SecureHTTPConnection(httplib.HTTPConnection):
|
||||
default_port = httplib.HTTPS_PORT
|
||||
|
||||
def __init__(self, host, port=None, key_file=None, cert_file=None,
|
||||
ca_certs=None, strict=None, verifycallback=None, **kwargs):
|
||||
httplib.HTTPConnection.__init__(self, host, port, strict, **kwargs)
|
||||
self.cert_reqs = ssl.CERT_NONE # verification will be done ssh style..
|
||||
self._certverify = verifycallback
|
||||
|
||||
def connect(self):
|
||||
plainsock = socket.create_connection((self.host, self.port))
|
||||
self.sock = ssl.wrap_socket(plainsock, cert_reqs=self.cert_reqs)
|
||||
# txtcert = self.sock.getpeercert() # currently not possible
|
||||
bincert = self.sock.getpeercert(binary_form=True)
|
||||
if not self._certverify(bincert):
|
||||
raise pygexc.UnrecognizedCertificate('Unknown certificate',
|
||||
bincert)
|
Loading…
x
Reference in New Issue
Block a user