#
##############################################################################
-import time
-import threading
-
import SimpleXMLRPCServer
-from ssl import SecureXMLRPCServer
-
-import signal
-import sys
-import xmlrpclib
import SocketServer
-import socket
import logging
import logging.handlers
import os
+import signal
+import socket
+import sys
+import threading
+import time
+import xmlrpclib
_service = {}
_group = {}
_res_id = 1
_res = {}
-
class ServiceEndPointCall(object):
def __init__(self, id, method):
self._id = id
pdb.post_mortem(tb)
raise xmlrpclib.Fault(s, tb_s)
+# refactoring from Tryton (B2CK, Cedric Krier, Bertrand Chenal)
+class SSLSocket(object):
+ def __init__(self, socket):
+ if not hasattr(socket, 'sock_shutdown'):
+ from OpenSSL import SSL
+ ctx = SSL.Context(SSL.SSLv23_METHOD)
+ ctx.use_privatekey_file('server.pkey')
+ ctx.use_certificate_file('server.cert')
+ self.socket = SSL.Connection(ctx, socket)
+ else:
+ self.socket = socket
+
+ def shutdown(self, how):
+ return self.socket.sock_shutdown(how)
+
+ def __getattr__(self, name):
+ return getattr(self.socket, name)
+
+class SimpleXMLRPCRequestHandler(GenericXMLRPCRequestHandler, SimpleXMLRPCServer.SimpleXMLRPCRequestHandler):
+ rpc_paths = map(lambda s: '/xmlrpc/%s' % s, _service)
+
+class SecureXMLRPCRequestHandler(SimpleXMLRPCRequestHandler):
+ def setup(self):
+ self.connection = SSLSocket(self.request)
+ self.rfile = socket._fileobject(self.request, "rb", self.rbufsize)
+ self.wfile = socket._fileobject(self.request, "wb", self.wbufsize)
+
+class SimpleThreadedXMLRPCServer(SocketServer.ThreadingMixIn, SimpleXMLRPCServer.SimpleXMLRPCServer):
+ def server_bind(self):
+ self.socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
+ SimpleXMLRPCServer.SimpleXMLRPCServer.server_bind(self)
+class SecureThreadedXMLRPCServer(SimpleThreadedXMLRPCServer):
+ def __init__(self, server_address, HandlerClass, logRequests=1):
+ SimpleThreadedXMLRPCServer.__init__(self, server_address, HandlerClass, logRequests)
+ self.socket = SSLSocket(socket.socket(self.address_family, self.socket_type))
+ self.server_bind()
+ self.server_activate()
+# end of refactoring from Tryton
class HttpDaemon(threading.Thread):
def __init__(self, interface, port, secure=False):
self.__port = port
self.__interface = interface
self.secure = bool(secure)
-
- base_handler_class = [SimpleXMLRPCServer.SimpleXMLRPCRequestHandler, SecureXMLRPCServer.SecureXMLRPCRequestHandler][self.secure]
- class OpenERPXMLRPCRequestHandler(GenericXMLRPCRequestHandler, base_handler_class):
- base_handler_class.rpc_paths = map(lambda s: '/xmlrpc/%s' % s, _service)
-
- base_server_class = [SimpleXMLRPCServer.SimpleXMLRPCServer, SecureXMLRPCServer.SecureXMLRPCServer][self.secure]
- class OpenERPThreadedXMLRPCServer(SocketServer.ThreadingMixIn, base_server_class):
- def server_bind(self):
- try:
- self.socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
- base_server_class.server_bind(self)
- except:
- Logger().notifyChannel('init', LOG_CRITICAL, 'Address already in use')
- sys.exit(1)
-
- self.server = OpenERPThreadedXMLRPCServer((interface, port), OpenERPXMLRPCRequestHandler, 0)
+ handler_class = (SimpleXMLRPCRequestHandler, SecureXMLRPCRequestHandler)[self.secure]
+ server_class = (SimpleThreadedXMLRPCServer, SecureThreadedXMLRPCServer)[self.secure]
+ self.server = server_class((interface, port), handler_class, 0)
def attach(self, path, gw):
pass
def stop(self):
self.running = False
if os.name != 'nt':
- value = hasattr(socket, 'SHUT_RDWR') and socket.SHUT_RDWR or 2
- if self.secure:
- self.server.socket.sock_shutdown(value)
- else:
- self.server.socket.shutdown(value)
+ self.server.socket.shutdown( hasattr(socket, 'SHUT_RDWR') and socket.SHUT_RDWR or 2 )
self.server.socket.close()
def run(self):
+++ /dev/null
-# -*- encoding: utf-8 -*-
-##############################################################################
-#
-# OpenERP, Open Source Management Solution
-# Copyright (C) 2004-2008 Tiny SPRL (<http://tiny.be>). All Rights Reserved
-# $Id$
-#
-# This program is free software: you can redistribute it and/or modify
-# it under the terms of the GNU General Public License as published by
-# the Free Software Foundation, either version 3 of the License, or
-# (at your option) any later version.
-#
-# 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 General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program. If not, see <http://www.gnu.org/licenses/>.
-#
-##############################################################################
-"""
-SecureXMLRPCServer module using pyOpenSSL 0.5
-Extremely kludgey code written 0907.2002
-by Michal Wallace ( http://www.sabren.net/ )
-
-This acts as a drop-in replacement for
-SimpleXMLRPCServer from the standard python
-library.
-
-This code is in the public domain and is
-provided AS-IS WITH NO WARRANTY WHATSOEVER.
-"""
-import SocketServer
-import os
-import socket
-import sys
-import SimpleXMLRPCServer
-from OpenSSL import SSL
-
-
-class SSLBugFix:
- """
- SSL Connection tends to die on sendall,
- so I use send() as a workaround. This is
- called by socket._fileobject, which is needed
- so SocketServer (and kids) can treat the connection
- as a regular file.
- """
- def __init__(self, conn):
- """
- For some reason, I can't subclass Connection,
- so I'm making a proxy, instead.
- """
- self.__dict__["conn"] = conn
- def __getattr__(self,name):
- return getattr(self.__dict__["conn"], name)
- def __setattr__(self,name, value):
- setattr(self.__dict__["conn"], name, value)
-
-
-# def sendall(self, data):
-# """
-# This is the bugfix. Connection.sendall() segfaults
-# on socket._fileobject.flush(), so just rewire it
-# to use send() instead.
-# """
-# self.__dict__["conn"].send(data)
-
- def shutdown(self, how=1):
- """
- This isn't part of the bugfix. SimpleXMLRpcServer.doPOST
- calls shutdown(1), and Connection.shutdown() doesn't take
- an argument. So we just discard it:
- """
- self.__dict__["conn"].shutdown()
-
- def accept(self):
- """
- This is the other part of the shutdown() workaround.
- Since servers create new sockets, we have to infect
- them with our magic. :)
- """
- c, a = self.__dict__["conn"].accept()
- return (SSLBugFix(c), a)
-
-
-
-class SecureTCPServer(SocketServer.TCPServer):
- """
- Just like TCPServer, but use a socket.
- This really ought to let you specify the key and certificate files.
- """
- def __init__(self, server_address, RequestHandlerClass):
- SocketServer.BaseServer.__init__(self, server_address, RequestHandlerClass)
-
- ## Same as normal, but make it secure:
- ctx = SSL.Context(SSL.SSLv23_METHOD)
- ctx.set_options(SSL.OP_NO_SSLv2)
-
- dir = os.path.join(os.getcwd(), os.path.dirname(sys.argv[0]))
- ctx.use_privatekey_file (os.path.join(dir, 'server.pkey'))
- ctx.use_certificate_file(os.path.join(dir, 'server.cert'))
-
- self.socket = SSLBugFix(SSL.Connection(ctx, socket.socket(self.address_family,
- self.socket_type)))
- self.server_bind()
- self.server_activate()
-
-
-class SecureXMLRPCRequestHandler(SimpleXMLRPCServer.SimpleXMLRPCRequestHandler):
- def setup(self):
- """
- We need to use socket._fileobject Because SSL.Connection
- doesn't have a 'dup'. Not exactly sure WHY this is, but
- this is backed up by comments in socket.py and SSL/connection.c
- """
- self.connection = self.request # for doPOST
- self.rfile = socket._fileobject(self.request, "rb", self.rbufsize)
- self.wfile = socket._fileobject(self.request, "wb", self.wbufsize)
-
-
-class SecureXMLRPCServer(SimpleXMLRPCServer.SimpleXMLRPCServer, SecureTCPServer):
- def __init__(self, addr,
- requestHandler=SecureXMLRPCRequestHandler,
- logRequests=1):
- """
- This is the exact same code as SimpleXMLRPCServer.__init__
- except it calls SecureTCPServer.__init__ instead of plain
- old TCPServer.__init__
- """
- self.funcs = {}
- self.logRequests = logRequests
- self.instance = None
- SecureTCPServer.__init__(self, addr, requestHandler)
-
-
-# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
-
+++ /dev/null
-# -*- encoding: utf-8 -*-
-##############################################################################
-#
-# OpenERP, Open Source Management Solution
-# Copyright (C) 2004-2008 Tiny SPRL (<http://tiny.be>). All Rights Reserved
-# $Id$
-#
-# This program is free software: you can redistribute it and/or modify
-# it under the terms of the GNU General Public License as published by
-# the Free Software Foundation, either version 3 of the License, or
-# (at your option) any later version.
-#
-# 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 General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program. If not, see <http://www.gnu.org/licenses/>.
-#
-##############################################################################
-
-
-import SecureXMLRPCServer
-
-# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
-
+++ /dev/null
------BEGIN CERTIFICATE-----
-MIICNDCCAZ0CAQEwDQYJKoZIhvcNAQEEBQAweTEQMA4GA1UEChMHVGlueUVSUDEM
-MAoGA1UECxMDRVJQMRkwFwYJKoZIhvcNAQkBFgpmcEB0aW55LmJlMRAwDgYDVQQH
-EwdXYWxoYWluMQswCQYDVQQIEwJCVzELMAkGA1UEBhMCQkUxEDAOBgNVBAMTB1Rp
-bnlFUlAwHhcNMDYwNTI0MDgzODUxWhcNMDcwNTI0MDgzODUxWjBMMQswCQYDVQQG
-EwJCRTELMAkGA1UECBMCQlcxEDAOBgNVBAoTB1RpbnlFUlAxDDAKBgNVBAsTA0VS
-UDEQMA4GA1UEAxMHVGlueUVSUDCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEA
-xzIDlU2PrczPsgXtxCskYxuwMPgNCNSCBfWsUZ9nJzlZfRAEXEq4LxaTPIgkzkIF
-82bmJLgFz6/CyCFid4mkBLQBj30Opp2Vco39WRncNKHKxbk+/wZpZtQ0bSpvf+F4
-MBqCLldYIqsoyenombVCb8X62IUu0ENF1wR22owvyKcCAwEAATANBgkqhkiG9w0B
-AQQFAAOBgQB2yUqJ3gbQ8I6rcmaVJlcLDHfC5w1Jr1cUzcJevOPh3wygSZYYoUoe
-yeYlzEag/DpPSHyRiJJVOKdiwU0yfmZPhfDNtDiBr47bz8qzIsYq5VeMmSeXrq/f
-AA3iI4xE8YFzJHWtiBCqqyUok+j9pVad7iV7+UVIePHZLEkGGWIjDA==
------END CERTIFICATE-----
+++ /dev/null
------BEGIN RSA PRIVATE KEY-----
-MIICXAIBAAKBgQDHMgOVTY+tzM+yBe3EKyRjG7Aw+A0I1IIF9axRn2cnOVl9EARc
-SrgvFpM8iCTOQgXzZuYkuAXPr8LIIWJ3iaQEtAGPfQ6mnZVyjf1ZGdw0ocrFuT7/
-Bmlm1DRtKm9/4XgwGoIuV1giqyjJ6eiZtUJvxfrYhS7QQ0XXBHbajC/IpwIDAQAB
-AoGAVwAxMHS/3FkoHckZICT3r5HYUosEpmaqo4+5w6yrkSYrP8RPI0A/UdG6XSXZ
-bXzIvJakzkTRxPQvTtnF+A/V4rF9hxwB8cGXSywv5eDGmZ91qIsxY7Sv99VqSKNH
-dNr9aZHloTvI51e/oramIJ/O3A+TbAS5i+u1DJC2IIFJcAECQQD8iRPTlPIqzjYD
-Lg7KYGvwW9TE4ONAhC86kJbzV5o3amlV5duJgnkl/mNlfN1ihA7f3Gx9dfCjfRKp
-V1rcjtCBAkEAye2aMw2v1m+MEqcPxyTUzVf5Y8BIXWbk15T43czXec9YclZSOBCX
-Dgv4a3Fk+yxQUE0cZUH0U4FJq6mTgpuFJwJASFqZ9KATNlJ4xTZ4BGHV6zrUXkg0
-tDJrObNdnID37XKulW7TFLXuMgWNwvEgmO5POLJ13whglubp5tzhapn8gQJAJz9Z
-U0b7wFAaB54VAP31ppvMy0iaSB0xqX05CdNAplpYtJB2lpMS6RYGiMuXdwJb8d+q
-/ztcg8aDTSw+kYoszQJBAPBrt694VkGT1k9Be6e5wyVDrE05bkHhFxPk/HMeWMDX
-sZqHPs9vVaLBqu/uU84FdwRMOV71RG90g6eUEl7HWsg=
------END RSA PRIVATE KEY-----