pysmb icon indicating copy to clipboard operation
pysmb copied to clipboard

Not supported SMB2 Dialect

Open elmosan opened this issue 7 years ago • 24 comments

Got this error message, when i tried to connect to smb2 server with pysmb==1.1.22:

smb.smb_structs.ProtocolError: Server does not support any of the pysmb dialects. Please email pysmb to add in support for your OS ==================== SMB Message ==================== Command: 0x72 (SMB_COM_NEGOTIATE) Status: NTSTATUS=0x00000000 Flags: 0x88 Flags2: 0xC003 PID: 10176 UID: 0 MID: 1 TID: 0 Security: 0x0000000000000000 Parameters: 2 bytes b'ffff' Data: 0 bytes b'' ==================== SMB Data Packet (hex) ==================== b'ff534d4272000000008803c00000000000000000000000000000c0270000010001ffff0000'

elmosan avatar Nov 19 '17 19:11 elmosan

@elmosan : What is the OS of the remote SMB server that you are connecting to?

miketeo avatar Nov 20 '17 02:11 miketeo

Sorry forgot to mention, it's a synology dsm 6.1 server with samba

elmosan avatar Nov 20 '17 06:11 elmosan

Weird. pysmb does have support for Samba. Are you able to find out what version of the Samba is running on server, or do a TCP packet capture between your client/server?

miketeo avatar Nov 20 '17 16:11 miketeo

The samba version is 4.4.13 Then samba is configured to use SMB2: min protocol=SMB2_10 Do you still need a tcp packet caputre?

elmosan avatar Nov 22 '17 16:11 elmosan

@elmosan : Will be good to have the packet capture. I'm using Samba 4.4.16 on my end.

miketeo avatar Nov 22 '17 16:11 miketeo

This sounds like the Samba server has a weird configuration, like SMB3 only, or pre 'NT' protocol. Can you show the smb.conf?

divad avatar Dec 01 '17 18:12 divad

@divad : I think elmosan's configuration tries to limit the acceptable protocols to a SMB2 version that is only supported by Windows 7 or later. Unfortunately, pySMB does not support the later SMB2 version.

