gpt4 book ai didi

python - wrap_socket() 得到了一个意外的关键字参数 'server_hostname' ?

转载 作者:太空宇宙 更新时间:2023-11-04 01:19:09 26 4
gpt4 key购买 nike

我正在尝试使用 Python 来测试网络服务器。我几乎没有使用 Python 的经验,但我鼓励使用它,因为它易于学习且易于使用(其他人的意见,目前不是我的意见)。我使用的脚本是:

s1 = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s2 = ssl.wrap_socket(s1,
ca_certs="./pki/signing-dss-cert.pem",
cert_reqs=ssl.CERT_REQUIRED,
ssl_version=ssl.PROTOCOL_TLSv1,
server_hostname="localhost")

s2.connect( ("localhost", 8443) )

s2.send("GET / ")
time.sleep(1)
s2.send("HTTP/1.1")

错误是:

Traceback (most recent call last):
File "./fetch.sh", line 10, in <module>
server_hostname="localhost")
TypeError: wrap_socket() got an unexpected keyword argument 'server_hostname'

我也尝试过使用 servernamenamehostnamesni,但并不愉快。

Python 文档没有提到 SNI(TLS/SSL wrapper for socket objectsSSL wiki page)。但我知道 SNI 和 server_hostname 的补丁已于 4 年前的 2010 年合并( Add a *server_hostname* argument to SSLContext.wrap_socketchangeset 65593:846c0e1342d0 )。

我需要访问的等效 OpenSSL 调用是 SSL_set_tlsext_host_name

如何指定 SNI 主机名? (最终,我需要将其设置为任意名称,因为我正在测试代理)。

最佳答案

patch you're mentioning适用于 Python 3.2,而您使用的是 Python 2.7。 Issue 5639似乎也表明没有计划向后移植 SNI 对 Python 2.7 的支持。

你可以用 pyOpenSSL 代替套接字(它的 Connection 类有一个 set_tlsext_host_name 从版本 0.13 开始。(我不确定 Debian 7.3 附带哪个版本,你可能想要设置一个 virtualenv 并在需要时在本地升级到更新的版本。)

有一个SNI example是 pyOpenSSL 存储库。

如果你希望你的 wrap_socket 的用法与技巧更兼容,你可以在 httplib 连接中替换 sock 的值,你可以看看如何urllib3 does this with pyOpenSSL .本质上,它从现有套接字创建一个 OpenSSL.SSL.Connection,但由于该连接与套接字不兼容,因此它将它包装到一个实现所需方法的类中。

(顺便说一句,在 Python 2.7 中,urlliburllib2httpconnection 根本不做任何证书验证,除非你通过包装他们的套接字自己实现它。)

编辑:

这是您的代码版本,应该适用于 Python 3.2。不幸的是,server_name 参数不在普通的 ssl.wrap_socket 中,仅在 SSLContext.wrap_socket 中,但您可以使用 SSLSocket 直接。

import socket
import ssl

CA_BUNDLE_FILE="/etc/ssl/certs/ca-certificates.crt"


HOST = "sni.velox.ch"
s1 = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s2 = ssl.SSLSocket(sock=s1, ca_certs=CA_BUNDLE_FILE,
cert_reqs=ssl.CERT_REQUIRED,
ssl_version=ssl.PROTOCOL_TLSv1,
server_hostname=HOST)

s2.connect((HOST, 443))

s2.send(bytes("GET / HTTP/1.1\n", "UTF-8"))
# This might need to be modified when using another port
s2.send(bytes("Host: %s\n" % (HOST,), "UTF-8"))
s2.send(bytes("\n", "UTF-8"))

# Certainly not the best way to read the response, but it works.
while True:
x = s2.read()
if not x:
break
print(x)

关于python - wrap_socket() 得到了一个意外的关键字参数 'server_hostname' ?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22387651/

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