2
0
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:
Jarrod Johnson 2015-11-17 15:50:06 -05:00
parent 4cc75b4736
commit 03e3da529b
6 changed files with 105 additions and 0 deletions

View File

@ -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

View File

@ -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
"""

View File

@ -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.

View File

@ -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
View File

@ -0,0 +1 @@
__author__ = 'jjohnson2'

42
pyghmi/util/webclient.py Normal file
View 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)