Closed Boris-Sachet closed 1 year ago
Hmm based on your output the error is failing on the first message being sent, the SMB2 Negotiate Request. This might indicate that we are sending a value that the NAS is unable to parse but without having the box to test with it's hard for me to tell.
Can you try the following and let me know what ones pass and which ones fail?
import traceback
import uuid
from smbprotocol import Dialects
from smbprotocol.connection import Connection
for dialect in [Dialects.SMB_3_1_1, Dialects.SMB_3_0_2, Dialects.SMB_2_1_0]:
conn = Connection(uuid.uuid4(), "server2022.domain.test", 445)
try:
conn.connect(dialect=dialect)
except Exception as e:
print(f"Dialect 0x{dialect:04X} failed")
traceback.print_exc()
else:
conn.disconnect()
print(f"Dialect 0x{dialect:04X} successful")
If all but Dialect 0x0311
pass can you then try
import traceback
import uuid
from smbprotocol import Dialects
from smbprotocol.connection import Connection, Ciphers, SigningAlgorithms
conn = Connection(uuid.uuid4(), "server2022.domain.test", 445)
try:
conn.connect(
dialect=Dialects.SMB_3_1_1,
preferred_encryption_algos=[Ciphers.AES_128_GCM, Ciphers.AES_128_CCM],
preferred_signing_algos=[SigningAlgorithms.AES_CMAC],
)
except Exception as e:
print("Failure")
traceback.print_exc()
else:
conn.disconnect()
print("Success")
Another option is to enable debug logging for Samba on your Synology box to see if it gives more info as to why it rejected the negotiate request. Seeing if there are any updates available would be good. I believe in the past some older Samba versions rejected a message with the SMB2_NETNAME_NEGOTIATE_CONTEXT_ID
which newer Windows versions sent. This was a bug on their side and should be fixed in newer versions on Samba.
Finally you can use Wireshark to compare the first SMB request sent by smbprotocol vs something like Windows. If you can share the capture that would be great. Otherwise comparing the Negotiate Protocol Request
between what works and what doesn't will hopefully pick up on something different.
Hi! Thanks for your quick answer! I just tried your test code with the nas ip instead of server2022.domain.test and got a partial success:
First test
Dialect 0x0311 failed
Traceback (most recent call last):
File "/home/boris/comic-back/test.py", line 10, in <module>
conn.connect(dialect=dialect)
File "/home/boris/comic-back/venv/lib/python3.10/site-packages/smbprotocol/connection.py", line 799, in connect
smb_response = self._send_smb2_negotiate(dialect, timeout, enc_algos, sign_algos)
File "/home/boris/comic-back/venv/lib/python3.10/site-packages/smbprotocol/connection.py", line 1497, in _send_smb2_negotiate
response = self.receive(request, timeout=timeout)
File "/home/boris/comic-back/venv/lib/python3.10/site-packages/smbprotocol/connection.py", line 1006, in receive
raise SMBResponseException(response)
smbprotocol.exceptions.InvalidParameter: Received unexpected status from the server: An invalid parameter was passed to a service or function. (3221225485) STATUS_INVALID_PARAMETER: 0xc000000d
Dialect 0x0302 successful
Dialect 0x0210 successful
Second test
Traceback (most recent call last):
File "/home/boris/comic-back/test.py", line 9, in <module>
conn.connect(
File "/home/boris/comic-back/venv/lib/python3.10/site-packages/smbprotocol/connection.py", line 799, in connect
smb_response = self._send_smb2_negotiate(dialect, timeout, enc_algos, sign_algos)
File "/home/boris/comic-back/venv/lib/python3.10/site-packages/smbprotocol/connection.py", line 1497, in _send_smb2_negotiate
response = self.receive(request, timeout=timeout)
File "/home/boris/comic-back/venv/lib/python3.10/site-packages/smbprotocol/connection.py", line 1006, in receive
raise SMBResponseException(response)
smbprotocol.exceptions.InvalidParameter: Received unexpected status from the server: An invalid parameter was passed to a service or function. (3221225485) STATUS_INVALID_PARAMETER: 0xc000000d
Failure
I looked at the logging options on synology but it seems to be able to only log the file operations, not the connection process.
I'll try to connect on windows and record it with wireshark, I'll update you once it's done
I tested your first bit of code on windows and ubuntu, the python traceback is the same for booth (and same as the one in the first message so I didn't include it here). This is only the first request, the of for smb 3.1.1 that fail, the other two are sucessfull, I can post them later if you want.
Windows
Frame 53: 290 bytes on wire (2320 bits), 290 bytes captured (2320 bits) on interface \Device\NPF_{B0126886-B856-4B2B-86B8-D71408AF2710}, id 0
Ethernet II, Src: ASUSTekC_xx:xx:xx (xx:xx:xx:xx:xx:xx), Dst: Synology_xx:xx:xx (xx:xx:xx:xx:xx:xx)
Internet Protocol Version 4, Src: 192.168.1.43, Dst: 192.168.1.17
Transmission Control Protocol, Src Port: 63637, Dst Port: 445, Seq: 1, Ack: 1, Len: 236
NetBIOS Session Service
SMB2 (Server Message Block Protocol version 2)
SMB2 Header
ProtocolId: 0xfe534d42
Header Length: 64
Credit Charge: 0
Channel Sequence: 0
Reserved: 0000
Command: Negotiate Protocol (0)
Credits requested: 0
Flags: 0x00000000
.... .... .... .... .... .... .... ...0 = Response: This is a REQUEST
.... .... .... .... .... .... .... ..0. = Async command: This is a SYNC command
.... .... .... .... .... .... .... .0.. = Chained: This pdu is NOT a chained command
.... .... .... .... .... .... .... 0... = Signing: This pdu is NOT signed
.... .... .... .... .... .... .000 .... = Priority: This pdu does NOT contain a PRIORITY
...0 .... .... .... .... .... .... .... = DFS operation: This is a normal operation
..0. .... .... .... .... .... .... .... = Replay operation: This is NOT a replay operation
Chain Offset: 0x00000000
Message ID: 0
Process Id: 0x00000000
Tree Id: 0x00000000
Session Id: 0x0000000000000000
Signature: 00000000000000000000000000000000
[Response in: 55]
Negotiate Protocol Request (0x00)
[Preauth Hash: 710aaf8922ca96629c3d8ccd30865d7b58fc2f985e066f6fda4a7d2251388d312693f876…]
StructureSize: 0x0024
0000 0000 0010 010. = Fixed Part Length: 18
.... .... .... ...0 = Dynamic Part: False
Dialect count: 1
Security mode: 0x02, Signing required
.... ...0 = Signing enabled: False
.... ..1. = Signing required: True
Reserved: 0000
Capabilities: 0x00000045, DFS, LARGE MTU, ENCRYPTION
.... .... .... .... .... .... .... ...1 = DFS: This host supports DFS
.... .... .... .... .... .... .... ..0. = LEASING: This host does NOT support LEASING
.... .... .... .... .... .... .... .1.. = LARGE MTU: This host supports LARGE_MTU
.... .... .... .... .... .... .... 0... = MULTI CHANNEL: This host does NOT support MULTI CHANNEL
.... .... .... .... .... .... ...0 .... = PERSISTENT HANDLES: This host does NOT support PERSISTENT HANDLES
.... .... .... .... .... .... ..0. .... = DIRECTORY LEASING: This host does NOT support DIRECTORY LEASING
.... .... .... .... .... .... .1.. .... = ENCRYPTION: This host supports ENCRYPTION
Client Guid: d5fa2389-2c71-e348-bce9-a65b122d460a
NegotiateContextOffset: 0x00000068
NegotiateContextCount: 4
Reserved: 0000
Dialect: SMB 3.1.1 (0x0311)
Negotiate Context: SMB2_PREAUTH_INTEGRITY_CAPABILITIES
Type: SMB2_PREAUTH_INTEGRITY_CAPABILITIES (0x0001)
DataLength: 38
Reserved: 00000000
HashAlgorithmCount: 1
SaltLength: 32
HashAlgorithm: SHA-512 (0x0001)
Salt: f646d1120c555d824f7454b94dc2f44d1805ab87a0f4a227aa1fbb980b0a69cb
Negotiate Context: SMB2_ENCRYPTION_CAPABILITIES
Type: SMB2_ENCRYPTION_CAPABILITIES (0x0002)
DataLength: 10
Reserved: 00000000
CipherCount: 4
CipherId: AES-128-GCM (0x0002)
CipherId: AES-128-CCM (0x0001)
CipherId: AES-256-GCM (0x0004)
CipherId: AES-256-CCM (0x0003)
Negotiate Context: SMB2_NETNAME_NEGOTIATE_CONTEXT_ID
Type: SMB2_NETNAME_NEGOTIATE_CONTEXT_ID (0x0005)
DataLength: 24
Reserved: 00000000
Netname: 192.168.1.17
Negotiate Context: Unknown Type: (0x0)
Type: Unknown (0x0000)
DataLength: 0
Reserved: 00000000
Unknown: <MISSING>
Test on ubuntu:
Frame 5: 302 bytes on wire (2416 bits), 302 bytes captured (2416 bits) on interface \Device\NPF_{31D47A6B-0927-4E10-B347-D16F86EBF391}, id 0
Ethernet II, Src: Microsof_xx:xx:xx (xx:xx:xx:xx:xx:xx), Dst: Microsof_xx:xx:xx (xx:xx:xx:xx:xx:xx)
Internet Protocol Version 4, Src: 172.18.81.105, Dst: 192.168.1.17
Transmission Control Protocol, Src Port: 53884, Dst Port: 445, Seq: 1, Ack: 1, Len: 236
NetBIOS Session Service
SMB2 (Server Message Block Protocol version 2)
SMB2 Header
ProtocolId: 0xfe534d42
Header Length: 64
Credit Charge: 0
Channel Sequence: 0
Reserved: 0000
Command: Negotiate Protocol (0)
Credits requested: 0
Flags: 0x00000000
.... .... .... .... .... .... .... ...0 = Response: This is a REQUEST
.... .... .... .... .... .... .... ..0. = Async command: This is a SYNC command
.... .... .... .... .... .... .... .0.. = Chained: This pdu is NOT a chained command
.... .... .... .... .... .... .... 0... = Signing: This pdu is NOT signed
.... .... .... .... .... .... .000 .... = Priority: This pdu does NOT contain a PRIORITY
...0 .... .... .... .... .... .... .... = DFS operation: This is a normal operation
..0. .... .... .... .... .... .... .... = Replay operation: This is NOT a replay operation
Chain Offset: 0x00000000
Message ID: 0
Process Id: 0x00000000
Tree Id: 0x00000000
Session Id: 0x0000000000000000
Signature: 00000000000000000000000000000000
[Response in: 7]
Negotiate Protocol Request (0x00)
[Preauth Hash: a707762659cd229635b1a7a1c15b45b4f0305a21fbd158971f460902ef54925815d09a81…]
StructureSize: 0x0024
0000 0000 0010 010. = Fixed Part Length: 18
.... .... .... ...0 = Dynamic Part: False
Dialect count: 1
Security mode: 0x02, Signing required
.... ...0 = Signing enabled: False
.... ..1. = Signing required: True
Reserved: 0000
Capabilities: 0x00000045, DFS, LARGE MTU, ENCRYPTION
.... .... .... .... .... .... .... ...1 = DFS: This host supports DFS
.... .... .... .... .... .... .... ..0. = LEASING: This host does NOT support LEASING
.... .... .... .... .... .... .... .1.. = LARGE MTU: This host supports LARGE_MTU
.... .... .... .... .... .... .... 0... = MULTI CHANNEL: This host does NOT support MULTI CHANNEL
.... .... .... .... .... .... ...0 .... = PERSISTENT HANDLES: This host does NOT support PERSISTENT HANDLES
.... .... .... .... .... .... ..0. .... = DIRECTORY LEASING: This host does NOT support DIRECTORY LEASING
.... .... .... .... .... .... .1.. .... = ENCRYPTION: This host supports ENCRYPTION
Client Guid: 546dd9ab-700f-9e40-bdcf-7b2100fd622f
NegotiateContextOffset: 0x00000068
NegotiateContextCount: 4
Reserved: 0000
Dialect: SMB 3.1.1 (0x0311)
Negotiate Context: SMB2_PREAUTH_INTEGRITY_CAPABILITIES
Type: SMB2_PREAUTH_INTEGRITY_CAPABILITIES (0x0001)
DataLength: 38
Reserved: 00000000
HashAlgorithmCount: 1
SaltLength: 32
HashAlgorithm: SHA-512 (0x0001)
Salt: 0bf72302f6d0cc082bbef4422118c235abef2d4b0f66470c64439f0f69954acb
Negotiate Context: SMB2_ENCRYPTION_CAPABILITIES
Type: SMB2_ENCRYPTION_CAPABILITIES (0x0002)
DataLength: 10
Reserved: 00000000
CipherCount: 4
CipherId: AES-128-GCM (0x0002)
CipherId: AES-128-CCM (0x0001)
CipherId: AES-256-GCM (0x0004)
CipherId: AES-256-CCM (0x0003)
Negotiate Context: SMB2_NETNAME_NEGOTIATE_CONTEXT_ID
Type: SMB2_NETNAME_NEGOTIATE_CONTEXT_ID (0x0005)
DataLength: 24
Reserved: 00000000
Netname: 192.168.1.17
Negotiate Context: Unknown Type: (0x0)
Type: Unknown (0x0000)
DataLength: 0
Reserved: 00000000
Unknown: <MISSING>
So at a guess I believe the issue is the same with https://github.com/jborean93/smbprotocol/issues/158 where the presence of the SMB2_NETNAME_NEGOTIATE_CONTEXT_ID
entry is causing problems. When doing a wireshark capture on Windows you should try and capture the native Windows client not smbprotocol. Only really newer builds of Windows 10 (and 11) include this field so if you have a new enough version I expect Windows to fail in the same way. If Windows sends that field but still succeeds then something else is at play, if it fails then it's the most likely culprit.
Unfortunately at this point in time I'm not sure what else I can do. This field is meant to be ignored by older hosts and if it isn't even newer Windows builds will be failing to connect to it. Your only real recurse is to figure out if you can update the Samba version used on the Synology box.
Ok so I did delete the SMB cache on the synology and opened the root share again (on windows 10), and to my surprise they communicated fully in ipv6 instead of ipv4.
The Server Message Block Protocol part has less fields, I'm not even sure which version of the smb protocol it is using.
Frame 157: 147 bytes on wire (1176 bits), 147 bytes captured (1176 bits) on interface \Device\NPF_{B0126886-B856-4B2B-86B8-D71408AF2710}, id 0
Ethernet II, Src: ASUSTekC_32:72:c2 (78:24:af:32:72:c2), Dst: Synology_ad:a5:f2 (00:11:32:ad:a5:f2)
Internet Protocol Version 6, Src: fe80::401:3a5c:f2ee:c7de, Dst: fe80::211:32ff:fead:a5f2
Transmission Control Protocol, Src Port: 59971, Dst Port: 445, Seq: 1, Ack: 1, Len: 73
NetBIOS Session Service
SMB (Server Message Block Protocol)
SMB Header
Server Component: SMB
SMB Command: Negotiate Protocol (0x72)
NT Status: STATUS_SUCCESS (0x00000000)
Flags: 0x18, Canonicalized Pathnames, Case Sensitivity
0... .... = Request/Response: Message is a request to the server
.0.. .... = Notify: Notify client only on open
..0. .... = Oplocks: OpLock not requested/granted
...1 .... = Canonicalized Pathnames: Pathnames are canonicalized
.... 1... = Case Sensitivity: Path names are caseless
.... ..0. = Receive Buffer Posted: Receive buffer has not been posted
.... ...0 = Lock and Read: Lock&Read, Write&Unlock are not supported
Flags2: 0xc853, Unicode Strings, Error Code Type, Extended Security Negotiation, Long Names Used, Security Signatures Required, Extended Attributes, Long Names Allowed
1... .... .... .... = Unicode Strings: Strings are Unicode
.1.. .... .... .... = Error Code Type: Error codes are NT error codes
..0. .... .... .... = Execute-only Reads: Don't permit reads if execute-only
...0 .... .... .... = Dfs: Don't resolve pathnames with Dfs
.... 1... .... .... = Extended Security Negotiation: Extended security negotiation is supported
.... .0.. .... .... = Reparse Path: The request does not use a @GMT reparse path
.... .... .1.. .... = Long Names Used: Path names in request are long file names
.... .... ...1 .... = Security Signatures Required: Security signatures are required
.... .... .... 0... = Compressed: Compression is not requested
.... .... .... .0.. = Security Signatures: Security signatures are not supported
.... .... .... ..1. = Extended Attributes: Extended attributes are supported
.... .... .... ...1 = Long Names Allowed: Long file names are allowed in the response
Process ID High: 0
Signature: 0000000000000000
Reserved: 0000
Tree ID: 65535
Process ID: 65279
User ID: 0
Multiplex ID: 0
Negotiate Protocol Request (0x72)
Word Count (WCT): 0
Byte Count (BCC): 34
Requested Dialects
Dialect: NT LM 0.12
Buffer Format: Dialect (2)
Name: NT LM 0.12
Dialect: SMB 2.002
Buffer Format: Dialect (2)
Name: SMB 2.002
Dialect: SMB 2.???
Buffer Format: Dialect (2)
Name: SMB 2.???
Here's the full conversation:
The Nas is already using the latest version of DSM so there's no update I can do.
I'll gladly open an issue to them, but I'm not really good with network stuff so I'm not sure what to tell them exactly.
That’s the smb1 request which you can ignore. See the next smb negotiate request to see the smb2 details which compare to what smbprotocol sends.
My bad, here's the correct one.
The SMB2_NETNAME_NEGOTIATE_CONTEXT_ID
field is present and almost the same, the only difference I noted is that it used the nas hostname instead of the ip which shouldn't affect the outcome, but the DataLength of 16 instead of 24 might be what make the difference?
Frame 161: 302 bytes on wire (2416 bits), 302 bytes captured (2416 bits) on interface \Device\NPF_{B0126886-B856-4B2B-86B8-D71408AF2710}, id 0
Ethernet II, Src: ASUSTekC_32:72:c2 (78:24:af:32:72:c2), Dst: Synology_ad:a5:f2 (00:11:32:ad:a5:f2)
Internet Protocol Version 6, Src: fe80::401:3a5c:f2ee:c7de, Dst: fe80::211:32ff:fead:a5f2
Transmission Control Protocol, Src Port: 59971, Dst Port: 445, Seq: 74, Ack: 207, Len: 228
NetBIOS Session Service
SMB2 (Server Message Block Protocol version 2)
SMB2 Header
ProtocolId: 0xfe534d42
Header Length: 64
Credit Charge: 0
Channel Sequence: 0
Reserved: 0000
Command: Negotiate Protocol (0)
Credits requested: 0
Flags: 0x00000000
.... .... .... .... .... .... .... ...0 = Response: This is a REQUEST
.... .... .... .... .... .... .... ..0. = Async command: This is a SYNC command
.... .... .... .... .... .... .... .0.. = Chained: This pdu is NOT a chained command
.... .... .... .... .... .... .... 0... = Signing: This pdu is NOT signed
.... .... .... .... .... .... .000 .... = Priority: This pdu does NOT contain a PRIORITY
...0 .... .... .... .... .... .... .... = DFS operation: This is a normal operation
..0. .... .... .... .... .... .... .... = Replay operation: This is NOT a replay operation
Chain Offset: 0x00000000
Message ID: 1
Process Id: 0x0000feff
Tree Id: 0x00000000
Session Id: 0x0000000000000000
Signature: 00000000000000000000000000000000
[Response in: 162]
Negotiate Protocol Request (0x00)
[Preauth Hash: 7f123ee1263b48abcd6dba58ae3432c4b066c40807d62f677ca7e9c6260315c34d4cf096…]
StructureSize: 0x0024
0000 0000 0010 010. = Fixed Part Length: 18
.... .... .... ...0 = Dynamic Part: False
Dialect count: 5
Security mode: 0x01, Signing enabled
.... ...1 = Signing enabled: True
.... ..0. = Signing required: False
Reserved: 0000
Capabilities: 0x0000007f, DFS, LEASING, LARGE MTU, MULTI CHANNEL, PERSISTENT HANDLES, DIRECTORY LEASING, ENCRYPTION
.... .... .... .... .... .... .... ...1 = DFS: This host supports DFS
.... .... .... .... .... .... .... ..1. = LEASING: This host supports LEASING
.... .... .... .... .... .... .... .1.. = LARGE MTU: This host supports LARGE_MTU
.... .... .... .... .... .... .... 1... = MULTI CHANNEL: This host supports MULTI CHANNEL
.... .... .... .... .... .... ...1 .... = PERSISTENT HANDLES: This host supports PERSISTENT HANDLES
.... .... .... .... .... .... ..1. .... = DIRECTORY LEASING: This host supports DIRECTORY LEASING
.... .... .... .... .... .... .1.. .... = ENCRYPTION: This host supports ENCRYPTION
Client Guid: 35f8913b-5d00-11ed-873c-001a7dda7113
NegotiateContextOffset: 0x00000070
NegotiateContextCount: 4
Reserved: 0000
Dialect: SMB 2.0.2 (0x0202)
Dialect: SMB 2.1 (0x0210)
Dialect: SMB 3.0 (0x0300)
Dialect: SMB 3.0.2 (0x0302)
Dialect: SMB 3.1.1 (0x0311)
Negotiate Context: SMB2_PREAUTH_INTEGRITY_CAPABILITIES
Type: SMB2_PREAUTH_INTEGRITY_CAPABILITIES (0x0001)
DataLength: 38
Reserved: 00000000
HashAlgorithmCount: 1
SaltLength: 32
HashAlgorithm: SHA-512 (0x0001)
Salt: dad05af2240ca8a1664ba463f220aaebcfa6ea5cf14c3ba8a118fa69669c1ee6
Negotiate Context: SMB2_ENCRYPTION_CAPABILITIES
Type: SMB2_ENCRYPTION_CAPABILITIES (0x0002)
DataLength: 6
Reserved: 00000000
CipherCount: 2
CipherId: AES-128-GCM (0x0002)
CipherId: AES-128-CCM (0x0001)
Negotiate Context: SMB2_COMPRESSION_CAPABILITIES
Type: SMB2_COMPRESSION_CAPABILITIES (0x0003)
DataLength: 16
Reserved: 00000000
CompressionAlgorithmCount: 4
Flags: 0x00000001, Chained
.... .... .... .... .... .... .... ...1 = Chained: True
0000 0000 0000 0000 0000 0000 0000 000. = Reserved: 0x00000000
CompressionAlgorithmId: Pattern_V1 (0x0004)
CompressionAlgorithmId: LZ77 (0x0002)
CompressionAlgorithmId: LZ77+Huffman (0x0003)
CompressionAlgorithmId: LZNT1 (0x0001)
Negotiate Context: SMB2_NETNAME_NEGOTIATE_CONTEXT_ID
Type: SMB2_NETNAME_NEGOTIATE_CONTEXT_ID (0x0005)
DataLength: 16
Reserved: 00000000
Netname: Heimdall
Also I just noticed it now, but the two test script you provided had this field which seems incomplete, couldn't that be the source of the smbprotocol.exceptions.InvalidParameter error?
Negotiate Context: Unknown Type: (0x0)
Type: Unknown (0x0000)
DataLength: 0
Reserved: 00000000
Unknown: <MISSING>
Thanks for confirming that Windows is sending SMB2_NETNAME_NEGOTIATE_CONTEXT_ID
and it still works.
Also I just noticed it now, but the two test script you provided had this field which seems incomplete, couldn't that be the source of the smbprotocol.exceptions.InvalidParameter error?
It certainly could be it and most likely the cause. I'll have to play around with this and see if I can replicate it in Wireshark and figure out why it's happening. At a guess the padding calculation is wrong.
Thanks for all the information, it's been very helpful in tracking down the problem. The PR https://github.com/jborean93/smbprotocol/pull/201 will fix the problem here. Ultimately the code was adding padding where it wasn't actually needed as the hostname used was a multiple of 8 bytes.
If this is still a problem when upgrading to 1.10.0 please let me know and I'll open the issue again to look further into it.
Thanks for all your quick replies and fixing the problem so quickly, I'll try it tomorrow and update you if it's working :)
Just tested it and it is now working! Thanks a lot!
Fantastic, thanks for confirming.
I've been trying to connect to a smb share in python 3.10 from ubuntu 22.04 to my Synology NAS (DS218 on DSM 7.1.1-42962 Update 1) and I got this error with a simple test code:
I tried with a few variations in the path string, a raw string string, with and without the auth_protocol="ntlm" param, with no better success.
Full traceback
The SMB is configured on the NAS to accept SMB1, SMB2, SMB2 and Large MTU and SMB3, encryption is defined by the client.
Packages list on the venv
I looked at issues #89 and #112 but I couldn't find any fitting solution in them