miketeo / pysmb

pysmb is an experimental SMB/CIFS library written in Python. It implements the client-side SMB/CIFS protocol (SMB1 and SMB2) which allows your Python application to access and transfer files to/from SMB/CIFS shared folders like your Windows file sharing and Samba folders.
Other
338 stars 95 forks source link

Issue with listPath() #24

Closed humberry closed 9 years ago

humberry commented 9 years ago

Hi, I use your great module to get access to my mini wifi router (hootoo) usbstick (fat32). Everything seems to work except listPath() from the SMBConnection Class. Most of the time I got a error (98 out of 100 tries), but I can't find the bug. my example In the SMB Message 1 I can find "A: NTFS SMBu". Should it be 'FAT32' or is this correct?

miketeo commented 9 years ago

Hi, are you able to provide more details on the failures? Like any exception messages?

Not sure about the SMB Message 1. Can you copy/paste the entire message content?

humberry commented 9 years ago

This is the correct response (only 2 out of 100 tries worked) "\USBDisk1_Volume1\share\": . .. .Thumbs raspi-guide.pdf

And most of the time I get this long exception (you can find at the end of each smb message the ascii text I found): Failed to list \share\ on USBDisk1_Volume1: Unable to retrieve file list ==================== SMB Message 0 ==================== SMB Header:

Command: 0x75 (SMB_COM_TREE_CONNECT_ANDX) Status: NTSTATUS=0x00000000 Flags: 0x18 Flags2: 0xC807 PID: 3278 UID: 101 MID: 4 TID: 0 Security: 0x0000000000000000 Parameters: 8 bytes ff0000000c000100 Data: 55 bytes 005c005c0054004d00300032005c005500530042004400690073006b0031005f0056006f006c0075006d006500310000003f3f3f3f3f00 SMB Data Packet (hex):

ff534d4275000000001807c80000000000000000000000000000ce0c6500040004ff0000000c0001003700005c005c0054004d00300032005c005500530042004400690073006b0031005f0056006f006c0075006d006500310000003f3f3f3f3f00 (ASCII: \TM02\USBDisk1_Volume1 ????? SMBu) ==================== SMB Message 1 ==================== SMB Header:

Command: 0x75 (SMB_COM_TREE_CONNECT_ANDX) Status: NTSTATUS=0x00000000 Flags: 0x88 Flags2: 0xC801 PID: 3278 UID: 101 MID: 4 TID: 1 Security: 0x0000000000000000 Parameters: 6 bytes ff0000000300 Data: 13 bytes 413a004e005400460053000000 SMB Data Packet (hex):

ff534d4275000000008801c80000000000000000000000000100ce0c6500040003ff00000003000d00413a004e005400460053000000 (ASCII: A: NTFS SMBu) ==================== SMB Message 2 ==================== SMB Header:

Command: 0x32 (SMB_COM_TRANSACTION2) Status: NTSTATUS=0x00000000 Flags: 0x18 Flags2: 0xC807 PID: 3278 UID: 101 MID: 5 TID: 1 Security: 0x0000000000000000 Parameters: 30 bytes 200000000a00044100000000000000000000200044000000000001000100 Data: 35 bytes 0000003700640006000401000000005c00730068006100720065005c002a002e002a00 SMB Data Packet (hex):

ff534d4232000000001807c80000000000000000000000000100ce0c650005000f200000000a0004410000000000000000000020004400000000000100010023000000003700640006000401000000005c00730068006100720065005c002a002e002a00 (ASCII: \share. SMB2) ==================== SMB Message 3 ==================== SMB Header:

Command: 0x32 (SMB_COM_TRANSACTION2) Status: NTSTATUS=0xC000000F Flags: 0x88 Flags2: 0xC841 PID: 3278 UID: 101 MID: 5 TID: 1 Security: 0x0000000000000000 Parameters: 0 bytes

Data: 0 bytes SMB Data Packet (hex):

ff534d42320f0000c08841c80000000000000000000000000100ce0c65000500000000 (ASCII: SMB2)

humberry commented 9 years ago

Now the usbstick has ntfs, but I got the same exception "Failed to list \share\ on USBDisk1_Volume1: Unable to retrieve file list".

cclauss commented 9 years ago
    except Exception, e:
      print(type(e))  # what gets printed here?  i.e. What is the exception type?
humberry commented 9 years ago

<class 'smb.smb_structs.OperationFailure'>

cclauss commented 9 years ago

I got a summary like this:

==================== SMB Message 0 ====================
Command: 0x75 (SMB_COM_TREE_CONNECT_ANDX)
Status: NTSTATUS=0x00000000
Data: 55 bytes
005c005c0054004d00300032005c005500530042004400690073006b0031005f0056006f006c0075006d006500310000003f3f3f3f3f00
ascii: '\\TM02\USBDisk1_Volume1 ?  '
SMB Data Packet (hex):
ff534d4275000000001807c80000000000000000000000000000ce0c6500040004ff0000000c0001003700005c005c0054004d00300032005c005500530042004400690073006b0031005f0056006f006c0075006d006500310000003f3f3f3f3f00
ascii: '                      \\TM02\USBDisk1_Volume1 ?  '
==================== SMB Message 1 ====================
Command: 0x75 (SMB_COM_TREE_CONNECT_ANDX)
Status: NTSTATUS=0x00000000
Data: 13 bytes
413a004e005400460053000000
ascii: ' NTFS '
SMB Data Packet (hex):
ff534d4275000000008801c80000000000000000000000000100ce0c6500040003ff00000003000d00413a004e005400460053000000
ascii: '                      NTFS '
==================== SMB Message 2 ====================
Command: 0x32 (SMB_COM_TRANSACTION2)
Status: NTSTATUS=0x00000000
Data: 35 bytes
0000003700640006000401000000005c00730068006100720065005c002a002e002a00
ascii: ' 7d    \share\*.*'
SMB Data Packet (hex):
ff534d4232000000001807c80000000000000000000000000100ce0c650005000f200000000a0004410000000000000000000020004400000000000100010023000000003700640006000401000000005c00730068006100720065005c002a002e002a00
ascii: '                                  7d    \share\*.*'
==================== SMB Message 3 ====================
Command: 0x32 (SMB_COM_TRANSACTION2)
Status: NTSTATUS=0xC000000F
Data: 0 bytes
SMB Data Packet (hex):
ff534d42320f0000c08841c80000000000000000000000000100ce0c65000500000000
ascii: '                 '

