From d7bedad2db872afec66c2a9c930d0e39f42cac0d Mon Sep 17 00:00:00 2001 From: CentOS Sources Date: Nov 01 2019 16:29:48 +0000 Subject: import pywbem-0.7.0-25.20130827svn625.el7 --- diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..a1850d1 --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +SOURCES/pywbem-20130827.tar.xz diff --git a/.pywbem.metadata b/.pywbem.metadata new file mode 100644 index 0000000..c1350c6 --- /dev/null +++ b/.pywbem.metadata @@ -0,0 +1 @@ +12344c2915e42cc6abf78d9e81669856e0e528e6 SOURCES/pywbem-20130827.tar.xz diff --git a/SOURCES/pywbem-20130411-mof_compiler-import.patch b/SOURCES/pywbem-20130411-mof_compiler-import.patch new file mode 100644 index 0000000..845deb6 --- /dev/null +++ b/SOURCES/pywbem-20130411-mof_compiler-import.patch @@ -0,0 +1,22 @@ +diff -up pywbem-20130411/mof_compiler.py.bak pywbem-20130411/mof_compiler.py +--- pywbem-20130411/mof_compiler.py.bak 2009-07-30 00:55:26.000000000 +0200 ++++ pywbem-20130411/mof_compiler.py 2013-05-24 17:40:16.684813502 +0200 +@@ -20,12 +20,12 @@ + + import sys + import os +-import lex +-import yacc +-from lex import TOKEN +-from cim_operations import CIMError, WBEMConnection +-from cim_obj import * +-from cim_constants import * ++from pywbem import lex ++from pywbem import yacc ++from pywbem.lex import TOKEN ++from pywbem.cim_operations import CIMError, WBEMConnection ++from pywbem.cim_obj import * ++from pywbem.cim_constants import * + from getpass import getpass + + _optimize = 1 diff --git a/SOURCES/pywbem-20130723-shebang.patch b/SOURCES/pywbem-20130723-shebang.patch new file mode 100644 index 0000000..acb3453 --- /dev/null +++ b/SOURCES/pywbem-20130723-shebang.patch @@ -0,0 +1,9 @@ +diff -up pywbem-20130723/mof_compiler.py.orig pywbem-20130723/mof_compiler.py +--- pywbem-20130723/mof_compiler.py.orig 2013-08-15 09:35:10.961057738 +0200 ++++ pywbem-20130723/mof_compiler.py 2013-08-15 09:35:16.255079334 +0200 +@@ -1,4 +1,4 @@ +-#!/usr/bin/env python ++#!/usr/bin/python + # + # (C) Copyright 2006-2007 Novell, Inc. + # diff --git a/SOURCES/pywbem-20131121-dry-run.patch b/SOURCES/pywbem-20131121-dry-run.patch new file mode 100644 index 0000000..44a1b6e --- /dev/null +++ b/SOURCES/pywbem-20131121-dry-run.patch @@ -0,0 +1,44 @@ +commit 754e24718e00fb7e5ec10fb1c01bc9521ff4e7a0 +Author: jsafranek +Date: Thu Nov 21 13:46:57 2013 +0000 + + mof_compiler: Add '-d' option to dry-run the operation. + + It just checks the mof file syntax. + + The idea behind this patch is to easily detect included mof files from 'mof_compiler -v -d' output. + + git-svn-id: https://svn.code.sf.net/p/pywbem/code/pywbem/trunk@626 84f79d66-d411-0410-a85a-a3183736c6e8 + +diff --git a/mof_compiler.py b/mof_compiler.py +index d1dd333..84f33d4 100644 +--- a/mof_compiler.py ++++ b/mof_compiler.py +@@ -1680,6 +1680,9 @@ if __name__ == '__main__': + oparser.add_option('-p', '--password', + dest='password', metavar='Password', + help='Specify the password') ++ oparser.add_option('-d', '--dry-run', ++ dest='dry_run', default=False, action='store_true', ++ help="Don't actually modify the repository, just check mof file syntax. Connection to CIMOM is still required to check qualifiers.") + + (options, args) = oparser.parse_args() + search = options.search +@@ -1695,7 +1698,7 @@ if __name__ == '__main__': + conn = WBEMConnection(options.url, (options.username, passwd)) + else: + conn = WBEMConnection(options.url) +- if options.remove: ++ if options.remove or options.dry_run: + conn = MOFWBEMConnection(conn=conn) + #conn.debug = True + conn.default_namespace = options.ns +@@ -1728,7 +1731,5 @@ if __name__ == '__main__': + except CIMError, ce: + sys.exit(1) + +- if options.remove: ++ if options.remove and not options.dry_run: + conn.rollback(verbose=options.verbose) +- +- diff --git a/SOURCES/pywbem-20131121-local_root_auth.patch b/SOURCES/pywbem-20131121-local_root_auth.patch new file mode 100644 index 0000000..ce80f39 --- /dev/null +++ b/SOURCES/pywbem-20131121-local_root_auth.patch @@ -0,0 +1,50 @@ +Index: pywbem-20131121/cim_http.py +=================================================================== +--- pywbem-20131121.orig/cim_http.py ++++ pywbem-20131121/cim_http.py +@@ -42,6 +42,33 @@ class AuthError(Error): + """This exception is raised when an authentication error (401) occurs.""" + pass + ++try: ++ import pwd ++ def get_user_name(uid=None): ++ """Return user name for given uid. ++ :param int uid: User id of user whose name is desired. ++ If not given, current user will be assumed. ++ """ ++ try: ++ if uid is None: ++ uid = os.getuid() ++ return pwd.getpwuid(uid).pw_name ++ except KeyError: ++ pass ++except ImportError: # pwd is available only on *nix ++ def get_user_name(uid=None): ++ """ ++ Return user name of current user. ++ :param int uid: Optional argument. Note that uid may be equal only ++ to current user's id, otherwise an exception will be raised. ++ """ ++ if uid is not None and uid != os.getuid(): ++ raise ValueError("Can not get user name for other user.") ++ try: ++ return getpass.getuser() ++ except KeyError: ++ pass ++ + def parse_url(url): + """Return a tuple of (host, port, ssl) from the URL parameter. + The returned port defaults to 5988 if not specified. SSL supports +@@ -226,10 +253,7 @@ def wbem_request(url, data, creds, heade + local = True + if local: + uid = os.getuid() +- try: +- locallogin = getpass.getuser() +- except KeyError: +- locallogin = None ++ locallogin = get_user_name(uid) + while numTries < tryLimit: + numTries = numTries + 1 + diff --git a/SOURCES/pywbem-20131121-ssl_verify_host.patch b/SOURCES/pywbem-20131121-ssl_verify_host.patch new file mode 100644 index 0000000..a707e42 --- /dev/null +++ b/SOURCES/pywbem-20131121-ssl_verify_host.patch @@ -0,0 +1,270 @@ +Index: pywbem-20131121/cim_http.py +=================================================================== +--- pywbem-20131121.orig/cim_http.py ++++ pywbem-20131121/cim_http.py +@@ -28,6 +28,7 @@ being transferred is XML. It is up to t + data and interpret the result. + ''' + ++from M2Crypto import SSL, Err + import sys, string, re, os, socket, getpass + from stat import S_ISSOCK + import cim_obj +@@ -74,8 +75,26 @@ def parse_url(url): + + return host, port, ssl + ++def get_default_ca_certs(): ++ """ ++ Try to find out system path with ca certificates. This path is cached and ++ returned. If no path is found out, None is returned. ++ """ ++ if not hasattr(get_default_ca_certs, '_path'): ++ for path in ( ++ '/etc/pki/ca-trust/extracted/openssl/ca-bundle.trust.crt', ++ '/etc/ssl/certs', ++ '/etc/ssl/certificates'): ++ if os.path.exists(path): ++ get_default_ca_certs._path = path ++ break ++ else: ++ get_default_ca_certs._path = None ++ return get_default_ca_certs._path ++ + def wbem_request(url, data, creds, headers = [], debug = 0, x509 = None, +- verify_callback = None): ++ verify_callback = None, ca_certs = None, ++ no_verification = False): + """Send XML data over HTTP to the specified url. Return the + response in XML. Uses Python's build-in httplib. x509 may be a + dictionary containing the location of the SSL certificate and key +@@ -105,10 +124,49 @@ def wbem_request(url, data, creds, heade + + class HTTPSConnection(HTTPBaseConnection, httplib.HTTPSConnection): + def __init__(self, host, port=None, key_file=None, cert_file=None, +- strict=None): ++ strict=None, ca_certs=None, verify_callback=None): + httplib.HTTPSConnection.__init__(self, host, port, key_file, + cert_file, strict) +- ++ self.ca_certs = ca_certs ++ self.verify_callback = verify_callback ++ ++ def connect(self): ++ "Connect to a host on a given (SSL) port." ++ self.sock = socket.create_connection((self.host, self.port), ++ self.timeout, self.source_address) ++ if self._tunnel_host: ++ self.sock = sock ++ self._tunnel() ++ ctx = SSL.Context('sslv23') ++ if self.cert_file: ++ ctx.load_cert(self.cert_file, keyfile=self.key_file) ++ if self.ca_certs: ++ ctx.set_verify(SSL.verify_peer | SSL.verify_fail_if_no_peer_cert, ++ depth=9, callback=verify_callback) ++ if os.path.isdir(self.ca_certs): ++ ctx.load_verify_locations(capath=self.ca_certs) ++ else: ++ ctx.load_verify_locations(cafile=self.ca_certs) ++ try: ++ self.sock = SSL.Connection(ctx, self.sock) ++ # Below is a body of SSL.Connection.connect() method ++ # except for the first line (socket connection). We want to preserve ++ # tunneling ability. ++ self.sock.addr = (self.host, self.port) ++ self.sock.setup_ssl() ++ self.sock.set_connect_state() ++ ret = self.sock.connect_ssl() ++ if self.ca_certs: ++ check = getattr(self.sock, 'postConnectionCheck', ++ self.sock.clientPostConnectionCheck) ++ if check is not None: ++ if not check(self.sock.get_peer_cert(), self.host): ++ raise Error('SSL error: post connection check failed') ++ return ret ++ except ( Err.SSLError, SSL.SSLError, SSL.SSLTimeoutError ++ , SSL.Checker.WrongHost), arg: ++ raise Error("SSL error: %s" % arg) ++ + class FileHTTPConnection(HTTPBaseConnection, httplib.HTTPConnection): + def __init__(self, uds_path): + httplib.HTTPConnection.__init__(self, 'localhost') +@@ -117,64 +175,36 @@ def wbem_request(url, data, creds, heade + self.sock = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM) + self.sock.connect(self.uds_path) + +- host, port, ssl = parse_url(url) ++ host, port, use_ssl = parse_url(url) + + key_file = None + cert_file = None + +- if ssl: +- +- if x509 is not None: +- cert_file = x509.get('cert_file') +- key_file = x509.get('key_file') +- +- if verify_callback is not None: +- addr_ind = 0 +- # Temporary exception store +- addr_exc = None +- # Get a list of arguments for socket(). +- addr_list = socket.getaddrinfo(host, port, 0, socket.SOCK_STREAM) +- for addr_ind in xrange(len(addr_list)): +- family, socktype, proto, canonname, sockaddr = addr_list[addr_ind] +- try: +- from OpenSSL import SSL +- ctx = SSL.Context(SSL.SSLv3_METHOD) +- ctx.set_verify(SSL.VERIFY_PEER, verify_callback) +- ctx.set_default_verify_paths() +- # Add the key and certificate to the session +- if cert_file is not None and key_file is not None: +- ctx.use_certificate_file(cert_file) +- ctx.use_privatekey_file(key_file) +- s = SSL.Connection(ctx, socket.socket(family, socktype, proto)) +- s.connect((host, port)) +- s.do_handshake() +- s.shutdown() +- s.close() +- addr_exc = None +- break +- except (socket.gaierror, socket.error), arg: +- # Could not perform connect() call, store the exception object for +- # later use. +- addr_exc = arg +- continue +- except socket.sslerror, arg: +- raise Error("SSL error: %s" % (arg,)) +- +- # Did we try all the addresses from getaddrinfo() and no successful +- # connection performed? +- if addr_exc: +- raise Error("Socket error: %s" % (addr_exc),) ++ if use_ssl and x509 is not None: ++ cert_file = x509.get('cert_file') ++ key_file = x509.get('key_file') + + numTries = 0 + localAuthHeader = None + tryLimit = 5 + ++ if isinstance(data, unicode): ++ data = data.encode('utf-8') + data = '\n' + data + ++ if not no_verification and ca_certs is None: ++ ca_certs = get_default_ca_certs() ++ elif no_verification: ++ ca_certs = None ++ + local = False +- if ssl: +- h = HTTPSConnection(host, port = port, key_file = key_file, +- cert_file = cert_file) ++ if use_ssl: ++ h = HTTPSConnection(host, ++ port = port, ++ key_file = key_file, ++ cert_file = cert_file, ++ ca_certs = ca_certs, ++ verify_callback = verify_callback) + else: + if url.startswith('http'): + h = HTTPConnection(host, port = port) +@@ -216,6 +246,8 @@ def wbem_request(url, data, creds, heade + h.putheader('PegasusAuthorization', 'Local "%s"' % locallogin) + + for hdr in headers: ++ if isinstance(hdr, unicode): ++ hdr = hdr.encode('utf-8') + s = map(lambda x: string.strip(x), string.split(hdr, ":", 1)) + h.putheader(urllib.quote(s[0]), urllib.quote(s[1])) + +Index: pywbem-20131121/cim_operations.py +=================================================================== +--- pywbem-20131121.orig/cim_operations.py ++++ pywbem-20131121/cim_operations.py +@@ -78,12 +78,12 @@ class WBEMConnection(object): + the request before it is sent, and the reply before it is + unpacked. + +- verify_callback is used to verify the server certificate. +- It is passed to OpenSSL.SSL.set_verify, and is called during the SSL +- handshake. verify_callback should take five arguments: A Connection +- object, an X509 object, and three integer variables, which are in turn +- potential error number, error depth and return code. verify_callback +- should return True if verification passes and False otherwise. ++ verify_callback is used to verify the server certificate. It is passed to ++ M2Crypto.SSL.Context.set_verify, and is called during the SSL handshake. ++ verify_callback should take five arguments: An SSL Context object, an X509 ++ object, and three integer variables, which are in turn potential error ++ number, error depth and return code. verify_callback should return True if ++ verification passes and False otherwise. + + The value of the x509 argument is used only when the url contains + 'https'. x509 must be a dictionary containing the keys 'cert_file' +@@ -91,14 +91,27 @@ class WBEMConnection(object): + filename of an certificate and the value of 'key_file' must consist + of a filename containing the private key belonging to the public key + that is part of the certificate in cert_file. ++ ++ ca_certs specifies where CA certificates for verification purposes are ++ located. These are trusted certificates. Note that the certificates have to ++ be in PEM format. Either it is a directory prepared using the c_rehash tool ++ included with OpenSSL or an pemfile. If None, default system path will be ++ used. ++ ++ no_verification allows to disable peer's verification. This is insecure and ++ should be avoided. If True, peer's certificate is not verified and ca_certs ++ argument is ignored. + """ + + def __init__(self, url, creds = None, default_namespace = DEFAULT_NAMESPACE, +- x509 = None, verify_callback = None): ++ x509 = None, verify_callback = None, ca_certs = None, ++ no_verification = False): + self.url = url + self.creds = creds + self.x509 = x509 + self.verify_callback = verify_callback ++ self.ca_certs = ca_certs ++ self.no_verification = no_verification + self.last_request = self.last_reply = '' + self.default_namespace = default_namespace + self.debug = False +@@ -164,7 +177,9 @@ class WBEMConnection(object): + resp_xml = cim_http.wbem_request(self.url, req_xml.toxml(), + self.creds, headers, + x509 = self.x509, +- verify_callback = self.verify_callback) ++ verify_callback = self.verify_callback, ++ ca_certs = self.ca_certs, ++ no_verification = self.no_verification) + except cim_http.AuthError: + raise + except cim_http.Error, arg: +@@ -321,7 +336,9 @@ class WBEMConnection(object): + resp_xml = cim_http.wbem_request(self.url, req_xml.toxml(), + self.creds, headers, + x509 = self.x509, +- verify_callback = self.verify_callback) ++ verify_callback = self.verify_callback, ++ ca_certs = self.ca_certs, ++ no_verification = self.no_verification) + except cim_http.Error, arg: + # Convert cim_http exceptions to CIMError exceptions + raise CIMError(0, str(arg)) +Index: pywbem-20131121/setup.py +=================================================================== +--- pywbem-20131121.orig/setup.py ++++ pywbem-20131121/setup.py +@@ -37,6 +37,7 @@ args = {'name': 'pywbem', + 'version': '0.7.0', + 'license': 'LGPLv2', + 'packages': ['pywbem'], ++ 'install_requires': ['M2Crypto'], + # Make packages in root dir appear in pywbem module + 'package_dir': {'pywbem': ''}, + # Make extensions in root dir appear in pywbem module diff --git a/SOURCES/pywbem-20131121-utf_encoding.patch b/SOURCES/pywbem-20131121-utf_encoding.patch new file mode 100644 index 0000000..0adb380 --- /dev/null +++ b/SOURCES/pywbem-20131121-utf_encoding.patch @@ -0,0 +1,112 @@ +Index: pywbem-20130827/cim_obj.py +=================================================================== +--- pywbem-20130827.orig/cim_obj.py ++++ pywbem-20130827/cim_obj.py +@@ -391,7 +391,7 @@ class CIMProperty(object): + if value is not None: + if value: + if self.embedded_object is not None: +- value = [v.tocimxml().toxml() for v in value] ++ value = [v.tocimxml().toxml(encoding='utf-8') for v in value] + value = VALUE_ARRAY([VALUE(atomic_to_cim_xml(v)) for v in value]) + + return PROPERTY_ARRAY( +@@ -422,7 +422,7 @@ class CIMProperty(object): + value = self.value + if value is not None: + if self.embedded_object is not None: +- value = value.tocimxml().toxml() ++ value = value.tocimxml().toxml(encoding='utf-8') + else: + value = atomic_to_cim_xml(value) + value = VALUE(value) +@@ -599,9 +599,9 @@ class CIMInstanceName(object): + # long or float + _type = 'numeric' + value = str(kb[1]) +- elif type(kb[1]) == str or type(kb[1]) == unicode: ++ elif isinstance(kb[1], basestring): + _type = 'string' +- value = kb[1] ++ value = kb[1].decode('utf-8') if isinstance(kb[1], str) else kb[1] + else: + raise TypeError( + 'Invalid keybinding type for keybinding ' '%s: %s' % (kb[0],`type(kb[1])`)) +@@ -1341,7 +1341,8 @@ def tocimxml(value): + + if isinstance(value, cim_types.CIMType) or \ + type(value) in (str, unicode, int): +- return cim_xml.VALUE(unicode(value)) ++ value = value.decode('utf-8') if isinstance(value, str) else unicode(value) ++ return cim_xml.VALUE(value) + + if isinstance(value, bool): + if value: +Index: pywbem-20130827/cim_operations.py +=================================================================== +--- pywbem-20130827.orig/cim_operations.py ++++ pywbem-20130827/cim_operations.py +@@ -165,8 +165,8 @@ class WBEMConnection(object): + '2.0', '2.0') + + if self.debug: +- self.last_raw_request = req_xml.toxml() +- self.last_request = req_xml.toprettyxml(indent=' ') ++ self.last_raw_request = req_xml.toxml(encoding='utf-8') ++ self.last_request = req_xml.toprettyxml(indent=' ', encoding='utf-8') + + self.last_reply = None + self.last_raw_reply = None +@@ -174,7 +174,7 @@ class WBEMConnection(object): + # Get XML response + + try: +- resp_xml = cim_http.wbem_request(self.url, req_xml.toxml(), ++ resp_xml = cim_http.wbem_request(self.url, req_xml.toxml(encoding='utf-8'), + self.creds, headers, + x509 = self.x509, + verify_callback = self.verify_callback, +@@ -192,7 +192,7 @@ class WBEMConnection(object): + reply_dom = minidom.parseString(resp_xml) + + if self.debug: +- self.last_reply = reply_dom.toprettyxml(indent=' ') ++ self.last_reply = reply_dom.toprettyxml(indent=' ', encoding='utf-8') + self.last_raw_reply = resp_xml + + # Parse response +@@ -292,7 +292,7 @@ class WBEMConnection(object): + if isinstance(obj, (CIMClassName, CIMInstanceName)): + return cim_xml.VALUE_REFERENCE(obj.tocimxml()) + if isinstance(obj, (CIMClass, CIMInstance)): +- return cim_xml.VALUE(obj.tocimxml().toxml()) ++ return cim_xml.VALUE(obj.tocimxml().toxml(encoding='utf-8')) + if isinstance(obj, list): + if obj and isinstance(obj[0], (CIMClassName, CIMInstanceName)): + return cim_xml.VALUE_REFARRAY([paramvalue(x) for x in obj]) +@@ -328,12 +328,12 @@ class WBEMConnection(object): + '2.0', '2.0') + + if self.debug: +- self.last_request = req_xml.toprettyxml(indent=' ') ++ self.last_request = req_xml.toprettyxml(indent=' ', encoding='utf-8') + + # Get XML response + + try: +- resp_xml = cim_http.wbem_request(self.url, req_xml.toxml(), ++ resp_xml = cim_http.wbem_request(self.url, req_xml.toxml(encoding='utf-8'), + self.creds, headers, + x509 = self.x509, + verify_callback = self.verify_callback, +Index: pywbem-20130827/cim_types.py +=================================================================== +--- pywbem-20130827.orig/cim_types.py ++++ pywbem-20130827/cim_types.py +@@ -258,5 +258,5 @@ def atomic_to_cim_xml(obj): + elif cimtype(obj) == 'real64': + return u'%.16E' % obj + else: +- return unicode(obj) ++ return obj.decode('utf-8') if isinstance(obj, str) else unicode(obj) + diff --git a/SOURCES/pywbem-remove-twisted.patch b/SOURCES/pywbem-remove-twisted.patch new file mode 100644 index 0000000..db36a63 --- /dev/null +++ b/SOURCES/pywbem-remove-twisted.patch @@ -0,0 +1,742 @@ +Common subdirectories: old/irecv and pywbem-20130702/irecv +Common subdirectories: old/testsuite and pywbem-20130702/testsuite +diff -u -N old/twisted_client.py pywbem-20130702/twisted_client.py +--- old/twisted_client.py 2010-08-05 02:03:34.000000000 +0200 ++++ pywbem-20130702/twisted_client.py 1970-01-01 01:00:00.000000000 +0100 +@@ -1,736 +0,0 @@ +-# +-# (C) Copyright 2005,2007 Hewlett-Packard Development Company, L.P. +-# +-# This program is free software; you can redistribute it and/or modify +-# it under the terms of the GNU Lesser General Public License as +-# published by the Free Software Foundation; version 2 of the License. +-# +-# This program is distributed in the hope that it will be useful, +-# but WITHOUT ANY WARRANTY; without even the implied warranty of +-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +-# GNU Lesser General Public License for more details. +-# +-# You should have received a copy of the GNU Lesser General Public +-# License along with this program; if not, write to the Free Software +-# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +-# +- +-# Author: Tim Potter +- +-"""pywbem.twisted - WBEM client bindings for Twisted Python. +- +-This module contains factory classes that produce WBEMClient instances +-that perform WBEM requests over HTTP using the +-twisted.protocols.http.HTTPClient base class. +-""" +- +-from twisted.internet import reactor, protocol, defer +-from twisted.web import http, client, error +- +-from pywbem import CIMClass, CIMClassName, CIMInstance, CIMInstanceName, CIMError, CIMDateTime, cim_types, cim_xml, cim_obj +- +-try: +- from elementtree.ElementTree import fromstring, tostring +-except ImportError, arg: +- from xml.etree.ElementTree import fromstring, tostring +- +-import string, base64 +- +-from types import StringTypes +-from datetime import datetime, timedelta +- +-class WBEMClient(http.HTTPClient): +- """A HTTPClient subclass that handles WBEM requests.""" +- +- status = None +- +- def connectionMade(self): +- """Send a HTTP POST command with the appropriate CIM over HTTP +- headers and payload.""" +- +- self.factory.request_xml = str(self.factory.payload) +- +- self.sendCommand('POST', '/cimom') +- +- self.sendHeader('Host', '%s:%d' % +- (self.transport.addr[0], self.transport.addr[1])) +- self.sendHeader('User-Agent', 'pywbem/twisted') +- self.sendHeader('Content-length', len(self.factory.payload)) +- self.sendHeader('Content-type', 'application/xml') +- +- if self.factory.creds: +- auth = base64.b64encode('%s:%s' % (self.factory.creds[0], +- self.factory.creds[1])) +- +- self.sendHeader('Authorization', 'Basic %s' % auth) +- +- self.sendHeader('CIMOperation', str(self.factory.operation)) +- self.sendHeader('CIMMethod', str(self.factory.method)) +- self.sendHeader('CIMObject', str(self.factory.object)) +- +- self.endHeaders() +- +- # TODO: Figure out why twisted doesn't support unicode. An +- # exception should be thrown by the str() call if the payload +- # can't be converted to the current codepage. +- +- self.transport.write(str(self.factory.payload)) +- +- def handleResponse(self, data): +- """Called when all response data has been received.""" +- +- self.factory.response_xml = data +- +- if self.status == '200': +- self.factory.parseErrorAndResponse(data) +- +- self.factory.deferred = None +- self.transport.loseConnection() +- +- def handleStatus(self, version, status, message): +- """Save the status code for processing when we get to the end +- of the headers.""" +- +- self.status = status +- self.message = message +- +- def handleHeader(self, key, value): +- """Handle header values.""" +- +- import urllib +- if key == 'CIMError': +- self.CIMError = urllib.unquote(value) +- if key == 'PGErrorDetail': +- self.PGErrorDetail = urllib.unquote(value) +- +- def handleEndHeaders(self): +- """Check whether the status was OK and raise an error if not +- using previously saved header information.""" +- +- if self.status != '200': +- +- if not hasattr(self, 'cimerror') or \ +- not hasattr(self, 'errordetail'): +- +- self.factory.deferred.errback( +- CIMError(0, 'HTTP error %s: %s' % +- (self.status, self.message))) +- +- else: +- +- self.factory.deferred.errback( +- CIMError(0, '%s: %s' % (cimerror, errordetail))) +- +-class WBEMClientFactory(protocol.ClientFactory): +- """Create instances of the WBEMClient class.""" +- +- request_xml = None +- response_xml = None +- xml_header = '' +- +- def __init__(self, creds, operation, method, object, payload): +- self.creds = creds +- self.operation = operation +- self.method = method +- self.object = object +- self.payload = payload +- self.protocol = lambda: WBEMClient() +- self.deferred = defer.Deferred() +- +- def clientConnectionFailed(self, connector, reason): +- if self.deferred is not None: +- reactor.callLater(0, self.deferred.errback, reason) +- +- def clientConnectionLost(self, connector, reason): +- if self.deferred is not None: +- reactor.callLater(0, self.deferred.errback, reason) +- +- def imethodcallPayload(self, methodname, localnsp, **kwargs): +- """Generate the XML payload for an intrinsic methodcall.""" +- +- param_list = [pywbem.IPARAMVALUE(x[0], pywbem.tocimxml(x[1])) +- for x in kwargs.items()] +- +- payload = pywbem.CIM( +- pywbem.MESSAGE( +- pywbem.SIMPLEREQ( +- pywbem.IMETHODCALL( +- methodname, +- pywbem.LOCALNAMESPACEPATH( +- [pywbem.NAMESPACE(ns) +- for ns in string.split(localnsp, '/')]), +- param_list)), +- '1001', '1.0'), +- '2.0', '2.0') +- +- return self.xml_header + payload.toxml() +- +- def methodcallPayload(self, methodname, obj, namespace, **kwargs): +- """Generate the XML payload for an extrinsic methodcall.""" +- +- if isinstance(obj, CIMInstanceName): +- +- path = obj.copy() +- +- path.host = None +- path.namespace = None +- +- localpath = pywbem.LOCALINSTANCEPATH( +- pywbem.LOCALNAMESPACEPATH( +- [pywbem.NAMESPACE(ns) +- for ns in string.split(namespace, '/')]), +- path.tocimxml()) +- else: +- localpath = pywbem.LOCALCLASSPATH( +- pywbem.LOCALNAMESPACEPATH( +- [pywbem.NAMESPACE(ns) +- for ns in string.split(namespace, '/')]), +- obj) +- +- def paramtype(obj): +- """Return a string to be used as the CIMTYPE for a parameter.""" +- if isinstance(obj, cim_types.CIMType): +- return obj.cimtype +- elif type(obj) == bool: +- return 'boolean' +- elif isinstance(obj, StringTypes): +- return 'string' +- elif isinstance(obj, (datetime, timedelta)): +- return 'datetime' +- elif isinstance(obj, (CIMClassName, CIMInstanceName)): +- return 'reference' +- elif isinstance(obj, (CIMClass, CIMInstance)): +- return 'string' +- elif isinstance(obj, list): +- return paramtype(obj[0]) +- raise TypeError('Unsupported parameter type "%s"' % type(obj)) +- +- def paramvalue(obj): +- """Return a cim_xml node to be used as the value for a +- parameter.""" +- if isinstance(obj, (datetime, timedelta)): +- obj = CIMDateTime(obj) +- if isinstance(obj, (cim_types.CIMType, bool, StringTypes)): +- return cim_xml.VALUE(cim_types.atomic_to_cim_xml(obj)) +- if isinstance(obj, (CIMClassName, CIMInstanceName)): +- return cim_xml.VALUE_REFERENCE(obj.tocimxml()) +- if isinstance(obj, (CIMClass, CIMInstance)): +- return cim_xml.VALUE(obj.tocimxml().toxml()) +- if isinstance(obj, list): +- if isinstance(obj[0], (CIMClassName, CIMInstanceName)): +- return cim_xml.VALUE_REFARRAY([paramvalue(x) for x in obj]) +- return cim_xml.VALUE_ARRAY([paramvalue(x) for x in obj]) +- raise TypeError('Unsupported parameter type "%s"' % type(obj)) +- +- param_list = [pywbem.PARAMVALUE(x[0], +- paramvalue(x[1]), +- paramtype(x[1])) +- for x in kwargs.items()] +- +- payload = pywbem.CIM( +- pywbem.MESSAGE( +- pywbem.SIMPLEREQ( +- pywbem.METHODCALL(methodname, +- localpath, +- param_list)), +- '1001', '1.0'), +- '2.0', '2.0') +- +- return self.xml_header + payload.toxml() +- +- def parseErrorAndResponse(self, data): +- """Parse returned XML for errors, then convert into +- appropriate Python objects.""" +- +- xml = fromstring(data) +- error = xml.find('.//ERROR') +- +- if error is None: +- self.deferred.callback(self.parseResponse(xml)) +- return +- +- try: +- code = int(error.attrib['CODE']) +- except ValueError: +- code = 0 +- +- self.deferred.errback(CIMError(code, error.attrib['DESCRIPTION'])) +- +- def parseResponse(self, xml): +- """Parse returned XML and convert into appropriate Python +- objects. Override in subclass""" +- +- pass +- +-# TODO: Eww - we should get rid of the tupletree, tupleparse modules +-# and replace with elementtree based code. +- +-import pywbem.tupletree +- +-class EnumerateInstances(WBEMClientFactory): +- """Factory to produce EnumerateInstances WBEM clients.""" +- +- def __init__(self, creds, classname, namespace = 'root/cimv2', **kwargs): +- +- self.classname = classname +- self.namespace = namespace +- +- payload = self.imethodcallPayload( +- 'EnumerateInstances', +- namespace, +- ClassName = CIMClassName(classname), +- **kwargs) +- +- WBEMClientFactory.__init__( +- self, +- creds, +- operation = 'MethodCall', +- method = 'EnumerateInstances', +- object = namespace, +- payload = payload) +- +- def __repr__(self): +- return '<%s(/%s:%s) at 0x%x>' % \ +- (self.__class__, self.namespace, self.classname, id(self)) +- +- def parseResponse(self, xml): +- +- tt = [pywbem.tupletree.xml_to_tupletree(tostring(x)) +- for x in xml.findall('.//VALUE.NAMEDINSTANCE')] +- +- return [pywbem.tupleparse.parse_value_namedinstance(x) for x in tt] +- +-class EnumerateInstanceNames(WBEMClientFactory): +- """Factory to produce EnumerateInstanceNames WBEM clients.""" +- +- def __init__(self, creds, classname, namespace = 'root/cimv2', **kwargs): +- +- self.classname = classname +- self.namespace = namespace +- +- payload = self.imethodcallPayload( +- 'EnumerateInstanceNames', +- namespace, +- ClassName = CIMClassName(classname), +- **kwargs) +- +- WBEMClientFactory.__init__( +- self, +- creds, +- operation = 'MethodCall', +- method = 'EnumerateInstanceNames', +- object = namespace, +- payload = payload) +- +- def __repr__(self): +- return '<%s(/%s:%s) at 0x%x>' % \ +- (self.__class__, self.namespace, self.classname, id(self)) +- +- def parseResponse(self, xml): +- +- tt = [pywbem.tupletree.xml_to_tupletree(tostring(x)) +- for x in xml.findall('.//INSTANCENAME')] +- +- names = [pywbem.tupleparse.parse_instancename(x) for x in tt] +- +- [setattr(n, 'namespace', self.namespace) for n in names] +- +- return names +- +-class GetInstance(WBEMClientFactory): +- """Factory to produce GetInstance WBEM clients.""" +- +- def __init__(self, creds, instancename, namespace = 'root/cimv2', **kwargs): +- +- self.instancename = instancename +- self.namespace = namespace +- +- payload = self.imethodcallPayload( +- 'GetInstance', +- namespace, +- InstanceName = instancename, +- **kwargs) +- +- WBEMClientFactory.__init__( +- self, +- creds, +- operation = 'MethodCall', +- method = 'GetInstance', +- object = namespace, +- payload = payload) +- +- def __repr__(self): +- return '<%s(/%s:%s) at 0x%x>' % \ +- (self.__class__, self.namespace, self.instancename, id(self)) +- +- def parseResponse(self, xml): +- +- tt = pywbem.tupletree.xml_to_tupletree( +- tostring(xml.find('.//INSTANCE'))) +- +- return pywbem.tupleparse.parse_instance(tt) +- +-class DeleteInstance(WBEMClientFactory): +- """Factory to produce DeleteInstance WBEM clients.""" +- +- def __init__(self, creds, instancename, namespace = 'root/cimv2', **kwargs): +- +- self.instancename = instancename +- self.namespace = namespace +- +- payload = self.imethodcallPayload( +- 'DeleteInstance', +- namespace, +- InstanceName = instancename, +- **kwargs) +- +- WBEMClientFactory.__init__( +- self, +- creds, +- operation = 'MethodCall', +- method = 'DeleteInstance', +- object = namespace, +- payload = payload) +- +- def __repr__(self): +- return '<%s(/%s:%s) at 0x%x>' % \ +- (self.__class__, self.namespace, self.instancename, id(self)) +- +-class CreateInstance(WBEMClientFactory): +- """Factory to produce CreateInstance WBEM clients.""" +- +- # TODO: Implement __repr__ method +- +- def __init__(self, creds, instance, namespace = 'root/cimv2', **kwargs): +- +- payload = self.imethodcallPayload( +- 'CreateInstance', +- namespace, +- NewInstance = instance, +- **kwargs) +- +- WBEMClientFactory.__init__( +- self, +- creds, +- operation = 'MethodCall', +- method = 'CreateInstance', +- object = namespace, +- payload = payload) +- +- def parseResponse(self, xml): +- +- tt = pywbem.tupletree.xml_to_tupletree( +- tostring(xml.find('.//INSTANCENAME'))) +- +- return pywbem.tupleparse.parse_instancename(tt) +- +-class ModifyInstance(WBEMClientFactory): +- """Factory to produce ModifyInstance WBEM clients.""" +- +- # TODO: Implement __repr__ method +- +- def __init__(self, creds, instancename, instance, namespace = 'root/cimv2', +- **kwargs): +- +- wrapped_instance = CIMNamedInstance(instancename, instance) +- +- payload = self.imethodcallPayload( +- 'ModifyInstance', +- namespace, +- ModifiedInstance = wrapped_instance, +- **kwargs) +- +- WBEMClientFactory.__init__( +- self, +- creds, +- operation = 'MethodCall', +- method = 'ModifyInstance', +- object = namespace, +- payload = payload) +- +-class EnumerateClassNames(WBEMClientFactory): +- """Factory to produce EnumerateClassNames WBEM clients.""" +- +- def __init__(self, creds, namespace = 'root/cimv2', **kwargs): +- +- self.localnsp = LocalNamespacePath +- +- payload = self.imethodcallPayload( +- 'EnumerateClassNames', +- namespace, +- **kwargs) +- +- WBEMClientFactory.__init__( +- self, +- creds, +- operation = 'MethodCall', +- method = 'EnumerateClassNames', +- object = LocalNamespacePath, +- payload = payload) +- +- def __repr__(self): +- return '<%s(/%s) at 0x%x>' % \ +- (self.__class__, self.namespace, id(self)) +- +- def parseResponse(self, xml): +- +- tt = [pywbem.tupletree.xml_to_tupletree(tostring(x)) +- for x in xml.findall('.//CLASSNAME')] +- +- return [pywbem.tupleparse.parse_classname(x) for x in tt] +- +-class EnumerateClasses(WBEMClientFactory): +- """Factory to produce EnumerateClasses WBEM clients.""" +- +- def __init__(self, creds, namespace = 'root/cimv2', **kwargs): +- +- self.localnsp = LocalNamespacePath +- +- payload = self.imethodcallPayload( +- 'EnumerateClasses', +- namespace, +- **kwargs) +- +- WBEMClientFactory.__init__( +- self, +- creds, +- operation = 'MethodCall', +- method = 'EnumerateClasses', +- object = namespace, +- payload = payload) +- +- def __repr__(self): +- return '<%s(/%s) at 0x%x>' % \ +- (self.__class__, self.namespace, id(self)) +- +- def parseResponse(self, xml): +- +- tt = [pywbem.tupletree.xml_to_tupletree(tostring(x)) +- for x in xml.findall('.//CLASS')] +- +- return [pywbem.tupleparse.parse_class(x) for x in tt] +- +-class GetClass(WBEMClientFactory): +- """Factory to produce GetClass WBEM clients.""" +- +- def __init__(self, creds, classname, namespace = 'root/cimv2', **kwargs): +- +- self.classname = classname +- self.namespace = namespace +- +- payload = self.imethodcallPayload( +- 'GetClass', +- namespace, +- ClassName = CIMClassName(classname), +- **kwargs) +- +- WBEMClientFactory.__init__( +- self, +- creds, +- operation = 'MethodCall', +- method = 'GetClass', +- object = namespace, +- payload = payload) +- +- def __repr__(self): +- return '<%s(/%s:%s) at 0x%x>' % \ +- (self.__class__, self.namespace, self.classname, id(self)) +- +- def parseResponse(self, xml): +- +- tt = pywbem.tupletree.xml_to_tupletree( +- tostring(xml.find('.//CLASS'))) +- +- return pywbem.tupleparse.parse_class(tt) +- +-class Associators(WBEMClientFactory): +- """Factory to produce Associators WBEM clients.""" +- +- # TODO: Implement __repr__ method +- +- def __init__(self, creds, obj, namespace = 'root/cimv2', **kwargs): +- +- if isinstance(obj, CIMInstanceName): +- kwargs['ObjectName'] = obj +- else: +- kwargs['ObjectName'] = CIMClassName(obj) +- +- payload = self.imethodcallPayload( +- 'Associators', +- namespace, +- **kwargs) +- +- WBEMClientFactory.__init__( +- self, +- creds, +- operation = 'MethodCall', +- method = 'Associators', +- object = namespace, +- payload = payload) +- +-class AssociatorNames(WBEMClientFactory): +- """Factory to produce AssociatorNames WBEM clients.""" +- +- # TODO: Implement __repr__ method +- +- def __init__(self, creds, obj, namespace = 'root/cimv2', **kwargs): +- +- if isinstance(obj, CIMInstanceName): +- kwargs['ObjectName'] = obj +- else: +- kwargs['ObjectName'] = CIMClassName(obj) +- +- payload = self.imethodcallPayload( +- 'AssociatorNames', +- namespace, +- **kwargs) +- +- WBEMClientFactory.__init__( +- self, +- creds, +- operation = 'MethodCall', +- method = 'AssociatorNames', +- object = namespace, +- payload = payload) +- +- def parseResponse(self, xml): +- +- if len(xml.findall('.//INSTANCENAME')) > 0: +- +- tt = [pywbem.tupletree.xml_to_tupletree(tostring(x)) +- for x in xml.findall('.//INSTANCENAME')] +- +- return [pywbem.tupleparse.parse_instancename(x) for x in tt] +- +- else: +- +- tt = [pywbem.tupletree.xml_to_tupletree(tostring(x)) +- for x in xml.findall('.//OBJECTPATH')] +- +- return [pywbem.tupleparse.parse_objectpath(x)[2] for x in tt] +- +-class References(WBEMClientFactory): +- """Factory to produce References WBEM clients.""" +- +- def __init__(self, creds, obj, namespace = 'root/cimv2', **kwargs): +- +- if isinstance(obj, CIMInstanceName): +- kwargs['ObjectName'] = obj +- else: +- kwargs['ObjectName'] = CIMClassName(obj) +- +- payload = self.imethodcallPayload( +- 'References', +- namespace, +- **kwargs) +- +- WBEMClientFactory.__init__( +- self, +- creds, +- operation = 'MethodCall', +- method = 'References', +- object = namespace, +- payload = payload) +- +-class ReferenceNames(WBEMClientFactory): +- """Factory to produce ReferenceNames WBEM clients.""" +- +- # TODO: Implement __repr__ method +- +- def __init__(self, creds, obj, namespace = 'root/cimv2', **kwargs): +- +- if isinstance(obj, CIMInstanceName): +- kwargs['ObjectName'] = obj +- else: +- kwargs['ObjectName'] = CIMClassName(obj) +- +- payload = self.imethodcallPayload( +- 'ReferenceNames', +- namespace, +- **kwargs) +- +- WBEMClientFactory.__init__( +- self, +- creds, +- operation = 'MethodCall', +- method = 'ReferenceNames', +- object = namespace, +- payload = payload) +- +- def parseResponse(self, xml): +- +- if len(xml.findall('.//INSTANCENAME')) > 0: +- +- tt = [pywbem.tupletree.xml_to_tupletree(tostring(x)) +- for x in xml.findall('.//INSTANCENAME')] +- +- return [pywbem.tupleparse.parse_instancename(x) for x in tt] +- +- else: +- +- tt = [pywbem.tupletree.xml_to_tupletree(tostring(x)) +- for x in xml.findall('.//OBJECTPATH')] +- +- return [pywbem.tupleparse.parse_objectpath(x)[2] for x in tt] +- +-class InvokeMethod(WBEMClientFactory): +- """Factory to produce InvokeMethod WBEM clients.""" +- +- def __init__(self, creds, MethodName, ObjectName, namespace = 'root/cimv2', +- **kwargs): +- +- # Convert string to CIMClassName +- +- obj = ObjectName +- +- if isinstance(obj, StringTypes): +- obj = CIMClassName(obj, namespace = namespace) +- +- if isinstance(obj, CIMInstanceName) and obj.namespace is None: +- obj = ObjectName.copy() +- obj.namespace = namespace +- +- # Make the method call +- +- payload = self.methodcallPayload( +- MethodName, +- obj, +- namespace, +- **kwargs) +- +- WBEMClientFactory.__init__( +- self, +- creds, +- operation = 'MethodCall', +- method = MethodName, +- object = obj, +- payload = payload) +- +- def parseResponse(self, xml): +- +- # Return value of method +- +- result_xml = pywbem.tupletree.xml_to_tupletree( +- tostring(xml.find('.//RETURNVALUE'))) +- +- result_tt = pywbem.tupleparse.parse_any(result_xml) +- +- result = cim_obj.tocimobj(result_tt[1]['PARAMTYPE'], +- result_tt[2]) +- +- # Output parameters +- +- params_xml = [pywbem.tupletree.xml_to_tupletree(tostring(x)) +- for x in xml.findall('.//PARAMVALUE')] +- +- params_tt = [pywbem.tupleparse.parse_any(x) for x in params_xml] +- +- params = {} +- +- for p in params_tt: +- if p[1] == 'reference': +- params[p[0]] = p[2] +- else: +- params[p[0]] = cim_obj.tocimobj(p[1], p[2]) +- +- return (result, params) diff --git a/SPECS/pywbem.spec b/SPECS/pywbem.spec new file mode 100644 index 0000000..bb78d84 --- /dev/null +++ b/SPECS/pywbem.spec @@ -0,0 +1,162 @@ +%{!?python_sitelib: %define python_sitelib %(%{__python} -c "from distutils.sysconfig import get_python_lib; print get_python_lib()")} +%global svnrev 625 +%global revdate 20130827 + +Name: pywbem +Version: 0.7.0 +Release: 25.%{revdate}svn%{svnrev}%{?dist} +Summary: Python WBEM Client and Provider Interface +Group: Development/Libraries +License: LGPLv2 +URL: http://pywbem.sourceforge.net +# The source for this package was pulled from upstream svn repository. +# Use the following commands to get the archive: +# svn export -r 613 svn://svn.code.sf.net/p/pywbem/code/pywbem/trunk pywbem-20130128 +# tar -cJvf pywbem-20130128.tar.xz pywbem-20130128 +Source0: %{name}-%{revdate}.tar.xz +BuildRequires: python-setuptools-devel +BuildRequires: m2crypto +BuildArch: noarch +Requires: m2crypto + +# fix module imports in /usr/bin/mofcomp +Patch0: pywbem-20130411-mof_compiler-import.patch +# Remove python-twisted module, we don't want twisted in RHEL +Patch1: pywbem-remove-twisted.patch +# Use system python, in case someone has enabled software collection +# See bug #987039 +Patch2: pywbem-20130723-shebang.patch +# Add '-d' option to /usr/bin/mofcomp (SVN rev. 626) +# See bug #1031085 +Patch3: pywbem-20131121-dry-run.patch +# See bug rhbz#1026891 +Patch4: pywbem-20131121-ssl_verify_host.patch +Patch5: pywbem-20131121-utf_encoding.patch +Patch6: pywbem-20131121-local_root_auth.patch + +%description +A Python library for making CIM (Common Information Model) operations over HTTP +using the WBEM CIM-XML protocol. It is based on the idea that a good WBEM +client should be easy to use and not necessarily require a large amount of +programming knowledge. It is suitable for a large range of tasks from simply +poking around to writing web and GUI applications. + +WBEM, or Web Based Enterprise Management is a manageability protocol, like +SNMP, standardised by the Distributed Management Task Force (DMTF) available +at http://www.dmtf.org/standards/wbem. + +It also provides a Python provider interface, and is the fastest and +easiest way to write providers on the planet. + +%prep +%setup -q -n %{name}-%{revdate} +%patch0 -p1 -b .mofcomp-imports +%patch1 -p1 +%patch2 -p1 -b .shebang +%patch3 -p1 -b .dry-run +%patch4 -p1 -b .ssl_verifyhost +%patch5 -p1 -b .utf_encoding +%patch6 -p1 -b .local_root_auth + +%build +# dirty workaround to fix the mof_compiler.py module path +ln -s . pywbem +CFLAGS="%{optflags}" %{__python} setup.py build + +%install +rm -rf %{buildroot} +%{__python} setup.py install -O1 --skip-build --root %{buildroot} +mkdir -p -m755 %{buildroot}%{_bindir} +mv %{buildroot}/%{python_sitelib}/%{name}/wbemcli.py %{buildroot}/%{_bindir}/pywbemcli +mv %{buildroot}/%{python_sitelib}/%{name}/mof_compiler.py %{buildroot}/%{_bindir}/mofcomp +rm %{buildroot}/%{python_sitelib}/%{name}/wbemcli.py[co] +rm %{buildroot}/%{python_sitelib}/%{name}/mof_compiler.py[co] + +%clean +rm -rf %{buildroot} + +%files +%{python_sitelib}/* +%attr(755,root,root) %{_bindir}/mofcomp +%attr(755,root,root) %{_bindir}/pywbemcli +%doc README + +%changelog +* Mon Feb 24 2014 Michal Minar 0.7.0-25.20130827svn625 +- Fixed local authentication under root. + +* Wed Jan 22 2014 Michal Minar 0.7.0-24.20130827svn625 +- Added support for non-ascii strings. +- Resolves: rhbz#1056620 + +* Fri Jan 03 2014 Michal Minar 0.7.0-23.20130827svn625 +- Skip hostname check when no verification is desired. + +* Mon Dec 30 2013 Michal Minar 0.7.0-22.20130827svn625 +- Work around M2Crypto's inability to handle unicode strings. + +* Fri Dec 27 2013 Daniel Mach - 0.7.0-21.20130827svn625 +- Mass rebuild 2013-12-27 + +* Thu Dec 19 2013 Michal Minar 0.7.0-20.20130827svn625 +- Adjusted default certificate paths used for verification. + +* Tue Dec 17 2013 Michal Minar 0.7.0-19.20130827svn625 +- Fixes TOCTOU vulnerability in certificate validation. +- Resolves: rhbz#1026891 + +* Thu Nov 21 2013 Jan Safranek 0.7.0-17.20130827svn625 +- Added '-d' option to /usr/bin/mofcomp to just check mof files and their + includes (#1031085). + +* Tue Aug 27 2013 Jan Safranek 0.7.0-16.20130827svn625 +- Fixed parsing of ipv6 addresses. + +* Thu Aug 15 2013 Jan Safranek 0.7.0-15.20130723svn623 +- Fixed /usr/bin/mofcomp shebang to use system python (rhbz#987039). + +* Tue Aug 13 2013 Jan Safranek 0.7.0-14.20130723svn623 +- Fixed certificate verification issue. + +* Tue Jul 23 2013 0.7.0-13.20130723svn623 +- Fixed checking of CIMVERSION in CIM-XML. + +* Tue Jul 16 2013 Jan Safranek 0.7.0-12.20130702svn622 +- Removed dependency on python-twisted. + +* Tue Jul 2 2013 Jan Safranek 0.7.0-11.20130702svn622 +- New upstream version. +- Method parameters are now case-insensitive. + +* Fri May 24 2013 Tomas Bzatek 0.7.0-10.20130411svn619 +- Fix module imports in /usr/bin/mofcomp + +* Thu Apr 11 2013 Jan Safranek 0.7.0-9.20130411svn619 +- New upstream version. +- Removed debug 'print' statements. + +* Mon Jan 28 2013 Michal Minar 0.7.0-8.20130128svn613 +- New upstream version. +- Added post-release snapshot version info. +- Removed obsoleted BuildRoot, + +* Sat Jul 21 2012 Fedora Release Engineering - 0.7.0-7 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_18_Mass_Rebuild + +* Sat Jan 14 2012 Fedora Release Engineering - 0.7.0-6 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_17_Mass_Rebuild + +* Wed Feb 09 2011 Fedora Release Engineering - 0.7.0-5 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_15_Mass_Rebuild + +* Thu Jul 22 2010 David Malcolm - 0.7.0-4 +- Rebuilt for https://fedoraproject.org/wiki/Features/Python_2.7/MassRebuild + +* Fri Jan 01 2010 David Nalley 0.7.0-3 +- refined requires for epel compat +* Sun Jun 28 2009 David Nalley 0.7.0-2 +- Added some verbiage regarding what WBEM is and expanding WBEM and CIM acronyms +- Added python-twisted as a dependency +* Thu Jun 25 2009 David Nalley 0.7.0-1 +- Initial packaging +