Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
镜像
Eclipse Foundation
paho.mqtt.python
提交
0a8cccc2
P
paho.mqtt.python
项目概览
镜像
/
Eclipse Foundation
/
paho.mqtt.python
11 个月 前同步成功
通知
2
Star
0
Fork
0
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
DevOps
流水线
流水线任务
计划
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
P
paho.mqtt.python
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
DevOps
DevOps
流水线
流水线任务
计划
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
流水线任务
提交
Issue看板
体验新版 GitCode,发现更多精彩内容 >>
提交
0a8cccc2
编写于
9月 29, 2016
作者:
J
James Myatt
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
Remove support for SSL without SSLContext (Fixes #115)
Signed-off-by:
N
James Myatt
<
james@jamesmyatt.co.uk
>
上级
37cf9537
变更
6
显示空白变更内容
内联
并排
Showing
6 changed file
with
105 addition
and
167 deletion
+105
-167
src/paho/mqtt/client.py
src/paho/mqtt/client.py
+99
-161
test/lib/context.py
test/lib/context.py
+2
-2
test/lib/python/08-ssl-bad-cacert.test
test/lib/python/08-ssl-bad-cacert.test
+1
-1
test/lib/python/08-ssl-connect-cert-auth.test
test/lib/python/08-ssl-connect-cert-auth.test
+1
-1
test/lib/python/08-ssl-connect-no-auth.test
test/lib/python/08-ssl-connect-no-auth.test
+1
-1
test/lib/python/08-ssl-fake-cacert.test
test/lib/python/08-ssl-fake-cacert.test
+1
-1
未找到文件。
src/paho/mqtt/client.py
浏览文件 @
0a8cccc2
...
@@ -24,10 +24,7 @@ import socket
...
@@ -24,10 +24,7 @@ import socket
try
:
try
:
import
ssl
import
ssl
except
ImportError
:
except
ImportError
:
HAVE_SSL
=
False
ssl
=
None
ssl
=
None
else
:
HAVE_SSL
=
True
import
struct
import
struct
import
sys
import
sys
...
@@ -258,16 +255,6 @@ def _socketpair_compat():
...
@@ -258,16 +255,6 @@ def _socketpair_compat():
return
(
sock1
,
sock2
)
return
(
sock1
,
sock2
)
def
_check_can_read_file
(
filename
):
if
filename
:
try
:
f
=
open
(
filename
,
"r"
)
except
IOError
as
err
:
raise
IOError
(
filename
+
": "
+
err
.
strerror
)
else
:
f
.
close
()
class
MQTTMessageInfo
:
class
MQTTMessageInfo
:
"""This is a class returned from Client.publish() and can be used to find
"""This is a class returned from Client.publish() and can be used to find
out the mid of the message that was published, and to determine whether the
out the mid of the message that was published, and to determine whether the
...
@@ -446,6 +433,7 @@ class Client(object):
...
@@ -446,6 +433,7 @@ class Client(object):
MQTT_LOG_ERR, and MQTT_LOG_DEBUG. The message itself is in buf.
MQTT_LOG_ERR, and MQTT_LOG_DEBUG. The message itself is in buf.
"""
"""
def
__init__
(
self
,
client_id
=
""
,
clean_session
=
True
,
userdata
=
None
,
protocol
=
MQTTv311
,
transport
=
"tcp"
):
def
__init__
(
self
,
client_id
=
""
,
clean_session
=
True
,
userdata
=
None
,
protocol
=
MQTTv311
,
transport
=
"tcp"
):
"""client_id is the unique client id string used when connecting to the
"""client_id is the unique client id string used when connecting to the
broker. If client_id is zero length or None, then the behaviour is
broker. If client_id is zero length or None, then the behaviour is
...
@@ -546,7 +534,7 @@ class Client(object):
...
@@ -546,7 +534,7 @@ class Client(object):
self
.
_thread_terminate
=
False
self
.
_thread_terminate
=
False
self
.
_ssl
=
False
self
.
_ssl
=
False
self
.
_ssl_context
=
None
self
.
_ssl_context
=
None
self
.
_tls_insecure
=
False
self
.
_tls_insecure
=
False
# Only used when SSL context does not have check_hostname attribute
self
.
_logger
=
None
self
.
_logger
=
None
# No default callbacks
# No default callbacks
self
.
_on_log
=
None
self
.
_on_log
=
None
...
@@ -576,19 +564,15 @@ class Client(object):
...
@@ -576,19 +564,15 @@ class Client(object):
def
tls_set_context
(
self
,
context
=
None
):
def
tls_set_context
(
self
,
context
=
None
):
"""Configure network encryption and authentication context. Enables SSL/TLS support.
"""Configure network encryption and authentication context. Enables SSL/TLS support.
context : an ssl.SSLContext object, or a dictionary containing
context : an ssl.SSLContext object. By default this is given by
arguments for ssl.wrap_socket. By default this is given by
`ssl.create_default_context()`, if available.
`ssl.create_default_context()`, if available.
Must be called before connect() or connect_async()."""
Must be called before connect() or connect_async()."""
if
self
.
_ssl_context
is
not
None
:
if
self
.
_ssl_context
is
not
None
:
raise
ValueError
(
'SSL/TLS has already been configured.'
)
raise
ValueError
(
'SSL/TLS has already been configured.'
)
if
HAVE_SSL
is
False
:
# Assume that have SSL support, or at least that context input behaves like ssl.SSLContext
raise
ValueError
(
'This platform has no SSL/TLS.'
)
# in current versions of Python
if
sys
.
version_info
<
(
2
,
7
):
raise
ValueError
(
'Python 2.7 is the minimum supported version for TLS.'
)
if
context
is
None
:
if
context
is
None
:
if
hasattr
(
ssl
,
'create_default_context'
):
if
hasattr
(
ssl
,
'create_default_context'
):
...
@@ -599,6 +583,10 @@ class Client(object):
...
@@ -599,6 +583,10 @@ class Client(object):
self
.
_ssl
=
True
self
.
_ssl
=
True
self
.
_ssl_context
=
context
self
.
_ssl_context
=
context
# Ensure _tls_insecure is consistent with check_hostname attribute
if
hasattr
(
context
,
'check_hostname'
):
self
.
_tls_insecure
=
not
context
.
check_hostname
def
tls_set
(
self
,
ca_certs
,
certfile
=
None
,
keyfile
=
None
,
cert_reqs
=
None
,
tls_version
=
None
,
ciphers
=
None
):
def
tls_set
(
self
,
ca_certs
,
certfile
=
None
,
keyfile
=
None
,
cert_reqs
=
None
,
tls_version
=
None
,
ciphers
=
None
):
"""Configure network encryption and authentication options. Enables SSL/TLS support.
"""Configure network encryption and authentication options. Enables SSL/TLS support.
...
@@ -634,53 +622,37 @@ class Client(object):
...
@@ -634,53 +622,37 @@ class Client(object):
more information.
more information.
Must be called before connect() or connect_async()."""
Must be called before connect() or connect_async()."""
if
HAVE_SSL
is
Fals
e
:
if
ssl
is
Non
e
:
raise
ValueError
(
'This platform has no SSL/TLS.'
)
raise
ValueError
(
'This platform has no SSL/TLS.'
)
if
sys
.
version_info
<
(
2
,
7
):
if
not
hasattr
(
ssl
,
'SSLContext'
):
raise
ValueError
(
'Python 2.7 is the minimum supported version for TLS.'
)
# Require Python version that has SSL context support in standard library
raise
ValueError
(
'Python 2.7.9 and 3.2 are the minimum supported versions for TLS.'
)
if
ca_certs
is
None
:
if
ca_certs
is
None
:
raise
ValueError
(
'ca_certs must not be None.'
)
raise
ValueError
(
'ca_certs must not be None.'
)
# Load defaults
# Create SSLContext object
if
cert_reqs
is
None
:
cert_reqs
=
ssl
.
CERT_REQUIRED
if
tls_version
is
None
:
if
tls_version
is
None
:
tls_version
=
ssl
.
PROTOCOL_TLSv1
tls_version
=
ssl
.
PROTOCOL_TLSv1
if
hasattr
(
ssl
,
'SSLContext'
):
# Create SSLContext object
context
=
ssl
.
SSLContext
(
tls_version
)
context
=
ssl
.
SSLContext
(
tls_version
)
# Configure context
# Configure context
if
certfile
is
not
None
:
if
certfile
is
not
None
:
context
.
load_cert_chain
(
certfile
,
keyfile
)
context
.
load_cert_chain
(
certfile
,
keyfile
)
if
cert_reqs
is
not
None
:
context
.
verify_mode
=
cert_reqs
context
.
verify_mode
=
ssl
.
CERT_REQUIRED
if
cert_reqs
is
None
else
cert_reqs
if
ca_certs
is
not
None
:
context
.
load_verify_locations
(
ca_certs
)
context
.
load_verify_locations
(
ca_certs
)
if
ciphers
is
not
None
:
if
ciphers
is
not
None
:
context
.
set_ciphers
(
ciphers
)
context
.
set_ciphers
(
ciphers
)
else
:
# Revert to version without SSLContext, since not available
_check_can_read_file
(
ca_certs
)
_check_can_read_file
(
certfile
)
_check_can_read_file
(
keyfile
)
# Dictionary of arguments for ssl.wrap_socket
context
=
{
'certfile'
:
certfile
,
'keyfile'
:
keyfile
,
'ca_certs'
:
ca_certs
,
'cert_reqs'
:
cert_reqs
,
'ciphers'
:
ciphers
,
'ssl_version'
:
tls_version
}
self
.
tls_set_context
(
context
)
self
.
tls_set_context
(
context
)
# Default to secure, sets context.check_hostname attribute if available
self
.
tls_insecure_set
(
False
)
def
tls_insecure_set
(
self
,
value
):
def
tls_insecure_set
(
self
,
value
):
"""Configure verification of the server hostname in the server certificate.
"""Configure verification of the server hostname in the server certificate.
...
@@ -693,12 +665,20 @@ class Client(object):
...
@@ -693,12 +665,20 @@ class Client(object):
Do not use this function in a real system. Setting value to true means
Do not use this function in a real system. Setting value to true means
there is no point using encryption.
there is no point using encryption.
Must be called before connect()."""
Must be called before connect() and after either tls_set() or
if
HAVE_SSL
is
False
:
tls_set_context()."""
raise
ValueError
(
'This platform has no SSL/TLS.'
)
if
self
.
_ssl_context
is
None
:
raise
ValueError
(
'Must configure SSL context before using tls_insecure_set.'
)
self
.
_tls_insecure
=
value
self
.
_tls_insecure
=
value
# Ensure check_hostname is consistent with _tls_insecure attribute
if
hasattr
(
self
.
_ssl_context
,
'check_hostname'
):
# Rely on SSLContext to check host name
# If verify_mode is CERT_NONE then the host name will never be checked
self
.
_ssl_context
.
check_hostname
=
not
value
def
enable_logger
(
self
,
logger
=
None
):
def
enable_logger
(
self
,
logger
=
None
):
if
not
logger
:
if
not
logger
:
if
self
.
_logger
:
if
self
.
_logger
:
...
@@ -847,20 +827,22 @@ class Client(object):
...
@@ -847,20 +827,22 @@ class Client(object):
raise
raise
if
self
.
_ssl
:
if
self
.
_ssl
:
if
isinstance
(
self
.
_ssl_context
,
dict
):
# SSL is only supported when SSLContext is available (implies Python >= 2.7.9 or >= 3.2)
# Version without SSL Context
sock
=
ssl
.
wrap_socket
(
verify_host
=
not
self
.
_tls_insecure
sock
,
**
self
.
_ssl_context
)
try
:
else
:
# Try with server_hostname, even it's not supported in certain scenarios
# Use SSLContext (implies Python >= 3.2)
sock
=
self
.
_ssl_context
.
wrap_socket
(
sock
,
server_hostname
=
self
.
_host
)
server_hostname
=
self
.
_host
if
ssl
.
HAS_SNI
else
None
except
ValueError
:
sock
=
self
.
_ssl_context
.
wrap_socket
(
# Python version requires SNI in order to handle server_hostname, but SNI is not available
sock
,
server_hostname
=
server_hostname
)
sock
=
self
.
_ssl_context
.
wrap_socket
(
sock
)
if
not
self
.
_tls_insecure
:
if
sys
.
version_info
<
(
2
,
7
,
9
)
or
(
sys
.
version_info
[
0
]
==
3
and
sys
.
version_info
[
1
]
<
2
):
self
.
_tls_match_hostname
(
sock
)
else
:
else
:
# If SSL context has already checked hostname, then don't need to do it again
if
(
hasattr
(
self
.
_ssl_context
,
'check_hostname'
)
and
self
.
_ssl_context
.
check_hostname
):
verify_host
=
False
if
verify_host
:
ssl
.
match_hostname
(
sock
.
getpeercert
(),
self
.
_host
)
ssl
.
match_hostname
(
sock
.
getpeercert
(),
self
.
_host
)
if
self
.
_transport
==
"websockets"
:
if
self
.
_transport
==
"websockets"
:
...
@@ -1256,7 +1238,7 @@ class Client(object):
...
@@ -1256,7 +1238,7 @@ class Client(object):
now
=
time_func
()
now
=
time_func
()
self
.
_check_keepalive
()
self
.
_check_keepalive
()
if
self
.
_last_retry_check
+
1
<
now
:
if
self
.
_last_retry_check
+
1
<
now
:
# Only check once a second at most
# Only check once a second at most
self
.
_message_retry_check
()
self
.
_message_retry_check
()
self
.
_last_retry_check
=
now
self
.
_last_retry_check
=
now
...
@@ -1970,12 +1952,12 @@ class Client(object):
...
@@ -1970,12 +1952,12 @@ class Client(object):
if
self
.
_sock
is
None
:
if
self
.
_sock
is
None
:
return
MQTT_ERR_NO_CONN
return
MQTT_ERR_NO_CONN
command
=
PUBLISH
|
((
dup
&
0x1
)
<<
3
)
|
(
qos
<<
1
)
|
retain
command
=
PUBLISH
|
((
dup
&
0x1
)
<<
3
)
|
(
qos
<<
1
)
|
retain
packet
=
bytearray
()
packet
=
bytearray
()
packet
.
append
(
command
)
packet
.
append
(
command
)
payloadlen
=
len
(
payload
)
payloadlen
=
len
(
payload
)
remaining_length
=
2
+
len
(
topic
)
+
payloadlen
remaining_length
=
2
+
len
(
topic
)
+
payloadlen
if
payloadlen
==
0
:
if
payloadlen
==
0
:
self
.
_easy_log
(
self
.
_easy_log
(
...
@@ -2011,7 +1993,7 @@ class Client(object):
...
@@ -2011,7 +1993,7 @@ class Client(object):
def
_send_pubrel
(
self
,
mid
,
dup
=
False
):
def
_send_pubrel
(
self
,
mid
,
dup
=
False
):
self
.
_easy_log
(
MQTT_LOG_DEBUG
,
"Sending PUBREL (Mid: %d)"
,
mid
)
self
.
_easy_log
(
MQTT_LOG_DEBUG
,
"Sending PUBREL (Mid: %d)"
,
mid
)
return
self
.
_send_command_with_mid
(
PUBREL
|
2
,
mid
,
dup
)
return
self
.
_send_command_with_mid
(
PUBREL
|
2
,
mid
,
dup
)
def
_send_command_with_mid
(
self
,
command
,
mid
,
dup
):
def
_send_command_with_mid
(
self
,
command
,
mid
,
dup
):
# For PUBACK, PUBCOMP, PUBREC, and PUBREL
# For PUBACK, PUBCOMP, PUBREC, and PUBREL
...
@@ -2037,21 +2019,21 @@ class Client(object):
...
@@ -2037,21 +2019,21 @@ class Client(object):
proto_ver
=
4
proto_ver
=
4
protocol
=
protocol
.
encode
(
'utf-8'
)
protocol
=
protocol
.
encode
(
'utf-8'
)
remaining_length
=
2
+
len
(
protocol
)
+
1
+
1
+
2
+
2
+
len
(
self
.
_client_id
)
remaining_length
=
2
+
len
(
protocol
)
+
1
+
1
+
2
+
2
+
len
(
self
.
_client_id
)
connect_flags
=
0
connect_flags
=
0
if
clean_session
:
if
clean_session
:
connect_flags
|=
0x02
connect_flags
|=
0x02
if
self
.
_will
:
if
self
.
_will
:
remaining_length
+=
2
+
len
(
self
.
_will_topic
)
+
2
+
len
(
self
.
_will_payload
)
remaining_length
+=
2
+
len
(
self
.
_will_topic
)
+
2
+
len
(
self
.
_will_payload
)
connect_flags
|=
0x04
|
((
self
.
_will_qos
&
0x03
)
<<
3
)
|
((
self
.
_will_retain
&
0x01
)
<<
5
)
connect_flags
|=
0x04
|
((
self
.
_will_qos
&
0x03
)
<<
3
)
|
((
self
.
_will_retain
&
0x01
)
<<
5
)
if
self
.
_username
is
not
None
:
if
self
.
_username
is
not
None
:
remaining_length
+=
2
+
len
(
self
.
_username
)
remaining_length
+=
2
+
len
(
self
.
_username
)
connect_flags
|=
0x80
connect_flags
|=
0x80
if
self
.
_password
is
not
None
:
if
self
.
_password
is
not
None
:
connect_flags
|=
0x40
connect_flags
|=
0x40
remaining_length
+=
2
+
len
(
self
.
_password
)
remaining_length
+=
2
+
len
(
self
.
_password
)
command
=
CONNECT
command
=
CONNECT
packet
=
bytearray
()
packet
=
bytearray
()
...
@@ -2094,9 +2076,9 @@ class Client(object):
...
@@ -2094,9 +2076,9 @@ class Client(object):
def
_send_subscribe
(
self
,
dup
,
topics
):
def
_send_subscribe
(
self
,
dup
,
topics
):
remaining_length
=
2
remaining_length
=
2
for
t
,
_
in
topics
:
for
t
,
_
in
topics
:
remaining_length
+=
2
+
len
(
t
)
+
1
remaining_length
+=
2
+
len
(
t
)
+
1
command
=
SUBSCRIBE
|
(
dup
<<
3
)
|
0x2
command
=
SUBSCRIBE
|
(
dup
<<
3
)
|
0x2
packet
=
bytearray
()
packet
=
bytearray
()
packet
.
append
(
command
)
packet
.
append
(
command
)
self
.
_pack_remaining_length
(
packet
,
remaining_length
)
self
.
_pack_remaining_length
(
packet
,
remaining_length
)
...
@@ -2110,9 +2092,9 @@ class Client(object):
...
@@ -2110,9 +2092,9 @@ class Client(object):
def
_send_unsubscribe
(
self
,
dup
,
topics
):
def
_send_unsubscribe
(
self
,
dup
,
topics
):
remaining_length
=
2
remaining_length
=
2
for
t
in
topics
:
for
t
in
topics
:
remaining_length
+=
2
+
len
(
t
)
remaining_length
+=
2
+
len
(
t
)
command
=
UNSUBSCRIBE
|
(
dup
<<
3
)
|
0x2
command
=
UNSUBSCRIBE
|
(
dup
<<
3
)
|
0x2
packet
=
bytearray
()
packet
=
bytearray
()
packet
.
append
(
command
)
packet
.
append
(
command
)
self
.
_pack_remaining_length
(
packet
,
remaining_length
)
self
.
_pack_remaining_length
(
packet
,
remaining_length
)
...
@@ -2121,7 +2103,7 @@ class Client(object):
...
@@ -2121,7 +2103,7 @@ class Client(object):
for
t
in
topics
:
for
t
in
topics
:
self
.
_pack_str16
(
packet
,
t
)
self
.
_pack_str16
(
packet
,
t
)
#topics_repr = ", ".join("'"+topic.decode('utf8')+"'" for topic in topics)
#
topics_repr = ", ".join("'"+topic.decode('utf8')+"'" for topic in topics)
self
.
_easy_log
(
MQTT_LOG_DEBUG
,
"Sending UNSUBSCRIBE (d%d) %s"
,
dup
,
topics
)
self
.
_easy_log
(
MQTT_LOG_DEBUG
,
"Sending UNSUBSCRIBE (d%d) %s"
,
dup
,
topics
)
return
(
self
.
_packet_queue
(
command
,
packet
,
local_mid
,
1
),
local_mid
)
return
(
self
.
_packet_queue
(
command
,
packet
,
local_mid
,
1
),
local_mid
)
...
@@ -2157,12 +2139,12 @@ class Client(object):
...
@@ -2157,12 +2139,12 @@ class Client(object):
if
m
.
qos
==
0
:
if
m
.
qos
==
0
:
m
.
state
=
mqtt_ms_publish
m
.
state
=
mqtt_ms_publish
elif
m
.
qos
==
1
:
elif
m
.
qos
==
1
:
#self._inflight_messages = self._inflight_messages + 1
#
self._inflight_messages = self._inflight_messages + 1
if
m
.
state
==
mqtt_ms_wait_for_puback
:
if
m
.
state
==
mqtt_ms_wait_for_puback
:
m
.
dup
=
True
m
.
dup
=
True
m
.
state
=
mqtt_ms_publish
m
.
state
=
mqtt_ms_publish
elif
m
.
qos
==
2
:
elif
m
.
qos
==
2
:
#self._inflight_messages = self._inflight_messages + 1
#
self._inflight_messages = self._inflight_messages + 1
if
m
.
state
==
mqtt_ms_wait_for_pubcomp
:
if
m
.
state
==
mqtt_ms_wait_for_pubcomp
:
m
.
state
=
mqtt_ms_resend_pubrel
m
.
state
=
mqtt_ms_resend_pubrel
m
.
dup
=
True
m
.
dup
=
True
...
@@ -2361,9 +2343,9 @@ class Client(object):
...
@@ -2361,9 +2343,9 @@ class Client(object):
def
_handle_suback
(
self
):
def
_handle_suback
(
self
):
self
.
_easy_log
(
MQTT_LOG_DEBUG
,
"Received SUBACK"
)
self
.
_easy_log
(
MQTT_LOG_DEBUG
,
"Received SUBACK"
)
pack_format
=
"!H"
+
str
(
len
(
self
.
_in_packet
[
'packet'
])
-
2
)
+
's'
pack_format
=
"!H"
+
str
(
len
(
self
.
_in_packet
[
'packet'
])
-
2
)
+
's'
(
mid
,
packet
)
=
struct
.
unpack
(
pack_format
,
self
.
_in_packet
[
'packet'
])
(
mid
,
packet
)
=
struct
.
unpack
(
pack_format
,
self
.
_in_packet
[
'packet'
])
pack_format
=
"!"
+
"B"
*
len
(
packet
)
pack_format
=
"!"
+
"B"
*
len
(
packet
)
granted_qos
=
struct
.
unpack
(
pack_format
,
packet
)
granted_qos
=
struct
.
unpack
(
pack_format
,
packet
)
self
.
_callback_mutex
.
acquire
()
self
.
_callback_mutex
.
acquire
()
...
@@ -2380,13 +2362,13 @@ class Client(object):
...
@@ -2380,13 +2362,13 @@ class Client(object):
header
=
self
.
_in_packet
[
'command'
]
header
=
self
.
_in_packet
[
'command'
]
message
=
MQTTMessage
()
message
=
MQTTMessage
()
message
.
dup
=
(
header
&
0x08
)
>>
3
message
.
dup
=
(
header
&
0x08
)
>>
3
message
.
qos
=
(
header
&
0x06
)
>>
1
message
.
qos
=
(
header
&
0x06
)
>>
1
message
.
retain
=
(
header
&
0x01
)
message
.
retain
=
(
header
&
0x01
)
pack_format
=
"!H"
+
str
(
len
(
self
.
_in_packet
[
'packet'
])
-
2
)
+
's'
pack_format
=
"!H"
+
str
(
len
(
self
.
_in_packet
[
'packet'
])
-
2
)
+
's'
(
slen
,
packet
)
=
struct
.
unpack
(
pack_format
,
self
.
_in_packet
[
'packet'
])
(
slen
,
packet
)
=
struct
.
unpack
(
pack_format
,
self
.
_in_packet
[
'packet'
])
pack_format
=
'!'
+
str
(
slen
)
+
's'
+
str
(
len
(
packet
)
-
slen
)
+
's'
pack_format
=
'!'
+
str
(
slen
)
+
's'
+
str
(
len
(
packet
)
-
slen
)
+
's'
(
message
.
topic
,
packet
)
=
struct
.
unpack
(
pack_format
,
packet
)
(
message
.
topic
,
packet
)
=
struct
.
unpack
(
pack_format
,
packet
)
if
len
(
message
.
topic
)
==
0
:
if
len
(
message
.
topic
)
==
0
:
...
@@ -2396,7 +2378,7 @@ class Client(object):
...
@@ -2396,7 +2378,7 @@ class Client(object):
message
.
topic
=
message
.
topic
.
decode
(
'utf-8'
)
message
.
topic
=
message
.
topic
.
decode
(
'utf-8'
)
if
message
.
qos
>
0
:
if
message
.
qos
>
0
:
pack_format
=
"!H"
+
str
(
len
(
packet
)
-
2
)
+
's'
pack_format
=
"!H"
+
str
(
len
(
packet
)
-
2
)
+
's'
(
message
.
mid
,
packet
)
=
struct
.
unpack
(
pack_format
,
packet
)
(
message
.
mid
,
packet
)
=
struct
.
unpack
(
pack_format
,
packet
)
message
.
payload
=
packet
message
.
payload
=
packet
...
@@ -2573,58 +2555,14 @@ class Client(object):
...
@@ -2573,58 +2555,14 @@ class Client(object):
def
_thread_main
(
self
):
def
_thread_main
(
self
):
self
.
loop_forever
(
retry_first_connection
=
True
)
self
.
loop_forever
(
retry_first_connection
=
True
)
def
_host_matches_cert
(
self
,
host
,
cert_host
):
if
cert_host
[
0
:
2
]
==
"*."
:
if
cert_host
.
count
(
"*"
)
!=
1
:
return
False
host_match
=
host
.
split
(
"."
,
1
)[
1
]
cert_match
=
cert_host
.
split
(
"."
,
1
)[
1
]
return
host_match
==
cert_match
else
:
return
host
==
cert_host
def
_tls_match_hostname
(
self
,
sock
):
try
:
cert
=
sock
.
getpeercert
()
except
AttributeError
:
# the getpeercert can throw Attribute error: object has no attribute 'peer_certificate'
# Don't let that crash the whole client. See also: http://bugs.python.org/issue13721
raise
ssl
.
SSLError
(
'Not connected'
)
san
=
cert
.
get
(
'subjectAltName'
)
if
san
:
have_san_dns
=
False
for
(
key
,
value
)
in
san
:
if
key
==
'DNS'
:
have_san_dns
=
True
if
self
.
_host_matches_cert
(
self
.
_host
.
lower
(),
value
.
lower
()):
return
if
key
==
'IP Address'
:
have_san_dns
=
True
if
value
.
lower
()
==
self
.
_host
.
lower
():
return
if
have_san_dns
:
# Only check subject if subjectAltName dns not found.
raise
ssl
.
SSLError
(
'Certificate subject does not match remote hostname.'
)
subject
=
cert
.
get
(
'subject'
)
if
subject
:
for
((
key
,
value
),)
in
subject
:
if
key
==
'commonName'
:
if
self
.
_host_matches_cert
(
self
.
_host
.
lower
(),
value
.
lower
()):
return
raise
ssl
.
SSLError
(
'Certificate subject does not match remote hostname.'
)
# Compatibility class for easy porting from mosquitto.py.
# Compatibility class for easy porting from mosquitto.py.
class
Mosquitto
(
Client
):
class
Mosquitto
(
Client
):
def
__init__
(
self
,
client_id
=
""
,
clean_session
=
True
,
userdata
=
None
):
def
__init__
(
self
,
client_id
=
""
,
clean_session
=
True
,
userdata
=
None
):
super
(
Mosquitto
,
self
).
__init__
(
client_id
,
clean_session
,
userdata
)
super
(
Mosquitto
,
self
).
__init__
(
client_id
,
clean_session
,
userdata
)
class
WebsocketWrapper
:
class
WebsocketWrapper
:
OPCODE_CONTINUATION
=
0x0
OPCODE_CONTINUATION
=
0x0
OPCODE_TEXT
=
0x1
OPCODE_TEXT
=
0x1
OPCODE_BINARY
=
0x2
OPCODE_BINARY
=
0x2
...
@@ -2660,13 +2598,13 @@ class WebsocketWrapper:
...
@@ -2660,13 +2598,13 @@ class WebsocketWrapper:
sec_websocket_key
=
uuid
.
uuid4
().
bytes
sec_websocket_key
=
uuid
.
uuid4
().
bytes
sec_websocket_key
=
base64
.
b64encode
(
sec_websocket_key
)
sec_websocket_key
=
base64
.
b64encode
(
sec_websocket_key
)
header
=
b
"GET /mqtt HTTP/1.1
\r\n
"
+
\
header
=
b
"GET /mqtt HTTP/1.1
\r\n
"
+
\
b
"Upgrade: websocket
\r\n
"
+
\
b
"Upgrade: websocket
\r\n
"
+
\
b
"Connection: Upgrade
\r\n
"
+
\
b
"Connection: Upgrade
\r\n
"
+
\
b
"Host: "
+
str
(
self
.
_host
).
encode
(
'utf-8'
)
+
b
":"
+
str
(
self
.
_port
).
encode
(
'utf-8'
)
+
b
"
\r\n
"
+
\
b
"Host: "
+
str
(
self
.
_host
).
encode
(
'utf-8'
)
+
b
":"
+
str
(
self
.
_port
).
encode
(
'utf-8'
)
+
b
"
\r\n
"
+
\
b
"Origin: http://"
+
str
(
self
.
_host
).
encode
(
'utf-8'
)
+
b
":"
+
str
(
self
.
_port
).
encode
(
'utf-8'
)
+
b
"
\r\n
"
+
\
b
"Origin: http://"
+
str
(
self
.
_host
).
encode
(
'utf-8'
)
+
b
":"
+
str
(
self
.
_port
).
encode
(
'utf-8'
)
+
b
"
\r\n
"
+
\
b
"Sec-WebSocket-Key: "
+
sec_websocket_key
+
b
"
\r\n
"
+
\
b
"Sec-WebSocket-Key: "
+
sec_websocket_key
+
b
"
\r\n
"
+
\
b
"Sec-WebSocket-Version: 13
\r\n
"
+
\
b
"Sec-WebSocket-Version: 13
\r\n
"
+
\
b
"Sec-WebSocket-Protocol: mqtt
\r\n\r\n
"
b
"Sec-WebSocket-Protocol: mqtt
\r\n\r\n
"
self
.
_socket
.
send
(
header
)
self
.
_socket
.
send
(
header
)
...
@@ -2765,7 +2703,7 @@ class WebsocketWrapper:
...
@@ -2765,7 +2703,7 @@ class WebsocketWrapper:
self
.
_readbuffer
.
extend
(
data
)
self
.
_readbuffer
.
extend
(
data
)
self
.
_readbuffer_head
+=
length
self
.
_readbuffer_head
+=
length
return
self
.
_readbuffer
[
self
.
_readbuffer_head
-
length
:
self
.
_readbuffer_head
]
return
self
.
_readbuffer
[
self
.
_readbuffer_head
-
length
:
self
.
_readbuffer_head
]
def
_recv_impl
(
self
,
length
):
def
_recv_impl
(
self
,
length
):
...
@@ -2890,5 +2828,5 @@ class WebsocketWrapper:
...
@@ -2890,5 +2828,5 @@ class WebsocketWrapper:
def
fileno
(
self
):
def
fileno
(
self
):
return
self
.
_socket
.
fileno
()
return
self
.
_socket
.
fileno
()
def
setblocking
(
self
,
flag
):
def
setblocking
(
self
,
flag
):
self
.
_socket
.
setblocking
(
flag
)
self
.
_socket
.
setblocking
(
flag
)
test/lib/context.py
浏览文件 @
0a8cccc2
...
@@ -52,6 +52,6 @@ def check_ssl():
...
@@ -52,6 +52,6 @@ def check_ssl():
print
(
"WARNING: SSL not available in current environment"
)
print
(
"WARNING: SSL not available in current environment"
)
exit
(
0
)
exit
(
0
)
if
sys
.
version
<
'2.7'
:
if
not
hasattr
(
ssl
,
'SSLContext'
)
:
print
(
"WARNING: SSL
not supported on Python 2.6
"
)
print
(
"WARNING: SSL
without SSLContext is not supported
"
)
exit
(
0
)
exit
(
0
)
test/lib/python/08-ssl-bad-cacert.test
浏览文件 @
0a8cccc2
...
@@ -9,7 +9,7 @@ from struct import *
...
@@ -9,7 +9,7 @@ from struct import *
import
paho
.
mqtt
.
client
as
mqtt
import
paho
.
mqtt
.
client
as
mqtt
if
sys
.
version
<
'2.7'
:
if
sys
.
version
_info
<
(
2
,
7
,
9
)
:
print
(
"WARNING: SSL/TLS not supported on Python 2.6"
)
print
(
"WARNING: SSL/TLS not supported on Python 2.6"
)
exit
(
0
)
exit
(
0
)
...
...
test/lib/python/08-ssl-connect-cert-auth.test
浏览文件 @
0a8cccc2
...
@@ -9,7 +9,7 @@ from struct import *
...
@@ -9,7 +9,7 @@ from struct import *
import
paho
.
mqtt
.
client
as
mqtt
import
paho
.
mqtt
.
client
as
mqtt
if
sys
.
version_info
<
(
2
,
7
)
:
if
sys
.
version_info
<
(
2
,
7
,
9
)
:
print
(
"WARNING: SSL/TLS not supported on Python 2.6"
)
print
(
"WARNING: SSL/TLS not supported on Python 2.6"
)
exit
(
0
)
exit
(
0
)
...
...
test/lib/python/08-ssl-connect-no-auth.test
浏览文件 @
0a8cccc2
...
@@ -9,7 +9,7 @@ from struct import *
...
@@ -9,7 +9,7 @@ from struct import *
import
paho
.
mqtt
.
client
as
mqtt
import
paho
.
mqtt
.
client
as
mqtt
if
sys
.
version_info
<
(
2
,
7
)
:
if
sys
.
version_info
<
(
2
,
7
,
9
)
:
print
(
"WARNING: SSL/TLS not supported on Python 2.6"
)
print
(
"WARNING: SSL/TLS not supported on Python 2.6"
)
exit
(
0
)
exit
(
0
)
...
...
test/lib/python/08-ssl-fake-cacert.test
浏览文件 @
0a8cccc2
...
@@ -10,7 +10,7 @@ import ssl
...
@@ -10,7 +10,7 @@ import ssl
import
paho
.
mqtt
.
client
as
mqtt
import
paho
.
mqtt
.
client
as
mqtt
if
sys
.
version_info
<
(
2
,
7
)
:
if
sys
.
version_info
<
(
2
,
7
,
9
)
:
print
(
"WARNING: SSL/TLS not supported on Python 2.6"
)
print
(
"WARNING: SSL/TLS not supported on Python 2.6"
)
exit
(
0
)
exit
(
0
)
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录