When I do a print(smb_exception_decode(str(e))) with the code:

target_dict = { '=========' : -1,
                'Command: ' : -1,
                'Status: '  : -1,
                'Data: '    : 1,
                'SMB Data'  : 2 }

def ascii(in_hex):
    if in_hex.endswith('00'):
        in_hex = in_hex[:-2]
    s = ''
    #print(in_hex)
    while in_hex:
        i, in_hex = int(in_hex[-4:], 16), in_hex[:-4]
        s = (unichr(i) if 31 < i < 127 else ' ') + s
    return s

def smb_exception_decode(exception_text):
    trigger = -1  # when trigger is zero we need to ascii decode the line
    s = []
    for line in exception_text.splitlines():
        trigger -= 1
        if not trigger:
            s.append(line)
            s.append("ascii: '{}'".format(ascii(line)))
        else:
            for tt in target_dict:
                if line.startswith(tt):
                    s.append(line)
                    trigger = target_dict[tt]
                    if line.startswith('Data: 0 bytes'):
                        trigger = -1  # special case: no data
    return '\n'.join(s)
humberry commented 9 years ago

If you check each byte you can also see the 'SMBx' strings. But I have no idea why the last two messages contain SMB2 when smb_structs.SUPPORT_SMB2 is disabled (I also tried to enable it, but whenever I check it with conn.isUsingSMB2 the result is False).

humberry commented 9 years ago

In the file SMBConnection.py (section getAttributes()) I found: param string/unicode path: Path of the file on the remote server. If the file cannot be opened for reading, an :doc:OperationFailure<smb_exceptions> will be raised. But the path worked for up- and download files...

humberry commented 9 years ago

I modified smb/base.py and now I can tell you the exception raised in def _listPath_SMB1(self, service_name, path, callback, errback, search, pattern, timeout = 30): ... def findFirstCB(find_message, **kwargs): ... find_message.status.hasError = True

cclauss commented 9 years ago

I did not see the pattern 0x837766 or 0x008300770066.

>>> for c in 'SMB2':
...     print('{c} ==> 0x{i} or 0x00{i}'.format(c=c, i=ord(c)))
... 

S ==> 0x83 or 0x0083 M ==> 0x77 or 0x0077 B ==> 0x66 or 0x0066 2 ==> 0x50 or 0x0050

humberry commented 9 years ago

I think these values are decimal. 83 => 0x53 => S 77 => 0x4D => M 66 => 0x42 => B 50 => 0x32 => 2

humberry commented 9 years ago

Now I tried to establish a connection from a windows 7 system and noticed that I can use only the ip address and not the NetBIOS Name 'TM02'. Could this be the problem?

cclauss commented 9 years ago

You are correct on dec vs. hex!

IP address sounds like the way to go.

humberry commented 9 years ago

Unfortunately I got also an exception when I use the ip address as remote_name.

miketeo commented 9 years ago

The NTStatus 0xC000000F indicates an invalid/missing file error. Can you change your pattern

pattern="*"

For the SMB2 issue, I think you are misinterpreting the values. All SMB1 messages have the magic header 0xff534d42. The next byte after this magic header is the SMB command field. By some magical coincidence, the command value for SMB_COM_TRANSACTION2 is 0x32 which is the ASCII value for the character "2". If pysmb needs to issue SMB_COM_TRANSACTION2_SECONDARY request (0x33), then your debug message will print "SMB3"

humberry commented 9 years ago

I changed the pattern to "*" but the exception still raised in def _listPath_SMB1(self, service_name, path, callback, errback, search, pattern, timeout = 30): ... def findFirstCB(find_message, **kwargs): ... find_message.status.hasError = True (else branch)

And I had the chance to test it on an other pc, so I know the NetBIOS Name 'TM02' is reachable and not the issue.

miketeo commented 9 years ago

@humberry : Can you do run wireshark and do 2 packet captures of

  1. A successful directory listing of the shared folder using Windows or Linux
  2. A failed directory listing of the shared folder on pysmb?

Then I can compare the packet captures and see what are the flags that could cause the listing to fail.

humberry commented 9 years ago

I sent you an email with the filtered packets.

miketeo commented 9 years ago

@humbery: I have confirmed your issue has something to do with Windows DFS which is not supported by pysmb. I have not been able to get access or setup a DFS environment due to a lack of time and resources.

Can you email me more information about your environment and the model number of your router? It seems odd that a wifi router has DFS enabled. If the model is available in my local hardware store or from ebay, I might just buy to test it out.

humberry commented 9 years ago

HooToo TripMate Nano Wireless N Pocket Travel Router (HT-TM02) http://www.hootoo.com/media/downloads/User%20Guide%201.0%20-%20HT-TM02%20TripMate%20Nano.pdf

miketeo commented 9 years ago

The fix for this issue has been released in pysmb 1.1.14