gpt4 book ai didi

python - Python 3 中通过 HTTPS 的 XMLRPC 服务器

转载 作者:行者123 更新时间:2023-11-28 19:27:40 27 4
gpt4 key购买 nike

我正在尝试在 Python 3 上实现一个简单的 XML-RPC 服务器,我希望它使用标准 ssl 库(包含在 Python 2.6 和 Python 3.x 中)通过 HTTPS 运行。

我看过一些使用 OpenSSL 或 M2Crypto 模块的代码,但我想避免任何依赖。

我实现了下一个代码,它应该在套接字上包装 SSL 协议(protocol):

"""Monkey patching standard xmlrpc.server.SimpleXMLRPCServer
to run over TLS (SSL)

Changes inspired on http://www.cs.technion.ac.il/~danken/SecureXMLRPCServer.py
"""
import socket
import socketserver
import ssl
from xmlrpc.server import SimpleXMLRPCServer, SimpleXMLRPCDispatcher, SimpleXMLRPCRequestHandler
try:
import fcntl
except ImportError:
fcntl = None


class SimpleXMLRPCServerTLS(SimpleXMLRPCServer):
def __init__(self, addr, requestHandler=SimpleXMLRPCRequestHandler,
logRequests=True, allow_none=False, encoding=None, bind_and_activate=True):
"""Overriding __init__ method of the SimpleXMLRPCServer

The method is an exact copy, except the TCPServer __init__
call, which is rewritten using TLS
"""
self.logRequests = logRequests

SimpleXMLRPCDispatcher.__init__(self, allow_none, encoding)

"""This is the modified part. Original code was:

socketserver.TCPServer.__init__(self, addr, requestHandler, bind_and_activate)

which executed:

def __init__(self, server_address, RequestHandlerClass, bind_and_activate=True):
BaseServer.__init__(self, server_address, RequestHandlerClass)
self.socket = socket.socket(self.address_family,
self.socket_type)
if bind_and_activate:
self.server_bind()
self.server_activate()

"""
socketserver.BaseServer.__init__(self, addr, requestHandler)
self.socket = ssl.wrap_socket(
socket.socket(self.address_family, self.socket_type),
server_side=True,
cert_reqs=ssl.CERT_NONE,
ssl_version=ssl.PROTOCOL_TLSv1,
)
if bind_and_activate:
self.server_bind()
self.server_activate()

"""End of modified part"""

# [Bug #1222790] If possible, set close-on-exec flag; if a
# method spawns a subprocess, the subprocess shouldn't have
# the listening socket open.
if fcntl is not None and hasattr(fcntl, 'FD_CLOEXEC'):
flags = fcntl.fcntl(self.fileno(), fcntl.F_GETFD)
flags |= fcntl.FD_CLOEXEC
fcntl.fcntl(self.fileno(), fcntl.F_SETFD, flags)

但由于某种原因我无法确定,它引发了这个错误:

[Errno 8] _ssl.c:502: EOF occurred in violation of protocol

在调用远程方法之前。

有没有人知道可能会发生什么,或者知道如何收集更多信息以获取可能出现问题的线索?

提前致谢!

更新:

已修复。代码有两个错误。首先,需要指定证书文件(也可以包含 key )。

其次是 xmlrpc.client.ServerProxy(包含在 Python 中)正在使用 SSLv2,因此 TLSv1 不起作用。

工作代码是:

"""Monkey patching standard xmlrpc.server.SimpleXMLRPCServer
to run over TLS (SSL)

Changes inspired on http://www.cs.technion.ac.il/~danken/SecureXMLRPCServer.py
"""
import socket
import socketserver
import ssl
from xmlrpc.server import SimpleXMLRPCServer, SimpleXMLRPCDispatcher, SimpleXMLRPCRequestHandler
try:
import fcntl
except ImportError:
fcntl = None


class SimpleXMLRPCServerTLS(SimpleXMLRPCServer):
def __init__(self, addr, requestHandler=SimpleXMLRPCRequestHandler,
logRequests=True, allow_none=False, encoding=None, bind_and_activate=True):
"""Overriding __init__ method of the SimpleXMLRPCServer

The method is an exact copy, except the TCPServer __init__
call, which is rewritten using TLS
"""
self.logRequests = logRequests

SimpleXMLRPCDispatcher.__init__(self, allow_none, encoding)

"""This is the modified part. Original code was:

socketserver.TCPServer.__init__(self, addr, requestHandler, bind_and_activate)

which executed:

def __init__(self, server_address, RequestHandlerClass, bind_and_activate=True):
BaseServer.__init__(self, server_address, RequestHandlerClass)
self.socket = socket.socket(self.address_family,
self.socket_type)
if bind_and_activate:
self.server_bind()
self.server_activate()

"""
socketserver.BaseServer.__init__(self, addr, requestHandler)
self.socket = ssl.wrap_socket(
socket.socket(self.address_family, self.socket_type),
server_side=True,
certfile='cert.pem',
cert_reqs=ssl.CERT_NONE,
ssl_version=ssl.PROTOCOL_SSLv23,
)
if bind_and_activate:
self.server_bind()
self.server_activate()

"""End of modified part"""

# [Bug #1222790] If possible, set close-on-exec flag; if a
# method spawns a subprocess, the subprocess shouldn't have
# the listening socket open.
if fcntl is not None and hasattr(fcntl, 'FD_CLOEXEC'):
flags = fcntl.fcntl(self.fileno(), fcntl.F_GETFD)
flags |= fcntl.FD_CLOEXEC
fcntl.fcntl(self.fileno(), fcntl.F_SETFD, flags)

最佳答案

你为什么不这样写:

server = SimpleXMLRPCServer(...)
...
server.socket = ssl.wrap_socket(srv.socket, ...)
server.serve_forever()

关于python - Python 3 中通过 HTTPS 的 XMLRPC 服务器,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5690733/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com