From dcb2292ea2b00e133f9b2e33f112fa42beab7985 Mon Sep 17 00:00:00 2001 From: iabdalkader Date: Tue, 28 May 2024 10:06:07 +0200 Subject: [PATCH 1/5] ussl: Fix exception on missing SSL Context attributes. Signed-off-by: iabdalkader --- src/arduino_iot_cloud/ussl.py | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/src/arduino_iot_cloud/ussl.py b/src/arduino_iot_cloud/ussl.py index 5910149..f0c51af 100644 --- a/src/arduino_iot_cloud/ussl.py +++ b/src/arduino_iot_cloud/ussl.py @@ -7,6 +7,8 @@ # SSL module with m2crypto backend for HSM support. import ssl +import sys +import logging pkcs11 = None @@ -29,7 +31,7 @@ def wrap_socket(sock, ssl_params={}): ctx = ssl.SSLContext(ssl.PROTOCOL_TLS_CLIENT) if hasattr(ctx, "set_default_verify_paths"): ctx.set_default_verify_paths() - if verify != ssl.CERT_REQUIRED: + if hasattr(ctx, "check_hostname") and verify != ssl.CERT_REQUIRED: ctx.check_hostname = False ctx.verify_mode = verify if keyfile is not None and certfile is not None: @@ -41,7 +43,11 @@ def wrap_socket(sock, ssl_params={}): return ctx.wrap_socket(sock, server_hostname=hostname) else: # Use M2Crypto to load key and cert from HSM. - from M2Crypto import m2, SSL, Engine + try: + from M2Crypto import m2, SSL, Engine + except (ImportError, AttributeError): + logging.error("The m2crypto module is required to use HSM.") + sys.exit(1) global pkcs11 if pkcs11 is None: From af378da96da85742c544acec8453e245d00bb8e5 Mon Sep 17 00:00:00 2001 From: iabdalkader Date: Tue, 28 May 2024 10:07:04 +0200 Subject: [PATCH 2/5] ucloud: Fix exception when using an old version of CBOR2. Outdated versions of the CBOR2 library will not raise an exception. Signed-off-by: iabdalkader --- src/arduino_iot_cloud/ucloud.py | 21 +++++++-------------- 1 file changed, 7 insertions(+), 14 deletions(-) diff --git a/src/arduino_iot_cloud/ucloud.py b/src/arduino_iot_cloud/ucloud.py index 36e5e3b..5dbf0de 100644 --- a/src/arduino_iot_cloud/ucloud.py +++ b/src/arduino_iot_cloud/ucloud.py @@ -5,7 +5,6 @@ # file, You can obtain one at https://mozilla.org/MPL/2.0/. import time -import sys import logging import cbor2 from senml import SenmlPack @@ -22,7 +21,7 @@ class InvalidStateError(Exception): try: from arduino_iot_cloud._version import __version__ except (ImportError, AttributeError): - __version__ = "1.3.0" + __version__ = "1.3.1" # Server/port for basic auth. _DEFAULT_SERVER = "iot.arduino.cc" @@ -40,7 +39,7 @@ def timestamp(): def timestamp_ms(): - return time.time_ns()//1000000 + return time.time_ns() // 1000000 def log_level_enabled(level): @@ -199,14 +198,6 @@ def __init__( self.async_mode = not sync_mode self.connected = False - if "pin" in ssl_params: - try: - # Use M2Crypto to load key and cert from HSM. - import M2Crypto # noqa - except (ImportError, AttributeError): - logging.error("The m2crypto module is required to use HSM.") - sys.exit(1) - # Convert args to bytes if they are passed as strings. if isinstance(device_id, str): device_id = bytes(device_id, "utf-8") @@ -372,9 +363,11 @@ def poll_discovery(self, aiot=None): self.mqtt.subscribe(self.create_topic("shadow", "i"), qos=1) self.mqtt.publish(self.create_topic("shadow", "o"), self.senmlpack.to_cbor(), qos=1) - # Push library version and mode. - libv = "%s-%s" % (__version__, "async" if self.async_mode else "sync") - self.mqtt.publish(self.command_topic, cbor2.dumps(cbor2.CBORTag(67328, [libv])), qos=1) + if hasattr(cbor2, "dumps"): + # Push library version and mode. + libv = "%s-%s" % (__version__, "async" if self.async_mode else "sync") + # Note we have to add the tag manually because python-ecosys's cbor2 doesn't suppor CBORTags. + self.mqtt.publish(self.command_topic, b"\xda\x00\x01\x07\x00" + cbor2.dumps([libv]), qos=1) logging.info("Device configured via discovery protocol.") if self.async_mode: raise DoneException() From 1b077a043dff29630b9f58213745432d7f216aff Mon Sep 17 00:00:00 2001 From: iabdalkader Date: Tue, 28 May 2024 10:09:56 +0200 Subject: [PATCH 3/5] misc: Fix README.md typo. Signed-off-by: iabdalkader --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 93733cf..5a8d1fc 100644 --- a/README.md +++ b/README.md @@ -41,7 +41,7 @@ DEVICE_ID = "" # Provided by Arduino cloud when creating a device. SECRET_KEY = "" # Provided by Arduino cloud when creating a device. ``` -Note that by default, the client runs in asynchronous mode. In this mode, the client takes runs an asyncio loop that updates tasks and records, polls networking events, etc. The client also supports a synchronous mode, which requires periodic client polling. To run the client in synchronous mode, pass `sync_mode=True` when creating a client object and call `client.update()` periodically after connecting. For example: +Note that by default, the client runs in asynchronous mode. In this mode, the client runs an asyncio loop that updates tasks and records, polls networking events, etc. The client also supports a synchronous mode, which requires periodic client polling. To run the client in synchronous mode, pass `sync_mode=True` when creating a client object and call `client.update()` periodically after connecting. For example: ```Python # Run the client in synchronous mode. From 4c359e1e0ad00e47a882355e0735dd1c383678d2 Mon Sep 17 00:00:00 2001 From: iabdalkader Date: Tue, 28 May 2024 10:33:25 +0200 Subject: [PATCH 4/5] misc: Update workflow to ignore C901. Signed-off-by: iabdalkader --- .github/workflows/python-linter.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/python-linter.yml b/.github/workflows/python-linter.yml index 9526de7..60ca55e 100644 --- a/.github/workflows/python-linter.yml +++ b/.github/workflows/python-linter.yml @@ -35,4 +35,4 @@ jobs: run: | # stop the build if there are Python syntax errors or undefined names flake8 . --count --select=E9,F63,F7,F82 --show-source --statistics - flake8 . --count --max-complexity=15 --max-line-length=120 --statistics + flake8 . --count --ignore=C901 --max-complexity=15 --max-line-length=120 --statistics From 184561c7186561ac607c5c2acaa31fda73051c74 Mon Sep 17 00:00:00 2001 From: iabdalkader Date: Tue, 28 May 2024 10:35:38 +0200 Subject: [PATCH 5/5] misc: Fix linter errors. Signed-off-by: iabdalkader --- examples/example.py | 4 ++-- tests/ci.py | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/examples/example.py b/examples/example.py index 62f3b71..a945c04 100644 --- a/examples/example.py +++ b/examples/example.py @@ -43,8 +43,8 @@ def user_task(client): if __name__ == "__main__": # Parse command line args. parser = argparse.ArgumentParser(description="arduino_iot_cloud.py") - parser.add_argument("-d", "--debug", action="store_true", help="Enable debugging messages") - parser.add_argument("-s", "--sync", action="store_true", help="Run in synchronous mode") + parser.add_argument("-d", "--debug", action="store_true", help="Enable debugging messages") + parser.add_argument("-s", "--sync", action="store_true", help="Run in synchronous mode") args = parser.parse_args() # Assume the host has an active Internet connection. diff --git a/tests/ci.py b/tests/ci.py index f639c49..40ca1eb 100644 --- a/tests/ci.py +++ b/tests/ci.py @@ -48,7 +48,7 @@ def wdt_task(client, ts=[None]): "-f", "--file-auth", action="store_true", help="Use key/cert files" ) parser.add_argument( - "-s", "--sync", action="store_true", help="Run in synchronous mode" + "-s", "--sync", action="store_true", help="Run in synchronous mode" ) args = parser.parse_args()