swaped sudsds for suds

migr_to_suds 3.6.10
idziubenko 3 years ago
parent b2ca07b661
commit 69527ef02c

@ -16,9 +16,10 @@
from calculate.core.server.local_call import Display, Methods, has_force_arg
from calculate.lib.utils.tools import unpack_single_opts
from sudsds import WebFault
from sudsds.transport import TransportError
# from sudsds import WebFault
from suds import WebFault
# from sudsds.transport import TransportError
from suds.transport import TransportError
from client_class import Client_suds
import traceback as tb
import time
@ -383,10 +384,10 @@ def main(wait_thread):
list(unpack_single_opts(sys.argv[1:])))
logging.basicConfig(level=logging.FATAL)
logging.getLogger('sudsds.client').setLevel(logging.FATAL)
logging.getLogger('sudsds.transport').setLevel(logging.FATAL)
logging.getLogger('sudsds.transport.http').setLevel(logging.FATAL)
logging.getLogger('sudsds.umx.typed').setLevel(logging.ERROR)
logging.getLogger('suds.client').setLevel(logging.FATAL)
logging.getLogger('suds.transport').setLevel(logging.FATAL)
logging.getLogger('suds.transport.http').setLevel(logging.FATAL)
logging.getLogger('suds.umx.typed').setLevel(logging.ERROR)
clVarsCore = DataVarsCore()
clVarsCore.importCore()