I'm trying to get pysmb to support this later SMB2 version, but isn't making much progress. Samba keeps dropping the authentication attempt by closing the TCP connection with an INVALID code :(

miketeo avatar Dec 02 '17 14:12 miketeo

@divad Thanks, it's the protocol. I changed the smb.conf min protocol=SMB2_10 parameter to min protocol=SMB2 and it works now.

The smb parameters are explained here: https://www.samba.org/samba/docs/man/manpages-3/smb.conf.5.html

@miketeo Thanks for your efforts. Ok, I will work with the older SMB2 version for now and hope you can find a way.

edit: Changed because of the reply from miketeo

elmosan avatar Dec 03 '17 10:12 elmosan

Okay so I found time to look into this, and I think I might have found something interesting. In MS-SMB2 the documentation suggests that the negotiation is quite different between SMB 2.0 and SMB 2.1 (SMB 2.???).

Section 4.1 describes how pysmb is written, with SMB 2 support:

  1. Send SMB COM NEGOTIATE, get response
  2. Send SMB SESSION SETUP, get response
  3. Send SMB TREE CONNECT, get response

However Section 4.2 describes a different approach for SMB 2.1:

  1. Send SMB COM NEGOTIATE, get response
  2. Send SMB COM NEGOTIATE /again/.

This is what pysmb does not do, it proceeds to Session Setup, Samba expects SMB NEGOTIATE again, and so it sends NT_STATUS_INVALID_PARAMETER and closes the session.

According to the docs, the flow is as follows:

  1. The client sends an SMB negotiate packet with the string "SMB 2.???" in the dialect string list, along with the other SMB dialects the client implements.
  2. The server receives the SMB negotiate request and finds the "SMB 2.???" string in the dialect string list. The server responds with an SMB2 NEGOTIATE Response with the DialectRevision set to 0x02ff.
  3. The client receives the SMB2 NEGOTIATE Response. The client issues a new SMB2 NEGOTIATE Request with a new dialect 0x0210 appended along with other SMB2 dialects.
  4. The server receives the SMB2 negotiate request and finds dialect 0x0210. The server sends an SMB2 NEGOTIATE Response with DialectRevision set to 0x0210.

Now, it could be you already know this and I'm barking up the wrong tree, in which case, sorry! If that is the case, can I see the code you've written to do the above, so I can try to figure out what other error you're seeing?

divad avatar Jan 24 '18 17:01 divad

Yes, so this is the issue. What we need to do is:

  1. Send SMB COM NEGOTIATE, get response
  2. Send SMB2 NEGOTIATE, get response

I'm writing an implementation of SMB2 NEGOTIATE now, but I've never dabbled at this level before, so it may take me some time xD

divad avatar Jan 24 '18 19:01 divad

I have a working implementation of SMB2 COM NEGOTIATE and I can now, with pysmb, connect to SMB servers using the 2.1 dialect.

However, now I'm getting weird errors after connecting, wireshark insists that pysmb is trying to open a file called "(" (????). Its all very confusing. I'll keep working on it!

divad avatar Jan 24 '18 21:01 divad

Right, the problem is credits. With SMB 2.1 enabled (which actually is SMB2 proper, really), the client must request credits. pysmb does not, and so the server gets angry.

divad avatar Jan 24 '18 22:01 divad

@divad : Many thanks for identifying the problem for SMB 2.1 in pysmb. I will have to read up the credits sections in [MS-SMB2] again. The dual NEGOTIATE requests really sound like an Easter egg in the specifications.

miketeo avatar Jan 29 '18 17:01 miketeo

Yup. Would you like me to send the work I've done so far, even if incomplete? I'll create a branch and share it with you a bit later today.

divad avatar Jan 29 '18 17:01 divad

I was gonna read this repo in depth: https://github.com/hirochachacha/go-smb2

Its a working SMB2/3 client, with credits support. Its Go, so its quite easy to follow. It has a fully implemented credits solution.

divad avatar Jan 29 '18 17:01 divad

@divad : (code-sharing) Yes, please. Will be useful when I have the time to work on this.

miketeo avatar Jan 29 '18 17:01 miketeo

Microsoft included a 'helpful' diagram to explain:

smb dialects

divad avatar Jan 29 '18 18:01 divad

I launch the samba service in docker container dperson/samba. However, when I connect the service using pysmb, Exception Server does not support any of the pysmb dialects. Please email pysmb to add in support for your OS always is thrown.

What should I do next?

cobolbaby avatar Sep 26 '19 03:09 cobolbaby

@miketeo

cobolbaby avatar Sep 26 '19 03:09 cobolbaby

What is the version of the Samba service?

miketeo avatar Sep 26 '19 05:09 miketeo

You can try editing the smb.conf file and change (or add if necessary) this parameter: server min protocol = LANMAN1

Remember to restart the samba service after the change.

miketeo avatar Sep 26 '19 05:09 miketeo

@divad did you ever get further with this?

malthe avatar Jul 20 '21 08:07 malthe


C:\QGB\Anaconda3\lib\site-packages\smb\smb_structs.py in decode(self, message)
    360         elif self.dialect_index == 0xFFFF:
    361             raise ProtocolError('Server does not support any of the pysmb dialects. Please email pysmb to add in support for your OS',
--> 362                                 message.raw_data, message)
    363         else:
    364             raise ProtocolError('Unknown dialect index (0x%04X)' % self.dialect_index, message.raw_data, message)

ProtocolError: Server does not support any of the pysmb dialects. Please email pysmb to add in support for your OS
==================== SMB Message ====================
Command: 0x72 (SMB_COM_NEGOTIATE)
Status: NTSTATUS=0x00000000
Flags: 0x88
Flags2: 0xC003
PID: 6672
UID: 0
MID: 1
TID: 0
Security: 0x0000000000000000
Parameters: 2 bytes
b'ffff'
Data: 0 bytes
b''
==================== SMB Data Packet (hex) ====================
b'ff534d4272000000008803c00000000000000000000000000000101a0000010001ffff0000'

QGB avatar Sep 15 '22 12:09 QGB

In [134]: conn.connect('192.168.1.3',445)
---------------------------------------------------------------------------
ConnectionResetError                      Traceback (most recent call last)
<ipython-input-134-b35ca093384e> in <module>
----> 1 conn.connect('192.168.1.3',445)

C:\QGB\Anaconda3\lib\site-packages\smb\SMBConnection.py in connect(self, ip, port, sock_family, timeout)
    125                 self.onNMBSessionOK()
    126             while self.auth_result is None:
--> 127                 self._pollForNetBIOSPacket(timeout)
    128         finally:
    129             self.is_busy = False

C:\QGB\Anaconda3\lib\site-packages\smb\SMBConnection.py in _pollForNetBIOSPacket(self, timeout)
    611                         raise ex
    612                 else:
--> 613                     raise ex
    614
    615         type, flags, length = struct.unpack('>BBH', data)

C:\QGB\Anaconda3\lib\site-packages\smb\SMBConnection.py in _pollForNetBIOSPacket(self, timeout)
    600                     raise SMBTimeout
    601
--> 602                 d = self.sock.recv(read_len)
    603                 if len(d) == 0:
    604                     raise NotConnectedError

ConnectionResetError: [WinError 10054] 远程主机强迫关闭了一个现有的连接。

QGB avatar Sep 15 '22 12:09 QGB