From c40a11439c738b67471da01ebfbc3d3d66db6311 Mon Sep 17 00:00:00 2001 From: Marek 'marx' Grac Date: Fri, 7 Mar 2014 15:13:44 +0100 Subject: [PATCH] fence_vmware_soap: Add new options --ssl-secure and --ssl-insecure These new options extends current --ssl (same as --ssl-secure). Until now certificate of the fence device was not validated what can possibly lead to attack on infrastructe. With this patch, user can decide if certificate should (--ssl-secure) or should not (--ssl-insecure) be verified. python-suds do not validates SSL certificates at all. It is required to change underlying library to one that can support that what results in new dependency on python-requests. --- fence/agents/vmware_soap/fence_vmware_soap.py | 35 +++++++++++++++++++++--- 1 files changed, 30 insertions(+), 5 deletions(-) diff --git a/fence/agents/vmware_soap/fence_vmware_soap.py b/fence/agents/vmware_soap/fence_vmware_soap.py index bbac1c5..a578662 100644 --- a/fence/agents/vmware_soap/fence_vmware_soap.py +++ b/fence/agents/vmware_soap/fence_vmware_soap.py @@ -2,11 +2,13 @@ import sys, exceptions, time import shutil, tempfile, suds -import logging +import logging, requests sys.path.append("@FENCEAGENTSLIBDIR@") from suds.client import Client from suds.sudsobject import Property +from suds.transport.http import HttpAuthenticated +from suds.transport import Reply, TransportError from fencing import * #BEGIN_VERSION_GENERATION @@ -15,13 +17,32 @@ REDHAT_COPYRIGHT="" BUILD_DATE="April, 2011" #END_VERSION_GENERATION +class RequestsTransport(HttpAuthenticated): + def __init__(self, **kwargs): + self.cert = kwargs.pop('cert', None) + self.verify = kwargs.pop('verify', True) + self.session = requests.Session() + # super won't work because not using new style class + HttpAuthenticated.__init__(self, **kwargs) + + def send(self, request): + self.addcredentials(request) + resp = self.session.post(request.url, data = request.message, headers = request.headers, cert = self.cert, verify = self.verify) + result = Reply(resp.status_code, resp.headers, resp.content) + return result + def soap_login(options): if options["--action"] in ["off", "reboot"]: time.sleep(int(options["--delay"])) - if options.has_key("--ssl"): + if options.has_key("--ssl") or options.has_key("--ssl-secure") or options.has_key("--ssl-insecure"): + if options.has_key("--ssl-insecure"): + verify = False + else: + verify = True url = "https://" else: + verify = False url = "http://" url += options["--ip"] + ":" + str(options["--ipport"]) + "/sdk" @@ -29,10 +50,10 @@ def soap_login(options): tmp_dir = tempfile.mkdtemp() tempfile.tempdir = tmp_dir atexit.register(remove_tmp_dir, tmp_dir) - + try: - conn = Client(url + "/vimService.wsdl") - conn.set_options(location = url) + headers = {"Content-Type" : "text/xml;charset=UTF-8", "SOAPAction" : ""} + conn = Client(url + "/vimService.wsdl", location = url, transport = RequestsTransport(verify = verify), headers = headers) mo_ServiceInstance = Property('ServiceInstance') mo_ServiceInstance._type = 'ServiceInstance' @@ -41,6 +62,8 @@ def soap_login(options): mo_SessionManager._type = 'SessionManager' SessionManager = conn.service.Login(mo_SessionManager, options["--username"], options["--password"]) + except requests.exceptions.SSLError, ex: + fail_usage("Server side certificate verification failed") except Exception, ex: fail(EC_LOGIN_DENIED) @@ -202,6 +225,8 @@ Alternatively you can always use UUID to access virtual machine." logging.basicConfig(level=logging.INFO) logging.getLogger('suds.client').setLevel(logging.CRITICAL) + logging.getLogger("requests").setLevel(logging.CRITICAL) + logging.getLogger("urllib3").setLevel(logging.CRITICAL) ## ## Operate the fencing device -- 1.7.7.6