@ -27,14 +27,26 @@ import hashlib
import M2Crypto
from calculate.core.datavars import DataVarsCore
from calculate.lib.datavars import DataVars
from sudsds.client import Client
# from sudsds.client import Client
from suds.client import Client
from cert_verify import verify, get_CRL
from sudsds.transport.http import (HttpTransport, SUDSHTTPRedirectHandler,
CheckingHTTPSConnection,
CheckingHTTPSHandler,
PYOPENSSL_AVAILABLE, PyOpenSSLSocket)
from sudsds.transport import Transport
from sudsds.properties import Unskin
# from sudsds.transport.http import (HttpTransport, SUDSHTTPRedirectHandler,
# CheckingHTTPSConnection,
# CheckingHTTPSHandler,
# PYOPENSSL_AVAILABLE, PyOpenSSLSocket)
import httplib
from suds.transport.http import HttpTransport
try:
from pyopenssl_wrapper import PyOpenSSLSocket
except ImportError:
PYOPENSSL_AVAILABLE = False
else:
PYOPENSSL_AVAILABLE = True
# from sudsds.transport import Transport
# from sudsds.properties import Unskin
from suds.transport import Transport
from suds.properties import Unskin
from cookielib import CookieJar, DefaultCookiePolicy
from logging import getLogger
from calculate.console.datavars import DataVarsConsole
@ -47,6 +59,122 @@ setLocalTranslate('cl_console3', sys.modules[__name__])
log = getLogger(__name__)
flag = 0
class SUDSHTTPRedirectHandler(u2.HTTPRedirectHandler):
def redirect_request(self, req, fp, code, msg, headers, newurl):
"""Return a Request or None in response to a redirect.
This is called by the http_error_30x methods,
it was taken from the original Python version and modified
to use POST when redirection takes place.
This allows a SOAP message to be redirected without a loss
of content.
"""
m = req.get_method()
if (code in (301, 302, 303, 307) and m in ("GET", "HEAD")
or code in (301, 302, 303) and m == "POST"):
newurl = newurl.replace(' ', '%20')
newheaders = dict((k,v) for k,v in req.headers.items()
if k.lower() not in ("content-length", "content-type")
)
log.debug("Redirecting to %s", newurl)
return u2.Request(newurl,
data=req.data, # here we pass the original data
headers=newheaders,
origin_req_host=req.get_origin_req_host(),
unverifiable=True,
)
else:
raise u2.HTTPError(req.get_full_url(), code, msg, headers, fp)
class MyHTTPResponse(httplib.HTTPResponse):
def __init__(self, sock, debuglevel=0, strict=0, method=None):
httplib.HTTPResponse.__init__(self, sock, debuglevel, strict, method)
class CheckingHTTPSConnection(httplib.HTTPSConnection):
"""based on httplib.HTTPSConnection code - extended to support
server certificate verification and client certificate authorization"""
response_class = MyHTTPResponse
FORCE_SSL_VERSION = None
SERVER_CERT_CHECK = True # might be turned off when a workaround is needed
def __init__(self, host, ca_certs=None, cert_verifier=None,
keyobj=None, certobj=None, **kw):
"""cert_verifier is a function returning either True or False
based on whether the certificate was found to be OK,
keyobj and certobj represent internal PyOpenSSL structures holding
the key and certificate respectively.
"""
httplib.HTTPSConnection.__init__(self, host, **kw)
self.ca_certs = ca_certs
self.cert_verifier = cert_verifier
self.keyobj = keyobj
self.certobj = certobj
def connect(self):
sock = socket.create_connection((self.host, self.port), self.timeout)
if hasattr(self, '_tunnel_host') and self._tunnel_host:
self.sock = sock
self._tunnel()
if self.FORCE_SSL_VERSION:
add = {'ssl_version': self.FORCE_SSL_VERSION}
else:
add = {}
if self.SERVER_CERT_CHECK and self.ca_certs:
add['cert_reqs'] = ssl.CERT_REQUIRED
else:
add['cert_reqs'] = ssl.CERT_NONE
# try to use PyOpenSSL by default
if PYOPENSSL_AVAILABLE:
wrap_class = PyOpenSSLSocket
add['keyobj'] = self.keyobj
add['certobj'] = self.certobj
add['keyfile'] = self.key_file
add['certfile'] = self.cert_file
else:
wrap_class = ssl.SSLSocket
self.sock = wrap_class(sock, ca_certs=self.ca_certs, **add)
#if self.cert_verifier and self.SERVER_CERT_CHECK:
# if not self.cert_verifier(self.sock.getpeercert()):
# raise Exception("Server certificate did not pass security check.",
# self.sock.getpeercert())
class CheckingHTTPSHandler(u2.HTTPSHandler):
def __init__(self, ca_certs=None, cert_verifier=None,
client_certfile=None, client_keyfile=None,
client_keyobj=None, client_certobj=None,
*args, **kw):
"""cert_verifier is a function returning either True or False
based on whether the certificate was found to be OK"""
u2.HTTPSHandler.__init__(self, *args, **kw)
self.ca_certs = ca_certs
self.cert_verifier = cert_verifier
self.client_keyfile = client_keyfile # filename
self.client_certfile = client_certfile # filename
self.keyobj = client_keyobj
self.certobj = client_certobj
# FOR DEBUG
# self.set_http_debuglevel(100)
def https_open(self, req):
def open(*args, **kw):
new_kw = dict(ca_certs=self.ca_certs,
cert_verifier=self.cert_verifier,
cert_file=self.client_certfile,
key_file=self.client_keyfile,
keyobj=self.keyobj,
certobj=self.certobj)
new_kw.update(kw)
return CheckingHTTPSConnection(*args, **new_kw)
return self.do_open(open, req)
https_request = u2.AbstractHTTPHandler.do_request_
class Client_suds(SessionId, Client):
def set_parameters(self, path_to_cert, CERT_FILE, PKEY_FILE, HOST):
@ -505,11 +633,20 @@ class HTTPSClientCertTransport(HttpTransport):
self.cookie_callback = cookie_callback
self.user_agent_string = user_agent_string
log.debug("Proxy: %s", self.options.proxy)
from dslib.network import ProxyManager
proxy_handler = ProxyManager.HTTPS_PROXY.create_proxy_handler()
proxy_auth_handler = \
ProxyManager.HTTPS_PROXY.create_proxy_auth_handler()
#TODO to be removed:
# artifacts from old times:
# from dslib.network import ProxyManager
# proxy_handler = ProxyManager.HTTPS_PROXY.create_proxy_handler()
# proxy_auth_handler = ProxyManager.HTTPS_PROXY.create_proxy_auth_handler()
# apparently, dslib simply returned None on create_proxy_auth_handler
# if this is ever needed, probably use urllib2.ProxyBasicAuthHandler
proxy_auth_handler = None
# and create_proxy_handler SHOULD HAVE eval'd to this:
# proxy_handler = urllib2.ProxyHandler({"https" : "https://hostname"})
# but because no hostname was given, it also just returned None
proxy_handler = None
if (ca_certs or (client_keyfile and client_certfile)
or (client_keyobj and client_certobj)):
https_handler = CheckingClientHTTPSHandler(

@ -27,8 +27,8 @@ from calculate.core.server.cert_cmd import getHwAddr, getIpLocal
from calculate.core.server.local_call import print_brief_group
from calculate.lib.cl_lang import setLocalTranslate
from calculate.lib.utils.files import readFile
from sudsds import MethodNotFound
# from sudsds import MethodNotFound
from suds import MethodNotFound
_ = lambda x: x
setLocalTranslate('cl_console3', sys.modules[__name__])

@ -0,0 +1,352 @@
"""
This is just a simple copy of the ssl.py module contained in the Python
standard library. It was modified to work with PyOpenSSL and only to the
extent that it works with the DS server. It might not work for any other
purpose.
"""
import textwrap
import _ssl # if we can't import it, let the error propagate
from _ssl import SSLError
from _ssl import CERT_NONE, CERT_OPTIONAL, CERT_REQUIRED
from _ssl import PROTOCOL_SSLv23, PROTOCOL_TLSv1
from _ssl import RAND_status, RAND_add
from _ssl import \
SSL_ERROR_ZERO_RETURN, \
SSL_ERROR_WANT_READ, \
SSL_ERROR_WANT_WRITE, \
SSL_ERROR_WANT_X509_LOOKUP, \
SSL_ERROR_SYSCALL, \
SSL_ERROR_SSL, \
SSL_ERROR_WANT_CONNECT, \
SSL_ERROR_EOF, \
SSL_ERROR_INVALID_ERROR_CODE
from socket import socket, _fileobject
from socket import getnameinfo as _getnameinfo
import base64 # for DER-to-PEM translation
# the OpenSSL stuff
import OpenSSL
_ssl_to_openssl_cert_op_remap = {
CERT_NONE: OpenSSL.SSL.VERIFY_NONE,
CERT_OPTIONAL: OpenSSL.SSL.VERIFY_PEER,
CERT_REQUIRED: OpenSSL.SSL.VERIFY_PEER|OpenSSL.SSL.VERIFY_FAIL_IF_NO_PEER_CERT
}
_ssl_to_openssl_version_remap = {
PROTOCOL_SSLv23: OpenSSL.SSL.SSLv23_METHOD,
PROTOCOL_TLSv1: OpenSSL.SSL.TLSv1_METHOD,
}
class PyOpenSSLSocket (socket):
"""This class implements a subtype of socket.socket that wraps
the underlying OS socket in an SSL context when necessary, and
provides read and write methods over that channel."""
def __init__(self, sock, keyfile=None, certfile=None,
server_side=False, cert_reqs=CERT_NONE,
ssl_version=PROTOCOL_SSLv23, ca_certs=None,
do_handshake_on_connect=True,
suppress_ragged_eofs=True,
keyobj=None, certobj=None):
socket.__init__(self, _sock=sock._sock)
# the initializer for socket trashes the methods (tsk, tsk), so...
self.send = lambda data, flags=0: PyOpenSSLSocket.send(self, data, flags)
self.sendto = lambda data, addr, flags=0: PyOpenSSLSocket.sendto(self, data, addr, flags)
self.recv = lambda buflen=1024, flags=0: PyOpenSSLSocket.recv(self, buflen, flags)
self.recvfrom = lambda addr, buflen=1024, flags=0: PyOpenSSLSocket.recvfrom(self, addr, buflen, flags)
self.recv_into = lambda buffer, nbytes=None, flags=0: PyOpenSSLSocket.recv_into(self, buffer, nbytes, flags)
self.recvfrom_into = lambda buffer, nbytes=None, flags=0: PyOpenSSLSocket.recvfrom_into(self, buffer, nbytes, flags)
if certfile and not keyfile:
keyfile = certfile
# see if it's connected
try:
socket.getpeername(self)
except:
# no, no connection yet
self._sslobj = None
else:
# yes, create the SSL object
self._sslobj = sslwrap(self._sock, server_side,
keyfile, certfile,
cert_reqs, ssl_version, ca_certs,
keyobj=keyobj, certobj=certobj)
if do_handshake_on_connect:
timeout = self.gettimeout()
try:
self.settimeout(None)
self.do_handshake()
finally:
self.settimeout(timeout)
self.keyfile = keyfile
self.certfile = certfile
self.cert_reqs = cert_reqs
self.ssl_version = ssl_version
self.ca_certs = ca_certs
self.do_handshake_on_connect = do_handshake_on_connect
self.suppress_ragged_eofs = suppress_ragged_eofs
self._makefile_refs = 0
self.keyobj = keyobj
self.certobj = certobj
def read(self, len=1024):
"""Read up to LEN bytes and return them.
Return zero-length string on EOF."""
try:
return self._sslobj.read(len)
except SSLError, x:
if x.args[0] == SSL_ERROR_EOF and self.suppress_ragged_eofs:
return ''
else:
raise
def write(self, data):
"""Write DATA to the underlying SSL channel. Returns
number of bytes of DATA actually transmitted."""
return self._sslobj.write(data)
def getpeercert(self, binary_form=False):
"""Returns a formatted version of the data in the
certificate provided by the other end of the SSL channel.
Return None if no certificate was provided, {} if a
certificate was provided, but not validated."""
return self._sslobj.get_peer_certificate()
def cipher (self):
if not self._sslobj:
return None
else:
return self._sslobj.cipher()
def send (self, data, flags=0):
if self._sslobj:
if flags != 0:
raise ValueError(
"non-zero flags not allowed in calls to send() on %s" %
self.__class__)
while True:
try:
v = self._sslobj.write(data)
except SSLError, x:
if x.args[0] == SSL_ERROR_WANT_READ:
return 0
elif x.args[0] == SSL_ERROR_WANT_WRITE:
return 0
else:
raise
else:
return v
else:
return socket.send(self, data, flags)
def sendto (self, data, addr, flags=0):
if self._sslobj:
raise ValueError("sendto not allowed on instances of %s" %
self.__class__)
else:
return socket.sendto(self, data, addr, flags)
def sendall (self, data, flags=0):
if self._sslobj:
if flags != 0:
raise ValueError(
"non-zero flags not allowed in calls to sendall() on %s" %
self.__class__)
amount = len(data)
count = 0
while (count < amount):
v = self.send(data[count:])
count += v
return amount
else:
return socket.sendall(self, data, flags)
def recv (self, buflen=1024, flags=0):
if self._sslobj:
if flags != 0:
raise ValueError(
"non-zero flags not allowed in calls to sendall() on %s" %
self.__class__)
while True:
try:
return self.read(buflen)
except SSLError, x:
if x.args[0] == SSL_ERROR_WANT_READ:
continue
else:
raise x
else:
return socket.recv(self, buflen, flags)
def recv_into (self, buffer, nbytes=None, flags=0):
if buffer and (nbytes is None):
nbytes = len(buffer)
elif nbytes is None:
nbytes = 1024
if self._sslobj:
if flags != 0:
raise ValueError(
"non-zero flags not allowed in calls to recv_into() on %s" %
self.__class__)
while True:
try:
tmp_buffer = self.read(nbytes)
v = len(tmp_buffer)
buffer[:v] = tmp_buffer
return v
except SSLError, x:
if x.args[0] == SSL_ERROR_WANT_READ:
continue
else:
raise x
else:
return socket.recv_into(self, buffer, nbytes, flags)
def recvfrom (self, addr, buflen=1024, flags=0):
if self._sslobj:
raise ValueError("recvfrom not allowed on instances of %s" %
self.__class__)
else:
return socket.recvfrom(self, addr, buflen, flags)
def recvfrom_into (self, buffer, nbytes=None, flags=0):
if self._sslobj:
raise ValueError("recvfrom_into not allowed on instances of %s" %
self.__class__)
else:
return socket.recvfrom_into(self, buffer, nbytes, flags)
def pending (self):
if self._sslobj:
return self._sslobj.pending()
else:
return 0
def unwrap (self):
if self._sslobj:
s = self._sslobj.shutdown()
self._sslobj = None
return s
else:
raise ValueError("No SSL wrapper around " + str(self))
def shutdown (self, how):
self._sslobj = None
socket.shutdown(self, how)
def close (self):
if self._makefile_refs < 1:
self._sslobj = None
socket.close(self)
else:
self._makefile_refs -= 1
def do_handshake (self):
"""Perform a TLS/SSL handshake."""
self._sslobj.do_handshake()
def connect(self, addr):
"""Connects to remote ADDR, and then wraps the connection in
an SSL channel."""
# Here we assume that the socket is client-side, and not
# connected at the time of the call. We connect it, then wrap it.
if self._sslobj:
raise ValueError("attempt to connect already-connected PyOpenSSLSocket!")
socket.connect(self, addr)
self._sslobj = sslwrap(self._sock, False, self.keyfile, self.certfile,
self.cert_reqs, self.ssl_version,
self.ca_certs,
keyobj=self.keyobj, certobj=self.certobj)
if self.do_handshake_on_connect:
self.do_handshake()
def accept(self):
"""Accepts a new connection from a remote client, and returns
a tuple containing that new connection wrapped with a server-side
SSL channel, and the address of the remote client."""
newsock, addr = socket.accept(self)
return (PyOpenSSLSocket(newsock,
keyfile=self.keyfile,
certfile=self.certfile,
server_side=True,
cert_reqs=self.cert_reqs,
ssl_version=self.ssl_version,
ca_certs=self.ca_certs,
do_handshake_on_connect=self.do_handshake_on_connect,
suppress_ragged_eofs=self.suppress_ragged_eofs),
addr)
def makefile(self, mode='r', bufsize=-1):
"""Make and return a file-like object that
works with the SSL connection. Just use the code
from the socket module."""
self._makefile_refs += 1
return _fileobject(self, mode, bufsize)
def wrap_socket(sock, keyfile=None, certfile=None,
server_side=False, cert_reqs=CERT_NONE,
ssl_version=PROTOCOL_SSLv23, ca_certs=None,
do_handshake_on_connect=True,
suppress_ragged_eofs=True):
return PyOpenSSLSocket(sock, keyfile=keyfile, certfile=certfile,
server_side=server_side, cert_reqs=cert_reqs,
ssl_version=ssl_version, ca_certs=ca_certs,
do_handshake_on_connect=do_handshake_on_connect,
suppress_ragged_eofs=suppress_ragged_eofs)
def verify_connection(conn, x509, error_code, depth, ret_code):
# no extra validation - just return whatever OpenSSL already
# decided during its check
return bool(ret_code)
def sslwrap(sock, server_side=False, keyfile=None, certfile=None,
cert_reqs=CERT_NONE, ssl_version=PROTOCOL_SSLv23,
ca_certs=None, keyobj=None, certobj=None):
"""this is modification of _ssl.sslwrap that uses PyOpenSSL,
keyobj and certobj are new parameters allowing setting the
key and cert not by filename, but from internal PyOpenSSL
structures.
"""
ctx = OpenSSL.SSL.Context(_ssl_to_openssl_version_remap[ssl_version])
if ca_certs:
ctx.load_verify_locations(ca_certs)
ctx.set_verify(_ssl_to_openssl_cert_op_remap[cert_reqs], verify_connection)
if keyobj:
ctx.use_privatekey(keyobj)
elif keyfile:
ctx.use_privatekey_file(keyfile)
if certobj:
ctx.use_certificate(certobj)
elif certfile:
ctx.use_certificate_file(certfile)
ctx.set_options(0x4000) # THIS IS THE KEY TO SUCCESS OF DS
ssl_sock = OpenSSL.SSL.Connection(ctx, sock)
ssl_sock.setblocking(True)
ssl_sock.set_connect_state()
return ssl_sock
Loading…
Cancel
Save