From cf94109e562914be58feb16c8adf16164cd8f817 Mon Sep 17 00:00:00 2001 From: Maxim Martynov Date: Sun, 20 Aug 2023 11:50:48 +0300 Subject: [PATCH] Upgrade to Python 3.7+ syntax (#234) --- README.md | 2 +- build_helpers/check-smb.py | 18 ++-- examples/high-level/directory-management.py | 15 ++- examples/low-level/directory-management.py | 10 +- examples/low-level/file-management.py | 12 ++- reports/coverage.coverage | Bin 0 -> 372736 bytes ...-6.4.9-1-MANJARO-x86_64-with-glibc2.38.xml | 1 + setup.py | 1 - src/smbclient/__init__.py | 1 - src/smbclient/_io.py | 22 ++-- src/smbclient/_os.py | 28 +++-- src/smbclient/_pool.py | 44 ++++---- src/smbclient/path.py | 1 - src/smbclient/shutil.py | 3 +- src/smbprotocol/__init__.py | 1 - src/smbprotocol/_text.py | 1 - src/smbprotocol/change_notify.py | 9 +- src/smbprotocol/connection.py | 57 ++++++----- src/smbprotocol/create_contexts.py | 1 - src/smbprotocol/dfs.py | 56 +++++----- src/smbprotocol/exceptions.py | 58 +++++------ src/smbprotocol/file_info.py | 1 - src/smbprotocol/header.py | 1 - src/smbprotocol/ioctl.py | 1 - src/smbprotocol/open.py | 76 ++++++++------ src/smbprotocol/query_info.py | 1 - src/smbprotocol/reparse_point.py | 5 +- src/smbprotocol/security_descriptor.py | 6 +- src/smbprotocol/session.py | 15 ++- src/smbprotocol/structure.py | 96 ++++++++---------- src/smbprotocol/transport.py | 14 ++- src/smbprotocol/tree.py | 34 +++---- tests/__init__.py | 1 - tests/conftest.py | 16 +-- tests/test_change_notify.py | 1 - tests/test_connection.py | 1 - tests/test_create_contexts.py | 5 +- tests/test_dfs.py | 1 - tests/test_exceptions.py | 2 - tests/test_file_info.py | 1 - tests/test_header.py | 1 - tests/test_ioctl.py | 1 - tests/test_open.py | 1 - tests/test_query_info.py | 1 - tests/test_reparse_point.py | 1 - tests/test_security_descriptor.py | 1 - tests/test_session.py | 1 - tests/test_smbclient_os.py | 45 ++++---- tests/test_smbclient_path.py | 1 - tests/test_smbclient_pool.py | 15 ++- tests/test_smbclient_shutil.py | 3 +- tests/test_structure.py | 1 - tests/test_text.py | 1 - tests/test_transport.py | 3 +- tests/test_tree.py | 1 - 55 files changed, 339 insertions(+), 357 deletions(-) create mode 100644 reports/coverage.coverage create mode 100644 reports/junit/python-3.11.3-Linux-6.4.9-1-MANJARO-x86_64-with-glibc2.38.xml diff --git a/README.md b/README.md index c85fa6b3..3edd0148 100644 --- a/README.md +++ b/README.md @@ -59,7 +59,7 @@ try: from gssapi.raw import inquire_sec_context_by_oid print("python-gssapi extension is available") except ImportError as exc: - print("python-gssapi extension is not available: %s" % str(exc)) + print(f"python-gssapi extension is not available: {exc}") ``` If it isn't available, then either a newer version of the system's gssapi implementation needs to be setup and diff --git a/build_helpers/check-smb.py b/build_helpers/check-smb.py index 9d1db9d5..17e52a71 100755 --- a/build_helpers/check-smb.py +++ b/build_helpers/check-smb.py @@ -1,13 +1,17 @@ +import logging import os import time import uuid from smbprotocol.connection import Connection +log = logging.getLogger(__name__) +logging.basicConfig(level=logging.INFO) + def test_connection(server, port): conn = Connection(uuid.uuid4(), server, port=port) - print("Opening connection to %s:%d" % (server, port)) + log.info("Opening connection to %s:%d", server, port) conn.connect(timeout=5) conn.disconnect(True) @@ -15,22 +19,22 @@ def test_connection(server, port): if __name__ == "__main__": server = os.environ.get("SMB_SERVER", "127.0.0.1") port = int(os.environ.get("SMB_PORT", 445)) - print("Waiting for SMB server to be online") + log.info("Waiting for SMB server to be online") attempt = 1 total_attempts = 20 while attempt < total_attempts: - print("Starting attempt %d" % attempt) + log.info("Starting attempt %d", attempt) try: test_connection(server, port) break except Exception as e: - print("Connection attempt %d failed: %s" % (attempt, str(e))) + log.info("Connection attempt %d failed: %s", attempt, e) attempt += 1 if attempt == total_attempts: - raise Exception("Timeout while waiting for SMB server to come online") + raise Exception("Timeout while waiting for SMB server to come online") from e - print("Sleeping for 5 seconds before next attempt") + log.info("Sleeping for 5 seconds before next attempt") time.sleep(5) - print("Connection successful") + log.info("Connection successful") diff --git a/examples/high-level/directory-management.py b/examples/high-level/directory-management.py index 3eef9396..e63f234e 100644 --- a/examples/high-level/directory-management.py +++ b/examples/high-level/directory-management.py @@ -1,6 +1,11 @@ +import logging + from smbclient import listdir, mkdir, register_session, rmdir, scandir from smbclient.path import isdir +log = logging.getLogger(__name__) +logging.basicConfig(level=logging.INFO) + # Optional - register the server with explicit credentials register_session("server", username="admin", password="pass") @@ -12,18 +17,18 @@ # Checking whether a file is a directory d_filename = r"\\server\share\directory" -print("Is file {} dir?: {}".format(d_filename, isdir(d_filename))) +log.info("Is file %s dir?: %b", d_filename, isdir(d_filename)) # List the files/directories inside a dir for filename in listdir(r"\\server\share\directory"): - print(filename) + log.info(filename) # Use scandir as a more efficient directory listing as it already contains info like stat and attributes. for file_info in scandir(r"\\server\share\directory"): file_inode = file_info.inode() if file_info.is_file(): - print("File: %s %d" % (file_info.name, file_inode)) + log.info("File: %s %d", file_info.name, file_inode) elif file_info.is_dir(): - print("Dir: %s %d" % (file_info.name, file_inode)) + log.info("Dir: %s %d", file_info.name, file_inode) else: - print("Symlink: %s %d" % (file_info.name, file_inode)) + log.info("Symlink: %s %d", file_info.name, file_inode) diff --git a/examples/low-level/directory-management.py b/examples/low-level/directory-management.py index 18ac9cf0..74a2b2d1 100644 --- a/examples/low-level/directory-management.py +++ b/examples/low-level/directory-management.py @@ -1,3 +1,4 @@ +import logging import uuid from smbprotocol.connection import Connection @@ -15,11 +16,14 @@ from smbprotocol.session import Session from smbprotocol.tree import TreeConnect +log = logging.getLogger(__name__) +logging.basicConfig(level=logging.INFO) + server = "127.0.0.1" port = 445 username = "smbuser" password = "smbpassword" -share = r"\\%s\share" % server +share = rf"\\{server}\share" dir_name = "directory" connection = Connection(uuid.uuid4(), server, port) @@ -55,7 +59,7 @@ ) compound_messages = [ - directory_file.write("Hello World".encode("utf-8"), 0, send=False), + directory_file.write(b"Hello World", 0, send=False), dir_open.query_directory("*", FileInformationClass.FILE_NAMES_INFORMATION, send=False), directory_file.close(False, send=False), dir_open.close(False, send=False), @@ -70,7 +74,7 @@ for dir_file in responses[1]: dir_files.append(dir_file["file_name"].get_value().decode("utf-16-le")) - print("Directory '%s\\%s' contains the files: '%s'" % (share, dir_name, "', '".join(dir_files))) + log.info("Directory '%s\\%s' contains the files: %s", share, dir_name, ", ".join(repr(file) for file in dir_files)) # delete a directory (note the dir needs to be empty to delete on close) dir_open = Open(tree, dir_name) diff --git a/examples/low-level/file-management.py b/examples/low-level/file-management.py index a2e39032..beb5ec8e 100644 --- a/examples/low-level/file-management.py +++ b/examples/low-level/file-management.py @@ -1,3 +1,4 @@ +import logging import uuid from smbprotocol.connection import Connection @@ -27,11 +28,14 @@ from smbprotocol.structure import FlagField from smbprotocol.tree import TreeConnect +log = logging.getLogger(__name__) +logging.basicConfig(level=logging.INFO) + server = "127.0.0.1" port = 445 username = "smbuser" password = "smbpassword" -share = r"\\%s\share" % server +share = rf"\\{server}\share" file_name = "file-test.txt" connection = Connection(uuid.uuid4(), server, port) @@ -83,7 +87,7 @@ # flag field, set the value and get the human readble string max_access = FlagField(size=4, flag_type=FilePipePrinterAccessMask, flag_strict=False) max_access.set_value(open_info[0]["maximal_access"].get_value()) - print("Maximum access mask for file %s\\%s: %s" % (share, file_name, str(max_access))) + log.info("Maximum access mask for file %s\\%s: %s", share, file_name, max_access) # write to a file text = "Hello World, what a nice day to play with SMB" @@ -91,7 +95,7 @@ # read from a file file_text = file_open.read(0, 1024) - print("Text of file %s\\%s: %s" % (share, file_name, file_text.decode("utf-8"))) + log.info("Text of file %s\\%s: %s", share, file_name, file_text.decode("utf-8")) file_open.close(False) # read and delete a file in a single SMB packet instead of 3 @@ -116,6 +120,6 @@ for i, request in enumerate(requests): response = delete_msgs[i][1](request) responses.append(response) - print("Text of file when reading/deleting in 1 request: %s" % responses[1].decode("utf-8")) + log.info("Text of file when reading/deleting in 1 request: %s", responses[1].decode("utf-8")) finally: connection.disconnect(True) diff --git a/reports/coverage.coverage b/reports/coverage.coverage new file mode 100644 index 0000000000000000000000000000000000000000..1c408cf22efec313fd31c7ae3a3fe14235248795 GIT binary patch literal 372736 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 literal 0 HcmV?d00001 diff --git a/reports/junit/python-3.11.3-Linux-6.4.9-1-MANJARO-x86_64-with-glibc2.38.xml b/reports/junit/python-3.11.3-Linux-6.4.9-1-MANJARO-x86_64-with-glibc2.38.xml new file mode 100644 index 00000000..d6c593a7 --- /dev/null +++ b/reports/junit/python-3.11.3-Linux-6.4.9-1-MANJARO-x86_64-with-glibc2.38.xml @@ -0,0 +1 @@ +/home/maxim/Repo/smbprotocol/tests/test_change_notify.py:121: The SMB_SHARE env var was not set, integration tests will be skipped/home/maxim/Repo/smbprotocol/tests/test_change_notify.py:189: The SMB_SHARE env var was not set, integration tests will be skipped/home/maxim/Repo/smbprotocol/tests/test_change_notify.py:280: The SMB_SHARE env var was not set, integration tests will be skipped/home/maxim/Repo/smbprotocol/tests/test_change_notify.py:345: The SMB_SHARE env var was not set, integration tests will be skipped/home/maxim/Repo/smbprotocol/tests/test_change_notify.py:376: The SMB_SHARE env var was not set, integration tests will be skipped/home/maxim/Repo/smbprotocol/tests/test_change_notify.py:417: The SMB_SHARE env var was not set, integration tests will be skipped/home/maxim/Repo/smbprotocol/tests/test_connection.py:860: The SMB_SHARE env var was not set, integration tests will be skipped/home/maxim/Repo/smbprotocol/tests/test_connection.py:877: The SMB_SHARE env var was not set, integration tests will be skipped/home/maxim/Repo/smbprotocol/tests/test_connection.py:894: The SMB_SHARE env var was not set, integration tests will be skipped/home/maxim/Repo/smbprotocol/tests/test_connection.py:911: The SMB_SHARE env var was not set, integration tests will be skipped/home/maxim/Repo/smbprotocol/tests/test_connection.py:928: The SMB_SHARE env var was not set, integration tests will be skipped/home/maxim/Repo/smbprotocol/tests/test_connection.py:949: The SMB_SHARE env var was not set, integration tests will be skipped/home/maxim/Repo/smbprotocol/tests/test_connection.py:972: The SMB_SHARE env var was not set, integration tests will be skipped/home/maxim/Repo/smbprotocol/tests/test_connection.py:982: The SMB_SHARE env var was not set, integration tests will be skipped/home/maxim/Repo/smbprotocol/tests/test_connection.py:1063: The SMB_SHARE env var was not set, integration tests will be skipped/home/maxim/Repo/smbprotocol/tests/test_connection.py:1076: The SMB_SHARE env var was not set, integration tests will be skipped/home/maxim/Repo/smbprotocol/tests/test_connection.py:1094: The SMB_SHARE env var was not set, integration tests will be skipped/home/maxim/Repo/smbprotocol/tests/test_connection.py:1113: The SMB_SHARE env var was not set, integration tests will be skipped/home/maxim/Repo/smbprotocol/tests/test_connection.py:1132: The SMB_SHARE env var was not set, integration tests will be skipped/home/maxim/Repo/smbprotocol/tests/test_connection.py:1144: The SMB_SHARE env var was not set, integration tests will be skipped/home/maxim/Repo/smbprotocol/tests/test_connection.py:1158: The SMB_SHARE env var was not set, integration tests will be skipped/home/maxim/Repo/smbprotocol/tests/test_open.py:1167: The SMB_SHARE env var was not set, integration tests will be skipped/home/maxim/Repo/smbprotocol/tests/test_open.py:1211: The SMB_SHARE env var was not set, integration tests will be skipped/home/maxim/Repo/smbprotocol/tests/test_open.py:1255: The SMB_SHARE env var was not set, integration tests will be skipped/home/maxim/Repo/smbprotocol/tests/test_open.py:1299: The SMB_SHARE env var was not set, integration tests will be skipped/home/maxim/Repo/smbprotocol/tests/test_open.py:1343: The SMB_SHARE env var was not set, integration tests will be skipped/home/maxim/Repo/smbprotocol/tests/test_open.py:1387: The SMB_SHARE env var was not set, integration tests will be skipped/home/maxim/Repo/smbprotocol/tests/test_open.py:1410: The SMB_SHARE env var was not set, integration tests will be skipped/home/maxim/Repo/smbprotocol/tests/test_open.py:1454: The SMB_SHARE env var was not set, integration tests will be skipped/home/maxim/Repo/smbprotocol/tests/test_open.py:1499: The SMB_SHARE env var was not set, integration tests will be skipped/home/maxim/Repo/smbprotocol/tests/test_open.py:1499: The SMB_SHARE env var was not set, integration tests will be skipped/home/maxim/Repo/smbprotocol/tests/test_open.py:1539: The SMB_SHARE env var was not set, integration tests will be skipped/home/maxim/Repo/smbprotocol/tests/test_open.py:1565: The SMB_SHARE env var was not set, integration tests will be skipped/home/maxim/Repo/smbprotocol/tests/test_open.py:1595: The SMB_SHARE env var was not set, integration tests will be skipped/home/maxim/Repo/smbprotocol/tests/test_open.py:1624: The SMB_SHARE env var was not set, integration tests will be skipped/home/maxim/Repo/smbprotocol/tests/test_open.py:1654: The SMB_SHARE env var was not set, integration tests will be skipped/home/maxim/Repo/smbprotocol/tests/test_open.py:1679: The SMB_SHARE env var was not set, integration tests will be skipped/home/maxim/Repo/smbprotocol/tests/test_open.py:1713: The SMB_SHARE env var was not set, integration tests will be skipped/home/maxim/Repo/smbprotocol/tests/test_open.py:1740: The SMB_SHARE env var was not set, integration tests will be skipped/home/maxim/Repo/smbprotocol/tests/test_open.py:1773: The SMB_SHARE env var was not set, integration tests will be skipped/home/maxim/Repo/smbprotocol/tests/test_open.py:1800: The SMB_SHARE env var was not set, integration tests will be skipped/home/maxim/Repo/smbprotocol/tests/test_open.py:1833: The SMB_SHARE env var was not set, integration tests will be skipped/home/maxim/Repo/smbprotocol/tests/test_open.py:1893: The SMB_SHARE env var was not set, integration tests will be skipped/home/maxim/Repo/smbprotocol/tests/test_open.py:1936: The SMB_SHARE env var was not set, integration tests will be skipped/home/maxim/Repo/smbprotocol/tests/test_open.py:1979: The SMB_SHARE env var was not set, integration tests will be skipped/home/maxim/Repo/smbprotocol/tests/test_open.py:2066: The SMB_SHARE env var was not set, integration tests will be skipped/home/maxim/Repo/smbprotocol/tests/test_open.py:2153: The SMB_SHARE env var was not set, integration tests will be skipped/home/maxim/Repo/smbprotocol/tests/test_open.py:2180: The SMB_SHARE env var was not set, integration tests will be skipped/home/maxim/Repo/smbprotocol/tests/test_open.py:2209: The SMB_SHARE env var was not set, integration tests will be skipped/home/maxim/Repo/smbprotocol/tests/test_open.py:2238: The SMB_SHARE env var was not set, integration tests will be skipped/home/maxim/Repo/smbprotocol/tests/test_open.py:2262: The SMB_SHARE env var was not set, integration tests will be skipped/home/maxim/Repo/smbprotocol/tests/test_open.py:2301: The SMB_SHARE env var was not set, integration tests will be skipped/home/maxim/Repo/smbprotocol/tests/test_open.py:2331: The SMB_SHARE env var was not set, integration tests will be skipped/home/maxim/Repo/smbprotocol/tests/test_session.py:106: The SMB_SHARE env var was not set, integration tests will be skipped/home/maxim/Repo/smbprotocol/tests/test_session.py:126: The SMB_SHARE env var was not set, integration tests will be skipped/home/maxim/Repo/smbprotocol/tests/test_session.py:146: The SMB_SHARE env var was not set, integration tests will be skipped/home/maxim/Repo/smbprotocol/tests/test_session.py:170: The SMB_SHARE env var was not set, integration tests will be skipped/home/maxim/Repo/smbprotocol/tests/test_session.py:194: The SMB_SHARE env var was not set, integration tests will be skipped/home/maxim/Repo/smbprotocol/tests/test_session.py:220: The SMB_SHARE env var was not set, integration tests will be skipped/home/maxim/Repo/smbprotocol/tests/test_session.py:244: The SMB_SHARE env var was not set, integration tests will be skipped/home/maxim/Repo/smbprotocol/tests/test_session.py:255: The SMB_SHARE env var was not set, integration tests will be skipped/home/maxim/Repo/smbprotocol/tests/test_session.py:270: The SMB_SHARE env var was not set, integration tests will be skipped/home/maxim/Repo/smbprotocol/tests/test_session.py:311: The SMB_SHARE env var was not set, integration tests will be skipped/home/maxim/Repo/smbprotocol/tests/test_smbclient_os.py:37: The SMB_SHARE env var was not set, integration tests will be skipped/home/maxim/Repo/smbprotocol/tests/test_smbclient_os.py:37: The SMB_SHARE env var was not set, integration tests will be skipped/home/maxim/Repo/smbprotocol/tests/test_smbclient_os.py:48: The SMB_SHARE env var was not set, integration tests will be skipped/home/maxim/Repo/smbprotocol/tests/test_smbclient_os.py:48: The SMB_SHARE env var was not set, integration tests will be skipped/home/maxim/Repo/smbprotocol/tests/test_smbclient_os.py:59: The SMB_SHARE env var was not set, integration tests will be skipped/home/maxim/Repo/smbprotocol/tests/test_smbclient_os.py:59: The SMB_SHARE env var was not set, integration tests will be skipped/home/maxim/Repo/smbprotocol/tests/test_smbclient_os.py:77: The SMB_SHARE env var was not set, integration tests will be skipped/home/maxim/Repo/smbprotocol/tests/test_smbclient_os.py:77: The SMB_SHARE env var was not set, integration tests will be skipped/home/maxim/Repo/smbprotocol/tests/test_smbclient_os.py:90: The SMB_SHARE env var was not set, integration tests will be skipped/home/maxim/Repo/smbprotocol/tests/test_smbclient_os.py:90: The SMB_SHARE env var was not set, integration tests will be skipped/home/maxim/Repo/smbprotocol/tests/test_smbclient_os.py:101: The SMB_SHARE env var was not set, integration tests will be skipped/home/maxim/Repo/smbprotocol/tests/test_smbclient_os.py:101: The SMB_SHARE env var was not set, integration tests will be skipped/home/maxim/Repo/smbprotocol/tests/test_smbclient_os.py:112: The SMB_SHARE env var was not set, integration tests will be skipped/home/maxim/Repo/smbprotocol/tests/test_smbclient_os.py:112: The SMB_SHARE env var was not set, integration tests will be skipped/home/maxim/Repo/smbprotocol/tests/test_smbclient_os.py:130: The SMB_SHARE env var was not set, integration tests will be skipped/home/maxim/Repo/smbprotocol/tests/test_smbclient_os.py:130: The SMB_SHARE env var was not set, integration tests will be skipped/home/maxim/Repo/smbprotocol/tests/test_smbclient_os.py:136: The SMB_SHARE env var was not set, integration tests will be skipped/home/maxim/Repo/smbprotocol/tests/test_smbclient_os.py:136: The SMB_SHARE env var was not set, integration tests will be skipped/home/maxim/Repo/smbprotocol/tests/test_smbclient_os.py:142: The SMB_SHARE env var was not set, integration tests will be skipped/home/maxim/Repo/smbprotocol/tests/test_smbclient_os.py:142: The SMB_SHARE env var was not set, integration tests will be skipped/home/maxim/Repo/smbprotocol/tests/test_smbclient_os.py:148: The SMB_SHARE env var was not set, integration tests will be skipped/home/maxim/Repo/smbprotocol/tests/test_smbclient_os.py:148: The SMB_SHARE env var was not set, integration tests will be skipped/home/maxim/Repo/smbprotocol/tests/test_smbclient_os.py:163: The SMB_SHARE env var was not set, integration tests will be skipped/home/maxim/Repo/smbprotocol/tests/test_smbclient_os.py:163: The SMB_SHARE env var was not set, integration tests will be skipped/home/maxim/Repo/smbprotocol/tests/test_smbclient_os.py:172: The SMB_SHARE env var was not set, integration tests will be skipped/home/maxim/Repo/smbprotocol/tests/test_smbclient_os.py:172: The SMB_SHARE env var was not set, integration tests will be skipped/home/maxim/Repo/smbprotocol/tests/test_smbclient_os.py:194: cannot create symlinks on Samba/home/maxim/Repo/smbprotocol/tests/test_smbclient_os.py:194: cannot create symlinks on Samba/home/maxim/Repo/smbprotocol/tests/test_smbclient_os.py:214: cannot create symlinks on Samba/home/maxim/Repo/smbprotocol/tests/test_smbclient_os.py:214: cannot create symlinks on Samba/home/maxim/Repo/smbprotocol/tests/test_smbclient_os.py:234: The SMB_SHARE env var was not set, integration tests will be skipped/home/maxim/Repo/smbprotocol/tests/test_smbclient_os.py:234: The SMB_SHARE env var was not set, integration tests will be skipped/home/maxim/Repo/smbprotocol/tests/test_smbclient_os.py:234: The SMB_SHARE env var was not set, integration tests will be skipped/home/maxim/Repo/smbprotocol/tests/test_smbclient_os.py:234: The SMB_SHARE env var was not set, integration tests will be skipped/home/maxim/Repo/smbprotocol/tests/test_smbclient_os.py:247: The SMB_SHARE env var was not set, integration tests will be skipped/home/maxim/Repo/smbprotocol/tests/test_smbclient_os.py:247: The SMB_SHARE env var was not set, integration tests will be skipped/home/maxim/Repo/smbprotocol/tests/test_smbclient_os.py:257: The SMB_SHARE env var was not set, integration tests will be skipped/home/maxim/Repo/smbprotocol/tests/test_smbclient_os.py:257: The SMB_SHARE env var was not set, integration tests will be skipped/home/maxim/Repo/smbprotocol/tests/test_smbclient_os.py:257: The SMB_SHARE env var was not set, integration tests will be skipped/home/maxim/Repo/smbprotocol/tests/test_smbclient_os.py:257: The SMB_SHARE env var was not set, integration tests will be skipped/home/maxim/Repo/smbprotocol/tests/test_smbclient_os.py:284: The SMB_SHARE env var was not set, integration tests will be skipped/home/maxim/Repo/smbprotocol/tests/test_smbclient_os.py:284: The SMB_SHARE env var was not set, integration tests will be skipped/home/maxim/Repo/smbprotocol/tests/test_smbclient_os.py:297: The SMB_SHARE env var was not set, integration tests will be skipped/home/maxim/Repo/smbprotocol/tests/test_smbclient_os.py:297: The SMB_SHARE env var was not set, integration tests will be skipped/home/maxim/Repo/smbprotocol/tests/test_smbclient_os.py:302: The SMB_SHARE env var was not set, integration tests will be skipped/home/maxim/Repo/smbprotocol/tests/test_smbclient_os.py:302: The SMB_SHARE env var was not set, integration tests will be skipped/home/maxim/Repo/smbprotocol/tests/test_smbclient_os.py:325: The SMB_SHARE env var was not set, integration tests will be skipped/home/maxim/Repo/smbprotocol/tests/test_smbclient_os.py:325: The SMB_SHARE env var was not set, integration tests will be skipped/home/maxim/Repo/smbprotocol/tests/test_smbclient_os.py:347: cannot create symlinks on Samba/home/maxim/Repo/smbprotocol/tests/test_smbclient_os.py:347: cannot create symlinks on Samba/home/maxim/Repo/smbprotocol/tests/test_smbclient_os.py:366: The SMB_SHARE env var was not set, integration tests will be skipped/home/maxim/Repo/smbprotocol/tests/test_smbclient_os.py:366: The SMB_SHARE env var was not set, integration tests will be skipped/home/maxim/Repo/smbprotocol/tests/test_smbclient_os.py:377: The SMB_SHARE env var was not set, integration tests will be skipped/home/maxim/Repo/smbprotocol/tests/test_smbclient_os.py:377: The SMB_SHARE env var was not set, integration tests will be skipped/home/maxim/Repo/smbprotocol/tests/test_smbclient_os.py:384: The SMB_SHARE env var was not set, integration tests will be skipped/home/maxim/Repo/smbprotocol/tests/test_smbclient_os.py:384: The SMB_SHARE env var was not set, integration tests will be skipped/home/maxim/Repo/smbprotocol/tests/test_smbclient_os.py:394: The SMB_SHARE env var was not set, integration tests will be skipped/home/maxim/Repo/smbprotocol/tests/test_smbclient_os.py:394: The SMB_SHARE env var was not set, integration tests will be skipped/home/maxim/Repo/smbprotocol/tests/test_smbclient_os.py:400: The SMB_SHARE env var was not set, integration tests will be skipped/home/maxim/Repo/smbprotocol/tests/test_smbclient_os.py:400: The SMB_SHARE env var was not set, integration tests will be skipped/home/maxim/Repo/smbprotocol/tests/test_smbclient_os.py:411: The SMB_SHARE env var was not set, integration tests will be skipped/home/maxim/Repo/smbprotocol/tests/test_smbclient_os.py:411: The SMB_SHARE env var was not set, integration tests will be skipped/home/maxim/Repo/smbprotocol/tests/test_smbclient_os.py:417: The SMB_SHARE env var was not set, integration tests will be skipped/home/maxim/Repo/smbprotocol/tests/test_smbclient_os.py:417: The SMB_SHARE env var was not set, integration tests will be skipped/home/maxim/Repo/smbprotocol/tests/test_smbclient_os.py:432: The SMB_SHARE env var was not set, integration tests will be skipped/home/maxim/Repo/smbprotocol/tests/test_smbclient_os.py:432: The SMB_SHARE env var was not set, integration tests will be skipped/home/maxim/Repo/smbprotocol/tests/test_smbclient_os.py:473: The SMB_SHARE env var was not set, integration tests will be skipped/home/maxim/Repo/smbprotocol/tests/test_smbclient_os.py:473: The SMB_SHARE env var was not set, integration tests will be skipped/home/maxim/Repo/smbprotocol/tests/test_smbclient_os.py:504: The SMB_SHARE env var was not set, integration tests will be skipped/home/maxim/Repo/smbprotocol/tests/test_smbclient_os.py:504: The SMB_SHARE env var was not set, integration tests will be skipped/home/maxim/Repo/smbprotocol/tests/test_smbclient_os.py:533: The SMB_SHARE env var was not set, integration tests will be skipped/home/maxim/Repo/smbprotocol/tests/test_smbclient_os.py:533: The SMB_SHARE env var was not set, integration tests will be skipped/home/maxim/Repo/smbprotocol/tests/test_smbclient_os.py:564: The SMB_SHARE env var was not set, integration tests will be skipped/home/maxim/Repo/smbprotocol/tests/test_smbclient_os.py:564: The SMB_SHARE env var was not set, integration tests will be skipped/home/maxim/Repo/smbprotocol/tests/test_smbclient_os.py:576: The SMB_SHARE env var was not set, integration tests will be skipped/home/maxim/Repo/smbprotocol/tests/test_smbclient_os.py:576: The SMB_SHARE env var was not set, integration tests will be skipped/home/maxim/Repo/smbprotocol/tests/test_smbclient_os.py:602: The SMB_SHARE env var was not set, integration tests will be skipped/home/maxim/Repo/smbprotocol/tests/test_smbclient_os.py:602: The SMB_SHARE env var was not set, integration tests will be skipped/home/maxim/Repo/smbprotocol/tests/test_smbclient_os.py:628: The SMB_SHARE env var was not set, integration tests will be skipped/home/maxim/Repo/smbprotocol/tests/test_smbclient_os.py:628: The SMB_SHARE env var was not set, integration tests will be skipped/home/maxim/Repo/smbprotocol/tests/test_smbclient_os.py:649: The SMB_SHARE env var was not set, integration tests will be skipped/home/maxim/Repo/smbprotocol/tests/test_smbclient_os.py:649: The SMB_SHARE env var was not set, integration tests will be skipped/home/maxim/Repo/smbprotocol/tests/test_smbclient_os.py:670: The SMB_SHARE env var was not set, integration tests will be skipped/home/maxim/Repo/smbprotocol/tests/test_smbclient_os.py:670: The SMB_SHARE env var was not set, integration tests will be skipped/home/maxim/Repo/smbprotocol/tests/test_smbclient_os.py:681: The SMB_SHARE env var was not set, integration tests will be skipped/home/maxim/Repo/smbprotocol/tests/test_smbclient_os.py:681: The SMB_SHARE env var was not set, integration tests will be skipped/home/maxim/Repo/smbprotocol/tests/test_smbclient_os.py:692: The SMB_SHARE env var was not set, integration tests will be skipped/home/maxim/Repo/smbprotocol/tests/test_smbclient_os.py:692: The SMB_SHARE env var was not set, integration tests will be skipped/home/maxim/Repo/smbprotocol/tests/test_smbclient_os.py:700: The SMB_SHARE env var was not set, integration tests will be skipped/home/maxim/Repo/smbprotocol/tests/test_smbclient_os.py:700: The SMB_SHARE env var was not set, integration tests will be skipped/home/maxim/Repo/smbprotocol/tests/test_smbclient_os.py:711: The SMB_SHARE env var was not set, integration tests will be skipped/home/maxim/Repo/smbprotocol/tests/test_smbclient_os.py:711: The SMB_SHARE env var was not set, integration tests will be skipped/home/maxim/Repo/smbprotocol/tests/test_smbclient_os.py:718: The SMB_SHARE env var was not set, integration tests will be skipped/home/maxim/Repo/smbprotocol/tests/test_smbclient_os.py:718: The SMB_SHARE env var was not set, integration tests will be skipped/home/maxim/Repo/smbprotocol/tests/test_smbclient_os.py:740: The SMB_SHARE env var was not set, integration tests will be skipped/home/maxim/Repo/smbprotocol/tests/test_smbclient_os.py:740: The SMB_SHARE env var was not set, integration tests will be skipped/home/maxim/Repo/smbprotocol/tests/test_smbclient_os.py:764: The SMB_SHARE env var was not set, integration tests will be skipped/home/maxim/Repo/smbprotocol/tests/test_smbclient_os.py:764: The SMB_SHARE env var was not set, integration tests will be skipped/home/maxim/Repo/smbprotocol/tests/test_smbclient_os.py:778: The SMB_SHARE env var was not set, integration tests will be skipped/home/maxim/Repo/smbprotocol/tests/test_smbclient_os.py:778: The SMB_SHARE env var was not set, integration tests will be skipped/home/maxim/Repo/smbprotocol/tests/test_smbclient_os.py:783: The SMB_SHARE env var was not set, integration tests will be skipped/home/maxim/Repo/smbprotocol/tests/test_smbclient_os.py:783: The SMB_SHARE env var was not set, integration tests will be skipped/home/maxim/Repo/smbprotocol/tests/test_smbclient_os.py:788: The SMB_SHARE env var was not set, integration tests will be skipped/home/maxim/Repo/smbprotocol/tests/test_smbclient_os.py:788: The SMB_SHARE env var was not set, integration tests will be skipped/home/maxim/Repo/smbprotocol/tests/test_smbclient_os.py:793: The SMB_SHARE env var was not set, integration tests will be skipped/home/maxim/Repo/smbprotocol/tests/test_smbclient_os.py:793: The SMB_SHARE env var was not set, integration tests will be skipped/home/maxim/Repo/smbprotocol/tests/test_smbclient_os.py:802: The SMB_SHARE env var was not set, integration tests will be skipped/home/maxim/Repo/smbprotocol/tests/test_smbclient_os.py:802: The SMB_SHARE env var was not set, integration tests will be skipped/home/maxim/Repo/smbprotocol/tests/test_smbclient_os.py:815: The SMB_SHARE env var was not set, integration tests will be skipped/home/maxim/Repo/smbprotocol/tests/test_smbclient_os.py:815: The SMB_SHARE env var was not set, integration tests will be skipped/home/maxim/Repo/smbprotocol/tests/test_smbclient_os.py:821: The SMB_SHARE env var was not set, integration tests will be skipped/home/maxim/Repo/smbprotocol/tests/test_smbclient_os.py:821: The SMB_SHARE env var was not set, integration tests will be skipped/home/maxim/Repo/smbprotocol/tests/test_smbclient_os.py:844: cannot create symlinks on Samba/home/maxim/Repo/smbprotocol/tests/test_smbclient_os.py:844: cannot create symlinks on Samba/home/maxim/Repo/smbprotocol/tests/test_smbclient_os.py:860: cannot create symlinks on Samba/home/maxim/Repo/smbprotocol/tests/test_smbclient_os.py:860: cannot create symlinks on Samba/home/maxim/Repo/smbprotocol/tests/test_smbclient_os.py:876: cannot create symlinks on Samba/home/maxim/Repo/smbprotocol/tests/test_smbclient_os.py:876: cannot create symlinks on Samba/home/maxim/Repo/smbprotocol/tests/test_smbclient_os.py:889: cannot create symlinks on Samba/home/maxim/Repo/smbprotocol/tests/test_smbclient_os.py:889: cannot create symlinks on Samba/home/maxim/Repo/smbprotocol/tests/test_smbclient_os.py:902: cannot create symlinks on Samba/home/maxim/Repo/smbprotocol/tests/test_smbclient_os.py:902: cannot create symlinks on Samba/home/maxim/Repo/smbprotocol/tests/test_smbclient_os.py:916: The SMB_SHARE env var was not set, integration tests will be skipped/home/maxim/Repo/smbprotocol/tests/test_smbclient_os.py:916: The SMB_SHARE env var was not set, integration tests will be skipped/home/maxim/Repo/smbprotocol/tests/test_smbclient_os.py:940: The SMB_SHARE env var was not set, integration tests will be skipped/home/maxim/Repo/smbprotocol/tests/test_smbclient_os.py:940: The SMB_SHARE env var was not set, integration tests will be skipped/home/maxim/Repo/smbprotocol/tests/test_smbclient_os.py:951: The SMB_SHARE env var was not set, integration tests will be skipped/home/maxim/Repo/smbprotocol/tests/test_smbclient_os.py:951: The SMB_SHARE env var was not set, integration tests will be skipped/home/maxim/Repo/smbprotocol/tests/test_smbclient_os.py:966: The SMB_SHARE env var was not set, integration tests will be skipped/home/maxim/Repo/smbprotocol/tests/test_smbclient_os.py:966: The SMB_SHARE env var was not set, integration tests will be skipped/home/maxim/Repo/smbprotocol/tests/test_smbclient_os.py:978: cannot create symlinks on Samba/home/maxim/Repo/smbprotocol/tests/test_smbclient_os.py:978: cannot create symlinks on Samba/home/maxim/Repo/smbprotocol/tests/test_smbclient_os.py:991: cannot create symlinks on Samba/home/maxim/Repo/smbprotocol/tests/test_smbclient_os.py:991: cannot create symlinks on Samba/home/maxim/Repo/smbprotocol/tests/test_smbclient_os.py:1007: The SMB_SHARE env var was not set, integration tests will be skipped/home/maxim/Repo/smbprotocol/tests/test_smbclient_os.py:1007: The SMB_SHARE env var was not set, integration tests will be skipped/home/maxim/Repo/smbprotocol/tests/test_smbclient_os.py:1023: The SMB_SHARE env var was not set, integration tests will be skipped/home/maxim/Repo/smbprotocol/tests/test_smbclient_os.py:1023: The SMB_SHARE env var was not set, integration tests will be skipped/home/maxim/Repo/smbprotocol/tests/test_smbclient_os.py:1034: The SMB_SHARE env var was not set, integration tests will be skipped/home/maxim/Repo/smbprotocol/tests/test_smbclient_os.py:1034: The SMB_SHARE env var was not set, integration tests will be skipped/home/maxim/Repo/smbprotocol/tests/test_smbclient_os.py:1044: The SMB_SHARE env var was not set, integration tests will be skipped/home/maxim/Repo/smbprotocol/tests/test_smbclient_os.py:1044: The SMB_SHARE env var was not set, integration tests will be skipped/home/maxim/Repo/smbprotocol/tests/test_smbclient_os.py:1050: The SMB_SHARE env var was not set, integration tests will be skipped/home/maxim/Repo/smbprotocol/tests/test_smbclient_os.py:1050: The SMB_SHARE env var was not set, integration tests will be skipped/home/maxim/Repo/smbprotocol/tests/test_smbclient_os.py:1058: The SMB_SHARE env var was not set, integration tests will be skipped/home/maxim/Repo/smbprotocol/tests/test_smbclient_os.py:1058: The SMB_SHARE env var was not set, integration tests will be skipped/home/maxim/Repo/smbprotocol/tests/test_smbclient_os.py:1074: The SMB_SHARE env var was not set, integration tests will be skipped/home/maxim/Repo/smbprotocol/tests/test_smbclient_os.py:1074: The SMB_SHARE env var was not set, integration tests will be skipped/home/maxim/Repo/smbprotocol/tests/test_smbclient_os.py:1099: The SMB_SHARE env var was not set, integration tests will be skipped/home/maxim/Repo/smbprotocol/tests/test_smbclient_os.py:1099: The SMB_SHARE env var was not set, integration tests will be skipped/home/maxim/Repo/smbprotocol/tests/test_smbclient_os.py:1122: The SMB_SHARE env var was not set, integration tests will be skipped/home/maxim/Repo/smbprotocol/tests/test_smbclient_os.py:1122: The SMB_SHARE env var was not set, integration tests will be skipped/home/maxim/Repo/smbprotocol/tests/test_smbclient_os.py:1135: The SMB_SHARE env var was not set, integration tests will be skipped/home/maxim/Repo/smbprotocol/tests/test_smbclient_os.py:1135: The SMB_SHARE env var was not set, integration tests will be skipped/home/maxim/Repo/smbprotocol/tests/test_smbclient_os.py:1148: The SMB_SHARE env var was not set, integration tests will be skipped/home/maxim/Repo/smbprotocol/tests/test_smbclient_os.py:1148: The SMB_SHARE env var was not set, integration tests will be skipped/home/maxim/Repo/smbprotocol/tests/test_smbclient_os.py:1161: The SMB_SHARE env var was not set, integration tests will be skipped/home/maxim/Repo/smbprotocol/tests/test_smbclient_os.py:1161: The SMB_SHARE env var was not set, integration tests will be skipped/home/maxim/Repo/smbprotocol/tests/test_smbclient_os.py:1171: cannot create symlinks on Samba/home/maxim/Repo/smbprotocol/tests/test_smbclient_os.py:1171: cannot create symlinks on Samba/home/maxim/Repo/smbprotocol/tests/test_smbclient_os.py:1184: cannot create symlinks on Samba/home/maxim/Repo/smbprotocol/tests/test_smbclient_os.py:1184: cannot create symlinks on Samba/home/maxim/Repo/smbprotocol/tests/test_smbclient_os.py:1198: The SMB_SHARE env var was not set, integration tests will be skipped/home/maxim/Repo/smbprotocol/tests/test_smbclient_os.py:1198: The SMB_SHARE env var was not set, integration tests will be skipped/home/maxim/Repo/smbprotocol/tests/test_smbclient_os.py:1218: The SMB_SHARE env var was not set, integration tests will be skipped/home/maxim/Repo/smbprotocol/tests/test_smbclient_os.py:1218: The SMB_SHARE env var was not set, integration tests will be skipped/home/maxim/Repo/smbprotocol/tests/test_smbclient_os.py:1263: The SMB_SHARE env var was not set, integration tests will be skipped/home/maxim/Repo/smbprotocol/tests/test_smbclient_os.py:1263: The SMB_SHARE env var was not set, integration tests will be skipped/home/maxim/Repo/smbprotocol/tests/test_smbclient_os.py:1285: cannot create symlinks on Samba/home/maxim/Repo/smbprotocol/tests/test_smbclient_os.py:1285: cannot create symlinks on Samba/home/maxim/Repo/smbprotocol/tests/test_smbclient_os.py:1313: cannot create symlinks on Samba/home/maxim/Repo/smbprotocol/tests/test_smbclient_os.py:1313: cannot create symlinks on Samba/home/maxim/Repo/smbprotocol/tests/test_smbclient_os.py:1328: The SMB_SHARE env var was not set, integration tests will be skipped/home/maxim/Repo/smbprotocol/tests/test_smbclient_os.py:1382: The SMB_SHARE env var was not set, integration tests will be skipped/home/maxim/Repo/smbprotocol/tests/test_smbclient_os.py:1382: The SMB_SHARE env var was not set, integration tests will be skipped/home/maxim/Repo/smbprotocol/tests/test_smbclient_os.py:1422: The SMB_SHARE env var was not set, integration tests will be skipped/home/maxim/Repo/smbprotocol/tests/test_smbclient_os.py:1422: The SMB_SHARE env var was not set, integration tests will be skipped/home/maxim/Repo/smbprotocol/tests/test_smbclient_os.py:1466: The SMB_SHARE env var was not set, integration tests will be skipped/home/maxim/Repo/smbprotocol/tests/test_smbclient_os.py:1466: The SMB_SHARE env var was not set, integration tests will be skipped/home/maxim/Repo/smbprotocol/tests/test_smbclient_os.py:1476: cannot create symlinks on Samba/home/maxim/Repo/smbprotocol/tests/test_smbclient_os.py:1476: cannot create symlinks on Samba/home/maxim/Repo/smbprotocol/tests/test_smbclient_os.py:1493: cannot create symlinks on Samba/home/maxim/Repo/smbprotocol/tests/test_smbclient_os.py:1493: cannot create symlinks on Samba/home/maxim/Repo/smbprotocol/tests/test_smbclient_os.py:1507: cannot create symlinks on Samba/home/maxim/Repo/smbprotocol/tests/test_smbclient_os.py:1507: cannot create symlinks on Samba/home/maxim/Repo/smbprotocol/tests/test_smbclient_os.py:1525: The SMB_SHARE env var was not set, integration tests will be skipped/home/maxim/Repo/smbprotocol/tests/test_smbclient_os.py:1525: The SMB_SHARE env var was not set, integration tests will be skipped/home/maxim/Repo/smbprotocol/tests/test_smbclient_os.py:1534: cannot create symlinks on Samba/home/maxim/Repo/smbprotocol/tests/test_smbclient_os.py:1534: cannot create symlinks on Samba/home/maxim/Repo/smbprotocol/tests/test_smbclient_os.py:1551: cannot create symlinks on Samba/home/maxim/Repo/smbprotocol/tests/test_smbclient_os.py:1551: cannot create symlinks on Samba/home/maxim/Repo/smbprotocol/tests/test_smbclient_os.py:1574: cannot create symlinks on Samba/home/maxim/Repo/smbprotocol/tests/test_smbclient_os.py:1574: cannot create symlinks on Samba/home/maxim/Repo/smbprotocol/tests/test_smbclient_os.py:1591: cannot create symlinks on Samba/home/maxim/Repo/smbprotocol/tests/test_smbclient_os.py:1591: cannot create symlinks on Samba/home/maxim/Repo/smbprotocol/tests/test_smbclient_os.py:1612: cannot create symlinks on Samba/home/maxim/Repo/smbprotocol/tests/test_smbclient_os.py:1612: cannot create symlinks on Samba/home/maxim/Repo/smbprotocol/tests/test_smbclient_os.py:1637: The SMB_SHARE env var was not set, integration tests will be skipped/home/maxim/Repo/smbprotocol/tests/test_smbclient_os.py:1637: The SMB_SHARE env var was not set, integration tests will be skipped/home/maxim/Repo/smbprotocol/tests/test_smbclient_os.py:1643: The SMB_SHARE env var was not set, integration tests will be skipped/home/maxim/Repo/smbprotocol/tests/test_smbclient_os.py:1643: The SMB_SHARE env var was not set, integration tests will be skipped/home/maxim/Repo/smbprotocol/tests/test_smbclient_os.py:1649: The SMB_SHARE env var was not set, integration tests will be skipped/home/maxim/Repo/smbprotocol/tests/test_smbclient_os.py:1649: The SMB_SHARE env var was not set, integration tests will be skipped/home/maxim/Repo/smbprotocol/tests/test_smbclient_os.py:1665: The SMB_SHARE env var was not set, integration tests will be skipped/home/maxim/Repo/smbprotocol/tests/test_smbclient_os.py:1665: The SMB_SHARE env var was not set, integration tests will be skipped/home/maxim/Repo/smbprotocol/tests/test_smbclient_os.py:1676: Samba does not update timestamps/home/maxim/Repo/smbprotocol/tests/test_smbclient_os.py:1676: Samba does not update timestamps/home/maxim/Repo/smbprotocol/tests/test_smbclient_os.py:1697: Samba does not update timestamps/home/maxim/Repo/smbprotocol/tests/test_smbclient_os.py:1697: Samba does not update timestamps/home/maxim/Repo/smbprotocol/tests/test_smbclient_os.py:1718: Samba does not update timestamps/home/maxim/Repo/smbprotocol/tests/test_smbclient_os.py:1718: Samba does not update timestamps/home/maxim/Repo/smbprotocol/tests/test_smbclient_os.py:1738: Samba does not update timestamps/home/maxim/Repo/smbprotocol/tests/test_smbclient_os.py:1738: Samba does not update timestamps/home/maxim/Repo/smbprotocol/tests/test_smbclient_os.py:1770: Samba does not update timestamps/home/maxim/Repo/smbprotocol/tests/test_smbclient_os.py:1770: Samba does not update timestamps/home/maxim/Repo/smbprotocol/tests/test_smbclient_os.py:1793: cannot create symlinks on Samba/home/maxim/Repo/smbprotocol/tests/test_smbclient_os.py:1793: cannot create symlinks on Samba/home/maxim/Repo/smbprotocol/tests/test_smbclient_os.py:1816: cannot create symlinks on Samba/home/maxim/Repo/smbprotocol/tests/test_smbclient_os.py:1816: cannot create symlinks on Samba/home/maxim/Repo/smbprotocol/tests/test_smbclient_os.py:1839: The SMB_SHARE env var was not set, integration tests will be skipped/home/maxim/Repo/smbprotocol/tests/test_smbclient_os.py:1839: The SMB_SHARE env var was not set, integration tests will be skipped/home/maxim/Repo/smbprotocol/tests/test_smbclient_os.py:1860: The SMB_SHARE env var was not set, integration tests will be skipped/home/maxim/Repo/smbprotocol/tests/test_smbclient_os.py:1860: The SMB_SHARE env var was not set, integration tests will be skipped/home/maxim/Repo/smbprotocol/tests/test_smbclient_os.py:1878: The SMB_SHARE env var was not set, integration tests will be skipped/home/maxim/Repo/smbprotocol/tests/test_smbclient_os.py:1878: The SMB_SHARE env var was not set, integration tests will be skipped/home/maxim/Repo/smbprotocol/tests/test_smbclient_os.py:1886: The SMB_SHARE env var was not set, integration tests will be skipped/home/maxim/Repo/smbprotocol/tests/test_smbclient_os.py:1886: The SMB_SHARE env var was not set, integration tests will be skipped/home/maxim/Repo/smbprotocol/tests/test_smbclient_os.py:1898: cannot create symlinks on Samba/home/maxim/Repo/smbprotocol/tests/test_smbclient_os.py:1898: cannot create symlinks on Samba/home/maxim/Repo/smbprotocol/tests/test_smbclient_os.py:1926: cannot create symlinks on Samba/home/maxim/Repo/smbprotocol/tests/test_smbclient_os.py:1926: cannot create symlinks on Samba/home/maxim/Repo/smbprotocol/tests/test_smbclient_os.py:1951: The SMB_SHARE env var was not set, integration tests will be skipped/home/maxim/Repo/smbprotocol/tests/test_smbclient_os.py:1951: The SMB_SHARE env var was not set, integration tests will be skipped/home/maxim/Repo/smbprotocol/tests/test_smbclient_os.py:1988: The SMB_SHARE env var was not set, integration tests will be skipped/home/maxim/Repo/smbprotocol/tests/test_smbclient_os.py:1988: The SMB_SHARE env var was not set, integration tests will be skipped/home/maxim/Repo/smbprotocol/tests/test_smbclient_os.py:1996: cannot create symlinks on Samba/home/maxim/Repo/smbprotocol/tests/test_smbclient_os.py:1996: cannot create symlinks on Samba/home/maxim/Repo/smbprotocol/tests/test_smbclient_os.py:2018: cannot create symlinks on Samba/home/maxim/Repo/smbprotocol/tests/test_smbclient_os.py:2018: cannot create symlinks on Samba/home/maxim/Repo/smbprotocol/tests/test_smbclient_os.py:2040: The SMB_SHARE env var was not set, integration tests will be skipped/home/maxim/Repo/smbprotocol/tests/test_smbclient_os.py:2040: The SMB_SHARE env var was not set, integration tests will be skipped/home/maxim/Repo/smbprotocol/tests/test_smbclient_os.py:2061: The SMB_SHARE env var was not set, integration tests will be skipped/home/maxim/Repo/smbprotocol/tests/test_smbclient_os.py:2061: The SMB_SHARE env var was not set, integration tests will be skipped/home/maxim/Repo/smbprotocol/tests/test_smbclient_os.py:2061: The SMB_SHARE env var was not set, integration tests will be skipped/home/maxim/Repo/smbprotocol/tests/test_smbclient_os.py:2084: The SMB_SHARE env var was not set, integration tests will be skipped/home/maxim/Repo/smbprotocol/tests/test_smbclient_os.py:2084: The SMB_SHARE env var was not set, integration tests will be skipped/home/maxim/Repo/smbprotocol/tests/test_smbclient_os.py:2084: The SMB_SHARE env var was not set, integration tests will be skipped/home/maxim/Repo/smbprotocol/tests/test_smbclient_os.py:2102: The SMB_SHARE env var was not set, integration tests will be skipped/home/maxim/Repo/smbprotocol/tests/test_smbclient_os.py:2102: The SMB_SHARE env var was not set, integration tests will be skipped/home/maxim/Repo/smbprotocol/tests/test_smbclient_os.py:2102: The SMB_SHARE env var was not set, integration tests will be skipped/home/maxim/Repo/smbprotocol/tests/test_smbclient_os.py:2126: The SMB_SHARE env var was not set, integration tests will be skipped/home/maxim/Repo/smbprotocol/tests/test_smbclient_path.py:26: The SMB_SHARE env var was not set, integration tests will be skipped/home/maxim/Repo/smbprotocol/tests/test_smbclient_path.py:26: The SMB_SHARE env var was not set, integration tests will be skipped/home/maxim/Repo/smbprotocol/tests/test_smbclient_path.py:37: The SMB_SHARE env var was not set, integration tests will be skipped/home/maxim/Repo/smbprotocol/tests/test_smbclient_path.py:37: The SMB_SHARE env var was not set, integration tests will be skipped/home/maxim/Repo/smbprotocol/tests/test_smbclient_path.py:42: cannot create symlinks on Samba/home/maxim/Repo/smbprotocol/tests/test_smbclient_path.py:42: cannot create symlinks on Samba/home/maxim/Repo/smbprotocol/tests/test_smbclient_path.py:54: cannot create symlinks on Samba/home/maxim/Repo/smbprotocol/tests/test_smbclient_path.py:54: cannot create symlinks on Samba/home/maxim/Repo/smbprotocol/tests/test_smbclient_path.py:69: The SMB_SHARE env var was not set, integration tests will be skipped/home/maxim/Repo/smbprotocol/tests/test_smbclient_path.py:69: The SMB_SHARE env var was not set, integration tests will be skipped/home/maxim/Repo/smbprotocol/tests/test_smbclient_path.py:80: The SMB_SHARE env var was not set, integration tests will be skipped/home/maxim/Repo/smbprotocol/tests/test_smbclient_path.py:80: The SMB_SHARE env var was not set, integration tests will be skipped/home/maxim/Repo/smbprotocol/tests/test_smbclient_path.py:85: cannot create symlinks on Samba/home/maxim/Repo/smbprotocol/tests/test_smbclient_path.py:85: cannot create symlinks on Samba/home/maxim/Repo/smbprotocol/tests/test_smbclient_path.py:97: cannot create symlinks on Samba/home/maxim/Repo/smbprotocol/tests/test_smbclient_path.py:97: cannot create symlinks on Samba/home/maxim/Repo/smbprotocol/tests/test_smbclient_path.py:112: The SMB_SHARE env var was not set, integration tests will be skipped/home/maxim/Repo/smbprotocol/tests/test_smbclient_path.py:112: The SMB_SHARE env var was not set, integration tests will be skipped/home/maxim/Repo/smbprotocol/tests/test_smbclient_path.py:122: The SMB_SHARE env var was not set, integration tests will be skipped/home/maxim/Repo/smbprotocol/tests/test_smbclient_path.py:122: The SMB_SHARE env var was not set, integration tests will be skipped/home/maxim/Repo/smbprotocol/tests/test_smbclient_path.py:132: The SMB_SHARE env var was not set, integration tests will be skipped/home/maxim/Repo/smbprotocol/tests/test_smbclient_path.py:132: The SMB_SHARE env var was not set, integration tests will be skipped/home/maxim/Repo/smbprotocol/tests/test_smbclient_path.py:142: The SMB_SHARE env var was not set, integration tests will be skipped/home/maxim/Repo/smbprotocol/tests/test_smbclient_path.py:142: The SMB_SHARE env var was not set, integration tests will be skipped/home/maxim/Repo/smbprotocol/tests/test_smbclient_path.py:151: The SMB_SHARE env var was not set, integration tests will be skipped/home/maxim/Repo/smbprotocol/tests/test_smbclient_path.py:151: The SMB_SHARE env var was not set, integration tests will be skipped/home/maxim/Repo/smbprotocol/tests/test_smbclient_path.py:155: The SMB_SHARE env var was not set, integration tests will be skipped/home/maxim/Repo/smbprotocol/tests/test_smbclient_path.py:155: The SMB_SHARE env var was not set, integration tests will be skipped/home/maxim/Repo/smbprotocol/tests/test_smbclient_path.py:159: The SMB_SHARE env var was not set, integration tests will be skipped/home/maxim/Repo/smbprotocol/tests/test_smbclient_path.py:159: The SMB_SHARE env var was not set, integration tests will be skipped/home/maxim/Repo/smbprotocol/tests/test_smbclient_path.py:166: The SMB_SHARE env var was not set, integration tests will be skipped/home/maxim/Repo/smbprotocol/tests/test_smbclient_path.py:166: The SMB_SHARE env var was not set, integration tests will be skipped/home/maxim/Repo/smbprotocol/tests/test_smbclient_path.py:172: cannot create symlinks on Samba/home/maxim/Repo/smbprotocol/tests/test_smbclient_path.py:172: cannot create symlinks on Samba/home/maxim/Repo/smbprotocol/tests/test_smbclient_path.py:186: cannot create symlinks on Samba/home/maxim/Repo/smbprotocol/tests/test_smbclient_path.py:186: cannot create symlinks on Samba/home/maxim/Repo/smbprotocol/tests/test_smbclient_path.py:198: The SMB_SHARE env var was not set, integration tests will be skipped/home/maxim/Repo/smbprotocol/tests/test_smbclient_path.py:198: The SMB_SHARE env var was not set, integration tests will be skipped/home/maxim/Repo/smbprotocol/tests/test_smbclient_path.py:202: The SMB_SHARE env var was not set, integration tests will be skipped/home/maxim/Repo/smbprotocol/tests/test_smbclient_path.py:202: The SMB_SHARE env var was not set, integration tests will be skipped/home/maxim/Repo/smbprotocol/tests/test_smbclient_path.py:206: The SMB_SHARE env var was not set, integration tests will be skipped/home/maxim/Repo/smbprotocol/tests/test_smbclient_path.py:206: The SMB_SHARE env var was not set, integration tests will be skipped/home/maxim/Repo/smbprotocol/tests/test_smbclient_path.py:213: The SMB_SHARE env var was not set, integration tests will be skipped/home/maxim/Repo/smbprotocol/tests/test_smbclient_path.py:213: The SMB_SHARE env var was not set, integration tests will be skipped/home/maxim/Repo/smbprotocol/tests/test_smbclient_path.py:219: cannot create symlinks on Samba/home/maxim/Repo/smbprotocol/tests/test_smbclient_path.py:219: cannot create symlinks on Samba/home/maxim/Repo/smbprotocol/tests/test_smbclient_path.py:232: cannot create symlinks on Samba/home/maxim/Repo/smbprotocol/tests/test_smbclient_path.py:232: cannot create symlinks on Samba/home/maxim/Repo/smbprotocol/tests/test_smbclient_path.py:244: The SMB_SHARE env var was not set, integration tests will be skipped/home/maxim/Repo/smbprotocol/tests/test_smbclient_path.py:244: The SMB_SHARE env var was not set, integration tests will be skipped/home/maxim/Repo/smbprotocol/tests/test_smbclient_path.py:248: The SMB_SHARE env var was not set, integration tests will be skipped/home/maxim/Repo/smbprotocol/tests/test_smbclient_path.py:248: The SMB_SHARE env var was not set, integration tests will be skipped/home/maxim/Repo/smbprotocol/tests/test_smbclient_path.py:252: The SMB_SHARE env var was not set, integration tests will be skipped/home/maxim/Repo/smbprotocol/tests/test_smbclient_path.py:252: The SMB_SHARE env var was not set, integration tests will be skipped/home/maxim/Repo/smbprotocol/tests/test_smbclient_path.py:259: The SMB_SHARE env var was not set, integration tests will be skipped/home/maxim/Repo/smbprotocol/tests/test_smbclient_path.py:259: The SMB_SHARE env var was not set, integration tests will be skipped/home/maxim/Repo/smbprotocol/tests/test_smbclient_path.py:265: cannot create symlinks on Samba/home/maxim/Repo/smbprotocol/tests/test_smbclient_path.py:265: cannot create symlinks on Samba/home/maxim/Repo/smbprotocol/tests/test_smbclient_path.py:279: cannot create symlinks on Samba/home/maxim/Repo/smbprotocol/tests/test_smbclient_path.py:279: cannot create symlinks on Samba/home/maxim/Repo/smbprotocol/tests/test_smbclient_path.py:291: cannot create symlinks on Samba/home/maxim/Repo/smbprotocol/tests/test_smbclient_path.py:291: cannot create symlinks on Samba/home/maxim/Repo/smbprotocol/tests/test_smbclient_path.py:304: cannot create symlinks on Samba/home/maxim/Repo/smbprotocol/tests/test_smbclient_path.py:304: cannot create symlinks on Samba/home/maxim/Repo/smbprotocol/tests/test_smbclient_path.py:316: The SMB_SHARE env var was not set, integration tests will be skipped/home/maxim/Repo/smbprotocol/tests/test_smbclient_path.py:316: The SMB_SHARE env var was not set, integration tests will be skipped/home/maxim/Repo/smbprotocol/tests/test_smbclient_path.py:329: The SMB_SHARE env var was not set, integration tests will be skipped/home/maxim/Repo/smbprotocol/tests/test_smbclient_path.py:329: The SMB_SHARE env var was not set, integration tests will be skipped/home/maxim/Repo/smbprotocol/tests/test_smbclient_path.py:341: The SMB_SHARE env var was not set, integration tests will be skipped/home/maxim/Repo/smbprotocol/tests/test_smbclient_path.py:341: The SMB_SHARE env var was not set, integration tests will be skipped/home/maxim/Repo/smbprotocol/tests/test_smbclient_path.py:353: The SMB_SHARE env var was not set, integration tests will be skipped/home/maxim/Repo/smbprotocol/tests/test_smbclient_path.py:353: The SMB_SHARE env var was not set, integration tests will be skipped/home/maxim/Repo/smbprotocol/tests/test_smbclient_path.py:365: cannot create symlinks on Samba/home/maxim/Repo/smbprotocol/tests/test_smbclient_path.py:365: cannot create symlinks on Samba/home/maxim/Repo/smbprotocol/tests/test_smbclient_path.py:380: cannot create symlinks on Samba/home/maxim/Repo/smbprotocol/tests/test_smbclient_path.py:380: cannot create symlinks on Samba/home/maxim/Repo/smbprotocol/tests/test_smbclient_shutil.py:79: The SMB_SHARE env var was not set, integration tests will be skipped/home/maxim/Repo/smbprotocol/tests/test_smbclient_shutil.py:79: The SMB_SHARE env var was not set, integration tests will be skipped/home/maxim/Repo/smbprotocol/tests/test_smbclient_shutil.py:89: The SMB_SHARE env var was not set, integration tests will be skipped/home/maxim/Repo/smbprotocol/tests/test_smbclient_shutil.py:89: The SMB_SHARE env var was not set, integration tests will be skipped/home/maxim/Repo/smbprotocol/tests/test_smbclient_shutil.py:117: The SMB_SHARE env var was not set, integration tests will be skipped/home/maxim/Repo/smbprotocol/tests/test_smbclient_shutil.py:117: The SMB_SHARE env var was not set, integration tests will be skipped/home/maxim/Repo/smbprotocol/tests/test_smbclient_shutil.py:141: The SMB_SHARE env var was not set, integration tests will be skipped/home/maxim/Repo/smbprotocol/tests/test_smbclient_shutil.py:141: The SMB_SHARE env var was not set, integration tests will be skipped/home/maxim/Repo/smbprotocol/tests/test_smbclient_shutil.py:162: Samba does not update timestamps/home/maxim/Repo/smbprotocol/tests/test_smbclient_shutil.py:162: Samba does not update timestamps/home/maxim/Repo/smbprotocol/tests/test_smbclient_shutil.py:189: Samba does not update timestamps/home/maxim/Repo/smbprotocol/tests/test_smbclient_shutil.py:189: Samba does not update timestamps/home/maxim/Repo/smbprotocol/tests/test_smbclient_shutil.py:217: The SMB_SHARE env var was not set, integration tests will be skipped/home/maxim/Repo/smbprotocol/tests/test_smbclient_shutil.py:217: The SMB_SHARE env var was not set, integration tests will be skipped/home/maxim/Repo/smbprotocol/tests/test_smbclient_shutil.py:238: The SMB_SHARE env var was not set, integration tests will be skipped/home/maxim/Repo/smbprotocol/tests/test_smbclient_shutil.py:238: The SMB_SHARE env var was not set, integration tests will be skipped/home/maxim/Repo/smbprotocol/tests/test_smbclient_shutil.py:248: The SMB_SHARE env var was not set, integration tests will be skipped/home/maxim/Repo/smbprotocol/tests/test_smbclient_shutil.py:248: The SMB_SHARE env var was not set, integration tests will be skipped/home/maxim/Repo/smbprotocol/tests/test_smbclient_shutil.py:262: The SMB_SHARE env var was not set, integration tests will be skipped/home/maxim/Repo/smbprotocol/tests/test_smbclient_shutil.py:262: The SMB_SHARE env var was not set, integration tests will be skipped/home/maxim/Repo/smbprotocol/tests/test_smbclient_shutil.py:279: The SMB_SHARE env var was not set, integration tests will be skipped/home/maxim/Repo/smbprotocol/tests/test_smbclient_shutil.py:279: The SMB_SHARE env var was not set, integration tests will be skipped/home/maxim/Repo/smbprotocol/tests/test_smbclient_shutil.py:294: The SMB_SHARE env var was not set, integration tests will be skipped/home/maxim/Repo/smbprotocol/tests/test_smbclient_shutil.py:294: The SMB_SHARE env var was not set, integration tests will be skipped/home/maxim/Repo/smbprotocol/tests/test_smbclient_shutil.py:324: The SMB_SHARE env var was not set, integration tests will be skipped/home/maxim/Repo/smbprotocol/tests/test_smbclient_shutil.py:324: The SMB_SHARE env var was not set, integration tests will be skipped/home/maxim/Repo/smbprotocol/tests/test_smbclient_shutil.py:335: The SMB_SHARE env var was not set, integration tests will be skipped/home/maxim/Repo/smbprotocol/tests/test_smbclient_shutil.py:335: The SMB_SHARE env var was not set, integration tests will be skipped/home/maxim/Repo/smbprotocol/tests/test_smbclient_shutil.py:349: cannot create symlinks on Samba/home/maxim/Repo/smbprotocol/tests/test_smbclient_shutil.py:349: cannot create symlinks on Samba/home/maxim/Repo/smbprotocol/tests/test_smbclient_shutil.py:370: cannot create symlinks on Samba/home/maxim/Repo/smbprotocol/tests/test_smbclient_shutil.py:370: cannot create symlinks on Samba/home/maxim/Repo/smbprotocol/tests/test_smbclient_shutil.py:392: cannot create symlinks on Samba/home/maxim/Repo/smbprotocol/tests/test_smbclient_shutil.py:392: cannot create symlinks on Samba/home/maxim/Repo/smbprotocol/tests/test_smbclient_shutil.py:405: The SMB_SHARE env var was not set, integration tests will be skipped/home/maxim/Repo/smbprotocol/tests/test_smbclient_shutil.py:405: The SMB_SHARE env var was not set, integration tests will be skipped/home/maxim/Repo/smbprotocol/tests/test_smbclient_shutil.py:431: The SMB_SHARE env var was not set, integration tests will be skipped/home/maxim/Repo/smbprotocol/tests/test_smbclient_shutil.py:431: The SMB_SHARE env var was not set, integration tests will be skipped/home/maxim/Repo/smbprotocol/tests/test_smbclient_shutil.py:460: The SMB_SHARE env var was not set, integration tests will be skipped/home/maxim/Repo/smbprotocol/tests/test_smbclient_shutil.py:460: The SMB_SHARE env var was not set, integration tests will be skipped/home/maxim/Repo/smbprotocol/tests/test_smbclient_shutil.py:484: The SMB_SHARE env var was not set, integration tests will be skipped/home/maxim/Repo/smbprotocol/tests/test_smbclient_shutil.py:484: The SMB_SHARE env var was not set, integration tests will be skipped/home/maxim/Repo/smbprotocol/tests/test_smbclient_shutil.py:512: The SMB_SHARE env var was not set, integration tests will be skipped/home/maxim/Repo/smbprotocol/tests/test_smbclient_shutil.py:512: The SMB_SHARE env var was not set, integration tests will be skipped/home/maxim/Repo/smbprotocol/tests/test_smbclient_shutil.py:631: The SMB_SHARE env var was not set, integration tests will be skipped/home/maxim/Repo/smbprotocol/tests/test_smbclient_shutil.py:631: The SMB_SHARE env var was not set, integration tests will be skipped/home/maxim/Repo/smbprotocol/tests/test_smbclient_shutil.py:636: The SMB_SHARE env var was not set, integration tests will be skipped/home/maxim/Repo/smbprotocol/tests/test_smbclient_shutil.py:636: The SMB_SHARE env var was not set, integration tests will be skipped/home/maxim/Repo/smbprotocol/tests/test_smbclient_shutil.py:641: cannot create symlinks on Samba/home/maxim/Repo/smbprotocol/tests/test_smbclient_shutil.py:641: cannot create symlinks on Samba/home/maxim/Repo/smbprotocol/tests/test_smbclient_shutil.py:681: cannot create symlinks on Samba/home/maxim/Repo/smbprotocol/tests/test_smbclient_shutil.py:681: cannot create symlinks on Samba/home/maxim/Repo/smbprotocol/tests/test_smbclient_shutil.py:721: Samba does not update timestamps/home/maxim/Repo/smbprotocol/tests/test_smbclient_shutil.py:721: Samba does not update timestamps/home/maxim/Repo/smbprotocol/tests/test_smbclient_shutil.py:743: Samba does not update timestamps/home/maxim/Repo/smbprotocol/tests/test_smbclient_shutil.py:743: Samba does not update timestamps/home/maxim/Repo/smbprotocol/tests/test_smbclient_shutil.py:766: Samba does not update timestamps/home/maxim/Repo/smbprotocol/tests/test_smbclient_shutil.py:766: Samba does not update timestamps/home/maxim/Repo/smbprotocol/tests/test_smbclient_shutil.py:790: Samba does not update timestamps/home/maxim/Repo/smbprotocol/tests/test_smbclient_shutil.py:790: Samba does not update timestamps/home/maxim/Repo/smbprotocol/tests/test_smbclient_shutil.py:891: cannot create symlinks on Samba/home/maxim/Repo/smbprotocol/tests/test_smbclient_shutil.py:891: cannot create symlinks on Samba/home/maxim/Repo/smbprotocol/tests/test_smbclient_shutil.py:927: cannot create symlinks on Samba/home/maxim/Repo/smbprotocol/tests/test_smbclient_shutil.py:927: cannot create symlinks on Samba/home/maxim/Repo/smbprotocol/tests/test_smbclient_shutil.py:965: The SMB_SHARE env var was not set, integration tests will be skipped/home/maxim/Repo/smbprotocol/tests/test_smbclient_shutil.py:965: The SMB_SHARE env var was not set, integration tests will be skipped/home/maxim/Repo/smbprotocol/tests/test_smbclient_shutil.py:970: The SMB_SHARE env var was not set, integration tests will be skipped/home/maxim/Repo/smbprotocol/tests/test_smbclient_shutil.py:970: The SMB_SHARE env var was not set, integration tests will be skipped/home/maxim/Repo/smbprotocol/tests/test_smbclient_shutil.py:975: The SMB_SHARE env var was not set, integration tests will be skipped/home/maxim/Repo/smbprotocol/tests/test_smbclient_shutil.py:975: The SMB_SHARE env var was not set, integration tests will be skipped/home/maxim/Repo/smbprotocol/tests/test_smbclient_shutil.py:981: The SMB_SHARE env var was not set, integration tests will be skipped/home/maxim/Repo/smbprotocol/tests/test_smbclient_shutil.py:981: The SMB_SHARE env var was not set, integration tests will be skipped/home/maxim/Repo/smbprotocol/tests/test_smbclient_shutil.py:1067: The SMB_SHARE env var was not set, integration tests will be skipped/home/maxim/Repo/smbprotocol/tests/test_smbclient_shutil.py:1067: The SMB_SHARE env var was not set, integration tests will be skipped/home/maxim/Repo/smbprotocol/tests/test_smbclient_shutil.py:1079: The SMB_SHARE env var was not set, integration tests will be skipped/home/maxim/Repo/smbprotocol/tests/test_smbclient_shutil.py:1079: The SMB_SHARE env var was not set, integration tests will be skipped/home/maxim/Repo/smbprotocol/tests/test_smbclient_shutil.py:1116: The SMB_SHARE env var was not set, integration tests will be skipped/home/maxim/Repo/smbprotocol/tests/test_smbclient_shutil.py:1116: The SMB_SHARE env var was not set, integration tests will be skipped/home/maxim/Repo/smbprotocol/tests/test_smbclient_shutil.py:1152: The SMB_SHARE env var was not set, integration tests will be skipped/home/maxim/Repo/smbprotocol/tests/test_smbclient_shutil.py:1152: The SMB_SHARE env var was not set, integration tests will be skipped/home/maxim/Repo/smbprotocol/tests/test_smbclient_shutil.py:1179: The SMB_SHARE env var was not set, integration tests will be skipped/home/maxim/Repo/smbprotocol/tests/test_smbclient_shutil.py:1179: The SMB_SHARE env var was not set, integration tests will be skipped/home/maxim/Repo/smbprotocol/tests/test_smbclient_shutil.py:1206: Samba does not update timestamps/home/maxim/Repo/smbprotocol/tests/test_smbclient_shutil.py:1206: Samba does not update timestamps/home/maxim/Repo/smbprotocol/tests/test_smbclient_shutil.py:1288: The SMB_SHARE env var was not set, integration tests will be skipped/home/maxim/Repo/smbprotocol/tests/test_smbclient_shutil.py:1288: The SMB_SHARE env var was not set, integration tests will be skipped/home/maxim/Repo/smbprotocol/tests/test_smbclient_shutil.py:1324: cannot create symlinks on Samba/home/maxim/Repo/smbprotocol/tests/test_smbclient_shutil.py:1324: cannot create symlinks on Samba/home/maxim/Repo/smbprotocol/tests/test_smbclient_shutil.py:1359: cannot create symlinks on Samba/home/maxim/Repo/smbprotocol/tests/test_smbclient_shutil.py:1359: cannot create symlinks on Samba/home/maxim/Repo/smbprotocol/tests/test_smbclient_shutil.py:1390: cannot create symlinks on Samba/home/maxim/Repo/smbprotocol/tests/test_smbclient_shutil.py:1390: cannot create symlinks on Samba/home/maxim/Repo/smbprotocol/tests/test_smbclient_shutil.py:1417: cannot create symlinks on Samba/home/maxim/Repo/smbprotocol/tests/test_smbclient_shutil.py:1417: cannot create symlinks on Samba/home/maxim/Repo/smbprotocol/tests/test_smbclient_shutil.py:1434: The SMB_SHARE env var was not set, integration tests will be skipped/home/maxim/Repo/smbprotocol/tests/test_smbclient_shutil.py:1434: The SMB_SHARE env var was not set, integration tests will be skipped/home/maxim/Repo/smbprotocol/tests/test_smbclient_shutil.py:1460: The SMB_SHARE env var was not set, integration tests will be skipped/home/maxim/Repo/smbprotocol/tests/test_smbclient_shutil.py:1460: The SMB_SHARE env var was not set, integration tests will be skipped/home/maxim/Repo/smbprotocol/tests/test_smbclient_shutil.py:1484: The SMB_SHARE env var was not set, integration tests will be skipped/home/maxim/Repo/smbprotocol/tests/test_smbclient_shutil.py:1484: The SMB_SHARE env var was not set, integration tests will be skipped/home/maxim/Repo/smbprotocol/tests/test_smbclient_shutil.py:1510: cannot create symlinks on Samba/home/maxim/Repo/smbprotocol/tests/test_smbclient_shutil.py:1510: cannot create symlinks on Samba/home/maxim/Repo/smbprotocol/tests/test_tree.py:104: The SMB_SHARE env var was not set, integration tests will be skipped/home/maxim/Repo/smbprotocol/tests/test_tree.py:120: The SMB_SHARE env var was not set, integration tests will be skipped/home/maxim/Repo/smbprotocol/tests/test_tree.py:136: The SMB_SHARE env var was not set, integration tests will be skipped/home/maxim/Repo/smbprotocol/tests/test_tree.py:152: The SMB_SHARE env var was not set, integration tests will be skipped/home/maxim/Repo/smbprotocol/tests/test_tree.py:168: The SMB_SHARE env var was not set, integration tests will be skipped/home/maxim/Repo/smbprotocol/tests/test_tree.py:184: The SMB_SHARE env var was not set, integration tests will be skipped/home/maxim/Repo/smbprotocol/tests/test_tree.py:196: The SMB_SHARE env var was not set, integration tests will be skipped/home/maxim/Repo/smbprotocol/tests/test_tree.py:212: The SMB_SHARE env var was not set, integration tests will be skipped/home/maxim/Repo/smbprotocol/tests/test_tree.py:226: The SMB_SHARE env var was not set, integration tests will be skipped/home/maxim/Repo/smbprotocol/tests/test_tree.py:244: The SMB_SHARE env var was not set, integration tests will be skipped/home/maxim/Repo/smbprotocol/tests/test_tree.py:244: The SMB_SHARE env var was not set, integration tests will be skipped/home/maxim/Repo/smbprotocol/tests/test_tree.py:244: The SMB_SHARE env var was not set, integration tests will be skipped/home/maxim/Repo/smbprotocol/tests/test_tree.py:244: The SMB_SHARE env var was not set, integration tests will be skipped/home/maxim/Repo/smbprotocol/tests/test_tree.py:272: The SMB_SHARE env var was not set, integration tests will be skipped/home/maxim/Repo/smbprotocol/tests/test_tree.py:272: The SMB_SHARE env var was not set, integration tests will be skipped/home/maxim/Repo/smbprotocol/tests/test_tree.py:272: The SMB_SHARE env var was not set, integration tests will be skipped \ No newline at end of file diff --git a/setup.py b/setup.py index 1939b8e2..dc8676d5 100644 --- a/setup.py +++ b/setup.py @@ -1,5 +1,4 @@ #!/usr/bin/env python -# -*- coding: utf-8 -*- # Copyright: (c) 2019, Jordan Borean (@jborean93) # MIT License (see LICENSE or https://opensource.org/licenses/MIT) diff --git a/src/smbclient/__init__.py b/src/smbclient/__init__.py index eaec4af4..151ae647 100644 --- a/src/smbclient/__init__.py +++ b/src/smbclient/__init__.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- # Copyright: (c) 2019, Jordan Borean (@jborean93) # MIT License (see LICENSE or https://opensource.org/licenses/MIT) diff --git a/src/smbclient/_io.py b/src/smbclient/_io.py index b2032ae9..f836c9d5 100644 --- a/src/smbclient/_io.py +++ b/src/smbclient/_io.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- # Copyright: (c) 2019, Jordan Borean (@jborean93) # MIT License (see LICENSE or https://opensource.org/licenses/MIT) @@ -52,9 +51,8 @@ def _parse_share_access(raw, mode): for c in raw: access_val = share_access_map.get(c) if access_val is None: - raise ValueError( - "Invalid share_access char %s, can only be %s" % (c, ", ".join(sorted(share_access_map.keys()))) - ) + chars = ", ".join(sorted(share_access_map.keys())) + raise ValueError(f"Invalid share_access char {c}, can only be {chars}") share_access |= access_val if "r" in mode: @@ -82,12 +80,15 @@ def _parse_mode(raw, invalid=""): for c in raw: dispo_val = disposition_map.get(c) if dispo_val is None: - raise ValueError("Invalid mode char %s, can only be %s" % (c, ", ".join(sorted(disposition_map.keys())))) + chars = ", ".join(sorted(disposition_map.keys())) + raise ValueError( + f"Invalid mode char {c}, can only be {chars}", + ) create_disposition |= dispo_val if create_disposition == 0: - raise ValueError("Invalid mode value %s, must contain at least r, w, x, or a" % raw) + raise ValueError(f"Invalid mode value {raw}, must contain at least r, w, x, or a") return create_disposition @@ -102,7 +103,7 @@ def _chunk_size(connection, length, operation): :param operation: The operation the chunk is for: 'read', 'write', 'transact' :return: The size of the chunk we can use and the number of credits to request for the next operation. """ - max_size = getattr(connection, "max_%s_size" % operation) + max_size = getattr(connection, f"max_{operation}_size") # Determine the maximum data length we can send for the operation. We do this by checking the available credits and # calculating whatever is the smallest; length, negotiated operation size, available credit size). @@ -141,7 +142,7 @@ def _resolve_dfs(raw_io): if not info: raise ObjectPathNotFound() - connection_kwargs = getattr(raw_io, "_%s__kwargs" % SMBRawIO.__name__, {}) + connection_kwargs = getattr(raw_io, f"_{SMBRawIO.__name__}__kwargs", {}) for target in info: new_path = raw_path.replace(info.dfs_path, target.target_path, 1) @@ -150,7 +151,7 @@ def _resolve_dfs(raw_io): tree, fd_path = get_smb_tree(new_path, **connection_kwargs) except SMBResponseException as link_exc: - log.warning("Failed to connect to DFS link target %s: %s", str(target), link_exc) + log.warning("Failed to connect to DFS link target %s", target, exc_info=link_exc) continue # Record the target that worked for future reference. @@ -612,8 +613,7 @@ def query_directory(self, pattern, info_class): break query_flags = 0 # Only the first request should have set SMB2_RESTART_SCANS - for entry in entries: - yield entry + yield from entries def readable(self): return False diff --git a/src/smbclient/_os.py b/src/smbclient/_os.py index 63d17741..859fa161 100644 --- a/src/smbclient/_os.py +++ b/src/smbclient/_os.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- # Copyright: (c) 2019, Jordan Borean (@jborean93) # MIT License (see LICENSE or https://opensource.org/licenses/MIT) @@ -102,7 +101,7 @@ ) -def is_remote_path(path): # type: (str) -> bool +def is_remote_path(path: str) -> bool: """ Returns True iff the given path is a remote SMB path (rather than a local path). @@ -182,9 +181,8 @@ def copyfile(src, dst, **kwargs): copychunk_response = SMB2SrvCopyChunkResponse() copychunk_response.unpack(result) if copychunk_response["chunks_written"].get_value() != len(batch): - raise IOError( - "Failed to copy all the chunks in a server side copyfile: '%s' -> '%s'" - % (norm_src, norm_dst) + raise OSError( + f"Failed to copy all the chunks in a server side copyfile: '{norm_src}' -> '{norm_dst}'" ) @@ -433,7 +431,7 @@ def readlink(path, **kwargs): reparse_buffer = _get_reparse_point(norm_path, **kwargs) reparse_tag = reparse_buffer["reparse_tag"] if reparse_tag.get_value() != ReparseTags.IO_REPARSE_TAG_SYMLINK: - raise ValueError("Cannot read link of reparse point with tag %s at '%s'" % (str(reparse_tag), norm_path)) + raise ValueError(f"Cannot read link of reparse point with tag {reparse_tag} at '{norm_path}'") symlink_buffer = SymbolicLinkReparseDataBuffer() symlink_buffer.unpack(reparse_buffer["data_buffer"].get_value()) @@ -549,7 +547,7 @@ def scandir(path, search_pattern="*", **kwargs): continue dir_entry = SMBDirEntry( - SMBRawIO("%s\\%s" % (path, filename), **kwargs), dir_info, connection_cache=connection_cache + SMBRawIO(rf"{path}\{filename}", **kwargs), dir_info, connection_cache=connection_cache ) yield dir_entry @@ -696,12 +694,12 @@ def symlink(src, dst, target_is_directory=False, **kwargs): norm_src = ntpath.abspath(ntpath.join(dst_dir, norm_src)) else: flags = SymbolicLinkFlags.SYMLINK_FLAG_ABSOLUTE - substitute_name = "\\??\\UNC\\%s" % norm_src[2:] + substitute_name = "\\??\\UNC\\" + norm_src[2:] src_drive = ntpath.splitdrive(norm_src)[0] dst_drive = ntpath.splitdrive(norm_dst)[0] if src_drive.lower() != dst_drive.lower(): - raise ValueError("Resolved link src root '%s' must be the same as the dst root '%s'" % (src_drive, dst_drive)) + raise ValueError(f"Resolved link src root '{src_drive}' must be the same as the dst root '{dst_drive}'") try: src_stat = stat(norm_src, **kwargs) @@ -901,13 +899,11 @@ def walk(top, topdown=True, onerror=None, follow_symlinks=False, **kwargs): if not follow_symlinks and py_stat.S_ISLNK(lstat(dirpath, **kwargs).st_mode): continue - for dir_top, dir_dirs, dir_files in walk(dirpath, **walk_kwargs): - yield dir_top, dir_dirs, dir_files + yield from walk(dirpath, **walk_kwargs) else: # On a bottom up approach we yield the sub directories before the top path. for dirpath in bottom_up_dirs: - for dir_top, dir_dirs, dir_files in walk(dirpath, **walk_kwargs): - yield dir_top, dir_dirs, dir_files + yield from walk(dirpath, **walk_kwargs) yield top, dirs, files @@ -1095,7 +1091,7 @@ def _get_reparse_point(path, **kwargs): def _rename_information(src, dst, replace_if_exists=False, **kwargs): verb = "replace" if replace_if_exists else "rename" if not is_remote_path(ntpath.normpath(dst)): - raise ValueError("dst must be an absolute path to where the file or directory should be %sd." % verb) + raise ValueError(f"dst must be an absolute path to where the file or directory should be {verb}d.") raw_args = dict(kwargs) raw_args.update( @@ -1126,7 +1122,7 @@ def _rename_information(src, dst, replace_if_exists=False, **kwargs): dst_share = ntpath.normpath(dst_raw.fd.tree_connect.share_name).split("\\")[-1] if src_guid != dst_guid or src_share.lower() != dst_share.lower(): - raise ValueError("Cannot %s a file to a different root than the src." % verb) + raise ValueError(f"Cannot {verb} a file to a different root than the src.") dst_tree = dst_raw.fd.tree_connect dst_path = dst_raw.fd.file_name @@ -1181,7 +1177,7 @@ def __init__(self, raw, dir_info, connection_cache=None): self._connection_cache = connection_cache def __str__(self): - return "<{0}: {1!r}>".format(self.__class__.__name__, self.name) + return f"<{self.__class__.__name__}: {self.name!r}>" @property def name(self): diff --git a/src/smbclient/_pool.py b/src/smbclient/_pool.py index 14e80395..c5c8cf1f 100644 --- a/src/smbclient/_pool.py +++ b/src/smbclient/_pool.py @@ -1,13 +1,12 @@ -# -*- coding: utf-8 -*- # Copyright: (c) 2019, Jordan Borean (@jborean93) # MIT License (see LICENSE or https://opensource.org/licenses/MIT) +from __future__ import annotations + import atexit import logging import ntpath -import typing import uuid -import warnings from smbprotocol._text import to_text from smbprotocol.connection import Capabilities, Connection @@ -59,7 +58,7 @@ def __call__(cls, *args, **kwargs): return config -class ClientConfig(object, metaclass=_ConfigSingleton): +class ClientConfig(metaclass=_ConfigSingleton): """SMB Client global settings This class defines global settings for the client that affects all connections that the client makes. When setting @@ -99,9 +98,9 @@ def __init__( self.skip_dfs = skip_dfs self.auth_protocol = auth_protocol self.require_secure_negotiate = require_secure_negotiate - self._domain_controller = domain_controller # type: Optional[str] - self._domain_cache = [] # type: List[DomainEntry] - self._referral_cache = [] # type: List[ReferralEntry] + self._domain_controller: str | None = domain_controller + self._domain_cache: list[DomainEntry] = [] + self._referral_cache: list[ReferralEntry] = [] @property def domain_controller(self): @@ -119,13 +118,14 @@ def domain_controller(self, value): if not value or self.skip_dfs: return - ipc_tree = get_smb_tree("\\\\%s\\IPC$" % value)[0] + ipc_tree = get_smb_tree(rf"\\{value}\IPC$")[0] try: domain_referral_response = dfs_request(ipc_tree, "") except InvalidParameter: log.warning( "Specified domain controller %s return STATUS_INVALID_PARAMETER, cannot use as DFS domain " - "cache source" % value + "cache source", + value, ) return @@ -139,13 +139,13 @@ def cache_referral(self, referral): if referral["number_of_referrals"].get_value() > 0: self._referral_cache.append(ReferralEntry(referral)) - def lookup_domain(self, domain_name): # type: (str) -> Optional[DomainEntry] + def lookup_domain(self, domain_name: str) -> DomainEntry | None: # TODO: Check domain referral expiry and resend request if expired for domain in self._domain_cache: if domain.domain_name.lower() == ("\\" + domain_name.lower()): return domain - def lookup_referral(self, path_components: typing.List[str]) -> typing.Optional[ReferralEntry]: + def lookup_referral(self, path_components: list[str]) -> ReferralEntry | None: """Checks if the path exists in the DFS referral cache.""" # A lookup in ReferralCache involves searching for an entry with DFSPathPrefix that is a complete prefix of the # path being looked up. @@ -169,7 +169,7 @@ def set(self, **config): domain_controller = False for key, value in config.items(): if key.startswith("_"): - raise ValueError("Cannot set private attribute %s" % key) + raise ValueError(f"Cannot set private attribute {key}") elif key == "domain_controller": # This must be set last in case we are setting any username/password used for a domain referral lookup. @@ -186,7 +186,7 @@ def _clear_expired_cache(self) -> None: self._referral_cache = [refferal for refferal in self._referral_cache if not refferal.is_expired] -def dfs_request(tree, path): # type: (TreeConnect, str) -> DFSReferralResponse +def dfs_request(tree: TreeConnect, path: str) -> DFSReferralResponse: """Send a DFS Referral request to the IPC tree and return the referrals.""" dfs_referral = DFSReferralRequest() dfs_referral["request_file_name"] = to_text(path) @@ -219,7 +219,7 @@ def delete_session(server, port=445, connection_cache=None): :param port: The port used for the server. :param connection_cache: Connection cache to be used with """ - connection_key = "%s:%s" % (server.lower(), port) + connection_key = f"{server.lower()}:{port}" if connection_cache is None: connection_cache = _SMB_CONNECTIONS @@ -284,14 +284,14 @@ def get_smb_tree( if domain_referral and not domain_referral.is_valid: # If the path is a valid domain name but our domain referral is not currently valid, issue a DC referral # to our known domain controller. - ipc_tree = get_smb_tree("\\\\%s\\IPC$" % client_config.domain_controller, **get_kwargs)[0] + ipc_tree = get_smb_tree(rf"\\{client_config.domain_controller}\IPC$", **get_kwargs)[0] referral_response = dfs_request(ipc_tree, domain_referral.domain_name) domain_referral.process_dc_referral(referral_response) if domain_referral: # Use the dc hint as the source for the root referral request - ipc_tree = get_smb_tree("\\%s\\IPC$" % domain_referral.dc_hint, **get_kwargs)[0] - referral_response = dfs_request(ipc_tree, "\\%s\\%s" % (path_split[0], path_split[1])) + ipc_tree = get_smb_tree(rf"\{domain_referral.dc_hint}\IPC$", **get_kwargs)[0] + referral_response = dfs_request(ipc_tree, rf"\{path_split[0]}\{path_split[1]}") client_config.cache_referral(referral_response) referral = client_config.lookup_referral(path_split) if not referral: @@ -312,7 +312,7 @@ def get_smb_tree( auth_protocol=auth_protocol, ) - share_path = "\\\\%s\\%s" % (server, path_split[1]) + share_path = rf"\\{server}\{path_split[1]}" tree = next((t for t in session.tree_connect_table.values() if t.share_name == share_path), None) if not tree: tree = TreeConnect(session, share_path) @@ -324,14 +324,14 @@ def get_smb_tree( if not session.connection.server_capabilities.has_flag(Capabilities.SMB2_GLOBAL_CAP_DFS): raise - ipc_path = "\\\\%s\\IPC$" % server + ipc_path = rf"\\{server}\IPC$" if path == ipc_path: # In case we already tried connecting to IPC$ but that failed. raise # The share could be a DFS root, issue a root referral request to the hostname and cache the result. ipc_tree = get_smb_tree(ipc_path, **get_kwargs)[0] try: - referral = dfs_request(ipc_tree, "\\%s\\%s" % (path_split[0], path_split[1])) + referral = dfs_request(ipc_tree, rf"\{path_split[0]}\{path_split[1]}") except FSDriverRequired: # If the DFS Request fails with STATUS_FS_DRIVER_REQUIRED then # the server doesn't support DFS requests and the original @@ -396,7 +396,7 @@ def register_session( :param require_signing: Whether signing is required on SMB messages sent over this session. Defaults to True. :return: The Session that was registered or already existed in the pool. """ - connection_key = "%s:%s" % (server.lower(), port) + connection_key = f"{server.lower()}:{port}" if connection_cache is None: connection_cache = _SMB_CONNECTIONS @@ -448,7 +448,7 @@ def reset_connection_cache(fail_on_error=True, connection_cache=None): if fail_on_error: raise else: - warnings.warn("Failed to close connection %s: %s" % (name, str(e))) + log.warning("Failed to close connection %s", name, exc_info=e) atexit.register(reset_connection_cache, fail_on_error=False) diff --git a/src/smbclient/path.py b/src/smbclient/path.py index b6027edd..c3b4d44a 100644 --- a/src/smbclient/path.py +++ b/src/smbclient/path.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- # Copyright: (c) 2019, Jordan Borean (@jborean93) # MIT License (see LICENSE or https://opensource.org/licenses/MIT) diff --git a/src/smbclient/shutil.py b/src/smbclient/shutil.py index c9d7aefe..30146bc7 100644 --- a/src/smbclient/shutil.py +++ b/src/smbclient/shutil.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- # Copyright: (c) 2019, Jordan Borean (@jborean93) and other contributors # MIT License (see LICENSE or https://opensource.org/licenses/MIT) @@ -173,7 +172,7 @@ def copyfile(src, dst, follow_symlinks=True, **kwargs): raise if is_same: - raise shutil.Error("'%s' and '%s' are the same file, cannot copy" % (src, dst)) + raise shutil.Error(f"'{src}' and '{dst}' are the same file, cannot copy") smbclient_copyfile(src, dst, **kwargs) return dst diff --git a/src/smbprotocol/__init__.py b/src/smbprotocol/__init__.py index 2dd7a52a..3beb7344 100644 --- a/src/smbprotocol/__init__.py +++ b/src/smbprotocol/__init__.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- # Copyright: (c) 2019, Jordan Borean (@jborean93) # MIT License (see LICENSE or https://opensource.org/licenses/MIT) diff --git a/src/smbprotocol/_text.py b/src/smbprotocol/_text.py index 71eb8abd..683386ae 100644 --- a/src/smbprotocol/_text.py +++ b/src/smbprotocol/_text.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- # Copyright: (c) 2019, Jordan Borean (@jborean93) # MIT License (see LICENSE or https://opensource.org/licenses/MIT) diff --git a/src/smbprotocol/change_notify.py b/src/smbprotocol/change_notify.py index c7ecb31a..1565b473 100644 --- a/src/smbprotocol/change_notify.py +++ b/src/smbprotocol/change_notify.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- # Copyright: (c) 2019, Jordan Borean (@jborean93) # MIT License (see LICENSE or https://opensource.org/licenses/MIT) @@ -280,8 +279,10 @@ def start(self, completion_filter, flags=0, output_buffer_length=65536, send=Tru change_notify["completion_filter"] = completion_filter log.info( - "Session: %s, Tree Connect: %s , Open: %s - sending SMB2 Change Notify request" - % (self.open.tree_connect.session.username, self.open.tree_connect.share_name, self.open.file_name) + "Session: %s, Tree Connect: %s , Open: %s - sending SMB2 Change Notify request", + self.open.tree_connect.session.username, + self.open.tree_connect.share_name, + self.open.file_name, ) log.debug(change_notify) if send: @@ -326,5 +327,5 @@ def _on_response(self): self._t_exc = exc finally: - log.debug("Firing response event for %s change notify" % self.open.file_name) + log.debug("Firing response event for %s change notify", self.open.file_name) self.response_event.set() diff --git a/src/smbprotocol/connection.py b/src/smbprotocol/connection.py index ce663cb6..be06a403 100644 --- a/src/smbprotocol/connection.py +++ b/src/smbprotocol/connection.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- # Copyright: (c) 2019, Jordan Borean (@jborean93) # MIT License (see LICENSE or https://opensource.org/licenses/MIT) @@ -740,8 +739,11 @@ def __init__(self, guid, server_name, port=445, require_signing=True): sent over this connection """ log.info( - "Initialising connection, guid: %s, require_signing: %s, " - "server_name: %s, port: %d" % (guid, require_signing, server_name, port) + "Initialising connection, guid: %s, require_signing: %s, server_name: %s, port: %d", + guid, + require_signing, + server_name, + port, ) self.server_name = server_name self.port = port @@ -860,7 +862,7 @@ def connect(self, dialect=None, timeout=60, preferred_encryption_algos=None, pre self.transport = Tcp(self.server_name, self.port, timeout) self.transport.connect() t_worker = threading.Thread( - target=self._process_message_thread, name="msg_worker-%s:%s" % (self.server_name, self.port) + target=self._process_message_thread, name=f"msg_worker-{self.server_name}:{self.port}" ) t_worker.daemon = True t_worker.start() @@ -878,7 +880,7 @@ def connect(self, dialect=None, timeout=60, preferred_encryption_algos=None, pre SigningAlgorithms.HMAC_SHA256, ] smb_response = self._send_smb2_negotiate(dialect, timeout, enc_algos, sign_algos) - log.info("Negotiated dialect: %s" % str(smb_response["dialect_revision"])) + log.info("Negotiated dialect: %s", smb_response["dialect_revision"]) self.dialect = smb_response["dialect_revision"].get_value() self.max_transact_size = smb_response["max_transact_size"].get_value() self.max_read_size = smb_response["max_read_size"].get_value() @@ -890,7 +892,7 @@ def connect(self, dialect=None, timeout=60, preferred_encryption_algos=None, pre SecurityMode.SMB2_NEGOTIATE_SIGNING_REQUIRED ): self.require_signing = True - log.info("Connection require signing: %s" % self.require_signing) + log.info("Connection require signing: %s", self.require_signing) capabilities = smb_response["capabilities"] self.server_capabilities = capabilities @@ -1006,9 +1008,10 @@ def receive(self, request, wait=True, timeout=None, resolve_symlinks=True): while True: iter_timeout = int(max(timeout - (time.time() - start_time), 1)) if timeout is not None else None if not request.response_event.wait(timeout=iter_timeout): + value = request.message["message_id"].get_value() raise SMBException( - "Connection timeout of %d seconds exceeded while waiting for a message id %s " - "response from the server" % (timeout, request.message["message_id"].get_value()) + f"Connection timeout of {timeout} seconds exceeded while waiting for a message id {value} " + "response from the server" ) # Use a lock on the request so that in the case of a pending response we have exclusive lock on the event @@ -1044,9 +1047,7 @@ def receive(self, request, wait=True, timeout=None, resolve_symlinks=True): ) exp = SMBResponseException(response) - reparse_buffer = next( - (e for e in exp.error_details if isinstance(e, SMB2SymbolicLinkErrorResponse)) - ) + reparse_buffer = next(e for e in exp.error_details if isinstance(e, SMB2SymbolicLinkErrorResponse)) new_path = reparse_buffer.resolve_path(original_path)[len(tree_share_name) :] new_open = Open(tree, new_path) @@ -1151,7 +1152,7 @@ def verify_signature(self, header, session_id, force=False): session = self.session_table.get(session_id, None) if session is None: - raise SMBException("Failed to find session %s for message verification" % session_id) + raise SMBException(f"Failed to find session {session_id} for message verification") expected = self._generate_signature( header.pack(), @@ -1162,9 +1163,10 @@ def verify_signature(self, header, session_id, force=False): ) actual = header["signature"].get_value() if actual != expected: + actual_signature = binascii.hexlify(actual).decode() + expected_signature = binascii.hexlify(expected).decode() raise SMBException( - "Server message signature could not be verified: %s != %s" - % (binascii.hexlify(actual).decode(), binascii.hexlify(expected).decode()) + f"Server message signature could not be verified: {actual_signature} != {expected_signature}", ) def _check_worker_running(self): @@ -1221,8 +1223,8 @@ def _send( credits_available = sequence_window_high - sequence_window_low if credit_charge > credits_available: raise SMBException( - "Request requires %d credits but only %d credits are available" - % (credit_charge, credits_available) + f"Request requires {credit_charge} credits but only {credits_available} " + "credits are available" ) current_id = message_id or sequence_window_low @@ -1471,17 +1473,15 @@ def _encrypt(self, b_data, session): return header def _decrypt(self, message): - if message["flags"].get_value() != 0x0001: - error_msg = "Expecting flag of 0x0001 but got %s in the SMB Transform Header Response" % format( - message["flags"].get_value(), "x" - ) + value = message["flags"].get_value() + if value != 0x0001: + error_msg = f"Expecting flag of 0x0001 but got {value:x} in the SMB Transform Header Response" raise SMBException(error_msg) session_id = message["session_id"].get_value() session = self.session_table.get(session_id, None) if session is None: - error_msg = "Failed to find valid session %s for message decryption" % session_id - raise SMBException(error_msg) + raise SMBException(f"Failed to find valid session {session_id} for message decryption") if self.dialect >= Dialects.SMB_3_1_1: cipher_id = self.cipher_id @@ -1537,14 +1537,14 @@ def _send_smb2_negotiate(self, dialect, timeout, encryption_algorithms, signing_ highest_dialect = sorted(negotiated_dialects)[-1] self.negotiated_dialects = neg_req["dialects"] = negotiated_dialects log.info( - "Negotiating with SMB2 protocol with highest client dialect " - "of: %s" % [dialect for dialect, v in vars(Dialects).items() if v == highest_dialect][0] + "Negotiating with SMB2 protocol with highest client dialect of: %s", + [dialect for dialect, v in vars(Dialects).items() if v == highest_dialect][0], ) neg_req["security_mode"] = self.client_security_mode if highest_dialect >= Dialects.SMB_2_1_0: - log.debug("Adding client guid %s to negotiate request" % self.client_guid) + log.debug("Adding client guid %s to negotiate request", self.client_guid) neg_req["client_guid"] = self.client_guid else: @@ -1552,7 +1552,7 @@ def _send_smb2_negotiate(self, dialect, timeout, encryption_algorithms, signing_ self.client_guid = None if highest_dialect >= Dialects.SMB_3_0_0: - log.debug("Adding client capabilities %d to negotiate request" % self.client_capabilities) + log.debug("Adding client capabilities %d to negotiate request", self.client_capabilities) neg_req["capabilities"] = self.client_capabilities else: @@ -1566,7 +1566,8 @@ def _send_smb2_negotiate(self, dialect, timeout, encryption_algorithms, signing_ int_cap["data"]["hash_algorithms"] = [HashAlgorithms.SHA_512] int_cap["data"]["salt"] = self.salt log.debug( - "Adding preauth integrity capabilities of hash SHA512 and salt %s to negotiate request" % self.salt + "Adding preauth integrity capabilities of hash SHA512 and salt %s to negotiate request", + self.salt, ) enc_cap = SMB2NegotiateContextRequest() @@ -1699,7 +1700,7 @@ def cancel(self): return message_id = self.message["message_id"].get_value() - log.info("Cancelling message %s" % message_id) + log.info("Cancelling message %s", message_id) self._connection.send( SMB2CancelRequest(), sid=self.session_id, credit_request=0, message_id=message_id, async_id=self.async_id ) diff --git a/src/smbprotocol/create_contexts.py b/src/smbprotocol/create_contexts.py index 6b0bb1a9..d6426edd 100644 --- a/src/smbprotocol/create_contexts.py +++ b/src/smbprotocol/create_contexts.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- # Copyright: (c) 2019, Jordan Borean (@jborean93) # MIT License (see LICENSE or https://opensource.org/licenses/MIT) diff --git a/src/smbprotocol/dfs.py b/src/smbprotocol/dfs.py index 6e46f1d1..37cccbe0 100644 --- a/src/smbprotocol/dfs.py +++ b/src/smbprotocol/dfs.py @@ -1,8 +1,11 @@ # Copyright: (c) 2020, Jordan Borean (@jborean93) # MIT License (see LICENSE or https://opensource.org/licenses/MIT) +from __future__ import annotations + import time from collections import OrderedDict, namedtuple +from typing import Iterator from smbprotocol.structure import ( BytesField, @@ -41,24 +44,24 @@ class DomainEntry: domain_list (List[str]): A list of known domain controller hostnames for the domain. """ - def __init__(self, referral): # type: (DFSReferralEntryV3) -> None + def __init__(self, referral: DFSReferralEntryV3): self.domain_list = [] - self._referral = referral # type: DFSReferralEntryV3 - self._start_time = time.time() # type: float - self._domain_hint_idx = None # type: Optional[int] + self._referral = referral + self._start_time: float = time.time() + self._domain_hint_idx: int | None = None @property - def domain_name(self): # type: () -> str + def domain_name(self) -> str: """The domain DFS path.""" return self._referral.dfs_path @property - def dc_hint(self): # type: () -> str + def dc_hint(self) -> str: """The last known good domain hostname in domain_list.""" return self.domain_list[self._domain_hint_idx] @dc_hint.setter - def dc_hint(self, value): # type: (str) -> None + def dc_hint(self, value: str) -> None: for idx, target in enumerate(self.domain_list): if target == value: self._domain_hint_idx = idx @@ -68,16 +71,16 @@ def dc_hint(self, value): # type: (str) -> None raise ValueError("The specific domain hint does not exist in this domain cache entry") @property - def is_expired(self): # type: () -> bool + def is_expired(self) -> bool: """Whether the hint has expired or not.""" return ((time.time() - self._start_time) - self._referral["time_to_live"].get_value()) >= 0 @property - def is_valid(self): # type: () -> bool + def is_valid(self) -> bool: """Whether the domain entry has had a DC referral response or not.""" return self._domain_hint_idx is not None and not self.is_expired - def process_dc_referral(self, referral): # type: (DFSReferralResponse) -> None + def process_dc_referral(self, referral: DFSReferralResponse) -> None: if self._domain_hint_idx is None: self._domain_hint_idx = 0 @@ -96,54 +99,53 @@ class ReferralEntry: referral: The DFSReferralResponse to cache. """ - def __init__(self, referral): # type: (DFSReferralResponse) -> None + def __init__(self, referral: DFSReferralResponse): referrals = referral["referral_entries"].get_value() self._referral_header_flags = referral["referral_header_flags"] - self._referrals = referrals # type: List[Union[DFSReferralEntryV1, DFSReferralEntryV2, DFSReferralEntryV3]] - self._start_time = time.time() # type: float - self._target_hint_idx = 0 # type: int + self._referrals: list[DFSReferralEntryV1 | DFSReferralEntryV2 | DFSReferralEntryV3] = referrals + self._start_time: float = time.time() + self._target_hint_idx: int = 0 @property - def dfs_path(self): # type: () -> str + def dfs_path(self) -> str: return self._referrals[self._target_hint_idx].dfs_path @property - def is_root(self): # type: () -> bool + def is_root(self) -> bool: return self._referrals[self._target_hint_idx]["server_type"].has_flag(DFSServerTypes.ROOT_TARGETS) @property - def is_link(self): # type: () -> bool + def is_link(self) -> bool: return not self.is_root # @property - # def is_interlink(self): # type: () -> bool + # def is_interlink(self) -> bool: # return False @property - def is_expired(self): # type: () -> bool + def is_expired(self) -> bool: referral = self._referrals[self._target_hint_idx] return ((time.time() - self._start_time) - referral["time_to_live"].get_value()) >= 0 @property - def target_failback(self): # type: () -> bool + def target_failback(self) -> bool: return self._referral_header_flags.has_flag(DFSReferralHeaderFlags.TARGET_FAIL_BACK) @property - def target_hint(self): # type: () -> DFSTarget + def target_hint(self) -> DFSTarget: return self.target_list[self._target_hint_idx] @target_hint.setter - def target_hint(self, value): # type: (DFSTarget) -> None + def target_hint(self, value: DFSTarget) -> None: for idx, target in enumerate(self.target_list): if target == value: self._target_hint_idx = idx break - else: raise ValueError("The specific target hint does not exist in this referral entry") @property - def target_list(self): # type: () -> List[DFSTarget] + def target_list(self) -> list[DFSTarget]: return [ DFSTarget( target_path=e.network_address, @@ -152,7 +154,7 @@ def target_list(self): # type: () -> List[DFSTarget] for e in self._referrals ] - def __iter__(self): # type: () -> Iterator[DFSTarget] + def __iter__(self) -> Iterator[DFSTarget]: """Iterates through the target_list with a priority being the hinted value.""" yield self.target_list[self._target_hint_idx] @@ -387,7 +389,7 @@ def process_string_buffer(self, buffer, entry_offset): buffer_fields = ["dfs_path", "dfs_alternate_path", "network_address"] for field_name in buffer_fields: - field_offset = self["%s_offset" % field_name].get_value() + field_offset = self[f"{field_name}_offset"].get_value() if field_offset == 0: continue @@ -433,7 +435,7 @@ def process_string_buffer(self, buffer, entry_offset): buffer_fields.insert(1, "dfs_alternate_path") for field_name in buffer_fields: - field_offset = self["%s_offset" % field_name].get_value() + field_offset = self[f"{field_name}_offset"].get_value() if field_offset == 0: continue diff --git a/src/smbprotocol/exceptions.py b/src/smbprotocol/exceptions.py index a9ec482f..8508eed0 100644 --- a/src/smbprotocol/exceptions.py +++ b/src/smbprotocol/exceptions.py @@ -1,13 +1,15 @@ -# -*- coding: utf-8 -*- # Copyright: (c) 2019, Jordan Borean (@jborean93) # MIT License (see LICENSE or https://opensource.org/licenses/MIT) +from __future__ import annotations + import binascii import errno import ntpath import os import socket from collections import OrderedDict +from typing import Any from smbprotocol import Dialects from smbprotocol._text import to_bytes, to_text @@ -47,7 +49,7 @@ class SMBOSError(OSError, SMBException): def __init__(self, ntstatus, filename, filename2=None): self.ntstatus = ntstatus - self.filename2 = str(filename2) if filename2 else None + self.filename2 = os.fspath(filename2) if filename2 else None ntstatus_name = "STATUS_UNKNOWN" for name, val in vars(NtStatus).items(): @@ -70,19 +72,18 @@ def __init__(self, ntstatus, filename, filename2=None): NtStatus.STATUS_NOT_A_DIRECTORY: errno.ENOTDIR, NtStatus.STATUS_DIRECTORY_NOT_EMPTY: errno.ENOTEMPTY, NtStatus.STATUS_END_OF_FILE: getattr(errno, "ENODATA", 120), # Not present on py2 for Windows. - }.get(ntstatus, (0, "Unknown NtStatus error returned '%s'" % ntstatus_name)) + }.get(ntstatus, (0, f"Unknown NtStatus error returned '{ntstatus_name}'")) if not isinstance(error_details, tuple): error_details = (error_details, os.strerror(error_details)) - super().__init__(error_details[0], error_details[1], str(filename)) + super().__init__(error_details[0], error_details[1], os.fspath(filename)) def __str__(self): - msg = "[Error {0}] [NtStatus 0x{1}] {2}: '{3}'".format( - self.errno, format(self.ntstatus, "x").zfill(8), self.strerror, self.filename - ) + status = format(self.ntstatus, "x").zfill(8) + msg = f"[Error {self.errno}] [NtStatus 0x{status}] {self.strerror}: '{self.filename}'" if self.filename2: - msg += " -> '%s'" % self.filename2 + msg += f" -> '{self.filename2}'" return msg @@ -90,10 +91,9 @@ def __str__(self): class SMBLinkRedirectionError(SMBException): @property def message(self): - msg = "Encountered symlink at '%s' that points to '%s' which cannot be redirected: %s" % ( - str(self.path), - str(self.target), - str(self.args[0]), + msg = ( + f"Encountered symlink at '{self.path}' that points to " + f"'{self.target}' which cannot be redirected: {self.args[0]}" ) return msg @@ -141,11 +141,9 @@ def message(self): required_dialect = self._get_dialect_name(self.required_dialect) negotiated_dialect = self._get_dialect_name(self.negotiated_dialect) - msg = "%s is not available on the negotiated dialect %s, requires dialect %s%s" % ( - self.feature_name, - negotiated_dialect, - required_dialect, - msg_suffix, + msg = ( + f"{self.feature_name} is not available on the negotiated dialect {negotiated_dialect}, " + f"requires dialect {required_dialect}{msg_suffix}" ) return msg @@ -169,9 +167,7 @@ def __init__(cls, name, bases, attributes): return if not hasattr(cls, "_STATUS_CODE"): - raise ValueError( - "%s.%s does not have the _STATUS_CODE class attribute set" % (cls.__module__, cls.__name__) - ) + raise ValueError(f"{cls.__module__}.{cls.__name__} does not have the _STATUS_CODE class attribute set") cls.__registry[cls._STATUS_CODE] = cls @@ -201,11 +197,11 @@ class SMBResponseException(SMBException, metaclass=_SMBErrorRegistry): _BASE_MESSAGE = "Unknown error." - def __init__(self, header): # type: (SMB2HeaderResponse) -> None + def __init__(self, header: SMB2HeaderResponse): self.header = header @property - def error_details(self): # type: () -> List[any] + def error_details(self) -> list[Any]: # list of error_details returned by the server, currently used in # the SMB 3.1.1 error response for certain situations error = SMB2ErrorResponse() @@ -235,7 +231,7 @@ def error_details(self): # type: () -> List[any] return error_details @property - def message(self): # type: () -> str + def message(self) -> str: error_details = [] for detail in self.error_details: @@ -243,7 +239,7 @@ def message(self): # type: () -> str flag = str(detail["flags"]) print_name = detail.get_print_name() sub_name = detail.get_substitute_name() - error_details.append("Flag: %s, Print Name: %s, Substitute Name: %s" % (flag, print_name, sub_name)) + error_details.append(f"Flag: {flag}, Print Name: {print_name}, Substitute Name: {sub_name}") elif isinstance(detail, SMB2ShareRedirectErrorContext): ip_addresses = [] @@ -251,19 +247,19 @@ def message(self): # type: () -> str ip_addresses.append(ip_addr.get_ipaddress()) resource_name = to_text(detail["resource_name"].get_value(), encoding="utf-16-le") - error_details.append( - "IP Addresses: '%s', Resource Name: %s" % ("', '".join(ip_addresses), resource_name) - ) + addresses = "', '".join(ip_addresses) + error_details.append(f"IP Addresses: '{addresses}', Resource Name: {resource_name}") else: # unknown error details in response, output raw bytes - error_details.append("Raw: %s" % to_text(binascii.hexlify(detail))) + error_details.append("Raw: " + to_text(binascii.hexlify(detail))) - error_msg = "%s %s: 0x%s" % (self._BASE_MESSAGE, str(self.header["status"]), format(self.status, "x").zfill(8)) + status = format(self.status, "x").zfill(8) + error_msg = f"{self._BASE_MESSAGE} {self.header['status']}: 0x{status}" if error_details: - error_msg += " - %s" % ", ".join(error_details) + error_msg += " - " + (", ".join(error_details)) - return "Received unexpected status from the server: %s" % error_msg + return f"Received unexpected status from the server: {error_msg}" @property def status(self): diff --git a/src/smbprotocol/file_info.py b/src/smbprotocol/file_info.py index 0fc4df71..b54f6090 100644 --- a/src/smbprotocol/file_info.py +++ b/src/smbprotocol/file_info.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- # Copyright: (c) 2019, Jordan Borean (@jborean93) # MIT License (see LICENSE or https://opensource.org/licenses/MIT) diff --git a/src/smbprotocol/header.py b/src/smbprotocol/header.py index 8142d3d8..fb3a0301 100644 --- a/src/smbprotocol/header.py +++ b/src/smbprotocol/header.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- # Copyright: (c) 2020, Jordan Borean (@jborean93) # MIT License (see LICENSE or https://opensource.org/licenses/MIT) diff --git a/src/smbprotocol/ioctl.py b/src/smbprotocol/ioctl.py index 662f5bf2..cf2c5876 100644 --- a/src/smbprotocol/ioctl.py +++ b/src/smbprotocol/ioctl.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- # Copyright: (c) 2019, Jordan Borean (@jborean93) # MIT License (see LICENSE or https://opensource.org/licenses/MIT) diff --git a/src/smbprotocol/open.py b/src/smbprotocol/open.py index 6885b489..14467d4c 100644 --- a/src/smbprotocol/open.py +++ b/src/smbprotocol/open.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- # Copyright: (c) 2019, Jordan Borean (@jborean93) # MIT License (see LICENSE or https://opensource.org/licenses/MIT) @@ -1150,8 +1149,10 @@ def create( return create, self._create_response log.info( - "Session: %s, Tree Connect: %s - sending SMB2 Create Request " - "for file %s" % (self.tree_connect.session.username, self.tree_connect.share_name, self.file_name) + "Session: %s, Tree Connect: %s - sending SMB2 Create Request for file %s", + self.tree_connect.session.username, + self.tree_connect.share_name, + self.file_name, ) log.debug(create) @@ -1160,8 +1161,9 @@ def create( def _create_response(self, request): log.info( - "Session: %s, Tree Connect: %s - receiving SMB2 Create " - "Response" % (self.tree_connect.session.username, self.tree_connect.share_name) + "Session: %s, Tree Connect: %s - receiving SMB2 Create Response", + self.tree_connect.session.username, + self.tree_connect.share_name, ) response = self.connection.receive(request) create_response = SMB2CreateResponse() @@ -1222,8 +1224,8 @@ def read(self, offset, length, min_length=0, unbuffered=False, wait=True, send=T """ if length > self.connection.max_read_size: raise SMBException( - "The requested read length %d is greater than " - "the maximum negotiated read size %d" % (length, self.connection.max_read_size) + f"The requested read length {length} is greater than " + f"the maximum negotiated read size {self.connection.max_read_size}" ) read = SMB2ReadRequest() @@ -1244,8 +1246,10 @@ def read(self, offset, length, min_length=0, unbuffered=False, wait=True, send=T return read, self._read_response log.info( - "Session: %s, Tree Connect ID: %s - sending SMB2 Read " - "Request for file %s" % (self.tree_connect.session.username, self.tree_connect.share_name, self.file_name) + "Session: %s, Tree Connect ID: %s - sending SMB2 Read Request for file %s", + self.tree_connect.session.username, + self.tree_connect.share_name, + self.file_name, ) log.debug(read) request = self.connection.send(read, self.tree_connect.session.session_id, self.tree_connect.tree_connect_id) @@ -1253,8 +1257,9 @@ def read(self, offset, length, min_length=0, unbuffered=False, wait=True, send=T def _read_response(self, request, wait=True): log.info( - "Session: %s, Tree Connect ID: %s - receiving SMB2 Read " - "Response" % (self.tree_connect.session.username, self.tree_connect.share_name) + "Session: %s, Tree Connect ID: %s - receiving SMB2 Read Response", + self.tree_connect.session.username, + self.tree_connect.share_name, ) response = self.connection.receive(request, wait=wait) read_response = SMB2ReadResponse() @@ -1288,8 +1293,8 @@ def write(self, data, offset=0, write_through=False, unbuffered=False, wait=True data_len = len(data) if data_len > self.connection.max_write_size: raise SMBException( - "The requested write length %d is greater than " - "the maximum negotiated write size %d" % (data_len, self.connection.max_write_size) + f"The requested write length {data_len} is greater than " + f"the maximum negotiated write size {self.connection.max_write_size}" ) write = SMB2WriteRequest() @@ -1316,8 +1321,10 @@ def write(self, data, offset=0, write_through=False, unbuffered=False, wait=True return write, self._write_response log.info( - "Session: %s, Tree Connect: %s - sending SMB2 Write Request " - "for file %s" % (self.tree_connect.session.username, self.tree_connect.share_name, self.file_name) + "Session: %s, Tree Connect: %s - sending SMB2 Write Request for file %s", + self.tree_connect.session.username, + self.tree_connect.share_name, + self.file_name, ) log.debug(write) request = self.connection.send(write, self.tree_connect.session.session_id, self.tree_connect.tree_connect_id) @@ -1325,8 +1332,9 @@ def write(self, data, offset=0, write_through=False, unbuffered=False, wait=True def _write_response(self, request, wait=True): log.info( - "Session: %s, Tree Connect: %s - receiving SMB2 Write " - "Response" % (self.tree_connect.session.username, self.tree_connect.share_name) + "Session: %s, Tree Connect: %s - receiving SMB2 Write Response", + self.tree_connect.session.username, + self.tree_connect.share_name, ) response = self.connection.receive(request, wait=wait) write_response = SMB2WriteResponse() @@ -1357,8 +1365,10 @@ def flush(self, send=True): return flush, self._flush_response log.info( - "Session: %s, Tree Connect: %s - sending SMB2 Flush Request " - "for file %s" % (self.tree_connect.session.username, self.tree_connect.share_name, self.file_name) + "Session: %s, Tree Connect: %s - sending SMB2 Flush Request for file %s", + self.tree_connect.session.username, + self.tree_connect.share_name, + self.file_name, ) log.debug(flush) request = self.connection.send(flush, self.tree_connect.session.session_id, self.tree_connect.tree_connect_id) @@ -1366,8 +1376,9 @@ def flush(self, send=True): def _flush_response(self, request): log.info( - "Session: %s, Tree Connect: %s - receiving SMB2 Flush " - "Response" % (self.tree_connect.session.username, self.tree_connect.share_name) + "Session: %s, Tree Connect: %s - receiving SMB2 Flush Response", + self.tree_connect.session.username, + self.tree_connect.share_name, ) response = self.connection.receive(request) flush_response = SMB2FlushResponse() @@ -1415,9 +1426,10 @@ def query_directory( return query, self._query_directory_response log.info( - "Session: %s, Tree Connect: %s - sending SMB2 Query " - "Directory Request for directory %s" - % (self.tree_connect.session.username, self.tree_connect.share_name, self.file_name) + "Session: %s, Tree Connect: %s - sending SMB2 Query Directory Request for directory %s", + self.tree_connect.session.username, + self.tree_connect.share_name, + self.file_name, ) log.debug(query) request = self.connection.send(query, self.tree_connect.session.session_id, self.tree_connect.tree_connect_id) @@ -1425,8 +1437,9 @@ def query_directory( def _query_directory_response(self, request): log.info( - "Session: %s, Tree Connect: %s - receiving SMB2 Query " - "Response" % (self.tree_connect.session.username, self.tree_connect.share_name) + "Session: %s, Tree Connect: %s - receiving SMB2 Query Response", + self.tree_connect.session.username, + self.tree_connect.share_name, ) response = self.connection.receive(request) query_response = SMB2QueryDirectoryResponse() @@ -1470,8 +1483,10 @@ def close(self, get_attributes=False, send=True): return close, self._close_response log.info( - "Session: %s, Tree Connect: %s - sending SMB2 Close Request " - "for file %s" % (self.tree_connect.session.username, self.tree_connect.share_name, self.file_name) + "Session: %s, Tree Connect: %s - sending SMB2 Close Request for file %s", + self.tree_connect.session.username, + self.tree_connect.share_name, + self.file_name, ) log.debug(close) request = self.connection.send(close, self.tree_connect.session.session_id, self.tree_connect.tree_connect_id) @@ -1479,8 +1494,9 @@ def close(self, get_attributes=False, send=True): def _close_response(self, request): log.info( - "Session: %s, Tree Connect: %s - receiving SMB2 Close " - "Response" % (self.tree_connect.session.username, self.tree_connect.share_name) + "Session: %s, Tree Connect: %s - receiving SMB2 Close Response", + self.tree_connect.session.username, + self.tree_connect.share_name, ) try: response = self.connection.receive(request) diff --git a/src/smbprotocol/query_info.py b/src/smbprotocol/query_info.py index ef56ccad..88c20227 100644 --- a/src/smbprotocol/query_info.py +++ b/src/smbprotocol/query_info.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- # Copyright: (c) 2019, Jordan Borean (@jborean93) # MIT License (see LICENSE or https://opensource.org/licenses/MIT) diff --git a/src/smbprotocol/reparse_point.py b/src/smbprotocol/reparse_point.py index d8ed4126..70829dad 100644 --- a/src/smbprotocol/reparse_point.py +++ b/src/smbprotocol/reparse_point.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- # Copyright: (c) 2019, Jordan Borean (@jborean93) # MIT License (see LICENSE or https://opensource.org/licenses/MIT) @@ -201,7 +200,7 @@ def resolve_link(self, path): return ntpath.abspath(link_target) def _get_name(self, prefix): - offset = self["%s_name_offset" % prefix].get_value() - length = self["%s_name_length" % prefix].get_value() + offset = self[f"{prefix}_name_offset"].get_value() + length = self[f"{prefix}_name_length"].get_value() b_name = self["buffer"].get_value()[offset : offset + length] return to_text(b_name, encoding="utf-16-le") diff --git a/src/smbprotocol/security_descriptor.py b/src/smbprotocol/security_descriptor.py index 0d7636db..bbfc7ca7 100644 --- a/src/smbprotocol/security_descriptor.py +++ b/src/smbprotocol/security_descriptor.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- # Copyright: (c) 2019, Jordan Borean (@jborean93) # MIT License (see LICENSE or https://opensource.org/licenses/MIT) @@ -158,7 +157,8 @@ def __str__(self): revision = self["revision"].get_value() id_authority = self["identifier_authority"].get_value() sub_authorities = self["sub_authorities"].get_value() - sid_string = "S-%d-%d-%s" % (revision, id_authority, "-".join(str(x) for x in sub_authorities)) + authorities_string = "-".join(str(x) for x in sub_authorities) + sid_string = f"S-{revision}-{id_authority}-{authorities_string}" return sid_string def from_string(self, sid_string): @@ -389,7 +389,7 @@ def _rebuild_buffer(self): for field, value in self._buffer.items(): if not value: continue - offset_field = "offset_%s" % field + offset_field = f"offset_{field}" field_bytes = value.pack() buffer += field_bytes self[offset_field].set_value(offset_count) diff --git a/src/smbprotocol/session.py b/src/smbprotocol/session.py index 56c36fde..f521173f 100644 --- a/src/smbprotocol/session.py +++ b/src/smbprotocol/session.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- # Copyright: (c) 2019, Jordan Borean (@jborean93) # MIT License (see LICENSE or https://opensource.org/licenses/MIT) @@ -216,7 +215,7 @@ def __init__(self, connection, username=None, password=None, require_encryption= values are 'negotiate', 'ntlm' or 'kerberos'. Defaults to 'negotiate'. """ - log.info("Initialising session with username: %s" % username) + log.info("Initialising session with username: %s", username) self._connected = False self.session_id = 0 self.require_encryption = require_encryption @@ -272,7 +271,7 @@ def connect(self): protocol=self.auth_protocol, ) except spnego.exceptions.SpnegoError as err: - raise SMBAuthenticationError("Failed to authenticate with server: %s" % str(err.message)) + raise SMBAuthenticationError(f"Failed to authenticate with server: {err}") from err in_token = self.connection.gss_negotiate_token if self.auth_protocol != "negotiate": @@ -282,7 +281,7 @@ def connect(self): try: out_token = context.step(in_token) except spnego.exceptions.SpnegoError as err: - raise SMBAuthenticationError("Failed to authenticate with server: %s" % str(err.message)) + raise SMBAuthenticationError(f"Failed to authenticate with server: {err}") from err if not out_token: break @@ -320,7 +319,7 @@ def connect(self): if status == NtStatus.STATUS_MORE_PROCESSING_REQUIRED: log.info("More processing is required for SMB2_SESSION_SETUP") - log.info("Setting session id to %s" % self.session_id) + log.info("Setting session id to %s", self.session_id) self._connected = True # Move the session from the preauth table to the actual session table. @@ -412,13 +411,13 @@ def disconnect(self, close=True): for tree in list(self.tree_connect_table.values()): tree.disconnect() - log.info("Session: %s - Logging off of SMB Session" % self.username) + log.info("Session: %s - Logging off of SMB Session", self.username) logoff = SMB2Logoff() - log.info("Session: %s - Sending Logoff message" % self.username) + log.info("Session: %s - Sending Logoff message", self.username) log.debug(logoff) request = self.connection.send(logoff, sid=self.session_id) - log.info("Session: %s - Receiving Logoff response" % self.username) + log.info("Session: %s - Receiving Logoff response", self.username) res = self.connection.receive(request) res_logoff = SMB2Logoff() res_logoff.unpack(res["data"].get_value()) diff --git a/src/smbprotocol/structure.py b/src/smbprotocol/structure.py index d9726551..7f20d8ec 100644 --- a/src/smbprotocol/structure.py +++ b/src/smbprotocol/structure.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- # Copyright: (c) 2019, Jordan Borean (@jborean93) # MIT License (see LICENSE or https://opensource.org/licenses/MIT) @@ -71,11 +70,10 @@ def __str__(self): # the field header is slightly different for a StructureField # remove the leading space and put the value on the next line if isinstance(field, StructureField): - field_header = "%s =\n%s" + field_string = f"{field.name} =\n{field}" else: - field_header = "%s = %s" + field_string = f"{field.name} = {field}" - field_string = field_header % (field.name, str(field)) field_strings.append(_indent_lines(field_string, TAB)) field_strings.append("") @@ -87,8 +85,9 @@ def __str__(self): ) field_strings.append(hex_wrapper.fill(raw_hex)) - string = "%s:\n%s" % (to_text(struct_name), "\n".join([to_text(s) for s in field_strings])) - + struct_name = to_text(struct_name) + field_names = "\n".join([to_text(s) for s in field_strings]) + string = f"{struct_name}:\n{field_names}" return string def __setitem__(self, key, value): @@ -125,7 +124,7 @@ def unpack(self, data): def _get_field(self, key): field = self.fields.get(key, None) if field is None: - raise ValueError("Structure does not contain field %s" % key) + raise ValueError(f"Structure does not contain field {key}") return field @@ -150,7 +149,7 @@ def __init__(self, little_endian=True, default=None, size=None): self.little_endian = little_endian if not (size is None or isinstance(size, int) or isinstance(size, types.LambdaType)): - raise InvalidFieldDefinition("%s size for field must be an int or None for a variable length" % field_type) + raise InvalidFieldDefinition(f"{field_type} size for field must be an int or None for a variable length") self.size = size self.default = default self.value = None @@ -161,6 +160,10 @@ def __str__(self): def __len__(self): return self._get_packed_size() + @property + def _endian_prefix(self): + return "<" if self.little_endian else ">" + def pack(self): """ Packs the field value into a byte string so it can be sent to the @@ -172,10 +175,11 @@ def pack(self): value = self._get_calculated_value(self.value) packed_value = self._pack_value(value) size = self._get_calculated_size(self.size, packed_value) - if len(packed_value) != size: + packed_value_len = len(packed_value) + if packed_value_len != size: raise ValueError( - "Invalid packed data length for field %s of %d " - "does not fit field size of %d" % (self.name, len(packed_value), size) + f"Invalid packed data length for field {self.name} of {packed_value_len} " + f"does not fit field size of {size}" ) return packed_value @@ -310,7 +314,7 @@ def _get_struct_format(self, size, unsigned=True): struct_format = {1: "B", 2: "H", 4: "L", 8: "Q"} if size not in struct_format.keys(): - raise InvalidFieldDefinition("Cannot struct format of size %s" % size) + raise InvalidFieldDefinition(f"Cannot struct format of size {size}") format_char = struct_format[size] if not unsigned: format_char = format_char.lower() @@ -329,13 +333,12 @@ def __init__(self, size, unsigned=True, **kwargs): :param kwargs: Any other kwarg to be sent to Field() """ if size not in [1, 2, 4, 8]: - raise InvalidFieldDefinition("IntField size must have a value of 1, 2, 4, or 8 not %s" % str(size)) + raise InvalidFieldDefinition(f"IntField size must have a value of 1, 2, 4, or 8 not {size}") self.unsigned = unsigned super().__init__(size=size, **kwargs) def _pack_value(self, value): - format = self._get_struct_format(self.size, self.unsigned) - struct_string = "%s%s" % ("<" if self.little_endian else ">", format) + struct_string = self._endian_prefix + self._get_struct_format(self.size, self.unsigned) packed_int = struct.pack(struct_string, value) return packed_int @@ -345,13 +348,12 @@ def _parse_value(self, value): elif isinstance(value, types.LambdaType): int_value = value elif isinstance(value, bytes): - format = self._get_struct_format(self.size, self.unsigned) - struct_string = "%s%s" % ("<" if self.little_endian else ">", format) + struct_string = self._endian_prefix + self._get_struct_format(self.size, self.unsigned) int_value = struct.unpack(struct_string, value)[0] elif isinstance(value, int): int_value = value else: - raise TypeError("Cannot parse value for field %s of type %s to an int" % (self.name, type(value).__name__)) + raise TypeError(f"Cannot parse value for field {self.name} of type {type(value).__name__} to an int") return int_value def _get_packed_size(self): @@ -377,17 +379,14 @@ def _parse_value(self, value): elif isinstance(value, types.LambdaType): bytes_value = value elif isinstance(value, int): - format = self._get_struct_format(self.size) - struct_string = "%s%s" % ("<" if self.little_endian else ">", format) + struct_string = self._endian_prefix + self._get_struct_format(self.size) bytes_value = struct.pack(struct_string, value) elif isinstance(value, Structure): bytes_value = value.pack() elif isinstance(value, bytes): bytes_value = value else: - raise TypeError( - "Cannot parse value for field %s of type %s to a byte string" % (self.name, type(value).__name__) - ) + raise TypeError(f"Cannot parse value for field {self.name} of type {type(value).__name__} to a byte string") return bytes_value def _get_packed_size(self): @@ -487,7 +486,7 @@ def _parse_value(self, value): # manually parse each list entry to the field type specified list_value = value else: - raise TypeError("Cannot parse value for field %s of type %s to a list" % (self.name, type(value).__name__)) + raise TypeError(f"Cannot parse value for field {self.name} of type {type(value).__name__} to a list") list_value = [self._parse_sub_value(v) for v in list_value] return list_value @@ -500,12 +499,12 @@ def _parse_sub_value(self, value): structure_type=type(value), default=value, ) - new_field.name = "%s list entry" % self.name + new_field.name = f"{self.name} list entry" new_field.structure = value new_field.set_value(new_field.default) else: new_field = copy.deepcopy(self.list_type) - new_field.name = "%s list entry" % self.name + new_field.name = f"{self.name} list entry" new_field.set_value(value) return new_field @@ -522,7 +521,8 @@ def _to_string(self): if len(list_string) == 0: string = "[]" else: - string = "[\n%s\n]" % ",\n".join(list_string) + list_str = ",\n".join(list_string) + string = f"[\n{list_str}\n]" return string def _create_list_from_bytes(self, list_count, list_type, value): @@ -583,9 +583,7 @@ def _parse_value(self, value): elif isinstance(value, Structure): structure_value = value else: - raise TypeError( - "Cannot parse value for field %s of type %s to a structure" % (self.name, type(value).__name__) - ) + raise TypeError(f"Cannot parse value for field {self.name} of type {type(value).__name__} to a structure") if isinstance(structure_value, bytes) and self.structure_type and structure_value != b"": if isinstance(self.structure_type, types.LambdaType): @@ -608,7 +606,7 @@ def _to_string(self): def _get_field(self, key): structure_value = self._get_calculated_value(self.value) if isinstance(structure_value, bytes): - raise ValueError("Cannot get field %s when structure is defined as a byte string" % key) + raise ValueError(f"Cannot get field {key} when structure is defined as a byte string") field = structure_value._get_field(key) return field @@ -634,7 +632,7 @@ def __init__(self, size=None, **kwargs): :param kwargs: Any other kwarg to be sent to Field() """ if not (size is None or size == 8): - raise InvalidFieldDefinition("DateTimeField type must have a size of 8 not %d" % size) + raise InvalidFieldDefinition(f"DateTimeField type must have a size of 8 not {size}") super().__init__(size=8, **kwargs) def _pack_value(self, value): @@ -644,8 +642,7 @@ def _pack_value(self, value): epoch_time_ms = td.microseconds + (td.seconds + td.days * 24 * 3600) * 10**6 ns100 = self.EPOCH_FILETIME + (epoch_time_ms * 10) - format = self._get_struct_format(8) - struct_string = "%s%s" % ("<" if self.little_endian else ">", format) + struct_string = self._endian_prefix + self._get_struct_format(8) bytes_value = struct.pack(struct_string, ns100) return bytes_value @@ -656,8 +653,7 @@ def _parse_value(self, value): elif isinstance(value, types.LambdaType): datetime_value = value elif isinstance(value, bytes): - format = self._get_struct_format(8) - struct_string = "%s%s" % ("<" if self.little_endian else ">", format) + struct_string = self._endian_prefix + self._get_struct_format(8) int_value = struct.unpack(struct_string, value)[0] return self._parse_value(int_value) # just parse the value again elif isinstance(value, int): @@ -671,9 +667,7 @@ def _parse_value(self, value): elif isinstance(value, datetime.datetime): datetime_value = value else: - raise TypeError( - "Cannot parse value for field %s of type %s to a datetime" % (self.name, type(value).__name__) - ) + raise TypeError(f"Cannot parse value for field {self.name} of type {type(value).__name__} to a datetime") return datetime_value def _get_packed_size(self): @@ -694,7 +688,7 @@ def __init__(self, size=None, **kwargs): :param kwargs: Any other kwarg to be sent to Field() """ if not (size is None or size == 16): - raise InvalidFieldDefinition("UuidField type must have a size of 16 not %d" % size) + raise InvalidFieldDefinition(f"UuidField type must have a size of 16 not {size}") super().__init__(size=16, **kwargs) def _pack_value(self, value): @@ -717,7 +711,7 @@ def _parse_value(self, value): elif isinstance(value, types.LambdaType): uuid_value = value else: - raise TypeError("Cannot parse value for field %s of type %s to a uuid" % (self.name, type(value).__name__)) + raise TypeError(f"Cannot parse value for field {self.name} of type {type(value).__name__} to a uuid") return uuid_value def _get_packed_size(self): @@ -743,7 +737,7 @@ def _parse_value(self, value): break if not valid and int_value != 0 and self.enum_strict: - raise ValueError("Enum value %d does not exist in enum type %s" % (int_value, self.enum_type)) + raise ValueError(f"Enum value {int_value} does not exist in enum type {self.enum_type}") return int_value def _to_string(self): @@ -754,9 +748,9 @@ def _to_string(self): enum_name = enum break if enum_name is None: - return "(%d) UNKNOWN_ENUM" % value + return f"({value}) UNKNOWN_ENUM" else: - return "(%d) %s" % (value, enum_name) + return f"({value}) {enum_name}" class FlagField(IntField): @@ -773,7 +767,7 @@ def set_flag(self, flag): break if not valid and self.flag_strict: - raise ValueError("Flag value does not exist in flag type %s" % self.flag_type) + raise ValueError(f"Flag value does not exist in flag type {self.flag_type}") self.set_value(self.value | flag) def has_flag(self, flag): @@ -786,7 +780,7 @@ def _parse_value(self, value): if isinstance(value, int): current_val &= ~value if current_val != 0 and self.flag_strict: - raise ValueError("Invalid flag for field %s value set %d" % (self.name, current_val)) + raise ValueError(f"Invalid flag for field {self.name} value set {current_val}") return int_value @@ -799,7 +793,7 @@ def _to_string(self): if isinstance(value, int) and self.has_flag(value): flags.append(flag) flags.sort() - return "(%d) %s" % (field_value, ", ".join(flags)) + return f"({field_value}) " + (", ".join(flags)) class BoolField(Field): @@ -811,7 +805,7 @@ def __init__(self, size=1, **kwargs): :param kwargs: Any other kwargs to be sent to Field() """ if size != 1: - raise InvalidFieldDefinition("BoolField size must have a value of 1, not %d" % size) + raise InvalidFieldDefinition(f"BoolField size must have a value of 1, not {size}") super().__init__(size=size, **kwargs) def _pack_value(self, value): @@ -827,7 +821,7 @@ def _parse_value(self, value): elif isinstance(value, types.LambdaType): bool_value = value else: - raise TypeError("Cannot parse value for field %s of type %s to a bool" % (self.name, type(value).__name__)) + raise TypeError(f"Cannot parse value for field {self.name} of type {type(value).__name__} to a bool") return bool_value def _get_packed_size(self): @@ -858,9 +852,7 @@ def _parse_value(self, value): elif isinstance(value, types.LambdaType): text_value = value else: - raise TypeError( - "Cannot parse value for field %s of type %s to a text string" % (self.name, type(value).__name__) - ) + raise TypeError(f"Cannot parse value for field {self.name} of type {type(value).__name__} to a text string") return text_value diff --git a/src/smbprotocol/transport.py b/src/smbprotocol/transport.py index 3ba05b35..052b43a4 100644 --- a/src/smbprotocol/transport.py +++ b/src/smbprotocol/transport.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- # Copyright: (c) 2019, Jordan Borean (@jborean93) # MIT License (see LICENSE or https://opensource.org/licenses/MIT) @@ -66,7 +65,7 @@ def connect(self): try: self._sock = socket.create_connection((self.server, self.port), timeout=self.timeout) except (OSError, socket.gaierror) as err: - raise ValueError("Failed to connect to '%s:%s': %s" % (self.server, self.port, str(err))) from err + raise ValueError(f"Failed to connect to '{self.server}:{self.port}'") from err self._sock.settimeout(None) # Make sure the socket is in blocking mode. self.connected = True @@ -79,7 +78,7 @@ def close(self): # which returns b'' meaning it was closed. try: self._sock.shutdown(socket.SHUT_RDWR) - except socket.error as e: # pragma: no cover + except OSError as e: # pragma: no cover # Avoid collecting coverage here to avoid CI failing due to race condition differences if e.errno != errno.ENOTCONN: raise @@ -98,8 +97,7 @@ def send(self, header): data_length = len(b_msg) if data_length > self.MAX_SIZE: raise ValueError( - "Data to be sent over Direct TCP size %d exceeds the max length allowed %d" - % (data_length, self.MAX_SIZE) + f"Data to be sent over Direct TCP size {data_length} exceeds the max length allowed {self.MAX_SIZE}" ) tcp_packet = DirectTCPPacket() @@ -127,7 +125,7 @@ def _recv(self, length, timeout): offset = 0 while offset < length: read_len = length - offset - log.debug("Socket recv(%s) (total %s)" % (read_len, length)) + log.debug(f"Socket recv({read_len}) (total {length})") start_time = timeit.default_timer() @@ -144,7 +142,7 @@ def _recv(self, length, timeout): try: b_data = self._sock.recv(read_len) - except socket.error as e: + except OSError as e: # Windows will raise this error if the socket has been shutdown, Linux return returns an empty byte # string so we just replicate that. if e.errno not in [errno.ESHUTDOWN, errno.ECONNRESET]: @@ -153,7 +151,7 @@ def _recv(self, length, timeout): b_data = b"" read_len = len(b_data) - log.debug("Socket recv() returned %s bytes (total %s)" % (read_len, length)) + log.debug(f"Socket recv() returned {read_len} bytes (total {length})") if read_len == 0: self.close() diff --git a/src/smbprotocol/tree.py b/src/smbprotocol/tree.py index 94f3e37d..7383aeb9 100644 --- a/src/smbprotocol/tree.py +++ b/src/smbprotocol/tree.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- # Copyright: (c) 2019, Jordan Borean (@jborean93) # MIT License (see LICENSE or https://opensource.org/licenses/MIT) @@ -236,16 +235,16 @@ def connect(self, require_secure_negotiate=True): verify the negotiation parameters with the server to prevent SMB downgrade attacks """ - log.info("Session: %s - Creating connection to share %s" % (self.session.username, self.share_name)) + log.info(f"Session: {self.session.username} - Creating connection to share {self.share_name}") utf_share_name = self.share_name.encode("utf-16-le") connect = SMB2TreeConnectRequest() connect["buffer"] = utf_share_name - log.info("Session: %s - Sending Tree Connect message" % self.session.username) + log.info("Session: %s - Sending Tree Connect message", self.session.username) log.debug(connect) request = self.session.connection.send(connect, sid=self.session.session_id) - log.info("Session: %s - Receiving Tree Connect response" % self.session.username) + log.info("Session: %s - Receiving Tree Connect response", self.session.username) response = self.session.connection.receive(request) tree_response = SMB2TreeConnectResponse() tree_response.unpack(response["data"].get_value()) @@ -253,7 +252,7 @@ def connect(self, require_secure_negotiate=True): # https://msdn.microsoft.com/en-us/library/cc246687.aspx self.tree_connect_id = response["tree_id"].get_value() - log.info("Session: %s - Created tree connection with ID %d" % (self.session.username, self.tree_connect_id)) + log.info("Session: %s - Created tree connection with ID %d", self.session.username, self.tree_connect_id) self._connected = True self.session.tree_connect_table[self.tree_connect_id] = self @@ -277,16 +276,14 @@ def disconnect(self): if not self._connected: return - log.info("Session: %s, Tree: %s - Disconnecting from Tree Connect" % (self.session.username, self.share_name)) + log.info(f"Session: {self.session.username}, Tree: {self.share_name} - Disconnecting from Tree Connect") req = SMB2TreeDisconnect() - log.info("Session: %s, Tree: %s - Sending Tree Disconnect message" % (self.session.username, self.share_name)) + log.info(f"Session: {self.session.username}, Tree: {self.share_name} - Sending Tree Disconnect message") log.debug(req) request = self.session.connection.send(req, sid=self.session.session_id, tid=self.tree_connect_id) - log.info( - "Session: %s, Tree: %s - Receiving Tree Disconnect response" % (self.session.username, self.share_name) - ) + log.info(f"Session: {self.session.username}, Tree: {self.share_name} - Receiving Tree Disconnect response") res = self.session.connection.receive(request) res_disconnect = SMB2TreeDisconnect() res_disconnect.unpack(res["data"].get_value()) @@ -295,8 +292,8 @@ def disconnect(self): del self.session.tree_connect_table[self.tree_connect_id] def _verify_dialect_negotiate(self): - log_header = "Session: %s, Tree: %s" % (self.session.username, self.share_name) - log.info("%s - Running secure negotiate process" % log_header) + log_header = f"Session: {self.session.username}, Tree: {self.share_name}" + log.info("%s - Running secure negotiate process", log_header) if not self.session.signing_key: # This will only happen if we authenticated with the guest or anonymous user. @@ -324,13 +321,13 @@ def _verify_dialect_negotiate(self): ioctl_request["buffer"] = val_neg ioctl_request["max_output_response"] = len(val_neg) ioctl_request["flags"] = IOCTLFlags.SMB2_0_IOCTL_IS_FSCTL - log.info("%s - Sending Secure Negotiate Validation message" % log_header) + log.info("%s - Sending Secure Negotiate Validation message", log_header) log.debug(ioctl_request) request = self.session.connection.send( ioctl_request, sid=self.session.session_id, tid=self.tree_connect_id, force_signature=True ) - log.info("%s - Receiving secure negotiation response" % log_header) + log.info("%s - Receiving secure negotiation response", log_header) try: response = self.session.connection.receive(request) @@ -349,7 +346,7 @@ def _verify_dialect_negotiate(self): ioctl_resp.unpack(response["data"].get_value()) log.debug(ioctl_resp) - log.info("%s - Unpacking secure negotiate response info" % log_header) + log.info("%s - Unpacking secure negotiate response info", log_header) val_resp = SMB2ValidateNegotiateInfoResponse() val_resp.unpack(ioctl_resp["buffer"].get_value()) log.debug(val_resp) @@ -364,12 +361,11 @@ def _verify_dialect_negotiate(self): "server security mode", val_resp["security_mode"].get_value(), self.session.connection.server_security_mode ) self._verify("server dialect", val_resp["dialect"].get_value(), self.session.connection.dialect) - log.info("Session: %d, Tree: %d - Secure negotiate complete" % (self.session.session_id, self.tree_connect_id)) + log.info("Session: %d, Tree: %d - Secure negotiate complete", self.session.session_id, self.tree_connect_id) def _verify(self, check, actual, expected): - log_header = "Session: %d, Tree: %d" % (self.session.session_id, self.tree_connect_id) if actual != expected: + log_header = f"Session: {self.session.session_id}, Tree: {self.tree_connect_id}" raise SMBException( - "%s - Secure negotiate failed to verify %s, " - "Actual: %s, Expected: %s" % (log_header, check, actual, expected) + f"{log_header} - Secure negotiate failed to verify {check}, Actual: {actual}, Expected: {expected}", ) diff --git a/tests/__init__.py b/tests/__init__.py index b6f1b33a..a687ba1a 100644 --- a/tests/__init__.py +++ b/tests/__init__.py @@ -1,3 +1,2 @@ -# -*- coding: utf-8 -*- # Copyright: (c) 2019, Jordan Borean (@jborean93) # MIT License (see LICENSE or https://opensource.org/licenses/MIT) diff --git a/tests/conftest.py b/tests/conftest.py index ae47c8d2..ffa2f34b 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- # Copyright: (c) 2019, Jordan Borean (@jborean93) # MIT License (see LICENSE or https://opensource.org/licenses/MIT) @@ -167,8 +166,8 @@ def smb_real(): share = os.environ.get("SMB_SHARE", "share") if server: - share = r"\\%s\%s" % (server, share) - encrypted_share = "%s-encrypted" % share + share = rf"\\{server}\{share}" + encrypted_share = f"{share}-encrypted" return username, password, server, int(port), share, encrypted_share else: pytest.skip("The SMB_SHARE env var was not set, integration tests will be skipped") @@ -183,7 +182,8 @@ def smb_real(): ) def smb_share(request, smb_real): # Use some non ASCII chars to test out edge cases by default. - share_path = "%s\\%s" % (smb_real[request.param[1]], "Pýtæs†-[%s] 💩" % time.time()) + test_folder = f"Pýtæs†-[{time.time()}] 💩" + share_path = rf"{smb_real[request.param[1]]}\{test_folder}" delete_session(smb_real[2]) # Test out forward slashes also work with the share-encrypted test @@ -206,14 +206,14 @@ def smb_share(request, smb_real): ids=["dfs-root", "dfs-single-target", "dfs-broken-target"], ) def smb_dfs_share(request, smb_real): - test_folder = "Pýtæs†-[%s] 💩" % time.time() + test_folder = f"Pýtæs†-[{time.time()}] 💩" if request.param[1]: - target_share_path = "%s\\%s" % (smb_real[request.param[1]], test_folder) - dfs_path = "\\\\%s\\dfs\\%s\\%s" % (smb_real[2], request.param[0], test_folder) + target_share_path = rf"{smb_real[request.param[1]]}\{test_folder}" + dfs_path = rf"\\{smb_real[2]}\dfs\{request.param[0]}\{test_folder}" else: - target_share_path = "\\\\%s\\dfs\\%s" % (smb_real[2], test_folder) + target_share_path = rf"\\{smb_real[2]}\dfs\{test_folder}" dfs_path = target_share_path mkdir(target_share_path, username=smb_real[0], password=smb_real[1], port=smb_real[3]) diff --git a/tests/test_change_notify.py b/tests/test_change_notify.py index 422a5ed7..1ffd0594 100644 --- a/tests/test_change_notify.py +++ b/tests/test_change_notify.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- # Copyright: (c) 2019, Jordan Borean (@jborean93) # MIT License (see LICENSE or https://opensource.org/licenses/MIT) diff --git a/tests/test_connection.py b/tests/test_connection.py index 67885c3d..644e5d0e 100644 --- a/tests/test_connection.py +++ b/tests/test_connection.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- # Copyright: (c) 2019, Jordan Borean (@jborean93) # MIT License (see LICENSE or https://opensource.org/licenses/MIT) diff --git a/tests/test_create_contexts.py b/tests/test_create_contexts.py index 70e0745f..a95e5d1a 100644 --- a/tests/test_create_contexts.py +++ b/tests/test_create_contexts.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- # Copyright: (c) 2019, Jordan Borean (@jborean93) # MIT License (see LICENSE or https://opensource.org/licenses/MIT) @@ -59,11 +58,11 @@ class TestSMB2CreateContextName: def test_create_message(self): ea_buffer1 = SMB2CreateEABuffer() ea_buffer1["ea_name"] = "Authors\x00".encode("ascii") - ea_buffer1["ea_value"] = "Jordan Borean".encode("utf-8") + ea_buffer1["ea_value"] = b"Jordan Borean" ea_buffer2 = SMB2CreateEABuffer() ea_buffer2["ea_name"] = "Title\x00".encode("ascii") - ea_buffer2["ea_value"] = "Jordan Borean Title".encode("utf-8") + ea_buffer2["ea_value"] = b"Jordan Borean Title" ea_buffers = SMB2CreateContextRequest() ea_buffers["buffer_name"] = CreateContextName.SMB2_CREATE_EA_BUFFER diff --git a/tests/test_dfs.py b/tests/test_dfs.py index 9479a03f..1476130a 100644 --- a/tests/test_dfs.py +++ b/tests/test_dfs.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- # Copyright: (c) 2019, Jordan Borean (@jborean93) # MIT License (see LICENSE or https://opensource.org/licenses/MIT) diff --git a/tests/test_exceptions.py b/tests/test_exceptions.py index 1f4551fb..f4795b6b 100644 --- a/tests/test_exceptions.py +++ b/tests/test_exceptions.py @@ -1,5 +1,3 @@ -# -*- coding: utf-8 -*- -# Copyright: (c) 2019, Jordan Borean# -*- coding: utf-8 -*- (@jborean93) # MIT License (see LICENSE or https://opensource.org/licenses/MIT) import re diff --git a/tests/test_file_info.py b/tests/test_file_info.py index 3cb3d3c5..ce5535cc 100644 --- a/tests/test_file_info.py +++ b/tests/test_file_info.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- # Copyright: (c) 2019, Jordan Borean (@jborean93) # MIT License (see LICENSE or https://opensource.org/licenses/MIT) diff --git a/tests/test_header.py b/tests/test_header.py index 51cb4864..1175c8b0 100644 --- a/tests/test_header.py +++ b/tests/test_header.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- # Copyright: (c) 2020, Jordan Borean (@jborean93) # MIT License (see LICENSE or https://opensource.org/licenses/MIT) diff --git a/tests/test_ioctl.py b/tests/test_ioctl.py index 8e8fca33..7f94ee34 100644 --- a/tests/test_ioctl.py +++ b/tests/test_ioctl.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- # Copyright: (c) 2019, Jordan Borean (@jborean93) # MIT License (see LICENSE or https://opensource.org/licenses/MIT) diff --git a/tests/test_open.py b/tests/test_open.py index d9f596cf..86d2c1d0 100644 --- a/tests/test_open.py +++ b/tests/test_open.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- # Copyright: (c) 2019, Jordan Borean (@jborean93) # MIT License (see LICENSE or https://opensource.org/licenses/MIT) diff --git a/tests/test_query_info.py b/tests/test_query_info.py index 2ae9284a..a6e48120 100644 --- a/tests/test_query_info.py +++ b/tests/test_query_info.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- # Copyright: (c) 2019, Jordan Borean (@jborean93) # MIT License (see LICENSE or https://opensource.org/licenses/MIT) diff --git a/tests/test_reparse_point.py b/tests/test_reparse_point.py index 3b9255e3..97650428 100644 --- a/tests/test_reparse_point.py +++ b/tests/test_reparse_point.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- # Copyright: (c) 2019, Jordan Borean (@jborean93) # MIT License (see LICENSE or https://opensource.org/licenses/MIT) diff --git a/tests/test_security_descriptor.py b/tests/test_security_descriptor.py index 385918bb..38f1cdfe 100644 --- a/tests/test_security_descriptor.py +++ b/tests/test_security_descriptor.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- # Copyright: (c) 2019, Jordan Borean (@jborean93) # MIT License (see LICENSE or https://opensource.org/licenses/MIT) diff --git a/tests/test_session.py b/tests/test_session.py index 3ecb177d..5efd6d45 100644 --- a/tests/test_session.py +++ b/tests/test_session.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- # Copyright: (c) 2019, Jordan Borean (@jborean93) # MIT License (see LICENSE or https://opensource.org/licenses/MIT) diff --git a/tests/test_smbclient_os.py b/tests/test_smbclient_os.py index 37a3493c..da91c20a 100644 --- a/tests/test_smbclient_os.py +++ b/tests/test_smbclient_os.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- # Copyright: (c) 2019, Jordan Borean (@jborean93) # MIT License (see LICENSE or https://opensource.org/licenses/MIT) @@ -283,7 +282,7 @@ def test_listdir(dirname, smb_share): def test_listdir_with_pattern(smb_share): for filename in ["file.txt", "file-test1.txt", "file-test1a.txt"]: - with smbclient.open_file("%s\\%s" % (smb_share, filename), mode="w") as fd: + with smbclient.open_file(rf"{smb_share}\{filename}", mode="w") as fd: fd.write("content") actual = smbclient.listdir(smb_share, search_pattern="file-test*.txt") @@ -430,7 +429,7 @@ def test_makedirs_file_as_parent(smb_share): def test_read_text_file(smb_share): - file_path = "%s\\%s" % (smb_share, "file.txt") + file_path = rf"{smb_share}\file.txt" file_contents = "File Contents\nNewline" expected = "[NtStatus 0xc0000034] No such file or directory" @@ -471,7 +470,7 @@ def test_read_text_file(smb_share): def test_read_byte_file(smb_share): - file_path = "%s\\%s" % (smb_share, "file.txt") + file_path = rf"{smb_share}\file.txt" file_contents = b"\x00\x01\x02\x03" expected = "[NtStatus 0xc0000034] No such file or directory" @@ -502,7 +501,7 @@ def test_read_byte_file(smb_share): def test_write_text_file(smb_share): - file_path = "%s\\%s" % (smb_share, "file.txt") + file_path = rf"{smb_share}\file.txt" file_contents = "File Contents\nNewline" with smbclient.open_file(file_path, mode="w") as fd: @@ -531,7 +530,7 @@ def test_write_text_file(smb_share): def test_write_byte_file(smb_share): - file_path = "%s\\%s" % (smb_share, "file.txt") + file_path = rf"{smb_share}\file.txt" file_contents = b"File Contents\nNewline" with smbclient.open_file(file_path, mode="wb") as fd: @@ -562,7 +561,7 @@ def test_write_byte_file(smb_share): # https://github.com/jborean93/smbprotocol/issues/20 def test_read_large_text_file(smb_share): - file_path = "%s\\%s" % (smb_share, "file.txt") + file_path = rf"{smb_share}\file.txt" file_contents = "a" * 131074 with smbclient.open_file(file_path, mode="w") as fd: @@ -574,7 +573,7 @@ def test_read_large_text_file(smb_share): def test_write_exclusive_text_file(smb_share): - file_path = "%s\\%s" % (smb_share, "file.txt") + file_path = rf"{smb_share}\file.txt" file_contents = "File Contents\nNewline" with smbclient.open_file(file_path, mode="x") as fd: @@ -600,7 +599,7 @@ def test_write_exclusive_text_file(smb_share): def test_write_exclusive_byte_file(smb_share): - file_path = "%s\\%s" % (smb_share, "file.txt") + file_path = rf"{smb_share}\file.txt" file_contents = b"File Contents\nNewline" with smbclient.open_file(file_path, mode="xb") as fd: @@ -626,7 +625,7 @@ def test_write_exclusive_byte_file(smb_share): def test_append_text_file(smb_share): - file_path = "%s\\%s" % (smb_share, "file.txt") + file_path = rf"{smb_share}\file.txt" with smbclient.open_file(file_path, mode="a") as fd: assert isinstance(fd, io.TextIOWrapper) @@ -647,7 +646,7 @@ def test_append_text_file(smb_share): def test_append_byte_file(smb_share): - file_path = "%s\\%s" % (smb_share, "file.txt") + file_path = rf"{smb_share}\file.txt" with smbclient.open_file(file_path, mode="ab") as fd: assert isinstance(fd, io.BufferedWriter) @@ -668,7 +667,7 @@ def test_append_byte_file(smb_share): def test_read_write_text_file(smb_share): - file_path = "%s\\%s" % (smb_share, "file.txt") + file_path = rf"{smb_share}\file.txt" with smbclient.open_file(file_path, mode="w+") as fd: fd.write("abc") @@ -679,7 +678,7 @@ def test_read_write_text_file(smb_share): def test_read_write_byte_file(smb_share): - file_path = "%s\\%s" % (smb_share, "file.txt") + file_path = rf"{smb_share}\file.txt" with smbclient.open_file(file_path, mode="bw+") as fd: fd.write(b"abc") @@ -690,7 +689,7 @@ def test_read_write_byte_file(smb_share): def test_open_directory_fail(smb_share): - dir_path = "%s\\%s" % (smb_share, "dir") + dir_path = rf"{smb_share}\dir" smbclient.mkdir(dir_path) with pytest.raises(OSError, match=re.escape("[NtStatus 0xc00000ba] Is a directory: ")): @@ -709,14 +708,14 @@ def test_open_directory_with_correct_file_type(smb_share): def test_open_file_in_missing_dir(smb_share): - file_path = "%s\\dir\\%s" % (smb_share, "file.txt") + file_path = rf"{smb_share}\dir\file.txt" with pytest.raises(OSError, match=re.escape("[NtStatus 0xc000003a] No such file or directory: ")): smbclient.open_file(file_path) def test_open_file_with_read_share_access(smb_share): - file_path = "%s\\%s" % (smb_share, "file.txt") + file_path = rf"{smb_share}\file.txt" with smbclient.open_file(file_path, mode="w") as fd: fd.write("contents") @@ -738,7 +737,7 @@ def test_open_file_with_read_share_access(smb_share): def test_open_file_with_write_share_access(smb_share): - file_path = "%s\\%s" % (smb_share, "file.txt") + file_path = rf"{smb_share}\file.txt" with smbclient.open_file(file_path, mode="w") as fd: expected = ( @@ -762,7 +761,7 @@ def test_open_file_with_write_share_access(smb_share): def test_open_file_with_read_write_access(smb_share): - file_path = "%s\\%s" % (smb_share, "file.txt") + file_path = rf"{smb_share}\file.txt" with smbclient.open_file(file_path, mode="w", share_access="rw") as fd: fd.write("content") @@ -1262,7 +1261,7 @@ def test_scandir(smb_share): def test_scamdir_with_pattern(smb_share): for filename in ["file.txt", "file-test1.txt", "file-test1a.txt"]: - with smbclient.open_file("%s\\%s" % (smb_share, filename), mode="w") as fd: + with smbclient.open_file(rf"{smb_share}\{filename}", mode="w") as fd: fd.write("content") count = 0 @@ -1326,7 +1325,9 @@ def test_scandir_with_broken_symlink(smb_share): def test_scandir_with_cache(smb_real): - share_path = "%s\\%s" % (smb_real[4], "Pýtæs†-[%s] 💩" % time.time()) + share = smb_real[4] + test_folder = f"Pýtæs†-[{time.time()}] 💩" + share_path = rf"{share}\{test_folder}" cache = {} smbclient.mkdir(share_path, username=smb_real[0], password=smb_real[1], port=smb_real[3], connection_cache=cache) @@ -1840,7 +1841,7 @@ def test_walk_topdown(smb_share): smbclient.makedirs("%s\\dir1\\dir2\\dir3" % smb_share) for name in ["file1.txt", "dir1\\file2.txt", "dir1\\dir2\\file3.txt", "dir1\\dir2\\dir3\\file4.txt"]: - with smbclient.open_file("%s\\%s" % (smb_share, name), mode="w") as fd: + with smbclient.open_file(rf"{smb_share}\{name}", mode="w") as fd: fd.write("content") scanned_files = [] @@ -1861,7 +1862,7 @@ def test_walk_bottomup(smb_share): smbclient.makedirs("%s\\dir1\\dir2\\dir3" % smb_share) for name in ["file1.txt", "dir1\\file2.txt", "dir1\\dir2\\file3.txt", "dir1\\dir2\\dir3\\file4.txt"]: - with smbclient.open_file("%s\\%s" % (smb_share, name), mode="w") as fd: + with smbclient.open_file(rf"{smb_share}\{name}", mode="w") as fd: fd.write("content") scanned_files = [] diff --git a/tests/test_smbclient_path.py b/tests/test_smbclient_path.py index 9f22a6a8..edf45ea1 100644 --- a/tests/test_smbclient_path.py +++ b/tests/test_smbclient_path.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- # Copyright: (c) 2019, Jordan Borean (@jborean93) # MIT License (see LICENSE or https://opensource.org/licenses/MIT) diff --git a/tests/test_smbclient_pool.py b/tests/test_smbclient_pool.py index eaeaed37..02c5e489 100644 --- a/tests/test_smbclient_pool.py +++ b/tests/test_smbclient_pool.py @@ -1,7 +1,8 @@ -# -*- coding: utf-8 -*- # Copyright: (c) 2020, Jordan Borean (@jborean93) # MIT License (see LICENSE or https://opensource.org/licenses/MIT) +import logging + import pytest import smbclient._io as io @@ -89,16 +90,14 @@ def test_reset_connection_error_fail(mocker): pool.reset_connection_cache(connection_cache={"conn": connection_mock}) -def test_reset_connection_error_warning(monkeypatch, mocker): +def test_reset_connection_error_warning(mocker, caplog): connection_mock = mocker.MagicMock() connection_mock.disconnect.side_effect = Exception("exception") - warning_mock = mocker.MagicMock() - monkeypatch.setattr(pool.warnings, "warn", warning_mock) - pool.reset_connection_cache(fail_on_error=False, connection_cache={"conn": connection_mock}) + with caplog.at_level(logging.WARNING): + pool.reset_connection_cache(fail_on_error=False, connection_cache={"conn": connection_mock}) - assert warning_mock.call_count == 1 - assert warning_mock.call_args[0][0] == "Failed to close connection conn: exception" + assert "Failed to close connection conn" in caplog.text def test_dfs_referral_no_links_no_domain(reset_config, monkeypatch, mocker): @@ -134,7 +133,7 @@ def test_dfs_referral_no_links_from_domain(reset_config, monkeypatch, mocker): config.domain_controller = DOMAIN_NAME with pytest.raises(ObjectPathNotFound): - actual_get_smb_tree(f"\\\\{DOMAIN_NAME}\\dfs") + actual_get_smb_tree(rf"\\{DOMAIN_NAME}\dfs") def test_resolve_dfs_referral_no_links(reset_config, monkeypatch, mocker): diff --git a/tests/test_smbclient_shutil.py b/tests/test_smbclient_shutil.py index 5b8fd56a..36258ffa 100644 --- a/tests/test_smbclient_shutil.py +++ b/tests/test_smbclient_shutil.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- # Copyright: (c) 2019, Jordan Borean (@jborean93) # MIT License (see LICENSE or https://opensource.org/licenses/MIT) @@ -109,7 +108,7 @@ def test_copy_from_local(smb_share, tmp_path): ctypes.windll.kernel32.SetFileTime(handle, ref_time, ref_time, ref_time) ctypes.windll.kernel32.CloseHandle(handle) - dst_filename = "{}\\target.txt".format(smb_share) + dst_filename = f"{smb_share}\\target.txt" copy_from_to(str(src_filename), dst_filename) diff --git a/tests/test_structure.py b/tests/test_structure.py index 47f54637..f262778a 100644 --- a/tests/test_structure.py +++ b/tests/test_structure.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- # Copyright: (c) 2019, Jordan Borean (@jborean93) # MIT License (see LICENSE or https://opensource.org/licenses/MIT) diff --git a/tests/test_text.py b/tests/test_text.py index 87edb6be..232178de 100644 --- a/tests/test_text.py +++ b/tests/test_text.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- # Copyright: (c) 2019, Jordan Borean (@jborean93) # MIT License (see LICENSE or https://opensource.org/licenses/MIT) diff --git a/tests/test_transport.py b/tests/test_transport.py index 5fa89000..960350ca 100644 --- a/tests/test_transport.py +++ b/tests/test_transport.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- # Copyright: (c) 2019, Jordan Borean (@jborean93) # MIT License (see LICENSE or https://opensource.org/licenses/MIT) @@ -74,7 +73,7 @@ def test_normal_fail_message_too_big(self): def test_invalid_host(self): tcp = Tcp("fake-host", 445) - with pytest.raises(ValueError, match=re.escape("Failed to connect to 'fake-host:445': ")): + with pytest.raises(ValueError, match=re.escape("Failed to connect to 'fake-host:445'")): tcp.connect() diff --git a/tests/test_tree.py b/tests/test_tree.py index f2a53ec4..92206530 100644 --- a/tests/test_tree.py +++ b/tests/test_tree.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- # Copyright: (c) 2019, Jordan Borean (@jborean93) # MIT License (see LICENSE or https://opensource.org/licenses/MIT)